File: /usr/src/linux/drivers/s390/block/dasd_3990_erp.c
1 /*
2 * File...........: linux/drivers/s390/block/dasd_3990_erp.c
3 * Author(s)......: Horst Hummel <Horst.Hummel@de.ibm.com>
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 *
8 * History of changes:
9 * 05/14/01 fixed PL030160GTO (BUG() in erp_action_5)
10 */
11
12 #include <asm/ccwcache.h>
13 #include <asm/idals.h>
14 #include <asm/s390io.h>
15 #include <linux/timer.h>
16
17 #include "dasd_int.h"
18 #include "dasd_eckd.h"
19 #include "dasd_3990_erp.h"
20
21 #ifdef PRINTK_HEADER
22 #undef PRINTK_HEADER
23 #endif /* PRINTK_HEADER */
24 #define PRINTK_HEADER "dasd_erp(3990): "
25
26 /*
27 *****************************************************************************
28 * SECTION DEBUG ROUTINES
29 *****************************************************************************
30 */
31 void
32 log_erp_chain (ccw_req_t *cqr,
33 int caller,
34 __u32 cpa)
35 {
36
37 ccw_req_t *loop_cqr = cqr;
38 dasd_device_t *device = cqr->device;
39
40 int i;
41 char *nl,
42 *end_cqr,
43 *begin,
44 *end;
45
46 /* dump sense data */
47 if (device->discipline &&
48 device->discipline->dump_sense ) {
49
50 device->discipline->dump_sense (device,
51 cqr);
52 }
53
54 /* log the channel program */
55 while (loop_cqr != NULL) {
56
57 DASD_MESSAGE (KERN_ERR, device,
58 "(%s) ERP chain report for req: %p\n",
59 caller == 0 ? "EXAMINE" : "ACTION",
60 loop_cqr);
61
62 nl = (char *) loop_cqr;
63 end_cqr = nl + sizeof (ccw_req_t);
64
65 while (nl < end_cqr) {
66
67 DASD_MESSAGE (KERN_ERR, device,
68 "%p: %02x%02x%02x%02x %02x%02x%02x%02x "
69 "%02x%02x%02x%02x %02x%02x%02x%02x\n",
70 nl,
71 nl[0], nl[1], nl[2], nl[3],
72 nl[4], nl[5], nl[6], nl[7],
73 nl[8], nl[9], nl[10], nl[11],
74 nl[12], nl[13], nl[14], nl[15]);
75 nl +=16;
76 }
77
78 nl = (char *) loop_cqr->cpaddr;
79
80 if (loop_cqr->cplength > 40) { /* log only parts of the CP */
81
82 DASD_MESSAGE (KERN_ERR, device, "%s",
83 "Start of channel program:\n");
84
85 for (i = 0; i < 20; i += 2) {
86
87 DASD_MESSAGE (KERN_ERR, device,
88 "%p: %02x%02x%02x%02x %02x%02x%02x%02x "
89 "%02x%02x%02x%02x %02x%02x%02x%02x\n",
90 nl,
91 nl[0], nl[1], nl[2], nl[3],
92 nl[4], nl[5], nl[6], nl[7],
93 nl[8], nl[9], nl[10], nl[11],
94 nl[12], nl[13], nl[14], nl[15]);
95
96 nl += 16;
97 }
98
99 DASD_MESSAGE (KERN_ERR, device, "%s",
100 "End of channel program:\n");
101
102 nl = (char *) loop_cqr->cpaddr;
103 nl += ((loop_cqr->cplength - 10) * 8);
104
105 for (i = 0; i < 20; i += 2) {
106
107 DASD_MESSAGE (KERN_ERR, device,
108 "%p: %02x%02x%02x%02x %02x%02x%02x%02x "
109 "%02x%02x%02x%02x %02x%02x%02x%02x\n",
110 nl,
111 nl[0], nl[1], nl[2], nl[3],
112 nl[4], nl[5], nl[6], nl[7],
113 nl[8], nl[9], nl[10], nl[11],
114 nl[12], nl[13], nl[14], nl[15]);
115
116 nl += 16;
117 }
118
119 } else { /* log the whole CP */
120
121 DASD_MESSAGE (KERN_ERR, device, "%s",
122 "Channel program (complete):\n");
123
124 for (i = 0; i < (loop_cqr->cplength + 4); i += 2) {
125
126 DASD_MESSAGE (KERN_ERR, device,
127 "%p: %02x%02x%02x%02x %02x%02x%02x%02x "
128 "%02x%02x%02x%02x %02x%02x%02x%02x\n",
129 nl,
130 nl[0], nl[1], nl[2], nl[3],
131 nl[4], nl[5], nl[6], nl[7],
132 nl[8], nl[9], nl[10], nl[11],
133 nl[12], nl[13], nl[14], nl[15]);
134
135 nl += 16;
136 }
137 }
138
139 /* log bytes arround failed CCW if not already done */
140 begin = (char *) loop_cqr->cpaddr;
141 end = begin + ((loop_cqr->cplength+4) * 8);
142 nl = (void *)(long)cpa;
143
144 if (loop_cqr == cqr) { /* log only once */
145
146 /* if not whole CP logged OR CCW outside logged CP */
147 if ((loop_cqr->cplength > 40) ||
148 ((nl < begin ) &&
149 (nl > end ) ) ) {
150
151 nl -= 10*8; /* start some bytes before */
152
153 DASD_MESSAGE (KERN_ERR, device,
154 "Failed CCW (%p) (area):\n",
155 (void *)(long)cpa);
156
157 for (i = 0; i < 20; i += 2) {
158
159 DASD_MESSAGE (KERN_ERR, device,
160 "%p: %02x%02x%02x%02x %02x%02x%02x%02x "
161 "%02x%02x%02x%02x %02x%02x%02x%02x\n",
162 nl,
163 nl[0], nl[1], nl[2], nl[3],
164 nl[4], nl[5], nl[6], nl[7],
165 nl[8], nl[9], nl[10], nl[11],
166 nl[12], nl[13], nl[14], nl[15]);
167
168 nl += 16;
169 }
170
171 } else {
172
173 DASD_MESSAGE (KERN_ERR, device,
174 "Failed CCW (%p) already logged\n",
175 (void *)(long)cpa);
176 }
177 }
178
179 loop_cqr = loop_cqr->refers;
180 }
181
182 } /* end log_erp_chain */
183
184 /*
185 *****************************************************************************
186 * SECTION ERP EXAMINATION
187 *****************************************************************************
188 */
189
190 /*
191 * DASD_3990_ERP_EXAMINE_24
192 *
193 * DESCRIPTION
194 * Checks only for fatal (unrecoverable) error.
195 * A detailed examination of the sense data is done later outside
196 * the interrupt handler.
197 *
198 * Each bit configuration leading to an action code 2 (Exit with
199 * programming error or unusual condition indication)
200 * are handled as fatal errorīs.
201 *
202 * All other configurations are handled as recoverable errors.
203 *
204 * RETURN VALUES
205 * dasd_era_fatal for all fatal (unrecoverable errors)
206 * dasd_era_recover for all others.
207 */
208 dasd_era_t
209 dasd_3990_erp_examine_24 (ccw_req_t *cqr,
210 char *sense)
211 {
212
213 dasd_device_t *device = cqr->device;
214
215 /* check for 'Command Reject' */
216 if (( sense[0] & SNS0_CMD_REJECT ) &&
217 (!(sense[2] & SNS2_ENV_DATA_PRESENT)) ) {
218
219 DASD_MESSAGE (KERN_ERR, device, "%s",
220 "EXAMINE 24: Command Reject detected - "
221 "fatal error");
222
223 return dasd_era_fatal;
224 }
225
226 /* check for 'Invalid Track Format' */
227 if (( sense[1] & SNS1_INV_TRACK_FORMAT ) &&
228 (!(sense[2] & SNS2_ENV_DATA_PRESENT)) ) {
229
230 DASD_MESSAGE (KERN_ERR, device, "%s",
231 "EXAMINE 24: Invalid Track Format detected "
232 "- fatal error");
233
234 return dasd_era_fatal;
235 }
236
237 /* check for 'No Record Found' */
238 if (sense[1] & SNS1_NO_REC_FOUND) {
239
240 DASD_MESSAGE (KERN_ERR, device, "%s",
241 "EXAMINE 24: No Record Found detected "
242 "- fatal error");
243
244 return dasd_era_fatal;
245 }
246
247 /* return recoverable for all others */
248 return dasd_era_recover;
249 } /* END dasd_3990_erp_examine_24 */
250
251 /*
252 * DASD_3990_ERP_EXAMINE_32
253 *
254 * DESCRIPTION
255 * Checks only for fatal/no/recoverable error.
256 * A detailed examination of the sense data is done later outside
257 * the interrupt handler.
258 *
259 * RETURN VALUES
260 * dasd_era_none no error
261 * dasd_era_fatal for all fatal (unrecoverable errors)
262 * dasd_era_recover for recoverable others.
263 */
264 dasd_era_t
265 dasd_3990_erp_examine_32 (ccw_req_t *cqr,
266 char *sense)
267 {
268
269 dasd_device_t *device = cqr->device;
270
271 switch (sense[25]) {
272 case 0x00:
273 return dasd_era_none;
274
275 case 0x01:
276 DASD_MESSAGE (KERN_ERR, device, "%s",
277 "EXAMINE 32: fatal error");
278 return dasd_era_fatal;
279
280 default:
281
282 return dasd_era_recover;
283 }
284
285 } /* end dasd_3990_erp_examine_32 */
286
287 /*
288 * DASD_3990_ERP_EXAMINE
289 *
290 * DESCRIPTION
291 * Checks only for fatal/no/recover error.
292 * A detailed examination of the sense data is done later outside
293 * the interrupt handler.
294 *
295 * The logic is based on the 'IBM 3990 Storage Control Reference' manual
296 * 'Chapter 7. Error Recovery Procedures'.
297 *
298 * RETURN VALUES
299 * dasd_era_none no error
300 * dasd_era_fatal for all fatal (unrecoverable errors)
301 * dasd_era_recover for all others.
302 */
303 dasd_era_t
304 dasd_3990_erp_examine (ccw_req_t *cqr,
305 devstat_t *stat)
306 {
307
308 char *sense = stat->ii.sense.data;
309 dasd_era_t era = dasd_era_recover;
310
311 /* check for successful execution first */
312 if (stat->cstat == 0x00 &&
313 stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) )
314 return dasd_era_none;
315
316 /* distinguish between 24 and 32 byte sense data */
317 if (sense[27] & DASD_SENSE_BIT_0) {
318
319 era = dasd_3990_erp_examine_24 (cqr,
320 sense);
321
322 } else {
323
324 era = dasd_3990_erp_examine_32 (cqr,
325 sense);
326
327 }
328
329 /* log the erp chain if fatal error occurred */
330 if (era == dasd_era_fatal) {
331
332 log_erp_chain (cqr,
333 0,
334 stat->cpa);
335 }
336
337 return era;
338
339 } /* END dasd_3990_erp_examine */
340
341 /*
342 *****************************************************************************
343 * SECTION ERP HANDLING
344 *****************************************************************************
345 */
346 /*
347 *****************************************************************************
348 * 24 and 32 byte sense ERP functions
349 *****************************************************************************
350 */
351
352 /*
353 * DASD_3990_ERP_CLEANUP
354 *
355 * DESCRIPTION
356 * Removes the already build but not neccessary ERP request and sets
357 * the status of the original cqr / erp to the given (final) status
358 *
359 * PARAMETER
360 * erp request to be blocked
361 * final_status either CQR_STATUS_DONE or CQR_STATUS_FAILED
362 *
363 * RETURN VALUES
364 * cqr original cqr
365 */
366 ccw_req_t *
367 dasd_3990_erp_cleanup (ccw_req_t *erp,
368 char final_status)
369 {
370
371 ccw_req_t *cqr = erp->refers;
372
373 dasd_free_request (erp, erp->device);
374
375 check_then_set (&cqr->status,
376 CQR_STATUS_ERROR,
377 final_status);
378
379 return cqr;
380
381 } /* end dasd_3990_erp_cleanup */
382
383 /*
384 * DASD_3990_ERP_BLOCK_QUEUE
385 *
386 * DESCRIPTION
387 * Block the given device request queue to prevent from further
388 * processing until the started timer has expired or an related
389 * interrupt was received.
390 *
391 * PARAMETER
392 * erp request to be blocked
393 * expires time to wait until restart (in seconds)
394 *
395 * RETURN VALUES
396 * void
397 */
398 void
399 dasd_3990_erp_block_queue (ccw_req_t *erp,
400 unsigned long expires)
401 {
402
403 dasd_device_t *device = erp->device;
404
405 DASD_MESSAGE (KERN_INFO, device,
406 "blocking request queue for %is",
407 (int) expires);
408
409 check_then_set (&erp->status,
410 CQR_STATUS_ERROR,
411 CQR_STATUS_PENDING);
412
413 /* restart queue after some time */
414 device->timer.function = dasd_3990_erp_restart_queue;
415 device->timer.data = (unsigned long) erp;
416 device->timer.expires = jiffies + (expires * HZ);
417
418 add_timer(&device->timer);
419
420 } /* end dasd_3990_erp_block_queue */
421
422 /*
423 * DASD_3990_ERP_RESTART_QUEUE
424 *
425 * DESCRIPTION
426 * Restarts request currently in status PENDING.
427 * This has to be done if either an related interrupt has received, or
428 * a timer has expired.
429 *
430 *
431 * PARAMETER
432 * erp pointer to the PENDING ERP
433 *
434 * RETURN VALUES
435 * void
436 *
437 */
438 void
439 dasd_3990_erp_restart_queue (unsigned long erp)
440 {
441
442 ccw_req_t *cqr = (void *) erp;
443 dasd_device_t *device = cqr->device;
444 unsigned long flags;
445
446 /* get the needed locks to modify the request queue */
447 s390irq_spin_lock_irqsave (device->devinfo.irq,
448 flags);
449
450 /* 'restart' the device queue */
451 if (cqr->status == CQR_STATUS_PENDING) {
452
453 DASD_MESSAGE (KERN_INFO, device, "%s",
454 "request queue restarted by MIH");
455
456 check_then_set (&cqr->status,
457 CQR_STATUS_PENDING,
458 CQR_STATUS_QUEUED);
459 }
460
461 /* release the lock */
462 s390irq_spin_unlock_irqrestore (device->devinfo.irq,
463 flags);
464
465 dasd_schedule_bh (device);
466
467 } /* end dasd_3990_erp_restart_queue */
468
469 /*
470 * DASD_3990_ERP_INT_REQ
471 *
472 * DESCRIPTION
473 * Handles 'Intervention Required' error.
474 * This means either device offline or not installed.
475 *
476 * PARAMETER
477 * erp current erp
478 * RETURN VALUES
479 * erp modified erp
480 */
481 ccw_req_t *
482 dasd_3990_erp_int_req (ccw_req_t *erp)
483 {
484
485 dasd_device_t *device = erp->device;
486
487 /* first time set initial retry counter and erp_function */
488 /* and retry once without blocking queue */
489 /* (this enables easier enqueing of the cqr) */
490 if (erp->function != dasd_3990_erp_int_req) {
491
492 erp->retries = 256;
493 erp->function = dasd_3990_erp_int_req;
494
495 } else {
496
497 /* issue a message and wait for 'device ready' interrupt */
498 DASD_MESSAGE (KERN_ERR, device, "%s",
499 "is offline or not installed - "
500 "INTERVENTION REQUIRED!!");
501
502 dasd_3990_erp_block_queue (erp,
503 60);
504 }
505
506 return erp;
507
508 } /* end dasd_3990_erp_int_req */
509
510 /*
511 * DASD_3990_ERP_ALTERNATE_PATH
512 *
513 * DESCRIPTION
514 * Repeat the operation on a different channel path.
515 * If all alternate paths have been tried, the request is posted with a
516 * permanent error.
517 *
518 * PARAMETER
519 * erp pointer to the current ERP
520 *
521 * RETURN VALUES
522 * erp modified pointer to the ERP
523 *
524 */
525 void
526 dasd_3990_erp_alternate_path (ccw_req_t *erp)
527 {
528
529 dasd_device_t *device = erp->device;
530 int irq = device->devinfo.irq;
531
532 /* try alternate valid path */
533 erp->lpm &= ~(erp->dstat->lpum);
534 erp->options |= DOIO_VALID_LPM; /* use LPM for DO_IO */
535
536 if ((erp->lpm & ioinfo[irq]->opm) != 0x00) {
537
538 DASD_MESSAGE (KERN_DEBUG, device,
539 "try alternate lpm=%x (lpum=%x / opm=%x)",
540 erp->lpm,
541 erp->dstat->lpum,
542 ioinfo[irq]->opm);
543
544 /* reset status to queued to handle the request again... */
545 check_then_set (&erp->status,
546 CQR_STATUS_ERROR,
547 CQR_STATUS_QUEUED);
548
549 erp->retries = 1;
550
551 } else {
552
553 DASD_MESSAGE (KERN_ERR, device,
554 "No alternate channel path left (lpum=%x / "
555 "opm=%x) -> permanent error",
556 erp->dstat->lpum,
557 ioinfo[irq]->opm);
558
559 /* post request with permanent error */
560 check_then_set (&erp->status,
561 CQR_STATUS_ERROR,
562 CQR_STATUS_FAILED);
563
564 }
565
566 } /* end dasd_3990_erp_alternate_path */
567
568 /*
569 * DASD_3990_ERP_DCTL
570 *
571 * DESCRIPTION
572 * Setup cqr to do the Diagnostic Control (DCTL) command with an
573 * Inhibit Write subcommand (0x20) and the given modifier.
574 *
575 * PARAMETER
576 * erp pointer to the current (failed) ERP
577 * modifier subcommand modifier
578 *
579 * RETURN VALUES
580 * dctl_cqr pointer to NEW dctl_cqr
581 *
582 */
583 ccw_req_t *
584 dasd_3990_erp_DCTL (ccw_req_t *erp,
585 char modifier)
586 {
587
588 dasd_device_t *device = erp->device;
589 DCTL_data_t *DCTL_data;
590 ccw1_t *ccw;
591 ccw_req_t *dctl_cqr = dasd_alloc_request ((char *) &erp->magic,
592 1,
593 sizeof(DCTL_data_t),
594 erp->device);
595
596 if (!dctl_cqr) {
597
598 DASD_MESSAGE (KERN_ERR, device, "%s",
599 "Unable to allocate DCTL-CQR");
600
601 check_then_set (&erp->status,
602 CQR_STATUS_ERROR,
603 CQR_STATUS_FAILED);
604
605 return erp;
606 }
607
608 DCTL_data = dctl_cqr->data;
609
610 DCTL_data->subcommand = 0x02; /* Inhibit Write */
611 DCTL_data->modifier = modifier;
612
613 ccw = dctl_cqr->cpaddr;
614 memset (ccw, 0, sizeof (ccw1_t));
615 ccw->cmd_code = CCW_CMD_DCTL;
616 ccw->count = 4;
617 if (dasd_set_normalized_cda(ccw,
618 __pa (DCTL_data), dctl_cqr, erp->device)) {
619 dasd_free_request (dctl_cqr, erp->device);
620 DASD_MESSAGE (KERN_ERR, device, "%s",
621 "Unable to allocate DCTL-CQR");
622
623 check_then_set (&erp->status,
624 CQR_STATUS_ERROR,
625 CQR_STATUS_FAILED);
626 return erp;
627 }
628 dctl_cqr->function = dasd_3990_erp_DCTL;
629 dctl_cqr->refers = erp;
630 dctl_cqr->device = erp->device;
631 dctl_cqr->magic = erp->magic;
632 dctl_cqr->lpm = LPM_ANYPATH;
633 dctl_cqr->expires = 5 * TOD_MIN;
634 dctl_cqr->retries = 2;
635 asm volatile ("STCK %0":"=m" (dctl_cqr->buildclk));
636
637 dctl_cqr->status = CQR_STATUS_FILLED;
638
639 return dctl_cqr;
640
641 } /* end dasd_3990_erp_DCTL */
642
643 /*
644 * DASD_3990_ERP_ACTION_1
645 *
646 * DESCRIPTION
647 * Setup ERP to do the ERP action 1 (see Reference manual).
648 * Repeat the operation on a different channel path.
649 * If all alternate paths have been tried, the request is posted with a
650 * permanent error.
651 * Note: duplex handling is not implemented (yet).
652 *
653 * PARAMETER
654 * erp pointer to the current ERP
655 *
656 * RETURN VALUES
657 * erp pointer to the ERP
658 *
659 */
660 ccw_req_t *
661 dasd_3990_erp_action_1 (ccw_req_t *erp)
662 {
663
664 erp->function = dasd_3990_erp_action_1;
665
666 dasd_3990_erp_alternate_path (erp);
667
668 return erp;
669
670 } /* end dasd_3990_erp_action_1 */
671
672 /*
673 * DASD_3990_ERP_ACTION_4
674 *
675 * DESCRIPTION
676 * Setup ERP to do the ERP action 4 (see Reference manual).
677 * Set the current request to PENDING to block the CQR queue for that device
678 * until the state change interrupt appears.
679 * Use a timer (20 seconds) to retry the cqr if the interrupt is still missing.
680 *
681 * PARAMETER
682 * sense sense data of the actual error
683 * erp pointer to the current ERP
684 *
685 * RETURN VALUES
686 * erp pointer to the ERP
687 *
688 */
689 ccw_req_t *
690 dasd_3990_erp_action_4 (ccw_req_t *erp,
691 char *sense)
692 {
693
694 dasd_device_t *device = erp->device;
695
696 /* first time set initial retry counter and erp_function */
697 /* and retry once without waiting for state change pending */
698 /* interrupt (this enables easier enqueing of the cqr) */
699 if (erp->function != dasd_3990_erp_action_4) {
700
701 erp->retries = 256;
702 erp->function = dasd_3990_erp_action_4;
703
704 } else {
705
706 if (sense[25] & 0x1D) { /* state change pending */
707
708 DASD_MESSAGE (KERN_INFO, device, "%s",
709 "waiting for state change pending "
710 "int");
711
712 dasd_3990_erp_block_queue (erp,
713 30);
714
715 } else {
716
717 /* no state change pending - retry */
718 check_then_set (&erp->status,
719 CQR_STATUS_ERROR,
720 CQR_STATUS_QUEUED);
721 }
722 }
723
724 return erp;
725
726 } /* end dasd_3990_erp_action_4 */
727
728 /*
729 *****************************************************************************
730 * 24 byte sense ERP functions (only)
731 *****************************************************************************
732 */
733
734 /*
735 * DASD_3990_ERP_ACTION_5
736 *
737 * DESCRIPTION
738 * Setup ERP to do the ERP action 5 (see Reference manual).
739 * NOTE: Further handling is done in xxx_further_erp after the retries.
740 *
741 * PARAMETER
742 * erp pointer to the current ERP
743 *
744 * RETURN VALUES
745 * erp pointer to the ERP
746 *
747 */
748 ccw_req_t *
749 dasd_3990_erp_action_5 (ccw_req_t *erp)
750 {
751
752 /* first of all retry */
753 erp->retries = 10;
754 erp->function = dasd_3990_erp_action_5;
755
756 return erp;
757
758 } /* end dasd_3990_erp_action_5 */
759
760 /*
761 * DASD_3990_HANDLE_ENV_DATA
762 *
763 * DESCRIPTION
764 * Handles 24 byte 'Enviromental data present'.
765 * Does a analysis of the sense data (message Format)
766 * and prints the error messages.
767 *
768 * PARAMETER
769 * sense current sense data
770 *
771 * RETURN VALUES
772 * void
773 */
774 void
775 dasd_3990_handle_env_data (ccw_req_t *erp,
776 char *sense)
777 {
778
779 dasd_device_t *device = erp->device;
780 char msg_format = (sense[7] & 0xF0);
781 char msg_no = (sense[7] & 0x0F);
782
783
784 switch (msg_format) {
785 case 0x00: /* Format 0 - Program or System Checks */
786
787 if (sense[1] & 0x10) { /* check message to operator bit */
788
789 switch (msg_no) {
790 case 0x00: /* No Message */
791 break;
792 case 0x01:
793 DASD_MESSAGE (KERN_WARNING, device, "%s",
794 "FORMAT 0 - Invalid Command");
795 break;
796 case 0x02:
797 DASD_MESSAGE (KERN_WARNING, device, "%s",
798 "FORMAT 0 - Invalid Command "
799 "Sequence");
800 break;
801 case 0x03:
802 DASD_MESSAGE (KERN_WARNING, device, "%s",
803 "FORMAT 0 - CCW Count less than "
804 "required");
805 break;
806 case 0x04:
807 DASD_MESSAGE (KERN_WARNING, device, "%s",
808 "FORMAT 0 - Invalid Parameter");
809 break;
810 case 0x05:
811 DASD_MESSAGE (KERN_WARNING, device, "%s",
812 "FORMAT 0 - Diagnostic of Sepecial"
813 " Command Violates File Mask");
814 break;
815 case 0x07:
816 DASD_MESSAGE (KERN_WARNING, device, "%s",
817 "FORMAT 0 - Channel Returned with "
818 "Incorrect retry CCW");
819 break;
820 case 0x08:
821 DASD_MESSAGE (KERN_WARNING, device, "%s",
822 "FORMAT 0 - Reset Notification");
823 break;
824 case 0x09:
825 DASD_MESSAGE (KERN_WARNING, device, "%s",
826 "FORMAT 0 - Storage Path Restart");
827 break;
828 case 0x0A:
829 DASD_MESSAGE (KERN_WARNING, device,
830 "FORMAT 0 - Channel requested "
831 "... %02x",
832 sense[8]);
833 break;
834 case 0x0B:
835 DASD_MESSAGE (KERN_WARNING, device, "%s",
836 "FORMAT 0 - Invalid Defective/"
837 "Alternate Track Pointer");
838 break;
839 case 0x0C:
840 DASD_MESSAGE (KERN_WARNING, device, "%s",
841 "FORMAT 0 - DPS Installation "
842 "Check");
843 break;
844 case 0x0E:
845 DASD_MESSAGE (KERN_WARNING, device, "%s",
846 "FORMAT 0 - Command Invalid on "
847 "Secondary Address");
848 break;
849 case 0x0F:
850 DASD_MESSAGE (KERN_WARNING, device,
851 "FORMAT 0 - Status Not As "
852 "Required: reason %02x",
853 sense[8]);
854 break;
855 default:
856 DASD_MESSAGE (KERN_WARNING, device, "%s",
857 "FORMAT 0 - Reseved");
858 }
859 } else {
860 switch (msg_no) {
861 case 0x00: /* No Message */
862 break;
863 case 0x01:
864 DASD_MESSAGE (KERN_WARNING, device, "%s",
865 "FORMAT 0 - Device Error Source");
866 break;
867 case 0x02:
868 DASD_MESSAGE (KERN_WARNING, device, "%s",
869 "FORMAT 0 - Reserved");
870 break;
871 case 0x03:
872 DASD_MESSAGE (KERN_WARNING, device,
873 "FORMAT 0 - Device Fenced - "
874 "device = %02x",
875 sense[4]);
876 break;
877 case 0x04:
878 DASD_MESSAGE (KERN_WARNING, device, "%s",
879 "FORMAT 0 - Data Pinned for "
880 "Device");
881 break;
882 default:
883 DASD_MESSAGE (KERN_WARNING, device, "%s",
884 "FORMAT 0 - Reserved");
885 }
886 }
887 break;
888
889 case 0x10: /* Format 1 - Device Equipment Checks */
890 switch (msg_no) {
891 case 0x00: /* No Message */
892 break;
893 case 0x01:
894 DASD_MESSAGE (KERN_WARNING, device, "%s",
895 "FORMAT 1 - Device Status 1 not as "
896 "expected");
897 break;
898 case 0x03:
899 DASD_MESSAGE (KERN_WARNING, device, "%s",
900 "FORMAT 1 - Index missing");
901 break;
902 case 0x04:
903 DASD_MESSAGE (KERN_WARNING, device, "%s",
904 "FORMAT 1 - Interruption cannot be reset");
905 break;
906 case 0x05:
907 DASD_MESSAGE (KERN_WARNING, device, "%s",
908 "FORMAT 1 - Device did not respond to "
909 "selection");
910 break;
911 case 0x06:
912 DASD_MESSAGE (KERN_WARNING, device, "%s",
913 "FORMAT 1 - Device check-2 error or Set "
914 "Sector is not complete");
915 break;
916 case 0x07:
917 DASD_MESSAGE (KERN_WARNING, device, "%s",
918 "FORMAT 1 - Head address does not "
919 "compare");
920 break;
921 case 0x08:
922 DASD_MESSAGE (KERN_WARNING, device, "%s",
923 "FORMAT 1 - Device status 1 not valid");
924 break;
925 case 0x09:
926 DASD_MESSAGE (KERN_WARNING, device, "%s",
927 "FORMAT 1 - Device not ready");
928 break;
929 case 0x0A:
930 DASD_MESSAGE (KERN_WARNING, device, "%s",
931 "FORMAT 1 - Track physical address did "
932 "not compare");
933 break;
934 case 0x0B:
935 DASD_MESSAGE (KERN_WARNING, device, "%s",
936 "FORMAT 1 - Missing device address bit");
937 break;
938 case 0x0C:
939 DASD_MESSAGE (KERN_WARNING, device, "%s",
940 "FORMAT 1 - Drive motor switch is off");
941 break;
942 case 0x0D:
943 DASD_MESSAGE (KERN_WARNING, device, "%s",
944 "FORMAT 1 - Seek incomplete");
945 break;
946 case 0x0E:
947 DASD_MESSAGE (KERN_WARNING, device, "%s",
948 "FORMAT 1 - Cylinder address did not "
949 "compare");
950 break;
951 case 0x0F:
952 DASD_MESSAGE (KERN_WARNING, device, "%s",
953 "FORMAT 1 - Offset active cannot be "
954 "reset");
955 break;
956 default:
957 DASD_MESSAGE (KERN_WARNING, device, "%s",
958 "FORMAT 1 - Reserved");
959 }
960 break;
961
962 case 0x20: /* Format 2 - 3990 Equipment Checks */
963 switch (msg_no) {
964 case 0x08:
965 DASD_MESSAGE (KERN_WARNING, device, "%s",
966 "FORMAT 2 - 3990 check-2 error");
967 break;
968 case 0x0E:
969 DASD_MESSAGE (KERN_WARNING, device, "%s",
970 "FORMAT 2 - Support facility errors");
971 break;
972 case 0x0F:
973 DASD_MESSAGE (KERN_WARNING, device,
974 "FORMAT 2 - Microcode detected error %02x",
975 sense[8]);
976 break;
977 default:
978 DASD_MESSAGE (KERN_WARNING, device, "%s",
979 "FORMAT 2 - Reserved");
980 }
981 break;
982
983 case 0x30: /* Format 3 - 3990 Control Checks */
984 switch (msg_no) {
985 case 0x0F:
986 DASD_MESSAGE (KERN_WARNING, device, "%s",
987 "FORMAT 3 - Allegiance terminated");
988 break;
989 default:
990 DASD_MESSAGE (KERN_WARNING, device, "%s",
991 "FORMAT 3 - Reserved");
992 }
993 break;
994
995 case 0x40: /* Format 4 - Data Checks */
996 switch (msg_no) {
997 case 0x00:
998 DASD_MESSAGE (KERN_WARNING, device, "%s",
999 "FORMAT 4 - Home address area error");
1000 break;
1001 case 0x01:
1002 DASD_MESSAGE (KERN_WARNING, device, "%s",
1003 "FORMAT 4 - Count area error");
1004 break;
1005 case 0x02:
1006 DASD_MESSAGE (KERN_WARNING, device, "%s",
1007 "FORMAT 4 - Key area error");
1008 break;
1009 case 0x03:
1010 DASD_MESSAGE (KERN_WARNING, device, "%s",
1011 "FORMAT 4 - Data area error");
1012 break;
1013 case 0x04:
1014 DASD_MESSAGE (KERN_WARNING, device, "%s",
1015 "FORMAT 4 - No sync byte in home address "
1016 "area");
1017 break;
1018 case 0x05:
1019 DASD_MESSAGE (KERN_WARNING, device, "%s",
1020 "FORMAT 4 - No sync byte in count address "
1021 "area");
1022 break;
1023 case 0x06:
1024 DASD_MESSAGE (KERN_WARNING, device, "%s",
1025 "FORMAT 4 - No sync byte in key area");
1026 break;
1027 case 0x07:
1028 DASD_MESSAGE (KERN_WARNING, device, "%s",
1029 "FORMAT 4 - No sync byte in data area");
1030 break;
1031 case 0x08:
1032 DASD_MESSAGE (KERN_WARNING, device, "%s",
1033 "FORMAT 4 - Home address area error; "
1034 "offset active");
1035 break;
1036 case 0x09:
1037 DASD_MESSAGE (KERN_WARNING, device, "%s",
1038 "FORMAT 4 - Count area error; offset "
1039 "active");
1040 break;
1041 case 0x0A:
1042 DASD_MESSAGE (KERN_WARNING, device, "%s",
1043 "FORMAT 4 - Key area error; offset "
1044 "active");
1045 break;
1046 case 0x0B:
1047 DASD_MESSAGE (KERN_WARNING, device, "%s",
1048 "FORMAT 4 - Data area error; "
1049 "offset active");
1050 break;
1051 case 0x0C:
1052 DASD_MESSAGE (KERN_WARNING, device, "%s",
1053 "FORMAT 4 - No sync byte in home "
1054 "address area; offset active");
1055 break;
1056 case 0x0D:
1057 DASD_MESSAGE (KERN_WARNING, device, "%s",
1058 "FORMAT 4 - No syn byte in count "
1059 "address area; offset active");
1060 break;
1061 case 0x0E:
1062 DASD_MESSAGE (KERN_WARNING, device, "%s",
1063 "FORMAT 4 - No sync byte in key area; "
1064 "offset active");
1065 break;
1066 case 0x0F:
1067 DASD_MESSAGE (KERN_WARNING, device, "%s",
1068 "FORMAT 4 - No syn byte in data area; "
1069 "offset active");
1070 break;
1071 default:
1072 DASD_MESSAGE (KERN_WARNING, device, "%s",
1073 "FORMAT 4 - Reserved");
1074 }
1075 break;
1076
1077 case 0x50: /* Format 5 - Data Check with displacement information */
1078 switch (msg_no) {
1079 case 0x00:
1080 DASD_MESSAGE (KERN_WARNING, device, "%s",
1081 "FORMAT 5 - Data Check in the "
1082 "home address area");
1083 break;
1084 case 0x01:
1085 DASD_MESSAGE (KERN_WARNING, device, "%s",
1086 "FORMAT 5 - Data Check in the count area");
1087 break;
1088 case 0x02:
1089 DASD_MESSAGE (KERN_WARNING, device, "%s",
1090 "FORMAT 5 - Data Check in the key area");
1091 break;
1092 case 0x03:
1093 DASD_MESSAGE (KERN_WARNING, device, "%s",
1094 "FORMAT 5 - Data Check in the data area");
1095 break;
1096 case 0x08:
1097 DASD_MESSAGE (KERN_WARNING, device, "%s",
1098 "FORMAT 5 - Data Check in the "
1099 "home address area; offset active");
1100 break;
1101 case 0x09:
1102 DASD_MESSAGE (KERN_WARNING, device, "%s",
1103 "FORMAT 5 - Data Check in the count area; "
1104 "offset active");
1105 break;
1106 case 0x0A:
1107 DASD_MESSAGE (KERN_WARNING, device, "%s",
1108 "FORMAT 5 - Data Check in the key area; "
1109 "offset active");
1110 break;
1111 case 0x0B:
1112 DASD_MESSAGE (KERN_WARNING, device, "%s",
1113 "FORMAT 5 - Data Check in the data area; "
1114 "offset active");
1115 break;
1116 default:
1117 DASD_MESSAGE (KERN_WARNING, device, "%s",
1118 "FORMAT 5 - Reserved");
1119 }
1120 break;
1121
1122 case 0x60: /* Format 6 - Usage Statistics/Overrun Errors */
1123 switch (msg_no) {
1124 case 0x00:
1125 DASD_MESSAGE (KERN_WARNING, device, "%s",
1126 "FORMAT 6 - Overrun on channel A");
1127 break;
1128 case 0x01:
1129 DASD_MESSAGE (KERN_WARNING, device, "%s",
1130 "FORMAT 6 - Overrun on channel B");
1131 break;
1132 case 0x02:
1133 DASD_MESSAGE (KERN_WARNING, device, "%s",
1134 "FORMAT 6 - Overrun on channel C");
1135 break;
1136 case 0x03:
1137 DASD_MESSAGE (KERN_WARNING, device, "%s",
1138 "FORMAT 6 - Overrun on channel D");
1139 break;
1140 case 0x04:
1141 DASD_MESSAGE (KERN_WARNING, device, "%s",
1142 "FORMAT 6 - Overrun on channel E");
1143 break;
1144 case 0x05:
1145 DASD_MESSAGE (KERN_WARNING, device, "%s",
1146 "FORMAT 6 - Overrun on channel F");
1147 break;
1148 case 0x06:
1149 DASD_MESSAGE (KERN_WARNING, device, "%s",
1150 "FORMAT 6 - Overrun on channel G");
1151 break;
1152 case 0x07:
1153 DASD_MESSAGE (KERN_WARNING, device, "%s",
1154 "FORMAT 6 - Overrun on channel H");
1155 break;
1156 default:
1157 DASD_MESSAGE (KERN_WARNING, device, "%s",
1158 "FORMAT 6 - Reserved");
1159 }
1160 break;
1161
1162 case 0x70: /* Format 7 - Device Connection Control Checks */
1163 switch (msg_no) {
1164 case 0x00:
1165 DASD_MESSAGE (KERN_WARNING, device, "%s",
1166 "FORMAT 7 - RCC initiated by a connection "
1167 "check alert");
1168 break;
1169 case 0x01:
1170 DASD_MESSAGE (KERN_WARNING, device, "%s",
1171 "FORMAT 7 - RCC 1 sequence not "
1172 "successful");
1173 break;
1174 case 0x02:
1175 DASD_MESSAGE (KERN_WARNING, device, "%s",
1176 "FORMAT 7 - RCC 1 and RCC 2 sequences not "
1177 "successful");
1178 break;
1179 case 0x03:
1180 DASD_MESSAGE (KERN_WARNING, device, "%s",
1181 "FORMAT 7 - Invalid tag-in during "
1182 "selection sequence");
1183 break;
1184 case 0x04:
1185 DASD_MESSAGE (KERN_WARNING, device, "%s",
1186 "FORMAT 7 - extra RCC required");
1187 break;
1188 case 0x05:
1189 DASD_MESSAGE (KERN_WARNING, device, "%s",
1190 "FORMAT 7 - Invalid DCC selection "
1191 "response or timeout");
1192 break;
1193 case 0x06:
1194 DASD_MESSAGE (KERN_WARNING, device, "%s",
1195 "FORMAT 7 - Missing end operation; device "
1196 "transfer complete");
1197 break;
1198 case 0x07:
1199 DASD_MESSAGE (KERN_WARNING, device, "%s",
1200 "FORMAT 7 - Missing end operation; device "
1201 "transfer incomplete");
1202 break;
1203 case 0x08:
1204 DASD_MESSAGE (KERN_WARNING, device, "%s",
1205 "FORMAT 7 - Invalid tag-in for an "
1206 "immediate command sequence");
1207 break;
1208 case 0x09:
1209 DASD_MESSAGE (KERN_WARNING, device, "%s",
1210 "FORMAT 7 - Invalid tag-in for an "
1211 "extended command sequence");
1212 break;
1213 case 0x0A:
1214 DASD_MESSAGE (KERN_WARNING, device, "%s",
1215 "FORMAT 7 - 3990 microcode time out when "
1216 "stopping selection");
1217 break;
1218 case 0x0B:
1219 DASD_MESSAGE (KERN_WARNING, device, "%s",
1220 "FORMAT 7 - No response to selection "
1221 "after a poll interruption");
1222 break;
1223 case 0x0C:
1224 DASD_MESSAGE (KERN_WARNING, device, "%s",
1225 "FORMAT 7 - Permanent path error (DASD "
1226 "controller not available)");
1227 break;
1228 case 0x0D:
1229 DASD_MESSAGE (KERN_WARNING, device, "%s",
1230 "FORMAT 7 - DASD controller not available"
1231 " on disconnected command chain");
1232 break;
1233 default:
1234 DASD_MESSAGE (KERN_WARNING, device, "%s",
1235 "FORMAT 7 - Reserved");
1236 }
1237 break;
1238
1239 case 0x80: /* Format 8 - Additional Device Equipment Checks */
1240 switch (msg_no) {
1241 case 0x00: /* No Message */
1242 case 0x01:
1243 DASD_MESSAGE (KERN_WARNING, device, "%s",
1244 "FORMAT 8 - Error correction code "
1245 "hardware fault");
1246 break;
1247 case 0x03:
1248 DASD_MESSAGE (KERN_WARNING, device, "%s",
1249 "FORMAT 8 - Unexpected end operation "
1250 "response code");
1251 break;
1252 case 0x04:
1253 DASD_MESSAGE (KERN_WARNING, device, "%s",
1254 "FORMAT 8 - End operation with transfer "
1255 "count not zero");
1256 break;
1257 case 0x05:
1258 DASD_MESSAGE (KERN_WARNING, device, "%s",
1259 "FORMAT 8 - End operation with transfer "
1260 "count zero");
1261 break;
1262 case 0x06:
1263 DASD_MESSAGE (KERN_WARNING, device, "%s",
1264 "FORMAT 8 - DPS checks after a system "
1265 "reset or selective reset");
1266 break;
1267 case 0x07:
1268 DASD_MESSAGE (KERN_WARNING, device, "%s",
1269 "FORMAT 8 - DPS cannot be filled");
1270 break;
1271 case 0x08:
1272 DASD_MESSAGE (KERN_WARNING, device, "%s",
1273 "FORMAT 8 - Short busy time-out during "
1274 "device selection");
1275 break;
1276 case 0x09:
1277 DASD_MESSAGE (KERN_WARNING, device, "%s",
1278 "FORMAT 8 - DASD controller failed to "
1279 "set or reset the long busy latch");
1280 break;
1281 case 0x0A:
1282 DASD_MESSAGE (KERN_WARNING, device, "%s",
1283 "FORMAT 8 - No interruption from device "
1284 "during a command chain");
1285 break;
1286 default:
1287 DASD_MESSAGE (KERN_WARNING, device, "%s",
1288 "FORMAT 8 - Reserved");
1289 }
1290 break;
1291
1292 case 0x90: /* Format 9 - Device Read, Write, and Seek Checks */
1293 switch (msg_no) {
1294 case 0x00:
1295 break; /* No Message */
1296 case 0x06:
1297 DASD_MESSAGE (KERN_WARNING, device, "%s",
1298 "FORMAT 9 - Device check-2 error");
1299 break;
1300 case 0x07:
1301 DASD_MESSAGE (KERN_WARNING, device, "%s",
1302 "FORMAT 9 - Head address did not compare");
1303 break;
1304 case 0x0A:
1305 DASD_MESSAGE (KERN_WARNING, device, "%s",
1306 "FORMAT 9 - Track physical address did "
1307 "not compare while oriented");
1308 break;
1309 case 0x0E:
1310 DASD_MESSAGE (KERN_WARNING, device, "%s",
1311 "FORMAT 9 - Cylinder address did not "
1312 "compare");
1313 break;
1314 default:
1315 DASD_MESSAGE (KERN_WARNING, device, "%s",
1316 "FORMAT 9 - Reserved");
1317 }
1318 break;
1319
1320 case 0xF0: /* Format F - Cache Storage Checks */
1321 switch (msg_no) {
1322 case 0x00:
1323 DASD_MESSAGE (KERN_WARNING, device, "%s",
1324 "FORMAT F - Operation Terminated");
1325 break;
1326 case 0x01:
1327 DASD_MESSAGE (KERN_WARNING, device, "%s",
1328 "FORMAT F - Subsystem Processing Error");
1329 break;
1330 case 0x02:
1331 DASD_MESSAGE (KERN_WARNING, device, "%s",
1332 "FORMAT F - Cache or nonvolatile storage "
1333 "equipment failure");
1334 break;
1335 case 0x04:
1336 DASD_MESSAGE (KERN_WARNING, device, "%s",
1337 "FORMAT F - Caching terminated");
1338 break;
1339 case 0x06:
1340 DASD_MESSAGE (KERN_WARNING, device, "%s",
1341 "FORMAT F - Cache fast write access not "
1342 "authorized");
1343 break;
1344 case 0x07:
1345 DASD_MESSAGE (KERN_WARNING, device, "%s",
1346 "FORMAT F - Track format incorrect");
1347 break;
1348 case 0x09:
1349 DASD_MESSAGE (KERN_WARNING, device, "%s",
1350 "FORMAT F - Caching reinitiated");
1351 break;
1352 case 0x0A:
1353 DASD_MESSAGE (KERN_WARNING, device, "%s",
1354 "FORMAT F - Nonvolatile storage "
1355 "terminated");
1356 break;
1357 case 0x0B:
1358 DASD_MESSAGE (KERN_WARNING, device, "%s",
1359 "FORMAT F - Volume is suspended duplex");
1360 break;
1361 case 0x0C:
1362 DASD_MESSAGE (KERN_WARNING, device, "%s",
1363 "FORMAT F - Subsystem status connot be "
1364 "determined");
1365 break;
1366 case 0x0D:
1367 DASD_MESSAGE (KERN_WARNING, device, "%s",
1368 "FORMAT F - Caching status reset to "
1369 "default");
1370 break;
1371 case 0x0E:
1372 DASD_MESSAGE (KERN_WARNING, device, "%s",
1373 "FORMAT F - DASD Fast Write inhibited");
1374 break;
1375 default:
1376 DASD_MESSAGE (KERN_WARNING, device, "%s",
1377 "FORMAT D - Reserved");
1378 }
1379 break;
1380
1381 default: /* unknown message format - should not happen */
1382
1383 } /* end switch message format */
1384
1385 } /* end dasd_3990_handle_env_data */
1386
1387 /*
1388 * DASD_3990_ERP_COM_REJ
1389 *
1390 * DESCRIPTION
1391 * Handles 24 byte 'Command Reject' error.
1392 *
1393 * PARAMETER
1394 * erp current erp_head
1395 * sense current sense data
1396 *
1397 * RETURN VALUES
1398 * erp 'new' erp_head - pointer to new ERP
1399 */
1400 ccw_req_t *
1401 dasd_3990_erp_com_rej (ccw_req_t *erp,
1402 char *sense)
1403 {
1404
1405 dasd_device_t *device = erp->device;
1406
1407 erp->function = dasd_3990_erp_com_rej;
1408
1409 /* env data present (ACTION 10 - retry should work) */
1410 if (sense[2] & SNS2_ENV_DATA_PRESENT) {
1411
1412 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1413 "Command Reject - environmental data present");
1414
1415 dasd_3990_handle_env_data (erp,
1416 sense);
1417
1418 erp->retries = 5;
1419
1420 } else {
1421 /* fatal error - set status to FAILED */
1422 DASD_MESSAGE (KERN_ERR, device, "%s",
1423 "Command Reject - Fatal error");
1424
1425 erp = dasd_3990_erp_cleanup (erp,
1426 CQR_STATUS_FAILED);
1427 }
1428
1429 return erp;
1430
1431 } /* end dasd_3990_erp_com_rej */
1432
1433 /*
1434 * DASD_3990_ERP_BUS_OUT
1435 *
1436 * DESCRIPTION
1437 * Handles 24 byte 'Bus Out Parity Check' error.
1438 *
1439 * PARAMETER
1440 * erp current erp_head
1441 * RETURN VALUES
1442 * erp new erp_head - pointer to new ERP
1443 */
1444 ccw_req_t *
1445 dasd_3990_erp_bus_out (ccw_req_t *erp)
1446 {
1447
1448 dasd_device_t *device = erp->device;
1449
1450 /* first time set initial retry counter and erp_function */
1451 /* and retry once without blocking queue */
1452 /* (this enables easier enqueing of the cqr) */
1453 if (erp->function != dasd_3990_erp_bus_out) {
1454 erp->retries = 256;
1455 erp->function = dasd_3990_erp_bus_out;
1456
1457 } else {
1458
1459 /* issue a message and wait for 'device ready' interrupt */
1460 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1461 "bus out parity error or BOPC requested by "
1462 "channel");
1463
1464 dasd_3990_erp_block_queue (erp,
1465 60);
1466
1467 }
1468
1469 return erp;
1470
1471 } /* end dasd_3990_erp_bus_out */
1472
1473 /*
1474 * DASD_3990_ERP_EQUIP_CHECK
1475 *
1476 * DESCRIPTION
1477 * Handles 24 byte 'Equipment Check' error.
1478 *
1479 * PARAMETER
1480 * erp current erp_head
1481 * RETURN VALUES
1482 * erp new erp_head - pointer to new ERP
1483 */
1484 ccw_req_t *
1485 dasd_3990_erp_equip_check (ccw_req_t *erp,
1486 char *sense)
1487 {
1488
1489 dasd_device_t *device = erp->device;
1490
1491 erp->function = dasd_3990_erp_equip_check;
1492
1493 if (sense[1] & SNS1_WRITE_INHIBITED) {
1494
1495 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1496 "Write inhibited path encountered");
1497
1498 /* vary path offline */
1499 DASD_MESSAGE (KERN_ERR, device, "%s",
1500 "Path should be varied off-line. "
1501 "This is not implemented yet \n - please report "
1502 "to linux390@de.ibm.com");
1503
1504 erp = dasd_3990_erp_action_1 (erp);
1505
1506 } else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
1507
1508 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1509 "Equipment Check - "
1510 "environmental data present");
1511
1512 dasd_3990_handle_env_data (erp,
1513 sense);
1514
1515 erp = dasd_3990_erp_action_4 (erp,
1516 sense);
1517
1518 } else if (sense[1] & SNS1_PERM_ERR) {
1519 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1520 "Equipment Check - retry exhausted or "
1521 "undesirable");
1522
1523 erp = dasd_3990_erp_action_1 (erp);
1524
1525 } else {
1526 /* all other equipment checks - Action 5 */
1527 /* rest is done when retries == 0 */
1528 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1529 "Equipment check or processing error");
1530
1531 erp = dasd_3990_erp_action_5 (erp);
1532 }
1533
1534 return erp;
1535
1536 } /* end dasd_3990_erp_equip_check */
1537
1538 /*
1539 * DASD_3990_ERP_DATA_CHECK
1540 *
1541 * DESCRIPTION
1542 * Handles 24 byte 'Data Check' error.
1543 *
1544 * PARAMETER
1545 * erp current erp_head
1546 * RETURN VALUES
1547 * erp new erp_head - pointer to new ERP
1548 */
1549 ccw_req_t *
1550 dasd_3990_erp_data_check (ccw_req_t *erp,
1551 char *sense)
1552 {
1553
1554 dasd_device_t *device = erp->device;
1555
1556 erp->function = dasd_3990_erp_data_check;
1557
1558 if (sense[2] & SNS2_CORRECTABLE) { /* correctable data check */
1559
1560 /* issue message that the data has been corrected */
1561 DASD_MESSAGE (KERN_EMERG, device, "%s",
1562 "Data recovered during retry with PCI "
1563 "fetch mode active");
1564
1565 /* not possible to handle this situation in Linux */
1566 panic("No way to inform appliction about the possibly "
1567 "incorret data");
1568
1569 } else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
1570
1571 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1572 "Uncorrectable data check recovered secondary "
1573 "addr of duplex pair");
1574
1575 erp = dasd_3990_erp_action_4 (erp,
1576 sense);
1577
1578 } else if (sense[1] & SNS1_PERM_ERR) {
1579
1580 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1581 "Uncorrectable data check with internal "
1582 "retry exhausted");
1583
1584 erp = dasd_3990_erp_action_1 (erp);
1585
1586 } else {
1587 /* all other data checks */
1588 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1589 "Uncorrectable data check with retry count "
1590 "exhausted...");
1591
1592 erp = dasd_3990_erp_action_5 (erp);
1593 }
1594
1595 return erp;
1596
1597 } /* end dasd_3990_erp_data_check */
1598
1599 /*
1600 * DASD_3990_ERP_OVERRUN
1601 *
1602 * DESCRIPTION
1603 * Handles 24 byte 'Overrun' error.
1604 *
1605 * PARAMETER
1606 * erp current erp_head
1607 * RETURN VALUES
1608 * erp new erp_head - pointer to new ERP
1609 */
1610 ccw_req_t *
1611 dasd_3990_erp_overrun (ccw_req_t *erp,
1612 char *sense)
1613 {
1614
1615 dasd_device_t *device = erp->device;
1616
1617 erp->function = dasd_3990_erp_overrun;
1618
1619 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1620 "Overrun - service overrun or overrun"
1621 " error requested by channel");
1622
1623 erp = dasd_3990_erp_action_5 (erp);
1624
1625 return erp;
1626
1627 } /* end dasd_3990_erp_overrun */
1628
1629 /*
1630 * DASD_3990_ERP_INV_FORMAT
1631 *
1632 * DESCRIPTION
1633 * Handles 24 byte 'Invalid Track Format' error.
1634 *
1635 * PARAMETER
1636 * erp current erp_head
1637 * RETURN VALUES
1638 * erp new erp_head - pointer to new ERP
1639 */
1640 ccw_req_t *
1641 dasd_3990_erp_inv_format (ccw_req_t *erp,
1642 char *sense)
1643 {
1644
1645 dasd_device_t *device = erp->device;
1646
1647 erp->function = dasd_3990_erp_inv_format;
1648
1649 if (sense[2] & SNS2_ENV_DATA_PRESENT) {
1650
1651 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1652 "Track format error when destaging or "
1653 "staging data");
1654
1655 dasd_3990_handle_env_data (erp,
1656 sense);
1657
1658 erp = dasd_3990_erp_action_4 (erp,
1659 sense);
1660
1661 } else {
1662 DASD_MESSAGE (KERN_ERR, device, "%s",
1663 "Invalid Track Format - Fatal error should have "
1664 "been handled within the interrupt handler");
1665
1666 erp= dasd_3990_erp_cleanup (erp,
1667 CQR_STATUS_FAILED);
1668 }
1669
1670 return erp;
1671
1672 } /* end dasd_3990_erp_inv_format */
1673
1674 /*
1675 * DASD_3990_ERP_EOC
1676 *
1677 * DESCRIPTION
1678 * Handles 24 byte 'End-of-Cylinder' error.
1679 *
1680 * PARAMETER
1681 * erp already added default erp
1682 * RETURN VALUES
1683 * erp pointer to original (failed) cqr.
1684 */
1685 ccw_req_t *
1686 dasd_3990_erp_EOC (ccw_req_t *default_erp,
1687 char *sense)
1688 {
1689
1690 dasd_device_t *device = default_erp->device;
1691
1692 DASD_MESSAGE (KERN_ERR, device, "%s",
1693 "End-of-Cylinder - must never happen");
1694
1695 /* implement action 7 - BUG */
1696 return dasd_3990_erp_cleanup (default_erp,
1697 CQR_STATUS_FAILED);
1698
1699 } /* end dasd_3990_erp_EOC */
1700
1701 /*
1702 * DASD_3990_ERP_ENV_DATA
1703 *
1704 * DESCRIPTION
1705 * Handles 24 byte 'Environmental-Data Present' error.
1706 *
1707 * PARAMETER
1708 * erp current erp_head
1709 * RETURN VALUES
1710 * erp new erp_head - pointer to new ERP
1711 */
1712 ccw_req_t *
1713 dasd_3990_erp_env_data (ccw_req_t *erp,
1714 char *sense)
1715 {
1716
1717 dasd_device_t *device = erp->device;
1718
1719 erp->function = dasd_3990_erp_env_data;
1720
1721 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1722 "Environmental data present");
1723
1724 dasd_3990_handle_env_data (erp,
1725 sense);
1726
1727 erp = dasd_3990_erp_action_4 (erp,
1728 sense);
1729
1730 return erp;
1731
1732 } /* end dasd_3990_erp_env_data */
1733
1734 /*
1735 * DASD_3990_ERP_NO_REC
1736 *
1737 * DESCRIPTION
1738 * Handles 24 byte 'No Record Found' error.
1739 *
1740 * PARAMETER
1741 * erp already added default ERP
1742 *
1743 * RETURN VALUES
1744 * erp new erp_head - pointer to new ERP
1745 */
1746 ccw_req_t *
1747 dasd_3990_erp_no_rec (ccw_req_t *default_erp,
1748 char *sense)
1749 {
1750
1751 dasd_device_t *device = default_erp->device;
1752
1753 DASD_MESSAGE (KERN_ERR, device, "%s",
1754 "No Record Found - Fatal error should "
1755 "have been handled within the interrupt handler");
1756
1757 return dasd_3990_erp_cleanup (default_erp,
1758 CQR_STATUS_FAILED);
1759
1760 } /* end dasd_3990_erp_no_rec */
1761
1762 /*
1763 * DASD_3990_ERP_FILE_PROT
1764 *
1765 * DESCRIPTION
1766 * Handles 24 byte 'File Protected' error.
1767 * Note: Seek related recovery is not implemented because
1768 * wee don't use the seek command yet.
1769 *
1770 * PARAMETER
1771 * erp current erp_head
1772 * RETURN VALUES
1773 * erp new erp_head - pointer to new ERP
1774 */
1775 ccw_req_t *
1776 dasd_3990_erp_file_prot (ccw_req_t *erp)
1777 {
1778
1779 dasd_device_t *device = erp->device;
1780
1781 DASD_MESSAGE (KERN_ERR, device, "%s",
1782 "File Protected");
1783
1784 return dasd_3990_erp_cleanup (erp,
1785 CQR_STATUS_FAILED);
1786
1787 } /* end dasd_3990_erp_file_prot */
1788
1789 /*
1790 * DASD_3990_ERP_INSPECT_24
1791 *
1792 * DESCRIPTION
1793 * Does a detailed inspection of the 24 byte sense data
1794 * and sets up a related error recovery action.
1795 *
1796 * PARAMETER
1797 * sense sense data of the actual error
1798 * erp pointer to the currently created default ERP
1799 *
1800 * RETURN VALUES
1801 * erp pointer to the (addtitional) ERP
1802 */
1803 ccw_req_t *
1804 dasd_3990_erp_inspect_24 (ccw_req_t *erp,
1805 char *sense)
1806 {
1807
1808 ccw_req_t *erp_filled = NULL;
1809
1810 /* Check sense for .... */
1811 /* 'Command Reject' */
1812 if ((erp_filled == NULL) &&
1813 (sense[0] & SNS0_CMD_REJECT)) {
1814 erp_filled = dasd_3990_erp_com_rej (erp,
1815 sense);
1816 }
1817 /* 'Intervention Required' */
1818 if ((erp_filled == NULL) &&
1819 (sense[0] & SNS0_INTERVENTION_REQ)) {
1820 erp_filled = dasd_3990_erp_int_req (erp);
1821 }
1822 /* 'Bus Out Parity Check' */
1823 if ((erp_filled == NULL) &&
1824 (sense[0] & SNS0_BUS_OUT_CHECK)) {
1825 erp_filled = dasd_3990_erp_bus_out (erp);
1826 }
1827 /* 'Equipment Check' */
1828 if ((erp_filled == NULL) &&
1829 (sense[0] & SNS0_EQUIPMENT_CHECK)) {
1830 erp_filled = dasd_3990_erp_equip_check (erp,
1831 sense);
1832 }
1833 /* 'Data Check' */
1834 if ((erp_filled == NULL) &&
1835 (sense[0] & SNS0_DATA_CHECK)) {
1836 erp_filled = dasd_3990_erp_data_check (erp,
1837 sense);
1838 }
1839 /* 'Overrun' */
1840 if ((erp_filled == NULL) &&
1841 (sense[0] & SNS0_OVERRUN)) {
1842 erp_filled = dasd_3990_erp_overrun (erp,
1843 sense);
1844 }
1845 /* 'Invalid Track Format' */
1846 if ((erp_filled == NULL) &&
1847 (sense[1] & SNS1_INV_TRACK_FORMAT)) {
1848 erp_filled = dasd_3990_erp_inv_format (erp,
1849 sense);
1850 }
1851 /* 'End-of-Cylinder' */
1852 if ((erp_filled == NULL) &&
1853 (sense[1] & SNS1_EOC)) {
1854 erp_filled = dasd_3990_erp_EOC (erp,
1855 sense);
1856 }
1857 /* 'Environmental Data' */
1858 if ((erp_filled == NULL) &&
1859 (sense[2] & SNS2_ENV_DATA_PRESENT)) {
1860 erp_filled = dasd_3990_erp_env_data (erp,
1861 sense);
1862 }
1863 /* 'No Record Found' */
1864 if ((erp_filled == NULL) &&
1865 (sense[1] & SNS1_NO_REC_FOUND)) {
1866 erp_filled = dasd_3990_erp_no_rec (erp,
1867 sense);
1868 }
1869 /* 'File Protected' */
1870 if ((erp_filled == NULL) &&
1871 (sense[1] & SNS1_FILE_PROTECTED)) {
1872 erp_filled = dasd_3990_erp_file_prot (erp);
1873 }
1874 /* other (unknown) error - do default ERP */
1875 if (erp_filled == NULL) {
1876
1877 erp_filled = erp;
1878 }
1879
1880 return erp_filled;
1881
1882 } /* END dasd_3990_erp_inspect_24 */
1883
1884 /*
1885 *****************************************************************************
1886 * 32 byte sense ERP functions (only)
1887 *****************************************************************************
1888 */
1889
1890 /*
1891 * DASD_3990_ERPACTION_10_32
1892 *
1893 * DESCRIPTION
1894 * Handles 32 byte 'Action 10' of Single Program Action Codes.
1895 * Just retry and if retry doesn't work, return with error.
1896 *
1897 * PARAMETER
1898 * erp current erp_head
1899 * sense current sense data
1900 * RETURN VALUES
1901 * erp modified erp_head
1902 */
1903 ccw_req_t *
1904 dasd_3990_erp_action_10_32 (ccw_req_t *erp,
1905 char *sense)
1906 {
1907
1908 dasd_device_t *device = erp->device;
1909
1910 erp->retries = 256;
1911 erp->function = dasd_3990_erp_action_10_32;
1912
1913 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1914 "Perform logging requested");
1915
1916 return erp;
1917
1918 } /* end dasd_3990_erp_action_10_32 */
1919
1920 /*
1921 * DASD_3990_ERP_ACTION_1B_32
1922 *
1923 * DESCRIPTION
1924 * Handles 32 byte 'Action 1B' of Single Program Action Codes.
1925 * A write operation could not be finished because of an unexpected
1926 * condition.
1927 * The already created 'default erp' is used to get the link to
1928 * the erp chain, but it can not be used for this recovery
1929 * action because it contains no DE/LO data space.
1930 *
1931 * PARAMETER
1932 * default_erp already added default erp.
1933 * sense current sense data
1934 *
1935 * RETURN VALUES
1936 * erp new erp or
1937 * default_erp in case of imprecise ending or error
1938 */
1939 ccw_req_t *
1940 dasd_3990_erp_action_1B_32 (ccw_req_t *default_erp,
1941 char *sense)
1942 {
1943
1944 dasd_device_t *device = default_erp->device;
1945 __u32 cpa = 0;
1946 ccw_req_t *cqr;
1947 ccw_req_t *erp;
1948 DE_eckd_data_t *DE_data;
1949 char *LO_data; /* LO_eckd_data_t */
1950 ccw1_t *ccw;
1951
1952 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1953 "Write not finished because of unexpected condition");
1954
1955 default_erp->function = dasd_3990_erp_action_1B_32;
1956
1957 /* determine the original cqr */
1958 cqr = default_erp;
1959
1960 while (cqr->refers != NULL){
1961 cqr = cqr->refers;
1962 }
1963
1964 /* for imprecise ending just do default erp */
1965 if (sense[1] & 0x01) {
1966
1967 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1968 "Imprecise ending is set - just retry");
1969
1970 return default_erp;
1971 }
1972
1973 /* determine the address of the CCW to be restarted */
1974 /* Imprecise ending is not set -> addr from IRB-SCSW */
1975 cpa = default_erp->refers->dstat->cpa;
1976
1977 if (cpa == 0) {
1978
1979 DASD_MESSAGE (KERN_DEBUG, device, "%s",
1980 "Unable to determine address of the CCW "
1981 "to be restarted");
1982
1983 return dasd_3990_erp_cleanup (default_erp,
1984 CQR_STATUS_FAILED);
1985 }
1986
1987 /* Build new ERP request including DE/LO */
1988 erp = dasd_alloc_request ((char *) &cqr->magic,
1989 2 + 1, /* DE/LO + TIC */
1990 sizeof (DE_eckd_data_t) +
1991 sizeof (LO_eckd_data_t),
1992 device);
1993
1994 if (!erp) {
1995
1996 DASD_MESSAGE (KERN_ERR, device, "%s",
1997 "Unable to allocate ERP");
1998
1999 return dasd_3990_erp_cleanup (default_erp,
2000 CQR_STATUS_FAILED);
2001 }
2002
2003 /* use original DE */
2004 DE_data = erp->data;
2005 memcpy (DE_data,
2006 cqr->data,
2007 sizeof (DE_eckd_data_t));
2008
2009 /* create LO */
2010 LO_data = erp->data + sizeof (DE_eckd_data_t);
2011
2012 if ((sense[3] == 0x01) &&
2013 (LO_data[1] & 0x01) ){
2014
2015 DASD_MESSAGE (KERN_ERR, device, "%s",
2016 "BUG - this should not happen");
2017
2018 return dasd_3990_erp_cleanup (default_erp,
2019 CQR_STATUS_FAILED);
2020 }
2021
2022 if ((sense[7] & 0x3F) == 0x01) {
2023 /* operation code is WRITE DATA -> data area orientation */
2024 LO_data[0] = 0x81;
2025
2026 } else if ((sense[7] & 0x3F) == 0x03) {
2027 /* operation code is FORMAT WRITE -> index orientation */
2028 LO_data[0] = 0xC3;
2029
2030 } else {
2031 LO_data[0] = sense[7]; /* operation */
2032 }
2033
2034 LO_data[1] = sense[8]; /* auxiliary */
2035 LO_data[2] = sense[9];
2036 LO_data[3] = sense[3]; /* count */
2037 LO_data[4] = sense[29]; /* seek_addr.cyl */
2038 LO_data[5] = sense[30]; /* seek_addr.cyl 2nd byte */
2039 LO_data[7] = sense[31]; /* seek_addr.head 2nd byte */
2040
2041 memcpy (&(LO_data[8]), &(sense[11]), 8);
2042
2043 /* create DE ccw */
2044 ccw = erp->cpaddr;
2045 memset (ccw, 0, sizeof (ccw1_t));
2046 ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;
2047 ccw->flags = CCW_FLAG_CC;
2048 ccw->count = 16;
2049 if (dasd_set_normalized_cda (ccw,
2050 __pa (DE_data), erp, device)) {
2051 dasd_free_request (erp, device);
2052 DASD_MESSAGE (KERN_ERR, device, "%s",
2053 "Unable to allocate ERP");
2054
2055 return dasd_3990_erp_cleanup (default_erp,
2056 CQR_STATUS_FAILED);
2057 }
2058
2059 /* create LO ccw */
2060 ccw++;
2061 memset (ccw, 0, sizeof (ccw1_t));
2062 ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
2063 ccw->flags = CCW_FLAG_CC;
2064 ccw->count = 16;
2065 if (dasd_set_normalized_cda (ccw,
2066 __pa (LO_data), erp, device)){
2067 dasd_free_request (erp, device);
2068 DASD_MESSAGE (KERN_ERR, device, "%s",
2069 "Unable to allocate ERP");
2070
2071 return dasd_3990_erp_cleanup (default_erp,
2072 CQR_STATUS_FAILED);
2073 }
2074
2075 /* TIC to the failed ccw */
2076 ccw++;
2077 ccw->cmd_code = CCW_CMD_TIC;
2078 ccw->cda = cpa;
2079
2080 /* fill erp related fields */
2081 erp->function = dasd_3990_erp_action_1B_32;
2082 erp->refers = default_erp->refers;
2083 erp->device = device;
2084 erp->magic = default_erp->magic;
2085 erp->lpm = 0xFF;
2086 erp->expires = 0;
2087 erp->retries = 256;
2088 erp->status = CQR_STATUS_FILLED;
2089
2090 /* remove the default erp */
2091 dasd_free_request (default_erp, device);
2092
2093 return erp;
2094
2095 } /* end dasd_3990_erp_action_1B_32 */
2096
2097 /*
2098 * DASD_3990_UPDATE_1B
2099 *
2100 * DESCRIPTION
2101 * Handles the update to the 32 byte 'Action 1B' of Single Program
2102 * Action Codes in case the first action was not successful.
2103 * The already created 'previous_erp' is the currently not successful
2104 * ERP.
2105 *
2106 * PARAMETER
2107 * previous_erp already created previous erp.
2108 * sense current sense data
2109 * RETURN VALUES
2110 * erp modified erp
2111 */
2112 ccw_req_t *
2113 dasd_3990_update_1B (ccw_req_t *previous_erp,
2114 char *sense)
2115 {
2116
2117 dasd_device_t *device = previous_erp->device;
2118 __u32 cpa = 0;
2119 ccw_req_t *cqr;
2120 ccw_req_t *erp;
2121 char *LO_data; /* LO_eckd_data_t */
2122 ccw1_t *ccw;
2123
2124 DASD_MESSAGE (KERN_DEBUG, device, "%s",
2125 "Write not finished because of unexpected condition"
2126 " - follow on");
2127
2128 /* determine the original cqr */
2129 cqr = previous_erp;
2130
2131 while (cqr->refers != NULL){
2132 cqr = cqr->refers;
2133 }
2134
2135 /* for imprecise ending just do default erp */
2136 if (sense[1] & 0x01) {
2137
2138 DASD_MESSAGE (KERN_DEBUG, device, "%s",
2139 "Imprecise ending is set - just retry");
2140
2141 check_then_set (&previous_erp->status,
2142 CQR_STATUS_ERROR,
2143 CQR_STATUS_QUEUED);
2144
2145 return previous_erp;
2146 }
2147
2148 /* determine the address of the CCW to be restarted */
2149 /* Imprecise ending is not set -> addr from IRB-SCSW */
2150 cpa = previous_erp->dstat->cpa;
2151
2152 if (cpa == 0) {
2153
2154 DASD_MESSAGE (KERN_DEBUG, device, "%s",
2155 "Unable to determine address of the CCW "
2156 "to be restarted");
2157
2158 check_then_set (&previous_erp->status,
2159 CQR_STATUS_ERROR,
2160 CQR_STATUS_FAILED);
2161
2162 return previous_erp;
2163 }
2164
2165 erp = previous_erp;
2166
2167 /* update the LO with the new returned sense data */
2168 LO_data = erp->data + sizeof (DE_eckd_data_t);
2169
2170 if ((sense[3] == 0x01) &&
2171 (LO_data[1] & 0x01) ){
2172
2173 DASD_MESSAGE (KERN_ERR, device, "%s",
2174 "BUG - this should not happen");
2175
2176 check_then_set (&previous_erp->status,
2177 CQR_STATUS_ERROR,
2178 CQR_STATUS_FAILED);
2179
2180 return previous_erp;
2181 }
2182
2183 if ((sense[7] & 0x3F) == 0x01) {
2184 /* operation code is WRITE DATA -> data area orientation */
2185 LO_data[0] = 0x81;
2186
2187 } else if ((sense[7] & 0x3F) == 0x03) {
2188 /* operation code is FORMAT WRITE -> index orientation */
2189 LO_data[0] = 0xC3;
2190
2191 } else {
2192 LO_data[0] = sense[7]; /* operation */
2193 }
2194
2195 LO_data[1] = sense[8]; /* auxiliary */
2196 LO_data[2] = sense[9];
2197 LO_data[3] = sense[3]; /* count */
2198 LO_data[4] = sense[29]; /* seek_addr.cyl */
2199 LO_data[5] = sense[30]; /* seek_addr.cyl 2nd byte */
2200 LO_data[7] = sense[31]; /* seek_addr.head 2nd byte */
2201
2202 memcpy (&(LO_data[8]), &(sense[11]), 8);
2203
2204 /* TIC to the failed ccw */
2205 ccw = erp->cpaddr; /* addr of DE ccw */
2206 ccw++; /* addr of LE ccw */
2207 ccw++; /* addr of TIC ccw */
2208 ccw->cda = cpa;
2209
2210 check_then_set (&erp->status,
2211 CQR_STATUS_ERROR,
2212 CQR_STATUS_QUEUED);
2213
2214 return erp;
2215
2216 } /* end dasd_3990_update_1B */
2217
2218 /*
2219 * DASD_3990_ERP_COMPOUND_RETRY
2220 *
2221 * DESCRIPTION
2222 * Handles the compound ERP action retry code.
2223 * NOTE: At least one retry is done even if zero is specified
2224 * by the sense data. This makes enqueueing of the request
2225 * easier.
2226 *
2227 * PARAMETER
2228 * sense sense data of the actual error
2229 * erp pointer to the currently created ERP
2230 *
2231 * RETURN VALUES
2232 * erp modified ERP pointer
2233 *
2234 */
2235 void
2236 dasd_3990_erp_compound_retry (ccw_req_t *erp,
2237 char *sense)
2238 {
2239
2240 switch (sense[25] & 0x03) {
2241 case 0x00: /* no not retry */
2242 erp->retries = 1;
2243 break;
2244
2245 case 0x01: /* retry 2 times */
2246 erp->retries = 2;
2247 break;
2248
2249 case 0x02: /* retry 10 times */
2250 erp->retries = 10;
2251 break;
2252
2253 case 0x03: /* retry 256 times */
2254 erp->retries = 256;
2255 break;
2256
2257 default:
2258 BUG();
2259 }
2260
2261 erp->function = dasd_3990_erp_compound_retry;
2262
2263 } /* end dasd_3990_erp_compound_retry */
2264
2265 /*
2266 * DASD_3990_ERP_COMPOUND_PATH
2267 *
2268 * DESCRIPTION
2269 * Handles the compound ERP action for retry on alternate
2270 * channel path.
2271 *
2272 * PARAMETER
2273 * sense sense data of the actual error
2274 * erp pointer to the currently created ERP
2275 *
2276 * RETURN VALUES
2277 * erp modified ERP pointer
2278 *
2279 */
2280 void
2281 dasd_3990_erp_compound_path (ccw_req_t *erp,
2282 char *sense)
2283 {
2284
2285 if (sense[25] & DASD_SENSE_BIT_3) {
2286 dasd_3990_erp_alternate_path (erp);
2287
2288 if (erp->status == CQR_STATUS_FAILED) {
2289 /* reset the lpm and the status to be able to
2290 * try further actions. */
2291
2292 erp->lpm = LPM_ANYPATH;
2293
2294 check_then_set (&erp->status,
2295 CQR_STATUS_FAILED,
2296 CQR_STATUS_ERROR);
2297
2298 }
2299 }
2300
2301 erp->function = dasd_3990_erp_compound_path;
2302
2303 } /* end dasd_3990_erp_compound_path */
2304
2305 /*
2306 * DASD_3990_ERP_COMPOUND_CODE
2307 *
2308 * DESCRIPTION
2309 * Handles the compound ERP action for retry code.
2310 *
2311 * PARAMETER
2312 * sense sense data of the actual error
2313 * erp pointer to the currently created ERP
2314 *
2315 * RETURN VALUES
2316 * erp NEW ERP pointer
2317 *
2318 */
2319 ccw_req_t *
2320 dasd_3990_erp_compound_code (ccw_req_t *erp,
2321 char *sense)
2322 {
2323
2324 if (sense[25] & DASD_SENSE_BIT_2) {
2325
2326 switch (sense[28]) {
2327 case 0x17:
2328 /* issue a Diagnostic Control command with an
2329 * Inhibit Write subcommand and controler modifier */
2330 erp = dasd_3990_erp_DCTL (erp,
2331 0x20);
2332 break;
2333
2334 case 0x25:
2335 /* wait for 5 seconds and retry again */
2336 erp->retries = 1;
2337
2338 dasd_3990_erp_block_queue (erp,
2339 5);
2340 break;
2341
2342 default:
2343 /* should not happen - continue */
2344
2345 }
2346 }
2347
2348 erp->function = dasd_3990_erp_compound_code;
2349
2350 return erp;
2351
2352 } /* end dasd_3990_erp_compound_code */
2353
2354 /*
2355 * DASD_3990_ERP_COMPOUND_CONFIG
2356 *
2357 * DESCRIPTION
2358 * Handles the compound ERP action for configruation
2359 * dependent error.
2360 * Note: duplex handling is not implemented (yet).
2361 *
2362 * PARAMETER
2363 * sense sense data of the actual error
2364 * erp pointer to the currently created ERP
2365 *
2366 * RETURN VALUES
2367 * erp modified ERP pointer
2368 *
2369 */
2370 void
2371 dasd_3990_erp_compound_config (ccw_req_t *erp,
2372 char *sense)
2373 {
2374
2375 if ((sense[25] & DASD_SENSE_BIT_1) &&
2376 (sense[26] & DASD_SENSE_BIT_2) ) {
2377
2378 /* set to suspended duplex state then restart */
2379 dasd_device_t *device = erp->device;
2380
2381 DASD_MESSAGE (KERN_ERR, device, "%s",
2382 "Set device to suspended duplex state should be "
2383 "done!\n"
2384 "This is not implemented yet (for compound ERP)"
2385 " - please report to linux390@de.ibm.com");
2386
2387 }
2388
2389 erp->function = dasd_3990_erp_compound_config;
2390
2391 } /* end dasd_3990_erp_compound_config */
2392
2393 /*
2394 * DASD_3990_ERP_COMPOUND
2395 *
2396 * DESCRIPTION
2397 * Does the further compound program action if
2398 * compound retry was not successful.
2399 *
2400 * PARAMETER
2401 * sense sense data of the actual error
2402 * erp pointer to the current (failed) ERP
2403 *
2404 * RETURN VALUES
2405 * erp (additional) ERP pointer
2406 *
2407 */
2408 ccw_req_t *
2409 dasd_3990_erp_compound (ccw_req_t *erp,
2410 char *sense)
2411 {
2412
2413 if ((erp->function == dasd_3990_erp_compound_retry) &&
2414 (erp->status == CQR_STATUS_ERROR ) ) {
2415
2416 dasd_3990_erp_compound_path (erp,
2417 sense);
2418 }
2419
2420 if ((erp->function == dasd_3990_erp_compound_path) &&
2421 (erp->status == CQR_STATUS_ERROR ) ){
2422
2423 erp = dasd_3990_erp_compound_code (erp,
2424 sense);
2425 }
2426
2427 if ((erp->function == dasd_3990_erp_compound_code) &&
2428 (erp->status == CQR_STATUS_ERROR ) ) {
2429
2430 dasd_3990_erp_compound_config (erp,
2431 sense);
2432 }
2433
2434 /* if no compound action ERP specified, the request failed */
2435 if (erp->status == CQR_STATUS_ERROR) {
2436
2437 check_then_set (&erp->status,
2438 CQR_STATUS_ERROR,
2439 CQR_STATUS_FAILED);
2440 }
2441
2442 return erp;
2443
2444 } /* end dasd_3990_erp_compound */
2445
2446 /*
2447 * DASD_3990_ERP_INSPECT_32
2448 *
2449 * DESCRIPTION
2450 * Does a detailed inspection of the 32 byte sense data
2451 * and sets up a related error recovery action.
2452 *
2453 * PARAMETER
2454 * sense sense data of the actual error
2455 * erp pointer to the currently created default ERP
2456 *
2457 * RETURN VALUES
2458 * erp_filled pointer to the ERP
2459 *
2460 */
2461 ccw_req_t *
2462 dasd_3990_erp_inspect_32 ( ccw_req_t *erp,
2463 char *sense )
2464 {
2465
2466 dasd_device_t *device = erp->device;
2467
2468 erp->function = dasd_3990_erp_inspect_32;
2469
2470 if (sense[25] & DASD_SENSE_BIT_0) {
2471
2472 /* compound program action codes (byte25 bit 0 == '1') */
2473 dasd_3990_erp_compound_retry (erp,
2474 sense);
2475
2476 } else {
2477
2478 /* single program action codes (byte25 bit 0 == '0') */
2479 switch (sense[25]) {
2480
2481 case 0x00: /* success */
2482 DASD_MESSAGE (KERN_DEBUG, device,
2483 "ERP called for successful request %p"
2484 " - NO ERP necessary",
2485 erp);
2486
2487 erp = dasd_3990_erp_cleanup (erp,
2488 CQR_STATUS_DONE);
2489
2490 break;
2491
2492 case 0x01: /* fatal error */
2493 DASD_MESSAGE (KERN_ERR, device, "%s",
2494 "Fatal error should have been "
2495 "handled within the interrupt handler");
2496
2497 erp = dasd_3990_erp_cleanup (erp,
2498 CQR_STATUS_FAILED);
2499 break;
2500
2501 case 0x02: /* intervention required */
2502 case 0x03: /* intervention required during dual copy */
2503 erp = dasd_3990_erp_int_req (erp);
2504 break;
2505
2506 case 0x0F: /* length mismatch during update write command */
2507 DASD_MESSAGE (KERN_ERR, device, "%s",
2508 "update write command error - should not "
2509 "happen;\n"
2510 "Please send this message together with "
2511 "the above sense data to linux390@de."
2512 "ibm.com");
2513
2514 erp = dasd_3990_erp_cleanup (erp,
2515 CQR_STATUS_FAILED);
2516 break;
2517
2518 case 0x10: /* logging required for other channel program */
2519 erp = dasd_3990_erp_action_10_32 (erp,
2520 sense);
2521 break;
2522
2523 case 0x15: /* next track outside defined extend */
2524 DASD_MESSAGE (KERN_ERR, device, "%s",
2525 "next track outside defined extend - "
2526 "should not happen;\n"
2527 "Please send this message together with "
2528 "the above sense data to linux390@de."
2529 "ibm.com");
2530
2531 erp= dasd_3990_erp_cleanup (erp,
2532 CQR_STATUS_FAILED);
2533 break;
2534
2535 case 0x1B: /* unexpected condition during write */
2536
2537 erp = dasd_3990_erp_action_1B_32 (erp,
2538 sense);
2539 break;
2540
2541 case 0x1C: /* invalid data */
2542 DASD_MESSAGE (KERN_EMERG, device, "%s",
2543 "Data recovered during retry with PCI "
2544 "fetch mode active");
2545
2546 /* not possible to handle this situation in Linux */
2547 panic("Invalid data - No way to inform appliction about "
2548 "the possibly incorret data");
2549 break;
2550
2551 case 0x1D: /* state-change pending */
2552 DASD_MESSAGE (KERN_DEBUG, device, "%s",
2553 "A State change pending condition exists "
2554 "for the subsystem or device");
2555
2556 erp = dasd_3990_erp_action_4 (erp,
2557 sense);
2558 break;
2559
2560 default: /* all others errors - default erp */
2561
2562 }
2563 }
2564
2565 return erp;
2566
2567 } /* end dasd_3990_erp_inspect_32 */
2568
2569 /*
2570 *****************************************************************************
2571 * main ERP control fuctions (24 and 32 byte sense)
2572 *****************************************************************************
2573 */
2574
2575 /*
2576 * DASD_3990_ERP_INSPECT
2577 *
2578 * DESCRIPTION
2579 * Does a detailed inspection for sense data by calling either
2580 * the 24-byte or the 32-byte inspection routine.
2581 *
2582 * PARAMETER
2583 * erp pointer to the currently created default ERP
2584 * RETURN VALUES
2585 * erp_new contens was possibly modified
2586 */
2587 ccw_req_t *
2588 dasd_3990_erp_inspect (ccw_req_t *erp)
2589 {
2590
2591 ccw_req_t *erp_new = NULL;
2592 /* sense data are located in the refers record of the */
2593 /* already set up new ERP ! */
2594 char *sense = erp->refers->dstat->ii.sense.data;
2595
2596 /* distinguish between 24 and 32 byte sense data */
2597 if (sense[27] & DASD_SENSE_BIT_0) {
2598
2599 /* inspect the 24 byte sense data */
2600 erp_new = dasd_3990_erp_inspect_24 (erp,
2601 sense);
2602
2603 } else {
2604
2605 /* inspect the 32 byte sense data */
2606 erp_new = dasd_3990_erp_inspect_32 (erp,
2607 sense);
2608
2609 } /* end distinguish between 24 and 32 byte sense data */
2610
2611 return erp_new;
2612
2613 } /* END dasd_3990_erp_inspect */
2614
2615 /*
2616 * DASD_3990_ERP_ADD_ERP
2617 *
2618 * DESCRIPTION
2619 * This funtion adds an additional request block (ERP) to the head of
2620 * the given cqr (or erp).
2621 * This erp is initialized as an default erp (retry TIC)
2622 *
2623 * PARAMETER
2624 * cqr head of the current ERP-chain (or single cqr if
2625 * first error)
2626 * RETURN VALUES
2627 * erp pointer to new ERP-chain head
2628 */
2629 ccw_req_t *
2630 dasd_3990_erp_add_erp (ccw_req_t *cqr)
2631 {
2632
2633 dasd_device_t *device = cqr->device;
2634
2635 /* allocate additional request block */
2636 ccw_req_t *erp = dasd_alloc_request ((char *) &cqr->magic, 1, 0, cqr->device);
2637
2638 if (!erp) {
2639
2640 DASD_MESSAGE (KERN_ERR, device, "%s",
2641 "Unable to allocate ERP request");
2642
2643 check_then_set (&cqr->status,
2644 CQR_STATUS_ERROR,
2645 CQR_STATUS_FAILED);
2646
2647 return cqr;
2648 }
2649
2650 /* initialize request with default TIC to current ERP/CQR */
2651 erp->cpaddr->cmd_code = CCW_CMD_TIC;
2652 erp->cpaddr->cda = (long)(cqr->cpaddr);
2653 erp->function = dasd_3990_erp_add_erp;
2654 erp->refers = cqr;
2655 erp->device = cqr->device;
2656 erp->magic = cqr->magic;
2657 erp->lpm = 0xFF;
2658 erp->expires = 0;
2659 erp->retries = 256;
2660
2661 erp->status = CQR_STATUS_FILLED;
2662
2663 return erp;
2664 }
2665
2666 /*
2667 * DASD_3990_ERP_ADDITIONAL_ERP
2668 *
2669 * DESCRIPTION
2670 * An additional ERP is needed to handle the current error.
2671 * Add ERP to the head of the ERP-chain containing the ERP processing
2672 * determined based on the sense data.
2673 *
2674 * PARAMETER
2675 * cqr head of the current ERP-chain (or single cqr if
2676 * first error)
2677 *
2678 * RETURN VALUES
2679 * erp pointer to new ERP-chain head
2680 */
2681 ccw_req_t *
2682 dasd_3990_erp_additional_erp (ccw_req_t *cqr)
2683 {
2684
2685 ccw_req_t *erp = NULL;
2686
2687 /* add erp and initialize with default TIC */
2688 erp = dasd_3990_erp_add_erp (cqr);
2689
2690 /* inspect sense, determine specific ERP if possible */
2691 if (erp != cqr) {
2692
2693 erp = dasd_3990_erp_inspect (erp);
2694 }
2695
2696 return erp;
2697
2698 } /* end dasd_3990_erp_additional_erp */
2699
2700 /*
2701 * DASD_3990_ERP_ERROR_MATCH
2702 *
2703 * DESCRIPTION
2704 * check if the the device status of the given cqr is the same.
2705 * This means that the failed CCW and the relevant sense data
2706 * must match.
2707 * I don't distinguish between 24 and 32 byte sense becaus in case of
2708 * 24 byte sense byte 25 and 27 is set as well.
2709 *
2710 * PARAMETER
2711 * cqr1 first cqr, which will be compared with the
2712 * cqr2 second cqr.
2713 *
2714 * RETURN VALUES
2715 * match 'boolean' for match found
2716 * returns 1 if match found, otherwise 0.
2717 */
2718 int
2719 dasd_3990_erp_error_match (ccw_req_t *cqr1,
2720 ccw_req_t *cqr2)
2721 {
2722
2723 /* check failed CCW */
2724 if (cqr1->dstat->cpa !=
2725 cqr2->dstat->cpa) {
2726 // return 0; /* CCW doesn't match */
2727 }
2728
2729 /* check sense data; byte 0-2,25,27 */
2730 if (!((strncmp (cqr1->dstat->ii.sense.data,
2731 cqr2->dstat->ii.sense.data,
2732 3) == 0) &&
2733 (cqr1->dstat->ii.sense.data[27] ==
2734 cqr2->dstat->ii.sense.data[27] ) &&
2735 (cqr1->dstat->ii.sense.data[25] ==
2736 cqr2->dstat->ii.sense.data[25] ) )) {
2737
2738 return 0; /* sense doesn't match */
2739 }
2740
2741 return 1; /* match */
2742
2743 } /* end dasd_3990_erp_error_match */
2744
2745 /*
2746 * DASD_3990_ERP_IN_ERP
2747 *
2748 * DESCRIPTION
2749 * check if the current error already happened before.
2750 * quick exit if current cqr is not an ERP (cqr->refers=NULL)
2751 *
2752 * PARAMETER
2753 * cqr failed cqr (either original cqr or already an erp)
2754 *
2755 * RETURN VALUES
2756 * erp erp-pointer to the already defined error
2757 * recovery procedure OR
2758 * NULL if a 'new' error occurred.
2759 */
2760 ccw_req_t *
2761 dasd_3990_erp_in_erp (ccw_req_t *cqr)
2762 {
2763
2764 ccw_req_t *erp_head = cqr, /* save erp chain head */
2765 *erp_match = NULL; /* save erp chain head */
2766 int match = 0; /* 'boolean' for matching error found */
2767
2768 if (cqr->refers == NULL) { /* return if not in erp */
2769 return NULL;
2770 }
2771
2772 /* check the erp/cqr chain for current error */
2773 do {
2774 match = dasd_3990_erp_error_match (erp_head,
2775 cqr->refers);
2776 erp_match = cqr; /* save possible matching erp */
2777 cqr = cqr->refers; /* check next erp/cqr in queue */
2778
2779 } while ((cqr->refers != NULL) &&
2780 (!match ) );
2781
2782 if (!match) {
2783 return NULL; /* no match was found */
2784 }
2785
2786 return erp_match; /* return address of matching erp */
2787
2788 } /* END dasd_3990_erp_in_erp */
2789
2790 /*
2791 * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense)
2792 *
2793 * DESCRIPTION
2794 * No retry is left for the current ERP. Check what has to be done
2795 * with the ERP.
2796 * - do further defined ERP action or
2797 * - wait for interrupt or
2798 * - exit with permanent error
2799 *
2800 * PARAMETER
2801 * erp ERP which is in progress wiht no retry left
2802 *
2803 * RETURN VALUES
2804 * erp modified/additional ERP
2805 */
2806 ccw_req_t *
2807 dasd_3990_erp_further_erp (ccw_req_t *erp)
2808 {
2809
2810 dasd_device_t *device = erp->device;
2811 char *sense = erp->dstat->ii.sense.data;
2812
2813 /* check for 24 byte sense ERP */
2814 if ((erp->function == dasd_3990_erp_bus_out ) ||
2815 (erp->function == dasd_3990_erp_action_1) ||
2816 (erp->function == dasd_3990_erp_action_4) ){
2817
2818 erp = dasd_3990_erp_action_1 (erp);
2819
2820 } else if (erp->function == dasd_3990_erp_action_5) {
2821
2822 /* retries have not been successful */
2823 /* prepare erp for retry on different channel path */
2824 erp = dasd_3990_erp_action_1 (erp);
2825
2826 if (!(sense[ 2] & DASD_SENSE_BIT_0)) {
2827
2828 /* issue a Diagnostic Control command with an
2829 * Inhibit Write subcommand */
2830
2831 switch (sense[25]) {
2832 case 0x17:
2833 case 0x57: { /* controller */
2834 erp = dasd_3990_erp_DCTL (erp,
2835 0x20);
2836 break;
2837 }
2838 case 0x18:
2839 case 0x58: { /* channel path */
2840 erp = dasd_3990_erp_DCTL (erp,
2841 0x40);
2842 break;
2843 }
2844 case 0x19:
2845 case 0x59: { /* storage director */
2846 erp = dasd_3990_erp_DCTL (erp,
2847 0x80);
2848 break;
2849 }
2850 default:
2851 DASD_MESSAGE (KERN_DEBUG, device,
2852 "invalid subcommand modifier 0x%x "
2853 "for Diagnostic Control Command",
2854 sense[25]);
2855 }
2856 }
2857
2858 /* check for 32 byte sense ERP */
2859 } else if ((erp->function == dasd_3990_erp_compound_retry ) ||
2860 (erp->function == dasd_3990_erp_compound_path ) ||
2861 (erp->function == dasd_3990_erp_compound_code ) ||
2862 (erp->function == dasd_3990_erp_compound_config) ) {
2863
2864 erp = dasd_3990_erp_compound (erp,
2865 sense);
2866
2867 } else {
2868 /* no retry left and no additional special handling necessary */
2869 DASD_MESSAGE (KERN_ERR, device,
2870 "no retries left for erp %p - "
2871 "set status to FAILED",
2872 erp);
2873
2874 check_then_set (&erp->status,
2875 CQR_STATUS_ERROR,
2876 CQR_STATUS_FAILED);
2877 }
2878
2879 return erp;
2880
2881 } /* end dasd_3990_erp_further_erp */
2882
2883 /*
2884 * DASD_3990_ERP_HANDLE_MATCH_ERP
2885 *
2886 * DESCRIPTION
2887 * An error occurred again and an ERP has been detected which is already
2888 * used to handle this error (e.g. retries).
2889 * All prior ERP's are asumed to be successful and therefore removed
2890 * from queue.
2891 * If retry counter of matching erp is already 0, it is checked if further
2892 * action is needed (besides retry) or if the ERP has failed.
2893 *
2894 * PARAMETER
2895 * erp_head first ERP in ERP-chain
2896 * erp ERP that handles the actual error.
2897 * (matching erp)
2898 *
2899 * RETURN VALUES
2900 * erp modified/additional ERP
2901 */
2902 ccw_req_t *
2903 dasd_3990_erp_handle_match_erp (ccw_req_t *erp_head,
2904 ccw_req_t *erp)
2905 {
2906
2907 dasd_device_t *device = erp_head->device;
2908 ccw_req_t *erp_done = erp_head; /* finished req */
2909 ccw_req_t *erp_free = NULL; /* req to be freed */
2910
2911 /* loop over successful ERPs and remove them from chanq */
2912 while (erp_done != erp) {
2913
2914 if (erp_done == NULL) /* end of chain reached */
2915 panic (PRINTK_HEADER "Programming error in ERP! The "
2916 "original request was lost\n");
2917
2918 /* remove the request from the device queue */
2919 dasd_chanq_deq (&device->queue,
2920 erp_done);
2921
2922 erp_free = erp_done;
2923 erp_done = erp_done->refers;
2924
2925 /* free the finished erp request */
2926 dasd_free_request (erp_free, erp_free->device);
2927
2928 } /* end while */
2929
2930 if (erp->retries > 0) {
2931
2932 char *sense = erp->dstat->ii.sense.data;
2933
2934 /* check for special retries */
2935 if (erp->function == dasd_3990_erp_action_4) {
2936
2937 erp = dasd_3990_erp_action_4 (erp,
2938 sense);
2939
2940 } else if (erp->function == dasd_3990_erp_action_1B_32) {
2941
2942 erp = dasd_3990_update_1B (erp,
2943 sense);
2944
2945 } else if (erp->function == dasd_3990_erp_int_req) {
2946
2947 erp = dasd_3990_erp_int_req (erp);
2948
2949 } else {
2950 /* simple retry */
2951 DASD_MESSAGE (KERN_DEBUG, device,
2952 "%i retries left for erp %p",
2953 erp->retries,
2954 erp);
2955
2956 /* handle the request again... */
2957 check_then_set (&erp->status,
2958 CQR_STATUS_ERROR,
2959 CQR_STATUS_QUEUED);
2960 }
2961
2962 } else {
2963 /* no retry left - check for further necessary action */
2964 /* if no further actions, handle rest as permanent error */
2965 erp = dasd_3990_erp_further_erp (erp);
2966 }
2967
2968 return erp;
2969
2970 } /* end dasd_3990_erp_handle_match_erp */
2971
2972 /*
2973 * DASD_3990_ERP_ACTION
2974 *
2975 * DESCRIPTION
2976 * controll routine for 3990 erp actions.
2977 * Has to be called with the queue lock (namely the s390_irq_lock) acquired.
2978 *
2979 * PARAMETER
2980 * cqr failed cqr (either original cqr or already an erp)
2981 *
2982 * RETURN VALUES
2983 * erp erp-pointer to the head of the ERP action chain.
2984 * This means:
2985 * - either a ptr to an additional ERP cqr or
2986 * - the original given cqr (which's status might
2987 * be modified)
2988 */
2989 ccw_req_t *
2990 dasd_3990_erp_action (ccw_req_t *cqr)
2991 {
2992
2993 ccw_req_t *erp = NULL;
2994 dasd_device_t *device = cqr->device;
2995 __u32 cpa = cqr->dstat->cpa;
2996
2997 #ifdef ERP_DEBUG
2998 DASD_MESSAGE (KERN_DEBUG, device,
2999 "entering 3990 ERP for "
3000 "0x%04X on sch %d = /dev/%s ",
3001 device->devinfo.devno,
3002 device->devinfo.irq,
3003 device->name);
3004
3005 /* print current erp_chain */
3006 DASD_MESSAGE (KERN_DEBUG, device, "%s",
3007 "ERP chain at BEGINNING of ERP-ACTION");
3008 {
3009 ccw_req_t *temp_erp = NULL;
3010 for (temp_erp = cqr;
3011 temp_erp != NULL;
3012 temp_erp = temp_erp->refers){
3013
3014 DASD_MESSAGE (KERN_DEBUG, device,
3015 " erp %p refers to %p",
3016 temp_erp,
3017 temp_erp->refers);
3018 }
3019 }
3020 #endif /* ERP_DEBUG */
3021
3022 /* double-check if current erp/cqr was successfull */
3023 if ((cqr->dstat->cstat == 0x00 ) &&
3024 (cqr->dstat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) ) {
3025
3026 DASD_MESSAGE (KERN_DEBUG, device,
3027 "ERP called for successful request %p"
3028 " - NO ERP necessary",
3029 cqr);
3030
3031 check_then_set (&cqr->status,
3032 CQR_STATUS_ERROR,
3033 CQR_STATUS_DONE);
3034
3035 return cqr;
3036 }
3037 /* check if sense data are available */
3038 if (!cqr->dstat->ii.sense.data) {
3039 DASD_MESSAGE (KERN_DEBUG, device,
3040 "ERP called witout sense data avail ..."
3041 "request %p - NO ERP possible",
3042 cqr);
3043
3044 check_then_set (&cqr->status,
3045 CQR_STATUS_ERROR,
3046 CQR_STATUS_FAILED);
3047
3048 return cqr;
3049
3050 }
3051
3052 /* check if error happened before */
3053 erp = dasd_3990_erp_in_erp (cqr);
3054
3055 if (erp == NULL) {
3056 /* no matching erp found - set up erp */
3057 erp = dasd_3990_erp_additional_erp (cqr);
3058 } else {
3059 /* matching erp found - set all leading erp's to DONE */
3060 erp = dasd_3990_erp_handle_match_erp (cqr,
3061 erp);
3062 }
3063
3064 #ifdef ERP_DEBUG
3065 /* print current erp_chain */
3066 DASD_MESSAGE (KERN_DEBUG, device, "%s",
3067 "ERP chain at END of ERP-ACTION");
3068 {
3069 ccw_req_t *temp_erp = NULL;
3070 for (temp_erp = erp;
3071 temp_erp != NULL;
3072 temp_erp = temp_erp->refers) {
3073
3074 DASD_MESSAGE (KERN_DEBUG, device,
3075 " erp %p refers to %p",
3076 temp_erp,
3077 temp_erp->refers);
3078 }
3079 }
3080 #endif /* ERP_DEBUG */
3081
3082 if (erp->status == CQR_STATUS_FAILED) {
3083
3084 log_erp_chain (erp,
3085 1,
3086 cpa);
3087 }
3088
3089 /* enqueue added ERP request */
3090 if ((erp != cqr ) &&
3091 (erp->status == CQR_STATUS_FILLED) ){
3092
3093 dasd_chanq_enq_head (&device->queue,
3094 erp);
3095 } else {
3096 if ((erp->status == CQR_STATUS_FILLED )||
3097 (erp != cqr ) ){
3098 /* something strange happened - log the error and throw a BUG() */
3099 DASD_MESSAGE (KERN_ERR, device, "%s",
3100 "Problems with ERP chain!!! BUG");
3101
3102 /* print current erp_chain */
3103 DASD_MESSAGE (KERN_DEBUG, device, "%s",
3104 "ERP chain at END of ERP-ACTION");
3105 {
3106 ccw_req_t *temp_erp = NULL;
3107 for (temp_erp = erp;
3108 temp_erp != NULL;
3109 temp_erp = temp_erp->refers) {
3110
3111 DASD_MESSAGE (KERN_DEBUG, device,
3112 " erp %p (function %p) refers to %p",
3113 temp_erp,
3114 temp_erp->function,
3115 temp_erp->refers);
3116 }
3117 }
3118 BUG();
3119 }
3120
3121 }
3122
3123 return erp;
3124
3125 } /* end dasd_3990_erp_action */
3126
3127 /*
3128 * DASD_3990_ERP_POSTACTION
3129 *
3130 * DESCRIPTION
3131 * Frees all ERPs of the current ERP Chain and set the status
3132 * of the original CQR either to CQR_STATUS_DONE if ERP was successful
3133 * or to CQR_STATUS_FAILED if ERP was NOT successful.
3134 *
3135 * PARAMETER
3136 * erp current erp_head
3137 *
3138 * RETURN VALUES
3139 * cqr pointer to the original CQR
3140 */
3141 ccw_req_t *
3142 dasd_3990_erp_postaction (ccw_req_t *erp)
3143 {
3144
3145 ccw_req_t *cqr = NULL,
3146 *free_erp = NULL;
3147 dasd_device_t *device = erp->device;
3148 int success;
3149
3150 if (erp->refers == NULL ||
3151 erp->function == NULL ) {
3152
3153 BUG ();
3154 }
3155
3156 if (erp->status == CQR_STATUS_DONE)
3157 success = 1;
3158 else
3159 success = 0;
3160
3161 #ifdef ERP_DEBUG
3162
3163 /* print current erp_chain */
3164 printk (KERN_DEBUG PRINTK_HEADER
3165 "3990 ERP postaction called for erp chain:\n");
3166 {
3167 ccw_req_t *temp_erp = NULL;
3168
3169 for (temp_erp = erp;
3170 temp_erp != NULL;
3171 temp_erp = temp_erp->refers) {
3172
3173 printk (KERN_DEBUG PRINTK_HEADER
3174 " erp %p refers to %p with erp function %p\n",
3175 temp_erp, temp_erp->refers, temp_erp->function);
3176 }
3177 }
3178
3179 #endif /* ERP_DEBUG */
3180
3181 /* free all ERPs - but NOT the original cqr */
3182 while (erp->refers != NULL) {
3183
3184 free_erp = erp;
3185 erp = erp->refers;
3186
3187 /* remove the request from the device queue */
3188 dasd_chanq_deq (&device->queue,
3189 free_erp);
3190
3191 /* free the finished erp request */
3192 dasd_free_request (free_erp, free_erp->device);
3193 }
3194
3195 /* save ptr to original cqr */
3196 cqr = erp;
3197
3198 /* set corresponding status to original cqr */
3199 if (success) {
3200
3201 check_then_set (&cqr->status,
3202 CQR_STATUS_ERROR,
3203 CQR_STATUS_DONE);
3204 } else {
3205
3206 check_then_set (&cqr->status,
3207 CQR_STATUS_ERROR,
3208 CQR_STATUS_FAILED);
3209 }
3210
3211 #ifdef ERP_DEBUG
3212 /* print current erp_chain */
3213 printk (KERN_DEBUG PRINTK_HEADER
3214 "3990 ERP postaction finished with remaining chain:\n");
3215 {
3216 ccw_req_t *temp_erp = NULL;
3217
3218 for (temp_erp = cqr;
3219 temp_erp != NULL;
3220 temp_erp = temp_erp->refers) {
3221
3222 printk (KERN_DEBUG PRINTK_HEADER
3223 " erp %p refers to %p \n", temp_erp,
3224 temp_erp->refers);
3225 }
3226 }
3227 #endif /* ERP_DEBUG */
3228
3229 return cqr;
3230
3231 } /* end dasd_3990_erp_postaction */
3232
3233 /*
3234 * Overrides for Emacs so that we follow Linus's tabbing style.
3235 * Emacs will notice this stuff at the end of the file and automatically
3236 * adjust the settings for this buffer only. This must remain at the end
3237 * of the file.
3238 * ---------------------------------------------------------------------------
3239 * Local variables:
3240 * c-indent-level: 4
3241 * c-brace-imaginary-offset: 0
3242 * c-brace-offset: -4
3243 * c-argdecl-indent: 4
3244 * c-label-offset: -4
3245 * c-continued-statement-offset: 4
3246 * c-continued-brace-offset: 0
3247 * indent-tabs-mode: nil
3248 * tab-width: 8
3249 * End:
3250 */
3251