Commit 35f751d9 authored by Alan Stern's avatar Alan Stern Committed by Deepak Saxena

[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.
parent 8e2c8a8a
......@@ -561,23 +561,14 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
/*
* 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;
}
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment