[S390] cio: wake up on failed recognition
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Tue, 31 Mar 2009 17:16:03 +0000 (19:16 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 31 Mar 2009 17:17:03 +0000 (19:17 +0200)
Wake up even on failed device recognition, since this may be triggered
from a user trying to force a device online. With this patch a write
to the online sysfs attribute will not block for ever but return with
-EAGAIN in this case.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/cio/device.c
drivers/s390/cio/device_fsm.c

index c4d2f66..9f016fe 100644 (file)
@@ -482,17 +482,21 @@ static int online_store_recog_and_online(struct ccw_device *cdev)
                }
                wait_event(cdev->private->wait_q,
                           cdev->private->flags.recog_done);
+               if (cdev->private->state != DEV_STATE_OFFLINE)
+                       /* recognition failed */
+                       return -EAGAIN;
        }
        if (cdev->drv && cdev->drv->set_online)
                ccw_device_set_online(cdev);
        return 0;
 }
+
 static int online_store_handle_online(struct ccw_device *cdev, int force)
 {
        int ret;
 
        ret = online_store_recog_and_online(cdev);
-       if (ret)
+       if (ret && !force)
                return ret;
        if (force && cdev->private->state == DEV_STATE_BOXED) {
                ret = ccw_device_stlck(cdev);
@@ -500,7 +504,9 @@ static int online_store_handle_online(struct ccw_device *cdev, int force)
                        return ret;
                if (cdev->id.cu_type == 0)
                        cdev->private->state = DEV_STATE_NOT_OPER;
-               online_store_recog_and_online(cdev);
+               ret = online_store_recog_and_online(cdev);
+               if (ret)
+                       return ret;
        }
        return 0;
 }
index 87b4bfc..ccd72f9 100644 (file)
@@ -260,6 +260,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
                if (state == DEV_STATE_NOT_OPER) {
                        cdev->private->flags.recog_done = 1;
                        cdev->private->state = DEV_STATE_DISCONNECTED;
+                       wake_up(&cdev->private->wait_q);
                        return;
                }
                /* Boxed devices don't need extra treatment. */
@@ -311,8 +312,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
        }
        cdev->private->state = state;
        io_subchannel_recog_done(cdev);
-       if (state != DEV_STATE_NOT_OPER)
-               wake_up(&cdev->private->wait_q);
+       wake_up(&cdev->private->wait_q);
 }
 
 /*