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 #ifndef MINIMALISTIC 50 #include <limits.h> 51 #include <inttypes.h> 52 #endif 53 54 #include <cam/cam.h> 55 #include <cam/cam_debug.h> 56 #include <cam/cam_ccb.h> 57 #include <cam/scsi/scsi_all.h> 58 #include <cam/scsi/scsi_da.h> 59 #include <cam/scsi/scsi_pass.h> 60 #include <cam/scsi/scsi_message.h> 61 #include <cam/scsi/smp_all.h> 62 #include <cam/ata/ata_all.h> 63 #include <camlib.h> 64 #include "camcontrol.h" 65 66 typedef enum { 67 CAM_CMD_NONE = 0x00000000, 68 CAM_CMD_DEVLIST = 0x00000001, 69 CAM_CMD_TUR = 0x00000002, 70 CAM_CMD_INQUIRY = 0x00000003, 71 CAM_CMD_STARTSTOP = 0x00000004, 72 CAM_CMD_RESCAN = 0x00000005, 73 CAM_CMD_READ_DEFECTS = 0x00000006, 74 CAM_CMD_MODE_PAGE = 0x00000007, 75 CAM_CMD_SCSI_CMD = 0x00000008, 76 CAM_CMD_DEVTREE = 0x00000009, 77 CAM_CMD_USAGE = 0x0000000a, 78 CAM_CMD_DEBUG = 0x0000000b, 79 CAM_CMD_RESET = 0x0000000c, 80 CAM_CMD_FORMAT = 0x0000000d, 81 CAM_CMD_TAG = 0x0000000e, 82 CAM_CMD_RATE = 0x0000000f, 83 CAM_CMD_DETACH = 0x00000010, 84 CAM_CMD_REPORTLUNS = 0x00000011, 85 CAM_CMD_READCAP = 0x00000012, 86 CAM_CMD_IDENTIFY = 0x00000013, 87 CAM_CMD_IDLE = 0x00000014, 88 CAM_CMD_STANDBY = 0x00000015, 89 CAM_CMD_SLEEP = 0x00000016, 90 CAM_CMD_SMP_CMD = 0x00000017, 91 CAM_CMD_SMP_RG = 0x00000018, 92 CAM_CMD_SMP_PC = 0x00000019, 93 CAM_CMD_SMP_PHYLIST = 0x0000001a, 94 CAM_CMD_SMP_MANINFO = 0x0000001b, 95 CAM_CMD_DOWNLOAD_FW = 0x0000001c, 96 CAM_CMD_SECURITY = 0x0000001d, 97 CAM_CMD_HPA = 0x0000001e, 98 CAM_CMD_SANITIZE = 0x0000001f, 99 CAM_CMD_PERSIST = 0x00000020, 100 CAM_CMD_APM = 0x00000021, 101 CAM_CMD_AAM = 0x00000022 102 } cam_cmdmask; 103 104 typedef enum { 105 CAM_ARG_NONE = 0x00000000, 106 CAM_ARG_VERBOSE = 0x00000001, 107 CAM_ARG_DEVICE = 0x00000002, 108 CAM_ARG_BUS = 0x00000004, 109 CAM_ARG_TARGET = 0x00000008, 110 CAM_ARG_LUN = 0x00000010, 111 CAM_ARG_EJECT = 0x00000020, 112 CAM_ARG_UNIT = 0x00000040, 113 CAM_ARG_FORMAT_BLOCK = 0x00000080, 114 CAM_ARG_FORMAT_BFI = 0x00000100, 115 CAM_ARG_FORMAT_PHYS = 0x00000200, 116 CAM_ARG_PLIST = 0x00000400, 117 CAM_ARG_GLIST = 0x00000800, 118 CAM_ARG_GET_SERIAL = 0x00001000, 119 CAM_ARG_GET_STDINQ = 0x00002000, 120 CAM_ARG_GET_XFERRATE = 0x00004000, 121 CAM_ARG_INQ_MASK = 0x00007000, 122 CAM_ARG_MODE_EDIT = 0x00008000, 123 CAM_ARG_PAGE_CNTL = 0x00010000, 124 CAM_ARG_TIMEOUT = 0x00020000, 125 CAM_ARG_CMD_IN = 0x00040000, 126 CAM_ARG_CMD_OUT = 0x00080000, 127 CAM_ARG_DBD = 0x00100000, 128 CAM_ARG_ERR_RECOVER = 0x00200000, 129 CAM_ARG_RETRIES = 0x00400000, 130 CAM_ARG_START_UNIT = 0x00800000, 131 CAM_ARG_DEBUG_INFO = 0x01000000, 132 CAM_ARG_DEBUG_TRACE = 0x02000000, 133 CAM_ARG_DEBUG_SUBTRACE = 0x04000000, 134 CAM_ARG_DEBUG_CDB = 0x08000000, 135 CAM_ARG_DEBUG_XPT = 0x10000000, 136 CAM_ARG_DEBUG_PERIPH = 0x20000000, 137 CAM_ARG_DEBUG_PROBE = 0x40000000, 138 } cam_argmask; 139 140 struct camcontrol_opts { 141 const char *optname; 142 uint32_t cmdnum; 143 cam_argmask argnum; 144 const char *subopt; 145 }; 146 147 #ifndef MINIMALISTIC 148 struct ata_res_pass16 { 149 u_int16_t reserved[5]; 150 u_int8_t flags; 151 u_int8_t error; 152 u_int8_t sector_count_exp; 153 u_int8_t sector_count; 154 u_int8_t lba_low_exp; 155 u_int8_t lba_low; 156 u_int8_t lba_mid_exp; 157 u_int8_t lba_mid; 158 u_int8_t lba_high_exp; 159 u_int8_t lba_high; 160 u_int8_t device; 161 u_int8_t status; 162 }; 163 164 struct ata_set_max_pwd 165 { 166 u_int16_t reserved1; 167 u_int8_t password[32]; 168 u_int16_t reserved2[239]; 169 }; 170 171 static const char scsicmd_opts[] = "a:c:dfi:o:r"; 172 static const char readdefect_opts[] = "f:GPqsS:X"; 173 static const char negotiate_opts[] = "acD:M:O:qR:T:UW:"; 174 static const char smprg_opts[] = "l"; 175 static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:"; 176 static const char smpphylist_opts[] = "lq"; 177 static char pwd_opt; 178 #endif 179 180 static struct camcontrol_opts option_table[] = { 181 #ifndef MINIMALISTIC 182 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL}, 183 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"}, 184 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL}, 185 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL}, 186 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL}, 187 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL}, 188 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL}, 189 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"}, 190 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"}, 191 #endif /* MINIMALISTIC */ 192 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL}, 193 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL}, 194 #ifndef MINIMALISTIC 195 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts}, 196 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts}, 197 {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"}, 198 {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts}, 199 {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts}, 200 {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts}, 201 {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts}, 202 {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts}, 203 {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts}, 204 {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"}, 205 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts}, 206 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts}, 207 #endif /* MINIMALISTIC */ 208 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"}, 209 #ifndef MINIMALISTIC 210 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL}, 211 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"}, 212 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"}, 213 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, 214 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, 215 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"}, 216 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"}, 217 {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"}, 218 {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"}, 219 {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"}, 220 {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""}, 221 {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"}, 222 {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"}, 223 {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:ys"}, 224 {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"}, 225 {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"}, 226 {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"}, 227 #endif /* MINIMALISTIC */ 228 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, 229 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, 230 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, 231 {NULL, 0, 0, NULL} 232 }; 233 234 struct cam_devitem { 235 struct device_match_result dev_match; 236 int num_periphs; 237 struct periph_match_result *periph_matches; 238 struct scsi_vpd_device_id *device_id; 239 int device_id_len; 240 STAILQ_ENTRY(cam_devitem) links; 241 }; 242 243 struct cam_devlist { 244 STAILQ_HEAD(, cam_devitem) dev_queue; 245 path_id_t path_id; 246 }; 247 248 static cam_cmdmask cmdlist; 249 static cam_argmask arglist; 250 251 camcontrol_optret getoption(struct camcontrol_opts *table, char *arg, 252 uint32_t *cmdnum, cam_argmask *argnum, 253 const char **subopt); 254 #ifndef MINIMALISTIC 255 static int getdevlist(struct cam_device *device); 256 #endif /* MINIMALISTIC */ 257 static int getdevtree(int argc, char **argv, char *combinedopt); 258 #ifndef MINIMALISTIC 259 static int testunitready(struct cam_device *device, int retry_count, 260 int timeout, int quiet); 261 static int scsistart(struct cam_device *device, int startstop, int loadeject, 262 int retry_count, int timeout); 263 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout); 264 static int scsiserial(struct cam_device *device, int retry_count, int timeout); 265 static int camxferrate(struct cam_device *device); 266 #endif /* MINIMALISTIC */ 267 static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target, 268 lun_id_t *lun, cam_argmask *arglst); 269 static int dorescan_or_reset(int argc, char **argv, int rescan); 270 static int rescan_or_reset_bus(path_id_t bus, int rescan); 271 static int scanlun_or_reset_dev(path_id_t bus, target_id_t target, 272 lun_id_t lun, int scan); 273 #ifndef MINIMALISTIC 274 static int readdefects(struct cam_device *device, int argc, char **argv, 275 char *combinedopt, int retry_count, int timeout); 276 static void modepage(struct cam_device *device, int argc, char **argv, 277 char *combinedopt, int retry_count, int timeout); 278 static int scsicmd(struct cam_device *device, int argc, char **argv, 279 char *combinedopt, int retry_count, int timeout); 280 static int smpcmd(struct cam_device *device, int argc, char **argv, 281 char *combinedopt, int retry_count, int timeout); 282 static int smpreportgeneral(struct cam_device *device, int argc, char **argv, 283 char *combinedopt, int retry_count, int timeout); 284 static int smpphycontrol(struct cam_device *device, int argc, char **argv, 285 char *combinedopt, int retry_count, int timeout); 286 static int smpmaninfo(struct cam_device *device, int argc, char **argv, 287 char *combinedopt, int retry_count, int timeout); 288 static int getdevid(struct cam_devitem *item); 289 static int buildbusdevlist(struct cam_devlist *devlist); 290 static void freebusdevlist(struct cam_devlist *devlist); 291 static struct cam_devitem *findsasdevice(struct cam_devlist *devlist, 292 uint64_t sasaddr); 293 static int smpphylist(struct cam_device *device, int argc, char **argv, 294 char *combinedopt, int retry_count, int timeout); 295 static int tagcontrol(struct cam_device *device, int argc, char **argv, 296 char *combinedopt); 297 static void cts_print(struct cam_device *device, 298 struct ccb_trans_settings *cts); 299 static void cpi_print(struct ccb_pathinq *cpi); 300 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi); 301 static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd); 302 static int get_print_cts(struct cam_device *device, int user_settings, 303 int quiet, struct ccb_trans_settings *cts); 304 static int ratecontrol(struct cam_device *device, int retry_count, 305 int timeout, int argc, char **argv, char *combinedopt); 306 static int scsiformat(struct cam_device *device, int argc, char **argv, 307 char *combinedopt, int retry_count, int timeout); 308 static int scsisanitize(struct cam_device *device, int argc, char **argv, 309 char *combinedopt, int retry_count, int timeout); 310 static int scsireportluns(struct cam_device *device, int argc, char **argv, 311 char *combinedopt, int retry_count, int timeout); 312 static int scsireadcapacity(struct cam_device *device, int argc, char **argv, 313 char *combinedopt, int retry_count, int timeout); 314 static int atapm(struct cam_device *device, int argc, char **argv, 315 char *combinedopt, int retry_count, int timeout); 316 static int atasecurity(struct cam_device *device, int retry_count, int timeout, 317 int argc, char **argv, char *combinedopt); 318 static int atahpa(struct cam_device *device, int retry_count, int timeout, 319 int argc, char **argv, char *combinedopt); 320 321 #endif /* MINIMALISTIC */ 322 #ifndef min 323 #define min(a,b) (((a)<(b))?(a):(b)) 324 #endif 325 #ifndef max 326 #define max(a,b) (((a)>(b))?(a):(b)) 327 #endif 328 329 camcontrol_optret 330 getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum, 331 cam_argmask *argnum, const char **subopt) 332 { 333 struct camcontrol_opts *opts; 334 int num_matches = 0; 335 336 for (opts = table; (opts != NULL) && (opts->optname != NULL); 337 opts++) { 338 if (strncmp(opts->optname, arg, strlen(arg)) == 0) { 339 *cmdnum = opts->cmdnum; 340 *argnum = opts->argnum; 341 *subopt = opts->subopt; 342 if (++num_matches > 1) 343 return(CC_OR_AMBIGUOUS); 344 } 345 } 346 347 if (num_matches > 0) 348 return(CC_OR_FOUND); 349 else 350 return(CC_OR_NOT_FOUND); 351 } 352 353 #ifndef MINIMALISTIC 354 static int 355 getdevlist(struct cam_device *device) 356 { 357 union ccb *ccb; 358 char status[32]; 359 int error = 0; 360 361 ccb = cam_getccb(device); 362 363 ccb->ccb_h.func_code = XPT_GDEVLIST; 364 ccb->ccb_h.flags = CAM_DIR_NONE; 365 ccb->ccb_h.retry_count = 1; 366 ccb->cgdl.index = 0; 367 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS; 368 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) { 369 if (cam_send_ccb(device, ccb) < 0) { 370 perror("error getting device list"); 371 cam_freeccb(ccb); 372 return(1); 373 } 374 375 status[0] = '\0'; 376 377 switch (ccb->cgdl.status) { 378 case CAM_GDEVLIST_MORE_DEVS: 379 strcpy(status, "MORE"); 380 break; 381 case CAM_GDEVLIST_LAST_DEVICE: 382 strcpy(status, "LAST"); 383 break; 384 case CAM_GDEVLIST_LIST_CHANGED: 385 strcpy(status, "CHANGED"); 386 break; 387 case CAM_GDEVLIST_ERROR: 388 strcpy(status, "ERROR"); 389 error = 1; 390 break; 391 } 392 393 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n", 394 ccb->cgdl.periph_name, 395 ccb->cgdl.unit_number, 396 ccb->cgdl.generation, 397 ccb->cgdl.index, 398 status); 399 400 /* 401 * If the list has changed, we need to start over from the 402 * beginning. 403 */ 404 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED) 405 ccb->cgdl.index = 0; 406 } 407 408 cam_freeccb(ccb); 409 410 return(error); 411 } 412 #endif /* MINIMALISTIC */ 413 414 static int 415 getdevtree(int argc, char **argv, char *combinedopt) 416 { 417 union ccb ccb; 418 int bufsize, fd; 419 unsigned int i; 420 int need_close = 0; 421 int error = 0; 422 int skip_device = 0; 423 int busonly = 0; 424 int c; 425 426 while ((c = getopt(argc, argv, combinedopt)) != -1) { 427 switch(c) { 428 case 'b': 429 if ((arglist & CAM_ARG_VERBOSE) == 0) 430 busonly = 1; 431 break; 432 default: 433 break; 434 } 435 } 436 437 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { 438 warn("couldn't open %s", XPT_DEVICE); 439 return(1); 440 } 441 442 bzero(&ccb, sizeof(union ccb)); 443 444 ccb.ccb_h.path_id = CAM_XPT_PATH_ID; 445 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 446 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 447 448 ccb.ccb_h.func_code = XPT_DEV_MATCH; 449 bufsize = sizeof(struct dev_match_result) * 100; 450 ccb.cdm.match_buf_len = bufsize; 451 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); 452 if (ccb.cdm.matches == NULL) { 453 warnx("can't malloc memory for matches"); 454 close(fd); 455 return(1); 456 } 457 ccb.cdm.num_matches = 0; 458 459 /* 460 * We fetch all nodes, since we display most of them in the default 461 * case, and all in the verbose case. 462 */ 463 ccb.cdm.num_patterns = 0; 464 ccb.cdm.pattern_buf_len = 0; 465 466 /* 467 * We do the ioctl multiple times if necessary, in case there are 468 * more than 100 nodes in the EDT. 469 */ 470 do { 471 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 472 warn("error sending CAMIOCOMMAND ioctl"); 473 error = 1; 474 break; 475 } 476 477 if ((ccb.ccb_h.status != CAM_REQ_CMP) 478 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) 479 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { 480 warnx("got CAM error %#x, CDM error %d\n", 481 ccb.ccb_h.status, ccb.cdm.status); 482 error = 1; 483 break; 484 } 485 486 for (i = 0; i < ccb.cdm.num_matches; i++) { 487 switch (ccb.cdm.matches[i].type) { 488 case DEV_MATCH_BUS: { 489 struct bus_match_result *bus_result; 490 491 /* 492 * Only print the bus information if the 493 * user turns on the verbose flag. 494 */ 495 if ((busonly == 0) && 496 (arglist & CAM_ARG_VERBOSE) == 0) 497 break; 498 499 bus_result = 500 &ccb.cdm.matches[i].result.bus_result; 501 502 if (need_close) { 503 fprintf(stdout, ")\n"); 504 need_close = 0; 505 } 506 507 fprintf(stdout, "scbus%d on %s%d bus %d%s\n", 508 bus_result->path_id, 509 bus_result->dev_name, 510 bus_result->unit_number, 511 bus_result->bus_id, 512 (busonly ? "" : ":")); 513 break; 514 } 515 case DEV_MATCH_DEVICE: { 516 struct device_match_result *dev_result; 517 char vendor[16], product[48], revision[16]; 518 char fw[5], tmpstr[256]; 519 520 if (busonly == 1) 521 break; 522 523 dev_result = 524 &ccb.cdm.matches[i].result.device_result; 525 526 if ((dev_result->flags 527 & DEV_RESULT_UNCONFIGURED) 528 && ((arglist & CAM_ARG_VERBOSE) == 0)) { 529 skip_device = 1; 530 break; 531 } else 532 skip_device = 0; 533 534 if (dev_result->protocol == PROTO_SCSI) { 535 cam_strvis(vendor, dev_result->inq_data.vendor, 536 sizeof(dev_result->inq_data.vendor), 537 sizeof(vendor)); 538 cam_strvis(product, 539 dev_result->inq_data.product, 540 sizeof(dev_result->inq_data.product), 541 sizeof(product)); 542 cam_strvis(revision, 543 dev_result->inq_data.revision, 544 sizeof(dev_result->inq_data.revision), 545 sizeof(revision)); 546 sprintf(tmpstr, "<%s %s %s>", vendor, product, 547 revision); 548 } else if (dev_result->protocol == PROTO_ATA || 549 dev_result->protocol == PROTO_SATAPM) { 550 cam_strvis(product, 551 dev_result->ident_data.model, 552 sizeof(dev_result->ident_data.model), 553 sizeof(product)); 554 cam_strvis(revision, 555 dev_result->ident_data.revision, 556 sizeof(dev_result->ident_data.revision), 557 sizeof(revision)); 558 sprintf(tmpstr, "<%s %s>", product, 559 revision); 560 } else if (dev_result->protocol == PROTO_SEMB) { 561 struct sep_identify_data *sid; 562 563 sid = (struct sep_identify_data *) 564 &dev_result->ident_data; 565 cam_strvis(vendor, sid->vendor_id, 566 sizeof(sid->vendor_id), 567 sizeof(vendor)); 568 cam_strvis(product, sid->product_id, 569 sizeof(sid->product_id), 570 sizeof(product)); 571 cam_strvis(revision, sid->product_rev, 572 sizeof(sid->product_rev), 573 sizeof(revision)); 574 cam_strvis(fw, sid->firmware_rev, 575 sizeof(sid->firmware_rev), 576 sizeof(fw)); 577 sprintf(tmpstr, "<%s %s %s %s>", 578 vendor, product, revision, fw); 579 } else { 580 sprintf(tmpstr, "<>"); 581 } 582 if (need_close) { 583 fprintf(stdout, ")\n"); 584 need_close = 0; 585 } 586 587 fprintf(stdout, "%-33s at scbus%d " 588 "target %d lun %jx (", 589 tmpstr, 590 dev_result->path_id, 591 dev_result->target_id, 592 (uintmax_t)dev_result->target_lun); 593 594 need_close = 1; 595 596 break; 597 } 598 case DEV_MATCH_PERIPH: { 599 struct periph_match_result *periph_result; 600 601 periph_result = 602 &ccb.cdm.matches[i].result.periph_result; 603 604 if (busonly || skip_device != 0) 605 break; 606 607 if (need_close > 1) 608 fprintf(stdout, ","); 609 610 fprintf(stdout, "%s%d", 611 periph_result->periph_name, 612 periph_result->unit_number); 613 614 need_close++; 615 break; 616 } 617 default: 618 fprintf(stdout, "unknown match type\n"); 619 break; 620 } 621 } 622 623 } while ((ccb.ccb_h.status == CAM_REQ_CMP) 624 && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); 625 626 if (need_close) 627 fprintf(stdout, ")\n"); 628 629 close(fd); 630 631 return(error); 632 } 633 634 #ifndef MINIMALISTIC 635 static int 636 testunitready(struct cam_device *device, int retry_count, int timeout, 637 int quiet) 638 { 639 int error = 0; 640 union ccb *ccb; 641 642 ccb = cam_getccb(device); 643 644 scsi_test_unit_ready(&ccb->csio, 645 /* retries */ retry_count, 646 /* cbfcnp */ NULL, 647 /* tag_action */ MSG_SIMPLE_Q_TAG, 648 /* sense_len */ SSD_FULL_SIZE, 649 /* timeout */ timeout ? timeout : 5000); 650 651 /* Disable freezing the device queue */ 652 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 653 654 if (arglist & CAM_ARG_ERR_RECOVER) 655 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 656 657 if (cam_send_ccb(device, ccb) < 0) { 658 if (quiet == 0) 659 perror("error sending test unit ready"); 660 661 if (arglist & CAM_ARG_VERBOSE) { 662 cam_error_print(device, ccb, CAM_ESF_ALL, 663 CAM_EPF_ALL, stderr); 664 } 665 666 cam_freeccb(ccb); 667 return(1); 668 } 669 670 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { 671 if (quiet == 0) 672 fprintf(stdout, "Unit is ready\n"); 673 } else { 674 if (quiet == 0) 675 fprintf(stdout, "Unit is not ready\n"); 676 error = 1; 677 678 if (arglist & CAM_ARG_VERBOSE) { 679 cam_error_print(device, ccb, CAM_ESF_ALL, 680 CAM_EPF_ALL, stderr); 681 } 682 } 683 684 cam_freeccb(ccb); 685 686 return(error); 687 } 688 689 static int 690 scsistart(struct cam_device *device, int startstop, int loadeject, 691 int retry_count, int timeout) 692 { 693 union ccb *ccb; 694 int error = 0; 695 696 ccb = cam_getccb(device); 697 698 /* 699 * If we're stopping, send an ordered tag so the drive in question 700 * will finish any previously queued writes before stopping. If 701 * the device isn't capable of tagged queueing, or if tagged 702 * queueing is turned off, the tag action is a no-op. 703 */ 704 scsi_start_stop(&ccb->csio, 705 /* retries */ retry_count, 706 /* cbfcnp */ NULL, 707 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG : 708 MSG_ORDERED_Q_TAG, 709 /* start/stop */ startstop, 710 /* load_eject */ loadeject, 711 /* immediate */ 0, 712 /* sense_len */ SSD_FULL_SIZE, 713 /* timeout */ timeout ? timeout : 120000); 714 715 /* Disable freezing the device queue */ 716 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 717 718 if (arglist & CAM_ARG_ERR_RECOVER) 719 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 720 721 if (cam_send_ccb(device, ccb) < 0) { 722 perror("error sending start unit"); 723 724 if (arglist & CAM_ARG_VERBOSE) { 725 cam_error_print(device, ccb, CAM_ESF_ALL, 726 CAM_EPF_ALL, stderr); 727 } 728 729 cam_freeccb(ccb); 730 return(1); 731 } 732 733 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 734 if (startstop) { 735 fprintf(stdout, "Unit started successfully"); 736 if (loadeject) 737 fprintf(stdout,", Media loaded\n"); 738 else 739 fprintf(stdout,"\n"); 740 } else { 741 fprintf(stdout, "Unit stopped successfully"); 742 if (loadeject) 743 fprintf(stdout, ", Media ejected\n"); 744 else 745 fprintf(stdout, "\n"); 746 } 747 else { 748 error = 1; 749 if (startstop) 750 fprintf(stdout, 751 "Error received from start unit command\n"); 752 else 753 fprintf(stdout, 754 "Error received from stop unit command\n"); 755 756 if (arglist & CAM_ARG_VERBOSE) { 757 cam_error_print(device, ccb, CAM_ESF_ALL, 758 CAM_EPF_ALL, stderr); 759 } 760 } 761 762 cam_freeccb(ccb); 763 764 return(error); 765 } 766 767 int 768 scsidoinquiry(struct cam_device *device, int argc, char **argv, 769 char *combinedopt, int retry_count, int timeout) 770 { 771 int c; 772 int error = 0; 773 774 while ((c = getopt(argc, argv, combinedopt)) != -1) { 775 switch(c) { 776 case 'D': 777 arglist |= CAM_ARG_GET_STDINQ; 778 break; 779 case 'R': 780 arglist |= CAM_ARG_GET_XFERRATE; 781 break; 782 case 'S': 783 arglist |= CAM_ARG_GET_SERIAL; 784 break; 785 default: 786 break; 787 } 788 } 789 790 /* 791 * If the user didn't specify any inquiry options, he wants all of 792 * them. 793 */ 794 if ((arglist & CAM_ARG_INQ_MASK) == 0) 795 arglist |= CAM_ARG_INQ_MASK; 796 797 if (arglist & CAM_ARG_GET_STDINQ) 798 error = scsiinquiry(device, retry_count, timeout); 799 800 if (error != 0) 801 return(error); 802 803 if (arglist & CAM_ARG_GET_SERIAL) 804 scsiserial(device, retry_count, timeout); 805 806 if (error != 0) 807 return(error); 808 809 if (arglist & CAM_ARG_GET_XFERRATE) 810 error = camxferrate(device); 811 812 return(error); 813 } 814 815 static int 816 scsiinquiry(struct cam_device *device, int retry_count, int timeout) 817 { 818 union ccb *ccb; 819 struct scsi_inquiry_data *inq_buf; 820 int error = 0; 821 822 ccb = cam_getccb(device); 823 824 if (ccb == NULL) { 825 warnx("couldn't allocate CCB"); 826 return(1); 827 } 828 829 /* cam_getccb cleans up the header, caller has to zero the payload */ 830 bzero(&(&ccb->ccb_h)[1], 831 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 832 833 inq_buf = (struct scsi_inquiry_data *)malloc( 834 sizeof(struct scsi_inquiry_data)); 835 836 if (inq_buf == NULL) { 837 cam_freeccb(ccb); 838 warnx("can't malloc memory for inquiry\n"); 839 return(1); 840 } 841 bzero(inq_buf, sizeof(*inq_buf)); 842 843 /* 844 * Note that although the size of the inquiry buffer is the full 845 * 256 bytes specified in the SCSI spec, we only tell the device 846 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are 847 * two reasons for this: 848 * 849 * - The SCSI spec says that when a length field is only 1 byte, 850 * a value of 0 will be interpreted as 256. Therefore 851 * scsi_inquiry() will convert an inq_len (which is passed in as 852 * a u_int32_t, but the field in the CDB is only 1 byte) of 256 853 * to 0. Evidently, very few devices meet the spec in that 854 * regard. Some devices, like many Seagate disks, take the 0 as 855 * 0, and don't return any data. One Pioneer DVD-R drive 856 * returns more data than the command asked for. 857 * 858 * So, since there are numerous devices that just don't work 859 * right with the full inquiry size, we don't send the full size. 860 * 861 * - The second reason not to use the full inquiry data length is 862 * that we don't need it here. The only reason we issue a 863 * standard inquiry is to get the vendor name, device name, 864 * and revision so scsi_print_inquiry() can print them. 865 * 866 * If, at some point in the future, more inquiry data is needed for 867 * some reason, this code should use a procedure similar to the 868 * probe code. i.e., issue a short inquiry, and determine from 869 * the additional length passed back from the device how much 870 * inquiry data the device supports. Once the amount the device 871 * supports is determined, issue an inquiry for that amount and no 872 * more. 873 * 874 * KDM, 2/18/2000 875 */ 876 scsi_inquiry(&ccb->csio, 877 /* retries */ retry_count, 878 /* cbfcnp */ NULL, 879 /* tag_action */ MSG_SIMPLE_Q_TAG, 880 /* inq_buf */ (u_int8_t *)inq_buf, 881 /* inq_len */ SHORT_INQUIRY_LENGTH, 882 /* evpd */ 0, 883 /* page_code */ 0, 884 /* sense_len */ SSD_FULL_SIZE, 885 /* timeout */ timeout ? timeout : 5000); 886 887 /* Disable freezing the device queue */ 888 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 889 890 if (arglist & CAM_ARG_ERR_RECOVER) 891 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 892 893 if (cam_send_ccb(device, ccb) < 0) { 894 perror("error sending SCSI inquiry"); 895 896 if (arglist & CAM_ARG_VERBOSE) { 897 cam_error_print(device, ccb, CAM_ESF_ALL, 898 CAM_EPF_ALL, stderr); 899 } 900 901 cam_freeccb(ccb); 902 return(1); 903 } 904 905 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 906 error = 1; 907 908 if (arglist & CAM_ARG_VERBOSE) { 909 cam_error_print(device, ccb, CAM_ESF_ALL, 910 CAM_EPF_ALL, stderr); 911 } 912 } 913 914 cam_freeccb(ccb); 915 916 if (error != 0) { 917 free(inq_buf); 918 return(error); 919 } 920 921 fprintf(stdout, "%s%d: ", device->device_name, 922 device->dev_unit_num); 923 scsi_print_inquiry(inq_buf); 924 925 free(inq_buf); 926 927 return(0); 928 } 929 930 static int 931 scsiserial(struct cam_device *device, int retry_count, int timeout) 932 { 933 union ccb *ccb; 934 struct scsi_vpd_unit_serial_number *serial_buf; 935 char serial_num[SVPD_SERIAL_NUM_SIZE + 1]; 936 int error = 0; 937 938 ccb = cam_getccb(device); 939 940 if (ccb == NULL) { 941 warnx("couldn't allocate CCB"); 942 return(1); 943 } 944 945 /* cam_getccb cleans up the header, caller has to zero the payload */ 946 bzero(&(&ccb->ccb_h)[1], 947 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 948 949 serial_buf = (struct scsi_vpd_unit_serial_number *) 950 malloc(sizeof(*serial_buf)); 951 952 if (serial_buf == NULL) { 953 cam_freeccb(ccb); 954 warnx("can't malloc memory for serial number"); 955 return(1); 956 } 957 958 scsi_inquiry(&ccb->csio, 959 /*retries*/ retry_count, 960 /*cbfcnp*/ NULL, 961 /* tag_action */ MSG_SIMPLE_Q_TAG, 962 /* inq_buf */ (u_int8_t *)serial_buf, 963 /* inq_len */ sizeof(*serial_buf), 964 /* evpd */ 1, 965 /* page_code */ SVPD_UNIT_SERIAL_NUMBER, 966 /* sense_len */ SSD_FULL_SIZE, 967 /* timeout */ timeout ? timeout : 5000); 968 969 /* Disable freezing the device queue */ 970 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 971 972 if (arglist & CAM_ARG_ERR_RECOVER) 973 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 974 975 if (cam_send_ccb(device, ccb) < 0) { 976 warn("error getting serial number"); 977 978 if (arglist & CAM_ARG_VERBOSE) { 979 cam_error_print(device, ccb, CAM_ESF_ALL, 980 CAM_EPF_ALL, stderr); 981 } 982 983 cam_freeccb(ccb); 984 free(serial_buf); 985 return(1); 986 } 987 988 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 989 error = 1; 990 991 if (arglist & CAM_ARG_VERBOSE) { 992 cam_error_print(device, ccb, CAM_ESF_ALL, 993 CAM_EPF_ALL, stderr); 994 } 995 } 996 997 cam_freeccb(ccb); 998 999 if (error != 0) { 1000 free(serial_buf); 1001 return(error); 1002 } 1003 1004 bcopy(serial_buf->serial_num, serial_num, serial_buf->length); 1005 serial_num[serial_buf->length] = '\0'; 1006 1007 if ((arglist & CAM_ARG_GET_STDINQ) 1008 || (arglist & CAM_ARG_GET_XFERRATE)) 1009 fprintf(stdout, "%s%d: Serial Number ", 1010 device->device_name, device->dev_unit_num); 1011 1012 fprintf(stdout, "%.60s\n", serial_num); 1013 1014 free(serial_buf); 1015 1016 return(0); 1017 } 1018 1019 static int 1020 camxferrate(struct cam_device *device) 1021 { 1022 struct ccb_pathinq cpi; 1023 u_int32_t freq = 0; 1024 u_int32_t speed = 0; 1025 union ccb *ccb; 1026 u_int mb; 1027 int retval = 0; 1028 1029 if ((retval = get_cpi(device, &cpi)) != 0) 1030 return (1); 1031 1032 ccb = cam_getccb(device); 1033 1034 if (ccb == NULL) { 1035 warnx("couldn't allocate CCB"); 1036 return(1); 1037 } 1038 1039 bzero(&(&ccb->ccb_h)[1], 1040 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr)); 1041 1042 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 1043 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS; 1044 1045 if (((retval = cam_send_ccb(device, ccb)) < 0) 1046 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 1047 const char error_string[] = "error getting transfer settings"; 1048 1049 if (retval < 0) 1050 warn(error_string); 1051 else 1052 warnx(error_string); 1053 1054 if (arglist & CAM_ARG_VERBOSE) 1055 cam_error_print(device, ccb, CAM_ESF_ALL, 1056 CAM_EPF_ALL, stderr); 1057 1058 retval = 1; 1059 1060 goto xferrate_bailout; 1061 1062 } 1063 1064 speed = cpi.base_transfer_speed; 1065 freq = 0; 1066 if (ccb->cts.transport == XPORT_SPI) { 1067 struct ccb_trans_settings_spi *spi = 1068 &ccb->cts.xport_specific.spi; 1069 1070 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { 1071 freq = scsi_calc_syncsrate(spi->sync_period); 1072 speed = freq; 1073 } 1074 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { 1075 speed *= (0x01 << spi->bus_width); 1076 } 1077 } else if (ccb->cts.transport == XPORT_FC) { 1078 struct ccb_trans_settings_fc *fc = 1079 &ccb->cts.xport_specific.fc; 1080 1081 if (fc->valid & CTS_FC_VALID_SPEED) 1082 speed = fc->bitrate; 1083 } else if (ccb->cts.transport == XPORT_SAS) { 1084 struct ccb_trans_settings_sas *sas = 1085 &ccb->cts.xport_specific.sas; 1086 1087 if (sas->valid & CTS_SAS_VALID_SPEED) 1088 speed = sas->bitrate; 1089 } else if (ccb->cts.transport == XPORT_ATA) { 1090 struct ccb_trans_settings_pata *pata = 1091 &ccb->cts.xport_specific.ata; 1092 1093 if (pata->valid & CTS_ATA_VALID_MODE) 1094 speed = ata_mode2speed(pata->mode); 1095 } else if (ccb->cts.transport == XPORT_SATA) { 1096 struct ccb_trans_settings_sata *sata = 1097 &ccb->cts.xport_specific.sata; 1098 1099 if (sata->valid & CTS_SATA_VALID_REVISION) 1100 speed = ata_revision2speed(sata->revision); 1101 } 1102 1103 mb = speed / 1000; 1104 if (mb > 0) { 1105 fprintf(stdout, "%s%d: %d.%03dMB/s transfers", 1106 device->device_name, device->dev_unit_num, 1107 mb, speed % 1000); 1108 } else { 1109 fprintf(stdout, "%s%d: %dKB/s transfers", 1110 device->device_name, device->dev_unit_num, 1111 speed); 1112 } 1113 1114 if (ccb->cts.transport == XPORT_SPI) { 1115 struct ccb_trans_settings_spi *spi = 1116 &ccb->cts.xport_specific.spi; 1117 1118 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) 1119 && (spi->sync_offset != 0)) 1120 fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000, 1121 freq % 1000, spi->sync_offset); 1122 1123 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) 1124 && (spi->bus_width > 0)) { 1125 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) 1126 && (spi->sync_offset != 0)) { 1127 fprintf(stdout, ", "); 1128 } else { 1129 fprintf(stdout, " ("); 1130 } 1131 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width)); 1132 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) 1133 && (spi->sync_offset != 0)) { 1134 fprintf(stdout, ")"); 1135 } 1136 } else if (ccb->cts.transport == XPORT_ATA) { 1137 struct ccb_trans_settings_pata *pata = 1138 &ccb->cts.xport_specific.ata; 1139 1140 printf(" ("); 1141 if (pata->valid & CTS_ATA_VALID_MODE) 1142 printf("%s, ", ata_mode2string(pata->mode)); 1143 if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0) 1144 printf("ATAPI %dbytes, ", pata->atapi); 1145 if (pata->valid & CTS_ATA_VALID_BYTECOUNT) 1146 printf("PIO %dbytes", pata->bytecount); 1147 printf(")"); 1148 } else if (ccb->cts.transport == XPORT_SATA) { 1149 struct ccb_trans_settings_sata *sata = 1150 &ccb->cts.xport_specific.sata; 1151 1152 printf(" ("); 1153 if (sata->valid & CTS_SATA_VALID_REVISION) 1154 printf("SATA %d.x, ", sata->revision); 1155 else 1156 printf("SATA, "); 1157 if (sata->valid & CTS_SATA_VALID_MODE) 1158 printf("%s, ", ata_mode2string(sata->mode)); 1159 if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0) 1160 printf("ATAPI %dbytes, ", sata->atapi); 1161 if (sata->valid & CTS_SATA_VALID_BYTECOUNT) 1162 printf("PIO %dbytes", sata->bytecount); 1163 printf(")"); 1164 } 1165 1166 if (ccb->cts.protocol == PROTO_SCSI) { 1167 struct ccb_trans_settings_scsi *scsi = 1168 &ccb->cts.proto_specific.scsi; 1169 if (scsi->valid & CTS_SCSI_VALID_TQ) { 1170 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) { 1171 fprintf(stdout, ", Command Queueing Enabled"); 1172 } 1173 } 1174 } 1175 1176 fprintf(stdout, "\n"); 1177 1178 xferrate_bailout: 1179 1180 cam_freeccb(ccb); 1181 1182 return(retval); 1183 } 1184 1185 static void 1186 atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header) 1187 { 1188 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 | 1189 ((u_int32_t)parm->lba_size_2 << 16); 1190 1191 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) | 1192 ((u_int64_t)parm->lba_size48_2 << 16) | 1193 ((u_int64_t)parm->lba_size48_3 << 32) | 1194 ((u_int64_t)parm->lba_size48_4 << 48); 1195 1196 if (header) { 1197 printf("\nFeature " 1198 "Support Enabled Value\n"); 1199 } 1200 1201 printf("Host Protected Area (HPA) "); 1202 if (parm->support.command1 & ATA_SUPPORT_PROTECTED) { 1203 u_int64_t lba = lbasize48 ? lbasize48 : lbasize; 1204 printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ", 1205 lba, hpasize); 1206 1207 printf("HPA - Security "); 1208 if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY) 1209 printf("yes\n"); 1210 else 1211 printf("no\n"); 1212 } else { 1213 printf("no\n"); 1214 } 1215 } 1216 1217 static int 1218 atasata(struct ata_params *parm) 1219 { 1220 1221 1222 if (parm->satacapabilities != 0xffff && 1223 parm->satacapabilities != 0x0000) 1224 return 1; 1225 1226 return 0; 1227 } 1228 1229 static void 1230 atacapprint(struct ata_params *parm) 1231 { 1232 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 | 1233 ((u_int32_t)parm->lba_size_2 << 16); 1234 1235 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) | 1236 ((u_int64_t)parm->lba_size48_2 << 16) | 1237 ((u_int64_t)parm->lba_size48_3 << 32) | 1238 ((u_int64_t)parm->lba_size48_4 << 48); 1239 1240 printf("\n"); 1241 printf("protocol "); 1242 printf("ATA/ATAPI-%d", ata_version(parm->version_major)); 1243 if (parm->satacapabilities && parm->satacapabilities != 0xffff) { 1244 if (parm->satacapabilities & ATA_SATA_GEN3) 1245 printf(" SATA 3.x\n"); 1246 else if (parm->satacapabilities & ATA_SATA_GEN2) 1247 printf(" SATA 2.x\n"); 1248 else if (parm->satacapabilities & ATA_SATA_GEN1) 1249 printf(" SATA 1.x\n"); 1250 else 1251 printf(" SATA\n"); 1252 } 1253 else 1254 printf("\n"); 1255 printf("device model %.40s\n", parm->model); 1256 printf("firmware revision %.8s\n", parm->revision); 1257 printf("serial number %.20s\n", parm->serial); 1258 if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) { 1259 printf("WWN %04x%04x%04x%04x\n", 1260 parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]); 1261 } 1262 if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) { 1263 printf("media serial number %.30s\n", 1264 parm->media_serial); 1265 } 1266 1267 printf("cylinders %d\n", parm->cylinders); 1268 printf("heads %d\n", parm->heads); 1269 printf("sectors/track %d\n", parm->sectors); 1270 printf("sector size logical %u, physical %lu, offset %lu\n", 1271 ata_logical_sector_size(parm), 1272 (unsigned long)ata_physical_sector_size(parm), 1273 (unsigned long)ata_logical_sector_offset(parm)); 1274 1275 if (parm->config == ATA_PROTO_CFA || 1276 (parm->support.command2 & ATA_SUPPORT_CFA)) 1277 printf("CFA supported\n"); 1278 1279 printf("LBA%ssupported ", 1280 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not "); 1281 if (lbasize) 1282 printf("%d sectors\n", lbasize); 1283 else 1284 printf("\n"); 1285 1286 printf("LBA48%ssupported ", 1287 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not "); 1288 if (lbasize48) 1289 printf("%ju sectors\n", (uintmax_t)lbasize48); 1290 else 1291 printf("\n"); 1292 1293 printf("PIO supported PIO"); 1294 switch (ata_max_pmode(parm)) { 1295 case ATA_PIO4: 1296 printf("4"); 1297 break; 1298 case ATA_PIO3: 1299 printf("3"); 1300 break; 1301 case ATA_PIO2: 1302 printf("2"); 1303 break; 1304 case ATA_PIO1: 1305 printf("1"); 1306 break; 1307 default: 1308 printf("0"); 1309 } 1310 if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0) 1311 printf(" w/o IORDY"); 1312 printf("\n"); 1313 1314 printf("DMA%ssupported ", 1315 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not "); 1316 if (parm->capabilities1 & ATA_SUPPORT_DMA) { 1317 if (parm->mwdmamodes & 0xff) { 1318 printf("WDMA"); 1319 if (parm->mwdmamodes & 0x04) 1320 printf("2"); 1321 else if (parm->mwdmamodes & 0x02) 1322 printf("1"); 1323 else if (parm->mwdmamodes & 0x01) 1324 printf("0"); 1325 printf(" "); 1326 } 1327 if ((parm->atavalid & ATA_FLAG_88) && 1328 (parm->udmamodes & 0xff)) { 1329 printf("UDMA"); 1330 if (parm->udmamodes & 0x40) 1331 printf("6"); 1332 else if (parm->udmamodes & 0x20) 1333 printf("5"); 1334 else if (parm->udmamodes & 0x10) 1335 printf("4"); 1336 else if (parm->udmamodes & 0x08) 1337 printf("3"); 1338 else if (parm->udmamodes & 0x04) 1339 printf("2"); 1340 else if (parm->udmamodes & 0x02) 1341 printf("1"); 1342 else if (parm->udmamodes & 0x01) 1343 printf("0"); 1344 printf(" "); 1345 } 1346 } 1347 printf("\n"); 1348 1349 if (parm->media_rotation_rate == 1) { 1350 printf("media RPM non-rotating\n"); 1351 } else if (parm->media_rotation_rate >= 0x0401 && 1352 parm->media_rotation_rate <= 0xFFFE) { 1353 printf("media RPM %d\n", 1354 parm->media_rotation_rate); 1355 } 1356 1357 printf("\nFeature " 1358 "Support Enabled Value Vendor\n"); 1359 printf("read ahead %s %s\n", 1360 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no", 1361 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no"); 1362 printf("write cache %s %s\n", 1363 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no", 1364 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no"); 1365 printf("flush cache %s %s\n", 1366 parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no", 1367 parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no"); 1368 printf("overlap %s\n", 1369 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no"); 1370 printf("Tagged Command Queuing (TCQ) %s %s", 1371 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no", 1372 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no"); 1373 if (parm->support.command2 & ATA_SUPPORT_QUEUED) { 1374 printf(" %d tags\n", 1375 ATA_QUEUE_LEN(parm->queue) + 1); 1376 } else 1377 printf("\n"); 1378 printf("Native Command Queuing (NCQ) "); 1379 if (parm->satacapabilities != 0xffff && 1380 (parm->satacapabilities & ATA_SUPPORT_NCQ)) { 1381 printf("yes %d tags\n", 1382 ATA_QUEUE_LEN(parm->queue) + 1); 1383 } else 1384 printf("no\n"); 1385 1386 printf("NCQ Queue Management %s\n", atasata(parm) && 1387 parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ? 1388 "yes" : "no"); 1389 printf("NCQ Streaming %s\n", atasata(parm) && 1390 parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ? 1391 "yes" : "no"); 1392 printf("Receive & Send FPDMA Queued %s\n", atasata(parm) && 1393 parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ? 1394 "yes" : "no"); 1395 1396 printf("SMART %s %s\n", 1397 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no", 1398 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no"); 1399 printf("microcode download %s %s\n", 1400 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no", 1401 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no"); 1402 printf("security %s %s\n", 1403 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no", 1404 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no"); 1405 printf("power management %s %s\n", 1406 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no", 1407 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no"); 1408 printf("advanced power management %s %s", 1409 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no", 1410 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no"); 1411 if (parm->support.command2 & ATA_SUPPORT_APM) { 1412 printf(" %d/0x%02X\n", 1413 parm->apm_value & 0xff, parm->apm_value & 0xff); 1414 } else 1415 printf("\n"); 1416 printf("automatic acoustic management %s %s", 1417 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no", 1418 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no"); 1419 if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) { 1420 printf(" %d/0x%02X %d/0x%02X\n", 1421 ATA_ACOUSTIC_CURRENT(parm->acoustic), 1422 ATA_ACOUSTIC_CURRENT(parm->acoustic), 1423 ATA_ACOUSTIC_VENDOR(parm->acoustic), 1424 ATA_ACOUSTIC_VENDOR(parm->acoustic)); 1425 } else 1426 printf("\n"); 1427 printf("media status notification %s %s\n", 1428 parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no", 1429 parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no"); 1430 printf("power-up in Standby %s %s\n", 1431 parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no", 1432 parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no"); 1433 printf("write-read-verify %s %s", 1434 parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no", 1435 parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no"); 1436 if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) { 1437 printf(" %d/0x%x\n", 1438 parm->wrv_mode, parm->wrv_mode); 1439 } else 1440 printf("\n"); 1441 printf("unload %s %s\n", 1442 parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no", 1443 parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no"); 1444 printf("general purpose logging %s %s\n", 1445 parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no", 1446 parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no"); 1447 printf("free-fall %s %s\n", 1448 parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no", 1449 parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no"); 1450 printf("Data Set Management (DSM/TRIM) "); 1451 if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) { 1452 printf("yes\n"); 1453 printf("DSM - max 512byte blocks "); 1454 if (parm->max_dsm_blocks == 0x00) 1455 printf("yes not specified\n"); 1456 else 1457 printf("yes %d\n", 1458 parm->max_dsm_blocks); 1459 1460 printf("DSM - deterministic read "); 1461 if (parm->support3 & ATA_SUPPORT_DRAT) { 1462 if (parm->support3 & ATA_SUPPORT_RZAT) 1463 printf("yes zeroed\n"); 1464 else 1465 printf("yes any value\n"); 1466 } else { 1467 printf("no\n"); 1468 } 1469 } else { 1470 printf("no\n"); 1471 } 1472 } 1473 1474 static int 1475 scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet) 1476 { 1477 struct ata_pass_16 *ata_pass_16; 1478 struct ata_cmd ata_cmd; 1479 1480 ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes; 1481 ata_cmd.command = ata_pass_16->command; 1482 ata_cmd.control = ata_pass_16->control; 1483 ata_cmd.features = ata_pass_16->features; 1484 1485 if (arglist & CAM_ARG_VERBOSE) { 1486 warnx("sending ATA %s via pass_16 with timeout of %u msecs", 1487 ata_op_string(&ata_cmd), 1488 ccb->csio.ccb_h.timeout); 1489 } 1490 1491 /* Disable freezing the device queue */ 1492 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 1493 1494 if (arglist & CAM_ARG_ERR_RECOVER) 1495 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 1496 1497 if (cam_send_ccb(device, ccb) < 0) { 1498 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) { 1499 warn("error sending ATA %s via pass_16", 1500 ata_op_string(&ata_cmd)); 1501 } 1502 1503 if (arglist & CAM_ARG_VERBOSE) { 1504 cam_error_print(device, ccb, CAM_ESF_ALL, 1505 CAM_EPF_ALL, stderr); 1506 } 1507 1508 return (1); 1509 } 1510 1511 if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) && 1512 (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1513 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) { 1514 warnx("ATA %s via pass_16 failed", 1515 ata_op_string(&ata_cmd)); 1516 } 1517 if (arglist & CAM_ARG_VERBOSE) { 1518 cam_error_print(device, ccb, CAM_ESF_ALL, 1519 CAM_EPF_ALL, stderr); 1520 } 1521 1522 return (1); 1523 } 1524 1525 return (0); 1526 } 1527 1528 1529 static int 1530 ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet) 1531 { 1532 if (arglist & CAM_ARG_VERBOSE) { 1533 warnx("sending ATA %s with timeout of %u msecs", 1534 ata_op_string(&(ccb->ataio.cmd)), 1535 ccb->ataio.ccb_h.timeout); 1536 } 1537 1538 /* Disable freezing the device queue */ 1539 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 1540 1541 if (arglist & CAM_ARG_ERR_RECOVER) 1542 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 1543 1544 if (cam_send_ccb(device, ccb) < 0) { 1545 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) { 1546 warn("error sending ATA %s", 1547 ata_op_string(&(ccb->ataio.cmd))); 1548 } 1549 1550 if (arglist & CAM_ARG_VERBOSE) { 1551 cam_error_print(device, ccb, CAM_ESF_ALL, 1552 CAM_EPF_ALL, stderr); 1553 } 1554 1555 return (1); 1556 } 1557 1558 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1559 if (quiet != 1 || arglist & CAM_ARG_VERBOSE) { 1560 warnx("ATA %s failed: %d", 1561 ata_op_string(&(ccb->ataio.cmd)), quiet); 1562 } 1563 1564 if (arglist & CAM_ARG_VERBOSE) { 1565 cam_error_print(device, ccb, CAM_ESF_ALL, 1566 CAM_EPF_ALL, stderr); 1567 } 1568 1569 return (1); 1570 } 1571 1572 return (0); 1573 } 1574 1575 static int 1576 ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries, 1577 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags, 1578 u_int8_t tag_action, u_int8_t command, u_int8_t features, 1579 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr, 1580 u_int16_t dxfer_len, int timeout, int quiet) 1581 { 1582 if (data_ptr != NULL) { 1583 ata_flags |= AP_FLAG_BYT_BLOK_BYTES | 1584 AP_FLAG_TLEN_SECT_CNT; 1585 if (flags & CAM_DIR_OUT) 1586 ata_flags |= AP_FLAG_TDIR_TO_DEV; 1587 else 1588 ata_flags |= AP_FLAG_TDIR_FROM_DEV; 1589 } else { 1590 ata_flags |= AP_FLAG_TLEN_NO_DATA; 1591 } 1592 1593 bzero(&(&ccb->ccb_h)[1], 1594 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 1595 1596 scsi_ata_pass_16(&ccb->csio, 1597 retries, 1598 NULL, 1599 flags, 1600 tag_action, 1601 protocol, 1602 ata_flags, 1603 features, 1604 sector_count, 1605 lba, 1606 command, 1607 /*control*/0, 1608 data_ptr, 1609 dxfer_len, 1610 /*sense_len*/SSD_FULL_SIZE, 1611 timeout); 1612 1613 return scsi_cam_pass_16_send(device, ccb, quiet); 1614 } 1615 1616 static int 1617 ata_try_pass_16(struct cam_device *device) 1618 { 1619 struct ccb_pathinq cpi; 1620 1621 if (get_cpi(device, &cpi) != 0) { 1622 warnx("couldn't get CPI"); 1623 return (-1); 1624 } 1625 1626 if (cpi.protocol == PROTO_SCSI) { 1627 /* possibly compatible with pass_16 */ 1628 return (1); 1629 } 1630 1631 /* likely not compatible with pass_16 */ 1632 return (0); 1633 } 1634 1635 static int 1636 ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries, 1637 u_int32_t flags, u_int8_t protocol, u_int8_t tag_action, 1638 u_int8_t command, u_int8_t features, u_int32_t lba, 1639 u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len, 1640 int timeout, int quiet) 1641 { 1642 1643 1644 switch (ata_try_pass_16(device)) { 1645 case -1: 1646 return (1); 1647 case 1: 1648 /* Try using SCSI Passthrough */ 1649 return ata_do_pass_16(device, ccb, retries, flags, protocol, 1650 0, tag_action, command, features, lba, 1651 sector_count, data_ptr, dxfer_len, 1652 timeout, quiet); 1653 } 1654 1655 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) - 1656 sizeof(struct ccb_hdr)); 1657 cam_fill_ataio(&ccb->ataio, 1658 retries, 1659 NULL, 1660 flags, 1661 tag_action, 1662 data_ptr, 1663 dxfer_len, 1664 timeout); 1665 1666 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count); 1667 return ata_cam_send(device, ccb, quiet); 1668 } 1669 1670 static int 1671 ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries, 1672 u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags, 1673 u_int8_t tag_action, u_int8_t command, u_int8_t features, 1674 u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr, 1675 u_int16_t dxfer_len, int timeout, int force48bit) 1676 { 1677 int retval; 1678 1679 retval = ata_try_pass_16(device); 1680 if (retval == -1) 1681 return (1); 1682 1683 if (retval == 1) { 1684 int error; 1685 1686 /* Try using SCSI Passthrough */ 1687 error = ata_do_pass_16(device, ccb, retries, flags, protocol, 1688 ata_flags, tag_action, command, features, 1689 lba, sector_count, data_ptr, dxfer_len, 1690 timeout, 0); 1691 1692 if (ata_flags & AP_FLAG_CHK_COND) { 1693 /* Decode ata_res from sense data */ 1694 struct ata_res_pass16 *res_pass16; 1695 struct ata_res *res; 1696 u_int i; 1697 u_int16_t *ptr; 1698 1699 /* sense_data is 4 byte aligned */ 1700 ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data; 1701 for (i = 0; i < sizeof(*res_pass16) / 2; i++) 1702 ptr[i] = le16toh(ptr[i]); 1703 1704 /* sense_data is 4 byte aligned */ 1705 res_pass16 = (struct ata_res_pass16 *)(uintptr_t) 1706 &ccb->csio.sense_data; 1707 res = &ccb->ataio.res; 1708 res->flags = res_pass16->flags; 1709 res->status = res_pass16->status; 1710 res->error = res_pass16->error; 1711 res->lba_low = res_pass16->lba_low; 1712 res->lba_mid = res_pass16->lba_mid; 1713 res->lba_high = res_pass16->lba_high; 1714 res->device = res_pass16->device; 1715 res->lba_low_exp = res_pass16->lba_low_exp; 1716 res->lba_mid_exp = res_pass16->lba_mid_exp; 1717 res->lba_high_exp = res_pass16->lba_high_exp; 1718 res->sector_count = res_pass16->sector_count; 1719 res->sector_count_exp = res_pass16->sector_count_exp; 1720 } 1721 1722 return (error); 1723 } 1724 1725 bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_ataio) - 1726 sizeof(struct ccb_hdr)); 1727 cam_fill_ataio(&ccb->ataio, 1728 retries, 1729 NULL, 1730 flags, 1731 tag_action, 1732 data_ptr, 1733 dxfer_len, 1734 timeout); 1735 1736 if (force48bit || lba > ATA_MAX_28BIT_LBA) 1737 ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count); 1738 else 1739 ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count); 1740 1741 if (ata_flags & AP_FLAG_CHK_COND) 1742 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; 1743 1744 return ata_cam_send(device, ccb, 0); 1745 } 1746 1747 static void 1748 dump_data(uint16_t *ptr, uint32_t len) 1749 { 1750 u_int i; 1751 1752 for (i = 0; i < len / 2; i++) { 1753 if ((i % 8) == 0) 1754 printf(" %3d: ", i); 1755 printf("%04hx ", ptr[i]); 1756 if ((i % 8) == 7) 1757 printf("\n"); 1758 } 1759 if ((i % 8) != 7) 1760 printf("\n"); 1761 } 1762 1763 static int 1764 atahpa_proc_resp(struct cam_device *device, union ccb *ccb, 1765 int is48bit, u_int64_t *hpasize) 1766 { 1767 struct ata_res *res; 1768 1769 res = &ccb->ataio.res; 1770 if (res->status & ATA_STATUS_ERROR) { 1771 if (arglist & CAM_ARG_VERBOSE) { 1772 cam_error_print(device, ccb, CAM_ESF_ALL, 1773 CAM_EPF_ALL, stderr); 1774 printf("error = 0x%02x, sector_count = 0x%04x, " 1775 "device = 0x%02x, status = 0x%02x\n", 1776 res->error, res->sector_count, 1777 res->device, res->status); 1778 } 1779 1780 if (res->error & ATA_ERROR_ID_NOT_FOUND) { 1781 warnx("Max address has already been set since " 1782 "last power-on or hardware reset"); 1783 } 1784 1785 return (1); 1786 } 1787 1788 if (arglist & CAM_ARG_VERBOSE) { 1789 fprintf(stdout, "%s%d: Raw native max data:\n", 1790 device->device_name, device->dev_unit_num); 1791 /* res is 4 byte aligned */ 1792 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res)); 1793 1794 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, " 1795 "status = 0x%02x\n", res->error, res->sector_count, 1796 res->device, res->status); 1797 } 1798 1799 if (hpasize != NULL) { 1800 if (is48bit) { 1801 *hpasize = (((u_int64_t)((res->lba_high_exp << 16) | 1802 (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) | 1803 ((res->lba_high << 16) | (res->lba_mid << 8) | 1804 res->lba_low)) + 1; 1805 } else { 1806 *hpasize = (((res->device & 0x0f) << 24) | 1807 (res->lba_high << 16) | (res->lba_mid << 8) | 1808 res->lba_low) + 1; 1809 } 1810 } 1811 1812 return (0); 1813 } 1814 1815 static int 1816 ata_read_native_max(struct cam_device *device, int retry_count, 1817 u_int32_t timeout, union ccb *ccb, 1818 struct ata_params *parm, u_int64_t *hpasize) 1819 { 1820 int error; 1821 u_int cmd, is48bit; 1822 u_int8_t protocol; 1823 1824 is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48; 1825 protocol = AP_PROTO_NON_DATA; 1826 1827 if (is48bit) { 1828 cmd = ATA_READ_NATIVE_MAX_ADDRESS48; 1829 protocol |= AP_EXTEND; 1830 } else { 1831 cmd = ATA_READ_NATIVE_MAX_ADDRESS; 1832 } 1833 1834 error = ata_do_cmd(device, 1835 ccb, 1836 retry_count, 1837 /*flags*/CAM_DIR_NONE, 1838 /*protocol*/protocol, 1839 /*ata_flags*/AP_FLAG_CHK_COND, 1840 /*tag_action*/MSG_SIMPLE_Q_TAG, 1841 /*command*/cmd, 1842 /*features*/0, 1843 /*lba*/0, 1844 /*sector_count*/0, 1845 /*data_ptr*/NULL, 1846 /*dxfer_len*/0, 1847 timeout ? timeout : 1000, 1848 is48bit); 1849 1850 if (error) 1851 return (error); 1852 1853 return atahpa_proc_resp(device, ccb, is48bit, hpasize); 1854 } 1855 1856 static int 1857 atahpa_set_max(struct cam_device *device, int retry_count, 1858 u_int32_t timeout, union ccb *ccb, 1859 int is48bit, u_int64_t maxsize, int persist) 1860 { 1861 int error; 1862 u_int cmd; 1863 u_int8_t protocol; 1864 1865 protocol = AP_PROTO_NON_DATA; 1866 1867 if (is48bit) { 1868 cmd = ATA_SET_MAX_ADDRESS48; 1869 protocol |= AP_EXTEND; 1870 } else { 1871 cmd = ATA_SET_MAX_ADDRESS; 1872 } 1873 1874 /* lba's are zero indexed so the max lba is requested max - 1 */ 1875 if (maxsize) 1876 maxsize--; 1877 1878 error = ata_do_cmd(device, 1879 ccb, 1880 retry_count, 1881 /*flags*/CAM_DIR_NONE, 1882 /*protocol*/protocol, 1883 /*ata_flags*/AP_FLAG_CHK_COND, 1884 /*tag_action*/MSG_SIMPLE_Q_TAG, 1885 /*command*/cmd, 1886 /*features*/ATA_HPA_FEAT_MAX_ADDR, 1887 /*lba*/maxsize, 1888 /*sector_count*/persist, 1889 /*data_ptr*/NULL, 1890 /*dxfer_len*/0, 1891 timeout ? timeout : 1000, 1892 is48bit); 1893 1894 if (error) 1895 return (error); 1896 1897 return atahpa_proc_resp(device, ccb, is48bit, NULL); 1898 } 1899 1900 static int 1901 atahpa_password(struct cam_device *device, int retry_count, 1902 u_int32_t timeout, union ccb *ccb, 1903 int is48bit, struct ata_set_max_pwd *pwd) 1904 { 1905 int error; 1906 u_int cmd; 1907 u_int8_t protocol; 1908 1909 protocol = AP_PROTO_PIO_OUT; 1910 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; 1911 1912 error = ata_do_cmd(device, 1913 ccb, 1914 retry_count, 1915 /*flags*/CAM_DIR_OUT, 1916 /*protocol*/protocol, 1917 /*ata_flags*/AP_FLAG_CHK_COND, 1918 /*tag_action*/MSG_SIMPLE_Q_TAG, 1919 /*command*/cmd, 1920 /*features*/ATA_HPA_FEAT_SET_PWD, 1921 /*lba*/0, 1922 /*sector_count*/0, 1923 /*data_ptr*/(u_int8_t*)pwd, 1924 /*dxfer_len*/sizeof(struct ata_set_max_pwd), 1925 timeout ? timeout : 1000, 1926 is48bit); 1927 1928 if (error) 1929 return (error); 1930 1931 return atahpa_proc_resp(device, ccb, is48bit, NULL); 1932 } 1933 1934 static int 1935 atahpa_lock(struct cam_device *device, int retry_count, 1936 u_int32_t timeout, union ccb *ccb, int is48bit) 1937 { 1938 int error; 1939 u_int cmd; 1940 u_int8_t protocol; 1941 1942 protocol = AP_PROTO_NON_DATA; 1943 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; 1944 1945 error = ata_do_cmd(device, 1946 ccb, 1947 retry_count, 1948 /*flags*/CAM_DIR_NONE, 1949 /*protocol*/protocol, 1950 /*ata_flags*/AP_FLAG_CHK_COND, 1951 /*tag_action*/MSG_SIMPLE_Q_TAG, 1952 /*command*/cmd, 1953 /*features*/ATA_HPA_FEAT_LOCK, 1954 /*lba*/0, 1955 /*sector_count*/0, 1956 /*data_ptr*/NULL, 1957 /*dxfer_len*/0, 1958 timeout ? timeout : 1000, 1959 is48bit); 1960 1961 if (error) 1962 return (error); 1963 1964 return atahpa_proc_resp(device, ccb, is48bit, NULL); 1965 } 1966 1967 static int 1968 atahpa_unlock(struct cam_device *device, int retry_count, 1969 u_int32_t timeout, union ccb *ccb, 1970 int is48bit, struct ata_set_max_pwd *pwd) 1971 { 1972 int error; 1973 u_int cmd; 1974 u_int8_t protocol; 1975 1976 protocol = AP_PROTO_PIO_OUT; 1977 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; 1978 1979 error = ata_do_cmd(device, 1980 ccb, 1981 retry_count, 1982 /*flags*/CAM_DIR_OUT, 1983 /*protocol*/protocol, 1984 /*ata_flags*/AP_FLAG_CHK_COND, 1985 /*tag_action*/MSG_SIMPLE_Q_TAG, 1986 /*command*/cmd, 1987 /*features*/ATA_HPA_FEAT_UNLOCK, 1988 /*lba*/0, 1989 /*sector_count*/0, 1990 /*data_ptr*/(u_int8_t*)pwd, 1991 /*dxfer_len*/sizeof(struct ata_set_max_pwd), 1992 timeout ? timeout : 1000, 1993 is48bit); 1994 1995 if (error) 1996 return (error); 1997 1998 return atahpa_proc_resp(device, ccb, is48bit, NULL); 1999 } 2000 2001 static int 2002 atahpa_freeze_lock(struct cam_device *device, int retry_count, 2003 u_int32_t timeout, union ccb *ccb, int is48bit) 2004 { 2005 int error; 2006 u_int cmd; 2007 u_int8_t protocol; 2008 2009 protocol = AP_PROTO_NON_DATA; 2010 cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; 2011 2012 error = ata_do_cmd(device, 2013 ccb, 2014 retry_count, 2015 /*flags*/CAM_DIR_NONE, 2016 /*protocol*/protocol, 2017 /*ata_flags*/AP_FLAG_CHK_COND, 2018 /*tag_action*/MSG_SIMPLE_Q_TAG, 2019 /*command*/cmd, 2020 /*features*/ATA_HPA_FEAT_FREEZE, 2021 /*lba*/0, 2022 /*sector_count*/0, 2023 /*data_ptr*/NULL, 2024 /*dxfer_len*/0, 2025 timeout ? timeout : 1000, 2026 is48bit); 2027 2028 if (error) 2029 return (error); 2030 2031 return atahpa_proc_resp(device, ccb, is48bit, NULL); 2032 } 2033 2034 2035 static int 2036 ata_do_identify(struct cam_device *device, int retry_count, int timeout, 2037 union ccb *ccb, struct ata_params** ident_bufp) 2038 { 2039 struct ata_params *ident_buf; 2040 struct ccb_pathinq cpi; 2041 struct ccb_getdev cgd; 2042 u_int i, error; 2043 int16_t *ptr; 2044 u_int8_t command, retry_command; 2045 2046 if (get_cpi(device, &cpi) != 0) { 2047 warnx("couldn't get CPI"); 2048 return (-1); 2049 } 2050 2051 /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */ 2052 if (cpi.protocol == PROTO_ATA) { 2053 if (get_cgd(device, &cgd) != 0) { 2054 warnx("couldn't get CGD"); 2055 return (-1); 2056 } 2057 2058 command = (cgd.protocol == PROTO_ATA) ? 2059 ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY; 2060 retry_command = 0; 2061 } else { 2062 /* We don't know which for sure so try both */ 2063 command = ATA_ATA_IDENTIFY; 2064 retry_command = ATA_ATAPI_IDENTIFY; 2065 } 2066 2067 ptr = (uint16_t *)calloc(1, sizeof(struct ata_params)); 2068 if (ptr == NULL) { 2069 warnx("can't calloc memory for identify\n"); 2070 return (1); 2071 } 2072 2073 error = ata_do_28bit_cmd(device, 2074 ccb, 2075 /*retries*/retry_count, 2076 /*flags*/CAM_DIR_IN, 2077 /*protocol*/AP_PROTO_PIO_IN, 2078 /*tag_action*/MSG_SIMPLE_Q_TAG, 2079 /*command*/command, 2080 /*features*/0, 2081 /*lba*/0, 2082 /*sector_count*/(u_int8_t)sizeof(struct ata_params), 2083 /*data_ptr*/(u_int8_t *)ptr, 2084 /*dxfer_len*/sizeof(struct ata_params), 2085 /*timeout*/timeout ? timeout : 30 * 1000, 2086 /*quiet*/1); 2087 2088 if (error != 0) { 2089 if (retry_command == 0) { 2090 free(ptr); 2091 return (1); 2092 } 2093 error = ata_do_28bit_cmd(device, 2094 ccb, 2095 /*retries*/retry_count, 2096 /*flags*/CAM_DIR_IN, 2097 /*protocol*/AP_PROTO_PIO_IN, 2098 /*tag_action*/MSG_SIMPLE_Q_TAG, 2099 /*command*/retry_command, 2100 /*features*/0, 2101 /*lba*/0, 2102 /*sector_count*/(u_int8_t) 2103 sizeof(struct ata_params), 2104 /*data_ptr*/(u_int8_t *)ptr, 2105 /*dxfer_len*/sizeof(struct ata_params), 2106 /*timeout*/timeout ? timeout : 30 * 1000, 2107 /*quiet*/0); 2108 2109 if (error != 0) { 2110 free(ptr); 2111 return (1); 2112 } 2113 } 2114 2115 error = 1; 2116 for (i = 0; i < sizeof(struct ata_params) / 2; i++) { 2117 ptr[i] = le16toh(ptr[i]); 2118 if (ptr[i] != 0) 2119 error = 0; 2120 } 2121 2122 if (arglist & CAM_ARG_VERBOSE) { 2123 fprintf(stdout, "%s%d: Raw identify data:\n", 2124 device->device_name, device->dev_unit_num); 2125 dump_data(ptr, sizeof(struct ata_params)); 2126 } 2127 2128 /* check for invalid (all zero) response */ 2129 if (error != 0) { 2130 warnx("Invalid identify response detected"); 2131 free(ptr); 2132 return (error); 2133 } 2134 2135 ident_buf = (struct ata_params *)ptr; 2136 if (strncmp(ident_buf->model, "FX", 2) && 2137 strncmp(ident_buf->model, "NEC", 3) && 2138 strncmp(ident_buf->model, "Pioneer", 7) && 2139 strncmp(ident_buf->model, "SHARP", 5)) { 2140 ata_bswap(ident_buf->model, sizeof(ident_buf->model)); 2141 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision)); 2142 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial)); 2143 ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial)); 2144 } 2145 ata_btrim(ident_buf->model, sizeof(ident_buf->model)); 2146 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model)); 2147 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision)); 2148 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision)); 2149 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial)); 2150 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial)); 2151 ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial)); 2152 ata_bpack(ident_buf->media_serial, ident_buf->media_serial, 2153 sizeof(ident_buf->media_serial)); 2154 2155 *ident_bufp = ident_buf; 2156 2157 return (0); 2158 } 2159 2160 2161 static int 2162 ataidentify(struct cam_device *device, int retry_count, int timeout) 2163 { 2164 union ccb *ccb; 2165 struct ata_params *ident_buf; 2166 u_int64_t hpasize; 2167 2168 if ((ccb = cam_getccb(device)) == NULL) { 2169 warnx("couldn't allocate CCB"); 2170 return (1); 2171 } 2172 2173 if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) { 2174 cam_freeccb(ccb); 2175 return (1); 2176 } 2177 2178 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) { 2179 if (ata_read_native_max(device, retry_count, timeout, ccb, 2180 ident_buf, &hpasize) != 0) { 2181 cam_freeccb(ccb); 2182 return (1); 2183 } 2184 } else { 2185 hpasize = 0; 2186 } 2187 2188 printf("%s%d: ", device->device_name, device->dev_unit_num); 2189 ata_print_ident(ident_buf); 2190 camxferrate(device); 2191 atacapprint(ident_buf); 2192 atahpa_print(ident_buf, hpasize, 0); 2193 2194 free(ident_buf); 2195 cam_freeccb(ccb); 2196 2197 return (0); 2198 } 2199 #endif /* MINIMALISTIC */ 2200 2201 2202 #ifndef MINIMALISTIC 2203 enum { 2204 ATA_SECURITY_ACTION_PRINT, 2205 ATA_SECURITY_ACTION_FREEZE, 2206 ATA_SECURITY_ACTION_UNLOCK, 2207 ATA_SECURITY_ACTION_DISABLE, 2208 ATA_SECURITY_ACTION_ERASE, 2209 ATA_SECURITY_ACTION_ERASE_ENHANCED, 2210 ATA_SECURITY_ACTION_SET_PASSWORD 2211 }; 2212 2213 static void 2214 atasecurity_print_time(u_int16_t tw) 2215 { 2216 2217 if (tw == 0) 2218 printf("unspecified"); 2219 else if (tw >= 255) 2220 printf("> 508 min"); 2221 else 2222 printf("%i min", 2 * tw); 2223 } 2224 2225 static u_int32_t 2226 atasecurity_erase_timeout_msecs(u_int16_t timeout) 2227 { 2228 2229 if (timeout == 0) 2230 return 2 * 3600 * 1000; /* default: two hours */ 2231 else if (timeout > 255) 2232 return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */ 2233 2234 return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */ 2235 } 2236 2237 2238 static void 2239 atasecurity_notify(u_int8_t command, struct ata_security_password *pwd) 2240 { 2241 struct ata_cmd cmd; 2242 2243 bzero(&cmd, sizeof(cmd)); 2244 cmd.command = command; 2245 printf("Issuing %s", ata_op_string(&cmd)); 2246 2247 if (pwd != NULL) { 2248 char pass[sizeof(pwd->password)+1]; 2249 2250 /* pwd->password may not be null terminated */ 2251 pass[sizeof(pwd->password)] = '\0'; 2252 strncpy(pass, pwd->password, sizeof(pwd->password)); 2253 printf(" password='%s', user='%s'", 2254 pass, 2255 (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ? 2256 "master" : "user"); 2257 2258 if (command == ATA_SECURITY_SET_PASSWORD) { 2259 printf(", mode='%s'", 2260 (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ? 2261 "maximum" : "high"); 2262 } 2263 } 2264 2265 printf("\n"); 2266 } 2267 2268 static int 2269 atasecurity_freeze(struct cam_device *device, union ccb *ccb, 2270 int retry_count, u_int32_t timeout, int quiet) 2271 { 2272 2273 if (quiet == 0) 2274 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL); 2275 2276 return ata_do_28bit_cmd(device, 2277 ccb, 2278 retry_count, 2279 /*flags*/CAM_DIR_NONE, 2280 /*protocol*/AP_PROTO_NON_DATA, 2281 /*tag_action*/MSG_SIMPLE_Q_TAG, 2282 /*command*/ATA_SECURITY_FREEZE_LOCK, 2283 /*features*/0, 2284 /*lba*/0, 2285 /*sector_count*/0, 2286 /*data_ptr*/NULL, 2287 /*dxfer_len*/0, 2288 /*timeout*/timeout, 2289 /*quiet*/0); 2290 } 2291 2292 static int 2293 atasecurity_unlock(struct cam_device *device, union ccb *ccb, 2294 int retry_count, u_int32_t timeout, 2295 struct ata_security_password *pwd, int quiet) 2296 { 2297 2298 if (quiet == 0) 2299 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd); 2300 2301 return ata_do_28bit_cmd(device, 2302 ccb, 2303 retry_count, 2304 /*flags*/CAM_DIR_OUT, 2305 /*protocol*/AP_PROTO_PIO_OUT, 2306 /*tag_action*/MSG_SIMPLE_Q_TAG, 2307 /*command*/ATA_SECURITY_UNLOCK, 2308 /*features*/0, 2309 /*lba*/0, 2310 /*sector_count*/0, 2311 /*data_ptr*/(u_int8_t *)pwd, 2312 /*dxfer_len*/sizeof(*pwd), 2313 /*timeout*/timeout, 2314 /*quiet*/0); 2315 } 2316 2317 static int 2318 atasecurity_disable(struct cam_device *device, union ccb *ccb, 2319 int retry_count, u_int32_t timeout, 2320 struct ata_security_password *pwd, int quiet) 2321 { 2322 2323 if (quiet == 0) 2324 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd); 2325 return ata_do_28bit_cmd(device, 2326 ccb, 2327 retry_count, 2328 /*flags*/CAM_DIR_OUT, 2329 /*protocol*/AP_PROTO_PIO_OUT, 2330 /*tag_action*/MSG_SIMPLE_Q_TAG, 2331 /*command*/ATA_SECURITY_DISABLE_PASSWORD, 2332 /*features*/0, 2333 /*lba*/0, 2334 /*sector_count*/0, 2335 /*data_ptr*/(u_int8_t *)pwd, 2336 /*dxfer_len*/sizeof(*pwd), 2337 /*timeout*/timeout, 2338 /*quiet*/0); 2339 } 2340 2341 2342 static int 2343 atasecurity_erase_confirm(struct cam_device *device, 2344 struct ata_params* ident_buf) 2345 { 2346 2347 printf("\nYou are about to ERASE ALL DATA from the following" 2348 " device:\n%s%d,%s%d: ", device->device_name, 2349 device->dev_unit_num, device->given_dev_name, 2350 device->given_unit_number); 2351 ata_print_ident(ident_buf); 2352 2353 for(;;) { 2354 char str[50]; 2355 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) "); 2356 2357 if (fgets(str, sizeof(str), stdin) != NULL) { 2358 if (strncasecmp(str, "yes", 3) == 0) { 2359 return (1); 2360 } else if (strncasecmp(str, "no", 2) == 0) { 2361 return (0); 2362 } else { 2363 printf("Please answer \"yes\" or " 2364 "\"no\"\n"); 2365 } 2366 } 2367 } 2368 2369 /* NOTREACHED */ 2370 return (0); 2371 } 2372 2373 static int 2374 atasecurity_erase(struct cam_device *device, union ccb *ccb, 2375 int retry_count, u_int32_t timeout, 2376 u_int32_t erase_timeout, 2377 struct ata_security_password *pwd, int quiet) 2378 { 2379 int error; 2380 2381 if (quiet == 0) 2382 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL); 2383 2384 error = ata_do_28bit_cmd(device, 2385 ccb, 2386 retry_count, 2387 /*flags*/CAM_DIR_NONE, 2388 /*protocol*/AP_PROTO_NON_DATA, 2389 /*tag_action*/MSG_SIMPLE_Q_TAG, 2390 /*command*/ATA_SECURITY_ERASE_PREPARE, 2391 /*features*/0, 2392 /*lba*/0, 2393 /*sector_count*/0, 2394 /*data_ptr*/NULL, 2395 /*dxfer_len*/0, 2396 /*timeout*/timeout, 2397 /*quiet*/0); 2398 2399 if (error != 0) 2400 return error; 2401 2402 if (quiet == 0) 2403 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd); 2404 2405 error = ata_do_28bit_cmd(device, 2406 ccb, 2407 retry_count, 2408 /*flags*/CAM_DIR_OUT, 2409 /*protocol*/AP_PROTO_PIO_OUT, 2410 /*tag_action*/MSG_SIMPLE_Q_TAG, 2411 /*command*/ATA_SECURITY_ERASE_UNIT, 2412 /*features*/0, 2413 /*lba*/0, 2414 /*sector_count*/0, 2415 /*data_ptr*/(u_int8_t *)pwd, 2416 /*dxfer_len*/sizeof(*pwd), 2417 /*timeout*/erase_timeout, 2418 /*quiet*/0); 2419 2420 if (error == 0 && quiet == 0) 2421 printf("\nErase Complete\n"); 2422 2423 return error; 2424 } 2425 2426 static int 2427 atasecurity_set_password(struct cam_device *device, union ccb *ccb, 2428 int retry_count, u_int32_t timeout, 2429 struct ata_security_password *pwd, int quiet) 2430 { 2431 2432 if (quiet == 0) 2433 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd); 2434 2435 return ata_do_28bit_cmd(device, 2436 ccb, 2437 retry_count, 2438 /*flags*/CAM_DIR_OUT, 2439 /*protocol*/AP_PROTO_PIO_OUT, 2440 /*tag_action*/MSG_SIMPLE_Q_TAG, 2441 /*command*/ATA_SECURITY_SET_PASSWORD, 2442 /*features*/0, 2443 /*lba*/0, 2444 /*sector_count*/0, 2445 /*data_ptr*/(u_int8_t *)pwd, 2446 /*dxfer_len*/sizeof(*pwd), 2447 /*timeout*/timeout, 2448 /*quiet*/0); 2449 } 2450 2451 static void 2452 atasecurity_print(struct ata_params *parm) 2453 { 2454 2455 printf("\nSecurity Option Value\n"); 2456 if (arglist & CAM_ARG_VERBOSE) { 2457 printf("status %04x\n", 2458 parm->security_status); 2459 } 2460 printf("supported %s\n", 2461 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no"); 2462 if (!(parm->security_status & ATA_SECURITY_SUPPORTED)) 2463 return; 2464 printf("enabled %s\n", 2465 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no"); 2466 printf("drive locked %s\n", 2467 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no"); 2468 printf("security config frozen %s\n", 2469 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no"); 2470 printf("count expired %s\n", 2471 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no"); 2472 printf("security level %s\n", 2473 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high"); 2474 printf("enhanced erase supported %s\n", 2475 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no"); 2476 printf("erase time "); 2477 atasecurity_print_time(parm->erase_time); 2478 printf("\n"); 2479 printf("enhanced erase time "); 2480 atasecurity_print_time(parm->enhanced_erase_time); 2481 printf("\n"); 2482 printf("master password rev %04x%s\n", 2483 parm->master_passwd_revision, 2484 parm->master_passwd_revision == 0x0000 || 2485 parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : ""); 2486 } 2487 2488 /* 2489 * Validates and copies the password in optarg to the passed buffer. 2490 * If the password in optarg is the same length as the buffer then 2491 * the data will still be copied but no null termination will occur. 2492 */ 2493 static int 2494 ata_getpwd(u_int8_t *passwd, int max, char opt) 2495 { 2496 int len; 2497 2498 len = strlen(optarg); 2499 if (len > max) { 2500 warnx("-%c password is too long", opt); 2501 return (1); 2502 } else if (len == 0) { 2503 warnx("-%c password is missing", opt); 2504 return (1); 2505 } else if (optarg[0] == '-'){ 2506 warnx("-%c password starts with '-' (generic arg?)", opt); 2507 return (1); 2508 } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) { 2509 warnx("-%c password conflicts with existing password from -%c", 2510 opt, pwd_opt); 2511 return (1); 2512 } 2513 2514 /* Callers pass in a buffer which does NOT need to be terminated */ 2515 strncpy(passwd, optarg, max); 2516 pwd_opt = opt; 2517 2518 return (0); 2519 } 2520 2521 enum { 2522 ATA_HPA_ACTION_PRINT, 2523 ATA_HPA_ACTION_SET_MAX, 2524 ATA_HPA_ACTION_SET_PWD, 2525 ATA_HPA_ACTION_LOCK, 2526 ATA_HPA_ACTION_UNLOCK, 2527 ATA_HPA_ACTION_FREEZE_LOCK 2528 }; 2529 2530 static int 2531 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf, 2532 u_int64_t maxsize, int persist) 2533 { 2534 printf("\nYou are about to configure HPA to limit the user accessible\n" 2535 "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize, 2536 persist ? "persistently" : "temporarily", 2537 device->device_name, device->dev_unit_num, 2538 device->given_dev_name, device->given_unit_number); 2539 ata_print_ident(ident_buf); 2540 2541 for(;;) { 2542 char str[50]; 2543 printf("\nAre you SURE you want to configure HPA? (yes/no) "); 2544 2545 if (NULL != fgets(str, sizeof(str), stdin)) { 2546 if (0 == strncasecmp(str, "yes", 3)) { 2547 return (1); 2548 } else if (0 == strncasecmp(str, "no", 2)) { 2549 return (0); 2550 } else { 2551 printf("Please answer \"yes\" or " 2552 "\"no\"\n"); 2553 } 2554 } 2555 } 2556 2557 /* NOTREACHED */ 2558 return (0); 2559 } 2560 2561 static int 2562 atahpa(struct cam_device *device, int retry_count, int timeout, 2563 int argc, char **argv, char *combinedopt) 2564 { 2565 union ccb *ccb; 2566 struct ata_params *ident_buf; 2567 struct ccb_getdev cgd; 2568 struct ata_set_max_pwd pwd; 2569 int error, confirm, quiet, c, action, actions, setpwd, persist; 2570 int security, is48bit, pwdsize; 2571 u_int64_t hpasize, maxsize; 2572 2573 actions = 0; 2574 setpwd = 0; 2575 confirm = 0; 2576 quiet = 0; 2577 maxsize = 0; 2578 persist = 0; 2579 security = 0; 2580 2581 memset(&pwd, 0, sizeof(pwd)); 2582 2583 /* default action is to print hpa information */ 2584 action = ATA_HPA_ACTION_PRINT; 2585 pwdsize = sizeof(pwd.password); 2586 2587 while ((c = getopt(argc, argv, combinedopt)) != -1) { 2588 switch(c){ 2589 case 's': 2590 action = ATA_HPA_ACTION_SET_MAX; 2591 maxsize = strtoumax(optarg, NULL, 0); 2592 actions++; 2593 break; 2594 2595 case 'p': 2596 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 2597 return (1); 2598 action = ATA_HPA_ACTION_SET_PWD; 2599 security = 1; 2600 actions++; 2601 break; 2602 2603 case 'l': 2604 action = ATA_HPA_ACTION_LOCK; 2605 security = 1; 2606 actions++; 2607 break; 2608 2609 case 'U': 2610 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 2611 return (1); 2612 action = ATA_HPA_ACTION_UNLOCK; 2613 security = 1; 2614 actions++; 2615 break; 2616 2617 case 'f': 2618 action = ATA_HPA_ACTION_FREEZE_LOCK; 2619 security = 1; 2620 actions++; 2621 break; 2622 2623 case 'P': 2624 persist = 1; 2625 break; 2626 2627 case 'y': 2628 confirm++; 2629 break; 2630 2631 case 'q': 2632 quiet++; 2633 break; 2634 } 2635 } 2636 2637 if (actions > 1) { 2638 warnx("too many hpa actions specified"); 2639 return (1); 2640 } 2641 2642 if (get_cgd(device, &cgd) != 0) { 2643 warnx("couldn't get CGD"); 2644 return (1); 2645 } 2646 2647 ccb = cam_getccb(device); 2648 if (ccb == NULL) { 2649 warnx("couldn't allocate CCB"); 2650 return (1); 2651 } 2652 2653 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf); 2654 if (error != 0) { 2655 cam_freeccb(ccb); 2656 return (1); 2657 } 2658 2659 if (quiet == 0) { 2660 printf("%s%d: ", device->device_name, device->dev_unit_num); 2661 ata_print_ident(ident_buf); 2662 camxferrate(device); 2663 } 2664 2665 if (action == ATA_HPA_ACTION_PRINT) { 2666 error = ata_read_native_max(device, retry_count, timeout, ccb, 2667 ident_buf, &hpasize); 2668 if (error == 0) 2669 atahpa_print(ident_buf, hpasize, 1); 2670 2671 cam_freeccb(ccb); 2672 free(ident_buf); 2673 return (error); 2674 } 2675 2676 if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) { 2677 warnx("HPA is not supported by this device"); 2678 cam_freeccb(ccb); 2679 free(ident_buf); 2680 return (1); 2681 } 2682 2683 if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) { 2684 warnx("HPA Security is not supported by this device"); 2685 cam_freeccb(ccb); 2686 free(ident_buf); 2687 return (1); 2688 } 2689 2690 is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48; 2691 2692 /* 2693 * The ATA spec requires: 2694 * 1. Read native max addr is called directly before set max addr 2695 * 2. Read native max addr is NOT called before any other set max call 2696 */ 2697 switch(action) { 2698 case ATA_HPA_ACTION_SET_MAX: 2699 if (confirm == 0 && 2700 atahpa_set_confirm(device, ident_buf, maxsize, 2701 persist) == 0) { 2702 cam_freeccb(ccb); 2703 free(ident_buf); 2704 return (1); 2705 } 2706 2707 error = ata_read_native_max(device, retry_count, timeout, 2708 ccb, ident_buf, &hpasize); 2709 if (error == 0) { 2710 error = atahpa_set_max(device, retry_count, timeout, 2711 ccb, is48bit, maxsize, persist); 2712 if (error == 0) { 2713 /* redo identify to get new lba values */ 2714 error = ata_do_identify(device, retry_count, 2715 timeout, ccb, 2716 &ident_buf); 2717 atahpa_print(ident_buf, hpasize, 1); 2718 } 2719 } 2720 break; 2721 2722 case ATA_HPA_ACTION_SET_PWD: 2723 error = atahpa_password(device, retry_count, timeout, 2724 ccb, is48bit, &pwd); 2725 if (error == 0) 2726 printf("HPA password has been set\n"); 2727 break; 2728 2729 case ATA_HPA_ACTION_LOCK: 2730 error = atahpa_lock(device, retry_count, timeout, 2731 ccb, is48bit); 2732 if (error == 0) 2733 printf("HPA has been locked\n"); 2734 break; 2735 2736 case ATA_HPA_ACTION_UNLOCK: 2737 error = atahpa_unlock(device, retry_count, timeout, 2738 ccb, is48bit, &pwd); 2739 if (error == 0) 2740 printf("HPA has been unlocked\n"); 2741 break; 2742 2743 case ATA_HPA_ACTION_FREEZE_LOCK: 2744 error = atahpa_freeze_lock(device, retry_count, timeout, 2745 ccb, is48bit); 2746 if (error == 0) 2747 printf("HPA has been frozen\n"); 2748 break; 2749 2750 default: 2751 errx(1, "Option currently not supported"); 2752 } 2753 2754 cam_freeccb(ccb); 2755 free(ident_buf); 2756 2757 return (error); 2758 } 2759 2760 static int 2761 atasecurity(struct cam_device *device, int retry_count, int timeout, 2762 int argc, char **argv, char *combinedopt) 2763 { 2764 union ccb *ccb; 2765 struct ata_params *ident_buf; 2766 int error, confirm, quiet, c, action, actions, setpwd; 2767 int security_enabled, erase_timeout, pwdsize; 2768 struct ata_security_password pwd; 2769 2770 actions = 0; 2771 setpwd = 0; 2772 erase_timeout = 0; 2773 confirm = 0; 2774 quiet = 0; 2775 2776 memset(&pwd, 0, sizeof(pwd)); 2777 2778 /* default action is to print security information */ 2779 action = ATA_SECURITY_ACTION_PRINT; 2780 2781 /* user is master by default as its safer that way */ 2782 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER; 2783 pwdsize = sizeof(pwd.password); 2784 2785 while ((c = getopt(argc, argv, combinedopt)) != -1) { 2786 switch(c){ 2787 case 'f': 2788 action = ATA_SECURITY_ACTION_FREEZE; 2789 actions++; 2790 break; 2791 2792 case 'U': 2793 if (strcasecmp(optarg, "user") == 0) { 2794 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER; 2795 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER; 2796 } else if (strcasecmp(optarg, "master") == 0) { 2797 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER; 2798 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER; 2799 } else { 2800 warnx("-U argument '%s' is invalid (must be " 2801 "'user' or 'master')", optarg); 2802 return (1); 2803 } 2804 break; 2805 2806 case 'l': 2807 if (strcasecmp(optarg, "high") == 0) { 2808 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH; 2809 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM; 2810 } else if (strcasecmp(optarg, "maximum") == 0) { 2811 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM; 2812 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH; 2813 } else { 2814 warnx("-l argument '%s' is unknown (must be " 2815 "'high' or 'maximum')", optarg); 2816 return (1); 2817 } 2818 break; 2819 2820 case 'k': 2821 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 2822 return (1); 2823 action = ATA_SECURITY_ACTION_UNLOCK; 2824 actions++; 2825 break; 2826 2827 case 'd': 2828 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 2829 return (1); 2830 action = ATA_SECURITY_ACTION_DISABLE; 2831 actions++; 2832 break; 2833 2834 case 'e': 2835 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 2836 return (1); 2837 action = ATA_SECURITY_ACTION_ERASE; 2838 actions++; 2839 break; 2840 2841 case 'h': 2842 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 2843 return (1); 2844 pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED; 2845 action = ATA_SECURITY_ACTION_ERASE_ENHANCED; 2846 actions++; 2847 break; 2848 2849 case 's': 2850 if (ata_getpwd(pwd.password, pwdsize, c) != 0) 2851 return (1); 2852 setpwd = 1; 2853 if (action == ATA_SECURITY_ACTION_PRINT) 2854 action = ATA_SECURITY_ACTION_SET_PASSWORD; 2855 /* 2856 * Don't increment action as this can be combined 2857 * with other actions. 2858 */ 2859 break; 2860 2861 case 'y': 2862 confirm++; 2863 break; 2864 2865 case 'q': 2866 quiet++; 2867 break; 2868 2869 case 'T': 2870 erase_timeout = atoi(optarg) * 1000; 2871 break; 2872 } 2873 } 2874 2875 if (actions > 1) { 2876 warnx("too many security actions specified"); 2877 return (1); 2878 } 2879 2880 if ((ccb = cam_getccb(device)) == NULL) { 2881 warnx("couldn't allocate CCB"); 2882 return (1); 2883 } 2884 2885 error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf); 2886 if (error != 0) { 2887 cam_freeccb(ccb); 2888 return (1); 2889 } 2890 2891 if (quiet == 0) { 2892 printf("%s%d: ", device->device_name, device->dev_unit_num); 2893 ata_print_ident(ident_buf); 2894 camxferrate(device); 2895 } 2896 2897 if (action == ATA_SECURITY_ACTION_PRINT) { 2898 atasecurity_print(ident_buf); 2899 free(ident_buf); 2900 cam_freeccb(ccb); 2901 return (0); 2902 } 2903 2904 if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) { 2905 warnx("Security not supported"); 2906 free(ident_buf); 2907 cam_freeccb(ccb); 2908 return (1); 2909 } 2910 2911 /* default timeout 15 seconds the same as linux hdparm */ 2912 timeout = timeout ? timeout : 15 * 1000; 2913 2914 security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED; 2915 2916 /* first set the password if requested */ 2917 if (setpwd == 1) { 2918 /* confirm we can erase before setting the password if erasing */ 2919 if (confirm == 0 && 2920 (action == ATA_SECURITY_ACTION_ERASE_ENHANCED || 2921 action == ATA_SECURITY_ACTION_ERASE) && 2922 atasecurity_erase_confirm(device, ident_buf) == 0) { 2923 cam_freeccb(ccb); 2924 free(ident_buf); 2925 return (error); 2926 } 2927 2928 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) { 2929 pwd.revision = ident_buf->master_passwd_revision; 2930 if (pwd.revision != 0 && pwd.revision != 0xfff && 2931 --pwd.revision == 0) { 2932 pwd.revision = 0xfffe; 2933 } 2934 } 2935 error = atasecurity_set_password(device, ccb, retry_count, 2936 timeout, &pwd, quiet); 2937 if (error != 0) { 2938 cam_freeccb(ccb); 2939 free(ident_buf); 2940 return (error); 2941 } 2942 security_enabled = 1; 2943 } 2944 2945 switch(action) { 2946 case ATA_SECURITY_ACTION_FREEZE: 2947 error = atasecurity_freeze(device, ccb, retry_count, 2948 timeout, quiet); 2949 break; 2950 2951 case ATA_SECURITY_ACTION_UNLOCK: 2952 if (security_enabled) { 2953 if (ident_buf->security_status & ATA_SECURITY_LOCKED) { 2954 error = atasecurity_unlock(device, ccb, 2955 retry_count, timeout, &pwd, quiet); 2956 } else { 2957 warnx("Can't unlock, drive is not locked"); 2958 error = 1; 2959 } 2960 } else { 2961 warnx("Can't unlock, security is disabled"); 2962 error = 1; 2963 } 2964 break; 2965 2966 case ATA_SECURITY_ACTION_DISABLE: 2967 if (security_enabled) { 2968 /* First unlock the drive if its locked */ 2969 if (ident_buf->security_status & ATA_SECURITY_LOCKED) { 2970 error = atasecurity_unlock(device, ccb, 2971 retry_count, 2972 timeout, 2973 &pwd, 2974 quiet); 2975 } 2976 2977 if (error == 0) { 2978 error = atasecurity_disable(device, 2979 ccb, 2980 retry_count, 2981 timeout, 2982 &pwd, 2983 quiet); 2984 } 2985 } else { 2986 warnx("Can't disable security (already disabled)"); 2987 error = 1; 2988 } 2989 break; 2990 2991 case ATA_SECURITY_ACTION_ERASE: 2992 if (security_enabled) { 2993 if (erase_timeout == 0) { 2994 erase_timeout = atasecurity_erase_timeout_msecs( 2995 ident_buf->erase_time); 2996 } 2997 2998 error = atasecurity_erase(device, ccb, retry_count, 2999 timeout, erase_timeout, &pwd, 3000 quiet); 3001 } else { 3002 warnx("Can't secure erase (security is disabled)"); 3003 error = 1; 3004 } 3005 break; 3006 3007 case ATA_SECURITY_ACTION_ERASE_ENHANCED: 3008 if (security_enabled) { 3009 if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) { 3010 if (erase_timeout == 0) { 3011 erase_timeout = 3012 atasecurity_erase_timeout_msecs( 3013 ident_buf->enhanced_erase_time); 3014 } 3015 3016 error = atasecurity_erase(device, ccb, 3017 retry_count, timeout, 3018 erase_timeout, &pwd, 3019 quiet); 3020 } else { 3021 warnx("Enhanced erase is not supported"); 3022 error = 1; 3023 } 3024 } else { 3025 warnx("Can't secure erase (enhanced), " 3026 "(security is disabled)"); 3027 error = 1; 3028 } 3029 break; 3030 } 3031 3032 cam_freeccb(ccb); 3033 free(ident_buf); 3034 3035 return (error); 3036 } 3037 #endif /* MINIMALISTIC */ 3038 3039 /* 3040 * Parse out a bus, or a bus, target and lun in the following 3041 * format: 3042 * bus 3043 * bus:target 3044 * bus:target:lun 3045 * 3046 * Returns the number of parsed components, or 0. 3047 */ 3048 static int 3049 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun, 3050 cam_argmask *arglst) 3051 { 3052 char *tmpstr; 3053 int convs = 0; 3054 3055 while (isspace(*tstr) && (*tstr != '\0')) 3056 tstr++; 3057 3058 tmpstr = (char *)strtok(tstr, ":"); 3059 if ((tmpstr != NULL) && (*tmpstr != '\0')) { 3060 *bus = strtol(tmpstr, NULL, 0); 3061 *arglst |= CAM_ARG_BUS; 3062 convs++; 3063 tmpstr = (char *)strtok(NULL, ":"); 3064 if ((tmpstr != NULL) && (*tmpstr != '\0')) { 3065 *target = strtol(tmpstr, NULL, 0); 3066 *arglst |= CAM_ARG_TARGET; 3067 convs++; 3068 tmpstr = (char *)strtok(NULL, ":"); 3069 if ((tmpstr != NULL) && (*tmpstr != '\0')) { 3070 *lun = strtol(tmpstr, NULL, 0); 3071 *arglst |= CAM_ARG_LUN; 3072 convs++; 3073 } 3074 } 3075 } 3076 3077 return convs; 3078 } 3079 3080 static int 3081 dorescan_or_reset(int argc, char **argv, int rescan) 3082 { 3083 static const char must[] = 3084 "you must specify \"all\", a bus, or a bus:target:lun to %s"; 3085 int rv, error = 0; 3086 path_id_t bus = CAM_BUS_WILDCARD; 3087 target_id_t target = CAM_TARGET_WILDCARD; 3088 lun_id_t lun = CAM_LUN_WILDCARD; 3089 char *tstr; 3090 3091 if (argc < 3) { 3092 warnx(must, rescan? "rescan" : "reset"); 3093 return(1); 3094 } 3095 3096 tstr = argv[optind]; 3097 while (isspace(*tstr) && (*tstr != '\0')) 3098 tstr++; 3099 if (strncasecmp(tstr, "all", strlen("all")) == 0) 3100 arglist |= CAM_ARG_BUS; 3101 else { 3102 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist); 3103 if (rv != 1 && rv != 3) { 3104 warnx(must, rescan? "rescan" : "reset"); 3105 return(1); 3106 } 3107 } 3108 3109 if ((arglist & CAM_ARG_BUS) 3110 && (arglist & CAM_ARG_TARGET) 3111 && (arglist & CAM_ARG_LUN)) 3112 error = scanlun_or_reset_dev(bus, target, lun, rescan); 3113 else 3114 error = rescan_or_reset_bus(bus, rescan); 3115 3116 return(error); 3117 } 3118 3119 static int 3120 rescan_or_reset_bus(path_id_t bus, int rescan) 3121 { 3122 union ccb ccb, matchccb; 3123 int fd, retval; 3124 int bufsize; 3125 3126 retval = 0; 3127 3128 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { 3129 warnx("error opening transport layer device %s", XPT_DEVICE); 3130 warn("%s", XPT_DEVICE); 3131 return(1); 3132 } 3133 3134 if (bus != CAM_BUS_WILDCARD) { 3135 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS; 3136 ccb.ccb_h.path_id = bus; 3137 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 3138 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 3139 ccb.crcn.flags = CAM_FLAG_NONE; 3140 3141 /* run this at a low priority */ 3142 ccb.ccb_h.pinfo.priority = 5; 3143 3144 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 3145 warn("CAMIOCOMMAND ioctl failed"); 3146 close(fd); 3147 return(1); 3148 } 3149 3150 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { 3151 fprintf(stdout, "%s of bus %d was successful\n", 3152 rescan ? "Re-scan" : "Reset", bus); 3153 } else { 3154 fprintf(stdout, "%s of bus %d returned error %#x\n", 3155 rescan ? "Re-scan" : "Reset", bus, 3156 ccb.ccb_h.status & CAM_STATUS_MASK); 3157 retval = 1; 3158 } 3159 3160 close(fd); 3161 return(retval); 3162 3163 } 3164 3165 3166 /* 3167 * The right way to handle this is to modify the xpt so that it can 3168 * handle a wildcarded bus in a rescan or reset CCB. At the moment 3169 * that isn't implemented, so instead we enumerate the busses and 3170 * send the rescan or reset to those busses in the case where the 3171 * given bus is -1 (wildcard). We don't send a rescan or reset 3172 * to the xpt bus; sending a rescan to the xpt bus is effectively a 3173 * no-op, sending a rescan to the xpt bus would result in a status of 3174 * CAM_REQ_INVALID. 3175 */ 3176 bzero(&(&matchccb.ccb_h)[1], 3177 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr)); 3178 matchccb.ccb_h.func_code = XPT_DEV_MATCH; 3179 matchccb.ccb_h.path_id = CAM_BUS_WILDCARD; 3180 bufsize = sizeof(struct dev_match_result) * 20; 3181 matchccb.cdm.match_buf_len = bufsize; 3182 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize); 3183 if (matchccb.cdm.matches == NULL) { 3184 warnx("can't malloc memory for matches"); 3185 retval = 1; 3186 goto bailout; 3187 } 3188 matchccb.cdm.num_matches = 0; 3189 3190 matchccb.cdm.num_patterns = 1; 3191 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern); 3192 3193 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc( 3194 matchccb.cdm.pattern_buf_len); 3195 if (matchccb.cdm.patterns == NULL) { 3196 warnx("can't malloc memory for patterns"); 3197 retval = 1; 3198 goto bailout; 3199 } 3200 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS; 3201 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY; 3202 3203 do { 3204 unsigned int i; 3205 3206 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) { 3207 warn("CAMIOCOMMAND ioctl failed"); 3208 retval = 1; 3209 goto bailout; 3210 } 3211 3212 if ((matchccb.ccb_h.status != CAM_REQ_CMP) 3213 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST) 3214 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) { 3215 warnx("got CAM error %#x, CDM error %d\n", 3216 matchccb.ccb_h.status, matchccb.cdm.status); 3217 retval = 1; 3218 goto bailout; 3219 } 3220 3221 for (i = 0; i < matchccb.cdm.num_matches; i++) { 3222 struct bus_match_result *bus_result; 3223 3224 /* This shouldn't happen. */ 3225 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS) 3226 continue; 3227 3228 bus_result = &matchccb.cdm.matches[i].result.bus_result; 3229 3230 /* 3231 * We don't want to rescan or reset the xpt bus. 3232 * See above. 3233 */ 3234 if (bus_result->path_id == CAM_XPT_PATH_ID) 3235 continue; 3236 3237 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : 3238 XPT_RESET_BUS; 3239 ccb.ccb_h.path_id = bus_result->path_id; 3240 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 3241 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 3242 ccb.crcn.flags = CAM_FLAG_NONE; 3243 3244 /* run this at a low priority */ 3245 ccb.ccb_h.pinfo.priority = 5; 3246 3247 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 3248 warn("CAMIOCOMMAND ioctl failed"); 3249 retval = 1; 3250 goto bailout; 3251 } 3252 3253 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){ 3254 fprintf(stdout, "%s of bus %d was successful\n", 3255 rescan? "Re-scan" : "Reset", 3256 bus_result->path_id); 3257 } else { 3258 /* 3259 * Don't bail out just yet, maybe the other 3260 * rescan or reset commands will complete 3261 * successfully. 3262 */ 3263 fprintf(stderr, "%s of bus %d returned error " 3264 "%#x\n", rescan? "Re-scan" : "Reset", 3265 bus_result->path_id, 3266 ccb.ccb_h.status & CAM_STATUS_MASK); 3267 retval = 1; 3268 } 3269 } 3270 } while ((matchccb.ccb_h.status == CAM_REQ_CMP) 3271 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE)); 3272 3273 bailout: 3274 3275 if (fd != -1) 3276 close(fd); 3277 3278 if (matchccb.cdm.patterns != NULL) 3279 free(matchccb.cdm.patterns); 3280 if (matchccb.cdm.matches != NULL) 3281 free(matchccb.cdm.matches); 3282 3283 return(retval); 3284 } 3285 3286 static int 3287 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan) 3288 { 3289 union ccb ccb; 3290 struct cam_device *device; 3291 int fd; 3292 3293 device = NULL; 3294 3295 if (bus == CAM_BUS_WILDCARD) { 3296 warnx("invalid bus number %d", bus); 3297 return(1); 3298 } 3299 3300 if (target == CAM_TARGET_WILDCARD) { 3301 warnx("invalid target number %d", target); 3302 return(1); 3303 } 3304 3305 if (lun == CAM_LUN_WILDCARD) { 3306 warnx("invalid lun number %jx", (uintmax_t)lun); 3307 return(1); 3308 } 3309 3310 fd = -1; 3311 3312 bzero(&ccb, sizeof(union ccb)); 3313 3314 if (scan) { 3315 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { 3316 warnx("error opening transport layer device %s\n", 3317 XPT_DEVICE); 3318 warn("%s", XPT_DEVICE); 3319 return(1); 3320 } 3321 } else { 3322 device = cam_open_btl(bus, target, lun, O_RDWR, NULL); 3323 if (device == NULL) { 3324 warnx("%s", cam_errbuf); 3325 return(1); 3326 } 3327 } 3328 3329 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV; 3330 ccb.ccb_h.path_id = bus; 3331 ccb.ccb_h.target_id = target; 3332 ccb.ccb_h.target_lun = lun; 3333 ccb.ccb_h.timeout = 5000; 3334 ccb.crcn.flags = CAM_FLAG_NONE; 3335 3336 /* run this at a low priority */ 3337 ccb.ccb_h.pinfo.priority = 5; 3338 3339 if (scan) { 3340 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) { 3341 warn("CAMIOCOMMAND ioctl failed"); 3342 close(fd); 3343 return(1); 3344 } 3345 } else { 3346 if (cam_send_ccb(device, &ccb) < 0) { 3347 warn("error sending XPT_RESET_DEV CCB"); 3348 cam_close_device(device); 3349 return(1); 3350 } 3351 } 3352 3353 if (scan) 3354 close(fd); 3355 else 3356 cam_close_device(device); 3357 3358 /* 3359 * An error code of CAM_BDR_SENT is normal for a BDR request. 3360 */ 3361 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 3362 || ((!scan) 3363 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) { 3364 fprintf(stdout, "%s of %d:%d:%jx was successful\n", 3365 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun); 3366 return(0); 3367 } else { 3368 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n", 3369 scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun, 3370 ccb.ccb_h.status & CAM_STATUS_MASK); 3371 return(1); 3372 } 3373 } 3374 3375 #ifndef MINIMALISTIC 3376 3377 static struct scsi_nv defect_list_type_map[] = { 3378 { "block", SRDD10_BLOCK_FORMAT }, 3379 { "extbfi", SRDD10_EXT_BFI_FORMAT }, 3380 { "extphys", SRDD10_EXT_PHYS_FORMAT }, 3381 { "longblock", SRDD10_LONG_BLOCK_FORMAT }, 3382 { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT }, 3383 { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT } 3384 }; 3385 3386 static int 3387 readdefects(struct cam_device *device, int argc, char **argv, 3388 char *combinedopt, int retry_count, int timeout) 3389 { 3390 union ccb *ccb = NULL; 3391 struct scsi_read_defect_data_hdr_10 *hdr10 = NULL; 3392 struct scsi_read_defect_data_hdr_12 *hdr12 = NULL; 3393 size_t hdr_size = 0, entry_size = 0; 3394 int use_12byte = 0; 3395 int hex_format = 0; 3396 u_int8_t *defect_list = NULL; 3397 u_int8_t list_format = 0; 3398 int list_type_set = 0; 3399 u_int32_t dlist_length = 0; 3400 u_int32_t returned_length = 0, valid_len = 0; 3401 u_int32_t num_returned = 0, num_valid = 0; 3402 u_int32_t max_possible_size = 0, hdr_max = 0; 3403 u_int32_t starting_offset = 0; 3404 u_int8_t returned_format, returned_type; 3405 unsigned int i; 3406 int summary = 0, quiet = 0; 3407 int c, error = 0; 3408 int lists_specified = 0; 3409 int get_length = 1, first_pass = 1; 3410 int mads = 0; 3411 3412 while ((c = getopt(argc, argv, combinedopt)) != -1) { 3413 switch(c){ 3414 case 'f': 3415 { 3416 scsi_nv_status status; 3417 int entry_num = 0; 3418 3419 status = scsi_get_nv(defect_list_type_map, 3420 sizeof(defect_list_type_map) / 3421 sizeof(defect_list_type_map[0]), optarg, 3422 &entry_num, SCSI_NV_FLAG_IG_CASE); 3423 3424 if (status == SCSI_NV_FOUND) { 3425 list_format = defect_list_type_map[ 3426 entry_num].value; 3427 list_type_set = 1; 3428 } else { 3429 warnx("%s: %s %s option %s", __func__, 3430 (status == SCSI_NV_AMBIGUOUS) ? 3431 "ambiguous" : "invalid", "defect list type", 3432 optarg); 3433 error = 1; 3434 goto defect_bailout; 3435 } 3436 break; 3437 } 3438 case 'G': 3439 arglist |= CAM_ARG_GLIST; 3440 break; 3441 case 'P': 3442 arglist |= CAM_ARG_PLIST; 3443 break; 3444 case 'q': 3445 quiet = 1; 3446 break; 3447 case 's': 3448 summary = 1; 3449 break; 3450 case 'S': { 3451 char *endptr; 3452 3453 starting_offset = strtoul(optarg, &endptr, 0); 3454 if (*endptr != '\0') { 3455 error = 1; 3456 warnx("invalid starting offset %s", optarg); 3457 goto defect_bailout; 3458 } 3459 break; 3460 } 3461 case 'X': 3462 hex_format = 1; 3463 break; 3464 default: 3465 break; 3466 } 3467 } 3468 3469 if (list_type_set == 0) { 3470 error = 1; 3471 warnx("no defect list format specified"); 3472 goto defect_bailout; 3473 } 3474 3475 if (arglist & CAM_ARG_PLIST) { 3476 list_format |= SRDD10_PLIST; 3477 lists_specified++; 3478 } 3479 3480 if (arglist & CAM_ARG_GLIST) { 3481 list_format |= SRDD10_GLIST; 3482 lists_specified++; 3483 } 3484 3485 /* 3486 * This implies a summary, and was the previous behavior. 3487 */ 3488 if (lists_specified == 0) 3489 summary = 1; 3490 3491 ccb = cam_getccb(device); 3492 3493 retry_12byte: 3494 3495 /* 3496 * We start off asking for just the header to determine how much 3497 * defect data is available. Some Hitachi drives return an error 3498 * if you ask for more data than the drive has. Once we know the 3499 * length, we retry the command with the returned length. 3500 */ 3501 if (use_12byte == 0) 3502 dlist_length = sizeof(*hdr10); 3503 else 3504 dlist_length = sizeof(*hdr12); 3505 3506 retry: 3507 if (defect_list != NULL) { 3508 free(defect_list); 3509 defect_list = NULL; 3510 } 3511 defect_list = malloc(dlist_length); 3512 if (defect_list == NULL) { 3513 warnx("can't malloc memory for defect list"); 3514 error = 1; 3515 goto defect_bailout; 3516 } 3517 3518 next_batch: 3519 bzero(defect_list, dlist_length); 3520 3521 /* 3522 * cam_getccb() zeros the CCB header only. So we need to zero the 3523 * payload portion of the ccb. 3524 */ 3525 bzero(&(&ccb->ccb_h)[1], 3526 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 3527 3528 scsi_read_defects(&ccb->csio, 3529 /*retries*/ retry_count, 3530 /*cbfcnp*/ NULL, 3531 /*tag_action*/ MSG_SIMPLE_Q_TAG, 3532 /*list_format*/ list_format, 3533 /*addr_desc_index*/ starting_offset, 3534 /*data_ptr*/ defect_list, 3535 /*dxfer_len*/ dlist_length, 3536 /*minimum_cmd_size*/ use_12byte ? 12 : 0, 3537 /*sense_len*/ SSD_FULL_SIZE, 3538 /*timeout*/ timeout ? timeout : 5000); 3539 3540 /* Disable freezing the device queue */ 3541 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 3542 3543 if (cam_send_ccb(device, ccb) < 0) { 3544 perror("error reading defect list"); 3545 3546 if (arglist & CAM_ARG_VERBOSE) { 3547 cam_error_print(device, ccb, CAM_ESF_ALL, 3548 CAM_EPF_ALL, stderr); 3549 } 3550 3551 error = 1; 3552 goto defect_bailout; 3553 } 3554 3555 valid_len = ccb->csio.dxfer_len - ccb->csio.resid; 3556 3557 if (use_12byte == 0) { 3558 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list; 3559 hdr_size = sizeof(*hdr10); 3560 hdr_max = SRDDH10_MAX_LENGTH; 3561 3562 if (valid_len >= hdr_size) { 3563 returned_length = scsi_2btoul(hdr10->length); 3564 returned_format = hdr10->format; 3565 } else { 3566 returned_length = 0; 3567 returned_format = 0; 3568 } 3569 } else { 3570 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list; 3571 hdr_size = sizeof(*hdr12); 3572 hdr_max = SRDDH12_MAX_LENGTH; 3573 3574 if (valid_len >= hdr_size) { 3575 returned_length = scsi_4btoul(hdr12->length); 3576 returned_format = hdr12->format; 3577 } else { 3578 returned_length = 0; 3579 returned_format = 0; 3580 } 3581 } 3582 3583 returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK; 3584 switch (returned_type) { 3585 case SRDD10_BLOCK_FORMAT: 3586 entry_size = sizeof(struct scsi_defect_desc_block); 3587 break; 3588 case SRDD10_LONG_BLOCK_FORMAT: 3589 entry_size = sizeof(struct scsi_defect_desc_long_block); 3590 break; 3591 case SRDD10_EXT_PHYS_FORMAT: 3592 case SRDD10_PHYSICAL_SECTOR_FORMAT: 3593 entry_size = sizeof(struct scsi_defect_desc_phys_sector); 3594 break; 3595 case SRDD10_EXT_BFI_FORMAT: 3596 case SRDD10_BYTES_FROM_INDEX_FORMAT: 3597 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index); 3598 break; 3599 default: 3600 warnx("Unknown defect format 0x%x\n", returned_type); 3601 error = 1; 3602 goto defect_bailout; 3603 break; 3604 } 3605 3606 max_possible_size = (hdr_max / entry_size) * entry_size; 3607 num_returned = returned_length / entry_size; 3608 num_valid = min(returned_length, valid_len - hdr_size); 3609 num_valid /= entry_size; 3610 3611 if (get_length != 0) { 3612 get_length = 0; 3613 3614 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 3615 CAM_SCSI_STATUS_ERROR) { 3616 struct scsi_sense_data *sense; 3617 int error_code, sense_key, asc, ascq; 3618 3619 sense = &ccb->csio.sense_data; 3620 scsi_extract_sense_len(sense, ccb->csio.sense_len - 3621 ccb->csio.sense_resid, &error_code, &sense_key, 3622 &asc, &ascq, /*show_errors*/ 1); 3623 3624 /* 3625 * If the drive is reporting that it just doesn't 3626 * support the defect list format, go ahead and use 3627 * the length it reported. Otherwise, the length 3628 * may not be valid, so use the maximum. 3629 */ 3630 if ((sense_key == SSD_KEY_RECOVERED_ERROR) 3631 && (asc == 0x1c) && (ascq == 0x00) 3632 && (returned_length > 0)) { 3633 if ((use_12byte == 0) 3634 && (returned_length >= max_possible_size)) { 3635 get_length = 1; 3636 use_12byte = 1; 3637 goto retry_12byte; 3638 } 3639 dlist_length = returned_length + hdr_size; 3640 } else if ((sense_key == SSD_KEY_RECOVERED_ERROR) 3641 && (asc == 0x1f) && (ascq == 0x00) 3642 && (returned_length > 0)) { 3643 /* Partial defect list transfer */ 3644 /* 3645 * Hitachi drives return this error 3646 * along with a partial defect list if they 3647 * have more defects than the 10 byte 3648 * command can support. Retry with the 12 3649 * byte command. 3650 */ 3651 if (use_12byte == 0) { 3652 get_length = 1; 3653 use_12byte = 1; 3654 goto retry_12byte; 3655 } 3656 dlist_length = returned_length + hdr_size; 3657 } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST) 3658 && (asc == 0x24) && (ascq == 0x00)) { 3659 /* Invalid field in CDB */ 3660 /* 3661 * SBC-3 says that if the drive has more 3662 * defects than can be reported with the 3663 * 10 byte command, it should return this 3664 * error and no data. Retry with the 12 3665 * byte command. 3666 */ 3667 if (use_12byte == 0) { 3668 get_length = 1; 3669 use_12byte = 1; 3670 goto retry_12byte; 3671 } 3672 dlist_length = returned_length + hdr_size; 3673 } else { 3674 /* 3675 * If we got a SCSI error and no valid length, 3676 * just use the 10 byte maximum. The 12 3677 * byte maximum is too large. 3678 */ 3679 if (returned_length == 0) 3680 dlist_length = SRDD10_MAX_LENGTH; 3681 else { 3682 if ((use_12byte == 0) 3683 && (returned_length >= 3684 max_possible_size)) { 3685 get_length = 1; 3686 use_12byte = 1; 3687 goto retry_12byte; 3688 } 3689 dlist_length = returned_length + 3690 hdr_size; 3691 } 3692 } 3693 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != 3694 CAM_REQ_CMP){ 3695 error = 1; 3696 warnx("Error reading defect header"); 3697 if (arglist & CAM_ARG_VERBOSE) 3698 cam_error_print(device, ccb, CAM_ESF_ALL, 3699 CAM_EPF_ALL, stderr); 3700 goto defect_bailout; 3701 } else { 3702 if ((use_12byte == 0) 3703 && (returned_length >= max_possible_size)) { 3704 get_length = 1; 3705 use_12byte = 1; 3706 goto retry_12byte; 3707 } 3708 dlist_length = returned_length + hdr_size; 3709 } 3710 if (summary != 0) { 3711 fprintf(stdout, "%u", num_returned); 3712 if (quiet == 0) { 3713 fprintf(stdout, " defect%s", 3714 (num_returned != 1) ? "s" : ""); 3715 } 3716 fprintf(stdout, "\n"); 3717 3718 goto defect_bailout; 3719 } 3720 3721 /* 3722 * We always limit the list length to the 10-byte maximum 3723 * length (0xffff). The reason is that some controllers 3724 * can't handle larger I/Os, and we can transfer the entire 3725 * 10 byte list in one shot. For drives that support the 12 3726 * byte read defects command, we'll step through the list 3727 * by specifying a starting offset. For drives that don't 3728 * support the 12 byte command's starting offset, we'll 3729 * just display the first 64K. 3730 */ 3731 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH); 3732 3733 goto retry; 3734 } 3735 3736 3737 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) 3738 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) 3739 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 3740 struct scsi_sense_data *sense; 3741 int error_code, sense_key, asc, ascq; 3742 3743 sense = &ccb->csio.sense_data; 3744 scsi_extract_sense_len(sense, ccb->csio.sense_len - 3745 ccb->csio.sense_resid, &error_code, &sense_key, &asc, 3746 &ascq, /*show_errors*/ 1); 3747 3748 /* 3749 * According to the SCSI spec, if the disk doesn't support 3750 * the requested format, it will generally return a sense 3751 * key of RECOVERED ERROR, and an additional sense code 3752 * of "DEFECT LIST NOT FOUND". HGST drives also return 3753 * Primary/Grown defect list not found errors. So just 3754 * check for an ASC of 0x1c. 3755 */ 3756 if ((sense_key == SSD_KEY_RECOVERED_ERROR) 3757 && (asc == 0x1c)) { 3758 const char *format_str; 3759 3760 format_str = scsi_nv_to_str(defect_list_type_map, 3761 sizeof(defect_list_type_map) / 3762 sizeof(defect_list_type_map[0]), 3763 list_format & SRDD10_DLIST_FORMAT_MASK); 3764 warnx("requested defect format %s not available", 3765 format_str ? format_str : "unknown"); 3766 3767 format_str = scsi_nv_to_str(defect_list_type_map, 3768 sizeof(defect_list_type_map) / 3769 sizeof(defect_list_type_map[0]), returned_type); 3770 if (format_str != NULL) { 3771 warnx("Device returned %s format", 3772 format_str); 3773 } else { 3774 error = 1; 3775 warnx("Device returned unknown defect" 3776 " data format %#x", returned_type); 3777 goto defect_bailout; 3778 } 3779 } else { 3780 error = 1; 3781 warnx("Error returned from read defect data command"); 3782 if (arglist & CAM_ARG_VERBOSE) 3783 cam_error_print(device, ccb, CAM_ESF_ALL, 3784 CAM_EPF_ALL, stderr); 3785 goto defect_bailout; 3786 } 3787 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 3788 error = 1; 3789 warnx("Error returned from read defect data command"); 3790 if (arglist & CAM_ARG_VERBOSE) 3791 cam_error_print(device, ccb, CAM_ESF_ALL, 3792 CAM_EPF_ALL, stderr); 3793 goto defect_bailout; 3794 } 3795 3796 if (first_pass != 0) { 3797 fprintf(stderr, "Got %d defect", num_returned); 3798 3799 if ((lists_specified == 0) || (num_returned == 0)) { 3800 fprintf(stderr, "s.\n"); 3801 goto defect_bailout; 3802 } else if (num_returned == 1) 3803 fprintf(stderr, ":\n"); 3804 else 3805 fprintf(stderr, "s:\n"); 3806 3807 first_pass = 0; 3808 } 3809 3810 /* 3811 * XXX KDM I should probably clean up the printout format for the 3812 * disk defects. 3813 */ 3814 switch (returned_type) { 3815 case SRDD10_PHYSICAL_SECTOR_FORMAT: 3816 case SRDD10_EXT_PHYS_FORMAT: 3817 { 3818 struct scsi_defect_desc_phys_sector *dlist; 3819 3820 dlist = (struct scsi_defect_desc_phys_sector *) 3821 (defect_list + hdr_size); 3822 3823 for (i = 0; i < num_valid; i++) { 3824 uint32_t sector; 3825 3826 sector = scsi_4btoul(dlist[i].sector); 3827 if (returned_type == SRDD10_EXT_PHYS_FORMAT) { 3828 mads = (sector & SDD_EXT_PHYS_MADS) ? 3829 0 : 1; 3830 sector &= ~SDD_EXT_PHYS_FLAG_MASK; 3831 } 3832 if (hex_format == 0) 3833 fprintf(stdout, "%d:%d:%d%s", 3834 scsi_3btoul(dlist[i].cylinder), 3835 dlist[i].head, 3836 scsi_4btoul(dlist[i].sector), 3837 mads ? " - " : "\n"); 3838 else 3839 fprintf(stdout, "0x%x:0x%x:0x%x%s", 3840 scsi_3btoul(dlist[i].cylinder), 3841 dlist[i].head, 3842 scsi_4btoul(dlist[i].sector), 3843 mads ? " - " : "\n"); 3844 mads = 0; 3845 } 3846 if (num_valid < num_returned) { 3847 starting_offset += num_valid; 3848 goto next_batch; 3849 } 3850 break; 3851 } 3852 case SRDD10_BYTES_FROM_INDEX_FORMAT: 3853 case SRDD10_EXT_BFI_FORMAT: 3854 { 3855 struct scsi_defect_desc_bytes_from_index *dlist; 3856 3857 dlist = (struct scsi_defect_desc_bytes_from_index *) 3858 (defect_list + hdr_size); 3859 3860 for (i = 0; i < num_valid; i++) { 3861 uint32_t bfi; 3862 3863 bfi = scsi_4btoul(dlist[i].bytes_from_index); 3864 if (returned_type == SRDD10_EXT_BFI_FORMAT) { 3865 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0; 3866 bfi &= ~SDD_EXT_BFI_FLAG_MASK; 3867 } 3868 if (hex_format == 0) 3869 fprintf(stdout, "%d:%d:%d%s", 3870 scsi_3btoul(dlist[i].cylinder), 3871 dlist[i].head, 3872 scsi_4btoul(dlist[i].bytes_from_index), 3873 mads ? " - " : "\n"); 3874 else 3875 fprintf(stdout, "0x%x:0x%x:0x%x%s", 3876 scsi_3btoul(dlist[i].cylinder), 3877 dlist[i].head, 3878 scsi_4btoul(dlist[i].bytes_from_index), 3879 mads ? " - " : "\n"); 3880 3881 mads = 0; 3882 } 3883 if (num_valid < num_returned) { 3884 starting_offset += num_valid; 3885 goto next_batch; 3886 } 3887 break; 3888 } 3889 case SRDDH10_BLOCK_FORMAT: 3890 { 3891 struct scsi_defect_desc_block *dlist; 3892 3893 dlist = (struct scsi_defect_desc_block *) 3894 (defect_list + hdr_size); 3895 3896 for (i = 0; i < num_valid; i++) { 3897 if (hex_format == 0) 3898 fprintf(stdout, "%u\n", 3899 scsi_4btoul(dlist[i].address)); 3900 else 3901 fprintf(stdout, "0x%x\n", 3902 scsi_4btoul(dlist[i].address)); 3903 } 3904 3905 if (num_valid < num_returned) { 3906 starting_offset += num_valid; 3907 goto next_batch; 3908 } 3909 3910 break; 3911 } 3912 case SRDD10_LONG_BLOCK_FORMAT: 3913 { 3914 struct scsi_defect_desc_long_block *dlist; 3915 3916 dlist = (struct scsi_defect_desc_long_block *) 3917 (defect_list + hdr_size); 3918 3919 for (i = 0; i < num_valid; i++) { 3920 if (hex_format == 0) 3921 fprintf(stdout, "%ju\n", 3922 (uintmax_t)scsi_8btou64( 3923 dlist[i].address)); 3924 else 3925 fprintf(stdout, "0x%jx\n", 3926 (uintmax_t)scsi_8btou64( 3927 dlist[i].address)); 3928 } 3929 3930 if (num_valid < num_returned) { 3931 starting_offset += num_valid; 3932 goto next_batch; 3933 } 3934 break; 3935 } 3936 default: 3937 fprintf(stderr, "Unknown defect format 0x%x\n", 3938 returned_type); 3939 error = 1; 3940 break; 3941 } 3942 defect_bailout: 3943 3944 if (defect_list != NULL) 3945 free(defect_list); 3946 3947 if (ccb != NULL) 3948 cam_freeccb(ccb); 3949 3950 return(error); 3951 } 3952 #endif /* MINIMALISTIC */ 3953 3954 #if 0 3955 void 3956 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks) 3957 { 3958 union ccb *ccb; 3959 3960 ccb = cam_getccb(device); 3961 3962 cam_freeccb(ccb); 3963 } 3964 #endif 3965 3966 #ifndef MINIMALISTIC 3967 void 3968 mode_sense(struct cam_device *device, int mode_page, int page_control, 3969 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen) 3970 { 3971 union ccb *ccb; 3972 int retval; 3973 3974 ccb = cam_getccb(device); 3975 3976 if (ccb == NULL) 3977 errx(1, "mode_sense: couldn't allocate CCB"); 3978 3979 bzero(&(&ccb->ccb_h)[1], 3980 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 3981 3982 scsi_mode_sense(&ccb->csio, 3983 /* retries */ retry_count, 3984 /* cbfcnp */ NULL, 3985 /* tag_action */ MSG_SIMPLE_Q_TAG, 3986 /* dbd */ dbd, 3987 /* page_code */ page_control << 6, 3988 /* page */ mode_page, 3989 /* param_buf */ data, 3990 /* param_len */ datalen, 3991 /* sense_len */ SSD_FULL_SIZE, 3992 /* timeout */ timeout ? timeout : 5000); 3993 3994 if (arglist & CAM_ARG_ERR_RECOVER) 3995 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 3996 3997 /* Disable freezing the device queue */ 3998 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 3999 4000 if (((retval = cam_send_ccb(device, ccb)) < 0) 4001 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 4002 if (arglist & CAM_ARG_VERBOSE) { 4003 cam_error_print(device, ccb, CAM_ESF_ALL, 4004 CAM_EPF_ALL, stderr); 4005 } 4006 cam_freeccb(ccb); 4007 cam_close_device(device); 4008 if (retval < 0) 4009 err(1, "error sending mode sense command"); 4010 else 4011 errx(1, "error sending mode sense command"); 4012 } 4013 4014 cam_freeccb(ccb); 4015 } 4016 4017 void 4018 mode_select(struct cam_device *device, int save_pages, int retry_count, 4019 int timeout, u_int8_t *data, int datalen) 4020 { 4021 union ccb *ccb; 4022 int retval; 4023 4024 ccb = cam_getccb(device); 4025 4026 if (ccb == NULL) 4027 errx(1, "mode_select: couldn't allocate CCB"); 4028 4029 bzero(&(&ccb->ccb_h)[1], 4030 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 4031 4032 scsi_mode_select(&ccb->csio, 4033 /* retries */ retry_count, 4034 /* cbfcnp */ NULL, 4035 /* tag_action */ MSG_SIMPLE_Q_TAG, 4036 /* scsi_page_fmt */ 1, 4037 /* save_pages */ save_pages, 4038 /* param_buf */ data, 4039 /* param_len */ datalen, 4040 /* sense_len */ SSD_FULL_SIZE, 4041 /* timeout */ timeout ? timeout : 5000); 4042 4043 if (arglist & CAM_ARG_ERR_RECOVER) 4044 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 4045 4046 /* Disable freezing the device queue */ 4047 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 4048 4049 if (((retval = cam_send_ccb(device, ccb)) < 0) 4050 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 4051 if (arglist & CAM_ARG_VERBOSE) { 4052 cam_error_print(device, ccb, CAM_ESF_ALL, 4053 CAM_EPF_ALL, stderr); 4054 } 4055 cam_freeccb(ccb); 4056 cam_close_device(device); 4057 4058 if (retval < 0) 4059 err(1, "error sending mode select command"); 4060 else 4061 errx(1, "error sending mode select command"); 4062 4063 } 4064 4065 cam_freeccb(ccb); 4066 } 4067 4068 void 4069 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, 4070 int retry_count, int timeout) 4071 { 4072 int c, mode_page = -1, page_control = 0; 4073 int binary = 0, list = 0; 4074 4075 while ((c = getopt(argc, argv, combinedopt)) != -1) { 4076 switch(c) { 4077 case 'b': 4078 binary = 1; 4079 break; 4080 case 'd': 4081 arglist |= CAM_ARG_DBD; 4082 break; 4083 case 'e': 4084 arglist |= CAM_ARG_MODE_EDIT; 4085 break; 4086 case 'l': 4087 list = 1; 4088 break; 4089 case 'm': 4090 mode_page = strtol(optarg, NULL, 0); 4091 if (mode_page < 0) 4092 errx(1, "invalid mode page %d", mode_page); 4093 break; 4094 case 'P': 4095 page_control = strtol(optarg, NULL, 0); 4096 if ((page_control < 0) || (page_control > 3)) 4097 errx(1, "invalid page control field %d", 4098 page_control); 4099 arglist |= CAM_ARG_PAGE_CNTL; 4100 break; 4101 default: 4102 break; 4103 } 4104 } 4105 4106 if (mode_page == -1 && list == 0) 4107 errx(1, "you must specify a mode page!"); 4108 4109 if (list) { 4110 mode_list(device, page_control, arglist & CAM_ARG_DBD, 4111 retry_count, timeout); 4112 } else { 4113 mode_edit(device, mode_page, page_control, 4114 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary, 4115 retry_count, timeout); 4116 } 4117 } 4118 4119 static int 4120 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, 4121 int retry_count, int timeout) 4122 { 4123 union ccb *ccb; 4124 u_int32_t flags = CAM_DIR_NONE; 4125 u_int8_t *data_ptr = NULL; 4126 u_int8_t cdb[20]; 4127 u_int8_t atacmd[12]; 4128 struct get_hook hook; 4129 int c, data_bytes = 0; 4130 int cdb_len = 0; 4131 int atacmd_len = 0; 4132 int dmacmd = 0; 4133 int fpdmacmd = 0; 4134 int need_res = 0; 4135 char *datastr = NULL, *tstr, *resstr = NULL; 4136 int error = 0; 4137 int fd_data = 0, fd_res = 0; 4138 int retval; 4139 4140 ccb = cam_getccb(device); 4141 4142 if (ccb == NULL) { 4143 warnx("scsicmd: error allocating ccb"); 4144 return(1); 4145 } 4146 4147 bzero(&(&ccb->ccb_h)[1], 4148 sizeof(union ccb) - sizeof(struct ccb_hdr)); 4149 4150 while ((c = getopt(argc, argv, combinedopt)) != -1) { 4151 switch(c) { 4152 case 'a': 4153 tstr = optarg; 4154 while (isspace(*tstr) && (*tstr != '\0')) 4155 tstr++; 4156 hook.argc = argc - optind; 4157 hook.argv = argv + optind; 4158 hook.got = 0; 4159 atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr, 4160 iget, &hook); 4161 /* 4162 * Increment optind by the number of arguments the 4163 * encoding routine processed. After each call to 4164 * getopt(3), optind points to the argument that 4165 * getopt should process _next_. In this case, 4166 * that means it points to the first command string 4167 * argument, if there is one. Once we increment 4168 * this, it should point to either the next command 4169 * line argument, or it should be past the end of 4170 * the list. 4171 */ 4172 optind += hook.got; 4173 break; 4174 case 'c': 4175 tstr = optarg; 4176 while (isspace(*tstr) && (*tstr != '\0')) 4177 tstr++; 4178 hook.argc = argc - optind; 4179 hook.argv = argv + optind; 4180 hook.got = 0; 4181 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr, 4182 iget, &hook); 4183 /* 4184 * Increment optind by the number of arguments the 4185 * encoding routine processed. After each call to 4186 * getopt(3), optind points to the argument that 4187 * getopt should process _next_. In this case, 4188 * that means it points to the first command string 4189 * argument, if there is one. Once we increment 4190 * this, it should point to either the next command 4191 * line argument, or it should be past the end of 4192 * the list. 4193 */ 4194 optind += hook.got; 4195 break; 4196 case 'd': 4197 dmacmd = 1; 4198 break; 4199 case 'f': 4200 fpdmacmd = 1; 4201 break; 4202 case 'i': 4203 if (arglist & CAM_ARG_CMD_OUT) { 4204 warnx("command must either be " 4205 "read or write, not both"); 4206 error = 1; 4207 goto scsicmd_bailout; 4208 } 4209 arglist |= CAM_ARG_CMD_IN; 4210 flags = CAM_DIR_IN; 4211 data_bytes = strtol(optarg, NULL, 0); 4212 if (data_bytes <= 0) { 4213 warnx("invalid number of input bytes %d", 4214 data_bytes); 4215 error = 1; 4216 goto scsicmd_bailout; 4217 } 4218 hook.argc = argc - optind; 4219 hook.argv = argv + optind; 4220 hook.got = 0; 4221 optind++; 4222 datastr = cget(&hook, NULL); 4223 /* 4224 * If the user supplied "-" instead of a format, he 4225 * wants the data to be written to stdout. 4226 */ 4227 if ((datastr != NULL) 4228 && (datastr[0] == '-')) 4229 fd_data = 1; 4230 4231 data_ptr = (u_int8_t *)malloc(data_bytes); 4232 if (data_ptr == NULL) { 4233 warnx("can't malloc memory for data_ptr"); 4234 error = 1; 4235 goto scsicmd_bailout; 4236 } 4237 break; 4238 case 'o': 4239 if (arglist & CAM_ARG_CMD_IN) { 4240 warnx("command must either be " 4241 "read or write, not both"); 4242 error = 1; 4243 goto scsicmd_bailout; 4244 } 4245 arglist |= CAM_ARG_CMD_OUT; 4246 flags = CAM_DIR_OUT; 4247 data_bytes = strtol(optarg, NULL, 0); 4248 if (data_bytes <= 0) { 4249 warnx("invalid number of output bytes %d", 4250 data_bytes); 4251 error = 1; 4252 goto scsicmd_bailout; 4253 } 4254 hook.argc = argc - optind; 4255 hook.argv = argv + optind; 4256 hook.got = 0; 4257 datastr = cget(&hook, NULL); 4258 data_ptr = (u_int8_t *)malloc(data_bytes); 4259 if (data_ptr == NULL) { 4260 warnx("can't malloc memory for data_ptr"); 4261 error = 1; 4262 goto scsicmd_bailout; 4263 } 4264 bzero(data_ptr, data_bytes); 4265 /* 4266 * If the user supplied "-" instead of a format, he 4267 * wants the data to be read from stdin. 4268 */ 4269 if ((datastr != NULL) 4270 && (datastr[0] == '-')) 4271 fd_data = 1; 4272 else 4273 buff_encode_visit(data_ptr, data_bytes, datastr, 4274 iget, &hook); 4275 optind += hook.got; 4276 break; 4277 case 'r': 4278 need_res = 1; 4279 hook.argc = argc - optind; 4280 hook.argv = argv + optind; 4281 hook.got = 0; 4282 resstr = cget(&hook, NULL); 4283 if ((resstr != NULL) && (resstr[0] == '-')) 4284 fd_res = 1; 4285 optind += hook.got; 4286 break; 4287 default: 4288 break; 4289 } 4290 } 4291 4292 /* 4293 * If fd_data is set, and we're writing to the device, we need to 4294 * read the data the user wants written from stdin. 4295 */ 4296 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) { 4297 ssize_t amt_read; 4298 int amt_to_read = data_bytes; 4299 u_int8_t *buf_ptr = data_ptr; 4300 4301 for (amt_read = 0; amt_to_read > 0; 4302 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) { 4303 if (amt_read == -1) { 4304 warn("error reading data from stdin"); 4305 error = 1; 4306 goto scsicmd_bailout; 4307 } 4308 amt_to_read -= amt_read; 4309 buf_ptr += amt_read; 4310 } 4311 } 4312 4313 if (arglist & CAM_ARG_ERR_RECOVER) 4314 flags |= CAM_PASS_ERR_RECOVER; 4315 4316 /* Disable freezing the device queue */ 4317 flags |= CAM_DEV_QFRZDIS; 4318 4319 if (cdb_len) { 4320 /* 4321 * This is taken from the SCSI-3 draft spec. 4322 * (T10/1157D revision 0.3) 4323 * The top 3 bits of an opcode are the group code. 4324 * The next 5 bits are the command code. 4325 * Group 0: six byte commands 4326 * Group 1: ten byte commands 4327 * Group 2: ten byte commands 4328 * Group 3: reserved 4329 * Group 4: sixteen byte commands 4330 * Group 5: twelve byte commands 4331 * Group 6: vendor specific 4332 * Group 7: vendor specific 4333 */ 4334 switch((cdb[0] >> 5) & 0x7) { 4335 case 0: 4336 cdb_len = 6; 4337 break; 4338 case 1: 4339 case 2: 4340 cdb_len = 10; 4341 break; 4342 case 3: 4343 case 6: 4344 case 7: 4345 /* computed by buff_encode_visit */ 4346 break; 4347 case 4: 4348 cdb_len = 16; 4349 break; 4350 case 5: 4351 cdb_len = 12; 4352 break; 4353 } 4354 4355 /* 4356 * We should probably use csio_build_visit or something like that 4357 * here, but it's easier to encode arguments as you go. The 4358 * alternative would be skipping the CDB argument and then encoding 4359 * it here, since we've got the data buffer argument by now. 4360 */ 4361 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len); 4362 4363 cam_fill_csio(&ccb->csio, 4364 /*retries*/ retry_count, 4365 /*cbfcnp*/ NULL, 4366 /*flags*/ flags, 4367 /*tag_action*/ MSG_SIMPLE_Q_TAG, 4368 /*data_ptr*/ data_ptr, 4369 /*dxfer_len*/ data_bytes, 4370 /*sense_len*/ SSD_FULL_SIZE, 4371 /*cdb_len*/ cdb_len, 4372 /*timeout*/ timeout ? timeout : 5000); 4373 } else { 4374 atacmd_len = 12; 4375 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len); 4376 if (need_res) 4377 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; 4378 if (dmacmd) 4379 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA; 4380 if (fpdmacmd) 4381 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA; 4382 4383 cam_fill_ataio(&ccb->ataio, 4384 /*retries*/ retry_count, 4385 /*cbfcnp*/ NULL, 4386 /*flags*/ flags, 4387 /*tag_action*/ 0, 4388 /*data_ptr*/ data_ptr, 4389 /*dxfer_len*/ data_bytes, 4390 /*timeout*/ timeout ? timeout : 5000); 4391 } 4392 4393 if (((retval = cam_send_ccb(device, ccb)) < 0) 4394 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 4395 const char warnstr[] = "error sending command"; 4396 4397 if (retval < 0) 4398 warn(warnstr); 4399 else 4400 warnx(warnstr); 4401 4402 if (arglist & CAM_ARG_VERBOSE) { 4403 cam_error_print(device, ccb, CAM_ESF_ALL, 4404 CAM_EPF_ALL, stderr); 4405 } 4406 4407 error = 1; 4408 goto scsicmd_bailout; 4409 } 4410 4411 if (atacmd_len && need_res) { 4412 if (fd_res == 0) { 4413 buff_decode_visit(&ccb->ataio.res.status, 11, resstr, 4414 arg_put, NULL); 4415 fprintf(stdout, "\n"); 4416 } else { 4417 fprintf(stdout, 4418 "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", 4419 ccb->ataio.res.status, 4420 ccb->ataio.res.error, 4421 ccb->ataio.res.lba_low, 4422 ccb->ataio.res.lba_mid, 4423 ccb->ataio.res.lba_high, 4424 ccb->ataio.res.device, 4425 ccb->ataio.res.lba_low_exp, 4426 ccb->ataio.res.lba_mid_exp, 4427 ccb->ataio.res.lba_high_exp, 4428 ccb->ataio.res.sector_count, 4429 ccb->ataio.res.sector_count_exp); 4430 fflush(stdout); 4431 } 4432 } 4433 4434 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 4435 && (arglist & CAM_ARG_CMD_IN) 4436 && (data_bytes > 0)) { 4437 if (fd_data == 0) { 4438 buff_decode_visit(data_ptr, data_bytes, datastr, 4439 arg_put, NULL); 4440 fprintf(stdout, "\n"); 4441 } else { 4442 ssize_t amt_written; 4443 int amt_to_write = data_bytes; 4444 u_int8_t *buf_ptr = data_ptr; 4445 4446 for (amt_written = 0; (amt_to_write > 0) && 4447 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){ 4448 amt_to_write -= amt_written; 4449 buf_ptr += amt_written; 4450 } 4451 if (amt_written == -1) { 4452 warn("error writing data to stdout"); 4453 error = 1; 4454 goto scsicmd_bailout; 4455 } else if ((amt_written == 0) 4456 && (amt_to_write > 0)) { 4457 warnx("only wrote %u bytes out of %u", 4458 data_bytes - amt_to_write, data_bytes); 4459 } 4460 } 4461 } 4462 4463 scsicmd_bailout: 4464 4465 if ((data_bytes > 0) && (data_ptr != NULL)) 4466 free(data_ptr); 4467 4468 cam_freeccb(ccb); 4469 4470 return(error); 4471 } 4472 4473 static int 4474 camdebug(int argc, char **argv, char *combinedopt) 4475 { 4476 int c, fd; 4477 path_id_t bus = CAM_BUS_WILDCARD; 4478 target_id_t target = CAM_TARGET_WILDCARD; 4479 lun_id_t lun = CAM_LUN_WILDCARD; 4480 char *tstr, *tmpstr = NULL; 4481 union ccb ccb; 4482 int error = 0; 4483 4484 bzero(&ccb, sizeof(union ccb)); 4485 4486 while ((c = getopt(argc, argv, combinedopt)) != -1) { 4487 switch(c) { 4488 case 'I': 4489 arglist |= CAM_ARG_DEBUG_INFO; 4490 ccb.cdbg.flags |= CAM_DEBUG_INFO; 4491 break; 4492 case 'P': 4493 arglist |= CAM_ARG_DEBUG_PERIPH; 4494 ccb.cdbg.flags |= CAM_DEBUG_PERIPH; 4495 break; 4496 case 'S': 4497 arglist |= CAM_ARG_DEBUG_SUBTRACE; 4498 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE; 4499 break; 4500 case 'T': 4501 arglist |= CAM_ARG_DEBUG_TRACE; 4502 ccb.cdbg.flags |= CAM_DEBUG_TRACE; 4503 break; 4504 case 'X': 4505 arglist |= CAM_ARG_DEBUG_XPT; 4506 ccb.cdbg.flags |= CAM_DEBUG_XPT; 4507 break; 4508 case 'c': 4509 arglist |= CAM_ARG_DEBUG_CDB; 4510 ccb.cdbg.flags |= CAM_DEBUG_CDB; 4511 break; 4512 case 'p': 4513 arglist |= CAM_ARG_DEBUG_PROBE; 4514 ccb.cdbg.flags |= CAM_DEBUG_PROBE; 4515 break; 4516 default: 4517 break; 4518 } 4519 } 4520 4521 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { 4522 warnx("error opening transport layer device %s", XPT_DEVICE); 4523 warn("%s", XPT_DEVICE); 4524 return(1); 4525 } 4526 argc -= optind; 4527 argv += optind; 4528 4529 if (argc <= 0) { 4530 warnx("you must specify \"off\", \"all\" or a bus,"); 4531 warnx("bus:target, or bus:target:lun"); 4532 close(fd); 4533 return(1); 4534 } 4535 4536 tstr = *argv; 4537 4538 while (isspace(*tstr) && (*tstr != '\0')) 4539 tstr++; 4540 4541 if (strncmp(tstr, "off", 3) == 0) { 4542 ccb.cdbg.flags = CAM_DEBUG_NONE; 4543 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH| 4544 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE| 4545 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE); 4546 } else if (strncmp(tstr, "all", 3) != 0) { 4547 tmpstr = (char *)strtok(tstr, ":"); 4548 if ((tmpstr != NULL) && (*tmpstr != '\0')){ 4549 bus = strtol(tmpstr, NULL, 0); 4550 arglist |= CAM_ARG_BUS; 4551 tmpstr = (char *)strtok(NULL, ":"); 4552 if ((tmpstr != NULL) && (*tmpstr != '\0')){ 4553 target = strtol(tmpstr, NULL, 0); 4554 arglist |= CAM_ARG_TARGET; 4555 tmpstr = (char *)strtok(NULL, ":"); 4556 if ((tmpstr != NULL) && (*tmpstr != '\0')){ 4557 lun = strtol(tmpstr, NULL, 0); 4558 arglist |= CAM_ARG_LUN; 4559 } 4560 } 4561 } else { 4562 error = 1; 4563 warnx("you must specify \"all\", \"off\", or a bus,"); 4564 warnx("bus:target, or bus:target:lun to debug"); 4565 } 4566 } 4567 4568 if (error == 0) { 4569 4570 ccb.ccb_h.func_code = XPT_DEBUG; 4571 ccb.ccb_h.path_id = bus; 4572 ccb.ccb_h.target_id = target; 4573 ccb.ccb_h.target_lun = lun; 4574 4575 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 4576 warn("CAMIOCOMMAND ioctl failed"); 4577 error = 1; 4578 } 4579 4580 if (error == 0) { 4581 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == 4582 CAM_FUNC_NOTAVAIL) { 4583 warnx("CAM debugging not available"); 4584 warnx("you need to put options CAMDEBUG in" 4585 " your kernel config file!"); 4586 error = 1; 4587 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) != 4588 CAM_REQ_CMP) { 4589 warnx("XPT_DEBUG CCB failed with status %#x", 4590 ccb.ccb_h.status); 4591 error = 1; 4592 } else { 4593 if (ccb.cdbg.flags == CAM_DEBUG_NONE) { 4594 fprintf(stderr, 4595 "Debugging turned off\n"); 4596 } else { 4597 fprintf(stderr, 4598 "Debugging enabled for " 4599 "%d:%d:%jx\n", 4600 bus, target, (uintmax_t)lun); 4601 } 4602 } 4603 } 4604 close(fd); 4605 } 4606 4607 return(error); 4608 } 4609 4610 static int 4611 tagcontrol(struct cam_device *device, int argc, char **argv, 4612 char *combinedopt) 4613 { 4614 int c; 4615 union ccb *ccb; 4616 int numtags = -1; 4617 int retval = 0; 4618 int quiet = 0; 4619 char pathstr[1024]; 4620 4621 ccb = cam_getccb(device); 4622 4623 if (ccb == NULL) { 4624 warnx("tagcontrol: error allocating ccb"); 4625 return(1); 4626 } 4627 4628 while ((c = getopt(argc, argv, combinedopt)) != -1) { 4629 switch(c) { 4630 case 'N': 4631 numtags = strtol(optarg, NULL, 0); 4632 if (numtags < 0) { 4633 warnx("tag count %d is < 0", numtags); 4634 retval = 1; 4635 goto tagcontrol_bailout; 4636 } 4637 break; 4638 case 'q': 4639 quiet++; 4640 break; 4641 default: 4642 break; 4643 } 4644 } 4645 4646 cam_path_string(device, pathstr, sizeof(pathstr)); 4647 4648 if (numtags >= 0) { 4649 bzero(&(&ccb->ccb_h)[1], 4650 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr)); 4651 ccb->ccb_h.func_code = XPT_REL_SIMQ; 4652 ccb->ccb_h.flags = CAM_DEV_QFREEZE; 4653 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS; 4654 ccb->crs.openings = numtags; 4655 4656 4657 if (cam_send_ccb(device, ccb) < 0) { 4658 perror("error sending XPT_REL_SIMQ CCB"); 4659 retval = 1; 4660 goto tagcontrol_bailout; 4661 } 4662 4663 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4664 warnx("XPT_REL_SIMQ CCB failed"); 4665 cam_error_print(device, ccb, CAM_ESF_ALL, 4666 CAM_EPF_ALL, stderr); 4667 retval = 1; 4668 goto tagcontrol_bailout; 4669 } 4670 4671 4672 if (quiet == 0) 4673 fprintf(stdout, "%stagged openings now %d\n", 4674 pathstr, ccb->crs.openings); 4675 } 4676 4677 bzero(&(&ccb->ccb_h)[1], 4678 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr)); 4679 4680 ccb->ccb_h.func_code = XPT_GDEV_STATS; 4681 4682 if (cam_send_ccb(device, ccb) < 0) { 4683 perror("error sending XPT_GDEV_STATS CCB"); 4684 retval = 1; 4685 goto tagcontrol_bailout; 4686 } 4687 4688 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4689 warnx("XPT_GDEV_STATS CCB failed"); 4690 cam_error_print(device, ccb, CAM_ESF_ALL, 4691 CAM_EPF_ALL, stderr); 4692 retval = 1; 4693 goto tagcontrol_bailout; 4694 } 4695 4696 if (arglist & CAM_ARG_VERBOSE) { 4697 fprintf(stdout, "%s", pathstr); 4698 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings); 4699 fprintf(stdout, "%s", pathstr); 4700 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active); 4701 fprintf(stdout, "%s", pathstr); 4702 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated); 4703 fprintf(stdout, "%s", pathstr); 4704 fprintf(stdout, "queued %d\n", ccb->cgds.queued); 4705 fprintf(stdout, "%s", pathstr); 4706 fprintf(stdout, "held %d\n", ccb->cgds.held); 4707 fprintf(stdout, "%s", pathstr); 4708 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags); 4709 fprintf(stdout, "%s", pathstr); 4710 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags); 4711 } else { 4712 if (quiet == 0) { 4713 fprintf(stdout, "%s", pathstr); 4714 fprintf(stdout, "device openings: "); 4715 } 4716 fprintf(stdout, "%d\n", ccb->cgds.dev_openings + 4717 ccb->cgds.dev_active); 4718 } 4719 4720 tagcontrol_bailout: 4721 4722 cam_freeccb(ccb); 4723 return(retval); 4724 } 4725 4726 static void 4727 cts_print(struct cam_device *device, struct ccb_trans_settings *cts) 4728 { 4729 char pathstr[1024]; 4730 4731 cam_path_string(device, pathstr, sizeof(pathstr)); 4732 4733 if (cts->transport == XPORT_SPI) { 4734 struct ccb_trans_settings_spi *spi = 4735 &cts->xport_specific.spi; 4736 4737 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { 4738 4739 fprintf(stdout, "%ssync parameter: %d\n", pathstr, 4740 spi->sync_period); 4741 4742 if (spi->sync_offset != 0) { 4743 u_int freq; 4744 4745 freq = scsi_calc_syncsrate(spi->sync_period); 4746 fprintf(stdout, "%sfrequency: %d.%03dMHz\n", 4747 pathstr, freq / 1000, freq % 1000); 4748 } 4749 } 4750 4751 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) { 4752 fprintf(stdout, "%soffset: %d\n", pathstr, 4753 spi->sync_offset); 4754 } 4755 4756 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) { 4757 fprintf(stdout, "%sbus width: %d bits\n", pathstr, 4758 (0x01 << spi->bus_width) * 8); 4759 } 4760 4761 if (spi->valid & CTS_SPI_VALID_DISC) { 4762 fprintf(stdout, "%sdisconnection is %s\n", pathstr, 4763 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ? 4764 "enabled" : "disabled"); 4765 } 4766 } 4767 if (cts->transport == XPORT_FC) { 4768 struct ccb_trans_settings_fc *fc = 4769 &cts->xport_specific.fc; 4770 4771 if (fc->valid & CTS_FC_VALID_WWNN) 4772 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr, 4773 (long long) fc->wwnn); 4774 if (fc->valid & CTS_FC_VALID_WWPN) 4775 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr, 4776 (long long) fc->wwpn); 4777 if (fc->valid & CTS_FC_VALID_PORT) 4778 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port); 4779 if (fc->valid & CTS_FC_VALID_SPEED) 4780 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n", 4781 pathstr, fc->bitrate / 1000, fc->bitrate % 1000); 4782 } 4783 if (cts->transport == XPORT_SAS) { 4784 struct ccb_trans_settings_sas *sas = 4785 &cts->xport_specific.sas; 4786 4787 if (sas->valid & CTS_SAS_VALID_SPEED) 4788 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n", 4789 pathstr, sas->bitrate / 1000, sas->bitrate % 1000); 4790 } 4791 if (cts->transport == XPORT_ATA) { 4792 struct ccb_trans_settings_pata *pata = 4793 &cts->xport_specific.ata; 4794 4795 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) { 4796 fprintf(stdout, "%sATA mode: %s\n", pathstr, 4797 ata_mode2string(pata->mode)); 4798 } 4799 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) { 4800 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, 4801 pata->atapi); 4802 } 4803 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) { 4804 fprintf(stdout, "%sPIO transaction length: %d\n", 4805 pathstr, pata->bytecount); 4806 } 4807 } 4808 if (cts->transport == XPORT_SATA) { 4809 struct ccb_trans_settings_sata *sata = 4810 &cts->xport_specific.sata; 4811 4812 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) { 4813 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr, 4814 sata->revision); 4815 } 4816 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) { 4817 fprintf(stdout, "%sATA mode: %s\n", pathstr, 4818 ata_mode2string(sata->mode)); 4819 } 4820 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) { 4821 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, 4822 sata->atapi); 4823 } 4824 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) { 4825 fprintf(stdout, "%sPIO transaction length: %d\n", 4826 pathstr, sata->bytecount); 4827 } 4828 if ((sata->valid & CTS_SATA_VALID_PM) != 0) { 4829 fprintf(stdout, "%sPMP presence: %d\n", pathstr, 4830 sata->pm_present); 4831 } 4832 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) { 4833 fprintf(stdout, "%sNumber of tags: %d\n", pathstr, 4834 sata->tags); 4835 } 4836 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) { 4837 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr, 4838 sata->caps); 4839 } 4840 } 4841 if (cts->protocol == PROTO_ATA) { 4842 struct ccb_trans_settings_ata *ata= 4843 &cts->proto_specific.ata; 4844 4845 if (ata->valid & CTS_ATA_VALID_TQ) { 4846 fprintf(stdout, "%stagged queueing: %s\n", pathstr, 4847 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ? 4848 "enabled" : "disabled"); 4849 } 4850 } 4851 if (cts->protocol == PROTO_SCSI) { 4852 struct ccb_trans_settings_scsi *scsi= 4853 &cts->proto_specific.scsi; 4854 4855 if (scsi->valid & CTS_SCSI_VALID_TQ) { 4856 fprintf(stdout, "%stagged queueing: %s\n", pathstr, 4857 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ? 4858 "enabled" : "disabled"); 4859 } 4860 } 4861 4862 } 4863 4864 /* 4865 * Get a path inquiry CCB for the specified device. 4866 */ 4867 static int 4868 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi) 4869 { 4870 union ccb *ccb; 4871 int retval = 0; 4872 4873 ccb = cam_getccb(device); 4874 if (ccb == NULL) { 4875 warnx("get_cpi: couldn't allocate CCB"); 4876 return(1); 4877 } 4878 bzero(&(&ccb->ccb_h)[1], 4879 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr)); 4880 ccb->ccb_h.func_code = XPT_PATH_INQ; 4881 if (cam_send_ccb(device, ccb) < 0) { 4882 warn("get_cpi: error sending Path Inquiry CCB"); 4883 if (arglist & CAM_ARG_VERBOSE) 4884 cam_error_print(device, ccb, CAM_ESF_ALL, 4885 CAM_EPF_ALL, stderr); 4886 retval = 1; 4887 goto get_cpi_bailout; 4888 } 4889 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4890 if (arglist & CAM_ARG_VERBOSE) 4891 cam_error_print(device, ccb, CAM_ESF_ALL, 4892 CAM_EPF_ALL, stderr); 4893 retval = 1; 4894 goto get_cpi_bailout; 4895 } 4896 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq)); 4897 4898 get_cpi_bailout: 4899 cam_freeccb(ccb); 4900 return(retval); 4901 } 4902 4903 /* 4904 * Get a get device CCB for the specified device. 4905 */ 4906 static int 4907 get_cgd(struct cam_device *device, struct ccb_getdev *cgd) 4908 { 4909 union ccb *ccb; 4910 int retval = 0; 4911 4912 ccb = cam_getccb(device); 4913 if (ccb == NULL) { 4914 warnx("get_cgd: couldn't allocate CCB"); 4915 return(1); 4916 } 4917 bzero(&(&ccb->ccb_h)[1], 4918 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr)); 4919 ccb->ccb_h.func_code = XPT_GDEV_TYPE; 4920 if (cam_send_ccb(device, ccb) < 0) { 4921 warn("get_cgd: error sending Path Inquiry CCB"); 4922 if (arglist & CAM_ARG_VERBOSE) 4923 cam_error_print(device, ccb, CAM_ESF_ALL, 4924 CAM_EPF_ALL, stderr); 4925 retval = 1; 4926 goto get_cgd_bailout; 4927 } 4928 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4929 if (arglist & CAM_ARG_VERBOSE) 4930 cam_error_print(device, ccb, CAM_ESF_ALL, 4931 CAM_EPF_ALL, stderr); 4932 retval = 1; 4933 goto get_cgd_bailout; 4934 } 4935 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev)); 4936 4937 get_cgd_bailout: 4938 cam_freeccb(ccb); 4939 return(retval); 4940 } 4941 4942 /* return the type of disk (really the command type) */ 4943 static const char * 4944 get_disk_type(struct cam_device *device) 4945 { 4946 struct ccb_getdev cgd; 4947 4948 (void) memset(&cgd, 0x0, sizeof(cgd)); 4949 get_cgd(device, &cgd); 4950 switch(cgd.protocol) { 4951 case PROTO_SCSI: 4952 return "scsi"; 4953 case PROTO_ATA: 4954 case PROTO_ATAPI: 4955 case PROTO_SATAPM: 4956 return "ata"; 4957 default: 4958 return "unknown"; 4959 } 4960 } 4961 4962 static void 4963 cpi_print(struct ccb_pathinq *cpi) 4964 { 4965 char adapter_str[1024]; 4966 int i; 4967 4968 snprintf(adapter_str, sizeof(adapter_str), 4969 "%s%d:", cpi->dev_name, cpi->unit_number); 4970 4971 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str, 4972 cpi->version_num); 4973 4974 for (i = 1; i < 0xff; i = i << 1) { 4975 const char *str; 4976 4977 if ((i & cpi->hba_inquiry) == 0) 4978 continue; 4979 4980 fprintf(stdout, "%s supports ", adapter_str); 4981 4982 switch(i) { 4983 case PI_MDP_ABLE: 4984 str = "MDP message"; 4985 break; 4986 case PI_WIDE_32: 4987 str = "32 bit wide SCSI"; 4988 break; 4989 case PI_WIDE_16: 4990 str = "16 bit wide SCSI"; 4991 break; 4992 case PI_SDTR_ABLE: 4993 str = "SDTR message"; 4994 break; 4995 case PI_LINKED_CDB: 4996 str = "linked CDBs"; 4997 break; 4998 case PI_TAG_ABLE: 4999 str = "tag queue messages"; 5000 break; 5001 case PI_SOFT_RST: 5002 str = "soft reset alternative"; 5003 break; 5004 case PI_SATAPM: 5005 str = "SATA Port Multiplier"; 5006 break; 5007 default: 5008 str = "unknown PI bit set"; 5009 break; 5010 } 5011 fprintf(stdout, "%s\n", str); 5012 } 5013 5014 for (i = 1; i < 0xff; i = i << 1) { 5015 const char *str; 5016 5017 if ((i & cpi->hba_misc) == 0) 5018 continue; 5019 5020 fprintf(stdout, "%s ", adapter_str); 5021 5022 switch(i) { 5023 case PIM_SCANHILO: 5024 str = "bus scans from high ID to low ID"; 5025 break; 5026 case PIM_NOREMOVE: 5027 str = "removable devices not included in scan"; 5028 break; 5029 case PIM_NOINITIATOR: 5030 str = "initiator role not supported"; 5031 break; 5032 case PIM_NOBUSRESET: 5033 str = "user has disabled initial BUS RESET or" 5034 " controller is in target/mixed mode"; 5035 break; 5036 case PIM_NO_6_BYTE: 5037 str = "do not send 6-byte commands"; 5038 break; 5039 case PIM_SEQSCAN: 5040 str = "scan bus sequentially"; 5041 break; 5042 default: 5043 str = "unknown PIM bit set"; 5044 break; 5045 } 5046 fprintf(stdout, "%s\n", str); 5047 } 5048 5049 for (i = 1; i < 0xff; i = i << 1) { 5050 const char *str; 5051 5052 if ((i & cpi->target_sprt) == 0) 5053 continue; 5054 5055 fprintf(stdout, "%s supports ", adapter_str); 5056 switch(i) { 5057 case PIT_PROCESSOR: 5058 str = "target mode processor mode"; 5059 break; 5060 case PIT_PHASE: 5061 str = "target mode phase cog. mode"; 5062 break; 5063 case PIT_DISCONNECT: 5064 str = "disconnects in target mode"; 5065 break; 5066 case PIT_TERM_IO: 5067 str = "terminate I/O message in target mode"; 5068 break; 5069 case PIT_GRP_6: 5070 str = "group 6 commands in target mode"; 5071 break; 5072 case PIT_GRP_7: 5073 str = "group 7 commands in target mode"; 5074 break; 5075 default: 5076 str = "unknown PIT bit set"; 5077 break; 5078 } 5079 5080 fprintf(stdout, "%s\n", str); 5081 } 5082 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str, 5083 cpi->hba_eng_cnt); 5084 fprintf(stdout, "%s maximum target: %d\n", adapter_str, 5085 cpi->max_target); 5086 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str, 5087 cpi->max_lun); 5088 fprintf(stdout, "%s highest path ID in subsystem: %d\n", 5089 adapter_str, cpi->hpath_id); 5090 fprintf(stdout, "%s initiator ID: %d\n", adapter_str, 5091 cpi->initiator_id); 5092 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid); 5093 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid); 5094 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n", 5095 adapter_str, cpi->hba_vendor); 5096 fprintf(stdout, "%s HBA device ID: 0x%04x\n", 5097 adapter_str, cpi->hba_device); 5098 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n", 5099 adapter_str, cpi->hba_subvendor); 5100 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n", 5101 adapter_str, cpi->hba_subdevice); 5102 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id); 5103 fprintf(stdout, "%s base transfer speed: ", adapter_str); 5104 if (cpi->base_transfer_speed > 1000) 5105 fprintf(stdout, "%d.%03dMB/sec\n", 5106 cpi->base_transfer_speed / 1000, 5107 cpi->base_transfer_speed % 1000); 5108 else 5109 fprintf(stdout, "%dKB/sec\n", 5110 (cpi->base_transfer_speed % 1000) * 1000); 5111 fprintf(stdout, "%s maximum transfer size: %u bytes\n", 5112 adapter_str, cpi->maxio); 5113 } 5114 5115 static int 5116 get_print_cts(struct cam_device *device, int user_settings, int quiet, 5117 struct ccb_trans_settings *cts) 5118 { 5119 int retval; 5120 union ccb *ccb; 5121 5122 retval = 0; 5123 ccb = cam_getccb(device); 5124 5125 if (ccb == NULL) { 5126 warnx("get_print_cts: error allocating ccb"); 5127 return(1); 5128 } 5129 5130 bzero(&(&ccb->ccb_h)[1], 5131 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr)); 5132 5133 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 5134 5135 if (user_settings == 0) 5136 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS; 5137 else 5138 ccb->cts.type = CTS_TYPE_USER_SETTINGS; 5139 5140 if (cam_send_ccb(device, ccb) < 0) { 5141 perror("error sending XPT_GET_TRAN_SETTINGS CCB"); 5142 if (arglist & CAM_ARG_VERBOSE) 5143 cam_error_print(device, ccb, CAM_ESF_ALL, 5144 CAM_EPF_ALL, stderr); 5145 retval = 1; 5146 goto get_print_cts_bailout; 5147 } 5148 5149 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5150 warnx("XPT_GET_TRANS_SETTINGS CCB failed"); 5151 if (arglist & CAM_ARG_VERBOSE) 5152 cam_error_print(device, ccb, CAM_ESF_ALL, 5153 CAM_EPF_ALL, stderr); 5154 retval = 1; 5155 goto get_print_cts_bailout; 5156 } 5157 5158 if (quiet == 0) 5159 cts_print(device, &ccb->cts); 5160 5161 if (cts != NULL) 5162 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings)); 5163 5164 get_print_cts_bailout: 5165 5166 cam_freeccb(ccb); 5167 5168 return(retval); 5169 } 5170 5171 static int 5172 ratecontrol(struct cam_device *device, int retry_count, int timeout, 5173 int argc, char **argv, char *combinedopt) 5174 { 5175 int c; 5176 union ccb *ccb; 5177 int user_settings = 0; 5178 int retval = 0; 5179 int disc_enable = -1, tag_enable = -1; 5180 int mode = -1; 5181 int offset = -1; 5182 double syncrate = -1; 5183 int bus_width = -1; 5184 int quiet = 0; 5185 int change_settings = 0, send_tur = 0; 5186 struct ccb_pathinq cpi; 5187 5188 ccb = cam_getccb(device); 5189 if (ccb == NULL) { 5190 warnx("ratecontrol: error allocating ccb"); 5191 return(1); 5192 } 5193 while ((c = getopt(argc, argv, combinedopt)) != -1) { 5194 switch(c){ 5195 case 'a': 5196 send_tur = 1; 5197 break; 5198 case 'c': 5199 user_settings = 0; 5200 break; 5201 case 'D': 5202 if (strncasecmp(optarg, "enable", 6) == 0) 5203 disc_enable = 1; 5204 else if (strncasecmp(optarg, "disable", 7) == 0) 5205 disc_enable = 0; 5206 else { 5207 warnx("-D argument \"%s\" is unknown", optarg); 5208 retval = 1; 5209 goto ratecontrol_bailout; 5210 } 5211 change_settings = 1; 5212 break; 5213 case 'M': 5214 mode = ata_string2mode(optarg); 5215 if (mode < 0) { 5216 warnx("unknown mode '%s'", optarg); 5217 retval = 1; 5218 goto ratecontrol_bailout; 5219 } 5220 change_settings = 1; 5221 break; 5222 case 'O': 5223 offset = strtol(optarg, NULL, 0); 5224 if (offset < 0) { 5225 warnx("offset value %d is < 0", offset); 5226 retval = 1; 5227 goto ratecontrol_bailout; 5228 } 5229 change_settings = 1; 5230 break; 5231 case 'q': 5232 quiet++; 5233 break; 5234 case 'R': 5235 syncrate = atof(optarg); 5236 if (syncrate < 0) { 5237 warnx("sync rate %f is < 0", syncrate); 5238 retval = 1; 5239 goto ratecontrol_bailout; 5240 } 5241 change_settings = 1; 5242 break; 5243 case 'T': 5244 if (strncasecmp(optarg, "enable", 6) == 0) 5245 tag_enable = 1; 5246 else if (strncasecmp(optarg, "disable", 7) == 0) 5247 tag_enable = 0; 5248 else { 5249 warnx("-T argument \"%s\" is unknown", optarg); 5250 retval = 1; 5251 goto ratecontrol_bailout; 5252 } 5253 change_settings = 1; 5254 break; 5255 case 'U': 5256 user_settings = 1; 5257 break; 5258 case 'W': 5259 bus_width = strtol(optarg, NULL, 0); 5260 if (bus_width < 0) { 5261 warnx("bus width %d is < 0", bus_width); 5262 retval = 1; 5263 goto ratecontrol_bailout; 5264 } 5265 change_settings = 1; 5266 break; 5267 default: 5268 break; 5269 } 5270 } 5271 bzero(&(&ccb->ccb_h)[1], 5272 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr)); 5273 /* 5274 * Grab path inquiry information, so we can determine whether 5275 * or not the initiator is capable of the things that the user 5276 * requests. 5277 */ 5278 ccb->ccb_h.func_code = XPT_PATH_INQ; 5279 if (cam_send_ccb(device, ccb) < 0) { 5280 perror("error sending XPT_PATH_INQ CCB"); 5281 if (arglist & CAM_ARG_VERBOSE) { 5282 cam_error_print(device, ccb, CAM_ESF_ALL, 5283 CAM_EPF_ALL, stderr); 5284 } 5285 retval = 1; 5286 goto ratecontrol_bailout; 5287 } 5288 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5289 warnx("XPT_PATH_INQ CCB failed"); 5290 if (arglist & CAM_ARG_VERBOSE) { 5291 cam_error_print(device, ccb, CAM_ESF_ALL, 5292 CAM_EPF_ALL, stderr); 5293 } 5294 retval = 1; 5295 goto ratecontrol_bailout; 5296 } 5297 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq)); 5298 bzero(&(&ccb->ccb_h)[1], 5299 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr)); 5300 if (quiet == 0) { 5301 fprintf(stdout, "%s parameters:\n", 5302 user_settings ? "User" : "Current"); 5303 } 5304 retval = get_print_cts(device, user_settings, quiet, &ccb->cts); 5305 if (retval != 0) 5306 goto ratecontrol_bailout; 5307 5308 if (arglist & CAM_ARG_VERBOSE) 5309 cpi_print(&cpi); 5310 5311 if (change_settings) { 5312 int didsettings = 0; 5313 struct ccb_trans_settings_spi *spi = NULL; 5314 struct ccb_trans_settings_pata *pata = NULL; 5315 struct ccb_trans_settings_sata *sata = NULL; 5316 struct ccb_trans_settings_ata *ata = NULL; 5317 struct ccb_trans_settings_scsi *scsi = NULL; 5318 5319 if (ccb->cts.transport == XPORT_SPI) 5320 spi = &ccb->cts.xport_specific.spi; 5321 if (ccb->cts.transport == XPORT_ATA) 5322 pata = &ccb->cts.xport_specific.ata; 5323 if (ccb->cts.transport == XPORT_SATA) 5324 sata = &ccb->cts.xport_specific.sata; 5325 if (ccb->cts.protocol == PROTO_ATA) 5326 ata = &ccb->cts.proto_specific.ata; 5327 if (ccb->cts.protocol == PROTO_SCSI) 5328 scsi = &ccb->cts.proto_specific.scsi; 5329 ccb->cts.xport_specific.valid = 0; 5330 ccb->cts.proto_specific.valid = 0; 5331 if (spi && disc_enable != -1) { 5332 spi->valid |= CTS_SPI_VALID_DISC; 5333 if (disc_enable == 0) 5334 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 5335 else 5336 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 5337 didsettings++; 5338 } 5339 if (tag_enable != -1) { 5340 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) { 5341 warnx("HBA does not support tagged queueing, " 5342 "so you cannot modify tag settings"); 5343 retval = 1; 5344 goto ratecontrol_bailout; 5345 } 5346 if (ata) { 5347 ata->valid |= CTS_SCSI_VALID_TQ; 5348 if (tag_enable == 0) 5349 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB; 5350 else 5351 ata->flags |= CTS_ATA_FLAGS_TAG_ENB; 5352 didsettings++; 5353 } else if (scsi) { 5354 scsi->valid |= CTS_SCSI_VALID_TQ; 5355 if (tag_enable == 0) 5356 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 5357 else 5358 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 5359 didsettings++; 5360 } 5361 } 5362 if (spi && offset != -1) { 5363 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5364 warnx("HBA is not capable of changing offset"); 5365 retval = 1; 5366 goto ratecontrol_bailout; 5367 } 5368 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 5369 spi->sync_offset = offset; 5370 didsettings++; 5371 } 5372 if (spi && syncrate != -1) { 5373 int prelim_sync_period; 5374 5375 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5376 warnx("HBA is not capable of changing " 5377 "transfer rates"); 5378 retval = 1; 5379 goto ratecontrol_bailout; 5380 } 5381 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 5382 /* 5383 * The sync rate the user gives us is in MHz. 5384 * We need to translate it into KHz for this 5385 * calculation. 5386 */ 5387 syncrate *= 1000; 5388 /* 5389 * Next, we calculate a "preliminary" sync period 5390 * in tenths of a nanosecond. 5391 */ 5392 if (syncrate == 0) 5393 prelim_sync_period = 0; 5394 else 5395 prelim_sync_period = 10000000 / syncrate; 5396 spi->sync_period = 5397 scsi_calc_syncparam(prelim_sync_period); 5398 didsettings++; 5399 } 5400 if (sata && syncrate != -1) { 5401 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5402 warnx("HBA is not capable of changing " 5403 "transfer rates"); 5404 retval = 1; 5405 goto ratecontrol_bailout; 5406 } 5407 if (!user_settings) { 5408 warnx("You can modify only user rate " 5409 "settings for SATA"); 5410 retval = 1; 5411 goto ratecontrol_bailout; 5412 } 5413 sata->revision = ata_speed2revision(syncrate * 100); 5414 if (sata->revision < 0) { 5415 warnx("Invalid rate %f", syncrate); 5416 retval = 1; 5417 goto ratecontrol_bailout; 5418 } 5419 sata->valid |= CTS_SATA_VALID_REVISION; 5420 didsettings++; 5421 } 5422 if ((pata || sata) && mode != -1) { 5423 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5424 warnx("HBA is not capable of changing " 5425 "transfer rates"); 5426 retval = 1; 5427 goto ratecontrol_bailout; 5428 } 5429 if (!user_settings) { 5430 warnx("You can modify only user mode " 5431 "settings for ATA/SATA"); 5432 retval = 1; 5433 goto ratecontrol_bailout; 5434 } 5435 if (pata) { 5436 pata->mode = mode; 5437 pata->valid |= CTS_ATA_VALID_MODE; 5438 } else { 5439 sata->mode = mode; 5440 sata->valid |= CTS_SATA_VALID_MODE; 5441 } 5442 didsettings++; 5443 } 5444 /* 5445 * The bus_width argument goes like this: 5446 * 0 == 8 bit 5447 * 1 == 16 bit 5448 * 2 == 32 bit 5449 * Therefore, if you shift the number of bits given on the 5450 * command line right by 4, you should get the correct 5451 * number. 5452 */ 5453 if (spi && bus_width != -1) { 5454 /* 5455 * We might as well validate things here with a 5456 * decipherable error message, rather than what 5457 * will probably be an indecipherable error message 5458 * by the time it gets back to us. 5459 */ 5460 if ((bus_width == 16) 5461 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) { 5462 warnx("HBA does not support 16 bit bus width"); 5463 retval = 1; 5464 goto ratecontrol_bailout; 5465 } else if ((bus_width == 32) 5466 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) { 5467 warnx("HBA does not support 32 bit bus width"); 5468 retval = 1; 5469 goto ratecontrol_bailout; 5470 } else if ((bus_width != 8) 5471 && (bus_width != 16) 5472 && (bus_width != 32)) { 5473 warnx("Invalid bus width %d", bus_width); 5474 retval = 1; 5475 goto ratecontrol_bailout; 5476 } 5477 spi->valid |= CTS_SPI_VALID_BUS_WIDTH; 5478 spi->bus_width = bus_width >> 4; 5479 didsettings++; 5480 } 5481 if (didsettings == 0) { 5482 goto ratecontrol_bailout; 5483 } 5484 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 5485 if (cam_send_ccb(device, ccb) < 0) { 5486 perror("error sending XPT_SET_TRAN_SETTINGS CCB"); 5487 if (arglist & CAM_ARG_VERBOSE) { 5488 cam_error_print(device, ccb, CAM_ESF_ALL, 5489 CAM_EPF_ALL, stderr); 5490 } 5491 retval = 1; 5492 goto ratecontrol_bailout; 5493 } 5494 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5495 warnx("XPT_SET_TRANS_SETTINGS CCB failed"); 5496 if (arglist & CAM_ARG_VERBOSE) { 5497 cam_error_print(device, ccb, CAM_ESF_ALL, 5498 CAM_EPF_ALL, stderr); 5499 } 5500 retval = 1; 5501 goto ratecontrol_bailout; 5502 } 5503 } 5504 if (send_tur) { 5505 retval = testunitready(device, retry_count, timeout, 5506 (arglist & CAM_ARG_VERBOSE) ? 0 : 1); 5507 /* 5508 * If the TUR didn't succeed, just bail. 5509 */ 5510 if (retval != 0) { 5511 if (quiet == 0) 5512 fprintf(stderr, "Test Unit Ready failed\n"); 5513 goto ratecontrol_bailout; 5514 } 5515 } 5516 if ((change_settings || send_tur) && !quiet && 5517 (ccb->cts.transport == XPORT_ATA || 5518 ccb->cts.transport == XPORT_SATA || send_tur)) { 5519 fprintf(stdout, "New parameters:\n"); 5520 retval = get_print_cts(device, user_settings, 0, NULL); 5521 } 5522 5523 ratecontrol_bailout: 5524 cam_freeccb(ccb); 5525 return(retval); 5526 } 5527 5528 static int 5529 scsiformat(struct cam_device *device, int argc, char **argv, 5530 char *combinedopt, int retry_count, int timeout) 5531 { 5532 union ccb *ccb; 5533 int c; 5534 int ycount = 0, quiet = 0; 5535 int error = 0, retval = 0; 5536 int use_timeout = 10800 * 1000; 5537 int immediate = 1; 5538 struct format_defect_list_header fh; 5539 u_int8_t *data_ptr = NULL; 5540 u_int32_t dxfer_len = 0; 5541 u_int8_t byte2 = 0; 5542 int num_warnings = 0; 5543 int reportonly = 0; 5544 5545 ccb = cam_getccb(device); 5546 5547 if (ccb == NULL) { 5548 warnx("scsiformat: error allocating ccb"); 5549 return(1); 5550 } 5551 5552 bzero(&(&ccb->ccb_h)[1], 5553 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 5554 5555 while ((c = getopt(argc, argv, combinedopt)) != -1) { 5556 switch(c) { 5557 case 'q': 5558 quiet++; 5559 break; 5560 case 'r': 5561 reportonly = 1; 5562 break; 5563 case 'w': 5564 immediate = 0; 5565 break; 5566 case 'y': 5567 ycount++; 5568 break; 5569 } 5570 } 5571 5572 if (reportonly) 5573 goto doreport; 5574 5575 if (quiet == 0) { 5576 fprintf(stdout, "You are about to REMOVE ALL DATA from the " 5577 "following device:\n"); 5578 5579 error = scsidoinquiry(device, argc, argv, combinedopt, 5580 retry_count, timeout); 5581 5582 if (error != 0) { 5583 warnx("scsiformat: error sending inquiry"); 5584 goto scsiformat_bailout; 5585 } 5586 } 5587 5588 if (ycount == 0) { 5589 if (!get_confirmation()) { 5590 error = 1; 5591 goto scsiformat_bailout; 5592 } 5593 } 5594 5595 if (timeout != 0) 5596 use_timeout = timeout; 5597 5598 if (quiet == 0) { 5599 fprintf(stdout, "Current format timeout is %d seconds\n", 5600 use_timeout / 1000); 5601 } 5602 5603 /* 5604 * If the user hasn't disabled questions and didn't specify a 5605 * timeout on the command line, ask them if they want the current 5606 * timeout. 5607 */ 5608 if ((ycount == 0) 5609 && (timeout == 0)) { 5610 char str[1024]; 5611 int new_timeout = 0; 5612 5613 fprintf(stdout, "Enter new timeout in seconds or press\n" 5614 "return to keep the current timeout [%d] ", 5615 use_timeout / 1000); 5616 5617 if (fgets(str, sizeof(str), stdin) != NULL) { 5618 if (str[0] != '\0') 5619 new_timeout = atoi(str); 5620 } 5621 5622 if (new_timeout != 0) { 5623 use_timeout = new_timeout * 1000; 5624 fprintf(stdout, "Using new timeout value %d\n", 5625 use_timeout / 1000); 5626 } 5627 } 5628 5629 /* 5630 * Keep this outside the if block below to silence any unused 5631 * variable warnings. 5632 */ 5633 bzero(&fh, sizeof(fh)); 5634 5635 /* 5636 * If we're in immediate mode, we've got to include the format 5637 * header 5638 */ 5639 if (immediate != 0) { 5640 fh.byte2 = FU_DLH_IMMED; 5641 data_ptr = (u_int8_t *)&fh; 5642 dxfer_len = sizeof(fh); 5643 byte2 = FU_FMT_DATA; 5644 } else if (quiet == 0) { 5645 fprintf(stdout, "Formatting..."); 5646 fflush(stdout); 5647 } 5648 5649 scsi_format_unit(&ccb->csio, 5650 /* retries */ retry_count, 5651 /* cbfcnp */ NULL, 5652 /* tag_action */ MSG_SIMPLE_Q_TAG, 5653 /* byte2 */ byte2, 5654 /* ileave */ 0, 5655 /* data_ptr */ data_ptr, 5656 /* dxfer_len */ dxfer_len, 5657 /* sense_len */ SSD_FULL_SIZE, 5658 /* timeout */ use_timeout); 5659 5660 /* Disable freezing the device queue */ 5661 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 5662 5663 if (arglist & CAM_ARG_ERR_RECOVER) 5664 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 5665 5666 if (((retval = cam_send_ccb(device, ccb)) < 0) 5667 || ((immediate == 0) 5668 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) { 5669 const char errstr[] = "error sending format command"; 5670 5671 if (retval < 0) 5672 warn(errstr); 5673 else 5674 warnx(errstr); 5675 5676 if (arglist & CAM_ARG_VERBOSE) { 5677 cam_error_print(device, ccb, CAM_ESF_ALL, 5678 CAM_EPF_ALL, stderr); 5679 } 5680 error = 1; 5681 goto scsiformat_bailout; 5682 } 5683 5684 /* 5685 * If we ran in non-immediate mode, we already checked for errors 5686 * above and printed out any necessary information. If we're in 5687 * immediate mode, we need to loop through and get status 5688 * information periodically. 5689 */ 5690 if (immediate == 0) { 5691 if (quiet == 0) { 5692 fprintf(stdout, "Format Complete\n"); 5693 } 5694 goto scsiformat_bailout; 5695 } 5696 5697 doreport: 5698 do { 5699 cam_status status; 5700 5701 bzero(&(&ccb->ccb_h)[1], 5702 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 5703 5704 /* 5705 * There's really no need to do error recovery or 5706 * retries here, since we're just going to sit in a 5707 * loop and wait for the device to finish formatting. 5708 */ 5709 scsi_test_unit_ready(&ccb->csio, 5710 /* retries */ 0, 5711 /* cbfcnp */ NULL, 5712 /* tag_action */ MSG_SIMPLE_Q_TAG, 5713 /* sense_len */ SSD_FULL_SIZE, 5714 /* timeout */ 5000); 5715 5716 /* Disable freezing the device queue */ 5717 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 5718 5719 retval = cam_send_ccb(device, ccb); 5720 5721 /* 5722 * If we get an error from the ioctl, bail out. SCSI 5723 * errors are expected. 5724 */ 5725 if (retval < 0) { 5726 warn("error sending CAMIOCOMMAND ioctl"); 5727 if (arglist & CAM_ARG_VERBOSE) { 5728 cam_error_print(device, ccb, CAM_ESF_ALL, 5729 CAM_EPF_ALL, stderr); 5730 } 5731 error = 1; 5732 goto scsiformat_bailout; 5733 } 5734 5735 status = ccb->ccb_h.status & CAM_STATUS_MASK; 5736 5737 if ((status != CAM_REQ_CMP) 5738 && (status == CAM_SCSI_STATUS_ERROR) 5739 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 5740 struct scsi_sense_data *sense; 5741 int error_code, sense_key, asc, ascq; 5742 5743 sense = &ccb->csio.sense_data; 5744 scsi_extract_sense_len(sense, ccb->csio.sense_len - 5745 ccb->csio.sense_resid, &error_code, &sense_key, 5746 &asc, &ascq, /*show_errors*/ 1); 5747 5748 /* 5749 * According to the SCSI-2 and SCSI-3 specs, a 5750 * drive that is in the middle of a format should 5751 * return NOT READY with an ASC of "logical unit 5752 * not ready, format in progress". The sense key 5753 * specific bytes will then be a progress indicator. 5754 */ 5755 if ((sense_key == SSD_KEY_NOT_READY) 5756 && (asc == 0x04) && (ascq == 0x04)) { 5757 uint8_t sks[3]; 5758 5759 if ((scsi_get_sks(sense, ccb->csio.sense_len - 5760 ccb->csio.sense_resid, sks) == 0) 5761 && (quiet == 0)) { 5762 int val; 5763 u_int64_t percentage; 5764 5765 val = scsi_2btoul(&sks[1]); 5766 percentage = 10000 * val; 5767 5768 fprintf(stdout, 5769 "\rFormatting: %ju.%02u %% " 5770 "(%d/%d) done", 5771 (uintmax_t)(percentage / 5772 (0x10000 * 100)), 5773 (unsigned)((percentage / 5774 0x10000) % 100), 5775 val, 0x10000); 5776 fflush(stdout); 5777 } else if ((quiet == 0) 5778 && (++num_warnings <= 1)) { 5779 warnx("Unexpected SCSI Sense Key " 5780 "Specific value returned " 5781 "during format:"); 5782 scsi_sense_print(device, &ccb->csio, 5783 stderr); 5784 warnx("Unable to print status " 5785 "information, but format will " 5786 "proceed."); 5787 warnx("will exit when format is " 5788 "complete"); 5789 } 5790 sleep(1); 5791 } else { 5792 warnx("Unexpected SCSI error during format"); 5793 cam_error_print(device, ccb, CAM_ESF_ALL, 5794 CAM_EPF_ALL, stderr); 5795 error = 1; 5796 goto scsiformat_bailout; 5797 } 5798 5799 } else if (status != CAM_REQ_CMP) { 5800 warnx("Unexpected CAM status %#x", status); 5801 if (arglist & CAM_ARG_VERBOSE) 5802 cam_error_print(device, ccb, CAM_ESF_ALL, 5803 CAM_EPF_ALL, stderr); 5804 error = 1; 5805 goto scsiformat_bailout; 5806 } 5807 5808 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); 5809 5810 if (quiet == 0) 5811 fprintf(stdout, "\nFormat Complete\n"); 5812 5813 scsiformat_bailout: 5814 5815 cam_freeccb(ccb); 5816 5817 return(error); 5818 } 5819 5820 static int 5821 scsisanitize(struct cam_device *device, int argc, char **argv, 5822 char *combinedopt, int retry_count, int timeout) 5823 { 5824 union ccb *ccb; 5825 u_int8_t action = 0; 5826 int c; 5827 int ycount = 0, quiet = 0; 5828 int error = 0, retval = 0; 5829 int use_timeout = 10800 * 1000; 5830 int immediate = 1; 5831 int invert = 0; 5832 int passes = 0; 5833 int ause = 0; 5834 int fd = -1; 5835 const char *pattern = NULL; 5836 u_int8_t *data_ptr = NULL; 5837 u_int32_t dxfer_len = 0; 5838 u_int8_t byte2 = 0; 5839 int num_warnings = 0; 5840 int reportonly = 0; 5841 5842 ccb = cam_getccb(device); 5843 5844 if (ccb == NULL) { 5845 warnx("scsisanitize: error allocating ccb"); 5846 return(1); 5847 } 5848 5849 bzero(&(&ccb->ccb_h)[1], 5850 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 5851 5852 while ((c = getopt(argc, argv, combinedopt)) != -1) { 5853 switch(c) { 5854 case 'a': 5855 if (strcasecmp(optarg, "overwrite") == 0) 5856 action = SSZ_SERVICE_ACTION_OVERWRITE; 5857 else if (strcasecmp(optarg, "block") == 0) 5858 action = SSZ_SERVICE_ACTION_BLOCK_ERASE; 5859 else if (strcasecmp(optarg, "crypto") == 0) 5860 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE; 5861 else if (strcasecmp(optarg, "exitfailure") == 0) 5862 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE; 5863 else { 5864 warnx("invalid service operation \"%s\"", 5865 optarg); 5866 error = 1; 5867 goto scsisanitize_bailout; 5868 } 5869 break; 5870 case 'c': 5871 passes = strtol(optarg, NULL, 0); 5872 if (passes < 1 || passes > 31) { 5873 warnx("invalid passes value %d", passes); 5874 error = 1; 5875 goto scsisanitize_bailout; 5876 } 5877 break; 5878 case 'I': 5879 invert = 1; 5880 break; 5881 case 'P': 5882 pattern = optarg; 5883 break; 5884 case 'q': 5885 quiet++; 5886 break; 5887 case 'U': 5888 ause = 1; 5889 break; 5890 case 'r': 5891 reportonly = 1; 5892 break; 5893 case 'w': 5894 immediate = 0; 5895 break; 5896 case 'y': 5897 ycount++; 5898 break; 5899 } 5900 } 5901 5902 if (reportonly) 5903 goto doreport; 5904 5905 if (action == 0) { 5906 warnx("an action is required"); 5907 error = 1; 5908 goto scsisanitize_bailout; 5909 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) { 5910 struct scsi_sanitize_parameter_list *pl; 5911 struct stat sb; 5912 ssize_t sz, amt; 5913 5914 if (pattern == NULL) { 5915 warnx("overwrite action requires -P argument"); 5916 error = 1; 5917 goto scsisanitize_bailout; 5918 } 5919 fd = open(pattern, O_RDONLY); 5920 if (fd < 0) { 5921 warn("cannot open pattern file %s", pattern); 5922 error = 1; 5923 goto scsisanitize_bailout; 5924 } 5925 if (fstat(fd, &sb) < 0) { 5926 warn("cannot stat pattern file %s", pattern); 5927 error = 1; 5928 goto scsisanitize_bailout; 5929 } 5930 sz = sb.st_size; 5931 if (sz > SSZPL_MAX_PATTERN_LENGTH) { 5932 warnx("pattern file size exceeds maximum value %d", 5933 SSZPL_MAX_PATTERN_LENGTH); 5934 error = 1; 5935 goto scsisanitize_bailout; 5936 } 5937 dxfer_len = sizeof(*pl) + sz; 5938 data_ptr = calloc(1, dxfer_len); 5939 if (data_ptr == NULL) { 5940 warnx("cannot allocate parameter list buffer"); 5941 error = 1; 5942 goto scsisanitize_bailout; 5943 } 5944 5945 amt = read(fd, data_ptr + sizeof(*pl), sz); 5946 if (amt < 0) { 5947 warn("cannot read pattern file"); 5948 error = 1; 5949 goto scsisanitize_bailout; 5950 } else if (amt != sz) { 5951 warnx("short pattern file read"); 5952 error = 1; 5953 goto scsisanitize_bailout; 5954 } 5955 5956 pl = (struct scsi_sanitize_parameter_list *)data_ptr; 5957 if (passes == 0) 5958 pl->byte1 = 1; 5959 else 5960 pl->byte1 = passes; 5961 if (invert != 0) 5962 pl->byte1 |= SSZPL_INVERT; 5963 scsi_ulto2b(sz, pl->length); 5964 } else { 5965 const char *arg; 5966 5967 if (passes != 0) 5968 arg = "-c"; 5969 else if (invert != 0) 5970 arg = "-I"; 5971 else if (pattern != NULL) 5972 arg = "-P"; 5973 else 5974 arg = NULL; 5975 if (arg != NULL) { 5976 warnx("%s argument only valid with overwrite " 5977 "operation", arg); 5978 error = 1; 5979 goto scsisanitize_bailout; 5980 } 5981 } 5982 5983 if (quiet == 0) { 5984 fprintf(stdout, "You are about to REMOVE ALL DATA from the " 5985 "following device:\n"); 5986 5987 error = scsidoinquiry(device, argc, argv, combinedopt, 5988 retry_count, timeout); 5989 5990 if (error != 0) { 5991 warnx("scsisanitize: error sending inquiry"); 5992 goto scsisanitize_bailout; 5993 } 5994 } 5995 5996 if (ycount == 0) { 5997 if (!get_confirmation()) { 5998 error = 1; 5999 goto scsisanitize_bailout; 6000 } 6001 } 6002 6003 if (timeout != 0) 6004 use_timeout = timeout; 6005 6006 if (quiet == 0) { 6007 fprintf(stdout, "Current sanitize timeout is %d seconds\n", 6008 use_timeout / 1000); 6009 } 6010 6011 /* 6012 * If the user hasn't disabled questions and didn't specify a 6013 * timeout on the command line, ask them if they want the current 6014 * timeout. 6015 */ 6016 if ((ycount == 0) 6017 && (timeout == 0)) { 6018 char str[1024]; 6019 int new_timeout = 0; 6020 6021 fprintf(stdout, "Enter new timeout in seconds or press\n" 6022 "return to keep the current timeout [%d] ", 6023 use_timeout / 1000); 6024 6025 if (fgets(str, sizeof(str), stdin) != NULL) { 6026 if (str[0] != '\0') 6027 new_timeout = atoi(str); 6028 } 6029 6030 if (new_timeout != 0) { 6031 use_timeout = new_timeout * 1000; 6032 fprintf(stdout, "Using new timeout value %d\n", 6033 use_timeout / 1000); 6034 } 6035 } 6036 6037 byte2 = action; 6038 if (ause != 0) 6039 byte2 |= SSZ_UNRESTRICTED_EXIT; 6040 if (immediate != 0) 6041 byte2 |= SSZ_IMMED; 6042 6043 scsi_sanitize(&ccb->csio, 6044 /* retries */ retry_count, 6045 /* cbfcnp */ NULL, 6046 /* tag_action */ MSG_SIMPLE_Q_TAG, 6047 /* byte2 */ byte2, 6048 /* control */ 0, 6049 /* data_ptr */ data_ptr, 6050 /* dxfer_len */ dxfer_len, 6051 /* sense_len */ SSD_FULL_SIZE, 6052 /* timeout */ use_timeout); 6053 6054 /* Disable freezing the device queue */ 6055 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6056 6057 if (arglist & CAM_ARG_ERR_RECOVER) 6058 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6059 6060 if (cam_send_ccb(device, ccb) < 0) { 6061 warn("error sending sanitize command"); 6062 error = 1; 6063 goto scsisanitize_bailout; 6064 } 6065 6066 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6067 struct scsi_sense_data *sense; 6068 int error_code, sense_key, asc, ascq; 6069 6070 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 6071 CAM_SCSI_STATUS_ERROR) { 6072 sense = &ccb->csio.sense_data; 6073 scsi_extract_sense_len(sense, ccb->csio.sense_len - 6074 ccb->csio.sense_resid, &error_code, &sense_key, 6075 &asc, &ascq, /*show_errors*/ 1); 6076 6077 if (sense_key == SSD_KEY_ILLEGAL_REQUEST && 6078 asc == 0x20 && ascq == 0x00) 6079 warnx("sanitize is not supported by " 6080 "this device"); 6081 else 6082 warnx("error sanitizing this device"); 6083 } else 6084 warnx("error sanitizing this device"); 6085 6086 if (arglist & CAM_ARG_VERBOSE) { 6087 cam_error_print(device, ccb, CAM_ESF_ALL, 6088 CAM_EPF_ALL, stderr); 6089 } 6090 error = 1; 6091 goto scsisanitize_bailout; 6092 } 6093 6094 /* 6095 * If we ran in non-immediate mode, we already checked for errors 6096 * above and printed out any necessary information. If we're in 6097 * immediate mode, we need to loop through and get status 6098 * information periodically. 6099 */ 6100 if (immediate == 0) { 6101 if (quiet == 0) { 6102 fprintf(stdout, "Sanitize Complete\n"); 6103 } 6104 goto scsisanitize_bailout; 6105 } 6106 6107 doreport: 6108 do { 6109 cam_status status; 6110 6111 bzero(&(&ccb->ccb_h)[1], 6112 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 6113 6114 /* 6115 * There's really no need to do error recovery or 6116 * retries here, since we're just going to sit in a 6117 * loop and wait for the device to finish sanitizing. 6118 */ 6119 scsi_test_unit_ready(&ccb->csio, 6120 /* retries */ 0, 6121 /* cbfcnp */ NULL, 6122 /* tag_action */ MSG_SIMPLE_Q_TAG, 6123 /* sense_len */ SSD_FULL_SIZE, 6124 /* timeout */ 5000); 6125 6126 /* Disable freezing the device queue */ 6127 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6128 6129 retval = cam_send_ccb(device, ccb); 6130 6131 /* 6132 * If we get an error from the ioctl, bail out. SCSI 6133 * errors are expected. 6134 */ 6135 if (retval < 0) { 6136 warn("error sending CAMIOCOMMAND ioctl"); 6137 if (arglist & CAM_ARG_VERBOSE) { 6138 cam_error_print(device, ccb, CAM_ESF_ALL, 6139 CAM_EPF_ALL, stderr); 6140 } 6141 error = 1; 6142 goto scsisanitize_bailout; 6143 } 6144 6145 status = ccb->ccb_h.status & CAM_STATUS_MASK; 6146 6147 if ((status != CAM_REQ_CMP) 6148 && (status == CAM_SCSI_STATUS_ERROR) 6149 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 6150 struct scsi_sense_data *sense; 6151 int error_code, sense_key, asc, ascq; 6152 6153 sense = &ccb->csio.sense_data; 6154 scsi_extract_sense_len(sense, ccb->csio.sense_len - 6155 ccb->csio.sense_resid, &error_code, &sense_key, 6156 &asc, &ascq, /*show_errors*/ 1); 6157 6158 /* 6159 * According to the SCSI-3 spec, a drive that is in the 6160 * middle of a sanitize should return NOT READY with an 6161 * ASC of "logical unit not ready, sanitize in 6162 * progress". The sense key specific bytes will then 6163 * be a progress indicator. 6164 */ 6165 if ((sense_key == SSD_KEY_NOT_READY) 6166 && (asc == 0x04) && (ascq == 0x1b)) { 6167 uint8_t sks[3]; 6168 6169 if ((scsi_get_sks(sense, ccb->csio.sense_len - 6170 ccb->csio.sense_resid, sks) == 0) 6171 && (quiet == 0)) { 6172 int val; 6173 u_int64_t percentage; 6174 6175 val = scsi_2btoul(&sks[1]); 6176 percentage = 10000 * val; 6177 6178 fprintf(stdout, 6179 "\rSanitizing: %ju.%02u %% " 6180 "(%d/%d) done", 6181 (uintmax_t)(percentage / 6182 (0x10000 * 100)), 6183 (unsigned)((percentage / 6184 0x10000) % 100), 6185 val, 0x10000); 6186 fflush(stdout); 6187 } else if ((quiet == 0) 6188 && (++num_warnings <= 1)) { 6189 warnx("Unexpected SCSI Sense Key " 6190 "Specific value returned " 6191 "during sanitize:"); 6192 scsi_sense_print(device, &ccb->csio, 6193 stderr); 6194 warnx("Unable to print status " 6195 "information, but sanitze will " 6196 "proceed."); 6197 warnx("will exit when sanitize is " 6198 "complete"); 6199 } 6200 sleep(1); 6201 } else { 6202 warnx("Unexpected SCSI error during sanitize"); 6203 cam_error_print(device, ccb, CAM_ESF_ALL, 6204 CAM_EPF_ALL, stderr); 6205 error = 1; 6206 goto scsisanitize_bailout; 6207 } 6208 6209 } else if (status != CAM_REQ_CMP) { 6210 warnx("Unexpected CAM status %#x", status); 6211 if (arglist & CAM_ARG_VERBOSE) 6212 cam_error_print(device, ccb, CAM_ESF_ALL, 6213 CAM_EPF_ALL, stderr); 6214 error = 1; 6215 goto scsisanitize_bailout; 6216 } 6217 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); 6218 6219 if (quiet == 0) 6220 fprintf(stdout, "\nSanitize Complete\n"); 6221 6222 scsisanitize_bailout: 6223 if (fd >= 0) 6224 close(fd); 6225 if (data_ptr != NULL) 6226 free(data_ptr); 6227 cam_freeccb(ccb); 6228 6229 return(error); 6230 } 6231 6232 static int 6233 scsireportluns(struct cam_device *device, int argc, char **argv, 6234 char *combinedopt, int retry_count, int timeout) 6235 { 6236 union ccb *ccb; 6237 int c, countonly, lunsonly; 6238 struct scsi_report_luns_data *lundata; 6239 int alloc_len; 6240 uint8_t report_type; 6241 uint32_t list_len, i, j; 6242 int retval; 6243 6244 retval = 0; 6245 lundata = NULL; 6246 report_type = RPL_REPORT_DEFAULT; 6247 ccb = cam_getccb(device); 6248 6249 if (ccb == NULL) { 6250 warnx("%s: error allocating ccb", __func__); 6251 return (1); 6252 } 6253 6254 bzero(&(&ccb->ccb_h)[1], 6255 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 6256 6257 countonly = 0; 6258 lunsonly = 0; 6259 6260 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6261 switch (c) { 6262 case 'c': 6263 countonly++; 6264 break; 6265 case 'l': 6266 lunsonly++; 6267 break; 6268 case 'r': 6269 if (strcasecmp(optarg, "default") == 0) 6270 report_type = RPL_REPORT_DEFAULT; 6271 else if (strcasecmp(optarg, "wellknown") == 0) 6272 report_type = RPL_REPORT_WELLKNOWN; 6273 else if (strcasecmp(optarg, "all") == 0) 6274 report_type = RPL_REPORT_ALL; 6275 else { 6276 warnx("%s: invalid report type \"%s\"", 6277 __func__, optarg); 6278 retval = 1; 6279 goto bailout; 6280 } 6281 break; 6282 default: 6283 break; 6284 } 6285 } 6286 6287 if ((countonly != 0) 6288 && (lunsonly != 0)) { 6289 warnx("%s: you can only specify one of -c or -l", __func__); 6290 retval = 1; 6291 goto bailout; 6292 } 6293 /* 6294 * According to SPC-4, the allocation length must be at least 16 6295 * bytes -- enough for the header and one LUN. 6296 */ 6297 alloc_len = sizeof(*lundata) + 8; 6298 6299 retry: 6300 6301 lundata = malloc(alloc_len); 6302 6303 if (lundata == NULL) { 6304 warn("%s: error mallocing %d bytes", __func__, alloc_len); 6305 retval = 1; 6306 goto bailout; 6307 } 6308 6309 scsi_report_luns(&ccb->csio, 6310 /*retries*/ retry_count, 6311 /*cbfcnp*/ NULL, 6312 /*tag_action*/ MSG_SIMPLE_Q_TAG, 6313 /*select_report*/ report_type, 6314 /*rpl_buf*/ lundata, 6315 /*alloc_len*/ alloc_len, 6316 /*sense_len*/ SSD_FULL_SIZE, 6317 /*timeout*/ timeout ? timeout : 5000); 6318 6319 /* Disable freezing the device queue */ 6320 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6321 6322 if (arglist & CAM_ARG_ERR_RECOVER) 6323 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6324 6325 if (cam_send_ccb(device, ccb) < 0) { 6326 warn("error sending REPORT LUNS command"); 6327 6328 if (arglist & CAM_ARG_VERBOSE) 6329 cam_error_print(device, ccb, CAM_ESF_ALL, 6330 CAM_EPF_ALL, stderr); 6331 6332 retval = 1; 6333 goto bailout; 6334 } 6335 6336 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6337 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 6338 retval = 1; 6339 goto bailout; 6340 } 6341 6342 6343 list_len = scsi_4btoul(lundata->length); 6344 6345 /* 6346 * If we need to list the LUNs, and our allocation 6347 * length was too short, reallocate and retry. 6348 */ 6349 if ((countonly == 0) 6350 && (list_len > (alloc_len - sizeof(*lundata)))) { 6351 alloc_len = list_len + sizeof(*lundata); 6352 free(lundata); 6353 goto retry; 6354 } 6355 6356 if (lunsonly == 0) 6357 fprintf(stdout, "%u LUN%s found\n", list_len / 8, 6358 ((list_len / 8) > 1) ? "s" : ""); 6359 6360 if (countonly != 0) 6361 goto bailout; 6362 6363 for (i = 0; i < (list_len / 8); i++) { 6364 int no_more; 6365 6366 no_more = 0; 6367 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) { 6368 if (j != 0) 6369 fprintf(stdout, ","); 6370 switch (lundata->luns[i].lundata[j] & 6371 RPL_LUNDATA_ATYP_MASK) { 6372 case RPL_LUNDATA_ATYP_PERIPH: 6373 if ((lundata->luns[i].lundata[j] & 6374 RPL_LUNDATA_PERIPH_BUS_MASK) != 0) 6375 fprintf(stdout, "%d:", 6376 lundata->luns[i].lundata[j] & 6377 RPL_LUNDATA_PERIPH_BUS_MASK); 6378 else if ((j == 0) 6379 && ((lundata->luns[i].lundata[j+2] & 6380 RPL_LUNDATA_PERIPH_BUS_MASK) == 0)) 6381 no_more = 1; 6382 6383 fprintf(stdout, "%d", 6384 lundata->luns[i].lundata[j+1]); 6385 break; 6386 case RPL_LUNDATA_ATYP_FLAT: { 6387 uint8_t tmplun[2]; 6388 tmplun[0] = lundata->luns[i].lundata[j] & 6389 RPL_LUNDATA_FLAT_LUN_MASK; 6390 tmplun[1] = lundata->luns[i].lundata[j+1]; 6391 6392 fprintf(stdout, "%d", scsi_2btoul(tmplun)); 6393 no_more = 1; 6394 break; 6395 } 6396 case RPL_LUNDATA_ATYP_LUN: 6397 fprintf(stdout, "%d:%d:%d", 6398 (lundata->luns[i].lundata[j+1] & 6399 RPL_LUNDATA_LUN_BUS_MASK) >> 5, 6400 lundata->luns[i].lundata[j] & 6401 RPL_LUNDATA_LUN_TARG_MASK, 6402 lundata->luns[i].lundata[j+1] & 6403 RPL_LUNDATA_LUN_LUN_MASK); 6404 break; 6405 case RPL_LUNDATA_ATYP_EXTLUN: { 6406 int field_len_code, eam_code; 6407 6408 eam_code = lundata->luns[i].lundata[j] & 6409 RPL_LUNDATA_EXT_EAM_MASK; 6410 field_len_code = (lundata->luns[i].lundata[j] & 6411 RPL_LUNDATA_EXT_LEN_MASK) >> 4; 6412 6413 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK) 6414 && (field_len_code == 0x00)) { 6415 fprintf(stdout, "%d", 6416 lundata->luns[i].lundata[j+1]); 6417 } else if ((eam_code == 6418 RPL_LUNDATA_EXT_EAM_NOT_SPEC) 6419 && (field_len_code == 0x03)) { 6420 uint8_t tmp_lun[8]; 6421 6422 /* 6423 * This format takes up all 8 bytes. 6424 * If we aren't starting at offset 0, 6425 * that's a bug. 6426 */ 6427 if (j != 0) { 6428 fprintf(stdout, "Invalid " 6429 "offset %d for " 6430 "Extended LUN not " 6431 "specified format", j); 6432 no_more = 1; 6433 break; 6434 } 6435 bzero(tmp_lun, sizeof(tmp_lun)); 6436 bcopy(&lundata->luns[i].lundata[j+1], 6437 &tmp_lun[1], sizeof(tmp_lun) - 1); 6438 fprintf(stdout, "%#jx", 6439 (intmax_t)scsi_8btou64(tmp_lun)); 6440 no_more = 1; 6441 } else { 6442 fprintf(stderr, "Unknown Extended LUN" 6443 "Address method %#x, length " 6444 "code %#x", eam_code, 6445 field_len_code); 6446 no_more = 1; 6447 } 6448 break; 6449 } 6450 default: 6451 fprintf(stderr, "Unknown LUN address method " 6452 "%#x\n", lundata->luns[i].lundata[0] & 6453 RPL_LUNDATA_ATYP_MASK); 6454 break; 6455 } 6456 /* 6457 * For the flat addressing method, there are no 6458 * other levels after it. 6459 */ 6460 if (no_more != 0) 6461 break; 6462 } 6463 fprintf(stdout, "\n"); 6464 } 6465 6466 bailout: 6467 6468 cam_freeccb(ccb); 6469 6470 free(lundata); 6471 6472 return (retval); 6473 } 6474 6475 static int 6476 scsireadcapacity(struct cam_device *device, int argc, char **argv, 6477 char *combinedopt, int retry_count, int timeout) 6478 { 6479 union ccb *ccb; 6480 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten; 6481 struct scsi_read_capacity_data rcap; 6482 struct scsi_read_capacity_data_long rcaplong; 6483 uint64_t maxsector; 6484 uint32_t block_len; 6485 int retval; 6486 int c; 6487 6488 blocksizeonly = 0; 6489 humanize = 0; 6490 numblocks = 0; 6491 quiet = 0; 6492 sizeonly = 0; 6493 baseten = 0; 6494 retval = 0; 6495 6496 ccb = cam_getccb(device); 6497 6498 if (ccb == NULL) { 6499 warnx("%s: error allocating ccb", __func__); 6500 return (1); 6501 } 6502 6503 bzero(&(&ccb->ccb_h)[1], 6504 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 6505 6506 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6507 switch (c) { 6508 case 'b': 6509 blocksizeonly++; 6510 break; 6511 case 'h': 6512 humanize++; 6513 baseten = 0; 6514 break; 6515 case 'H': 6516 humanize++; 6517 baseten++; 6518 break; 6519 case 'N': 6520 numblocks++; 6521 break; 6522 case 'q': 6523 quiet++; 6524 break; 6525 case 's': 6526 sizeonly++; 6527 break; 6528 default: 6529 break; 6530 } 6531 } 6532 6533 if ((blocksizeonly != 0) 6534 && (numblocks != 0)) { 6535 warnx("%s: you can only specify one of -b or -N", __func__); 6536 retval = 1; 6537 goto bailout; 6538 } 6539 6540 if ((blocksizeonly != 0) 6541 && (sizeonly != 0)) { 6542 warnx("%s: you can only specify one of -b or -s", __func__); 6543 retval = 1; 6544 goto bailout; 6545 } 6546 6547 if ((humanize != 0) 6548 && (quiet != 0)) { 6549 warnx("%s: you can only specify one of -h/-H or -q", __func__); 6550 retval = 1; 6551 goto bailout; 6552 } 6553 6554 if ((humanize != 0) 6555 && (blocksizeonly != 0)) { 6556 warnx("%s: you can only specify one of -h/-H or -b", __func__); 6557 retval = 1; 6558 goto bailout; 6559 } 6560 6561 scsi_read_capacity(&ccb->csio, 6562 /*retries*/ retry_count, 6563 /*cbfcnp*/ NULL, 6564 /*tag_action*/ MSG_SIMPLE_Q_TAG, 6565 &rcap, 6566 SSD_FULL_SIZE, 6567 /*timeout*/ timeout ? timeout : 5000); 6568 6569 /* Disable freezing the device queue */ 6570 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6571 6572 if (arglist & CAM_ARG_ERR_RECOVER) 6573 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6574 6575 if (cam_send_ccb(device, ccb) < 0) { 6576 warn("error sending READ CAPACITY command"); 6577 6578 if (arglist & CAM_ARG_VERBOSE) 6579 cam_error_print(device, ccb, CAM_ESF_ALL, 6580 CAM_EPF_ALL, stderr); 6581 6582 retval = 1; 6583 goto bailout; 6584 } 6585 6586 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6587 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 6588 retval = 1; 6589 goto bailout; 6590 } 6591 6592 maxsector = scsi_4btoul(rcap.addr); 6593 block_len = scsi_4btoul(rcap.length); 6594 6595 /* 6596 * A last block of 2^32-1 means that the true capacity is over 2TB, 6597 * and we need to issue the long READ CAPACITY to get the real 6598 * capacity. Otherwise, we're all set. 6599 */ 6600 if (maxsector != 0xffffffff) 6601 goto do_print; 6602 6603 scsi_read_capacity_16(&ccb->csio, 6604 /*retries*/ retry_count, 6605 /*cbfcnp*/ NULL, 6606 /*tag_action*/ MSG_SIMPLE_Q_TAG, 6607 /*lba*/ 0, 6608 /*reladdr*/ 0, 6609 /*pmi*/ 0, 6610 /*rcap_buf*/ (uint8_t *)&rcaplong, 6611 /*rcap_buf_len*/ sizeof(rcaplong), 6612 /*sense_len*/ SSD_FULL_SIZE, 6613 /*timeout*/ timeout ? timeout : 5000); 6614 6615 /* Disable freezing the device queue */ 6616 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6617 6618 if (arglist & CAM_ARG_ERR_RECOVER) 6619 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6620 6621 if (cam_send_ccb(device, ccb) < 0) { 6622 warn("error sending READ CAPACITY (16) command"); 6623 6624 if (arglist & CAM_ARG_VERBOSE) 6625 cam_error_print(device, ccb, CAM_ESF_ALL, 6626 CAM_EPF_ALL, stderr); 6627 6628 retval = 1; 6629 goto bailout; 6630 } 6631 6632 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6633 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 6634 retval = 1; 6635 goto bailout; 6636 } 6637 6638 maxsector = scsi_8btou64(rcaplong.addr); 6639 block_len = scsi_4btoul(rcaplong.length); 6640 6641 do_print: 6642 if (blocksizeonly == 0) { 6643 /* 6644 * Humanize implies !quiet, and also implies numblocks. 6645 */ 6646 if (humanize != 0) { 6647 char tmpstr[6]; 6648 int64_t tmpbytes; 6649 int ret; 6650 6651 tmpbytes = (maxsector + 1) * block_len; 6652 ret = humanize_number(tmpstr, sizeof(tmpstr), 6653 tmpbytes, "", HN_AUTOSCALE, 6654 HN_B | HN_DECIMAL | 6655 ((baseten != 0) ? 6656 HN_DIVISOR_1000 : 0)); 6657 if (ret == -1) { 6658 warnx("%s: humanize_number failed!", __func__); 6659 retval = 1; 6660 goto bailout; 6661 } 6662 fprintf(stdout, "Device Size: %s%s", tmpstr, 6663 (sizeonly == 0) ? ", " : "\n"); 6664 } else if (numblocks != 0) { 6665 fprintf(stdout, "%s%ju%s", (quiet == 0) ? 6666 "Blocks: " : "", (uintmax_t)maxsector + 1, 6667 (sizeonly == 0) ? ", " : "\n"); 6668 } else { 6669 fprintf(stdout, "%s%ju%s", (quiet == 0) ? 6670 "Last Block: " : "", (uintmax_t)maxsector, 6671 (sizeonly == 0) ? ", " : "\n"); 6672 } 6673 } 6674 if (sizeonly == 0) 6675 fprintf(stdout, "%s%u%s\n", (quiet == 0) ? 6676 "Block Length: " : "", block_len, (quiet == 0) ? 6677 " bytes" : ""); 6678 bailout: 6679 cam_freeccb(ccb); 6680 6681 return (retval); 6682 } 6683 6684 static int 6685 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, 6686 int retry_count, int timeout) 6687 { 6688 int c, error = 0; 6689 union ccb *ccb; 6690 uint8_t *smp_request = NULL, *smp_response = NULL; 6691 int request_size = 0, response_size = 0; 6692 int fd_request = 0, fd_response = 0; 6693 char *datastr = NULL; 6694 struct get_hook hook; 6695 int retval; 6696 int flags = 0; 6697 6698 /* 6699 * Note that at the moment we don't support sending SMP CCBs to 6700 * devices that aren't probed by CAM. 6701 */ 6702 ccb = cam_getccb(device); 6703 if (ccb == NULL) { 6704 warnx("%s: error allocating CCB", __func__); 6705 return (1); 6706 } 6707 6708 bzero(&(&ccb->ccb_h)[1], 6709 sizeof(union ccb) - sizeof(struct ccb_hdr)); 6710 6711 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6712 switch (c) { 6713 case 'R': 6714 arglist |= CAM_ARG_CMD_IN; 6715 response_size = strtol(optarg, NULL, 0); 6716 if (response_size <= 0) { 6717 warnx("invalid number of response bytes %d", 6718 response_size); 6719 error = 1; 6720 goto smpcmd_bailout; 6721 } 6722 hook.argc = argc - optind; 6723 hook.argv = argv + optind; 6724 hook.got = 0; 6725 optind++; 6726 datastr = cget(&hook, NULL); 6727 /* 6728 * If the user supplied "-" instead of a format, he 6729 * wants the data to be written to stdout. 6730 */ 6731 if ((datastr != NULL) 6732 && (datastr[0] == '-')) 6733 fd_response = 1; 6734 6735 smp_response = (u_int8_t *)malloc(response_size); 6736 if (smp_response == NULL) { 6737 warn("can't malloc memory for SMP response"); 6738 error = 1; 6739 goto smpcmd_bailout; 6740 } 6741 break; 6742 case 'r': 6743 arglist |= CAM_ARG_CMD_OUT; 6744 request_size = strtol(optarg, NULL, 0); 6745 if (request_size <= 0) { 6746 warnx("invalid number of request bytes %d", 6747 request_size); 6748 error = 1; 6749 goto smpcmd_bailout; 6750 } 6751 hook.argc = argc - optind; 6752 hook.argv = argv + optind; 6753 hook.got = 0; 6754 datastr = cget(&hook, NULL); 6755 smp_request = (u_int8_t *)malloc(request_size); 6756 if (smp_request == NULL) { 6757 warn("can't malloc memory for SMP request"); 6758 error = 1; 6759 goto smpcmd_bailout; 6760 } 6761 bzero(smp_request, request_size); 6762 /* 6763 * If the user supplied "-" instead of a format, he 6764 * wants the data to be read from stdin. 6765 */ 6766 if ((datastr != NULL) 6767 && (datastr[0] == '-')) 6768 fd_request = 1; 6769 else 6770 buff_encode_visit(smp_request, request_size, 6771 datastr, 6772 iget, &hook); 6773 optind += hook.got; 6774 break; 6775 default: 6776 break; 6777 } 6778 } 6779 6780 /* 6781 * If fd_data is set, and we're writing to the device, we need to 6782 * read the data the user wants written from stdin. 6783 */ 6784 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) { 6785 ssize_t amt_read; 6786 int amt_to_read = request_size; 6787 u_int8_t *buf_ptr = smp_request; 6788 6789 for (amt_read = 0; amt_to_read > 0; 6790 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) { 6791 if (amt_read == -1) { 6792 warn("error reading data from stdin"); 6793 error = 1; 6794 goto smpcmd_bailout; 6795 } 6796 amt_to_read -= amt_read; 6797 buf_ptr += amt_read; 6798 } 6799 } 6800 6801 if (((arglist & CAM_ARG_CMD_IN) == 0) 6802 || ((arglist & CAM_ARG_CMD_OUT) == 0)) { 6803 warnx("%s: need both the request (-r) and response (-R) " 6804 "arguments", __func__); 6805 error = 1; 6806 goto smpcmd_bailout; 6807 } 6808 6809 flags |= CAM_DEV_QFRZDIS; 6810 6811 cam_fill_smpio(&ccb->smpio, 6812 /*retries*/ retry_count, 6813 /*cbfcnp*/ NULL, 6814 /*flags*/ flags, 6815 /*smp_request*/ smp_request, 6816 /*smp_request_len*/ request_size, 6817 /*smp_response*/ smp_response, 6818 /*smp_response_len*/ response_size, 6819 /*timeout*/ timeout ? timeout : 5000); 6820 6821 ccb->smpio.flags = SMP_FLAG_NONE; 6822 6823 if (((retval = cam_send_ccb(device, ccb)) < 0) 6824 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 6825 const char warnstr[] = "error sending command"; 6826 6827 if (retval < 0) 6828 warn(warnstr); 6829 else 6830 warnx(warnstr); 6831 6832 if (arglist & CAM_ARG_VERBOSE) { 6833 cam_error_print(device, ccb, CAM_ESF_ALL, 6834 CAM_EPF_ALL, stderr); 6835 } 6836 } 6837 6838 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 6839 && (response_size > 0)) { 6840 if (fd_response == 0) { 6841 buff_decode_visit(smp_response, response_size, 6842 datastr, arg_put, NULL); 6843 fprintf(stdout, "\n"); 6844 } else { 6845 ssize_t amt_written; 6846 int amt_to_write = response_size; 6847 u_int8_t *buf_ptr = smp_response; 6848 6849 for (amt_written = 0; (amt_to_write > 0) && 6850 (amt_written = write(STDOUT_FILENO, buf_ptr, 6851 amt_to_write)) > 0;){ 6852 amt_to_write -= amt_written; 6853 buf_ptr += amt_written; 6854 } 6855 if (amt_written == -1) { 6856 warn("error writing data to stdout"); 6857 error = 1; 6858 goto smpcmd_bailout; 6859 } else if ((amt_written == 0) 6860 && (amt_to_write > 0)) { 6861 warnx("only wrote %u bytes out of %u", 6862 response_size - amt_to_write, 6863 response_size); 6864 } 6865 } 6866 } 6867 smpcmd_bailout: 6868 if (ccb != NULL) 6869 cam_freeccb(ccb); 6870 6871 if (smp_request != NULL) 6872 free(smp_request); 6873 6874 if (smp_response != NULL) 6875 free(smp_response); 6876 6877 return (error); 6878 } 6879 6880 static int 6881 smpreportgeneral(struct cam_device *device, int argc, char **argv, 6882 char *combinedopt, int retry_count, int timeout) 6883 { 6884 union ccb *ccb; 6885 struct smp_report_general_request *request = NULL; 6886 struct smp_report_general_response *response = NULL; 6887 struct sbuf *sb = NULL; 6888 int error = 0; 6889 int c, long_response = 0; 6890 int retval; 6891 6892 /* 6893 * Note that at the moment we don't support sending SMP CCBs to 6894 * devices that aren't probed by CAM. 6895 */ 6896 ccb = cam_getccb(device); 6897 if (ccb == NULL) { 6898 warnx("%s: error allocating CCB", __func__); 6899 return (1); 6900 } 6901 6902 bzero(&(&ccb->ccb_h)[1], 6903 sizeof(union ccb) - sizeof(struct ccb_hdr)); 6904 6905 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6906 switch (c) { 6907 case 'l': 6908 long_response = 1; 6909 break; 6910 default: 6911 break; 6912 } 6913 } 6914 request = malloc(sizeof(*request)); 6915 if (request == NULL) { 6916 warn("%s: unable to allocate %zd bytes", __func__, 6917 sizeof(*request)); 6918 error = 1; 6919 goto bailout; 6920 } 6921 6922 response = malloc(sizeof(*response)); 6923 if (response == NULL) { 6924 warn("%s: unable to allocate %zd bytes", __func__, 6925 sizeof(*response)); 6926 error = 1; 6927 goto bailout; 6928 } 6929 6930 try_long: 6931 smp_report_general(&ccb->smpio, 6932 retry_count, 6933 /*cbfcnp*/ NULL, 6934 request, 6935 /*request_len*/ sizeof(*request), 6936 (uint8_t *)response, 6937 /*response_len*/ sizeof(*response), 6938 /*long_response*/ long_response, 6939 timeout); 6940 6941 if (((retval = cam_send_ccb(device, ccb)) < 0) 6942 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 6943 const char warnstr[] = "error sending command"; 6944 6945 if (retval < 0) 6946 warn(warnstr); 6947 else 6948 warnx(warnstr); 6949 6950 if (arglist & CAM_ARG_VERBOSE) { 6951 cam_error_print(device, ccb, CAM_ESF_ALL, 6952 CAM_EPF_ALL, stderr); 6953 } 6954 error = 1; 6955 goto bailout; 6956 } 6957 6958 /* 6959 * If the device supports the long response bit, try again and see 6960 * if we can get all of the data. 6961 */ 6962 if ((response->long_response & SMP_RG_LONG_RESPONSE) 6963 && (long_response == 0)) { 6964 ccb->ccb_h.status = CAM_REQ_INPROG; 6965 bzero(&(&ccb->ccb_h)[1], 6966 sizeof(union ccb) - sizeof(struct ccb_hdr)); 6967 long_response = 1; 6968 goto try_long; 6969 } 6970 6971 /* 6972 * XXX KDM detect and decode SMP errors here. 6973 */ 6974 sb = sbuf_new_auto(); 6975 if (sb == NULL) { 6976 warnx("%s: error allocating sbuf", __func__); 6977 goto bailout; 6978 } 6979 6980 smp_report_general_sbuf(response, sizeof(*response), sb); 6981 6982 if (sbuf_finish(sb) != 0) { 6983 warnx("%s: sbuf_finish", __func__); 6984 goto bailout; 6985 } 6986 6987 printf("%s", sbuf_data(sb)); 6988 6989 bailout: 6990 if (ccb != NULL) 6991 cam_freeccb(ccb); 6992 6993 if (request != NULL) 6994 free(request); 6995 6996 if (response != NULL) 6997 free(response); 6998 6999 if (sb != NULL) 7000 sbuf_delete(sb); 7001 7002 return (error); 7003 } 7004 7005 static struct camcontrol_opts phy_ops[] = { 7006 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL}, 7007 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL}, 7008 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL}, 7009 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL}, 7010 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL}, 7011 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL}, 7012 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL}, 7013 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL}, 7014 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL}, 7015 {NULL, 0, 0, NULL} 7016 }; 7017 7018 static int 7019 smpphycontrol(struct cam_device *device, int argc, char **argv, 7020 char *combinedopt, int retry_count, int timeout) 7021 { 7022 union ccb *ccb; 7023 struct smp_phy_control_request *request = NULL; 7024 struct smp_phy_control_response *response = NULL; 7025 int long_response = 0; 7026 int retval = 0; 7027 int phy = -1; 7028 uint32_t phy_operation = SMP_PC_PHY_OP_NOP; 7029 int phy_op_set = 0; 7030 uint64_t attached_dev_name = 0; 7031 int dev_name_set = 0; 7032 uint32_t min_plr = 0, max_plr = 0; 7033 uint32_t pp_timeout_val = 0; 7034 int slumber_partial = 0; 7035 int set_pp_timeout_val = 0; 7036 int c; 7037 7038 /* 7039 * Note that at the moment we don't support sending SMP CCBs to 7040 * devices that aren't probed by CAM. 7041 */ 7042 ccb = cam_getccb(device); 7043 if (ccb == NULL) { 7044 warnx("%s: error allocating CCB", __func__); 7045 return (1); 7046 } 7047 7048 bzero(&(&ccb->ccb_h)[1], 7049 sizeof(union ccb) - sizeof(struct ccb_hdr)); 7050 7051 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7052 switch (c) { 7053 case 'a': 7054 case 'A': 7055 case 's': 7056 case 'S': { 7057 int enable = -1; 7058 7059 if (strcasecmp(optarg, "enable") == 0) 7060 enable = 1; 7061 else if (strcasecmp(optarg, "disable") == 0) 7062 enable = 2; 7063 else { 7064 warnx("%s: Invalid argument %s", __func__, 7065 optarg); 7066 retval = 1; 7067 goto bailout; 7068 } 7069 switch (c) { 7070 case 's': 7071 slumber_partial |= enable << 7072 SMP_PC_SAS_SLUMBER_SHIFT; 7073 break; 7074 case 'S': 7075 slumber_partial |= enable << 7076 SMP_PC_SAS_PARTIAL_SHIFT; 7077 break; 7078 case 'a': 7079 slumber_partial |= enable << 7080 SMP_PC_SATA_SLUMBER_SHIFT; 7081 break; 7082 case 'A': 7083 slumber_partial |= enable << 7084 SMP_PC_SATA_PARTIAL_SHIFT; 7085 break; 7086 default: 7087 warnx("%s: programmer error", __func__); 7088 retval = 1; 7089 goto bailout; 7090 break; /*NOTREACHED*/ 7091 } 7092 break; 7093 } 7094 case 'd': 7095 attached_dev_name = (uintmax_t)strtoumax(optarg, 7096 NULL,0); 7097 dev_name_set = 1; 7098 break; 7099 case 'l': 7100 long_response = 1; 7101 break; 7102 case 'm': 7103 /* 7104 * We don't do extensive checking here, so this 7105 * will continue to work when new speeds come out. 7106 */ 7107 min_plr = strtoul(optarg, NULL, 0); 7108 if ((min_plr == 0) 7109 || (min_plr > 0xf)) { 7110 warnx("%s: invalid link rate %x", 7111 __func__, min_plr); 7112 retval = 1; 7113 goto bailout; 7114 } 7115 break; 7116 case 'M': 7117 /* 7118 * We don't do extensive checking here, so this 7119 * will continue to work when new speeds come out. 7120 */ 7121 max_plr = strtoul(optarg, NULL, 0); 7122 if ((max_plr == 0) 7123 || (max_plr > 0xf)) { 7124 warnx("%s: invalid link rate %x", 7125 __func__, max_plr); 7126 retval = 1; 7127 goto bailout; 7128 } 7129 break; 7130 case 'o': { 7131 camcontrol_optret optreturn; 7132 cam_argmask argnums; 7133 const char *subopt; 7134 7135 if (phy_op_set != 0) { 7136 warnx("%s: only one phy operation argument " 7137 "(-o) allowed", __func__); 7138 retval = 1; 7139 goto bailout; 7140 } 7141 7142 phy_op_set = 1; 7143 7144 /* 7145 * Allow the user to specify the phy operation 7146 * numerically, as well as with a name. This will 7147 * future-proof it a bit, so options that are added 7148 * in future specs can be used. 7149 */ 7150 if (isdigit(optarg[0])) { 7151 phy_operation = strtoul(optarg, NULL, 0); 7152 if ((phy_operation == 0) 7153 || (phy_operation > 0xff)) { 7154 warnx("%s: invalid phy operation %#x", 7155 __func__, phy_operation); 7156 retval = 1; 7157 goto bailout; 7158 } 7159 break; 7160 } 7161 optreturn = getoption(phy_ops, optarg, &phy_operation, 7162 &argnums, &subopt); 7163 7164 if (optreturn == CC_OR_AMBIGUOUS) { 7165 warnx("%s: ambiguous option %s", __func__, 7166 optarg); 7167 usage(0); 7168 retval = 1; 7169 goto bailout; 7170 } else if (optreturn == CC_OR_NOT_FOUND) { 7171 warnx("%s: option %s not found", __func__, 7172 optarg); 7173 usage(0); 7174 retval = 1; 7175 goto bailout; 7176 } 7177 break; 7178 } 7179 case 'p': 7180 phy = atoi(optarg); 7181 break; 7182 case 'T': 7183 pp_timeout_val = strtoul(optarg, NULL, 0); 7184 if (pp_timeout_val > 15) { 7185 warnx("%s: invalid partial pathway timeout " 7186 "value %u, need a value less than 16", 7187 __func__, pp_timeout_val); 7188 retval = 1; 7189 goto bailout; 7190 } 7191 set_pp_timeout_val = 1; 7192 break; 7193 default: 7194 break; 7195 } 7196 } 7197 7198 if (phy == -1) { 7199 warnx("%s: a PHY (-p phy) argument is required",__func__); 7200 retval = 1; 7201 goto bailout; 7202 } 7203 7204 if (((dev_name_set != 0) 7205 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME)) 7206 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME) 7207 && (dev_name_set == 0))) { 7208 warnx("%s: -d name and -o setdevname arguments both " 7209 "required to set device name", __func__); 7210 retval = 1; 7211 goto bailout; 7212 } 7213 7214 request = malloc(sizeof(*request)); 7215 if (request == NULL) { 7216 warn("%s: unable to allocate %zd bytes", __func__, 7217 sizeof(*request)); 7218 retval = 1; 7219 goto bailout; 7220 } 7221 7222 response = malloc(sizeof(*response)); 7223 if (response == NULL) { 7224 warn("%s: unable to allocate %zd bytes", __func__, 7225 sizeof(*request)); 7226 retval = 1; 7227 goto bailout; 7228 } 7229 7230 smp_phy_control(&ccb->smpio, 7231 retry_count, 7232 /*cbfcnp*/ NULL, 7233 request, 7234 sizeof(*request), 7235 (uint8_t *)response, 7236 sizeof(*response), 7237 long_response, 7238 /*expected_exp_change_count*/ 0, 7239 phy, 7240 phy_operation, 7241 (set_pp_timeout_val != 0) ? 1 : 0, 7242 attached_dev_name, 7243 min_plr, 7244 max_plr, 7245 slumber_partial, 7246 pp_timeout_val, 7247 timeout); 7248 7249 if (((retval = cam_send_ccb(device, ccb)) < 0) 7250 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7251 const char warnstr[] = "error sending command"; 7252 7253 if (retval < 0) 7254 warn(warnstr); 7255 else 7256 warnx(warnstr); 7257 7258 if (arglist & CAM_ARG_VERBOSE) { 7259 /* 7260 * Use CAM_EPF_NORMAL so we only get one line of 7261 * SMP command decoding. 7262 */ 7263 cam_error_print(device, ccb, CAM_ESF_ALL, 7264 CAM_EPF_NORMAL, stderr); 7265 } 7266 retval = 1; 7267 goto bailout; 7268 } 7269 7270 /* XXX KDM print out something here for success? */ 7271 bailout: 7272 if (ccb != NULL) 7273 cam_freeccb(ccb); 7274 7275 if (request != NULL) 7276 free(request); 7277 7278 if (response != NULL) 7279 free(response); 7280 7281 return (retval); 7282 } 7283 7284 static int 7285 smpmaninfo(struct cam_device *device, int argc, char **argv, 7286 char *combinedopt, int retry_count, int timeout) 7287 { 7288 union ccb *ccb; 7289 struct smp_report_manuf_info_request request; 7290 struct smp_report_manuf_info_response response; 7291 struct sbuf *sb = NULL; 7292 int long_response = 0; 7293 int retval = 0; 7294 int c; 7295 7296 /* 7297 * Note that at the moment we don't support sending SMP CCBs to 7298 * devices that aren't probed by CAM. 7299 */ 7300 ccb = cam_getccb(device); 7301 if (ccb == NULL) { 7302 warnx("%s: error allocating CCB", __func__); 7303 return (1); 7304 } 7305 7306 bzero(&(&ccb->ccb_h)[1], 7307 sizeof(union ccb) - sizeof(struct ccb_hdr)); 7308 7309 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7310 switch (c) { 7311 case 'l': 7312 long_response = 1; 7313 break; 7314 default: 7315 break; 7316 } 7317 } 7318 bzero(&request, sizeof(request)); 7319 bzero(&response, sizeof(response)); 7320 7321 smp_report_manuf_info(&ccb->smpio, 7322 retry_count, 7323 /*cbfcnp*/ NULL, 7324 &request, 7325 sizeof(request), 7326 (uint8_t *)&response, 7327 sizeof(response), 7328 long_response, 7329 timeout); 7330 7331 if (((retval = cam_send_ccb(device, ccb)) < 0) 7332 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7333 const char warnstr[] = "error sending command"; 7334 7335 if (retval < 0) 7336 warn(warnstr); 7337 else 7338 warnx(warnstr); 7339 7340 if (arglist & CAM_ARG_VERBOSE) { 7341 cam_error_print(device, ccb, CAM_ESF_ALL, 7342 CAM_EPF_ALL, stderr); 7343 } 7344 retval = 1; 7345 goto bailout; 7346 } 7347 7348 sb = sbuf_new_auto(); 7349 if (sb == NULL) { 7350 warnx("%s: error allocating sbuf", __func__); 7351 goto bailout; 7352 } 7353 7354 smp_report_manuf_info_sbuf(&response, sizeof(response), sb); 7355 7356 if (sbuf_finish(sb) != 0) { 7357 warnx("%s: sbuf_finish", __func__); 7358 goto bailout; 7359 } 7360 7361 printf("%s", sbuf_data(sb)); 7362 7363 bailout: 7364 7365 if (ccb != NULL) 7366 cam_freeccb(ccb); 7367 7368 if (sb != NULL) 7369 sbuf_delete(sb); 7370 7371 return (retval); 7372 } 7373 7374 static int 7375 getdevid(struct cam_devitem *item) 7376 { 7377 int retval = 0; 7378 union ccb *ccb = NULL; 7379 7380 struct cam_device *dev; 7381 7382 dev = cam_open_btl(item->dev_match.path_id, 7383 item->dev_match.target_id, 7384 item->dev_match.target_lun, O_RDWR, NULL); 7385 7386 if (dev == NULL) { 7387 warnx("%s", cam_errbuf); 7388 retval = 1; 7389 goto bailout; 7390 } 7391 7392 item->device_id_len = 0; 7393 7394 ccb = cam_getccb(dev); 7395 if (ccb == NULL) { 7396 warnx("%s: error allocating CCB", __func__); 7397 retval = 1; 7398 goto bailout; 7399 } 7400 7401 bzero(&(&ccb->ccb_h)[1], 7402 sizeof(union ccb) - sizeof(struct ccb_hdr)); 7403 7404 /* 7405 * On the first try, we just probe for the size of the data, and 7406 * then allocate that much memory and try again. 7407 */ 7408 retry: 7409 ccb->ccb_h.func_code = XPT_DEV_ADVINFO; 7410 ccb->ccb_h.flags = CAM_DIR_IN; 7411 ccb->cdai.flags = CDAI_FLAG_NONE; 7412 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID; 7413 ccb->cdai.bufsiz = item->device_id_len; 7414 if (item->device_id_len != 0) 7415 ccb->cdai.buf = (uint8_t *)item->device_id; 7416 7417 if (cam_send_ccb(dev, ccb) < 0) { 7418 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__); 7419 retval = 1; 7420 goto bailout; 7421 } 7422 7423 if (ccb->ccb_h.status != CAM_REQ_CMP) { 7424 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status); 7425 retval = 1; 7426 goto bailout; 7427 } 7428 7429 if (item->device_id_len == 0) { 7430 /* 7431 * This is our first time through. Allocate the buffer, 7432 * and then go back to get the data. 7433 */ 7434 if (ccb->cdai.provsiz == 0) { 7435 warnx("%s: invalid .provsiz field returned with " 7436 "XPT_GDEV_ADVINFO CCB", __func__); 7437 retval = 1; 7438 goto bailout; 7439 } 7440 item->device_id_len = ccb->cdai.provsiz; 7441 item->device_id = malloc(item->device_id_len); 7442 if (item->device_id == NULL) { 7443 warn("%s: unable to allocate %d bytes", __func__, 7444 item->device_id_len); 7445 retval = 1; 7446 goto bailout; 7447 } 7448 ccb->ccb_h.status = CAM_REQ_INPROG; 7449 goto retry; 7450 } 7451 7452 bailout: 7453 if (dev != NULL) 7454 cam_close_device(dev); 7455 7456 if (ccb != NULL) 7457 cam_freeccb(ccb); 7458 7459 return (retval); 7460 } 7461 7462 /* 7463 * XXX KDM merge this code with getdevtree()? 7464 */ 7465 static int 7466 buildbusdevlist(struct cam_devlist *devlist) 7467 { 7468 union ccb ccb; 7469 int bufsize, fd = -1; 7470 struct dev_match_pattern *patterns; 7471 struct cam_devitem *item = NULL; 7472 int skip_device = 0; 7473 int retval = 0; 7474 7475 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { 7476 warn("couldn't open %s", XPT_DEVICE); 7477 return(1); 7478 } 7479 7480 bzero(&ccb, sizeof(union ccb)); 7481 7482 ccb.ccb_h.path_id = CAM_XPT_PATH_ID; 7483 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 7484 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 7485 7486 ccb.ccb_h.func_code = XPT_DEV_MATCH; 7487 bufsize = sizeof(struct dev_match_result) * 100; 7488 ccb.cdm.match_buf_len = bufsize; 7489 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); 7490 if (ccb.cdm.matches == NULL) { 7491 warnx("can't malloc memory for matches"); 7492 close(fd); 7493 return(1); 7494 } 7495 ccb.cdm.num_matches = 0; 7496 ccb.cdm.num_patterns = 2; 7497 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) * 7498 ccb.cdm.num_patterns; 7499 7500 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len); 7501 if (patterns == NULL) { 7502 warnx("can't malloc memory for patterns"); 7503 retval = 1; 7504 goto bailout; 7505 } 7506 7507 ccb.cdm.patterns = patterns; 7508 bzero(patterns, ccb.cdm.pattern_buf_len); 7509 7510 patterns[0].type = DEV_MATCH_DEVICE; 7511 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH; 7512 patterns[0].pattern.device_pattern.path_id = devlist->path_id; 7513 patterns[1].type = DEV_MATCH_PERIPH; 7514 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH; 7515 patterns[1].pattern.periph_pattern.path_id = devlist->path_id; 7516 7517 /* 7518 * We do the ioctl multiple times if necessary, in case there are 7519 * more than 100 nodes in the EDT. 7520 */ 7521 do { 7522 unsigned int i; 7523 7524 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 7525 warn("error sending CAMIOCOMMAND ioctl"); 7526 retval = 1; 7527 goto bailout; 7528 } 7529 7530 if ((ccb.ccb_h.status != CAM_REQ_CMP) 7531 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) 7532 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { 7533 warnx("got CAM error %#x, CDM error %d\n", 7534 ccb.ccb_h.status, ccb.cdm.status); 7535 retval = 1; 7536 goto bailout; 7537 } 7538 7539 for (i = 0; i < ccb.cdm.num_matches; i++) { 7540 switch (ccb.cdm.matches[i].type) { 7541 case DEV_MATCH_DEVICE: { 7542 struct device_match_result *dev_result; 7543 7544 dev_result = 7545 &ccb.cdm.matches[i].result.device_result; 7546 7547 if (dev_result->flags & 7548 DEV_RESULT_UNCONFIGURED) { 7549 skip_device = 1; 7550 break; 7551 } else 7552 skip_device = 0; 7553 7554 item = malloc(sizeof(*item)); 7555 if (item == NULL) { 7556 warn("%s: unable to allocate %zd bytes", 7557 __func__, sizeof(*item)); 7558 retval = 1; 7559 goto bailout; 7560 } 7561 bzero(item, sizeof(*item)); 7562 bcopy(dev_result, &item->dev_match, 7563 sizeof(*dev_result)); 7564 STAILQ_INSERT_TAIL(&devlist->dev_queue, item, 7565 links); 7566 7567 if (getdevid(item) != 0) { 7568 retval = 1; 7569 goto bailout; 7570 } 7571 break; 7572 } 7573 case DEV_MATCH_PERIPH: { 7574 struct periph_match_result *periph_result; 7575 7576 periph_result = 7577 &ccb.cdm.matches[i].result.periph_result; 7578 7579 if (skip_device != 0) 7580 break; 7581 item->num_periphs++; 7582 item->periph_matches = realloc( 7583 item->periph_matches, 7584 item->num_periphs * 7585 sizeof(struct periph_match_result)); 7586 if (item->periph_matches == NULL) { 7587 warn("%s: error allocating periph " 7588 "list", __func__); 7589 retval = 1; 7590 goto bailout; 7591 } 7592 bcopy(periph_result, &item->periph_matches[ 7593 item->num_periphs - 1], 7594 sizeof(*periph_result)); 7595 break; 7596 } 7597 default: 7598 fprintf(stderr, "%s: unexpected match " 7599 "type %d\n", __func__, 7600 ccb.cdm.matches[i].type); 7601 retval = 1; 7602 goto bailout; 7603 break; /*NOTREACHED*/ 7604 } 7605 } 7606 } while ((ccb.ccb_h.status == CAM_REQ_CMP) 7607 && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); 7608 bailout: 7609 7610 if (fd != -1) 7611 close(fd); 7612 7613 free(patterns); 7614 7615 free(ccb.cdm.matches); 7616 7617 if (retval != 0) 7618 freebusdevlist(devlist); 7619 7620 return (retval); 7621 } 7622 7623 static void 7624 freebusdevlist(struct cam_devlist *devlist) 7625 { 7626 struct cam_devitem *item, *item2; 7627 7628 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) { 7629 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem, 7630 links); 7631 free(item->device_id); 7632 free(item->periph_matches); 7633 free(item); 7634 } 7635 } 7636 7637 static struct cam_devitem * 7638 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr) 7639 { 7640 struct cam_devitem *item; 7641 7642 STAILQ_FOREACH(item, &devlist->dev_queue, links) { 7643 struct scsi_vpd_id_descriptor *idd; 7644 7645 /* 7646 * XXX KDM look for LUN IDs as well? 7647 */ 7648 idd = scsi_get_devid(item->device_id, 7649 item->device_id_len, 7650 scsi_devid_is_sas_target); 7651 if (idd == NULL) 7652 continue; 7653 7654 if (scsi_8btou64(idd->identifier) == sasaddr) 7655 return (item); 7656 } 7657 7658 return (NULL); 7659 } 7660 7661 static int 7662 smpphylist(struct cam_device *device, int argc, char **argv, 7663 char *combinedopt, int retry_count, int timeout) 7664 { 7665 struct smp_report_general_request *rgrequest = NULL; 7666 struct smp_report_general_response *rgresponse = NULL; 7667 struct smp_discover_request *disrequest = NULL; 7668 struct smp_discover_response *disresponse = NULL; 7669 struct cam_devlist devlist; 7670 union ccb *ccb; 7671 int long_response = 0; 7672 int num_phys = 0; 7673 int quiet = 0; 7674 int retval; 7675 int i, c; 7676 7677 /* 7678 * Note that at the moment we don't support sending SMP CCBs to 7679 * devices that aren't probed by CAM. 7680 */ 7681 ccb = cam_getccb(device); 7682 if (ccb == NULL) { 7683 warnx("%s: error allocating CCB", __func__); 7684 return (1); 7685 } 7686 7687 bzero(&(&ccb->ccb_h)[1], 7688 sizeof(union ccb) - sizeof(struct ccb_hdr)); 7689 STAILQ_INIT(&devlist.dev_queue); 7690 7691 rgrequest = malloc(sizeof(*rgrequest)); 7692 if (rgrequest == NULL) { 7693 warn("%s: unable to allocate %zd bytes", __func__, 7694 sizeof(*rgrequest)); 7695 retval = 1; 7696 goto bailout; 7697 } 7698 7699 rgresponse = malloc(sizeof(*rgresponse)); 7700 if (rgresponse == NULL) { 7701 warn("%s: unable to allocate %zd bytes", __func__, 7702 sizeof(*rgresponse)); 7703 retval = 1; 7704 goto bailout; 7705 } 7706 7707 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7708 switch (c) { 7709 case 'l': 7710 long_response = 1; 7711 break; 7712 case 'q': 7713 quiet = 1; 7714 break; 7715 default: 7716 break; 7717 } 7718 } 7719 7720 smp_report_general(&ccb->smpio, 7721 retry_count, 7722 /*cbfcnp*/ NULL, 7723 rgrequest, 7724 /*request_len*/ sizeof(*rgrequest), 7725 (uint8_t *)rgresponse, 7726 /*response_len*/ sizeof(*rgresponse), 7727 /*long_response*/ long_response, 7728 timeout); 7729 7730 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 7731 7732 if (((retval = cam_send_ccb(device, ccb)) < 0) 7733 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7734 const char warnstr[] = "error sending command"; 7735 7736 if (retval < 0) 7737 warn(warnstr); 7738 else 7739 warnx(warnstr); 7740 7741 if (arglist & CAM_ARG_VERBOSE) { 7742 cam_error_print(device, ccb, CAM_ESF_ALL, 7743 CAM_EPF_ALL, stderr); 7744 } 7745 retval = 1; 7746 goto bailout; 7747 } 7748 7749 num_phys = rgresponse->num_phys; 7750 7751 if (num_phys == 0) { 7752 if (quiet == 0) 7753 fprintf(stdout, "%s: No Phys reported\n", __func__); 7754 retval = 1; 7755 goto bailout; 7756 } 7757 7758 devlist.path_id = device->path_id; 7759 7760 retval = buildbusdevlist(&devlist); 7761 if (retval != 0) 7762 goto bailout; 7763 7764 if (quiet == 0) { 7765 fprintf(stdout, "%d PHYs:\n", num_phys); 7766 fprintf(stdout, "PHY Attached SAS Address\n"); 7767 } 7768 7769 disrequest = malloc(sizeof(*disrequest)); 7770 if (disrequest == NULL) { 7771 warn("%s: unable to allocate %zd bytes", __func__, 7772 sizeof(*disrequest)); 7773 retval = 1; 7774 goto bailout; 7775 } 7776 7777 disresponse = malloc(sizeof(*disresponse)); 7778 if (disresponse == NULL) { 7779 warn("%s: unable to allocate %zd bytes", __func__, 7780 sizeof(*disresponse)); 7781 retval = 1; 7782 goto bailout; 7783 } 7784 7785 for (i = 0; i < num_phys; i++) { 7786 struct cam_devitem *item; 7787 struct device_match_result *dev_match; 7788 char vendor[16], product[48], revision[16]; 7789 char tmpstr[256]; 7790 int j; 7791 7792 bzero(&(&ccb->ccb_h)[1], 7793 sizeof(union ccb) - sizeof(struct ccb_hdr)); 7794 7795 ccb->ccb_h.status = CAM_REQ_INPROG; 7796 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 7797 7798 smp_discover(&ccb->smpio, 7799 retry_count, 7800 /*cbfcnp*/ NULL, 7801 disrequest, 7802 sizeof(*disrequest), 7803 (uint8_t *)disresponse, 7804 sizeof(*disresponse), 7805 long_response, 7806 /*ignore_zone_group*/ 0, 7807 /*phy*/ i, 7808 timeout); 7809 7810 if (((retval = cam_send_ccb(device, ccb)) < 0) 7811 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 7812 && (disresponse->function_result != SMP_FR_PHY_VACANT))) { 7813 const char warnstr[] = "error sending command"; 7814 7815 if (retval < 0) 7816 warn(warnstr); 7817 else 7818 warnx(warnstr); 7819 7820 if (arglist & CAM_ARG_VERBOSE) { 7821 cam_error_print(device, ccb, CAM_ESF_ALL, 7822 CAM_EPF_ALL, stderr); 7823 } 7824 retval = 1; 7825 goto bailout; 7826 } 7827 7828 if (disresponse->function_result == SMP_FR_PHY_VACANT) { 7829 if (quiet == 0) 7830 fprintf(stdout, "%3d <vacant>\n", i); 7831 continue; 7832 } 7833 7834 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) { 7835 item = NULL; 7836 } else { 7837 item = findsasdevice(&devlist, 7838 scsi_8btou64(disresponse->attached_sas_address)); 7839 } 7840 7841 if ((quiet == 0) 7842 || (item != NULL)) { 7843 fprintf(stdout, "%3d 0x%016jx", i, 7844 (uintmax_t)scsi_8btou64( 7845 disresponse->attached_sas_address)); 7846 if (item == NULL) { 7847 fprintf(stdout, "\n"); 7848 continue; 7849 } 7850 } else if (quiet != 0) 7851 continue; 7852 7853 dev_match = &item->dev_match; 7854 7855 if (dev_match->protocol == PROTO_SCSI) { 7856 cam_strvis(vendor, dev_match->inq_data.vendor, 7857 sizeof(dev_match->inq_data.vendor), 7858 sizeof(vendor)); 7859 cam_strvis(product, dev_match->inq_data.product, 7860 sizeof(dev_match->inq_data.product), 7861 sizeof(product)); 7862 cam_strvis(revision, dev_match->inq_data.revision, 7863 sizeof(dev_match->inq_data.revision), 7864 sizeof(revision)); 7865 sprintf(tmpstr, "<%s %s %s>", vendor, product, 7866 revision); 7867 } else if ((dev_match->protocol == PROTO_ATA) 7868 || (dev_match->protocol == PROTO_SATAPM)) { 7869 cam_strvis(product, dev_match->ident_data.model, 7870 sizeof(dev_match->ident_data.model), 7871 sizeof(product)); 7872 cam_strvis(revision, dev_match->ident_data.revision, 7873 sizeof(dev_match->ident_data.revision), 7874 sizeof(revision)); 7875 sprintf(tmpstr, "<%s %s>", product, revision); 7876 } else { 7877 sprintf(tmpstr, "<>"); 7878 } 7879 fprintf(stdout, " %-33s ", tmpstr); 7880 7881 /* 7882 * If we have 0 periphs, that's a bug... 7883 */ 7884 if (item->num_periphs == 0) { 7885 fprintf(stdout, "\n"); 7886 continue; 7887 } 7888 7889 fprintf(stdout, "("); 7890 for (j = 0; j < item->num_periphs; j++) { 7891 if (j > 0) 7892 fprintf(stdout, ","); 7893 7894 fprintf(stdout, "%s%d", 7895 item->periph_matches[j].periph_name, 7896 item->periph_matches[j].unit_number); 7897 7898 } 7899 fprintf(stdout, ")\n"); 7900 } 7901 bailout: 7902 if (ccb != NULL) 7903 cam_freeccb(ccb); 7904 7905 free(rgrequest); 7906 7907 free(rgresponse); 7908 7909 free(disrequest); 7910 7911 free(disresponse); 7912 7913 freebusdevlist(&devlist); 7914 7915 return (retval); 7916 } 7917 7918 static int 7919 atapm(struct cam_device *device, int argc, char **argv, 7920 char *combinedopt, int retry_count, int timeout) 7921 { 7922 union ccb *ccb; 7923 int retval = 0; 7924 int t = -1; 7925 int c; 7926 u_char cmd, sc; 7927 7928 ccb = cam_getccb(device); 7929 7930 if (ccb == NULL) { 7931 warnx("%s: error allocating ccb", __func__); 7932 return (1); 7933 } 7934 7935 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7936 switch (c) { 7937 case 't': 7938 t = atoi(optarg); 7939 break; 7940 default: 7941 break; 7942 } 7943 } 7944 if (strcmp(argv[1], "idle") == 0) { 7945 if (t == -1) 7946 cmd = ATA_IDLE_IMMEDIATE; 7947 else 7948 cmd = ATA_IDLE_CMD; 7949 } else if (strcmp(argv[1], "standby") == 0) { 7950 if (t == -1) 7951 cmd = ATA_STANDBY_IMMEDIATE; 7952 else 7953 cmd = ATA_STANDBY_CMD; 7954 } else { 7955 cmd = ATA_SLEEP; 7956 t = -1; 7957 } 7958 7959 if (t < 0) 7960 sc = 0; 7961 else if (t <= (240 * 5)) 7962 sc = (t + 4) / 5; 7963 else if (t <= (252 * 5)) 7964 /* special encoding for 21 minutes */ 7965 sc = 252; 7966 else if (t <= (11 * 30 * 60)) 7967 sc = (t - 1) / (30 * 60) + 241; 7968 else 7969 sc = 253; 7970 7971 retval = ata_do_28bit_cmd(device, 7972 ccb, 7973 /*retries*/retry_count, 7974 /*flags*/CAM_DIR_NONE, 7975 /*protocol*/AP_PROTO_NON_DATA, 7976 /*tag_action*/MSG_SIMPLE_Q_TAG, 7977 /*command*/cmd, 7978 /*features*/0, 7979 /*lba*/0, 7980 /*sector_count*/sc, 7981 /*data_ptr*/NULL, 7982 /*dxfer_len*/0, 7983 /*timeout*/timeout ? timeout : 30 * 1000, 7984 /*quiet*/1); 7985 7986 cam_freeccb(ccb); 7987 return (retval); 7988 } 7989 7990 static int 7991 ataaxm(struct cam_device *device, int argc, char **argv, 7992 char *combinedopt, int retry_count, int timeout) 7993 { 7994 union ccb *ccb; 7995 int retval = 0; 7996 int l = -1; 7997 int c; 7998 u_char cmd, sc; 7999 8000 ccb = cam_getccb(device); 8001 8002 if (ccb == NULL) { 8003 warnx("%s: error allocating ccb", __func__); 8004 return (1); 8005 } 8006 8007 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8008 switch (c) { 8009 case 'l': 8010 l = atoi(optarg); 8011 break; 8012 default: 8013 break; 8014 } 8015 } 8016 sc = 0; 8017 if (strcmp(argv[1], "apm") == 0) { 8018 if (l == -1) 8019 cmd = 0x85; 8020 else { 8021 cmd = 0x05; 8022 sc = l; 8023 } 8024 } else /* aam */ { 8025 if (l == -1) 8026 cmd = 0xC2; 8027 else { 8028 cmd = 0x42; 8029 sc = l; 8030 } 8031 } 8032 8033 retval = ata_do_28bit_cmd(device, 8034 ccb, 8035 /*retries*/retry_count, 8036 /*flags*/CAM_DIR_NONE, 8037 /*protocol*/AP_PROTO_NON_DATA, 8038 /*tag_action*/MSG_SIMPLE_Q_TAG, 8039 /*command*/ATA_SETFEATURES, 8040 /*features*/cmd, 8041 /*lba*/0, 8042 /*sector_count*/sc, 8043 /*data_ptr*/NULL, 8044 /*dxfer_len*/0, 8045 /*timeout*/timeout ? timeout : 30 * 1000, 8046 /*quiet*/1); 8047 8048 cam_freeccb(ccb); 8049 return (retval); 8050 } 8051 8052 #endif /* MINIMALISTIC */ 8053 8054 void 8055 usage(int printlong) 8056 { 8057 8058 fprintf(printlong ? stdout : stderr, 8059 "usage: camcontrol <command> [device id][generic args][command args]\n" 8060 " camcontrol devlist [-v]\n" 8061 #ifndef MINIMALISTIC 8062 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n" 8063 " camcontrol tur [dev_id][generic args]\n" 8064 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n" 8065 " camcontrol identify [dev_id][generic args] [-v]\n" 8066 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n" 8067 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n" 8068 " [-q] [-s]\n" 8069 " camcontrol start [dev_id][generic args]\n" 8070 " camcontrol stop [dev_id][generic args]\n" 8071 " camcontrol load [dev_id][generic args]\n" 8072 " camcontrol eject [dev_id][generic args]\n" 8073 #endif /* MINIMALISTIC */ 8074 " camcontrol rescan <all | bus[:target:lun]>\n" 8075 " camcontrol reset <all | bus[:target:lun]>\n" 8076 #ifndef MINIMALISTIC 8077 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n" 8078 " [-q][-s][-S offset][-X]\n" 8079 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n" 8080 " [-P pagectl][-e | -b][-d]\n" 8081 " camcontrol cmd [dev_id][generic args]\n" 8082 " <-a cmd [args] | -c cmd [args]>\n" 8083 " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n" 8084 " camcontrol smpcmd [dev_id][generic args]\n" 8085 " <-r len fmt [args]> <-R len fmt [args]>\n" 8086 " camcontrol smprg [dev_id][generic args][-l]\n" 8087 " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n" 8088 " [-o operation][-d name][-m rate][-M rate]\n" 8089 " [-T pp_timeout][-a enable|disable]\n" 8090 " [-A enable|disable][-s enable|disable]\n" 8091 " [-S enable|disable]\n" 8092 " camcontrol smpphylist [dev_id][generic args][-l][-q]\n" 8093 " camcontrol smpmaninfo [dev_id][generic args][-l]\n" 8094 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n" 8095 " <all|bus[:target[:lun]]|off>\n" 8096 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n" 8097 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n" 8098 " [-D <enable|disable>][-M mode][-O offset]\n" 8099 " [-q][-R syncrate][-v][-T <enable|disable>]\n" 8100 " [-U][-W bus_width]\n" 8101 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n" 8102 " camcontrol sanitize [dev_id][generic args]\n" 8103 " [-a overwrite|block|crypto|exitfailure]\n" 8104 " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n" 8105 " [-y]\n" 8106 " camcontrol idle [dev_id][generic args][-t time]\n" 8107 " camcontrol standby [dev_id][generic args][-t time]\n" 8108 " camcontrol sleep [dev_id][generic args]\n" 8109 " camcontrol apm [dev_id][generic args][-l level]\n" 8110 " camcontrol aam [dev_id][generic args][-l level]\n" 8111 " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-y][-s]\n" 8112 " camcontrol security [dev_id][generic args]\n" 8113 " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n" 8114 " [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n" 8115 " [-U <user|master>] [-y]\n" 8116 " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n" 8117 " [-q] [-s max_sectors] [-U pwd] [-y]\n" 8118 " camcontrol persist [dev_id][generic args] <-i action|-o action>\n" 8119 " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n" 8120 " [-s scope][-S][-T type][-U]\n" 8121 #endif /* MINIMALISTIC */ 8122 " camcontrol help\n"); 8123 if (!printlong) 8124 return; 8125 #ifndef MINIMALISTIC 8126 fprintf(stdout, 8127 "Specify one of the following options:\n" 8128 "devlist list all CAM devices\n" 8129 "periphlist list all CAM peripheral drivers attached to a device\n" 8130 "tur send a test unit ready to the named device\n" 8131 "inquiry send a SCSI inquiry command to the named device\n" 8132 "identify send a ATA identify command to the named device\n" 8133 "reportluns send a SCSI report luns command to the device\n" 8134 "readcap send a SCSI read capacity command to the device\n" 8135 "start send a Start Unit command to the device\n" 8136 "stop send a Stop Unit command to the device\n" 8137 "load send a Start Unit command to the device with the load bit set\n" 8138 "eject send a Stop Unit command to the device with the eject bit set\n" 8139 "rescan rescan all busses, the given bus, or bus:target:lun\n" 8140 "reset reset all busses, the given bus, or bus:target:lun\n" 8141 "defects read the defect list of the specified device\n" 8142 "modepage display or edit (-e) the given mode page\n" 8143 "cmd send the given SCSI command, may need -i or -o as well\n" 8144 "smpcmd send the given SMP command, requires -o and -i\n" 8145 "smprg send the SMP Report General command\n" 8146 "smppc send the SMP PHY Control command, requires -p\n" 8147 "smpphylist display phys attached to a SAS expander\n" 8148 "smpmaninfo send the SMP Report Manufacturer Info command\n" 8149 "debug turn debugging on/off for a bus, target, or lun, or all devices\n" 8150 "tags report or set the number of transaction slots for a device\n" 8151 "negotiate report or set device negotiation parameters\n" 8152 "format send the SCSI FORMAT UNIT command to the named device\n" 8153 "sanitize send the SCSI SANITIZE command to the named device\n" 8154 "idle send the ATA IDLE command to the named device\n" 8155 "standby send the ATA STANDBY command to the named device\n" 8156 "sleep send the ATA SLEEP command to the named device\n" 8157 "fwdownload program firmware of the named device with the given image\n" 8158 "security report or send ATA security commands to the named device\n" 8159 "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n" 8160 "help this message\n" 8161 "Device Identifiers:\n" 8162 "bus:target specify the bus and target, lun defaults to 0\n" 8163 "bus:target:lun specify the bus, target and lun\n" 8164 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n" 8165 "Generic arguments:\n" 8166 "-v be verbose, print out sense information\n" 8167 "-t timeout command timeout in seconds, overrides default timeout\n" 8168 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n" 8169 "-u unit specify unit number, e.g. \"0\", \"5\"\n" 8170 "-E have the kernel attempt to perform SCSI error recovery\n" 8171 "-C count specify the SCSI command retry count (needs -E to work)\n" 8172 "modepage arguments:\n" 8173 "-l list all available mode pages\n" 8174 "-m page specify the mode page to view or edit\n" 8175 "-e edit the specified mode page\n" 8176 "-b force view to binary mode\n" 8177 "-d disable block descriptors for mode sense\n" 8178 "-P pgctl page control field 0-3\n" 8179 "defects arguments:\n" 8180 "-f format specify defect list format (block, bfi or phys)\n" 8181 "-G get the grown defect list\n" 8182 "-P get the permanent defect list\n" 8183 "inquiry arguments:\n" 8184 "-D get the standard inquiry data\n" 8185 "-S get the serial number\n" 8186 "-R get the transfer rate, etc.\n" 8187 "reportluns arguments:\n" 8188 "-c only report a count of available LUNs\n" 8189 "-l only print out luns, and not a count\n" 8190 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n" 8191 "readcap arguments\n" 8192 "-b only report the blocksize\n" 8193 "-h human readable device size, base 2\n" 8194 "-H human readable device size, base 10\n" 8195 "-N print the number of blocks instead of last block\n" 8196 "-q quiet, print numbers only\n" 8197 "-s only report the last block/device size\n" 8198 "cmd arguments:\n" 8199 "-c cdb [args] specify the SCSI CDB\n" 8200 "-i len fmt specify input data and input data format\n" 8201 "-o len fmt [args] specify output data and output data fmt\n" 8202 "smpcmd arguments:\n" 8203 "-r len fmt [args] specify the SMP command to be sent\n" 8204 "-R len fmt [args] specify SMP response format\n" 8205 "smprg arguments:\n" 8206 "-l specify the long response format\n" 8207 "smppc arguments:\n" 8208 "-p phy specify the PHY to operate on\n" 8209 "-l specify the long request/response format\n" 8210 "-o operation specify the phy control operation\n" 8211 "-d name set the attached device name\n" 8212 "-m rate set the minimum physical link rate\n" 8213 "-M rate set the maximum physical link rate\n" 8214 "-T pp_timeout set the partial pathway timeout value\n" 8215 "-a enable|disable enable or disable SATA slumber\n" 8216 "-A enable|disable enable or disable SATA partial phy power\n" 8217 "-s enable|disable enable or disable SAS slumber\n" 8218 "-S enable|disable enable or disable SAS partial phy power\n" 8219 "smpphylist arguments:\n" 8220 "-l specify the long response format\n" 8221 "-q only print phys with attached devices\n" 8222 "smpmaninfo arguments:\n" 8223 "-l specify the long response format\n" 8224 "debug arguments:\n" 8225 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n" 8226 "-T CAM_DEBUG_TRACE -- routine flow tracking\n" 8227 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n" 8228 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n" 8229 "tags arguments:\n" 8230 "-N tags specify the number of tags to use for this device\n" 8231 "-q be quiet, don't report the number of tags\n" 8232 "-v report a number of tag-related parameters\n" 8233 "negotiate arguments:\n" 8234 "-a send a test unit ready after negotiation\n" 8235 "-c report/set current negotiation settings\n" 8236 "-D <arg> \"enable\" or \"disable\" disconnection\n" 8237 "-M mode set ATA mode\n" 8238 "-O offset set command delay offset\n" 8239 "-q be quiet, don't report anything\n" 8240 "-R syncrate synchronization rate in MHz\n" 8241 "-T <arg> \"enable\" or \"disable\" tagged queueing\n" 8242 "-U report/set user negotiation settings\n" 8243 "-W bus_width set the bus width in bits (8, 16 or 32)\n" 8244 "-v also print a Path Inquiry CCB for the controller\n" 8245 "format arguments:\n" 8246 "-q be quiet, don't print status messages\n" 8247 "-r run in report only mode\n" 8248 "-w don't send immediate format command\n" 8249 "-y don't ask any questions\n" 8250 "sanitize arguments:\n" 8251 "-a operation operation mode: overwrite, block, crypto or exitfailure\n" 8252 "-c passes overwrite passes to perform (1 to 31)\n" 8253 "-I invert overwrite pattern after each pass\n" 8254 "-P pattern path to overwrite pattern file\n" 8255 "-q be quiet, don't print status messages\n" 8256 "-r run in report only mode\n" 8257 "-U run operation in unrestricted completion exit mode\n" 8258 "-w don't send immediate sanitize command\n" 8259 "-y don't ask any questions\n" 8260 "idle/standby arguments:\n" 8261 "-t <arg> number of seconds before respective state.\n" 8262 "fwdownload arguments:\n" 8263 "-f fw_image path to firmware image file\n" 8264 "-y don't ask any questions\n" 8265 "-s run in simulation mode\n" 8266 "-v print info for every firmware segment sent to device\n" 8267 "security arguments:\n" 8268 "-d pwd disable security using the given password for the selected\n" 8269 " user\n" 8270 "-e pwd erase the device using the given pwd for the selected user\n" 8271 "-f freeze the security configuration of the specified device\n" 8272 "-h pwd enhanced erase the device using the given pwd for the\n" 8273 " selected user\n" 8274 "-k pwd unlock the device using the given pwd for the selected\n" 8275 " user\n" 8276 "-l <high|maximum> specifies which security level to set: high or maximum\n" 8277 "-q be quiet, do not print any status messages\n" 8278 "-s pwd password the device (enable security) using the given\n" 8279 " pwd for the selected user\n" 8280 "-T timeout overrides the timeout (seconds) used for erase operation\n" 8281 "-U <user|master> specifies which user to set: user or master\n" 8282 "-y don't ask any questions\n" 8283 "hpa arguments:\n" 8284 "-f freeze the HPA configuration of the device\n" 8285 "-l lock the HPA configuration of the device\n" 8286 "-P make the HPA max sectors persist\n" 8287 "-p pwd Set the HPA configuration password required for unlock\n" 8288 " calls\n" 8289 "-q be quiet, do not print any status messages\n" 8290 "-s sectors configures the maximum user accessible sectors of the\n" 8291 " device\n" 8292 "-U pwd unlock the HPA configuration of the device\n" 8293 "-y don't ask any questions\n" 8294 "persist arguments:\n" 8295 "-i action specify read_keys, read_reservation, report_cap, or\n" 8296 " read_full_status\n" 8297 "-o action specify register, register_ignore, reserve, release,\n" 8298 " clear, preempt, preempt_abort, register_move, replace_lost\n" 8299 "-a set the All Target Ports (ALL_TG_PT) bit\n" 8300 "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n" 8301 "-k key specify the Reservation Key\n" 8302 "-K sa_key specify the Service Action Reservation Key\n" 8303 "-p set the Activate Persist Through Power Loss bit\n" 8304 "-R rtp specify the Relative Target Port\n" 8305 "-s scope specify the scope: lun, extent, element or a number\n" 8306 "-S specify Transport ID for register, requires -I\n" 8307 "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n" 8308 " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n" 8309 "-U unregister the current initiator for register_move\n" 8310 ); 8311 #endif /* MINIMALISTIC */ 8312 } 8313 8314 int 8315 main(int argc, char **argv) 8316 { 8317 int c; 8318 char *device = NULL; 8319 int unit = 0; 8320 struct cam_device *cam_dev = NULL; 8321 int timeout = 0, retry_count = 1; 8322 camcontrol_optret optreturn; 8323 char *tstr; 8324 const char *mainopt = "C:En:t:u:v"; 8325 const char *subopt = NULL; 8326 char combinedopt[256]; 8327 int error = 0, optstart = 2; 8328 int devopen = 1; 8329 #ifndef MINIMALISTIC 8330 path_id_t bus; 8331 target_id_t target; 8332 lun_id_t lun; 8333 #endif /* MINIMALISTIC */ 8334 8335 cmdlist = CAM_CMD_NONE; 8336 arglist = CAM_ARG_NONE; 8337 8338 if (argc < 2) { 8339 usage(0); 8340 exit(1); 8341 } 8342 8343 /* 8344 * Get the base option. 8345 */ 8346 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt); 8347 8348 if (optreturn == CC_OR_AMBIGUOUS) { 8349 warnx("ambiguous option %s", argv[1]); 8350 usage(0); 8351 exit(1); 8352 } else if (optreturn == CC_OR_NOT_FOUND) { 8353 warnx("option %s not found", argv[1]); 8354 usage(0); 8355 exit(1); 8356 } 8357 8358 /* 8359 * Ahh, getopt(3) is a pain. 8360 * 8361 * This is a gross hack. There really aren't many other good 8362 * options (excuse the pun) for parsing options in a situation like 8363 * this. getopt is kinda braindead, so you end up having to run 8364 * through the options twice, and give each invocation of getopt 8365 * the option string for the other invocation. 8366 * 8367 * You would think that you could just have two groups of options. 8368 * The first group would get parsed by the first invocation of 8369 * getopt, and the second group would get parsed by the second 8370 * invocation of getopt. It doesn't quite work out that way. When 8371 * the first invocation of getopt finishes, it leaves optind pointing 8372 * to the argument _after_ the first argument in the second group. 8373 * So when the second invocation of getopt comes around, it doesn't 8374 * recognize the first argument it gets and then bails out. 8375 * 8376 * A nice alternative would be to have a flag for getopt that says 8377 * "just keep parsing arguments even when you encounter an unknown 8378 * argument", but there isn't one. So there's no real clean way to 8379 * easily parse two sets of arguments without having one invocation 8380 * of getopt know about the other. 8381 * 8382 * Without this hack, the first invocation of getopt would work as 8383 * long as the generic arguments are first, but the second invocation 8384 * (in the subfunction) would fail in one of two ways. In the case 8385 * where you don't set optreset, it would fail because optind may be 8386 * pointing to the argument after the one it should be pointing at. 8387 * In the case where you do set optreset, and reset optind, it would 8388 * fail because getopt would run into the first set of options, which 8389 * it doesn't understand. 8390 * 8391 * All of this would "sort of" work if you could somehow figure out 8392 * whether optind had been incremented one option too far. The 8393 * mechanics of that, however, are more daunting than just giving 8394 * both invocations all of the expect options for either invocation. 8395 * 8396 * Needless to say, I wouldn't mind if someone invented a better 8397 * (non-GPL!) command line parsing interface than getopt. I 8398 * wouldn't mind if someone added more knobs to getopt to make it 8399 * work better. Who knows, I may talk myself into doing it someday, 8400 * if the standards weenies let me. As it is, it just leads to 8401 * hackery like this and causes people to avoid it in some cases. 8402 * 8403 * KDM, September 8th, 1998 8404 */ 8405 if (subopt != NULL) 8406 sprintf(combinedopt, "%s%s", mainopt, subopt); 8407 else 8408 sprintf(combinedopt, "%s", mainopt); 8409 8410 /* 8411 * For these options we do not parse optional device arguments and 8412 * we do not open a passthrough device. 8413 */ 8414 if ((cmdlist == CAM_CMD_RESCAN) 8415 || (cmdlist == CAM_CMD_RESET) 8416 || (cmdlist == CAM_CMD_DEVTREE) 8417 || (cmdlist == CAM_CMD_USAGE) 8418 || (cmdlist == CAM_CMD_DEBUG)) 8419 devopen = 0; 8420 8421 #ifndef MINIMALISTIC 8422 if ((devopen == 1) 8423 && (argc > 2 && argv[2][0] != '-')) { 8424 char name[30]; 8425 int rv; 8426 8427 if (isdigit(argv[2][0])) { 8428 /* device specified as bus:target[:lun] */ 8429 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist); 8430 if (rv < 2) 8431 errx(1, "numeric device specification must " 8432 "be either bus:target, or " 8433 "bus:target:lun"); 8434 /* default to 0 if lun was not specified */ 8435 if ((arglist & CAM_ARG_LUN) == 0) { 8436 lun = 0; 8437 arglist |= CAM_ARG_LUN; 8438 } 8439 optstart++; 8440 } else { 8441 if (cam_get_device(argv[2], name, sizeof name, &unit) 8442 == -1) 8443 errx(1, "%s", cam_errbuf); 8444 device = strdup(name); 8445 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT; 8446 optstart++; 8447 } 8448 } 8449 #endif /* MINIMALISTIC */ 8450 /* 8451 * Start getopt processing at argv[2/3], since we've already 8452 * accepted argv[1..2] as the command name, and as a possible 8453 * device name. 8454 */ 8455 optind = optstart; 8456 8457 /* 8458 * Now we run through the argument list looking for generic 8459 * options, and ignoring options that possibly belong to 8460 * subfunctions. 8461 */ 8462 while ((c = getopt(argc, argv, combinedopt))!= -1){ 8463 switch(c) { 8464 case 'C': 8465 retry_count = strtol(optarg, NULL, 0); 8466 if (retry_count < 0) 8467 errx(1, "retry count %d is < 0", 8468 retry_count); 8469 arglist |= CAM_ARG_RETRIES; 8470 break; 8471 case 'E': 8472 arglist |= CAM_ARG_ERR_RECOVER; 8473 break; 8474 case 'n': 8475 arglist |= CAM_ARG_DEVICE; 8476 tstr = optarg; 8477 while (isspace(*tstr) && (*tstr != '\0')) 8478 tstr++; 8479 device = (char *)strdup(tstr); 8480 break; 8481 case 't': 8482 timeout = strtol(optarg, NULL, 0); 8483 if (timeout < 0) 8484 errx(1, "invalid timeout %d", timeout); 8485 /* Convert the timeout from seconds to ms */ 8486 timeout *= 1000; 8487 arglist |= CAM_ARG_TIMEOUT; 8488 break; 8489 case 'u': 8490 arglist |= CAM_ARG_UNIT; 8491 unit = strtol(optarg, NULL, 0); 8492 break; 8493 case 'v': 8494 arglist |= CAM_ARG_VERBOSE; 8495 break; 8496 default: 8497 break; 8498 } 8499 } 8500 8501 #ifndef MINIMALISTIC 8502 /* 8503 * For most commands we'll want to open the passthrough device 8504 * associated with the specified device. In the case of the rescan 8505 * commands, we don't use a passthrough device at all, just the 8506 * transport layer device. 8507 */ 8508 if (devopen == 1) { 8509 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0) 8510 && (((arglist & CAM_ARG_DEVICE) == 0) 8511 || ((arglist & CAM_ARG_UNIT) == 0))) { 8512 errx(1, "subcommand \"%s\" requires a valid device " 8513 "identifier", argv[1]); 8514 } 8515 8516 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))? 8517 cam_open_btl(bus, target, lun, O_RDWR, NULL) : 8518 cam_open_spec_device(device,unit,O_RDWR,NULL))) 8519 == NULL) 8520 errx(1,"%s", cam_errbuf); 8521 } 8522 #endif /* MINIMALISTIC */ 8523 8524 /* 8525 * Reset optind to 2, and reset getopt, so these routines can parse 8526 * the arguments again. 8527 */ 8528 optind = optstart; 8529 optreset = 1; 8530 8531 switch(cmdlist) { 8532 #ifndef MINIMALISTIC 8533 case CAM_CMD_DEVLIST: 8534 error = getdevlist(cam_dev); 8535 break; 8536 case CAM_CMD_HPA: 8537 error = atahpa(cam_dev, retry_count, timeout, 8538 argc, argv, combinedopt); 8539 break; 8540 #endif /* MINIMALISTIC */ 8541 case CAM_CMD_DEVTREE: 8542 error = getdevtree(argc, argv, combinedopt); 8543 break; 8544 #ifndef MINIMALISTIC 8545 case CAM_CMD_TUR: 8546 error = testunitready(cam_dev, retry_count, timeout, 0); 8547 break; 8548 case CAM_CMD_INQUIRY: 8549 error = scsidoinquiry(cam_dev, argc, argv, combinedopt, 8550 retry_count, timeout); 8551 break; 8552 case CAM_CMD_IDENTIFY: 8553 error = ataidentify(cam_dev, retry_count, timeout); 8554 break; 8555 case CAM_CMD_STARTSTOP: 8556 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT, 8557 arglist & CAM_ARG_EJECT, retry_count, 8558 timeout); 8559 break; 8560 #endif /* MINIMALISTIC */ 8561 case CAM_CMD_RESCAN: 8562 error = dorescan_or_reset(argc, argv, 1); 8563 break; 8564 case CAM_CMD_RESET: 8565 error = dorescan_or_reset(argc, argv, 0); 8566 break; 8567 #ifndef MINIMALISTIC 8568 case CAM_CMD_READ_DEFECTS: 8569 error = readdefects(cam_dev, argc, argv, combinedopt, 8570 retry_count, timeout); 8571 break; 8572 case CAM_CMD_MODE_PAGE: 8573 modepage(cam_dev, argc, argv, combinedopt, 8574 retry_count, timeout); 8575 break; 8576 case CAM_CMD_SCSI_CMD: 8577 error = scsicmd(cam_dev, argc, argv, combinedopt, 8578 retry_count, timeout); 8579 break; 8580 case CAM_CMD_SMP_CMD: 8581 error = smpcmd(cam_dev, argc, argv, combinedopt, 8582 retry_count, timeout); 8583 break; 8584 case CAM_CMD_SMP_RG: 8585 error = smpreportgeneral(cam_dev, argc, argv, 8586 combinedopt, retry_count, 8587 timeout); 8588 break; 8589 case CAM_CMD_SMP_PC: 8590 error = smpphycontrol(cam_dev, argc, argv, combinedopt, 8591 retry_count, timeout); 8592 break; 8593 case CAM_CMD_SMP_PHYLIST: 8594 error = smpphylist(cam_dev, argc, argv, combinedopt, 8595 retry_count, timeout); 8596 break; 8597 case CAM_CMD_SMP_MANINFO: 8598 error = smpmaninfo(cam_dev, argc, argv, combinedopt, 8599 retry_count, timeout); 8600 break; 8601 case CAM_CMD_DEBUG: 8602 error = camdebug(argc, argv, combinedopt); 8603 break; 8604 case CAM_CMD_TAG: 8605 error = tagcontrol(cam_dev, argc, argv, combinedopt); 8606 break; 8607 case CAM_CMD_RATE: 8608 error = ratecontrol(cam_dev, retry_count, timeout, 8609 argc, argv, combinedopt); 8610 break; 8611 case CAM_CMD_FORMAT: 8612 error = scsiformat(cam_dev, argc, argv, 8613 combinedopt, retry_count, timeout); 8614 break; 8615 case CAM_CMD_REPORTLUNS: 8616 error = scsireportluns(cam_dev, argc, argv, 8617 combinedopt, retry_count, 8618 timeout); 8619 break; 8620 case CAM_CMD_READCAP: 8621 error = scsireadcapacity(cam_dev, argc, argv, 8622 combinedopt, retry_count, 8623 timeout); 8624 break; 8625 case CAM_CMD_IDLE: 8626 case CAM_CMD_STANDBY: 8627 case CAM_CMD_SLEEP: 8628 error = atapm(cam_dev, argc, argv, 8629 combinedopt, retry_count, timeout); 8630 break; 8631 case CAM_CMD_APM: 8632 case CAM_CMD_AAM: 8633 error = ataaxm(cam_dev, argc, argv, 8634 combinedopt, retry_count, timeout); 8635 break; 8636 case CAM_CMD_SECURITY: 8637 error = atasecurity(cam_dev, retry_count, timeout, 8638 argc, argv, combinedopt); 8639 break; 8640 case CAM_CMD_DOWNLOAD_FW: 8641 error = fwdownload(cam_dev, argc, argv, combinedopt, 8642 arglist & CAM_ARG_VERBOSE, retry_count, timeout, 8643 get_disk_type(cam_dev)); 8644 break; 8645 case CAM_CMD_SANITIZE: 8646 error = scsisanitize(cam_dev, argc, argv, 8647 combinedopt, retry_count, timeout); 8648 break; 8649 case CAM_CMD_PERSIST: 8650 error = scsipersist(cam_dev, argc, argv, combinedopt, 8651 retry_count, timeout, arglist & CAM_ARG_VERBOSE, 8652 arglist & CAM_ARG_ERR_RECOVER); 8653 break; 8654 #endif /* MINIMALISTIC */ 8655 case CAM_CMD_USAGE: 8656 usage(1); 8657 break; 8658 default: 8659 usage(0); 8660 error = 1; 8661 break; 8662 } 8663 8664 if (cam_dev != NULL) 8665 cam_close_device(cam_dev); 8666 8667 exit(error); 8668 } 8669