/* try to compute the actual residue, based on how much data
         * was really transferred and what the device tells us */
-       if (residue) {
-               if (!(us->fflags & US_FL_IGNORE_RESIDUE)) {
+       if (residue && !(us->fflags & 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->fflags |= US_FL_IGNORE_RESIDUE;
+
+               } else {
                        residue = min(residue, transfer_length);
                        scsi_set_resid(srb, max(scsi_get_resid(srb),
                                                               (int) residue));