1 /*
2  * Copyright (c) 2022 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_DRIVERS_DISK_NVME_NVME_NAMESPACE_H_
8 #define ZEPHYR_DRIVERS_DISK_NVME_NVME_NAMESPACE_H_
9 
10 #include <zephyr/drivers/disk.h>
11 
12 struct nvme_namespace_data {
13 	/** namespace size */
14 	uint64_t		nsze;
15 
16 	/** namespace capacity */
17 	uint64_t		ncap;
18 
19 	/** namespace utilization */
20 	uint64_t		nuse;
21 
22 	/** namespace features */
23 	uint8_t			nsfeat;
24 
25 	/** number of lba formats */
26 	uint8_t			nlbaf;
27 
28 	/** formatted lba size */
29 	uint8_t			flbas;
30 
31 	/** metadata capabilities */
32 	uint8_t			mc;
33 
34 	/** end-to-end data protection capabilities */
35 	uint8_t			dpc;
36 
37 	/** end-to-end data protection type settings */
38 	uint8_t			dps;
39 
40 	/** Namespace Multi-path I/O and Namespace Sharing Capabilities */
41 	uint8_t			nmic;
42 
43 	/** Reservation Capabilities */
44 	uint8_t			rescap;
45 
46 	/** Format Progress Indicator */
47 	uint8_t			fpi;
48 
49 	/** Deallocate Logical Block Features */
50 	uint8_t			dlfeat;
51 
52 	/** Namespace Atomic Write Unit Normal  */
53 	uint16_t		nawun;
54 
55 	/** Namespace Atomic Write Unit Power Fail */
56 	uint16_t		nawupf;
57 
58 	/** Namespace Atomic Compare & Write Unit */
59 	uint16_t		nacwu;
60 
61 	/** Namespace Atomic Boundary Size Normal */
62 	uint16_t		nabsn;
63 
64 	/** Namespace Atomic Boundary Offset */
65 	uint16_t		nabo;
66 
67 	/** Namespace Atomic Boundary Size Power Fail */
68 	uint16_t		nabspf;
69 
70 	/** Namespace Optimal IO Boundary */
71 	uint16_t		noiob;
72 
73 	/** NVM Capacity */
74 	uint8_t			nvmcap[16];
75 
76 	/** Namespace Preferred Write Granularity  */
77 	uint16_t		npwg;
78 
79 	/** Namespace Preferred Write Alignment */
80 	uint16_t		npwa;
81 
82 	/** Namespace Preferred Deallocate Granularity */
83 	uint16_t		npdg;
84 
85 	/** Namespace Preferred Deallocate Alignment */
86 	uint16_t		npda;
87 
88 	/** Namespace Optimal Write Size */
89 	uint16_t		nows;
90 
91 	/* bytes 74-91: Reserved */
92 	uint8_t			reserved5[18];
93 
94 	/** ANA Group Identifier */
95 	uint32_t		anagrpid;
96 
97 	/* bytes 96-98: Reserved */
98 	uint8_t			reserved6[3];
99 
100 	/** Namespace Attributes */
101 	uint8_t			nsattr;
102 
103 	/** NVM Set Identifier */
104 	uint16_t		nvmsetid;
105 
106 	/** Endurance Group Identifier */
107 	uint16_t		endgid;
108 
109 	/** Namespace Globally Unique Identifier */
110 	uint8_t			nguid[16];
111 
112 	/** IEEE Extended Unique Identifier */
113 	uint8_t			eui64[8];
114 
115 	/** lba format support */
116 	uint32_t		lbaf[16];
117 
118 	uint8_t			reserved7[192];
119 
120 	uint8_t			vendor_specific[3712];
121 } __packed __aligned(4);
122 
123 static inline
nvme_namespace_data_swapbytes(struct nvme_namespace_data * s)124 void nvme_namespace_data_swapbytes(struct nvme_namespace_data *s)
125 {
126 #if _BYTE_ORDER != _LITTLE_ENDIAN
127 	int i;
128 
129 	s->nsze = sys_le64_to_cpu(s->nsze);
130 	s->ncap = sys_le64_to_cpu(s->ncap);
131 	s->nuse = sys_le64_to_cpu(s->nuse);
132 	s->nawun = sys_le16_to_cpu(s->nawun);
133 	s->nawupf = sys_le16_to_cpu(s->nawupf);
134 	s->nacwu = sys_le16_to_cpu(s->nacwu);
135 	s->nabsn = sys_le16_to_cpu(s->nabsn);
136 	s->nabo = sys_le16_to_cpu(s->nabo);
137 	s->nabspf = sys_le16_to_cpu(s->nabspf);
138 	s->noiob = sys_le16_to_cpu(s->noiob);
139 	s->npwg = sys_le16_to_cpu(s->npwg);
140 	s->npwa = sys_le16_to_cpu(s->npwa);
141 	s->npdg = sys_le16_to_cpu(s->npdg);
142 	s->npda = sys_le16_to_cpu(s->npda);
143 	s->nows = sys_le16_to_cpu(s->nows);
144 	s->anagrpid = sys_le32_to_cpu(s->anagrpid);
145 	s->nvmsetid = sys_le16_to_cpu(s->nvmsetid);
146 	s->endgid = sys_le16_to_cpu(s->endgid);
147 	for (i = 0; i < 16; i++) {
148 		s->lbaf[i] = sys_le32_to_cpu(s->lbaf[i]);
149 	}
150 #else
151 	ARG_UNUSED(s);
152 #endif
153 }
154 
155 /* Readable identifier: nvme%%n%%\0 */
156 #define NVME_NAMESPACE_NAME_MAX_LENGTH 10
157 
158 struct nvme_namespace {
159 	struct nvme_controller *ctrlr;
160 	struct nvme_namespace_data data;
161 	struct disk_info disk;
162 	uint32_t id;
163 	uint32_t flags;
164 	uint32_t boundary;
165 	char name[NVME_NAMESPACE_NAME_MAX_LENGTH];
166 };
167 
168 enum nvme_namespace_flags {
169 	NVME_NS_DEALLOCATE_SUPPORTED	= 0x1,
170 	NVME_NS_FLUSH_SUPPORTED		= 0x2,
171 };
172 
173 uint32_t nvme_namespace_get_sector_size(struct nvme_namespace *ns);
174 
175 uint64_t nvme_namespace_get_num_sectors(struct nvme_namespace *ns);
176 
177 uint64_t nvme_namespace_get_size(struct nvme_namespace *ns);
178 
179 uint32_t nvme_namespace_get_flags(struct nvme_namespace *ns);
180 
181 const char *nvme_namespace_get_serial_number(struct nvme_namespace *ns);
182 
183 const char *nvme_namespace_get_model_number(struct nvme_namespace *ns);
184 
185 const struct nvme_namespace_data *
186 nvme_namespace_get_data(struct nvme_namespace *ns);
187 
188 uint32_t nvme_namespace_get_stripesize(struct nvme_namespace *ns);
189 
190 int nvme_namespace_construct(struct nvme_namespace *ns,
191 			     uint32_t id,
192 			     struct nvme_controller *ctrlr);
193 
194 int nvme_namespace_disk_setup(struct nvme_namespace *ns,
195 			      struct disk_info *disk);
196 
197 #endif /* ZEPHYR_DRIVERS_DISK_NVME_NVME_NAMESPACE_H_ */
198