Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Jun 2018 22:00:08 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r335092 - head/sbin/camcontrol
Message-ID:  <201806132200.w5DM08iB097255@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Wed Jun 13 22:00:08 2018
New Revision: 335092
URL: https://svnweb.freebsd.org/changeset/base/335092

Log:
  Make camcontrol identify work with nda devices
  
  Both ATA and NVME have an identify command. They are completely
  different, but to the user they are the same. Leverage nvmecontrol's
  print_controller code to provide that functionality to camcontrol
  identify. Query the path to see what kind of protocol it supports, and
  send the most appropriate command down. Refactor nvme_print_dev a
  little to make it easy to get the nvme cdata.
  
  Sponsored by: Netflix
  Differential Revision: https://reviews.freebsd.org/D15371

Modified:
  head/sbin/camcontrol/Makefile
  head/sbin/camcontrol/camcontrol.c

Modified: head/sbin/camcontrol/Makefile
==============================================================================
--- head/sbin/camcontrol/Makefile	Wed Jun 13 22:00:02 2018	(r335091)
+++ head/sbin/camcontrol/Makefile	Wed Jun 13 22:00:08 2018	(r335092)
@@ -8,6 +8,11 @@ SRCS+=	attrib.c epc.c fwdownload.c modeedit.c persist.
 .else
 CFLAGS+= -DMINIMALISTIC
 .endif
+.PATH:	${SRCTOP}/sbin/nvmecontrol
+CFLAGS+= -I${SRCTOP}/sbin/nvmecontrol
+SRCS+=	identify_ext.c nc_util.c
+.PATH:	${SRCTOP}/sys/dev/nvme
+SRCS+=	nvme_util.c
 # This is verboten
 .if ${MACHINE_CPUARCH} == "arm"
 WARNS?= 3

Modified: head/sbin/camcontrol/camcontrol.c
==============================================================================
--- head/sbin/camcontrol/camcontrol.c	Wed Jun 13 22:00:02 2018	(r335091)
+++ head/sbin/camcontrol/camcontrol.c	Wed Jun 13 22:00:08 2018	(r335092)
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
 #include <cam/mmc/mmc_all.h>
 #include <camlib.h>
 #include "camcontrol.h"
+#include "nvmecontrol_ext.h"
 
 typedef enum {
 	CAM_CMD_NONE		= 0x00000000,
@@ -763,21 +764,11 @@ print_dev_mmcsd(struct device_match_result *dev_result
 }
 
 static int
-print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
+nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata)
 {
 	union ccb *ccb;
 	struct ccb_dev_advinfo *advi;
-	struct cam_device *dev;
-	struct nvme_controller_data cdata;
-	char vendor[64], product[64];
 
-	dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
-	    dev_result->target_lun, O_RDWR, NULL);
-	if (dev == NULL) {
-		warnx("%s", cam_errbuf);
-		return (1);
-	}
-	
 	ccb = cam_getccb(dev);
 	if (ccb == NULL) {
 		warnx("couldn't allocate CCB");
@@ -791,7 +782,7 @@ print_dev_nvme(struct device_match_result *dev_result,
 	advi->flags = CDAI_FLAG_NONE;
 	advi->buftype = CDAI_TYPE_NVME_CNTRL;
 	advi->bufsiz = sizeof(struct nvme_controller_data);
-	advi->buf = (uint8_t *)&cdata;
+	advi->buf = (uint8_t *)cdata;
 
 	if (cam_send_ccb(dev, ccb) < 0) {
 		warn("error sending CAMIOCOMMAND ioctl");
@@ -805,11 +796,31 @@ print_dev_nvme(struct device_match_result *dev_result,
 		cam_close_device(dev);
 		return(1);
 	}
+	cam_freeccb(ccb);
+	return 0;
+}
+
+static int
+print_dev_nvme(struct device_match_result *dev_result, char *tmpstr)
+{
+	struct cam_device *dev;
+	struct nvme_controller_data cdata;
+	char vendor[64], product[64];
+
+	dev = cam_open_btl(dev_result->path_id, dev_result->target_id,
+	    dev_result->target_lun, O_RDWR, NULL);
+	if (dev == NULL) {
+		warnx("%s", cam_errbuf);
+		return (1);
+	}
+
+	if (nvme_get_cdata(dev, &cdata))
+		return (1);
+
 	cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor));
 	cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product));
 	sprintf(tmpstr, "<%s %s>", vendor, product);
 
-	cam_freeccb(ccb);
 	cam_close_device(dev);
 	return (0);
 }
@@ -2390,6 +2401,34 @@ ataidentify(struct cam_device *device, int retry_count
 
 	return (0);
 }
+
+static int
+nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused)
+{
+	struct nvme_controller_data cdata;
+
+	if (nvme_get_cdata(device, &cdata))
+		return (1);
+	nvme_print_controller(&cdata);
+
+	return (0);
+}
+
+static int
+identify(struct cam_device *device, int retry_count, int timeout)
+{
+	struct ccb_pathinq cpi;
+
+	if (get_cpi(device, &cpi) != 0) {
+		warnx("couldn't get CPI");
+		return (-1);
+	}
+
+	if (cpi.protocol == PROTO_NVME) {
+		return (nvmeidentify(device, retry_count, timeout));
+	}
+	return (ataidentify(device, retry_count, timeout));
+}
 #endif /* MINIMALISTIC */
 
 
@@ -10058,7 +10097,7 @@ main(int argc, char **argv)
 				      task_attr, retry_count, timeout);
 		break;
 	case CAM_CMD_IDENTIFY:
-		error = ataidentify(cam_dev, retry_count, timeout);
+		error = identify(cam_dev, retry_count, timeout);
 		break;
 	case CAM_CMD_STARTSTOP:
 		error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,



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