]> xenbits.xensource.com Git - qemu-upstream-4.6-testing.git/commitdiff
usb-storage: fill status in complete callback.
authorGerd Hoffmann <kraxel@redhat.com>
Mon, 21 Nov 2011 10:29:27 +0000 (11:29 +0100)
committerGerd Hoffmann <kraxel@redhat.com>
Mon, 21 Nov 2011 13:08:01 +0000 (14:08 +0100)
Put status word into device state, fill it in command_complete, have
usb_msd_send_status just send it out.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
hw/usb-msd.c

index 8dde421328773fa1221456425b5fcd202a308169..5dc4afc53851b3e6d34776ca273e4aadc766385a 100644 (file)
@@ -38,6 +38,13 @@ enum USBMSDMode {
     USB_MSDM_CSW /* Command Status.  */
 };
 
+struct usb_msd_csw {
+    uint32_t sig;
+    uint32_t tag;
+    uint32_t residue;
+    uint8_t status;
+};
+
 typedef struct {
     USBDevice dev;
     enum USBMSDMode mode;
@@ -46,6 +53,7 @@ typedef struct {
     uint32_t data_len;
     uint32_t residue;
     uint32_t tag;
+    struct usb_msd_csw csw;
     SCSIRequest *req;
     SCSIBus bus;
     BlockConf conf;
@@ -67,13 +75,6 @@ struct usb_msd_cbw {
     uint8_t cmd[16];
 };
 
-struct usb_msd_csw {
-    uint32_t sig;
-    uint32_t tag;
-    uint32_t residue;
-    uint8_t status;
-};
-
 enum {
     STR_MANUFACTURER = 1,
     STR_PRODUCT,
@@ -191,19 +192,15 @@ static void usb_msd_copy_data(MSDState *s, USBPacket *p)
 
 static void usb_msd_send_status(MSDState *s, USBPacket *p)
 {
-    struct usb_msd_csw csw;
     int len;
 
     DPRINTF("Command status %d tag 0x%x, len %zd\n",
-            s->result, s->tag, p->iov.size);
-    csw.sig = cpu_to_le32(0x53425355);
-    csw.tag = cpu_to_le32(s->tag);
-    csw.residue = s->residue;
-    csw.status = s->result;
-
-    len = MIN(sizeof(csw), p->iov.size);
-    usb_packet_copy(p, &csw, len);
-    p->result = len;
+            s->csw.status, s->csw.tag, p->iov.size);
+
+    assert(s->csw.sig == 0x53425355);
+    len = MIN(sizeof(s->csw), p->iov.size);
+    usb_packet_copy(p, &s->csw, len);
+    memset(&s->csw, 0, sizeof(s->csw));
 }
 
 static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
@@ -236,6 +233,12 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status)
     DPRINTF("Command complete %d\n", status);
     s->residue = s->data_len;
     s->result = status != 0;
+
+    s->csw.sig = cpu_to_le32(0x53425355);
+    s->csw.tag = cpu_to_le32(s->tag);
+    s->csw.residue = s->residue;
+    s->csw.status = s->result;
+
     if (s->packet) {
         if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
             /* A deferred packet with no write data remaining must be
@@ -257,6 +260,7 @@ static void usb_msd_command_complete(SCSIRequest *req, uint32_t status)
     } else if (s->data_len == 0) {
         s->mode = USB_MSDM_CSW;
     }
+
     scsi_req_unref(req);
     s->req = NULL;
 }