diff options
author | James Bottomley <James.Bottomley@SteelEye.com> | 2007-12-02 12:10:40 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-11 19:22:50 -0500 |
commit | 001aac257cf8adbe90cdcba6e07f8d12dfc8fa6b (patch) | |
tree | 0eb6294049245e05f47fdb76e3f878c78c015d88 /drivers/scsi/sd.c | |
parent | 4a03d90e35bc5273d27301fa669d4b2103196f94 (diff) |
[SCSI] sd,sr: add early detection of medium not present
The current scsi_test_unit_ready() is updated to return sense code
information (in struct scsi_sense_hdr). The sd and sr drivers are
changed to interpret the sense code return asc 0x3a as no media and
adjust the device status accordingly.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 18343a6acd8e..212f6bcfd457 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -736,6 +736,7 @@ static int sd_media_changed(struct gendisk *disk) | |||
736 | { | 736 | { |
737 | struct scsi_disk *sdkp = scsi_disk(disk); | 737 | struct scsi_disk *sdkp = scsi_disk(disk); |
738 | struct scsi_device *sdp = sdkp->device; | 738 | struct scsi_device *sdp = sdkp->device; |
739 | struct scsi_sense_hdr *sshdr = NULL; | ||
739 | int retval; | 740 | int retval; |
740 | 741 | ||
741 | SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n")); | 742 | SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n")); |
@@ -766,8 +767,11 @@ static int sd_media_changed(struct gendisk *disk) | |||
766 | */ | 767 | */ |
767 | retval = -ENODEV; | 768 | retval = -ENODEV; |
768 | 769 | ||
769 | if (scsi_block_when_processing_errors(sdp)) | 770 | if (scsi_block_when_processing_errors(sdp)) { |
770 | retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES); | 771 | sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); |
772 | retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES, | ||
773 | sshdr); | ||
774 | } | ||
771 | 775 | ||
772 | /* | 776 | /* |
773 | * Unable to test, unit probably not ready. This usually | 777 | * Unable to test, unit probably not ready. This usually |
@@ -775,7 +779,9 @@ static int sd_media_changed(struct gendisk *disk) | |||
775 | * and we will figure it out later once the drive is | 779 | * and we will figure it out later once the drive is |
776 | * available again. | 780 | * available again. |
777 | */ | 781 | */ |
778 | if (retval) { | 782 | if (retval || (scsi_sense_valid(sshdr) && |
783 | /* 0x3a is medium not present */ | ||
784 | sshdr->asc == 0x3a)) { | ||
779 | set_media_not_present(sdkp); | 785 | set_media_not_present(sdkp); |
780 | retval = 1; | 786 | retval = 1; |
781 | goto out; | 787 | goto out; |
@@ -794,6 +800,7 @@ out: | |||
794 | if (retval != sdkp->previous_state) | 800 | if (retval != sdkp->previous_state) |
795 | sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL); | 801 | sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL); |
796 | sdkp->previous_state = retval; | 802 | sdkp->previous_state = retval; |
803 | kfree(sshdr); | ||
797 | return retval; | 804 | return retval; |
798 | } | 805 | } |
799 | 806 | ||