Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/dev/ic/siop.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/dev/ic/siop.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.40.2.8 retrieving revision 1.40.2.9 diff -u -p -r1.40.2.8 -r1.40.2.9 --- src/sys/dev/ic/siop.c 2002/04/17 00:05:50 1.40.2.8 +++ src/sys/dev/ic/siop.c 2002/06/20 03:44:59 1.40.2.9 @@ -1,4 +1,4 @@ -/* $NetBSD: siop.c,v 1.40.2.8 2002/04/17 00:05:50 nathanw Exp $ */ +/* $NetBSD: siop.c,v 1.40.2.9 2002/06/20 03:44:59 nathanw Exp $ */ /* * Copyright (c) 2000 Manuel Bouyer. @@ -13,7 +13,7 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by Manuel Bouyer + * This product includes software developed by Manuel Bouyer. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * @@ -33,7 +33,7 @@ /* SYM53c7/8xx PCI-SCSI I/O Processors driver */ #include -__KERNEL_RCSID(0, "$NetBSD: siop.c,v 1.40.2.8 2002/04/17 00:05:50 nathanw Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siop.c,v 1.40.2.9 2002/06/20 03:44:59 nathanw Exp $"); #include #include @@ -56,8 +56,10 @@ __KERNEL_RCSID(0, "$NetBSD: siop.c,v 1.4 #include #include -#include #include +#include + +#include "opt_siop.h" #ifndef DEBUG #undef DEBUG @@ -94,7 +96,8 @@ void siop_dump_script __P((struct siop_s void siop_morecbd __P((struct siop_softc *)); struct siop_lunsw *siop_get_lunsw __P((struct siop_softc *)); void siop_add_reselsw __P((struct siop_softc *, int)); -void siop_update_scntl3 __P((struct siop_softc *, struct siop_target *)); +void siop_update_scntl3 __P((struct siop_softc *, + struct siop_common_target *)); #ifdef SIOP_STATS static int siop_stat_intr = 0; @@ -116,8 +119,8 @@ siop_script_sync(sc, ops) struct siop_softc *sc; int ops; { - if ((sc->features & SF_CHIP_RAM) == 0) - bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, 0, + if ((sc->sc_c.features & SF_CHIP_RAM) == 0) + bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_c.sc_scriptdma, 0, PAGE_SIZE, ops); } @@ -127,10 +130,11 @@ siop_script_read(sc, offset) struct siop_softc *sc; u_int offset; { - if (sc->features & SF_CHIP_RAM) { - return bus_space_read_4(sc->sc_ramt, sc->sc_ramh, offset * 4); + if (sc->sc_c.features & SF_CHIP_RAM) { + return bus_space_read_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh, + offset * 4); } else { - return le32toh(sc->sc_script[offset]); + return le32toh(sc->sc_c.sc_script[offset]); } } @@ -142,10 +146,11 @@ siop_script_write(sc, offset, val) u_int offset; u_int32_t val; { - if (sc->features & SF_CHIP_RAM) { - bus_space_write_4(sc->sc_ramt, sc->sc_ramh, offset * 4, val); + if (sc->sc_c.features & SF_CHIP_RAM) { + bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh, + offset * 4, val); } else { - sc->sc_script[offset] = htole32(val); + sc->sc_c.sc_script[offset] = htole32(val); } } @@ -153,93 +158,24 @@ void siop_attach(sc) struct siop_softc *sc; { - int error, i; - bus_dma_segment_t seg; - int rseg; + if (siop_common_attach(&sc->sc_c) != 0) + return; - /* - * Allocate DMA-safe memory for the script and map it. - */ - if ((sc->features & SF_CHIP_RAM) == 0) { - error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, - PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT); - if (error) { - printf("%s: unable to allocate script DMA memory, " - "error = %d\n", sc->sc_dev.dv_xname, error); - return; - } - error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, PAGE_SIZE, - (caddr_t *)&sc->sc_script, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); - if (error) { - printf("%s: unable to map script DMA memory, " - "error = %d\n", sc->sc_dev.dv_xname, error); - return; - } - error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, - PAGE_SIZE, 0, BUS_DMA_NOWAIT, &sc->sc_scriptdma); - if (error) { - printf("%s: unable to create script DMA map, " - "error = %d\n", sc->sc_dev.dv_xname, error); - return; - } - error = bus_dmamap_load(sc->sc_dmat, sc->sc_scriptdma, - sc->sc_script, PAGE_SIZE, NULL, BUS_DMA_NOWAIT); - if (error) { - printf("%s: unable to load script DMA map, " - "error = %d\n", sc->sc_dev.dv_xname, error); - return; - } - sc->sc_scriptaddr = sc->sc_scriptdma->dm_segs[0].ds_addr; - sc->ram_size = PAGE_SIZE; - } TAILQ_INIT(&sc->free_list); TAILQ_INIT(&sc->cmds); TAILQ_INIT(&sc->lunsw_list); sc->sc_currschedslot = 0; #ifdef SIOP_DEBUG printf("%s: script size = %d, PHY addr=0x%x, VIRT=%p\n", - sc->sc_dev.dv_xname, (int)sizeof(siop_script), - (u_int32_t)sc->sc_scriptaddr, sc->sc_script); + sc->sc_c.sc_dev.dv_xname, (int)sizeof(siop_script), + (u_int32_t)sc->sc_c.sc_scriptaddr, sc->sc_c.sc_script); #endif - sc->sc_adapt.adapt_dev = &sc->sc_dev; - sc->sc_adapt.adapt_nchannels = 1; - sc->sc_adapt.adapt_openings = 0; - sc->sc_adapt.adapt_max_periph = SIOP_NTAG - 1; - sc->sc_adapt.adapt_ioctl = siop_ioctl; - sc->sc_adapt.adapt_minphys = minphys; - sc->sc_adapt.adapt_request = siop_scsipi_request; - - memset(&sc->sc_chan, 0, sizeof(sc->sc_chan)); - sc->sc_chan.chan_adapter = &sc->sc_adapt; - sc->sc_chan.chan_bustype = &scsi_bustype; - sc->sc_chan.chan_channel = 0; - sc->sc_chan.chan_flags = SCSIPI_CHAN_CANGROW; - sc->sc_chan.chan_ntargets = (sc->features & SF_BUS_WIDE) ? 16 : 8; - sc->sc_chan.chan_nluns = 8; - sc->sc_chan.chan_id = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SCID); - if (sc->sc_chan.chan_id == 0 || - sc->sc_chan.chan_id >= sc->sc_chan.chan_ntargets) - sc->sc_chan.chan_id = SIOP_DEFAULT_TARGET; - - for (i = 0; i < 16; i++) - sc->targets[i] = NULL; - - /* find min/max sync period for this chip */ - sc->maxsync = 0; - sc->minsync = 255; - for (i = 0; i < sizeof(scf_period) / sizeof(scf_period[0]); i++) { - if (sc->clock_period != scf_period[i].clock) - continue; - if (sc->maxsync < scf_period[i].period) - sc->maxsync = scf_period[i].period; - if (sc->minsync > scf_period[i].period) - sc->minsync = scf_period[i].period; - } - if (sc->maxsync == 255 || sc->minsync == 0) - panic("siop: can't find my sync parameters\n"); + sc->sc_c.sc_adapt.adapt_max_periph = SIOP_NTAG - 1; + sc->sc_c.sc_adapt.adapt_request = siop_scsipi_request; + /* Do a bus reset, so that devices fall back to narrow/async */ - siop_resetbus(sc); + siop_resetbus(&sc->sc_c); /* * siop_reset() will reset the chip, thus clearing pending interrupts */ @@ -248,7 +184,7 @@ siop_attach(sc) siop_dump_script(sc); #endif - config_found((struct device*)sc, &sc->sc_chan, scsiprint); + config_found((struct device*)sc, &sc->sc_c.sc_chan, scsiprint); } void @@ -258,81 +194,114 @@ siop_reset(sc) int i, j; struct siop_lunsw *lunsw; - siop_common_reset(sc); + siop_common_reset(&sc->sc_c); /* copy and patch the script */ - if (sc->features & SF_CHIP_RAM) { - bus_space_write_region_4(sc->sc_ramt, sc->sc_ramh, 0, + if (sc->sc_c.features & SF_CHIP_RAM) { + bus_space_write_region_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh, 0, siop_script, sizeof(siop_script) / sizeof(siop_script[0])); for (j = 0; j < (sizeof(E_abs_msgin_Used) / sizeof(E_abs_msgin_Used[0])); j++) { - bus_space_write_4(sc->sc_ramt, sc->sc_ramh, + bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh, E_abs_msgin_Used[j] * 4, - sc->sc_scriptaddr + Ent_msgin_space); + sc->sc_c.sc_scriptaddr + Ent_msgin_space); + } + if (sc->sc_c.features & SF_CHIP_LED0) { + bus_space_write_region_4(sc->sc_c.sc_ramt, + sc->sc_c.sc_ramh, + Ent_led_on1, siop_led_on, + sizeof(siop_led_on) / sizeof(siop_led_on[0])); + bus_space_write_region_4(sc->sc_c.sc_ramt, + sc->sc_c.sc_ramh, + Ent_led_on2, siop_led_on, + sizeof(siop_led_on) / sizeof(siop_led_on[0])); + bus_space_write_region_4(sc->sc_c.sc_ramt, + sc->sc_c.sc_ramh, + Ent_led_off, siop_led_off, + sizeof(siop_led_off) / sizeof(siop_led_off[0])); } } else { for (j = 0; j < (sizeof(siop_script) / sizeof(siop_script[0])); j++) { - sc->sc_script[j] = htole32(siop_script[j]); + sc->sc_c.sc_script[j] = htole32(siop_script[j]); } for (j = 0; j < (sizeof(E_abs_msgin_Used) / sizeof(E_abs_msgin_Used[0])); j++) { - sc->sc_script[E_abs_msgin_Used[j]] = - htole32(sc->sc_scriptaddr + Ent_msgin_space); + sc->sc_c.sc_script[E_abs_msgin_Used[j]] = + htole32(sc->sc_c.sc_scriptaddr + Ent_msgin_space); + } + if (sc->sc_c.features & SF_CHIP_LED0) { + for (j = 0; j < (sizeof(siop_led_on) / + sizeof(siop_led_on[0])); j++) + sc->sc_c.sc_script[ + Ent_led_on1 / sizeof(siop_led_on[0]) + j + ] = htole32(siop_led_on[j]); + for (j = 0; j < (sizeof(siop_led_on) / + sizeof(siop_led_on[0])); j++) + sc->sc_c.sc_script[ + Ent_led_on2 / sizeof(siop_led_on[0]) + j + ] = htole32(siop_led_on[j]); + for (j = 0; j < (sizeof(siop_led_off) / + sizeof(siop_led_off[0])); j++) + sc->sc_c.sc_script[ + Ent_led_off / sizeof(siop_led_off[0]) + j + ] = htole32(siop_led_off[j]); } } sc->script_free_lo = sizeof(siop_script) / sizeof(siop_script[0]); - sc->script_free_hi = sc->ram_size / 4; + sc->script_free_hi = sc->sc_c.ram_size / 4; /* free used and unused lun switches */ while((lunsw = TAILQ_FIRST(&sc->lunsw_list)) != NULL) { #ifdef SIOP_DEBUG printf("%s: free lunsw at offset %d\n", - sc->sc_dev.dv_xname, lunsw->lunsw_off); + sc->sc_c.sc_dev.dv_xname, lunsw->lunsw_off); #endif TAILQ_REMOVE(&sc->lunsw_list, lunsw, next); free(lunsw, M_DEVBUF); } TAILQ_INIT(&sc->lunsw_list); /* restore reselect switch */ - for (i = 0; i < sc->sc_chan.chan_ntargets; i++) { - if (sc->targets[i] == NULL) + for (i = 0; i < sc->sc_c.sc_chan.chan_ntargets; i++) { + struct siop_target *target; + if (sc->sc_c.targets[i] == NULL) continue; #ifdef SIOP_DEBUG printf("%s: restore sw for target %d\n", - sc->sc_dev.dv_xname, i); + sc->sc_c.sc_dev.dv_xname, i); #endif - free(sc->targets[i]->lunsw, M_DEVBUF); - sc->targets[i]->lunsw = siop_get_lunsw(sc); - if (sc->targets[i]->lunsw == NULL) { + target = (struct siop_target *)sc->sc_c.targets[i]; + free(target->lunsw, M_DEVBUF); + target->lunsw = siop_get_lunsw(sc); + if (target->lunsw == NULL) { printf("%s: can't alloc lunsw for target %d\n", - sc->sc_dev.dv_xname, i); + sc->sc_c.sc_dev.dv_xname, i); break; } siop_add_reselsw(sc, i); } /* start script */ - if ((sc->features & SF_CHIP_RAM) == 0) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, 0, PAGE_SIZE, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + if ((sc->sc_c.features & SF_CHIP_RAM) == 0) { + bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_c.sc_scriptdma, 0, + PAGE_SIZE, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } - bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, - sc->sc_scriptaddr + Ent_reselect); + bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP, + sc->sc_c.sc_scriptaddr + Ent_reselect); } #if 0 #define CALL_SCRIPT(ent) do {\ printf ("start script DSA 0x%lx DSP 0x%lx\n", \ - siop_cmd->dsa, \ - sc->sc_scriptaddr + ent); \ -bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->sc_scriptaddr + ent); \ + siop_cmd->cmd_c.dsa, \ + sc->sc_c.sc_scriptaddr + ent); \ +bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP, sc->sc_c.sc_scriptaddr + ent); \ } while (0) #else #define CALL_SCRIPT(ent) do {\ -bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->sc_scriptaddr + ent); \ +bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP, sc->sc_c.sc_scriptaddr + ent); \ } while (0) #endif @@ -354,16 +323,23 @@ siop_intr(v) int freetarget = 0; int restart = 0; - istat = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_ISTAT); + istat = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_ISTAT); if ((istat & (ISTAT_INTF | ISTAT_DIP | ISTAT_SIP)) == 0) return 0; INCSTAT(siop_stat_intr); if (istat & ISTAT_INTF) { printf("INTRF\n"); - bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_ISTAT, ISTAT_INTF); + bus_space_write_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_ISTAT, ISTAT_INTF); + } + if ((istat &(ISTAT_DIP | ISTAT_SIP | ISTAT_ABRT)) == + (ISTAT_DIP | ISTAT_ABRT)) { + /* clear abort */ + bus_space_write_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_ISTAT, 0); } /* use DSA to find the current siop_cmd */ - dsa = bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA); + dsa = bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA); for (cbdp = TAILQ_FIRST(&sc->cmds); cbdp != NULL; cbdp = TAILQ_NEXT(cbdp, next)) { if (dsa >= cbdp->xferdma->dm_segs[0].ds_addr && @@ -379,17 +355,17 @@ siop_intr(v) siop_cmd = NULL; } if (siop_cmd) { - xs = siop_cmd->xs; - siop_target = siop_cmd->siop_target; - target = siop_cmd->xs->xs_periph->periph_target; - lun = siop_cmd->xs->xs_periph->periph_lun; - tag = siop_cmd->tag; + xs = siop_cmd->cmd_c.xs; + siop_target = (struct siop_target *)siop_cmd->cmd_c.siop_target; + target = siop_cmd->cmd_c.xs->xs_periph->periph_target; + lun = siop_cmd->cmd_c.xs->xs_periph->periph_lun; + tag = siop_cmd->cmd_c.tag; siop_lun = siop_target->siop_lun[lun]; #ifdef DIAGNOSTIC - if (siop_cmd->status != CMDST_ACTIVE) { + if (siop_cmd->cmd_c.status != CMDST_ACTIVE) { printf("siop_cmd (lun %d) for DSA 0x%x " "not active (%d)\n", lun, (u_int)dsa, - siop_cmd->status); + siop_cmd->cmd_c.status); xs = NULL; siop_target = NULL; target = -1; @@ -412,43 +388,54 @@ siop_intr(v) siop_lun = NULL; } if (istat & ISTAT_DIP) { - dstat = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_DSTAT); + dstat = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_DSTAT); + if (dstat & DSTAT_ABRT) { + /* was probably generated by a bus reset IOCTL */ + if ((dstat & DSTAT_DFE) == 0) + siop_clearfifo(&sc->sc_c); + goto reset; + } if (dstat & DSTAT_SSI) { printf("single step dsp 0x%08x dsa 0x08%x\n", - (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) - - sc->sc_scriptaddr), - bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA)); + (int)(bus_space_read_4(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, SIOP_DSP) - + sc->sc_c.sc_scriptaddr), + bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_DSA)); if ((dstat & ~(DSTAT_DFE | DSTAT_SSI)) == 0 && (istat & ISTAT_SIP) == 0) { - bus_space_write_1(sc->sc_rt, sc->sc_rh, - SIOP_DCNTL, bus_space_read_1(sc->sc_rt, - sc->sc_rh, SIOP_DCNTL) | DCNTL_STD); + bus_space_write_1(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, SIOP_DCNTL, + bus_space_read_1(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, SIOP_DCNTL) | DCNTL_STD); } return 1; } + if (dstat & ~(DSTAT_SIR | DSTAT_DFE | DSTAT_SSI)) { printf("DMA IRQ:"); if (dstat & DSTAT_IID) printf(" Illegal instruction"); - if (dstat & DSTAT_ABRT) - printf(" abort"); if (dstat & DSTAT_BF) printf(" bus fault"); if (dstat & DSTAT_MDPE) printf(" parity"); if (dstat & DSTAT_DFE) printf(" dma fifo empty"); + else + siop_clearfifo(&sc->sc_c); printf(", DSP=0x%x DSA=0x%x: ", - (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) - - sc->sc_scriptaddr), - bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA)); + (int)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_DSP) - sc->sc_c.sc_scriptaddr), + bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA)); if (siop_cmd) printf("last msg_in=0x%x status=0x%x\n", - siop_cmd->siop_tables.msg_in[0], - le32toh(siop_cmd->siop_tables.status)); + siop_cmd->cmd_tables->msg_in[0], + le32toh(siop_cmd->cmd_tables->status)); else printf("%s: current DSA invalid\n", - sc->sc_dev.dv_xname); + sc->sc_c.sc_dev.dv_xname); need_reset = 1; } } @@ -459,15 +446,19 @@ siop_intr(v) * Can't read sist0 & sist1 independantly, or we have to * insert delay */ - sist = bus_space_read_2(sc->sc_rt, sc->sc_rh, SIOP_SIST0); - sstat1 = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SSTAT1); + sist = bus_space_read_2(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_SIST0); + sstat1 = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_SSTAT1); #ifdef SIOP_DEBUG_INTR printf("scsi interrupt, sist=0x%x sstat1=0x%x " "DSA=0x%x DSP=0x%lx\n", sist, - bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SSTAT1), - bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA), - (u_long)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) - - sc->sc_scriptaddr)); + bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_SSTAT1), + bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA), + (u_long)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_DSP) - + sc->sc_c.sc_scriptaddr)); #endif if (sist & SIST0_RST) { siop_handle_reset(sc); @@ -478,23 +469,24 @@ siop_intr(v) if (siop_cmd) scsipi_printaddr(xs->xs_periph); else - printf("%s:", sc->sc_dev.dv_xname); + printf("%s:", sc->sc_c.sc_dev.dv_xname); printf("scsi gross error\n"); goto reset; } if ((sist & SIST0_MA) && need_reset == 0) { if (siop_cmd) { int scratcha0; - dstat = bus_space_read_1(sc->sc_rt, sc->sc_rh, - SIOP_DSTAT); + dstat = bus_space_read_1(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, SIOP_DSTAT); /* * first restore DSA, in case we were in a S/G * operation. */ - bus_space_write_4(sc->sc_rt, sc->sc_rh, - SIOP_DSA, siop_cmd->dsa); - scratcha0 = bus_space_read_1(sc->sc_rt, - sc->sc_rh, SIOP_SCRATCHA); + bus_space_write_4(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, + SIOP_DSA, siop_cmd->cmd_c.dsa); + scratcha0 = bus_space_read_1(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, SIOP_SCRATCHA); switch (sstat1 & SSTAT1_PHASE_MASK) { case SSTAT1_PHASE_STATUS: /* @@ -505,7 +497,7 @@ siop_intr(v) */ INCSTAT(siop_stat_intr_shortxfer); if ((dstat & DSTAT_DFE) == 0) - siop_clearfifo(sc); + siop_clearfifo(&sc->sc_c); /* no table to flush here */ CALL_SCRIPT(Ent_status); return 1; @@ -516,11 +508,11 @@ siop_intr(v) */ INCSTAT(siop_stat_intr_xferdisc); if (scratcha0 & A_flag_data) - siop_sdp(siop_cmd); + siop_sdp(&siop_cmd->cmd_c); else if ((dstat & DSTAT_DFE) == 0) - siop_clearfifo(sc); - bus_space_write_1(sc->sc_rt, sc->sc_rh, - SIOP_SCRATCHA, + siop_clearfifo(&sc->sc_c); + bus_space_write_1(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, SIOP_SCRATCHA, scratcha0 & ~A_flag_data); siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | @@ -529,11 +521,11 @@ siop_intr(v) return 1; } printf("%s: unexpected phase mismatch %d\n", - sc->sc_dev.dv_xname, + sc->sc_c.sc_dev.dv_xname, sstat1 & SSTAT1_PHASE_MASK); } else { printf("%s: phase mismatch without command\n", - sc->sc_dev.dv_xname); + sc->sc_c.sc_dev.dv_xname); } need_reset = 1; } @@ -542,20 +534,20 @@ siop_intr(v) if (siop_cmd) scsipi_printaddr(xs->xs_periph); else - printf("%s:", sc->sc_dev.dv_xname); + printf("%s:", sc->sc_c.sc_dev.dv_xname); printf("parity error\n"); goto reset; } if ((sist & (SIST1_STO << 8)) && need_reset == 0) { /* selection time out, assume there's no device here */ if (siop_cmd) { - siop_cmd->status = CMDST_DONE; + siop_cmd->cmd_c.status = CMDST_DONE; xs->error = XS_SELTIMEOUT; freetarget = 1; goto end; } else { printf("%s: selection timeout without " - "command\n", sc->sc_dev.dv_xname); + "command\n", sc->sc_c.sc_dev.dv_xname); need_reset = 1; } } @@ -565,17 +557,17 @@ siop_intr(v) * a fatal condition this way. Attempt to get sense. */ if (siop_cmd) { - siop_cmd->siop_tables.status = + siop_cmd->cmd_tables->status = htole32(SCSI_CHECK); goto end; } printf("%s: unexpected disconnect without " - "command\n", sc->sc_dev.dv_xname); + "command\n", sc->sc_c.sc_dev.dv_xname); goto reset; } if (sist & (SIST1_SBMC << 8)) { /* SCSI bus mode change */ - if (siop_modechange(sc) == 0 || need_reset == 1) + if (siop_modechange(&sc->sc_c) == 0 || need_reset == 1) goto reset; if ((istat & ISTAT_DIP) && (dstat & DSTAT_SIR)) { /* @@ -588,20 +580,22 @@ siop_intr(v) * else we have to restart it ourselve, at the * interrupted instruction. */ - bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, - bus_space_read_4(sc->sc_rt, sc->sc_rh, + bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_DSP, + bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSP) - 8); return 1; } /* Else it's an unhandled exeption (for now). */ printf("%s: unhandled scsi interrupt, sist=0x%x sstat1=0x%x " - "DSA=0x%x DSP=0x%x\n", sc->sc_dev.dv_xname, sist, - bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SSTAT1), - bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA), - (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) - - sc->sc_scriptaddr)); + "DSA=0x%x DSP=0x%x\n", sc->sc_c.sc_dev.dv_xname, sist, + bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_SSTAT1), + bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSA), + (int)(bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_DSP) - sc->sc_c.sc_scriptaddr)); if (siop_cmd) { - siop_cmd->status = CMDST_DONE; + siop_cmd->cmd_c.status = CMDST_DONE; xs->error = XS_SELTIMEOUT; goto end; } @@ -610,14 +604,14 @@ siop_intr(v) if (need_reset) { reset: /* fatal error, reset the bus */ - siop_resetbus(sc); + siop_resetbus(&sc->sc_c); /* no table to flush here */ return 1; } scintr: if ((istat & ISTAT_DIP) && (dstat & DSTAT_SIR)) { /* script interrupt */ - irqcode = bus_space_read_4(sc->sc_rt, sc->sc_rh, + irqcode = bus_space_read_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_DSPS); #ifdef SIOP_DEBUG_INTR printf("script interrupt 0x%x\n", irqcode); @@ -630,22 +624,22 @@ scintr: if (siop_cmd == NULL) { printf( "%s: script interrupt (0x%x) with invalid DSA !!!\n", - sc->sc_dev.dv_xname, irqcode); + sc->sc_c.sc_dev.dv_xname, irqcode); goto reset; } - if (siop_cmd->status != CMDST_ACTIVE) { + if (siop_cmd->cmd_c.status != CMDST_ACTIVE) { printf("%s: command with invalid status " "(IRQ code 0x%x current status %d) !\n", - sc->sc_dev.dv_xname, - irqcode, siop_cmd->status); + sc->sc_c.sc_dev.dv_xname, + irqcode, siop_cmd->cmd_c.status); xs = NULL; } } switch(irqcode) { case A_int_err: printf("error, DSP=0x%x\n", - (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, - SIOP_DSP) - sc->sc_scriptaddr)); + (int)(bus_space_read_4(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, SIOP_DSP) - sc->sc_c.sc_scriptaddr)); if (xs) { xs->error = XS_SELTIMEOUT; goto end; @@ -654,64 +648,68 @@ scintr: } case A_int_reseltarg: printf("%s: reselect with invalid target\n", - sc->sc_dev.dv_xname); + sc->sc_c.sc_dev.dv_xname); goto reset; case A_int_resellun: INCSTAT(siop_stat_intr_lunresel); - target = bus_space_read_1(sc->sc_rt, sc->sc_rh, - SIOP_SCRATCHA) & 0xf; - lun = bus_space_read_1(sc->sc_rt, sc->sc_rh, + target = bus_space_read_1(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, SIOP_SCRATCHA) & 0xf; + lun = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_SCRATCHA + 1); - tag = bus_space_read_1(sc->sc_rt, sc->sc_rh, + tag = bus_space_read_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, SIOP_SCRATCHA + 2); - siop_target = sc->targets[target]; + siop_target = + (struct siop_target *)sc->sc_c.targets[target]; if (siop_target == NULL) { - printf("%s: reselect with invalid " - "target %d\n", sc->sc_dev.dv_xname, target); + printf("%s: reselect with invalid target %d\n", + sc->sc_c.sc_dev.dv_xname, target); goto reset; } siop_lun = siop_target->siop_lun[lun]; if (siop_lun == NULL) { printf("%s: target %d reselect with invalid " - "lun %d\n", sc->sc_dev.dv_xname, + "lun %d\n", sc->sc_c.sc_dev.dv_xname, target, lun); goto reset; } if (siop_lun->siop_tag[tag].active == NULL) { printf("%s: target %d lun %d tag %d reselect " - "without command\n", sc->sc_dev.dv_xname, + "without command\n", + sc->sc_c.sc_dev.dv_xname, target, lun, tag); goto reset; } siop_cmd = siop_lun->siop_tag[tag].active; - bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, - siop_cmd->dsa + sizeof(struct siop_xfer_common) + + bus_space_write_4(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_DSP, siop_cmd->cmd_c.dsa + + sizeof(struct siop_common_xfer) + Ent_ldsa_reload_dsa); siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE); return 1; case A_int_reseltag: printf("%s: reselect with invalid tag\n", - sc->sc_dev.dv_xname); + sc->sc_c.sc_dev.dv_xname); goto reset; case A_int_msgin: { - int msgin = bus_space_read_1(sc->sc_rt, sc->sc_rh, - SIOP_SFBR); + int msgin = bus_space_read_1(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, SIOP_SFBR); if (msgin == MSG_MESSAGE_REJECT) { int msg, extmsg; - if (siop_cmd->siop_tables.msg_out[0] & 0x80) { + if (siop_cmd->cmd_tables->msg_out[0] & 0x80) { /* * message was part of a identify + * something else. Identify shoudl't * have been rejected. */ - msg = siop_cmd->siop_tables.msg_out[1]; + msg = + siop_cmd->cmd_tables->msg_out[1]; extmsg = - siop_cmd->siop_tables.msg_out[3]; + siop_cmd->cmd_tables->msg_out[3]; } else { - msg = siop_cmd->siop_tables.msg_out[0]; + msg = siop_cmd->cmd_tables->msg_out[0]; extmsg = - siop_cmd->siop_tables.msg_out[2]; + siop_cmd->cmd_tables->msg_out[2]; } if (msg == MSG_MESSAGE_REJECT) { /* MSG_REJECT for a MSG_REJECT !*/ @@ -719,7 +717,7 @@ scintr: scsipi_printaddr(xs->xs_periph); else printf("%s: ", - sc->sc_dev.dv_xname); + sc->sc_c.sc_dev.dv_xname); printf("our reject message was " "rejected\n"); goto reset; @@ -727,18 +725,21 @@ scintr: if (msg == MSG_EXTENDED && extmsg == MSG_EXT_WDTR) { /* WDTR rejected, initiate sync */ - if ((siop_target->flags & TARF_SYNC) - == 0) { - siop_target->status = TARST_OK; - siop_update_xfer_mode(sc, + if ((siop_target->target_c.flags & + TARF_SYNC) == 0) { + siop_target->target_c.status = + TARST_OK; + siop_update_xfer_mode(&sc->sc_c, target); /* no table to flush here */ CALL_SCRIPT(Ent_msgin_ack); return 1; } - siop_target->status = TARST_SYNC_NEG; - siop_sdtr_msg(siop_cmd, 0, - sc->minsync, sc->maxoff); + siop_target->target_c.status = + TARST_SYNC_NEG; + siop_sdtr_msg(&siop_cmd->cmd_c, 0, + sc->sc_c.st_minsync, + sc->sc_c.maxoff); siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -747,10 +748,11 @@ scintr: } else if (msg == MSG_EXTENDED && extmsg == MSG_EXT_SDTR) { /* sync rejected */ - siop_target->offset = 0; - siop_target->period = 0; - siop_target->status = TARST_OK; - siop_update_xfer_mode(sc, target); + siop_target->target_c.offset = 0; + siop_target->target_c.period = 0; + siop_target->target_c.status = TARST_OK; + siop_update_xfer_mode(&sc->sc_c, + target); /* no table to flush here */ CALL_SCRIPT(Ent_msgin_ack); return 1; @@ -766,7 +768,8 @@ scintr: if (xs) scsipi_printaddr(xs->xs_periph); else - printf("%s: ", sc->sc_dev.dv_xname); + printf("%s: ", + sc->sc_c.sc_dev.dv_xname); if (msg == MSG_EXTENDED) { printf("scsi message reject, extended " "message sent was 0x%x\n", extmsg); @@ -781,11 +784,11 @@ scintr: if (xs) scsipi_printaddr(xs->xs_periph); else - printf("%s: ", sc->sc_dev.dv_xname); + printf("%s: ", sc->sc_c.sc_dev.dv_xname); printf("unhandled message 0x%x\n", - siop_cmd->siop_tables.msg_in[0]); - siop_cmd->siop_tables.msg_out[0] = MSG_MESSAGE_REJECT; - siop_cmd->siop_tables.t_msgout.count= htole32(1); + siop_cmd->cmd_tables->msg_in[0]); + siop_cmd->cmd_tables->msg_out[0] = MSG_MESSAGE_REJECT; + siop_cmd->cmd_tables->t_msgout.count= htole32(1); siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); CALL_SCRIPT(Ent_send_msgout); @@ -794,15 +797,16 @@ scintr: case A_int_extmsgin: #ifdef SIOP_DEBUG_INTR printf("extended message: msg 0x%x len %d\n", - siop_cmd->siop_tables.msg_in[2], - siop_cmd->siop_tables.msg_in[1]); + siop_cmd->cmd_tables->msg_in[2], + siop_cmd->cmd_tables->msg_in[1]); #endif - if (siop_cmd->siop_tables.msg_in[1] > 6) + if (siop_cmd->cmd_tables->msg_in[1] > + sizeof(siop_cmd->cmd_tables->msg_in) - 2) printf("%s: extended message too big (%d)\n", - sc->sc_dev.dv_xname, - siop_cmd->siop_tables.msg_in[1]); - siop_cmd->siop_tables.t_extmsgdata.count = - htole32(siop_cmd->siop_tables.msg_in[1] - 1); + sc->sc_c.sc_dev.dv_xname, + siop_cmd->cmd_tables->msg_in[1]); + siop_cmd->cmd_tables->t_extmsgdata.count = + htole32(siop_cmd->cmd_tables->msg_in[1] - 1); siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); CALL_SCRIPT(Ent_get_extmsgdata); @@ -812,19 +816,19 @@ scintr: { int i; printf("extended message: 0x%x, data:", - siop_cmd->siop_tables.msg_in[2]); - for (i = 3; i < 2 + siop_cmd->siop_tables.msg_in[1]; + siop_cmd->cmd_tables->msg_in[2]); + for (i = 3; i < 2 + siop_cmd->cmd_tables->msg_in[1]; i++) printf(" 0x%x", - siop_cmd->siop_tables.msg_in[i]); + siop_cmd->cmd_tables->msg_in[i]); printf("\n"); } #endif - if (siop_cmd->siop_tables.msg_in[2] == MSG_EXT_WDTR) { - switch (siop_wdtr_neg(siop_cmd)) { + if (siop_cmd->cmd_tables->msg_in[2] == MSG_EXT_WDTR) { + switch (siop_wdtr_neg(&siop_cmd->cmd_c)) { case SIOP_NEG_MSGOUT: siop_update_scntl3(sc, - siop_cmd->siop_target); + siop_cmd->cmd_c.siop_target); siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -832,7 +836,7 @@ scintr: return(1); case SIOP_NEG_ACK: siop_update_scntl3(sc, - siop_cmd->siop_target); + siop_cmd->cmd_c.siop_target); CALL_SCRIPT(Ent_msgin_ack); return(1); default: @@ -841,11 +845,11 @@ scintr: } return(1); } - if (siop_cmd->siop_tables.msg_in[2] == MSG_EXT_SDTR) { - switch (siop_sdtr_neg(siop_cmd)) { + if (siop_cmd->cmd_tables->msg_in[2] == MSG_EXT_SDTR) { + switch (siop_sdtr_neg(&siop_cmd->cmd_c)) { case SIOP_NEG_MSGOUT: siop_update_scntl3(sc, - siop_cmd->siop_target); + siop_cmd->cmd_c.siop_target); siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -853,7 +857,7 @@ scintr: return(1); case SIOP_NEG_ACK: siop_update_scntl3(sc, - siop_cmd->siop_target); + siop_cmd->cmd_c.siop_target); CALL_SCRIPT(Ent_msgin_ack); return(1); default: @@ -863,22 +867,22 @@ scintr: return(1); } /* send a message reject */ - siop_cmd->siop_tables.msg_out[0] = MSG_MESSAGE_REJECT; - siop_cmd->siop_tables.t_msgout.count = htole32(1); + siop_cmd->cmd_tables->msg_out[0] = MSG_MESSAGE_REJECT; + siop_cmd->cmd_tables->t_msgout.count = htole32(1); siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); CALL_SCRIPT(Ent_send_msgout); return 1; case A_int_disc: INCSTAT(siop_stat_intr_sdp); - offset = bus_space_read_1(sc->sc_rt, sc->sc_rh, - SIOP_SCRATCHA + 1); + offset = bus_space_read_1(sc->sc_c.sc_rt, + sc->sc_c.sc_rh, SIOP_SCRATCHA + 1); #ifdef SIOP_DEBUG_DR printf("disconnect offset %d\n", offset); #endif if (offset > SIOP_NSG) { printf("%s: bad offset for disconnect (%d)\n", - sc->sc_dev.dv_xname, offset); + sc->sc_c.sc_dev.dv_xname, offset); goto reset; } /* @@ -887,8 +891,8 @@ scintr: * Don't call memmove in this case. */ if (offset < SIOP_NSG) { - memmove(&siop_cmd->siop_tables.data[0], - &siop_cmd->siop_tables.data[offset], + memmove(&siop_cmd->cmd_tables->data[0], + &siop_cmd->cmd_tables->data[offset], (SIOP_NSG - offset) * sizeof(scr_table_t)); siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -902,20 +906,21 @@ scintr: case A_int_done: if (xs == NULL) { printf("%s: done without command, DSA=0x%lx\n", - sc->sc_dev.dv_xname, (u_long)siop_cmd->dsa); - siop_cmd->status = CMDST_FREE; + sc->sc_c.sc_dev.dv_xname, + (u_long)siop_cmd->cmd_c.dsa); + siop_cmd->cmd_c.status = CMDST_FREE; CALL_SCRIPT(Ent_script_sched); return 1; } #ifdef SIOP_DEBUG_INTR printf("done, DSA=0x%lx target id 0x%x last msg " - "in=0x%x status=0x%x\n", (u_long)siop_cmd->dsa, - le32toh(siop_cmd->siop_tables.id), - siop_cmd->siop_tables.msg_in[0], - le32toh(siop_cmd->siop_tables.status)); + "in=0x%x status=0x%x\n", (u_long)siop_cmd->cmd_c.dsa, + le32toh(siop_cmd->cmd_tables->id), + siop_cmd->cmd_tables->msg_in[0], + le32toh(siop_cmd->cmd_tables->status)); #endif INCSTAT(siop_stat_intr_done); - siop_cmd->status = CMDST_DONE; + siop_cmd->cmd_c.status = CMDST_DONE; goto end; default: printf("unknown irqcode %x\n", irqcode); @@ -936,21 +941,21 @@ end: * Otherwise wait for siop_scsicmd_end(), we may need to cleanup the * queue */ - xs->status = le32toh(siop_cmd->siop_tables.status); + xs->status = le32toh(siop_cmd->cmd_tables->status); if (xs->status == SCSI_OK) CALL_SCRIPT(Ent_script_sched); else restart = 1; siop_lun->siop_tag[tag].active = NULL; siop_scsicmd_end(siop_cmd); - if (freetarget && siop_target->status == TARST_PROBING) + if (freetarget && siop_target->target_c.status == TARST_PROBING) siop_del_dev(sc, target, lun); if (restart) CALL_SCRIPT(Ent_script_sched); if (sc->sc_flags & SCF_CHAN_NOSLOT) { /* a command terminated, so we have free slots now */ sc->sc_flags &= ~SCF_CHAN_NOSLOT; - scsipi_channel_thaw(&sc->sc_chan, 1); + scsipi_channel_thaw(&sc->sc_c.sc_chan, 1); } return 1; @@ -960,8 +965,8 @@ void siop_scsicmd_end(siop_cmd) struct siop_cmd *siop_cmd; { - struct scsipi_xfer *xs = siop_cmd->xs; - struct siop_softc *sc = siop_cmd->siop_sc; + struct scsipi_xfer *xs = siop_cmd->cmd_c.xs; + struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc; switch(xs->status) { case SCSI_OK: @@ -979,9 +984,10 @@ siop_scsicmd_end(siop_cmd) case SCSI_QUEUE_FULL: INCSTAT(siop_stat_intr_qfull); #ifdef SIOP_DEBUG - printf("%s:%d:%d: queue full (tag %d)\n", sc->sc_dev.dv_xname, + printf("%s:%d:%d: queue full (tag %d)\n", + sc->sc_c.sc_dev.dv_xname, xs->xs_periph->periph_target, - xs->xs_periph->periph_lun, siop_cmd->tag); + xs->xs_periph->periph_lun, siop_cmd->cmd_c.tag); #endif xs->error = XS_BUSY; break; @@ -998,18 +1004,20 @@ siop_scsicmd_end(siop_cmd) xs->error = XS_SELTIMEOUT; break; default: + scsipi_printaddr(xs->xs_periph); + printf("invalid status code %d\n", xs->status); xs->error = XS_DRIVER_STUFFUP; } if (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { - bus_dmamap_sync(sc->sc_dmat, siop_cmd->dmamap_data, 0, - siop_cmd->dmamap_data->dm_mapsize, + bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data, 0, + siop_cmd->cmd_c.dmamap_data->dm_mapsize, (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sc_dmat, siop_cmd->dmamap_data); + bus_dmamap_unload(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_data); } - bus_dmamap_unload(sc->sc_dmat, siop_cmd->dmamap_cmd); - callout_stop(&siop_cmd->xs->xs_callout); - siop_cmd->status = CMDST_FREE; + bus_dmamap_unload(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_cmd); + callout_stop(&siop_cmd->cmd_c.xs->xs_callout); + siop_cmd->cmd_c.status = CMDST_FREE; TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next); xs->resid = 0; scsipi_done (xs); @@ -1023,7 +1031,8 @@ siop_unqueue(sc, target, lun) { int slot, tag; struct siop_cmd *siop_cmd; - struct siop_lun *siop_lun = sc->targets[target]->siop_lun[lun]; + struct siop_lun *siop_lun = + ((struct siop_target *)sc->sc_c.targets[target])->siop_lun[lun]; /* first make sure to read valid data */ siop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); @@ -1036,7 +1045,8 @@ siop_unqueue(sc, target, lun) for (slot = 0; slot <= sc->sc_currschedslot; slot++) { if (siop_script_read(sc, (Ent_script_sched_slot0 / 4) + slot * 2 + 1) == - siop_cmd->dsa + sizeof(struct siop_xfer_common) + + siop_cmd->cmd_c.dsa + + sizeof(struct siop_common_xfer) + Ent_ldsa_select) break; } @@ -1049,8 +1059,8 @@ siop_unqueue(sc, target, lun) siop_script_write(sc, (Ent_script_sched_slot0 / 4) + slot * 2, 0x80000000); /* ask to requeue */ - siop_cmd->xs->error = XS_REQUEUE; - siop_cmd->xs->status = SCSI_SIOP_NOCHECK; + siop_cmd->cmd_c.xs->error = XS_REQUEUE; + siop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK; siop_lun->siop_tag[tag].active = NULL; siop_scsicmd_end(siop_cmd); } @@ -1071,34 +1081,35 @@ int siop_handle_qtag_reject(siop_cmd) struct siop_cmd *siop_cmd; { - struct siop_softc *sc = siop_cmd->siop_sc; - int target = siop_cmd->xs->xs_periph->periph_target; - int lun = siop_cmd->xs->xs_periph->periph_lun; - int tag = siop_cmd->siop_tables.msg_out[2]; - struct siop_lun *siop_lun = sc->targets[target]->siop_lun[lun]; + struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc; + int target = siop_cmd->cmd_c.xs->xs_periph->periph_target; + int lun = siop_cmd->cmd_c.xs->xs_periph->periph_lun; + int tag = siop_cmd->cmd_tables->msg_out[2]; + struct siop_lun *siop_lun = + ((struct siop_target*)sc->sc_c.targets[target])->siop_lun[lun]; #ifdef SIOP_DEBUG printf("%s:%d:%d: tag message %d (%d) rejected (status %d)\n", - sc->sc_dev.dv_xname, target, lun, tag, siop_cmd->tag, - siop_cmd->status); + sc->sc_c.sc_dev.dv_xname, target, lun, tag, siop_cmd->cmd_c.tag, + siop_cmd->cmd_c.status); #endif if (siop_lun->siop_tag[0].active != NULL) { printf("%s: untagged command already running for target %d " - "lun %d (status %d)\n", sc->sc_dev.dv_xname, target, lun, - siop_lun->siop_tag[0].active->status); + "lun %d (status %d)\n", sc->sc_c.sc_dev.dv_xname, + target, lun, siop_lun->siop_tag[0].active->cmd_c.status); return -1; } /* clear tag slot */ siop_lun->siop_tag[tag].active = NULL; /* add command to non-tagged slot */ siop_lun->siop_tag[0].active = siop_cmd; - siop_cmd->tag = 0; + siop_cmd->cmd_c.tag = 0; /* adjust reselect script if there is one */ if (siop_lun->siop_tag[0].reseloff > 0) { siop_script_write(sc, siop_lun->siop_tag[0].reseloff + 1, - siop_cmd->dsa + sizeof(struct siop_xfer_common) + + siop_cmd->cmd_c.dsa + sizeof(struct siop_common_xfer) + Ent_ldsa_reload_dsa); siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE); } @@ -1122,50 +1133,53 @@ siop_handle_reset(sc) * scsi bus reset. reset the chip and restart * the queue. Need to clean up all active commands */ - printf("%s: scsi bus reset\n", sc->sc_dev.dv_xname); + printf("%s: scsi bus reset\n", sc->sc_c.sc_dev.dv_xname); /* stop, reset and restart the chip */ siop_reset(sc); if (sc->sc_flags & SCF_CHAN_NOSLOT) { /* chip has been reset, all slots are free now */ sc->sc_flags &= ~SCF_CHAN_NOSLOT; - scsipi_channel_thaw(&sc->sc_chan, 1); + scsipi_channel_thaw(&sc->sc_c.sc_chan, 1); } /* * Process all commands: first commmands being executed */ - for (target = 0; target < sc->sc_chan.chan_ntargets; + for (target = 0; target < sc->sc_c.sc_chan.chan_ntargets; target++) { - if (sc->targets[target] == NULL) + if (sc->sc_c.targets[target] == NULL) continue; for (lun = 0; lun < 8; lun++) { - siop_lun = sc->targets[target]->siop_lun[lun]; + struct siop_target *siop_target = + (struct siop_target *)sc->sc_c.targets[target]; + siop_lun = siop_target->siop_lun[lun]; if (siop_lun == NULL) continue; for (tag = 0; tag < - ((sc->targets[target]->flags & TARF_TAG) ? + ((sc->sc_c.targets[target]->flags & TARF_TAG) ? SIOP_NTAG : 1); tag++) { siop_cmd = siop_lun->siop_tag[tag].active; if (siop_cmd == NULL) continue; - scsipi_printaddr(siop_cmd->xs->xs_periph); + scsipi_printaddr(siop_cmd->cmd_c.xs->xs_periph); printf("command with tag id %d reset\n", tag); - siop_cmd->xs->error = - (siop_cmd->flags & CMDFL_TIMEOUT) ? + siop_cmd->cmd_c.xs->error = + (siop_cmd->cmd_c.flags & CMDFL_TIMEOUT) ? XS_TIMEOUT : XS_RESET; - siop_cmd->xs->status = SCSI_SIOP_NOCHECK; + siop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK; siop_lun->siop_tag[tag].active = NULL; - siop_cmd->status = CMDST_DONE; + siop_cmd->cmd_c.status = CMDST_DONE; siop_scsicmd_end(siop_cmd); } } - sc->targets[target]->status = TARST_ASYNC; - sc->targets[target]->flags &= ~TARF_ISWIDE; - sc->targets[target]->period = sc->targets[target]->offset = 0; - siop_update_xfer_mode(sc, target); + sc->sc_c.targets[target]->status = TARST_ASYNC; + sc->sc_c.targets[target]->flags &= ~TARF_ISWIDE; + sc->sc_c.targets[target]->period = + sc->sc_c.targets[target]->offset = 0; + siop_update_xfer_mode(&sc->sc_c, target); } - scsipi_async_event(&sc->sc_chan, ASYNC_EVENT_RESET, NULL); + scsipi_async_event(&sc->sc_c.sc_chan, ASYNC_EVENT_RESET, NULL); } void @@ -1178,6 +1192,7 @@ siop_scsipi_request(chan, req, arg) struct scsipi_periph *periph; struct siop_softc *sc = (void *)chan->chan_adapter->adapt_dev; struct siop_cmd *siop_cmd; + struct siop_target *siop_target; int s, error, i; int target; int lun; @@ -1202,100 +1217,116 @@ siop_scsipi_request(chan, req, arg) } TAILQ_REMOVE(&sc->free_list, siop_cmd, next); #ifdef DIAGNOSTIC - if (siop_cmd->status != CMDST_FREE) + if (siop_cmd->cmd_c.status != CMDST_FREE) panic("siop_scsicmd: new cmd not free"); #endif - if (sc->targets[target] == NULL) { + siop_target = (struct siop_target*)sc->sc_c.targets[target]; + if (siop_target == NULL) { #ifdef SIOP_DEBUG printf("%s: alloc siop_target for target %d\n", - sc->sc_dev.dv_xname, target); + sc->sc_c.sc_dev.dv_xname, target); #endif - sc->targets[target] = + sc->sc_c.targets[target] = malloc(sizeof(struct siop_target), M_DEVBUF, M_NOWAIT); - if (sc->targets[target] == NULL) { + if (sc->sc_c.targets[target] == NULL) { printf("%s: can't malloc memory for " - "target %d\n", sc->sc_dev.dv_xname, target); + "target %d\n", sc->sc_c.sc_dev.dv_xname, + target); xs->error = XS_RESOURCE_SHORTAGE; scsipi_done(xs); splx(s); return; } - sc->targets[target]->status = TARST_PROBING; - sc->targets[target]->flags = 0; - sc->targets[target]->id = - sc->clock_div << 24; /* scntl3 */ - sc->targets[target]->id |= target << 16; /* id */ - /* sc->targets[target]->id |= 0x0 << 8; scxfer is 0 */ + siop_target = + (struct siop_target*)sc->sc_c.targets[target]; + siop_target->target_c.status = TARST_PROBING; + siop_target->target_c.flags = 0; + siop_target->target_c.id = + sc->sc_c.clock_div << 24; /* scntl3 */ + siop_target->target_c.id |= target << 16; /* id */ + /* siop_target->target_c.id |= 0x0 << 8; scxfer is 0 */ /* get a lun switch script */ - sc->targets[target]->lunsw = siop_get_lunsw(sc); - if (sc->targets[target]->lunsw == NULL) { + siop_target->lunsw = siop_get_lunsw(sc); + if (siop_target->lunsw == NULL) { printf("%s: can't alloc lunsw for target %d\n", - sc->sc_dev.dv_xname, target); + sc->sc_c.sc_dev.dv_xname, target); xs->error = XS_RESOURCE_SHORTAGE; scsipi_done(xs); splx(s); return; } for (i=0; i < 8; i++) - sc->targets[target]->siop_lun[i] = NULL; + siop_target->siop_lun[i] = NULL; siop_add_reselsw(sc, target); } - if (sc->targets[target]->siop_lun[lun] == NULL) { - sc->targets[target]->siop_lun[lun] = + if (siop_target->siop_lun[lun] == NULL) { + siop_target->siop_lun[lun] = malloc(sizeof(struct siop_lun), M_DEVBUF, M_NOWAIT|M_ZERO); - if (sc->targets[target]->siop_lun[lun] == NULL) { + if (siop_target->siop_lun[lun] == NULL) { printf("%s: can't alloc siop_lun for " "target %d lun %d\n", - sc->sc_dev.dv_xname, target, lun); + sc->sc_c.sc_dev.dv_xname, target, lun); xs->error = XS_RESOURCE_SHORTAGE; scsipi_done(xs); splx(s); return; } } - siop_cmd->siop_target = sc->targets[target]; - siop_cmd->xs = xs; - siop_cmd->flags = 0; - siop_cmd->status = CMDST_READY; + siop_cmd->cmd_c.siop_target = sc->sc_c.targets[target]; + siop_cmd->cmd_c.xs = xs; + siop_cmd->cmd_c.flags = 0; + siop_cmd->cmd_c.status = CMDST_READY; /* load the DMA maps */ - error = bus_dmamap_load(sc->sc_dmat, siop_cmd->dmamap_cmd, + error = bus_dmamap_load(sc->sc_c.sc_dmat, + siop_cmd->cmd_c.dmamap_cmd, xs->cmd, xs->cmdlen, NULL, BUS_DMA_NOWAIT); if (error) { printf("%s: unable to load cmd DMA map: %d\n", - sc->sc_dev.dv_xname, error); + sc->sc_c.sc_dev.dv_xname, error); xs->error = XS_DRIVER_STUFFUP; scsipi_done(xs); splx(s); return; } if (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { - error = bus_dmamap_load(sc->sc_dmat, - siop_cmd->dmamap_data, xs->data, xs->datalen, + error = bus_dmamap_load(sc->sc_c.sc_dmat, + siop_cmd->cmd_c.dmamap_data, xs->data, xs->datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING | ((xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE)); if (error) { printf("%s: unable to load cmd DMA map: %d", - sc->sc_dev.dv_xname, error); + sc->sc_c.sc_dev.dv_xname, error); xs->error = XS_DRIVER_STUFFUP; scsipi_done(xs); - bus_dmamap_unload(sc->sc_dmat, siop_cmd->dmamap_cmd); + bus_dmamap_unload(sc->sc_c.sc_dmat, + siop_cmd->cmd_c.dmamap_cmd); splx(s); return; } - bus_dmamap_sync(sc->sc_dmat, siop_cmd->dmamap_data, 0, - siop_cmd->dmamap_data->dm_mapsize, + bus_dmamap_sync(sc->sc_c.sc_dmat, + siop_cmd->cmd_c.dmamap_data, 0, + siop_cmd->cmd_c.dmamap_data->dm_mapsize, (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); } - bus_dmamap_sync(sc->sc_dmat, siop_cmd->dmamap_cmd, 0, - siop_cmd->dmamap_cmd->dm_mapsize, BUS_DMASYNC_PREWRITE); - - siop_setuptables(siop_cmd); + bus_dmamap_sync(sc->sc_c.sc_dmat, siop_cmd->cmd_c.dmamap_cmd, 0, + siop_cmd->cmd_c.dmamap_cmd->dm_mapsize, + BUS_DMASYNC_PREWRITE); + + if (xs->xs_tag_type) { + /* use tag_id + 1, tag 0 is reserved for untagged cmds*/ + siop_cmd->cmd_c.tag = xs->xs_tag_id + 1; + } else { + siop_cmd->cmd_c.tag = 0; + } + siop_setuptables(&siop_cmd->cmd_c); + siop_table_sync(siop_cmd, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); siop_start(sc, siop_cmd); if (xs->xs_control & XS_CTL_POLL) { /* poll for command completion */ @@ -1309,8 +1340,8 @@ siop_scsipi_request(chan, req, arg) case ADAPTER_REQ_GROW_RESOURCES: #ifdef SIOP_DEBUG - printf("%s grow resources (%d)\n", sc->sc_dev.dv_xname, - sc->sc_adapt.adapt_openings); + printf("%s grow resources (%d)\n", sc->sc_c.sc_dev.dv_xname, + sc->sc_c.sc_adapt.adapt_openings); #endif siop_morecbd(sc); return; @@ -1318,25 +1349,27 @@ siop_scsipi_request(chan, req, arg) case ADAPTER_REQ_SET_XFER_MODE: { struct scsipi_xfer_mode *xm = arg; - if (sc->targets[xm->xm_target] == NULL) + if (sc->sc_c.targets[xm->xm_target] == NULL) return; s = splbio(); if (xm->xm_mode & PERIPH_CAP_TQING) - sc->targets[xm->xm_target]->flags |= TARF_TAG; + sc->sc_c.targets[xm->xm_target]->flags |= TARF_TAG; if ((xm->xm_mode & PERIPH_CAP_WIDE16) && - (sc->features & SF_BUS_WIDE)) - sc->targets[xm->xm_target]->flags |= TARF_WIDE; + (sc->sc_c.features & SF_BUS_WIDE)) + sc->sc_c.targets[xm->xm_target]->flags |= TARF_WIDE; if (xm->xm_mode & PERIPH_CAP_SYNC) - sc->targets[xm->xm_target]->flags |= TARF_SYNC; + sc->sc_c.targets[xm->xm_target]->flags |= TARF_SYNC; if ((xm->xm_mode & (PERIPH_CAP_SYNC | PERIPH_CAP_WIDE16)) || - sc->targets[xm->xm_target]->status == TARST_PROBING) - sc->targets[xm->xm_target]->status = + sc->sc_c.targets[xm->xm_target]->status == TARST_PROBING) + sc->sc_c.targets[xm->xm_target]->status = TARST_ASYNC; - for (lun = 0; lun < sc->sc_chan.chan_nluns; lun++) { - if (sc->sc_chan.chan_periphs[xm->xm_target][lun]) + for (lun = 0; lun < sc->sc_c.sc_chan.chan_nluns; lun++) { + if (scsipi_lookup_periph(chan, + xm->xm_target, lun) != NULL) { /* allocate a lun sw entry for this device */ siop_add_dev(sc, xm->xm_target, lun); + } } splx(s); @@ -1350,6 +1383,7 @@ siop_start(sc, siop_cmd) struct siop_cmd *siop_cmd; { struct siop_lun *siop_lun; + struct siop_xfer *siop_xfer; u_int32_t dsa; int timeout; int target, lun, slot; @@ -1382,21 +1416,22 @@ siop_start(sc, siop_cmd) } else { slot++; } - target = siop_cmd->xs->xs_periph->periph_target; - lun = siop_cmd->xs->xs_periph->periph_lun; - siop_lun = sc->targets[target]->siop_lun[lun]; + target = siop_cmd->cmd_c.xs->xs_periph->periph_target; + lun = siop_cmd->cmd_c.xs->xs_periph->periph_lun; + siop_lun = + ((struct siop_target*)sc->sc_c.targets[target])->siop_lun[lun]; /* if non-tagged command active, panic: this shouldn't happen */ if (siop_lun->siop_tag[0].active != NULL) { panic("siop_start: tagged cmd while untagged running"); } #ifdef DIAGNOSTIC /* sanity check the tag if needed */ - if (siop_cmd->flags & CMDFL_TAG) { - if (siop_lun->siop_tag[siop_cmd->tag].active != NULL) + if (siop_cmd->cmd_c.flags & CMDFL_TAG) { + if (siop_lun->siop_tag[siop_cmd->cmd_c.tag].active != NULL) panic("siop_start: tag not free"); - if (siop_cmd->tag >= SIOP_NTAG) { - scsipi_printaddr(siop_cmd->xs->xs_periph); - printf(": tag id %d\n", siop_cmd->tag); + if (siop_cmd->cmd_c.tag >= SIOP_NTAG) { + scsipi_printaddr(siop_cmd->cmd_c.xs->xs_periph); + printf(": tag id %d\n", siop_cmd->cmd_c.tag); panic("siop_start: invalid tag id"); } } @@ -1418,46 +1453,47 @@ siop_start(sc, siop_cmd) * no more free slot, no need to continue. freeze the queue * and requeue this command. */ - scsipi_channel_freeze(&sc->sc_chan, 1); + scsipi_channel_freeze(&sc->sc_c.sc_chan, 1); sc->sc_flags |= SCF_CHAN_NOSLOT; - siop_cmd->xs->error = XS_REQUEUE; - siop_cmd->xs->status = SCSI_SIOP_NOCHECK; + siop_cmd->cmd_c.xs->error = XS_REQUEUE; + siop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK; siop_scsicmd_end(siop_cmd); return; } #ifdef SIOP_DEBUG_SCHED printf("using slot %d for DSA 0x%lx\n", slot, - (u_long)siop_cmd->dsa); + (u_long)siop_cmd->cmd_c.dsa); #endif /* mark command as active */ - if (siop_cmd->status == CMDST_READY) - siop_cmd->status = CMDST_ACTIVE; + if (siop_cmd->cmd_c.status == CMDST_READY) + siop_cmd->cmd_c.status = CMDST_ACTIVE; else panic("siop_start: bad status"); - siop_lun->siop_tag[siop_cmd->tag].active = siop_cmd; + siop_lun->siop_tag[siop_cmd->cmd_c.tag].active = siop_cmd; /* patch scripts with DSA addr */ - dsa = siop_cmd->dsa; + dsa = siop_cmd->cmd_c.dsa; /* first reselect switch, if we have an entry */ - if (siop_lun->siop_tag[siop_cmd->tag].reseloff > 0) + if (siop_lun->siop_tag[siop_cmd->cmd_c.tag].reseloff > 0) siop_script_write(sc, - siop_lun->siop_tag[siop_cmd->tag].reseloff + 1, - dsa + sizeof(struct siop_xfer_common) + + siop_lun->siop_tag[siop_cmd->cmd_c.tag].reseloff + 1, + dsa + sizeof(struct siop_common_xfer) + Ent_ldsa_reload_dsa); /* CMD script: MOVE MEMORY addr */ - siop_cmd->siop_xfer->resel[E_ldsa_abs_slot_Used[0]] = - htole32(sc->sc_scriptaddr + Ent_script_sched_slot0 + slot * 8); + siop_xfer = (struct siop_xfer*)siop_cmd->cmd_tables; + siop_xfer->resel[E_ldsa_abs_slot_Used[0]] = + htole32(sc->sc_c.sc_scriptaddr + Ent_script_sched_slot0 + slot * 8); siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE); /* scheduler slot: JUMP ldsa_select */ siop_script_write(sc, (Ent_script_sched_slot0 / 4) + slot * 2 + 1, - dsa + sizeof(struct siop_xfer_common) + Ent_ldsa_select); + dsa + sizeof(struct siop_common_xfer) + Ent_ldsa_select); /* handle timeout */ - if ((siop_cmd->xs->xs_control & XS_CTL_POLL) == 0) { + if ((siop_cmd->cmd_c.xs->xs_control & XS_CTL_POLL) == 0) { /* start exire timer */ - timeout = mstohz(siop_cmd->xs->timeout); + timeout = mstohz(siop_cmd->cmd_c.xs->timeout); if (timeout == 0) timeout = 1; - callout_reset( &siop_cmd->xs->xs_callout, + callout_reset( &siop_cmd->cmd_c.xs->xs_callout, timeout, siop_timeout, siop_cmd); } /* @@ -1470,7 +1506,8 @@ siop_start(sc, siop_cmd) /* make sure SCRIPT processor will read valid data */ siop_script_sync(sc,BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* Signal script it has some work to do */ - bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_ISTAT, ISTAT_SIGP); + bus_space_write_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh, + SIOP_ISTAT, ISTAT_SIGP); /* and wait for IRQ */ return; } @@ -1480,25 +1517,25 @@ siop_timeout(v) void *v; { struct siop_cmd *siop_cmd = v; - struct siop_softc *sc = siop_cmd->siop_sc; + struct siop_softc *sc = (struct siop_softc *)siop_cmd->cmd_c.siop_sc; int s; - scsipi_printaddr(siop_cmd->xs->xs_periph); + scsipi_printaddr(siop_cmd->cmd_c.xs->xs_periph); printf("command timeout\n"); s = splbio(); /* reset the scsi bus */ - siop_resetbus(sc); + siop_resetbus(&sc->sc_c); /* deactivate callout */ - callout_stop(&siop_cmd->xs->xs_callout); + callout_stop(&siop_cmd->cmd_c.xs->xs_callout); /* mark command as being timed out; siop_intr will handle it */ /* * mark command has being timed out and just return; * the bus reset will generate an interrupt, * it will be handled in siop_intr() */ - siop_cmd->flags |= CMDFL_TIMEOUT; + siop_cmd->cmd_c.flags |= CMDFL_TIMEOUT; splx(s); return; @@ -1511,10 +1548,12 @@ siop_dump_script(sc) int i; for (i = 0; i < PAGE_SIZE / 4; i += 2) { printf("0x%04x: 0x%08x 0x%08x", i * 4, - le32toh(sc->sc_script[i]), le32toh(sc->sc_script[i+1])); - if ((le32toh(sc->sc_script[i]) & 0xe0000000) == 0xc0000000) { + le32toh(sc->sc_c.sc_script[i]), + le32toh(sc->sc_c.sc_script[i+1])); + if ((le32toh(sc->sc_c.sc_script[i]) & 0xe0000000) == + 0xc0000000) { i++; - printf(" 0x%08x", le32toh(sc->sc_script[i+1])); + printf(" 0x%08x", le32toh(sc->sc_c.sc_script[i+1])); } printf("\n"); } @@ -1528,6 +1567,7 @@ siop_morecbd(sc) bus_dma_segment_t seg; int rseg; struct siop_cbd *newcbd; + struct siop_xfer *xfer; bus_addr_t dsa; u_int32_t *scr; @@ -1535,7 +1575,7 @@ siop_morecbd(sc) newcbd = malloc(sizeof(struct siop_cbd), M_DEVBUF, M_NOWAIT|M_ZERO); if (newcbd == NULL) { printf("%s: can't allocate memory for command descriptors " - "head\n", sc->sc_dev.dv_xname); + "head\n", sc->sc_c.sc_dev.dv_xname); return; } @@ -1544,83 +1584,85 @@ siop_morecbd(sc) M_DEVBUF, M_NOWAIT|M_ZERO); if (newcbd->cmds == NULL) { printf("%s: can't allocate memory for command descriptors\n", - sc->sc_dev.dv_xname); + sc->sc_c.sc_dev.dv_xname); goto bad3; } - error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0, &seg, + error = bus_dmamem_alloc(sc->sc_c.sc_dmat, PAGE_SIZE, PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT); if (error) { printf("%s: unable to allocate cbd DMA memory, error = %d\n", - sc->sc_dev.dv_xname, error); + sc->sc_c.sc_dev.dv_xname, error); goto bad2; } - error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, PAGE_SIZE, + error = bus_dmamem_map(sc->sc_c.sc_dmat, &seg, rseg, PAGE_SIZE, (caddr_t *)&newcbd->xfers, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); if (error) { printf("%s: unable to map cbd DMA memory, error = %d\n", - sc->sc_dev.dv_xname, error); + sc->sc_c.sc_dev.dv_xname, error); goto bad2; } - error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0, + error = bus_dmamap_create(sc->sc_c.sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0, BUS_DMA_NOWAIT, &newcbd->xferdma); if (error) { printf("%s: unable to create cbd DMA map, error = %d\n", - sc->sc_dev.dv_xname, error); + sc->sc_c.sc_dev.dv_xname, error); goto bad1; } - error = bus_dmamap_load(sc->sc_dmat, newcbd->xferdma, newcbd->xfers, + error = bus_dmamap_load(sc->sc_c.sc_dmat, newcbd->xferdma, newcbd->xfers, PAGE_SIZE, NULL, BUS_DMA_NOWAIT); if (error) { printf("%s: unable to load cbd DMA map, error = %d\n", - sc->sc_dev.dv_xname, error); + sc->sc_c.sc_dev.dv_xname, error); goto bad0; } #ifdef DEBUG - printf("%s: alloc newcdb at PHY addr 0x%lx\n", sc->sc_dev.dv_xname, + printf("%s: alloc newcdb at PHY addr 0x%lx\n", sc->sc_c.sc_dev.dv_xname, (unsigned long)newcbd->xferdma->dm_segs[0].ds_addr); #endif for (i = 0; i < SIOP_NCMDPB; i++) { - error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, SIOP_NSG, + error = bus_dmamap_create(sc->sc_c.sc_dmat, MAXPHYS, SIOP_NSG, MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, - &newcbd->cmds[i].dmamap_data); + &newcbd->cmds[i].cmd_c.dmamap_data); if (error) { printf("%s: unable to create data DMA map for cbd: " "error %d\n", - sc->sc_dev.dv_xname, error); + sc->sc_c.sc_dev.dv_xname, error); goto bad0; } - error = bus_dmamap_create(sc->sc_dmat, + error = bus_dmamap_create(sc->sc_c.sc_dmat, sizeof(struct scsipi_generic), 1, sizeof(struct scsipi_generic), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, - &newcbd->cmds[i].dmamap_cmd); + &newcbd->cmds[i].cmd_c.dmamap_cmd); if (error) { printf("%s: unable to create cmd DMA map for cbd %d\n", - sc->sc_dev.dv_xname, error); + sc->sc_c.sc_dev.dv_xname, error); goto bad0; } - newcbd->cmds[i].siop_sc = sc; + newcbd->cmds[i].cmd_c.siop_sc = &sc->sc_c; newcbd->cmds[i].siop_cbdp = newcbd; - newcbd->cmds[i].siop_xfer = &newcbd->xfers[i]; - memset(newcbd->cmds[i].siop_xfer, 0, - sizeof(struct siop_xfer)); - newcbd->cmds[i].dsa = newcbd->xferdma->dm_segs[0].ds_addr + + xfer = &newcbd->xfers[i]; + newcbd->cmds[i].cmd_tables = (struct siop_common_xfer *)xfer; + memset(newcbd->cmds[i].cmd_tables, 0, sizeof(struct siop_xfer)); + dsa = newcbd->xferdma->dm_segs[0].ds_addr + i * sizeof(struct siop_xfer); - dsa = newcbd->cmds[i].dsa; - newcbd->cmds[i].status = CMDST_FREE; - newcbd->cmds[i].siop_tables.t_msgout.count= htole32(1); - newcbd->cmds[i].siop_tables.t_msgout.addr = htole32(dsa); - newcbd->cmds[i].siop_tables.t_msgin.count= htole32(1); - newcbd->cmds[i].siop_tables.t_msgin.addr = htole32(dsa + 8); - newcbd->cmds[i].siop_tables.t_extmsgin.count= htole32(2); - newcbd->cmds[i].siop_tables.t_extmsgin.addr = htole32(dsa + 9); - newcbd->cmds[i].siop_tables.t_extmsgdata.addr = - htole32(dsa + 11); - newcbd->cmds[i].siop_tables.t_status.count= htole32(1); - newcbd->cmds[i].siop_tables.t_status.addr = htole32(dsa + 16); - + newcbd->cmds[i].cmd_c.dsa = dsa; + newcbd->cmds[i].cmd_c.status = CMDST_FREE; + xfer->siop_tables.t_msgout.count= htole32(1); + xfer->siop_tables.t_msgout.addr = htole32(dsa); + xfer->siop_tables.t_msgin.count= htole32(1); + xfer->siop_tables.t_msgin.addr = htole32(dsa + + offsetof(struct siop_common_xfer, msg_in)); + xfer->siop_tables.t_extmsgin.count= htole32(2); + xfer->siop_tables.t_extmsgin.addr = htole32(dsa + + offsetof(struct siop_common_xfer, msg_in) + 1); + xfer->siop_tables.t_extmsgdata.addr = htole32(dsa + + offsetof(struct siop_common_xfer, msg_in) + 3); + xfer->siop_tables.t_status.count= htole32(1); + xfer->siop_tables.t_status.addr = htole32(dsa + + offsetof(struct siop_common_xfer, status)); /* The select/reselect script */ - scr = &newcbd->cmds[i].siop_xfer->resel[0]; + scr = &xfer->resel[0]; for (j = 0; j < sizeof(load_dsa) / sizeof(load_dsa[0]); j++) scr[j] = htole32(load_dsa[j]); /* @@ -1636,13 +1678,13 @@ siop_morecbd(sc) scr[Ent_rdsa3 / 4] = htole32(0x78130000 | ((dsa & 0xff000000) >> 16)); scr[E_ldsa_abs_reselected_Used[0]] = - htole32(sc->sc_scriptaddr + Ent_reselected); + htole32(sc->sc_c.sc_scriptaddr + Ent_reselected); scr[E_ldsa_abs_reselect_Used[0]] = - htole32(sc->sc_scriptaddr + Ent_reselect); + htole32(sc->sc_c.sc_scriptaddr + Ent_reselect); scr[E_ldsa_abs_selected_Used[0]] = - htole32(sc->sc_scriptaddr + Ent_selected); + htole32(sc->sc_c.sc_scriptaddr + Ent_selected); scr[E_ldsa_abs_data_Used[0]] = - htole32(dsa + sizeof(struct siop_xfer_common) + + htole32(dsa + sizeof(struct siop_common_xfer) + Ent_ldsa_data); /* JUMP foo, IF FALSE - used by MOVE MEMORY to clear the slot */ scr[Ent_ldsa_data / 4] = htole32(0x80000000); @@ -1651,21 +1693,21 @@ siop_morecbd(sc) splx(s); #ifdef SIOP_DEBUG printf("tables[%d]: in=0x%x out=0x%x status=0x%x\n", i, - le32toh(newcbd->cmds[i].siop_tables.t_msgin.addr), - le32toh(newcbd->cmds[i].siop_tables.t_msgout.addr), - le32toh(newcbd->cmds[i].siop_tables.t_status.addr)); + le32toh(newcbd->cmds[i].cmd_tables->t_msgin.addr), + le32toh(newcbd->cmds[i].cmd_tables->t_msgout.addr), + le32toh(newcbd->cmds[i].cmd_tables->t_status.addr)); #endif } s = splbio(); TAILQ_INSERT_TAIL(&sc->cmds, newcbd, next); - sc->sc_adapt.adapt_openings += SIOP_NCMDPB; + sc->sc_c.sc_adapt.adapt_openings += SIOP_NCMDPB; splx(s); return; bad0: - bus_dmamap_unload(sc->sc_dmat, newcbd->xferdma); - bus_dmamap_destroy(sc->sc_dmat, newcbd->xferdma); + bus_dmamap_unload(sc->sc_c.sc_dmat, newcbd->xferdma); + bus_dmamap_destroy(sc->sc_c.sc_dmat, newcbd->xferdma); bad1: - bus_dmamem_free(sc->sc_dmat, &seg, rseg); + bus_dmamem_free(sc->sc_c.sc_dmat, &seg, rseg); bad2: free(newcbd->cmds, M_DEVBUF); bad3: @@ -1698,20 +1740,21 @@ siop_get_lunsw(sc) #ifdef SIOP_DEBUG printf("allocating lunsw at offset %d\n", sc->script_free_lo); #endif - if (sc->features & SF_CHIP_RAM) { - bus_space_write_region_4(sc->sc_ramt, sc->sc_ramh, + if (sc->sc_c.features & SF_CHIP_RAM) { + bus_space_write_region_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh, sc->script_free_lo * 4, lun_switch, sizeof(lun_switch) / sizeof(lun_switch[0])); - bus_space_write_4(sc->sc_ramt, sc->sc_ramh, + bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh, (sc->script_free_lo + E_abs_lunsw_return_Used[0]) * 4, - sc->sc_scriptaddr + Ent_lunsw_return); + sc->sc_c.sc_scriptaddr + Ent_lunsw_return); } else { for (i = 0; i < sizeof(lun_switch) / sizeof(lun_switch[0]); i++) - sc->sc_script[sc->script_free_lo + i] = + sc->sc_c.sc_script[sc->script_free_lo + i] = htole32(lun_switch[i]); - sc->sc_script[sc->script_free_lo + E_abs_lunsw_return_Used[0]] = - htole32(sc->sc_scriptaddr + Ent_lunsw_return); + sc->sc_c.sc_script[ + sc->script_free_lo + E_abs_lunsw_return_Used[0]] = + htole32(sc->sc_c.sc_scriptaddr + Ent_lunsw_return); } lunsw->lunsw_off = sc->script_free_lo; lunsw->lunsw_size = sizeof(lun_switch) / sizeof(lun_switch[0]); @@ -1726,25 +1769,28 @@ siop_add_reselsw(sc, target) int target; { int i; + struct siop_target *siop_target; struct siop_lun *siop_lun; + + siop_target = (struct siop_target *)sc->sc_c.targets[target]; /* * add an entry to resel switch */ siop_script_sync(sc, BUS_DMASYNC_POSTWRITE); for (i = 0; i < 15; i++) { - sc->targets[target]->reseloff = Ent_resel_targ0 / 4 + i * 2; - if ((siop_script_read(sc, sc->targets[target]->reseloff) & 0xff) + siop_target->reseloff = Ent_resel_targ0 / 4 + i * 2; + if ((siop_script_read(sc, siop_target->reseloff) & 0xff) == 0xff) { /* it's free */ #ifdef SIOP_DEBUG printf("siop: target %d slot %d offset %d\n", - target, i, sc->targets[target]->reseloff); + target, i, siop_target->reseloff); #endif /* JUMP abs_foo, IF target | 0x80; */ - siop_script_write(sc, sc->targets[target]->reseloff, + siop_script_write(sc, siop_target->reseloff, 0x800c0080 | target); - siop_script_write(sc, sc->targets[target]->reseloff + 1, - sc->sc_scriptaddr + - sc->targets[target]->lunsw->lunsw_off * 4 + + siop_script_write(sc, siop_target->reseloff + 1, + sc->sc_c.sc_scriptaddr + + siop_target->lunsw->lunsw_off * 4 + Ent_lun_switch_entry); break; } @@ -1754,7 +1800,7 @@ siop_add_reselsw(sc, target) sc->sc_ntargets++; for (i = 0; i < 8; i++) { - siop_lun = sc->targets[target]->siop_lun[i]; + siop_lun = siop_target->siop_lun[i]; if (siop_lun == NULL) continue; if (siop_lun->reseloff > 0) { @@ -1762,23 +1808,24 @@ siop_add_reselsw(sc, target) siop_add_dev(sc, target, i); } } - siop_update_scntl3(sc, sc->targets[target]); + siop_update_scntl3(sc, sc->sc_c.targets[target]); siop_script_sync(sc, BUS_DMASYNC_PREWRITE); } void -siop_update_scntl3(sc, siop_target) +siop_update_scntl3(sc, _siop_target) struct siop_softc *sc; - struct siop_target *siop_target; + struct siop_common_target *_siop_target; { + struct siop_target *siop_target = (struct siop_target *)_siop_target; /* MOVE target->id >> 24 TO SCNTL3 */ siop_script_write(sc, siop_target->lunsw->lunsw_off + (Ent_restore_scntl3 / 4), - 0x78030000 | ((siop_target->id >> 16) & 0x0000ff00)); + 0x78030000 | ((siop_target->target_c.id >> 16) & 0x0000ff00)); /* MOVE target->id >> 8 TO SXFER */ siop_script_write(sc, siop_target->lunsw->lunsw_off + (Ent_restore_scntl3 / 4) + 2, - 0x78050000 | (siop_target->id & 0x0000ff00)); + 0x78050000 | (siop_target->target_c.id & 0x0000ff00)); siop_script_sync(sc, BUS_DMASYNC_PREWRITE); } @@ -1789,12 +1836,14 @@ siop_add_dev(sc, target, lun) int lun; { struct siop_lunsw *lunsw; - struct siop_lun *siop_lun = sc->targets[target]->siop_lun[lun]; + struct siop_target *siop_target = + (struct siop_target *)sc->sc_c.targets[target]; + struct siop_lun *siop_lun = siop_target->siop_lun[lun]; int i, ntargets; if (siop_lun->reseloff > 0) return; - lunsw = sc->targets[target]->lunsw; + lunsw = siop_target->lunsw; if ((lunsw->lunsw_off + lunsw->lunsw_size) < sc->script_free_lo) { /* * can't extend this slot. Probably not worth trying to deal @@ -1802,12 +1851,12 @@ siop_add_dev(sc, target, lun) */ #ifdef DEBUG printf("%s:%d:%d: can't allocate a lun sw slot\n", - sc->sc_dev.dv_xname, target, lun); + sc->sc_c.sc_dev.dv_xname, target, lun); #endif return; } /* count how many free targets we still have to probe */ - ntargets = sc->sc_chan.chan_ntargets - 1 - sc->sc_ntargets; + ntargets = sc->sc_c.sc_chan.chan_ntargets - 1 - sc->sc_ntargets; /* * we need 8 bytes for the lun sw additionnal entry, and @@ -1817,7 +1866,7 @@ siop_add_dev(sc, target, lun) */ if (sc->script_free_lo + 2 + (ntargets * sizeof(lun_switch) / sizeof(lun_switch[0])) >= - ((sc->targets[target]->flags & TARF_TAG) ? + ((siop_target->target_c.flags & TARF_TAG) ? sc->script_free_hi - (sizeof(tag_switch) / sizeof(tag_switch[0])) : sc->script_free_hi)) { /* @@ -1826,13 +1875,13 @@ siop_add_dev(sc, target, lun) */ #ifdef DEBUG printf("%s:%d:%d: not enouth memory for a lun sw slot\n", - sc->sc_dev.dv_xname, target, lun); + sc->sc_c.sc_dev.dv_xname, target, lun); #endif return; } #ifdef SIOP_DEBUG printf("%s:%d:%d: allocate lun sw entry\n", - sc->sc_dev.dv_xname, target, lun); + sc->sc_c.sc_dev.dv_xname, target, lun); #endif /* INT int_resellun */ siop_script_write(sc, sc->script_free_lo, 0x98080000); @@ -1844,25 +1893,26 @@ siop_add_dev(sc, target, lun) siop_lun->reseloff = sc->script_free_lo - 2; lunsw->lunsw_size += 2; sc->script_free_lo += 2; - if (sc->targets[target]->flags & TARF_TAG) { + if (siop_target->target_c.flags & TARF_TAG) { /* we need a tag switch */ sc->script_free_hi -= sizeof(tag_switch) / sizeof(tag_switch[0]); - if (sc->features & SF_CHIP_RAM) { - bus_space_write_region_4(sc->sc_ramt, sc->sc_ramh, + if (sc->sc_c.features & SF_CHIP_RAM) { + bus_space_write_region_4(sc->sc_c.sc_ramt, + sc->sc_c.sc_ramh, sc->script_free_hi * 4, tag_switch, sizeof(tag_switch) / sizeof(tag_switch[0])); } else { for(i = 0; i < sizeof(tag_switch) / sizeof(tag_switch[0]); i++) { - sc->sc_script[sc->script_free_hi + i] = + sc->sc_c.sc_script[sc->script_free_hi + i] = htole32(tag_switch[i]); } } siop_script_write(sc, siop_lun->reseloff + 1, - sc->sc_scriptaddr + sc->script_free_hi * 4 + + sc->sc_c.sc_scriptaddr + sc->script_free_hi * 4 + Ent_tag_switch_entry); for (i = 0; i < SIOP_NTAG; i++) { @@ -1872,7 +1922,7 @@ siop_add_dev(sc, target, lun) } else { /* non-tag case; just work with the lun switch */ siop_lun->siop_tag[0].reseloff = - sc->targets[target]->siop_lun[lun]->reseloff; + siop_target->siop_lun[lun]->reseloff; } siop_script_sync(sc, BUS_DMASYNC_PREWRITE); } @@ -1884,62 +1934,39 @@ siop_del_dev(sc, target, lun) int lun; { int i; + struct siop_target *siop_target; #ifdef SIOP_DEBUG printf("%s:%d:%d: free lun sw entry\n", - sc->sc_dev.dv_xname, target, lun); + sc->sc_c.sc_dev.dv_xname, target, lun); #endif - if (sc->targets[target] == NULL) + if (sc->sc_c.targets[target] == NULL) return; - free(sc->targets[target]->siop_lun[lun], M_DEVBUF); - sc->targets[target]->siop_lun[lun] = NULL; + siop_target = (struct siop_target *)sc->sc_c.targets[target]; + free(siop_target->siop_lun[lun], M_DEVBUF); + siop_target->siop_lun[lun] = NULL; /* XXX compact sw entry too ? */ /* check if we can free the whole target */ for (i = 0; i < 8; i++) { - if (sc->targets[target]->siop_lun[i] != NULL) + if (siop_target->siop_lun[i] != NULL) return; } #ifdef SIOP_DEBUG printf("%s: free siop_target for target %d lun %d lunsw offset %d\n", - sc->sc_dev.dv_xname, target, lun, - sc->targets[target]->lunsw->lunsw_off); + sc->sc_c.sc_dev.dv_xname, target, lun, + sc->sc_c.targets[target]->lunsw->lunsw_off); #endif /* * nothing here, free the target struct and resel * switch entry */ - siop_script_write(sc, sc->targets[target]->reseloff, 0x800c00ff); + siop_script_write(sc, siop_target->reseloff, 0x800c00ff); siop_script_sync(sc, BUS_DMASYNC_PREWRITE); - TAILQ_INSERT_TAIL(&sc->lunsw_list, sc->targets[target]->lunsw, next); - free(sc->targets[target], M_DEVBUF); - sc->targets[target] = NULL; + TAILQ_INSERT_TAIL(&sc->lunsw_list, siop_target->lunsw, next); + free(sc->sc_c.targets[target], M_DEVBUF); + sc->sc_c.targets[target] = NULL; sc->sc_ntargets--; } -void -siop_update_xfer_mode(sc, target) - struct siop_softc *sc; - int target; -{ - struct siop_target *siop_target = sc->targets[target]; - struct scsipi_xfer_mode xm; - - xm.xm_target = target; - xm.xm_mode = 0; - xm.xm_period = 0; - xm.xm_offset = 0; - - if (siop_target->flags & TARF_ISWIDE) - xm.xm_mode |= PERIPH_CAP_WIDE16; - if (siop_target->period) { - xm.xm_period = siop_target->period; - xm.xm_offset = siop_target->offset; - xm.xm_mode |= PERIPH_CAP_SYNC; - } - if (siop_target->flags & TARF_TAG) - xm.xm_mode |= PERIPH_CAP_TQING; - scsipi_async_event(&sc->sc_chan, ASYNC_EVENT_XFER_MODE, &xm); -} - #ifdef SIOP_STATS void siop_printstats()