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