|
@@ -154,9 +154,6 @@ struct host_info {
|
|
|
|
|
|
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
|
|
|
static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env);
|
|
|
-static void nodemgr_resume_ne(struct node_entry *ne);
|
|
|
-static void nodemgr_remove_ne(struct node_entry *ne);
|
|
|
-static struct node_entry *find_entry_by_guid(u64 guid);
|
|
|
|
|
|
struct bus_type ieee1394_bus_type = {
|
|
|
.name = "ieee1394",
|
|
@@ -385,27 +382,6 @@ static ssize_t fw_get_ignore_driver(struct device *dev, struct device_attribute
|
|
|
static DEVICE_ATTR(ignore_driver, S_IWUSR | S_IRUGO, fw_get_ignore_driver, fw_set_ignore_driver);
|
|
|
|
|
|
|
|
|
-static ssize_t fw_set_destroy_node(struct bus_type *bus, const char *buf, size_t count)
|
|
|
-{
|
|
|
- struct node_entry *ne;
|
|
|
- u64 guid = (u64)simple_strtoull(buf, NULL, 16);
|
|
|
-
|
|
|
- ne = find_entry_by_guid(guid);
|
|
|
-
|
|
|
- if (ne == NULL || !ne->in_limbo)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- nodemgr_remove_ne(ne);
|
|
|
-
|
|
|
- return count;
|
|
|
-}
|
|
|
-static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf)
|
|
|
-{
|
|
|
- return sprintf(buf, "You can destroy in_limbo nodes by writing their GUID to this file\n");
|
|
|
-}
|
|
|
-static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node);
|
|
|
-
|
|
|
-
|
|
|
static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf,
|
|
|
size_t count)
|
|
|
{
|
|
@@ -442,7 +418,6 @@ static BUS_ATTR(ignore_drivers, S_IWUSR | S_IRUGO, fw_get_ignore_drivers, fw_set
|
|
|
|
|
|
|
|
|
struct bus_attribute *const fw_bus_attrs[] = {
|
|
|
- &bus_attr_destroy_node,
|
|
|
&bus_attr_rescan,
|
|
|
&bus_attr_ignore_drivers,
|
|
|
NULL
|
|
@@ -734,10 +709,10 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
|
|
|
|
|
|
static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
|
|
|
|
|
|
-static int __match_ne(struct device *dev, void *data)
|
|
|
+static int match_ne(struct device *dev, void *data)
|
|
|
{
|
|
|
struct unit_directory *ud;
|
|
|
- struct node_entry *ne = (struct node_entry *)data;
|
|
|
+ struct node_entry *ne = data;
|
|
|
|
|
|
ud = container_of(dev, struct unit_directory, unit_dev);
|
|
|
return ud->ne == ne;
|
|
@@ -754,8 +729,7 @@ static void nodemgr_remove_uds(struct node_entry *ne)
|
|
|
*/
|
|
|
mutex_lock(&nodemgr_serialize_remove_uds);
|
|
|
for (;;) {
|
|
|
- dev = class_find_device(&nodemgr_ud_class, NULL, ne,
|
|
|
- __match_ne);
|
|
|
+ dev = class_find_device(&nodemgr_ud_class, NULL, ne, match_ne);
|
|
|
if (!dev)
|
|
|
break;
|
|
|
ud = container_of(dev, struct unit_directory, unit_dev);
|
|
@@ -785,7 +759,7 @@ static void nodemgr_remove_ne(struct node_entry *ne)
|
|
|
put_device(dev);
|
|
|
}
|
|
|
|
|
|
-static int __nodemgr_remove_host_dev(struct device *dev, void *data)
|
|
|
+static int remove_host_dev(struct device *dev, void *data)
|
|
|
{
|
|
|
if (dev->bus == &ieee1394_bus_type)
|
|
|
nodemgr_remove_ne(container_of(dev, struct node_entry,
|
|
@@ -795,7 +769,7 @@ static int __nodemgr_remove_host_dev(struct device *dev, void *data)
|
|
|
|
|
|
static void nodemgr_remove_host_dev(struct device *dev)
|
|
|
{
|
|
|
- WARN_ON(device_for_each_child(dev, NULL, __nodemgr_remove_host_dev));
|
|
|
+ device_for_each_child(dev, NULL, remove_host_dev);
|
|
|
sysfs_remove_link(&dev->kobj, "irm_id");
|
|
|
sysfs_remove_link(&dev->kobj, "busmgr_id");
|
|
|
sysfs_remove_link(&dev->kobj, "host_id");
|
|
@@ -830,11 +804,10 @@ static void nodemgr_update_bus_options(struct node_entry *ne)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr *csr,
|
|
|
- struct host_info *hi, nodeid_t nodeid,
|
|
|
- unsigned int generation)
|
|
|
+static struct node_entry *nodemgr_create_node(octlet_t guid,
|
|
|
+ struct csr1212_csr *csr, struct hpsb_host *host,
|
|
|
+ nodeid_t nodeid, unsigned int generation)
|
|
|
{
|
|
|
- struct hpsb_host *host = hi->host;
|
|
|
struct node_entry *ne;
|
|
|
|
|
|
ne = kzalloc(sizeof(*ne), GFP_KERNEL);
|
|
@@ -888,10 +861,10 @@ fail_alloc:
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-static int __match_ne_guid(struct device *dev, void *data)
|
|
|
+static int match_ne_guid(struct device *dev, void *data)
|
|
|
{
|
|
|
struct node_entry *ne;
|
|
|
- u64 *guid = (u64 *)data;
|
|
|
+ u64 *guid = data;
|
|
|
|
|
|
ne = container_of(dev, struct node_entry, node_dev);
|
|
|
return ne->guid == *guid;
|
|
@@ -902,8 +875,7 @@ static struct node_entry *find_entry_by_guid(u64 guid)
|
|
|
struct device *dev;
|
|
|
struct node_entry *ne;
|
|
|
|
|
|
- dev = class_find_device(&nodemgr_ne_class, NULL, &guid,
|
|
|
- __match_ne_guid);
|
|
|
+ dev = class_find_device(&nodemgr_ne_class, NULL, &guid, match_ne_guid);
|
|
|
if (!dev)
|
|
|
return NULL;
|
|
|
ne = container_of(dev, struct node_entry, node_dev);
|
|
@@ -912,21 +884,21 @@ static struct node_entry *find_entry_by_guid(u64 guid)
|
|
|
return ne;
|
|
|
}
|
|
|
|
|
|
-struct match_nodeid_param {
|
|
|
+struct match_nodeid_parameter {
|
|
|
struct hpsb_host *host;
|
|
|
nodeid_t nodeid;
|
|
|
};
|
|
|
|
|
|
-static int __match_ne_nodeid(struct device *dev, void *data)
|
|
|
+static int match_ne_nodeid(struct device *dev, void *data)
|
|
|
{
|
|
|
int found = 0;
|
|
|
struct node_entry *ne;
|
|
|
- struct match_nodeid_param *param = (struct match_nodeid_param *)data;
|
|
|
+ struct match_nodeid_parameter *p = data;
|
|
|
|
|
|
if (!dev)
|
|
|
goto ret;
|
|
|
ne = container_of(dev, struct node_entry, node_dev);
|
|
|
- if (ne->host == param->host && ne->nodeid == param->nodeid)
|
|
|
+ if (ne->host == p->host && ne->nodeid == p->nodeid)
|
|
|
found = 1;
|
|
|
ret:
|
|
|
return found;
|
|
@@ -937,13 +909,12 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
|
|
|
{
|
|
|
struct device *dev;
|
|
|
struct node_entry *ne;
|
|
|
- struct match_nodeid_param param;
|
|
|
+ struct match_nodeid_parameter p;
|
|
|
|
|
|
- param.host = host;
|
|
|
- param.nodeid = nodeid;
|
|
|
+ p.host = host;
|
|
|
+ p.nodeid = nodeid;
|
|
|
|
|
|
- dev = class_find_device(&nodemgr_ne_class, NULL, ¶m,
|
|
|
- __match_ne_nodeid);
|
|
|
+ dev = class_find_device(&nodemgr_ne_class, NULL, &p, match_ne_nodeid);
|
|
|
if (!dev)
|
|
|
return NULL;
|
|
|
ne = container_of(dev, struct node_entry, node_dev);
|
|
@@ -990,7 +961,7 @@ fail_devreg:
|
|
|
* immediate unit directories looking for software_id and
|
|
|
* software_version entries, in order to get driver autoloading working. */
|
|
|
static struct unit_directory *nodemgr_process_unit_directory
|
|
|
- (struct host_info *hi, struct node_entry *ne, struct csr1212_keyval *ud_kv,
|
|
|
+ (struct node_entry *ne, struct csr1212_keyval *ud_kv,
|
|
|
unsigned int *id, struct unit_directory *parent)
|
|
|
{
|
|
|
struct unit_directory *ud;
|
|
@@ -1083,7 +1054,7 @@ static struct unit_directory *nodemgr_process_unit_directory
|
|
|
nodemgr_register_device(ne, ud, &ne->device);
|
|
|
|
|
|
/* process the child unit */
|
|
|
- ud_child = nodemgr_process_unit_directory(hi, ne, kv, id, ud);
|
|
|
+ ud_child = nodemgr_process_unit_directory(ne, kv, id, ud);
|
|
|
|
|
|
if (ud_child == NULL)
|
|
|
break;
|
|
@@ -1137,7 +1108,7 @@ unit_directory_error:
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void nodemgr_process_root_directory(struct host_info *hi, struct node_entry *ne)
|
|
|
+static void nodemgr_process_root_directory(struct node_entry *ne)
|
|
|
{
|
|
|
unsigned int ud_id = 0;
|
|
|
struct csr1212_dentry *dentry;
|
|
@@ -1157,7 +1128,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
|
|
|
break;
|
|
|
|
|
|
case CSR1212_KV_ID_UNIT:
|
|
|
- nodemgr_process_unit_directory(hi, ne, kv, &ud_id, NULL);
|
|
|
+ nodemgr_process_unit_directory(ne, kv, &ud_id, NULL);
|
|
|
break;
|
|
|
|
|
|
case CSR1212_KV_ID_DESCRIPTOR:
|
|
@@ -1273,8 +1244,7 @@ void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
|
|
|
* the to take whatever actions required.
|
|
|
*/
|
|
|
static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
|
|
|
- struct host_info *hi, nodeid_t nodeid,
|
|
|
- unsigned int generation)
|
|
|
+ nodeid_t nodeid, unsigned int generation)
|
|
|
{
|
|
|
if (ne->nodeid != nodeid) {
|
|
|
HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT,
|
|
@@ -1305,19 +1275,23 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
|
|
|
csr1212_destroy_csr(csr);
|
|
|
}
|
|
|
|
|
|
- if (ne->in_limbo)
|
|
|
- nodemgr_resume_ne(ne);
|
|
|
-
|
|
|
/* Mark the node current */
|
|
|
ne->generation = generation;
|
|
|
-}
|
|
|
|
|
|
+ if (ne->in_limbo) {
|
|
|
+ device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
|
|
|
+ ne->in_limbo = false;
|
|
|
|
|
|
+ HPSB_DEBUG("Node reactivated: "
|
|
|
+ "ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
|
|
|
+ NODE_BUS_ARGS(ne->host, ne->nodeid),
|
|
|
+ (unsigned long long)ne->guid);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
-static void nodemgr_node_scan_one(struct host_info *hi,
|
|
|
+static void nodemgr_node_scan_one(struct hpsb_host *host,
|
|
|
nodeid_t nodeid, int generation)
|
|
|
{
|
|
|
- struct hpsb_host *host = hi->host;
|
|
|
struct node_entry *ne;
|
|
|
octlet_t guid;
|
|
|
struct csr1212_csr *csr;
|
|
@@ -1373,16 +1347,15 @@ static void nodemgr_node_scan_one(struct host_info *hi,
|
|
|
}
|
|
|
|
|
|
if (!ne)
|
|
|
- nodemgr_create_node(guid, csr, hi, nodeid, generation);
|
|
|
+ nodemgr_create_node(guid, csr, host, nodeid, generation);
|
|
|
else
|
|
|
- nodemgr_update_node(ne, csr, hi, nodeid, generation);
|
|
|
+ nodemgr_update_node(ne, csr, nodeid, generation);
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void nodemgr_node_scan(struct host_info *hi, int generation)
|
|
|
+static void nodemgr_node_scan(struct hpsb_host *host, int generation)
|
|
|
{
|
|
|
int count;
|
|
|
- struct hpsb_host *host = hi->host;
|
|
|
struct selfid *sid = (struct selfid *)host->topology_map;
|
|
|
nodeid_t nodeid = LOCAL_BUS;
|
|
|
|
|
@@ -1395,89 +1368,26 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
|
|
|
nodeid++;
|
|
|
continue;
|
|
|
}
|
|
|
- nodemgr_node_scan_one(hi, nodeid++, generation);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static int __nodemgr_driver_suspend(struct device *dev, void *data)
|
|
|
-{
|
|
|
- struct unit_directory *ud;
|
|
|
- struct device_driver *drv;
|
|
|
- struct node_entry *ne = (struct node_entry *)data;
|
|
|
- int error;
|
|
|
-
|
|
|
- ud = container_of(dev, struct unit_directory, unit_dev);
|
|
|
- if (ud->ne == ne) {
|
|
|
- drv = get_driver(ud->device.driver);
|
|
|
- if (drv) {
|
|
|
- error = 1; /* release if suspend is not implemented */
|
|
|
- if (drv->suspend) {
|
|
|
- down(&ud->device.sem);
|
|
|
- error = drv->suspend(&ud->device, PMSG_SUSPEND);
|
|
|
- up(&ud->device.sem);
|
|
|
- }
|
|
|
- if (error)
|
|
|
- device_release_driver(&ud->device);
|
|
|
- put_driver(drv);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int __nodemgr_driver_resume(struct device *dev, void *data)
|
|
|
-{
|
|
|
- struct unit_directory *ud;
|
|
|
- struct device_driver *drv;
|
|
|
- struct node_entry *ne = (struct node_entry *)data;
|
|
|
-
|
|
|
- ud = container_of(dev, struct unit_directory, unit_dev);
|
|
|
- if (ud->ne == ne) {
|
|
|
- drv = get_driver(ud->device.driver);
|
|
|
- if (drv) {
|
|
|
- if (drv->resume) {
|
|
|
- down(&ud->device.sem);
|
|
|
- drv->resume(&ud->device);
|
|
|
- up(&ud->device.sem);
|
|
|
- }
|
|
|
- put_driver(drv);
|
|
|
- }
|
|
|
+ nodemgr_node_scan_one(host, nodeid++, generation);
|
|
|
}
|
|
|
-
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
-static void nodemgr_suspend_ne(struct node_entry *ne)
|
|
|
+static void nodemgr_pause_ne(struct node_entry *ne)
|
|
|
{
|
|
|
- HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
|
|
|
+ HPSB_DEBUG("Node paused: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
|
|
|
NODE_BUS_ARGS(ne->host, ne->nodeid),
|
|
|
(unsigned long long)ne->guid);
|
|
|
|
|
|
- ne->in_limbo = 1;
|
|
|
+ ne->in_limbo = true;
|
|
|
WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
|
|
|
-
|
|
|
- class_for_each_device(&nodemgr_ud_class, NULL, ne,
|
|
|
- __nodemgr_driver_suspend);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void nodemgr_resume_ne(struct node_entry *ne)
|
|
|
-{
|
|
|
- ne->in_limbo = 0;
|
|
|
- device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
|
|
|
-
|
|
|
- class_for_each_device(&nodemgr_ud_class, NULL, ne,
|
|
|
- __nodemgr_driver_resume);
|
|
|
- HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
|
|
|
- NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
|
|
|
}
|
|
|
|
|
|
-static int __nodemgr_update_pdrv(struct device *dev, void *data)
|
|
|
+static int update_pdrv(struct device *dev, void *data)
|
|
|
{
|
|
|
struct unit_directory *ud;
|
|
|
struct device_driver *drv;
|
|
|
struct hpsb_protocol_driver *pdrv;
|
|
|
- struct node_entry *ne = (struct node_entry *)data;
|
|
|
+ struct node_entry *ne = data;
|
|
|
int error;
|
|
|
|
|
|
ud = container_of(dev, struct unit_directory, unit_dev);
|
|
@@ -1503,11 +1413,9 @@ static int __nodemgr_update_pdrv(struct device *dev, void *data)
|
|
|
|
|
|
static void nodemgr_update_pdrv(struct node_entry *ne)
|
|
|
{
|
|
|
- class_for_each_device(&nodemgr_ud_class, NULL, ne,
|
|
|
- __nodemgr_update_pdrv);
|
|
|
+ class_for_each_device(&nodemgr_ud_class, NULL, ne, update_pdrv);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This
|
|
|
* seems like an optional service but in the end it is practically mandatory
|
|
|
* as a consequence of these clauses.
|
|
@@ -1535,11 +1443,12 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
|
|
|
+static void nodemgr_probe_ne(struct hpsb_host *host, struct node_entry *ne,
|
|
|
+ int generation)
|
|
|
{
|
|
|
struct device *dev;
|
|
|
|
|
|
- if (ne->host != hi->host || ne->in_limbo)
|
|
|
+ if (ne->host != host || ne->in_limbo)
|
|
|
return;
|
|
|
|
|
|
dev = get_device(&ne->device);
|
|
@@ -1554,40 +1463,40 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
|
|
|
* down to the drivers. Otherwise, this is a dead node and we
|
|
|
* suspend it. */
|
|
|
if (ne->needs_probe)
|
|
|
- nodemgr_process_root_directory(hi, ne);
|
|
|
+ nodemgr_process_root_directory(ne);
|
|
|
else if (ne->generation == generation)
|
|
|
nodemgr_update_pdrv(ne);
|
|
|
else
|
|
|
- nodemgr_suspend_ne(ne);
|
|
|
+ nodemgr_pause_ne(ne);
|
|
|
|
|
|
put_device(dev);
|
|
|
}
|
|
|
|
|
|
-struct probe_param {
|
|
|
- struct host_info *hi;
|
|
|
+struct node_probe_parameter {
|
|
|
+ struct hpsb_host *host;
|
|
|
int generation;
|
|
|
bool probe_now;
|
|
|
};
|
|
|
|
|
|
static int node_probe(struct device *dev, void *data)
|
|
|
{
|
|
|
- struct probe_param *p = data;
|
|
|
+ struct node_probe_parameter *p = data;
|
|
|
struct node_entry *ne;
|
|
|
|
|
|
- if (p->generation != get_hpsb_generation(p->hi->host))
|
|
|
+ if (p->generation != get_hpsb_generation(p->host))
|
|
|
return -EAGAIN;
|
|
|
|
|
|
ne = container_of(dev, struct node_entry, node_dev);
|
|
|
if (ne->needs_probe == p->probe_now)
|
|
|
- nodemgr_probe_ne(p->hi, ne, p->generation);
|
|
|
+ nodemgr_probe_ne(p->host, ne, p->generation);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void nodemgr_node_probe(struct host_info *hi, int generation)
|
|
|
+static int nodemgr_node_probe(struct hpsb_host *host, int generation)
|
|
|
{
|
|
|
- struct probe_param p;
|
|
|
+ struct node_probe_parameter p;
|
|
|
|
|
|
- p.hi = hi;
|
|
|
+ p.host = host;
|
|
|
p.generation = generation;
|
|
|
/*
|
|
|
* Do some processing of the nodes we've probed. This pulls them
|
|
@@ -1604,11 +1513,11 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
|
|
|
*/
|
|
|
p.probe_now = false;
|
|
|
if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
|
|
|
- return;
|
|
|
+ return 0;
|
|
|
|
|
|
p.probe_now = true;
|
|
|
if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
|
|
|
- return;
|
|
|
+ return 0;
|
|
|
/*
|
|
|
* Now let's tell the bus to rescan our devices. This may seem
|
|
|
* like overhead, but the driver-model core will only scan a
|
|
@@ -1620,6 +1529,27 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
|
|
|
*/
|
|
|
if (bus_rescan_devices(&ieee1394_bus_type) != 0)
|
|
|
HPSB_DEBUG("bus_rescan_devices had an error");
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+static int remove_nodes_in_limbo(struct device *dev, void *data)
|
|
|
+{
|
|
|
+ struct node_entry *ne;
|
|
|
+
|
|
|
+ if (dev->bus != &ieee1394_bus_type)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ ne = container_of(dev, struct node_entry, device);
|
|
|
+ if (ne->in_limbo)
|
|
|
+ nodemgr_remove_ne(ne);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void nodemgr_remove_nodes_in_limbo(struct hpsb_host *host)
|
|
|
+{
|
|
|
+ device_for_each_child(&host->device, NULL, remove_nodes_in_limbo);
|
|
|
}
|
|
|
|
|
|
static int nodemgr_send_resume_packet(struct hpsb_host *host)
|
|
@@ -1730,10 +1660,9 @@ static int nodemgr_check_irm_capability(struct hpsb_host *host, int cycles)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-static int nodemgr_host_thread(void *__hi)
|
|
|
+static int nodemgr_host_thread(void *data)
|
|
|
{
|
|
|
- struct host_info *hi = (struct host_info *)__hi;
|
|
|
- struct hpsb_host *host = hi->host;
|
|
|
+ struct hpsb_host *host = data;
|
|
|
unsigned int g, generation = 0;
|
|
|
int i, reset_cycles = 0;
|
|
|
|
|
@@ -1787,36 +1716,48 @@ static int nodemgr_host_thread(void *__hi)
|
|
|
* entries. This does not do the sysfs stuff, since that
|
|
|
* would trigger uevents and such, which is a bad idea at
|
|
|
* this point. */
|
|
|
- nodemgr_node_scan(hi, generation);
|
|
|
+ nodemgr_node_scan(host, generation);
|
|
|
|
|
|
/* This actually does the full probe, with sysfs
|
|
|
* registration. */
|
|
|
- nodemgr_node_probe(hi, generation);
|
|
|
+ if (!nodemgr_node_probe(host, generation))
|
|
|
+ continue;
|
|
|
|
|
|
/* Update some of our sysfs symlinks */
|
|
|
nodemgr_update_host_dev_links(host);
|
|
|
+
|
|
|
+ /* Sleep 3 seconds */
|
|
|
+ for (i = 3000/200; i; i--) {
|
|
|
+ msleep_interruptible(200);
|
|
|
+ if (kthread_should_stop())
|
|
|
+ goto exit;
|
|
|
+
|
|
|
+ if (generation != get_hpsb_generation(host))
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ /* Remove nodes which are gone, unless a bus reset happened */
|
|
|
+ if (!i)
|
|
|
+ nodemgr_remove_nodes_in_limbo(host);
|
|
|
}
|
|
|
exit:
|
|
|
HPSB_VERBOSE("NodeMgr: Exiting thread");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-struct host_iter_param {
|
|
|
+struct per_host_parameter {
|
|
|
void *data;
|
|
|
int (*cb)(struct hpsb_host *, void *);
|
|
|
};
|
|
|
|
|
|
-static int __nodemgr_for_each_host(struct device *dev, void *data)
|
|
|
+static int per_host(struct device *dev, void *data)
|
|
|
{
|
|
|
struct hpsb_host *host;
|
|
|
- struct host_iter_param *hip = (struct host_iter_param *)data;
|
|
|
- int error = 0;
|
|
|
+ struct per_host_parameter *p = data;
|
|
|
|
|
|
host = container_of(dev, struct hpsb_host, host_dev);
|
|
|
- error = hip->cb(host, hip->data);
|
|
|
-
|
|
|
- return error;
|
|
|
+ return p->cb(host, p->data);
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
* nodemgr_for_each_host - call a function for each IEEE 1394 host
|
|
|
* @data: an address to supply to the callback
|
|
@@ -1831,15 +1772,11 @@ static int __nodemgr_for_each_host(struct device *dev, void *data)
|
|
|
*/
|
|
|
int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
|
|
|
{
|
|
|
- struct host_iter_param hip;
|
|
|
- int error;
|
|
|
-
|
|
|
- hip.cb = cb;
|
|
|
- hip.data = data;
|
|
|
- error = class_for_each_device(&hpsb_host_class, NULL, &hip,
|
|
|
- __nodemgr_for_each_host);
|
|
|
+ struct per_host_parameter p;
|
|
|
|
|
|
- return error;
|
|
|
+ p.cb = cb;
|
|
|
+ p.data = data;
|
|
|
+ return class_for_each_device(&hpsb_host_class, NULL, &p, per_host);
|
|
|
}
|
|
|
|
|
|
/* The following two convenience functions use a struct node_entry
|
|
@@ -1893,7 +1830,7 @@ static void nodemgr_add_host(struct hpsb_host *host)
|
|
|
return;
|
|
|
}
|
|
|
hi->host = host;
|
|
|
- hi->thread = kthread_run(nodemgr_host_thread, hi, "knodemgrd_%d",
|
|
|
+ hi->thread = kthread_run(nodemgr_host_thread, host, "knodemgrd_%d",
|
|
|
host->id);
|
|
|
if (IS_ERR(hi->thread)) {
|
|
|
HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id);
|