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