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