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