Source-Changes-HG archive

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

[src/netbsd-1-4]: src/sys/dev/ic Pull up revisions 1.1-1.17 + patch (requeste...



details:   https://anonhg.NetBSD.org/src/rev/d52b8eef42a7
branches:  netbsd-1-4
changeset: 470071:d52b8eef42a7
user:      he <he%NetBSD.org@localhost>
date:      Mon Jan 17 18:32:50 2000 +0000

description:
Pull up revisions 1.1-1.17 + patch (requested by ad):
  Add driver for DPT SmartCache and SmartRAID III or IV SCSI
  adapters.

diffstat:

 sys/dev/ic/dpt.c |  1156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1156 insertions(+), 0 deletions(-)

diffs (truncated from 1160 to 300 lines):

diff -r 8040d7db6bfa -r d52b8eef42a7 sys/dev/ic/dpt.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/dpt.c  Mon Jan 17 18:32:50 2000 +0000
@@ -0,0 +1,1156 @@
+/*     $NetBSD: dpt.c,v 1.17.2.2 2000/01/17 18:32:50 he Exp $  */
+
+/*-
+ * Copyright (c) 1997, 1998, 1999, 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andy Doran, Charles M. Hannum and by Jason R. Thorpe of the Numerical 
+ * Aerospace Simulation Facility, NASA Ames Research Center.
+ *
+ * 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 NetBSD
+ *     Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * Portions of this code fall under the following copyright:
+ *
+ * Originally written by Julian Elischer (julian%tfs.com@localhost)
+ * for TRW Financial Systems for use under the MACH(2.5) operating system.
+ *
+ * TRW Financial Systems, in accordance with their agreement with Carnegie
+ * Mellon University, makes this software available to CMU to distribute
+ * or use in any manner that they see fit as long as this message is kept with
+ * the software. For this reason TFS also grants any other persons or
+ * organisations permission to use or modify this software.
+ *
+ * TFS supplies this software to be publicly redistributed
+ * on the understanding that TFS is not responsible for the correct
+ * functioning of this software in any circumstances.
+ */
+
+/*
+ * Driver for DPT EATA SCSI adapters.
+ *
+ * TODO:
+ *
+ * o Need a front-end for (newer) ISA boards.
+ * o Handle older firmware better.
+ * o Find a bunch of different firmware EEPROMs and try them out.
+ * o Test with a bunch of different boards.
+ * o dpt_readcfg() should not be using CP_PIO_GETCFG.
+ * o An interface to userland applications.
+ * o Some sysctls or a utility (eg dptctl(8)) to control parameters.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: dpt.c,v 1.17.2.2 2000/01/17 18:32:50 he Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/queue.h>
+#include <sys/proc.h>
+#include <sys/buf.h>
+
+#include <machine/endian.h>
+#include <machine/bswap.h>
+#include <machine/bus.h>
+
+#include <dev/scsipi/scsi_all.h>
+#include <dev/scsipi/scsipi_all.h>
+#include <dev/scsipi/scsiconf.h>
+
+#include <dev/ic/dptreg.h>
+#include <dev/ic/dptvar.h>
+
+/* A default for our link struct */
+static struct scsipi_device dpt_dev = {
+       NULL,                   /* Use default error handler */
+       NULL,                   /* have a queue, served by this */
+       NULL,                   /* have no async handler */
+       NULL,                   /* Use default 'done' routine */
+};
+
+static char *dpt_cname[] = {
+       "PM3334", "SmartRAID IV",
+       "PM3332", "SmartRAID IV",
+       "PM2144", "SmartCache IV",
+       "PM2044", "SmartCache IV",
+       "PM2142", "SmartCache IV",
+       "PM2042", "SmartCache IV",
+       "PM2041", "SmartCache IV",
+       "PM3224", "SmartRAID III",
+       "PM3222", "SmartRAID III", 
+       "PM3021", "SmartRAID III",
+       "PM2124", "SmartCache III",
+       "PM2024", "SmartCache III",
+       "PM2122", "SmartCache III",
+       "PM2022", "SmartCache III",
+       "PM2021", "SmartCache III",
+       "SK2012", "SmartCache Plus", 
+       "SK2011", "SmartCache Plus",
+       NULL,     "unknown adapter, please report using send-pr(1)",
+};
+
+/*
+ * Handle an interrupt from the HBA.
+ */
+int
+dpt_intr(xxx_sc)
+       void *xxx_sc;
+{
+       struct dpt_softc *sc;
+       struct dpt_ccb *ccb;
+       struct eata_sp *sp;
+       static int moretimo;
+       int more;
+
+       sc = xxx_sc;
+       sp = sc->sc_statpack;
+       more = 0;
+
+#ifdef DEBUG
+       if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
+               printf("%s: spurious intr\n", sc->sc_dv.dv_xname);
+#endif
+       
+       /* Don't get stalled by HA_ST_MORE */
+       if (moretimo < DPT_MORE_TIMEOUT / 100)
+               moretimo = 0;
+       
+       for (;;) {
+               /*
+                * HBA might have interrupted while we were dealing with the
+                * last completed command, since we ACK before we deal; keep 
+                * polling. If no interrupt is signalled, but the HBA has
+                * indicated that more data will be available soon, hang 
+                * around. 
+                */ 
+               if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0) {
+                       if (more != 0 && moretimo++ < DPT_MORE_TIMEOUT / 100) {
+                               DELAY(10);
+                               continue;
+                       }
+                       break;
+               }
+               
+               bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
+                   sizeof(struct eata_sp), BUS_DMASYNC_POSTREAD);
+
+               /* Might have looped before HBA can reset HBA_AUX_INTR */
+               if (sp->sp_ccbid == -1) {
+                       DELAY(50);
+#ifdef DIAGNOSTIC
+                       printf("%s: slow reset of HA_AUX_STATUS?",
+                           sc->sc_dv.dv_xname);
+#endif
+                       if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
+                               return (0);
+#ifdef DIAGNOSTIC
+                       printf("%s: was a slow reset of HA_AUX_STATUS",
+                           sc->sc_dv.dv_xname);
+#endif
+                       /* Re-sync DMA map */
+                       bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, 
+                           sc->sc_spoff, sizeof(struct eata_sp),
+                           BUS_DMASYNC_POSTREAD);
+               }
+
+               /* Make sure CCB ID from status packet is realistic */
+               if (sp->sp_ccbid >= 0 && sp->sp_ccbid < sc->sc_nccbs) {
+                       /* Sync up DMA map and cache cmd status */
+                       ccb = sc->sc_ccbs + sp->sp_ccbid;
+
+                       bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, 
+                           CCB_OFF(sc, ccb), sizeof(struct dpt_ccb), 
+                           BUS_DMASYNC_POSTWRITE);
+
+                       ccb->ccb_hba_status = sp->sp_hba_status & 0x7F;
+                       ccb->ccb_scsi_status = sp->sp_scsi_status;
+
+                       /* 
+                        * Ack the interrupt and process the CCB. If this
+                        * is a private CCB it's up to dpt_poll() to notice.
+                        */
+                       sp->sp_ccbid = -1;
+                       ccb->ccb_flg |= CCB_INTR;
+                       more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
+                       if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
+                               dpt_done_ccb(sc, ccb);
+               } else {
+                       printf("%s: bogus status (returned CCB id %d)\n", 
+                           sc->sc_dv.dv_xname, sp->sp_ccbid);
+
+                       /* Ack the interrupt */
+                       sp->sp_ccbid = -1;
+                       more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
+               }
+               
+               /* Don't get stalled by HA_ST_MORE */
+               if (moretimo < DPT_MORE_TIMEOUT / 100)
+                       moretimo = 0;
+       }
+
+       return (0);
+}
+
+/*
+ * Initialize and attach the HBA. This is the entry point from bus
+ * specific probe-and-attach code.
+ */
+void
+dpt_init(sc, intrstr)
+       struct dpt_softc *sc;
+       const char *intrstr;
+{
+       struct eata_inquiry_data *ei;
+       int i, j, error, rseg, mapsize;
+       bus_dma_segment_t seg;
+       struct eata_cfg *ec;
+       char model[16];
+       
+       ec = &sc->sc_ec;
+       
+       /* Allocate the CCB/status packet/scratch DMA map and load */
+       sc->sc_nccbs = min(SWAP16(*(int16_t *)ec->ec_queuedepth), DPT_MAX_CCBS);
+       sc->sc_spoff = sc->sc_nccbs * sizeof(struct dpt_ccb);
+       sc->sc_scroff = sc->sc_spoff + sizeof(struct eata_sp);
+       sc->sc_scrlen = 256; /* XXX */
+       mapsize = sc->sc_nccbs * sizeof(struct dpt_ccb) + sc->sc_scrlen +
+           sizeof(struct eata_sp);
+               
+       if ((error = bus_dmamem_alloc(sc->sc_dmat, mapsize, NBPG, 0, 
+           &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
+               printf("%s: unable to allocate CCBs, error = %d\n",
+                   sc->sc_dv.dv_xname, error);
+               return;
+       }
+
+       if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, mapsize,
+           (caddr_t *)&sc->sc_ccbs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
+               printf("%s: unable to map CCBs, error = %d\n",
+                   sc->sc_dv.dv_xname, error);
+               return;
+       }
+
+       if ((error = bus_dmamap_create(sc->sc_dmat, mapsize, mapsize, 1, 0, 
+           BUS_DMA_NOWAIT, &sc->sc_dmamap_ccb)) != 0) {
+               printf("%s: unable to create CCB DMA map, error = %d\n",
+                   sc->sc_dv.dv_xname, error);
+               return;
+       }
+
+       if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_ccb,
+           sc->sc_ccbs, mapsize, NULL, BUS_DMA_NOWAIT)) != 0) {
+               printf("%s: unable to load CCB DMA map, error = %d\n",
+                   sc->sc_dv.dv_xname, error);
+               return;
+       }
+
+       sc->sc_statpack = (struct eata_sp *)((caddr_t)sc->sc_ccbs +
+           sc->sc_spoff);
+       sc->sc_sppa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_spoff;
+       sc->sc_scr = (caddr_t)sc->sc_ccbs + sc->sc_scroff;
+       sc->sc_scrpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_scroff;
+       sc->sc_statpack->sp_ccbid = -1;
+
+       /* Initialize the CCBs */
+       TAILQ_INIT(&sc->sc_free_ccb);
+       i = dpt_create_ccbs(sc, sc->sc_ccbs, sc->sc_nccbs);
+
+       if (i == 0) {
+               printf("%s: unable to create CCBs\n", sc->sc_dv.dv_xname);
+               return;
+       } else if (i != sc->sc_nccbs) {
+               printf("%s: %d/%d CCBs created!\n", sc->sc_dv.dv_xname, i, 
+                   sc->sc_nccbs);
+               sc->sc_nccbs = i;
+       }
+



Home | Main Index | Thread Index | Old Index