diff options
Diffstat (limited to 'sys/dev/mpr/mprvar.h')
-rw-r--r-- | sys/dev/mpr/mprvar.h | 151 |
1 files changed, 131 insertions, 20 deletions
diff --git a/sys/dev/mpr/mprvar.h b/sys/dev/mpr/mprvar.h index 7cb71d6..9ef0c76 100644 --- a/sys/dev/mpr/mprvar.h +++ b/sys/dev/mpr/mprvar.h @@ -33,7 +33,7 @@ #ifndef _MPRVAR_H #define _MPRVAR_H -#define MPR_DRIVER_VERSION "15.01.00.00-fbsd" +#define MPR_DRIVER_VERSION "15.02.00.00-fbsd" #define MPR_DB_MAX_WAIT 2500 @@ -50,6 +50,17 @@ #define MPR_DEFAULT_CHAIN_SEG_SIZE 8 #define MPR_MAX_CHAIN_ELEMENT_SIZE 16 +/* + * PCIe NVMe Specific defines + */ +//SLM-for now just use the same value as a SAS disk +#define NVME_QDEPTH MPR_REQ_FRAMES +#define PRP_ENTRY_SIZE 8 +#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 HOST_PAGE_SIZE_4K 12 + #define MPR_FUNCTRACE(sc) \ mpr_dprint((sc), MPR_TRACE, "%s\n", __func__) @@ -184,6 +195,12 @@ struct mpr_chain { uint64_t chain_busaddr; }; +struct mpr_prp_page { + TAILQ_ENTRY(mpr_prp_page) prp_page_link; + uint64_t *prp_page; + uint64_t prp_page_busaddr; +}; + /* * This needs to be at least 2 to support SMP passthrough. */ @@ -229,9 +246,11 @@ struct mpr_command { #define MPR_CM_STATE_TIMEDOUT 2 bus_dmamap_t cm_dmamap; struct scsi_sense_data *cm_sense; + uint64_t *nvme_error_response; TAILQ_HEAD(, mpr_chain) cm_chain_list; + TAILQ_HEAD(, mpr_prp_page) cm_prp_page_list; uint32_t cm_req_busaddr; - uint32_t cm_sense_busaddr; + bus_addr_t cm_sense_busaddr; struct callout cm_callout; }; @@ -257,26 +276,35 @@ struct mpr_softc { #define MPR_FLAGS_SHUTDOWN (1 << 3) #define MPR_FLAGS_DIAGRESET (1 << 4) #define MPR_FLAGS_ATTACH_DONE (1 << 5) +#define MPR_FLAGS_GEN35_IOC (1 << 6) u_int mpr_debug; u_int disable_msix; u_int disable_msi; + u_int atomic_desc_capable; int tm_cmds_active; int io_cmds_active; int io_cmds_highwater; int chain_free; int max_chains; int max_io_pages; + u_int maxio; int chain_free_lowwater; uint32_t chain_frame_size; uint16_t chain_seg_size; + int prp_buffer_size; + int prp_pages_free; + int prp_pages_free_lowwater; u_int enable_ssu; int spinup_wait_time; + int use_phynum; uint64_t chain_alloc_fail; + uint64_t prp_page_alloc_fail; struct sysctl_ctx_list sysctl_ctx; struct sysctl_oid *sysctl_tree; char fw_version[16]; struct mpr_command *commands; struct mpr_chain *chains; + struct mpr_prp_page *prps; struct callout periodic; struct mprsas_softc *sassc; @@ -284,6 +312,7 @@ struct mpr_softc { TAILQ_HEAD(, mpr_command) req_list; TAILQ_HEAD(, mpr_command) high_priority_req_list; TAILQ_HEAD(, mpr_chain) chain_list; + TAILQ_HEAD(, mpr_prp_page) prp_page_list; TAILQ_HEAD(, mpr_command) tm_list; int replypostindex; int replyfreeindex; @@ -332,6 +361,11 @@ struct mpr_softc { bus_dma_tag_t chain_dmat; bus_dmamap_t chain_map; + uint8_t *prp_pages; + bus_addr_t prp_page_busaddr; + bus_dma_tag_t prp_page_dmat; + bus_dmamap_t prp_page_map; + MPI2_REPLY_DESCRIPTORS_UNION *post_queue; bus_addr_t post_busaddr; uint32_t *free_queue; @@ -470,10 +504,33 @@ mpr_free_chain(struct mpr_softc *sc, struct mpr_chain *chain) TAILQ_INSERT_TAIL(&sc->chain_list, chain, chain_link); } +static __inline struct mpr_prp_page * +mpr_alloc_prp_page(struct mpr_softc *sc) +{ + struct mpr_prp_page *prp_page; + + if ((prp_page = TAILQ_FIRST(&sc->prp_page_list)) != NULL) { + TAILQ_REMOVE(&sc->prp_page_list, prp_page, prp_page_link); + sc->prp_pages_free--; + if (sc->prp_pages_free < sc->prp_pages_free_lowwater) + sc->prp_pages_free_lowwater = sc->prp_pages_free; + } else + sc->prp_page_alloc_fail++; + return (prp_page); +} + +static __inline void +mpr_free_prp_page(struct mpr_softc *sc, struct mpr_prp_page *prp_page) +{ + sc->prp_pages_free++; + TAILQ_INSERT_TAIL(&sc->prp_page_list, prp_page, prp_page_link); +} + static __inline void mpr_free_command(struct mpr_softc *sc, struct mpr_command *cm) { struct mpr_chain *chain, *chain_temp; + struct mpr_prp_page *prp_page, *prp_page_temp; if (cm->cm_reply != NULL) mpr_free_reply(sc, cm->cm_reply_data); @@ -496,6 +553,11 @@ mpr_free_command(struct mpr_softc *sc, struct mpr_command *cm) TAILQ_REMOVE(&cm->cm_chain_list, chain, chain_link); mpr_free_chain(sc, chain); } + TAILQ_FOREACH_SAFE(prp_page, &cm->cm_prp_page_list, prp_page_link, + prp_page_temp) { + TAILQ_REMOVE(&cm->cm_prp_page_list, prp_page, prp_page_link); + mpr_free_prp_page(sc, prp_page); + } TAILQ_INSERT_TAIL(&sc->req_list, cm, cm_link); } @@ -509,7 +571,8 @@ mpr_alloc_command(struct mpr_softc *sc) return (NULL); TAILQ_REMOVE(&sc->req_list, cm, cm_link); - KASSERT(cm->cm_state == MPR_CM_STATE_FREE, ("mpr: Allocating busy command\n")); + KASSERT(cm->cm_state == MPR_CM_STATE_FREE, ("mpr: Allocating busy " + "command\n")); cm->cm_state = MPR_CM_STATE_BUSY; return (cm); } @@ -546,7 +609,8 @@ mpr_alloc_high_priority_command(struct mpr_softc *sc) return (NULL); TAILQ_REMOVE(&sc->high_priority_req_list, cm, cm_link); - KASSERT(cm->cm_state == MPR_CM_STATE_FREE, ("mpr: Allocating busy command\n")); + KASSERT(cm->cm_state == MPR_CM_STATE_FREE, ("mpr: Allocating busy " + "command\n")); cm->cm_state = MPR_CM_STATE_BUSY; return (cm); } @@ -583,6 +647,9 @@ mpr_unlock(struct mpr_softc *sc) #define mpr_printf(sc, args...) \ device_printf((sc)->mpr_dev, ##args) +#define mpr_print_field(sc, msg, args...) \ + printf("\t" msg, ##args) + #define mpr_vprintf(sc, args...) \ do { \ if (bootverbose) \ @@ -595,25 +662,13 @@ do { \ device_printf((sc)->mpr_dev, msg, ##args); \ } while (0) -#define mpr_dprint_field(sc, level, msg, args...) \ -do { \ - if ((sc)->mpr_debug & (level)) \ - printf("\t" msg, ##args); \ -} while (0) - #define MPR_PRINTFIELD_START(sc, tag...) \ - mpr_dprint((sc), MPR_INFO, ##tag); \ - mpr_dprint_field((sc), MPR_INFO, ":\n") + mpr_printf((sc), ##tag); \ + mpr_print_field((sc), ":\n") #define MPR_PRINTFIELD_END(sc, tag) \ - mpr_dprint((sc), MPR_INFO, tag "\n") + mpr_printf((sc), tag "\n") #define MPR_PRINTFIELD(sc, facts, attr, fmt) \ - mpr_dprint_field((sc), MPR_INFO, #attr ": " #fmt "\n", (facts)->attr) - -#define MPR_EVENTFIELD_START(sc, tag...) \ - mpr_dprint((sc), MPR_EVENT, ##tag); \ - mpr_dprint_field((sc), MPR_EVENT, ":\n") -#define MPR_EVENTFIELD(sc, facts, attr, fmt) \ - mpr_dprint_field((sc), MPR_EVENT, #attr ": " #fmt "\n", (facts)->attr) + mpr_print_field((sc), #attr ": " #fmt "\n", (facts)->attr) static __inline void mpr_from_u64(uint64_t data, U64 *mpr) @@ -661,6 +716,9 @@ int mpr_register_events(struct mpr_softc *, uint8_t *, mpr_evt_callback_t *, int mpr_restart(struct mpr_softc *); int mpr_update_events(struct mpr_softc *, struct mpr_event_handle *, uint8_t *); int mpr_deregister_events(struct mpr_softc *, struct mpr_event_handle *); +void mpr_build_nvme_prp(struct mpr_softc *sc, struct mpr_command *cm, + Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request, void *data, + uint32_t data_in_sz, uint32_t data_out_sz); int mpr_push_sge(struct mpr_command *, MPI2_SGE_SIMPLE64 *, size_t, int); int mpr_push_ieee_sge(struct mpr_command *, void *, int); int mpr_add_dmaseg(struct mpr_command *, vm_paddr_t, size_t, u_int, int); @@ -690,6 +748,10 @@ int mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page); int mpr_config_get_sas_device_pg0(struct mpr_softc *, Mpi2ConfigReply_t *, Mpi2SasDevicePage0_t *, u32 , u16 ); +int mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t + *mpi_reply, Mpi26PCIeDevicePage0_t *config_page, u32 form, u16 handle); +int mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t + *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, u32 form, u16 handle); int mpr_config_get_dpm_pg0(struct mpr_softc *, Mpi2ConfigReply_t *, Mpi2DriverMappingPage0_t *, u16 ); int mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, @@ -710,6 +772,8 @@ void mpr_base_static_config_pages(struct mpr_softc *sc); int mpr_mapping_initialize(struct mpr_softc *); void mpr_mapping_topology_change_event(struct mpr_softc *, Mpi2EventDataSasTopologyChangeList_t *); +void mpr_mapping_pcie_topology_change_event(struct mpr_softc *sc, + Mpi26EventDataPCIeTopologyChangeList_t *event_data); int mpr_mapping_is_reinit_required(struct mpr_softc *); void mpr_mapping_free_memory(struct mpr_softc *sc); int mpr_config_set_dpm_pg0(struct mpr_softc *, Mpi2ConfigReply_t *, @@ -777,5 +841,52 @@ SYSCTL_DECL(_hw_mpr); #define CAM_PRIORITY_NORMAL CAM_PRIORITY_NONE #endif +/* Definitions for SCSI unmap translation to NVMe DSM command */ + +/* UNMAP block descriptor structure */ +struct unmap_blk_desc { + uint64_t slba; + uint32_t nlb; + uint32_t resv; +}; + +/* UNMAP command's data */ +struct unmap_parm_list { + uint16_t unmap_data_len; + uint16_t unmap_blk_desc_data_len; + uint32_t resv; + struct unmap_blk_desc desc[0]; +}; + +/* SCSI ADDITIONAL SENSE Codes */ +#define FIXED_SENSE_DATA 0x70 +#define SCSI_ASC_NO_SENSE 0x00 +#define SCSI_ASC_PERIPHERAL_DEV_WRITE_FAULT 0x03 +#define SCSI_ASC_LUN_NOT_READY 0x04 +#define SCSI_ASC_WARNING 0x0B +#define SCSI_ASC_LOG_BLOCK_GUARD_CHECK_FAILED 0x10 +#define SCSI_ASC_LOG_BLOCK_APPTAG_CHECK_FAILED 0x10 +#define SCSI_ASC_LOG_BLOCK_REFTAG_CHECK_FAILED 0x10 +#define SCSI_ASC_UNRECOVERED_READ_ERROR 0x11 +#define SCSI_ASC_MISCOMPARE_DURING_VERIFY 0x1D +#define SCSI_ASC_ACCESS_DENIED_INVALID_LUN_ID 0x20 +#define SCSI_ASC_ILLEGAL_COMMAND 0x20 +#define SCSI_ASC_ILLEGAL_BLOCK 0x21 +#define SCSI_ASC_INVALID_CDB 0x24 +#define SCSI_ASC_INVALID_LUN 0x25 +#define SCSI_ASC_INVALID_PARAMETER 0x26 +#define SCSI_ASC_FORMAT_COMMAND_FAILED 0x31 +#define SCSI_ASC_INTERNAL_TARGET_FAILURE 0x44 + +/* SCSI ADDITIONAL SENSE Code Qualifiers */ +#define SCSI_ASCQ_CAUSE_NOT_REPORTABLE 0x00 +#define SCSI_ASCQ_FORMAT_COMMAND_FAILED 0x01 +#define SCSI_ASCQ_LOG_BLOCK_GUARD_CHECK_FAILED 0x01 +#define SCSI_ASCQ_LOG_BLOCK_APPTAG_CHECK_FAILED 0x02 +#define SCSI_ASCQ_LOG_BLOCK_REFTAG_CHECK_FAILED 0x03 +#define SCSI_ASCQ_FORMAT_IN_PROGRESS 0x04 +#define SCSI_ASCQ_POWER_LOSS_EXPECTED 0x08 +#define SCSI_ASCQ_INVALID_LUN_ID 0x09 + #endif |