]> err.no Git - linux-2.6/blobdiff - drivers/ieee1394/nodemgr.c
Merge branch 'for_paulus' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerp...
[linux-2.6] / drivers / ieee1394 / nodemgr.c
index b79ff695ca3cda0e320591ed9fe8c4e717c927e2..61307ca296ae4745c26c2242d24aae238c2361a5 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/freezer.h>
 #include <asm/atomic.h>
@@ -67,7 +68,7 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
 {
        quadlet_t q;
        u8 i, *speed, old_speed, good_speed;
-       int ret;
+       int error;
 
        speed = &(ci->host->speed[NODEID_TO_NODE(ci->nodeid)]);
        old_speed = *speed;
@@ -79,9 +80,9 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
         * just finished its initialization. */
        for (i = IEEE1394_SPEED_100; i <= old_speed; i++) {
                *speed = i;
-               ret = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
-                               &q, sizeof(quadlet_t));
-               if (ret)
+               error = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
+                                 &q, sizeof(quadlet_t));
+               if (error)
                        break;
                *buffer = q;
                good_speed = i;
@@ -95,19 +96,19 @@ static int nodemgr_check_speed(struct nodemgr_csr_info *ci, u64 addr,
                return 0;
        }
        *speed = old_speed;
-       return ret;
+       return error;
 }
 
 static int nodemgr_bus_read(struct csr1212_csr *csr, u64 addr, u16 length,
-                            void *buffer, void *__ci)
+                           void *buffer, void *__ci)
 {
        struct nodemgr_csr_info *ci = (struct nodemgr_csr_info*)__ci;
-       int i, ret;
+       int i, error;
 
        for (i = 1; ; i++) {
-               ret = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
-                               buffer, length);
-               if (!ret) {
+               error = hpsb_read(ci->host, ci->nodeid, ci->generation, addr,
+                                 buffer, length);
+               if (!error) {
                        ci->speed_unverified = 0;
                        break;
                }
@@ -118,14 +119,14 @@ static int nodemgr_bus_read(struct csr1212_csr *csr, u64 addr, u16 length,
                /* The ieee1394_core guessed the node's speed capability from
                 * the self ID.  Check whether a lower speed works. */
                if (ci->speed_unverified && length == sizeof(quadlet_t)) {
-                       ret = nodemgr_check_speed(ci, addr, buffer);
-                       if (!ret)
+                       error = nodemgr_check_speed(ci, addr, buffer);
+                       if (!error)
                                break;
                }
                if (msleep_interruptible(334))
                        return -EINTR;
        }
-       return ret;
+       return error;
 }
 
 static int nodemgr_get_max_rom(quadlet_t *bus_info_data, void *__ci)
@@ -260,9 +261,20 @@ static struct device nodemgr_dev_template_ne = {
        .release        = nodemgr_release_ne,
 };
 
+/* This dummy driver prevents the host devices from being scanned. We have no
+ * useful drivers for them yet, and there would be a deadlock possible if the
+ * driver core scans the host device while the host's low-level driver (i.e.
+ * the host's parent device) is being removed. */
+static struct device_driver nodemgr_mid_layer_driver = {
+       .bus            = &ieee1394_bus_type,
+       .name           = "nodemgr",
+       .owner          = THIS_MODULE,
+};
+
 struct device nodemgr_dev_template_host = {
        .bus            = &ieee1394_bus_type,
        .release        = nodemgr_release_host,
+       .driver         = &nodemgr_mid_layer_driver,
 };
 
 
@@ -307,8 +319,8 @@ static ssize_t fw_drv_show_##field (struct device_driver *drv, char *buf) \
        return sprintf(buf, format_string, (type)driver->field);\
 }                                                              \
 static struct driver_attribute driver_attr_drv_##field = {     \
-        .attr = {.name = __stringify(field), .mode = S_IRUGO },        \
-        .show   = fw_drv_show_##field,                         \
+       .attr = {.name = __stringify(field), .mode = S_IRUGO }, \
+       .show   = fw_drv_show_##field,                          \
 };
 
 
@@ -362,7 +374,7 @@ static ssize_t fw_show_ne_tlabels_mask(struct device *dev,
 #endif
        spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
 
-       return sprintf(buf, "0x%016llx\n", tm);
+       return sprintf(buf, "0x%016llx\n", (unsigned long long)tm);
 }
 static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL);
 #endif /* HPSB_DEBUG_TLABELS */
@@ -374,11 +386,11 @@ static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute
        int state = simple_strtoul(buf, NULL, 10);
 
        if (state == 1) {
-               down_write(&dev->bus->subsys.rwsem);
-               device_release_driver(dev);
                ud->ignore_driver = 1;
-               up_write(&dev->bus->subsys.rwsem);
-       } else if (!state)
+               down_write(&ieee1394_bus_type.subsys.rwsem);
+               device_release_driver(dev);
+               up_write(&ieee1394_bus_type.subsys.rwsem);
+       } else if (state == 0)
                ud->ignore_driver = 0;
 
        return count;
@@ -436,7 +448,7 @@ static ssize_t fw_set_ignore_drivers(struct bus_type *bus, const char *buf, size
 
        if (state == 1)
                ignore_drivers = 1;
-       else if (!state)
+       else if (state == 0)
                ignore_drivers = 0;
 
        return count;
@@ -529,7 +541,7 @@ static ssize_t fw_show_drv_device_ids(struct device_driver *drv, char *buf)
        int length = 0;
        char *scratch = buf;
 
-        driver = container_of(drv, struct hpsb_protocol_driver, driver);
+       driver = container_of(drv, struct hpsb_protocol_driver, driver);
 
        for (id = driver->id_table; id->match_flags != 0; id++) {
                int need_coma = 0;
@@ -696,8 +708,8 @@ fail:
 
 static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
 {
-        struct hpsb_protocol_driver *driver;
-        struct unit_directory *ud;
+       struct hpsb_protocol_driver *driver;
+       struct unit_directory *ud;
        struct ieee1394_device_id *id;
 
        /* We only match unit directories */
@@ -705,55 +717,77 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
                return 0;
 
        ud = container_of(dev, struct unit_directory, device);
-       driver = container_of(drv, struct hpsb_protocol_driver, driver);
-
        if (ud->ne->in_limbo || ud->ignore_driver)
                return 0;
 
-        for (id = driver->id_table; id->match_flags != 0; id++) {
-                if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
-                    id->vendor_id != ud->vendor_id)
-                        continue;
+       /* We only match drivers of type hpsb_protocol_driver */
+       if (drv == &nodemgr_mid_layer_driver)
+               return 0;
 
-                if ((id->match_flags & IEEE1394_MATCH_MODEL_ID) &&
-                    id->model_id != ud->model_id)
-                        continue;
+       driver = container_of(drv, struct hpsb_protocol_driver, driver);
+       for (id = driver->id_table; id->match_flags != 0; id++) {
+               if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
+                   id->vendor_id != ud->vendor_id)
+                       continue;
 
-                if ((id->match_flags & IEEE1394_MATCH_SPECIFIER_ID) &&
-                    id->specifier_id != ud->specifier_id)
-                        continue;
+               if ((id->match_flags & IEEE1394_MATCH_MODEL_ID) &&
+                   id->model_id != ud->model_id)
+                       continue;
 
-                if ((id->match_flags & IEEE1394_MATCH_VERSION) &&
-                    id->version != ud->version)
-                        continue;
+               if ((id->match_flags & IEEE1394_MATCH_SPECIFIER_ID) &&
+                   id->specifier_id != ud->specifier_id)
+                       continue;
+
+               if ((id->match_flags & IEEE1394_MATCH_VERSION) &&
+                   id->version != ud->version)
+                       continue;
 
                return 1;
-        }
+       }
 
        return 0;
 }
 
 
+static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
+
 static void nodemgr_remove_uds(struct node_entry *ne)
 {
-       struct class_device *cdev, *next;
-       struct unit_directory *ud;
-
-       list_for_each_entry_safe(cdev, next, &nodemgr_ud_class.children, node) {
-               ud = container_of(cdev, struct unit_directory, class_dev);
-
-               if (ud->ne != ne)
-                       continue;
-
+       struct class_device *cdev;
+       struct unit_directory *tmp, *ud;
+
+       /* Iteration over nodemgr_ud_class.children has to be protected by
+        * nodemgr_ud_class.sem, but class_device_unregister() will eventually
+        * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time,
+        * release the semaphore, and then unregister the ud. Since this code
+        * may be called from other contexts besides the knodemgrds, protect the
+        * gap after release of the semaphore by nodemgr_serialize_remove_uds.
+        */
+       mutex_lock(&nodemgr_serialize_remove_uds);
+       for (;;) {
+               ud = NULL;
+               down(&nodemgr_ud_class.sem);
+               list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
+                       tmp = container_of(cdev, struct unit_directory,
+                                          class_dev);
+                       if (tmp->ne == ne) {
+                               ud = tmp;
+                               break;
+                       }
+               }
+               up(&nodemgr_ud_class.sem);
+               if (ud == NULL)
+                       break;
                class_device_unregister(&ud->class_dev);
                device_unregister(&ud->device);
        }
+       mutex_unlock(&nodemgr_serialize_remove_uds);
 }
 
 
 static void nodemgr_remove_ne(struct node_entry *ne)
 {
-       struct device *dev = &ne->device;
+       struct device *dev;
 
        dev = get_device(&ne->device);
        if (!dev)
@@ -792,16 +826,16 @@ static void nodemgr_update_bus_options(struct node_entry *ne)
 #endif
        quadlet_t busoptions = be32_to_cpu(ne->csr->bus_info_data[2]);
 
-       ne->busopt.irmc         = (busoptions >> 31) & 1;
-       ne->busopt.cmc          = (busoptions >> 30) & 1;
-       ne->busopt.isc          = (busoptions >> 29) & 1;
-       ne->busopt.bmc          = (busoptions >> 28) & 1;
-       ne->busopt.pmc          = (busoptions >> 27) & 1;
-       ne->busopt.cyc_clk_acc  = (busoptions >> 16) & 0xff;
-       ne->busopt.max_rec      = 1 << (((busoptions >> 12) & 0xf) + 1);
+       ne->busopt.irmc         = (busoptions >> 31) & 1;
+       ne->busopt.cmc          = (busoptions >> 30) & 1;
+       ne->busopt.isc          = (busoptions >> 29) & 1;
+       ne->busopt.bmc          = (busoptions >> 28) & 1;
+       ne->busopt.pmc          = (busoptions >> 27) & 1;
+       ne->busopt.cyc_clk_acc  = (busoptions >> 16) & 0xff;
+       ne->busopt.max_rec      = 1 << (((busoptions >> 12) & 0xf) + 1);
        ne->busopt.max_rom      = (busoptions >> 8) & 0x3;
-       ne->busopt.generation   = (busoptions >> 4) & 0xf;
-       ne->busopt.lnkspd       = busoptions & 0x7;
+       ne->busopt.generation   = (busoptions >> 4) & 0xf;
+       ne->busopt.lnkspd       = busoptions & 0x7;
 
        HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
                     "cyc_clk_acc=%d max_rec=%d max_rom=%d gen=%d lspd=%d",
@@ -880,12 +914,11 @@ fail_alloc:
 
 static struct node_entry *find_entry_by_guid(u64 guid)
 {
-       struct class *class = &nodemgr_ne_class;
        struct class_device *cdev;
        struct node_entry *ne, *ret_ne = NULL;
 
-       down_read(&class->subsys.rwsem);
-       list_for_each_entry(cdev, &class->children, node) {
+       down(&nodemgr_ne_class.sem);
+       list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
                ne = container_of(cdev, struct node_entry, class_dev);
 
                if (ne->guid == guid) {
@@ -893,20 +926,20 @@ static struct node_entry *find_entry_by_guid(u64 guid)
                        break;
                }
        }
-       up_read(&class->subsys.rwsem);
+       up(&nodemgr_ne_class.sem);
 
-        return ret_ne;
+       return ret_ne;
 }
 
 
-static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t nodeid)
+static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
+                                              nodeid_t nodeid)
 {
-       struct class *class = &nodemgr_ne_class;
        struct class_device *cdev;
        struct node_entry *ne, *ret_ne = NULL;
 
-       down_read(&class->subsys.rwsem);
-       list_for_each_entry(cdev, &class->children, node) {
+       down(&nodemgr_ne_class.sem);
+       list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
                ne = container_of(cdev, struct node_entry, class_dev);
 
                if (ne->host == host && ne->nodeid == nodeid) {
@@ -914,7 +947,7 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t
                        break;
                }
        }
-       up_read(&class->subsys.rwsem);
+       up(&nodemgr_ne_class.sem);
 
        return ret_ne;
 }
@@ -1034,10 +1067,9 @@ static struct unit_directory *nodemgr_process_unit_directory
                        /* Logical Unit Number */
                        if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
                                if (ud->flags & UNIT_DIRECTORY_HAS_LUN) {
-                                       ud_child = kmalloc(sizeof(*ud_child), GFP_KERNEL);
+                                       ud_child = kmemdup(ud, sizeof(*ud_child), GFP_KERNEL);
                                        if (!ud_child)
                                                goto unit_directory_error;
-                                       memcpy(ud_child, ud, sizeof(*ud_child));
                                        nodemgr_register_device(ne, ud_child, &ne->device);
                                        ud_child = NULL;
                                        
@@ -1224,16 +1256,20 @@ static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
 #endif /* CONFIG_HOTPLUG */
 
 
-int hpsb_register_protocol(struct hpsb_protocol_driver *driver)
+int __hpsb_register_protocol(struct hpsb_protocol_driver *drv,
+                            struct module *owner)
 {
-       int ret;
+       int error;
 
-       /* This will cause a probe for devices */
-       ret = driver_register(&driver->driver);
-       if (!ret)
-               nodemgr_create_drv_files(driver);
+       drv->driver.bus = &ieee1394_bus_type;
+       drv->driver.owner = owner;
+       drv->driver.name = drv->name;
 
-       return ret;
+       /* This will cause a probe for devices */
+       error = driver_register(&drv->driver);
+       if (!error)
+               nodemgr_create_drv_files(drv);
+       return error;
 }
 
 void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
@@ -1361,26 +1397,25 @@ static void nodemgr_node_scan_one(struct host_info *hi,
 
 static void nodemgr_node_scan(struct host_info *hi, int generation)
 {
-        int count;
-        struct hpsb_host *host = hi->host;
-        struct selfid *sid = (struct selfid *)host->topology_map;
-        nodeid_t nodeid = LOCAL_BUS;
+       int count;
+       struct hpsb_host *host = hi->host;
+       struct selfid *sid = (struct selfid *)host->topology_map;
+       nodeid_t nodeid = LOCAL_BUS;
 
-        /* Scan each node on the bus */
-        for (count = host->selfid_count; count; count--, sid++) {
-                if (sid->extended)
-                        continue;
+       /* Scan each node on the bus */
+       for (count = host->selfid_count; count; count--, sid++) {
+               if (sid->extended)
+                       continue;
 
-                if (!sid->link_active) {
-                        nodeid++;
-                        continue;
-                }
-                nodemgr_node_scan_one(hi, nodeid++, generation);
-        }
+               if (!sid->link_active) {
+                       nodeid++;
+                       continue;
+               }
+               nodemgr_node_scan_one(hi, nodeid++, generation);
+       }
 }
 
 
-/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader. */
 static void nodemgr_suspend_ne(struct node_entry *ne)
 {
        struct class_device *cdev;
@@ -1392,19 +1427,20 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
        ne->in_limbo = 1;
        WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
 
-       down_write(&ne->device.bus->subsys.rwsem);
+       down(&nodemgr_ud_class.sem);
        list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
                ud = container_of(cdev, struct unit_directory, class_dev);
-
                if (ud->ne != ne)
                        continue;
 
+               down_write(&ieee1394_bus_type.subsys.rwsem);
                if (ud->device.driver &&
                    (!ud->device.driver->suspend ||
                      ud->device.driver->suspend(&ud->device, PMSG_SUSPEND)))
                        device_release_driver(&ud->device);
+               up_write(&ieee1394_bus_type.subsys.rwsem);
        }
-       up_write(&ne->device.bus->subsys.rwsem);
+       up(&nodemgr_ud_class.sem);
 }
 
 
@@ -1416,45 +1452,47 @@ static void nodemgr_resume_ne(struct node_entry *ne)
        ne->in_limbo = 0;
        device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
 
-       down_read(&nodemgr_ud_class.subsys.rwsem);
-       down_read(&ne->device.bus->subsys.rwsem);
+       down(&nodemgr_ud_class.sem);
        list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
                ud = container_of(cdev, struct unit_directory, class_dev);
-
                if (ud->ne != ne)
                        continue;
 
+               down_read(&ieee1394_bus_type.subsys.rwsem);
                if (ud->device.driver && ud->device.driver->resume)
                        ud->device.driver->resume(&ud->device);
+               up_read(&ieee1394_bus_type.subsys.rwsem);
        }
-       up_read(&ne->device.bus->subsys.rwsem);
-       up_read(&nodemgr_ud_class.subsys.rwsem);
+       up(&nodemgr_ud_class.sem);
 
        HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
                   NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
 }
 
 
-/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader. */
 static void nodemgr_update_pdrv(struct node_entry *ne)
 {
        struct unit_directory *ud;
        struct hpsb_protocol_driver *pdrv;
        struct class_device *cdev;
 
+       down(&nodemgr_ud_class.sem);
        list_for_each_entry(cdev, &nodemgr_ud_class.children, node) {
                ud = container_of(cdev, struct unit_directory, class_dev);
-               if (ud->ne != ne || !ud->device.driver)
+               if (ud->ne != ne)
                        continue;
 
-               pdrv = container_of(ud->device.driver, struct hpsb_protocol_driver, driver);
-
-               if (pdrv->update && pdrv->update(ud)) {
-                       down_write(&ud->device.bus->subsys.rwsem);
-                       device_release_driver(&ud->device);
-                       up_write(&ud->device.bus->subsys.rwsem);
+               down_write(&ieee1394_bus_type.subsys.rwsem);
+               if (ud->device.driver) {
+                       pdrv = container_of(ud->device.driver,
+                                           struct hpsb_protocol_driver,
+                                           driver);
+                       if (pdrv->update && pdrv->update(ud))
+                               device_release_driver(&ud->device);
                }
+               up_write(&ieee1394_bus_type.subsys.rwsem);
        }
+       up(&nodemgr_ud_class.sem);
 }
 
 
@@ -1468,7 +1506,7 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
 {
        const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL);
        quadlet_t bc_remote, bc_local;
-       int ret;
+       int error;
 
        if (!ne->host->is_irm || ne->generation != generation ||
            ne->nodeid == ne->host->node_id)
@@ -1477,16 +1515,14 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
        bc_local = cpu_to_be32(ne->host->csr.broadcast_channel);
 
        /* Check if the register is implemented and 1394a compliant. */
-       ret = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
-                       sizeof(bc_remote));
-       if (!ret && bc_remote & cpu_to_be32(0x80000000) &&
+       error = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
+                         sizeof(bc_remote));
+       if (!error && bc_remote & cpu_to_be32(0x80000000) &&
            bc_remote != bc_local)
                hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local));
 }
 
 
-/* Caller needs to hold nodemgr_ud_class.subsys.rwsem as reader because the
- * calls to nodemgr_update_pdrv() and nodemgr_suspend_ne() here require it. */
 static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
 {
        struct device *dev;
@@ -1519,7 +1555,6 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
 static void nodemgr_node_probe(struct host_info *hi, int generation)
 {
        struct hpsb_host *host = hi->host;
-       struct class *class = &nodemgr_ne_class;
        struct class_device *cdev;
        struct node_entry *ne;
 
@@ -1532,18 +1567,18 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
         * while probes are time-consuming. (Well, those probes need some
         * improvement...) */
 
-       down_read(&class->subsys.rwsem);
-       list_for_each_entry(cdev, &class->children, node) {
+       down(&nodemgr_ne_class.sem);
+       list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
                ne = container_of(cdev, struct node_entry, class_dev);
                if (!ne->needs_probe)
                        nodemgr_probe_ne(hi, ne, generation);
        }
-       list_for_each_entry(cdev, &class->children, node) {
+       list_for_each_entry(cdev, &nodemgr_ne_class.children, node) {
                ne = container_of(cdev, struct node_entry, class_dev);
                if (ne->needs_probe)
                        nodemgr_probe_ne(hi, ne, generation);
        }
-        up_read(&class->subsys.rwsem);
+       up(&nodemgr_ne_class.sem);
 
 
        /* If we had a bus reset while we were scanning the bus, it is
@@ -1561,15 +1596,14 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
         * just removed.  */
 
        if (generation == get_hpsb_generation(host))
-               WARN_ON(bus_rescan_devices(&ieee1394_bus_type));
-
-       return;
+               if (bus_rescan_devices(&ieee1394_bus_type))
+                       HPSB_DEBUG("bus_rescan_devices had an error");
 }
 
 static int nodemgr_send_resume_packet(struct hpsb_host *host)
 {
        struct hpsb_packet *packet;
-       int ret = 1;
+       int error = -ENOMEM;
 
        packet = hpsb_make_phypacket(host,
                        EXTPHYPACKET_TYPE_RESUME |
@@ -1577,12 +1611,12 @@ static int nodemgr_send_resume_packet(struct hpsb_host *host)
        if (packet) {
                packet->no_waiter = 1;
                packet->generation = get_hpsb_generation(host);
-               ret = hpsb_send_packet(packet);
+               error = hpsb_send_packet(packet);
        }
-       if (ret)
+       if (error)
                HPSB_WARN("fw-host%d: Failed to broadcast resume packet",
                          host->id);
-       return ret;
+       return error;
 }
 
 /* Perform a few high-level IRM responsibilities. */
@@ -1755,19 +1789,18 @@ exit:
 
 int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
 {
-       struct class *class = &hpsb_host_class;
        struct class_device *cdev;
        struct hpsb_host *host;
        int error = 0;
 
-       down_read(&class->subsys.rwsem);
-       list_for_each_entry(cdev, &class->children, node) {
+       down(&hpsb_host_class.sem);
+       list_for_each_entry(cdev, &hpsb_host_class.children, node) {
                host = container_of(cdev, struct hpsb_host, class_dev);
 
                if ((error = cb(host, __data)))
                        break;
        }
-       up_read(&class->subsys.rwsem);
+       up(&hpsb_host_class.sem);
 
        return error;
 }
@@ -1789,10 +1822,10 @@ int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
 
 void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *pkt)
 {
-        pkt->host = ne->host;
-        pkt->generation = ne->generation;
+       pkt->host = ne->host;
+       pkt->generation = ne->generation;
        barrier();
-        pkt->node_id = ne->nodeid;
+       pkt->node_id = ne->nodeid;
 }
 
 int hpsb_node_write(struct node_entry *ne, u64 addr,
@@ -1852,26 +1885,25 @@ static struct hpsb_highlevel nodemgr_highlevel = {
 
 int init_ieee1394_nodemgr(void)
 {
-       int ret;
+       int error;
 
-       ret = class_register(&nodemgr_ne_class);
-       if (ret < 0)
-               return ret;
+       error = class_register(&nodemgr_ne_class);
+       if (error)
+               return error;
 
-       ret = class_register(&nodemgr_ud_class);
-       if (ret < 0) {
+       error = class_register(&nodemgr_ud_class);
+       if (error) {
                class_unregister(&nodemgr_ne_class);
-               return ret;
+               return error;
        }
-
+       error = driver_register(&nodemgr_mid_layer_driver);
        hpsb_register_highlevel(&nodemgr_highlevel);
-
        return 0;
 }
 
 void cleanup_ieee1394_nodemgr(void)
 {
-        hpsb_unregister_highlevel(&nodemgr_highlevel);
+       hpsb_unregister_highlevel(&nodemgr_highlevel);
 
        class_unregister(&nodemgr_ud_class);
        class_unregister(&nodemgr_ne_class);