Index: esp_sbus.c =================================================================== RCS file: /mnt/futile/usr/data/bsd/cvs/fbsd/src/sys/dev/esp/esp_sbus.c,v retrieving revision 1.11 diff -u -p -r1.11 esp_sbus.c --- esp_sbus.c 19 May 2005 14:51:10 -0000 1.11 +++ esp_sbus.c 23 Jul 2006 14:24:33 -0000 @@ -1,5 +1,6 @@ /*- * Copyright (c) 2004 Scott Long + * Copyright (c) 2005 Marius Strobl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -217,7 +218,7 @@ esp_sbus_attach(device_t dev) esc->sc_dev = dev; name = ofw_bus_get_name(dev); node = ofw_bus_get_node(dev); - if (OF_getprop(node, "initiator-id", &sc->sc_id, + if (OF_getprop(node, "scsi-initiator-id", &sc->sc_id, sizeof(sc->sc_id)) == -1) sc->sc_id = 7; sc->sc_freq = sbus_get_clockfreq(dev); @@ -259,7 +260,7 @@ esp_sbus_attach(device_t dev) /* Create a parent DMA tag based on this bus. */ error = bus_dma_tag_create( NULL, /* parent */ - PAGE_SIZE, 0, /* alignment, boundary */ + 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ @@ -415,7 +416,7 @@ esp_dma_attach(device_t dev) esc->sc_dev = dev; node = ofw_bus_get_node(dev); - if (OF_getprop(node, "initiator-id", &sc->sc_id, + if (OF_getprop(node, "scsi-initiator-id", &sc->sc_id, sizeof(sc->sc_id)) == -1) sc->sc_id = 7; if (OF_getprop(node, "clock-frequency", &sc->sc_freq, @@ -676,9 +677,6 @@ espattach(struct esp_softc *esc, struct break; } - /* Limit minsync due to unsolved performance issues. */ - sc->sc_maxsync = sc->sc_minsync; - /* Establish interrupt channel */ esc->sc_irqrid = 0; if ((esc->sc_irqres = bus_alloc_resource_any(esc->sc_dev, SYS_RES_IRQ, Index: ncr53c9x.c =================================================================== RCS file: /mnt/futile/usr/data/bsd/cvs/fbsd/src/sys/dev/esp/ncr53c9x.c,v retrieving revision 1.13 diff -u -p -r1.13 ncr53c9x.c --- ncr53c9x.c 4 Dec 2005 10:06:03 -0000 1.13 +++ ncr53c9x.c 23 Jul 2006 17:33:16 -0000 @@ -1,5 +1,6 @@ /*- * Copyright (c) 2004 Scott Long + * Copyright (c) 2005, 2006 Marius Strobl * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,7 +26,7 @@ * */ -/* $NetBSD: ncr53c9x.c,v 1.114 2005/02/27 00:27:02 perry Exp $ */ +/* $NetBSD: ncr53c9x.c,v 1.116 2005/11/06 10:31:46 tsutsui Exp $ */ /*- * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc. @@ -111,8 +112,8 @@ __FBSDID("$FreeBSD: src/sys/dev/esp/ncr5 #include #include #include -#include #include +#include #include #include #include @@ -129,15 +130,16 @@ __FBSDID("$FreeBSD: src/sys/dev/esp/ncr5 #include #include +MODULE_DEPEND(esp, cam, 1, 1, 1); + +#ifdef NCR53C9X_DEBUG int ncr53c9x_debug = NCR_SHOWMISC /*|NCR_SHOWPHASE|NCR_SHOWTRAC|NCR_SHOWCMDS*/; -#ifdef DEBUG -int ncr53c9x_notag = 0; #endif static void ncr53c9x_select(struct ncr53c9x_softc *, struct ncr53c9x_ecb *); static int ncr53c9x_reselect(struct ncr53c9x_softc *, int, int, int); -static void ncr53c9x_scsi_reset(struct ncr53c9x_softc *); static void ncr53c9x_poll(struct cam_sim *); +static void ncr53c9x_async(void *, uint32_t, struct cam_path *, void *); static void ncr53c9x_sched(struct ncr53c9x_softc *); static void ncr53c9x_done(struct ncr53c9x_softc *, struct ncr53c9x_ecb *); static void ncr53c9x_msgin(struct ncr53c9x_softc *); @@ -227,6 +229,7 @@ ncr53c9x_attach(struct ncr53c9x_softc *s struct cam_sim *sim; struct cam_path *path; struct ncr53c9x_ecb *ecb; + struct ccb_setasync csa; int error, i; mtx_init(&sc->sc_lock, "ncr", "ncr53c9x lock", MTX_DEF); @@ -237,7 +240,8 @@ ncr53c9x_attach(struct ncr53c9x_softc *s if (sc->sc_rev >= NCR_VARIANT_MAX) { device_printf(sc->sc_dev, "unknown variant %d, devices not " "attached\n", sc->sc_rev); - return (EINVAL); + error = EINVAL; + goto fail_mtx; } device_printf(sc->sc_dev, "%s, %dMHz, SCSI ID %d\n", @@ -257,7 +261,8 @@ ncr53c9x_attach(struct ncr53c9x_softc *s if (sc->sc_omess == NULL) { device_printf(sc->sc_dev, "cannot allocate MSGOUT buffer\n"); - return (ENOMEM); + error = ENOMEM; + goto fail_mtx; } } else sc->sc_omess_self = 0; @@ -346,12 +351,21 @@ ncr53c9x_attach(struct ncr53c9x_softc *s goto fail_bus; } + xpt_setup_ccb(&csa.ccb_h, path, 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = AC_LOST_DEVICE; + csa.callback = ncr53c9x_async; + csa.callback_arg = sim; + xpt_action((union ccb *)&csa); + sc->sc_sim = sim; sc->sc_path = path; /* Reset state & bus */ #if 0 sc->sc_cfflags = sc->sc_dev.dv_cfdata->cf_flags; +#else + sc->sc_cfflags = 0; #endif sc->sc_state = 0; ncr53c9x_init(sc, 1); @@ -361,7 +375,7 @@ ncr53c9x_attach(struct ncr53c9x_softc *s M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) { device_printf(sc->sc_dev, "cannot allocate ECB array\n"); error = ENOMEM; - goto fail_path; + goto fail_async; } for (i = 0; i < NCR_TAG_DEPTH; i++) { ecb = &sc->ecb_array[i]; @@ -374,7 +388,13 @@ ncr53c9x_attach(struct ncr53c9x_softc *s return (0); -fail_path: +fail_async: + xpt_setup_ccb(&csa.ccb_h, path, 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = 0; + csa.callback = ncr53c9x_async; + csa.callback_arg = sim; + xpt_action((union ccb *)&csa); xpt_free_path(path); fail_bus: xpt_bus_deregister(cam_sim_path(sim)); @@ -390,17 +410,26 @@ fail_imess: fail_omess: if (sc->sc_omess_self) free(sc->sc_omess, M_DEVBUF); +fail_mtx: + mtx_destroy(&sc->sc_lock); return (error); } int ncr53c9x_detach(struct ncr53c9x_softc *sc) { + struct ccb_setasync csa; callout_drain(&sc->sc_watchdog); mtx_lock(&sc->sc_lock); ncr53c9x_init(sc, 1); mtx_unlock(&sc->sc_lock); + xpt_setup_ccb(&csa.ccb_h, sc->sc_path, 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = 0; + csa.callback = ncr53c9x_async; + csa.callback_arg = sc->sc_sim; + xpt_action((union ccb *)&csa); xpt_free_path(sc->sc_path); xpt_bus_deregister(cam_sim_path(sc->sc_sim)); cam_sim_free(sc->sc_sim, TRUE); @@ -464,9 +493,11 @@ ncr53c9x_reset(struct ncr53c9x_softc *sc sc->sc_features |= NCR_F_HASCFG3 | NCR_F_FASTSCSI | NCR_F_SELATN3; sc->sc_cfg3 = NCRFASCFG3_FASTCLK | NCRFASCFG3_OBAUTO; + if ((sc->sc_id & 8) != 0) + sc->sc_cfg3 |= NCRFASCFG3_IDBIT3; sc->sc_cfg3_fscsi = NCRFASCFG3_FASTSCSI; NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); - sc->sc_cfg2 = 0; /* NCRCFG2_HMEFE| NCRCFG2_HME32 */ + sc->sc_cfg2 = NCRCFG2_HMEFE | NCRCFG2_HME32; NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1); NCR_WRITE_REG(sc, NCR_CCF, sc->sc_ccf); @@ -496,26 +527,13 @@ ncr53c9x_reset(struct ncr53c9x_softc *sc } /* - * Reset the SCSI bus, but not the chip - */ -static void -ncr53c9x_scsi_reset(struct ncr53c9x_softc *sc) -{ - - (*sc->sc_glue->gl_dma_stop)(sc); - - NCR_MISC(("%s: resetting SCSI bus\n", device_get_nameunit(sc->sc_dev))); - NCRCMD(sc, NCRCMD_RSTSCSI); - DELAY(250000); /* Give the bus a fighting chance to settle */ -} - -/* * Initialize ncr53c9x state machine */ void ncr53c9x_init(struct ncr53c9x_softc *sc, int doreset) { struct ncr53c9x_ecb *ecb; + struct ncr53c9x_tinfo *ti; struct ncr53c9x_linfo *li; int i, r; @@ -538,7 +556,7 @@ ncr53c9x_init(struct ncr53c9x_softc *sc, ecb->ccb->ccb_h.status = CAM_CMD_TIMEOUT; ncr53c9x_done(sc, ecb); } - /* Cancel outstanding disconnected commands on each LUN */ + /* Cancel outstanding disconnected commands on each LUN. */ for (r = 0; r < sc->sc_ntarg; r++) { LIST_FOREACH(li, &sc->sc_tinfo[r].luns, link) { if ((ecb = li->untagged) != NULL) { @@ -554,7 +572,7 @@ ncr53c9x_init(struct ncr53c9x_softc *sc, CAM_CMD_TIMEOUT; ncr53c9x_done(sc, ecb); } - for (i = 0; i < 256; i++) + for (i = 0; i < NCR_TAG_DEPTH; i++) if ((ecb = li->queued[i])) { li->queued[i] = NULL; ecb->ccb->ccb_h.status = @@ -575,25 +593,40 @@ ncr53c9x_init(struct ncr53c9x_softc *sc, sc->sc_msgpriq = sc->sc_msgout = sc->sc_msgoutq = 0; sc->sc_phase = sc->sc_prevphase = INVALID_PHASE; - for (r = 0; r < sc->sc_ntarg; r++) { - struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[r]; + /* + * If we're the first time through, set the default parameters + * for all targets. Otherwise we only clear their current transfer + * settings so we'll renegotiate their goal settings with the next + * command. + */ + if (sc->sc_state == 0) { + for (r = 0; r < sc->sc_ntarg; r++) { + ti = &sc->sc_tinfo[r]; /* XXX - config flags per target: low bits: no reselect; high bits: no synch */ - ti->flags = ((sc->sc_minsync && !(sc->sc_cfflags & (1<<((r&7)+8)))) - ? 0 : T_SYNCHOFF) | - ((sc->sc_cfflags & (1<<(r&7))) ? T_RSELECTOFF : 0); -#ifdef DEBUG - if (ncr53c9x_notag) - ti->flags &= ~T_TAG; -#endif - ti->period = sc->sc_minsync; - ti->offset = 0; - ti->cfg3 = 0; + ti->flags = + ((sc->sc_minsync && !(sc->sc_cfflags & (1<<((r&7)+8)))) + ? 0 : T_SYNCHOFF) | + ((sc->sc_cfflags & (1<<(r&7))) ? T_RSELECTOFF : 0); + ti->curr.period = ti->goal.period = 0; + ti->curr.offset = ti->goal.offset = 0; + ti->curr.width = ti->goal.width = 0; + } + } else { + for (r = 0; r < sc->sc_ntarg; r++) { + ti = &sc->sc_tinfo[r]; + ti->flags &= ~(T_SDTRSENT | T_WDTRSENT); + ti->curr.period = 0; + ti->curr.offset = 0; + ti->curr.width = 0; + } } if (doreset) { sc->sc_state = NCR_SBR; NCRCMD(sc, NCRCMD_RSTSCSI); + /* Give the bus a fighting chance to settle. */ + DELAY(250000); } else { sc->sc_state = NCR_IDLE; ncr53c9x_sched(sc); @@ -654,18 +687,18 @@ ncr53c9x_stp2cpb(struct ncr53c9x_softc * static __inline void ncr53c9x_setsync(struct ncr53c9x_softc *sc, struct ncr53c9x_tinfo *ti) { - u_char syncoff, synctp; - u_char cfg3 = sc->sc_cfg3 | ti->cfg3; + u_char cfg3, syncoff, synctp; - if (ti->flags & T_SYNCMODE) { - syncoff = ti->offset; - synctp = ncr53c9x_stp2cpb(sc, ti->period); + cfg3 = sc->sc_cfg3; + if (ti->curr.offset != 0) { + syncoff = ti->curr.offset; + synctp = ncr53c9x_stp2cpb(sc, ti->curr.period); if (sc->sc_features & NCR_F_FASTSCSI) { /* * If the period is 200ns or less (ti->period <= 50), * put the chip in Fast SCSI mode. */ - if (ti->period <= 50) + if (ti->curr.period <= 50) /* * There are (at least) 4 variations of the * configuration 3 register. The drive attach @@ -688,6 +721,11 @@ ncr53c9x_setsync(struct ncr53c9x_softc * synctp = 0; } + if (ti->curr.width != 0) { + if (sc->sc_rev == NCR_VARIANT_FAS366) + cfg3 |= NCRFASCFG3_EWIDE; + } + if (sc->sc_features & NCR_F_HASCFG3) NCR_WRITE_REG(sc, NCR_CFG3, cfg3); @@ -708,7 +746,7 @@ ncr53c9x_select(struct ncr53c9x_softc *s int target = ecb->ccb->ccb_h.target_id; int lun = ecb->ccb->ccb_h.target_lun; struct ncr53c9x_tinfo *ti; - int tiflags; + struct ncr53c9x_linfo *li; u_char *cmd; int clen; int selatn3, selatns; @@ -718,7 +756,6 @@ ncr53c9x_select(struct ncr53c9x_softc *s target, lun, ecb->cmd.cmd.opcode, ecb->tag[0], ecb->tag[1])); ti = &sc->sc_tinfo[target]; - tiflags = ti->flags; sc->sc_state = NCR_SELECTING; /* * Schedule the timeout now, the first time we will go away @@ -734,41 +771,34 @@ ncr53c9x_select(struct ncr53c9x_softc *s */ if (sc->sc_rev == NCR_VARIANT_FAS366) { NCRCMD(sc, NCRCMD_FLUSH); - NCR_WRITE_REG(sc, NCR_SELID, target | NCR_BUSID_HME); + NCR_WRITE_REG(sc, NCR_SELID, target | NCR_BUSID_HMEXC32 | + NCR_BUSID_HMEENCID); } else { NCR_WRITE_REG(sc, NCR_SELID, target); } - ncr53c9x_setsync(sc, ti); - - if ((ecb->flags & ECB_SENSE) != 0) { - /* - * For REQUEST SENSE, we should not send an IDENTIFY or - * otherwise mangle the target. There should be no MESSAGE IN - * phase. - */ - if (sc->sc_features & NCR_F_DMASELECT) { - /* setup DMA transfer for command */ - dmasize = clen = ecb->clen; - sc->sc_cmdlen = clen; - sc->sc_cmdp = (caddr_t)&ecb->cmd.cmd; - - /* Program the SCSI counter */ - NCR_SET_COUNT(sc, dmasize); - - if (sc->sc_rev != NCR_VARIANT_FAS366) - NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA); - /* And get the targets attention */ - NCRCMD(sc, NCRCMD_SELNATN | NCRCMD_DMA); - NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, - &dmasize); - NCRDMA_GO(sc); - } else { - ncr53c9x_wrfifo(sc, (u_char *)&ecb->cmd.cmd, ecb->clen); - NCRCMD(sc, NCRCMD_SELNATN); + /* + * As suggested in the SCSI-2 spec, force a renegotiation on + * each REQUEST SENSE and INQUIRY command, as the target might + * have lost our transfer negotiations. We only do so if the + * other LUNs of the target currently are neither busy nor used + * though, as otherwise we might start negotiating in the middle + * of another command for a different LUN of the same target. + */ + if (ecb->cmd.cmd.opcode == REQUEST_SENSE || + ecb->cmd.cmd.opcode == INQUIRY) { + LIST_FOREACH(li, &sc->sc_tinfo[target].luns, link) { + if (li->lun == lun) + continue; + if (li->untagged != NULL || li->used != 0) + goto setsync; } - return; + ti->curr.period = 0; + ti->curr.offset = 0; + ti->curr.width = 0; } +setsync: + ncr53c9x_setsync(sc, ti); selatn3 = selatns = 0; if (ecb->tag[0] != 0) { @@ -780,7 +810,9 @@ ncr53c9x_select(struct ncr53c9x_softc *s selatns = 1; } - if (ti->flags & T_NEGOTIATE) { + if (ti->curr.period != ti->goal.period || + ti->curr.offset != ti->goal.offset || + ti->curr.width != ti->goal.width) { /* We have to use SELATNS to send sync/wide messages */ selatn3 = 0; selatns = 1; @@ -799,7 +831,7 @@ ncr53c9x_select(struct ncr53c9x_softc *s /* We don't have tags, or will send messages with SELATNS */ clen = ecb->clen + 1; cmd -= 1; - cmd[0] = MSG_IDENTIFY(lun, (tiflags & T_RSELECTOFF) == 0); + cmd[0] = MSG_IDENTIFY(lun, (ti->flags & T_RSELECTOFF) == 0); } if ((sc->sc_features & NCR_F_DMASELECT) && !selatns) { @@ -809,6 +841,7 @@ ncr53c9x_select(struct ncr53c9x_softc *s sc->sc_cmdlen = clen; sc->sc_cmdp = cmd; + NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize); /* Program the SCSI counter */ NCR_SET_COUNT(sc, dmasize); @@ -823,7 +856,6 @@ ncr53c9x_select(struct ncr53c9x_softc *s NCRCMD(sc, NCRCMD_SELATN3 | NCRCMD_DMA); } else NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA); - NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize); NCRDMA_GO(sc); return; } @@ -898,7 +930,7 @@ ncr53c9x_action(struct cam_sim *sim, uni switch (ccb->ccb_h.func_code) { case XPT_RESET_BUS: - ncr53c9x_scsi_reset(sc); + ncr53c9x_init(sc, 1); ccb->ccb_h.status = CAM_REQ_CMP; mtx_unlock(&sc->sc_lock); xpt_done(ccb); @@ -920,7 +952,7 @@ ncr53c9x_action(struct cam_sim *sim, uni cpi->hba_misc = 0; cpi->hba_eng_cnt = 0; cpi->max_target = sc->sc_ntarg - 1; - cpi->max_lun = 8; + cpi->max_lun = 7; cpi->initiator_id = sc->sc_id; cpi->bus_id = 0; cpi->base_transfer_speed = 3300; @@ -941,9 +973,9 @@ ncr53c9x_action(struct cam_sim *sim, uni ti = &sc->sc_tinfo[ccb->ccb_h.target_id]; if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { - cts->sync_period = ti->period; - cts->sync_offset = ti->offset; - cts->bus_width = ti->width; + cts->sync_period = ti->curr.period; + cts->sync_offset = ti->curr.offset; + cts->bus_width = ti->curr.width; if ((ti->flags & T_TAG) != 0) cts->flags |= (CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); @@ -951,8 +983,13 @@ ncr53c9x_action(struct cam_sim *sim, uni cts->flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); } else { - cts->sync_period = sc->sc_maxsync; - cts->sync_offset = sc->sc_maxoffset; + if ((ti->flags & T_SYNCHOFF) != 0) { + cts->sync_period = 0; + cts->sync_offset = 0; + } else { + cts->sync_period = sc->sc_minsync; + cts->sync_offset = sc->sc_maxoffset; + } cts->bus_width = sc->sc_maxwidth; cts->flags |= (CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); } @@ -967,19 +1004,18 @@ ncr53c9x_action(struct cam_sim *sim, uni return; } case XPT_ABORT: - printf("XPT_ABORT called\n"); + device_printf(sc->sc_dev, "XPT_ABORT called\n"); ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; mtx_unlock(&sc->sc_lock); xpt_done(ccb); return; case XPT_TERM_IO: - printf("XPT_TERM_IO called\n"); + device_printf(sc->sc_dev, "XPT_TERM_IO called\n"); ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; mtx_unlock(&sc->sc_lock); xpt_done(ccb); return; case XPT_RESET_DEV: - printf("XPT_RESET_DEV called\n"); case XPT_SCSI_IO: { struct ccb_scsiio *csio; @@ -1000,7 +1036,7 @@ ncr53c9x_action(struct cam_sim *sim, uni if (ecb == NULL) { xpt_freeze_simq(sim, 1); ccb->ccb_h.status = CAM_REQUEUE_REQ; - printf("unable to allocate ecb\n"); + device_printf(sc->sc_dev, "unable to allocate ecb\n"); mtx_unlock(&sc->sc_lock); xpt_done(ccb); return; @@ -1058,29 +1094,22 @@ ncr53c9x_action(struct cam_sim *sim, uni if (cts->bus_width != 0) { NCR_MISC(("%s: target %d: wide negotiation\n", device_get_nameunit(sc->sc_dev), target)); - if (sc->sc_rev == NCR_VARIANT_FAS366) { - ti->flags |= T_WIDE; - ti->width = 1; - } - } else { - ti->flags &= ~T_WIDE; - ti->width = 0; - } - ti->flags |= T_NEGOTIATE; + if (sc->sc_rev == NCR_VARIANT_FAS366) + ti->goal.width = 1; + } else + ti->goal.width = 0; } if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) { NCR_MISC(("%s: target %d: sync period negotiation\n", device_get_nameunit(sc->sc_dev), target)); - ti->flags |= T_NEGOTIATE; - ti->period = cts->sync_period; + ti->goal.period = cts->sync_period; } if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) { NCR_MISC(("%s: target %d: sync offset negotiation\n", device_get_nameunit(sc->sc_dev), target)); - ti->flags |= T_NEGOTIATE; - ti->offset = cts->sync_offset; + ti->goal.offset = cts->sync_offset; } mtx_unlock(&sc->sc_lock); @@ -1117,14 +1146,77 @@ ncr53c9x_poll(struct cam_sim *sim) } /* + * Asynchronous notification handler + */ +static void +ncr53c9x_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg) +{ + struct ncr53c9x_softc *sc; + struct ncr53c9x_ecb *ecb; + struct ncr53c9x_tinfo *ti; + struct ncr53c9x_linfo *li; + int i, target; + + sc = cam_sim_softc(cbarg); + mtx_lock(&sc->sc_lock); + + switch (code) { + case AC_LOST_DEVICE: + target = xpt_path_target_id(path); + if (target < 0 || target >= sc->sc_ntarg) + break; + + /* Cancel outstanding disconnected commands on each LUN. */ + LIST_FOREACH(li, &sc->sc_tinfo[target].luns, link) { + if ((ecb = li->untagged) != NULL) { + li->untagged = NULL; + /* + * XXXXXXX + * + * Should we terminate a command + * that never reached the disk? + */ + li->busy = 0; + ecb->ccb->ccb_h.status = CAM_CMD_TIMEOUT; + ncr53c9x_done(sc, ecb); + } + for (i = 0; i < NCR_TAG_DEPTH; i++) + if ((ecb = li->queued[i])) { + li->queued[i] = NULL; + ecb->ccb->ccb_h.status = + CAM_CMD_TIMEOUT; + ncr53c9x_done(sc, ecb); + } + li->used = 0; + } + + /* Set the default parameters for the target. */ + ti = &sc->sc_tinfo[target]; +/* XXX - config flags per target: low bits: no reselect; high bits: no synch */ + ti->flags = + ((sc->sc_minsync && !(sc->sc_cfflags & (1<<((target&7)+8)))) + ? 0 : T_SYNCHOFF) | + ((sc->sc_cfflags & (1<<(target&7))) ? T_RSELECTOFF : 0); + ti->curr.period = ti->goal.period = 0; + ti->curr.offset = ti->goal.offset = 0; + ti->curr.width = ti->goal.width = 0; + break; + default: + break; + } + + mtx_unlock(&sc->sc_lock); +} + +/* * LOW LEVEL SCSI UTILITIES */ /* * Schedule a scsi operation. This has now been pulled out of the interrupt - * handler so that we may call it from ncr53c9x_scsipi_request and - * ncr53c9x_done. This may save us an unnecessary interrupt just to get - * things going. Should only be called when state == NCR_IDLE and at bio pl. + * handler so that we may call it from ncr53c9x_action and ncr53c9x_done. + * This may save us an unnecessary interrupt just to get things going. + * Should only be called when state == NCR_IDLE and with sc_lock held. */ static void ncr53c9x_sched(struct ncr53c9x_softc *sc) @@ -1143,15 +1235,12 @@ ncr53c9x_sched(struct ncr53c9x_softc *sc * Find first ecb in ready queue that is for a target/lunit * combinations that is not busy. */ - for (ecb = TAILQ_FIRST(&sc->ready_list); ecb != NULL; - ecb = TAILQ_NEXT(ecb, chain)) { + TAILQ_FOREACH(ecb, &sc->ready_list, chain) { ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id]; lun = ecb->ccb->ccb_h.target_lun; /* Select type of tag for this command */ - if ((ti->flags & (T_RSELECTOFF)) != 0) - tag = 0; - else if ((ti->flags & (T_TAG)) == 0) + if ((ti->flags & (T_RSELECTOFF | T_TAG)) != T_TAG) tag = 0; else if ((ecb->flags & ECB_SENSE) != 0) tag = 0; @@ -1280,47 +1369,53 @@ ncr53c9x_done(struct ncr53c9x_softc *sc, /* * Now, if we've come here with no error code, i.e. we've kept the - * initial XS_NOERROR, and the status code signals that we should + * initial CAM_REQ_CMP, and the status code signals that we should * check sense, we'll need to set up a request sense cmd block and * push the command back into the ready queue *before* any other * commands for this target/lunit, else we lose the sense info. * We don't support chk sense conditions for the request sense cmd. */ if (ccb->ccb_h.status == CAM_REQ_CMP) { + ccb->csio.scsi_status = ecb->stat; if ((ecb->flags & ECB_ABORT) != 0) { ccb->ccb_h.status = CAM_CMD_TIMEOUT; } else if ((ecb->flags & ECB_SENSE) != 0 && (ecb->stat != SCSI_STATUS_CHECK_COND)) { - ccb->ccb_h.status = CAM_AUTOSNS_VALID; + ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; + ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR | + CAM_AUTOSNS_VALID; } else if (ecb->stat == SCSI_STATUS_CHECK_COND) { if ((ecb->flags & ECB_SENSE) != 0) ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; else { /* First, save the return values */ ccb->csio.resid = ecb->dleft; - ncr53c9x_sense(sc, ecb); - return; + if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == + 0) { + ncr53c9x_sense(sc, ecb); + return; + } + ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; } } else { ccb->csio.resid = ecb->dleft; } -#if 0 - if (xs->status == SCSI_QUEUE_FULL || xs->status == XS_BUSY) - xs->error = XS_BUSY; -#endif + if (ecb->stat == SCSI_STATUS_QUEUE_FULL) + ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; + else if (ecb->stat == SCSI_STATUS_BUSY) + ccb->ccb_h.status = CAM_SCSI_BUSY; } #ifdef NCR53C9X_DEBUG if (ncr53c9x_debug & NCR_SHOWTRAC) { if (ccb->csio.resid != 0) printf("resid=%d ", ccb->csio.resid); -#if 0 - if (xs->error == XS_SENSE) + if ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0) printf("sense=0x%02x\n", - xs->sense.scsi_sense.error_code); + ccb->csio.sense_data.error_code); else - printf("error=%d\n", xs->error); -#endif + printf("status SCSI=0x%x CAM=0x%x\n", + ccb->csio.scsi_status, ccb->ccb_h.status); } #endif @@ -1382,6 +1477,7 @@ ncr53c9x_dequeue(struct ncr53c9x_softc * li->queued[ecb->tag[1]] = NULL; li->used--; } + ecb->tag[0] = ecb->tag[1] = 0; if ((ecb->flags & ECB_READY) != 0) { ecb->flags &= ~ECB_READY; @@ -1422,15 +1518,15 @@ static int ncr53c9x_rdfifo(struct ncr53c9x_softc *sc, int how) { int i, n; - u_char *buf; + u_char *ibuf; switch(how) { case NCR_RDFIFO_START: - buf = sc->sc_imess; + ibuf = sc->sc_imess; sc->sc_imlen = 0; break; case NCR_RDFIFO_CONTINUE: - buf = sc->sc_imess + sc->sc_imlen; + ibuf = sc->sc_imess + sc->sc_imlen; break; default: panic("ncr53c9x_rdfifo: bad flag"); @@ -1447,12 +1543,12 @@ ncr53c9x_rdfifo(struct ncr53c9x_softc *s n *= 2; for (i = 0; i < n; i++) - buf[i] = NCR_READ_REG(sc, NCR_FIFO); + ibuf[i] = NCR_READ_REG(sc, NCR_FIFO); if (sc->sc_espstat2 & NCRFAS_STAT2_ISHUTTLE) { NCR_WRITE_REG(sc, NCR_FIFO, 0); - buf[i++] = NCR_READ_REG(sc, NCR_FIFO); + ibuf[i++] = NCR_READ_REG(sc, NCR_FIFO); NCR_READ_REG(sc, NCR_FIFO); @@ -1460,7 +1556,7 @@ ncr53c9x_rdfifo(struct ncr53c9x_softc *s } } else { for (i = 0; i < n; i++) - buf[i] = NCR_READ_REG(sc, NCR_FIFO); + ibuf[i] = NCR_READ_REG(sc, NCR_FIFO); } sc->sc_imlen += i; @@ -1515,7 +1611,6 @@ ncr53c9x_reselect(struct ncr53c9x_softc struct ncr53c9x_tinfo *ti; struct ncr53c9x_linfo *li; - if (sc->sc_rev == NCR_VARIANT_FAS366) { target = sc->sc_selid; } else { @@ -1651,7 +1746,8 @@ ncr53c9x_msgin(struct ncr53c9x_softc *sc */ if ((sc->sc_flags & NCR_DROP_MSGI) != 0) { NCRCMD(sc, NCRCMD_MSGOK); - printf("", sc->sc_imess[sc->sc_imlen]); + device_printf(sc->sc_dev, "", + sc->sc_imess[sc->sc_imlen]); return; } @@ -1757,8 +1853,9 @@ gotit: "rejected: target %d\n", ecb->ccb->ccb_h.target_id); - sc->sc_flags &= ~NCR_SYNCHNEGO; - ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE); + ti->flags &= ~T_SDTRSENT; + ti->curr.period = ti->goal.period = 0; + ti->curr.offset = ti->goal.offset = 0; ncr53c9x_setsync(sc, ti); break; @@ -1766,8 +1863,10 @@ gotit: device_printf(sc->sc_dev, "wide transfer " "rejected: target %d\n", ecb->ccb->ccb_h.target_id); - ti->flags &= ~(T_WIDE | T_WDTRSENT); - ti->width = 0; + + ti->flags &= ~T_WDTRSENT; + ti->curr.width = ti->goal.width = 0; + ncr53c9x_setsync(sc, ti); break; case SEND_INIT_DET_ERR: @@ -1822,69 +1921,66 @@ gotit: sc->sc_imess[3], sc->sc_imess[4])); if (sc->sc_imess[1] != 3) goto reject; - ti->period = sc->sc_imess[3]; - ti->offset = sc->sc_imess[4]; - ti->flags &= ~T_NEGOTIATE; + ti->curr.period = sc->sc_imess[3]; + ti->curr.offset = sc->sc_imess[4]; if (sc->sc_minsync == 0 || - ti->offset == 0 || - ti->period > 124) { + ti->curr.offset == 0 || + ti->curr.period > 124) { #if 0 #ifdef NCR53C9X_DEBUG xpt_print_path(ecb->ccb->ccb_h.path); printf("async mode\n"); #endif #endif - ti->flags &= ~T_SYNCMODE; - if ((sc->sc_flags&NCR_SYNCHNEGO) == 0) { + if ((ti->flags & T_SDTRSENT) == 0) { /* * target initiated negotiation */ - ti->offset = 0; + ti->curr.offset = 0; ncr53c9x_sched_msgout( SEND_SDTR); } } else { - int p; - - p = ncr53c9x_stp2cpb(sc, ti->period); - ti->period = ncr53c9x_cpb2stp(sc, p); - if ((sc->sc_flags&NCR_SYNCHNEGO) == 0) { + ti->curr.period = + ncr53c9x_cpb2stp(sc, + ncr53c9x_stp2cpb(sc, + ti->curr.period)); + if ((ti->flags & T_SDTRSENT) == 0) { /* * target initiated negotiation */ - if (ti->period < sc->sc_minsync) - ti->period = + if (ti->curr.period < + sc->sc_minsync) + ti->curr.period = sc->sc_minsync; - if (ti->offset > 15) - ti->offset = 15; - ti->flags &= ~T_SYNCMODE; + if (ti->curr.offset > + sc->sc_maxoffset) + ti->curr.offset = + sc->sc_maxoffset; ncr53c9x_sched_msgout( SEND_SDTR); - } else { - /* we are sync */ - ti->flags |= T_SYNCMODE; } } - sc->sc_flags &= ~NCR_SYNCHNEGO; + ti->flags &= ~T_SDTRSENT; + ti->goal.period = ti->curr.period; + ti->goal.offset = ti->curr.offset; ncr53c9x_setsync(sc, ti); break; case MSG_EXT_WDTR: -#ifdef NCR53C9X_DEBUG - device_printf(sc->sc_dev, "wide mode %d\n", - sc->sc_imess[3]); -#endif - if (sc->sc_imess[3] == 1) { - ti->cfg3 |= NCRFASCFG3_EWIDE; - ncr53c9x_setsync(sc, ti); - } else - ti->width = 0; - /* - * Device started width negotiation. - */ + NCR_MSGS(("wide mode %d ", sc->sc_imess[3])); + if (sc->sc_imess[3] == 1) + ti->curr.width = 1; + else + ti->curr.width = 0; if (!(ti->flags & T_WDTRSENT)) + /* + * target initiated negotiation + */ ncr53c9x_sched_msgout(SEND_WDTR); - ti->flags &= ~(T_WIDE | T_WDTRSENT); + ti->flags &= ~T_WDTRSENT; + ti->goal.width = ti->curr.width; + ncr53c9x_setsync(sc, ti); break; default: xpt_print_path(ecb->ccb->ccb_h.path); @@ -1943,8 +2039,10 @@ gotit: } /* if we have more messages to send set ATN */ - if (sc->sc_msgpriq) + if (sc->sc_msgpriq) { NCRCMD(sc, NCRCMD_SETATN); + sc->sc_flags |= NCR_ATN; + } /* Ack last message byte */ NCRCMD(sc, NCRCMD_MSGOK); @@ -1954,7 +2052,6 @@ gotit: sc->sc_imlen = 0; } - /* * Send the highest priority, scheduled message */ @@ -2006,13 +2103,9 @@ ncr53c9x_msgout(struct ncr53c9x_softc *s sc->sc_omess[0] = MSG_EXTENDED; sc->sc_omess[1] = MSG_EXT_SDTR_LEN; sc->sc_omess[2] = MSG_EXT_SDTR; - sc->sc_omess[3] = ti->period; - sc->sc_omess[4] = ti->offset; + sc->sc_omess[3] = ti->goal.period; + sc->sc_omess[4] = ti->goal.offset; sc->sc_omlen = 5; - if ((sc->sc_flags & NCR_SYNCHNEGO) == 0) { - ti->flags |= T_SYNCMODE; - ncr53c9x_setsync(sc, ti); - } break; case SEND_WDTR: ecb = sc->sc_nexus; @@ -2020,7 +2113,7 @@ ncr53c9x_msgout(struct ncr53c9x_softc *s sc->sc_omess[0] = MSG_EXTENDED; sc->sc_omess[1] = MSG_EXT_WDTR_LEN; sc->sc_omess[2] = MSG_EXT_WDTR; - sc->sc_omess[3] = ti->width; + sc->sc_omess[3] = ti->goal.width; sc->sc_omlen = 4; break; case SEND_IDENTIFY: @@ -2047,10 +2140,9 @@ ncr53c9x_msgout(struct ncr53c9x_softc *s sc->sc_omess[0] = MSG_BUS_DEV_RESET; ecb = sc->sc_nexus; ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id]; - ti->flags &= ~T_SYNCMODE; - if ((ti->flags & T_SYNCHOFF) == 0) - /* We can re-start sync negotiation */ - ti->flags |= T_NEGOTIATE; + ti->curr.period = 0; + ti->curr.offset = 0; + ti->curr.width = 0; break; case SEND_PARITY_ERROR: sc->sc_omess[0] = MSG_PARITY_ERROR; @@ -2174,7 +2266,7 @@ again: goto out; } #if 0 -/*XXX*/ printf("sc_dev, "\n", sc->sc_espintr, sc->sc_espstat, sc->sc_espstep); #endif @@ -2228,8 +2320,7 @@ again: NCRCMD(sc, NCRCMD_FLUSH); DELAY(1); } - ncr53c9x_init(sc, 1); /* Restart everything */ - goto out; + goto reset; } } sc->sc_flags &= ~NCR_EXPECT_ILLCMD; @@ -2242,11 +2333,9 @@ again: * change is expected. */ if (NCRDMA_ISACTIVE(sc)) { - int r = NCRDMA_INTR(sc); - if (r == -1) { + if (NCRDMA_INTR(sc) == -1) { device_printf(sc->sc_dev, "DMA error; resetting\n"); - ncr53c9x_init(sc, 1); - goto out; + goto reset; } /* If DMA active here, then go back to work... */ if (NCRDMA_ISACTIVE(sc)) @@ -2300,7 +2389,11 @@ again: sc->sc_espstep, sc->sc_prevphase, ecb ? ecb->dleft : -1); +#if 0 panic("esp: unrecoverable DMA error"); +#else + goto reset; +#endif } } } @@ -2360,15 +2453,23 @@ again: goto finish; } case NCR_CONNECTED: - if ((sc->sc_flags & NCR_SYNCHNEGO) != 0) { -#ifdef NCR53C9X_DEBUG - if (ecb != NULL) - xpt_print_path(ecb->ccb->ccb_h.path); - printf("sync nego not completed!\n"); -#endif + if (ecb != NULL) { ti = &sc->sc_tinfo[ecb->ccb->ccb_h.target_id]; - sc->sc_flags &= ~NCR_SYNCHNEGO; - ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE); + if ((ti->flags & T_SDTRSENT) != 0) { + xpt_print_path(ecb->ccb->ccb_h.path); + printf("sync nego not completed!\n"); + ti->flags &= ~T_SDTRSENT; + ti->curr.period = ti->goal.period = 0; + ti->curr.offset = ti->goal.offset = 0; + ncr53c9x_setsync(sc, ti); + } + if ((ti->flags & T_WDTRSENT) != 0) { + xpt_print_path(ecb->ccb->ccb_h.path); + printf("wide nego not completed!\n"); + ti->flags &= ~T_WDTRSENT; + ti->curr.width = ti->goal.width = 0; + ncr53c9x_setsync(sc, ti); + } } /* it may be OK to disconnect */ @@ -2405,6 +2506,10 @@ again: ecb->ccb->ccb_h.timeout_ch); ncr53c9x_sense(sc, ecb); goto out; + } else if (ecb != NULL && + (ecb->flags & ECB_RESET) != 0) { + ecb->ccb->ccb_h.status = CAM_REQ_CMP; + goto finish; } ecb->ccb->ccb_h.status = CAM_CMD_TIMEOUT; @@ -2432,8 +2537,7 @@ again: */ device_printf(sc->sc_dev, "unhandled reselect continuation, " "state %d, intr %02x\n", sc->sc_state, sc->sc_espintr); - ncr53c9x_init(sc, 1); - goto out; + goto reset; break; case NCR_IDENTIFIED: @@ -2450,8 +2554,7 @@ again: while (i-- > 0) printf("[%d] ", NCR_READ_REG(sc, NCR_FIFO)); - ncr53c9x_init(sc, 1); - goto out; + goto reset; } else goto msgin; @@ -2483,8 +2586,7 @@ again: */ device_printf(sc->sc_dev, "target didn't " "identify\n"); - ncr53c9x_init(sc, 1); - goto out; + goto reset; } /* * The C90 only inhibits FIFO writes until reselection @@ -2525,8 +2627,7 @@ again: sc->sc_espstat, sc->sc_espstep, sc->sc_prevphase); - ncr53c9x_init(sc, 1); - goto out; + goto reset; } sc->sc_selid = sc->sc_imess[0]; NCR_INTS(("selid=%02x ", sc->sc_selid)); @@ -2540,8 +2641,7 @@ again: device_printf(sc->sc_dev, "identify failed, " "state %d, intr %02x\n", sc->sc_state, sc->sc_espintr); - ncr53c9x_init(sc, 1); - goto out; + goto reset; } goto shortcut; /* ie. next phase expected soon */ } @@ -2580,34 +2680,49 @@ again: NCRCMD(sc, NCRCMD_RSTATN); break; case 1: - if ((ti->flags & T_NEGOTIATE) == 0 && + if (ti->curr.period == ti->goal.period && + ti->curr.offset == ti->goal.offset && + ti->curr.width == ti->goal.width && ecb->tag[0] == 0) { - device_printf(sc->sc_dev, "step 1 & " - "!NEG\n"); + device_printf(sc->sc_dev, "step 1 " + "and no negotiation to perform " + "or tag to send\n"); goto reset; } if (sc->sc_phase != MESSAGE_OUT_PHASE) { - device_printf(sc->sc_dev, "!MSGOUT\n"); + device_printf(sc->sc_dev, "step 1 " + "but not in MESSAGE_OUT_PHASE\n"); goto reset; } - if (ti->flags & T_WIDE) { - ti->flags |= T_WDTRSENT; - ncr53c9x_sched_msgout(SEND_WDTR); + sc->sc_prevphase = MESSAGE_OUT_PHASE; /* XXXX */ + if (ecb->flags & ECB_RESET) { + /* + * A DEVICE RESET was scheduled and + * ATNS used. As SEND_DEV_RESET has + * the highest priority, the target + * will reset and disconnect and we + * will end up in ncr53c9x_done w/o + * negotiating or sending a TAG. So + * we just break here in order to + * avoid warnings about negotiation + * not having completed. + */ + ncr53c9x_sched_msgout(SEND_DEV_RESET); + break; } - if (ti->flags & T_NEGOTIATE) { - /* Start negotiating */ - sc->sc_flags |= NCR_SYNCHNEGO; - if (ecb->tag[0]) - ncr53c9x_sched_msgout( - SEND_TAG|SEND_SDTR); - else - ncr53c9x_sched_msgout( - SEND_SDTR); - } else { + if (ti->curr.width != ti->goal.width) { + ti->flags |= T_WDTRSENT | T_SDTRSENT; + ncr53c9x_sched_msgout(SEND_WDTR | + SEND_SDTR); + } + if (ti->curr.period != ti->goal.period || + ti->curr.offset != ti->goal.offset) { + ti->flags |= T_SDTRSENT; + ncr53c9x_sched_msgout(SEND_SDTR); + } + if (ecb->tag[0] != 0) /* Could not do ATN3 so send TAG */ ncr53c9x_sched_msgout(SEND_TAG); - } - sc->sc_prevphase = MESSAGE_OUT_PHASE; /* XXXX */ break; case 3: /* @@ -2627,12 +2742,9 @@ again: /* Hope for the best.. */ break; } - printf("(%s:%d:%d): selection failed;" - " %d left in FIFO " + xpt_print_path(ecb->ccb->ccb_h.path); + printf("selection failed; %d left in FIFO " "[intr %x, stat %x, step %d]\n", - device_get_nameunit(sc->sc_dev), - ecb->ccb->ccb_h.target_id, - ecb->ccb->ccb_h.target_lun, NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF, sc->sc_espintr, sc->sc_espstat, @@ -2646,17 +2758,15 @@ again: break; case 4: if (sc->sc_features & NCR_F_DMASELECT && - sc->sc_cmdlen != 0) - printf("(%s:%d:%d): select; " - "%lu left in DMA buffer " + sc->sc_cmdlen != 0) { + xpt_print_path(ecb->ccb->ccb_h.path); + printf("select; %lu left in DMA buffer " "[intr %x, stat %x, step %d]\n", - device_get_nameunit(sc->sc_dev), - ecb->ccb->ccb_h.target_id, - ecb->ccb->ccb_h.target_lun, (u_long)sc->sc_cmdlen, sc->sc_espintr, sc->sc_espstat, sc->sc_espstep); + } /* So far, everything went fine */ break; } @@ -2785,6 +2895,15 @@ msgin: NCRCMD(sc, NCRCMD_FLUSH); /* DELAY(1);*/ } + /* + * If we have more messages to send, e.g. WDTR or SDTR + * after we've sent a TAG, set ATN so we'll go back to + * MESSAGE_OUT_PHASE. + */ + if (sc->sc_msgpriq) { + NCRCMD(sc, NCRCMD_SETATN); + sc->sc_flags |= NCR_ATN; + } if (sc->sc_features & NCR_F_DMASELECT) { /* setup DMA transfer for command */ size = ecb->clen; @@ -2977,13 +3096,12 @@ ncr53c9x_timeout(void *arg) /* Disable sync mode if stuck in a data phase */ if (ecb == sc->sc_nexus && - (ti->flags & T_SYNCMODE) != 0 && + ti->curr.offset != 0 && (sc->sc_phase & (MSGI|CDI)) == 0) { /* XXX ASYNC CALLBACK! */ + ti->goal.offset = 0; xpt_print_path(ccb->ccb_h.path); printf("sync negotiation disabled\n"); - sc->sc_cfflags |= - (1 << ((ccb->ccb_h.target_id & 7) + 8)); } } Index: ncr53c9xreg.h =================================================================== RCS file: /mnt/futile/usr/data/bsd/cvs/fbsd/src/sys/dev/esp/ncr53c9xreg.h,v retrieving revision 1.5 diff -u -p -r1.5 ncr53c9xreg.h --- ncr53c9xreg.h 19 May 2005 14:51:10 -0000 1.5 +++ ncr53c9xreg.h 16 Jul 2006 20:52:16 -0000 @@ -84,8 +84,8 @@ #define NCRSTAT_PHASE 0x07 /* Phase bits */ #define NCR_SELID 0x04 /* WO - Select/Reselect Bus ID */ -#define NCR_BUSID_HME 0x10 /* XXX HME reselect ID */ -#define NCR_BUSID_HME32 0x40 /* XXX HME to select more than 16 */ +#define NCR_BUSID_HMEXC32 0x40 /* HME xfer counter is 32bit */ +#define NCR_BUSID_HMEENCID 0x10 /* HME encode reselection ID */ #define NCR_INTR 0x05 /* RO - Interrupt */ #define NCRINTR_SBR 0x80 /* SCSI Bus Reset */ Index: ncr53c9xvar.h =================================================================== RCS file: /mnt/futile/usr/data/bsd/cvs/fbsd/src/sys/dev/esp/ncr53c9xvar.h,v retrieving revision 1.8 diff -u -p -r1.8 ncr53c9xvar.h --- ncr53c9xvar.h 4 Dec 2005 10:06:03 -0000 1.8 +++ ncr53c9xvar.h 22 Jul 2006 00:50:35 -0000 @@ -110,9 +110,9 @@ * ECB. Holds additional information for each SCSI command Comments: We * need a separate scsi command block because we may need to overwrite it * with a request sense command. Basicly, we refrain from fiddling with - * the scsipi_xfer struct (except do the expected updating of return values). - * We'll generally update: xs->{flags,resid,error,sense,status} and - * occasionally xs->retries. + * the ccb union (except do the expected updating of return values). + * We'll generally update: ccb->ccb_h.status and ccb->csio.{resid, + * scsi_status,sense_data}. */ struct ncr53c9x_ecb { /* These fields are preserved between alloc and free */ @@ -180,6 +180,12 @@ struct ncr53c9x_linfo { struct ncr53c9x_ecb *queued[NCR_TAG_DEPTH]; }; +struct ncr53c9x_xinfo { + u_char period; + u_char offset; + u_char width; +}; + struct ncr53c9x_tinfo { int cmds; /* # of commands processed */ int dconns; /* # of disconnects */ @@ -187,18 +193,13 @@ struct ncr53c9x_tinfo { int perrs; /* # of parity errors */ int senses; /* # of request sense commands sent */ u_char flags; -#define T_NEGOTIATE 0x02 /* (Re)Negotiate synchronous options */ -#define T_SYNCMODE 0x08 /* SYNC mode has been negotiated */ -#define T_SYNCHOFF 0x10 /* SYNC mode for is permanently off */ -#define T_RSELECTOFF 0x20 /* RE-SELECT mode is off */ -#define T_TAG 0x40 /* Turn on TAG QUEUEs */ -#define T_WIDE 0x80 /* Negotiate wide options */ -#define T_WDTRSENT 0x04 /* WDTR message has been sent to */ - u_char period; /* Period suggestion */ - u_char offset; /* Offset suggestion */ - u_char cfg3; /* per target config 3 */ - u_char nextag; /* Next available tag */ - u_char width; /* width suggesion */ +#define T_SYNCHOFF 0x01 /* SYNC mode for is permanently off */ +#define T_RSELECTOFF 0x02 /* RE-SELECT mode is off */ +#define T_TAG 0x04 /* Turn on TAG QUEUEs */ +#define T_SDTRSENT 0x08 /* SDTR message has been sent to */ +#define T_WDTRSENT 0x10 /* WDTR message has been sent to */ + struct ncr53c9x_xinfo curr; + struct ncr53c9x_xinfo goal; LIST_HEAD(lun_list, ncr53c9x_linfo) luns; struct ncr53c9x_linfo *lun[NCR_NLUN]; /* For speedy lookups */ }; @@ -353,7 +354,6 @@ struct ncr53c9x_softc { int sc_features; /* Chip features */ int sc_minsync; /* Minimum sync period / 4 */ int sc_maxxfer; /* Maximum transfer size */ - int sc_maxsync; /* Maximum sync period */ int sc_maxoffset; /* Maximum offset */ int sc_maxwidth; /* Maximum width */ int sc_extended_geom; /* Should we return extended geometry */ @@ -378,12 +378,10 @@ struct ncr53c9x_softc { /* values for sc_flags */ #define NCR_DROP_MSGI 0x01 /* Discard all msgs (parity err detected) */ #define NCR_ABORTING 0x02 /* Bailing out */ -#define NCR_DOINGDMA 0x04 /* The FIFO data path is active! */ -#define NCR_SYNCHNEGO 0x08 /* Synch negotiation in progress. */ -#define NCR_ICCS 0x10 /* Expect status phase results */ -#define NCR_WAITI 0x20 /* Waiting for non-DMA data to arrive */ -#define NCR_ATN 0x40 /* ATN asserted */ -#define NCR_EXPECT_ILLCMD 0x80 /* Expect Illegal Command Interrupt */ +#define NCR_ICCS 0x04 /* Expect status phase results */ +#define NCR_WAITI 0x08 /* Waiting for non-DMA data to arrive */ +#define NCR_ATN 0x10 /* ATN asserted */ +#define NCR_EXPECT_ILLCMD 0x20 /* Expect Illegal Command Interrupt */ /* values for sc_features */ #define NCR_F_HASCFG3 0x01 /* chip has CFG3 register */ @@ -398,9 +396,9 @@ struct ncr53c9x_softc { #define SEND_REJECT 0x0008 #define SEND_IDENTIFY 0x0010 #define SEND_ABORT 0x0020 -#define SEND_WDTR 0x0040 -#define SEND_SDTR 0x0080 -#define SEND_TAG 0x0100 +#define SEND_TAG 0x0040 +#define SEND_WDTR 0x0080 +#define SEND_SDTR 0x0100 /* SCSI Status codes */ #define ST_MASK 0x3e /* bit 0,6,7 is reserved */ @@ -453,6 +451,7 @@ struct ncr53c9x_softc { #define NCRDMA_SETUP(sc, addr, len, datain, dmasize) \ (*(sc)->sc_glue->gl_dma_setup)((sc), (addr), (len), (datain), (dmasize)) #define NCRDMA_GO(sc) (*(sc)->sc_glue->gl_dma_go)((sc)) +#define NCRDMA_STOP(sc) (*(sc)->sc_glue->gl_dma_stop)((sc)) #define NCRDMA_ISACTIVE(sc) (*(sc)->sc_glue->gl_dma_isactive)((sc)) /*