diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2008-07-29 11:58:06 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-08-13 20:32:50 -0400 |
commit | 59f4ff2ecff4cef36378928cec891785b402e80c (patch) | |
tree | b49428f1fd19f26c75ed3e2d6994ba72d3a3d190 | |
parent | 1a21175a615ed346e8043f5e9d60a672266b84b4 (diff) |
usb-storage: automatically recognize bad residues
This patch (as1119) will help to reduce the clutter of usb-storage's
unusual_devs file by automatically detecting some devices that need
the IGNORE_RESIDUE flag. The idea is that devices should never return
a non-zero residue for an INQUIRY or a READ CAPACITY command unless
they failed to transfer all the requested data. So if one of these
commands transfers a standard amount of data but there is a positive
residue, we know that the residue is bogus and we can set the flag.
This fixes the problems reported in Bugzilla #11125.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/storage/transport.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index fcbbfdb7b2b0..3523a0bfa0ff 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
@@ -1032,8 +1032,21 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1032 | 1032 | ||
1033 | /* try to compute the actual residue, based on how much data | 1033 | /* try to compute the actual residue, based on how much data |
1034 | * was really transferred and what the device tells us */ | 1034 | * was really transferred and what the device tells us */ |
1035 | if (residue) { | 1035 | if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) { |
1036 | if (!(us->fflags & US_FL_IGNORE_RESIDUE)) { | 1036 | |
1037 | /* Heuristically detect devices that generate bogus residues | ||
1038 | * by seeing what happens with INQUIRY and READ CAPACITY | ||
1039 | * commands. | ||
1040 | */ | ||
1041 | if (bcs->Status == US_BULK_STAT_OK && | ||
1042 | scsi_get_resid(srb) == 0 && | ||
1043 | ((srb->cmnd[0] == INQUIRY && | ||
1044 | transfer_length == 36) || | ||
1045 | (srb->cmnd[0] == READ_CAPACITY && | ||
1046 | transfer_length == 8))) { | ||
1047 | us->fflags |= US_FL_IGNORE_RESIDUE; | ||
1048 | |||
1049 | } else { | ||
1037 | residue = min(residue, transfer_length); | 1050 | residue = min(residue, transfer_length); |
1038 | scsi_set_resid(srb, max(scsi_get_resid(srb), | 1051 | scsi_set_resid(srb, max(scsi_get_resid(srb), |
1039 | (int) residue)); | 1052 | (int) residue)); |