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