]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/s390/cio/device.c
Merge 'drm-3264' branch of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/airlied...
[linux-2.6-omap-h63xx.git] / drivers / s390 / cio / device.c
index 809e1108a06ef40c00603133d98a38bcc9eaceba..14c76f5e417708ebbd22321ebda46ed9cd5d79b3 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;