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/endian.h> 36 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <unistd.h> 41 #include <fcntl.h> 42 #include <ctype.h> 43 #include <err.h> 44 #include <libutil.h> 45 46 #include <cam/cam.h> 47 #include <cam/cam_debug.h> 48 #include <cam/cam_ccb.h> 49 #include <cam/scsi/scsi_all.h> 50 #include <cam/scsi/scsi_da.h> 51 #include <cam/scsi/scsi_pass.h> 52 #include <cam/scsi/scsi_message.h> 53 #include <cam/ata/ata_all.h> 54 #include <camlib.h> 55 #include "camcontrol.h" 56 57 typedef enum { 58 CAM_CMD_NONE = 0x00000000, 59 CAM_CMD_DEVLIST = 0x00000001, 60 CAM_CMD_TUR = 0x00000002, 61 CAM_CMD_INQUIRY = 0x00000003, 62 CAM_CMD_STARTSTOP = 0x00000004, 63 CAM_CMD_RESCAN = 0x00000005, 64 CAM_CMD_READ_DEFECTS = 0x00000006, 65 CAM_CMD_MODE_PAGE = 0x00000007, 66 CAM_CMD_SCSI_CMD = 0x00000008, 67 CAM_CMD_DEVTREE = 0x00000009, 68 CAM_CMD_USAGE = 0x0000000a, 69 CAM_CMD_DEBUG = 0x0000000b, 70 CAM_CMD_RESET = 0x0000000c, 71 CAM_CMD_FORMAT = 0x0000000d, 72 CAM_CMD_TAG = 0x0000000e, 73 CAM_CMD_RATE = 0x0000000f, 74 CAM_CMD_DETACH = 0x00000010, 75 CAM_CMD_REPORTLUNS = 0x00000011, 76 CAM_CMD_READCAP = 0x00000012, 77 CAM_CMD_IDENTIFY = 0x00000013 78 } cam_cmdmask; 79 80 typedef enum { 81 CAM_ARG_NONE = 0x00000000, 82 CAM_ARG_VERBOSE = 0x00000001, 83 CAM_ARG_DEVICE = 0x00000002, 84 CAM_ARG_BUS = 0x00000004, 85 CAM_ARG_TARGET = 0x00000008, 86 CAM_ARG_LUN = 0x00000010, 87 CAM_ARG_EJECT = 0x00000020, 88 CAM_ARG_UNIT = 0x00000040, 89 CAM_ARG_FORMAT_BLOCK = 0x00000080, 90 CAM_ARG_FORMAT_BFI = 0x00000100, 91 CAM_ARG_FORMAT_PHYS = 0x00000200, 92 CAM_ARG_PLIST = 0x00000400, 93 CAM_ARG_GLIST = 0x00000800, 94 CAM_ARG_GET_SERIAL = 0x00001000, 95 CAM_ARG_GET_STDINQ = 0x00002000, 96 CAM_ARG_GET_XFERRATE = 0x00004000, 97 CAM_ARG_INQ_MASK = 0x00007000, 98 CAM_ARG_MODE_EDIT = 0x00008000, 99 CAM_ARG_PAGE_CNTL = 0x00010000, 100 CAM_ARG_TIMEOUT = 0x00020000, 101 CAM_ARG_CMD_IN = 0x00040000, 102 CAM_ARG_CMD_OUT = 0x00080000, 103 CAM_ARG_DBD = 0x00100000, 104 CAM_ARG_ERR_RECOVER = 0x00200000, 105 CAM_ARG_RETRIES = 0x00400000, 106 CAM_ARG_START_UNIT = 0x00800000, 107 CAM_ARG_DEBUG_INFO = 0x01000000, 108 CAM_ARG_DEBUG_TRACE = 0x02000000, 109 CAM_ARG_DEBUG_SUBTRACE = 0x04000000, 110 CAM_ARG_DEBUG_CDB = 0x08000000, 111 CAM_ARG_DEBUG_XPT = 0x10000000, 112 CAM_ARG_DEBUG_PERIPH = 0x20000000, 113 } cam_argmask; 114 115 struct camcontrol_opts { 116 const char *optname; 117 cam_cmdmask cmdnum; 118 cam_argmask argnum; 119 const char *subopt; 120 }; 121 122 #ifndef MINIMALISTIC 123 static const char scsicmd_opts[] = "c:i:o:"; 124 static const char readdefect_opts[] = "f:GP"; 125 static const char negotiate_opts[] = "acD:O:qR:T:UW:"; 126 #endif 127 128 struct camcontrol_opts option_table[] = { 129 #ifndef MINIMALISTIC 130 {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL}, 131 {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"}, 132 {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL}, 133 {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL}, 134 {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL}, 135 {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL}, 136 {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL}, 137 {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"}, 138 {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHNqs"}, 139 #endif /* MINIMALISTIC */ 140 {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL}, 141 {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL}, 142 #ifndef MINIMALISTIC 143 {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts}, 144 {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts}, 145 {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts}, 146 {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts}, 147 #endif /* MINIMALISTIC */ 148 {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, NULL}, 149 #ifndef MINIMALISTIC 150 {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL}, 151 {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"}, 152 {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"}, 153 {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, 154 {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, 155 {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXc"}, 156 {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"}, 157 #endif /* MINIMALISTIC */ 158 {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, 159 {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, 160 {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, 161 {NULL, 0, 0, NULL} 162 }; 163 164 typedef enum { 165 CC_OR_NOT_FOUND, 166 CC_OR_AMBIGUOUS, 167 CC_OR_FOUND 168 } camcontrol_optret; 169 170 cam_cmdmask cmdlist; 171 cam_argmask arglist; 172 173 174 camcontrol_optret getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum, 175 const char **subopt); 176 #ifndef MINIMALISTIC 177 static int getdevlist(struct cam_device *device); 178 #endif /* MINIMALISTIC */ 179 static int getdevtree(void); 180 #ifndef MINIMALISTIC 181 static int testunitready(struct cam_device *device, int retry_count, 182 int timeout, int quiet); 183 static int scsistart(struct cam_device *device, int startstop, int loadeject, 184 int retry_count, int timeout); 185 static int scsidoinquiry(struct cam_device *device, int argc, char **argv, 186 char *combinedopt, int retry_count, int timeout); 187 static int scsiinquiry(struct cam_device *device, int retry_count, int timeout); 188 static int scsiserial(struct cam_device *device, int retry_count, int timeout); 189 static int scsixferrate(struct cam_device *device); 190 #endif /* MINIMALISTIC */ 191 static int parse_btl(char *tstr, int *bus, int *target, int *lun, 192 cam_argmask *arglst); 193 static int dorescan_or_reset(int argc, char **argv, int rescan); 194 static int rescan_or_reset_bus(int bus, int rescan); 195 static int scanlun_or_reset_dev(int bus, int target, int lun, int scan); 196 #ifndef MINIMALISTIC 197 static int readdefects(struct cam_device *device, int argc, char **argv, 198 char *combinedopt, int retry_count, int timeout); 199 static void modepage(struct cam_device *device, int argc, char **argv, 200 char *combinedopt, int retry_count, int timeout); 201 static int scsicmd(struct cam_device *device, int argc, char **argv, 202 char *combinedopt, int retry_count, int timeout); 203 static int tagcontrol(struct cam_device *device, int argc, char **argv, 204 char *combinedopt); 205 static void cts_print(struct cam_device *device, 206 struct ccb_trans_settings *cts); 207 static void cpi_print(struct ccb_pathinq *cpi); 208 static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi); 209 static int get_print_cts(struct cam_device *device, int user_settings, 210 int quiet, struct ccb_trans_settings *cts); 211 static int ratecontrol(struct cam_device *device, int retry_count, 212 int timeout, int argc, char **argv, char *combinedopt); 213 static int scsiformat(struct cam_device *device, int argc, char **argv, 214 char *combinedopt, int retry_count, int timeout); 215 static int scsireportluns(struct cam_device *device, int argc, char **argv, 216 char *combinedopt, int retry_count, int timeout); 217 static int scsireadcapacity(struct cam_device *device, int argc, char **argv, 218 char *combinedopt, int retry_count, int timeout); 219 #endif /* MINIMALISTIC */ 220 221 camcontrol_optret 222 getoption(char *arg, cam_cmdmask *cmdnum, cam_argmask *argnum, 223 const char **subopt) 224 { 225 struct camcontrol_opts *opts; 226 int num_matches = 0; 227 228 for (opts = option_table; (opts != NULL) && (opts->optname != NULL); 229 opts++) { 230 if (strncmp(opts->optname, arg, strlen(arg)) == 0) { 231 *cmdnum = opts->cmdnum; 232 *argnum = opts->argnum; 233 *subopt = opts->subopt; 234 if (++num_matches > 1) 235 return(CC_OR_AMBIGUOUS); 236 } 237 } 238 239 if (num_matches > 0) 240 return(CC_OR_FOUND); 241 else 242 return(CC_OR_NOT_FOUND); 243 } 244 245 #ifndef MINIMALISTIC 246 static int 247 getdevlist(struct cam_device *device) 248 { 249 union ccb *ccb; 250 char status[32]; 251 int error = 0; 252 253 ccb = cam_getccb(device); 254 255 ccb->ccb_h.func_code = XPT_GDEVLIST; 256 ccb->ccb_h.flags = CAM_DIR_NONE; 257 ccb->ccb_h.retry_count = 1; 258 ccb->cgdl.index = 0; 259 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS; 260 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) { 261 if (cam_send_ccb(device, ccb) < 0) { 262 perror("error getting device list"); 263 cam_freeccb(ccb); 264 return(1); 265 } 266 267 status[0] = '\0'; 268 269 switch (ccb->cgdl.status) { 270 case CAM_GDEVLIST_MORE_DEVS: 271 strcpy(status, "MORE"); 272 break; 273 case CAM_GDEVLIST_LAST_DEVICE: 274 strcpy(status, "LAST"); 275 break; 276 case CAM_GDEVLIST_LIST_CHANGED: 277 strcpy(status, "CHANGED"); 278 break; 279 case CAM_GDEVLIST_ERROR: 280 strcpy(status, "ERROR"); 281 error = 1; 282 break; 283 } 284 285 fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n", 286 ccb->cgdl.periph_name, 287 ccb->cgdl.unit_number, 288 ccb->cgdl.generation, 289 ccb->cgdl.index, 290 status); 291 292 /* 293 * If the list has changed, we need to start over from the 294 * beginning. 295 */ 296 if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED) 297 ccb->cgdl.index = 0; 298 } 299 300 cam_freeccb(ccb); 301 302 return(error); 303 } 304 #endif /* MINIMALISTIC */ 305 306 static int 307 getdevtree(void) 308 { 309 union ccb ccb; 310 int bufsize, fd; 311 unsigned int i; 312 int need_close = 0; 313 int error = 0; 314 int skip_device = 0; 315 316 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { 317 warn("couldn't open %s", XPT_DEVICE); 318 return(1); 319 } 320 321 bzero(&ccb, sizeof(union ccb)); 322 323 ccb.ccb_h.path_id = CAM_XPT_PATH_ID; 324 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 325 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 326 327 ccb.ccb_h.func_code = XPT_DEV_MATCH; 328 bufsize = sizeof(struct dev_match_result) * 100; 329 ccb.cdm.match_buf_len = bufsize; 330 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); 331 if (ccb.cdm.matches == NULL) { 332 warnx("can't malloc memory for matches"); 333 close(fd); 334 return(1); 335 } 336 ccb.cdm.num_matches = 0; 337 338 /* 339 * We fetch all nodes, since we display most of them in the default 340 * case, and all in the verbose case. 341 */ 342 ccb.cdm.num_patterns = 0; 343 ccb.cdm.pattern_buf_len = 0; 344 345 /* 346 * We do the ioctl multiple times if necessary, in case there are 347 * more than 100 nodes in the EDT. 348 */ 349 do { 350 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 351 warn("error sending CAMIOCOMMAND ioctl"); 352 error = 1; 353 break; 354 } 355 356 if ((ccb.ccb_h.status != CAM_REQ_CMP) 357 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) 358 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { 359 warnx("got CAM error %#x, CDM error %d\n", 360 ccb.ccb_h.status, ccb.cdm.status); 361 error = 1; 362 break; 363 } 364 365 for (i = 0; i < ccb.cdm.num_matches; i++) { 366 switch (ccb.cdm.matches[i].type) { 367 case DEV_MATCH_BUS: { 368 struct bus_match_result *bus_result; 369 370 /* 371 * Only print the bus information if the 372 * user turns on the verbose flag. 373 */ 374 if ((arglist & CAM_ARG_VERBOSE) == 0) 375 break; 376 377 bus_result = 378 &ccb.cdm.matches[i].result.bus_result; 379 380 if (need_close) { 381 fprintf(stdout, ")\n"); 382 need_close = 0; 383 } 384 385 fprintf(stdout, "scbus%d on %s%d bus %d:\n", 386 bus_result->path_id, 387 bus_result->dev_name, 388 bus_result->unit_number, 389 bus_result->bus_id); 390 break; 391 } 392 case DEV_MATCH_DEVICE: { 393 struct device_match_result *dev_result; 394 char vendor[16], product[48], revision[16]; 395 char tmpstr[256]; 396 397 dev_result = 398 &ccb.cdm.matches[i].result.device_result; 399 400 if ((dev_result->flags 401 & DEV_RESULT_UNCONFIGURED) 402 && ((arglist & CAM_ARG_VERBOSE) == 0)) { 403 skip_device = 1; 404 break; 405 } else 406 skip_device = 0; 407 408 if (dev_result->protocol == PROTO_SCSI) { 409 cam_strvis(vendor, dev_result->inq_data.vendor, 410 sizeof(dev_result->inq_data.vendor), 411 sizeof(vendor)); 412 cam_strvis(product, 413 dev_result->inq_data.product, 414 sizeof(dev_result->inq_data.product), 415 sizeof(product)); 416 cam_strvis(revision, 417 dev_result->inq_data.revision, 418 sizeof(dev_result->inq_data.revision), 419 sizeof(revision)); 420 sprintf(tmpstr, "<%s %s %s>", vendor, product, 421 revision); 422 } else if (dev_result->protocol == PROTO_ATA || 423 dev_result->protocol == PROTO_SATAPM) { 424 cam_strvis(product, 425 dev_result->ident_data.model, 426 sizeof(dev_result->ident_data.model), 427 sizeof(product)); 428 cam_strvis(revision, 429 dev_result->ident_data.revision, 430 sizeof(dev_result->ident_data.revision), 431 sizeof(revision)); 432 sprintf(tmpstr, "<%s %s>", product, 433 revision); 434 } else { 435 sprintf(tmpstr, "<>"); 436 } 437 if (need_close) { 438 fprintf(stdout, ")\n"); 439 need_close = 0; 440 } 441 442 fprintf(stdout, "%-33s at scbus%d " 443 "target %d lun %d (", 444 tmpstr, 445 dev_result->path_id, 446 dev_result->target_id, 447 dev_result->target_lun); 448 449 need_close = 1; 450 451 break; 452 } 453 case DEV_MATCH_PERIPH: { 454 struct periph_match_result *periph_result; 455 456 periph_result = 457 &ccb.cdm.matches[i].result.periph_result; 458 459 if (skip_device != 0) 460 break; 461 462 if (need_close > 1) 463 fprintf(stdout, ","); 464 465 fprintf(stdout, "%s%d", 466 periph_result->periph_name, 467 periph_result->unit_number); 468 469 need_close++; 470 break; 471 } 472 default: 473 fprintf(stdout, "unknown match type\n"); 474 break; 475 } 476 } 477 478 } while ((ccb.ccb_h.status == CAM_REQ_CMP) 479 && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); 480 481 if (need_close) 482 fprintf(stdout, ")\n"); 483 484 close(fd); 485 486 return(error); 487 } 488 489 #ifndef MINIMALISTIC 490 static int 491 testunitready(struct cam_device *device, int retry_count, int timeout, 492 int quiet) 493 { 494 int error = 0; 495 union ccb *ccb; 496 497 ccb = cam_getccb(device); 498 499 scsi_test_unit_ready(&ccb->csio, 500 /* retries */ retry_count, 501 /* cbfcnp */ NULL, 502 /* tag_action */ MSG_SIMPLE_Q_TAG, 503 /* sense_len */ SSD_FULL_SIZE, 504 /* timeout */ timeout ? timeout : 5000); 505 506 /* Disable freezing the device queue */ 507 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 508 509 if (arglist & CAM_ARG_ERR_RECOVER) 510 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 511 512 if (cam_send_ccb(device, ccb) < 0) { 513 if (quiet == 0) 514 perror("error sending test unit ready"); 515 516 if (arglist & CAM_ARG_VERBOSE) { 517 cam_error_print(device, ccb, CAM_ESF_ALL, 518 CAM_EPF_ALL, stderr); 519 } 520 521 cam_freeccb(ccb); 522 return(1); 523 } 524 525 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { 526 if (quiet == 0) 527 fprintf(stdout, "Unit is ready\n"); 528 } else { 529 if (quiet == 0) 530 fprintf(stdout, "Unit is not ready\n"); 531 error = 1; 532 533 if (arglist & CAM_ARG_VERBOSE) { 534 cam_error_print(device, ccb, CAM_ESF_ALL, 535 CAM_EPF_ALL, stderr); 536 } 537 } 538 539 cam_freeccb(ccb); 540 541 return(error); 542 } 543 544 static int 545 scsistart(struct cam_device *device, int startstop, int loadeject, 546 int retry_count, int timeout) 547 { 548 union ccb *ccb; 549 int error = 0; 550 551 ccb = cam_getccb(device); 552 553 /* 554 * If we're stopping, send an ordered tag so the drive in question 555 * will finish any previously queued writes before stopping. If 556 * the device isn't capable of tagged queueing, or if tagged 557 * queueing is turned off, the tag action is a no-op. 558 */ 559 scsi_start_stop(&ccb->csio, 560 /* retries */ retry_count, 561 /* cbfcnp */ NULL, 562 /* tag_action */ startstop ? MSG_SIMPLE_Q_TAG : 563 MSG_ORDERED_Q_TAG, 564 /* start/stop */ startstop, 565 /* load_eject */ loadeject, 566 /* immediate */ 0, 567 /* sense_len */ SSD_FULL_SIZE, 568 /* timeout */ timeout ? timeout : 120000); 569 570 /* Disable freezing the device queue */ 571 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 572 573 if (arglist & CAM_ARG_ERR_RECOVER) 574 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 575 576 if (cam_send_ccb(device, ccb) < 0) { 577 perror("error sending start unit"); 578 579 if (arglist & CAM_ARG_VERBOSE) { 580 cam_error_print(device, ccb, CAM_ESF_ALL, 581 CAM_EPF_ALL, stderr); 582 } 583 584 cam_freeccb(ccb); 585 return(1); 586 } 587 588 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 589 if (startstop) { 590 fprintf(stdout, "Unit started successfully"); 591 if (loadeject) 592 fprintf(stdout,", Media loaded\n"); 593 else 594 fprintf(stdout,"\n"); 595 } else { 596 fprintf(stdout, "Unit stopped successfully"); 597 if (loadeject) 598 fprintf(stdout, ", Media ejected\n"); 599 else 600 fprintf(stdout, "\n"); 601 } 602 else { 603 error = 1; 604 if (startstop) 605 fprintf(stdout, 606 "Error received from start unit command\n"); 607 else 608 fprintf(stdout, 609 "Error received from stop unit command\n"); 610 611 if (arglist & CAM_ARG_VERBOSE) { 612 cam_error_print(device, ccb, CAM_ESF_ALL, 613 CAM_EPF_ALL, stderr); 614 } 615 } 616 617 cam_freeccb(ccb); 618 619 return(error); 620 } 621 622 static int 623 scsidoinquiry(struct cam_device *device, int argc, char **argv, 624 char *combinedopt, int retry_count, int timeout) 625 { 626 int c; 627 int error = 0; 628 629 while ((c = getopt(argc, argv, combinedopt)) != -1) { 630 switch(c) { 631 case 'D': 632 arglist |= CAM_ARG_GET_STDINQ; 633 break; 634 case 'R': 635 arglist |= CAM_ARG_GET_XFERRATE; 636 break; 637 case 'S': 638 arglist |= CAM_ARG_GET_SERIAL; 639 break; 640 default: 641 break; 642 } 643 } 644 645 /* 646 * If the user didn't specify any inquiry options, he wants all of 647 * them. 648 */ 649 if ((arglist & CAM_ARG_INQ_MASK) == 0) 650 arglist |= CAM_ARG_INQ_MASK; 651 652 if (arglist & CAM_ARG_GET_STDINQ) 653 error = scsiinquiry(device, retry_count, timeout); 654 655 if (error != 0) 656 return(error); 657 658 if (arglist & CAM_ARG_GET_SERIAL) 659 scsiserial(device, retry_count, timeout); 660 661 if (error != 0) 662 return(error); 663 664 if (arglist & CAM_ARG_GET_XFERRATE) 665 error = scsixferrate(device); 666 667 return(error); 668 } 669 670 static int 671 scsiinquiry(struct cam_device *device, int retry_count, int timeout) 672 { 673 union ccb *ccb; 674 struct scsi_inquiry_data *inq_buf; 675 int error = 0; 676 677 ccb = cam_getccb(device); 678 679 if (ccb == NULL) { 680 warnx("couldn't allocate CCB"); 681 return(1); 682 } 683 684 /* cam_getccb cleans up the header, caller has to zero the payload */ 685 bzero(&(&ccb->ccb_h)[1], 686 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 687 688 inq_buf = (struct scsi_inquiry_data *)malloc( 689 sizeof(struct scsi_inquiry_data)); 690 691 if (inq_buf == NULL) { 692 cam_freeccb(ccb); 693 warnx("can't malloc memory for inquiry\n"); 694 return(1); 695 } 696 bzero(inq_buf, sizeof(*inq_buf)); 697 698 /* 699 * Note that although the size of the inquiry buffer is the full 700 * 256 bytes specified in the SCSI spec, we only tell the device 701 * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are 702 * two reasons for this: 703 * 704 * - The SCSI spec says that when a length field is only 1 byte, 705 * a value of 0 will be interpreted as 256. Therefore 706 * scsi_inquiry() will convert an inq_len (which is passed in as 707 * a u_int32_t, but the field in the CDB is only 1 byte) of 256 708 * to 0. Evidently, very few devices meet the spec in that 709 * regard. Some devices, like many Seagate disks, take the 0 as 710 * 0, and don't return any data. One Pioneer DVD-R drive 711 * returns more data than the command asked for. 712 * 713 * So, since there are numerous devices that just don't work 714 * right with the full inquiry size, we don't send the full size. 715 * 716 * - The second reason not to use the full inquiry data length is 717 * that we don't need it here. The only reason we issue a 718 * standard inquiry is to get the vendor name, device name, 719 * and revision so scsi_print_inquiry() can print them. 720 * 721 * If, at some point in the future, more inquiry data is needed for 722 * some reason, this code should use a procedure similar to the 723 * probe code. i.e., issue a short inquiry, and determine from 724 * the additional length passed back from the device how much 725 * inquiry data the device supports. Once the amount the device 726 * supports is determined, issue an inquiry for that amount and no 727 * more. 728 * 729 * KDM, 2/18/2000 730 */ 731 scsi_inquiry(&ccb->csio, 732 /* retries */ retry_count, 733 /* cbfcnp */ NULL, 734 /* tag_action */ MSG_SIMPLE_Q_TAG, 735 /* inq_buf */ (u_int8_t *)inq_buf, 736 /* inq_len */ SHORT_INQUIRY_LENGTH, 737 /* evpd */ 0, 738 /* page_code */ 0, 739 /* sense_len */ SSD_FULL_SIZE, 740 /* timeout */ timeout ? timeout : 5000); 741 742 /* Disable freezing the device queue */ 743 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 744 745 if (arglist & CAM_ARG_ERR_RECOVER) 746 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 747 748 if (cam_send_ccb(device, ccb) < 0) { 749 perror("error sending SCSI inquiry"); 750 751 if (arglist & CAM_ARG_VERBOSE) { 752 cam_error_print(device, ccb, CAM_ESF_ALL, 753 CAM_EPF_ALL, stderr); 754 } 755 756 cam_freeccb(ccb); 757 return(1); 758 } 759 760 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 761 error = 1; 762 763 if (arglist & CAM_ARG_VERBOSE) { 764 cam_error_print(device, ccb, CAM_ESF_ALL, 765 CAM_EPF_ALL, stderr); 766 } 767 } 768 769 cam_freeccb(ccb); 770 771 if (error != 0) { 772 free(inq_buf); 773 return(error); 774 } 775 776 fprintf(stdout, "%s%d: ", device->device_name, 777 device->dev_unit_num); 778 scsi_print_inquiry(inq_buf); 779 780 free(inq_buf); 781 782 return(0); 783 } 784 785 static int 786 scsiserial(struct cam_device *device, int retry_count, int timeout) 787 { 788 union ccb *ccb; 789 struct scsi_vpd_unit_serial_number *serial_buf; 790 char serial_num[SVPD_SERIAL_NUM_SIZE + 1]; 791 int error = 0; 792 793 ccb = cam_getccb(device); 794 795 if (ccb == NULL) { 796 warnx("couldn't allocate CCB"); 797 return(1); 798 } 799 800 /* cam_getccb cleans up the header, caller has to zero the payload */ 801 bzero(&(&ccb->ccb_h)[1], 802 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 803 804 serial_buf = (struct scsi_vpd_unit_serial_number *) 805 malloc(sizeof(*serial_buf)); 806 807 if (serial_buf == NULL) { 808 cam_freeccb(ccb); 809 warnx("can't malloc memory for serial number"); 810 return(1); 811 } 812 813 scsi_inquiry(&ccb->csio, 814 /*retries*/ retry_count, 815 /*cbfcnp*/ NULL, 816 /* tag_action */ MSG_SIMPLE_Q_TAG, 817 /* inq_buf */ (u_int8_t *)serial_buf, 818 /* inq_len */ sizeof(*serial_buf), 819 /* evpd */ 1, 820 /* page_code */ SVPD_UNIT_SERIAL_NUMBER, 821 /* sense_len */ SSD_FULL_SIZE, 822 /* timeout */ timeout ? timeout : 5000); 823 824 /* Disable freezing the device queue */ 825 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 826 827 if (arglist & CAM_ARG_ERR_RECOVER) 828 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 829 830 if (cam_send_ccb(device, ccb) < 0) { 831 warn("error getting serial number"); 832 833 if (arglist & CAM_ARG_VERBOSE) { 834 cam_error_print(device, ccb, CAM_ESF_ALL, 835 CAM_EPF_ALL, stderr); 836 } 837 838 cam_freeccb(ccb); 839 free(serial_buf); 840 return(1); 841 } 842 843 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 844 error = 1; 845 846 if (arglist & CAM_ARG_VERBOSE) { 847 cam_error_print(device, ccb, CAM_ESF_ALL, 848 CAM_EPF_ALL, stderr); 849 } 850 } 851 852 cam_freeccb(ccb); 853 854 if (error != 0) { 855 free(serial_buf); 856 return(error); 857 } 858 859 bcopy(serial_buf->serial_num, serial_num, serial_buf->length); 860 serial_num[serial_buf->length] = '\0'; 861 862 if ((arglist & CAM_ARG_GET_STDINQ) 863 || (arglist & CAM_ARG_GET_XFERRATE)) 864 fprintf(stdout, "%s%d: Serial Number ", 865 device->device_name, device->dev_unit_num); 866 867 fprintf(stdout, "%.60s\n", serial_num); 868 869 free(serial_buf); 870 871 return(0); 872 } 873 874 static int 875 scsixferrate(struct cam_device *device) 876 { 877 u_int32_t freq = 0; 878 u_int32_t speed = 0; 879 union ccb *ccb; 880 u_int mb; 881 int retval = 0; 882 883 ccb = cam_getccb(device); 884 885 if (ccb == NULL) { 886 warnx("couldn't allocate CCB"); 887 return(1); 888 } 889 890 bzero(&(&ccb->ccb_h)[1], 891 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr)); 892 893 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 894 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS; 895 896 if (((retval = cam_send_ccb(device, ccb)) < 0) 897 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 898 const char error_string[] = "error getting transfer settings"; 899 900 if (retval < 0) 901 warn(error_string); 902 else 903 warnx(error_string); 904 905 if (arglist & CAM_ARG_VERBOSE) 906 cam_error_print(device, ccb, CAM_ESF_ALL, 907 CAM_EPF_ALL, stderr); 908 909 retval = 1; 910 911 goto xferrate_bailout; 912 913 } 914 915 if (ccb->cts.transport == XPORT_SPI) { 916 struct ccb_trans_settings_spi *spi = 917 &ccb->cts.xport_specific.spi; 918 919 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { 920 freq = scsi_calc_syncsrate(spi->sync_period); 921 speed = freq; 922 } else { 923 struct ccb_pathinq cpi; 924 925 retval = get_cpi(device, &cpi); 926 if (retval == 0) { 927 speed = cpi.base_transfer_speed; 928 freq = 0; 929 } 930 } 931 932 fprintf(stdout, "%s%d: ", device->device_name, 933 device->dev_unit_num); 934 935 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { 936 speed *= (0x01 << spi->bus_width); 937 } 938 939 mb = speed / 1000; 940 941 if (mb > 0) 942 fprintf(stdout, "%d.%03dMB/s transfers ", 943 mb, speed % 1000); 944 else 945 fprintf(stdout, "%dKB/s transfers ", 946 speed); 947 948 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) 949 && (spi->sync_offset != 0)) 950 fprintf(stdout, "(%d.%03dMHz, offset %d", freq / 1000, 951 freq % 1000, spi->sync_offset); 952 953 if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) 954 && (spi->bus_width > 0)) { 955 if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) 956 && (spi->sync_offset != 0)) { 957 fprintf(stdout, ", "); 958 } else { 959 fprintf(stdout, " ("); 960 } 961 fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width)); 962 } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) 963 && (spi->sync_offset != 0)) { 964 fprintf(stdout, ")"); 965 } 966 } else { 967 struct ccb_pathinq cpi; 968 969 retval = get_cpi(device, &cpi); 970 971 if (retval != 0) 972 goto xferrate_bailout; 973 974 speed = cpi.base_transfer_speed; 975 freq = 0; 976 977 mb = speed / 1000; 978 979 if (mb > 0) 980 fprintf(stdout, "%d.%03dMB/s transfers ", 981 mb, speed % 1000); 982 else 983 fprintf(stdout, "%dKB/s transfers ", 984 speed); 985 } 986 987 if (ccb->cts.protocol == PROTO_SCSI) { 988 struct ccb_trans_settings_scsi *scsi = 989 &ccb->cts.proto_specific.scsi; 990 if (scsi->valid & CTS_SCSI_VALID_TQ) { 991 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) { 992 fprintf(stdout, ", Command Queueing Enabled"); 993 } 994 } 995 } 996 997 fprintf(stdout, "\n"); 998 999 xferrate_bailout: 1000 1001 cam_freeccb(ccb); 1002 1003 return(retval); 1004 } 1005 1006 static void 1007 atacapprint(struct ata_params *parm) 1008 { 1009 u_int32_t lbasize = (u_int32_t)parm->lba_size_1 | 1010 ((u_int32_t)parm->lba_size_2 << 16); 1011 1012 u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) | 1013 ((u_int64_t)parm->lba_size48_2 << 16) | 1014 ((u_int64_t)parm->lba_size48_3 << 32) | 1015 ((u_int64_t)parm->lba_size48_4 << 48); 1016 1017 printf("\n"); 1018 printf("Protocol "); 1019 if (parm->satacapabilities && parm->satacapabilities != 0xffff) { 1020 if (parm->satacapabilities & ATA_SATA_GEN2) 1021 printf("SATA revision 2.x\n"); 1022 else if (parm->satacapabilities & ATA_SATA_GEN1) 1023 printf("SATA revision 1.x\n"); 1024 else 1025 printf("Unknown SATA revision\n"); 1026 } 1027 else 1028 printf("ATA/ATAPI revision %d\n", ata_version(parm->version_major)); 1029 printf("device model %.40s\n", parm->model); 1030 printf("serial number %.20s\n", parm->serial); 1031 printf("firmware revision %.8s\n", parm->revision); 1032 1033 printf("cylinders %d\n", parm->cylinders); 1034 printf("heads %d\n", parm->heads); 1035 printf("sectors/track %d\n", parm->sectors); 1036 1037 if (parm->config == ATA_PROTO_CFA || 1038 (parm->support.command2 & ATA_SUPPORT_CFA)) 1039 printf("CFA supported\n"); 1040 1041 printf("lba%ssupported ", 1042 parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not "); 1043 if (lbasize) 1044 printf("%d sectors\n", lbasize); 1045 else 1046 printf("\n"); 1047 1048 printf("lba48%ssupported ", 1049 parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not "); 1050 if (lbasize48) 1051 printf("%ju sectors\n", (uintmax_t)lbasize48); 1052 else 1053 printf("\n"); 1054 1055 printf("dma%ssupported\n", 1056 parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not "); 1057 1058 printf("overlap%ssupported\n", 1059 parm->capabilities1 & ATA_SUPPORT_OVERLAP ? " " : " not "); 1060 1061 printf("\nFeature " 1062 "Support Enable Value Vendor\n"); 1063 1064 printf("write cache %s %s\n", 1065 parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no", 1066 parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no"); 1067 1068 printf("read ahead %s %s\n", 1069 parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no", 1070 parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no"); 1071 1072 if (parm->satacapabilities && parm->satacapabilities != 0xffff) { 1073 printf("Native Command Queuing (NCQ) %s %s" 1074 " %d/0x%02X\n", 1075 parm->satacapabilities & ATA_SUPPORT_NCQ ? 1076 "yes" : "no", " -", 1077 (parm->satacapabilities & ATA_SUPPORT_NCQ) ? 1078 ATA_QUEUE_LEN(parm->queue) : 0, 1079 (parm->satacapabilities & ATA_SUPPORT_NCQ) ? 1080 ATA_QUEUE_LEN(parm->queue) : 0); 1081 } 1082 printf("Tagged Command Queuing (TCQ) %s %s %d/0x%02X\n", 1083 parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no", 1084 parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no", 1085 ATA_QUEUE_LEN(parm->queue), ATA_QUEUE_LEN(parm->queue)); 1086 1087 printf("SMART %s %s\n", 1088 parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no", 1089 parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no"); 1090 1091 printf("microcode download %s %s\n", 1092 parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no", 1093 parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no"); 1094 1095 printf("security %s %s\n", 1096 parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no", 1097 parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no"); 1098 1099 printf("power management %s %s\n", 1100 parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no", 1101 parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no"); 1102 1103 printf("advanced power management %s %s %d/0x%02X\n", 1104 parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no", 1105 parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no", 1106 parm->apm_value, parm->apm_value); 1107 1108 printf("automatic acoustic management %s %s " 1109 "%d/0x%02X %d/0x%02X\n", 1110 parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no", 1111 parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no", 1112 ATA_ACOUSTIC_CURRENT(parm->acoustic), 1113 ATA_ACOUSTIC_CURRENT(parm->acoustic), 1114 ATA_ACOUSTIC_VENDOR(parm->acoustic), 1115 ATA_ACOUSTIC_VENDOR(parm->acoustic)); 1116 } 1117 1118 1119 static int 1120 ataidentify(struct cam_device *device, int retry_count, int timeout) 1121 { 1122 union ccb *ccb; 1123 struct ata_params *ident_buf; 1124 u_int i, error = 0; 1125 int16_t *ptr; 1126 1127 ccb = cam_getccb(device); 1128 1129 if (ccb == NULL) { 1130 warnx("couldn't allocate CCB"); 1131 return(1); 1132 } 1133 1134 /* cam_getccb cleans up the header, caller has to zero the payload */ 1135 bzero(&(&ccb->ccb_h)[1], 1136 sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr)); 1137 1138 ptr = (uint16_t *)malloc(sizeof(struct ata_params)); 1139 1140 if (ptr == NULL) { 1141 cam_freeccb(ccb); 1142 warnx("can't malloc memory for identify\n"); 1143 return(1); 1144 } 1145 bzero(ptr, sizeof(struct ata_params)); 1146 1147 cam_fill_ataio(&ccb->ataio, 1148 retry_count, 1149 NULL, 1150 /*flags*/CAM_DIR_IN, 1151 MSG_SIMPLE_Q_TAG, 1152 /*data_ptr*/(u_int8_t *)ptr, 1153 /*dxfer_len*/sizeof(struct ata_params), 1154 timeout ? timeout : 30 * 1000); 1155 // if (periph->path->device->protocol == PROTO_ATA) 1156 ata_36bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0); 1157 // else 1158 // ata_36bit_cmd(&ccb->ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0); 1159 1160 /* Disable freezing the device queue */ 1161 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 1162 1163 if (arglist & CAM_ARG_ERR_RECOVER) 1164 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 1165 1166 if (cam_send_ccb(device, ccb) < 0) { 1167 perror("error sending ATA identify"); 1168 1169 if (arglist & CAM_ARG_VERBOSE) { 1170 cam_error_print(device, ccb, CAM_ESF_ALL, 1171 CAM_EPF_ALL, stderr); 1172 } 1173 1174 free(ptr); 1175 cam_freeccb(ccb); 1176 return(1); 1177 } 1178 1179 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1180 error = 1; 1181 1182 if (arglist & CAM_ARG_VERBOSE) { 1183 cam_error_print(device, ccb, CAM_ESF_ALL, 1184 CAM_EPF_ALL, stderr); 1185 } 1186 } 1187 1188 cam_freeccb(ccb); 1189 1190 if (error != 0) { 1191 free(ptr); 1192 return(error); 1193 } 1194 1195 for (i = 0; i < sizeof(struct ata_params) / 2; i++) 1196 ptr[i] = le16toh(ptr[i]); 1197 ident_buf = (struct ata_params *)ptr; 1198 1199 if (strncmp(ident_buf->model, "FX", 2) && 1200 strncmp(ident_buf->model, "NEC", 3) && 1201 strncmp(ident_buf->model, "Pioneer", 7) && 1202 strncmp(ident_buf->model, "SHARP", 5)) { 1203 ata_bswap(ident_buf->model, sizeof(ident_buf->model)); 1204 ata_bswap(ident_buf->revision, sizeof(ident_buf->revision)); 1205 ata_bswap(ident_buf->serial, sizeof(ident_buf->serial)); 1206 } 1207 ata_btrim(ident_buf->model, sizeof(ident_buf->model)); 1208 ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model)); 1209 ata_btrim(ident_buf->revision, sizeof(ident_buf->revision)); 1210 ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision)); 1211 ata_btrim(ident_buf->serial, sizeof(ident_buf->serial)); 1212 ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial)); 1213 1214 fprintf(stdout, "%s%d: ", device->device_name, 1215 device->dev_unit_num); 1216 ata_print_ident(ident_buf); 1217 atacapprint(ident_buf); 1218 1219 free(ident_buf); 1220 1221 return(0); 1222 } 1223 #endif /* MINIMALISTIC */ 1224 1225 /* 1226 * Parse out a bus, or a bus, target and lun in the following 1227 * format: 1228 * bus 1229 * bus:target 1230 * bus:target:lun 1231 * 1232 * Returns the number of parsed components, or 0. 1233 */ 1234 static int 1235 parse_btl(char *tstr, int *bus, int *target, int *lun, cam_argmask *arglst) 1236 { 1237 char *tmpstr; 1238 int convs = 0; 1239 1240 while (isspace(*tstr) && (*tstr != '\0')) 1241 tstr++; 1242 1243 tmpstr = (char *)strtok(tstr, ":"); 1244 if ((tmpstr != NULL) && (*tmpstr != '\0')) { 1245 *bus = strtol(tmpstr, NULL, 0); 1246 *arglst |= CAM_ARG_BUS; 1247 convs++; 1248 tmpstr = (char *)strtok(NULL, ":"); 1249 if ((tmpstr != NULL) && (*tmpstr != '\0')) { 1250 *target = strtol(tmpstr, NULL, 0); 1251 *arglst |= CAM_ARG_TARGET; 1252 convs++; 1253 tmpstr = (char *)strtok(NULL, ":"); 1254 if ((tmpstr != NULL) && (*tmpstr != '\0')) { 1255 *lun = strtol(tmpstr, NULL, 0); 1256 *arglst |= CAM_ARG_LUN; 1257 convs++; 1258 } 1259 } 1260 } 1261 1262 return convs; 1263 } 1264 1265 static int 1266 dorescan_or_reset(int argc, char **argv, int rescan) 1267 { 1268 static const char must[] = 1269 "you must specify \"all\", a bus, or a bus:target:lun to %s"; 1270 int rv, error = 0; 1271 int bus = -1, target = -1, lun = -1; 1272 char *tstr; 1273 1274 if (argc < 3) { 1275 warnx(must, rescan? "rescan" : "reset"); 1276 return(1); 1277 } 1278 1279 tstr = argv[optind]; 1280 while (isspace(*tstr) && (*tstr != '\0')) 1281 tstr++; 1282 if (strncasecmp(tstr, "all", strlen("all")) == 0) 1283 arglist |= CAM_ARG_BUS; 1284 else { 1285 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist); 1286 if (rv != 1 && rv != 3) { 1287 warnx(must, rescan? "rescan" : "reset"); 1288 return(1); 1289 } 1290 } 1291 1292 if ((arglist & CAM_ARG_BUS) 1293 && (arglist & CAM_ARG_TARGET) 1294 && (arglist & CAM_ARG_LUN)) 1295 error = scanlun_or_reset_dev(bus, target, lun, rescan); 1296 else 1297 error = rescan_or_reset_bus(bus, rescan); 1298 1299 return(error); 1300 } 1301 1302 static int 1303 rescan_or_reset_bus(int bus, int rescan) 1304 { 1305 union ccb ccb, matchccb; 1306 int fd, retval; 1307 int bufsize; 1308 1309 retval = 0; 1310 1311 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { 1312 warnx("error opening transport layer device %s", XPT_DEVICE); 1313 warn("%s", XPT_DEVICE); 1314 return(1); 1315 } 1316 1317 if (bus != -1) { 1318 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS; 1319 ccb.ccb_h.path_id = bus; 1320 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 1321 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 1322 ccb.crcn.flags = CAM_FLAG_NONE; 1323 1324 /* run this at a low priority */ 1325 ccb.ccb_h.pinfo.priority = 5; 1326 1327 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 1328 warn("CAMIOCOMMAND ioctl failed"); 1329 close(fd); 1330 return(1); 1331 } 1332 1333 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { 1334 fprintf(stdout, "%s of bus %d was successful\n", 1335 rescan ? "Re-scan" : "Reset", bus); 1336 } else { 1337 fprintf(stdout, "%s of bus %d returned error %#x\n", 1338 rescan ? "Re-scan" : "Reset", bus, 1339 ccb.ccb_h.status & CAM_STATUS_MASK); 1340 retval = 1; 1341 } 1342 1343 close(fd); 1344 return(retval); 1345 1346 } 1347 1348 1349 /* 1350 * The right way to handle this is to modify the xpt so that it can 1351 * handle a wildcarded bus in a rescan or reset CCB. At the moment 1352 * that isn't implemented, so instead we enumerate the busses and 1353 * send the rescan or reset to those busses in the case where the 1354 * given bus is -1 (wildcard). We don't send a rescan or reset 1355 * to the xpt bus; sending a rescan to the xpt bus is effectively a 1356 * no-op, sending a rescan to the xpt bus would result in a status of 1357 * CAM_REQ_INVALID. 1358 */ 1359 bzero(&(&matchccb.ccb_h)[1], 1360 sizeof(struct ccb_dev_match) - sizeof(struct ccb_hdr)); 1361 matchccb.ccb_h.func_code = XPT_DEV_MATCH; 1362 bufsize = sizeof(struct dev_match_result) * 20; 1363 matchccb.cdm.match_buf_len = bufsize; 1364 matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize); 1365 if (matchccb.cdm.matches == NULL) { 1366 warnx("can't malloc memory for matches"); 1367 retval = 1; 1368 goto bailout; 1369 } 1370 matchccb.cdm.num_matches = 0; 1371 1372 matchccb.cdm.num_patterns = 1; 1373 matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern); 1374 1375 matchccb.cdm.patterns = (struct dev_match_pattern *)malloc( 1376 matchccb.cdm.pattern_buf_len); 1377 if (matchccb.cdm.patterns == NULL) { 1378 warnx("can't malloc memory for patterns"); 1379 retval = 1; 1380 goto bailout; 1381 } 1382 matchccb.cdm.patterns[0].type = DEV_MATCH_BUS; 1383 matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY; 1384 1385 do { 1386 unsigned int i; 1387 1388 if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) { 1389 warn("CAMIOCOMMAND ioctl failed"); 1390 retval = 1; 1391 goto bailout; 1392 } 1393 1394 if ((matchccb.ccb_h.status != CAM_REQ_CMP) 1395 || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST) 1396 && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) { 1397 warnx("got CAM error %#x, CDM error %d\n", 1398 matchccb.ccb_h.status, matchccb.cdm.status); 1399 retval = 1; 1400 goto bailout; 1401 } 1402 1403 for (i = 0; i < matchccb.cdm.num_matches; i++) { 1404 struct bus_match_result *bus_result; 1405 1406 /* This shouldn't happen. */ 1407 if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS) 1408 continue; 1409 1410 bus_result = &matchccb.cdm.matches[i].result.bus_result; 1411 1412 /* 1413 * We don't want to rescan or reset the xpt bus. 1414 * See above. 1415 */ 1416 if ((int)bus_result->path_id == -1) 1417 continue; 1418 1419 ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : 1420 XPT_RESET_BUS; 1421 ccb.ccb_h.path_id = bus_result->path_id; 1422 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 1423 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 1424 ccb.crcn.flags = CAM_FLAG_NONE; 1425 1426 /* run this at a low priority */ 1427 ccb.ccb_h.pinfo.priority = 5; 1428 1429 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 1430 warn("CAMIOCOMMAND ioctl failed"); 1431 retval = 1; 1432 goto bailout; 1433 } 1434 1435 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){ 1436 fprintf(stdout, "%s of bus %d was successful\n", 1437 rescan? "Re-scan" : "Reset", 1438 bus_result->path_id); 1439 } else { 1440 /* 1441 * Don't bail out just yet, maybe the other 1442 * rescan or reset commands will complete 1443 * successfully. 1444 */ 1445 fprintf(stderr, "%s of bus %d returned error " 1446 "%#x\n", rescan? "Re-scan" : "Reset", 1447 bus_result->path_id, 1448 ccb.ccb_h.status & CAM_STATUS_MASK); 1449 retval = 1; 1450 } 1451 } 1452 } while ((matchccb.ccb_h.status == CAM_REQ_CMP) 1453 && (matchccb.cdm.status == CAM_DEV_MATCH_MORE)); 1454 1455 bailout: 1456 1457 if (fd != -1) 1458 close(fd); 1459 1460 if (matchccb.cdm.patterns != NULL) 1461 free(matchccb.cdm.patterns); 1462 if (matchccb.cdm.matches != NULL) 1463 free(matchccb.cdm.matches); 1464 1465 return(retval); 1466 } 1467 1468 static int 1469 scanlun_or_reset_dev(int bus, int target, int lun, int scan) 1470 { 1471 union ccb ccb; 1472 struct cam_device *device; 1473 int fd; 1474 1475 device = NULL; 1476 1477 if (bus < 0) { 1478 warnx("invalid bus number %d", bus); 1479 return(1); 1480 } 1481 1482 if (target < 0) { 1483 warnx("invalid target number %d", target); 1484 return(1); 1485 } 1486 1487 if (lun < 0) { 1488 warnx("invalid lun number %d", lun); 1489 return(1); 1490 } 1491 1492 fd = -1; 1493 1494 bzero(&ccb, sizeof(union ccb)); 1495 1496 if (scan) { 1497 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { 1498 warnx("error opening transport layer device %s\n", 1499 XPT_DEVICE); 1500 warn("%s", XPT_DEVICE); 1501 return(1); 1502 } 1503 } else { 1504 device = cam_open_btl(bus, target, lun, O_RDWR, NULL); 1505 if (device == NULL) { 1506 warnx("%s", cam_errbuf); 1507 return(1); 1508 } 1509 } 1510 1511 ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV; 1512 ccb.ccb_h.path_id = bus; 1513 ccb.ccb_h.target_id = target; 1514 ccb.ccb_h.target_lun = lun; 1515 ccb.ccb_h.timeout = 5000; 1516 ccb.crcn.flags = CAM_FLAG_NONE; 1517 1518 /* run this at a low priority */ 1519 ccb.ccb_h.pinfo.priority = 5; 1520 1521 if (scan) { 1522 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) { 1523 warn("CAMIOCOMMAND ioctl failed"); 1524 close(fd); 1525 return(1); 1526 } 1527 } else { 1528 if (cam_send_ccb(device, &ccb) < 0) { 1529 warn("error sending XPT_RESET_DEV CCB"); 1530 cam_close_device(device); 1531 return(1); 1532 } 1533 } 1534 1535 if (scan) 1536 close(fd); 1537 else 1538 cam_close_device(device); 1539 1540 /* 1541 * An error code of CAM_BDR_SENT is normal for a BDR request. 1542 */ 1543 if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 1544 || ((!scan) 1545 && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) { 1546 fprintf(stdout, "%s of %d:%d:%d was successful\n", 1547 scan? "Re-scan" : "Reset", bus, target, lun); 1548 return(0); 1549 } else { 1550 fprintf(stdout, "%s of %d:%d:%d returned error %#x\n", 1551 scan? "Re-scan" : "Reset", bus, target, lun, 1552 ccb.ccb_h.status & CAM_STATUS_MASK); 1553 return(1); 1554 } 1555 } 1556 1557 #ifndef MINIMALISTIC 1558 static int 1559 readdefects(struct cam_device *device, int argc, char **argv, 1560 char *combinedopt, int retry_count, int timeout) 1561 { 1562 union ccb *ccb = NULL; 1563 struct scsi_read_defect_data_10 *rdd_cdb; 1564 u_int8_t *defect_list = NULL; 1565 u_int32_t dlist_length = 65000; 1566 u_int32_t returned_length = 0; 1567 u_int32_t num_returned = 0; 1568 u_int8_t returned_format; 1569 unsigned int i; 1570 int c, error = 0; 1571 int lists_specified = 0; 1572 1573 while ((c = getopt(argc, argv, combinedopt)) != -1) { 1574 switch(c){ 1575 case 'f': 1576 { 1577 char *tstr; 1578 tstr = optarg; 1579 while (isspace(*tstr) && (*tstr != '\0')) 1580 tstr++; 1581 if (strcmp(tstr, "block") == 0) 1582 arglist |= CAM_ARG_FORMAT_BLOCK; 1583 else if (strcmp(tstr, "bfi") == 0) 1584 arglist |= CAM_ARG_FORMAT_BFI; 1585 else if (strcmp(tstr, "phys") == 0) 1586 arglist |= CAM_ARG_FORMAT_PHYS; 1587 else { 1588 error = 1; 1589 warnx("invalid defect format %s", tstr); 1590 goto defect_bailout; 1591 } 1592 break; 1593 } 1594 case 'G': 1595 arglist |= CAM_ARG_GLIST; 1596 break; 1597 case 'P': 1598 arglist |= CAM_ARG_PLIST; 1599 break; 1600 default: 1601 break; 1602 } 1603 } 1604 1605 ccb = cam_getccb(device); 1606 1607 /* 1608 * Hopefully 65000 bytes is enough to hold the defect list. If it 1609 * isn't, the disk is probably dead already. We'd have to go with 1610 * 12 byte command (i.e. alloc_length is 32 bits instead of 16) 1611 * to hold them all. 1612 */ 1613 defect_list = malloc(dlist_length); 1614 if (defect_list == NULL) { 1615 warnx("can't malloc memory for defect list"); 1616 error = 1; 1617 goto defect_bailout; 1618 } 1619 1620 rdd_cdb =(struct scsi_read_defect_data_10 *)&ccb->csio.cdb_io.cdb_bytes; 1621 1622 /* 1623 * cam_getccb() zeros the CCB header only. So we need to zero the 1624 * payload portion of the ccb. 1625 */ 1626 bzero(&(&ccb->ccb_h)[1], 1627 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 1628 1629 cam_fill_csio(&ccb->csio, 1630 /*retries*/ retry_count, 1631 /*cbfcnp*/ NULL, 1632 /*flags*/ CAM_DIR_IN | ((arglist & CAM_ARG_ERR_RECOVER) ? 1633 CAM_PASS_ERR_RECOVER : 0), 1634 /*tag_action*/ MSG_SIMPLE_Q_TAG, 1635 /*data_ptr*/ defect_list, 1636 /*dxfer_len*/ dlist_length, 1637 /*sense_len*/ SSD_FULL_SIZE, 1638 /*cdb_len*/ sizeof(struct scsi_read_defect_data_10), 1639 /*timeout*/ timeout ? timeout : 5000); 1640 1641 rdd_cdb->opcode = READ_DEFECT_DATA_10; 1642 if (arglist & CAM_ARG_FORMAT_BLOCK) 1643 rdd_cdb->format = SRDD10_BLOCK_FORMAT; 1644 else if (arglist & CAM_ARG_FORMAT_BFI) 1645 rdd_cdb->format = SRDD10_BYTES_FROM_INDEX_FORMAT; 1646 else if (arglist & CAM_ARG_FORMAT_PHYS) 1647 rdd_cdb->format = SRDD10_PHYSICAL_SECTOR_FORMAT; 1648 else { 1649 error = 1; 1650 warnx("no defect list format specified"); 1651 goto defect_bailout; 1652 } 1653 if (arglist & CAM_ARG_PLIST) { 1654 rdd_cdb->format |= SRDD10_PLIST; 1655 lists_specified++; 1656 } 1657 1658 if (arglist & CAM_ARG_GLIST) { 1659 rdd_cdb->format |= SRDD10_GLIST; 1660 lists_specified++; 1661 } 1662 1663 scsi_ulto2b(dlist_length, rdd_cdb->alloc_length); 1664 1665 /* Disable freezing the device queue */ 1666 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 1667 1668 if (cam_send_ccb(device, ccb) < 0) { 1669 perror("error reading defect list"); 1670 1671 if (arglist & CAM_ARG_VERBOSE) { 1672 cam_error_print(device, ccb, CAM_ESF_ALL, 1673 CAM_EPF_ALL, stderr); 1674 } 1675 1676 error = 1; 1677 goto defect_bailout; 1678 } 1679 1680 returned_length = scsi_2btoul(((struct 1681 scsi_read_defect_data_hdr_10 *)defect_list)->length); 1682 1683 returned_format = ((struct scsi_read_defect_data_hdr_10 *) 1684 defect_list)->format; 1685 1686 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) 1687 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) 1688 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 1689 struct scsi_sense_data *sense; 1690 int error_code, sense_key, asc, ascq; 1691 1692 sense = &ccb->csio.sense_data; 1693 scsi_extract_sense(sense, &error_code, &sense_key, &asc, &ascq); 1694 1695 /* 1696 * According to the SCSI spec, if the disk doesn't support 1697 * the requested format, it will generally return a sense 1698 * key of RECOVERED ERROR, and an additional sense code 1699 * of "DEFECT LIST NOT FOUND". So, we check for that, and 1700 * also check to make sure that the returned length is 1701 * greater than 0, and then print out whatever format the 1702 * disk gave us. 1703 */ 1704 if ((sense_key == SSD_KEY_RECOVERED_ERROR) 1705 && (asc == 0x1c) && (ascq == 0x00) 1706 && (returned_length > 0)) { 1707 warnx("requested defect format not available"); 1708 switch(returned_format & SRDDH10_DLIST_FORMAT_MASK) { 1709 case SRDD10_BLOCK_FORMAT: 1710 warnx("Device returned block format"); 1711 break; 1712 case SRDD10_BYTES_FROM_INDEX_FORMAT: 1713 warnx("Device returned bytes from index" 1714 " format"); 1715 break; 1716 case SRDD10_PHYSICAL_SECTOR_FORMAT: 1717 warnx("Device returned physical sector format"); 1718 break; 1719 default: 1720 error = 1; 1721 warnx("Device returned unknown defect" 1722 " data format %#x", returned_format); 1723 goto defect_bailout; 1724 break; /* NOTREACHED */ 1725 } 1726 } else { 1727 error = 1; 1728 warnx("Error returned from read defect data command"); 1729 if (arglist & CAM_ARG_VERBOSE) 1730 cam_error_print(device, ccb, CAM_ESF_ALL, 1731 CAM_EPF_ALL, stderr); 1732 goto defect_bailout; 1733 } 1734 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1735 error = 1; 1736 warnx("Error returned from read defect data command"); 1737 if (arglist & CAM_ARG_VERBOSE) 1738 cam_error_print(device, ccb, CAM_ESF_ALL, 1739 CAM_EPF_ALL, stderr); 1740 goto defect_bailout; 1741 } 1742 1743 /* 1744 * XXX KDM I should probably clean up the printout format for the 1745 * disk defects. 1746 */ 1747 switch (returned_format & SRDDH10_DLIST_FORMAT_MASK){ 1748 case SRDDH10_PHYSICAL_SECTOR_FORMAT: 1749 { 1750 struct scsi_defect_desc_phys_sector *dlist; 1751 1752 dlist = (struct scsi_defect_desc_phys_sector *) 1753 (defect_list + 1754 sizeof(struct scsi_read_defect_data_hdr_10)); 1755 1756 num_returned = returned_length / 1757 sizeof(struct scsi_defect_desc_phys_sector); 1758 1759 fprintf(stderr, "Got %d defect", num_returned); 1760 1761 if ((lists_specified == 0) || (num_returned == 0)) { 1762 fprintf(stderr, "s.\n"); 1763 break; 1764 } else if (num_returned == 1) 1765 fprintf(stderr, ":\n"); 1766 else 1767 fprintf(stderr, "s:\n"); 1768 1769 for (i = 0; i < num_returned; i++) { 1770 fprintf(stdout, "%d:%d:%d\n", 1771 scsi_3btoul(dlist[i].cylinder), 1772 dlist[i].head, 1773 scsi_4btoul(dlist[i].sector)); 1774 } 1775 break; 1776 } 1777 case SRDDH10_BYTES_FROM_INDEX_FORMAT: 1778 { 1779 struct scsi_defect_desc_bytes_from_index *dlist; 1780 1781 dlist = (struct scsi_defect_desc_bytes_from_index *) 1782 (defect_list + 1783 sizeof(struct scsi_read_defect_data_hdr_10)); 1784 1785 num_returned = returned_length / 1786 sizeof(struct scsi_defect_desc_bytes_from_index); 1787 1788 fprintf(stderr, "Got %d defect", num_returned); 1789 1790 if ((lists_specified == 0) || (num_returned == 0)) { 1791 fprintf(stderr, "s.\n"); 1792 break; 1793 } else if (num_returned == 1) 1794 fprintf(stderr, ":\n"); 1795 else 1796 fprintf(stderr, "s:\n"); 1797 1798 for (i = 0; i < num_returned; i++) { 1799 fprintf(stdout, "%d:%d:%d\n", 1800 scsi_3btoul(dlist[i].cylinder), 1801 dlist[i].head, 1802 scsi_4btoul(dlist[i].bytes_from_index)); 1803 } 1804 break; 1805 } 1806 case SRDDH10_BLOCK_FORMAT: 1807 { 1808 struct scsi_defect_desc_block *dlist; 1809 1810 dlist = (struct scsi_defect_desc_block *)(defect_list + 1811 sizeof(struct scsi_read_defect_data_hdr_10)); 1812 1813 num_returned = returned_length / 1814 sizeof(struct scsi_defect_desc_block); 1815 1816 fprintf(stderr, "Got %d defect", num_returned); 1817 1818 if ((lists_specified == 0) || (num_returned == 0)) { 1819 fprintf(stderr, "s.\n"); 1820 break; 1821 } else if (num_returned == 1) 1822 fprintf(stderr, ":\n"); 1823 else 1824 fprintf(stderr, "s:\n"); 1825 1826 for (i = 0; i < num_returned; i++) 1827 fprintf(stdout, "%u\n", 1828 scsi_4btoul(dlist[i].address)); 1829 break; 1830 } 1831 default: 1832 fprintf(stderr, "Unknown defect format %d\n", 1833 returned_format & SRDDH10_DLIST_FORMAT_MASK); 1834 error = 1; 1835 break; 1836 } 1837 defect_bailout: 1838 1839 if (defect_list != NULL) 1840 free(defect_list); 1841 1842 if (ccb != NULL) 1843 cam_freeccb(ccb); 1844 1845 return(error); 1846 } 1847 #endif /* MINIMALISTIC */ 1848 1849 #if 0 1850 void 1851 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks) 1852 { 1853 union ccb *ccb; 1854 1855 ccb = cam_getccb(device); 1856 1857 cam_freeccb(ccb); 1858 } 1859 #endif 1860 1861 #ifndef MINIMALISTIC 1862 void 1863 mode_sense(struct cam_device *device, int mode_page, int page_control, 1864 int dbd, int retry_count, int timeout, u_int8_t *data, int datalen) 1865 { 1866 union ccb *ccb; 1867 int retval; 1868 1869 ccb = cam_getccb(device); 1870 1871 if (ccb == NULL) 1872 errx(1, "mode_sense: couldn't allocate CCB"); 1873 1874 bzero(&(&ccb->ccb_h)[1], 1875 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 1876 1877 scsi_mode_sense(&ccb->csio, 1878 /* retries */ retry_count, 1879 /* cbfcnp */ NULL, 1880 /* tag_action */ MSG_SIMPLE_Q_TAG, 1881 /* dbd */ dbd, 1882 /* page_code */ page_control << 6, 1883 /* page */ mode_page, 1884 /* param_buf */ data, 1885 /* param_len */ datalen, 1886 /* sense_len */ SSD_FULL_SIZE, 1887 /* timeout */ timeout ? timeout : 5000); 1888 1889 if (arglist & CAM_ARG_ERR_RECOVER) 1890 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 1891 1892 /* Disable freezing the device queue */ 1893 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 1894 1895 if (((retval = cam_send_ccb(device, ccb)) < 0) 1896 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 1897 if (arglist & CAM_ARG_VERBOSE) { 1898 cam_error_print(device, ccb, CAM_ESF_ALL, 1899 CAM_EPF_ALL, stderr); 1900 } 1901 cam_freeccb(ccb); 1902 cam_close_device(device); 1903 if (retval < 0) 1904 err(1, "error sending mode sense command"); 1905 else 1906 errx(1, "error sending mode sense command"); 1907 } 1908 1909 cam_freeccb(ccb); 1910 } 1911 1912 void 1913 mode_select(struct cam_device *device, int save_pages, int retry_count, 1914 int timeout, u_int8_t *data, int datalen) 1915 { 1916 union ccb *ccb; 1917 int retval; 1918 1919 ccb = cam_getccb(device); 1920 1921 if (ccb == NULL) 1922 errx(1, "mode_select: couldn't allocate CCB"); 1923 1924 bzero(&(&ccb->ccb_h)[1], 1925 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 1926 1927 scsi_mode_select(&ccb->csio, 1928 /* retries */ retry_count, 1929 /* cbfcnp */ NULL, 1930 /* tag_action */ MSG_SIMPLE_Q_TAG, 1931 /* scsi_page_fmt */ 1, 1932 /* save_pages */ save_pages, 1933 /* param_buf */ data, 1934 /* param_len */ datalen, 1935 /* sense_len */ SSD_FULL_SIZE, 1936 /* timeout */ timeout ? timeout : 5000); 1937 1938 if (arglist & CAM_ARG_ERR_RECOVER) 1939 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 1940 1941 /* Disable freezing the device queue */ 1942 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 1943 1944 if (((retval = cam_send_ccb(device, ccb)) < 0) 1945 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 1946 if (arglist & CAM_ARG_VERBOSE) { 1947 cam_error_print(device, ccb, CAM_ESF_ALL, 1948 CAM_EPF_ALL, stderr); 1949 } 1950 cam_freeccb(ccb); 1951 cam_close_device(device); 1952 1953 if (retval < 0) 1954 err(1, "error sending mode select command"); 1955 else 1956 errx(1, "error sending mode select command"); 1957 1958 } 1959 1960 cam_freeccb(ccb); 1961 } 1962 1963 void 1964 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, 1965 int retry_count, int timeout) 1966 { 1967 int c, mode_page = -1, page_control = 0; 1968 int binary = 0, list = 0; 1969 1970 while ((c = getopt(argc, argv, combinedopt)) != -1) { 1971 switch(c) { 1972 case 'b': 1973 binary = 1; 1974 break; 1975 case 'd': 1976 arglist |= CAM_ARG_DBD; 1977 break; 1978 case 'e': 1979 arglist |= CAM_ARG_MODE_EDIT; 1980 break; 1981 case 'l': 1982 list = 1; 1983 break; 1984 case 'm': 1985 mode_page = strtol(optarg, NULL, 0); 1986 if (mode_page < 0) 1987 errx(1, "invalid mode page %d", mode_page); 1988 break; 1989 case 'P': 1990 page_control = strtol(optarg, NULL, 0); 1991 if ((page_control < 0) || (page_control > 3)) 1992 errx(1, "invalid page control field %d", 1993 page_control); 1994 arglist |= CAM_ARG_PAGE_CNTL; 1995 break; 1996 default: 1997 break; 1998 } 1999 } 2000 2001 if (mode_page == -1 && list == 0) 2002 errx(1, "you must specify a mode page!"); 2003 2004 if (list) { 2005 mode_list(device, page_control, arglist & CAM_ARG_DBD, 2006 retry_count, timeout); 2007 } else { 2008 mode_edit(device, mode_page, page_control, 2009 arglist & CAM_ARG_DBD, arglist & CAM_ARG_MODE_EDIT, binary, 2010 retry_count, timeout); 2011 } 2012 } 2013 2014 static int 2015 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, 2016 int retry_count, int timeout) 2017 { 2018 union ccb *ccb; 2019 u_int32_t flags = CAM_DIR_NONE; 2020 u_int8_t *data_ptr = NULL; 2021 u_int8_t cdb[20]; 2022 struct get_hook hook; 2023 int c, data_bytes = 0; 2024 int cdb_len = 0; 2025 char *datastr = NULL, *tstr; 2026 int error = 0; 2027 int fd_data = 0; 2028 int retval; 2029 2030 ccb = cam_getccb(device); 2031 2032 if (ccb == NULL) { 2033 warnx("scsicmd: error allocating ccb"); 2034 return(1); 2035 } 2036 2037 bzero(&(&ccb->ccb_h)[1], 2038 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 2039 2040 while ((c = getopt(argc, argv, combinedopt)) != -1) { 2041 switch(c) { 2042 case 'c': 2043 tstr = optarg; 2044 while (isspace(*tstr) && (*tstr != '\0')) 2045 tstr++; 2046 hook.argc = argc - optind; 2047 hook.argv = argv + optind; 2048 hook.got = 0; 2049 cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr, 2050 iget, &hook); 2051 /* 2052 * Increment optind by the number of arguments the 2053 * encoding routine processed. After each call to 2054 * getopt(3), optind points to the argument that 2055 * getopt should process _next_. In this case, 2056 * that means it points to the first command string 2057 * argument, if there is one. Once we increment 2058 * this, it should point to either the next command 2059 * line argument, or it should be past the end of 2060 * the list. 2061 */ 2062 optind += hook.got; 2063 break; 2064 case 'i': 2065 if (arglist & CAM_ARG_CMD_OUT) { 2066 warnx("command must either be " 2067 "read or write, not both"); 2068 error = 1; 2069 goto scsicmd_bailout; 2070 } 2071 arglist |= CAM_ARG_CMD_IN; 2072 flags = CAM_DIR_IN; 2073 data_bytes = strtol(optarg, NULL, 0); 2074 if (data_bytes <= 0) { 2075 warnx("invalid number of input bytes %d", 2076 data_bytes); 2077 error = 1; 2078 goto scsicmd_bailout; 2079 } 2080 hook.argc = argc - optind; 2081 hook.argv = argv + optind; 2082 hook.got = 0; 2083 optind++; 2084 datastr = cget(&hook, NULL); 2085 /* 2086 * If the user supplied "-" instead of a format, he 2087 * wants the data to be written to stdout. 2088 */ 2089 if ((datastr != NULL) 2090 && (datastr[0] == '-')) 2091 fd_data = 1; 2092 2093 data_ptr = (u_int8_t *)malloc(data_bytes); 2094 if (data_ptr == NULL) { 2095 warnx("can't malloc memory for data_ptr"); 2096 error = 1; 2097 goto scsicmd_bailout; 2098 } 2099 break; 2100 case 'o': 2101 if (arglist & CAM_ARG_CMD_IN) { 2102 warnx("command must either be " 2103 "read or write, not both"); 2104 error = 1; 2105 goto scsicmd_bailout; 2106 } 2107 arglist |= CAM_ARG_CMD_OUT; 2108 flags = CAM_DIR_OUT; 2109 data_bytes = strtol(optarg, NULL, 0); 2110 if (data_bytes <= 0) { 2111 warnx("invalid number of output bytes %d", 2112 data_bytes); 2113 error = 1; 2114 goto scsicmd_bailout; 2115 } 2116 hook.argc = argc - optind; 2117 hook.argv = argv + optind; 2118 hook.got = 0; 2119 datastr = cget(&hook, NULL); 2120 data_ptr = (u_int8_t *)malloc(data_bytes); 2121 if (data_ptr == NULL) { 2122 warnx("can't malloc memory for data_ptr"); 2123 error = 1; 2124 goto scsicmd_bailout; 2125 } 2126 /* 2127 * If the user supplied "-" instead of a format, he 2128 * wants the data to be read from stdin. 2129 */ 2130 if ((datastr != NULL) 2131 && (datastr[0] == '-')) 2132 fd_data = 1; 2133 else 2134 buff_encode_visit(data_ptr, data_bytes, datastr, 2135 iget, &hook); 2136 optind += hook.got; 2137 break; 2138 default: 2139 break; 2140 } 2141 } 2142 2143 /* 2144 * If fd_data is set, and we're writing to the device, we need to 2145 * read the data the user wants written from stdin. 2146 */ 2147 if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) { 2148 ssize_t amt_read; 2149 int amt_to_read = data_bytes; 2150 u_int8_t *buf_ptr = data_ptr; 2151 2152 for (amt_read = 0; amt_to_read > 0; 2153 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) { 2154 if (amt_read == -1) { 2155 warn("error reading data from stdin"); 2156 error = 1; 2157 goto scsicmd_bailout; 2158 } 2159 amt_to_read -= amt_read; 2160 buf_ptr += amt_read; 2161 } 2162 } 2163 2164 if (arglist & CAM_ARG_ERR_RECOVER) 2165 flags |= CAM_PASS_ERR_RECOVER; 2166 2167 /* Disable freezing the device queue */ 2168 flags |= CAM_DEV_QFRZDIS; 2169 2170 /* 2171 * This is taken from the SCSI-3 draft spec. 2172 * (T10/1157D revision 0.3) 2173 * The top 3 bits of an opcode are the group code. The next 5 bits 2174 * are the command code. 2175 * Group 0: six byte commands 2176 * Group 1: ten byte commands 2177 * Group 2: ten byte commands 2178 * Group 3: reserved 2179 * Group 4: sixteen byte commands 2180 * Group 5: twelve byte commands 2181 * Group 6: vendor specific 2182 * Group 7: vendor specific 2183 */ 2184 switch((cdb[0] >> 5) & 0x7) { 2185 case 0: 2186 cdb_len = 6; 2187 break; 2188 case 1: 2189 case 2: 2190 cdb_len = 10; 2191 break; 2192 case 3: 2193 case 6: 2194 case 7: 2195 /* computed by buff_encode_visit */ 2196 break; 2197 case 4: 2198 cdb_len = 16; 2199 break; 2200 case 5: 2201 cdb_len = 12; 2202 break; 2203 } 2204 2205 /* 2206 * We should probably use csio_build_visit or something like that 2207 * here, but it's easier to encode arguments as you go. The 2208 * alternative would be skipping the CDB argument and then encoding 2209 * it here, since we've got the data buffer argument by now. 2210 */ 2211 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len); 2212 2213 cam_fill_csio(&ccb->csio, 2214 /*retries*/ retry_count, 2215 /*cbfcnp*/ NULL, 2216 /*flags*/ flags, 2217 /*tag_action*/ MSG_SIMPLE_Q_TAG, 2218 /*data_ptr*/ data_ptr, 2219 /*dxfer_len*/ data_bytes, 2220 /*sense_len*/ SSD_FULL_SIZE, 2221 /*cdb_len*/ cdb_len, 2222 /*timeout*/ timeout ? timeout : 5000); 2223 2224 if (((retval = cam_send_ccb(device, ccb)) < 0) 2225 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 2226 if (retval < 0) 2227 warn("error sending command"); 2228 else 2229 warnx("error sending command"); 2230 2231 if (arglist & CAM_ARG_VERBOSE) { 2232 cam_error_print(device, ccb, CAM_ESF_ALL, 2233 CAM_EPF_ALL, stderr); 2234 } 2235 2236 error = 1; 2237 goto scsicmd_bailout; 2238 } 2239 2240 2241 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 2242 && (arglist & CAM_ARG_CMD_IN) 2243 && (data_bytes > 0)) { 2244 if (fd_data == 0) { 2245 buff_decode_visit(data_ptr, data_bytes, datastr, 2246 arg_put, NULL); 2247 fprintf(stdout, "\n"); 2248 } else { 2249 ssize_t amt_written; 2250 int amt_to_write = data_bytes; 2251 u_int8_t *buf_ptr = data_ptr; 2252 2253 for (amt_written = 0; (amt_to_write > 0) && 2254 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){ 2255 amt_to_write -= amt_written; 2256 buf_ptr += amt_written; 2257 } 2258 if (amt_written == -1) { 2259 warn("error writing data to stdout"); 2260 error = 1; 2261 goto scsicmd_bailout; 2262 } else if ((amt_written == 0) 2263 && (amt_to_write > 0)) { 2264 warnx("only wrote %u bytes out of %u", 2265 data_bytes - amt_to_write, data_bytes); 2266 } 2267 } 2268 } 2269 2270 scsicmd_bailout: 2271 2272 if ((data_bytes > 0) && (data_ptr != NULL)) 2273 free(data_ptr); 2274 2275 cam_freeccb(ccb); 2276 2277 return(error); 2278 } 2279 2280 static int 2281 camdebug(int argc, char **argv, char *combinedopt) 2282 { 2283 int c, fd; 2284 int bus = -1, target = -1, lun = -1; 2285 char *tstr, *tmpstr = NULL; 2286 union ccb ccb; 2287 int error = 0; 2288 2289 bzero(&ccb, sizeof(union ccb)); 2290 2291 while ((c = getopt(argc, argv, combinedopt)) != -1) { 2292 switch(c) { 2293 case 'I': 2294 arglist |= CAM_ARG_DEBUG_INFO; 2295 ccb.cdbg.flags |= CAM_DEBUG_INFO; 2296 break; 2297 case 'P': 2298 arglist |= CAM_ARG_DEBUG_PERIPH; 2299 ccb.cdbg.flags |= CAM_DEBUG_PERIPH; 2300 break; 2301 case 'S': 2302 arglist |= CAM_ARG_DEBUG_SUBTRACE; 2303 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE; 2304 break; 2305 case 'T': 2306 arglist |= CAM_ARG_DEBUG_TRACE; 2307 ccb.cdbg.flags |= CAM_DEBUG_TRACE; 2308 break; 2309 case 'X': 2310 arglist |= CAM_ARG_DEBUG_XPT; 2311 ccb.cdbg.flags |= CAM_DEBUG_XPT; 2312 break; 2313 case 'c': 2314 arglist |= CAM_ARG_DEBUG_CDB; 2315 ccb.cdbg.flags |= CAM_DEBUG_CDB; 2316 break; 2317 default: 2318 break; 2319 } 2320 } 2321 2322 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { 2323 warnx("error opening transport layer device %s", XPT_DEVICE); 2324 warn("%s", XPT_DEVICE); 2325 return(1); 2326 } 2327 argc -= optind; 2328 argv += optind; 2329 2330 if (argc <= 0) { 2331 warnx("you must specify \"off\", \"all\" or a bus,"); 2332 warnx("bus:target, or bus:target:lun"); 2333 close(fd); 2334 return(1); 2335 } 2336 2337 tstr = *argv; 2338 2339 while (isspace(*tstr) && (*tstr != '\0')) 2340 tstr++; 2341 2342 if (strncmp(tstr, "off", 3) == 0) { 2343 ccb.cdbg.flags = CAM_DEBUG_NONE; 2344 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH| 2345 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE| 2346 CAM_ARG_DEBUG_XPT); 2347 } else if (strncmp(tstr, "all", 3) != 0) { 2348 tmpstr = (char *)strtok(tstr, ":"); 2349 if ((tmpstr != NULL) && (*tmpstr != '\0')){ 2350 bus = strtol(tmpstr, NULL, 0); 2351 arglist |= CAM_ARG_BUS; 2352 tmpstr = (char *)strtok(NULL, ":"); 2353 if ((tmpstr != NULL) && (*tmpstr != '\0')){ 2354 target = strtol(tmpstr, NULL, 0); 2355 arglist |= CAM_ARG_TARGET; 2356 tmpstr = (char *)strtok(NULL, ":"); 2357 if ((tmpstr != NULL) && (*tmpstr != '\0')){ 2358 lun = strtol(tmpstr, NULL, 0); 2359 arglist |= CAM_ARG_LUN; 2360 } 2361 } 2362 } else { 2363 error = 1; 2364 warnx("you must specify \"all\", \"off\", or a bus,"); 2365 warnx("bus:target, or bus:target:lun to debug"); 2366 } 2367 } 2368 2369 if (error == 0) { 2370 2371 ccb.ccb_h.func_code = XPT_DEBUG; 2372 ccb.ccb_h.path_id = bus; 2373 ccb.ccb_h.target_id = target; 2374 ccb.ccb_h.target_lun = lun; 2375 2376 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 2377 warn("CAMIOCOMMAND ioctl failed"); 2378 error = 1; 2379 } 2380 2381 if (error == 0) { 2382 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == 2383 CAM_FUNC_NOTAVAIL) { 2384 warnx("CAM debugging not available"); 2385 warnx("you need to put options CAMDEBUG in" 2386 " your kernel config file!"); 2387 error = 1; 2388 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) != 2389 CAM_REQ_CMP) { 2390 warnx("XPT_DEBUG CCB failed with status %#x", 2391 ccb.ccb_h.status); 2392 error = 1; 2393 } else { 2394 if (ccb.cdbg.flags == CAM_DEBUG_NONE) { 2395 fprintf(stderr, 2396 "Debugging turned off\n"); 2397 } else { 2398 fprintf(stderr, 2399 "Debugging enabled for " 2400 "%d:%d:%d\n", 2401 bus, target, lun); 2402 } 2403 } 2404 } 2405 close(fd); 2406 } 2407 2408 return(error); 2409 } 2410 2411 static int 2412 tagcontrol(struct cam_device *device, int argc, char **argv, 2413 char *combinedopt) 2414 { 2415 int c; 2416 union ccb *ccb; 2417 int numtags = -1; 2418 int retval = 0; 2419 int quiet = 0; 2420 char pathstr[1024]; 2421 2422 ccb = cam_getccb(device); 2423 2424 if (ccb == NULL) { 2425 warnx("tagcontrol: error allocating ccb"); 2426 return(1); 2427 } 2428 2429 while ((c = getopt(argc, argv, combinedopt)) != -1) { 2430 switch(c) { 2431 case 'N': 2432 numtags = strtol(optarg, NULL, 0); 2433 if (numtags < 0) { 2434 warnx("tag count %d is < 0", numtags); 2435 retval = 1; 2436 goto tagcontrol_bailout; 2437 } 2438 break; 2439 case 'q': 2440 quiet++; 2441 break; 2442 default: 2443 break; 2444 } 2445 } 2446 2447 cam_path_string(device, pathstr, sizeof(pathstr)); 2448 2449 if (numtags >= 0) { 2450 bzero(&(&ccb->ccb_h)[1], 2451 sizeof(struct ccb_relsim) - sizeof(struct ccb_hdr)); 2452 ccb->ccb_h.func_code = XPT_REL_SIMQ; 2453 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS; 2454 ccb->crs.openings = numtags; 2455 2456 2457 if (cam_send_ccb(device, ccb) < 0) { 2458 perror("error sending XPT_REL_SIMQ CCB"); 2459 retval = 1; 2460 goto tagcontrol_bailout; 2461 } 2462 2463 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 2464 warnx("XPT_REL_SIMQ CCB failed"); 2465 cam_error_print(device, ccb, CAM_ESF_ALL, 2466 CAM_EPF_ALL, stderr); 2467 retval = 1; 2468 goto tagcontrol_bailout; 2469 } 2470 2471 2472 if (quiet == 0) 2473 fprintf(stdout, "%stagged openings now %d\n", 2474 pathstr, ccb->crs.openings); 2475 } 2476 2477 bzero(&(&ccb->ccb_h)[1], 2478 sizeof(struct ccb_getdevstats) - sizeof(struct ccb_hdr)); 2479 2480 ccb->ccb_h.func_code = XPT_GDEV_STATS; 2481 2482 if (cam_send_ccb(device, ccb) < 0) { 2483 perror("error sending XPT_GDEV_STATS CCB"); 2484 retval = 1; 2485 goto tagcontrol_bailout; 2486 } 2487 2488 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 2489 warnx("XPT_GDEV_STATS CCB failed"); 2490 cam_error_print(device, ccb, CAM_ESF_ALL, 2491 CAM_EPF_ALL, stderr); 2492 retval = 1; 2493 goto tagcontrol_bailout; 2494 } 2495 2496 if (arglist & CAM_ARG_VERBOSE) { 2497 fprintf(stdout, "%s", pathstr); 2498 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings); 2499 fprintf(stdout, "%s", pathstr); 2500 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active); 2501 fprintf(stdout, "%s", pathstr); 2502 fprintf(stdout, "devq_openings %d\n", ccb->cgds.devq_openings); 2503 fprintf(stdout, "%s", pathstr); 2504 fprintf(stdout, "devq_queued %d\n", ccb->cgds.devq_queued); 2505 fprintf(stdout, "%s", pathstr); 2506 fprintf(stdout, "held %d\n", ccb->cgds.held); 2507 fprintf(stdout, "%s", pathstr); 2508 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags); 2509 fprintf(stdout, "%s", pathstr); 2510 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags); 2511 } else { 2512 if (quiet == 0) { 2513 fprintf(stdout, "%s", pathstr); 2514 fprintf(stdout, "device openings: "); 2515 } 2516 fprintf(stdout, "%d\n", ccb->cgds.dev_openings + 2517 ccb->cgds.dev_active); 2518 } 2519 2520 tagcontrol_bailout: 2521 2522 cam_freeccb(ccb); 2523 return(retval); 2524 } 2525 2526 static void 2527 cts_print(struct cam_device *device, struct ccb_trans_settings *cts) 2528 { 2529 char pathstr[1024]; 2530 2531 cam_path_string(device, pathstr, sizeof(pathstr)); 2532 2533 if (cts->transport == XPORT_SPI) { 2534 struct ccb_trans_settings_spi *spi = 2535 &cts->xport_specific.spi; 2536 2537 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { 2538 2539 fprintf(stdout, "%ssync parameter: %d\n", pathstr, 2540 spi->sync_period); 2541 2542 if (spi->sync_offset != 0) { 2543 u_int freq; 2544 2545 freq = scsi_calc_syncsrate(spi->sync_period); 2546 fprintf(stdout, "%sfrequency: %d.%03dMHz\n", 2547 pathstr, freq / 1000, freq % 1000); 2548 } 2549 } 2550 2551 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) { 2552 fprintf(stdout, "%soffset: %d\n", pathstr, 2553 spi->sync_offset); 2554 } 2555 2556 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) { 2557 fprintf(stdout, "%sbus width: %d bits\n", pathstr, 2558 (0x01 << spi->bus_width) * 8); 2559 } 2560 2561 if (spi->valid & CTS_SPI_VALID_DISC) { 2562 fprintf(stdout, "%sdisconnection is %s\n", pathstr, 2563 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ? 2564 "enabled" : "disabled"); 2565 } 2566 } 2567 2568 if (cts->protocol == PROTO_SCSI) { 2569 struct ccb_trans_settings_scsi *scsi= 2570 &cts->proto_specific.scsi; 2571 2572 if (scsi->valid & CTS_SCSI_VALID_TQ) { 2573 fprintf(stdout, "%stagged queueing is %s\n", pathstr, 2574 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ? 2575 "enabled" : "disabled"); 2576 } 2577 } 2578 2579 } 2580 2581 /* 2582 * Get a path inquiry CCB for the specified device. 2583 */ 2584 static int 2585 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi) 2586 { 2587 union ccb *ccb; 2588 int retval = 0; 2589 2590 ccb = cam_getccb(device); 2591 2592 if (ccb == NULL) { 2593 warnx("get_cpi: couldn't allocate CCB"); 2594 return(1); 2595 } 2596 2597 bzero(&(&ccb->ccb_h)[1], 2598 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr)); 2599 2600 ccb->ccb_h.func_code = XPT_PATH_INQ; 2601 2602 if (cam_send_ccb(device, ccb) < 0) { 2603 warn("get_cpi: error sending Path Inquiry CCB"); 2604 2605 if (arglist & CAM_ARG_VERBOSE) 2606 cam_error_print(device, ccb, CAM_ESF_ALL, 2607 CAM_EPF_ALL, stderr); 2608 2609 retval = 1; 2610 2611 goto get_cpi_bailout; 2612 } 2613 2614 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 2615 2616 if (arglist & CAM_ARG_VERBOSE) 2617 cam_error_print(device, ccb, CAM_ESF_ALL, 2618 CAM_EPF_ALL, stderr); 2619 2620 retval = 1; 2621 2622 goto get_cpi_bailout; 2623 } 2624 2625 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq)); 2626 2627 get_cpi_bailout: 2628 2629 cam_freeccb(ccb); 2630 2631 return(retval); 2632 } 2633 2634 static void 2635 cpi_print(struct ccb_pathinq *cpi) 2636 { 2637 char adapter_str[1024]; 2638 int i; 2639 2640 snprintf(adapter_str, sizeof(adapter_str), 2641 "%s%d:", cpi->dev_name, cpi->unit_number); 2642 2643 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str, 2644 cpi->version_num); 2645 2646 for (i = 1; i < 0xff; i = i << 1) { 2647 const char *str; 2648 2649 if ((i & cpi->hba_inquiry) == 0) 2650 continue; 2651 2652 fprintf(stdout, "%s supports ", adapter_str); 2653 2654 switch(i) { 2655 case PI_MDP_ABLE: 2656 str = "MDP message"; 2657 break; 2658 case PI_WIDE_32: 2659 str = "32 bit wide SCSI"; 2660 break; 2661 case PI_WIDE_16: 2662 str = "16 bit wide SCSI"; 2663 break; 2664 case PI_SDTR_ABLE: 2665 str = "SDTR message"; 2666 break; 2667 case PI_LINKED_CDB: 2668 str = "linked CDBs"; 2669 break; 2670 case PI_TAG_ABLE: 2671 str = "tag queue messages"; 2672 break; 2673 case PI_SOFT_RST: 2674 str = "soft reset alternative"; 2675 break; 2676 default: 2677 str = "unknown PI bit set"; 2678 break; 2679 } 2680 fprintf(stdout, "%s\n", str); 2681 } 2682 2683 for (i = 1; i < 0xff; i = i << 1) { 2684 const char *str; 2685 2686 if ((i & cpi->hba_misc) == 0) 2687 continue; 2688 2689 fprintf(stdout, "%s ", adapter_str); 2690 2691 switch(i) { 2692 case PIM_SCANHILO: 2693 str = "bus scans from high ID to low ID"; 2694 break; 2695 case PIM_NOREMOVE: 2696 str = "removable devices not included in scan"; 2697 break; 2698 case PIM_NOINITIATOR: 2699 str = "initiator role not supported"; 2700 break; 2701 case PIM_NOBUSRESET: 2702 str = "user has disabled initial BUS RESET or" 2703 " controller is in target/mixed mode"; 2704 break; 2705 default: 2706 str = "unknown PIM bit set"; 2707 break; 2708 } 2709 fprintf(stdout, "%s\n", str); 2710 } 2711 2712 for (i = 1; i < 0xff; i = i << 1) { 2713 const char *str; 2714 2715 if ((i & cpi->target_sprt) == 0) 2716 continue; 2717 2718 fprintf(stdout, "%s supports ", adapter_str); 2719 switch(i) { 2720 case PIT_PROCESSOR: 2721 str = "target mode processor mode"; 2722 break; 2723 case PIT_PHASE: 2724 str = "target mode phase cog. mode"; 2725 break; 2726 case PIT_DISCONNECT: 2727 str = "disconnects in target mode"; 2728 break; 2729 case PIT_TERM_IO: 2730 str = "terminate I/O message in target mode"; 2731 break; 2732 case PIT_GRP_6: 2733 str = "group 6 commands in target mode"; 2734 break; 2735 case PIT_GRP_7: 2736 str = "group 7 commands in target mode"; 2737 break; 2738 default: 2739 str = "unknown PIT bit set"; 2740 break; 2741 } 2742 2743 fprintf(stdout, "%s\n", str); 2744 } 2745 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str, 2746 cpi->hba_eng_cnt); 2747 fprintf(stdout, "%s maximum target: %d\n", adapter_str, 2748 cpi->max_target); 2749 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str, 2750 cpi->max_lun); 2751 fprintf(stdout, "%s highest path ID in subsystem: %d\n", 2752 adapter_str, cpi->hpath_id); 2753 fprintf(stdout, "%s initiator ID: %d\n", adapter_str, 2754 cpi->initiator_id); 2755 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid); 2756 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid); 2757 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id); 2758 fprintf(stdout, "%s base transfer speed: ", adapter_str); 2759 if (cpi->base_transfer_speed > 1000) 2760 fprintf(stdout, "%d.%03dMB/sec\n", 2761 cpi->base_transfer_speed / 1000, 2762 cpi->base_transfer_speed % 1000); 2763 else 2764 fprintf(stdout, "%dKB/sec\n", 2765 (cpi->base_transfer_speed % 1000) * 1000); 2766 } 2767 2768 static int 2769 get_print_cts(struct cam_device *device, int user_settings, int quiet, 2770 struct ccb_trans_settings *cts) 2771 { 2772 int retval; 2773 union ccb *ccb; 2774 2775 retval = 0; 2776 ccb = cam_getccb(device); 2777 2778 if (ccb == NULL) { 2779 warnx("get_print_cts: error allocating ccb"); 2780 return(1); 2781 } 2782 2783 bzero(&(&ccb->ccb_h)[1], 2784 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr)); 2785 2786 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 2787 2788 if (user_settings == 0) 2789 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS; 2790 else 2791 ccb->cts.type = CTS_TYPE_USER_SETTINGS; 2792 2793 if (cam_send_ccb(device, ccb) < 0) { 2794 perror("error sending XPT_GET_TRAN_SETTINGS CCB"); 2795 if (arglist & CAM_ARG_VERBOSE) 2796 cam_error_print(device, ccb, CAM_ESF_ALL, 2797 CAM_EPF_ALL, stderr); 2798 retval = 1; 2799 goto get_print_cts_bailout; 2800 } 2801 2802 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 2803 warnx("XPT_GET_TRANS_SETTINGS CCB failed"); 2804 if (arglist & CAM_ARG_VERBOSE) 2805 cam_error_print(device, ccb, CAM_ESF_ALL, 2806 CAM_EPF_ALL, stderr); 2807 retval = 1; 2808 goto get_print_cts_bailout; 2809 } 2810 2811 if (quiet == 0) 2812 cts_print(device, &ccb->cts); 2813 2814 if (cts != NULL) 2815 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings)); 2816 2817 get_print_cts_bailout: 2818 2819 cam_freeccb(ccb); 2820 2821 return(retval); 2822 } 2823 2824 static int 2825 ratecontrol(struct cam_device *device, int retry_count, int timeout, 2826 int argc, char **argv, char *combinedopt) 2827 { 2828 int c; 2829 union ccb *ccb; 2830 int user_settings = 0; 2831 int retval = 0; 2832 int disc_enable = -1, tag_enable = -1; 2833 int offset = -1; 2834 double syncrate = -1; 2835 int bus_width = -1; 2836 int quiet = 0; 2837 int change_settings = 0, send_tur = 0; 2838 struct ccb_pathinq cpi; 2839 2840 ccb = cam_getccb(device); 2841 2842 if (ccb == NULL) { 2843 warnx("ratecontrol: error allocating ccb"); 2844 return(1); 2845 } 2846 2847 while ((c = getopt(argc, argv, combinedopt)) != -1) { 2848 switch(c){ 2849 case 'a': 2850 send_tur = 1; 2851 break; 2852 case 'c': 2853 user_settings = 0; 2854 break; 2855 case 'D': 2856 if (strncasecmp(optarg, "enable", 6) == 0) 2857 disc_enable = 1; 2858 else if (strncasecmp(optarg, "disable", 7) == 0) 2859 disc_enable = 0; 2860 else { 2861 warnx("-D argument \"%s\" is unknown", optarg); 2862 retval = 1; 2863 goto ratecontrol_bailout; 2864 } 2865 change_settings = 1; 2866 break; 2867 case 'O': 2868 offset = strtol(optarg, NULL, 0); 2869 if (offset < 0) { 2870 warnx("offset value %d is < 0", offset); 2871 retval = 1; 2872 goto ratecontrol_bailout; 2873 } 2874 change_settings = 1; 2875 break; 2876 case 'q': 2877 quiet++; 2878 break; 2879 case 'R': 2880 syncrate = atof(optarg); 2881 2882 if (syncrate < 0) { 2883 warnx("sync rate %f is < 0", syncrate); 2884 retval = 1; 2885 goto ratecontrol_bailout; 2886 } 2887 change_settings = 1; 2888 break; 2889 case 'T': 2890 if (strncasecmp(optarg, "enable", 6) == 0) 2891 tag_enable = 1; 2892 else if (strncasecmp(optarg, "disable", 7) == 0) 2893 tag_enable = 0; 2894 else { 2895 warnx("-T argument \"%s\" is unknown", optarg); 2896 retval = 1; 2897 goto ratecontrol_bailout; 2898 } 2899 change_settings = 1; 2900 break; 2901 case 'U': 2902 user_settings = 1; 2903 break; 2904 case 'W': 2905 bus_width = strtol(optarg, NULL, 0); 2906 if (bus_width < 0) { 2907 warnx("bus width %d is < 0", bus_width); 2908 retval = 1; 2909 goto ratecontrol_bailout; 2910 } 2911 change_settings = 1; 2912 break; 2913 default: 2914 break; 2915 } 2916 } 2917 2918 bzero(&(&ccb->ccb_h)[1], 2919 sizeof(struct ccb_pathinq) - sizeof(struct ccb_hdr)); 2920 2921 /* 2922 * Grab path inquiry information, so we can determine whether 2923 * or not the initiator is capable of the things that the user 2924 * requests. 2925 */ 2926 ccb->ccb_h.func_code = XPT_PATH_INQ; 2927 2928 if (cam_send_ccb(device, ccb) < 0) { 2929 perror("error sending XPT_PATH_INQ CCB"); 2930 if (arglist & CAM_ARG_VERBOSE) { 2931 cam_error_print(device, ccb, CAM_ESF_ALL, 2932 CAM_EPF_ALL, stderr); 2933 } 2934 retval = 1; 2935 goto ratecontrol_bailout; 2936 } 2937 2938 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 2939 warnx("XPT_PATH_INQ CCB failed"); 2940 if (arglist & CAM_ARG_VERBOSE) { 2941 cam_error_print(device, ccb, CAM_ESF_ALL, 2942 CAM_EPF_ALL, stderr); 2943 } 2944 retval = 1; 2945 goto ratecontrol_bailout; 2946 } 2947 2948 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq)); 2949 2950 bzero(&(&ccb->ccb_h)[1], 2951 sizeof(struct ccb_trans_settings) - sizeof(struct ccb_hdr)); 2952 2953 if (quiet == 0) 2954 fprintf(stdout, "Current Parameters:\n"); 2955 2956 retval = get_print_cts(device, user_settings, quiet, &ccb->cts); 2957 2958 if (retval != 0) 2959 goto ratecontrol_bailout; 2960 2961 if (arglist & CAM_ARG_VERBOSE) 2962 cpi_print(&cpi); 2963 2964 if (change_settings) { 2965 int didsettings = 0; 2966 struct ccb_trans_settings_spi *spi = NULL; 2967 struct ccb_trans_settings_scsi *scsi = NULL; 2968 2969 if (ccb->cts.transport == XPORT_SPI) { 2970 spi = &ccb->cts.xport_specific.spi; 2971 spi->valid = 0; 2972 } 2973 if (ccb->cts.protocol == PROTO_SCSI) { 2974 scsi = &ccb->cts.proto_specific.scsi; 2975 scsi->valid = 0; 2976 } 2977 if (spi && disc_enable != -1) { 2978 spi->valid |= CTS_SPI_VALID_DISC; 2979 if (disc_enable == 0) 2980 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 2981 else 2982 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 2983 } 2984 2985 if (scsi && tag_enable != -1) { 2986 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) { 2987 warnx("HBA does not support tagged queueing, " 2988 "so you cannot modify tag settings"); 2989 retval = 1; 2990 goto ratecontrol_bailout; 2991 } 2992 2993 scsi->valid |= CTS_SCSI_VALID_TQ; 2994 2995 if (tag_enable == 0) 2996 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 2997 else 2998 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 2999 didsettings++; 3000 } 3001 3002 if (spi && offset != -1) { 3003 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 3004 warnx("HBA at %s%d is not cable of changing " 3005 "offset", cpi.dev_name, 3006 cpi.unit_number); 3007 retval = 1; 3008 goto ratecontrol_bailout; 3009 } 3010 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 3011 spi->sync_offset = offset; 3012 didsettings++; 3013 } 3014 3015 if (spi && syncrate != -1) { 3016 int prelim_sync_period; 3017 u_int freq; 3018 3019 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 3020 warnx("HBA at %s%d is not cable of changing " 3021 "transfer rates", cpi.dev_name, 3022 cpi.unit_number); 3023 retval = 1; 3024 goto ratecontrol_bailout; 3025 } 3026 3027 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 3028 3029 /* 3030 * The sync rate the user gives us is in MHz. 3031 * We need to translate it into KHz for this 3032 * calculation. 3033 */ 3034 syncrate *= 1000; 3035 3036 /* 3037 * Next, we calculate a "preliminary" sync period 3038 * in tenths of a nanosecond. 3039 */ 3040 if (syncrate == 0) 3041 prelim_sync_period = 0; 3042 else 3043 prelim_sync_period = 10000000 / syncrate; 3044 3045 spi->sync_period = 3046 scsi_calc_syncparam(prelim_sync_period); 3047 3048 freq = scsi_calc_syncsrate(spi->sync_period); 3049 didsettings++; 3050 } 3051 3052 /* 3053 * The bus_width argument goes like this: 3054 * 0 == 8 bit 3055 * 1 == 16 bit 3056 * 2 == 32 bit 3057 * Therefore, if you shift the number of bits given on the 3058 * command line right by 4, you should get the correct 3059 * number. 3060 */ 3061 if (spi && bus_width != -1) { 3062 3063 /* 3064 * We might as well validate things here with a 3065 * decipherable error message, rather than what 3066 * will probably be an indecipherable error message 3067 * by the time it gets back to us. 3068 */ 3069 if ((bus_width == 16) 3070 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) { 3071 warnx("HBA does not support 16 bit bus width"); 3072 retval = 1; 3073 goto ratecontrol_bailout; 3074 } else if ((bus_width == 32) 3075 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) { 3076 warnx("HBA does not support 32 bit bus width"); 3077 retval = 1; 3078 goto ratecontrol_bailout; 3079 } else if ((bus_width != 8) 3080 && (bus_width != 16) 3081 && (bus_width != 32)) { 3082 warnx("Invalid bus width %d", bus_width); 3083 retval = 1; 3084 goto ratecontrol_bailout; 3085 } 3086 3087 spi->valid |= CTS_SPI_VALID_BUS_WIDTH; 3088 spi->bus_width = bus_width >> 4; 3089 didsettings++; 3090 } 3091 3092 if (didsettings == 0) { 3093 goto ratecontrol_bailout; 3094 } 3095 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 3096 3097 if (cam_send_ccb(device, ccb) < 0) { 3098 perror("error sending XPT_SET_TRAN_SETTINGS CCB"); 3099 if (arglist & CAM_ARG_VERBOSE) { 3100 cam_error_print(device, ccb, CAM_ESF_ALL, 3101 CAM_EPF_ALL, stderr); 3102 } 3103 retval = 1; 3104 goto ratecontrol_bailout; 3105 } 3106 3107 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 3108 warnx("XPT_SET_TRANS_SETTINGS CCB failed"); 3109 if (arglist & CAM_ARG_VERBOSE) { 3110 cam_error_print(device, ccb, CAM_ESF_ALL, 3111 CAM_EPF_ALL, stderr); 3112 } 3113 retval = 1; 3114 goto ratecontrol_bailout; 3115 } 3116 } 3117 3118 if (send_tur) { 3119 retval = testunitready(device, retry_count, timeout, 3120 (arglist & CAM_ARG_VERBOSE) ? 0 : 1); 3121 3122 /* 3123 * If the TUR didn't succeed, just bail. 3124 */ 3125 if (retval != 0) { 3126 if (quiet == 0) 3127 fprintf(stderr, "Test Unit Ready failed\n"); 3128 goto ratecontrol_bailout; 3129 } 3130 3131 /* 3132 * If the user wants things quiet, there's no sense in 3133 * getting the transfer settings, if we're not going 3134 * to print them. 3135 */ 3136 if (quiet != 0) 3137 goto ratecontrol_bailout; 3138 3139 fprintf(stdout, "New Parameters:\n"); 3140 retval = get_print_cts(device, user_settings, 0, NULL); 3141 } 3142 3143 ratecontrol_bailout: 3144 3145 cam_freeccb(ccb); 3146 return(retval); 3147 } 3148 3149 static int 3150 scsiformat(struct cam_device *device, int argc, char **argv, 3151 char *combinedopt, int retry_count, int timeout) 3152 { 3153 union ccb *ccb; 3154 int c; 3155 int ycount = 0, quiet = 0; 3156 int error = 0, response = 0, retval = 0; 3157 int use_timeout = 10800 * 1000; 3158 int immediate = 1; 3159 struct format_defect_list_header fh; 3160 u_int8_t *data_ptr = NULL; 3161 u_int32_t dxfer_len = 0; 3162 u_int8_t byte2 = 0; 3163 int num_warnings = 0; 3164 int reportonly = 0; 3165 3166 ccb = cam_getccb(device); 3167 3168 if (ccb == NULL) { 3169 warnx("scsiformat: error allocating ccb"); 3170 return(1); 3171 } 3172 3173 bzero(&(&ccb->ccb_h)[1], 3174 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 3175 3176 while ((c = getopt(argc, argv, combinedopt)) != -1) { 3177 switch(c) { 3178 case 'q': 3179 quiet++; 3180 break; 3181 case 'r': 3182 reportonly = 1; 3183 break; 3184 case 'w': 3185 immediate = 0; 3186 break; 3187 case 'y': 3188 ycount++; 3189 break; 3190 } 3191 } 3192 3193 if (reportonly) 3194 goto doreport; 3195 3196 if (quiet == 0) { 3197 fprintf(stdout, "You are about to REMOVE ALL DATA from the " 3198 "following device:\n"); 3199 3200 error = scsidoinquiry(device, argc, argv, combinedopt, 3201 retry_count, timeout); 3202 3203 if (error != 0) { 3204 warnx("scsiformat: error sending inquiry"); 3205 goto scsiformat_bailout; 3206 } 3207 } 3208 3209 if (ycount == 0) { 3210 3211 do { 3212 char str[1024]; 3213 3214 fprintf(stdout, "Are you SURE you want to do " 3215 "this? (yes/no) "); 3216 3217 if (fgets(str, sizeof(str), stdin) != NULL) { 3218 3219 if (strncasecmp(str, "yes", 3) == 0) 3220 response = 1; 3221 else if (strncasecmp(str, "no", 2) == 0) 3222 response = -1; 3223 else { 3224 fprintf(stdout, "Please answer" 3225 " \"yes\" or \"no\"\n"); 3226 } 3227 } 3228 } while (response == 0); 3229 3230 if (response == -1) { 3231 error = 1; 3232 goto scsiformat_bailout; 3233 } 3234 } 3235 3236 if (timeout != 0) 3237 use_timeout = timeout; 3238 3239 if (quiet == 0) { 3240 fprintf(stdout, "Current format timeout is %d seconds\n", 3241 use_timeout / 1000); 3242 } 3243 3244 /* 3245 * If the user hasn't disabled questions and didn't specify a 3246 * timeout on the command line, ask them if they want the current 3247 * timeout. 3248 */ 3249 if ((ycount == 0) 3250 && (timeout == 0)) { 3251 char str[1024]; 3252 int new_timeout = 0; 3253 3254 fprintf(stdout, "Enter new timeout in seconds or press\n" 3255 "return to keep the current timeout [%d] ", 3256 use_timeout / 1000); 3257 3258 if (fgets(str, sizeof(str), stdin) != NULL) { 3259 if (str[0] != '\0') 3260 new_timeout = atoi(str); 3261 } 3262 3263 if (new_timeout != 0) { 3264 use_timeout = new_timeout * 1000; 3265 fprintf(stdout, "Using new timeout value %d\n", 3266 use_timeout / 1000); 3267 } 3268 } 3269 3270 /* 3271 * Keep this outside the if block below to silence any unused 3272 * variable warnings. 3273 */ 3274 bzero(&fh, sizeof(fh)); 3275 3276 /* 3277 * If we're in immediate mode, we've got to include the format 3278 * header 3279 */ 3280 if (immediate != 0) { 3281 fh.byte2 = FU_DLH_IMMED; 3282 data_ptr = (u_int8_t *)&fh; 3283 dxfer_len = sizeof(fh); 3284 byte2 = FU_FMT_DATA; 3285 } else if (quiet == 0) { 3286 fprintf(stdout, "Formatting..."); 3287 fflush(stdout); 3288 } 3289 3290 scsi_format_unit(&ccb->csio, 3291 /* retries */ retry_count, 3292 /* cbfcnp */ NULL, 3293 /* tag_action */ MSG_SIMPLE_Q_TAG, 3294 /* byte2 */ byte2, 3295 /* ileave */ 0, 3296 /* data_ptr */ data_ptr, 3297 /* dxfer_len */ dxfer_len, 3298 /* sense_len */ SSD_FULL_SIZE, 3299 /* timeout */ use_timeout); 3300 3301 /* Disable freezing the device queue */ 3302 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 3303 3304 if (arglist & CAM_ARG_ERR_RECOVER) 3305 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 3306 3307 if (((retval = cam_send_ccb(device, ccb)) < 0) 3308 || ((immediate == 0) 3309 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) { 3310 const char errstr[] = "error sending format command"; 3311 3312 if (retval < 0) 3313 warn(errstr); 3314 else 3315 warnx(errstr); 3316 3317 if (arglist & CAM_ARG_VERBOSE) { 3318 cam_error_print(device, ccb, CAM_ESF_ALL, 3319 CAM_EPF_ALL, stderr); 3320 } 3321 error = 1; 3322 goto scsiformat_bailout; 3323 } 3324 3325 /* 3326 * If we ran in non-immediate mode, we already checked for errors 3327 * above and printed out any necessary information. If we're in 3328 * immediate mode, we need to loop through and get status 3329 * information periodically. 3330 */ 3331 if (immediate == 0) { 3332 if (quiet == 0) { 3333 fprintf(stdout, "Format Complete\n"); 3334 } 3335 goto scsiformat_bailout; 3336 } 3337 3338 doreport: 3339 do { 3340 cam_status status; 3341 3342 bzero(&(&ccb->ccb_h)[1], 3343 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 3344 3345 /* 3346 * There's really no need to do error recovery or 3347 * retries here, since we're just going to sit in a 3348 * loop and wait for the device to finish formatting. 3349 */ 3350 scsi_test_unit_ready(&ccb->csio, 3351 /* retries */ 0, 3352 /* cbfcnp */ NULL, 3353 /* tag_action */ MSG_SIMPLE_Q_TAG, 3354 /* sense_len */ SSD_FULL_SIZE, 3355 /* timeout */ 5000); 3356 3357 /* Disable freezing the device queue */ 3358 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 3359 3360 retval = cam_send_ccb(device, ccb); 3361 3362 /* 3363 * If we get an error from the ioctl, bail out. SCSI 3364 * errors are expected. 3365 */ 3366 if (retval < 0) { 3367 warn("error sending CAMIOCOMMAND ioctl"); 3368 if (arglist & CAM_ARG_VERBOSE) { 3369 cam_error_print(device, ccb, CAM_ESF_ALL, 3370 CAM_EPF_ALL, stderr); 3371 } 3372 error = 1; 3373 goto scsiformat_bailout; 3374 } 3375 3376 status = ccb->ccb_h.status & CAM_STATUS_MASK; 3377 3378 if ((status != CAM_REQ_CMP) 3379 && (status == CAM_SCSI_STATUS_ERROR) 3380 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 3381 struct scsi_sense_data *sense; 3382 int error_code, sense_key, asc, ascq; 3383 3384 sense = &ccb->csio.sense_data; 3385 scsi_extract_sense(sense, &error_code, &sense_key, 3386 &asc, &ascq); 3387 3388 /* 3389 * According to the SCSI-2 and SCSI-3 specs, a 3390 * drive that is in the middle of a format should 3391 * return NOT READY with an ASC of "logical unit 3392 * not ready, format in progress". The sense key 3393 * specific bytes will then be a progress indicator. 3394 */ 3395 if ((sense_key == SSD_KEY_NOT_READY) 3396 && (asc == 0x04) && (ascq == 0x04)) { 3397 if ((sense->extra_len >= 10) 3398 && ((sense->sense_key_spec[0] & 3399 SSD_SCS_VALID) != 0) 3400 && (quiet == 0)) { 3401 int val; 3402 u_int64_t percentage; 3403 3404 val = scsi_2btoul( 3405 &sense->sense_key_spec[1]); 3406 percentage = 10000 * val; 3407 3408 fprintf(stdout, 3409 "\rFormatting: %ju.%02u %% " 3410 "(%d/%d) done", 3411 (uintmax_t)(percentage / 3412 (0x10000 * 100)), 3413 (unsigned)((percentage / 3414 0x10000) % 100), 3415 val, 0x10000); 3416 fflush(stdout); 3417 } else if ((quiet == 0) 3418 && (++num_warnings <= 1)) { 3419 warnx("Unexpected SCSI Sense Key " 3420 "Specific value returned " 3421 "during format:"); 3422 scsi_sense_print(device, &ccb->csio, 3423 stderr); 3424 warnx("Unable to print status " 3425 "information, but format will " 3426 "proceed."); 3427 warnx("will exit when format is " 3428 "complete"); 3429 } 3430 sleep(1); 3431 } else { 3432 warnx("Unexpected SCSI error during format"); 3433 cam_error_print(device, ccb, CAM_ESF_ALL, 3434 CAM_EPF_ALL, stderr); 3435 error = 1; 3436 goto scsiformat_bailout; 3437 } 3438 3439 } else if (status != CAM_REQ_CMP) { 3440 warnx("Unexpected CAM status %#x", status); 3441 if (arglist & CAM_ARG_VERBOSE) 3442 cam_error_print(device, ccb, CAM_ESF_ALL, 3443 CAM_EPF_ALL, stderr); 3444 error = 1; 3445 goto scsiformat_bailout; 3446 } 3447 3448 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); 3449 3450 if (quiet == 0) 3451 fprintf(stdout, "\nFormat Complete\n"); 3452 3453 scsiformat_bailout: 3454 3455 cam_freeccb(ccb); 3456 3457 return(error); 3458 } 3459 3460 static int 3461 scsireportluns(struct cam_device *device, int argc, char **argv, 3462 char *combinedopt, int retry_count, int timeout) 3463 { 3464 union ccb *ccb; 3465 int c, countonly, lunsonly; 3466 struct scsi_report_luns_data *lundata; 3467 int alloc_len; 3468 uint8_t report_type; 3469 uint32_t list_len, i, j; 3470 int retval; 3471 3472 retval = 0; 3473 lundata = NULL; 3474 report_type = RPL_REPORT_DEFAULT; 3475 ccb = cam_getccb(device); 3476 3477 if (ccb == NULL) { 3478 warnx("%s: error allocating ccb", __func__); 3479 return (1); 3480 } 3481 3482 bzero(&(&ccb->ccb_h)[1], 3483 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 3484 3485 countonly = 0; 3486 lunsonly = 0; 3487 3488 while ((c = getopt(argc, argv, combinedopt)) != -1) { 3489 switch (c) { 3490 case 'c': 3491 countonly++; 3492 break; 3493 case 'l': 3494 lunsonly++; 3495 break; 3496 case 'r': 3497 if (strcasecmp(optarg, "default") == 0) 3498 report_type = RPL_REPORT_DEFAULT; 3499 else if (strcasecmp(optarg, "wellknown") == 0) 3500 report_type = RPL_REPORT_WELLKNOWN; 3501 else if (strcasecmp(optarg, "all") == 0) 3502 report_type = RPL_REPORT_ALL; 3503 else { 3504 warnx("%s: invalid report type \"%s\"", 3505 __func__, optarg); 3506 retval = 1; 3507 goto bailout; 3508 } 3509 break; 3510 default: 3511 break; 3512 } 3513 } 3514 3515 if ((countonly != 0) 3516 && (lunsonly != 0)) { 3517 warnx("%s: you can only specify one of -c or -l", __func__); 3518 retval = 1; 3519 goto bailout; 3520 } 3521 /* 3522 * According to SPC-4, the allocation length must be at least 16 3523 * bytes -- enough for the header and one LUN. 3524 */ 3525 alloc_len = sizeof(*lundata) + 8; 3526 3527 retry: 3528 3529 lundata = malloc(alloc_len); 3530 3531 if (lundata == NULL) { 3532 warn("%s: error mallocing %d bytes", __func__, alloc_len); 3533 retval = 1; 3534 goto bailout; 3535 } 3536 3537 scsi_report_luns(&ccb->csio, 3538 /*retries*/ retry_count, 3539 /*cbfcnp*/ NULL, 3540 /*tag_action*/ MSG_SIMPLE_Q_TAG, 3541 /*select_report*/ report_type, 3542 /*rpl_buf*/ lundata, 3543 /*alloc_len*/ alloc_len, 3544 /*sense_len*/ SSD_FULL_SIZE, 3545 /*timeout*/ timeout ? timeout : 5000); 3546 3547 /* Disable freezing the device queue */ 3548 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 3549 3550 if (arglist & CAM_ARG_ERR_RECOVER) 3551 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 3552 3553 if (cam_send_ccb(device, ccb) < 0) { 3554 warn("error sending REPORT LUNS command"); 3555 3556 if (arglist & CAM_ARG_VERBOSE) 3557 cam_error_print(device, ccb, CAM_ESF_ALL, 3558 CAM_EPF_ALL, stderr); 3559 3560 retval = 1; 3561 goto bailout; 3562 } 3563 3564 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 3565 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 3566 retval = 1; 3567 goto bailout; 3568 } 3569 3570 3571 list_len = scsi_4btoul(lundata->length); 3572 3573 /* 3574 * If we need to list the LUNs, and our allocation 3575 * length was too short, reallocate and retry. 3576 */ 3577 if ((countonly == 0) 3578 && (list_len > (alloc_len - sizeof(*lundata)))) { 3579 alloc_len = list_len + sizeof(*lundata); 3580 free(lundata); 3581 goto retry; 3582 } 3583 3584 if (lunsonly == 0) 3585 fprintf(stdout, "%u LUN%s found\n", list_len / 8, 3586 ((list_len / 8) > 1) ? "s" : ""); 3587 3588 if (countonly != 0) 3589 goto bailout; 3590 3591 for (i = 0; i < (list_len / 8); i++) { 3592 int no_more; 3593 3594 no_more = 0; 3595 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) { 3596 if (j != 0) 3597 fprintf(stdout, ","); 3598 switch (lundata->luns[i].lundata[j] & 3599 RPL_LUNDATA_ATYP_MASK) { 3600 case RPL_LUNDATA_ATYP_PERIPH: 3601 if ((lundata->luns[i].lundata[j] & 3602 RPL_LUNDATA_PERIPH_BUS_MASK) != 0) 3603 fprintf(stdout, "%d:", 3604 lundata->luns[i].lundata[j] & 3605 RPL_LUNDATA_PERIPH_BUS_MASK); 3606 else if ((j == 0) 3607 && ((lundata->luns[i].lundata[j+2] & 3608 RPL_LUNDATA_PERIPH_BUS_MASK) == 0)) 3609 no_more = 1; 3610 3611 fprintf(stdout, "%d", 3612 lundata->luns[i].lundata[j+1]); 3613 break; 3614 case RPL_LUNDATA_ATYP_FLAT: { 3615 uint8_t tmplun[2]; 3616 tmplun[0] = lundata->luns[i].lundata[j] & 3617 RPL_LUNDATA_FLAT_LUN_MASK; 3618 tmplun[1] = lundata->luns[i].lundata[j+1]; 3619 3620 fprintf(stdout, "%d", scsi_2btoul(tmplun)); 3621 no_more = 1; 3622 break; 3623 } 3624 case RPL_LUNDATA_ATYP_LUN: 3625 fprintf(stdout, "%d:%d:%d", 3626 (lundata->luns[i].lundata[j+1] & 3627 RPL_LUNDATA_LUN_BUS_MASK) >> 5, 3628 lundata->luns[i].lundata[j] & 3629 RPL_LUNDATA_LUN_TARG_MASK, 3630 lundata->luns[i].lundata[j+1] & 3631 RPL_LUNDATA_LUN_LUN_MASK); 3632 break; 3633 case RPL_LUNDATA_ATYP_EXTLUN: { 3634 int field_len, field_len_code, eam_code; 3635 3636 eam_code = lundata->luns[i].lundata[j] & 3637 RPL_LUNDATA_EXT_EAM_MASK; 3638 field_len_code = (lundata->luns[i].lundata[j] & 3639 RPL_LUNDATA_EXT_LEN_MASK) >> 4; 3640 field_len = field_len_code * 2; 3641 3642 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK) 3643 && (field_len_code == 0x00)) { 3644 fprintf(stdout, "%d", 3645 lundata->luns[i].lundata[j+1]); 3646 } else if ((eam_code == 3647 RPL_LUNDATA_EXT_EAM_NOT_SPEC) 3648 && (field_len_code == 0x03)) { 3649 uint8_t tmp_lun[8]; 3650 3651 /* 3652 * This format takes up all 8 bytes. 3653 * If we aren't starting at offset 0, 3654 * that's a bug. 3655 */ 3656 if (j != 0) { 3657 fprintf(stdout, "Invalid " 3658 "offset %d for " 3659 "Extended LUN not " 3660 "specified format", j); 3661 no_more = 1; 3662 break; 3663 } 3664 bzero(tmp_lun, sizeof(tmp_lun)); 3665 bcopy(&lundata->luns[i].lundata[j+1], 3666 &tmp_lun[1], sizeof(tmp_lun) - 1); 3667 fprintf(stdout, "%#jx", 3668 (intmax_t)scsi_8btou64(tmp_lun)); 3669 no_more = 1; 3670 } else { 3671 fprintf(stderr, "Unknown Extended LUN" 3672 "Address method %#x, length " 3673 "code %#x", eam_code, 3674 field_len_code); 3675 no_more = 1; 3676 } 3677 break; 3678 } 3679 default: 3680 fprintf(stderr, "Unknown LUN address method " 3681 "%#x\n", lundata->luns[i].lundata[0] & 3682 RPL_LUNDATA_ATYP_MASK); 3683 break; 3684 } 3685 /* 3686 * For the flat addressing method, there are no 3687 * other levels after it. 3688 */ 3689 if (no_more != 0) 3690 break; 3691 } 3692 fprintf(stdout, "\n"); 3693 } 3694 3695 bailout: 3696 3697 cam_freeccb(ccb); 3698 3699 free(lundata); 3700 3701 return (retval); 3702 } 3703 3704 static int 3705 scsireadcapacity(struct cam_device *device, int argc, char **argv, 3706 char *combinedopt, int retry_count, int timeout) 3707 { 3708 union ccb *ccb; 3709 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten; 3710 struct scsi_read_capacity_data rcap; 3711 struct scsi_read_capacity_data_long rcaplong; 3712 uint64_t maxsector; 3713 uint32_t block_len; 3714 int retval; 3715 int c; 3716 3717 blocksizeonly = 0; 3718 humanize = 0; 3719 numblocks = 0; 3720 quiet = 0; 3721 sizeonly = 0; 3722 baseten = 0; 3723 retval = 0; 3724 3725 ccb = cam_getccb(device); 3726 3727 if (ccb == NULL) { 3728 warnx("%s: error allocating ccb", __func__); 3729 return (1); 3730 } 3731 3732 bzero(&(&ccb->ccb_h)[1], 3733 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); 3734 3735 while ((c = getopt(argc, argv, combinedopt)) != -1) { 3736 switch (c) { 3737 case 'b': 3738 blocksizeonly++; 3739 break; 3740 case 'h': 3741 humanize++; 3742 baseten = 0; 3743 break; 3744 case 'H': 3745 humanize++; 3746 baseten++; 3747 break; 3748 case 'N': 3749 numblocks++; 3750 break; 3751 case 'q': 3752 quiet++; 3753 break; 3754 case 's': 3755 sizeonly++; 3756 break; 3757 default: 3758 break; 3759 } 3760 } 3761 3762 if ((blocksizeonly != 0) 3763 && (numblocks != 0)) { 3764 warnx("%s: you can only specify one of -b or -N", __func__); 3765 retval = 1; 3766 goto bailout; 3767 } 3768 3769 if ((blocksizeonly != 0) 3770 && (sizeonly != 0)) { 3771 warnx("%s: you can only specify one of -b or -s", __func__); 3772 retval = 1; 3773 goto bailout; 3774 } 3775 3776 if ((humanize != 0) 3777 && (quiet != 0)) { 3778 warnx("%s: you can only specify one of -h/-H or -q", __func__); 3779 retval = 1; 3780 goto bailout; 3781 } 3782 3783 if ((humanize != 0) 3784 && (blocksizeonly != 0)) { 3785 warnx("%s: you can only specify one of -h/-H or -b", __func__); 3786 retval = 1; 3787 goto bailout; 3788 } 3789 3790 scsi_read_capacity(&ccb->csio, 3791 /*retries*/ retry_count, 3792 /*cbfcnp*/ NULL, 3793 /*tag_action*/ MSG_SIMPLE_Q_TAG, 3794 &rcap, 3795 SSD_FULL_SIZE, 3796 /*timeout*/ timeout ? timeout : 5000); 3797 3798 /* Disable freezing the device queue */ 3799 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 3800 3801 if (arglist & CAM_ARG_ERR_RECOVER) 3802 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 3803 3804 if (cam_send_ccb(device, ccb) < 0) { 3805 warn("error sending READ CAPACITY command"); 3806 3807 if (arglist & CAM_ARG_VERBOSE) 3808 cam_error_print(device, ccb, CAM_ESF_ALL, 3809 CAM_EPF_ALL, stderr); 3810 3811 retval = 1; 3812 goto bailout; 3813 } 3814 3815 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 3816 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 3817 retval = 1; 3818 goto bailout; 3819 } 3820 3821 maxsector = scsi_4btoul(rcap.addr); 3822 block_len = scsi_4btoul(rcap.length); 3823 3824 /* 3825 * A last block of 2^32-1 means that the true capacity is over 2TB, 3826 * and we need to issue the long READ CAPACITY to get the real 3827 * capacity. Otherwise, we're all set. 3828 */ 3829 if (maxsector != 0xffffffff) 3830 goto do_print; 3831 3832 scsi_read_capacity_16(&ccb->csio, 3833 /*retries*/ retry_count, 3834 /*cbfcnp*/ NULL, 3835 /*tag_action*/ MSG_SIMPLE_Q_TAG, 3836 /*lba*/ 0, 3837 /*reladdr*/ 0, 3838 /*pmi*/ 0, 3839 &rcaplong, 3840 /*sense_len*/ SSD_FULL_SIZE, 3841 /*timeout*/ timeout ? timeout : 5000); 3842 3843 /* Disable freezing the device queue */ 3844 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 3845 3846 if (arglist & CAM_ARG_ERR_RECOVER) 3847 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 3848 3849 if (cam_send_ccb(device, ccb) < 0) { 3850 warn("error sending READ CAPACITY (16) command"); 3851 3852 if (arglist & CAM_ARG_VERBOSE) 3853 cam_error_print(device, ccb, CAM_ESF_ALL, 3854 CAM_EPF_ALL, stderr); 3855 3856 retval = 1; 3857 goto bailout; 3858 } 3859 3860 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 3861 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 3862 retval = 1; 3863 goto bailout; 3864 } 3865 3866 maxsector = scsi_8btou64(rcaplong.addr); 3867 block_len = scsi_4btoul(rcaplong.length); 3868 3869 do_print: 3870 if (blocksizeonly == 0) { 3871 /* 3872 * Humanize implies !quiet, and also implies numblocks. 3873 */ 3874 if (humanize != 0) { 3875 char tmpstr[6]; 3876 int64_t tmpbytes; 3877 int ret; 3878 3879 tmpbytes = (maxsector + 1) * block_len; 3880 ret = humanize_number(tmpstr, sizeof(tmpstr), 3881 tmpbytes, "", HN_AUTOSCALE, 3882 HN_B | HN_DECIMAL | 3883 ((baseten != 0) ? 3884 HN_DIVISOR_1000 : 0)); 3885 if (ret == -1) { 3886 warnx("%s: humanize_number failed!", __func__); 3887 retval = 1; 3888 goto bailout; 3889 } 3890 fprintf(stdout, "Device Size: %s%s", tmpstr, 3891 (sizeonly == 0) ? ", " : "\n"); 3892 } else if (numblocks != 0) { 3893 fprintf(stdout, "%s%ju%s", (quiet == 0) ? 3894 "Blocks: " : "", (uintmax_t)maxsector + 1, 3895 (sizeonly == 0) ? ", " : "\n"); 3896 } else { 3897 fprintf(stdout, "%s%ju%s", (quiet == 0) ? 3898 "Last Block: " : "", (uintmax_t)maxsector, 3899 (sizeonly == 0) ? ", " : "\n"); 3900 } 3901 } 3902 if (sizeonly == 0) 3903 fprintf(stdout, "%s%u%s\n", (quiet == 0) ? 3904 "Block Length: " : "", block_len, (quiet == 0) ? 3905 " bytes" : ""); 3906 bailout: 3907 cam_freeccb(ccb); 3908 3909 return (retval); 3910 } 3911 3912 #endif /* MINIMALISTIC */ 3913 3914 void 3915 usage(int verbose) 3916 { 3917 fprintf(verbose ? stdout : stderr, 3918 "usage: camcontrol <command> [device id][generic args][command args]\n" 3919 " camcontrol devlist [-v]\n" 3920 #ifndef MINIMALISTIC 3921 " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n" 3922 " camcontrol tur [dev_id][generic args]\n" 3923 " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n" 3924 " camcontrol identify [dev_id][generic args]\n" 3925 " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n" 3926 " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n" 3927 " [-q] [-s]\n" 3928 " camcontrol start [dev_id][generic args]\n" 3929 " camcontrol stop [dev_id][generic args]\n" 3930 " camcontrol load [dev_id][generic args]\n" 3931 " camcontrol eject [dev_id][generic args]\n" 3932 #endif /* MINIMALISTIC */ 3933 " camcontrol rescan <all | bus[:target:lun]>\n" 3934 " camcontrol reset <all | bus[:target:lun]>\n" 3935 #ifndef MINIMALISTIC 3936 " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n" 3937 " camcontrol modepage [dev_id][generic args] <-m page | -l>\n" 3938 " [-P pagectl][-e | -b][-d]\n" 3939 " camcontrol cmd [dev_id][generic args] <-c cmd [args]>\n" 3940 " [-i len fmt|-o len fmt [args]]\n" 3941 " camcontrol debug [-I][-P][-T][-S][-X][-c]\n" 3942 " <all|bus[:target[:lun]]|off>\n" 3943 " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n" 3944 " camcontrol negotiate [dev_id][generic args] [-a][-c]\n" 3945 " [-D <enable|disable>][-O offset][-q]\n" 3946 " [-R syncrate][-v][-T <enable|disable>]\n" 3947 " [-U][-W bus_width]\n" 3948 " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n" 3949 #endif /* MINIMALISTIC */ 3950 " camcontrol help\n"); 3951 if (!verbose) 3952 return; 3953 #ifndef MINIMALISTIC 3954 fprintf(stdout, 3955 "Specify one of the following options:\n" 3956 "devlist list all CAM devices\n" 3957 "periphlist list all CAM peripheral drivers attached to a device\n" 3958 "tur send a test unit ready to the named device\n" 3959 "inquiry send a SCSI inquiry command to the named device\n" 3960 "identify send a ATA identify command to the named device\n" 3961 "reportluns send a SCSI report luns command to the device\n" 3962 "readcap send a SCSI read capacity command to the device\n" 3963 "start send a Start Unit command to the device\n" 3964 "stop send a Stop Unit command to the device\n" 3965 "load send a Start Unit command to the device with the load bit set\n" 3966 "eject send a Stop Unit command to the device with the eject bit set\n" 3967 "rescan rescan all busses, the given bus, or bus:target:lun\n" 3968 "reset reset all busses, the given bus, or bus:target:lun\n" 3969 "defects read the defect list of the specified device\n" 3970 "modepage display or edit (-e) the given mode page\n" 3971 "cmd send the given scsi command, may need -i or -o as well\n" 3972 "debug turn debugging on/off for a bus, target, or lun, or all devices\n" 3973 "tags report or set the number of transaction slots for a device\n" 3974 "negotiate report or set device negotiation parameters\n" 3975 "format send the SCSI FORMAT UNIT command to the named device\n" 3976 "help this message\n" 3977 "Device Identifiers:\n" 3978 "bus:target specify the bus and target, lun defaults to 0\n" 3979 "bus:target:lun specify the bus, target and lun\n" 3980 "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n" 3981 "Generic arguments:\n" 3982 "-v be verbose, print out sense information\n" 3983 "-t timeout command timeout in seconds, overrides default timeout\n" 3984 "-n dev_name specify device name, e.g. \"da\", \"cd\"\n" 3985 "-u unit specify unit number, e.g. \"0\", \"5\"\n" 3986 "-E have the kernel attempt to perform SCSI error recovery\n" 3987 "-C count specify the SCSI command retry count (needs -E to work)\n" 3988 "modepage arguments:\n" 3989 "-l list all available mode pages\n" 3990 "-m page specify the mode page to view or edit\n" 3991 "-e edit the specified mode page\n" 3992 "-b force view to binary mode\n" 3993 "-d disable block descriptors for mode sense\n" 3994 "-P pgctl page control field 0-3\n" 3995 "defects arguments:\n" 3996 "-f format specify defect list format (block, bfi or phys)\n" 3997 "-G get the grown defect list\n" 3998 "-P get the permanant defect list\n" 3999 "inquiry arguments:\n" 4000 "-D get the standard inquiry data\n" 4001 "-S get the serial number\n" 4002 "-R get the transfer rate, etc.\n" 4003 "reportluns arguments:\n" 4004 "-c only report a count of available LUNs\n" 4005 "-l only print out luns, and not a count\n" 4006 "-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n" 4007 "readcap arguments\n" 4008 "-b only report the blocksize\n" 4009 "-h human readable device size, base 2\n" 4010 "-H human readable device size, base 10\n" 4011 "-N print the number of blocks instead of last block\n" 4012 "-q quiet, print numbers only\n" 4013 "-s only report the last block/device size\n" 4014 "cmd arguments:\n" 4015 "-c cdb [args] specify the SCSI CDB\n" 4016 "-i len fmt specify input data and input data format\n" 4017 "-o len fmt [args] specify output data and output data fmt\n" 4018 "debug arguments:\n" 4019 "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n" 4020 "-T CAM_DEBUG_TRACE -- routine flow tracking\n" 4021 "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n" 4022 "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n" 4023 "tags arguments:\n" 4024 "-N tags specify the number of tags to use for this device\n" 4025 "-q be quiet, don't report the number of tags\n" 4026 "-v report a number of tag-related parameters\n" 4027 "negotiate arguments:\n" 4028 "-a send a test unit ready after negotiation\n" 4029 "-c report/set current negotiation settings\n" 4030 "-D <arg> \"enable\" or \"disable\" disconnection\n" 4031 "-O offset set command delay offset\n" 4032 "-q be quiet, don't report anything\n" 4033 "-R syncrate synchronization rate in MHz\n" 4034 "-T <arg> \"enable\" or \"disable\" tagged queueing\n" 4035 "-U report/set user negotiation settings\n" 4036 "-W bus_width set the bus width in bits (8, 16 or 32)\n" 4037 "-v also print a Path Inquiry CCB for the controller\n" 4038 "format arguments:\n" 4039 "-q be quiet, don't print status messages\n" 4040 "-r run in report only mode\n" 4041 "-w don't send immediate format command\n" 4042 "-y don't ask any questions\n"); 4043 #endif /* MINIMALISTIC */ 4044 } 4045 4046 int 4047 main(int argc, char **argv) 4048 { 4049 int c; 4050 char *device = NULL; 4051 int unit = 0; 4052 struct cam_device *cam_dev = NULL; 4053 int timeout = 0, retry_count = 1; 4054 camcontrol_optret optreturn; 4055 char *tstr; 4056 const char *mainopt = "C:En:t:u:v"; 4057 const char *subopt = NULL; 4058 char combinedopt[256]; 4059 int error = 0, optstart = 2; 4060 int devopen = 1; 4061 #ifndef MINIMALISTIC 4062 int bus, target, lun; 4063 #endif /* MINIMALISTIC */ 4064 4065 cmdlist = CAM_CMD_NONE; 4066 arglist = CAM_ARG_NONE; 4067 4068 if (argc < 2) { 4069 usage(0); 4070 exit(1); 4071 } 4072 4073 /* 4074 * Get the base option. 4075 */ 4076 optreturn = getoption(argv[1], &cmdlist, &arglist, &subopt); 4077 4078 if (optreturn == CC_OR_AMBIGUOUS) { 4079 warnx("ambiguous option %s", argv[1]); 4080 usage(0); 4081 exit(1); 4082 } else if (optreturn == CC_OR_NOT_FOUND) { 4083 warnx("option %s not found", argv[1]); 4084 usage(0); 4085 exit(1); 4086 } 4087 4088 /* 4089 * Ahh, getopt(3) is a pain. 4090 * 4091 * This is a gross hack. There really aren't many other good 4092 * options (excuse the pun) for parsing options in a situation like 4093 * this. getopt is kinda braindead, so you end up having to run 4094 * through the options twice, and give each invocation of getopt 4095 * the option string for the other invocation. 4096 * 4097 * You would think that you could just have two groups of options. 4098 * The first group would get parsed by the first invocation of 4099 * getopt, and the second group would get parsed by the second 4100 * invocation of getopt. It doesn't quite work out that way. When 4101 * the first invocation of getopt finishes, it leaves optind pointing 4102 * to the argument _after_ the first argument in the second group. 4103 * So when the second invocation of getopt comes around, it doesn't 4104 * recognize the first argument it gets and then bails out. 4105 * 4106 * A nice alternative would be to have a flag for getopt that says 4107 * "just keep parsing arguments even when you encounter an unknown 4108 * argument", but there isn't one. So there's no real clean way to 4109 * easily parse two sets of arguments without having one invocation 4110 * of getopt know about the other. 4111 * 4112 * Without this hack, the first invocation of getopt would work as 4113 * long as the generic arguments are first, but the second invocation 4114 * (in the subfunction) would fail in one of two ways. In the case 4115 * where you don't set optreset, it would fail because optind may be 4116 * pointing to the argument after the one it should be pointing at. 4117 * In the case where you do set optreset, and reset optind, it would 4118 * fail because getopt would run into the first set of options, which 4119 * it doesn't understand. 4120 * 4121 * All of this would "sort of" work if you could somehow figure out 4122 * whether optind had been incremented one option too far. The 4123 * mechanics of that, however, are more daunting than just giving 4124 * both invocations all of the expect options for either invocation. 4125 * 4126 * Needless to say, I wouldn't mind if someone invented a better 4127 * (non-GPL!) command line parsing interface than getopt. I 4128 * wouldn't mind if someone added more knobs to getopt to make it 4129 * work better. Who knows, I may talk myself into doing it someday, 4130 * if the standards weenies let me. As it is, it just leads to 4131 * hackery like this and causes people to avoid it in some cases. 4132 * 4133 * KDM, September 8th, 1998 4134 */ 4135 if (subopt != NULL) 4136 sprintf(combinedopt, "%s%s", mainopt, subopt); 4137 else 4138 sprintf(combinedopt, "%s", mainopt); 4139 4140 /* 4141 * For these options we do not parse optional device arguments and 4142 * we do not open a passthrough device. 4143 */ 4144 if ((cmdlist == CAM_CMD_RESCAN) 4145 || (cmdlist == CAM_CMD_RESET) 4146 || (cmdlist == CAM_CMD_DEVTREE) 4147 || (cmdlist == CAM_CMD_USAGE) 4148 || (cmdlist == CAM_CMD_DEBUG)) 4149 devopen = 0; 4150 4151 #ifndef MINIMALISTIC 4152 if ((devopen == 1) 4153 && (argc > 2 && argv[2][0] != '-')) { 4154 char name[30]; 4155 int rv; 4156 4157 /* 4158 * First catch people who try to do things like: 4159 * camcontrol tur /dev/da0 4160 * camcontrol doesn't take device nodes as arguments. 4161 */ 4162 if (argv[2][0] == '/') { 4163 warnx("%s is not a valid device identifier", argv[2]); 4164 errx(1, "please read the camcontrol(8) man page"); 4165 } else if (isdigit(argv[2][0])) { 4166 /* device specified as bus:target[:lun] */ 4167 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist); 4168 if (rv < 2) 4169 errx(1, "numeric device specification must " 4170 "be either bus:target, or " 4171 "bus:target:lun"); 4172 /* default to 0 if lun was not specified */ 4173 if ((arglist & CAM_ARG_LUN) == 0) { 4174 lun = 0; 4175 arglist |= CAM_ARG_LUN; 4176 } 4177 optstart++; 4178 } else { 4179 if (cam_get_device(argv[2], name, sizeof name, &unit) 4180 == -1) 4181 errx(1, "%s", cam_errbuf); 4182 device = strdup(name); 4183 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT; 4184 optstart++; 4185 } 4186 } 4187 #endif /* MINIMALISTIC */ 4188 /* 4189 * Start getopt processing at argv[2/3], since we've already 4190 * accepted argv[1..2] as the command name, and as a possible 4191 * device name. 4192 */ 4193 optind = optstart; 4194 4195 /* 4196 * Now we run through the argument list looking for generic 4197 * options, and ignoring options that possibly belong to 4198 * subfunctions. 4199 */ 4200 while ((c = getopt(argc, argv, combinedopt))!= -1){ 4201 switch(c) { 4202 case 'C': 4203 retry_count = strtol(optarg, NULL, 0); 4204 if (retry_count < 0) 4205 errx(1, "retry count %d is < 0", 4206 retry_count); 4207 arglist |= CAM_ARG_RETRIES; 4208 break; 4209 case 'E': 4210 arglist |= CAM_ARG_ERR_RECOVER; 4211 break; 4212 case 'n': 4213 arglist |= CAM_ARG_DEVICE; 4214 tstr = optarg; 4215 while (isspace(*tstr) && (*tstr != '\0')) 4216 tstr++; 4217 device = (char *)strdup(tstr); 4218 break; 4219 case 't': 4220 timeout = strtol(optarg, NULL, 0); 4221 if (timeout < 0) 4222 errx(1, "invalid timeout %d", timeout); 4223 /* Convert the timeout from seconds to ms */ 4224 timeout *= 1000; 4225 arglist |= CAM_ARG_TIMEOUT; 4226 break; 4227 case 'u': 4228 arglist |= CAM_ARG_UNIT; 4229 unit = strtol(optarg, NULL, 0); 4230 break; 4231 case 'v': 4232 arglist |= CAM_ARG_VERBOSE; 4233 break; 4234 default: 4235 break; 4236 } 4237 } 4238 4239 #ifndef MINIMALISTIC 4240 /* 4241 * For most commands we'll want to open the passthrough device 4242 * associated with the specified device. In the case of the rescan 4243 * commands, we don't use a passthrough device at all, just the 4244 * transport layer device. 4245 */ 4246 if (devopen == 1) { 4247 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0) 4248 && (((arglist & CAM_ARG_DEVICE) == 0) 4249 || ((arglist & CAM_ARG_UNIT) == 0))) { 4250 errx(1, "subcommand \"%s\" requires a valid device " 4251 "identifier", argv[1]); 4252 } 4253 4254 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))? 4255 cam_open_btl(bus, target, lun, O_RDWR, NULL) : 4256 cam_open_spec_device(device,unit,O_RDWR,NULL))) 4257 == NULL) 4258 errx(1,"%s", cam_errbuf); 4259 } 4260 #endif /* MINIMALISTIC */ 4261 4262 /* 4263 * Reset optind to 2, and reset getopt, so these routines can parse 4264 * the arguments again. 4265 */ 4266 optind = optstart; 4267 optreset = 1; 4268 4269 switch(cmdlist) { 4270 #ifndef MINIMALISTIC 4271 case CAM_CMD_DEVLIST: 4272 error = getdevlist(cam_dev); 4273 break; 4274 #endif /* MINIMALISTIC */ 4275 case CAM_CMD_DEVTREE: 4276 error = getdevtree(); 4277 break; 4278 #ifndef MINIMALISTIC 4279 case CAM_CMD_TUR: 4280 error = testunitready(cam_dev, retry_count, timeout, 0); 4281 break; 4282 case CAM_CMD_INQUIRY: 4283 error = scsidoinquiry(cam_dev, argc, argv, combinedopt, 4284 retry_count, timeout); 4285 break; 4286 case CAM_CMD_IDENTIFY: 4287 error = ataidentify(cam_dev, retry_count, timeout); 4288 break; 4289 case CAM_CMD_STARTSTOP: 4290 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT, 4291 arglist & CAM_ARG_EJECT, retry_count, 4292 timeout); 4293 break; 4294 #endif /* MINIMALISTIC */ 4295 case CAM_CMD_RESCAN: 4296 error = dorescan_or_reset(argc, argv, 1); 4297 break; 4298 case CAM_CMD_RESET: 4299 error = dorescan_or_reset(argc, argv, 0); 4300 break; 4301 #ifndef MINIMALISTIC 4302 case CAM_CMD_READ_DEFECTS: 4303 error = readdefects(cam_dev, argc, argv, combinedopt, 4304 retry_count, timeout); 4305 break; 4306 case CAM_CMD_MODE_PAGE: 4307 modepage(cam_dev, argc, argv, combinedopt, 4308 retry_count, timeout); 4309 break; 4310 case CAM_CMD_SCSI_CMD: 4311 error = scsicmd(cam_dev, argc, argv, combinedopt, 4312 retry_count, timeout); 4313 break; 4314 case CAM_CMD_DEBUG: 4315 error = camdebug(argc, argv, combinedopt); 4316 break; 4317 case CAM_CMD_TAG: 4318 error = tagcontrol(cam_dev, argc, argv, combinedopt); 4319 break; 4320 case CAM_CMD_RATE: 4321 error = ratecontrol(cam_dev, retry_count, timeout, 4322 argc, argv, combinedopt); 4323 break; 4324 case CAM_CMD_FORMAT: 4325 error = scsiformat(cam_dev, argc, argv, 4326 combinedopt, retry_count, timeout); 4327 break; 4328 case CAM_CMD_REPORTLUNS: 4329 error = scsireportluns(cam_dev, argc, argv, 4330 combinedopt, retry_count, 4331 timeout); 4332 break; 4333 case CAM_CMD_READCAP: 4334 error = scsireadcapacity(cam_dev, argc, argv, 4335 combinedopt, retry_count, 4336 timeout); 4337 break; 4338 #endif /* MINIMALISTIC */ 4339 case CAM_CMD_USAGE: 4340 usage(1); 4341 break; 4342 default: 4343 usage(0); 4344 error = 1; 4345 break; 4346 } 4347 4348 if (cam_dev != NULL) 4349 cam_close_device(cam_dev); 4350 4351 exit(error); 4352 } 4353