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>