From 978e8c75a78d16d933dfa471fa247e7e61c9f7a4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 5 Aug 2008 10:46:23 -0400 Subject: [PATCH] usb-storage: automatically recognize bad residues commit 59f4ff2ecff4cef36378928cec891785b402e80c upstream This patch (as1119b) 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 Tested-by: Matthew Frost Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/transport.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 6610d2dd1e7..f2062e171f8 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -1034,8 +1034,21 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) /* try to compute the actual residue, based on how much data * was really transferred and what the device tells us */ - if (residue) { - if (!(us->flags & US_FL_IGNORE_RESIDUE)) { + if (residue && !(us->flags & US_FL_IGNORE_RESIDUE)) { + + /* Heuristically detect devices that generate bogus residues + * by seeing what happens with INQUIRY and READ CAPACITY + * commands. + */ + if (bcs->Status == US_BULK_STAT_OK && + scsi_get_resid(srb) == 0 && + ((srb->cmnd[0] == INQUIRY && + transfer_length == 36) || + (srb->cmnd[0] == READ_CAPACITY && + transfer_length == 8))) { + us->flags |= US_FL_IGNORE_RESIDUE; + + } else { residue = min(residue, transfer_length); scsi_set_resid(srb, max(scsi_get_resid(srb), (int) residue)); -- 2.34.1