Commit 93c9bf4d1838d5851a18ca398b0ad66397f05056

Authored by Alan Stern
Committed by Greg Kroah-Hartman
1 parent 90a646c770

usb-storage: handle a skipped data phase

Sometimes mass-storage devices using the Bulk-only transport will
mistakenly skip the data phase of a command.  Rather than sending the
data expected by the host or sending a zero-length packet, they go
directly to the status phase and send the CSW.

This causes problems for usb-storage, for obvious reasons.  The driver
will interpret the CSW as a short data transfer and will wait to
receive a CSW.  The device won't have anything left to send, so the
command eventually times out.

The SCSI layer doesn't retry commands after they time out (this is a
relatively recent change).  Therefore we should do our best to detect
a skipped data phase and handle it promptly.

This patch adds code to do that.  If usb-storage receives a short
13-byte data transfer from the device, and if the first four bytes of
the data match the CSW signature, the driver will set the residue to
the full transfer length and interpret the data as a CSW.

This fixes Bugzilla #86611.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Tested-by: Paul Osmialowski <newchief@king.net.pl>
CC: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 26 additions and 0 deletions Side-by-side Diff

drivers/usb/storage/transport.c
... ... @@ -1118,6 +1118,31 @@
1118 1118 */
1119 1119 if (result == USB_STOR_XFER_LONG)
1120 1120 fake_sense = 1;
  1121 +
  1122 + /*
  1123 + * Sometimes a device will mistakenly skip the data phase
  1124 + * and go directly to the status phase without sending a
  1125 + * zero-length packet. If we get a 13-byte response here,
  1126 + * check whether it really is a CSW.
  1127 + */
  1128 + if (result == USB_STOR_XFER_SHORT &&
  1129 + srb->sc_data_direction == DMA_FROM_DEVICE &&
  1130 + transfer_length - scsi_get_resid(srb) ==
  1131 + US_BULK_CS_WRAP_LEN) {
  1132 + struct scatterlist *sg = NULL;
  1133 + unsigned int offset = 0;
  1134 +
  1135 + if (usb_stor_access_xfer_buf((unsigned char *) bcs,
  1136 + US_BULK_CS_WRAP_LEN, srb, &sg,
  1137 + &offset, FROM_XFER_BUF) ==
  1138 + US_BULK_CS_WRAP_LEN &&
  1139 + bcs->Signature ==
  1140 + cpu_to_le32(US_BULK_CS_SIGN)) {
  1141 + usb_stor_dbg(us, "Device skipped data phase\n");
  1142 + scsi_set_resid(srb, transfer_length);
  1143 + goto skipped_data_phase;
  1144 + }
  1145 + }
1121 1146 }
1122 1147  
1123 1148 /* See flow chart on pg 15 of the Bulk Only Transport spec for
... ... @@ -1153,6 +1178,7 @@
1153 1178 if (result != USB_STOR_XFER_GOOD)
1154 1179 return USB_STOR_TRANSPORT_ERROR;
1155 1180  
  1181 + skipped_data_phase:
1156 1182 /* check bulk status */
1157 1183 residue = le32_to_cpu(bcs->Residue);
1158 1184 usb_stor_dbg(us, "Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",