This is not really required for the state machine but it improves
the symmetry of zero-data packets with data packets, and helps with
assertions and reasoning about traces.

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 include/hw/usb/msd.h |  1 +
 hw/usb/dev-storage.c | 10 +++++++---
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/include/hw/usb/msd.h b/include/hw/usb/msd.h
index af12a16c35f..6d741e44160 100644
--- a/include/hw/usb/msd.h
+++ b/include/hw/usb/msd.h
@@ -14,6 +14,7 @@ typedef enum USBMSDCBWState {
     USB_MSD_CBW_NONE,    /* Ready, waiting for CBW packet. */
     USB_MSD_CBW_DATAOUT, /* Expecting DATA-OUT (to device) packet */
     USB_MSD_CBW_DATAIN,  /* Expecting DATA-IN (from device) packet */
+    USB_MSD_CBW_NODATA,  /* No data, CSW but also a SCSI completion */
     USB_MSD_CBW_CSW      /* No more data, expecting CSW packet.  */
 } USBMSDCBWState;
 
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index 5b773a22e60..a2544d2659f 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -318,9 +318,12 @@ void usb_msd_command_complete(SCSIRequest *req, size_t 
resid)
     scsi_req_unref(req);
     s->req = NULL;
 
+    g_assert(s->cbw_state == USB_MSD_CBW_DATAIN ||
+             s->cbw_state == USB_MSD_CBW_DATAOUT ||
+             s->cbw_state == USB_MSD_CBW_NODATA);
+
     if (p) {
-        g_assert(s->cbw_state == USB_MSD_CBW_DATAIN ||
-                 s->cbw_state == USB_MSD_CBW_DATAOUT);
+        g_assert(s->cbw_state != USB_MSD_CBW_NODATA);
         if (s->data_len) {
             int len = (p->iov.size - p->actual_length);
             usb_packet_skip(p, len);
@@ -500,7 +503,7 @@ static void usb_msd_handle_data_out(USBDevice *dev, 
USBPacket *p)
         tag = le32_to_cpu(cbw.tag);
         s->data_len = le32_to_cpu(cbw.data_len);
         if (s->data_len == 0) {
-            s->cbw_state = USB_MSD_CBW_CSW;
+            s->cbw_state = USB_MSD_CBW_NODATA;
         } else if (cbw.flags & 0x80) {
             s->cbw_state = USB_MSD_CBW_DATAIN;
         } else {
@@ -565,6 +568,7 @@ static void usb_msd_handle_data_in(USBDevice *dev, 
USBPacket *p)
     int len;
 
     switch (s->cbw_state) {
+    case USB_MSD_CBW_NODATA:
     case USB_MSD_CBW_DATAOUT:
         if (!check_valid_csw(p)) {
             goto fail;
-- 
2.47.1


Reply via email to