diff options
author | Kay Sievers <kay.sievers@vrfy.org> | 2007-08-14 08:10:39 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-11 19:22:30 -0500 |
commit | 285e9670d91cdeb6b6693729950339cb45410fdc (patch) | |
tree | 5edd3f6d19ca92b408ed07daa85cc0361a7a9a72 | |
parent | d0c4c9d4a2e46f052178806c4004d52cd3ae040f (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.c | 24 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 14 | ||||
-rw-r--r-- | drivers/scsi/sr.h | 1 | ||||
-rw-r--r-- | include/scsi/sd.h | 1 |
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 | 793 | out: | |
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 | |||
789 | not_present: | ||
790 | set_media_not_present(sdkp); | ||
791 | return 1; | ||
792 | } | 798 | } |
793 | 799 | ||
794 | static int sd_sync_cache(struct scsi_disk *sdkp) | 800 | static 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 | |||
210 | out: | ||
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 */ |