ctcm: suspend has to wait for outstanding I/O
authorFrank Blaschka <frank.blaschka@de.ibm.com>
Thu, 12 Nov 2009 21:46:28 +0000 (21:46 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 14 Nov 2009 04:46:59 +0000 (20:46 -0800)
State transition to DEV_STATE_STOPPED indicates all outstanding I/O has
finished. Add wait queue to wait for this state.

Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/s390/net/ctcm_main.c
drivers/s390/net/fsm.c
drivers/s390/net/fsm.h

index db054ed1a8cc7fae08e2a45a8108434406cbefcc..ecac3b2e32d4dd845519efe88e886ec4e14537c8 100644 (file)
@@ -1720,6 +1720,11 @@ static int ctcm_pm_suspend(struct ccwgroup_device *gdev)
                return 0;
        netif_device_detach(priv->channel[READ]->netdev);
        ctcm_close(priv->channel[READ]->netdev);
+       if (!wait_event_timeout(priv->fsm->wait_q,
+           fsm_getstate(priv->fsm) == DEV_STATE_STOPPED, CTCM_TIME_5_SEC)) {
+               netif_device_attach(priv->channel[READ]->netdev);
+               return -EBUSY;
+       }
        ccw_device_set_offline(gdev->cdev[1]);
        ccw_device_set_offline(gdev->cdev[0]);
        return 0;
index 2c1db8036b7c7aa04bbc33b725da877a0794601b..cae48cbc5e965b9f970728f0d8656a267636e276 100644 (file)
@@ -27,6 +27,7 @@ init_fsm(char *name, const char **state_names, const char **event_names, int nr_
                return NULL;
        }
        strlcpy(this->name, name, sizeof(this->name));
+       init_waitqueue_head(&this->wait_q);
 
        f = kzalloc(sizeof(fsm), order);
        if (f == NULL) {
index af679c10f1bd307deea0674458fb96f9ecc866b6..1e8b235d95b597c026f235e34a116b627757e756 100644 (file)
@@ -66,6 +66,7 @@ typedef struct fsm_instance_t {
        char name[16];
        void *userdata;
        int userint;
+       wait_queue_head_t wait_q;
 #if FSM_DEBUG_HISTORY
        int         history_index;
        int         history_size;
@@ -197,6 +198,7 @@ fsm_newstate(fsm_instance *fi, int newstate)
        printk(KERN_DEBUG "fsm(%s): New state %s\n", fi->name,
                fi->f->state_names[newstate]);
 #endif
+       wake_up(&fi->wait_q);
 }
 
 /**