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:
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to