Revert "scsi: sd: remove check_events callback"

This reverts commit fe64842c81.
On auto platforms, it is observed that sdcard is not getting
detected using usb card reader as check_events callback was
removed. For usb card reader case, scsi check_events() callback
is required which sends test unit ready command to check if
underlying media state has changed. So instead of removing
check_events() completely, simply return for embedded storage
media like UFS.

Change-Id: Iefd163db1a1098c01c2dbaf441f072b07b19caca
Signed-off-by: Sayali Lokhande <sayalil@codeaurora.org>
This commit is contained in:
Sayali Lokhande 2018-05-24 16:18:41 +05:30
parent c43f38b61e
commit cee071276c

View file

@ -1420,6 +1420,85 @@ static int media_not_present(struct scsi_disk *sdkp,
return 0;
}
/**
* sd_check_events - check media events
* @disk: kernel device descriptor
* @clearing: disk events currently being cleared
*
* Returns mask of DISK_EVENT_*.
*
* Note: this function is invoked from the block subsystem.
**/
static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
{
struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdp = sdkp->device;
struct scsi_sense_hdr *sshdr = NULL;
int retval;
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n"));
/* Simply return for embedded storage media such as UFS */
if (!sdp->removable)
goto out;
/*
* If the device is offline, don't send any commands - just pretend as
* if the command failed. If the device ever comes back online, we
* 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)) {
set_media_not_present(sdkp);
goto out;
}
/*
* Using TEST_UNIT_READY enables differentiation between drive with
* no cartridge loaded - NOT READY, drive with changed cartridge -
* UNIT ATTENTION, or with same cartridge - GOOD STATUS.
*
* Drives that auto spin down. eg iomega jaz 1G, will be started
* by sd_spinup_disk() from sd_revalidate_disk(), which happens whenever
* sd_revalidate() is called.
*/
retval = -ENODEV;
if (scsi_block_when_processing_errors(sdp)) {
sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL);
retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES,
sshdr);
}
/* failed to execute TUR, assume media not present */
if (host_byte(retval)) {
set_media_not_present(sdkp);
goto out;
}
if (media_not_present(sdkp, sshdr))
goto out;
/*
* For removable scsi disk we have to recognise the presence
* of a disk in the drive.
*/
if (!sdkp->media_present)
sdp->changed = 1;
sdkp->media_present = 1;
out:
/*
* sdp->changed is set under the following conditions:
*
* Medium present state has changed in either direction.
* Device has indicated UNIT_ATTENTION.
*/
kfree(sshdr);
retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0;
sdp->changed = 0;
return retval;
}
static int sd_sync_cache(struct scsi_disk *sdkp)
{
int retries, res;
@ -1612,6 +1691,7 @@ static const struct block_device_operations sd_fops = {
#ifdef CONFIG_COMPAT
.compat_ioctl = sd_compat_ioctl,
#endif
.check_events = sd_check_events,
.revalidate_disk = sd_revalidate_disk,
.unlock_native_capacity = sd_unlock_native_capacity,
.pr_ops = &sd_pr_ops,