[S390] cio: introduce fcx enabled scsw format
[linux-block.git] / drivers / s390 / block / dasd_3990_erp.c
CommitLineData
138c014d 1/*
1da177e4 2 * File...........: linux/drivers/s390/block/dasd_3990_erp.c
138c014d 3 * Author(s)......: Horst Hummel <Horst.Hummel@de.ibm.com>
1da177e4
LT
4 * Holger Smolinski <Holger.Smolinski@de.ibm.com>
5 * Bugreports.to..: <Linux390@de.ibm.com>
6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
7 *
1da177e4
LT
8 */
9
10#include <linux/timer.h>
11#include <linux/slab.h>
12#include <asm/idals.h>
13#include <asm/todclk.h>
14
15#define PRINTK_HEADER "dasd_erp(3990): "
16
17#include "dasd_int.h"
18#include "dasd_eckd.h"
19
20
21struct DCTL_data {
22 unsigned char subcommand; /* e.g Inhibit Write, Enable Write,... */
23 unsigned char modifier; /* Subcommand modifier */
24 unsigned short res; /* reserved */
25} __attribute__ ((packed));
26
1da177e4 27/*
138c014d 28 *****************************************************************************
1da177e4 29 * SECTION ERP HANDLING
138c014d 30 *****************************************************************************
1da177e4
LT
31 */
32/*
138c014d 33 *****************************************************************************
1da177e4 34 * 24 and 32 byte sense ERP functions
138c014d 35 *****************************************************************************
1da177e4
LT
36 */
37
38/*
138c014d 39 * DASD_3990_ERP_CLEANUP
1da177e4
LT
40 *
41 * DESCRIPTION
42 * Removes the already build but not necessary ERP request and sets
43 * the status of the original cqr / erp to the given (final) status
44 *
45 * PARAMETER
46 * erp request to be blocked
138c014d 47 * final_status either DASD_CQR_DONE or DASD_CQR_FAILED
1da177e4
LT
48 *
49 * RETURN VALUES
138c014d 50 * cqr original cqr
1da177e4
LT
51 */
52static struct dasd_ccw_req *
53dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status)
54{
55 struct dasd_ccw_req *cqr = erp->refers;
56
8e09f215 57 dasd_free_erp_request(erp, erp->memdev);
1da177e4
LT
58 cqr->status = final_status;
59 return cqr;
60
61} /* end dasd_3990_erp_cleanup */
62
63/*
138c014d 64 * DASD_3990_ERP_BLOCK_QUEUE
1da177e4
LT
65 *
66 * DESCRIPTION
67 * Block the given device request queue to prevent from further
68 * processing until the started timer has expired or an related
69 * interrupt was received.
70 */
71static void
72dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
73{
74
8e09f215
SW
75 struct dasd_device *device = erp->startdev;
76 unsigned long flags;
1da177e4
LT
77
78 DEV_MESSAGE(KERN_INFO, device,
79 "blocking request queue for %is", expires/HZ);
80
8e09f215 81 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
1da177e4 82 device->stopped |= DASD_STOPPED_PENDING;
8e09f215
SW
83 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
84 erp->status = DASD_CQR_FILLED;
85 dasd_block_set_timer(device->block, expires);
1da177e4
LT
86}
87
88/*
138c014d 89 * DASD_3990_ERP_INT_REQ
1da177e4
LT
90 *
91 * DESCRIPTION
92 * Handles 'Intervention Required' error.
93 * This means either device offline or not installed.
94 *
95 * PARAMETER
96 * erp current erp
97 * RETURN VALUES
98 * erp modified erp
99 */
100static struct dasd_ccw_req *
101dasd_3990_erp_int_req(struct dasd_ccw_req * erp)
102{
103
8e09f215 104 struct dasd_device *device = erp->startdev;
1da177e4
LT
105
106 /* first time set initial retry counter and erp_function */
107 /* and retry once without blocking queue */
108 /* (this enables easier enqueing of the cqr) */
109 if (erp->function != dasd_3990_erp_int_req) {
110
111 erp->retries = 256;
112 erp->function = dasd_3990_erp_int_req;
113
114 } else {
115
116 /* issue a message and wait for 'device ready' interrupt */
117 DEV_MESSAGE(KERN_ERR, device, "%s",
118 "is offline or not installed - "
119 "INTERVENTION REQUIRED!!");
120
121 dasd_3990_erp_block_queue(erp, 60*HZ);
122 }
123
124 return erp;
125
126} /* end dasd_3990_erp_int_req */
127
128/*
138c014d 129 * DASD_3990_ERP_ALTERNATE_PATH
1da177e4
LT
130 *
131 * DESCRIPTION
132 * Repeat the operation on a different channel path.
133 * If all alternate paths have been tried, the request is posted with a
134 * permanent error.
135 *
136 * PARAMETER
137 * erp pointer to the current ERP
138 *
139 * RETURN VALUES
140 * erp modified pointer to the ERP
141 */
142static void
143dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
144{
8e09f215 145 struct dasd_device *device = erp->startdev;
1da177e4 146 __u8 opm;
8e09f215 147 unsigned long flags;
1da177e4
LT
148
149 /* try alternate valid path */
8e09f215 150 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
1da177e4 151 opm = ccw_device_get_path_mask(device->cdev);
8e09f215 152 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
1da177e4
LT
153 //FIXME: start with get_opm ?
154 if (erp->lpm == 0)
155 erp->lpm = LPM_ANYPATH & ~(erp->irb.esw.esw0.sublog.lpum);
156 else
157 erp->lpm &= ~(erp->irb.esw.esw0.sublog.lpum);
158
159 if ((erp->lpm & opm) != 0x00) {
160
161 DEV_MESSAGE(KERN_DEBUG, device,
162 "try alternate lpm=%x (lpum=%x / opm=%x)",
163 erp->lpm, erp->irb.esw.esw0.sublog.lpum, opm);
164
8e09f215
SW
165 /* reset status to submit the request again... */
166 erp->status = DASD_CQR_FILLED;
6c5f57c7 167 erp->retries = 10;
1da177e4
LT
168 } else {
169 DEV_MESSAGE(KERN_ERR, device,
170 "No alternate channel path left (lpum=%x / "
171 "opm=%x) -> permanent error",
172 erp->irb.esw.esw0.sublog.lpum, opm);
173
174 /* post request with permanent error */
8e09f215 175 erp->status = DASD_CQR_FAILED;
1da177e4
LT
176 }
177} /* end dasd_3990_erp_alternate_path */
178
179/*
180 * DASD_3990_ERP_DCTL
181 *
182 * DESCRIPTION
138c014d 183 * Setup cqr to do the Diagnostic Control (DCTL) command with an
1da177e4
LT
184 * Inhibit Write subcommand (0x20) and the given modifier.
185 *
186 * PARAMETER
187 * erp pointer to the current (failed) ERP
188 * modifier subcommand modifier
138c014d 189 *
1da177e4 190 * RETURN VALUES
138c014d 191 * dctl_cqr pointer to NEW dctl_cqr
1da177e4
LT
192 *
193 */
194static struct dasd_ccw_req *
195dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier)
196{
197
8e09f215 198 struct dasd_device *device = erp->startdev;
1da177e4
LT
199 struct DCTL_data *DCTL_data;
200 struct ccw1 *ccw;
201 struct dasd_ccw_req *dctl_cqr;
202
203 dctl_cqr = dasd_alloc_erp_request((char *) &erp->magic, 1,
8e09f215
SW
204 sizeof(struct DCTL_data),
205 device);
1da177e4
LT
206 if (IS_ERR(dctl_cqr)) {
207 DEV_MESSAGE(KERN_ERR, device, "%s",
208 "Unable to allocate DCTL-CQR");
209 erp->status = DASD_CQR_FAILED;
210 return erp;
211 }
212
213 DCTL_data = dctl_cqr->data;
214
215 DCTL_data->subcommand = 0x02; /* Inhibit Write */
216 DCTL_data->modifier = modifier;
217
218 ccw = dctl_cqr->cpaddr;
8e09f215 219 memset(ccw, 0, sizeof(struct ccw1));
1da177e4
LT
220 ccw->cmd_code = CCW_CMD_DCTL;
221 ccw->count = 4;
222 ccw->cda = (__u32)(addr_t) DCTL_data;
223 dctl_cqr->function = dasd_3990_erp_DCTL;
224 dctl_cqr->refers = erp;
8e09f215
SW
225 dctl_cqr->startdev = device;
226 dctl_cqr->memdev = device;
1da177e4
LT
227 dctl_cqr->magic = erp->magic;
228 dctl_cqr->expires = 5 * 60 * HZ;
229 dctl_cqr->retries = 2;
230
231 dctl_cqr->buildclk = get_clock();
232
233 dctl_cqr->status = DASD_CQR_FILLED;
234
235 return dctl_cqr;
236
237} /* end dasd_3990_erp_DCTL */
238
239/*
138c014d 240 * DASD_3990_ERP_ACTION_1
1da177e4
LT
241 *
242 * DESCRIPTION
243 * Setup ERP to do the ERP action 1 (see Reference manual).
244 * Repeat the operation on a different channel path.
245 * If all alternate paths have been tried, the request is posted with a
246 * permanent error.
247 * Note: duplex handling is not implemented (yet).
248 *
249 * PARAMETER
250 * erp pointer to the current ERP
251 *
252 * RETURN VALUES
253 * erp pointer to the ERP
254 *
255 */
256static struct dasd_ccw_req *
257dasd_3990_erp_action_1(struct dasd_ccw_req * erp)
258{
259
260 erp->function = dasd_3990_erp_action_1;
261
262 dasd_3990_erp_alternate_path(erp);
263
264 return erp;
265
266} /* end dasd_3990_erp_action_1 */
267
268/*
138c014d 269 * DASD_3990_ERP_ACTION_4
1da177e4
LT
270 *
271 * DESCRIPTION
272 * Setup ERP to do the ERP action 4 (see Reference manual).
273 * Set the current request to PENDING to block the CQR queue for that device
274 * until the state change interrupt appears.
275 * Use a timer (20 seconds) to retry the cqr if the interrupt is still
276 * missing.
277 *
278 * PARAMETER
279 * sense sense data of the actual error
280 * erp pointer to the current ERP
281 *
282 * RETURN VALUES
283 * erp pointer to the ERP
284 *
285 */
286static struct dasd_ccw_req *
287dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
288{
289
8e09f215 290 struct dasd_device *device = erp->startdev;
1da177e4
LT
291
292 /* first time set initial retry counter and erp_function */
293 /* and retry once without waiting for state change pending */
294 /* interrupt (this enables easier enqueing of the cqr) */
295 if (erp->function != dasd_3990_erp_action_4) {
296
297 DEV_MESSAGE(KERN_INFO, device, "%s",
298 "dasd_3990_erp_action_4: first time retry");
299
300 erp->retries = 256;
301 erp->function = dasd_3990_erp_action_4;
302
303 } else {
6c5f57c7 304 if (sense && (sense[25] == 0x1D)) { /* state change pending */
1da177e4 305
138c014d 306 DEV_MESSAGE(KERN_INFO, device,
1da177e4
LT
307 "waiting for state change pending "
308 "interrupt, %d retries left",
309 erp->retries);
138c014d 310
1da177e4
LT
311 dasd_3990_erp_block_queue(erp, 30*HZ);
312
6c5f57c7 313 } else if (sense && (sense[25] == 0x1E)) { /* busy */
1da177e4
LT
314 DEV_MESSAGE(KERN_INFO, device,
315 "busy - redriving request later, "
316 "%d retries left",
317 erp->retries);
318 dasd_3990_erp_block_queue(erp, HZ);
319 } else {
320
321 /* no state change pending - retry */
138c014d 322 DEV_MESSAGE (KERN_INFO, device,
1da177e4 323 "redriving request immediately, "
138c014d 324 "%d retries left",
1da177e4 325 erp->retries);
8e09f215 326 erp->status = DASD_CQR_FILLED;
1da177e4
LT
327 }
328 }
329
330 return erp;
331
332} /* end dasd_3990_erp_action_4 */
333
334/*
138c014d 335 *****************************************************************************
1da177e4 336 * 24 byte sense ERP functions (only)
138c014d 337 *****************************************************************************
1da177e4
LT
338 */
339
340/*
138c014d 341 * DASD_3990_ERP_ACTION_5
1da177e4
LT
342 *
343 * DESCRIPTION
344 * Setup ERP to do the ERP action 5 (see Reference manual).
345 * NOTE: Further handling is done in xxx_further_erp after the retries.
346 *
347 * PARAMETER
348 * erp pointer to the current ERP
349 *
350 * RETURN VALUES
351 * erp pointer to the ERP
352 *
353 */
354static struct dasd_ccw_req *
355dasd_3990_erp_action_5(struct dasd_ccw_req * erp)
356{
357
358 /* first of all retry */
359 erp->retries = 10;
360 erp->function = dasd_3990_erp_action_5;
361
362 return erp;
363
364} /* end dasd_3990_erp_action_5 */
365
366/*
367 * DASD_3990_HANDLE_ENV_DATA
368 *
369 * DESCRIPTION
370 * Handles 24 byte 'Environmental data present'.
371 * Does a analysis of the sense data (message Format)
372 * and prints the error messages.
373 *
374 * PARAMETER
375 * sense current sense data
138c014d 376 *
1da177e4
LT
377 * RETURN VALUES
378 * void
379 */
380static void
381dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
382{
383
8e09f215 384 struct dasd_device *device = erp->startdev;
1da177e4
LT
385 char msg_format = (sense[7] & 0xF0);
386 char msg_no = (sense[7] & 0x0F);
387
388 switch (msg_format) {
389 case 0x00: /* Format 0 - Program or System Checks */
390
391 if (sense[1] & 0x10) { /* check message to operator bit */
392
393 switch (msg_no) {
394 case 0x00: /* No Message */
395 break;
396 case 0x01:
397 DEV_MESSAGE(KERN_WARNING, device, "%s",
398 "FORMAT 0 - Invalid Command");
399 break;
400 case 0x02:
401 DEV_MESSAGE(KERN_WARNING, device, "%s",
402 "FORMAT 0 - Invalid Command "
403 "Sequence");
404 break;
405 case 0x03:
406 DEV_MESSAGE(KERN_WARNING, device, "%s",
407 "FORMAT 0 - CCW Count less than "
408 "required");
409 break;
410 case 0x04:
411 DEV_MESSAGE(KERN_WARNING, device, "%s",
412 "FORMAT 0 - Invalid Parameter");
413 break;
414 case 0x05:
415 DEV_MESSAGE(KERN_WARNING, device, "%s",
416 "FORMAT 0 - Diagnostic of Sepecial"
417 " Command Violates File Mask");
418 break;
419 case 0x07:
420 DEV_MESSAGE(KERN_WARNING, device, "%s",
421 "FORMAT 0 - Channel Returned with "
422 "Incorrect retry CCW");
423 break;
424 case 0x08:
425 DEV_MESSAGE(KERN_WARNING, device, "%s",
426 "FORMAT 0 - Reset Notification");
427 break;
428 case 0x09:
429 DEV_MESSAGE(KERN_WARNING, device, "%s",
430 "FORMAT 0 - Storage Path Restart");
431 break;
432 case 0x0A:
433 DEV_MESSAGE(KERN_WARNING, device,
434 "FORMAT 0 - Channel requested "
435 "... %02x", sense[8]);
436 break;
437 case 0x0B:
438 DEV_MESSAGE(KERN_WARNING, device, "%s",
439 "FORMAT 0 - Invalid Defective/"
440 "Alternate Track Pointer");
441 break;
442 case 0x0C:
443 DEV_MESSAGE(KERN_WARNING, device, "%s",
444 "FORMAT 0 - DPS Installation "
445 "Check");
446 break;
447 case 0x0E:
448 DEV_MESSAGE(KERN_WARNING, device, "%s",
449 "FORMAT 0 - Command Invalid on "
450 "Secondary Address");
451 break;
452 case 0x0F:
453 DEV_MESSAGE(KERN_WARNING, device,
454 "FORMAT 0 - Status Not As "
455 "Required: reason %02x", sense[8]);
456 break;
457 default:
458 DEV_MESSAGE(KERN_WARNING, device, "%s",
459 "FORMAT 0 - Reseved");
460 }
461 } else {
462 switch (msg_no) {
463 case 0x00: /* No Message */
464 break;
465 case 0x01:
466 DEV_MESSAGE(KERN_WARNING, device, "%s",
467 "FORMAT 0 - Device Error Source");
468 break;
469 case 0x02:
470 DEV_MESSAGE(KERN_WARNING, device, "%s",
471 "FORMAT 0 - Reserved");
472 break;
473 case 0x03:
474 DEV_MESSAGE(KERN_WARNING, device,
475 "FORMAT 0 - Device Fenced - "
476 "device = %02x", sense[4]);
477 break;
478 case 0x04:
479 DEV_MESSAGE(KERN_WARNING, device, "%s",
480 "FORMAT 0 - Data Pinned for "
481 "Device");
482 break;
483 default:
484 DEV_MESSAGE(KERN_WARNING, device, "%s",
485 "FORMAT 0 - Reserved");
486 }
487 }
488 break;
489
490 case 0x10: /* Format 1 - Device Equipment Checks */
491 switch (msg_no) {
492 case 0x00: /* No Message */
493 break;
494 case 0x01:
495 DEV_MESSAGE(KERN_WARNING, device, "%s",
496 "FORMAT 1 - Device Status 1 not as "
497 "expected");
498 break;
499 case 0x03:
500 DEV_MESSAGE(KERN_WARNING, device, "%s",
501 "FORMAT 1 - Index missing");
502 break;
503 case 0x04:
504 DEV_MESSAGE(KERN_WARNING, device, "%s",
505 "FORMAT 1 - Interruption cannot be reset");
506 break;
507 case 0x05:
508 DEV_MESSAGE(KERN_WARNING, device, "%s",
509 "FORMAT 1 - Device did not respond to "
510 "selection");
511 break;
512 case 0x06:
513 DEV_MESSAGE(KERN_WARNING, device, "%s",
514 "FORMAT 1 - Device check-2 error or Set "
515 "Sector is not complete");
516 break;
517 case 0x07:
518 DEV_MESSAGE(KERN_WARNING, device, "%s",
519 "FORMAT 1 - Head address does not "
520 "compare");
521 break;
522 case 0x08:
523 DEV_MESSAGE(KERN_WARNING, device, "%s",
524 "FORMAT 1 - Device status 1 not valid");
525 break;
526 case 0x09:
527 DEV_MESSAGE(KERN_WARNING, device, "%s",
528 "FORMAT 1 - Device not ready");
529 break;
530 case 0x0A:
531 DEV_MESSAGE(KERN_WARNING, device, "%s",
532 "FORMAT 1 - Track physical address did "
533 "not compare");
534 break;
535 case 0x0B:
536 DEV_MESSAGE(KERN_WARNING, device, "%s",
537 "FORMAT 1 - Missing device address bit");
538 break;
539 case 0x0C:
540 DEV_MESSAGE(KERN_WARNING, device, "%s",
541 "FORMAT 1 - Drive motor switch is off");
542 break;
543 case 0x0D:
544 DEV_MESSAGE(KERN_WARNING, device, "%s",
545 "FORMAT 1 - Seek incomplete");
546 break;
547 case 0x0E:
548 DEV_MESSAGE(KERN_WARNING, device, "%s",
549 "FORMAT 1 - Cylinder address did not "
550 "compare");
551 break;
552 case 0x0F:
553 DEV_MESSAGE(KERN_WARNING, device, "%s",
554 "FORMAT 1 - Offset active cannot be "
555 "reset");
556 break;
557 default:
558 DEV_MESSAGE(KERN_WARNING, device, "%s",
559 "FORMAT 1 - Reserved");
560 }
561 break;
562
563 case 0x20: /* Format 2 - 3990 Equipment Checks */
564 switch (msg_no) {
565 case 0x08:
566 DEV_MESSAGE(KERN_WARNING, device, "%s",
567 "FORMAT 2 - 3990 check-2 error");
568 break;
569 case 0x0E:
570 DEV_MESSAGE(KERN_WARNING, device, "%s",
571 "FORMAT 2 - Support facility errors");
572 break;
573 case 0x0F:
574 DEV_MESSAGE(KERN_WARNING, device,
575 "FORMAT 2 - Microcode detected error %02x",
576 sense[8]);
577 break;
578 default:
579 DEV_MESSAGE(KERN_WARNING, device, "%s",
580 "FORMAT 2 - Reserved");
581 }
582 break;
583
584 case 0x30: /* Format 3 - 3990 Control Checks */
585 switch (msg_no) {
586 case 0x0F:
587 DEV_MESSAGE(KERN_WARNING, device, "%s",
588 "FORMAT 3 - Allegiance terminated");
589 break;
590 default:
591 DEV_MESSAGE(KERN_WARNING, device, "%s",
592 "FORMAT 3 - Reserved");
593 }
594 break;
595
596 case 0x40: /* Format 4 - Data Checks */
597 switch (msg_no) {
598 case 0x00:
599 DEV_MESSAGE(KERN_WARNING, device, "%s",
600 "FORMAT 4 - Home address area error");
601 break;
602 case 0x01:
603 DEV_MESSAGE(KERN_WARNING, device, "%s",
604 "FORMAT 4 - Count area error");
605 break;
606 case 0x02:
607 DEV_MESSAGE(KERN_WARNING, device, "%s",
608 "FORMAT 4 - Key area error");
609 break;
610 case 0x03:
611 DEV_MESSAGE(KERN_WARNING, device, "%s",
612 "FORMAT 4 - Data area error");
613 break;
614 case 0x04:
615 DEV_MESSAGE(KERN_WARNING, device, "%s",
616 "FORMAT 4 - No sync byte in home address "
617 "area");
618 break;
619 case 0x05:
620 DEV_MESSAGE(KERN_WARNING, device, "%s",
621 "FORMAT 4 - No sync byte in count address "
622 "area");
623 break;
624 case 0x06:
625 DEV_MESSAGE(KERN_WARNING, device, "%s",
626 "FORMAT 4 - No sync byte in key area");
627 break;
628 case 0x07:
629 DEV_MESSAGE(KERN_WARNING, device, "%s",
630 "FORMAT 4 - No sync byte in data area");
631 break;
632 case 0x08:
633 DEV_MESSAGE(KERN_WARNING, device, "%s",
634 "FORMAT 4 - Home address area error; "
635 "offset active");
636 break;
637 case 0x09:
638 DEV_MESSAGE(KERN_WARNING, device, "%s",
639 "FORMAT 4 - Count area error; offset "
640 "active");
641 break;
642 case 0x0A:
643 DEV_MESSAGE(KERN_WARNING, device, "%s",
644 "FORMAT 4 - Key area error; offset "
645 "active");
646 break;
647 case 0x0B:
648 DEV_MESSAGE(KERN_WARNING, device, "%s",
649 "FORMAT 4 - Data area error; "
650 "offset active");
651 break;
652 case 0x0C:
653 DEV_MESSAGE(KERN_WARNING, device, "%s",
654 "FORMAT 4 - No sync byte in home "
655 "address area; offset active");
656 break;
657 case 0x0D:
658 DEV_MESSAGE(KERN_WARNING, device, "%s",
659 "FORMAT 4 - No syn byte in count "
660 "address area; offset active");
661 break;
662 case 0x0E:
663 DEV_MESSAGE(KERN_WARNING, device, "%s",
664 "FORMAT 4 - No sync byte in key area; "
665 "offset active");
666 break;
667 case 0x0F:
668 DEV_MESSAGE(KERN_WARNING, device, "%s",
669 "FORMAT 4 - No syn byte in data area; "
670 "offset active");
671 break;
672 default:
673 DEV_MESSAGE(KERN_WARNING, device, "%s",
674 "FORMAT 4 - Reserved");
675 }
676 break;
677
678 case 0x50: /* Format 5 - Data Check with displacement information */
679 switch (msg_no) {
680 case 0x00:
681 DEV_MESSAGE(KERN_WARNING, device, "%s",
682 "FORMAT 5 - Data Check in the "
683 "home address area");
684 break;
685 case 0x01:
686 DEV_MESSAGE(KERN_WARNING, device, "%s",
687 "FORMAT 5 - Data Check in the count area");
688 break;
689 case 0x02:
690 DEV_MESSAGE(KERN_WARNING, device, "%s",
691 "FORMAT 5 - Data Check in the key area");
692 break;
693 case 0x03:
694 DEV_MESSAGE(KERN_WARNING, device, "%s",
695 "FORMAT 5 - Data Check in the data area");
696 break;
697 case 0x08:
698 DEV_MESSAGE(KERN_WARNING, device, "%s",
699 "FORMAT 5 - Data Check in the "
700 "home address area; offset active");
701 break;
702 case 0x09:
703 DEV_MESSAGE(KERN_WARNING, device, "%s",
704 "FORMAT 5 - Data Check in the count area; "
705 "offset active");
706 break;
707 case 0x0A:
708 DEV_MESSAGE(KERN_WARNING, device, "%s",
709 "FORMAT 5 - Data Check in the key area; "
710 "offset active");
711 break;
712 case 0x0B:
713 DEV_MESSAGE(KERN_WARNING, device, "%s",
714 "FORMAT 5 - Data Check in the data area; "
715 "offset active");
716 break;
717 default:
718 DEV_MESSAGE(KERN_WARNING, device, "%s",
719 "FORMAT 5 - Reserved");
720 }
721 break;
722
723 case 0x60: /* Format 6 - Usage Statistics/Overrun Errors */
724 switch (msg_no) {
725 case 0x00:
726 DEV_MESSAGE(KERN_WARNING, device, "%s",
727 "FORMAT 6 - Overrun on channel A");
728 break;
729 case 0x01:
730 DEV_MESSAGE(KERN_WARNING, device, "%s",
731 "FORMAT 6 - Overrun on channel B");
732 break;
733 case 0x02:
734 DEV_MESSAGE(KERN_WARNING, device, "%s",
735 "FORMAT 6 - Overrun on channel C");
736 break;
737 case 0x03:
738 DEV_MESSAGE(KERN_WARNING, device, "%s",
739 "FORMAT 6 - Overrun on channel D");
740 break;
741 case 0x04:
742 DEV_MESSAGE(KERN_WARNING, device, "%s",
743 "FORMAT 6 - Overrun on channel E");
744 break;
745 case 0x05:
746 DEV_MESSAGE(KERN_WARNING, device, "%s",
747 "FORMAT 6 - Overrun on channel F");
748 break;
749 case 0x06:
750 DEV_MESSAGE(KERN_WARNING, device, "%s",
751 "FORMAT 6 - Overrun on channel G");
752 break;
753 case 0x07:
754 DEV_MESSAGE(KERN_WARNING, device, "%s",
755 "FORMAT 6 - Overrun on channel H");
756 break;
757 default:
758 DEV_MESSAGE(KERN_WARNING, device, "%s",
759 "FORMAT 6 - Reserved");
760 }
761 break;
762
763 case 0x70: /* Format 7 - Device Connection Control Checks */
764 switch (msg_no) {
765 case 0x00:
766 DEV_MESSAGE(KERN_WARNING, device, "%s",
767 "FORMAT 7 - RCC initiated by a connection "
768 "check alert");
769 break;
770 case 0x01:
771 DEV_MESSAGE(KERN_WARNING, device, "%s",
772 "FORMAT 7 - RCC 1 sequence not "
773 "successful");
774 break;
775 case 0x02:
776 DEV_MESSAGE(KERN_WARNING, device, "%s",
777 "FORMAT 7 - RCC 1 and RCC 2 sequences not "
778 "successful");
779 break;
780 case 0x03:
781 DEV_MESSAGE(KERN_WARNING, device, "%s",
782 "FORMAT 7 - Invalid tag-in during "
783 "selection sequence");
784 break;
785 case 0x04:
786 DEV_MESSAGE(KERN_WARNING, device, "%s",
787 "FORMAT 7 - extra RCC required");
788 break;
789 case 0x05:
790 DEV_MESSAGE(KERN_WARNING, device, "%s",
791 "FORMAT 7 - Invalid DCC selection "
792 "response or timeout");
793 break;
794 case 0x06:
795 DEV_MESSAGE(KERN_WARNING, device, "%s",
796 "FORMAT 7 - Missing end operation; device "
797 "transfer complete");
798 break;
799 case 0x07:
800 DEV_MESSAGE(KERN_WARNING, device, "%s",
801 "FORMAT 7 - Missing end operation; device "
802 "transfer incomplete");
803 break;
804 case 0x08:
805 DEV_MESSAGE(KERN_WARNING, device, "%s",
806 "FORMAT 7 - Invalid tag-in for an "
807 "immediate command sequence");
808 break;
809 case 0x09:
810 DEV_MESSAGE(KERN_WARNING, device, "%s",
811 "FORMAT 7 - Invalid tag-in for an "
812 "extended command sequence");
813 break;
814 case 0x0A:
815 DEV_MESSAGE(KERN_WARNING, device, "%s",
816 "FORMAT 7 - 3990 microcode time out when "
817 "stopping selection");
818 break;
819 case 0x0B:
820 DEV_MESSAGE(KERN_WARNING, device, "%s",
821 "FORMAT 7 - No response to selection "
822 "after a poll interruption");
823 break;
824 case 0x0C:
825 DEV_MESSAGE(KERN_WARNING, device, "%s",
826 "FORMAT 7 - Permanent path error (DASD "
827 "controller not available)");
828 break;
829 case 0x0D:
830 DEV_MESSAGE(KERN_WARNING, device, "%s",
831 "FORMAT 7 - DASD controller not available"
832 " on disconnected command chain");
833 break;
834 default:
835 DEV_MESSAGE(KERN_WARNING, device, "%s",
836 "FORMAT 7 - Reserved");
837 }
838 break;
839
840 case 0x80: /* Format 8 - Additional Device Equipment Checks */
841 switch (msg_no) {
842 case 0x00: /* No Message */
843 case 0x01:
844 DEV_MESSAGE(KERN_WARNING, device, "%s",
845 "FORMAT 8 - Error correction code "
846 "hardware fault");
847 break;
848 case 0x03:
849 DEV_MESSAGE(KERN_WARNING, device, "%s",
850 "FORMAT 8 - Unexpected end operation "
851 "response code");
852 break;
853 case 0x04:
854 DEV_MESSAGE(KERN_WARNING, device, "%s",
855 "FORMAT 8 - End operation with transfer "
856 "count not zero");
857 break;
858 case 0x05:
859 DEV_MESSAGE(KERN_WARNING, device, "%s",
860 "FORMAT 8 - End operation with transfer "
861 "count zero");
862 break;
863 case 0x06:
864 DEV_MESSAGE(KERN_WARNING, device, "%s",
865 "FORMAT 8 - DPS checks after a system "
866 "reset or selective reset");
867 break;
868 case 0x07:
869 DEV_MESSAGE(KERN_WARNING, device, "%s",
870 "FORMAT 8 - DPS cannot be filled");
871 break;
872 case 0x08:
873 DEV_MESSAGE(KERN_WARNING, device, "%s",
874 "FORMAT 8 - Short busy time-out during "
875 "device selection");
876 break;
877 case 0x09:
878 DEV_MESSAGE(KERN_WARNING, device, "%s",
879 "FORMAT 8 - DASD controller failed to "
880 "set or reset the long busy latch");
881 break;
882 case 0x0A:
883 DEV_MESSAGE(KERN_WARNING, device, "%s",
884 "FORMAT 8 - No interruption from device "
885 "during a command chain");
886 break;
887 default:
888 DEV_MESSAGE(KERN_WARNING, device, "%s",
889 "FORMAT 8 - Reserved");
890 }
891 break;
892
893 case 0x90: /* Format 9 - Device Read, Write, and Seek Checks */
894 switch (msg_no) {
895 case 0x00:
896 break; /* No Message */
897 case 0x06:
898 DEV_MESSAGE(KERN_WARNING, device, "%s",
899 "FORMAT 9 - Device check-2 error");
900 break;
901 case 0x07:
902 DEV_MESSAGE(KERN_WARNING, device, "%s",
903 "FORMAT 9 - Head address did not compare");
904 break;
905 case 0x0A:
906 DEV_MESSAGE(KERN_WARNING, device, "%s",
907 "FORMAT 9 - Track physical address did "
908 "not compare while oriented");
909 break;
910 case 0x0E:
911 DEV_MESSAGE(KERN_WARNING, device, "%s",
912 "FORMAT 9 - Cylinder address did not "
913 "compare");
914 break;
915 default:
916 DEV_MESSAGE(KERN_WARNING, device, "%s",
917 "FORMAT 9 - Reserved");
918 }
919 break;
920
921 case 0xF0: /* Format F - Cache Storage Checks */
922 switch (msg_no) {
923 case 0x00:
924 DEV_MESSAGE(KERN_WARNING, device, "%s",
925 "FORMAT F - Operation Terminated");
926 break;
927 case 0x01:
928 DEV_MESSAGE(KERN_WARNING, device, "%s",
929 "FORMAT F - Subsystem Processing Error");
930 break;
931 case 0x02:
932 DEV_MESSAGE(KERN_WARNING, device, "%s",
933 "FORMAT F - Cache or nonvolatile storage "
934 "equipment failure");
935 break;
936 case 0x04:
937 DEV_MESSAGE(KERN_WARNING, device, "%s",
938 "FORMAT F - Caching terminated");
939 break;
940 case 0x06:
941 DEV_MESSAGE(KERN_WARNING, device, "%s",
942 "FORMAT F - Cache fast write access not "
943 "authorized");
944 break;
945 case 0x07:
946 DEV_MESSAGE(KERN_WARNING, device, "%s",
947 "FORMAT F - Track format incorrect");
948 break;
949 case 0x09:
950 DEV_MESSAGE(KERN_WARNING, device, "%s",
951 "FORMAT F - Caching reinitiated");
952 break;
953 case 0x0A:
954 DEV_MESSAGE(KERN_WARNING, device, "%s",
955 "FORMAT F - Nonvolatile storage "
956 "terminated");
957 break;
958 case 0x0B:
959 DEV_MESSAGE(KERN_WARNING, device, "%s",
960 "FORMAT F - Volume is suspended duplex");
20c64468
SW
961 /* call extended error reporting (EER) */
962 dasd_eer_write(device, erp->refers,
963 DASD_EER_PPRCSUSPEND);
1da177e4
LT
964 break;
965 case 0x0C:
966 DEV_MESSAGE(KERN_WARNING, device, "%s",
967 "FORMAT F - Subsystem status connot be "
968 "determined");
969 break;
970 case 0x0D:
971 DEV_MESSAGE(KERN_WARNING, device, "%s",
972 "FORMAT F - Caching status reset to "
973 "default");
974 break;
975 case 0x0E:
976 DEV_MESSAGE(KERN_WARNING, device, "%s",
977 "FORMAT F - DASD Fast Write inhibited");
978 break;
979 default:
980 DEV_MESSAGE(KERN_WARNING, device, "%s",
981 "FORMAT D - Reserved");
982 }
983 break;
984
985 default: /* unknown message format - should not happen */
986 DEV_MESSAGE (KERN_WARNING, device,
987 "unknown message format %02x",
988 msg_format);
989 break;
990 } /* end switch message format */
991
992} /* end dasd_3990_handle_env_data */
993
994/*
995 * DASD_3990_ERP_COM_REJ
996 *
997 * DESCRIPTION
998 * Handles 24 byte 'Command Reject' error.
999 *
1000 * PARAMETER
1001 * erp current erp_head
1002 * sense current sense data
138c014d 1003 *
1da177e4 1004 * RETURN VALUES
138c014d 1005 * erp 'new' erp_head - pointer to new ERP
1da177e4
LT
1006 */
1007static struct dasd_ccw_req *
1008dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
1009{
1010
8e09f215 1011 struct dasd_device *device = erp->startdev;
1da177e4
LT
1012
1013 erp->function = dasd_3990_erp_com_rej;
1014
1015 /* env data present (ACTION 10 - retry should work) */
1016 if (sense[2] & SNS2_ENV_DATA_PRESENT) {
1017
1018 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1019 "Command Reject - environmental data present");
1020
1021 dasd_3990_handle_env_data(erp, sense);
1022
1023 erp->retries = 5;
1024
1025 } else {
1026 /* fatal error - set status to FAILED */
1027 DEV_MESSAGE(KERN_ERR, device, "%s",
1028 "Command Reject - Fatal error");
1029
1030 erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
1031 }
1032
1033 return erp;
1034
1035} /* end dasd_3990_erp_com_rej */
1036
1037/*
138c014d 1038 * DASD_3990_ERP_BUS_OUT
1da177e4
LT
1039 *
1040 * DESCRIPTION
1041 * Handles 24 byte 'Bus Out Parity Check' error.
1042 *
1043 * PARAMETER
1044 * erp current erp_head
1045 * RETURN VALUES
1046 * erp new erp_head - pointer to new ERP
1047 */
1048static struct dasd_ccw_req *
1049dasd_3990_erp_bus_out(struct dasd_ccw_req * erp)
1050{
1051
8e09f215 1052 struct dasd_device *device = erp->startdev;
1da177e4
LT
1053
1054 /* first time set initial retry counter and erp_function */
1055 /* and retry once without blocking queue */
1056 /* (this enables easier enqueing of the cqr) */
1057 if (erp->function != dasd_3990_erp_bus_out) {
1058 erp->retries = 256;
1059 erp->function = dasd_3990_erp_bus_out;
1060
1061 } else {
1062
1063 /* issue a message and wait for 'device ready' interrupt */
1064 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1065 "bus out parity error or BOPC requested by "
1066 "channel");
1067
1068 dasd_3990_erp_block_queue(erp, 60*HZ);
1069
1070 }
1071
1072 return erp;
1073
1074} /* end dasd_3990_erp_bus_out */
1075
1076/*
1077 * DASD_3990_ERP_EQUIP_CHECK
1078 *
1079 * DESCRIPTION
1080 * Handles 24 byte 'Equipment Check' error.
1081 *
1082 * PARAMETER
1083 * erp current erp_head
1084 * RETURN VALUES
1085 * erp new erp_head - pointer to new ERP
1086 */
1087static struct dasd_ccw_req *
1088dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
1089{
1090
8e09f215 1091 struct dasd_device *device = erp->startdev;
1da177e4
LT
1092
1093 erp->function = dasd_3990_erp_equip_check;
1094
1095 if (sense[1] & SNS1_WRITE_INHIBITED) {
1096
1097 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1098 "Write inhibited path encountered");
1099
1100 /* vary path offline */
1101 DEV_MESSAGE(KERN_ERR, device, "%s",
1102 "Path should be varied off-line. "
1103 "This is not implemented yet \n - please report "
1104 "to linux390@de.ibm.com");
1105
1106 erp = dasd_3990_erp_action_1(erp);
1107
1108 } else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
1109
1110 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1111 "Equipment Check - " "environmental data present");
1112
1113 dasd_3990_handle_env_data(erp, sense);
1114
1115 erp = dasd_3990_erp_action_4(erp, sense);
1116
1117 } else if (sense[1] & SNS1_PERM_ERR) {
1118
1119 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1120 "Equipment Check - retry exhausted or "
1121 "undesirable");
1122
1123 erp = dasd_3990_erp_action_1(erp);
1124
1125 } else {
1126 /* all other equipment checks - Action 5 */
1127 /* rest is done when retries == 0 */
1128 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1129 "Equipment check or processing error");
1130
1131 erp = dasd_3990_erp_action_5(erp);
1132 }
1da177e4
LT
1133 return erp;
1134
1135} /* end dasd_3990_erp_equip_check */
1136
1137/*
1138 * DASD_3990_ERP_DATA_CHECK
1139 *
1140 * DESCRIPTION
1141 * Handles 24 byte 'Data Check' error.
1142 *
1143 * PARAMETER
1144 * erp current erp_head
1145 * RETURN VALUES
1146 * erp new erp_head - pointer to new ERP
1147 */
1148static struct dasd_ccw_req *
1149dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
1150{
1151
8e09f215 1152 struct dasd_device *device = erp->startdev;
1da177e4
LT
1153
1154 erp->function = dasd_3990_erp_data_check;
1155
1156 if (sense[2] & SNS2_CORRECTABLE) { /* correctable data check */
1157
1158 /* issue message that the data has been corrected */
1159 DEV_MESSAGE(KERN_EMERG, device, "%s",
1160 "Data recovered during retry with PCI "
1161 "fetch mode active");
1162
1163 /* not possible to handle this situation in Linux */
1164 panic("No way to inform application about the possibly "
1165 "incorrect data");
1166
1167 } else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
1168
1169 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1170 "Uncorrectable data check recovered secondary "
1171 "addr of duplex pair");
1172
1173 erp = dasd_3990_erp_action_4(erp, sense);
1174
1175 } else if (sense[1] & SNS1_PERM_ERR) {
1176
1177 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1178 "Uncorrectable data check with internal "
1179 "retry exhausted");
1180
1181 erp = dasd_3990_erp_action_1(erp);
1182
1183 } else {
1184 /* all other data checks */
1185 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1186 "Uncorrectable data check with retry count "
1187 "exhausted...");
1188
1189 erp = dasd_3990_erp_action_5(erp);
1190 }
1191
1192 return erp;
1193
1194} /* end dasd_3990_erp_data_check */
1195
1196/*
1197 * DASD_3990_ERP_OVERRUN
1198 *
1199 * DESCRIPTION
1200 * Handles 24 byte 'Overrun' error.
1201 *
1202 * PARAMETER
1203 * erp current erp_head
1204 * RETURN VALUES
1205 * erp new erp_head - pointer to new ERP
1206 */
1207static struct dasd_ccw_req *
1208dasd_3990_erp_overrun(struct dasd_ccw_req * erp, char *sense)
1209{
1210
8e09f215 1211 struct dasd_device *device = erp->startdev;
1da177e4
LT
1212
1213 erp->function = dasd_3990_erp_overrun;
1214
1215 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1216 "Overrun - service overrun or overrun"
1217 " error requested by channel");
1218
1219 erp = dasd_3990_erp_action_5(erp);
1220
1221 return erp;
1222
1223} /* end dasd_3990_erp_overrun */
1224
1225/*
1226 * DASD_3990_ERP_INV_FORMAT
1227 *
1228 * DESCRIPTION
1229 * Handles 24 byte 'Invalid Track Format' error.
1230 *
1231 * PARAMETER
1232 * erp current erp_head
1233 * RETURN VALUES
1234 * erp new erp_head - pointer to new ERP
1235 */
1236static struct dasd_ccw_req *
1237dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense)
1238{
1239
8e09f215 1240 struct dasd_device *device = erp->startdev;
1da177e4
LT
1241
1242 erp->function = dasd_3990_erp_inv_format;
1243
1244 if (sense[2] & SNS2_ENV_DATA_PRESENT) {
1245
1246 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1247 "Track format error when destaging or "
1248 "staging data");
1249
1250 dasd_3990_handle_env_data(erp, sense);
1251
1252 erp = dasd_3990_erp_action_4(erp, sense);
1253
1254 } else {
1255 DEV_MESSAGE(KERN_ERR, device, "%s",
8e09f215 1256 "Invalid Track Format - Fatal error");
1da177e4
LT
1257
1258 erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
1259 }
1260
1261 return erp;
1262
1263} /* end dasd_3990_erp_inv_format */
1264
1265/*
1266 * DASD_3990_ERP_EOC
1267 *
1268 * DESCRIPTION
1269 * Handles 24 byte 'End-of-Cylinder' error.
1270 *
1271 * PARAMETER
1272 * erp already added default erp
1273 * RETURN VALUES
1274 * erp pointer to original (failed) cqr.
1275 */
1276static struct dasd_ccw_req *
1277dasd_3990_erp_EOC(struct dasd_ccw_req * default_erp, char *sense)
1278{
1279
8e09f215 1280 struct dasd_device *device = default_erp->startdev;
1da177e4
LT
1281
1282 DEV_MESSAGE(KERN_ERR, device, "%s",
1283 "End-of-Cylinder - must never happen");
1284
1285 /* implement action 7 - BUG */
1286 return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
1287
1288} /* end dasd_3990_erp_EOC */
1289
1290/*
1291 * DASD_3990_ERP_ENV_DATA
1292 *
1293 * DESCRIPTION
1294 * Handles 24 byte 'Environmental-Data Present' error.
1295 *
1296 * PARAMETER
1297 * erp current erp_head
1298 * RETURN VALUES
1299 * erp new erp_head - pointer to new ERP
1300 */
1301static struct dasd_ccw_req *
1302dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense)
1303{
1304
8e09f215 1305 struct dasd_device *device = erp->startdev;
1da177e4
LT
1306
1307 erp->function = dasd_3990_erp_env_data;
1308
1309 DEV_MESSAGE(KERN_DEBUG, device, "%s", "Environmental data present");
1310
1311 dasd_3990_handle_env_data(erp, sense);
1312
1313 /* don't retry on disabled interface */
1314 if (sense[7] != 0x0F) {
1da177e4
LT
1315 erp = dasd_3990_erp_action_4(erp, sense);
1316 } else {
8e09f215 1317 erp->status = DASD_CQR_FILLED;
1da177e4
LT
1318 }
1319
1320 return erp;
1321
1322} /* end dasd_3990_erp_env_data */
1323
1324/*
1325 * DASD_3990_ERP_NO_REC
1326 *
1327 * DESCRIPTION
1328 * Handles 24 byte 'No Record Found' error.
1329 *
1330 * PARAMETER
1331 * erp already added default ERP
138c014d 1332 *
1da177e4
LT
1333 * RETURN VALUES
1334 * erp new erp_head - pointer to new ERP
1335 */
1336static struct dasd_ccw_req *
1337dasd_3990_erp_no_rec(struct dasd_ccw_req * default_erp, char *sense)
1338{
1339
8e09f215 1340 struct dasd_device *device = default_erp->startdev;
1da177e4
LT
1341
1342 DEV_MESSAGE(KERN_ERR, device, "%s",
8e09f215 1343 "No Record Found - Fatal error ");
1da177e4
LT
1344
1345 return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
1346
1347} /* end dasd_3990_erp_no_rec */
1348
1349/*
1350 * DASD_3990_ERP_FILE_PROT
1351 *
1352 * DESCRIPTION
1353 * Handles 24 byte 'File Protected' error.
1354 * Note: Seek related recovery is not implemented because
1355 * wee don't use the seek command yet.
1356 *
1357 * PARAMETER
1358 * erp current erp_head
1359 * RETURN VALUES
1360 * erp new erp_head - pointer to new ERP
1361 */
1362static struct dasd_ccw_req *
1363dasd_3990_erp_file_prot(struct dasd_ccw_req * erp)
1364{
1365
8e09f215 1366 struct dasd_device *device = erp->startdev;
1da177e4
LT
1367
1368 DEV_MESSAGE(KERN_ERR, device, "%s", "File Protected");
1369
1370 return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
1371
1372} /* end dasd_3990_erp_file_prot */
1373
8e09f215
SW
1374/*
1375 * DASD_3990_ERP_INSPECT_ALIAS
1376 *
1377 * DESCRIPTION
1378 * Checks if the original request was started on an alias device.
1379 * If yes, it modifies the original and the erp request so that
1380 * the erp request can be started on a base device.
1381 *
1382 * PARAMETER
1383 * erp pointer to the currently created default ERP
1384 *
1385 * RETURN VALUES
1386 * erp pointer to the modified ERP, or NULL
1387 */
1388
1389static struct dasd_ccw_req *dasd_3990_erp_inspect_alias(
1390 struct dasd_ccw_req *erp)
1391{
1392 struct dasd_ccw_req *cqr = erp->refers;
1393
1394 if (cqr->block &&
1395 (cqr->block->base != cqr->startdev)) {
1396 if (cqr->startdev->features & DASD_FEATURE_ERPLOG) {
1397 DEV_MESSAGE(KERN_ERR, cqr->startdev,
1398 "ERP on alias device for request %p,"
1399 " recover on base device %s", cqr,
1400 cqr->block->base->cdev->dev.bus_id);
1401 }
1402 dasd_eckd_reset_ccw_to_base_io(cqr);
1403 erp->startdev = cqr->block->base;
1404 erp->function = dasd_3990_erp_inspect_alias;
1405 return erp;
1406 } else
1407 return NULL;
1408}
1409
1410
1da177e4 1411/*
138c014d 1412 * DASD_3990_ERP_INSPECT_24
1da177e4
LT
1413 *
1414 * DESCRIPTION
1415 * Does a detailed inspection of the 24 byte sense data
138c014d 1416 * and sets up a related error recovery action.
1da177e4
LT
1417 *
1418 * PARAMETER
1419 * sense sense data of the actual error
1420 * erp pointer to the currently created default ERP
1421 *
1422 * RETURN VALUES
1423 * erp pointer to the (addtitional) ERP
1424 */
1425static struct dasd_ccw_req *
1426dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense)
1427{
1428
1429 struct dasd_ccw_req *erp_filled = NULL;
1430
1431 /* Check sense for .... */
1432 /* 'Command Reject' */
1433 if ((erp_filled == NULL) && (sense[0] & SNS0_CMD_REJECT)) {
1434 erp_filled = dasd_3990_erp_com_rej(erp, sense);
1435 }
1436 /* 'Intervention Required' */
1437 if ((erp_filled == NULL) && (sense[0] & SNS0_INTERVENTION_REQ)) {
1438 erp_filled = dasd_3990_erp_int_req(erp);
1439 }
1440 /* 'Bus Out Parity Check' */
1441 if ((erp_filled == NULL) && (sense[0] & SNS0_BUS_OUT_CHECK)) {
1442 erp_filled = dasd_3990_erp_bus_out(erp);
1443 }
1444 /* 'Equipment Check' */
1445 if ((erp_filled == NULL) && (sense[0] & SNS0_EQUIPMENT_CHECK)) {
1446 erp_filled = dasd_3990_erp_equip_check(erp, sense);
1447 }
1448 /* 'Data Check' */
1449 if ((erp_filled == NULL) && (sense[0] & SNS0_DATA_CHECK)) {
1450 erp_filled = dasd_3990_erp_data_check(erp, sense);
1451 }
1452 /* 'Overrun' */
1453 if ((erp_filled == NULL) && (sense[0] & SNS0_OVERRUN)) {
1454 erp_filled = dasd_3990_erp_overrun(erp, sense);
1455 }
1456 /* 'Invalid Track Format' */
1457 if ((erp_filled == NULL) && (sense[1] & SNS1_INV_TRACK_FORMAT)) {
1458 erp_filled = dasd_3990_erp_inv_format(erp, sense);
1459 }
1460 /* 'End-of-Cylinder' */
1461 if ((erp_filled == NULL) && (sense[1] & SNS1_EOC)) {
1462 erp_filled = dasd_3990_erp_EOC(erp, sense);
1463 }
1464 /* 'Environmental Data' */
1465 if ((erp_filled == NULL) && (sense[2] & SNS2_ENV_DATA_PRESENT)) {
1466 erp_filled = dasd_3990_erp_env_data(erp, sense);
1467 }
1468 /* 'No Record Found' */
1469 if ((erp_filled == NULL) && (sense[1] & SNS1_NO_REC_FOUND)) {
1470 erp_filled = dasd_3990_erp_no_rec(erp, sense);
1471 }
1472 /* 'File Protected' */
1473 if ((erp_filled == NULL) && (sense[1] & SNS1_FILE_PROTECTED)) {
1474 erp_filled = dasd_3990_erp_file_prot(erp);
1475 }
1476 /* other (unknown) error - do default ERP */
1477 if (erp_filled == NULL) {
1478
1479 erp_filled = erp;
1480 }
1481
1482 return erp_filled;
1483
1484} /* END dasd_3990_erp_inspect_24 */
1485
1486/*
138c014d 1487 *****************************************************************************
1da177e4 1488 * 32 byte sense ERP functions (only)
138c014d 1489 *****************************************************************************
1da177e4
LT
1490 */
1491
1492/*
138c014d 1493 * DASD_3990_ERPACTION_10_32
1da177e4
LT
1494 *
1495 * DESCRIPTION
1496 * Handles 32 byte 'Action 10' of Single Program Action Codes.
1497 * Just retry and if retry doesn't work, return with error.
1498 *
1499 * PARAMETER
1500 * erp current erp_head
138c014d 1501 * sense current sense data
1da177e4
LT
1502 * RETURN VALUES
1503 * erp modified erp_head
1504 */
1505static struct dasd_ccw_req *
1506dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense)
1507{
1508
8e09f215 1509 struct dasd_device *device = erp->startdev;
1da177e4
LT
1510
1511 erp->retries = 256;
1512 erp->function = dasd_3990_erp_action_10_32;
1513
1514 DEV_MESSAGE(KERN_DEBUG, device, "%s", "Perform logging requested");
1515
1516 return erp;
1517
1518} /* end dasd_3990_erp_action_10_32 */
1519
1520/*
1521 * DASD_3990_ERP_ACTION_1B_32
1522 *
1523 * DESCRIPTION
1524 * Handles 32 byte 'Action 1B' of Single Program Action Codes.
138c014d 1525 * A write operation could not be finished because of an unexpected
1da177e4 1526 * condition.
138c014d
HH
1527 * The already created 'default erp' is used to get the link to
1528 * the erp chain, but it can not be used for this recovery
1da177e4
LT
1529 * action because it contains no DE/LO data space.
1530 *
1531 * PARAMETER
1532 * default_erp already added default erp.
138c014d 1533 * sense current sense data
1da177e4
LT
1534 *
1535 * RETURN VALUES
138c014d 1536 * erp new erp or
1da177e4
LT
1537 * default_erp in case of imprecise ending or error
1538 */
1539static struct dasd_ccw_req *
1540dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
1541{
1542
8e09f215 1543 struct dasd_device *device = default_erp->startdev;
1da177e4
LT
1544 __u32 cpa = 0;
1545 struct dasd_ccw_req *cqr;
1546 struct dasd_ccw_req *erp;
1547 struct DE_eckd_data *DE_data;
8e09f215 1548 struct PFX_eckd_data *PFX_data;
1da177e4 1549 char *LO_data; /* LO_eckd_data_t */
8e09f215 1550 struct ccw1 *ccw, *oldccw;
1da177e4
LT
1551
1552 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1553 "Write not finished because of unexpected condition");
1554
1555 default_erp->function = dasd_3990_erp_action_1B_32;
1556
1557 /* determine the original cqr */
1558 cqr = default_erp;
1559
1560 while (cqr->refers != NULL) {
1561 cqr = cqr->refers;
1562 }
1563
1564 /* for imprecise ending just do default erp */
1565 if (sense[1] & 0x01) {
1566
1567 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1568 "Imprecise ending is set - just retry");
1569
1570 return default_erp;
1571 }
1572
1573 /* determine the address of the CCW to be restarted */
1574 /* Imprecise ending is not set -> addr from IRB-SCSW */
23d805b6 1575 cpa = default_erp->refers->irb.scsw.cmd.cpa;
1da177e4
LT
1576
1577 if (cpa == 0) {
1578
1579 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1580 "Unable to determine address of the CCW "
1581 "to be restarted");
1582
1583 return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
1584 }
1585
1586 /* Build new ERP request including DE/LO */
1587 erp = dasd_alloc_erp_request((char *) &cqr->magic,
1588 2 + 1,/* DE/LO + TIC */
8e09f215
SW
1589 sizeof(struct DE_eckd_data) +
1590 sizeof(struct LO_eckd_data), device);
1da177e4
LT
1591
1592 if (IS_ERR(erp)) {
1593 DEV_MESSAGE(KERN_ERR, device, "%s", "Unable to allocate ERP");
1594 return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
1595 }
1596
1597 /* use original DE */
1598 DE_data = erp->data;
8e09f215
SW
1599 oldccw = cqr->cpaddr;
1600 if (oldccw->cmd_code == DASD_ECKD_CCW_PFX) {
1601 PFX_data = cqr->data;
1602 memcpy(DE_data, &PFX_data->define_extend,
1603 sizeof(struct DE_eckd_data));
1604 } else
1605 memcpy(DE_data, cqr->data, sizeof(struct DE_eckd_data));
1da177e4
LT
1606
1607 /* create LO */
8e09f215 1608 LO_data = erp->data + sizeof(struct DE_eckd_data);
1da177e4
LT
1609
1610 if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
1611
1612 DEV_MESSAGE(KERN_ERR, device, "%s",
1613 "BUG - this should not happen");
1614
1615 return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
1616 }
1617
1618 if ((sense[7] & 0x3F) == 0x01) {
1619 /* operation code is WRITE DATA -> data area orientation */
1620 LO_data[0] = 0x81;
1621
1622 } else if ((sense[7] & 0x3F) == 0x03) {
1623 /* operation code is FORMAT WRITE -> index orientation */
1624 LO_data[0] = 0xC3;
1625
1626 } else {
1627 LO_data[0] = sense[7]; /* operation */
1628 }
1629
1630 LO_data[1] = sense[8]; /* auxiliary */
1631 LO_data[2] = sense[9];
1632 LO_data[3] = sense[3]; /* count */
1633 LO_data[4] = sense[29]; /* seek_addr.cyl */
1634 LO_data[5] = sense[30]; /* seek_addr.cyl 2nd byte */
1635 LO_data[7] = sense[31]; /* seek_addr.head 2nd byte */
1636
1637 memcpy(&(LO_data[8]), &(sense[11]), 8);
1638
1639 /* create DE ccw */
1640 ccw = erp->cpaddr;
8e09f215 1641 memset(ccw, 0, sizeof(struct ccw1));
1da177e4
LT
1642 ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;
1643 ccw->flags = CCW_FLAG_CC;
1644 ccw->count = 16;
1645 ccw->cda = (__u32)(addr_t) DE_data;
1646
1647 /* create LO ccw */
1648 ccw++;
8e09f215 1649 memset(ccw, 0, sizeof(struct ccw1));
1da177e4
LT
1650 ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
1651 ccw->flags = CCW_FLAG_CC;
1652 ccw->count = 16;
1653 ccw->cda = (__u32)(addr_t) LO_data;
1654
1655 /* TIC to the failed ccw */
1656 ccw++;
1657 ccw->cmd_code = CCW_CMD_TIC;
1658 ccw->cda = cpa;
1659
1660 /* fill erp related fields */
1661 erp->function = dasd_3990_erp_action_1B_32;
1662 erp->refers = default_erp->refers;
8e09f215
SW
1663 erp->startdev = device;
1664 erp->memdev = device;
1da177e4
LT
1665 erp->magic = default_erp->magic;
1666 erp->expires = 0;
1667 erp->retries = 256;
1668 erp->buildclk = get_clock();
1669 erp->status = DASD_CQR_FILLED;
1670
1671 /* remove the default erp */
1672 dasd_free_erp_request(default_erp, device);
1673
1674 return erp;
1675
1676} /* end dasd_3990_erp_action_1B_32 */
1677
1678/*
1679 * DASD_3990_UPDATE_1B
1680 *
1681 * DESCRIPTION
138c014d 1682 * Handles the update to the 32 byte 'Action 1B' of Single Program
1da177e4
LT
1683 * Action Codes in case the first action was not successful.
1684 * The already created 'previous_erp' is the currently not successful
138c014d 1685 * ERP.
1da177e4
LT
1686 *
1687 * PARAMETER
1688 * previous_erp already created previous erp.
138c014d 1689 * sense current sense data
1da177e4 1690 * RETURN VALUES
138c014d 1691 * erp modified erp
1da177e4
LT
1692 */
1693static struct dasd_ccw_req *
1694dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
1695{
1696
8e09f215 1697 struct dasd_device *device = previous_erp->startdev;
1da177e4
LT
1698 __u32 cpa = 0;
1699 struct dasd_ccw_req *cqr;
1700 struct dasd_ccw_req *erp;
1701 char *LO_data; /* struct LO_eckd_data */
1702 struct ccw1 *ccw;
1703
1704 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1705 "Write not finished because of unexpected condition"
1706 " - follow on");
1707
1708 /* determine the original cqr */
1709 cqr = previous_erp;
1710
1711 while (cqr->refers != NULL) {
1712 cqr = cqr->refers;
1713 }
1714
1715 /* for imprecise ending just do default erp */
1716 if (sense[1] & 0x01) {
1717
1718 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1719 "Imprecise ending is set - just retry");
1720
8e09f215 1721 previous_erp->status = DASD_CQR_FILLED;
1da177e4
LT
1722
1723 return previous_erp;
1724 }
1725
1726 /* determine the address of the CCW to be restarted */
1727 /* Imprecise ending is not set -> addr from IRB-SCSW */
23d805b6 1728 cpa = previous_erp->irb.scsw.cmd.cpa;
1da177e4
LT
1729
1730 if (cpa == 0) {
1731
1732 DEV_MESSAGE(KERN_DEBUG, device, "%s",
1733 "Unable to determine address of the CCW "
1734 "to be restarted");
1735
1736 previous_erp->status = DASD_CQR_FAILED;
1737
1738 return previous_erp;
1739 }
1740
1741 erp = previous_erp;
1742
1743 /* update the LO with the new returned sense data */
8e09f215 1744 LO_data = erp->data + sizeof(struct DE_eckd_data);
1da177e4
LT
1745
1746 if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
1747
1748 DEV_MESSAGE(KERN_ERR, device, "%s",
1749 "BUG - this should not happen");
1750
1751 previous_erp->status = DASD_CQR_FAILED;
1752
1753 return previous_erp;
1754 }
1755
1756 if ((sense[7] & 0x3F) == 0x01) {
1757 /* operation code is WRITE DATA -> data area orientation */
1758 LO_data[0] = 0x81;
1759
1760 } else if ((sense[7] & 0x3F) == 0x03) {
1761 /* operation code is FORMAT WRITE -> index orientation */
1762 LO_data[0] = 0xC3;
1763
1764 } else {
1765 LO_data[0] = sense[7]; /* operation */
1766 }
1767
1768 LO_data[1] = sense[8]; /* auxiliary */
1769 LO_data[2] = sense[9];
1770 LO_data[3] = sense[3]; /* count */
1771 LO_data[4] = sense[29]; /* seek_addr.cyl */
1772 LO_data[5] = sense[30]; /* seek_addr.cyl 2nd byte */
1773 LO_data[7] = sense[31]; /* seek_addr.head 2nd byte */
1774
1775 memcpy(&(LO_data[8]), &(sense[11]), 8);
1776
1777 /* TIC to the failed ccw */
1778 ccw = erp->cpaddr; /* addr of DE ccw */
1779 ccw++; /* addr of LE ccw */
1780 ccw++; /* addr of TIC ccw */
1781 ccw->cda = cpa;
1782
8e09f215 1783 erp->status = DASD_CQR_FILLED;
1da177e4
LT
1784
1785 return erp;
1786
1787} /* end dasd_3990_update_1B */
1788
1789/*
138c014d 1790 * DASD_3990_ERP_COMPOUND_RETRY
1da177e4
LT
1791 *
1792 * DESCRIPTION
1793 * Handles the compound ERP action retry code.
1794 * NOTE: At least one retry is done even if zero is specified
1795 * by the sense data. This makes enqueueing of the request
1796 * easier.
1797 *
1798 * PARAMETER
1799 * sense sense data of the actual error
1800 * erp pointer to the currently created ERP
1801 *
1802 * RETURN VALUES
1803 * erp modified ERP pointer
1804 *
1805 */
1806static void
1807dasd_3990_erp_compound_retry(struct dasd_ccw_req * erp, char *sense)
1808{
1809
1810 switch (sense[25] & 0x03) {
1811 case 0x00: /* no not retry */
1812 erp->retries = 1;
1813 break;
1814
1815 case 0x01: /* retry 2 times */
1816 erp->retries = 2;
1817 break;
1818
1819 case 0x02: /* retry 10 times */
1820 erp->retries = 10;
1821 break;
1822
1823 case 0x03: /* retry 256 times */
1824 erp->retries = 256;
1825 break;
1826
1827 default:
1828 BUG();
1829 }
1830
1831 erp->function = dasd_3990_erp_compound_retry;
1832
1833} /* end dasd_3990_erp_compound_retry */
1834
1835/*
138c014d 1836 * DASD_3990_ERP_COMPOUND_PATH
1da177e4
LT
1837 *
1838 * DESCRIPTION
1839 * Handles the compound ERP action for retry on alternate
1840 * channel path.
1841 *
1842 * PARAMETER
1843 * sense sense data of the actual error
1844 * erp pointer to the currently created ERP
1845 *
1846 * RETURN VALUES
1847 * erp modified ERP pointer
1848 *
1849 */
1850static void
1851dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense)
1852{
1853
1854 if (sense[25] & DASD_SENSE_BIT_3) {
1855 dasd_3990_erp_alternate_path(erp);
1856
1857 if (erp->status == DASD_CQR_FAILED) {
138c014d 1858 /* reset the lpm and the status to be able to
1da177e4
LT
1859 * try further actions. */
1860
1861 erp->lpm = 0;
8e09f215 1862 erp->status = DASD_CQR_NEED_ERP;
1da177e4
LT
1863 }
1864 }
1865
1866 erp->function = dasd_3990_erp_compound_path;
1867
1868} /* end dasd_3990_erp_compound_path */
1869
1870/*
138c014d 1871 * DASD_3990_ERP_COMPOUND_CODE
1da177e4
LT
1872 *
1873 * DESCRIPTION
1874 * Handles the compound ERP action for retry code.
1875 *
1876 * PARAMETER
1877 * sense sense data of the actual error
1878 * erp pointer to the currently created ERP
1879 *
1880 * RETURN VALUES
1881 * erp NEW ERP pointer
1882 *
1883 */
1884static struct dasd_ccw_req *
1885dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense)
1886{
1887
1888 if (sense[25] & DASD_SENSE_BIT_2) {
1889
1890 switch (sense[28]) {
1891 case 0x17:
138c014d 1892 /* issue a Diagnostic Control command with an
3a4fa0a2 1893 * Inhibit Write subcommand and controller modifier */
1da177e4
LT
1894 erp = dasd_3990_erp_DCTL(erp, 0x20);
1895 break;
138c014d 1896
1da177e4
LT
1897 case 0x25:
1898 /* wait for 5 seconds and retry again */
1899 erp->retries = 1;
138c014d 1900
1da177e4
LT
1901 dasd_3990_erp_block_queue (erp, 5*HZ);
1902 break;
138c014d 1903
1da177e4
LT
1904 default:
1905 /* should not happen - continue */
1906 break;
1907 }
1908 }
1909
1910 erp->function = dasd_3990_erp_compound_code;
1911
1912 return erp;
1913
1914} /* end dasd_3990_erp_compound_code */
1915
1916/*
138c014d 1917 * DASD_3990_ERP_COMPOUND_CONFIG
1da177e4
LT
1918 *
1919 * DESCRIPTION
1920 * Handles the compound ERP action for configruation
1921 * dependent error.
1922 * Note: duplex handling is not implemented (yet).
1923 *
1924 * PARAMETER
1925 * sense sense data of the actual error
1926 * erp pointer to the currently created ERP
1927 *
1928 * RETURN VALUES
1929 * erp modified ERP pointer
1930 *
1931 */
1932static void
1933dasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense)
1934{
1935
1936 if ((sense[25] & DASD_SENSE_BIT_1) && (sense[26] & DASD_SENSE_BIT_2)) {
1937
1938 /* set to suspended duplex state then restart */
8e09f215 1939 struct dasd_device *device = erp->startdev;
1da177e4
LT
1940
1941 DEV_MESSAGE(KERN_ERR, device, "%s",
1942 "Set device to suspended duplex state should be "
1943 "done!\n"
1944 "This is not implemented yet (for compound ERP)"
1945 " - please report to linux390@de.ibm.com");
1946
1947 }
1948
1949 erp->function = dasd_3990_erp_compound_config;
1950
1951} /* end dasd_3990_erp_compound_config */
1952
1953/*
138c014d 1954 * DASD_3990_ERP_COMPOUND
1da177e4
LT
1955 *
1956 * DESCRIPTION
138c014d 1957 * Does the further compound program action if
1da177e4
LT
1958 * compound retry was not successful.
1959 *
1960 * PARAMETER
1961 * sense sense data of the actual error
1962 * erp pointer to the current (failed) ERP
1963 *
1964 * RETURN VALUES
1965 * erp (additional) ERP pointer
1966 *
1967 */
1968static struct dasd_ccw_req *
1969dasd_3990_erp_compound(struct dasd_ccw_req * erp, char *sense)
1970{
1971
1972 if ((erp->function == dasd_3990_erp_compound_retry) &&
8e09f215 1973 (erp->status == DASD_CQR_NEED_ERP)) {
1da177e4
LT
1974
1975 dasd_3990_erp_compound_path(erp, sense);
1976 }
1977
1978 if ((erp->function == dasd_3990_erp_compound_path) &&
8e09f215 1979 (erp->status == DASD_CQR_NEED_ERP)) {
1da177e4
LT
1980
1981 erp = dasd_3990_erp_compound_code(erp, sense);
1982 }
1983
1984 if ((erp->function == dasd_3990_erp_compound_code) &&
8e09f215 1985 (erp->status == DASD_CQR_NEED_ERP)) {
1da177e4
LT
1986
1987 dasd_3990_erp_compound_config(erp, sense);
1988 }
1989
1990 /* if no compound action ERP specified, the request failed */
8e09f215 1991 if (erp->status == DASD_CQR_NEED_ERP)
1da177e4 1992 erp->status = DASD_CQR_FAILED;
1da177e4
LT
1993
1994 return erp;
1995
1996} /* end dasd_3990_erp_compound */
1997
f60c768c
SH
1998/*
1999 *DASD_3990_ERP_HANDLE_SIM
2000 *
2001 *DESCRIPTION
2002 * inspects the SIM SENSE data and starts an appropriate action
2003 *
2004 * PARAMETER
2005 * sense sense data of the actual error
2006 *
2007 * RETURN VALUES
2008 * none
2009 */
2010void
2011dasd_3990_erp_handle_sim(struct dasd_device *device, char *sense)
2012{
2013 /* print message according to log or message to operator mode */
2014 if ((sense[24] & DASD_SIM_MSG_TO_OP) || (sense[1] & 0x10)) {
2015
2016 /* print SIM SRC from RefCode */
2017 DEV_MESSAGE(KERN_ERR, device, "SIM - SRC: "
2018 "%02x%02x%02x%02x", sense[22],
2019 sense[23], sense[11], sense[12]);
2020 } else if (sense[24] & DASD_SIM_LOG) {
2021 /* print SIM SRC Refcode */
2022 DEV_MESSAGE(KERN_WARNING, device, "SIM - SRC: "
2023 "%02x%02x%02x%02x", sense[22],
2024 sense[23], sense[11], sense[12]);
2025 }
2026}
2027
1da177e4 2028/*
138c014d 2029 * DASD_3990_ERP_INSPECT_32
1da177e4
LT
2030 *
2031 * DESCRIPTION
2032 * Does a detailed inspection of the 32 byte sense data
138c014d 2033 * and sets up a related error recovery action.
1da177e4
LT
2034 *
2035 * PARAMETER
2036 * sense sense data of the actual error
2037 * erp pointer to the currently created default ERP
2038 *
2039 * RETURN VALUES
2040 * erp_filled pointer to the ERP
2041 *
2042 */
2043static struct dasd_ccw_req *
2044dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
2045{
2046
8e09f215 2047 struct dasd_device *device = erp->startdev;
1da177e4
LT
2048
2049 erp->function = dasd_3990_erp_inspect_32;
2050
f60c768c
SH
2051 /* check for SIM sense data */
2052 if ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)
2053 dasd_3990_erp_handle_sim(device, sense);
2054
1da177e4
LT
2055 if (sense[25] & DASD_SENSE_BIT_0) {
2056
2057 /* compound program action codes (byte25 bit 0 == '1') */
2058 dasd_3990_erp_compound_retry(erp, sense);
2059
2060 } else {
2061
2062 /* single program action codes (byte25 bit 0 == '0') */
2063 switch (sense[25]) {
2064
2065 case 0x00: /* success - use default ERP for retries */
2066 DEV_MESSAGE(KERN_DEBUG, device, "%s",
2067 "ERP called for successful request"
2068 " - just retry");
2069 break;
2070
2071 case 0x01: /* fatal error */
2072 DEV_MESSAGE(KERN_ERR, device, "%s",
8e09f215 2073 "Retry not recommended - Fatal error");
1da177e4
LT
2074
2075 erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
2076 break;
2077
2078 case 0x02: /* intervention required */
2079 case 0x03: /* intervention required during dual copy */
2080 erp = dasd_3990_erp_int_req(erp);
2081 break;
2082
2083 case 0x0F: /* length mismatch during update write command */
2084 DEV_MESSAGE(KERN_ERR, device, "%s",
2085 "update write command error - should not "
2086 "happen;\n"
2087 "Please send this message together with "
2088 "the above sense data to linux390@de."
2089 "ibm.com");
2090
2091 erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
2092 break;
2093
2094 case 0x10: /* logging required for other channel program */
2095 erp = dasd_3990_erp_action_10_32(erp, sense);
2096 break;
2097
2098 case 0x15: /* next track outside defined extend */
2099 DEV_MESSAGE(KERN_ERR, device, "%s",
2100 "next track outside defined extend - "
2101 "should not happen;\n"
2102 "Please send this message together with "
2103 "the above sense data to linux390@de."
2104 "ibm.com");
2105
2106 erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
2107 break;
2108
2109 case 0x1B: /* unexpected condition during write */
2110
2111 erp = dasd_3990_erp_action_1B_32(erp, sense);
2112 break;
2113
2114 case 0x1C: /* invalid data */
2115 DEV_MESSAGE(KERN_EMERG, device, "%s",
2116 "Data recovered during retry with PCI "
2117 "fetch mode active");
2118
2119 /* not possible to handle this situation in Linux */
2120 panic
2121 ("Invalid data - No way to inform application "
2122 "about the possibly incorrect data");
2123 break;
2124
2125 case 0x1D: /* state-change pending */
2126 DEV_MESSAGE(KERN_DEBUG, device, "%s",
2127 "A State change pending condition exists "
2128 "for the subsystem or device");
2129
2130 erp = dasd_3990_erp_action_4(erp, sense);
2131 break;
2132
2133 case 0x1E: /* busy */
2134 DEV_MESSAGE(KERN_DEBUG, device, "%s",
2135 "Busy condition exists "
2136 "for the subsystem or device");
2137 erp = dasd_3990_erp_action_4(erp, sense);
2138 break;
2139
2140 default: /* all others errors - default erp */
2141 break;
2142 }
2143 }
2144
2145 return erp;
2146
2147} /* end dasd_3990_erp_inspect_32 */
2148
2149/*
138c014d 2150 *****************************************************************************
1da177e4 2151 * main ERP control fuctions (24 and 32 byte sense)
138c014d 2152 *****************************************************************************
1da177e4
LT
2153 */
2154
6c5f57c7
SH
2155/*
2156 * DASD_3990_ERP_CONTROL_CHECK
2157 *
2158 * DESCRIPTION
2159 * Does a generic inspection if a control check occured and sets up
2160 * the related error recovery procedure
2161 *
2162 * PARAMETER
2163 * erp pointer to the currently created default ERP
2164 *
2165 * RETURN VALUES
2166 * erp_filled pointer to the erp
2167 */
2168
2169static struct dasd_ccw_req *
2170dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
2171{
2172 struct dasd_device *device = erp->startdev;
2173
23d805b6 2174 if (erp->refers->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK
6c5f57c7
SH
2175 | SCHN_STAT_CHN_CTRL_CHK)) {
2176 DEV_MESSAGE(KERN_DEBUG, device, "%s",
2177 "channel or interface control check");
2178 erp = dasd_3990_erp_action_4(erp, NULL);
2179 }
2180 return erp;
2181}
2182
1da177e4
LT
2183/*
2184 * DASD_3990_ERP_INSPECT
2185 *
2186 * DESCRIPTION
2187 * Does a detailed inspection for sense data by calling either
2188 * the 24-byte or the 32-byte inspection routine.
2189 *
2190 * PARAMETER
2191 * erp pointer to the currently created default ERP
2192 * RETURN VALUES
138c014d 2193 * erp_new contens was possibly modified
1da177e4
LT
2194 */
2195static struct dasd_ccw_req *
2196dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
2197{
2198
2199 struct dasd_ccw_req *erp_new = NULL;
2200 /* sense data are located in the refers record of the */
2201 /* already set up new ERP ! */
2202 char *sense = erp->refers->irb.ecw;
2203
8e09f215
SW
2204 /* if this problem occured on an alias retry on base */
2205 erp_new = dasd_3990_erp_inspect_alias(erp);
2206 if (erp_new)
2207 return erp_new;
2208
6c5f57c7
SH
2209 /* check if no concurrent sens is available */
2210 if (!erp->refers->irb.esw.esw0.erw.cons)
2211 erp_new = dasd_3990_erp_control_check(erp);
1da177e4 2212 /* distinguish between 24 and 32 byte sense data */
6c5f57c7 2213 else if (sense[27] & DASD_SENSE_BIT_0) {
1da177e4
LT
2214
2215 /* inspect the 24 byte sense data */
2216 erp_new = dasd_3990_erp_inspect_24(erp, sense);
2217
2218 } else {
2219
2220 /* inspect the 32 byte sense data */
2221 erp_new = dasd_3990_erp_inspect_32(erp, sense);
2222
2223 } /* end distinguish between 24 and 32 byte sense data */
2224
2225 return erp_new;
2226}
2227
2228/*
2229 * DASD_3990_ERP_ADD_ERP
138c014d 2230 *
1da177e4
LT
2231 * DESCRIPTION
2232 * This funtion adds an additional request block (ERP) to the head of
2233 * the given cqr (or erp).
2234 * This erp is initialized as an default erp (retry TIC)
2235 *
2236 * PARAMETER
138c014d 2237 * cqr head of the current ERP-chain (or single cqr if
1da177e4
LT
2238 * first error)
2239 * RETURN VALUES
2240 * erp pointer to new ERP-chain head
2241 */
2242static struct dasd_ccw_req *
2243dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
2244{
2245
8e09f215 2246 struct dasd_device *device = cqr->startdev;
1da177e4
LT
2247 struct ccw1 *ccw;
2248
2249 /* allocate additional request block */
2250 struct dasd_ccw_req *erp;
2251
8e09f215 2252 erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, device);
1da177e4
LT
2253 if (IS_ERR(erp)) {
2254 if (cqr->retries <= 0) {
2255 DEV_MESSAGE(KERN_ERR, device, "%s",
2256 "Unable to allocate ERP request");
2257 cqr->status = DASD_CQR_FAILED;
2258 cqr->stopclk = get_clock ();
2259 } else {
2260 DEV_MESSAGE (KERN_ERR, device,
2261 "Unable to allocate ERP request "
2262 "(%i retries left)",
2263 cqr->retries);
8e09f215 2264 dasd_block_set_timer(device->block, (HZ << 3));
1da177e4
LT
2265 }
2266 return cqr;
2267 }
2268
2269 /* initialize request with default TIC to current ERP/CQR */
2270 ccw = erp->cpaddr;
2271 ccw->cmd_code = CCW_CMD_NOOP;
2272 ccw->flags = CCW_FLAG_CC;
2273 ccw++;
2274 ccw->cmd_code = CCW_CMD_TIC;
2275 ccw->cda = (long)(cqr->cpaddr);
2276 erp->function = dasd_3990_erp_add_erp;
2277 erp->refers = cqr;
8e09f215
SW
2278 erp->startdev = device;
2279 erp->memdev = device;
2280 erp->block = cqr->block;
1da177e4
LT
2281 erp->magic = cqr->magic;
2282 erp->expires = 0;
2283 erp->retries = 256;
2284 erp->buildclk = get_clock();
2285
2286 erp->status = DASD_CQR_FILLED;
2287
2288 return erp;
2289}
2290
2291/*
138c014d
HH
2292 * DASD_3990_ERP_ADDITIONAL_ERP
2293 *
1da177e4
LT
2294 * DESCRIPTION
2295 * An additional ERP is needed to handle the current error.
2296 * Add ERP to the head of the ERP-chain containing the ERP processing
2297 * determined based on the sense data.
2298 *
2299 * PARAMETER
138c014d 2300 * cqr head of the current ERP-chain (or single cqr if
1da177e4
LT
2301 * first error)
2302 *
2303 * RETURN VALUES
2304 * erp pointer to new ERP-chain head
2305 */
2306static struct dasd_ccw_req *
2307dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr)
2308{
2309
2310 struct dasd_ccw_req *erp = NULL;
2311
2312 /* add erp and initialize with default TIC */
2313 erp = dasd_3990_erp_add_erp(cqr);
2314
2315 /* inspect sense, determine specific ERP if possible */
2316 if (erp != cqr) {
2317
2318 erp = dasd_3990_erp_inspect(erp);
2319 }
2320
2321 return erp;
2322
2323} /* end dasd_3990_erp_additional_erp */
2324
2325/*
2326 * DASD_3990_ERP_ERROR_MATCH
2327 *
2328 * DESCRIPTION
2329 * Check if the device status of the given cqr is the same.
2330 * This means that the failed CCW and the relevant sense data
2331 * must match.
2332 * I don't distinguish between 24 and 32 byte sense because in case of
2333 * 24 byte sense byte 25 and 27 is set as well.
2334 *
2335 * PARAMETER
138c014d 2336 * cqr1 first cqr, which will be compared with the
1da177e4
LT
2337 * cqr2 second cqr.
2338 *
2339 * RETURN VALUES
2340 * match 'boolean' for match found
2341 * returns 1 if match found, otherwise 0.
2342 */
2343static int
2344dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
2345{
2346
5c12f240
SW
2347 if (cqr1->startdev != cqr2->startdev)
2348 return 0;
1da177e4 2349
6c5f57c7
SH
2350 if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons)
2351 return 0;
2352
2353 if ((cqr1->irb.esw.esw0.erw.cons == 0) &&
2354 (cqr2->irb.esw.esw0.erw.cons == 0)) {
23d805b6 2355 if ((cqr1->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
6c5f57c7 2356 SCHN_STAT_CHN_CTRL_CHK)) ==
23d805b6 2357 (cqr2->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
6c5f57c7
SH
2358 SCHN_STAT_CHN_CTRL_CHK)))
2359 return 1; /* match with ifcc*/
2360 }
1da177e4
LT
2361 /* check sense data; byte 0-2,25,27 */
2362 if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) &&
2363 (cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) &&
2364 (cqr1->irb.ecw[25] == cqr2->irb.ecw[25]))) {
2365
2366 return 0; /* sense doesn't match */
2367 }
2368
2369 return 1; /* match */
2370
2371} /* end dasd_3990_erp_error_match */
2372
2373/*
2374 * DASD_3990_ERP_IN_ERP
2375 *
2376 * DESCRIPTION
2377 * check if the current error already happened before.
2378 * quick exit if current cqr is not an ERP (cqr->refers=NULL)
2379 *
2380 * PARAMETER
2381 * cqr failed cqr (either original cqr or already an erp)
2382 *
2383 * RETURN VALUES
138c014d 2384 * erp erp-pointer to the already defined error
1da177e4
LT
2385 * recovery procedure OR
2386 * NULL if a 'new' error occurred.
2387 */
2388static struct dasd_ccw_req *
2389dasd_3990_erp_in_erp(struct dasd_ccw_req *cqr)
2390{
2391
2392 struct dasd_ccw_req *erp_head = cqr, /* save erp chain head */
2393 *erp_match = NULL; /* save erp chain head */
2394 int match = 0; /* 'boolean' for matching error found */
2395
2396 if (cqr->refers == NULL) { /* return if not in erp */
2397 return NULL;
2398 }
2399
2400 /* check the erp/cqr chain for current error */
2401 do {
2402 match = dasd_3990_erp_error_match(erp_head, cqr->refers);
2403 erp_match = cqr; /* save possible matching erp */
2404 cqr = cqr->refers; /* check next erp/cqr in queue */
2405
2406 } while ((cqr->refers != NULL) && (!match));
2407
2408 if (!match) {
2409 return NULL; /* no match was found */
2410 }
2411
2412 return erp_match; /* return address of matching erp */
2413
2414} /* END dasd_3990_erp_in_erp */
2415
2416/*
2417 * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense)
2418 *
2419 * DESCRIPTION
138c014d 2420 * No retry is left for the current ERP. Check what has to be done
1da177e4
LT
2421 * with the ERP.
2422 * - do further defined ERP action or
138c014d 2423 * - wait for interrupt or
1da177e4
LT
2424 * - exit with permanent error
2425 *
2426 * PARAMETER
2427 * erp ERP which is in progress with no retry left
2428 *
2429 * RETURN VALUES
2430 * erp modified/additional ERP
2431 */
2432static struct dasd_ccw_req *
2433dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
2434{
2435
8e09f215 2436 struct dasd_device *device = erp->startdev;
1da177e4
LT
2437 char *sense = erp->irb.ecw;
2438
2439 /* check for 24 byte sense ERP */
2440 if ((erp->function == dasd_3990_erp_bus_out) ||
2441 (erp->function == dasd_3990_erp_action_1) ||
2442 (erp->function == dasd_3990_erp_action_4)) {
2443
2444 erp = dasd_3990_erp_action_1(erp);
2445
2446 } else if (erp->function == dasd_3990_erp_action_5) {
2447
2448 /* retries have not been successful */
2449 /* prepare erp for retry on different channel path */
2450 erp = dasd_3990_erp_action_1(erp);
2451
2452 if (!(sense[2] & DASD_SENSE_BIT_0)) {
2453
138c014d 2454 /* issue a Diagnostic Control command with an
1da177e4
LT
2455 * Inhibit Write subcommand */
2456
2457 switch (sense[25]) {
2458 case 0x17:
2459 case 0x57:{ /* controller */
2460 erp = dasd_3990_erp_DCTL(erp, 0x20);
2461 break;
2462 }
2463 case 0x18:
2464 case 0x58:{ /* channel path */
2465 erp = dasd_3990_erp_DCTL(erp, 0x40);
2466 break;
2467 }
2468 case 0x19:
2469 case 0x59:{ /* storage director */
2470 erp = dasd_3990_erp_DCTL(erp, 0x80);
2471 break;
2472 }
2473 default:
2474 DEV_MESSAGE(KERN_DEBUG, device,
2475 "invalid subcommand modifier 0x%x "
2476 "for Diagnostic Control Command",
2477 sense[25]);
2478 }
2479 }
2480
2481 /* check for 32 byte sense ERP */
2482 } else if ((erp->function == dasd_3990_erp_compound_retry) ||
2483 (erp->function == dasd_3990_erp_compound_path) ||
2484 (erp->function == dasd_3990_erp_compound_code) ||
2485 (erp->function == dasd_3990_erp_compound_config)) {
2486
2487 erp = dasd_3990_erp_compound(erp, sense);
2488
2489 } else {
2490 /* No retry left and no additional special handling */
2491 /*necessary */
2492 DEV_MESSAGE(KERN_ERR, device,
2493 "no retries left for erp %p - "
2494 "set status to FAILED", erp);
2495
2496 erp->status = DASD_CQR_FAILED;
2497 }
2498
2499 return erp;
2500
2501} /* end dasd_3990_erp_further_erp */
2502
2503/*
138c014d 2504 * DASD_3990_ERP_HANDLE_MATCH_ERP
1da177e4
LT
2505 *
2506 * DESCRIPTION
2507 * An error occurred again and an ERP has been detected which is already
138c014d 2508 * used to handle this error (e.g. retries).
1da177e4
LT
2509 * All prior ERP's are asumed to be successful and therefore removed
2510 * from queue.
138c014d 2511 * If retry counter of matching erp is already 0, it is checked if further
1da177e4
LT
2512 * action is needed (besides retry) or if the ERP has failed.
2513 *
2514 * PARAMETER
2515 * erp_head first ERP in ERP-chain
2516 * erp ERP that handles the actual error.
2517 * (matching erp)
2518 *
2519 * RETURN VALUES
2520 * erp modified/additional ERP
2521 */
2522static struct dasd_ccw_req *
2523dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head,
2524 struct dasd_ccw_req *erp)
2525{
2526
8e09f215 2527 struct dasd_device *device = erp_head->startdev;
1da177e4
LT
2528 struct dasd_ccw_req *erp_done = erp_head; /* finished req */
2529 struct dasd_ccw_req *erp_free = NULL; /* req to be freed */
2530
2531 /* loop over successful ERPs and remove them from chanq */
2532 while (erp_done != erp) {
2533
2534 if (erp_done == NULL) /* end of chain reached */
2535 panic(PRINTK_HEADER "Programming error in ERP! The "
2536 "original request was lost\n");
2537
2538 /* remove the request from the device queue */
8e09f215 2539 list_del(&erp_done->blocklist);
1da177e4
LT
2540
2541 erp_free = erp_done;
2542 erp_done = erp_done->refers;
2543
2544 /* free the finished erp request */
8e09f215 2545 dasd_free_erp_request(erp_free, erp_free->memdev);
1da177e4
LT
2546
2547 } /* end while */
2548
2549 if (erp->retries > 0) {
2550
2551 char *sense = erp->refers->irb.ecw;
2552
2553 /* check for special retries */
2554 if (erp->function == dasd_3990_erp_action_4) {
2555
2556 erp = dasd_3990_erp_action_4(erp, sense);
2557
2558 } else if (erp->function == dasd_3990_erp_action_1B_32) {
2559
2560 erp = dasd_3990_update_1B(erp, sense);
2561
2562 } else if (erp->function == dasd_3990_erp_int_req) {
2563
2564 erp = dasd_3990_erp_int_req(erp);
2565
2566 } else {
2567 /* simple retry */
2568 DEV_MESSAGE(KERN_DEBUG, device,
2569 "%i retries left for erp %p",
2570 erp->retries, erp);
2571
2572 /* handle the request again... */
8e09f215 2573 erp->status = DASD_CQR_FILLED;
1da177e4
LT
2574 }
2575
2576 } else {
2577 /* no retry left - check for further necessary action */
2578 /* if no further actions, handle rest as permanent error */
2579 erp = dasd_3990_erp_further_erp(erp);
2580 }
2581
2582 return erp;
2583
2584} /* end dasd_3990_erp_handle_match_erp */
2585
2586/*
2587 * DASD_3990_ERP_ACTION
2588 *
2589 * DESCRIPTION
5d67d164 2590 * control routine for 3990 erp actions.
1da177e4
LT
2591 * Has to be called with the queue lock (namely the s390_irq_lock) acquired.
2592 *
2593 * PARAMETER
2594 * cqr failed cqr (either original cqr or already an erp)
2595 *
2596 * RETURN VALUES
2597 * erp erp-pointer to the head of the ERP action chain.
2598 * This means:
2599 * - either a ptr to an additional ERP cqr or
138c014d 2600 * - the original given cqr (which's status might
1da177e4
LT
2601 * be modified)
2602 */
2603struct dasd_ccw_req *
2604dasd_3990_erp_action(struct dasd_ccw_req * cqr)
2605{
1da177e4 2606 struct dasd_ccw_req *erp = NULL;
8e09f215 2607 struct dasd_device *device = cqr->startdev;
9575bf26 2608 struct dasd_ccw_req *temp_erp = NULL;
1da177e4 2609
9575bf26
HH
2610 if (device->features & DASD_FEATURE_ERPLOG) {
2611 /* print current erp_chain */
2612 DEV_MESSAGE(KERN_ERR, device, "%s",
2613 "ERP chain at BEGINNING of ERP-ACTION");
1da177e4
LT
2614 for (temp_erp = cqr;
2615 temp_erp != NULL; temp_erp = temp_erp->refers) {
2616
2617 DEV_MESSAGE(KERN_ERR, device,
2618 " erp %p (%02x) refers to %p",
2619 temp_erp, temp_erp->status,
2620 temp_erp->refers);
2621 }
2622 }
1da177e4
LT
2623
2624 /* double-check if current erp/cqr was successfull */
23d805b6
PO
2625 if ((cqr->irb.scsw.cmd.cstat == 0x00) &&
2626 (cqr->irb.scsw.cmd.dstat ==
2627 (DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
1da177e4
LT
2628
2629 DEV_MESSAGE(KERN_DEBUG, device,
2630 "ERP called for successful request %p"
2631 " - NO ERP necessary", cqr);
2632
2633 cqr->status = DASD_CQR_DONE;
2634
2635 return cqr;
2636 }
1da177e4
LT
2637
2638 /* check if error happened before */
2639 erp = dasd_3990_erp_in_erp(cqr);
2640
2641 if (erp == NULL) {
2642 /* no matching erp found - set up erp */
2643 erp = dasd_3990_erp_additional_erp(cqr);
2644 } else {
2645 /* matching erp found - set all leading erp's to DONE */
2646 erp = dasd_3990_erp_handle_match_erp(cqr, erp);
2647 }
2648
9575bf26
HH
2649 if (device->features & DASD_FEATURE_ERPLOG) {
2650 /* print current erp_chain */
2651 DEV_MESSAGE(KERN_ERR, device, "%s",
2652 "ERP chain at END of ERP-ACTION");
1da177e4
LT
2653 for (temp_erp = erp;
2654 temp_erp != NULL; temp_erp = temp_erp->refers) {
2655
2656 DEV_MESSAGE(KERN_ERR, device,
2657 " erp %p (%02x) refers to %p",
2658 temp_erp, temp_erp->status,
2659 temp_erp->refers);
2660 }
2661 }
1da177e4 2662
8e09f215
SW
2663 /* enqueue ERP request if it's a new one */
2664 if (list_empty(&erp->blocklist)) {
2665 cqr->status = DASD_CQR_IN_ERP;
2666 /* add erp request before the cqr */
2667 list_add_tail(&erp->blocklist, &cqr->blocklist);
1da177e4
LT
2668 }
2669
2670 return erp;
2671
2672} /* end dasd_3990_erp_action */