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 Reviewed by: scottl@, rpokala@ Differential Revision: https://reviews.freebsd.org/D20950
This commit is contained in:
parent
32451fb9fc
commit
d455c0d04a
@ -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
|
||||
@ -2516,6 +2519,26 @@ option.
|
||||
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.
|
||||
.El
|
||||
|
@ -109,6 +109,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 {
|
||||
@ -217,6 +218,7 @@ static struct camcontrol_opts option_table[] = {
|
||||
{"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
|
||||
{"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts},
|
||||
{"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"},
|
||||
{"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""},
|
||||
{"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL},
|
||||
{"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"},
|
||||
{"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"},
|
||||
@ -263,11 +265,22 @@ 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);
|
||||
static int getdevlist(struct cam_device *device);
|
||||
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);
|
||||
@ -653,6 +666,24 @@ getdevtree(int argc, char **argv, char *combinedopt)
|
||||
return (error);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -5351,7 +5382,7 @@ get_device_type(struct cam_device *dev, int retry_count, int timeout,
|
||||
int verbosemode, camcontrol_devtype *devtype)
|
||||
{
|
||||
struct ccb_getdev cgd;
|
||||
int retval = 0;
|
||||
int retval;
|
||||
|
||||
retval = get_cgd(dev, &cgd);
|
||||
if (retval != 0)
|
||||
@ -5380,21 +5411,34 @@ get_device_type(struct cam_device *dev, int retry_count, int timeout,
|
||||
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:
|
||||
@ -9620,6 +9664,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"
|
||||
" camcontrol help\n");
|
||||
if (!printlong)
|
||||
@ -9665,6 +9710,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"
|
||||
@ -10128,6 +10174,9 @@ main(int argc, char **argv)
|
||||
case CAM_CMD_DEVTREE:
|
||||
error = getdevtree(argc, argv, combinedopt);
|
||||
break;
|
||||
case CAM_CMD_DEVTYPE:
|
||||
error = getdevtype(cam_dev);
|
||||
break;
|
||||
case CAM_CMD_TUR:
|
||||
error = testunitready(cam_dev, task_attr, retry_count,
|
||||
timeout, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user