Commit afdfed0f authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky

s390/cio: get rid of static console device

Remove the static console ccw device (and friends) and use dynamic
allocation for these structures. With this change the console
device is treated (mostly) like any other ccw device and we can
remove some special cases.
Reviewed-by: default avatarPeter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 863fc849
...@@ -1087,19 +1087,12 @@ static int io_subchannel_probe(struct subchannel *sch) ...@@ -1087,19 +1087,12 @@ static int io_subchannel_probe(struct subchannel *sch)
dev_set_uevent_suppress(&sch->dev, 0); dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD); kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
cdev = sch_get_cdev(sch); cdev = sch_get_cdev(sch);
cdev->dev.groups = ccwdev_attr_groups; rc = ccw_device_register(cdev);
device_initialize(&cdev->dev); if (rc) {
cdev->private->flags.initialized = 1; /* Release online reference. */
ccw_device_register(cdev); put_device(&cdev->dev);
/* goto out_schedule;
* Check if the device is already online. If it is }
* the reference count needs to be corrected since we
* didn't obtain a reference in ccw_device_set_online.
*/
if (cdev->private->state != DEV_STATE_NOT_OPER &&
cdev->private->state != DEV_STATE_OFFLINE &&
cdev->private->state != DEV_STATE_BOXED)
get_device(&cdev->dev);
return 0; return 0;
} }
io_subchannel_init_fields(sch); io_subchannel_init_fields(sch);
...@@ -1581,10 +1574,6 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) ...@@ -1581,10 +1574,6 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
} }
#ifdef CONFIG_CCW_CONSOLE #ifdef CONFIG_CCW_CONSOLE
static struct ccw_device console_cdev;
static struct ccw_device_private console_private;
static int console_cdev_in_use;
static int ccw_device_console_enable(struct ccw_device *cdev, static int ccw_device_console_enable(struct ccw_device *cdev,
struct subchannel *sch) struct subchannel *sch)
{ {
...@@ -1595,8 +1584,6 @@ static int ccw_device_console_enable(struct ccw_device *cdev, ...@@ -1595,8 +1584,6 @@ static int ccw_device_console_enable(struct ccw_device *cdev,
if (rc) if (rc)
return rc; return rc;
sch->driver = &io_subchannel_driver; sch->driver = &io_subchannel_driver;
/* Initialize the ccw_device structure. */
cdev->dev.parent= &sch->dev;
sch_set_cdev(sch, cdev); sch_set_cdev(sch, cdev);
io_subchannel_recog(cdev, sch); io_subchannel_recog(cdev, sch);
/* Now wait for the async. recognition to come to an end. */ /* Now wait for the async. recognition to come to an end. */
...@@ -1604,58 +1591,58 @@ static int ccw_device_console_enable(struct ccw_device *cdev, ...@@ -1604,58 +1591,58 @@ static int ccw_device_console_enable(struct ccw_device *cdev,
while (!dev_fsm_final_state(cdev)) while (!dev_fsm_final_state(cdev))
ccw_device_wait_idle(cdev); ccw_device_wait_idle(cdev);
rc = -EIO; /* Hold on to an extra reference while device is online. */
if (cdev->private->state != DEV_STATE_OFFLINE) get_device(&cdev->dev);
rc = ccw_device_online(cdev);
if (rc)
goto out_unlock; goto out_unlock;
ccw_device_online(cdev);
while (!dev_fsm_final_state(cdev)) while (!dev_fsm_final_state(cdev))
ccw_device_wait_idle(cdev); ccw_device_wait_idle(cdev);
if (cdev->private->state != DEV_STATE_ONLINE) if (cdev->private->state == DEV_STATE_ONLINE)
goto out_unlock; cdev->online = 1;
rc = 0; else
rc = -EIO;
out_unlock: out_unlock:
spin_unlock_irq(cdev->ccwlock); spin_unlock_irq(cdev->ccwlock);
if (rc) /* Give up online reference since onlining failed. */
put_device(&cdev->dev);
return rc; return rc;
} }
struct ccw_device * struct ccw_device *ccw_device_probe_console(void)
ccw_device_probe_console(void)
{ {
struct io_subchannel_private *io_priv; struct io_subchannel_private *io_priv;
struct ccw_device *cdev;
struct subchannel *sch; struct subchannel *sch;
int ret; int ret;
if (xchg(&console_cdev_in_use, 1) != 0)
return ERR_PTR(-EBUSY);
sch = cio_probe_console(); sch = cio_probe_console();
if (IS_ERR(sch)) { if (IS_ERR(sch))
console_cdev_in_use = 0; return ERR_CAST(sch);
return (void *) sch;
}
memset(&console_cdev, 0, sizeof(struct ccw_device));
memset(&console_private, 0, sizeof(struct ccw_device_private));
console_cdev.private = &console_private;
console_private.cdev = &console_cdev;
console_private.int_class = IRQIO_CIO;
io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA); io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA);
if (!io_priv) { if (!io_priv) {
put_device(&sch->dev); put_device(&sch->dev);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
cdev = io_subchannel_create_ccwdev(sch);
if (IS_ERR(cdev)) {
put_device(&sch->dev);
kfree(io_priv);
return cdev;
}
set_io_private(sch, io_priv); set_io_private(sch, io_priv);
ret = ccw_device_console_enable(cdev, sch);
ret = ccw_device_console_enable(&console_cdev, sch);
if (ret) { if (ret) {
console_cdev_in_use = 0;
set_io_private(sch, NULL); set_io_private(sch, NULL);
put_device(&sch->dev); put_device(&sch->dev);
put_device(&cdev->dev);
kfree(io_priv); kfree(io_priv);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
console_cdev.online = 1; return cdev;
return &console_cdev;
} }
/** /**
......
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