Commit 73cf6023 authored by Dave Young's avatar Dave Young Committed by Greg Kroah-Hartman

ieee1394: use class iteration api

Convert to use the class iteration api.
Signed-off-by: default avatarDave Young <hidave.darkstar@gmail.com>
Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent fd04897b
...@@ -727,33 +727,31 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv) ...@@ -727,33 +727,31 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
static DEFINE_MUTEX(nodemgr_serialize_remove_uds); static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
static int __match_ne(struct device *dev, void *data)
{
struct unit_directory *ud;
struct node_entry *ne = (struct node_entry *)data;
ud = container_of(dev, struct unit_directory, unit_dev);
return ud->ne == ne;
}
static void nodemgr_remove_uds(struct node_entry *ne) static void nodemgr_remove_uds(struct node_entry *ne)
{ {
struct device *dev; struct device *dev;
struct unit_directory *tmp, *ud; struct unit_directory *ud;
/* Iteration over nodemgr_ud_class.devices has to be protected by /* Use class_find device to iterate the devices. Since this code
* nodemgr_ud_class.sem, but device_unregister() will eventually * may be called from other contexts besides the knodemgrds,
* take nodemgr_ud_class.sem too. Therefore pick out one ud at a time, * protect it by nodemgr_serialize_remove_uds.
* 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); mutex_lock(&nodemgr_serialize_remove_uds);
for (;;) { for (;;) {
ud = NULL; dev = class_find_device(&nodemgr_ud_class, ne, __match_ne);
down(&nodemgr_ud_class.sem); if (!dev)
list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
tmp = container_of(dev, struct unit_directory,
unit_dev);
if (tmp->ne == ne) {
ud = tmp;
break;
}
}
up(&nodemgr_ud_class.sem);
if (ud == NULL)
break; break;
ud = container_of(dev, struct unit_directory, unit_dev);
put_device(dev);
device_unregister(&ud->unit_dev); device_unregister(&ud->unit_dev);
device_unregister(&ud->device); device_unregister(&ud->device);
} }
...@@ -882,45 +880,66 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr ...@@ -882,45 +880,66 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
return NULL; return NULL;
} }
static int __match_ne_guid(struct device *dev, void *data)
{
struct node_entry *ne;
u64 *guid = (u64 *)data;
ne = container_of(dev, struct node_entry, node_dev);
return ne->guid == *guid;
}
static struct node_entry *find_entry_by_guid(u64 guid) static struct node_entry *find_entry_by_guid(u64 guid)
{ {
struct device *dev; struct device *dev;
struct node_entry *ne, *ret_ne = NULL; struct node_entry *ne;
down(&nodemgr_ne_class.sem); dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid);
list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { if (!dev)
return NULL;
ne = container_of(dev, struct node_entry, node_dev); ne = container_of(dev, struct node_entry, node_dev);
put_device(dev);
if (ne->guid == guid) { return ne;
ret_ne = ne;
break;
}
}
up(&nodemgr_ne_class.sem);
return ret_ne;
} }
struct match_nodeid_param {
struct hpsb_host *host;
nodeid_t nodeid;
};
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;
if (!dev)
goto ret;
ne = container_of(dev, struct node_entry, node_dev);
if (ne->host == param->host && ne->nodeid == param->nodeid)
found = 1;
ret:
return found;
}
static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
nodeid_t nodeid) nodeid_t nodeid)
{ {
struct device *dev; struct device *dev;
struct node_entry *ne, *ret_ne = NULL; struct node_entry *ne;
struct match_nodeid_param param;
down(&nodemgr_ne_class.sem); param.host = host;
list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { param.nodeid = nodeid;
ne = container_of(dev, struct node_entry, node_dev);
if (ne->host == host && ne->nodeid == nodeid) { dev = class_find_device(&nodemgr_ne_class, &param, __match_ne_nodeid);
ret_ne = ne; if (!dev)
break; return NULL;
} ne = container_of(dev, struct node_entry, node_dev);
} put_device(dev);
up(&nodemgr_ne_class.sem);
return ret_ne; return ne;
} }
...@@ -1370,30 +1389,17 @@ static void nodemgr_node_scan(struct host_info *hi, int generation) ...@@ -1370,30 +1389,17 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
} }
} }
static int __nodemgr_driver_suspend(struct device *dev, void *data)
static void nodemgr_suspend_ne(struct node_entry *ne)
{ {
struct device *dev;
struct unit_directory *ud; struct unit_directory *ud;
struct device_driver *drv; struct device_driver *drv;
struct node_entry *ne = (struct node_entry *)data;
int error; int error;
HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
ne->in_limbo = 1;
WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
down(&nodemgr_ud_class.sem);
list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
ud = container_of(dev, struct unit_directory, unit_dev); ud = container_of(dev, struct unit_directory, unit_dev);
if (ud->ne != ne) if (ud->ne == ne) {
continue;
drv = get_driver(ud->device.driver); drv = get_driver(ud->device.driver);
if (!drv) if (drv) {
continue;
error = 1; /* release if suspend is not implemented */ error = 1; /* release if suspend is not implemented */
if (drv->suspend) { if (drv->suspend) {
down(&ud->device.sem); down(&ud->device.sem);
...@@ -1404,29 +1410,21 @@ static void nodemgr_suspend_ne(struct node_entry *ne) ...@@ -1404,29 +1410,21 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
device_release_driver(&ud->device); device_release_driver(&ud->device);
put_driver(drv); put_driver(drv);
} }
up(&nodemgr_ud_class.sem); }
}
return 0;
}
static void nodemgr_resume_ne(struct node_entry *ne) static int __nodemgr_driver_resume(struct device *dev, void *data)
{ {
struct device *dev;
struct unit_directory *ud; struct unit_directory *ud;
struct device_driver *drv; struct device_driver *drv;
struct node_entry *ne = (struct node_entry *)data;
ne->in_limbo = 0;
device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
down(&nodemgr_ud_class.sem);
list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
ud = container_of(dev, struct unit_directory, unit_dev); ud = container_of(dev, struct unit_directory, unit_dev);
if (ud->ne != ne) if (ud->ne == ne) {
continue;
drv = get_driver(ud->device.driver); drv = get_driver(ud->device.driver);
if (!drv) if (drv) {
continue;
if (drv->resume) { if (drv->resume) {
down(&ud->device.sem); down(&ud->device.sem);
drv->resume(&ud->device); drv->resume(&ud->device);
...@@ -1434,33 +1432,49 @@ static void nodemgr_resume_ne(struct node_entry *ne) ...@@ -1434,33 +1432,49 @@ static void nodemgr_resume_ne(struct node_entry *ne)
} }
put_driver(drv); put_driver(drv);
} }
up(&nodemgr_ud_class.sem); }
return 0;
}
static void nodemgr_suspend_ne(struct node_entry *ne)
{
HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
NODE_BUS_ARGS(ne->host, ne->nodeid),
(unsigned long long)ne->guid);
ne->in_limbo = 1;
WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
class_for_each_device(&nodemgr_ud_class, 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, ne, __nodemgr_driver_resume);
HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
} }
static int __nodemgr_update_pdrv(struct device *dev, void *data)
static void nodemgr_update_pdrv(struct node_entry *ne)
{ {
struct device *dev;
struct unit_directory *ud; struct unit_directory *ud;
struct device_driver *drv; struct device_driver *drv;
struct hpsb_protocol_driver *pdrv; struct hpsb_protocol_driver *pdrv;
struct node_entry *ne = (struct node_entry *)data;
int error; int error;
down(&nodemgr_ud_class.sem);
list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
ud = container_of(dev, struct unit_directory, unit_dev); ud = container_of(dev, struct unit_directory, unit_dev);
if (ud->ne != ne) if (ud->ne == ne) {
continue;
drv = get_driver(ud->device.driver); drv = get_driver(ud->device.driver);
if (!drv) if (drv) {
continue;
error = 0; error = 0;
pdrv = container_of(drv, struct hpsb_protocol_driver, driver); pdrv = container_of(drv, struct hpsb_protocol_driver,
driver);
if (pdrv->update) { if (pdrv->update) {
down(&ud->device.sem); down(&ud->device.sem);
error = pdrv->update(ud); error = pdrv->update(ud);
...@@ -1470,7 +1484,14 @@ static void nodemgr_update_pdrv(struct node_entry *ne) ...@@ -1470,7 +1484,14 @@ static void nodemgr_update_pdrv(struct node_entry *ne)
device_release_driver(&ud->device); device_release_driver(&ud->device);
put_driver(drv); put_driver(drv);
} }
up(&nodemgr_ud_class.sem); }
return 0;
}
static void nodemgr_update_pdrv(struct node_entry *ne)
{
class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_update_pdrv);
} }
...@@ -1529,13 +1550,31 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge ...@@ -1529,13 +1550,31 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
put_device(dev); put_device(dev);
} }
struct probe_param {
struct host_info *hi;
int generation;
};
static int __nodemgr_node_probe(struct device *dev, void *data)
{
struct probe_param *param = (struct probe_param *)data;
struct node_entry *ne;
ne = container_of(dev, struct node_entry, node_dev);
if (!ne->needs_probe)
nodemgr_probe_ne(param->hi, ne, param->generation);
if (ne->needs_probe)
nodemgr_probe_ne(param->hi, ne, param->generation);
return 0;
}
static void nodemgr_node_probe(struct host_info *hi, int generation) static void nodemgr_node_probe(struct host_info *hi, int generation)
{ {
struct hpsb_host *host = hi->host; struct hpsb_host *host = hi->host;
struct device *dev; struct probe_param param;
struct node_entry *ne;
param.hi = hi;
param.generation = generation;
/* Do some processing of the nodes we've probed. This pulls them /* Do some processing of the nodes we've probed. This pulls them
* into the sysfs layer if needed, and can result in processing of * into the sysfs layer if needed, and can result in processing of
* unit-directories, or just updating the node and it's * 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,19 +1584,7 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
* while probes are time-consuming. (Well, those probes need some * while probes are time-consuming. (Well, those probes need some
* improvement...) */ * improvement...) */
down(&nodemgr_ne_class.sem); class_for_each_device(&nodemgr_ne_class, &param, __nodemgr_node_probe);
list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
ne = container_of(dev, struct node_entry, node_dev);
if (!ne->needs_probe)
nodemgr_probe_ne(hi, ne, generation);
}
list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
ne = container_of(dev, struct node_entry, node_dev);
if (ne->needs_probe)
nodemgr_probe_ne(hi, ne, generation);
}
up(&nodemgr_ne_class.sem);
/* If we had a bus reset while we were scanning the bus, it is /* If we had a bus reset while we were scanning the bus, it is
* possible that we did not probe all nodes. In that case, we * possible that we did not probe all nodes. In that case, we
...@@ -1757,6 +1784,22 @@ static int nodemgr_host_thread(void *__hi) ...@@ -1757,6 +1784,22 @@ static int nodemgr_host_thread(void *__hi)
return 0; return 0;
} }
struct host_iter_param {
void *data;
int (*cb)(struct hpsb_host *, void *);
};
static int __nodemgr_for_each_host(struct device *dev, void *data)
{
struct hpsb_host *host;
struct host_iter_param *hip = (struct host_iter_param *)data;
int error = 0;
host = container_of(dev, struct hpsb_host, host_dev);
error = hip->cb(host, hip->data);
return error;
}
/** /**
* nodemgr_for_each_host - call a function for each IEEE 1394 host * nodemgr_for_each_host - call a function for each IEEE 1394 host
* @data: an address to supply to the callback * @data: an address to supply to the callback
...@@ -1771,18 +1814,13 @@ static int nodemgr_host_thread(void *__hi) ...@@ -1771,18 +1814,13 @@ static int nodemgr_host_thread(void *__hi)
*/ */
int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
{ {
struct device *dev; struct host_iter_param hip;
struct hpsb_host *host; int error;
int error = 0;
down(&hpsb_host_class.sem);
list_for_each_entry(dev, &hpsb_host_class.devices, node) {
host = container_of(dev, struct hpsb_host, host_dev);
if ((error = cb(host, data))) hip.cb = cb;
break; hip.data = data;
} error = class_for_each_device(&hpsb_host_class, &hip,
up(&hpsb_host_class.sem); __nodemgr_for_each_host);
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment