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