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