Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 7 May 2014 16:16:50 +0000 (UTC)
From:      Doug Ambrisko <ambrisko@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r265555 - in head: share/man/man4 sys/conf sys/dev/mrsas sys/modules sys/modules/mrsas
Message-ID:  <201405071616.s47GGoLE057251@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ambrisko
Date: Wed May  7 16:16:49 2014
New Revision: 265555
URL: http://svnweb.freebsd.org/changeset/base/265555

Log:
  Add mrsas(4) driver from LSI official support of newer MegaRAID SAS
  cards.  LSI has been maintaining this driver outside of the FreeBSD
  tree.  It overlaps support of ThunderBolt and Invader cards that mfi(4)
  supports.  By default mfi(4) will attach to cards.  If the tunable:
  	hw.mfi.mrsas_enable=1
  is set then mfi(4) will not probe and attach to these newer cards and
  allow mrsas(4) to attach.  So by default this driver will not effect
  a FreeBSD system unless mfi(4) is removed from the kernel or the
  tunable is enabled.
  
  mrsas(4) attaches disks to the CAM layer so it depends on CAM and devices
  show up as /dev/daX.  mfiutil(8) does not work with mrsas.  The FreeBSD
  version of MegaCli and StorCli from LSI do work with mrsas.  It appears
  that StorCli only works with mrsas.  MegaCli appears to work with mfi(4)
  and mrsas(4).
  
  It would be good to add mfiutil(4) support to mrsas, emulations modes,
  kernel logging, device aliases to ease the transition between mfi(4)
  and mrsas(4).
  
  Style issues should be resolved by LSI when they get committers approved.
  The plan is get this driver in FreeBSD 9.3 to improve HW support.
  
  Thanks to LSI for developing, testing and working with FreeBSD to
  make this driver co-exist in FreeBSD.  This improves the overall
  support of MegaRAID SAS.
  
  Submitted by:	Kashyap Desai <Kashyap.Desai@lsi.com>
  Reviewed by:	scottl
  MFC after:	3 days
  Sponsored by:	LSI

Added:
  head/share/man/man4/mrsas.4   (contents, props changed)
  head/sys/dev/mrsas/
  head/sys/dev/mrsas/mrsas.c   (contents, props changed)
  head/sys/dev/mrsas/mrsas.h   (contents, props changed)
  head/sys/dev/mrsas/mrsas_cam.c   (contents, props changed)
  head/sys/dev/mrsas/mrsas_fp.c   (contents, props changed)
  head/sys/dev/mrsas/mrsas_ioctl.c   (contents, props changed)
  head/sys/dev/mrsas/mrsas_ioctl.h   (contents, props changed)
  head/sys/modules/mrsas/
  head/sys/modules/mrsas/Makefile   (contents, props changed)
Modified:
  head/share/man/man4/Makefile
  head/sys/conf/files
  head/sys/modules/Makefile

Modified: head/share/man/man4/Makefile
==============================================================================
--- head/share/man/man4/Makefile	Wed May  7 15:52:41 2014	(r265554)
+++ head/share/man/man4/Makefile	Wed May  7 16:16:49 2014	(r265555)
@@ -265,6 +265,7 @@ MAN=	aac.4 \
 	mpr.4 \
 	mps.4 \
 	mpt.4 \
+	mrsas.4 \
 	msk.4 \
 	mtio.4 \
 	multicast.4 \

Added: head/share/man/man4/mrsas.4
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/man/man4/mrsas.4	Wed May  7 16:16:49 2014	(r265555)
@@ -0,0 +1,374 @@
+.\" Copyright (c) 2014 LSI Corp
+.\" All rights reserved.
+.\" Author: Kashyap Desai
+.\" 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:
+.\" 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 <ORGANIZATION> 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
+.\" official policies,either expressed or implied, of the FreeBSD Project
+.\"
+.\" $FreeBSD$
+.\"
+
+ 
+.Dd Apr 12, 2013
+.Dt MRSAS 4
+.Os
+.Sh NAME
+.Nm mrsas
+.Nd "LSI MegaRAID 6Gb/s and 12Gb/s SAS+SATA Raid controller driver"
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device pci"
+.Cd "device mrsas"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+mrsas_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm 
+driver will detect LSI's next generation (6Gb/s and 12Gb/s) PCI Express
+SAS/SATA RAID controllers.
+See the
+.Nm HARDWARE
+section for the supported devices list.
+A disk (virtual disk/physical disk) attached to the 
+.Nm
+driver will be visible to the user through 
+.Xr camcontrol 8 as
+.Pa /dev/da?
+device nodes.
+A simple management interface is also provided on a per-controller basis via the
+.Pa /dev/mrsas?
+device node.
+.Pp
+The
+.Nm
+name is derived from the phrase "MegaRAID SAS HBA", which is
+substantially different than the old "MegaRAID" Driver
+.Xr mfi 4
+which does not connect targets 
+to the 
+.Xr cam 4
+layer and thus requires a new driver which attaches targets to the 
+.Xr cam 4 
+layer. Older MegaRAID controllers are supported by
+.Xr mfi 4
+and will not work with
+.Nm ,
+but both the
+.Xr mfi 4
+and 
+.Nm
+drivers can detect and manage the LSI MegaRAID SAS 2208/2308/3008/3108 series of
+controllers.
+.Pp
+The
+.Nm device.hints 
+option is provided to tune the
+.Nm
+driver's behavior for LSI MegaRAID SAS 2208/2308/3008/3108 controllers.
+By default, the
+.Xr mfi 4
+driver will detect these controllers. See the 
+.Nm PRIORITY 
+section to know more about driver priority for MR-Fusion devices.
+.Pp
+.Nm
+will provide a priority of (-30) (between BUS_PROBE_DEFAULT and
+BUS_PROBE_LOW_PRIORITY) at probe call for device id's 0x005B, 0x005D, and
+0x005F so that
+.Nm
+does not take control of these devices without user intervention.
+.Sh HARDWARE
+The
+.Nm
+driver supports the following hardware:
+.Pp
+.Bl -bullet -compact
+[ Thunderbolt 6Gbp/s MR controller ]
+.It
+LSI MegaRAID SAS 9265
+.It
+LSI MegaRAID SAS 9266
+.It
+LSI MegaRAID SAS 9267
+.It
+LSI MegaRAID SAS 9270
+.It
+LSI MegaRAID SAS 9271
+.It
+LSI MegaRAID SAS 9272
+.It
+LSI MegaRAID SAS 9285
+.It
+LSI MegaRAID SAS 9286
+.It
+DELL PERC H810
+.It
+DELL PERC H710/P
+.El
+.Pp
+.Bl -bullet -compact
+[ Invader/Fury 12Gpb/s MR controller ]
+.It
+LSI MegaRAID SAS 9380
+.It
+LSI MegaRAID SAS 9361
+.It
+LSI MegaRAID SAS 9341
+.It
+DELL PERC H830
+.It
+DELL PERC H730/P
+.It
+DELL PERC H330
+.El
+.Sh CONFIGURATION
+To disable Online Controller Reset(OCR) for a specific
+.Nm
+driver instance, set the 
+following tunable value in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+dev.mrsas.X.disable_ocr=1 
+.Ed
+.Pp
+where X is the adapter number.
+.Pp
+To change the IO timeout value for a specific 
+.Nm
+driver instance, set the following tunable value in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+dev.mrsas.X.mrsas_io_timeout=NNNNNN
+.Ed
+.Pp
+where NNNNNN is the timeout value in milli-seconds.
+.Pp
+To change the firmware fault check timer value for a specific
+.Nm
+driver instance, set the following tunable value in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+dev.mrsas.X.mrsas_fw_fault_check_delay=NN
+.Ed
+.Pp
+where NN is the fault check delay value in seconds.
+.Pp
+The current number of active I/O commands is shown in the
+dev.mrsas.X.fw_outstanding
+.Xr sysctl 8
+variable.
+.Sh DEBUGGING
+To enable debugging prints from the
+.Nm
+driver, set the
+.Bd -literal -offset indent
+hw.mrsas.X.debug_level
+.Ed
+.Pp
+variable, where X is the adapter number, either in
+.Xr loader.conf 5
+or via
+.Xr sysctl 8 .
+The following bits have the described effects:
+.Bl -tag -offset indent
+.It 0x01
+Enable informational prints.
+.It 0x02
+Enable tracing prints.
+.It 0x04
+Enable prints for driver faults.
+.It 0x08
+Enable prints for OCR and IO timeout.
+.It 0x10
+Enable prints for AEN events.
+.El
+.Sh PRIORITY
+The
+.Nm
+driver will always set a default (-30) priority in the pci subsystem for
+selection of MR-Fusion cards.  (It is between BUS_PROBE_DEFAULT and
+BUS_PROBE_LOW_PRIORITY). MR-Fusion Controllers include all cards with the
+Device IDs -
+0x005B, 
+0x005D,
+0x005F.
+.Pp
+The
+.Xr mfi 4 
+driver will set a priority of either BUS_PROBE_DEFAULT or
+BUS_PROBE_LOW_PRIORITY (depending on the device.hint setting) in the pci
+subsystem for selection of MR-Fusion cards.  With the above design in place, the
+.Xr mfi 4
+driver will attach to a MR-Fusion card given that it has a higher priority than
+.Nm .
+.Pp
+Using /boot/device.hints (as mentioned below), the user can provide a preference
+for the
+.Nm
+driver to detect a MR-Fusion card instead of the
+.Xr mfi 4
+driver. 
+.Bd -ragged -offset indent
+.Cd hw.mfi.mrsas_enable="1"
+.Ed
+.Pp
+At boot time, the
+.Xr mfi 4 
+driver will get priority to detect MR-Fusion controllers by default.  Before
+changing this default driver selection policy, LSI advises users to understand
+how the driver selection policy works.  LSI's policy is to provide priority to
+the
+.Xr mfi 4
+driver to detect MR-Fusion cards, but allow for the ability to choose the
+.Nm
+driver to detect MR-Fusion cards.
+.Pp
+LSI recommends setting hw.mfi.mrsas_enable="0" for customers who are using the
+older 
+.Xr mfi 4 
+driver and do not want to switch to 
+.Nm .
+For those customers who are using a MR-Fusion controller for the first time, LSI
+recommends using the
+.Nm
+driver and setting hw.mfi.mrsas_enable="1".
+.Pp
+Changing the default behavior is well tested under most conditions, but
+unexpected behavior may pop up if more complex and unrealistic operations are
+executed by switching between the
+.Xr mfi 4 and 
+.Nm 
+drivers for MR-Fusion.
+Switching drivers is designed to happen only one time.  Although multiple
+switching is possible, it is not recommended.  The user should decide from
+.Nm Start of Day
+which driver they want to use for the MR-Fusion card.
+.Pp
+The user may see different device names when switching from 
+.Xr mfi 4 
+to 
+.Nm .
+This behavior is
+.Nm Functions As Designed
+and the user needs to change the fstab
+entry manually if they are doing any experiments with 
+.Xr mfi 4 
+and
+.Nm
+interoperability.
+.Sh FILES
+.Bl -tag -width ".Pa /dev/mrsas?" -compact
+.It /dev/da?
+array/logical disk interface
+.It /dev/mrsas?
+management interface
+.El
+.Sh SEE ALSO
+.Xr pci 4 ,
+.Xr mfi 4 ,
+.Xr cam 4 ,
+.Xr device.hints 5 ,
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 10.0 .
+.Bd -ragged
+.Cd "mfi Driver:"
+.Xr mfi 4
+is the old FreeBSD driver which started with support for Gen-1 Controllers and
+was extended to support up to MR-Fusion (Device ID = 0x005B, 0x005D, 0x005F).
+.Ed
+.Bd -ragged
+.Cd "mrsas Driver:"
+.Nm
+is the new driver reworked by LSI which supports Thunderbolt and onward
+products. The SAS+SATA RAID controller with device id 0x005b is referred to as
+the Thunderbolt controller throughout in this man page.
+.Ed 
+.Bd -ragged
+.Nm cam aware HBA drivers:
+FreeBSD has a
+.Xr cam 4
+layer which attaches storage devices and provides a common access mechanism to
+storage controllers and attached devices.  The
+.Nm 
+driver is
+.Xr cam 4 aware and devices associated with 
+.Nm 
+can be seen using 
+.Xr camcontrol 8 .
+The
+.Xr mfi 4
+driver does not understand the
+.Xr cam 4
+layer and it directly associates storage disks to the block layer.
+.Pp
+.Nm Thunderbolt Controller: 
+This is the 6Gb/s MegaRAID HBA card which has device id 0x005B.
+.Pp
+.Nm Invader Controller: 
+This is 12Gb/s MegaRAID HBA card which has device id 0x005D.
+.Pp
+.Nm Fury Controller: 
+This is the 12Gb/s MegaRAID HBA card which has device id 0x005F.
+.Ed
+.Sh AUTHORS
+The
+.Nm
+driver and this manual page were written by
+.An Kashyap Desai Aq Kashyap.Desai@lsi.com .
+.Sh TODO
+The driver does not support big-endian architectures at this time.
+.Pp
+The driver does not support alias for device name (it is required when the user
+switches between two drivers and does not want to edit /etc/fstab manually).
+.Pp
+The
+.Nm 
+driver exposes devices as /dev/da?, whereas 
+.Xr mfi 4 
+exposes deivces as /dev/mfid?
+.Pp
+.Nm
+does not support the Linux Emulator interface.
+.Pp
+.Nm
+will not work with
+.Xr mfiutil 8

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Wed May  7 15:52:41 2014	(r265554)
+++ head/sys/conf/files	Wed May  7 16:16:49 2014	(r265555)
@@ -1832,6 +1832,10 @@ dev/mpt/mpt_debug.c		optional mpt
 dev/mpt/mpt_pci.c		optional mpt pci
 dev/mpt/mpt_raid.c		optional mpt
 dev/mpt/mpt_user.c		optional mpt
+dev/mrsas/mrsas.c		optional mrsas
+dev/mrsas/mrsas_cam.c		optional mrsas
+dev/mrsas/mrsas_ioctl.c		optional mrsas
+dev/mrsas/mrsas_fp.c		optional mrsas
 dev/msk/if_msk.c		optional msk
 dev/mvs/mvs.c			optional mvs
 dev/mvs/mvs_if.m		optional mvs

Added: head/sys/dev/mrsas/mrsas.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/mrsas/mrsas.c	Wed May  7 16:16:49 2014	(r265555)
@@ -0,0 +1,3672 @@
+/*
+ * 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:
+ *
+ * 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 <ORGANIZATION> 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
+ * official policies,either expressed or implied, of the FreeBSD Project.
+ *
+ * Send feedback to: <megaraidfbsd@lsi.com>
+ * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035
+ *    ATTN: MegaRaid FreeBSD
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/mrsas/mrsas.h>
+#include <dev/mrsas/mrsas_ioctl.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/kthread.h>
+#include <sys/taskqueue.h>
+
+
+/* 
+ * 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 struct mrsas_ident *mrsas_find_ident(device_t);
+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);
+static void mrsas_ocr_thread(void *arg);
+static int mrsas_get_map_info(struct mrsas_softc *sc);
+static int mrsas_get_ld_map_info(struct mrsas_softc *sc);
+static int mrsas_sync_map_info(struct mrsas_softc *sc);
+static int mrsas_get_pd_list(struct mrsas_softc *sc);
+static int mrsas_get_ld_list(struct mrsas_softc *sc);
+static int mrsas_setup_irq(struct mrsas_softc *sc);
+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_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);
+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);
+
+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 struct mrsas_mpt_cmd *mrsas_get_mpt_cmd(struct mrsas_softc *sc);
+extern int mrsas_passthru(struct mrsas_softc *sc, void *arg);
+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 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 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");
+
+
+/**
+ * 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;
+
+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}
+};
+
+/**
+ * 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",
+};
+
+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.
+ */
+int
+mrsas_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
+{
+    struct mrsas_softc *sc;
+
+    sc = dev->si_drv1;
+    return (0);
+}
+
+int
+mrsas_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
+{
+    struct mrsas_softc *sc;
+
+    sc = dev->si_drv1;
+    return (0);
+}
+
+int
+mrsas_read(struct cdev *dev, struct uio *uio, int ioflag)
+{
+    struct mrsas_softc *sc;
+
+    sc = dev->si_drv1;
+    return (0);
+}
+int
+mrsas_write(struct cdev *dev, struct uio *uio, int ioflag)
+{
+    struct mrsas_softc *sc;
+
+    sc = dev->si_drv1;
+    return (0);
+}
+
+/** 
+ * Register Read/Write Functions 
+ *
+ */
+void
+mrsas_write_reg(struct mrsas_softc *sc, int offset,
+                  u_int32_t value)
+{
+    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);
+}
+
+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;
+
+    return((u_int32_t)bus_space_read_4(bus_tag, bus_handle, offset));
+}
+
+
+/** 
+ * Interrupt Disable/Enable/Clear Functions 
+ *
+ */
+void mrsas_disable_intr(struct mrsas_softc *sc)
+{
+    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));
+}
+
+void mrsas_enable_intr(struct mrsas_softc *sc)
+{
+    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_mask), ~mask);
+    status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask));
+}
+
+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));
+
+    /* 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);
+}
+
+/** 
+ * PCI Support Functions 
+ *
+ */
+static struct mrsas_ident * mrsas_find_ident(device_t dev)
+{
+    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);
+}
+
+static int mrsas_probe(device_t dev)
+{
+    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);
+}
+
+/**
+ * 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, 0, "FW outstanding commands");
+
+	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_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. <default is 1 sec>");
+
+    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
+ *
+ * Get tunable parameters. This will help to debug driver at boot time.
+ */
+static void
+mrsas_get_tunables(struct mrsas_softc *sc)
+{
+    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
+ *
+ * Allocates DMAable memory for the event log info internal command.
+ */
+int mrsas_alloc_evt_log_info_cmd(struct mrsas_softc *sc)
+{
+    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
+ *
+ * Deallocates memory for the event log info internal command.
+ */
+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);
+}
+
+/**
+ *  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.
+ */
+
+static int
+mrsas_get_seq_num(struct mrsas_softc *sc,
+		    struct mrsas_evt_log_info *eli)
+{
+	struct mrsas_mfi_cmd *cmd;
+	struct mrsas_dcmd_frame *dcmd;
+
+	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) {
+		device_printf(sc->mrsas_dev, "Cannot allocate evt log info cmd\n");
+		mrsas_release_mfi_cmd(cmd);
+		return -ENOMEM;
+	}
+	
+	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+	dcmd->cmd = MFI_CMD_DCMD;
+	dcmd->cmd_status = 0x0;
+	dcmd->sge_count = 1;
+	dcmd->flags = MFI_FRAME_DIR_READ;
+	dcmd->timeout = 0;
+	dcmd->pad_0 = 0;
+	dcmd->data_xfer_len = sizeof(struct mrsas_evt_log_info);
+	dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO;
+	dcmd->sgl.sge32[0].phys_addr = sc->el_info_phys_addr;
+	dcmd->sgl.sge32[0].length = sizeof(struct mrsas_evt_log_info);
+
+	mrsas_issue_blocked_cmd(sc, cmd);
+
+	/*
+ 	 * 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);
+
+	return 0;
+}
+
+
+/**
+ *  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.
+ * 
+ * */
+static int
+mrsas_register_aen(struct mrsas_softc *sc, u_int32_t seq_num,
+		     u_int32_t class_locale_word)
+{
+	int ret_val;
+	struct mrsas_mfi_cmd *cmd;
+	struct mrsas_dcmd_frame *dcmd;
+	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
+ * */
+
+	curr_aen.word = class_locale_word;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405071616.s47GGoLE057251>