diff options
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 67 |
1 files changed, 53 insertions, 14 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 392d8db33905..429c9b73e3e4 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/slab.h> | ||
10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
11 | #include <linux/blkdev.h> | 12 | #include <linux/blkdev.h> |
12 | #include <linux/device.h> | 13 | #include <linux/device.h> |
@@ -766,10 +767,13 @@ sdev_store_queue_depth_rw(struct device *dev, struct device_attribute *attr, | |||
766 | if (depth < 1) | 767 | if (depth < 1) |
767 | return -EINVAL; | 768 | return -EINVAL; |
768 | 769 | ||
769 | retval = sht->change_queue_depth(sdev, depth); | 770 | retval = sht->change_queue_depth(sdev, depth, |
771 | SCSI_QDEPTH_DEFAULT); | ||
770 | if (retval < 0) | 772 | if (retval < 0) |
771 | return retval; | 773 | return retval; |
772 | 774 | ||
775 | sdev->max_queue_depth = sdev->queue_depth; | ||
776 | |||
773 | return count; | 777 | return count; |
774 | } | 778 | } |
775 | 779 | ||
@@ -778,6 +782,37 @@ static struct device_attribute sdev_attr_queue_depth_rw = | |||
778 | sdev_store_queue_depth_rw); | 782 | sdev_store_queue_depth_rw); |
779 | 783 | ||
780 | static ssize_t | 784 | static ssize_t |
785 | sdev_show_queue_ramp_up_period(struct device *dev, | ||
786 | struct device_attribute *attr, | ||
787 | char *buf) | ||
788 | { | ||
789 | struct scsi_device *sdev; | ||
790 | sdev = to_scsi_device(dev); | ||
791 | return snprintf(buf, 20, "%u\n", | ||
792 | jiffies_to_msecs(sdev->queue_ramp_up_period)); | ||
793 | } | ||
794 | |||
795 | static ssize_t | ||
796 | sdev_store_queue_ramp_up_period(struct device *dev, | ||
797 | struct device_attribute *attr, | ||
798 | const char *buf, size_t count) | ||
799 | { | ||
800 | struct scsi_device *sdev = to_scsi_device(dev); | ||
801 | unsigned long period; | ||
802 | |||
803 | if (strict_strtoul(buf, 10, &period)) | ||
804 | return -EINVAL; | ||
805 | |||
806 | sdev->queue_ramp_up_period = msecs_to_jiffies(period); | ||
807 | return period; | ||
808 | } | ||
809 | |||
810 | static struct device_attribute sdev_attr_queue_ramp_up_period = | ||
811 | __ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR, | ||
812 | sdev_show_queue_ramp_up_period, | ||
813 | sdev_store_queue_ramp_up_period); | ||
814 | |||
815 | static ssize_t | ||
781 | sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr, | 816 | sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr, |
782 | const char *buf, size_t count) | 817 | const char *buf, size_t count) |
783 | { | 818 | { |
@@ -813,6 +848,8 @@ static int scsi_target_add(struct scsi_target *starget) | |||
813 | if (starget->state != STARGET_CREATED) | 848 | if (starget->state != STARGET_CREATED) |
814 | return 0; | 849 | return 0; |
815 | 850 | ||
851 | device_enable_async_suspend(&starget->dev); | ||
852 | |||
816 | error = device_add(&starget->dev); | 853 | error = device_add(&starget->dev); |
817 | if (error) { | 854 | if (error) { |
818 | dev_err(&starget->dev, "target device_add failed, error %d\n", error); | 855 | dev_err(&starget->dev, "target device_add failed, error %d\n", error); |
@@ -844,7 +881,8 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
844 | struct request_queue *rq = sdev->request_queue; | 881 | struct request_queue *rq = sdev->request_queue; |
845 | struct scsi_target *starget = sdev->sdev_target; | 882 | struct scsi_target *starget = sdev->sdev_target; |
846 | 883 | ||
847 | if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0) | 884 | error = scsi_device_set_state(sdev, SDEV_RUNNING); |
885 | if (error) | ||
848 | return error; | 886 | return error; |
849 | 887 | ||
850 | error = scsi_target_add(starget); | 888 | error = scsi_target_add(starget); |
@@ -852,34 +890,40 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
852 | return error; | 890 | return error; |
853 | 891 | ||
854 | transport_configure_device(&starget->dev); | 892 | transport_configure_device(&starget->dev); |
893 | device_enable_async_suspend(&sdev->sdev_gendev); | ||
855 | error = device_add(&sdev->sdev_gendev); | 894 | error = device_add(&sdev->sdev_gendev); |
856 | if (error) { | 895 | if (error) { |
857 | printk(KERN_INFO "error 1\n"); | 896 | printk(KERN_INFO "error 1\n"); |
858 | goto out_remove; | 897 | return error; |
859 | } | 898 | } |
899 | device_enable_async_suspend(&sdev->sdev_dev); | ||
860 | error = device_add(&sdev->sdev_dev); | 900 | error = device_add(&sdev->sdev_dev); |
861 | if (error) { | 901 | if (error) { |
862 | printk(KERN_INFO "error 2\n"); | 902 | printk(KERN_INFO "error 2\n"); |
863 | device_del(&sdev->sdev_gendev); | 903 | device_del(&sdev->sdev_gendev); |
864 | goto out_remove; | 904 | return error; |
865 | } | 905 | } |
866 | transport_add_device(&sdev->sdev_gendev); | 906 | transport_add_device(&sdev->sdev_gendev); |
867 | sdev->is_visible = 1; | 907 | sdev->is_visible = 1; |
868 | 908 | ||
869 | /* create queue files, which may be writable, depending on the host */ | 909 | /* create queue files, which may be writable, depending on the host */ |
870 | if (sdev->host->hostt->change_queue_depth) | 910 | if (sdev->host->hostt->change_queue_depth) { |
871 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); | 911 | error = device_create_file(&sdev->sdev_gendev, |
912 | &sdev_attr_queue_depth_rw); | ||
913 | error = device_create_file(&sdev->sdev_gendev, | ||
914 | &sdev_attr_queue_ramp_up_period); | ||
915 | } | ||
872 | else | 916 | else |
873 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth); | 917 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth); |
874 | if (error) | 918 | if (error) |
875 | goto out_remove; | 919 | return error; |
876 | 920 | ||
877 | if (sdev->host->hostt->change_queue_type) | 921 | if (sdev->host->hostt->change_queue_type) |
878 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw); | 922 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw); |
879 | else | 923 | else |
880 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type); | 924 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type); |
881 | if (error) | 925 | if (error) |
882 | goto out_remove; | 926 | return error; |
883 | 927 | ||
884 | error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL); | 928 | error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL); |
885 | 929 | ||
@@ -895,16 +939,11 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
895 | error = device_create_file(&sdev->sdev_gendev, | 939 | error = device_create_file(&sdev->sdev_gendev, |
896 | sdev->host->hostt->sdev_attrs[i]); | 940 | sdev->host->hostt->sdev_attrs[i]); |
897 | if (error) | 941 | if (error) |
898 | goto out_remove; | 942 | return error; |
899 | } | 943 | } |
900 | } | 944 | } |
901 | 945 | ||
902 | return 0; | ||
903 | |||
904 | out_remove: | ||
905 | __scsi_remove_device(sdev); | ||
906 | return error; | 946 | return error; |
907 | |||
908 | } | 947 | } |
909 | 948 | ||
910 | void __scsi_remove_device(struct scsi_device *sdev) | 949 | void __scsi_remove_device(struct scsi_device *sdev) |