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 @@
#include "mpi/mpi2_raid.h"
#include "mpi/mpi2_tool.h"
#include "mpi/mpi2_sas.h"
#include "mpi/mpi2_pci.h"
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
......@@ -115,6 +116,7 @@
#define MPT3SAS_KDUMP_SCSI_IO_DEPTH 200
#define MPT3SAS_RAID_MAX_SECTORS 8192
#define MPT3SAS_HOST_PAGE_SIZE_4K 12
#define MPT_NAME_LENGTH 32 /* generic length of strings */
#define MPT_STRING_LENGTH 64
......@@ -132,6 +134,15 @@
#define MAX_CHAIN_ELEMT_SZ 16
#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
*/
......@@ -736,6 +747,16 @@ enum reset_type {
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
* @chain_buffer: chain buffer
......@@ -762,6 +783,7 @@ struct scsiio_tracker {
struct scsi_cmnd *scmd;
u8 cb_idx;
u8 direct_io;
struct pcie_sg_list pcie_sg_list;
struct list_head chain_list;
struct list_head tracker_list;
u16 msix_io;
......@@ -835,13 +857,19 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
/* SAS3.0 support */
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,
dma_addr_t data_out_dma, size_t data_out_sz,
dma_addr_t data_in_dma, size_t data_in_sz);
typedef void (*MPT_BUILD_ZERO_LEN_SGE)(struct MPT3SAS_ADAPTER *ioc,
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*/
typedef void (*PUT_SMID_IO_FP_HIP) (struct MPT3SAS_ADAPTER *ioc, u16 smid,
u16 funcdep);
......@@ -884,6 +912,7 @@ struct mpt3sas_facts {
u16 MaxDevHandle;
u16 MaxPersistentEntries;
u16 MinDevHandle;
u8 CurrentHostPageSize;
};
struct mpt3sas_port_facts {
......@@ -1223,6 +1252,11 @@ struct MPT3SAS_ADAPTER {
int pending_io_count;
wait_queue_head_t reset_wq;
/* PCIe SGL */
struct dma_pool *pcie_sgl_dma_pool;
/* Host Page Size */
u32 page_size;
/* chain */
struct chain_tracker *chain_lookup;
struct list_head free_chain_list;
......@@ -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);
__le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc,
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);
/* hi-priority queue */
......@@ -1570,7 +1605,7 @@ void
mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io);
void
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);
/* NCQ Prio Handling Check */
......
......@@ -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);
ioc->ctl_cmds.status &= ~MPT3_CMD_PENDING;
complete(&ioc->ctl_cmds.done);
......
......@@ -4255,7 +4255,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
*/
static void
_scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
Mpi2SCSIIORequest_t *mpi_request)
Mpi25SCSIIORequest_t *mpi_request)
{
u16 eedp_flags;
unsigned char prot_op = scsi_get_prot_op(scmd);
......@@ -4358,7 +4358,8 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
struct _raid_device *raid_device;
struct request *rq = scmd->request;
int class;
Mpi2SCSIIORequest_t *mpi_request;
Mpi25SCSIIORequest_t *mpi_request;
struct _pcie_device *pcie_device = NULL;
u32 mpi_control;
u16 smid;
u16 handle;
......@@ -4446,7 +4447,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
goto out;
}
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);
if (scmd->cmd_len == 32)
......@@ -4465,13 +4466,14 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
mpi_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
mpi_request->SenseBufferLowAddress =
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 *)
mpi_request->LUN);
memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
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);
goto out;
}
......@@ -4924,7 +4926,7 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle)
static u8
_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;
struct scsi_cmnd *scmd;
u16 ioc_status;
......
......@@ -299,7 +299,7 @@ mpt3sas_scsi_direct_io_set(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
*/
void
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)
{
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