~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/s390/cio/device_fsm.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * drivers/s390/cio/device_fsm.c
 
3
 * finite state machine for device handling
 
4
 *
 
5
 *    Copyright IBM Corp. 2002,2008
 
6
 *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
 
7
 *               Martin Schwidefsky (schwidefsky@de.ibm.com)
 
8
 */
 
9
 
 
10
#include <linux/module.h>
 
11
#include <linux/init.h>
 
12
#include <linux/jiffies.h>
 
13
#include <linux/string.h>
 
14
 
 
15
#include <asm/ccwdev.h>
 
16
#include <asm/cio.h>
 
17
#include <asm/chpid.h>
 
18
 
 
19
#include "cio.h"
 
20
#include "cio_debug.h"
 
21
#include "css.h"
 
22
#include "device.h"
 
23
#include "chsc.h"
 
24
#include "ioasm.h"
 
25
#include "chp.h"
 
26
 
 
27
static int timeout_log_enabled;
 
28
 
 
29
static int __init ccw_timeout_log_setup(char *unused)
 
30
{
 
31
        timeout_log_enabled = 1;
 
32
        return 1;
 
33
}
 
34
 
 
35
__setup("ccw_timeout_log", ccw_timeout_log_setup);
 
36
 
 
37
static void ccw_timeout_log(struct ccw_device *cdev)
 
38
{
 
39
        struct schib schib;
 
40
        struct subchannel *sch;
 
41
        struct io_subchannel_private *private;
 
42
        union orb *orb;
 
43
        int cc;
 
44
 
 
45
        sch = to_subchannel(cdev->dev.parent);
 
46
        private = to_io_private(sch);
 
47
        orb = &private->orb;
 
48
        cc = stsch_err(sch->schid, &schib);
 
49
 
 
50
        printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
 
51
               "device information:\n", get_clock());
 
52
        printk(KERN_WARNING "cio: orb:\n");
 
53
        print_hex_dump(KERN_WARNING, "cio:  ", DUMP_PREFIX_NONE, 16, 1,
 
54
                       orb, sizeof(*orb), 0);
 
55
        printk(KERN_WARNING "cio: ccw device bus id: %s\n",
 
56
               dev_name(&cdev->dev));
 
57
        printk(KERN_WARNING "cio: subchannel bus id: %s\n",
 
58
               dev_name(&sch->dev));
 
59
        printk(KERN_WARNING "cio: subchannel lpm: %02x, opm: %02x, "
 
60
               "vpm: %02x\n", sch->lpm, sch->opm, sch->vpm);
 
61
 
 
62
        if (orb->tm.b) {
 
63
                printk(KERN_WARNING "cio: orb indicates transport mode\n");
 
64
                printk(KERN_WARNING "cio: last tcw:\n");
 
65
                print_hex_dump(KERN_WARNING, "cio:  ", DUMP_PREFIX_NONE, 16, 1,
 
66
                               (void *)(addr_t)orb->tm.tcw,
 
67
                               sizeof(struct tcw), 0);
 
68
        } else {
 
69
                printk(KERN_WARNING "cio: orb indicates command mode\n");
 
70
                if ((void *)(addr_t)orb->cmd.cpa == &private->sense_ccw ||
 
71
                    (void *)(addr_t)orb->cmd.cpa == cdev->private->iccws)
 
72
                        printk(KERN_WARNING "cio: last channel program "
 
73
                               "(intern):\n");
 
74
                else
 
75
                        printk(KERN_WARNING "cio: last channel program:\n");
 
76
 
 
77
                print_hex_dump(KERN_WARNING, "cio:  ", DUMP_PREFIX_NONE, 16, 1,
 
78
                               (void *)(addr_t)orb->cmd.cpa,
 
79
                               sizeof(struct ccw1), 0);
 
80
        }
 
81
        printk(KERN_WARNING "cio: ccw device state: %d\n",
 
82
               cdev->private->state);
 
83
        printk(KERN_WARNING "cio: store subchannel returned: cc=%d\n", cc);
 
84
        printk(KERN_WARNING "cio: schib:\n");
 
85
        print_hex_dump(KERN_WARNING, "cio:  ", DUMP_PREFIX_NONE, 16, 1,
 
86
                       &schib, sizeof(schib), 0);
 
87
        printk(KERN_WARNING "cio: ccw device flags:\n");
 
88
        print_hex_dump(KERN_WARNING, "cio:  ", DUMP_PREFIX_NONE, 16, 1,
 
89
                       &cdev->private->flags, sizeof(cdev->private->flags), 0);
 
90
}
 
91
 
 
92
/*
 
93
 * Timeout function. It just triggers a DEV_EVENT_TIMEOUT.
 
94
 */
 
95
static void
 
96
ccw_device_timeout(unsigned long data)
 
97
{
 
98
        struct ccw_device *cdev;
 
99
 
 
100
        cdev = (struct ccw_device *) data;
 
101
        spin_lock_irq(cdev->ccwlock);
 
102
        if (timeout_log_enabled)
 
103
                ccw_timeout_log(cdev);
 
104
        dev_fsm_event(cdev, DEV_EVENT_TIMEOUT);
 
105
        spin_unlock_irq(cdev->ccwlock);
 
106
}
 
107
 
 
108
/*
 
109
 * Set timeout
 
110
 */
 
111
void
 
112
ccw_device_set_timeout(struct ccw_device *cdev, int expires)
 
113
{
 
114
        if (expires == 0) {
 
115
                del_timer(&cdev->private->timer);
 
116
                return;
 
117
        }
 
118
        if (timer_pending(&cdev->private->timer)) {
 
119
                if (mod_timer(&cdev->private->timer, jiffies + expires))
 
120
                        return;
 
121
        }
 
122
        cdev->private->timer.function = ccw_device_timeout;
 
123
        cdev->private->timer.data = (unsigned long) cdev;
 
124
        cdev->private->timer.expires = jiffies + expires;
 
125
        add_timer(&cdev->private->timer);
 
126
}
 
127
 
 
128
/*
 
129
 * Cancel running i/o. This is called repeatedly since halt/clear are
 
130
 * asynchronous operations. We do one try with cio_cancel, two tries
 
131
 * with cio_halt, 255 tries with cio_clear. If everythings fails panic.
 
132
 * Returns 0 if device now idle, -ENODEV for device not operational and
 
133
 * -EBUSY if an interrupt is expected (either from halt/clear or from a
 
134
 * status pending).
 
135
 */
 
136
int
 
137
ccw_device_cancel_halt_clear(struct ccw_device *cdev)
 
138
{
 
139
        struct subchannel *sch;
 
140
        int ret;
 
141
 
 
142
        sch = to_subchannel(cdev->dev.parent);
 
143
        if (cio_update_schib(sch))
 
144
                return -ENODEV; 
 
145
        if (!sch->schib.pmcw.ena)
 
146
                /* Not operational -> done. */
 
147
                return 0;
 
148
        /* Stage 1: cancel io. */
 
149
        if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_HALT_PEND) &&
 
150
            !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) {
 
151
                if (!scsw_is_tm(&sch->schib.scsw)) {
 
152
                        ret = cio_cancel(sch);
 
153
                        if (ret != -EINVAL)
 
154
                                return ret;
 
155
                }
 
156
                /* cancel io unsuccessful or not applicable (transport mode).
 
157
                 * Continue with asynchronous instructions. */
 
158
                cdev->private->iretry = 3;      /* 3 halt retries. */
 
159
        }
 
160
        if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) {
 
161
                /* Stage 2: halt io. */
 
162
                if (cdev->private->iretry) {
 
163
                        cdev->private->iretry--;
 
164
                        ret = cio_halt(sch);
 
165
                        if (ret != -EBUSY)
 
166
                                return (ret == 0) ? -EBUSY : ret;
 
167
                }
 
168
                /* halt io unsuccessful. */
 
169
                cdev->private->iretry = 255;    /* 255 clear retries. */
 
170
        }
 
171
        /* Stage 3: clear io. */
 
172
        if (cdev->private->iretry) {
 
173
                cdev->private->iretry--;
 
174
                ret = cio_clear (sch);
 
175
                return (ret == 0) ? -EBUSY : ret;
 
176
        }
 
177
        /* Function was unsuccessful */
 
178
        CIO_MSG_EVENT(0, "0.%x.%04x: could not stop I/O\n",
 
179
                      cdev->private->dev_id.ssid, cdev->private->dev_id.devno);
 
180
        return -EIO;
 
181
}
 
182
 
 
183
void ccw_device_update_sense_data(struct ccw_device *cdev)
 
184
{
 
185
        memset(&cdev->id, 0, sizeof(cdev->id));
 
186
        cdev->id.cu_type   = cdev->private->senseid.cu_type;
 
187
        cdev->id.cu_model  = cdev->private->senseid.cu_model;
 
188
        cdev->id.dev_type  = cdev->private->senseid.dev_type;
 
189
        cdev->id.dev_model = cdev->private->senseid.dev_model;
 
190
}
 
191
 
 
192
int ccw_device_test_sense_data(struct ccw_device *cdev)
 
193
{
 
194
        return cdev->id.cu_type == cdev->private->senseid.cu_type &&
 
195
                cdev->id.cu_model == cdev->private->senseid.cu_model &&
 
196
                cdev->id.dev_type == cdev->private->senseid.dev_type &&
 
197
                cdev->id.dev_model == cdev->private->senseid.dev_model;
 
198
}
 
199
 
 
200
/*
 
201
 * The machine won't give us any notification by machine check if a chpid has
 
202
 * been varied online on the SE so we have to find out by magic (i. e. driving
 
203
 * the channel subsystem to device selection and updating our path masks).
 
204
 */
 
205
static void
 
206
__recover_lost_chpids(struct subchannel *sch, int old_lpm)
 
207
{
 
208
        int mask, i;
 
209
        struct chp_id chpid;
 
210
 
 
211
        chp_id_init(&chpid);
 
212
        for (i = 0; i<8; i++) {
 
213
                mask = 0x80 >> i;
 
214
                if (!(sch->lpm & mask))
 
215
                        continue;
 
216
                if (old_lpm & mask)
 
217
                        continue;
 
218
                chpid.id = sch->schib.pmcw.chpid[i];
 
219
                if (!chp_is_registered(chpid))
 
220
                        css_schedule_eval_all();
 
221
        }
 
222
}
 
223
 
 
224
/*
 
225
 * Stop device recognition.
 
226
 */
 
227
static void
 
228
ccw_device_recog_done(struct ccw_device *cdev, int state)
 
229
{
 
230
        struct subchannel *sch;
 
231
        int old_lpm;
 
232
 
 
233
        sch = to_subchannel(cdev->dev.parent);
 
234
 
 
235
        if (cio_disable_subchannel(sch))
 
236
                state = DEV_STATE_NOT_OPER;
 
237
        /*
 
238
         * Now that we tried recognition, we have performed device selection
 
239
         * through ssch() and the path information is up to date.
 
240
         */
 
241
        old_lpm = sch->lpm;
 
242
 
 
243
        /* Check since device may again have become not operational. */
 
244
        if (cio_update_schib(sch))
 
245
                state = DEV_STATE_NOT_OPER;
 
246
        else
 
247
                sch->lpm = sch->schib.pmcw.pam & sch->opm;
 
248
 
 
249
        if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID)
 
250
                /* Force reprobe on all chpids. */
 
251
                old_lpm = 0;
 
252
        if (sch->lpm != old_lpm)
 
253
                __recover_lost_chpids(sch, old_lpm);
 
254
        if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID &&
 
255
            (state == DEV_STATE_NOT_OPER || state == DEV_STATE_BOXED)) {
 
256
                cdev->private->flags.recog_done = 1;
 
257
                cdev->private->state = DEV_STATE_DISCONNECTED;
 
258
                wake_up(&cdev->private->wait_q);
 
259
                return;
 
260
        }
 
261
        if (cdev->private->flags.resuming) {
 
262
                cdev->private->state = state;
 
263
                cdev->private->flags.recog_done = 1;
 
264
                wake_up(&cdev->private->wait_q);
 
265
                return;
 
266
        }
 
267
        switch (state) {
 
268
        case DEV_STATE_NOT_OPER:
 
269
                break;
 
270
        case DEV_STATE_OFFLINE:
 
271
                if (!cdev->online) {
 
272
                        ccw_device_update_sense_data(cdev);
 
273
                        break;
 
274
                }
 
275
                cdev->private->state = DEV_STATE_OFFLINE;
 
276
                cdev->private->flags.recog_done = 1;
 
277
                if (ccw_device_test_sense_data(cdev)) {
 
278
                        cdev->private->flags.donotify = 1;
 
279
                        ccw_device_online(cdev);
 
280
                        wake_up(&cdev->private->wait_q);
 
281
                } else {
 
282
                        ccw_device_update_sense_data(cdev);
 
283
                        ccw_device_sched_todo(cdev, CDEV_TODO_REBIND);
 
284
                }
 
285
                return;
 
286
        case DEV_STATE_BOXED:
 
287
                if (cdev->id.cu_type != 0) { /* device was recognized before */
 
288
                        cdev->private->flags.recog_done = 1;
 
289
                        cdev->private->state = DEV_STATE_BOXED;
 
290
                        wake_up(&cdev->private->wait_q);
 
291
                        return;
 
292
                }
 
293
                break;
 
294
        }
 
295
        cdev->private->state = state;
 
296
        io_subchannel_recog_done(cdev);
 
297
        wake_up(&cdev->private->wait_q);
 
298
}
 
299
 
 
300
/*
 
301
 * Function called from device_id.c after sense id has completed.
 
302
 */
 
303
void
 
304
ccw_device_sense_id_done(struct ccw_device *cdev, int err)
 
305
{
 
306
        switch (err) {
 
307
        case 0:
 
308
                ccw_device_recog_done(cdev, DEV_STATE_OFFLINE);
 
309
                break;
 
310
        case -ETIME:            /* Sense id stopped by timeout. */
 
311
                ccw_device_recog_done(cdev, DEV_STATE_BOXED);
 
312
                break;
 
313
        default:
 
314
                ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
 
315
                break;
 
316
        }
 
317
}
 
318
 
 
319
/**
 
320
  * ccw_device_notify() - inform the device's driver about an event
 
321
  * @cdev: device for which an event occurred
 
322
  * @event: event that occurred
 
323
  *
 
324
  * Returns:
 
325
  *   -%EINVAL if the device is offline or has no driver.
 
326
  *   -%EOPNOTSUPP if the device's driver has no notifier registered.
 
327
  *   %NOTIFY_OK if the driver wants to keep the device.
 
328
  *   %NOTIFY_BAD if the driver doesn't want to keep the device.
 
329
  */
 
330
int ccw_device_notify(struct ccw_device *cdev, int event)
 
331
{
 
332
        int ret = -EINVAL;
 
333
 
 
334
        if (!cdev->drv)
 
335
                goto out;
 
336
        if (!cdev->online)
 
337
                goto out;
 
338
        CIO_MSG_EVENT(2, "notify called for 0.%x.%04x, event=%d\n",
 
339
                      cdev->private->dev_id.ssid, cdev->private->dev_id.devno,
 
340
                      event);
 
341
        if (!cdev->drv->notify) {
 
342
                ret = -EOPNOTSUPP;
 
343
                goto out;
 
344
        }
 
345
        if (cdev->drv->notify(cdev, event))
 
346
                ret = NOTIFY_OK;
 
347
        else
 
348
                ret = NOTIFY_BAD;
 
349
out:
 
350
        return ret;
 
351
}
 
352
 
 
353
static void ccw_device_oper_notify(struct ccw_device *cdev)
 
354
{
 
355
        struct subchannel *sch = to_subchannel(cdev->dev.parent);
 
356
 
 
357
        if (ccw_device_notify(cdev, CIO_OPER) == NOTIFY_OK) {
 
358
                /* Reenable channel measurements, if needed. */
 
359
                ccw_device_sched_todo(cdev, CDEV_TODO_ENABLE_CMF);
 
360
                /* Save indication for new paths. */
 
361
                cdev->private->path_new_mask = sch->vpm;
 
362
                return;
 
363
        }
 
364
        /* Driver doesn't want device back. */
 
365
        ccw_device_set_notoper(cdev);
 
366
        ccw_device_sched_todo(cdev, CDEV_TODO_REBIND);
 
367
}
 
368
 
 
369
/*
 
370
 * Finished with online/offline processing.
 
371
 */
 
372
static void
 
373
ccw_device_done(struct ccw_device *cdev, int state)
 
374
{
 
375
        struct subchannel *sch;
 
376
 
 
377
        sch = to_subchannel(cdev->dev.parent);
 
378
 
 
379
        ccw_device_set_timeout(cdev, 0);
 
380
 
 
381
        if (state != DEV_STATE_ONLINE)
 
382
                cio_disable_subchannel(sch);
 
383
 
 
384
        /* Reset device status. */
 
385
        memset(&cdev->private->irb, 0, sizeof(struct irb));
 
386
 
 
387
        cdev->private->state = state;
 
388
 
 
389
        switch (state) {
 
390
        case DEV_STATE_BOXED:
 
391
                CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
 
392
                              cdev->private->dev_id.devno, sch->schid.sch_no);
 
393
                if (cdev->online &&
 
394
                    ccw_device_notify(cdev, CIO_BOXED) != NOTIFY_OK)
 
395
                        ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 
396
                cdev->private->flags.donotify = 0;
 
397
                break;
 
398
        case DEV_STATE_NOT_OPER:
 
399
                CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n",
 
400
                              cdev->private->dev_id.devno, sch->schid.sch_no);
 
401
                if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
 
402
                        ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 
403
                else
 
404
                        ccw_device_set_disconnected(cdev);
 
405
                cdev->private->flags.donotify = 0;
 
406
                break;
 
407
        case DEV_STATE_DISCONNECTED:
 
408
                CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel "
 
409
                              "%04x\n", cdev->private->dev_id.devno,
 
410
                              sch->schid.sch_no);
 
411
                if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK) {
 
412
                        cdev->private->state = DEV_STATE_NOT_OPER;
 
413
                        ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 
414
                } else
 
415
                        ccw_device_set_disconnected(cdev);
 
416
                cdev->private->flags.donotify = 0;
 
417
                break;
 
418
        default:
 
419
                break;
 
420
        }
 
421
 
 
422
        if (cdev->private->flags.donotify) {
 
423
                cdev->private->flags.donotify = 0;
 
424
                ccw_device_oper_notify(cdev);
 
425
        }
 
426
        wake_up(&cdev->private->wait_q);
 
427
}
 
428
 
 
429
/*
 
430
 * Start device recognition.
 
431
 */
 
432
void ccw_device_recognition(struct ccw_device *cdev)
 
433
{
 
434
        struct subchannel *sch = to_subchannel(cdev->dev.parent);
 
435
 
 
436
        /*
 
437
         * We used to start here with a sense pgid to find out whether a device
 
438
         * is locked by someone else. Unfortunately, the sense pgid command
 
439
         * code has other meanings on devices predating the path grouping
 
440
         * algorithm, so we start with sense id and box the device after an
 
441
         * timeout (or if sense pgid during path verification detects the device
 
442
         * is locked, as may happen on newer devices).
 
443
         */
 
444
        cdev->private->flags.recog_done = 0;
 
445
        cdev->private->state = DEV_STATE_SENSE_ID;
 
446
        if (cio_enable_subchannel(sch, (u32) (addr_t) sch)) {
 
447
                ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
 
448
                return;
 
449
        }
 
450
        ccw_device_sense_id_start(cdev);
 
451
}
 
452
 
 
453
/*
 
454
 * Handle events for states that use the ccw request infrastructure.
 
455
 */
 
456
static void ccw_device_request_event(struct ccw_device *cdev, enum dev_event e)
 
457
{
 
458
        switch (e) {
 
459
        case DEV_EVENT_NOTOPER:
 
460
                ccw_request_notoper(cdev);
 
461
                break;
 
462
        case DEV_EVENT_INTERRUPT:
 
463
                ccw_request_handler(cdev);
 
464
                break;
 
465
        case DEV_EVENT_TIMEOUT:
 
466
                ccw_request_timeout(cdev);
 
467
                break;
 
468
        default:
 
469
                break;
 
470
        }
 
471
}
 
472
 
 
473
static void ccw_device_report_path_events(struct ccw_device *cdev)
 
474
{
 
475
        struct subchannel *sch = to_subchannel(cdev->dev.parent);
 
476
        int path_event[8];
 
477
        int chp, mask;
 
478
 
 
479
        for (chp = 0, mask = 0x80; chp < 8; chp++, mask >>= 1) {
 
480
                path_event[chp] = PE_NONE;
 
481
                if (mask & cdev->private->path_gone_mask & ~(sch->vpm))
 
482
                        path_event[chp] |= PE_PATH_GONE;
 
483
                if (mask & cdev->private->path_new_mask & sch->vpm)
 
484
                        path_event[chp] |= PE_PATH_AVAILABLE;
 
485
                if (mask & cdev->private->pgid_reset_mask & sch->vpm)
 
486
                        path_event[chp] |= PE_PATHGROUP_ESTABLISHED;
 
487
        }
 
488
        if (cdev->online && cdev->drv->path_event)
 
489
                cdev->drv->path_event(cdev, path_event);
 
490
}
 
491
 
 
492
static void ccw_device_reset_path_events(struct ccw_device *cdev)
 
493
{
 
494
        cdev->private->path_gone_mask = 0;
 
495
        cdev->private->path_new_mask = 0;
 
496
        cdev->private->pgid_reset_mask = 0;
 
497
}
 
498
 
 
499
static void create_fake_irb(struct irb *irb, int type)
 
500
{
 
501
        memset(irb, 0, sizeof(*irb));
 
502
        if (type == FAKE_CMD_IRB) {
 
503
                struct cmd_scsw *scsw = &irb->scsw.cmd;
 
504
                scsw->cc = 1;
 
505
                scsw->fctl = SCSW_FCTL_START_FUNC;
 
506
                scsw->actl = SCSW_ACTL_START_PEND;
 
507
                scsw->stctl = SCSW_STCTL_STATUS_PEND;
 
508
        } else if (type == FAKE_TM_IRB) {
 
509
                struct tm_scsw *scsw = &irb->scsw.tm;
 
510
                scsw->x = 1;
 
511
                scsw->cc = 1;
 
512
                scsw->fctl = SCSW_FCTL_START_FUNC;
 
513
                scsw->actl = SCSW_ACTL_START_PEND;
 
514
                scsw->stctl = SCSW_STCTL_STATUS_PEND;
 
515
        }
 
516
}
 
517
 
 
518
void ccw_device_verify_done(struct ccw_device *cdev, int err)
 
519
{
 
520
        struct subchannel *sch;
 
521
 
 
522
        sch = to_subchannel(cdev->dev.parent);
 
523
        /* Update schib - pom may have changed. */
 
524
        if (cio_update_schib(sch)) {
 
525
                err = -ENODEV;
 
526
                goto callback;
 
527
        }
 
528
        /* Update lpm with verified path mask. */
 
529
        sch->lpm = sch->vpm;
 
530
        /* Repeat path verification? */
 
531
        if (cdev->private->flags.doverify) {
 
532
                ccw_device_verify_start(cdev);
 
533
                return;
 
534
        }
 
535
callback:
 
536
        switch (err) {
 
537
        case 0:
 
538
                ccw_device_done(cdev, DEV_STATE_ONLINE);
 
539
                /* Deliver fake irb to device driver, if needed. */
 
540
                if (cdev->private->flags.fake_irb) {
 
541
                        create_fake_irb(&cdev->private->irb,
 
542
                                        cdev->private->flags.fake_irb);
 
543
                        cdev->private->flags.fake_irb = 0;
 
544
                        if (cdev->handler)
 
545
                                cdev->handler(cdev, cdev->private->intparm,
 
546
                                              &cdev->private->irb);
 
547
                        memset(&cdev->private->irb, 0, sizeof(struct irb));
 
548
                }
 
549
                ccw_device_report_path_events(cdev);
 
550
                break;
 
551
        case -ETIME:
 
552
        case -EUSERS:
 
553
                /* Reset oper notify indication after verify error. */
 
554
                cdev->private->flags.donotify = 0;
 
555
                ccw_device_done(cdev, DEV_STATE_BOXED);
 
556
                break;
 
557
        case -EACCES:
 
558
                /* Reset oper notify indication after verify error. */
 
559
                cdev->private->flags.donotify = 0;
 
560
                ccw_device_done(cdev, DEV_STATE_DISCONNECTED);
 
561
                break;
 
562
        default:
 
563
                /* Reset oper notify indication after verify error. */
 
564
                cdev->private->flags.donotify = 0;
 
565
                ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 
566
                break;
 
567
        }
 
568
        ccw_device_reset_path_events(cdev);
 
569
}
 
570
 
 
571
/*
 
572
 * Get device online.
 
573
 */
 
574
int
 
575
ccw_device_online(struct ccw_device *cdev)
 
576
{
 
577
        struct subchannel *sch;
 
578
        int ret;
 
579
 
 
580
        if ((cdev->private->state != DEV_STATE_OFFLINE) &&
 
581
            (cdev->private->state != DEV_STATE_BOXED))
 
582
                return -EINVAL;
 
583
        sch = to_subchannel(cdev->dev.parent);
 
584
        ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
 
585
        if (ret != 0) {
 
586
                /* Couldn't enable the subchannel for i/o. Sick device. */
 
587
                if (ret == -ENODEV)
 
588
                        dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 
589
                return ret;
 
590
        }
 
591
        /* Start initial path verification. */
 
592
        cdev->private->state = DEV_STATE_VERIFY;
 
593
        ccw_device_verify_start(cdev);
 
594
        return 0;
 
595
}
 
596
 
 
597
void
 
598
ccw_device_disband_done(struct ccw_device *cdev, int err)
 
599
{
 
600
        switch (err) {
 
601
        case 0:
 
602
                ccw_device_done(cdev, DEV_STATE_OFFLINE);
 
603
                break;
 
604
        case -ETIME:
 
605
                ccw_device_done(cdev, DEV_STATE_BOXED);
 
606
                break;
 
607
        default:
 
608
                cdev->private->flags.donotify = 0;
 
609
                ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 
610
                break;
 
611
        }
 
612
}
 
613
 
 
614
/*
 
615
 * Shutdown device.
 
616
 */
 
617
int
 
618
ccw_device_offline(struct ccw_device *cdev)
 
619
{
 
620
        struct subchannel *sch;
 
621
 
 
622
        /* Allow ccw_device_offline while disconnected. */
 
623
        if (cdev->private->state == DEV_STATE_DISCONNECTED ||
 
624
            cdev->private->state == DEV_STATE_NOT_OPER) {
 
625
                cdev->private->flags.donotify = 0;
 
626
                ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 
627
                return 0;
 
628
        }
 
629
        if (cdev->private->state == DEV_STATE_BOXED) {
 
630
                ccw_device_done(cdev, DEV_STATE_BOXED);
 
631
                return 0;
 
632
        }
 
633
        if (ccw_device_is_orphan(cdev)) {
 
634
                ccw_device_done(cdev, DEV_STATE_OFFLINE);
 
635
                return 0;
 
636
        }
 
637
        sch = to_subchannel(cdev->dev.parent);
 
638
        if (cio_update_schib(sch))
 
639
                return -ENODEV;
 
640
        if (scsw_actl(&sch->schib.scsw) != 0)
 
641
                return -EBUSY;
 
642
        if (cdev->private->state != DEV_STATE_ONLINE)
 
643
                return -EINVAL;
 
644
        /* Are we doing path grouping? */
 
645
        if (!cdev->private->flags.pgroup) {
 
646
                /* No, set state offline immediately. */
 
647
                ccw_device_done(cdev, DEV_STATE_OFFLINE);
 
648
                return 0;
 
649
        }
 
650
        /* Start Set Path Group commands. */
 
651
        cdev->private->state = DEV_STATE_DISBAND_PGID;
 
652
        ccw_device_disband_start(cdev);
 
653
        return 0;
 
654
}
 
655
 
 
656
/*
 
657
 * Handle not operational event in non-special state.
 
658
 */
 
659
static void ccw_device_generic_notoper(struct ccw_device *cdev,
 
660
                                       enum dev_event dev_event)
 
661
{
 
662
        if (ccw_device_notify(cdev, CIO_GONE) != NOTIFY_OK)
 
663
                ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
 
664
        else
 
665
                ccw_device_set_disconnected(cdev);
 
666
}
 
667
 
 
668
/*
 
669
 * Handle path verification event in offline state.
 
670
 */
 
671
static void ccw_device_offline_verify(struct ccw_device *cdev,
 
672
                                      enum dev_event dev_event)
 
673
{
 
674
        struct subchannel *sch = to_subchannel(cdev->dev.parent);
 
675
 
 
676
        css_schedule_eval(sch->schid);
 
677
}
 
678
 
 
679
/*
 
680
 * Handle path verification event.
 
681
 */
 
682
static void
 
683
ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event)
 
684
{
 
685
        struct subchannel *sch;
 
686
 
 
687
        if (cdev->private->state == DEV_STATE_W4SENSE) {
 
688
                cdev->private->flags.doverify = 1;
 
689
                return;
 
690
        }
 
691
        sch = to_subchannel(cdev->dev.parent);
 
692
        /*
 
693
         * Since we might not just be coming from an interrupt from the
 
694
         * subchannel we have to update the schib.
 
695
         */
 
696
        if (cio_update_schib(sch)) {
 
697
                ccw_device_verify_done(cdev, -ENODEV);
 
698
                return;
 
699
        }
 
700
 
 
701
        if (scsw_actl(&sch->schib.scsw) != 0 ||
 
702
            (scsw_stctl(&sch->schib.scsw) & SCSW_STCTL_STATUS_PEND) ||
 
703
            (scsw_stctl(&cdev->private->irb.scsw) & SCSW_STCTL_STATUS_PEND)) {
 
704
                /*
 
705
                 * No final status yet or final status not yet delivered
 
706
                 * to the device driver. Can't do path verification now,
 
707
                 * delay until final status was delivered.
 
708
                 */
 
709
                cdev->private->flags.doverify = 1;
 
710
                return;
 
711
        }
 
712
        /* Device is idle, we can do the path verification. */
 
713
        cdev->private->state = DEV_STATE_VERIFY;
 
714
        ccw_device_verify_start(cdev);
 
715
}
 
716
 
 
717
/*
 
718
 * Handle path verification event in boxed state.
 
719
 */
 
720
static void ccw_device_boxed_verify(struct ccw_device *cdev,
 
721
                                    enum dev_event dev_event)
 
722
{
 
723
        struct subchannel *sch = to_subchannel(cdev->dev.parent);
 
724
 
 
725
        if (cdev->online) {
 
726
                if (cio_enable_subchannel(sch, (u32) (addr_t) sch))
 
727
                        ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 
728
                else
 
729
                        ccw_device_online_verify(cdev, dev_event);
 
730
        } else
 
731
                css_schedule_eval(sch->schid);
 
732
}
 
733
 
 
734
/*
 
735
 * Got an interrupt for a normal io (state online).
 
736
 */
 
737
static void
 
738
ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event)
 
739
{
 
740
        struct irb *irb;
 
741
        int is_cmd;
 
742
 
 
743
        irb = (struct irb *)&S390_lowcore.irb;
 
744
        is_cmd = !scsw_is_tm(&irb->scsw);
 
745
        /* Check for unsolicited interrupt. */
 
746
        if (!scsw_is_solicited(&irb->scsw)) {
 
747
                if (is_cmd && (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
 
748
                    !irb->esw.esw0.erw.cons) {
 
749
                        /* Unit check but no sense data. Need basic sense. */
 
750
                        if (ccw_device_do_sense(cdev, irb) != 0)
 
751
                                goto call_handler_unsol;
 
752
                        memcpy(&cdev->private->irb, irb, sizeof(struct irb));
 
753
                        cdev->private->state = DEV_STATE_W4SENSE;
 
754
                        cdev->private->intparm = 0;
 
755
                        return;
 
756
                }
 
757
call_handler_unsol:
 
758
                if (cdev->handler)
 
759
                        cdev->handler (cdev, 0, irb);
 
760
                if (cdev->private->flags.doverify)
 
761
                        ccw_device_online_verify(cdev, 0);
 
762
                return;
 
763
        }
 
764
        /* Accumulate status and find out if a basic sense is needed. */
 
765
        ccw_device_accumulate_irb(cdev, irb);
 
766
        if (is_cmd && cdev->private->flags.dosense) {
 
767
                if (ccw_device_do_sense(cdev, irb) == 0) {
 
768
                        cdev->private->state = DEV_STATE_W4SENSE;
 
769
                }
 
770
                return;
 
771
        }
 
772
        /* Call the handler. */
 
773
        if (ccw_device_call_handler(cdev) && cdev->private->flags.doverify)
 
774
                /* Start delayed path verification. */
 
775
                ccw_device_online_verify(cdev, 0);
 
776
}
 
777
 
 
778
/*
 
779
 * Got an timeout in online state.
 
780
 */
 
781
static void
 
782
ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event)
 
783
{
 
784
        int ret;
 
785
 
 
786
        ccw_device_set_timeout(cdev, 0);
 
787
        cdev->private->iretry = 255;
 
788
        ret = ccw_device_cancel_halt_clear(cdev);
 
789
        if (ret == -EBUSY) {
 
790
                ccw_device_set_timeout(cdev, 3*HZ);
 
791
                cdev->private->state = DEV_STATE_TIMEOUT_KILL;
 
792
                return;
 
793
        }
 
794
        if (ret)
 
795
                dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 
796
        else if (cdev->handler)
 
797
                cdev->handler(cdev, cdev->private->intparm,
 
798
                              ERR_PTR(-ETIMEDOUT));
 
799
}
 
800
 
 
801
/*
 
802
 * Got an interrupt for a basic sense.
 
803
 */
 
804
static void
 
805
ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
 
806
{
 
807
        struct irb *irb;
 
808
 
 
809
        irb = (struct irb *)&S390_lowcore.irb;
 
810
        /* Check for unsolicited interrupt. */
 
811
        if (scsw_stctl(&irb->scsw) ==
 
812
            (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
 
813
                if (scsw_cc(&irb->scsw) == 1)
 
814
                        /* Basic sense hasn't started. Try again. */
 
815
                        ccw_device_do_sense(cdev, irb);
 
816
                else {
 
817
                        CIO_MSG_EVENT(0, "0.%x.%04x: unsolicited "
 
818
                                      "interrupt during w4sense...\n",
 
819
                                      cdev->private->dev_id.ssid,
 
820
                                      cdev->private->dev_id.devno);
 
821
                        if (cdev->handler)
 
822
                                cdev->handler (cdev, 0, irb);
 
823
                }
 
824
                return;
 
825
        }
 
826
        /*
 
827
         * Check if a halt or clear has been issued in the meanwhile. If yes,
 
828
         * only deliver the halt/clear interrupt to the device driver as if it
 
829
         * had killed the original request.
 
830
         */
 
831
        if (scsw_fctl(&irb->scsw) &
 
832
            (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) {
 
833
                cdev->private->flags.dosense = 0;
 
834
                memset(&cdev->private->irb, 0, sizeof(struct irb));
 
835
                ccw_device_accumulate_irb(cdev, irb);
 
836
                goto call_handler;
 
837
        }
 
838
        /* Add basic sense info to irb. */
 
839
        ccw_device_accumulate_basic_sense(cdev, irb);
 
840
        if (cdev->private->flags.dosense) {
 
841
                /* Another basic sense is needed. */
 
842
                ccw_device_do_sense(cdev, irb);
 
843
                return;
 
844
        }
 
845
call_handler:
 
846
        cdev->private->state = DEV_STATE_ONLINE;
 
847
        /* In case sensing interfered with setting the device online */
 
848
        wake_up(&cdev->private->wait_q);
 
849
        /* Call the handler. */
 
850
        if (ccw_device_call_handler(cdev) && cdev->private->flags.doverify)
 
851
                /* Start delayed path verification. */
 
852
                ccw_device_online_verify(cdev, 0);
 
853
}
 
854
 
 
855
static void
 
856
ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
 
857
{
 
858
        ccw_device_set_timeout(cdev, 0);
 
859
        /* Start delayed path verification. */
 
860
        ccw_device_online_verify(cdev, 0);
 
861
        /* OK, i/o is dead now. Call interrupt handler. */
 
862
        if (cdev->handler)
 
863
                cdev->handler(cdev, cdev->private->intparm,
 
864
                              ERR_PTR(-EIO));
 
865
}
 
866
 
 
867
static void
 
868
ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event)
 
869
{
 
870
        int ret;
 
871
 
 
872
        ret = ccw_device_cancel_halt_clear(cdev);
 
873
        if (ret == -EBUSY) {
 
874
                ccw_device_set_timeout(cdev, 3*HZ);
 
875
                return;
 
876
        }
 
877
        /* Start delayed path verification. */
 
878
        ccw_device_online_verify(cdev, 0);
 
879
        if (cdev->handler)
 
880
                cdev->handler(cdev, cdev->private->intparm,
 
881
                              ERR_PTR(-EIO));
 
882
}
 
883
 
 
884
void ccw_device_kill_io(struct ccw_device *cdev)
 
885
{
 
886
        int ret;
 
887
 
 
888
        cdev->private->iretry = 255;
 
889
        ret = ccw_device_cancel_halt_clear(cdev);
 
890
        if (ret == -EBUSY) {
 
891
                ccw_device_set_timeout(cdev, 3*HZ);
 
892
                cdev->private->state = DEV_STATE_TIMEOUT_KILL;
 
893
                return;
 
894
        }
 
895
        /* Start delayed path verification. */
 
896
        ccw_device_online_verify(cdev, 0);
 
897
        if (cdev->handler)
 
898
                cdev->handler(cdev, cdev->private->intparm,
 
899
                              ERR_PTR(-EIO));
 
900
}
 
901
 
 
902
static void
 
903
ccw_device_delay_verify(struct ccw_device *cdev, enum dev_event dev_event)
 
904
{
 
905
        /* Start verification after current task finished. */
 
906
        cdev->private->flags.doverify = 1;
 
907
}
 
908
 
 
909
static void
 
910
ccw_device_start_id(struct ccw_device *cdev, enum dev_event dev_event)
 
911
{
 
912
        struct subchannel *sch;
 
913
 
 
914
        sch = to_subchannel(cdev->dev.parent);
 
915
        if (cio_enable_subchannel(sch, (u32)(addr_t)sch) != 0)
 
916
                /* Couldn't enable the subchannel for i/o. Sick device. */
 
917
                return;
 
918
        cdev->private->state = DEV_STATE_DISCONNECTED_SENSE_ID;
 
919
        ccw_device_sense_id_start(cdev);
 
920
}
 
921
 
 
922
void ccw_device_trigger_reprobe(struct ccw_device *cdev)
 
923
{
 
924
        struct subchannel *sch;
 
925
 
 
926
        if (cdev->private->state != DEV_STATE_DISCONNECTED)
 
927
                return;
 
928
 
 
929
        sch = to_subchannel(cdev->dev.parent);
 
930
        /* Update some values. */
 
931
        if (cio_update_schib(sch))
 
932
                return;
 
933
        /*
 
934
         * The pim, pam, pom values may not be accurate, but they are the best
 
935
         * we have before performing device selection :/
 
936
         */
 
937
        sch->lpm = sch->schib.pmcw.pam & sch->opm;
 
938
        /*
 
939
         * Use the initial configuration since we can't be shure that the old
 
940
         * paths are valid.
 
941
         */
 
942
        io_subchannel_init_config(sch);
 
943
        if (cio_commit_config(sch))
 
944
                return;
 
945
 
 
946
        /* We should also udate ssd info, but this has to wait. */
 
947
        /* Check if this is another device which appeared on the same sch. */
 
948
        if (sch->schib.pmcw.dev != cdev->private->dev_id.devno)
 
949
                css_schedule_eval(sch->schid);
 
950
        else
 
951
                ccw_device_start_id(cdev, 0);
 
952
}
 
953
 
 
954
static void ccw_device_disabled_irq(struct ccw_device *cdev,
 
955
                                    enum dev_event dev_event)
 
956
{
 
957
        struct subchannel *sch;
 
958
 
 
959
        sch = to_subchannel(cdev->dev.parent);
 
960
        /*
 
961
         * An interrupt in a disabled state means a previous disable was not
 
962
         * successful - should not happen, but we try to disable again.
 
963
         */
 
964
        cio_disable_subchannel(sch);
 
965
}
 
966
 
 
967
static void
 
968
ccw_device_change_cmfstate(struct ccw_device *cdev, enum dev_event dev_event)
 
969
{
 
970
        retry_set_schib(cdev);
 
971
        cdev->private->state = DEV_STATE_ONLINE;
 
972
        dev_fsm_event(cdev, dev_event);
 
973
}
 
974
 
 
975
static void ccw_device_update_cmfblock(struct ccw_device *cdev,
 
976
                                       enum dev_event dev_event)
 
977
{
 
978
        cmf_retry_copy_block(cdev);
 
979
        cdev->private->state = DEV_STATE_ONLINE;
 
980
        dev_fsm_event(cdev, dev_event);
 
981
}
 
982
 
 
983
static void
 
984
ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event)
 
985
{
 
986
        ccw_device_set_timeout(cdev, 0);
 
987
        cdev->private->state = DEV_STATE_NOT_OPER;
 
988
        wake_up(&cdev->private->wait_q);
 
989
}
 
990
 
 
991
static void
 
992
ccw_device_quiesce_timeout(struct ccw_device *cdev, enum dev_event dev_event)
 
993
{
 
994
        int ret;
 
995
 
 
996
        ret = ccw_device_cancel_halt_clear(cdev);
 
997
        if (ret == -EBUSY) {
 
998
                ccw_device_set_timeout(cdev, HZ/10);
 
999
        } else {
 
1000
                cdev->private->state = DEV_STATE_NOT_OPER;
 
1001
                wake_up(&cdev->private->wait_q);
 
1002
        }
 
1003
}
 
1004
 
 
1005
/*
 
1006
 * No operation action. This is used e.g. to ignore a timeout event in
 
1007
 * state offline.
 
1008
 */
 
1009
static void
 
1010
ccw_device_nop(struct ccw_device *cdev, enum dev_event dev_event)
 
1011
{
 
1012
}
 
1013
 
 
1014
/*
 
1015
 * device statemachine
 
1016
 */
 
1017
fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
 
1018
        [DEV_STATE_NOT_OPER] = {
 
1019
                [DEV_EVENT_NOTOPER]     = ccw_device_nop,
 
1020
                [DEV_EVENT_INTERRUPT]   = ccw_device_disabled_irq,
 
1021
                [DEV_EVENT_TIMEOUT]     = ccw_device_nop,
 
1022
                [DEV_EVENT_VERIFY]      = ccw_device_nop,
 
1023
        },
 
1024
        [DEV_STATE_SENSE_PGID] = {
 
1025
                [DEV_EVENT_NOTOPER]     = ccw_device_request_event,
 
1026
                [DEV_EVENT_INTERRUPT]   = ccw_device_request_event,
 
1027
                [DEV_EVENT_TIMEOUT]     = ccw_device_request_event,
 
1028
                [DEV_EVENT_VERIFY]      = ccw_device_nop,
 
1029
        },
 
1030
        [DEV_STATE_SENSE_ID] = {
 
1031
                [DEV_EVENT_NOTOPER]     = ccw_device_request_event,
 
1032
                [DEV_EVENT_INTERRUPT]   = ccw_device_request_event,
 
1033
                [DEV_EVENT_TIMEOUT]     = ccw_device_request_event,
 
1034
                [DEV_EVENT_VERIFY]      = ccw_device_nop,
 
1035
        },
 
1036
        [DEV_STATE_OFFLINE] = {
 
1037
                [DEV_EVENT_NOTOPER]     = ccw_device_generic_notoper,
 
1038
                [DEV_EVENT_INTERRUPT]   = ccw_device_disabled_irq,
 
1039
                [DEV_EVENT_TIMEOUT]     = ccw_device_nop,
 
1040
                [DEV_EVENT_VERIFY]      = ccw_device_offline_verify,
 
1041
        },
 
1042
        [DEV_STATE_VERIFY] = {
 
1043
                [DEV_EVENT_NOTOPER]     = ccw_device_request_event,
 
1044
                [DEV_EVENT_INTERRUPT]   = ccw_device_request_event,
 
1045
                [DEV_EVENT_TIMEOUT]     = ccw_device_request_event,
 
1046
                [DEV_EVENT_VERIFY]      = ccw_device_delay_verify,
 
1047
        },
 
1048
        [DEV_STATE_ONLINE] = {
 
1049
                [DEV_EVENT_NOTOPER]     = ccw_device_generic_notoper,
 
1050
                [DEV_EVENT_INTERRUPT]   = ccw_device_irq,
 
1051
                [DEV_EVENT_TIMEOUT]     = ccw_device_online_timeout,
 
1052
                [DEV_EVENT_VERIFY]      = ccw_device_online_verify,
 
1053
        },
 
1054
        [DEV_STATE_W4SENSE] = {
 
1055
                [DEV_EVENT_NOTOPER]     = ccw_device_generic_notoper,
 
1056
                [DEV_EVENT_INTERRUPT]   = ccw_device_w4sense,
 
1057
                [DEV_EVENT_TIMEOUT]     = ccw_device_nop,
 
1058
                [DEV_EVENT_VERIFY]      = ccw_device_online_verify,
 
1059
        },
 
1060
        [DEV_STATE_DISBAND_PGID] = {
 
1061
                [DEV_EVENT_NOTOPER]     = ccw_device_request_event,
 
1062
                [DEV_EVENT_INTERRUPT]   = ccw_device_request_event,
 
1063
                [DEV_EVENT_TIMEOUT]     = ccw_device_request_event,
 
1064
                [DEV_EVENT_VERIFY]      = ccw_device_nop,
 
1065
        },
 
1066
        [DEV_STATE_BOXED] = {
 
1067
                [DEV_EVENT_NOTOPER]     = ccw_device_generic_notoper,
 
1068
                [DEV_EVENT_INTERRUPT]   = ccw_device_nop,
 
1069
                [DEV_EVENT_TIMEOUT]     = ccw_device_nop,
 
1070
                [DEV_EVENT_VERIFY]      = ccw_device_boxed_verify,
 
1071
        },
 
1072
        /* states to wait for i/o completion before doing something */
 
1073
        [DEV_STATE_TIMEOUT_KILL] = {
 
1074
                [DEV_EVENT_NOTOPER]     = ccw_device_generic_notoper,
 
1075
                [DEV_EVENT_INTERRUPT]   = ccw_device_killing_irq,
 
1076
                [DEV_EVENT_TIMEOUT]     = ccw_device_killing_timeout,
 
1077
                [DEV_EVENT_VERIFY]      = ccw_device_nop, //FIXME
 
1078
        },
 
1079
        [DEV_STATE_QUIESCE] = {
 
1080
                [DEV_EVENT_NOTOPER]     = ccw_device_quiesce_done,
 
1081
                [DEV_EVENT_INTERRUPT]   = ccw_device_quiesce_done,
 
1082
                [DEV_EVENT_TIMEOUT]     = ccw_device_quiesce_timeout,
 
1083
                [DEV_EVENT_VERIFY]      = ccw_device_nop,
 
1084
        },
 
1085
        /* special states for devices gone not operational */
 
1086
        [DEV_STATE_DISCONNECTED] = {
 
1087
                [DEV_EVENT_NOTOPER]     = ccw_device_nop,
 
1088
                [DEV_EVENT_INTERRUPT]   = ccw_device_start_id,
 
1089
                [DEV_EVENT_TIMEOUT]     = ccw_device_nop,
 
1090
                [DEV_EVENT_VERIFY]      = ccw_device_start_id,
 
1091
        },
 
1092
        [DEV_STATE_DISCONNECTED_SENSE_ID] = {
 
1093
                [DEV_EVENT_NOTOPER]     = ccw_device_request_event,
 
1094
                [DEV_EVENT_INTERRUPT]   = ccw_device_request_event,
 
1095
                [DEV_EVENT_TIMEOUT]     = ccw_device_request_event,
 
1096
                [DEV_EVENT_VERIFY]      = ccw_device_nop,
 
1097
        },
 
1098
        [DEV_STATE_CMFCHANGE] = {
 
1099
                [DEV_EVENT_NOTOPER]     = ccw_device_change_cmfstate,
 
1100
                [DEV_EVENT_INTERRUPT]   = ccw_device_change_cmfstate,
 
1101
                [DEV_EVENT_TIMEOUT]     = ccw_device_change_cmfstate,
 
1102
                [DEV_EVENT_VERIFY]      = ccw_device_change_cmfstate,
 
1103
        },
 
1104
        [DEV_STATE_CMFUPDATE] = {
 
1105
                [DEV_EVENT_NOTOPER]     = ccw_device_update_cmfblock,
 
1106
                [DEV_EVENT_INTERRUPT]   = ccw_device_update_cmfblock,
 
1107
                [DEV_EVENT_TIMEOUT]     = ccw_device_update_cmfblock,
 
1108
                [DEV_EVENT_VERIFY]      = ccw_device_update_cmfblock,
 
1109
        },
 
1110
        [DEV_STATE_STEAL_LOCK] = {
 
1111
                [DEV_EVENT_NOTOPER]     = ccw_device_request_event,
 
1112
                [DEV_EVENT_INTERRUPT]   = ccw_device_request_event,
 
1113
                [DEV_EVENT_TIMEOUT]     = ccw_device_request_event,
 
1114
                [DEV_EVENT_VERIFY]      = ccw_device_nop,
 
1115
        },
 
1116
};
 
1117
 
 
1118
EXPORT_SYMBOL_GPL(ccw_device_set_timeout);