Re-introduce "[SCSI] extend the last_sector_bug flag to cover more sectors"
This re-introduces commit2b14290078
, which was reverted due to the regression it caused by commitfca082c9f1
. That regression was not root-caused by the original commit, it was just uncovered by it, and the real fix was done by Alan Stern in commit580da34847
("Fix USB storage hang on command abort"). We can thus re-introduce the change that was confirmed by Alan Jenkins to be still required by his odd card reader. Cc: Alan Jenkins <alan-jenkins@tuffmail.co.uk> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
@@ -375,6 +375,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
|
||||
struct gendisk *disk = rq->rq_disk;
|
||||
struct scsi_disk *sdkp;
|
||||
sector_t block = rq->sector;
|
||||
sector_t threshold;
|
||||
unsigned int this_count = rq->nr_sectors;
|
||||
unsigned int timeout = sdp->timeout;
|
||||
int ret;
|
||||
@@ -422,13 +423,21 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
|
||||
}
|
||||
|
||||
/*
|
||||
* Some devices (some sdcards for one) don't like it if the
|
||||
* last sector gets read in a larger then 1 sector read.
|
||||
* Some SD card readers can't handle multi-sector accesses which touch
|
||||
* the last one or two hardware sectors. Split accesses as needed.
|
||||
*/
|
||||
if (unlikely(sdp->last_sector_bug &&
|
||||
rq->nr_sectors > sdp->sector_size / 512 &&
|
||||
block + this_count == get_capacity(disk)))
|
||||
this_count -= sdp->sector_size / 512;
|
||||
threshold = get_capacity(disk) - SD_LAST_BUGGY_SECTORS *
|
||||
(sdp->sector_size / 512);
|
||||
|
||||
if (unlikely(sdp->last_sector_bug && block + this_count > threshold)) {
|
||||
if (block < threshold) {
|
||||
/* Access up to the threshold but not beyond */
|
||||
this_count = threshold - block;
|
||||
} else {
|
||||
/* Access only a single hardware sector */
|
||||
this_count = sdp->sector_size / 512;
|
||||
}
|
||||
}
|
||||
|
||||
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n",
|
||||
(unsigned long long)block));
|
||||
|
Reference in New Issue
Block a user