Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+176 −138
Original line number Diff line number Diff line
@@ -727,33 +727,31 @@ 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)
{
	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)
{
	struct device *dev;
	struct unit_directory *tmp, *ud;

	/* Iteration over nodemgr_ud_class.devices has to be protected by
	 * nodemgr_ud_class.sem, but 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.
	struct unit_directory *ud;

	/* Use class_find device to iterate the devices. Since this code
	 * may be called from other contexts besides the knodemgrds,
	 * protect it by nodemgr_serialize_remove_uds.
	 */
	mutex_lock(&nodemgr_serialize_remove_uds);
	for (;;) {
		ud = NULL;
		down(&nodemgr_ud_class.sem);
		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)
		dev = class_find_device(&nodemgr_ud_class, ne, __match_ne);
		if (!dev)
			break;
		ud = container_of(dev, struct unit_directory, unit_dev);
		put_device(dev);
		device_unregister(&ud->unit_dev);
		device_unregister(&ud->device);
	}
@@ -882,45 +880,66 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
	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)
{
	struct device *dev;
	struct node_entry *ne, *ret_ne = NULL;
	struct node_entry *ne;

	down(&nodemgr_ne_class.sem);
	list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
	dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid);
	if (!dev)
		return NULL;
	ne = container_of(dev, struct node_entry, node_dev);
	put_device(dev);

		if (ne->guid == guid) {
			ret_ne = ne;
			break;
		}
	return ne;
}
	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,
					       nodeid_t nodeid)
{
	struct device *dev;
	struct node_entry *ne, *ret_ne = NULL;
	struct node_entry *ne;
	struct match_nodeid_param param;

	down(&nodemgr_ne_class.sem);
	list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
		ne = container_of(dev, struct node_entry, node_dev);
	param.host = host;
	param.nodeid = nodeid;

		if (ne->host == host && ne->nodeid == nodeid) {
			ret_ne = ne;
			break;
		}
	}
	up(&nodemgr_ne_class.sem);
	dev = class_find_device(&nodemgr_ne_class, &param, __match_ne_nodeid);
	if (!dev)
		return NULL;
	ne = container_of(dev, struct node_entry, node_dev);
	put_device(dev);

	return ret_ne;
	return ne;
}


@@ -1370,30 +1389,17 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
	}
}


static void nodemgr_suspend_ne(struct node_entry *ne)
static int __nodemgr_driver_suspend(struct device *dev, void *data)
{
	struct device *dev;
	struct unit_directory *ud;
	struct device_driver *drv;
	struct node_entry *ne = (struct node_entry *)data;
	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);
		if (ud->ne != ne)
			continue;

	if (ud->ne == ne) {
		drv = get_driver(ud->device.driver);
		if (!drv)
			continue;

		if (drv) {
			error = 1; /* release if suspend is not implemented */
			if (drv->suspend) {
				down(&ud->device.sem);
@@ -1404,29 +1410,21 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
				device_release_driver(&ud->device);
			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 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);
		if (ud->ne != ne)
			continue;

	if (ud->ne == ne) {
		drv = get_driver(ud->device.driver);
		if (!drv)
			continue;

		if (drv) {
			if (drv->resume) {
				down(&ud->device.sem);
				drv->resume(&ud->device);
@@ -1434,33 +1432,49 @@ static void nodemgr_resume_ne(struct node_entry *ne)
			}
			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]",
		   NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
}


static void nodemgr_update_pdrv(struct node_entry *ne)
static int __nodemgr_update_pdrv(struct device *dev, void *data)
{
	struct device *dev;
	struct unit_directory *ud;
	struct device_driver *drv;
	struct hpsb_protocol_driver *pdrv;
	struct node_entry *ne = (struct node_entry *)data;
	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);
		if (ud->ne != ne)
			continue;

	if (ud->ne == ne) {
		drv = get_driver(ud->device.driver);
		if (!drv)
			continue;

		if (drv) {
			error = 0;
		pdrv = container_of(drv, struct hpsb_protocol_driver, driver);
			pdrv = container_of(drv, struct hpsb_protocol_driver,
					    driver);
			if (pdrv->update) {
				down(&ud->device.sem);
				error = pdrv->update(ud);
@@ -1470,7 +1484,14 @@ static void nodemgr_update_pdrv(struct node_entry *ne)
				device_release_driver(&ud->device);
			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
	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)
{
	struct hpsb_host *host = hi->host;
	struct device *dev;
	struct node_entry *ne;
	struct probe_param param;

	param.hi = hi;
	param.generation = generation;
	/* Do some processing of the nodes we've probed. This pulls them
	 * into the sysfs layer if needed, and can result in processing of
	 * 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)
	 * while probes are time-consuming. (Well, those probes need some
	 * improvement...) */

	down(&nodemgr_ne_class.sem);
	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);

	class_for_each_device(&nodemgr_ne_class, &param, __nodemgr_node_probe);

	/* 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
@@ -1757,6 +1784,22 @@ static int nodemgr_host_thread(void *__hi)
	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
 * @data: an address to supply to the callback
@@ -1771,18 +1814,13 @@ static int nodemgr_host_thread(void *__hi)
 */
int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
{
	struct device *dev;
	struct hpsb_host *host;
	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);
	struct host_iter_param hip;
	int error;

		if ((error = cb(host, data)))
			break;
	}
	up(&hpsb_host_class.sem);
	hip.cb = cb;
	hip.data = data;
	error = class_for_each_device(&hpsb_host_class, &hip,
				      __nodemgr_for_each_host);

	return error;
}