]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
f6aa61d5 ZZ |
2 | /* |
3 | * Copyright (C) 2017 NXP Semiconductors | |
4 | * Copyright (C) 2017 Bin Meng <[email protected]> | |
f6aa61d5 ZZ |
5 | */ |
6 | ||
7 | #include <common.h> | |
8 | #include <dm.h> | |
9 | #include <errno.h> | |
704e040a | 10 | #include <memalign.h> |
f6aa61d5 ZZ |
11 | #include <nvme.h> |
12 | #include "nvme.h" | |
13 | ||
14 | static void print_optional_admin_cmd(u16 oacs, int devnum) | |
15 | { | |
16 | printf("Blk device %d: Optional Admin Command Support:\n", | |
17 | devnum); | |
18 | printf("\tNamespace Management/Attachment: %s\n", | |
19 | oacs & 0x08 ? "yes" : "no"); | |
20 | printf("\tFirmware Commit/Image download: %s\n", | |
21 | oacs & 0x04 ? "yes" : "no"); | |
22 | printf("\tFormat NVM: %s\n", | |
23 | oacs & 0x02 ? "yes" : "no"); | |
24 | printf("\tSecurity Send/Receive: %s\n", | |
25 | oacs & 0x01 ? "yes" : "no"); | |
26 | } | |
27 | ||
28 | static void print_optional_nvm_cmd(u16 oncs, int devnum) | |
29 | { | |
30 | printf("Blk device %d: Optional NVM Command Support:\n", | |
31 | devnum); | |
32 | printf("\tReservation: %s\n", | |
33 | oncs & 0x10 ? "yes" : "no"); | |
34 | printf("\tSave/Select field in the Set/Get features: %s\n", | |
35 | oncs & 0x08 ? "yes" : "no"); | |
36 | printf("\tWrite Zeroes: %s\n", | |
37 | oncs & 0x04 ? "yes" : "no"); | |
38 | printf("\tDataset Management: %s\n", | |
39 | oncs & 0x02 ? "yes" : "no"); | |
40 | printf("\tWrite Uncorrectable: %s\n", | |
41 | oncs & 0x01 ? "yes" : "no"); | |
42 | } | |
43 | ||
44 | static void print_format_nvme_attributes(u8 fna, int devnum) | |
45 | { | |
46 | printf("Blk device %d: Format NVM Attributes:\n", devnum); | |
47 | printf("\tSupport Cryptographic Erase: %s\n", | |
48 | fna & 0x04 ? "yes" : "No"); | |
49 | printf("\tSupport erase a particular namespace: %s\n", | |
50 | fna & 0x02 ? "No" : "Yes"); | |
51 | printf("\tSupport format a particular namespace: %s\n", | |
52 | fna & 0x01 ? "No" : "Yes"); | |
53 | } | |
54 | ||
55 | static void print_format(struct nvme_lbaf *lbaf) | |
56 | { | |
57 | u8 str[][10] = {"Best", "Better", "Good", "Degraded"}; | |
58 | ||
59 | printf("\t\tMetadata Size: %d\n", le16_to_cpu(lbaf->ms)); | |
60 | printf("\t\tLBA Data Size: %d\n", 1 << lbaf->ds); | |
61 | printf("\t\tRelative Performance: %s\n", str[lbaf->rp & 0x03]); | |
62 | } | |
63 | ||
64 | static void print_formats(struct nvme_id_ns *id, struct nvme_ns *ns) | |
65 | { | |
66 | int i; | |
67 | ||
68 | printf("Blk device %d: LBA Format Support:\n", ns->devnum); | |
69 | ||
70 | for (i = 0; i < id->nlbaf; i++) { | |
71 | printf("\tLBA Foramt %d Support: ", i); | |
72 | if (i == ns->flbas) | |
73 | printf("(current)\n"); | |
74 | else | |
75 | printf("\n"); | |
76 | print_format(id->lbaf + i); | |
77 | } | |
78 | } | |
79 | ||
80 | static void print_data_protect_cap(u8 dpc, int devnum) | |
81 | { | |
82 | printf("Blk device %d: End-to-End Data", devnum); | |
83 | printf("Protect Capabilities:\n"); | |
84 | printf("\tAs last eight bytes: %s\n", | |
85 | dpc & 0x10 ? "yes" : "No"); | |
86 | printf("\tAs first eight bytes: %s\n", | |
87 | dpc & 0x08 ? "yes" : "No"); | |
88 | printf("\tSupport Type3: %s\n", | |
89 | dpc & 0x04 ? "yes" : "No"); | |
90 | printf("\tSupport Type2: %s\n", | |
91 | dpc & 0x02 ? "yes" : "No"); | |
92 | printf("\tSupport Type1: %s\n", | |
93 | dpc & 0x01 ? "yes" : "No"); | |
94 | } | |
95 | ||
96 | static void print_metadata_cap(u8 mc, int devnum) | |
97 | { | |
98 | printf("Blk device %d: Metadata capabilities:\n", devnum); | |
99 | printf("\tAs part of a separate buffer: %s\n", | |
100 | mc & 0x02 ? "yes" : "No"); | |
101 | printf("\tAs part of an extended data LBA: %s\n", | |
102 | mc & 0x01 ? "yes" : "No"); | |
103 | } | |
104 | ||
105 | int nvme_print_info(struct udevice *udev) | |
106 | { | |
107 | struct nvme_ns *ns = dev_get_priv(udev); | |
108 | struct nvme_dev *dev = ns->dev; | |
d17ab6e1 T |
109 | struct nvme_id_ctrl *ctrl; |
110 | struct nvme_id_ns *id; | |
111 | int ret = 0; | |
f6aa61d5 | 112 | |
d17ab6e1 T |
113 | ctrl = memalign(dev->page_size, sizeof(struct nvme_id_ctrl)); |
114 | if (!ctrl) | |
115 | return -ENOMEM; | |
116 | ||
117 | if (nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl)) { | |
118 | ret = -EIO; | |
119 | goto free_ctrl; | |
120 | } | |
f6aa61d5 ZZ |
121 | |
122 | print_optional_admin_cmd(le16_to_cpu(ctrl->oacs), ns->devnum); | |
123 | print_optional_nvm_cmd(le16_to_cpu(ctrl->oncs), ns->devnum); | |
124 | print_format_nvme_attributes(ctrl->fna, ns->devnum); | |
125 | ||
d17ab6e1 T |
126 | id = memalign(dev->page_size, sizeof(struct nvme_id_ns)); |
127 | if (!id) { | |
128 | ret = -ENOMEM; | |
129 | goto free_ctrl; | |
130 | } | |
131 | ||
132 | if (nvme_identify(dev, ns->ns_id, 0, (dma_addr_t)(long)id)) { | |
133 | ret = -EIO; | |
134 | goto free_id; | |
135 | } | |
f6aa61d5 ZZ |
136 | |
137 | print_formats(id, ns); | |
138 | print_data_protect_cap(id->dpc, ns->devnum); | |
139 | print_metadata_cap(id->mc, ns->devnum); | |
140 | ||
d17ab6e1 T |
141 | free_id: |
142 | free(id); | |
143 | free_ctrl: | |
144 | free(ctrl); | |
145 | return ret; | |
f6aa61d5 | 146 | } |