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