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