]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - sys/dev/nvme/nvme.h
240618, 240621, 240633, 240671, 240672, 240697, 240700, 241433,
[FreeBSD/stable/9.git] / sys / dev / nvme / nvme.h
1 /*-
2  * Copyright (C) 2012 Intel Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #ifndef __NVME_H__
30 #define __NVME_H__
31
32 #ifdef _KERNEL
33 #include <sys/types.h>
34 #endif
35
36 #define NVME_PASSTHROUGH_CMD            _IOWR('n', 0, struct nvme_pt_command)
37 #define NVME_RESET_CONTROLLER           _IO('n', 1)
38
39 #define NVME_IO_TEST                    _IOWR('n', 100, struct nvme_io_test)
40 #define NVME_BIO_TEST                   _IOWR('n', 101, struct nvme_io_test)
41
42 /*
43  * Use to mark a command to apply to all namespaces, or to retrieve global
44  *  log pages.
45  */
46 #define NVME_GLOBAL_NAMESPACE_TAG       ((uint32_t)0xFFFFFFFF)
47
48 union cap_lo_register {
49         uint32_t        raw;
50         struct {
51                 /** maximum queue entries supported */
52                 uint32_t mqes           : 16;
53
54                 /** contiguous queues required */
55                 uint32_t cqr            : 1;
56
57                 /** arbitration mechanism supported */
58                 uint32_t ams            : 2;
59
60                 uint32_t reserved1      : 5;
61
62                 /** timeout */
63                 uint32_t to             : 8;
64         } bits __packed;
65 } __packed;
66
67 union cap_hi_register {
68         uint32_t        raw;
69         struct {
70                 /** doorbell stride */
71                 uint32_t dstrd          : 4;
72
73                 uint32_t reserved3      : 1;
74
75                 /** command sets supported */
76                 uint32_t css_nvm        : 1;
77
78                 uint32_t css_reserved   : 3;
79                 uint32_t reserved2      : 7;
80
81                 /** memory page size minimum */
82                 uint32_t mpsmin         : 4;
83
84                 /** memory page size maximum */
85                 uint32_t mpsmax         : 4;
86
87                 uint32_t reserved1      : 8;
88         } bits __packed;
89 } __packed;
90
91 union cc_register {
92         uint32_t        raw;
93         struct {
94                 /** enable */
95                 uint32_t en             : 1;
96
97                 uint32_t reserved1      : 3;
98
99                 /** i/o command set selected */
100                 uint32_t css            : 3;
101
102                 /** memory page size */
103                 uint32_t mps            : 4;
104
105                 /** arbitration mechanism selected */
106                 uint32_t ams            : 3;
107
108                 /** shutdown notification */
109                 uint32_t shn            : 2;
110
111                 /** i/o submission queue entry size */
112                 uint32_t iosqes         : 4;
113
114                 /** i/o completion queue entry size */
115                 uint32_t iocqes         : 4;
116
117                 uint32_t reserved2      : 8;
118         } bits __packed;
119 } __packed;
120
121 enum shn_value {
122         NVME_SHN_NORMAL         = 0x1,
123         NVME_SHN_ABRUPT         = 0x2,
124 };
125
126 union csts_register {
127         uint32_t        raw;
128         struct {
129                 /** ready */
130                 uint32_t rdy            : 1;
131
132                 /** controller fatal status */
133                 uint32_t cfs            : 1;
134
135                 /** shutdown status */
136                 uint32_t shst           : 2;
137
138                 uint32_t reserved1      : 28;
139         } bits __packed;
140 } __packed;
141
142 enum shst_value {
143         NVME_SHST_NORMAL        = 0x0,
144         NVME_SHST_OCCURRING     = 0x1,
145         NVME_SHST_COMPLETE      = 0x2,
146 };
147
148 union aqa_register {
149         uint32_t        raw;
150         struct {
151                 /** admin submission queue size */
152                 uint32_t asqs           : 12;
153
154                 uint32_t reserved1      : 4;
155
156                 /** admin completion queue size */
157                 uint32_t acqs           : 12;
158
159                 uint32_t reserved2      : 4;
160         } bits __packed;
161 } __packed;
162
163 struct nvme_registers
164 {
165         /** controller capabilities */
166         union cap_lo_register   cap_lo;
167         union cap_hi_register   cap_hi;
168
169         uint32_t        vs;             /* version */
170         uint32_t        intms;          /* interrupt mask set */
171         uint32_t        intmc;          /* interrupt mask clear */
172
173         /** controller configuration */
174         union cc_register       cc;
175
176         uint32_t        reserved1;
177         uint32_t        csts;           /* controller status */
178         uint32_t        reserved2;
179
180         /** admin queue attributes */
181         union aqa_register      aqa;
182
183         uint64_t        asq;            /* admin submission queue base addr */
184         uint64_t        acq;            /* admin completion queue base addr */
185         uint32_t        reserved3[0x3f2];
186
187         struct {
188             uint32_t    sq_tdbl;        /* submission queue tail doorbell */
189             uint32_t    cq_hdbl;        /* completion queue head doorbell */
190         } doorbell[1] __packed;
191 } __packed;
192
193 struct nvme_command
194 {
195         /* dword 0 */
196         uint16_t opc    :  8;   /* opcode */
197         uint16_t fuse   :  2;   /* fused operation */
198         uint16_t rsvd1  :  6;
199         uint16_t cid;           /* command identifier */
200
201         /* dword 1 */
202         uint32_t nsid;          /* namespace identifier */
203
204         /* dword 2-3 */
205         uint32_t rsvd2;
206         uint32_t rsvd3;
207
208         /* dword 4-5 */
209         uint64_t mptr;          /* metadata pointer */
210
211         /* dword 6-7 */
212         uint64_t prp1;          /* prp entry 1 */
213
214         /* dword 8-9 */
215         uint64_t prp2;          /* prp entry 2 */
216
217         /* dword 10-15 */
218         uint32_t cdw10;         /* command-specific */
219         uint32_t cdw11;         /* command-specific */
220         uint32_t cdw12;         /* command-specific */
221         uint32_t cdw13;         /* command-specific */
222         uint32_t cdw14;         /* command-specific */
223         uint32_t cdw15;         /* command-specific */
224 } __packed;
225
226 struct nvme_status {
227
228         uint16_t p      :  1;   /* phase tag */
229         uint16_t sc     :  8;   /* status code */
230         uint16_t sct    :  3;   /* status code type */
231         uint16_t rsvd2  :  2;
232         uint16_t m      :  1;   /* more */
233         uint16_t dnr    :  1;   /* do not retry */
234 } __packed;
235
236 struct nvme_completion {
237
238         /* dword 0 */
239         uint32_t                cdw0;   /* command-specific */
240
241         /* dword 1 */
242         uint32_t                rsvd1;
243
244         /* dword 2 */
245         uint16_t                sqhd;   /* submission queue head pointer */
246         uint16_t                sqid;   /* submission queue identifier */
247
248         /* dword 3 */
249         uint16_t                cid;    /* command identifier */
250         struct nvme_status      status;
251 } __packed;
252
253 struct nvme_dsm_range {
254
255         uint32_t attributes;
256         uint32_t length;
257         uint64_t starting_lba;
258 } __packed;
259
260 /* status code types */
261 enum nvme_status_code_type {
262         NVME_SCT_GENERIC                = 0x0,
263         NVME_SCT_COMMAND_SPECIFIC       = 0x1,
264         NVME_SCT_MEDIA_ERROR            = 0x2,
265         /* 0x3-0x6 - reserved */
266         NVME_SCT_VENDOR_SPECIFIC        = 0x7,
267 };
268
269 /* generic command status codes */
270 enum nvme_generic_command_status_code {
271         NVME_SC_SUCCESS                         = 0x00,
272         NVME_SC_INVALID_OPCODE                  = 0x01,
273         NVME_SC_INVALID_FIELD                   = 0x02,
274         NVME_SC_COMMAND_ID_CONFLICT             = 0x03,
275         NVME_SC_DATA_TRANSFER_ERROR             = 0x04,
276         NVME_SC_ABORTED_POWER_LOSS              = 0x05,
277         NVME_SC_INTERNAL_DEVICE_ERROR           = 0x06,
278         NVME_SC_ABORTED_BY_REQUEST              = 0x07,
279         NVME_SC_ABORTED_SQ_DELETION             = 0x08,
280         NVME_SC_ABORTED_FAILED_FUSED            = 0x09,
281         NVME_SC_ABORTED_MISSING_FUSED           = 0x0a,
282         NVME_SC_INVALID_NAMESPACE_OR_FORMAT     = 0x0b,
283         NVME_SC_COMMAND_SEQUENCE_ERROR          = 0x0c,
284
285         NVME_SC_LBA_OUT_OF_RANGE                = 0x80,
286         NVME_SC_CAPACITY_EXCEEDED               = 0x81,
287         NVME_SC_NAMESPACE_NOT_READY             = 0x82,
288 };
289
290 /* command specific status codes */
291 enum nvme_command_specific_status_code {
292         NVME_SC_COMPLETION_QUEUE_INVALID        = 0x00,
293         NVME_SC_INVALID_QUEUE_IDENTIFIER        = 0x01,
294         NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED     = 0x02,
295         NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED    = 0x03,
296         /* 0x04 - reserved */
297         NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED = 0x05,
298         NVME_SC_INVALID_FIRMWARE_SLOT           = 0x06,
299         NVME_SC_INVALID_FIRMWARE_IMAGE          = 0x07,
300         NVME_SC_INVALID_INTERRUPT_VECTOR        = 0x08,
301         NVME_SC_INVALID_LOG_PAGE                = 0x09,
302         NVME_SC_INVALID_FORMAT                  = 0x0a,
303         NVME_SC_FIRMWARE_REQUIRES_RESET         = 0x0b,
304
305         NVME_SC_CONFLICTING_ATTRIBUTES          = 0x80,
306         NVME_SC_INVALID_PROTECTION_INFO         = 0x81,
307         NVME_SC_ATTEMPTED_WRITE_TO_RO_PAGE      = 0x82,
308 };
309
310 /* media error status codes */
311 enum nvme_media_error_status_code {
312         NVME_SC_WRITE_FAULTS                    = 0x80,
313         NVME_SC_UNRECOVERED_READ_ERROR          = 0x81,
314         NVME_SC_GUARD_CHECK_ERROR               = 0x82,
315         NVME_SC_APPLICATION_TAG_CHECK_ERROR     = 0x83,
316         NVME_SC_REFERENCE_TAG_CHECK_ERROR       = 0x84,
317         NVME_SC_COMPARE_FAILURE                 = 0x85,
318         NVME_SC_ACCESS_DENIED                   = 0x86,
319 };
320
321 /* admin opcodes */
322 enum nvme_admin_opcode {
323         NVME_OPC_DELETE_IO_SQ                   = 0x00,
324         NVME_OPC_CREATE_IO_SQ                   = 0x01,
325         NVME_OPC_GET_LOG_PAGE                   = 0x02,
326         /* 0x03 - reserved */
327         NVME_OPC_DELETE_IO_CQ                   = 0x04,
328         NVME_OPC_CREATE_IO_CQ                   = 0x05,
329         NVME_OPC_IDENTIFY                       = 0x06,
330         /* 0x07 - reserved */
331         NVME_OPC_ABORT                          = 0x08,
332         NVME_OPC_SET_FEATURES                   = 0x09,
333         NVME_OPC_GET_FEATURES                   = 0x0a,
334         /* 0x0b - reserved */
335         NVME_OPC_ASYNC_EVENT_REQUEST            = 0x0c,
336         /* 0x0d-0x0f - reserved */
337         NVME_OPC_FIRMWARE_ACTIVATE              = 0x10,
338         NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD        = 0x11,
339
340         NVME_OPC_FORMAT_NVM                     = 0x80,
341         NVME_OPC_SECURITY_SEND                  = 0x81,
342         NVME_OPC_SECURITY_RECEIVE               = 0x82,
343 };
344
345 /* nvme nvm opcodes */
346 enum nvme_nvm_opcode {
347         NVME_OPC_FLUSH                          = 0x00,
348         NVME_OPC_WRITE                          = 0x01,
349         NVME_OPC_READ                           = 0x02,
350         /* 0x03 - reserved */
351         NVME_OPC_WRITE_UNCORRECTABLE            = 0x04,
352         NVME_OPC_COMPARE                        = 0x05,
353         /* 0x06-0x07 - reserved */
354         NVME_OPC_DATASET_MANAGEMENT             = 0x09,
355 };
356
357 enum nvme_feature {
358         /* 0x00 - reserved */
359         NVME_FEAT_ARBITRATION                   = 0x01,
360         NVME_FEAT_POWER_MANAGEMENT              = 0x02,
361         NVME_FEAT_LBA_RANGE_TYPE                = 0x03,
362         NVME_FEAT_TEMPERATURE_THRESHOLD         = 0x04,
363         NVME_FEAT_ERROR_RECOVERY                = 0x05,
364         NVME_FEAT_VOLATILE_WRITE_CACHE          = 0x06,
365         NVME_FEAT_NUMBER_OF_QUEUES              = 0x07,
366         NVME_FEAT_INTERRUPT_COALESCING          = 0x08,
367         NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09,
368         NVME_FEAT_WRITE_ATOMICITY               = 0x0A,
369         NVME_FEAT_ASYNC_EVENT_CONFIGURATION     = 0x0B,
370         /* 0x0C-0x7F - reserved */
371         NVME_FEAT_SOFTWARE_PROGRESS_MARKER      = 0x80,
372         /* 0x81-0xBF - command set specific (reserved) */
373         /* 0xC0-0xFF - vendor specific */
374 };
375
376 enum nvme_dsm_attribute {
377         NVME_DSM_ATTR_INTEGRAL_READ             = 0x1,
378         NVME_DSM_ATTR_INTEGRAL_WRITE            = 0x2,
379         NVME_DSM_ATTR_DEALLOCATE                = 0x4,
380 };
381
382 struct nvme_controller_data {
383
384         /* bytes 0-255: controller capabilities and features */
385
386         /** pci vendor id */
387         uint16_t                vid;
388
389         /** pci subsystem vendor id */
390         uint16_t                ssvid;
391
392         /** serial number */
393         int8_t                  sn[20];
394
395         /** model number */
396         int8_t                  mn[40];
397
398         /** firmware revision */
399         uint8_t                 fr[8];
400
401         /** recommended arbitration burst */
402         uint8_t                 rab;
403
404         /** ieee oui identifier */
405         uint8_t                 ieee[3];
406
407         /** multi-interface capabilities */
408         uint8_t                 mic;
409
410         /** maximum data transfer size */
411         uint8_t                 mdts;
412
413         uint8_t                 reserved1[178];
414
415         /* bytes 256-511: admin command set attributes */
416
417         /** optional admin command support */
418         struct {
419                 /* supports security send/receive commands */
420                 uint16_t        security  : 1;
421
422                 /* supports format nvm command */
423                 uint16_t        format    : 1;
424
425                 /* supports firmware activate/download commands */
426                 uint16_t        firmware  : 1;
427
428                 uint16_t        oacs_rsvd : 13;
429         } __packed oacs;
430
431         /** abort command limit */
432         uint8_t                 acl;
433
434         /** asynchronous event request limit */
435         uint8_t                 aerl;
436
437         /** firmware updates */
438         struct {
439                 /* first slot is read-only */
440                 uint8_t         slot1_ro  : 1;
441
442                 /* number of firmware slots */
443                 uint8_t         num_slots : 3;
444
445                 uint8_t         frmw_rsvd : 4;
446         } __packed frmw;
447
448         /** log page attributes */
449         struct {
450                 /* per namespace smart/health log page */
451                 uint8_t         ns_smart : 1;
452
453                 uint8_t         lpa_rsvd : 7;
454         } __packed lpa;
455
456         /** error log page entries */
457         uint8_t                 elpe;
458
459         /** number of power states supported */
460         uint8_t                 npss;
461
462         /** admin vendor specific command configuration */
463         struct {
464                 /* admin vendor specific commands use spec format */
465                 uint8_t         spec_format : 1;
466
467                 uint8_t         avscc_rsvd  : 7;
468         } __packed avscc;
469
470         uint8_t                 reserved2[247];
471
472         /* bytes 512-703: nvm command set attributes */
473
474         /** submission queue entry size */
475         struct {
476                 uint8_t         min : 4;
477                 uint8_t         max : 4;
478         } __packed sqes;
479
480         /** completion queue entry size */
481         struct {
482                 uint8_t         min : 4;
483                 uint8_t         max : 4;
484         } __packed cqes;
485
486         uint8_t                 reserved3[2];
487
488         /** number of namespaces */
489         uint32_t                nn;
490
491         /** optional nvm command support */
492         struct {
493                 uint16_t        compare : 1;
494                 uint16_t        write_unc : 1;
495                 uint16_t        dsm: 1;
496                 uint16_t        reserved: 13;
497         } __packed oncs;
498
499         /** fused operation support */
500         uint16_t                fuses;
501
502         /** format nvm attributes */
503         uint8_t                 fna;
504
505         /** volatile write cache */
506         struct {
507                 uint8_t         present : 1;
508                 uint8_t         reserved : 7;
509         } __packed vwc;
510
511         /* TODO: flesh out remaining nvm command set attributes */
512         uint8_t                 reserved4[178];
513
514         /* bytes 704-2047: i/o command set attributes */
515         uint8_t                 reserved5[1344];
516
517         /* bytes 2048-3071: power state descriptors */
518         uint8_t                 reserved6[1024];
519
520         /* bytes 3072-4095: vendor specific */
521         uint8_t                 reserved7[1024];
522 } __packed __aligned(4);
523
524 struct nvme_namespace_data {
525
526         /** namespace size */
527         uint64_t                nsze;
528
529         /** namespace capacity */
530         uint64_t                ncap;
531
532         /** namespace utilization */
533         uint64_t                nuse;
534
535         /** namespace features */
536         struct {
537                 /** thin provisioning */
538                 uint8_t         thin_prov : 1;
539                 uint8_t         reserved1 : 7;
540         } __packed nsfeat;
541
542         /** number of lba formats */
543         uint8_t                 nlbaf;
544
545         /** formatted lba size */
546         struct {
547                 uint8_t         format    : 4;
548                 uint8_t         extended  : 1;
549                 uint8_t         reserved2 : 3;
550         } __packed flbas;
551
552         /** metadata capabilities */
553         struct {
554                 /* metadata can be transferred as part of data prp list */
555                 uint8_t         extended  : 1;
556
557                 /* metadata can be transferred with separate metadata pointer */
558                 uint8_t         pointer   : 1;
559
560                 uint8_t         reserved3 : 6;
561         } __packed mc;
562
563         /** end-to-end data protection capabilities */
564         struct {
565                 /* protection information type 1 */
566                 uint8_t         pit1     : 1;
567
568                 /* protection information type 2 */
569                 uint8_t         pit2     : 1;
570
571                 /* protection information type 3 */
572                 uint8_t         pit3     : 1;
573
574                 /* first eight bytes of metadata */
575                 uint8_t         md_start : 1;
576
577                 /* last eight bytes of metadata */
578                 uint8_t         md_end   : 1;
579         } __packed dpc;
580
581         /** end-to-end data protection type settings */
582         struct {
583                 /* protection information type */
584                 uint8_t         pit       : 3;
585
586                 /* 1 == protection info transferred at start of metadata */
587                 /* 0 == protection info transferred at end of metadata */
588                 uint8_t         md_start  : 1;
589
590                 uint8_t         reserved4 : 4;
591         } __packed dps;
592
593         uint8_t                 reserved5[98];
594
595         /** lba format support */
596         struct {
597                 /** metadata size */
598                 uint32_t        ms        : 16;
599
600                 /** lba data size */
601                 uint32_t        lbads     : 8;
602
603                 /** relative performance */
604                 uint32_t        rp        : 2;
605
606                 uint32_t        reserved6 : 6;
607         } __packed lbaf[16];
608
609         uint8_t                 reserved6[192];
610
611         uint8_t                 vendor_specific[3712];
612 } __packed __aligned(4);
613
614 enum nvme_log_page {
615
616         /* 0x00 - reserved */
617         NVME_LOG_ERROR                  = 0x01,
618         NVME_LOG_HEALTH_INFORMATION     = 0x02,
619         NVME_LOG_FIRMWARE_SLOT          = 0x03,
620         /* 0x04-0x7F - reserved */
621         /* 0x80-0xBF - I/O command set specific */
622         /* 0xC0-0xFF - vendor specific */
623 };
624
625 struct nvme_error_information_entry {
626
627         uint64_t                error_count;
628         uint16_t                sqid;
629         uint16_t                cid;
630         struct nvme_status      status;
631         uint16_t                error_location;
632         uint64_t                lba;
633         uint32_t                nsid;
634         uint8_t                 vendor_specific;
635         uint8_t                 reserved[35];
636 } __packed __aligned(4);
637
638 union nvme_critical_warning_state {
639
640         uint8_t         raw;
641
642         struct {
643                 uint8_t available_spare         : 1;
644                 uint8_t temperature             : 1;
645                 uint8_t device_reliability      : 1;
646                 uint8_t read_only               : 1;
647                 uint8_t volatile_memory_backup  : 1;
648                 uint8_t reserved                : 3;
649         } __packed bits;
650 } __packed;
651
652 struct nvme_health_information_page {
653
654         union nvme_critical_warning_state       critical_warning;
655
656         uint16_t                temperature;
657         uint8_t                 available_spare;
658         uint8_t                 available_spare_threshold;
659         uint8_t                 percentage_used;
660
661         uint8_t                 reserved[26];
662
663         /*
664          * Note that the following are 128-bit values, but are
665          *  defined as an array of 2 64-bit values.
666          */
667         /* Data Units Read is always in 512-byte units. */
668         uint64_t                data_units_read[2];
669         /* Data Units Written is always in 512-byte units. */
670         uint64_t                data_units_written[2];
671         /* For NVM command set, this includes Compare commands. */
672         uint64_t                host_read_commands[2];
673         uint64_t                host_write_commands[2];
674         /* Controller Busy Time is reported in minutes. */
675         uint64_t                controller_busy_time[2];
676         uint64_t                power_cycles[2];
677         uint64_t                power_on_hours[2];
678         uint64_t                unsafe_shutdowns[2];
679         uint64_t                media_errors[2];
680         uint64_t                num_error_info_log_entries[2];
681
682         uint8_t                 reserved2[320];
683 } __packed __aligned(4);
684
685 struct nvme_firmware_page {
686
687         struct {
688                 uint8_t slot            : 3; /* slot for current FW */
689                 uint8_t reserved        : 5;
690         } __packed afi;
691
692         uint8_t                 reserved[7];
693         uint64_t                revision[7]; /* revisions for 7 slots */
694         uint8_t                 reserved2[448];
695 } __packed __aligned(4);
696
697 #define NVME_TEST_MAX_THREADS   128
698
699 struct nvme_io_test {
700
701         enum nvme_nvm_opcode    opc;
702         uint32_t                size;
703         uint32_t                time;   /* in seconds */
704         uint32_t                num_threads;
705         uint32_t                flags;
706         uint32_t                io_completed[NVME_TEST_MAX_THREADS];
707 };
708
709 enum nvme_io_test_flags {
710
711         /*
712          * Specifies whether dev_refthread/dev_relthread should be
713          *  called during NVME_BIO_TEST.  Ignored for other test
714          *  types.
715          */
716         NVME_TEST_FLAG_REFTHREAD =      0x1,
717 };
718
719 struct nvme_pt_command {
720
721         /*
722          * cmd is used to specify a passthrough command to a controller or
723          *  namespace.
724          *
725          * The following fields from cmd may be specified by the caller:
726          *      * opc  (opcode)
727          *      * nsid (namespace id) - for admin commands only
728          *      * cdw10-cdw15
729          *
730          * Remaining fields must be set to 0 by the caller.
731          */
732         struct nvme_command     cmd;
733
734         /*
735          * cpl returns completion status for the passthrough command
736          *  specified by cmd.
737          *
738          * The following fields will be filled out by the driver, for
739          *  consumption by the caller:
740          *      * cdw0
741          *      * status (except for phase)
742          *
743          * Remaining fields will be set to 0 by the driver.
744          */
745         struct nvme_completion  cpl;
746
747         /* buf is the data buffer associated with this passthrough command. */
748         void *                  buf;
749
750         /*
751          * len is the length of the data buffer associated with this
752          *  passthrough command.
753          */
754         uint32_t                len;
755
756         /*
757          * is_read = 1 if the passthrough command will read data into the
758          *  supplied buffer.
759          *
760          * is_read = 0 if the passthrough command will write data into the
761          *  supplied buffer.
762          */
763         uint32_t                is_read;
764
765         /*
766          * driver_lock is used by the driver only.  It must be set to 0
767          *  by the caller.
768          */
769         struct mtx *            driver_lock;
770 };
771
772 #define nvme_completion_is_error(cpl)                                   \
773         ((cpl)->status.sc != 0 || (cpl)->status.sct != 0)
774
775 #ifdef _KERNEL
776
777 struct bio;
778
779 struct nvme_namespace;
780 struct nvme_controller;
781 struct nvme_consumer;
782
783 typedef void (*nvme_cb_fn_t)(void *, const struct nvme_completion *);
784
785 typedef void *(*nvme_cons_ns_fn_t)(struct nvme_namespace *, void *);
786 typedef void *(*nvme_cons_ctrlr_fn_t)(struct nvme_controller *);
787 typedef void (*nvme_cons_async_fn_t)(void *, const struct nvme_completion *,
788                                      uint32_t, void *, uint32_t);
789 typedef void (*nvme_cons_fail_fn_t)(void *);
790
791 enum nvme_namespace_flags {
792         NVME_NS_DEALLOCATE_SUPPORTED    = 0x1,
793         NVME_NS_FLUSH_SUPPORTED         = 0x2,
794 };
795
796 int     nvme_ctrlr_passthrough_cmd(struct nvme_controller *ctrlr,
797                                    struct nvme_pt_command *pt,
798                                    uint32_t nsid, int is_user_buffer,
799                                    int is_admin_cmd);
800
801 /* Admin functions */
802 void    nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr,
803                                    uint8_t feature, uint32_t cdw11,
804                                    void *payload, uint32_t payload_size,
805                                    nvme_cb_fn_t cb_fn, void *cb_arg);
806 void    nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr,
807                                    uint8_t feature, uint32_t cdw11,
808                                    void *payload, uint32_t payload_size,
809                                    nvme_cb_fn_t cb_fn, void *cb_arg);
810 void    nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr,
811                                     uint8_t log_page, uint32_t nsid,
812                                     void *payload, uint32_t payload_size,
813                                     nvme_cb_fn_t cb_fn, void *cb_arg);
814
815 /* NVM I/O functions */
816 int     nvme_ns_cmd_write(struct nvme_namespace *ns, void *payload,
817                           uint64_t lba, uint32_t lba_count, nvme_cb_fn_t cb_fn,
818                           void *cb_arg);
819 int     nvme_ns_cmd_write_bio(struct nvme_namespace *ns, struct bio *bp,
820                               nvme_cb_fn_t cb_fn, void *cb_arg);
821 int     nvme_ns_cmd_read(struct nvme_namespace *ns, void *payload,
822                          uint64_t lba, uint32_t lba_count, nvme_cb_fn_t cb_fn,
823                          void *cb_arg);
824 int     nvme_ns_cmd_read_bio(struct nvme_namespace *ns, struct bio *bp,
825                               nvme_cb_fn_t cb_fn, void *cb_arg);
826 int     nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
827                                uint8_t num_ranges, nvme_cb_fn_t cb_fn,
828                                void *cb_arg);
829 int     nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn,
830                           void *cb_arg);
831
832 /* Registration functions */
833 struct nvme_consumer *  nvme_register_consumer(nvme_cons_ns_fn_t    ns_fn,
834                                                nvme_cons_ctrlr_fn_t ctrlr_fn,
835                                                nvme_cons_async_fn_t async_fn,
836                                                nvme_cons_fail_fn_t  fail_fn);
837 void            nvme_unregister_consumer(struct nvme_consumer *consumer);
838
839 /* Controller helper functions */
840 device_t        nvme_ctrlr_get_device(struct nvme_controller *ctrlr);
841 const struct nvme_controller_data *
842                 nvme_ctrlr_get_data(struct nvme_controller *ctrlr);
843
844 /* Namespace helper functions */
845 uint32_t        nvme_ns_get_max_io_xfer_size(struct nvme_namespace *ns);
846 uint32_t        nvme_ns_get_sector_size(struct nvme_namespace *ns);
847 uint64_t        nvme_ns_get_num_sectors(struct nvme_namespace *ns);
848 uint64_t        nvme_ns_get_size(struct nvme_namespace *ns);
849 uint32_t        nvme_ns_get_flags(struct nvme_namespace *ns);
850 const char *    nvme_ns_get_serial_number(struct nvme_namespace *ns);
851 const char *    nvme_ns_get_model_number(struct nvme_namespace *ns);
852 const struct nvme_namespace_data *
853                 nvme_ns_get_data(struct nvme_namespace *ns);
854
855 int     nvme_ns_bio_process(struct nvme_namespace *ns, struct bio *bp,
856                             nvme_cb_fn_t cb_fn);
857
858 #endif /* _KERNEL */
859
860 #endif /* __NVME_H__ */