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