Esempio n. 1
0
static int scsi_bus_resume_common(struct device *dev,
		int (*cb)(struct device *, const struct dev_pm_ops *))
{
	async_func_t fn;

	if (!scsi_is_sdev_device(dev))
		fn = NULL;
	else if (cb == do_scsi_resume)
		fn = async_sdev_resume;
	else if (cb == do_scsi_thaw)
		fn = async_sdev_thaw;
	else if (cb == do_scsi_restore)
		fn = async_sdev_restore;
	else
		fn = NULL;

	if (fn) {
		async_schedule_domain(fn, dev, &scsi_sd_pm_domain);

		/*
		 * If a user has disabled async probing a likely reason
		 * is due to a storage enclosure that does not inject
		 * staggered spin-ups.  For safety, make resume
		 * synchronous as well in that case.
		 */
		if (strncmp(scsi_scan_type, "async", 5) != 0)
			async_synchronize_full_domain(&scsi_sd_pm_domain);
	} else {
		pm_runtime_disable(dev);
		pm_runtime_set_active(dev);
		pm_runtime_enable(dev);
	}
	return 0;
}
Esempio n. 2
0
static int scsi_bus_prepare(struct device *dev)
{
    if (scsi_is_sdev_device(dev)) {
        /* sd probing uses async_schedule.  Wait until it finishes. */
        async_synchronize_full_domain(&scsi_sd_probe_domain);

    } else if (scsi_is_host_device(dev)) {
        /* Wait until async scanning is finished */
        scsi_complete_async_scans();
    }
    return 0;
}
Esempio n. 3
0
static int scsi_dev_type_suspend(struct device *dev,
		int (*cb)(struct device *, const struct dev_pm_ops *))
{
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
	int err;

	/* flush pending in-flight resume operations, suspend is synchronous */
	async_synchronize_full_domain(&scsi_sd_pm_domain);

	err = scsi_device_quiesce(to_scsi_device(dev));
	if (err == 0) {
		err = cb(dev, pm);
		if (err)
			scsi_device_resume(to_scsi_device(dev));
	}
	dev_dbg(dev, "scsi suspend: %d\n", err);
	return err;
}
Esempio n. 4
0
static int scsi_bus_resume_common(struct device *dev,
		int (*cb)(struct device *, const struct dev_pm_ops *))
{
	async_func_t fn;

	if (!scsi_is_sdev_device(dev))
		fn = NULL;
	else if (cb == do_scsi_resume)
		fn = async_sdev_resume;
	else if (cb == do_scsi_thaw)
		fn = async_sdev_thaw;
	else if (cb == do_scsi_restore)
		fn = async_sdev_restore;
	else
		fn = NULL;

	/*
	 * Forcibly set runtime PM status of request queue to "active" to
	 * make sure we can again get requests from the queue (see also
	 * blk_pm_peek_request()).
	 *
	 * The resume hook will correct runtime PM status of the disk.
	 */
	if (scsi_is_sdev_device(dev) && pm_runtime_suspended(dev))
		blk_set_runtime_active(to_scsi_device(dev)->request_queue);

	if (fn) {
		async_schedule_domain(fn, dev, &scsi_sd_pm_domain);

		/*
		 * If a user has disabled async probing a likely reason
		 * is due to a storage enclosure that does not inject
		 * staggered spin-ups.  For safety, make resume
		 * synchronous as well in that case.
		 */
		if (strncmp(scsi_scan_type, "async", 5) != 0)
			async_synchronize_full_domain(&scsi_sd_pm_domain);
	} else {
		pm_runtime_disable(dev);
		pm_runtime_set_active(dev);
		pm_runtime_enable(dev);
	}
	return 0;
}