aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2007-08-14 08:10:39 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:22:30 -0500
commit285e9670d91cdeb6b6693729950339cb45410fdc (patch)
tree5edd3f6d19ca92b408ed07daa85cc0361a7a9a72
parentd0c4c9d4a2e46f052178806c4004d52cd3ae040f (diff)
[SCSI] sr,sd: send media state change modification events
This will send for a card reader slot (remove/add media): UEVENT[1187091572.155884] change /devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/host7/target7:0:0/7:0:0:0 (scsi) UEVENT[1187091572.162314] remove /block/sdb/sdb1 (block) UEVENT[1187091572.172464] add /block/sdb/sdb1 (block) UEVENT[1187091572.175408] change /devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/host7/target7:0:0/7:0:0:0 (scsi) and for a DVD drive (add/eject media): UEVENT[1187091590.189159] change /devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0 (scsi) UEVENT[1187091590.957124] add /module/isofs (module) UEVENT[1187091604.468207] change /devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0 (scsi) Userspace gets events, even for unpartitioned media. This unifies the event handling for asynchronoous events (AN) and events caused by perodical polling the device from userspace. Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> [jejb: modified for new event API] Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/sd.c24
-rw-r--r--drivers/scsi/sr.c14
-rw-r--r--drivers/scsi/sr.h1
-rw-r--r--include/scsi/sd.h1
4 files changed, 28 insertions, 12 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index a69b155f39a2..18343a6acd8e 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -749,8 +749,11 @@ static int sd_media_changed(struct gendisk *disk)
749 * can deal with it then. It is only because of unrecoverable errors 749 * 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. 750 * that we would ever take a device offline in the first place.
751 */ 751 */
752 if (!scsi_device_online(sdp)) 752 if (!scsi_device_online(sdp)) {
753 goto not_present; 753 set_media_not_present(sdkp);
754 retval = 1;
755 goto out;
756 }
754 757
755 /* 758 /*
756 * Using TEST_UNIT_READY enables differentiation between drive with 759 * Using TEST_UNIT_READY enables differentiation between drive with
@@ -762,6 +765,7 @@ static int sd_media_changed(struct gendisk *disk)
762 * sd_revalidate() is called. 765 * sd_revalidate() is called.
763 */ 766 */
764 retval = -ENODEV; 767 retval = -ENODEV;
768
765 if (scsi_block_when_processing_errors(sdp)) 769 if (scsi_block_when_processing_errors(sdp))
766 retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES); 770 retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES);
767 771
@@ -771,8 +775,11 @@ static int sd_media_changed(struct gendisk *disk)
771 * and we will figure it out later once the drive is 775 * and we will figure it out later once the drive is
772 * available again. 776 * available again.
773 */ 777 */
774 if (retval) 778 if (retval) {
775 goto not_present; 779 set_media_not_present(sdkp);
780 retval = 1;
781 goto out;
782 }
776 783
777 /* 784 /*
778 * For removable scsi disk we have to recognise the presence 785 * For removable scsi disk we have to recognise the presence
@@ -783,12 +790,11 @@ static int sd_media_changed(struct gendisk *disk)
783 790
784 retval = sdp->changed; 791 retval = sdp->changed;
785 sdp->changed = 0; 792 sdp->changed = 0;
786 793out:
794 if (retval != sdkp->previous_state)
795 sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL);
796 sdkp->previous_state = retval;
787 return retval; 797 return retval;
788
789not_present:
790 set_media_not_present(sdkp);
791 return 1;
792} 798}
793 799
794static int sd_sync_cache(struct scsi_disk *sdkp) 800static int sd_sync_cache(struct scsi_disk *sdkp)
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index c61999031141..7702681d93f9 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -192,8 +192,9 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot)
192 * and we will figure it out later once the drive is 192 * and we will figure it out later once the drive is
193 * available again. */ 193 * available again. */
194 cd->device->changed = 1; 194 cd->device->changed = 1;
195 return 1; /* This will force a flush, if called from 195 /* This will force a flush, if called from check_disk_change */
196 * check_disk_change */ 196 retval = 1;
197 goto out;
197 }; 198 };
198 199
199 retval = cd->device->changed; 200 retval = cd->device->changed;
@@ -203,9 +204,16 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot)
203 if (retval) { 204 if (retval) {
204 /* check multisession offset etc */ 205 /* check multisession offset etc */
205 sr_cd_check(cdi); 206 sr_cd_check(cdi);
206
207 get_sectorsize(cd); 207 get_sectorsize(cd);
208 } 208 }
209
210out:
211 /* Notify userspace, that media has changed. */
212 if (retval != cd->previous_state)
213 sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE,
214 GFP_KERNEL);
215 cd->previous_state = retval;
216
209 return retval; 217 return retval;
210} 218}
211 219
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h
index d65de9621b27..0d04e2878c9d 100644
--- a/drivers/scsi/sr.h
+++ b/drivers/scsi/sr.h
@@ -37,6 +37,7 @@ typedef struct scsi_cd {
37 unsigned xa_flag:1; /* CD has XA sectors ? */ 37 unsigned xa_flag:1; /* CD has XA sectors ? */
38 unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */ 38 unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */
39 unsigned readcd_cdda:1; /* reading audio data using READ_CD */ 39 unsigned readcd_cdda:1; /* reading audio data using READ_CD */
40 unsigned previous_state:1; /* media has changed */
40 struct cdrom_device_info cdi; 41 struct cdrom_device_info cdi;
41 /* We hold gendisk and scsi_device references on probe and use 42 /* We hold gendisk and scsi_device references on probe and use
42 * the refs on this kref to decide when to release them */ 43 * the refs on this kref to decide when to release them */
diff --git a/include/scsi/sd.h b/include/scsi/sd.h
index f7513313ef0d..8ea9f7358ac1 100644
--- a/include/scsi/sd.h
+++ b/include/scsi/sd.h
@@ -41,6 +41,7 @@ struct scsi_disk {
41 u32 index; 41 u32 index;
42 u8 media_present; 42 u8 media_present;
43 u8 write_prot; 43 u8 write_prot;
44 unsigned previous_state : 1;
44 unsigned WCE : 1; /* state of disk WCE bit */ 45 unsigned WCE : 1; /* state of disk WCE bit */
45 unsigned RCD : 1; /* state of disk RCD bit, unused */ 46 unsigned RCD : 1; /* state of disk RCD bit, unused */
46 unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ 47 unsigned DPOFUA : 1; /* state of disk DPOFUA bit */