Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Jun 2013 23:00:43 +0000 (UTC)
From:      Jim Harris <jimharris@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r252266 - head/sbin/nvmecontrol
Message-ID:  <201306262300.r5QN0hu8097400@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jimharris
Date: Wed Jun 26 23:00:42 2013
New Revision: 252266
URL: http://svnweb.freebsd.org/changeset/base/252266

Log:
  Break out code related to the identify command into a separate source file.
  
  Sponsored by:	Intel
  MFC after:	3 days

Added:
  head/sbin/nvmecontrol/identify.c   (contents, props changed)
Modified:
  head/sbin/nvmecontrol/Makefile
  head/sbin/nvmecontrol/nvmecontrol.c
  head/sbin/nvmecontrol/nvmecontrol.h

Modified: head/sbin/nvmecontrol/Makefile
==============================================================================
--- head/sbin/nvmecontrol/Makefile	Wed Jun 26 22:58:59 2013	(r252265)
+++ head/sbin/nvmecontrol/Makefile	Wed Jun 26 23:00:42 2013	(r252266)
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 PROG=	nvmecontrol
-SRCS=	nvmecontrol.c devlist.c
+SRCS=	nvmecontrol.c devlist.c identify.c
 MAN=	nvmecontrol.8
 
 .include <bsd.prog.mk>

Added: head/sbin/nvmecontrol/identify.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sbin/nvmecontrol/identify.c	Wed Jun 26 23:00:42 2013	(r252266)
@@ -0,0 +1,321 @@
+/*-
+ * Copyright (C) 2012-2013 Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include "nvmecontrol.h"
+
+static void
+print_controller_hex(struct nvme_controller_data *cdata, uint32_t length)
+{
+	uint32_t	*p;
+	uint32_t	i, j;
+
+	p = (uint32_t *)cdata;
+	length /= sizeof(uint32_t);
+
+	for (i = 0; i < length; i+=8) {
+		printf("%03x: ", i*4);
+		for (j = 0; j < 8; j++)
+			printf("%08x ", p[i+j]);
+		printf("\n");
+	}
+
+	printf("\n");
+}
+
+static void
+print_controller(struct nvme_controller_data *cdata)
+{
+	printf("Controller Capabilities/Features\n");
+	printf("================================\n");
+	printf("Vendor ID:                  %04x\n", cdata->vid);
+	printf("Subsystem Vendor ID:        %04x\n", cdata->ssvid);
+	printf("Serial Number:              %s\n", cdata->sn);
+	printf("Model Number:               %s\n", cdata->mn);
+	printf("Firmware Version:           %s\n", cdata->fr);
+	printf("Recommended Arb Burst:      %d\n", cdata->rab);
+	printf("IEEE OUI Identifier:        %02x %02x %02x\n",
+		cdata->ieee[0], cdata->ieee[1], cdata->ieee[2]);
+	printf("Multi-Interface Cap:        %02x\n", cdata->mic);
+	/* TODO: Use CAP.MPSMIN to determine true memory page size. */
+	printf("Max Data Transfer Size:     ");
+	if (cdata->mdts == 0)
+		printf("Unlimited\n");
+	else
+		printf("%d\n", PAGE_SIZE * (1 << cdata->mdts));
+	printf("\n");
+
+	printf("Admin Command Set Attributes\n");
+	printf("============================\n");
+	printf("Security Send/Receive:       %s\n",
+		cdata->oacs.security ? "Supported" : "Not Supported");
+	printf("Format NVM:                  %s\n",
+		cdata->oacs.format ? "Supported" : "Not Supported");
+	printf("Firmware Activate/Download:  %s\n",
+		cdata->oacs.firmware ? "Supported" : "Not Supported");
+	printf("Abort Command Limit:         %d\n", cdata->acl+1);
+	printf("Async Event Request Limit:   %d\n", cdata->aerl+1);
+	printf("Number of Firmware Slots:    ");
+	if (cdata->oacs.firmware != 0)
+		printf("%d\n", cdata->frmw.num_slots);
+	else
+		printf("N/A\n");
+	printf("Firmware Slot 1 Read-Only:   ");
+	if (cdata->oacs.firmware != 0)
+		printf("%s\n", cdata->frmw.slot1_ro ? "Yes" : "No");
+	else
+		printf("N/A\n");
+	printf("Per-Namespace SMART Log:     %s\n",
+		cdata->lpa.ns_smart ? "Yes" : "No");
+	printf("Error Log Page Entries:      %d\n", cdata->elpe+1);
+	printf("Number of Power States:      %d\n", cdata->npss+1);
+	printf("\n");
+
+	printf("NVM Command Set Attributes\n");
+	printf("==========================\n");
+	printf("Submission Queue Entry Size\n");
+	printf("  Max:                       %d\n", 1 << cdata->sqes.max);
+	printf("  Min:                       %d\n", 1 << cdata->sqes.min);
+	printf("Completion Queue Entry Size\n");
+	printf("  Max:                       %d\n", 1 << cdata->cqes.max);
+	printf("  Min:                       %d\n", 1 << cdata->cqes.min);
+	printf("Number of Namespaces:        %d\n", cdata->nn);
+	printf("Compare Command:             %s\n",
+		cdata->oncs.compare ? "Supported" : "Not Supported");
+	printf("Write Uncorrectable Command: %s\n",
+		cdata->oncs.write_unc ? "Supported" : "Not Supported");
+	printf("Dataset Management Command:  %s\n",
+		cdata->oncs.dsm ? "Supported" : "Not Supported");
+	printf("Volatile Write Cache:        %s\n",
+		cdata->vwc.present ? "Present" : "Not Present");
+}
+
+static void
+print_namespace_hex(struct nvme_namespace_data *nsdata, uint32_t length)
+{
+	uint32_t	*p;
+	uint32_t	i, j;
+
+	p = (uint32_t *)nsdata;
+	length /= sizeof(uint32_t);
+
+	for (i = 0; i < length; i+=8) {
+		printf("%03x: ", i*4);
+		for (j = 0; j < 8; j++)
+			printf("%08x ", p[i+j]);
+		printf("\n");
+	}
+
+	printf("\n");
+}
+
+static void
+print_namespace(struct nvme_namespace_data *nsdata)
+{
+	uint32_t	i;
+
+	printf("Size (in LBAs):              %lld (%lldM)\n",
+		(long long)nsdata->nsze,
+		(long long)nsdata->nsze / 1024 / 1024);
+	printf("Capacity (in LBAs):          %lld (%lldM)\n",
+		(long long)nsdata->ncap,
+		(long long)nsdata->ncap / 1024 / 1024);
+	printf("Utilization (in LBAs):       %lld (%lldM)\n",
+		(long long)nsdata->nuse,
+		(long long)nsdata->nuse / 1024 / 1024);
+	printf("Thin Provisioning:           %s\n",
+		nsdata->nsfeat.thin_prov ? "Supported" : "Not Supported");
+	printf("Number of LBA Formats:       %d\n", nsdata->nlbaf+1);
+	printf("Current LBA Format:          LBA Format #%d\n",
+		nsdata->flbas.format);
+	for (i = 0; i <= nsdata->nlbaf; i++) {
+		printf("LBA Format #%d:\n", i);
+		printf("  LBA Data Size:             %d\n",
+			1 << nsdata->lbaf[i].lbads);
+	}
+}
+
+static void
+identify_usage(void)
+{
+	fprintf(stderr, "usage:\n");
+	fprintf(stderr, IDENTIFY_USAGE);
+	exit(EX_USAGE);
+}
+
+static void
+identify_ctrlr(int argc, char *argv[])
+{
+	struct nvme_controller_data	cdata;
+	int				ch, fd, hexflag = 0, hexlength;
+	int				verboseflag = 0;
+
+	while ((ch = getopt(argc, argv, "vx")) != -1) {
+		switch ((char)ch) {
+		case 'v':
+			verboseflag = 1;
+			break;
+		case 'x':
+			hexflag = 1;
+			break;
+		default:
+			identify_usage();
+		}
+	}
+
+	open_dev(argv[optind], &fd, 1, 1);
+	read_controller_data(fd, &cdata);
+	close(fd);
+
+	if (hexflag == 1) {
+		if (verboseflag == 1)
+			hexlength = sizeof(struct nvme_controller_data);
+		else
+			hexlength = offsetof(struct nvme_controller_data,
+			    reserved5);
+		print_controller_hex(&cdata, hexlength);
+		exit(EX_OK);
+	}
+
+	if (verboseflag == 1) {
+		printf("-v not currently supported without -x.\n");
+		identify_usage();
+	}
+
+	print_controller(&cdata);
+	exit(EX_OK);
+}
+
+static void
+identify_ns(int argc, char *argv[])
+{
+	struct nvme_namespace_data	nsdata;
+	char				path[64];
+	char				*nsloc;
+	int				ch, fd, hexflag = 0, hexlength, nsid;
+	int				verboseflag = 0;
+
+	while ((ch = getopt(argc, argv, "vx")) != -1) {
+		switch ((char)ch) {
+		case 'v':
+			verboseflag = 1;
+			break;
+		case 'x':
+			hexflag = 1;
+			break;
+		default:
+			identify_usage();
+		}
+	}
+
+	/*
+	 * Check if the specified device node exists before continuing.
+	 *  This is a cleaner check for cases where the correct controller
+	 *  is specified, but an invalid namespace on that controller.
+	 */
+	open_dev(argv[optind], &fd, 1, 1);
+	close(fd);
+
+	/*
+	 * Pull the namespace id from the string. +2 skips past the "ns" part
+	 *  of the string.  Don't search past 10 characters into the string,
+	 *  otherwise we know it is malformed.
+	 */
+	nsloc = strnstr(argv[optind], "ns", 10);
+	if (nsloc != NULL)
+		nsid = strtol(nsloc + 2, NULL, 10);
+	if (nsloc == NULL || (nsid == 0 && errno != 0)) {
+		printf("Invalid namespace ID %s.\n", argv[optind]);
+		exit(EX_IOERR);
+	}
+
+	/*
+	 * We send IDENTIFY commands to the controller, not the namespace,
+	 *  since it is an admin cmd.  So the path should only include the
+	 *  nvmeX part of the nvmeXnsY string.
+	 */
+	snprintf(path, nsloc - argv[optind] + 1, "%s", argv[optind]);
+	open_dev(path, &fd, 1, 1);
+	read_namespace_data(fd, nsid, &nsdata);
+	close(fd);
+
+	if (hexflag == 1) {
+		if (verboseflag == 1)
+			hexlength = sizeof(struct nvme_namespace_data);
+		else
+			hexlength = offsetof(struct nvme_namespace_data,
+			    reserved6);
+		print_namespace_hex(&nsdata, hexlength);
+		exit(EX_OK);
+	}
+
+	if (verboseflag == 1) {
+		printf("-v not currently supported without -x.\n");
+		identify_usage();
+	}
+
+	print_namespace(&nsdata);
+	exit(EX_OK);
+}
+
+void
+identify(int argc, char *argv[])
+{
+	char	*target;
+
+	if (argc < 2)
+		identify_usage();
+
+	while (getopt(argc, argv, "vx") != -1) ;
+
+	target = argv[optind];
+
+	optreset = 1;
+	optind = 1;
+
+	/*
+	 * If device node contains "ns", we consider it a namespace,
+	 *  otherwise, consider it a controller.
+	 */
+	if (strstr(target, "ns") == NULL)
+		identify_ctrlr(argc, argv);
+	else
+		identify_ns(argc, argv);
+}

Modified: head/sbin/nvmecontrol/nvmecontrol.c
==============================================================================
--- head/sbin/nvmecontrol/nvmecontrol.c	Wed Jun 26 22:58:59 2013	(r252265)
+++ head/sbin/nvmecontrol/nvmecontrol.c	Wed Jun 26 23:00:42 2013	(r252266)
@@ -57,137 +57,6 @@ usage(void)
 	exit(EX_USAGE);
 }
 
-static void
-print_controller_hex(struct nvme_controller_data *cdata, uint32_t length)
-{
-	uint32_t	*p;
-	uint32_t	i, j;
-
-	p = (uint32_t *)cdata;
-	length /= sizeof(uint32_t);
-
-	for (i = 0; i < length; i+=8) {
-		printf("%03x: ", i*4);
-		for (j = 0; j < 8; j++)
-			printf("%08x ", p[i+j]);
-		printf("\n");
-	}
-
-	printf("\n");
-}
-
-static void
-print_controller(struct nvme_controller_data *cdata)
-{
-	printf("Controller Capabilities/Features\n");
-	printf("================================\n");
-	printf("Vendor ID:                  %04x\n", cdata->vid);
-	printf("Subsystem Vendor ID:        %04x\n", cdata->ssvid);
-	printf("Serial Number:              %s\n", cdata->sn);
-	printf("Model Number:               %s\n", cdata->mn);
-	printf("Firmware Version:           %s\n", cdata->fr);
-	printf("Recommended Arb Burst:      %d\n", cdata->rab);
-	printf("IEEE OUI Identifier:        %02x %02x %02x\n",
-		cdata->ieee[0], cdata->ieee[1], cdata->ieee[2]);
-	printf("Multi-Interface Cap:        %02x\n", cdata->mic);
-	/* TODO: Use CAP.MPSMIN to determine true memory page size. */
-	printf("Max Data Transfer Size:     ");
-	if (cdata->mdts == 0)
-		printf("Unlimited\n");
-	else
-		printf("%d\n", PAGE_SIZE * (1 << cdata->mdts));
-	printf("\n");
-
-	printf("Admin Command Set Attributes\n");
-	printf("============================\n");
-	printf("Security Send/Receive:       %s\n",
-		cdata->oacs.security ? "Supported" : "Not Supported");
-	printf("Format NVM:                  %s\n",
-		cdata->oacs.format ? "Supported" : "Not Supported");
-	printf("Firmware Activate/Download:  %s\n",
-		cdata->oacs.firmware ? "Supported" : "Not Supported");
-	printf("Abort Command Limit:         %d\n", cdata->acl+1);
-	printf("Async Event Request Limit:   %d\n", cdata->aerl+1);
-	printf("Number of Firmware Slots:    ");
-	if (cdata->oacs.firmware != 0)
-		printf("%d\n", cdata->frmw.num_slots);
-	else
-		printf("N/A\n");
-	printf("Firmware Slot 1 Read-Only:   ");
-	if (cdata->oacs.firmware != 0)
-		printf("%s\n", cdata->frmw.slot1_ro ? "Yes" : "No");
-	else
-		printf("N/A\n");
-	printf("Per-Namespace SMART Log:     %s\n",
-		cdata->lpa.ns_smart ? "Yes" : "No");
-	printf("Error Log Page Entries:      %d\n", cdata->elpe+1);
-	printf("Number of Power States:      %d\n", cdata->npss+1);
-	printf("\n");
-
-	printf("NVM Command Set Attributes\n");
-	printf("==========================\n");
-	printf("Submission Queue Entry Size\n");
-	printf("  Max:                       %d\n", 1 << cdata->sqes.max);
-	printf("  Min:                       %d\n", 1 << cdata->sqes.min);
-	printf("Completion Queue Entry Size\n");
-	printf("  Max:                       %d\n", 1 << cdata->cqes.max);
-	printf("  Min:                       %d\n", 1 << cdata->cqes.min);
-	printf("Number of Namespaces:        %d\n", cdata->nn);
-	printf("Compare Command:             %s\n",
-		cdata->oncs.compare ? "Supported" : "Not Supported");
-	printf("Write Uncorrectable Command: %s\n",
-		cdata->oncs.write_unc ? "Supported" : "Not Supported");
-	printf("Dataset Management Command:  %s\n",
-		cdata->oncs.dsm ? "Supported" : "Not Supported");
-	printf("Volatile Write Cache:        %s\n",
-		cdata->vwc.present ? "Present" : "Not Present");
-}
-
-static void
-print_namespace_hex(struct nvme_namespace_data *nsdata, uint32_t length)
-{
-	uint32_t	*p;
-	uint32_t	i, j;
-
-	p = (uint32_t *)nsdata;
-	length /= sizeof(uint32_t);
-
-	for (i = 0; i < length; i+=8) {
-		printf("%03x: ", i*4);
-		for (j = 0; j < 8; j++)
-			printf("%08x ", p[i+j]);
-		printf("\n");
-	}
-
-	printf("\n");
-}
-
-static void
-print_namespace(struct nvme_namespace_data *nsdata)
-{
-	uint32_t	i;
-
-	printf("Size (in LBAs):              %lld (%lldM)\n",
-		(long long)nsdata->nsze,
-		(long long)nsdata->nsze / 1024 / 1024);
-	printf("Capacity (in LBAs):          %lld (%lldM)\n",
-		(long long)nsdata->ncap,
-		(long long)nsdata->ncap / 1024 / 1024);
-	printf("Utilization (in LBAs):       %lld (%lldM)\n",
-		(long long)nsdata->nuse,
-		(long long)nsdata->nuse / 1024 / 1024);
-	printf("Thin Provisioning:           %s\n",
-		nsdata->nsfeat.thin_prov ? "Supported" : "Not Supported");
-	printf("Number of LBA Formats:       %d\n", nsdata->nlbaf+1);
-	printf("Current LBA Format:          LBA Format #%d\n",
-		nsdata->flbas.format);
-	for (i = 0; i <= nsdata->nlbaf; i++) {
-		printf("LBA Format #%d:\n", i);
-		printf("  LBA Data Size:             %d\n",
-			1 << nsdata->lbaf[i].lbads);
-	}
-}
-
 void
 read_controller_data(int fd, struct nvme_controller_data *cdata)
 {
@@ -267,154 +136,6 @@ open_dev(const char *str, int *fd, int s
 }
 
 static void
-identify_usage(void)
-{
-	fprintf(stderr, "usage:\n");
-	fprintf(stderr, IDENTIFY_USAGE);
-	exit(EX_USAGE);
-}
-
-static void
-identify_ctrlr(int argc, char *argv[])
-{
-	struct nvme_controller_data	cdata;
-	int				ch, fd, hexflag = 0, hexlength;
-	int				verboseflag = 0;
-
-	while ((ch = getopt(argc, argv, "vx")) != -1) {
-		switch ((char)ch) {
-		case 'v':
-			verboseflag = 1;
-			break;
-		case 'x':
-			hexflag = 1;
-			break;
-		default:
-			identify_usage();
-		}
-	}
-
-	open_dev(argv[optind], &fd, 1, 1);
-	read_controller_data(fd, &cdata);
-	close(fd);
-
-	if (hexflag == 1) {
-		if (verboseflag == 1)
-			hexlength = sizeof(struct nvme_controller_data);
-		else
-			hexlength = offsetof(struct nvme_controller_data,
-			    reserved5);
-		print_controller_hex(&cdata, hexlength);
-		exit(EX_OK);
-	}
-
-	if (verboseflag == 1) {
-		printf("-v not currently supported without -x.\n");
-		identify_usage();
-	}
-
-	print_controller(&cdata);
-	exit(EX_OK);
-}
-
-static void
-identify_ns(int argc, char *argv[])
-{
-	struct nvme_namespace_data	nsdata;
-	char				path[64];
-	char				*nsloc;
-	int				ch, fd, hexflag = 0, hexlength, nsid;
-	int				verboseflag = 0;
-
-	while ((ch = getopt(argc, argv, "vx")) != -1) {
-		switch ((char)ch) {
-		case 'v':
-			verboseflag = 1;
-			break;
-		case 'x':
-			hexflag = 1;
-			break;
-		default:
-			identify_usage();
-		}
-	}
-
-	/*
-	 * Check if the specified device node exists before continuing.
-	 *  This is a cleaner check for cases where the correct controller
-	 *  is specified, but an invalid namespace on that controller.
-	 */
-	open_dev(argv[optind], &fd, 1, 1);
-	close(fd);
-
-	/*
-	 * Pull the namespace id from the string. +2 skips past the "ns" part
-	 *  of the string.  Don't search past 10 characters into the string,
-	 *  otherwise we know it is malformed.
-	 */
-	nsloc = strnstr(argv[optind], "ns", 10);
-	if (nsloc != NULL)
-		nsid = strtol(nsloc + 2, NULL, 10);
-	if (nsloc == NULL || (nsid == 0 && errno != 0)) {
-		printf("Invalid namespace ID %s.\n", argv[optind]);
-		exit(EX_IOERR);
-	}
-
-	/*
-	 * We send IDENTIFY commands to the controller, not the namespace,
-	 *  since it is an admin cmd.  So the path should only include the
-	 *  nvmeX part of the nvmeXnsY string.
-	 */
-	snprintf(path, nsloc - argv[optind] + 1, "%s", argv[optind]);
-	open_dev(path, &fd, 1, 1);
-	read_namespace_data(fd, nsid, &nsdata);
-	close(fd);
-
-	if (hexflag == 1) {
-		if (verboseflag == 1)
-			hexlength = sizeof(struct nvme_namespace_data);
-		else
-			hexlength = offsetof(struct nvme_namespace_data,
-			    reserved6);
-		print_namespace_hex(&nsdata, hexlength);
-		exit(EX_OK);
-	}
-
-	if (verboseflag == 1) {
-		printf("-v not currently supported without -x.\n");
-		identify_usage();
-	}
-
-	print_namespace(&nsdata);
-	exit(EX_OK);
-}
-
-static void
-identify(int argc, char *argv[])
-{
-	char	*target;
-
-	if (argc < 2)
-		identify_usage();
-
-	while (getopt(argc, argv, "vx") != -1) ;
-
-	target = argv[optind];
-
-	optreset = 1;
-	optind = 1;
-
-	/*
-	 * If device node contains "ns", we consider it a namespace,
-	 *  otherwise, consider it a controller.
-	 */
-	if (strstr(target, "ns") == NULL)
-		identify_ctrlr(argc, argv);
-	else
-		identify_ns(argc, argv);
-}
-
-static void
 print_perftest(struct nvme_io_test *io_test, bool perthread)
 {
 	uint32_t i, io_completed = 0, iops, mbps;

Modified: head/sbin/nvmecontrol/nvmecontrol.h
==============================================================================
--- head/sbin/nvmecontrol/nvmecontrol.h	Wed Jun 26 22:58:59 2013	(r252265)
+++ head/sbin/nvmecontrol/nvmecontrol.h	Wed Jun 26 23:00:42 2013	(r252266)
@@ -51,6 +51,7 @@ void read_controller_data(int fd, struct
 void read_namespace_data(int fd, int nsid, struct nvme_namespace_data *nsdata);
 
 void devlist(int argc, char *argv[]);
+void identify(int argc, char *argv[]);
 
 #endif
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201306262300.r5QN0hu8097400>