From owner-svn-src-all@FreeBSD.ORG Sun Dec 21 02:35:23 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 9C2C9527; Sun, 21 Dec 2014 02:35:23 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 85C412013; Sun, 21 Dec 2014 02:35:23 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sBL2ZN0G014342; Sun, 21 Dec 2014 02:35:23 GMT (envelope-from smh@FreeBSD.org) Received: (from smh@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sBL2ZNB6014340; Sun, 21 Dec 2014 02:35:23 GMT (envelope-from smh@FreeBSD.org) Message-Id: <201412210235.sBL2ZNB6014340@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: smh set sender to smh@FreeBSD.org using -f From: Steven Hartland Date: Sun, 21 Dec 2014 02:35:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r275976 - in stable/10/sys: dev/mrsas modules/mrsas modules/mrsas/mrsas_linux X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Dec 2014 02:35:23 -0000 Author: smh Date: Sun Dec 21 02:35:22 2014 New Revision: 275976 URL: https://svnweb.freebsd.org/changeset/base/275976 Log: MFC r272735: Support upto 256VD. MFC r272737: Support 32-bit linux binaries on FreeBSD 64bit. MFC r272738: Fix the minor svn add issue. MFC r272739: Extended MSI-x vectors support for Invader and Fury(12Gb/s HBA). MFC r272740: Add d_poll support. MFC r272741: Fix leak of mfi cmd in the passthru and correctly limit oustanding. MFC r272742: Import vendor Phase 6.5 driver MFC r272744: Style (9) fixes. MFC r273040: Fix for build issue on i386.xen and amd64.xen. Sponsored by: Multiplay Added: stable/10/sys/dev/mrsas/mrsas_linux.c - copied, changed from r272737, head/sys/dev/mrsas/mrsas_linux.c stable/10/sys/modules/mrsas/mrsas_linux/ - copied from r272737, head/sys/modules/mrsas/mrsas_linux/ Modified: stable/10/sys/dev/mrsas/mrsas.c stable/10/sys/dev/mrsas/mrsas.h stable/10/sys/dev/mrsas/mrsas_cam.c stable/10/sys/dev/mrsas/mrsas_fp.c stable/10/sys/dev/mrsas/mrsas_ioctl.c stable/10/sys/dev/mrsas/mrsas_ioctl.h stable/10/sys/modules/mrsas/Makefile stable/10/sys/modules/mrsas/mrsas_linux/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/mrsas/mrsas.c ============================================================================== --- stable/10/sys/dev/mrsas/mrsas.c Sun Dec 21 01:39:21 2014 (r275975) +++ stable/10/sys/dev/mrsas/mrsas.c Sun Dec 21 02:35:22 2014 (r275976) @@ -1,43 +1,38 @@ /* - * Copyright (c) 2014, LSI Corp. - * All rights reserved. - * Author: Marian Choy + * Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy * Support: freebsdraid@lsi.com * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. Neither the name of the 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 COPYRIGHT HOLDERS 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 - * COPYRIGHT HOLDER 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 + * 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. Neither the name of the + * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 + * 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. * - * Send feedback to: - * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035 - * ATTN: MegaRaid FreeBSD + * Send feedback to: Mail to: LSI Corporation, 1621 + * Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD * */ @@ -54,18 +49,23 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include -/* - * Function prototypes +/* + * Function prototypes */ -static d_open_t mrsas_open; -static d_close_t mrsas_close; -static d_read_t mrsas_read; -static d_write_t mrsas_write; -static d_ioctl_t mrsas_ioctl; +static d_open_t mrsas_open; +static d_close_t mrsas_close; +static d_read_t mrsas_read; +static d_write_t mrsas_write; +static d_ioctl_t mrsas_ioctl; +static d_poll_t mrsas_poll; +static struct mrsas_mgmt_info mrsas_mgmt_info; static struct mrsas_ident *mrsas_find_ident(device_t); +static int mrsas_setup_msix(struct mrsas_softc *sc); +static int mrsas_allocate_msix(struct mrsas_softc *sc); static void mrsas_shutdown_ctlr(struct mrsas_softc *sc, u_int32_t opcode); static void mrsas_flush_cache(struct mrsas_softc *sc); static void mrsas_reset_reply_desc(struct mrsas_softc *sc); @@ -79,456 +79,476 @@ static int mrsas_setup_irq(struct mrsas_ static int mrsas_alloc_mem(struct mrsas_softc *sc); static int mrsas_init_fw(struct mrsas_softc *sc); static int mrsas_setup_raidmap(struct mrsas_softc *sc); -static int mrsas_complete_cmd(struct mrsas_softc *sc); +static int mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex); static int mrsas_clear_intr(struct mrsas_softc *sc); -static int mrsas_get_ctrl_info(struct mrsas_softc *sc, - struct mrsas_ctrl_info *ctrl_info); -static int mrsas_issue_blocked_abort_cmd(struct mrsas_softc *sc, - struct mrsas_mfi_cmd *cmd_to_abort); +static int +mrsas_get_ctrl_info(struct mrsas_softc *sc, + struct mrsas_ctrl_info *ctrl_info); +static int +mrsas_issue_blocked_abort_cmd(struct mrsas_softc *sc, + struct mrsas_mfi_cmd *cmd_to_abort); u_int32_t mrsas_read_reg(struct mrsas_softc *sc, int offset); -u_int8_t mrsas_build_mptmfi_passthru(struct mrsas_softc *sc, - struct mrsas_mfi_cmd *mfi_cmd); -int mrsas_transition_to_ready(struct mrsas_softc *sc, int ocr); -int mrsas_init_adapter(struct mrsas_softc *sc); -int mrsas_alloc_mpt_cmds(struct mrsas_softc *sc); -int mrsas_alloc_ioc_cmd(struct mrsas_softc *sc); -int mrsas_alloc_ctlr_info_cmd(struct mrsas_softc *sc); -int mrsas_ioc_init(struct mrsas_softc *sc); -int mrsas_bus_scan(struct mrsas_softc *sc); -int mrsas_issue_dcmd(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); -int mrsas_issue_polled(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); -int mrsas_reset_ctrl(struct mrsas_softc *sc); -int mrsas_wait_for_outstanding(struct mrsas_softc *sc); -int mrsas_issue_blocked_cmd(struct mrsas_softc *sc, - struct mrsas_mfi_cmd *cmd); -int mrsas_alloc_tmp_dcmd(struct mrsas_softc *sc, struct mrsas_tmp_dcmd *tcmd, - int size); -void mrsas_release_mfi_cmd(struct mrsas_mfi_cmd *cmd); -void mrsas_wakeup(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); -void mrsas_complete_aen(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); -void mrsas_complete_abort(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); -void mrsas_disable_intr(struct mrsas_softc *sc); -void mrsas_enable_intr(struct mrsas_softc *sc); -void mrsas_free_ioc_cmd(struct mrsas_softc *sc); -void mrsas_free_mem(struct mrsas_softc *sc); -void mrsas_free_tmp_dcmd(struct mrsas_tmp_dcmd *tmp); -void mrsas_isr(void *arg); -void mrsas_teardown_intr(struct mrsas_softc *sc); -void mrsas_addr_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error); -void mrsas_kill_hba (struct mrsas_softc *sc); -void mrsas_aen_handler(struct mrsas_softc *sc); -void mrsas_write_reg(struct mrsas_softc *sc, int offset, - u_int32_t value); -void mrsas_fire_cmd(struct mrsas_softc *sc, u_int32_t req_desc_lo, - u_int32_t req_desc_hi); -void mrsas_free_ctlr_info_cmd(struct mrsas_softc *sc); -void mrsas_complete_mptmfi_passthru(struct mrsas_softc *sc, - struct mrsas_mfi_cmd *cmd, u_int8_t status); -void mrsas_map_mpt_cmd_status(struct mrsas_mpt_cmd *cmd, u_int8_t status, - u_int8_t extStatus); -struct mrsas_mfi_cmd* mrsas_get_mfi_cmd(struct mrsas_softc *sc); -MRSAS_REQUEST_DESCRIPTOR_UNION * mrsas_build_mpt_cmd(struct mrsas_softc *sc, - struct mrsas_mfi_cmd *cmd); +u_int8_t +mrsas_build_mptmfi_passthru(struct mrsas_softc *sc, + struct mrsas_mfi_cmd *mfi_cmd); +int mrsas_transition_to_ready(struct mrsas_softc *sc, int ocr); +int mrsas_init_adapter(struct mrsas_softc *sc); +int mrsas_alloc_mpt_cmds(struct mrsas_softc *sc); +int mrsas_alloc_ioc_cmd(struct mrsas_softc *sc); +int mrsas_alloc_ctlr_info_cmd(struct mrsas_softc *sc); +int mrsas_ioc_init(struct mrsas_softc *sc); +int mrsas_bus_scan(struct mrsas_softc *sc); +int mrsas_issue_dcmd(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); +int mrsas_issue_polled(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); +int mrsas_reset_ctrl(struct mrsas_softc *sc); +int mrsas_wait_for_outstanding(struct mrsas_softc *sc); +int +mrsas_issue_blocked_cmd(struct mrsas_softc *sc, + struct mrsas_mfi_cmd *cmd); +int +mrsas_alloc_tmp_dcmd(struct mrsas_softc *sc, struct mrsas_tmp_dcmd *tcmd, + int size); +void mrsas_release_mfi_cmd(struct mrsas_mfi_cmd *cmd); +void mrsas_wakeup(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); +void mrsas_complete_aen(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); +void mrsas_complete_abort(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); +void mrsas_disable_intr(struct mrsas_softc *sc); +void mrsas_enable_intr(struct mrsas_softc *sc); +void mrsas_free_ioc_cmd(struct mrsas_softc *sc); +void mrsas_free_mem(struct mrsas_softc *sc); +void mrsas_free_tmp_dcmd(struct mrsas_tmp_dcmd *tmp); +void mrsas_isr(void *arg); +void mrsas_teardown_intr(struct mrsas_softc *sc); +void mrsas_addr_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error); +void mrsas_kill_hba(struct mrsas_softc *sc); +void mrsas_aen_handler(struct mrsas_softc *sc); +void +mrsas_write_reg(struct mrsas_softc *sc, int offset, + u_int32_t value); +void +mrsas_fire_cmd(struct mrsas_softc *sc, u_int32_t req_desc_lo, + u_int32_t req_desc_hi); +void mrsas_free_ctlr_info_cmd(struct mrsas_softc *sc); +void +mrsas_complete_mptmfi_passthru(struct mrsas_softc *sc, + struct mrsas_mfi_cmd *cmd, u_int8_t status); +void +mrsas_map_mpt_cmd_status(struct mrsas_mpt_cmd *cmd, u_int8_t status, + u_int8_t extStatus); +struct mrsas_mfi_cmd *mrsas_get_mfi_cmd(struct mrsas_softc *sc); + +MRSAS_REQUEST_DESCRIPTOR_UNION *mrsas_build_mpt_cmd + (struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); extern int mrsas_cam_attach(struct mrsas_softc *sc); extern void mrsas_cam_detach(struct mrsas_softc *sc); extern void mrsas_cmd_done(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd); extern void mrsas_free_frame(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd); extern int mrsas_alloc_mfi_cmds(struct mrsas_softc *sc); -extern void mrsas_release_mpt_cmd(struct mrsas_mpt_cmd *cmd); +extern void mrsas_release_mpt_cmd(struct mrsas_mpt_cmd *cmd); extern struct mrsas_mpt_cmd *mrsas_get_mpt_cmd(struct mrsas_softc *sc); -extern int mrsas_passthru(struct mrsas_softc *sc, void *arg); +extern int mrsas_passthru(struct mrsas_softc *sc, void *arg, u_long ioctlCmd); extern uint8_t MR_ValidateMapInfo(struct mrsas_softc *sc); -extern u_int16_t MR_GetLDTgtId(u_int32_t ld, MR_FW_RAID_MAP_ALL *map); -extern MR_LD_RAID *MR_LdRaidGet(u_int32_t ld, MR_FW_RAID_MAP_ALL *map); +extern u_int16_t MR_GetLDTgtId(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map); +extern MR_LD_RAID *MR_LdRaidGet(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map); extern void mrsas_xpt_freeze(struct mrsas_softc *sc); extern void mrsas_xpt_release(struct mrsas_softc *sc); -extern MRSAS_REQUEST_DESCRIPTOR_UNION *mrsas_get_request_desc(struct mrsas_softc *sc, - u_int16_t index); +extern MRSAS_REQUEST_DESCRIPTOR_UNION * +mrsas_get_request_desc(struct mrsas_softc *sc, + u_int16_t index); extern int mrsas_bus_scan_sim(struct mrsas_softc *sc, struct cam_sim *sim); static int mrsas_alloc_evt_log_info_cmd(struct mrsas_softc *sc); static void mrsas_free_evt_log_info_cmd(struct mrsas_softc *sc); -SYSCTL_NODE(_hw, OID_AUTO, mrsas, CTLFLAG_RD, 0, "MRSAS Driver Parameters"); +SYSCTL_NODE(_hw, OID_AUTO, mrsas, CTLFLAG_RD, 0, "MRSAS Driver Parameters"); -/** +/* * PCI device struct and table * */ typedef struct mrsas_ident { - uint16_t vendor; - uint16_t device; - uint16_t subvendor; - uint16_t subdevice; - const char *desc; -} MRSAS_CTLR_ID; + uint16_t vendor; + uint16_t device; + uint16_t subvendor; + uint16_t subdevice; + const char *desc; +} MRSAS_CTLR_ID; MRSAS_CTLR_ID device_table[] = { - {0x1000, MRSAS_TBOLT, 0xffff, 0xffff, "LSI Thunderbolt SAS Controller"}, - {0x1000, MRSAS_INVADER, 0xffff, 0xffff, "LSI Invader SAS Controller"}, - {0x1000, MRSAS_FURY, 0xffff, 0xffff, "LSI Fury SAS Controller"}, - {0, 0, 0, 0, NULL} + {0x1000, MRSAS_TBOLT, 0xffff, 0xffff, "LSI Thunderbolt SAS Controller"}, + {0x1000, MRSAS_INVADER, 0xffff, 0xffff, "LSI Invader SAS Controller"}, + {0x1000, MRSAS_FURY, 0xffff, 0xffff, "LSI Fury SAS Controller"}, + {0, 0, 0, 0, NULL} }; -/** - * Character device entry points +/* + * Character device entry points * */ static struct cdevsw mrsas_cdevsw = { - .d_version = D_VERSION, - .d_open = mrsas_open, - .d_close = mrsas_close, - .d_read = mrsas_read, - .d_write = mrsas_write, - .d_ioctl = mrsas_ioctl, - .d_name = "mrsas", + .d_version = D_VERSION, + .d_open = mrsas_open, + .d_close = mrsas_close, + .d_read = mrsas_read, + .d_write = mrsas_write, + .d_ioctl = mrsas_ioctl, + .d_poll = mrsas_poll, + .d_name = "mrsas", }; MALLOC_DEFINE(M_MRSAS, "mrsasbuf", "Buffers for the MRSAS driver"); -/** - * In the cdevsw routines, we find our softc by using the si_drv1 member - * of struct cdev. We set this variable to point to our softc in our - * attach routine when we create the /dev entry. +/* + * In the cdevsw routines, we find our softc by using the si_drv1 member of + * struct cdev. We set this variable to point to our softc in our attach + * routine when we create the /dev entry. */ int mrsas_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td) { - struct mrsas_softc *sc; + struct mrsas_softc *sc; - sc = dev->si_drv1; - return (0); + sc = dev->si_drv1; + return (0); } int mrsas_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td) { - struct mrsas_softc *sc; + struct mrsas_softc *sc; - sc = dev->si_drv1; - return (0); + sc = dev->si_drv1; + return (0); } int mrsas_read(struct cdev *dev, struct uio *uio, int ioflag) { - struct mrsas_softc *sc; + struct mrsas_softc *sc; - sc = dev->si_drv1; - return (0); + sc = dev->si_drv1; + return (0); } int mrsas_write(struct cdev *dev, struct uio *uio, int ioflag) { - struct mrsas_softc *sc; + struct mrsas_softc *sc; - sc = dev->si_drv1; - return (0); + sc = dev->si_drv1; + return (0); } -/** - * Register Read/Write Functions +/* + * Register Read/Write Functions * */ void mrsas_write_reg(struct mrsas_softc *sc, int offset, - u_int32_t value) + u_int32_t value) { - bus_space_tag_t bus_tag = sc->bus_tag; - bus_space_handle_t bus_handle = sc->bus_handle; + bus_space_tag_t bus_tag = sc->bus_tag; + bus_space_handle_t bus_handle = sc->bus_handle; - bus_space_write_4(bus_tag, bus_handle, offset, value); + bus_space_write_4(bus_tag, bus_handle, offset, value); } u_int32_t mrsas_read_reg(struct mrsas_softc *sc, int offset) { - bus_space_tag_t bus_tag = sc->bus_tag; - bus_space_handle_t bus_handle = sc->bus_handle; + bus_space_tag_t bus_tag = sc->bus_tag; + bus_space_handle_t bus_handle = sc->bus_handle; - return((u_int32_t)bus_space_read_4(bus_tag, bus_handle, offset)); + return ((u_int32_t)bus_space_read_4(bus_tag, bus_handle, offset)); } -/** - * Interrupt Disable/Enable/Clear Functions +/* + * Interrupt Disable/Enable/Clear Functions * */ -void mrsas_disable_intr(struct mrsas_softc *sc) +void +mrsas_disable_intr(struct mrsas_softc *sc) { - u_int32_t mask = 0xFFFFFFFF; - u_int32_t status; + u_int32_t mask = 0xFFFFFFFF; + u_int32_t status; - mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask), mask); - /* Dummy read to force pci flush */ - status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask)); + mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask), mask); + /* Dummy read to force pci flush */ + status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask)); } -void mrsas_enable_intr(struct mrsas_softc *sc) +void +mrsas_enable_intr(struct mrsas_softc *sc) { - u_int32_t mask = MFI_FUSION_ENABLE_INTERRUPT_MASK; - u_int32_t status; + u_int32_t mask = MFI_FUSION_ENABLE_INTERRUPT_MASK; + u_int32_t status; - mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status), ~0); - status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status)); + mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status), ~0); + status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status)); - mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask), ~mask); - status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask)); + mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask), ~mask); + status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask)); } -static int mrsas_clear_intr(struct mrsas_softc *sc) +static int +mrsas_clear_intr(struct mrsas_softc *sc) { - u_int32_t status, fw_status, fw_state; - - /* Read received interrupt */ - status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status)); + u_int32_t status, fw_status, fw_state; - /* If FW state change interrupt is received, write to it again to clear */ - if (status & MRSAS_FW_STATE_CHNG_INTERRUPT) { - fw_status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, - outbound_scratch_pad)); - fw_state = fw_status & MFI_STATE_MASK; - if (fw_state == MFI_STATE_FAULT) { - device_printf(sc->mrsas_dev, "FW is in FAULT state!\n"); - if(sc->ocr_thread_active) - wakeup(&sc->ocr_chan); - } - mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status), status); - mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status)); - return(1); - } + /* Read received interrupt */ + status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status)); - /* Not our interrupt, so just return */ - if (!(status & MFI_FUSION_ENABLE_INTERRUPT_MASK)) - return(0); + /* + * If FW state change interrupt is received, write to it again to + * clear + */ + if (status & MRSAS_FW_STATE_CHNG_INTERRUPT) { + fw_status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, + outbound_scratch_pad)); + fw_state = fw_status & MFI_STATE_MASK; + if (fw_state == MFI_STATE_FAULT) { + device_printf(sc->mrsas_dev, "FW is in FAULT state!\n"); + if (sc->ocr_thread_active) + wakeup(&sc->ocr_chan); + } + mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status), status); + mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status)); + return (1); + } + /* Not our interrupt, so just return */ + if (!(status & MFI_FUSION_ENABLE_INTERRUPT_MASK)) + return (0); - /* We got a reply interrupt */ - return(1); + /* We got a reply interrupt */ + return (1); } -/** - * PCI Support Functions +/* + * PCI Support Functions * */ -static struct mrsas_ident * mrsas_find_ident(device_t dev) +static struct mrsas_ident * +mrsas_find_ident(device_t dev) { - struct mrsas_ident *pci_device; + struct mrsas_ident *pci_device; - for (pci_device=device_table; pci_device->vendor != 0; pci_device++) - { - if ((pci_device->vendor == pci_get_vendor(dev)) && - (pci_device->device == pci_get_device(dev)) && - ((pci_device->subvendor == pci_get_subvendor(dev)) || - (pci_device->subvendor == 0xffff)) && - ((pci_device->subdevice == pci_get_subdevice(dev)) || - (pci_device->subdevice == 0xffff))) - return (pci_device); - } - return (NULL); + for (pci_device = device_table; pci_device->vendor != 0; pci_device++) { + if ((pci_device->vendor == pci_get_vendor(dev)) && + (pci_device->device == pci_get_device(dev)) && + ((pci_device->subvendor == pci_get_subvendor(dev)) || + (pci_device->subvendor == 0xffff)) && + ((pci_device->subdevice == pci_get_subdevice(dev)) || + (pci_device->subdevice == 0xffff))) + return (pci_device); + } + return (NULL); } -static int mrsas_probe(device_t dev) +static int +mrsas_probe(device_t dev) { - static u_int8_t first_ctrl = 1; - struct mrsas_ident *id; + static u_int8_t first_ctrl = 1; + struct mrsas_ident *id; - if ((id = mrsas_find_ident(dev)) != NULL) { - if (first_ctrl) { - printf("LSI MegaRAID SAS FreeBSD mrsas driver version: %s\n", MRSAS_VERSION); - first_ctrl = 0; - } - device_set_desc(dev, id->desc); - /* between BUS_PROBE_DEFAULT and BUS_PROBE_LOW_PRIORITY */ - return (-30); - } - return (ENXIO); + if ((id = mrsas_find_ident(dev)) != NULL) { + if (first_ctrl) { + printf("LSI MegaRAID SAS FreeBSD mrsas driver version: %s\n", + MRSAS_VERSION); + first_ctrl = 0; + } + device_set_desc(dev, id->desc); + /* between BUS_PROBE_DEFAULT and BUS_PROBE_LOW_PRIORITY */ + return (-30); + } + return (ENXIO); } -/** - * mrsas_setup_sysctl: setup sysctl values for mrsas - * input: Adapter instance soft state +/* + * mrsas_setup_sysctl: setup sysctl values for mrsas + * input: Adapter instance soft state * * Setup sysctl entries for mrsas driver. */ static void mrsas_setup_sysctl(struct mrsas_softc *sc) { - struct sysctl_ctx_list *sysctl_ctx = NULL; - struct sysctl_oid *sysctl_tree = NULL; - char tmpstr[80], tmpstr2[80]; - - /* - * Setup the sysctl variable so the user can change the debug level - * on the fly. - */ - snprintf(tmpstr, sizeof(tmpstr), "MRSAS controller %d", - device_get_unit(sc->mrsas_dev)); - snprintf(tmpstr2, sizeof(tmpstr2), "%d", device_get_unit(sc->mrsas_dev)); - - sysctl_ctx = device_get_sysctl_ctx(sc->mrsas_dev); - if (sysctl_ctx != NULL) - sysctl_tree = device_get_sysctl_tree(sc->mrsas_dev); - - if (sysctl_tree == NULL) { - sysctl_ctx_init(&sc->sysctl_ctx); - sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx, - SYSCTL_STATIC_CHILDREN(_hw_mrsas), OID_AUTO, tmpstr2, - CTLFLAG_RD, 0, tmpstr); - if (sc->sysctl_tree == NULL) - return; - sysctl_ctx = &sc->sysctl_ctx; - sysctl_tree = sc->sysctl_tree; - } - SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "disable_ocr", CTLFLAG_RW, &sc->disableOnlineCtrlReset, 0, - "Disable the use of OCR"); - - SYSCTL_ADD_STRING(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "driver_version", CTLFLAG_RD, MRSAS_VERSION, - strlen(MRSAS_VERSION), "driver version"); - - SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "reset_count", CTLFLAG_RD, - &sc->reset_count, 0, "number of ocr from start of the day"); - - SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "fw_outstanding", CTLFLAG_RD, - &sc->fw_outstanding.val_rdonly, 0, "FW outstanding commands"); + struct sysctl_ctx_list *sysctl_ctx = NULL; + struct sysctl_oid *sysctl_tree = NULL; + char tmpstr[80], tmpstr2[80]; + + /* + * Setup the sysctl variable so the user can change the debug level + * on the fly. + */ + snprintf(tmpstr, sizeof(tmpstr), "MRSAS controller %d", + device_get_unit(sc->mrsas_dev)); + snprintf(tmpstr2, sizeof(tmpstr2), "%d", device_get_unit(sc->mrsas_dev)); + + sysctl_ctx = device_get_sysctl_ctx(sc->mrsas_dev); + if (sysctl_ctx != NULL) + sysctl_tree = device_get_sysctl_tree(sc->mrsas_dev); + + if (sysctl_tree == NULL) { + sysctl_ctx_init(&sc->sysctl_ctx); + sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_hw_mrsas), OID_AUTO, tmpstr2, + CTLFLAG_RD, 0, tmpstr); + if (sc->sysctl_tree == NULL) + return; + sysctl_ctx = &sc->sysctl_ctx; + sysctl_tree = sc->sysctl_tree; + } + SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "disable_ocr", CTLFLAG_RW, &sc->disableOnlineCtrlReset, 0, + "Disable the use of OCR"); + + SYSCTL_ADD_STRING(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "driver_version", CTLFLAG_RD, MRSAS_VERSION, + strlen(MRSAS_VERSION), "driver version"); SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "io_cmds_highwater", CTLFLAG_RD, - &sc->io_cmds_highwater, 0, "Max FW outstanding commands"); + OID_AUTO, "reset_count", CTLFLAG_RD, + &sc->reset_count, 0, "number of ocr from start of the day"); - SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "mrsas_debug", CTLFLAG_RW, &sc->mrsas_debug, 0, - "Driver debug level"); + SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "fw_outstanding", CTLFLAG_RD, + &sc->fw_outstanding.val_rdonly, 0, "FW outstanding commands"); - SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "mrsas_io_timeout", CTLFLAG_RW, &sc->mrsas_io_timeout, - 0, "Driver IO timeout value in mili-second."); + SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "io_cmds_highwater", CTLFLAG_RD, + &sc->io_cmds_highwater, 0, "Max FW outstanding commands"); - SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "mrsas_fw_fault_check_delay", CTLFLAG_RW, - &sc->mrsas_fw_fault_check_delay, - 0, "FW fault check thread delay in seconds. "); + SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "mrsas_debug", CTLFLAG_RW, &sc->mrsas_debug, 0, + "Driver debug level"); + + SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "mrsas_io_timeout", CTLFLAG_RW, &sc->mrsas_io_timeout, + 0, "Driver IO timeout value in mili-second."); + + SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "mrsas_fw_fault_check_delay", CTLFLAG_RW, + &sc->mrsas_fw_fault_check_delay, + 0, "FW fault check thread delay in seconds. "); - SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "reset_in_progress", CTLFLAG_RD, - &sc->reset_in_progress, 0, "ocr in progress status"); + SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "reset_in_progress", CTLFLAG_RD, + &sc->reset_in_progress, 0, "ocr in progress status"); } -/** - * mrsas_get_tunables: get tunable parameters. - * input: Adapter instance soft state +/* + * mrsas_get_tunables: get tunable parameters. + * input: Adapter instance soft state * * Get tunable parameters. This will help to debug driver at boot time. */ static void mrsas_get_tunables(struct mrsas_softc *sc) { - char tmpstr[80]; + char tmpstr[80]; - /* XXX default to some debugging for now */ - sc->mrsas_debug = MRSAS_FAULT; - sc->mrsas_io_timeout = MRSAS_IO_TIMEOUT; - sc->mrsas_fw_fault_check_delay = 1; - sc->reset_count = 0; - sc->reset_in_progress = 0; - - /* - * Grab the global variables. - */ - TUNABLE_INT_FETCH("hw.mrsas.debug_level", &sc->mrsas_debug); - - /* Grab the unit-instance variables */ - snprintf(tmpstr, sizeof(tmpstr), "dev.mrsas.%d.debug_level", - device_get_unit(sc->mrsas_dev)); - TUNABLE_INT_FETCH(tmpstr, &sc->mrsas_debug); -} - -/** - * mrsas_alloc_evt_log_info cmd: Allocates memory to get event log information. - * Used to get sequence number at driver load time. - * input: Adapter soft state + /* XXX default to some debugging for now */ + sc->mrsas_debug = MRSAS_FAULT; + sc->mrsas_io_timeout = MRSAS_IO_TIMEOUT; + sc->mrsas_fw_fault_check_delay = 1; + sc->reset_count = 0; + sc->reset_in_progress = 0; + + /* + * Grab the global variables. + */ + TUNABLE_INT_FETCH("hw.mrsas.debug_level", &sc->mrsas_debug); + + /* Grab the unit-instance variables */ + snprintf(tmpstr, sizeof(tmpstr), "dev.mrsas.%d.debug_level", + device_get_unit(sc->mrsas_dev)); + TUNABLE_INT_FETCH(tmpstr, &sc->mrsas_debug); +} + +/* + * mrsas_alloc_evt_log_info cmd: Allocates memory to get event log information. + * Used to get sequence number at driver load time. + * input: Adapter soft state * * Allocates DMAable memory for the event log info internal command. */ -int mrsas_alloc_evt_log_info_cmd(struct mrsas_softc *sc) +int +mrsas_alloc_evt_log_info_cmd(struct mrsas_softc *sc) { - int el_info_size; + int el_info_size; - /* Allocate get event log info command */ - el_info_size = sizeof(struct mrsas_evt_log_info); - if (bus_dma_tag_create( sc->mrsas_parent_tag, // parent - 1, 0, // algnmnt, boundary - BUS_SPACE_MAXADDR_32BIT,// lowaddr - BUS_SPACE_MAXADDR, // highaddr - NULL, NULL, // filter, filterarg - el_info_size, // maxsize - 1, // msegments - el_info_size, // maxsegsize - BUS_DMA_ALLOCNOW, // flags - NULL, NULL, // lockfunc, lockarg - &sc->el_info_tag)) { - device_printf(sc->mrsas_dev, "Cannot allocate event log info tag\n"); - return (ENOMEM); - } - if (bus_dmamem_alloc(sc->el_info_tag, (void **)&sc->el_info_mem, - BUS_DMA_NOWAIT, &sc->el_info_dmamap)) { - device_printf(sc->mrsas_dev, "Cannot allocate event log info cmd mem\n"); - return (ENOMEM); - } - if (bus_dmamap_load(sc->el_info_tag, sc->el_info_dmamap, - sc->el_info_mem, el_info_size, mrsas_addr_cb, - &sc->el_info_phys_addr, BUS_DMA_NOWAIT)) { - device_printf(sc->mrsas_dev, "Cannot load event log info cmd mem\n"); - return (ENOMEM); - } - - memset(sc->el_info_mem, 0, el_info_size); - return (0); -} - -/** - * mrsas_free_evt_info_cmd: Free memory for Event log info command - * input: Adapter soft state + /* Allocate get event log info command */ + el_info_size = sizeof(struct mrsas_evt_log_info); + if (bus_dma_tag_create(sc->mrsas_parent_tag, + 1, 0, + BUS_SPACE_MAXADDR_32BIT, + BUS_SPACE_MAXADDR, + NULL, NULL, + el_info_size, + 1, + el_info_size, + BUS_DMA_ALLOCNOW, + NULL, NULL, + &sc->el_info_tag)) { + device_printf(sc->mrsas_dev, "Cannot allocate event log info tag\n"); + return (ENOMEM); + } + if (bus_dmamem_alloc(sc->el_info_tag, (void **)&sc->el_info_mem, + BUS_DMA_NOWAIT, &sc->el_info_dmamap)) { + device_printf(sc->mrsas_dev, "Cannot allocate event log info cmd mem\n"); + return (ENOMEM); + } + if (bus_dmamap_load(sc->el_info_tag, sc->el_info_dmamap, + sc->el_info_mem, el_info_size, mrsas_addr_cb, + &sc->el_info_phys_addr, BUS_DMA_NOWAIT)) { + device_printf(sc->mrsas_dev, "Cannot load event log info cmd mem\n"); + return (ENOMEM); + } + memset(sc->el_info_mem, 0, el_info_size); + return (0); +} + +/* + * mrsas_free_evt_info_cmd: Free memory for Event log info command + * input: Adapter soft state * * Deallocates memory for the event log info internal command. */ -void mrsas_free_evt_log_info_cmd(struct mrsas_softc *sc) +void +mrsas_free_evt_log_info_cmd(struct mrsas_softc *sc) { - if (sc->el_info_phys_addr) - bus_dmamap_unload(sc->el_info_tag, sc->el_info_dmamap); - if (sc->el_info_mem != NULL) - bus_dmamem_free(sc->el_info_tag, sc->el_info_mem, sc->el_info_dmamap); - if (sc->el_info_tag != NULL) - bus_dma_tag_destroy(sc->el_info_tag); + if (sc->el_info_phys_addr) + bus_dmamap_unload(sc->el_info_tag, sc->el_info_dmamap); + if (sc->el_info_mem != NULL) + bus_dmamem_free(sc->el_info_tag, sc->el_info_mem, sc->el_info_dmamap); + if (sc->el_info_tag != NULL) + bus_dma_tag_destroy(sc->el_info_tag); } -/** +/* * mrsas_get_seq_num: Get latest event sequence number * @sc: Adapter soft state * @eli: Firmware event log sequence number information. - * Firmware maintains a log of all events in a non-volatile area. - * Driver get the sequence number using DCMD - * "MR_DCMD_CTRL_EVENT_GET_INFO" at driver load time. + * + * Firmware maintains a log of all events in a non-volatile area. + * Driver get the sequence number using DCMD + * "MR_DCMD_CTRL_EVENT_GET_INFO" at driver load time. */ static int mrsas_get_seq_num(struct mrsas_softc *sc, - struct mrsas_evt_log_info *eli) + struct mrsas_evt_log_info *eli) { struct mrsas_mfi_cmd *cmd; struct mrsas_dcmd_frame *dcmd; - cmd = mrsas_get_mfi_cmd(sc); + cmd = mrsas_get_mfi_cmd(sc); if (!cmd) { device_printf(sc->mrsas_dev, "Failed to get a free cmd\n"); return -ENOMEM; } - dcmd = &cmd->frame->dcmd; if (mrsas_alloc_evt_log_info_cmd(sc) != SUCCESS) { @@ -536,7 +556,6 @@ mrsas_get_seq_num(struct mrsas_softc *sc mrsas_release_mfi_cmd(cmd); return -ENOMEM; } - memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); dcmd->cmd = MFI_CMD_DCMD; @@ -553,8 +572,8 @@ mrsas_get_seq_num(struct mrsas_softc *sc mrsas_issue_blocked_cmd(sc, cmd); /* - * Copy the data back into callers buffer - */ + * Copy the data back into callers buffer + */ memcpy(eli, sc->el_info_mem, sizeof(struct mrsas_evt_log_info)); mrsas_free_evt_log_info_cmd(sc); mrsas_release_mfi_cmd(cmd); @@ -563,18 +582,19 @@ mrsas_get_seq_num(struct mrsas_softc *sc } -/** +/* * mrsas_register_aen: Register for asynchronous event notification - * @sc: Adapter soft state - * @seq_num: Starting sequence number - * @class_locale: Class of the event - * This function subscribes for events beyond the @seq_num - * and type @class_locale. - * - * */ + * @sc: Adapter soft state + * @seq_num: Starting sequence number + * @class_locale: Class of the event + * + * This function subscribes for events beyond the @seq_num + * and type @class_locale. + * + */ static int mrsas_register_aen(struct mrsas_softc *sc, u_int32_t seq_num, - u_int32_t class_locale_word) + u_int32_t class_locale_word) { int ret_val; struct mrsas_mfi_cmd *cmd; @@ -582,17 +602,16 @@ mrsas_register_aen(struct mrsas_softc *s union mrsas_evt_class_locale curr_aen; union mrsas_evt_class_locale prev_aen; -/* - * If there an AEN pending already (aen_cmd), check if the - * class_locale of that pending AEN is inclusive of the new - * AEN request we currently have. If it is, then we don't have - * to do anything. In other words, whichever events the current - * AEN request is subscribing to, have already been subscribed - * to. - * If the old_cmd is _not_ inclusive, then we have to abort - * that command, form a class_locale that is superset of both - * old and current and re-issue to the FW - * */ + /* + * If there an AEN pending already (aen_cmd), check if the + * class_locale of that pending AEN is inclusive of the new AEN + * request we currently have. If it is, then we don't have to do + * anything. In other words, whichever events the current AEN request + * is subscribing to, have already been subscribed to. If the old_cmd + * is _not_ inclusive, then we have to abort that command, form a + * class_locale that is superset of both old and current and re-issue + * to the FW + */ curr_aen.word = class_locale_word; @@ -600,21 +619,21 @@ mrsas_register_aen(struct mrsas_softc *s prev_aen.word = sc->aen_cmd->frame->dcmd.mbox.w[1]; -/* - * A class whose enum value is smaller is inclusive of all - * higher values. If a PROGRESS (= -1) was previously - * registered, then a new registration requests for higher - * classes need not be sent to FW. They are automatically - * included. - * Locale numbers don't have such hierarchy. They are bitmap values - */ + /* + * A class whose enum value is smaller is inclusive of all + * higher values. If a PROGRESS (= -1) was previously + * registered, then a new registration requests for higher + * classes need not be sent to FW. They are automatically + * included. Locale numbers don't have such hierarchy. They + * are bitmap values + */ if ((prev_aen.members.class <= curr_aen.members.class) && - !((prev_aen.members.locale & curr_aen.members.locale) ^ - curr_aen.members.locale)) { + !((prev_aen.members.locale & curr_aen.members.locale) ^ + curr_aen.members.locale)) { /* - * Previously issued event registration includes - * current request. Nothing to do. - */ + * Previously issued event registration includes + * current request. Nothing to do. + */ return 0; } else { curr_aen.members.locale |= prev_aen.members.locale; @@ -624,17 +643,16 @@ mrsas_register_aen(struct mrsas_softc *s sc->aen_cmd->abort_aen = 1; ret_val = mrsas_issue_blocked_abort_cmd(sc, - sc->aen_cmd); + sc->aen_cmd); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***