summaryrefslogtreecommitdiffstats
path: root/sys/dev/mpr/mpr_user.c
diff options
context:
space:
mode:
authorslm <slm@FreeBSD.org>2017-06-01 15:39:09 +0000
committerslm <slm@FreeBSD.org>2017-06-01 15:39:09 +0000
commit58a58e183e3d690ffdaa01b0873c17c420cd765a (patch)
tree461c5682b74995934f8ece68093966c7d13bd028 /sys/dev/mpr/mpr_user.c
parent5e170453372eb92d479ec8beb3e61951b2369f71 (diff)
downloadFreeBSD-src-58a58e183e3d690ffdaa01b0873c17c420cd765a.zip
FreeBSD-src-58a58e183e3d690ffdaa01b0873c17c420cd765a.tar.gz
MFC r308217, r308301, r311958, r312437, r318188, r318427, r318679
r308217: Add a fallback to the device mapper logic. We've seen systems in the field that are apparently misconfigured by the manufacturer and cause the mapping logic to fail. The fallback allows drive numbers to be assigned based on the PHY number that they're attached to. Add sysctls and tunables to overrid this new behavior, but they should be considered only necessary for debugging. Reviewed by: imp, smh Obtained from: Netflix MFC after: 3 days Sponsored by: D8403 r308301: Record the LogInfo field when reporting the IOCStatus. Helps in debugging errors. Submitted by: slm Obtained from: Netflix MFC after: 3 days r311958: Print out the number of queues/MSIx vectors. Sponsored by: Netflix r312437: Rework the debug print API. Event printing no longer gets special handling. All of the printing from the tables file now has wrappers so that the handling is cleaner and it's possible to print something out (say, during development) without having to fight the global debug flags. This re-org will also make it easier to have the tables be compiled out at build time if desired. Other than fixing some minor bugs, there are no user-visible changes from this change Sponsored by: Netflix, Inc. Differential Revision: D9238 r318188: Improve error messages during command timeout for the mpr and mps drivers. Sponsored by: Netflix r318427: Add tri-mode support (SAS/SATA/PCIe). This includes NVMe device support and adds support for the following adapters: SAS 3408 SAS 3416 SAS 3508 SAS 3516 SAS 3616 SAS 3708 SAS 3716 Reviewed by: ken, scottl, asomers, mav Approved by: ken, scottl, mav MFC after: 2 weeks Relnotes: yes Differential Revision: https://reviews.freebsd.org/D10095 r318679: Fix powerpc compiler error. Approved by: ken
Diffstat (limited to 'sys/dev/mpr/mpr_user.c')
-rw-r--r--sys/dev/mpr/mpr_user.c82
1 files changed, 75 insertions, 7 deletions
diff --git a/sys/dev/mpr/mpr_user.c b/sys/dev/mpr/mpr_user.c
index 0a847de..b1c1109 100644
--- a/sys/dev/mpr/mpr_user.c
+++ b/sys/dev/mpr/mpr_user.c
@@ -99,6 +99,7 @@ __FBSDID("$FreeBSD$");
#include <dev/mpr/mpi/mpi2_cnfg.h>
#include <dev/mpr/mpi/mpi2_init.h>
#include <dev/mpr/mpi/mpi2_tool.h>
+#include <dev/mpr/mpi/mpi2_pci.h>
#include <dev/mpr/mpr_ioctl.h>
#include <dev/mpr/mprvar.h>
#include <dev/mpr/mpr_table.h>
@@ -747,6 +748,8 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
{
MPI2_REQUEST_HEADER *hdr, tmphdr;
MPI2_DEFAULT_REPLY *rpl;
+ Mpi26NVMeEncapsulatedErrorReply_t *nvme_error_reply = NULL;
+ Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request = NULL;
struct mpr_command *cm = NULL;
int i, err = 0, dir = 0, sz;
uint8_t tool, function = 0;
@@ -923,8 +926,8 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
cm->cm_data, data->DataSize);
}
if (err != 0)
- mpr_dprint(sc, MPR_FAULT, "%s: failed to copy "
- "IOCTL data from user space\n", __func__);
+ mpr_dprint(sc, MPR_FAULT, "%s: failed to copy IOCTL "
+ "data from user space\n", __func__);
}
/*
* Set this flag only if processing a command that does not need an
@@ -946,6 +949,35 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
}
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
+ if (function == MPI2_FUNCTION_NVME_ENCAPSULATED) {
+ nvme_encap_request =
+ (Mpi26NVMeEncapsulatedRequest_t *)cm->cm_req;
+ cm->cm_desc.Default.RequestFlags =
+ MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED;
+
+ /*
+ * Get the Physical Address of the sense buffer.
+ * Save the user's Error Response buffer address and use that
+ * field to hold the sense buffer address.
+ * Clear the internal sense buffer, which will potentially hold
+ * the Completion Queue Entry on return, or 0 if no Entry.
+ * Build the PRPs and set direction bits.
+ * Send the request.
+ */
+ cm->nvme_error_response =
+ (uint64_t *)(uintptr_t)(((uint64_t)nvme_encap_request->
+ ErrorResponseBaseAddress.High << 32) |
+ (uint64_t)nvme_encap_request->
+ ErrorResponseBaseAddress.Low);
+ nvme_encap_request->ErrorResponseBaseAddress.High =
+ htole32((uint32_t)((uint64_t)cm->cm_sense_busaddr >> 32));
+ nvme_encap_request->ErrorResponseBaseAddress.Low =
+ htole32(cm->cm_sense_busaddr);
+ memset(cm->cm_sense, 0, NVME_ERROR_RESPONSE_SIZE);
+ mpr_build_nvme_prp(sc, cm, nvme_encap_request, cm->cm_data,
+ data->DataSize, data->DataOutSize);
+ }
+
/*
* Set up Sense buffer and SGL offset for IO passthru. SCSI IO request
* uses SCSI IO or Fast Path SCSI IO descriptor.
@@ -994,15 +1026,19 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO) {
cm->cm_desc.FastPathSCSIIO.RequestFlags =
MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
- cm->cm_desc.FastPathSCSIIO.DevHandle =
- scsi_io_req->DevHandle;
+ if (!sc->atomic_desc_capable) {
+ cm->cm_desc.FastPathSCSIIO.DevHandle =
+ scsi_io_req->DevHandle;
+ }
scsi_io_req->IoFlags |=
MPI25_SCSIIO_IOFLAGS_FAST_PATH;
} else {
cm->cm_desc.SCSIIO.RequestFlags =
MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
- cm->cm_desc.SCSIIO.DevHandle =
- scsi_io_req->DevHandle;
+ if (!sc->atomic_desc_capable) {
+ cm->cm_desc.SCSIIO.DevHandle =
+ scsi_io_req->DevHandle;
+ }
}
/*
@@ -1079,6 +1115,38 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
mpr_lock(sc);
}
}
+
+ /*
+ * Copy out the NVMe Error Reponse to user. The Error Response
+ * buffer is given by the user, but a sense buffer is used to
+ * get that data from the IOC. The user's
+ * ErrorResponseBaseAddress is saved in the
+ * 'nvme_error_response' field before the command because that
+ * field is set to a sense buffer. When the command is
+ * complete, the Error Response data from the IOC is copied to
+ * that user address after it is checked for validity.
+ * Also note that 'sense' buffers are not defined for
+ * NVMe commands. Sense terminalogy is only used here so that
+ * the same IOCTL structure and sense buffers can be used for
+ * NVMe.
+ */
+ if (function == MPI2_FUNCTION_NVME_ENCAPSULATED) {
+ if (cm->nvme_error_response == NULL) {
+ mpr_dprint(sc, MPR_INFO, "NVMe Error Response "
+ "buffer is NULL. Response data will not be "
+ "returned.\n");
+ mpr_unlock(sc);
+ goto RetFreeUnlocked;
+ }
+
+ nvme_error_reply =
+ (Mpi26NVMeEncapsulatedErrorReply_t *)cm->cm_reply;
+ sz = MIN(le32toh(nvme_error_reply->ErrorResponseCount),
+ NVME_ERROR_RESPONSE_SIZE);
+ mpr_unlock(sc);
+ copyout(cm->cm_sense, cm->nvme_error_response, sz);
+ mpr_lock(sc);
+ }
}
mpr_unlock(sc);
@@ -2068,7 +2136,7 @@ mpr_user_btdh(struct mpr_softc *sc, mpr_btdh_mapping_t *data)
return (EINVAL);
if (target > sc->max_devices) {
- mpr_dprint(sc, MPR_FAULT, "Target ID is out of range "
+ mpr_dprint(sc, MPR_XINFO, "Target ID is out of range "
"for Bus/Target to DevHandle mapping.");
return (EINVAL);
}
OpenPOWER on IntegriCloud