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