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