cc -O2 -fno-strict-aliasing -pipe -fno-delete-null-pointer-checks -march=core2 -
fno-builtin-strftime -Wsystem-headers -Wall -Wno-format-y2k -W -Wno-unused-param
eter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wno-uninitialized
 -Wno-pointer-sign -c /usr/src/usr.sbin/mfiutil/mfi_evt.c
/usr/src/usr.sbin/mfiutil/mfi_evt.c: In function 'mfi_decode_evt':
/usr/src/usr.sbin/mfiutil/mfi_evt.c:366: error: 'struct mfi_evt_detail' has no m
ember named 'class'
/usr/src/usr.sbin/mfiutil/mfi_evt.c:367: error: 'struct mfi_evt_detail' has no m
ember named 'class'
/usr/src/usr.sbin/mfiutil/mfi_evt.c: In function 'show_events':
/usr/src/usr.sbin/mfiutil/mfi_evt.c:562: error: 'struct <anonymous>' has no memb
er named 'class'
/usr/src/usr.sbin/mfiutil/mfi_evt.c:572: error: 'struct <anonymous>' has no memb
er named 'class'
cc -O2 -fno-strict-aliasing -pipe -fno-delete-null-pointer-checks -march=core2 -
DGTAGS -DSYSV_CURSES -I/usr/src/usr.bin/vi -I/usr/src/usr.bin/vi/../../contrib/n
vi -I/usr/src/usr.bin/vi/../../contrib/nvi/include  -c /usr/src/usr.bin/vi/../..
/contrib/nvi/ex/ex_put.c
*** Error code 1

---------------

diff --git a/usr.sbin/mfiutil/mfi_evt.c b/usr.sbin/mfiutil/mfi_evt.c
index a14bb19..336fbd3 100644
--- a/usr.sbin/mfiutil/mfi_evt.c
+++ b/usr.sbin/mfiutil/mfi_evt.c
@@ -363,8 +363,8 @@ mfi_decode_evt(int fd, struct mfi_evt_detail
*detail, int verbose)
 {

        printf("%5d (%s/%s/%s) - ", detail->seq, format_timestamp(detail->time),
-           format_locale(detail->class.members.locale),
-           format_class(detail->class.members.class));
+           format_locale(detail->evt_class.members.locale),
+           format_class(detail->evt_class.members.evt_class));
        switch (detail->arg_type) {
        case MR_EVT_ARGS_NONE:
                break;
@@ -559,7 +559,7 @@ show_events(int ac, char **av)
        num_events = 15;
        filter.members.reserved = 0;
        filter.members.locale = MFI_EVT_LOCALE_ALL;
-       filter.members.class = MFI_EVT_CLASS_WARNING;
+       filter.members.evt_class = MFI_EVT_CLASS_WARNING;
        start = info.boot_seq_num;
        stop = info.newest_seq_num;
        verbose = 0;
@@ -569,7 +569,7 @@ show_events(int ac, char **av)
        while ((ch = getopt(ac, av, "c:l:n:v")) != -1) {
                switch (ch) {
                case 'c':
-                       if (parse_class(optarg, &filter.members.class) < 0) {
+                       if (parse_class(optarg,
&filter.members.evt_class) < 0) {
                                error = errno;
                                warn("Error parsing event class");
                                close(fd);


--------------

not tested, compiling now

On 5/19/12, Sean Bruno <sbr...@freebsd.org> wrote:
> Author: sbruno
> Date: Fri May 18 23:29:30 2012
> New Revision: 235636
> URL: http://svn.freebsd.org/changeset/base/235636
>
> Log:
>   MFC of head thunderbolt support for mfi(4)
>
>   r233711 -- IFV head_mfi into head for initial thunderbolt support
>   r233768 -- atomic_t --> mfi_atomic
>   r233805 -- fix tinderbuild, move megasas_sge to mfivar.h
>   r233877 -- remove atomic.h from includes
>   r235014 -- fix reading of sector >= 2^32 or 2^21, repair RAID handling
>   r235016 -- style(9)
>   r235040 -- fix returns from mfi_tbolt_sync_map_info()
>   r235318 -- repair panic on PAE i386
>   r235321 -- repair the repair of panics on PAE i386
>
> Added:
>   stable/7/sys/dev/mfi/mfi_syspd.c
>      - copied unchanged from r233711, head/sys/dev/mfi/mfi_syspd.c
>   stable/7/sys/dev/mfi/mfi_tbolt.c
>      - copied, changed from r233711, head/sys/dev/mfi/mfi_tbolt.c
> Modified:
>   stable/7/sys/conf/files
>   stable/7/sys/dev/mfi/mfi.c
>   stable/7/sys/dev/mfi/mfi_cam.c
>   stable/7/sys/dev/mfi/mfi_debug.c
>   stable/7/sys/dev/mfi/mfi_disk.c
>   stable/7/sys/dev/mfi/mfi_ioctl.h
>   stable/7/sys/dev/mfi/mfi_linux.c
>   stable/7/sys/dev/mfi/mfi_pci.c
>   stable/7/sys/dev/mfi/mfireg.h
>   stable/7/sys/dev/mfi/mfivar.h
>   stable/7/sys/modules/mfi/Makefile
> Directory Properties:
>   stable/7/sys/   (props changed)
>
> Modified: stable/7/sys/conf/files
> ==============================================================================
> --- stable/7/sys/conf/files   Fri May 18 21:50:26 2012        (r235635)
> +++ stable/7/sys/conf/files   Fri May 18 23:29:30 2012        (r235636)
> @@ -948,6 +948,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: stable/7/sys/dev/mfi/mfi.c
> ==============================================================================
> --- stable/7/sys/dev/mfi/mfi.c        Fri May 18 21:50:26 2012        
> (r235635)
> +++ stable/7/sys/dev/mfi/mfi.c        Fri May 18 23:29:30 2012        
> (r235636)
> @@ -53,6 +53,7 @@
>  #include <sys/cdefs.h>
>  __FBSDID("$FreeBSD$");
>
> +#include "opt_compat.h"
>  #include "opt_mfi.h"
>
>  #include <sys/param.h>
> @@ -72,6 +73,7 @@ __FBSDID("$FreeBSD$");
>  #include <sys/uio.h>
>  #include <sys/proc.h>
>  #include <sys/signalvar.h>
> +#include <sys/taskqueue.h>
>
>  #include <machine/bus.h>
>  #include <machine/resource.h>
> @@ -79,43 +81,52 @@ __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 **);
>  static int   mfi_parse_entries(struct mfi_softc *, int, int);
> -static int   mfi_dcmd_command(struct mfi_softc *, struct mfi_command **,
> -                 uint32_t, void **, size_t);
>  static void  mfi_data_cb(void *, bus_dma_segment_t *, int, int);
>  static void  mfi_startup(void *arg);
>  static void  mfi_intr(void *arg);
>  static void  mfi_ldprobe(struct mfi_softc *sc);
> +static void  mfi_syspdprobe(struct mfi_softc *sc);
> +static void  mfi_handle_evt(void *context, int pending);
>  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,
> d_thread_t *);
> +static int   mfi_linux_ioctl_int(struct cdev *, u_long, caddr_t, int, struct
> thread *);
>  static void  mfi_timeout(void *);
>  static int   mfi_user_command(struct mfi_softc *,
>                   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 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_enable_intr_xscale(struct mfi_softc *sc);
> +static void  mfi_enable_intr_ppc(struct mfi_softc *sc);
> +static int32_t       mfi_read_fw_status_xscale(struct mfi_softc *sc);
> +static int32_t       mfi_read_fw_status_ppc(struct mfi_softc *sc);
> +static int   mfi_check_clear_intr_xscale(struct mfi_softc *sc);
> +static int   mfi_check_clear_intr_ppc(struct mfi_softc *sc);
> +static void  mfi_issue_cmd_xscale(struct mfi_softc *sc, 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;
> @@ -133,6 +144,11 @@ TUNABLE_INT("hw.mfi.max_cmds", &mfi_max_
>  SYSCTL_INT(_hw_mfi, OID_AUTO, max_cmds, CTLFLAG_RD, &mfi_max_cmds,
>          0, "Max commands");
>
> +static int   mfi_detect_jbod_change = 1;
> +TUNABLE_INT("hw.mfi.detect_jbod_change", &mfi_detect_jbod_change);
> +SYSCTL_INT(_hw_mfi, OID_AUTO, detect_jbod_change, CTLFLAG_RW,
> +        &mfi_detect_jbod_change, 0, "Detect a change to a JBOD");
> +
>  /* Management interface */
>  static d_open_t              mfi_open;
>  static d_close_t     mfi_close;
> @@ -152,6 +168,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 +179,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 +227,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)
>  {
> -     int32_t fw_state, cur_state;
> +     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,36 +282,62 @@ 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, 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:
> +                     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 %d\n",
> +                     device_printf(sc->mfi_dev, "Unknown firmware state 
> %#x\n",
>                           fw_state);
>                       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 "
> +                     device_printf(sc->mfi_dev, "Firmware stuck in state "
>                           "%#x\n", fw_state);
>                       return (ENXIO);
>               }
> @@ -282,26 +346,36 @@ 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;
>
> -     device_printf(sc->mfi_dev, "Megaraid SAS driver Ver 3.00 \n");
> +     if (sc == NULL)
> +             return EINVAL;
> +
> +     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_evt_queue);
> +     TASK_INIT(&sc->mfi_evt_task, 0, mfi_handle_evt, sc);
> +     TASK_INIT(&sc->mfi_map_sync_task, 0, mfi_handle_map_sync, sc);
>       TAILQ_INIT(&sc->mfi_aen_pids);
>       TAILQ_INIT(&sc->mfi_cam_ccbq);
>
> @@ -310,15 +384,29 @@ mfi_attach(struct mfi_softc *sc)
>       mfi_initq_busy(sc);
>       mfi_initq_bio(sc);
>
> +     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 {
> +     } 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;
>       }
> @@ -331,6 +419,32 @@ mfi_attach(struct mfi_softc *sc)
>               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
>        * frame pool.  Size down the sgl parameter since we know that
> @@ -341,8 +455,102 @@ mfi_attach(struct mfi_softc *sc)
>       status = sc->mfi_read_fw_status(sc);
>       sc->mfi_max_fw_cmds = status & MFI_FWSTATE_MAXCMD_MASK;
>       max_fw_sge = (status & MFI_FWSTATE_MAXSGL_MASK) >> 16;
> -     sc->mfi_max_sge = min(max_fw_sge, ((MAXPHYS / PAGE_SIZE) + 1));
> +     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,               /* alignmnt, 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.
> @@ -392,8 +600,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
> @@ -410,6 +617,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;
> @@ -434,8 +643,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
> @@ -461,39 +669,46 @@ 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;
> +             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);
> +     } 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);
> +             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;
> @@ -503,6 +718,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.
> @@ -541,6 +760,10 @@ mfi_attach(struct mfi_softc *sc)
>       callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz,
>           mfi_timeout, sc);
>
> +     if (sc->mfi_flags & MFI_FLAGS_TBOLT) {
> +             mfi_tbolt_sync_map_info(sc);
> +     }
> +
>       return (0);
>  }
>
> @@ -574,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++;
> @@ -590,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
> @@ -614,24 +842,31 @@ 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);
>  }
>
> -static int
> -mfi_dcmd_command(struct mfi_softc *sc, struct mfi_command **cmp, uint32_t
> opcode,
> -    void **bufp, size_t bufsize)
> +int
> +mfi_dcmd_command(struct mfi_softc *sc, struct mfi_command **cmp,
> +    uint32_t opcode, void **bufp, size_t bufsize)
>  {
>       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);
> @@ -651,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;
> @@ -672,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;
> @@ -737,9 +979,11 @@ 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.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)
> @@ -756,6 +1000,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)
> @@ -774,11 +1019,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;
> @@ -788,10 +1034,11 @@ mfi_aen_setup(struct mfi_softc *sc, uint
>
>       class_locale.members.reserved = 0;
>       class_locale.members.locale = mfi_event_locale;
> -     class_locale.members.class  = mfi_event_class;
> +     class_locale.members.evt_class  = mfi_event_class;
>
>       if (seq_start == 0) {
>               error = mfi_get_log_state(sc, &log_state);
> +             sc->mfi_boot_seq_num = log_state->boot_seq_num;
>               if (error) {
>                       if (log_state)
>                               free(log_state, M_MFIBUF);
> @@ -813,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)
>  {
>
> @@ -886,6 +1133,64 @@ mfi_free(struct mfi_softc *sc)
>       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 packet 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,6 +1217,8 @@ mfi_startup(void *arg)
>       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);
>  }
> @@ -928,12 +1235,7 @@ mfi_intr(void *arg)
>       if (sc->mfi_check_clear_intr(sc))
>               return;
>
> -     /*
> -      * Do a dummy read to flush the interrupt ACK that we just performed,
> -      * ensuring that everything is really, truly consistent.
> -      */
> -     (void)sc->mfi_read_fw_status(sc);
> -
> +restart:
>       pi = sc->mfi_comms->hw_pi;
>       ci = sc->mfi_comms->hw_ci;
>       mtx_lock(&sc->mfi_io_lock);
> @@ -958,6 +1260,14 @@ mfi_intr(void *arg)
>       mfi_startio(sc);
>       mtx_unlock(&sc->mfi_io_lock);
>
> +     /*
> +      * Dummy read to flush the bus; this ensures that the indexes are up
> +      * to date.  Restart processing if more commands have come it.
> +      */
> +     (void)sc->mfi_read_fw_status(sc);
> +     if (pi != sc->mfi_comms->hw_pi)
> +             goto restart;
> +
>       return;
>  }
>
> @@ -978,6 +1288,9 @@ mfi_shutdown(struct mfi_softc *sc)
>       if (sc->mfi_aen_cm != NULL)
>               mfi_abort(sc, sc->mfi_aen_cm);
>
> +     if (sc->mfi_map_sync_cm != NULL)
> +             mfi_abort(sc, sc->mfi_map_sync_cm);
> +
>       dcmd = &cm->cm_frame->dcmd;
>       dcmd->header.flags = MFI_FRAME_DIR_NONE;
>       cm->cm_flags = MFI_CMD_POLLED;
> @@ -993,6 +1306,81 @@ mfi_shutdown(struct mfi_softc *sc)
>  }
>
>  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, *tmp;
> +     int error, i, found;
> +
> +     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;
> +     }
> +     /* Get each PD and add it to the system */
> +     for (i = 0; i < pdlist->count; i++) {
> +             if (pdlist->addr[i].device_id ==
> +                 pdlist->addr[i].encl_device_id)
> +                     continue;
> +             found = 0;
> +             TAILQ_FOREACH(syspd, &sc->mfi_syspd_tqh, pd_link) {
> +                     if (syspd->pd_id == pdlist->addr[i].device_id)
> +                             found = 1;
> +             }
> +             if (found == 0)
> +                     mfi_add_sys_pd(sc, pdlist->addr[i].device_id);
> +     }
> +     /* Delete SYSPD's whose state has been changed */
> +     TAILQ_FOREACH_SAFE(syspd, &sc->mfi_syspd_tqh, pd_link, tmp) {
> +             found = 0;
> +             for (i = 0; i < pdlist->count; i++) {
> +                     if (syspd->pd_id == pdlist->addr[i].device_id)
> +                             found = 1;
> +             }
> +             if (found == 0) {
> +                     printf("DELETE\n");
> +                     mtx_unlock(&sc->mfi_io_lock);
> +                     mtx_lock(&Giant);
> +                     device_delete_child(sc->mfi_dev, syspd->pd_dev);
> +                     mtx_unlock(&Giant);
> +                     mtx_lock(&sc->mfi_io_lock);
> +             }
> +     }
> +out:
> +     if (pdlist)
> +         free(pdlist, M_MFIBUF);
> +     if (cm)
> +         mfi_release_command(cm);
> +
> +     return;
> +}
> +
> +static void
>  mfi_ldprobe(struct mfi_softc *sc)
>  {
>       struct mfi_frame_header *hdr;
> @@ -1086,10 +1474,124 @@ format_class(int8_t class)
>  static void
>  mfi_decode_evt(struct mfi_softc *sc, struct mfi_evt_detail *detail)
>  {
> +     struct mfi_system_pd *syspd = NULL;
>
>       device_printf(sc->mfi_dev, "%d (%s/0x%04x/%s) - %s\n", detail->seq,
> -         format_timestamp(detail->time), detail->class.members.locale,
> -         format_class(detail->class.members.class), detail->description);
> +         format_timestamp(detail->time), detail->evt_class.members.locale,
> +         format_class(detail->evt_class.members.evt_class),
> +         detail->description);
> +
> +        /* Don't act on old AEN's or while shutting down */
> +        if (detail->seq < sc->mfi_boot_seq_num || sc->mfi_detaching)
> +                return;
> +
> +     switch (detail->arg_type) {
> +     case MR_EVT_ARGS_NONE:
> +             if (detail->code == MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED) {
> +                 device_printf(sc->mfi_dev, "HostBus scan raised\n");
> +                     if (mfi_detect_jbod_change) {
> +                             /*
> +                              * 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 (detail->args.ld_state.new_state == MFI_LD_STATE_OFFLINE ) {
> +                     /* Remove the LD */
> +                     struct mfi_disk *ld;
> +                     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;
>
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
> _______________________________________________
> svn-src-sta...@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/svn-src-stable
> To unsubscribe, send any mail to "svn-src-stable-unsubscr...@freebsd.org"
>
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to