Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 Apr 2010 12:08:05 GMT
From:      Alexander Motin <mav@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 177174 for review
Message-ID:  <201004211208.o3LC85jH001860@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@177174?ac=10

Change 177174 by mav@mav_mavtest on 2010/04/21 12:07:13

	Implement error handling.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#4 edit
.. //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.h#4 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.c#4 (text+ko) ====

@@ -87,6 +87,7 @@
 static void mvs_legacy_execute_transaction(struct mvs_slot *slot);
 static void mvs_timeout(struct mvs_slot *slot);
 static void mvs_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error);
+static void mvs_requeue_frozen(device_t dev);
 static void mvs_execute_transaction(struct mvs_slot *slot);
 static void mvs_end_transaction(struct mvs_slot *slot, enum mvs_err_type et);
 
@@ -843,6 +844,7 @@
 	ch->curr_mode = mode;
 	ch->fbs_enabled = 0;
 	ch->fake_busy = 0;
+	device_printf(dev, "EDMA mode: %d\n", mode);
 	if (mode == MVS_EDMA_OFF)
 		return;
 	/* Configure new mode. */
@@ -865,10 +867,10 @@
 	ATA_OUTL(ch->r_mem, EDMA_CFG, reg);
 	mvs_setup_edma_queues(dev);
 	/* Configure FBS */
-	device_printf(dev, "fisc %08x\n",ATA_INL(ch->r_mem, SATA_FISC));
-	device_printf(dev, "ltmode %08x\n",ATA_INL(ch->r_mem, SATA_LTM));
-	device_printf(dev, "edmacfg %08x\n",ATA_INL(ch->r_mem, EDMA_CFG));
-	device_printf(dev, "haltcond %08x\n",ATA_INL(ch->r_mem, EDMA_HC));
+//	device_printf(dev, "fisc %08x\n",ATA_INL(ch->r_mem, SATA_FISC));
+//	device_printf(dev, "ltmode %08x\n",ATA_INL(ch->r_mem, SATA_LTM));
+//	device_printf(dev, "edmacfg %08x\n",ATA_INL(ch->r_mem, EDMA_CFG));
+//	device_printf(dev, "haltcond %08x\n",ATA_INL(ch->r_mem, EDMA_HC));
 	/* Run EDMA. */
 	ATA_OUTL(ch->r_mem, EDMA_CMD, EDMA_CMD_EENEDMA);
 }
@@ -977,10 +979,13 @@
 	device_t dev = (device_t)arg->arg;
 	struct mvs_channel *ch = device_get_softc(dev);
 	uint32_t iec, serr = 0, fisic = 0;
+	enum mvs_err_type et;
+	int i, ccs, port = -1;
+	int edma = (ch->numtslots != 0 || ch->numdslots != 0);
 
-//device_printf(dev, "irq cause %02x IEC %08x\n",
-//    arg->cause, ATA_INL(ch->r_mem, EDMA_IEC));
-	if ((ch->numtslots != 0 || ch->numdslots != 0) && (arg->cause & 2))
+//device_printf(dev, "irq cause %02x EDMA %d IEC %08x\n",
+//    arg->cause, edma, ATA_INL(ch->r_mem, EDMA_IEC));
+	if ((arg->cause & 2) && edma)
 		mvs_crbq_intr(dev);
 	if (arg->cause & 1) {
 		iec = ATA_INL(ch->r_mem, EDMA_IEC);
@@ -991,12 +996,82 @@
 		}
 		if (iec & EDMA_IE_ETRANSINT) {
 			fisic = ATA_INL(ch->r_mem, SATA_FISIC);
-			ATA_OUTL(ch->r_mem, SATA_FISIC, ~fisic);
 device_printf(dev, "FISC %08x\n", ATA_INL(ch->r_mem, SATA_FISC));
 device_printf(dev, "FISIC %08x\n", fisic);
 device_printf(dev, "FISIM %08x\n", ATA_INL(ch->r_mem, SATA_FISIM));
 		}
 		ATA_OUTL(ch->r_mem, EDMA_IEC, ~iec);
+		/* Interface errors or Device error. */
+		if (iec & (0xfffff000 | EDMA_IE_EDEVERR)) {
+			port = -1;
+			if (ch->numpslots != 0) {
+				ccs = 0;
+			} else {
+				if (ch->quirks & MVS_Q_GENIIE)
+					ccs = EDMA_S_EIOID(ATA_INL(ch->r_mem, EDMA_S));
+				else
+					ccs = EDMA_S_EDEVQUETAG(ATA_INL(ch->r_mem, EDMA_S));
+				/* Check if error is one-PMP-port-specific, */
+				if (ch->fbs_enabled) {
+					/* Which ports were active. */
+					for (i = 0; i < 16; i++) {
+						if (ch->numrslotspd[i] == 0)
+							continue;
+						if (port == -1)
+							port = i;
+						else if (port != i) {
+							port = -2;
+							break;
+						}
+					}
+					/* If several ports were active and EDMA still enabled - 
+					 * other ports are probably unaffected and may continue.
+					 */
+					if (port == -2 && (iec & EDMA_IE_ESELFDIS) == 0) {
+						uint16_t p = ATA_INL(ch->r_mem, SATA_SATAITC) >> 16;
+						port = ffs(p) - 1;
+						if (port != (fls(p) - 1))
+							port = -2;
+					}
+				}
+			}
+device_printf(dev, "err slot %d port %d\n", ccs, port);
+			mvs_requeue_frozen(dev);
+			for (i = 0; i < MVS_MAX_SLOTS; i++) {
+				/* XXX: reqests in loading state. */
+				if (((ch->rslots >> i) & 1) == 0)
+					continue;
+				if (port >= 0 &&
+				    ch->slot[i].ccb->ccb_h.target_id != port)
+					continue;
+				if (iec & EDMA_IE_EDEVERR) { /* Device error. */
+				    if (port != -2) {
+					if (ch->numtslots == 0) {
+						/* Untagged operation. */
+						if (i == ccs)
+							et = MVS_ERR_TFE;
+						else
+							et = MVS_ERR_INNOCENT;
+					} else {
+						/* Tagged operation. */
+						et = MVS_ERR_NCQ;
+					}
+				    } else {
+					et = MVS_ERR_TFE;
+					ch->fatalerr = 1;
+				    }
+				} else if (iec & 0xfffff000) {
+					if (ch->numtslots == 0 && i != ccs && port != -2)
+						et = MVS_ERR_INNOCENT;
+					else
+						et = MVS_ERR_SATA;
+				} else
+					et = MVS_ERR_INVALID;
+				mvs_end_transaction(&ch->slot[i], et);
+			}
+		}
+		if (fisic)
+			ATA_OUTL(ch->r_mem, SATA_FISIC, ~fisic);
 		if (iec & EDMA_IE_ESELFDIS)
 			ch->curr_mode = MVS_EDMA_OFF;
 		if ((iec & (EDMA_IE_EDEVDIS | EDMA_IE_EDEVCON)) ||
@@ -1005,146 +1080,8 @@
 		if (fisic & SATA_FISC_FISWAIT4HOSTRDYEN_B1)
 			mvs_notify_events(dev, ch->pm_present ? 0x8000 : 0x0001);
 	}
-	if ((ch->numpslots != 0) && (arg->cause & 2))
+	if ((arg->cause & 2) && !edma)
 		mvs_legacy_intr(dev);
-#if 0
-	uint32_t istatus, sstatus, cstatus, serr = 0, sntf = 0, ok, err;
-	enum mvs_err_type et;
-	int i, ccs, port;
-
-	/* Read and clear interrupt statuses. */
-	istatus = ATA_INL(ch->r_mem, MVS_P_IS);
-	if (istatus == 0)
-		return;
-	ATA_OUTL(ch->r_mem, MVS_P_IS, istatus);
-	/* Read command statuses. */
-	sstatus = ATA_INL(ch->r_mem, MVS_P_SACT);
-	cstatus = ATA_INL(ch->r_mem, MVS_P_CI);
-	if (istatus & MVS_P_IX_SDB) {
-		if (ch->caps & MVS_CAP_SSNTF)
-			sntf = ATA_INL(ch->r_mem, MVS_P_SNTF);
-		else if (ch->fbs_enabled) {
-			u_int8_t *fis = ch->dma.rfis + 0x58;
-
-			for (i = 0; i < 16; i++) {
-				if (fis[1] & 0x80) {
-					fis[1] &= 0x7f;
-	    				sntf |= 1 << i;
-	    			}
-	    			fis += 256;
-	    		}
-		} else {
-			u_int8_t *fis = ch->dma.rfis + 0x58;
-
-			if (fis[1] & 0x80)
-				sntf = (1 << (fis[1] & 0x0f));
-		}
-	}
-	/* Process PHY events */
-	if (istatus & (MVS_P_IX_PC | MVS_P_IX_PRC | MVS_P_IX_OF |
-	    MVS_P_IX_IF | MVS_P_IX_HBD | MVS_P_IX_HBF | MVS_P_IX_TFE)) {
-		serr = ATA_INL(ch->r_mem, SATA_SE);
-		if (serr) {
-			ATA_OUTL(ch->r_mem, SATA_SE, 0xffffffff);
-			mvs_phy_check_events(dev, serr);
-		}
-	}
-	/* Process command errors */
-	if (istatus & (MVS_P_IX_OF | MVS_P_IX_IF |
-	    MVS_P_IX_HBD | MVS_P_IX_HBF | MVS_P_IX_TFE)) {
-		ccs = (ATA_INL(ch->r_mem, MVS_P_CMD) & MVS_P_CMD_CCS_MASK)
-		    >> MVS_P_CMD_CCS_SHIFT;
-//device_printf(dev, "%s ERROR is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x fbs %08x ccs %d\n",
-//    __func__, istatus, cstatus, sstatus, ch->rslots, ATA_INL(ch->r_mem, MVS_P_TFD),
-//    serr, ATA_INL(ch->r_mem, MVS_P_FBS), ccs);
-		port = -1;
-		if (ch->fbs_enabled) {
-			uint32_t fbs = ATA_INL(ch->r_mem, MVS_P_FBS);
-			if (fbs & MVS_P_FBS_SDE) {
-				port = (fbs & MVS_P_FBS_DWE)
-				    >> MVS_P_FBS_DWE_SHIFT;
-			} else {
-				for (i = 0; i < 16; i++) {
-					if (ch->numrslotspd[i] == 0)
-						continue;
-					if (port == -1)
-						port = i;
-					else if (port != i) {
-						port = -2;
-						break;
-					}
-				}
-			}
-		}
-		err = ch->rslots & (cstatus | sstatus);
-	} else {
-		ccs = 0;
-		err = 0;
-		port = -1;
-	}
-	/* Complete all successfull commands. */
-	ok = ch->rslots & ~(cstatus | sstatus);
-	for (i = 0; i < MVS_MAX_SLOTS; i++) {
-		if ((ok >> i) & 1)
-			mvs_end_transaction(&ch->slot[i], MVS_ERR_NONE);
-	}
-	/* On error, complete the rest of commands with error statuses. */
-	if (err) {
-		if (ch->frozen) {
-			union ccb *fccb = ch->frozen;
-			ch->frozen = NULL;
-			fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
-			if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
-				xpt_freeze_devq(fccb->ccb_h.path, 1);
-				fccb->ccb_h.status |= CAM_DEV_QFRZN;
-			}
-			xpt_done(fccb);
-		}
-		for (i = 0; i < MVS_MAX_SLOTS; i++) {
-			/* XXX: reqests in loading state. */
-			if (((err >> i) & 1) == 0)
-				continue;
-			if (port >= 0 &&
-			    ch->slot[i].ccb->ccb_h.target_id != port)
-				continue;
-			if (istatus & MVS_P_IX_TFE) {
-			    if (port != -2) {
-				/* Task File Error */
-				if (ch->numtslotspd[
-				    ch->slot[i].ccb->ccb_h.target_id] == 0) {
-					/* Untagged operation. */
-					if (i == ccs)
-						et = MVS_ERR_TFE;
-					else
-						et = MVS_ERR_INNOCENT;
-				} else {
-					/* Tagged operation. */
-					et = MVS_ERR_NCQ;
-				}
-			    } else {
-				et = MVS_ERR_TFE;
-				ch->fatalerr = 1;
-			    }
-			} else if (istatus & MVS_P_IX_IF) {
-				if (ch->numtslots == 0 && i != ccs && port != -2)
-					et = MVS_ERR_INNOCENT;
-				else
-					et = MVS_ERR_SATA;
-			} else
-				et = MVS_ERR_INVALID;
-			mvs_end_transaction(&ch->slot[i], et);
-		}
-		/*
-		 * We can't reinit port if there are some other
-		 * commands active, use resume to complete them.
-		 */
-		if (ch->rslots != 0) 
-			ATA_OUTL(ch->r_mem, MVS_P_FBS, MVS_P_FBS_EN | MVS_P_FBS_DEC);
-	}
-	/* Process NOTIFY events */
-	if (sntf)
-		mvs_notify_events(dev, sntf);
-#endif
 }
 
 static uint8_t
@@ -1166,7 +1103,8 @@
 mvs_legacy_intr(device_t dev)
 {
 	struct mvs_channel *ch = device_get_softc(dev);
-	union ccb *ccb = ch->slot[0].ccb;
+	struct mvs_slot *slot = &ch->slot[0]; /* PIO is always in slot 0. */
+	union ccb *ccb = slot->ccb;
 	enum mvs_err_type et = MVS_ERR_NONE;
 	int port = ccb->ccb_h.target_id & 0x0f;
 	u_int length;
@@ -1176,7 +1114,7 @@
 	status = mvs_getstatus(dev, 1);
 //	device_printf(dev, "Legacy intr status %02x\n",
 //	    status);
-	if (ch->slot[0].state < MVS_SLOT_RUNNING) {
+	if (slot->state < MVS_SLOT_RUNNING) {
 //	    device_printf(dev, "Stray irq\n");
 	    return;
 	}
@@ -1343,7 +1281,7 @@
 	mvs_tfd_read(dev, ccb);
 //	device_printf(dev, "After complete status %02x\n",
 //	    ATA_INB(ch->r_mem, ATA_ALTSTAT));
-	mvs_end_transaction(&ch->slot[0], et);
+	mvs_end_transaction(slot, et);
 }
 
 static void
@@ -1363,15 +1301,24 @@
 		crpb = (struct mvs_crpb *)
 		    (ch->dma.workrp + MVS_CRPB_OFFSET + (MVS_CRPB_SIZE * ch->in_idx));
 		slot = le16toh(crpb->id) & MVS_CRPB_TAG_MASK;
-		if (ch->slot[slot].state >= MVS_SLOT_RUNNING) {
-//device_printf(dev, "CRPB %d %d %04x\n", ch->in_idx, slot, le16toh(crpb->rspflg));
-			flags = le16toh(crpb->rspflg);
-			ccb = ch->slot[slot].ccb;
-			ccb->ataio.res.status = (flags & MVS_CRPB_ATASTS_MASK) >>
-			    MVS_CRPB_ATASTS_SHIFT;
-			mvs_end_transaction(&ch->slot[slot], MVS_ERR_NONE);
-		} else 
-device_printf(dev, "EMPTY CRPB %d %d %04x\n", ch->in_idx, slot, le16toh(crpb->rspflg));
+		flags = le16toh(crpb->rspflg);
+//device_printf(dev, "CRPB %d %d %04x\n", ch->in_idx, slot, flags);
+		/*
+		 * Handle only successfull completions.
+		 * Errors will be handled by main intr handler.
+		 */
+		if (ch->numtslots != 0 || (flags & EDMA_IE_EDEVERR) == 0) {
+if ((flags >> 8) & ATA_S_ERROR)
+device_printf(dev, "ERROR STATUS CRPB %d %d %04x\n", ch->in_idx, slot, flags);
+			if (ch->slot[slot].state >= MVS_SLOT_RUNNING) {
+				ccb = ch->slot[slot].ccb;
+				ccb->ataio.res.status = (flags & MVS_CRPB_ATASTS_MASK) >>
+				    MVS_CRPB_ATASTS_SHIFT;
+				mvs_end_transaction(&ch->slot[slot], MVS_ERR_NONE);
+			} else 
+device_printf(dev, "EMPTY CRPB %d %d %04x\n", ch->in_idx, slot, flags);
+		} else
+device_printf(dev, "ERROR FLAGS CRPB %d %d %04x\n", ch->in_idx, slot, flags);
 
 		ch->in_idx = (ch->in_idx + 1) & (MVS_MAX_SLOTS - 1);
 	}
@@ -1682,8 +1629,8 @@
 	int port = ccb->ccb_h.target_id & 0x0f;
 	int i;
 
-//	device_printf(dev, "%d EDMA command %02x size %d (%p) slot %d tag %d\n",
-//	    port, ccb->ataio.cmd.command, ccb->ataio.dxfer_len, ccb->ataio.data_ptr, slot->slot, slot->tag);
+	device_printf(dev, "%d EDMA command %02x size %d (%p) slot %d tag %d\n",
+	    port, ccb->ataio.cmd.command, ccb->ataio.dxfer_len, ccb->ataio.data_ptr, slot->slot, slot->tag);
 	/* Get address of the prepared EPRD */
 	eprd = ch->dma.workrq_bus + MVS_EPRD_OFFSET + (MVS_EPRD_SIZE * slot->slot);
 	/* Prepare CRQB. Gen IIe uses different CRQB format. */
@@ -1776,7 +1723,7 @@
 	ATA_OUTL(ch->r_mem, EDMA_REQQIP,
 	    ch->dma.workrq_bus + MVS_CRQB_OFFSET + (MVS_CRQB_SIZE * ch->out_idx));
 	/* Start command execution timeout */
-	callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 2000,
+	callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 1000,
 	    (timeout_t*)mvs_timeout, slot);
 	return;
 }
@@ -1826,70 +1773,26 @@
 {
 	device_t dev = slot->dev;
 	struct mvs_channel *ch = device_get_softc(dev);
-//	uint32_t sstatus;
-//	int ccs;
-	int i;
 
 	/* Check for stale timeout. */
 	if (slot->state < MVS_SLOT_RUNNING)
 		return;
-#if 0
-	/* Check if slot was not being executed last time we checked. */
-	if (slot->state < MVS_SLOT_EXECUTING) {
-		/* Check if slot started executing. */
-		sstatus = ATA_INL(ch->r_mem, MVS_P_SACT);
-		ccs = (ATA_INL(ch->r_mem, MVS_P_CMD) & MVS_P_CMD_CCS_MASK)
-		    >> MVS_P_CMD_CCS_SHIFT;
-		if ((sstatus & (1 << slot->slot)) != 0 || ccs == slot->slot ||
-		    ch->fbs_enabled)
-			slot->state = MVS_SLOT_EXECUTING;
-
-		callout_reset(&slot->timeout,
-		    (int)slot->ccb->ccb_h.timeout * hz / 2000,
-		    (timeout_t*)mvs_timeout, slot);
-		return;
-	}
-#endif
 	device_printf(dev, "Timeout on slot %d\n", slot->slot);
 	device_printf(dev, "ic %08x iec %08x edma_s %08x dma_c %08x dma_s %08x rs %08x tfd %02x serr %08x\n",
 	    ATA_INL(ch->r_mem, HC_IC), ATA_INL(ch->r_mem, EDMA_IEC),
 	    ATA_INL(ch->r_mem, EDMA_S), ATA_INL(ch->r_mem, DMA_C), ATA_INL(ch->r_mem, DMA_S), ch->rslots,
 	    ATA_INB(ch->r_mem, ATA_ALTSTAT), ATA_INL(ch->r_mem, SATA_SE));
-
 	/* Handle frozen command. */
-	if (ch->frozen) {
-		union ccb *fccb = ch->frozen;
-		ch->frozen = NULL;
-		fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
-		if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
-			xpt_freeze_devq(fccb->ccb_h.path, 1);
-			fccb->ccb_h.status |= CAM_DEV_QFRZN;
-		}
-		xpt_done(fccb);
-	}
-	if (ch->fbs_enabled == 0 || ch->pm_present == 0) {
-		/* Without FBS we know real timeout source. */
-		ch->fatalerr = 1;
-		/* Handle command with timeout. */
-		mvs_end_transaction(&ch->slot[slot->slot], MVS_ERR_TIMEOUT);
-		/* Handle the rest of commands. */
-		for (i = 0; i < MVS_MAX_SLOTS; i++) {
-			/* Do we have a running request on slot? */
-			if (ch->slot[i].state < MVS_SLOT_RUNNING)
-				continue;
-			mvs_end_transaction(&ch->slot[i], MVS_ERR_INNOCENT);
-		}
-	} else {
-		/* With FBS we wait for other commands timeout and pray. */
-		if (ch->toslots == 0)
-			xpt_freeze_simq(ch->sim, 1);
-		ch->toslots |= (1 << slot->slot);
-		if ((ch->rslots & ~ch->toslots) == 0)
-			mvs_process_timeout(dev);
-		else
-			device_printf(dev, " ... waiting for slots %08x\n",
-			    ch->rslots & ~ch->toslots);
-	}
+	mvs_requeue_frozen(dev);
+	/* We wait for other commands timeout and pray. */
+	if (ch->toslots == 0)
+		xpt_freeze_simq(ch->sim, 1);
+	ch->toslots |= (1 << slot->slot);
+	if ((ch->rslots & ~ch->toslots) == 0)
+		mvs_process_timeout(dev);
+	else
+		device_printf(dev, " ... waiting for slots %08x\n",
+		    ch->rslots & ~ch->toslots);
 }
 
 /* Must be called with channel locked. */
@@ -1900,6 +1803,7 @@
 	struct mvs_channel *ch = device_get_softc(dev);
 	union ccb *ccb = slot->ccb;
 
+device_printf(dev, "cmd done status %d\n", et);
 	bus_dmamap_sync(ch->dma.workrq_tag, ch->dma.workrq_map,
 	    BUS_DMASYNC_POSTWRITE);
 	/* Read result registers to the result struct
@@ -2008,6 +1912,7 @@
 	/* If it was NCQ command error, put result on hold. */
 	} else if (et == MVS_ERR_NCQ) {
 		ch->hold[slot->slot] = ccb;
+		ch->holdtag[slot->slot] = slot->tag;
 		ch->numhslots++;
 	} else
 		xpt_done(ccb);
@@ -2026,8 +1931,8 @@
 		} else {
 			/* if we have slots in error, we can reinit port. */
 			if (ch->eslots != 0) {
-//				mvs_stop(dev);
-//				mvs_start(dev, 1);
+				mvs_set_edma_mode(dev, MVS_EDMA_OFF);
+				ch->eslots = 0;
 			}
 			/* if there commands on hold, we can do READ LOG. */
 			if (!ch->readlog && ch->numhslots)
@@ -2103,7 +2008,9 @@
 		for (i = 0; i < MVS_MAX_SLOTS; i++) {
 			if (!ch->hold[i])
 				continue;
-			if ((data[0] & 0x1F) == i) {
+			if (ch->hold[i]->ccb_h.target_id != ccb->ccb_h.target_id)
+				continue;
+			if ((data[0] & 0x1F) == ch->holdtag[i]) {
 				res = &ch->hold[i]->ataio.res;
 				res->status = data[2];
 				res->error = data[3];
@@ -2133,6 +2040,8 @@
 		for (i = 0; i < MVS_MAX_SLOTS; i++) {
 			if (!ch->hold[i])
 				continue;
+			if (ch->hold[i]->ccb_h.target_id != ccb->ccb_h.target_id)
+				continue;
 			xpt_done(ch->hold[i]);
 			ch->hold[i] = NULL;
 			ch->numhslots--;
@@ -2161,18 +2070,12 @@
 }
 
 static void
-mvs_reset(device_t dev)
+mvs_requeue_frozen(device_t dev)
 {
 	struct mvs_channel *ch = device_get_softc(dev);
-//	struct mvs_controller *ctlr = device_get_softc(device_get_parent(dev));
-	int i;
+	union ccb *fccb = ch->frozen;
 
-	xpt_freeze_simq(ch->sim, 1);
-	if (bootverbose)
-		device_printf(dev, "MVS reset...\n");
-	/* Requeue freezed command. */
-	if (ch->frozen) {
-		union ccb *fccb = ch->frozen;
+	if (fccb) {
 		ch->frozen = NULL;
 		fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
 		if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
@@ -2181,6 +2084,19 @@
 		}
 		xpt_done(fccb);
 	}
+}
+
+static void
+mvs_reset(device_t dev)
+{
+	struct mvs_channel *ch = device_get_softc(dev);
+	int i;
+
+	xpt_freeze_simq(ch->sim, 1);
+	if (bootverbose)
+		device_printf(dev, "MVS reset...\n");
+	/* Requeue freezed command. */
+	mvs_requeue_frozen(dev);
 	/* Kill the engine and requeue all running commands. */
 	mvs_set_edma_mode(dev, MVS_EDMA_OFF);
 	for (i = 0; i < MVS_MAX_SLOTS; i++) {

==== //depot/projects/scottl-camlock/src/sys/dev/mvs/mvs.h#4 (text+ko) ====

@@ -510,6 +510,7 @@
 
 	struct mvs_slot		slot[MVS_MAX_SLOTS];
 	union ccb		*hold[MVS_MAX_SLOTS];
+	int			holdtag[MVS_MAX_SLOTS]; /* Tags used for holden commands. */
 	struct mtx		mtx;		/* state lock */
 	int			devices;        /* What is present */
 	int			pm_present;	/* PM presence reported */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004211208.o3LC85jH001860>