[Midnightbsd-cvs] src: dev/mpt: add newer raid controllers

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Mon Dec 1 20:17:25 EST 2008


Log Message:
-----------
add newer raid controllers

Modified Files:
--------------
    src/sys/dev/mpt:
        mpt.c (r1.2 -> r1.3)
        mpt.h (r1.3 -> r1.4)
        mpt_cam.c (r1.3 -> r1.4)
        mpt_cam.h (r1.2 -> r1.3)
        mpt_debug.c (r1.2 -> r1.3)
        mpt_pci.c (r1.2 -> r1.3)
        mpt_raid.c (r1.2 -> r1.3)
        mpt_raid.h (r1.2 -> r1.3)
        mpt_reg.h (r1.2 -> r1.3)
    src/sys/dev/mpt/mpilib:
        mpi.h (r1.2 -> r1.3)
        mpi_cnfg.h (r1.2 -> r1.3)
        mpi_fc.h (r1.2 -> r1.3)
        mpi_inb.h (r1.1 -> r1.2)
        mpi_init.h (r1.2 -> r1.3)
        mpi_ioc.h (r1.2 -> r1.3)
        mpi_lan.h (r1.2 -> r1.3)
        mpi_raid.h (r1.2 -> r1.3)
        mpi_sas.h (r1.1 -> r1.2)
        mpi_targ.h (r1.2 -> r1.3)
        mpi_tool.h (r1.1 -> r1.2)
        mpi_type.h (r1.2 -> r1.3)

Removed Files:
-------------
    src/sys/dev/mpt/mpilib:
        mpi_log_fc.h
        mpi_log_sas.h

-------------- next part --------------
Index: mpt.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpt.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -L sys/dev/mpt/mpt.h -L sys/dev/mpt/mpt.h -u -r1.3 -r1.4
--- sys/dev/mpt/mpt.h
+++ sys/dev/mpt/mpt.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpt.h,v 1.6.2.4 2006/09/16 05:42:06 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpt.h,v 1.42 2007/08/14 19:17:35 scottl Exp $ */
 /*-
  * Generic defines for LSI '909 FC  adapters.
  * FreeBSD Version.
@@ -105,12 +105,19 @@
 #include <sys/systm.h>
 #include <sys/endian.h>
 #include <sys/eventhandler.h>
+#if __FreeBSD_version < 500000  
+#include <sys/kernel.h>
+#include <sys/queue.h>
+#include <sys/malloc.h>
+#include <sys/devicestat.h>
+#else
 #include <sys/lock.h>
 #include <sys/kernel.h>
 #include <sys/queue.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
 #include <sys/condvar.h>
+#endif
 #include <sys/proc.h>
 #include <sys/bus.h>
 #include <sys/module.h>
@@ -118,10 +125,20 @@
 #include <machine/cpu.h>
 #include <machine/resource.h>
 
+#if __FreeBSD_version < 500000  
+#include <machine/bus.h>
+#include <machine/clock.h>
+#endif
+
 #include <sys/rman.h>
 
+#if __FreeBSD_version < 500000  
+#include <pci/pcireg.h>
+#include <pci/pcivar.h>
+#else
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
+#endif
 
 #include <machine/bus.h>
 #include "opt_ddb.h"
@@ -139,7 +156,11 @@
 /* XXX For mpt_debug.c */
 #include <dev/mpt/mpilib/mpi_init.h>
 
+#define	MPT_S64_2_SCALAR(y)	((((int64_t)y.High) << 32) | (y.Low))
+#define	MPT_U64_2_SCALAR(y)	((((uint64_t)y.High) << 32) | (y.Low))
+
 /****************************** Misc Definitions ******************************/
+/* #define MPT_TEST_MULTIPATH	1 */
 #define MPT_OK (0)
 #define MPT_FAIL (0x10000)
 
@@ -210,6 +231,9 @@
 #define bus_dmamap_sync_range(dma_tag, dmamap, offset, len, op)	\
 	bus_dmamap_sync(dma_tag, dmamap, op)
 
+#if __FreeBSD_version < 600000
+#define	bus_get_dma_tag(x)	NULL
+#endif
 #if __FreeBSD_version >= 501102
 #define mpt_dma_tag_create(mpt, parent_tag, alignment, boundary,	\
 			   lowaddr, highaddr, filter, filterarg,	\
@@ -218,7 +242,7 @@
 	bus_dma_tag_create(parent_tag, alignment, boundary,		\
 			   lowaddr, highaddr, filter, filterarg,	\
 			   maxsize, nsegments, maxsegsz, flags,		\
-			   busdma_lock_mutex, &Giant,			\
+			   busdma_lock_mutex, &(mpt)->mpt_lock,		\
 			   dma_tagp)
 #else
 #define mpt_dma_tag_create(mpt, parent_tag, alignment, boundary,	\
@@ -238,6 +262,13 @@
 };
 
 void mpt_map_rquest(void *, bus_dma_segment_t *, int, int);
+/* **************************** NewBUS interrupt Crock ************************/
+#if __FreeBSD_version < 700031
+#define	mpt_setup_intr(d, i, f, U, if, ifa, hp)	\
+	bus_setup_intr(d, i, f, if, ifa, hp)
+#else
+#define	mpt_setup_intr	bus_setup_intr
+#endif
 
 /**************************** Kernel Thread Support ***************************/
 #if __FreeBSD_version > 500005
@@ -250,21 +281,35 @@
 
 /****************************** Timer Facilities ******************************/
 #if __FreeBSD_version > 500000
-#define mpt_callout_init(c)	callout_init(c, /*mpsafe*/0);
+#define mpt_callout_init(c)	callout_init(c, /*mpsafe*/1);
 #else
 #define mpt_callout_init(c)	callout_init(c);
 #endif
 
 /********************************** Endianess *********************************/
-static __inline uint64_t
-u64toh(U64 s)
-{
-	uint64_t result;
-
-	result = le32toh(s.Low);
-	result |= ((uint64_t)le32toh(s.High)) << 32;
-	return (result);
-}
+#define	MPT_2_HOST64(ptr, tag)	ptr->tag = le64toh(ptr->tag)
+#define	MPT_2_HOST32(ptr, tag)	ptr->tag = le32toh(ptr->tag)
+#define	MPT_2_HOST16(ptr, tag)	ptr->tag = le16toh(ptr->tag)
+
+#define	HOST_2_MPT64(ptr, tag)	ptr->tag = htole64(ptr->tag)
+#define	HOST_2_MPT32(ptr, tag)	ptr->tag = htole32(ptr->tag)
+#define	HOST_2_MPT16(ptr, tag)	ptr->tag = htole16(ptr->tag)
+
+#if	_BYTE_ORDER == _BIG_ENDIAN
+void mpt2host_sge_simple_union(SGE_SIMPLE_UNION *);
+void mpt2host_iocfacts_reply(MSG_IOC_FACTS_REPLY *);
+void mpt2host_portfacts_reply(MSG_PORT_FACTS_REPLY *);
+void mpt2host_config_page_ioc2(CONFIG_PAGE_IOC_2 *);
+void mpt2host_config_page_raid_vol_0(CONFIG_PAGE_RAID_VOL_0 *);
+void mpt2host_mpi_raid_vol_indicator(MPI_RAID_VOL_INDICATOR *);
+#else
+#define	mpt2host_sge_simple_union(x)		do { ; } while (0)
+#define	mpt2host_iocfacts_reply(x)		do { ; } while (0)
+#define	mpt2host_portfacts_reply(x)		do { ; } while (0)
+#define	mpt2host_config_page_ioc2(x)		do { ; } while (0)
+#define	mpt2host_config_page_raid_vol_0(x)	do { ; } while (0)
+#define	mpt2host_mpi_raid_vol_indicator(x)	do { ; } while (0)
+#endif
 
 /**************************** MPI Transaction State ***************************/
 typedef enum {
@@ -293,8 +338,20 @@
 	bus_addr_t	sense_pbuf;	/* Physical Address of sense data */
 	bus_dmamap_t	dmap;		/* DMA map for data buffers */
 	struct req_entry *chain;	/* for SGE overallocations */
+	struct callout  callout;	/* Timeout for the request */
 };
 
+typedef struct mpt_config_params {
+	u_int		Action;
+	u_int		PageVersion;
+	u_int		PageLength;
+	u_int		PageNumber;
+	u_int		PageType;
+	u_int		PageAddress;
+	u_int		ExtPageLength;
+	u_int		ExtPageType;
+} cfgparms_t;
+
 /**************************** MPI Target State Info ***************************/
 
 typedef struct {
@@ -468,6 +525,36 @@
 
 LIST_HEAD(mpt_evtf_list, mpt_evtf_record);
 
+struct mptsas_devinfo {
+	uint16_t	dev_handle;
+	uint16_t	parent_dev_handle;
+	uint16_t	enclosure_handle;
+	uint16_t	slot;
+	uint8_t		phy_num;
+	uint8_t		physical_port;
+	uint8_t		target_id;
+	uint8_t		bus;
+	uint64_t	sas_address;
+	uint32_t	device_info;
+};
+
+struct mptsas_phyinfo {
+	uint16_t	handle;
+	uint8_t		phy_num;
+	uint8_t		port_id;
+	uint8_t		negotiated_link_rate;
+	uint8_t		hw_link_rate;
+	uint8_t		programmed_link_rate;
+	uint8_t		sas_port_add_phy;
+	struct mptsas_devinfo identify;
+	struct mptsas_devinfo attached;
+};
+
+struct mptsas_portinfo {
+	uint16_t			num_phys;
+	struct mptsas_phyinfo		*phy_info;
+};
+
 struct mpt_softc {
 	device_t		dev;
 #if __FreeBSD_version < 500000  
@@ -479,8 +566,11 @@
 #endif
 	uint32_t		mpt_pers_mask;
 	uint32_t
+				: 8,
 		unit		: 8,
-				: 3,
+		ready		: 1,
+		fw_uploaded	: 1,
+		msi_enable	: 1,
 		twildcard	: 1,
 		tenabled	: 1,
 		do_cfg_role	: 1,
@@ -499,25 +589,21 @@
 	u_int			role;	/* role: none, ini, target, both */
 
 	u_int			verbose;
+#ifdef	MPT_TEST_MULTIPATH
+	int			failure_id;
+#endif
 
 	/*
 	 * IOC Facts
 	 */
-	uint16_t	mpt_global_credits;
-	uint16_t	request_frame_size;
-	uint8_t		mpt_max_devices;
-	uint8_t		mpt_max_buses;
-	uint8_t		ioc_facts_flags;
-	uint8_t		padding0;
+	MSG_IOC_FACTS_REPLY	ioc_facts;
 
 	/*
 	 * Port Facts
-	 * XXX - Add multi-port support!.
 	 */
-	uint16_t	mpt_ini_id;
-	uint16_t	mpt_port_type;
-	uint16_t	mpt_proto_flags;
-	uint16_t	mpt_max_tgtcmds;
+	MSG_PORT_FACTS_REPLY *	port_facts;
+#define	mpt_ini_id	port_facts[0].PortSCSIID
+#define	mpt_max_tgtcmds	port_facts[0].MaxPostedCmdBuffers
 
 	/*
 	 * Device Configuration Information
@@ -583,6 +669,7 @@
 	/*
 	 * PCI Hardware info
 	 */
+	int			pci_msi_count;
 	struct resource *	pci_irq;	/* Interrupt map for chip */
 	void *			ih;		/* Interupt handle */
 	struct mpt_pci_cfg	pci_cfg;	/* saved PCI conf registers */
@@ -675,6 +762,9 @@
 	bus_dmamap_t		fw_dmap;	/* DMA map for firmware image */
 	bus_addr_t		fw_phys;	/* BusAddr of firmware image */
 
+	/* SAS Topology */
+	struct mptsas_portinfo	*sas_portinfo;
+
 	/* Shutdown Event Handler. */
 	eventhandler_tag         eh;
 
@@ -697,6 +787,7 @@
 #define	MPT_LOCK(mpt)		mpt_lockspl(mpt)
 #define	MPT_UNLOCK(mpt)		mpt_unlockspl(mpt)
 #define	MPT_OWNED(mpt)		mpt->mpt_islocked
+#define	MPT_LOCK_ASSERT(mpt)
 #define	MPTLOCK_2_CAMLOCK	MPT_UNLOCK
 #define	CAMLOCK_2_MPTLOCK	MPT_LOCK
 #define	MPT_LOCK_SETUP(mpt)
@@ -749,9 +840,13 @@
 	return (error);
 }
 
+#define mpt_req_timeout(req, ticks, func, arg) \
+	callout_reset(&(req)->callout, (ticks), (func), (arg));
+#define mpt_req_untimeout(req, func, arg) \
+	callout_stop(&(req)->callout)
+
 #else
-#ifdef	LOCKING_WORKED_AS_IT_SHOULD
-#error "Shouldn't Be Here!"
+#if 1
 #define	MPT_IFLAGS		INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE
 #define	MPT_LOCK_SETUP(mpt)						\
 		mtx_init(&mpt->mpt_lock, "mpt", NULL, MTX_DEF);		\
@@ -765,53 +860,44 @@
 #define	MPT_LOCK(mpt)		mtx_lock(&(mpt)->mpt_lock)
 #define	MPT_UNLOCK(mpt)		mtx_unlock(&(mpt)->mpt_lock)
 #define	MPT_OWNED(mpt)		mtx_owned(&(mpt)->mpt_lock)
-#define	MPTLOCK_2_CAMLOCK(mpt)	\
-	mtx_unlock(&(mpt)->mpt_lock); mtx_lock(&Giant)
-#define	CAMLOCK_2_MPTLOCK(mpt)	\
-	mtx_unlock(&Giant); mtx_lock(&(mpt)->mpt_lock)
+#define	MPT_LOCK_ASSERT(mpt)	mtx_assert(&(mpt)->mpt_lock, MA_OWNED)
+#define	MPTLOCK_2_CAMLOCK(mpt)
+#define	CAMLOCK_2_MPTLOCK(mpt)
 #define mpt_sleep(mpt, ident, priority, wmesg, timo) \
 	msleep(ident, &(mpt)->mpt_lock, priority, wmesg, timo)
+#define mpt_req_timeout(req, ticks, func, arg) \
+	callout_reset(&(req)->callout, (ticks), (func), (arg));
+#define mpt_req_untimeout(req, func, arg) \
+	callout_stop(&(req)->callout)
 
 #else
 
 #define	MPT_IFLAGS		INTR_TYPE_CAM | INTR_ENTROPY
 #define	MPT_LOCK_SETUP(mpt)	do { } while (0)
 #define	MPT_LOCK_DESTROY(mpt)	do { } while (0)
-#if	0
-#define	MPT_LOCK(mpt)		\
-	device_printf(mpt->dev, "LOCK %s:%d\n", __FILE__, __LINE__); 	\
-	KASSERT(mpt->mpt_locksetup == 0,				\
-	    ("recursive lock acquire at %s:%d", __FILE__, __LINE__));	\
-	mpt->mpt_locksetup = 1
-#define	MPT_UNLOCK(mpt)		\
-	device_printf(mpt->dev, "UNLK %s:%d\n", __FILE__, __LINE__); 	\
-	KASSERT(mpt->mpt_locksetup == 1,				\
-	    ("release unowned lock at %s:%d", __FILE__, __LINE__));	\
-	mpt->mpt_locksetup = 0
-#else
-#define	MPT_LOCK(mpt)							\
-	KASSERT(mpt->mpt_locksetup == 0,				\
-	    ("recursive lock acquire at %s:%d", __FILE__, __LINE__));	\
-	mpt->mpt_locksetup = 1
-#define	MPT_UNLOCK(mpt)							\
-	KASSERT(mpt->mpt_locksetup == 1,				\
-	    ("release unowned lock at %s:%d", __FILE__, __LINE__));	\
-	mpt->mpt_locksetup = 0
-#endif
-#define	MPT_OWNED(mpt)		mpt->mpt_locksetup
-#define	MPTLOCK_2_CAMLOCK(mpt)	MPT_UNLOCK(mpt)
-#define	CAMLOCK_2_MPTLOCK(mpt)	MPT_LOCK(mpt)
+#define	MPT_LOCK_ASSERT(mpt)	mtx_assert(&Giant, MA_OWNED)
+#define	MPT_LOCK(mpt)		mtx_lock(&Giant)
+#define	MPT_UNLOCK(mpt)		mtx_unlock(&Giant)
+#define	MPTLOCK_2_CAMLOCK(mpt)
+#define	CAMLOCK_2_MPTLOCK(mpt)
 
 static __inline int
 mpt_sleep(struct mpt_softc *, void *, int, const char *, int);
 
+#define mpt_ccb_timeout(ccb, ticks, func, arg) \
+	do {	\
+		(ccb)->ccb_h.timeout_ch = timeout((func), (arg), (ticks)); \
+	} while (0)
+#define mpt_ccb_untimeout(ccb, func, arg) \
+	untimeout((func), (arg), (ccb)->ccb_h.timeout_ch)
+#define mpt_ccb_timeout_init(ccb) \
+	callout_handle_init(&(ccb)->ccb_h.timeout_ch)
+
 static __inline int
 mpt_sleep(struct mpt_softc *mpt, void *i, int p, const char *w, int t)
 {
 	int r;
-	MPT_UNLOCK(mpt);
 	r = tsleep(i, p, w, t);
-	MPT_LOCK(mpt);
 	return (r);
 }
 #endif
@@ -913,7 +999,7 @@
 
 /************************** Scatter Gather Managment **************************/
 /* MPT_RQSL- size of request frame, in bytes */
-#define	MPT_RQSL(mpt)		(mpt->request_frame_size << 2)
+#define	MPT_RQSL(mpt)		(mpt->ioc_facts.RequestFrameSize << 2)
 
 /* MPT_NSGL- how many SG entries can fit in a request frame size */
 #define	MPT_NSGL(mpt)		(MPT_RQSL(mpt) / sizeof (SGE_IO_UNION))
@@ -1140,11 +1226,19 @@
 
 void		mpt_set_config_regs(struct mpt_softc *);
 int		mpt_issue_cfg_req(struct mpt_softc */*mpt*/, request_t */*req*/,
-				  u_int /*Action*/, u_int /*PageVersion*/,
-				  u_int /*PageLength*/, u_int /*PageNumber*/,
-				  u_int /*PageType*/, uint32_t /*PageAddress*/,
+				  cfgparms_t *params,
 				  bus_addr_t /*addr*/, bus_size_t/*len*/,
 				  int /*sleep_ok*/, int /*timeout_ms*/);
+int		mpt_read_extcfg_header(struct mpt_softc *mpt, int PageVersion,
+				       int PageNumber, uint32_t PageAddress,
+				       int ExtPageType,
+				       CONFIG_EXTENDED_PAGE_HEADER *rslt,
+				       int sleep_ok, int timeout_ms);
+int		mpt_read_extcfg_page(struct mpt_softc *mpt, int Action,
+				     uint32_t PageAddress,
+				     CONFIG_EXTENDED_PAGE_HEADER *hdr,
+				     void *buf, size_t len, int sleep_ok,
+				     int timeout_ms);
 int		mpt_read_cfg_header(struct mpt_softc *, int /*PageType*/,
 				    int /*PageNumber*/,
 				    uint32_t /*PageAddress*/,
@@ -1176,7 +1270,6 @@
 				   PageAddress, hdr, len, sleep_ok,
 				   timeout_ms));
 }
-
 /* mpt_debug.c functions */
 void mpt_print_reply(void *vmsg);
 void mpt_print_db(uint32_t mb);
Index: mpt_raid.c
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpt_raid.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpt_raid.c -L sys/dev/mpt/mpt_raid.c -u -r1.2 -r1.3
--- sys/dev/mpt/mpt_raid.c
+++ sys/dev/mpt/mpt_raid.c
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt_raid.c,v 1.1.2.3 2006/09/16 05:42:06 mjacob Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt_raid.c,v 1.15 2007/05/05 20:18:24 mjacob Exp $");
 
 #include <dev/mpt/mpt.h>
 #include <dev/mpt/mpt_raid.h>
@@ -116,12 +116,14 @@
 static void mpt_enable_vol(struct mpt_softc *mpt,
 			   struct mpt_raid_volume *mpt_vol, int enable);
 #endif
-static void mpt_verify_mwce(struct mpt_softc *mpt,
-			    struct mpt_raid_volume *mpt_vol);
-static void mpt_adjust_queue_depth(struct mpt_softc *mpt,
-				   struct mpt_raid_volume *mpt_vol,
-				   struct cam_path *path);
-static void mpt_raid_sysctl_attach(struct mpt_softc *mpt);
+static void mpt_verify_mwce(struct mpt_softc *, struct mpt_raid_volume *);
+static void mpt_adjust_queue_depth(struct mpt_softc *, struct mpt_raid_volume *,
+    struct cam_path *);
+#if __FreeBSD_version < 500000
+#define	mpt_raid_sysctl_attach(x)	do { } while (0)
+#else
+static void mpt_raid_sysctl_attach(struct mpt_softc *);
+#endif
 
 static uint32_t raid_handler_id = MPT_HANDLER_ID_NONE;
 
@@ -270,6 +272,13 @@
 
 	mpt_callout_init(&mpt->raid_timer);
 
+	error = mpt_spawn_raid_thread(mpt);
+	if (error != 0) {
+		mpt_prt(mpt, "Unable to spawn RAID thread!\n");
+		goto cleanup;
+	}
+ 
+	MPT_LOCK(mpt);
 	handler.reply_handler = mpt_raid_reply_handler;
 	error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
 				     &raid_handler_id);
@@ -278,28 +287,22 @@
 		goto cleanup;
 	}
 
-	error = mpt_spawn_raid_thread(mpt);
-	if (error != 0) {
-		mpt_prt(mpt, "Unable to spawn RAID thread!\n");
-		goto cleanup;
-	}
- 
 	xpt_setup_ccb(&csa.ccb_h, mpt->path, 5);
 	csa.ccb_h.func_code = XPT_SASYNC_CB;
 	csa.event_enable = AC_FOUND_DEVICE;
 	csa.callback = mpt_raid_async;
 	csa.callback_arg = mpt;
-	MPTLOCK_2_CAMLOCK(mpt);
 	xpt_action((union ccb *)&csa);
-	CAMLOCK_2_MPTLOCK(mpt);
 	if (csa.ccb_h.status != CAM_REQ_CMP) {
 		mpt_prt(mpt, "mpt_raid_attach: Unable to register "
 			"CAM async handler.\n");
 	}
+	MPT_UNLOCK(mpt);
 
 	mpt_raid_sysctl_attach(mpt);
 	return (0);
 cleanup:
+	MPT_UNLOCK(mpt);
 	mpt_raid_detach(mpt);
 	return (error);
 }
@@ -317,6 +320,7 @@
 	mpt_handler_t handler;
 
 	callout_stop(&mpt->raid_timer);
+	MPT_LOCK(mpt);
 	mpt_terminate_raid_thread(mpt); 
 
 	handler.reply_handler = mpt_raid_reply_handler;
@@ -327,9 +331,8 @@
 	csa.event_enable = 0;
 	csa.callback = mpt_raid_async;
 	csa.callback_arg = mpt;
-	MPTLOCK_2_CAMLOCK(mpt);
 	xpt_action((union ccb *)&csa);
-	CAMLOCK_2_MPTLOCK(mpt);
+	MPT_UNLOCK(mpt);
 }
 
 static void
@@ -620,12 +623,17 @@
 	 * reject I/O to an ID we later determine is for a
 	 * hidden physdisk.
 	 */
+	MPT_LOCK(mpt);
 	xpt_freeze_simq(mpt->phydisk_sim, 1);
+	MPT_UNLOCK(mpt);
 	error = mpt_kthread_create(mpt_raid_thread, mpt,
 	    &mpt->raid_thread, /*flags*/0, /*altstack*/0,
 	    "mpt_raid%d", mpt->unit);
-	if (error != 0)
+	if (error != 0) {
+		MPT_LOCK(mpt);
 		xpt_release_simq(mpt->phydisk_sim, /*run_queue*/FALSE);
+		MPT_UNLOCK(mpt);
+	}
 	return (error);
 }
 
@@ -658,9 +666,6 @@
 	struct mpt_softc *mpt;
 	int firstrun;
 
-#if __FreeBSD_version >= 500000
-	mtx_lock(&Giant);
-#endif
 	mpt = (struct mpt_softc *)arg;
 	firstrun = 1;
 	MPT_LOCK(mpt);
@@ -717,9 +722,6 @@
 	mpt->raid_thread = NULL;
 	wakeup(&mpt->raid_thread);
 	MPT_UNLOCK(mpt);
-#if __FreeBSD_version >= 500000
-	mtx_unlock(&Giant);
-#endif
 	kthread_exit(0);
 }
 
@@ -756,8 +758,7 @@
 		if (rv != 0)
 			return (CAM_REQ_CMP_ERR);
 
-		ccb->ccb_h.timeout_ch =
-			timeout(mpt_raid_quiesce_timeout, (caddr_t)ccb, 5 * hz);
+		mpt_req_timeout(req, mpt_raid_quiesce_timeout, ccb, 5 * hz);
 #if 0
 		if (rv == ETIMEDOUT) {
 			mpt_disk_prt(mpt, mpt_disk, "mpt_raid_quiesce_disk: "
@@ -792,7 +793,6 @@
 	mpt_disk = mpt->raid_disks + ccb->ccb_h.target_id;
 	if (ccb->ccb_h.target_id < mpt->raid_max_disks
 	 && (mpt_disk->flags & MPT_RDF_ACTIVE) != 0) {
-
 		*tgt = mpt_disk->config_page.PhysDiskID;
 		return (0);
 	}
@@ -808,6 +808,9 @@
 	CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol;
 	CONFIG_PAGE_IOC_2_RAID_VOL *ioc_last_vol;
 
+	if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0) {
+		return (0);
+	}
 	ioc_vol = mpt->ioc_page2->RaidVolume;
 	ioc_last_vol = ioc_vol + mpt->ioc_page2->NumActiveVolumes;
 	for (;ioc_vol != ioc_last_vol; ioc_vol++) {
@@ -1106,20 +1109,66 @@
 	for (i = 0; i < vol_pg->NumPhysDisks; i++){
 		struct mpt_raid_disk *mpt_disk;
 		CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
+		int pt_bus = cam_sim_bus(mpt->phydisk_sim);
+		U8 f, s;
 
-		mpt_disk = mpt->raid_disks 
-			 + vol_pg->PhysDisk[i].PhysDiskNum;
+		mpt_disk = mpt->raid_disks + vol_pg->PhysDisk[i].PhysDiskNum;
 		disk_pg = &mpt_disk->config_page;
 		mpt_prtc(mpt, "      ");
-		mpt_prtc(mpt, "(%s:%d:%d): ", device_get_nameunit(mpt->dev),
-			 disk_pg->PhysDiskBus, disk_pg->PhysDiskID);
-		if (vol_pg->VolumeType == MPI_RAID_VOL_TYPE_IM)
-			mpt_prtc(mpt, "%s\n",
-				 mpt_disk->member_number == 0
-			       ? "Primary" : "Secondary");
-		else
-			mpt_prtc(mpt, "Stripe Position %d\n",
+		mpt_prtc(mpt, "(%s:%d:%d:0): ", device_get_nameunit(mpt->dev),
+			 pt_bus, disk_pg->PhysDiskID);
+		if (vol_pg->VolumeType == MPI_RAID_VOL_TYPE_IM) {
+			mpt_prtc(mpt, "%s", mpt_disk->member_number == 0?
+			    "Primary" : "Secondary");
+		} else {
+			mpt_prtc(mpt, "Stripe Position %d",
 				 mpt_disk->member_number);
+		}
+		f = disk_pg->PhysDiskStatus.Flags;
+		s = disk_pg->PhysDiskStatus.State;
+		if (f & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC) {
+			mpt_prtc(mpt, " Out of Sync");
+		}
+		if (f & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED) {
+			mpt_prtc(mpt, " Quiesced");
+		}
+		if (f & MPI_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME) {
+			mpt_prtc(mpt, " Inactive");
+		}
+		if (f & MPI_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS) {
+			mpt_prtc(mpt, " Was Optimal");
+		}
+		if (f & MPI_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS) {
+			mpt_prtc(mpt, " Was Non-Optimal");
+		}
+		switch (s) {
+		case MPI_PHYSDISK0_STATUS_ONLINE:
+			mpt_prtc(mpt, " Online");
+			break;
+		case MPI_PHYSDISK0_STATUS_MISSING:
+			mpt_prtc(mpt, " Missing");
+			break;
+		case MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE:
+			mpt_prtc(mpt, " Incompatible");
+			break;
+		case MPI_PHYSDISK0_STATUS_FAILED:
+			mpt_prtc(mpt, " Failed");
+			break;
+		case MPI_PHYSDISK0_STATUS_INITIALIZING:
+			mpt_prtc(mpt, " Initializing");
+			break;
+		case MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED:
+			mpt_prtc(mpt, " Requested Offline");
+			break;
+		case MPI_PHYSDISK0_STATUS_FAILED_REQUESTED:
+			mpt_prtc(mpt, " Requested Failed");
+			break;
+		case MPI_PHYSDISK0_STATUS_OTHER_OFFLINE:
+		default:
+			mpt_prtc(mpt, " Offline Other (%x)", s);
+			break;
+		}
+		mpt_prtc(mpt, "\n");
 	}
 }
 
@@ -1127,15 +1176,16 @@
 mpt_announce_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk)
 {
 	CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
+	int rd_bus = cam_sim_bus(mpt->sim);
+	int pt_bus = cam_sim_bus(mpt->phydisk_sim);
 	u_int i;
 
 	disk_pg = &mpt_disk->config_page;
 	mpt_disk_prt(mpt, mpt_disk,
-		     "Physical (%s:%d:%d), Pass-thru (%s:%d:%d)\n",
-		     device_get_nameunit(mpt->dev), disk_pg->PhysDiskBus, 
+		     "Physical (%s:%d:%d:0), Pass-thru (%s:%d:%d:0)\n",
+		     device_get_nameunit(mpt->dev), rd_bus,
 		     disk_pg->PhysDiskID, device_get_nameunit(mpt->dev),
-		     /*bus*/1, mpt_disk - mpt->raid_disks);
-
+		     pt_bus, mpt_disk - mpt->raid_disks);
 	if (disk_pg->PhysDiskSettings.HotSparePool == 0)
 		return;
 	mpt_disk_prt(mpt, mpt_disk, "Member of Hot Spare Pool%s",
@@ -1180,7 +1230,7 @@
 
 static void
 mpt_refresh_raid_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol,
-		     CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol)
+    CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol)
 {
 	CONFIG_PAGE_RAID_VOL_0 *vol_pg;
 	struct mpt_raid_action_result *ar;
@@ -1190,55 +1240,55 @@
 
 	vol_pg = mpt_vol->config_page;
 	mpt_vol->flags &= ~MPT_RVF_UP2DATE;
-	rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_RAID_VOLUME,
-				 /*PageNumber*/0, ioc_vol->VolumePageNumber,
-				 &vol_pg->Header, /*sleep_ok*/TRUE,
-				 /*timeout_ms*/5000);
+
+	rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_RAID_VOLUME, 0,
+	    ioc_vol->VolumePageNumber, &vol_pg->Header, TRUE, 5000);
 	if (rv != 0) {
-		mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: "
-			    "Failed to read RAID Vol Hdr(%d)\n",
-			    ioc_vol->VolumePageNumber);
+		mpt_vol_prt(mpt, mpt_vol,
+		    "mpt_refresh_raid_vol: Failed to read RAID Vol Hdr(%d)\n",
+		    ioc_vol->VolumePageNumber);
 		return;
 	}
+
 	rv = mpt_read_cur_cfg_page(mpt, ioc_vol->VolumePageNumber,
-				   &vol_pg->Header, mpt->raid_page0_len,
-				   /*sleep_ok*/TRUE, /*timeout_ms*/5000);
+	    &vol_pg->Header, mpt->raid_page0_len, TRUE, 5000);
 	if (rv != 0) {
-		mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: "
-			    "Failed to read RAID Vol Page(%d)\n",
-			    ioc_vol->VolumePageNumber);
+		mpt_vol_prt(mpt, mpt_vol,
+		    "mpt_refresh_raid_vol: Failed to read RAID Vol Page(%d)\n",
+		    ioc_vol->VolumePageNumber);
 		return;
 	}
+	mpt2host_config_page_raid_vol_0(vol_pg);
+
 	mpt_vol->flags |= MPT_RVF_ACTIVE;
 
 	/* Update disk entry array data. */
 	for (i = 0; i < vol_pg->NumPhysDisks; i++) {
 		struct mpt_raid_disk *mpt_disk;
-
 		mpt_disk = mpt->raid_disks + vol_pg->PhysDisk[i].PhysDiskNum;
 		mpt_disk->volume = mpt_vol;
 		mpt_disk->member_number = vol_pg->PhysDisk[i].PhysDiskMap;
-		if (vol_pg->VolumeType == MPI_RAID_VOL_TYPE_IM)
+		if (vol_pg->VolumeType == MPI_RAID_VOL_TYPE_IM) {
 			mpt_disk->member_number--;
+		}
 	}
 
 	if ((vol_pg->VolumeStatus.Flags
 	   & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) == 0)
 		return;
 
-	req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
+	req = mpt_get_request(mpt, TRUE);
 	if (req == NULL) {
 		mpt_vol_prt(mpt, mpt_vol,
-			    "mpt_refresh_raid_vol: Get request failed!\n");
+		    "mpt_refresh_raid_vol: Get request failed!\n");
 		return;
 	}
-	rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
-				MPI_RAID_ACTION_INDICATOR_STRUCT,
-				/*ActionWord*/0, /*addr*/0, /*len*/0,
-				/*write*/FALSE, /*wait*/TRUE);
+	rv = mpt_issue_raid_req(mpt, mpt_vol, NULL, req,
+	    MPI_RAID_ACTION_INDICATOR_STRUCT, 0, 0, 0, FALSE, TRUE);
 	if (rv == ETIMEDOUT) {
-		mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: "
-			    "Progress indicator fetch timedout!\n");
+		mpt_vol_prt(mpt, mpt_vol,
+		    "mpt_refresh_raid_vol: Progress Indicator fetch timeout\n");
+		mpt_free_request(mpt, req);
 		return;
 	}
 
@@ -1249,9 +1299,10 @@
 		memcpy(&mpt_vol->sync_progress,
 		       &ar->action_data.indicator_struct,
 		       sizeof(mpt_vol->sync_progress));
+		mpt2host_mpi_raid_vol_indicator(&mpt_vol->sync_progress);
 	} else {
-		mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: "
-			    "Progress indicator fetch failed!\n");
+		mpt_vol_prt(mpt, mpt_vol,
+		    "mpt_refresh_raid_vol: Progress indicator fetch failed!\n");
 	}
 	mpt_free_request(mpt, req);
 }
@@ -1364,8 +1415,9 @@
 
 		mpt_vol = &mpt->raid_volumes[i];
 
-		if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
+		if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0) {
 			continue;
+		}
 
 		vol_pg = mpt_vol->config_page;
 		if ((mpt_vol->flags & (MPT_RVF_REFERENCED|MPT_RVF_ANNOUNCED))
@@ -1376,7 +1428,6 @@
 		}
 
 		if ((mpt_vol->flags & MPT_RVF_ANNOUNCED) == 0) {
-
 			mpt_announce_vol(mpt, mpt_vol);
 			mpt_vol->flags |= MPT_RVF_ANNOUNCED;
 		}
@@ -1390,11 +1441,12 @@
 
 		mpt_vol->flags |= MPT_RVF_UP2DATE;
 		mpt_vol_prt(mpt, mpt_vol, "%s - %s\n",
-			    mpt_vol_type(mpt_vol), mpt_vol_state(mpt_vol));
+		    mpt_vol_type(mpt_vol), mpt_vol_state(mpt_vol));
 		mpt_verify_mwce(mpt, mpt_vol);
 
-		if (vol_pg->VolumeStatus.Flags == 0)
+		if (vol_pg->VolumeStatus.Flags == 0) {
 			continue;
+		}
 
 		mpt_vol_prt(mpt, mpt_vol, "Status (");
 		for (m = 1; m <= 0x80; m <<= 1) {
@@ -1423,8 +1475,8 @@
 
 		mpt_verify_resync_rate(mpt, mpt_vol);
 
-		left = u64toh(mpt_vol->sync_progress.BlocksRemaining);
-		total = u64toh(mpt_vol->sync_progress.TotalBlocks);
+		left = MPT_U64_2_SCALAR(mpt_vol->sync_progress.BlocksRemaining);
+		total = MPT_U64_2_SCALAR(mpt_vol->sync_progress.TotalBlocks);
 		if (vol_pg->ResyncRate != 0) {
 
 			prio = ((u_int)vol_pg->ResyncRate * 100000) / 0xFF;
@@ -1554,6 +1606,7 @@
 	mpt->raid_max_disks =  0;
 }
 
+#if __FreeBSD_version >= 500000
 static int
 mpt_raid_set_vol_resync_rate(struct mpt_softc *mpt, u_int rate)
 {
@@ -1595,16 +1648,19 @@
 
 		mpt->raid_rescan = 0;
 
+		MPTLOCK_2_CAMLOCK(mpt);
 		error = xpt_create_path(&path, xpt_periph,
 					cam_sim_path(mpt->sim),
 					mpt_vol->config_page->VolumeID,
 					/*lun*/0);
 		if (error != CAM_REQ_CMP) {
+			CAMLOCK_2_MPTLOCK(mpt);
 			mpt_vol_prt(mpt, mpt_vol, "Unable to allocate path!\n");
 			continue;
 		}
 		mpt_adjust_queue_depth(mpt, mpt_vol, path);
 		xpt_free_path(path);
+		CAMLOCK_2_MPTLOCK(mpt);
 	}
 	MPT_UNLOCK(mpt);
 	return (0);
@@ -1664,7 +1720,6 @@
 	MPT_UNLOCK(mpt);
 	return (0);
 }
-
 const char *mpt_vol_mwce_strs[] =
 {
 	"On",
@@ -1753,7 +1808,6 @@
 static void
 mpt_raid_sysctl_attach(struct mpt_softc *mpt)
 {
-#if __FreeBSD_version >= 500000
 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(mpt->dev);
 	struct sysctl_oid *tree = device_get_sysctl_tree(mpt->dev);
 
@@ -1775,5 +1829,5 @@
 			"nonoptimal_volumes", CTLFLAG_RD,
 			&mpt->raid_nonopt_volumes, 0,
 			"number of nonoptimal volumes");
-#endif
 }
+#endif
Index: mpt_debug.c
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpt_debug.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpt_debug.c -L sys/dev/mpt/mpt_debug.c -u -r1.2 -r1.3
--- sys/dev/mpt/mpt_debug.c
+++ sys/dev/mpt/mpt_debug.c
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt_debug.c,v 1.8.2.2 2006/09/16 05:42:06 mjacob Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt_debug.c,v 1.18 2006/12/07 22:02:28 mjacob Exp $");
 
 #include <dev/mpt/mpt.h>
 
@@ -819,7 +819,7 @@
 mpt_dump_request(struct mpt_softc *mpt, request_t *req)
 {
         uint32_t *pReq = req->req_vbuf;
-	int offset;
+	int o;
 #if __FreeBSD_version >= 500000
 	mpt_prt(mpt, "Send Request %d (%jx):",
 	    req->index, (uintmax_t) req->req_pbuf);
@@ -827,12 +827,12 @@
 	mpt_prt(mpt, "Send Request %d (%llx):",
 	    req->index, (unsigned long long) req->req_pbuf);
 #endif
-	for (offset = 0; offset < mpt->request_frame_size; offset++) {
-		if ((offset & 0x7) == 0) {
+	for (o = 0; o < mpt->ioc_facts.RequestFrameSize; o++) {
+		if ((o & 0x7) == 0) {
 			mpt_prtc(mpt, "\n");
 			mpt_prt(mpt, " ");
 		}
-		mpt_prtc(mpt, " %08x", pReq[offset]);
+		mpt_prtc(mpt, " %08x", pReq[o]);
 	}
 	mpt_prtc(mpt, "\n");
 }
Index: mpt_reg.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpt_reg.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpt_reg.h -L sys/dev/mpt/mpt_reg.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpt_reg.h
+++ sys/dev/mpt/mpt_reg.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpt_reg.h,v 1.1.2.2 2006/09/16 05:42:06 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpt_reg.h,v 1.4 2006/05/29 20:34:28 mjacob Exp $ */
 /*-
  * Generic defines for LSI '909 FC  adapters.
  * FreeBSD Version.
Index: mpt_raid.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpt_raid.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpt_raid.h -L sys/dev/mpt/mpt_raid.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpt_raid.h
+++ sys/dev/mpt/mpt_raid.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpt_raid.h,v 1.1.2.3 2006/09/16 05:42:06 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpt_raid.h,v 1.7 2006/07/16 03:31:01 mjacob Exp $ */
 /*-
  * Definitions for the integrated RAID features LSI MPT Fusion adapters.
  *
Index: mpt.c
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpt.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpt.c -L sys/dev/mpt/mpt.c -u -r1.2 -r1.3
--- sys/dev/mpt/mpt.c
+++ sys/dev/mpt/mpt.c
@@ -96,7 +96,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt.c,v 1.12.2.4 2006/09/16 05:42:06 mjacob Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt.c,v 1.44.2.2 2007/12/15 18:39:07 delphij Exp $");
 
 #include <dev/mpt/mpt.h>
 #include <dev/mpt/mpt_cam.h> /* XXX For static handler registration */
@@ -128,7 +128,7 @@
 static int mpt_send_event_request(struct mpt_softc *mpt, int onoff);
 static int mpt_soft_reset(struct mpt_softc *mpt);
 static void mpt_hard_reset(struct mpt_softc *mpt);
-static int mpt_configure_ioc(struct mpt_softc *mpt);
+static int mpt_configure_ioc(struct mpt_softc *mpt, int, int);
 static int mpt_enable_ioc(struct mpt_softc *mpt, int);
 
 /************************* Personality Module Support *************************/
@@ -503,6 +503,8 @@
 			req->IOCStatus = le16toh(reply_frame->IOCStatus);
 			bcopy(&reply->Header, &cfgp->Header,
 			      sizeof(cfgp->Header));
+			cfgp->ExtPageLength = reply->ExtPageLength;
+			cfgp->ExtPageType = reply->ExtPageType;
 		}
 		req->state &= ~REQ_STATE_QUEUED;
 		req->state |= REQ_STATE_DONE;
@@ -547,6 +549,10 @@
 
 		handled = 0;
 		msg = (MSG_EVENT_NOTIFY_REPLY *)reply_frame;
+		msg->EventDataLength = le16toh(msg->EventDataLength);
+		msg->IOCStatus = le16toh(msg->IOCStatus);
+		msg->IOCLogInfo = le32toh(msg->IOCLogInfo);
+		msg->Event = le32toh(msg->Event);
 		MPT_PERS_FOREACH(mpt, pers)
 			handled += pers->event(mpt, req, msg);
 
@@ -556,7 +562,8 @@
 				"Event %#x (ACK %sequired).\n",
 				msg->Event, msg->AckRequired? "r" : "not r");
 		} else if (handled == 0) {
-			mpt_lprt(mpt, MPT_PRT_WARN,
+			mpt_lprt(mpt,
+				msg->AckRequired? MPT_PRT_WARN : MPT_PRT_INFO,
 				"Unhandled Event Notify Frame. Event %#x "
 				"(ACK %sequired).\n",
 				msg->Event, msg->AckRequired? "r" : "not r");
@@ -566,7 +573,7 @@
 			request_t *ack_req;
 			uint32_t context;
 
-			context = htole32(req->index|MPT_REPLY_HANDLER_EVENTS);
+			context = req->index | MPT_REPLY_HANDLER_EVENTS;
 			ack_req = mpt_get_request(mpt, FALSE);
 			if (ack_req == NULL) {
 				struct mpt_evtf_record *evtf;
@@ -683,9 +690,9 @@
 	ackp = (MSG_EVENT_ACK *)ack_req->req_vbuf;
 	memset(ackp, 0, sizeof (*ackp));
 	ackp->Function = MPI_FUNCTION_EVENT_ACK;
-	ackp->Event = msg->Event;
-	ackp->EventContext = msg->EventContext;
-	ackp->MsgContext = context;
+	ackp->Event = htole32(msg->Event);
+	ackp->EventContext = htole32(msg->EventContext);
+	ackp->MsgContext = htole32(context);
 	mpt_check_doorbell(mpt);
 	mpt_send_cmd(mpt, ack_req);
 }
@@ -700,6 +707,8 @@
 
 	mpt = (struct mpt_softc *)arg;
 	mpt_lprt(mpt, MPT_PRT_DEBUG2, "enter mpt_intr\n");
+	MPT_LOCK_ASSERT(mpt);
+
 	while ((reply_desc = mpt_pop_reply_queue(mpt)) != MPT_REPLY_EMPTY) {
 		request_t	  *req;
 		MSG_DEFAULT_REPLY *reply_frame;
@@ -890,7 +899,7 @@
 mpt_wait_db_int(struct mpt_softc *mpt)
 {
 	int i;
-	for (i=0; i < MPT_MAX_WAIT; i++) {
+	for (i = 0; i < MPT_MAX_WAIT; i++) {
 		if (MPT_DB_INTR(mpt_rd_intr(mpt))) {
 			maxwait_int = i > maxwait_int ? i : maxwait_int;
 			return MPT_OK;
@@ -1167,7 +1176,7 @@
 	}
 	KASSERT(req->state != REQ_STATE_FREE, ("freeing free request"));
 	KASSERT(!(req->state & REQ_STATE_LOCKED), ("freeing locked request"));
-	KASSERT(MPT_OWNED(mpt), ("mpt_free_request: mpt not locked\n"));
+	MPT_LOCK_ASSERT(mpt);
 	KASSERT(mpt_req_on_free_list(mpt, req) == 0,
 	    ("mpt_free_request: req %p:%u func %x already on freelist",
 	    req, req->serno, ((MSG_REQUEST_HEADER *)req->req_vbuf)->Function));
@@ -1216,7 +1225,7 @@
 	request_t *req;
 
 retry:
-	KASSERT(MPT_OWNED(mpt), ("mpt_get_request: mpt not locked\n"));
+	MPT_LOCK_ASSERT(mpt);
 	req = TAILQ_FIRST(&mpt->request_free_list);
 	if (req != NULL) {
 		KASSERT(req == &mpt->request_pool[req->index],
@@ -1229,6 +1238,7 @@
 		req->state = REQ_STATE_ALLOCATED;
 		req->chain = NULL;
 		mpt_assign_serno(mpt, req);
+		mpt_callout_init(&req->callout);
 	} else if (sleep_ok != 0) {
 		mpt->getreqwaiter = 1;
 		mpt_sleep(mpt, &mpt->request_free_list, PUSER, "mptgreq", 0);
@@ -1347,7 +1357,7 @@
 	len = (len + 3) >> 2;
 	data32 = cmd;
 
-	/* Clear any left over pending doorbell interupts */
+	/* Clear any left over pending doorbell interrupts */
 	if (MPT_DB_INTR(mpt_rd_intr(mpt)))
 		mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
 
@@ -1361,7 +1371,7 @@
 
 	/* Wait for the chip to notice */
 	if (mpt_wait_db_int(mpt) != MPT_OK) {
-		mpt_prt(mpt, "mpt_send_handshake_cmd timeout1\n");
+		mpt_prt(mpt, "mpt_send_handshake_cmd: db ignored\n");
 		return (ETIMEDOUT);
 	}
 
@@ -1369,17 +1379,16 @@
 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
 
 	if (mpt_wait_db_ack(mpt) != MPT_OK) {
-		mpt_prt(mpt, "mpt_send_handshake_cmd timeout2\n");
+		mpt_prt(mpt, "mpt_send_handshake_cmd: db ack timed out\n");
 		return (ETIMEDOUT);
 	}
 
 	/* Send the command */
 	for (i = 0; i < len; i++) {
-		mpt_write(mpt, MPT_OFFSET_DOORBELL, *data32++);
+		mpt_write(mpt, MPT_OFFSET_DOORBELL, htole32(*data32++));
 		if (mpt_wait_db_ack(mpt) != MPT_OK) {
 			mpt_prt(mpt,
-				"mpt_send_handshake_cmd timeout! index = %d\n",
-				i);
+			    "mpt_send_handshake_cmd: timeout @ index %d\n", i);
 			return (ETIMEDOUT);
 		}
 	}
@@ -1392,6 +1401,7 @@
 {
 	int left, reply_left;
 	u_int16_t *data16;
+	uint32_t data;
 	MSG_DEFAULT_REPLY *hdr;
 
 	/* We move things out in 16 bit chunks */
@@ -1405,7 +1415,8 @@
 		mpt_prt(mpt, "mpt_recv_handshake_cmd timeout1\n");
 		return ETIMEDOUT;
 	}
-	*data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
+	data = mpt_read(mpt, MPT_OFFSET_DOORBELL);
+	*data16++ = le16toh(data & MPT_DB_DATA_MASK);
 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
 
 	/* Get Second Word */
@@ -1413,7 +1424,8 @@
 		mpt_prt(mpt, "mpt_recv_handshake_cmd timeout2\n");
 		return ETIMEDOUT;
 	}
-	*data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
+	data = mpt_read(mpt, MPT_OFFSET_DOORBELL);
+	*data16++ = le16toh(data & MPT_DB_DATA_MASK);
 	mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
 
 	/*
@@ -1443,10 +1455,11 @@
 			mpt_prt(mpt, "mpt_recv_handshake_cmd timeout3\n");
 			return ETIMEDOUT;
 		}
-		datum = mpt_read(mpt, MPT_OFFSET_DOORBELL);
+		data = mpt_read(mpt, MPT_OFFSET_DOORBELL);
+		datum = le16toh(data & MPT_DB_DATA_MASK);
 
 		if (reply_left-- > 0)
-			*data16++ = datum & MPT_DB_DATA_MASK;
+			*data16++ = datum;
 
 		mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
 	}
@@ -1477,25 +1490,27 @@
 	f_req.Function = MPI_FUNCTION_IOC_FACTS;
 	f_req.MsgContext = htole32(MPT_REPLY_HANDLER_HANDSHAKE);
 	error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
-	if (error)
+	if (error) {
 		return(error);
+	}
 	error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
 	return (error);
 }
 
 static int
-mpt_get_portfacts(struct mpt_softc *mpt, MSG_PORT_FACTS_REPLY *freplp)
+mpt_get_portfacts(struct mpt_softc *mpt, U8 port, MSG_PORT_FACTS_REPLY *freplp)
 {
 	MSG_PORT_FACTS f_req;
 	int error;
 	
-	/* XXX: Only getting PORT FACTS for Port 0 */
 	memset(&f_req, 0, sizeof f_req);
 	f_req.Function = MPI_FUNCTION_PORT_FACTS;
+	f_req.PortNumber = port;
 	f_req.MsgContext = htole32(MPT_REPLY_HANDLER_HANDSHAKE);
 	error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
-	if (error)
+	if (error) {
 		return(error);
+	}
 	error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
 	return (error);
 }
@@ -1516,8 +1531,8 @@
 	memset(&init, 0, sizeof init);
 	init.WhoInit = who;
 	init.Function = MPI_FUNCTION_IOC_INIT;
-	init.MaxDevices = mpt->mpt_max_devices;
-	init.MaxBuses = 1;
+	init.MaxDevices = 0;	/* at least 256 devices per bus */
+	init.MaxBuses = 16;	/* at least 16 busses */
 
 	init.MsgVersion = htole16(MPI_VERSION);
 	init.HeaderVersion = htole16(MPI_HEADER_VERSION);
@@ -1537,32 +1552,39 @@
  * Utiltity routine to read configuration headers and pages
  */
 int
-mpt_issue_cfg_req(struct mpt_softc *mpt, request_t *req, u_int Action,
-		  u_int PageVersion, u_int PageLength, u_int PageNumber,
-		  u_int PageType, uint32_t PageAddress, bus_addr_t addr,
-		  bus_size_t len, int sleep_ok, int timeout_ms)
+mpt_issue_cfg_req(struct mpt_softc *mpt, request_t *req, cfgparms_t *params,
+		  bus_addr_t addr, bus_size_t len, int sleep_ok, int timeout_ms)
 {
 	MSG_CONFIG *cfgp;
 	SGE_SIMPLE32 *se;
 
 	cfgp = req->req_vbuf;
 	memset(cfgp, 0, sizeof *cfgp);
-	cfgp->Action = Action;
+	cfgp->Action = params->Action;
 	cfgp->Function = MPI_FUNCTION_CONFIG;
-	cfgp->Header.PageVersion = PageVersion;
-	cfgp->Header.PageLength = PageLength;
-	cfgp->Header.PageNumber = PageNumber;
-	cfgp->Header.PageType = PageType;
-	cfgp->PageAddress = PageAddress;
+	cfgp->Header.PageVersion = params->PageVersion;
+	cfgp->Header.PageNumber = params->PageNumber;
+	cfgp->PageAddress = htole32(params->PageAddress);
+	if ((params->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
+	    MPI_CONFIG_PAGETYPE_EXTENDED) {
+		cfgp->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+		cfgp->Header.PageLength = 0;
+		cfgp->ExtPageLength = htole16(params->ExtPageLength);
+		cfgp->ExtPageType = params->ExtPageType;
+	} else {
+		cfgp->Header.PageType = params->PageType;
+		cfgp->Header.PageLength = params->PageLength;
+	}
 	se = (SGE_SIMPLE32 *)&cfgp->PageBufferSGE;
-	se->Address = addr;
+	se->Address = htole32(addr);
 	MPI_pSGE_SET_LENGTH(se, len);
 	MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
 	    MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
 	    MPI_SGE_FLAGS_END_OF_LIST |
-	    ((Action == MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
-	  || Action == MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM)
+	    ((params->Action == MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
+	  || params->Action == MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM)
 	   ? MPI_SGE_FLAGS_HOST_TO_IOC : MPI_SGE_FLAGS_IOC_TO_HOST)));
+	se->FlagsLength = htole32(se->FlagsLength);
 	cfgp->MsgContext = htole32(req->index | MPT_REPLY_HANDLER_CONFIG);
 
 	mpt_check_doorbell(mpt);
@@ -1571,6 +1593,113 @@
 			     sleep_ok, timeout_ms));
 }
 
+int
+mpt_read_extcfg_header(struct mpt_softc *mpt, int PageVersion, int PageNumber,
+		       uint32_t PageAddress, int ExtPageType,
+		       CONFIG_EXTENDED_PAGE_HEADER *rslt,
+		       int sleep_ok, int timeout_ms)
+{
+	request_t  *req;
+	cfgparms_t params;
+	MSG_CONFIG_REPLY *cfgp;
+	int	    error;
+
+	req = mpt_get_request(mpt, sleep_ok);
+	if (req == NULL) {
+		mpt_prt(mpt, "mpt_extread_cfg_header: Get request failed!\n");
+		return (ENOMEM);
+	}
+
+	params.Action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	params.PageVersion = PageVersion;
+	params.PageLength = 0;
+	params.PageNumber = PageNumber;
+	params.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+	params.PageAddress = PageAddress;
+	params.ExtPageType = ExtPageType;
+	params.ExtPageLength = 0;
+	error = mpt_issue_cfg_req(mpt, req, &params, /*addr*/0, /*len*/0,
+				  sleep_ok, timeout_ms);
+	if (error != 0) {
+		/*
+		 * Leave the request. Without resetting the chip, it's
+		 * still owned by it and we'll just get into trouble
+		 * freeing it now. Mark it as abandoned so that if it
+		 * shows up later it can be freed.
+		 */
+		mpt_prt(mpt, "read_extcfg_header timed out\n");
+		return (ETIMEDOUT);
+	}
+
+        switch (req->IOCStatus & MPI_IOCSTATUS_MASK) {
+	case MPI_IOCSTATUS_SUCCESS:
+		cfgp = req->req_vbuf;
+		rslt->PageVersion = cfgp->Header.PageVersion;
+		rslt->PageNumber = cfgp->Header.PageNumber;
+		rslt->PageType = cfgp->Header.PageType;
+		rslt->ExtPageLength = cfgp->ExtPageLength;
+		rslt->ExtPageType = cfgp->ExtPageType;
+		error = 0;
+		break;
+	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:
+		mpt_lprt(mpt, MPT_PRT_DEBUG,
+		    "Invalid Page Type %d Number %d Addr 0x%0x\n",
+		    MPI_CONFIG_PAGETYPE_EXTENDED, PageNumber, PageAddress);
+		error = EINVAL;
+		break;
+	default:
+		mpt_prt(mpt, "mpt_read_extcfg_header: Config Info Status %x\n",
+			req->IOCStatus);
+		error = EIO;
+		break;
+	}
+	mpt_free_request(mpt, req);
+	return (error);
+}
+
+int
+mpt_read_extcfg_page(struct mpt_softc *mpt, int Action, uint32_t PageAddress,
+		     CONFIG_EXTENDED_PAGE_HEADER *hdr, void *buf, size_t len,
+		     int sleep_ok, int timeout_ms)
+{
+	request_t    *req;
+	cfgparms_t    params;
+	int	      error;
+
+	req = mpt_get_request(mpt, sleep_ok);
+	if (req == NULL) {
+		mpt_prt(mpt, "mpt_read_cfg_page: Get request failed!\n");
+		return (-1);
+	}
+
+	params.Action = Action;
+	params.PageVersion = hdr->PageVersion;
+	params.PageLength = 0;
+	params.PageNumber = hdr->PageNumber;
+	params.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+	params.PageAddress = PageAddress;
+	params.ExtPageType = hdr->ExtPageType;
+	params.ExtPageLength = hdr->ExtPageLength;
+	error = mpt_issue_cfg_req(mpt, req, &params,
+				  req->req_pbuf + MPT_RQSL(mpt),
+				  len, sleep_ok, timeout_ms);
+	if (error != 0) {
+		mpt_prt(mpt, "read_extcfg_page(%d) timed out\n", Action);
+		return (-1);
+	}
+
+	if ((req->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
+		mpt_prt(mpt, "mpt_read_extcfg_page: Config Info Status %x\n",
+			req->IOCStatus);
+		mpt_free_request(mpt, req);
+		return (-1);
+	}
+	bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
+	    BUS_DMASYNC_POSTREAD);
+	memcpy(buf, ((uint8_t *)req->req_vbuf)+MPT_RQSL(mpt), len);
+	mpt_free_request(mpt, req);
+	return (0);
+}
 
 int
 mpt_read_cfg_header(struct mpt_softc *mpt, int PageType, int PageNumber,
@@ -1578,6 +1707,7 @@
 		    int sleep_ok, int timeout_ms)
 {
 	request_t  *req;
+	cfgparms_t params;
 	MSG_CONFIG *cfgp;
 	int	    error;
 
@@ -1587,9 +1717,13 @@
 		return (ENOMEM);
 	}
 
-	error = mpt_issue_cfg_req(mpt, req, MPI_CONFIG_ACTION_PAGE_HEADER,
-				  /*PageVersion*/0, /*PageLength*/0, PageNumber,
-				  PageType, PageAddress, /*addr*/0, /*len*/0,
+	params.Action = MPI_CONFIG_ACTION_PAGE_HEADER;
+	params.PageVersion = 0;
+	params.PageLength = 0;
+	params.PageNumber = PageNumber;
+	params.PageType = PageType;
+	params.PageAddress = PageAddress;
+	error = mpt_issue_cfg_req(mpt, req, &params, /*addr*/0, /*len*/0,
 				  sleep_ok, timeout_ms);
 	if (error != 0) {
 		/*
@@ -1630,6 +1764,7 @@
 		  int timeout_ms)
 {
 	request_t    *req;
+	cfgparms_t    params;
 	int	      error;
 
 	req = mpt_get_request(mpt, sleep_ok);
@@ -1638,10 +1773,14 @@
 		return (-1);
 	}
 
-	error = mpt_issue_cfg_req(mpt, req, Action, hdr->PageVersion,
-				  hdr->PageLength, hdr->PageNumber,
-				  hdr->PageType & MPI_CONFIG_PAGETYPE_MASK,
-				  PageAddress, req->req_pbuf + MPT_RQSL(mpt),
+	params.Action = Action;
+	params.PageVersion = hdr->PageVersion;
+	params.PageLength = hdr->PageLength;
+	params.PageNumber = hdr->PageNumber;
+	params.PageType = hdr->PageType & MPI_CONFIG_PAGETYPE_MASK;
+	params.PageAddress = PageAddress;
+	error = mpt_issue_cfg_req(mpt, req, &params,
+				  req->req_pbuf + MPT_RQSL(mpt),
 				  len, sleep_ok, timeout_ms);
 	if (error != 0) {
 		mpt_prt(mpt, "read_cfg_page(%d) timed out\n", Action);
@@ -1667,6 +1806,7 @@
 		   int timeout_ms)
 {
 	request_t    *req;
+	cfgparms_t    params;
 	u_int	      hdr_attr;
 	int	      error;
 
@@ -1696,22 +1836,21 @@
 	 * if you then mask them going down to issue the request.
 	 */
 
+	params.Action = Action;
+	params.PageVersion = hdr->PageVersion;
+	params.PageLength = hdr->PageLength;
+	params.PageNumber = hdr->PageNumber;
+	params.PageAddress = PageAddress;
 #if	0
 	/* Restore stripped out attributes */
 	hdr->PageType |= hdr_attr;
-
-	error = mpt_issue_cfg_req(mpt, req, Action, hdr->PageVersion,
-				  hdr->PageLength, hdr->PageNumber,
-				  hdr->PageType & MPI_CONFIG_PAGETYPE_MASK,
-				  PageAddress, req->req_pbuf + MPT_RQSL(mpt),
-				  len, sleep_ok, timeout_ms);
+	params.PageType = hdr->PageType & MPI_CONFIG_PAGETYPE_MASK;
 #else
-	error = mpt_issue_cfg_req(mpt, req, Action, hdr->PageVersion,
-				  hdr->PageLength, hdr->PageNumber,
-				  hdr->PageType, PageAddress,
+	params.PageType = hdr->PageType;
+#endif
+	error = mpt_issue_cfg_req(mpt, req, &params,
 				  req->req_pbuf + MPT_RQSL(mpt),
 				  len, sleep_ok, timeout_ms);
-#endif
 	if (error != 0) {
 		mpt_prt(mpt, "mpt_write_cfg_page timed out\n");
 		return (-1);
@@ -1751,17 +1890,10 @@
 		return (rv);
 	}
 
-#if __FreeBSD_version >= 500000
-	mpt_lprt(mpt, MPT_PRT_DEBUG,  "IOC Page 2 Header: ver %x, len %zx, "
-		 "num %x, type %x\n", hdr.PageVersion,
-		 hdr.PageLength * sizeof(uint32_t),
-		 hdr.PageNumber, hdr.PageType);
-#else
-	mpt_lprt(mpt, MPT_PRT_DEBUG,  "IOC Page 2 Header: ver %x, len %z, "
-		 "num %x, type %x\n", hdr.PageVersion,
-		 hdr.PageLength * sizeof(uint32_t),
-		 hdr.PageNumber, hdr.PageType);
-#endif
+	mpt_lprt(mpt, MPT_PRT_DEBUG,
+	    "IOC Page 2 Header: Version %x len %x PageNumber %x PageType %x\n",
+	    hdr.PageVersion, hdr.PageLength << 2,
+	    hdr.PageNumber, hdr.PageType);
 
 	len = hdr.PageLength * sizeof(uint32_t);
 	mpt->ioc_page2 = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -1778,6 +1910,7 @@
 		mpt_raid_free_mem(mpt);
 		return (EIO);
 	}
+	mpt2host_config_page_ioc2(mpt->ioc_page2);
 
 	if (mpt->ioc_page2->CapabilitiesFlags != 0) {
 		uint32_t mask;
@@ -1963,7 +2096,7 @@
 }
 
 /*
- * Un-mask the interupts on the chip.
+ * Un-mask the interrupts on the chip.
  */
 void
 mpt_enable_ints(struct mpt_softc *mpt)
@@ -1973,7 +2106,7 @@
 }
 
 /*
- * Mask the interupts on the chip.
+ * Mask the interrupts on the chip.
  */
 void
 mpt_disable_ints(struct mpt_softc *mpt)
@@ -1996,6 +2129,11 @@
 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
 		       "role", CTLFLAG_RD, &mpt->role, 0,
 		       "HBA role");
+#ifdef	MPT_TEST_MULTIPATH
+	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+		       "failure_id", CTLFLAG_RW, &mpt->failure_id, -1,
+		       "Next Target to Fail");
+#endif
 #endif
 }
 
@@ -2098,37 +2236,37 @@
 int
 mpt_core_attach(struct mpt_softc *mpt)
 {
-        int val;
-	int error;
-
+        int val, error;
 
 	LIST_INIT(&mpt->ack_frames);
-
 	/* Put all request buffers on the free list */
 	TAILQ_INIT(&mpt->request_pending_list);
 	TAILQ_INIT(&mpt->request_free_list);
 	TAILQ_INIT(&mpt->request_timeout_list);
+	MPT_LOCK(mpt);
 	for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) {
 		request_t *req = &mpt->request_pool[val];
 		req->state = REQ_STATE_ALLOCATED;
 		mpt_free_request(mpt, req);
 	}
-
+	MPT_UNLOCK(mpt);
 	for (val = 0; val < MPT_MAX_LUNS; val++) {
 		STAILQ_INIT(&mpt->trt[val].atios);
 		STAILQ_INIT(&mpt->trt[val].inots);
 	}
 	STAILQ_INIT(&mpt->trt_wildcard.atios);
 	STAILQ_INIT(&mpt->trt_wildcard.inots);
-
+#ifdef	MPT_TEST_MULTIPATH
+	mpt->failure_id = -1;
+#endif
 	mpt->scsi_tgt_handler_id = MPT_HANDLER_ID_NONE;
-
 	mpt_sysctl_attach(mpt);
-
 	mpt_lprt(mpt, MPT_PRT_DEBUG, "doorbell req = %s\n",
 	    mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
 
-	error = mpt_configure_ioc(mpt);
+	MPT_LOCK(mpt);
+	error = mpt_configure_ioc(mpt, 0, 0);
+	MPT_UNLOCK(mpt);
 
 	return (error);
 }
@@ -2141,6 +2279,7 @@
 	 * not enabled, ports not enabled and interrupts
 	 * not enabled.
 	 */
+	MPT_LOCK(mpt);
 
 	/*
 	 * Enable asynchronous event reporting- all personalities
@@ -2175,8 +2314,10 @@
 	 */
 	if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
 		mpt_prt(mpt, "failed to enable port 0\n");
+		MPT_UNLOCK(mpt);
 		return (ENXIO);
 	}
+	MPT_UNLOCK(mpt);
 	return (0);
 }
 
@@ -2189,6 +2330,9 @@
 void
 mpt_core_detach(struct mpt_softc *mpt)
 {
+	/*
+	 * XXX: FREE MEMORY 
+	 */
 	mpt_disable_ints(mpt);
 }
 
@@ -2329,226 +2473,229 @@
  * once at instance startup.
  */
 static int
-mpt_configure_ioc(struct mpt_softc *mpt)
+mpt_configure_ioc(struct mpt_softc *mpt, int tn, int needreset)
 {
-        MSG_PORT_FACTS_REPLY pfp;
-        MSG_IOC_FACTS_REPLY facts;
-	int try;
-	int needreset;
-	uint32_t max_chain_depth;
+	PTR_MSG_PORT_FACTS_REPLY pfp;
+	int error,  port;
+	size_t len;
 
-	needreset = 0;
-	for (try = 0; try < MPT_MAX_TRYS; try++) {
+	if (tn == MPT_MAX_TRYS) {
+		return (-1);
+	}
 
-		/*
-		 * No need to reset if the IOC is already in the READY state.
-		 *
-		 * Force reset if initialization failed previously.
-		 * Note that a hard_reset of the second channel of a '929
-		 * will stop operation of the first channel.  Hopefully, if the
-		 * first channel is ok, the second will not require a hard
-		 * reset.
-		 */
-		if (needreset || MPT_STATE(mpt_rd_db(mpt)) !=
-		    MPT_DB_STATE_READY) {
-			if (mpt_reset(mpt, FALSE) != MPT_OK) {
-				continue;
-			}
+	/*
+	 * No need to reset if the IOC is already in the READY state.
+	 *
+	 * Force reset if initialization failed previously.
+	 * Note that a hard_reset of the second channel of a '929
+	 * will stop operation of the first channel.  Hopefully, if the
+	 * first channel is ok, the second will not require a hard
+	 * reset.
+	 */
+	if (needreset || MPT_STATE(mpt_rd_db(mpt)) != MPT_DB_STATE_READY) {
+		if (mpt_reset(mpt, FALSE) != MPT_OK) {
+			return (mpt_configure_ioc(mpt, tn++, 1));
 		}
 		needreset = 0;
+	}
 
-		if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
-			mpt_prt(mpt, "mpt_get_iocfacts failed\n");
-			needreset = 1;
-			continue;
-		}
-
-		mpt->mpt_global_credits = le16toh(facts.GlobalCredits);
-		mpt->request_frame_size = le16toh(facts.RequestFrameSize);
-		mpt->ioc_facts_flags = facts.Flags;
-		mpt_prt(mpt, "MPI Version=%d.%d.%d.%d\n",
-			    le16toh(facts.MsgVersion) >> 8,
-			    le16toh(facts.MsgVersion) & 0xFF,
-			    le16toh(facts.HeaderVersion) >> 8,
-			    le16toh(facts.HeaderVersion) & 0xFF);
-
-		/*
-		 * Now that we know request frame size, we can calculate
-		 * the actual (reasonable) segment limit for read/write I/O.
-		 *
-		 * This limit is constrained by:
-		 *
-		 *  + The size of each area we allocate per command (and how
-                 *    many chain segments we can fit into it).
-                 *  + The total number of areas we've set up.
-		 *  + The actual chain depth the card will allow.
-		 *
-		 * The first area's segment count is limited by the I/O request
-		 * at the head of it. We cannot allocate realistically more
-		 * than MPT_MAX_REQUESTS areas. Therefore, to account for both
-		 * conditions, we'll just start out with MPT_MAX_REQUESTS-2.
-		 *
-		 */
-		max_chain_depth = facts.MaxChainDepth;
-
-		/* total number of request areas we (can) allocate */
-		mpt->max_seg_cnt = MPT_MAX_REQUESTS(mpt) - 2;
+	if (mpt_get_iocfacts(mpt, &mpt->ioc_facts) != MPT_OK) {
+		mpt_prt(mpt, "mpt_get_iocfacts failed\n");
+		return (mpt_configure_ioc(mpt, tn++, 1));
+	}
+	mpt2host_iocfacts_reply(&mpt->ioc_facts);
 
-		/* converted to the number of chain areas possible */
-		mpt->max_seg_cnt *= MPT_NRFM(mpt);
+	mpt_prt(mpt, "MPI Version=%d.%d.%d.%d\n",
+	    mpt->ioc_facts.MsgVersion >> 8,
+	    mpt->ioc_facts.MsgVersion & 0xFF,
+	    mpt->ioc_facts.HeaderVersion >> 8,
+	    mpt->ioc_facts.HeaderVersion & 0xFF);
 
-		/* limited by the number of chain areas the card will support */
-		if (mpt->max_seg_cnt > max_chain_depth) {
-			mpt_lprt(mpt, MPT_PRT_DEBUG,
-			    "chain depth limited to %u (from %u)\n",
-			    max_chain_depth, mpt->max_seg_cnt);
-			mpt->max_seg_cnt = max_chain_depth;
-		}
+	/*
+	 * Now that we know request frame size, we can calculate
+	 * the actual (reasonable) segment limit for read/write I/O.
+	 *
+	 * This limit is constrained by:
+	 *
+	 *  + The size of each area we allocate per command (and how
+	 *    many chain segments we can fit into it).
+	 *  + The total number of areas we've set up.
+	 *  + The actual chain depth the card will allow.
+	 *
+	 * The first area's segment count is limited by the I/O request
+	 * at the head of it. We cannot allocate realistically more
+	 * than MPT_MAX_REQUESTS areas. Therefore, to account for both
+	 * conditions, we'll just start out with MPT_MAX_REQUESTS-2.
+	 *
+	 */
+	/* total number of request areas we (can) allocate */
+	mpt->max_seg_cnt = MPT_MAX_REQUESTS(mpt) - 2;
 
-		/* converted to the number of simple sges in chain segments. */
-		mpt->max_seg_cnt *= (MPT_NSGL(mpt) - 1);
+	/* converted to the number of chain areas possible */
+	mpt->max_seg_cnt *= MPT_NRFM(mpt);
 
+	/* limited by the number of chain areas the card will support */
+	if (mpt->max_seg_cnt > mpt->ioc_facts.MaxChainDepth) {
 		mpt_lprt(mpt, MPT_PRT_DEBUG,
-		    "Maximum Segment Count: %u\n", mpt->max_seg_cnt);
-		mpt_lprt(mpt, MPT_PRT_DEBUG,
-			 "MsgLength=%u IOCNumber = %d\n",
-			 facts.MsgLength, facts.IOCNumber);
-		mpt_lprt(mpt, MPT_PRT_DEBUG,
-			 "IOCFACTS: GlobalCredits=%d BlockSize=%u bytes "
-			 "Request Frame Size %u bytes Max Chain Depth %u\n",
-                         mpt->mpt_global_credits, facts.BlockSize,
-                         mpt->request_frame_size << 2, max_chain_depth);
-		mpt_lprt(mpt, MPT_PRT_DEBUG,
-			 "IOCFACTS: Num Ports %d, FWImageSize %d, "
-			 "Flags=%#x\n", facts.NumberOfPorts,
-			 le32toh(facts.FWImageSize), facts.Flags);
-
+		    "chain depth limited to %u (from %u)\n",
+		    mpt->ioc_facts.MaxChainDepth, mpt->max_seg_cnt);
+		mpt->max_seg_cnt = mpt->ioc_facts.MaxChainDepth;
+	}
+
+	/* converted to the number of simple sges in chain segments. */
+	mpt->max_seg_cnt *= (MPT_NSGL(mpt) - 1);
+
+	mpt_lprt(mpt, MPT_PRT_DEBUG, "Maximum Segment Count: %u\n",
+	    mpt->max_seg_cnt);
+	mpt_lprt(mpt, MPT_PRT_DEBUG, "MsgLength=%u IOCNumber = %d\n",
+	    mpt->ioc_facts.MsgLength, mpt->ioc_facts.IOCNumber);
+	mpt_lprt(mpt, MPT_PRT_DEBUG,
+	    "IOCFACTS: GlobalCredits=%d BlockSize=%u bytes "
+	    "Request Frame Size %u bytes Max Chain Depth %u\n",
+	    mpt->ioc_facts.GlobalCredits, mpt->ioc_facts.BlockSize,
+	    mpt->ioc_facts.RequestFrameSize << 2,
+	    mpt->ioc_facts.MaxChainDepth);
+	mpt_lprt(mpt, MPT_PRT_DEBUG, "IOCFACTS: Num Ports %d, FWImageSize %d, "
+	    "Flags=%#x\n", mpt->ioc_facts.NumberOfPorts,
+	    mpt->ioc_facts.FWImageSize, mpt->ioc_facts.Flags);
+
+	len = mpt->ioc_facts.NumberOfPorts * sizeof (MSG_PORT_FACTS_REPLY);
+	mpt->port_facts = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (mpt->port_facts == NULL) {
+		mpt_prt(mpt, "unable to allocate memory for port facts\n");
+		return (ENOMEM);
+	}
 
-		if ((facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) != 0) {
-			struct mpt_map_info mi;
-			int error;
 
-			/*
-			 * In some configurations, the IOC's firmware is
-			 * stored in a shared piece of system NVRAM that
-			 * is only accessable via the BIOS.  In this
-			 * case, the firmware keeps a copy of firmware in
-			 * RAM until the OS driver retrieves it.  Once
-			 * retrieved, we are responsible for re-downloading
-			 * the firmware after any hard-reset.
-			 */
-			mpt->fw_image_size = le32toh(facts.FWImageSize);
-			error = mpt_dma_tag_create(mpt, mpt->parent_dmat,
-			    /*alignment*/1, /*boundary*/0,
-			    /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
-			    /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL,
-			    /*filterarg*/NULL, mpt->fw_image_size,
-			    /*nsegments*/1, /*maxsegsz*/mpt->fw_image_size,
-			    /*flags*/0, &mpt->fw_dmat);
-			if (error != 0) {
-				mpt_prt(mpt, "cannot create fw dma tag\n");
-				return (ENOMEM);
-			}
-			error = bus_dmamem_alloc(mpt->fw_dmat,
-			    (void **)&mpt->fw_image, BUS_DMA_NOWAIT,
-			    &mpt->fw_dmap);
-			if (error != 0) {
-				mpt_prt(mpt, "cannot allocate fw mem.\n");
-				bus_dma_tag_destroy(mpt->fw_dmat);
-				return (ENOMEM);
-			}
-			mi.mpt = mpt;
-			mi.error = 0;
-			bus_dmamap_load(mpt->fw_dmat, mpt->fw_dmap,
-			    mpt->fw_image, mpt->fw_image_size, mpt_map_rquest,
-			    &mi, 0);
-			mpt->fw_phys = mi.phys;
+	if ((mpt->ioc_facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) &&
+	    (mpt->fw_uploaded == 0)) {
+		struct mpt_map_info mi;
 
-			error = mpt_upload_fw(mpt);
-			if (error != 0) {
-				mpt_prt(mpt, "fw upload failed.\n");
-				bus_dmamap_unload(mpt->fw_dmat, mpt->fw_dmap);
-				bus_dmamem_free(mpt->fw_dmat, mpt->fw_image,
-				    mpt->fw_dmap);
-				bus_dma_tag_destroy(mpt->fw_dmat);
-				mpt->fw_image = NULL;
-				return (EIO);
-			}
+		/*
+		 * In some configurations, the IOC's firmware is
+		 * stored in a shared piece of system NVRAM that
+		 * is only accessable via the BIOS.  In this
+		 * case, the firmware keeps a copy of firmware in
+		 * RAM until the OS driver retrieves it.  Once
+		 * retrieved, we are responsible for re-downloading
+		 * the firmware after any hard-reset.
+		 */
+		mpt->fw_image_size = mpt->ioc_facts.FWImageSize;
+		error = mpt_dma_tag_create(mpt, mpt->parent_dmat, 1, 0,
+		    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+		    mpt->fw_image_size, 1, mpt->fw_image_size, 0,
+		    &mpt->fw_dmat);
+		if (error != 0) {
+			mpt_prt(mpt, "cannot create firmwarew dma tag\n");
+			return (ENOMEM);
 		}
-
-		if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) {
-			mpt_prt(mpt, "mpt_get_portfacts failed\n");
-			needreset = 1;
-			continue;
+		error = bus_dmamem_alloc(mpt->fw_dmat,
+		    (void **)&mpt->fw_image, BUS_DMA_NOWAIT, &mpt->fw_dmap);
+		if (error != 0) {
+			mpt_prt(mpt, "cannot allocate firmware memory\n");
+			bus_dma_tag_destroy(mpt->fw_dmat);
+			return (ENOMEM);
 		}
-
-		mpt_lprt(mpt, MPT_PRT_DEBUG,
-			 "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d\n",
-			 pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID,
-			 pfp.MaxDevices);
-
-		mpt->mpt_port_type = pfp.PortType;
-		mpt->mpt_proto_flags = pfp.ProtocolFlags;
-		if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
-		    pfp.PortType != MPI_PORTFACTS_PORTTYPE_SAS &&
-		    pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
-			mpt_prt(mpt, "Unsupported Port Type (%x)\n",
-			    pfp.PortType);
-			return (ENXIO);
+		mi.mpt = mpt;
+		mi.error = 0;
+		bus_dmamap_load(mpt->fw_dmat, mpt->fw_dmap,
+		    mpt->fw_image, mpt->fw_image_size, mpt_map_rquest, &mi, 0);
+		mpt->fw_phys = mi.phys;
+
+		error = mpt_upload_fw(mpt);
+		if (error != 0) {
+			mpt_prt(mpt, "firmware upload failed.\n");
+			bus_dmamap_unload(mpt->fw_dmat, mpt->fw_dmap);
+			bus_dmamem_free(mpt->fw_dmat, mpt->fw_image,
+			    mpt->fw_dmap);
+			bus_dma_tag_destroy(mpt->fw_dmat);
+			mpt->fw_image = NULL;
+			return (EIO);
+		}
+		mpt->fw_uploaded = 1;
+	}
+
+	for (port = 0; port < mpt->ioc_facts.NumberOfPorts; port++) {
+		pfp = &mpt->port_facts[port];
+		error = mpt_get_portfacts(mpt, 0, pfp);
+		if (error != MPT_OK) {
+			mpt_prt(mpt,
+			    "mpt_get_portfacts on port %d failed\n", port);
+			free(mpt->port_facts, M_DEVBUF);
+			mpt->port_facts = NULL;
+			return (mpt_configure_ioc(mpt, tn++, 1));
 		}
-		mpt->mpt_max_tgtcmds = le16toh(pfp.MaxPostedCmdBuffers);
+		mpt2host_portfacts_reply(pfp);
 
-		if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
-			mpt->is_fc = 1;
-			mpt->is_sas = 0;
-			mpt->is_spi = 0;
-		} else if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_SAS) {
-			mpt->is_fc = 0;
-			mpt->is_sas = 1;
-			mpt->is_spi = 0;
+		if (port > 0) {
+			error = MPT_PRT_INFO;
 		} else {
-			mpt->is_fc = 0;
-			mpt->is_sas = 0;
-			mpt->is_spi = 1;
+			error = MPT_PRT_DEBUG;
 		}
-		mpt->mpt_ini_id = pfp.PortSCSIID;
-		mpt->mpt_max_devices = pfp.MaxDevices;
+		mpt_lprt(mpt, error,
+		    "PORTFACTS[%d]: Type %x PFlags %x IID %d MaxDev %d\n",
+		    port, pfp->PortType, pfp->ProtocolFlags, pfp->PortSCSIID,
+		    pfp->MaxDevices);
 
-		/*
-		 * Set our role with what this port supports.
-		 *
-		 * Note this might be changed later in different modules
-		 * if this is different from what is wanted.
-		 */
-		mpt->role = MPT_ROLE_NONE;
-		if (pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
-			mpt->role |= MPT_ROLE_INITIATOR;
-		}
-		if (pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
-			mpt->role |= MPT_ROLE_TARGET;
-		}
-		if (mpt_enable_ioc(mpt, 0) != MPT_OK) {
-			mpt_prt(mpt, "unable to initialize IOC\n");
-			return (ENXIO);
-		}
+	}
 
-		/*
-		 * Read IOC configuration information.
-		 *
-		 * We need this to determine whether or not we have certain
-		 * settings for Integrated Mirroring (e.g.).
-		 */
-		mpt_read_config_info_ioc(mpt);
+	/*
+	 * XXX: Not yet supporting more than port 0
+	 */
+	pfp = &mpt->port_facts[0];
+	if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_FC) {
+		mpt->is_fc = 1;
+		mpt->is_sas = 0;
+		mpt->is_spi = 0;
+	} else if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_SAS) {
+		mpt->is_fc = 0;
+		mpt->is_sas = 1;
+		mpt->is_spi = 0;
+	} else if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_SCSI) {
+		mpt->is_fc = 0;
+		mpt->is_sas = 0;
+		mpt->is_spi = 1;
+	} else if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_ISCSI) {
+		mpt_prt(mpt, "iSCSI not supported yet\n");
+		return (ENXIO);
+	} else if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_INACTIVE) {
+		mpt_prt(mpt, "Inactive Port\n");
+		return (ENXIO);
+	} else {
+		mpt_prt(mpt, "unknown Port Type %#x\n", pfp->PortType);
+		return (ENXIO);
+	}
 
-		/* Everything worked */
-		break;
+	/*
+	 * Set our role with what this port supports.
+	 *
+	 * Note this might be changed later in different modules
+	 * if this is different from what is wanted.
+	 */
+	mpt->role = MPT_ROLE_NONE;
+	if (pfp->ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
+		mpt->role |= MPT_ROLE_INITIATOR;
+	}
+	if (pfp->ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
+		mpt->role |= MPT_ROLE_TARGET;
 	}
 
-	if (try >= MPT_MAX_TRYS) {
-		mpt_prt(mpt, "failed to initialize IOC");
-		return (EIO);
+	/*
+	 * Enable the IOC
+	 */
+	if (mpt_enable_ioc(mpt, 0) != MPT_OK) {
+		mpt_prt(mpt, "unable to initialize IOC\n");
+		return (ENXIO);
 	}
 
+	/*
+	 * Read IOC configuration information.
+	 *
+	 * We need this to determine whether or not we have certain
+	 * settings for Integrated Mirroring (e.g.).
+	 */
+	mpt_read_config_info_ioc(mpt);
+
 	return (0);
 }
 
@@ -2580,7 +2727,7 @@
 	    (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
 	     pptr += MPT_REPLY_SIZE) {
 		mpt_free_reply(mpt, pptr);
-		if (++val == mpt->mpt_global_credits - 1)
+		if (++val == mpt->ioc_facts.GlobalCredits - 1)
 			break;
 	}
 
@@ -2602,3 +2749,95 @@
 	}
 	return (MPT_OK);
 }
+
+/*
+ * Endian Conversion Functions- only used on Big Endian machines
+ */
+#if	_BYTE_ORDER == _BIG_ENDIAN
+void
+mpt2host_sge_simple_union(SGE_SIMPLE_UNION *sge)
+{
+	MPT_2_HOST32(sge, FlagsLength);
+	MPT_2_HOST32(sge, u.Address64.Low);
+	MPT_2_HOST32(sge, u.Address64.High);
+}
+
+void
+mpt2host_iocfacts_reply(MSG_IOC_FACTS_REPLY *rp)
+{
+	MPT_2_HOST16(rp, MsgVersion);
+	MPT_2_HOST16(rp, HeaderVersion);
+	MPT_2_HOST32(rp, MsgContext);
+	MPT_2_HOST16(rp, IOCExceptions);
+	MPT_2_HOST16(rp, IOCStatus);
+	MPT_2_HOST32(rp, IOCLogInfo);
+	MPT_2_HOST16(rp, ReplyQueueDepth);
+	MPT_2_HOST16(rp, RequestFrameSize);
+	MPT_2_HOST16(rp, Reserved_0101_FWVersion);
+	MPT_2_HOST16(rp, ProductID);
+	MPT_2_HOST32(rp, CurrentHostMfaHighAddr);
+	MPT_2_HOST16(rp, GlobalCredits);
+	MPT_2_HOST32(rp, CurrentSenseBufferHighAddr);
+	MPT_2_HOST16(rp, CurReplyFrameSize);
+	MPT_2_HOST32(rp, FWImageSize);
+	MPT_2_HOST32(rp, IOCCapabilities);
+	MPT_2_HOST32(rp, FWVersion.Word);
+	MPT_2_HOST16(rp, HighPriorityQueueDepth);
+	MPT_2_HOST16(rp, Reserved2);
+	mpt2host_sge_simple_union(&rp->HostPageBufferSGE);
+	MPT_2_HOST32(rp, ReplyFifoHostSignalingAddr);
+}
+
+void
+mpt2host_portfacts_reply(MSG_PORT_FACTS_REPLY *pfp)
+{
+	MPT_2_HOST16(pfp, Reserved);
+	MPT_2_HOST16(pfp, Reserved1);
+	MPT_2_HOST32(pfp, MsgContext);
+	MPT_2_HOST16(pfp, Reserved2);
+	MPT_2_HOST16(pfp, IOCStatus);
+	MPT_2_HOST32(pfp, IOCLogInfo);
+	MPT_2_HOST16(pfp, MaxDevices);
+	MPT_2_HOST16(pfp, PortSCSIID);
+	MPT_2_HOST16(pfp, ProtocolFlags);
+	MPT_2_HOST16(pfp, MaxPostedCmdBuffers);
+	MPT_2_HOST16(pfp, MaxPersistentIDs);
+	MPT_2_HOST16(pfp, MaxLanBuckets);
+	MPT_2_HOST16(pfp, Reserved4);
+	MPT_2_HOST32(pfp, Reserved5);
+}
+void
+mpt2host_config_page_ioc2(CONFIG_PAGE_IOC_2 *ioc2)
+{
+	int i;
+	ioc2->CapabilitiesFlags = htole32(ioc2->CapabilitiesFlags);
+	for (i = 0; i < MPI_IOC_PAGE_2_RAID_VOLUME_MAX; i++) {
+		MPT_2_HOST16(ioc2, RaidVolume[i].Reserved3);
+	}
+}
+
+void
+mpt2host_config_page_raid_vol_0(CONFIG_PAGE_RAID_VOL_0 *volp)
+{
+	int i;
+	MPT_2_HOST16(volp, VolumeStatus.Reserved);
+	MPT_2_HOST16(volp, VolumeSettings.Settings);
+	MPT_2_HOST32(volp, MaxLBA);
+	MPT_2_HOST32(volp, MaxLBAHigh);
+	MPT_2_HOST32(volp, StripeSize);
+	MPT_2_HOST32(volp, Reserved2);
+	MPT_2_HOST32(volp, Reserved3);
+	for (i = 0; i < MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX; i++) {
+		MPT_2_HOST16(volp, PhysDisk[i].Reserved);
+	}
+}
+
+void
+mpt2host_mpi_raid_vol_indicator(MPI_RAID_VOL_INDICATOR *vi)
+{
+	MPT_2_HOST16(vi, TotalBlocks.High);
+	MPT_2_HOST16(vi, TotalBlocks.Low);
+	MPT_2_HOST16(vi, BlocksRemaining.High);
+	MPT_2_HOST16(vi, BlocksRemaining.Low);
+}
+#endif
Index: mpt_cam.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpt_cam.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpt_cam.h -L sys/dev/mpt/mpt_cam.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpt_cam.h
+++ sys/dev/mpt/mpt_cam.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpt_cam.h,v 1.1.2.3 2006/09/16 05:42:06 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpt_cam.h,v 1.6 2007/05/05 20:18:24 mjacob Exp $ */
 /*-
  * LSI MPT Host Adapter FreeBSD Wrapper Definitions (CAM version)
  *
@@ -101,6 +101,8 @@
 #include <cam/cam_ccb.h>
 #include <cam/cam_sim.h>
 #include <cam/cam_xpt.h>
+#include <cam/cam_periph.h>
+#include <cam/cam_xpt_periph.h>
 #include <cam/cam_xpt_sim.h>
 #include <cam/cam_debug.h>
 #include <cam/scsi/scsi_all.h>
@@ -141,4 +143,12 @@
 	wakeup(mpt);
 }
 
+/************************** Version Compatibility *************************/
+#if	__FreeBSD_version < 700031
+#define	mpt_sim_alloc(a, b, c, mpt, e, f, g)	\
+	cam_sim_alloc(a, b, c, mpt, (mpt)->unit, e, f, g)
+#else
+#define	mpt_sim_alloc(a, b, c, mpt, e, f, g)	\
+	cam_sim_alloc(a, b, c, mpt, (mpt)->unit, &(mpt)->mpt_lock, e, f, g)
+#endif
 #endif /*_MPT_CAM_H_ */
Index: mpt_pci.c
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpt_pci.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpt_pci.c -L sys/dev/mpt/mpt_pci.c -u -r1.2 -r1.3
--- sys/dev/mpt/mpt_pci.c
+++ sys/dev/mpt/mpt_pci.c
@@ -99,12 +99,19 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt_pci.c,v 1.20.2.6 2006/09/16 05:42:06 mjacob Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt_pci.c,v 1.51 2007/09/18 16:39:24 ambrisko Exp $");
 
 #include <dev/mpt/mpt.h>
 #include <dev/mpt/mpt_cam.h>
 #include <dev/mpt/mpt_raid.h>
 
+#if __FreeBSD_version < 700000
+#define	pci_msix_count(x)	0
+#define	pci_msi_count(x)	0
+#define	pci_alloc_msi(x, y)	1
+#define	pci_alloc_msix(x, y)	1
+#define	pci_release_msi(x)	do { ; } while (0)
+#endif
 
 #ifndef	PCI_VENDOR_LSI
 #define	PCI_VENDOR_LSI			0x1000
@@ -175,7 +182,7 @@
 #endif
 
 #ifndef PCI_PRODUCT_LSI_SAS1078
-#define PCI_PRODUCT_LSI_SAS1078		0x0060
+#define PCI_PRODUCT_LSI_SAS1078		0x0062
 #endif
 
 #ifndef	PCIM_CMD_SERRESPEN
@@ -210,6 +217,7 @@
 };
 static devclass_t mpt_devclass;
 DRIVER_MODULE(mpt, pci, mpt_driver, mpt_devclass, 0, 0);
+MODULE_DEPEND(mpt, pci, 1, 1, 1);
 MODULE_VERSION(mpt, 1);
 
 static int
@@ -326,6 +334,7 @@
 		}
 		mpt->do_cfg_role = 1;
 	}
+	mpt->msi_enable = 0;
 }
 #else
 static void
@@ -350,6 +359,13 @@
 		mpt->cfg_role = tval;
 		mpt->do_cfg_role = 1;
 	}
+
+	tval = 0;
+	mpt->msi_enable = 0;
+	if (resource_int_value(device_get_name(mpt->dev),
+	    device_get_unit(mpt->dev), "msi_enable", &tval) == 0 && tval == 1) {
+		mpt->msi_enable = 1;
+	}
 }
 #endif
 
@@ -512,6 +528,28 @@
 
 	/* Get a handle to the interrupt */
 	iqd = 0;
+	if (mpt->msi_enable) {
+		/*
+		 * First try to alloc an MSI-X message.  If that
+		 * fails, then try to alloc an MSI message instead.
+		 */
+		if (pci_msix_count(dev) == 1) {
+			mpt->pci_msi_count = 1;
+			if (pci_alloc_msix(dev, &mpt->pci_msi_count) == 0) {
+				iqd = 1;
+			} else {
+				mpt->pci_msi_count = 0;
+			}
+		}
+		if (iqd == 0 && pci_msi_count(dev) == 1) {
+			mpt->pci_msi_count = 1;
+			if (pci_alloc_msi(dev, &mpt->pci_msi_count) == 0) {
+				iqd = 1;
+			} else {
+				mpt->pci_msi_count = 0;
+			}
+		}
+	}
 	mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd,
 	    RF_ACTIVE | RF_SHAREABLE);
 	if (mpt->pci_irq == NULL) {
@@ -525,7 +563,7 @@
 	mpt_disable_ints(mpt);
 
 	/* Register the interrupt handler */
-	if (bus_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, mpt_pci_intr,
+	if (mpt_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, NULL, mpt_pci_intr,
 	    mpt, &mpt->ih)) {
 		device_printf(dev, "could not setup interrupt\n");
 		goto bad;
@@ -559,12 +597,9 @@
 
 	/* Initialize the hardware */
 	if (mpt->disabled == 0) {
-		MPT_LOCK(mpt);
 		if (mpt_attach(mpt) != 0) {
-			MPT_UNLOCK(mpt);
 			goto bad;
 		}
-		MPT_UNLOCK(mpt);
 	} else {
 		mpt_prt(mpt, "device disabled at user request\n");
 		goto bad;
@@ -575,12 +610,9 @@
 
 	if (mpt->eh == NULL) {
 		mpt_prt(mpt, "shutdown event registration failed\n");
-		MPT_LOCK(mpt);
 		(void) mpt_detach(mpt);
-		MPT_UNLOCK(mpt);
 		goto bad;
 	}
-	KASSERT(MPT_OWNED(mpt) == 0, ("leaving attach with device locked"));
 	return (0);
 
 bad:
@@ -608,10 +640,16 @@
 	}
 
 	if (mpt->pci_irq) {
-		bus_release_resource(mpt->dev, SYS_RES_IRQ, 0, mpt->pci_irq);
+		bus_release_resource(mpt->dev, SYS_RES_IRQ,
+		    mpt->pci_msi_count ? 1 : 0, mpt->pci_irq);
 		mpt->pci_irq = 0;
 	}
 
+	if (mpt->pci_msi_count) {
+		pci_release_msi(mpt->dev);
+		mpt->pci_msi_count = 0;
+	}
+		
 	if (mpt->pci_pio_reg) {
 		bus_release_resource(mpt->dev, SYS_RES_IOPORT, mpt->pci_pio_rid,
 			mpt->pci_pio_reg);
@@ -637,7 +675,6 @@
 	mpt  = (struct mpt_softc*)device_get_softc(dev);
 
 	if (mpt) {
-		MPT_LOCK(mpt);
 		mpt_disable_ints(mpt);
 		mpt_detach(mpt);
 		mpt_reset(mpt, /*reinit*/FALSE);
@@ -647,7 +684,6 @@
 		if (mpt->eh != NULL) {
                         EVENTHANDLER_DEREGISTER(shutdown_final, mpt->eh);
 		}
-		MPT_UNLOCK(mpt);
 	}
 	return(0);
 }
@@ -664,9 +700,7 @@
 	mpt = (struct mpt_softc *)device_get_softc(dev);
 	if (mpt) {
 		int r;
-		MPT_LOCK(mpt);
 		r = mpt_shutdown(mpt);
-		MPT_UNLOCK(mpt);
 		return (r);
 	}
 	return(0);
@@ -708,8 +742,8 @@
 	 * Align at byte boundaries,
 	 * Limit to 32-bit addressing for request/reply queues.
 	 */
-	if (mpt_dma_tag_create(mpt, /*parent*/NULL, /*alignment*/1,
-	    /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR,
+	if (mpt_dma_tag_create(mpt, /*parent*/bus_get_dma_tag(mpt->dev),
+	    /*alignment*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR,
 	    /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL,
 	    /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
 	    /*nsegments*/BUS_SPACE_MAXSIZE_32BIT,
Index: mpt_cam.c
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpt_cam.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -L sys/dev/mpt/mpt_cam.c -L sys/dev/mpt/mpt_cam.c -u -r1.3 -r1.4
--- sys/dev/mpt/mpt_cam.c
+++ sys/dev/mpt/mpt_cam.c
@@ -94,7 +94,7 @@
  * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt_cam.c,v 1.1.2.6 2006/09/27 15:30:46 mjacob Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mpt/mpt_cam.c,v 1.61.2.1 2007/10/19 15:22:24 scottl Exp $");
 
 #include <dev/mpt/mpt.h>
 #include <dev/mpt/mpt_cam.h>
@@ -104,10 +104,19 @@
 #include "dev/mpt/mpilib/mpi_init.h"
 #include "dev/mpt/mpilib/mpi_targ.h"
 #include "dev/mpt/mpilib/mpi_fc.h"
+#include "dev/mpt/mpilib/mpi_sas.h"
+#if __FreeBSD_version >= 500000
 #include <sys/sysctl.h>
+#endif
 #include <sys/callout.h>
 #include <sys/kthread.h>
 
+#if __FreeBSD_version >= 700025
+#ifndef	CAM_NEW_TRAN_CODE
+#define	CAM_NEW_TRAN_CODE	1
+#endif
+#endif
+
 static void mpt_poll(struct cam_sim *);
 static timeout_t mpt_timeout;
 static void mpt_action(struct cam_sim *, union ccb *);
@@ -151,10 +160,12 @@
 static void mpt_tgt_dump_tgt_state(struct mpt_softc *, request_t *);
 static void mpt_tgt_dump_req_state(struct mpt_softc *, request_t *);
 static mpt_reply_handler_t mpt_scsi_tgt_reply_handler;
+static mpt_reply_handler_t mpt_sata_pass_reply_handler;
 
 static uint32_t scsi_io_handler_id = MPT_HANDLER_ID_NONE;
 static uint32_t scsi_tmf_handler_id = MPT_HANDLER_ID_NONE;
 static uint32_t fc_els_handler_id = MPT_HANDLER_ID_NONE;
+static uint32_t sata_pass_handler_id = MPT_HANDLER_ID_NONE;
 
 static mpt_probe_handler_t	mpt_cam_probe;
 static mpt_attach_handler_t	mpt_cam_attach;
@@ -177,6 +188,10 @@
 };
 
 DECLARE_MPT_PERSONALITY(mpt_cam, SI_ORDER_SECOND);
+MODULE_DEPEND(mpt_cam, cam, 1, 1, 1);
+
+int mpt_enable_sata_wc = -1;
+TUNABLE_INT("hw.mpt.enable_sata_wc", &mpt_enable_sata_wc);
 
 int
 mpt_cam_probe(struct mpt_softc *mpt)
@@ -208,22 +223,25 @@
 	int		 maxq;
 	int		 error;
 
+	MPT_LOCK(mpt);
 	TAILQ_INIT(&mpt->request_timeout_list);
-	maxq = (mpt->mpt_global_credits < MPT_MAX_REQUESTS(mpt))?
-	    mpt->mpt_global_credits : MPT_MAX_REQUESTS(mpt);
+	maxq = (mpt->ioc_facts.GlobalCredits < MPT_MAX_REQUESTS(mpt))?
+	    mpt->ioc_facts.GlobalCredits : MPT_MAX_REQUESTS(mpt);
 
 	handler.reply_handler = mpt_scsi_reply_handler;
 	error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
 				     &scsi_io_handler_id);
 	if (error != 0) {
-		goto cleanup0;
+		MPT_UNLOCK(mpt);
+		goto cleanup;
 	}
 
 	handler.reply_handler = mpt_scsi_tmf_reply_handler;
 	error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
 				     &scsi_tmf_handler_id);
 	if (error != 0) {
-		goto cleanup0;
+		MPT_UNLOCK(mpt);
+		goto cleanup;
 	}
 
 	/*
@@ -235,11 +253,13 @@
 		error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
 		    &fc_els_handler_id);
 		if (error != 0) {
-			goto cleanup0;
+			MPT_UNLOCK(mpt);
+			goto cleanup;
 		}
 		if (mpt_add_els_buffers(mpt) == FALSE) {
 			error = ENOMEM;
-			goto cleanup0;
+			MPT_UNLOCK(mpt);
+			goto cleanup;
 		}
 		maxq -= mpt->els_cmds_allocated;
 	}
@@ -254,7 +274,18 @@
 		error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
 		    &mpt->scsi_tgt_handler_id);
 		if (error != 0) {
-			goto cleanup0;
+			MPT_UNLOCK(mpt);
+			goto cleanup;
+		}
+	}
+
+	if (mpt->is_sas) {
+		handler.reply_handler = mpt_sata_pass_reply_handler;
+		error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
+		    &sata_pass_handler_id);
+		if (error != 0) {
+			MPT_UNLOCK(mpt);
+			goto cleanup;
 		}
 	}
 
@@ -265,7 +296,8 @@
 	if (mpt->tmf_req == NULL) {
 		mpt_prt(mpt, "Unable to allocate dedicated TMF request!\n");
 		error = ENOMEM;
-		goto cleanup0;
+		MPT_UNLOCK(mpt);
+		goto cleanup;
 	}
 
 	/*
@@ -277,18 +309,18 @@
 	mpt->tmf_req->state = REQ_STATE_FREE;
 	maxq--;
 
+	/*
+	 * The rest of this is CAM foo, for which we need to drop our lock
+	 */
+	MPT_UNLOCK(mpt);
+
 	if (mpt_spawn_recovery_thread(mpt) != 0) {
 		mpt_prt(mpt, "Unable to spawn recovery thread!\n");
 		error = ENOMEM;
-		goto cleanup0;
+		goto cleanup;
 	}
 
 	/*
-	 * The rest of this is CAM foo, for which we need to drop our lock
-	 */
-	MPTLOCK_2_CAMLOCK(mpt);
-
-	/*
 	 * Create the device queue for our SIM(s).
 	 */
 	devq = cam_simq_alloc(maxq);
@@ -301,8 +333,8 @@
 	/*
 	 * Construct our SIM entry.
 	 */
-	mpt->sim = cam_sim_alloc(mpt_action, mpt_poll, "mpt", mpt,
-	    mpt->unit, 1, maxq, devq);
+	mpt->sim =
+	    mpt_sim_alloc(mpt_action, mpt_poll, "mpt", mpt, 1, maxq, devq);
 	if (mpt->sim == NULL) {
 		mpt_prt(mpt, "Unable to allocate CAM SIM!\n");
 		cam_simq_free(devq);
@@ -313,9 +345,11 @@
 	/*
 	 * Register exactly this bus.
 	 */
-	if (xpt_bus_register(mpt->sim, 0) != CAM_SUCCESS) {
+	MPT_LOCK(mpt);
+	if (xpt_bus_register(mpt->sim, mpt->dev, 0) != CAM_SUCCESS) {
 		mpt_prt(mpt, "Bus registration Failed!\n");
 		error = ENOMEM;
+		MPT_UNLOCK(mpt);
 		goto cleanup;
 	}
 
@@ -323,23 +357,24 @@
 	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
 		mpt_prt(mpt, "Unable to allocate Path!\n");
 		error = ENOMEM;
+		MPT_UNLOCK(mpt);
 		goto cleanup;
 	}
+	MPT_UNLOCK(mpt);
 
 	/*
 	 * Only register a second bus for RAID physical
 	 * devices if the controller supports RAID.
 	 */
 	if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0) {
-		CAMLOCK_2_MPTLOCK(mpt);
 		return (0);
 	}
 
 	/*
 	 * Create a "bus" to export all hidden disks to CAM.
 	 */
-	mpt->phydisk_sim = cam_sim_alloc(mpt_action, mpt_poll, "mpt", mpt,
-	    mpt->unit, 1, maxq, devq);
+	mpt->phydisk_sim =
+	    mpt_sim_alloc(mpt_action, mpt_poll, "mpt", mpt, 1, maxq, devq);
 	if (mpt->phydisk_sim == NULL) {
 		mpt_prt(mpt, "Unable to allocate Physical Disk CAM SIM!\n");
 		error = ENOMEM;
@@ -349,9 +384,11 @@
 	/*
 	 * Register this bus.
 	 */
-	if (xpt_bus_register(mpt->phydisk_sim, 1) != CAM_SUCCESS) {
+	MPT_LOCK(mpt);
+	if (xpt_bus_register(mpt->phydisk_sim, mpt->dev, 1) != CAM_SUCCESS) {
 		mpt_prt(mpt, "Physical Disk Bus registration Failed!\n");
 		error = ENOMEM;
+		MPT_UNLOCK(mpt);
 		goto cleanup;
 	}
 
@@ -360,15 +397,14 @@
 	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
 		mpt_prt(mpt, "Unable to allocate Physical Disk Path!\n");
 		error = ENOMEM;
+		MPT_UNLOCK(mpt);
 		goto cleanup;
 	}
-	CAMLOCK_2_MPTLOCK(mpt);
+	MPT_UNLOCK(mpt);
 	mpt_lprt(mpt, MPT_PRT_DEBUG, "attached cam\n");
 	return (0);
 
 cleanup:
-	CAMLOCK_2_MPTLOCK(mpt);
-cleanup0:
 	mpt_cam_detach(mpt);
 	return (error);
 }
@@ -435,6 +471,8 @@
 	    mpt->mpt_fcport_page0.WWPN.High,
 	    mpt->mpt_fcport_page0.WWPN.Low,
 	    mpt->mpt_fcport_speed);
+#if __FreeBSD_version >= 500000
+	MPT_UNLOCK(mpt);
 	{
 		struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(mpt->dev);
 		struct sysctl_oid *tree = device_get_sysctl_tree(mpt->dev);
@@ -458,6 +496,8 @@
 		       "World Wide Port Name");
 
 	}
+	MPT_LOCK(mpt);
+#endif
 	return (0);
 }
 
@@ -560,24 +600,309 @@
 	return (0);
 }
 
+static int
+mptsas_sas_io_unit_pg0(struct mpt_softc *mpt, struct mptsas_portinfo *portinfo)
+{
+	ConfigExtendedPageHeader_t hdr;
+	struct mptsas_phyinfo *phyinfo;
+	SasIOUnitPage0_t *buffer;
+	int error, len, i;
+
+	error = mpt_read_extcfg_header(mpt, MPI_SASIOUNITPAGE0_PAGEVERSION,
+				       0, 0, MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
+				       &hdr, 0, 10000);
+	if (error)
+		goto out;
+	if (hdr.ExtPageLength == 0) {
+		error = ENXIO;
+		goto out;
+	}
+
+	len = hdr.ExtPageLength * 4;
+	buffer = malloc(len, M_DEVBUF, M_NOWAIT|M_ZERO);
+	if (buffer == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+
+	error = mpt_read_extcfg_page(mpt, MPI_CONFIG_ACTION_PAGE_READ_CURRENT,
+				     0, &hdr, buffer, len, 0, 10000);
+	if (error) {
+		free(buffer, M_DEVBUF);
+		goto out;
+	}
+
+	portinfo->num_phys = buffer->NumPhys;
+	portinfo->phy_info = malloc(sizeof(*portinfo->phy_info) *
+	    portinfo->num_phys, M_DEVBUF, M_NOWAIT|M_ZERO);
+	if (portinfo->phy_info == NULL) {
+		free(buffer, M_DEVBUF);
+		error = ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < portinfo->num_phys; i++) {
+		phyinfo = &portinfo->phy_info[i];
+		phyinfo->phy_num = i;
+		phyinfo->port_id = buffer->PhyData[i].Port;
+		phyinfo->negotiated_link_rate =
+		    buffer->PhyData[i].NegotiatedLinkRate;
+		phyinfo->handle =
+		    le16toh(buffer->PhyData[i].ControllerDevHandle);
+	}
+
+	free(buffer, M_DEVBUF);
+out:
+	return (error);
+}
+
+static int
+mptsas_sas_phy_pg0(struct mpt_softc *mpt, struct mptsas_phyinfo *phy_info,
+	uint32_t form, uint32_t form_specific)
+{
+	ConfigExtendedPageHeader_t hdr;
+	SasPhyPage0_t *buffer;
+	int error;
+
+	error = mpt_read_extcfg_header(mpt, MPI_SASPHY0_PAGEVERSION, 0, 0,
+				       MPI_CONFIG_EXTPAGETYPE_SAS_PHY, &hdr,
+				       0, 10000);
+	if (error)
+		goto out;
+	if (hdr.ExtPageLength == 0) {
+		error = ENXIO;
+		goto out;
+	}
+
+	buffer = malloc(sizeof(SasPhyPage0_t), M_DEVBUF, M_NOWAIT|M_ZERO);
+	if (buffer == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+
+	error = mpt_read_extcfg_page(mpt, MPI_CONFIG_ACTION_PAGE_READ_CURRENT,
+				     form + form_specific, &hdr, buffer,
+				     sizeof(SasPhyPage0_t), 0, 10000);
+	if (error) {
+		free(buffer, M_DEVBUF);
+		goto out;
+	}
+
+	phy_info->hw_link_rate = buffer->HwLinkRate;
+	phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
+	phy_info->identify.dev_handle = le16toh(buffer->OwnerDevHandle);
+	phy_info->attached.dev_handle = le16toh(buffer->AttachedDevHandle);
+
+	free(buffer, M_DEVBUF);
+out:
+	return (error);
+}
+
+static int
+mptsas_sas_device_pg0(struct mpt_softc *mpt, struct mptsas_devinfo *device_info,
+	uint32_t form, uint32_t form_specific)
+{
+	ConfigExtendedPageHeader_t hdr;
+	SasDevicePage0_t *buffer;
+	uint64_t sas_address;
+	int error = 0;
+
+	bzero(device_info, sizeof(*device_info));
+	error = mpt_read_extcfg_header(mpt, MPI_SASDEVICE0_PAGEVERSION, 0, 0,
+				       MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE,
+				       &hdr, 0, 10000);
+	if (error)
+		goto out;
+	if (hdr.ExtPageLength == 0) {
+		error = ENXIO;
+		goto out;
+	}
+
+	buffer = malloc(sizeof(SasDevicePage0_t), M_DEVBUF, M_NOWAIT|M_ZERO);
+	if (buffer == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+
+	error = mpt_read_extcfg_page(mpt, MPI_CONFIG_ACTION_PAGE_READ_CURRENT,
+				     form + form_specific, &hdr, buffer,
+				     sizeof(SasDevicePage0_t), 0, 10000);
+	if (error) {
+		free(buffer, M_DEVBUF);
+		goto out;
+	}
+
+	device_info->dev_handle = le16toh(buffer->DevHandle);
+	device_info->parent_dev_handle = le16toh(buffer->ParentDevHandle);
+	device_info->enclosure_handle = le16toh(buffer->EnclosureHandle);
+	device_info->slot = le16toh(buffer->Slot);
+	device_info->phy_num = buffer->PhyNum;
+	device_info->physical_port = buffer->PhysicalPort;
+	device_info->target_id = buffer->TargetID;
+	device_info->bus = buffer->Bus;
+	bcopy(&buffer->SASAddress, &sas_address, sizeof(uint64_t));
+	device_info->sas_address = le64toh(sas_address);
+	device_info->device_info = le32toh(buffer->DeviceInfo);
+
+	free(buffer, M_DEVBUF);
+out:
+	return (error);
+}
+
 /*
  * Read SAS configuration information. Nothing to do yet.
  */
 static int
 mpt_read_config_info_sas(struct mpt_softc *mpt)
 {
+	struct mptsas_portinfo *portinfo;
+	struct mptsas_phyinfo *phyinfo;
+	int error, i;
+
+	portinfo = malloc(sizeof(*portinfo), M_DEVBUF, M_NOWAIT|M_ZERO);
+	if (portinfo == NULL)
+		return (ENOMEM);
+
+	error = mptsas_sas_io_unit_pg0(mpt, portinfo);
+	if (error) {
+		free(portinfo, M_DEVBUF);
+		return (0);
+	}
+
+	for (i = 0; i < portinfo->num_phys; i++) {
+		phyinfo = &portinfo->phy_info[i];
+		error = mptsas_sas_phy_pg0(mpt, phyinfo,
+		    (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
+		    MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
+		if (error)
+			break;
+		error = mptsas_sas_device_pg0(mpt, &phyinfo->identify,
+		    (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
+		    MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+		    phyinfo->handle);
+		if (error)
+			break;
+		phyinfo->identify.phy_num = phyinfo->phy_num = i;
+		if (phyinfo->attached.dev_handle)
+			error = mptsas_sas_device_pg0(mpt,
+			    &phyinfo->attached,
+			    (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
+			    MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+			    phyinfo->attached.dev_handle);
+		if (error)
+			break;
+	}
+	mpt->sas_portinfo = portinfo;
 	return (0);
 }
 
+static void
+mptsas_set_sata_wc(struct mpt_softc *mpt, struct mptsas_devinfo *devinfo,
+	int enabled)
+{
+	SataPassthroughRequest_t	*pass;
+	request_t *req;
+	int error, status;
+
+	req = mpt_get_request(mpt, 0);
+	if (req == NULL)
+		return;
+
+	pass = req->req_vbuf;
+	bzero(pass, sizeof(SataPassthroughRequest_t));
+	pass->Function = MPI_FUNCTION_SATA_PASSTHROUGH;
+	pass->TargetID = devinfo->target_id;
+	pass->Bus = devinfo->bus;
+	pass->PassthroughFlags = 0;
+	pass->ConnectionRate = MPI_SATA_PT_REQ_CONNECT_RATE_NEGOTIATED;
+	pass->DataLength = 0;
+	pass->MsgContext = htole32(req->index | sata_pass_handler_id);
+	pass->CommandFIS[0] = 0x27;
+	pass->CommandFIS[1] = 0x80;
+	pass->CommandFIS[2] = 0xef;
+	pass->CommandFIS[3] = (enabled) ? 0x02 : 0x82;
+	pass->CommandFIS[7] = 0x40;
+	pass->CommandFIS[15] = 0x08;
+
+	mpt_check_doorbell(mpt);
+	mpt_send_cmd(mpt, req);
+	error = mpt_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE, 0,
+			     10 * 1000);
+	if (error) {
+		mpt_free_request(mpt, req);
+		printf("error %d sending passthrough\n", error);
+		return;
+	}
+
+	status = le16toh(req->IOCStatus);
+	if (status != MPI_IOCSTATUS_SUCCESS) {
+		mpt_free_request(mpt, req);
+		printf("IOCSTATUS %d\n", status);
+		return;
+	}
+
+	mpt_free_request(mpt, req);
+}
+
 /*
  * Set SAS configuration information. Nothing to do yet.
  */
 static int
 mpt_set_initial_config_sas(struct mpt_softc *mpt)
 {
+	struct mptsas_phyinfo *phyinfo;
+	int i;
+
+	if ((mpt_enable_sata_wc != -1) && (mpt->sas_portinfo != NULL)) {
+		for (i = 0; i < mpt->sas_portinfo->num_phys; i++) {
+			phyinfo = &mpt->sas_portinfo->phy_info[i];
+			if (phyinfo->attached.dev_handle == 0)
+				continue;
+			if ((phyinfo->attached.device_info &
+			    MPI_SAS_DEVICE_INFO_SATA_DEVICE) == 0)
+				continue;
+			if (bootverbose)
+				device_printf(mpt->dev,
+				    "%sabling SATA WC on phy %d\n",
+				    (mpt_enable_sata_wc) ? "En" : "Dis", i);
+			mptsas_set_sata_wc(mpt, &phyinfo->attached,
+					   mpt_enable_sata_wc);
+		}
+	}
+
 	return (0);
 }
 
+static int
+mpt_sata_pass_reply_handler(struct mpt_softc *mpt, request_t *req,
+ uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
+{
+	if (req != NULL) {
+
+		if (reply_frame != NULL) {
+			MSG_SATA_PASSTHROUGH_REQUEST *pass;
+			MSG_SATA_PASSTHROUGH_REPLY *reply;
+
+			pass = (MSG_SATA_PASSTHROUGH_REQUEST *)req->req_vbuf;
+			reply = (MSG_SATA_PASSTHROUGH_REPLY *)reply_frame;
+			req->IOCStatus = le16toh(reply_frame->IOCStatus);
+		}
+		req->state &= ~REQ_STATE_QUEUED;
+		req->state |= REQ_STATE_DONE;
+		TAILQ_REMOVE(&mpt->request_pending_list, req, links);
+		if ((req->state & REQ_STATE_NEED_WAKEUP) != 0) {
+			wakeup(req);
+		} else if ((req->state & REQ_STATE_TIMEDOUT) != 0) {
+			/*
+			 * Whew- we can free this request (late completion)
+			 */
+			mpt_free_request(mpt, req);
+		}
+	}
+
+	return (TRUE);
+}
+
 /*
  * Read SCSI configuration information
  */
@@ -656,7 +981,7 @@
 	if (rv) {
 		mpt_prt(mpt, "failed to read SPI Port Page 0\n");
 	} else {
-		mpt_lprt(mpt, MPT_PRT_DEBUG,
+		mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
 		    "SPI Port Page 0: Capabilities %x PhysicalInterface %x\n",
 		    mpt->mpt_port_page0.Capabilities,
 		    mpt->mpt_port_page0.PhysicalInterface);
@@ -789,29 +1114,38 @@
 int
 mpt_cam_enable(struct mpt_softc *mpt)
 {
+	int error;
+
+	MPT_LOCK(mpt);
+
+	error = EIO;
 	if (mpt->is_fc) {
 		if (mpt_read_config_info_fc(mpt)) {
-			return (EIO);
+			goto out;
 		}
 		if (mpt_set_initial_config_fc(mpt)) {
-			return (EIO);
+			goto out;
 		}
 	} else if (mpt->is_sas) {
 		if (mpt_read_config_info_sas(mpt)) {
-			return (EIO);
+			goto out;
 		}
 		if (mpt_set_initial_config_sas(mpt)) {
-			return (EIO);
+			goto out;
 		}
 	} else if (mpt->is_spi) {
 		if (mpt_read_config_info_spi(mpt)) {
-			return (EIO);
+			goto out;
 		}
 		if (mpt_set_initial_config_spi(mpt)) {
-			return (EIO);
+			goto out;
 		}
 	}
-	return (0);
+	error = 0;
+
+out:
+	MPT_UNLOCK(mpt);
+	return (error);
 }
 
 void
@@ -831,6 +1165,7 @@
 		}
 		MPT_UNLOCK(mpt);
 	}
+	mpt->ready = 1;
 }
 
 void
@@ -838,6 +1173,8 @@
 {
 	mpt_handler_t handler;
 
+	MPT_LOCK(mpt);
+	mpt->ready = 0;
 	mpt_terminate_recovery_thread(mpt); 
 
 	handler.reply_handler = mpt_scsi_reply_handler;
@@ -852,29 +1189,33 @@
 	handler.reply_handler = mpt_scsi_tgt_reply_handler;
 	mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
 			       mpt->scsi_tgt_handler_id);
+	handler.reply_handler = mpt_sata_pass_reply_handler;
+	mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
+			       sata_pass_handler_id);
 
 	if (mpt->tmf_req != NULL) {
 		mpt->tmf_req->state = REQ_STATE_ALLOCATED;
 		mpt_free_request(mpt, mpt->tmf_req);
 		mpt->tmf_req = NULL;
 	}
+	if (mpt->sas_portinfo != NULL) {
+		free(mpt->sas_portinfo, M_DEVBUF);
+		mpt->sas_portinfo = NULL;
+	}
+	MPT_UNLOCK(mpt);
 
 	if (mpt->sim != NULL) {
-		MPTLOCK_2_CAMLOCK(mpt);
 		xpt_free_path(mpt->path);
 		xpt_bus_deregister(cam_sim_path(mpt->sim));
 		cam_sim_free(mpt->sim, TRUE);
 		mpt->sim = NULL;
-		CAMLOCK_2_MPTLOCK(mpt);
 	}
 
 	if (mpt->phydisk_sim != NULL) {
-		MPTLOCK_2_CAMLOCK(mpt);
 		xpt_free_path(mpt->phydisk_path);
 		xpt_bus_deregister(cam_sim_path(mpt->phydisk_sim));
 		cam_sim_free(mpt->phydisk_sim, TRUE);
 		mpt->phydisk_sim = NULL;
-		CAMLOCK_2_MPTLOCK(mpt);
 	}
 }
 
@@ -886,9 +1227,7 @@
 	struct mpt_softc *mpt;
 
 	mpt = (struct mpt_softc *)cam_sim_softc(sim);
-	MPT_LOCK(mpt);
 	mpt_intr(mpt);
-	MPT_UNLOCK(mpt);
 }
 
 /*
@@ -1032,6 +1371,7 @@
 		MPI_pSGE_SET_FLAGS(se1,
 		    (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
 		    MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
+		se1->FlagsLength = htole32(se1->FlagsLength);
 		goto out;
 	}
 
@@ -1089,7 +1429,7 @@
 		uint32_t tf;
 
 		memset(se, 0, sizeof (*se));
-		se->Address.Low = dm_segs->ds_addr;
+		se->Address.Low = htole32(dm_segs->ds_addr & 0xffffffff);
 		if (sizeof(bus_addr_t) > 4) {
 			se->Address.High = ((uint64_t) dm_segs->ds_addr) >> 32;
 		}
@@ -1103,6 +1443,7 @@
 				MPI_SGE_FLAGS_END_OF_BUFFER;
 		}
 		MPI_pSGE_SET_FLAGS(se, tf);
+		se->FlagsLength = htole32(se->FlagsLength);
 	}
 
 	if (seg == nseg) {
@@ -1165,9 +1506,9 @@
 		chain_list_addr += cur_off;
 		if (sizeof (bus_addr_t) > 4) {
 			ce->Address.High =
-			    (uint32_t) ((uint64_t)chain_list_addr >> 32);
+			    htole32((uint32_t) ((uint64_t)chain_list_addr >> 32));
 		}
-		ce->Address.Low = (uint32_t) chain_list_addr;
+		ce->Address.Low = htole32((uint32_t) chain_list_addr);
 		ce->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT |
 			    MPI_SGE_FLAGS_64_BIT_ADDRESSING;
 
@@ -1204,10 +1545,10 @@
 		 */
 		while (seg < this_seg_lim) {
 			memset(se, 0, sizeof (*se));
-			se->Address.Low = dm_segs->ds_addr;
+			se->Address.Low = htole32(dm_segs->ds_addr);
 			if (sizeof (bus_addr_t) > 4) {
 				se->Address.High =
-				    ((uint64_t)dm_segs->ds_addr) >> 32;
+				    htole32(((uint64_t)dm_segs->ds_addr) >> 32);
 			}
 			MPI_pSGE_SET_LENGTH(se, dm_segs->ds_len);
 			tf = flags;
@@ -1219,6 +1560,7 @@
 					MPI_SGE_FLAGS_END_OF_BUFFER;
 			}
 			MPI_pSGE_SET_FLAGS(se, tf);
+			se->FlagsLength = htole32(se->FlagsLength);
 			se++;
 			seg++;
 			dm_segs++;
@@ -1291,11 +1633,8 @@
 
 	ccb->ccb_h.status |= CAM_SIM_QUEUED;
 	if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
-		ccb->ccb_h.timeout_ch =
-			timeout(mpt_timeout, (caddr_t)ccb,
-				(ccb->ccb_h.timeout * hz) / 1000);
-	} else {
-		callout_handle_init(&ccb->ccb_h.timeout_ch);
+		mpt_req_timeout(req, (ccb->ccb_h.timeout * hz) / 1000,
+		    mpt_timeout, ccb);
 	}
 	if (mpt->verbose > MPT_PRT_DEBUG) {
 		int nc = 0;
@@ -1432,6 +1771,7 @@
 		MPI_pSGE_SET_FLAGS(se1,
 		    (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
 		    MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
+		se1->FlagsLength = htole32(se1->FlagsLength);
 		goto out;
 	}
 
@@ -1503,6 +1843,7 @@
 				MPI_SGE_FLAGS_END_OF_BUFFER;
 		}
 		MPI_pSGE_SET_FLAGS(se, tf);
+		se->FlagsLength = htole32(se->FlagsLength);
 	}
 
 	if (seg == nseg) {
@@ -1618,6 +1959,7 @@
 					MPI_SGE_FLAGS_END_OF_BUFFER;
 			}
 			MPI_pSGE_SET_FLAGS(se, tf);
+			se->FlagsLength = htole32(se->FlagsLength);
 			se++;
 			seg++;
 			dm_segs++;
@@ -1690,11 +2032,8 @@
 
 	ccb->ccb_h.status |= CAM_SIM_QUEUED;
 	if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
-		ccb->ccb_h.timeout_ch =
-			timeout(mpt_timeout, (caddr_t)ccb,
-				(ccb->ccb_h.timeout * hz) / 1000);
-	} else {
-		callout_handle_init(&ccb->ccb_h.timeout_ch);
+		mpt_req_timeout(req, (ccb->ccb_h.timeout * hz) / 1000,
+		    mpt_timeout, ccb);
 	}
 	if (mpt->verbose > MPT_PRT_DEBUG) {
 		int nc = 0;
@@ -1862,19 +2201,21 @@
 	}
 
 	mpt_req->CDBLength = csio->cdb_len;
-	mpt_req->DataLength = csio->dxfer_len;
-	mpt_req->SenseBufferLowAddr = req->sense_pbuf;
+	mpt_req->DataLength = htole32(csio->dxfer_len);
+	mpt_req->SenseBufferLowAddr = htole32(req->sense_pbuf);
 
 	/*
 	 * Do a *short* print here if we're set to MPT_PRT_DEBUG
 	 */
 	if (mpt->verbose == MPT_PRT_DEBUG) {
+		U32 df;
 		mpt_prt(mpt, "mpt_start: %s op 0x%x ",
 		    (mpt_req->Function == MPI_FUNCTION_SCSI_IO_REQUEST)?
 		    "SCSI_IO_REQUEST" : "SCSI_IO_PASSTHRU", mpt_req->CDB[0]);
-		if (mpt_req->Control != MPI_SCSIIO_CONTROL_NODATATRANSFER) {
+		df = mpt_req->Control & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
+		if (df != MPI_SCSIIO_CONTROL_NODATATRANSFER) {
 			mpt_prtc(mpt, "(%s %u byte%s ",
-			    (mpt_req->Control == MPI_SCSIIO_CONTROL_READ)?
+			    (df == MPI_SCSIIO_CONTROL_READ)?
 			    "read" : "write",  csio->dxfer_len,
 			    (csio->dxfer_len == 1)? ")" : "s)");
 		}
@@ -2034,17 +2375,20 @@
 mpt_cam_event(struct mpt_softc *mpt, request_t *req,
 	      MSG_EVENT_NOTIFY_REPLY *msg)
 {
+	uint32_t data0, data1;
 
+	data0 = le32toh(msg->Data[0]);
+	data1 = le32toh(msg->Data[1]);
 	switch(msg->Event & 0xFF) {
 	case MPI_EVENT_UNIT_ATTENTION:
 		mpt_prt(mpt, "UNIT ATTENTION: Bus: 0x%02x TargetID: 0x%02x\n",
-		    (msg->Data[0] >> 8) & 0xff, msg->Data[0] & 0xff);
+		    (data0 >> 8) & 0xff, data0 & 0xff);
 		break;
 
 	case MPI_EVENT_IOC_BUS_RESET:
 		/* We generated a bus reset */
 		mpt_prt(mpt, "IOC Generated Bus Reset Port: %d\n",
-		    (msg->Data[0] >> 8) & 0xff);
+		    (data0 >> 8) & 0xff);
 		xpt_async(AC_BUS_RESET, mpt->path, NULL);
 		break;
 
@@ -2059,88 +2403,120 @@
 		break;
 
 	case MPI_EVENT_RESCAN:
+#if __FreeBSD_version >= 600000
+	{
+		union ccb *ccb;
+		uint32_t pathid;
 		/*
 		 * In general this means a device has been added to the loop.
 		 */
-		mpt_prt(mpt, "Rescan Port: %d\n", (msg->Data[0] >> 8) & 0xff);
-/*		xpt_async(AC_FOUND_DEVICE, path, NULL);  */
-		break;
+		mpt_prt(mpt, "Rescan Port: %d\n", (data0 >> 8) & 0xff);
+		if (mpt->ready == 0) {
+			break;
+		}
+		if (mpt->phydisk_sim) {
+			pathid = cam_sim_path(mpt->phydisk_sim);
+		} else {
+			pathid = cam_sim_path(mpt->sim);
+		}
+		MPTLOCK_2_CAMLOCK(mpt);
+		/*
+		 * Allocate a CCB, create a wildcard path for this bus,
+		 * and schedule a rescan.
+		 */
+		ccb = xpt_alloc_ccb_nowait();
+		if (ccb == NULL) {
+			mpt_prt(mpt, "unable to alloc CCB for rescan\n");
+			CAMLOCK_2_MPTLOCK(mpt);
+			break;
+		}
 
+		if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, pathid,
+		    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+			CAMLOCK_2_MPTLOCK(mpt);
+			mpt_prt(mpt, "unable to create path for rescan\n");
+			xpt_free_ccb(ccb);
+			break;
+		}
+		xpt_rescan(ccb);
+		CAMLOCK_2_MPTLOCK(mpt);
+		break;
+	}
+#else
+		mpt_prt(mpt, "Rescan Port: %d\n", (data0 >> 8) & 0xff);
+		break;
+#endif
 	case MPI_EVENT_LINK_STATUS_CHANGE:
 		mpt_prt(mpt, "Port %d: LinkState: %s\n",
-		    (msg->Data[1] >> 8) & 0xff,
-		    ((msg->Data[0] & 0xff) == 0)?  "Failed" : "Active");
+		    (data1 >> 8) & 0xff,
+		    ((data0 & 0xff) == 0)?  "Failed" : "Active");
 		break;
 
 	case MPI_EVENT_LOOP_STATE_CHANGE:
-		switch ((msg->Data[0] >> 16) & 0xff) {
+		switch ((data0 >> 16) & 0xff) {
 		case 0x01:
 			mpt_prt(mpt,
 			    "Port 0x%x: FC LinkEvent: LIP(%02x,%02x) "
 			    "(Loop Initialization)\n",
-			    (msg->Data[1] >> 8) & 0xff,
-			    (msg->Data[0] >> 8) & 0xff,
-			    (msg->Data[0]     ) & 0xff);
-			switch ((msg->Data[0] >> 8) & 0xff) {
+			    (data1 >> 8) & 0xff,
+			    (data0 >> 8) & 0xff,
+			    (data0     ) & 0xff);
+			switch ((data0 >> 8) & 0xff) {
 			case 0xF7:
-				if ((msg->Data[0] & 0xff) == 0xF7) {
+				if ((data0 & 0xff) == 0xF7) {
 					mpt_prt(mpt, "Device needs AL_PA\n");
 				} else {
 					mpt_prt(mpt, "Device %02x doesn't like "
 					    "FC performance\n",
-					    msg->Data[0] & 0xFF);
+					    data0 & 0xFF);
 				}
 				break;
 			case 0xF8:
-				if ((msg->Data[0] & 0xff) == 0xF7) {
+				if ((data0 & 0xff) == 0xF7) {
 					mpt_prt(mpt, "Device had loop failure "
 					    "at its receiver prior to acquiring"
 					    " AL_PA\n");
 				} else {
 					mpt_prt(mpt, "Device %02x detected loop"
 					    " failure at its receiver\n", 
-					    msg->Data[0] & 0xFF);
+					    data0 & 0xFF);
 				}
 				break;
 			default:
 				mpt_prt(mpt, "Device %02x requests that device "
 				    "%02x reset itself\n", 
-				    msg->Data[0] & 0xFF,
-				    (msg->Data[0] >> 8) & 0xFF);
+				    data0 & 0xFF,
+				    (data0 >> 8) & 0xFF);
 				break;
 			}
 			break;
 		case 0x02:
 			mpt_prt(mpt, "Port 0x%x: FC LinkEvent: "
 			    "LPE(%02x,%02x) (Loop Port Enable)\n",
-			    (msg->Data[1] >> 8) & 0xff, /* Port */
-			    (msg->Data[0] >>  8) & 0xff, /* Character 3 */
-			    (msg->Data[0]      ) & 0xff  /* Character 4 */);
+			    (data1 >> 8) & 0xff, /* Port */
+			    (data0 >>  8) & 0xff, /* Character 3 */
+			    (data0      ) & 0xff  /* Character 4 */);
 			break;
 		case 0x03:
 			mpt_prt(mpt, "Port 0x%x: FC LinkEvent: "
 			    "LPB(%02x,%02x) (Loop Port Bypass)\n",
-			    (msg->Data[1] >> 8) & 0xff, /* Port */
-			    (msg->Data[0] >> 8) & 0xff, /* Character 3 */
-			    (msg->Data[0]     ) & 0xff  /* Character 4 */);
+			    (data1 >> 8) & 0xff, /* Port */
+			    (data0 >> 8) & 0xff, /* Character 3 */
+			    (data0     ) & 0xff  /* Character 4 */);
 			break;
 		default:
 			mpt_prt(mpt, "Port 0x%x: FC LinkEvent: Unknown "
 			    "FC event (%02x %02x %02x)\n",
-			    (msg->Data[1] >> 8) & 0xff, /* Port */
-			    (msg->Data[0] >> 16) & 0xff, /* Event */
-			    (msg->Data[0] >>  8) & 0xff, /* Character 3 */
-			    (msg->Data[0]      ) & 0xff  /* Character 4 */);
+			    (data1 >> 8) & 0xff, /* Port */
+			    (data0 >> 16) & 0xff, /* Event */
+			    (data0 >>  8) & 0xff, /* Character 3 */
+			    (data0      ) & 0xff  /* Character 4 */);
 		}
 		break;
 
 	case MPI_EVENT_LOGOUT:
 		mpt_prt(mpt, "FC Logout Port: %d N_PortID: %02x\n",
-		    (msg->Data[1] >> 8) & 0xff, msg->Data[0]);
-		break;
-	case MPI_EVENT_EVENT_CHANGE:
-		mpt_lprt(mpt, MPT_PRT_DEBUG,
-		    "mpt_cam_event: MPI_EVENT_EVENT_CHANGE\n");
+		    (data1 >> 8) & 0xff, data0);
 		break;
 	case MPI_EVENT_QUEUE_FULL:
 	{
@@ -2180,18 +2556,11 @@
 		CAMLOCK_2_MPTLOCK(mpt);
 		break;
 	}
+	case MPI_EVENT_EVENT_CHANGE:
+	case MPI_EVENT_INTEGRATED_RAID:
 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
-	{
-		mpt_lprt(mpt, MPT_PRT_DEBUG,
-		    "mpt_cam_event: SAS_DEVICE_STATUS_CHANGE\n");
-		break;
-	}
 	case MPI_EVENT_SAS_SES:
-	{
-		mpt_lprt(mpt, MPT_PRT_DEBUG,
-		    "mpt_cam_event: MPI_EVENT_SAS_SES\n");
 		break;
-	}
 	default:
 		mpt_lprt(mpt, MPT_PRT_WARN, "mpt_cam_event: 0x%x\n",
 		    msg->Event & 0xFF);
@@ -2232,7 +2601,7 @@
 	}
 
 	tgt = scsi_req->TargetID;
-	untimeout(mpt_timeout, ccb, ccb->ccb_h.timeout_ch);
+	mpt_req_untimeout(req, mpt_timeout, ccb);
 	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
 
 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
@@ -2314,7 +2683,7 @@
 	req->IOCStatus = le16toh(tmf_reply->IOCStatus);
 	req->ResponseCode = tmf_reply->ResponseCode;
 
-	mpt_lprt(mpt, MPT_PRT_INFO, "TMF complete: req %p:%u status 0x%x\n",
+	mpt_lprt(mpt, MPT_PRT_DEBUG, "TMF complete: req %p:%u status 0x%x\n",
 	    req, req->serno, le16toh(tmf_reply->IOCStatus));
 	TAILQ_REMOVE(&mpt->request_pending_list, req, links);
 	if ((req->state & REQ_STATE_NEED_WAKEUP) != 0) {
@@ -2348,6 +2717,7 @@
 mpt_fc_els_send_response(struct mpt_softc *mpt, request_t *req,
     PTR_MSG_LINK_SERVICE_BUFFER_POST_REPLY rp, U8 length)
 {
+	uint32_t fl;
 	MSG_LINK_SERVICE_RSP_REQUEST tmp;
 	PTR_MSG_LINK_SERVICE_RSP_REQUEST rsp;
 
@@ -2387,15 +2757,16 @@
 	bus_addr_t paddr = req->req_pbuf;
 	paddr += MPT_RQSL(mpt);
 
-	se->FlagsLength =
+	fl =
 		MPI_SGE_FLAGS_HOST_TO_IOC	|
 		MPI_SGE_FLAGS_SIMPLE_ELEMENT	|
 		MPI_SGE_FLAGS_LAST_ELEMENT	|
 		MPI_SGE_FLAGS_END_OF_LIST	|
 		MPI_SGE_FLAGS_END_OF_BUFFER;
-	se->FlagsLength <<= MPI_SGE_FLAGS_SHIFT;
-	se->FlagsLength |= (length);
-	se->Address = (uint32_t) paddr;
+	fl <<= MPI_SGE_FLAGS_SHIFT;
+	fl |= (length);
+	se->FlagsLength = htole32(fl);
+	se->Address = htole32((uint32_t) paddr);
 }
 #endif
 
@@ -2853,12 +3224,13 @@
 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("mpt_action\n"));
 
 	mpt = (struct mpt_softc *)cam_sim_softc(sim);
-	KASSERT(MPT_OWNED(mpt) == 0, ("mpt owned on entrance to mpt_action"));
 	raid_passthru = (sim == mpt->phydisk_sim);
+	MPT_LOCK_ASSERT(mpt);
 
 	tgt = ccb->ccb_h.target_id;
 	lun = ccb->ccb_h.target_lun;
-	if (raid_passthru && ccb->ccb_h.func_code != XPT_PATH_INQ &&
+	if (raid_passthru &&
+	    ccb->ccb_h.func_code != XPT_PATH_INQ &&
 	    ccb->ccb_h.func_code != XPT_RESET_BUS &&
 	    ccb->ccb_h.func_code != XPT_RESET_DEV) {
 		CAMLOCK_2_MPTLOCK(mpt);
@@ -2893,16 +3265,31 @@
 			mpt_set_ccb_status(ccb, CAM_REQ_INVALID);
 			break;
 		}
+#ifdef	MPT_TEST_MULTIPATH
+		if (mpt->failure_id == ccb->ccb_h.target_id) {
+			ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
+			mpt_set_ccb_status(ccb, CAM_SEL_TIMEOUT);
+			break;
+		}
+#endif
 		ccb->csio.scsi_status = SCSI_STATUS_OK;
 		mpt_start(sim, ccb);
 		return;
 
 	case XPT_RESET_BUS:
+		if (raid_passthru) {
+			ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
+			mpt_set_ccb_status(ccb, CAM_REQ_CMP);
+			break;
+		}
 	case XPT_RESET_DEV:
-		mpt_lprt(mpt, MPT_PRT_DEBUG,
-			ccb->ccb_h.func_code == XPT_RESET_BUS ?
-			"XPT_RESET_BUS\n" : "XPT_RESET_DEV\n");
-
+		if (ccb->ccb_h.func_code == XPT_RESET_BUS) {
+			if (bootverbose) {
+				xpt_print(ccb->ccb_h.path, "reset bus\n");
+			}
+		} else {
+			xpt_print(ccb->ccb_h.path, "reset device\n");
+		}
 		CAMLOCK_2_MPTLOCK(mpt);
 		(void) mpt_bus_reset(mpt, tgt, lun, FALSE);
 		MPTLOCK_2_CAMLOCK(mpt);
@@ -2977,6 +3364,19 @@
 			break;
 		}
 
+#ifdef	CAM_NEW_TRAN_CODE
+		scsi = &cts->proto_specific.scsi;
+		spi = &cts->xport_specific.spi;
+
+		/*
+		 * We can be called just to valid transport and proto versions
+		 */
+		if (scsi->valid == 0 && spi->valid == 0) {
+			mpt_set_ccb_status(ccb, CAM_REQ_CMP);
+			break;
+		}
+#endif
+
 		/*
 		 * Skip attempting settings on RAID volume disks.
 		 * Other devices on the bus get the normal treatment.
@@ -2984,7 +3384,7 @@
 		if (mpt->phydisk_sim && raid_passthru == 0 &&
 		    mpt_is_raid_volume(mpt, tgt) != 0) {
 			mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
-			    "skipping transfer settings for RAID volumes\n");
+			    "no transfer settings for RAID vols\n");
 			mpt_set_ccb_status(ccb, CAM_REQ_CMP);
 			break;
 		}
@@ -3027,16 +3427,13 @@
 			offset = cts->sync_offset;
 		}
 #else
-		scsi = &cts->proto_specific.scsi;
-		spi = &cts->xport_specific.spi;
-
 		if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
-			dval |= (spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) ?
+			dval |= ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) ?
 			    DP_DISC_ENABLE : DP_DISC_DISABL;
 		}
 
 		if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
-			dval |= (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) ?
+			dval |= ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) ?
 			    DP_TQING_ENABLE : DP_TQING_DISABL;
 		}
 
@@ -3045,12 +3442,25 @@
 			    DP_WIDE : DP_NARROW;
 		}
 
-		if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) &&
-		    (spi->valid & CTS_SPI_VALID_SYNC_RATE) &&
-		    (spi->sync_period && spi->sync_offset)) {
+		if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
 			dval |= DP_SYNC;
-			period = spi->sync_period;
 			offset = spi->sync_offset;
+		} else {
+			PTR_CONFIG_PAGE_SCSI_DEVICE_1 ptr =
+			    &mpt->mpt_dev_page1[tgt];
+			offset = ptr->RequestedParameters;
+			offset &= MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK;
+	    		offset >>= MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET;
+		}
+		if (spi->valid & CTS_SPI_VALID_SYNC_RATE) {
+			dval |= DP_SYNC;
+			period = spi->sync_period;
+		} else {
+			PTR_CONFIG_PAGE_SCSI_DEVICE_1 ptr =
+			    &mpt->mpt_dev_page1[tgt];
+			period = ptr->RequestedParameters;
+			period &= MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK;
+	    		period >>= MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD;
 		}
 #endif
 		CAMLOCK_2_MPTLOCK(mpt);
@@ -3070,7 +3480,14 @@
 		if (dval & DP_SYNC) {
 			mpt_setsync(mpt, tgt, period, offset);
 		}
-
+		if (dval == 0) {
+			MPTLOCK_2_CAMLOCK(mpt);
+			mpt_set_ccb_status(ccb, CAM_REQ_CMP);
+			break;
+		}
+		mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
+		    "set [%d]: 0x%x period 0x%x offset %d\n",
+		    tgt, dval, period, offset);
 		if (mpt_update_spi_config(mpt, tgt)) {
 			mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
 		} else {
@@ -3080,66 +3497,57 @@
 		break;
 	}
 	case XPT_GET_TRAN_SETTINGS:
+	{
+#ifdef	CAM_NEW_TRAN_CODE
+		struct ccb_trans_settings_scsi *scsi;
 		cts = &ccb->cts;
+		cts->protocol = PROTO_SCSI;
 		if (mpt->is_fc) {
-#ifndef	CAM_NEW_TRAN_CODE
-			/*
-			 * a lot of normal SCSI things don't make sense.
-			 */
-			cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
-			cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
-			/*
-			 * How do you measure the width of a high
-			 * speed serial bus? Well, in bytes.
-			 *
-			 * Offset and period make no sense, though, so we set
-			 * (above) a 'base' transfer speed to be gigabit.
-			 */
-			cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
-#else
 			struct ccb_trans_settings_fc *fc =
 			    &cts->xport_specific.fc;
-
-			cts->protocol = PROTO_SCSI;
-			cts->protocol_version = SCSI_REV_2;
+			cts->protocol_version = SCSI_REV_SPC;
 			cts->transport = XPORT_FC;
 			cts->transport_version = 0;
-
 			fc->valid = CTS_FC_VALID_SPEED;
-			fc->bitrate = 100000;	/* XXX: Need for 2Gb/s */
-			/* XXX: need a port database for each target */
-#endif
+			fc->bitrate = 100000;
 		} else if (mpt->is_sas) {
-#ifndef	CAM_NEW_TRAN_CODE
-			cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
-			cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
-			/*
-			 * How do you measure the width of a high
-			 * speed serial bus? Well, in bytes.
-			 *
-			 * Offset and period make no sense, though, so we set
-			 * (above) a 'base' transfer speed to be gigabit.
-			 */
-			cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
-#else
 			struct ccb_trans_settings_sas *sas =
 			    &cts->xport_specific.sas;
-
-			cts->protocol = PROTO_SCSI;
-			cts->protocol_version = SCSI_REV_3;
+			cts->protocol_version = SCSI_REV_SPC2;
 			cts->transport = XPORT_SAS;
 			cts->transport_version = 0;
-
 			sas->valid = CTS_SAS_VALID_SPEED;
-			sas->bitrate = 300000;	/* XXX: Default 3Gbps */
-#endif
+			sas->bitrate = 300000;
+		} else {
+			cts->protocol_version = SCSI_REV_2;
+			cts->transport = XPORT_SPI;
+			cts->transport_version = 2;
+			if (mpt_get_spi_settings(mpt, cts) != 0) {
+				mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
+				break;
+			}
+		}
+		scsi = &cts->proto_specific.scsi;
+		scsi->valid = CTS_SCSI_VALID_TQ;
+		scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
+#else
+		cts = &ccb->cts;
+		if (mpt->is_fc) {
+			cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
+			cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
+			cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
+		} else if (mpt->is_sas) {
+			cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
+			cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
+			cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
 		} else if (mpt_get_spi_settings(mpt, cts) != 0) {
 			mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
 			break;
 		}
+#endif
 		mpt_set_ccb_status(ccb, CAM_REQ_CMP);
 		break;
-
+	}
 	case XPT_CALC_GEOMETRY:
 	{
 		struct ccb_calc_geometry *ccg;
@@ -3161,56 +3569,79 @@
 		cpi->version_num = 1;
 		cpi->target_sprt = 0;
 		cpi->hba_eng_cnt = 0;
-		cpi->max_target = mpt->mpt_max_devices - 1;
+		cpi->max_target = mpt->port_facts[0].MaxDevices - 1;
 		/*
-		 * XXX: FC cards report MAX_DEVICES of 512- but we
-		 * XXX: seem to hang when going higher than 255.
+		 * FC cards report MAX_DEVICES of 512, but
+		 * the MSG_SCSI_IO_REQUEST target id field
+		 * is only 8 bits. Until we fix the driver
+		 * to support 'channels' for bus overflow,
+		 * just limit it.
 		 */
-		if (cpi->max_target > 255)
+		if (cpi->max_target > 255) {
 			cpi->max_target = 255;
+		}
+
 		/*
-		 * XXX: VMware ESX reports > 16 devices and then dies
-		 * XXX: when we probe.
+		 * VMware ESX reports > 16 devices and then dies when we probe.
 		 */
-		if (mpt->is_spi && cpi->max_target > 15)
+		if (mpt->is_spi && cpi->max_target > 15) {
 			cpi->max_target = 15;
+		}
 		cpi->max_lun = 7;
 		cpi->initiator_id = mpt->mpt_ini_id;
-
 		cpi->bus_id = cam_sim_bus(sim);
+
 		/*
-		 * Actual speed for each device varies.
-		 *
 		 * The base speed is the speed of the underlying connection.
-		 * This is strictly determined for SPI (async, narrow). If
-		 * link is up for Fibre Channel, then speed can be gotten
-		 * from that.
 		 */
+#ifdef	CAM_NEW_TRAN_CODE
+		cpi->protocol = PROTO_SCSI;
 		if (mpt->is_fc) {
 			cpi->hba_misc = PIM_NOBUSRESET;
-			cpi->base_transfer_speed =
-			    mpt->mpt_fcport_speed * 100000;
+			cpi->base_transfer_speed = 100000;
 			cpi->hba_inquiry = PI_TAG_ABLE;
+			cpi->transport = XPORT_FC;
+			cpi->transport_version = 0;
+			cpi->protocol_version = SCSI_REV_SPC;
 		} else if (mpt->is_sas) {
 			cpi->hba_misc = PIM_NOBUSRESET;
 			cpi->base_transfer_speed = 300000;
 			cpi->hba_inquiry = PI_TAG_ABLE;
+			cpi->transport = XPORT_SAS;
+			cpi->transport_version = 0;
+			cpi->protocol_version = SCSI_REV_SPC2;
 		} else {
 			cpi->hba_misc = PIM_SEQSCAN;
 			cpi->base_transfer_speed = 3300;
 			cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
+			cpi->transport = XPORT_SPI;
+			cpi->transport_version = 2;
+			cpi->protocol_version = SCSI_REV_2;
 		}
+#else
+		if (mpt->is_fc) {
+			cpi->hba_misc = PIM_NOBUSRESET;
+			cpi->base_transfer_speed = 100000;
+			cpi->hba_inquiry = PI_TAG_ABLE;
+		} else if (mpt->is_sas) {
+			cpi->hba_misc = PIM_NOBUSRESET;
+			cpi->base_transfer_speed = 300000;
+			cpi->hba_inquiry = PI_TAG_ABLE;
+		} else {
+			cpi->hba_misc = PIM_SEQSCAN;
+			cpi->base_transfer_speed = 3300;
+			cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
+		}
+#endif
 
 		/*
 		 * We give our fake RAID passhtru bus a width that is MaxVolumes
-		 * wide, restrict it to one lun and have it *not* be a bus
-		 * that can have a SCSI bus reset.
+		 * wide and restrict it to one lun.
 		 */
 		if (raid_passthru) {
 			cpi->max_target = mpt->ioc_page2->MaxPhysDisks - 1;
 			cpi->initiator_id = cpi->max_target + 1;
 			cpi->max_lun = 0;
-			cpi->hba_misc |= PIM_NOBUSRESET;
 		}
 
 		if ((mpt->role & MPT_ROLE_INITIATOR) == 0) {
@@ -3309,10 +3740,12 @@
 	struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
 #endif
 	target_id_t tgt;
-	uint8_t dval, pval, oval;
+	uint32_t dval, pval, oval;
 	int rv;
 
-	if (xpt_path_sim(cts->ccb_h.path) == mpt->phydisk_sim) {
+	if (IS_CURRENT_SETTINGS(cts) == 0) {
+		tgt = cts->ccb_h.target_id;
+	} else if (xpt_path_sim(cts->ccb_h.path) == mpt->phydisk_sim) {
 		if (mpt_map_physdisk(mpt, (union ccb *)cts, &tgt)) {
 			return (-1);
 		}
@@ -3321,8 +3754,10 @@
 	}
 
 	/*
-	 * XXX: We aren't looking Port Page 2 BIOS settings here.
-	 * XXX: For goal settings, we pick the max from port page 0
+	 * We aren't looking at Port Page 2 BIOS settings here-
+	 * sometimes these have been known to be bogus XXX.
+	 *
+	 * For user settings, we pick the max from port page 0
 	 * 
 	 * For current settings we read the current settings out from
 	 * device page 0 for that target.
@@ -3341,64 +3776,61 @@
 			return (rv);
 		}
 		MPTLOCK_2_CAMLOCK(mpt);
+		mpt_lprt(mpt, MPT_PRT_DEBUG,
+		    "mpt_get_spi_settings[%d]: current NP %x Info %x\n", tgt,
+		    tmp.NegotiatedParameters, tmp.Information);
 		dval |= (tmp.NegotiatedParameters & MPI_SCSIDEVPAGE0_NP_WIDE) ?
 		    DP_WIDE : DP_NARROW;
 		dval |= (mpt->mpt_disc_enable & (1 << tgt)) ?
 		    DP_DISC_ENABLE : DP_DISC_DISABL;
 		dval |= (mpt->mpt_tag_enable & (1 << tgt)) ?
 		    DP_TQING_ENABLE : DP_TQING_DISABL;
-		oval = (tmp.NegotiatedParameters >> 16) & 0xff;
-		pval = (tmp.NegotiatedParameters >>  8) & 0xff;
+		oval = tmp.NegotiatedParameters;
+		oval &= MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK;
+		oval >>= MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET;
+		pval = tmp.NegotiatedParameters;
+		pval &= MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK;
+		pval >>= MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD;
 		mpt->mpt_dev_page0[tgt] = tmp;
 	} else {
-		/*
-		 * XXX: Just make theoretical maximum.
-		 */
-		dval = DP_WIDE|DP_DISC_ENABLE|DP_TQING_ENABLE;
-		oval = (mpt->mpt_port_page0.Capabilities >> 16) & 0xff;
-		pval = (mpt->mpt_port_page0.Capabilities >>  8) & 0xff;
+		dval = DP_WIDE|DP_DISC_ENABLE|DP_TQING_ENABLE|DP_SYNC;
+		oval = mpt->mpt_port_page0.Capabilities;
+		oval = MPI_SCSIPORTPAGE0_CAP_GET_MAX_SYNC_OFFSET(oval);
+		pval = mpt->mpt_port_page0.Capabilities;
+		pval = MPI_SCSIPORTPAGE0_CAP_GET_MIN_SYNC_PERIOD(pval);
 	}
+
 #ifndef	CAM_NEW_TRAN_CODE
 	cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
-	if (dval & DP_DISC_ENABLE) {
-		cts->flags |= CCB_TRANS_DISC_ENB;
-	}
-	if (dval & DP_TQING_ENABLE) {
-		cts->flags |= CCB_TRANS_TAG_ENB;
-	}
+	cts->valid = 0;
+	cts->sync_period = pval;
+	cts->sync_offset = oval;
+	cts->valid |= CCB_TRANS_SYNC_RATE_VALID;
+	cts->valid |= CCB_TRANS_SYNC_OFFSET_VALID;
+	cts->valid |= CCB_TRANS_BUS_WIDTH_VALID;
 	if (dval & DP_WIDE) {
 		cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 	} else {
 		cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
 	}
-	cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
-	    CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
-	if (oval) {
-		cts->sync_period = pval;
-		cts->sync_offset = oval;
-		cts->valid |=
-		    CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID;
+	if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
+		cts->valid |= CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
+		if (dval & DP_DISC_ENABLE) {
+			cts->flags |= CCB_TRANS_DISC_ENB;
+		}
+		if (dval & DP_TQING_ENABLE) {
+			cts->flags |= CCB_TRANS_TAG_ENB;
+		}
 	}
 #else
-	cts->protocol = PROTO_SCSI;
-	cts->protocol_version = SCSI_REV_2;
-	cts->transport = XPORT_SPI;
-	cts->transport_version = 2;
-
-	scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
-	spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
-	if (dval & DP_DISC_ENABLE) {
-		spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
-	}
-	if (dval & DP_TQING_ENABLE) {
-		scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
-	}
-	if (oval && pval) {
-		spi->sync_offset = oval;
-		spi->sync_period = pval;
-		spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
-		spi->valid |= CTS_SPI_VALID_SYNC_RATE;
-	}
+	spi->valid = 0;
+	scsi->valid = 0;
+	spi->flags = 0;
+	scsi->flags = 0;
+	spi->sync_offset = oval;
+	spi->sync_period = pval;
+	spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
+	spi->valid |= CTS_SPI_VALID_SYNC_RATE;
 	spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
 	if (dval & DP_WIDE) {
 		spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
@@ -3407,13 +3839,17 @@
 	}
 	if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
 		scsi->valid = CTS_SCSI_VALID_TQ;
+		if (dval & DP_TQING_ENABLE) {
+			scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
+		}
 		spi->valid |= CTS_SPI_VALID_DISC;
-	} else {
-		scsi->valid = 0;
+		if (dval & DP_DISC_ENABLE) {
+			spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
+		}
 	}
 #endif
 	mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
-	    "mpt_get_spi_settings[%d]: %s 0x%x period 0x%x offset %d\n", tgt,
+	    "mpt_get_spi_settings[%d]: %s flags 0x%x per 0x%x off=%d\n", tgt,
 	    IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM ", dval, pval, oval);
 	return (0);
 }
@@ -3442,7 +3878,13 @@
 	ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_DT;
 	ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_QAS;
 	ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_IU;
-	ptr->RequestedParameters |= (period << 8) | (offset << 16);
+	if (period == 0) {
+		return;
+	}
+	ptr->RequestedParameters |=
+	    period << MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD;
+	ptr->RequestedParameters |=
+	    offset << MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET;
 	if (period < 0xa) {
 		ptr->RequestedParameters |= MPI_SCSIDEVPAGE1_RP_DT;
 	}
@@ -3474,7 +3916,28 @@
 static void
 mpt_calc_geometry(struct ccb_calc_geometry *ccg, int extended)
 {
+#if __FreeBSD_version >= 500000
 	cam_calc_geometry(ccg, extended);
+#else
+	uint32_t size_mb;
+	uint32_t secs_per_cylinder;
+
+	if (ccg->block_size == 0) {
+		ccg->ccb_h.status = CAM_REQ_INVALID;
+		return;
+	}
+	size_mb = ccg->volume_size / ((1024L * 1024L) / ccg->block_size);
+	if (size_mb > 1024 && extended) {
+		ccg->heads = 255;
+		ccg->secs_per_track = 63;
+	} else {
+		ccg->heads = 64;
+		ccg->secs_per_track = 32;
+	}
+	secs_per_cylinder = ccg->heads * ccg->secs_per_track;
+	ccg->cylinders = ccg->volume_size / secs_per_cylinder;
+	ccg->ccb_h.status = CAM_REQ_CMP;
+#endif
 }
 
 /****************************** Timeout Recovery ******************************/
@@ -3509,7 +3972,6 @@
 {
 	struct mpt_softc *mpt;
 
-	mtx_lock(&Giant);
 	mpt = (struct mpt_softc *)arg;
 	MPT_LOCK(mpt);
 	for (;;) {
@@ -3526,7 +3988,6 @@
 	mpt->recovery_thread = NULL;
 	wakeup(&mpt->recovery_thread);
 	MPT_UNLOCK(mpt);
-	mtx_unlock(&Giant);
 	kthread_exit(0);
 }
 
@@ -3573,7 +4034,7 @@
 	}
 	tmf_req->TaskMsgContext = abort_ctx;
 
-	mpt_lprt(mpt, MPT_PRT_INFO,
+	mpt_lprt(mpt, MPT_PRT_DEBUG,
 	    "Issuing TMF %p:%u with MsgContext of 0x%x\n", mpt->tmf_req,
 	    mpt->tmf_req->serno, tmf_req->MsgContext);
 	if (mpt->verbose > MPT_PRT_DEBUG) {
@@ -3585,6 +4046,8 @@
 	TAILQ_INSERT_HEAD(&mpt->request_pending_list, mpt->tmf_req, links);
 	error = mpt_send_handshake_cmd(mpt, sizeof(*tmf_req), tmf_req);
 	if (error != MPT_OK) {
+		TAILQ_REMOVE(&mpt->request_pending_list, mpt->tmf_req, links);
+		mpt->tmf_req->state = REQ_STATE_FREE;
 		mpt_reset(mpt, TRUE);
 	}
 	return (error);
@@ -3732,6 +4195,7 @@
 	PTR_SGE_TRANSACTION32 tep;
 	PTR_SGE_SIMPLE32 se;
 	bus_addr_t paddr;
+	uint32_t fl;
 
 	paddr = req->req_pbuf;
 	paddr += MPT_RQSL(mpt);
@@ -3756,15 +4220,16 @@
 	tep->TransactionContext[0] = htole32(ioindex);
 
 	se = (PTR_SGE_SIMPLE32) &tep->TransactionDetails[0];
-	se->FlagsLength =
+	fl =
 		MPI_SGE_FLAGS_HOST_TO_IOC	|
 		MPI_SGE_FLAGS_SIMPLE_ELEMENT	|
 		MPI_SGE_FLAGS_LAST_ELEMENT	|
 		MPI_SGE_FLAGS_END_OF_LIST	|
 		MPI_SGE_FLAGS_END_OF_BUFFER;
-	se->FlagsLength <<= MPI_SGE_FLAGS_SHIFT;
-	se->FlagsLength |= (MPT_NRFM(mpt) - MPT_RQSL(mpt));
-	se->Address = (uint32_t) paddr;
+	fl <<= MPI_SGE_FLAGS_SHIFT;
+	fl |= (MPT_NRFM(mpt) - MPT_RQSL(mpt));
+	se->FlagsLength = htole32(fl);
+	se->Address = htole32((uint32_t) paddr);
 	mpt_lprt(mpt, MPT_PRT_DEBUG,
 	    "add ELS index %d ioindex %d for %p:%u\n",
 	    req->index, ioindex, req, req->serno);
@@ -3792,7 +4257,7 @@
 
 	cb = &fc->Buffer[0];
 	cb->IoIndex = htole16(ioindex);
-	cb->u.PhysicalAddress32 = (U32) paddr;
+	cb->u.PhysicalAddress32 = htole32((U32) paddr);
 
 	mpt_check_doorbell(mpt);
 	mpt_send_cmd(mpt, req);
@@ -4157,12 +4622,16 @@
 	bus_addr_t pptr;
 	request_t *req;
 
-	if (length == 0) {
+	/*
+	 * We enter with resid set to the data load for the command.
+	 */
+	tgt = MPT_TGT_STATE(mpt, cmd_req);
+	if (length == 0 || tgt->resid == 0) {
+		tgt->resid = 0;
 		mpt_scsi_tgt_status(mpt, NULL, cmd_req, 0, NULL);
 		return;
 	}
 
-	tgt = MPT_TGT_STATE(mpt, cmd_req);
 	if ((req = mpt_get_request(mpt, FALSE)) == NULL) {
 		mpt_prt(mpt, "out of resources- dropping local response\n");
 		return;
@@ -4214,7 +4683,7 @@
 
 	tgt->ccb = NULL;
 	tgt->req = req;
-	tgt->resid = 0;
+	tgt->resid -= length;
 	tgt->bytes_xfered = length;
 #ifdef	WE_TRUST_AUTO_GOOD_STATUS
 	tgt->state = TGT_STATE_MOVING_DATA_AND_STATUS;
@@ -4320,6 +4789,7 @@
 	request_t *req;
 	bus_addr_t paddr;
 	int resplen = 0;
+	uint32_t fl;
 
 	cmd_vbuf = cmd_req->req_vbuf;
 	cmd_vbuf += MPT_RQSL(mpt);
@@ -4439,15 +4909,16 @@
 	if (status == SCSI_STATUS_OK && resplen == 0) {
 		tp->MsgFlags |= TARGET_STATUS_SEND_FLAGS_AUTO_GOOD_STATUS;
 	} else {
-		tp->StatusDataSGE.u.Address32 = (uint32_t) paddr;
-		tp->StatusDataSGE.FlagsLength =
+		tp->StatusDataSGE.u.Address32 = htole32((uint32_t) paddr);
+		fl =
 			MPI_SGE_FLAGS_HOST_TO_IOC	|
 			MPI_SGE_FLAGS_SIMPLE_ELEMENT	|
 			MPI_SGE_FLAGS_LAST_ELEMENT	|
 			MPI_SGE_FLAGS_END_OF_LIST	|
 			MPI_SGE_FLAGS_END_OF_BUFFER;
-		tp->StatusDataSGE.FlagsLength <<= MPI_SGE_FLAGS_SHIFT;
-		tp->StatusDataSGE.FlagsLength |= resplen;
+		fl <<= MPI_SGE_FLAGS_SHIFT;
+		fl |= resplen;
+		tp->StatusDataSGE.FlagsLength = htole32(fl);
 	}
 
 	mpt_lprt(mpt, MPT_PRT_DEBUG, 
@@ -4456,7 +4927,7 @@
 	    req->serno, tgt->resid);
 	if (ccb) {
 		ccb->ccb_h.status = CAM_SIM_QUEUED | CAM_REQ_INPROG;
-		ccb->ccb_h.timeout_ch = timeout(mpt_timeout, ccb, 60 * hz);
+		mpt_req_timeout(req, 60 * hz, mpt_timeout, ccb);
 	}
 	mpt_send_cmd(mpt, req);
 }
@@ -4518,6 +4989,13 @@
 static void
 mpt_scsi_tgt_atio(struct mpt_softc *mpt, request_t *req, uint32_t reply_desc)
 {
+	static uint8_t null_iqd[SHORT_INQUIRY_LENGTH] = {
+	    0x7f, 0x00, 0x02, 0x02, 0x20, 0x00, 0x00, 0x32,
+	     'F',  'R',  'E',  'E',  'B',  'S',  'D',  ' ',
+	     'L',  'S',  'I',  '-',  'L',  'O',  'G',  'I',
+	     'C',  ' ',  'N',  'U',  'L',  'D',  'E',  'V',
+	     '0',  '0',  '0',  '1'
+	};
 	struct ccb_accept_tio *atiop;
 	lun_id_t lun;
 	int tag_action = 0;
@@ -4557,7 +5035,12 @@
 	tgt->state = TGT_STATE_IN_CAM;
 	tgt->reply_desc = reply_desc;
 	ioindex = GET_IO_INDEX(reply_desc);
-
+	if (mpt->verbose >= MPT_PRT_DEBUG) {
+		mpt_dump_data(mpt, "mpt_scsi_tgt_atio response", vbuf,
+		    max(sizeof (MPI_TARGET_FCP_CMD_BUFFER),
+		    max(sizeof (MPI_TARGET_SSP_CMD_BUFFER),
+		    sizeof (MPI_TARGET_SCSI_SPI_CMD_BUFFER))));
+	}
 	if (mpt->is_fc) {
 		PTR_MPI_TARGET_FCP_CMD_BUFFER fc;
 		fc = (PTR_MPI_TARGET_FCP_CMD_BUFFER) vbuf;
@@ -4659,11 +5142,8 @@
 			 * REPORT LUNS gets illegal command.
 			 * All other commands get 'no such device'.
 			 */
-
 			uint8_t *sp, cond, buf[MPT_SENSE_SIZE];
-
-			mpt_prt(mpt, "CMD 0x%x to unmanaged lun %u\n",
-			    cdbp[0], lun);
+			size_t len;
 
 			memset(buf, 0, MPT_SENSE_SIZE);
 			cond = SCSI_STATUS_CHECK_COND;
@@ -4676,31 +5156,38 @@
 			switch (cdbp[0]) {
 			case INQUIRY:
 			{
-				static uint8_t iqd[8] = {
-				    0x7f, 0x0, 0x4, 0x12, 0x0
-				};
 				if (cdbp[1] != 0) {
 					buf[12] = 0x26;
 					buf[13] = 0x01;
 					break;
 				}
-				mpt_prt(mpt, "local inquiry\n");
+				len = min(tgt->resid, cdbp[4]);
+				len = min(len, sizeof (null_iqd));
+				mpt_lprt(mpt, MPT_PRT_DEBUG,
+				    "local inquiry %ld bytes\n", (long) len);
 				mpt_scsi_tgt_local(mpt, req, lun, 1,
-				    iqd, sizeof (iqd));
+				    null_iqd, len);
 				return;
 			}
 			case REQUEST_SENSE:
 			{
 				buf[2] = 0x0;
-				mpt_prt(mpt, "local request sense\n");
+				len = min(tgt->resid, cdbp[4]);
+				len = min(len, sizeof (buf));
+				mpt_lprt(mpt, MPT_PRT_DEBUG,
+				    "local reqsense %ld bytes\n", (long) len);
 				mpt_scsi_tgt_local(mpt, req, lun, 1,
-				    buf, sizeof (buf));
+				    buf, len);
 				return;
 			}
 			case REPORT_LUNS:
+				mpt_lprt(mpt, MPT_PRT_DEBUG, "REPORT LUNS\n");
 				buf[12] = 0x26;
-				break;
+				return;
 			default:
+				mpt_lprt(mpt, MPT_PRT_DEBUG,
+				    "CMD 0x%x to unmanaged lun %u\n",
+				    cdbp[0], lun);
 				buf[12] = 0x25;
 				break;
 			}
@@ -4855,7 +5342,7 @@
 			}
 			tgt->ccb = NULL;
 			tgt->nxfers++;
-			untimeout(mpt_timeout, ccb, ccb->ccb_h.timeout_ch);
+			mpt_req_untimeout(req, mpt_timeout, ccb);
 			mpt_lprt(mpt, MPT_PRT_DEBUG,
 			    "TARGET_ASSIST %p (req %p:%u) done tag 0x%x\n",
 			    ccb, tgt->req, tgt->req->serno, ccb->csio.tag_id);
@@ -4920,8 +5407,7 @@
 				    TGT_STATE_MOVING_DATA_AND_STATUS) {
 					tgt->nxfers++;
 				}
-				untimeout(mpt_timeout, ccb,
-				    ccb->ccb_h.timeout_ch);
+				mpt_req_untimeout(req, mpt_timeout, ccb);
 				if (ccb->ccb_h.flags & CAM_SEND_SENSE) {
 					ccb->ccb_h.status |= CAM_SENT_SENSE;
 				}
Index: mpi_lan.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_lan.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpilib/mpi_lan.h -L sys/dev/mpt/mpilib/mpi_lan.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpilib/mpi_lan.h
+++ sys/dev/mpt/mpilib/mpi_lan.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_lan.h,v 1.5.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_lan.h,v 1.6 2006/01/21 00:29:51 mjacob Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
--- sys/dev/mpt/mpilib/mpi_log_sas.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_log_sas.h,v 1.1.2.1 2006/06/08 17:47:35 mjacob Exp $ */
-/*-
- * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    substantially similar to the "NO WARRANTY" disclaimer below
- *    ("Disclaimer") and any redistribution must be conditioned upon including
- *    a substantially similar Disclaimer requirement for further binary
- *    redistribution.
- * 3. Neither the name of the LSI Logic Corporation 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 OWNER 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 THE COPYRIGHT
- * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *                                                                         *
- ***************************************************************************
- *
- *           Name:  iopiIocLogInfo.h
- *          Title:  SAS Firmware IOP Interface IOC Log Info Definitions
- *     Programmer:  Guy Kendall
- *  Creation Date:  September 24, 2003
- *
- *  Version History
- *  ---------------
- *
- *  Last Updated
- *  -------------
- *  Version         %version: 22 %
- *  Date Updated    %date_modified: %
- *  Programmer      %created_by: nperucca %
- *
- *  Date      Who   Description
- *  --------  ---   -------------------------------------------------------
- *  09/24/03  GWK   Initial version
- *
- *
- * Description
- * ------------
- * This include file contains SAS firmware interface IOC Log Info codes
- *
- *-------------------------------------------------------------------------
- */
-
-#ifndef IOPI_IOCLOGINFO_H_INCLUDED
-#define IOPI_IOCLOGINFO_H_INCLUDED
-
-
-/****************************************************************************/
-/*  IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF                            */
-/*  Format:                                                                 */
-/*      Bits 31-28: MPI_IOCLOGINFO_TYPE_SAS (3)                             */
-/*      Bits 27-24: IOC_LOGINFO_ORIGINATOR: 0=IOP, 1=PL, 2=IR               */
-/*      Bits 23-16: LOGINFO_CODE                                            */
-/*      Bits 15-0:  LOGINFO_CODE Specific                                   */
-/****************************************************************************/
-
-/****************************************************************************/
-/* IOC_LOGINFO_ORIGINATOR defines                                           */
-/****************************************************************************/
-#define IOC_LOGINFO_ORIGINATOR_IOP                      (0x00000000)
-#define IOC_LOGINFO_ORIGINATOR_PL                       (0x01000000)
-#define IOC_LOGINFO_ORIGINATOR_IR                       (0x02000000)
-
-/****************************************************************************/
-/* LOGINFO_CODE defines                                                     */
-/****************************************************************************/
-#define IOC_LOGINFO_CODE_MASK                           (0x00FF0000)
-#define IOC_LOGINFO_CODE_SHIFT                          (16)
-
-/****************************************************************************/
-/* IOP LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IOP          */
-/****************************************************************************/
-#define IOP_LOGINFO_CODE_INVALID_SAS_ADDRESS            (0x00010000)
-#define IOP_LOGINFO_CODE_UNUSED2                        (0x00020000)
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE            (0x00030000)
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_RT         (0x00030100) /* Route Table Entry not found */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PN         (0x00030200) /* Invalid Page Number */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM       (0x00030300) /* Invalid FORM */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT         (0x00030400) /* Invalid Page Type */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM        (0x00030500) /* Device Not Mapped */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST    (0x00030600) /* Persistent Page not found */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT    (0x00030700) /* Default Page not found */
-#define IOP_LOGINFO_CODE_TASK_TERMINATED                (0x00050000)
-
-
-/****************************************************************************/
-/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL            */
-/****************************************************************************/
-#define PL_LOGINFO_CODE_OPEN_FAILURE                        (0x00010000)
-#define PL_LOGINFO_CODE_INVALID_SGL                         (0x00020000)
-#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH       (0x00030000)
-#define PL_LOGINFO_CODE_FRAME_XFER_ERROR                    (0x00040000)
-#define PL_LOGINFO_CODE_TX_FM_CONNECTED_LOW                 (0x00050000)
-#define PL_LOGINFO_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET         (0x00060000)
-#define PL_LOGINFO_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR      (0x00070000)
-#define PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR     (0x00080000)
-#define PL_LOGINFO_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS     (0x00090000)
-#define PL_LOGINFO_CODE_RX_FM_INVALID_MESSAGE               (0x000A0000)
-#define PL_LOGINFO_CODE_RX_CTX_MESSAGE_VALID_ERROR          (0x000B0000)
-#define PL_LOGINFO_CODE_RX_FM_CURRENT_FRAME_ERROR           (0x000C0000)
-#define PL_LOGINFO_CODE_SATA_LINK_DOWN                      (0x000D0000)
-#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS           (0x000E0000)
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE                 (0x000F0000)
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT              (0x000F0100) /* Invalid Page Type */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS        (0x000F0200) /* Invalid Number of Phys */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP         (0x000F0300) /* Case Not Handled */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_DEV          (0x000F0400) /* No Device Found */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM            (0x000F0500) /* Invalid FORM */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY             (0x000F0600) /* Invalid Phy */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER        (0x000F0700) /* No Owner Found */
-#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT            (0x00100000)
-#define PL_LOGINFO_CODE_RESET                               (0x00110000)
-#define PL_LOGINFO_CODE_ABORT                               (0x00120000)
-#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED                 (0x00130000)
-#define PL_LOGINFO_CODE_IO_EXECUTED                         (0x00140000)
-#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE                    (0x00000100)
-#define PL_LOGINFO_SUB_CODE_INVALID_SGL                     (0x00000200)
-#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH   (0x00000300)
-#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR                (0x00000400)
-#define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW             (0x00000500)
-#define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET     (0x00000600)
-#define PL_LOGINFO_SUB_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR  (0x00000700)
-#define PL_LOGINFO_SUB_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00000800)
-#define PL_LOGINFO_SUB_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00000900)
-#define PL_LOGINFO_SUB_CODE_RX_FM_INVALID_MESSAGE           (0x00000A00)
-#define PL_LOGINFO_SUB_CODE_RX_CTX_MESSAGE_VALID_ERROR      (0x00000B00)
-#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR       (0x00000C00)
-#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN                  (0x00000D00)
-#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS       (0x00000E00)
-#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT        (0x00001000)
-
-
-#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE         (0x00200000) /* Can't get SMP Frame */
-#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR            (0x00200001) /* Error occured on SMP Read */
-#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR           (0x00200002) /* Error occured on SMP Write */
-#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL     (0x00200004) /* Encl Mgmt services not available for this WWID */
-#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED   (0x00200005) /* Address Mode not suppored */
-#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM              (0x00200006) /* Invalid Slot Number in SEP Msg */
-#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT         (0x00200007) /* SGPIO not present/enabled */
-
-#define PL_LOGINFO_DA_SEP_NOT_PRESENT                       (0x00200100) /* SEP not present when msg received */
-#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR               (0x00200101) /* Can only accept 1 msg at a time */
-#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE          (0x00200102) /* ISTWI interrupt recvd. while IDLE */
-#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE          (0x00200103) /* SEP NACK'd, it is busy */
-#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM             (0x00200104) /* SEP stopped or sent bad chksum in Hdr */
-#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1         (0x00200105) /* SEP returned unknown scsi status */
-#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2         (0x00200106) /* SEP returned unknown scsi status */
-#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP           (0x00200107) /* SEP returned bad chksum after STOP */
-#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA   (0x00200108) /* SEP returned bad chksum after STOP while gettin data*/
-
-
-/****************************************************************************/
-/* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR            */
-/****************************************************************************/
-#define IR_LOGINFO_CODE_UNUSED1                         (0x00010000)
-#define IR_LOGINFO_CODE_UNUSED2                         (0x00020000)
-
-/****************************************************************************/
-/* Defines for convienence                                                  */
-/****************************************************************************/
-#define IOC_LOGINFO_PREFIX_IOP                          ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP)
-#define IOC_LOGINFO_PREFIX_PL                           ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL)
-#define IOC_LOGINFO_PREFIX_IR                           ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IR)
-
-#endif /* end of file */
Index: mpi_init.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_init.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpilib/mpi_init.h -L sys/dev/mpt/mpilib/mpi_init.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpilib/mpi_init.h
+++ sys/dev/mpt/mpilib/mpi_init.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_init.h,v 1.6.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_init.h,v 1.8 2007/06/03 22:58:27 scottl Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
@@ -28,12 +28,12 @@
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
  * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
+ *
  *           Name:  mpi_init.h
  *          Title:  MPI initiator mode messages and structures
  *  Creation Date:  June 8, 2000
  *
- *    mpi_init.h Version:  01.05.06
+ *    mpi_init.h Version:  01.05.09
  *
  *  Version History
  *  ---------------
@@ -79,6 +79,10 @@
  *                      Added four new defines for SEP SlotStatus.
  *  08-03-05  01.05.06  Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
  *                      unique in the first 32 characters.
+ *  03-27-06  01.05.07  Added Task Management type of Clear ACA.
+ *  10-11-06  01.05.08  Shortened define for Task Management type of Clear ACA.
+ *  02-28-07  01.05.09  Defined two new MsgFlags bits for SCSI Task Management
+ *                      Request: Do Not Send Task IU and Soft Reset Option.
  *  --------------------------------------------------------------------------
  */
 
@@ -454,12 +458,17 @@
 #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET    (0x05)
 #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET        (0x06)
 #define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK            (0x07)
+#define MPI_SCSITASKMGMT_TASKTYPE_CLR_ACA               (0x08)
 
 /* MsgFlags bits */
+#define MPI_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU   (0x01)
+
 #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION   (0x00)
 #define MPI_SCSITASKMGMT_MSGFLAGS_LIP_RESET_OPTION      (0x02)
 #define MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION (0x04)
 
+#define MPI_SCSITASKMGMT_MSGFLAGS_SOFT_RESET_OPTION     (0x08)
+
 /* SCSI Task Management Reply */
 typedef struct _MSG_SCSI_TASK_MGMT_REPLY
 {
Index: mpi_inb.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_inb.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -L sys/dev/mpt/mpilib/mpi_inb.h -L sys/dev/mpt/mpilib/mpi_inb.h -u -r1.1 -r1.2
--- sys/dev/mpt/mpilib/mpi_inb.h
+++ sys/dev/mpt/mpilib/mpi_inb.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_inb.h,v 1.1.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_inb.h,v 1.1 2006/01/21 00:29:51 mjacob Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
Index: mpi_type.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_type.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpilib/mpi_type.h -L sys/dev/mpt/mpilib/mpi_type.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpilib/mpi_type.h
+++ sys/dev/mpt/mpilib/mpi_type.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_type.h,v 1.7.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_type.h,v 1.10 2006/02/26 22:50:14 mjacob Exp $ */
 /*
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
Index: mpi_raid.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_raid.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpilib/mpi_raid.h -L sys/dev/mpt/mpilib/mpi_raid.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpilib/mpi_raid.h
+++ sys/dev/mpt/mpilib/mpi_raid.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_raid.h,v 1.6.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_raid.h,v 1.8 2007/06/03 22:58:27 scottl Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
@@ -28,13 +28,12 @@
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
  * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * 
+ *
  *           Name:  mpi_raid.h
  *          Title:  MPI RAID message and structures
  *  Creation Date:  February 27, 2001
  *
- *    mpi_raid.h Version:  01.05.02
+ *    mpi_raid.h Version:  01.05.03
  *
  *  Version History
  *  ---------------
@@ -60,6 +59,8 @@
  *  08-19-04  01.05.01  Original release for MPI v1.5.
  *  01-15-05  01.05.02  Added defines for the two new RAID Actions for
  *                      _SET_RESYNC_RATE and _SET_DATA_SCRUB_RATE.
+ *  02-28-07  01.05.03  Added new RAID Action, Device FW Update Mode, and
+ *                      associated defines.
  *  --------------------------------------------------------------------------
  */
 
@@ -118,6 +119,7 @@
 #define MPI_RAID_ACTION_INACTIVATE_VOLUME           (0x12)
 #define MPI_RAID_ACTION_SET_RESYNC_RATE             (0x13)
 #define MPI_RAID_ACTION_SET_DATA_SCRUB_RATE         (0x14)
+#define MPI_RAID_ACTION_DEVICE_FW_UPDATE_MODE       (0x15)
 
 /* ActionDataWord defines for use with MPI_RAID_ACTION_CREATE_VOLUME action */
 #define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC           (0x00000001)
@@ -139,6 +141,10 @@
 /* ActionDataWord defines for use with MPI_RAID_ACTION_SET_DATA_SCRUB_RATE action */
 #define MPI_RAID_ACTION_ADATA_DATA_SCRUB_RATE_MASK  (0x000000FF)
 
+/* ActionDataWord defines for use with MPI_RAID_ACTION_DEVICE_FW_UPDATE_MODE action */
+#define MPI_RAID_ACTION_ADATA_ENABLE_FW_UPDATE          (0x00000001)
+#define MPI_RAID_ACTION_ADATA_MASK_FW_UPDATE_TIMEOUT    (0x0000FF00)
+#define MPI_RAID_ACTION_ADATA_SHIFT_FW_UPDATE_TIMEOUT   (8)
 
 
 /* RAID Action reply message */
Index: mpi.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpilib/mpi.h -L sys/dev/mpt/mpilib/mpi.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpilib/mpi.h
+++ sys/dev/mpt/mpilib/mpi.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi.h,v 1.6.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi.h,v 1.9 2007/06/03 22:58:26 scottl Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
@@ -33,7 +33,7 @@
  *          Title:  MPI Message independent structures and definitions
  *  Creation Date:  July 27, 2000
  *
- *    mpi.h Version:  01.05.10
+ *    mpi.h Version:  01.05.13
  *
  *  Version History
  *  ---------------
@@ -103,6 +103,9 @@
  *                      Added EEDP IOCStatus codes.
  *  08-03-05  01.05.09  Bumped MPI_HEADER_VERSION_UNIT.
  *  08-30-05  01.05.10  Added 2 new IOCStatus codes for Target.
+ *  03-27-06  01.05.11  Bumped MPI_HEADER_VERSION_UNIT.
+ *  10-11-06  01.05.12  Bumped MPI_HEADER_VERSION_UNIT.
+ *  05-24-07  01.05.13  Bumped MPI_HEADER_VERSION_UNIT.
  *  --------------------------------------------------------------------------
  */
 
@@ -133,7 +136,7 @@
 /* Note: The major versions of 0xe0 through 0xff are reserved */
 
 /* versioning for this MPI header set */
-#define MPI_HEADER_VERSION_UNIT             (0x0C)
+#define MPI_HEADER_VERSION_UNIT             (0x10)
 #define MPI_HEADER_VERSION_DEV              (0x00)
 #define MPI_HEADER_VERSION_UNIT_MASK        (0xFF00)
 #define MPI_HEADER_VERSION_UNIT_SHIFT       (8)
@@ -675,45 +678,45 @@
 /*  Common IOCStatus values for all replies                                 */
 /****************************************************************************/
 
-#define MPI_IOCSTATUS_SUCCESS                  (0x0000)
-#define MPI_IOCSTATUS_INVALID_FUNCTION         (0x0001)
-#define MPI_IOCSTATUS_BUSY                     (0x0002)
-#define MPI_IOCSTATUS_INVALID_SGL              (0x0003)
-#define MPI_IOCSTATUS_INTERNAL_ERROR           (0x0004)
-#define MPI_IOCSTATUS_RESERVED                 (0x0005)
-#define MPI_IOCSTATUS_INSUFFICIENT_RESOURCES   (0x0006)
-#define MPI_IOCSTATUS_INVALID_FIELD            (0x0007)
-#define MPI_IOCSTATUS_INVALID_STATE            (0x0008)
+#define MPI_IOCSTATUS_SUCCESS                   (0x0000)
+#define MPI_IOCSTATUS_INVALID_FUNCTION          (0x0001)
+#define MPI_IOCSTATUS_BUSY                      (0x0002)
+#define MPI_IOCSTATUS_INVALID_SGL               (0x0003)
+#define MPI_IOCSTATUS_INTERNAL_ERROR            (0x0004)
+#define MPI_IOCSTATUS_RESERVED                  (0x0005)
+#define MPI_IOCSTATUS_INSUFFICIENT_RESOURCES    (0x0006)
+#define MPI_IOCSTATUS_INVALID_FIELD             (0x0007)
+#define MPI_IOCSTATUS_INVALID_STATE             (0x0008)
 #define MPI_IOCSTATUS_OP_STATE_NOT_SUPPORTED    (0x0009)
 
 /****************************************************************************/
 /*  Config IOCStatus values                                                 */
 /****************************************************************************/
 
-#define MPI_IOCSTATUS_CONFIG_INVALID_ACTION    (0x0020)
-#define MPI_IOCSTATUS_CONFIG_INVALID_TYPE      (0x0021)
-#define MPI_IOCSTATUS_CONFIG_INVALID_PAGE      (0x0022)
-#define MPI_IOCSTATUS_CONFIG_INVALID_DATA      (0x0023)
-#define MPI_IOCSTATUS_CONFIG_NO_DEFAULTS       (0x0024)
-#define MPI_IOCSTATUS_CONFIG_CANT_COMMIT       (0x0025)
+#define MPI_IOCSTATUS_CONFIG_INVALID_ACTION     (0x0020)
+#define MPI_IOCSTATUS_CONFIG_INVALID_TYPE       (0x0021)
+#define MPI_IOCSTATUS_CONFIG_INVALID_PAGE       (0x0022)
+#define MPI_IOCSTATUS_CONFIG_INVALID_DATA       (0x0023)
+#define MPI_IOCSTATUS_CONFIG_NO_DEFAULTS        (0x0024)
+#define MPI_IOCSTATUS_CONFIG_CANT_COMMIT        (0x0025)
 
 /****************************************************************************/
 /*  SCSIIO Reply (SPI & FCP) initiator values                               */
 /****************************************************************************/
 
-#define MPI_IOCSTATUS_SCSI_RECOVERED_ERROR     (0x0040)
-#define MPI_IOCSTATUS_SCSI_INVALID_BUS         (0x0041)
-#define MPI_IOCSTATUS_SCSI_INVALID_TARGETID    (0x0042)
-#define MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE    (0x0043)
-#define MPI_IOCSTATUS_SCSI_DATA_OVERRUN        (0x0044)
-#define MPI_IOCSTATUS_SCSI_DATA_UNDERRUN       (0x0045)
-#define MPI_IOCSTATUS_SCSI_IO_DATA_ERROR       (0x0046)
-#define MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR      (0x0047)
-#define MPI_IOCSTATUS_SCSI_TASK_TERMINATED     (0x0048)
-#define MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH   (0x0049)
-#define MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED    (0x004A)
-#define MPI_IOCSTATUS_SCSI_IOC_TERMINATED      (0x004B)
-#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED      (0x004C)
+#define MPI_IOCSTATUS_SCSI_RECOVERED_ERROR      (0x0040)
+#define MPI_IOCSTATUS_SCSI_INVALID_BUS          (0x0041)
+#define MPI_IOCSTATUS_SCSI_INVALID_TARGETID     (0x0042)
+#define MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE     (0x0043)
+#define MPI_IOCSTATUS_SCSI_DATA_OVERRUN         (0x0044)
+#define MPI_IOCSTATUS_SCSI_DATA_UNDERRUN        (0x0045)
+#define MPI_IOCSTATUS_SCSI_IO_DATA_ERROR        (0x0046)
+#define MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR       (0x0047)
+#define MPI_IOCSTATUS_SCSI_TASK_TERMINATED      (0x0048)
+#define MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH    (0x0049)
+#define MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED     (0x004A)
+#define MPI_IOCSTATUS_SCSI_IOC_TERMINATED       (0x004B)
+#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED       (0x004C)
 
 /****************************************************************************/
 /*  For use by SCSI Initiator and SCSI Target end-to-end data protection    */
Index: mpi_ioc.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_ioc.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpilib/mpi_ioc.h -L sys/dev/mpt/mpilib/mpi_ioc.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpilib/mpi_ioc.h
+++ sys/dev/mpt/mpilib/mpi_ioc.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_ioc.h,v 1.6.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_ioc.h,v 1.9 2007/06/03 22:58:27 scottl Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
@@ -28,13 +28,12 @@
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
  * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * 
+ *
  *           Name:  mpi_ioc.h
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  August 11, 2000
  *
- *    mpi_ioc.h Version:  01.05.10
+ *    mpi_ioc.h Version:  01.05.14
  *
  *  Version History
  *  ---------------
@@ -115,6 +114,32 @@
  *                      Added new ReasonCode value for SAS Device Status Change
  *                      event.
  *                      Added new family code for FC949E.
+ *  03-27-06  01.05.11  Added MPI_IOCFACTS_CAPABILITY_TLR.
+ *                      Added additional Reason Codes and more event data fields
+ *                      to EVENT_DATA_SAS_DEVICE_STATUS_CHANGE.
+ *                      Added EVENT_DATA_SAS_BROADCAST_PRIMITIVE structure and
+ *                      new event.
+ *                      Added MPI_EVENT_SAS_SMP_ERROR and event data structure.
+ *                      Added MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE and event
+ *                      data structure.
+ *                      Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event
+ *                      data structure.
+ *                      Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.
+ *  10-11-06  01.05.12  Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED.
+ *                      Added MaxInitiators field to PortFacts reply.
+ *                      Added SAS Device Status Change ReasonCode for
+ *                      asynchronous notificaiton.
+ *                      Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event
+ *                      data structure.
+ *                      Added new ImageType values for FWDownload and FWUpload
+ *                      requests.
+ *  02-28-07  01.05.13  Added MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT for SAS
+ *                      Broadcast Event Data (replacing _RESERVED2).
+ *                      For Discovery Error Event Data DiscoveryStatus field,
+ *                      replaced _MULTPL_PATHS with _UNSUPPORTED_DEVICE and
+ *                      added _MULTI_PORT_DOMAIN.
+ *  05-24-07  01.05.14  Added Common Boot Block type to FWDownload Request.
+ *                      Added Common Boot Block type to FWUpload Request.
  *  --------------------------------------------------------------------------
  */
 
@@ -155,17 +180,17 @@
   IOCInit_t, MPI_POINTER pIOCInit_t;
 
 /* WhoInit values */
-#define MPI_WHOINIT_NO_ONE                      (0x00)
-#define MPI_WHOINIT_SYSTEM_BIOS                 (0x01)
-#define MPI_WHOINIT_ROM_BIOS                    (0x02)
-#define MPI_WHOINIT_PCI_PEER                    (0x03)
-#define MPI_WHOINIT_HOST_DRIVER                 (0x04)
-#define MPI_WHOINIT_MANUFACTURER                (0x05)
+#define MPI_WHOINIT_NO_ONE                              (0x00)
+#define MPI_WHOINIT_SYSTEM_BIOS                         (0x01)
+#define MPI_WHOINIT_ROM_BIOS                            (0x02)
+#define MPI_WHOINIT_PCI_PEER                            (0x03)
+#define MPI_WHOINIT_HOST_DRIVER                         (0x04)
+#define MPI_WHOINIT_MANUFACTURER                        (0x05)
 
 /* Flags values */
 #define MPI_IOCINIT_FLAGS_HOST_PAGE_BUFFER_PERSISTENT   (0x04)
 #define MPI_IOCINIT_FLAGS_REPLY_FIFO_HOST_SIGNAL        (0x02)
-#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE      (0x01)
+#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE              (0x01)
 
 /* MsgVersion */
 #define MPI_IOCINIT_MSGVERSION_MAJOR_MASK               (0xFF00)
@@ -267,9 +292,9 @@
 } MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY,
   IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t;
 
-#define MPI_IOCFACTS_MSGVERSION_MAJOR_MASK          (0xFF00)
+#define MPI_IOCFACTS_MSGVERSION_MAJOR_MASK              (0xFF00)
 #define MPI_IOCFACTS_MSGVERSION_MAJOR_SHIFT             (8)
-#define MPI_IOCFACTS_MSGVERSION_MINOR_MASK          (0x00FF)
+#define MPI_IOCFACTS_MSGVERSION_MINOR_MASK              (0x00FF)
 #define MPI_IOCFACTS_MSGVERSION_MINOR_SHIFT             (0)
 
 #define MPI_IOCFACTS_HDRVERSION_UNIT_MASK               (0xFF00)
@@ -277,17 +302,18 @@
 #define MPI_IOCFACTS_HDRVERSION_DEV_MASK                (0x00FF)
 #define MPI_IOCFACTS_HDRVERSION_DEV_SHIFT               (0)
 
-#define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL    (0x0001)
-#define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID     (0x0002)
+#define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL        (0x0001)
+#define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID         (0x0002)
 #define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL            (0x0004)
 #define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL       (0x0008)
+#define MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED        (0x0010)
 
-#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT         (0x01)
+#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT             (0x01)
 #define MPI_IOCFACTS_FLAGS_REPLY_FIFO_HOST_SIGNAL       (0x02)
 #define MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT  (0x04)
 
-#define MPI_IOCFACTS_EVENTSTATE_DISABLED            (0x00)
-#define MPI_IOCFACTS_EVENTSTATE_ENABLED             (0x01)
+#define MPI_IOCFACTS_EVENTSTATE_DISABLED                (0x00)
+#define MPI_IOCFACTS_EVENTSTATE_ENABLED                 (0x01)
 
 #define MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q              (0x00000001)
 #define MPI_IOCFACTS_CAPABILITY_REPLY_HOST_SIGNAL       (0x00000002)
@@ -300,6 +326,7 @@
 #define MPI_IOCFACTS_CAPABILITY_MULTICAST               (0x00000100)
 #define MPI_IOCFACTS_CAPABILITY_SCSIIO32                (0x00000200)
 #define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16             (0x00000400)
+#define MPI_IOCFACTS_CAPABILITY_TLR                     (0x00000800)
 
 
 /*****************************************************************************
@@ -344,7 +371,8 @@
      U16                    MaxPostedCmdBuffers;        /* 1Ch */
      U16                    MaxPersistentIDs;           /* 1Eh */
      U16                    MaxLanBuckets;              /* 20h */
-     U16                    Reserved4;                  /* 22h */
+     U8                     MaxInitiators;              /* 22h */
+     U8                     Reserved4;                  /* 23h */
      U32                    Reserved5;                  /* 24h */
 } MSG_PORT_FACTS_REPLY, MPI_POINTER PTR_MSG_PORT_FACTS_REPLY,
   PortFactsReply_t, MPI_POINTER pPortFactsReply_t;
@@ -476,30 +504,35 @@
 
 /* Event */
 
-#define MPI_EVENT_NONE                      (0x00000000)
-#define MPI_EVENT_LOG_DATA                  (0x00000001)
-#define MPI_EVENT_STATE_CHANGE              (0x00000002)
-#define MPI_EVENT_UNIT_ATTENTION            (0x00000003)
-#define MPI_EVENT_IOC_BUS_RESET             (0x00000004)
-#define MPI_EVENT_EXT_BUS_RESET             (0x00000005)
-#define MPI_EVENT_RESCAN                    (0x00000006)
-#define MPI_EVENT_LINK_STATUS_CHANGE        (0x00000007)
-#define MPI_EVENT_LOOP_STATE_CHANGE         (0x00000008)
-#define MPI_EVENT_LOGOUT                    (0x00000009)
-#define MPI_EVENT_EVENT_CHANGE              (0x0000000A)
-#define MPI_EVENT_INTEGRATED_RAID           (0x0000000B)
-#define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE (0x0000000C)
-#define MPI_EVENT_ON_BUS_TIMER_EXPIRED      (0x0000000D)
-#define MPI_EVENT_QUEUE_FULL                (0x0000000E)
-#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE  (0x0000000F)
-#define MPI_EVENT_SAS_SES                   (0x00000010)
-#define MPI_EVENT_PERSISTENT_TABLE_FULL     (0x00000011)
-#define MPI_EVENT_SAS_PHY_LINK_STATUS       (0x00000012)
-#define MPI_EVENT_SAS_DISCOVERY_ERROR       (0x00000013)
-#define MPI_EVENT_IR_RESYNC_UPDATE          (0x00000014)
-#define MPI_EVENT_IR2                       (0x00000015)
-#define MPI_EVENT_SAS_DISCOVERY             (0x00000016)
-#define MPI_EVENT_LOG_ENTRY_ADDED           (0x00000021)
+#define MPI_EVENT_NONE                          (0x00000000)
+#define MPI_EVENT_LOG_DATA                      (0x00000001)
+#define MPI_EVENT_STATE_CHANGE                  (0x00000002)
+#define MPI_EVENT_UNIT_ATTENTION                (0x00000003)
+#define MPI_EVENT_IOC_BUS_RESET                 (0x00000004)
+#define MPI_EVENT_EXT_BUS_RESET                 (0x00000005)
+#define MPI_EVENT_RESCAN                        (0x00000006)
+#define MPI_EVENT_LINK_STATUS_CHANGE            (0x00000007)
+#define MPI_EVENT_LOOP_STATE_CHANGE             (0x00000008)
+#define MPI_EVENT_LOGOUT                        (0x00000009)
+#define MPI_EVENT_EVENT_CHANGE                  (0x0000000A)
+#define MPI_EVENT_INTEGRATED_RAID               (0x0000000B)
+#define MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE     (0x0000000C)
+#define MPI_EVENT_ON_BUS_TIMER_EXPIRED          (0x0000000D)
+#define MPI_EVENT_QUEUE_FULL                    (0x0000000E)
+#define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE      (0x0000000F)
+#define MPI_EVENT_SAS_SES                       (0x00000010)
+#define MPI_EVENT_PERSISTENT_TABLE_FULL         (0x00000011)
+#define MPI_EVENT_SAS_PHY_LINK_STATUS           (0x00000012)
+#define MPI_EVENT_SAS_DISCOVERY_ERROR           (0x00000013)
+#define MPI_EVENT_IR_RESYNC_UPDATE              (0x00000014)
+#define MPI_EVENT_IR2                           (0x00000015)
+#define MPI_EVENT_SAS_DISCOVERY                 (0x00000016)
+#define MPI_EVENT_SAS_BROADCAST_PRIMITIVE       (0x00000017)
+#define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018)
+#define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW       (0x00000019)
+#define MPI_EVENT_SAS_SMP_ERROR                 (0x0000001A)
+#define MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE    (0x0000001B)
+#define MPI_EVENT_LOG_ENTRY_ADDED               (0x00000021)
 
 /* AckRequired field values */
 
@@ -586,18 +619,26 @@
     U8                      PhyNum;                     /* 0Eh */
     U8                      Reserved1;                  /* 0Fh */
     U64                     SASAddress;                 /* 10h */
+    U8                      LUN[8];                     /* 18h */
+    U16                     TaskTag;                    /* 20h */
+    U16                     Reserved2;                  /* 22h */
 } EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
   MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
   MpiEventDataSasDeviceStatusChange_t,
   MPI_POINTER pMpiEventDataSasDeviceStatusChange_t;
 
 /* MPI SAS Device Status Change Event data ReasonCode values */
-#define MPI_EVENT_SAS_DEV_STAT_RC_ADDED                 (0x03)
-#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING        (0x04)
-#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA            (0x05)
-#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED      (0x06)
-#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED           (0x07)
-#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)
+#define MPI_EVENT_SAS_DEV_STAT_RC_ADDED                     (0x03)
+#define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING            (0x04)
+#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA                (0x05)
+#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED          (0x06)
+#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED               (0x07)
+#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET     (0x08)
+#define MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL       (0x09)
+#define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL   (0x0A)
+#define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL   (0x0B)
+#define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL       (0x0C)
+#define MPI_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION        (0x0D)
 
 
 /* SCSI Event data for Queue Full event */
@@ -770,6 +811,27 @@
 } EVENT_DATA_SAS_SES, MPI_POINTER PTR_EVENT_DATA_SAS_SES,
   MpiEventDataSasSes_t, MPI_POINTER pMpiEventDataSasSes_t;
 
+/* SAS Broadcast Primitive Event data */
+
+typedef struct _EVENT_DATA_SAS_BROADCAST_PRIMITIVE
+{
+    U8                      PhyNum;                     /* 00h */
+    U8                      Port;                       /* 01h */
+    U8                      PortWidth;                  /* 02h */
+    U8                      Primitive;                  /* 04h */
+} EVENT_DATA_SAS_BROADCAST_PRIMITIVE,
+  MPI_POINTER PTR_EVENT_DATA_SAS_BROADCAST_PRIMITIVE,
+  MpiEventDataSasBroadcastPrimitive_t,
+  MPI_POINTER pMpiEventDataSasBroadcastPrimitive_t;
+
+#define MPI_EVENT_PRIMITIVE_CHANGE              (0x01)
+#define MPI_EVENT_PRIMITIVE_EXPANDER            (0x03)
+#define MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT  (0x04)
+#define MPI_EVENT_PRIMITIVE_RESERVED3           (0x05)
+#define MPI_EVENT_PRIMITIVE_RESERVED4           (0x06)
+#define MPI_EVENT_PRIMITIVE_CHANGE0_RESERVED    (0x07)
+#define MPI_EVENT_PRIMITIVE_CHANGE1_RESERVED    (0x08)
+
 /* SAS Phy Link Status Event data */
 
 typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS
@@ -829,8 +891,104 @@
 #define MPI_EVENT_DSCVRY_ERR_DS_SMP_CRC_ERROR               (0x00000100)
 #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_SUBTRACTIVE          (0x00000200)
 #define MPI_EVENT_DSCVRY_ERR_DS_TABLE_TO_TABLE              (0x00000400)
-#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS                (0x00000800)
+#define MPI_EVENT_DSCVRY_ERR_DS_UNSUPPORTED_DEVICE          (0x00000800)
 #define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS            (0x00001000)
+#define MPI_EVENT_DSCVRY_ERR_DS_MULTI_PORT_DOMAIN           (0x00002000)
+
+/* SAS SMP Error Event data */
+
+typedef struct _EVENT_DATA_SAS_SMP_ERROR
+{
+    U8                      Status;                     /* 00h */
+    U8                      Port;                       /* 01h */
+    U8                      SMPFunctionResult;          /* 02h */
+    U8                      Reserved1;                  /* 03h */
+    U64                     SASAddress;                 /* 04h */
+} EVENT_DATA_SAS_SMP_ERROR, MPI_POINTER PTR_EVENT_DATA_SAS_SMP_ERROR,
+  MpiEventDataSasSmpError_t, MPI_POINTER pMpiEventDataSasSmpError_t;
+
+/* defines for the Status field of the SAS SMP Error event */
+#define MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID         (0x00)
+#define MPI_EVENT_SAS_SMP_CRC_ERROR                     (0x01)
+#define MPI_EVENT_SAS_SMP_TIMEOUT                       (0x02)
+#define MPI_EVENT_SAS_SMP_NO_DESTINATION                (0x03)
+#define MPI_EVENT_SAS_SMP_BAD_DESTINATION               (0x04)
+
+/* SAS Initiator Device Status Change Event data */
+
+typedef struct _EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE
+{
+    U8                      ReasonCode;                 /* 00h */
+    U8                      Port;                       /* 01h */
+    U16                     DevHandle;                  /* 02h */
+    U64                     SASAddress;                 /* 04h */
+} EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE,
+  MPI_POINTER PTR_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE,
+  MpiEventDataSasInitDevStatusChange_t,
+  MPI_POINTER pMpiEventDataSasInitDevStatusChange_t;
+
+/* defines for the ReasonCode field of the SAS Initiator Device Status Change event */
+#define MPI_EVENT_SAS_INIT_RC_ADDED                 (0x01)
+
+/* SAS Initiator Device Table Overflow Event data */
+
+typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW
+{
+    U8                      MaxInit;                    /* 00h */
+    U8                      CurrentInit;                /* 01h */
+    U16                     Reserved1;                  /* 02h */
+} EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
+  MPI_POINTER PTR_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW,
+  MpiEventDataSasInitTableOverflow_t,
+  MPI_POINTER pMpiEventDataSasInitTableOverflow_t;
+
+/* SAS Expander Status Change Event data */
+
+typedef struct _EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE
+{
+    U8                      ReasonCode;             /* 00h */
+    U8                      Reserved1;              /* 01h */
+    U16                     Reserved2;              /* 02h */
+    U8                      PhysicalPort;           /* 04h */
+    U8                      Reserved3;              /* 05h */
+    U16                     EnclosureHandle;        /* 06h */
+    U64                     SASAddress;             /* 08h */
+    U32                     DiscoveryStatus;        /* 10h */
+    U16                     DevHandle;              /* 14h */
+    U16                     ParentDevHandle;        /* 16h */
+    U16                     ExpanderChangeCount;    /* 18h */
+    U16                     ExpanderRouteIndexes;   /* 1Ah */
+    U8                      NumPhys;                /* 1Ch */
+    U8                      SASLevel;               /* 1Dh */
+    U8                      Flags;                  /* 1Eh */
+    U8                      Reserved4;              /* 1Fh */
+} EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE,
+  MPI_POINTER PTR_EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE,
+  MpiEventDataSasExpanderStatusChange_t,
+  MPI_POINTER pMpiEventDataSasExpanderStatusChange_t;
+
+/* values for ReasonCode field of SAS Expander Status Change Event data */
+#define MPI_EVENT_SAS_EXP_RC_ADDED                      (0x00)
+#define MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING             (0x01)
+
+/* values for DiscoveryStatus field of SAS Expander Status Change Event data */
+#define MPI_EVENT_SAS_EXP_DS_LOOP_DETECTED              (0x00000001)
+#define MPI_EVENT_SAS_EXP_DS_UNADDRESSABLE_DEVICE       (0x00000002)
+#define MPI_EVENT_SAS_EXP_DS_MULTIPLE_PORTS             (0x00000004)
+#define MPI_EVENT_SAS_EXP_DS_EXPANDER_ERR               (0x00000008)
+#define MPI_EVENT_SAS_EXP_DS_SMP_TIMEOUT                (0x00000010)
+#define MPI_EVENT_SAS_EXP_DS_OUT_ROUTE_ENTRIES          (0x00000020)
+#define MPI_EVENT_SAS_EXP_DS_INDEX_NOT_EXIST            (0x00000040)
+#define MPI_EVENT_SAS_EXP_DS_SMP_FUNCTION_FAILED        (0x00000080)
+#define MPI_EVENT_SAS_EXP_DS_SMP_CRC_ERROR              (0x00000100)
+#define MPI_EVENT_SAS_EXP_DS_SUBTRACTIVE_LINK           (0x00000200)
+#define MPI_EVENT_SAS_EXP_DS_TABLE_LINK                 (0x00000400)
+#define MPI_EVENT_SAS_EXP_DS_UNSUPPORTED_DEVICE         (0x00000800)
+
+/* values for Flags field of SAS Expander Status Change Event data */
+#define MPI_EVENT_SAS_EXP_FLAGS_ROUTE_TABLE_CONFIG      (0x02)
+#define MPI_EVENT_SAS_EXP_FLAGS_CONFIG_IN_PROGRESS      (0x01)
+
 
 
 /*****************************************************************************
@@ -858,11 +1016,16 @@
 
 #define MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT    (0x01)
 
-#define MPI_FW_DOWNLOAD_ITYPE_RESERVED      (0x00)
-#define MPI_FW_DOWNLOAD_ITYPE_FW            (0x01)
-#define MPI_FW_DOWNLOAD_ITYPE_BIOS          (0x02)
-#define MPI_FW_DOWNLOAD_ITYPE_NVDATA        (0x03)
+#define MPI_FW_DOWNLOAD_ITYPE_RESERVED          (0x00)
+#define MPI_FW_DOWNLOAD_ITYPE_FW                (0x01)
+#define MPI_FW_DOWNLOAD_ITYPE_BIOS              (0x02)
+#define MPI_FW_DOWNLOAD_ITYPE_NVDATA            (0x03)
 #define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER        (0x04)
+#define MPI_FW_DOWNLOAD_ITYPE_MANUFACTURING     (0x06)
+#define MPI_FW_DOWNLOAD_ITYPE_CONFIG_1          (0x07)
+#define MPI_FW_DOWNLOAD_ITYPE_CONFIG_2          (0x08)
+#define MPI_FW_DOWNLOAD_ITYPE_MEGARAID          (0x09)
+#define MPI_FW_DOWNLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B)
 
 
 typedef struct _FWDownloadTCSGE
@@ -911,12 +1074,18 @@
 } MSG_FW_UPLOAD, MPI_POINTER PTR_MSG_FW_UPLOAD,
   FWUpload_t, MPI_POINTER pFWUpload_t;
 
-#define MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM      (0x00)
-#define MPI_FW_UPLOAD_ITYPE_FW_FLASH        (0x01)
-#define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH      (0x02)
-#define MPI_FW_UPLOAD_ITYPE_NVDATA          (0x03)
-#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER      (0x04)
-#define MPI_FW_UPLOAD_ITYPE_FW_BACKUP       (0x05)
+#define MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM          (0x00)
+#define MPI_FW_UPLOAD_ITYPE_FW_FLASH            (0x01)
+#define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH          (0x02)
+#define MPI_FW_UPLOAD_ITYPE_NVDATA              (0x03)
+#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER          (0x04)
+#define MPI_FW_UPLOAD_ITYPE_FW_BACKUP           (0x05)
+#define MPI_FW_UPLOAD_ITYPE_MANUFACTURING       (0x06)
+#define MPI_FW_UPLOAD_ITYPE_CONFIG_1            (0x07)
+#define MPI_FW_UPLOAD_ITYPE_CONFIG_2            (0x08)
+#define MPI_FW_UPLOAD_ITYPE_MEGARAID            (0x09)
+#define MPI_FW_UPLOAD_ITYPE_COMPLETE            (0x0A)
+#define MPI_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK   (0x0B)
 
 typedef struct _FWUploadTCSGE
 {
@@ -1041,5 +1210,6 @@
 #define MPI_EXT_IMAGE_TYPE_FW                   (0x01)
 #define MPI_EXT_IMAGE_TYPE_NVDATA               (0x03)
 #define MPI_EXT_IMAGE_TYPE_BOOTLOADER           (0x04)
+#define MPI_EXT_IMAGE_TYPE_INITIALIZATION       (0x05)
 
 #endif
Index: mpi_fc.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_fc.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpilib/mpi_fc.h -L sys/dev/mpt/mpilib/mpi_fc.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpilib/mpi_fc.h
+++ sys/dev/mpt/mpilib/mpi_fc.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_fc.h,v 1.5.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_fc.h,v 1.6 2006/01/21 00:29:51 mjacob Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
--- sys/dev/mpt/mpilib/mpi_log_fc.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_log_fc.h,v 1.1.2.1 2006/06/08 17:47:35 mjacob Exp $ */
-/*-
- * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    substantially similar to the "NO WARRANTY" disclaimer below
- *    ("Disclaimer") and any redistribution must be conditioned upon including
- *    a substantially similar Disclaimer requirement for further binary
- *    redistribution.
- * 3. Neither the name of the LSI Logic Corporation 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 OWNER 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 THE COPYRIGHT
- * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  NAME:           fc_log.h
- *  SUMMARY:        MPI IocLogInfo definitions for the SYMFC9xx chips
- *  DESCRIPTION:    Contains the enumerated list of values that may be returned
- *                  in the IOCLogInfo field of a MPI Default Reply Message.
- *
- *  CREATION DATE:  6/02/2000
- *  ID:             $Id: //prod/main/platform/os/linux/drivers/message/fusion/lsi/mpi_log_fc.h#1 $
- */
-
-
-/*
- * MpiIocLogInfo_t enum
- *
- * These 32 bit values are used in the IOCLogInfo field of the MPI reply
- * messages.
- * The value is 0xabcccccc where
- *          a = The type of log info as per the MPI spec. Since these codes are
- *              all for Fibre Channel this value will always be 2.
- *          b = Specifies a subclass of the firmware where
- *                  0 = FCP Initiator
- *                  1 = FCP Target
- *                  2 = LAN
- *                  3 = MPI Message Layer
- *                  4 = FC Link
- *                  5 = Context Manager
- *                  6 = Invalid Field Offset
- *                  7 = State Change Info
- *                  all others are reserved for future use
- *          c = A specific value within the subclass.
- *
- * NOTE: Any new values should be added to the end of each subclass so that the
- *       codes remain consistent across firmware releases.
- */
-typedef enum _MpiIocLogInfoFc
-{
-    MPI_IOCLOGINFO_FC_INIT_BASE                     = 0x20000000,
-    MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME   = 0x20000003, /* Bad Rx Frame, bad end of frame primative */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN           = 0x20000004, /* Bad Rx Frame, overrun */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER           = 0x20000005, /* Other errors caught by IOC which require retries */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD       = 0x20000006, /* Main processor could not initialize sub-processor */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN         = 0x20000007, /* Scatter Gather overrun  */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS      = 0x20000008, /* Receiver detected context mismatch via invalid header */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type  */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE       = 0x2000000A, /* Link failure occurred  */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT         = 0x2000000B, /* Transmitter timeout error */
-
-    MPI_IOCLOGINFO_FC_TARGET_BASE                   = 0x21000000,
-    MPI_IOCLOGINFO_FC_TARGET_NO_PDISC               = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */
-    MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN               = 0x21000002, /* not sent because we are not logged in to the remote node */
-    MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP     = 0x21000003, /* Data Out, Auto Response, not sent due to a LIP */
-    MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP     = 0x21000004, /* Data In, Auto Response, not sent due to a LIP */
-    MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA      = 0x21000005, /* Data In, Auto Response, missing data frames */
-    MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP     = 0x21000006, /* Data Out, No Response, not sent due to a LIP */
-    MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP     = 0x21000007, /* Auto-response after a write not sent due to a LIP */
-    MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP     = 0x21000008, /* Data In, No Response, not completed due to a LIP */
-    MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA      = 0x21000009, /* Data In, No Response, missing data frames */
-    MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP     = 0x2100000a, /* Manual Response not sent due to a LIP */
-    MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3             = 0x2100000b, /* not sent because remote node does not support Class 3 */
-    MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID        = 0x2100000c, /* not sent because login to remote node not validated */
-    MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND          = 0x2100000e, /* cleared from the outbound queue after a logout */
-    MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN    = 0x2100000f, /* cleared waiting for data after a logout */
-
-    MPI_IOCLOGINFO_FC_LAN_BASE                      = 0x22000000,
-    MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING         = 0x22000001, /* Transaction Context Sgl Missing */
-    MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE         = 0x22000002, /* Transaction Context found before an EOB */
-    MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET        = 0x22000003, /* Transaction Context value has reserved bits set */
-    MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG            = 0x22000004, /* Invalid SGL Flags */
-
-    MPI_IOCLOGINFO_FC_MSG_BASE                      = 0x23000000,
-
-    MPI_IOCLOGINFO_FC_LINK_BASE                     = 0x24000000,
-    MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT        = 0x24000001, /* Loop initialization timed out */
-    MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED      = 0x24000002, /* Another system controller already initialized the loop */
-    MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED     = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */
-    MPI_IOCLOGINFO_FC_LINK_CRC_ERROR                = 0x24000004, /* CRC check detected error on received frame */
-
-    MPI_IOCLOGINFO_FC_CTX_BASE                      = 0x25000000,
-
-    MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET     = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */
-    MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET      = 0x26ffffff,
-
-    MPI_IOCLOGINFO_FC_STATE_CHANGE                  = 0x27000000  /* The lower 24 bits give additional information concerning state change */
-
-} MpiIocLogInfoFc_t;
Index: mpi_sas.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_sas.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -L sys/dev/mpt/mpilib/mpi_sas.h -L sys/dev/mpt/mpilib/mpi_sas.h -u -r1.1 -r1.2
--- sys/dev/mpt/mpilib/mpi_sas.h
+++ sys/dev/mpt/mpilib/mpi_sas.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_sas.h,v 1.2.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_sas.h,v 1.3 2007/06/03 22:58:27 scottl Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
@@ -29,12 +29,11 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
  * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *
  *           Name:  mpi_sas.h
  *          Title:  MPI Serial Attached SCSI structures and definitions
  *  Creation Date:  August 19, 2004
  *
- *    mpi_sas.h Version:  01.05.02
+ *    mpi_sas.h Version:  01.05.04
  *
  *  Version History
  *  ---------------
@@ -45,6 +44,12 @@
  *  08-30-05  01.05.02  Added DeviceInfo bit for SEP.
  *                      Added PrimFlags and Primitive field to SAS IO Unit
  *                      Control request, and added a new operation code.
+ *  03-27-06  01.05.03  Added Force Full Discovery, Transmit Port Select Signal,
+ *                      and Remove Device operations to SAS IO Unit Control.
+ *                      Added DevHandle field to SAS IO Unit Control request and
+ *                      reply.
+ *  10-11-06  01.05.04  Fixed the name of a define for Operation field of SAS IO
+ *                      Unit Control request.
  *  --------------------------------------------------------------------------
  */
 
@@ -237,7 +242,7 @@
     U8                      Reserved1;          /* 01h */
     U8                      ChainOffset;        /* 02h */
     U8                      Function;           /* 03h */
-    U16                     Reserved2;          /* 04h */
+    U16                     DevHandle;          /* 04h */
     U8                      Reserved3;          /* 06h */
     U8                      MsgFlags;           /* 07h */
     U32                     MsgContext;         /* 08h */
@@ -252,13 +257,17 @@
   SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t;
 
 /* values for the Operation field */
-#define MPI_SAS_OP_CLEAR_NOT_PRESENT             (0x01)
-#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT          (0x02)
-#define MPI_SAS_OP_PHY_LINK_RESET                (0x06)
-#define MPI_SAS_OP_PHY_HARD_RESET                (0x07)
-#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG           (0x08)
-#define MPI_SAS_OP_MAP_CURRENT                   (0x09)
+#define MPI_SAS_OP_CLEAR_NOT_PRESENT            (0x01)
+#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT         (0x02)
+#define MPI_SAS_OP_PHY_LINK_RESET               (0x06)
+#define MPI_SAS_OP_PHY_HARD_RESET               (0x07)
+#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG          (0x08)
+#define MPI_SAS_OP_MAP_CURRENT                  (0x09)
 #define MPI_SAS_OP_SEND_PRIMITIVE               (0x0A)
+#define MPI_SAS_OP_FORCE_FULL_DISCOVERY         (0x0B)
+#define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL  (0x0C)
+#define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE       (0x0D)  /* obsolete name */
+#define MPI_SAS_OP_REMOVE_DEVICE                (0x0D)
 
 /* values for the PrimFlags field */
 #define MPI_SAS_PRIMFLAGS_SINGLE                (0x08)
@@ -273,7 +282,7 @@
     U8                      Reserved1;          /* 01h */
     U8                      MsgLength;          /* 02h */
     U8                      Function;           /* 03h */
-    U16                     Reserved2;          /* 04h */
+    U16                     DevHandle;          /* 04h */
     U8                      Reserved3;          /* 06h */
     U8                      MsgFlags;           /* 07h */
     U32                     MsgContext;         /* 08h */
Index: mpi_tool.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_tool.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -L sys/dev/mpt/mpilib/mpi_tool.h -L sys/dev/mpt/mpilib/mpi_tool.h -u -r1.1 -r1.2
--- sys/dev/mpt/mpilib/mpi_tool.h
+++ sys/dev/mpt/mpilib/mpi_tool.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_tool.h,v 1.1.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_tool.h,v 1.1 2006/01/21 00:29:51 mjacob Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
Index: mpi_targ.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_targ.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpilib/mpi_targ.h -L sys/dev/mpt/mpilib/mpi_targ.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpilib/mpi_targ.h
+++ sys/dev/mpt/mpilib/mpi_targ.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_targ.h,v 1.5.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_targ.h,v 1.7 2007/06/03 22:58:27 scottl Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
@@ -29,12 +29,11 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
  * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *
  *           Name:  mpi_targ.h
  *          Title:  MPI Target mode messages and structures
  *  Creation Date:  June 22, 2000
  *
- *    mpi_targ.h Version:  01.05.05
+ *    mpi_targ.h Version:  01.05.06
  *
  *  Version History
  *  ---------------
@@ -82,6 +81,7 @@
  *  02-22-05  01.05.03  Changed a comment.
  *  03-11-05  01.05.04  Removed TargetAssistExtended Request.
  *  06-24-05  01.05.05  Added TargetAssistExtended structures and defines.
+ *  03-27-06  01.05.06  Added a comment.
  *  --------------------------------------------------------------------------
  */
 
@@ -379,7 +379,7 @@
 #define TARGET_ASSIST_FLAGS_CONFIRMED               (0x08)
 #define TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER       (0x80)
 
-
+/* Standard Target Mode Reply message */
 typedef struct _MSG_TARGET_ERROR_REPLY
 {
     U16                     Reserved;                   /* 00h */
Index: mpi_cnfg.h
===================================================================
RCS file: /home/cvs/src/sys/dev/mpt/mpilib/mpi_cnfg.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/dev/mpt/mpilib/mpi_cnfg.h -L sys/dev/mpt/mpilib/mpi_cnfg.h -u -r1.2 -r1.3
--- sys/dev/mpt/mpilib/mpi_cnfg.h
+++ sys/dev/mpt/mpilib/mpi_cnfg.h
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_cnfg.h,v 1.6.2.1 2006/06/08 17:47:35 mjacob Exp $ */
+/* $FreeBSD: src/sys/dev/mpt/mpilib/mpi_cnfg.h,v 1.9 2007/06/03 22:58:26 scottl Exp $ */
 /*-
  * Copyright (c) 2000-2005, LSI Logic Corporation and its contributors.
  * All rights reserved.
@@ -33,7 +33,7 @@
  *          Title:  MPI Config message, structures, and Pages
  *  Creation Date:  July 27, 2000
  *
- *    mpi_cnfg.h Version:  01.05.11
+ *    mpi_cnfg.h Version:  01.05.15
  *
  *  Version History
  *  ---------------
@@ -293,6 +293,48 @@
  *                      Added postpone SATA Init bit to SAS IO Unit Page 1
  *                      ControlFlags.
  *                      Changed LogEntry format for Log Page 0.
+ *  03-27-06  01.05.12  Added two new Flags defines for Manufacturing Page 4.
+ *                      Added Manufacturing Page 7.
+ *                      Added MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING.
+ *                      Added IOC Page 6.
+ *                      Added PrevBootDeviceForm field to CONFIG_PAGE_BIOS_2.
+ *                      Added MaxLBAHigh field to RAID Volume Page 0.
+ *                      Added Nvdata version fields to SAS IO Unit Page 0.
+ *                      Added AdditionalControlFlags, MaxTargetPortConnectTime,
+ *                      ReportDeviceMissingDelay, and IODeviceMissingDelay
+ *                      fields to SAS IO Unit Page 1.
+ *  10-11-06  01.05.13  Added NumForceWWID field and ForceWWID array to
+ *                      Manufacturing Page 5.
+ *                      Added Manufacturing pages 8 through 10.
+ *                      Added defines for supported metadata size bits in
+ *                      CapabilitiesFlags field of IOC Page 6.
+ *                      Added defines for metadata size bits in VolumeSettings
+ *                      field of RAID Volume Page 0.
+ *                      Added SATA Link Reset settings, Enable SATA Asynchronous
+ *                      Notification bit, and HideNonZeroAttachedPhyIdentifiers
+ *                      bit to AdditionalControlFlags field of SAS IO Unit
+ *                      Page 1.
+ *                      Added defines for Enclosure Devices Unmapped and
+ *                      Device Limit Exceeded bits in Status field of SAS IO
+ *                      Unit Page 2.
+ *                      Added more AccessStatus values for SAS Device Page 0.
+ *                      Added bit for SATA Asynchronous Notification Support in
+ *                      Flags field of SAS Device Page 0.
+ *  02-28-07  01.05.14  Added ExtFlags field to Manufacturing Page 4.
+ *                      Added Disable SMART Polling for CapabilitiesFlags of
+ *                      IOC Page 6.
+ *                      Added Disable SMART Polling to DeviceSettings of BIOS
+ *                      Page 1.
+ *                      Added Multi-Port Domain bit for DiscoveryStatus field
+ *                      of SAS IO Unit Page.
+ *                      Added Multi-Port Domain Illegal flag for SAS IO Unit
+ *                      Page 1 AdditionalControlFlags field.
+ *  05-24-07  01.05.15  Added Hide Physical Disks with Non-Integrated RAID
+ *                      Metadata bit to Manufacturing Page 4 ExtFlags field.
+ *                      Added Internal Connector to End Device Present bit to
+ *                      Expander Page 0 Flags field.
+ *                      Fixed define for
+ *                      MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED.
  *  --------------------------------------------------------------------------
  */
 
@@ -639,7 +681,7 @@
     U8                              InfoSize1;          /* 0Bh */
     U8                              InquirySize;        /* 0Ch */
     U8                              Flags;              /* 0Dh */
-    U16                             Reserved2;          /* 0Eh */
+    U16                             ExtFlags;           /* 0Eh */
     U8                              InquiryData[56];    /* 10h */
     U32                             ISVolumeSettings;   /* 48h */
     U32                             IMEVolumeSettings;  /* 4Ch */
@@ -658,9 +700,11 @@
 } CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
   ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
 
-#define MPI_MANUFACTURING4_PAGEVERSION                  (0x03)
+#define MPI_MANUFACTURING4_PAGEVERSION                  (0x05)
 
 /* defines for the Flags field */
+#define MPI_MANPAGE4_FORCE_BAD_BLOCK_TABLE              (0x80)
+#define MPI_MANPAGE4_FORCE_OFFLINE_FAILOVER             (0x40)
 #define MPI_MANPAGE4_IME_DISABLE                        (0x20)
 #define MPI_MANPAGE4_IM_DISABLE                         (0x10)
 #define MPI_MANPAGE4_IS_DISABLE                         (0x08)
@@ -668,18 +712,31 @@
 #define MPI_MANPAGE4_IM_RESYNC_CACHE_ENABLE             (0x02)
 #define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA                 (0x01)
 
+/* defines for the ExtFlags field */
+#define MPI_MANPAGE4_EXTFLAGS_HIDE_NON_IR_METADATA      (0x0008)
+#define MPI_MANPAGE4_EXTFLAGS_SAS_CACHE_DISABLE         (0x0004)
+#define MPI_MANPAGE4_EXTFLAGS_SATA_CACHE_DISABLE        (0x0002)
+#define MPI_MANPAGE4_EXTFLAGS_LEGACY_MODE               (0x0001)
+
+
+#ifndef MPI_MANPAGE5_NUM_FORCEWWID
+#define MPI_MANPAGE5_NUM_FORCEWWID      (1)
+#endif
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_5
 {
     CONFIG_PAGE_HEADER              Header;             /* 00h */
     U64                             BaseWWID;           /* 04h */
     U8                              Flags;              /* 0Ch */
-    U8                              Reserved1;          /* 0Dh */
+    U8                              NumForceWWID;       /* 0Dh */
     U16                             Reserved2;          /* 0Eh */
+    U32                             Reserved3;          /* 10h */
+    U32                             Reserved4;          /* 14h */
+    U64                             ForceWWID[MPI_MANPAGE5_NUM_FORCEWWID]; /* 18h */
 } CONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5,
   ManufacturingPage5_t, MPI_POINTER pManufacturingPage5_t;
 
-#define MPI_MANUFACTURING5_PAGEVERSION                  (0x01)
+#define MPI_MANUFACTURING5_PAGEVERSION                  (0x02)
 
 /* defines for the Flags field */
 #define MPI_MANPAGE5_TWO_WWID_PER_PHY                   (0x01)
@@ -695,6 +752,96 @@
 #define MPI_MANUFACTURING6_PAGEVERSION                  (0x00)
 
 
+typedef struct _MPI_MANPAGE7_CONNECTOR_INFO
+{
+    U32                         Pinout;                 /* 00h */
+    U8                          Connector[16];          /* 04h */
+    U8                          Location;               /* 14h */
+    U8                          Reserved1;              /* 15h */
+    U16                         Slot;                   /* 16h */
+    U32                         Reserved2;              /* 18h */
+} MPI_MANPAGE7_CONNECTOR_INFO, MPI_POINTER PTR_MPI_MANPAGE7_CONNECTOR_INFO,
+  MpiManPage7ConnectorInfo_t, MPI_POINTER pMpiManPage7ConnectorInfo_t;
+
+/* defines for the Pinout field */
+#define MPI_MANPAGE7_PINOUT_SFF_8484_L4                 (0x00080000)
+#define MPI_MANPAGE7_PINOUT_SFF_8484_L3                 (0x00040000)
+#define MPI_MANPAGE7_PINOUT_SFF_8484_L2                 (0x00020000)
+#define MPI_MANPAGE7_PINOUT_SFF_8484_L1                 (0x00010000)
+#define MPI_MANPAGE7_PINOUT_SFF_8470_L4                 (0x00000800)
+#define MPI_MANPAGE7_PINOUT_SFF_8470_L3                 (0x00000400)
+#define MPI_MANPAGE7_PINOUT_SFF_8470_L2                 (0x00000200)
+#define MPI_MANPAGE7_PINOUT_SFF_8470_L1                 (0x00000100)
+#define MPI_MANPAGE7_PINOUT_SFF_8482                    (0x00000002)
+#define MPI_MANPAGE7_PINOUT_CONNECTION_UNKNOWN          (0x00000001)
+
+/* defines for the Location field */
+#define MPI_MANPAGE7_LOCATION_UNKNOWN                   (0x01)
+#define MPI_MANPAGE7_LOCATION_INTERNAL                  (0x02)
+#define MPI_MANPAGE7_LOCATION_EXTERNAL                  (0x04)
+#define MPI_MANPAGE7_LOCATION_SWITCHABLE                (0x08)
+#define MPI_MANPAGE7_LOCATION_AUTO                      (0x10)
+#define MPI_MANPAGE7_LOCATION_NOT_PRESENT               (0x20)
+#define MPI_MANPAGE7_LOCATION_NOT_CONNECTED             (0x80)
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check NumPhys at runtime.
+ */
+#ifndef MPI_MANPAGE7_CONNECTOR_INFO_MAX
+#define MPI_MANPAGE7_CONNECTOR_INFO_MAX   (1)
+#endif
+
+typedef struct _CONFIG_PAGE_MANUFACTURING_7
+{
+    CONFIG_PAGE_HEADER          Header;                 /* 00h */
+    U32                         Reserved1;              /* 04h */
+    U32                         Reserved2;              /* 08h */
+    U32                         Flags;                  /* 0Ch */
+    U8                          EnclosureName[16];      /* 10h */
+    U8                          NumPhys;                /* 20h */
+    U8                          Reserved3;              /* 21h */
+    U16                         Reserved4;              /* 22h */
+    MPI_MANPAGE7_CONNECTOR_INFO ConnectorInfo[MPI_MANPAGE7_CONNECTOR_INFO_MAX]; /* 24h */
+} CONFIG_PAGE_MANUFACTURING_7, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_7,
+  ManufacturingPage7_t, MPI_POINTER pManufacturingPage7_t;
+
+#define MPI_MANUFACTURING7_PAGEVERSION                  (0x00)
+
+/* defines for the Flags field */
+#define MPI_MANPAGE7_FLAG_USE_SLOT_INFO                 (0x00000001)
+
+
+typedef struct _CONFIG_PAGE_MANUFACTURING_8
+{
+    CONFIG_PAGE_HEADER              Header;             /* 00h */
+    U32                             ProductSpecificInfo;/* 04h */
+} CONFIG_PAGE_MANUFACTURING_8, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_8,
+  ManufacturingPage8_t, MPI_POINTER pManufacturingPage8_t;
+
+#define MPI_MANUFACTURING8_PAGEVERSION                  (0x00)
+
+
+typedef struct _CONFIG_PAGE_MANUFACTURING_9
+{
+    CONFIG_PAGE_HEADER              Header;             /* 00h */
+    U32                             ProductSpecificInfo;/* 04h */
+} CONFIG_PAGE_MANUFACTURING_9, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_9,
+  ManufacturingPage9_t, MPI_POINTER pManufacturingPage9_t;
+
+#define MPI_MANUFACTURING9_PAGEVERSION                  (0x00)
+
+
+typedef struct _CONFIG_PAGE_MANUFACTURING_10
+{
+    CONFIG_PAGE_HEADER              Header;             /* 00h */
+    U32                             ProductSpecificInfo;/* 04h */
+} CONFIG_PAGE_MANUFACTURING_10, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_10,
+  ManufacturingPage10_t, MPI_POINTER pManufacturingPage10_t;
+
+#define MPI_MANUFACTURING10_PAGEVERSION                 (0x00)
+
+
 /****************************************************************************
 *   IO Unit Config Pages
 ****************************************************************************/
@@ -894,7 +1041,7 @@
 } CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
   IOCPage2_t, MPI_POINTER pIOCPage2_t;
 
-#define MPI_IOCPAGE2_PAGEVERSION                        (0x03)
+#define MPI_IOCPAGE2_PAGEVERSION                        (0x04)
 
 /* IOC Page 2 Capabilities flags */
 
@@ -905,6 +1052,7 @@
 #define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT           (0x00000010)
 #define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT          (0x00000020)
 #define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT          (0x00000040)
+#define MPI_IOCPAGE2_CAP_FLAGS_RAID_64_BIT_ADDRESSING   (0x10000000)
 #define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT              (0x20000000)
 #define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT            (0x40000000)
 #define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT    (0x80000000)
@@ -1002,6 +1150,50 @@
 
 #define MPI_IOCPAGE5_PAGEVERSION                        (0x00)
 
+typedef struct _CONFIG_PAGE_IOC_6
+{
+    CONFIG_PAGE_HEADER          Header;                         /* 00h */
+    U32                         CapabilitiesFlags;              /* 04h */
+    U8                          MaxDrivesIS;                    /* 08h */
+    U8                          MaxDrivesIM;                    /* 09h */
+    U8                          MaxDrivesIME;                   /* 0Ah */
+    U8                          Reserved1;                      /* 0Bh */
+    U8                          MinDrivesIS;                    /* 0Ch */
+    U8                          MinDrivesIM;                    /* 0Dh */
+    U8                          MinDrivesIME;                   /* 0Eh */
+    U8                          Reserved2;                      /* 0Fh */
+    U8                          MaxGlobalHotSpares;             /* 10h */
+    U8                          Reserved3;                      /* 11h */
+    U16                         Reserved4;                      /* 12h */
+    U32                         Reserved5;                      /* 14h */
+    U32                         SupportedStripeSizeMapIS;       /* 18h */
+    U32                         SupportedStripeSizeMapIME;      /* 1Ch */
+    U32                         Reserved6;                      /* 20h */
+    U8                          MetadataSize;                   /* 24h */
+    U8                          Reserved7;                      /* 25h */
+    U16                         Reserved8;                      /* 26h */
+    U16                         MaxBadBlockTableEntries;        /* 28h */
+    U16                         Reserved9;                      /* 2Ah */
+    U16                         IRNvsramUsage;                  /* 2Ch */
+    U16                         Reserved10;                     /* 2Eh */
+    U32                         IRNvsramVersion;                /* 30h */
+    U32                         Reserved11;                     /* 34h */
+    U32                         Reserved12;                     /* 38h */
+} CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6,
+  IOCPage6_t, MPI_POINTER pIOCPage6_t;
+
+#define MPI_IOCPAGE6_PAGEVERSION                        (0x01)
+
+/* IOC Page 6 Capabilities Flags */
+
+#define MPI_IOCPAGE6_CAP_FLAGS_DISABLE_SMART_POLLING    (0x00000008)
+
+#define MPI_IOCPAGE6_CAP_FLAGS_MASK_METADATA_SIZE       (0x00000006)
+#define MPI_IOCPAGE6_CAP_FLAGS_64MB_METADATA_SIZE       (0x00000000)
+#define MPI_IOCPAGE6_CAP_FLAGS_512MB_METADATA_SIZE      (0x00000002)
+
+#define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE         (0x00000001)
+
 
 /****************************************************************************
 *   BIOS Config Pages
@@ -1066,6 +1258,7 @@
 #define MPI_BIOSPAGE1_IOCSET_ALTERNATE_CHS              (0x00000008)
 
 /* values for the DeviceSettings field */
+#define MPI_BIOSPAGE1_DEVSET_DISABLE_SMART_POLLING      (0x00000010)
 #define MPI_BIOSPAGE1_DEVSET_DISABLE_SEQ_LUN            (0x00000008)
 #define MPI_BIOSPAGE1_DEVSET_DISABLE_RM_LUN             (0x00000004)
 #define MPI_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN         (0x00000002)
@@ -1245,13 +1438,13 @@
     U32                         Reserved5;              /* 14h */
     U32                         Reserved6;              /* 18h */
     U8                          BootDeviceForm;         /* 1Ch */
-    U8                          Reserved7;              /* 1Dh */
+    U8                          PrevBootDeviceForm;     /* 1Ch */
     U16                         Reserved8;              /* 1Eh */
     MPI_BIOSPAGE2_BOOT_DEVICE   BootDevice;             /* 20h */
 } CONFIG_PAGE_BIOS_2, MPI_POINTER PTR_CONFIG_PAGE_BIOS_2,
   BIOSPage2_t, MPI_POINTER pBIOSPage2_t;
 
-#define MPI_BIOSPAGE2_PAGEVERSION                       (0x01)
+#define MPI_BIOSPAGE2_PAGEVERSION                       (0x02)
 
 #define MPI_BIOSPAGE2_FORM_MASK                         (0x0F)
 #define MPI_BIOSPAGE2_FORM_ADAPTER_ORDER                (0x00)
@@ -1602,9 +1795,9 @@
 #define MPI_FCPORTPAGE0_SUPPORT_CLASS_3                 (0x00000004)
 
 #define MPI_FCPORTPAGE0_SUPPORT_SPEED_UKNOWN            (0x00000000) /* (SNIA)HBA_PORTSPEED_UNKNOWN 0   Unknown - transceiver incapable of reporting */
-#define MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED             (0x00000001) /* (SNIA)HBA_PORTSPEED_1GBIT 1  1 GBit/sec  */
-#define MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED             (0x00000002) /* (SNIA)HBA_PORTSPEED_2GBIT 2  2 GBit/sec  */
-#define MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED            (0x00000004) /* (SNIA)HBA_PORTSPEED_10GBIT 4 10 GBit/sec */
+#define MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED             (0x00000001) /* (SNIA)HBA_PORTSPEED_1GBIT   1   1 GBit/sec */
+#define MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED             (0x00000002) /* (SNIA)HBA_PORTSPEED_2GBIT   2   2 GBit/sec */
+#define MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED            (0x00000004) /* (SNIA)HBA_PORTSPEED_10GBIT  4  10 GBit/sec */
 #define MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED             (0x00000008) /* (SNIA)HBA_PORTSPEED_4GBIT   8   4 GBit/sec */
 
 #define MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN            MPI_FCPORTPAGE0_SUPPORT_SPEED_UKNOWN
@@ -2076,6 +2269,11 @@
 #define MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE             (0x0004)
 #define MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC            (0x0008)
 #define MPI_RAIDVOL0_SETTING_FAST_DATA_SCRUBBING_0102   (0x0020) /* obsolete */
+
+#define MPI_RAIDVOL0_SETTING_MASK_METADATA_SIZE         (0x00C0)
+#define MPI_RAIDVOL0_SETTING_64MB_METADATA_SIZE         (0x0000)
+#define MPI_RAIDVOL0_SETTING_512MB_METADATA_SIZE        (0x0040)
+
 #define MPI_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX      (0x0010)
 #define MPI_RAIDVOL0_SETTING_USE_DEFAULTS               (0x8000)
 
@@ -2107,7 +2305,7 @@
     RAID_VOL0_STATUS        VolumeStatus;   /* 08h */
     RAID_VOL0_SETTINGS      VolumeSettings; /* 0Ch */
     U32                     MaxLBA;         /* 10h */
-    U32                     Reserved1;      /* 14h */
+    U32                     MaxLBAHigh;     /* 14h */
     U32                     StripeSize;     /* 18h */
     U32                     Reserved2;      /* 1Ch */
     U32                     Reserved3;      /* 20h */
@@ -2119,7 +2317,7 @@
 } CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
   RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
 
-#define MPI_RAIDVOLPAGE0_PAGEVERSION                    (0x05)
+#define MPI_RAIDVOLPAGE0_PAGEVERSION                    (0x07)
 
 /* values for RAID Volume Page 0 InactiveStatus field */
 #define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE               (0x00)
@@ -2134,11 +2332,11 @@
 typedef struct _CONFIG_PAGE_RAID_VOL_1
 {
     CONFIG_PAGE_HEADER      Header;         /* 00h */
-    U8                      VolumeID;       /* 01h */
-    U8                      VolumeBus;      /* 02h */
-    U8                      VolumeIOC;      /* 03h */
-    U8                      Reserved0;      /* 04h */
-    U8                      GUID[24];       /* 05h */
+    U8                      VolumeID;       /* 04h */
+    U8                      VolumeBus;      /* 05h */
+    U8                      VolumeIOC;      /* 06h */
+    U8                      Reserved0;      /* 07h */
+    U8                      GUID[24];       /* 08h */
     U8                      Name[32];       /* 20h */
     U64                     WWID;           /* 40h */
     U32                     Reserved1;      /* 48h */
@@ -2193,7 +2391,7 @@
 } RAID_PHYS_DISK0_STATUS, MPI_POINTER PTR_RAID_PHYS_DISK0_STATUS,
   RaidPhysDiskStatus_t, MPI_POINTER pRaidPhysDiskStatus_t;
 
-/* RAID Volume 2 IM Physical Disk DiskStatus flags */
+/* RAID Physical Disk PhysDiskStatus flags */
 
 #define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC           (0x01)
 #define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED              (0x02)
@@ -2351,7 +2549,8 @@
 typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
 {
     CONFIG_EXTENDED_PAGE_HEADER     Header;                             /* 00h */
-    U32                             Reserved1;                          /* 08h */
+    U16                             NvdataVersionDefault;               /* 08h */
+    U16                             NvdataVersionPersistent;            /* 0Ah */
     U8                              NumPhys;                            /* 0Ch */
     U8                              Reserved2;                          /* 0Dh */
     U16                             Reserved3;                          /* 0Eh */
@@ -2359,7 +2558,7 @@
 } CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
   SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t;
 
-#define MPI_SASIOUNITPAGE0_PAGEVERSION      (0x03)
+#define MPI_SASIOUNITPAGE0_PAGEVERSION      (0x04)
 
 /* values for SAS IO Unit Page 0 PortFlags */
 #define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS    (0x08)
@@ -2396,16 +2595,18 @@
 #define MPI_SAS_IOUNIT0_DS_TABLE_LINK                       (0x00000400)
 #define MPI_SAS_IOUNIT0_DS_UNSUPPORTED_DEVICE               (0x00000800)
 #define MPI_SAS_IOUNIT0_DS_MAX_SATA_TARGETS                 (0x00001000)
+#define MPI_SAS_IOUNIT0_DS_MULTI_PORT_DOMAIN                (0x00002000)
 
 
 typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA
 {
-    U8          Port;                   /* 00h */
-    U8          PortFlags;              /* 01h */
-    U8          PhyFlags;               /* 02h */
-    U8          MaxMinLinkRate;         /* 03h */
-    U32         ControllerPhyDeviceInfo;/* 04h */
-    U32         Reserved1;              /* 08h */
+    U8          Port;                       /* 00h */
+    U8          PortFlags;                  /* 01h */
+    U8          PhyFlags;                   /* 02h */
+    U8          MaxMinLinkRate;             /* 03h */
+    U32         ControllerPhyDeviceInfo;    /* 04h */
+    U16         MaxTargetPortConnectTime;   /* 08h */
+    U16         Reserved1;                  /* 0Ah */
 } MPI_SAS_IO_UNIT1_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT1_PHY_DATA,
   SasIOUnit1PhyData, MPI_POINTER pSasIOUnit1PhyData;
 
@@ -2422,15 +2623,17 @@
     CONFIG_EXTENDED_PAGE_HEADER Header;                             /* 00h */
     U16                         ControlFlags;                       /* 08h */
     U16                         MaxNumSATATargets;                  /* 0Ah */
-    U32                         Reserved1;                          /* 0Ch */
+    U16                         AdditionalControlFlags;             /* 0Ch */
+    U16                         Reserved1;                          /* 0Eh */
     U8                          NumPhys;                            /* 10h */
     U8                          SATAMaxQDepth;                      /* 11h */
-    U16                         Reserved2;                          /* 12h */
+    U8                          ReportDeviceMissingDelay;           /* 12h */
+    U8                          IODeviceMissingDelay;               /* 13h */
     MPI_SAS_IO_UNIT1_PHY_DATA   PhyData[MPI_SAS_IOUNIT1_PHY_MAX];   /* 14h */
 } CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
   SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
 
-#define MPI_SASIOUNITPAGE1_PAGEVERSION      (0x05)
+#define MPI_SASIOUNITPAGE1_PAGEVERSION      (0x07)
 
 /* values for SAS IO Unit Page 1 ControlFlags */
 #define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST            (0x8000)
@@ -2455,6 +2658,20 @@
 #define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY         (0x0002)
 #define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION           (0x0001)
 
+/* values for SAS IO Unit Page 1 AdditionalControlFlags */
+#define MPI_SAS_IOUNIT1_ACONTROL_MULTI_PORT_DOMAIN_ILLEGAL          (0x0080)
+#define MPI_SAS_IOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION    (0x0040)
+#define MPI_SAS_IOUNIT1_ACONTROL_HIDE_NONZERO_ATTACHED_PHY_IDENT    (0x0020)
+#define MPI_SAS_IOUNIT1_ACONTROL_PORT_ENABLE_ONLY_SATA_LINK_RESET   (0x0010)
+#define MPI_SAS_IOUNIT1_ACONTROL_OTHER_AFFILIATION_SATA_LINK_RESET  (0x0008)
+#define MPI_SAS_IOUNIT1_ACONTROL_SELF_AFFILIATION_SATA_LINK_RESET   (0x0004)
+#define MPI_SAS_IOUNIT1_ACONTROL_NO_AFFILIATION_SATA_LINK_RESET     (0x0002)
+#define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE               (0x0001)
+
+/* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */
+#define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK         (0x7F)
+#define MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16              (0x80)
+
 /* values for SAS IO Unit Page 1 PortFlags */
 #define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM         (0x00)
 #define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM         (0x04)
@@ -2490,9 +2707,11 @@
 } CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
   SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
 
-#define MPI_SASIOUNITPAGE2_PAGEVERSION      (0x05)
+#define MPI_SASIOUNITPAGE2_PAGEVERSION      (0x06)
 
 /* values for SAS IO Unit Page 2 Status field */
+#define MPI_SAS_IOUNIT2_STATUS_DEVICE_LIMIT_EXCEEDED        (0x08)
+#define MPI_SAS_IOUNIT2_STATUS_ENCLOSURE_DEVICES_UNMAPPED   (0x04)
 #define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
 #define MPI_SAS_IOUNIT2_STATUS_FULL_PERSISTENT_MAPPINGS     (0x01)
 
@@ -2568,6 +2787,7 @@
 #define MPI_SAS_EXPANDER0_DS_UNSUPPORTED_DEVICE         (0x00000800)
 
 /* values for SAS Expander Page 0 Flags field */
+#define MPI_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE    (0x04)
 #define MPI_SAS_EXPANDER0_FLAGS_ROUTE_TABLE_CONFIG      (0x02)
 #define MPI_SAS_EXPANDER0_FLAGS_CONFIG_IN_PROGRESS      (0x01)
 
@@ -2608,7 +2828,7 @@
 /* see mpi_sas.h for values for SAS Expander Page 1 AttachedDeviceInfo values */
 
 /* values for SAS Expander Page 1 DiscoveryInfo field */
-#define MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY DISABLED     (0x04)
+#define MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED     (0x04)
 #define MPI_SAS_EXPANDER1_DISCINFO_LINK_STATUS_CHANGE   (0x02)
 #define MPI_SAS_EXPANDER1_DISCINFO_NO_ROUTING_ENTRIES   (0x01)
 
@@ -2644,24 +2864,38 @@
 } CONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0,
   SasDevicePage0_t, MPI_POINTER pSasDevicePage0_t;
 
-#define MPI_SASDEVICE0_PAGEVERSION          (0x04)
+#define MPI_SASDEVICE0_PAGEVERSION          (0x05)
 
 /* values for SAS Device Page 0 AccessStatus field */
-#define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS               (0x00)
-#define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED        (0x01)
-#define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED  (0x02)
+#define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS                   (0x00)
+#define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED            (0x01)
+#define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED      (0x02)
+#define MPI_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT   (0x03)
+/* specific values for SATA Init failures */
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN                 (0x10)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT    (0x11)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_DIAG                    (0x12)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION          (0x13)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER             (0x14)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_PIO_SN                  (0x15)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN                 (0x16)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN                 (0x17)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION        (0x18)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE         (0x19)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_MAX                     (0x1F)
 
 /* values for SAS Device Page 0 Flags field */
-#define MPI_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE          (0x0200)
-#define MPI_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE        (0x0100)
-#define MPI_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED  (0x0080)
-#define MPI_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED      (0x0040)
-#define MPI_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED        (0x0020)
-#define MPI_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED        (0x0010)
-#define MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH      (0x0008)
-#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT        (0x0004)
-#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED             (0x0002)
-#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT            (0x0001)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY      (0x0400)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE              (0x0200)
+#define MPI_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE            (0x0100)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED      (0x0080)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED          (0x0040)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED            (0x0020)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED            (0x0010)
+#define MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH          (0x0008)
+#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT            (0x0004)
+#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED                 (0x0002)
+#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT                (0x0001)
 
 /* see mpi_sas.h for values for SAS Device Page 0 DeviceInfo values */
 
@@ -2715,11 +2949,11 @@
     U8                                  AttachedPhyIdentifier;  /* 16h */
     U8                                  Reserved2;              /* 17h */
     U32                                 AttachedDeviceInfo;     /* 18h */
-    U8                                  ProgrammedLinkRate;     /* 20h */
-    U8                                  HwLinkRate;             /* 21h */
-    U8                                  ChangeCount;            /* 22h */
-    U8                                  Flags;                  /* 23h */
-    U32                                 PhyInfo;                /* 24h */
+    U8                                  ProgrammedLinkRate;     /* 1Ch */
+    U8                                  HwLinkRate;             /* 1Dh */
+    U8                                  ChangeCount;            /* 1Eh */
+    U8                                  Flags;                  /* 1Fh */
+    U32                                 PhyInfo;                /* 20h */
 } CONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0,
   SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t;
 


More information about the Midnightbsd-cvs mailing list