diff options
Diffstat (limited to 'drivers')
-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)); |