Commit 297b8a07 authored by James Bottomley's avatar James Bottomley
Browse files

Merge branch 'postmerge' into for-linus

parents 832e77bc 6df339a5
Loading
Loading
Loading
Loading
+4 −5
Original line number Original line Diff line number Diff line
@@ -276,11 +276,10 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
}
}
EXPORT_SYMBOL(scsi_execute);
EXPORT_SYMBOL(scsi_execute);



int scsi_execute_req_flags(struct scsi_device *sdev, const unsigned char *cmd,
int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
		     int data_direction, void *buffer, unsigned bufflen,
		     int data_direction, void *buffer, unsigned bufflen,
		     struct scsi_sense_hdr *sshdr, int timeout, int retries,
		     struct scsi_sense_hdr *sshdr, int timeout, int retries,
		     int *resid)
		     int *resid, int flags)
{
{
	char *sense = NULL;
	char *sense = NULL;
	int result;
	int result;
@@ -291,14 +290,14 @@ int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
			return DRIVER_ERROR << 24;
			return DRIVER_ERROR << 24;
	}
	}
	result = scsi_execute(sdev, cmd, data_direction, buffer, bufflen,
	result = scsi_execute(sdev, cmd, data_direction, buffer, bufflen,
			      sense, timeout, retries, 0, resid);
			      sense, timeout, retries, flags, resid);
	if (sshdr)
	if (sshdr)
		scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, sshdr);
		scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, sshdr);


	kfree(sense);
	kfree(sense);
	return result;
	return result;
}
}
EXPORT_SYMBOL(scsi_execute_req);
EXPORT_SYMBOL(scsi_execute_req_flags);


/*
/*
 * Function:    scsi_init_cmd_errh()
 * Function:    scsi_init_cmd_errh()
+71 −13
Original line number Original line Diff line number Diff line
@@ -144,33 +144,83 @@ static int scsi_bus_restore(struct device *dev)


#ifdef CONFIG_PM_RUNTIME
#ifdef CONFIG_PM_RUNTIME


static int scsi_runtime_suspend(struct device *dev)
static int sdev_blk_runtime_suspend(struct scsi_device *sdev,
					int (*cb)(struct device *))
{
	int err;

	err = blk_pre_runtime_suspend(sdev->request_queue);
	if (err)
		return err;
	if (cb)
		err = cb(&sdev->sdev_gendev);
	blk_post_runtime_suspend(sdev->request_queue, err);

	return err;
}

static int sdev_runtime_suspend(struct device *dev)
{
{
	int err = 0;
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
	int (*cb)(struct device *) = pm ? pm->runtime_suspend : NULL;
	struct scsi_device *sdev = to_scsi_device(dev);
	int err;


	dev_dbg(dev, "scsi_runtime_suspend\n");
	if (sdev->request_queue->dev)
	if (scsi_is_sdev_device(dev)) {
		return sdev_blk_runtime_suspend(sdev, cb);
		err = scsi_dev_type_suspend(dev,

				pm ? pm->runtime_suspend : NULL);
	err = scsi_dev_type_suspend(dev, cb);
	if (err == -EAGAIN)
	if (err == -EAGAIN)
		pm_schedule_suspend(dev, jiffies_to_msecs(
		pm_schedule_suspend(dev, jiffies_to_msecs(
					round_jiffies_up_relative(HZ/10)));
					round_jiffies_up_relative(HZ/10)));
	return err;
}
}


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 = sdev_runtime_suspend(dev);

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


	return err;
	return err;
}
}


static int scsi_runtime_resume(struct device *dev)
static int sdev_blk_runtime_resume(struct scsi_device *sdev,
					int (*cb)(struct device *))
{
{
	int err = 0;
	int err = 0;

	blk_pre_runtime_resume(sdev->request_queue);
	if (cb)
		err = cb(&sdev->sdev_gendev);
	blk_post_runtime_resume(sdev->request_queue, err);

	return err;
}

static int sdev_runtime_resume(struct device *dev)
{
	struct scsi_device *sdev = to_scsi_device(dev);
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
	int (*cb)(struct device *) = pm ? pm->runtime_resume : NULL;

	if (sdev->request_queue->dev)
		return sdev_blk_runtime_resume(sdev, cb);
	else
		return scsi_dev_type_resume(dev, cb);
}

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


	dev_dbg(dev, "scsi_runtime_resume\n");
	dev_dbg(dev, "scsi_runtime_resume\n");
	if (scsi_is_sdev_device(dev))
	if (scsi_is_sdev_device(dev))
		err = scsi_dev_type_resume(dev, pm ? pm->runtime_resume : NULL);
		err = sdev_runtime_resume(dev);


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


@@ -185,10 +235,18 @@ static int scsi_runtime_idle(struct device *dev)


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


	if (scsi_is_sdev_device(dev))
	if (scsi_is_sdev_device(dev)) {
		err = pm_schedule_suspend(dev, 100);
		struct scsi_device *sdev = to_scsi_device(dev);
	else

		if (sdev->request_queue->dev) {
			pm_runtime_mark_last_busy(dev);
			err = pm_runtime_autosuspend(dev);
		} else {
			err = pm_runtime_suspend(dev);
			err = pm_runtime_suspend(dev);
		}
	} else {
		err = pm_runtime_suspend(dev);
	}
	return err;
	return err;
}
}


+6 −16
Original line number Original line Diff line number Diff line
@@ -1136,10 +1136,6 @@ static int sd_open(struct block_device *bdev, fmode_t mode)


	sdev = sdkp->device;
	sdev = sdkp->device;


	retval = scsi_autopm_get_device(sdev);
	if (retval)
		goto error_autopm;

	/*
	/*
	 * If the device is in error recovery, wait until it is done.
	 * If the device is in error recovery, wait until it is done.
	 * If the device is offline, then disallow any access to it.
	 * If the device is offline, then disallow any access to it.
@@ -1184,8 +1180,6 @@ static int sd_open(struct block_device *bdev, fmode_t mode)
	return 0;
	return 0;


error_out:
error_out:
	scsi_autopm_put_device(sdev);
error_autopm:
	scsi_disk_put(sdkp);
	scsi_disk_put(sdkp);
	return retval;	
	return retval;	
}
}
@@ -1220,7 +1214,6 @@ static void sd_release(struct gendisk *disk, fmode_t mode)
	 * XXX is followed by a "rmmod sd_mod"?
	 * XXX is followed by a "rmmod sd_mod"?
	 */
	 */


	scsi_autopm_put_device(sdev);
	scsi_disk_put(sdkp);
	scsi_disk_put(sdkp);
}
}


@@ -1381,14 +1374,9 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
	retval = -ENODEV;
	retval = -ENODEV;


	if (scsi_block_when_processing_errors(sdp)) {
	if (scsi_block_when_processing_errors(sdp)) {
		retval = scsi_autopm_get_device(sdp);
		if (retval)
			goto out;

		sshdr  = kzalloc(sizeof(*sshdr), GFP_KERNEL);
		sshdr  = kzalloc(sizeof(*sshdr), GFP_KERNEL);
		retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES,
		retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES,
					      sshdr);
					      sshdr);
		scsi_autopm_put_device(sdp);
	}
	}


	/* failed to execute TUR, assume media not present */
	/* failed to execute TUR, assume media not present */
@@ -1438,8 +1426,9 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
		 * Leave the rest of the command zero to indicate
		 * Leave the rest of the command zero to indicate
		 * flush everything.
		 * flush everything.
		 */
		 */
		res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
		res = scsi_execute_req_flags(sdp, cmd, DMA_NONE, NULL, 0,
				       SD_FLUSH_TIMEOUT, SD_MAX_RETRIES, NULL);
					     &sshdr, SD_FLUSH_TIMEOUT,
					     SD_MAX_RETRIES, NULL, REQ_PM);
		if (res == 0)
		if (res == 0)
			break;
			break;
	}
	}
@@ -2857,6 +2846,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie)


	sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
	sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
		  sdp->removable ? "removable " : "");
		  sdp->removable ? "removable " : "");
	blk_pm_runtime_init(sdp->request_queue, dev);
	scsi_autopm_put_device(sdp);
	scsi_autopm_put_device(sdp);
	put_device(&sdkp->dev);
	put_device(&sdkp->dev);
}
}
@@ -3040,8 +3030,8 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
	if (!scsi_device_online(sdp))
	if (!scsi_device_online(sdp))
		return -ENODEV;
		return -ENODEV;


	res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
	res = scsi_execute_req_flags(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
			       SD_TIMEOUT, SD_MAX_RETRIES, NULL);
			       SD_TIMEOUT, SD_MAX_RETRIES, NULL, REQ_PM);
	if (res) {
	if (res) {
		sd_printk(KERN_WARNING, sdkp, "START_STOP FAILED\n");
		sd_printk(KERN_WARNING, sdkp, "START_STOP FAILED\n");
		sd_print_result(sdkp, res);
		sd_print_result(sdkp, res);
+12 −4
Original line number Original line Diff line number Diff line
@@ -394,10 +394,18 @@ extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
			int data_direction, void *buffer, unsigned bufflen,
			int data_direction, void *buffer, unsigned bufflen,
			unsigned char *sense, int timeout, int retries,
			unsigned char *sense, int timeout, int retries,
			int flag, int *resid);
			int flag, int *resid);
extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
extern int scsi_execute_req_flags(struct scsi_device *sdev,
			    int data_direction, void *buffer, unsigned bufflen,
	const unsigned char *cmd, int data_direction, void *buffer,
			    struct scsi_sense_hdr *, int timeout, int retries,
	unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout,
			    int *resid);
	int retries, int *resid, int flags);
static inline int scsi_execute_req(struct scsi_device *sdev,
	const unsigned char *cmd, int data_direction, void *buffer,
	unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout,
	int retries, int *resid)
{
	return scsi_execute_req_flags(sdev, cmd, data_direction, buffer,
		bufflen, sshdr, timeout, retries, resid, 0);
}
extern void sdev_disable_disk_events(struct scsi_device *sdev);
extern void sdev_disable_disk_events(struct scsi_device *sdev);
extern void sdev_enable_disk_events(struct scsi_device *sdev);
extern void sdev_enable_disk_events(struct scsi_device *sdev);