Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Re-introduce "[SCSI] extend the last_sector_bug flag to cover more sectors"

This re-introduces commit 2b142900784c6e38c8d39fa57d5f95ef08e735d8,
which was reverted due to the regression it caused by commit
fca082c9f1e11ec07efa8d2f9f13688521253f36.

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 commit
580da34847488b404218d1d7f53b156f245f5555 ("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>

+23 -7
+15 -6
drivers/scsi/sd.c
··· 375 375 struct gendisk *disk = rq->rq_disk; 376 376 struct scsi_disk *sdkp; 377 377 sector_t block = rq->sector; 378 + sector_t threshold; 378 379 unsigned int this_count = rq->nr_sectors; 379 380 unsigned int timeout = sdp->timeout; 380 381 int ret; ··· 423 422 } 424 423 425 424 /* 426 - * Some devices (some sdcards for one) don't like it if the 427 - * last sector gets read in a larger then 1 sector read. 425 + * Some SD card readers can't handle multi-sector accesses which touch 426 + * the last one or two hardware sectors. Split accesses as needed. 428 427 */ 429 - if (unlikely(sdp->last_sector_bug && 430 - rq->nr_sectors > sdp->sector_size / 512 && 431 - block + this_count == get_capacity(disk))) 432 - this_count -= sdp->sector_size / 512; 428 + threshold = get_capacity(disk) - SD_LAST_BUGGY_SECTORS * 429 + (sdp->sector_size / 512); 430 + 431 + if (unlikely(sdp->last_sector_bug && block + this_count > threshold)) { 432 + if (block < threshold) { 433 + /* Access up to the threshold but not beyond */ 434 + this_count = threshold - block; 435 + } else { 436 + /* Access only a single hardware sector */ 437 + this_count = sdp->sector_size / 512; 438 + } 439 + } 433 440 434 441 SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", 435 442 (unsigned long long)block));
+6
drivers/scsi/sd.h
··· 31 31 */ 32 32 #define SD_BUF_SIZE 512 33 33 34 + /* 35 + * Number of sectors at the end of the device to avoid multi-sector 36 + * accesses to in the case of last_sector_bug 37 + */ 38 + #define SD_LAST_BUGGY_SECTORS 8 39 + 34 40 struct scsi_disk { 35 41 struct scsi_driver *driver; /* always &sd_template */ 36 42 struct scsi_device *device;
+2 -1
include/scsi/scsi_device.h
··· 140 140 unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ 141 141 unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */ 142 142 unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ 143 - unsigned last_sector_bug:1; /* Always read last sector in a 1 sector read */ 143 + unsigned last_sector_bug:1; /* do not use multisector accesses on 144 + SD_LAST_BUGGY_SECTORS */ 144 145 145 146 DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ 146 147 struct list_head event_list; /* asserted events */