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