aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2007-09-11 11:00:14 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:48:22 -0400
commitbfd129445f23c037d9a440ebfa4109e11c220301 (patch)
tree7952a3701233972e2257e8c85d063188413b9c78 /drivers/scsi/scsi_sysfs.c
parent01fbfe0b8359695a3ff7f4b79ab1e0a777f10ae4 (diff)
[SCSI] switch sdev sysfs attributes to default attributes
This removes the unused sysfs attribute overwriting logic for most of the attributes, and plugs them into the driver core default attribute creation. Without this patch, at the time of the events for the SCSI LUN's, there will be no sysfs files, because their creation is delayed until the sd driver has spun up the disks, which might take several seconds. It is the last WAIT_FOR_SYSFS rule in the default udev setup which can be removed with this change. Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c136
1 files changed, 52 insertions, 84 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index a3d227f3f520..0088c4dd7c6a 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -618,24 +618,31 @@ sdev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
618static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL); 618static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL);
619 619
620/* Default template for device attributes. May NOT be modified */ 620/* Default template for device attributes. May NOT be modified */
621static struct device_attribute *scsi_sysfs_sdev_attrs[] = { 621static struct attribute *scsi_sdev_attrs[] = {
622 &dev_attr_device_blocked, 622 &dev_attr_device_blocked.attr,
623 &dev_attr_queue_depth, 623 &dev_attr_type.attr,
624 &dev_attr_queue_type, 624 &dev_attr_scsi_level.attr,
625 &dev_attr_type, 625 &dev_attr_vendor.attr,
626 &dev_attr_scsi_level, 626 &dev_attr_model.attr,
627 &dev_attr_vendor, 627 &dev_attr_rev.attr,
628 &dev_attr_model, 628 &dev_attr_rescan.attr,
629 &dev_attr_rev, 629 &dev_attr_delete.attr,
630 &dev_attr_rescan, 630 &dev_attr_state.attr,
631 &dev_attr_delete, 631 &dev_attr_timeout.attr,
632 &dev_attr_state, 632 &dev_attr_iocounterbits.attr,
633 &dev_attr_timeout, 633 &dev_attr_iorequest_cnt.attr,
634 &dev_attr_iocounterbits, 634 &dev_attr_iodone_cnt.attr,
635 &dev_attr_iorequest_cnt, 635 &dev_attr_ioerr_cnt.attr,
636 &dev_attr_iodone_cnt, 636 &dev_attr_modalias.attr,
637 &dev_attr_ioerr_cnt, 637 NULL
638 &dev_attr_modalias, 638};
639
640static struct attribute_group scsi_sdev_attr_group = {
641 .attrs = scsi_sdev_attrs,
642};
643
644static struct attribute_group *scsi_sdev_attr_groups[] = {
645 &scsi_sdev_attr_group,
639 NULL 646 NULL
640}; 647};
641 648
@@ -697,56 +704,6 @@ static struct device_attribute sdev_attr_queue_type_rw =
697 __ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field, 704 __ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field,
698 sdev_store_queue_type_rw); 705 sdev_store_queue_type_rw);
699 706
700static struct device_attribute *attr_changed_internally(
701 struct Scsi_Host *shost,
702 struct device_attribute * attr)
703{
704 if (!strcmp("queue_depth", attr->attr.name)
705 && shost->hostt->change_queue_depth)
706 return &sdev_attr_queue_depth_rw;
707 else if (!strcmp("queue_type", attr->attr.name)
708 && shost->hostt->change_queue_type)
709 return &sdev_attr_queue_type_rw;
710 return attr;
711}
712
713
714static struct device_attribute *attr_overridden(
715 struct device_attribute **attrs,
716 struct device_attribute *attr)
717{
718 int i;
719
720 if (!attrs)
721 return NULL;
722 for (i = 0; attrs[i]; i++)
723 if (!strcmp(attrs[i]->attr.name, attr->attr.name))
724 return attrs[i];
725 return NULL;
726}
727
728static int attr_add(struct device *dev, struct device_attribute *attr)
729{
730 struct device_attribute *base_attr;
731
732 /*
733 * Spare the caller from having to copy things it's not interested in.
734 */
735 base_attr = attr_overridden(scsi_sysfs_sdev_attrs, attr);
736 if (base_attr) {
737 /* extend permissions */
738 attr->attr.mode |= base_attr->attr.mode;
739
740 /* override null show/store with default */
741 if (!attr->show)
742 attr->show = base_attr->show;
743 if (!attr->store)
744 attr->store = base_attr->store;
745 }
746
747 return device_create_file(dev, attr);
748}
749
750/** 707/**
751 * scsi_sysfs_add_sdev - add scsi device to sysfs 708 * scsi_sysfs_add_sdev - add scsi device to sysfs
752 * @sdev: scsi_device to add 709 * @sdev: scsi_device to add
@@ -778,6 +735,24 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
778 * released by the sdev_class .release */ 735 * released by the sdev_class .release */
779 get_device(&sdev->sdev_gendev); 736 get_device(&sdev->sdev_gendev);
780 737
738 /* create queue files, which may be writable, depending on the host */
739 if (sdev->host->hostt->change_queue_depth)
740 error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw);
741 else
742 error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
743 if (error) {
744 __scsi_remove_device(sdev);
745 goto out;
746 }
747 if (sdev->host->hostt->change_queue_type)
748 error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw);
749 else
750 error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type);
751 if (error) {
752 __scsi_remove_device(sdev);
753 goto out;
754 }
755
781 error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL); 756 error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL);
782 757
783 if (error) 758 if (error)
@@ -788,9 +763,10 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
788 * nothing went wrong */ 763 * nothing went wrong */
789 error = 0; 764 error = 0;
790 765
766 /* add additional host specific attributes */
791 if (sdev->host->hostt->sdev_attrs) { 767 if (sdev->host->hostt->sdev_attrs) {
792 for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { 768 for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
793 error = attr_add(&sdev->sdev_gendev, 769 error = device_create_file(&sdev->sdev_gendev,
794 sdev->host->hostt->sdev_attrs[i]); 770 sdev->host->hostt->sdev_attrs[i]);
795 if (error) { 771 if (error) {
796 __scsi_remove_device(sdev); 772 __scsi_remove_device(sdev);
@@ -798,20 +774,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
798 } 774 }
799 } 775 }
800 } 776 }
801
802 for (i = 0; scsi_sysfs_sdev_attrs[i]; i++) {
803 if (!attr_overridden(sdev->host->hostt->sdev_attrs,
804 scsi_sysfs_sdev_attrs[i])) {
805 struct device_attribute * attr =
806 attr_changed_internally(sdev->host,
807 scsi_sysfs_sdev_attrs[i]);
808 error = device_create_file(&sdev->sdev_gendev, attr);
809 if (error) {
810 __scsi_remove_device(sdev);
811 goto out;
812 }
813 }
814 }
815 777
816 transport_add_device(&sdev->sdev_gendev); 778 transport_add_device(&sdev->sdev_gendev);
817 out: 779 out:
@@ -998,6 +960,12 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost)
998 return 0; 960 return 0;
999} 961}
1000 962
963static struct device_type scsi_dev_type = {
964 .name = "scsi_device",
965 .release = scsi_device_dev_release,
966 .groups = scsi_sdev_attr_groups,
967};
968
1001void scsi_sysfs_device_initialize(struct scsi_device *sdev) 969void scsi_sysfs_device_initialize(struct scsi_device *sdev)
1002{ 970{
1003 unsigned long flags; 971 unsigned long flags;
@@ -1006,7 +974,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
1006 974
1007 device_initialize(&sdev->sdev_gendev); 975 device_initialize(&sdev->sdev_gendev);
1008 sdev->sdev_gendev.bus = &scsi_bus_type; 976 sdev->sdev_gendev.bus = &scsi_bus_type;
1009 sdev->sdev_gendev.release = scsi_device_dev_release; 977 sdev->sdev_gendev.type = &scsi_dev_type;
1010 sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d", 978 sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d",
1011 sdev->host->host_no, sdev->channel, sdev->id, 979 sdev->host->host_no, sdev->channel, sdev->id,
1012 sdev->lun); 980 sdev->lun);