Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 157434
b: refs/heads/master
c: 217ee6c
h: refs/heads/master
v: v3
  • Loading branch information
Michael Ernst authored and Martin Schwidefsky committed Sep 11, 2009
1 parent a1d4f59 commit c114fb4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 36 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: be7a2ddce66991c05a1c6ad19790289591e53547
refs/heads/master: 217ee6c64a9589bc5ad4d1c88136fc359d17930b
100 changes: 65 additions & 35 deletions trunk/drivers/s390/cio/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,30 +380,34 @@ int ccw_device_set_offline(struct ccw_device *cdev)
}
cdev->online = 0;
spin_lock_irq(cdev->ccwlock);
ret = ccw_device_offline(cdev);
if (ret == -ENODEV) {
if (cdev->private->state != DEV_STATE_NOT_OPER) {
cdev->private->state = DEV_STATE_OFFLINE;
dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
}
/* Wait until a final state or DISCONNECTED is reached */
while (!dev_fsm_final_state(cdev) &&
cdev->private->state != DEV_STATE_DISCONNECTED) {
spin_unlock_irq(cdev->ccwlock);
/* Give up reference from ccw_device_set_online(). */
put_device(&cdev->dev);
return ret;
wait_event(cdev->private->wait_q, (dev_fsm_final_state(cdev) ||
cdev->private->state == DEV_STATE_DISCONNECTED));
spin_lock_irq(cdev->ccwlock);
}
ret = ccw_device_offline(cdev);
if (ret)
goto error;
spin_unlock_irq(cdev->ccwlock);
if (ret == 0) {
wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
/* Give up reference from ccw_device_set_online(). */
put_device(&cdev->dev);
} else {
CIO_MSG_EVENT(0, "ccw_device_offline returned %d, "
"device 0.%x.%04x\n",
ret, cdev->private->dev_id.ssid,
cdev->private->dev_id.devno);
cdev->online = 1;
}
return ret;
wait_event(cdev->private->wait_q, (dev_fsm_final_state(cdev) ||
cdev->private->state == DEV_STATE_DISCONNECTED));
/* Give up reference from ccw_device_set_online(). */
put_device(&cdev->dev);
return 0;

error:
CIO_MSG_EVENT(0, "ccw_device_offline returned %d, device 0.%x.%04x\n",
ret, cdev->private->dev_id.ssid,
cdev->private->dev_id.devno);
cdev->private->state = DEV_STATE_OFFLINE;
dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
spin_unlock_irq(cdev->ccwlock);
/* Give up reference from ccw_device_set_online(). */
put_device(&cdev->dev);
return -ENODEV;
}

/**
Expand All @@ -421,6 +425,7 @@ int ccw_device_set_offline(struct ccw_device *cdev)
int ccw_device_set_online(struct ccw_device *cdev)
{
int ret;
int ret2;

if (!cdev)
return -ENODEV;
Expand All @@ -444,28 +449,53 @@ int ccw_device_set_online(struct ccw_device *cdev)
put_device(&cdev->dev);
return ret;
}
if (cdev->private->state != DEV_STATE_ONLINE) {
spin_lock_irq(cdev->ccwlock);
/* Check if online processing was successful */
if ((cdev->private->state != DEV_STATE_ONLINE) &&
(cdev->private->state != DEV_STATE_W4SENSE)) {
spin_unlock_irq(cdev->ccwlock);
/* Give up online reference since onlining failed. */
put_device(&cdev->dev);
return -ENODEV;
}
if (!cdev->drv->set_online || cdev->drv->set_online(cdev) == 0) {
cdev->online = 1;
return 0;
}
spin_unlock_irq(cdev->ccwlock);
if (cdev->drv->set_online)
ret = cdev->drv->set_online(cdev);
if (ret)
goto rollback;
cdev->online = 1;
return 0;

rollback:
spin_lock_irq(cdev->ccwlock);
ret = ccw_device_offline(cdev);
/* Wait until a final state or DISCONNECTED is reached */
while (!dev_fsm_final_state(cdev) &&
cdev->private->state != DEV_STATE_DISCONNECTED) {
spin_unlock_irq(cdev->ccwlock);
wait_event(cdev->private->wait_q, (dev_fsm_final_state(cdev) ||
cdev->private->state == DEV_STATE_DISCONNECTED));
spin_lock_irq(cdev->ccwlock);
}
ret2 = ccw_device_offline(cdev);
if (ret2)
goto error;
spin_unlock_irq(cdev->ccwlock);
if (ret == 0)
wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
else
CIO_MSG_EVENT(0, "ccw_device_offline returned %d, "
"device 0.%x.%04x\n",
ret, cdev->private->dev_id.ssid,
cdev->private->dev_id.devno);
wait_event(cdev->private->wait_q, (dev_fsm_final_state(cdev) ||
cdev->private->state == DEV_STATE_DISCONNECTED));
/* Give up online reference since onlining failed. */
put_device(&cdev->dev);
return (ret == 0) ? -ENODEV : ret;
return ret;

error:
CIO_MSG_EVENT(0, "rollback ccw_device_offline returned %d, "
"device 0.%x.%04x\n",
ret2, cdev->private->dev_id.ssid,
cdev->private->dev_id.devno);
cdev->private->state = DEV_STATE_OFFLINE;
spin_unlock_irq(cdev->ccwlock);
/* Give up online reference since onlining failed. */
put_device(&cdev->dev);
return ret;
}

static int online_store_handle_offline(struct ccw_device *cdev)
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/s390/cio/device_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,8 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
}
call_handler:
cdev->private->state = DEV_STATE_ONLINE;
/* In case sensing interfered with setting the device online */
wake_up(&cdev->private->wait_q);
/* Call the handler. */
if (ccw_device_call_handler(cdev) && cdev->private->flags.doverify)
/* Start delayed path verification. */
Expand Down

0 comments on commit c114fb4

Please sign in to comment.