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