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