diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2011-05-23 04:23:32 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-05-23 04:23:43 -0400 |
commit | 9bf05098ce34e68a9e15f09ad6cdfea4ed64057a (patch) | |
tree | 57638d72b4f1543d9e17b17e85af5d8d59f5461e /drivers/s390 | |
parent | caebc160ce3f76761cc62ad96ef6d6f30f54e3dd (diff) |
[S390] cio: fix unreg race in set_online path
In ccw_device_set_online we basically start path verification and
wait for the device to reach a final state. If it turns out that the
device has no useable path we schedule the deregistration of the
device (which is still in an non-final state) and wake up the waiting
process. The deregistration process will set a final state, but if
the wake up happens to be prior to this, the device will hang forever
in ccw_device_set_online.
To fix this just set the final NOT_OPER state prior to the scheduled
deregistration of the device.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 6084103672b5..e087a8685f95 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -408,9 +408,10 @@ ccw_device_done(struct ccw_device *cdev, int state) | |||
408 | CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel " | 408 | CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel " |
409 | "%04x\n", cdev->private->dev_id.devno, | 409 | "%04x\n", cdev->private->dev_id.devno, |
410 | sch->schid.sch_no); | 410 | sch->schid.sch_no); |
411 | if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK) | 411 | if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK) { |
412 | cdev->private->state = DEV_STATE_NOT_OPER; | ||
412 | ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); | 413 | ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); |
413 | else | 414 | } else |
414 | ccw_device_set_disconnected(cdev); | 415 | ccw_device_set_disconnected(cdev); |
415 | cdev->private->flags.donotify = 0; | 416 | cdev->private->flags.donotify = 0; |
416 | break; | 417 | break; |