[PATCH] s/390: Use klist in cio
authorCornelia Huck <cohuck@de.ibm.com>
Sat, 25 Jun 2005 21:55:27 +0000 (14:55 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 25 Jun 2005 23:24:36 +0000 (16:24 -0700)
Convert the common I/O layer to use the klist interfaces.

This patch has been adapted from the previous version to the changed interface
semantics.  Also, gcc 4.0 compile warnings have been removed.

Signed-off-by: Cornelia Huck <cohuck@de.ibm.com>
Cc: Greg KH <greg@kroah.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/css.c
drivers/s390/cio/device.c

index 306525a..91ea8e4 100644 (file)
@@ -403,34 +403,22 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
        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_device *cdev)
        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);
                }
index 87bd70e..555119c 100644 (file)
@@ -128,34 +128,28 @@ css_probe_device(int irq)
        return ret;
 }
 
+static int
+check_subchannel(struct device * dev, void * data)
+{
+       struct subchannel *sch;
+       int irq = (unsigned long)data;
+
+       sch = to_subchannel(dev);
+       return (sch->irq == irq);
+}
+
 struct subchannel *
 get_subchannel_by_schid(int irq)
 {
-       struct subchannel *sch;
-       struct list_head *entry;
        struct device *dev;
 
-       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;
-               sch = to_subchannel(dev);
-               if (sch->irq == irq)
-                       break;
-               put_device(dev);
-               sch = NULL;
-       }
-       up_read(&css_bus_type.subsys.rwsem);
-       put_bus(&css_bus_type);
+       dev = bus_find_device(&css_bus_type, NULL,
+                             (void *)(unsigned long)irq, check_subchannel);
 
-       return sch;
+       return dev ? to_subchannel(dev) : NULL;
 }
 
+
 static inline int
 css_get_subchannel_status(struct subchannel *sch, int schid)
 {
index 809e110..14c76f5 100644 (file)
@@ -514,36 +514,39 @@ ccw_device_register(struct ccw_device *cdev)
        return ret;
 }
 
+struct match_data {
+       unsigned int  devno;
+       struct ccw_device * sibling;
+};
+
+static int
+match_devno(struct device * dev, void * data)
+{
+       struct match_data * d = (struct match_data *)data;
+       struct ccw_device * cdev;
+
+       cdev = to_ccwdev(dev);
+       if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
+           (cdev->private->devno == d->devno) &&
+           (cdev != d->sibling)) {
+               cdev->private->state = DEV_STATE_NOT_OPER;
+               return 1;
+       }
+       return 0;
+}
+
 static struct ccw_device *
 get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
 {
-       struct ccw_device *cdev;
-       struct list_head *entry;
        struct device *dev;
+       struct match_data data = {
+               .devno  = devno,
+               .sibling = sibling,
+       };
 
-       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;
-               cdev = to_ccwdev(dev);
-               if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
-                   (cdev->private->devno == devno) &&
-                   (cdev != sibling)) {
-                       cdev->private->state = DEV_STATE_NOT_OPER;
-                       break;
-               }
-               put_device(dev);
-               cdev = NULL;
-       }
-       up_read(&ccw_bus_type.subsys.rwsem);
-       put_bus(&ccw_bus_type);
+       dev = bus_find_device(&css_bus_type, NULL, &data, match_devno);
 
-       return cdev;
+       return dev ? to_ccwdev(dev) : NULL;
 }
 
 static void
@@ -647,7 +650,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 +1022,29 @@ 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;
+
+       return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 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;