diff options
author | scottl <scottl@FreeBSD.org> | 2007-08-25 23:58:45 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2007-08-25 23:58:45 +0000 |
commit | 975e1272a0dce9299febe1a3ca5a8dcda1dd4f1b (patch) | |
tree | bc071779902a9a4b8d691bd9db0412ffc1be3def /sys | |
parent | 2e3a8d80169839d59c7e290fa44af4d1f3b691c2 (diff) | |
download | FreeBSD-src-975e1272a0dce9299febe1a3ca5a8dcda1dd4f1b.zip FreeBSD-src-975e1272a0dce9299febe1a3ca5a8dcda1dd4f1b.tar.gz |
Update the MFI driver to support new "1078" series of hardware. This
includes the upcoming Dell PERC6 series. Many thanks to LSI for
contributing this code.
Submitted by: LSI
Approved by: re
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/mfi/mfi.c | 141 | ||||
-rw-r--r-- | sys/dev/mfi/mfi_pci.c | 33 | ||||
-rw-r--r-- | sys/dev/mfi/mfireg.h | 37 | ||||
-rw-r--r-- | sys/dev/mfi/mfivar.h | 34 |
4 files changed, 221 insertions, 24 deletions
diff --git a/sys/dev/mfi/mfi.c b/sys/dev/mfi/mfi.c index 3a96d96..592aa00 100644 --- a/sys/dev/mfi/mfi.c +++ b/sys/dev/mfi/mfi.c @@ -23,6 +23,32 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +/*- + * Copyright (c) 2007 LSI Corp. + * Copyright (c) 2007 Rajesh Prabhakaran. + * 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. + */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -66,7 +92,6 @@ static int mfi_dcmd_command(struct mfi_softc *, struct mfi_command **, static void mfi_data_cb(void *, bus_dma_segment_t *, int, int); static void mfi_startup(void *arg); static void mfi_intr(void *arg); -static void mfi_enable_intr(struct mfi_softc *sc); static void mfi_ldprobe(struct mfi_softc *sc); static int mfi_aen_register(struct mfi_softc *sc, int seq, int locale); static void mfi_aen_complete(struct mfi_command *); @@ -81,7 +106,14 @@ static void mfi_complete(struct mfi_softc *, struct mfi_command *); static int mfi_abort(struct mfi_softc *, struct mfi_command *); static int mfi_linux_ioctl_int(struct cdev *, u_long, caddr_t, int, d_thread_t *); static void mfi_timeout(void *); - +static void mfi_enable_intr_xscale(struct mfi_softc *sc); +static void mfi_enable_intr_ppc(struct mfi_softc *sc); +static int32_t mfi_read_fw_status_xscale(struct mfi_softc *sc); +static int32_t mfi_read_fw_status_ppc(struct mfi_softc *sc); +static int mfi_check_clear_intr_xscale(struct mfi_softc *sc); +static int mfi_check_clear_intr_ppc(struct mfi_softc *sc); +static void mfi_issue_cmd_xscale(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt); +static void mfi_issue_cmd_ppc(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt); SYSCTL_NODE(_hw, OID_AUTO, mfi, CTLFLAG_RD, 0, "MFI driver parameters"); static int mfi_event_locale = MFI_EVT_LOCALE_ALL; @@ -114,17 +146,80 @@ MALLOC_DEFINE(M_MFIBUF, "mfibuf", "Buffers for the MFI driver"); #define MFI_INQ_LENGTH SHORT_INQUIRY_LENGTH +static void +mfi_enable_intr_xscale(struct mfi_softc *sc) +{ + MFI_WRITE4(sc, MFI_OMSK, 0x01); +} + +static void +mfi_enable_intr_ppc(struct mfi_softc *sc) +{ + MFI_WRITE4(sc, MFI_ODCR0, 0xFFFFFFFF); + MFI_WRITE4(sc, MFI_OMSK, ~MFI_1078_EIM); +} + +static int32_t +mfi_read_fw_status_xscale(struct mfi_softc *sc) +{ + return MFI_READ4(sc, MFI_OMSG0); +} + +static int32_t +mfi_read_fw_status_ppc(struct mfi_softc *sc) +{ + return MFI_READ4(sc, MFI_OSP0); +} + +static int +mfi_check_clear_intr_xscale(struct mfi_softc *sc) +{ + int32_t status; + + status = MFI_READ4(sc, MFI_OSTS); + if ((status & MFI_OSTS_INTR_VALID) == 0) + return 1; + + MFI_WRITE4(sc, MFI_OSTS, status); + return 0; + } + +static int +mfi_check_clear_intr_ppc(struct mfi_softc *sc) +{ + int32_t status; + + status = MFI_READ4(sc, MFI_OSTS); + if (!status) + return 1; + + MFI_WRITE4(sc, MFI_ODCR0, status); + return 0; + } + +static void +mfi_issue_cmd_xscale(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt) +{ + MFI_WRITE4(sc, MFI_IQP,(bus_add >>3)|frame_cnt); +} + +static void +mfi_issue_cmd_ppc(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt) +{ + MFI_WRITE4(sc, MFI_IQP, (bus_add |frame_cnt <<1)|1 ); +} + static int mfi_transition_firmware(struct mfi_softc *sc) { int32_t fw_state, cur_state; int max_wait, i; - fw_state = MFI_READ4(sc, MFI_OMSG0) & MFI_FWSTATE_MASK; + fw_state = sc->mfi_read_fw_status(sc)& MFI_FWSTATE_MASK; while (fw_state != MFI_FWSTATE_READY) { if (bootverbose) device_printf(sc->mfi_dev, "Waiting for firmware to " - "become ready\n"); + "become ready\n"); cur_state = fw_state; switch (fw_state) { case MFI_FWSTATE_FAULT: @@ -153,7 +248,7 @@ mfi_transition_firmware(struct mfi_softc *sc) return (ENXIO); } for (i = 0; i < (max_wait * 10); i++) { - fw_state = MFI_READ4(sc, MFI_OMSG0) & MFI_FWSTATE_MASK; + fw_state = sc->mfi_read_fw_status(sc) & MFI_FWSTATE_MASK; if (fw_state == cur_state) DELAY(100000); else @@ -183,6 +278,7 @@ mfi_attach(struct mfi_softc *sc) uint32_t status; int error, commsz, framessz, sensesz; int frames, unit, max_fw_sge; + device_printf(sc->mfi_dev, "Megaraid SAS driver Ver 2.00 \n"); mtx_init(&sc->mfi_io_lock, "MFI I/O lock", NULL, MTX_DEF); sx_init(&sc->mfi_config_lock, "MFI config"); @@ -195,6 +291,20 @@ mfi_attach(struct mfi_softc *sc) mfi_initq_busy(sc); mfi_initq_bio(sc); + if (sc->mfi_flags & MFI_FLAGS_1064R) { + sc->mfi_enable_intr = mfi_enable_intr_xscale; + sc->mfi_read_fw_status = mfi_read_fw_status_xscale; + sc->mfi_check_clear_intr = mfi_check_clear_intr_xscale; + sc->mfi_issue_cmd = mfi_issue_cmd_xscale; + } + else { + sc->mfi_enable_intr = mfi_enable_intr_ppc; + sc->mfi_read_fw_status = mfi_read_fw_status_ppc; + sc->mfi_check_clear_intr = mfi_check_clear_intr_ppc; + sc->mfi_issue_cmd = mfi_issue_cmd_ppc; + } + + /* Before we get too far, see if the firmware is working */ if ((error = mfi_transition_firmware(sc)) != 0) { device_printf(sc->mfi_dev, "Firmware not in READY state, " @@ -209,7 +319,7 @@ mfi_attach(struct mfi_softc *sc) * It would be nice if these constants were available at runtime * instead of compile time. */ - status = MFI_READ4(sc, MFI_OMSG0); + status = sc->mfi_read_fw_status(sc); sc->mfi_max_fw_cmds = status & MFI_FWSTATE_MAXCMD_MASK; max_fw_sge = (status & MFI_FWSTATE_MAXSGL_MASK) >> 16; sc->mfi_max_sge = min(max_fw_sge, ((MAXPHYS / PAGE_SIZE) + 1)); @@ -777,7 +887,7 @@ mfi_startup(void *arg) config_intrhook_disestablish(&sc->mfi_ich); - mfi_enable_intr(sc); + sc->mfi_enable_intr(sc); sx_xlock(&sc->mfi_config_lock); mtx_lock(&sc->mfi_io_lock); mfi_ldprobe(sc); @@ -790,16 +900,13 @@ mfi_intr(void *arg) { struct mfi_softc *sc; struct mfi_command *cm; - uint32_t status, pi, ci, context; + uint32_t pi, ci, context; sc = (struct mfi_softc *)arg; - status = MFI_READ4(sc, MFI_OSTS); - if ((status & MFI_OSTS_INTR_VALID) == 0) + if (sc->mfi_check_clear_intr(sc)) return; - MFI_WRITE4(sc, MFI_OSTS, status); - pi = sc->mfi_comms->hw_pi; ci = sc->mfi_comms->hw_ci; mtx_lock(&sc->mfi_io_lock); @@ -859,13 +966,6 @@ mfi_shutdown(struct mfi_softc *sc) } static void -mfi_enable_intr(struct mfi_softc *sc) -{ - - MFI_WRITE4(sc, MFI_OMSK, 0x01); -} - -static void mfi_ldprobe(struct mfi_softc *sc) { struct mfi_frame_header *hdr; @@ -1657,8 +1757,7 @@ mfi_send_frame(struct mfi_softc *sc, struct mfi_command *cm) if (cm->cm_extra_frames > 7) cm->cm_extra_frames = 7; - MFI_WRITE4(sc, MFI_IQP, (cm->cm_frame_busaddr >> 3) | - cm->cm_extra_frames); + sc->mfi_issue_cmd(sc,cm->cm_frame_busaddr,cm->cm_extra_frames); if ((cm->cm_flags & MFI_CMD_POLLED) == 0) return (0); diff --git a/sys/dev/mfi/mfi_pci.c b/sys/dev/mfi/mfi_pci.c index 45e8311..7085008 100644 --- a/sys/dev/mfi/mfi_pci.c +++ b/sys/dev/mfi/mfi_pci.c @@ -23,6 +23,32 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +/*- + * Copyright (c) 2007 LSI Corp. + * Copyright (c) 2007 Rajesh Prabhakaran. + * 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. + */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -88,9 +114,10 @@ struct mfi_ident { int flags; const char *desc; } mfi_identifiers[] = { - {0x1000, 0x0411, 0xffff, 0xffff, 0, "LSI MegaSAS 1064R"}, /* Brocton IOP */ - {0x1000, 0x0413, 0xffff, 0xffff, 0, "LSI MegaSAS 1064R"}, /* Verde ZCR */ - {0x1028, 0x0015, 0xffff, 0xffff, 0, "Dell PERC 5/i"}, + {0x1000, 0x0411, 0xffff, 0xffff, MFI_FLAGS_1064R, "LSI MegaSAS 1064R"}, /* Brocton IOP */ + {0x1000, 0x0413, 0xffff, 0xffff, MFI_FLAGS_1064R, "LSI MegaSAS 1064R"}, /* Verde ZCR */ + {0x1028, 0x0015, 0xffff, 0xffff, MFI_FLAGS_1064R, "Dell PERC 5/i"}, + {0x1000, 0x0060, 0xffff, 0xffff, MFI_FLAGS_1078, "LSI MegaSAS 1078"}, {0, 0, 0, 0, 0, NULL} }; diff --git a/sys/dev/mfi/mfireg.h b/sys/dev/mfi/mfireg.h index 841756c..2bd8a51 100644 --- a/sys/dev/mfi/mfireg.h +++ b/sys/dev/mfi/mfireg.h @@ -23,6 +23,32 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +/*- + * Copyright (c) 2007 LSI Corp. + * Copyright (c) 2007 Rajesh Prabhakaran. + * 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. + */ #ifndef _MFIREG_H #define _MFIREG_H @@ -56,6 +82,17 @@ __FBSDID("$FreeBSD$"); #define MFI_IQP 0x40 /* Inbound queue port */ #define MFI_OQP 0x44 /* Outbound queue port */ +/* + * 1078 specific related register + */ +#define MFI_ODR0 0x9c /* outbound doorbell register0 */ +#define MFI_ODCR0 0xa0 /* outbound doorbell clear register0 */ +#define MFI_OSP0 0xb0 /* outbound scratch pad0 */ +#define MFI_1078_EIM 0x80000004 /* 1078 enable intrrupt mask */ +#define MFI_RMI 0x2 /* reply message interrupt */ +#define MFI_1078_RM 0x80000000 /* reply 1078 message interrupt */ +#define MFI_ODC 0x4 /* outbound doorbell change interrupt */ + /* Bits for MFI_OSTS */ #define MFI_OSTS_INTR_VALID 0x00000002 diff --git a/sys/dev/mfi/mfivar.h b/sys/dev/mfi/mfivar.h index 80714a0..f6b633b 100644 --- a/sys/dev/mfi/mfivar.h +++ b/sys/dev/mfi/mfivar.h @@ -23,6 +23,32 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +/*- + * Copyright (c) 2007 LSI Corp. + * Copyright (c) 2007 Rajesh Prabhakaran. + * 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. + */ #ifndef _MFIVAR_H #define _MFIVAR_H @@ -105,6 +131,8 @@ struct mfi_softc { #define MFI_FLAGS_QFRZN (1<<1) #define MFI_FLAGS_OPEN (1<<2) #define MFI_FLAGS_STOP (1<<3) +#define MFI_FLAGS_1064R (1<<4) +#define MFI_FLAGS_1078 (1<<5) struct mfi_hwcomms *mfi_comms; TAILQ_HEAD(,mfi_command) mfi_free; @@ -193,6 +221,12 @@ struct mfi_softc { struct callout mfi_watchdog_callout; struct mtx mfi_io_lock; struct sx mfi_config_lock; + + /* Controller type specific interfaces */ + void (*mfi_enable_intr)(struct mfi_softc *sc); + int32_t (*mfi_read_fw_status)(struct mfi_softc *sc); + int (*mfi_check_clear_intr)(struct mfi_softc *sc); + void (*mfi_issue_cmd)(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt); }; extern int mfi_attach(struct mfi_softc *); |