Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db5bd1e0 authored by Alan Stern's avatar Alan Stern Committed by James Bottomley
Browse files

[SCSI] convert to the new PM framework



This patch (as1397b) converts the SCSI midlayer to use the new PM
callbacks (struct dev_pm_ops).  A new source file, scsi_pm.c, is
created to hold the new callback routines, and the existing
suspend/resume code is moved there.

Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent df64d3ca
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -163,6 +163,7 @@ scsi_mod-$(CONFIG_SCSI_NETLINK) += scsi_netlink.o
scsi_mod-$(CONFIG_SYSCTL)	+= scsi_sysctl.o
scsi_mod-$(CONFIG_SCSI_PROC_FS)	+= scsi_proc.o
scsi_mod-y			+= scsi_trace.o
scsi_mod-$(CONFIG_PM_OPS)	+= scsi_pm.o

scsi_tgt-y			+= scsi_tgt_lib.o scsi_tgt_if.o

drivers/scsi/scsi_pm.c

0 → 100644
+96 −0
Original line number Diff line number Diff line
/*
 *	scsi_pm.c	Copyright (C) 2010 Alan Stern
 *
 *	SCSI dynamic Power Management
 *		Initial version: Alan Stern <stern@rowland.harvard.edu>
 */

#include <linux/pm_runtime.h>

#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_host.h>

#include "scsi_priv.h"

static int scsi_dev_type_suspend(struct device *dev, pm_message_t msg)
{
	struct device_driver *drv;
	int err;

	err = scsi_device_quiesce(to_scsi_device(dev));
	if (err == 0) {
		drv = dev->driver;
		if (drv && drv->suspend)
			err = drv->suspend(dev, msg);
	}
	dev_dbg(dev, "scsi suspend: %d\n", err);
	return err;
}

static int scsi_dev_type_resume(struct device *dev)
{
	struct device_driver *drv;
	int err = 0;

	drv = dev->driver;
	if (drv && drv->resume)
		err = drv->resume(dev);
	scsi_device_resume(to_scsi_device(dev));
	dev_dbg(dev, "scsi resume: %d\n", err);
	return err;
}

#ifdef CONFIG_PM_SLEEP

static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
{
	int err = 0;

	if (scsi_is_sdev_device(dev))
		err = scsi_dev_type_suspend(dev, msg);
	return err;
}

static int scsi_bus_resume_common(struct device *dev)
{
	int err = 0;

	if (scsi_is_sdev_device(dev))
		err = scsi_dev_type_resume(dev);
	return err;
}

static int scsi_bus_suspend(struct device *dev)
{
	return scsi_bus_suspend_common(dev, PMSG_SUSPEND);
}

static int scsi_bus_freeze(struct device *dev)
{
	return scsi_bus_suspend_common(dev, PMSG_FREEZE);
}

static int scsi_bus_poweroff(struct device *dev)
{
	return scsi_bus_suspend_common(dev, PMSG_HIBERNATE);
}

#else /* CONFIG_PM_SLEEP */

#define scsi_bus_resume_common		NULL
#define scsi_bus_suspend		NULL
#define scsi_bus_freeze			NULL
#define scsi_bus_poweroff		NULL

#endif /* CONFIG_PM_SLEEP */

const struct dev_pm_ops scsi_bus_pm_ops = {
	.suspend =		scsi_bus_suspend,
	.resume =		scsi_bus_resume_common,
	.freeze =		scsi_bus_freeze,
	.thaw =			scsi_bus_resume_common,
	.poweroff =		scsi_bus_poweroff,
	.restore =		scsi_bus_resume_common,
};
+7 −0
Original line number Diff line number Diff line
@@ -144,6 +144,13 @@ static inline void scsi_netlink_init(void) {}
static inline void scsi_netlink_exit(void) {}
#endif

/* scsi_pm.c */
#ifdef CONFIG_PM_OPS
extern const struct dev_pm_ops scsi_bus_pm_ops;
#else
#define scsi_bus_pm_ops		(*NULL)
#endif

/* 
 * internal scsi timeout functions: for use by mid-layer and transport
 * classes.
+1 −47
Original line number Diff line number Diff line
@@ -376,57 +376,11 @@ static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
	return 0;
}

static int scsi_bus_suspend(struct device * dev, pm_message_t state)
{
	struct device_driver *drv;
	struct scsi_device *sdev;
	int err;

	if (dev->type != &scsi_dev_type)
		return 0;

	drv = dev->driver;
	sdev = to_scsi_device(dev);

	err = scsi_device_quiesce(sdev);
	if (err)
		return err;

	if (drv && drv->suspend) {
		err = drv->suspend(dev, state);
		if (err)
			return err;
	}

	return 0;
}

static int scsi_bus_resume(struct device * dev)
{
	struct device_driver *drv;
	struct scsi_device *sdev;
	int err = 0;

	if (dev->type != &scsi_dev_type)
		return 0;

	drv = dev->driver;
	sdev = to_scsi_device(dev);

	if (drv && drv->resume)
		err = drv->resume(dev);

	scsi_device_resume(sdev);

	return err;
}

struct bus_type scsi_bus_type = {
        .name		= "scsi",
        .match		= scsi_bus_match,
	.uevent		= scsi_bus_uevent,
	.suspend	= scsi_bus_suspend,
	.resume		= scsi_bus_resume,
	.pm		= &scsi_bus_pm_ops,
};
EXPORT_SYMBOL_GPL(scsi_bus_type);