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