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