summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>2017-08-18 15:38:08 +0000
committerken <ken@FreeBSD.org>2017-08-18 15:38:08 +0000
commit505bc21ab0ebc18185b7a6cab2e17c84f7534a47 (patch)
treedeea465608d25cf3a2296434aecc52cd37d1ec15
parent52ef15fd258065de0e182da8ce09b1ebe4522404 (diff)
downloadFreeBSD-src-505bc21ab0ebc18185b7a6cab2e17c84f7534a47.zip
FreeBSD-src-505bc21ab0ebc18185b7a6cab2e17c84f7534a47.tar.gz
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 ------------------------------------------------------------------------ Approved by: re (marius)
-rw-r--r--sys/dev/mpr/mpr.c65
-rw-r--r--sys/dev/mpr/mpr_config.c114
-rw-r--r--sys/dev/mpr/mpr_pci.c77
-rw-r--r--sys/dev/mpr/mpr_sas.c9
-rw-r--r--sys/dev/mpr/mpr_sas_lsi.c18
-rw-r--r--sys/dev/mpr/mpr_table.c16
-rw-r--r--sys/dev/mpr/mpr_table.h69
-rw-r--r--sys/dev/mpr/mpr_user.c41
-rw-r--r--sys/dev/mpr/mprvar.h7
-rw-r--r--sys/dev/mps/mps.c45
-rw-r--r--sys/dev/mps/mps_config.c108
-rw-r--r--sys/dev/mps/mps_pci.c39
-rw-r--r--sys/dev/mps/mps_sas.c7
-rw-r--r--sys/dev/mps/mps_sas_lsi.c15
-rw-r--r--sys/dev/mps/mps_table.c16
-rw-r--r--sys/dev/mps/mps_table.h68
-rw-r--r--sys/dev/mps/mps_user.c38
-rw-r--r--sys/dev/mps/mpsvar.h5
18 files changed, 409 insertions, 348 deletions
diff --git a/sys/dev/mpr/mpr.c b/sys/dev/mpr/mpr.c
index 72edf46..f988e79 100644
--- a/sys/dev/mpr/mpr.c
+++ b/sys/dev/mpr/mpr.c
@@ -381,7 +381,7 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
}
}
- 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 attaching)
/* 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 attaching)
(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 data,
{
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, struct mpr_command *cm)
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_event_handle *handle,
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_event_handle *handle,
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_command *cm)
* 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_command *cm, int timeout,
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_command *cm, int timeout,
* 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_command *cm)
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_command *cm)
/*
* 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_command *cm)
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_config_params *params)
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);
diff --git a/sys/dev/mpr/mpr_config.c b/sys/dev/mpr/mpr_config.c
index 1ae0700..9f1ed1d 100644
--- a/sys/dev/mpr/mpr_config.c
+++ b/sys/dev/mpr/mpr_config.c
@@ -95,8 +95,9 @@ mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
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, Mpi2ConfigReply_t *mpi_reply,
}
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, Mpi2ConfigReply_t *mpi_reply,
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, Mpi2ConfigReply_t *mpi_reply,
}
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, Mpi2ConfigReply_t *mpi_reply,
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, Mpi2ConfigReply_t *mpi_reply,
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, Mpi2ConfigReply_t *mpi_reply,
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, Mpi2ConfigReply_t *mpi_reply,
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, Mpi2ConfigReply_t
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, Mpi2ConfigReply_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 */
/*
@@ -799,8 +809,9 @@ mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t
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, Mpi2ConfigReply_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 */
/*
@@ -934,8 +946,9 @@ mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t
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, Mpi2ConfigReply_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 */
/*
@@ -1066,8 +1080,9 @@ mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
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, Mpi2ConfigReply_t *mpi_reply,
}
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, Mpi2ConfigReply_t
*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, Mpi2ConfigReply_t
* 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, Mpi2ConfigReply_t
* 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, Mpi2ConfigReply_t
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, Mpi2ConfigReply_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 */
/*
@@ -1459,7 +1479,7 @@ mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply,
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, Mpi2ConfigReply_t *mpi_reply,
* 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, Mpi2ConfigReply_t *mpi_reply,
* 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 */
diff --git a/sys/dev/mpr/mpr_pci.c b/sys/dev/mpr/mpr_pci.c
index 4b9f0aa..6275c98 100644
--- a/sys/dev/mpr/mpr_pci.c
+++ b/sys/dev/mpr/mpr_pci.c
@@ -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;
+
+ 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 (error != 0) {
+ 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,
diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c
index 13a7667..bdaa4ab 100644
--- a/sys/dev/mpr/mpr_sas.c
+++ b/sys/dev/mpr/mpr_sas.c
@@ -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 mpr_command *cm)
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");
}
}
diff --git a/sys/dev/mpr/mpr_sas_lsi.c b/sys/dev/mpr/mpr_sas_lsi.c
index 0443181..1883b1c 100644
--- a/sys/dev/mpr/mpr_sas_lsi.c
+++ b/sys/dev/mpr/mpr_sas_lsi.c
@@ -139,7 +139,7 @@ mprsas_evt_handler(struct mpr_softc *sc, uintptr_t data,
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_event_work *fw_event)
{
// 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_event_work *fw_event)
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 handle,
"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);
/*
diff --git a/sys/dev/mpr/mpr_table.c b/sys/dev/mpr/mpr_table.c
index 44420fd..bef865f 100644
--- a/sys/dev/mpr/mpr_table.c
+++ b/sys/dev/mpr/mpr_table.c
@@ -219,7 +219,7 @@ mpr_describe_devinfo(uint32_t devinfo, char *string, int len)
}
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_FACTS_REPLY *facts)
}
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_FACTS_REPLY *facts)
}
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_NOTIFICATION_REPLY *event)
}
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_PAGE_SAS_DEV_0 *buf)
}
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_NOTIFICATION_REPLY *event)
}
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_PAGE_EXPANDER_1 *buf)
}
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);
diff --git a/sys/dev/mpr/mpr_table.h b/sys/dev/mpr/mpr_table.h
index 162689a..5254259 100644
--- a/sys/dev/mpr/mpr_table.h
+++ b/sys/dev/mpr/mpr_table.h
@@ -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);
-}
-
-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_PAGE(sc, level, func, buf) \
+do { \
+ if ((sc)->mpr_debug & level) \
+ mpr_print_##func((sc), buf); \
+} while (0)
+#define MPR_DPRINT_EVENT(sc, func, buf) \
+ MPR_DPRINT_PAGE(sc, MPR_EVENT, evt_##func, buf)
#endif
diff --git a/sys/dev/mpr/mpr_user.c b/sys/dev/mpr/mpr_user.c
index 750b126..fb9a0ba 100644
--- a/sys/dev/mpr/mpr_user.c
+++ b/sys/dev/mpr/mpr_user.c
@@ -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_command *cmd)
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_command *cmd)
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_command *cmd)
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_t *data)
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_t *data)
/*
* 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_t *data)
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_t *data)
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);
}
diff --git a/sys/dev/mpr/mprvar.h b/sys/dev/mpr/mprvar.h
index 1e97a75..fd16bef 100644
--- a/sys/dev/mpr/mprvar.h
+++ b/sys/dev/mpr/mprvar.h
@@ -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;
@@ -702,6 +704,7 @@ mpr_unmask_intr(struct mpr_softc *sc)
int mpr_pci_setup_interrupts(struct mpr_softc *sc);
int mpr_pci_restore(struct mpr_softc *sc);
+void mpr_get_tunables(struct mpr_softc *sc);
int mpr_attach(struct mpr_softc *sc);
int mpr_free(struct mpr_softc *sc);
void mpr_intr(void *);
@@ -730,9 +733,9 @@ void mprsas_record_event(struct mpr_softc *sc,
MPI2_EVENT_NOTIFICATION_REPLY *event_reply);
int mpr_map_command(struct mpr_softc *sc, struct mpr_command *cm);
-int mpr_wait_command(struct mpr_softc *sc, struct mpr_command *cm, int timeout,
+int mpr_wait_command(struct mpr_softc *sc, struct mpr_command **cm, int timeout,
int sleep_flag);
-int mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm);
+int mpr_request_polled(struct mpr_softc *sc, struct mpr_command **cm);
int mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t
*mpi_reply, Mpi2BiosPage3_t *config_page);
diff --git a/sys/dev/mps/mps.c b/sys/dev/mps/mps.c
index 357c87f..ec046a4 100644
--- a/sys/dev/mps/mps.c
+++ b/sys/dev/mps/mps.c
@@ -373,7 +373,7 @@ mps_iocfacts_allocate(struct mps_softc *sc, uint8_t attaching)
}
}
- mps_print_iocfacts(sc, sc->facts);
+ MPS_DPRINT_PAGE(sc, MPS_XINFO, iocfacts, sc->facts);
snprintf(sc->fw_version, sizeof(sc->fw_version),
"%02d.%02d.%02d.%02d",
@@ -427,6 +427,8 @@ mps_iocfacts_allocate(struct mps_softc *sc, uint8_t attaching)
/* Only deallocate and reallocate if relevant IOC Facts have changed */
reallocating = FALSE;
+ sc->mps_flags &= ~MPS_FLAGS_REALLOCATED;
+
if ((!attaching) &&
((saved_facts.MsgVersion != sc->facts->MsgVersion) ||
(saved_facts.HeaderVersion != sc->facts->HeaderVersion) ||
@@ -447,6 +449,9 @@ mps_iocfacts_allocate(struct mps_softc *sc, uint8_t attaching)
(saved_facts.MaxPersistentEntries !=
sc->facts->MaxPersistentEntries))) {
reallocating = TRUE;
+
+ /* Record that we reallocated everything */
+ sc->mps_flags |= MPS_FLAGS_REALLOCATED;
}
/*
@@ -1341,7 +1346,7 @@ mps_init_queues(struct mps_softc *sc)
* Next are the global settings, if they exist. Highest are the per-unit
* settings, if they exist.
*/
-static void
+void
mps_get_tunables(struct mps_softc *sc)
{
char tmpstr[80];
@@ -1513,8 +1518,6 @@ mps_attach(struct mps_softc *sc)
{
int error;
- mps_get_tunables(sc);
-
MPS_FUNCTRACE(sc);
mtx_init(&sc->mps_mtx, "MPT2SAS lock", NULL, MTX_DEF);
@@ -1625,7 +1628,7 @@ mps_log_evt_handler(struct mps_softc *sc, uintptr_t data,
{
MPI2_EVENT_DATA_LOG_ENTRY_ADDED *entry;
- mps_print_event(sc, event);
+ MPS_DPRINT_EVENT(sc, generic, event);
switch (event->Event) {
case MPI2_EVENT_LOG_DATA:
@@ -2035,7 +2038,7 @@ mps_reregister_events_complete(struct mps_softc *sc, struct mps_command *cm)
mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
if (cm->cm_reply)
- mps_print_event(sc,
+ MPS_DPRINT_EVENT(sc, generic,
(MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply);
mps_free_command(sc, cm);
@@ -2077,7 +2080,7 @@ mps_update_events(struct mps_softc *sc, struct mps_event_handle *handle,
u32 *mask)
{
MPI2_EVENT_NOTIFICATION_REQUEST *evtreq;
- MPI2_EVENT_NOTIFICATION_REPLY *reply;
+ MPI2_EVENT_NOTIFICATION_REPLY *reply = NULL;
struct mps_command *cm;
int error, i;
@@ -2115,15 +2118,20 @@ mps_update_events(struct mps_softc *sc, struct mps_event_handle *handle,
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
- error = mps_wait_command(sc, cm, 60, 0);
- reply = (MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, 0);
+ if (cm != NULL)
+ reply = (MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply;
if ((reply == NULL) ||
(reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS)
error = ENXIO;
- mps_print_event(sc, reply);
+
+ if (reply)
+ MPS_DPRINT_EVENT(sc, generic, reply);
+
mps_dprint(sc, MPS_TRACE, "%s finished error %d\n", __func__, error);
- mps_free_command(sc, cm);
+ if (cm != NULL)
+ mps_free_command(sc, cm);
return (error);
}
@@ -2529,11 +2537,12 @@ mps_map_command(struct mps_softc *sc, struct mps_command *cm)
* be executed and enqueued automatically. Other errors come from msleep().
*/
int
-mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout,
+mps_wait_command(struct mps_softc *sc, struct mps_command **cmp, int timeout,
int sleep_flag)
{
int error, rc;
struct timeval cur_time, start_time;
+ struct mps_command *cm = *cmp;
if (sc->mps_flags & MPS_FLAGS_DIAGRESET)
return EBUSY;
@@ -2587,6 +2596,13 @@ mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout,
rc = mps_reinit(sc);
mps_dprint(sc, MPS_FAULT, "Reinit %s\n", (rc == 0) ? "success" :
"failed");
+ if (sc->mps_flags & MPS_FLAGS_REALLOCATED) {
+ /*
+ * Tell the caller that we freed the command in a
+ * reinit.
+ */
+ *cmp = NULL;
+ }
error = ETIMEDOUT;
}
return (error);
@@ -2653,11 +2669,12 @@ mps_read_config_page(struct mps_softc *sc, struct mps_config_params *params)
cm->cm_complete = mps_config_complete;
return (mps_map_command(sc, cm));
} else {
- error = mps_wait_command(sc, cm, 0, CAN_SLEEP);
+ error = mps_wait_command(sc, &cm, 0, CAN_SLEEP);
if (error) {
mps_dprint(sc, MPS_FAULT,
"Error %d reading config page\n", error);
- mps_free_command(sc, cm);
+ if (cm != NULL)
+ mps_free_command(sc, cm);
return (error);
}
mps_config_complete(sc, cm);
diff --git a/sys/dev/mps/mps_config.c b/sys/dev/mps/mps_config.c
index 8afd384..905fd73 100644
--- a/sys/dev/mps/mps_config.c
+++ b/sys/dev/mps/mps_config.c
@@ -71,7 +71,7 @@ mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
Mpi2IOCPage8_t *config_page)
{
MPI2_CONFIG_REQUEST *request;
- MPI2_CONFIG_REPLY *reply;
+ MPI2_CONFIG_REPLY *reply = NULL;
struct mps_command *cm;
MPI2_CONFIG_PAGE_IOC_8 *page = NULL;
int error = 0;
@@ -94,8 +94,9 @@ mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
request->Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -152,8 +153,9 @@ mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
}
cm->cm_data = page;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -200,7 +202,7 @@ int
mps_config_get_man_pg10(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply)
{
MPI2_CONFIG_REQUEST *request;
- MPI2_CONFIG_REPLY *reply;
+ MPI2_CONFIG_REPLY *reply = NULL;
struct mps_command *cm;
pMpi2ManufacturingPagePS_t page = NULL;
uint32_t *pPS_info;
@@ -230,8 +232,9 @@ mps_config_get_man_pg10(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply)
* This page must be polled because the IOC isn't ready yet when this
* page is needed.
*/
- error = mps_wait_command(sc, cm, 60, 0);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, 0);
+ 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 */
@@ -286,8 +289,9 @@ mps_config_get_man_pg10(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply)
* This page must be polled because the IOC isn't ready yet when this
* page is needed.
*/
- error = mps_wait_command(sc, cm, 60, 0);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, 0);
+ 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 */
@@ -559,7 +563,7 @@ mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
Mpi2DriverMappingPage0_t *config_page, u16 sz)
{
MPI2_CONFIG_REQUEST *request;
- MPI2_CONFIG_REPLY *reply;
+ MPI2_CONFIG_REPLY *reply = NULL;
struct mps_command *cm;
Mpi2DriverMappingPage0_t *page = NULL;
int error = 0;
@@ -586,8 +590,9 @@ mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -646,8 +651,9 @@ mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
goto out;
}
cm->cm_data = page;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -695,7 +701,7 @@ int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
Mpi2DriverMappingPage0_t *config_page, u16 entry_idx)
{
MPI2_CONFIG_REQUEST *request;
- MPI2_CONFIG_REPLY *reply;
+ MPI2_CONFIG_REPLY *reply = NULL;
struct mps_command *cm;
MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 *page = NULL;
int error = 0;
@@ -722,8 +728,9 @@ int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
request->PageAddress |= htole16(entry_idx);
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -784,8 +791,9 @@ int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
bcopy(config_page, page, MIN(cm->cm_length,
(sizeof(Mpi2DriverMappingPage0_t))));
cm->cm_data = page;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -833,7 +841,7 @@ mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t
*mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u16 handle)
{
MPI2_CONFIG_REQUEST *request;
- MPI2_CONFIG_REPLY *reply;
+ MPI2_CONFIG_REPLY *reply = NULL;
struct mps_command *cm;
Mpi2SasDevicePage0_t *page = NULL;
int error = 0;
@@ -857,8 +865,9 @@ mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t
request->Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -917,8 +926,9 @@ mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t
}
cm->cm_data = page;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -966,7 +976,7 @@ mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
Mpi2BiosPage3_t *config_page)
{
MPI2_CONFIG_REQUEST *request;
- MPI2_CONFIG_REPLY *reply;
+ MPI2_CONFIG_REPLY *reply = NULL;
struct mps_command *cm;
Mpi2BiosPage3_t *page = NULL;
int error = 0;
@@ -989,8 +999,9 @@ mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
request->Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -1047,8 +1058,9 @@ mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
}
cm->cm_data = page;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -1096,7 +1108,7 @@ mps_config_get_raid_volume_pg0(struct mps_softc *sc, Mpi2ConfigReply_t
*mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address)
{
MPI2_CONFIG_REQUEST *request;
- MPI2_CONFIG_REPLY *reply;
+ MPI2_CONFIG_REPLY *reply = NULL;
struct mps_command *cm;
Mpi2RaidVolPage0_t *page = NULL;
int error = 0;
@@ -1124,8 +1136,9 @@ mps_config_get_raid_volume_pg0(struct mps_softc *sc, Mpi2ConfigReply_t
* This page must be polled because the IOC isn't ready yet when this
* page is needed.
*/
- error = mps_wait_command(sc, cm, 60, 0);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, 0);
+ 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 */
@@ -1181,8 +1194,9 @@ mps_config_get_raid_volume_pg0(struct mps_softc *sc, Mpi2ConfigReply_t
* This page must be polled because the IOC isn't ready yet when this
* page is needed.
*/
- error = mps_wait_command(sc, cm, 60, 0);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, 0);
+ 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 */
@@ -1225,7 +1239,7 @@ mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t
*mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u16 handle)
{
MPI2_CONFIG_REQUEST *request;
- MPI2_CONFIG_REPLY *reply;
+ MPI2_CONFIG_REPLY *reply = NULL;
struct mps_command *cm;
Mpi2RaidVolPage1_t *page = NULL;
int error = 0;
@@ -1248,8 +1262,9 @@ mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t
request->Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -1307,8 +1322,9 @@ mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t
}
cm->cm_data = page;
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
+ if (cm != NULL)
+ reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
@@ -1382,7 +1398,7 @@ mps_config_get_raid_pd_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address)
{
MPI2_CONFIG_REQUEST *request;
- MPI2_CONFIG_REPLY *reply;
+ MPI2_CONFIG_REPLY *reply = NULL;
struct mps_command *cm;
Mpi2RaidPhysDiskPage0_t *page = NULL;
int error = 0;
@@ -1410,8 +1426,9 @@ mps_config_get_raid_pd_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
* This page must be polled because the IOC isn't ready yet when this
* page is needed.
*/
- error = mps_wait_command(sc, cm, 60, 0);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, 0);
+ 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 */
@@ -1467,8 +1484,9 @@ mps_config_get_raid_pd_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply,
* This page must be polled because the IOC isn't ready yet when this
* page is needed.
*/
- error = mps_wait_command(sc, cm, 60, 0);
- reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
+ error = mps_wait_command(sc, &cm, 60, 0);
+ 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 */
diff --git a/sys/dev/mps/mps_pci.c b/sys/dev/mps/mps_pci.c
index cee4376..bfa71cc 100644
--- a/sys/dev/mps/mps_pci.c
+++ b/sys/dev/mps/mps_pci.c
@@ -68,6 +68,7 @@ static int mps_pci_resume(device_t);
static void mps_pci_free(struct mps_softc *);
static int mps_alloc_msix(struct mps_softc *sc, int msgs);
static int mps_alloc_msi(struct mps_softc *sc, int msgs);
+static int mps_pci_alloc_interrupts(struct mps_softc *sc);
static device_method_t mps_methods[] = {
DEVMETHOD(device_probe, mps_pci_probe),
@@ -191,6 +192,8 @@ mps_pci_attach(device_t dev)
m = mps_find_ident(dev);
sc->mps_flags = m->flags;
+ mps_get_tunables(sc);
+
/* Twiddle basic PCI config bits for a sanity check */
pci_enable_busmaster(dev);
@@ -221,28 +224,52 @@ mps_pci_attach(device_t dev)
return (ENOMEM);
}
- if ((error = mps_attach(sc)) != 0)
+ if (((error = mps_pci_alloc_interrupts(sc)) != 0) ||
+ ((error = mps_attach(sc)) != 0))
mps_pci_free(sc);
return (error);
}
-int
-mps_pci_setup_interrupts(struct mps_softc *sc)
+/*
+ * 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.
+ */
+static int
+mps_pci_alloc_interrupts(struct mps_softc *sc)
{
device_t dev;
- int i, error, msgs;
+ int error, msgs;
dev = sc->mps_dev;
- error = ENXIO;
+ error = 0;
+ msgs = 0;
+
if ((sc->disable_msix == 0) &&
((msgs = pci_msix_count(dev)) >= MPS_MSI_COUNT))
error = mps_alloc_msix(sc, MPS_MSI_COUNT);
if ((error != 0) && (sc->disable_msi == 0) &&
((msgs = pci_msi_count(dev)) >= MPS_MSI_COUNT))
error = mps_alloc_msi(sc, MPS_MSI_COUNT);
+ if (error != 0)
+ msgs = 0;
+
+ sc->msi_msgs = msgs;
+ return (error);
+}
+
+int
+mps_pci_setup_interrupts(struct mps_softc *sc)
+{
+ device_t dev;
+ int i, error;
+
+ dev = sc->mps_dev;
+ error = ENXIO;
- if (error != 0) {
+ if (sc->msi_msgs == 0) {
sc->mps_flags |= MPS_FLAGS_INTX;
sc->mps_irq_rid[0] = 0;
sc->mps_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ,
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index af2e396..5fcdeb0 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -1131,13 +1131,8 @@ mpssas_complete_all_commands(struct mps_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 {
- mps_dprint(cm->cm_sc, MPS_INFO, "Warning: "
- "io_cmds_active is out of sync - resynching to "
- "0\n");
- }
if ((completed == 0) && (cm->cm_state != MPS_CM_STATE_FREE)) {
/* this should never happen, but if it does, log */
diff --git a/sys/dev/mps/mps_sas_lsi.c b/sys/dev/mps/mps_sas_lsi.c
index aa77067..a9ccd5b 100644
--- a/sys/dev/mps/mps_sas_lsi.c
+++ b/sys/dev/mps/mps_sas_lsi.c
@@ -136,7 +136,7 @@ mpssas_evt_handler(struct mps_softc *sc, uintptr_t data,
u16 sz;
mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
- mps_print_evt_sas(sc, event);
+ MPS_DPRINT_EVENT(sc, sas, event);
mpssas_record_event(sc, event);
fw_event = malloc(sizeof(struct mps_fw_event_work), M_MPT2,
@@ -915,7 +915,7 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 handle,
Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz, u32 devinfo)
{
Mpi2SataPassthroughRequest_t *mpi_request;
- Mpi2SataPassthroughReply_t *reply;
+ Mpi2SataPassthroughReply_t *reply = NULL;
struct mps_command *cm;
char *buffer;
int error = 0;
@@ -957,12 +957,14 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 handle,
"command\n", __func__);
callout_reset(&cm->cm_callout, MPS_ATA_ID_TIMEOUT * hz,
mpssas_ata_id_timeout, cm);
- error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
+ error = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
mps_dprint(sc, MPS_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 */
/*
@@ -989,7 +991,8 @@ out:
* it. The command will be freed after sending a target reset TM. If
* the command did timeout, use EWOULDBLOCK.
*/
- if ((cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
+ if ((cm != NULL)
+ && (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
mps_free_command(sc, cm);
else if (error == 0)
error = EWOULDBLOCK;
@@ -1285,7 +1288,7 @@ mpssas_ir_shutdown(struct mps_softc *sc)
action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
mps_lock(sc);
- mps_wait_command(sc, cm, 5, CAN_SLEEP);
+ mps_wait_command(sc, &cm, 5, CAN_SLEEP);
mps_unlock(sc);
/*
diff --git a/sys/dev/mps/mps_table.c b/sys/dev/mps/mps_table.c
index b6c96ed..3abcc601 100644
--- a/sys/dev/mps/mps_table.c
+++ b/sys/dev/mps/mps_table.c
@@ -196,7 +196,7 @@ mps_describe_devinfo(uint32_t devinfo, char *string, int len)
}
void
-_mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
+mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
{
MPS_PRINTFIELD_START(sc, "IOCFacts");
@@ -237,7 +237,7 @@ _mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
}
void
-_mps_print_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
+mps_print_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
{
MPS_PRINTFIELD_START(sc, "PortFacts");
@@ -247,7 +247,7 @@ _mps_print_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
}
void
-_mps_print_event(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+mps_print_evt_generic(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
{
MPS_PRINTFIELD_START(sc, "EventReply");
@@ -259,7 +259,7 @@ _mps_print_event(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
}
void
-_mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
+mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
{
MPS_PRINTFIELD_START(sc, "SAS Device Page 0");
MPS_PRINTFIELD(sc, buf, Slot, %d);
@@ -288,10 +288,10 @@ _mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
}
void
-_mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
+mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
{
- _mps_print_event(sc, event);
+ mps_print_evt_generic(sc, event);
switch(event->Event) {
case MPI2_EVENT_SAS_DISCOVERY:
@@ -384,7 +384,7 @@ _mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
}
void
-_mps_print_expander1(struct mps_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
+mps_print_expander1(struct mps_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
{
MPS_PRINTFIELD_START(sc, "SAS Expander Page 1 #%d", buf->Phy);
MPS_PRINTFIELD(sc, buf, PhysicalPort, %d);
@@ -424,7 +424,7 @@ _mps_print_expander1(struct mps_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
}
void
-_mps_print_sasphy0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
+mps_print_sasphy0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
{
MPS_PRINTFIELD_START(sc, "SAS PHY Page 0");
MPS_PRINTFIELD(sc, buf, OwnerDevHandle, 0x%04x);
diff --git a/sys/dev/mps/mps_table.h b/sys/dev/mps/mps_table.h
index 1fe6b1e..77e060a 100644
--- a/sys/dev/mps/mps_table.h
+++ b/sys/dev/mps/mps_table.h
@@ -41,63 +41,23 @@ extern struct mps_table_lookup mps_event_names[];
extern struct mps_table_lookup mps_phystatus_names[];
extern struct mps_table_lookup mps_linkrate_names[];
-void _mps_print_iocfacts(struct mps_softc *, MPI2_IOC_FACTS_REPLY *);
-void _mps_print_portfacts(struct mps_softc *, MPI2_PORT_FACTS_REPLY *);
-void _mps_print_event(struct mps_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
-void _mps_print_sasdev0(struct mps_softc *, MPI2_CONFIG_PAGE_SAS_DEV_0 *);
-void _mps_print_evt_sas(struct mps_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
-void _mps_print_expander1(struct mps_softc *, MPI2_CONFIG_PAGE_EXPANDER_1 *);
-void _mps_print_sasphy0(struct mps_softc *, MPI2_CONFIG_PAGE_SAS_PHY_0 *);
+void mps_print_iocfacts(struct mps_softc *, MPI2_IOC_FACTS_REPLY *);
+void mps_print_portfacts(struct mps_softc *, MPI2_PORT_FACTS_REPLY *);
+void mps_print_evt_generic(struct mps_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
+void mps_print_sasdev0(struct mps_softc *, MPI2_CONFIG_PAGE_SAS_DEV_0 *);
+void mps_print_evt_sas(struct mps_softc *, MPI2_EVENT_NOTIFICATION_REPLY *);
+void mps_print_expander1(struct mps_softc *, MPI2_CONFIG_PAGE_EXPANDER_1 *);
+void mps_print_sasphy0(struct mps_softc *, MPI2_CONFIG_PAGE_SAS_PHY_0 *);
void mps_print_sgl(struct mps_softc *, struct mps_command *, int);
void mps_print_scsiio_cmd(struct mps_softc *, struct mps_command *);
-static __inline void
-mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
-{
- if (sc->mps_debug & MPS_XINFO)
- _mps_print_iocfacts(sc, facts);
-}
+#define MPS_DPRINT_PAGE(sc, level, func, buf) \
+do { \
+ if ((sc)->mps_debug & level) \
+ mps_print_##func((sc), buf); \
+} while (0)
-static __inline void
-mps_print_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
-{
- if (sc->mps_debug & MPS_XINFO)
- _mps_print_portfacts(sc, facts);
-}
-
-static __inline void
-mps_print_event(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
-{
- if (sc->mps_debug & MPS_EVENT)
- _mps_print_event(sc, event);
-}
-
-static __inline void
-mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
-{
- if (sc->mps_debug & MPS_XINFO)
- _mps_print_sasdev0(sc, buf);
-}
-
-static __inline void
-mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
-{
- if (sc->mps_debug & MPS_EVENT)
- _mps_print_evt_sas(sc, event);
-}
-
-static __inline void
-mps_print_expander1(struct mps_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
-{
- if (sc->mps_debug & MPS_XINFO)
- _mps_print_expander1(sc, buf);
-}
-
-static __inline void
-mps_print_sasphy0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
-{
- if (sc->mps_debug & MPS_XINFO)
- _mps_print_sasphy0(sc, buf);
-}
+#define MPS_DPRINT_EVENT(sc, func, buf) \
+ MPS_DPRINT_PAGE(sc, MPS_EVENT, evt_##func, buf)
#endif
diff --git a/sys/dev/mps/mps_user.c b/sys/dev/mps/mps_user.c
index dc1ced1..c245efa 100644
--- a/sys/dev/mps/mps_user.c
+++ b/sys/dev/mps/mps_user.c
@@ -677,7 +677,7 @@ mps_user_command(struct mps_softc *sc, struct mps_usr_command *cmd)
if (cm == NULL) {
mps_printf(sc, "%s: no mps requests\n", __func__);
err = ENOMEM;
- goto Ret;
+ goto RetFree;
}
mps_unlock(sc);
@@ -719,12 +719,12 @@ mps_user_command(struct mps_softc *sc, struct mps_usr_command *cmd)
goto RetFreeUnlocked;
mps_lock(sc);
- err = mps_wait_command(sc, cm, 60, CAN_SLEEP);
+ err = mps_wait_command(sc, &cm, 60, CAN_SLEEP);
- if (err) {
+ if (err || (cm == NULL)) {
mps_printf(sc, "%s: invalid request: error %d\n",
__func__, err);
- goto Ret;
+ goto RetFree;
}
rpl = (MPI2_DEFAULT_REPLY *)cm->cm_reply;
@@ -747,9 +747,9 @@ mps_user_command(struct mps_softc *sc, struct mps_usr_command *cmd)
RetFreeUnlocked:
mps_lock(sc);
+RetFree:
if (cm != NULL)
mps_free_command(sc, cm);
-Ret:
mps_unlock(sc);
if (buf != NULL)
free(buf, M_MPSUSER);
@@ -760,7 +760,7 @@ static int
mps_user_pass_thru(struct mps_softc *sc, mps_pass_thru_t *data)
{
MPI2_REQUEST_HEADER *hdr, tmphdr;
- MPI2_DEFAULT_REPLY *rpl;
+ MPI2_DEFAULT_REPLY *rpl = NULL;
struct mps_command *cm = NULL;
int err = 0, dir = 0, sz;
uint8_t function = 0;
@@ -861,7 +861,7 @@ mps_user_pass_thru(struct mps_softc *sc, mps_pass_thru_t *data)
err = 1;
} else {
mpssas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD);
- err = mps_wait_command(sc, cm, 30, CAN_SLEEP);
+ err = mps_wait_command(sc, &cm, 30, CAN_SLEEP);
}
if (err != 0) {
@@ -872,7 +872,7 @@ mps_user_pass_thru(struct mps_softc *sc, mps_pass_thru_t *data)
/*
* 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;
@@ -993,9 +993,9 @@ mps_user_pass_thru(struct mps_softc *sc, mps_pass_thru_t *data)
mps_lock(sc);
- err = mps_wait_command(sc, cm, 30, CAN_SLEEP);
+ err = mps_wait_command(sc, &cm, 30, CAN_SLEEP);
- if (err) {
+ if (err || (cm == NULL)) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
err);
mps_unlock(sc);
@@ -1161,7 +1161,7 @@ mps_post_fw_diag_buffer(struct mps_softc *sc,
mps_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code)
{
MPI2_DIAG_BUFFER_POST_REQUEST *req;
- MPI2_DIAG_BUFFER_POST_REPLY *reply;
+ MPI2_DIAG_BUFFER_POST_REPLY *reply = NULL;
struct mps_command *cm = NULL;
int i, status;
@@ -1208,8 +1208,8 @@ mps_post_fw_diag_buffer(struct mps_softc *sc,
/*
* Send command synchronously.
*/
- status = mps_wait_command(sc, cm, 30, CAN_SLEEP);
- if (status) {
+ status = mps_wait_command(sc, &cm, 30, CAN_SLEEP);
+ if (status || (cm == NULL)) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
status);
status = MPS_DIAG_FAILURE;
@@ -1240,7 +1240,8 @@ mps_post_fw_diag_buffer(struct mps_softc *sc,
status = MPS_DIAG_SUCCESS;
done:
- mps_free_command(sc, cm);
+ if (cm != NULL)
+ mps_free_command(sc, cm);
return (status);
}
@@ -1250,7 +1251,7 @@ mps_release_fw_diag_buffer(struct mps_softc *sc,
uint32_t diag_type)
{
MPI2_DIAG_RELEASE_REQUEST *req;
- MPI2_DIAG_RELEASE_REPLY *reply;
+ MPI2_DIAG_RELEASE_REPLY *reply = NULL;
struct mps_command *cm = NULL;
int status;
@@ -1294,8 +1295,8 @@ mps_release_fw_diag_buffer(struct mps_softc *sc,
/*
* Send command synchronously.
*/
- status = mps_wait_command(sc, cm, 30, CAN_SLEEP);
- if (status) {
+ status = mps_wait_command(sc, &cm, 30, CAN_SLEEP);
+ if (status || (cm == NULL)) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
status);
status = MPS_DIAG_FAILURE;
@@ -1330,6 +1331,9 @@ mps_release_fw_diag_buffer(struct mps_softc *sc,
}
done:
+ if (cm != NULL)
+ mps_free_command(sc, cm);
+
return (status);
}
diff --git a/sys/dev/mps/mpsvar.h b/sys/dev/mps/mpsvar.h
index 9b6d72f..b8d074a 100644
--- a/sys/dev/mps/mpsvar.h
+++ b/sys/dev/mps/mpsvar.h
@@ -271,9 +271,11 @@ struct mps_softc {
#define MPS_FLAGS_DIAGRESET (1 << 4)
#define MPS_FLAGS_ATTACH_DONE (1 << 5)
#define MPS_FLAGS_WD_AVAILABLE (1 << 6)
+#define MPS_FLAGS_REALLOCATED (1 << 7)
u_int mps_debug;
u_int disable_msix;
u_int disable_msi;
+ u_int msi_msgs;
int tm_cmds_active;
int io_cmds_active;
int io_cmds_highwater;
@@ -671,6 +673,7 @@ mps_unmask_intr(struct mps_softc *sc)
int mps_pci_setup_interrupts(struct mps_softc *sc);
int mps_pci_restore(struct mps_softc *sc);
+void mps_get_tunables(struct mps_softc *sc);
int mps_attach(struct mps_softc *sc);
int mps_free(struct mps_softc *sc);
void mps_intr(void *);
@@ -695,7 +698,7 @@ void mpssas_record_event(struct mps_softc *sc,
MPI2_EVENT_NOTIFICATION_REPLY *event_reply);
int mps_map_command(struct mps_softc *sc, struct mps_command *cm);
-int mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout,
+int mps_wait_command(struct mps_softc *sc, struct mps_command **cm, int timeout,
int sleep_flag);
int mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t
OpenPOWER on IntegriCloud