123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /* SPDX-License-Identifier: MIT */
- /*
- * Description: Helpers for NVMe uring passthrough commands
- */
- #ifndef LIBURING_NVME_H
- #define LIBURING_NVME_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <sys/ioctl.h>
- #include <linux/nvme_ioctl.h>
- /*
- * If the uapi headers installed on the system lacks nvme uring command
- * support, use the local version to prevent compilation issues.
- */
- #ifndef CONFIG_HAVE_NVME_URING
- struct nvme_uring_cmd {
- __u8 opcode;
- __u8 flags;
- __u16 rsvd1;
- __u32 nsid;
- __u32 cdw2;
- __u32 cdw3;
- __u64 metadata;
- __u64 addr;
- __u32 metadata_len;
- __u32 data_len;
- __u32 cdw10;
- __u32 cdw11;
- __u32 cdw12;
- __u32 cdw13;
- __u32 cdw14;
- __u32 cdw15;
- __u32 timeout_ms;
- __u32 rsvd2;
- };
- #define NVME_URING_CMD_IO _IOWR('N', 0x80, struct nvme_uring_cmd)
- #define NVME_URING_CMD_IO_VEC _IOWR('N', 0x81, struct nvme_uring_cmd)
- #endif /* CONFIG_HAVE_NVME_URING */
- #define NVME_DEFAULT_IOCTL_TIMEOUT 0
- #define NVME_IDENTIFY_DATA_SIZE 4096
- #define NVME_IDENTIFY_CSI_SHIFT 24
- #define NVME_IDENTIFY_CNS_NS 0
- #define NVME_CSI_NVM 0
- enum nvme_admin_opcode {
- nvme_admin_identify = 0x06,
- };
- enum nvme_io_opcode {
- nvme_cmd_write = 0x01,
- nvme_cmd_read = 0x02,
- };
- static int nsid;
- static __u32 lba_shift;
- struct nvme_lbaf {
- __le16 ms;
- __u8 ds;
- __u8 rp;
- };
- struct nvme_id_ns {
- __le64 nsze;
- __le64 ncap;
- __le64 nuse;
- __u8 nsfeat;
- __u8 nlbaf;
- __u8 flbas;
- __u8 mc;
- __u8 dpc;
- __u8 dps;
- __u8 nmic;
- __u8 rescap;
- __u8 fpi;
- __u8 dlfeat;
- __le16 nawun;
- __le16 nawupf;
- __le16 nacwu;
- __le16 nabsn;
- __le16 nabo;
- __le16 nabspf;
- __le16 noiob;
- __u8 nvmcap[16];
- __le16 npwg;
- __le16 npwa;
- __le16 npdg;
- __le16 npda;
- __le16 nows;
- __le16 mssrl;
- __le32 mcl;
- __u8 msrc;
- __u8 rsvd81[11];
- __le32 anagrpid;
- __u8 rsvd96[3];
- __u8 nsattr;
- __le16 nvmsetid;
- __le16 endgid;
- __u8 nguid[16];
- __u8 eui64[8];
- struct nvme_lbaf lbaf[16];
- __u8 rsvd192[192];
- __u8 vs[3712];
- };
- static inline int ilog2(uint32_t i)
- {
- int log = -1;
- while (i) {
- i >>= 1;
- log++;
- }
- return log;
- }
- __attribute__((__unused__))
- static int nvme_get_info(const char *file)
- {
- struct nvme_id_ns ns;
- int fd, err;
- __u32 lba_size;
- fd = open(file, O_RDONLY);
- if (fd < 0) {
- perror("file open");
- return -errno;
- }
- nsid = ioctl(fd, NVME_IOCTL_ID);
- if (nsid < 0) {
- close(fd);
- return -errno;
- }
- struct nvme_passthru_cmd cmd = {
- .opcode = nvme_admin_identify,
- .nsid = nsid,
- .addr = (__u64)(uintptr_t)&ns,
- .data_len = NVME_IDENTIFY_DATA_SIZE,
- .cdw10 = NVME_IDENTIFY_CNS_NS,
- .cdw11 = NVME_CSI_NVM << NVME_IDENTIFY_CSI_SHIFT,
- .timeout_ms = NVME_DEFAULT_IOCTL_TIMEOUT,
- };
- err = ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd);
- if (err) {
- close(fd);
- return err;
- }
- lba_size = 1 << ns.lbaf[(ns.flbas & 0x0f)].ds;
- lba_shift = ilog2(lba_size);
- close(fd);
- return 0;
- }
- #ifdef __cplusplus
- }
- #endif
- #endif
|