[patch 2/16] s390: use klist in cio.
From: Martin Schwidefsky
Date: Tue Jun 21 2005 - 11:26:15 EST
[patch 2/16] s390: use klist in cio.
From: Cornelia Huck <cohuck@xxxxxxxxxx>
Convert the common I/O layer to use the klist interfaces.
Signed-off-by: Martin Schwidefsky <schwidefsky@xxxxxxxxxx>
diffstat:
drivers/s390/cio/ccwgroup.c | 30 ++++-----------
drivers/s390/cio/css.c | 36 +++++++++---------
drivers/s390/cio/device.c | 85 ++++++++++++++++++++++++--------------------
3 files changed, 74 insertions(+), 77 deletions(-)
diff -urpN linux-2.6/drivers/s390/cio/ccwgroup.c linux-2.6-patched/drivers/s390/cio/ccwgroup.c
--- linux-2.6/drivers/s390/cio/ccwgroup.c 2005-06-21 17:36:39.000000000 +0200
+++ linux-2.6-patched/drivers/s390/cio/ccwgroup.c 2005-06-21 17:36:45.000000000 +0200
@@ -403,34 +403,22 @@ ccwgroup_driver_register (struct ccwgrou
return driver_register(&cdriver->driver);
}
-static inline struct device *
-__get_next_ccwgroup_device(struct device_driver *drv)
+static int
+__ccwgroup_driver_unregister_device(struct device *dev, void *data)
{
- struct device *dev, *d;
-
- down_read(&drv->bus->subsys.rwsem);
- dev = NULL;
- list_for_each_entry(d, &drv->devices, driver_list) {
- dev = get_device(d);
- if (dev)
- break;
- }
- up_read(&drv->bus->subsys.rwsem);
- return dev;
+ __ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
+ device_unregister(dev);
+ put_device(dev);
+ return 0;
}
void
ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver)
{
- struct device *dev;
-
/* We don't want ccwgroup devices to live longer than their driver. */
get_driver(&cdriver->driver);
- while ((dev = __get_next_ccwgroup_device(&cdriver->driver))) {
- __ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
- device_unregister(dev);
- put_device(dev);
- };
+ driver_for_each_device(&cdriver->driver, NULL, NULL,
+ __ccwgroup_driver_unregister_device);
put_driver(&cdriver->driver);
driver_unregister(&cdriver->driver);
}
@@ -449,7 +437,7 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_d
if (cdev->dev.driver_data) {
gdev = (struct ccwgroup_device *)cdev->dev.driver_data;
if (get_device(&gdev->dev)) {
- if (!list_empty(&gdev->dev.node))
+ if (klist_node_attached(&gdev->dev.knode_bus))
return gdev;
put_device(&gdev->dev);
}
diff -urpN linux-2.6/drivers/s390/cio/css.c linux-2.6-patched/drivers/s390/cio/css.c
--- linux-2.6/drivers/s390/cio/css.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6-patched/drivers/s390/cio/css.c 2005-06-21 17:36:45.000000000 +0200
@@ -128,34 +128,34 @@ css_probe_device(int irq)
return ret;
}
-struct subchannel *
-get_subchannel_by_schid(int irq)
+static int
+check_subchannel(struct device * dev, void * data)
{
struct subchannel *sch;
- struct list_head *entry;
- struct device *dev;
+ int irq = (int)data;
- if (!get_bus(&css_bus_type))
- return NULL;
- down_read(&css_bus_type.subsys.rwsem);
- sch = NULL;
- list_for_each(entry, &css_bus_type.devices.list) {
- dev = get_device(container_of(entry,
- struct device, bus_list));
- if (!dev)
- continue;
+ if (get_device(dev)) {
sch = to_subchannel(dev);
if (sch->irq == irq)
- break;
+ return 1;
put_device(dev);
- sch = NULL;
+
}
- up_read(&css_bus_type.subsys.rwsem);
- put_bus(&css_bus_type);
+ return 0;
+}
- return sch;
+struct subchannel *
+get_subchannel_by_schid(int irq)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&css_bus_type, NULL,
+ (void *)irq, check_subchannel);
+
+ return dev ? to_subchannel(dev) : NULL;
}
+
static inline int
css_get_subchannel_status(struct subchannel *sch, int schid)
{
diff -urpN linux-2.6/drivers/s390/cio/device.c linux-2.6-patched/drivers/s390/cio/device.c
--- linux-2.6/drivers/s390/cio/device.c 2005-06-21 17:36:39.000000000 +0200
+++ linux-2.6-patched/drivers/s390/cio/device.c 2005-06-21 17:36:45.000000000 +0200
@@ -514,36 +514,42 @@ ccw_device_register(struct ccw_device *c
return ret;
}
-static struct ccw_device *
-get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
+struct match_data {
+ unsigned int devno;
+ struct ccw_device * sibling;
+};
+
+static int
+match_devno(struct device * dev, void * data)
{
- struct ccw_device *cdev;
- struct list_head *entry;
- struct device *dev;
+ struct match_data * d = (struct match_data *)data;
+ struct ccw_device * cdev;
- if (!get_bus(&ccw_bus_type))
- return NULL;
- down_read(&ccw_bus_type.subsys.rwsem);
- cdev = NULL;
- list_for_each(entry, &ccw_bus_type.devices.list) {
- dev = get_device(container_of(entry,
- struct device, bus_list));
- if (!dev)
- continue;
+ if (get_device(dev)) {
cdev = to_ccwdev(dev);
if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
- (cdev->private->devno == devno) &&
- (cdev != sibling)) {
+ (cdev->private->devno == d->devno) &&
+ (cdev != d->sibling)) {
cdev->private->state = DEV_STATE_NOT_OPER;
- break;
+ return 1;
}
put_device(dev);
- cdev = NULL;
}
- up_read(&ccw_bus_type.subsys.rwsem);
- put_bus(&ccw_bus_type);
+ return 0;
+}
+
+static struct ccw_device *
+get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
+{
+ struct device *dev;
+ struct match_data data = {
+ .devno = devno,
+ .sibling = sibling,
+ };
+
+ dev = bus_find_device(&css_bus_type, NULL, &data, match_devno);
- return cdev;
+ return dev ? to_ccwdev(dev) : NULL;
}
static void
@@ -647,7 +653,7 @@ io_subchannel_register(void *data)
cdev = (struct ccw_device *) data;
sch = to_subchannel(cdev->dev.parent);
- if (!list_empty(&sch->dev.children)) {
+ if (klist_node_attached(&cdev->dev.knode_parent)) {
bus_rescan_devices(&ccw_bus_type);
goto out;
}
@@ -1019,30 +1025,33 @@ ccw_device_probe_console(void)
/*
* get ccw_device matching the busid, but only if owned by cdrv
*/
+static int
+__ccwdev_check_busid(struct device *dev, void *id)
+{
+ char *bus_id;
+
+ bus_id = (char *)id;
+ if (get_device(dev)) {
+ if (!strncmp(bus_id, dev->bus_id, BUS_ID_SIZE))
+ return 1;
+ put_device(dev);
+ }
+ return 0;
+}
+
+
struct ccw_device *
get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id)
{
- struct device *d, *dev;
+ struct device *dev;
struct device_driver *drv;
drv = get_driver(&cdrv->driver);
if (!drv)
- return 0;
-
- down_read(&drv->bus->subsys.rwsem);
-
- dev = NULL;
- list_for_each_entry(d, &drv->devices, driver_list) {
- dev = get_device(d);
+ return NULL;
- if (dev && !strncmp(bus_id, dev->bus_id, BUS_ID_SIZE))
- break;
- else if (dev) {
- put_device(dev);
- dev = NULL;
- }
- }
- up_read(&drv->bus->subsys.rwsem);
+ dev = driver_find_device(drv, NULL, (void *)bus_id,
+ __ccwdev_check_busid);
put_driver(drv);
return dev ? to_ccwdev(dev) : 0;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/