Пример #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;
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
0
static int scsi_runtime_resume(struct device *dev)
{
	int err = 0;

	dev_dbg(dev, "scsi_runtime_resume\n");
	if (scsi_is_sdev_device(dev))
		err = scsi_dev_type_resume(dev);

	/* Insert hooks here for targets, hosts, and transport classes */

	return err;
}
Пример #5
0
static int scsi_bus_prepare(struct device *dev)
{
	if (scsi_is_sdev_device(dev)) {
		
		async_synchronize_full();

	} else if (scsi_is_host_device(dev)) {
		
		scsi_complete_async_scans();
	}
	return 0;
}
Пример #6
0
static int scsi_runtime_resume(struct device *dev)
{
	int err = 0;

	dev_dbg(dev, "scsi_runtime_resume\n");
	if (scsi_is_sdev_device(dev))
		err = scsi_dev_type_resume(dev);

	

	return err;
}
Пример #7
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();

	} else if (scsi_is_host_device(dev)) {
		/* Wait until async scanning is finished */
		scsi_complete_async_scans();
	}
	return 0;
}
Пример #8
0
static int scsi_runtime_idle(struct device *dev)
{
	int err;

	dev_dbg(dev, "scsi_runtime_idle\n");

	/* Insert hooks here for targets, hosts, and transport classes */

	if (scsi_is_sdev_device(dev))
		err = pm_schedule_suspend(dev, 100);
	else
		err = pm_runtime_suspend(dev);
	return err;
}
Пример #9
0
static int scsi_runtime_idle(struct device *dev)
{
	int err;

	dev_dbg(dev, "scsi_runtime_idle\n");

	

	if (scsi_is_sdev_device(dev))
		err = pm_schedule_suspend(dev, 100);
	else
		err = pm_runtime_suspend(dev);
	return err;
}
Пример #10
0
static int scsi_bus_resume_common(struct device *dev)
{
	int err = 0;

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

	if (err == 0) {
		pm_runtime_disable(dev);
		pm_runtime_set_active(dev);
		pm_runtime_enable(dev);
	}
	return err;
}
Пример #11
0
static int scsi_runtime_idle(struct device *dev)
{
	dev_dbg(dev, "scsi_runtime_idle\n");

	/* Insert hooks here for targets, hosts, and transport classes */

	if (scsi_is_sdev_device(dev)) {
		pm_runtime_mark_last_busy(dev);
		pm_runtime_autosuspend(dev);
		return -EBUSY;
	}

	return 0;
}
Пример #12
0
/**
 * proc_print_scsidevice - return data about this host
 * @dev: A scsi device
 * @data: &struct seq_file to output to.
 *
 * Description: prints Host, Channel, Id, Lun, Vendor, Model, Rev, Type,
 * and revision.
 */
static int proc_print_scsidevice(struct device *dev, void *data)
{
    struct scsi_device *sdev;
    struct seq_file *s = data;
    int i;

    if (!scsi_is_sdev_device(dev))
        goto out;

    sdev = to_scsi_device(dev);
    seq_printf(s,
               "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n  Vendor: ",
               sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
    for (i = 0; i < 8; i++) {
        if (sdev->vendor[i] >= 0x20)
            seq_printf(s, "%c", sdev->vendor[i]);
        else
            seq_printf(s, " ");
    }

    seq_printf(s, " Model: ");
    for (i = 0; i < 16; i++) {
        if (sdev->model[i] >= 0x20)
            seq_printf(s, "%c", sdev->model[i]);
        else
            seq_printf(s, " ");
    }

    seq_printf(s, " Rev: ");
    for (i = 0; i < 4; i++) {
        if (sdev->rev[i] >= 0x20)
            seq_printf(s, "%c", sdev->rev[i]);
        else
            seq_printf(s, " ");
    }

    seq_printf(s, "\n");

    seq_printf(s, "  Type:   %s ", scsi_device_type(sdev->type));
    seq_printf(s, "               ANSI  SCSI revision: %02x",
               sdev->scsi_level - (sdev->scsi_level > 1));
    if (sdev->scsi_level == 2)
        seq_printf(s, " CCS\n");
    else
        seq_printf(s, "\n");

out:
    return 0;
}
Пример #13
0
static int scsi_runtime_suspend(struct device *dev)
{
	int err = 0;

	dev_dbg(dev, "scsi_runtime_suspend\n");
	if (scsi_is_sdev_device(dev)) {
		err = scsi_dev_type_suspend(dev, PMSG_AUTO_SUSPEND);
		if (err == -EAGAIN)
			pm_schedule_suspend(dev, jiffies_to_msecs(
				round_jiffies_up_relative(HZ/10)));
	}

	

	return err;
}
Пример #14
0
static int scsi_runtime_suspend(struct device *dev)
{
	int err = 0;

	dev_dbg(dev, "scsi_runtime_suspend\n");
	if (scsi_is_sdev_device(dev)) {
		err = scsi_dev_type_suspend(dev, PMSG_AUTO_SUSPEND);
		if (err == -EAGAIN)
			pm_schedule_suspend(dev, jiffies_to_msecs(
				round_jiffies_up_relative(HZ/10)));
	}

	/* Insert hooks here for targets, hosts, and transport classes */

	return err;
}
Пример #15
0
static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
{
	int err = 0;

	if (scsi_is_sdev_device(dev)) {
		if (pm_runtime_suspended(dev)) {
			if (msg.event == PM_EVENT_SUSPEND ||
			    msg.event == PM_EVENT_HIBERNATE)
				return 0;	

			
			pm_runtime_resume(dev);
		}
		err = scsi_dev_type_suspend(dev, msg);
	}
	return err;
}
Пример #16
0
static int
scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *))
{
    int err = 0;

    if (scsi_is_sdev_device(dev)) {
        /*
         * All the high-level SCSI drivers that implement runtime
         * PM treat runtime suspend, system suspend, and system
         * hibernate identically.
         */
        if (pm_runtime_suspended(dev))
            return 0;

        err = scsi_dev_type_suspend(dev, cb);
    }

    return err;
}
Пример #17
0
static int
scsi_bus_suspend_common(struct device *dev,
		int (*cb)(struct device *, const struct dev_pm_ops *))
{
	int err = 0;

	if (scsi_is_sdev_device(dev)) {
		/*
		 * All the high-level SCSI drivers that implement runtime
		 * PM treat runtime suspend, system suspend, and system
		 * hibernate nearly identically. In all cases the requirements
		 * for runtime suspension are stricter.
		 */
		if (pm_runtime_suspended(dev))
			return 0;

		err = scsi_dev_type_suspend(dev, cb);
	}

	return err;
}
Пример #18
0
static int scsi_runtime_idle(struct device *dev)
{
    int err;

    dev_dbg(dev, "scsi_runtime_idle\n");

    /* Insert hooks here for targets, hosts, and transport classes */

    if (scsi_is_sdev_device(dev)) {
        struct scsi_device *sdev = to_scsi_device(dev);

        if (sdev->request_queue->dev) {
            pm_runtime_mark_last_busy(dev);
            err = pm_runtime_autosuspend(dev);
        } else {
            err = pm_runtime_suspend(dev);
        }
    } else {
        err = pm_runtime_suspend(dev);
    }
    return err;
}
Пример #19
0
static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
{
	int err = 0;

	if (scsi_is_sdev_device(dev)) {
		/*
		 * sd is the only high-level SCSI driver to implement runtime
		 * PM, and sd treats runtime suspend, system suspend, and
		 * system hibernate identically (but not system freeze).
		 */
		if (pm_runtime_suspended(dev)) {
			if (msg.event == PM_EVENT_SUSPEND ||
			    msg.event == PM_EVENT_HIBERNATE)
				return 0;	/* already suspended */

			/* wake up device so that FREEZE will succeed */
			pm_runtime_resume(dev);
		}
		err = scsi_dev_type_suspend(dev, msg);
	}
	return err;
}
Пример #20
0
static int scsi_bus_resume_common(struct device *dev)
{
	int err = 0;

	if (scsi_is_sdev_device(dev)) {
		/*
		 * Parent device may have runtime suspended as soon as
		 * it is woken up during the system resume.
		 *
		 * Resume it on behalf of child.
		 */
		pm_runtime_get_sync(dev->parent);
		err = scsi_dev_type_resume(dev);
		pm_runtime_put_sync(dev->parent);
	}

	if (err == 0) {
		pm_runtime_disable(dev);
		pm_runtime_set_active(dev);
		pm_runtime_enable(dev);
	}
	return err;
}
Пример #21
0
/*
 * TODO: need some interface so we can set trespass values
 */
static int clariion_bus_notify(struct notifier_block *nb,
				unsigned long action, void *data)
{
	struct device *dev = data;
	struct scsi_device *sdev;
	struct scsi_dh_data *scsi_dh_data;
	struct clariion_dh_data *h;
	int i, found = 0;
	unsigned long flags;

	if (!scsi_is_sdev_device(dev))
		return 0;

	sdev = to_scsi_device(dev);

	if (action == BUS_NOTIFY_ADD_DEVICE) {
		for (i = 0; clariion_dev_list[i].vendor; i++) {
			if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor,
				     strlen(clariion_dev_list[i].vendor)) &&
			    !strncmp(sdev->model, clariion_dev_list[i].model,
				     strlen(clariion_dev_list[i].model))) {
				found = 1;
				break;
			}
		}
		if (!found)
			goto out;

		scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *)
				+ sizeof(*h) , GFP_KERNEL);
		if (!scsi_dh_data) {
			sdev_printk(KERN_ERR, sdev, "Attach failed %s.\n",
				    CLARIION_NAME);
			goto out;
		}

		scsi_dh_data->scsi_dh = &clariion_dh;
		h = (struct clariion_dh_data *) scsi_dh_data->buf;
		h->default_sp = CLARIION_UNBOUND_LU;
		h->current_sp = CLARIION_UNBOUND_LU;

		spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
		sdev->scsi_dh_data = scsi_dh_data;
		spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);

		sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n", CLARIION_NAME);
		try_module_get(THIS_MODULE);

	} else if (action == BUS_NOTIFY_DEL_DEVICE) {
		if (sdev->scsi_dh_data == NULL ||
				sdev->scsi_dh_data->scsi_dh != &clariion_dh)
			goto out;

		spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
		scsi_dh_data = sdev->scsi_dh_data;
		sdev->scsi_dh_data = NULL;
		spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);

		sdev_printk(KERN_NOTICE, sdev, "Dettached %s.\n",
			    CLARIION_NAME);

		kfree(scsi_dh_data);
		module_put(THIS_MODULE);
	}

out:
	return 0;
}