Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Add support newer LSI RAID controllers based on the ...



details:   https://anonhg.NetBSD.org/src/rev/c222b010c023
branches:  trunk
changeset: 781153:c222b010c023
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Thu Aug 23 09:59:13 2012 +0000

description:
Add support newer LSI RAID controllers based on the SAS2208 chip,
codenamed "ThunderBolt". Add tagged queuing support for all adapters
supported by mfi(4).
Tested with a MegaRAID SAS 9265-8i adapter, and an older Dell PERC 5/i.

diffstat:

 sys/dev/ic/mfi.c      |  1161 ++++++++++++++++++++++++++++++++++++++++++++----
 sys/dev/ic/mfireg.h   |   855 ++++++++++++++++++++++++++++++++---
 sys/dev/ic/mfivar.h   |    53 +-
 sys/dev/pci/mfi_pci.c |    52 +-
 4 files changed, 1913 insertions(+), 208 deletions(-)

diffs (truncated from 2891 to 300 lines):

diff -r fff0d46308d7 -r c222b010c023 sys/dev/ic/mfi.c
--- a/sys/dev/ic/mfi.c  Thu Aug 23 01:30:54 2012 +0000
+++ b/sys/dev/ic/mfi.c  Thu Aug 23 09:59:13 2012 +0000
@@ -1,5 +1,30 @@
-/* $NetBSD: mfi.c,v 1.42 2012/08/05 22:47:36 bouyer Exp $ */
+/* $NetBSD: mfi.c,v 1.43 2012/08/23 09:59:13 bouyer Exp $ */
 /* $OpenBSD: mfi.c,v 1.66 2006/11/28 23:59:45 dlg Exp $ */
+
+/*
+ * Copyright (c) 2012 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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) 2006 Marco Peereboom <marco%peereboom.us@localhost>
  *
@@ -16,8 +41,39 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+ /*-
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *            Copyright 1994-2009 The FreeBSD Project.
+ *            All rights reserved.
+ *
+ * 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 FREEBSD PROJECT``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 FREEBSD PROJECT 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.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies,either expressed or implied, of the FreeBSD Project.
+ */
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.42 2012/08/05 22:47:36 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.43 2012/08/23 09:59:13 bouyer Exp $");
 
 #include "bio.h"
 
@@ -29,6 +85,7 @@
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/proc.h>
+#include <sys/cpu.h>
 
 #include <uvm/uvm_param.h>
 
@@ -50,14 +107,15 @@
 
 #ifdef MFI_DEBUG
 uint32_t       mfi_debug = 0
-/*                 | MFI_D_CMD */
+/*                 | MFI_D_CMD  */
 /*                 | MFI_D_INTR */
 /*                 | MFI_D_MISC */
 /*                 | MFI_D_DMA */
-                   | MFI_D_IOCTL
+/*                 | MFI_D_IOCTL */
 /*                 | MFI_D_RW */
 /*                 | MFI_D_MEM */
 /*                 | MFI_D_CCB */
+/*                 | MFI_D_SYNC */
                ;
 #endif
 
@@ -82,9 +140,10 @@
 
 /* commands */
 static int             mfi_scsi_ld(struct mfi_ccb *, struct scsipi_xfer *);
-static int             mfi_scsi_io(struct mfi_ccb *, struct scsipi_xfer *,
-                               uint32_t, uint32_t);
-static void            mfi_scsi_xs_done(struct mfi_ccb *);
+static int             mfi_scsi_ld_io(struct mfi_ccb *, struct scsipi_xfer *,
+                               uint64_t, uint32_t);
+static void            mfi_scsi_ld_done(struct mfi_ccb *);
+static void            mfi_scsi_xs_done(struct mfi_ccb *, int, int);
 static int             mfi_mgmt_internal(struct mfi_softc *,
                            uint32_t, uint32_t, uint32_t, void *, uint8_t *);
 static int             mfi_mgmt(struct mfi_ccb *,struct scsipi_xfer *,
@@ -120,7 +179,8 @@
        mfi_xscale_intr_dis,
        mfi_xscale_intr_ena,
        mfi_xscale_intr,
-       mfi_xscale_post
+       mfi_xscale_post,
+       mfi_scsi_ld_io,
 };
 
 static uint32_t        mfi_ppc_fw_state(struct mfi_softc *sc);
@@ -134,7 +194,8 @@
        mfi_ppc_intr_dis,
        mfi_ppc_intr_ena,
        mfi_ppc_intr,
-       mfi_ppc_post
+       mfi_ppc_post,
+       mfi_scsi_ld_io,
 };
 
 uint32_t       mfi_gen2_fw_state(struct mfi_softc *sc);
@@ -148,7 +209,8 @@
        mfi_gen2_intr_dis,
        mfi_gen2_intr_ena,
        mfi_gen2_intr,
-       mfi_gen2_post
+       mfi_gen2_post,
+       mfi_scsi_ld_io,
 };
 
 u_int32_t      mfi_skinny_fw_state(struct mfi_softc *);
@@ -162,7 +224,33 @@
        mfi_skinny_intr_dis,
        mfi_skinny_intr_ena,
        mfi_skinny_intr,
-       mfi_skinny_post
+       mfi_skinny_post,
+       mfi_scsi_ld_io,
+};
+
+static int     mfi_tbolt_init_desc_pool(struct mfi_softc *);
+static int     mfi_tbolt_init_MFI_queue(struct mfi_softc *);
+static void    mfi_tbolt_build_mpt_ccb(struct mfi_ccb *);
+int            mfi_tbolt_scsi_ld_io(struct mfi_ccb *, struct scsipi_xfer *,
+                   uint64_t, uint32_t);
+static void    mfi_tbolt_scsi_ld_done(struct mfi_ccb *);
+static int     mfi_tbolt_create_sgl(struct mfi_ccb *, int);
+void           mfi_tbolt_sync_map_info(struct work *, void *);
+static void    mfi_sync_map_complete(struct mfi_ccb *);
+
+u_int32_t      mfi_tbolt_fw_state(struct mfi_softc *);
+void           mfi_tbolt_intr_dis(struct mfi_softc *);
+void           mfi_tbolt_intr_ena(struct mfi_softc *);
+int            mfi_tbolt_intr(struct mfi_softc *sc);
+void           mfi_tbolt_post(struct mfi_softc *, struct mfi_ccb *);
+
+static const struct mfi_iop_ops mfi_iop_tbolt = {
+       mfi_tbolt_fw_state,
+       mfi_tbolt_intr_dis,
+       mfi_tbolt_intr_ena,
+       mfi_tbolt_intr,
+       mfi_tbolt_post,
+       mfi_tbolt_scsi_ld_io,
 };
 
 #define mfi_fw_state(_s)       ((_s)->sc_iop->mio_fw_state(_s))
@@ -186,6 +274,8 @@
        splx(s);
 
        DNPRINTF(MFI_D_CCB, "%s: mfi_get_ccb: %p\n", DEVNAME(sc), ccb);
+       if (ccb == NULL)
+               aprint_error_dev(sc->sc_dev, "out of ccb\n");
 
        return ccb;
 }
@@ -211,7 +301,12 @@
        ccb->ccb_sgl = NULL;
        ccb->ccb_data = NULL;
        ccb->ccb_len = 0;
-
+       if (sc->sc_ioptype == MFI_IOP_TBOLT) {
+               /* erase tb_request_desc but preserve SMID */
+               int index = ccb->ccb_tb_request_desc.header.SMID;
+               ccb->ccb_tb_request_desc.words = 0;
+               ccb->ccb_tb_request_desc.header.SMID = index;
+       }
        s = splbio();
        TAILQ_INSERT_TAIL(&sc->sc_ccb_freeq, ccb, ccb_link);
        splx(s);
@@ -223,12 +318,12 @@
        struct mfi_ccb          *ccb;
        uint32_t                i;
 
-       DNPRINTF(MFI_D_CCB, "%s: mfi_init_ccb\n", DEVNAME(sc));
+       DNPRINTF(MFI_D_CCB, "%s: mfi_destroy_ccb\n", DEVNAME(sc));
 
 
        for (i = 0; (ccb = mfi_get_ccb(sc)) != NULL; i++) {
                /* create a dma map for transfer */
-               bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
+               bus_dmamap_destroy(sc->sc_datadmat, ccb->ccb_dmamap);
        }
 
        if (i < sc->sc_max_cmds)
@@ -245,11 +340,24 @@
        struct mfi_ccb          *ccb;
        uint32_t                i;
        int                     error;
+       bus_addr_t              io_req_base_phys;
+       uint8_t                 *io_req_base;
+       int offset;
 
        DNPRINTF(MFI_D_CCB, "%s: mfi_init_ccb\n", DEVNAME(sc));
 
        sc->sc_ccb = malloc(sizeof(struct mfi_ccb) * sc->sc_max_cmds,
            M_DEVBUF, M_WAITOK|M_ZERO);
+       if (sc->sc_ioptype == MFI_IOP_TBOLT) {
+               /*
+                * The first 256 bytes (SMID 0) is not used.
+                * Don't add to the cmd list.
+                */
+               io_req_base = (uint8_t *)MFIMEM_KVA(sc->sc_tbolt_reqmsgpool) +
+                       MEGASAS_THUNDERBOLT_NEW_MSG_SIZE;
+               io_req_base_phys = MFIMEM_DVA(sc->sc_tbolt_reqmsgpool) +
+                       MEGASAS_THUNDERBOLT_NEW_MSG_SIZE;
+       }
 
        for (i = 0; i < sc->sc_max_cmds; i++) {
                ccb = &sc->sc_ccb[i];
@@ -270,14 +378,30 @@
                    (MFIMEM_DVA(sc->sc_sense) + MFI_SENSE_SIZE * i);
 
                /* create a dma map for transfer */
-               error = bus_dmamap_create(sc->sc_dmat,
+               error = bus_dmamap_create(sc->sc_datadmat,
                    MAXPHYS, sc->sc_max_sgl, MAXPHYS, 0,
                    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ccb_dmamap);
                if (error) {
-                       printf("%s: cannot create ccb dmamap (%d)\n",
-                           DEVNAME(sc), error);
+                       aprint_error_dev(sc->sc_dev,
+                           "cannot create ccb dmamap (%d)\n", error);
                        goto destroy;
                }
+               if (sc->sc_ioptype == MFI_IOP_TBOLT) {
+                       offset = MEGASAS_THUNDERBOLT_NEW_MSG_SIZE * i;
+                       ccb->ccb_tb_io_request =
+                           (struct mfi_mpi2_request_raid_scsi_io *)
+                           (io_req_base + offset);
+                       ccb->ccb_tb_pio_request =
+                           io_req_base_phys + offset;
+                       offset = MEGASAS_MAX_SZ_CHAIN_FRAME * i;
+                       ccb->ccb_tb_sg_frame =
+                           (mpi2_sge_io_union *)(sc->sc_reply_pool_limit +
+                           offset);
+                       ccb->ccb_tb_psg_frame = sc->sc_sg_frame_busaddr +
+                           offset;
+                       /* SMID 0 is reserved. Set SMID/index from 1 */
+                       ccb->ccb_tb_request_desc.header.SMID = i + 1;
+               }
 
                DNPRINTF(MFI_D_CCB,
                    "ccb(%d): %p frame: %#lx (%#lx) sense: %#lx (%#lx) map: %#lx\n",
@@ -296,7 +420,7 @@
        while (i) {
                i--;
                ccb = &sc->sc_ccb[i];
-               bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
+               bus_dmamap_destroy(sc->sc_datadmat, ccb->ccb_dmamap);
        }
 
        free(sc->sc_ccb, M_DEVBUF);
@@ -413,17 +537,19 @@
                cur_state = fw_state;
                switch (fw_state) {
                case MFI_STATE_FAULT:
-                       printf("%s: firmware fault\n", DEVNAME(sc));
+                       aprint_error_dev(sc->sc_dev, "firmware fault\n");
                        return 1;
                case MFI_STATE_WAIT_HANDSHAKE:
-                       if (sc->sc_ioptype == MFI_IOP_SKINNY)
+                       if (sc->sc_ioptype == MFI_IOP_SKINNY ||
+                           sc->sc_ioptype == MFI_IOP_TBOLT)
                                mfi_write(sc, MFI_SKINNY_IDB, MFI_INIT_CLEAR_HANDSHAKE);
                        else



Home | Main Index | Thread Index | Old Index