aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-zpodd.c7
-rw-r--r--drivers/scsi/scsi_lib.c14
-rw-r--r--drivers/scsi/sr.c10
-rw-r--r--include/scsi/scsi_device.h4
4 files changed, 32 insertions, 3 deletions
diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c
index 540b0b7904fb..a7df60383532 100644
--- a/drivers/ata/libata-zpodd.c
+++ b/drivers/ata/libata-zpodd.c
@@ -178,11 +178,16 @@ bool zpodd_zpready(struct ata_device *dev)
178 * Enable runtime wake capability through ACPI and set the powered_off flag, 178 * Enable runtime wake capability through ACPI and set the powered_off flag,
179 * this flag will be used during resume to decide what operations are needed 179 * this flag will be used during resume to decide what operations are needed
180 * to take. 180 * to take.
181 *
182 * Also, media poll needs to be silenced, so that it doesn't bring the ODD
183 * back to full power state every few seconds.
181 */ 184 */
182void zpodd_enable_run_wake(struct ata_device *dev) 185void zpodd_enable_run_wake(struct ata_device *dev)
183{ 186{
184 struct zpodd *zpodd = dev->zpodd; 187 struct zpodd *zpodd = dev->zpodd;
185 188
189 sdev_disable_disk_events(dev->sdev);
190
186 zpodd->powered_off = true; 191 zpodd->powered_off = true;
187 device_set_run_wake(&dev->sdev->sdev_gendev, true); 192 device_set_run_wake(&dev->sdev->sdev_gendev, true);
188 acpi_pm_device_run_wake(&dev->sdev->sdev_gendev, true); 193 acpi_pm_device_run_wake(&dev->sdev->sdev_gendev, true);
@@ -231,6 +236,8 @@ void zpodd_post_poweron(struct ata_device *dev)
231 236
232 zpodd->zp_sampled = false; 237 zpodd->zp_sampled = false;
233 zpodd->zp_ready = false; 238 zpodd->zp_ready = false;
239
240 sdev_enable_disk_events(dev->sdev);
234} 241}
235 242
236static void zpodd_wake_dev(acpi_handle handle, u32 event, void *context) 243static 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 f1bf5aff68ed..765398c063c7 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2617,3 +2617,17 @@ void scsi_kunmap_atomic_sg(void *virt)
2617 kunmap_atomic(virt); 2617 kunmap_atomic(virt);
2618} 2618}
2619EXPORT_SYMBOL(scsi_kunmap_atomic_sg); 2619EXPORT_SYMBOL(scsi_kunmap_atomic_sg);
2620
2621void sdev_disable_disk_events(struct scsi_device *sdev)
2622{
2623 atomic_inc(&sdev->disk_events_disable_depth);
2624}
2625EXPORT_SYMBOL(sdev_disable_disk_events);
2626
2627void sdev_enable_disk_events(struct scsi_device *sdev)
2628{
2629 if (WARN_ON_ONCE(atomic_read(&sdev->disk_events_disable_depth) <= 0))
2630 return;
2631 atomic_dec(&sdev->disk_events_disable_depth);
2632}
2633EXPORT_SYMBOL(sdev_enable_disk_events);
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 2e8ddd77366f..f2884ee90710 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,
602 struct scsi_cd *cd = scsi_cd(disk); 602 struct scsi_cd *cd = scsi_cd(disk);
603 unsigned int ret; 603 unsigned int ret;
604 604
605 scsi_autopm_get_device(cd->device); 605 if (atomic_read(&cd->device->disk_events_disable_depth) == 0) {
606 ret = cdrom_check_events(&cd->cdi, clearing); 606 scsi_autopm_get_device(cd->device);
607 scsi_autopm_put_device(cd->device); 607 ret = cdrom_check_events(&cd->cdi, clearing);
608 scsi_autopm_put_device(cd->device);
609 } else {
610 ret = 0;
611 }
608 612
609 return ret; 613 return ret;
610} 614}
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index e65c62e82c5a..bb1371bf171d 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -161,6 +161,8 @@ struct scsi_device {
161 unsigned wce_default_on:1; /* Cache is ON by default */ 161 unsigned wce_default_on:1; /* Cache is ON by default */
162 unsigned no_dif:1; /* T10 PI (DIF) should be disabled */ 162 unsigned no_dif:1; /* T10 PI (DIF) should be disabled */
163 163
164 atomic_t disk_events_disable_depth; /* disable depth for disk events */
165
164 DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ 166 DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
165 struct list_head event_list; /* asserted events */ 167 struct list_head event_list; /* asserted events */
166 struct work_struct event_work; 168 struct work_struct event_work;
@@ -397,6 +399,8 @@ extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
397 int data_direction, void *buffer, unsigned bufflen, 399 int data_direction, void *buffer, unsigned bufflen,
398 struct scsi_sense_hdr *, int timeout, int retries, 400 struct scsi_sense_hdr *, int timeout, int retries,
399 int *resid); 401 int *resid);
402extern void sdev_disable_disk_events(struct scsi_device *sdev);
403extern void sdev_enable_disk_events(struct scsi_device *sdev);
400 404
401#ifdef CONFIG_PM_RUNTIME 405#ifdef CONFIG_PM_RUNTIME
402extern int scsi_autopm_get_device(struct scsi_device *); 406extern int scsi_autopm_get_device(struct scsi_device *);