diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-28 11:26:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-28 11:26:12 -0400 |
commit | 7a9787e1eba95a166265e6a260cf30af04ef0a99 (patch) | |
tree | e730a4565e0318140d2fbd2f0415d18a339d7336 /drivers/ieee1394/nodemgr.c | |
parent | 41b9eb264c8407655db57b60b4457fe1b2ec9977 (diff) | |
parent | 0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff) |
Merge commit 'v2.6.28-rc2' into x86/pci-ioapic-boot-irq-quirks
Diffstat (limited to 'drivers/ieee1394/nodemgr.c')
-rw-r--r-- | drivers/ieee1394/nodemgr.c | 319 |
1 files changed, 133 insertions, 186 deletions
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 05710c7c1220..2376b729e876 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -154,9 +154,6 @@ struct host_info { | |||
154 | 154 | ||
155 | static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); | 155 | static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); |
156 | static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env); | 156 | static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env); |
157 | static void nodemgr_resume_ne(struct node_entry *ne); | ||
158 | static void nodemgr_remove_ne(struct node_entry *ne); | ||
159 | static struct node_entry *find_entry_by_guid(u64 guid); | ||
160 | 157 | ||
161 | struct bus_type ieee1394_bus_type = { | 158 | struct bus_type ieee1394_bus_type = { |
162 | .name = "ieee1394", | 159 | .name = "ieee1394", |
@@ -385,27 +382,6 @@ static ssize_t fw_get_ignore_driver(struct device *dev, struct device_attribute | |||
385 | static DEVICE_ATTR(ignore_driver, S_IWUSR | S_IRUGO, fw_get_ignore_driver, fw_set_ignore_driver); | 382 | static DEVICE_ATTR(ignore_driver, S_IWUSR | S_IRUGO, fw_get_ignore_driver, fw_set_ignore_driver); |
386 | 383 | ||
387 | 384 | ||
388 | static ssize_t fw_set_destroy_node(struct bus_type *bus, const char *buf, size_t count) | ||
389 | { | ||
390 | struct node_entry *ne; | ||
391 | u64 guid = (u64)simple_strtoull(buf, NULL, 16); | ||
392 | |||
393 | ne = find_entry_by_guid(guid); | ||
394 | |||
395 | if (ne == NULL || !ne->in_limbo) | ||
396 | return -EINVAL; | ||
397 | |||
398 | nodemgr_remove_ne(ne); | ||
399 | |||
400 | return count; | ||
401 | } | ||
402 | static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf) | ||
403 | { | ||
404 | return sprintf(buf, "You can destroy in_limbo nodes by writing their GUID to this file\n"); | ||
405 | } | ||
406 | static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node); | ||
407 | |||
408 | |||
409 | static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, | 385 | static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, |
410 | size_t count) | 386 | size_t count) |
411 | { | 387 | { |
@@ -442,7 +418,6 @@ static BUS_ATTR(ignore_drivers, S_IWUSR | S_IRUGO, fw_get_ignore_drivers, fw_set | |||
442 | 418 | ||
443 | 419 | ||
444 | struct bus_attribute *const fw_bus_attrs[] = { | 420 | struct bus_attribute *const fw_bus_attrs[] = { |
445 | &bus_attr_destroy_node, | ||
446 | &bus_attr_rescan, | 421 | &bus_attr_rescan, |
447 | &bus_attr_ignore_drivers, | 422 | &bus_attr_ignore_drivers, |
448 | NULL | 423 | NULL |
@@ -734,10 +709,10 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv) | |||
734 | 709 | ||
735 | static DEFINE_MUTEX(nodemgr_serialize_remove_uds); | 710 | static DEFINE_MUTEX(nodemgr_serialize_remove_uds); |
736 | 711 | ||
737 | static int __match_ne(struct device *dev, void *data) | 712 | static int match_ne(struct device *dev, void *data) |
738 | { | 713 | { |
739 | struct unit_directory *ud; | 714 | struct unit_directory *ud; |
740 | struct node_entry *ne = (struct node_entry *)data; | 715 | struct node_entry *ne = data; |
741 | 716 | ||
742 | ud = container_of(dev, struct unit_directory, unit_dev); | 717 | ud = container_of(dev, struct unit_directory, unit_dev); |
743 | return ud->ne == ne; | 718 | return ud->ne == ne; |
@@ -754,7 +729,7 @@ static void nodemgr_remove_uds(struct node_entry *ne) | |||
754 | */ | 729 | */ |
755 | mutex_lock(&nodemgr_serialize_remove_uds); | 730 | mutex_lock(&nodemgr_serialize_remove_uds); |
756 | for (;;) { | 731 | for (;;) { |
757 | dev = class_find_device(&nodemgr_ud_class, ne, __match_ne); | 732 | dev = class_find_device(&nodemgr_ud_class, NULL, ne, match_ne); |
758 | if (!dev) | 733 | if (!dev) |
759 | break; | 734 | break; |
760 | ud = container_of(dev, struct unit_directory, unit_dev); | 735 | ud = container_of(dev, struct unit_directory, unit_dev); |
@@ -784,7 +759,7 @@ static void nodemgr_remove_ne(struct node_entry *ne) | |||
784 | put_device(dev); | 759 | put_device(dev); |
785 | } | 760 | } |
786 | 761 | ||
787 | static int __nodemgr_remove_host_dev(struct device *dev, void *data) | 762 | static int remove_host_dev(struct device *dev, void *data) |
788 | { | 763 | { |
789 | if (dev->bus == &ieee1394_bus_type) | 764 | if (dev->bus == &ieee1394_bus_type) |
790 | nodemgr_remove_ne(container_of(dev, struct node_entry, | 765 | nodemgr_remove_ne(container_of(dev, struct node_entry, |
@@ -794,7 +769,7 @@ static int __nodemgr_remove_host_dev(struct device *dev, void *data) | |||
794 | 769 | ||
795 | static void nodemgr_remove_host_dev(struct device *dev) | 770 | static void nodemgr_remove_host_dev(struct device *dev) |
796 | { | 771 | { |
797 | WARN_ON(device_for_each_child(dev, NULL, __nodemgr_remove_host_dev)); | 772 | device_for_each_child(dev, NULL, remove_host_dev); |
798 | sysfs_remove_link(&dev->kobj, "irm_id"); | 773 | sysfs_remove_link(&dev->kobj, "irm_id"); |
799 | sysfs_remove_link(&dev->kobj, "busmgr_id"); | 774 | sysfs_remove_link(&dev->kobj, "busmgr_id"); |
800 | sysfs_remove_link(&dev->kobj, "host_id"); | 775 | sysfs_remove_link(&dev->kobj, "host_id"); |
@@ -829,11 +804,10 @@ static void nodemgr_update_bus_options(struct node_entry *ne) | |||
829 | } | 804 | } |
830 | 805 | ||
831 | 806 | ||
832 | static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr *csr, | 807 | static struct node_entry *nodemgr_create_node(octlet_t guid, |
833 | struct host_info *hi, nodeid_t nodeid, | 808 | struct csr1212_csr *csr, struct hpsb_host *host, |
834 | unsigned int generation) | 809 | nodeid_t nodeid, unsigned int generation) |
835 | { | 810 | { |
836 | struct hpsb_host *host = hi->host; | ||
837 | struct node_entry *ne; | 811 | struct node_entry *ne; |
838 | 812 | ||
839 | ne = kzalloc(sizeof(*ne), GFP_KERNEL); | 813 | ne = kzalloc(sizeof(*ne), GFP_KERNEL); |
@@ -843,7 +817,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr | |||
843 | ne->host = host; | 817 | ne->host = host; |
844 | ne->nodeid = nodeid; | 818 | ne->nodeid = nodeid; |
845 | ne->generation = generation; | 819 | ne->generation = generation; |
846 | ne->needs_probe = 1; | 820 | ne->needs_probe = true; |
847 | 821 | ||
848 | ne->guid = guid; | 822 | ne->guid = guid; |
849 | ne->guid_vendor_id = (guid >> 40) & 0xffffff; | 823 | ne->guid_vendor_id = (guid >> 40) & 0xffffff; |
@@ -887,10 +861,10 @@ fail_alloc: | |||
887 | return NULL; | 861 | return NULL; |
888 | } | 862 | } |
889 | 863 | ||
890 | static int __match_ne_guid(struct device *dev, void *data) | 864 | static int match_ne_guid(struct device *dev, void *data) |
891 | { | 865 | { |
892 | struct node_entry *ne; | 866 | struct node_entry *ne; |
893 | u64 *guid = (u64 *)data; | 867 | u64 *guid = data; |
894 | 868 | ||
895 | ne = container_of(dev, struct node_entry, node_dev); | 869 | ne = container_of(dev, struct node_entry, node_dev); |
896 | return ne->guid == *guid; | 870 | return ne->guid == *guid; |
@@ -901,7 +875,7 @@ static struct node_entry *find_entry_by_guid(u64 guid) | |||
901 | struct device *dev; | 875 | struct device *dev; |
902 | struct node_entry *ne; | 876 | struct node_entry *ne; |
903 | 877 | ||
904 | dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid); | 878 | dev = class_find_device(&nodemgr_ne_class, NULL, &guid, match_ne_guid); |
905 | if (!dev) | 879 | if (!dev) |
906 | return NULL; | 880 | return NULL; |
907 | ne = container_of(dev, struct node_entry, node_dev); | 881 | ne = container_of(dev, struct node_entry, node_dev); |
@@ -910,21 +884,21 @@ static struct node_entry *find_entry_by_guid(u64 guid) | |||
910 | return ne; | 884 | return ne; |
911 | } | 885 | } |
912 | 886 | ||
913 | struct match_nodeid_param { | 887 | struct match_nodeid_parameter { |
914 | struct hpsb_host *host; | 888 | struct hpsb_host *host; |
915 | nodeid_t nodeid; | 889 | nodeid_t nodeid; |
916 | }; | 890 | }; |
917 | 891 | ||
918 | static int __match_ne_nodeid(struct device *dev, void *data) | 892 | static int match_ne_nodeid(struct device *dev, void *data) |
919 | { | 893 | { |
920 | int found = 0; | 894 | int found = 0; |
921 | struct node_entry *ne; | 895 | struct node_entry *ne; |
922 | struct match_nodeid_param *param = (struct match_nodeid_param *)data; | 896 | struct match_nodeid_parameter *p = data; |
923 | 897 | ||
924 | if (!dev) | 898 | if (!dev) |
925 | goto ret; | 899 | goto ret; |
926 | ne = container_of(dev, struct node_entry, node_dev); | 900 | ne = container_of(dev, struct node_entry, node_dev); |
927 | if (ne->host == param->host && ne->nodeid == param->nodeid) | 901 | if (ne->host == p->host && ne->nodeid == p->nodeid) |
928 | found = 1; | 902 | found = 1; |
929 | ret: | 903 | ret: |
930 | return found; | 904 | return found; |
@@ -935,12 +909,12 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, | |||
935 | { | 909 | { |
936 | struct device *dev; | 910 | struct device *dev; |
937 | struct node_entry *ne; | 911 | struct node_entry *ne; |
938 | struct match_nodeid_param param; | 912 | struct match_nodeid_parameter p; |
939 | 913 | ||
940 | param.host = host; | 914 | p.host = host; |
941 | param.nodeid = nodeid; | 915 | p.nodeid = nodeid; |
942 | 916 | ||
943 | dev = class_find_device(&nodemgr_ne_class, ¶m, __match_ne_nodeid); | 917 | dev = class_find_device(&nodemgr_ne_class, NULL, &p, match_ne_nodeid); |
944 | if (!dev) | 918 | if (!dev) |
945 | return NULL; | 919 | return NULL; |
946 | ne = container_of(dev, struct node_entry, node_dev); | 920 | ne = container_of(dev, struct node_entry, node_dev); |
@@ -987,7 +961,7 @@ fail_devreg: | |||
987 | * immediate unit directories looking for software_id and | 961 | * immediate unit directories looking for software_id and |
988 | * software_version entries, in order to get driver autoloading working. */ | 962 | * software_version entries, in order to get driver autoloading working. */ |
989 | static struct unit_directory *nodemgr_process_unit_directory | 963 | static struct unit_directory *nodemgr_process_unit_directory |
990 | (struct host_info *hi, struct node_entry *ne, struct csr1212_keyval *ud_kv, | 964 | (struct node_entry *ne, struct csr1212_keyval *ud_kv, |
991 | unsigned int *id, struct unit_directory *parent) | 965 | unsigned int *id, struct unit_directory *parent) |
992 | { | 966 | { |
993 | struct unit_directory *ud; | 967 | struct unit_directory *ud; |
@@ -1080,7 +1054,7 @@ static struct unit_directory *nodemgr_process_unit_directory | |||
1080 | nodemgr_register_device(ne, ud, &ne->device); | 1054 | nodemgr_register_device(ne, ud, &ne->device); |
1081 | 1055 | ||
1082 | /* process the child unit */ | 1056 | /* process the child unit */ |
1083 | ud_child = nodemgr_process_unit_directory(hi, ne, kv, id, ud); | 1057 | ud_child = nodemgr_process_unit_directory(ne, kv, id, ud); |
1084 | 1058 | ||
1085 | if (ud_child == NULL) | 1059 | if (ud_child == NULL) |
1086 | break; | 1060 | break; |
@@ -1134,14 +1108,14 @@ unit_directory_error: | |||
1134 | } | 1108 | } |
1135 | 1109 | ||
1136 | 1110 | ||
1137 | static void nodemgr_process_root_directory(struct host_info *hi, struct node_entry *ne) | 1111 | static void nodemgr_process_root_directory(struct node_entry *ne) |
1138 | { | 1112 | { |
1139 | unsigned int ud_id = 0; | 1113 | unsigned int ud_id = 0; |
1140 | struct csr1212_dentry *dentry; | 1114 | struct csr1212_dentry *dentry; |
1141 | struct csr1212_keyval *kv, *vendor_name_kv = NULL; | 1115 | struct csr1212_keyval *kv, *vendor_name_kv = NULL; |
1142 | u8 last_key_id = 0; | 1116 | u8 last_key_id = 0; |
1143 | 1117 | ||
1144 | ne->needs_probe = 0; | 1118 | ne->needs_probe = false; |
1145 | 1119 | ||
1146 | csr1212_for_each_dir_entry(ne->csr, kv, ne->csr->root_kv, dentry) { | 1120 | csr1212_for_each_dir_entry(ne->csr, kv, ne->csr->root_kv, dentry) { |
1147 | switch (kv->key.id) { | 1121 | switch (kv->key.id) { |
@@ -1154,7 +1128,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent | |||
1154 | break; | 1128 | break; |
1155 | 1129 | ||
1156 | case CSR1212_KV_ID_UNIT: | 1130 | case CSR1212_KV_ID_UNIT: |
1157 | nodemgr_process_unit_directory(hi, ne, kv, &ud_id, NULL); | 1131 | nodemgr_process_unit_directory(ne, kv, &ud_id, NULL); |
1158 | break; | 1132 | break; |
1159 | 1133 | ||
1160 | case CSR1212_KV_ID_DESCRIPTOR: | 1134 | case CSR1212_KV_ID_DESCRIPTOR: |
@@ -1270,8 +1244,7 @@ void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver) | |||
1270 | * the to take whatever actions required. | 1244 | * the to take whatever actions required. |
1271 | */ | 1245 | */ |
1272 | static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, | 1246 | static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, |
1273 | struct host_info *hi, nodeid_t nodeid, | 1247 | nodeid_t nodeid, unsigned int generation) |
1274 | unsigned int generation) | ||
1275 | { | 1248 | { |
1276 | if (ne->nodeid != nodeid) { | 1249 | if (ne->nodeid != nodeid) { |
1277 | HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT, | 1250 | HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT, |
@@ -1292,7 +1265,7 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, | |||
1292 | nodemgr_update_bus_options(ne); | 1265 | nodemgr_update_bus_options(ne); |
1293 | 1266 | ||
1294 | /* Mark the node as new, so it gets re-probed */ | 1267 | /* Mark the node as new, so it gets re-probed */ |
1295 | ne->needs_probe = 1; | 1268 | ne->needs_probe = true; |
1296 | } else { | 1269 | } else { |
1297 | /* old cache is valid, so update its generation */ | 1270 | /* old cache is valid, so update its generation */ |
1298 | struct nodemgr_csr_info *ci = ne->csr->private; | 1271 | struct nodemgr_csr_info *ci = ne->csr->private; |
@@ -1302,19 +1275,23 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, | |||
1302 | csr1212_destroy_csr(csr); | 1275 | csr1212_destroy_csr(csr); |
1303 | } | 1276 | } |
1304 | 1277 | ||
1305 | if (ne->in_limbo) | ||
1306 | nodemgr_resume_ne(ne); | ||
1307 | |||
1308 | /* Mark the node current */ | 1278 | /* Mark the node current */ |
1309 | ne->generation = generation; | 1279 | ne->generation = generation; |
1310 | } | ||
1311 | 1280 | ||
1281 | if (ne->in_limbo) { | ||
1282 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); | ||
1283 | ne->in_limbo = false; | ||
1312 | 1284 | ||
1285 | HPSB_DEBUG("Node reactivated: " | ||
1286 | "ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | ||
1287 | NODE_BUS_ARGS(ne->host, ne->nodeid), | ||
1288 | (unsigned long long)ne->guid); | ||
1289 | } | ||
1290 | } | ||
1313 | 1291 | ||
1314 | static void nodemgr_node_scan_one(struct host_info *hi, | 1292 | static void nodemgr_node_scan_one(struct hpsb_host *host, |
1315 | nodeid_t nodeid, int generation) | 1293 | nodeid_t nodeid, int generation) |
1316 | { | 1294 | { |
1317 | struct hpsb_host *host = hi->host; | ||
1318 | struct node_entry *ne; | 1295 | struct node_entry *ne; |
1319 | octlet_t guid; | 1296 | octlet_t guid; |
1320 | struct csr1212_csr *csr; | 1297 | struct csr1212_csr *csr; |
@@ -1370,16 +1347,15 @@ static void nodemgr_node_scan_one(struct host_info *hi, | |||
1370 | } | 1347 | } |
1371 | 1348 | ||
1372 | if (!ne) | 1349 | if (!ne) |
1373 | nodemgr_create_node(guid, csr, hi, nodeid, generation); | 1350 | nodemgr_create_node(guid, csr, host, nodeid, generation); |
1374 | else | 1351 | else |
1375 | nodemgr_update_node(ne, csr, hi, nodeid, generation); | 1352 | nodemgr_update_node(ne, csr, nodeid, generation); |
1376 | } | 1353 | } |
1377 | 1354 | ||
1378 | 1355 | ||
1379 | static void nodemgr_node_scan(struct host_info *hi, int generation) | 1356 | static void nodemgr_node_scan(struct hpsb_host *host, int generation) |
1380 | { | 1357 | { |
1381 | int count; | 1358 | int count; |
1382 | struct hpsb_host *host = hi->host; | ||
1383 | struct selfid *sid = (struct selfid *)host->topology_map; | 1359 | struct selfid *sid = (struct selfid *)host->topology_map; |
1384 | nodeid_t nodeid = LOCAL_BUS; | 1360 | nodeid_t nodeid = LOCAL_BUS; |
1385 | 1361 | ||
@@ -1392,87 +1368,26 @@ static void nodemgr_node_scan(struct host_info *hi, int generation) | |||
1392 | nodeid++; | 1368 | nodeid++; |
1393 | continue; | 1369 | continue; |
1394 | } | 1370 | } |
1395 | nodemgr_node_scan_one(hi, nodeid++, generation); | 1371 | nodemgr_node_scan_one(host, nodeid++, generation); |
1396 | } | ||
1397 | } | ||
1398 | |||
1399 | static int __nodemgr_driver_suspend(struct device *dev, void *data) | ||
1400 | { | ||
1401 | struct unit_directory *ud; | ||
1402 | struct device_driver *drv; | ||
1403 | struct node_entry *ne = (struct node_entry *)data; | ||
1404 | int error; | ||
1405 | |||
1406 | ud = container_of(dev, struct unit_directory, unit_dev); | ||
1407 | if (ud->ne == ne) { | ||
1408 | drv = get_driver(ud->device.driver); | ||
1409 | if (drv) { | ||
1410 | error = 1; /* release if suspend is not implemented */ | ||
1411 | if (drv->suspend) { | ||
1412 | down(&ud->device.sem); | ||
1413 | error = drv->suspend(&ud->device, PMSG_SUSPEND); | ||
1414 | up(&ud->device.sem); | ||
1415 | } | ||
1416 | if (error) | ||
1417 | device_release_driver(&ud->device); | ||
1418 | put_driver(drv); | ||
1419 | } | ||
1420 | } | ||
1421 | |||
1422 | return 0; | ||
1423 | } | ||
1424 | |||
1425 | static int __nodemgr_driver_resume(struct device *dev, void *data) | ||
1426 | { | ||
1427 | struct unit_directory *ud; | ||
1428 | struct device_driver *drv; | ||
1429 | struct node_entry *ne = (struct node_entry *)data; | ||
1430 | |||
1431 | ud = container_of(dev, struct unit_directory, unit_dev); | ||
1432 | if (ud->ne == ne) { | ||
1433 | drv = get_driver(ud->device.driver); | ||
1434 | if (drv) { | ||
1435 | if (drv->resume) { | ||
1436 | down(&ud->device.sem); | ||
1437 | drv->resume(&ud->device); | ||
1438 | up(&ud->device.sem); | ||
1439 | } | ||
1440 | put_driver(drv); | ||
1441 | } | ||
1442 | } | 1372 | } |
1443 | |||
1444 | return 0; | ||
1445 | } | 1373 | } |
1446 | 1374 | ||
1447 | static void nodemgr_suspend_ne(struct node_entry *ne) | 1375 | static void nodemgr_pause_ne(struct node_entry *ne) |
1448 | { | 1376 | { |
1449 | HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | 1377 | HPSB_DEBUG("Node paused: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", |
1450 | NODE_BUS_ARGS(ne->host, ne->nodeid), | 1378 | NODE_BUS_ARGS(ne->host, ne->nodeid), |
1451 | (unsigned long long)ne->guid); | 1379 | (unsigned long long)ne->guid); |
1452 | 1380 | ||
1453 | ne->in_limbo = 1; | 1381 | ne->in_limbo = true; |
1454 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); | 1382 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); |
1455 | |||
1456 | class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_suspend); | ||
1457 | } | ||
1458 | |||
1459 | |||
1460 | static void nodemgr_resume_ne(struct node_entry *ne) | ||
1461 | { | ||
1462 | ne->in_limbo = 0; | ||
1463 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); | ||
1464 | |||
1465 | class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_resume); | ||
1466 | HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | ||
1467 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); | ||
1468 | } | 1383 | } |
1469 | 1384 | ||
1470 | static int __nodemgr_update_pdrv(struct device *dev, void *data) | 1385 | static int update_pdrv(struct device *dev, void *data) |
1471 | { | 1386 | { |
1472 | struct unit_directory *ud; | 1387 | struct unit_directory *ud; |
1473 | struct device_driver *drv; | 1388 | struct device_driver *drv; |
1474 | struct hpsb_protocol_driver *pdrv; | 1389 | struct hpsb_protocol_driver *pdrv; |
1475 | struct node_entry *ne = (struct node_entry *)data; | 1390 | struct node_entry *ne = data; |
1476 | int error; | 1391 | int error; |
1477 | 1392 | ||
1478 | ud = container_of(dev, struct unit_directory, unit_dev); | 1393 | ud = container_of(dev, struct unit_directory, unit_dev); |
@@ -1498,10 +1413,9 @@ static int __nodemgr_update_pdrv(struct device *dev, void *data) | |||
1498 | 1413 | ||
1499 | static void nodemgr_update_pdrv(struct node_entry *ne) | 1414 | static void nodemgr_update_pdrv(struct node_entry *ne) |
1500 | { | 1415 | { |
1501 | class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_update_pdrv); | 1416 | class_for_each_device(&nodemgr_ud_class, NULL, ne, update_pdrv); |
1502 | } | 1417 | } |
1503 | 1418 | ||
1504 | |||
1505 | /* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This | 1419 | /* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This |
1506 | * seems like an optional service but in the end it is practically mandatory | 1420 | * seems like an optional service but in the end it is practically mandatory |
1507 | * as a consequence of these clauses. | 1421 | * as a consequence of these clauses. |
@@ -1529,11 +1443,12 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation) | |||
1529 | } | 1443 | } |
1530 | 1444 | ||
1531 | 1445 | ||
1532 | static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation) | 1446 | static void nodemgr_probe_ne(struct hpsb_host *host, struct node_entry *ne, |
1447 | int generation) | ||
1533 | { | 1448 | { |
1534 | struct device *dev; | 1449 | struct device *dev; |
1535 | 1450 | ||
1536 | if (ne->host != hi->host || ne->in_limbo) | 1451 | if (ne->host != host || ne->in_limbo) |
1537 | return; | 1452 | return; |
1538 | 1453 | ||
1539 | dev = get_device(&ne->device); | 1454 | dev = get_device(&ne->device); |
@@ -1548,68 +1463,93 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge | |||
1548 | * down to the drivers. Otherwise, this is a dead node and we | 1463 | * down to the drivers. Otherwise, this is a dead node and we |
1549 | * suspend it. */ | 1464 | * suspend it. */ |
1550 | if (ne->needs_probe) | 1465 | if (ne->needs_probe) |
1551 | nodemgr_process_root_directory(hi, ne); | 1466 | nodemgr_process_root_directory(ne); |
1552 | else if (ne->generation == generation) | 1467 | else if (ne->generation == generation) |
1553 | nodemgr_update_pdrv(ne); | 1468 | nodemgr_update_pdrv(ne); |
1554 | else | 1469 | else |
1555 | nodemgr_suspend_ne(ne); | 1470 | nodemgr_pause_ne(ne); |
1556 | 1471 | ||
1557 | put_device(dev); | 1472 | put_device(dev); |
1558 | } | 1473 | } |
1559 | 1474 | ||
1560 | struct probe_param { | 1475 | struct node_probe_parameter { |
1561 | struct host_info *hi; | 1476 | struct hpsb_host *host; |
1562 | int generation; | 1477 | int generation; |
1478 | bool probe_now; | ||
1563 | }; | 1479 | }; |
1564 | 1480 | ||
1565 | static int __nodemgr_node_probe(struct device *dev, void *data) | 1481 | static int node_probe(struct device *dev, void *data) |
1566 | { | 1482 | { |
1567 | struct probe_param *param = (struct probe_param *)data; | 1483 | struct node_probe_parameter *p = data; |
1568 | struct node_entry *ne; | 1484 | struct node_entry *ne; |
1569 | 1485 | ||
1486 | if (p->generation != get_hpsb_generation(p->host)) | ||
1487 | return -EAGAIN; | ||
1488 | |||
1570 | ne = container_of(dev, struct node_entry, node_dev); | 1489 | ne = container_of(dev, struct node_entry, node_dev); |
1571 | if (!ne->needs_probe) | 1490 | if (ne->needs_probe == p->probe_now) |
1572 | nodemgr_probe_ne(param->hi, ne, param->generation); | 1491 | nodemgr_probe_ne(p->host, ne, p->generation); |
1573 | if (ne->needs_probe) | ||
1574 | nodemgr_probe_ne(param->hi, ne, param->generation); | ||
1575 | return 0; | 1492 | return 0; |
1576 | } | 1493 | } |
1577 | 1494 | ||
1578 | static void nodemgr_node_probe(struct host_info *hi, int generation) | 1495 | static int nodemgr_node_probe(struct hpsb_host *host, int generation) |
1579 | { | 1496 | { |
1580 | struct hpsb_host *host = hi->host; | 1497 | struct node_probe_parameter p; |
1581 | struct probe_param param; | ||
1582 | 1498 | ||
1583 | param.hi = hi; | 1499 | p.host = host; |
1584 | param.generation = generation; | 1500 | p.generation = generation; |
1585 | /* Do some processing of the nodes we've probed. This pulls them | 1501 | /* |
1502 | * Do some processing of the nodes we've probed. This pulls them | ||
1586 | * into the sysfs layer if needed, and can result in processing of | 1503 | * into the sysfs layer if needed, and can result in processing of |
1587 | * unit-directories, or just updating the node and it's | 1504 | * unit-directories, or just updating the node and it's |
1588 | * unit-directories. | 1505 | * unit-directories. |
1589 | * | 1506 | * |
1590 | * Run updates before probes. Usually, updates are time-critical | 1507 | * Run updates before probes. Usually, updates are time-critical |
1591 | * while probes are time-consuming. (Well, those probes need some | 1508 | * while probes are time-consuming. |
1592 | * improvement...) */ | ||
1593 | |||
1594 | class_for_each_device(&nodemgr_ne_class, ¶m, __nodemgr_node_probe); | ||
1595 | |||
1596 | /* If we had a bus reset while we were scanning the bus, it is | ||
1597 | * possible that we did not probe all nodes. In that case, we | ||
1598 | * skip the clean up for now, since we could remove nodes that | ||
1599 | * were still on the bus. Another bus scan is pending which will | ||
1600 | * do the clean up eventually. | ||
1601 | * | 1509 | * |
1510 | * Meanwhile, another bus reset may have happened. In this case we | ||
1511 | * skip everything here and let the next bus scan handle it. | ||
1512 | * Otherwise we may prematurely remove nodes which are still there. | ||
1513 | */ | ||
1514 | p.probe_now = false; | ||
1515 | if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0) | ||
1516 | return 0; | ||
1517 | |||
1518 | p.probe_now = true; | ||
1519 | if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0) | ||
1520 | return 0; | ||
1521 | /* | ||
1602 | * Now let's tell the bus to rescan our devices. This may seem | 1522 | * Now let's tell the bus to rescan our devices. This may seem |
1603 | * like overhead, but the driver-model core will only scan a | 1523 | * like overhead, but the driver-model core will only scan a |
1604 | * device for a driver when either the device is added, or when a | 1524 | * device for a driver when either the device is added, or when a |
1605 | * new driver is added. A bus reset is a good reason to rescan | 1525 | * new driver is added. A bus reset is a good reason to rescan |
1606 | * devices that were there before. For example, an sbp2 device | 1526 | * devices that were there before. For example, an sbp2 device |
1607 | * may become available for login, if the host that held it was | 1527 | * may become available for login, if the host that held it was |
1608 | * just removed. */ | 1528 | * just removed. |
1529 | */ | ||
1530 | if (bus_rescan_devices(&ieee1394_bus_type) != 0) | ||
1531 | HPSB_DEBUG("bus_rescan_devices had an error"); | ||
1609 | 1532 | ||
1610 | if (generation == get_hpsb_generation(host)) | 1533 | return 1; |
1611 | if (bus_rescan_devices(&ieee1394_bus_type)) | 1534 | } |
1612 | HPSB_DEBUG("bus_rescan_devices had an error"); | 1535 | |
1536 | static int remove_nodes_in_limbo(struct device *dev, void *data) | ||
1537 | { | ||
1538 | struct node_entry *ne; | ||
1539 | |||
1540 | if (dev->bus != &ieee1394_bus_type) | ||
1541 | return 0; | ||
1542 | |||
1543 | ne = container_of(dev, struct node_entry, device); | ||
1544 | if (ne->in_limbo) | ||
1545 | nodemgr_remove_ne(ne); | ||
1546 | |||
1547 | return 0; | ||
1548 | } | ||
1549 | |||
1550 | static void nodemgr_remove_nodes_in_limbo(struct hpsb_host *host) | ||
1551 | { | ||
1552 | device_for_each_child(&host->device, NULL, remove_nodes_in_limbo); | ||
1613 | } | 1553 | } |
1614 | 1554 | ||
1615 | static int nodemgr_send_resume_packet(struct hpsb_host *host) | 1555 | static int nodemgr_send_resume_packet(struct hpsb_host *host) |
@@ -1720,10 +1660,9 @@ static int nodemgr_check_irm_capability(struct hpsb_host *host, int cycles) | |||
1720 | return 1; | 1660 | return 1; |
1721 | } | 1661 | } |
1722 | 1662 | ||
1723 | static int nodemgr_host_thread(void *__hi) | 1663 | static int nodemgr_host_thread(void *data) |
1724 | { | 1664 | { |
1725 | struct host_info *hi = (struct host_info *)__hi; | 1665 | struct hpsb_host *host = data; |
1726 | struct hpsb_host *host = hi->host; | ||
1727 | unsigned int g, generation = 0; | 1666 | unsigned int g, generation = 0; |
1728 | int i, reset_cycles = 0; | 1667 | int i, reset_cycles = 0; |
1729 | 1668 | ||
@@ -1777,36 +1716,48 @@ static int nodemgr_host_thread(void *__hi) | |||
1777 | * entries. This does not do the sysfs stuff, since that | 1716 | * entries. This does not do the sysfs stuff, since that |
1778 | * would trigger uevents and such, which is a bad idea at | 1717 | * would trigger uevents and such, which is a bad idea at |
1779 | * this point. */ | 1718 | * this point. */ |
1780 | nodemgr_node_scan(hi, generation); | 1719 | nodemgr_node_scan(host, generation); |
1781 | 1720 | ||
1782 | /* This actually does the full probe, with sysfs | 1721 | /* This actually does the full probe, with sysfs |
1783 | * registration. */ | 1722 | * registration. */ |
1784 | nodemgr_node_probe(hi, generation); | 1723 | if (!nodemgr_node_probe(host, generation)) |
1724 | continue; | ||
1785 | 1725 | ||
1786 | /* Update some of our sysfs symlinks */ | 1726 | /* Update some of our sysfs symlinks */ |
1787 | nodemgr_update_host_dev_links(host); | 1727 | nodemgr_update_host_dev_links(host); |
1728 | |||
1729 | /* Sleep 3 seconds */ | ||
1730 | for (i = 3000/200; i; i--) { | ||
1731 | msleep_interruptible(200); | ||
1732 | if (kthread_should_stop()) | ||
1733 | goto exit; | ||
1734 | |||
1735 | if (generation != get_hpsb_generation(host)) | ||
1736 | break; | ||
1737 | } | ||
1738 | /* Remove nodes which are gone, unless a bus reset happened */ | ||
1739 | if (!i) | ||
1740 | nodemgr_remove_nodes_in_limbo(host); | ||
1788 | } | 1741 | } |
1789 | exit: | 1742 | exit: |
1790 | HPSB_VERBOSE("NodeMgr: Exiting thread"); | 1743 | HPSB_VERBOSE("NodeMgr: Exiting thread"); |
1791 | return 0; | 1744 | return 0; |
1792 | } | 1745 | } |
1793 | 1746 | ||
1794 | struct host_iter_param { | 1747 | struct per_host_parameter { |
1795 | void *data; | 1748 | void *data; |
1796 | int (*cb)(struct hpsb_host *, void *); | 1749 | int (*cb)(struct hpsb_host *, void *); |
1797 | }; | 1750 | }; |
1798 | 1751 | ||
1799 | static int __nodemgr_for_each_host(struct device *dev, void *data) | 1752 | static int per_host(struct device *dev, void *data) |
1800 | { | 1753 | { |
1801 | struct hpsb_host *host; | 1754 | struct hpsb_host *host; |
1802 | struct host_iter_param *hip = (struct host_iter_param *)data; | 1755 | struct per_host_parameter *p = data; |
1803 | int error = 0; | ||
1804 | 1756 | ||
1805 | host = container_of(dev, struct hpsb_host, host_dev); | 1757 | host = container_of(dev, struct hpsb_host, host_dev); |
1806 | error = hip->cb(host, hip->data); | 1758 | return p->cb(host, p->data); |
1807 | |||
1808 | return error; | ||
1809 | } | 1759 | } |
1760 | |||
1810 | /** | 1761 | /** |
1811 | * nodemgr_for_each_host - call a function for each IEEE 1394 host | 1762 | * nodemgr_for_each_host - call a function for each IEEE 1394 host |
1812 | * @data: an address to supply to the callback | 1763 | * @data: an address to supply to the callback |
@@ -1821,15 +1772,11 @@ static int __nodemgr_for_each_host(struct device *dev, void *data) | |||
1821 | */ | 1772 | */ |
1822 | int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) | 1773 | int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) |
1823 | { | 1774 | { |
1824 | struct host_iter_param hip; | 1775 | struct per_host_parameter p; |
1825 | int error; | ||
1826 | |||
1827 | hip.cb = cb; | ||
1828 | hip.data = data; | ||
1829 | error = class_for_each_device(&hpsb_host_class, &hip, | ||
1830 | __nodemgr_for_each_host); | ||
1831 | 1776 | ||
1832 | return error; | 1777 | p.cb = cb; |
1778 | p.data = data; | ||
1779 | return class_for_each_device(&hpsb_host_class, NULL, &p, per_host); | ||
1833 | } | 1780 | } |
1834 | 1781 | ||
1835 | /* The following two convenience functions use a struct node_entry | 1782 | /* The following two convenience functions use a struct node_entry |
@@ -1883,7 +1830,7 @@ static void nodemgr_add_host(struct hpsb_host *host) | |||
1883 | return; | 1830 | return; |
1884 | } | 1831 | } |
1885 | hi->host = host; | 1832 | hi->host = host; |
1886 | hi->thread = kthread_run(nodemgr_host_thread, hi, "knodemgrd_%d", | 1833 | hi->thread = kthread_run(nodemgr_host_thread, host, "knodemgrd_%d", |
1887 | host->id); | 1834 | host->id); |
1888 | if (IS_ERR(hi->thread)) { | 1835 | if (IS_ERR(hi->thread)) { |
1889 | HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id); | 1836 | HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id); |