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