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