diff options
| author | bouyer <bouyer@NetBSD.org> | 2000-10-06 16:35:13 +0000 |
|---|---|---|
| committer | bouyer <bouyer@NetBSD.org> | 2000-10-06 16:35:13 +0000 |
| commit | e353a6d9b20c4fee59842d2289a37b8ca705f0a7 (patch) | |
| tree | 2e3c5b3990c7475dd9739d82fb0adf957f5e76ff /sys/dev | |
| parent | eae96f0267f9e80431d514727ad0e6317df3eaae (diff) | |
Adapt for reselect handling from the script. While here, fix typo
(SIOP_SCXFER -> SIOP_SXFER).
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ic/siop.c | 134 | ||||
| -rw-r--r-- | sys/dev/ic/siop_common.c | 18 | ||||
| -rw-r--r-- | sys/dev/ic/siopreg.h | 12 | ||||
| -rw-r--r-- | sys/dev/ic/siopvar.h | 6 | ||||
| -rw-r--r-- | sys/dev/ic/siopvar_common.h | 3 |
5 files changed, 137 insertions, 36 deletions
diff --git a/sys/dev/ic/siop.c b/sys/dev/ic/siop.c index e77c630f0c2..c2a3d43f5ed 100644 --- a/sys/dev/ic/siop.c +++ b/sys/dev/ic/siop.c @@ -1,4 +1,4 @@ -/* $NetBSD: siop.c,v 1.27 2000/07/27 21:28:17 bouyer Exp $ */ +/* $NetBSD: siop.c,v 1.28 2000/10/06 16:35:13 bouyer Exp $ */ /* * Copyright (c) 2000 Manuel Bouyer. @@ -54,7 +54,7 @@ #include <dev/ic/siopvar.h> #include <dev/ic/siopvar_common.h> -#undef DEBUG +#define DEBUG #undef DEBUG_DR #undef DEBUG_INTR #undef DEBUG_SHED @@ -128,7 +128,16 @@ siop_shed_sync(sc, ops) struct siop_softc *sc; int ops; { - bus_dmamap_sync(sc->sc_dmat, sc->sc_sheddma, 0, NBPG, ops); + bus_dmamap_sync(sc->sc_dmat, sc->sc_sheddma, 0, 2*NBPG, ops); +} + +static __inline__ void siop_resel_sync __P((struct siop_softc *, int)); +static __inline__ void +siop_resel_sync(sc, ops) + struct siop_softc *sc; + int ops; +{ + bus_dmamap_sync(sc->sc_dmat, sc->sc_sheddma, NBPG, NBPG, ops); } void @@ -175,34 +184,35 @@ siop_attach(sc) } sc->sc_scriptaddr = sc->sc_scriptdma->dm_segs[0].ds_addr; } - error = bus_dmamem_alloc(sc->sc_dmat, NBPG, - NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT); + error = bus_dmamem_alloc(sc->sc_dmat, 2 * NBPG, + 2 * NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT); if (error) { printf("%s: unable to allocate scheduler DMA memory, " "error = %d\n", sc->sc_dev.dv_xname, error); return; } - error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, NBPG, + error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, 2 * NBPG, (caddr_t *)&sc->sc_shed, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); if (error) { printf("%s: unable to map scheduler DMA memory, error = %d\n", sc->sc_dev.dv_xname, error); return; } - error = bus_dmamap_create(sc->sc_dmat, NBPG, 1, - NBPG, 0, BUS_DMA_NOWAIT, &sc->sc_sheddma); + error = bus_dmamap_create(sc->sc_dmat, 2 * NBPG, 1, + 2 * NBPG, 0, BUS_DMA_NOWAIT, &sc->sc_sheddma); if (error) { printf("%s: unable to create scheduler DMA map, error = %d\n", sc->sc_dev.dv_xname, error); return; } error = bus_dmamap_load(sc->sc_dmat, sc->sc_sheddma, sc->sc_shed, - NBPG, NULL, BUS_DMA_NOWAIT); + 2 * NBPG, NULL, BUS_DMA_NOWAIT); if (error) { printf("%s: unable to load scheduler DMA map, error = %d\n", sc->sc_dev.dv_xname, error); return; } + sc->sc_resel = &sc->sc_shed[NBPG / sizeof(int32_t)]; TAILQ_INIT(&sc->free_list); TAILQ_INIT(&sc->cmds); /* compute number of scheduler slots */ @@ -211,10 +221,17 @@ siop_attach(sc) - sizeof(endslot_script) /* memory needed at end of scheduler */ ) / (sizeof(slot_script) - 8); sc->sc_currshedslot = 0; + /* compute number of reselect slots */ + sc->sc_nreselslots = ( + NBPG /* memory size allocated for reselect script */ + - sizeof(reselected_end_script) /* memory needed at end */ + ) / (sizeof(reselected_script) - 16); #ifdef DEBUG - printf("%s: script size = %d, PHY addr=0x%x, VIRT=%p nslots %d\n", + printf("%s: script size = %d, PHY addr=0x%x, VIRT=%p nslots %d " + "nresel %d\n", sc->sc_dev.dv_xname, (int)sizeof(siop_script), - sc->sc_scriptaddr, sc->sc_script, sc->sc_nshedslots); + (u_int32_t)sc->sc_scriptaddr, sc->sc_script, sc->sc_nshedslots, + sc->sc_nreselslots); #endif sc->sc_link.adapter_softc = sc; @@ -285,6 +302,14 @@ siop_reset(sc) E_script_abs_shed_Used[j] * 4, sc->sc_sheddma->dm_segs[0].ds_addr); } + for (j = 0; j < + (sizeof(E_abs_find_dsa_Used) / + sizeof(E_abs_find_dsa_Used[0])); + j++) { + bus_space_write_4(sc->sc_ramt, sc->sc_ramh, + E_abs_find_dsa_Used[j] * 4, + sc->sc_sheddma->dm_segs[0].ds_addr + NBPG); + } } else { for (j = 0; j < (sizeof(siop_script) / sizeof(siop_script[0])); j++) { @@ -295,7 +320,14 @@ siop_reset(sc) sizeof(E_script_abs_shed_Used[0])); j++) { sc->sc_script[E_script_abs_shed_Used[j]] = - htole32(sc->sc_sheddma->dm_segs[0].ds_addr); + htole32(sc->sc_sheddma->dm_segs[0].ds_addr); + } + for (j = 0; j < + (sizeof(E_abs_find_dsa_Used) / + sizeof(E_abs_find_dsa_Used[0])); + j++) { + sc->sc_script[E_abs_find_dsa_Used[j]] = + htole32(sc->sc_sheddma->dm_segs[0].ds_addr + NBPG); } } /* copy and init the scheduler slots script */ @@ -331,6 +363,25 @@ siop_reset(sc) scr[E_endslot_abs_reselect_Used[0]] = htole32(sc->sc_scriptaddr + Ent_reselect); + /* The reselect script */ + for (i = 0; i < sc->sc_nreselslots; i++) { + scr = &sc->sc_resel[(Ent_res_nextld / 4) * i]; + for (j = 0; j < + (sizeof(reselected_script) / sizeof(reselected_script[0])); + j++) { + scr[j] = htole32(reselected_script[j]); + } + scr[E_resel_abs_selected_Used[0]] = + htole32(sc->sc_scriptaddr + Ent_selected); + } + /* The final int */ + scr = &sc->sc_resel[(Ent_res_nextld / 4) * sc->sc_nreselslots]; + for (j = 0; j < + (sizeof(reselected_end_script) / sizeof(reselected_end_script[0])); + j++) { + scr[j] = htole32(reselected_end_script[j]); + } + /* start script */ if ((sc->features & SF_CHIP_RAM) == 0) { bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, 0, NBPG, @@ -866,7 +917,7 @@ scintr: siop_cmd->dsa); bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCNTL3, (sc->targets[target]->id >> 24) & 0xff); - bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCXFER, + bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SXFER, (sc->targets[target]->id >> 8) & 0xff); /* no table to flush */ CALL_SCRIPT(Ent_selected); @@ -988,7 +1039,16 @@ siop_scsicmd_end(siop_cmd) { struct scsipi_xfer *xs = siop_cmd->xs; struct siop_softc *sc = siop_cmd->siop_target->siop_sc; + u_int32_t *scr; + /* remove from reselect slot */ + siop_resel_sync(sc, BUS_DMASYNC_POSTWRITE); +#ifdef DEBUG_SHED + printf("freeing resel %d\n", siop_cmd->reselslot); +#endif + scr = &sc->sc_resel[(Ent_res_nextld / 4) * siop_cmd->reselslot]; + scr[Ent_rtarget / 4] = htole32(0x808400ff); + siop_resel_sync(sc, BUS_DMASYNC_PREWRITE); if (siop_cmd->status != CMDST_SENSE_DONE && xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { bus_dmamap_sync(sc->sc_dmat, siop_cmd->dmamap_data, 0, @@ -1271,10 +1331,10 @@ siop_start(sc) struct siop_softc *sc; { struct siop_cmd *siop_cmd; - u_int32_t *scr; + u_int32_t *scr, *rscr; u_int32_t dsa; int timeout; - int target, lun, slot; + int target, lun, slot, resel; int newcmd = 0; /* @@ -1318,6 +1378,22 @@ siop_start(sc) if (siop_cmd->status != CMDST_READY && siop_cmd->status != CMDST_SENSE) continue; + /* find a reselect slot */ + for (resel = 0; resel < sc->sc_nreselslots; resel++) { + /* if target is 0xff the slot is free */ + rscr = &sc->sc_resel[ + (Ent_res_nextld / 4) * resel]; + if ((htole32(rscr[Ent_rtarget / 4]) & 0xff) + == 0xff) + break; + } + if (resel == sc->sc_nreselslots) { +#ifdef DEBUG + printf("%s: out of reselect slot\n", + sc->sc_dev.dv_xname); +#endif + goto end; /* no free slot */ + } /* find a free scheduler slot and load it */ for (; slot < sc->sc_nshedslots; slot++) { scr = &sc->sc_shed[(Ent_nextslot / 4) * slot]; @@ -1328,8 +1404,7 @@ siop_start(sc) if (scr[Ent_slot / 4 + 1] == 0) continue; #ifdef DEBUG_SHED - printf("using slot %d for DSA 0x%lx\n", slot, - (u_long)siop_cmd->dsa); + printf("using slot %d resel %d for DSA 0x%lx\n", slot, resel, (u_long)siop_cmd->dsa); #endif /* note that we started a new command */ newcmd = 1; @@ -1340,12 +1415,35 @@ siop_start(sc) siop_cmd->status = CMDST_SENSE_ACTIVE; else panic("siop_start: bad status"); - /* patch script with DSA addr */ + /* patch scripts with DSA addr */ dsa = siop_cmd->dsa; /* + * first reselect script + * 0x808400xx is 'JUMP foo if not 0xxx' + * we need target | 0x80 for the IDENTIFY cmd. + */ + rscr[Ent_rtarget / 4] = + htole32(0x80840080 | target); + rscr[Ent_rlun / 4] = + htole32(0x80840000 | lun); + /* * 0x78000000 is a 'move data8 to reg'. data8 * is the second octet, reg offset is the third. */ + rscr[Ent_rdsa0 / 4] = + htole32(0x78100000 | + ((dsa & 0x000000ff) << 8)); + rscr[Ent_rdsa1 / 4] = + htole32(0x78110000 | + ( dsa & 0x0000ff00 )); + rscr[Ent_rdsa2 / 4] = + htole32(0x78120000 | + ((dsa & 0x00ff0000) >> 8)); + rscr[Ent_rdsa3 / 4] = + htole32(0x78130000 | + ((dsa & 0xff000000) >> 16)); + siop_cmd->reselslot = resel; + /* now scheduler slot */ scr[Ent_idsa0 / 4] = htole32(0x78100000 | ((dsa & 0x000000ff) << 8)); diff --git a/sys/dev/ic/siop_common.c b/sys/dev/ic/siop_common.c index ba2928936f4..336b18c0795 100644 --- a/sys/dev/ic/siop_common.c +++ b/sys/dev/ic/siop_common.c @@ -1,4 +1,4 @@ -/* $NetBSD: siop_common.c,v 1.6 2000/07/24 15:15:01 bouyer Exp $ */ +/* $NetBSD: siop_common.c,v 1.7 2000/10/06 16:35:13 bouyer Exp $ */ /* * Copyright (c) 2000 Manuel Bouyer. @@ -72,7 +72,7 @@ siop_common_reset(sc) SCNTL0_ARB_MASK | SCNTL0_EPC | SCNTL0_AAP); bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCNTL1, 0); bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCNTL3, sc->clock_div); - bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCXFER, 0); + bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SXFER, 0); bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_DIEN, 0xff); bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SIEN0, 0xff & ~(SIEN0_CMP | SIEN0_SEL | SIEN0_RSL)); @@ -263,9 +263,9 @@ siop_sdtr_neg(siop_cmd) sc->targets[target]->id &= ~(SCNTL3_ULTRA << 24); sc->targets[target]->id &= - ~(SCXFER_MO_MASK << 8); + ~(SXFER_MO_MASK << 8); sc->targets[target]->id |= - (offset & SCXFER_MO_MASK) << 8; + (offset & SXFER_MO_MASK) << 8; goto end; } } @@ -281,7 +281,7 @@ reject: target); sc->targets[target]->id &= ~(SCNTL3_SCF_MASK << 24); sc->targets[target]->id &= ~(SCNTL3_ULTRA << 24); - sc->targets[target]->id &= ~(SCXFER_MO_MASK << 8); + sc->targets[target]->id &= ~(SXFER_MO_MASK << 8); } else { /* target initiated sync neg */ #ifdef DEBUG printf("sdtr (target): sync %d offset %d\n", sync, offset); @@ -314,9 +314,9 @@ reject: sc->targets[target]->id &= ~(SCNTL3_ULTRA << 24); sc->targets[target]->id &= - ~(SCXFER_MO_MASK << 8); + ~(SXFER_MO_MASK << 8); sc->targets[target]->id |= - (offset & SCXFER_MO_MASK) << 8; + (offset & SXFER_MO_MASK) << 8; siop_cmd->siop_table->msg_out[0] = MSG_EXTENDED; siop_cmd->siop_table->msg_out[1] = MSG_EXT_SDTR_LEN; @@ -334,7 +334,7 @@ async: sc->sc_dev.dv_xname, target); sc->targets[target]->id &= ~(SCNTL3_SCF_MASK << 24); sc->targets[target]->id &= ~(SCNTL3_ULTRA << 24); - sc->targets[target]->id &= ~(SCXFER_MO_MASK << 8); + sc->targets[target]->id &= ~(SXFER_MO_MASK << 8); siop_cmd->siop_table->msg_out[0] = MSG_EXTENDED; siop_cmd->siop_table->msg_out[1] = MSG_EXT_SDTR_LEN; siop_cmd->siop_table->msg_out[2] = MSG_EXT_SDTR; @@ -351,7 +351,7 @@ end: siop_cmd->siop_table->id = htole32(sc->targets[target]->id); bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCNTL3, (sc->targets[target]->id >> 24) & 0xff); - bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCXFER, + bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SXFER, (sc->targets[target]->id >> 8) & 0xff); if (send_msgout) { siop_cmd->siop_table->t_msgout.addr = htole32(siop_cmd->dsa); diff --git a/sys/dev/ic/siopreg.h b/sys/dev/ic/siopreg.h index aa8b9aa86dc..e7f41445105 100644 --- a/sys/dev/ic/siopreg.h +++ b/sys/dev/ic/siopreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: siopreg.h,v 1.6 2000/06/12 20:13:41 bouyer Exp $ */ +/* $NetBSD: siopreg.h,v 1.7 2000/10/06 16:35:13 bouyer Exp $ */ /* * Copyright (c) 2000 Manuel Bouyer. @@ -103,11 +103,11 @@ static const struct scf_period scf_period[] __attribute__((__unused__)) = { #define SCID_ENCID_SHIFT 0 #define SCID_ENCID_MASK 0x07 -#define SIOP_SCXFER 0x05 /* SCSI transfer, R/W */ -#define SCXFER_TP_SHIFT 5 -#define SCXFER_TP_MASK 0xe0 -#define SCXFER_MO_SHIFT 0 -#define SCXFER_MO_MASK 0x1f +#define SIOP_SXFER 0x05 /* SCSI transfer, R/W */ +#define SXFER_TP_SHIFT 5 +#define SXFER_TP_MASK 0xe0 +#define SXFER_MO_SHIFT 0 +#define SXFER_MO_MASK 0x1f #define SIOP_SDID 0x06 /* SCSI destiation ID, R/W */ #define SDID_ENCID_SHIFT 0 diff --git a/sys/dev/ic/siopvar.h b/sys/dev/ic/siopvar.h index 24b1771ed19..55276fdd47c 100644 --- a/sys/dev/ic/siopvar.h +++ b/sys/dev/ic/siopvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: siopvar.h,v 1.8 2000/06/13 13:59:17 bouyer Exp $ */ +/* $NetBSD: siopvar.h,v 1.9 2000/10/06 16:35:13 bouyer Exp $ */ /* * Copyright (c) 2000 Manuel Bouyer. @@ -55,11 +55,13 @@ struct siop_softc { bus_dma_tag_t sc_dmat; /* bus DMA tag */ void (*sc_reset) __P((struct siop_softc*)); /* reset callback */ bus_dmamap_t sc_scriptdma; /* DMA map for script */ - bus_dmamap_t sc_sheddma; /* DMA map for scheduler script */ + bus_dmamap_t sc_sheddma; /* DMA map for sched and resel script */ u_int32_t *sc_script; /* script location in memory */ u_int32_t *sc_shed; /* script scheduler location in mem */ + u_int32_t *sc_resel; /* reselect script location in mem */ int sc_nshedslots; /* number of scheduler slots */ int sc_currshedslot; /* current scheduler slot */ + int sc_nreselslots; /* number of reselect slots */ struct cbd_list cmds; /* list of command block descriptors */ struct cmd_list free_list; /* cmd descr free list */ struct siop_target *targets[16]; /* per-target states */ diff --git a/sys/dev/ic/siopvar_common.h b/sys/dev/ic/siopvar_common.h index c90f69261fa..91f91f9e592 100644 --- a/sys/dev/ic/siopvar_common.h +++ b/sys/dev/ic/siopvar_common.h @@ -1,4 +1,4 @@ -/* $NetBSD: siopvar_common.h,v 1.4 2000/07/24 15:15:01 bouyer Exp $ */ +/* $NetBSD: siopvar_common.h,v 1.5 2000/10/06 16:35:13 bouyer Exp $ */ /* * Copyright (c) 2000 Manuel Bouyer. @@ -83,6 +83,7 @@ struct siop_cmd { struct scsipi_sense rs_cmd; /* request sense command buffer */ int status; int flags; + int reselslot; /* the reselect slot used */ }; /* command block descriptors: an array of siop_cmd + an array of siop_xfer */ |
