svn commit: r322658 - in stable/11/sys/dev: mpr mps

Kenneth D. Merry ken at FreeBSD.org
Fri Aug 18 14:25:09 UTC 2017


Author: ken
Date: Fri Aug 18 14:25:07 2017
New Revision: 322658
URL: https://svnweb.freebsd.org/changeset/base/322658

Log:
  MFC r321502, r321714, r321733, r321737, r321799, r322364:
  
    ------------------------------------------------------------------------
    r321502 | scottl | 2017-07-25 19:48:13 -0600 (Tue, 25 Jul 2017) | 2 lines
  
    Quiet a message that sounds far more dire than it really is.
  
    ------------------------------------------------------------------------
    r321714 | scottl | 2017-07-30 00:53:58 -0600 (Sun, 30 Jul 2017) | 13 lines
  
        Split the interrupt setup code into two parts: allocation and configuration.
        Do the allocation before requesting the IOCFacts message.  This triggers
        the LSI firmware to recognize the multiqueue should be enabled if available.
        Multiqueue isn't used by the driver yet, but this also fixes a problem with
        the cached IOCFacts not matching latter checks, leading to potential problems
        with error recovery.
  
        As a side-effect, fetch the driver tunables as early as possible.
  
    Reviewed by:	slm
    Obtained from:	Netflix
    Differential Revision:	D9243
  
    ------------------------------------------------------------------------
    r321733 | scottl | 2017-07-30 16:34:24 -0600 (Sun, 30 Jul 2017) | 5 lines
  
    Change from using underbar function names to normal function names for
    the informational print functions.  Collapse the debug API a bit to be
    more generic and not require as much code duplication.  While here, fix
    a bug in MPS that was already fixed in MPR.
  
    ------------------------------------------------------------------------
    r321737 | scottl | 2017-07-30 18:05:49 -0600 (Sun, 30 Jul 2017) | 3 lines
  
        Don't re-parse PCI IDs in order to set card-specific flags, use
        the flags field in the PCIID table.
  
    ------------------------------------------------------------------------
    r321799 | scottl | 2017-07-31 10:55:56 -0600 (Mon, 31 Jul 2017) | 4 lines
  
    Fix a logic bug in the split PCI interrupt code that slipped through
  
    Reported by:	Harry Schmalzbauer
  
    ------------------------------------------------------------------------
    r322364 | ken | 2017-08-10 08:59:17 -0600 (Thu, 10 Aug 2017) | 39 lines
  
    Changes to make mps(4) and mpr(4) handle reinit with reallocation.
  
    When the mps(4) and mpr(4) drivers need to reinitialize the
    firmware, they sometimes need to reallocate all of the memory
    allocated by the driver.  The reallocation happens whenever the IOC
    Facts change.  That should only happen after a firmware upgrade.
  
    If the reinitialization happens as a result of a timed out command
    sent to the card, the command that timed out and triggered the
    reinit may have been freed if iocfacts_allocate() reallocated all
    memory.  If the caller attempts to access the command after that,
    the kernel will panic because the caller will be dereferencing
    freed memory.
  
    The solution is to set a flag in the softc when we reallocate,
    and avoid dereferencing the command strucure if we've reallocated.
  
    The changes are largely the same in both drivers, since mpr(4) is a
    derivative of mps(4).
  
     o In iocfacts_allocate(), if the IOC Facts have changed and we
       need to reallocate, set the REALLOCATED flag in the softc.
  
     o Change wait_command() to take a struct mps_command ** instead of
       a struct mps_command *.  This allows us to NULL out the caller's
       command pointer if we have to reinit the controller and the data
       structures get reallocated.  (The REALLOCATED flag will be set
       in the softc if that has happened.)
  
     o In every place that calls wait_command(), make sure we handle
       the case where the command is NULL after the call.
  
     o The mpr(4) driver has mpr_request_polled() which can also
       reinitialize the card.  Also check for reallocation there.
  
    Reviewed by:	scottl, slm
    Sponsored by:	Spectra Logic
  
    ------------------------------------------------------------------------

Modified:
  stable/11/sys/dev/mpr/mpr.c
  stable/11/sys/dev/mpr/mpr_config.c
  stable/11/sys/dev/mpr/mpr_pci.c
  stable/11/sys/dev/mpr/mpr_sas.c
  stable/11/sys/dev/mpr/mpr_sas_lsi.c
  stable/11/sys/dev/mpr/mpr_table.c
  stable/11/sys/dev/mpr/mpr_table.h
  stable/11/sys/dev/mpr/mpr_user.c
  stable/11/sys/dev/mpr/mprvar.h
  stable/11/sys/dev/mps/mps.c
  stable/11/sys/dev/mps/mps_config.c
  stable/11/sys/dev/mps/mps_pci.c
  stable/11/sys/dev/mps/mps_sas.c
  stable/11/sys/dev/mps/mps_sas_lsi.c
  stable/11/sys/dev/mps/mps_table.c
  stable/11/sys/dev/mps/mps_table.h
  stable/11/sys/dev/mps/mps_user.c
  stable/11/sys/dev/mps/mpsvar.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/mpr/mpr.c
==============================================================================
--- stable/11/sys/dev/mpr/mpr.c	Fri Aug 18 14:17:12 2017	(r322657)
+++ stable/11/sys/dev/mpr/mpr.c	Fri Aug 18 14:25:07 2017	(r322658)
@@ -381,7 +381,7 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t at
 		}
 	}
 
-	mpr_print_iocfacts(sc, sc->facts);
+	MPR_DPRINT_PAGE(sc, MPR_XINFO, iocfacts, sc->facts);
 
 	snprintf(sc->fw_version, sizeof(sc->fw_version), 
 	    "%02d.%02d.%02d.%02d", 
@@ -436,6 +436,8 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t at
 
 	/* Only deallocate and reallocate if relevant IOC Facts have changed */
 	reallocating = FALSE;
+	sc->mpr_flags &= ~MPR_FLAGS_REALLOCATED;
+
 	if ((!attaching) &&
 	    ((saved_facts.MsgVersion != sc->facts->MsgVersion) ||
 	    (saved_facts.HeaderVersion != sc->facts->HeaderVersion) ||
@@ -458,6 +460,9 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t at
 	    (saved_facts.MaxPersistentEntries !=
 	    sc->facts->MaxPersistentEntries))) {
 		reallocating = TRUE;
+
+		/* Record that we reallocated everything */
+		sc->mpr_flags |= MPR_FLAGS_REALLOCATED;
 	}
 
 	/*
@@ -1482,7 +1487,7 @@ mpr_init_queues(struct mpr_softc *sc)
  * Next are the global settings, if they exist.  Highest are the per-unit
  * settings, if they exist.
  */
-static void
+void
 mpr_get_tunables(struct mpr_softc *sc)
 {
 	char tmpstr[80];
@@ -1658,8 +1663,6 @@ mpr_attach(struct mpr_softc *sc)
 {
 	int error;
 
-	mpr_get_tunables(sc);
-
 	MPR_FUNCTRACE(sc);
 
 	mtx_init(&sc->mpr_mtx, "MPR lock", NULL, MTX_DEF);
@@ -1774,7 +1777,7 @@ mpr_log_evt_handler(struct mpr_softc *sc, uintptr_t da
 {
 	MPI2_EVENT_DATA_LOG_ENTRY_ADDED *entry;
 
-	mpr_print_event(sc, event);
+	MPR_DPRINT_EVENT(sc, generic, event);
 
 	switch (event->Event) {
 	case MPI2_EVENT_LOG_DATA:
@@ -2189,7 +2192,7 @@ mpr_reregister_events_complete(struct mpr_softc *sc, s
 	mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
 
 	if (cm->cm_reply)
-		mpr_print_event(sc,
+		MPR_DPRINT_EVENT(sc, generic,
 			(MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply);
 
 	mpr_free_command(sc, cm);
@@ -2231,8 +2234,8 @@ mpr_update_events(struct mpr_softc *sc, struct mpr_eve
     uint8_t *mask)
 {
 	MPI2_EVENT_NOTIFICATION_REQUEST *evtreq;
-	MPI2_EVENT_NOTIFICATION_REPLY *reply;
-	struct mpr_command *cm;
+	MPI2_EVENT_NOTIFICATION_REPLY *reply = NULL;
+	struct mpr_command *cm = NULL;
 	struct mpr_event_handle *eh;
 	int error, i;
 
@@ -2265,18 +2268,20 @@ mpr_update_events(struct mpr_softc *sc, struct mpr_eve
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
 
-	error = mpr_request_polled(sc, cm);
-	reply = (MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply;
+	error = mpr_request_polled(sc, &cm);
+	if (cm != NULL)
+		reply = (MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply;
 	if ((reply == NULL) ||
 	    (reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS)
 		error = ENXIO;
 	
 	if (reply)
-		mpr_print_event(sc, reply);
+		MPR_DPRINT_EVENT(sc, generic, reply);
 
 	mpr_dprint(sc, MPR_TRACE, "%s finished error %d\n", __func__, error);
 
-	mpr_free_command(sc, cm);
+	if (cm != NULL)
+		mpr_free_command(sc, cm);
 	return (error);
 }
 
@@ -3262,11 +3267,12 @@ mpr_map_command(struct mpr_softc *sc, struct mpr_comma
  * be executed and enqueued automatically.  Other errors come from msleep().
  */
 int
-mpr_wait_command(struct mpr_softc *sc, struct mpr_command *cm, int timeout,
+mpr_wait_command(struct mpr_softc *sc, struct mpr_command **cmp, int timeout,
     int sleep_flag)
 {
 	int error, rc;
 	struct timeval cur_time, start_time;
+	struct mpr_command *cm = *cmp;
 
 	if (sc->mpr_flags & MPR_FLAGS_DIAGRESET) 
 		return  EBUSY;
@@ -3321,6 +3327,13 @@ mpr_wait_command(struct mpr_softc *sc, struct mpr_comm
 		rc = mpr_reinit(sc);
 		mpr_dprint(sc, MPR_FAULT, "Reinit %s\n", (rc == 0) ? "success" :
 		    "failed");
+		if (sc->mpr_flags & MPR_FLAGS_REALLOCATED) {
+			/*
+			 * Tell the caller that we freed the command in a
+			 * reinit.
+			 */
+			*cmp = NULL;
+		}
 		error = ETIMEDOUT;
 	}
 	return (error);
@@ -3331,10 +3344,11 @@ mpr_wait_command(struct mpr_softc *sc, struct mpr_comm
  * completion.  Its use should be rare.
  */
 int
-mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm)
+mpr_request_polled(struct mpr_softc *sc, struct mpr_command **cmp)
 {
-	int error, timeout = 0, rc;
+	int error, rc;
 	struct timeval cur_time, start_time;
+	struct mpr_command *cm = *cmp;
 
 	error = 0;
 
@@ -3342,7 +3356,7 @@ mpr_request_polled(struct mpr_softc *sc, struct mpr_co
 	cm->cm_complete = NULL;
 	mpr_map_command(sc, cm);
 
-	getmicrotime(&start_time);
+	getmicrouptime(&start_time);
 	while ((cm->cm_flags & MPR_CM_FLAGS_COMPLETE) == 0) {
 		mpr_intr_locked(sc);
 
@@ -3355,9 +3369,9 @@ mpr_request_polled(struct mpr_softc *sc, struct mpr_co
 		/*
 		 * Check for real-time timeout and fail if more than 60 seconds.
 		 */
-		getmicrotime(&cur_time);
-		timeout = cur_time.tv_sec - start_time.tv_sec;
-		if (timeout > 60) {
+		getmicrouptime(&cur_time);
+		timevalsub(&cur_time, &start_time);
+		if (cur_time.tv_sec > 60) {
 			mpr_dprint(sc, MPR_FAULT, "polling failed\n");
 			error = ETIMEDOUT;
 			break;
@@ -3369,6 +3383,14 @@ mpr_request_polled(struct mpr_softc *sc, struct mpr_co
 		rc = mpr_reinit(sc);
 		mpr_dprint(sc, MPR_FAULT, "Reinit %s\n", (rc == 0) ? "success" :
 		    "failed");
+
+		if (sc->mpr_flags & MPR_FLAGS_REALLOCATED) {
+			/*
+			 * Tell the caller that we freed the command in a
+			 * reinit.
+			 */
+			*cmp = NULL;
+		}
 	}
 	return (error);
 }
@@ -3434,11 +3456,12 @@ mpr_read_config_page(struct mpr_softc *sc, struct mpr_
 		cm->cm_complete = mpr_config_complete;
 		return (mpr_map_command(sc, cm));
 	} else {
-		error = mpr_wait_command(sc, cm, 0, CAN_SLEEP);
+		error = mpr_wait_command(sc, &cm, 0, CAN_SLEEP);
 		if (error) {
 			mpr_dprint(sc, MPR_FAULT,
 			    "Error %d reading config page\n", error);
-			mpr_free_command(sc, cm);
+			if (cm != NULL)
+				mpr_free_command(sc, cm);
 			return (error);
 		}
 		mpr_config_complete(sc, cm);

Modified: stable/11/sys/dev/mpr/mpr_config.c
==============================================================================
--- stable/11/sys/dev/mpr/mpr_config.c	Fri Aug 18 14:17:12 2017	(r322657)
+++ stable/11/sys/dev/mpr/mpr_config.c	Fri Aug 18 14:25:07 2017	(r322658)
@@ -95,8 +95,9 @@ mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2Confi
 	request->Header.PageLength = request->Header.PageVersion = 0;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -153,8 +154,9 @@ mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2Confi
 	}
 	cm->cm_data = page;
 
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -225,8 +227,9 @@ mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2Co
 	request->Header.PageLength = request->Header.PageVersion = 0;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -283,8 +286,9 @@ mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2Co
 	}
 	cm->cm_data = page;
 
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -393,8 +397,9 @@ mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2Confi
 	    MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -453,8 +458,9 @@ mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2Confi
 		goto out;
 	}
 	cm->cm_data = page;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -529,8 +535,9 @@ int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2C
 	request->PageAddress |= htole16(entry_idx);
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -591,8 +598,9 @@ int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2C
 	bcopy(config_page, page, MIN(cm->cm_length, 
 	    (sizeof(Mpi2DriverMappingPage0_t))));
 	cm->cm_data = page;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -664,8 +672,9 @@ mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mp
 	request->ExtPageLength = request->Header.PageVersion = 0;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -724,8 +733,9 @@ mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mp
 	}
 	cm->cm_data = page;
 
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -799,8 +809,9 @@ mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, M
 	request->ExtPageLength = request->Header.PageVersion = 0;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -859,8 +870,9 @@ mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, M
 	}
 	cm->cm_data = page;
 
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -934,8 +946,9 @@ mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, M
 	request->ExtPageLength = request->Header.PageVersion = 0;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -994,8 +1007,9 @@ mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, M
 	}
 	cm->cm_data = page;
 
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -1066,8 +1080,9 @@ mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2Conf
 	request->Header.PageLength = request->Header.PageVersion = 0;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -1124,8 +1139,9 @@ mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2Conf
 	}
 	cm->cm_data = page;
 
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -1173,7 +1189,7 @@ mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, M
     *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address)
 {
 	MPI2_CONFIG_REQUEST *request;
-	MPI2_CONFIG_REPLY *reply;
+	MPI2_CONFIG_REPLY *reply = NULL;
 	struct mpr_command *cm;
 	Mpi2RaidVolPage0_t *page = NULL;
 	int error = 0;
@@ -1201,8 +1217,9 @@ mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, M
 	 * This page must be polled because the IOC isn't ready yet when this
 	 * page is needed.
 	 */
-	error = mpr_request_polled(sc, cm);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_request_polled(sc, &cm);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/* If the poll returns error then we need to do diag reset */ 
@@ -1258,8 +1275,9 @@ mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, M
 	 * This page must be polled because the IOC isn't ready yet when this
 	 * page is needed.
 	 */
-	error = mpr_request_polled(sc, cm);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_request_polled(sc, &cm);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/* If the poll returns error then we need to do diag reset */ 
@@ -1325,8 +1343,9 @@ mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, M
 	request->Header.PageLength = request->Header.PageVersion = 0;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	cm->cm_data = NULL;
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -1384,8 +1403,9 @@ mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, M
 	}
 	cm->cm_data = page;
 
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -1459,7 +1479,7 @@ mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2C
     Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address)
 {
 	MPI2_CONFIG_REQUEST *request;
-	MPI2_CONFIG_REPLY *reply;
+	MPI2_CONFIG_REPLY *reply = NULL;
 	struct mpr_command *cm;
 	Mpi2RaidPhysDiskPage0_t *page = NULL;
 	int error = 0;
@@ -1487,8 +1507,9 @@ mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2C
 	 * This page must be polled because the IOC isn't ready yet when this
 	 * page is needed.
 	 */
-	error = mpr_request_polled(sc, cm);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_request_polled(sc, &cm);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/* If the poll returns error then we need to do diag reset */ 
@@ -1544,8 +1565,9 @@ mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2C
 	 * This page must be polled because the IOC isn't ready yet when this
 	 * page is needed.
 	 */
-	error = mpr_request_polled(sc, cm);
-	reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+	error = mpr_request_polled(sc, &cm);
+	if (cm != NULL)
+		reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/* If the poll returns error then we need to do diag reset */ 

Modified: stable/11/sys/dev/mpr/mpr_pci.c
==============================================================================
--- stable/11/sys/dev/mpr/mpr_pci.c	Fri Aug 18 14:17:12 2017	(r322657)
+++ stable/11/sys/dev/mpr/mpr_pci.c	Fri Aug 18 14:25:07 2017	(r322658)
@@ -69,6 +69,7 @@ static int	mpr_pci_resume(device_t);
 static void	mpr_pci_free(struct mpr_softc *);
 static int	mpr_alloc_msix(struct mpr_softc *sc, int msgs);
 static int	mpr_alloc_msi(struct mpr_softc *sc, int msgs);
+static int	mpr_pci_alloc_interrupts(struct mpr_softc *sc);
 
 static device_method_t mpr_methods[] = {
 	DEVMETHOD(device_probe,		mpr_pci_probe),
@@ -124,23 +125,32 @@ struct mpr_ident {
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_2,
 	    0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3324_2" },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3408,
-	    0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3408" },
+	    0xffff, 0xffff, MPR_FLAGS_GEN35_IOC,
+	    "Avago Technologies (LSI) SAS3408" },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3416,
-	    0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3416" },
+	    0xffff, 0xffff, MPR_FLAGS_GEN35_IOC,
+	    "Avago Technologies (LSI) SAS3416" },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3508,
-	    0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3508" },
+	    0xffff, 0xffff, MPR_FLAGS_GEN35_IOC,
+	    "Avago Technologies (LSI) SAS3508" },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3508_1,
-	    0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3508_1" },
+	    0xffff, 0xffff, MPR_FLAGS_GEN35_IOC,
+	    "Avago Technologies (LSI) SAS3508_1" },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3516,
-	    0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3516" },
+	    0xffff, 0xffff, MPR_FLAGS_GEN35_IOC,
+	    "Avago Technologies (LSI) SAS3516" },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3516_1,
-	    0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3516_1" },
+	    0xffff, 0xffff, MPR_FLAGS_GEN35_IOC,
+	    "Avago Technologies (LSI) SAS3516_1" },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3616,
-	    0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3616" },
+	    0xffff, 0xffff, MPR_FLAGS_GEN35_IOC,
+	    "Avago Technologies (LSI) SAS3616" },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3708,
-	    0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3708" },
+	    0xffff, 0xffff, MPR_FLAGS_GEN35_IOC,
+	    "Avago Technologies (LSI) SAS3708" },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3716,
-	    0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3716" },
+	    0xffff, 0xffff, MPR_FLAGS_GEN35_IOC,
+	    "Avago Technologies (LSI) SAS3716" },
 	{ 0, 0, 0, 0, 0, NULL }
 };
 
@@ -191,22 +201,11 @@ mpr_pci_attach(device_t dev)
 	m = mpr_find_ident(dev);
 	sc->mpr_flags = m->flags;
 
+	mpr_get_tunables(sc);
+
 	/* Twiddle basic PCI config bits for a sanity check */
 	pci_enable_busmaster(dev);
 
-	/* Set flag if this is a Gen3.5 IOC */
-	if ((m->device == MPI26_MFGPAGE_DEVID_SAS3508) ||
-	    (m->device == MPI26_MFGPAGE_DEVID_SAS3508_1) ||
-	    (m->device == MPI26_MFGPAGE_DEVID_SAS3408) ||
-	    (m->device == MPI26_MFGPAGE_DEVID_SAS3516) ||
-	    (m->device == MPI26_MFGPAGE_DEVID_SAS3516_1) ||
-	    (m->device == MPI26_MFGPAGE_DEVID_SAS3416) ||
-	    (m->device == MPI26_MFGPAGE_DEVID_SAS3716) ||
-	    (m->device == MPI26_MFGPAGE_DEVID_SAS3616) ||
-	    (m->device == MPI26_MFGPAGE_DEVID_SAS3708)) {
-		sc->mpr_flags |= MPR_FLAGS_GEN35_IOC;
-	}
-
 	for (i = 0; i < PCI_MAXMAPS_0; i++) {
 		sc->mpr_regs_rid = PCIR_BAR(i);
 
@@ -240,28 +239,52 @@ mpr_pci_attach(device_t dev)
 		return (ENOMEM);
 	}
 
-	if ((error = mpr_attach(sc)) != 0)
+	if (((error = mpr_pci_alloc_interrupts(sc)) != 0) ||
+	    ((error = mpr_attach(sc)) != 0))
 		mpr_pci_free(sc);
 
 	return (error);
 }
 
+/*
+ * Allocate, but don't assign interrupts early.  Doing it before requesting
+ * the IOCFacts message informs the firmware that we want to do MSI-X
+ * multiqueue.  We might not use all of the available messages, but there's
+ * no reason to re-alloc if we don't.
+ */
 int
-mpr_pci_setup_interrupts(struct mpr_softc *sc)
+mpr_pci_alloc_interrupts(struct mpr_softc *sc)
 {
 	device_t dev;
-	int i, error, msgs;
+	int error, msgs;
 
 	dev = sc->mpr_dev;
-	error = ENXIO;
+	error = 0;
+	msgs = 0;
+
 	if ((sc->disable_msix == 0) &&
 	    ((msgs = pci_msix_count(dev)) >= MPR_MSI_COUNT))
 		error = mpr_alloc_msix(sc, MPR_MSI_COUNT);
 	if ((error != 0) && (sc->disable_msi == 0) &&
 	    ((msgs = pci_msi_count(dev)) >= MPR_MSI_COUNT))
 		error = mpr_alloc_msi(sc, MPR_MSI_COUNT);
+	if (error != 0)
+		msgs = 0;
 
-	if (error != 0) {
+	sc->msi_msgs = msgs;
+	return (error);
+}
+
+int
+mpr_pci_setup_interrupts(struct mpr_softc *sc)
+{
+	device_t dev;
+	int i, error;
+
+	dev = sc->mpr_dev;
+	error = ENXIO;
+
+	if (sc->msi_msgs == 0) {
 		sc->mpr_flags |= MPR_FLAGS_INTX;
 		sc->mpr_irq_rid[0] = 0;
 		sc->mpr_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ,

Modified: stable/11/sys/dev/mpr/mpr_sas.c
==============================================================================
--- stable/11/sys/dev/mpr/mpr_sas.c	Fri Aug 18 14:17:12 2017	(r322657)
+++ stable/11/sys/dev/mpr/mpr_sas.c	Fri Aug 18 14:25:07 2017	(r322658)
@@ -1193,13 +1193,8 @@ mprsas_complete_all_commands(struct mpr_softc *sc)
 			completed = 1;
 		}
 
-		if (cm->cm_sc->io_cmds_active != 0) {
+		if (cm->cm_sc->io_cmds_active != 0)
 			cm->cm_sc->io_cmds_active--;
-		} else {
-			mpr_dprint(cm->cm_sc, MPR_INFO, "Warning: "
-			    "io_cmds_active is out of sync - resynching to "
-			    "0\n");
-		}
 		
 		if ((completed == 0) && (cm->cm_state != MPR_CM_STATE_FREE)) {
 			/* this should never happen, but if it does, log */
@@ -2677,7 +2672,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mp
 		if ((sassc->flags & MPRSAS_QUEUE_FROZEN) == 0) {
 			xpt_freeze_simq(sassc->sim, 1);
 			sassc->flags |= MPRSAS_QUEUE_FROZEN;
-			mpr_dprint(sc, MPR_INFO, "Error sending command, "
+			mpr_dprint(sc, MPR_XINFO, "Error sending command, "
 			    "freezing SIM queue\n");
 		}
 	}

Modified: stable/11/sys/dev/mpr/mpr_sas_lsi.c
==============================================================================
--- stable/11/sys/dev/mpr/mpr_sas_lsi.c	Fri Aug 18 14:17:12 2017	(r322657)
+++ stable/11/sys/dev/mpr/mpr_sas_lsi.c	Fri Aug 18 14:25:07 2017	(r322658)
@@ -139,7 +139,7 @@ mprsas_evt_handler(struct mpr_softc *sc, uintptr_t dat
 	u16 sz;
 
 	mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
-	mpr_print_evt_sas(sc, event);
+	MPR_DPRINT_EVENT(sc, sas, event);
 	mprsas_record_event(sc, event);
 
 	fw_event = malloc(sizeof(struct mpr_fw_event_work), M_MPR,
@@ -324,7 +324,7 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_eve
 			{
 				// build RAID Action message
 				Mpi2RaidActionRequest_t	*action;
-				Mpi2RaidActionReply_t *reply;
+				Mpi2RaidActionReply_t *reply = NULL;
 				struct mpr_command *cm;
 				int error = 0;
 				if ((cm = mpr_alloc_command(sc)) == NULL) {
@@ -344,8 +344,10 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_eve
 				action->PhysDiskNum = element->PhysDiskNum;
 				cm->cm_desc.Default.RequestFlags =
 				    MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
-				error = mpr_request_polled(sc, cm);
-				reply = (Mpi2RaidActionReply_t *)cm->cm_reply;
+				error = mpr_request_polled(sc, &cm);
+				if (cm != NULL)
+					reply = (Mpi2RaidActionReply_t *)
+					    cm->cm_reply;
 				if (error || (reply == NULL)) {
 					/* FIXME */
 					/*
@@ -1132,12 +1134,14 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 han
 	    "command\n", __func__);
 	callout_reset(&cm->cm_callout, MPR_ATA_ID_TIMEOUT * hz,
 	    mprsas_ata_id_timeout, cm);
-	error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
+	error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP);
 	mpr_dprint(sc, MPR_XINFO, "%s stop timeout counter for SATA ID "
 	    "command\n", __func__);
+	/* XXX KDM need to fix the case where this command is destroyed */
 	callout_stop(&cm->cm_callout);
 
-	reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply;
+	if (cm != NULL)
+		reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply;
 	if (error || (reply == NULL)) {
 		/* FIXME */
 		/*
@@ -1603,7 +1607,7 @@ mprsas_ir_shutdown(struct mpr_softc *sc)
 	action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
 	mpr_lock(sc);
-	mpr_wait_command(sc, cm, 5, CAN_SLEEP);
+	mpr_wait_command(sc, &cm, 5, CAN_SLEEP);
 	mpr_unlock(sc);
 
 	/*

Modified: stable/11/sys/dev/mpr/mpr_table.c
==============================================================================
--- stable/11/sys/dev/mpr/mpr_table.c	Fri Aug 18 14:17:12 2017	(r322657)
+++ stable/11/sys/dev/mpr/mpr_table.c	Fri Aug 18 14:25:07 2017	(r322658)
@@ -219,7 +219,7 @@ mpr_describe_devinfo(uint32_t devinfo, char *string, i
 }
 
 void
-_mpr_print_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
+mpr_print_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
 {
 	MPR_PRINTFIELD_START(sc, "IOCFacts");
 	MPR_PRINTFIELD(sc, facts, MsgVersion, 0x%x);
@@ -259,7 +259,7 @@ _mpr_print_iocfacts(struct mpr_softc *sc, MPI2_IOC_FAC
 }
 
 void
-_mpr_print_portfacts(struct mpr_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
+mpr_print_portfacts(struct mpr_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
 {
 
 	MPR_PRINTFIELD_START(sc, "PortFacts");
@@ -269,7 +269,7 @@ _mpr_print_portfacts(struct mpr_softc *sc, MPI2_PORT_F
 }
 
 void
-_mpr_print_event(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+mpr_print_evt_generic(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 {
 
 	MPR_PRINTFIELD_START(sc, "EventReply");
@@ -281,7 +281,7 @@ _mpr_print_event(struct mpr_softc *sc, MPI2_EVENT_NOTI
 }
 
 void
-_mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
+mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
 {
 	MPR_PRINTFIELD_START(sc, "SAS Device Page 0");
 	MPR_PRINTFIELD(sc, buf, Slot, %d);
@@ -310,10 +310,10 @@ _mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_P
 }
 
 void
-_mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
 {
 
-	_mpr_print_event(sc, event);
+	mpr_print_evt_generic(sc, event);
 
 	switch(event->Event) {
 	case MPI2_EVENT_SAS_DISCOVERY:
@@ -407,7 +407,7 @@ _mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NO
 }
 
 void
-_mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
+mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
 {
 	MPR_PRINTFIELD_START(sc, "SAS Expander Page 1 #%d", buf->Phy);
 	MPR_PRINTFIELD(sc, buf, PhysicalPort, %d);
@@ -447,7 +447,7 @@ _mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG
 }
 
 void
-_mpr_print_sasphy0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
+mpr_print_sasphy0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
 {
 	MPR_PRINTFIELD_START(sc, "SAS PHY Page 0");
 	MPR_PRINTFIELD(sc, buf, OwnerDevHandle, 0x%04x);

Modified: stable/11/sys/dev/mpr/mpr_table.h
==============================================================================
--- stable/11/sys/dev/mpr/mpr_table.h	Fri Aug 18 14:17:12 2017	(r322657)
+++ stable/11/sys/dev/mpr/mpr_table.h	Fri Aug 18 14:25:07 2017	(r322658)
@@ -42,63 +42,22 @@ extern struct mpr_table_lookup mpr_phystatus_names[];
 extern struct mpr_table_lookup mpr_linkrate_names[];
 extern struct mpr_table_lookup mpr_pcie_linkrate_names[];
 
-void _mpr_print_iocfacts(struct mpr_softc *, MPI2_IOC_FACTS_REPLY *);
-void _mpr_print_portfacts(struct mpr_softc *, MPI2_PORT_FACTS_REPLY *);
-void _mpr_print_event(struct mpr_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
-void _mpr_print_sasdev0(struct mpr_softc *, MPI2_CONFIG_PAGE_SAS_DEV_0 *);
-void _mpr_print_evt_sas(struct mpr_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
-void _mpr_print_expander1(struct mpr_softc *, MPI2_CONFIG_PAGE_EXPANDER_1 *);
-void _mpr_print_sasphy0(struct mpr_softc *, MPI2_CONFIG_PAGE_SAS_PHY_0 *);
+void mpr_print_iocfacts(struct mpr_softc *, MPI2_IOC_FACTS_REPLY *);
+void mpr_print_portfacts(struct mpr_softc *, MPI2_PORT_FACTS_REPLY *);
+void mpr_print_evt_generic(struct mpr_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
+void mpr_print_sasdev0(struct mpr_softc *, MPI2_CONFIG_PAGE_SAS_DEV_0 *);
+void mpr_print_evt_sas(struct mpr_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
+void mpr_print_expander1(struct mpr_softc *, MPI2_CONFIG_PAGE_EXPANDER_1 *);
+void mpr_print_sasphy0(struct mpr_softc *, MPI2_CONFIG_PAGE_SAS_PHY_0 *);
 void mpr_print_sgl(struct mpr_softc *, struct mpr_command *, int);
 void mpr_print_scsiio_cmd(struct mpr_softc *, struct mpr_command *);
 
-static __inline void
-mpr_print_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
-{
-	if (sc->mpr_debug & MPR_XINFO)
-		_mpr_print_iocfacts(sc, facts);
-}
+#define MPR_DPRINT_PAGE(sc, level, func, buf)			\
+do {								\
+	if ((sc)->mpr_debug & level)				\
+		mpr_print_##func((sc), buf);			\
+} while (0)
 
-static __inline void
-mpr_print_portfacts(struct mpr_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
-{
-	if (sc->mpr_debug & MPR_XINFO)
-		_mpr_print_portfacts(sc, facts);
-}
-
-static __inline void
-mpr_print_event(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
-{
-	if (sc->mpr_debug & MPR_EVENT)
-		_mpr_print_event(sc, event);
-}
-
-static __inline void
-mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
-{
-	if (sc->mpr_debug & MPR_EVENT)
-		_mpr_print_evt_sas(sc, event);
-}
-
-static __inline void
-mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
-{
-	if (sc->mpr_debug & MPR_XINFO)
-		_mpr_print_sasdev0(sc, buf);
-}
-
-static __inline void
-mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
-{
-	if (sc->mpr_debug & MPR_XINFO)
-		_mpr_print_expander1(sc, buf);
-}
-
-static __inline void
-mpr_print_sasphy0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
-{
-	if (sc->mpr_debug & MPR_XINFO)
-		_mpr_print_sasphy0(sc, buf);
-}
-
+#define MPR_DPRINT_EVENT(sc, func, buf)				\
+	MPR_DPRINT_PAGE(sc, MPR_EVENT, evt_##func, buf)
 #endif

Modified: stable/11/sys/dev/mpr/mpr_user.c
==============================================================================
--- stable/11/sys/dev/mpr/mpr_user.c	Fri Aug 18 14:17:12 2017	(r322657)
+++ stable/11/sys/dev/mpr/mpr_user.c	Fri Aug 18 14:25:07 2017	(r322658)
@@ -652,7 +652,7 @@ static int
 mpr_user_command(struct mpr_softc *sc, struct mpr_usr_command *cmd)
 {
 	MPI2_REQUEST_HEADER *hdr;	
-	MPI2_DEFAULT_REPLY *rpl;
+	MPI2_DEFAULT_REPLY *rpl = NULL;
 	void *buf = NULL;
 	struct mpr_command *cm = NULL;
 	int err = 0;
@@ -664,7 +664,7 @@ mpr_user_command(struct mpr_softc *sc, struct mpr_usr_
 	if (cm == NULL) {
 		mpr_printf(sc, "%s: no mpr requests\n", __func__);
 		err = ENOMEM;
-		goto Ret;
+		goto RetFree;
 	}
 	mpr_unlock(sc);
 
@@ -706,15 +706,16 @@ mpr_user_command(struct mpr_softc *sc, struct mpr_usr_
 		goto RetFreeUnlocked;
 
 	mpr_lock(sc);
-	err = mpr_wait_command(sc, cm, 30, CAN_SLEEP);
+	err = mpr_wait_command(sc, &cm, 30, CAN_SLEEP);
 
-	if (err) {
+	if (err || (cm == NULL)) {
 		mpr_printf(sc, "%s: invalid request: error %d\n",
 		    __func__, err);
-		goto Ret;
+		goto RetFree;
 	}
 
-	rpl = (MPI2_DEFAULT_REPLY *)cm->cm_reply;
+	if (cm != NULL)
+		rpl = (MPI2_DEFAULT_REPLY *)cm->cm_reply;
 	if (rpl != NULL)
 		sz = rpl->MsgLength * 4;
 	else
@@ -734,9 +735,9 @@ mpr_user_command(struct mpr_softc *sc, struct mpr_usr_
 
 RetFreeUnlocked:
 	mpr_lock(sc);
+RetFree:
 	if (cm != NULL)
 		mpr_free_command(sc, cm);
-Ret:
 	mpr_unlock(sc);
 	if (buf != NULL)
 		free(buf, M_MPRUSER);
@@ -850,7 +851,7 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru
 			err = 1;
 		} else {
 			mprsas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD);
-			err = mpr_wait_command(sc, cm, 30, CAN_SLEEP);
+			err = mpr_wait_command(sc, &cm, 30, CAN_SLEEP);
 		}
 
 		if (err != 0) {
@@ -861,7 +862,7 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru
 		/*
 		 * Copy the reply data and sense data to user space.
 		 */
-		if (cm->cm_reply != NULL) {
+		if ((cm != NULL) && (cm->cm_reply != NULL)) {
 			rpl = (MPI2_DEFAULT_REPLY *)cm->cm_reply;
 			sz = rpl->MsgLength * 4;
 	
@@ -1054,13 +1055,12 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru
 
 	mpr_lock(sc);
 
-	err = mpr_wait_command(sc, cm, 30, CAN_SLEEP);
+	err = mpr_wait_command(sc, &cm, 30, CAN_SLEEP);
 
-	if (err) {
+	if (err || (cm == NULL)) {
 		mpr_printf(sc, "%s: invalid request: error %d\n", __func__,
 		    err);
-		mpr_unlock(sc);
-		goto RetFreeUnlocked;
+		goto RetFree;
 	}
 
 	/*
@@ -1153,6 +1153,7 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru
 RetFreeUnlocked:
 	mpr_lock(sc);
 
+RetFree:
 	if (cm != NULL) {
 		if (cm->cm_data)
 			free(cm->cm_data, M_MPRUSER);
@@ -1301,8 +1302,8 @@ mpr_post_fw_diag_buffer(struct mpr_softc *sc,
 	/*
 	 * Send command synchronously.
 	 */
-	status = mpr_wait_command(sc, cm, 30, CAN_SLEEP);
-	if (status) {
+	status = mpr_wait_command(sc, &cm, 30, CAN_SLEEP);
+	if (status || (cm == NULL)) {
 		mpr_printf(sc, "%s: invalid request: error %d\n", __func__,
 		    status);
 		status = MPR_DIAG_FAILURE;
@@ -1333,7 +1334,8 @@ mpr_post_fw_diag_buffer(struct mpr_softc *sc,
 	status = MPR_DIAG_SUCCESS;
 
 done:
-	mpr_free_command(sc, cm);
+	if (cm != NULL)
+		mpr_free_command(sc, cm);
 	return (status);
 }
 
@@ -1387,8 +1389,8 @@ mpr_release_fw_diag_buffer(struct mpr_softc *sc,
 	/*
 	 * Send command synchronously.
 	 */
-	status = mpr_wait_command(sc, cm, 30, CAN_SLEEP);
-	if (status) {
+	status = mpr_wait_command(sc, &cm, 30, CAN_SLEEP);
+	if (status || (cm == NULL)) {
 		mpr_printf(sc, "%s: invalid request: error %d\n", __func__,
 		    status);
 		status = MPR_DIAG_FAILURE;
@@ -1423,6 +1425,9 @@ mpr_release_fw_diag_buffer(struct mpr_softc *sc,
 	}
 
 done:
+	if (cm != NULL)
+		mpr_free_command(sc, cm);
+
 	return (status);
 }
 

Modified: stable/11/sys/dev/mpr/mprvar.h
==============================================================================
--- stable/11/sys/dev/mpr/mprvar.h	Fri Aug 18 14:17:12 2017	(r322657)
+++ stable/11/sys/dev/mpr/mprvar.h	Fri Aug 18 14:25:07 2017	(r322658)
@@ -275,9 +275,11 @@ struct mpr_softc {
 #define MPR_FLAGS_DIAGRESET	(1 << 4)
 #define	MPR_FLAGS_ATTACH_DONE	(1 << 5)
 #define	MPR_FLAGS_GEN35_IOC	(1 << 6)
+#define	MPR_FLAGS_REALLOCATED	(1 << 7)
 	u_int				mpr_debug;
 	u_int				disable_msix;
 	u_int				disable_msi;
+	int				msi_msgs;
 	u_int				atomic_desc_capable;
 	int				tm_cmds_active;
 	int				io_cmds_active;

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


More information about the svn-src-all mailing list