Author: kadesai Date: Fri May 13 12:12:09 2016 New Revision: 299668 URL: https://svnweb.freebsd.org/changeset/base/299668
Log: 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.sax...@broadcom.com> Reviewed by: Kashyap Desai <kashyap.de...@broadcom.com> MFC after: 3 days Sponsored by: AVAGO Technologies Modified: head/sys/dev/mrsas/mrsas.c head/sys/dev/mrsas/mrsas.h head/sys/dev/mrsas/mrsas_cam.c Modified: head/sys/dev/mrsas/mrsas.c ============================================================================== --- head/sys/dev/mrsas/mrsas.c Fri May 13 12:05:02 2016 (r299667) +++ head/sys/dev/mrsas/mrsas.c Fri May 13 12:12:09 2016 (r299668) @@ -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 *s 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 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 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); } Modified: head/sys/dev/mrsas/mrsas.h ============================================================================== --- head/sys/dev/mrsas/mrsas.h Fri May 13 12:05:02 2016 (r299667) +++ head/sys/dev/mrsas/mrsas.h Fri May 13 12:12:09 2016 (r299668) @@ -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; Modified: head/sys/dev/mrsas/mrsas_cam.c ============================================================================== --- head/sys/dev/mrsas/mrsas_cam.c Fri May 13 12:05:02 2016 (r299667) +++ head/sys/dev/mrsas/mrsas_cam.c Fri May 13 12:12:09 2016 (r299668) @@ -344,7 +344,7 @@ mrsas_action(struct cam_sim *sim, union 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, st 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, st 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, st #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 * 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_soft 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 * 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); _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"