diff options
-rw-r--r-- | drivers/ata/libata-zpodd.c | 7 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 14 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 10 | ||||
-rw-r--r-- | include/scsi/scsi_device.h | 4 |
4 files changed, 32 insertions, 3 deletions
diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c index 540b0b7904f..a7df6038353 100644 --- a/drivers/ata/libata-zpodd.c +++ b/drivers/ata/libata-zpodd.c @@ -178,11 +178,16 @@ bool zpodd_zpready(struct ata_device *dev) * Enable runtime wake capability through ACPI and set the powered_off flag, * this flag will be used during resume to decide what operations are needed * to take. + * + * Also, media poll needs to be silenced, so that it doesn't bring the ODD + * back to full power state every few seconds. */ void zpodd_enable_run_wake(struct ata_device *dev) { struct zpodd *zpodd = dev->zpodd; + sdev_disable_disk_events(dev->sdev); + zpodd->powered_off = true; device_set_run_wake(&dev->sdev->sdev_gendev, true); acpi_pm_device_run_wake(&dev->sdev->sdev_gendev, true); @@ -231,6 +236,8 @@ void zpodd_post_poweron(struct ata_device *dev) zpodd->zp_sampled = false; zpodd->zp_ready = false; + + sdev_enable_disk_events(dev->sdev); } static void zpodd_wake_dev(acpi_handle handle, u32 event, void *context) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index f1bf5aff68e..765398c063c 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2617,3 +2617,17 @@ void scsi_kunmap_atomic_sg(void *virt) kunmap_atomic(virt); } EXPORT_SYMBOL(scsi_kunmap_atomic_sg); + +void sdev_disable_disk_events(struct scsi_device *sdev) +{ + atomic_inc(&sdev->disk_events_disable_depth); +} +EXPORT_SYMBOL(sdev_disable_disk_events); + +void sdev_enable_disk_events(struct scsi_device *sdev) +{ + if (WARN_ON_ONCE(atomic_read(&sdev->disk_events_disable_depth) <= 0)) + return; + atomic_dec(&sdev->disk_events_disable_depth); +} +EXPORT_SYMBOL(sdev_enable_disk_events); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 2e8ddd77366..f2884ee9071 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -602,9 +602,13 @@ static unsigned int sr_block_check_events(struct gendisk *disk, struct scsi_cd *cd = scsi_cd(disk); unsigned int ret; - scsi_autopm_get_device(cd->device); - ret = cdrom_check_events(&cd->cdi, clearing); - scsi_autopm_put_device(cd->device); + if (atomic_read(&cd->device->disk_events_disable_depth) == 0) { + scsi_autopm_get_device(cd->device); + ret = cdrom_check_events(&cd->cdi, clearing); + scsi_autopm_put_device(cd->device); + } else { + ret = 0; + } return ret; } diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index e65c62e82c5..bb1371bf171 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -161,6 +161,8 @@ struct scsi_device { unsigned wce_default_on:1; /* Cache is ON by default */ unsigned no_dif:1; /* T10 PI (DIF) should be disabled */ + atomic_t disk_events_disable_depth; /* disable depth for disk events */ + DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ struct list_head event_list; /* asserted events */ struct work_struct event_work; @@ -397,6 +399,8 @@ extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, struct scsi_sense_hdr *, int timeout, int retries, int *resid); +extern void sdev_disable_disk_events(struct scsi_device *sdev); +extern void sdev_enable_disk_events(struct scsi_device *sdev); #ifdef CONFIG_PM_RUNTIME extern int scsi_autopm_get_device(struct scsi_device *); |