1 /* $OpenBSD: nvmevar.h,v 1.28 2021/08/29 12:02:52 kettenis Exp $ */ 2 3 /* 4 * Copyright (c) 2014 David Gwynne <dlg@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #define NVME_IO_Q 1 20 #define NVME_HIB_Q 2 21 #define NVME_MAXPHYS (128 * 1024) 22 23 struct nvme_dmamem { 24 bus_dmamap_t ndm_map; 25 bus_dma_segment_t ndm_seg; 26 size_t ndm_size; 27 caddr_t ndm_kva; 28 }; 29 #define NVME_DMA_MAP(_ndm) ((_ndm)->ndm_map) 30 #define NVME_DMA_LEN(_ndm) ((_ndm)->ndm_map->dm_segs[0].ds_len) 31 #define NVME_DMA_DVA(_ndm) ((u_int64_t)(_ndm)->ndm_map->dm_segs[0].ds_addr) 32 #define NVME_DMA_KVA(_ndm) ((void *)(_ndm)->ndm_kva) 33 34 struct nvme_softc; 35 struct nvme_queue; 36 37 struct nvme_ccb { 38 SIMPLEQ_ENTRY(nvme_ccb) ccb_entry; 39 40 bus_dmamap_t ccb_dmamap; 41 42 void *ccb_cookie; 43 void (*ccb_done)(struct nvme_softc *sc, 44 struct nvme_ccb *, struct nvme_cqe *); 45 46 bus_addr_t ccb_prpl_off; 47 u_int64_t ccb_prpl_dva; 48 u_int64_t *ccb_prpl; 49 50 u_int16_t ccb_id; 51 }; 52 SIMPLEQ_HEAD(nvme_ccb_list, nvme_ccb); 53 54 struct nvme_queue { 55 struct mutex q_sq_mtx; 56 struct mutex q_cq_mtx; 57 struct nvme_dmamem *q_sq_dmamem; 58 struct nvme_dmamem *q_cq_dmamem; 59 struct nvme_dmamem *q_nvmmu_dmamem; /* for aplns(4) */ 60 bus_size_t q_sqtdbl; /* submission queue tail doorbell */ 61 bus_size_t q_cqhdbl; /* completion queue head doorbell */ 62 u_int16_t q_id; 63 u_int32_t q_entries; 64 u_int32_t q_sq_tail; 65 u_int32_t q_cq_head; 66 u_int16_t q_cq_phase; 67 }; 68 69 struct nvme_namespace { 70 struct nvm_identify_namespace *ident; 71 }; 72 73 struct nvme_ops { 74 void (*op_enable)(struct nvme_softc *); 75 76 int (*op_q_alloc)(struct nvme_softc *, 77 struct nvme_queue *); 78 void (*op_q_free)(struct nvme_softc *, 79 struct nvme_queue *); 80 81 uint32_t (*op_sq_enter)(struct nvme_softc *, 82 struct nvme_queue *, struct nvme_ccb *); 83 void (*op_sq_leave)(struct nvme_softc *, 84 struct nvme_queue *, struct nvme_ccb *); 85 uint32_t (*op_sq_enter_locked)(struct nvme_softc *, 86 struct nvme_queue *, struct nvme_ccb *); 87 void (*op_sq_leave_locked)(struct nvme_softc *, 88 struct nvme_queue *, struct nvme_ccb *); 89 90 void (*op_cq_done)(struct nvme_softc *, 91 struct nvme_queue *, struct nvme_ccb *); 92 }; 93 94 struct nvme_softc { 95 struct device sc_dev; 96 97 const struct nvme_ops *sc_ops; 98 u_int sc_openings; 99 100 bus_space_tag_t sc_iot; 101 bus_space_handle_t sc_ioh; 102 bus_size_t sc_ios; 103 bus_dma_tag_t sc_dmat; 104 105 void *sc_ih; 106 107 u_int sc_rdy_to; 108 size_t sc_mps; 109 size_t sc_mdts; 110 u_int sc_max_prpl; 111 u_int sc_dstrd; 112 113 struct nvm_identify_controller 114 sc_identify; 115 116 u_int sc_nn; 117 struct nvme_namespace *sc_namespaces; 118 119 struct nvme_queue *sc_admin_q; 120 struct nvme_queue *sc_q; 121 struct nvme_queue *sc_hib_q; 122 123 struct mutex sc_ccb_mtx; 124 struct nvme_ccb *sc_ccbs; 125 struct nvme_ccb_list sc_ccb_list; 126 struct nvme_dmamem *sc_ccb_prpls; 127 struct scsi_iopool sc_iopool; 128 }; 129 130 #define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname) 131 132 int nvme_attach(struct nvme_softc *); 133 int nvme_activate(struct nvme_softc *, int); 134 int nvme_intr(void *); 135 int nvme_intr_intx(void *); 136 137 #define nvme_read4(_s, _r) \ 138 bus_space_read_4((_s)->sc_iot, (_s)->sc_ioh, (_r)) 139 #define nvme_write4(_s, _r, _v) \ 140 bus_space_write_4((_s)->sc_iot, (_s)->sc_ioh, (_r), (_v)) 141 142 u_int64_t 143 nvme_read8(struct nvme_softc *, bus_size_t); 144 void nvme_write8(struct nvme_softc *, bus_size_t, u_int64_t); 145 146 #define nvme_barrier(_s, _r, _l, _f) \ 147 bus_space_barrier((_s)->sc_iot, (_s)->sc_ioh, (_r), (_l), (_f)) 148 149 struct nvme_dmamem * 150 nvme_dmamem_alloc(struct nvme_softc *, size_t); 151 void nvme_dmamem_free(struct nvme_softc *, struct nvme_dmamem *); 152 void nvme_dmamem_sync(struct nvme_softc *, struct nvme_dmamem *, int); 153