1af4a03dfSAugustin Cavalier /*- 2af4a03dfSAugustin Cavalier * BSD LICENSE 3af4a03dfSAugustin Cavalier * 4af4a03dfSAugustin Cavalier * Copyright (c) Intel Corporation. All rights reserved. 5af4a03dfSAugustin Cavalier * Copyright (c) 2017, Western Digital Corporation or its affiliates. 6af4a03dfSAugustin Cavalier * 7af4a03dfSAugustin Cavalier * Redistribution and use in source and binary forms, with or without 8af4a03dfSAugustin Cavalier * modification, are permitted provided that the following conditions 9af4a03dfSAugustin Cavalier * are met: 10af4a03dfSAugustin Cavalier * 11af4a03dfSAugustin Cavalier * * Redistributions of source code must retain the above copyright 12af4a03dfSAugustin Cavalier * notice, this list of conditions and the following disclaimer. 13af4a03dfSAugustin Cavalier * * Redistributions in binary form must reproduce the above copyright 14af4a03dfSAugustin Cavalier * notice, this list of conditions and the following disclaimer in 15af4a03dfSAugustin Cavalier * the documentation and/or other materials provided with the 16af4a03dfSAugustin Cavalier * distribution. 17af4a03dfSAugustin Cavalier * * Neither the name of Intel Corporation nor the names of its 18af4a03dfSAugustin Cavalier * contributors may be used to endorse or promote products derived 19af4a03dfSAugustin Cavalier * from this software without specific prior written permission. 20af4a03dfSAugustin Cavalier * 21af4a03dfSAugustin Cavalier * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22af4a03dfSAugustin Cavalier * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23af4a03dfSAugustin Cavalier * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24af4a03dfSAugustin Cavalier * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25af4a03dfSAugustin Cavalier * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26af4a03dfSAugustin Cavalier * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27af4a03dfSAugustin Cavalier * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28af4a03dfSAugustin Cavalier * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29af4a03dfSAugustin Cavalier * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30af4a03dfSAugustin Cavalier * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31af4a03dfSAugustin Cavalier * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32af4a03dfSAugustin Cavalier */ 33af4a03dfSAugustin Cavalier 34af4a03dfSAugustin Cavalier #ifndef __NVME_INTERNAL_H__ 35af4a03dfSAugustin Cavalier #define __NVME_INTERNAL_H__ 36af4a03dfSAugustin Cavalier 37af4a03dfSAugustin Cavalier #include "nvme_common.h" 38af4a03dfSAugustin Cavalier #include "nvme_pci.h" 39af4a03dfSAugustin Cavalier #include "nvme_intel.h" 40af4a03dfSAugustin Cavalier #include "nvme_mem.h" 41af4a03dfSAugustin Cavalier 42af4a03dfSAugustin Cavalier #ifndef __HAIKU__ 43af4a03dfSAugustin Cavalier #include <pthread.h> 44af4a03dfSAugustin Cavalier #include <sys/user.h> /* PAGE_SIZE */ 45af4a03dfSAugustin Cavalier #else 46af4a03dfSAugustin Cavalier #include "nvme_platform.h" 47af4a03dfSAugustin Cavalier #endif 48af4a03dfSAugustin Cavalier 49af4a03dfSAugustin Cavalier /* 50af4a03dfSAugustin Cavalier * List functions. 51af4a03dfSAugustin Cavalier */ 52af4a03dfSAugustin Cavalier #define LIST_FOREACH_SAFE(var, head, field, tvar) \ 53af4a03dfSAugustin Cavalier for ((var) = LIST_FIRST((head)); \ 54af4a03dfSAugustin Cavalier (var) && ((tvar) = LIST_NEXT((var), field), 1); \ 55af4a03dfSAugustin Cavalier (var) = (tvar)) 56af4a03dfSAugustin Cavalier 57af4a03dfSAugustin Cavalier /* 58af4a03dfSAugustin Cavalier * Tail queue functions. 59af4a03dfSAugustin Cavalier */ 60af4a03dfSAugustin Cavalier #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ 61af4a03dfSAugustin Cavalier for ((var) = TAILQ_FIRST((head)); \ 62af4a03dfSAugustin Cavalier (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ 63af4a03dfSAugustin Cavalier (var) = (tvar)) 64af4a03dfSAugustin Cavalier 65af4a03dfSAugustin Cavalier #define INTEL_DC_P3X00_DEVID 0x09538086 66af4a03dfSAugustin Cavalier 67af4a03dfSAugustin Cavalier #define NVME_TIMEOUT_INFINITE UINT64_MAX 68af4a03dfSAugustin Cavalier 69af4a03dfSAugustin Cavalier /* 70af4a03dfSAugustin Cavalier * Some Intel devices support vendor-unique read latency log page even 71af4a03dfSAugustin Cavalier * though the log page directory says otherwise. 72af4a03dfSAugustin Cavalier */ 73af4a03dfSAugustin Cavalier #define NVME_INTEL_QUIRK_READ_LATENCY 0x1 74af4a03dfSAugustin Cavalier 75af4a03dfSAugustin Cavalier /* 76af4a03dfSAugustin Cavalier * Some Intel devices support vendor-unique write latency log page even 77af4a03dfSAugustin Cavalier * though the log page directory says otherwise. 78af4a03dfSAugustin Cavalier */ 79af4a03dfSAugustin Cavalier #define NVME_INTEL_QUIRK_WRITE_LATENCY 0x2 80af4a03dfSAugustin Cavalier 81af4a03dfSAugustin Cavalier /* 82af4a03dfSAugustin Cavalier * Some controllers need a delay before starting to check the device 83af4a03dfSAugustin Cavalier * readiness, which is done by reading the controller status register rdy bit. 84af4a03dfSAugustin Cavalier */ 85af4a03dfSAugustin Cavalier #define NVME_QUIRK_DELAY_BEFORE_CHK_RDY 0x4 86af4a03dfSAugustin Cavalier 87af4a03dfSAugustin Cavalier /* 88af4a03dfSAugustin Cavalier * Some controllers need a delay once the controller status register rdy bit 89af4a03dfSAugustin Cavalier * switches from 0 to 1. 90af4a03dfSAugustin Cavalier */ 91af4a03dfSAugustin Cavalier #define NVME_QUIRK_DELAY_AFTER_RDY 0x8 92af4a03dfSAugustin Cavalier 93af4a03dfSAugustin Cavalier /* 94af4a03dfSAugustin Cavalier * Queues may consist of a contiguous block of physical 95af4a03dfSAugustin Cavalier * memory or optionally a non-contiguous set of physical 96af4a03dfSAugustin Cavalier * memory pages (defined by a Physical Region Pages List) 97af4a03dfSAugustin Cavalier */ 98af4a03dfSAugustin Cavalier #define NVME_MAX_PRP_LIST_ENTRIES (506) 99af4a03dfSAugustin Cavalier 100af4a03dfSAugustin Cavalier /* 101af4a03dfSAugustin Cavalier * For commands requiring more than 2 PRP entries, one PRP will be 102af4a03dfSAugustin Cavalier * embedded in the command (prp1), and the rest of the PRP entries 103af4a03dfSAugustin Cavalier * will be in a list pointed to by the command (prp2). This means 104af4a03dfSAugustin Cavalier * that real max number of PRP entries we support is 506+1, which 105af4a03dfSAugustin Cavalier * results in a max xfer size of 506*PAGE_SIZE. 106af4a03dfSAugustin Cavalier */ 107af4a03dfSAugustin Cavalier #define NVME_MAX_XFER_SIZE NVME_MAX_PRP_LIST_ENTRIES * PAGE_SIZE 108af4a03dfSAugustin Cavalier 109af4a03dfSAugustin Cavalier #define NVME_ADMIN_TRACKERS (16) 110af4a03dfSAugustin Cavalier #define NVME_ADMIN_ENTRIES (128) 111af4a03dfSAugustin Cavalier 112af4a03dfSAugustin Cavalier /* 113af4a03dfSAugustin Cavalier * NVME_IO_ENTRIES defines the size of an I/O qpair's submission and completion 114af4a03dfSAugustin Cavalier * queues, while NVME_IO_TRACKERS defines the maximum number of I/O that we 115af4a03dfSAugustin Cavalier * will allow outstanding on an I/O qpair at any time. The only advantage in 116af4a03dfSAugustin Cavalier * having IO_ENTRIES > IO_TRACKERS is for debugging purposes - when dumping 117af4a03dfSAugustin Cavalier * the contents of the submission and completion queues, it will show a longer 118af4a03dfSAugustin Cavalier * history of data. 119af4a03dfSAugustin Cavalier */ 120af4a03dfSAugustin Cavalier #define NVME_IO_ENTRIES (1024U) 121af4a03dfSAugustin Cavalier #define NVME_IO_TRACKERS (128U) 122af4a03dfSAugustin Cavalier #define NVME_IO_ENTRIES_VS_TRACKERS_RATIO (NVME_IO_ENTRIES / NVME_IO_TRACKERS) 123af4a03dfSAugustin Cavalier 124af4a03dfSAugustin Cavalier /* 125af4a03dfSAugustin Cavalier * NVME_MAX_SGL_DESCRIPTORS defines the maximum number of descriptors in one SGL 126af4a03dfSAugustin Cavalier * segment. 127af4a03dfSAugustin Cavalier */ 128af4a03dfSAugustin Cavalier #define NVME_MAX_SGL_DESCRIPTORS (253) 129af4a03dfSAugustin Cavalier 130af4a03dfSAugustin Cavalier /* 131af4a03dfSAugustin Cavalier * NVME_MAX_IO_ENTRIES is not defined, since it is specified in CC.MQES 132af4a03dfSAugustin Cavalier * for each controller. 133af4a03dfSAugustin Cavalier */ 134af4a03dfSAugustin Cavalier 135af4a03dfSAugustin Cavalier #define NVME_MAX_ASYNC_EVENTS (8) 136af4a03dfSAugustin Cavalier 137af4a03dfSAugustin Cavalier /* 138af4a03dfSAugustin Cavalier * NVME_MAX_IO_QUEUES in nvme_spec.h defines the 64K spec-limit, but this 139af4a03dfSAugustin Cavalier * define specifies the maximum number of queues this driver will actually 140af4a03dfSAugustin Cavalier * try to configure, if available. 141af4a03dfSAugustin Cavalier */ 142af4a03dfSAugustin Cavalier #define DEFAULT_MAX_IO_QUEUES (1024) 143af4a03dfSAugustin Cavalier 144af4a03dfSAugustin Cavalier /* 145af4a03dfSAugustin Cavalier * Maximum of times a failed command can be retried. 146af4a03dfSAugustin Cavalier */ 147af4a03dfSAugustin Cavalier #define NVME_MAX_RETRY_COUNT (3) 148af4a03dfSAugustin Cavalier 149af4a03dfSAugustin Cavalier /* 150af4a03dfSAugustin Cavalier * I/O queue type. 151af4a03dfSAugustin Cavalier */ 152af4a03dfSAugustin Cavalier enum nvme_io_queue_type { 153af4a03dfSAugustin Cavalier 154af4a03dfSAugustin Cavalier NVME_IO_QTYPE_INVALID = 0, 155af4a03dfSAugustin Cavalier NVME_IO_SUBMISSION_QUEUE, 156af4a03dfSAugustin Cavalier NVME_IO_COMPLETION_QUEUE, 157af4a03dfSAugustin Cavalier }; 158af4a03dfSAugustin Cavalier 159af4a03dfSAugustin Cavalier enum nvme_payload_type { 160af4a03dfSAugustin Cavalier 161af4a03dfSAugustin Cavalier NVME_PAYLOAD_TYPE_INVALID = 0, 162af4a03dfSAugustin Cavalier 163af4a03dfSAugustin Cavalier /* 164af4a03dfSAugustin Cavalier * nvme_request::u.payload.contig_buffer is valid for this request. 165af4a03dfSAugustin Cavalier */ 166af4a03dfSAugustin Cavalier NVME_PAYLOAD_TYPE_CONTIG, 167af4a03dfSAugustin Cavalier 168af4a03dfSAugustin Cavalier /* 169af4a03dfSAugustin Cavalier * nvme_request::u.sgl is valid for this request 170af4a03dfSAugustin Cavalier */ 171af4a03dfSAugustin Cavalier NVME_PAYLOAD_TYPE_SGL, 172af4a03dfSAugustin Cavalier }; 173af4a03dfSAugustin Cavalier 174af4a03dfSAugustin Cavalier /* 175af4a03dfSAugustin Cavalier * Controller support flags. 176af4a03dfSAugustin Cavalier */ 177af4a03dfSAugustin Cavalier enum nvme_ctrlr_flags { 178af4a03dfSAugustin Cavalier 179af4a03dfSAugustin Cavalier /* 180af4a03dfSAugustin Cavalier * The SGL is supported. 181af4a03dfSAugustin Cavalier */ 182af4a03dfSAugustin Cavalier NVME_CTRLR_SGL_SUPPORTED = 0x1, 183af4a03dfSAugustin Cavalier 184af4a03dfSAugustin Cavalier }; 185af4a03dfSAugustin Cavalier 186af4a03dfSAugustin Cavalier /* 187af4a03dfSAugustin Cavalier * Descriptor for a request data payload. 188af4a03dfSAugustin Cavalier * 189af4a03dfSAugustin Cavalier * This struct is arranged so that it fits nicely in struct nvme_request. 190af4a03dfSAugustin Cavalier */ 191af4a03dfSAugustin Cavalier struct __attribute__((packed)) nvme_payload { 192af4a03dfSAugustin Cavalier 193af4a03dfSAugustin Cavalier union { 194af4a03dfSAugustin Cavalier /* 195af4a03dfSAugustin Cavalier * Virtual memory address of a single 196af4a03dfSAugustin Cavalier * physically contiguous buffer 197af4a03dfSAugustin Cavalier */ 198af4a03dfSAugustin Cavalier void *contig; 199af4a03dfSAugustin Cavalier 200af4a03dfSAugustin Cavalier /* 201af4a03dfSAugustin Cavalier * Call back functions for retrieving physical 202af4a03dfSAugustin Cavalier * addresses for scattered payloads. 203af4a03dfSAugustin Cavalier */ 204af4a03dfSAugustin Cavalier struct { 205af4a03dfSAugustin Cavalier nvme_req_reset_sgl_cb reset_sgl_fn; 206af4a03dfSAugustin Cavalier nvme_req_next_sge_cb next_sge_fn; 207af4a03dfSAugustin Cavalier void *cb_arg; 208af4a03dfSAugustin Cavalier } sgl; 209af4a03dfSAugustin Cavalier } u; 210af4a03dfSAugustin Cavalier 211af4a03dfSAugustin Cavalier /* 212af4a03dfSAugustin Cavalier * Virtual memory address of a single physically 213af4a03dfSAugustin Cavalier * contiguous metadata buffer 214af4a03dfSAugustin Cavalier */ 215af4a03dfSAugustin Cavalier void *md; 216af4a03dfSAugustin Cavalier 217af4a03dfSAugustin Cavalier /* 218af4a03dfSAugustin Cavalier * Payload type. 219af4a03dfSAugustin Cavalier */ 220af4a03dfSAugustin Cavalier uint8_t type; 221af4a03dfSAugustin Cavalier 222af4a03dfSAugustin Cavalier }; 223af4a03dfSAugustin Cavalier 224af4a03dfSAugustin Cavalier struct nvme_request { 225af4a03dfSAugustin Cavalier 226af4a03dfSAugustin Cavalier /* 227af4a03dfSAugustin Cavalier * NVMe command: must be aligned on 64B. 228af4a03dfSAugustin Cavalier */ 229af4a03dfSAugustin Cavalier struct nvme_cmd cmd; 230af4a03dfSAugustin Cavalier 231af4a03dfSAugustin Cavalier /* 232af4a03dfSAugustin Cavalier * Data payload for this request's command. 233af4a03dfSAugustin Cavalier */ 234af4a03dfSAugustin Cavalier struct nvme_payload payload; 235af4a03dfSAugustin Cavalier 236af4a03dfSAugustin Cavalier uint8_t retries; 237af4a03dfSAugustin Cavalier 238af4a03dfSAugustin Cavalier /* 239af4a03dfSAugustin Cavalier * Number of child requests still outstanding for this 240af4a03dfSAugustin Cavalier * request which was split into multiple child requests. 241af4a03dfSAugustin Cavalier */ 242af4a03dfSAugustin Cavalier uint8_t child_reqs; 243af4a03dfSAugustin Cavalier uint32_t payload_size; 244af4a03dfSAugustin Cavalier 245af4a03dfSAugustin Cavalier /* 246af4a03dfSAugustin Cavalier * Offset in bytes from the beginning of payload for this request. 247af4a03dfSAugustin Cavalier * This is used for I/O commands that are split into multiple requests. 248af4a03dfSAugustin Cavalier */ 249af4a03dfSAugustin Cavalier uint32_t payload_offset; 250af4a03dfSAugustin Cavalier uint32_t md_offset; 251af4a03dfSAugustin Cavalier 252af4a03dfSAugustin Cavalier nvme_cmd_cb cb_fn; 253af4a03dfSAugustin Cavalier void *cb_arg; 254af4a03dfSAugustin Cavalier 255af4a03dfSAugustin Cavalier /* 256af4a03dfSAugustin Cavalier * The following members should not be reordered with members 257af4a03dfSAugustin Cavalier * above. These members are only needed when splitting 258af4a03dfSAugustin Cavalier * requests which is done rarely, and the driver is careful 259af4a03dfSAugustin Cavalier * to not touch the following fields until a split operation is 260af4a03dfSAugustin Cavalier * needed, to avoid touching an extra cacheline. 261af4a03dfSAugustin Cavalier */ 262af4a03dfSAugustin Cavalier 263af4a03dfSAugustin Cavalier /* 264af4a03dfSAugustin Cavalier * Points to the outstanding child requests for a parent request. 265af4a03dfSAugustin Cavalier * Only valid if a request was split into multiple child 266af4a03dfSAugustin Cavalier * requests, and is not initialized for non-split requests. 267af4a03dfSAugustin Cavalier */ 268af4a03dfSAugustin Cavalier TAILQ_HEAD(, nvme_request) children; 269af4a03dfSAugustin Cavalier 270af4a03dfSAugustin Cavalier /* 271af4a03dfSAugustin Cavalier * Linked-list pointers for a child request in its parent's list. 272af4a03dfSAugustin Cavalier */ 273af4a03dfSAugustin Cavalier TAILQ_ENTRY(nvme_request) child_tailq; 274af4a03dfSAugustin Cavalier 275af4a03dfSAugustin Cavalier /* 276af4a03dfSAugustin Cavalier * For queueing in qpair queued_req or free_req. 277af4a03dfSAugustin Cavalier */ 278af4a03dfSAugustin Cavalier struct nvme_qpair *qpair; 279af4a03dfSAugustin Cavalier STAILQ_ENTRY(nvme_request) stailq; 280af4a03dfSAugustin Cavalier 281af4a03dfSAugustin Cavalier /* 282af4a03dfSAugustin Cavalier * Points to a parent request if part of a split request, 283af4a03dfSAugustin Cavalier * NULL otherwise. 284af4a03dfSAugustin Cavalier */ 285af4a03dfSAugustin Cavalier struct nvme_request *parent; 286af4a03dfSAugustin Cavalier 287af4a03dfSAugustin Cavalier /* 288af4a03dfSAugustin Cavalier * Completion status for a parent request. Initialized to all 0's 289af4a03dfSAugustin Cavalier * (SUCCESS) before child requests are submitted. If a child 290af4a03dfSAugustin Cavalier * request completes with error, the error status is copied here, 291af4a03dfSAugustin Cavalier * to ensure that the parent request is also completed with error 292af4a03dfSAugustin Cavalier * status once all child requests are completed. 293af4a03dfSAugustin Cavalier */ 294af4a03dfSAugustin Cavalier struct nvme_cpl parent_status; 295af4a03dfSAugustin Cavalier 296af4a03dfSAugustin Cavalier } __attribute__((aligned(64))); 297af4a03dfSAugustin Cavalier 298af4a03dfSAugustin Cavalier struct nvme_completion_poll_status { 299af4a03dfSAugustin Cavalier struct nvme_cpl cpl; 300af4a03dfSAugustin Cavalier bool done; 301af4a03dfSAugustin Cavalier }; 302af4a03dfSAugustin Cavalier 303af4a03dfSAugustin Cavalier struct nvme_async_event_request { 304af4a03dfSAugustin Cavalier struct nvme_ctrlr *ctrlr; 305af4a03dfSAugustin Cavalier struct nvme_request *req; 306af4a03dfSAugustin Cavalier struct nvme_cpl cpl; 307af4a03dfSAugustin Cavalier }; 308af4a03dfSAugustin Cavalier 309af4a03dfSAugustin Cavalier struct nvme_tracker { 310af4a03dfSAugustin Cavalier 311af4a03dfSAugustin Cavalier LIST_ENTRY(nvme_tracker) list; 312af4a03dfSAugustin Cavalier 313af4a03dfSAugustin Cavalier struct nvme_request *req; 314*1bcecb98SAugustin Cavalier #if INTPTR_MAX == INT32_MAX 315*1bcecb98SAugustin Cavalier int32_t __pad[3]; 316*1bcecb98SAugustin Cavalier #elif !defined(INTPTR_MAX) 317*1bcecb98SAugustin Cavalier # error Need definition of INTPTR_MAX! 318*1bcecb98SAugustin Cavalier #endif 319*1bcecb98SAugustin Cavalier 320af4a03dfSAugustin Cavalier uint16_t cid; 321af4a03dfSAugustin Cavalier 322af4a03dfSAugustin Cavalier uint16_t rsvd1: 15; 323af4a03dfSAugustin Cavalier uint16_t active: 1; 324af4a03dfSAugustin Cavalier 325af4a03dfSAugustin Cavalier uint32_t rsvd2; 326af4a03dfSAugustin Cavalier 327af4a03dfSAugustin Cavalier uint64_t prp_sgl_bus_addr; 328af4a03dfSAugustin Cavalier 329af4a03dfSAugustin Cavalier union { 330af4a03dfSAugustin Cavalier uint64_t prp[NVME_MAX_PRP_LIST_ENTRIES]; 331af4a03dfSAugustin Cavalier struct nvme_sgl_descriptor sgl[NVME_MAX_SGL_DESCRIPTORS]; 332af4a03dfSAugustin Cavalier } u; 333af4a03dfSAugustin Cavalier 334af4a03dfSAugustin Cavalier uint64_t rsvd3; 335af4a03dfSAugustin Cavalier }; 336af4a03dfSAugustin Cavalier 337af4a03dfSAugustin Cavalier /* 338af4a03dfSAugustin Cavalier * struct nvme_tracker must be exactly 4K so that the prp[] array does not 339af4a03dfSAugustin Cavalier * cross a page boundery and so that there is no padding required to meet 340af4a03dfSAugustin Cavalier * alignment requirements. 341af4a03dfSAugustin Cavalier */ 342af4a03dfSAugustin Cavalier nvme_static_assert(sizeof(struct nvme_tracker) == 4096, 343af4a03dfSAugustin Cavalier "nvme_tracker is not 4K"); 344af4a03dfSAugustin Cavalier nvme_static_assert((offsetof(struct nvme_tracker, u.sgl) & 7) == 0, 345af4a03dfSAugustin Cavalier "SGL must be Qword aligned"); 346af4a03dfSAugustin Cavalier 347af4a03dfSAugustin Cavalier struct nvme_qpair { 348625dc38aSAugustin Cavalier /* 349625dc38aSAugustin Cavalier * Guards access to this structure. 350625dc38aSAugustin Cavalier */ 351625dc38aSAugustin Cavalier pthread_mutex_t lock; 352af4a03dfSAugustin Cavalier 353af4a03dfSAugustin Cavalier volatile uint32_t *sq_tdbl; 354af4a03dfSAugustin Cavalier volatile uint32_t *cq_hdbl; 355af4a03dfSAugustin Cavalier 356af4a03dfSAugustin Cavalier /* 357af4a03dfSAugustin Cavalier * Submission queue 358af4a03dfSAugustin Cavalier */ 359af4a03dfSAugustin Cavalier struct nvme_cmd *cmd; 360af4a03dfSAugustin Cavalier 361af4a03dfSAugustin Cavalier /* 362af4a03dfSAugustin Cavalier * Completion queue 363af4a03dfSAugustin Cavalier */ 364af4a03dfSAugustin Cavalier struct nvme_cpl *cpl; 365af4a03dfSAugustin Cavalier 366af4a03dfSAugustin Cavalier LIST_HEAD(, nvme_tracker) free_tr; 367af4a03dfSAugustin Cavalier LIST_HEAD(, nvme_tracker) outstanding_tr; 368af4a03dfSAugustin Cavalier 369af4a03dfSAugustin Cavalier /* 370af4a03dfSAugustin Cavalier * Array of trackers indexed by command ID. 371af4a03dfSAugustin Cavalier */ 372af4a03dfSAugustin Cavalier uint16_t trackers; 373af4a03dfSAugustin Cavalier struct nvme_tracker *tr; 374af4a03dfSAugustin Cavalier 375af4a03dfSAugustin Cavalier struct nvme_request *reqs; 376af4a03dfSAugustin Cavalier unsigned int num_reqs; 377af4a03dfSAugustin Cavalier STAILQ_HEAD(, nvme_request) free_req; 378af4a03dfSAugustin Cavalier STAILQ_HEAD(, nvme_request) queued_req; 379af4a03dfSAugustin Cavalier 380af4a03dfSAugustin Cavalier uint16_t id; 381af4a03dfSAugustin Cavalier 382af4a03dfSAugustin Cavalier uint16_t entries; 383af4a03dfSAugustin Cavalier uint16_t sq_tail; 384af4a03dfSAugustin Cavalier uint16_t cq_head; 385af4a03dfSAugustin Cavalier 386af4a03dfSAugustin Cavalier uint8_t phase; 387af4a03dfSAugustin Cavalier 388af4a03dfSAugustin Cavalier bool enabled; 389af4a03dfSAugustin Cavalier bool sq_in_cmb; 390af4a03dfSAugustin Cavalier 391af4a03dfSAugustin Cavalier /* 392af4a03dfSAugustin Cavalier * Fields below this point should not be touched on the 393af4a03dfSAugustin Cavalier * normal I/O happy path. 394af4a03dfSAugustin Cavalier */ 395af4a03dfSAugustin Cavalier 396af4a03dfSAugustin Cavalier uint8_t qprio; 397af4a03dfSAugustin Cavalier 398af4a03dfSAugustin Cavalier struct nvme_ctrlr *ctrlr; 399af4a03dfSAugustin Cavalier 400af4a03dfSAugustin Cavalier /* List entry for nvme_ctrlr::free_io_qpairs and active_io_qpairs */ 401af4a03dfSAugustin Cavalier TAILQ_ENTRY(nvme_qpair) tailq; 402af4a03dfSAugustin Cavalier 403af4a03dfSAugustin Cavalier phys_addr_t cmd_bus_addr; 404af4a03dfSAugustin Cavalier phys_addr_t cpl_bus_addr; 405af4a03dfSAugustin Cavalier }; 406af4a03dfSAugustin Cavalier 407af4a03dfSAugustin Cavalier struct nvme_ns { 408af4a03dfSAugustin Cavalier 409af4a03dfSAugustin Cavalier struct nvme_ctrlr *ctrlr; 410af4a03dfSAugustin Cavalier 411af4a03dfSAugustin Cavalier uint32_t stripe_size; 412af4a03dfSAugustin Cavalier uint32_t sector_size; 413af4a03dfSAugustin Cavalier 414af4a03dfSAugustin Cavalier uint32_t md_size; 415af4a03dfSAugustin Cavalier uint32_t pi_type; 416af4a03dfSAugustin Cavalier 417af4a03dfSAugustin Cavalier uint32_t sectors_per_max_io; 418af4a03dfSAugustin Cavalier uint32_t sectors_per_stripe; 419af4a03dfSAugustin Cavalier 420af4a03dfSAugustin Cavalier uint16_t id; 421af4a03dfSAugustin Cavalier uint16_t flags; 422af4a03dfSAugustin Cavalier 423af4a03dfSAugustin Cavalier int open_count; 424af4a03dfSAugustin Cavalier 425af4a03dfSAugustin Cavalier }; 426af4a03dfSAugustin Cavalier 427af4a03dfSAugustin Cavalier /* 428af4a03dfSAugustin Cavalier * State of struct nvme_ctrlr (in particular, during initialization). 429af4a03dfSAugustin Cavalier */ 430af4a03dfSAugustin Cavalier enum nvme_ctrlr_state { 431af4a03dfSAugustin Cavalier 432af4a03dfSAugustin Cavalier /* 433af4a03dfSAugustin Cavalier * Controller has not been initialized yet. 434af4a03dfSAugustin Cavalier */ 435af4a03dfSAugustin Cavalier NVME_CTRLR_STATE_INIT = 0, 436af4a03dfSAugustin Cavalier 437af4a03dfSAugustin Cavalier /* 438af4a03dfSAugustin Cavalier * Waiting for CSTS.RDY to transition from 0 to 1 439af4a03dfSAugustin Cavalier * so that CC.EN may be set to 0. 440af4a03dfSAugustin Cavalier */ 441af4a03dfSAugustin Cavalier NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1, 442af4a03dfSAugustin Cavalier 443af4a03dfSAugustin Cavalier /* 444af4a03dfSAugustin Cavalier * Waiting for CSTS.RDY to transition from 1 to 0 445af4a03dfSAugustin Cavalier * so that CC.EN may be set to 1. 446af4a03dfSAugustin Cavalier */ 447af4a03dfSAugustin Cavalier NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0, 448af4a03dfSAugustin Cavalier 449af4a03dfSAugustin Cavalier /* 450af4a03dfSAugustin Cavalier * Waiting for CSTS.RDY to transition from 0 to 1 451af4a03dfSAugustin Cavalier * after enabling the controller. 452af4a03dfSAugustin Cavalier */ 453af4a03dfSAugustin Cavalier NVME_CTRLR_STATE_ENABLE_WAIT_FOR_READY_1, 454af4a03dfSAugustin Cavalier 455af4a03dfSAugustin Cavalier /* 456af4a03dfSAugustin Cavalier * Controller initialization has completed and 457af4a03dfSAugustin Cavalier * the controller is ready. 458af4a03dfSAugustin Cavalier */ 459af4a03dfSAugustin Cavalier NVME_CTRLR_STATE_READY 460af4a03dfSAugustin Cavalier }; 461af4a03dfSAugustin Cavalier 462af4a03dfSAugustin Cavalier /* 463af4a03dfSAugustin Cavalier * One of these per allocated PCI device. 464af4a03dfSAugustin Cavalier */ 465af4a03dfSAugustin Cavalier struct nvme_ctrlr { 466af4a03dfSAugustin Cavalier 467af4a03dfSAugustin Cavalier /* 468af4a03dfSAugustin Cavalier * NVMe MMIO register space. 469af4a03dfSAugustin Cavalier */ 470af4a03dfSAugustin Cavalier volatile struct nvme_registers *regs; 471af4a03dfSAugustin Cavalier 472af4a03dfSAugustin Cavalier /* 473af4a03dfSAugustin Cavalier * Array of I/O queue pairs. 474af4a03dfSAugustin Cavalier */ 475af4a03dfSAugustin Cavalier struct nvme_qpair *ioq; 476af4a03dfSAugustin Cavalier 477af4a03dfSAugustin Cavalier /* 478af4a03dfSAugustin Cavalier * Size of the array of I/O queue pairs. 479af4a03dfSAugustin Cavalier */ 480af4a03dfSAugustin Cavalier unsigned int io_queues; 481af4a03dfSAugustin Cavalier 482af4a03dfSAugustin Cavalier /* 483af4a03dfSAugustin Cavalier * Maximum I/O queue pairs. 484af4a03dfSAugustin Cavalier */ 485af4a03dfSAugustin Cavalier unsigned int max_io_queues; 486af4a03dfSAugustin Cavalier 487af4a03dfSAugustin Cavalier /* 488af4a03dfSAugustin Cavalier * Number of I/O queue pairs enabled 489af4a03dfSAugustin Cavalier */ 490af4a03dfSAugustin Cavalier unsigned int enabled_io_qpairs; 491af4a03dfSAugustin Cavalier 492af4a03dfSAugustin Cavalier /* 493af4a03dfSAugustin Cavalier * Maximum entries for I/O qpairs 494af4a03dfSAugustin Cavalier */ 495af4a03dfSAugustin Cavalier unsigned int io_qpairs_max_entries; 496af4a03dfSAugustin Cavalier 497af4a03dfSAugustin Cavalier /* 498af4a03dfSAugustin Cavalier * Array of namespace IDs. 499af4a03dfSAugustin Cavalier */ 500af4a03dfSAugustin Cavalier unsigned int nr_ns; 501af4a03dfSAugustin Cavalier struct nvme_ns *ns; 502af4a03dfSAugustin Cavalier 503af4a03dfSAugustin Cavalier /* 504af4a03dfSAugustin Cavalier * Controller state. 505af4a03dfSAugustin Cavalier */ 506af4a03dfSAugustin Cavalier bool resetting; 507af4a03dfSAugustin Cavalier bool failed; 508af4a03dfSAugustin Cavalier 509af4a03dfSAugustin Cavalier /* 510af4a03dfSAugustin Cavalier * Controller support flags. 511af4a03dfSAugustin Cavalier */ 512af4a03dfSAugustin Cavalier uint64_t flags; 513af4a03dfSAugustin Cavalier 514af4a03dfSAugustin Cavalier /* 515af4a03dfSAugustin Cavalier * Cold data (not accessed in normal I/O path) is after this point. 516af4a03dfSAugustin Cavalier */ 517af4a03dfSAugustin Cavalier enum nvme_ctrlr_state state; 518af4a03dfSAugustin Cavalier uint64_t state_timeout_ms; 519af4a03dfSAugustin Cavalier 520af4a03dfSAugustin Cavalier /* 521af4a03dfSAugustin Cavalier * All the log pages supported. 522af4a03dfSAugustin Cavalier */ 523af4a03dfSAugustin Cavalier bool log_page_supported[256]; 524af4a03dfSAugustin Cavalier 525af4a03dfSAugustin Cavalier /* 526af4a03dfSAugustin Cavalier * All the features supported. 527af4a03dfSAugustin Cavalier */ 528af4a03dfSAugustin Cavalier bool feature_supported[256]; 529af4a03dfSAugustin Cavalier 530af4a03dfSAugustin Cavalier /* 531af4a03dfSAugustin Cavalier * Associated PCI device information. 532af4a03dfSAugustin Cavalier */ 533af4a03dfSAugustin Cavalier struct pci_device *pci_dev; 534af4a03dfSAugustin Cavalier 535af4a03dfSAugustin Cavalier /* 536af4a03dfSAugustin Cavalier * Maximum i/o size in bytes. 537af4a03dfSAugustin Cavalier */ 538af4a03dfSAugustin Cavalier uint32_t max_xfer_size; 539af4a03dfSAugustin Cavalier 540af4a03dfSAugustin Cavalier /* 541af4a03dfSAugustin Cavalier * Minimum page size supported by this controller in bytes. 542af4a03dfSAugustin Cavalier */ 543af4a03dfSAugustin Cavalier uint32_t min_page_size; 544af4a03dfSAugustin Cavalier 545af4a03dfSAugustin Cavalier /* 546af4a03dfSAugustin Cavalier * Stride in uint32_t units between doorbell registers 547af4a03dfSAugustin Cavalier * (1 = 4 bytes, 2 = 8 bytes, ...). 548af4a03dfSAugustin Cavalier */ 549af4a03dfSAugustin Cavalier uint32_t doorbell_stride_u32; 550af4a03dfSAugustin Cavalier 551af4a03dfSAugustin Cavalier uint32_t num_aers; 552af4a03dfSAugustin Cavalier struct nvme_async_event_request aer[NVME_MAX_ASYNC_EVENTS]; 553af4a03dfSAugustin Cavalier nvme_aer_cb aer_cb_fn; 554af4a03dfSAugustin Cavalier void *aer_cb_arg; 555af4a03dfSAugustin Cavalier 556af4a03dfSAugustin Cavalier /* 557af4a03dfSAugustin Cavalier * Admin queue pair. 558af4a03dfSAugustin Cavalier */ 559af4a03dfSAugustin Cavalier struct nvme_qpair adminq; 560af4a03dfSAugustin Cavalier 561af4a03dfSAugustin Cavalier /* 562625dc38aSAugustin Cavalier * Guards access to the controller itself. 563625dc38aSAugustin Cavalier */ 564625dc38aSAugustin Cavalier pthread_mutex_t lock; 565625dc38aSAugustin Cavalier 566625dc38aSAugustin Cavalier /* 567af4a03dfSAugustin Cavalier * Identify Controller data. 568af4a03dfSAugustin Cavalier */ 569af4a03dfSAugustin Cavalier struct nvme_ctrlr_data cdata; 570af4a03dfSAugustin Cavalier 571af4a03dfSAugustin Cavalier /* 572af4a03dfSAugustin Cavalier * Array of Identify Namespace data. 573af4a03dfSAugustin Cavalier * Stored separately from ns since nsdata should 574af4a03dfSAugustin Cavalier * not normally be accessed during I/O. 575af4a03dfSAugustin Cavalier */ 576af4a03dfSAugustin Cavalier struct nvme_ns_data *nsdata; 577af4a03dfSAugustin Cavalier 578af4a03dfSAugustin Cavalier TAILQ_HEAD(, nvme_qpair) free_io_qpairs; 579af4a03dfSAugustin Cavalier TAILQ_HEAD(, nvme_qpair) active_io_qpairs; 580af4a03dfSAugustin Cavalier 581af4a03dfSAugustin Cavalier /* 582af4a03dfSAugustin Cavalier * Controller option set on open. 583af4a03dfSAugustin Cavalier */ 584af4a03dfSAugustin Cavalier struct nvme_ctrlr_opts opts; 585af4a03dfSAugustin Cavalier 586af4a03dfSAugustin Cavalier /* 587af4a03dfSAugustin Cavalier * BAR mapping address which contains controller memory buffer. 588af4a03dfSAugustin Cavalier */ 589af4a03dfSAugustin Cavalier void *cmb_bar_virt_addr; 590af4a03dfSAugustin Cavalier 591af4a03dfSAugustin Cavalier /* 592af4a03dfSAugustin Cavalier * BAR physical address which contains controller memory buffer. 593af4a03dfSAugustin Cavalier */ 594af4a03dfSAugustin Cavalier uint64_t cmb_bar_phys_addr; 595af4a03dfSAugustin Cavalier 596af4a03dfSAugustin Cavalier /* 597af4a03dfSAugustin Cavalier * Controller memory buffer size in Bytes. 598af4a03dfSAugustin Cavalier */ 599af4a03dfSAugustin Cavalier uint64_t cmb_size; 600af4a03dfSAugustin Cavalier 601af4a03dfSAugustin Cavalier /* 602af4a03dfSAugustin Cavalier * Current offset of controller memory buffer. 603af4a03dfSAugustin Cavalier */ 604af4a03dfSAugustin Cavalier uint64_t cmb_current_offset; 605af4a03dfSAugustin Cavalier 606af4a03dfSAugustin Cavalier /* 607af4a03dfSAugustin Cavalier * Quirks flags. 608af4a03dfSAugustin Cavalier */ 609af4a03dfSAugustin Cavalier unsigned int quirks; 610af4a03dfSAugustin Cavalier 611af4a03dfSAugustin Cavalier /* 612af4a03dfSAugustin Cavalier * For controller list. 613af4a03dfSAugustin Cavalier */ 614af4a03dfSAugustin Cavalier LIST_ENTRY(nvme_ctrlr) link; 615af4a03dfSAugustin Cavalier 616af4a03dfSAugustin Cavalier } __attribute__((aligned(PAGE_SIZE))); 617af4a03dfSAugustin Cavalier 618af4a03dfSAugustin Cavalier /* 619af4a03dfSAugustin Cavalier * Admin functions. 620af4a03dfSAugustin Cavalier */ 621af4a03dfSAugustin Cavalier extern int nvme_admin_identify_ctrlr(struct nvme_ctrlr *ctrlr, 622af4a03dfSAugustin Cavalier struct nvme_ctrlr_data *cdata); 623af4a03dfSAugustin Cavalier 624af4a03dfSAugustin Cavalier extern int nvme_admin_get_feature(struct nvme_ctrlr *ctrlr, 625af4a03dfSAugustin Cavalier enum nvme_feat_sel sel, 626af4a03dfSAugustin Cavalier enum nvme_feat feature, 627af4a03dfSAugustin Cavalier uint32_t cdw11, uint32_t *attributes); 628af4a03dfSAugustin Cavalier 629af4a03dfSAugustin Cavalier extern int nvme_admin_set_feature(struct nvme_ctrlr *ctrlr, 630af4a03dfSAugustin Cavalier bool save, 631af4a03dfSAugustin Cavalier enum nvme_feat feature, 632af4a03dfSAugustin Cavalier uint32_t cdw11, uint32_t cdw12, 633af4a03dfSAugustin Cavalier uint32_t *attributes); 634af4a03dfSAugustin Cavalier 635af4a03dfSAugustin Cavalier extern int nvme_admin_format_nvm(struct nvme_ctrlr *ctrlr, 636af4a03dfSAugustin Cavalier unsigned int nsid, 637af4a03dfSAugustin Cavalier struct nvme_format *format); 638af4a03dfSAugustin Cavalier 639af4a03dfSAugustin Cavalier extern int nvme_admin_get_log_page(struct nvme_ctrlr *ctrlr, 640af4a03dfSAugustin Cavalier uint8_t log_page, uint32_t nsid, 641af4a03dfSAugustin Cavalier void *payload, uint32_t payload_size); 642af4a03dfSAugustin Cavalier 643af4a03dfSAugustin Cavalier extern int nvme_admin_abort_cmd(struct nvme_ctrlr *ctrlr, 644af4a03dfSAugustin Cavalier uint16_t cid, uint16_t sqid); 645af4a03dfSAugustin Cavalier 646af4a03dfSAugustin Cavalier extern int nvme_admin_create_ioq(struct nvme_ctrlr *ctrlr, 647af4a03dfSAugustin Cavalier struct nvme_qpair *io_que, 648af4a03dfSAugustin Cavalier enum nvme_io_queue_type io_qtype); 649af4a03dfSAugustin Cavalier 650af4a03dfSAugustin Cavalier extern int nvme_admin_delete_ioq(struct nvme_ctrlr *ctrlr, 651af4a03dfSAugustin Cavalier struct nvme_qpair *qpair, 652af4a03dfSAugustin Cavalier enum nvme_io_queue_type io_qtype); 653af4a03dfSAugustin Cavalier 654af4a03dfSAugustin Cavalier extern int nvme_admin_identify_ns(struct nvme_ctrlr *ctrlr, 655af4a03dfSAugustin Cavalier uint16_t nsid, 656af4a03dfSAugustin Cavalier struct nvme_ns_data *nsdata); 657af4a03dfSAugustin Cavalier 658af4a03dfSAugustin Cavalier extern int nvme_admin_attach_ns(struct nvme_ctrlr *ctrlr, 659af4a03dfSAugustin Cavalier uint32_t nsid, 660af4a03dfSAugustin Cavalier struct nvme_ctrlr_list *clist); 661af4a03dfSAugustin Cavalier 662af4a03dfSAugustin Cavalier extern int nvme_admin_detach_ns(struct nvme_ctrlr *ctrlr, 663af4a03dfSAugustin Cavalier uint32_t nsid, 664af4a03dfSAugustin Cavalier struct nvme_ctrlr_list *clist); 665af4a03dfSAugustin Cavalier 666af4a03dfSAugustin Cavalier extern int nvme_admin_create_ns(struct nvme_ctrlr *ctrlr, 667af4a03dfSAugustin Cavalier struct nvme_ns_data *nsdata, 668af4a03dfSAugustin Cavalier unsigned int *nsid); 669af4a03dfSAugustin Cavalier 670af4a03dfSAugustin Cavalier extern int nvme_admin_delete_ns(struct nvme_ctrlr *ctrlr, 671af4a03dfSAugustin Cavalier unsigned int nsid); 672af4a03dfSAugustin Cavalier 673af4a03dfSAugustin Cavalier extern int nvme_admin_fw_commit(struct nvme_ctrlr *ctrlr, 674af4a03dfSAugustin Cavalier const struct nvme_fw_commit *fw_commit); 675af4a03dfSAugustin Cavalier 676af4a03dfSAugustin Cavalier extern int nvme_admin_fw_image_dl(struct nvme_ctrlr *ctrlr, 677af4a03dfSAugustin Cavalier void *fw, uint32_t size, uint32_t offset); 678af4a03dfSAugustin Cavalier 679af4a03dfSAugustin Cavalier extern void nvme_request_completion_poll_cb(void *arg, 680af4a03dfSAugustin Cavalier const struct nvme_cpl *cpl); 681af4a03dfSAugustin Cavalier 682af4a03dfSAugustin Cavalier extern struct nvme_ctrlr *nvme_ctrlr_attach(struct pci_device *pci_dev, 683af4a03dfSAugustin Cavalier struct nvme_ctrlr_opts *opts); 684af4a03dfSAugustin Cavalier 685af4a03dfSAugustin Cavalier extern void nvme_ctrlr_detach(struct nvme_ctrlr *ctrlr); 686af4a03dfSAugustin Cavalier 687af4a03dfSAugustin Cavalier extern int nvme_qpair_construct(struct nvme_ctrlr *ctrlr, 688af4a03dfSAugustin Cavalier struct nvme_qpair *qpair, enum nvme_qprio qprio, 689af4a03dfSAugustin Cavalier uint16_t entries, uint16_t trackers); 690af4a03dfSAugustin Cavalier 691af4a03dfSAugustin Cavalier extern void nvme_qpair_destroy(struct nvme_qpair *qpair); 692af4a03dfSAugustin Cavalier extern void nvme_qpair_enable(struct nvme_qpair *qpair); 693af4a03dfSAugustin Cavalier extern void nvme_qpair_disable(struct nvme_qpair *qpair); 694af4a03dfSAugustin Cavalier extern int nvme_qpair_submit_request(struct nvme_qpair *qpair, 695af4a03dfSAugustin Cavalier struct nvme_request *req); 696af4a03dfSAugustin Cavalier extern void nvme_qpair_reset(struct nvme_qpair *qpair); 697af4a03dfSAugustin Cavalier extern void nvme_qpair_fail(struct nvme_qpair *qpair); 698af4a03dfSAugustin Cavalier 699af4a03dfSAugustin Cavalier extern int nvme_request_pool_construct(struct nvme_qpair *qpair); 700af4a03dfSAugustin Cavalier 701af4a03dfSAugustin Cavalier extern void nvme_request_pool_destroy(struct nvme_qpair *qpair); 702af4a03dfSAugustin Cavalier 703af4a03dfSAugustin Cavalier extern struct nvme_request *nvme_request_allocate(struct nvme_qpair *qpair, 704af4a03dfSAugustin Cavalier const struct nvme_payload *payload, uint32_t payload_size, 705af4a03dfSAugustin Cavalier nvme_cmd_cb cb_fn, void *cb_arg); 706af4a03dfSAugustin Cavalier 707af4a03dfSAugustin Cavalier extern struct nvme_request *nvme_request_allocate_null(struct nvme_qpair *qpair, 708af4a03dfSAugustin Cavalier nvme_cmd_cb cb_fn, 709af4a03dfSAugustin Cavalier void *cb_arg); 710af4a03dfSAugustin Cavalier 711af4a03dfSAugustin Cavalier extern struct nvme_request * 712af4a03dfSAugustin Cavalier nvme_request_allocate_contig(struct nvme_qpair *qpair, 713af4a03dfSAugustin Cavalier void *buffer, uint32_t payload_size, 714af4a03dfSAugustin Cavalier nvme_cmd_cb cb_fn, void *cb_arg); 715af4a03dfSAugustin Cavalier 716af4a03dfSAugustin Cavalier extern void nvme_request_free(struct nvme_request *req); 717a73bad3eSAugustin Cavalier extern void nvme_request_free_locked(struct nvme_request *req); 718af4a03dfSAugustin Cavalier 719af4a03dfSAugustin Cavalier extern void nvme_request_add_child(struct nvme_request *parent, 720af4a03dfSAugustin Cavalier struct nvme_request *child); 721af4a03dfSAugustin Cavalier 722af4a03dfSAugustin Cavalier extern void nvme_request_remove_child(struct nvme_request *parent, 723af4a03dfSAugustin Cavalier struct nvme_request *child); 724af4a03dfSAugustin Cavalier 725af4a03dfSAugustin Cavalier extern unsigned int nvme_ctrlr_get_quirks(struct pci_device *pdev); 726af4a03dfSAugustin Cavalier 727af4a03dfSAugustin Cavalier extern int nvme_ns_construct(struct nvme_ctrlr *ctrlr, 728af4a03dfSAugustin Cavalier struct nvme_ns *ns, unsigned int id); 729af4a03dfSAugustin Cavalier 730af4a03dfSAugustin Cavalier /* 731af4a03dfSAugustin Cavalier * Registers mmio access. 732af4a03dfSAugustin Cavalier */ 733af4a03dfSAugustin Cavalier #define nvme_reg_mmio_read_4(sc, reg) \ 734af4a03dfSAugustin Cavalier nvme_mmio_read_4((__u32 *)&(sc)->regs->reg) 735af4a03dfSAugustin Cavalier 736af4a03dfSAugustin Cavalier #define nvme_reg_mmio_read_8(sc, reg) \ 737af4a03dfSAugustin Cavalier nvme_mmio_read_8((__u64 *)&(sc)->regs->reg) 738af4a03dfSAugustin Cavalier 739af4a03dfSAugustin Cavalier #define nvme_reg_mmio_write_4(sc, reg, val) \ 740af4a03dfSAugustin Cavalier nvme_mmio_write_4((__u32 *)&(sc)->regs->reg, val) 741af4a03dfSAugustin Cavalier 742af4a03dfSAugustin Cavalier #define nvme_reg_mmio_write_8(sc, reg, val) \ 743af4a03dfSAugustin Cavalier nvme_mmio_write_8((__u64 *)&(sc)->regs->reg, val) 744af4a03dfSAugustin Cavalier 745af4a03dfSAugustin Cavalier #endif /* __NVME_INTERNAL_H__ */ 746