From owner-p4-projects@FreeBSD.ORG Wed Apr 21 12:08:06 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 37EF41065672; Wed, 21 Apr 2010 12:08:06 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F05561065670 for ; Wed, 21 Apr 2010 12:08:05 +0000 (UTC) (envelope-from mav@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id DC8508FC25 for ; Wed, 21 Apr 2010 12:08:05 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o3LC85PZ001862 for ; Wed, 21 Apr 2010 12:08:05 GMT (envelope-from mav@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o3LC85jH001860 for perforce@freebsd.org; Wed, 21 Apr 2010 12:08:05 GMT (envelope-from mav@freebsd.org) Date: Wed, 21 Apr 2010 12:08:05 GMT Message-Id: <201004211208.o3LC85jH001860@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mav@freebsd.org using -f From: Alexander Motin To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 177174 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Apr 2010 12:08:06 -0000 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 */