svn commit: r227068 - in projects/head_mfi/sys: conf dev/mfi
modules/mfi
Doug Ambrisko
ambrisko at FreeBSD.org
Fri Nov 4 02:34:53 UTC 2011
Author: ambrisko
Date: Fri Nov 4 02:34:52 2011
New Revision: 227068
URL: http://svn.freebsd.org/changeset/base/227068
Log:
First cut at updating mfi(4) to support newer LSI MegaRAID SAS cards.
Specifically, add support for "Drake Skinny" and "ThunderBolt" LSI
cards.
Initial code was supplied by LSI under BSD license. Several improvements
were done by myself. Such things like making it work in a static kernel,
be able to boot of the RAID, performance improvements. I removed some
fairly complicated code that seemed to directly access the disks under
the firmware. It doesn't seem to be needed and significantly slowed
down the performance of the driver and caused tons of sense errors to
be reported.
This code is being checked in this area so others can help me get it into
shape to commit into the FreeBSD tree. Assistance has been volunteered
by iXsystems.
We might want to re-work the JBOD attachment that creates /dev/mfisyspd?
node for each disk.
Performance is faster then prior cards. It works okay with WITNESS
and INVARIANTS on amd64 and i386. I recall seeing a use after
free time bug with FreeBSD 8 and a Drake Skinny card with WITNESS
and INVARIANTS on.
First task is get all of the new structures to be named in FreeBSD
style format.
Next is probably to deal with the 64bit addressing changes that are
mostly around the #ifdef __amd64__ checks.
Thanks to LSI for providing the initial code.
Obtained from: LSI
Added:
projects/head_mfi/sys/dev/mfi/mfi_syspd.c
projects/head_mfi/sys/dev/mfi/mfi_tbolt.c
Modified:
projects/head_mfi/sys/conf/files
projects/head_mfi/sys/dev/mfi/mfi.c
projects/head_mfi/sys/dev/mfi/mfi_cam.c
projects/head_mfi/sys/dev/mfi/mfi_disk.c
projects/head_mfi/sys/dev/mfi/mfi_ioctl.h
projects/head_mfi/sys/dev/mfi/mfi_linux.c
projects/head_mfi/sys/dev/mfi/mfi_pci.c
projects/head_mfi/sys/dev/mfi/mfireg.h
projects/head_mfi/sys/dev/mfi/mfivar.h
projects/head_mfi/sys/modules/mfi/Makefile
Modified: projects/head_mfi/sys/conf/files
==============================================================================
--- projects/head_mfi/sys/conf/files Fri Nov 4 01:58:55 2011 (r227067)
+++ projects/head_mfi/sys/conf/files Fri Nov 4 02:34:52 2011 (r227068)
@@ -1410,6 +1410,8 @@ dev/mfi/mfi.c optional mfi
dev/mfi/mfi_debug.c optional mfi
dev/mfi/mfi_pci.c optional mfi pci
dev/mfi/mfi_disk.c optional mfi
+dev/mfi/mfi_syspd.c optional mfi
+dev/mfi/mfi_tbolt.c optional mfi
dev/mfi/mfi_linux.c optional mfi compat_linux
dev/mfi/mfi_cam.c optional mfip scbus
dev/mii/acphy.c optional miibus | acphy
Modified: projects/head_mfi/sys/dev/mfi/mfi.c
==============================================================================
--- projects/head_mfi/sys/dev/mfi/mfi.c Fri Nov 4 01:58:55 2011 (r227067)
+++ projects/head_mfi/sys/dev/mfi/mfi.c Fri Nov 4 02:34:52 2011 (r227068)
@@ -79,10 +79,11 @@ __FBSDID("$FreeBSD$");
#include <dev/mfi/mfireg.h>
#include <dev/mfi/mfi_ioctl.h>
#include <dev/mfi/mfivar.h>
+#include <sys/interrupt.h>
+#include <sys/priority.h>
static int mfi_alloc_commands(struct mfi_softc *);
static int mfi_comms_init(struct mfi_softc *);
-static int mfi_wait_command(struct mfi_softc *, struct mfi_command *);
static int mfi_get_controller_info(struct mfi_softc *);
static int mfi_get_log_state(struct mfi_softc *,
struct mfi_evt_log_state **);
@@ -93,16 +94,18 @@ static void mfi_data_cb(void *, bus_dma_
static void mfi_startup(void *arg);
static void mfi_intr(void *arg);
static void mfi_ldprobe(struct mfi_softc *sc);
+static void mfi_syspdprobe(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 *);
-static int mfi_aen_setup(struct mfi_softc *, uint32_t);
static int mfi_add_ld(struct mfi_softc *sc, int);
static void mfi_add_ld_complete(struct mfi_command *);
+static int mfi_add_sys_pd(struct mfi_softc *sc, int);
+static void mfi_add_sys_pd_complete(struct mfi_command *);
static struct mfi_command * mfi_bio_command(struct mfi_softc *);
static void mfi_bio_complete(struct mfi_command *);
-static int mfi_mapcmd(struct mfi_softc *, struct mfi_command *);
+static struct mfi_command *mfi_build_ldio(struct mfi_softc *,struct bio*);
+static struct mfi_command *mfi_build_syspdio(struct mfi_softc *,struct bio*);
static int mfi_send_frame(struct mfi_softc *, struct mfi_command *);
-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, struct thread *);
static void mfi_timeout(void *);
@@ -110,12 +113,17 @@ static int mfi_user_command(struct mfi_s
struct mfi_ioc_passthru *);
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 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);
+static void mfi_issue_cmd_xscale(struct mfi_softc *sc, bus_addr_t bus_add,uint32_t frame_cnt);
+static void mfi_issue_cmd_ppc(struct mfi_softc *sc, bus_addr_t bus_add,uint32_t frame_cnt);
+static int mfi_config_lock(struct mfi_softc *sc, uint32_t opcode);
+static void mfi_config_unlock(struct mfi_softc *sc, int locked);
+static int mfi_check_command_pre(struct mfi_softc *sc, struct mfi_command *cm);
+static void mfi_check_command_post(struct mfi_softc *sc, struct mfi_command *cm);
+static int mfi_check_for_sscd(struct mfi_softc *sc, struct mfi_command *cm);
SYSCTL_NODE(_hw, OID_AUTO, mfi, CTLFLAG_RD, 0, "MFI driver parameters");
static int mfi_event_locale = MFI_EVT_LOCALE_ALL;
@@ -152,6 +160,7 @@ static struct cdevsw mfi_cdevsw = {
MALLOC_DEFINE(M_MFIBUF, "mfibuf", "Buffers for the MFI driver");
#define MFI_INQ_LENGTH SHORT_INQUIRY_LENGTH
+struct mfi_skinny_dma_info mfi_skinny;
static void
mfi_enable_intr_xscale(struct mfi_softc *sc)
@@ -162,12 +171,17 @@ mfi_enable_intr_xscale(struct mfi_softc
static void
mfi_enable_intr_ppc(struct mfi_softc *sc)
{
- MFI_WRITE4(sc, MFI_ODCR0, 0xFFFFFFFF);
if (sc->mfi_flags & MFI_FLAGS_1078) {
+ MFI_WRITE4(sc, MFI_ODCR0, 0xFFFFFFFF);
MFI_WRITE4(sc, MFI_OMSK, ~MFI_1078_EIM);
- } else if (sc->mfi_flags & MFI_FLAGS_GEN2) {
+ }
+ else if (sc->mfi_flags & MFI_FLAGS_GEN2) {
+ MFI_WRITE4(sc, MFI_ODCR0, 0xFFFFFFFF);
MFI_WRITE4(sc, MFI_OMSK, ~MFI_GEN2_EIM);
}
+ else if (sc->mfi_flags & MFI_FLAGS_SKINNY) {
+ MFI_WRITE4(sc, MFI_OMSK, ~0x00000001);
+ }
}
static int32_t
@@ -205,35 +219,51 @@ mfi_check_clear_intr_ppc(struct mfi_soft
if (!(status & MFI_1078_RM)) {
return 1;
}
- } else if (sc->mfi_flags & MFI_FLAGS_GEN2) {
+ }
+ else if (sc->mfi_flags & MFI_FLAGS_GEN2) {
if (!(status & MFI_GEN2_RM)) {
return 1;
}
}
-
- MFI_WRITE4(sc, MFI_ODCR0, status);
+ else if (sc->mfi_flags & MFI_FLAGS_SKINNY) {
+ if (!(status & MFI_SKINNY_RM)) {
+ return 1;
+ }
+ }
+ if (sc->mfi_flags & MFI_FLAGS_SKINNY)
+ MFI_WRITE4(sc, MFI_OSTS, status);
+ else
+ 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_issue_cmd_xscale(struct mfi_softc *sc, bus_addr_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_issue_cmd_ppc(struct mfi_softc *sc, bus_addr_t bus_add, uint32_t frame_cnt)
{
- MFI_WRITE4(sc, MFI_IQP, (bus_add |frame_cnt <<1)|1 );
+ if (sc->mfi_flags & MFI_FLAGS_SKINNY) {
+ MFI_WRITE4(sc, MFI_IQPL, (bus_add | frame_cnt <<1)|1 );
+ MFI_WRITE4(sc, MFI_IQPH, 0x00000000);
+ } else {
+ MFI_WRITE4(sc, MFI_IQP, (bus_add | frame_cnt <<1)|1 );
+ }
}
-static int
+int
mfi_transition_firmware(struct mfi_softc *sc)
{
uint32_t fw_state, cur_state;
int max_wait, i;
+ uint32_t cur_abs_reg_val = 0;
+ uint32_t prev_abs_reg_val = 0;
- fw_state = sc->mfi_read_fw_status(sc)& MFI_FWSTATE_MASK;
+ cur_abs_reg_val = sc->mfi_read_fw_status(sc);
+ fw_state = cur_abs_reg_val & MFI_FWSTATE_MASK;
while (fw_state != MFI_FWSTATE_READY) {
if (bootverbose)
device_printf(sc->mfi_dev, "Waiting for firmware to "
@@ -244,25 +274,41 @@ mfi_transition_firmware(struct mfi_softc
device_printf(sc->mfi_dev, "Firmware fault\n");
return (ENXIO);
case MFI_FWSTATE_WAIT_HANDSHAKE:
- MFI_WRITE4(sc, MFI_IDB, MFI_FWINIT_CLEAR_HANDSHAKE);
- max_wait = 2;
+ if (sc->mfi_flags & MFI_FLAGS_SKINNY || sc->mfi_flags & MFI_FLAGS_TBOLT)
+ MFI_WRITE4(sc, MFI_SKINNY_IDB, MFI_FWINIT_CLEAR_HANDSHAKE);
+ else
+ MFI_WRITE4(sc, MFI_IDB, MFI_FWINIT_CLEAR_HANDSHAKE);
+ max_wait = MFI_RESET_WAIT_TIME;
break;
case MFI_FWSTATE_OPERATIONAL:
- MFI_WRITE4(sc, MFI_IDB, MFI_FWINIT_READY);
- max_wait = 10;
+ if (sc->mfi_flags & MFI_FLAGS_SKINNY || sc->mfi_flags & MFI_FLAGS_TBOLT)
+ //MFI_WRITE4(sc, MFI_SKINNY_IDB, MFI_FWINIT_READY);
+ MFI_WRITE4(sc, MFI_SKINNY_IDB, 7);
+ else
+ MFI_WRITE4(sc, MFI_IDB, MFI_FWINIT_READY);
+ max_wait = MFI_RESET_WAIT_TIME;
break;
case MFI_FWSTATE_UNDEFINED:
case MFI_FWSTATE_BB_INIT:
- max_wait = 2;
+ max_wait = MFI_RESET_WAIT_TIME;
+ break;
+ case MFI_FWSTATE_FW_INIT_2:
+ max_wait = MFI_RESET_WAIT_TIME;
break;
case MFI_FWSTATE_FW_INIT:
- case MFI_FWSTATE_DEVICE_SCAN:
case MFI_FWSTATE_FLUSH_CACHE:
- max_wait = 20;
+ max_wait = MFI_RESET_WAIT_TIME;
+ break;
+ case MFI_FWSTATE_DEVICE_SCAN:
+ max_wait = MFI_RESET_WAIT_TIME; /* wait for 180 seconds */
+ prev_abs_reg_val = cur_abs_reg_val;
break;
case MFI_FWSTATE_BOOT_MESSAGE_PENDING:
- MFI_WRITE4(sc, MFI_IDB, MFI_FWINIT_HOTPLUG);
- max_wait = 10;
+ if (sc->mfi_flags & MFI_FLAGS_SKINNY || sc->mfi_flags & MFI_FLAGS_TBOLT)
+ MFI_WRITE4(sc, MFI_SKINNY_IDB, MFI_FWINIT_HOTPLUG);
+ else
+ MFI_WRITE4(sc, MFI_IDB, MFI_FWINIT_HOTPLUG);
+ max_wait = MFI_RESET_WAIT_TIME;
break;
default:
device_printf(sc->mfi_dev,"Unknown firmware state %#x\n",
@@ -270,12 +316,20 @@ mfi_transition_firmware(struct mfi_softc
return (ENXIO);
}
for (i = 0; i < (max_wait * 10); i++) {
- fw_state = sc->mfi_read_fw_status(sc) & MFI_FWSTATE_MASK;
+
+ cur_abs_reg_val = sc->mfi_read_fw_status(sc);
+ fw_state = cur_abs_reg_val & MFI_FWSTATE_MASK;
if (fw_state == cur_state)
DELAY(100000);
else
break;
}
+ if (fw_state == MFI_FWSTATE_DEVICE_SCAN) {
+ /* Check the device scanning progress */
+ if (prev_abs_reg_val != cur_abs_reg_val) {
+ continue;
+ }
+ }
if (fw_state == cur_state) {
device_printf(sc->mfi_dev, "Firmware stuck in state "
"%#x\n", fw_state);
@@ -286,26 +340,31 @@ mfi_transition_firmware(struct mfi_softc
}
static void
-mfi_addr32_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+mfi_addr_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
{
- uint32_t *addr;
+ bus_addr_t *addr;
addr = arg;
*addr = segs[0].ds_addr;
}
+
int
mfi_attach(struct mfi_softc *sc)
{
uint32_t status;
int error, commsz, framessz, sensesz;
int frames, unit, max_fw_sge;
+ uint32_t tb_mem_size = 0;
+ if(sc == NULL)
+ return EINVAL;
- device_printf(sc->mfi_dev, "Megaraid SAS driver Ver 3.00 \n");
+ device_printf(sc->mfi_dev, "Megaraid SAS driver Ver %s \n",MEGASAS_VERSION);
mtx_init(&sc->mfi_io_lock, "MFI I/O lock", NULL, MTX_DEF);
sx_init(&sc->mfi_config_lock, "MFI config");
TAILQ_INIT(&sc->mfi_ld_tqh);
+ TAILQ_INIT(&sc->mfi_syspd_tqh);
TAILQ_INIT(&sc->mfi_aen_pids);
TAILQ_INIT(&sc->mfi_cam_ccbq);
@@ -314,15 +373,32 @@ mfi_attach(struct mfi_softc *sc)
mfi_initq_busy(sc);
mfi_initq_bio(sc);
+ //atomic_set(&sc->fw_reset_no_pci_access, 0);
+ sc->adpreset = 0;
+ sc->last_seq_num = 0;
+ sc->disableOnlineCtrlReset = 1;
+ sc->issuepend_done = 1;
+ sc->hw_crit_error = 0;
+
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 if(sc->mfi_flags & MFI_FLAGS_TBOLT) {
+ sc->mfi_enable_intr = mfi_tbolt_enable_intr_ppc;
+ sc->mfi_disable_intr = mfi_tbolt_disable_intr_ppc;
+ sc->mfi_read_fw_status = mfi_tbolt_read_fw_status_ppc;
+ sc->mfi_check_clear_intr = mfi_tbolt_check_clear_intr_ppc;
+ sc->mfi_issue_cmd = mfi_tbolt_issue_cmd_ppc;
+ sc->mfi_adp_reset = mfi_tbolt_adp_reset;
+ sc->mfi_tbolt = 1;
+ TAILQ_INIT(&sc->mfi_cmd_tbolt_tqh);
+ }
else {
sc->mfi_enable_intr = mfi_enable_intr_ppc;
- sc->mfi_read_fw_status = mfi_read_fw_status_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;
}
@@ -334,6 +410,32 @@ mfi_attach(struct mfi_softc *sc)
"error %d\n", error);
return (ENXIO);
}
+ //
+
+ //Start: LSIP200113393
+ if (bus_dma_tag_create( sc->mfi_parent_dmat, /* parent */
+ 1, 0, /* algnmnt, boundary */
+ BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MEGASAS_MAX_NAME*sizeof(bus_addr_t), /* maxsize */
+ 1, /* msegments */
+ MEGASAS_MAX_NAME*sizeof(bus_addr_t), /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->verbuf_h_dmat)) {
+ device_printf(sc->mfi_dev, "Cannot allocate verbuf_h_dmat DMA tag\n");
+ return (ENOMEM);
+ }
+ if (bus_dmamem_alloc(sc->verbuf_h_dmat, (void **)&sc->verbuf,
+ BUS_DMA_NOWAIT, &sc->verbuf_h_dmamap)) {
+ device_printf(sc->mfi_dev, "Cannot allocate verbuf_h_dmamap memory\n");
+ return (ENOMEM);
+ }
+ bzero(sc->verbuf, MEGASAS_MAX_NAME*sizeof(bus_addr_t));
+ bus_dmamap_load(sc->verbuf_h_dmat, sc->verbuf_h_dmamap,
+ sc->verbuf, MEGASAS_MAX_NAME*sizeof(bus_addr_t), mfi_addr_cb, &sc->verbuf_h_busaddr, 0);
+ //End: LSIP200113393
/*
* Get information needed for sizing the contiguous memory for the
@@ -347,6 +449,94 @@ mfi_attach(struct mfi_softc *sc)
max_fw_sge = (status & MFI_FWSTATE_MAXSGL_MASK) >> 16;
sc->mfi_max_sge = min(max_fw_sge, ((MFI_MAXPHYS / PAGE_SIZE) + 1));
+ /* ThunderBolt Support get the contiguous memory */
+
+ if(sc->mfi_flags & MFI_FLAGS_TBOLT) {
+ mfi_tbolt_init_globals(sc);
+ device_printf(sc->mfi_dev,"MaxCmd = %x MaxSgl = %x state = %x \n",
+ sc->mfi_max_fw_cmds, sc->mfi_max_sge, status);
+ tb_mem_size = mfi_tbolt_get_memory_requirement(sc);
+
+ if (bus_dma_tag_create( sc->mfi_parent_dmat, /* parent */
+ 1, 0, /* algnmnt, boundary */
+ BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ tb_mem_size, /* maxsize */
+ 1, /* msegments */
+ tb_mem_size, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->mfi_tb_dmat)) {
+ device_printf(sc->mfi_dev, "Cannot allocate comms DMA tag\n");
+ return (ENOMEM);
+ }
+ if (bus_dmamem_alloc(sc->mfi_tb_dmat, (void **)&sc->request_message_pool,
+ BUS_DMA_NOWAIT, &sc->mfi_tb_dmamap)) {
+ device_printf(sc->mfi_dev, "Cannot allocate comms memory\n");
+ return (ENOMEM);
+ }
+ bzero(sc->request_message_pool, tb_mem_size);
+ bus_dmamap_load(sc->mfi_tb_dmat, sc->mfi_tb_dmamap,
+ sc->request_message_pool, tb_mem_size, mfi_addr_cb, &sc->mfi_tb_busaddr, 0);
+
+ /* For ThunderBolt memory init */
+ if (bus_dma_tag_create( sc->mfi_parent_dmat, /* parent */
+ 0x100, 0, /* algnmnt, boundary */
+ BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MFI_FRAME_SIZE, /* maxsize */
+ 1, /* msegments */
+ MFI_FRAME_SIZE, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->mfi_tb_init_dmat)) {
+ device_printf(sc->mfi_dev, "Cannot allocate init DMA tag\n");
+ return (ENOMEM);
+ }
+ if (bus_dmamem_alloc(sc->mfi_tb_init_dmat, (void **)&sc->mfi_tb_init,
+ BUS_DMA_NOWAIT, &sc->mfi_tb_init_dmamap)) {
+ device_printf(sc->mfi_dev, "Cannot allocate init memory\n");
+ return (ENOMEM);
+ }
+ bzero(sc->mfi_tb_init, MFI_FRAME_SIZE);
+ bus_dmamap_load(sc->mfi_tb_init_dmat, sc->mfi_tb_init_dmamap,
+ sc->mfi_tb_init, MFI_FRAME_SIZE, mfi_addr_cb, &sc->mfi_tb_init_busaddr, 0);
+ if(mfi_tbolt_init_desc_pool(sc, sc->request_message_pool, tb_mem_size)) {
+ device_printf(sc->mfi_dev,"Thunderbolt pool preparation error\n");
+ return 0;
+ }
+
+ /*
+ Allocate DMA memory mapping for MPI2 IOC Init descriptor,
+ we are taking it diffrent from what we have allocated for Request
+ and reply descriptors to avoid confusion later
+ */
+ tb_mem_size = sizeof(struct MPI2_IOC_INIT_REQUEST);
+ if (bus_dma_tag_create( sc->mfi_parent_dmat, /* parent */
+ 1, 0, /* algnmnt, boundary */
+ BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ tb_mem_size, /* maxsize */
+ 1, /* msegments */
+ tb_mem_size, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->mfi_tb_ioc_init_dmat)) {
+ device_printf(sc->mfi_dev, "Cannot allocate comms DMA tag\n");
+ return (ENOMEM);
+ }
+ if (bus_dmamem_alloc(sc->mfi_tb_ioc_init_dmat, (void **)&sc->mfi_tb_ioc_init_desc,
+ BUS_DMA_NOWAIT, &sc->mfi_tb_ioc_init_dmamap)) {
+ device_printf(sc->mfi_dev, "Cannot allocate comms memory\n");
+ return (ENOMEM);
+ }
+ bzero(sc->mfi_tb_ioc_init_desc, tb_mem_size);
+ bus_dmamap_load(sc->mfi_tb_ioc_init_dmat, sc->mfi_tb_ioc_init_dmamap,
+ sc->mfi_tb_ioc_init_desc, tb_mem_size, mfi_addr_cb, &sc->mfi_tb_ioc_init_busaddr, 0);
+ }
/*
* Create the dma tag for data buffers. Used both for block I/O
* and for various internal data queries.
@@ -396,8 +586,7 @@ mfi_attach(struct mfi_softc *sc)
}
bzero(sc->mfi_comms, commsz);
bus_dmamap_load(sc->mfi_comms_dmat, sc->mfi_comms_dmamap,
- sc->mfi_comms, commsz, mfi_addr32_cb, &sc->mfi_comms_busaddr, 0);
-
+ sc->mfi_comms, commsz, mfi_addr_cb, &sc->mfi_comms_busaddr, 0);
/*
* Allocate DMA memory for the command frames. Keep them in the
* lower 4GB for efficiency. Calculate the size of the commands at
@@ -414,6 +603,8 @@ mfi_attach(struct mfi_softc *sc)
} else {
sc->mfi_sge_size = sizeof(struct mfi_sg32);
}
+ if (sc->mfi_flags & MFI_FLAGS_SKINNY)
+ sc->mfi_sge_size = sizeof(struct mfi_sg_skinny);
frames = (sc->mfi_sge_size * sc->mfi_max_sge - 1) / MFI_FRAME_SIZE + 2;
sc->mfi_cmd_size = frames * MFI_FRAME_SIZE;
framessz = sc->mfi_cmd_size * sc->mfi_max_fw_cmds;
@@ -438,8 +629,7 @@ mfi_attach(struct mfi_softc *sc)
}
bzero(sc->mfi_frames, framessz);
bus_dmamap_load(sc->mfi_frames_dmat, sc->mfi_frames_dmamap,
- sc->mfi_frames, framessz, mfi_addr32_cb, &sc->mfi_frames_busaddr,0);
-
+ sc->mfi_frames, framessz, mfi_addr_cb, &sc->mfi_frames_busaddr,0);
/*
* Allocate DMA memory for the frame sense data. Keep them in the
* lower 4GB for efficiency
@@ -465,40 +655,63 @@ mfi_attach(struct mfi_softc *sc)
return (ENOMEM);
}
bus_dmamap_load(sc->mfi_sense_dmat, sc->mfi_sense_dmamap,
- sc->mfi_sense, sensesz, mfi_addr32_cb, &sc->mfi_sense_busaddr, 0);
-
+ sc->mfi_sense, sensesz, mfi_addr_cb, &sc->mfi_sense_busaddr, 0);
if ((error = mfi_alloc_commands(sc)) != 0)
return (error);
- if ((error = mfi_comms_init(sc)) != 0)
- return (error);
+ /* Before moving the FW to operational state, check whether
+ * hostmemory is required by the FW or not
+ */
- if ((error = mfi_get_controller_info(sc)) != 0)
- return (error);
+ /* ThunderBolt MFI_IOC2 INIT */
+ if(sc->mfi_flags & MFI_FLAGS_TBOLT)
+ {
+ sc->mfi_disable_intr(sc);
+ if((error = mfi_tbolt_init_MFI_queue(sc)) != 0)
+ {
+ device_printf(sc->mfi_dev,"TB Init has failed with error %d\n",error);
+ return error;
+ }
- mtx_lock(&sc->mfi_io_lock);
- if ((error = mfi_aen_setup(sc, 0), 0) != 0) {
- mtx_unlock(&sc->mfi_io_lock);
- return (error);
- }
- mtx_unlock(&sc->mfi_io_lock);
+ if((error = mfi_tbolt_alloc_cmd(sc)) != 0)
+ return error;
+ sc->mfi_irq_rid = 0;
+ if ((sc->mfi_irq = bus_alloc_resource_any(sc->mfi_dev, SYS_RES_IRQ,
+ &sc->mfi_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+ device_printf(sc->mfi_dev, "Cannot allocate interrupt\n");
+ return (EINVAL);
+ }
+ if (bus_setup_intr(sc->mfi_dev, sc->mfi_irq, INTR_MPSAFE|INTR_TYPE_BIO,
+ NULL, mfi_intr_tbolt, sc, &sc->mfi_intr)) {
+ device_printf(sc->mfi_dev, "Cannot set up interrupt\n");
+ return (EINVAL);
+ }
+ sc->mfi_enable_intr(sc);
+ sc->map_id = 0;
+ }
+ else
+ {
+
+ if ((error = mfi_comms_init(sc)) != 0)
+ return (error);
- /*
- * Set up the interrupt handler. XXX This should happen in
- * mfi_pci.c
- */
- sc->mfi_irq_rid = 0;
- if ((sc->mfi_irq = bus_alloc_resource_any(sc->mfi_dev, SYS_RES_IRQ,
- &sc->mfi_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
- device_printf(sc->mfi_dev, "Cannot allocate interrupt\n");
- return (EINVAL);
- }
- if (bus_setup_intr(sc->mfi_dev, sc->mfi_irq, INTR_MPSAFE|INTR_TYPE_BIO,
- NULL, mfi_intr, sc, &sc->mfi_intr)) {
- device_printf(sc->mfi_dev, "Cannot set up interrupt\n");
- return (EINVAL);
+ sc->mfi_irq_rid = 0;
+ if ((sc->mfi_irq = bus_alloc_resource_any(sc->mfi_dev, SYS_RES_IRQ,
+ &sc->mfi_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+ device_printf(sc->mfi_dev, "Cannot allocate interrupt\n");
+ return (EINVAL);
+ }
+ if (bus_setup_intr(sc->mfi_dev, sc->mfi_irq, INTR_MPSAFE|INTR_TYPE_BIO,
+ NULL, mfi_intr, sc, &sc->mfi_intr)) {
+ device_printf(sc->mfi_dev, "Cannot set up interrupt\n");
+ return (EINVAL);
+ }
+ sc->mfi_enable_intr(sc);
}
-
+ if ((error = mfi_get_controller_info(sc)) != 0)
+ return (error);
+ sc->disableOnlineCtrlReset = 0;
+
/* Register a config hook to probe the bus for arrays */
sc->mfi_ich.ich_func = mfi_startup;
sc->mfi_ich.ich_arg = sc;
@@ -507,6 +720,10 @@ mfi_attach(struct mfi_softc *sc)
"hook\n");
return (EINVAL);
}
+ if ((error = mfi_aen_setup(sc, 0), 0) != 0) {
+ mtx_unlock(&sc->mfi_io_lock);
+ return (error);
+ }
/*
* Register a shutdown handler.
@@ -548,6 +765,8 @@ mfi_attach(struct mfi_softc *sc)
return (0);
}
+
+
static int
mfi_alloc_commands(struct mfi_softc *sc)
{
@@ -578,8 +797,11 @@ mfi_alloc_commands(struct mfi_softc *sc)
cm->cm_sc = sc;
cm->cm_index = i;
if (bus_dmamap_create(sc->mfi_buffer_dmat, 0,
- &cm->cm_dmamap) == 0)
+ &cm->cm_dmamap) == 0) {
+ mtx_lock(&sc->mfi_io_lock);
mfi_release_command(cm);
+ mtx_unlock(&sc->mfi_io_lock);
+ }
else
break;
sc->mfi_total_cmds++;
@@ -594,6 +816,8 @@ mfi_release_command(struct mfi_command *
struct mfi_frame_header *hdr;
uint32_t *hdr_data;
+ mtx_assert(&cm->cm_sc->mfi_io_lock, MA_OWNED);
+
/*
* Zero out the important fields of the frame, but make sure the
* context field is preserved. For efficiency, handle the fields
@@ -618,6 +842,7 @@ mfi_release_command(struct mfi_command *
cm->cm_data = NULL;
cm->cm_sg = 0;
cm->cm_total_frame_size = 0;
+ cm->retry_for_fw_reset = 0;
mfi_enqueue_free(cm);
}
@@ -629,13 +854,19 @@ mfi_dcmd_command(struct mfi_softc *sc, s
struct mfi_command *cm;
struct mfi_dcmd_frame *dcmd;
void *buf = NULL;
-
+ uint32_t context = 0;
+
mtx_assert(&sc->mfi_io_lock, MA_OWNED);
-
+
cm = mfi_dequeue_free(sc);
if (cm == NULL)
return (EBUSY);
+ /* Zero out the MFI frame */
+ context = cm->cm_frame->header.context;
+ bzero(cm->cm_frame,sizeof (union mfi_frame));
+ cm->cm_frame->header.context = context;
+
if ((bufsize > 0) && (bufp != NULL)) {
if (*bufp == NULL) {
buf = malloc(bufsize, M_MFIBUF, M_NOWAIT|M_ZERO);
@@ -655,6 +886,7 @@ mfi_dcmd_command(struct mfi_softc *sc, s
dcmd->header.timeout = 0;
dcmd->header.flags = 0;
dcmd->header.data_len = bufsize;
+ dcmd->header.scsi_status = 0;
dcmd->opcode = opcode;
cm->cm_sg = &dcmd->sgl;
cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE;
@@ -676,11 +908,17 @@ mfi_comms_init(struct mfi_softc *sc)
struct mfi_init_frame *init;
struct mfi_init_qinfo *qinfo;
int error;
+ uint32_t context = 0;
mtx_lock(&sc->mfi_io_lock);
if ((cm = mfi_dequeue_free(sc)) == NULL)
return (EBUSY);
+ /* Zero out the MFI frame */
+ context = cm->cm_frame->header.context;
+ bzero(cm->cm_frame,sizeof (union mfi_frame));
+ cm->cm_frame->header.context = context;
+
/*
* Abuse the SG list area of the frame to hold the init_qinfo
* object;
@@ -741,10 +979,13 @@ mfi_get_controller_info(struct mfi_softc
BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
- max_sectors_1 = (1 << ci->stripe_sz_ops.min) * ci->max_strips_per_io;
+
+ //max_sectors_1 = (1 << ci->stripe_sz_ops.min) * ci->max_strips_per_io;
+ max_sectors_1 = (1 << ci->stripe_sz_ops.max) * ci->max_strips_per_io;
max_sectors_2 = ci->max_request_size;
sc->mfi_max_io = min(max_sectors_1, max_sectors_2);
-
+ sc->disableOnlineCtrlReset = ci->properties.OnOffProperties.disableOnlineCtrlReset;
+
out:
if (ci)
free(ci, M_MFIBUF);
@@ -760,6 +1001,7 @@ mfi_get_log_state(struct mfi_softc *sc,
struct mfi_command *cm = NULL;
int error;
+ mtx_lock(&sc->mfi_io_lock);
error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_EVENT_GETINFO,
(void **)log_state, sizeof(**log_state));
if (error)
@@ -778,11 +1020,12 @@ mfi_get_log_state(struct mfi_softc *sc,
out:
if (cm)
mfi_release_command(cm);
+ mtx_unlock(&sc->mfi_io_lock);
return (error);
}
-static int
+int
mfi_aen_setup(struct mfi_softc *sc, uint32_t seq_start)
{
struct mfi_evt_log_state *log_state = NULL;
@@ -817,7 +1060,7 @@ mfi_aen_setup(struct mfi_softc *sc, uint
return 0;
}
-static int
+int
mfi_wait_command(struct mfi_softc *sc, struct mfi_command *cm)
{
@@ -840,7 +1083,6 @@ mfi_wait_command(struct mfi_softc *sc, s
msleep(cm, &sc->mfi_io_lock, PRIBIO, "mfiwait", 0);
return (cm->cm_error);
}
-
void
mfi_free(struct mfi_softc *sc)
{
@@ -889,7 +1131,70 @@ mfi_free(struct mfi_softc *sc)
sc->mfi_comms_dmamap);
if (sc->mfi_comms_dmat != NULL)
bus_dma_tag_destroy(sc->mfi_comms_dmat);
+
+ /* ThunderBolt contiguous memory free here */
+
+ if(sc->mfi_flags & MFI_FLAGS_TBOLT)
+ {
+ if (sc->mfi_tb_busaddr != 0)
+ bus_dmamap_unload(sc->mfi_tb_dmat, sc->mfi_tb_dmamap);
+ if (sc->request_message_pool != NULL)
+ bus_dmamem_free(sc->mfi_tb_dmat, sc->request_message_pool,
+ sc->mfi_tb_dmamap);
+ if (sc->mfi_tb_dmat != NULL)
+ bus_dma_tag_destroy(sc->mfi_tb_dmat);
+
+ /* Version buffer memory free */
+ // Start LSIP200113393
+ if (sc->verbuf_h_busaddr != 0)
+ bus_dmamap_unload(sc->verbuf_h_dmat, sc->verbuf_h_dmamap);
+ if (sc->verbuf != NULL)
+ bus_dmamem_free(sc->verbuf_h_dmat, sc->verbuf,
+ sc->verbuf_h_dmamap);
+ if (sc->verbuf_h_dmat != NULL)
+ bus_dma_tag_destroy(sc->verbuf_h_dmat);
+
+ // End LSIP200113393
+ /* ThunderBolt INIT pcaket memory Free */
+ if (sc->mfi_tb_init_busaddr != 0)
+ bus_dmamap_unload(sc->mfi_tb_init_dmat, sc->mfi_tb_init_dmamap);
+ if (sc->mfi_tb_init != NULL)
+ bus_dmamem_free(sc->mfi_tb_init_dmat, sc->mfi_tb_init,
+ sc->mfi_tb_init_dmamap);
+ if (sc->mfi_tb_init_dmat != NULL)
+ bus_dma_tag_destroy(sc->mfi_tb_init_dmat);
+ /* ThunderBolt IOC Init Desc memory free here */
+
+ if (sc->mfi_tb_ioc_init_busaddr != 0)
+ bus_dmamap_unload(sc->mfi_tb_ioc_init_dmat, sc->mfi_tb_ioc_init_dmamap);
+ if (sc->mfi_tb_ioc_init_desc != NULL)
+ bus_dmamem_free(sc->mfi_tb_ioc_init_dmat, sc->mfi_tb_ioc_init_desc, sc->mfi_tb_ioc_init_dmamap);
+ if (sc->mfi_tb_ioc_init_dmat != NULL)
+ bus_dma_tag_destroy(sc->mfi_tb_ioc_init_dmat);
+
+ for(int i=0; i < sc->mfi_max_fw_cmds; i++)
+ {
+ if (sc->mfi_cmd_pool_tbolt != NULL)
+ {
+ if (sc->mfi_cmd_pool_tbolt[i] != NULL)
+ {
+ free(sc->mfi_cmd_pool_tbolt[i], M_MFIBUF);
+ sc->mfi_cmd_pool_tbolt[i] = NULL;
+ }
+ }
+ }
+ if (sc->mfi_cmd_pool_tbolt != NULL)
+ {
+ free(sc->mfi_cmd_pool_tbolt, M_MFIBUF);
+ sc->mfi_cmd_pool_tbolt = NULL;
+ }
+ if (sc->request_desc_pool != NULL)
+ {
+ free(sc->request_desc_pool, M_MFIBUF);
+ sc->request_desc_pool = NULL;
+ }
+ }
if (sc->mfi_buffer_dmat != NULL)
bus_dma_tag_destroy(sc->mfi_buffer_dmat);
if (sc->mfi_parent_dmat != NULL)
@@ -912,10 +1217,12 @@ mfi_startup(void *arg)
config_intrhook_disestablish(&sc->mfi_ich);
- sc->mfi_enable_intr(sc);
+ //sc->mfi_enable_intr(sc);
sx_xlock(&sc->mfi_config_lock);
mtx_lock(&sc->mfi_io_lock);
mfi_ldprobe(sc);
+ if (sc->mfi_flags & MFI_FLAGS_SKINNY)
+ mfi_syspdprobe(sc);
mtx_unlock(&sc->mfi_io_lock);
sx_xunlock(&sc->mfi_config_lock);
}
@@ -976,6 +1283,9 @@ mfi_shutdown(struct mfi_softc *sc)
if (sc->mfi_aen_cm != NULL)
mfi_abort(sc, sc->mfi_aen_cm);
+ if (sc->map_update_cmd != NULL)
+ mfi_abort(sc, sc->map_update_cmd);
+
dcmd = &cm->cm_frame->dcmd;
dcmd->header.flags = MFI_FRAME_DIR_NONE;
cm->cm_flags = MFI_CMD_POLLED;
@@ -986,9 +1296,80 @@ mfi_shutdown(struct mfi_softc *sc)
}
mfi_release_command(cm);
+ sc->shutdown_issued = 1;
mtx_unlock(&sc->mfi_io_lock);
return (error);
}
+static void
+mfi_syspdprobe(struct mfi_softc *sc)
+{
+ struct mfi_frame_header *hdr;
+ struct mfi_command *cm = NULL;
+ struct mfi_pd_list *pdlist = NULL;
+ struct mfi_system_pd *syspd;
+ int error, i;
+
+ sx_assert(&sc->mfi_config_lock,SA_XLOCKED);
+ mtx_assert(&sc->mfi_io_lock,MA_OWNED);
+ /* Add SYSTEM PD's */
+ error = mfi_dcmd_command(sc, &cm, MFI_DCMD_PD_LIST_QUERY,
+ (void **)&pdlist, sizeof(*pdlist));
+ if (error){
+ device_printf(sc->mfi_dev,"Error while forming SYSTEM PD list\n");
+ goto out;
+ }
+
+ cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
+ cm->cm_frame->dcmd.mbox[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
+ cm->cm_frame->dcmd.mbox[1] = 0;
+ if (mfi_mapcmd(sc, cm) != 0) {
+ device_printf(sc->mfi_dev, "Failed to get syspd device listing\n");
+ goto out;
+ }
+ bus_dmamap_sync(sc->mfi_buffer_dmat,cm->cm_dmamap,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
+ hdr = &cm->cm_frame->header;
+ if (hdr->cmd_status != MFI_STAT_OK) {
+ device_printf(sc->mfi_dev, "MFI_DCMD_PD_LIST_QUERY failed %x\n",
+ hdr->cmd_status);
+ goto out;
+ }
+ for (i=0;i<pdlist->count;i++) {
+ if(pdlist->addr[i].device_id == pdlist->addr[i].encl_device_id)
+ goto skip_sys_pd_add;
+ /* Get each PD and add it to the system */
+ if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
+ TAILQ_FOREACH(syspd, &sc->mfi_syspd_tqh,pd_link) {
+ if (syspd->pd_id == pdlist->addr[i].device_id)
+ goto skip_sys_pd_add;
+ }
+ }
+ mfi_add_sys_pd(sc,pdlist->addr[i].device_id);
+ skip_sys_pd_add:;
+
+ }
+ /* Delete SYSPD's whose state has been changed */
+ if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
+ TAILQ_FOREACH(syspd, &sc->mfi_syspd_tqh,pd_link) {
+ for (i=0;i<pdlist->count;i++) {
+ if (syspd->pd_id == pdlist->addr[i].device_id)
+ goto skip_sys_pd_delete;
+ }
+ mtx_lock(&Giant);
+ device_delete_child(sc->mfi_dev,syspd->pd_dev);
+ mtx_unlock(&Giant);
+skip_sys_pd_delete:;
+ }
+ }
+out:
+ if (pdlist)
+ free(pdlist, M_MFIBUF);
+ if (cm)
+ mfi_release_command(cm);
+
+ return;
+}
static void
mfi_ldprobe(struct mfi_softc *sc)
@@ -1082,8 +1463,79 @@ format_class(int8_t class)
}
static void
-mfi_decode_evt(struct mfi_softc *sc, struct mfi_evt_detail *detail)
+mfi_decode_evt(struct mfi_softc *sc, struct mfi_evt_detail *detail,uint8_t probe_sys_pd)
{
+ struct mfi_system_pd *syspd = NULL;
+ switch (detail->arg_type) {
+ case MR_EVT_ARGS_NONE:
+#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED 0x0152
+ if (detail->code == MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED) {
+ device_printf(sc->mfi_dev,"HostBus scan raised\n");
+ if (probe_sys_pd) {
+ /* Probe for new SYSPD's and Delete invalid SYSPD's */
+ sx_xlock(&sc->mfi_config_lock);
+ mtx_lock(&sc->mfi_io_lock);
+ mfi_syspdprobe(sc);
+ mtx_unlock(&sc->mfi_io_lock);
+ sx_xunlock(&sc->mfi_config_lock);
+ }
+ }
+ break;
+ case MR_EVT_ARGS_LD_STATE:
+ /* During load time driver reads all the events starting from the one that
+ * has been logged after shutdown. Avoid these old events.
+ */
+ if (!TAILQ_EMPTY(&sc->mfi_ld_tqh)) {
+ if (detail->args.ld_state.new_state == MFI_LD_STATE_OFFLINE ) {
+ /* Remove the LD */
+ struct mfi_disk *ld = NULL;
+ TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
+ if (ld->ld_id == detail->args.ld_state.ld.target_id)
+ break;
+ }
+ /*
+ Fix: for kernel panics when SSCD is removed
+ KASSERT(ld != NULL, ("volume dissappeared"));
+ */
+ if(ld != NULL)
+ {
+ mtx_lock(&Giant);
+ device_delete_child(sc->mfi_dev, ld->ld_dev);
+ mtx_unlock(&Giant);
+ }
+ }
+ }
+ break;
+ case MR_EVT_ARGS_PD:
+#define MR_EVT_PD_REMOVED 0x0070
+#define MR_EVT_PD_INSERTED 0x005b
+ if (detail->code == MR_EVT_PD_REMOVED) {
+ if (probe_sys_pd) {
+ /* If the removed device is a SYSPD then delete it */
+ if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
+ TAILQ_FOREACH(syspd,&sc->mfi_syspd_tqh,pd_link) {
+ if (syspd->pd_id == detail->args.pd.device_id) {
+ mtx_lock(&Giant);
+ device_delete_child(sc->mfi_dev,syspd->pd_dev);
+ mtx_unlock(&Giant);
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (detail->code == MR_EVT_PD_INSERTED) {
+ if (probe_sys_pd) {
+ /* Probe for new SYSPD's */
+ sx_xlock(&sc->mfi_config_lock);
+ mtx_lock(&sc->mfi_io_lock);
+ mfi_syspdprobe(sc);
+ mtx_unlock(&sc->mfi_io_lock);
+ sx_xunlock(&sc->mfi_config_lock);
+ }
+ }
+ break;
+ }
device_printf(sc->mfi_dev, "%d (%s/0x%04x/%s) - %s\n", detail->seq,
format_timestamp(detail->time), detail->evt_class.members.locale,
@@ -1113,12 +1565,16 @@ mfi_aen_register(struct mfi_softc *sc, i
< current_aen.members.evt_class)
current_aen.members.evt_class =
prior_aen.members.evt_class;
+ mtx_lock(&sc->mfi_io_lock);
mfi_abort(sc, sc->mfi_aen_cm);
+ mtx_unlock(&sc->mfi_io_lock);
}
}
+ mtx_lock(&sc->mfi_io_lock);
error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_EVENT_WAIT,
(void **)&ed, sizeof(*ed));
+ mtx_unlock(&sc->mfi_io_lock);
if (error) {
goto out;
}
@@ -1128,11 +1584,14 @@ mfi_aen_register(struct mfi_softc *sc, i
((uint32_t *)&dcmd->mbox)[1] = locale;
cm->cm_flags = MFI_CMD_DATAIN;
cm->cm_complete = mfi_aen_complete;
-
+
+ sc->last_seq_num = seq;
sc->mfi_aen_cm = cm;
+ mtx_lock(&sc->mfi_io_lock);
mfi_enqueue_ready(cm);
mfi_startio(sc);
+ mtx_unlock(&sc->mfi_io_lock);
out:
return (error);
@@ -1148,6 +1607,8 @@ mfi_aen_complete(struct mfi_command *cm)
int seq = 0, aborted = 0;
sc = cm->cm_sc;
+ mtx_assert(&sc->mfi_io_lock, MA_OWNED);
+
hdr = &cm->cm_frame->header;
if (sc->mfi_aen_cm == NULL)
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list