Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Allocate dynamically the command block descriptors.
details: https://anonhg.NetBSD.org/src/rev/3902ddcd8570
branches: trunk
changeset: 486505:3902ddcd8570
user: bouyer <bouyer%NetBSD.org@localhost>
date: Tue May 23 17:08:07 2000 +0000
description:
Allocate dynamically the command block descriptors.
diffstat:
sys/dev/ic/siop.c | 245 +++++++++++++++++++++++++++++--------------
sys/dev/ic/siopvar.h | 5 +-
sys/dev/ic/siopvar_common.h | 12 +-
3 files changed, 179 insertions(+), 83 deletions(-)
diffs (truncated from 421 to 300 lines):
diff -r 290ba41bf2f0 -r 3902ddcd8570 sys/dev/ic/siop.c
--- a/sys/dev/ic/siop.c Tue May 23 16:47:44 2000 +0000
+++ b/sys/dev/ic/siop.c Tue May 23 17:08:07 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: siop.c,v 1.15 2000/05/15 15:16:59 bouyer Exp $ */
+/* $NetBSD: siop.c,v 1.16 2000/05/23 17:08:07 bouyer Exp $ */
/*
* Copyright (c) 2000 Manuel Bouyer.
@@ -70,11 +70,8 @@
#define SIOP_DEFAULT_TARGET 7
#endif
-#define MEM_SIZE 8192
-#define CMD_OFF 4096
-
-/* initial number of cmd descriptors */
-#define SIOP_NCMD 10
+/* number of cmd descriptors per block */
+#define SIOP_NCMDPB (NBPG / sizeof(struct siop_xfer))
void siop_reset __P((struct siop_softc *));
void siop_handle_reset __P((struct siop_softc *));
@@ -83,6 +80,7 @@
void siop_timeout __P((void *));
int siop_scsicmd __P((struct scsipi_xfer *));
void siop_dump_script __P((struct siop_softc *));
+int siop_morecbd __P((struct siop_softc *));
struct scsipi_adapter siop_adapter = {
0,
@@ -121,8 +119,9 @@
struct siop_softc *sc = siop_cmd->siop_target->siop_sc;
bus_addr_t offset;
- offset = siop_cmd->dsa - sc->sc_scriptdma->dm_segs[0].ds_addr;
- bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, offset,
+ offset = siop_cmd->dsa -
+ siop_cmd->siop_cbdp->xferdma->dm_segs[0].ds_addr;
+ bus_dmamap_sync(sc->sc_dmat, siop_cmd->siop_cbdp->xferdma, offset,
sizeof(struct siop_xfer), ops);
}
@@ -132,7 +131,7 @@
struct siop_softc *sc;
int ops;
{
- bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, 0, CMD_OFF, ops);
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, 0, NBPG, ops);
}
void
@@ -147,94 +146,39 @@
* Allocate DMA-safe memory for the script itself and internal
* variables and map it.
*/
- error = bus_dmamem_alloc(sc->sc_dmat, MEM_SIZE,
+ 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, MEM_SIZE,
+ 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, MEM_SIZE, 1,
- MEM_SIZE, 0, BUS_DMA_NOWAIT, &sc->sc_scriptdma);
+ 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,
- MEM_SIZE, NULL, BUS_DMA_NOWAIT);
+ 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;
}
TAILQ_INIT(&sc->free_list);
- /* allocate cmd list */
- sc->cmds =
- malloc(sizeof(struct siop_cmd) * SIOP_NCMD, M_DEVBUF, M_NOWAIT);
- if (sc->cmds == NULL) {
- printf("%s: can't allocate memory for command descriptors\n",
- sc->sc_dev.dv_xname);
- return;
- }
- for (i = 0; i < SIOP_NCMD; i++) {
- error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, SIOP_NSG,
- MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
- &sc->cmds[i].dmamap_data);
- if (error) {
- printf("%s: unable to create data DMA map for cbd %d\n",
- sc->sc_dev.dv_xname, error);
- return;
- }
- error = bus_dmamap_create(sc->sc_dmat,
- sizeof(struct scsipi_generic), 1,
- sizeof(struct scsipi_generic), 0,
- BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
- &sc->cmds[i].dmamap_cmd);
- if (error) {
- printf("%s: unable to create cmd DMA map for cbd %d\n",
- sc->sc_dev.dv_xname, error);
- return;
- }
- sc->cmds[i].siop_table =
- &((struct siop_xfer *)(&sc->sc_script[CMD_OFF/4]))[i];
- memset(sc->cmds[i].siop_table, 0, sizeof(struct siop_xfer));
- sc->cmds[i].dsa = sc->sc_scriptdma->dm_segs[0].ds_addr +
- CMD_OFF + i * sizeof(struct siop_xfer);
- sc->cmds[i].status = CMDST_FREE;
- sc->cmds[i].siop_table->t_msgout.count= htole32(1);
- sc->cmds[i].siop_table->t_msgout.addr =
- htole32(sc->cmds[i].dsa);
- sc->cmds[i].siop_table->t_msgin.count= htole32(1);
- sc->cmds[i].siop_table->t_msgin.addr =
- htole32(sc->cmds[i].dsa + 8);
- sc->cmds[i].siop_table->t_extmsgin.count= htole32(2);
- sc->cmds[i].siop_table->t_extmsgin.addr =
- htole32(le32toh(sc->cmds[i].siop_table->t_msgin.addr) + 1);
- sc->cmds[i].siop_table->t_msgtag.count= htole32(2);
- sc->cmds[i].siop_table->t_msgtag.addr =
- htole32(le32toh(sc->cmds[i].siop_table->t_msgin.addr) + 1);
- sc->cmds[i].siop_table->t_status.count= htole32(1);
- sc->cmds[i].siop_table->t_status.addr =
- htole32(le32toh(sc->cmds[i].siop_table->t_msgin.addr) + 8);
- TAILQ_INSERT_TAIL(&sc->free_list, &sc->cmds[i], next);
-#ifdef DEBUG
- printf("tables[%d]: out=0x%x in=0x%x status=0x%x\n", i,
- le32toh(sc->cmds[i].siop_table->t_msgin.addr),
- le32toh(sc->cmds[i].siop_table->t_msgout.addr),
- le32toh(sc->cmds[i].siop_table->t_status.addr));
-#endif
- }
+ TAILQ_INIT(&sc->cmds);
/* compute number of sheduler slots */
sc->sc_nshedslots = (
- CMD_OFF /* memory size allocated for scripts */
+ NBPG /* memory size allocated for scripts */
- sizeof(siop_script) /* memory for main script */
+ 8 /* extra NOP at end of main script */
- sizeof(endslot_script) /* memory needed at end of sheduler */
@@ -368,6 +312,7 @@
int need_reset = 0;
int offset, target, lun;
bus_addr_t dsa;
+ struct siop_cbd *cbdp;
istat = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_ISTAT);
if ((istat & (ISTAT_INTF | ISTAT_DIP | ISTAT_SIP)) == 0)
@@ -379,14 +324,18 @@
}
/* use DSA to find the current siop_cmd */
dsa = bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA);
- if (dsa >= sc->sc_scriptdma->dm_segs[0].ds_addr + CMD_OFF &&
- dsa < sc->sc_scriptdma->dm_segs[0].ds_addr + CMD_OFF +
- SIOP_NCMD * sizeof(struct siop_xfer)) {
- dsa -= sc->sc_scriptdma->dm_segs[0].ds_addr + CMD_OFF;
- siop_cmd = &sc->cmds[dsa / sizeof(struct siop_xfer)];
- siop_table_sync(siop_cmd,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- } else {
+ for (cbdp = TAILQ_FIRST(&sc->cmds); cbdp != NULL;
+ cbdp = TAILQ_NEXT(cbdp, next)) {
+ if (dsa >= cbdp->xferdma->dm_segs[0].ds_addr &&
+ dsa < cbdp->xferdma->dm_segs[0].ds_addr + NBPG) {
+ dsa -= cbdp->xferdma->dm_segs[0].ds_addr;
+ siop_cmd = &cbdp->cmds[dsa / sizeof(struct siop_xfer)];
+ siop_table_sync(siop_cmd,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ break;
+ }
+ }
+ if (cbdp == NULL) {
printf("%s: current DSA invalid\n",
sc->sc_dev.dv_xname);
siop_cmd = NULL;
@@ -598,6 +547,11 @@
#ifdef DEBUG_INTR
printf("script interrupt 0x%x\n", irqcode);
#endif
+ if (siop_cmd == NULL) {
+ printf("%s: script interrupt (0x%x) with invalid "
+ "DSA !!!\n", sc->sc_dev.dv_xname, irqcode);
+ goto reset;
+ }
/*
* an inactive command is only valid if it's a reselect
* interrupt: we'll change siop_cmd to point to the rigth one
@@ -1071,6 +1025,11 @@
siop_cmd->xs->error = (siop_cmd->flags & CMDFL_TIMEOUT) ?
XS_TIMEOUT : XS_RESET;
printf("cmd %p about to be processed\n", siop_cmd);
+ if (siop_cmd->status == CMDST_SENSE ||
+ siop_cmd->status == CMDST_SENSE_ACTIVE)
+ siop_cmd->status = CMDST_SENSE_DONE;
+ else
+ siop_cmd->status = CMDST_DONE;
TAILQ_REMOVE(&reset_list, siop_cmd, next);
siop_scsicmd_end(siop_cmd);
TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next);
@@ -1094,6 +1053,15 @@
siop_cmd = sc->free_list.tqh_first;
if (siop_cmd) {
TAILQ_REMOVE(&sc->free_list, siop_cmd, next);
+ } else {
+ if (siop_morecbd(sc) == 0) {
+ siop_cmd = sc->free_list.tqh_first;
+#ifdef DIAGNOSTIC
+ if (siop_cmd == NULL)
+ panic("siop_morecbd succeed and does nothing");
+#endif
+ TAILQ_REMOVE(&sc->free_list, siop_cmd, next);
+ }
}
splx(s);
if (siop_cmd == NULL) {
@@ -1387,7 +1355,7 @@
{
int i;
siop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- for (i = 0; i < CMD_OFF / 4; i += 2) {
+ for (i = 0; i < NBPG / 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) {
@@ -1398,6 +1366,123 @@
}
}
+int
+siop_morecbd(sc)
+ struct siop_softc *sc;
+{
+ int error, i;
+ bus_dma_segment_t seg;
+ int rseg;
+ struct siop_cbd *newcbd;
+
+ /* allocate a new list head */
+ newcbd = malloc(sizeof(struct siop_cbd), M_DEVBUF, M_NOWAIT);
+ if (newcbd == NULL) {
+ printf("%s: can't allocate memory for command descriptors "
+ "head\n", sc->sc_dev.dv_xname);
+ return ENOMEM;
+ }
+
+ /* allocate cmd list */
+ newcbd->cmds =
+ malloc(sizeof(struct siop_cmd) * SIOP_NCMDPB, M_DEVBUF, M_NOWAIT);
+ if (newcbd->cmds == NULL) {
+ printf("%s: can't allocate memory for command descriptors\n",
+ sc->sc_dev.dv_xname);
+ error = ENOMEM;
+ goto bad3;
+ }
+ error = bus_dmamem_alloc(sc->sc_dmat, NBPG, NBPG, 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);
+ goto bad2;
+ }
+ error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, NBPG,
+ (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);
+ goto bad2;
+ }
+ error = bus_dmamap_create(sc->sc_dmat, NBPG, 1, NBPG, 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);
+ goto bad1;
+ }
+ error = bus_dmamap_load(sc->sc_dmat, newcbd->xferdma, newcbd->xfers,
+ NBPG, NULL, BUS_DMA_NOWAIT);
+ if (error) {
+ printf("%s: unable to load script DMA map, error = %d\n",
+ sc->sc_dev.dv_xname, error);
+ goto bad0;
+ }
+
+ for (i = 0; i < SIOP_NCMDPB; i++) {
+ error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, SIOP_NSG,
+ MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
Home |
Main Index |
Thread Index |
Old Index