aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/nodemgr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:34:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:35:13 -0500
commitdf8dc74e8a383eaf2d9b44b80a71ec6f0e52b42e (patch)
treebc3799a43e8b94fa84b32e37b1c124d5e4868f50 /drivers/ieee1394/nodemgr.c
parent556a169dab38b5100df6f4a45b655dddd3db94c1 (diff)
parent4a3ad20ccd8f4d2a0535cf98fa83f7b561ba59a9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6
This can be broken down into these major areas: - Documentation updates (language translations and fixes, as well as kobject and kset documenatation updates.) - major kset/kobject/ktype rework and fixes. This cleans up the kset and kobject and ktype relationship and architecture, making sense of things now, and good documenation and samples are provided for others to use. Also the attributes for kobjects are much easier to handle now. This cleaned up a LOT of code all through the kernel, making kobjects easier to use if you want to. - struct bus_type has been reworked to now handle the lifetime rules properly, as the kobject is properly dynamic. - struct driver has also been reworked, and now the lifetime issues are resolved. - the block subsystem has been converted to use struct device now, and not "raw" kobjects. This patch has been in the -mm tree for over a year now, and finally all the issues are worked out with it. Older distros now properly work with new kernels, and no userspace updates are needed at all. - nozomi driver is added. This has also been in -mm for a long time, and many people have asked for it to go in. It is now in good enough shape to do so. - lots of class_device conversions to use struct device instead. The tree is almost all cleaned up now, only SCSI and IB is the remaining code to fix up... * git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6: (196 commits) Driver core: coding style fixes Kobject: fix coding style issues in kobject c files Kobject: fix coding style issues in kobject.h Driver core: fix coding style issues in device.h spi: use class iteration api scsi: use class iteration api rtc: use class iteration api power supply : use class iteration api ieee1394: use class iteration api Driver Core: add class iteration api Driver core: Cleanup get_device_parent() in device_add() and device_move() UIO: constify function pointer tables Driver Core: constify the name passed to platform_device_register_simple driver core: fix build with SYSFS=n sysfs: make SYSFS_DEPRECATED depend on SYSFS Driver core: use LIST_HEAD instead of call to INIT_LIST_HEAD in __init kobject: add sample code for how to use ksets/ktypes/kobjects kobject: add sample code for how to use kobjects in a simple manner. kobject: update the kobject/kset documentation kobject: remove old, outdated documentation. ...
Diffstat (limited to 'drivers/ieee1394/nodemgr.c')
-rw-r--r--drivers/ieee1394/nodemgr.c314
1 files changed, 176 insertions, 138 deletions
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 90dc75be3418..511e4321c6b6 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -727,33 +727,31 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
727 727
728static DEFINE_MUTEX(nodemgr_serialize_remove_uds); 728static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
729 729
730static int __match_ne(struct device *dev, void *data)
731{
732 struct unit_directory *ud;
733 struct node_entry *ne = (struct node_entry *)data;
734
735 ud = container_of(dev, struct unit_directory, unit_dev);
736 return ud->ne == ne;
737}
738
730static void nodemgr_remove_uds(struct node_entry *ne) 739static void nodemgr_remove_uds(struct node_entry *ne)
731{ 740{
732 struct device *dev; 741 struct device *dev;
733 struct unit_directory *tmp, *ud; 742 struct unit_directory *ud;
734 743
735 /* Iteration over nodemgr_ud_class.devices has to be protected by 744 /* Use class_find device to iterate the devices. Since this code
736 * nodemgr_ud_class.sem, but device_unregister() will eventually 745 * may be called from other contexts besides the knodemgrds,
737 * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time, 746 * protect it by nodemgr_serialize_remove_uds.
738 * release the semaphore, and then unregister the ud. Since this code
739 * may be called from other contexts besides the knodemgrds, protect the
740 * gap after release of the semaphore by nodemgr_serialize_remove_uds.
741 */ 747 */
742 mutex_lock(&nodemgr_serialize_remove_uds); 748 mutex_lock(&nodemgr_serialize_remove_uds);
743 for (;;) { 749 for (;;) {
744 ud = NULL; 750 dev = class_find_device(&nodemgr_ud_class, ne, __match_ne);
745 down(&nodemgr_ud_class.sem); 751 if (!dev)
746 list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
747 tmp = container_of(dev, struct unit_directory,
748 unit_dev);
749 if (tmp->ne == ne) {
750 ud = tmp;
751 break;
752 }
753 }
754 up(&nodemgr_ud_class.sem);
755 if (ud == NULL)
756 break; 752 break;
753 ud = container_of(dev, struct unit_directory, unit_dev);
754 put_device(dev);
757 device_unregister(&ud->unit_dev); 755 device_unregister(&ud->unit_dev);
758 device_unregister(&ud->device); 756 device_unregister(&ud->device);
759 } 757 }
@@ -882,45 +880,66 @@ fail_alloc:
882 return NULL; 880 return NULL;
883} 881}
884 882
883static int __match_ne_guid(struct device *dev, void *data)
884{
885 struct node_entry *ne;
886 u64 *guid = (u64 *)data;
887
888 ne = container_of(dev, struct node_entry, node_dev);
889 return ne->guid == *guid;
890}
885 891
886static struct node_entry *find_entry_by_guid(u64 guid) 892static struct node_entry *find_entry_by_guid(u64 guid)
887{ 893{
888 struct device *dev; 894 struct device *dev;
889 struct node_entry *ne, *ret_ne = NULL; 895 struct node_entry *ne;
890
891 down(&nodemgr_ne_class.sem);
892 list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
893 ne = container_of(dev, struct node_entry, node_dev);
894 896
895 if (ne->guid == guid) { 897 dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid);
896 ret_ne = ne; 898 if (!dev)
897 break; 899 return NULL;
898 } 900 ne = container_of(dev, struct node_entry, node_dev);
899 } 901 put_device(dev);
900 up(&nodemgr_ne_class.sem);
901 902
902 return ret_ne; 903 return ne;
903} 904}
904 905
906struct match_nodeid_param {
907 struct hpsb_host *host;
908 nodeid_t nodeid;
909};
910
911static int __match_ne_nodeid(struct device *dev, void *data)
912{
913 int found = 0;
914 struct node_entry *ne;
915 struct match_nodeid_param *param = (struct match_nodeid_param *)data;
916
917 if (!dev)
918 goto ret;
919 ne = container_of(dev, struct node_entry, node_dev);
920 if (ne->host == param->host && ne->nodeid == param->nodeid)
921 found = 1;
922ret:
923 return found;
924}
905 925
906static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, 926static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
907 nodeid_t nodeid) 927 nodeid_t nodeid)
908{ 928{
909 struct device *dev; 929 struct device *dev;
910 struct node_entry *ne, *ret_ne = NULL; 930 struct node_entry *ne;
931 struct match_nodeid_param param;
911 932
912 down(&nodemgr_ne_class.sem); 933 param.host = host;
913 list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { 934 param.nodeid = nodeid;
914 ne = container_of(dev, struct node_entry, node_dev);
915 935
916 if (ne->host == host && ne->nodeid == nodeid) { 936 dev = class_find_device(&nodemgr_ne_class, &param, __match_ne_nodeid);
917 ret_ne = ne; 937 if (!dev)
918 break; 938 return NULL;
919 } 939 ne = container_of(dev, struct node_entry, node_dev);
920 } 940 put_device(dev);
921 up(&nodemgr_ne_class.sem);
922 941
923 return ret_ne; 942 return ne;
924} 943}
925 944
926 945
@@ -1370,107 +1389,109 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
1370 } 1389 }
1371} 1390}
1372 1391
1373 1392static int __nodemgr_driver_suspend(struct device *dev, void *data)
1374static void nodemgr_suspend_ne(struct node_entry *ne)
1375{ 1393{
1376 struct device *dev;
1377 struct unit_directory *ud; 1394 struct unit_directory *ud;
1378 struct device_driver *drv; 1395 struct device_driver *drv;
1396 struct node_entry *ne = (struct node_entry *)data;
1379 int error; 1397 int error;
1380 1398
1381 HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", 1399 ud = container_of(dev, struct unit_directory, unit_dev);
1382 NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); 1400 if (ud->ne == ne) {
1401 drv = get_driver(ud->device.driver);
1402 if (drv) {
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)
1410 device_release_driver(&ud->device);
1411 put_driver(drv);
1412 }
1413 }
1383 1414
1384 ne->in_limbo = 1; 1415 return 0;
1385 WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); 1416}
1386 1417
1387 down(&nodemgr_ud_class.sem); 1418static int __nodemgr_driver_resume(struct device *dev, void *data)
1388 list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { 1419{
1389 ud = container_of(dev, struct unit_directory, unit_dev); 1420 struct unit_directory *ud;
1390 if (ud->ne != ne) 1421 struct device_driver *drv;
1391 continue; 1422 struct node_entry *ne = (struct node_entry *)data;
1392 1423
1424 ud = container_of(dev, struct unit_directory, unit_dev);
1425 if (ud->ne == ne) {
1393 drv = get_driver(ud->device.driver); 1426 drv = get_driver(ud->device.driver);
1394 if (!drv) 1427 if (drv) {
1395 continue; 1428 if (drv->resume) {
1396 1429 down(&ud->device.sem);
1397 error = 1; /* release if suspend is not implemented */ 1430 drv->resume(&ud->device);
1398 if (drv->suspend) { 1431 up(&ud->device.sem);
1399 down(&ud->device.sem); 1432 }
1400 error = drv->suspend(&ud->device, PMSG_SUSPEND); 1433 put_driver(drv);
1401 up(&ud->device.sem);
1402 } 1434 }
1403 if (error)
1404 device_release_driver(&ud->device);
1405 put_driver(drv);
1406 } 1435 }
1407 up(&nodemgr_ud_class.sem);
1408}
1409 1436
1437 return 0;
1438}
1410 1439
1411static void nodemgr_resume_ne(struct node_entry *ne) 1440static void nodemgr_suspend_ne(struct node_entry *ne)
1412{ 1441{
1413 struct device *dev; 1442 HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
1414 struct unit_directory *ud; 1443 NODE_BUS_ARGS(ne->host, ne->nodeid),
1415 struct device_driver *drv; 1444 (unsigned long long)ne->guid);
1416 1445
1417 ne->in_limbo = 0; 1446 ne->in_limbo = 1;
1418 device_remove_file(&ne->device, &dev_attr_ne_in_limbo); 1447 WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
1419 1448
1420 down(&nodemgr_ud_class.sem); 1449 class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_suspend);
1421 list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { 1450}
1422 ud = container_of(dev, struct unit_directory, unit_dev);
1423 if (ud->ne != ne)
1424 continue;
1425 1451
1426 drv = get_driver(ud->device.driver);
1427 if (!drv)
1428 continue;
1429 1452
1430 if (drv->resume) { 1453static void nodemgr_resume_ne(struct node_entry *ne)
1431 down(&ud->device.sem); 1454{
1432 drv->resume(&ud->device); 1455 ne->in_limbo = 0;
1433 up(&ud->device.sem); 1456 device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
1434 }
1435 put_driver(drv);
1436 }
1437 up(&nodemgr_ud_class.sem);
1438 1457
1458 class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_resume);
1439 HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", 1459 HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
1440 NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); 1460 NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
1441} 1461}
1442 1462
1443 1463static int __nodemgr_update_pdrv(struct device *dev, void *data)
1444static void nodemgr_update_pdrv(struct node_entry *ne)
1445{ 1464{
1446 struct device *dev;
1447 struct unit_directory *ud; 1465 struct unit_directory *ud;
1448 struct device_driver *drv; 1466 struct device_driver *drv;
1449 struct hpsb_protocol_driver *pdrv; 1467 struct hpsb_protocol_driver *pdrv;
1468 struct node_entry *ne = (struct node_entry *)data;
1450 int error; 1469 int error;
1451 1470
1452 down(&nodemgr_ud_class.sem); 1471 ud = container_of(dev, struct unit_directory, unit_dev);
1453 list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { 1472 if (ud->ne == ne) {
1454 ud = container_of(dev, struct unit_directory, unit_dev);
1455 if (ud->ne != ne)
1456 continue;
1457
1458 drv = get_driver(ud->device.driver); 1473 drv = get_driver(ud->device.driver);
1459 if (!drv) 1474 if (drv) {
1460 continue; 1475 error = 0;
1461 1476 pdrv = container_of(drv, struct hpsb_protocol_driver,
1462 error = 0; 1477 driver);
1463 pdrv = container_of(drv, struct hpsb_protocol_driver, driver); 1478 if (pdrv->update) {
1464 if (pdrv->update) { 1479 down(&ud->device.sem);
1465 down(&ud->device.sem); 1480 error = pdrv->update(ud);
1466 error = pdrv->update(ud); 1481 up(&ud->device.sem);
1467 up(&ud->device.sem); 1482 }
1483 if (error)
1484 device_release_driver(&ud->device);
1485 put_driver(drv);
1468 } 1486 }
1469 if (error)
1470 device_release_driver(&ud->device);
1471 put_driver(drv);
1472 } 1487 }
1473 up(&nodemgr_ud_class.sem); 1488
1489 return 0;
1490}
1491
1492static void nodemgr_update_pdrv(struct node_entry *ne)
1493{
1494 class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_update_pdrv);
1474} 1495}
1475 1496
1476 1497
@@ -1529,13 +1550,31 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
1529 put_device(dev); 1550 put_device(dev);
1530} 1551}
1531 1552
1553struct probe_param {
1554 struct host_info *hi;
1555 int generation;
1556};
1557
1558static int __nodemgr_node_probe(struct device *dev, void *data)
1559{
1560 struct probe_param *param = (struct probe_param *)data;
1561 struct node_entry *ne;
1562
1563 ne = container_of(dev, struct node_entry, node_dev);
1564 if (!ne->needs_probe)
1565 nodemgr_probe_ne(param->hi, ne, param->generation);
1566 if (ne->needs_probe)
1567 nodemgr_probe_ne(param->hi, ne, param->generation);
1568 return 0;
1569}
1532 1570
1533static void nodemgr_node_probe(struct host_info *hi, int generation) 1571static void nodemgr_node_probe(struct host_info *hi, int generation)
1534{ 1572{
1535 struct hpsb_host *host = hi->host; 1573 struct hpsb_host *host = hi->host;
1536 struct device *dev; 1574 struct probe_param param;
1537 struct node_entry *ne;
1538 1575
1576 param.hi = hi;
1577 param.generation = generation;
1539 /* Do some processing of the nodes we've probed. This pulls them 1578 /* Do some processing of the nodes we've probed. This pulls them
1540 * into the sysfs layer if needed, and can result in processing of 1579 * into the sysfs layer if needed, and can result in processing of
1541 * unit-directories, or just updating the node and it's 1580 * unit-directories, or just updating the node and it's
@@ -1545,19 +1584,7 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
1545 * while probes are time-consuming. (Well, those probes need some 1584 * while probes are time-consuming. (Well, those probes need some
1546 * improvement...) */ 1585 * improvement...) */
1547 1586
1548 down(&nodemgr_ne_class.sem); 1587 class_for_each_device(&nodemgr_ne_class, &param, __nodemgr_node_probe);
1549 list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
1550 ne = container_of(dev, struct node_entry, node_dev);
1551 if (!ne->needs_probe)
1552 nodemgr_probe_ne(hi, ne, generation);
1553 }
1554 list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
1555 ne = container_of(dev, struct node_entry, node_dev);
1556 if (ne->needs_probe)
1557 nodemgr_probe_ne(hi, ne, generation);
1558 }
1559 up(&nodemgr_ne_class.sem);
1560
1561 1588
1562 /* If we had a bus reset while we were scanning the bus, it is 1589 /* If we had a bus reset while we were scanning the bus, it is
1563 * possible that we did not probe all nodes. In that case, we 1590 * possible that we did not probe all nodes. In that case, we
@@ -1757,6 +1784,22 @@ exit:
1757 return 0; 1784 return 0;
1758} 1785}
1759 1786
1787struct host_iter_param {
1788 void *data;
1789 int (*cb)(struct hpsb_host *, void *);
1790};
1791
1792static int __nodemgr_for_each_host(struct device *dev, void *data)
1793{
1794 struct hpsb_host *host;
1795 struct host_iter_param *hip = (struct host_iter_param *)data;
1796 int error = 0;
1797
1798 host = container_of(dev, struct hpsb_host, host_dev);
1799 error = hip->cb(host, hip->data);
1800
1801 return error;
1802}
1760/** 1803/**
1761 * nodemgr_for_each_host - call a function for each IEEE 1394 host 1804 * nodemgr_for_each_host - call a function for each IEEE 1394 host
1762 * @data: an address to supply to the callback 1805 * @data: an address to supply to the callback
@@ -1771,18 +1814,13 @@ exit:
1771 */ 1814 */
1772int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) 1815int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
1773{ 1816{
1774 struct device *dev; 1817 struct host_iter_param hip;
1775 struct hpsb_host *host; 1818 int error;
1776 int error = 0;
1777
1778 down(&hpsb_host_class.sem);
1779 list_for_each_entry(dev, &hpsb_host_class.devices, node) {
1780 host = container_of(dev, struct hpsb_host, host_dev);
1781 1819
1782 if ((error = cb(host, data))) 1820 hip.cb = cb;
1783 break; 1821 hip.data = data;
1784 } 1822 error = class_for_each_device(&hpsb_host_class, &hip,
1785 up(&hpsb_host_class.sem); 1823 __nodemgr_for_each_host);
1786 1824
1787 return error; 1825 return error;
1788} 1826}