aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/nodemgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ieee1394/nodemgr.c')
-rw-r--r--drivers/ieee1394/nodemgr.c227
1 files changed, 93 insertions, 134 deletions
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index d541b508a159..3e7974c57443 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -12,26 +12,23 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/list.h> 13#include <linux/list.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/smp_lock.h>
16#include <linux/interrupt.h>
17#include <linux/kmod.h>
18#include <linux/completion.h>
19#include <linux/delay.h> 15#include <linux/delay.h>
20#include <linux/pci.h> 16#include <linux/kthread.h>
21#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
22#include <asm/atomic.h> 18#include <asm/atomic.h>
23 19
24#include "ieee1394_types.h" 20#include "csr.h"
21#include "highlevel.h"
22#include "hosts.h"
25#include "ieee1394.h" 23#include "ieee1394.h"
26#include "ieee1394_core.h" 24#include "ieee1394_core.h"
27#include "hosts.h" 25#include "ieee1394_hotplug.h"
26#include "ieee1394_types.h"
28#include "ieee1394_transactions.h" 27#include "ieee1394_transactions.h"
29#include "highlevel.h"
30#include "csr.h"
31#include "nodemgr.h" 28#include "nodemgr.h"
32 29
33static int ignore_drivers; 30static int ignore_drivers;
34module_param(ignore_drivers, int, 0444); 31module_param(ignore_drivers, int, S_IRUGO | S_IWUSR);
35MODULE_PARM_DESC(ignore_drivers, "Disable automatic probing for drivers."); 32MODULE_PARM_DESC(ignore_drivers, "Disable automatic probing for drivers.");
36 33
37struct nodemgr_csr_info { 34struct nodemgr_csr_info {
@@ -71,7 +68,7 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
71 u8 i, *speed, old_speed, good_speed; 68 u8 i, *speed, old_speed, good_speed;
72 int ret; 69 int ret;
73 70
74 speed = ci->host->speed + NODEID_TO_NODE(ci->nodeid); 71 speed = &(ci->host->speed[NODEID_TO_NODE(ci->nodeid)]);
75 old_speed = *speed; 72 old_speed = *speed;
76 good_speed = IEEE1394_SPEED_MAX + 1; 73 good_speed = IEEE1394_SPEED_MAX + 1;
77 74
@@ -161,16 +158,12 @@ static struct csr1212_bus_ops nodemgr_csr_ops = {
161 * but now we are much simpler because of the LDM. 158 * but now we are much simpler because of the LDM.
162 */ 159 */
163 160
164static DECLARE_MUTEX(nodemgr_serialize); 161static DEFINE_MUTEX(nodemgr_serialize);
165 162
166struct host_info { 163struct host_info {
167 struct hpsb_host *host; 164 struct hpsb_host *host;
168 struct list_head list; 165 struct list_head list;
169 struct completion exited; 166 struct task_struct *thread;
170 struct semaphore reset_sem;
171 int pid;
172 char daemon_name[15];
173 int kill_me;
174}; 167};
175 168
176static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); 169static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
@@ -334,34 +327,44 @@ static ssize_t fw_show_ne_bus_options(struct device *dev, struct device_attribut
334static DEVICE_ATTR(bus_options,S_IRUGO,fw_show_ne_bus_options,NULL); 327static DEVICE_ATTR(bus_options,S_IRUGO,fw_show_ne_bus_options,NULL);
335 328
336 329
337/* tlabels_free, tlabels_allocations, tlabels_mask are read non-atomically 330#ifdef HPSB_DEBUG_TLABELS
338 * here, therefore displayed values may be occasionally wrong. */ 331static ssize_t fw_show_ne_tlabels_free(struct device *dev,
339static ssize_t fw_show_ne_tlabels_free(struct device *dev, struct device_attribute *attr, char *buf) 332 struct device_attribute *attr, char *buf)
340{ 333{
341 struct node_entry *ne = container_of(dev, struct node_entry, device); 334 struct node_entry *ne = container_of(dev, struct node_entry, device);
342 return sprintf(buf, "%d\n", 64 - bitmap_weight(ne->tpool->pool, 64)); 335 unsigned long flags;
343} 336 unsigned long *tp = ne->host->tl_pool[NODEID_TO_NODE(ne->nodeid)].map;
344static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL); 337 int tf;
345 338
339 spin_lock_irqsave(&hpsb_tlabel_lock, flags);
340 tf = 64 - bitmap_weight(tp, 64);
341 spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
346 342
347static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, struct device_attribute *attr, char *buf) 343 return sprintf(buf, "%d\n", tf);
348{
349 struct node_entry *ne = container_of(dev, struct node_entry, device);
350 return sprintf(buf, "%u\n", ne->tpool->allocations);
351} 344}
352static DEVICE_ATTR(tlabels_allocations,S_IRUGO,fw_show_ne_tlabels_allocations,NULL); 345static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL);
353 346
354 347
355static ssize_t fw_show_ne_tlabels_mask(struct device *dev, struct device_attribute *attr, char *buf) 348static ssize_t fw_show_ne_tlabels_mask(struct device *dev,
349 struct device_attribute *attr, char *buf)
356{ 350{
357 struct node_entry *ne = container_of(dev, struct node_entry, device); 351 struct node_entry *ne = container_of(dev, struct node_entry, device);
352 unsigned long flags;
353 unsigned long *tp = ne->host->tl_pool[NODEID_TO_NODE(ne->nodeid)].map;
354 u64 tm;
355
356 spin_lock_irqsave(&hpsb_tlabel_lock, flags);
358#if (BITS_PER_LONG <= 32) 357#if (BITS_PER_LONG <= 32)
359 return sprintf(buf, "0x%08lx%08lx\n", ne->tpool->pool[0], ne->tpool->pool[1]); 358 tm = ((u64)tp[0] << 32) + tp[1];
360#else 359#else
361 return sprintf(buf, "0x%016lx\n", ne->tpool->pool[0]); 360 tm = tp[0];
362#endif 361#endif
362 spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
363
364 return sprintf(buf, "0x%016llx\n", tm);
363} 365}
364static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL); 366static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL);
367#endif /* HPSB_DEBUG_TLABELS */
365 368
366 369
367static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 370static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
@@ -408,26 +411,11 @@ static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf)
408} 411}
409static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node); 412static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node);
410 413
411static int nodemgr_rescan_bus_thread(void *__unused)
412{
413 /* No userlevel access needed */
414 daemonize("kfwrescan");
415
416 bus_rescan_devices(&ieee1394_bus_type);
417
418 return 0;
419}
420 414
421static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, size_t count) 415static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf, size_t count)
422{ 416{
423 int state = simple_strtoul(buf, NULL, 10); 417 if (simple_strtoul(buf, NULL, 10) == 1)
424 418 bus_rescan_devices(&ieee1394_bus_type);
425 /* Don't wait for this, or care about errors. Root could do
426 * something stupid and spawn this a lot of times, but that's
427 * root's fault. */
428 if (state == 1)
429 kernel_thread(nodemgr_rescan_bus_thread, NULL, CLONE_KERNEL);
430
431 return count; 419 return count;
432} 420}
433static ssize_t fw_get_rescan(struct bus_type *bus, char *buf) 421static ssize_t fw_get_rescan(struct bus_type *bus, char *buf)
@@ -483,9 +471,10 @@ static struct device_attribute *const fw_ne_attrs[] = {
483 &dev_attr_ne_vendor_id, 471 &dev_attr_ne_vendor_id,
484 &dev_attr_ne_nodeid, 472 &dev_attr_ne_nodeid,
485 &dev_attr_bus_options, 473 &dev_attr_bus_options,
474#ifdef HPSB_DEBUG_TLABELS
486 &dev_attr_tlabels_free, 475 &dev_attr_tlabels_free,
487 &dev_attr_tlabels_allocations,
488 &dev_attr_tlabels_mask, 476 &dev_attr_tlabels_mask,
477#endif
489}; 478};
490 479
491 480
@@ -804,8 +793,6 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
804 if (!ne) 793 if (!ne)
805 return NULL; 794 return NULL;
806 795
807 ne->tpool = &host->tpool[nodeid & NODE_MASK];
808
809 ne->host = host; 796 ne->host = host;
810 ne->nodeid = nodeid; 797 ne->nodeid = nodeid;
811 ne->generation = generation; 798 ne->generation = generation;
@@ -1251,6 +1238,7 @@ static void nodemgr_node_scan_one(struct host_info *hi,
1251 octlet_t guid; 1238 octlet_t guid;
1252 struct csr1212_csr *csr; 1239 struct csr1212_csr *csr;
1253 struct nodemgr_csr_info *ci; 1240 struct nodemgr_csr_info *ci;
1241 u8 *speed;
1254 1242
1255 ci = kmalloc(sizeof(*ci), GFP_KERNEL); 1243 ci = kmalloc(sizeof(*ci), GFP_KERNEL);
1256 if (!ci) 1244 if (!ci)
@@ -1259,8 +1247,12 @@ static void nodemgr_node_scan_one(struct host_info *hi,
1259 ci->host = host; 1247 ci->host = host;
1260 ci->nodeid = nodeid; 1248 ci->nodeid = nodeid;
1261 ci->generation = generation; 1249 ci->generation = generation;
1262 ci->speed_unverified = 1250
1263 host->speed[NODEID_TO_NODE(nodeid)] > IEEE1394_SPEED_100; 1251 /* Prepare for speed probe which occurs when reading the ROM */
1252 speed = &(host->speed[NODEID_TO_NODE(nodeid)]);
1253 if (*speed > host->csr.lnk_spd)
1254 *speed = host->csr.lnk_spd;
1255 ci->speed_unverified = *speed > IEEE1394_SPEED_100;
1264 1256
1265 /* We need to detect when the ConfigROM's generation has changed, 1257 /* We need to detect when the ConfigROM's generation has changed,
1266 * so we only update the node's info when it needs to be. */ 1258 * so we only update the node's info when it needs to be. */
@@ -1300,8 +1292,6 @@ static void nodemgr_node_scan_one(struct host_info *hi,
1300 nodemgr_create_node(guid, csr, hi, nodeid, generation); 1292 nodemgr_create_node(guid, csr, hi, nodeid, generation);
1301 else 1293 else
1302 nodemgr_update_node(ne, csr, hi, nodeid, generation); 1294 nodemgr_update_node(ne, csr, hi, nodeid, generation);
1303
1304 return;
1305} 1295}
1306 1296
1307 1297
@@ -1326,6 +1316,7 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
1326} 1316}
1327 1317
1328 1318
1319/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader. */
1329static void nodemgr_suspend_ne(struct node_entry *ne) 1320static void nodemgr_suspend_ne(struct node_entry *ne)
1330{ 1321{
1331 struct class_device *cdev; 1322 struct class_device *cdev;
@@ -1361,6 +1352,7 @@ static void nodemgr_resume_ne(struct node_entry *ne)
1361 ne->in_limbo = 0; 1352 ne->in_limbo = 0;
1362 device_remove_file(&ne->device, &dev_attr_ne_in_limbo); 1353 device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
1363 1354
1355 down_read(&nodemgr_ud_class.subsys.rwsem);
1364 down_read(&ne->device.bus->subsys.rwsem); 1356 down_read(&ne->device.bus->subsys.rwsem);
1365 list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { 1357 list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
1366 ud = container_of(cdev, struct unit_directory, class_dev); 1358 ud = container_of(cdev, struct unit_directory, class_dev);
@@ -1372,21 +1364,21 @@ static void nodemgr_resume_ne(struct node_entry *ne)
1372 ud->device.driver->resume(&ud->device); 1364 ud->device.driver->resume(&ud->device);
1373 } 1365 }
1374 up_read(&ne->device.bus->subsys.rwsem); 1366 up_read(&ne->device.bus->subsys.rwsem);
1367 up_read(&nodemgr_ud_class.subsys.rwsem);
1375 1368
1376 HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", 1369 HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
1377 NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); 1370 NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
1378} 1371}
1379 1372
1380 1373
1374/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader. */
1381static void nodemgr_update_pdrv(struct node_entry *ne) 1375static void nodemgr_update_pdrv(struct node_entry *ne)
1382{ 1376{
1383 struct unit_directory *ud; 1377 struct unit_directory *ud;
1384 struct hpsb_protocol_driver *pdrv; 1378 struct hpsb_protocol_driver *pdrv;
1385 struct class *class = &nodemgr_ud_class;
1386 struct class_device *cdev; 1379 struct class_device *cdev;
1387 1380
1388 down_read(&class->subsys.rwsem); 1381 list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
1389 list_for_each_entry(cdev, &class->children, node) {
1390 ud = container_of(cdev, struct unit_directory, class_dev); 1382 ud = container_of(cdev, struct unit_directory, class_dev);
1391 if (ud->ne != ne || !ud->device.driver) 1383 if (ud->ne != ne || !ud->device.driver)
1392 continue; 1384 continue;
@@ -1399,7 +1391,6 @@ static void nodemgr_update_pdrv(struct node_entry *ne)
1399 up_write(&ud->device.bus->subsys.rwsem); 1391 up_write(&ud->device.bus->subsys.rwsem);
1400 } 1392 }
1401 } 1393 }
1402 up_read(&class->subsys.rwsem);
1403} 1394}
1404 1395
1405 1396
@@ -1430,6 +1421,8 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
1430} 1421}
1431 1422
1432 1423
1424/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader because the
1425 * calls to nodemgr_update_pdrv() and nodemgr_suspend_ne() here require it. */
1433static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation) 1426static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
1434{ 1427{
1435 struct device *dev; 1428 struct device *dev;
@@ -1492,9 +1485,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
1492 /* If we had a bus reset while we were scanning the bus, it is 1485 /* If we had a bus reset while we were scanning the bus, it is
1493 * possible that we did not probe all nodes. In that case, we 1486 * possible that we did not probe all nodes. In that case, we
1494 * skip the clean up for now, since we could remove nodes that 1487 * skip the clean up for now, since we could remove nodes that
1495 * were still on the bus. The bus reset increased hi->reset_sem, 1488 * were still on the bus. Another bus scan is pending which will
1496 * so there's a bus scan pending which will do the clean up 1489 * do the clean up eventually.
1497 * eventually.
1498 * 1490 *
1499 * Now let's tell the bus to rescan our devices. This may seem 1491 * Now let's tell the bus to rescan our devices. This may seem
1500 * like overhead, but the driver-model core will only scan a 1492 * like overhead, but the driver-model core will only scan a
@@ -1622,41 +1614,37 @@ static int nodemgr_host_thread(void *__hi)
1622{ 1614{
1623 struct host_info *hi = (struct host_info *)__hi; 1615 struct host_info *hi = (struct host_info *)__hi;
1624 struct hpsb_host *host = hi->host; 1616 struct hpsb_host *host = hi->host;
1625 int reset_cycles = 0; 1617 unsigned int g, generation = get_hpsb_generation(host) - 1;
1626 1618 int i, reset_cycles = 0;
1627 /* No userlevel access needed */
1628 daemonize(hi->daemon_name);
1629 1619
1630 /* Setup our device-model entries */ 1620 /* Setup our device-model entries */
1631 nodemgr_create_host_dev_files(host); 1621 nodemgr_create_host_dev_files(host);
1632 1622
1633 /* Sit and wait for a signal to probe the nodes on the bus. This 1623 for (;;) {
1634 * happens when we get a bus reset. */ 1624 /* Sleep until next bus reset */
1635 while (1) { 1625 set_current_state(TASK_INTERRUPTIBLE);
1636 unsigned int generation = 0; 1626 if (get_hpsb_generation(host) == generation)
1637 int i; 1627 schedule();
1628 __set_current_state(TASK_RUNNING);
1629
1630 /* Thread may have been woken up to freeze or to exit */
1631 if (try_to_freeze())
1632 continue;
1633 if (kthread_should_stop())
1634 goto exit;
1638 1635
1639 if (down_interruptible(&hi->reset_sem) || 1636 if (mutex_lock_interruptible(&nodemgr_serialize)) {
1640 down_interruptible(&nodemgr_serialize)) {
1641 if (try_to_freeze()) 1637 if (try_to_freeze())
1642 continue; 1638 continue;
1643 printk("NodeMgr: received unexpected signal?!\n" ); 1639 goto exit;
1644 break;
1645 }
1646
1647 if (hi->kill_me) {
1648 up(&nodemgr_serialize);
1649 break;
1650 } 1640 }
1651 1641
1652 /* Pause for 1/4 second in 1/16 second intervals, 1642 /* Pause for 1/4 second in 1/16 second intervals,
1653 * to make sure things settle down. */ 1643 * to make sure things settle down. */
1644 g = get_hpsb_generation(host);
1654 for (i = 0; i < 4 ; i++) { 1645 for (i = 0; i < 4 ; i++) {
1655 set_current_state(TASK_INTERRUPTIBLE); 1646 if (msleep_interruptible(63) || kthread_should_stop())
1656 if (msleep_interruptible(63)) { 1647 goto unlock_exit;
1657 up(&nodemgr_serialize);
1658 goto caught_signal;
1659 }
1660 1648
1661 /* Now get the generation in which the node ID's we collect 1649 /* Now get the generation in which the node ID's we collect
1662 * are valid. During the bus scan we will use this generation 1650 * are valid. During the bus scan we will use this generation
@@ -1667,20 +1655,14 @@ static int nodemgr_host_thread(void *__hi)
1667 1655
1668 /* If we get a reset before we are done waiting, then 1656 /* If we get a reset before we are done waiting, then
1669 * start the the waiting over again */ 1657 * start the the waiting over again */
1670 while (!down_trylock(&hi->reset_sem)) 1658 if (generation != g)
1671 i = 0; 1659 g = generation, i = 0;
1672
1673 /* Check the kill_me again */
1674 if (hi->kill_me) {
1675 up(&nodemgr_serialize);
1676 goto caught_signal;
1677 }
1678 } 1660 }
1679 1661
1680 if (!nodemgr_check_irm_capability(host, reset_cycles) || 1662 if (!nodemgr_check_irm_capability(host, reset_cycles) ||
1681 !nodemgr_do_irm_duties(host, reset_cycles)) { 1663 !nodemgr_do_irm_duties(host, reset_cycles)) {
1682 reset_cycles++; 1664 reset_cycles++;
1683 up(&nodemgr_serialize); 1665 mutex_unlock(&nodemgr_serialize);
1684 continue; 1666 continue;
1685 } 1667 }
1686 reset_cycles = 0; 1668 reset_cycles = 0;
@@ -1698,13 +1680,13 @@ static int nodemgr_host_thread(void *__hi)
1698 /* Update some of our sysfs symlinks */ 1680 /* Update some of our sysfs symlinks */
1699 nodemgr_update_host_dev_links(host); 1681 nodemgr_update_host_dev_links(host);
1700 1682
1701 up(&nodemgr_serialize); 1683 mutex_unlock(&nodemgr_serialize);
1702 } 1684 }
1703 1685unlock_exit:
1704caught_signal: 1686 mutex_unlock(&nodemgr_serialize);
1687exit:
1705 HPSB_VERBOSE("NodeMgr: Exiting thread"); 1688 HPSB_VERBOSE("NodeMgr: Exiting thread");
1706 1689 return 0;
1707 complete_and_exit(&hi->exited, 0);
1708} 1690}
1709 1691
1710int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *)) 1692int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
@@ -1764,41 +1746,27 @@ static void nodemgr_add_host(struct hpsb_host *host)
1764 struct host_info *hi; 1746 struct host_info *hi;
1765 1747
1766 hi = hpsb_create_hostinfo(&nodemgr_highlevel, host, sizeof(*hi)); 1748 hi = hpsb_create_hostinfo(&nodemgr_highlevel, host, sizeof(*hi));
1767
1768 if (!hi) { 1749 if (!hi) {
1769 HPSB_ERR ("NodeMgr: out of memory in add host"); 1750 HPSB_ERR("NodeMgr: out of memory in add host");
1770 return; 1751 return;
1771 } 1752 }
1772
1773 hi->host = host; 1753 hi->host = host;
1774 init_completion(&hi->exited); 1754 hi->thread = kthread_run(nodemgr_host_thread, hi, "knodemgrd_%d",
1775 sema_init(&hi->reset_sem, 0); 1755 host->id);
1776 1756 if (IS_ERR(hi->thread)) {
1777 sprintf(hi->daemon_name, "knodemgrd_%d", host->id); 1757 HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id);
1778
1779 hi->pid = kernel_thread(nodemgr_host_thread, hi, CLONE_KERNEL);
1780
1781 if (hi->pid < 0) {
1782 HPSB_ERR ("NodeMgr: failed to start %s thread for %s",
1783 hi->daemon_name, host->driver->name);
1784 hpsb_destroy_hostinfo(&nodemgr_highlevel, host); 1758 hpsb_destroy_hostinfo(&nodemgr_highlevel, host);
1785 return;
1786 } 1759 }
1787
1788 return;
1789} 1760}
1790 1761
1791static void nodemgr_host_reset(struct hpsb_host *host) 1762static void nodemgr_host_reset(struct hpsb_host *host)
1792{ 1763{
1793 struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host); 1764 struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
1794 1765
1795 if (hi != NULL) { 1766 if (hi) {
1796 HPSB_VERBOSE("NodeMgr: Processing host reset for %s", hi->daemon_name); 1767 HPSB_VERBOSE("NodeMgr: Processing reset for host %d", host->id);
1797 up(&hi->reset_sem); 1768 wake_up_process(hi->thread);
1798 } else 1769 }
1799 HPSB_ERR ("NodeMgr: could not process reset of unused host");
1800
1801 return;
1802} 1770}
1803 1771
1804static void nodemgr_remove_host(struct hpsb_host *host) 1772static void nodemgr_remove_host(struct hpsb_host *host)
@@ -1806,18 +1774,9 @@ static void nodemgr_remove_host(struct hpsb_host *host)
1806 struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host); 1774 struct host_info *hi = hpsb_get_hostinfo(&nodemgr_highlevel, host);
1807 1775
1808 if (hi) { 1776 if (hi) {
1809 if (hi->pid >= 0) { 1777 kthread_stop(hi->thread);
1810 hi->kill_me = 1; 1778 nodemgr_remove_host_dev(&host->device);
1811 mb(); 1779 }
1812 up(&hi->reset_sem);
1813 wait_for_completion(&hi->exited);
1814 nodemgr_remove_host_dev(&host->device);
1815 }
1816 } else
1817 HPSB_ERR("NodeMgr: host %s does not exist, cannot remove",
1818 host->driver->name);
1819
1820 return;
1821} 1780}
1822 1781
1823static struct hpsb_highlevel nodemgr_highlevel = { 1782static struct hpsb_highlevel nodemgr_highlevel = {