brintos

brintos / linux-shallow public Read only

0
0
Text · 70.0 KiB · d0aa267 Raw
2816 lines · c
1// SPDX-License-Identifier: GPL-2.02/*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, 20017 *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 HANDLING26 *****************************************************************************27 */28/*29 *****************************************************************************30 * 24 and 32 byte sense ERP functions31 *****************************************************************************32 */33 34/*35 * DASD_3990_ERP_CLEANUP36 *37 * DESCRIPTION38 *   Removes the already build but not necessary ERP request and sets39 *   the status of the original cqr / erp to the given (final) status40 *41 *  PARAMETER42 *   erp		request to be blocked43 *   final_status	either DASD_CQR_DONE or DASD_CQR_FAILED44 *45 * RETURN VALUES46 *   cqr		original cqr47 */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_QUEUE61 *62 * DESCRIPTION63 *   Block the given device request queue to prevent from further64 *   processing until the started timer has expired or an related65 *   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	else83		dasd_device_set_timer(device, expires);84}85 86/*87 * DASD_3990_ERP_INT_REQ88 *89 * DESCRIPTION90 *   Handles 'Intervention Required' error.91 *   This means either device offline or not installed.92 *93 * PARAMETER94 *   erp		current erp95 * RETURN VALUES96 *   erp		modified erp97 */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_PATH128 *129 * DESCRIPTION130 *   Repeat the operation on a different channel path.131 *   If all alternate paths have been tried, the request is posted with a132 *   permanent error.133 *134 *  PARAMETER135 *   erp		pointer to the current ERP136 *137 * RETURN VALUES138 *   erp		modified pointer to the ERP139 */140static void141dasd_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	else155		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_DCTL178 *179 * DESCRIPTION180 *   Setup cqr to do the Diagnostic Control (DCTL) command with an181 *   Inhibit Write subcommand (0x20) and the given modifier.182 *183 *  PARAMETER184 *   erp		pointer to the current (failed) ERP185 *   modifier		subcommand modifier186 *187 * RETURN VALUES188 *   dctl_cqr		pointer to NEW dctl_cqr189 *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_1239 *240 * DESCRIPTION241 *   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 mask244 *   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 as247 *   we try to use them (flapping links).248 *   If all alternate paths have been tried twice, the request is posted with249 *   a permanent error.250 *251 *  PARAMETER252 *   erp		pointer to the current ERP253 *254 * RETURN VALUES255 *   erp		pointer to the ERP256 *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_4281 *282 * DESCRIPTION283 *   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 device285 *   until the state change interrupt appears.286 *   Use a timer (20 seconds) to retry the cqr if the interrupt is still287 *   missing.288 *289 *  PARAMETER290 *   sense		sense data of the actual error291 *   erp		pointer to the current ERP292 *293 * RETURN VALUES294 *   erp		pointer to the ERP295 *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_5352 *353 * DESCRIPTION354 *   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 *  PARAMETER358 *   erp		pointer to the current ERP359 *360 * RETURN VALUES361 *   erp		pointer to the ERP362 *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_DATA378 *379 * DESCRIPTION380 *   Handles 24 byte 'Environmental data present'.381 *   Does a analysis of the sense data (message Format)382 *   and prints the error messages.383 *384 * PARAMETER385 *   sense		current sense data386 *387 * RETURN VALUES388 *   void389 */390static void391dasd_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_REJ1012 *1013 * DESCRIPTION1014 *   Handles 24 byte 'Command Reject' error.1015 *1016 * PARAMETER1017 *   erp		current erp_head1018 *   sense		current sense data1019 *1020 * RETURN VALUES1021 *   erp		'new' erp_head - pointer to new ERP1022 */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_OUT1064 *1065 * DESCRIPTION1066 *   Handles 24 byte 'Bus Out Parity Check' error.1067 *1068 * PARAMETER1069 *   erp		current erp_head1070 * RETURN VALUES1071 *   erp		new erp_head - pointer to new ERP1072 */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_CHECK1103 *1104 * DESCRIPTION1105 *   Handles 24 byte 'Equipment Check' error.1106 *1107 * PARAMETER1108 *   erp		current erp_head1109 * RETURN VALUES1110 *   erp		new erp_head - pointer to new ERP1111 */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_CHECK1156 *1157 * DESCRIPTION1158 *   Handles 24 byte 'Data Check' error.1159 *1160 * PARAMETER1161 *   erp		current erp_head1162 * RETURN VALUES1163 *   erp		new erp_head - pointer to new ERP1164 */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_OVERRUN1215 *1216 * DESCRIPTION1217 *   Handles 24 byte 'Overrun' error.1218 *1219 * PARAMETER1220 *   erp		current erp_head1221 * RETURN VALUES1222 *   erp		new erp_head - pointer to new ERP1223 */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_FORMAT1244 *1245 * DESCRIPTION1246 *   Handles 24 byte 'Invalid Track Format' error.1247 *1248 * PARAMETER1249 *   erp		current erp_head1250 * RETURN VALUES1251 *   erp		new erp_head - pointer to new ERP1252 */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_EOC1282 *1283 * DESCRIPTION1284 *   Handles 24 byte 'End-of-Cylinder' error.1285 *1286 * PARAMETER1287 *   erp		already added default erp1288 * RETURN VALUES1289 *   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_DATA1307 *1308 * DESCRIPTION1309 *   Handles 24 byte 'Environmental-Data Present' error.1310 *1311 * PARAMETER1312 *   erp		current erp_head1313 * RETURN VALUES1314 *   erp		new erp_head - pointer to new ERP1315 */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_REC1341 *1342 * DESCRIPTION1343 *   Handles 24 byte 'No Record Found' error.1344 *1345 * PARAMETER1346 *   erp		already added default ERP1347 *1348 * RETURN VALUES1349 *   erp		new erp_head - pointer to new ERP1350 */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 and1359	 * 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_PROT1372 *1373 * DESCRIPTION1374 *   Handles 24 byte 'File Protected' error.1375 *   Note: Seek related recovery is not implemented because1376 *	   wee don't use the seek command yet.1377 *1378 * PARAMETER1379 *   erp		current erp_head1380 * RETURN VALUES1381 *   erp		new erp_head - pointer to new ERP1382 */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_ALIAS1398 *1399 * DESCRIPTION1400 *   Checks if the original request was started on an alias device.1401 *   If yes, it modifies the original and the erp request so that1402 *   the erp request can be started on a base device.1403 *1404 * PARAMETER1405 *   erp		pointer to the currently created default ERP1406 *1407 * RETURN VALUES1408 *   erp		pointer to the modified ERP, or NULL1409 */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 mapping1423		 */1424		if (!test_bit(DASD_FLAG_OFFLINE, &cqr->startdev->flags) && sense1425		    && (sense[0] == 0x10) && (sense[7] == 0x0F)1426		    && (sense[8] == 0x67)) {1427			/*1428			 * remove device from alias handling to prevent new1429			 * requests from being scheduled on the1430			 * wrong alias device1431			 */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	} else1449		return NULL;1450}1451 1452 1453/*1454 * DASD_3990_ERP_INSPECT_241455 *1456 * DESCRIPTION1457 *   Does a detailed inspection of the 24 byte sense data1458 *   and sets up a related error recovery action.1459 *1460 * PARAMETER1461 *   sense		sense data of the actual error1462 *   erp		pointer to the currently created default ERP1463 *1464 * RETURN VALUES1465 *   erp		pointer to the (addtitional) ERP1466 */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_321536 *1537 * DESCRIPTION1538 *   Handles 32 byte 'Action 10' of Single Program Action Codes.1539 *   Just retry and if retry doesn't work, return with error.1540 *1541 * PARAMETER1542 *   erp		current erp_head1543 *   sense		current sense data1544 * RETURN VALUES1545 *   erp		modified erp_head1546 */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_321564 *1565 * DESCRIPTION1566 *   Handles 32 byte 'Action 1B' of Single Program Action Codes.1567 *   A write operation could not be finished because of an unexpected1568 *   condition.1569 *   The already created 'default erp' is used to get the link to1570 *   the erp chain, but it can not be used for this recovery1571 *   action because it contains no DE/LO data space.1572 *1573 * PARAMETER1574 *   default_erp	already added default erp.1575 *   sense		current sense data1576 *1577 * RETURN VALUES1578 *   erp		new erp or1579 *			default_erp in case of imprecise ending or error1580 */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	} else1653		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_1B1726 *1727 * DESCRIPTION1728 *   Handles the update to the 32 byte 'Action 1B' of Single Program1729 *   Action Codes in case the first action was not successful.1730 *   The already created 'previous_erp' is the currently not successful1731 *   ERP.1732 *1733 * PARAMETER1734 *   previous_erp	already created previous erp.1735 *   sense		current sense data1736 * RETURN VALUES1737 *   erp		modified erp1738 */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_RETRY1838 *1839 * DESCRIPTION1840 *   Handles the compound ERP action retry code.1841 *   NOTE: At least one retry is done even if zero is specified1842 *	   by the sense data. This makes enqueueing of the request1843 *	   easier.1844 *1845 * PARAMETER1846 *   sense		sense data of the actual error1847 *   erp		pointer to the currently created ERP1848 *1849 * RETURN VALUES1850 *   erp		modified ERP pointer1851 *1852 */1853static void1854dasd_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_PATH1884 *1885 * DESCRIPTION1886 *   Handles the compound ERP action for retry on alternate1887 *   channel path.1888 *1889 * PARAMETER1890 *   sense		sense data of the actual error1891 *   erp		pointer to the currently created ERP1892 *1893 * RETURN VALUES1894 *   erp		modified ERP pointer1895 *1896 */1897static void1898dasd_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 to1906			 * 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_CODE1918 *1919 * DESCRIPTION1920 *   Handles the compound ERP action for retry code.1921 *1922 * PARAMETER1923 *   sense		sense data of the actual error1924 *   erp		pointer to the currently created ERP1925 *1926 * RETURN VALUES1927 *   erp		NEW ERP pointer1928 *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 an1939			 * 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_CONFIG1964 *1965 * DESCRIPTION1966 *   Handles the compound ERP action for configuration1967 *   dependent error.1968 *   Note: duplex handling is not implemented (yet).1969 *1970 * PARAMETER1971 *   sense		sense data of the actual error1972 *   erp		pointer to the currently created ERP1973 *1974 * RETURN VALUES1975 *   erp		modified ERP pointer1976 *1977 */1978static void1979dasd_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_COMPOUND1994 *1995 * DESCRIPTION1996 *   Does the further compound program action if1997 *   compound retry was not successful.1998 *1999 * PARAMETER2000 *   sense		sense data of the actual error2001 *   erp		pointer to the current (failed) ERP2002 *2003 * RETURN VALUES2004 *   erp		(additional) ERP pointer2005 *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_SIM2039 *2040 *DESCRIPTION2041 *  inspects the SIM SENSE data and starts an appropriate action2042 *2043 * PARAMETER2044 *   sense	   sense data of the actual error2045 *2046 * RETURN VALUES2047 *   none2048 */2049void2050dasd_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_322068 *2069 * DESCRIPTION2070 *   Does a detailed inspection of the 32 byte sense data2071 *   and sets up a related error recovery action.2072 *2073 * PARAMETER2074 *   sense		sense data of the actual error2075 *   erp		pointer to the currently created default ERP2076 *2077 * RETURN VALUES2078 *   erp_filled		pointer to the ERP2079 *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			panic2151			    ("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 state2223	 */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_CHECK2245 *2246 * DESCRIPTION2247 *   Does a generic inspection if a control check occurred and sets up2248 *   the related error recovery procedure2249 *2250 * PARAMETER2251 *   erp		pointer to the currently created default ERP2252 *2253 * RETURN VALUES2254 *   erp_filled		pointer to the erp2255 */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_CHK2263					   | 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_INSPECT2274 *2275 * DESCRIPTION2276 *   Does a detailed inspection for sense data by calling either2277 *   the 24-byte or the 32-byte inspection routine.2278 *2279 * PARAMETER2280 *   erp		pointer to the currently created default ERP2281 * RETURN VALUES2282 *   erp_new		contens was possibly modified2283 */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 the2297	 * already set up new ERP !2298	 * check if concurrent sens is available2299	 */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_ERP2321 *2322 * DESCRIPTION2323 *   This function adds an additional request block (ERP) to the head of2324 *   the given cqr (or erp).2325 *   For a command mode cqr the erp is initialized as an default erp2326 *   (retry TIC).2327 *   For transport mode we make a copy of the original TCW (points to2328 *   the original TCCB, TIDALs, etc.) but give it a fresh2329 *   TSB so the original sense data will not be changed.2330 *2331 * PARAMETER2332 *   cqr		head of the current ERP-chain (or single cqr if2333 *			first error)2334 * RETURN VALUES2335 *   erp		pointer to new ERP-chain head2336 */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_ERP2414 *2415 * DESCRIPTION2416 *   An additional ERP is needed to handle the current error.2417 *   Add ERP to the head of the ERP-chain containing the ERP processing2418 *   determined based on the sense data.2419 *2420 * PARAMETER2421 *   cqr		head of the current ERP-chain (or single cqr if2422 *			first error)2423 *2424 * RETURN VALUES2425 *   erp		pointer to new ERP-chain head2426 */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_MATCH2451 *2452 * DESCRIPTION2453 *   Check if the device status of the given cqr is the same.2454 *   This means that the failed CCW and the relevant sense data2455 *   must match.2456 *   I don't distinguish between 24 and 32 byte sense because in case of2457 *   24 byte sense byte 25 and 27 is set as well.2458 *2459 * PARAMETER2460 *   cqr1		first cqr, which will be compared with the2461 *   cqr2		second cqr.2462 *2463 * RETURN VALUES2464 *   match		'boolean' for match found2465 *			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_ERP2504 *2505 * DESCRIPTION2506 *   check if the current error already happened before.2507 *   quick exit if current cqr is not an ERP (cqr->refers=NULL)2508 *2509 * PARAMETER2510 *   cqr		failed cqr (either original cqr or already an erp)2511 *2512 * RETURN VALUES2513 *   erp		erp-pointer to the already defined error2514 *			recovery procedure OR2515 *			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 * DESCRIPTION2549 *   No retry is left for the current ERP. Check what has to be done2550 *   with the ERP.2551 *     - do further defined ERP action or2552 *     - wait for interrupt or2553 *     - exit with permanent error2554 *2555 * PARAMETER2556 *   erp		ERP which is in progress with no retry left2557 *2558 * RETURN VALUES2559 *   erp		modified/additional ERP2560 */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 an2586			 * 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 handling2624		 * necessary2625		 */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_ERP2638 *2639 * DESCRIPTION2640 *   An error occurred again and an ERP has been detected which is already2641 *   used to handle this error (e.g. retries).2642 *   All prior ERP's are asumed to be successful and therefore removed2643 *   from queue.2644 *   If retry counter of matching erp is already 0, it is checked if further2645 *   action is needed (besides retry) or if the ERP has failed.2646 *2647 * PARAMETER2648 *   erp_head		first ERP in ERP-chain2649 *   erp		ERP that handles the actual error.2650 *			(matching erp)2651 *2652 * RETURN VALUES2653 *   erp		modified/additional ERP2654 */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_ACTION2721 *2722 * DESCRIPTION2723 *   control routine for 3990 erp actions.2724 *   Has to be called with the queue lock (namely the s390_irq_lock) acquired.2725 *2726 * PARAMETER2727 *   cqr		failed cqr (either original cqr or already an erp)2728 *2729 * RETURN VALUES2730 *   erp		erp-pointer to the head of the ERP action chain.2731 *			This means:2732 *			 - either a ptr to an additional ERP cqr or2733 *			 - the original given cqr (which's status might2734 *			   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 was2785	 * originally chosen so that the per path configuration data is2786	 * 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 */2816