diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2006-10-10 15:19:21 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2006-12-07 15:29:57 -0500 |
commit | c1c9c7cd9f33ad6ff4407638060fe2730560bd56 (patch) | |
tree | 9c8f6eb326ccdba907a64c99f1b1f75604b0ff85 /drivers/ieee1394 | |
parent | 1ed891c6d49e97ebd3305d8c6213246a14f0800f (diff) |
ieee1394: handle sysfs errors
Handle driver core errors with as much care as appropriate.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r-- | drivers/ieee1394/hosts.c | 18 | ||||
-rw-r--r-- | drivers/ieee1394/nodemgr.c | 149 |
2 files changed, 118 insertions, 49 deletions
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index fbf17cfe79b0..ee82a5320bf7 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c | |||
@@ -131,10 +131,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, | |||
131 | return NULL; | 131 | return NULL; |
132 | 132 | ||
133 | h->csr.rom = csr1212_create_csr(&csr_bus_ops, CSR_BUS_INFO_SIZE, h); | 133 | h->csr.rom = csr1212_create_csr(&csr_bus_ops, CSR_BUS_INFO_SIZE, h); |
134 | if (!h->csr.rom) { | 134 | if (!h->csr.rom) |
135 | kfree(h); | 135 | goto fail; |
136 | return NULL; | ||
137 | } | ||
138 | 136 | ||
139 | h->hostdata = h + 1; | 137 | h->hostdata = h + 1; |
140 | h->driver = drv; | 138 | h->driver = drv; |
@@ -173,11 +171,19 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, | |||
173 | h->class_dev.class = &hpsb_host_class; | 171 | h->class_dev.class = &hpsb_host_class; |
174 | snprintf(h->class_dev.class_id, BUS_ID_SIZE, "fw-host%d", h->id); | 172 | snprintf(h->class_dev.class_id, BUS_ID_SIZE, "fw-host%d", h->id); |
175 | 173 | ||
176 | device_register(&h->device); | 174 | if (device_register(&h->device)) |
177 | class_device_register(&h->class_dev); | 175 | goto fail; |
176 | if (class_device_register(&h->class_dev)) { | ||
177 | device_unregister(&h->device); | ||
178 | goto fail; | ||
179 | } | ||
178 | get_device(&h->device); | 180 | get_device(&h->device); |
179 | 181 | ||
180 | return h; | 182 | return h; |
183 | |||
184 | fail: | ||
185 | kfree(h); | ||
186 | return NULL; | ||
181 | } | 187 | } |
182 | 188 | ||
183 | int hpsb_add_host(struct hpsb_host *host) | 189 | int hpsb_add_host(struct hpsb_host *host) |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index e829c9336b3c..e95fe400e04d 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -413,11 +413,14 @@ static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf) | |||
413 | static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node); | 413 | static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node); |
414 | 414 | ||
415 | 415 | ||
416 | static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, size_t count) | 416 | static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, |
417 | size_t count) | ||
417 | { | 418 | { |
419 | int error = 0; | ||
420 | |||
418 | if (simple_strtoul(buf, NULL, 10) == 1) | 421 | if (simple_strtoul(buf, NULL, 10) == 1) |
419 | bus_rescan_devices(&ieee1394_bus_type); | 422 | error = bus_rescan_devices(&ieee1394_bus_type); |
420 | return count; | 423 | return error ? error : count; |
421 | } | 424 | } |
422 | static ssize_t fw_get_rescan(struct bus_type *bus, char *buf) | 425 | static ssize_t fw_get_rescan(struct bus_type *bus, char *buf) |
423 | { | 426 | { |
@@ -583,7 +586,11 @@ static void nodemgr_create_drv_files(struct hpsb_protocol_driver *driver) | |||
583 | int i; | 586 | int i; |
584 | 587 | ||
585 | for (i = 0; i < ARRAY_SIZE(fw_drv_attrs); i++) | 588 | for (i = 0; i < ARRAY_SIZE(fw_drv_attrs); i++) |
586 | driver_create_file(drv, fw_drv_attrs[i]); | 589 | if (driver_create_file(drv, fw_drv_attrs[i])) |
590 | goto fail; | ||
591 | return; | ||
592 | fail: | ||
593 | HPSB_ERR("Failed to add sysfs attribute for driver %s", driver->name); | ||
587 | } | 594 | } |
588 | 595 | ||
589 | 596 | ||
@@ -603,7 +610,12 @@ static void nodemgr_create_ne_dev_files(struct node_entry *ne) | |||
603 | int i; | 610 | int i; |
604 | 611 | ||
605 | for (i = 0; i < ARRAY_SIZE(fw_ne_attrs); i++) | 612 | for (i = 0; i < ARRAY_SIZE(fw_ne_attrs); i++) |
606 | device_create_file(dev, fw_ne_attrs[i]); | 613 | if (device_create_file(dev, fw_ne_attrs[i])) |
614 | goto fail; | ||
615 | return; | ||
616 | fail: | ||
617 | HPSB_ERR("Failed to add sysfs attribute for node %016Lx", | ||
618 | (unsigned long long)ne->guid); | ||
607 | } | 619 | } |
608 | 620 | ||
609 | 621 | ||
@@ -613,11 +625,16 @@ static void nodemgr_create_host_dev_files(struct hpsb_host *host) | |||
613 | int i; | 625 | int i; |
614 | 626 | ||
615 | for (i = 0; i < ARRAY_SIZE(fw_host_attrs); i++) | 627 | for (i = 0; i < ARRAY_SIZE(fw_host_attrs); i++) |
616 | device_create_file(dev, fw_host_attrs[i]); | 628 | if (device_create_file(dev, fw_host_attrs[i])) |
629 | goto fail; | ||
630 | return; | ||
631 | fail: | ||
632 | HPSB_ERR("Failed to add sysfs attribute for host %d", host->id); | ||
617 | } | 633 | } |
618 | 634 | ||
619 | 635 | ||
620 | static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t nodeid); | 636 | static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, |
637 | nodeid_t nodeid); | ||
621 | 638 | ||
622 | static void nodemgr_update_host_dev_links(struct hpsb_host *host) | 639 | static void nodemgr_update_host_dev_links(struct hpsb_host *host) |
623 | { | 640 | { |
@@ -628,12 +645,18 @@ static void nodemgr_update_host_dev_links(struct hpsb_host *host) | |||
628 | sysfs_remove_link(&dev->kobj, "busmgr_id"); | 645 | sysfs_remove_link(&dev->kobj, "busmgr_id"); |
629 | sysfs_remove_link(&dev->kobj, "host_id"); | 646 | sysfs_remove_link(&dev->kobj, "host_id"); |
630 | 647 | ||
631 | if ((ne = find_entry_by_nodeid(host, host->irm_id))) | 648 | if ((ne = find_entry_by_nodeid(host, host->irm_id)) && |
632 | sysfs_create_link(&dev->kobj, &ne->device.kobj, "irm_id"); | 649 | sysfs_create_link(&dev->kobj, &ne->device.kobj, "irm_id")) |
633 | if ((ne = find_entry_by_nodeid(host, host->busmgr_id))) | 650 | goto fail; |
634 | sysfs_create_link(&dev->kobj, &ne->device.kobj, "busmgr_id"); | 651 | if ((ne = find_entry_by_nodeid(host, host->busmgr_id)) && |
635 | if ((ne = find_entry_by_nodeid(host, host->node_id))) | 652 | sysfs_create_link(&dev->kobj, &ne->device.kobj, "busmgr_id")) |
636 | sysfs_create_link(&dev->kobj, &ne->device.kobj, "host_id"); | 653 | goto fail; |
654 | if ((ne = find_entry_by_nodeid(host, host->node_id)) && | ||
655 | sysfs_create_link(&dev->kobj, &ne->device.kobj, "host_id")) | ||
656 | goto fail; | ||
657 | return; | ||
658 | fail: | ||
659 | HPSB_ERR("Failed to update sysfs attributes for host %d", host->id); | ||
637 | } | 660 | } |
638 | 661 | ||
639 | static void nodemgr_create_ud_dev_files(struct unit_directory *ud) | 662 | static void nodemgr_create_ud_dev_files(struct unit_directory *ud) |
@@ -642,25 +665,32 @@ static void nodemgr_create_ud_dev_files(struct unit_directory *ud) | |||
642 | int i; | 665 | int i; |
643 | 666 | ||
644 | for (i = 0; i < ARRAY_SIZE(fw_ud_attrs); i++) | 667 | for (i = 0; i < ARRAY_SIZE(fw_ud_attrs); i++) |
645 | device_create_file(dev, fw_ud_attrs[i]); | 668 | if (device_create_file(dev, fw_ud_attrs[i])) |
646 | 669 | goto fail; | |
647 | if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID) | 670 | if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID) |
648 | device_create_file(dev, &dev_attr_ud_specifier_id); | 671 | if (device_create_file(dev, &dev_attr_ud_specifier_id)) |
649 | 672 | goto fail; | |
650 | if (ud->flags & UNIT_DIRECTORY_VERSION) | 673 | if (ud->flags & UNIT_DIRECTORY_VERSION) |
651 | device_create_file(dev, &dev_attr_ud_version); | 674 | if (device_create_file(dev, &dev_attr_ud_version)) |
652 | 675 | goto fail; | |
653 | if (ud->flags & UNIT_DIRECTORY_VENDOR_ID) { | 676 | if (ud->flags & UNIT_DIRECTORY_VENDOR_ID) { |
654 | device_create_file(dev, &dev_attr_ud_vendor_id); | 677 | if (device_create_file(dev, &dev_attr_ud_vendor_id)) |
655 | if (ud->vendor_name_kv) | 678 | goto fail; |
656 | device_create_file(dev, &dev_attr_ud_vendor_name_kv); | 679 | if (ud->vendor_name_kv && |
680 | device_create_file(dev, &dev_attr_ud_vendor_name_kv)) | ||
681 | goto fail; | ||
657 | } | 682 | } |
658 | |||
659 | if (ud->flags & UNIT_DIRECTORY_MODEL_ID) { | 683 | if (ud->flags & UNIT_DIRECTORY_MODEL_ID) { |
660 | device_create_file(dev, &dev_attr_ud_model_id); | 684 | if (device_create_file(dev, &dev_attr_ud_model_id)) |
661 | if (ud->model_name_kv) | 685 | goto fail; |
662 | device_create_file(dev, &dev_attr_ud_model_name_kv); | 686 | if (ud->model_name_kv && |
687 | device_create_file(dev, &dev_attr_ud_model_name_kv)) | ||
688 | goto fail; | ||
663 | } | 689 | } |
690 | return; | ||
691 | fail: | ||
692 | HPSB_ERR("Failed to add sysfs attributes for unit %s", | ||
693 | ud->device.bus_id); | ||
664 | } | 694 | } |
665 | 695 | ||
666 | 696 | ||
@@ -748,7 +778,7 @@ static int __nodemgr_remove_host_dev(struct device *dev, void *data) | |||
748 | 778 | ||
749 | static void nodemgr_remove_host_dev(struct device *dev) | 779 | static void nodemgr_remove_host_dev(struct device *dev) |
750 | { | 780 | { |
751 | device_for_each_child(dev, NULL, __nodemgr_remove_host_dev); | 781 | WARN_ON(device_for_each_child(dev, NULL, __nodemgr_remove_host_dev)); |
752 | sysfs_remove_link(&dev->kobj, "irm_id"); | 782 | sysfs_remove_link(&dev->kobj, "irm_id"); |
753 | sysfs_remove_link(&dev->kobj, "busmgr_id"); | 783 | sysfs_remove_link(&dev->kobj, "busmgr_id"); |
754 | sysfs_remove_link(&dev->kobj, "host_id"); | 784 | sysfs_remove_link(&dev->kobj, "host_id"); |
@@ -792,7 +822,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr | |||
792 | 822 | ||
793 | ne = kzalloc(sizeof(*ne), GFP_KERNEL); | 823 | ne = kzalloc(sizeof(*ne), GFP_KERNEL); |
794 | if (!ne) | 824 | if (!ne) |
795 | return NULL; | 825 | goto fail_alloc; |
796 | 826 | ||
797 | ne->host = host; | 827 | ne->host = host; |
798 | ne->nodeid = nodeid; | 828 | ne->nodeid = nodeid; |
@@ -815,12 +845,15 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr | |||
815 | snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx", | 845 | snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx", |
816 | (unsigned long long)(ne->guid)); | 846 | (unsigned long long)(ne->guid)); |
817 | 847 | ||
818 | device_register(&ne->device); | 848 | if (device_register(&ne->device)) |
819 | class_device_register(&ne->class_dev); | 849 | goto fail_devreg; |
850 | if (class_device_register(&ne->class_dev)) | ||
851 | goto fail_classdevreg; | ||
820 | get_device(&ne->device); | 852 | get_device(&ne->device); |
821 | 853 | ||
822 | if (ne->guid_vendor_oui) | 854 | if (ne->guid_vendor_oui && |
823 | device_create_file(&ne->device, &dev_attr_ne_guid_vendor_oui); | 855 | device_create_file(&ne->device, &dev_attr_ne_guid_vendor_oui)) |
856 | goto fail_addoiu; | ||
824 | nodemgr_create_ne_dev_files(ne); | 857 | nodemgr_create_ne_dev_files(ne); |
825 | 858 | ||
826 | nodemgr_update_bus_options(ne); | 859 | nodemgr_update_bus_options(ne); |
@@ -830,6 +863,18 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr | |||
830 | NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid); | 863 | NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid); |
831 | 864 | ||
832 | return ne; | 865 | return ne; |
866 | |||
867 | fail_addoiu: | ||
868 | put_device(&ne->device); | ||
869 | fail_classdevreg: | ||
870 | device_unregister(&ne->device); | ||
871 | fail_devreg: | ||
872 | kfree(ne); | ||
873 | fail_alloc: | ||
874 | HPSB_ERR("Failed to create node ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | ||
875 | NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid); | ||
876 | |||
877 | return NULL; | ||
833 | } | 878 | } |
834 | 879 | ||
835 | 880 | ||
@@ -891,13 +936,25 @@ static void nodemgr_register_device(struct node_entry *ne, | |||
891 | snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u", | 936 | snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u", |
892 | ne->device.bus_id, ud->id); | 937 | ne->device.bus_id, ud->id); |
893 | 938 | ||
894 | device_register(&ud->device); | 939 | if (device_register(&ud->device)) |
895 | class_device_register(&ud->class_dev); | 940 | goto fail_devreg; |
941 | if (class_device_register(&ud->class_dev)) | ||
942 | goto fail_classdevreg; | ||
896 | get_device(&ud->device); | 943 | get_device(&ud->device); |
897 | 944 | ||
898 | if (ud->vendor_oui) | 945 | if (ud->vendor_oui && |
899 | device_create_file(&ud->device, &dev_attr_ud_vendor_oui); | 946 | device_create_file(&ud->device, &dev_attr_ud_vendor_oui)) |
947 | goto fail_addoui; | ||
900 | nodemgr_create_ud_dev_files(ud); | 948 | nodemgr_create_ud_dev_files(ud); |
949 | |||
950 | return; | ||
951 | |||
952 | fail_addoui: | ||
953 | put_device(&ud->device); | ||
954 | fail_classdevreg: | ||
955 | device_unregister(&ud->device); | ||
956 | fail_devreg: | ||
957 | HPSB_ERR("Failed to create unit %s", ud->device.bus_id); | ||
901 | } | 958 | } |
902 | 959 | ||
903 | 960 | ||
@@ -1094,10 +1151,16 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent | |||
1094 | last_key_id = kv->key.id; | 1151 | last_key_id = kv->key.id; |
1095 | } | 1152 | } |
1096 | 1153 | ||
1097 | if (ne->vendor_oui) | 1154 | if (ne->vendor_oui && |
1098 | device_create_file(&ne->device, &dev_attr_ne_vendor_oui); | 1155 | device_create_file(&ne->device, &dev_attr_ne_vendor_oui)) |
1099 | if (ne->vendor_name_kv) | 1156 | goto fail; |
1100 | device_create_file(&ne->device, &dev_attr_ne_vendor_name_kv); | 1157 | if (ne->vendor_name_kv && |
1158 | device_create_file(&ne->device, &dev_attr_ne_vendor_name_kv)) | ||
1159 | goto fail; | ||
1160 | return; | ||
1161 | fail: | ||
1162 | HPSB_ERR("Failed to add sysfs attribute for node %016Lx", | ||
1163 | (unsigned long long)ne->guid); | ||
1101 | } | 1164 | } |
1102 | 1165 | ||
1103 | #ifdef CONFIG_HOTPLUG | 1166 | #ifdef CONFIG_HOTPLUG |
@@ -1170,7 +1233,7 @@ int hpsb_register_protocol(struct hpsb_protocol_driver *driver) | |||
1170 | if (!ret) | 1233 | if (!ret) |
1171 | nodemgr_create_drv_files(driver); | 1234 | nodemgr_create_drv_files(driver); |
1172 | 1235 | ||
1173 | return ret; | 1236 | return 0; |
1174 | } | 1237 | } |
1175 | 1238 | ||
1176 | void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver) | 1239 | void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver) |
@@ -1327,7 +1390,7 @@ static void nodemgr_suspend_ne(struct node_entry *ne) | |||
1327 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); | 1390 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); |
1328 | 1391 | ||
1329 | ne->in_limbo = 1; | 1392 | ne->in_limbo = 1; |
1330 | device_create_file(&ne->device, &dev_attr_ne_in_limbo); | 1393 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); |
1331 | 1394 | ||
1332 | down_write(&ne->device.bus->subsys.rwsem); | 1395 | down_write(&ne->device.bus->subsys.rwsem); |
1333 | list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { | 1396 | list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { |
@@ -1498,7 +1561,7 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) | |||
1498 | * just removed. */ | 1561 | * just removed. */ |
1499 | 1562 | ||
1500 | if (generation == get_hpsb_generation(host)) | 1563 | if (generation == get_hpsb_generation(host)) |
1501 | bus_rescan_devices(&ieee1394_bus_type); | 1564 | WARN_ON(bus_rescan_devices(&ieee1394_bus_type)); |
1502 | 1565 | ||
1503 | return; | 1566 | return; |
1504 | } | 1567 | } |