ChangeSet 1.1557.49.12, 2004/02/17 16:44:27-08:00, stern@rowland.harvard.edu [PATCH] USB Storage: Reduce auto-sensing for CB transport This patch addresses a problem common among digital cameras that use the CB transport. Namely, too much auto-sensing confuses them; particularly auto-sensing after INQUIRY. I've made some traces of a Windows 2000 driver to see what it does (data sent to Andries Brouwer for inclusion on his web site; I'll announce when it's ready for viewing). Basically, it almost never sends REQUEST SENSE unless it received a STALL from the device. That's a pretty bogus way to operate, because it means that Windows has no way to tell when the device has finished executing a command if the command doesn't involve an IN transfer. Even after a lengthy WRITE, Windows continues to transmit more commands without regard for whether or not they will get overwritten in the device's internal buffer (and hence not executed). Indeed, exactly that happened with some of the commands in one of my traces. To be safe, we must follow every non-IN transfer with an auto-sense, but IN transfers that don't stall can be considered to have succeeded. That's what this patch does. It reduces auto-sensing by a considerable factor, probably close to half. It also fixes the problem with INQUIRY, since INQUIRY involves an IN data transfer. drivers/usb/storage/transport.c | 19 +++++-------------- 1 files changed, 5 insertions(+), 14 deletions(-) diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c Thu Feb 19 17:22:07 2004 +++ b/drivers/usb/storage/transport.c Thu Feb 19 17:22:07 2004 @@ -561,23 +561,14 @@ /* * If we're running the CB transport, which is incapable - * of determining status on it's own, we need to auto-sense almost - * every time. + * of determining status on its own, we need to auto-sense + * unless the operation involved a data-in transfer. Devices + * can signal data-in errors by stalling the bulk-in pipe. */ - if (us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) { + if ((us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) && + srb->sc_data_direction != SCSI_DATA_READ) { US_DEBUGP("-- CB transport device requiring auto-sense\n"); need_auto_sense = 1; - - /* There are some exceptions to this. Notably, if this is - * a UFI device and the command is REQUEST_SENSE or INQUIRY, - * then it is impossible to truly determine status. - */ - if (us->subclass == US_SC_UFI && - ((srb->cmnd[0] == REQUEST_SENSE) || - (srb->cmnd[0] == INQUIRY))) { - US_DEBUGP("** no auto-sense for a special command\n"); - need_auto_sense = 0; - } } /*