Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174178802
D59533.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D59533.diff
View Options
diff --git a/sbin/camcontrol/camcontrol.h b/sbin/camcontrol/camcontrol.h
--- a/sbin/camcontrol/camcontrol.h
+++ b/sbin/camcontrol/camcontrol.h
@@ -75,6 +75,8 @@
int get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
uint16_t *count, uint64_t *lba, uint8_t *device,
uint8_t *status);
+int nvme_get_data(struct cam_device *dev, int nvme_data_type, void *data,
+ size_t data_len);
int camxferrate(struct cam_device *device);
int fwdownload(struct cam_device *device, int argc, char **argv,
char *combinedopt, int printerrors, int task_attr,
diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8
--- a/sbin/camcontrol/camcontrol.8
+++ b/sbin/camcontrol/camcontrol.8
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd December 28, 2023
+.Dd August 21, 2026
.Dt CAMCONTROL 8
.Os
.Sh NAME
@@ -67,6 +67,7 @@
.Ic identify
.Op device id
.Op generic args
+.Op Fl N
.Op Fl v
.Nm
.Ic reportluns
@@ -524,7 +525,15 @@
Print out transfer rate information.
.El
.It Ic identify
-Send an ATA identify command (0xec) to a device.
+Send a ATA identify command (0xec) or NVMe identify command to a device.
+For NVMe devices, this displays Identify data cached in the kernel, and
+does not send commands to the drive.
+.Bl -tag -width 8n
+.It Fl N
+Display NVMe Identify Namespace data.
+This shows the capacity of the namespace (CAM peripheral drivers are attached
+to a NVMe namespace) as opposed to the entire drive.
+.El
.It Ic reportluns
Send the SCSI REPORT LUNS (0xA0) command to the given device.
By default,
@@ -2935,6 +2944,7 @@
.Xr pass 4 ,
.Xr xpt 4 ,
.Xr diskinfo 8 ,
+.Xr nvmecontrol 8 ,
.Xr trim 8 ,
.Xr zonectl 8
.Sh HISTORY
diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c
--- a/sbin/camcontrol/camcontrol.c
+++ b/sbin/camcontrol/camcontrol.c
@@ -185,7 +185,7 @@
static struct camcontrol_opts option_table[] = {
{"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL},
{"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"},
- {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL},
+ {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, "N"},
{"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL},
{"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL},
{"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL},
@@ -779,12 +779,35 @@
return (0);
}
-static int
-nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
+int
+nvme_get_data(struct cam_device *dev, int nvme_data_type, void *data,
+ size_t data_len)
{
union ccb *ccb;
+ struct nvme_controller_data *cdata;
+ struct nvme_namespace_data *nsdata;
struct ccb_dev_advinfo *advi;
+ switch (nvme_data_type) {
+ case CDAI_TYPE_NVME_CNTRL:
+ if (data_len != sizeof(*cdata)) {
+ warnx("%s: supplied data length %zu != controller data "
+ "length %zu", __func__, data_len, sizeof(*nsdata));
+ goto bailout_error;
+ }
+ break;
+ case CDAI_TYPE_NVME_NS:
+ if (data_len != sizeof(*nsdata)) {
+ warnx("%s: supplied data length %zu != namespace data "
+ "length %zu", __func__, data_len, sizeof(*nsdata));
+ goto bailout_error;
+ }
+ break;
+ default:
+ warnx("Unknown NVMe data type %d", nvme_data_type);
+ goto bailout_error;
+ }
+
ccb = cam_getccb(dev);
if (ccb == NULL) {
warnx("couldn't allocate CCB");
@@ -792,28 +815,31 @@
return (1);
}
+ CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
advi = &ccb->cdai;
advi->ccb_h.flags = CAM_DIR_IN;
advi->ccb_h.func_code = XPT_DEV_ADVINFO;
advi->flags = CDAI_FLAG_NONE;
- advi->buftype = CDAI_TYPE_NVME_CNTRL;
- advi->bufsiz = sizeof(struct nvme_controller_data);
- advi->buf = (uint8_t *)cdata;
+ advi->buftype = nvme_data_type;
+ advi->bufsiz = data_len;
+ advi->buf = data;
if (cam_send_ccb(dev, ccb) < 0) {
- warn("error sending XPT_DEV_ADVINFO CCB");
+ warn("%s: error sending XPT_DEV_ADVINFO CCB", __func__);
cam_freeccb(ccb);
- cam_close_device(dev);
- return(1);
+ goto bailout_error;
}
- if (advi->ccb_h.status != CAM_REQ_CMP) {
- warnx("got CAM error %#x", advi->ccb_h.status);
+ if ((advi->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ cam_error_print(dev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
cam_freeccb(ccb);
- cam_close_device(dev);
- return(1);
+ goto bailout_error;
}
cam_freeccb(ccb);
return 0;
+
+bailout_error:
+ cam_close_device(dev);
+ return (1);
}
static int
@@ -830,7 +856,7 @@
return (1);
}
- if (nvme_get_cdata(dev, &cdata))
+ if (nvme_get_data(dev, CDAI_TYPE_NVME_CNTRL, &cdata, sizeof(cdata)))
return (1);
cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
@@ -2470,7 +2496,8 @@
static int
-ataidentify(struct cam_device *device, int retry_count, int timeout)
+ataidentify(struct cam_device *device, int argc __unused, char **argv __unused,
+ char *combinedopt __unused, int retry_count, int timeout)
{
union ccb *ccb;
struct ata_params *ident_buf;
@@ -2515,19 +2542,47 @@
}
static int
-nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
+nvmeidentify(struct cam_device *device, int argc, char **argv,
+ char *combinedopt, int retry_count __unused, int timeout __unused)
{
- struct nvme_controller_data cdata;
+ int ns_identify = 0;
+ int c;
- if (nvme_get_cdata(device, &cdata))
- return (1);
- nvme_print_controller(&cdata);
+
+ while ((c = getopt(argc, argv, combinedopt)) != -1) {
+ switch (c) {
+ case 'N':
+ ns_identify = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (ns_identify == 0) {
+ struct nvme_controller_data cdata;
+
+ if (nvme_get_data(device, CDAI_TYPE_NVME_CNTRL, &cdata,
+ sizeof(cdata)))
+ return (1);
+
+ nvme_print_controller(&cdata);
+ } else {
+ struct nvme_namespace_data ns_data;
+
+ if (nvme_get_data(device, CDAI_TYPE_NVME_NS, &ns_data,
+ sizeof(ns_data)))
+ return (1);
+
+ nvme_print_namespace(&ns_data);
+ }
return (0);
}
static int
-identify(struct cam_device *device, int retry_count, int timeout)
+identify(struct cam_device *device, int argc, char **argv, char *combinedopt,
+ int retry_count, int timeout)
{
struct ccb_pathinq cpi;
@@ -2537,9 +2592,12 @@
}
if (cpi.protocol == PROTO_NVME) {
- return (nvmeidentify(device, retry_count, timeout));
+ return (nvmeidentify(device, argc, argv, combinedopt,
+ retry_count, timeout));
+ } else {
+ return (ataidentify(device, argc, argv, combinedopt,
+ retry_count, timeout));
}
- return (ataidentify(device, retry_count, timeout));
}
@@ -10030,7 +10088,7 @@
" camcontrol tur [dev_id][generic args]\n"
" camcontrol sense [dev_id][generic args][-D][-x]\n"
" camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n"
-" camcontrol identify [dev_id][generic args] [-v]\n"
+" camcontrol identify [dev_id][generic args] [-N] [-v]\n"
" camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
" camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
" [-q] [-s] [-l]\n"
@@ -10120,7 +10178,7 @@
"sense send a request sense command to the named device\n"
"tur send a test unit ready to the named device\n"
"inquiry send a SCSI inquiry command to the named device\n"
-"identify send a ATA identify command to the named device\n"
+"identify send a ATA or NVMe identify command to the named device\n"
"reportluns send a SCSI report luns command to the device\n"
"readcap send a SCSI read capacity command to the device\n"
"start send a Start Unit command to the device\n"
@@ -10189,6 +10247,8 @@
"-D get the standard inquiry data\n"
"-S get the serial number\n"
"-R get the transfer rate, etc.\n"
+"identify arguments:\n"
+"-N send identify to the NVMe namespace\n"
"reportluns arguments:\n"
"-c only report a count of available LUNs\n"
"-l only print out luns, and not a count\n"
@@ -10668,7 +10728,8 @@
task_attr, retry_count, timeout);
break;
case CAM_CMD_IDENTIFY:
- error = identify(cam_dev, retry_count, timeout);
+ error = identify(cam_dev, argc, argv, combinedopt, retry_count,
+ timeout);
break;
case CAM_CMD_STARTSTOP:
error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 2, 4:27 AM (7 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40054445
Default Alt Text
D59533.diff (8 KB)
Attached To
Mode
D59533: camcontrol: Add support for NVMe namespace Identify
Attached
Detach File
Event Timeline
Log In to Comment