aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index a69b155f39a2..24eba3118b5a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -395,6 +395,15 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
395 goto out; 395 goto out;
396 } 396 }
397 397
398 /*
399 * Some devices (some sdcards for one) don't like it if the
400 * last sector gets read in a larger then 1 sector read.
401 */
402 if (unlikely(sdp->last_sector_bug &&
403 rq->nr_sectors > sdp->sector_size / 512 &&
404 block + this_count == get_capacity(disk)))
405 this_count -= sdp->sector_size / 512;
406
398 SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", 407 SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n",
399 (unsigned long long)block)); 408 (unsigned long long)block));
400 409
@@ -736,6 +745,7 @@ static int sd_media_changed(struct gendisk *disk)
736{ 745{
737 struct scsi_disk *sdkp = scsi_disk(disk); 746 struct scsi_disk *sdkp = scsi_disk(disk);
738 struct scsi_device *sdp = sdkp->device; 747 struct scsi_device *sdp = sdkp->device;
748 struct scsi_sense_hdr *sshdr = NULL;
739 int retval; 749 int retval;
740 750
741 SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n")); 751 SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n"));
@@ -749,8 +759,11 @@ static int sd_media_changed(struct gendisk *disk)
749 * can deal with it then. It is only because of unrecoverable errors 759 * can deal with it then. It is only because of unrecoverable errors
750 * that we would ever take a device offline in the first place. 760 * that we would ever take a device offline in the first place.
751 */ 761 */
752 if (!scsi_device_online(sdp)) 762 if (!scsi_device_online(sdp)) {
753 goto not_present; 763 set_media_not_present(sdkp);
764 retval = 1;
765 goto out;
766 }
754 767
755 /* 768 /*
756 * Using TEST_UNIT_READY enables differentiation between drive with 769 * Using TEST_UNIT_READY enables differentiation between drive with
@@ -762,8 +775,12 @@ static int sd_media_changed(struct gendisk *disk)
762 * sd_revalidate() is called. 775 * sd_revalidate() is called.
763 */ 776 */
764 retval = -ENODEV; 777 retval = -ENODEV;
765 if (scsi_block_when_processing_errors(sdp)) 778
766 retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES); 779 if (scsi_block_when_processing_errors(sdp)) {
780 sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL);
781 retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES,
782 sshdr);
783 }
767 784
768 /* 785 /*
769 * Unable to test, unit probably not ready. This usually 786 * Unable to test, unit probably not ready. This usually
@@ -771,8 +788,13 @@ static int sd_media_changed(struct gendisk *disk)
771 * and we will figure it out later once the drive is 788 * and we will figure it out later once the drive is
772 * available again. 789 * available again.
773 */ 790 */
774 if (retval) 791 if (retval || (scsi_sense_valid(sshdr) &&
775 goto not_present; 792 /* 0x3a is medium not present */
793 sshdr->asc == 0x3a)) {
794 set_media_not_present(sdkp);
795 retval = 1;
796 goto out;
797 }
776 798
777 /* 799 /*
778 * For removable scsi disk we have to recognise the presence 800 * For removable scsi disk we have to recognise the presence
@@ -783,12 +805,12 @@ static int sd_media_changed(struct gendisk *disk)
783 805
784 retval = sdp->changed; 806 retval = sdp->changed;
785 sdp->changed = 0; 807 sdp->changed = 0;
786 808out:
809 if (retval != sdkp->previous_state)
810 sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL);
811 sdkp->previous_state = retval;
812 kfree(sshdr);
787 return retval; 813 return retval;
788
789not_present:
790 set_media_not_present(sdkp);
791 return 1;
792} 814}
793 815
794static int sd_sync_cache(struct scsi_disk *sdkp) 816static int sd_sync_cache(struct scsi_disk *sdkp)