summaryrefslogtreecommitdiffstats
path: root/sys/dev/mpr/mprvar.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/mpr/mprvar.h')
-rw-r--r--sys/dev/mpr/mprvar.h151
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
OpenPOWER on IntegriCloud