Commit b0744bd2 authored by Cornelia Huck's avatar Cornelia Huck Committed by Linus Torvalds

[PATCH] s/390: Use klist in cio

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: default avatarCornelia Huck <cohuck@de.ibm.com>
Cc: Greg KH <greg@kroah.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 84dd8d7e
...@@ -403,34 +403,22 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver) ...@@ -403,34 +403,22 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
return driver_register(&cdriver->driver); return driver_register(&cdriver->driver);
} }
static inline struct device * static int
__get_next_ccwgroup_device(struct device_driver *drv) __ccwgroup_driver_unregister_device(struct device *dev, void *data)
{ {
struct device *dev, *d; __ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
device_unregister(dev);
down_read(&drv->bus->subsys.rwsem); put_device(dev);
dev = NULL; return 0;
list_for_each_entry(d, &drv->devices, driver_list) {
dev = get_device(d);
if (dev)
break;
}
up_read(&drv->bus->subsys.rwsem);
return dev;
} }
void void
ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver)
{ {
struct device *dev;
/* We don't want ccwgroup devices to live longer than their driver. */ /* We don't want ccwgroup devices to live longer than their driver. */
get_driver(&cdriver->driver); get_driver(&cdriver->driver);
while ((dev = __get_next_ccwgroup_device(&cdriver->driver))) { driver_for_each_device(&cdriver->driver, NULL, NULL,
__ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); __ccwgroup_driver_unregister_device);
device_unregister(dev);
put_device(dev);
};
put_driver(&cdriver->driver); put_driver(&cdriver->driver);
driver_unregister(&cdriver->driver); driver_unregister(&cdriver->driver);
} }
...@@ -449,7 +437,7 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev) ...@@ -449,7 +437,7 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev)
if (cdev->dev.driver_data) { if (cdev->dev.driver_data) {
gdev = (struct ccwgroup_device *)cdev->dev.driver_data; gdev = (struct ccwgroup_device *)cdev->dev.driver_data;
if (get_device(&gdev->dev)) { if (get_device(&gdev->dev)) {
if (!list_empty(&gdev->dev.node)) if (klist_node_attached(&gdev->dev.knode_bus))
return gdev; return gdev;
put_device(&gdev->dev); put_device(&gdev->dev);
} }
......
...@@ -128,34 +128,28 @@ css_probe_device(int irq) ...@@ -128,34 +128,28 @@ css_probe_device(int irq)
return ret; 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 * struct subchannel *
get_subchannel_by_schid(int irq) get_subchannel_by_schid(int irq)
{ {
struct subchannel *sch;
struct list_head *entry;
struct device *dev; struct device *dev;
if (!get_bus(&css_bus_type)) dev = bus_find_device(&css_bus_type, NULL,
return NULL; (void *)(unsigned long)irq, check_subchannel);
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);
return sch; return dev ? to_subchannel(dev) : NULL;
} }
static inline int static inline int
css_get_subchannel_status(struct subchannel *sch, int schid) css_get_subchannel_status(struct subchannel *sch, int schid)
{ {
......
...@@ -514,36 +514,39 @@ ccw_device_register(struct ccw_device *cdev) ...@@ -514,36 +514,39 @@ ccw_device_register(struct ccw_device *cdev)
return ret; return ret;
} }
static struct ccw_device * struct match_data {
get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling) unsigned int devno;
struct ccw_device * sibling;
};
static int
match_devno(struct device * dev, void * data)
{ {
struct ccw_device *cdev; struct match_data * d = (struct match_data *)data;
struct list_head *entry; struct ccw_device * cdev;
struct device *dev;
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); cdev = to_ccwdev(dev);
if ((cdev->private->state == DEV_STATE_DISCONNECTED) && if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
(cdev->private->devno == devno) && (cdev->private->devno == d->devno) &&
(cdev != sibling)) { (cdev != d->sibling)) {
cdev->private->state = DEV_STATE_NOT_OPER; cdev->private->state = DEV_STATE_NOT_OPER;
break; return 1;
}
put_device(dev);
cdev = NULL;
} }
up_read(&ccw_bus_type.subsys.rwsem); return 0;
put_bus(&ccw_bus_type); }
return cdev; 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 dev ? to_ccwdev(dev) : NULL;
} }
static void static void
...@@ -647,7 +650,7 @@ io_subchannel_register(void *data) ...@@ -647,7 +650,7 @@ io_subchannel_register(void *data)
cdev = (struct ccw_device *) data; cdev = (struct ccw_device *) data;
sch = to_subchannel(cdev->dev.parent); 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); bus_rescan_devices(&ccw_bus_type);
goto out; goto out;
} }
...@@ -1019,30 +1022,29 @@ ccw_device_probe_console(void) ...@@ -1019,30 +1022,29 @@ ccw_device_probe_console(void)
/* /*
* get ccw_device matching the busid, but only if owned by cdrv * 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 * struct ccw_device *
get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id) get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id)
{ {
struct device *d, *dev; struct device *dev;
struct device_driver *drv; struct device_driver *drv;
drv = get_driver(&cdrv->driver); drv = get_driver(&cdrv->driver);
if (!drv) if (!drv)
return 0; return NULL;
down_read(&drv->bus->subsys.rwsem);
dev = NULL;
list_for_each_entry(d, &drv->devices, driver_list) {
dev = get_device(d);
if (dev && !strncmp(bus_id, dev->bus_id, BUS_ID_SIZE)) dev = driver_find_device(drv, NULL, (void *)bus_id,
break; __ccwdev_check_busid);
else if (dev) {
put_device(dev);
dev = NULL;
}
}
up_read(&drv->bus->subsys.rwsem);
put_driver(drv); put_driver(drv);
return dev ? to_ccwdev(dev) : 0; return dev ? to_ccwdev(dev) : 0;
......
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