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