From 24a5bbe1c8cd6f5e90100b42eac29f41c33939de Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 4 Jan 2012 18:13:54 +0100 Subject: usb-storage: cancel I/O on reset When resetting the usb-storage device we'll have to carefully cancel and clear any requests which might be in flight, otherwise we'll confuse the state machine. Signed-off-by: Gerd Hoffmann --- hw/usb-msd.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'hw') diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 4c06950..3147131 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -278,6 +278,18 @@ static void usb_msd_handle_reset(USBDevice *dev) MSDState *s = (MSDState *)dev; DPRINTF("Reset\n"); + if (s->req) { + scsi_req_cancel(s->req); + } + assert(s->req == NULL); + + if (s->packet) { + USBPacket *p = s->packet; + s->packet = NULL; + p->result = USB_RET_STALL; + usb_packet_complete(dev, p); + } + s->mode = USB_MSDM_CBW; } -- cgit v1.1 From fd891c9318b112462e54ee1b3b16b074b8bec5b1 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Thu, 22 Dec 2011 11:34:30 +0200 Subject: usb-ohci: td.cbp incorrectly updated near page end The current code that updates the cbp value after a transfer looks like this: td.cbp += ret; if ((td.cbp & 0xfff) + ret > 0xfff) { because the 'ret' value is effectively added twice the check may fire too early when the overflow hasn't happened yet. Below is one of the possible changes that correct the behavior: Signed-off-by: Gerd Hoffmann --- hw/usb-ohci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'hw') diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index e68be70..81488c4 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -1025,10 +1025,10 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) if (ret == len) { td.cbp = 0; } else { - td.cbp += ret; if ((td.cbp & 0xfff) + ret > 0xfff) { - td.cbp &= 0xfff; - td.cbp |= td.be & ~0xfff; + td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff); + } else { + td.cbp += ret; } } td.flags |= OHCI_TD_T1; -- cgit v1.1