From 373994c9b4fadef534fca0eb5b83277842db9748 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 7 Dec 2009 12:51:35 +0100 Subject: [PATCH] --- yaml --- r: 173246 b: refs/heads/master c: 56e6b796fe9b99287648fc5686aae00106b37bab h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/s390/cio/device.c | 35 ++++++++++++++++------------- trunk/drivers/s390/cio/device_fsm.c | 17 ++++---------- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/[refs] b/[refs] index 5c947b02d774..4faafd42c52c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 24a1872d6411c7cce82c0888a4fbea23e993e051 +refs/heads/master: 56e6b796fe9b99287648fc5686aae00106b37bab diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index e8cb99a63cc6..2b50f93b7fef 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -1130,33 +1130,36 @@ static int io_subchannel_chp_event(struct subchannel *sch, return 0; } -static void -io_subchannel_shutdown(struct subchannel *sch) +static void io_subchannel_shutdown(struct subchannel *sch) { struct ccw_device *cdev; int ret; + spin_lock_irq(sch->lock); cdev = sch_get_cdev(sch); - if (cio_is_console(sch->schid)) - return; + goto out_unlock; if (!sch->schib.pmcw.ena) - /* Nothing to do. */ - return; + goto out_unlock; ret = cio_disable_subchannel(sch); if (ret != -EBUSY) - /* Subchannel is disabled, we're done. */ - return; - cdev->private->state = DEV_STATE_QUIESCE; + goto out_unlock; if (cdev->handler) - cdev->handler(cdev, cdev->private->intparm, - ERR_PTR(-EIO)); - ret = ccw_device_cancel_halt_clear(cdev); - if (ret == -EBUSY) { - ccw_device_set_timeout(cdev, HZ/10); - wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); + cdev->handler(cdev, cdev->private->intparm, ERR_PTR(-EIO)); + while (ret == -EBUSY) { + cdev->private->state = DEV_STATE_QUIESCE; + ret = ccw_device_cancel_halt_clear(cdev); + if (ret == -EBUSY) { + ccw_device_set_timeout(cdev, HZ/10); + spin_unlock_irq(sch->lock); + wait_event(cdev->private->wait_q, + cdev->private->state != DEV_STATE_QUIESCE); + spin_lock_irq(sch->lock); + } + ret = cio_disable_subchannel(sch); } - cio_disable_subchannel(sch); +out_unlock: + spin_unlock_irq(sch->lock); } static int device_is_disconnected(struct ccw_device *cdev) diff --git a/trunk/drivers/s390/cio/device_fsm.c b/trunk/drivers/s390/cio/device_fsm.c index 7d42417bc2c7..862b89ef3ee6 100644 --- a/trunk/drivers/s390/cio/device_fsm.c +++ b/trunk/drivers/s390/cio/device_fsm.c @@ -911,10 +911,7 @@ static void ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event) { ccw_device_set_timeout(cdev, 0); - if (dev_event == DEV_EVENT_NOTOPER) - cdev->private->state = DEV_STATE_NOT_OPER; - else - cdev->private->state = DEV_STATE_OFFLINE; + cdev->private->state = DEV_STATE_NOT_OPER; wake_up(&cdev->private->wait_q); } @@ -924,17 +921,11 @@ ccw_device_quiesce_timeout(struct ccw_device *cdev, enum dev_event dev_event) int ret; ret = ccw_device_cancel_halt_clear(cdev); - switch (ret) { - case 0: - cdev->private->state = DEV_STATE_OFFLINE; - wake_up(&cdev->private->wait_q); - break; - case -ENODEV: + if (ret == -EBUSY) { + ccw_device_set_timeout(cdev, HZ/10); + } else { cdev->private->state = DEV_STATE_NOT_OPER; wake_up(&cdev->private->wait_q); - break; - default: - ccw_device_set_timeout(cdev, HZ/10); } }