From ad333f5b7b7cf035b6aaa92b3fa7492bdfaa5c01 Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Wed, 23 Jan 2013 15:09:32 +0800 Subject: [PATCH] --- yaml --- r: 356958 b: refs/heads/master c: 6f4c827e68a78731c6c75df69bf7b75b029ec70c h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/ata/libata-zpodd.c | 7 +++++++ trunk/drivers/scsi/scsi_lib.c | 14 ++++++++++++++ trunk/drivers/scsi/sr.c | 10 +++++++--- trunk/include/scsi/scsi_device.h | 4 ++++ 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index dc17360d53e8..8961083995ee 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6c7f1e2f12f6f37ddda01180c9e5c407eccce616 +refs/heads/master: 6f4c827e68a78731c6c75df69bf7b75b029ec70c diff --git a/trunk/drivers/ata/libata-zpodd.c b/trunk/drivers/ata/libata-zpodd.c index 540b0b7904fb..a7df60383532 100644 --- a/trunk/drivers/ata/libata-zpodd.c +++ b/trunk/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/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index f1bf5aff68ed..765398c063c7 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/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/trunk/drivers/scsi/sr.c b/trunk/drivers/scsi/sr.c index 2e8ddd77366f..f2884ee90710 100644 --- a/trunk/drivers/scsi/sr.c +++ b/trunk/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/trunk/include/scsi/scsi_device.h b/trunk/include/scsi/scsi_device.h index e65c62e82c5a..bb1371bf171d 100644 --- a/trunk/include/scsi/scsi_device.h +++ b/trunk/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 *);