Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Bare-bones driver for AMI RAID. Parts taken from Fre...



details:   https://anonhg.NetBSD.org/src/rev/6b82f580473d
branches:  trunk
changeset: 521416:6b82f580473d
user:      ad <ad%NetBSD.org@localhost>
date:      Wed Jan 30 14:35:43 2002 +0000

description:
Bare-bones driver for AMI RAID. Parts taken from FreeBSD. This was tried a
good while ago and it had problems under load. Changes were made to address
that, but I don't have the ability to test them. So, I'm committing it
before it rots.

diffstat:

 sys/dev/DEVNAMES      |     3 +-
 sys/dev/pci/amr.c     |  1004 +++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/pci/amrreg.h  |   438 +++++++++++++++++++++
 sys/dev/pci/amrvar.h  |   131 ++++++
 sys/dev/pci/files.pci |    10 +-
 sys/dev/pci/ld_amr.c  |   240 +++++++++++
 6 files changed, 1824 insertions(+), 2 deletions(-)

diffs (truncated from 1870 to 300 lines):

diff -r 8c1b1b31bb2a -r 6b82f580473d sys/dev/DEVNAMES
--- a/sys/dev/DEVNAMES  Wed Jan 30 14:01:33 2002 +0000
+++ b/sys/dev/DEVNAMES  Wed Jan 30 14:35:43 2002 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: DEVNAMES,v 1.92 2002/01/06 16:06:36 jmcneill Exp $
+#      $NetBSD: DEVNAMES,v 1.93 2002/01/30 14:35:43 ad Exp $
 #
 # This file contains all used device names and defined attributes in 
 # alphabetical order. New devices added to the system somewhere should first 
@@ -53,6 +53,7 @@
 amibus_wb              amiga           Attribute
 amibus_ww              amiga           Attribute
 amps                   arm32
+amr                    MI
 ams                    mac68k
 ams                    macppc
 an                     MI
diff -r 8c1b1b31bb2a -r 6b82f580473d sys/dev/pci/amr.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/amr.c Wed Jan 30 14:35:43 2002 +0000
@@ -0,0 +1,1004 @@
+/*     $NetBSD: amr.c,v 1.1 2002/01/30 14:35:45 ad Exp $       */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 1999,2000 Michael Smith
+ * Copyright (c) 2000 BSDi
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * from FreeBSD: amr_pci.c,v 1.5 2000/08/30 07:52:40 msmith Exp
+ * from FreeBSD: amr.c,v 1.16 2000/08/30 07:52:40 msmith Exp 
+ */
+
+/*
+ * Driver for AMI RAID controllers.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: amr.c,v 1.1 2002/01/30 14:35:45 ad 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 <sys/malloc.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/endian.h>
+#include <machine/bus.h>
+
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/amrreg.h>
+#include <dev/pci/amrvar.h>
+
+#if AMR_MAX_SEGS > 32
+#error AMR_MAX_SEGS too high
+#endif
+
+#define        AMR_ENQUIRY_BUFSIZE     2048
+#define        AMR_SGL_SIZE            (sizeof(struct amr_sgentry) * 32)
+
+void   amr_attach(struct device *, struct device *, void *);
+void   *amr_enquire(struct amr_softc *, u_int8_t, u_int8_t, u_int8_t);
+int    amr_init(struct amr_softc *, const char *,
+                        struct pci_attach_args *pa);
+int    amr_intr(void *);
+int    amr_match(struct device *, struct cfdata *, void *);
+int    amr_print(void *, const char *);
+void   amr_shutdown(void *);
+int    amr_submatch(struct device *, struct cfdata *, void *);
+
+int    amr_mbox_wait(struct amr_softc *);
+int    amr_quartz_get_work(struct amr_softc *, struct amr_mailbox *);
+int    amr_quartz_submit(struct amr_softc *, struct amr_ccb *);
+int    amr_std_get_work(struct amr_softc *, struct amr_mailbox *);
+int    amr_std_submit(struct amr_softc *, struct amr_ccb *);
+
+static inline u_int8_t amr_inb(struct amr_softc *, int);
+static inline u_int32_t        amr_inl(struct amr_softc *, int);
+static inline void     amr_outb(struct amr_softc *, int, u_int8_t);
+static inline void     amr_outl(struct amr_softc *, int, u_int32_t);
+
+struct cfattach amr_ca = {
+       sizeof(struct amr_softc), amr_match, amr_attach
+};
+
+#define AT_QUARTZ      0x01    /* `Quartz' chipset */
+#define        AT_SIG          0x02    /* Check for signature */
+
+struct amr_pci_type {
+       u_short apt_vendor;
+       u_short apt_product;
+       u_short apt_flags;
+} static const amr_pci_type[] = {
+       { PCI_VENDOR_AMI,   PCI_PRODUCT_AMI_MEGARAID,  0 },
+       { PCI_VENDOR_AMI,   PCI_PRODUCT_AMI_MEGARAID2, 0 },
+       { PCI_VENDOR_AMI,   PCI_PRODUCT_AMI_MEGARAID3, AT_QUARTZ },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_AMI_MEGARAID3, AT_QUARTZ | AT_SIG }
+};
+
+struct amr_typestr {
+       const char      *at_str;
+       int             at_sig;
+} static const amr_typestr[] = {
+       { "Series 431",                 AMR_SIG_431 },
+       { "Series 438",                 AMR_SIG_438 },
+       { "Series 466",                 AMR_SIG_466 },
+       { "Series 467",                 AMR_SIG_467 },
+       { "Series 490",                 AMR_SIG_490 },
+       { "Series 762",                 AMR_SIG_762 },
+       { "HP NetRAID (T5)",            AMR_SIG_T5 },
+       { "HP NetRAID (T7)",            AMR_SIG_T7 },
+};
+
+static void    *amr_sdh;
+
+static inline u_int8_t
+amr_inb(struct amr_softc *amr, int off)
+{
+
+       bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 1,
+           BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
+       return (bus_space_read_1(amr->amr_iot, amr->amr_ioh, off));
+}
+
+static inline u_int32_t
+amr_inl(struct amr_softc *amr, int off)
+{
+
+       bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 4,
+           BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
+       return (bus_space_read_4(amr->amr_iot, amr->amr_ioh, off));
+}
+
+static inline void
+amr_outb(struct amr_softc *amr, int off, u_int8_t val)
+{
+
+       bus_space_write_1(amr->amr_iot, amr->amr_ioh, off, val);
+       bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 1,
+           BUS_SPACE_BARRIER_WRITE);
+}
+
+static inline void
+amr_outl(struct amr_softc *amr, int off, u_int32_t val)
+{
+
+       bus_space_write_4(amr->amr_iot, amr->amr_ioh, off, val);
+       bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 4,
+           BUS_SPACE_BARRIER_WRITE);
+}
+
+/*
+ * Match a supported device.
+ */
+int
+amr_match(struct device *parent, struct cfdata *match, void *aux)
+{
+       struct pci_attach_args *pa;
+       pcireg_t s;
+       int i;
+
+       pa = (struct pci_attach_args *)aux;
+
+       /*
+        * Don't match the device if it's operating in I2O mode.  In this
+        * case it should be handled by the `iop' driver.
+        */
+       if (PCI_CLASS(pa->pa_class) == PCI_CLASS_I2O)
+               return (0);
+
+       for (i = 0; i < sizeof(amr_pci_type) / sizeof(amr_pci_type[0]); i++)
+               if (PCI_VENDOR(pa->pa_id) == amr_pci_type[i].apt_vendor && 
+                   PCI_PRODUCT(pa->pa_id) == amr_pci_type[i].apt_product)
+                       break;
+
+       if (i == sizeof(amr_pci_type) / sizeof(amr_pci_type[0]))
+               return (0);
+
+       if ((amr_pci_type[i].apt_flags & AT_SIG) == 0)
+               return (1);
+
+       s = pci_conf_read(pa->pa_pc, pa->pa_tag, AMR_QUARTZ_SIG_REG) & 0xffff;
+       return (s == AMR_QUARTZ_SIG0 || s == AMR_QUARTZ_SIG1);
+}
+
+/*
+ * Attach a supported device.  XXX This doesn't fail gracefully, and may
+ * over-allocate resources.
+ */
+void
+amr_attach(struct device *parent, struct device *self, void *aux)
+{
+       bus_space_tag_t memt, iot;
+       bus_space_handle_t memh, ioh;
+       struct pci_attach_args *pa;
+       struct amr_attach_args amra;
+       const struct amr_pci_type *apt;
+       struct amr_softc *amr;
+       pci_chipset_tag_t pc;
+       pci_intr_handle_t ih;
+       const char *intrstr;
+       pcireg_t reg;
+       int rseg, i, size, rv, memreg, ioreg;
+        bus_dma_segment_t seg;
+        struct amr_ccb *ac;
+
+       amr = (struct amr_softc *)self;
+       pa = (struct pci_attach_args *)aux;
+       pc = pa->pa_pc;
+
+       for (i = 0; i < sizeof(amr_pci_type) / sizeof(amr_pci_type[0]); i++)
+               if (PCI_VENDOR(pa->pa_id) == amr_pci_type[i].apt_vendor &&
+                   PCI_PRODUCT(pa->pa_id) == amr_pci_type[i].apt_product)
+                       break;
+       apt = amr_pci_type + i;
+
+       memreg = ioreg = 0;
+       for (i = 0x10; i <= 0x14; i += 4) {
+               reg = pci_conf_read(pc, pa->pa_tag, i);
+               switch (PCI_MAPREG_TYPE(reg)) {
+               case PCI_MAPREG_TYPE_MEM:
+                       if (PCI_MAPREG_MEM_SIZE(reg) != 0)
+                               memreg = i;
+                       break;
+               case PCI_MAPREG_TYPE_IO:
+                       if (PCI_MAPREG_IO_SIZE(reg) != 0)
+                               ioreg = i;
+                       break;
+               }
+       }
+
+       if (memreg != 0)
+               if (pci_mapreg_map(pa, memreg, PCI_MAPREG_TYPE_MEM, 0,
+                   &memt, &memh, NULL, NULL))
+                       memreg = 0;
+       if (ioreg != 0)
+               if (pci_mapreg_map(pa, ioreg, PCI_MAPREG_TYPE_IO, 0,
+                   &iot, &ioh, NULL, NULL))



Home | Main Index | Thread Index | Old Index