@@ -1287,6 +1287,15 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
scsi_set_resid(srb, max(scsi_get_resid(srb),
(int) residue));
}
+ } else if (!residue) {
+ /*
+ * The command may have been retried after a CHECK CONDITION
+ * failure and autosense execution, which can result in resid
+ * to indicate the residual at the time of the failure instead
+ * of 0. Clear the resid here to indicate that the command
+ * fully completed.
+ */
+ scsi_set_resid(srb, 0);
}
/* based on the status code, we report good or bad */
A scsi command terminated with CHECK CONDITION is hijacked to execute request sense with the original command information preserved and restored respectively with scsi_eh_prep_cmnd() and scsi_eh_restore_cmnd() in usb_stor_invoke_transport(). This means that if the original command is retried, the command resid may not be 0, indicating the residual at the time of the previous failed execution. If the command is retried and fully succeed, the residual of 0 should thus be set, always, to avoid reporting to the upper layer an incorrect non-zero residual. Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> --- drivers/usb/storage/transport.c | 9 +++++++++ 1 file changed, 9 insertions(+)