Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Separate the sheduler from the main script, allocate...
details: https://anonhg.NetBSD.org/src/rev/6d0496b38074
branches: trunk
changeset: 486545:6d0496b38074
user: bouyer <bouyer%NetBSD.org@localhost>
date: Thu May 25 10:10:54 2000 +0000
description:
Separate the sheduler from the main script, allocate another DMA-safe
memory page for the sheduler. Put the main script in the on-chip RAM when
available.
Avoid a null-pointer dereference when DSA is invalid.
diffstat:
sys/dev/ic/siop.c | 163 +++++++++++++++++++++++++++-------------
sys/dev/ic/siopvar.h | 7 +-
sys/dev/microcode/siop/siop.ss | 13 +--
sys/dev/pci/siop_pci_common.c | 31 +++++--
4 files changed, 142 insertions(+), 72 deletions(-)
diffs (truncated from 506 to 300 lines):
diff -r 8b19550d5373 -r 6d0496b38074 sys/dev/ic/siop.c
--- a/sys/dev/ic/siop.c Thu May 25 09:09:28 2000 +0000
+++ b/sys/dev/ic/siop.c Thu May 25 10:10:54 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: siop.c,v 1.16 2000/05/23 17:08:07 bouyer Exp $ */
+/* $NetBSD: siop.c,v 1.17 2000/05/25 10:10:56 bouyer Exp $ */
/*
* Copyright (c) 2000 Manuel Bouyer.
@@ -125,13 +125,13 @@
sizeof(struct siop_xfer), ops);
}
-static __inline__ void siop_script_sync __P((struct siop_softc *, int));
+static __inline__ void siop_shed_sync __P((struct siop_softc *, int));
static __inline__ void
-siop_script_sync(sc, ops)
+siop_shed_sync(sc, ops)
struct siop_softc *sc;
int ops;
{
- bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, 0, NBPG, ops);
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_sheddma, 0, NBPG, ops);
}
void
@@ -143,34 +143,66 @@
int rseg;
/*
- * Allocate DMA-safe memory for the script itself and internal
- * variables and map it.
+ * Allocate DMA-safe memory for the script and script sheduler
+ * and map it.
*/
+ if ((sc->features & SF_CHIP_RAM) == 0) {
+ error = bus_dmamem_alloc(sc->sc_dmat, NBPG,
+ NBPG, 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, NBPG,
+ (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, NBPG, 1,
+ NBPG, 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,
+ NBPG, 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;
+ }
error = bus_dmamem_alloc(sc->sc_dmat, NBPG,
NBPG, 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);
+ printf("%s: unable to allocate sheduler DMA memory, "
+ "error = %d\n", sc->sc_dev.dv_xname, error);
return;
}
error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, NBPG,
- (caddr_t *)&sc->sc_script, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
+ (caddr_t *)&sc->sc_shed, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
if (error) {
- printf("%s: unable to map script DMA memory, error = %d\n",
+ printf("%s: unable to map sheduler 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_scriptdma);
+ NBPG, 0, BUS_DMA_NOWAIT, &sc->sc_sheddma);
if (error) {
- printf("%s: unable to create script DMA map, error = %d\n",
+ printf("%s: unable to create sheduler 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,
+ error = bus_dmamap_load(sc->sc_dmat, sc->sc_sheddma, sc->sc_shed,
NBPG, NULL, BUS_DMA_NOWAIT);
if (error) {
- printf("%s: unable to load script DMA map, error = %d\n",
+ printf("%s: unable to load sheduler DMA map, error = %d\n",
sc->sc_dev.dv_xname, error);
return;
}
@@ -178,17 +210,14 @@
TAILQ_INIT(&sc->cmds);
/* compute number of sheduler slots */
sc->sc_nshedslots = (
- NBPG /* memory size allocated for scripts */
- - sizeof(siop_script) /* memory for main script */
- + 8 /* extra NOP at end of main script */
+ NBPG /* memory size allocated for sheduler */
- sizeof(endslot_script) /* memory needed at end of sheduler */
) / (sizeof(slot_script) - 8);
sc->sc_currshedslot = 0;
#ifdef DEBUG
printf("%s: script size = %d, PHY addr=0x%x, VIRT=%p nslots %d\n",
sc->sc_dev.dv_xname, (int)sizeof(siop_script),
- (u_int)sc->sc_scriptdma->dm_segs[0].ds_addr, sc->sc_script,
- sc->sc_nshedslots);
+ sc->sc_ramaddr, sc->sc_script, sc->sc_nshedslots);
#endif
sc->sc_link.adapter_softc = sc;
@@ -243,14 +272,35 @@
siop_common_reset(sc);
/* copy and patch the script */
- for (j = 0; j < (sizeof(siop_script) / sizeof(siop_script[0])); j++) {
- sc->sc_script[j] = htole32(siop_script[j]);
+ if (sc->features & SF_CHIP_RAM) {
+ bus_space_write_region_4(sc->sc_ramt, sc->sc_ramh, 0,
+ siop_script, sizeof(siop_script) / sizeof(siop_script[0]));
+ for (j = 0; j <
+ (sizeof(E_script_abs_shed_Used) /
+ sizeof(E_script_abs_shed_Used[0]));
+ j++) {
+ bus_space_write_4(sc->sc_ramt, sc->sc_ramh,
+ E_script_abs_shed_Used[j] * 4,
+ sc->sc_sheddma->dm_segs[0].ds_addr);
+ }
+ } else {
+ for (j = 0;
+ j < (sizeof(siop_script) / sizeof(siop_script[0])); j++) {
+ sc->sc_script[j] = htole32(siop_script[j]);
+ }
+ for (j = 0; j <
+ (sizeof(E_script_abs_shed_Used) /
+ 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);
+ }
}
- /* copy the sheduler slots script */
+ /* copy and init the sheduler slots script */
for (i = 0; i < sc->sc_nshedslots; i++) {
- scr = &sc->sc_script[Ent_sheduler / 4 + (Ent_nextslot / 4) * i];
- physaddr = sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_sheduler
- + Ent_nextslot * i;
+ scr = &sc->sc_shed[(Ent_nextslot / 4) * i];
+ physaddr = sc->sc_sheddma->dm_segs[0].ds_addr +
+ Ent_nextslot * i;
for (j = 0; j < (sizeof(slot_script) / sizeof(slot_script[0]));
j++) {
scr[j] = htole32(slot_script[j]);
@@ -265,37 +315,38 @@
Ent_slotdata + 4);
/* JUMP selected, in main script */
scr[E_slot_abs_selected_Used[0]] =
- htole32(sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_selected);
+ htole32(sc->sc_scriptaddr + Ent_selected);
/* JUMP addr if SELECT fail */
scr[E_slot_abs_reselect_Used[0]] =
- htole32(sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_reselect);
+ htole32(sc->sc_scriptaddr + Ent_reselect);
}
/* Now the final JUMP */
- scr = &sc->sc_script[Ent_sheduler / 4 +
- (Ent_nextslot / 4) * sc->sc_nshedslots];
+ scr = &sc->sc_shed[(Ent_nextslot / 4) * sc->sc_nshedslots];
for (j = 0; j < (sizeof(endslot_script) / sizeof(endslot_script[0]));
j++) {
scr[j] = htole32(endslot_script[j]);
}
scr[E_endslot_abs_reselect_Used[0]] =
- htole32(sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_reselect);
+ htole32(sc->sc_scriptaddr + Ent_reselect);
/* start script */
- siop_script_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, 0, NBPG,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ siop_shed_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP,
- sc->sc_scriptdma->dm_segs[0].ds_addr + Ent_reselect);
+ sc->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_scriptdma->dm_segs[0].ds_addr + ent); \
-bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->sc_scriptdma->dm_segs[0].ds_addr + ent); \
+ sc->sc_scriptaddr + ent); \
+bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->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_scriptdma->dm_segs[0].ds_addr + ent); \
+bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->sc_scriptaddr + ent); \
} while (0)
#endif
@@ -346,7 +397,7 @@
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_scriptdma->dm_segs[0].ds_addr),
+ sc->sc_scriptaddr),
bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA));
if ((dstat & ~(DSTAT_DFE | DSTAT_SSI)) == 0 &&
(istat & ISTAT_SIP) == 0) {
@@ -370,11 +421,11 @@
printf(" dma fifo empty");
printf(", DSP=0x%x DSA=0x%x: ",
(int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
- sc->sc_scriptdma->dm_segs[0].ds_addr),
+ sc->sc_scriptaddr),
bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA));
p = sc->sc_script +
(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
- sc->sc_scriptdma->dm_segs[0].ds_addr - 8) / 4;
+ sc->sc_scriptaddr - 8) / 4;
printf("0x%x 0x%x 0x%x 0x%x\n", le32toh(p[0]), le32toh(p[1]),
le32toh(p[2]), le32toh(p[3]));
if (siop_cmd)
@@ -389,7 +440,7 @@
* SCSI interrupt. If current command is not active,
* we don't need siop_cmd
*/
- if (siop_cmd->status != CMDST_ACTIVE &&
+ if (siop_cmd && siop_cmd->status != CMDST_ACTIVE &&
siop_cmd->status != CMDST_SENSE_ACTIVE) {
siop_cmd = NULL;
}
@@ -405,7 +456,7 @@
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_scriptdma->dm_segs[0].ds_addr));
+ sc->sc_scriptaddr));
#endif
if (siop_cmd) {
xs = siop_cmd->xs;
@@ -519,7 +570,7 @@
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_scriptdma->dm_segs[0].ds_addr));
+ sc->sc_scriptaddr));
if (siop_cmd) {
siop_cmd->status = CMDST_DONE;
xs->error = XS_SELTIMEOUT;
@@ -571,8 +622,8 @@
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_scriptdma->dm_segs[0].ds_addr));
+ (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh,
+ SIOP_DSP) - sc->sc_scriptaddr));
if (xs) {
xs->error = XS_SELTIMEOUT;
goto end;
@@ -815,18 +866,22 @@
siop_table_sync(siop_cmd,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
}
- CALL_SCRIPT(Ent_sheduler);
+ bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP,
+ sc->sc_sheddma->dm_segs[0].ds_addr);
return 1;
case A_int_resfail:
printf("reselect failed\n");
- CALL_SCRIPT(Ent_sheduler);
+ bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP,
+ sc->sc_sheddma->dm_segs[0].ds_addr);
return 1;
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;
- CALL_SCRIPT(Ent_sheduler);
+ bus_space_write_4(sc->sc_rt, sc->sc_rh,
+ SIOP_DSP,
+ sc->sc_sheddma->dm_segs[0].ds_addr);
siop_start(sc);
return 1;
Home |
Main Index |
Thread Index |
Old Index