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