diff options
Diffstat (limited to 'drivers/ieee1394/nodemgr.c')
-rw-r--r-- | drivers/ieee1394/nodemgr.c | 185 |
1 files changed, 102 insertions, 83 deletions
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 81b3864d2ba7..c4d3d4131f01 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | #include <linux/freezer.h> | 20 | #include <linux/freezer.h> |
21 | #include <asm/atomic.h> | 21 | #include <asm/atomic.h> |
22 | #include <asm/semaphore.h> | ||
22 | 23 | ||
23 | #include "csr.h" | 24 | #include "csr.h" |
24 | #include "highlevel.h" | 25 | #include "highlevel.h" |
@@ -145,8 +146,6 @@ static struct csr1212_bus_ops nodemgr_csr_ops = { | |||
145 | * but now we are much simpler because of the LDM. | 146 | * but now we are much simpler because of the LDM. |
146 | */ | 147 | */ |
147 | 148 | ||
148 | static DEFINE_MUTEX(nodemgr_serialize); | ||
149 | |||
150 | struct host_info { | 149 | struct host_info { |
151 | struct hpsb_host *host; | 150 | struct hpsb_host *host; |
152 | struct list_head list; | 151 | struct list_head list; |
@@ -154,7 +153,7 @@ struct host_info { | |||
154 | }; | 153 | }; |
155 | 154 | ||
156 | 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); |
157 | static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, | 156 | static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, |
158 | char *buffer, int buffer_size); | 157 | char *buffer, int buffer_size); |
159 | static void nodemgr_resume_ne(struct node_entry *ne); | 158 | static void nodemgr_resume_ne(struct node_entry *ne); |
160 | static void nodemgr_remove_ne(struct node_entry *ne); | 159 | static void nodemgr_remove_ne(struct node_entry *ne); |
@@ -165,37 +164,38 @@ struct bus_type ieee1394_bus_type = { | |||
165 | .match = nodemgr_bus_match, | 164 | .match = nodemgr_bus_match, |
166 | }; | 165 | }; |
167 | 166 | ||
168 | static void host_cls_release(struct class_device *class_dev) | 167 | static void host_cls_release(struct device *dev) |
169 | { | 168 | { |
170 | put_device(&container_of((class_dev), struct hpsb_host, class_dev)->device); | 169 | put_device(&container_of((dev), struct hpsb_host, host_dev)->device); |
171 | } | 170 | } |
172 | 171 | ||
173 | struct class hpsb_host_class = { | 172 | struct class hpsb_host_class = { |
174 | .name = "ieee1394_host", | 173 | .name = "ieee1394_host", |
175 | .release = host_cls_release, | 174 | .dev_release = host_cls_release, |
176 | }; | 175 | }; |
177 | 176 | ||
178 | static void ne_cls_release(struct class_device *class_dev) | 177 | static void ne_cls_release(struct device *dev) |
179 | { | 178 | { |
180 | put_device(&container_of((class_dev), struct node_entry, class_dev)->device); | 179 | put_device(&container_of((dev), struct node_entry, node_dev)->device); |
181 | } | 180 | } |
182 | 181 | ||
183 | static struct class nodemgr_ne_class = { | 182 | static struct class nodemgr_ne_class = { |
184 | .name = "ieee1394_node", | 183 | .name = "ieee1394_node", |
185 | .release = ne_cls_release, | 184 | .dev_release = ne_cls_release, |
186 | }; | 185 | }; |
187 | 186 | ||
188 | static void ud_cls_release(struct class_device *class_dev) | 187 | static void ud_cls_release(struct device *dev) |
189 | { | 188 | { |
190 | put_device(&container_of((class_dev), struct unit_directory, class_dev)->device); | 189 | put_device(&container_of((dev), struct unit_directory, unit_dev)->device); |
191 | } | 190 | } |
192 | 191 | ||
193 | /* The name here is only so that unit directory hotplug works with old | 192 | /* The name here is only so that unit directory hotplug works with old |
194 | * style hotplug, which only ever did unit directories anyway. */ | 193 | * style hotplug, which only ever did unit directories anyway. |
194 | */ | ||
195 | static struct class nodemgr_ud_class = { | 195 | static struct class nodemgr_ud_class = { |
196 | .name = "ieee1394", | 196 | .name = "ieee1394", |
197 | .release = ud_cls_release, | 197 | .dev_release = ud_cls_release, |
198 | .uevent = nodemgr_uevent, | 198 | .dev_uevent = nodemgr_uevent, |
199 | }; | 199 | }; |
200 | 200 | ||
201 | static struct hpsb_highlevel nodemgr_highlevel; | 201 | static struct hpsb_highlevel nodemgr_highlevel; |
@@ -730,11 +730,11 @@ static DEFINE_MUTEX(nodemgr_serialize_remove_uds); | |||
730 | 730 | ||
731 | static void nodemgr_remove_uds(struct node_entry *ne) | 731 | static void nodemgr_remove_uds(struct node_entry *ne) |
732 | { | 732 | { |
733 | struct class_device *cdev; | 733 | struct device *dev; |
734 | struct unit_directory *tmp, *ud; | 734 | struct unit_directory *tmp, *ud; |
735 | 735 | ||
736 | /* Iteration over nodemgr_ud_class.children has to be protected by | 736 | /* Iteration over nodemgr_ud_class.devices has to be protected by |
737 | * nodemgr_ud_class.sem, but class_device_unregister() will eventually | 737 | * nodemgr_ud_class.sem, but device_unregister() will eventually |
738 | * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time, | 738 | * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time, |
739 | * release the semaphore, and then unregister the ud. Since this code | 739 | * release the semaphore, and then unregister the ud. Since this code |
740 | * may be called from other contexts besides the knodemgrds, protect the | 740 | * may be called from other contexts besides the knodemgrds, protect the |
@@ -744,9 +744,9 @@ static void nodemgr_remove_uds(struct node_entry *ne) | |||
744 | for (;;) { | 744 | for (;;) { |
745 | ud = NULL; | 745 | ud = NULL; |
746 | down(&nodemgr_ud_class.sem); | 746 | down(&nodemgr_ud_class.sem); |
747 | list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { | 747 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { |
748 | tmp = container_of(cdev, struct unit_directory, | 748 | tmp = container_of(dev, struct unit_directory, |
749 | class_dev); | 749 | unit_dev); |
750 | if (tmp->ne == ne) { | 750 | if (tmp->ne == ne) { |
751 | ud = tmp; | 751 | ud = tmp; |
752 | break; | 752 | break; |
@@ -755,7 +755,7 @@ static void nodemgr_remove_uds(struct node_entry *ne) | |||
755 | up(&nodemgr_ud_class.sem); | 755 | up(&nodemgr_ud_class.sem); |
756 | if (ud == NULL) | 756 | if (ud == NULL) |
757 | break; | 757 | break; |
758 | class_device_unregister(&ud->class_dev); | 758 | device_unregister(&ud->unit_dev); |
759 | device_unregister(&ud->device); | 759 | device_unregister(&ud->device); |
760 | } | 760 | } |
761 | mutex_unlock(&nodemgr_serialize_remove_uds); | 761 | mutex_unlock(&nodemgr_serialize_remove_uds); |
@@ -772,10 +772,9 @@ static void nodemgr_remove_ne(struct node_entry *ne) | |||
772 | 772 | ||
773 | HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | 773 | HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", |
774 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); | 774 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); |
775 | |||
776 | nodemgr_remove_uds(ne); | 775 | nodemgr_remove_uds(ne); |
777 | 776 | ||
778 | class_device_unregister(&ne->class_dev); | 777 | device_unregister(&ne->node_dev); |
779 | device_unregister(dev); | 778 | device_unregister(dev); |
780 | 779 | ||
781 | put_device(dev); | 780 | put_device(dev); |
@@ -783,7 +782,9 @@ static void nodemgr_remove_ne(struct node_entry *ne) | |||
783 | 782 | ||
784 | static int __nodemgr_remove_host_dev(struct device *dev, void *data) | 783 | static int __nodemgr_remove_host_dev(struct device *dev, void *data) |
785 | { | 784 | { |
786 | nodemgr_remove_ne(container_of(dev, struct node_entry, device)); | 785 | if (dev->bus == &ieee1394_bus_type) |
786 | nodemgr_remove_ne(container_of(dev, struct node_entry, | ||
787 | device)); | ||
787 | return 0; | 788 | return 0; |
788 | } | 789 | } |
789 | 790 | ||
@@ -850,14 +851,14 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr | |||
850 | snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", | 851 | snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", |
851 | (unsigned long long)(ne->guid)); | 852 | (unsigned long long)(ne->guid)); |
852 | 853 | ||
853 | ne->class_dev.dev = &ne->device; | 854 | ne->node_dev.parent = &ne->device; |
854 | ne->class_dev.class = &nodemgr_ne_class; | 855 | ne->node_dev.class = &nodemgr_ne_class; |
855 | snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx", | 856 | snprintf(ne->node_dev.bus_id, BUS_ID_SIZE, "%016Lx", |
856 | (unsigned long long)(ne->guid)); | 857 | (unsigned long long)(ne->guid)); |
857 | 858 | ||
858 | if (device_register(&ne->device)) | 859 | if (device_register(&ne->device)) |
859 | goto fail_devreg; | 860 | goto fail_devreg; |
860 | if (class_device_register(&ne->class_dev)) | 861 | if (device_register(&ne->node_dev)) |
861 | goto fail_classdevreg; | 862 | goto fail_classdevreg; |
862 | get_device(&ne->device); | 863 | get_device(&ne->device); |
863 | 864 | ||
@@ -885,12 +886,12 @@ fail_alloc: | |||
885 | 886 | ||
886 | static struct node_entry *find_entry_by_guid(u64 guid) | 887 | static struct node_entry *find_entry_by_guid(u64 guid) |
887 | { | 888 | { |
888 | struct class_device *cdev; | 889 | struct device *dev; |
889 | struct node_entry *ne, *ret_ne = NULL; | 890 | struct node_entry *ne, *ret_ne = NULL; |
890 | 891 | ||
891 | down(&nodemgr_ne_class.sem); | 892 | down(&nodemgr_ne_class.sem); |
892 | list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { | 893 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { |
893 | ne = container_of(cdev, struct node_entry, class_dev); | 894 | ne = container_of(dev, struct node_entry, node_dev); |
894 | 895 | ||
895 | if (ne->guid == guid) { | 896 | if (ne->guid == guid) { |
896 | ret_ne = ne; | 897 | ret_ne = ne; |
@@ -906,12 +907,12 @@ static struct node_entry *find_entry_by_guid(u64 guid) | |||
906 | static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, | 907 | static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, |
907 | nodeid_t nodeid) | 908 | nodeid_t nodeid) |
908 | { | 909 | { |
909 | struct class_device *cdev; | 910 | struct device *dev; |
910 | struct node_entry *ne, *ret_ne = NULL; | 911 | struct node_entry *ne, *ret_ne = NULL; |
911 | 912 | ||
912 | down(&nodemgr_ne_class.sem); | 913 | down(&nodemgr_ne_class.sem); |
913 | list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { | 914 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { |
914 | ne = container_of(cdev, struct node_entry, class_dev); | 915 | ne = container_of(dev, struct node_entry, node_dev); |
915 | 916 | ||
916 | if (ne->host == host && ne->nodeid == nodeid) { | 917 | if (ne->host == host && ne->nodeid == nodeid) { |
917 | ret_ne = ne; | 918 | ret_ne = ne; |
@@ -935,14 +936,14 @@ static void nodemgr_register_device(struct node_entry *ne, | |||
935 | snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", | 936 | snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", |
936 | ne->device.bus_id, ud->id); | 937 | ne->device.bus_id, ud->id); |
937 | 938 | ||
938 | ud->class_dev.dev = &ud->device; | 939 | ud->unit_dev.parent = &ud->device; |
939 | ud->class_dev.class = &nodemgr_ud_class; | 940 | ud->unit_dev.class = &nodemgr_ud_class; |
940 | snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u", | 941 | snprintf(ud->unit_dev.bus_id, BUS_ID_SIZE, "%s-%u", |
941 | ne->device.bus_id, ud->id); | 942 | ne->device.bus_id, ud->id); |
942 | 943 | ||
943 | if (device_register(&ud->device)) | 944 | if (device_register(&ud->device)) |
944 | goto fail_devreg; | 945 | goto fail_devreg; |
945 | if (class_device_register(&ud->class_dev)) | 946 | if (device_register(&ud->unit_dev)) |
946 | goto fail_classdevreg; | 947 | goto fail_classdevreg; |
947 | get_device(&ud->device); | 948 | get_device(&ud->device); |
948 | 949 | ||
@@ -1159,7 +1160,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent | |||
1159 | 1160 | ||
1160 | #ifdef CONFIG_HOTPLUG | 1161 | #ifdef CONFIG_HOTPLUG |
1161 | 1162 | ||
1162 | static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, | 1163 | static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, |
1163 | char *buffer, int buffer_size) | 1164 | char *buffer, int buffer_size) |
1164 | { | 1165 | { |
1165 | struct unit_directory *ud; | 1166 | struct unit_directory *ud; |
@@ -1169,10 +1170,10 @@ static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, | |||
1169 | /* ieee1394:venNmoNspNverN */ | 1170 | /* ieee1394:venNmoNspNverN */ |
1170 | char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; | 1171 | char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; |
1171 | 1172 | ||
1172 | if (!cdev) | 1173 | if (!dev) |
1173 | return -ENODEV; | 1174 | return -ENODEV; |
1174 | 1175 | ||
1175 | ud = container_of(cdev, struct unit_directory, class_dev); | 1176 | ud = container_of(dev, struct unit_directory, unit_dev); |
1176 | 1177 | ||
1177 | if (ud->ne->in_limbo || ud->ignore_driver) | 1178 | if (ud->ne->in_limbo || ud->ignore_driver) |
1178 | return -ENODEV; | 1179 | return -ENODEV; |
@@ -1207,7 +1208,7 @@ do { \ | |||
1207 | 1208 | ||
1208 | #else | 1209 | #else |
1209 | 1210 | ||
1210 | static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, | 1211 | static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, |
1211 | char *buffer, int buffer_size) | 1212 | char *buffer, int buffer_size) |
1212 | { | 1213 | { |
1213 | return -ENODEV; | 1214 | return -ENODEV; |
@@ -1378,8 +1379,10 @@ static void nodemgr_node_scan(struct host_info *hi, int generation) | |||
1378 | 1379 | ||
1379 | static void nodemgr_suspend_ne(struct node_entry *ne) | 1380 | static void nodemgr_suspend_ne(struct node_entry *ne) |
1380 | { | 1381 | { |
1381 | struct class_device *cdev; | 1382 | struct device *dev; |
1382 | struct unit_directory *ud; | 1383 | struct unit_directory *ud; |
1384 | struct device_driver *drv; | ||
1385 | int error; | ||
1383 | 1386 | ||
1384 | HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | 1387 | HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", |
1385 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); | 1388 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); |
@@ -1388,15 +1391,24 @@ static void nodemgr_suspend_ne(struct node_entry *ne) | |||
1388 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); | 1391 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); |
1389 | 1392 | ||
1390 | down(&nodemgr_ud_class.sem); | 1393 | down(&nodemgr_ud_class.sem); |
1391 | list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { | 1394 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { |
1392 | ud = container_of(cdev, struct unit_directory, class_dev); | 1395 | ud = container_of(dev, struct unit_directory, unit_dev); |
1393 | if (ud->ne != ne) | 1396 | if (ud->ne != ne) |
1394 | continue; | 1397 | continue; |
1395 | 1398 | ||
1396 | if (ud->device.driver && | 1399 | drv = get_driver(ud->device.driver); |
1397 | (!ud->device.driver->suspend || | 1400 | if (!drv) |
1398 | ud->device.driver->suspend(&ud->device, PMSG_SUSPEND))) | 1401 | continue; |
1402 | |||
1403 | error = 1; /* release if suspend is not implemented */ | ||
1404 | if (drv->suspend) { | ||
1405 | down(&ud->device.sem); | ||
1406 | error = drv->suspend(&ud->device, PMSG_SUSPEND); | ||
1407 | up(&ud->device.sem); | ||
1408 | } | ||
1409 | if (error) | ||
1399 | device_release_driver(&ud->device); | 1410 | device_release_driver(&ud->device); |
1411 | put_driver(drv); | ||
1400 | } | 1412 | } |
1401 | up(&nodemgr_ud_class.sem); | 1413 | up(&nodemgr_ud_class.sem); |
1402 | } | 1414 | } |
@@ -1404,20 +1416,29 @@ static void nodemgr_suspend_ne(struct node_entry *ne) | |||
1404 | 1416 | ||
1405 | static void nodemgr_resume_ne(struct node_entry *ne) | 1417 | static void nodemgr_resume_ne(struct node_entry *ne) |
1406 | { | 1418 | { |
1407 | struct class_device *cdev; | 1419 | struct device *dev; |
1408 | struct unit_directory *ud; | 1420 | struct unit_directory *ud; |
1421 | struct device_driver *drv; | ||
1409 | 1422 | ||
1410 | ne->in_limbo = 0; | 1423 | ne->in_limbo = 0; |
1411 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); | 1424 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); |
1412 | 1425 | ||
1413 | down(&nodemgr_ud_class.sem); | 1426 | down(&nodemgr_ud_class.sem); |
1414 | list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { | 1427 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { |
1415 | ud = container_of(cdev, struct unit_directory, class_dev); | 1428 | ud = container_of(dev, struct unit_directory, unit_dev); |
1416 | if (ud->ne != ne) | 1429 | if (ud->ne != ne) |
1417 | continue; | 1430 | continue; |
1418 | 1431 | ||
1419 | if (ud->device.driver && ud->device.driver->resume) | 1432 | drv = get_driver(ud->device.driver); |
1420 | ud->device.driver->resume(&ud->device); | 1433 | if (!drv) |
1434 | continue; | ||
1435 | |||
1436 | if (drv->resume) { | ||
1437 | down(&ud->device.sem); | ||
1438 | drv->resume(&ud->device); | ||
1439 | up(&ud->device.sem); | ||
1440 | } | ||
1441 | put_driver(drv); | ||
1421 | } | 1442 | } |
1422 | up(&nodemgr_ud_class.sem); | 1443 | up(&nodemgr_ud_class.sem); |
1423 | 1444 | ||
@@ -1428,23 +1449,32 @@ static void nodemgr_resume_ne(struct node_entry *ne) | |||
1428 | 1449 | ||
1429 | static void nodemgr_update_pdrv(struct node_entry *ne) | 1450 | static void nodemgr_update_pdrv(struct node_entry *ne) |
1430 | { | 1451 | { |
1452 | struct device *dev; | ||
1431 | struct unit_directory *ud; | 1453 | struct unit_directory *ud; |
1454 | struct device_driver *drv; | ||
1432 | struct hpsb_protocol_driver *pdrv; | 1455 | struct hpsb_protocol_driver *pdrv; |
1433 | struct class_device *cdev; | 1456 | int error; |
1434 | 1457 | ||
1435 | down(&nodemgr_ud_class.sem); | 1458 | down(&nodemgr_ud_class.sem); |
1436 | list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { | 1459 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { |
1437 | ud = container_of(cdev, struct unit_directory, class_dev); | 1460 | ud = container_of(dev, struct unit_directory, unit_dev); |
1438 | if (ud->ne != ne) | 1461 | if (ud->ne != ne) |
1439 | continue; | 1462 | continue; |
1440 | 1463 | ||
1441 | if (ud->device.driver) { | 1464 | drv = get_driver(ud->device.driver); |
1442 | pdrv = container_of(ud->device.driver, | 1465 | if (!drv) |
1443 | struct hpsb_protocol_driver, | 1466 | continue; |
1444 | driver); | 1467 | |
1445 | if (pdrv->update && pdrv->update(ud)) | 1468 | error = 0; |
1446 | device_release_driver(&ud->device); | 1469 | pdrv = container_of(drv, struct hpsb_protocol_driver, driver); |
1470 | if (pdrv->update) { | ||
1471 | down(&ud->device.sem); | ||
1472 | error = pdrv->update(ud); | ||
1473 | up(&ud->device.sem); | ||
1447 | } | 1474 | } |
1475 | if (error) | ||
1476 | device_release_driver(&ud->device); | ||
1477 | put_driver(drv); | ||
1448 | } | 1478 | } |
1449 | up(&nodemgr_ud_class.sem); | 1479 | up(&nodemgr_ud_class.sem); |
1450 | } | 1480 | } |
@@ -1509,7 +1539,7 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge | |||
1509 | static void nodemgr_node_probe(struct host_info *hi, int generation) | 1539 | static void nodemgr_node_probe(struct host_info *hi, int generation) |
1510 | { | 1540 | { |
1511 | struct hpsb_host *host = hi->host; | 1541 | struct hpsb_host *host = hi->host; |
1512 | struct class_device *cdev; | 1542 | struct device *dev; |
1513 | struct node_entry *ne; | 1543 | struct node_entry *ne; |
1514 | 1544 | ||
1515 | /* Do some processing of the nodes we've probed. This pulls them | 1545 | /* Do some processing of the nodes we've probed. This pulls them |
@@ -1522,13 +1552,13 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) | |||
1522 | * improvement...) */ | 1552 | * improvement...) */ |
1523 | 1553 | ||
1524 | down(&nodemgr_ne_class.sem); | 1554 | down(&nodemgr_ne_class.sem); |
1525 | list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { | 1555 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { |
1526 | ne = container_of(cdev, struct node_entry, class_dev); | 1556 | ne = container_of(dev, struct node_entry, node_dev); |
1527 | if (!ne->needs_probe) | 1557 | if (!ne->needs_probe) |
1528 | nodemgr_probe_ne(hi, ne, generation); | 1558 | nodemgr_probe_ne(hi, ne, generation); |
1529 | } | 1559 | } |
1530 | list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { | 1560 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { |
1531 | ne = container_of(cdev, struct node_entry, class_dev); | 1561 | ne = container_of(dev, struct node_entry, node_dev); |
1532 | if (ne->needs_probe) | 1562 | if (ne->needs_probe) |
1533 | nodemgr_probe_ne(hi, ne, generation); | 1563 | nodemgr_probe_ne(hi, ne, generation); |
1534 | } | 1564 | } |
@@ -1686,18 +1716,12 @@ static int nodemgr_host_thread(void *__hi) | |||
1686 | if (kthread_should_stop()) | 1716 | if (kthread_should_stop()) |
1687 | goto exit; | 1717 | goto exit; |
1688 | 1718 | ||
1689 | if (mutex_lock_interruptible(&nodemgr_serialize)) { | ||
1690 | if (try_to_freeze()) | ||
1691 | continue; | ||
1692 | goto exit; | ||
1693 | } | ||
1694 | |||
1695 | /* Pause for 1/4 second in 1/16 second intervals, | 1719 | /* Pause for 1/4 second in 1/16 second intervals, |
1696 | * to make sure things settle down. */ | 1720 | * to make sure things settle down. */ |
1697 | g = get_hpsb_generation(host); | 1721 | g = get_hpsb_generation(host); |
1698 | for (i = 0; i < 4 ; i++) { | 1722 | for (i = 0; i < 4 ; i++) { |
1699 | if (msleep_interruptible(63) || kthread_should_stop()) | 1723 | if (msleep_interruptible(63) || kthread_should_stop()) |
1700 | goto unlock_exit; | 1724 | goto exit; |
1701 | 1725 | ||
1702 | /* Now get the generation in which the node ID's we collect | 1726 | /* Now get the generation in which the node ID's we collect |
1703 | * are valid. During the bus scan we will use this generation | 1727 | * are valid. During the bus scan we will use this generation |
@@ -1715,7 +1739,6 @@ static int nodemgr_host_thread(void *__hi) | |||
1715 | if (!nodemgr_check_irm_capability(host, reset_cycles) || | 1739 | if (!nodemgr_check_irm_capability(host, reset_cycles) || |
1716 | !nodemgr_do_irm_duties(host, reset_cycles)) { | 1740 | !nodemgr_do_irm_duties(host, reset_cycles)) { |
1717 | reset_cycles++; | 1741 | reset_cycles++; |
1718 | mutex_unlock(&nodemgr_serialize); | ||
1719 | continue; | 1742 | continue; |
1720 | } | 1743 | } |
1721 | reset_cycles = 0; | 1744 | reset_cycles = 0; |
@@ -1732,11 +1755,7 @@ static int nodemgr_host_thread(void *__hi) | |||
1732 | 1755 | ||
1733 | /* Update some of our sysfs symlinks */ | 1756 | /* Update some of our sysfs symlinks */ |
1734 | nodemgr_update_host_dev_links(host); | 1757 | nodemgr_update_host_dev_links(host); |
1735 | |||
1736 | mutex_unlock(&nodemgr_serialize); | ||
1737 | } | 1758 | } |
1738 | unlock_exit: | ||
1739 | mutex_unlock(&nodemgr_serialize); | ||
1740 | exit: | 1759 | exit: |
1741 | HPSB_VERBOSE("NodeMgr: Exiting thread"); | 1760 | HPSB_VERBOSE("NodeMgr: Exiting thread"); |
1742 | return 0; | 1761 | return 0; |
@@ -1756,13 +1775,13 @@ exit: | |||
1756 | */ | 1775 | */ |
1757 | int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) | 1776 | int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) |
1758 | { | 1777 | { |
1759 | struct class_device *cdev; | 1778 | struct device *dev; |
1760 | struct hpsb_host *host; | 1779 | struct hpsb_host *host; |
1761 | int error = 0; | 1780 | int error = 0; |
1762 | 1781 | ||
1763 | down(&hpsb_host_class.sem); | 1782 | down(&hpsb_host_class.sem); |
1764 | list_for_each_entry(cdev, &hpsb_host_class.children, node) { | 1783 | list_for_each_entry(dev, &hpsb_host_class.devices, node) { |
1765 | host = container_of(cdev, struct hpsb_host, class_dev); | 1784 | host = container_of(dev, struct hpsb_host, host_dev); |
1766 | 1785 | ||
1767 | if ((error = cb(host, data))) | 1786 | if ((error = cb(host, data))) |
1768 | break; | 1787 | break; |