Source-Changes-HG archive

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

[src/netbsd-6]: src/sys/dev Pull up following revision(s) (requested by bouye...



details:   https://anonhg.NetBSD.org/src/rev/115e05ba3cd4
branches:  netbsd-6
changeset: 775396:115e05ba3cd4
user:      riz <riz%NetBSD.org@localhost>
date:      Wed Oct 24 03:19:19 2012 +0000

description:
Pull up following revision(s) (requested by bouyer in ticket #628):
        sys/dev/ic/mfi.c: revision 1.40
        sys/dev/ic/mfi.c: revision 1.41
        sys/dev/ic/mfi.c: revision 1.42
        sys/dev/ic/mfi.c: revision 1.43
        sys/dev/ic/mfi.c: revision 1.44
        sys/dev/ic/mfi.c: revision 1.45
        sys/dev/ic/mfi.c: revision 1.46
        sys/dev/pci/pcidevs: revision 1.1128
        sys/dev/pci/mfi_pci.c: revision 1.15
        sys/dev/pci/mfi_pci.c: revision 1.16
        sys/dev/ic/mfi.c: revision 1.39
        sys/dev/ic/mfivar.h: revision 1.16
        sys/dev/ic/mfireg.h: revision 1.6
        sys/dev/ic/mfivar.h: revision 1.17
        sys/dev/ic/mfireg.h: revision 1.7
        sys/dev/ic/mfivar.h: revision 1.18
        sys/dev/ic/mfivar.h: revision 1.19
Add some support for 64bit DMA but stick to 32bit DMA for now.
>From OpenBSD mfi.c rev 1.119.
Add LSI MegaRAID SAS2208
MFI_IOP_SKINNY is an enum not a single bit value, so it can't be used as
a bit flag. As sc_flags is really used to hold an enum mfi_iop value,
change it to enum mfi_iop and rename to sc_ioptype. While there init it
in mfi_attach() instead of mfi_pci_attach().
sg64.len is 32bits, so use htole32()
Really init sc_ioptype in mfi_attach()
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.
Avoid "unused variable" warning for non-DIAGNOSTIC kernels.
Pointed out by Havard Eidnes
After discussion on tech-kern@, fix performance issue related to
cache flush commands from WAPBL, by skipping the cache flush if the
BBU is present and considered good. Users which still want the write back
cache with a non-working BBU can set vfs.wapbl.flush_disk_cache to 0.
- add commands to monitor the BBU state. Add a boolean BBU sensor
  to monitor the BBU state via sysmon_envsys(9).
- if the BBU is considered good, turn SCSI_SYNCHRONIZE_CACHE_10 and
  SCSI_SYNCHRONIZE_CACHE_16 commands from upper layer into NOOPs.
  While there, handle SCSI_SYNCHRONIZE_CACHE_16 in addition to
  SCSI_SYNCHRONIZE_CACHE_10.
- Add a shutdown pmf(9) handler, which flushes the cache and shutdown the
  firmware
- on detach, also flush cache and shutdown firmware.
- on attach, print the firmware-provided name, and the BBU state
Tested on a LSI MegaRAID SAS 9265-8i and a PERC 5/i Integrated
Make MFI_DEBUG build on i386.
Report BBU state changes with aprint_normal(), it seems that sysmon_envsys()
doens't report changes for ENVSYS_INDICATOR as it does for ENVSYS_DRIVE.

diffstat:

 sys/dev/ic/mfi.c      |  1467 ++++++++++++++++++++++++++++++++++++++++++++----
 sys/dev/ic/mfireg.h   |   940 ++++++++++++++++++++++++++++--
 sys/dev/ic/mfivar.h   |    57 +-
 sys/dev/pci/mfi_pci.c |    54 +-
 sys/dev/pci/pcidevs   |     3 +-
 5 files changed, 2274 insertions(+), 247 deletions(-)

diffs (truncated from 3509 to 300 lines):

diff -r 12e2e8bb6c69 -r 115e05ba3cd4 sys/dev/ic/mfi.c
--- a/sys/dev/ic/mfi.c  Tue Oct 23 20:20:15 2012 +0000
+++ b/sys/dev/ic/mfi.c  Wed Oct 24 03:19:19 2012 +0000
@@ -1,5 +1,30 @@
-/* $NetBSD: mfi.c,v 1.36.8.2 2012/03/22 23:04:27 riz Exp $ */
+/* $NetBSD: mfi.c,v 1.36.8.3 2012/10/24 03:19:19 riz 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.36.8.2 2012/03/22 23:04:27 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.36.8.3 2012/10/24 03:19:19 riz 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
 
@@ -75,6 +133,12 @@
 static int             mfi_transition_firmware(struct mfi_softc *);
 static int             mfi_initialize_firmware(struct mfi_softc *);
 static int             mfi_get_info(struct mfi_softc *);
+static int             mfi_get_bbu(struct mfi_softc *,
+                           struct mfi_bbu_status *);
+/* return codes for mfi_get_bbu */
+#define MFI_BBU_GOOD   0
+#define MFI_BBU_BAD    1
+#define MFI_BBU_UNKNOWN        2
 static uint32_t                mfi_read(struct mfi_softc *, bus_size_t);
 static void            mfi_write(struct mfi_softc *, bus_size_t, uint32_t);
 static int             mfi_poll(struct mfi_ccb *);
@@ -82,11 +146,12 @@
 
 /* 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_mgmt_internal(struct mfi_softc *,
-                           uint32_t, uint32_t, uint32_t, void *, uint8_t *);
+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 *, bool);
 static int             mfi_mgmt(struct mfi_ccb *,struct scsipi_xfer *,
                            uint32_t, uint32_t, uint32_t, void *, uint8_t *);
 static void            mfi_mgmt_done(struct mfi_ccb *);
@@ -108,6 +173,9 @@
 static void            mfi_sensor_refresh(struct sysmon_envsys *,
                                envsys_data_t *);
 #endif /* NBIO > 0 */
+static bool            mfi_shutdown(device_t, int);
+static bool            mfi_suspend(device_t, const pmf_qual_t *);
+static bool            mfi_resume(device_t, const pmf_qual_t *);
 
 static uint32_t        mfi_xscale_fw_state(struct mfi_softc *sc);
 static void            mfi_xscale_intr_ena(struct mfi_softc *sc);
@@ -120,7 +188,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 +203,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 +218,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 +233,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 +283,8 @@
        splx(s);
 
        DNPRINTF(MFI_D_CCB, "%s: mfi_get_ccb: %p\n", DEVNAME(sc), ccb);
+       if (__predict_false(ccb == NULL && sc->sc_running))
+               aprint_error_dev(sc->sc_dev, "out of ccb\n");
 
        return ccb;
 }
@@ -211,7 +310,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 +327,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 +349,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 +387,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 */



Home | Main Index | Thread Index | Old Index