[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: 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>
This commit is contained in:
committed by
Linus Torvalds
parent
84dd8d7e9c
commit
b0744bd292
@@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
return ret;
|
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 *
|
static struct ccw_device *
|
||||||
get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
|
get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
|
||||||
{
|
{
|
||||||
struct ccw_device *cdev;
|
|
||||||
struct list_head *entry;
|
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
struct match_data data = {
|
||||||
|
.devno = devno,
|
||||||
|
.sibling = sibling,
|
||||||
|
};
|
||||||
|
|
||||||
if (!get_bus(&ccw_bus_type))
|
dev = bus_find_device(&css_bus_type, NULL, &data, match_devno);
|
||||||
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);
|
|
||||||
|
|
||||||
return cdev;
|
return dev ? to_ccwdev(dev) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -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)
|
|||||||
/*
|
/*
|
||||||
* 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 = driver_find_device(drv, NULL, (void *)bus_id,
|
||||||
|
__ccwdev_check_busid);
|
||||||
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))
|
|
||||||
break;
|
|
||||||
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;
|
||||||
|
Reference in New Issue
Block a user