forked from mirrors/linux
		
	[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>
This commit is contained in:
		
							parent
							
								
									d0c4c9d4a2
								
							
						
					
					
						commit
						285e9670d9
					
				
					 4 changed files with 28 additions and 12 deletions
				
			
		|  | @ -749,8 +749,11 @@ static int sd_media_changed(struct gendisk *disk) | |||
| 	 * can deal with it then.  It is only because of unrecoverable errors | ||||
| 	 * that we would ever take a device offline in the first place. | ||||
| 	 */ | ||||
| 	if (!scsi_device_online(sdp)) | ||||
| 		goto not_present; | ||||
| 	if (!scsi_device_online(sdp)) { | ||||
| 		set_media_not_present(sdkp); | ||||
| 		retval = 1; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Using TEST_UNIT_READY enables differentiation between drive with | ||||
|  | @ -762,6 +765,7 @@ static int sd_media_changed(struct gendisk *disk) | |||
| 	 * sd_revalidate() is called. | ||||
| 	 */ | ||||
| 	retval = -ENODEV; | ||||
| 
 | ||||
| 	if (scsi_block_when_processing_errors(sdp)) | ||||
| 		retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES); | ||||
| 
 | ||||
|  | @ -771,8 +775,11 @@ static int sd_media_changed(struct gendisk *disk) | |||
| 	 * and we will figure it out later once the drive is | ||||
| 	 * available again. | ||||
| 	 */ | ||||
| 	if (retval) | ||||
| 		 goto not_present; | ||||
| 	if (retval) { | ||||
| 		set_media_not_present(sdkp); | ||||
| 		retval = 1; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * For removable scsi disk we have to recognise the presence | ||||
|  | @ -783,12 +790,11 @@ static int sd_media_changed(struct gendisk *disk) | |||
| 
 | ||||
| 	retval = sdp->changed; | ||||
| 	sdp->changed = 0; | ||||
| 
 | ||||
| out: | ||||
| 	if (retval != sdkp->previous_state) | ||||
| 		sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL); | ||||
| 	sdkp->previous_state = retval; | ||||
| 	return retval; | ||||
| 
 | ||||
| not_present: | ||||
| 	set_media_not_present(sdkp); | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static int sd_sync_cache(struct scsi_disk *sdkp) | ||||
|  |  | |||
|  | @ -192,8 +192,9 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) | |||
| 		 * and we will figure it out later once the drive is | ||||
| 		 * available again.  */ | ||||
| 		cd->device->changed = 1; | ||||
| 		return 1;	/* This will force a flush, if called from
 | ||||
| 				 * check_disk_change */ | ||||
| 		/* This will force a flush, if called from check_disk_change */ | ||||
| 		retval = 1; | ||||
| 		goto out; | ||||
| 	}; | ||||
| 
 | ||||
| 	retval = cd->device->changed; | ||||
|  | @ -203,9 +204,16 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) | |||
| 	if (retval) { | ||||
| 		/* check multisession offset etc */ | ||||
| 		sr_cd_check(cdi); | ||||
| 
 | ||||
| 		get_sectorsize(cd); | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	/* Notify userspace, that media has changed. */ | ||||
| 	if (retval != cd->previous_state) | ||||
| 		sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE, | ||||
| 				     GFP_KERNEL); | ||||
| 	cd->previous_state = retval; | ||||
| 
 | ||||
| 	return retval; | ||||
| } | ||||
|   | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ typedef struct scsi_cd { | |||
| 	unsigned xa_flag:1;	/* CD has XA sectors ? */ | ||||
| 	unsigned readcd_known:1;	/* drive supports READ_CD (0xbe) */ | ||||
| 	unsigned readcd_cdda:1;	/* reading audio data using READ_CD */ | ||||
| 	unsigned previous_state:1;	/* media has changed */ | ||||
| 	struct cdrom_device_info cdi; | ||||
| 	/* We hold gendisk and scsi_device references on probe and use
 | ||||
| 	 * the refs on this kref to decide when to release them */ | ||||
|  |  | |||
|  | @ -41,6 +41,7 @@ struct scsi_disk { | |||
| 	u32		index; | ||||
| 	u8		media_present; | ||||
| 	u8		write_prot; | ||||
| 	unsigned	previous_state : 1; | ||||
| 	unsigned	WCE : 1;	/* state of disk WCE bit */ | ||||
| 	unsigned	RCD : 1;	/* state of disk RCD bit, unused */ | ||||
| 	unsigned	DPOFUA : 1;	/* state of disk DPOFUA bit */ | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Kay Sievers
						Kay Sievers