Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev - Change the script to start new commands in an asyn...
details: https://anonhg.NetBSD.org/src/rev/25c71265224a
branches: trunk
changeset: 485350:25c71265224a
user: bouyer <bouyer%NetBSD.org@localhost>
date: Tue Apr 25 16:27:05 2000 +0000
description:
- Change the script to start new commands in an asyncronous way, using
'command slots' in which the host can put command and wait for the script
to start them
- Change siop.c to do full disconnect/reslelect, allowing as much as one
command per target/lun to run in parallel.
- Fix bug in registers init where a board without BIOS would end at
ID 0 (now the driver works on alpha too).
- better handling of messages, sending back a MSG_EXT_SDTR in response to an
incoming MSG_EXT_SDTR, and MSG_MESSAGE_REJECT for unhandled messages.
- fix use of bus_dmamap_sync() and htole32().
- supports shared interrups
- change some int8 and int16 to int, for alpha and mips benefits ( suggested by
Toru Nishimura)
diffstat:
sys/dev/ic/siop.c | 773 ++++++++++++++++++++++++++++++---------
sys/dev/ic/siopreg.h | 3 +-
sys/dev/ic/siopvar.h | 15 +-
sys/dev/microcode/siop/siop.out | 291 +++++++++-----
sys/dev/microcode/siop/siop.ss | 115 ++++-
5 files changed, 882 insertions(+), 315 deletions(-)
diffs (truncated from 1663 to 300 lines):
diff -r eb11966507a7 -r 25c71265224a sys/dev/ic/siop.c
--- a/sys/dev/ic/siop.c Tue Apr 25 16:05:06 2000 +0000
+++ b/sys/dev/ic/siop.c Tue Apr 25 16:27:05 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: siop.c,v 1.1 2000/04/21 17:56:58 bouyer Exp $ */
+/* $NetBSD: siop.c,v 1.2 2000/04/25 16:27:05 bouyer Exp $ */
/*
* Copyright (c) 2000 Manuel Bouyer.
@@ -41,6 +41,7 @@
#include <sys/malloc.h>
#include <sys/buf.h>
#include <sys/kernel.h>
+#include <sys/scsiio.h>
#include <machine/endian.h>
#include <machine/bus.h>
@@ -60,12 +61,19 @@
#include <dev/ic/siopreg.h>
#include <dev/ic/siopvar.h>
+#undef DEBUG
+#undef DEBUG_INTR
+#undef DEBUG_SHED
+#undef DUMP_SCRIPT
+
+#define SIOP_STATS
+
#ifndef SIOP_DEFAULT_TARGET
#define SIOP_DEFAULT_TARGET 7
#endif
#define MEM_SIZE 8192
-#define SCRIPT_OFF 4096
+#define CMD_OFF 4096
/* tables used by SCRIPT */
typedef struct scr_table {
@@ -81,17 +89,19 @@
* transfert. It lives in the same chunk of DMA-safe memory as the script.
*/
struct siop_xfer {
- u_int8_t msg_out; /* 0 */
- u_int8_t msg_in; /* 1 */
- u_int8_t status; /* 2 */
- u_int8_t pad2; /* 3 */
- u_int32_t id; /* 4 */
- u_int32_t pad1; /* 8 */
- scr_table_t t_msgin; /* 12 */
- scr_table_t t_msgout; /* 20 */
- scr_table_t cmd; /* 28 */
- scr_table_t t_status; /* 36 */
- scr_table_t data[SIOP_NSG]; /* 44 */
+ u_int8_t msg_out[8]; /* 0 */
+ u_int8_t msg_in[8]; /* 8 */
+ int status; /* 16 */
+ u_int32_t id; /* 20 */
+ u_int32_t pad1; /* 24 */
+ scr_table_t t_msgin; /* 28 */
+ scr_table_t t_extmsgin; /* 36 */
+ scr_table_t t_extmsgdata; /* 44 */
+ scr_table_t t_extmsgtag; /* 52 */
+ scr_table_t t_msgout; /* 60 */
+ scr_table_t cmd; /* 68 */
+ scr_table_t t_status; /* 76 */
+ scr_table_t data[SIOP_NSG]; /* 84 */
};
/*
@@ -104,20 +114,22 @@
struct siop_softc *siop_sc; /* pointer to adapter */
struct scsipi_xfer *xs; /* xfer from the upper level */
struct siop_xfer *siop_table; /* tables dealing with this xfer */
+ bus_addr_t dsa; /* DSA value to load */
bus_dmamap_t dmamap_cmd;
bus_dmamap_t dmamap_data;
struct scsipi_sense rs_cmd; /* request sense command buffer */
- u_int16_t status;
- u_int16_t flags;
+ int status;
+ int flags;
};
/* status defs */
-#define CMDST_FREE 0 /* cmd slot is free */
-#define CMDST_READY 1 /* cmd slot is waiting for processing */
-#define CMDST_ACTIVE 2 /* cmd slot is being processed */
-#define CMDST_SENSE 3 /* cmd slot is being requesting sense */
-#define CMDST_SENSE_DONE 4 /* request sense done */
-#define CMDST_DONE 5 /* cmd slot has been processed */
+#define CMDST_FREE 0 /* cmd slot is free */
+#define CMDST_READY 1 /* cmd slot is waiting for processing */
+#define CMDST_ACTIVE 2 /* cmd slot is being processed */
+#define CMDST_SENSE 3 /* cmd slot is being requesting sense */
+#define CMDST_SENSE_ACTIVE 4 /* request sense active */
+#define CMDST_SENSE_DONE 5 /* request sense done */
+#define CMDST_DONE 6 /* cmd slot has been processed */
/* flags defs */
#define CMDFL_TIMEOUT 0x0001 /* cmd timed out */
@@ -125,17 +137,23 @@
#define SIOP_NCMD 10
void siop_reset __P((struct siop_softc *));
+void siop_handle_reset __P((struct siop_softc *));
+void siop_scsicmd_end __P((struct siop_cmd *));
void siop_start __P((struct siop_softc *));
void siop_timeout __P((void *));
void siop_minphys __P((struct buf *));
+int siop_ioctl __P((struct scsipi_link *, u_long,
+ caddr_t, int, struct proc *));
int siop_scsicmd __P((struct scsipi_xfer *));
void siop_sdp __P((struct siop_cmd *));
void siop_ssg __P((struct siop_cmd *));
+void siop_dump_script __P((struct siop_softc *));
struct scsipi_adapter siop_adapter = {
0,
siop_scsicmd,
siop_minphys,
+ siop_ioctl,
NULL,
};
@@ -146,6 +164,42 @@
NULL,
};
+#ifdef SIOP_STATS
+static int siop_stat_intr = 0;
+static int siop_stat_intr_shortxfer = 0;
+static int siop_stat_intr_sdp = 0;
+static int siop_stat_intr_done = 0;
+static int siop_stat_intr_reselect = 0;
+static int siop_stat_intr_xferdisc = 0;
+void siop_printstats __P((void));
+#define INCSTAT(x) x++
+#else
+#define INCSTAT(x)
+#endif
+
+static __inline__ void siop_table_sync __P((struct siop_cmd *, int));
+static __inline__ void
+siop_table_sync(siop_cmd, ops)
+ struct siop_cmd *siop_cmd;
+ int ops;
+{
+ struct siop_softc *sc = siop_cmd->siop_sc;
+ bus_addr_t offset;
+
+ offset = sc->sc_scriptdma->dm_segs[0].ds_addr - siop_cmd->dsa;
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, offset,
+ sizeof(struct siop_xfer), ops);
+}
+
+static __inline__ void siop_script_sync __P((struct siop_softc *, int));
+static __inline__ void
+siop_script_sync(sc, ops)
+ struct siop_softc *sc;
+ int ops;
+{
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, 0, CMD_OFF, ops);
+}
+
void
siop_attach(sc)
struct siop_softc *sc;
@@ -153,7 +207,6 @@
int error, i;
bus_dma_segment_t seg;
int rseg;
- struct siop_cmd *cmds;
/*
* Allocate DMA-safe memory for the script itself and internal
@@ -191,8 +244,9 @@
for (i = 0; i < 16; i++)
TAILQ_INIT(&sc->active_list[i]);
/* allocate cmd list */
- cmds = malloc(sizeof(struct siop_cmd) * SIOP_NCMD, M_DEVBUF, M_NOWAIT);
- if (cmds == NULL) {
+ 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;
@@ -200,7 +254,7 @@
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,
- &cmds[i].dmamap_data);
+ &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);
@@ -210,35 +264,50 @@
sizeof(struct scsipi_generic), 1,
sizeof(struct scsipi_generic), 0,
BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
- &cmds[i].dmamap_cmd);
+ &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;
}
- cmds[i].siop_sc = sc;
- cmds[i].siop_table = &((struct siop_xfer *)sc->sc_script)[i];
- cmds[i].status = CMDST_FREE;
- cmds[i].siop_table->t_msgout.count= htole32(1);
- cmds[i].siop_table->t_msgout.addr =
- htole32(sc->sc_scriptdma->dm_segs[0].ds_addr +
- i * sizeof(struct siop_xfer));
- cmds[i].siop_table->t_msgin.count= htole32(1);
- cmds[i].siop_table->t_msgin.addr =
- htole32(htole32(cmds[i].siop_table->t_msgout.addr) + 1);
- cmds[i].siop_table->t_status.count= htole32(1);
- cmds[i].siop_table->t_status.addr =
- htole32(htole32(cmds[i].siop_table->t_msgin.addr) + 1);
- TAILQ_INSERT_TAIL(&sc->free_list, &cmds[i], next);
+ sc->cmds[i].siop_sc = sc;
+ sc->cmds[i].siop_table =
+ &((struct siop_xfer *)(&sc->sc_script[CMD_OFF/4]))[i];
+ 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(htole32(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(htole32(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,
- cmds[i].siop_table->t_msgin.addr,
- cmds[i].siop_table->t_msgout.addr,
- cmds[i].siop_table->t_status.addr);
+ sc->cmds[i].siop_table->t_msgin.addr,
+ sc->cmds[i].siop_table->t_msgout.addr,
+ sc->cmds[i].siop_table->t_status.addr);
+#endif
}
+ /* compute number of sheduler slots */
+ sc->sc_nshedslots = (
+ CMD_OFF /* 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 */
+ ) / (sizeof(slot_script) - 8);
#ifdef DEBUG
- printf("%s: script size = %d, PHY addr=0x%x, VIRT=%p\n",
- sc->sc_dev.dv_xname, sizeof(siop_script),
- (u_int)sc->sc_scriptdma->dm_segs[0].ds_addr, sc->sc_script);
+ 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);
#endif
sc->sc_link.adapter_softc = sc;
@@ -249,7 +318,8 @@
sc->sc_link.scsipi_scsi.max_lun = 7;
sc->sc_link.scsipi_scsi.adapter_target = bus_space_read_1(sc->sc_rt,
sc->sc_rh, SIOP_SCID);
- if (sc->sc_link.scsipi_scsi.adapter_target >
+ if (sc->sc_link.scsipi_scsi.adapter_target == 0 ||
+ sc->sc_link.scsipi_scsi.adapter_target >
sc->sc_link.scsipi_scsi.max_target)
sc->sc_link.scsipi_scsi.adapter_target = SIOP_DEFAULT_TARGET;
sc->sc_link.type = BUS_SCSI;
@@ -258,6 +328,9 @@
sc->sc_link.flags = 0;
siop_reset(sc);
+#ifdef DUMP_SCRIPT
+ siop_dump_script(sc);
+#endif
config_found((struct device*)sc, &sc->sc_link, scsiprint);
}
@@ -266,13 +339,43 @@
siop_reset(sc)
struct siop_softc *sc;
{
+ int i;
+ u_int32_t *scr;
+ bus_addr_t physaddr;
/* reset the chip */
bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_ISTAT, ISTAT_SRST);
delay(1000);
bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_ISTAT, 0);
Home |
Main Index |
Thread Index |
Old Index