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