diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-12-14 18:01:56 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-12-14 18:01:56 +0100 |
commit | b89371621e5bedc84498ced2c5c33976bd1b2f64 (patch) | |
tree | b309919239586e25617a17785b827577b1abb6b5 /drivers/scsi/scsi_sysfs.c | |
parent | sound: add Edirol UA-101 support (diff) | |
parent | ALSA: sb_mixer: convert pointer tables to mixer control tables (diff) | |
download | linux-b89371621e5bedc84498ced2c5c33976bd1b2f64.tar.xz linux-b89371621e5bedc84498ced2c5c33976bd1b2f64.zip |
Merge branch 'next/isa' into topic/misc
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 107 |
1 files changed, 68 insertions, 39 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 5c7eb63a19d1..5a065055e68a 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -766,10 +766,13 @@ sdev_store_queue_depth_rw(struct device *dev, struct device_attribute *attr, if (depth < 1) return -EINVAL; - retval = sht->change_queue_depth(sdev, depth); + retval = sht->change_queue_depth(sdev, depth, + SCSI_QDEPTH_DEFAULT); if (retval < 0) return retval; + sdev->max_queue_depth = sdev->queue_depth; + return count; } @@ -778,6 +781,37 @@ static struct device_attribute sdev_attr_queue_depth_rw = sdev_store_queue_depth_rw); static ssize_t +sdev_show_queue_ramp_up_period(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev; + sdev = to_scsi_device(dev); + return snprintf(buf, 20, "%u\n", + jiffies_to_msecs(sdev->queue_ramp_up_period)); +} + +static ssize_t +sdev_store_queue_ramp_up_period(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + unsigned long period; + + if (strict_strtoul(buf, 10, &period)) + return -EINVAL; + + sdev->queue_ramp_up_period = msecs_to_jiffies(period); + return period; +} + +static struct device_attribute sdev_attr_queue_ramp_up_period = + __ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR, + sdev_show_queue_ramp_up_period, + sdev_store_queue_ramp_up_period); + +static ssize_t sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -854,82 +888,77 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) transport_configure_device(&starget->dev); error = device_add(&sdev->sdev_gendev); if (error) { - put_device(sdev->sdev_gendev.parent); printk(KERN_INFO "error 1\n"); - return error; + goto out_remove; } error = device_add(&sdev->sdev_dev); if (error) { printk(KERN_INFO "error 2\n"); - goto clean_device; + device_del(&sdev->sdev_gendev); + goto out_remove; } + transport_add_device(&sdev->sdev_gendev); + sdev->is_visible = 1; /* create queue files, which may be writable, depending on the host */ - if (sdev->host->hostt->change_queue_depth) - error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); + if (sdev->host->hostt->change_queue_depth) { + error = device_create_file(&sdev->sdev_gendev, + &sdev_attr_queue_depth_rw); + error = device_create_file(&sdev->sdev_gendev, + &sdev_attr_queue_ramp_up_period); + } else error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth); - if (error) { - __scsi_remove_device(sdev); - goto out; - } + if (error) + goto out_remove; + if (sdev->host->hostt->change_queue_type) error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw); else error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type); - if (error) { - __scsi_remove_device(sdev); - goto out; - } + if (error) + goto out_remove; error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL); if (error) + /* we're treating error on bsg register as non-fatal, + * so pretend nothing went wrong */ sdev_printk(KERN_INFO, sdev, "Failed to register bsg queue, errno=%d\n", error); - /* we're treating error on bsg register as non-fatal, so pretend - * nothing went wrong */ - error = 0; - /* add additional host specific attributes */ if (sdev->host->hostt->sdev_attrs) { for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { error = device_create_file(&sdev->sdev_gendev, sdev->host->hostt->sdev_attrs[i]); - if (error) { - __scsi_remove_device(sdev); - goto out; - } + if (error) + goto out_remove; } } - transport_add_device(&sdev->sdev_gendev); - out: - return error; - - clean_device: - scsi_device_set_state(sdev, SDEV_CANCEL); - - device_del(&sdev->sdev_gendev); - transport_destroy_device(&sdev->sdev_gendev); - put_device(&sdev->sdev_dev); - put_device(&sdev->sdev_gendev); + return 0; + out_remove: + __scsi_remove_device(sdev); return error; + } void __scsi_remove_device(struct scsi_device *sdev) { struct device *dev = &sdev->sdev_gendev; - if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) - return; + if (sdev->is_visible) { + if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) + return; - bsg_unregister_queue(sdev->request_queue); - device_unregister(&sdev->sdev_dev); - transport_remove_device(dev); - device_del(dev); + bsg_unregister_queue(sdev->request_queue); + device_unregister(&sdev->sdev_dev); + transport_remove_device(dev); + device_del(dev); + } else + put_device(&sdev->sdev_dev); scsi_device_set_state(sdev, SDEV_DEL); if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); |