1/* 2 * Copyright (c) 1997-2007 Kenneth D. Merry 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD$"); 31 32#include <sys/ioctl.h> 33#include <sys/stdint.h> 34#include <sys/types.h> 35#include <sys/stat.h> 36#include <sys/endian.h> 37#include <sys/sbuf.h> 38 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42#include <unistd.h> 43#include <inttypes.h> 44#include <limits.h> 45#include <fcntl.h> 46#include <ctype.h> 47#include <err.h> 48#include <libutil.h> 49#include <limits.h> 50#include <inttypes.h> 51 52#include <cam/cam.h> 53#include <cam/cam_debug.h> 54#include <cam/cam_ccb.h> 55#include <cam/scsi/scsi_all.h> 56#include <cam/scsi/scsi_da.h> 57#include <cam/scsi/scsi_pass.h> 58#include <cam/scsi/scsi_message.h> 59#include <cam/scsi/smp_all.h> 60#include <cam/ata/ata_all.h> 61#include <cam/mmc/mmc_all.h> 62#include <camlib.h> 63#include "camcontrol.h" 64#ifdef WITH_NVME 65#include "nvmecontrol_ext.h" 66#endif 67 68typedef enum { 69 CAM_CMD_NONE = 0x00000000, 70 CAM_CMD_DEVLIST = 0x00000001, 71 CAM_CMD_TUR = 0x00000002, 72 CAM_CMD_INQUIRY = 0x00000003, 73 CAM_CMD_STARTSTOP = 0x00000004, 74 CAM_CMD_RESCAN = 0x00000005, 75 CAM_CMD_READ_DEFECTS = 0x00000006, 76 CAM_CMD_MODE_PAGE = 0x00000007, 77 CAM_CMD_SCSI_CMD = 0x00000008, 78 CAM_CMD_DEVTREE = 0x00000009, 79 CAM_CMD_USAGE = 0x0000000a, 80 CAM_CMD_DEBUG = 0x0000000b, 81 CAM_CMD_RESET = 0x0000000c, 82 CAM_CMD_FORMAT = 0x0000000d, 83 CAM_CMD_TAG = 0x0000000e, 84 CAM_CMD_RATE = 0x0000000f, 85 CAM_CMD_DETACH = 0x00000010, 86 CAM_CMD_REPORTLUNS = 0x00000011, 87 CAM_CMD_READCAP = 0x00000012, 88 CAM_CMD_IDENTIFY = 0x00000013, 89 CAM_CMD_IDLE = 0x00000014, 90 CAM_CMD_STANDBY = 0x00000015, 91 CAM_CMD_SLEEP = 0x00000016, 92 CAM_CMD_SMP_CMD = 0x00000017, 93 CAM_CMD_SMP_RG = 0x00000018, 94 CAM_CMD_SMP_PC = 0x00000019, 95 CAM_CMD_SMP_PHYLIST = 0x0000001a, 96 CAM_CMD_SMP_MANINFO = 0x0000001b, 97 CAM_CMD_DOWNLOAD_FW = 0x0000001c, 98 CAM_CMD_SECURITY = 0x0000001d, 99 CAM_CMD_HPA = 0x0000001e, 100 CAM_CMD_SANITIZE = 0x0000001f, 101 CAM_CMD_PERSIST = 0x00000020, 102 CAM_CMD_APM = 0x00000021, 103 CAM_CMD_AAM = 0x00000022, 104 CAM_CMD_ATTRIB = 0x00000023, 105 CAM_CMD_OPCODES = 0x00000024, 106 CAM_CMD_REPROBE = 0x00000025, 107 CAM_CMD_ZONE = 0x00000026, 108 CAM_CMD_EPC = 0x00000027, 109 CAM_CMD_TIMESTAMP = 0x00000028, 110 CAM_CMD_MMCSD_CMD = 0x00000029, 111 CAM_CMD_POWER_MODE = 0x0000002a, 112 CAM_CMD_DEVTYPE = 0x0000002b, 113 CAM_CMD_AMA = 0x0000002c, 114} cam_cmdmask; 115 116typedef enum { 117 CAM_ARG_NONE = 0x00000000, 118 CAM_ARG_VERBOSE = 0x00000001, 119 CAM_ARG_DEVICE = 0x00000002, 120 CAM_ARG_BUS = 0x00000004, 121 CAM_ARG_TARGET = 0x00000008, 122 CAM_ARG_LUN = 0x00000010, 123 CAM_ARG_EJECT = 0x00000020, 124 CAM_ARG_UNIT = 0x00000040, 125 CAM_ARG_FORMAT_BLOCK = 0x00000080, 126 CAM_ARG_FORMAT_BFI = 0x00000100, 127 CAM_ARG_FORMAT_PHYS = 0x00000200, 128 CAM_ARG_PLIST = 0x00000400, 129 CAM_ARG_GLIST = 0x00000800, 130 CAM_ARG_GET_SERIAL = 0x00001000, 131 CAM_ARG_GET_STDINQ = 0x00002000, 132 CAM_ARG_GET_XFERRATE = 0x00004000, 133 CAM_ARG_INQ_MASK = 0x00007000, 134 CAM_ARG_TIMEOUT = 0x00020000, 135 CAM_ARG_CMD_IN = 0x00040000, 136 CAM_ARG_CMD_OUT = 0x00080000, 137 CAM_ARG_ERR_RECOVER = 0x00200000, 138 CAM_ARG_RETRIES = 0x00400000, 139 CAM_ARG_START_UNIT = 0x00800000, 140 CAM_ARG_DEBUG_INFO = 0x01000000, 141 CAM_ARG_DEBUG_TRACE = 0x02000000, 142 CAM_ARG_DEBUG_SUBTRACE = 0x04000000, 143 CAM_ARG_DEBUG_CDB = 0x08000000, 144 CAM_ARG_DEBUG_XPT = 0x10000000, 145 CAM_ARG_DEBUG_PERIPH = 0x20000000, 146 CAM_ARG_DEBUG_PROBE = 0x40000000, 147} cam_argmask; 148 149struct camcontrol_opts { 150 const char *optname; 151 uint32_t cmdnum; 152 cam_argmask argnum; 153 const char *subopt; 154}; 155 156struct ata_set_max_pwd 157{ 158 u_int16_t reserved1; 159 u_int8_t password[32]; 160 u_int16_t reserved2[239]; 161}; 162 163static struct scsi_nv task_attrs[] = { 164 { "simple", MSG_SIMPLE_Q_TAG }, 165 { "head", MSG_HEAD_OF_Q_TAG }, 166 { "ordered", MSG_ORDERED_Q_TAG }, 167 { "iwr", MSG_IGN_WIDE_RESIDUE }, 168 { "aca", MSG_ACA_TASK } 169}; 170 171static const char scsicmd_opts[] = "a:c:dfi:o:r"; 172static const char readdefect_opts[] = "f:GPqsS:X"; 173static const char negotiate_opts[] = "acD:M:O:qR:T:UW:"; 174static const char smprg_opts[] = "l"; 175static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:"; 176static const char smpphylist_opts[] = "lq"; 177static char pwd_opt; 178 179static struct camcontrol_opts option_table[] = { 180 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL}, 181 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"}, 182 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL}, 183 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL}, 184 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL}, 185 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL}, 186 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL}, 187 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"}, 188 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"}, 189 {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL}, 190 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL}, 191 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL}, 192 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts}, 193 {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:F:f:Wb:l:41S:I"}, 194 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts}, 195 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"}, 196 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts}, 197 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts}, 198 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts}, 199 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts}, 200 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts}, 201 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts}, 202 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"}, 203 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts}, 204 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts}, 205 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"}, 206 {"devtype", CAM_CMD_DEVTYPE, CAM_ARG_NONE, ""}, 207 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL}, 208 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "6bdelm:DLP:"}, 209 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"}, 210 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, 211 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, 212 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"}, 213 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"}, 214 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"}, 215 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"}, 216 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"}, 217 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""}, 218 {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""}, 219 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"}, 220 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"}, 221 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"}, 222 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"}, 223 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"}, 224 {"ama", CAM_CMD_AMA, CAM_ARG_NONE, "fqs:"}, 225 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"}, 226 {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"}, 227 {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"}, 228 {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"}, 229 {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"}, 230 {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"}, 231 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, 232 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, 233 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, 234 {NULL, 0, 0, NULL} 235}; 236 237struct cam_devitem { 238 struct device_match_result dev_match; 239 int num_periphs; 240 struct periph_match_result *periph_matches; 241 struct scsi_vpd_device_id *device_id; 242 int device_id_len; 243 STAILQ_ENTRY(cam_devitem) links; 244}; 245 246struct cam_devlist { 247 STAILQ_HEAD(, cam_devitem) dev_queue; 248 path_id_t path_id; 249}; 250 251static cam_cmdmask cmdlist; 252static cam_argmask arglist; 253 254static const char *devtype_names[] = { 255 "none", 256 "scsi", 257 "satl", 258 "ata", 259 "nvme", 260 "mmcsd", 261 "unknown", 262}; 263 264camcontrol_optret getoption(struct camcontrol_opts *table, char *arg, 265 uint32_t *cmdnum, cam_argmask *argnum, 266 const char **subopt); 267static int getdevlist(struct cam_device *device); 268static int getdevtree(int argc, char **argv, char *combinedopt); 269static int getdevtype(struct cam_device *device); 270static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr); 271static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr); 272static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr); 273static int print_dev_mmcsd(struct device_match_result *dev_result, 274 char *tmpstr); 275#ifdef WITH_NVME 276static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr); 277#endif 278static int testunitready(struct cam_device *device, int task_attr, 279 int retry_count, int timeout, int quiet); 280static int scsistart(struct cam_device *device, int startstop, int loadeject, 281 int task_attr, int retry_count, int timeout); 282static int scsiinquiry(struct cam_device *device, int task_attr, 283 int retry_count, int timeout); 284static int scsiserial(struct cam_device *device, int task_attr, 285 int retry_count, int timeout); 286static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target, 287 lun_id_t *lun, cam_argmask *arglst); 288static int reprobe(struct cam_device *device); 289static int dorescan_or_reset(int argc, char **argv, int rescan); 290static int rescan_or_reset_bus(path_id_t bus, int rescan); 291static int scanlun_or_reset_dev(path_id_t bus, target_id_t target, 292 lun_id_t lun, int scan); 293static int readdefects(struct cam_device *device, int argc, char **argv, 294 char *combinedopt, int task_attr, int retry_count, 295 int timeout); 296static void modepage(struct cam_device *device, int argc, char **argv, 297 char *combinedopt, int task_attr, int retry_count, 298 int timeout); 299static int scsicmd(struct cam_device *device, int argc, char **argv, 300 char *combinedopt, int task_attr, int retry_count, 301 int timeout); 302static int smpcmd(struct cam_device *device, int argc, char **argv, 303 char *combinedopt, int retry_count, int timeout); 304static int mmcsdcmd(struct cam_device *device, int argc, char **argv, 305 char *combinedopt, int retry_count, int timeout); 306static int smpreportgeneral(struct cam_device *device, int argc, char **argv, 307 char *combinedopt, int retry_count, int timeout); 308static int smpphycontrol(struct cam_device *device, int argc, char **argv, 309 char *combinedopt, int retry_count, int timeout); 310static int smpmaninfo(struct cam_device *device, int argc, char **argv, 311 char *combinedopt, int retry_count, int timeout); 312static int getdevid(struct cam_devitem *item); 313static int buildbusdevlist(struct cam_devlist *devlist); 314static void freebusdevlist(struct cam_devlist *devlist); 315static struct cam_devitem *findsasdevice(struct cam_devlist *devlist, 316 uint64_t sasaddr); 317static int smpphylist(struct cam_device *device, int argc, char **argv, 318 char *combinedopt, int retry_count, int timeout); 319static int tagcontrol(struct cam_device *device, int argc, char **argv, 320 char *combinedopt); 321static void cts_print(struct cam_device *device, 322 struct ccb_trans_settings *cts); 323static void cpi_print(struct ccb_pathinq *cpi); 324static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi); 325static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd); 326static int get_print_cts(struct cam_device *device, int user_settings, 327 int quiet, struct ccb_trans_settings *cts); 328static int ratecontrol(struct cam_device *device, int task_attr, 329 int retry_count, int timeout, int argc, char **argv, 330 char *combinedopt); 331static int scsiformat(struct cam_device *device, int argc, char **argv, 332 char *combinedopt, int task_attr, int retry_count, 333 int timeout); 334static int sanitize(struct cam_device *device, int argc, char **argv, 335 char *combinedopt, int task_attr, int retry_count, 336 int timeout); 337static int scsireportluns(struct cam_device *device, int argc, char **argv, 338 char *combinedopt, int task_attr, int retry_count, 339 int timeout); 340static int scsireadcapacity(struct cam_device *device, int argc, char **argv, 341 char *combinedopt, int task_attr, int retry_count, 342 int timeout); 343static int atapm(struct cam_device *device, int argc, char **argv, 344 char *combinedopt, int retry_count, int timeout); 345static int atasecurity(struct cam_device *device, int retry_count, int timeout, 346 int argc, char **argv, char *combinedopt); 347static int atahpa(struct cam_device *device, int retry_count, int timeout, 348 int argc, char **argv, char *combinedopt); 349static int ataama(struct cam_device *device, int retry_count, int timeout, 350 int argc, char **argv, char *combinedopt); 351static int scsiprintoneopcode(struct cam_device *device, int req_opcode, 352 int sa_set, int req_sa, uint8_t *buf, 353 uint32_t valid_len); 354static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf, 355 uint32_t valid_len); 356static int scsiopcodes(struct cam_device *device, int argc, char **argv, 357 char *combinedopt, int task_attr, int retry_count, 358 int timeout, int verbose); 359 360#ifndef min 361#define min(a,b) (((a)<(b))?(a):(b)) 362#endif 363#ifndef max 364#define max(a,b) (((a)>(b))?(a):(b)) 365#endif 366 367camcontrol_optret 368getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum, 369 cam_argmask *argnum, const char **subopt) 370{ 371 struct camcontrol_opts *opts; 372 int num_matches = 0; 373 374 for (opts = table; (opts != NULL) && (opts->optname != NULL); 375 opts++) { 376 if (strncmp(opts->optname, arg, strlen(arg)) == 0) { 377 *cmdnum = opts->cmdnum; 378 *argnum = opts->argnum; 379 *subopt = opts->subopt; 380 if (++num_matches > 1) 381 return (CC_OR_AMBIGUOUS); 382 } 383 } 384 385 if (num_matches > 0) 386 return (CC_OR_FOUND); 387 else 388 return (CC_OR_NOT_FOUND); 389} 390 391static int 392getdevlist(struct cam_device *device) 393{ 394 union ccb *ccb; 395 char status[32]; 396 int error = 0; 397 398 ccb = cam_getccb(device); 399 400 ccb->ccb_h.func_code = XPT_GDEVLIST; 401 ccb->ccb_h.flags = CAM_DIR_NONE; 402 ccb->ccb_h.retry_count = 1; 403 ccb->cgdl.index = 0; 404 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS; 405 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) { 406 if (cam_send_ccb(device, ccb) < 0) { 407 warn("error getting device list"); 408 cam_freeccb(ccb); 409 return (1); 410 } 411 412 status[0] = '\0'; 413 414 switch (ccb->cgdl.status) { 415 case CAM_GDEVLIST_MORE_DEVS: 416 strcpy(status, "MORE"); 417 break; 418 case CAM_GDEVLIST_LAST_DEVICE: 419 strcpy(status, "LAST"); 420 break; 421 case CAM_GDEVLIST_LIST_CHANGED: 422 strcpy(status, "CHANGED"); 423 break; 424 case CAM_GDEVLIST_ERROR: 425 strcpy(status, "ERROR"); 426 error = 1; 427 break; 428 } 429 430 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n", 431 ccb->cgdl.periph_name, 432 ccb->cgdl.unit_number, 433 ccb->cgdl.generation, 434 ccb->cgdl.index, 435 status); 436 437 /* 438 * If the list has changed, we need to start over from the 439 * beginning. 440 */ 441 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED) 442 ccb->cgdl.index = 0; 443 } 444 445 cam_freeccb(ccb); 446 447 return (error); 448} 449 450static int 451getdevtree(int argc, char **argv, char *combinedopt) 452{ 453 union ccb ccb; 454 int bufsize, fd; 455 unsigned int i; 456 int need_close = 0; 457 int error = 0; 458 int skip_device = 0; 459 int busonly = 0; 460 int c; 461 462 while ((c = getopt(argc, argv, combinedopt)) != -1) { 463 switch(c) { 464 case 'b': 465 if ((arglist & CAM_ARG_VERBOSE) == 0) 466 busonly = 1; 467 break; 468 default: 469 break; 470 } 471 } 472 473 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { 474 warn("couldn't open %s", XPT_DEVICE); 475 return (1); 476 } 477 478 bzero(&ccb, sizeof(union ccb)); 479 480 ccb.ccb_h.path_id = CAM_XPT_PATH_ID; 481 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 482 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 483 484 ccb.ccb_h.func_code = XPT_DEV_MATCH; 485 bufsize = sizeof(struct dev_match_result) * 100; 486 ccb.cdm.match_buf_len = bufsize; 487 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); 488 if (ccb.cdm.matches == NULL) { 489 warnx("can't malloc memory for matches"); 490 close(fd); 491 return (1); 492 } 493 ccb.cdm.num_matches = 0; 494 495 /* 496 * We fetch all nodes, since we display most of them in the default 497 * case, and all in the verbose case. 498 */ 499 ccb.cdm.num_patterns = 0; 500 ccb.cdm.pattern_buf_len = 0; 501 502 /* 503 * We do the ioctl multiple times if necessary, in case there are 504 * more than 100 nodes in the EDT. 505 */ 506 do { 507 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 508 warn("error sending CAMIOCOMMAND ioctl"); 509 error = 1; 510 break; 511 } 512 513 if ((ccb.ccb_h.status != CAM_REQ_CMP) 514 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) 515 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { 516 warnx("got CAM error %#x, CDM error %d\n", 517 ccb.ccb_h.status, ccb.cdm.status); 518 error = 1; 519 break; 520 } 521 522 for (i = 0; i < ccb.cdm.num_matches; i++) { 523 switch (ccb.cdm.matches[i].type) { 524 case DEV_MATCH_BUS: { 525 struct bus_match_result *bus_result; 526 527 /* 528 * Only print the bus information if the 529 * user turns on the verbose flag. 530 */ 531 if ((busonly == 0) && 532 (arglist & CAM_ARG_VERBOSE) == 0) 533 break; 534 535 bus_result = 536 &ccb.cdm.matches[i].result.bus_result; 537 538 if (need_close) { 539 fprintf(stdout, ")\n"); 540 need_close = 0; 541 } 542 543 fprintf(stdout, "scbus%d on %s%d bus %d%s\n", 544 bus_result->path_id, 545 bus_result->dev_name, 546 bus_result->unit_number, 547 bus_result->bus_id, 548 (busonly ? "" : ":")); 549 break; 550 } 551 case DEV_MATCH_DEVICE: { 552 struct device_match_result *dev_result; 553 char tmpstr[256]; 554 555 if (busonly == 1) 556 break; 557 558 dev_result = 559 &ccb.cdm.matches[i].result.device_result; 560 561 if ((dev_result->flags 562 & DEV_RESULT_UNCONFIGURED) 563 && ((arglist & CAM_ARG_VERBOSE) == 0)) { 564 skip_device = 1; 565 break; 566 } else 567 skip_device = 0; 568 569 if (dev_result->protocol == PROTO_SCSI) { 570 if (print_dev_scsi(dev_result, 571 &tmpstr[0]) != 0) { 572 skip_device = 1; 573 break; 574 } 575 } else if (dev_result->protocol == PROTO_ATA || 576 dev_result->protocol == PROTO_SATAPM) { 577 if (print_dev_ata(dev_result, 578 &tmpstr[0]) != 0) { 579 skip_device = 1; 580 break; 581 } 582 } else if (dev_result->protocol == PROTO_MMCSD){ 583 if (print_dev_mmcsd(dev_result, 584 &tmpstr[0]) != 0) { 585 skip_device = 1; 586 break; 587 } 588 } else if (dev_result->protocol == PROTO_SEMB) { 589 if (print_dev_semb(dev_result, 590 &tmpstr[0]) != 0) { 591 skip_device = 1; 592 break; 593 } 594#ifdef WITH_NVME 595 } else if (dev_result->protocol == PROTO_NVME) { 596 if (print_dev_nvme(dev_result, 597 &tmpstr[0]) != 0) { 598 skip_device = 1; 599 break; 600 } 601#endif 602 } else { 603 sprintf(tmpstr, "<>"); 604 } 605 if (need_close) { 606 fprintf(stdout, ")\n"); 607 need_close = 0; 608 } 609 610 fprintf(stdout, "%-33s at scbus%d " 611 "target %d lun %jx (", 612 tmpstr, 613 dev_result->path_id, 614 dev_result->target_id, 615 (uintmax_t)dev_result->target_lun); 616 617 need_close = 1; 618 619 break; 620 } 621 case DEV_MATCH_PERIPH: { 622 struct periph_match_result *periph_result; 623 624 periph_result = 625 &ccb.cdm.matches[i].result.periph_result; 626 627 if (busonly || skip_device != 0) 628 break; 629 630 if (need_close > 1) 631 fprintf(stdout, ","); 632 633 fprintf(stdout, "%s%d", 634 periph_result->periph_name, 635 periph_result->unit_number); 636 637 need_close++; 638 break; 639 } 640 default: 641 fprintf(stdout, "unknown match type\n"); 642 break; 643 } 644 } 645 646 } while ((ccb.ccb_h.status == CAM_REQ_CMP) 647 && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); 648 649 if (need_close) 650 fprintf(stdout, ")\n"); 651 652 close(fd); 653 654 return (error); 655} 656 657static int 658getdevtype(struct cam_device *cam_dev) 659{ 660 camcontrol_devtype dt; 661 int error; 662 663 /* 664 * Get the device type and report it, request no I/O be done to do this. 665 */ 666 error = get_device_type(cam_dev, -1, 0, 0, &dt); 667 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) { 668 fprintf(stdout, "illegal\n"); 669 return (1); 670 } 671 fprintf(stdout, "%s\n", devtype_names[dt]); 672 return (0); 673} 674 675static int 676print_dev_scsi(struct device_match_result *dev_result, char *tmpstr) 677{ 678 char vendor[16], product[48], revision[16]; 679 680 cam_strvis(vendor, dev_result->inq_data.vendor, 681 sizeof(dev_result->inq_data.vendor), sizeof(vendor)); 682 cam_strvis(product, dev_result->inq_data.product, 683 sizeof(dev_result->inq_data.product), sizeof(product)); 684 cam_strvis(revision, dev_result->inq_data.revision, 685 sizeof(dev_result->inq_data.revision), sizeof(revision)); 686 sprintf(tmpstr, "<%s %s %s>", vendor, product, revision); 687 688 return (0); 689} 690 691static int 692print_dev_ata(struct device_match_result *dev_result, char *tmpstr) 693{ 694 char product[48], revision[16]; 695 696 cam_strvis(product, dev_result->ident_data.model, 697 sizeof(dev_result->ident_data.model), sizeof(product)); 698 cam_strvis(revision, dev_result->ident_data.revision, 699 sizeof(dev_result->ident_data.revision), sizeof(revision)); 700 sprintf(tmpstr, "<%s %s>", product, revision); 701 702 return (0); 703} 704 705static int 706print_dev_semb(struct device_match_result *dev_result, char *tmpstr) 707{ 708 struct sep_identify_data *sid; 709 char vendor[16], product[48], revision[16], fw[5]; 710 711 sid = (struct sep_identify_data *)&dev_result->ident_data; 712 cam_strvis(vendor, sid->vendor_id, 713 sizeof(sid->vendor_id), sizeof(vendor)); 714 cam_strvis(product, sid->product_id, 715 sizeof(sid->product_id), sizeof(product)); 716 cam_strvis(revision, sid->product_rev, 717 sizeof(sid->product_rev), sizeof(revision)); 718 cam_strvis(fw, sid->firmware_rev, 719 sizeof(sid->firmware_rev), sizeof(fw)); 720 sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw); 721 722 return (0); 723} 724 725static int 726print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr) 727{ 728 union ccb *ccb; 729 struct ccb_dev_advinfo *advi; 730 struct cam_device *dev; 731 struct mmc_params mmc_ident_data; 732 733 dev = cam_open_btl(dev_result->path_id, dev_result->target_id, 734 dev_result->target_lun, O_RDWR, NULL); 735 if (dev == NULL) { 736 warnx("%s", cam_errbuf); 737 return (1); 738 } 739 740 ccb = cam_getccb(dev); 741 if (ccb == NULL) { 742 warnx("couldn't allocate CCB"); 743 cam_close_device(dev); 744 return (1); 745 } 746 747 advi = &ccb->cdai; 748 advi->ccb_h.flags = CAM_DIR_IN; 749 advi->ccb_h.func_code = XPT_DEV_ADVINFO; 750 advi->flags = CDAI_FLAG_NONE; 751 advi->buftype = CDAI_TYPE_MMC_PARAMS; 752 advi->bufsiz = sizeof(struct mmc_params); 753 advi->buf = (uint8_t *)&mmc_ident_data; 754 755 if (cam_send_ccb(dev, ccb) < 0) { 756 warn("error sending XPT_DEV_ADVINFO CCB"); 757 cam_freeccb(ccb); 758 cam_close_device(dev); 759 return (1); 760 } 761 762 if (strlen(mmc_ident_data.model) > 0) { 763 sprintf(tmpstr, "<%s>", mmc_ident_data.model); 764 } else { 765 sprintf(tmpstr, "<%s card>", 766 mmc_ident_data.card_features & 767 CARD_FEATURE_SDIO ? "SDIO" : "unknown"); 768 } 769 770 cam_freeccb(ccb); 771 cam_close_device(dev); 772 return (0); 773} 774 775#ifdef WITH_NVME 776static int 777nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata) 778{ 779 union ccb *ccb; 780 struct ccb_dev_advinfo *advi; 781 782 ccb = cam_getccb(dev); 783 if (ccb == NULL) { 784 warnx("couldn't allocate CCB"); 785 cam_close_device(dev); 786 return (1); 787 } 788 789 advi = &ccb->cdai; 790 advi->ccb_h.flags = CAM_DIR_IN; 791 advi->ccb_h.func_code = XPT_DEV_ADVINFO; 792 advi->flags = CDAI_FLAG_NONE; 793 advi->buftype = CDAI_TYPE_NVME_CNTRL; 794 advi->bufsiz = sizeof(struct nvme_controller_data); 795 advi->buf = (uint8_t *)cdata; 796 797 if (cam_send_ccb(dev, ccb) < 0) { 798 warn("error sending XPT_DEV_ADVINFO CCB"); 799 cam_freeccb(ccb); 800 cam_close_device(dev); 801 return(1); 802 } 803 if (advi->ccb_h.status != CAM_REQ_CMP) { 804 warnx("got CAM error %#x", advi->ccb_h.status); 805 cam_freeccb(ccb); 806 cam_close_device(dev); 807 return(1); 808 } 809 cam_freeccb(ccb); 810 return 0; 811} 812 813static int 814print_dev_nvme(struct device_match_result *dev_result, char *tmpstr) 815{ 816 struct cam_device *dev; 817 struct nvme_controller_data cdata; 818 char vendor[64], product[64]; 819 820 dev = cam_open_btl(dev_result->path_id, dev_result->target_id, 821 dev_result->target_lun, O_RDWR, NULL); 822 if (dev == NULL) { 823 warnx("%s", cam_errbuf); 824 return (1); 825 } 826 827 if (nvme_get_cdata(dev, &cdata)) 828 return (1); 829 830 cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor)); 831 cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product)); 832 sprintf(tmpstr, "<%s %s>", vendor, product); 833 834 cam_close_device(dev); 835 return (0); 836} 837#endif 838 839static int 840testunitready(struct cam_device *device, int task_attr, int retry_count, 841 int timeout, int quiet) 842{ 843 int error = 0; 844 union ccb *ccb; 845 846 ccb = cam_getccb(device); 847 848 scsi_test_unit_ready(&ccb->csio, 849 /* retries */ retry_count, 850 /* cbfcnp */ NULL, 851 /* tag_action */ task_attr, 852 /* sense_len */ SSD_FULL_SIZE, 853 /* timeout */ timeout ? timeout : 5000); 854 855 /* Disable freezing the device queue */ 856 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 857 858 if (arglist & CAM_ARG_ERR_RECOVER) 859 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 860 861 if (cam_send_ccb(device, ccb) < 0) { 862 if (quiet == 0) 863 warn("error sending TEST UNIT READY command"); 864 cam_freeccb(ccb); 865 return (1); 866 } 867 868 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { 869 if (quiet == 0) 870 fprintf(stdout, "Unit is ready\n"); 871 } else { 872 if (quiet == 0) 873 fprintf(stdout, "Unit is not ready\n"); 874 error = 1; 875 876 if (arglist & CAM_ARG_VERBOSE) { 877 cam_error_print(device, ccb, CAM_ESF_ALL, 878 CAM_EPF_ALL, stderr); 879 } 880 } 881 882 cam_freeccb(ccb); 883 884 return (error); 885} 886 887static int 888scsistart(struct cam_device *device, int startstop, int loadeject, 889 int task_attr, int retry_count, int timeout) 890{ 891 union ccb *ccb; 892 int error = 0; 893 894 ccb = cam_getccb(device); 895 896 /* 897 * If we're stopping, send an ordered tag so the drive in question 898 * will finish any previously queued writes before stopping. If 899 * the device isn't capable of tagged queueing, or if tagged 900 * queueing is turned off, the tag action is a no-op. We override 901 * the default simple tag, although this also has the effect of 902 * overriding the user's wishes if he wanted to specify a simple 903 * tag. 904 */ 905 if ((startstop == 0) 906 && (task_attr == MSG_SIMPLE_Q_TAG)) 907 task_attr = MSG_ORDERED_Q_TAG; 908 909 scsi_start_stop(&ccb->csio, 910 /* retries */ retry_count, 911 /* cbfcnp */ NULL, 912 /* tag_action */ task_attr, 913 /* start/stop */ startstop, 914 /* load_eject */ loadeject, 915 /* immediate */ 0, 916 /* sense_len */ SSD_FULL_SIZE, 917 /* timeout */ timeout ? timeout : 120000); 918 919 /* Disable freezing the device queue */ 920 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 921 922 if (arglist & CAM_ARG_ERR_RECOVER) 923 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 924 925 if (cam_send_ccb(device, ccb) < 0) { 926 warn("error sending START STOP UNIT command"); 927 cam_freeccb(ccb); 928 return (1); 929 } 930 931 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 932 if (startstop) { 933 fprintf(stdout, "Unit started successfully"); 934 if (loadeject) 935 fprintf(stdout,", Media loaded\n"); 936 else 937 fprintf(stdout,"\n"); 938 } else { 939 fprintf(stdout, "Unit stopped successfully"); 940 if (loadeject) 941 fprintf(stdout, ", Media ejected\n"); 942 else 943 fprintf(stdout, "\n"); 944 } 945 else { 946 error = 1; 947 if (startstop) 948 fprintf(stdout, 949 "Error received from start unit command\n"); 950 else 951 fprintf(stdout, 952 "Error received from stop unit command\n"); 953 954 if (arglist & CAM_ARG_VERBOSE) { 955 cam_error_print(device, ccb, CAM_ESF_ALL, 956 CAM_EPF_ALL, stderr); 957 } 958 } 959 960 cam_freeccb(ccb); 961 962 return (error); 963} 964 965int 966scsidoinquiry(struct cam_device *device, int argc, char **argv, 967 char *combinedopt, int task_attr, int retry_count, int timeout) 968{ 969 int c; 970 int error = 0; 971 972 while ((c = getopt(argc, argv, combinedopt)) != -1) { 973 switch(c) { 974 case 'D': 975 arglist |= CAM_ARG_GET_STDINQ; 976 break; 977 case 'R': 978 arglist |= CAM_ARG_GET_XFERRATE; 979 break; 980 case 'S': 981 arglist |= CAM_ARG_GET_SERIAL; 982 break; 983 default: 984 break; 985 } 986 } 987 988 /* 989 * If the user didn't specify any inquiry options, he wants all of 990 * them. 991 */ 992 if ((arglist & CAM_ARG_INQ_MASK) == 0) 993 arglist |= CAM_ARG_INQ_MASK; 994 995 if (arglist & CAM_ARG_GET_STDINQ) 996 error = scsiinquiry(device, task_attr, retry_count, timeout); 997 998 if (error != 0) 999 return (error); 1000 1001 if (arglist & CAM_ARG_GET_SERIAL) 1002 scsiserial(device, task_attr, retry_count, timeout); 1003 1004 if (arglist & CAM_ARG_GET_XFERRATE) 1005 error = camxferrate(device); 1006 1007 return (error); 1008} 1009 1010static int 1011scsiinquiry(struct cam_device *device, int task_attr, int retry_count, 1012 int timeout) 1013{ 1014 union ccb *ccb; 1015 struct scsi_inquiry_data *inq_buf; 1016 int error = 0; 1017 1018 ccb = cam_getccb(device); 1019 1020 if (ccb == NULL) { 1021 warnx("couldn't allocate CCB"); 1022 return (1); 1023 } 1024 1025 /* cam_getccb cleans up the header, caller has to zero the payload */ 1026 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 1027 1028 inq_buf = (struct scsi_inquiry_data *)malloc( 1029 sizeof(struct scsi_inquiry_data)); 1030 1031 if (inq_buf == NULL) { 1032 cam_freeccb(ccb); 1033 warnx("can't malloc memory for inquiry\n"); 1034 return (1); 1035 } 1036 bzero(inq_buf, sizeof(*inq_buf)); 1037 1038 /* 1039 * Note that although the size of the inquiry buffer is the full 1040 * 256 bytes specified in the SCSI spec, we only tell the device 1041 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are 1042 * two reasons for this: 1043 * 1044 * - The SCSI spec says that when a length field is only 1 byte, 1045 * a value of 0 will be interpreted as 256. Therefore 1046 * scsi_inquiry() will convert an inq_len (which is passed in as 1047 * a u_int32_t, but the field in the CDB is only 1 byte) of 256 1048 * to 0. Evidently, very few devices meet the spec in that 1049 * regard. Some devices, like many Seagate disks, take the 0 as 1050 * 0, and don't return any data. One Pioneer DVD-R drive 1051 * returns more data than the command asked for. 1052 * 1053 * So, since there are numerous devices that just don't work 1054 * right with the full inquiry size, we don't send the full size. 1055 * 1056 * - The second reason not to use the full inquiry data length is 1057 * that we don't need it here. The only reason we issue a 1058 * standard inquiry is to get the vendor name, device name, 1059 * and revision so scsi_print_inquiry() can print them. 1060 * 1061 * If, at some point in the future, more inquiry data is needed for 1062 * some reason, this code should use a procedure similar to the 1063 * probe code. i.e., issue a short inquiry, and determine from 1064 * the additional length passed back from the device how much 1065 * inquiry data the device supports. Once the amount the device 1066 * supports is determined, issue an inquiry for that amount and no 1067 * more. 1068 * 1069 * KDM, 2/18/2000 1070 */ 1071 scsi_inquiry(&ccb->csio, 1072 /* retries */ retry_count, 1073 /* cbfcnp */ NULL, 1074 /* tag_action */ task_attr, 1075 /* inq_buf */ (u_int8_t *)inq_buf, 1076 /* inq_len */ SHORT_INQUIRY_LENGTH, 1077 /* evpd */ 0, 1078 /* page_code */ 0, 1079 /* sense_len */ SSD_FULL_SIZE, 1080 /* timeout */ timeout ? timeout : 5000); 1081 1082 /* Disable freezing the device queue */ 1083 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 1084 1085 if (arglist & CAM_ARG_ERR_RECOVER) 1086 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 1087 1088 if (cam_send_ccb(device, ccb) < 0) { 1089 warn("error sending INQUIRY command"); 1090 cam_freeccb(ccb); 1091 return (1); 1092 } 1093 1094 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1095 error = 1; 1096 1097 if (arglist & CAM_ARG_VERBOSE) { 1098 cam_error_print(device, ccb, CAM_ESF_ALL, 1099 CAM_EPF_ALL, stderr); 1100 } 1101 } 1102 1103 cam_freeccb(ccb); 1104 1105 if (error != 0) { 1106 free(inq_buf); 1107 return (error); 1108 } 1109 1110 fprintf(stdout, "%s%d: ", device->device_name, 1111 device->dev_unit_num); 1112 scsi_print_inquiry(inq_buf); 1113 1114 free(inq_buf); 1115 1116 return (0); 1117} 1118 1119static int 1120scsiserial(struct cam_device *device, int task_attr, int retry_count, 1121 int timeout) 1122{ 1123 union ccb *ccb; 1124 struct scsi_vpd_unit_serial_number *serial_buf; 1125 char serial_num[SVPD_SERIAL_NUM_SIZE + 1]; 1126 int error = 0; 1127 1128 ccb = cam_getccb(device); 1129 1130 if (ccb == NULL) { 1131 warnx("couldn't allocate CCB"); 1132 return (1); 1133 } 1134 1135 /* cam_getccb cleans up the header, caller has to zero the payload */ 1136 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 1137 1138 serial_buf = (struct scsi_vpd_unit_serial_number *) 1139 malloc(sizeof(*serial_buf)); 1140 1141 if (serial_buf == NULL) { 1142 cam_freeccb(ccb); 1143 warnx("can't malloc memory for serial number"); 1144 return (1); 1145 } 1146 1147 scsi_inquiry(&ccb->csio, 1148 /*retries*/ retry_count, 1149 /*cbfcnp*/ NULL, 1150 /* tag_action */ task_attr, 1151 /* inq_buf */ (u_int8_t *)serial_buf, 1152 /* inq_len */ sizeof(*serial_buf), 1153 /* evpd */ 1, 1154 /* page_code */ SVPD_UNIT_SERIAL_NUMBER, 1155 /* sense_len */ SSD_FULL_SIZE, 1156 /* timeout */ timeout ? timeout : 5000); 1157 1158 /* Disable freezing the device queue */ 1159 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 1160 1161 if (arglist & CAM_ARG_ERR_RECOVER) 1162 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 1163 1164 if (cam_send_ccb(device, ccb) < 0) { 1165 warn("error sending INQUIRY command"); 1166 cam_freeccb(ccb); 1167 free(serial_buf); 1168 return (1); 1169 } 1170 1171 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1172 error = 1; 1173 1174 if (arglist & CAM_ARG_VERBOSE) { 1175 cam_error_print(device, ccb, CAM_ESF_ALL, 1176 CAM_EPF_ALL, stderr); 1177 } 1178 } 1179 1180 cam_freeccb(ccb); 1181 1182 if (error != 0) { 1183 free(serial_buf); 1184 return (error); 1185 } 1186 1187 bcopy(serial_buf->serial_num, serial_num, serial_buf->length); 1188 serial_num[serial_buf->length] = '\0'; 1189 1190 if ((arglist & CAM_ARG_GET_STDINQ) 1191 || (arglist & CAM_ARG_GET_XFERRATE)) 1192 fprintf(stdout, "%s%d: Serial Number ", 1193 device->device_name, device->dev_unit_num); 1194 1195 fprintf(stdout, "%.60s\n", serial_num); 1196 1197 free(serial_buf); 1198 1199 return (0); 1200} 1201 1202int 1203camxferrate(struct cam_device *device) 1204{ 1205 struct ccb_pathinq cpi; 1206 u_int32_t freq = 0; 1207 u_int32_t speed = 0; 1208 union ccb *ccb; 1209 u_int mb; 1210 int retval = 0; 1211 1212 if ((retval = get_cpi(device, &cpi)) != 0) 1213 return (1); 1214 1215 ccb = cam_getccb(device); 1216 1217 if (ccb == NULL) { 1218 warnx("couldn't allocate CCB"); 1219 return (1); 1220 } 1221 1222 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); 1223 1224 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 1225 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS; 1226 1227 if (((retval = cam_send_ccb(device, ccb)) < 0) 1228 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 1229 const char error_string[] = "error getting transfer settings"; 1230 1231 if (retval < 0) 1232 warn(error_string); 1233 else 1234 warnx(error_string); 1235 1236 if (arglist & CAM_ARG_VERBOSE) 1237 cam_error_print(device, ccb, CAM_ESF_ALL, 1238 CAM_EPF_ALL, stderr); 1239 1240 retval = 1; 1241 1242 goto xferrate_bailout; 1243 1244 } 1245 1246 speed = cpi.base_transfer_speed; 1247 freq = 0; 1248 if (ccb->cts.transport == XPORT_SPI) { 1249 struct ccb_trans_settings_spi *spi = 1250 &ccb->cts.xport_specific.spi; 1251 1252 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { 1253 freq = scsi_calc_syncsrate(spi->sync_period); 1254 speed = freq; 1255 } 1256 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { 1257 speed *= (0x01 << spi->bus_width); 1258 } 1259 } else if (ccb->cts.transport == XPORT_FC) { 1260 struct ccb_trans_settings_fc *fc = 1261 &ccb->cts.xport_specific.fc; 1262 1263 if (fc->valid & CTS_FC_VALID_SPEED) 1264 speed = fc->bitrate; 1265 } else if (ccb->cts.transport == XPORT_SAS) { 1266 struct ccb_trans_settings_sas *sas = 1267 &ccb->cts.xport_specific.sas; 1268 1269 if (sas->valid & CTS_SAS_VALID_SPEED) 1270 speed = sas->bitrate; 1271 } else if (ccb->cts.transport == XPORT_ATA) { 1272 struct ccb_trans_settings_pata *pata = 1273 &ccb->cts.xport_specific.ata; 1274 1275 if (pata->valid & CTS_ATA_VALID_MODE) 1276 speed = ata_mode2speed(pata->mode); 1277 } else if (ccb->cts.transport == XPORT_SATA) { 1278 struct ccb_trans_settings_sata *sata = 1279 &ccb->cts.xport_specific.sata; 1280 1281 if (sata->valid & CTS_SATA_VALID_REVISION) 1282 speed = ata_revision2speed(sata->revision); 1283 } 1284 1285 mb = speed / 1000; 1286 if (mb > 0) { 1287 fprintf(stdout, "%s%d: %d.%03dMB/s transfers", 1288 device->device_name, device->dev_unit_num, 1289 mb, speed % 1000); 1290 } else { 1291 fprintf(stdout, "%s%d: %dKB/s transfers", 1292 device->device_name, device->dev_unit_num, 1293 speed); 1294 } 1295 1296 if (ccb->cts.transport == XPORT_SPI) { 1297 struct ccb_trans_settings_spi *spi = 1298 &ccb->cts.xport_specific.spi; 1299 1300 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) 1301 && (spi->sync_offset != 0)) 1302 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000, 1303 freq % 1000, spi->sync_offset); 1304 1305 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) 1306 && (spi->bus_width > 0)) { 1307 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) 1308 && (spi->sync_offset != 0)) { 1309 fprintf(stdout, ", "); 1310 } else { 1311 fprintf(stdout, " ("); 1312 } 1313 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width)); 1314 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) 1315 && (spi->sync_offset != 0)) { 1316 fprintf(stdout, ")"); 1317 } 1318 } else if (ccb->cts.transport == XPORT_ATA) { 1319 struct ccb_trans_settings_pata *pata = 1320 &ccb->cts.xport_specific.ata; 1321 1322 printf(" ("); 1323 if (pata->valid & CTS_ATA_VALID_MODE) 1324 printf("%s, ", ata_mode2string(pata->mode)); 1325 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0) 1326 printf("ATAPI %dbytes, ", pata->atapi); 1327 if (pata->valid & CTS_ATA_VALID_BYTECOUNT) 1328 printf("PIO %dbytes", pata->bytecount); 1329 printf(")"); 1330 } else if (ccb->cts.transport == XPORT_SATA) { 1331 struct ccb_trans_settings_sata *sata = 1332 &ccb->cts.xport_specific.sata; 1333 1334 printf(" ("); 1335 if (sata->valid & CTS_SATA_VALID_REVISION) 1336 printf("SATA %d.x, ", sata->revision); 1337 else 1338 printf("SATA, "); 1339 if (sata->valid & CTS_SATA_VALID_MODE) 1340 printf("%s, ", ata_mode2string(sata->mode)); 1341 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0) 1342 printf("ATAPI %dbytes, ", sata->atapi); 1343 if (sata->valid & CTS_SATA_VALID_BYTECOUNT) 1344 printf("PIO %dbytes", sata->bytecount); 1345 printf(")"); 1346 } 1347 1348 if (ccb->cts.protocol == PROTO_SCSI) { 1349 struct ccb_trans_settings_scsi *scsi = 1350 &ccb->cts.proto_specific.scsi; 1351 if (scsi->valid & CTS_SCSI_VALID_TQ) { 1352 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) { 1353 fprintf(stdout, ", Command Queueing Enabled"); 1354 } 1355 } 1356 } 1357 1358 fprintf(stdout, "\n"); 1359 1360xferrate_bailout: 1361 1362 cam_freeccb(ccb); 1363 1364 return (retval); 1365} 1366 1367static void 1368atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header) 1369{ 1370 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 | 1371 ((u_int32_t)parm->lba_size_2 << 16); 1372 1373 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) | 1374 ((u_int64_t)parm->lba_size48_2 << 16) | 1375 ((u_int64_t)parm->lba_size48_3 << 32) | 1376 ((u_int64_t)parm->lba_size48_4 << 48); 1377 1378 if (header) { 1379 printf("\nFeature " 1380 "Support Enabled Value\n"); 1381 } 1382 1383 printf("Host Protected Area (HPA) "); 1384 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) { 1385 u_int64_t lba = lbasize48 ? lbasize48 : lbasize; 1386 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ", 1387 lba, hpasize); 1388 1389 printf("HPA - Security "); 1390 if (parm->support.command2 & ATA_SUPPORT_MAXSECURITY) 1391 printf("yes %s\n", (parm->enabled.command2 & 1392 ATA_SUPPORT_MAXSECURITY) ? "yes" : "no "); 1393 else 1394 printf("no\n"); 1395 } else { 1396 printf("no\n"); 1397 } 1398} 1399 1400static void 1401ataama_print(struct ata_params *parm, u_int64_t nativesize, int header) 1402{ 1403 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 | 1404 ((u_int32_t)parm->lba_size_2 << 16); 1405 1406 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) | 1407 ((u_int64_t)parm->lba_size48_2 << 16) | 1408 ((u_int64_t)parm->lba_size48_3 << 32) | 1409 ((u_int64_t)parm->lba_size48_4 << 48); 1410 1411 if (header) { 1412 printf("\nFeature " 1413 "Support Enabled Value\n"); 1414 } 1415 1416 printf("Accessible Max Address Config "); 1417 if (parm->support2 & ATA_SUPPORT_AMAX_ADDR) { 1418 u_int64_t lba = lbasize48 ? lbasize48 : lbasize; 1419 printf("yes %s %ju/%ju\n", 1420 (nativesize > lba) ? "yes" : "no ", lba, nativesize); 1421 } else { 1422 printf("no\n"); 1423 } 1424} 1425 1426static int 1427atasata(struct ata_params *parm) 1428{ 1429 1430 1431 if (parm->satacapabilities != 0xffff && 1432 parm->satacapabilities != 0x0000) 1433 return 1; 1434 1435 return 0; 1436} 1437 1438static void 1439atacapprint(struct ata_params *parm) 1440{ 1441 const char *proto; 1442 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 | 1443 ((u_int32_t)parm->lba_size_2 << 16); 1444 1445 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) | 1446 ((u_int64_t)parm->lba_size48_2 << 16) | 1447 ((u_int64_t)parm->lba_size48_3 << 32) | 1448 ((u_int64_t)parm->lba_size48_4 << 48); 1449 1450 printf("\n"); 1451 printf("protocol "); 1452 proto = (parm->config == ATA_PROTO_CFA) ? "CFA" : 1453 (parm->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA"; 1454 if (ata_version(parm->version_major) == 0) { 1455 printf("%s", proto); 1456 } else if (ata_version(parm->version_major) <= 7) { 1457 printf("%s-%d", proto, 1458 ata_version(parm->version_major)); 1459 } else if (ata_version(parm->version_major) == 8) { 1460 printf("%s8-ACS", proto); 1461 } else { 1462 printf("ACS-%d %s", 1463 ata_version(parm->version_major) - 7, proto); 1464 } 1465 if (parm->satacapabilities && parm->satacapabilities != 0xffff) { 1466 if (parm->satacapabilities & ATA_SATA_GEN3) 1467 printf(" SATA 3.x\n"); 1468 else if (parm->satacapabilities & ATA_SATA_GEN2) 1469 printf(" SATA 2.x\n"); 1470 else if (parm->satacapabilities & ATA_SATA_GEN1) 1471 printf(" SATA 1.x\n"); 1472 else 1473 printf(" SATA\n"); 1474 } 1475 else 1476 printf("\n"); 1477 printf("device model %.40s\n", parm->model); 1478 printf("firmware revision %.8s\n", parm->revision); 1479 printf("serial number %.20s\n", parm->serial); 1480 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) { 1481 printf("WWN %04x%04x%04x%04x\n", 1482 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]); 1483 } 1484 printf("additional product id %.8s\n", parm->product_id); 1485 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) { 1486 printf("media serial number %.30s\n", 1487 parm->media_serial); 1488 } 1489 1490 printf("cylinders %d\n", parm->cylinders); 1491 printf("heads %d\n", parm->heads); 1492 printf("sectors/track %d\n", parm->sectors); 1493 printf("sector size logical %u, physical %lu, offset %lu\n", 1494 ata_logical_sector_size(parm), 1495 (unsigned long)ata_physical_sector_size(parm), 1496 (unsigned long)ata_logical_sector_offset(parm)); 1497 1498 if (parm->config == ATA_PROTO_CFA || 1499 (parm->support.command2 & ATA_SUPPORT_CFA)) 1500 printf("CFA supported\n"); 1501 1502 printf("LBA%ssupported ", 1503 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not "); 1504 if (lbasize) 1505 printf("%d sectors\n", lbasize); 1506 else 1507 printf("\n"); 1508 1509 printf("LBA48%ssupported ", 1510 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not "); 1511 if (lbasize48) 1512 printf("%ju sectors\n", (uintmax_t)lbasize48); 1513 else 1514 printf("\n"); 1515 1516 printf("PIO supported PIO"); 1517 switch (ata_max_pmode(parm)) { 1518 case ATA_PIO4: 1519 printf("4"); 1520 break; 1521 case ATA_PIO3: 1522 printf("3"); 1523 break; 1524 case ATA_PIO2: 1525 printf("2"); 1526 break; 1527 case ATA_PIO1: 1528 printf("1"); 1529 break; 1530 default: 1531 printf("0"); 1532 } 1533 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0) 1534 printf(" w/o IORDY"); 1535 printf("\n"); 1536 1537 printf("DMA%ssupported ", 1538 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not "); 1539 if (parm->capabilities1 & ATA_SUPPORT_DMA) { 1540 if (parm->mwdmamodes & 0xff) { 1541 printf("WDMA"); 1542 if (parm->mwdmamodes & 0x04) 1543 printf("2"); 1544 else if (parm->mwdmamodes & 0x02) 1545 printf("1"); 1546 else if (parm->mwdmamodes & 0x01) 1547 printf("0"); 1548 printf(" "); 1549 } 1550 if ((parm->atavalid & ATA_FLAG_88) && 1551 (parm->udmamodes & 0xff)) { 1552 printf("UDMA"); 1553 if (parm->udmamodes & 0x40) 1554 printf("6"); 1555 else if (parm->udmamodes & 0x20) 1556 printf("5"); 1557 else if (parm->udmamodes & 0x10) 1558 printf("4"); 1559 else if (parm->udmamodes & 0x08) 1560 printf("3"); 1561 else if (parm->udmamodes & 0x04) 1562 printf("2"); 1563 else if (parm->udmamodes & 0x02) 1564 printf("1"); 1565 else if (parm->udmamodes & 0x01) 1566 printf("0"); 1567 printf(" "); 1568 } 1569 } 1570 printf("\n"); 1571 1572 if (parm->media_rotation_rate == 1) { 1573 printf("media RPM non-rotating\n"); 1574 } else if (parm->media_rotation_rate >= 0x0401 && 1575 parm->media_rotation_rate <= 0xFFFE) { 1576 printf("media RPM %d\n", 1577 parm->media_rotation_rate); 1578 } 1579 1580 printf("Zoned-Device Commands "); 1581 switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) { 1582 case ATA_SUPPORT_ZONE_DEV_MANAGED: 1583 printf("device managed\n"); 1584 break; 1585 case ATA_SUPPORT_ZONE_HOST_AWARE: 1586 printf("host aware\n"); 1587 break; 1588 default: 1589 printf("no\n"); 1590 } 1591 1592 printf("\nFeature " 1593 "Support Enabled Value Vendor\n"); 1594 printf("read ahead %s %s\n", 1595 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no", 1596 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no"); 1597 printf("write cache %s %s\n", 1598 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no", 1599 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no"); 1600 printf("flush cache %s %s\n", 1601 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no", 1602 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no"); 1603 printf("Native Command Queuing (NCQ) "); 1604 if (atasata(parm) && (parm->satacapabilities & ATA_SUPPORT_NCQ)) { 1605 printf("yes %d tags\n", 1606 ATA_QUEUE_LEN(parm->queue) + 1); 1607 printf("NCQ Priority Information %s\n", 1608 parm->satacapabilities & ATA_SUPPORT_NCQ_PRIO ? 1609 "yes" : "no"); 1610 printf("NCQ Non-Data Command %s\n", 1611 parm->satacapabilities2 & ATA_SUPPORT_NCQ_NON_DATA ? 1612 "yes" : "no"); 1613 printf("NCQ Streaming %s\n", 1614 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ? 1615 "yes" : "no"); 1616 printf("Receive & Send FPDMA Queued %s\n", 1617 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ? 1618 "yes" : "no"); 1619 printf("NCQ Autosense %s\n", 1620 parm->satasupport & ATA_SUPPORT_NCQ_AUTOSENSE ? 1621 "yes" : "no"); 1622 } else 1623 printf("no\n"); 1624 1625 printf("SMART %s %s\n", 1626 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no", 1627 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no"); 1628 printf("security %s %s\n", 1629 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no", 1630 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no"); 1631 printf("power management %s %s\n", 1632 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no", 1633 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no"); 1634 printf("microcode download %s %s\n", 1635 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no", 1636 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no"); 1637 printf("advanced power management %s %s", 1638 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no", 1639 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no"); 1640 if (parm->support.command2 & ATA_SUPPORT_APM) { 1641 printf(" %d/0x%02X\n", 1642 parm->apm_value & 0xff, parm->apm_value & 0xff); 1643 } else 1644 printf("\n"); 1645 printf("automatic acoustic management %s %s", 1646 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no", 1647 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no"); 1648 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) { 1649 printf(" %d/0x%02X %d/0x%02X\n", 1650 ATA_ACOUSTIC_CURRENT(parm->acoustic), 1651 ATA_ACOUSTIC_CURRENT(parm->acoustic), 1652 ATA_ACOUSTIC_VENDOR(parm->acoustic), 1653 ATA_ACOUSTIC_VENDOR(parm->acoustic)); 1654 } else 1655 printf("\n"); 1656 printf("media status notification %s %s\n", 1657 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no", 1658 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no"); 1659 printf("power-up in Standby %s %s\n", 1660 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no", 1661 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no"); 1662 printf("write-read-verify %s %s", 1663 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no", 1664 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no"); 1665 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) { 1666 printf(" %d/0x%x\n", 1667 parm->wrv_mode, parm->wrv_mode); 1668 } else 1669 printf("\n"); 1670 printf("unload %s %s\n", 1671 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no", 1672 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no"); 1673 printf("general purpose logging %s %s\n", 1674 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no", 1675 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no"); 1676 printf("free-fall %s %s\n", 1677 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no", 1678 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no"); 1679 printf("sense data reporting %s %s\n", 1680 parm->support2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no", 1681 parm->enabled2 & ATA_SUPPORT_SENSE_REPORT ? "yes" : "no"); 1682 printf("extended power conditions %s %s\n", 1683 parm->support2 & ATA_SUPPORT_EPC ? "yes" : "no", 1684 parm->enabled2 & ATA_SUPPORT_EPC ? "yes" : "no"); 1685 printf("device statistics notification %s %s\n", 1686 parm->support2 & ATA_SUPPORT_DSN ? "yes" : "no", 1687 parm->enabled2 & ATA_SUPPORT_DSN ? "yes" : "no"); 1688 printf("Data Set Management (DSM/TRIM) "); 1689 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) { 1690 printf("yes\n"); 1691 printf("DSM - max 512byte blocks "); 1692 if (parm->max_dsm_blocks == 0x00) 1693 printf("yes not specified\n"); 1694 else 1695 printf("yes %d\n", 1696 parm->max_dsm_blocks); 1697 1698 printf("DSM - deterministic read "); 1699 if (parm->support3 & ATA_SUPPORT_DRAT) { 1700 if (parm->support3 & ATA_SUPPORT_RZAT) 1701 printf("yes zeroed\n"); 1702 else 1703 printf("yes any value\n"); 1704 } else { 1705 printf("no\n"); 1706 } 1707 } else { 1708 printf("no\n"); 1709 } 1710 printf("Trusted Computing %s\n", 1711 ((parm->tcg & 0xc000) == 0x4000) && (parm->tcg & ATA_SUPPORT_TCG) ? 1712 "yes" : "no"); 1713 printf("encrypts all user data %s\n", 1714 parm->support3 & ATA_ENCRYPTS_ALL_USER_DATA ? "yes" : "no"); 1715 printf("Sanitize "); 1716 if (parm->multi & ATA_SUPPORT_SANITIZE) { 1717 printf("yes\t\t%s%s%s\n", 1718 parm->multi & ATA_SUPPORT_BLOCK_ERASE_EXT ? "block, " : "", 1719 parm->multi & ATA_SUPPORT_OVERWRITE_EXT ? "overwrite, " : "", 1720 parm->multi & ATA_SUPPORT_CRYPTO_SCRAMBLE_EXT ? "crypto" : ""); 1721 printf("Sanitize - commands allowed %s\n", 1722 parm->multi & ATA_SUPPORT_SANITIZE_ALLOWED ? "yes" : "no"); 1723 printf("Sanitize - antifreeze lock %s\n", 1724 parm->multi & ATA_SUPPORT_ANTIFREEZE_LOCK_EXT ? "yes" : "no"); 1725 } else { 1726 printf("no\n"); 1727 } 1728} 1729 1730static int 1731scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb) 1732{ 1733 struct ata_pass_16 *ata_pass_16; 1734 struct ata_cmd ata_cmd; 1735 1736 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes; 1737 ata_cmd.command = ata_pass_16->command; 1738 ata_cmd.control = ata_pass_16->control; 1739 ata_cmd.features = ata_pass_16->features; 1740 1741 if (arglist & CAM_ARG_VERBOSE) { 1742 warnx("sending ATA %s via pass_16 with timeout of %u msecs", 1743 ata_op_string(&ata_cmd), 1744 ccb->csio.ccb_h.timeout); 1745 } 1746 1747 /* Disable freezing the device queue */ 1748 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 1749 1750 if (arglist & CAM_ARG_ERR_RECOVER) 1751 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 1752 1753 if (cam_send_ccb(device, ccb) < 0) { 1754 warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd)); 1755 return (1); 1756 } 1757 1758 /* 1759 * Consider any non-CAM_REQ_CMP status as error and report it here, 1760 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible. 1761 */ 1762 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) && 1763 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1764 warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd)); 1765 if (arglist & CAM_ARG_VERBOSE) { 1766 cam_error_print(device, ccb, CAM_ESF_ALL, 1767 CAM_EPF_ALL, stderr); 1768 } 1769 return (1); 1770 } 1771 1772 return (0); 1773} 1774 1775 1776static int 1777ata_cam_send(struct cam_device *device, union ccb *ccb) 1778{ 1779 if (arglist & CAM_ARG_VERBOSE) { 1780 warnx("sending ATA %s with timeout of %u msecs", 1781 ata_op_string(&(ccb->ataio.cmd)), 1782 ccb->ataio.ccb_h.timeout); 1783 } 1784 1785 /* Disable freezing the device queue */ 1786 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 1787 1788 if (arglist & CAM_ARG_ERR_RECOVER) 1789 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 1790 1791 if (cam_send_ccb(device, ccb) < 0) { 1792 warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd))); 1793 return (1); 1794 } 1795 1796 /* 1797 * Consider any non-CAM_REQ_CMP status as error and report it here, 1798 * unless caller set AP_FLAG_CHK_COND, in which case it is reponsible. 1799 */ 1800 if (!(ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) && 1801 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1802 warnx("ATA %s failed", ata_op_string(&(ccb->ataio.cmd))); 1803 if (arglist & CAM_ARG_VERBOSE) { 1804 cam_error_print(device, ccb, CAM_ESF_ALL, 1805 CAM_EPF_ALL, stderr); 1806 } 1807 return (1); 1808 } 1809 1810 return (0); 1811} 1812 1813static int 1814ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries, 1815 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags, 1816 u_int8_t tag_action, u_int8_t command, u_int16_t features, 1817 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr, 1818 u_int16_t dxfer_len, int timeout) 1819{ 1820 if (data_ptr != NULL) { 1821 if (flags & CAM_DIR_OUT) 1822 ata_flags |= AP_FLAG_TDIR_TO_DEV; 1823 else 1824 ata_flags |= AP_FLAG_TDIR_FROM_DEV; 1825 } else { 1826 ata_flags |= AP_FLAG_TLEN_NO_DATA; 1827 } 1828 1829 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 1830 1831 scsi_ata_pass_16(&ccb->csio, 1832 retries, 1833 NULL, 1834 flags, 1835 tag_action, 1836 protocol, 1837 ata_flags, 1838 features, 1839 sector_count, 1840 lba, 1841 command, 1842 /*control*/0, 1843 data_ptr, 1844 dxfer_len, 1845 /*sense_len*/SSD_FULL_SIZE, 1846 timeout); 1847 1848 return scsi_cam_pass_16_send(device, ccb); 1849} 1850 1851static int 1852ata_try_pass_16(struct cam_device *device) 1853{ 1854 struct ccb_pathinq cpi; 1855 1856 if (get_cpi(device, &cpi) != 0) { 1857 warnx("couldn't get CPI"); 1858 return (-1); 1859 } 1860 1861 if (cpi.protocol == PROTO_SCSI) { 1862 /* possibly compatible with pass_16 */ 1863 return (1); 1864 } 1865 1866 /* likely not compatible with pass_16 */ 1867 return (0); 1868} 1869 1870static int 1871ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries, 1872 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags, 1873 u_int8_t tag_action, u_int8_t command, u_int16_t features, 1874 u_int64_t lba, u_int16_t sector_count, u_int8_t *data_ptr, 1875 u_int16_t dxfer_len, int timeout, int force48bit) 1876{ 1877 int retval; 1878 1879 retval = ata_try_pass_16(device); 1880 if (retval == -1) 1881 return (1); 1882 1883 if (retval == 1) { 1884 return (ata_do_pass_16(device, ccb, retries, flags, protocol, 1885 ata_flags, tag_action, command, features, 1886 lba, sector_count, data_ptr, dxfer_len, 1887 timeout)); 1888 } 1889 1890 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio); 1891 cam_fill_ataio(&ccb->ataio, 1892 retries, 1893 NULL, 1894 flags, 1895 tag_action, 1896 data_ptr, 1897 dxfer_len, 1898 timeout); 1899 1900 if (force48bit || lba > ATA_MAX_28BIT_LBA) 1901 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count); 1902 else 1903 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count); 1904 1905 if (ata_flags & AP_FLAG_CHK_COND) 1906 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; 1907 1908 return ata_cam_send(device, ccb); 1909} 1910 1911static void 1912dump_data(uint16_t *ptr, uint32_t len) 1913{ 1914 u_int i; 1915 1916 for (i = 0; i < len / 2; i++) { 1917 if ((i % 8) == 0) 1918 printf(" %3d: ", i); 1919 printf("%04hx ", ptr[i]); 1920 if ((i % 8) == 7) 1921 printf("\n"); 1922 } 1923 if ((i % 8) != 7) 1924 printf("\n"); 1925} 1926 1927static int 1928atahpa_proc_resp(struct cam_device *device, union ccb *ccb, u_int64_t *hpasize) 1929{ 1930 uint8_t error = 0, ata_device = 0, status = 0; 1931 uint16_t count = 0; 1932 uint64_t lba = 0; 1933 int retval; 1934 1935 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device, 1936 &status); 1937 if (retval == 1) { 1938 if (arglist & CAM_ARG_VERBOSE) { 1939 cam_error_print(device, ccb, CAM_ESF_ALL, 1940 CAM_EPF_ALL, stderr); 1941 } 1942 warnx("Can't get ATA command status"); 1943 return (retval); 1944 } 1945 1946 if (status & ATA_STATUS_ERROR) { 1947 if (arglist & CAM_ARG_VERBOSE) { 1948 cam_error_print(device, ccb, CAM_ESF_ALL, 1949 CAM_EPF_ALL, stderr); 1950 } 1951 1952 if (error & ATA_ERROR_ID_NOT_FOUND) { 1953 warnx("Max address has already been set since " 1954 "last power-on or hardware reset"); 1955 } else if (hpasize == NULL) 1956 warnx("Command failed with ATA error"); 1957 1958 return (1); 1959 } 1960 1961 if (hpasize != NULL) { 1962 if (retval == 2 || retval == 6) 1963 return (1); 1964 *hpasize = lba + 1; 1965 } 1966 1967 return (0); 1968} 1969 1970static int 1971ata_read_native_max(struct cam_device *device, int retry_count, 1972 u_int32_t timeout, union ccb *ccb, 1973 struct ata_params *parm, u_int64_t *hpasize) 1974{ 1975 int error; 1976 u_int cmd, is48bit; 1977 u_int8_t protocol; 1978 1979 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48; 1980 protocol = AP_PROTO_NON_DATA; 1981 1982 if (is48bit) { 1983 cmd = ATA_READ_NATIVE_MAX_ADDRESS48; 1984 protocol |= AP_EXTEND; 1985 } else { 1986 cmd = ATA_READ_NATIVE_MAX_ADDRESS; 1987 } 1988 1989 error = ata_do_cmd(device, 1990 ccb, 1991 retry_count, 1992 /*flags*/CAM_DIR_NONE, 1993 /*protocol*/protocol, 1994 /*ata_flags*/AP_FLAG_CHK_COND, 1995 /*tag_action*/MSG_SIMPLE_Q_TAG, 1996 /*command*/cmd, 1997 /*features*/0, 1998 /*lba*/0, 1999 /*sector_count*/0, 2000 /*data_ptr*/NULL, 2001 /*dxfer_len*/0, 2002 timeout ? timeout : 5000, 2003 is48bit); 2004 2005 if (error) 2006 return (error); 2007 2008 return atahpa_proc_resp(device, ccb, hpasize); 2009} 2010 2011static int 2012atahpa_set_max(struct cam_device *device, int retry_count, 2013 u_int32_t timeout, union ccb *ccb, 2014 int is48bit, u_int64_t maxsize, int persist) 2015{ 2016 int error; 2017 u_int cmd; 2018 u_int8_t protocol; 2019 2020 protocol = AP_PROTO_NON_DATA; 2021 2022 if (is48bit) { 2023 cmd = ATA_SET_MAX_ADDRESS48; 2024 protocol |= AP_EXTEND; 2025 } else { 2026 cmd = ATA_SET_MAX_ADDRESS; 2027 } 2028 2029 /* lba's are zero indexed so the max lba is requested max - 1 */ 2030 if (maxsize) 2031 maxsize--; 2032 2033 error = ata_do_cmd(device, 2034 ccb, 2035 retry_count, 2036 /*flags*/CAM_DIR_NONE, 2037 /*protocol*/protocol, 2038 /*ata_flags*/AP_FLAG_CHK_COND, 2039 /*tag_action*/MSG_SIMPLE_Q_TAG, 2040 /*command*/cmd, 2041 /*features*/ATA_HPA_FEAT_MAX_ADDR, 2042 /*lba*/maxsize, 2043 /*sector_count*/persist, 2044 /*data_ptr*/NULL, 2045 /*dxfer_len*/0, 2046 timeout ? timeout : 1000, 2047 is48bit); 2048 2049 if (error) 2050 return (error); 2051 2052 return atahpa_proc_resp(device, ccb, NULL); 2053} 2054 2055static int 2056atahpa_password(struct cam_device *device, int retry_count, 2057 u_int32_t timeout, union ccb *ccb, 2058 int is48bit, struct ata_set_max_pwd *pwd) 2059{ 2060 u_int cmd; 2061 u_int8_t protocol; 2062 2063 protocol = AP_PROTO_PIO_OUT; 2064 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; 2065 2066 return (ata_do_cmd(device, 2067 ccb, 2068 retry_count, 2069 /*flags*/CAM_DIR_OUT, 2070 /*protocol*/protocol, 2071 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | 2072 AP_FLAG_TLEN_SECT_CNT, 2073 /*tag_action*/MSG_SIMPLE_Q_TAG, 2074 /*command*/cmd, 2075 /*features*/ATA_HPA_FEAT_SET_PWD, 2076 /*lba*/0, 2077 /*sector_count*/sizeof(*pwd) / 512, 2078 /*data_ptr*/(u_int8_t*)pwd, 2079 /*dxfer_len*/sizeof(*pwd), 2080 timeout ? timeout : 1000, 2081 is48bit)); 2082} 2083 2084static int 2085atahpa_lock(struct cam_device *device, int retry_count, 2086 u_int32_t timeout, union ccb *ccb, int is48bit) 2087{ 2088 u_int cmd; 2089 u_int8_t protocol; 2090 2091 protocol = AP_PROTO_NON_DATA; 2092 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; 2093 2094 return (ata_do_cmd(device, 2095 ccb, 2096 retry_count, 2097 /*flags*/CAM_DIR_NONE, 2098 /*protocol*/protocol, 2099 /*ata_flags*/0, 2100 /*tag_action*/MSG_SIMPLE_Q_TAG, 2101 /*command*/cmd, 2102 /*features*/ATA_HPA_FEAT_LOCK, 2103 /*lba*/0, 2104 /*sector_count*/0, 2105 /*data_ptr*/NULL, 2106 /*dxfer_len*/0, 2107 timeout ? timeout : 1000, 2108 is48bit)); 2109} 2110 2111static int 2112atahpa_unlock(struct cam_device *device, int retry_count, 2113 u_int32_t timeout, union ccb *ccb, 2114 int is48bit, struct ata_set_max_pwd *pwd) 2115{ 2116 u_int cmd; 2117 u_int8_t protocol; 2118 2119 protocol = AP_PROTO_PIO_OUT; 2120 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; 2121 2122 return (ata_do_cmd(device, 2123 ccb, 2124 retry_count, 2125 /*flags*/CAM_DIR_OUT, 2126 /*protocol*/protocol, 2127 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | 2128 AP_FLAG_TLEN_SECT_CNT, 2129 /*tag_action*/MSG_SIMPLE_Q_TAG, 2130 /*command*/cmd, 2131 /*features*/ATA_HPA_FEAT_UNLOCK, 2132 /*lba*/0, 2133 /*sector_count*/sizeof(*pwd) / 512, 2134 /*data_ptr*/(u_int8_t*)pwd, 2135 /*dxfer_len*/sizeof(*pwd), 2136 timeout ? timeout : 1000, 2137 is48bit)); 2138} 2139 2140static int 2141atahpa_freeze_lock(struct cam_device *device, int retry_count, 2142 u_int32_t timeout, union ccb *ccb, int is48bit) 2143{ 2144 u_int cmd; 2145 u_int8_t protocol; 2146 2147 protocol = AP_PROTO_NON_DATA; 2148 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; 2149 2150 return (ata_do_cmd(device, 2151 ccb, 2152 retry_count, 2153 /*flags*/CAM_DIR_NONE, 2154 /*protocol*/protocol, 2155 /*ata_flags*/0, 2156 /*tag_action*/MSG_SIMPLE_Q_TAG, 2157 /*command*/cmd, 2158 /*features*/ATA_HPA_FEAT_FREEZE, 2159 /*lba*/0, 2160 /*sector_count*/0, 2161 /*data_ptr*/NULL, 2162 /*dxfer_len*/0, 2163 timeout ? timeout : 1000, 2164 is48bit)); 2165} 2166 2167static int 2168ata_get_native_max(struct cam_device *device, int retry_count, 2169 u_int32_t timeout, union ccb *ccb, 2170 u_int64_t *nativesize) 2171{ 2172 int error; 2173 2174 error = ata_do_cmd(device, 2175 ccb, 2176 retry_count, 2177 /*flags*/CAM_DIR_NONE, 2178 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND, 2179 /*ata_flags*/AP_FLAG_CHK_COND, 2180 /*tag_action*/MSG_SIMPLE_Q_TAG, 2181 /*command*/ATA_AMAX_ADDR, 2182 /*features*/ATA_AMAX_ADDR_GET, 2183 /*lba*/0, 2184 /*sector_count*/0, 2185 /*data_ptr*/NULL, 2186 /*dxfer_len*/0, 2187 timeout ? timeout : 30 * 1000, 2188 /*force48bit*/1); 2189 2190 if (error) 2191 return (error); 2192 2193 return atahpa_proc_resp(device, ccb, nativesize); 2194} 2195 2196static int 2197ataama_set(struct cam_device *device, int retry_count, 2198 u_int32_t timeout, union ccb *ccb, u_int64_t maxsize) 2199{ 2200 int error; 2201 2202 /* lba's are zero indexed so the max lba is requested max - 1 */ 2203 if (maxsize) 2204 maxsize--; 2205 2206 error = ata_do_cmd(device, 2207 ccb, 2208 retry_count, 2209 /*flags*/CAM_DIR_NONE, 2210 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND, 2211 /*ata_flags*/AP_FLAG_CHK_COND, 2212 /*tag_action*/MSG_SIMPLE_Q_TAG, 2213 /*command*/ATA_AMAX_ADDR, 2214 /*features*/ATA_AMAX_ADDR_SET, 2215 /*lba*/maxsize, 2216 /*sector_count*/0, 2217 /*data_ptr*/NULL, 2218 /*dxfer_len*/0, 2219 timeout ? timeout : 30 * 1000, 2220 /*force48bit*/1); 2221 2222 if (error) 2223 return (error); 2224 2225 return atahpa_proc_resp(device, ccb, NULL); 2226} 2227 2228static int 2229ataama_freeze(struct cam_device *device, int retry_count, 2230 u_int32_t timeout, union ccb *ccb) 2231{ 2232 2233 return (ata_do_cmd(device, 2234 ccb, 2235 retry_count, 2236 /*flags*/CAM_DIR_NONE, 2237 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND, 2238 /*ata_flags*/0, 2239 /*tag_action*/MSG_SIMPLE_Q_TAG, 2240 /*command*/ATA_AMAX_ADDR, 2241 /*features*/ATA_AMAX_ADDR_FREEZE, 2242 /*lba*/0, 2243 /*sector_count*/0, 2244 /*data_ptr*/NULL, 2245 /*dxfer_len*/0, 2246 timeout ? timeout : 30 * 1000, 2247 /*force48bit*/1)); 2248} 2249 2250int 2251ata_do_identify(struct cam_device *device, int retry_count, int timeout, 2252 union ccb *ccb, struct ata_params** ident_bufp) 2253{ 2254 struct ata_params *ident_buf; 2255 struct ccb_pathinq cpi; 2256 struct ccb_getdev cgd; 2257 u_int i, error; 2258 int16_t *ptr; 2259 u_int8_t command, retry_command; 2260 2261 if (get_cpi(device, &cpi) != 0) { 2262 warnx("couldn't get CPI"); 2263 return (-1); 2264 } 2265 2266 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */ 2267 if (cpi.protocol == PROTO_ATA) { 2268 if (get_cgd(device, &cgd) != 0) { 2269 warnx("couldn't get CGD"); 2270 return (-1); 2271 } 2272 2273 command = (cgd.protocol == PROTO_ATA) ? 2274 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY; 2275 retry_command = 0; 2276 } else { 2277 /* We don't know which for sure so try both */ 2278 command = ATA_ATA_IDENTIFY; 2279 retry_command = ATA_ATAPI_IDENTIFY; 2280 } 2281 2282 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params)); 2283 if (ptr == NULL) { 2284 warnx("can't calloc memory for identify\n"); 2285 return (1); 2286 } 2287 2288retry: 2289 error = ata_do_cmd(device, 2290 ccb, 2291 /*retries*/retry_count, 2292 /*flags*/CAM_DIR_IN, 2293 /*protocol*/AP_PROTO_PIO_IN, 2294 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | 2295 AP_FLAG_TLEN_SECT_CNT, 2296 /*tag_action*/MSG_SIMPLE_Q_TAG, 2297 /*command*/command, 2298 /*features*/0, 2299 /*lba*/0, 2300 /*sector_count*/sizeof(struct ata_params) / 512, 2301 /*data_ptr*/(u_int8_t *)ptr, 2302 /*dxfer_len*/sizeof(struct ata_params), 2303 /*timeout*/timeout ? timeout : 30 * 1000, 2304 /*force48bit*/0); 2305 2306 if (error != 0) { 2307 if (retry_command != 0) { 2308 command = retry_command; 2309 retry_command = 0; 2310 goto retry; 2311 } 2312 free(ptr); 2313 return (1); 2314 } 2315 2316 ident_buf = (struct ata_params *)ptr; 2317 ata_param_fixup(ident_buf); 2318 2319 error = 1; 2320 for (i = 0; i < sizeof(struct ata_params) / 2; i++) { 2321 if (ptr[i] != 0) 2322 error = 0; 2323 } 2324 2325 /* check for invalid (all zero) response */ 2326 if (error != 0) { 2327 warnx("Invalid identify response detected"); 2328 free(ptr); 2329 return (error); 2330 } 2331 2332 *ident_bufp = ident_buf; 2333 2334 return (0); 2335} 2336 2337 2338static int 2339ataidentify(struct cam_device *device, int retry_count, int timeout) 2340{ 2341 union ccb *ccb; 2342 struct ata_params *ident_buf; 2343 u_int64_t hpasize = 0, nativesize = 0; 2344 2345 if ((ccb = cam_getccb(device)) == NULL) { 2346 warnx("couldn't allocate CCB"); 2347 return (1); 2348 } 2349 2350 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) { 2351 cam_freeccb(ccb); 2352 return (1); 2353 } 2354 2355 if (arglist & CAM_ARG_VERBOSE) { 2356 printf("%s%d: Raw identify data:\n", 2357 device->device_name, device->dev_unit_num); 2358 dump_data((uint16_t *)ident_buf, sizeof(struct ata_params)); 2359 } 2360 2361 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) { 2362 ata_read_native_max(device, retry_count, timeout, ccb, 2363 ident_buf, &hpasize); 2364 } 2365 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) { 2366 ata_get_native_max(device, retry_count, timeout, ccb, 2367 &nativesize); 2368 } 2369 2370 printf("%s%d: ", device->device_name, device->dev_unit_num); 2371 ata_print_ident(ident_buf); 2372 camxferrate(device); 2373 atacapprint(ident_buf); 2374 atahpa_print(ident_buf, hpasize, 0); 2375 ataama_print(ident_buf, nativesize, 0); 2376 2377 free(ident_buf); 2378 cam_freeccb(ccb); 2379 2380 return (0); 2381} 2382 2383#ifdef WITH_NVME 2384static int 2385nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused) 2386{ 2387 struct nvme_controller_data cdata; 2388 2389 if (nvme_get_cdata(device, &cdata)) 2390 return (1); 2391 nvme_print_controller(&cdata); 2392 2393 return (0); 2394} 2395#endif 2396 2397static int 2398identify(struct cam_device *device, int retry_count, int timeout) 2399{ 2400#ifdef WITH_NVME 2401 struct ccb_pathinq cpi; 2402 2403 if (get_cpi(device, &cpi) != 0) { 2404 warnx("couldn't get CPI"); 2405 return (-1); 2406 } 2407 2408 if (cpi.protocol == PROTO_NVME) { 2409 return (nvmeidentify(device, retry_count, timeout)); 2410 } 2411#endif 2412 return (ataidentify(device, retry_count, timeout)); 2413} 2414 2415 2416enum { 2417 ATA_SECURITY_ACTION_PRINT, 2418 ATA_SECURITY_ACTION_FREEZE, 2419 ATA_SECURITY_ACTION_UNLOCK, 2420 ATA_SECURITY_ACTION_DISABLE, 2421 ATA_SECURITY_ACTION_ERASE, 2422 ATA_SECURITY_ACTION_ERASE_ENHANCED, 2423 ATA_SECURITY_ACTION_SET_PASSWORD 2424}; 2425 2426static void 2427atasecurity_print_time(u_int16_t tw) 2428{ 2429 2430 if (tw == 0) 2431 printf("unspecified"); 2432 else if (tw >= 255) 2433 printf("> 508 min"); 2434 else 2435 printf("%i min", 2 * tw); 2436} 2437 2438static u_int32_t 2439atasecurity_erase_timeout_msecs(u_int16_t timeout) 2440{ 2441 2442 if (timeout == 0) 2443 return 2 * 3600 * 1000; /* default: two hours */ 2444 else if (timeout > 255) 2445 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */ 2446 2447 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */ 2448} 2449 2450 2451static void 2452atasecurity_notify(u_int8_t command, struct ata_security_password *pwd) 2453{ 2454 struct ata_cmd cmd; 2455 2456 bzero(&cmd, sizeof(cmd)); 2457 cmd.command = command; 2458 printf("Issuing %s", ata_op_string(&cmd)); 2459 2460 if (pwd != NULL) { 2461 /* pwd->password may not be null terminated */ 2462 char pass[sizeof(pwd->password)+1]; 2463 2464 strlcpy(pass, pwd->password, sizeof(pass)); 2465 printf(" password='%s', user='%s'", 2466 pass, 2467 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ? 2468 "master" : "user"); 2469 2470 if (command == ATA_SECURITY_SET_PASSWORD) { 2471 printf(", mode='%s'", 2472 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ? 2473 "maximum" : "high"); 2474 } 2475 } 2476 2477 printf("\n"); 2478} 2479 2480static int 2481atasecurity_freeze(struct cam_device *device, union ccb *ccb, 2482 int retry_count, u_int32_t timeout, int quiet) 2483{ 2484 2485 if (quiet == 0) 2486 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL); 2487 2488 return ata_do_cmd(device, 2489 ccb, 2490 retry_count, 2491 /*flags*/CAM_DIR_NONE, 2492 /*protocol*/AP_PROTO_NON_DATA, 2493 /*ata_flags*/0, 2494 /*tag_action*/MSG_SIMPLE_Q_TAG, 2495 /*command*/ATA_SECURITY_FREEZE_LOCK, 2496 /*features*/0, 2497 /*lba*/0, 2498 /*sector_count*/0, 2499 /*data_ptr*/NULL, 2500 /*dxfer_len*/0, 2501 /*timeout*/timeout, 2502 /*force48bit*/0); 2503} 2504 2505static int 2506atasecurity_unlock(struct cam_device *device, union ccb *ccb, 2507 int retry_count, u_int32_t timeout, 2508 struct ata_security_password *pwd, int quiet) 2509{ 2510 2511 if (quiet == 0) 2512 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd); 2513 2514 return ata_do_cmd(device, 2515 ccb, 2516 retry_count, 2517 /*flags*/CAM_DIR_OUT, 2518 /*protocol*/AP_PROTO_PIO_OUT, 2519 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | 2520 AP_FLAG_TLEN_SECT_CNT, 2521 /*tag_action*/MSG_SIMPLE_Q_TAG, 2522 /*command*/ATA_SECURITY_UNLOCK, 2523 /*features*/0, 2524 /*lba*/0, 2525 /*sector_count*/sizeof(*pwd) / 512, 2526 /*data_ptr*/(u_int8_t *)pwd, 2527 /*dxfer_len*/sizeof(*pwd), 2528 /*timeout*/timeout, 2529 /*force48bit*/0); 2530} 2531 2532static int 2533atasecurity_disable(struct cam_device *device, union ccb *ccb, 2534 int retry_count, u_int32_t timeout, 2535 struct ata_security_password *pwd, int quiet) 2536{ 2537 2538 if (quiet == 0) 2539 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd); 2540 return ata_do_cmd(device, 2541 ccb, 2542 retry_count, 2543 /*flags*/CAM_DIR_OUT, 2544 /*protocol*/AP_PROTO_PIO_OUT, 2545 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | 2546 AP_FLAG_TLEN_SECT_CNT, 2547 /*tag_action*/MSG_SIMPLE_Q_TAG, 2548 /*command*/ATA_SECURITY_DISABLE_PASSWORD, 2549 /*features*/0, 2550 /*lba*/0, 2551 /*sector_count*/sizeof(*pwd) / 512, 2552 /*data_ptr*/(u_int8_t *)pwd, 2553 /*dxfer_len*/sizeof(*pwd), 2554 /*timeout*/timeout, 2555 /*force48bit*/0); 2556} 2557 2558 2559static int 2560atasecurity_erase_confirm(struct cam_device *device, 2561 struct ata_params* ident_buf) 2562{ 2563 2564 printf("\nYou are about to ERASE ALL DATA from the following" 2565 " device:\n%s%d,%s%d: ", device->device_name, 2566 device->dev_unit_num, device->given_dev_name, 2567 device->given_unit_number); 2568 ata_print_ident(ident_buf); 2569 2570 for(;;) { 2571 char str[50]; 2572 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) "); 2573 2574 if (fgets(str, sizeof(str), stdin) != NULL) { 2575 if (strncasecmp(str, "yes", 3) == 0) { 2576 return (1); 2577 } else if (strncasecmp(str, "no", 2) == 0) { 2578 return (0); 2579 } else { 2580 printf("Please answer \"yes\" or " 2581 "\"no\"\n"); 2582 } 2583 } 2584 } 2585 2586 /* NOTREACHED */ 2587 return (0); 2588} 2589 2590static int 2591atasecurity_erase(struct cam_device *device, union ccb *ccb, 2592 int retry_count, u_int32_t timeout, 2593 u_int32_t erase_timeout, 2594 struct ata_security_password *pwd, int quiet) 2595{ 2596 int error; 2597 2598 if (quiet == 0) 2599 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL); 2600 2601 error = ata_do_cmd(device, 2602 ccb, 2603 retry_count, 2604 /*flags*/CAM_DIR_NONE, 2605 /*protocol*/AP_PROTO_NON_DATA, 2606 /*ata_flags*/0, 2607 /*tag_action*/MSG_SIMPLE_Q_TAG, 2608 /*command*/ATA_SECURITY_ERASE_PREPARE, 2609 /*features*/0, 2610 /*lba*/0, 2611 /*sector_count*/0, 2612 /*data_ptr*/NULL, 2613 /*dxfer_len*/0, 2614 /*timeout*/timeout, 2615 /*force48bit*/0); 2616 2617 if (error != 0) 2618 return error; 2619 2620 if (quiet == 0) 2621 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd); 2622 2623 error = ata_do_cmd(device, 2624 ccb, 2625 retry_count, 2626 /*flags*/CAM_DIR_OUT, 2627 /*protocol*/AP_PROTO_PIO_OUT, 2628 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | 2629 AP_FLAG_TLEN_SECT_CNT, 2630 /*tag_action*/MSG_SIMPLE_Q_TAG, 2631 /*command*/ATA_SECURITY_ERASE_UNIT, 2632 /*features*/0, 2633 /*lba*/0, 2634 /*sector_count*/sizeof(*pwd) / 512, 2635 /*data_ptr*/(u_int8_t *)pwd, 2636 /*dxfer_len*/sizeof(*pwd), 2637 /*timeout*/erase_timeout, 2638 /*force48bit*/0); 2639 2640 if (error == 0 && quiet == 0) 2641 printf("\nErase Complete\n"); 2642 2643 return error; 2644} 2645 2646static int 2647atasecurity_set_password(struct cam_device *device, union ccb *ccb, 2648 int retry_count, u_int32_t timeout, 2649 struct ata_security_password *pwd, int quiet) 2650{ 2651 2652 if (quiet == 0) 2653 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd); 2654 2655 return ata_do_cmd(device, 2656 ccb, 2657 retry_count, 2658 /*flags*/CAM_DIR_OUT, 2659 /*protocol*/AP_PROTO_PIO_OUT, 2660 /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS | 2661 AP_FLAG_TLEN_SECT_CNT, 2662 /*tag_action*/MSG_SIMPLE_Q_TAG, 2663 /*command*/ATA_SECURITY_SET_PASSWORD, 2664 /*features*/0, 2665 /*lba*/0, 2666 /*sector_count*/sizeof(*pwd) / 512, 2667 /*data_ptr*/(u_int8_t *)pwd, 2668 /*dxfer_len*/sizeof(*pwd), 2669 /*timeout*/timeout, 2670 /*force48bit*/0); 2671} 2672 2673static void 2674atasecurity_print(struct ata_params *parm) 2675{ 2676 2677 printf("\nSecurity Option Value\n"); 2678 if (arglist & CAM_ARG_VERBOSE) { 2679 printf("status %04x\n", 2680 parm->security_status); 2681 } 2682 printf("supported %s\n", 2683 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no"); 2684 if (!(parm->security_status & ATA_SECURITY_SUPPORTED)) 2685 return; 2686 printf("enabled %s\n", 2687 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no"); 2688 printf("drive locked %s\n", 2689 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no"); 2690 printf("security config frozen %s\n", 2691 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no"); 2692 printf("count expired %s\n", 2693 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no"); 2694 printf("security level %s\n", 2695 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high"); 2696 printf("enhanced erase supported %s\n", 2697 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no"); 2698 printf("erase time "); 2699 atasecurity_print_time(parm->erase_time); 2700 printf("\n"); 2701 printf("enhanced erase time "); 2702 atasecurity_print_time(parm->enhanced_erase_time); 2703 printf("\n"); 2704 printf("master password rev %04x%s\n", 2705 parm->master_passwd_revision, 2706 parm->master_passwd_revision == 0x0000 || 2707 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : ""); 2708} 2709 2710/* 2711 * Validates and copies the password in optarg to the passed buffer. 2712 * If the password in optarg is the same length as the buffer then 2713 * the data will still be copied but no null termination will occur. 2714 */ 2715static int 2716ata_getpwd(u_int8_t *passwd, int max, char opt) 2717{ 2718 int len; 2719 2720 len = strlen(optarg); 2721 if (len > max) { 2722 warnx("-%c password is too long", opt); 2723 return (1); 2724 } else if (len == 0) { 2725 warnx("-%c password is missing", opt); 2726 return (1); 2727 } else if (optarg[0] == '-'){ 2728 warnx("-%c password starts with '-' (generic arg?)", opt); 2729 return (1); 2730 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) { 2731 warnx("-%c password conflicts with existing password from -%c", 2732 opt, pwd_opt); 2733 return (1); 2734 } 2735 2736 /* Callers pass in a buffer which does NOT need to be terminated */ 2737 strncpy(passwd, optarg, max); 2738 pwd_opt = opt; 2739 2740 return (0); 2741} 2742 2743enum { 2744 ATA_HPA_ACTION_PRINT, 2745 ATA_HPA_ACTION_SET_MAX, 2746 ATA_HPA_ACTION_SET_PWD, 2747 ATA_HPA_ACTION_LOCK, 2748 ATA_HPA_ACTION_UNLOCK, 2749 ATA_HPA_ACTION_FREEZE_LOCK 2750}; 2751 2752static int 2753atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf, 2754 u_int64_t maxsize, int persist) 2755{ 2756 printf("\nYou are about to configure HPA to limit the user accessible\n" 2757 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize, 2758 persist ? "persistently" : "temporarily", 2759 device->device_name, device->dev_unit_num, 2760 device->given_dev_name, device->given_unit_number); 2761 ata_print_ident(ident_buf); 2762 2763 for(;;) { 2764 char str[50]; 2765 printf("\nAre you SURE you want to configure HPA? (yes/no) "); 2766 2767 if (NULL != fgets(str, sizeof(str), stdin)) { 2768 if (0 == strncasecmp(str, "yes", 3)) { 2769 return (1); 2770 } else if (0 == strncasecmp(str, "no", 2)) { 2771 return (0); 2772 } else { 2773 printf("Please answer \"yes\" or " 2774 "\"no\"\n"); 2775 } 2776 } 2777 } 2778 2779 /* NOTREACHED */ 2780 return (0); 2781} 2782 2783static int 2784atahpa(struct cam_device *device, int retry_count, int timeout, 2785 int argc, char **argv, char *combinedopt) 2786{ 2787 union ccb *ccb; 2788 struct ata_params *ident_buf; 2789 struct ccb_getdev cgd; 2790 struct ata_set_max_pwd pwd; 2791 int error, confirm, quiet, c, action, actions, persist; 2792 int security, is48bit, pwdsize; 2793 u_int64_t hpasize, maxsize; 2794 2795 actions = 0; 2796 confirm = 0; 2797 quiet = 0; 2798 maxsize = 0; 2799 persist = 0; 2800 security = 0; 2801 2802 memset(&pwd, 0, sizeof(pwd)); 2803 2804 /* default action is to print hpa information */ 2805 action = ATA_HPA_ACTION_PRINT; 2806 pwdsize = sizeof(pwd.password); 2807 2808 while ((c = getopt(argc, argv, combinedopt)) != -1) { 2809 switch(c){ 2810 case 's': 2811 action = ATA_HPA_ACTION_SET_MAX; 2812 maxsize = strtoumax(optarg, NULL, 0); 2813 actions++; 2814 break; 2815 2816 case 'p': 2817 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 2818 return (1); 2819 action = ATA_HPA_ACTION_SET_PWD; 2820 security = 1; 2821 actions++; 2822 break; 2823 2824 case 'l': 2825 action = ATA_HPA_ACTION_LOCK; 2826 security = 1; 2827 actions++; 2828 break; 2829 2830 case 'U': 2831 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 2832 return (1); 2833 action = ATA_HPA_ACTION_UNLOCK; 2834 security = 1; 2835 actions++; 2836 break; 2837 2838 case 'f': 2839 action = ATA_HPA_ACTION_FREEZE_LOCK; 2840 security = 1; 2841 actions++; 2842 break; 2843 2844 case 'P': 2845 persist = 1; 2846 break; 2847 2848 case 'y': 2849 confirm++; 2850 break; 2851 2852 case 'q': 2853 quiet++; 2854 break; 2855 } 2856 } 2857 2858 if (actions > 1) { 2859 warnx("too many hpa actions specified"); 2860 return (1); 2861 } 2862 2863 if (get_cgd(device, &cgd) != 0) { 2864 warnx("couldn't get CGD"); 2865 return (1); 2866 } 2867 2868 ccb = cam_getccb(device); 2869 if (ccb == NULL) { 2870 warnx("couldn't allocate CCB"); 2871 return (1); 2872 } 2873 2874 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf); 2875 if (error != 0) { 2876 cam_freeccb(ccb); 2877 return (1); 2878 } 2879 2880 if (quiet == 0) { 2881 printf("%s%d: ", device->device_name, device->dev_unit_num); 2882 ata_print_ident(ident_buf); 2883 camxferrate(device); 2884 } 2885 2886 if (action == ATA_HPA_ACTION_PRINT) { 2887 hpasize = 0; 2888 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) 2889 ata_read_native_max(device, retry_count, timeout, ccb, 2890 ident_buf, &hpasize); 2891 atahpa_print(ident_buf, hpasize, 1); 2892 2893 cam_freeccb(ccb); 2894 free(ident_buf); 2895 return (error); 2896 } 2897 2898 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) { 2899 warnx("HPA is not supported by this device"); 2900 cam_freeccb(ccb); 2901 free(ident_buf); 2902 return (1); 2903 } 2904 2905 if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) { 2906 warnx("HPA Security is not supported by this device"); 2907 cam_freeccb(ccb); 2908 free(ident_buf); 2909 return (1); 2910 } 2911 2912 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48; 2913 2914 /* 2915 * The ATA spec requires: 2916 * 1. Read native max addr is called directly before set max addr 2917 * 2. Read native max addr is NOT called before any other set max call 2918 */ 2919 switch(action) { 2920 case ATA_HPA_ACTION_SET_MAX: 2921 if (confirm == 0 && 2922 atahpa_set_confirm(device, ident_buf, maxsize, 2923 persist) == 0) { 2924 cam_freeccb(ccb); 2925 free(ident_buf); 2926 return (1); 2927 } 2928 2929 error = ata_read_native_max(device, retry_count, timeout, 2930 ccb, ident_buf, &hpasize); 2931 if (error == 0) { 2932 error = atahpa_set_max(device, retry_count, timeout, 2933 ccb, is48bit, maxsize, persist); 2934 if (error == 0) { 2935 if (quiet == 0) { 2936 /* redo identify to get new values */ 2937 error = ata_do_identify(device, 2938 retry_count, timeout, ccb, 2939 &ident_buf); 2940 atahpa_print(ident_buf, hpasize, 1); 2941 } 2942 /* Hint CAM to reprobe the device. */ 2943 reprobe(device); 2944 } 2945 } 2946 break; 2947 2948 case ATA_HPA_ACTION_SET_PWD: 2949 error = atahpa_password(device, retry_count, timeout, 2950 ccb, is48bit, &pwd); 2951 if (error == 0 && quiet == 0) 2952 printf("HPA password has been set\n"); 2953 break; 2954 2955 case ATA_HPA_ACTION_LOCK: 2956 error = atahpa_lock(device, retry_count, timeout, 2957 ccb, is48bit); 2958 if (error == 0 && quiet == 0) 2959 printf("HPA has been locked\n"); 2960 break; 2961 2962 case ATA_HPA_ACTION_UNLOCK: 2963 error = atahpa_unlock(device, retry_count, timeout, 2964 ccb, is48bit, &pwd); 2965 if (error == 0 && quiet == 0) 2966 printf("HPA has been unlocked\n"); 2967 break; 2968 2969 case ATA_HPA_ACTION_FREEZE_LOCK: 2970 error = atahpa_freeze_lock(device, retry_count, timeout, 2971 ccb, is48bit); 2972 if (error == 0 && quiet == 0) 2973 printf("HPA has been frozen\n"); 2974 break; 2975 2976 default: 2977 errx(1, "Option currently not supported"); 2978 } 2979 2980 cam_freeccb(ccb); 2981 free(ident_buf); 2982 2983 return (error); 2984} 2985 2986enum { 2987 ATA_AMA_ACTION_PRINT, 2988 ATA_AMA_ACTION_SET_MAX, 2989 ATA_AMA_ACTION_FREEZE_LOCK 2990}; 2991 2992static int 2993ataama(struct cam_device *device, int retry_count, int timeout, 2994 int argc, char **argv, char *combinedopt) 2995{ 2996 union ccb *ccb; 2997 struct ata_params *ident_buf; 2998 struct ccb_getdev cgd; 2999 int error, quiet, c, action, actions; 3000 u_int64_t nativesize, maxsize; 3001 3002 actions = 0; 3003 quiet = 0; 3004 maxsize = 0; 3005 3006 /* default action is to print AMA information */ 3007 action = ATA_AMA_ACTION_PRINT; 3008 3009 while ((c = getopt(argc, argv, combinedopt)) != -1) { 3010 switch(c){ 3011 case 's': 3012 action = ATA_AMA_ACTION_SET_MAX; 3013 maxsize = strtoumax(optarg, NULL, 0); 3014 actions++; 3015 break; 3016 3017 case 'f': 3018 action = ATA_AMA_ACTION_FREEZE_LOCK; 3019 actions++; 3020 break; 3021 3022 case 'q': 3023 quiet++; 3024 break; 3025 } 3026 } 3027 3028 if (actions > 1) { 3029 warnx("too many AMA actions specified"); 3030 return (1); 3031 } 3032 3033 if (get_cgd(device, &cgd) != 0) { 3034 warnx("couldn't get CGD"); 3035 return (1); 3036 } 3037 3038 ccb = cam_getccb(device); 3039 if (ccb == NULL) { 3040 warnx("couldn't allocate CCB"); 3041 return (1); 3042 } 3043 3044 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf); 3045 if (error != 0) { 3046 cam_freeccb(ccb); 3047 return (1); 3048 } 3049 3050 if (quiet == 0) { 3051 printf("%s%d: ", device->device_name, device->dev_unit_num); 3052 ata_print_ident(ident_buf); 3053 camxferrate(device); 3054 } 3055 3056 if (action == ATA_AMA_ACTION_PRINT) { 3057 nativesize = 0; 3058 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR) 3059 ata_get_native_max(device, retry_count, timeout, ccb, 3060 &nativesize); 3061 ataama_print(ident_buf, nativesize, 1); 3062 3063 cam_freeccb(ccb); 3064 free(ident_buf); 3065 return (error); 3066 } 3067 3068 if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) { 3069 warnx("Accessible Max Address is not supported by this device"); 3070 cam_freeccb(ccb); 3071 free(ident_buf); 3072 return (1); 3073 } 3074 3075 switch(action) { 3076 case ATA_AMA_ACTION_SET_MAX: 3077 error = ata_get_native_max(device, retry_count, timeout, ccb, 3078 &nativesize); 3079 if (error == 0) { 3080 error = ataama_set(device, retry_count, timeout, 3081 ccb, maxsize); 3082 if (error == 0) { 3083 if (quiet == 0) { 3084 /* redo identify to get new values */ 3085 error = ata_do_identify(device, 3086 retry_count, timeout, ccb, 3087 &ident_buf); 3088 ataama_print(ident_buf, nativesize, 1); 3089 } 3090 /* Hint CAM to reprobe the device. */ 3091 reprobe(device); 3092 } 3093 } 3094 break; 3095 3096 case ATA_AMA_ACTION_FREEZE_LOCK: 3097 error = ataama_freeze(device, retry_count, timeout, 3098 ccb); 3099 if (error == 0 && quiet == 0) 3100 printf("Accessible Max Address has been frozen\n"); 3101 break; 3102 3103 default: 3104 errx(1, "Option currently not supported"); 3105 } 3106 3107 cam_freeccb(ccb); 3108 free(ident_buf); 3109 3110 return (error); 3111} 3112 3113static int 3114atasecurity(struct cam_device *device, int retry_count, int timeout, 3115 int argc, char **argv, char *combinedopt) 3116{ 3117 union ccb *ccb; 3118 struct ata_params *ident_buf; 3119 int error, confirm, quiet, c, action, actions, setpwd; 3120 int security_enabled, erase_timeout, pwdsize; 3121 struct ata_security_password pwd; 3122 3123 actions = 0; 3124 setpwd = 0; 3125 erase_timeout = 0; 3126 confirm = 0; 3127 quiet = 0; 3128 3129 memset(&pwd, 0, sizeof(pwd)); 3130 3131 /* default action is to print security information */ 3132 action = ATA_SECURITY_ACTION_PRINT; 3133 3134 /* user is master by default as its safer that way */ 3135 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER; 3136 pwdsize = sizeof(pwd.password); 3137 3138 while ((c = getopt(argc, argv, combinedopt)) != -1) { 3139 switch(c){ 3140 case 'f': 3141 action = ATA_SECURITY_ACTION_FREEZE; 3142 actions++; 3143 break; 3144 3145 case 'U': 3146 if (strcasecmp(optarg, "user") == 0) { 3147 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER; 3148 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER; 3149 } else if (strcasecmp(optarg, "master") == 0) { 3150 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER; 3151 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER; 3152 } else { 3153 warnx("-U argument '%s' is invalid (must be " 3154 "'user' or 'master')", optarg); 3155 return (1); 3156 } 3157 break; 3158 3159 case 'l': 3160 if (strcasecmp(optarg, "high") == 0) { 3161 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH; 3162 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM; 3163 } else if (strcasecmp(optarg, "maximum") == 0) { 3164 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM; 3165 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH; 3166 } else { 3167 warnx("-l argument '%s' is unknown (must be " 3168 "'high' or 'maximum')", optarg); 3169 return (1); 3170 } 3171 break; 3172 3173 case 'k': 3174 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 3175 return (1); 3176 action = ATA_SECURITY_ACTION_UNLOCK; 3177 actions++; 3178 break; 3179 3180 case 'd': 3181 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 3182 return (1); 3183 action = ATA_SECURITY_ACTION_DISABLE; 3184 actions++; 3185 break; 3186 3187 case 'e': 3188 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 3189 return (1); 3190 action = ATA_SECURITY_ACTION_ERASE; 3191 actions++; 3192 break; 3193 3194 case 'h': 3195 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 3196 return (1); 3197 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED; 3198 action = ATA_SECURITY_ACTION_ERASE_ENHANCED; 3199 actions++; 3200 break; 3201 3202 case 's': 3203 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 3204 return (1); 3205 setpwd = 1; 3206 if (action == ATA_SECURITY_ACTION_PRINT) 3207 action = ATA_SECURITY_ACTION_SET_PASSWORD; 3208 /* 3209 * Don't increment action as this can be combined 3210 * with other actions. 3211 */ 3212 break; 3213 3214 case 'y': 3215 confirm++; 3216 break; 3217 3218 case 'q': 3219 quiet++; 3220 break; 3221 3222 case 'T': 3223 erase_timeout = atoi(optarg) * 1000; 3224 break; 3225 } 3226 } 3227 3228 if (actions > 1) { 3229 warnx("too many security actions specified"); 3230 return (1); 3231 } 3232 3233 if ((ccb = cam_getccb(device)) == NULL) { 3234 warnx("couldn't allocate CCB"); 3235 return (1); 3236 } 3237 3238 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf); 3239 if (error != 0) { 3240 cam_freeccb(ccb); 3241 return (1); 3242 } 3243 3244 if (quiet == 0) { 3245 printf("%s%d: ", device->device_name, device->dev_unit_num); 3246 ata_print_ident(ident_buf); 3247 camxferrate(device); 3248 } 3249 3250 if (action == ATA_SECURITY_ACTION_PRINT) { 3251 atasecurity_print(ident_buf); 3252 free(ident_buf); 3253 cam_freeccb(ccb); 3254 return (0); 3255 } 3256 3257 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) { 3258 warnx("Security not supported"); 3259 free(ident_buf); 3260 cam_freeccb(ccb); 3261 return (1); 3262 } 3263 3264 /* default timeout 15 seconds the same as linux hdparm */ 3265 timeout = timeout ? timeout : 15 * 1000; 3266 3267 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED; 3268 3269 /* first set the password if requested */ 3270 if (setpwd == 1) { 3271 /* confirm we can erase before setting the password if erasing */ 3272 if (confirm == 0 && 3273 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED || 3274 action == ATA_SECURITY_ACTION_ERASE) && 3275 atasecurity_erase_confirm(device, ident_buf) == 0) { 3276 cam_freeccb(ccb); 3277 free(ident_buf); 3278 return (error); 3279 } 3280 3281 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) { 3282 pwd.revision = ident_buf->master_passwd_revision; 3283 if (pwd.revision != 0 && pwd.revision != 0xfff && 3284 --pwd.revision == 0) { 3285 pwd.revision = 0xfffe; 3286 } 3287 } 3288 error = atasecurity_set_password(device, ccb, retry_count, 3289 timeout, &pwd, quiet); 3290 if (error != 0) { 3291 cam_freeccb(ccb); 3292 free(ident_buf); 3293 return (error); 3294 } 3295 security_enabled = 1; 3296 } 3297 3298 switch(action) { 3299 case ATA_SECURITY_ACTION_FREEZE: 3300 error = atasecurity_freeze(device, ccb, retry_count, 3301 timeout, quiet); 3302 break; 3303 3304 case ATA_SECURITY_ACTION_UNLOCK: 3305 if (security_enabled) { 3306 if (ident_buf->security_status & ATA_SECURITY_LOCKED) { 3307 error = atasecurity_unlock(device, ccb, 3308 retry_count, timeout, &pwd, quiet); 3309 } else { 3310 warnx("Can't unlock, drive is not locked"); 3311 error = 1; 3312 } 3313 } else { 3314 warnx("Can't unlock, security is disabled"); 3315 error = 1; 3316 } 3317 break; 3318 3319 case ATA_SECURITY_ACTION_DISABLE: 3320 if (security_enabled) { 3321 /* First unlock the drive if its locked */ 3322 if (ident_buf->security_status & ATA_SECURITY_LOCKED) { 3323 error = atasecurity_unlock(device, ccb, 3324 retry_count, 3325 timeout, 3326 &pwd, 3327 quiet); 3328 } 3329 3330 if (error == 0) { 3331 error = atasecurity_disable(device, 3332 ccb, 3333 retry_count, 3334 timeout, 3335 &pwd, 3336 quiet); 3337 } 3338 } else { 3339 warnx("Can't disable security (already disabled)"); 3340 error = 1; 3341 } 3342 break; 3343 3344 case ATA_SECURITY_ACTION_ERASE: 3345 if (security_enabled) { 3346 if (erase_timeout == 0) { 3347 erase_timeout = atasecurity_erase_timeout_msecs( 3348 ident_buf->erase_time); 3349 } 3350 3351 error = atasecurity_erase(device, ccb, retry_count, 3352 timeout, erase_timeout, &pwd, quiet); 3353 } else { 3354 warnx("Can't secure erase (security is disabled)"); 3355 error = 1; 3356 } 3357 break; 3358 3359 case ATA_SECURITY_ACTION_ERASE_ENHANCED: 3360 if (security_enabled) { 3361 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) { 3362 if (erase_timeout == 0) { 3363 erase_timeout = 3364 atasecurity_erase_timeout_msecs( 3365 ident_buf->enhanced_erase_time); 3366 } 3367 3368 error = atasecurity_erase(device, ccb, 3369 retry_count, timeout, 3370 erase_timeout, &pwd, 3371 quiet); 3372 } else { 3373 warnx("Enhanced erase is not supported"); 3374 error = 1; 3375 } 3376 } else { 3377 warnx("Can't secure erase (enhanced), " 3378 "(security is disabled)"); 3379 error = 1; 3380 } 3381 break; 3382 } 3383 3384 cam_freeccb(ccb); 3385 free(ident_buf); 3386 3387 return (error); 3388} 3389 3390/* 3391 * Convert periph name into a bus, target and lun. 3392 * 3393 * Returns the number of parsed components, or 0. 3394 */ 3395static int 3396parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun, 3397 cam_argmask *arglst) 3398{ 3399 int fd; 3400 union ccb ccb; 3401 3402 bzero(&ccb, sizeof(ccb)); 3403 ccb.ccb_h.func_code = XPT_GDEVLIST; 3404 if (cam_get_device(tstr, ccb.cgdl.periph_name, 3405 sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) { 3406 warnx("%s", cam_errbuf); 3407 return (0); 3408 } 3409 3410 /* 3411 * Attempt to get the passthrough device. This ioctl will 3412 * fail if the device name is null, if the device doesn't 3413 * exist, or if the passthrough driver isn't in the kernel. 3414 */ 3415 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { 3416 warn("Unable to open %s", XPT_DEVICE); 3417 return (0); 3418 } 3419 if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) { 3420 warn("Unable to find bus:target:lun for device %s%d", 3421 ccb.cgdl.periph_name, ccb.cgdl.unit_number); 3422 close(fd); 3423 return (0); 3424 } 3425 close(fd); 3426 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 3427 const struct cam_status_entry *entry; 3428 3429 entry = cam_fetch_status_entry(ccb.ccb_h.status); 3430 warnx("Unable to find bus:target_lun for device %s%d, " 3431 "CAM status: %s (%#x)", 3432 ccb.cgdl.periph_name, ccb.cgdl.unit_number, 3433 entry ? entry->status_text : "Unknown", 3434 ccb.ccb_h.status); 3435 return (0); 3436 } 3437 3438 /* 3439 * The kernel fills in the bus/target/lun. We don't 3440 * need the passthrough device name and unit number since 3441 * we aren't going to open it. 3442 */ 3443 *bus = ccb.ccb_h.path_id; 3444 *target = ccb.ccb_h.target_id; 3445 *lun = ccb.ccb_h.target_lun; 3446 *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN; 3447 return (3); 3448} 3449 3450/* 3451 * Parse out a bus, or a bus, target and lun in the following 3452 * format: 3453 * bus 3454 * bus:target 3455 * bus:target:lun 3456 * 3457 * Returns the number of parsed components, or 0. 3458 */ 3459static int 3460parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun, 3461 cam_argmask *arglst) 3462{ 3463 char *tmpstr, *end; 3464 int convs = 0; 3465 3466 *bus = CAM_BUS_WILDCARD; 3467 *target = CAM_TARGET_WILDCARD; 3468 *lun = CAM_LUN_WILDCARD; 3469 3470 while (isspace(*tstr) && (*tstr != '\0')) 3471 tstr++; 3472 3473 if (strncasecmp(tstr, "all", strlen("all")) == 0) { 3474 arglist |= CAM_ARG_BUS; 3475 return (1); 3476 } 3477 3478 if (!isdigit(*tstr)) 3479 return (parse_btl_name(tstr, bus, target, lun, arglst)); 3480 3481 tmpstr = strsep(&tstr, ":"); 3482 if ((tmpstr != NULL) && (*tmpstr != '\0')) { 3483 *bus = strtol(tmpstr, &end, 0); 3484 if (*end != '\0') 3485 return (0); 3486 *arglst |= CAM_ARG_BUS; 3487 convs++; 3488 tmpstr = strsep(&tstr, ":"); 3489 if ((tmpstr != NULL) && (*tmpstr != '\0')) { 3490 *target = strtol(tmpstr, &end, 0); 3491 if (*end != '\0') 3492 return (0); 3493 *arglst |= CAM_ARG_TARGET; 3494 convs++; 3495 tmpstr = strsep(&tstr, ":"); 3496 if ((tmpstr != NULL) && (*tmpstr != '\0')) { 3497 *lun = strtoll(tmpstr, &end, 0); 3498 if (*end != '\0') 3499 return (0); 3500 *arglst |= CAM_ARG_LUN; 3501 convs++; 3502 } 3503 } 3504 } 3505 3506 return convs; 3507} 3508 3509static int 3510dorescan_or_reset(int argc, char **argv, int rescan) 3511{ 3512 static const char must[] = 3513 "you must specify \"all\", a bus, a bus:target:lun or periph to %s"; 3514 int rv, error = 0; 3515 path_id_t bus = CAM_BUS_WILDCARD; 3516 target_id_t target = CAM_TARGET_WILDCARD; 3517 lun_id_t lun = CAM_LUN_WILDCARD; 3518 char *tstr; 3519 3520 if (argc < 3) { 3521 warnx(must, rescan? "rescan" : "reset"); 3522 return (1); 3523 } 3524 3525 tstr = argv[optind]; 3526 while (isspace(*tstr) && (*tstr != '\0')) 3527 tstr++; 3528 if (strncasecmp(tstr, "all", strlen("all")) == 0) 3529 arglist |= CAM_ARG_BUS; 3530 else { 3531 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist); 3532 if (rv != 1 && rv != 3) { 3533 warnx(must, rescan ? "rescan" : "reset"); 3534 return (1); 3535 } 3536 } 3537 3538 if (arglist & CAM_ARG_LUN) 3539 error = scanlun_or_reset_dev(bus, target, lun, rescan); 3540 else 3541 error = rescan_or_reset_bus(bus, rescan); 3542 3543 return (error); 3544} 3545 3546static int 3547rescan_or_reset_bus(path_id_t bus, int rescan) 3548{ 3549 union ccb *ccb = NULL, *matchccb = NULL; 3550 int fd = -1, retval; 3551 int bufsize; 3552 3553 retval = 0; 3554 3555 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { 3556 warnx("error opening transport layer device %s", XPT_DEVICE); 3557 warn("%s", XPT_DEVICE); 3558 return (1); 3559 } 3560 3561 ccb = malloc(sizeof(*ccb)); 3562 if (ccb == NULL) { 3563 warn("failed to allocate CCB"); 3564 retval = 1; 3565 goto bailout; 3566 } 3567 bzero(ccb, sizeof(*ccb)); 3568 3569 if (bus != CAM_BUS_WILDCARD) { 3570 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS; 3571 ccb->ccb_h.path_id = bus; 3572 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD; 3573 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD; 3574 ccb->crcn.flags = CAM_FLAG_NONE; 3575 3576 /* run this at a low priority */ 3577 ccb->ccb_h.pinfo.priority = 5; 3578 3579 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) { 3580 warn("CAMIOCOMMAND ioctl failed"); 3581 retval = 1; 3582 goto bailout; 3583 } 3584 3585 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { 3586 fprintf(stdout, "%s of bus %d was successful\n", 3587 rescan ? "Re-scan" : "Reset", bus); 3588 } else { 3589 fprintf(stdout, "%s of bus %d returned error %#x\n", 3590 rescan ? "Re-scan" : "Reset", bus, 3591 ccb->ccb_h.status & CAM_STATUS_MASK); 3592 retval = 1; 3593 } 3594 3595 goto bailout; 3596 } 3597 3598 3599 /* 3600 * The right way to handle this is to modify the xpt so that it can 3601 * handle a wildcarded bus in a rescan or reset CCB. At the moment 3602 * that isn't implemented, so instead we enumerate the buses and 3603 * send the rescan or reset to those buses in the case where the 3604 * given bus is -1 (wildcard). We don't send a rescan or reset 3605 * to the xpt bus; sending a rescan to the xpt bus is effectively a 3606 * no-op, sending a rescan to the xpt bus would result in a status of 3607 * CAM_REQ_INVALID. 3608 */ 3609 matchccb = malloc(sizeof(*matchccb)); 3610 if (matchccb == NULL) { 3611 warn("failed to allocate CCB"); 3612 retval = 1; 3613 goto bailout; 3614 } 3615 bzero(matchccb, sizeof(*matchccb)); 3616 matchccb->ccb_h.func_code = XPT_DEV_MATCH; 3617 matchccb->ccb_h.path_id = CAM_BUS_WILDCARD; 3618 bufsize = sizeof(struct dev_match_result) * 20; 3619 matchccb->cdm.match_buf_len = bufsize; 3620 matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize); 3621 if (matchccb->cdm.matches == NULL) { 3622 warnx("can't malloc memory for matches"); 3623 retval = 1; 3624 goto bailout; 3625 } 3626 matchccb->cdm.num_matches = 0; 3627 3628 matchccb->cdm.num_patterns = 1; 3629 matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern); 3630 3631 matchccb->cdm.patterns = (struct dev_match_pattern *)malloc( 3632 matchccb->cdm.pattern_buf_len); 3633 if (matchccb->cdm.patterns == NULL) { 3634 warnx("can't malloc memory for patterns"); 3635 retval = 1; 3636 goto bailout; 3637 } 3638 matchccb->cdm.patterns[0].type = DEV_MATCH_BUS; 3639 matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY; 3640 3641 do { 3642 unsigned int i; 3643 3644 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) { 3645 warn("CAMIOCOMMAND ioctl failed"); 3646 retval = 1; 3647 goto bailout; 3648 } 3649 3650 if ((matchccb->ccb_h.status != CAM_REQ_CMP) 3651 || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST) 3652 && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) { 3653 warnx("got CAM error %#x, CDM error %d\n", 3654 matchccb->ccb_h.status, matchccb->cdm.status); 3655 retval = 1; 3656 goto bailout; 3657 } 3658 3659 for (i = 0; i < matchccb->cdm.num_matches; i++) { 3660 struct bus_match_result *bus_result; 3661 3662 /* This shouldn't happen. */ 3663 if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS) 3664 continue; 3665 3666 bus_result =&matchccb->cdm.matches[i].result.bus_result; 3667 3668 /* 3669 * We don't want to rescan or reset the xpt bus. 3670 * See above. 3671 */ 3672 if (bus_result->path_id == CAM_XPT_PATH_ID) 3673 continue; 3674 3675 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : 3676 XPT_RESET_BUS; 3677 ccb->ccb_h.path_id = bus_result->path_id; 3678 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD; 3679 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD; 3680 ccb->crcn.flags = CAM_FLAG_NONE; 3681 3682 /* run this at a low priority */ 3683 ccb->ccb_h.pinfo.priority = 5; 3684 3685 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) { 3686 warn("CAMIOCOMMAND ioctl failed"); 3687 retval = 1; 3688 goto bailout; 3689 } 3690 3691 if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){ 3692 fprintf(stdout, "%s of bus %d was successful\n", 3693 rescan? "Re-scan" : "Reset", 3694 bus_result->path_id); 3695 } else { 3696 /* 3697 * Don't bail out just yet, maybe the other 3698 * rescan or reset commands will complete 3699 * successfully. 3700 */ 3701 fprintf(stderr, "%s of bus %d returned error " 3702 "%#x\n", rescan? "Re-scan" : "Reset", 3703 bus_result->path_id, 3704 ccb->ccb_h.status & CAM_STATUS_MASK); 3705 retval = 1; 3706 } 3707 } 3708 } while ((matchccb->ccb_h.status == CAM_REQ_CMP) 3709 && (matchccb->cdm.status == CAM_DEV_MATCH_MORE)); 3710 3711bailout: 3712 3713 if (fd != -1) 3714 close(fd); 3715 3716 if (matchccb != NULL) { 3717 free(matchccb->cdm.patterns); 3718 free(matchccb->cdm.matches); 3719 free(matchccb); 3720 } 3721 free(ccb); 3722 3723 return (retval); 3724} 3725 3726static int 3727scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan) 3728{ 3729 union ccb ccb; 3730 struct cam_device *device; 3731 int fd; 3732 3733 device = NULL; 3734 3735 if (bus == CAM_BUS_WILDCARD) { 3736 warnx("invalid bus number %d", bus); 3737 return (1); 3738 } 3739 3740 if (target == CAM_TARGET_WILDCARD) { 3741 warnx("invalid target number %d", target); 3742 return (1); 3743 } 3744 3745 if (lun == CAM_LUN_WILDCARD) { 3746 warnx("invalid lun number %jx", (uintmax_t)lun); 3747 return (1); 3748 } 3749 3750 fd = -1; 3751 3752 bzero(&ccb, sizeof(union ccb)); 3753 3754 if (scan) { 3755 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { 3756 warnx("error opening transport layer device %s\n", 3757 XPT_DEVICE); 3758 warn("%s", XPT_DEVICE); 3759 return (1); 3760 } 3761 } else { 3762 device = cam_open_btl(bus, target, lun, O_RDWR, NULL); 3763 if (device == NULL) { 3764 warnx("%s", cam_errbuf); 3765 return (1); 3766 } 3767 } 3768 3769 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV; 3770 ccb.ccb_h.path_id = bus; 3771 ccb.ccb_h.target_id = target; 3772 ccb.ccb_h.target_lun = lun; 3773 ccb.ccb_h.timeout = 5000; 3774 ccb.crcn.flags = CAM_FLAG_NONE; 3775 3776 /* run this at a low priority */ 3777 ccb.ccb_h.pinfo.priority = 5; 3778 3779 if (scan) { 3780 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) { 3781 warn("CAMIOCOMMAND ioctl failed"); 3782 close(fd); 3783 return (1); 3784 } 3785 } else { 3786 if (cam_send_ccb(device, &ccb) < 0) { 3787 warn("error sending XPT_RESET_DEV CCB"); 3788 cam_close_device(device); 3789 return (1); 3790 } 3791 } 3792 3793 if (scan) 3794 close(fd); 3795 else 3796 cam_close_device(device); 3797 3798 /* 3799 * An error code of CAM_BDR_SENT is normal for a BDR request. 3800 */ 3801 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 3802 || ((!scan) 3803 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) { 3804 fprintf(stdout, "%s of %d:%d:%jx was successful\n", 3805 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun); 3806 return (0); 3807 } else { 3808 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n", 3809 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun, 3810 ccb.ccb_h.status & CAM_STATUS_MASK); 3811 return (1); 3812 } 3813} 3814 3815 3816static struct scsi_nv defect_list_type_map[] = { 3817 { "block", SRDD10_BLOCK_FORMAT }, 3818 { "extbfi", SRDD10_EXT_BFI_FORMAT }, 3819 { "extphys", SRDD10_EXT_PHYS_FORMAT }, 3820 { "longblock", SRDD10_LONG_BLOCK_FORMAT }, 3821 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT }, 3822 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT } 3823}; 3824 3825static int 3826readdefects(struct cam_device *device, int argc, char **argv, 3827 char *combinedopt, int task_attr, int retry_count, int timeout) 3828{ 3829 union ccb *ccb = NULL; 3830 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL; 3831 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL; 3832 size_t hdr_size = 0, entry_size = 0; 3833 int use_12byte = 0; 3834 int hex_format = 0; 3835 u_int8_t *defect_list = NULL; 3836 u_int8_t list_format = 0; 3837 int list_type_set = 0; 3838 u_int32_t dlist_length = 0; 3839 u_int32_t returned_length = 0, valid_len = 0; 3840 u_int32_t num_returned = 0, num_valid = 0; 3841 u_int32_t max_possible_size = 0, hdr_max = 0; 3842 u_int32_t starting_offset = 0; 3843 u_int8_t returned_format, returned_type; 3844 unsigned int i; 3845 int summary = 0, quiet = 0; 3846 int c, error = 0; 3847 int lists_specified = 0; 3848 int get_length = 1, first_pass = 1; 3849 int mads = 0; 3850 3851 while ((c = getopt(argc, argv, combinedopt)) != -1) { 3852 switch(c){ 3853 case 'f': 3854 { 3855 scsi_nv_status status; 3856 int entry_num = 0; 3857 3858 status = scsi_get_nv(defect_list_type_map, 3859 sizeof(defect_list_type_map) / 3860 sizeof(defect_list_type_map[0]), optarg, 3861 &entry_num, SCSI_NV_FLAG_IG_CASE); 3862 3863 if (status == SCSI_NV_FOUND) { 3864 list_format = defect_list_type_map[ 3865 entry_num].value; 3866 list_type_set = 1; 3867 } else { 3868 warnx("%s: %s %s option %s", __func__, 3869 (status == SCSI_NV_AMBIGUOUS) ? 3870 "ambiguous" : "invalid", "defect list type", 3871 optarg); 3872 error = 1; 3873 goto defect_bailout; 3874 } 3875 break; 3876 } 3877 case 'G': 3878 arglist |= CAM_ARG_GLIST; 3879 break; 3880 case 'P': 3881 arglist |= CAM_ARG_PLIST; 3882 break; 3883 case 'q': 3884 quiet = 1; 3885 break; 3886 case 's': 3887 summary = 1; 3888 break; 3889 case 'S': { 3890 char *endptr; 3891 3892 starting_offset = strtoul(optarg, &endptr, 0); 3893 if (*endptr != '\0') { 3894 error = 1; 3895 warnx("invalid starting offset %s", optarg); 3896 goto defect_bailout; 3897 } 3898 break; 3899 } 3900 case 'X': 3901 hex_format = 1; 3902 break; 3903 default: 3904 break; 3905 } 3906 } 3907 3908 if (list_type_set == 0) { 3909 error = 1; 3910 warnx("no defect list format specified"); 3911 goto defect_bailout; 3912 } 3913 3914 if (arglist & CAM_ARG_PLIST) { 3915 list_format |= SRDD10_PLIST; 3916 lists_specified++; 3917 } 3918 3919 if (arglist & CAM_ARG_GLIST) { 3920 list_format |= SRDD10_GLIST; 3921 lists_specified++; 3922 } 3923 3924 /* 3925 * This implies a summary, and was the previous behavior. 3926 */ 3927 if (lists_specified == 0) 3928 summary = 1; 3929 3930 ccb = cam_getccb(device); 3931 3932retry_12byte: 3933 3934 /* 3935 * We start off asking for just the header to determine how much 3936 * defect data is available. Some Hitachi drives return an error 3937 * if you ask for more data than the drive has. Once we know the 3938 * length, we retry the command with the returned length. 3939 */ 3940 if (use_12byte == 0) 3941 dlist_length = sizeof(*hdr10); 3942 else 3943 dlist_length = sizeof(*hdr12); 3944 3945retry: 3946 if (defect_list != NULL) { 3947 free(defect_list); 3948 defect_list = NULL; 3949 } 3950 defect_list = malloc(dlist_length); 3951 if (defect_list == NULL) { 3952 warnx("can't malloc memory for defect list"); 3953 error = 1; 3954 goto defect_bailout; 3955 } 3956 3957next_batch: 3958 bzero(defect_list, dlist_length); 3959 3960 /* 3961 * cam_getccb() zeros the CCB header only. So we need to zero the 3962 * payload portion of the ccb. 3963 */ 3964 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 3965 3966 scsi_read_defects(&ccb->csio, 3967 /*retries*/ retry_count, 3968 /*cbfcnp*/ NULL, 3969 /*tag_action*/ task_attr, 3970 /*list_format*/ list_format, 3971 /*addr_desc_index*/ starting_offset, 3972 /*data_ptr*/ defect_list, 3973 /*dxfer_len*/ dlist_length, 3974 /*minimum_cmd_size*/ use_12byte ? 12 : 0, 3975 /*sense_len*/ SSD_FULL_SIZE, 3976 /*timeout*/ timeout ? timeout : 5000); 3977 3978 /* Disable freezing the device queue */ 3979 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 3980 3981 if (cam_send_ccb(device, ccb) < 0) { 3982 warn("error sending READ DEFECT DATA command"); 3983 error = 1; 3984 goto defect_bailout; 3985 } 3986 3987 valid_len = ccb->csio.dxfer_len - ccb->csio.resid; 3988 3989 if (use_12byte == 0) { 3990 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list; 3991 hdr_size = sizeof(*hdr10); 3992 hdr_max = SRDDH10_MAX_LENGTH; 3993 3994 if (valid_len >= hdr_size) { 3995 returned_length = scsi_2btoul(hdr10->length); 3996 returned_format = hdr10->format; 3997 } else { 3998 returned_length = 0; 3999 returned_format = 0; 4000 } 4001 } else { 4002 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list; 4003 hdr_size = sizeof(*hdr12); 4004 hdr_max = SRDDH12_MAX_LENGTH; 4005 4006 if (valid_len >= hdr_size) { 4007 returned_length = scsi_4btoul(hdr12->length); 4008 returned_format = hdr12->format; 4009 } else { 4010 returned_length = 0; 4011 returned_format = 0; 4012 } 4013 } 4014 4015 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK; 4016 switch (returned_type) { 4017 case SRDD10_BLOCK_FORMAT: 4018 entry_size = sizeof(struct scsi_defect_desc_block); 4019 break; 4020 case SRDD10_LONG_BLOCK_FORMAT: 4021 entry_size = sizeof(struct scsi_defect_desc_long_block); 4022 break; 4023 case SRDD10_EXT_PHYS_FORMAT: 4024 case SRDD10_PHYSICAL_SECTOR_FORMAT: 4025 entry_size = sizeof(struct scsi_defect_desc_phys_sector); 4026 break; 4027 case SRDD10_EXT_BFI_FORMAT: 4028 case SRDD10_BYTES_FROM_INDEX_FORMAT: 4029 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index); 4030 break; 4031 default: 4032 warnx("Unknown defect format 0x%x\n", returned_type); 4033 error = 1; 4034 goto defect_bailout; 4035 break; 4036 } 4037 4038 max_possible_size = (hdr_max / entry_size) * entry_size; 4039 num_returned = returned_length / entry_size; 4040 num_valid = min(returned_length, valid_len - hdr_size); 4041 num_valid /= entry_size; 4042 4043 if (get_length != 0) { 4044 get_length = 0; 4045 4046 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 4047 CAM_SCSI_STATUS_ERROR) { 4048 struct scsi_sense_data *sense; 4049 int error_code, sense_key, asc, ascq; 4050 4051 sense = &ccb->csio.sense_data; 4052 scsi_extract_sense_len(sense, ccb->csio.sense_len - 4053 ccb->csio.sense_resid, &error_code, &sense_key, 4054 &asc, &ascq, /*show_errors*/ 1); 4055 4056 /* 4057 * If the drive is reporting that it just doesn't 4058 * support the defect list format, go ahead and use 4059 * the length it reported. Otherwise, the length 4060 * may not be valid, so use the maximum. 4061 */ 4062 if ((sense_key == SSD_KEY_RECOVERED_ERROR) 4063 && (asc == 0x1c) && (ascq == 0x00) 4064 && (returned_length > 0)) { 4065 if ((use_12byte == 0) 4066 && (returned_length >= max_possible_size)) { 4067 get_length = 1; 4068 use_12byte = 1; 4069 goto retry_12byte; 4070 } 4071 dlist_length = returned_length + hdr_size; 4072 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR) 4073 && (asc == 0x1f) && (ascq == 0x00) 4074 && (returned_length > 0)) { 4075 /* Partial defect list transfer */ 4076 /* 4077 * Hitachi drives return this error 4078 * along with a partial defect list if they 4079 * have more defects than the 10 byte 4080 * command can support. Retry with the 12 4081 * byte command. 4082 */ 4083 if (use_12byte == 0) { 4084 get_length = 1; 4085 use_12byte = 1; 4086 goto retry_12byte; 4087 } 4088 dlist_length = returned_length + hdr_size; 4089 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST) 4090 && (asc == 0x24) && (ascq == 0x00)) { 4091 /* Invalid field in CDB */ 4092 /* 4093 * SBC-3 says that if the drive has more 4094 * defects than can be reported with the 4095 * 10 byte command, it should return this 4096 * error and no data. Retry with the 12 4097 * byte command. 4098 */ 4099 if (use_12byte == 0) { 4100 get_length = 1; 4101 use_12byte = 1; 4102 goto retry_12byte; 4103 } 4104 dlist_length = returned_length + hdr_size; 4105 } else { 4106 /* 4107 * If we got a SCSI error and no valid length, 4108 * just use the 10 byte maximum. The 12 4109 * byte maximum is too large. 4110 */ 4111 if (returned_length == 0) 4112 dlist_length = SRDD10_MAX_LENGTH; 4113 else { 4114 if ((use_12byte == 0) 4115 && (returned_length >= 4116 max_possible_size)) { 4117 get_length = 1; 4118 use_12byte = 1; 4119 goto retry_12byte; 4120 } 4121 dlist_length = returned_length + 4122 hdr_size; 4123 } 4124 } 4125 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != 4126 CAM_REQ_CMP){ 4127 error = 1; 4128 warnx("Error reading defect header"); 4129 if (arglist & CAM_ARG_VERBOSE) 4130 cam_error_print(device, ccb, CAM_ESF_ALL, 4131 CAM_EPF_ALL, stderr); 4132 goto defect_bailout; 4133 } else { 4134 if ((use_12byte == 0) 4135 && (returned_length >= max_possible_size)) { 4136 get_length = 1; 4137 use_12byte = 1; 4138 goto retry_12byte; 4139 } 4140 dlist_length = returned_length + hdr_size; 4141 } 4142 if (summary != 0) { 4143 fprintf(stdout, "%u", num_returned); 4144 if (quiet == 0) { 4145 fprintf(stdout, " defect%s", 4146 (num_returned != 1) ? "s" : ""); 4147 } 4148 fprintf(stdout, "\n"); 4149 4150 goto defect_bailout; 4151 } 4152 4153 /* 4154 * We always limit the list length to the 10-byte maximum 4155 * length (0xffff). The reason is that some controllers 4156 * can't handle larger I/Os, and we can transfer the entire 4157 * 10 byte list in one shot. For drives that support the 12 4158 * byte read defects command, we'll step through the list 4159 * by specifying a starting offset. For drives that don't 4160 * support the 12 byte command's starting offset, we'll 4161 * just display the first 64K. 4162 */ 4163 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH); 4164 4165 goto retry; 4166 } 4167 4168 4169 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) 4170 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) 4171 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 4172 struct scsi_sense_data *sense; 4173 int error_code, sense_key, asc, ascq; 4174 4175 sense = &ccb->csio.sense_data; 4176 scsi_extract_sense_len(sense, ccb->csio.sense_len - 4177 ccb->csio.sense_resid, &error_code, &sense_key, &asc, 4178 &ascq, /*show_errors*/ 1); 4179 4180 /* 4181 * According to the SCSI spec, if the disk doesn't support 4182 * the requested format, it will generally return a sense 4183 * key of RECOVERED ERROR, and an additional sense code 4184 * of "DEFECT LIST NOT FOUND". HGST drives also return 4185 * Primary/Grown defect list not found errors. So just 4186 * check for an ASC of 0x1c. 4187 */ 4188 if ((sense_key == SSD_KEY_RECOVERED_ERROR) 4189 && (asc == 0x1c)) { 4190 const char *format_str; 4191 4192 format_str = scsi_nv_to_str(defect_list_type_map, 4193 sizeof(defect_list_type_map) / 4194 sizeof(defect_list_type_map[0]), 4195 list_format & SRDD10_DLIST_FORMAT_MASK); 4196 warnx("requested defect format %s not available", 4197 format_str ? format_str : "unknown"); 4198 4199 format_str = scsi_nv_to_str(defect_list_type_map, 4200 sizeof(defect_list_type_map) / 4201 sizeof(defect_list_type_map[0]), returned_type); 4202 if (format_str != NULL) { 4203 warnx("Device returned %s format", 4204 format_str); 4205 } else { 4206 error = 1; 4207 warnx("Device returned unknown defect" 4208 " data format %#x", returned_type); 4209 goto defect_bailout; 4210 } 4211 } else { 4212 error = 1; 4213 warnx("Error returned from read defect data command"); 4214 if (arglist & CAM_ARG_VERBOSE) 4215 cam_error_print(device, ccb, CAM_ESF_ALL, 4216 CAM_EPF_ALL, stderr); 4217 goto defect_bailout; 4218 } 4219 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4220 error = 1; 4221 warnx("Error returned from read defect data command"); 4222 if (arglist & CAM_ARG_VERBOSE) 4223 cam_error_print(device, ccb, CAM_ESF_ALL, 4224 CAM_EPF_ALL, stderr); 4225 goto defect_bailout; 4226 } 4227 4228 if (first_pass != 0) { 4229 fprintf(stderr, "Got %d defect", num_returned); 4230 4231 if ((lists_specified == 0) || (num_returned == 0)) { 4232 fprintf(stderr, "s.\n"); 4233 goto defect_bailout; 4234 } else if (num_returned == 1) 4235 fprintf(stderr, ":\n"); 4236 else 4237 fprintf(stderr, "s:\n"); 4238 4239 first_pass = 0; 4240 } 4241 4242 /* 4243 * XXX KDM I should probably clean up the printout format for the 4244 * disk defects. 4245 */ 4246 switch (returned_type) { 4247 case SRDD10_PHYSICAL_SECTOR_FORMAT: 4248 case SRDD10_EXT_PHYS_FORMAT: 4249 { 4250 struct scsi_defect_desc_phys_sector *dlist; 4251 4252 dlist = (struct scsi_defect_desc_phys_sector *) 4253 (defect_list + hdr_size); 4254 4255 for (i = 0; i < num_valid; i++) { 4256 uint32_t sector; 4257 4258 sector = scsi_4btoul(dlist[i].sector); 4259 if (returned_type == SRDD10_EXT_PHYS_FORMAT) { 4260 mads = (sector & SDD_EXT_PHYS_MADS) ? 4261 0 : 1; 4262 sector &= ~SDD_EXT_PHYS_FLAG_MASK; 4263 } 4264 if (hex_format == 0) 4265 fprintf(stdout, "%d:%d:%d%s", 4266 scsi_3btoul(dlist[i].cylinder), 4267 dlist[i].head, 4268 scsi_4btoul(dlist[i].sector), 4269 mads ? " - " : "\n"); 4270 else 4271 fprintf(stdout, "0x%x:0x%x:0x%x%s", 4272 scsi_3btoul(dlist[i].cylinder), 4273 dlist[i].head, 4274 scsi_4btoul(dlist[i].sector), 4275 mads ? " - " : "\n"); 4276 mads = 0; 4277 } 4278 if (num_valid < num_returned) { 4279 starting_offset += num_valid; 4280 goto next_batch; 4281 } 4282 break; 4283 } 4284 case SRDD10_BYTES_FROM_INDEX_FORMAT: 4285 case SRDD10_EXT_BFI_FORMAT: 4286 { 4287 struct scsi_defect_desc_bytes_from_index *dlist; 4288 4289 dlist = (struct scsi_defect_desc_bytes_from_index *) 4290 (defect_list + hdr_size); 4291 4292 for (i = 0; i < num_valid; i++) { 4293 uint32_t bfi; 4294 4295 bfi = scsi_4btoul(dlist[i].bytes_from_index); 4296 if (returned_type == SRDD10_EXT_BFI_FORMAT) { 4297 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0; 4298 bfi &= ~SDD_EXT_BFI_FLAG_MASK; 4299 } 4300 if (hex_format == 0) 4301 fprintf(stdout, "%d:%d:%d%s", 4302 scsi_3btoul(dlist[i].cylinder), 4303 dlist[i].head, 4304 scsi_4btoul(dlist[i].bytes_from_index), 4305 mads ? " - " : "\n"); 4306 else 4307 fprintf(stdout, "0x%x:0x%x:0x%x%s", 4308 scsi_3btoul(dlist[i].cylinder), 4309 dlist[i].head, 4310 scsi_4btoul(dlist[i].bytes_from_index), 4311 mads ? " - " : "\n"); 4312 4313 mads = 0; 4314 } 4315 if (num_valid < num_returned) { 4316 starting_offset += num_valid; 4317 goto next_batch; 4318 } 4319 break; 4320 } 4321 case SRDDH10_BLOCK_FORMAT: 4322 { 4323 struct scsi_defect_desc_block *dlist; 4324 4325 dlist = (struct scsi_defect_desc_block *) 4326 (defect_list + hdr_size); 4327 4328 for (i = 0; i < num_valid; i++) { 4329 if (hex_format == 0) 4330 fprintf(stdout, "%u\n", 4331 scsi_4btoul(dlist[i].address)); 4332 else 4333 fprintf(stdout, "0x%x\n", 4334 scsi_4btoul(dlist[i].address)); 4335 } 4336 4337 if (num_valid < num_returned) { 4338 starting_offset += num_valid; 4339 goto next_batch; 4340 } 4341 4342 break; 4343 } 4344 case SRDD10_LONG_BLOCK_FORMAT: 4345 { 4346 struct scsi_defect_desc_long_block *dlist; 4347 4348 dlist = (struct scsi_defect_desc_long_block *) 4349 (defect_list + hdr_size); 4350 4351 for (i = 0; i < num_valid; i++) { 4352 if (hex_format == 0) 4353 fprintf(stdout, "%ju\n", 4354 (uintmax_t)scsi_8btou64( 4355 dlist[i].address)); 4356 else 4357 fprintf(stdout, "0x%jx\n", 4358 (uintmax_t)scsi_8btou64( 4359 dlist[i].address)); 4360 } 4361 4362 if (num_valid < num_returned) { 4363 starting_offset += num_valid; 4364 goto next_batch; 4365 } 4366 break; 4367 } 4368 default: 4369 fprintf(stderr, "Unknown defect format 0x%x\n", 4370 returned_type); 4371 error = 1; 4372 break; 4373 } 4374defect_bailout: 4375 4376 if (defect_list != NULL) 4377 free(defect_list); 4378 4379 if (ccb != NULL) 4380 cam_freeccb(ccb); 4381 4382 return (error); 4383} 4384 4385#if 0 4386void 4387reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks) 4388{ 4389 union ccb *ccb; 4390 4391 ccb = cam_getccb(device); 4392 4393 cam_freeccb(ccb); 4394} 4395#endif 4396 4397void 4398mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc, 4399 int page, int subpage, int task_attr, int retry_count, int timeout, 4400 u_int8_t *data, int datalen) 4401{ 4402 union ccb *ccb; 4403 int error_code, sense_key, asc, ascq; 4404 4405 ccb = cam_getccb(device); 4406 if (ccb == NULL) 4407 errx(1, "mode_sense: couldn't allocate CCB"); 4408 4409retry: 4410 /* 4411 * MODE SENSE(6) can't handle more then 255 bytes. If there are more, 4412 * device must return error, so we should not get trucated data. 4413 */ 4414 if (*cdb_len == 6 && datalen > 255) 4415 datalen = 255; 4416 4417 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 4418 4419 scsi_mode_sense_subpage(&ccb->csio, 4420 /* retries */ retry_count, 4421 /* cbfcnp */ NULL, 4422 /* tag_action */ task_attr, 4423 /* dbd */ dbd, 4424 /* pc */ pc << 6, 4425 /* page */ page, 4426 /* subpage */ subpage, 4427 /* param_buf */ data, 4428 /* param_len */ datalen, 4429 /* minimum_cmd_size */ *cdb_len, 4430 /* sense_len */ SSD_FULL_SIZE, 4431 /* timeout */ timeout ? timeout : 5000); 4432 if (llbaa && ccb->csio.cdb_len == 10) { 4433 struct scsi_mode_sense_10 *cdb = 4434 (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes; 4435 cdb->byte2 |= SMS10_LLBAA; 4436 } 4437 4438 /* Record what CDB size the above function really set. */ 4439 *cdb_len = ccb->csio.cdb_len; 4440 4441 if (arglist & CAM_ARG_ERR_RECOVER) 4442 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 4443 4444 /* Disable freezing the device queue */ 4445 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 4446 4447 if (cam_send_ccb(device, ccb) < 0) 4448 err(1, "error sending mode sense command"); 4449 4450 /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */ 4451 if (*cdb_len != 6 && 4452 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID || 4453 (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq) 4454 && sense_key == SSD_KEY_ILLEGAL_REQUEST))) { 4455 *cdb_len = 6; 4456 goto retry; 4457 } 4458 4459 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4460 if (arglist & CAM_ARG_VERBOSE) { 4461 cam_error_print(device, ccb, CAM_ESF_ALL, 4462 CAM_EPF_ALL, stderr); 4463 } 4464 cam_freeccb(ccb); 4465 cam_close_device(device); 4466 errx(1, "mode sense command returned error"); 4467 } 4468 4469 cam_freeccb(ccb); 4470} 4471 4472void 4473mode_select(struct cam_device *device, int cdb_len, int save_pages, 4474 int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen) 4475{ 4476 union ccb *ccb; 4477 int retval; 4478 4479 ccb = cam_getccb(device); 4480 4481 if (ccb == NULL) 4482 errx(1, "mode_select: couldn't allocate CCB"); 4483 4484 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 4485 4486 scsi_mode_select_len(&ccb->csio, 4487 /* retries */ retry_count, 4488 /* cbfcnp */ NULL, 4489 /* tag_action */ task_attr, 4490 /* scsi_page_fmt */ 1, 4491 /* save_pages */ save_pages, 4492 /* param_buf */ data, 4493 /* param_len */ datalen, 4494 /* minimum_cmd_size */ cdb_len, 4495 /* sense_len */ SSD_FULL_SIZE, 4496 /* timeout */ timeout ? timeout : 5000); 4497 4498 if (arglist & CAM_ARG_ERR_RECOVER) 4499 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 4500 4501 /* Disable freezing the device queue */ 4502 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 4503 4504 if (((retval = cam_send_ccb(device, ccb)) < 0) 4505 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 4506 if (arglist & CAM_ARG_VERBOSE) { 4507 cam_error_print(device, ccb, CAM_ESF_ALL, 4508 CAM_EPF_ALL, stderr); 4509 } 4510 cam_freeccb(ccb); 4511 cam_close_device(device); 4512 4513 if (retval < 0) 4514 err(1, "error sending mode select command"); 4515 else 4516 errx(1, "error sending mode select command"); 4517 4518 } 4519 4520 cam_freeccb(ccb); 4521} 4522 4523void 4524modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, 4525 int task_attr, int retry_count, int timeout) 4526{ 4527 char *str_subpage; 4528 int c, page = -1, subpage = 0, pc = 0, llbaa = 0; 4529 int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0; 4530 4531 while ((c = getopt(argc, argv, combinedopt)) != -1) { 4532 switch(c) { 4533 case '6': 4534 cdb_len = 6; 4535 break; 4536 case 'b': 4537 binary = 1; 4538 break; 4539 case 'd': 4540 dbd = 1; 4541 break; 4542 case 'e': 4543 edit = 1; 4544 break; 4545 case 'l': 4546 list++; 4547 break; 4548 case 'm': 4549 str_subpage = optarg; 4550 strsep(&str_subpage, ","); 4551 page = strtol(optarg, NULL, 0); 4552 if (str_subpage) 4553 subpage = strtol(str_subpage, NULL, 0); 4554 if (page < 0 || page > 0x3f) 4555 errx(1, "invalid mode page %d", page); 4556 if (subpage < 0 || subpage > 0xff) 4557 errx(1, "invalid mode subpage %d", subpage); 4558 break; 4559 case 'D': 4560 desc = 1; 4561 break; 4562 case 'L': 4563 llbaa = 1; 4564 break; 4565 case 'P': 4566 pc = strtol(optarg, NULL, 0); 4567 if ((pc < 0) || (pc > 3)) 4568 errx(1, "invalid page control field %d", pc); 4569 break; 4570 default: 4571 break; 4572 } 4573 } 4574 4575 if (desc && page == -1) 4576 page = SMS_ALL_PAGES_PAGE; 4577 4578 if (page == -1 && list == 0) 4579 errx(1, "you must specify a mode page!"); 4580 4581 if (dbd && desc) 4582 errx(1, "-d and -D are incompatible!"); 4583 4584 if (llbaa && cdb_len != 10) 4585 errx(1, "LLBAA bit is not present in MODE SENSE(6)!"); 4586 4587 if (list != 0) { 4588 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr, 4589 retry_count, timeout); 4590 } else { 4591 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage, 4592 edit, binary, task_attr, retry_count, timeout); 4593 } 4594} 4595 4596static int 4597scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, 4598 int task_attr, int retry_count, int timeout) 4599{ 4600 union ccb *ccb; 4601 u_int32_t flags = CAM_DIR_NONE; 4602 u_int8_t *data_ptr = NULL; 4603 u_int8_t cdb[20]; 4604 u_int8_t atacmd[12]; 4605 struct get_hook hook; 4606 int c, data_bytes = 0, valid_bytes; 4607 int cdb_len = 0; 4608 int atacmd_len = 0; 4609 int dmacmd = 0; 4610 int fpdmacmd = 0; 4611 int need_res = 0; 4612 char *datastr = NULL, *tstr, *resstr = NULL; 4613 int error = 0; 4614 int fd_data = 0, fd_res = 0; 4615 int retval; 4616 4617 ccb = cam_getccb(device); 4618 4619 if (ccb == NULL) { 4620 warnx("scsicmd: error allocating ccb"); 4621 return (1); 4622 } 4623 4624 CCB_CLEAR_ALL_EXCEPT_HDR(ccb); 4625 4626 while ((c = getopt(argc, argv, combinedopt)) != -1) { 4627 switch(c) { 4628 case 'a': 4629 tstr = optarg; 4630 while (isspace(*tstr) && (*tstr != '\0')) 4631 tstr++; 4632 hook.argc = argc - optind; 4633 hook.argv = argv + optind; 4634 hook.got = 0; 4635 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr, 4636 iget, &hook); 4637 /* 4638 * Increment optind by the number of arguments the 4639 * encoding routine processed. After each call to 4640 * getopt(3), optind points to the argument that 4641 * getopt should process _next_. In this case, 4642 * that means it points to the first command string 4643 * argument, if there is one. Once we increment 4644 * this, it should point to either the next command 4645 * line argument, or it should be past the end of 4646 * the list. 4647 */ 4648 optind += hook.got; 4649 break; 4650 case 'c': 4651 tstr = optarg; 4652 while (isspace(*tstr) && (*tstr != '\0')) 4653 tstr++; 4654 hook.argc = argc - optind; 4655 hook.argv = argv + optind; 4656 hook.got = 0; 4657 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr, 4658 iget, &hook); 4659 /* 4660 * Increment optind by the number of arguments the 4661 * encoding routine processed. After each call to 4662 * getopt(3), optind points to the argument that 4663 * getopt should process _next_. In this case, 4664 * that means it points to the first command string 4665 * argument, if there is one. Once we increment 4666 * this, it should point to either the next command 4667 * line argument, or it should be past the end of 4668 * the list. 4669 */ 4670 optind += hook.got; 4671 break; 4672 case 'd': 4673 dmacmd = 1; 4674 break; 4675 case 'f': 4676 fpdmacmd = 1; 4677 break; 4678 case 'i': 4679 if (arglist & CAM_ARG_CMD_OUT) { 4680 warnx("command must either be " 4681 "read or write, not both"); 4682 error = 1; 4683 goto scsicmd_bailout; 4684 } 4685 arglist |= CAM_ARG_CMD_IN; 4686 flags = CAM_DIR_IN; 4687 data_bytes = strtol(optarg, NULL, 0); 4688 if (data_bytes <= 0) { 4689 warnx("invalid number of input bytes %d", 4690 data_bytes); 4691 error = 1; 4692 goto scsicmd_bailout; 4693 } 4694 hook.argc = argc - optind; 4695 hook.argv = argv + optind; 4696 hook.got = 0; 4697 optind++; 4698 datastr = cget(&hook, NULL); 4699 /* 4700 * If the user supplied "-" instead of a format, he 4701 * wants the data to be written to stdout. 4702 */ 4703 if ((datastr != NULL) 4704 && (datastr[0] == '-')) 4705 fd_data = 1; 4706 4707 data_ptr = (u_int8_t *)malloc(data_bytes); 4708 if (data_ptr == NULL) { 4709 warnx("can't malloc memory for data_ptr"); 4710 error = 1; 4711 goto scsicmd_bailout; 4712 } 4713 break; 4714 case 'o': 4715 if (arglist & CAM_ARG_CMD_IN) { 4716 warnx("command must either be " 4717 "read or write, not both"); 4718 error = 1; 4719 goto scsicmd_bailout; 4720 } 4721 arglist |= CAM_ARG_CMD_OUT; 4722 flags = CAM_DIR_OUT; 4723 data_bytes = strtol(optarg, NULL, 0); 4724 if (data_bytes <= 0) { 4725 warnx("invalid number of output bytes %d", 4726 data_bytes); 4727 error = 1; 4728 goto scsicmd_bailout; 4729 } 4730 hook.argc = argc - optind; 4731 hook.argv = argv + optind; 4732 hook.got = 0; 4733 datastr = cget(&hook, NULL); 4734 data_ptr = (u_int8_t *)malloc(data_bytes); 4735 if (data_ptr == NULL) { 4736 warnx("can't malloc memory for data_ptr"); 4737 error = 1; 4738 goto scsicmd_bailout; 4739 } 4740 bzero(data_ptr, data_bytes); 4741 /* 4742 * If the user supplied "-" instead of a format, he 4743 * wants the data to be read from stdin. 4744 */ 4745 if ((datastr != NULL) 4746 && (datastr[0] == '-')) 4747 fd_data = 1; 4748 else 4749 buff_encode_visit(data_ptr, data_bytes, datastr, 4750 iget, &hook); 4751 optind += hook.got; 4752 break; 4753 case 'r': 4754 need_res = 1; 4755 hook.argc = argc - optind; 4756 hook.argv = argv + optind; 4757 hook.got = 0; 4758 resstr = cget(&hook, NULL); 4759 if ((resstr != NULL) && (resstr[0] == '-')) 4760 fd_res = 1; 4761 optind += hook.got; 4762 break; 4763 default: 4764 break; 4765 } 4766 } 4767 4768 /* 4769 * If fd_data is set, and we're writing to the device, we need to 4770 * read the data the user wants written from stdin. 4771 */ 4772 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) { 4773 ssize_t amt_read; 4774 int amt_to_read = data_bytes; 4775 u_int8_t *buf_ptr = data_ptr; 4776 4777 for (amt_read = 0; amt_to_read > 0; 4778 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) { 4779 if (amt_read == -1) { 4780 warn("error reading data from stdin"); 4781 error = 1; 4782 goto scsicmd_bailout; 4783 } 4784 amt_to_read -= amt_read; 4785 buf_ptr += amt_read; 4786 } 4787 } 4788 4789 if (arglist & CAM_ARG_ERR_RECOVER) 4790 flags |= CAM_PASS_ERR_RECOVER; 4791 4792 /* Disable freezing the device queue */ 4793 flags |= CAM_DEV_QFRZDIS; 4794 4795 if (cdb_len) { 4796 /* 4797 * This is taken from the SCSI-3 draft spec. 4798 * (T10/1157D revision 0.3) 4799 * The top 3 bits of an opcode are the group code. 4800 * The next 5 bits are the command code. 4801 * Group 0: six byte commands 4802 * Group 1: ten byte commands 4803 * Group 2: ten byte commands 4804 * Group 3: reserved 4805 * Group 4: sixteen byte commands 4806 * Group 5: twelve byte commands 4807 * Group 6: vendor specific 4808 * Group 7: vendor specific 4809 */ 4810 switch((cdb[0] >> 5) & 0x7) { 4811 case 0: 4812 cdb_len = 6; 4813 break; 4814 case 1: 4815 case 2: 4816 cdb_len = 10; 4817 break; 4818 case 3: 4819 case 6: 4820 case 7: 4821 /* computed by buff_encode_visit */ 4822 break; 4823 case 4: 4824 cdb_len = 16; 4825 break; 4826 case 5: 4827 cdb_len = 12; 4828 break; 4829 } 4830 4831 /* 4832 * We should probably use csio_build_visit or something like that 4833 * here, but it's easier to encode arguments as you go. The 4834 * alternative would be skipping the CDB argument and then encoding 4835 * it here, since we've got the data buffer argument by now. 4836 */ 4837 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len); 4838 4839 cam_fill_csio(&ccb->csio, 4840 /*retries*/ retry_count, 4841 /*cbfcnp*/ NULL, 4842 /*flags*/ flags, 4843 /*tag_action*/ task_attr, 4844 /*data_ptr*/ data_ptr, 4845 /*dxfer_len*/ data_bytes, 4846 /*sense_len*/ SSD_FULL_SIZE, 4847 /*cdb_len*/ cdb_len, 4848 /*timeout*/ timeout ? timeout : 5000); 4849 } else { 4850 atacmd_len = 12; 4851 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len); 4852 if (need_res) 4853 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; 4854 if (dmacmd) 4855 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA; 4856 if (fpdmacmd) 4857 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA; 4858 4859 cam_fill_ataio(&ccb->ataio, 4860 /*retries*/ retry_count, 4861 /*cbfcnp*/ NULL, 4862 /*flags*/ flags, 4863 /*tag_action*/ 0, 4864 /*data_ptr*/ data_ptr, 4865 /*dxfer_len*/ data_bytes, 4866 /*timeout*/ timeout ? timeout : 5000); 4867 } 4868 4869 if (((retval = cam_send_ccb(device, ccb)) < 0) 4870 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 4871 const char warnstr[] = "error sending command"; 4872 4873 if (retval < 0) 4874 warn(warnstr); 4875 else 4876 warnx(warnstr); 4877 4878 if (arglist & CAM_ARG_VERBOSE) { 4879 cam_error_print(device, ccb, CAM_ESF_ALL, 4880 CAM_EPF_ALL, stderr); 4881 } 4882 4883 error = 1; 4884 goto scsicmd_bailout; 4885 } 4886 4887 if (atacmd_len && need_res) { 4888 if (fd_res == 0) { 4889 buff_decode_visit(&ccb->ataio.res.status, 11, resstr, 4890 arg_put, NULL); 4891 fprintf(stdout, "\n"); 4892 } else { 4893 fprintf(stdout, 4894 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", 4895 ccb->ataio.res.status, 4896 ccb->ataio.res.error, 4897 ccb->ataio.res.lba_low, 4898 ccb->ataio.res.lba_mid, 4899 ccb->ataio.res.lba_high, 4900 ccb->ataio.res.device, 4901 ccb->ataio.res.lba_low_exp, 4902 ccb->ataio.res.lba_mid_exp, 4903 ccb->ataio.res.lba_high_exp, 4904 ccb->ataio.res.sector_count, 4905 ccb->ataio.res.sector_count_exp); 4906 fflush(stdout); 4907 } 4908 } 4909 4910 if (cdb_len) 4911 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid; 4912 else 4913 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid; 4914 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 4915 && (arglist & CAM_ARG_CMD_IN) 4916 && (valid_bytes > 0)) { 4917 if (fd_data == 0) { 4918 buff_decode_visit(data_ptr, valid_bytes, datastr, 4919 arg_put, NULL); 4920 fprintf(stdout, "\n"); 4921 } else { 4922 ssize_t amt_written; 4923 int amt_to_write = valid_bytes; 4924 u_int8_t *buf_ptr = data_ptr; 4925 4926 for (amt_written = 0; (amt_to_write > 0) && 4927 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){ 4928 amt_to_write -= amt_written; 4929 buf_ptr += amt_written; 4930 } 4931 if (amt_written == -1) { 4932 warn("error writing data to stdout"); 4933 error = 1; 4934 goto scsicmd_bailout; 4935 } else if ((amt_written == 0) 4936 && (amt_to_write > 0)) { 4937 warnx("only wrote %u bytes out of %u", 4938 valid_bytes - amt_to_write, valid_bytes); 4939 } 4940 } 4941 } 4942 4943scsicmd_bailout: 4944 4945 if ((data_bytes > 0) && (data_ptr != NULL)) 4946 free(data_ptr); 4947 4948 cam_freeccb(ccb); 4949 4950 return (error); 4951} 4952 4953static int 4954camdebug(int argc, char **argv, char *combinedopt) 4955{ 4956 int c, fd; 4957 path_id_t bus = CAM_BUS_WILDCARD; 4958 target_id_t target = CAM_TARGET_WILDCARD; 4959 lun_id_t lun = CAM_LUN_WILDCARD; 4960 char *tstr; 4961 union ccb ccb; 4962 int error = 0, rv; 4963 4964 bzero(&ccb, sizeof(union ccb)); 4965 4966 while ((c = getopt(argc, argv, combinedopt)) != -1) { 4967 switch(c) { 4968 case 'I': 4969 arglist |= CAM_ARG_DEBUG_INFO; 4970 ccb.cdbg.flags |= CAM_DEBUG_INFO; 4971 break; 4972 case 'P': 4973 arglist |= CAM_ARG_DEBUG_PERIPH; 4974 ccb.cdbg.flags |= CAM_DEBUG_PERIPH; 4975 break; 4976 case 'S': 4977 arglist |= CAM_ARG_DEBUG_SUBTRACE; 4978 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE; 4979 break; 4980 case 'T': 4981 arglist |= CAM_ARG_DEBUG_TRACE; 4982 ccb.cdbg.flags |= CAM_DEBUG_TRACE; 4983 break; 4984 case 'X': 4985 arglist |= CAM_ARG_DEBUG_XPT; 4986 ccb.cdbg.flags |= CAM_DEBUG_XPT; 4987 break; 4988 case 'c': 4989 arglist |= CAM_ARG_DEBUG_CDB; 4990 ccb.cdbg.flags |= CAM_DEBUG_CDB; 4991 break; 4992 case 'p': 4993 arglist |= CAM_ARG_DEBUG_PROBE; 4994 ccb.cdbg.flags |= CAM_DEBUG_PROBE; 4995 break; 4996 default: 4997 break; 4998 } 4999 } 5000 5001 argc -= optind; 5002 argv += optind; 5003 5004 if (argc <= 0) { 5005 warnx("you must specify \"off\", \"all\" or a bus,"); 5006 warnx("bus:target, bus:target:lun or periph"); 5007 return (1); 5008 } 5009 5010 tstr = *argv; 5011 while (isspace(*tstr) && (*tstr != '\0')) 5012 tstr++; 5013 5014 if (strncmp(tstr, "off", 3) == 0) { 5015 ccb.cdbg.flags = CAM_DEBUG_NONE; 5016 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH| 5017 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE| 5018 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE); 5019 } else { 5020 rv = parse_btl(tstr, &bus, &target, &lun, &arglist); 5021 if (rv < 1) { 5022 warnx("you must specify \"all\", \"off\", or a bus,"); 5023 warnx("bus:target, bus:target:lun or periph to debug"); 5024 return (1); 5025 } 5026 } 5027 5028 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { 5029 warnx("error opening transport layer device %s", XPT_DEVICE); 5030 warn("%s", XPT_DEVICE); 5031 return (1); 5032 } 5033 5034 ccb.ccb_h.func_code = XPT_DEBUG; 5035 ccb.ccb_h.path_id = bus; 5036 ccb.ccb_h.target_id = target; 5037 ccb.ccb_h.target_lun = lun; 5038 5039 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 5040 warn("CAMIOCOMMAND ioctl failed"); 5041 error = 1; 5042 } else { 5043 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == 5044 CAM_FUNC_NOTAVAIL) { 5045 warnx("CAM debugging not available"); 5046 warnx("you need to put options CAMDEBUG in" 5047 " your kernel config file!"); 5048 error = 1; 5049 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) != 5050 CAM_REQ_CMP) { 5051 warnx("XPT_DEBUG CCB failed with status %#x", 5052 ccb.ccb_h.status); 5053 error = 1; 5054 } else { 5055 if (ccb.cdbg.flags == CAM_DEBUG_NONE) { 5056 fprintf(stderr, 5057 "Debugging turned off\n"); 5058 } else { 5059 fprintf(stderr, 5060 "Debugging enabled for " 5061 "%d:%d:%jx\n", 5062 bus, target, (uintmax_t)lun); 5063 } 5064 } 5065 } 5066 close(fd); 5067 5068 return (error); 5069} 5070 5071static int 5072tagcontrol(struct cam_device *device, int argc, char **argv, 5073 char *combinedopt) 5074{ 5075 int c; 5076 union ccb *ccb; 5077 int numtags = -1; 5078 int retval = 0; 5079 int quiet = 0; 5080 char pathstr[1024]; 5081 5082 ccb = cam_getccb(device); 5083 5084 if (ccb == NULL) { 5085 warnx("tagcontrol: error allocating ccb"); 5086 return (1); 5087 } 5088 5089 while ((c = getopt(argc, argv, combinedopt)) != -1) { 5090 switch(c) { 5091 case 'N': 5092 numtags = strtol(optarg, NULL, 0); 5093 if (numtags < 0) { 5094 warnx("tag count %d is < 0", numtags); 5095 retval = 1; 5096 goto tagcontrol_bailout; 5097 } 5098 break; 5099 case 'q': 5100 quiet++; 5101 break; 5102 default: 5103 break; 5104 } 5105 } 5106 5107 cam_path_string(device, pathstr, sizeof(pathstr)); 5108 5109 if (numtags >= 0) { 5110 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs); 5111 ccb->ccb_h.func_code = XPT_REL_SIMQ; 5112 ccb->ccb_h.flags = CAM_DEV_QFREEZE; 5113 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS; 5114 ccb->crs.openings = numtags; 5115 5116 5117 if (cam_send_ccb(device, ccb) < 0) { 5118 warn("error sending XPT_REL_SIMQ CCB"); 5119 retval = 1; 5120 goto tagcontrol_bailout; 5121 } 5122 5123 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5124 warnx("XPT_REL_SIMQ CCB failed"); 5125 cam_error_print(device, ccb, CAM_ESF_ALL, 5126 CAM_EPF_ALL, stderr); 5127 retval = 1; 5128 goto tagcontrol_bailout; 5129 } 5130 5131 5132 if (quiet == 0) 5133 fprintf(stdout, "%stagged openings now %d\n", 5134 pathstr, ccb->crs.openings); 5135 } 5136 5137 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds); 5138 5139 ccb->ccb_h.func_code = XPT_GDEV_STATS; 5140 5141 if (cam_send_ccb(device, ccb) < 0) { 5142 warn("error sending XPT_GDEV_STATS CCB"); 5143 retval = 1; 5144 goto tagcontrol_bailout; 5145 } 5146 5147 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5148 warnx("XPT_GDEV_STATS CCB failed"); 5149 cam_error_print(device, ccb, CAM_ESF_ALL, 5150 CAM_EPF_ALL, stderr); 5151 retval = 1; 5152 goto tagcontrol_bailout; 5153 } 5154 5155 if (arglist & CAM_ARG_VERBOSE) { 5156 fprintf(stdout, "%s", pathstr); 5157 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings); 5158 fprintf(stdout, "%s", pathstr); 5159 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active); 5160 fprintf(stdout, "%s", pathstr); 5161 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated); 5162 fprintf(stdout, "%s", pathstr); 5163 fprintf(stdout, "queued %d\n", ccb->cgds.queued); 5164 fprintf(stdout, "%s", pathstr); 5165 fprintf(stdout, "held %d\n", ccb->cgds.held); 5166 fprintf(stdout, "%s", pathstr); 5167 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags); 5168 fprintf(stdout, "%s", pathstr); 5169 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags); 5170 } else { 5171 if (quiet == 0) { 5172 fprintf(stdout, "%s", pathstr); 5173 fprintf(stdout, "device openings: "); 5174 } 5175 fprintf(stdout, "%d\n", ccb->cgds.dev_openings + 5176 ccb->cgds.dev_active); 5177 } 5178 5179tagcontrol_bailout: 5180 5181 cam_freeccb(ccb); 5182 return (retval); 5183} 5184 5185static void 5186cts_print(struct cam_device *device, struct ccb_trans_settings *cts) 5187{ 5188 char pathstr[1024]; 5189 5190 cam_path_string(device, pathstr, sizeof(pathstr)); 5191 5192 if (cts->transport == XPORT_SPI) { 5193 struct ccb_trans_settings_spi *spi = 5194 &cts->xport_specific.spi; 5195 5196 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { 5197 5198 fprintf(stdout, "%ssync parameter: %d\n", pathstr, 5199 spi->sync_period); 5200 5201 if (spi->sync_offset != 0) { 5202 u_int freq; 5203 5204 freq = scsi_calc_syncsrate(spi->sync_period); 5205 fprintf(stdout, "%sfrequency: %d.%03dMHz\n", 5206 pathstr, freq / 1000, freq % 1000); 5207 } 5208 } 5209 5210 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) { 5211 fprintf(stdout, "%soffset: %d\n", pathstr, 5212 spi->sync_offset); 5213 } 5214 5215 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) { 5216 fprintf(stdout, "%sbus width: %d bits\n", pathstr, 5217 (0x01 << spi->bus_width) * 8); 5218 } 5219 5220 if (spi->valid & CTS_SPI_VALID_DISC) { 5221 fprintf(stdout, "%sdisconnection is %s\n", pathstr, 5222 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ? 5223 "enabled" : "disabled"); 5224 } 5225 } 5226 if (cts->transport == XPORT_FC) { 5227 struct ccb_trans_settings_fc *fc = 5228 &cts->xport_specific.fc; 5229 5230 if (fc->valid & CTS_FC_VALID_WWNN) 5231 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr, 5232 (long long) fc->wwnn); 5233 if (fc->valid & CTS_FC_VALID_WWPN) 5234 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr, 5235 (long long) fc->wwpn); 5236 if (fc->valid & CTS_FC_VALID_PORT) 5237 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port); 5238 if (fc->valid & CTS_FC_VALID_SPEED) 5239 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n", 5240 pathstr, fc->bitrate / 1000, fc->bitrate % 1000); 5241 } 5242 if (cts->transport == XPORT_SAS) { 5243 struct ccb_trans_settings_sas *sas = 5244 &cts->xport_specific.sas; 5245 5246 if (sas->valid & CTS_SAS_VALID_SPEED) 5247 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n", 5248 pathstr, sas->bitrate / 1000, sas->bitrate % 1000); 5249 } 5250 if (cts->transport == XPORT_ATA) { 5251 struct ccb_trans_settings_pata *pata = 5252 &cts->xport_specific.ata; 5253 5254 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) { 5255 fprintf(stdout, "%sATA mode: %s\n", pathstr, 5256 ata_mode2string(pata->mode)); 5257 } 5258 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) { 5259 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, 5260 pata->atapi); 5261 } 5262 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) { 5263 fprintf(stdout, "%sPIO transaction length: %d\n", 5264 pathstr, pata->bytecount); 5265 } 5266 } 5267 if (cts->transport == XPORT_SATA) { 5268 struct ccb_trans_settings_sata *sata = 5269 &cts->xport_specific.sata; 5270 5271 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) { 5272 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr, 5273 sata->revision); 5274 } 5275 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) { 5276 fprintf(stdout, "%sATA mode: %s\n", pathstr, 5277 ata_mode2string(sata->mode)); 5278 } 5279 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) { 5280 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, 5281 sata->atapi); 5282 } 5283 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) { 5284 fprintf(stdout, "%sPIO transaction length: %d\n", 5285 pathstr, sata->bytecount); 5286 } 5287 if ((sata->valid & CTS_SATA_VALID_PM) != 0) { 5288 fprintf(stdout, "%sPMP presence: %d\n", pathstr, 5289 sata->pm_present); 5290 } 5291 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) { 5292 fprintf(stdout, "%sNumber of tags: %d\n", pathstr, 5293 sata->tags); 5294 } 5295 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) { 5296 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr, 5297 sata->caps); 5298 } 5299 } 5300 if (cts->protocol == PROTO_ATA) { 5301 struct ccb_trans_settings_ata *ata= 5302 &cts->proto_specific.ata; 5303 5304 if (ata->valid & CTS_ATA_VALID_TQ) { 5305 fprintf(stdout, "%stagged queueing: %s\n", pathstr, 5306 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ? 5307 "enabled" : "disabled"); 5308 } 5309 } 5310 if (cts->protocol == PROTO_SCSI) { 5311 struct ccb_trans_settings_scsi *scsi= 5312 &cts->proto_specific.scsi; 5313 5314 if (scsi->valid & CTS_SCSI_VALID_TQ) { 5315 fprintf(stdout, "%stagged queueing: %s\n", pathstr, 5316 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ? 5317 "enabled" : "disabled"); 5318 } 5319 } 5320#ifdef WITH_NVME 5321 if (cts->protocol == PROTO_NVME) { 5322 struct ccb_trans_settings_nvme *nvmex = 5323 &cts->xport_specific.nvme; 5324 5325 if (nvmex->valid & CTS_NVME_VALID_SPEC) { 5326 fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr, 5327 NVME_MAJOR(nvmex->spec), 5328 NVME_MINOR(nvmex->spec)); 5329 } 5330 if (nvmex->valid & CTS_NVME_VALID_LINK) { 5331 fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr, 5332 nvmex->lanes, nvmex->max_lanes); 5333 fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr, 5334 nvmex->speed, nvmex->max_speed); 5335 } 5336 } 5337#endif 5338} 5339 5340/* 5341 * Get a path inquiry CCB for the specified device. 5342 */ 5343static int 5344get_cpi(struct cam_device *device, struct ccb_pathinq *cpi) 5345{ 5346 union ccb *ccb; 5347 int retval = 0; 5348 5349 ccb = cam_getccb(device); 5350 if (ccb == NULL) { 5351 warnx("get_cpi: couldn't allocate CCB"); 5352 return (1); 5353 } 5354 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi); 5355 ccb->ccb_h.func_code = XPT_PATH_INQ; 5356 if (cam_send_ccb(device, ccb) < 0) { 5357 warn("get_cpi: error sending Path Inquiry CCB"); 5358 retval = 1; 5359 goto get_cpi_bailout; 5360 } 5361 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5362 if (arglist & CAM_ARG_VERBOSE) 5363 cam_error_print(device, ccb, CAM_ESF_ALL, 5364 CAM_EPF_ALL, stderr); 5365 retval = 1; 5366 goto get_cpi_bailout; 5367 } 5368 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq)); 5369 5370get_cpi_bailout: 5371 cam_freeccb(ccb); 5372 return (retval); 5373} 5374 5375/* 5376 * Get a get device CCB for the specified device. 5377 */ 5378static int 5379get_cgd(struct cam_device *device, struct ccb_getdev *cgd) 5380{ 5381 union ccb *ccb; 5382 int retval = 0; 5383 5384 ccb = cam_getccb(device); 5385 if (ccb == NULL) { 5386 warnx("get_cgd: couldn't allocate CCB"); 5387 return (1); 5388 } 5389 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd); 5390 ccb->ccb_h.func_code = XPT_GDEV_TYPE; 5391 if (cam_send_ccb(device, ccb) < 0) { 5392 warn("get_cgd: error sending Get type information CCB"); 5393 retval = 1; 5394 goto get_cgd_bailout; 5395 } 5396 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5397 if (arglist & CAM_ARG_VERBOSE) 5398 cam_error_print(device, ccb, CAM_ESF_ALL, 5399 CAM_EPF_ALL, stderr); 5400 retval = 1; 5401 goto get_cgd_bailout; 5402 } 5403 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev)); 5404 5405get_cgd_bailout: 5406 cam_freeccb(ccb); 5407 return (retval); 5408} 5409 5410/* 5411 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an 5412 * error. 5413 */ 5414int 5415dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count, 5416 int timeout, int verbosemode) 5417{ 5418 union ccb *ccb = NULL; 5419 struct scsi_vpd_supported_page_list sup_pages; 5420 int i; 5421 int retval = 0; 5422 5423 ccb = cam_getccb(dev); 5424 if (ccb == NULL) { 5425 warn("Unable to allocate CCB"); 5426 retval = -1; 5427 goto bailout; 5428 } 5429 5430 /* cam_getccb cleans up the header, caller has to zero the payload */ 5431 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 5432 5433 bzero(&sup_pages, sizeof(sup_pages)); 5434 5435 scsi_inquiry(&ccb->csio, 5436 /*retries*/ retry_count, 5437 /*cbfcnp*/ NULL, 5438 /* tag_action */ MSG_SIMPLE_Q_TAG, 5439 /* inq_buf */ (u_int8_t *)&sup_pages, 5440 /* inq_len */ sizeof(sup_pages), 5441 /* evpd */ 1, 5442 /* page_code */ SVPD_SUPPORTED_PAGE_LIST, 5443 /* sense_len */ SSD_FULL_SIZE, 5444 /* timeout */ timeout ? timeout : 5000); 5445 5446 /* Disable freezing the device queue */ 5447 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 5448 5449 if (retry_count != 0) 5450 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 5451 5452 if (cam_send_ccb(dev, ccb) < 0) { 5453 cam_freeccb(ccb); 5454 ccb = NULL; 5455 retval = -1; 5456 goto bailout; 5457 } 5458 5459 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5460 if (verbosemode != 0) 5461 cam_error_print(dev, ccb, CAM_ESF_ALL, 5462 CAM_EPF_ALL, stderr); 5463 retval = -1; 5464 goto bailout; 5465 } 5466 5467 for (i = 0; i < sup_pages.length; i++) { 5468 if (sup_pages.list[i] == page_id) { 5469 retval = 1; 5470 goto bailout; 5471 } 5472 } 5473bailout: 5474 if (ccb != NULL) 5475 cam_freeccb(ccb); 5476 5477 return (retval); 5478} 5479 5480/* 5481 * devtype is filled in with the type of device. 5482 * Returns 0 for success, non-zero for failure. 5483 */ 5484int 5485get_device_type(struct cam_device *dev, int retry_count, int timeout, 5486 int verbosemode, camcontrol_devtype *devtype) 5487{ 5488 struct ccb_getdev cgd; 5489 int retval; 5490 5491 retval = get_cgd(dev, &cgd); 5492 if (retval != 0) 5493 goto bailout; 5494 5495 switch (cgd.protocol) { 5496 case PROTO_SCSI: 5497 break; 5498 case PROTO_ATA: 5499 case PROTO_ATAPI: 5500 case PROTO_SATAPM: 5501 *devtype = CC_DT_ATA; 5502 goto bailout; 5503 break; /*NOTREACHED*/ 5504 case PROTO_NVME: 5505 *devtype = CC_DT_NVME; 5506 goto bailout; 5507 break; /*NOTREACHED*/ 5508 case PROTO_MMCSD: 5509 *devtype = CC_DT_MMCSD; 5510 goto bailout; 5511 break; /*NOTREACHED*/ 5512 default: 5513 *devtype = CC_DT_UNKNOWN; 5514 goto bailout; 5515 break; /*NOTREACHED*/ 5516 } 5517 5518 if (retry_count == -1) { 5519 /* 5520 * For a retry count of -1, used only the cached data to avoid 5521 * I/O to the drive. Sending the identify command to the drive 5522 * can cause issues for SATL attachaed drives since identify is 5523 * not an NCQ command. We check for the strings that windows 5524 * displays since those will not be NULs (they are supposed 5525 * to be space padded). We could check other bits, but anything 5526 * non-zero implies SATL. 5527 */ 5528 if (cgd.ident_data.serial[0] != 0 || 5529 cgd.ident_data.revision[0] != 0 || 5530 cgd.ident_data.model[0] != 0) 5531 *devtype = CC_DT_SATL; 5532 else 5533 *devtype = CC_DT_SCSI; 5534 } else { 5535 /* 5536 * Check for the ATA Information VPD page (0x89). If this is an 5537 * ATA device behind a SCSI to ATA translation layer (SATL), 5538 * this VPD page should be present. 5539 * 5540 * If that VPD page isn't present, or we get an error back from 5541 * the INQUIRY command, we'll just treat it as a normal SCSI 5542 * device. 5543 */ 5544 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count, 5545 timeout, verbosemode); 5546 if (retval == 1) 5547 *devtype = CC_DT_SATL; 5548 else 5549 *devtype = CC_DT_SCSI; 5550 } 5551 retval = 0; 5552 5553bailout: 5554 return (retval); 5555} 5556 5557int 5558build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags, 5559 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features, 5560 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary, 5561 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage, 5562 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout, 5563 int is48bit, camcontrol_devtype devtype) 5564{ 5565 int retval = 0; 5566 5567 if (devtype == CC_DT_ATA) { 5568 cam_fill_ataio(&ccb->ataio, 5569 /*retries*/ retry_count, 5570 /*cbfcnp*/ NULL, 5571 /*flags*/ flags, 5572 /*tag_action*/ tag_action, 5573 /*data_ptr*/ data_ptr, 5574 /*dxfer_len*/ dxfer_len, 5575 /*timeout*/ timeout); 5576 if (is48bit || lba > ATA_MAX_28BIT_LBA) 5577 ata_48bit_cmd(&ccb->ataio, command, features, lba, 5578 sector_count); 5579 else 5580 ata_28bit_cmd(&ccb->ataio, command, features, lba, 5581 sector_count); 5582 5583 if (auxiliary != 0) { 5584 ccb->ataio.ata_flags |= ATA_FLAG_AUX; 5585 ccb->ataio.aux = auxiliary; 5586 } 5587 5588 if (ata_flags & AP_FLAG_CHK_COND) 5589 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; 5590 5591 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA) 5592 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA; 5593 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA) 5594 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA; 5595 } else { 5596 if (is48bit || lba > ATA_MAX_28BIT_LBA) 5597 protocol |= AP_EXTEND; 5598 5599 retval = scsi_ata_pass(&ccb->csio, 5600 /*retries*/ retry_count, 5601 /*cbfcnp*/ NULL, 5602 /*flags*/ flags, 5603 /*tag_action*/ tag_action, 5604 /*protocol*/ protocol, 5605 /*ata_flags*/ ata_flags, 5606 /*features*/ features, 5607 /*sector_count*/ sector_count, 5608 /*lba*/ lba, 5609 /*command*/ command, 5610 /*device*/ 0, 5611 /*icc*/ 0, 5612 /*auxiliary*/ auxiliary, 5613 /*control*/ 0, 5614 /*data_ptr*/ data_ptr, 5615 /*dxfer_len*/ dxfer_len, 5616 /*cdb_storage*/ cdb_storage, 5617 /*cdb_storage_len*/ cdb_storage_len, 5618 /*minimum_cmd_size*/ 0, 5619 /*sense_len*/ sense_len, 5620 /*timeout*/ timeout); 5621 } 5622 5623 return (retval); 5624} 5625 5626/* 5627 * Returns: 0 -- success, 1 -- error, 2 -- lba truncated, 5628 * 4 -- count truncated, 6 -- lba and count truncated. 5629 */ 5630int 5631get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error, 5632 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status) 5633{ 5634 int retval; 5635 5636 switch (ccb->ccb_h.func_code) { 5637 case XPT_SCSI_IO: { 5638 uint8_t opcode; 5639 int error_code = 0, sense_key = 0, asc = 0, ascq = 0; 5640 u_int sense_len; 5641 5642 /* 5643 * In this case, we have SCSI ATA PASS-THROUGH command, 12 5644 * or 16 byte, and need to see what 5645 */ 5646 if (ccb->ccb_h.flags & CAM_CDB_POINTER) 5647 opcode = ccb->csio.cdb_io.cdb_ptr[0]; 5648 else 5649 opcode = ccb->csio.cdb_io.cdb_bytes[0]; 5650 if ((opcode != ATA_PASS_12) 5651 && (opcode != ATA_PASS_16)) { 5652 warnx("%s: unsupported opcode %02x", __func__, opcode); 5653 return (1); 5654 } 5655 5656 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key, 5657 &asc, &ascq); 5658 /* Note: the _ccb() variant returns 0 for an error */ 5659 if (retval == 0) 5660 return (1); 5661 5662 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid; 5663 switch (error_code) { 5664 case SSD_DESC_CURRENT_ERROR: 5665 case SSD_DESC_DEFERRED_ERROR: { 5666 struct scsi_sense_data_desc *sense; 5667 struct scsi_sense_ata_ret_desc *desc; 5668 uint8_t *desc_ptr; 5669 5670 sense = (struct scsi_sense_data_desc *) 5671 &ccb->csio.sense_data; 5672 5673 desc_ptr = scsi_find_desc(sense, sense_len, 5674 SSD_DESC_ATA); 5675 if (desc_ptr == NULL) { 5676 cam_error_print(dev, ccb, CAM_ESF_ALL, 5677 CAM_EPF_ALL, stderr); 5678 return (1); 5679 } 5680 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr; 5681 5682 *error = desc->error; 5683 *count = (desc->count_15_8 << 8) | 5684 desc->count_7_0; 5685 *lba = ((uint64_t)desc->lba_47_40 << 40) | 5686 ((uint64_t)desc->lba_39_32 << 32) | 5687 ((uint64_t)desc->lba_31_24 << 24) | 5688 (desc->lba_23_16 << 16) | 5689 (desc->lba_15_8 << 8) | 5690 desc->lba_7_0; 5691 *device = desc->device; 5692 *status = desc->status; 5693 5694 /* 5695 * If the extend bit isn't set, the result is for a 5696 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte 5697 * command without the extend bit set. This means 5698 * that the device is supposed to return 28-bit 5699 * status. The count field is only 8 bits, and the 5700 * LBA field is only 8 bits. 5701 */ 5702 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){ 5703 *count &= 0xff; 5704 *lba &= 0x0fffffff; 5705 } 5706 break; 5707 } 5708 case SSD_CURRENT_ERROR: 5709 case SSD_DEFERRED_ERROR: { 5710 uint64_t val; 5711 5712 /* 5713 * In my understanding of SAT-5 specification, saying: 5714 * "without interpreting the contents of the STATUS", 5715 * this should not happen if CK_COND was set, but it 5716 * does at least for some devices, so try to revert. 5717 */ 5718 if ((sense_key == SSD_KEY_ABORTED_COMMAND) && 5719 (asc == 0) && (ascq == 0)) { 5720 *status = ATA_STATUS_ERROR; 5721 *error = ATA_ERROR_ABORT; 5722 *device = 0; 5723 *count = 0; 5724 *lba = 0; 5725 return (0); 5726 } 5727 5728 if ((sense_key != SSD_KEY_RECOVERED_ERROR) || 5729 (asc != 0x00) || (ascq != 0x1d)) 5730 return (1); 5731 5732 val = 0; 5733 scsi_get_sense_info(&ccb->csio.sense_data, sense_len, 5734 SSD_DESC_INFO, &val, NULL); 5735 *error = (val >> 24) & 0xff; 5736 *status = (val >> 16) & 0xff; 5737 *device = (val >> 8) & 0xff; 5738 *count = val & 0xff; 5739 5740 val = 0; 5741 scsi_get_sense_info(&ccb->csio.sense_data, sense_len, 5742 SSD_DESC_COMMAND, &val, NULL); 5743 *lba = ((val >> 16) & 0xff) | (val & 0xff00) | 5744 ((val & 0xff) << 16); 5745 5746 /* Report UPPER NONZERO bits as errors 2, 4 and 6. */ 5747 return ((val >> 28) & 0x06); 5748 } 5749 default: 5750 return (1); 5751 } 5752 5753 break; 5754 } 5755 case XPT_ATA_IO: { 5756 struct ata_res *res; 5757 5758 /* Only some statuses return ATA result register set. */ 5759 if (cam_ccb_status(ccb) != CAM_REQ_CMP && 5760 cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR) 5761 return (1); 5762 5763 res = &ccb->ataio.res; 5764 *error = res->error; 5765 *status = res->status; 5766 *device = res->device; 5767 *count = res->sector_count; 5768 *lba = (res->lba_high << 16) | 5769 (res->lba_mid << 8) | 5770 (res->lba_low); 5771 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) { 5772 *count |= (res->sector_count_exp << 8); 5773 *lba |= ((uint64_t)res->lba_low_exp << 24) | 5774 ((uint64_t)res->lba_mid_exp << 32) | 5775 ((uint64_t)res->lba_high_exp << 40); 5776 } else { 5777 *lba |= (res->device & 0xf) << 24; 5778 } 5779 break; 5780 } 5781 default: 5782 return (1); 5783 } 5784 return (0); 5785} 5786 5787static void 5788cpi_print(struct ccb_pathinq *cpi) 5789{ 5790 char adapter_str[1024]; 5791 uint64_t i; 5792 5793 snprintf(adapter_str, sizeof(adapter_str), 5794 "%s%d:", cpi->dev_name, cpi->unit_number); 5795 5796 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str, 5797 cpi->version_num); 5798 5799 for (i = 1; i < UINT8_MAX; i = i << 1) { 5800 const char *str; 5801 5802 if ((i & cpi->hba_inquiry) == 0) 5803 continue; 5804 5805 fprintf(stdout, "%s supports ", adapter_str); 5806 5807 switch(i) { 5808 case PI_MDP_ABLE: 5809 str = "MDP message"; 5810 break; 5811 case PI_WIDE_32: 5812 str = "32 bit wide SCSI"; 5813 break; 5814 case PI_WIDE_16: 5815 str = "16 bit wide SCSI"; 5816 break; 5817 case PI_SDTR_ABLE: 5818 str = "SDTR message"; 5819 break; 5820 case PI_LINKED_CDB: 5821 str = "linked CDBs"; 5822 break; 5823 case PI_TAG_ABLE: 5824 str = "tag queue messages"; 5825 break; 5826 case PI_SOFT_RST: 5827 str = "soft reset alternative"; 5828 break; 5829 case PI_SATAPM: 5830 str = "SATA Port Multiplier"; 5831 break; 5832 default: 5833 str = "unknown PI bit set"; 5834 break; 5835 } 5836 fprintf(stdout, "%s\n", str); 5837 } 5838 5839 for (i = 1; i < UINT32_MAX; i = i << 1) { 5840 const char *str; 5841 5842 if ((i & cpi->hba_misc) == 0) 5843 continue; 5844 5845 fprintf(stdout, "%s ", adapter_str); 5846 5847 switch(i) { 5848 case PIM_ATA_EXT: 5849 str = "can understand ata_ext requests"; 5850 break; 5851 case PIM_EXTLUNS: 5852 str = "64bit extended LUNs supported"; 5853 break; 5854 case PIM_SCANHILO: 5855 str = "bus scans from high ID to low ID"; 5856 break; 5857 case PIM_NOREMOVE: 5858 str = "removable devices not included in scan"; 5859 break; 5860 case PIM_NOINITIATOR: 5861 str = "initiator role not supported"; 5862 break; 5863 case PIM_NOBUSRESET: 5864 str = "user has disabled initial BUS RESET or" 5865 " controller is in target/mixed mode"; 5866 break; 5867 case PIM_NO_6_BYTE: 5868 str = "do not send 6-byte commands"; 5869 break; 5870 case PIM_SEQSCAN: 5871 str = "scan bus sequentially"; 5872 break; 5873 case PIM_UNMAPPED: 5874 str = "unmapped I/O supported"; 5875 break; 5876 case PIM_NOSCAN: 5877 str = "does its own scanning"; 5878 break; 5879 default: 5880 str = "unknown PIM bit set"; 5881 break; 5882 } 5883 fprintf(stdout, "%s\n", str); 5884 } 5885 5886 for (i = 1; i < UINT16_MAX; i = i << 1) { 5887 const char *str; 5888 5889 if ((i & cpi->target_sprt) == 0) 5890 continue; 5891 5892 fprintf(stdout, "%s supports ", adapter_str); 5893 switch(i) { 5894 case PIT_PROCESSOR: 5895 str = "target mode processor mode"; 5896 break; 5897 case PIT_PHASE: 5898 str = "target mode phase cog. mode"; 5899 break; 5900 case PIT_DISCONNECT: 5901 str = "disconnects in target mode"; 5902 break; 5903 case PIT_TERM_IO: 5904 str = "terminate I/O message in target mode"; 5905 break; 5906 case PIT_GRP_6: 5907 str = "group 6 commands in target mode"; 5908 break; 5909 case PIT_GRP_7: 5910 str = "group 7 commands in target mode"; 5911 break; 5912 default: 5913 str = "unknown PIT bit set"; 5914 break; 5915 } 5916 5917 fprintf(stdout, "%s\n", str); 5918 } 5919 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str, 5920 cpi->hba_eng_cnt); 5921 fprintf(stdout, "%s maximum target: %d\n", adapter_str, 5922 cpi->max_target); 5923 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str, 5924 cpi->max_lun); 5925 fprintf(stdout, "%s highest path ID in subsystem: %d\n", 5926 adapter_str, cpi->hpath_id); 5927 fprintf(stdout, "%s initiator ID: %d\n", adapter_str, 5928 cpi->initiator_id); 5929 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid); 5930 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid); 5931 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n", 5932 adapter_str, cpi->hba_vendor); 5933 fprintf(stdout, "%s HBA device ID: 0x%04x\n", 5934 adapter_str, cpi->hba_device); 5935 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n", 5936 adapter_str, cpi->hba_subvendor); 5937 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n", 5938 adapter_str, cpi->hba_subdevice); 5939 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id); 5940 fprintf(stdout, "%s base transfer speed: ", adapter_str); 5941 if (cpi->base_transfer_speed > 1000) 5942 fprintf(stdout, "%d.%03dMB/sec\n", 5943 cpi->base_transfer_speed / 1000, 5944 cpi->base_transfer_speed % 1000); 5945 else 5946 fprintf(stdout, "%dKB/sec\n", 5947 (cpi->base_transfer_speed % 1000) * 1000); 5948 fprintf(stdout, "%s maximum transfer size: %u bytes\n", 5949 adapter_str, cpi->maxio); 5950} 5951 5952static int 5953get_print_cts(struct cam_device *device, int user_settings, int quiet, 5954 struct ccb_trans_settings *cts) 5955{ 5956 int retval; 5957 union ccb *ccb; 5958 5959 retval = 0; 5960 ccb = cam_getccb(device); 5961 5962 if (ccb == NULL) { 5963 warnx("get_print_cts: error allocating ccb"); 5964 return (1); 5965 } 5966 5967 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); 5968 5969 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 5970 5971 if (user_settings == 0) 5972 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS; 5973 else 5974 ccb->cts.type = CTS_TYPE_USER_SETTINGS; 5975 5976 if (cam_send_ccb(device, ccb) < 0) { 5977 warn("error sending XPT_GET_TRAN_SETTINGS CCB"); 5978 retval = 1; 5979 goto get_print_cts_bailout; 5980 } 5981 5982 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5983 warnx("XPT_GET_TRANS_SETTINGS CCB failed"); 5984 if (arglist & CAM_ARG_VERBOSE) 5985 cam_error_print(device, ccb, CAM_ESF_ALL, 5986 CAM_EPF_ALL, stderr); 5987 retval = 1; 5988 goto get_print_cts_bailout; 5989 } 5990 5991 if (quiet == 0) 5992 cts_print(device, &ccb->cts); 5993 5994 if (cts != NULL) 5995 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings)); 5996 5997get_print_cts_bailout: 5998 5999 cam_freeccb(ccb); 6000 6001 return (retval); 6002} 6003 6004static int 6005ratecontrol(struct cam_device *device, int task_attr, int retry_count, 6006 int timeout, int argc, char **argv, char *combinedopt) 6007{ 6008 int c; 6009 union ccb *ccb; 6010 int user_settings = 0; 6011 int retval = 0; 6012 int disc_enable = -1, tag_enable = -1; 6013 int mode = -1; 6014 int offset = -1; 6015 double syncrate = -1; 6016 int bus_width = -1; 6017 int quiet = 0; 6018 int change_settings = 0, send_tur = 0; 6019 struct ccb_pathinq cpi; 6020 6021 ccb = cam_getccb(device); 6022 if (ccb == NULL) { 6023 warnx("ratecontrol: error allocating ccb"); 6024 return (1); 6025 } 6026 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6027 switch(c){ 6028 case 'a': 6029 send_tur = 1; 6030 break; 6031 case 'c': 6032 user_settings = 0; 6033 break; 6034 case 'D': 6035 if (strncasecmp(optarg, "enable", 6) == 0) 6036 disc_enable = 1; 6037 else if (strncasecmp(optarg, "disable", 7) == 0) 6038 disc_enable = 0; 6039 else { 6040 warnx("-D argument \"%s\" is unknown", optarg); 6041 retval = 1; 6042 goto ratecontrol_bailout; 6043 } 6044 change_settings = 1; 6045 break; 6046 case 'M': 6047 mode = ata_string2mode(optarg); 6048 if (mode < 0) { 6049 warnx("unknown mode '%s'", optarg); 6050 retval = 1; 6051 goto ratecontrol_bailout; 6052 } 6053 change_settings = 1; 6054 break; 6055 case 'O': 6056 offset = strtol(optarg, NULL, 0); 6057 if (offset < 0) { 6058 warnx("offset value %d is < 0", offset); 6059 retval = 1; 6060 goto ratecontrol_bailout; 6061 } 6062 change_settings = 1; 6063 break; 6064 case 'q': 6065 quiet++; 6066 break; 6067 case 'R': 6068 syncrate = atof(optarg); 6069 if (syncrate < 0) { 6070 warnx("sync rate %f is < 0", syncrate); 6071 retval = 1; 6072 goto ratecontrol_bailout; 6073 } 6074 change_settings = 1; 6075 break; 6076 case 'T': 6077 if (strncasecmp(optarg, "enable", 6) == 0) 6078 tag_enable = 1; 6079 else if (strncasecmp(optarg, "disable", 7) == 0) 6080 tag_enable = 0; 6081 else { 6082 warnx("-T argument \"%s\" is unknown", optarg); 6083 retval = 1; 6084 goto ratecontrol_bailout; 6085 } 6086 change_settings = 1; 6087 break; 6088 case 'U': 6089 user_settings = 1; 6090 break; 6091 case 'W': 6092 bus_width = strtol(optarg, NULL, 0); 6093 if (bus_width < 0) { 6094 warnx("bus width %d is < 0", bus_width); 6095 retval = 1; 6096 goto ratecontrol_bailout; 6097 } 6098 change_settings = 1; 6099 break; 6100 default: 6101 break; 6102 } 6103 } 6104 /* 6105 * Grab path inquiry information, so we can determine whether 6106 * or not the initiator is capable of the things that the user 6107 * requests. 6108 */ 6109 if ((retval = get_cpi(device, &cpi)) != 0) 6110 goto ratecontrol_bailout; 6111 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); 6112 if (quiet == 0) { 6113 fprintf(stdout, "%s parameters:\n", 6114 user_settings ? "User" : "Current"); 6115 } 6116 retval = get_print_cts(device, user_settings, quiet, &ccb->cts); 6117 if (retval != 0) 6118 goto ratecontrol_bailout; 6119 6120 if (arglist & CAM_ARG_VERBOSE) 6121 cpi_print(&cpi); 6122 6123 if (change_settings) { 6124 int didsettings = 0; 6125 struct ccb_trans_settings_spi *spi = NULL; 6126 struct ccb_trans_settings_pata *pata = NULL; 6127 struct ccb_trans_settings_sata *sata = NULL; 6128 struct ccb_trans_settings_ata *ata = NULL; 6129 struct ccb_trans_settings_scsi *scsi = NULL; 6130 6131 if (ccb->cts.transport == XPORT_SPI) 6132 spi = &ccb->cts.xport_specific.spi; 6133 if (ccb->cts.transport == XPORT_ATA) 6134 pata = &ccb->cts.xport_specific.ata; 6135 if (ccb->cts.transport == XPORT_SATA) 6136 sata = &ccb->cts.xport_specific.sata; 6137 if (ccb->cts.protocol == PROTO_ATA) 6138 ata = &ccb->cts.proto_specific.ata; 6139 if (ccb->cts.protocol == PROTO_SCSI) 6140 scsi = &ccb->cts.proto_specific.scsi; 6141 ccb->cts.xport_specific.valid = 0; 6142 ccb->cts.proto_specific.valid = 0; 6143 if (spi && disc_enable != -1) { 6144 spi->valid |= CTS_SPI_VALID_DISC; 6145 if (disc_enable == 0) 6146 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 6147 else 6148 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 6149 didsettings++; 6150 } 6151 if (tag_enable != -1) { 6152 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) { 6153 warnx("HBA does not support tagged queueing, " 6154 "so you cannot modify tag settings"); 6155 retval = 1; 6156 goto ratecontrol_bailout; 6157 } 6158 if (ata) { 6159 ata->valid |= CTS_SCSI_VALID_TQ; 6160 if (tag_enable == 0) 6161 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB; 6162 else 6163 ata->flags |= CTS_ATA_FLAGS_TAG_ENB; 6164 didsettings++; 6165 } else if (scsi) { 6166 scsi->valid |= CTS_SCSI_VALID_TQ; 6167 if (tag_enable == 0) 6168 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 6169 else 6170 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 6171 didsettings++; 6172 } 6173 } 6174 if (spi && offset != -1) { 6175 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 6176 warnx("HBA is not capable of changing offset"); 6177 retval = 1; 6178 goto ratecontrol_bailout; 6179 } 6180 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 6181 spi->sync_offset = offset; 6182 didsettings++; 6183 } 6184 if (spi && syncrate != -1) { 6185 int prelim_sync_period; 6186 6187 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 6188 warnx("HBA is not capable of changing " 6189 "transfer rates"); 6190 retval = 1; 6191 goto ratecontrol_bailout; 6192 } 6193 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 6194 /* 6195 * The sync rate the user gives us is in MHz. 6196 * We need to translate it into KHz for this 6197 * calculation. 6198 */ 6199 syncrate *= 1000; 6200 /* 6201 * Next, we calculate a "preliminary" sync period 6202 * in tenths of a nanosecond. 6203 */ 6204 if (syncrate == 0) 6205 prelim_sync_period = 0; 6206 else 6207 prelim_sync_period = 10000000 / syncrate; 6208 spi->sync_period = 6209 scsi_calc_syncparam(prelim_sync_period); 6210 didsettings++; 6211 } 6212 if (sata && syncrate != -1) { 6213 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 6214 warnx("HBA is not capable of changing " 6215 "transfer rates"); 6216 retval = 1; 6217 goto ratecontrol_bailout; 6218 } 6219 if (!user_settings) { 6220 warnx("You can modify only user rate " 6221 "settings for SATA"); 6222 retval = 1; 6223 goto ratecontrol_bailout; 6224 } 6225 sata->revision = ata_speed2revision(syncrate * 100); 6226 if (sata->revision < 0) { 6227 warnx("Invalid rate %f", syncrate); 6228 retval = 1; 6229 goto ratecontrol_bailout; 6230 } 6231 sata->valid |= CTS_SATA_VALID_REVISION; 6232 didsettings++; 6233 } 6234 if ((pata || sata) && mode != -1) { 6235 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 6236 warnx("HBA is not capable of changing " 6237 "transfer rates"); 6238 retval = 1; 6239 goto ratecontrol_bailout; 6240 } 6241 if (!user_settings) { 6242 warnx("You can modify only user mode " 6243 "settings for ATA/SATA"); 6244 retval = 1; 6245 goto ratecontrol_bailout; 6246 } 6247 if (pata) { 6248 pata->mode = mode; 6249 pata->valid |= CTS_ATA_VALID_MODE; 6250 } else { 6251 sata->mode = mode; 6252 sata->valid |= CTS_SATA_VALID_MODE; 6253 } 6254 didsettings++; 6255 } 6256 /* 6257 * The bus_width argument goes like this: 6258 * 0 == 8 bit 6259 * 1 == 16 bit 6260 * 2 == 32 bit 6261 * Therefore, if you shift the number of bits given on the 6262 * command line right by 4, you should get the correct 6263 * number. 6264 */ 6265 if (spi && bus_width != -1) { 6266 /* 6267 * We might as well validate things here with a 6268 * decipherable error message, rather than what 6269 * will probably be an indecipherable error message 6270 * by the time it gets back to us. 6271 */ 6272 if ((bus_width == 16) 6273 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) { 6274 warnx("HBA does not support 16 bit bus width"); 6275 retval = 1; 6276 goto ratecontrol_bailout; 6277 } else if ((bus_width == 32) 6278 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) { 6279 warnx("HBA does not support 32 bit bus width"); 6280 retval = 1; 6281 goto ratecontrol_bailout; 6282 } else if ((bus_width != 8) 6283 && (bus_width != 16) 6284 && (bus_width != 32)) { 6285 warnx("Invalid bus width %d", bus_width); 6286 retval = 1; 6287 goto ratecontrol_bailout; 6288 } 6289 spi->valid |= CTS_SPI_VALID_BUS_WIDTH; 6290 spi->bus_width = bus_width >> 4; 6291 didsettings++; 6292 } 6293 if (didsettings == 0) { 6294 goto ratecontrol_bailout; 6295 } 6296 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 6297 if (cam_send_ccb(device, ccb) < 0) { 6298 warn("error sending XPT_SET_TRAN_SETTINGS CCB"); 6299 retval = 1; 6300 goto ratecontrol_bailout; 6301 } 6302 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6303 warnx("XPT_SET_TRANS_SETTINGS CCB failed"); 6304 if (arglist & CAM_ARG_VERBOSE) { 6305 cam_error_print(device, ccb, CAM_ESF_ALL, 6306 CAM_EPF_ALL, stderr); 6307 } 6308 retval = 1; 6309 goto ratecontrol_bailout; 6310 } 6311 } 6312 if (send_tur) { 6313 retval = testunitready(device, task_attr, retry_count, timeout, 6314 (arglist & CAM_ARG_VERBOSE) ? 0 : 1); 6315 /* 6316 * If the TUR didn't succeed, just bail. 6317 */ 6318 if (retval != 0) { 6319 if (quiet == 0) 6320 fprintf(stderr, "Test Unit Ready failed\n"); 6321 goto ratecontrol_bailout; 6322 } 6323 } 6324 if ((change_settings || send_tur) && !quiet && 6325 (ccb->cts.transport == XPORT_ATA || 6326 ccb->cts.transport == XPORT_SATA || send_tur)) { 6327 fprintf(stdout, "New parameters:\n"); 6328 retval = get_print_cts(device, user_settings, 0, NULL); 6329 } 6330 6331ratecontrol_bailout: 6332 cam_freeccb(ccb); 6333 return (retval); 6334} 6335 6336static int 6337scsiformat(struct cam_device *device, int argc, char **argv, 6338 char *combinedopt, int task_attr, int retry_count, int timeout) 6339{ 6340 union ccb *ccb; 6341 int c; 6342 int ycount = 0, quiet = 0; 6343 int error = 0, retval = 0; 6344 int use_timeout = 10800 * 1000; 6345 int immediate = 1; 6346 struct format_defect_list_header fh; 6347 u_int8_t *data_ptr = NULL; 6348 u_int32_t dxfer_len = 0; 6349 u_int8_t byte2 = 0; 6350 int num_warnings = 0; 6351 int reportonly = 0; 6352 6353 ccb = cam_getccb(device); 6354 6355 if (ccb == NULL) { 6356 warnx("scsiformat: error allocating ccb"); 6357 return (1); 6358 } 6359 6360 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6361 6362 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6363 switch(c) { 6364 case 'q': 6365 quiet++; 6366 break; 6367 case 'r': 6368 reportonly = 1; 6369 break; 6370 case 'w': 6371 immediate = 0; 6372 break; 6373 case 'y': 6374 ycount++; 6375 break; 6376 } 6377 } 6378 6379 if (reportonly) 6380 goto doreport; 6381 6382 if (quiet == 0 && ycount == 0) { 6383 fprintf(stdout, "You are about to REMOVE ALL DATA from the " 6384 "following device:\n"); 6385 6386 error = scsidoinquiry(device, argc, argv, combinedopt, 6387 task_attr, retry_count, timeout); 6388 6389 if (error != 0) { 6390 warnx("scsiformat: error sending inquiry"); 6391 goto scsiformat_bailout; 6392 } 6393 } 6394 6395 if (ycount == 0) { 6396 if (!get_confirmation()) { 6397 error = 1; 6398 goto scsiformat_bailout; 6399 } 6400 } 6401 6402 if (timeout != 0) 6403 use_timeout = timeout; 6404 6405 if (quiet == 0) { 6406 fprintf(stdout, "Current format timeout is %d seconds\n", 6407 use_timeout / 1000); 6408 } 6409 6410 /* 6411 * If the user hasn't disabled questions and didn't specify a 6412 * timeout on the command line, ask them if they want the current 6413 * timeout. 6414 */ 6415 if ((ycount == 0) 6416 && (timeout == 0)) { 6417 char str[1024]; 6418 int new_timeout = 0; 6419 6420 fprintf(stdout, "Enter new timeout in seconds or press\n" 6421 "return to keep the current timeout [%d] ", 6422 use_timeout / 1000); 6423 6424 if (fgets(str, sizeof(str), stdin) != NULL) { 6425 if (str[0] != '\0') 6426 new_timeout = atoi(str); 6427 } 6428 6429 if (new_timeout != 0) { 6430 use_timeout = new_timeout * 1000; 6431 fprintf(stdout, "Using new timeout value %d\n", 6432 use_timeout / 1000); 6433 } 6434 } 6435 6436 /* 6437 * Keep this outside the if block below to silence any unused 6438 * variable warnings. 6439 */ 6440 bzero(&fh, sizeof(fh)); 6441 6442 /* 6443 * If we're in immediate mode, we've got to include the format 6444 * header 6445 */ 6446 if (immediate != 0) { 6447 fh.byte2 = FU_DLH_IMMED; 6448 data_ptr = (u_int8_t *)&fh; 6449 dxfer_len = sizeof(fh); 6450 byte2 = FU_FMT_DATA; 6451 } else if (quiet == 0) { 6452 fprintf(stdout, "Formatting..."); 6453 fflush(stdout); 6454 } 6455 6456 scsi_format_unit(&ccb->csio, 6457 /* retries */ retry_count, 6458 /* cbfcnp */ NULL, 6459 /* tag_action */ task_attr, 6460 /* byte2 */ byte2, 6461 /* ileave */ 0, 6462 /* data_ptr */ data_ptr, 6463 /* dxfer_len */ dxfer_len, 6464 /* sense_len */ SSD_FULL_SIZE, 6465 /* timeout */ use_timeout); 6466 6467 /* Disable freezing the device queue */ 6468 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6469 6470 if (arglist & CAM_ARG_ERR_RECOVER) 6471 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6472 6473 if (((retval = cam_send_ccb(device, ccb)) < 0) 6474 || ((immediate == 0) 6475 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) { 6476 const char errstr[] = "error sending format command"; 6477 6478 if (retval < 0) 6479 warn(errstr); 6480 else 6481 warnx(errstr); 6482 6483 if (arglist & CAM_ARG_VERBOSE) { 6484 cam_error_print(device, ccb, CAM_ESF_ALL, 6485 CAM_EPF_ALL, stderr); 6486 } 6487 error = 1; 6488 goto scsiformat_bailout; 6489 } 6490 6491 /* 6492 * If we ran in non-immediate mode, we already checked for errors 6493 * above and printed out any necessary information. If we're in 6494 * immediate mode, we need to loop through and get status 6495 * information periodically. 6496 */ 6497 if (immediate == 0) { 6498 if (quiet == 0) { 6499 fprintf(stdout, "Format Complete\n"); 6500 } 6501 goto scsiformat_bailout; 6502 } 6503 6504doreport: 6505 do { 6506 cam_status status; 6507 6508 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6509 6510 /* 6511 * There's really no need to do error recovery or 6512 * retries here, since we're just going to sit in a 6513 * loop and wait for the device to finish formatting. 6514 */ 6515 scsi_test_unit_ready(&ccb->csio, 6516 /* retries */ 0, 6517 /* cbfcnp */ NULL, 6518 /* tag_action */ task_attr, 6519 /* sense_len */ SSD_FULL_SIZE, 6520 /* timeout */ 5000); 6521 6522 /* Disable freezing the device queue */ 6523 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6524 6525 retval = cam_send_ccb(device, ccb); 6526 6527 /* 6528 * If we get an error from the ioctl, bail out. SCSI 6529 * errors are expected. 6530 */ 6531 if (retval < 0) { 6532 warn("error sending TEST UNIT READY command"); 6533 error = 1; 6534 goto scsiformat_bailout; 6535 } 6536 6537 status = ccb->ccb_h.status & CAM_STATUS_MASK; 6538 6539 if ((status != CAM_REQ_CMP) 6540 && (status == CAM_SCSI_STATUS_ERROR) 6541 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 6542 struct scsi_sense_data *sense; 6543 int error_code, sense_key, asc, ascq; 6544 6545 sense = &ccb->csio.sense_data; 6546 scsi_extract_sense_len(sense, ccb->csio.sense_len - 6547 ccb->csio.sense_resid, &error_code, &sense_key, 6548 &asc, &ascq, /*show_errors*/ 1); 6549 6550 /* 6551 * According to the SCSI-2 and SCSI-3 specs, a 6552 * drive that is in the middle of a format should 6553 * return NOT READY with an ASC of "logical unit 6554 * not ready, format in progress". The sense key 6555 * specific bytes will then be a progress indicator. 6556 */ 6557 if ((sense_key == SSD_KEY_NOT_READY) 6558 && (asc == 0x04) && (ascq == 0x04)) { 6559 uint8_t sks[3]; 6560 6561 if ((scsi_get_sks(sense, ccb->csio.sense_len - 6562 ccb->csio.sense_resid, sks) == 0) 6563 && (quiet == 0)) { 6564 uint32_t val; 6565 u_int64_t percentage; 6566 6567 val = scsi_2btoul(&sks[1]); 6568 percentage = 10000ull * val; 6569 6570 fprintf(stdout, 6571 "\rFormatting: %ju.%02u %% " 6572 "(%u/%d) done", 6573 (uintmax_t)(percentage / 6574 (0x10000 * 100)), 6575 (unsigned)((percentage / 6576 0x10000) % 100), 6577 val, 0x10000); 6578 fflush(stdout); 6579 } else if ((quiet == 0) 6580 && (++num_warnings <= 1)) { 6581 warnx("Unexpected SCSI Sense Key " 6582 "Specific value returned " 6583 "during format:"); 6584 scsi_sense_print(device, &ccb->csio, 6585 stderr); 6586 warnx("Unable to print status " 6587 "information, but format will " 6588 "proceed."); 6589 warnx("will exit when format is " 6590 "complete"); 6591 } 6592 sleep(1); 6593 } else { 6594 warnx("Unexpected SCSI error during format"); 6595 cam_error_print(device, ccb, CAM_ESF_ALL, 6596 CAM_EPF_ALL, stderr); 6597 error = 1; 6598 goto scsiformat_bailout; 6599 } 6600 6601 } else if (status != CAM_REQ_CMP) { 6602 warnx("Unexpected CAM status %#x", status); 6603 if (arglist & CAM_ARG_VERBOSE) 6604 cam_error_print(device, ccb, CAM_ESF_ALL, 6605 CAM_EPF_ALL, stderr); 6606 error = 1; 6607 goto scsiformat_bailout; 6608 } 6609 6610 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); 6611 6612 if (quiet == 0) 6613 fprintf(stdout, "\nFormat Complete\n"); 6614 6615scsiformat_bailout: 6616 6617 cam_freeccb(ccb); 6618 6619 return (error); 6620} 6621 6622static int 6623sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet, 6624 camcontrol_devtype devtype) 6625{ 6626 int retval; 6627 uint8_t error = 0, ata_device = 0, status = 0; 6628 uint16_t count = 0; 6629 uint64_t lba = 0; 6630 u_int val, perc; 6631 6632 do { 6633 retval = build_ata_cmd(ccb, 6634 /*retries*/ 0, 6635 /*flags*/ CAM_DIR_NONE, 6636 /*tag_action*/ MSG_SIMPLE_Q_TAG, 6637 /*protocol*/ AP_PROTO_NON_DATA, 6638 /*ata_flags*/ AP_FLAG_CHK_COND, 6639 /*features*/ 0x00, /* SANITIZE STATUS EXT */ 6640 /*sector_count*/ 0, 6641 /*lba*/ 0, 6642 /*command*/ ATA_SANITIZE, 6643 /*auxiliary*/ 0, 6644 /*data_ptr*/ NULL, 6645 /*dxfer_len*/ 0, 6646 /*cdb_storage*/ NULL, 6647 /*cdb_storage_len*/ 0, 6648 /*sense_len*/ SSD_FULL_SIZE, 6649 /*timeout*/ 10000, 6650 /*is48bit*/ 1, 6651 /*devtype*/ devtype); 6652 if (retval != 0) { 6653 warnx("%s: build_ata_cmd() failed, likely " 6654 "programmer error", __func__); 6655 return (1); 6656 } 6657 6658 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6659 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6660 retval = cam_send_ccb(device, ccb); 6661 if (retval != 0) { 6662 warn("error sending SANITIZE STATUS EXT command"); 6663 return (1); 6664 } 6665 6666 retval = get_ata_status(device, ccb, &error, &count, &lba, 6667 &ata_device, &status); 6668 if (retval != 0) { 6669 warnx("Can't get SANITIZE STATUS EXT status, " 6670 "sanitize may still run."); 6671 return (retval); 6672 } 6673 if (status & ATA_STATUS_ERROR) { 6674 if (error & ATA_ERROR_ABORT) { 6675 switch (lba & 0xff) { 6676 case 0x00: 6677 warnx("Reason not reported or sanitize failed."); 6678 return (1); 6679 case 0x01: 6680 warnx("Sanitize command unsuccessful. "); 6681 return (1); 6682 case 0x02: 6683 warnx("Unsupported sanitize device command. "); 6684 return (1); 6685 case 0x03: 6686 warnx("Device is in sanitize frozen state. "); 6687 return (1); 6688 case 0x04: 6689 warnx("Sanitize antifreeze lock is enabled. "); 6690 return (1); 6691 } 6692 } 6693 warnx("SANITIZE STATUS EXT failed, " 6694 "sanitize may still run."); 6695 return (1); 6696 } 6697 if (count & 0x4000) { 6698 if (quiet == 0) { 6699 val = lba & 0xffff; 6700 perc = 10000 * val; 6701 fprintf(stdout, 6702 "Sanitizing: %u.%02u%% (%d/%d)\r", 6703 (perc / (0x10000 * 100)), 6704 ((perc / 0x10000) % 100), 6705 val, 0x10000); 6706 fflush(stdout); 6707 } 6708 sleep(1); 6709 } else 6710 break; 6711 } while (1); 6712 return (0); 6713} 6714 6715static int 6716sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet) 6717{ 6718 int warnings = 0, retval; 6719 cam_status status; 6720 u_int val, perc; 6721 6722 do { 6723 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6724 6725 /* 6726 * There's really no need to do error recovery or 6727 * retries here, since we're just going to sit in a 6728 * loop and wait for the device to finish sanitizing. 6729 */ 6730 scsi_test_unit_ready(&ccb->csio, 6731 /* retries */ 0, 6732 /* cbfcnp */ NULL, 6733 /* tag_action */ task_attr, 6734 /* sense_len */ SSD_FULL_SIZE, 6735 /* timeout */ 5000); 6736 6737 /* Disable freezing the device queue */ 6738 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6739 6740 retval = cam_send_ccb(device, ccb); 6741 6742 /* 6743 * If we get an error from the ioctl, bail out. SCSI 6744 * errors are expected. 6745 */ 6746 if (retval < 0) { 6747 warn("error sending TEST UNIT READY command"); 6748 return (1); 6749 } 6750 6751 status = ccb->ccb_h.status & CAM_STATUS_MASK; 6752 if ((status == CAM_SCSI_STATUS_ERROR) && 6753 ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 6754 struct scsi_sense_data *sense; 6755 int error_code, sense_key, asc, ascq; 6756 6757 sense = &ccb->csio.sense_data; 6758 scsi_extract_sense_len(sense, ccb->csio.sense_len - 6759 ccb->csio.sense_resid, &error_code, &sense_key, 6760 &asc, &ascq, /*show_errors*/ 1); 6761 6762 /* 6763 * According to the SCSI-3 spec, a drive that is in the 6764 * middle of a sanitize should return NOT READY with an 6765 * ASC of "logical unit not ready, sanitize in 6766 * progress". The sense key specific bytes will then 6767 * be a progress indicator. 6768 */ 6769 if ((sense_key == SSD_KEY_NOT_READY) 6770 && (asc == 0x04) && (ascq == 0x1b)) { 6771 uint8_t sks[3]; 6772 6773 if ((scsi_get_sks(sense, ccb->csio.sense_len - 6774 ccb->csio.sense_resid, sks) == 0) 6775 && (quiet == 0)) { 6776 val = scsi_2btoul(&sks[1]); 6777 perc = 10000 * val; 6778 fprintf(stdout, 6779 "Sanitizing: %u.%02u%% (%d/%d)\r", 6780 (perc / (0x10000 * 100)), 6781 ((perc / 0x10000) % 100), 6782 val, 0x10000); 6783 fflush(stdout); 6784 } else if ((quiet == 0) && (++warnings <= 1)) { 6785 warnx("Unexpected SCSI Sense Key " 6786 "Specific value returned " 6787 "during sanitize:"); 6788 scsi_sense_print(device, &ccb->csio, 6789 stderr); 6790 warnx("Unable to print status " 6791 "information, but sanitze will " 6792 "proceed."); 6793 warnx("will exit when sanitize is " 6794 "complete"); 6795 } 6796 sleep(1); 6797 } else { 6798 warnx("Unexpected SCSI error during sanitize"); 6799 cam_error_print(device, ccb, CAM_ESF_ALL, 6800 CAM_EPF_ALL, stderr); 6801 return (1); 6802 } 6803 6804 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) { 6805 warnx("Unexpected CAM status %#x", status); 6806 if (arglist & CAM_ARG_VERBOSE) 6807 cam_error_print(device, ccb, CAM_ESF_ALL, 6808 CAM_EPF_ALL, stderr); 6809 return (1); 6810 } 6811 } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); 6812 return (0); 6813} 6814 6815static int 6816sanitize(struct cam_device *device, int argc, char **argv, 6817 char *combinedopt, int task_attr, int retry_count, int timeout) 6818{ 6819 union ccb *ccb; 6820 u_int8_t action = 0; 6821 int c; 6822 int ycount = 0, quiet = 0; 6823 int error = 0; 6824 int use_timeout; 6825 int immediate = 1; 6826 int invert = 0; 6827 int passes = 0; 6828 int ause = 0; 6829 int fd = -1; 6830 const char *pattern = NULL; 6831 u_int8_t *data_ptr = NULL; 6832 u_int32_t dxfer_len = 0; 6833 uint8_t byte2; 6834 uint16_t feature, count; 6835 uint64_t lba; 6836 int reportonly = 0; 6837 camcontrol_devtype dt; 6838 6839 /* 6840 * Get the device type, request no I/O be done to do this. 6841 */ 6842 error = get_device_type(device, -1, 0, 0, &dt); 6843 if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) { 6844 warnx("sanitize: can't get device type"); 6845 return (1); 6846 } 6847 6848 ccb = cam_getccb(device); 6849 6850 if (ccb == NULL) { 6851 warnx("sanitize: error allocating ccb"); 6852 return (1); 6853 } 6854 6855 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6856 6857 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6858 switch(c) { 6859 case 'a': 6860 if (strcasecmp(optarg, "overwrite") == 0) 6861 action = SSZ_SERVICE_ACTION_OVERWRITE; 6862 else if (strcasecmp(optarg, "block") == 0) 6863 action = SSZ_SERVICE_ACTION_BLOCK_ERASE; 6864 else if (strcasecmp(optarg, "crypto") == 0) 6865 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE; 6866 else if (strcasecmp(optarg, "exitfailure") == 0) 6867 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE; 6868 else { 6869 warnx("invalid service operation \"%s\"", 6870 optarg); 6871 error = 1; 6872 goto sanitize_bailout; 6873 } 6874 break; 6875 case 'c': 6876 passes = strtol(optarg, NULL, 0); 6877 if (passes < 1 || passes > 31) { 6878 warnx("invalid passes value %d", passes); 6879 error = 1; 6880 goto sanitize_bailout; 6881 } 6882 break; 6883 case 'I': 6884 invert = 1; 6885 break; 6886 case 'P': 6887 pattern = optarg; 6888 break; 6889 case 'q': 6890 quiet++; 6891 break; 6892 case 'U': 6893 ause = 1; 6894 break; 6895 case 'r': 6896 reportonly = 1; 6897 break; 6898 case 'w': 6899 /* ATA supports only immediate commands. */ 6900 if (dt == CC_DT_SCSI) 6901 immediate = 0; 6902 break; 6903 case 'y': 6904 ycount++; 6905 break; 6906 } 6907 } 6908 6909 if (reportonly) 6910 goto doreport; 6911 6912 if (action == 0) { 6913 warnx("an action is required"); 6914 error = 1; 6915 goto sanitize_bailout; 6916 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) { 6917 struct scsi_sanitize_parameter_list *pl; 6918 struct stat sb; 6919 ssize_t sz, amt; 6920 6921 if (pattern == NULL) { 6922 warnx("overwrite action requires -P argument"); 6923 error = 1; 6924 goto sanitize_bailout; 6925 } 6926 fd = open(pattern, O_RDONLY); 6927 if (fd < 0) { 6928 warn("cannot open pattern file %s", pattern); 6929 error = 1; 6930 goto sanitize_bailout; 6931 } 6932 if (fstat(fd, &sb) < 0) { 6933 warn("cannot stat pattern file %s", pattern); 6934 error = 1; 6935 goto sanitize_bailout; 6936 } 6937 sz = sb.st_size; 6938 if (sz > SSZPL_MAX_PATTERN_LENGTH) { 6939 warnx("pattern file size exceeds maximum value %d", 6940 SSZPL_MAX_PATTERN_LENGTH); 6941 error = 1; 6942 goto sanitize_bailout; 6943 } 6944 dxfer_len = sizeof(*pl) + sz; 6945 data_ptr = calloc(1, dxfer_len); 6946 if (data_ptr == NULL) { 6947 warnx("cannot allocate parameter list buffer"); 6948 error = 1; 6949 goto sanitize_bailout; 6950 } 6951 6952 amt = read(fd, data_ptr + sizeof(*pl), sz); 6953 if (amt < 0) { 6954 warn("cannot read pattern file"); 6955 error = 1; 6956 goto sanitize_bailout; 6957 } else if (amt != sz) { 6958 warnx("short pattern file read"); 6959 error = 1; 6960 goto sanitize_bailout; 6961 } 6962 6963 pl = (struct scsi_sanitize_parameter_list *)data_ptr; 6964 if (passes == 0) 6965 pl->byte1 = 1; 6966 else 6967 pl->byte1 = passes; 6968 if (invert != 0) 6969 pl->byte1 |= SSZPL_INVERT; 6970 scsi_ulto2b(sz, pl->length); 6971 } else { 6972 const char *arg; 6973 6974 if (passes != 0) 6975 arg = "-c"; 6976 else if (invert != 0) 6977 arg = "-I"; 6978 else if (pattern != NULL) 6979 arg = "-P"; 6980 else 6981 arg = NULL; 6982 if (arg != NULL) { 6983 warnx("%s argument only valid with overwrite " 6984 "operation", arg); 6985 error = 1; 6986 goto sanitize_bailout; 6987 } 6988 } 6989 6990 if (quiet == 0 && ycount == 0) { 6991 fprintf(stdout, "You are about to REMOVE ALL DATA from the " 6992 "following device:\n"); 6993 6994 if (dt == CC_DT_SCSI) { 6995 error = scsidoinquiry(device, argc, argv, combinedopt, 6996 task_attr, retry_count, timeout); 6997 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) { 6998 struct ata_params *ident_buf; 6999 error = ata_do_identify(device, retry_count, timeout, 7000 ccb, &ident_buf); 7001 if (error == 0) { 7002 printf("%s%d: ", device->device_name, 7003 device->dev_unit_num); 7004 ata_print_ident(ident_buf); 7005 free(ident_buf); 7006 } 7007 } else 7008 error = 1; 7009 7010 if (error != 0) { 7011 warnx("sanitize: error sending inquiry"); 7012 goto sanitize_bailout; 7013 } 7014 } 7015 7016 if (ycount == 0) { 7017 if (!get_confirmation()) { 7018 error = 1; 7019 goto sanitize_bailout; 7020 } 7021 } 7022 7023 if (timeout != 0) 7024 use_timeout = timeout; 7025 else 7026 use_timeout = (immediate ? 10 : 10800) * 1000; 7027 7028 if (immediate == 0 && quiet == 0) { 7029 fprintf(stdout, "Current sanitize timeout is %d seconds\n", 7030 use_timeout / 1000); 7031 } 7032 7033 /* 7034 * If the user hasn't disabled questions and didn't specify a 7035 * timeout on the command line, ask them if they want the current 7036 * timeout. 7037 */ 7038 if (immediate == 0 && ycount == 0 && timeout == 0) { 7039 char str[1024]; 7040 int new_timeout = 0; 7041 7042 fprintf(stdout, "Enter new timeout in seconds or press\n" 7043 "return to keep the current timeout [%d] ", 7044 use_timeout / 1000); 7045 7046 if (fgets(str, sizeof(str), stdin) != NULL) { 7047 if (str[0] != '\0') 7048 new_timeout = atoi(str); 7049 } 7050 7051 if (new_timeout != 0) { 7052 use_timeout = new_timeout * 1000; 7053 fprintf(stdout, "Using new timeout value %d\n", 7054 use_timeout / 1000); 7055 } 7056 } 7057 7058 if (dt == CC_DT_SCSI) { 7059 byte2 = action; 7060 if (ause != 0) 7061 byte2 |= SSZ_UNRESTRICTED_EXIT; 7062 if (immediate != 0) 7063 byte2 |= SSZ_IMMED; 7064 scsi_sanitize(&ccb->csio, 7065 /* retries */ retry_count, 7066 /* cbfcnp */ NULL, 7067 /* tag_action */ task_attr, 7068 /* byte2 */ byte2, 7069 /* control */ 0, 7070 /* data_ptr */ data_ptr, 7071 /* dxfer_len */ dxfer_len, 7072 /* sense_len */ SSD_FULL_SIZE, 7073 /* timeout */ use_timeout); 7074 7075 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 7076 if (arglist & CAM_ARG_ERR_RECOVER) 7077 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 7078 if (cam_send_ccb(device, ccb) < 0) { 7079 warn("error sending sanitize command"); 7080 error = 1; 7081 goto sanitize_bailout; 7082 } 7083 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) { 7084 if (action == SSZ_SERVICE_ACTION_OVERWRITE) { 7085 feature = 0x14; /* OVERWRITE EXT */ 7086 lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4); 7087 count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes; 7088 if (invert) 7089 count |= 0x80; /* INVERT PATTERN */ 7090 if (ause) 7091 count |= 0x10; /* FAILURE MODE */ 7092 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) { 7093 feature = 0x12; /* BLOCK ERASE EXT */ 7094 lba = 0x0000426B4572; 7095 count = 0; 7096 if (ause) 7097 count |= 0x10; /* FAILURE MODE */ 7098 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) { 7099 feature = 0x11; /* CRYPTO SCRAMBLE EXT */ 7100 lba = 0x000043727970; 7101 count = 0; 7102 if (ause) 7103 count |= 0x10; /* FAILURE MODE */ 7104 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) { 7105 feature = 0x00; /* SANITIZE STATUS EXT */ 7106 lba = 0; 7107 count = 1; /* CLEAR SANITIZE OPERATION FAILED */ 7108 } else { 7109 error = 1; 7110 goto sanitize_bailout; 7111 } 7112 7113 error = ata_do_cmd(device, 7114 ccb, 7115 retry_count, 7116 /*flags*/CAM_DIR_NONE, 7117 /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND, 7118 /*ata_flags*/0, 7119 /*tag_action*/MSG_SIMPLE_Q_TAG, 7120 /*command*/ATA_SANITIZE, 7121 /*features*/feature, 7122 /*lba*/lba, 7123 /*sector_count*/count, 7124 /*data_ptr*/NULL, 7125 /*dxfer_len*/0, 7126 /*timeout*/ use_timeout, 7127 /*is48bit*/1); 7128 } 7129 7130 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 7131 struct scsi_sense_data *sense; 7132 int error_code, sense_key, asc, ascq; 7133 7134 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 7135 CAM_SCSI_STATUS_ERROR) { 7136 sense = &ccb->csio.sense_data; 7137 scsi_extract_sense_len(sense, ccb->csio.sense_len - 7138 ccb->csio.sense_resid, &error_code, &sense_key, 7139 &asc, &ascq, /*show_errors*/ 1); 7140 7141 if (sense_key == SSD_KEY_ILLEGAL_REQUEST && 7142 asc == 0x20 && ascq == 0x00) 7143 warnx("sanitize is not supported by " 7144 "this device"); 7145 else 7146 warnx("error sanitizing this device"); 7147 } else 7148 warnx("error sanitizing this device"); 7149 7150 if (arglist & CAM_ARG_VERBOSE) { 7151 cam_error_print(device, ccb, CAM_ESF_ALL, 7152 CAM_EPF_ALL, stderr); 7153 } 7154 error = 1; 7155 goto sanitize_bailout; 7156 } 7157 7158 /* 7159 * If we ran in non-immediate mode, we already checked for errors 7160 * above and printed out any necessary information. If we're in 7161 * immediate mode, we need to loop through and get status 7162 * information periodically. 7163 */ 7164 if (immediate == 0) { 7165 if (quiet == 0) { 7166 fprintf(stdout, "Sanitize Complete\n"); 7167 } 7168 goto sanitize_bailout; 7169 } 7170 7171doreport: 7172 if (dt == CC_DT_SCSI) { 7173 error = sanitize_wait_scsi(device, ccb, task_attr, quiet); 7174 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) { 7175 error = sanitize_wait_ata(device, ccb, quiet, dt); 7176 } else 7177 error = 1; 7178 if (error == 0 && quiet == 0) 7179 fprintf(stdout, "Sanitize Complete \n"); 7180 7181sanitize_bailout: 7182 if (fd >= 0) 7183 close(fd); 7184 if (data_ptr != NULL) 7185 free(data_ptr); 7186 cam_freeccb(ccb); 7187 7188 return (error); 7189} 7190 7191static int 7192scsireportluns(struct cam_device *device, int argc, char **argv, 7193 char *combinedopt, int task_attr, int retry_count, int timeout) 7194{ 7195 union ccb *ccb; 7196 int c, countonly, lunsonly; 7197 struct scsi_report_luns_data *lundata; 7198 int alloc_len; 7199 uint8_t report_type; 7200 uint32_t list_len, i, j; 7201 int retval; 7202 7203 retval = 0; 7204 lundata = NULL; 7205 report_type = RPL_REPORT_DEFAULT; 7206 ccb = cam_getccb(device); 7207 7208 if (ccb == NULL) { 7209 warnx("%s: error allocating ccb", __func__); 7210 return (1); 7211 } 7212 7213 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 7214 7215 countonly = 0; 7216 lunsonly = 0; 7217 7218 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7219 switch (c) { 7220 case 'c': 7221 countonly++; 7222 break; 7223 case 'l': 7224 lunsonly++; 7225 break; 7226 case 'r': 7227 if (strcasecmp(optarg, "default") == 0) 7228 report_type = RPL_REPORT_DEFAULT; 7229 else if (strcasecmp(optarg, "wellknown") == 0) 7230 report_type = RPL_REPORT_WELLKNOWN; 7231 else if (strcasecmp(optarg, "all") == 0) 7232 report_type = RPL_REPORT_ALL; 7233 else { 7234 warnx("%s: invalid report type \"%s\"", 7235 __func__, optarg); 7236 retval = 1; 7237 goto bailout; 7238 } 7239 break; 7240 default: 7241 break; 7242 } 7243 } 7244 7245 if ((countonly != 0) 7246 && (lunsonly != 0)) { 7247 warnx("%s: you can only specify one of -c or -l", __func__); 7248 retval = 1; 7249 goto bailout; 7250 } 7251 /* 7252 * According to SPC-4, the allocation length must be at least 16 7253 * bytes -- enough for the header and one LUN. 7254 */ 7255 alloc_len = sizeof(*lundata) + 8; 7256 7257retry: 7258 7259 lundata = malloc(alloc_len); 7260 7261 if (lundata == NULL) { 7262 warn("%s: error mallocing %d bytes", __func__, alloc_len); 7263 retval = 1; 7264 goto bailout; 7265 } 7266 7267 scsi_report_luns(&ccb->csio, 7268 /*retries*/ retry_count, 7269 /*cbfcnp*/ NULL, 7270 /*tag_action*/ task_attr, 7271 /*select_report*/ report_type, 7272 /*rpl_buf*/ lundata, 7273 /*alloc_len*/ alloc_len, 7274 /*sense_len*/ SSD_FULL_SIZE, 7275 /*timeout*/ timeout ? timeout : 5000); 7276 7277 /* Disable freezing the device queue */ 7278 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 7279 7280 if (arglist & CAM_ARG_ERR_RECOVER) 7281 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 7282 7283 if (cam_send_ccb(device, ccb) < 0) { 7284 warn("error sending REPORT LUNS command"); 7285 retval = 1; 7286 goto bailout; 7287 } 7288 7289 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 7290 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 7291 retval = 1; 7292 goto bailout; 7293 } 7294 7295 7296 list_len = scsi_4btoul(lundata->length); 7297 7298 /* 7299 * If we need to list the LUNs, and our allocation 7300 * length was too short, reallocate and retry. 7301 */ 7302 if ((countonly == 0) 7303 && (list_len > (alloc_len - sizeof(*lundata)))) { 7304 alloc_len = list_len + sizeof(*lundata); 7305 free(lundata); 7306 goto retry; 7307 } 7308 7309 if (lunsonly == 0) 7310 fprintf(stdout, "%u LUN%s found\n", list_len / 8, 7311 ((list_len / 8) > 1) ? "s" : ""); 7312 7313 if (countonly != 0) 7314 goto bailout; 7315 7316 for (i = 0; i < (list_len / 8); i++) { 7317 int no_more; 7318 7319 no_more = 0; 7320 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) { 7321 if (j != 0) 7322 fprintf(stdout, ","); 7323 switch (lundata->luns[i].lundata[j] & 7324 RPL_LUNDATA_ATYP_MASK) { 7325 case RPL_LUNDATA_ATYP_PERIPH: 7326 if ((lundata->luns[i].lundata[j] & 7327 RPL_LUNDATA_PERIPH_BUS_MASK) != 0) 7328 fprintf(stdout, "%d:", 7329 lundata->luns[i].lundata[j] & 7330 RPL_LUNDATA_PERIPH_BUS_MASK); 7331 else if ((j == 0) 7332 && ((lundata->luns[i].lundata[j+2] & 7333 RPL_LUNDATA_PERIPH_BUS_MASK) == 0)) 7334 no_more = 1; 7335 7336 fprintf(stdout, "%d", 7337 lundata->luns[i].lundata[j+1]); 7338 break; 7339 case RPL_LUNDATA_ATYP_FLAT: { 7340 uint8_t tmplun[2]; 7341 tmplun[0] = lundata->luns[i].lundata[j] & 7342 RPL_LUNDATA_FLAT_LUN_MASK; 7343 tmplun[1] = lundata->luns[i].lundata[j+1]; 7344 7345 fprintf(stdout, "%d", scsi_2btoul(tmplun)); 7346 no_more = 1; 7347 break; 7348 } 7349 case RPL_LUNDATA_ATYP_LUN: 7350 fprintf(stdout, "%d:%d:%d", 7351 (lundata->luns[i].lundata[j+1] & 7352 RPL_LUNDATA_LUN_BUS_MASK) >> 5, 7353 lundata->luns[i].lundata[j] & 7354 RPL_LUNDATA_LUN_TARG_MASK, 7355 lundata->luns[i].lundata[j+1] & 7356 RPL_LUNDATA_LUN_LUN_MASK); 7357 break; 7358 case RPL_LUNDATA_ATYP_EXTLUN: { 7359 int field_len_code, eam_code; 7360 7361 eam_code = lundata->luns[i].lundata[j] & 7362 RPL_LUNDATA_EXT_EAM_MASK; 7363 field_len_code = (lundata->luns[i].lundata[j] & 7364 RPL_LUNDATA_EXT_LEN_MASK) >> 4; 7365 7366 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK) 7367 && (field_len_code == 0x00)) { 7368 fprintf(stdout, "%d", 7369 lundata->luns[i].lundata[j+1]); 7370 } else if ((eam_code == 7371 RPL_LUNDATA_EXT_EAM_NOT_SPEC) 7372 && (field_len_code == 0x03)) { 7373 uint8_t tmp_lun[8]; 7374 7375 /* 7376 * This format takes up all 8 bytes. 7377 * If we aren't starting at offset 0, 7378 * that's a bug. 7379 */ 7380 if (j != 0) { 7381 fprintf(stdout, "Invalid " 7382 "offset %d for " 7383 "Extended LUN not " 7384 "specified format", j); 7385 no_more = 1; 7386 break; 7387 } 7388 bzero(tmp_lun, sizeof(tmp_lun)); 7389 bcopy(&lundata->luns[i].lundata[j+1], 7390 &tmp_lun[1], sizeof(tmp_lun) - 1); 7391 fprintf(stdout, "%#jx", 7392 (intmax_t)scsi_8btou64(tmp_lun)); 7393 no_more = 1; 7394 } else { 7395 fprintf(stderr, "Unknown Extended LUN" 7396 "Address method %#x, length " 7397 "code %#x", eam_code, 7398 field_len_code); 7399 no_more = 1; 7400 } 7401 break; 7402 } 7403 default: 7404 fprintf(stderr, "Unknown LUN address method " 7405 "%#x\n", lundata->luns[i].lundata[0] & 7406 RPL_LUNDATA_ATYP_MASK); 7407 break; 7408 } 7409 /* 7410 * For the flat addressing method, there are no 7411 * other levels after it. 7412 */ 7413 if (no_more != 0) 7414 break; 7415 } 7416 fprintf(stdout, "\n"); 7417 } 7418 7419bailout: 7420 7421 cam_freeccb(ccb); 7422 7423 free(lundata); 7424 7425 return (retval); 7426} 7427 7428static int 7429scsireadcapacity(struct cam_device *device, int argc, char **argv, 7430 char *combinedopt, int task_attr, int retry_count, int timeout) 7431{ 7432 union ccb *ccb; 7433 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly; 7434 struct scsi_read_capacity_data rcap; 7435 struct scsi_read_capacity_data_long rcaplong; 7436 uint64_t maxsector; 7437 uint32_t block_len; 7438 int retval; 7439 int c; 7440 7441 blocksizeonly = 0; 7442 humanize = 0; 7443 longonly = 0; 7444 numblocks = 0; 7445 quiet = 0; 7446 sizeonly = 0; 7447 baseten = 0; 7448 retval = 0; 7449 7450 ccb = cam_getccb(device); 7451 7452 if (ccb == NULL) { 7453 warnx("%s: error allocating ccb", __func__); 7454 return (1); 7455 } 7456 7457 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 7458 7459 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7460 switch (c) { 7461 case 'b': 7462 blocksizeonly++; 7463 break; 7464 case 'h': 7465 humanize++; 7466 baseten = 0; 7467 break; 7468 case 'H': 7469 humanize++; 7470 baseten++; 7471 break; 7472 case 'l': 7473 longonly++; 7474 break; 7475 case 'N': 7476 numblocks++; 7477 break; 7478 case 'q': 7479 quiet++; 7480 break; 7481 case 's': 7482 sizeonly++; 7483 break; 7484 default: 7485 break; 7486 } 7487 } 7488 7489 if ((blocksizeonly != 0) 7490 && (numblocks != 0)) { 7491 warnx("%s: you can only specify one of -b or -N", __func__); 7492 retval = 1; 7493 goto bailout; 7494 } 7495 7496 if ((blocksizeonly != 0) 7497 && (sizeonly != 0)) { 7498 warnx("%s: you can only specify one of -b or -s", __func__); 7499 retval = 1; 7500 goto bailout; 7501 } 7502 7503 if ((humanize != 0) 7504 && (quiet != 0)) { 7505 warnx("%s: you can only specify one of -h/-H or -q", __func__); 7506 retval = 1; 7507 goto bailout; 7508 } 7509 7510 if ((humanize != 0) 7511 && (blocksizeonly != 0)) { 7512 warnx("%s: you can only specify one of -h/-H or -b", __func__); 7513 retval = 1; 7514 goto bailout; 7515 } 7516 7517 if (longonly != 0) 7518 goto long_only; 7519 7520 scsi_read_capacity(&ccb->csio, 7521 /*retries*/ retry_count, 7522 /*cbfcnp*/ NULL, 7523 /*tag_action*/ task_attr, 7524 &rcap, 7525 SSD_FULL_SIZE, 7526 /*timeout*/ timeout ? timeout : 5000); 7527 7528 /* Disable freezing the device queue */ 7529 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 7530 7531 if (arglist & CAM_ARG_ERR_RECOVER) 7532 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 7533 7534 if (cam_send_ccb(device, ccb) < 0) { 7535 warn("error sending READ CAPACITY command"); 7536 retval = 1; 7537 goto bailout; 7538 } 7539 7540 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 7541 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 7542 retval = 1; 7543 goto bailout; 7544 } 7545 7546 maxsector = scsi_4btoul(rcap.addr); 7547 block_len = scsi_4btoul(rcap.length); 7548 7549 /* 7550 * A last block of 2^32-1 means that the true capacity is over 2TB, 7551 * and we need to issue the long READ CAPACITY to get the real 7552 * capacity. Otherwise, we're all set. 7553 */ 7554 if (maxsector != 0xffffffff) 7555 goto do_print; 7556 7557long_only: 7558 scsi_read_capacity_16(&ccb->csio, 7559 /*retries*/ retry_count, 7560 /*cbfcnp*/ NULL, 7561 /*tag_action*/ task_attr, 7562 /*lba*/ 0, 7563 /*reladdr*/ 0, 7564 /*pmi*/ 0, 7565 /*rcap_buf*/ (uint8_t *)&rcaplong, 7566 /*rcap_buf_len*/ sizeof(rcaplong), 7567 /*sense_len*/ SSD_FULL_SIZE, 7568 /*timeout*/ timeout ? timeout : 5000); 7569 7570 /* Disable freezing the device queue */ 7571 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 7572 7573 if (arglist & CAM_ARG_ERR_RECOVER) 7574 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 7575 7576 if (cam_send_ccb(device, ccb) < 0) { 7577 warn("error sending READ CAPACITY (16) command"); 7578 retval = 1; 7579 goto bailout; 7580 } 7581 7582 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 7583 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 7584 retval = 1; 7585 goto bailout; 7586 } 7587 7588 maxsector = scsi_8btou64(rcaplong.addr); 7589 block_len = scsi_4btoul(rcaplong.length); 7590 7591do_print: 7592 if (blocksizeonly == 0) { 7593 /* 7594 * Humanize implies !quiet, and also implies numblocks. 7595 */ 7596 if (humanize != 0) { 7597 char tmpstr[6]; 7598 int64_t tmpbytes; 7599 int ret; 7600 7601 tmpbytes = (maxsector + 1) * block_len; 7602 ret = humanize_number(tmpstr, sizeof(tmpstr), 7603 tmpbytes, "", HN_AUTOSCALE, 7604 HN_B | HN_DECIMAL | 7605 ((baseten != 0) ? 7606 HN_DIVISOR_1000 : 0)); 7607 if (ret == -1) { 7608 warnx("%s: humanize_number failed!", __func__); 7609 retval = 1; 7610 goto bailout; 7611 } 7612 fprintf(stdout, "Device Size: %s%s", tmpstr, 7613 (sizeonly == 0) ? ", " : "\n"); 7614 } else if (numblocks != 0) { 7615 fprintf(stdout, "%s%ju%s", (quiet == 0) ? 7616 "Blocks: " : "", (uintmax_t)maxsector + 1, 7617 (sizeonly == 0) ? ", " : "\n"); 7618 } else { 7619 fprintf(stdout, "%s%ju%s", (quiet == 0) ? 7620 "Last Block: " : "", (uintmax_t)maxsector, 7621 (sizeonly == 0) ? ", " : "\n"); 7622 } 7623 } 7624 if (sizeonly == 0) 7625 fprintf(stdout, "%s%u%s\n", (quiet == 0) ? 7626 "Block Length: " : "", block_len, (quiet == 0) ? 7627 " bytes" : ""); 7628bailout: 7629 cam_freeccb(ccb); 7630 7631 return (retval); 7632} 7633 7634static int 7635smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, 7636 int retry_count, int timeout) 7637{ 7638 int c, error = 0; 7639 union ccb *ccb; 7640 uint8_t *smp_request = NULL, *smp_response = NULL; 7641 int request_size = 0, response_size = 0; 7642 int fd_request = 0, fd_response = 0; 7643 char *datastr = NULL; 7644 struct get_hook hook; 7645 int retval; 7646 int flags = 0; 7647 7648 /* 7649 * Note that at the moment we don't support sending SMP CCBs to 7650 * devices that aren't probed by CAM. 7651 */ 7652 ccb = cam_getccb(device); 7653 if (ccb == NULL) { 7654 warnx("%s: error allocating CCB", __func__); 7655 return (1); 7656 } 7657 7658 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7659 7660 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7661 switch (c) { 7662 case 'R': 7663 arglist |= CAM_ARG_CMD_IN; 7664 response_size = strtol(optarg, NULL, 0); 7665 if (response_size <= 0) { 7666 warnx("invalid number of response bytes %d", 7667 response_size); 7668 error = 1; 7669 goto smpcmd_bailout; 7670 } 7671 hook.argc = argc - optind; 7672 hook.argv = argv + optind; 7673 hook.got = 0; 7674 optind++; 7675 datastr = cget(&hook, NULL); 7676 /* 7677 * If the user supplied "-" instead of a format, he 7678 * wants the data to be written to stdout. 7679 */ 7680 if ((datastr != NULL) 7681 && (datastr[0] == '-')) 7682 fd_response = 1; 7683 7684 smp_response = (u_int8_t *)malloc(response_size); 7685 if (smp_response == NULL) { 7686 warn("can't malloc memory for SMP response"); 7687 error = 1; 7688 goto smpcmd_bailout; 7689 } 7690 break; 7691 case 'r': 7692 arglist |= CAM_ARG_CMD_OUT; 7693 request_size = strtol(optarg, NULL, 0); 7694 if (request_size <= 0) { 7695 warnx("invalid number of request bytes %d", 7696 request_size); 7697 error = 1; 7698 goto smpcmd_bailout; 7699 } 7700 hook.argc = argc - optind; 7701 hook.argv = argv + optind; 7702 hook.got = 0; 7703 datastr = cget(&hook, NULL); 7704 smp_request = (u_int8_t *)malloc(request_size); 7705 if (smp_request == NULL) { 7706 warn("can't malloc memory for SMP request"); 7707 error = 1; 7708 goto smpcmd_bailout; 7709 } 7710 bzero(smp_request, request_size); 7711 /* 7712 * If the user supplied "-" instead of a format, he 7713 * wants the data to be read from stdin. 7714 */ 7715 if ((datastr != NULL) 7716 && (datastr[0] == '-')) 7717 fd_request = 1; 7718 else 7719 buff_encode_visit(smp_request, request_size, 7720 datastr, 7721 iget, &hook); 7722 optind += hook.got; 7723 break; 7724 default: 7725 break; 7726 } 7727 } 7728 7729 /* 7730 * If fd_data is set, and we're writing to the device, we need to 7731 * read the data the user wants written from stdin. 7732 */ 7733 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) { 7734 ssize_t amt_read; 7735 int amt_to_read = request_size; 7736 u_int8_t *buf_ptr = smp_request; 7737 7738 for (amt_read = 0; amt_to_read > 0; 7739 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) { 7740 if (amt_read == -1) { 7741 warn("error reading data from stdin"); 7742 error = 1; 7743 goto smpcmd_bailout; 7744 } 7745 amt_to_read -= amt_read; 7746 buf_ptr += amt_read; 7747 } 7748 } 7749 7750 if (((arglist & CAM_ARG_CMD_IN) == 0) 7751 || ((arglist & CAM_ARG_CMD_OUT) == 0)) { 7752 warnx("%s: need both the request (-r) and response (-R) " 7753 "arguments", __func__); 7754 error = 1; 7755 goto smpcmd_bailout; 7756 } 7757 7758 flags |= CAM_DEV_QFRZDIS; 7759 7760 cam_fill_smpio(&ccb->smpio, 7761 /*retries*/ retry_count, 7762 /*cbfcnp*/ NULL, 7763 /*flags*/ flags, 7764 /*smp_request*/ smp_request, 7765 /*smp_request_len*/ request_size, 7766 /*smp_response*/ smp_response, 7767 /*smp_response_len*/ response_size, 7768 /*timeout*/ timeout ? timeout : 5000); 7769 7770 ccb->smpio.flags = SMP_FLAG_NONE; 7771 7772 if (((retval = cam_send_ccb(device, ccb)) < 0) 7773 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7774 const char warnstr[] = "error sending command"; 7775 7776 if (retval < 0) 7777 warn(warnstr); 7778 else 7779 warnx(warnstr); 7780 7781 if (arglist & CAM_ARG_VERBOSE) { 7782 cam_error_print(device, ccb, CAM_ESF_ALL, 7783 CAM_EPF_ALL, stderr); 7784 } 7785 } 7786 7787 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 7788 && (response_size > 0)) { 7789 if (fd_response == 0) { 7790 buff_decode_visit(smp_response, response_size, 7791 datastr, arg_put, NULL); 7792 fprintf(stdout, "\n"); 7793 } else { 7794 ssize_t amt_written; 7795 int amt_to_write = response_size; 7796 u_int8_t *buf_ptr = smp_response; 7797 7798 for (amt_written = 0; (amt_to_write > 0) && 7799 (amt_written = write(STDOUT_FILENO, buf_ptr, 7800 amt_to_write)) > 0;){ 7801 amt_to_write -= amt_written; 7802 buf_ptr += amt_written; 7803 } 7804 if (amt_written == -1) { 7805 warn("error writing data to stdout"); 7806 error = 1; 7807 goto smpcmd_bailout; 7808 } else if ((amt_written == 0) 7809 && (amt_to_write > 0)) { 7810 warnx("only wrote %u bytes out of %u", 7811 response_size - amt_to_write, 7812 response_size); 7813 } 7814 } 7815 } 7816smpcmd_bailout: 7817 if (ccb != NULL) 7818 cam_freeccb(ccb); 7819 7820 if (smp_request != NULL) 7821 free(smp_request); 7822 7823 if (smp_response != NULL) 7824 free(smp_response); 7825 7826 return (error); 7827} 7828 7829static int 7830mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, 7831 int retry_count, int timeout) 7832{ 7833 int c, error = 0; 7834 union ccb *ccb; 7835 int32_t mmc_opcode = 0, mmc_arg = 0; 7836 int32_t mmc_flags = -1; 7837 int retval; 7838 int is_write = 0; 7839 int is_bw_4 = 0, is_bw_1 = 0; 7840 int is_frequency = 0; 7841 int is_highspeed = 0, is_stdspeed = 0; 7842 int is_info_request = 0; 7843 int flags = 0; 7844 uint8_t mmc_data_byte = 0; 7845 uint32_t mmc_frequency = 0; 7846 7847 /* For IO_RW_EXTENDED command */ 7848 uint8_t *mmc_data = NULL; 7849 struct mmc_data mmc_d; 7850 int mmc_data_len = 0; 7851 7852 /* 7853 * Note that at the moment we don't support sending SMP CCBs to 7854 * devices that aren't probed by CAM. 7855 */ 7856 ccb = cam_getccb(device); 7857 if (ccb == NULL) { 7858 warnx("%s: error allocating CCB", __func__); 7859 return (1); 7860 } 7861 7862 bzero(&(&ccb->ccb_h)[1], 7863 sizeof(union ccb) - sizeof(struct ccb_hdr)); 7864 7865 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7866 switch (c) { 7867 case '4': 7868 is_bw_4 = 1; 7869 break; 7870 case '1': 7871 is_bw_1 = 1; 7872 break; 7873 case 'S': 7874 if (!strcmp(optarg, "high")) 7875 is_highspeed = 1; 7876 else 7877 is_stdspeed = 1; 7878 break; 7879 case 'I': 7880 is_info_request = 1; 7881 break; 7882 case 'F': 7883 is_frequency = 1; 7884 mmc_frequency = strtol(optarg, NULL, 0); 7885 break; 7886 case 'c': 7887 mmc_opcode = strtol(optarg, NULL, 0); 7888 if (mmc_opcode < 0) { 7889 warnx("invalid MMC opcode %d", 7890 mmc_opcode); 7891 error = 1; 7892 goto mmccmd_bailout; 7893 } 7894 break; 7895 case 'a': 7896 mmc_arg = strtol(optarg, NULL, 0); 7897 if (mmc_arg < 0) { 7898 warnx("invalid MMC arg %d", 7899 mmc_arg); 7900 error = 1; 7901 goto mmccmd_bailout; 7902 } 7903 break; 7904 case 'f': 7905 mmc_flags = strtol(optarg, NULL, 0); 7906 if (mmc_flags < 0) { 7907 warnx("invalid MMC flags %d", 7908 mmc_flags); 7909 error = 1; 7910 goto mmccmd_bailout; 7911 } 7912 break; 7913 case 'l': 7914 mmc_data_len = strtol(optarg, NULL, 0); 7915 if (mmc_data_len <= 0) { 7916 warnx("invalid MMC data len %d", 7917 mmc_data_len); 7918 error = 1; 7919 goto mmccmd_bailout; 7920 } 7921 break; 7922 case 'W': 7923 is_write = 1; 7924 break; 7925 case 'b': 7926 mmc_data_byte = strtol(optarg, NULL, 0); 7927 break; 7928 default: 7929 break; 7930 } 7931 } 7932 flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */ 7933 7934 /* If flags are left default, supply the right flags */ 7935 if (mmc_flags < 0) 7936 switch (mmc_opcode) { 7937 case MMC_GO_IDLE_STATE: 7938 mmc_flags = MMC_RSP_NONE | MMC_CMD_BC; 7939 break; 7940 case IO_SEND_OP_COND: 7941 mmc_flags = MMC_RSP_R4; 7942 break; 7943 case SD_SEND_RELATIVE_ADDR: 7944 mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR; 7945 break; 7946 case MMC_SELECT_CARD: 7947 mmc_flags = MMC_RSP_R1B | MMC_CMD_AC; 7948 mmc_arg = mmc_arg << 16; 7949 break; 7950 case SD_IO_RW_DIRECT: 7951 mmc_flags = MMC_RSP_R5 | MMC_CMD_AC; 7952 mmc_arg = SD_IO_RW_ADR(mmc_arg); 7953 if (is_write) 7954 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte); 7955 break; 7956 case SD_IO_RW_EXTENDED: 7957 mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC; 7958 mmc_arg = SD_IO_RW_ADR(mmc_arg); 7959 int len_arg = mmc_data_len; 7960 if (mmc_data_len == 512) 7961 len_arg = 0; 7962 7963 // Byte mode 7964 mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR; 7965 // Block mode 7966// mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR; 7967 break; 7968 default: 7969 mmc_flags = MMC_RSP_R1; 7970 break; 7971 } 7972 7973 // Switch bus width instead of sending IO command 7974 if (is_bw_4 || is_bw_1) { 7975 struct ccb_trans_settings_mmc *cts; 7976 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 7977 ccb->ccb_h.flags = 0; 7978 cts = &ccb->cts.proto_specific.mmc; 7979 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1; 7980 cts->ios_valid = MMC_BW; 7981 if (((retval = cam_send_ccb(device, ccb)) < 0) 7982 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7983 warn("Error sending command"); 7984 } else { 7985 printf("Parameters set OK\n"); 7986 } 7987 cam_freeccb(ccb); 7988 return (retval); 7989 } 7990 7991 if (is_frequency) { 7992 struct ccb_trans_settings_mmc *cts; 7993 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 7994 ccb->ccb_h.flags = 0; 7995 cts = &ccb->cts.proto_specific.mmc; 7996 cts->ios.clock = mmc_frequency; 7997 cts->ios_valid = MMC_CLK; 7998 if (((retval = cam_send_ccb(device, ccb)) < 0) 7999 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 8000 warn("Error sending command"); 8001 } else { 8002 printf("Parameters set OK\n"); 8003 } 8004 cam_freeccb(ccb); 8005 return (retval); 8006 } 8007 8008 // Switch bus speed instead of sending IO command 8009 if (is_stdspeed || is_highspeed) { 8010 struct ccb_trans_settings_mmc *cts; 8011 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 8012 ccb->ccb_h.flags = 0; 8013 cts = &ccb->cts.proto_specific.mmc; 8014 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal; 8015 cts->ios_valid = MMC_BT; 8016 if (((retval = cam_send_ccb(device, ccb)) < 0) 8017 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 8018 warn("Error sending command"); 8019 } else { 8020 printf("Speed set OK (HS: %d)\n", is_highspeed); 8021 } 8022 cam_freeccb(ccb); 8023 return (retval); 8024 } 8025 8026 // Get information about controller and its settings 8027 if (is_info_request) { 8028 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 8029 ccb->ccb_h.flags = 0; 8030 struct ccb_trans_settings_mmc *cts; 8031 cts = &ccb->cts.proto_specific.mmc; 8032 if (((retval = cam_send_ccb(device, ccb)) < 0) 8033 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 8034 warn("Error sending command"); 8035 return (retval); 8036 } 8037 printf("Host controller information\n"); 8038 printf("Host OCR: 0x%x\n", cts->host_ocr); 8039 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000); 8040 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000); 8041 printf("Supported bus width:\n"); 8042 if (cts->host_caps & MMC_CAP_4_BIT_DATA) 8043 printf(" 4 bit\n"); 8044 if (cts->host_caps & MMC_CAP_8_BIT_DATA) 8045 printf(" 8 bit\n"); 8046 8047 printf("Supported operating modes:\n"); 8048 if (cts->host_caps & MMC_CAP_HSPEED) 8049 printf(" Can do High Speed transfers\n"); 8050 if (cts->host_caps & MMC_CAP_UHS_SDR12) 8051 printf(" Can do UHS SDR12\n"); 8052 if (cts->host_caps & MMC_CAP_UHS_SDR25) 8053 printf(" Can do UHS SDR25\n"); 8054 if (cts->host_caps & MMC_CAP_UHS_SDR50) 8055 printf(" Can do UHS SDR50\n"); 8056 if (cts->host_caps & MMC_CAP_UHS_SDR104) 8057 printf(" Can do UHS SDR104\n"); 8058 if (cts->host_caps & MMC_CAP_UHS_DDR50) 8059 printf(" Can do UHS DDR50\n"); 8060 if (cts->host_caps & MMC_CAP_MMC_DDR52_120) 8061 printf(" Can do eMMC DDR52 at 1.2V\n"); 8062 if (cts->host_caps & MMC_CAP_MMC_DDR52_180) 8063 printf(" Can do eMMC DDR52 at 1.8V\n"); 8064 if (cts->host_caps & MMC_CAP_MMC_HS200_120) 8065 printf(" Can do eMMC HS200 at 1.2V\n"); 8066 if (cts->host_caps & MMC_CAP_MMC_HS200_180) 8067 printf(" Can do eMMC HS200 at 1.8V\n"); 8068 if (cts->host_caps & MMC_CAP_MMC_HS400_120) 8069 printf(" Can do eMMC HS400 at 1.2V\n"); 8070 if (cts->host_caps & MMC_CAP_MMC_HS400_180) 8071 printf(" Can do eMMC HS400 at 1.8V\n"); 8072 8073 printf("Supported VCCQ voltages:\n"); 8074 if (cts->host_caps & MMC_CAP_SIGNALING_120) 8075 printf(" 1.2V\n"); 8076 if (cts->host_caps & MMC_CAP_SIGNALING_180) 8077 printf(" 1.8V\n"); 8078 if (cts->host_caps & MMC_CAP_SIGNALING_330) 8079 printf(" 3.3V\n"); 8080 8081 printf("Current settings:\n"); 8082 printf(" Bus width: "); 8083 switch (cts->ios.bus_width) { 8084 case bus_width_1: 8085 printf("1 bit\n"); 8086 break; 8087 case bus_width_4: 8088 printf("4 bit\n"); 8089 break; 8090 case bus_width_8: 8091 printf("8 bit\n"); 8092 break; 8093 } 8094 printf(" Freq: %d.%03d MHz%s\n", 8095 cts->ios.clock / 1000000, 8096 (cts->ios.clock / 1000) % 1000, 8097 cts->ios.timing == bus_timing_hs ? " (high-speed timing)" : ""); 8098 8099 printf(" VCCQ: "); 8100 switch (cts->ios.vccq) { 8101 case vccq_330: 8102 printf("3.3V\n"); 8103 break; 8104 case vccq_180: 8105 printf("1.8V\n"); 8106 break; 8107 case vccq_120: 8108 printf("1.2V\n"); 8109 break; 8110 } 8111 return (0); 8112 } 8113 8114 printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags); 8115 8116 if (mmc_data_len > 0) { 8117 flags |= CAM_DIR_IN; 8118 mmc_data = malloc(mmc_data_len); 8119 memset(mmc_data, 0, mmc_data_len); 8120 memset(&mmc_d, 0, sizeof(mmc_d)); 8121 mmc_d.len = mmc_data_len; 8122 mmc_d.data = mmc_data; 8123 mmc_d.flags = MMC_DATA_READ; 8124 } else flags |= CAM_DIR_NONE; 8125 8126 cam_fill_mmcio(&ccb->mmcio, 8127 /*retries*/ retry_count, 8128 /*cbfcnp*/ NULL, 8129 /*flags*/ flags, 8130 /*mmc_opcode*/ mmc_opcode, 8131 /*mmc_arg*/ mmc_arg, 8132 /*mmc_flags*/ mmc_flags, 8133 /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL, 8134 /*timeout*/ timeout ? timeout : 5000); 8135 8136 if (((retval = cam_send_ccb(device, ccb)) < 0) 8137 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 8138 const char warnstr[] = "error sending command"; 8139 8140 if (retval < 0) 8141 warn(warnstr); 8142 else 8143 warnx(warnstr); 8144 8145 if (arglist & CAM_ARG_VERBOSE) { 8146 cam_error_print(device, ccb, CAM_ESF_ALL, 8147 CAM_EPF_ALL, stderr); 8148 } 8149 } 8150 8151 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) { 8152 printf("MMCIO: error %d, %08x %08x %08x %08x\n", 8153 ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0], 8154 ccb->mmcio.cmd.resp[1], 8155 ccb->mmcio.cmd.resp[2], 8156 ccb->mmcio.cmd.resp[3]); 8157 8158 switch (mmc_opcode) { 8159 case SD_IO_RW_DIRECT: 8160 printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n", 8161 SD_R5_DATA(ccb->mmcio.cmd.resp), 8162 (ccb->mmcio.cmd.resp[0] >> 12) & 0x3); 8163 break; 8164 case SD_IO_RW_EXTENDED: 8165 printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len); 8166 hexdump(mmc_data, mmc_data_len, NULL, 0); 8167 break; 8168 case SD_SEND_RELATIVE_ADDR: 8169 printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16); 8170 break; 8171 default: 8172 printf("No command-specific decoder for CMD %d\n", mmc_opcode); 8173 } 8174 } 8175mmccmd_bailout: 8176 if (ccb != NULL) 8177 cam_freeccb(ccb); 8178 8179 if (mmc_data_len > 0 && mmc_data != NULL) 8180 free(mmc_data); 8181 8182 return (error); 8183} 8184 8185static int 8186smpreportgeneral(struct cam_device *device, int argc, char **argv, 8187 char *combinedopt, int retry_count, int timeout) 8188{ 8189 union ccb *ccb; 8190 struct smp_report_general_request *request = NULL; 8191 struct smp_report_general_response *response = NULL; 8192 struct sbuf *sb = NULL; 8193 int error = 0; 8194 int c, long_response = 0; 8195 int retval; 8196 8197 /* 8198 * Note that at the moment we don't support sending SMP CCBs to 8199 * devices that aren't probed by CAM. 8200 */ 8201 ccb = cam_getccb(device); 8202 if (ccb == NULL) { 8203 warnx("%s: error allocating CCB", __func__); 8204 return (1); 8205 } 8206 8207 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 8208 8209 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8210 switch (c) { 8211 case 'l': 8212 long_response = 1; 8213 break; 8214 default: 8215 break; 8216 } 8217 } 8218 request = malloc(sizeof(*request)); 8219 if (request == NULL) { 8220 warn("%s: unable to allocate %zd bytes", __func__, 8221 sizeof(*request)); 8222 error = 1; 8223 goto bailout; 8224 } 8225 8226 response = malloc(sizeof(*response)); 8227 if (response == NULL) { 8228 warn("%s: unable to allocate %zd bytes", __func__, 8229 sizeof(*response)); 8230 error = 1; 8231 goto bailout; 8232 } 8233 8234try_long: 8235 smp_report_general(&ccb->smpio, 8236 retry_count, 8237 /*cbfcnp*/ NULL, 8238 request, 8239 /*request_len*/ sizeof(*request), 8240 (uint8_t *)response, 8241 /*response_len*/ sizeof(*response), 8242 /*long_response*/ long_response, 8243 timeout); 8244 8245 if (((retval = cam_send_ccb(device, ccb)) < 0) 8246 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 8247 const char warnstr[] = "error sending command"; 8248 8249 if (retval < 0) 8250 warn(warnstr); 8251 else 8252 warnx(warnstr); 8253 8254 if (arglist & CAM_ARG_VERBOSE) { 8255 cam_error_print(device, ccb, CAM_ESF_ALL, 8256 CAM_EPF_ALL, stderr); 8257 } 8258 error = 1; 8259 goto bailout; 8260 } 8261 8262 /* 8263 * If the device supports the long response bit, try again and see 8264 * if we can get all of the data. 8265 */ 8266 if ((response->long_response & SMP_RG_LONG_RESPONSE) 8267 && (long_response == 0)) { 8268 ccb->ccb_h.status = CAM_REQ_INPROG; 8269 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 8270 long_response = 1; 8271 goto try_long; 8272 } 8273 8274 /* 8275 * XXX KDM detect and decode SMP errors here. 8276 */ 8277 sb = sbuf_new_auto(); 8278 if (sb == NULL) { 8279 warnx("%s: error allocating sbuf", __func__); 8280 goto bailout; 8281 } 8282 8283 smp_report_general_sbuf(response, sizeof(*response), sb); 8284 8285 if (sbuf_finish(sb) != 0) { 8286 warnx("%s: sbuf_finish", __func__); 8287 goto bailout; 8288 } 8289 8290 printf("%s", sbuf_data(sb)); 8291 8292bailout: 8293 if (ccb != NULL) 8294 cam_freeccb(ccb); 8295 8296 if (request != NULL) 8297 free(request); 8298 8299 if (response != NULL) 8300 free(response); 8301 8302 if (sb != NULL) 8303 sbuf_delete(sb); 8304 8305 return (error); 8306} 8307 8308static struct camcontrol_opts phy_ops[] = { 8309 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL}, 8310 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL}, 8311 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL}, 8312 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL}, 8313 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL}, 8314 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL}, 8315 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL}, 8316 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL}, 8317 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL}, 8318 {NULL, 0, 0, NULL} 8319}; 8320 8321static int 8322smpphycontrol(struct cam_device *device, int argc, char **argv, 8323 char *combinedopt, int retry_count, int timeout) 8324{ 8325 union ccb *ccb; 8326 struct smp_phy_control_request *request = NULL; 8327 struct smp_phy_control_response *response = NULL; 8328 int long_response = 0; 8329 int retval = 0; 8330 int phy = -1; 8331 uint32_t phy_operation = SMP_PC_PHY_OP_NOP; 8332 int phy_op_set = 0; 8333 uint64_t attached_dev_name = 0; 8334 int dev_name_set = 0; 8335 uint32_t min_plr = 0, max_plr = 0; 8336 uint32_t pp_timeout_val = 0; 8337 int slumber_partial = 0; 8338 int set_pp_timeout_val = 0; 8339 int c; 8340 8341 /* 8342 * Note that at the moment we don't support sending SMP CCBs to 8343 * devices that aren't probed by CAM. 8344 */ 8345 ccb = cam_getccb(device); 8346 if (ccb == NULL) { 8347 warnx("%s: error allocating CCB", __func__); 8348 return (1); 8349 } 8350 8351 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 8352 8353 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8354 switch (c) { 8355 case 'a': 8356 case 'A': 8357 case 's': 8358 case 'S': { 8359 int enable = -1; 8360 8361 if (strcasecmp(optarg, "enable") == 0) 8362 enable = 1; 8363 else if (strcasecmp(optarg, "disable") == 0) 8364 enable = 2; 8365 else { 8366 warnx("%s: Invalid argument %s", __func__, 8367 optarg); 8368 retval = 1; 8369 goto bailout; 8370 } 8371 switch (c) { 8372 case 's': 8373 slumber_partial |= enable << 8374 SMP_PC_SAS_SLUMBER_SHIFT; 8375 break; 8376 case 'S': 8377 slumber_partial |= enable << 8378 SMP_PC_SAS_PARTIAL_SHIFT; 8379 break; 8380 case 'a': 8381 slumber_partial |= enable << 8382 SMP_PC_SATA_SLUMBER_SHIFT; 8383 break; 8384 case 'A': 8385 slumber_partial |= enable << 8386 SMP_PC_SATA_PARTIAL_SHIFT; 8387 break; 8388 default: 8389 warnx("%s: programmer error", __func__); 8390 retval = 1; 8391 goto bailout; 8392 break; /*NOTREACHED*/ 8393 } 8394 break; 8395 } 8396 case 'd': 8397 attached_dev_name = (uintmax_t)strtoumax(optarg, 8398 NULL,0); 8399 dev_name_set = 1; 8400 break; 8401 case 'l': 8402 long_response = 1; 8403 break; 8404 case 'm': 8405 /* 8406 * We don't do extensive checking here, so this 8407 * will continue to work when new speeds come out. 8408 */ 8409 min_plr = strtoul(optarg, NULL, 0); 8410 if ((min_plr == 0) 8411 || (min_plr > 0xf)) { 8412 warnx("%s: invalid link rate %x", 8413 __func__, min_plr); 8414 retval = 1; 8415 goto bailout; 8416 } 8417 break; 8418 case 'M': 8419 /* 8420 * We don't do extensive checking here, so this 8421 * will continue to work when new speeds come out. 8422 */ 8423 max_plr = strtoul(optarg, NULL, 0); 8424 if ((max_plr == 0) 8425 || (max_plr > 0xf)) { 8426 warnx("%s: invalid link rate %x", 8427 __func__, max_plr); 8428 retval = 1; 8429 goto bailout; 8430 } 8431 break; 8432 case 'o': { 8433 camcontrol_optret optreturn; 8434 cam_argmask argnums; 8435 const char *subopt; 8436 8437 if (phy_op_set != 0) { 8438 warnx("%s: only one phy operation argument " 8439 "(-o) allowed", __func__); 8440 retval = 1; 8441 goto bailout; 8442 } 8443 8444 phy_op_set = 1; 8445 8446 /* 8447 * Allow the user to specify the phy operation 8448 * numerically, as well as with a name. This will 8449 * future-proof it a bit, so options that are added 8450 * in future specs can be used. 8451 */ 8452 if (isdigit(optarg[0])) { 8453 phy_operation = strtoul(optarg, NULL, 0); 8454 if ((phy_operation == 0) 8455 || (phy_operation > 0xff)) { 8456 warnx("%s: invalid phy operation %#x", 8457 __func__, phy_operation); 8458 retval = 1; 8459 goto bailout; 8460 } 8461 break; 8462 } 8463 optreturn = getoption(phy_ops, optarg, &phy_operation, 8464 &argnums, &subopt); 8465 8466 if (optreturn == CC_OR_AMBIGUOUS) { 8467 warnx("%s: ambiguous option %s", __func__, 8468 optarg); 8469 usage(0); 8470 retval = 1; 8471 goto bailout; 8472 } else if (optreturn == CC_OR_NOT_FOUND) { 8473 warnx("%s: option %s not found", __func__, 8474 optarg); 8475 usage(0); 8476 retval = 1; 8477 goto bailout; 8478 } 8479 break; 8480 } 8481 case 'p': 8482 phy = atoi(optarg); 8483 break; 8484 case 'T': 8485 pp_timeout_val = strtoul(optarg, NULL, 0); 8486 if (pp_timeout_val > 15) { 8487 warnx("%s: invalid partial pathway timeout " 8488 "value %u, need a value less than 16", 8489 __func__, pp_timeout_val); 8490 retval = 1; 8491 goto bailout; 8492 } 8493 set_pp_timeout_val = 1; 8494 break; 8495 default: 8496 break; 8497 } 8498 } 8499 8500 if (phy == -1) { 8501 warnx("%s: a PHY (-p phy) argument is required",__func__); 8502 retval = 1; 8503 goto bailout; 8504 } 8505 8506 if (((dev_name_set != 0) 8507 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME)) 8508 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME) 8509 && (dev_name_set == 0))) { 8510 warnx("%s: -d name and -o setdevname arguments both " 8511 "required to set device name", __func__); 8512 retval = 1; 8513 goto bailout; 8514 } 8515 8516 request = malloc(sizeof(*request)); 8517 if (request == NULL) { 8518 warn("%s: unable to allocate %zd bytes", __func__, 8519 sizeof(*request)); 8520 retval = 1; 8521 goto bailout; 8522 } 8523 8524 response = malloc(sizeof(*response)); 8525 if (response == NULL) { 8526 warn("%s: unable to allocate %zd bytes", __func__, 8527 sizeof(*response)); 8528 retval = 1; 8529 goto bailout; 8530 } 8531 8532 smp_phy_control(&ccb->smpio, 8533 retry_count, 8534 /*cbfcnp*/ NULL, 8535 request, 8536 sizeof(*request), 8537 (uint8_t *)response, 8538 sizeof(*response), 8539 long_response, 8540 /*expected_exp_change_count*/ 0, 8541 phy, 8542 phy_operation, 8543 (set_pp_timeout_val != 0) ? 1 : 0, 8544 attached_dev_name, 8545 min_plr, 8546 max_plr, 8547 slumber_partial, 8548 pp_timeout_val, 8549 timeout); 8550 8551 if (((retval = cam_send_ccb(device, ccb)) < 0) 8552 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 8553 const char warnstr[] = "error sending command"; 8554 8555 if (retval < 0) 8556 warn(warnstr); 8557 else 8558 warnx(warnstr); 8559 8560 if (arglist & CAM_ARG_VERBOSE) { 8561 /* 8562 * Use CAM_EPF_NORMAL so we only get one line of 8563 * SMP command decoding. 8564 */ 8565 cam_error_print(device, ccb, CAM_ESF_ALL, 8566 CAM_EPF_NORMAL, stderr); 8567 } 8568 retval = 1; 8569 goto bailout; 8570 } 8571 8572 /* XXX KDM print out something here for success? */ 8573bailout: 8574 if (ccb != NULL) 8575 cam_freeccb(ccb); 8576 8577 if (request != NULL) 8578 free(request); 8579 8580 if (response != NULL) 8581 free(response); 8582 8583 return (retval); 8584} 8585 8586static int 8587smpmaninfo(struct cam_device *device, int argc, char **argv, 8588 char *combinedopt, int retry_count, int timeout) 8589{ 8590 union ccb *ccb; 8591 struct smp_report_manuf_info_request request; 8592 struct smp_report_manuf_info_response response; 8593 struct sbuf *sb = NULL; 8594 int long_response = 0; 8595 int retval = 0; 8596 int c; 8597 8598 /* 8599 * Note that at the moment we don't support sending SMP CCBs to 8600 * devices that aren't probed by CAM. 8601 */ 8602 ccb = cam_getccb(device); 8603 if (ccb == NULL) { 8604 warnx("%s: error allocating CCB", __func__); 8605 return (1); 8606 } 8607 8608 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 8609 8610 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8611 switch (c) { 8612 case 'l': 8613 long_response = 1; 8614 break; 8615 default: 8616 break; 8617 } 8618 } 8619 bzero(&request, sizeof(request)); 8620 bzero(&response, sizeof(response)); 8621 8622 smp_report_manuf_info(&ccb->smpio, 8623 retry_count, 8624 /*cbfcnp*/ NULL, 8625 &request, 8626 sizeof(request), 8627 (uint8_t *)&response, 8628 sizeof(response), 8629 long_response, 8630 timeout); 8631 8632 if (((retval = cam_send_ccb(device, ccb)) < 0) 8633 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 8634 const char warnstr[] = "error sending command"; 8635 8636 if (retval < 0) 8637 warn(warnstr); 8638 else 8639 warnx(warnstr); 8640 8641 if (arglist & CAM_ARG_VERBOSE) { 8642 cam_error_print(device, ccb, CAM_ESF_ALL, 8643 CAM_EPF_ALL, stderr); 8644 } 8645 retval = 1; 8646 goto bailout; 8647 } 8648 8649 sb = sbuf_new_auto(); 8650 if (sb == NULL) { 8651 warnx("%s: error allocating sbuf", __func__); 8652 goto bailout; 8653 } 8654 8655 smp_report_manuf_info_sbuf(&response, sizeof(response), sb); 8656 8657 if (sbuf_finish(sb) != 0) { 8658 warnx("%s: sbuf_finish", __func__); 8659 goto bailout; 8660 } 8661 8662 printf("%s", sbuf_data(sb)); 8663 8664bailout: 8665 8666 if (ccb != NULL) 8667 cam_freeccb(ccb); 8668 8669 if (sb != NULL) 8670 sbuf_delete(sb); 8671 8672 return (retval); 8673} 8674 8675static int 8676getdevid(struct cam_devitem *item) 8677{ 8678 int retval = 0; 8679 union ccb *ccb = NULL; 8680 8681 struct cam_device *dev; 8682 8683 dev = cam_open_btl(item->dev_match.path_id, 8684 item->dev_match.target_id, 8685 item->dev_match.target_lun, O_RDWR, NULL); 8686 8687 if (dev == NULL) { 8688 warnx("%s", cam_errbuf); 8689 retval = 1; 8690 goto bailout; 8691 } 8692 8693 item->device_id_len = 0; 8694 8695 ccb = cam_getccb(dev); 8696 if (ccb == NULL) { 8697 warnx("%s: error allocating CCB", __func__); 8698 retval = 1; 8699 goto bailout; 8700 } 8701 8702 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai); 8703 8704 /* 8705 * On the first try, we just probe for the size of the data, and 8706 * then allocate that much memory and try again. 8707 */ 8708retry: 8709 ccb->ccb_h.func_code = XPT_DEV_ADVINFO; 8710 ccb->ccb_h.flags = CAM_DIR_IN; 8711 ccb->cdai.flags = CDAI_FLAG_NONE; 8712 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID; 8713 ccb->cdai.bufsiz = item->device_id_len; 8714 if (item->device_id_len != 0) 8715 ccb->cdai.buf = (uint8_t *)item->device_id; 8716 8717 if (cam_send_ccb(dev, ccb) < 0) { 8718 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__); 8719 retval = 1; 8720 goto bailout; 8721 } 8722 8723 if (ccb->ccb_h.status != CAM_REQ_CMP) { 8724 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status); 8725 retval = 1; 8726 goto bailout; 8727 } 8728 8729 if (item->device_id_len == 0) { 8730 /* 8731 * This is our first time through. Allocate the buffer, 8732 * and then go back to get the data. 8733 */ 8734 if (ccb->cdai.provsiz == 0) { 8735 warnx("%s: invalid .provsiz field returned with " 8736 "XPT_GDEV_ADVINFO CCB", __func__); 8737 retval = 1; 8738 goto bailout; 8739 } 8740 item->device_id_len = ccb->cdai.provsiz; 8741 item->device_id = malloc(item->device_id_len); 8742 if (item->device_id == NULL) { 8743 warn("%s: unable to allocate %d bytes", __func__, 8744 item->device_id_len); 8745 retval = 1; 8746 goto bailout; 8747 } 8748 ccb->ccb_h.status = CAM_REQ_INPROG; 8749 goto retry; 8750 } 8751 8752bailout: 8753 if (dev != NULL) 8754 cam_close_device(dev); 8755 8756 if (ccb != NULL) 8757 cam_freeccb(ccb); 8758 8759 return (retval); 8760} 8761 8762/* 8763 * XXX KDM merge this code with getdevtree()? 8764 */ 8765static int 8766buildbusdevlist(struct cam_devlist *devlist) 8767{ 8768 union ccb ccb; 8769 int bufsize, fd = -1; 8770 struct dev_match_pattern *patterns; 8771 struct cam_devitem *item = NULL; 8772 int skip_device = 0; 8773 int retval = 0; 8774 8775 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { 8776 warn("couldn't open %s", XPT_DEVICE); 8777 return (1); 8778 } 8779 8780 bzero(&ccb, sizeof(union ccb)); 8781 8782 ccb.ccb_h.path_id = CAM_XPT_PATH_ID; 8783 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 8784 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 8785 8786 ccb.ccb_h.func_code = XPT_DEV_MATCH; 8787 bufsize = sizeof(struct dev_match_result) * 100; 8788 ccb.cdm.match_buf_len = bufsize; 8789 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); 8790 if (ccb.cdm.matches == NULL) { 8791 warnx("can't malloc memory for matches"); 8792 close(fd); 8793 return (1); 8794 } 8795 ccb.cdm.num_matches = 0; 8796 ccb.cdm.num_patterns = 2; 8797 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) * 8798 ccb.cdm.num_patterns; 8799 8800 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len); 8801 if (patterns == NULL) { 8802 warnx("can't malloc memory for patterns"); 8803 retval = 1; 8804 goto bailout; 8805 } 8806 8807 ccb.cdm.patterns = patterns; 8808 bzero(patterns, ccb.cdm.pattern_buf_len); 8809 8810 patterns[0].type = DEV_MATCH_DEVICE; 8811 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH; 8812 patterns[0].pattern.device_pattern.path_id = devlist->path_id; 8813 patterns[1].type = DEV_MATCH_PERIPH; 8814 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH; 8815 patterns[1].pattern.periph_pattern.path_id = devlist->path_id; 8816 8817 /* 8818 * We do the ioctl multiple times if necessary, in case there are 8819 * more than 100 nodes in the EDT. 8820 */ 8821 do { 8822 unsigned int i; 8823 8824 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 8825 warn("error sending CAMIOCOMMAND ioctl"); 8826 retval = 1; 8827 goto bailout; 8828 } 8829 8830 if ((ccb.ccb_h.status != CAM_REQ_CMP) 8831 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) 8832 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { 8833 warnx("got CAM error %#x, CDM error %d\n", 8834 ccb.ccb_h.status, ccb.cdm.status); 8835 retval = 1; 8836 goto bailout; 8837 } 8838 8839 for (i = 0; i < ccb.cdm.num_matches; i++) { 8840 switch (ccb.cdm.matches[i].type) { 8841 case DEV_MATCH_DEVICE: { 8842 struct device_match_result *dev_result; 8843 8844 dev_result = 8845 &ccb.cdm.matches[i].result.device_result; 8846 8847 if (dev_result->flags & 8848 DEV_RESULT_UNCONFIGURED) { 8849 skip_device = 1; 8850 break; 8851 } else 8852 skip_device = 0; 8853 8854 item = malloc(sizeof(*item)); 8855 if (item == NULL) { 8856 warn("%s: unable to allocate %zd bytes", 8857 __func__, sizeof(*item)); 8858 retval = 1; 8859 goto bailout; 8860 } 8861 bzero(item, sizeof(*item)); 8862 bcopy(dev_result, &item->dev_match, 8863 sizeof(*dev_result)); 8864 STAILQ_INSERT_TAIL(&devlist->dev_queue, item, 8865 links); 8866 8867 if (getdevid(item) != 0) { 8868 retval = 1; 8869 goto bailout; 8870 } 8871 break; 8872 } 8873 case DEV_MATCH_PERIPH: { 8874 struct periph_match_result *periph_result; 8875 8876 periph_result = 8877 &ccb.cdm.matches[i].result.periph_result; 8878 8879 if (skip_device != 0) 8880 break; 8881 item->num_periphs++; 8882 item->periph_matches = realloc( 8883 item->periph_matches, 8884 item->num_periphs * 8885 sizeof(struct periph_match_result)); 8886 if (item->periph_matches == NULL) { 8887 warn("%s: error allocating periph " 8888 "list", __func__); 8889 retval = 1; 8890 goto bailout; 8891 } 8892 bcopy(periph_result, &item->periph_matches[ 8893 item->num_periphs - 1], 8894 sizeof(*periph_result)); 8895 break; 8896 } 8897 default: 8898 fprintf(stderr, "%s: unexpected match " 8899 "type %d\n", __func__, 8900 ccb.cdm.matches[i].type); 8901 retval = 1; 8902 goto bailout; 8903 break; /*NOTREACHED*/ 8904 } 8905 } 8906 } while ((ccb.ccb_h.status == CAM_REQ_CMP) 8907 && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); 8908bailout: 8909 8910 if (fd != -1) 8911 close(fd); 8912 8913 free(patterns); 8914 8915 free(ccb.cdm.matches); 8916 8917 if (retval != 0) 8918 freebusdevlist(devlist); 8919 8920 return (retval); 8921} 8922 8923static void 8924freebusdevlist(struct cam_devlist *devlist) 8925{ 8926 struct cam_devitem *item, *item2; 8927 8928 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) { 8929 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem, 8930 links); 8931 free(item->device_id); 8932 free(item->periph_matches); 8933 free(item); 8934 } 8935} 8936 8937static struct cam_devitem * 8938findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr) 8939{ 8940 struct cam_devitem *item; 8941 8942 STAILQ_FOREACH(item, &devlist->dev_queue, links) { 8943 struct scsi_vpd_id_descriptor *idd; 8944 8945 /* 8946 * XXX KDM look for LUN IDs as well? 8947 */ 8948 idd = scsi_get_devid(item->device_id, 8949 item->device_id_len, 8950 scsi_devid_is_sas_target); 8951 if (idd == NULL) 8952 continue; 8953 8954 if (scsi_8btou64(idd->identifier) == sasaddr) 8955 return (item); 8956 } 8957 8958 return (NULL); 8959} 8960 8961static int 8962smpphylist(struct cam_device *device, int argc, char **argv, 8963 char *combinedopt, int retry_count, int timeout) 8964{ 8965 struct smp_report_general_request *rgrequest = NULL; 8966 struct smp_report_general_response *rgresponse = NULL; 8967 struct smp_discover_request *disrequest = NULL; 8968 struct smp_discover_response *disresponse = NULL; 8969 struct cam_devlist devlist; 8970 union ccb *ccb; 8971 int long_response = 0; 8972 int num_phys = 0; 8973 int quiet = 0; 8974 int retval; 8975 int i, c; 8976 8977 /* 8978 * Note that at the moment we don't support sending SMP CCBs to 8979 * devices that aren't probed by CAM. 8980 */ 8981 ccb = cam_getccb(device); 8982 if (ccb == NULL) { 8983 warnx("%s: error allocating CCB", __func__); 8984 return (1); 8985 } 8986 8987 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 8988 STAILQ_INIT(&devlist.dev_queue); 8989 8990 rgrequest = malloc(sizeof(*rgrequest)); 8991 if (rgrequest == NULL) { 8992 warn("%s: unable to allocate %zd bytes", __func__, 8993 sizeof(*rgrequest)); 8994 retval = 1; 8995 goto bailout; 8996 } 8997 8998 rgresponse = malloc(sizeof(*rgresponse)); 8999 if (rgresponse == NULL) { 9000 warn("%s: unable to allocate %zd bytes", __func__, 9001 sizeof(*rgresponse)); 9002 retval = 1; 9003 goto bailout; 9004 } 9005 9006 while ((c = getopt(argc, argv, combinedopt)) != -1) { 9007 switch (c) { 9008 case 'l': 9009 long_response = 1; 9010 break; 9011 case 'q': 9012 quiet = 1; 9013 break; 9014 default: 9015 break; 9016 } 9017 } 9018 9019 smp_report_general(&ccb->smpio, 9020 retry_count, 9021 /*cbfcnp*/ NULL, 9022 rgrequest, 9023 /*request_len*/ sizeof(*rgrequest), 9024 (uint8_t *)rgresponse, 9025 /*response_len*/ sizeof(*rgresponse), 9026 /*long_response*/ long_response, 9027 timeout); 9028 9029 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 9030 9031 if (((retval = cam_send_ccb(device, ccb)) < 0) 9032 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 9033 const char warnstr[] = "error sending command"; 9034 9035 if (retval < 0) 9036 warn(warnstr); 9037 else 9038 warnx(warnstr); 9039 9040 if (arglist & CAM_ARG_VERBOSE) { 9041 cam_error_print(device, ccb, CAM_ESF_ALL, 9042 CAM_EPF_ALL, stderr); 9043 } 9044 retval = 1; 9045 goto bailout; 9046 } 9047 9048 num_phys = rgresponse->num_phys; 9049 9050 if (num_phys == 0) { 9051 if (quiet == 0) 9052 fprintf(stdout, "%s: No Phys reported\n", __func__); 9053 retval = 1; 9054 goto bailout; 9055 } 9056 9057 devlist.path_id = device->path_id; 9058 9059 retval = buildbusdevlist(&devlist); 9060 if (retval != 0) 9061 goto bailout; 9062 9063 if (quiet == 0) { 9064 fprintf(stdout, "%d PHYs:\n", num_phys); 9065 fprintf(stdout, "PHY Attached SAS Address\n"); 9066 } 9067 9068 disrequest = malloc(sizeof(*disrequest)); 9069 if (disrequest == NULL) { 9070 warn("%s: unable to allocate %zd bytes", __func__, 9071 sizeof(*disrequest)); 9072 retval = 1; 9073 goto bailout; 9074 } 9075 9076 disresponse = malloc(sizeof(*disresponse)); 9077 if (disresponse == NULL) { 9078 warn("%s: unable to allocate %zd bytes", __func__, 9079 sizeof(*disresponse)); 9080 retval = 1; 9081 goto bailout; 9082 } 9083 9084 for (i = 0; i < num_phys; i++) { 9085 struct cam_devitem *item; 9086 struct device_match_result *dev_match; 9087 char vendor[16], product[48], revision[16]; 9088 char tmpstr[256]; 9089 int j; 9090 9091 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 9092 9093 ccb->ccb_h.status = CAM_REQ_INPROG; 9094 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 9095 9096 smp_discover(&ccb->smpio, 9097 retry_count, 9098 /*cbfcnp*/ NULL, 9099 disrequest, 9100 sizeof(*disrequest), 9101 (uint8_t *)disresponse, 9102 sizeof(*disresponse), 9103 long_response, 9104 /*ignore_zone_group*/ 0, 9105 /*phy*/ i, 9106 timeout); 9107 9108 if (((retval = cam_send_ccb(device, ccb)) < 0) 9109 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 9110 && (disresponse->function_result != SMP_FR_PHY_VACANT))) { 9111 const char warnstr[] = "error sending command"; 9112 9113 if (retval < 0) 9114 warn(warnstr); 9115 else 9116 warnx(warnstr); 9117 9118 if (arglist & CAM_ARG_VERBOSE) { 9119 cam_error_print(device, ccb, CAM_ESF_ALL, 9120 CAM_EPF_ALL, stderr); 9121 } 9122 retval = 1; 9123 goto bailout; 9124 } 9125 9126 if (disresponse->function_result == SMP_FR_PHY_VACANT) { 9127 if (quiet == 0) 9128 fprintf(stdout, "%3d <vacant>\n", i); 9129 continue; 9130 } 9131 9132 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) { 9133 item = NULL; 9134 } else { 9135 item = findsasdevice(&devlist, 9136 scsi_8btou64(disresponse->attached_sas_address)); 9137 } 9138 9139 if ((quiet == 0) 9140 || (item != NULL)) { 9141 fprintf(stdout, "%3d 0x%016jx", i, 9142 (uintmax_t)scsi_8btou64( 9143 disresponse->attached_sas_address)); 9144 if (item == NULL) { 9145 fprintf(stdout, "\n"); 9146 continue; 9147 } 9148 } else if (quiet != 0) 9149 continue; 9150 9151 dev_match = &item->dev_match; 9152 9153 if (dev_match->protocol == PROTO_SCSI) { 9154 cam_strvis(vendor, dev_match->inq_data.vendor, 9155 sizeof(dev_match->inq_data.vendor), 9156 sizeof(vendor)); 9157 cam_strvis(product, dev_match->inq_data.product, 9158 sizeof(dev_match->inq_data.product), 9159 sizeof(product)); 9160 cam_strvis(revision, dev_match->inq_data.revision, 9161 sizeof(dev_match->inq_data.revision), 9162 sizeof(revision)); 9163 sprintf(tmpstr, "<%s %s %s>", vendor, product, 9164 revision); 9165 } else if ((dev_match->protocol == PROTO_ATA) 9166 || (dev_match->protocol == PROTO_SATAPM)) { 9167 cam_strvis(product, dev_match->ident_data.model, 9168 sizeof(dev_match->ident_data.model), 9169 sizeof(product)); 9170 cam_strvis(revision, dev_match->ident_data.revision, 9171 sizeof(dev_match->ident_data.revision), 9172 sizeof(revision)); 9173 sprintf(tmpstr, "<%s %s>", product, revision); 9174 } else { 9175 sprintf(tmpstr, "<>"); 9176 } 9177 fprintf(stdout, " %-33s ", tmpstr); 9178 9179 /* 9180 * If we have 0 periphs, that's a bug... 9181 */ 9182 if (item->num_periphs == 0) { 9183 fprintf(stdout, "\n"); 9184 continue; 9185 } 9186 9187 fprintf(stdout, "("); 9188 for (j = 0; j < item->num_periphs; j++) { 9189 if (j > 0) 9190 fprintf(stdout, ","); 9191 9192 fprintf(stdout, "%s%d", 9193 item->periph_matches[j].periph_name, 9194 item->periph_matches[j].unit_number); 9195 9196 } 9197 fprintf(stdout, ")\n"); 9198 } 9199bailout: 9200 if (ccb != NULL) 9201 cam_freeccb(ccb); 9202 9203 free(rgrequest); 9204 9205 free(rgresponse); 9206 9207 free(disrequest); 9208 9209 free(disresponse); 9210 9211 freebusdevlist(&devlist); 9212 9213 return (retval); 9214} 9215 9216static int 9217atapm_proc_resp(struct cam_device *device, union ccb *ccb) 9218{ 9219 uint8_t error = 0, ata_device = 0, status = 0; 9220 uint16_t count = 0; 9221 uint64_t lba = 0; 9222 int retval; 9223 9224 retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device, 9225 &status); 9226 if (retval == 1) { 9227 if (arglist & CAM_ARG_VERBOSE) { 9228 cam_error_print(device, ccb, CAM_ESF_ALL, 9229 CAM_EPF_ALL, stderr); 9230 } 9231 warnx("Can't get ATA command status"); 9232 return (retval); 9233 } 9234 9235 if (status & ATA_STATUS_ERROR) { 9236 cam_error_print(device, ccb, CAM_ESF_ALL, 9237 CAM_EPF_ALL, stderr); 9238 return (1); 9239 } 9240 9241 printf("%s%d: ", device->device_name, device->dev_unit_num); 9242 switch (count) { 9243 case 0x00: 9244 printf("Standby mode\n"); 9245 break; 9246 case 0x01: 9247 printf("Standby_y mode\n"); 9248 break; 9249 case 0x40: 9250 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n"); 9251 break; 9252 case 0x41: 9253 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n"); 9254 break; 9255 case 0x80: 9256 printf("Idle mode\n"); 9257 break; 9258 case 0x81: 9259 printf("Idle_a mode\n"); 9260 break; 9261 case 0x82: 9262 printf("Idle_b mode\n"); 9263 break; 9264 case 0x83: 9265 printf("Idle_c mode\n"); 9266 break; 9267 case 0xff: 9268 printf("Active or Idle mode\n"); 9269 break; 9270 default: 9271 printf("Unknown mode 0x%02x\n", count); 9272 break; 9273 } 9274 9275 return (0); 9276} 9277 9278static int 9279atapm(struct cam_device *device, int argc, char **argv, 9280 char *combinedopt, int retry_count, int timeout) 9281{ 9282 union ccb *ccb; 9283 int retval = 0; 9284 int t = -1; 9285 int c; 9286 u_int8_t ata_flags = 0; 9287 u_char cmd, sc; 9288 9289 ccb = cam_getccb(device); 9290 9291 if (ccb == NULL) { 9292 warnx("%s: error allocating ccb", __func__); 9293 return (1); 9294 } 9295 9296 while ((c = getopt(argc, argv, combinedopt)) != -1) { 9297 switch (c) { 9298 case 't': 9299 t = atoi(optarg); 9300 break; 9301 default: 9302 break; 9303 } 9304 } 9305 if (strcmp(argv[1], "idle") == 0) { 9306 if (t == -1) 9307 cmd = ATA_IDLE_IMMEDIATE; 9308 else 9309 cmd = ATA_IDLE_CMD; 9310 } else if (strcmp(argv[1], "standby") == 0) { 9311 if (t == -1) 9312 cmd = ATA_STANDBY_IMMEDIATE; 9313 else 9314 cmd = ATA_STANDBY_CMD; 9315 } else if (strcmp(argv[1], "powermode") == 0) { 9316 cmd = ATA_CHECK_POWER_MODE; 9317 ata_flags = AP_FLAG_CHK_COND; 9318 t = -1; 9319 } else { 9320 cmd = ATA_SLEEP; 9321 t = -1; 9322 } 9323 9324 if (t < 0) 9325 sc = 0; 9326 else if (t <= (240 * 5)) 9327 sc = (t + 4) / 5; 9328 else if (t <= (252 * 5)) 9329 /* special encoding for 21 minutes */ 9330 sc = 252; 9331 else if (t <= (11 * 30 * 60)) 9332 sc = (t - 1) / (30 * 60) + 241; 9333 else 9334 sc = 253; 9335 9336 retval = ata_do_cmd(device, 9337 ccb, 9338 /*retries*/retry_count, 9339 /*flags*/CAM_DIR_NONE, 9340 /*protocol*/AP_PROTO_NON_DATA, 9341 /*ata_flags*/ata_flags, 9342 /*tag_action*/MSG_SIMPLE_Q_TAG, 9343 /*command*/cmd, 9344 /*features*/0, 9345 /*lba*/0, 9346 /*sector_count*/sc, 9347 /*data_ptr*/NULL, 9348 /*dxfer_len*/0, 9349 /*timeout*/timeout ? timeout : 30 * 1000, 9350 /*force48bit*/0); 9351 9352 cam_freeccb(ccb); 9353 9354 if (retval || cmd != ATA_CHECK_POWER_MODE) 9355 return (retval); 9356 9357 return (atapm_proc_resp(device, ccb)); 9358} 9359 9360static int 9361ataaxm(struct cam_device *device, int argc, char **argv, 9362 char *combinedopt, int retry_count, int timeout) 9363{ 9364 union ccb *ccb; 9365 int retval = 0; 9366 int l = -1; 9367 int c; 9368 u_char cmd, sc; 9369 9370 ccb = cam_getccb(device); 9371 9372 if (ccb == NULL) { 9373 warnx("%s: error allocating ccb", __func__); 9374 return (1); 9375 } 9376 9377 while ((c = getopt(argc, argv, combinedopt)) != -1) { 9378 switch (c) { 9379 case 'l': 9380 l = atoi(optarg); 9381 break; 9382 default: 9383 break; 9384 } 9385 } 9386 sc = 0; 9387 if (strcmp(argv[1], "apm") == 0) { 9388 if (l == -1) 9389 cmd = 0x85; 9390 else { 9391 cmd = 0x05; 9392 sc = l; 9393 } 9394 } else /* aam */ { 9395 if (l == -1) 9396 cmd = 0xC2; 9397 else { 9398 cmd = 0x42; 9399 sc = l; 9400 } 9401 } 9402 9403 retval = ata_do_cmd(device, 9404 ccb, 9405 /*retries*/retry_count, 9406 /*flags*/CAM_DIR_NONE, 9407 /*protocol*/AP_PROTO_NON_DATA, 9408 /*ata_flags*/0, 9409 /*tag_action*/MSG_SIMPLE_Q_TAG, 9410 /*command*/ATA_SETFEATURES, 9411 /*features*/cmd, 9412 /*lba*/0, 9413 /*sector_count*/sc, 9414 /*data_ptr*/NULL, 9415 /*dxfer_len*/0, 9416 /*timeout*/timeout ? timeout : 30 * 1000, 9417 /*force48bit*/0); 9418 9419 cam_freeccb(ccb); 9420 return (retval); 9421} 9422 9423int 9424scsigetopcodes(struct cam_device *device, int opcode_set, int opcode, 9425 int show_sa_errors, int sa_set, int service_action, 9426 int timeout_desc, int task_attr, int retry_count, int timeout, 9427 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr) 9428{ 9429 union ccb *ccb = NULL; 9430 uint8_t *buf = NULL; 9431 uint32_t alloc_len = 0, num_opcodes; 9432 uint32_t valid_len = 0; 9433 uint32_t avail_len = 0; 9434 struct scsi_report_supported_opcodes_all *all_hdr; 9435 struct scsi_report_supported_opcodes_one *one; 9436 int options = 0; 9437 int retval = 0; 9438 9439 /* 9440 * Make it clear that we haven't yet allocated or filled anything. 9441 */ 9442 *fill_len = 0; 9443 *data_ptr = NULL; 9444 9445 ccb = cam_getccb(device); 9446 if (ccb == NULL) { 9447 warnx("couldn't allocate CCB"); 9448 retval = 1; 9449 goto bailout; 9450 } 9451 9452 /* cam_getccb cleans up the header, caller has to zero the payload */ 9453 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 9454 9455 if (opcode_set != 0) { 9456 options |= RSO_OPTIONS_OC; 9457 num_opcodes = 1; 9458 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN; 9459 } else { 9460 num_opcodes = 256; 9461 alloc_len = sizeof(*all_hdr) + (num_opcodes * 9462 sizeof(struct scsi_report_supported_opcodes_descr)); 9463 } 9464 9465 if (timeout_desc != 0) { 9466 options |= RSO_RCTD; 9467 alloc_len += num_opcodes * 9468 sizeof(struct scsi_report_supported_opcodes_timeout); 9469 } 9470 9471 if (sa_set != 0) { 9472 options |= RSO_OPTIONS_OC_SA; 9473 if (show_sa_errors != 0) 9474 options &= ~RSO_OPTIONS_OC; 9475 } 9476 9477retry_alloc: 9478 if (buf != NULL) { 9479 free(buf); 9480 buf = NULL; 9481 } 9482 9483 buf = malloc(alloc_len); 9484 if (buf == NULL) { 9485 warn("Unable to allocate %u bytes", alloc_len); 9486 retval = 1; 9487 goto bailout; 9488 } 9489 bzero(buf, alloc_len); 9490 9491 scsi_report_supported_opcodes(&ccb->csio, 9492 /*retries*/ retry_count, 9493 /*cbfcnp*/ NULL, 9494 /*tag_action*/ task_attr, 9495 /*options*/ options, 9496 /*req_opcode*/ opcode, 9497 /*req_service_action*/ service_action, 9498 /*data_ptr*/ buf, 9499 /*dxfer_len*/ alloc_len, 9500 /*sense_len*/ SSD_FULL_SIZE, 9501 /*timeout*/ timeout ? timeout : 10000); 9502 9503 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 9504 9505 if (retry_count != 0) 9506 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 9507 9508 if (cam_send_ccb(device, ccb) < 0) { 9509 warn("error sending REPORT SUPPORTED OPERATION CODES command"); 9510 retval = 1; 9511 goto bailout; 9512 } 9513 9514 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 9515 if (verbosemode != 0) 9516 cam_error_print(device, ccb, CAM_ESF_ALL, 9517 CAM_EPF_ALL, stderr); 9518 retval = 1; 9519 goto bailout; 9520 } 9521 9522 valid_len = ccb->csio.dxfer_len - ccb->csio.resid; 9523 9524 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL) 9525 && (valid_len >= sizeof(*all_hdr))) { 9526 all_hdr = (struct scsi_report_supported_opcodes_all *)buf; 9527 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr); 9528 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL) 9529 && (valid_len >= sizeof(*one))) { 9530 uint32_t cdb_length; 9531 9532 one = (struct scsi_report_supported_opcodes_one *)buf; 9533 cdb_length = scsi_2btoul(one->cdb_length); 9534 avail_len = sizeof(*one) + cdb_length; 9535 if (one->support & RSO_ONE_CTDP) { 9536 struct scsi_report_supported_opcodes_timeout *td; 9537 9538 td = (struct scsi_report_supported_opcodes_timeout *) 9539 &buf[avail_len]; 9540 if (valid_len >= (avail_len + sizeof(td->length))) { 9541 avail_len += scsi_2btoul(td->length) + 9542 sizeof(td->length); 9543 } else { 9544 avail_len += sizeof(*td); 9545 } 9546 } 9547 } 9548 9549 /* 9550 * avail_len could be zero if we didn't get enough data back from 9551 * thet target to determine 9552 */ 9553 if ((avail_len != 0) 9554 && (avail_len > valid_len)) { 9555 alloc_len = avail_len; 9556 goto retry_alloc; 9557 } 9558 9559 *fill_len = valid_len; 9560 *data_ptr = buf; 9561bailout: 9562 if (retval != 0) 9563 free(buf); 9564 9565 cam_freeccb(ccb); 9566 9567 return (retval); 9568} 9569 9570static int 9571scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set, 9572 int req_sa, uint8_t *buf, uint32_t valid_len) 9573{ 9574 struct scsi_report_supported_opcodes_one *one; 9575 struct scsi_report_supported_opcodes_timeout *td; 9576 uint32_t cdb_len = 0, td_len = 0; 9577 const char *op_desc = NULL; 9578 unsigned int i; 9579 int retval = 0; 9580 9581 one = (struct scsi_report_supported_opcodes_one *)buf; 9582 9583 /* 9584 * If we don't have the full single opcode descriptor, no point in 9585 * continuing. 9586 */ 9587 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one, 9588 cdb_length)) { 9589 warnx("Only %u bytes returned, not enough to verify support", 9590 valid_len); 9591 retval = 1; 9592 goto bailout; 9593 } 9594 9595 op_desc = scsi_op_desc(req_opcode, &device->inq_data); 9596 9597 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN", 9598 req_opcode); 9599 if (sa_set != 0) 9600 printf(", SA 0x%x", req_sa); 9601 printf(": "); 9602 9603 switch (one->support & RSO_ONE_SUP_MASK) { 9604 case RSO_ONE_SUP_UNAVAIL: 9605 printf("No command support information currently available\n"); 9606 break; 9607 case RSO_ONE_SUP_NOT_SUP: 9608 printf("Command not supported\n"); 9609 retval = 1; 9610 goto bailout; 9611 break; /*NOTREACHED*/ 9612 case RSO_ONE_SUP_AVAIL: 9613 printf("Command is supported, complies with a SCSI standard\n"); 9614 break; 9615 case RSO_ONE_SUP_VENDOR: 9616 printf("Command is supported, vendor-specific " 9617 "implementation\n"); 9618 break; 9619 default: 9620 printf("Unknown command support flags 0x%#x\n", 9621 one->support & RSO_ONE_SUP_MASK); 9622 break; 9623 } 9624 9625 /* 9626 * If we don't have the CDB length, it isn't exactly an error, the 9627 * command probably isn't supported. 9628 */ 9629 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one, 9630 cdb_usage)) 9631 goto bailout; 9632 9633 cdb_len = scsi_2btoul(one->cdb_length); 9634 9635 /* 9636 * If our valid data doesn't include the full reported length, 9637 * return. The caller should have detected this and adjusted his 9638 * allocation length to get all of the available data. 9639 */ 9640 if (valid_len < sizeof(*one) + cdb_len) { 9641 retval = 1; 9642 goto bailout; 9643 } 9644 9645 /* 9646 * If all we have is the opcode, there is no point in printing out 9647 * the usage bitmap. 9648 */ 9649 if (cdb_len <= 1) { 9650 retval = 1; 9651 goto bailout; 9652 } 9653 9654 printf("CDB usage bitmap:"); 9655 for (i = 0; i < cdb_len; i++) { 9656 printf(" %02x", one->cdb_usage[i]); 9657 } 9658 printf("\n"); 9659 9660 /* 9661 * If we don't have a timeout descriptor, we're done. 9662 */ 9663 if ((one->support & RSO_ONE_CTDP) == 0) 9664 goto bailout; 9665 9666 /* 9667 * If we don't have enough valid length to include the timeout 9668 * descriptor length, we're done. 9669 */ 9670 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length))) 9671 goto bailout; 9672 9673 td = (struct scsi_report_supported_opcodes_timeout *) 9674 &buf[sizeof(*one) + cdb_len]; 9675 td_len = scsi_2btoul(td->length); 9676 td_len += sizeof(td->length); 9677 9678 /* 9679 * If we don't have the full timeout descriptor, we're done. 9680 */ 9681 if (td_len < sizeof(*td)) 9682 goto bailout; 9683 9684 /* 9685 * If we don't have enough valid length to contain the full timeout 9686 * descriptor, we're done. 9687 */ 9688 if (valid_len < (sizeof(*one) + cdb_len + td_len)) 9689 goto bailout; 9690 9691 printf("Timeout information:\n"); 9692 printf("Command-specific: 0x%02x\n", td->cmd_specific); 9693 printf("Nominal timeout: %u seconds\n", 9694 scsi_4btoul(td->nominal_time)); 9695 printf("Recommended timeout: %u seconds\n", 9696 scsi_4btoul(td->recommended_time)); 9697 9698bailout: 9699 return (retval); 9700} 9701 9702static int 9703scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf, 9704 uint32_t valid_len) 9705{ 9706 struct scsi_report_supported_opcodes_all *hdr; 9707 struct scsi_report_supported_opcodes_descr *desc; 9708 uint32_t avail_len = 0, used_len = 0; 9709 uint8_t *cur_ptr; 9710 int retval = 0; 9711 9712 if (valid_len < sizeof(*hdr)) { 9713 warnx("%s: not enough returned data (%u bytes) opcode list", 9714 __func__, valid_len); 9715 retval = 1; 9716 goto bailout; 9717 } 9718 hdr = (struct scsi_report_supported_opcodes_all *)buf; 9719 avail_len = scsi_4btoul(hdr->length); 9720 avail_len += sizeof(hdr->length); 9721 /* 9722 * Take the lesser of the amount of data the drive claims is 9723 * available, and the amount of data the HBA says was returned. 9724 */ 9725 avail_len = MIN(avail_len, valid_len); 9726 9727 used_len = sizeof(hdr->length); 9728 9729 printf("%-6s %4s %8s ", 9730 "Opcode", "SA", "CDB len" ); 9731 9732 if (td_req != 0) 9733 printf("%5s %6s %6s ", "CS", "Nom", "Rec"); 9734 printf(" Description\n"); 9735 9736 while ((avail_len - used_len) > sizeof(*desc)) { 9737 struct scsi_report_supported_opcodes_timeout *td; 9738 uint32_t td_len; 9739 const char *op_desc = NULL; 9740 9741 cur_ptr = &buf[used_len]; 9742 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr; 9743 9744 op_desc = scsi_op_desc(desc->opcode, &device->inq_data); 9745 if (op_desc == NULL) 9746 op_desc = "UNKNOWN"; 9747 9748 printf("0x%02x %#4x %8u ", desc->opcode, 9749 scsi_2btoul(desc->service_action), 9750 scsi_2btoul(desc->cdb_length)); 9751 9752 used_len += sizeof(*desc); 9753 9754 if ((desc->flags & RSO_CTDP) == 0) { 9755 printf(" %s\n", op_desc); 9756 continue; 9757 } 9758 9759 /* 9760 * If we don't have enough space to fit a timeout 9761 * descriptor, then we're done. 9762 */ 9763 if (avail_len - used_len < sizeof(*td)) { 9764 used_len = avail_len; 9765 printf(" %s\n", op_desc); 9766 continue; 9767 } 9768 cur_ptr = &buf[used_len]; 9769 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr; 9770 td_len = scsi_2btoul(td->length); 9771 td_len += sizeof(td->length); 9772 9773 used_len += td_len; 9774 /* 9775 * If the given timeout descriptor length is less than what 9776 * we understand, skip it. 9777 */ 9778 if (td_len < sizeof(*td)) { 9779 printf(" %s\n", op_desc); 9780 continue; 9781 } 9782 9783 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific, 9784 scsi_4btoul(td->nominal_time), 9785 scsi_4btoul(td->recommended_time), op_desc); 9786 } 9787bailout: 9788 return (retval); 9789} 9790 9791static int 9792scsiopcodes(struct cam_device *device, int argc, char **argv, 9793 char *combinedopt, int task_attr, int retry_count, int timeout, 9794 int verbosemode) 9795{ 9796 int c; 9797 uint32_t opcode = 0, service_action = 0; 9798 int td_set = 0, opcode_set = 0, sa_set = 0; 9799 int show_sa_errors = 1; 9800 uint32_t valid_len = 0; 9801 uint8_t *buf = NULL; 9802 char *endptr; 9803 int retval = 0; 9804 9805 while ((c = getopt(argc, argv, combinedopt)) != -1) { 9806 switch (c) { 9807 case 'N': 9808 show_sa_errors = 0; 9809 break; 9810 case 'o': 9811 opcode = strtoul(optarg, &endptr, 0); 9812 if (*endptr != '\0') { 9813 warnx("Invalid opcode \"%s\", must be a number", 9814 optarg); 9815 retval = 1; 9816 goto bailout; 9817 } 9818 if (opcode > 0xff) { 9819 warnx("Invalid opcode 0x%#x, must be between" 9820 "0 and 0xff inclusive", opcode); 9821 retval = 1; 9822 goto bailout; 9823 } 9824 opcode_set = 1; 9825 break; 9826 case 's': 9827 service_action = strtoul(optarg, &endptr, 0); 9828 if (*endptr != '\0') { 9829 warnx("Invalid service action \"%s\", must " 9830 "be a number", optarg); 9831 retval = 1; 9832 goto bailout; 9833 } 9834 if (service_action > 0xffff) { 9835 warnx("Invalid service action 0x%#x, must " 9836 "be between 0 and 0xffff inclusive", 9837 service_action); 9838 retval = 1; 9839 } 9840 sa_set = 1; 9841 break; 9842 case 'T': 9843 td_set = 1; 9844 break; 9845 default: 9846 break; 9847 } 9848 } 9849 9850 if ((sa_set != 0) 9851 && (opcode_set == 0)) { 9852 warnx("You must specify an opcode with -o if a service " 9853 "action is given"); 9854 retval = 1; 9855 goto bailout; 9856 } 9857 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors, 9858 sa_set, service_action, td_set, task_attr, 9859 retry_count, timeout, verbosemode, &valid_len, 9860 &buf); 9861 if (retval != 0) 9862 goto bailout; 9863 9864 if ((opcode_set != 0) 9865 || (sa_set != 0)) { 9866 retval = scsiprintoneopcode(device, opcode, sa_set, 9867 service_action, buf, valid_len); 9868 } else { 9869 retval = scsiprintopcodes(device, td_set, buf, valid_len); 9870 } 9871 9872bailout: 9873 free(buf); 9874 9875 return (retval); 9876} 9877 9878 9879static int 9880reprobe(struct cam_device *device) 9881{ 9882 union ccb *ccb; 9883 int retval = 0; 9884 9885 ccb = cam_getccb(device); 9886 9887 if (ccb == NULL) { 9888 warnx("%s: error allocating ccb", __func__); 9889 return (1); 9890 } 9891 9892 CCB_CLEAR_ALL_EXCEPT_HDR(ccb); 9893 9894 ccb->ccb_h.func_code = XPT_REPROBE_LUN; 9895 9896 if (cam_send_ccb(device, ccb) < 0) { 9897 warn("error sending XPT_REPROBE_LUN CCB"); 9898 retval = 1; 9899 goto bailout; 9900 } 9901 9902 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 9903 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 9904 retval = 1; 9905 goto bailout; 9906 } 9907 9908bailout: 9909 cam_freeccb(ccb); 9910 9911 return (retval); 9912} 9913 9914void 9915usage(int printlong) 9916{ 9917 9918 fprintf(printlong ? stdout : stderr, 9919"usage: camcontrol <command> [device id][generic args][command args]\n" 9920" camcontrol devlist [-b] [-v]\n" 9921" camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n" 9922" camcontrol tur [dev_id][generic args]\n" 9923" camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n" 9924" camcontrol identify [dev_id][generic args] [-v]\n" 9925" camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n" 9926" camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n" 9927" [-q] [-s] [-l]\n" 9928" camcontrol start [dev_id][generic args]\n" 9929" camcontrol stop [dev_id][generic args]\n" 9930" camcontrol load [dev_id][generic args]\n" 9931" camcontrol eject [dev_id][generic args]\n" 9932" camcontrol reprobe [dev_id][generic args]\n" 9933" camcontrol rescan <all | bus[:target:lun] | dev_id>\n" 9934" camcontrol reset <all | bus[:target:lun] | dev_id>\n" 9935" camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n" 9936" [-q][-s][-S offset][-X]\n" 9937" camcontrol modepage [dev_id][generic args] <-m page | -l>\n" 9938" [-P pagectl][-e | -b][-d]\n" 9939" camcontrol cmd [dev_id][generic args]\n" 9940" <-a cmd [args] | -c cmd [args]>\n" 9941" [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n" 9942" camcontrol smpcmd [dev_id][generic args]\n" 9943" <-r len fmt [args]> <-R len fmt [args]>\n" 9944" camcontrol smprg [dev_id][generic args][-l]\n" 9945" camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n" 9946" [-o operation][-d name][-m rate][-M rate]\n" 9947" [-T pp_timeout][-a enable|disable]\n" 9948" [-A enable|disable][-s enable|disable]\n" 9949" [-S enable|disable]\n" 9950" camcontrol smpphylist [dev_id][generic args][-l][-q]\n" 9951" camcontrol smpmaninfo [dev_id][generic args][-l]\n" 9952" camcontrol debug [-I][-P][-T][-S][-X][-c]\n" 9953" <all|dev_id|bus[:target[:lun]]|off>\n" 9954" camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n" 9955" camcontrol negotiate [dev_id][generic args] [-a][-c]\n" 9956" [-D <enable|disable>][-M mode][-O offset]\n" 9957" [-q][-R syncrate][-v][-T <enable|disable>]\n" 9958" [-U][-W bus_width]\n" 9959" camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n" 9960" camcontrol sanitize [dev_id][generic args]\n" 9961" [-a overwrite|block|crypto|exitfailure]\n" 9962" [-c passes][-I][-P pattern][-q][-U][-r][-w]\n" 9963" [-y]\n" 9964" camcontrol idle [dev_id][generic args][-t time]\n" 9965" camcontrol standby [dev_id][generic args][-t time]\n" 9966" camcontrol sleep [dev_id][generic args]\n" 9967" camcontrol powermode [dev_id][generic args]\n" 9968" camcontrol apm [dev_id][generic args][-l level]\n" 9969" camcontrol aam [dev_id][generic args][-l level]\n" 9970" camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n" 9971" [-s][-y]\n" 9972" camcontrol security [dev_id][generic args]\n" 9973" <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n" 9974" [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n" 9975" [-U <user|master>] [-y]\n" 9976" camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n" 9977" [-q] [-s max_sectors] [-U pwd] [-y]\n" 9978" camcontrol ama [dev_id][generic args] [-f] [-q] [-s max_sectors]\n" 9979" camcontrol persist [dev_id][generic args] <-i action|-o action>\n" 9980" [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n" 9981" [-s scope][-S][-T type][-U]\n" 9982" camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n" 9983" [-a attr_num][-c][-e elem][-F form1,form1]\n" 9984" [-p part][-s start][-T type][-V vol]\n" 9985" camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n" 9986" [-N][-T]\n" 9987" camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n" 9988" [-o rep_opts] [-P print_opts]\n" 9989" camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n" 9990" [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n" 9991" [-S power_src] [-T timer]\n" 9992" camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n" 9993" <-s <-f format -T time | -U >>\n" 9994" camcontrol devtype [dev_id]\n" 9995" camcontrol mmcsdcmd [dev_id] [[-c mmc_opcode] [-a mmc_arg]\n" 9996" [-f mmc_flags] [-l data_len]\n" 9997" [-W [-b data_byte]]] |\n" 9998" [-F frequency] |\n" 9999" [-I]\n" 10000" [-1 | -4]\n" 10001" [-S high|normal]\n" 10002" \n" 10003" camcontrol help\n"); 10004 if (!printlong) 10005 return; 10006 fprintf(stdout, 10007"Specify one of the following options:\n" 10008"devlist list all CAM devices\n" 10009"periphlist list all CAM peripheral drivers attached to a device\n" 10010"tur send a test unit ready to the named device\n" 10011"inquiry send a SCSI inquiry command to the named device\n" 10012"identify send a ATA identify command to the named device\n" 10013"reportluns send a SCSI report luns command to the device\n" 10014"readcap send a SCSI read capacity command to the device\n" 10015"start send a Start Unit command to the device\n" 10016"stop send a Stop Unit command to the device\n" 10017"load send a Start Unit command to the device with the load bit set\n" 10018"eject send a Stop Unit command to the device with the eject bit set\n" 10019"reprobe update capacity information of the given device\n" 10020"rescan rescan all buses, the given bus, bus:target:lun or device\n" 10021"reset reset all buses, the given bus, bus:target:lun or device\n" 10022"defects read the defect list of the specified device\n" 10023"modepage display or edit (-e) the given mode page\n" 10024"cmd send the given SCSI command, may need -i or -o as well\n" 10025"smpcmd send the given SMP command, requires -o and -i\n" 10026"smprg send the SMP Report General command\n" 10027"smppc send the SMP PHY Control command, requires -p\n" 10028"smpphylist display phys attached to a SAS expander\n" 10029"smpmaninfo send the SMP Report Manufacturer Info command\n" 10030"debug turn debugging on/off for a bus, target, or lun, or all devices\n" 10031"tags report or set the number of transaction slots for a device\n" 10032"negotiate report or set device negotiation parameters\n" 10033"format send the SCSI FORMAT UNIT command to the named device\n" 10034"sanitize send the SCSI SANITIZE command to the named device\n" 10035"idle send the ATA IDLE command to the named device\n" 10036"standby send the ATA STANDBY command to the named device\n" 10037"sleep send the ATA SLEEP command to the named device\n" 10038"powermode send the ATA CHECK POWER MODE command to the named device\n" 10039"fwdownload program firmware of the named device with the given image\n" 10040"security report or send ATA security commands to the named device\n" 10041"persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n" 10042"attrib send the SCSI READ or WRITE ATTRIBUTE commands\n" 10043"opcodes send the SCSI REPORT SUPPORTED OPCODES command\n" 10044"zone manage Zoned Block (Shingled) devices\n" 10045"epc send ATA Extended Power Conditions commands\n" 10046"timestamp report or set the device's timestamp\n" 10047"devtype report the type of device\n" 10048"mmcsdcmd send the given MMC command, needs -c and -a as well\n" 10049"help this message\n" 10050"Device Identifiers:\n" 10051"bus:target specify the bus and target, lun defaults to 0\n" 10052"bus:target:lun specify the bus, target and lun\n" 10053"deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n" 10054"Generic arguments:\n" 10055"-v be verbose, print out sense information\n" 10056"-t timeout command timeout in seconds, overrides default timeout\n" 10057"-n dev_name specify device name, e.g. \"da\", \"cd\"\n" 10058"-u unit specify unit number, e.g. \"0\", \"5\"\n" 10059"-E have the kernel attempt to perform SCSI error recovery\n" 10060"-C count specify the SCSI command retry count (needs -E to work)\n" 10061"-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n" 10062"modepage arguments:\n" 10063"-l list all available mode pages\n" 10064"-m page specify the mode page to view or edit\n" 10065"-e edit the specified mode page\n" 10066"-b force view to binary mode\n" 10067"-d disable block descriptors for mode sense\n" 10068"-P pgctl page control field 0-3\n" 10069"defects arguments:\n" 10070"-f format specify defect list format (block, bfi or phys)\n" 10071"-G get the grown defect list\n" 10072"-P get the permanent defect list\n" 10073"inquiry arguments:\n" 10074"-D get the standard inquiry data\n" 10075"-S get the serial number\n" 10076"-R get the transfer rate, etc.\n" 10077"reportluns arguments:\n" 10078"-c only report a count of available LUNs\n" 10079"-l only print out luns, and not a count\n" 10080"-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n" 10081"readcap arguments\n" 10082"-b only report the blocksize\n" 10083"-h human readable device size, base 2\n" 10084"-H human readable device size, base 10\n" 10085"-N print the number of blocks instead of last block\n" 10086"-q quiet, print numbers only\n" 10087"-s only report the last block/device size\n" 10088"cmd arguments:\n" 10089"-c cdb [args] specify the SCSI CDB\n" 10090"-i len fmt specify input data and input data format\n" 10091"-o len fmt [args] specify output data and output data fmt\n" 10092"smpcmd arguments:\n" 10093"-r len fmt [args] specify the SMP command to be sent\n" 10094"-R len fmt [args] specify SMP response format\n" 10095"smprg arguments:\n" 10096"-l specify the long response format\n" 10097"smppc arguments:\n" 10098"-p phy specify the PHY to operate on\n" 10099"-l specify the long request/response format\n" 10100"-o operation specify the phy control operation\n" 10101"-d name set the attached device name\n" 10102"-m rate set the minimum physical link rate\n" 10103"-M rate set the maximum physical link rate\n" 10104"-T pp_timeout set the partial pathway timeout value\n" 10105"-a enable|disable enable or disable SATA slumber\n" 10106"-A enable|disable enable or disable SATA partial phy power\n" 10107"-s enable|disable enable or disable SAS slumber\n" 10108"-S enable|disable enable or disable SAS partial phy power\n" 10109"smpphylist arguments:\n" 10110"-l specify the long response format\n" 10111"-q only print phys with attached devices\n" 10112"smpmaninfo arguments:\n" 10113"-l specify the long response format\n" 10114"debug arguments:\n" 10115"-I CAM_DEBUG_INFO -- scsi commands, errors, data\n" 10116"-T CAM_DEBUG_TRACE -- routine flow tracking\n" 10117"-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n" 10118"-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n" 10119"tags arguments:\n" 10120"-N tags specify the number of tags to use for this device\n" 10121"-q be quiet, don't report the number of tags\n" 10122"-v report a number of tag-related parameters\n" 10123"negotiate arguments:\n" 10124"-a send a test unit ready after negotiation\n" 10125"-c report/set current negotiation settings\n" 10126"-D <arg> \"enable\" or \"disable\" disconnection\n" 10127"-M mode set ATA mode\n" 10128"-O offset set command delay offset\n" 10129"-q be quiet, don't report anything\n" 10130"-R syncrate synchronization rate in MHz\n" 10131"-T <arg> \"enable\" or \"disable\" tagged queueing\n" 10132"-U report/set user negotiation settings\n" 10133"-W bus_width set the bus width in bits (8, 16 or 32)\n" 10134"-v also print a Path Inquiry CCB for the controller\n" 10135"format arguments:\n" 10136"-q be quiet, don't print status messages\n" 10137"-r run in report only mode\n" 10138"-w don't send immediate format command\n" 10139"-y don't ask any questions\n" 10140"sanitize arguments:\n" 10141"-a operation operation mode: overwrite, block, crypto or exitfailure\n" 10142"-c passes overwrite passes to perform (1 to 31)\n" 10143"-I invert overwrite pattern after each pass\n" 10144"-P pattern path to overwrite pattern file\n" 10145"-q be quiet, don't print status messages\n" 10146"-r run in report only mode\n" 10147"-U run operation in unrestricted completion exit mode\n" 10148"-w don't send immediate sanitize command\n" 10149"-y don't ask any questions\n" 10150"idle/standby arguments:\n" 10151"-t <arg> number of seconds before respective state.\n" 10152"fwdownload arguments:\n" 10153"-f fw_image path to firmware image file\n" 10154"-q don't print informational messages, only errors\n" 10155"-s run in simulation mode\n" 10156"-v print info for every firmware segment sent to device\n" 10157"-y don't ask any questions\n" 10158"security arguments:\n" 10159"-d pwd disable security using the given password for the selected\n" 10160" user\n" 10161"-e pwd erase the device using the given pwd for the selected user\n" 10162"-f freeze the security configuration of the specified device\n" 10163"-h pwd enhanced erase the device using the given pwd for the\n" 10164" selected user\n" 10165"-k pwd unlock the device using the given pwd for the selected\n" 10166" user\n" 10167"-l <high|maximum> specifies which security level to set: high or maximum\n" 10168"-q be quiet, do not print any status messages\n" 10169"-s pwd password the device (enable security) using the given\n" 10170" pwd for the selected user\n" 10171"-T timeout overrides the timeout (seconds) used for erase operation\n" 10172"-U <user|master> specifies which user to set: user or master\n" 10173"-y don't ask any questions\n" 10174"hpa arguments:\n" 10175"-f freeze the HPA configuration of the device\n" 10176"-l lock the HPA configuration of the device\n" 10177"-P make the HPA max sectors persist\n" 10178"-p pwd Set the HPA configuration password required for unlock\n" 10179" calls\n" 10180"-q be quiet, do not print any status messages\n" 10181"-s sectors configures the maximum user accessible sectors of the\n" 10182" device\n" 10183"-U pwd unlock the HPA configuration of the device\n" 10184"-y don't ask any questions\n" 10185"ama arguments:\n" 10186"-f freeze the AMA configuration of the device\n" 10187"-q be quiet, do not print any status messages\n" 10188"-s sectors configures the maximum user accessible sectors of the\n" 10189" device\n" 10190"persist arguments:\n" 10191"-i action specify read_keys, read_reservation, report_cap, or\n" 10192" read_full_status\n" 10193"-o action specify register, register_ignore, reserve, release,\n" 10194" clear, preempt, preempt_abort, register_move, replace_lost\n" 10195"-a set the All Target Ports (ALL_TG_PT) bit\n" 10196"-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n" 10197"-k key specify the Reservation Key\n" 10198"-K sa_key specify the Service Action Reservation Key\n" 10199"-p set the Activate Persist Through Power Loss bit\n" 10200"-R rtp specify the Relative Target Port\n" 10201"-s scope specify the scope: lun, extent, element or a number\n" 10202"-S specify Transport ID for register, requires -I\n" 10203"-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n" 10204" ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n" 10205"-U unregister the current initiator for register_move\n" 10206"attrib arguments:\n" 10207"-r action specify attr_values, attr_list, lv_list, part_list, or\n" 10208" supp_attr\n" 10209"-w attr specify an attribute to write, one -w argument per attr\n" 10210"-a attr_num only display this attribute number\n" 10211"-c get cached attributes\n" 10212"-e elem_addr request attributes for the given element in a changer\n" 10213"-F form1,form2 output format, comma separated list: text_esc, text_raw,\n" 10214" nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n" 10215" field_none, field_desc, field_num, field_size, field_rw\n" 10216"-p partition request attributes for the given partition\n" 10217"-s start_attr request attributes starting at the given number\n" 10218"-T elem_type specify the element type (used with -e)\n" 10219"-V logical_vol specify the logical volume ID\n" 10220"opcodes arguments:\n" 10221"-o opcode specify the individual opcode to list\n" 10222"-s service_action specify the service action for the opcode\n" 10223"-N do not return SCSI error for unsupported SA\n" 10224"-T request nominal and recommended timeout values\n" 10225"zone arguments:\n" 10226"-c cmd required: rz, open, close, finish, or rwp\n" 10227"-a apply the action to all zones\n" 10228"-l LBA specify the zone starting LBA\n" 10229"-o rep_opts report zones options: all, empty, imp_open, exp_open,\n" 10230" closed, full, ro, offline, reset, nonseq, nonwp\n" 10231"-P print_opt report zones printing: normal, summary, script\n" 10232"epc arguments:\n" 10233"-c cmd required: restore, goto, timer, state, enable, disable,\n" 10234" source, status, list\n" 10235"-d disable power mode (timer, state)\n" 10236"-D delayed entry (goto)\n" 10237"-e enable power mode (timer, state)\n" 10238"-H hold power mode (goto)\n" 10239"-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n" 10240" state, goto)\n" 10241"-P only display power mode (status)\n" 10242"-r rst_src restore settings from: default, saved (restore)\n" 10243"-s save mode (timer, state, restore)\n" 10244"-S power_src set power source: battery, nonbattery (source)\n" 10245"-T timer set timer, seconds, .1 sec resolution (timer)\n" 10246"timestamp arguments:\n" 10247"-r report the timestamp of the device\n" 10248"-f format report the timestamp of the device with the given\n" 10249" strftime(3) format string\n" 10250"-m report the timestamp of the device as milliseconds since\n" 10251" January 1st, 1970\n" 10252"-U report the time with UTC instead of the local time zone\n" 10253"-s set the timestamp of the device\n" 10254"-f format the format of the time string passed into strptime(3)\n" 10255"-T time the time value passed into strptime(3)\n" 10256"-U set the timestamp of the device to UTC time\n" 10257"mmcsdcmd arguments:\n" 10258"-c mmc_cmd MMC command to send to the card\n" 10259"-a mmc_arg Argument for the MMC command\n" 10260"-f mmc_flag Flags to set for the MMC command\n" 10261"-l data_len Expect data_len bytes of data in reply and display them\n" 10262"-W Fill the data buffer before invoking the MMC command\n" 10263"-b data_byte One byte of data to fill the data buffer with\n" 10264"-F frequency Operating frequency to set on the controller\n" 10265"-4 Set bus width to 4 bit\n" 10266"-1 Set bus width to 8 bit\n" 10267"-S high | std Set high-speed or standard timing\n" 10268"-I Display various card and host controller information\n" 10269); 10270} 10271 10272int 10273main(int argc, char **argv) 10274{ 10275 int c; 10276 char *device = NULL; 10277 int unit = 0; 10278 struct cam_device *cam_dev = NULL; 10279 int timeout = 0, retry_count = 1; 10280 camcontrol_optret optreturn; 10281 char *tstr; 10282 const char *mainopt = "C:En:Q:t:u:v"; 10283 const char *subopt = NULL; 10284 char combinedopt[256]; 10285 int error = 0, optstart = 2; 10286 int task_attr = MSG_SIMPLE_Q_TAG; 10287 int devopen = 1; 10288 path_id_t bus; 10289 target_id_t target; 10290 lun_id_t lun; 10291 10292 cmdlist = CAM_CMD_NONE; 10293 arglist = CAM_ARG_NONE; 10294 10295 if (argc < 2) { 10296 usage(0); 10297 exit(1); 10298 } 10299 10300 /* 10301 * Get the base option. 10302 */ 10303 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt); 10304 10305 if (optreturn == CC_OR_AMBIGUOUS) { 10306 warnx("ambiguous option %s", argv[1]); 10307 usage(0); 10308 exit(1); 10309 } else if (optreturn == CC_OR_NOT_FOUND) { 10310 warnx("option %s not found", argv[1]); 10311 usage(0); 10312 exit(1); 10313 } 10314 10315 /* 10316 * Ahh, getopt(3) is a pain. 10317 * 10318 * This is a gross hack. There really aren't many other good 10319 * options (excuse the pun) for parsing options in a situation like 10320 * this. getopt is kinda braindead, so you end up having to run 10321 * through the options twice, and give each invocation of getopt 10322 * the option string for the other invocation. 10323 * 10324 * You would think that you could just have two groups of options. 10325 * The first group would get parsed by the first invocation of 10326 * getopt, and the second group would get parsed by the second 10327 * invocation of getopt. It doesn't quite work out that way. When 10328 * the first invocation of getopt finishes, it leaves optind pointing 10329 * to the argument _after_ the first argument in the second group. 10330 * So when the second invocation of getopt comes around, it doesn't 10331 * recognize the first argument it gets and then bails out. 10332 * 10333 * A nice alternative would be to have a flag for getopt that says 10334 * "just keep parsing arguments even when you encounter an unknown 10335 * argument", but there isn't one. So there's no real clean way to 10336 * easily parse two sets of arguments without having one invocation 10337 * of getopt know about the other. 10338 * 10339 * Without this hack, the first invocation of getopt would work as 10340 * long as the generic arguments are first, but the second invocation 10341 * (in the subfunction) would fail in one of two ways. In the case 10342 * where you don't set optreset, it would fail because optind may be 10343 * pointing to the argument after the one it should be pointing at. 10344 * In the case where you do set optreset, and reset optind, it would 10345 * fail because getopt would run into the first set of options, which 10346 * it doesn't understand. 10347 * 10348 * All of this would "sort of" work if you could somehow figure out 10349 * whether optind had been incremented one option too far. The 10350 * mechanics of that, however, are more daunting than just giving 10351 * both invocations all of the expect options for either invocation. 10352 * 10353 * Needless to say, I wouldn't mind if someone invented a better 10354 * (non-GPL!) command line parsing interface than getopt. I 10355 * wouldn't mind if someone added more knobs to getopt to make it 10356 * work better. Who knows, I may talk myself into doing it someday, 10357 * if the standards weenies let me. As it is, it just leads to 10358 * hackery like this and causes people to avoid it in some cases. 10359 * 10360 * KDM, September 8th, 1998 10361 */ 10362 if (subopt != NULL) 10363 sprintf(combinedopt, "%s%s", mainopt, subopt); 10364 else 10365 sprintf(combinedopt, "%s", mainopt); 10366 10367 /* 10368 * For these options we do not parse optional device arguments and 10369 * we do not open a passthrough device. 10370 */ 10371 if ((cmdlist == CAM_CMD_RESCAN) 10372 || (cmdlist == CAM_CMD_RESET) 10373 || (cmdlist == CAM_CMD_DEVTREE) 10374 || (cmdlist == CAM_CMD_USAGE) 10375 || (cmdlist == CAM_CMD_DEBUG)) 10376 devopen = 0; 10377 10378 if ((devopen == 1) 10379 && (argc > 2 && argv[2][0] != '-')) { 10380 char name[30]; 10381 int rv; 10382 10383 if (isdigit(argv[2][0])) { 10384 /* device specified as bus:target[:lun] */ 10385 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist); 10386 if (rv < 2) 10387 errx(1, "numeric device specification must " 10388 "be either bus:target, or " 10389 "bus:target:lun"); 10390 /* default to 0 if lun was not specified */ 10391 if ((arglist & CAM_ARG_LUN) == 0) { 10392 lun = 0; 10393 arglist |= CAM_ARG_LUN; 10394 } 10395 optstart++; 10396 } else { 10397 if (cam_get_device(argv[2], name, sizeof name, &unit) 10398 == -1) 10399 errx(1, "%s", cam_errbuf); 10400 device = strdup(name); 10401 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT; 10402 optstart++; 10403 } 10404 } 10405 /* 10406 * Start getopt processing at argv[2/3], since we've already 10407 * accepted argv[1..2] as the command name, and as a possible 10408 * device name. 10409 */ 10410 optind = optstart; 10411 10412 /* 10413 * Now we run through the argument list looking for generic 10414 * options, and ignoring options that possibly belong to 10415 * subfunctions. 10416 */ 10417 while ((c = getopt(argc, argv, combinedopt))!= -1){ 10418 switch(c) { 10419 case 'C': 10420 retry_count = strtol(optarg, NULL, 0); 10421 if (retry_count < 0) 10422 errx(1, "retry count %d is < 0", 10423 retry_count); 10424 arglist |= CAM_ARG_RETRIES; 10425 break; 10426 case 'E': 10427 arglist |= CAM_ARG_ERR_RECOVER; 10428 break; 10429 case 'n': 10430 arglist |= CAM_ARG_DEVICE; 10431 tstr = optarg; 10432 while (isspace(*tstr) && (*tstr != '\0')) 10433 tstr++; 10434 device = (char *)strdup(tstr); 10435 break; 10436 case 'Q': { 10437 char *endptr; 10438 int table_entry = 0; 10439 10440 tstr = optarg; 10441 while (isspace(*tstr) && (*tstr != '\0')) 10442 tstr++; 10443 if (isdigit(*tstr)) { 10444 task_attr = strtol(tstr, &endptr, 0); 10445 if (*endptr != '\0') { 10446 errx(1, "Invalid queue option " 10447 "%s", tstr); 10448 } 10449 } else { 10450 size_t table_size; 10451 scsi_nv_status status; 10452 10453 table_size = sizeof(task_attrs) / 10454 sizeof(task_attrs[0]); 10455 status = scsi_get_nv(task_attrs, 10456 table_size, tstr, &table_entry, 10457 SCSI_NV_FLAG_IG_CASE); 10458 if (status == SCSI_NV_FOUND) 10459 task_attr = task_attrs[ 10460 table_entry].value; 10461 else { 10462 errx(1, "%s option %s", 10463 (status == SCSI_NV_AMBIGUOUS)? 10464 "ambiguous" : "invalid", 10465 tstr); 10466 } 10467 } 10468 break; 10469 } 10470 case 't': 10471 timeout = strtol(optarg, NULL, 0); 10472 if (timeout < 0) 10473 errx(1, "invalid timeout %d", timeout); 10474 /* Convert the timeout from seconds to ms */ 10475 timeout *= 1000; 10476 arglist |= CAM_ARG_TIMEOUT; 10477 break; 10478 case 'u': 10479 arglist |= CAM_ARG_UNIT; 10480 unit = strtol(optarg, NULL, 0); 10481 break; 10482 case 'v': 10483 arglist |= CAM_ARG_VERBOSE; 10484 break; 10485 default: 10486 break; 10487 } 10488 } 10489 10490 /* 10491 * For most commands we'll want to open the passthrough device 10492 * associated with the specified device. In the case of the rescan 10493 * commands, we don't use a passthrough device at all, just the 10494 * transport layer device. 10495 */ 10496 if (devopen == 1) { 10497 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0) 10498 && (((arglist & CAM_ARG_DEVICE) == 0) 10499 || ((arglist & CAM_ARG_UNIT) == 0))) { 10500 errx(1, "subcommand \"%s\" requires a valid device " 10501 "identifier", argv[1]); 10502 } 10503 10504 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))? 10505 cam_open_btl(bus, target, lun, O_RDWR, NULL) : 10506 cam_open_spec_device(device,unit,O_RDWR,NULL))) 10507 == NULL) 10508 errx(1,"%s", cam_errbuf); 10509 } 10510 10511 /* 10512 * Reset optind to 2, and reset getopt, so these routines can parse 10513 * the arguments again. 10514 */ 10515 optind = optstart; 10516 optreset = 1; 10517 10518 switch(cmdlist) { 10519 case CAM_CMD_DEVLIST: 10520 error = getdevlist(cam_dev); 10521 break; 10522 case CAM_CMD_HPA: 10523 error = atahpa(cam_dev, retry_count, timeout, 10524 argc, argv, combinedopt); 10525 break; 10526 case CAM_CMD_AMA: 10527 error = ataama(cam_dev, retry_count, timeout, 10528 argc, argv, combinedopt); 10529 break; 10530 case CAM_CMD_DEVTREE: 10531 error = getdevtree(argc, argv, combinedopt); 10532 break; 10533 case CAM_CMD_DEVTYPE: 10534 error = getdevtype(cam_dev); 10535 break; 10536 case CAM_CMD_TUR: 10537 error = testunitready(cam_dev, task_attr, retry_count, 10538 timeout, 0); 10539 break; 10540 case CAM_CMD_INQUIRY: 10541 error = scsidoinquiry(cam_dev, argc, argv, combinedopt, 10542 task_attr, retry_count, timeout); 10543 break; 10544 case CAM_CMD_IDENTIFY: 10545 error = identify(cam_dev, retry_count, timeout); 10546 break; 10547 case CAM_CMD_STARTSTOP: 10548 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT, 10549 arglist & CAM_ARG_EJECT, task_attr, 10550 retry_count, timeout); 10551 break; 10552 case CAM_CMD_RESCAN: 10553 error = dorescan_or_reset(argc, argv, 1); 10554 break; 10555 case CAM_CMD_RESET: 10556 error = dorescan_or_reset(argc, argv, 0); 10557 break; 10558 case CAM_CMD_READ_DEFECTS: 10559 error = readdefects(cam_dev, argc, argv, combinedopt, 10560 task_attr, retry_count, timeout); 10561 break; 10562 case CAM_CMD_MODE_PAGE: 10563 modepage(cam_dev, argc, argv, combinedopt, 10564 task_attr, retry_count, timeout); 10565 break; 10566 case CAM_CMD_SCSI_CMD: 10567 error = scsicmd(cam_dev, argc, argv, combinedopt, 10568 task_attr, retry_count, timeout); 10569 break; 10570 case CAM_CMD_MMCSD_CMD: 10571 error = mmcsdcmd(cam_dev, argc, argv, combinedopt, 10572 retry_count, timeout); 10573 break; 10574 case CAM_CMD_SMP_CMD: 10575 error = smpcmd(cam_dev, argc, argv, combinedopt, 10576 retry_count, timeout); 10577 break; 10578 case CAM_CMD_SMP_RG: 10579 error = smpreportgeneral(cam_dev, argc, argv, 10580 combinedopt, retry_count, 10581 timeout); 10582 break; 10583 case CAM_CMD_SMP_PC: 10584 error = smpphycontrol(cam_dev, argc, argv, combinedopt, 10585 retry_count, timeout); 10586 break; 10587 case CAM_CMD_SMP_PHYLIST: 10588 error = smpphylist(cam_dev, argc, argv, combinedopt, 10589 retry_count, timeout); 10590 break; 10591 case CAM_CMD_SMP_MANINFO: 10592 error = smpmaninfo(cam_dev, argc, argv, combinedopt, 10593 retry_count, timeout); 10594 break; 10595 case CAM_CMD_DEBUG: 10596 error = camdebug(argc, argv, combinedopt); 10597 break; 10598 case CAM_CMD_TAG: 10599 error = tagcontrol(cam_dev, argc, argv, combinedopt); 10600 break; 10601 case CAM_CMD_RATE: 10602 error = ratecontrol(cam_dev, task_attr, retry_count, 10603 timeout, argc, argv, combinedopt); 10604 break; 10605 case CAM_CMD_FORMAT: 10606 error = scsiformat(cam_dev, argc, argv, 10607 combinedopt, task_attr, retry_count, 10608 timeout); 10609 break; 10610 case CAM_CMD_REPORTLUNS: 10611 error = scsireportluns(cam_dev, argc, argv, 10612 combinedopt, task_attr, 10613 retry_count, timeout); 10614 break; 10615 case CAM_CMD_READCAP: 10616 error = scsireadcapacity(cam_dev, argc, argv, 10617 combinedopt, task_attr, 10618 retry_count, timeout); 10619 break; 10620 case CAM_CMD_IDLE: 10621 case CAM_CMD_STANDBY: 10622 case CAM_CMD_SLEEP: 10623 case CAM_CMD_POWER_MODE: 10624 error = atapm(cam_dev, argc, argv, 10625 combinedopt, retry_count, timeout); 10626 break; 10627 case CAM_CMD_APM: 10628 case CAM_CMD_AAM: 10629 error = ataaxm(cam_dev, argc, argv, 10630 combinedopt, retry_count, timeout); 10631 break; 10632 case CAM_CMD_SECURITY: 10633 error = atasecurity(cam_dev, retry_count, timeout, 10634 argc, argv, combinedopt); 10635 break; 10636 case CAM_CMD_DOWNLOAD_FW: 10637 error = fwdownload(cam_dev, argc, argv, combinedopt, 10638 arglist & CAM_ARG_VERBOSE, task_attr, retry_count, 10639 timeout); 10640 break; 10641 case CAM_CMD_SANITIZE: 10642 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr, 10643 retry_count, timeout); 10644 break; 10645 case CAM_CMD_PERSIST: 10646 error = scsipersist(cam_dev, argc, argv, combinedopt, 10647 task_attr, retry_count, timeout, 10648 arglist & CAM_ARG_VERBOSE, 10649 arglist & CAM_ARG_ERR_RECOVER); 10650 break; 10651 case CAM_CMD_ATTRIB: 10652 error = scsiattrib(cam_dev, argc, argv, combinedopt, 10653 task_attr, retry_count, timeout, 10654 arglist & CAM_ARG_VERBOSE, 10655 arglist & CAM_ARG_ERR_RECOVER); 10656 break; 10657 case CAM_CMD_OPCODES: 10658 error = scsiopcodes(cam_dev, argc, argv, combinedopt, 10659 task_attr, retry_count, timeout, 10660 arglist & CAM_ARG_VERBOSE); 10661 break; 10662 case CAM_CMD_REPROBE: 10663 error = reprobe(cam_dev); 10664 break; 10665 case CAM_CMD_ZONE: 10666 error = zone(cam_dev, argc, argv, combinedopt, 10667 task_attr, retry_count, timeout, 10668 arglist & CAM_ARG_VERBOSE); 10669 break; 10670 case CAM_CMD_EPC: 10671 error = epc(cam_dev, argc, argv, combinedopt, 10672 retry_count, timeout, arglist & CAM_ARG_VERBOSE); 10673 break; 10674 case CAM_CMD_TIMESTAMP: 10675 error = timestamp(cam_dev, argc, argv, combinedopt, 10676 task_attr, retry_count, timeout, 10677 arglist & CAM_ARG_VERBOSE); 10678 break; 10679 case CAM_CMD_USAGE: 10680 usage(1); 10681 break; 10682 default: 10683 usage(0); 10684 error = 1; 10685 break; 10686 } 10687 10688 if (cam_dev != NULL) 10689 cam_close_device(cam_dev); 10690 10691 exit(error); 10692} 10693