diff options
Diffstat (limited to 'drivers/ieee1394/nodemgr.c')
-rw-r--r-- | drivers/ieee1394/nodemgr.c | 279 |
1 files changed, 108 insertions, 171 deletions
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 16240a789650..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,8 +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, NULL, ne, | 732 | dev = class_find_device(&nodemgr_ud_class, NULL, ne, match_ne); |
758 | __match_ne); | ||
759 | if (!dev) | 733 | if (!dev) |
760 | break; | 734 | break; |
761 | ud = container_of(dev, struct unit_directory, unit_dev); | 735 | ud = container_of(dev, struct unit_directory, unit_dev); |
@@ -785,7 +759,7 @@ static void nodemgr_remove_ne(struct node_entry *ne) | |||
785 | put_device(dev); | 759 | put_device(dev); |
786 | } | 760 | } |
787 | 761 | ||
788 | static int __nodemgr_remove_host_dev(struct device *dev, void *data) | 762 | static int remove_host_dev(struct device *dev, void *data) |
789 | { | 763 | { |
790 | if (dev->bus == &ieee1394_bus_type) | 764 | if (dev->bus == &ieee1394_bus_type) |
791 | nodemgr_remove_ne(container_of(dev, struct node_entry, | 765 | nodemgr_remove_ne(container_of(dev, struct node_entry, |
@@ -795,7 +769,7 @@ static int __nodemgr_remove_host_dev(struct device *dev, void *data) | |||
795 | 769 | ||
796 | static void nodemgr_remove_host_dev(struct device *dev) | 770 | static void nodemgr_remove_host_dev(struct device *dev) |
797 | { | 771 | { |
798 | WARN_ON(device_for_each_child(dev, NULL, __nodemgr_remove_host_dev)); | 772 | device_for_each_child(dev, NULL, remove_host_dev); |
799 | sysfs_remove_link(&dev->kobj, "irm_id"); | 773 | sysfs_remove_link(&dev->kobj, "irm_id"); |
800 | sysfs_remove_link(&dev->kobj, "busmgr_id"); | 774 | sysfs_remove_link(&dev->kobj, "busmgr_id"); |
801 | sysfs_remove_link(&dev->kobj, "host_id"); | 775 | sysfs_remove_link(&dev->kobj, "host_id"); |
@@ -830,11 +804,10 @@ static void nodemgr_update_bus_options(struct node_entry *ne) | |||
830 | } | 804 | } |
831 | 805 | ||
832 | 806 | ||
833 | 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, |
834 | struct host_info *hi, nodeid_t nodeid, | 808 | struct csr1212_csr *csr, struct hpsb_host *host, |
835 | unsigned int generation) | 809 | nodeid_t nodeid, unsigned int generation) |
836 | { | 810 | { |
837 | struct hpsb_host *host = hi->host; | ||
838 | struct node_entry *ne; | 811 | struct node_entry *ne; |
839 | 812 | ||
840 | ne = kzalloc(sizeof(*ne), GFP_KERNEL); | 813 | ne = kzalloc(sizeof(*ne), GFP_KERNEL); |
@@ -888,10 +861,10 @@ fail_alloc: | |||
888 | return NULL; | 861 | return NULL; |
889 | } | 862 | } |
890 | 863 | ||
891 | static int __match_ne_guid(struct device *dev, void *data) | 864 | static int match_ne_guid(struct device *dev, void *data) |
892 | { | 865 | { |
893 | struct node_entry *ne; | 866 | struct node_entry *ne; |
894 | u64 *guid = (u64 *)data; | 867 | u64 *guid = data; |
895 | 868 | ||
896 | ne = container_of(dev, struct node_entry, node_dev); | 869 | ne = container_of(dev, struct node_entry, node_dev); |
897 | return ne->guid == *guid; | 870 | return ne->guid == *guid; |
@@ -902,8 +875,7 @@ static struct node_entry *find_entry_by_guid(u64 guid) | |||
902 | struct device *dev; | 875 | struct device *dev; |
903 | struct node_entry *ne; | 876 | struct node_entry *ne; |
904 | 877 | ||
905 | dev = class_find_device(&nodemgr_ne_class, NULL, &guid, | 878 | dev = class_find_device(&nodemgr_ne_class, NULL, &guid, match_ne_guid); |
906 | __match_ne_guid); | ||
907 | if (!dev) | 879 | if (!dev) |
908 | return NULL; | 880 | return NULL; |
909 | ne = container_of(dev, struct node_entry, node_dev); | 881 | ne = container_of(dev, struct node_entry, node_dev); |
@@ -912,21 +884,21 @@ static struct node_entry *find_entry_by_guid(u64 guid) | |||
912 | return ne; | 884 | return ne; |
913 | } | 885 | } |
914 | 886 | ||
915 | struct match_nodeid_param { | 887 | struct match_nodeid_parameter { |
916 | struct hpsb_host *host; | 888 | struct hpsb_host *host; |
917 | nodeid_t nodeid; | 889 | nodeid_t nodeid; |
918 | }; | 890 | }; |
919 | 891 | ||
920 | static int __match_ne_nodeid(struct device *dev, void *data) | 892 | static int match_ne_nodeid(struct device *dev, void *data) |
921 | { | 893 | { |
922 | int found = 0; | 894 | int found = 0; |
923 | struct node_entry *ne; | 895 | struct node_entry *ne; |
924 | struct match_nodeid_param *param = (struct match_nodeid_param *)data; | 896 | struct match_nodeid_parameter *p = data; |
925 | 897 | ||
926 | if (!dev) | 898 | if (!dev) |
927 | goto ret; | 899 | goto ret; |
928 | ne = container_of(dev, struct node_entry, node_dev); | 900 | ne = container_of(dev, struct node_entry, node_dev); |
929 | if (ne->host == param->host && ne->nodeid == param->nodeid) | 901 | if (ne->host == p->host && ne->nodeid == p->nodeid) |
930 | found = 1; | 902 | found = 1; |
931 | ret: | 903 | ret: |
932 | return found; | 904 | return found; |
@@ -937,13 +909,12 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, | |||
937 | { | 909 | { |
938 | struct device *dev; | 910 | struct device *dev; |
939 | struct node_entry *ne; | 911 | struct node_entry *ne; |
940 | struct match_nodeid_param param; | 912 | struct match_nodeid_parameter p; |
941 | 913 | ||
942 | param.host = host; | 914 | p.host = host; |
943 | param.nodeid = nodeid; | 915 | p.nodeid = nodeid; |
944 | 916 | ||
945 | dev = class_find_device(&nodemgr_ne_class, NULL, ¶m, | 917 | dev = class_find_device(&nodemgr_ne_class, NULL, &p, match_ne_nodeid); |
946 | __match_ne_nodeid); | ||
947 | if (!dev) | 918 | if (!dev) |
948 | return NULL; | 919 | return NULL; |
949 | ne = container_of(dev, struct node_entry, node_dev); | 920 | ne = container_of(dev, struct node_entry, node_dev); |
@@ -990,7 +961,7 @@ fail_devreg: | |||
990 | * immediate unit directories looking for software_id and | 961 | * immediate unit directories looking for software_id and |
991 | * software_version entries, in order to get driver autoloading working. */ | 962 | * software_version entries, in order to get driver autoloading working. */ |
992 | static struct unit_directory *nodemgr_process_unit_directory | 963 | static struct unit_directory *nodemgr_process_unit_directory |
993 | (struct host_info *hi, struct node_entry *ne, struct csr1212_keyval *ud_kv, | 964 | (struct node_entry *ne, struct csr1212_keyval *ud_kv, |
994 | unsigned int *id, struct unit_directory *parent) | 965 | unsigned int *id, struct unit_directory *parent) |
995 | { | 966 | { |
996 | struct unit_directory *ud; | 967 | struct unit_directory *ud; |
@@ -1083,7 +1054,7 @@ static struct unit_directory *nodemgr_process_unit_directory | |||
1083 | nodemgr_register_device(ne, ud, &ne->device); | 1054 | nodemgr_register_device(ne, ud, &ne->device); |
1084 | 1055 | ||
1085 | /* process the child unit */ | 1056 | /* process the child unit */ |
1086 | ud_child = nodemgr_process_unit_directory(hi, ne, kv, id, ud); | 1057 | ud_child = nodemgr_process_unit_directory(ne, kv, id, ud); |
1087 | 1058 | ||
1088 | if (ud_child == NULL) | 1059 | if (ud_child == NULL) |
1089 | break; | 1060 | break; |
@@ -1137,7 +1108,7 @@ unit_directory_error: | |||
1137 | } | 1108 | } |
1138 | 1109 | ||
1139 | 1110 | ||
1140 | 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) |
1141 | { | 1112 | { |
1142 | unsigned int ud_id = 0; | 1113 | unsigned int ud_id = 0; |
1143 | struct csr1212_dentry *dentry; | 1114 | struct csr1212_dentry *dentry; |
@@ -1157,7 +1128,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent | |||
1157 | break; | 1128 | break; |
1158 | 1129 | ||
1159 | case CSR1212_KV_ID_UNIT: | 1130 | case CSR1212_KV_ID_UNIT: |
1160 | nodemgr_process_unit_directory(hi, ne, kv, &ud_id, NULL); | 1131 | nodemgr_process_unit_directory(ne, kv, &ud_id, NULL); |
1161 | break; | 1132 | break; |
1162 | 1133 | ||
1163 | case CSR1212_KV_ID_DESCRIPTOR: | 1134 | case CSR1212_KV_ID_DESCRIPTOR: |
@@ -1273,8 +1244,7 @@ void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver) | |||
1273 | * the to take whatever actions required. | 1244 | * the to take whatever actions required. |
1274 | */ | 1245 | */ |
1275 | 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, |
1276 | struct host_info *hi, nodeid_t nodeid, | 1247 | nodeid_t nodeid, unsigned int generation) |
1277 | unsigned int generation) | ||
1278 | { | 1248 | { |
1279 | if (ne->nodeid != nodeid) { | 1249 | if (ne->nodeid != nodeid) { |
1280 | HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT, | 1250 | HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT, |
@@ -1305,19 +1275,23 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, | |||
1305 | csr1212_destroy_csr(csr); | 1275 | csr1212_destroy_csr(csr); |
1306 | } | 1276 | } |
1307 | 1277 | ||
1308 | if (ne->in_limbo) | ||
1309 | nodemgr_resume_ne(ne); | ||
1310 | |||
1311 | /* Mark the node current */ | 1278 | /* Mark the node current */ |
1312 | ne->generation = generation; | 1279 | ne->generation = generation; |
1313 | } | ||
1314 | 1280 | ||
1281 | if (ne->in_limbo) { | ||
1282 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); | ||
1283 | ne->in_limbo = false; | ||
1315 | 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 | } | ||
1316 | 1291 | ||
1317 | static void nodemgr_node_scan_one(struct host_info *hi, | 1292 | static void nodemgr_node_scan_one(struct hpsb_host *host, |
1318 | nodeid_t nodeid, int generation) | 1293 | nodeid_t nodeid, int generation) |
1319 | { | 1294 | { |
1320 | struct hpsb_host *host = hi->host; | ||
1321 | struct node_entry *ne; | 1295 | struct node_entry *ne; |
1322 | octlet_t guid; | 1296 | octlet_t guid; |
1323 | struct csr1212_csr *csr; | 1297 | struct csr1212_csr *csr; |
@@ -1373,16 +1347,15 @@ static void nodemgr_node_scan_one(struct host_info *hi, | |||
1373 | } | 1347 | } |
1374 | 1348 | ||
1375 | if (!ne) | 1349 | if (!ne) |
1376 | nodemgr_create_node(guid, csr, hi, nodeid, generation); | 1350 | nodemgr_create_node(guid, csr, host, nodeid, generation); |
1377 | else | 1351 | else |
1378 | nodemgr_update_node(ne, csr, hi, nodeid, generation); | 1352 | nodemgr_update_node(ne, csr, nodeid, generation); |
1379 | } | 1353 | } |
1380 | 1354 | ||
1381 | 1355 | ||
1382 | static void nodemgr_node_scan(struct host_info *hi, int generation) | 1356 | static void nodemgr_node_scan(struct hpsb_host *host, int generation) |
1383 | { | 1357 | { |
1384 | int count; | 1358 | int count; |
1385 | struct hpsb_host *host = hi->host; | ||
1386 | struct selfid *sid = (struct selfid *)host->topology_map; | 1359 | struct selfid *sid = (struct selfid *)host->topology_map; |
1387 | nodeid_t nodeid = LOCAL_BUS; | 1360 | nodeid_t nodeid = LOCAL_BUS; |
1388 | 1361 | ||
@@ -1395,89 +1368,26 @@ static void nodemgr_node_scan(struct host_info *hi, int generation) | |||
1395 | nodeid++; | 1368 | nodeid++; |
1396 | continue; | 1369 | continue; |
1397 | } | 1370 | } |
1398 | nodemgr_node_scan_one(hi, nodeid++, generation); | 1371 | nodemgr_node_scan_one(host, nodeid++, generation); |
1399 | } | ||
1400 | } | ||
1401 | |||
1402 | static int __nodemgr_driver_suspend(struct device *dev, void *data) | ||
1403 | { | ||
1404 | struct unit_directory *ud; | ||
1405 | struct device_driver *drv; | ||
1406 | struct node_entry *ne = (struct node_entry *)data; | ||
1407 | int error; | ||
1408 | |||
1409 | ud = container_of(dev, struct unit_directory, unit_dev); | ||
1410 | if (ud->ne == ne) { | ||
1411 | drv = get_driver(ud->device.driver); | ||
1412 | if (drv) { | ||
1413 | error = 1; /* release if suspend is not implemented */ | ||
1414 | if (drv->suspend) { | ||
1415 | down(&ud->device.sem); | ||
1416 | error = drv->suspend(&ud->device, PMSG_SUSPEND); | ||
1417 | up(&ud->device.sem); | ||
1418 | } | ||
1419 | if (error) | ||
1420 | device_release_driver(&ud->device); | ||
1421 | put_driver(drv); | ||
1422 | } | ||
1423 | } | ||
1424 | |||
1425 | return 0; | ||
1426 | } | ||
1427 | |||
1428 | static int __nodemgr_driver_resume(struct device *dev, void *data) | ||
1429 | { | ||
1430 | struct unit_directory *ud; | ||
1431 | struct device_driver *drv; | ||
1432 | struct node_entry *ne = (struct node_entry *)data; | ||
1433 | |||
1434 | ud = container_of(dev, struct unit_directory, unit_dev); | ||
1435 | if (ud->ne == ne) { | ||
1436 | drv = get_driver(ud->device.driver); | ||
1437 | if (drv) { | ||
1438 | if (drv->resume) { | ||
1439 | down(&ud->device.sem); | ||
1440 | drv->resume(&ud->device); | ||
1441 | up(&ud->device.sem); | ||
1442 | } | ||
1443 | put_driver(drv); | ||
1444 | } | ||
1445 | } | 1372 | } |
1446 | |||
1447 | return 0; | ||
1448 | } | 1373 | } |
1449 | 1374 | ||
1450 | static void nodemgr_suspend_ne(struct node_entry *ne) | 1375 | static void nodemgr_pause_ne(struct node_entry *ne) |
1451 | { | 1376 | { |
1452 | HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | 1377 | HPSB_DEBUG("Node paused: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", |
1453 | NODE_BUS_ARGS(ne->host, ne->nodeid), | 1378 | NODE_BUS_ARGS(ne->host, ne->nodeid), |
1454 | (unsigned long long)ne->guid); | 1379 | (unsigned long long)ne->guid); |
1455 | 1380 | ||
1456 | ne->in_limbo = 1; | 1381 | ne->in_limbo = true; |
1457 | 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)); |
1458 | |||
1459 | class_for_each_device(&nodemgr_ud_class, NULL, ne, | ||
1460 | __nodemgr_driver_suspend); | ||
1461 | } | ||
1462 | |||
1463 | |||
1464 | static void nodemgr_resume_ne(struct node_entry *ne) | ||
1465 | { | ||
1466 | ne->in_limbo = 0; | ||
1467 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); | ||
1468 | |||
1469 | class_for_each_device(&nodemgr_ud_class, NULL, ne, | ||
1470 | __nodemgr_driver_resume); | ||
1471 | HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | ||
1472 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); | ||
1473 | } | 1383 | } |
1474 | 1384 | ||
1475 | static int __nodemgr_update_pdrv(struct device *dev, void *data) | 1385 | static int update_pdrv(struct device *dev, void *data) |
1476 | { | 1386 | { |
1477 | struct unit_directory *ud; | 1387 | struct unit_directory *ud; |
1478 | struct device_driver *drv; | 1388 | struct device_driver *drv; |
1479 | struct hpsb_protocol_driver *pdrv; | 1389 | struct hpsb_protocol_driver *pdrv; |
1480 | struct node_entry *ne = (struct node_entry *)data; | 1390 | struct node_entry *ne = data; |
1481 | int error; | 1391 | int error; |
1482 | 1392 | ||
1483 | ud = container_of(dev, struct unit_directory, unit_dev); | 1393 | ud = container_of(dev, struct unit_directory, unit_dev); |
@@ -1503,11 +1413,9 @@ static int __nodemgr_update_pdrv(struct device *dev, void *data) | |||
1503 | 1413 | ||
1504 | static void nodemgr_update_pdrv(struct node_entry *ne) | 1414 | static void nodemgr_update_pdrv(struct node_entry *ne) |
1505 | { | 1415 | { |
1506 | class_for_each_device(&nodemgr_ud_class, NULL, ne, | 1416 | class_for_each_device(&nodemgr_ud_class, NULL, ne, update_pdrv); |
1507 | __nodemgr_update_pdrv); | ||
1508 | } | 1417 | } |
1509 | 1418 | ||
1510 | |||
1511 | /* 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 |
1512 | * 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 |
1513 | * as a consequence of these clauses. | 1421 | * as a consequence of these clauses. |
@@ -1535,11 +1443,12 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation) | |||
1535 | } | 1443 | } |
1536 | 1444 | ||
1537 | 1445 | ||
1538 | 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) | ||
1539 | { | 1448 | { |
1540 | struct device *dev; | 1449 | struct device *dev; |
1541 | 1450 | ||
1542 | if (ne->host != hi->host || ne->in_limbo) | 1451 | if (ne->host != host || ne->in_limbo) |
1543 | return; | 1452 | return; |
1544 | 1453 | ||
1545 | dev = get_device(&ne->device); | 1454 | dev = get_device(&ne->device); |
@@ -1554,40 +1463,40 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge | |||
1554 | * 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 |
1555 | * suspend it. */ | 1464 | * suspend it. */ |
1556 | if (ne->needs_probe) | 1465 | if (ne->needs_probe) |
1557 | nodemgr_process_root_directory(hi, ne); | 1466 | nodemgr_process_root_directory(ne); |
1558 | else if (ne->generation == generation) | 1467 | else if (ne->generation == generation) |
1559 | nodemgr_update_pdrv(ne); | 1468 | nodemgr_update_pdrv(ne); |
1560 | else | 1469 | else |
1561 | nodemgr_suspend_ne(ne); | 1470 | nodemgr_pause_ne(ne); |
1562 | 1471 | ||
1563 | put_device(dev); | 1472 | put_device(dev); |
1564 | } | 1473 | } |
1565 | 1474 | ||
1566 | struct probe_param { | 1475 | struct node_probe_parameter { |
1567 | struct host_info *hi; | 1476 | struct hpsb_host *host; |
1568 | int generation; | 1477 | int generation; |
1569 | bool probe_now; | 1478 | bool probe_now; |
1570 | }; | 1479 | }; |
1571 | 1480 | ||
1572 | static int node_probe(struct device *dev, void *data) | 1481 | static int node_probe(struct device *dev, void *data) |
1573 | { | 1482 | { |
1574 | struct probe_param *p = data; | 1483 | struct node_probe_parameter *p = data; |
1575 | struct node_entry *ne; | 1484 | struct node_entry *ne; |
1576 | 1485 | ||
1577 | if (p->generation != get_hpsb_generation(p->hi->host)) | 1486 | if (p->generation != get_hpsb_generation(p->host)) |
1578 | return -EAGAIN; | 1487 | return -EAGAIN; |
1579 | 1488 | ||
1580 | ne = container_of(dev, struct node_entry, node_dev); | 1489 | ne = container_of(dev, struct node_entry, node_dev); |
1581 | if (ne->needs_probe == p->probe_now) | 1490 | if (ne->needs_probe == p->probe_now) |
1582 | nodemgr_probe_ne(p->hi, ne, p->generation); | 1491 | nodemgr_probe_ne(p->host, ne, p->generation); |
1583 | return 0; | 1492 | return 0; |
1584 | } | 1493 | } |
1585 | 1494 | ||
1586 | static void nodemgr_node_probe(struct host_info *hi, int generation) | 1495 | static int nodemgr_node_probe(struct hpsb_host *host, int generation) |
1587 | { | 1496 | { |
1588 | struct probe_param p; | 1497 | struct node_probe_parameter p; |
1589 | 1498 | ||
1590 | p.hi = hi; | 1499 | p.host = host; |
1591 | p.generation = generation; | 1500 | p.generation = generation; |
1592 | /* | 1501 | /* |
1593 | * Do some processing of the nodes we've probed. This pulls them | 1502 | * Do some processing of the nodes we've probed. This pulls them |
@@ -1604,11 +1513,11 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) | |||
1604 | */ | 1513 | */ |
1605 | p.probe_now = false; | 1514 | p.probe_now = false; |
1606 | if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0) | 1515 | if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0) |
1607 | return; | 1516 | return 0; |
1608 | 1517 | ||
1609 | p.probe_now = true; | 1518 | p.probe_now = true; |
1610 | if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0) | 1519 | if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0) |
1611 | return; | 1520 | return 0; |
1612 | /* | 1521 | /* |
1613 | * 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 |
1614 | * like overhead, but the driver-model core will only scan a | 1523 | * like overhead, but the driver-model core will only scan a |
@@ -1620,6 +1529,27 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) | |||
1620 | */ | 1529 | */ |
1621 | if (bus_rescan_devices(&ieee1394_bus_type) != 0) | 1530 | if (bus_rescan_devices(&ieee1394_bus_type) != 0) |
1622 | HPSB_DEBUG("bus_rescan_devices had an error"); | 1531 | HPSB_DEBUG("bus_rescan_devices had an error"); |
1532 | |||
1533 | return 1; | ||
1534 | } | ||
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); | ||
1623 | } | 1553 | } |
1624 | 1554 | ||
1625 | static int nodemgr_send_resume_packet(struct hpsb_host *host) | 1555 | static int nodemgr_send_resume_packet(struct hpsb_host *host) |
@@ -1730,10 +1660,9 @@ static int nodemgr_check_irm_capability(struct hpsb_host *host, int cycles) | |||
1730 | return 1; | 1660 | return 1; |
1731 | } | 1661 | } |
1732 | 1662 | ||
1733 | static int nodemgr_host_thread(void *__hi) | 1663 | static int nodemgr_host_thread(void *data) |
1734 | { | 1664 | { |
1735 | struct host_info *hi = (struct host_info *)__hi; | 1665 | struct hpsb_host *host = data; |
1736 | struct hpsb_host *host = hi->host; | ||
1737 | unsigned int g, generation = 0; | 1666 | unsigned int g, generation = 0; |
1738 | int i, reset_cycles = 0; | 1667 | int i, reset_cycles = 0; |
1739 | 1668 | ||
@@ -1787,36 +1716,48 @@ static int nodemgr_host_thread(void *__hi) | |||
1787 | * entries. This does not do the sysfs stuff, since that | 1716 | * entries. This does not do the sysfs stuff, since that |
1788 | * would trigger uevents and such, which is a bad idea at | 1717 | * would trigger uevents and such, which is a bad idea at |
1789 | * this point. */ | 1718 | * this point. */ |
1790 | nodemgr_node_scan(hi, generation); | 1719 | nodemgr_node_scan(host, generation); |
1791 | 1720 | ||
1792 | /* This actually does the full probe, with sysfs | 1721 | /* This actually does the full probe, with sysfs |
1793 | * registration. */ | 1722 | * registration. */ |
1794 | nodemgr_node_probe(hi, generation); | 1723 | if (!nodemgr_node_probe(host, generation)) |
1724 | continue; | ||
1795 | 1725 | ||
1796 | /* Update some of our sysfs symlinks */ | 1726 | /* Update some of our sysfs symlinks */ |
1797 | 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); | ||
1798 | } | 1741 | } |
1799 | exit: | 1742 | exit: |
1800 | HPSB_VERBOSE("NodeMgr: Exiting thread"); | 1743 | HPSB_VERBOSE("NodeMgr: Exiting thread"); |
1801 | return 0; | 1744 | return 0; |
1802 | } | 1745 | } |
1803 | 1746 | ||
1804 | struct host_iter_param { | 1747 | struct per_host_parameter { |
1805 | void *data; | 1748 | void *data; |
1806 | int (*cb)(struct hpsb_host *, void *); | 1749 | int (*cb)(struct hpsb_host *, void *); |
1807 | }; | 1750 | }; |
1808 | 1751 | ||
1809 | static int __nodemgr_for_each_host(struct device *dev, void *data) | 1752 | static int per_host(struct device *dev, void *data) |
1810 | { | 1753 | { |
1811 | struct hpsb_host *host; | 1754 | struct hpsb_host *host; |
1812 | struct host_iter_param *hip = (struct host_iter_param *)data; | 1755 | struct per_host_parameter *p = data; |
1813 | int error = 0; | ||
1814 | 1756 | ||
1815 | host = container_of(dev, struct hpsb_host, host_dev); | 1757 | host = container_of(dev, struct hpsb_host, host_dev); |
1816 | error = hip->cb(host, hip->data); | 1758 | return p->cb(host, p->data); |
1817 | |||
1818 | return error; | ||
1819 | } | 1759 | } |
1760 | |||
1820 | /** | 1761 | /** |
1821 | * 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 |
1822 | * @data: an address to supply to the callback | 1763 | * @data: an address to supply to the callback |
@@ -1831,15 +1772,11 @@ static int __nodemgr_for_each_host(struct device *dev, void *data) | |||
1831 | */ | 1772 | */ |
1832 | 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 *)) |
1833 | { | 1774 | { |
1834 | struct host_iter_param hip; | 1775 | struct per_host_parameter p; |
1835 | int error; | ||
1836 | |||
1837 | hip.cb = cb; | ||
1838 | hip.data = data; | ||
1839 | error = class_for_each_device(&hpsb_host_class, NULL, &hip, | ||
1840 | __nodemgr_for_each_host); | ||
1841 | 1776 | ||
1842 | return error; | 1777 | p.cb = cb; |
1778 | p.data = data; | ||
1779 | return class_for_each_device(&hpsb_host_class, NULL, &p, per_host); | ||
1843 | } | 1780 | } |
1844 | 1781 | ||
1845 | /* The following two convenience functions use a struct node_entry | 1782 | /* The following two convenience functions use a struct node_entry |
@@ -1893,7 +1830,7 @@ static void nodemgr_add_host(struct hpsb_host *host) | |||
1893 | return; | 1830 | return; |
1894 | } | 1831 | } |
1895 | hi->host = host; | 1832 | hi->host = host; |
1896 | hi->thread = kthread_run(nodemgr_host_thread, hi, "knodemgrd_%d", | 1833 | hi->thread = kthread_run(nodemgr_host_thread, host, "knodemgrd_%d", |
1897 | host->id); | 1834 | host->id); |
1898 | if (IS_ERR(hi->thread)) { | 1835 | if (IS_ERR(hi->thread)) { |
1899 | HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id); | 1836 | HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id); |