brintos

brintos / linux-shallow public Read only

0
0
Text · 12.3 KiB · 0ff8482 Raw
401 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 *    Copyright IBM Corp. 20024 *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)5 *		 Martin Schwidefsky (schwidefsky@de.ibm.com)6 *7 * Status accumulation and basic sense functions.8 */9 10#include <linux/module.h>11#include <linux/init.h>12#include <linux/io.h>13 14#include <asm/ccwdev.h>15#include <asm/cio.h>16 17#include "cio.h"18#include "cio_debug.h"19#include "css.h"20#include "device.h"21#include "ioasm.h"22#include "io_sch.h"23 24/*25 * Check for any kind of channel or interface control check but don't26 * issue the message for the console device27 */28static void29ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)30{31	struct subchannel *sch = to_subchannel(cdev->dev.parent);32	char dbf_text[15];33 34	if (!scsw_is_valid_cstat(&irb->scsw) ||35	    !(scsw_cstat(&irb->scsw) & (SCHN_STAT_CHN_DATA_CHK |36	      SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK)))37		return;38	CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check "39		      "received"40		      " ... device %04x on subchannel 0.%x.%04x, dev_stat "41		      ": %02X sch_stat : %02X\n",42		      cdev->private->dev_id.devno, sch->schid.ssid,43		      sch->schid.sch_no,44		      scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw));45	sprintf(dbf_text, "chk%x", sch->schid.sch_no);46	CIO_TRACE_EVENT(0, dbf_text);47	CIO_HEX_EVENT(0, irb, sizeof(struct irb));48}49 50/*51 * Some paths became not operational (pno bit in scsw is set).52 */53static void54ccw_device_path_notoper(struct ccw_device *cdev)55{56	struct subchannel *sch;57 58	sch = to_subchannel(cdev->dev.parent);59	if (cio_update_schib(sch))60		goto doverify;61 62	CIO_MSG_EVENT(0, "%s(0.%x.%04x) - path(s) %02x are "63		      "not operational \n", __func__,64		      sch->schid.ssid, sch->schid.sch_no,65		      sch->schib.pmcw.pnom);66 67	sch->lpm &= ~sch->schib.pmcw.pnom;68doverify:69	cdev->private->flags.doverify = 1;70}71 72/*73 * Copy valid bits from the extended control word to device irb.74 */75static void76ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb)77{78	/*79	 * Copy extended control bit if it is valid... yes there80	 * are condition that have to be met for the extended control81	 * bit to have meaning. Sick.82	 */83	cdev->private->dma_area->irb.scsw.cmd.ectl = 0;84	if ((irb->scsw.cmd.stctl & SCSW_STCTL_ALERT_STATUS) &&85	    !(irb->scsw.cmd.stctl & SCSW_STCTL_INTER_STATUS))86		cdev->private->dma_area->irb.scsw.cmd.ectl = irb->scsw.cmd.ectl;87	/* Check if extended control word is valid. */88	if (!cdev->private->dma_area->irb.scsw.cmd.ectl)89		return;90	/* Copy concurrent sense / model dependent information. */91	memcpy(&cdev->private->dma_area->irb.ecw, irb->ecw, sizeof(irb->ecw));92}93 94/*95 * Check if extended status word is valid.96 */97static int98ccw_device_accumulate_esw_valid(struct irb *irb)99{100	if (!irb->scsw.cmd.eswf &&101	    (irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND))102		return 0;103	if (irb->scsw.cmd.stctl ==104			(SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND) &&105	    !(irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED))106		return 0;107	return 1;108}109 110/*111 * Copy valid bits from the extended status word to device irb.112 */113static void114ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb)115{116	struct irb *cdev_irb;117	struct sublog *cdev_sublog, *sublog;118 119	if (!ccw_device_accumulate_esw_valid(irb))120		return;121 122	cdev_irb = &cdev->private->dma_area->irb;123 124	/* Copy last path used mask. */125	cdev_irb->esw.esw1.lpum = irb->esw.esw1.lpum;126 127	/* Copy subchannel logout information if esw is of format 0. */128	if (irb->scsw.cmd.eswf) {129		cdev_sublog = &cdev_irb->esw.esw0.sublog;130		sublog = &irb->esw.esw0.sublog;131		/* Copy extended status flags. */132		cdev_sublog->esf = sublog->esf;133		/*134		 * Copy fields that have a meaning for channel data check135		 * channel control check and interface control check.136		 */137		if (irb->scsw.cmd.cstat & (SCHN_STAT_CHN_DATA_CHK |138				       SCHN_STAT_CHN_CTRL_CHK |139				       SCHN_STAT_INTF_CTRL_CHK)) {140			/* Copy ancillary report bit. */141			cdev_sublog->arep = sublog->arep;142			/* Copy field-validity-flags. */143			cdev_sublog->fvf = sublog->fvf;144			/* Copy storage access code. */145			cdev_sublog->sacc = sublog->sacc;146			/* Copy termination code. */147			cdev_sublog->termc = sublog->termc;148			/* Copy sequence code. */149			cdev_sublog->seqc = sublog->seqc;150		}151		/* Copy device status check. */152		cdev_sublog->devsc = sublog->devsc;153		/* Copy secondary error. */154		cdev_sublog->serr = sublog->serr;155		/* Copy i/o-error alert. */156		cdev_sublog->ioerr = sublog->ioerr;157		/* Copy channel path timeout bit. */158		if (irb->scsw.cmd.cstat & SCHN_STAT_INTF_CTRL_CHK)159			cdev_irb->esw.esw0.erw.cpt = irb->esw.esw0.erw.cpt;160		/* Copy failing storage address validity flag. */161		cdev_irb->esw.esw0.erw.fsavf = irb->esw.esw0.erw.fsavf;162		if (cdev_irb->esw.esw0.erw.fsavf) {163			/* ... and copy the failing storage address. */164			memcpy(cdev_irb->esw.esw0.faddr, irb->esw.esw0.faddr,165			       sizeof (irb->esw.esw0.faddr));166			/* ... and copy the failing storage address format. */167			cdev_irb->esw.esw0.erw.fsaf = irb->esw.esw0.erw.fsaf;168		}169		/* Copy secondary ccw address validity bit. */170		cdev_irb->esw.esw0.erw.scavf = irb->esw.esw0.erw.scavf;171		if (irb->esw.esw0.erw.scavf)172			/* ... and copy the secondary ccw address. */173			cdev_irb->esw.esw0.saddr = irb->esw.esw0.saddr;174		175	}176	/* FIXME: DCTI for format 2? */177 178	/* Copy authorization bit. */179	cdev_irb->esw.esw0.erw.auth = irb->esw.esw0.erw.auth;180	/* Copy path verification required flag. */181	cdev_irb->esw.esw0.erw.pvrf = irb->esw.esw0.erw.pvrf;182	if (irb->esw.esw0.erw.pvrf)183		cdev->private->flags.doverify = 1;184	/* Copy concurrent sense bit. */185	cdev_irb->esw.esw0.erw.cons = irb->esw.esw0.erw.cons;186	if (irb->esw.esw0.erw.cons)187		cdev_irb->esw.esw0.erw.scnt = irb->esw.esw0.erw.scnt;188}189 190/*191 * Accumulate status from irb to devstat.192 */193void194ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb)195{196	struct irb *cdev_irb;197 198	/*199	 * Check if the status pending bit is set in stctl.200	 * If not, the remaining bit have no meaning and we must ignore them.201	 * The esw is not meaningful as well...202	 */203	if (!(scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))204		return;205 206	/* Check for channel checks and interface control checks. */207	ccw_device_msg_control_check(cdev, irb);208 209	/* Check for path not operational. */210	if (scsw_is_valid_pno(&irb->scsw) && scsw_pno(&irb->scsw))211		ccw_device_path_notoper(cdev);212	/* No irb accumulation for transport mode irbs. */213	if (scsw_is_tm(&irb->scsw)) {214		memcpy(&cdev->private->dma_area->irb, irb, sizeof(struct irb));215		return;216	}217	/*218	 * Don't accumulate unsolicited interrupts.219	 */220	if (!scsw_is_solicited(&irb->scsw))221		return;222 223	cdev_irb = &cdev->private->dma_area->irb;224 225	/*226	 * If the clear function had been performed, all formerly pending227	 * status at the subchannel has been cleared and we must not pass228	 * intermediate accumulated status to the device driver.229	 */230	if (irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC)231		memset(&cdev->private->dma_area->irb, 0, sizeof(struct irb));232 233	/* Copy bits which are valid only for the start function. */234	if (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) {235		/* Copy key. */236		cdev_irb->scsw.cmd.key = irb->scsw.cmd.key;237		/* Copy suspend control bit. */238		cdev_irb->scsw.cmd.sctl = irb->scsw.cmd.sctl;239		/* Accumulate deferred condition code. */240		cdev_irb->scsw.cmd.cc |= irb->scsw.cmd.cc;241		/* Copy ccw format bit. */242		cdev_irb->scsw.cmd.fmt = irb->scsw.cmd.fmt;243		/* Copy prefetch bit. */244		cdev_irb->scsw.cmd.pfch = irb->scsw.cmd.pfch;245		/* Copy initial-status-interruption-control. */246		cdev_irb->scsw.cmd.isic = irb->scsw.cmd.isic;247		/* Copy address limit checking control. */248		cdev_irb->scsw.cmd.alcc = irb->scsw.cmd.alcc;249		/* Copy suppress suspend bit. */250		cdev_irb->scsw.cmd.ssi = irb->scsw.cmd.ssi;251	}252 253	/* Take care of the extended control bit and extended control word. */254	ccw_device_accumulate_ecw(cdev, irb);255	    256	/* Accumulate function control. */257	cdev_irb->scsw.cmd.fctl |= irb->scsw.cmd.fctl;258	/* Copy activity control. */259	cdev_irb->scsw.cmd.actl = irb->scsw.cmd.actl;260	/* Accumulate status control. */261	cdev_irb->scsw.cmd.stctl |= irb->scsw.cmd.stctl;262	/*263	 * Copy ccw address if it is valid. This is a bit simplified264	 * but should be close enough for all practical purposes.265	 */266	if ((irb->scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) ||267	    ((irb->scsw.cmd.stctl ==268	      (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND)) &&269	     (irb->scsw.cmd.actl & SCSW_ACTL_DEVACT) &&270	     (irb->scsw.cmd.actl & SCSW_ACTL_SCHACT)) ||271	    (irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED))272		cdev_irb->scsw.cmd.cpa = irb->scsw.cmd.cpa;273	/* Accumulate device status, but not the device busy flag. */274	cdev_irb->scsw.cmd.dstat &= ~DEV_STAT_BUSY;275	/* dstat is not always valid. */276	if (irb->scsw.cmd.stctl &277	    (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS278	     | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS))279		cdev_irb->scsw.cmd.dstat |= irb->scsw.cmd.dstat;280	/* Accumulate subchannel status. */281	cdev_irb->scsw.cmd.cstat |= irb->scsw.cmd.cstat;282	/* Copy residual count if it is valid. */283	if ((irb->scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) &&284	    (irb->scsw.cmd.cstat & ~(SCHN_STAT_PCI | SCHN_STAT_INCORR_LEN))285	     == 0)286		cdev_irb->scsw.cmd.count = irb->scsw.cmd.count;287 288	/* Take care of bits in the extended status word. */289	ccw_device_accumulate_esw(cdev, irb);290 291	/*292	 * Check whether we must issue a SENSE CCW ourselves if there is no293	 * concurrent sense facility installed for the subchannel.294	 * No sense is required if no delayed sense is pending295	 * and we did not get a unit check without sense information.296	 *297	 * Note: We should check for ioinfo[irq]->flags.consns but VM298	 *	 violates the ESA/390 architecture and doesn't present an299	 *	 operand exception for virtual devices without concurrent300	 *	 sense facility available/supported when enabling the301	 *	 concurrent sense facility.302	 */303	if ((cdev_irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&304	    !(cdev_irb->esw.esw0.erw.cons))305		cdev->private->flags.dosense = 1;306}307 308/*309 * Do a basic sense.310 */311int312ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb)313{314	struct subchannel *sch;315	struct ccw1 *sense_ccw;316	int rc;317 318	sch = to_subchannel(cdev->dev.parent);319 320	/* A sense is required, can we do it now ? */321	if (scsw_actl(&irb->scsw) & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT))322		/*323		 * we received an Unit Check but we have no final324		 *  status yet, therefore we must delay the SENSE325		 *  processing. We must not report this intermediate326		 *  status to the device interrupt handler.327		 */328		return -EBUSY;329 330	/*331	 * We have ending status but no sense information. Do a basic sense.332	 */333	sense_ccw = &to_io_private(sch)->dma_area->sense_ccw;334	sense_ccw->cmd_code = CCW_CMD_BASIC_SENSE;335	sense_ccw->cda = virt_to_dma32(cdev->private->dma_area->irb.ecw);336	sense_ccw->count = SENSE_MAX_COUNT;337	sense_ccw->flags = CCW_FLAG_SLI;338 339	rc = cio_start(sch, sense_ccw, 0xff);340	if (rc == -ENODEV || rc == -EACCES)341		dev_fsm_event(cdev, DEV_EVENT_VERIFY);342	return rc;343}344 345/*346 * Add information from basic sense to devstat.347 */348void349ccw_device_accumulate_basic_sense(struct ccw_device *cdev, struct irb *irb)350{351	/*352	 * Check if the status pending bit is set in stctl.353	 * If not, the remaining bit have no meaning and we must ignore them.354	 * The esw is not meaningful as well...355	 */356	if (!(scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))357		return;358 359	/* Check for channel checks and interface control checks. */360	ccw_device_msg_control_check(cdev, irb);361 362	/* Check for path not operational. */363	if (scsw_is_valid_pno(&irb->scsw) && scsw_pno(&irb->scsw))364		ccw_device_path_notoper(cdev);365 366	if (!(irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&367	    (irb->scsw.cmd.dstat & DEV_STAT_CHN_END)) {368		cdev->private->dma_area->irb.esw.esw0.erw.cons = 1;369		cdev->private->flags.dosense = 0;370	}371	/* Check if path verification is required. */372	if (ccw_device_accumulate_esw_valid(irb) &&373	    irb->esw.esw0.erw.pvrf)374		cdev->private->flags.doverify = 1;375}376 377/*378 * This function accumulates the status into the private devstat and379 * starts a basic sense if one is needed.380 */381int382ccw_device_accumulate_and_sense(struct ccw_device *cdev, struct irb *irb)383{384	ccw_device_accumulate_irb(cdev, irb);385	if ((irb->scsw.cmd.actl  & (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) != 0)386		return -EBUSY;387	/* Check for basic sense. */388	if (cdev->private->flags.dosense &&389	    !(irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)) {390		cdev->private->dma_area->irb.esw.esw0.erw.cons = 1;391		cdev->private->flags.dosense = 0;392		return 0;393	}394	if (cdev->private->flags.dosense) {395		ccw_device_do_sense(cdev, irb);396		return -EBUSY;397	}398	return 0;399}400 401