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