aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ieee1394/nodemgr.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 893955249bad..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
148static DEFINE_MUTEX(nodemgr_serialize);
149
150struct host_info { 149struct host_info {
151 struct hpsb_host *host; 150 struct hpsb_host *host;
152 struct list_head list; 151 struct list_head list;
@@ -1382,6 +1381,8 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
1382{ 1381{
1383 struct device *dev; 1382 struct device *dev;
1384 struct unit_directory *ud; 1383 struct unit_directory *ud;
1384 struct device_driver *drv;
1385 int error;
1385 1386
1386 HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", 1387 HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
1387 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);
@@ -1395,10 +1396,19 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
1395 if (ud->ne != ne) 1396 if (ud->ne != ne)
1396 continue; 1397 continue;
1397 1398
1398 if (ud->device.driver && 1399 drv = get_driver(ud->device.driver);
1399 (!ud->device.driver->suspend || 1400 if (!drv)
1400 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)
1401 device_release_driver(&ud->device); 1410 device_release_driver(&ud->device);
1411 put_driver(drv);
1402 } 1412 }
1403 up(&nodemgr_ud_class.sem); 1413 up(&nodemgr_ud_class.sem);
1404} 1414}
@@ -1408,6 +1418,7 @@ static void nodemgr_resume_ne(struct node_entry *ne)
1408{ 1418{
1409 struct device *dev; 1419 struct device *dev;
1410 struct unit_directory *ud; 1420 struct unit_directory *ud;
1421 struct device_driver *drv;
1411 1422
1412 ne->in_limbo = 0; 1423 ne->in_limbo = 0;
1413 device_remove_file(&ne->device, &dev_attr_ne_in_limbo); 1424 device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
@@ -1418,8 +1429,16 @@ static void nodemgr_resume_ne(struct node_entry *ne)
1418 if (ud->ne != ne) 1429 if (ud->ne != ne)
1419 continue; 1430 continue;
1420 1431
1421 if (ud->device.driver && ud->device.driver->resume) 1432 drv = get_driver(ud->device.driver);
1422 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);
1423 } 1442 }
1424 up(&nodemgr_ud_class.sem); 1443 up(&nodemgr_ud_class.sem);
1425 1444
@@ -1430,9 +1449,11 @@ static void nodemgr_resume_ne(struct node_entry *ne)
1430 1449
1431static void nodemgr_update_pdrv(struct node_entry *ne) 1450static void nodemgr_update_pdrv(struct node_entry *ne)
1432{ 1451{
1452 struct device *dev;
1433 struct unit_directory *ud; 1453 struct unit_directory *ud;
1454 struct device_driver *drv;
1434 struct hpsb_protocol_driver *pdrv; 1455 struct hpsb_protocol_driver *pdrv;
1435 struct device *dev; 1456 int error;
1436 1457
1437 down(&nodemgr_ud_class.sem); 1458 down(&nodemgr_ud_class.sem);
1438 list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { 1459 list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
@@ -1440,13 +1461,20 @@ static void nodemgr_update_pdrv(struct node_entry *ne)
1440 if (ud->ne != ne) 1461 if (ud->ne != ne)
1441 continue; 1462 continue;
1442 1463
1443 if (ud->device.driver) { 1464 drv = get_driver(ud->device.driver);
1444 pdrv = container_of(ud->device.driver, 1465 if (!drv)
1445 struct hpsb_protocol_driver, 1466 continue;
1446 driver); 1467
1447 if (pdrv->update && pdrv->update(ud)) 1468 error = 0;
1448 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);
1449 } 1474 }
1475 if (error)
1476 device_release_driver(&ud->device);
1477 put_driver(drv);
1450 } 1478 }
1451 up(&nodemgr_ud_class.sem); 1479 up(&nodemgr_ud_class.sem);
1452} 1480}
@@ -1688,18 +1716,12 @@ static int nodemgr_host_thread(void *__hi)
1688 if (kthread_should_stop()) 1716 if (kthread_should_stop())
1689 goto exit; 1717 goto exit;
1690 1718
1691 if (mutex_lock_interruptible(&nodemgr_serialize)) {
1692 if (try_to_freeze())
1693 continue;
1694 goto exit;
1695 }
1696
1697 /* Pause for 1/4 second in 1/16 second intervals, 1719 /* Pause for 1/4 second in 1/16 second intervals,
1698 * to make sure things settle down. */ 1720 * to make sure things settle down. */
1699 g = get_hpsb_generation(host); 1721 g = get_hpsb_generation(host);
1700 for (i = 0; i < 4 ; i++) { 1722 for (i = 0; i < 4 ; i++) {
1701 if (msleep_interruptible(63) || kthread_should_stop()) 1723 if (msleep_interruptible(63) || kthread_should_stop())
1702 goto unlock_exit; 1724 goto exit;
1703 1725
1704 /* 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
1705 * are valid. During the bus scan we will use this generation 1727 * are valid. During the bus scan we will use this generation
@@ -1717,7 +1739,6 @@ static int nodemgr_host_thread(void *__hi)
1717 if (!nodemgr_check_irm_capability(host, reset_cycles) || 1739 if (!nodemgr_check_irm_capability(host, reset_cycles) ||
1718 !nodemgr_do_irm_duties(host, reset_cycles)) { 1740 !nodemgr_do_irm_duties(host, reset_cycles)) {
1719 reset_cycles++; 1741 reset_cycles++;
1720 mutex_unlock(&nodemgr_serialize);
1721 continue; 1742 continue;
1722 } 1743 }
1723 reset_cycles = 0; 1744 reset_cycles = 0;
@@ -1734,11 +1755,7 @@ static int nodemgr_host_thread(void *__hi)
1734 1755
1735 /* Update some of our sysfs symlinks */ 1756 /* Update some of our sysfs symlinks */
1736 nodemgr_update_host_dev_links(host); 1757 nodemgr_update_host_dev_links(host);
1737
1738 mutex_unlock(&nodemgr_serialize);
1739 } 1758 }
1740unlock_exit:
1741 mutex_unlock(&nodemgr_serialize);
1742exit: 1759exit:
1743 HPSB_VERBOSE("NodeMgr: Exiting thread"); 1760 HPSB_VERBOSE("NodeMgr: Exiting thread");
1744 return 0; 1761 return 0;