File Index
Files and directories
Sign in
FILE

dasd_3990_erp.c

File preview with syntax highlighting.

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