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