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