Commit 559467ae authored by James Bottomley's avatar James Bottomley

SCSI:add change_queue_depth API to scsi host template

Originally, the 53c700 driver implemented queue_depth changing as an
attribute override, primarily as a demonstration of how it should be
done.  Now that a large number of drivers wish to implement this
functionality, it should become an API rather than an attribute
override, since the latter are supposed to be used as one off extensions
rather than the de-facto API.
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 8b3ba6c3
......@@ -391,7 +391,7 @@ show_state_field(struct device *dev, char *buf)
return snprintf(buf, 20, "%s\n", name);
}
DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_state_field, store_state_field);
static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_state_field, store_state_field);
/* Default template for device attributes. May NOT be modified */
......@@ -410,6 +410,38 @@ static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
NULL
};
static ssize_t sdev_store_queue_depth_rw(struct device *dev, const char *buf,
size_t count)
{
int depth, retval;
struct scsi_device *sdev = to_scsi_device(dev);
struct scsi_host_template *sht = sdev->host->hostt;
if (!sht->change_queue_depth)
return -EINVAL;
depth = simple_strtoul(buf, NULL, 0);
retval = sht->change_queue_depth(sdev, depth);
if (retval < 0)
return retval;
return count;
}
static struct device_attribute sdev_attr_queue_depth_rw =
__ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth,
sdev_store_queue_depth_rw);
static struct device_attribute *attr_changed_internally(
struct Scsi_Host *shost,
struct device_attribute * attr)
{
if (!strcmp("queue_depth", attr->attr.name)
&& shost->hostt->change_queue_depth)
return &sdev_attr_queue_depth_rw;
return attr;
}
static struct device_attribute *attr_overridden(
struct device_attribute **attrs,
......@@ -550,8 +582,10 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
for (i = 0; scsi_sysfs_sdev_attrs[i]; i++) {
if (!attr_overridden(sdev->host->hostt->sdev_attrs,
scsi_sysfs_sdev_attrs[i])) {
error = device_create_file(&sdev->sdev_gendev,
scsi_sysfs_sdev_attrs[i]);
struct device_attribute * attr =
attr_changed_internally(sdev->host,
scsi_sysfs_sdev_attrs[i]);
error = device_create_file(&sdev->sdev_gendev, attr);
if (error) {
scsi_remove_device(sdev);
goto out;
......
......@@ -215,6 +215,18 @@ struct scsi_host_template {
*/
void (* slave_destroy)(struct scsi_device *);
/*
* fill in this function to allow the queue depth of this host
* to be changeable (on a per device basis). returns either
* the current queue depth setting (may be different from what
* was passed in) or an error. An error should only be
* returned if the requested depth is legal but the driver was
* unable to set it. If the requested depth is illegal, the
* driver should set and return the closest legal queue depth.
*
*/
int (* change_queue_depth)(struct scsi_device *, int);
/*
* This function determines the bios parameters for a given
* harddisk. These tend to be numbers that are made up by
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment