From patchwork Tue Jan 15 09:20:57 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lu X-Patchwork-Id: 212048 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 495EC2C00A6 for ; Tue, 15 Jan 2013 20:21:00 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756599Ab3AOJUb (ORCPT ); Tue, 15 Jan 2013 04:20:31 -0500 Received: from mga01.intel.com ([192.55.52.88]:29538 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756644Ab3AOJUY (ORCPT ); Tue, 15 Jan 2013 04:20:24 -0500 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 15 Jan 2013 01:20:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.84,473,1355126400"; d="scan'208";a="273895847" Received: from aaronlu.sh.intel.com ([10.239.36.111]) by fmsmga001.fm.intel.com with ESMTP; 15 Jan 2013 01:20:21 -0800 From: Aaron Lu To: Jeff Garzik , James Bottomley , "Rafael J. Wysocki" , Alan Stern , Tejun Heo Cc: Aaron Lu , Jeff Wu , linux-ide@vger.kernel.org, linux-pm@vger.kernel.org, linux-scsi@vger.kernel.org, linux-acpi@vger.kernel.org Subject: [PATCH v13 1/9] scsi: sr: support runtime pm Date: Tue, 15 Jan 2013 17:20:57 +0800 Message-Id: <1358241665-2156-2-git-send-email-aaron.lu@intel.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1358241665-2156-1-git-send-email-aaron.lu@intel.com> References: <1358241665-2156-1-git-send-email-aaron.lu@intel.com> Sender: linux-ide-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ide@vger.kernel.org This patch adds runtime pm support for sr. It did this by increasing the runtime usage_count of the device when: - its block device is opened; - the events checking is to run. And decreasing the runtime usage_count of the device when: - its block device is closed; - After the events checking is done. The idea is discussed in this mail thread: http://thread.gmane.org/gmane.linux.acpi.devel/55243/focus=52703 Signed-off-by: Aaron Lu --- drivers/scsi/sr.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 5fc97d2..4d1a610 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -146,7 +147,8 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk) kref_get(&cd->kref); if (scsi_device_get(cd->device)) goto out_put; - goto out; + if (!scsi_autopm_get_device(cd->device)) + goto out; out_put: kref_put(&cd->kref, sr_kref_release); @@ -162,6 +164,7 @@ static void scsi_cd_put(struct scsi_cd *cd) mutex_lock(&sr_ref_mutex); kref_put(&cd->kref, sr_kref_release); + scsi_autopm_put_device(sdev); scsi_device_put(sdev); mutex_unlock(&sr_ref_mutex); } @@ -211,7 +214,7 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi, unsigned int clearing, int slot) { struct scsi_cd *cd = cdi->handle; - bool last_present; + bool last_present = cd->media_present; struct scsi_sense_hdr sshdr; unsigned int events; int ret; @@ -220,6 +223,8 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi, if (CDSL_CURRENT != slot) return 0; + scsi_autopm_get_device(cd->device); + events = sr_get_events(cd->device); cd->get_event_changed |= events & DISK_EVENT_MEDIA_CHANGE; @@ -246,10 +251,9 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi, } if (!(clearing & DISK_EVENT_MEDIA_CHANGE)) - return events; + goto out; do_tur: /* let's see whether the media is there with TUR */ - last_present = cd->media_present; ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); /* @@ -270,7 +274,7 @@ do_tur: } if (cd->ignore_get_event) - return events; + goto out; /* check whether GET_EVENT is reporting spurious MEDIA_CHANGE */ if (!cd->tur_changed) { @@ -287,6 +291,18 @@ do_tur: cd->tur_changed = false; cd->get_event_changed = false; +out: + /* + * If there is no medium detected or the medium has been there + * since last poll, try to suspend the device. Otherwise, keep + * it active for one more poll interval so that if user space + * application opens the block device, we can avoid a runtime + * status change. + */ + pm_runtime_put_noidle(&cd->device->sdev_gendev); + if (!cd->media_present || last_present) + pm_runtime_suspend(&cd->device->sdev_gendev); + return events; } @@ -718,6 +734,8 @@ static int sr_probe(struct device *dev) sdev_printk(KERN_DEBUG, sdev, "Attached scsi CD-ROM %s\n", cd->cdi.name); + scsi_autopm_put_device(cd->device); + return 0; fail_put: @@ -965,6 +983,8 @@ static int sr_remove(struct device *dev) { struct scsi_cd *cd = dev_get_drvdata(dev); + scsi_autopm_get_device(cd->device); + blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn); del_gendisk(cd->disk);