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