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