This patch implements driver support for 1MB IO size.

NOTE:
The FreeBSD system currently restricts the MAX IO size to MAXPHYS which
in turn is 128KB. We tested the 1MB IO by converting the MAXPHYS to 1MB.

Following is the mail reference:
http://lists.freebsd.org/pipermail/freebsd-scsi/2015-January/006568.html

Submitted by:   Sumit Saxena <sumit.saxena@broadcom.com>
Reviewed by:    Kashyap Desai <Kashyap.Desai@broadcom.com>
MFC after:  3 days
Sponsored by:   AVAGO Technologies
This commit is contained in:
Kashyap D Desai 2016-05-13 12:12:09 +00:00
parent a688fcd018
commit 3a3fc6cba6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=299668
3 changed files with 73 additions and 22 deletions

View File

@ -1703,9 +1703,9 @@ mrsas_alloc_mem(struct mrsas_softc *sc)
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
MRSAS_MAX_IO_SIZE, /* maxsize */
MRSAS_MAX_SGL, /* nsegments */
MRSAS_MAX_IO_SIZE, /* maxsegsize */
MAXPHYS, /* maxsize */
sc->max_num_sge, /* nsegments */
MAXPHYS, /* maxsegsize */
0, /* flags */
NULL, NULL, /* lockfunc, lockarg */
&sc->mrsas_parent_tag /* tag */
@ -1902,9 +1902,9 @@ mrsas_alloc_mem(struct mrsas_softc *sc)
BUS_SPACE_MAXADDR,
BUS_SPACE_MAXADDR,
NULL, NULL,
MRSAS_MAX_IO_SIZE,
MRSAS_MAX_SGL,
MRSAS_MAX_IO_SIZE,
MAXPHYS,
sc->max_num_sge, /* nsegments */
MAXPHYS,
BUS_DMA_ALLOCNOW,
busdma_lock_mutex,
&sc->io_lock,
@ -2248,7 +2248,7 @@ int
mrsas_init_adapter(struct mrsas_softc *sc)
{
uint32_t status;
u_int32_t max_cmd;
u_int32_t max_cmd, scratch_pad_2;
int ret;
int i = 0;
@ -2267,13 +2267,33 @@ mrsas_init_adapter(struct mrsas_softc *sc)
sc->request_alloc_sz = sizeof(MRSAS_REQUEST_DESCRIPTOR_UNION) * max_cmd;
sc->reply_alloc_sz = sizeof(MPI2_REPLY_DESCRIPTORS_UNION) * (sc->reply_q_depth);
sc->io_frames_alloc_sz = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE + (MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * (max_cmd + 1));
sc->chain_frames_alloc_sz = 1024 * max_cmd;
scratch_pad_2 = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad_2));
/*
* If scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK is set,
* Firmware support extended IO chain frame which is 4 time more
* than legacy Firmware. Legacy Firmware - Frame size is (8 * 128) =
* 1K 1M IO Firmware - Frame size is (8 * 128 * 4) = 4K
*/
if (scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK)
sc->max_chain_frame_sz =
((scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_MASK) >> 5)
* MEGASAS_1MB_IO;
else
sc->max_chain_frame_sz =
((scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_MASK) >> 5)
* MEGASAS_256K_IO;
sc->chain_frames_alloc_sz = sc->max_chain_frame_sz * max_cmd;
sc->max_sge_in_main_msg = (MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
offsetof(MRSAS_RAID_SCSI_IO_REQUEST, SGL)) / 16;
sc->max_sge_in_chain = MRSAS_MAX_SZ_CHAIN_FRAME / sizeof(MPI2_SGE_IO_UNION);
sc->max_sge_in_chain = sc->max_chain_frame_sz / sizeof(MPI2_SGE_IO_UNION);
sc->max_num_sge = sc->max_sge_in_main_msg + sc->max_sge_in_chain - 2;
mrsas_dprint(sc, MRSAS_INFO, "Avago Debug: MAX sge 0x%X MAX chain frame size 0x%X \n",
sc->max_num_sge, sc->max_chain_frame_sz);
/* Used for pass thru MFI frame (DCMD) */
sc->chain_offset_mfi_pthru = offsetof(MRSAS_RAID_SCSI_IO_REQUEST, SGL) / 16;
@ -2411,6 +2431,8 @@ mrsas_ioc_init(struct mrsas_softc *sc)
init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb = 1;
init_frame->driver_operations.mfi_capabilities.support_max_255lds = 1;
init_frame->driver_operations.mfi_capabilities.security_protocol_cmds_fw = 1;
if (sc->max_chain_frame_sz > MEGASAS_CHAIN_FRAME_SZ_MIN)
init_frame->driver_operations.mfi_capabilities.support_ext_io_size = 1;
phys_addr = (bus_addr_t)sc->ioc_init_phys_mem + 1024;
init_frame->queue_info_new_phys_addr_lo = phys_addr;
init_frame->data_xfer_len = sizeof(Mpi2IOCInitRequest_t);
@ -2513,7 +2535,7 @@ mrsas_alloc_mpt_cmds(struct mrsas_softc *sc)
for (i = 0; i < max_cmd; i++) {
cmd = sc->mpt_cmd_list[i];
offset = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * i;
chain_offset = 1024 * i;
chain_offset = sc->max_chain_frame_sz * i;
sense_offset = MRSAS_SENSE_LEN * i;
memset(cmd, 0, sizeof(struct mrsas_mpt_cmd));
cmd->index = i + 1;
@ -3447,7 +3469,7 @@ mrsas_build_mptmfi_passthru(struct mrsas_softc *sc, struct mrsas_mfi_cmd *mfi_cm
mpi25_ieee_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT |
MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR;
mpi25_ieee_chain->Length = MRSAS_MAX_SZ_CHAIN_FRAME;
mpi25_ieee_chain->Length = sc->max_chain_frame_sz;
return (0);
}

View File

@ -166,7 +166,9 @@ typedef struct _RAID_CONTEXT {
u_int8_t numSGE;
u_int16_t configSeqNum;
u_int8_t spanArm;
u_int8_t resvd2[3];
u_int8_t priority; /* 0x1D MR_PRIORITY_RANGE */
u_int8_t numSGEExt; /* 0x1E 1M IO support */
u_int8_t resvd2; /* 0x1F */
} RAID_CONTEXT;
@ -1240,7 +1242,7 @@ enum MR_EVT_ARGS {
/*
* Thunderbolt (and later) Defines
*/
#define MRSAS_MAX_SZ_CHAIN_FRAME 1024
#define MEGASAS_CHAIN_FRAME_SZ_MIN 1024
#define MFI_FUSION_ENABLE_INTERRUPT_MASK (0x00000009)
#define MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE 256
#define MRSAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST 0xF0
@ -1318,10 +1320,13 @@ typedef enum _REGION_TYPE {
#define MRSAS_SCSI_MAX_CMDS 8
#define MRSAS_SCSI_MAX_CDB_LEN 16
#define MRSAS_SCSI_SENSE_BUFFERSIZE 96
#define MRSAS_MAX_SGL 70
#define MRSAS_MAX_IO_SIZE (256 * 1024)
#define MRSAS_INTERNAL_CMDS 32
#define MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK 0x400000
#define MEGASAS_MAX_CHAIN_SIZE_MASK 0x3E0
#define MEGASAS_256K_IO 128
#define MEGASAS_1MB_IO (MEGASAS_256K_IO * 4)
/* Request types */
#define MRSAS_REQ_TYPE_INTERNAL_CMD 0x0
#define MRSAS_REQ_TYPE_AEN_FETCH 0x1
@ -2023,7 +2028,9 @@ typedef union _MFI_CAPABILITIES {
u_int32_t support_ndrive_r1_lb:1;
u_int32_t support_core_affinity:1;
u_int32_t security_protocol_cmds_fw:1;
u_int32_t reserved:25;
u_int32_t support_ext_queue_depth:1;
u_int32_t support_ext_io_size:1;
u_int32_t reserved:23;
} mfi_capabilities;
u_int32_t reg;
} MFI_CAPABILITIES;
@ -2697,6 +2704,7 @@ struct mrsas_softc {
int msix_enable;
uint32_t msix_reg_offset[16];
uint8_t mask_interrupts;
uint16_t max_chain_frame_sz;
struct mrsas_mpt_cmd **mpt_cmd_list;
struct mrsas_mfi_cmd **mfi_cmd_list;
TAILQ_HEAD(, mrsas_mpt_cmd) mrsas_mpt_cmd_list_head;

View File

@ -344,7 +344,7 @@ mrsas_action(struct cam_sim *sim, union ccb *ccb)
else
ccb->cpi.max_target = MRSAS_MAX_LD_IDS - 1;
#if (__FreeBSD_version > 704000)
ccb->cpi.maxio = MRSAS_MAX_IO_SIZE;
ccb->cpi.maxio = sc->max_num_sge * MRSAS_PAGE_SIZE;
#endif
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
@ -462,7 +462,7 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
ccb_h->status = CAM_REQ_INVALID;
goto done;
case CAM_DATA_VADDR:
if (csio->dxfer_len > MRSAS_MAX_IO_SIZE) {
if (csio->dxfer_len > (sc->max_num_sge * MRSAS_PAGE_SIZE)) {
mrsas_release_mpt_cmd(cmd);
ccb_h->status = CAM_REQ_TOO_BIG;
goto done;
@ -472,6 +472,11 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
cmd->data = csio->data_ptr;
break;
case CAM_DATA_BIO:
if (csio->dxfer_len > (sc->max_num_sge * MRSAS_PAGE_SIZE)) {
mrsas_release_mpt_cmd(cmd);
ccb_h->status = CAM_REQ_TOO_BIG;
goto done;
}
cmd->length = csio->dxfer_len;
if (cmd->length)
cmd->data = csio->data_ptr;
@ -483,7 +488,7 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
#else
if (!(ccb_h->flags & CAM_DATA_PHYS)) { /* Virtual data address */
if (!(ccb_h->flags & CAM_SCATTER_VALID)) {
if (csio->dxfer_len > MRSAS_MAX_IO_SIZE) {
if (csio->dxfer_len > (sc->max_num_sge * MRSAS_PAGE_SIZE)) {
mrsas_release_mpt_cmd(cmd);
ccb_h->status = CAM_REQ_TOO_BIG;
goto done;
@ -730,12 +735,18 @@ mrsas_build_ldio_rw(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
io_request->DataLength = cmd->length;
if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
if (cmd->sge_count > MRSAS_MAX_SGL) {
if (cmd->sge_count > sc->max_num_sge) {
device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) exceeds"
"max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge);
return (FAIL);
}
/*
* numSGE store lower 8 bit of sge_count. numSGEExt store
* higher 8 bit of sge_count
*/
io_request->RaidContext.numSGE = cmd->sge_count;
io_request->RaidContext.numSGEExt = (uint8_t)(cmd->sge_count >> 8);
} else {
device_printf(sc->mrsas_dev, "Data map/load failed.\n");
return (FAIL);
@ -939,12 +950,17 @@ mrsas_build_ldio_nonrw(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
io_request->DataLength = cmd->length;
if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
if (cmd->sge_count > MRSAS_MAX_SGL) {
if (cmd->sge_count > sc->max_num_sge) {
device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) exceeds"
"max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge);
return (1);
}
/*
* numSGE store lower 8 bit of sge_count. numSGEExt store
* higher 8 bit of sge_count
*/
io_request->RaidContext.numSGE = cmd->sge_count;
io_request->RaidContext.numSGEExt = (uint8_t)(cmd->sge_count >> 8);
} else {
device_printf(sc->mrsas_dev, "Data map/load failed.\n");
return (1);
@ -1042,12 +1058,17 @@ mrsas_build_syspdio(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
io_request->DataLength = cmd->length;
if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
if (cmd->sge_count > MRSAS_MAX_SGL) {
if (cmd->sge_count > sc->max_num_sge) {
device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) exceeds"
"max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge);
return (1);
}
/*
* numSGE store lower 8 bit of sge_count. numSGEExt store
* higher 8 bit of sge_count
*/
io_request->RaidContext.numSGE = cmd->sge_count;
io_request->RaidContext.numSGEExt = (uint8_t)(cmd->sge_count >> 8);
} else {
device_printf(sc->mrsas_dev, "Data map/load failed.\n");
return (1);