summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorbouyer <bouyer@NetBSD.org>2000-10-06 16:35:13 +0000
committerbouyer <bouyer@NetBSD.org>2000-10-06 16:35:13 +0000
commite353a6d9b20c4fee59842d2289a37b8ca705f0a7 (patch)
tree2e3c5b3990c7475dd9739d82fb0adf957f5e76ff /sys/dev
parenteae96f0267f9e80431d514727ad0e6317df3eaae (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.c134
-rw-r--r--sys/dev/ic/siop_common.c18
-rw-r--r--sys/dev/ic/siopreg.h12
-rw-r--r--sys/dev/ic/siopvar.h6
-rw-r--r--sys/dev/ic/siopvar_common.h3
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 */