Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Snapshot of work in progress: new driver for the NCR 53c...



details:   https://anonhg.NetBSD.org/src/rev/8d1ae34c77b9
branches:  trunk
changeset: 485191:8d1ae34c77b9
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Fri Apr 21 17:56:58 2000 +0000

description:
Snapshot of work in progress: new driver for the NCR 53c8xx SCSI controller
(the name 'siop' is still being discussed, may change).
Only basic disconnect/reselect for now, no sync/wide negotiation.
Tested with 810A, 875 and 895 on i386 only.
The bus-independant part should also be able to handle the 53c720 and 53c770.
A new driver with enhanced script should appear for the 825/875/895 'soon'.

diffstat:

 sys/conf/files                  |    6 +-
 sys/dev/ic/siop.c               |  922 ++++++++++++++++++++++++++++++++++++++++
 sys/dev/ic/siopreg.h            |  343 ++++++++++++++
 sys/dev/ic/siopvar.h            |   83 +++
 sys/dev/microcode/siop/Makefile |   15 +
 sys/dev/microcode/siop/siop.out |  121 +++++
 sys/dev/microcode/siop/siop.ss  |  153 ++++++
 sys/dev/pci/files.pci           |    7 +-
 sys/dev/pci/siop_pci.c          |  280 ++++++++++++
 9 files changed, 1928 insertions(+), 2 deletions(-)

diffs (truncated from 1986 to 300 lines):

diff -r 862dc7599ccb -r 8d1ae34c77b9 sys/conf/files
--- a/sys/conf/files    Fri Apr 21 17:52:06 2000 +0000
+++ b/sys/conf/files    Fri Apr 21 17:56:58 2000 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files,v 1.363 2000/04/20 18:23:37 thorpej Exp $
+#      $NetBSD: files,v 1.364 2000/04/21 17:57:01 bouyer Exp $
 
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
 
@@ -249,6 +249,10 @@
 file   dev/ic/isp_netbsd.c             isp
 file   dev/ic/isp_target.c             isp
 
+# Symbios/NCR 53c720/53c8xx SCSI controllers
+device siop: scsi
+file dev/ic/siop.c                     siop
+
 # UltraStor SCSI controllers
 device uha: scsi
 file   dev/ic/uha.c                    uha
diff -r 862dc7599ccb -r 8d1ae34c77b9 sys/dev/ic/siop.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/siop.c Fri Apr 21 17:56:58 2000 +0000
@@ -0,0 +1,922 @@
+/*     $NetBSD: siop.c,v 1.1 2000/04/21 17:56:58 bouyer Exp $  */
+
+/*
+ * Copyright (c) 2000 Manuel Bouyer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/* SYM53c7/8xx PCI-SCSI I/O Processors driver */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/kernel.h>
+
+#include <machine/endian.h>
+#include <machine/bus.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_kern.h>
+
+#include <dev/microcode/siop/siop.out>
+
+#include <dev/scsipi/scsi_all.h>
+#include <dev/scsipi/scsi_message.h>
+#include <dev/scsipi/scsipi_all.h>
+
+#include <dev/scsipi/scsiconf.h>
+
+#include <dev/ic/siopreg.h>
+#include <dev/ic/siopvar.h>
+
+#ifndef SIOP_DEFAULT_TARGET
+#define SIOP_DEFAULT_TARGET 7
+#endif
+
+#define MEM_SIZE 8192
+#define SCRIPT_OFF 4096
+
+/* tables used by SCRIPT */
+typedef struct scr_table {
+       u_int32_t count;
+       u_int32_t addr;
+} scr_table_t ;
+
+/* Number of scatter/gather entries */
+#define SIOP_NSG       (MAXPHYS/NBPG + 1)
+
+/*
+ * This structure interfaces the SCRIPT with the driver; it describes a full
+ * 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 */
+};
+
+/*
+ * This decribes a command handled by the SCSI controller
+ * These are chained in either a free list or a active list
+ * We have one queue per target + (one at the adapter's target for probe)
+ */
+struct siop_cmd {
+       TAILQ_ENTRY (siop_cmd) next;
+       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_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;
+};
+
+/* 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 */
+/* flags defs */
+#define CMDFL_TIMEOUT  0x0001 /* cmd timed out */
+
+/* initial number of cmd descriptors */
+#define SIOP_NCMD 10
+
+void   siop_reset __P((struct siop_softc *));
+void   siop_start __P((struct siop_softc *));
+void   siop_timeout __P((void *));
+void   siop_minphys __P((struct buf *));
+int    siop_scsicmd __P((struct scsipi_xfer *));
+void   siop_sdp __P((struct siop_cmd *));
+void   siop_ssg __P((struct siop_cmd *));
+
+struct scsipi_adapter siop_adapter = {
+       0,
+       siop_scsicmd,
+       siop_minphys,
+       NULL,
+};
+
+struct scsipi_device siop_dev = {
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+};
+
+void
+siop_attach(sc)
+       struct siop_softc *sc;
+{
+       int error, i;
+       bus_dma_segment_t seg;
+       int rseg;
+       struct siop_cmd *cmds;
+
+       /*
+        * Allocate DMA-safe memory for the script itself and internal
+        * variables and map it.
+        */
+       error = bus_dmamem_alloc(sc->sc_dmat, MEM_SIZE, 
+           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,
+           (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);
+       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);
+       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);
+       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) {
+               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,
+                   &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,
+                   &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);
+               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);
+       }
+#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);
+#endif
+
+       sc->sc_link.adapter_softc = sc;
+       sc->sc_link.openings = 1;
+       sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
+       sc->sc_link.scsipi_scsi.max_target  =
+           (sc->features & SF_BUS_WIDE) ? 15 : 7;
+       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 >
+           sc->sc_link.scsipi_scsi.max_target)
+               sc->sc_link.scsipi_scsi.adapter_target = SIOP_DEFAULT_TARGET;
+       sc->sc_link.type = BUS_SCSI;
+       sc->sc_link.adapter = &siop_adapter;
+       sc->sc_link.device = &siop_dev;
+       sc->sc_link.flags  = 0;
+
+       siop_reset(sc);
+
+       config_found((struct device*)sc, &sc->sc_link, scsiprint);
+}
+
+void
+siop_reset(sc)
+       struct siop_softc *sc;
+{
+       /* 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);
+
+       /* copy and patch the script */
+       memcpy(&sc->sc_script[SCRIPT_OFF/4], siop_script, sizeof(siop_script));
+



Home | Main Index | Thread Index | Old Index