Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Aug 2019 02:20:43 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r350728 - stable/12/sbin/camcontrol
Message-ID:  <201908080220.x782KhTI032239@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Aug  8 02:20:42 2019
New Revision: 350728
URL: https://svnweb.freebsd.org/changeset/base/350728

Log:
  MFC r350018: Implement a devtype command.
  
  List the device's protocol. The returned value is one of the following:
          ata     direct attach ATA or SATA device
          satl    a SATA device attached via SAS
          scsi    A parallel SCSI or SAS
          nvme    A direct attached NVMe device
          mmcsd   A MMC or SD attached device

Modified:
  stable/12/sbin/camcontrol/camcontrol.8
  stable/12/sbin/camcontrol/camcontrol.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sbin/camcontrol/camcontrol.8
==============================================================================
--- stable/12/sbin/camcontrol/camcontrol.8	Thu Aug  8 02:18:14 2019	(r350727)
+++ stable/12/sbin/camcontrol/camcontrol.8	Thu Aug  8 02:20:42 2019	(r350728)
@@ -353,6 +353,9 @@
 .Op generic args
 .Ao Fl r Oo Ns Fl f Ar format | Fl m | Fl U Oc | Fl s Ao Fl f Ar format Fl T Ar time | Fl U Ac Ac
 .Nm
+.Ic devtype
+.Op device id
+.Nm
 .Ic help
 .Sh DESCRIPTION
 The
@@ -2515,6 +2518,26 @@ option.
 .It Fl U
 Set the timestamp to the host system's time in UTC.
 .El
+.El
+.It Ic devtype
+Print out the device type for specified device.
+.Bl -tag -width 10n
+.It ata
+An ATA device attached directly to an ATA controller
+.It satl
+An SATA device attached behind a SAS controller via SCSI-ATA Translation Layer (SATL)
+.It scsi
+A SCSI device
+.It nvme
+An directly attached NVMe device
+.It mmcsd
+An MMC or SD device attached via a mmcsd bus
+.It none
+No device type reported
+.It unknown
+Device type is unknown
+.It illegal
+A programming error occurred
 .El
 .It Ic help
 Print out verbose usage information.

Modified: stable/12/sbin/camcontrol/camcontrol.c
==============================================================================
--- stable/12/sbin/camcontrol/camcontrol.c	Thu Aug  8 02:18:14 2019	(r350727)
+++ stable/12/sbin/camcontrol/camcontrol.c	Thu Aug  8 02:20:42 2019	(r350728)
@@ -111,6 +111,7 @@ typedef enum {
 	CAM_CMD_TIMESTAMP	= 0x00000028,
 	CAM_CMD_MMCSD_CMD	= 0x00000029,
 	CAM_CMD_POWER_MODE	= 0x0000002a,
+	CAM_CMD_DEVTYPE		= 0x0000002b,
 } cam_cmdmask;
 
 typedef enum {
@@ -225,6 +226,7 @@ static struct camcontrol_opts option_table[] = {
 	{"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
 #endif /* MINIMALISTIC */
 	{"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
+	{"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
 #ifndef MINIMALISTIC
 	{"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
 	{"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
@@ -273,6 +275,16 @@ struct cam_devlist {
 static cam_cmdmask cmdlist;
 static cam_argmask arglist;
 
+static const char *devtype_names[] = {
+	"none",
+	"scsi",
+	"satl",
+	"ata",
+	"nvme",
+	"mmcsd",
+	"unknown",
+};
+
 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg,
 			    uint32_t *cmdnum, cam_argmask *argnum,
 			    const char **subopt);
@@ -280,6 +292,7 @@ camcontrol_optret getoption(struct camcontrol_opts *ta
 static int getdevlist(struct cam_device *device);
 #endif /* MINIMALISTIC */
 static int getdevtree(int argc, char **argv, char *combinedopt);
+static int getdevtype(struct cam_device *device);
 static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr);
 static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr);
 static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr);
@@ -672,6 +685,24 @@ getdevtree(int argc, char **argv, char *combinedopt)
 }
 
 static int
+getdevtype(struct cam_device *cam_dev)
+{
+	camcontrol_devtype dt;
+	int error;
+
+	/*
+	 * Get the device type and report it, request no I/O be done to do this.
+	 */
+	error = get_device_type(cam_dev, -1, 0, 0, &dt);
+	if (error != 0 || dt < CC_DT_NONE || dt > CC_DT_UNKNOWN) {
+		fprintf(stdout, "illegal\n");
+		return (1);
+	}
+	fprintf(stdout, "%s\n", devtype_names[dt]);
+	return (0);
+}
+
+static int
 print_dev_scsi(struct device_match_result *dev_result, char *tmpstr)
 {
 	char vendor[16], product[48], revision[16];
@@ -5376,7 +5407,7 @@ get_device_type(struct cam_device *dev, int retry_coun
 		    int verbosemode, camcontrol_devtype *devtype)
 {
 	struct ccb_getdev cgd;
-	int retval = 0;
+	int retval;
 
 	retval = get_cgd(dev, &cgd);
 	if (retval != 0)
@@ -5405,21 +5436,34 @@ get_device_type(struct cam_device *dev, int retry_coun
 		break; /*NOTREACHED*/
 	}
 
-	/*
-	 * Check for the ATA Information VPD page (0x89).  If this is an
-	 * ATA device behind a SCSI to ATA translation layer, this VPD page
-	 * should be present.
-	 *
-	 * If that VPD page isn't present, or we get an error back from the
-	 * INQUIRY command, we'll just treat it as a normal SCSI device.
-	 */
-	retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
-				  timeout, verbosemode);
-	if (retval == 1)
-		*devtype = CC_DT_SATL;
-	else
-		*devtype = CC_DT_SCSI;
-
+	if (retry_count == -1) {
+		/*
+		 * For a retry count of -1, used only the cached data to avoid
+		 * I/O to the drive. Sending the identify command to the drive
+		 * can cause issues for SATL attachaed drives since identify is
+		 * not an NCQ command.
+		 */
+		if (cgd.ident_data.config != 0)
+			*devtype = CC_DT_SATL;
+		else
+			*devtype = CC_DT_SCSI;
+	} else {
+		/*
+		 * Check for the ATA Information VPD page (0x89).  If this is an
+		 * ATA device behind a SCSI to ATA translation layer (SATL),
+		 * this VPD page should be present.
+		 *
+		 * If that VPD page isn't present, or we get an error back from
+		 * the INQUIRY command, we'll just treat it as a normal SCSI
+		 * device.
+		 */
+		retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
+		    timeout, verbosemode);
+		if (retval == 1)
+			*devtype = CC_DT_SATL;
+		else
+			*devtype = CC_DT_SCSI;
+	}
 	retval = 0;
 
 bailout:
@@ -9648,6 +9692,7 @@ usage(int printlong)
 "                              [-S power_src] [-T timer]\n"
 "        camcontrol timestamp  [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
 "                              <-s <-f format -T time | -U >>\n"
+"        camcontrol devtype    [dev_id]\n"
 "                              \n"
 #endif /* MINIMALISTIC */
 "        camcontrol help\n");
@@ -9695,6 +9740,7 @@ usage(int printlong)
 "zone        manage Zoned Block (Shingled) devices\n"
 "epc         send ATA Extended Power Conditions commands\n"
 "timestamp   report or set the device's timestamp\n"
+"devtype     report the type of device\n"
 "help        this message\n"
 "Device Identifiers:\n"
 "bus:target        specify the bus and target, lun defaults to 0\n"
@@ -10166,6 +10212,9 @@ main(int argc, char **argv)
 #endif /* MINIMALISTIC */
 	case CAM_CMD_DEVTREE:
 		error = getdevtree(argc, argv, combinedopt);
+		break;
+	case CAM_CMD_DEVTYPE:
+		error = getdevtype(cam_dev);
 		break;
 #ifndef MINIMALISTIC
 	case CAM_CMD_TUR:



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