diff options
Diffstat (limited to 'drivers/usb/storage/transport.c')
-rw-r--r-- | drivers/usb/storage/transport.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 00418995d8e9..e8ae21b2d387 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
@@ -819,6 +819,35 @@ Retry_Sense: | |||
819 | } | 819 | } |
820 | } | 820 | } |
821 | 821 | ||
822 | /* | ||
823 | * Some devices don't work or return incorrect data the first | ||
824 | * time they get a READ(10) command, or for the first READ(10) | ||
825 | * after a media change. If the INITIAL_READ10 flag is set, | ||
826 | * keep track of whether READ(10) commands succeed. If the | ||
827 | * previous one succeeded and this one failed, set the REDO_READ10 | ||
828 | * flag to force a retry. | ||
829 | */ | ||
830 | if (unlikely((us->fflags & US_FL_INITIAL_READ10) && | ||
831 | srb->cmnd[0] == READ_10)) { | ||
832 | if (srb->result == SAM_STAT_GOOD) { | ||
833 | set_bit(US_FLIDX_READ10_WORKED, &us->dflags); | ||
834 | } else if (test_bit(US_FLIDX_READ10_WORKED, &us->dflags)) { | ||
835 | clear_bit(US_FLIDX_READ10_WORKED, &us->dflags); | ||
836 | set_bit(US_FLIDX_REDO_READ10, &us->dflags); | ||
837 | } | ||
838 | |||
839 | /* | ||
840 | * Next, if the REDO_READ10 flag is set, return a result | ||
841 | * code that will cause the SCSI core to retry the READ(10) | ||
842 | * command immediately. | ||
843 | */ | ||
844 | if (test_bit(US_FLIDX_REDO_READ10, &us->dflags)) { | ||
845 | clear_bit(US_FLIDX_REDO_READ10, &us->dflags); | ||
846 | srb->result = DID_IMM_RETRY << 16; | ||
847 | srb->sense_buffer[0] = 0; | ||
848 | } | ||
849 | } | ||
850 | |||
822 | /* Did we transfer less than the minimum amount required? */ | 851 | /* Did we transfer less than the minimum amount required? */ |
823 | if ((srb->result == SAM_STAT_GOOD || srb->sense_buffer[2] == 0) && | 852 | if ((srb->result == SAM_STAT_GOOD || srb->sense_buffer[2] == 0) && |
824 | scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow) | 853 | scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow) |