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