Commit 016d5c35 authored by Suganath Prabu Subramani's avatar Suganath Prabu Subramani Committed by Martin K. Petersen

scsi: mpt3sas: SGL to PRP Translation for I/Os to NVMe devices

* Added support for translating the SGLs associated with incoming
commands either to IEE SGL or NVMe PRPs for NVMe devices.

* The hardware translation of IEEE SGL to NVMe PRPs has limitations
and if a command cannot be translated by hardware then it will go to
firmware and the firmware needs to translate it. This will have a
performance impact. To avoid that, the driver proactively checks
whether the translation will be done in hardware or not. If not, then
driver translates.

[mkp: clarified commit message]
Signed-off-by: default avatarChaitra P B <chaitra.basappa@broadcom.com>
Signed-off-by: default avatarSuganath Prabu S <suganath-prabu.subramani@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d88e1eab
This diff is collapsed.
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "mpi/mpi2_raid.h" #include "mpi/mpi2_raid.h"
#include "mpi/mpi2_tool.h" #include "mpi/mpi2_tool.h"
#include "mpi/mpi2_sas.h" #include "mpi/mpi2_sas.h"
#include "mpi/mpi2_pci.h"
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
...@@ -115,6 +116,7 @@ ...@@ -115,6 +116,7 @@
#define MPT3SAS_KDUMP_SCSI_IO_DEPTH 200 #define MPT3SAS_KDUMP_SCSI_IO_DEPTH 200
#define MPT3SAS_RAID_MAX_SECTORS 8192 #define MPT3SAS_RAID_MAX_SECTORS 8192
#define MPT3SAS_HOST_PAGE_SIZE_4K 12
#define MPT_NAME_LENGTH 32 /* generic length of strings */ #define MPT_NAME_LENGTH 32 /* generic length of strings */
#define MPT_STRING_LENGTH 64 #define MPT_STRING_LENGTH 64
...@@ -132,6 +134,15 @@ ...@@ -132,6 +134,15 @@
#define MAX_CHAIN_ELEMT_SZ 16 #define MAX_CHAIN_ELEMT_SZ 16
#define DEFAULT_NUM_FWCHAIN_ELEMTS 8 #define DEFAULT_NUM_FWCHAIN_ELEMTS 8
/*
* NVMe defines
*/
#define NVME_PRP_SIZE 8 /* PRP size */
#define NVME_CMD_PRP1_OFFSET 24 /* PRP1 offset in NVMe cmd */
#define NVME_CMD_PRP2_OFFSET 32 /* PRP2 offset in NVMe cmd */
#define NVME_ERROR_RESPONSE_SIZE 16 /* Max NVME Error Response */
#define NVME_PRP_PAGE_SIZE 4096 /* Page size */
/* /*
* reset phases * reset phases
*/ */
...@@ -736,6 +747,16 @@ enum reset_type { ...@@ -736,6 +747,16 @@ enum reset_type {
SOFT_RESET, SOFT_RESET,
}; };
/**
* struct pcie_sg_list - PCIe SGL buffer (contiguous per I/O)
* @pcie_sgl: PCIe native SGL for NVMe devices
* @pcie_sgl_dma: physical address
*/
struct pcie_sg_list {
void *pcie_sgl;
dma_addr_t pcie_sgl_dma;
};
/** /**
* struct chain_tracker - firmware chain tracker * struct chain_tracker - firmware chain tracker
* @chain_buffer: chain buffer * @chain_buffer: chain buffer
...@@ -762,6 +783,7 @@ struct scsiio_tracker { ...@@ -762,6 +783,7 @@ struct scsiio_tracker {
struct scsi_cmnd *scmd; struct scsi_cmnd *scmd;
u8 cb_idx; u8 cb_idx;
u8 direct_io; u8 direct_io;
struct pcie_sg_list pcie_sg_list;
struct list_head chain_list; struct list_head chain_list;
struct list_head tracker_list; struct list_head tracker_list;
u16 msix_io; u16 msix_io;
...@@ -835,13 +857,19 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); ...@@ -835,13 +857,19 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
/* SAS3.0 support */ /* SAS3.0 support */
typedef int (*MPT_BUILD_SG_SCMD)(struct MPT3SAS_ADAPTER *ioc, typedef int (*MPT_BUILD_SG_SCMD)(struct MPT3SAS_ADAPTER *ioc,
struct scsi_cmnd *scmd, u16 smid); struct scsi_cmnd *scmd, u16 smid, struct _pcie_device *pcie_device);
typedef void (*MPT_BUILD_SG)(struct MPT3SAS_ADAPTER *ioc, void *psge, typedef void (*MPT_BUILD_SG)(struct MPT3SAS_ADAPTER *ioc, void *psge,
dma_addr_t data_out_dma, size_t data_out_sz, dma_addr_t data_out_dma, size_t data_out_sz,
dma_addr_t data_in_dma, size_t data_in_sz); dma_addr_t data_in_dma, size_t data_in_sz);
typedef void (*MPT_BUILD_ZERO_LEN_SGE)(struct MPT3SAS_ADAPTER *ioc, typedef void (*MPT_BUILD_ZERO_LEN_SGE)(struct MPT3SAS_ADAPTER *ioc,
void *paddr); void *paddr);
/* SAS3.5 support */
typedef void (*NVME_BUILD_PRP)(struct MPT3SAS_ADAPTER *ioc, u16 smid,
Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request,
dma_addr_t data_out_dma, size_t data_out_sz, dma_addr_t data_in_dma,
size_t data_in_sz);
/* To support atomic and non atomic descriptors*/ /* To support atomic and non atomic descriptors*/
typedef void (*PUT_SMID_IO_FP_HIP) (struct MPT3SAS_ADAPTER *ioc, u16 smid, typedef void (*PUT_SMID_IO_FP_HIP) (struct MPT3SAS_ADAPTER *ioc, u16 smid,
u16 funcdep); u16 funcdep);
...@@ -884,6 +912,7 @@ struct mpt3sas_facts { ...@@ -884,6 +912,7 @@ struct mpt3sas_facts {
u16 MaxDevHandle; u16 MaxDevHandle;
u16 MaxPersistentEntries; u16 MaxPersistentEntries;
u16 MinDevHandle; u16 MinDevHandle;
u8 CurrentHostPageSize;
}; };
struct mpt3sas_port_facts { struct mpt3sas_port_facts {
...@@ -1223,6 +1252,11 @@ struct MPT3SAS_ADAPTER { ...@@ -1223,6 +1252,11 @@ struct MPT3SAS_ADAPTER {
int pending_io_count; int pending_io_count;
wait_queue_head_t reset_wq; wait_queue_head_t reset_wq;
/* PCIe SGL */
struct dma_pool *pcie_sgl_dma_pool;
/* Host Page Size */
u32 page_size;
/* chain */ /* chain */
struct chain_tracker *chain_lookup; struct chain_tracker *chain_lookup;
struct list_head free_chain_list; struct list_head free_chain_list;
...@@ -1356,7 +1390,8 @@ void *mpt3sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid); ...@@ -1356,7 +1390,8 @@ void *mpt3sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid);
void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid); void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid);
__le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc, __le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc,
u16 smid); u16 smid);
void *mpt3sas_base_get_pcie_sgl(struct MPT3SAS_ADAPTER *ioc, u16 smid);
void *mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid);
void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc); void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc);
/* hi-priority queue */ /* hi-priority queue */
...@@ -1570,7 +1605,7 @@ void ...@@ -1570,7 +1605,7 @@ void
mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io); mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io);
void void
mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, struct _raid_device *raid_device, Mpi25SCSIIORequest_t *mpi_request,
u16 smid); u16 smid);
/* NCQ Prio Handling Check */ /* NCQ Prio Handling Check */
......
...@@ -299,6 +299,7 @@ mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, ...@@ -299,6 +299,7 @@ mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
} }
} }
} }
_ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply); _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);
ioc->ctl_cmds.status &= ~MPT3_CMD_PENDING; ioc->ctl_cmds.status &= ~MPT3_CMD_PENDING;
complete(&ioc->ctl_cmds.done); complete(&ioc->ctl_cmds.done);
......
...@@ -4255,7 +4255,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc) ...@@ -4255,7 +4255,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
*/ */
static void static void
_scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, _scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
Mpi2SCSIIORequest_t *mpi_request) Mpi25SCSIIORequest_t *mpi_request)
{ {
u16 eedp_flags; u16 eedp_flags;
unsigned char prot_op = scsi_get_prot_op(scmd); unsigned char prot_op = scsi_get_prot_op(scmd);
...@@ -4358,7 +4358,8 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) ...@@ -4358,7 +4358,8 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
struct _raid_device *raid_device; struct _raid_device *raid_device;
struct request *rq = scmd->request; struct request *rq = scmd->request;
int class; int class;
Mpi2SCSIIORequest_t *mpi_request; Mpi25SCSIIORequest_t *mpi_request;
struct _pcie_device *pcie_device = NULL;
u32 mpi_control; u32 mpi_control;
u16 smid; u16 smid;
u16 handle; u16 handle;
...@@ -4446,7 +4447,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) ...@@ -4446,7 +4447,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
goto out; goto out;
} }
mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t)); memset(mpi_request, 0, ioc->request_sz);
_scsih_setup_eedp(ioc, scmd, mpi_request); _scsih_setup_eedp(ioc, scmd, mpi_request);
if (scmd->cmd_len == 32) if (scmd->cmd_len == 32)
...@@ -4465,13 +4466,14 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) ...@@ -4465,13 +4466,14 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
mpi_request->SenseBufferLowAddress = mpi_request->SenseBufferLowAddress =
mpt3sas_base_get_sense_buffer_dma(ioc, smid); mpt3sas_base_get_sense_buffer_dma(ioc, smid);
mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4; mpi_request->SGLOffset0 = offsetof(Mpi25SCSIIORequest_t, SGL) / 4;
int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *) int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *)
mpi_request->LUN); mpi_request->LUN);
memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
if (mpi_request->DataLength) { if (mpi_request->DataLength) {
if (ioc->build_sg_scmd(ioc, scmd, smid)) { pcie_device = sas_target_priv_data->pcie_dev;
if (ioc->build_sg_scmd(ioc, scmd, smid, pcie_device)) {
mpt3sas_base_free_smid(ioc, smid); mpt3sas_base_free_smid(ioc, smid);
goto out; goto out;
} }
...@@ -4924,7 +4926,7 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -4924,7 +4926,7 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle)
static u8 static u8
_scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
{ {
Mpi2SCSIIORequest_t *mpi_request; Mpi25SCSIIORequest_t *mpi_request;
Mpi2SCSIIOReply_t *mpi_reply; Mpi2SCSIIOReply_t *mpi_reply;
struct scsi_cmnd *scmd; struct scsi_cmnd *scmd;
u16 ioc_status; u16 ioc_status;
......
...@@ -299,7 +299,7 @@ mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io) ...@@ -299,7 +299,7 @@ mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
*/ */
void void
mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, struct _raid_device *raid_device, Mpi25SCSIIORequest_t *mpi_request,
u16 smid) u16 smid)
{ {
sector_t v_lba, p_lba, stripe_off, column, io_size; sector_t v_lba, p_lba, stripe_off, column, io_size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment