camcontrol.c revision 312951
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 312951 2017-01-29 14:29:02Z 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, valid_bytes; 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 (cdb_len) 4453 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid; 4454 else 4455 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid; 4456 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 4457 && (arglist & CAM_ARG_CMD_IN) 4458 && (valid_bytes > 0)) { 4459 if (fd_data == 0) { 4460 buff_decode_visit(data_ptr, valid_bytes, datastr, 4461 arg_put, NULL); 4462 fprintf(stdout, "\n"); 4463 } else { 4464 ssize_t amt_written; 4465 int amt_to_write = valid_bytes; 4466 u_int8_t *buf_ptr = data_ptr; 4467 4468 for (amt_written = 0; (amt_to_write > 0) && 4469 (amt_written =write(1, buf_ptr,amt_to_write))> 0;){ 4470 amt_to_write -= amt_written; 4471 buf_ptr += amt_written; 4472 } 4473 if (amt_written == -1) { 4474 warn("error writing data to stdout"); 4475 error = 1; 4476 goto scsicmd_bailout; 4477 } else if ((amt_written == 0) 4478 && (amt_to_write > 0)) { 4479 warnx("only wrote %u bytes out of %u", 4480 valid_bytes - amt_to_write, valid_bytes); 4481 } 4482 } 4483 } 4484 4485scsicmd_bailout: 4486 4487 if ((data_bytes > 0) && (data_ptr != NULL)) 4488 free(data_ptr); 4489 4490 cam_freeccb(ccb); 4491 4492 return(error); 4493} 4494 4495static int 4496camdebug(int argc, char **argv, char *combinedopt) 4497{ 4498 int c, fd; 4499 path_id_t bus = CAM_BUS_WILDCARD; 4500 target_id_t target = CAM_TARGET_WILDCARD; 4501 lun_id_t lun = CAM_LUN_WILDCARD; 4502 char *tstr, *tmpstr = NULL; 4503 union ccb ccb; 4504 int error = 0; 4505 4506 bzero(&ccb, sizeof(union ccb)); 4507 4508 while ((c = getopt(argc, argv, combinedopt)) != -1) { 4509 switch(c) { 4510 case 'I': 4511 arglist |= CAM_ARG_DEBUG_INFO; 4512 ccb.cdbg.flags |= CAM_DEBUG_INFO; 4513 break; 4514 case 'P': 4515 arglist |= CAM_ARG_DEBUG_PERIPH; 4516 ccb.cdbg.flags |= CAM_DEBUG_PERIPH; 4517 break; 4518 case 'S': 4519 arglist |= CAM_ARG_DEBUG_SUBTRACE; 4520 ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE; 4521 break; 4522 case 'T': 4523 arglist |= CAM_ARG_DEBUG_TRACE; 4524 ccb.cdbg.flags |= CAM_DEBUG_TRACE; 4525 break; 4526 case 'X': 4527 arglist |= CAM_ARG_DEBUG_XPT; 4528 ccb.cdbg.flags |= CAM_DEBUG_XPT; 4529 break; 4530 case 'c': 4531 arglist |= CAM_ARG_DEBUG_CDB; 4532 ccb.cdbg.flags |= CAM_DEBUG_CDB; 4533 break; 4534 case 'p': 4535 arglist |= CAM_ARG_DEBUG_PROBE; 4536 ccb.cdbg.flags |= CAM_DEBUG_PROBE; 4537 break; 4538 default: 4539 break; 4540 } 4541 } 4542 4543 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { 4544 warnx("error opening transport layer device %s", XPT_DEVICE); 4545 warn("%s", XPT_DEVICE); 4546 return(1); 4547 } 4548 argc -= optind; 4549 argv += optind; 4550 4551 if (argc <= 0) { 4552 warnx("you must specify \"off\", \"all\" or a bus,"); 4553 warnx("bus:target, or bus:target:lun"); 4554 close(fd); 4555 return(1); 4556 } 4557 4558 tstr = *argv; 4559 4560 while (isspace(*tstr) && (*tstr != '\0')) 4561 tstr++; 4562 4563 if (strncmp(tstr, "off", 3) == 0) { 4564 ccb.cdbg.flags = CAM_DEBUG_NONE; 4565 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH| 4566 CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE| 4567 CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE); 4568 } else if (strncmp(tstr, "all", 3) != 0) { 4569 tmpstr = (char *)strtok(tstr, ":"); 4570 if ((tmpstr != NULL) && (*tmpstr != '\0')){ 4571 bus = strtol(tmpstr, NULL, 0); 4572 arglist |= CAM_ARG_BUS; 4573 tmpstr = (char *)strtok(NULL, ":"); 4574 if ((tmpstr != NULL) && (*tmpstr != '\0')){ 4575 target = strtol(tmpstr, NULL, 0); 4576 arglist |= CAM_ARG_TARGET; 4577 tmpstr = (char *)strtok(NULL, ":"); 4578 if ((tmpstr != NULL) && (*tmpstr != '\0')){ 4579 lun = strtol(tmpstr, NULL, 0); 4580 arglist |= CAM_ARG_LUN; 4581 } 4582 } 4583 } else { 4584 error = 1; 4585 warnx("you must specify \"all\", \"off\", or a bus,"); 4586 warnx("bus:target, or bus:target:lun to debug"); 4587 } 4588 } 4589 4590 if (error == 0) { 4591 4592 ccb.ccb_h.func_code = XPT_DEBUG; 4593 ccb.ccb_h.path_id = bus; 4594 ccb.ccb_h.target_id = target; 4595 ccb.ccb_h.target_lun = lun; 4596 4597 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 4598 warn("CAMIOCOMMAND ioctl failed"); 4599 error = 1; 4600 } 4601 4602 if (error == 0) { 4603 if ((ccb.ccb_h.status & CAM_STATUS_MASK) == 4604 CAM_FUNC_NOTAVAIL) { 4605 warnx("CAM debugging not available"); 4606 warnx("you need to put options CAMDEBUG in" 4607 " your kernel config file!"); 4608 error = 1; 4609 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) != 4610 CAM_REQ_CMP) { 4611 warnx("XPT_DEBUG CCB failed with status %#x", 4612 ccb.ccb_h.status); 4613 error = 1; 4614 } else { 4615 if (ccb.cdbg.flags == CAM_DEBUG_NONE) { 4616 fprintf(stderr, 4617 "Debugging turned off\n"); 4618 } else { 4619 fprintf(stderr, 4620 "Debugging enabled for " 4621 "%d:%d:%jx\n", 4622 bus, target, (uintmax_t)lun); 4623 } 4624 } 4625 } 4626 close(fd); 4627 } 4628 4629 return(error); 4630} 4631 4632static int 4633tagcontrol(struct cam_device *device, int argc, char **argv, 4634 char *combinedopt) 4635{ 4636 int c; 4637 union ccb *ccb; 4638 int numtags = -1; 4639 int retval = 0; 4640 int quiet = 0; 4641 char pathstr[1024]; 4642 4643 ccb = cam_getccb(device); 4644 4645 if (ccb == NULL) { 4646 warnx("tagcontrol: error allocating ccb"); 4647 return(1); 4648 } 4649 4650 while ((c = getopt(argc, argv, combinedopt)) != -1) { 4651 switch(c) { 4652 case 'N': 4653 numtags = strtol(optarg, NULL, 0); 4654 if (numtags < 0) { 4655 warnx("tag count %d is < 0", numtags); 4656 retval = 1; 4657 goto tagcontrol_bailout; 4658 } 4659 break; 4660 case 'q': 4661 quiet++; 4662 break; 4663 default: 4664 break; 4665 } 4666 } 4667 4668 cam_path_string(device, pathstr, sizeof(pathstr)); 4669 4670 if (numtags >= 0) { 4671 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs); 4672 ccb->ccb_h.func_code = XPT_REL_SIMQ; 4673 ccb->ccb_h.flags = CAM_DEV_QFREEZE; 4674 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS; 4675 ccb->crs.openings = numtags; 4676 4677 4678 if (cam_send_ccb(device, ccb) < 0) { 4679 perror("error sending XPT_REL_SIMQ CCB"); 4680 retval = 1; 4681 goto tagcontrol_bailout; 4682 } 4683 4684 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4685 warnx("XPT_REL_SIMQ CCB failed"); 4686 cam_error_print(device, ccb, CAM_ESF_ALL, 4687 CAM_EPF_ALL, stderr); 4688 retval = 1; 4689 goto tagcontrol_bailout; 4690 } 4691 4692 4693 if (quiet == 0) 4694 fprintf(stdout, "%stagged openings now %d\n", 4695 pathstr, ccb->crs.openings); 4696 } 4697 4698 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds); 4699 4700 ccb->ccb_h.func_code = XPT_GDEV_STATS; 4701 4702 if (cam_send_ccb(device, ccb) < 0) { 4703 perror("error sending XPT_GDEV_STATS CCB"); 4704 retval = 1; 4705 goto tagcontrol_bailout; 4706 } 4707 4708 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4709 warnx("XPT_GDEV_STATS CCB failed"); 4710 cam_error_print(device, ccb, CAM_ESF_ALL, 4711 CAM_EPF_ALL, stderr); 4712 retval = 1; 4713 goto tagcontrol_bailout; 4714 } 4715 4716 if (arglist & CAM_ARG_VERBOSE) { 4717 fprintf(stdout, "%s", pathstr); 4718 fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings); 4719 fprintf(stdout, "%s", pathstr); 4720 fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active); 4721 fprintf(stdout, "%s", pathstr); 4722 fprintf(stdout, "allocated %d\n", ccb->cgds.allocated); 4723 fprintf(stdout, "%s", pathstr); 4724 fprintf(stdout, "queued %d\n", ccb->cgds.queued); 4725 fprintf(stdout, "%s", pathstr); 4726 fprintf(stdout, "held %d\n", ccb->cgds.held); 4727 fprintf(stdout, "%s", pathstr); 4728 fprintf(stdout, "mintags %d\n", ccb->cgds.mintags); 4729 fprintf(stdout, "%s", pathstr); 4730 fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags); 4731 } else { 4732 if (quiet == 0) { 4733 fprintf(stdout, "%s", pathstr); 4734 fprintf(stdout, "device openings: "); 4735 } 4736 fprintf(stdout, "%d\n", ccb->cgds.dev_openings + 4737 ccb->cgds.dev_active); 4738 } 4739 4740tagcontrol_bailout: 4741 4742 cam_freeccb(ccb); 4743 return(retval); 4744} 4745 4746static void 4747cts_print(struct cam_device *device, struct ccb_trans_settings *cts) 4748{ 4749 char pathstr[1024]; 4750 4751 cam_path_string(device, pathstr, sizeof(pathstr)); 4752 4753 if (cts->transport == XPORT_SPI) { 4754 struct ccb_trans_settings_spi *spi = 4755 &cts->xport_specific.spi; 4756 4757 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { 4758 4759 fprintf(stdout, "%ssync parameter: %d\n", pathstr, 4760 spi->sync_period); 4761 4762 if (spi->sync_offset != 0) { 4763 u_int freq; 4764 4765 freq = scsi_calc_syncsrate(spi->sync_period); 4766 fprintf(stdout, "%sfrequency: %d.%03dMHz\n", 4767 pathstr, freq / 1000, freq % 1000); 4768 } 4769 } 4770 4771 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) { 4772 fprintf(stdout, "%soffset: %d\n", pathstr, 4773 spi->sync_offset); 4774 } 4775 4776 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) { 4777 fprintf(stdout, "%sbus width: %d bits\n", pathstr, 4778 (0x01 << spi->bus_width) * 8); 4779 } 4780 4781 if (spi->valid & CTS_SPI_VALID_DISC) { 4782 fprintf(stdout, "%sdisconnection is %s\n", pathstr, 4783 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ? 4784 "enabled" : "disabled"); 4785 } 4786 } 4787 if (cts->transport == XPORT_FC) { 4788 struct ccb_trans_settings_fc *fc = 4789 &cts->xport_specific.fc; 4790 4791 if (fc->valid & CTS_FC_VALID_WWNN) 4792 fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr, 4793 (long long) fc->wwnn); 4794 if (fc->valid & CTS_FC_VALID_WWPN) 4795 fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr, 4796 (long long) fc->wwpn); 4797 if (fc->valid & CTS_FC_VALID_PORT) 4798 fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port); 4799 if (fc->valid & CTS_FC_VALID_SPEED) 4800 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n", 4801 pathstr, fc->bitrate / 1000, fc->bitrate % 1000); 4802 } 4803 if (cts->transport == XPORT_SAS) { 4804 struct ccb_trans_settings_sas *sas = 4805 &cts->xport_specific.sas; 4806 4807 if (sas->valid & CTS_SAS_VALID_SPEED) 4808 fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n", 4809 pathstr, sas->bitrate / 1000, sas->bitrate % 1000); 4810 } 4811 if (cts->transport == XPORT_ATA) { 4812 struct ccb_trans_settings_pata *pata = 4813 &cts->xport_specific.ata; 4814 4815 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) { 4816 fprintf(stdout, "%sATA mode: %s\n", pathstr, 4817 ata_mode2string(pata->mode)); 4818 } 4819 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) { 4820 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, 4821 pata->atapi); 4822 } 4823 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) { 4824 fprintf(stdout, "%sPIO transaction length: %d\n", 4825 pathstr, pata->bytecount); 4826 } 4827 } 4828 if (cts->transport == XPORT_SATA) { 4829 struct ccb_trans_settings_sata *sata = 4830 &cts->xport_specific.sata; 4831 4832 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) { 4833 fprintf(stdout, "%sSATA revision: %d.x\n", pathstr, 4834 sata->revision); 4835 } 4836 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) { 4837 fprintf(stdout, "%sATA mode: %s\n", pathstr, 4838 ata_mode2string(sata->mode)); 4839 } 4840 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) { 4841 fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, 4842 sata->atapi); 4843 } 4844 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) { 4845 fprintf(stdout, "%sPIO transaction length: %d\n", 4846 pathstr, sata->bytecount); 4847 } 4848 if ((sata->valid & CTS_SATA_VALID_PM) != 0) { 4849 fprintf(stdout, "%sPMP presence: %d\n", pathstr, 4850 sata->pm_present); 4851 } 4852 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) { 4853 fprintf(stdout, "%sNumber of tags: %d\n", pathstr, 4854 sata->tags); 4855 } 4856 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) { 4857 fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr, 4858 sata->caps); 4859 } 4860 } 4861 if (cts->protocol == PROTO_ATA) { 4862 struct ccb_trans_settings_ata *ata= 4863 &cts->proto_specific.ata; 4864 4865 if (ata->valid & CTS_ATA_VALID_TQ) { 4866 fprintf(stdout, "%stagged queueing: %s\n", pathstr, 4867 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ? 4868 "enabled" : "disabled"); 4869 } 4870 } 4871 if (cts->protocol == PROTO_SCSI) { 4872 struct ccb_trans_settings_scsi *scsi= 4873 &cts->proto_specific.scsi; 4874 4875 if (scsi->valid & CTS_SCSI_VALID_TQ) { 4876 fprintf(stdout, "%stagged queueing: %s\n", pathstr, 4877 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ? 4878 "enabled" : "disabled"); 4879 } 4880 } 4881 4882} 4883 4884/* 4885 * Get a path inquiry CCB for the specified device. 4886 */ 4887static int 4888get_cpi(struct cam_device *device, struct ccb_pathinq *cpi) 4889{ 4890 union ccb *ccb; 4891 int retval = 0; 4892 4893 ccb = cam_getccb(device); 4894 if (ccb == NULL) { 4895 warnx("get_cpi: couldn't allocate CCB"); 4896 return(1); 4897 } 4898 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi); 4899 ccb->ccb_h.func_code = XPT_PATH_INQ; 4900 if (cam_send_ccb(device, ccb) < 0) { 4901 warn("get_cpi: error sending Path Inquiry CCB"); 4902 if (arglist & CAM_ARG_VERBOSE) 4903 cam_error_print(device, ccb, CAM_ESF_ALL, 4904 CAM_EPF_ALL, stderr); 4905 retval = 1; 4906 goto get_cpi_bailout; 4907 } 4908 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4909 if (arglist & CAM_ARG_VERBOSE) 4910 cam_error_print(device, ccb, CAM_ESF_ALL, 4911 CAM_EPF_ALL, stderr); 4912 retval = 1; 4913 goto get_cpi_bailout; 4914 } 4915 bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq)); 4916 4917get_cpi_bailout: 4918 cam_freeccb(ccb); 4919 return(retval); 4920} 4921 4922/* 4923 * Get a get device CCB for the specified device. 4924 */ 4925static int 4926get_cgd(struct cam_device *device, struct ccb_getdev *cgd) 4927{ 4928 union ccb *ccb; 4929 int retval = 0; 4930 4931 ccb = cam_getccb(device); 4932 if (ccb == NULL) { 4933 warnx("get_cgd: couldn't allocate CCB"); 4934 return(1); 4935 } 4936 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd); 4937 ccb->ccb_h.func_code = XPT_GDEV_TYPE; 4938 if (cam_send_ccb(device, ccb) < 0) { 4939 warn("get_cgd: error sending Path Inquiry CCB"); 4940 if (arglist & CAM_ARG_VERBOSE) 4941 cam_error_print(device, ccb, CAM_ESF_ALL, 4942 CAM_EPF_ALL, stderr); 4943 retval = 1; 4944 goto get_cgd_bailout; 4945 } 4946 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4947 if (arglist & CAM_ARG_VERBOSE) 4948 cam_error_print(device, ccb, CAM_ESF_ALL, 4949 CAM_EPF_ALL, stderr); 4950 retval = 1; 4951 goto get_cgd_bailout; 4952 } 4953 bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev)); 4954 4955get_cgd_bailout: 4956 cam_freeccb(ccb); 4957 return(retval); 4958} 4959 4960/* 4961 * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an 4962 * error. 4963 */ 4964int 4965dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count, 4966 int timeout, int verbosemode) 4967{ 4968 union ccb *ccb = NULL; 4969 struct scsi_vpd_supported_page_list sup_pages; 4970 int i; 4971 int retval = 0; 4972 4973 ccb = cam_getccb(dev); 4974 if (ccb == NULL) { 4975 warn("Unable to allocate CCB"); 4976 retval = -1; 4977 goto bailout; 4978 } 4979 4980 /* cam_getccb cleans up the header, caller has to zero the payload */ 4981 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 4982 4983 bzero(&sup_pages, sizeof(sup_pages)); 4984 4985 scsi_inquiry(&ccb->csio, 4986 /*retries*/ retry_count, 4987 /*cbfcnp*/ NULL, 4988 /* tag_action */ MSG_SIMPLE_Q_TAG, 4989 /* inq_buf */ (u_int8_t *)&sup_pages, 4990 /* inq_len */ sizeof(sup_pages), 4991 /* evpd */ 1, 4992 /* page_code */ SVPD_SUPPORTED_PAGE_LIST, 4993 /* sense_len */ SSD_FULL_SIZE, 4994 /* timeout */ timeout ? timeout : 5000); 4995 4996 /* Disable freezing the device queue */ 4997 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 4998 4999 if (retry_count != 0) 5000 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 5001 5002 if (cam_send_ccb(dev, ccb) < 0) { 5003 cam_freeccb(ccb); 5004 ccb = NULL; 5005 retval = -1; 5006 goto bailout; 5007 } 5008 5009 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5010 if (verbosemode != 0) 5011 cam_error_print(dev, ccb, CAM_ESF_ALL, 5012 CAM_EPF_ALL, stderr); 5013 retval = -1; 5014 goto bailout; 5015 } 5016 5017 for (i = 0; i < sup_pages.length; i++) { 5018 if (sup_pages.list[i] == page_id) { 5019 retval = 1; 5020 goto bailout; 5021 } 5022 } 5023bailout: 5024 if (ccb != NULL) 5025 cam_freeccb(ccb); 5026 5027 return (retval); 5028} 5029 5030/* 5031 * devtype is filled in with the type of device. 5032 * Returns 0 for success, non-zero for failure. 5033 */ 5034int 5035get_device_type(struct cam_device *dev, int retry_count, int timeout, 5036 int verbosemode, camcontrol_devtype *devtype) 5037{ 5038 struct ccb_getdev cgd; 5039 int retval = 0; 5040 5041 retval = get_cgd(dev, &cgd); 5042 if (retval != 0) 5043 goto bailout; 5044 5045 switch (cgd.protocol) { 5046 case PROTO_SCSI: 5047 break; 5048 case PROTO_ATA: 5049 case PROTO_ATAPI: 5050 case PROTO_SATAPM: 5051 *devtype = CC_DT_ATA; 5052 goto bailout; 5053 break; /*NOTREACHED*/ 5054 default: 5055 *devtype = CC_DT_UNKNOWN; 5056 goto bailout; 5057 break; /*NOTREACHED*/ 5058 } 5059 5060 /* 5061 * Check for the ATA Information VPD page (0x89). If this is an 5062 * ATA device behind a SCSI to ATA translation layer, this VPD page 5063 * should be present. 5064 * 5065 * If that VPD page isn't present, or we get an error back from the 5066 * INQUIRY command, we'll just treat it as a normal SCSI device. 5067 */ 5068 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count, 5069 timeout, verbosemode); 5070 if (retval == 1) 5071 *devtype = CC_DT_ATA_BEHIND_SCSI; 5072 else 5073 *devtype = CC_DT_SCSI; 5074 5075 retval = 0; 5076 5077bailout: 5078 return (retval); 5079} 5080 5081void 5082build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags, 5083 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features, 5084 uint16_t sector_count, uint64_t lba, uint8_t command, uint8_t *data_ptr, 5085 uint16_t dxfer_len, uint8_t sense_len, uint32_t timeout, 5086 int is48bit, camcontrol_devtype devtype) 5087{ 5088 if (devtype == CC_DT_ATA) { 5089 cam_fill_ataio(&ccb->ataio, 5090 /*retries*/ retry_count, 5091 /*cbfcnp*/ NULL, 5092 /*flags*/ flags, 5093 /*tag_action*/ tag_action, 5094 /*data_ptr*/ data_ptr, 5095 /*dxfer_len*/ dxfer_len, 5096 /*timeout*/ timeout); 5097 if (is48bit || lba > ATA_MAX_28BIT_LBA) 5098 ata_48bit_cmd(&ccb->ataio, command, features, lba, 5099 sector_count); 5100 else 5101 ata_28bit_cmd(&ccb->ataio, command, features, lba, 5102 sector_count); 5103 } else { 5104 if (is48bit || lba > ATA_MAX_28BIT_LBA) 5105 protocol |= AP_EXTEND; 5106 5107 scsi_ata_pass_16(&ccb->csio, 5108 /*retries*/ retry_count, 5109 /*cbfcnp*/ NULL, 5110 /*flags*/ flags, 5111 /*tag_action*/ tag_action, 5112 /*protocol*/ protocol, 5113 /*ata_flags*/ ata_flags, 5114 /*features*/ features, 5115 /*sector_count*/ sector_count, 5116 /*lba*/ lba, 5117 /*command*/ command, 5118 /*control*/ 0, 5119 /*data_ptr*/ data_ptr, 5120 /*dxfer_len*/ dxfer_len, 5121 /*sense_len*/ sense_len, 5122 /*timeout*/ timeout); 5123 } 5124} 5125 5126 5127static void 5128cpi_print(struct ccb_pathinq *cpi) 5129{ 5130 char adapter_str[1024]; 5131 int i; 5132 5133 snprintf(adapter_str, sizeof(adapter_str), 5134 "%s%d:", cpi->dev_name, cpi->unit_number); 5135 5136 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str, 5137 cpi->version_num); 5138 5139 for (i = 1; i < 0xff; i = i << 1) { 5140 const char *str; 5141 5142 if ((i & cpi->hba_inquiry) == 0) 5143 continue; 5144 5145 fprintf(stdout, "%s supports ", adapter_str); 5146 5147 switch(i) { 5148 case PI_MDP_ABLE: 5149 str = "MDP message"; 5150 break; 5151 case PI_WIDE_32: 5152 str = "32 bit wide SCSI"; 5153 break; 5154 case PI_WIDE_16: 5155 str = "16 bit wide SCSI"; 5156 break; 5157 case PI_SDTR_ABLE: 5158 str = "SDTR message"; 5159 break; 5160 case PI_LINKED_CDB: 5161 str = "linked CDBs"; 5162 break; 5163 case PI_TAG_ABLE: 5164 str = "tag queue messages"; 5165 break; 5166 case PI_SOFT_RST: 5167 str = "soft reset alternative"; 5168 break; 5169 case PI_SATAPM: 5170 str = "SATA Port Multiplier"; 5171 break; 5172 default: 5173 str = "unknown PI bit set"; 5174 break; 5175 } 5176 fprintf(stdout, "%s\n", str); 5177 } 5178 5179 for (i = 1; i < 0xff; i = i << 1) { 5180 const char *str; 5181 5182 if ((i & cpi->hba_misc) == 0) 5183 continue; 5184 5185 fprintf(stdout, "%s ", adapter_str); 5186 5187 switch(i) { 5188 case PIM_SCANHILO: 5189 str = "bus scans from high ID to low ID"; 5190 break; 5191 case PIM_NOREMOVE: 5192 str = "removable devices not included in scan"; 5193 break; 5194 case PIM_NOINITIATOR: 5195 str = "initiator role not supported"; 5196 break; 5197 case PIM_NOBUSRESET: 5198 str = "user has disabled initial BUS RESET or" 5199 " controller is in target/mixed mode"; 5200 break; 5201 case PIM_NO_6_BYTE: 5202 str = "do not send 6-byte commands"; 5203 break; 5204 case PIM_SEQSCAN: 5205 str = "scan bus sequentially"; 5206 break; 5207 default: 5208 str = "unknown PIM bit set"; 5209 break; 5210 } 5211 fprintf(stdout, "%s\n", str); 5212 } 5213 5214 for (i = 1; i < 0xff; i = i << 1) { 5215 const char *str; 5216 5217 if ((i & cpi->target_sprt) == 0) 5218 continue; 5219 5220 fprintf(stdout, "%s supports ", adapter_str); 5221 switch(i) { 5222 case PIT_PROCESSOR: 5223 str = "target mode processor mode"; 5224 break; 5225 case PIT_PHASE: 5226 str = "target mode phase cog. mode"; 5227 break; 5228 case PIT_DISCONNECT: 5229 str = "disconnects in target mode"; 5230 break; 5231 case PIT_TERM_IO: 5232 str = "terminate I/O message in target mode"; 5233 break; 5234 case PIT_GRP_6: 5235 str = "group 6 commands in target mode"; 5236 break; 5237 case PIT_GRP_7: 5238 str = "group 7 commands in target mode"; 5239 break; 5240 default: 5241 str = "unknown PIT bit set"; 5242 break; 5243 } 5244 5245 fprintf(stdout, "%s\n", str); 5246 } 5247 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str, 5248 cpi->hba_eng_cnt); 5249 fprintf(stdout, "%s maximum target: %d\n", adapter_str, 5250 cpi->max_target); 5251 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str, 5252 cpi->max_lun); 5253 fprintf(stdout, "%s highest path ID in subsystem: %d\n", 5254 adapter_str, cpi->hpath_id); 5255 fprintf(stdout, "%s initiator ID: %d\n", adapter_str, 5256 cpi->initiator_id); 5257 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid); 5258 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid); 5259 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n", 5260 adapter_str, cpi->hba_vendor); 5261 fprintf(stdout, "%s HBA device ID: 0x%04x\n", 5262 adapter_str, cpi->hba_device); 5263 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n", 5264 adapter_str, cpi->hba_subvendor); 5265 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n", 5266 adapter_str, cpi->hba_subdevice); 5267 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id); 5268 fprintf(stdout, "%s base transfer speed: ", adapter_str); 5269 if (cpi->base_transfer_speed > 1000) 5270 fprintf(stdout, "%d.%03dMB/sec\n", 5271 cpi->base_transfer_speed / 1000, 5272 cpi->base_transfer_speed % 1000); 5273 else 5274 fprintf(stdout, "%dKB/sec\n", 5275 (cpi->base_transfer_speed % 1000) * 1000); 5276 fprintf(stdout, "%s maximum transfer size: %u bytes\n", 5277 adapter_str, cpi->maxio); 5278} 5279 5280static int 5281get_print_cts(struct cam_device *device, int user_settings, int quiet, 5282 struct ccb_trans_settings *cts) 5283{ 5284 int retval; 5285 union ccb *ccb; 5286 5287 retval = 0; 5288 ccb = cam_getccb(device); 5289 5290 if (ccb == NULL) { 5291 warnx("get_print_cts: error allocating ccb"); 5292 return(1); 5293 } 5294 5295 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); 5296 5297 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 5298 5299 if (user_settings == 0) 5300 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS; 5301 else 5302 ccb->cts.type = CTS_TYPE_USER_SETTINGS; 5303 5304 if (cam_send_ccb(device, ccb) < 0) { 5305 perror("error sending XPT_GET_TRAN_SETTINGS CCB"); 5306 if (arglist & CAM_ARG_VERBOSE) 5307 cam_error_print(device, ccb, CAM_ESF_ALL, 5308 CAM_EPF_ALL, stderr); 5309 retval = 1; 5310 goto get_print_cts_bailout; 5311 } 5312 5313 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5314 warnx("XPT_GET_TRANS_SETTINGS CCB failed"); 5315 if (arglist & CAM_ARG_VERBOSE) 5316 cam_error_print(device, ccb, CAM_ESF_ALL, 5317 CAM_EPF_ALL, stderr); 5318 retval = 1; 5319 goto get_print_cts_bailout; 5320 } 5321 5322 if (quiet == 0) 5323 cts_print(device, &ccb->cts); 5324 5325 if (cts != NULL) 5326 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings)); 5327 5328get_print_cts_bailout: 5329 5330 cam_freeccb(ccb); 5331 5332 return(retval); 5333} 5334 5335static int 5336ratecontrol(struct cam_device *device, int retry_count, int timeout, 5337 int argc, char **argv, char *combinedopt) 5338{ 5339 int c; 5340 union ccb *ccb; 5341 int user_settings = 0; 5342 int retval = 0; 5343 int disc_enable = -1, tag_enable = -1; 5344 int mode = -1; 5345 int offset = -1; 5346 double syncrate = -1; 5347 int bus_width = -1; 5348 int quiet = 0; 5349 int change_settings = 0, send_tur = 0; 5350 struct ccb_pathinq cpi; 5351 5352 ccb = cam_getccb(device); 5353 if (ccb == NULL) { 5354 warnx("ratecontrol: error allocating ccb"); 5355 return(1); 5356 } 5357 while ((c = getopt(argc, argv, combinedopt)) != -1) { 5358 switch(c){ 5359 case 'a': 5360 send_tur = 1; 5361 break; 5362 case 'c': 5363 user_settings = 0; 5364 break; 5365 case 'D': 5366 if (strncasecmp(optarg, "enable", 6) == 0) 5367 disc_enable = 1; 5368 else if (strncasecmp(optarg, "disable", 7) == 0) 5369 disc_enable = 0; 5370 else { 5371 warnx("-D argument \"%s\" is unknown", optarg); 5372 retval = 1; 5373 goto ratecontrol_bailout; 5374 } 5375 change_settings = 1; 5376 break; 5377 case 'M': 5378 mode = ata_string2mode(optarg); 5379 if (mode < 0) { 5380 warnx("unknown mode '%s'", optarg); 5381 retval = 1; 5382 goto ratecontrol_bailout; 5383 } 5384 change_settings = 1; 5385 break; 5386 case 'O': 5387 offset = strtol(optarg, NULL, 0); 5388 if (offset < 0) { 5389 warnx("offset value %d is < 0", offset); 5390 retval = 1; 5391 goto ratecontrol_bailout; 5392 } 5393 change_settings = 1; 5394 break; 5395 case 'q': 5396 quiet++; 5397 break; 5398 case 'R': 5399 syncrate = atof(optarg); 5400 if (syncrate < 0) { 5401 warnx("sync rate %f is < 0", syncrate); 5402 retval = 1; 5403 goto ratecontrol_bailout; 5404 } 5405 change_settings = 1; 5406 break; 5407 case 'T': 5408 if (strncasecmp(optarg, "enable", 6) == 0) 5409 tag_enable = 1; 5410 else if (strncasecmp(optarg, "disable", 7) == 0) 5411 tag_enable = 0; 5412 else { 5413 warnx("-T argument \"%s\" is unknown", optarg); 5414 retval = 1; 5415 goto ratecontrol_bailout; 5416 } 5417 change_settings = 1; 5418 break; 5419 case 'U': 5420 user_settings = 1; 5421 break; 5422 case 'W': 5423 bus_width = strtol(optarg, NULL, 0); 5424 if (bus_width < 0) { 5425 warnx("bus width %d is < 0", bus_width); 5426 retval = 1; 5427 goto ratecontrol_bailout; 5428 } 5429 change_settings = 1; 5430 break; 5431 default: 5432 break; 5433 } 5434 } 5435 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi); 5436 /* 5437 * Grab path inquiry information, so we can determine whether 5438 * or not the initiator is capable of the things that the user 5439 * requests. 5440 */ 5441 ccb->ccb_h.func_code = XPT_PATH_INQ; 5442 if (cam_send_ccb(device, ccb) < 0) { 5443 perror("error sending XPT_PATH_INQ CCB"); 5444 if (arglist & CAM_ARG_VERBOSE) { 5445 cam_error_print(device, ccb, CAM_ESF_ALL, 5446 CAM_EPF_ALL, stderr); 5447 } 5448 retval = 1; 5449 goto ratecontrol_bailout; 5450 } 5451 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5452 warnx("XPT_PATH_INQ CCB failed"); 5453 if (arglist & CAM_ARG_VERBOSE) { 5454 cam_error_print(device, ccb, CAM_ESF_ALL, 5455 CAM_EPF_ALL, stderr); 5456 } 5457 retval = 1; 5458 goto ratecontrol_bailout; 5459 } 5460 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq)); 5461 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); 5462 if (quiet == 0) { 5463 fprintf(stdout, "%s parameters:\n", 5464 user_settings ? "User" : "Current"); 5465 } 5466 retval = get_print_cts(device, user_settings, quiet, &ccb->cts); 5467 if (retval != 0) 5468 goto ratecontrol_bailout; 5469 5470 if (arglist & CAM_ARG_VERBOSE) 5471 cpi_print(&cpi); 5472 5473 if (change_settings) { 5474 int didsettings = 0; 5475 struct ccb_trans_settings_spi *spi = NULL; 5476 struct ccb_trans_settings_pata *pata = NULL; 5477 struct ccb_trans_settings_sata *sata = NULL; 5478 struct ccb_trans_settings_ata *ata = NULL; 5479 struct ccb_trans_settings_scsi *scsi = NULL; 5480 5481 if (ccb->cts.transport == XPORT_SPI) 5482 spi = &ccb->cts.xport_specific.spi; 5483 if (ccb->cts.transport == XPORT_ATA) 5484 pata = &ccb->cts.xport_specific.ata; 5485 if (ccb->cts.transport == XPORT_SATA) 5486 sata = &ccb->cts.xport_specific.sata; 5487 if (ccb->cts.protocol == PROTO_ATA) 5488 ata = &ccb->cts.proto_specific.ata; 5489 if (ccb->cts.protocol == PROTO_SCSI) 5490 scsi = &ccb->cts.proto_specific.scsi; 5491 ccb->cts.xport_specific.valid = 0; 5492 ccb->cts.proto_specific.valid = 0; 5493 if (spi && disc_enable != -1) { 5494 spi->valid |= CTS_SPI_VALID_DISC; 5495 if (disc_enable == 0) 5496 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 5497 else 5498 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 5499 didsettings++; 5500 } 5501 if (tag_enable != -1) { 5502 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) { 5503 warnx("HBA does not support tagged queueing, " 5504 "so you cannot modify tag settings"); 5505 retval = 1; 5506 goto ratecontrol_bailout; 5507 } 5508 if (ata) { 5509 ata->valid |= CTS_SCSI_VALID_TQ; 5510 if (tag_enable == 0) 5511 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB; 5512 else 5513 ata->flags |= CTS_ATA_FLAGS_TAG_ENB; 5514 didsettings++; 5515 } else if (scsi) { 5516 scsi->valid |= CTS_SCSI_VALID_TQ; 5517 if (tag_enable == 0) 5518 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 5519 else 5520 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 5521 didsettings++; 5522 } 5523 } 5524 if (spi && offset != -1) { 5525 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5526 warnx("HBA is not capable of changing offset"); 5527 retval = 1; 5528 goto ratecontrol_bailout; 5529 } 5530 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 5531 spi->sync_offset = offset; 5532 didsettings++; 5533 } 5534 if (spi && syncrate != -1) { 5535 int prelim_sync_period; 5536 5537 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5538 warnx("HBA is not capable of changing " 5539 "transfer rates"); 5540 retval = 1; 5541 goto ratecontrol_bailout; 5542 } 5543 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 5544 /* 5545 * The sync rate the user gives us is in MHz. 5546 * We need to translate it into KHz for this 5547 * calculation. 5548 */ 5549 syncrate *= 1000; 5550 /* 5551 * Next, we calculate a "preliminary" sync period 5552 * in tenths of a nanosecond. 5553 */ 5554 if (syncrate == 0) 5555 prelim_sync_period = 0; 5556 else 5557 prelim_sync_period = 10000000 / syncrate; 5558 spi->sync_period = 5559 scsi_calc_syncparam(prelim_sync_period); 5560 didsettings++; 5561 } 5562 if (sata && syncrate != -1) { 5563 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5564 warnx("HBA is not capable of changing " 5565 "transfer rates"); 5566 retval = 1; 5567 goto ratecontrol_bailout; 5568 } 5569 if (!user_settings) { 5570 warnx("You can modify only user rate " 5571 "settings for SATA"); 5572 retval = 1; 5573 goto ratecontrol_bailout; 5574 } 5575 sata->revision = ata_speed2revision(syncrate * 100); 5576 if (sata->revision < 0) { 5577 warnx("Invalid rate %f", syncrate); 5578 retval = 1; 5579 goto ratecontrol_bailout; 5580 } 5581 sata->valid |= CTS_SATA_VALID_REVISION; 5582 didsettings++; 5583 } 5584 if ((pata || sata) && mode != -1) { 5585 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5586 warnx("HBA is not capable of changing " 5587 "transfer rates"); 5588 retval = 1; 5589 goto ratecontrol_bailout; 5590 } 5591 if (!user_settings) { 5592 warnx("You can modify only user mode " 5593 "settings for ATA/SATA"); 5594 retval = 1; 5595 goto ratecontrol_bailout; 5596 } 5597 if (pata) { 5598 pata->mode = mode; 5599 pata->valid |= CTS_ATA_VALID_MODE; 5600 } else { 5601 sata->mode = mode; 5602 sata->valid |= CTS_SATA_VALID_MODE; 5603 } 5604 didsettings++; 5605 } 5606 /* 5607 * The bus_width argument goes like this: 5608 * 0 == 8 bit 5609 * 1 == 16 bit 5610 * 2 == 32 bit 5611 * Therefore, if you shift the number of bits given on the 5612 * command line right by 4, you should get the correct 5613 * number. 5614 */ 5615 if (spi && bus_width != -1) { 5616 /* 5617 * We might as well validate things here with a 5618 * decipherable error message, rather than what 5619 * will probably be an indecipherable error message 5620 * by the time it gets back to us. 5621 */ 5622 if ((bus_width == 16) 5623 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) { 5624 warnx("HBA does not support 16 bit bus width"); 5625 retval = 1; 5626 goto ratecontrol_bailout; 5627 } else if ((bus_width == 32) 5628 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) { 5629 warnx("HBA does not support 32 bit bus width"); 5630 retval = 1; 5631 goto ratecontrol_bailout; 5632 } else if ((bus_width != 8) 5633 && (bus_width != 16) 5634 && (bus_width != 32)) { 5635 warnx("Invalid bus width %d", bus_width); 5636 retval = 1; 5637 goto ratecontrol_bailout; 5638 } 5639 spi->valid |= CTS_SPI_VALID_BUS_WIDTH; 5640 spi->bus_width = bus_width >> 4; 5641 didsettings++; 5642 } 5643 if (didsettings == 0) { 5644 goto ratecontrol_bailout; 5645 } 5646 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 5647 if (cam_send_ccb(device, ccb) < 0) { 5648 perror("error sending XPT_SET_TRAN_SETTINGS CCB"); 5649 if (arglist & CAM_ARG_VERBOSE) { 5650 cam_error_print(device, ccb, CAM_ESF_ALL, 5651 CAM_EPF_ALL, stderr); 5652 } 5653 retval = 1; 5654 goto ratecontrol_bailout; 5655 } 5656 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5657 warnx("XPT_SET_TRANS_SETTINGS CCB failed"); 5658 if (arglist & CAM_ARG_VERBOSE) { 5659 cam_error_print(device, ccb, CAM_ESF_ALL, 5660 CAM_EPF_ALL, stderr); 5661 } 5662 retval = 1; 5663 goto ratecontrol_bailout; 5664 } 5665 } 5666 if (send_tur) { 5667 retval = testunitready(device, retry_count, timeout, 5668 (arglist & CAM_ARG_VERBOSE) ? 0 : 1); 5669 /* 5670 * If the TUR didn't succeed, just bail. 5671 */ 5672 if (retval != 0) { 5673 if (quiet == 0) 5674 fprintf(stderr, "Test Unit Ready failed\n"); 5675 goto ratecontrol_bailout; 5676 } 5677 } 5678 if ((change_settings || send_tur) && !quiet && 5679 (ccb->cts.transport == XPORT_ATA || 5680 ccb->cts.transport == XPORT_SATA || send_tur)) { 5681 fprintf(stdout, "New parameters:\n"); 5682 retval = get_print_cts(device, user_settings, 0, NULL); 5683 } 5684 5685ratecontrol_bailout: 5686 cam_freeccb(ccb); 5687 return(retval); 5688} 5689 5690static int 5691scsiformat(struct cam_device *device, int argc, char **argv, 5692 char *combinedopt, int retry_count, int timeout) 5693{ 5694 union ccb *ccb; 5695 int c; 5696 int ycount = 0, quiet = 0; 5697 int error = 0, retval = 0; 5698 int use_timeout = 10800 * 1000; 5699 int immediate = 1; 5700 struct format_defect_list_header fh; 5701 u_int8_t *data_ptr = NULL; 5702 u_int32_t dxfer_len = 0; 5703 u_int8_t byte2 = 0; 5704 int num_warnings = 0; 5705 int reportonly = 0; 5706 5707 ccb = cam_getccb(device); 5708 5709 if (ccb == NULL) { 5710 warnx("scsiformat: error allocating ccb"); 5711 return(1); 5712 } 5713 5714 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 5715 5716 while ((c = getopt(argc, argv, combinedopt)) != -1) { 5717 switch(c) { 5718 case 'q': 5719 quiet++; 5720 break; 5721 case 'r': 5722 reportonly = 1; 5723 break; 5724 case 'w': 5725 immediate = 0; 5726 break; 5727 case 'y': 5728 ycount++; 5729 break; 5730 } 5731 } 5732 5733 if (reportonly) 5734 goto doreport; 5735 5736 if (quiet == 0) { 5737 fprintf(stdout, "You are about to REMOVE ALL DATA from the " 5738 "following device:\n"); 5739 5740 error = scsidoinquiry(device, argc, argv, combinedopt, 5741 retry_count, timeout); 5742 5743 if (error != 0) { 5744 warnx("scsiformat: error sending inquiry"); 5745 goto scsiformat_bailout; 5746 } 5747 } 5748 5749 if (ycount == 0) { 5750 if (!get_confirmation()) { 5751 error = 1; 5752 goto scsiformat_bailout; 5753 } 5754 } 5755 5756 if (timeout != 0) 5757 use_timeout = timeout; 5758 5759 if (quiet == 0) { 5760 fprintf(stdout, "Current format timeout is %d seconds\n", 5761 use_timeout / 1000); 5762 } 5763 5764 /* 5765 * If the user hasn't disabled questions and didn't specify a 5766 * timeout on the command line, ask them if they want the current 5767 * timeout. 5768 */ 5769 if ((ycount == 0) 5770 && (timeout == 0)) { 5771 char str[1024]; 5772 int new_timeout = 0; 5773 5774 fprintf(stdout, "Enter new timeout in seconds or press\n" 5775 "return to keep the current timeout [%d] ", 5776 use_timeout / 1000); 5777 5778 if (fgets(str, sizeof(str), stdin) != NULL) { 5779 if (str[0] != '\0') 5780 new_timeout = atoi(str); 5781 } 5782 5783 if (new_timeout != 0) { 5784 use_timeout = new_timeout * 1000; 5785 fprintf(stdout, "Using new timeout value %d\n", 5786 use_timeout / 1000); 5787 } 5788 } 5789 5790 /* 5791 * Keep this outside the if block below to silence any unused 5792 * variable warnings. 5793 */ 5794 bzero(&fh, sizeof(fh)); 5795 5796 /* 5797 * If we're in immediate mode, we've got to include the format 5798 * header 5799 */ 5800 if (immediate != 0) { 5801 fh.byte2 = FU_DLH_IMMED; 5802 data_ptr = (u_int8_t *)&fh; 5803 dxfer_len = sizeof(fh); 5804 byte2 = FU_FMT_DATA; 5805 } else if (quiet == 0) { 5806 fprintf(stdout, "Formatting..."); 5807 fflush(stdout); 5808 } 5809 5810 scsi_format_unit(&ccb->csio, 5811 /* retries */ retry_count, 5812 /* cbfcnp */ NULL, 5813 /* tag_action */ MSG_SIMPLE_Q_TAG, 5814 /* byte2 */ byte2, 5815 /* ileave */ 0, 5816 /* data_ptr */ data_ptr, 5817 /* dxfer_len */ dxfer_len, 5818 /* sense_len */ SSD_FULL_SIZE, 5819 /* timeout */ use_timeout); 5820 5821 /* Disable freezing the device queue */ 5822 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 5823 5824 if (arglist & CAM_ARG_ERR_RECOVER) 5825 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 5826 5827 if (((retval = cam_send_ccb(device, ccb)) < 0) 5828 || ((immediate == 0) 5829 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) { 5830 const char errstr[] = "error sending format command"; 5831 5832 if (retval < 0) 5833 warn(errstr); 5834 else 5835 warnx(errstr); 5836 5837 if (arglist & CAM_ARG_VERBOSE) { 5838 cam_error_print(device, ccb, CAM_ESF_ALL, 5839 CAM_EPF_ALL, stderr); 5840 } 5841 error = 1; 5842 goto scsiformat_bailout; 5843 } 5844 5845 /* 5846 * If we ran in non-immediate mode, we already checked for errors 5847 * above and printed out any necessary information. If we're in 5848 * immediate mode, we need to loop through and get status 5849 * information periodically. 5850 */ 5851 if (immediate == 0) { 5852 if (quiet == 0) { 5853 fprintf(stdout, "Format Complete\n"); 5854 } 5855 goto scsiformat_bailout; 5856 } 5857 5858doreport: 5859 do { 5860 cam_status status; 5861 5862 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 5863 5864 /* 5865 * There's really no need to do error recovery or 5866 * retries here, since we're just going to sit in a 5867 * loop and wait for the device to finish formatting. 5868 */ 5869 scsi_test_unit_ready(&ccb->csio, 5870 /* retries */ 0, 5871 /* cbfcnp */ NULL, 5872 /* tag_action */ MSG_SIMPLE_Q_TAG, 5873 /* sense_len */ SSD_FULL_SIZE, 5874 /* timeout */ 5000); 5875 5876 /* Disable freezing the device queue */ 5877 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 5878 5879 retval = cam_send_ccb(device, ccb); 5880 5881 /* 5882 * If we get an error from the ioctl, bail out. SCSI 5883 * errors are expected. 5884 */ 5885 if (retval < 0) { 5886 warn("error sending CAMIOCOMMAND ioctl"); 5887 if (arglist & CAM_ARG_VERBOSE) { 5888 cam_error_print(device, ccb, CAM_ESF_ALL, 5889 CAM_EPF_ALL, stderr); 5890 } 5891 error = 1; 5892 goto scsiformat_bailout; 5893 } 5894 5895 status = ccb->ccb_h.status & CAM_STATUS_MASK; 5896 5897 if ((status != CAM_REQ_CMP) 5898 && (status == CAM_SCSI_STATUS_ERROR) 5899 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 5900 struct scsi_sense_data *sense; 5901 int error_code, sense_key, asc, ascq; 5902 5903 sense = &ccb->csio.sense_data; 5904 scsi_extract_sense_len(sense, ccb->csio.sense_len - 5905 ccb->csio.sense_resid, &error_code, &sense_key, 5906 &asc, &ascq, /*show_errors*/ 1); 5907 5908 /* 5909 * According to the SCSI-2 and SCSI-3 specs, a 5910 * drive that is in the middle of a format should 5911 * return NOT READY with an ASC of "logical unit 5912 * not ready, format in progress". The sense key 5913 * specific bytes will then be a progress indicator. 5914 */ 5915 if ((sense_key == SSD_KEY_NOT_READY) 5916 && (asc == 0x04) && (ascq == 0x04)) { 5917 uint8_t sks[3]; 5918 5919 if ((scsi_get_sks(sense, ccb->csio.sense_len - 5920 ccb->csio.sense_resid, sks) == 0) 5921 && (quiet == 0)) { 5922 int val; 5923 u_int64_t percentage; 5924 5925 val = scsi_2btoul(&sks[1]); 5926 percentage = 10000 * val; 5927 5928 fprintf(stdout, 5929 "\rFormatting: %ju.%02u %% " 5930 "(%d/%d) done", 5931 (uintmax_t)(percentage / 5932 (0x10000 * 100)), 5933 (unsigned)((percentage / 5934 0x10000) % 100), 5935 val, 0x10000); 5936 fflush(stdout); 5937 } else if ((quiet == 0) 5938 && (++num_warnings <= 1)) { 5939 warnx("Unexpected SCSI Sense Key " 5940 "Specific value returned " 5941 "during format:"); 5942 scsi_sense_print(device, &ccb->csio, 5943 stderr); 5944 warnx("Unable to print status " 5945 "information, but format will " 5946 "proceed."); 5947 warnx("will exit when format is " 5948 "complete"); 5949 } 5950 sleep(1); 5951 } else { 5952 warnx("Unexpected SCSI error during format"); 5953 cam_error_print(device, ccb, CAM_ESF_ALL, 5954 CAM_EPF_ALL, stderr); 5955 error = 1; 5956 goto scsiformat_bailout; 5957 } 5958 5959 } else if (status != CAM_REQ_CMP) { 5960 warnx("Unexpected CAM status %#x", status); 5961 if (arglist & CAM_ARG_VERBOSE) 5962 cam_error_print(device, ccb, CAM_ESF_ALL, 5963 CAM_EPF_ALL, stderr); 5964 error = 1; 5965 goto scsiformat_bailout; 5966 } 5967 5968 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); 5969 5970 if (quiet == 0) 5971 fprintf(stdout, "\nFormat Complete\n"); 5972 5973scsiformat_bailout: 5974 5975 cam_freeccb(ccb); 5976 5977 return(error); 5978} 5979 5980static int 5981scsisanitize(struct cam_device *device, int argc, char **argv, 5982 char *combinedopt, int retry_count, int timeout) 5983{ 5984 union ccb *ccb; 5985 u_int8_t action = 0; 5986 int c; 5987 int ycount = 0, quiet = 0; 5988 int error = 0, retval = 0; 5989 int use_timeout = 10800 * 1000; 5990 int immediate = 1; 5991 int invert = 0; 5992 int passes = 0; 5993 int ause = 0; 5994 int fd = -1; 5995 const char *pattern = NULL; 5996 u_int8_t *data_ptr = NULL; 5997 u_int32_t dxfer_len = 0; 5998 u_int8_t byte2 = 0; 5999 int num_warnings = 0; 6000 int reportonly = 0; 6001 6002 ccb = cam_getccb(device); 6003 6004 if (ccb == NULL) { 6005 warnx("scsisanitize: error allocating ccb"); 6006 return(1); 6007 } 6008 6009 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6010 6011 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6012 switch(c) { 6013 case 'a': 6014 if (strcasecmp(optarg, "overwrite") == 0) 6015 action = SSZ_SERVICE_ACTION_OVERWRITE; 6016 else if (strcasecmp(optarg, "block") == 0) 6017 action = SSZ_SERVICE_ACTION_BLOCK_ERASE; 6018 else if (strcasecmp(optarg, "crypto") == 0) 6019 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE; 6020 else if (strcasecmp(optarg, "exitfailure") == 0) 6021 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE; 6022 else { 6023 warnx("invalid service operation \"%s\"", 6024 optarg); 6025 error = 1; 6026 goto scsisanitize_bailout; 6027 } 6028 break; 6029 case 'c': 6030 passes = strtol(optarg, NULL, 0); 6031 if (passes < 1 || passes > 31) { 6032 warnx("invalid passes value %d", passes); 6033 error = 1; 6034 goto scsisanitize_bailout; 6035 } 6036 break; 6037 case 'I': 6038 invert = 1; 6039 break; 6040 case 'P': 6041 pattern = optarg; 6042 break; 6043 case 'q': 6044 quiet++; 6045 break; 6046 case 'U': 6047 ause = 1; 6048 break; 6049 case 'r': 6050 reportonly = 1; 6051 break; 6052 case 'w': 6053 immediate = 0; 6054 break; 6055 case 'y': 6056 ycount++; 6057 break; 6058 } 6059 } 6060 6061 if (reportonly) 6062 goto doreport; 6063 6064 if (action == 0) { 6065 warnx("an action is required"); 6066 error = 1; 6067 goto scsisanitize_bailout; 6068 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) { 6069 struct scsi_sanitize_parameter_list *pl; 6070 struct stat sb; 6071 ssize_t sz, amt; 6072 6073 if (pattern == NULL) { 6074 warnx("overwrite action requires -P argument"); 6075 error = 1; 6076 goto scsisanitize_bailout; 6077 } 6078 fd = open(pattern, O_RDONLY); 6079 if (fd < 0) { 6080 warn("cannot open pattern file %s", pattern); 6081 error = 1; 6082 goto scsisanitize_bailout; 6083 } 6084 if (fstat(fd, &sb) < 0) { 6085 warn("cannot stat pattern file %s", pattern); 6086 error = 1; 6087 goto scsisanitize_bailout; 6088 } 6089 sz = sb.st_size; 6090 if (sz > SSZPL_MAX_PATTERN_LENGTH) { 6091 warnx("pattern file size exceeds maximum value %d", 6092 SSZPL_MAX_PATTERN_LENGTH); 6093 error = 1; 6094 goto scsisanitize_bailout; 6095 } 6096 dxfer_len = sizeof(*pl) + sz; 6097 data_ptr = calloc(1, dxfer_len); 6098 if (data_ptr == NULL) { 6099 warnx("cannot allocate parameter list buffer"); 6100 error = 1; 6101 goto scsisanitize_bailout; 6102 } 6103 6104 amt = read(fd, data_ptr + sizeof(*pl), sz); 6105 if (amt < 0) { 6106 warn("cannot read pattern file"); 6107 error = 1; 6108 goto scsisanitize_bailout; 6109 } else if (amt != sz) { 6110 warnx("short pattern file read"); 6111 error = 1; 6112 goto scsisanitize_bailout; 6113 } 6114 6115 pl = (struct scsi_sanitize_parameter_list *)data_ptr; 6116 if (passes == 0) 6117 pl->byte1 = 1; 6118 else 6119 pl->byte1 = passes; 6120 if (invert != 0) 6121 pl->byte1 |= SSZPL_INVERT; 6122 scsi_ulto2b(sz, pl->length); 6123 } else { 6124 const char *arg; 6125 6126 if (passes != 0) 6127 arg = "-c"; 6128 else if (invert != 0) 6129 arg = "-I"; 6130 else if (pattern != NULL) 6131 arg = "-P"; 6132 else 6133 arg = NULL; 6134 if (arg != NULL) { 6135 warnx("%s argument only valid with overwrite " 6136 "operation", arg); 6137 error = 1; 6138 goto scsisanitize_bailout; 6139 } 6140 } 6141 6142 if (quiet == 0) { 6143 fprintf(stdout, "You are about to REMOVE ALL DATA from the " 6144 "following device:\n"); 6145 6146 error = scsidoinquiry(device, argc, argv, combinedopt, 6147 retry_count, timeout); 6148 6149 if (error != 0) { 6150 warnx("scsisanitize: error sending inquiry"); 6151 goto scsisanitize_bailout; 6152 } 6153 } 6154 6155 if (ycount == 0) { 6156 if (!get_confirmation()) { 6157 error = 1; 6158 goto scsisanitize_bailout; 6159 } 6160 } 6161 6162 if (timeout != 0) 6163 use_timeout = timeout; 6164 6165 if (quiet == 0) { 6166 fprintf(stdout, "Current sanitize timeout is %d seconds\n", 6167 use_timeout / 1000); 6168 } 6169 6170 /* 6171 * If the user hasn't disabled questions and didn't specify a 6172 * timeout on the command line, ask them if they want the current 6173 * timeout. 6174 */ 6175 if ((ycount == 0) 6176 && (timeout == 0)) { 6177 char str[1024]; 6178 int new_timeout = 0; 6179 6180 fprintf(stdout, "Enter new timeout in seconds or press\n" 6181 "return to keep the current timeout [%d] ", 6182 use_timeout / 1000); 6183 6184 if (fgets(str, sizeof(str), stdin) != NULL) { 6185 if (str[0] != '\0') 6186 new_timeout = atoi(str); 6187 } 6188 6189 if (new_timeout != 0) { 6190 use_timeout = new_timeout * 1000; 6191 fprintf(stdout, "Using new timeout value %d\n", 6192 use_timeout / 1000); 6193 } 6194 } 6195 6196 byte2 = action; 6197 if (ause != 0) 6198 byte2 |= SSZ_UNRESTRICTED_EXIT; 6199 if (immediate != 0) 6200 byte2 |= SSZ_IMMED; 6201 6202 scsi_sanitize(&ccb->csio, 6203 /* retries */ retry_count, 6204 /* cbfcnp */ NULL, 6205 /* tag_action */ MSG_SIMPLE_Q_TAG, 6206 /* byte2 */ byte2, 6207 /* control */ 0, 6208 /* data_ptr */ data_ptr, 6209 /* dxfer_len */ dxfer_len, 6210 /* sense_len */ SSD_FULL_SIZE, 6211 /* timeout */ use_timeout); 6212 6213 /* Disable freezing the device queue */ 6214 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6215 6216 if (arglist & CAM_ARG_ERR_RECOVER) 6217 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6218 6219 if (cam_send_ccb(device, ccb) < 0) { 6220 warn("error sending sanitize command"); 6221 error = 1; 6222 goto scsisanitize_bailout; 6223 } 6224 6225 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6226 struct scsi_sense_data *sense; 6227 int error_code, sense_key, asc, ascq; 6228 6229 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 6230 CAM_SCSI_STATUS_ERROR) { 6231 sense = &ccb->csio.sense_data; 6232 scsi_extract_sense_len(sense, ccb->csio.sense_len - 6233 ccb->csio.sense_resid, &error_code, &sense_key, 6234 &asc, &ascq, /*show_errors*/ 1); 6235 6236 if (sense_key == SSD_KEY_ILLEGAL_REQUEST && 6237 asc == 0x20 && ascq == 0x00) 6238 warnx("sanitize is not supported by " 6239 "this device"); 6240 else 6241 warnx("error sanitizing this device"); 6242 } else 6243 warnx("error sanitizing this device"); 6244 6245 if (arglist & CAM_ARG_VERBOSE) { 6246 cam_error_print(device, ccb, CAM_ESF_ALL, 6247 CAM_EPF_ALL, stderr); 6248 } 6249 error = 1; 6250 goto scsisanitize_bailout; 6251 } 6252 6253 /* 6254 * If we ran in non-immediate mode, we already checked for errors 6255 * above and printed out any necessary information. If we're in 6256 * immediate mode, we need to loop through and get status 6257 * information periodically. 6258 */ 6259 if (immediate == 0) { 6260 if (quiet == 0) { 6261 fprintf(stdout, "Sanitize Complete\n"); 6262 } 6263 goto scsisanitize_bailout; 6264 } 6265 6266doreport: 6267 do { 6268 cam_status status; 6269 6270 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6271 6272 /* 6273 * There's really no need to do error recovery or 6274 * retries here, since we're just going to sit in a 6275 * loop and wait for the device to finish sanitizing. 6276 */ 6277 scsi_test_unit_ready(&ccb->csio, 6278 /* retries */ 0, 6279 /* cbfcnp */ NULL, 6280 /* tag_action */ MSG_SIMPLE_Q_TAG, 6281 /* sense_len */ SSD_FULL_SIZE, 6282 /* timeout */ 5000); 6283 6284 /* Disable freezing the device queue */ 6285 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6286 6287 retval = cam_send_ccb(device, ccb); 6288 6289 /* 6290 * If we get an error from the ioctl, bail out. SCSI 6291 * errors are expected. 6292 */ 6293 if (retval < 0) { 6294 warn("error sending CAMIOCOMMAND ioctl"); 6295 if (arglist & CAM_ARG_VERBOSE) { 6296 cam_error_print(device, ccb, CAM_ESF_ALL, 6297 CAM_EPF_ALL, stderr); 6298 } 6299 error = 1; 6300 goto scsisanitize_bailout; 6301 } 6302 6303 status = ccb->ccb_h.status & CAM_STATUS_MASK; 6304 6305 if ((status != CAM_REQ_CMP) 6306 && (status == CAM_SCSI_STATUS_ERROR) 6307 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 6308 struct scsi_sense_data *sense; 6309 int error_code, sense_key, asc, ascq; 6310 6311 sense = &ccb->csio.sense_data; 6312 scsi_extract_sense_len(sense, ccb->csio.sense_len - 6313 ccb->csio.sense_resid, &error_code, &sense_key, 6314 &asc, &ascq, /*show_errors*/ 1); 6315 6316 /* 6317 * According to the SCSI-3 spec, a drive that is in the 6318 * middle of a sanitize should return NOT READY with an 6319 * ASC of "logical unit not ready, sanitize in 6320 * progress". The sense key specific bytes will then 6321 * be a progress indicator. 6322 */ 6323 if ((sense_key == SSD_KEY_NOT_READY) 6324 && (asc == 0x04) && (ascq == 0x1b)) { 6325 uint8_t sks[3]; 6326 6327 if ((scsi_get_sks(sense, ccb->csio.sense_len - 6328 ccb->csio.sense_resid, sks) == 0) 6329 && (quiet == 0)) { 6330 int val; 6331 u_int64_t percentage; 6332 6333 val = scsi_2btoul(&sks[1]); 6334 percentage = 10000 * val; 6335 6336 fprintf(stdout, 6337 "\rSanitizing: %ju.%02u %% " 6338 "(%d/%d) done", 6339 (uintmax_t)(percentage / 6340 (0x10000 * 100)), 6341 (unsigned)((percentage / 6342 0x10000) % 100), 6343 val, 0x10000); 6344 fflush(stdout); 6345 } else if ((quiet == 0) 6346 && (++num_warnings <= 1)) { 6347 warnx("Unexpected SCSI Sense Key " 6348 "Specific value returned " 6349 "during sanitize:"); 6350 scsi_sense_print(device, &ccb->csio, 6351 stderr); 6352 warnx("Unable to print status " 6353 "information, but sanitze will " 6354 "proceed."); 6355 warnx("will exit when sanitize is " 6356 "complete"); 6357 } 6358 sleep(1); 6359 } else { 6360 warnx("Unexpected SCSI error during sanitize"); 6361 cam_error_print(device, ccb, CAM_ESF_ALL, 6362 CAM_EPF_ALL, stderr); 6363 error = 1; 6364 goto scsisanitize_bailout; 6365 } 6366 6367 } else if (status != CAM_REQ_CMP) { 6368 warnx("Unexpected CAM status %#x", status); 6369 if (arglist & CAM_ARG_VERBOSE) 6370 cam_error_print(device, ccb, CAM_ESF_ALL, 6371 CAM_EPF_ALL, stderr); 6372 error = 1; 6373 goto scsisanitize_bailout; 6374 } 6375 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); 6376 6377 if (quiet == 0) 6378 fprintf(stdout, "\nSanitize Complete\n"); 6379 6380scsisanitize_bailout: 6381 if (fd >= 0) 6382 close(fd); 6383 if (data_ptr != NULL) 6384 free(data_ptr); 6385 cam_freeccb(ccb); 6386 6387 return(error); 6388} 6389 6390static int 6391scsireportluns(struct cam_device *device, int argc, char **argv, 6392 char *combinedopt, int retry_count, int timeout) 6393{ 6394 union ccb *ccb; 6395 int c, countonly, lunsonly; 6396 struct scsi_report_luns_data *lundata; 6397 int alloc_len; 6398 uint8_t report_type; 6399 uint32_t list_len, i, j; 6400 int retval; 6401 6402 retval = 0; 6403 lundata = NULL; 6404 report_type = RPL_REPORT_DEFAULT; 6405 ccb = cam_getccb(device); 6406 6407 if (ccb == NULL) { 6408 warnx("%s: error allocating ccb", __func__); 6409 return (1); 6410 } 6411 6412 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6413 6414 countonly = 0; 6415 lunsonly = 0; 6416 6417 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6418 switch (c) { 6419 case 'c': 6420 countonly++; 6421 break; 6422 case 'l': 6423 lunsonly++; 6424 break; 6425 case 'r': 6426 if (strcasecmp(optarg, "default") == 0) 6427 report_type = RPL_REPORT_DEFAULT; 6428 else if (strcasecmp(optarg, "wellknown") == 0) 6429 report_type = RPL_REPORT_WELLKNOWN; 6430 else if (strcasecmp(optarg, "all") == 0) 6431 report_type = RPL_REPORT_ALL; 6432 else { 6433 warnx("%s: invalid report type \"%s\"", 6434 __func__, optarg); 6435 retval = 1; 6436 goto bailout; 6437 } 6438 break; 6439 default: 6440 break; 6441 } 6442 } 6443 6444 if ((countonly != 0) 6445 && (lunsonly != 0)) { 6446 warnx("%s: you can only specify one of -c or -l", __func__); 6447 retval = 1; 6448 goto bailout; 6449 } 6450 /* 6451 * According to SPC-4, the allocation length must be at least 16 6452 * bytes -- enough for the header and one LUN. 6453 */ 6454 alloc_len = sizeof(*lundata) + 8; 6455 6456retry: 6457 6458 lundata = malloc(alloc_len); 6459 6460 if (lundata == NULL) { 6461 warn("%s: error mallocing %d bytes", __func__, alloc_len); 6462 retval = 1; 6463 goto bailout; 6464 } 6465 6466 scsi_report_luns(&ccb->csio, 6467 /*retries*/ retry_count, 6468 /*cbfcnp*/ NULL, 6469 /*tag_action*/ MSG_SIMPLE_Q_TAG, 6470 /*select_report*/ report_type, 6471 /*rpl_buf*/ lundata, 6472 /*alloc_len*/ alloc_len, 6473 /*sense_len*/ SSD_FULL_SIZE, 6474 /*timeout*/ timeout ? timeout : 5000); 6475 6476 /* Disable freezing the device queue */ 6477 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6478 6479 if (arglist & CAM_ARG_ERR_RECOVER) 6480 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6481 6482 if (cam_send_ccb(device, ccb) < 0) { 6483 warn("error sending REPORT LUNS command"); 6484 6485 if (arglist & CAM_ARG_VERBOSE) 6486 cam_error_print(device, ccb, CAM_ESF_ALL, 6487 CAM_EPF_ALL, stderr); 6488 6489 retval = 1; 6490 goto bailout; 6491 } 6492 6493 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6494 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 6495 retval = 1; 6496 goto bailout; 6497 } 6498 6499 6500 list_len = scsi_4btoul(lundata->length); 6501 6502 /* 6503 * If we need to list the LUNs, and our allocation 6504 * length was too short, reallocate and retry. 6505 */ 6506 if ((countonly == 0) 6507 && (list_len > (alloc_len - sizeof(*lundata)))) { 6508 alloc_len = list_len + sizeof(*lundata); 6509 free(lundata); 6510 goto retry; 6511 } 6512 6513 if (lunsonly == 0) 6514 fprintf(stdout, "%u LUN%s found\n", list_len / 8, 6515 ((list_len / 8) > 1) ? "s" : ""); 6516 6517 if (countonly != 0) 6518 goto bailout; 6519 6520 for (i = 0; i < (list_len / 8); i++) { 6521 int no_more; 6522 6523 no_more = 0; 6524 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) { 6525 if (j != 0) 6526 fprintf(stdout, ","); 6527 switch (lundata->luns[i].lundata[j] & 6528 RPL_LUNDATA_ATYP_MASK) { 6529 case RPL_LUNDATA_ATYP_PERIPH: 6530 if ((lundata->luns[i].lundata[j] & 6531 RPL_LUNDATA_PERIPH_BUS_MASK) != 0) 6532 fprintf(stdout, "%d:", 6533 lundata->luns[i].lundata[j] & 6534 RPL_LUNDATA_PERIPH_BUS_MASK); 6535 else if ((j == 0) 6536 && ((lundata->luns[i].lundata[j+2] & 6537 RPL_LUNDATA_PERIPH_BUS_MASK) == 0)) 6538 no_more = 1; 6539 6540 fprintf(stdout, "%d", 6541 lundata->luns[i].lundata[j+1]); 6542 break; 6543 case RPL_LUNDATA_ATYP_FLAT: { 6544 uint8_t tmplun[2]; 6545 tmplun[0] = lundata->luns[i].lundata[j] & 6546 RPL_LUNDATA_FLAT_LUN_MASK; 6547 tmplun[1] = lundata->luns[i].lundata[j+1]; 6548 6549 fprintf(stdout, "%d", scsi_2btoul(tmplun)); 6550 no_more = 1; 6551 break; 6552 } 6553 case RPL_LUNDATA_ATYP_LUN: 6554 fprintf(stdout, "%d:%d:%d", 6555 (lundata->luns[i].lundata[j+1] & 6556 RPL_LUNDATA_LUN_BUS_MASK) >> 5, 6557 lundata->luns[i].lundata[j] & 6558 RPL_LUNDATA_LUN_TARG_MASK, 6559 lundata->luns[i].lundata[j+1] & 6560 RPL_LUNDATA_LUN_LUN_MASK); 6561 break; 6562 case RPL_LUNDATA_ATYP_EXTLUN: { 6563 int field_len_code, eam_code; 6564 6565 eam_code = lundata->luns[i].lundata[j] & 6566 RPL_LUNDATA_EXT_EAM_MASK; 6567 field_len_code = (lundata->luns[i].lundata[j] & 6568 RPL_LUNDATA_EXT_LEN_MASK) >> 4; 6569 6570 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK) 6571 && (field_len_code == 0x00)) { 6572 fprintf(stdout, "%d", 6573 lundata->luns[i].lundata[j+1]); 6574 } else if ((eam_code == 6575 RPL_LUNDATA_EXT_EAM_NOT_SPEC) 6576 && (field_len_code == 0x03)) { 6577 uint8_t tmp_lun[8]; 6578 6579 /* 6580 * This format takes up all 8 bytes. 6581 * If we aren't starting at offset 0, 6582 * that's a bug. 6583 */ 6584 if (j != 0) { 6585 fprintf(stdout, "Invalid " 6586 "offset %d for " 6587 "Extended LUN not " 6588 "specified format", j); 6589 no_more = 1; 6590 break; 6591 } 6592 bzero(tmp_lun, sizeof(tmp_lun)); 6593 bcopy(&lundata->luns[i].lundata[j+1], 6594 &tmp_lun[1], sizeof(tmp_lun) - 1); 6595 fprintf(stdout, "%#jx", 6596 (intmax_t)scsi_8btou64(tmp_lun)); 6597 no_more = 1; 6598 } else { 6599 fprintf(stderr, "Unknown Extended LUN" 6600 "Address method %#x, length " 6601 "code %#x", eam_code, 6602 field_len_code); 6603 no_more = 1; 6604 } 6605 break; 6606 } 6607 default: 6608 fprintf(stderr, "Unknown LUN address method " 6609 "%#x\n", lundata->luns[i].lundata[0] & 6610 RPL_LUNDATA_ATYP_MASK); 6611 break; 6612 } 6613 /* 6614 * For the flat addressing method, there are no 6615 * other levels after it. 6616 */ 6617 if (no_more != 0) 6618 break; 6619 } 6620 fprintf(stdout, "\n"); 6621 } 6622 6623bailout: 6624 6625 cam_freeccb(ccb); 6626 6627 free(lundata); 6628 6629 return (retval); 6630} 6631 6632static int 6633scsireadcapacity(struct cam_device *device, int argc, char **argv, 6634 char *combinedopt, int retry_count, int timeout) 6635{ 6636 union ccb *ccb; 6637 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten; 6638 struct scsi_read_capacity_data rcap; 6639 struct scsi_read_capacity_data_long rcaplong; 6640 uint64_t maxsector; 6641 uint32_t block_len; 6642 int retval; 6643 int c; 6644 6645 blocksizeonly = 0; 6646 humanize = 0; 6647 numblocks = 0; 6648 quiet = 0; 6649 sizeonly = 0; 6650 baseten = 0; 6651 retval = 0; 6652 6653 ccb = cam_getccb(device); 6654 6655 if (ccb == NULL) { 6656 warnx("%s: error allocating ccb", __func__); 6657 return (1); 6658 } 6659 6660 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6661 6662 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6663 switch (c) { 6664 case 'b': 6665 blocksizeonly++; 6666 break; 6667 case 'h': 6668 humanize++; 6669 baseten = 0; 6670 break; 6671 case 'H': 6672 humanize++; 6673 baseten++; 6674 break; 6675 case 'N': 6676 numblocks++; 6677 break; 6678 case 'q': 6679 quiet++; 6680 break; 6681 case 's': 6682 sizeonly++; 6683 break; 6684 default: 6685 break; 6686 } 6687 } 6688 6689 if ((blocksizeonly != 0) 6690 && (numblocks != 0)) { 6691 warnx("%s: you can only specify one of -b or -N", __func__); 6692 retval = 1; 6693 goto bailout; 6694 } 6695 6696 if ((blocksizeonly != 0) 6697 && (sizeonly != 0)) { 6698 warnx("%s: you can only specify one of -b or -s", __func__); 6699 retval = 1; 6700 goto bailout; 6701 } 6702 6703 if ((humanize != 0) 6704 && (quiet != 0)) { 6705 warnx("%s: you can only specify one of -h/-H or -q", __func__); 6706 retval = 1; 6707 goto bailout; 6708 } 6709 6710 if ((humanize != 0) 6711 && (blocksizeonly != 0)) { 6712 warnx("%s: you can only specify one of -h/-H or -b", __func__); 6713 retval = 1; 6714 goto bailout; 6715 } 6716 6717 scsi_read_capacity(&ccb->csio, 6718 /*retries*/ retry_count, 6719 /*cbfcnp*/ NULL, 6720 /*tag_action*/ MSG_SIMPLE_Q_TAG, 6721 &rcap, 6722 SSD_FULL_SIZE, 6723 /*timeout*/ timeout ? timeout : 5000); 6724 6725 /* Disable freezing the device queue */ 6726 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6727 6728 if (arglist & CAM_ARG_ERR_RECOVER) 6729 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6730 6731 if (cam_send_ccb(device, ccb) < 0) { 6732 warn("error sending READ CAPACITY command"); 6733 6734 if (arglist & CAM_ARG_VERBOSE) 6735 cam_error_print(device, ccb, CAM_ESF_ALL, 6736 CAM_EPF_ALL, stderr); 6737 6738 retval = 1; 6739 goto bailout; 6740 } 6741 6742 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6743 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 6744 retval = 1; 6745 goto bailout; 6746 } 6747 6748 maxsector = scsi_4btoul(rcap.addr); 6749 block_len = scsi_4btoul(rcap.length); 6750 6751 /* 6752 * A last block of 2^32-1 means that the true capacity is over 2TB, 6753 * and we need to issue the long READ CAPACITY to get the real 6754 * capacity. Otherwise, we're all set. 6755 */ 6756 if (maxsector != 0xffffffff) 6757 goto do_print; 6758 6759 scsi_read_capacity_16(&ccb->csio, 6760 /*retries*/ retry_count, 6761 /*cbfcnp*/ NULL, 6762 /*tag_action*/ MSG_SIMPLE_Q_TAG, 6763 /*lba*/ 0, 6764 /*reladdr*/ 0, 6765 /*pmi*/ 0, 6766 /*rcap_buf*/ (uint8_t *)&rcaplong, 6767 /*rcap_buf_len*/ sizeof(rcaplong), 6768 /*sense_len*/ SSD_FULL_SIZE, 6769 /*timeout*/ timeout ? timeout : 5000); 6770 6771 /* Disable freezing the device queue */ 6772 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6773 6774 if (arglist & CAM_ARG_ERR_RECOVER) 6775 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6776 6777 if (cam_send_ccb(device, ccb) < 0) { 6778 warn("error sending READ CAPACITY (16) command"); 6779 6780 if (arglist & CAM_ARG_VERBOSE) 6781 cam_error_print(device, ccb, CAM_ESF_ALL, 6782 CAM_EPF_ALL, stderr); 6783 6784 retval = 1; 6785 goto bailout; 6786 } 6787 6788 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6789 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 6790 retval = 1; 6791 goto bailout; 6792 } 6793 6794 maxsector = scsi_8btou64(rcaplong.addr); 6795 block_len = scsi_4btoul(rcaplong.length); 6796 6797do_print: 6798 if (blocksizeonly == 0) { 6799 /* 6800 * Humanize implies !quiet, and also implies numblocks. 6801 */ 6802 if (humanize != 0) { 6803 char tmpstr[6]; 6804 int64_t tmpbytes; 6805 int ret; 6806 6807 tmpbytes = (maxsector + 1) * block_len; 6808 ret = humanize_number(tmpstr, sizeof(tmpstr), 6809 tmpbytes, "", HN_AUTOSCALE, 6810 HN_B | HN_DECIMAL | 6811 ((baseten != 0) ? 6812 HN_DIVISOR_1000 : 0)); 6813 if (ret == -1) { 6814 warnx("%s: humanize_number failed!", __func__); 6815 retval = 1; 6816 goto bailout; 6817 } 6818 fprintf(stdout, "Device Size: %s%s", tmpstr, 6819 (sizeonly == 0) ? ", " : "\n"); 6820 } else if (numblocks != 0) { 6821 fprintf(stdout, "%s%ju%s", (quiet == 0) ? 6822 "Blocks: " : "", (uintmax_t)maxsector + 1, 6823 (sizeonly == 0) ? ", " : "\n"); 6824 } else { 6825 fprintf(stdout, "%s%ju%s", (quiet == 0) ? 6826 "Last Block: " : "", (uintmax_t)maxsector, 6827 (sizeonly == 0) ? ", " : "\n"); 6828 } 6829 } 6830 if (sizeonly == 0) 6831 fprintf(stdout, "%s%u%s\n", (quiet == 0) ? 6832 "Block Length: " : "", block_len, (quiet == 0) ? 6833 " bytes" : ""); 6834bailout: 6835 cam_freeccb(ccb); 6836 6837 return (retval); 6838} 6839 6840static int 6841smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, 6842 int retry_count, int timeout) 6843{ 6844 int c, error = 0; 6845 union ccb *ccb; 6846 uint8_t *smp_request = NULL, *smp_response = NULL; 6847 int request_size = 0, response_size = 0; 6848 int fd_request = 0, fd_response = 0; 6849 char *datastr = NULL; 6850 struct get_hook hook; 6851 int retval; 6852 int flags = 0; 6853 6854 /* 6855 * Note that at the moment we don't support sending SMP CCBs to 6856 * devices that aren't probed by CAM. 6857 */ 6858 ccb = cam_getccb(device); 6859 if (ccb == NULL) { 6860 warnx("%s: error allocating CCB", __func__); 6861 return (1); 6862 } 6863 6864 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 6865 6866 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6867 switch (c) { 6868 case 'R': 6869 arglist |= CAM_ARG_CMD_IN; 6870 response_size = strtol(optarg, NULL, 0); 6871 if (response_size <= 0) { 6872 warnx("invalid number of response bytes %d", 6873 response_size); 6874 error = 1; 6875 goto smpcmd_bailout; 6876 } 6877 hook.argc = argc - optind; 6878 hook.argv = argv + optind; 6879 hook.got = 0; 6880 optind++; 6881 datastr = cget(&hook, NULL); 6882 /* 6883 * If the user supplied "-" instead of a format, he 6884 * wants the data to be written to stdout. 6885 */ 6886 if ((datastr != NULL) 6887 && (datastr[0] == '-')) 6888 fd_response = 1; 6889 6890 smp_response = (u_int8_t *)malloc(response_size); 6891 if (smp_response == NULL) { 6892 warn("can't malloc memory for SMP response"); 6893 error = 1; 6894 goto smpcmd_bailout; 6895 } 6896 break; 6897 case 'r': 6898 arglist |= CAM_ARG_CMD_OUT; 6899 request_size = strtol(optarg, NULL, 0); 6900 if (request_size <= 0) { 6901 warnx("invalid number of request bytes %d", 6902 request_size); 6903 error = 1; 6904 goto smpcmd_bailout; 6905 } 6906 hook.argc = argc - optind; 6907 hook.argv = argv + optind; 6908 hook.got = 0; 6909 datastr = cget(&hook, NULL); 6910 smp_request = (u_int8_t *)malloc(request_size); 6911 if (smp_request == NULL) { 6912 warn("can't malloc memory for SMP request"); 6913 error = 1; 6914 goto smpcmd_bailout; 6915 } 6916 bzero(smp_request, request_size); 6917 /* 6918 * If the user supplied "-" instead of a format, he 6919 * wants the data to be read from stdin. 6920 */ 6921 if ((datastr != NULL) 6922 && (datastr[0] == '-')) 6923 fd_request = 1; 6924 else 6925 buff_encode_visit(smp_request, request_size, 6926 datastr, 6927 iget, &hook); 6928 optind += hook.got; 6929 break; 6930 default: 6931 break; 6932 } 6933 } 6934 6935 /* 6936 * If fd_data is set, and we're writing to the device, we need to 6937 * read the data the user wants written from stdin. 6938 */ 6939 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) { 6940 ssize_t amt_read; 6941 int amt_to_read = request_size; 6942 u_int8_t *buf_ptr = smp_request; 6943 6944 for (amt_read = 0; amt_to_read > 0; 6945 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) { 6946 if (amt_read == -1) { 6947 warn("error reading data from stdin"); 6948 error = 1; 6949 goto smpcmd_bailout; 6950 } 6951 amt_to_read -= amt_read; 6952 buf_ptr += amt_read; 6953 } 6954 } 6955 6956 if (((arglist & CAM_ARG_CMD_IN) == 0) 6957 || ((arglist & CAM_ARG_CMD_OUT) == 0)) { 6958 warnx("%s: need both the request (-r) and response (-R) " 6959 "arguments", __func__); 6960 error = 1; 6961 goto smpcmd_bailout; 6962 } 6963 6964 flags |= CAM_DEV_QFRZDIS; 6965 6966 cam_fill_smpio(&ccb->smpio, 6967 /*retries*/ retry_count, 6968 /*cbfcnp*/ NULL, 6969 /*flags*/ flags, 6970 /*smp_request*/ smp_request, 6971 /*smp_request_len*/ request_size, 6972 /*smp_response*/ smp_response, 6973 /*smp_response_len*/ response_size, 6974 /*timeout*/ timeout ? timeout : 5000); 6975 6976 ccb->smpio.flags = SMP_FLAG_NONE; 6977 6978 if (((retval = cam_send_ccb(device, ccb)) < 0) 6979 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 6980 const char warnstr[] = "error sending command"; 6981 6982 if (retval < 0) 6983 warn(warnstr); 6984 else 6985 warnx(warnstr); 6986 6987 if (arglist & CAM_ARG_VERBOSE) { 6988 cam_error_print(device, ccb, CAM_ESF_ALL, 6989 CAM_EPF_ALL, stderr); 6990 } 6991 } 6992 6993 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 6994 && (response_size > 0)) { 6995 if (fd_response == 0) { 6996 buff_decode_visit(smp_response, response_size, 6997 datastr, arg_put, NULL); 6998 fprintf(stdout, "\n"); 6999 } else { 7000 ssize_t amt_written; 7001 int amt_to_write = response_size; 7002 u_int8_t *buf_ptr = smp_response; 7003 7004 for (amt_written = 0; (amt_to_write > 0) && 7005 (amt_written = write(STDOUT_FILENO, buf_ptr, 7006 amt_to_write)) > 0;){ 7007 amt_to_write -= amt_written; 7008 buf_ptr += amt_written; 7009 } 7010 if (amt_written == -1) { 7011 warn("error writing data to stdout"); 7012 error = 1; 7013 goto smpcmd_bailout; 7014 } else if ((amt_written == 0) 7015 && (amt_to_write > 0)) { 7016 warnx("only wrote %u bytes out of %u", 7017 response_size - amt_to_write, 7018 response_size); 7019 } 7020 } 7021 } 7022smpcmd_bailout: 7023 if (ccb != NULL) 7024 cam_freeccb(ccb); 7025 7026 if (smp_request != NULL) 7027 free(smp_request); 7028 7029 if (smp_response != NULL) 7030 free(smp_response); 7031 7032 return (error); 7033} 7034 7035static int 7036smpreportgeneral(struct cam_device *device, int argc, char **argv, 7037 char *combinedopt, int retry_count, int timeout) 7038{ 7039 union ccb *ccb; 7040 struct smp_report_general_request *request = NULL; 7041 struct smp_report_general_response *response = NULL; 7042 struct sbuf *sb = NULL; 7043 int error = 0; 7044 int c, long_response = 0; 7045 int retval; 7046 7047 /* 7048 * Note that at the moment we don't support sending SMP CCBs to 7049 * devices that aren't probed by CAM. 7050 */ 7051 ccb = cam_getccb(device); 7052 if (ccb == NULL) { 7053 warnx("%s: error allocating CCB", __func__); 7054 return (1); 7055 } 7056 7057 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7058 7059 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7060 switch (c) { 7061 case 'l': 7062 long_response = 1; 7063 break; 7064 default: 7065 break; 7066 } 7067 } 7068 request = malloc(sizeof(*request)); 7069 if (request == NULL) { 7070 warn("%s: unable to allocate %zd bytes", __func__, 7071 sizeof(*request)); 7072 error = 1; 7073 goto bailout; 7074 } 7075 7076 response = malloc(sizeof(*response)); 7077 if (response == NULL) { 7078 warn("%s: unable to allocate %zd bytes", __func__, 7079 sizeof(*response)); 7080 error = 1; 7081 goto bailout; 7082 } 7083 7084try_long: 7085 smp_report_general(&ccb->smpio, 7086 retry_count, 7087 /*cbfcnp*/ NULL, 7088 request, 7089 /*request_len*/ sizeof(*request), 7090 (uint8_t *)response, 7091 /*response_len*/ sizeof(*response), 7092 /*long_response*/ long_response, 7093 timeout); 7094 7095 if (((retval = cam_send_ccb(device, ccb)) < 0) 7096 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7097 const char warnstr[] = "error sending command"; 7098 7099 if (retval < 0) 7100 warn(warnstr); 7101 else 7102 warnx(warnstr); 7103 7104 if (arglist & CAM_ARG_VERBOSE) { 7105 cam_error_print(device, ccb, CAM_ESF_ALL, 7106 CAM_EPF_ALL, stderr); 7107 } 7108 error = 1; 7109 goto bailout; 7110 } 7111 7112 /* 7113 * If the device supports the long response bit, try again and see 7114 * if we can get all of the data. 7115 */ 7116 if ((response->long_response & SMP_RG_LONG_RESPONSE) 7117 && (long_response == 0)) { 7118 ccb->ccb_h.status = CAM_REQ_INPROG; 7119 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7120 long_response = 1; 7121 goto try_long; 7122 } 7123 7124 /* 7125 * XXX KDM detect and decode SMP errors here. 7126 */ 7127 sb = sbuf_new_auto(); 7128 if (sb == NULL) { 7129 warnx("%s: error allocating sbuf", __func__); 7130 goto bailout; 7131 } 7132 7133 smp_report_general_sbuf(response, sizeof(*response), sb); 7134 7135 if (sbuf_finish(sb) != 0) { 7136 warnx("%s: sbuf_finish", __func__); 7137 goto bailout; 7138 } 7139 7140 printf("%s", sbuf_data(sb)); 7141 7142bailout: 7143 if (ccb != NULL) 7144 cam_freeccb(ccb); 7145 7146 if (request != NULL) 7147 free(request); 7148 7149 if (response != NULL) 7150 free(response); 7151 7152 if (sb != NULL) 7153 sbuf_delete(sb); 7154 7155 return (error); 7156} 7157 7158static struct camcontrol_opts phy_ops[] = { 7159 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL}, 7160 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL}, 7161 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL}, 7162 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL}, 7163 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL}, 7164 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL}, 7165 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL}, 7166 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL}, 7167 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL}, 7168 {NULL, 0, 0, NULL} 7169}; 7170 7171static int 7172smpphycontrol(struct cam_device *device, int argc, char **argv, 7173 char *combinedopt, int retry_count, int timeout) 7174{ 7175 union ccb *ccb; 7176 struct smp_phy_control_request *request = NULL; 7177 struct smp_phy_control_response *response = NULL; 7178 int long_response = 0; 7179 int retval = 0; 7180 int phy = -1; 7181 uint32_t phy_operation = SMP_PC_PHY_OP_NOP; 7182 int phy_op_set = 0; 7183 uint64_t attached_dev_name = 0; 7184 int dev_name_set = 0; 7185 uint32_t min_plr = 0, max_plr = 0; 7186 uint32_t pp_timeout_val = 0; 7187 int slumber_partial = 0; 7188 int set_pp_timeout_val = 0; 7189 int c; 7190 7191 /* 7192 * Note that at the moment we don't support sending SMP CCBs to 7193 * devices that aren't probed by CAM. 7194 */ 7195 ccb = cam_getccb(device); 7196 if (ccb == NULL) { 7197 warnx("%s: error allocating CCB", __func__); 7198 return (1); 7199 } 7200 7201 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7202 7203 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7204 switch (c) { 7205 case 'a': 7206 case 'A': 7207 case 's': 7208 case 'S': { 7209 int enable = -1; 7210 7211 if (strcasecmp(optarg, "enable") == 0) 7212 enable = 1; 7213 else if (strcasecmp(optarg, "disable") == 0) 7214 enable = 2; 7215 else { 7216 warnx("%s: Invalid argument %s", __func__, 7217 optarg); 7218 retval = 1; 7219 goto bailout; 7220 } 7221 switch (c) { 7222 case 's': 7223 slumber_partial |= enable << 7224 SMP_PC_SAS_SLUMBER_SHIFT; 7225 break; 7226 case 'S': 7227 slumber_partial |= enable << 7228 SMP_PC_SAS_PARTIAL_SHIFT; 7229 break; 7230 case 'a': 7231 slumber_partial |= enable << 7232 SMP_PC_SATA_SLUMBER_SHIFT; 7233 break; 7234 case 'A': 7235 slumber_partial |= enable << 7236 SMP_PC_SATA_PARTIAL_SHIFT; 7237 break; 7238 default: 7239 warnx("%s: programmer error", __func__); 7240 retval = 1; 7241 goto bailout; 7242 break; /*NOTREACHED*/ 7243 } 7244 break; 7245 } 7246 case 'd': 7247 attached_dev_name = (uintmax_t)strtoumax(optarg, 7248 NULL,0); 7249 dev_name_set = 1; 7250 break; 7251 case 'l': 7252 long_response = 1; 7253 break; 7254 case 'm': 7255 /* 7256 * We don't do extensive checking here, so this 7257 * will continue to work when new speeds come out. 7258 */ 7259 min_plr = strtoul(optarg, NULL, 0); 7260 if ((min_plr == 0) 7261 || (min_plr > 0xf)) { 7262 warnx("%s: invalid link rate %x", 7263 __func__, min_plr); 7264 retval = 1; 7265 goto bailout; 7266 } 7267 break; 7268 case 'M': 7269 /* 7270 * We don't do extensive checking here, so this 7271 * will continue to work when new speeds come out. 7272 */ 7273 max_plr = strtoul(optarg, NULL, 0); 7274 if ((max_plr == 0) 7275 || (max_plr > 0xf)) { 7276 warnx("%s: invalid link rate %x", 7277 __func__, max_plr); 7278 retval = 1; 7279 goto bailout; 7280 } 7281 break; 7282 case 'o': { 7283 camcontrol_optret optreturn; 7284 cam_argmask argnums; 7285 const char *subopt; 7286 7287 if (phy_op_set != 0) { 7288 warnx("%s: only one phy operation argument " 7289 "(-o) allowed", __func__); 7290 retval = 1; 7291 goto bailout; 7292 } 7293 7294 phy_op_set = 1; 7295 7296 /* 7297 * Allow the user to specify the phy operation 7298 * numerically, as well as with a name. This will 7299 * future-proof it a bit, so options that are added 7300 * in future specs can be used. 7301 */ 7302 if (isdigit(optarg[0])) { 7303 phy_operation = strtoul(optarg, NULL, 0); 7304 if ((phy_operation == 0) 7305 || (phy_operation > 0xff)) { 7306 warnx("%s: invalid phy operation %#x", 7307 __func__, phy_operation); 7308 retval = 1; 7309 goto bailout; 7310 } 7311 break; 7312 } 7313 optreturn = getoption(phy_ops, optarg, &phy_operation, 7314 &argnums, &subopt); 7315 7316 if (optreturn == CC_OR_AMBIGUOUS) { 7317 warnx("%s: ambiguous option %s", __func__, 7318 optarg); 7319 usage(0); 7320 retval = 1; 7321 goto bailout; 7322 } else if (optreturn == CC_OR_NOT_FOUND) { 7323 warnx("%s: option %s not found", __func__, 7324 optarg); 7325 usage(0); 7326 retval = 1; 7327 goto bailout; 7328 } 7329 break; 7330 } 7331 case 'p': 7332 phy = atoi(optarg); 7333 break; 7334 case 'T': 7335 pp_timeout_val = strtoul(optarg, NULL, 0); 7336 if (pp_timeout_val > 15) { 7337 warnx("%s: invalid partial pathway timeout " 7338 "value %u, need a value less than 16", 7339 __func__, pp_timeout_val); 7340 retval = 1; 7341 goto bailout; 7342 } 7343 set_pp_timeout_val = 1; 7344 break; 7345 default: 7346 break; 7347 } 7348 } 7349 7350 if (phy == -1) { 7351 warnx("%s: a PHY (-p phy) argument is required",__func__); 7352 retval = 1; 7353 goto bailout; 7354 } 7355 7356 if (((dev_name_set != 0) 7357 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME)) 7358 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME) 7359 && (dev_name_set == 0))) { 7360 warnx("%s: -d name and -o setdevname arguments both " 7361 "required to set device name", __func__); 7362 retval = 1; 7363 goto bailout; 7364 } 7365 7366 request = malloc(sizeof(*request)); 7367 if (request == NULL) { 7368 warn("%s: unable to allocate %zd bytes", __func__, 7369 sizeof(*request)); 7370 retval = 1; 7371 goto bailout; 7372 } 7373 7374 response = malloc(sizeof(*response)); 7375 if (response == NULL) { 7376 warn("%s: unable to allocate %zd bytes", __func__, 7377 sizeof(*response)); 7378 retval = 1; 7379 goto bailout; 7380 } 7381 7382 smp_phy_control(&ccb->smpio, 7383 retry_count, 7384 /*cbfcnp*/ NULL, 7385 request, 7386 sizeof(*request), 7387 (uint8_t *)response, 7388 sizeof(*response), 7389 long_response, 7390 /*expected_exp_change_count*/ 0, 7391 phy, 7392 phy_operation, 7393 (set_pp_timeout_val != 0) ? 1 : 0, 7394 attached_dev_name, 7395 min_plr, 7396 max_plr, 7397 slumber_partial, 7398 pp_timeout_val, 7399 timeout); 7400 7401 if (((retval = cam_send_ccb(device, ccb)) < 0) 7402 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7403 const char warnstr[] = "error sending command"; 7404 7405 if (retval < 0) 7406 warn(warnstr); 7407 else 7408 warnx(warnstr); 7409 7410 if (arglist & CAM_ARG_VERBOSE) { 7411 /* 7412 * Use CAM_EPF_NORMAL so we only get one line of 7413 * SMP command decoding. 7414 */ 7415 cam_error_print(device, ccb, CAM_ESF_ALL, 7416 CAM_EPF_NORMAL, stderr); 7417 } 7418 retval = 1; 7419 goto bailout; 7420 } 7421 7422 /* XXX KDM print out something here for success? */ 7423bailout: 7424 if (ccb != NULL) 7425 cam_freeccb(ccb); 7426 7427 if (request != NULL) 7428 free(request); 7429 7430 if (response != NULL) 7431 free(response); 7432 7433 return (retval); 7434} 7435 7436static int 7437smpmaninfo(struct cam_device *device, int argc, char **argv, 7438 char *combinedopt, int retry_count, int timeout) 7439{ 7440 union ccb *ccb; 7441 struct smp_report_manuf_info_request request; 7442 struct smp_report_manuf_info_response response; 7443 struct sbuf *sb = NULL; 7444 int long_response = 0; 7445 int retval = 0; 7446 int c; 7447 7448 /* 7449 * Note that at the moment we don't support sending SMP CCBs to 7450 * devices that aren't probed by CAM. 7451 */ 7452 ccb = cam_getccb(device); 7453 if (ccb == NULL) { 7454 warnx("%s: error allocating CCB", __func__); 7455 return (1); 7456 } 7457 7458 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7459 7460 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7461 switch (c) { 7462 case 'l': 7463 long_response = 1; 7464 break; 7465 default: 7466 break; 7467 } 7468 } 7469 bzero(&request, sizeof(request)); 7470 bzero(&response, sizeof(response)); 7471 7472 smp_report_manuf_info(&ccb->smpio, 7473 retry_count, 7474 /*cbfcnp*/ NULL, 7475 &request, 7476 sizeof(request), 7477 (uint8_t *)&response, 7478 sizeof(response), 7479 long_response, 7480 timeout); 7481 7482 if (((retval = cam_send_ccb(device, ccb)) < 0) 7483 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7484 const char warnstr[] = "error sending command"; 7485 7486 if (retval < 0) 7487 warn(warnstr); 7488 else 7489 warnx(warnstr); 7490 7491 if (arglist & CAM_ARG_VERBOSE) { 7492 cam_error_print(device, ccb, CAM_ESF_ALL, 7493 CAM_EPF_ALL, stderr); 7494 } 7495 retval = 1; 7496 goto bailout; 7497 } 7498 7499 sb = sbuf_new_auto(); 7500 if (sb == NULL) { 7501 warnx("%s: error allocating sbuf", __func__); 7502 goto bailout; 7503 } 7504 7505 smp_report_manuf_info_sbuf(&response, sizeof(response), sb); 7506 7507 if (sbuf_finish(sb) != 0) { 7508 warnx("%s: sbuf_finish", __func__); 7509 goto bailout; 7510 } 7511 7512 printf("%s", sbuf_data(sb)); 7513 7514bailout: 7515 7516 if (ccb != NULL) 7517 cam_freeccb(ccb); 7518 7519 if (sb != NULL) 7520 sbuf_delete(sb); 7521 7522 return (retval); 7523} 7524 7525static int 7526getdevid(struct cam_devitem *item) 7527{ 7528 int retval = 0; 7529 union ccb *ccb = NULL; 7530 7531 struct cam_device *dev; 7532 7533 dev = cam_open_btl(item->dev_match.path_id, 7534 item->dev_match.target_id, 7535 item->dev_match.target_lun, O_RDWR, NULL); 7536 7537 if (dev == NULL) { 7538 warnx("%s", cam_errbuf); 7539 retval = 1; 7540 goto bailout; 7541 } 7542 7543 item->device_id_len = 0; 7544 7545 ccb = cam_getccb(dev); 7546 if (ccb == NULL) { 7547 warnx("%s: error allocating CCB", __func__); 7548 retval = 1; 7549 goto bailout; 7550 } 7551 7552 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai); 7553 7554 /* 7555 * On the first try, we just probe for the size of the data, and 7556 * then allocate that much memory and try again. 7557 */ 7558retry: 7559 ccb->ccb_h.func_code = XPT_DEV_ADVINFO; 7560 ccb->ccb_h.flags = CAM_DIR_IN; 7561 ccb->cdai.flags = CDAI_FLAG_NONE; 7562 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID; 7563 ccb->cdai.bufsiz = item->device_id_len; 7564 if (item->device_id_len != 0) 7565 ccb->cdai.buf = (uint8_t *)item->device_id; 7566 7567 if (cam_send_ccb(dev, ccb) < 0) { 7568 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__); 7569 retval = 1; 7570 goto bailout; 7571 } 7572 7573 if (ccb->ccb_h.status != CAM_REQ_CMP) { 7574 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status); 7575 retval = 1; 7576 goto bailout; 7577 } 7578 7579 if (item->device_id_len == 0) { 7580 /* 7581 * This is our first time through. Allocate the buffer, 7582 * and then go back to get the data. 7583 */ 7584 if (ccb->cdai.provsiz == 0) { 7585 warnx("%s: invalid .provsiz field returned with " 7586 "XPT_GDEV_ADVINFO CCB", __func__); 7587 retval = 1; 7588 goto bailout; 7589 } 7590 item->device_id_len = ccb->cdai.provsiz; 7591 item->device_id = malloc(item->device_id_len); 7592 if (item->device_id == NULL) { 7593 warn("%s: unable to allocate %d bytes", __func__, 7594 item->device_id_len); 7595 retval = 1; 7596 goto bailout; 7597 } 7598 ccb->ccb_h.status = CAM_REQ_INPROG; 7599 goto retry; 7600 } 7601 7602bailout: 7603 if (dev != NULL) 7604 cam_close_device(dev); 7605 7606 if (ccb != NULL) 7607 cam_freeccb(ccb); 7608 7609 return (retval); 7610} 7611 7612/* 7613 * XXX KDM merge this code with getdevtree()? 7614 */ 7615static int 7616buildbusdevlist(struct cam_devlist *devlist) 7617{ 7618 union ccb ccb; 7619 int bufsize, fd = -1; 7620 struct dev_match_pattern *patterns; 7621 struct cam_devitem *item = NULL; 7622 int skip_device = 0; 7623 int retval = 0; 7624 7625 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { 7626 warn("couldn't open %s", XPT_DEVICE); 7627 return(1); 7628 } 7629 7630 bzero(&ccb, sizeof(union ccb)); 7631 7632 ccb.ccb_h.path_id = CAM_XPT_PATH_ID; 7633 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 7634 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 7635 7636 ccb.ccb_h.func_code = XPT_DEV_MATCH; 7637 bufsize = sizeof(struct dev_match_result) * 100; 7638 ccb.cdm.match_buf_len = bufsize; 7639 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); 7640 if (ccb.cdm.matches == NULL) { 7641 warnx("can't malloc memory for matches"); 7642 close(fd); 7643 return(1); 7644 } 7645 ccb.cdm.num_matches = 0; 7646 ccb.cdm.num_patterns = 2; 7647 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) * 7648 ccb.cdm.num_patterns; 7649 7650 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len); 7651 if (patterns == NULL) { 7652 warnx("can't malloc memory for patterns"); 7653 retval = 1; 7654 goto bailout; 7655 } 7656 7657 ccb.cdm.patterns = patterns; 7658 bzero(patterns, ccb.cdm.pattern_buf_len); 7659 7660 patterns[0].type = DEV_MATCH_DEVICE; 7661 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH; 7662 patterns[0].pattern.device_pattern.path_id = devlist->path_id; 7663 patterns[1].type = DEV_MATCH_PERIPH; 7664 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH; 7665 patterns[1].pattern.periph_pattern.path_id = devlist->path_id; 7666 7667 /* 7668 * We do the ioctl multiple times if necessary, in case there are 7669 * more than 100 nodes in the EDT. 7670 */ 7671 do { 7672 unsigned int i; 7673 7674 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 7675 warn("error sending CAMIOCOMMAND ioctl"); 7676 retval = 1; 7677 goto bailout; 7678 } 7679 7680 if ((ccb.ccb_h.status != CAM_REQ_CMP) 7681 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) 7682 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { 7683 warnx("got CAM error %#x, CDM error %d\n", 7684 ccb.ccb_h.status, ccb.cdm.status); 7685 retval = 1; 7686 goto bailout; 7687 } 7688 7689 for (i = 0; i < ccb.cdm.num_matches; i++) { 7690 switch (ccb.cdm.matches[i].type) { 7691 case DEV_MATCH_DEVICE: { 7692 struct device_match_result *dev_result; 7693 7694 dev_result = 7695 &ccb.cdm.matches[i].result.device_result; 7696 7697 if (dev_result->flags & 7698 DEV_RESULT_UNCONFIGURED) { 7699 skip_device = 1; 7700 break; 7701 } else 7702 skip_device = 0; 7703 7704 item = malloc(sizeof(*item)); 7705 if (item == NULL) { 7706 warn("%s: unable to allocate %zd bytes", 7707 __func__, sizeof(*item)); 7708 retval = 1; 7709 goto bailout; 7710 } 7711 bzero(item, sizeof(*item)); 7712 bcopy(dev_result, &item->dev_match, 7713 sizeof(*dev_result)); 7714 STAILQ_INSERT_TAIL(&devlist->dev_queue, item, 7715 links); 7716 7717 if (getdevid(item) != 0) { 7718 retval = 1; 7719 goto bailout; 7720 } 7721 break; 7722 } 7723 case DEV_MATCH_PERIPH: { 7724 struct periph_match_result *periph_result; 7725 7726 periph_result = 7727 &ccb.cdm.matches[i].result.periph_result; 7728 7729 if (skip_device != 0) 7730 break; 7731 item->num_periphs++; 7732 item->periph_matches = realloc( 7733 item->periph_matches, 7734 item->num_periphs * 7735 sizeof(struct periph_match_result)); 7736 if (item->periph_matches == NULL) { 7737 warn("%s: error allocating periph " 7738 "list", __func__); 7739 retval = 1; 7740 goto bailout; 7741 } 7742 bcopy(periph_result, &item->periph_matches[ 7743 item->num_periphs - 1], 7744 sizeof(*periph_result)); 7745 break; 7746 } 7747 default: 7748 fprintf(stderr, "%s: unexpected match " 7749 "type %d\n", __func__, 7750 ccb.cdm.matches[i].type); 7751 retval = 1; 7752 goto bailout; 7753 break; /*NOTREACHED*/ 7754 } 7755 } 7756 } while ((ccb.ccb_h.status == CAM_REQ_CMP) 7757 && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); 7758bailout: 7759 7760 if (fd != -1) 7761 close(fd); 7762 7763 free(patterns); 7764 7765 free(ccb.cdm.matches); 7766 7767 if (retval != 0) 7768 freebusdevlist(devlist); 7769 7770 return (retval); 7771} 7772 7773static void 7774freebusdevlist(struct cam_devlist *devlist) 7775{ 7776 struct cam_devitem *item, *item2; 7777 7778 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) { 7779 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem, 7780 links); 7781 free(item->device_id); 7782 free(item->periph_matches); 7783 free(item); 7784 } 7785} 7786 7787static struct cam_devitem * 7788findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr) 7789{ 7790 struct cam_devitem *item; 7791 7792 STAILQ_FOREACH(item, &devlist->dev_queue, links) { 7793 struct scsi_vpd_id_descriptor *idd; 7794 7795 /* 7796 * XXX KDM look for LUN IDs as well? 7797 */ 7798 idd = scsi_get_devid(item->device_id, 7799 item->device_id_len, 7800 scsi_devid_is_sas_target); 7801 if (idd == NULL) 7802 continue; 7803 7804 if (scsi_8btou64(idd->identifier) == sasaddr) 7805 return (item); 7806 } 7807 7808 return (NULL); 7809} 7810 7811static int 7812smpphylist(struct cam_device *device, int argc, char **argv, 7813 char *combinedopt, int retry_count, int timeout) 7814{ 7815 struct smp_report_general_request *rgrequest = NULL; 7816 struct smp_report_general_response *rgresponse = NULL; 7817 struct smp_discover_request *disrequest = NULL; 7818 struct smp_discover_response *disresponse = NULL; 7819 struct cam_devlist devlist; 7820 union ccb *ccb; 7821 int long_response = 0; 7822 int num_phys = 0; 7823 int quiet = 0; 7824 int retval; 7825 int i, c; 7826 7827 /* 7828 * Note that at the moment we don't support sending SMP CCBs to 7829 * devices that aren't probed by CAM. 7830 */ 7831 ccb = cam_getccb(device); 7832 if (ccb == NULL) { 7833 warnx("%s: error allocating CCB", __func__); 7834 return (1); 7835 } 7836 7837 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7838 STAILQ_INIT(&devlist.dev_queue); 7839 7840 rgrequest = malloc(sizeof(*rgrequest)); 7841 if (rgrequest == NULL) { 7842 warn("%s: unable to allocate %zd bytes", __func__, 7843 sizeof(*rgrequest)); 7844 retval = 1; 7845 goto bailout; 7846 } 7847 7848 rgresponse = malloc(sizeof(*rgresponse)); 7849 if (rgresponse == NULL) { 7850 warn("%s: unable to allocate %zd bytes", __func__, 7851 sizeof(*rgresponse)); 7852 retval = 1; 7853 goto bailout; 7854 } 7855 7856 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7857 switch (c) { 7858 case 'l': 7859 long_response = 1; 7860 break; 7861 case 'q': 7862 quiet = 1; 7863 break; 7864 default: 7865 break; 7866 } 7867 } 7868 7869 smp_report_general(&ccb->smpio, 7870 retry_count, 7871 /*cbfcnp*/ NULL, 7872 rgrequest, 7873 /*request_len*/ sizeof(*rgrequest), 7874 (uint8_t *)rgresponse, 7875 /*response_len*/ sizeof(*rgresponse), 7876 /*long_response*/ long_response, 7877 timeout); 7878 7879 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 7880 7881 if (((retval = cam_send_ccb(device, ccb)) < 0) 7882 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7883 const char warnstr[] = "error sending command"; 7884 7885 if (retval < 0) 7886 warn(warnstr); 7887 else 7888 warnx(warnstr); 7889 7890 if (arglist & CAM_ARG_VERBOSE) { 7891 cam_error_print(device, ccb, CAM_ESF_ALL, 7892 CAM_EPF_ALL, stderr); 7893 } 7894 retval = 1; 7895 goto bailout; 7896 } 7897 7898 num_phys = rgresponse->num_phys; 7899 7900 if (num_phys == 0) { 7901 if (quiet == 0) 7902 fprintf(stdout, "%s: No Phys reported\n", __func__); 7903 retval = 1; 7904 goto bailout; 7905 } 7906 7907 devlist.path_id = device->path_id; 7908 7909 retval = buildbusdevlist(&devlist); 7910 if (retval != 0) 7911 goto bailout; 7912 7913 if (quiet == 0) { 7914 fprintf(stdout, "%d PHYs:\n", num_phys); 7915 fprintf(stdout, "PHY Attached SAS Address\n"); 7916 } 7917 7918 disrequest = malloc(sizeof(*disrequest)); 7919 if (disrequest == NULL) { 7920 warn("%s: unable to allocate %zd bytes", __func__, 7921 sizeof(*disrequest)); 7922 retval = 1; 7923 goto bailout; 7924 } 7925 7926 disresponse = malloc(sizeof(*disresponse)); 7927 if (disresponse == NULL) { 7928 warn("%s: unable to allocate %zd bytes", __func__, 7929 sizeof(*disresponse)); 7930 retval = 1; 7931 goto bailout; 7932 } 7933 7934 for (i = 0; i < num_phys; i++) { 7935 struct cam_devitem *item; 7936 struct device_match_result *dev_match; 7937 char vendor[16], product[48], revision[16]; 7938 char tmpstr[256]; 7939 int j; 7940 7941 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7942 7943 ccb->ccb_h.status = CAM_REQ_INPROG; 7944 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 7945 7946 smp_discover(&ccb->smpio, 7947 retry_count, 7948 /*cbfcnp*/ NULL, 7949 disrequest, 7950 sizeof(*disrequest), 7951 (uint8_t *)disresponse, 7952 sizeof(*disresponse), 7953 long_response, 7954 /*ignore_zone_group*/ 0, 7955 /*phy*/ i, 7956 timeout); 7957 7958 if (((retval = cam_send_ccb(device, ccb)) < 0) 7959 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 7960 && (disresponse->function_result != SMP_FR_PHY_VACANT))) { 7961 const char warnstr[] = "error sending command"; 7962 7963 if (retval < 0) 7964 warn(warnstr); 7965 else 7966 warnx(warnstr); 7967 7968 if (arglist & CAM_ARG_VERBOSE) { 7969 cam_error_print(device, ccb, CAM_ESF_ALL, 7970 CAM_EPF_ALL, stderr); 7971 } 7972 retval = 1; 7973 goto bailout; 7974 } 7975 7976 if (disresponse->function_result == SMP_FR_PHY_VACANT) { 7977 if (quiet == 0) 7978 fprintf(stdout, "%3d <vacant>\n", i); 7979 continue; 7980 } 7981 7982 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) { 7983 item = NULL; 7984 } else { 7985 item = findsasdevice(&devlist, 7986 scsi_8btou64(disresponse->attached_sas_address)); 7987 } 7988 7989 if ((quiet == 0) 7990 || (item != NULL)) { 7991 fprintf(stdout, "%3d 0x%016jx", i, 7992 (uintmax_t)scsi_8btou64( 7993 disresponse->attached_sas_address)); 7994 if (item == NULL) { 7995 fprintf(stdout, "\n"); 7996 continue; 7997 } 7998 } else if (quiet != 0) 7999 continue; 8000 8001 dev_match = &item->dev_match; 8002 8003 if (dev_match->protocol == PROTO_SCSI) { 8004 cam_strvis(vendor, dev_match->inq_data.vendor, 8005 sizeof(dev_match->inq_data.vendor), 8006 sizeof(vendor)); 8007 cam_strvis(product, dev_match->inq_data.product, 8008 sizeof(dev_match->inq_data.product), 8009 sizeof(product)); 8010 cam_strvis(revision, dev_match->inq_data.revision, 8011 sizeof(dev_match->inq_data.revision), 8012 sizeof(revision)); 8013 sprintf(tmpstr, "<%s %s %s>", vendor, product, 8014 revision); 8015 } else if ((dev_match->protocol == PROTO_ATA) 8016 || (dev_match->protocol == PROTO_SATAPM)) { 8017 cam_strvis(product, dev_match->ident_data.model, 8018 sizeof(dev_match->ident_data.model), 8019 sizeof(product)); 8020 cam_strvis(revision, dev_match->ident_data.revision, 8021 sizeof(dev_match->ident_data.revision), 8022 sizeof(revision)); 8023 sprintf(tmpstr, "<%s %s>", product, revision); 8024 } else { 8025 sprintf(tmpstr, "<>"); 8026 } 8027 fprintf(stdout, " %-33s ", tmpstr); 8028 8029 /* 8030 * If we have 0 periphs, that's a bug... 8031 */ 8032 if (item->num_periphs == 0) { 8033 fprintf(stdout, "\n"); 8034 continue; 8035 } 8036 8037 fprintf(stdout, "("); 8038 for (j = 0; j < item->num_periphs; j++) { 8039 if (j > 0) 8040 fprintf(stdout, ","); 8041 8042 fprintf(stdout, "%s%d", 8043 item->periph_matches[j].periph_name, 8044 item->periph_matches[j].unit_number); 8045 8046 } 8047 fprintf(stdout, ")\n"); 8048 } 8049bailout: 8050 if (ccb != NULL) 8051 cam_freeccb(ccb); 8052 8053 free(rgrequest); 8054 8055 free(rgresponse); 8056 8057 free(disrequest); 8058 8059 free(disresponse); 8060 8061 freebusdevlist(&devlist); 8062 8063 return (retval); 8064} 8065 8066static int 8067atapm(struct cam_device *device, int argc, char **argv, 8068 char *combinedopt, int retry_count, int timeout) 8069{ 8070 union ccb *ccb; 8071 int retval = 0; 8072 int t = -1; 8073 int c; 8074 u_char cmd, sc; 8075 8076 ccb = cam_getccb(device); 8077 8078 if (ccb == NULL) { 8079 warnx("%s: error allocating ccb", __func__); 8080 return (1); 8081 } 8082 8083 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8084 switch (c) { 8085 case 't': 8086 t = atoi(optarg); 8087 break; 8088 default: 8089 break; 8090 } 8091 } 8092 if (strcmp(argv[1], "idle") == 0) { 8093 if (t == -1) 8094 cmd = ATA_IDLE_IMMEDIATE; 8095 else 8096 cmd = ATA_IDLE_CMD; 8097 } else if (strcmp(argv[1], "standby") == 0) { 8098 if (t == -1) 8099 cmd = ATA_STANDBY_IMMEDIATE; 8100 else 8101 cmd = ATA_STANDBY_CMD; 8102 } else { 8103 cmd = ATA_SLEEP; 8104 t = -1; 8105 } 8106 8107 if (t < 0) 8108 sc = 0; 8109 else if (t <= (240 * 5)) 8110 sc = (t + 4) / 5; 8111 else if (t <= (252 * 5)) 8112 /* special encoding for 21 minutes */ 8113 sc = 252; 8114 else if (t <= (11 * 30 * 60)) 8115 sc = (t - 1) / (30 * 60) + 241; 8116 else 8117 sc = 253; 8118 8119 retval = ata_do_28bit_cmd(device, 8120 ccb, 8121 /*retries*/retry_count, 8122 /*flags*/CAM_DIR_NONE, 8123 /*protocol*/AP_PROTO_NON_DATA, 8124 /*tag_action*/MSG_SIMPLE_Q_TAG, 8125 /*command*/cmd, 8126 /*features*/0, 8127 /*lba*/0, 8128 /*sector_count*/sc, 8129 /*data_ptr*/NULL, 8130 /*dxfer_len*/0, 8131 /*timeout*/timeout ? timeout : 30 * 1000, 8132 /*quiet*/1); 8133 8134 cam_freeccb(ccb); 8135 return (retval); 8136} 8137 8138static int 8139ataaxm(struct cam_device *device, int argc, char **argv, 8140 char *combinedopt, int retry_count, int timeout) 8141{ 8142 union ccb *ccb; 8143 int retval = 0; 8144 int l = -1; 8145 int c; 8146 u_char cmd, sc; 8147 8148 ccb = cam_getccb(device); 8149 8150 if (ccb == NULL) { 8151 warnx("%s: error allocating ccb", __func__); 8152 return (1); 8153 } 8154 8155 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8156 switch (c) { 8157 case 'l': 8158 l = atoi(optarg); 8159 break; 8160 default: 8161 break; 8162 } 8163 } 8164 sc = 0; 8165 if (strcmp(argv[1], "apm") == 0) { 8166 if (l == -1) 8167 cmd = 0x85; 8168 else { 8169 cmd = 0x05; 8170 sc = l; 8171 } 8172 } else /* aam */ { 8173 if (l == -1) 8174 cmd = 0xC2; 8175 else { 8176 cmd = 0x42; 8177 sc = l; 8178 } 8179 } 8180 8181 retval = ata_do_28bit_cmd(device, 8182 ccb, 8183 /*retries*/retry_count, 8184 /*flags*/CAM_DIR_NONE, 8185 /*protocol*/AP_PROTO_NON_DATA, 8186 /*tag_action*/MSG_SIMPLE_Q_TAG, 8187 /*command*/ATA_SETFEATURES, 8188 /*features*/cmd, 8189 /*lba*/0, 8190 /*sector_count*/sc, 8191 /*data_ptr*/NULL, 8192 /*dxfer_len*/0, 8193 /*timeout*/timeout ? timeout : 30 * 1000, 8194 /*quiet*/1); 8195 8196 cam_freeccb(ccb); 8197 return (retval); 8198} 8199 8200int 8201scsigetopcodes(struct cam_device *device, int opcode_set, int opcode, 8202 int show_sa_errors, int sa_set, int service_action, 8203 int timeout_desc, int retry_count, int timeout, int verbosemode, 8204 uint32_t *fill_len, uint8_t **data_ptr) 8205{ 8206 union ccb *ccb = NULL; 8207 uint8_t *buf = NULL; 8208 uint32_t alloc_len = 0, num_opcodes; 8209 uint32_t valid_len = 0; 8210 uint32_t avail_len = 0; 8211 struct scsi_report_supported_opcodes_all *all_hdr; 8212 struct scsi_report_supported_opcodes_one *one; 8213 int options = 0; 8214 int retval = 0; 8215 8216 /* 8217 * Make it clear that we haven't yet allocated or filled anything. 8218 */ 8219 *fill_len = 0; 8220 *data_ptr = NULL; 8221 8222 ccb = cam_getccb(device); 8223 if (ccb == NULL) { 8224 warnx("couldn't allocate CCB"); 8225 retval = 1; 8226 goto bailout; 8227 } 8228 8229 /* cam_getccb cleans up the header, caller has to zero the payload */ 8230 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 8231 8232 if (opcode_set != 0) { 8233 options |= RSO_OPTIONS_OC; 8234 num_opcodes = 1; 8235 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN; 8236 } else { 8237 num_opcodes = 256; 8238 alloc_len = sizeof(*all_hdr) + (num_opcodes * 8239 sizeof(struct scsi_report_supported_opcodes_descr)); 8240 } 8241 8242 if (timeout_desc != 0) { 8243 options |= RSO_RCTD; 8244 alloc_len += num_opcodes * 8245 sizeof(struct scsi_report_supported_opcodes_timeout); 8246 } 8247 8248 if (sa_set != 0) { 8249 options |= RSO_OPTIONS_OC_SA; 8250 if (show_sa_errors != 0) 8251 options &= ~RSO_OPTIONS_OC; 8252 } 8253 8254retry_alloc: 8255 if (buf != NULL) { 8256 free(buf); 8257 buf = NULL; 8258 } 8259 8260 buf = malloc(alloc_len); 8261 if (buf == NULL) { 8262 warn("Unable to allocate %u bytes", alloc_len); 8263 retval = 1; 8264 goto bailout; 8265 } 8266 bzero(buf, alloc_len); 8267 8268 scsi_report_supported_opcodes(&ccb->csio, 8269 /*retries*/ retry_count, 8270 /*cbfcnp*/ NULL, 8271 /*tag_action*/ MSG_SIMPLE_Q_TAG, 8272 /*options*/ options, 8273 /*req_opcode*/ opcode, 8274 /*req_service_action*/ service_action, 8275 /*data_ptr*/ buf, 8276 /*dxfer_len*/ alloc_len, 8277 /*sense_len*/ SSD_FULL_SIZE, 8278 /*timeout*/ timeout ? timeout : 10000); 8279 8280 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 8281 8282 if (retry_count != 0) 8283 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 8284 8285 if (cam_send_ccb(device, ccb) < 0) { 8286 perror("error sending REPORT SUPPORTED OPERATION CODES"); 8287 retval = 1; 8288 goto bailout; 8289 } 8290 8291 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 8292 if (verbosemode != 0) 8293 cam_error_print(device, ccb, CAM_ESF_ALL, 8294 CAM_EPF_ALL, stderr); 8295 8296 retval = 1; 8297 goto bailout; 8298 } 8299 8300 valid_len = ccb->csio.dxfer_len - ccb->csio.resid; 8301 8302 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL) 8303 && (valid_len >= sizeof(*all_hdr))) { 8304 all_hdr = (struct scsi_report_supported_opcodes_all *)buf; 8305 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr); 8306 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL) 8307 && (valid_len >= sizeof(*one))) { 8308 uint32_t cdb_length; 8309 8310 one = (struct scsi_report_supported_opcodes_one *)buf; 8311 cdb_length = scsi_2btoul(one->cdb_length); 8312 avail_len = sizeof(*one) + cdb_length; 8313 if (one->support & RSO_ONE_CTDP) { 8314 struct scsi_report_supported_opcodes_timeout *td; 8315 8316 td = (struct scsi_report_supported_opcodes_timeout *) 8317 &buf[avail_len]; 8318 if (valid_len >= (avail_len + sizeof(td->length))) { 8319 avail_len += scsi_2btoul(td->length) + 8320 sizeof(td->length); 8321 } else { 8322 avail_len += sizeof(*td); 8323 } 8324 } 8325 } 8326 8327 /* 8328 * avail_len could be zero if we didn't get enough data back from 8329 * thet target to determine 8330 */ 8331 if ((avail_len != 0) 8332 && (avail_len > valid_len)) { 8333 alloc_len = avail_len; 8334 goto retry_alloc; 8335 } 8336 8337 *fill_len = valid_len; 8338 *data_ptr = buf; 8339bailout: 8340 if (retval != 0) 8341 free(buf); 8342 8343 cam_freeccb(ccb); 8344 8345 return (retval); 8346} 8347 8348static int 8349scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set, 8350 int req_sa, uint8_t *buf, uint32_t valid_len) 8351{ 8352 struct scsi_report_supported_opcodes_one *one; 8353 struct scsi_report_supported_opcodes_timeout *td; 8354 uint32_t cdb_len = 0, td_len = 0; 8355 const char *op_desc = NULL; 8356 unsigned int i; 8357 int retval = 0; 8358 8359 one = (struct scsi_report_supported_opcodes_one *)buf; 8360 8361 /* 8362 * If we don't have the full single opcode descriptor, no point in 8363 * continuing. 8364 */ 8365 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one, 8366 cdb_length)) { 8367 warnx("Only %u bytes returned, not enough to verify support", 8368 valid_len); 8369 retval = 1; 8370 goto bailout; 8371 } 8372 8373 op_desc = scsi_op_desc(req_opcode, &device->inq_data); 8374 8375 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN", 8376 req_opcode); 8377 if (sa_set != 0) 8378 printf(", SA 0x%x", req_sa); 8379 printf(": "); 8380 8381 switch (one->support & RSO_ONE_SUP_MASK) { 8382 case RSO_ONE_SUP_UNAVAIL: 8383 printf("No command support information currently available\n"); 8384 break; 8385 case RSO_ONE_SUP_NOT_SUP: 8386 printf("Command not supported\n"); 8387 retval = 1; 8388 goto bailout; 8389 break; /*NOTREACHED*/ 8390 case RSO_ONE_SUP_AVAIL: 8391 printf("Command is supported, complies with a SCSI standard\n"); 8392 break; 8393 case RSO_ONE_SUP_VENDOR: 8394 printf("Command is supported, vendor-specific " 8395 "implementation\n"); 8396 break; 8397 default: 8398 printf("Unknown command support flags 0x%#x\n", 8399 one->support & RSO_ONE_SUP_MASK); 8400 break; 8401 } 8402 8403 /* 8404 * If we don't have the CDB length, it isn't exactly an error, the 8405 * command probably isn't supported. 8406 */ 8407 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one, 8408 cdb_usage)) 8409 goto bailout; 8410 8411 cdb_len = scsi_2btoul(one->cdb_length); 8412 8413 /* 8414 * If our valid data doesn't include the full reported length, 8415 * return. The caller should have detected this and adjusted his 8416 * allocation length to get all of the available data. 8417 */ 8418 if (valid_len < sizeof(*one) + cdb_len) { 8419 retval = 1; 8420 goto bailout; 8421 } 8422 8423 /* 8424 * If all we have is the opcode, there is no point in printing out 8425 * the usage bitmap. 8426 */ 8427 if (cdb_len <= 1) { 8428 retval = 1; 8429 goto bailout; 8430 } 8431 8432 printf("CDB usage bitmap:"); 8433 for (i = 0; i < cdb_len; i++) { 8434 printf(" %02x", one->cdb_usage[i]); 8435 } 8436 printf("\n"); 8437 8438 /* 8439 * If we don't have a timeout descriptor, we're done. 8440 */ 8441 if ((one->support & RSO_ONE_CTDP) == 0) 8442 goto bailout; 8443 8444 /* 8445 * If we don't have enough valid length to include the timeout 8446 * descriptor length, we're done. 8447 */ 8448 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length))) 8449 goto bailout; 8450 8451 td = (struct scsi_report_supported_opcodes_timeout *) 8452 &buf[sizeof(*one) + cdb_len]; 8453 td_len = scsi_2btoul(td->length); 8454 td_len += sizeof(td->length); 8455 8456 /* 8457 * If we don't have the full timeout descriptor, we're done. 8458 */ 8459 if (td_len < sizeof(*td)) 8460 goto bailout; 8461 8462 /* 8463 * If we don't have enough valid length to contain the full timeout 8464 * descriptor, we're done. 8465 */ 8466 if (valid_len < (sizeof(*one) + cdb_len + td_len)) 8467 goto bailout; 8468 8469 printf("Timeout information:\n"); 8470 printf("Command-specific: 0x%02x\n", td->cmd_specific); 8471 printf("Nominal timeout: %u seconds\n", 8472 scsi_4btoul(td->nominal_time)); 8473 printf("Recommended timeout: %u seconds\n", 8474 scsi_4btoul(td->recommended_time)); 8475 8476bailout: 8477 return (retval); 8478} 8479 8480static int 8481scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf, 8482 uint32_t valid_len) 8483{ 8484 struct scsi_report_supported_opcodes_all *hdr; 8485 struct scsi_report_supported_opcodes_descr *desc; 8486 uint32_t avail_len = 0, used_len = 0; 8487 uint8_t *cur_ptr; 8488 int retval = 0; 8489 8490 if (valid_len < sizeof(*hdr)) { 8491 warnx("%s: not enough returned data (%u bytes) opcode list", 8492 __func__, valid_len); 8493 retval = 1; 8494 goto bailout; 8495 } 8496 hdr = (struct scsi_report_supported_opcodes_all *)buf; 8497 avail_len = scsi_4btoul(hdr->length); 8498 avail_len += sizeof(hdr->length); 8499 /* 8500 * Take the lesser of the amount of data the drive claims is 8501 * available, and the amount of data the HBA says was returned. 8502 */ 8503 avail_len = MIN(avail_len, valid_len); 8504 8505 used_len = sizeof(hdr->length); 8506 8507 printf("%-6s %4s %8s ", 8508 "Opcode", "SA", "CDB len" ); 8509 8510 if (td_req != 0) 8511 printf("%5s %6s %6s ", "CS", "Nom", "Rec"); 8512 printf(" Description\n"); 8513 8514 while ((avail_len - used_len) > sizeof(*desc)) { 8515 struct scsi_report_supported_opcodes_timeout *td; 8516 uint32_t td_len; 8517 const char *op_desc = NULL; 8518 8519 cur_ptr = &buf[used_len]; 8520 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr; 8521 8522 op_desc = scsi_op_desc(desc->opcode, &device->inq_data); 8523 if (op_desc == NULL) 8524 op_desc = "UNKNOWN"; 8525 8526 printf("0x%02x %#4x %8u ", desc->opcode, 8527 scsi_2btoul(desc->service_action), 8528 scsi_2btoul(desc->cdb_length)); 8529 8530 used_len += sizeof(*desc); 8531 8532 if ((desc->flags & RSO_CTDP) == 0) { 8533 printf(" %s\n", op_desc); 8534 continue; 8535 } 8536 8537 /* 8538 * If we don't have enough space to fit a timeout 8539 * descriptor, then we're done. 8540 */ 8541 if (avail_len - used_len < sizeof(*td)) { 8542 used_len = avail_len; 8543 printf(" %s\n", op_desc); 8544 continue; 8545 } 8546 cur_ptr = &buf[used_len]; 8547 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr; 8548 td_len = scsi_2btoul(td->length); 8549 td_len += sizeof(td->length); 8550 8551 used_len += td_len; 8552 /* 8553 * If the given timeout descriptor length is less than what 8554 * we understand, skip it. 8555 */ 8556 if (td_len < sizeof(*td)) { 8557 printf(" %s\n", op_desc); 8558 continue; 8559 } 8560 8561 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific, 8562 scsi_4btoul(td->nominal_time), 8563 scsi_4btoul(td->recommended_time), op_desc); 8564 } 8565bailout: 8566 return (retval); 8567} 8568 8569static int 8570scsiopcodes(struct cam_device *device, int argc, char **argv, 8571 char *combinedopt, int retry_count, int timeout, int verbosemode) 8572{ 8573 int c; 8574 uint32_t opcode = 0, service_action = 0; 8575 int td_set = 0, opcode_set = 0, sa_set = 0; 8576 int show_sa_errors = 1; 8577 uint32_t valid_len = 0; 8578 uint8_t *buf = NULL; 8579 char *endptr; 8580 int retval = 0; 8581 8582 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8583 switch (c) { 8584 case 'N': 8585 show_sa_errors = 0; 8586 break; 8587 case 'o': 8588 opcode = strtoul(optarg, &endptr, 0); 8589 if (*endptr != '\0') { 8590 warnx("Invalid opcode \"%s\", must be a number", 8591 optarg); 8592 retval = 1; 8593 goto bailout; 8594 } 8595 if (opcode > 0xff) { 8596 warnx("Invalid opcode 0x%#x, must be between" 8597 "0 and 0xff inclusive", opcode); 8598 retval = 1; 8599 goto bailout; 8600 } 8601 opcode_set = 1; 8602 break; 8603 case 's': 8604 service_action = strtoul(optarg, &endptr, 0); 8605 if (*endptr != '\0') { 8606 warnx("Invalid service action \"%s\", must " 8607 "be a number", optarg); 8608 retval = 1; 8609 goto bailout; 8610 } 8611 if (service_action > 0xffff) { 8612 warnx("Invalid service action 0x%#x, must " 8613 "be between 0 and 0xffff inclusive", 8614 service_action); 8615 retval = 1; 8616 } 8617 sa_set = 1; 8618 break; 8619 case 'T': 8620 td_set = 1; 8621 break; 8622 default: 8623 break; 8624 } 8625 } 8626 8627 if ((sa_set != 0) 8628 && (opcode_set == 0)) { 8629 warnx("You must specify an opcode with -o if a service " 8630 "action is given"); 8631 retval = 1; 8632 goto bailout; 8633 } 8634 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors, 8635 sa_set, service_action, td_set, retry_count, 8636 timeout, verbosemode, &valid_len, &buf); 8637 if (retval != 0) 8638 goto bailout; 8639 8640 if ((opcode_set != 0) 8641 || (sa_set != 0)) { 8642 retval = scsiprintoneopcode(device, opcode, sa_set, 8643 service_action, buf, valid_len); 8644 } else { 8645 retval = scsiprintopcodes(device, td_set, buf, valid_len); 8646 } 8647 8648bailout: 8649 free(buf); 8650 8651 return (retval); 8652} 8653 8654#endif /* MINIMALISTIC */ 8655 8656static int 8657scsireprobe(struct cam_device *device) 8658{ 8659 union ccb *ccb; 8660 int retval = 0; 8661 8662 ccb = cam_getccb(device); 8663 8664 if (ccb == NULL) { 8665 warnx("%s: error allocating ccb", __func__); 8666 return (1); 8667 } 8668 8669 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 8670 8671 ccb->ccb_h.func_code = XPT_REPROBE_LUN; 8672 8673 if (cam_send_ccb(device, ccb) < 0) { 8674 warn("error sending XPT_REPROBE_LUN CCB"); 8675 retval = 1; 8676 goto bailout; 8677 } 8678 8679 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 8680 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 8681 retval = 1; 8682 goto bailout; 8683 } 8684 8685bailout: 8686 cam_freeccb(ccb); 8687 8688 return (retval); 8689} 8690 8691void 8692usage(int printlong) 8693{ 8694 8695 fprintf(printlong ? stdout : stderr, 8696"usage: camcontrol <command> [device id][generic args][command args]\n" 8697" camcontrol devlist [-b] [-v]\n" 8698#ifndef MINIMALISTIC 8699" camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n" 8700" camcontrol tur [dev_id][generic args]\n" 8701" camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n" 8702" camcontrol identify [dev_id][generic args] [-v]\n" 8703" camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n" 8704" camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n" 8705" [-q] [-s]\n" 8706" camcontrol start [dev_id][generic args]\n" 8707" camcontrol stop [dev_id][generic args]\n" 8708" camcontrol load [dev_id][generic args]\n" 8709" camcontrol eject [dev_id][generic args]\n" 8710" camcontrol reprobe [dev_id][generic args]\n" 8711#endif /* MINIMALISTIC */ 8712" camcontrol rescan <all | bus[:target:lun]>\n" 8713" camcontrol reset <all | bus[:target:lun]>\n" 8714#ifndef MINIMALISTIC 8715" camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n" 8716" [-q][-s][-S offset][-X]\n" 8717" camcontrol modepage [dev_id][generic args] <-m page | -l>\n" 8718" [-P pagectl][-e | -b][-d]\n" 8719" camcontrol cmd [dev_id][generic args]\n" 8720" <-a cmd [args] | -c cmd [args]>\n" 8721" [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n" 8722" camcontrol smpcmd [dev_id][generic args]\n" 8723" <-r len fmt [args]> <-R len fmt [args]>\n" 8724" camcontrol smprg [dev_id][generic args][-l]\n" 8725" camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n" 8726" [-o operation][-d name][-m rate][-M rate]\n" 8727" [-T pp_timeout][-a enable|disable]\n" 8728" [-A enable|disable][-s enable|disable]\n" 8729" [-S enable|disable]\n" 8730" camcontrol smpphylist [dev_id][generic args][-l][-q]\n" 8731" camcontrol smpmaninfo [dev_id][generic args][-l]\n" 8732" camcontrol debug [-I][-P][-T][-S][-X][-c]\n" 8733" <all|bus[:target[:lun]]|off>\n" 8734" camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n" 8735" camcontrol negotiate [dev_id][generic args] [-a][-c]\n" 8736" [-D <enable|disable>][-M mode][-O offset]\n" 8737" [-q][-R syncrate][-v][-T <enable|disable>]\n" 8738" [-U][-W bus_width]\n" 8739" camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n" 8740" camcontrol sanitize [dev_id][generic args]\n" 8741" [-a overwrite|block|crypto|exitfailure]\n" 8742" [-c passes][-I][-P pattern][-q][-U][-r][-w]\n" 8743" [-y]\n" 8744" camcontrol idle [dev_id][generic args][-t time]\n" 8745" camcontrol standby [dev_id][generic args][-t time]\n" 8746" camcontrol sleep [dev_id][generic args]\n" 8747" camcontrol apm [dev_id][generic args][-l level]\n" 8748" camcontrol aam [dev_id][generic args][-l level]\n" 8749" camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n" 8750" [-s][-y]\n" 8751" camcontrol security [dev_id][generic args]\n" 8752" <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n" 8753" [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n" 8754" [-U <user|master>] [-y]\n" 8755" camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n" 8756" [-q] [-s max_sectors] [-U pwd] [-y]\n" 8757" camcontrol persist [dev_id][generic args] <-i action|-o action>\n" 8758" [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n" 8759" [-s scope][-S][-T type][-U]\n" 8760" camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n" 8761" [-a attr_num][-c][-e elem][-F form1,form1]\n" 8762" [-p part][-s start][-T type][-V vol]\n" 8763" camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n" 8764" [-N][-T]\n" 8765#endif /* MINIMALISTIC */ 8766" camcontrol help\n"); 8767 if (!printlong) 8768 return; 8769#ifndef MINIMALISTIC 8770 fprintf(stdout, 8771"Specify one of the following options:\n" 8772"devlist list all CAM devices\n" 8773"periphlist list all CAM peripheral drivers attached to a device\n" 8774"tur send a test unit ready to the named device\n" 8775"inquiry send a SCSI inquiry command to the named device\n" 8776"identify send a ATA identify command to the named device\n" 8777"reportluns send a SCSI report luns command to the device\n" 8778"readcap send a SCSI read capacity command to the device\n" 8779"start send a Start Unit command to the device\n" 8780"stop send a Stop Unit command to the device\n" 8781"load send a Start Unit command to the device with the load bit set\n" 8782"eject send a Stop Unit command to the device with the eject bit set\n" 8783"reprobe update capacity information of the given device\n" 8784"rescan rescan all busses, the given bus, or bus:target:lun\n" 8785"reset reset all busses, the given bus, or bus:target:lun\n" 8786"defects read the defect list of the specified device\n" 8787"modepage display or edit (-e) the given mode page\n" 8788"cmd send the given SCSI command, may need -i or -o as well\n" 8789"smpcmd send the given SMP command, requires -o and -i\n" 8790"smprg send the SMP Report General command\n" 8791"smppc send the SMP PHY Control command, requires -p\n" 8792"smpphylist display phys attached to a SAS expander\n" 8793"smpmaninfo send the SMP Report Manufacturer Info command\n" 8794"debug turn debugging on/off for a bus, target, or lun, or all devices\n" 8795"tags report or set the number of transaction slots for a device\n" 8796"negotiate report or set device negotiation parameters\n" 8797"format send the SCSI FORMAT UNIT command to the named device\n" 8798"sanitize send the SCSI SANITIZE command to the named device\n" 8799"idle send the ATA IDLE command to the named device\n" 8800"standby send the ATA STANDBY command to the named device\n" 8801"sleep send the ATA SLEEP command to the named device\n" 8802"fwdownload program firmware of the named device with the given image\n" 8803"security report or send ATA security commands to the named device\n" 8804"persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n" 8805"attrib send the SCSI READ or WRITE ATTRIBUTE commands\n" 8806"opcodes send the SCSI REPORT SUPPORTED OPCODES command\n" 8807"help this message\n" 8808"Device Identifiers:\n" 8809"bus:target specify the bus and target, lun defaults to 0\n" 8810"bus:target:lun specify the bus, target and lun\n" 8811"deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n" 8812"Generic arguments:\n" 8813"-v be verbose, print out sense information\n" 8814"-t timeout command timeout in seconds, overrides default timeout\n" 8815"-n dev_name specify device name, e.g. \"da\", \"cd\"\n" 8816"-u unit specify unit number, e.g. \"0\", \"5\"\n" 8817"-E have the kernel attempt to perform SCSI error recovery\n" 8818"-C count specify the SCSI command retry count (needs -E to work)\n" 8819"modepage arguments:\n" 8820"-l list all available mode pages\n" 8821"-m page specify the mode page to view or edit\n" 8822"-e edit the specified mode page\n" 8823"-b force view to binary mode\n" 8824"-d disable block descriptors for mode sense\n" 8825"-P pgctl page control field 0-3\n" 8826"defects arguments:\n" 8827"-f format specify defect list format (block, bfi or phys)\n" 8828"-G get the grown defect list\n" 8829"-P get the permanent defect list\n" 8830"inquiry arguments:\n" 8831"-D get the standard inquiry data\n" 8832"-S get the serial number\n" 8833"-R get the transfer rate, etc.\n" 8834"reportluns arguments:\n" 8835"-c only report a count of available LUNs\n" 8836"-l only print out luns, and not a count\n" 8837"-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n" 8838"readcap arguments\n" 8839"-b only report the blocksize\n" 8840"-h human readable device size, base 2\n" 8841"-H human readable device size, base 10\n" 8842"-N print the number of blocks instead of last block\n" 8843"-q quiet, print numbers only\n" 8844"-s only report the last block/device size\n" 8845"cmd arguments:\n" 8846"-c cdb [args] specify the SCSI CDB\n" 8847"-i len fmt specify input data and input data format\n" 8848"-o len fmt [args] specify output data and output data fmt\n" 8849"smpcmd arguments:\n" 8850"-r len fmt [args] specify the SMP command to be sent\n" 8851"-R len fmt [args] specify SMP response format\n" 8852"smprg arguments:\n" 8853"-l specify the long response format\n" 8854"smppc arguments:\n" 8855"-p phy specify the PHY to operate on\n" 8856"-l specify the long request/response format\n" 8857"-o operation specify the phy control operation\n" 8858"-d name set the attached device name\n" 8859"-m rate set the minimum physical link rate\n" 8860"-M rate set the maximum physical link rate\n" 8861"-T pp_timeout set the partial pathway timeout value\n" 8862"-a enable|disable enable or disable SATA slumber\n" 8863"-A enable|disable enable or disable SATA partial phy power\n" 8864"-s enable|disable enable or disable SAS slumber\n" 8865"-S enable|disable enable or disable SAS partial phy power\n" 8866"smpphylist arguments:\n" 8867"-l specify the long response format\n" 8868"-q only print phys with attached devices\n" 8869"smpmaninfo arguments:\n" 8870"-l specify the long response format\n" 8871"debug arguments:\n" 8872"-I CAM_DEBUG_INFO -- scsi commands, errors, data\n" 8873"-T CAM_DEBUG_TRACE -- routine flow tracking\n" 8874"-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n" 8875"-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n" 8876"tags arguments:\n" 8877"-N tags specify the number of tags to use for this device\n" 8878"-q be quiet, don't report the number of tags\n" 8879"-v report a number of tag-related parameters\n" 8880"negotiate arguments:\n" 8881"-a send a test unit ready after negotiation\n" 8882"-c report/set current negotiation settings\n" 8883"-D <arg> \"enable\" or \"disable\" disconnection\n" 8884"-M mode set ATA mode\n" 8885"-O offset set command delay offset\n" 8886"-q be quiet, don't report anything\n" 8887"-R syncrate synchronization rate in MHz\n" 8888"-T <arg> \"enable\" or \"disable\" tagged queueing\n" 8889"-U report/set user negotiation settings\n" 8890"-W bus_width set the bus width in bits (8, 16 or 32)\n" 8891"-v also print a Path Inquiry CCB for the controller\n" 8892"format arguments:\n" 8893"-q be quiet, don't print status messages\n" 8894"-r run in report only mode\n" 8895"-w don't send immediate format command\n" 8896"-y don't ask any questions\n" 8897"sanitize arguments:\n" 8898"-a operation operation mode: overwrite, block, crypto or exitfailure\n" 8899"-c passes overwrite passes to perform (1 to 31)\n" 8900"-I invert overwrite pattern after each pass\n" 8901"-P pattern path to overwrite pattern file\n" 8902"-q be quiet, don't print status messages\n" 8903"-r run in report only mode\n" 8904"-U run operation in unrestricted completion exit mode\n" 8905"-w don't send immediate sanitize command\n" 8906"-y don't ask any questions\n" 8907"idle/standby arguments:\n" 8908"-t <arg> number of seconds before respective state.\n" 8909"fwdownload arguments:\n" 8910"-f fw_image path to firmware image file\n" 8911"-q don't print informational messages, only errors\n" 8912"-s run in simulation mode\n" 8913"-v print info for every firmware segment sent to device\n" 8914"-y don't ask any questions\n" 8915"security arguments:\n" 8916"-d pwd disable security using the given password for the selected\n" 8917" user\n" 8918"-e pwd erase the device using the given pwd for the selected user\n" 8919"-f freeze the security configuration of the specified device\n" 8920"-h pwd enhanced erase the device using the given pwd for the\n" 8921" selected user\n" 8922"-k pwd unlock the device using the given pwd for the selected\n" 8923" user\n" 8924"-l <high|maximum> specifies which security level to set: high or maximum\n" 8925"-q be quiet, do not print any status messages\n" 8926"-s pwd password the device (enable security) using the given\n" 8927" pwd for the selected user\n" 8928"-T timeout overrides the timeout (seconds) used for erase operation\n" 8929"-U <user|master> specifies which user to set: user or master\n" 8930"-y don't ask any questions\n" 8931"hpa arguments:\n" 8932"-f freeze the HPA configuration of the device\n" 8933"-l lock the HPA configuration of the device\n" 8934"-P make the HPA max sectors persist\n" 8935"-p pwd Set the HPA configuration password required for unlock\n" 8936" calls\n" 8937"-q be quiet, do not print any status messages\n" 8938"-s sectors configures the maximum user accessible sectors of the\n" 8939" device\n" 8940"-U pwd unlock the HPA configuration of the device\n" 8941"-y don't ask any questions\n" 8942"persist arguments:\n" 8943"-i action specify read_keys, read_reservation, report_cap, or\n" 8944" read_full_status\n" 8945"-o action specify register, register_ignore, reserve, release,\n" 8946" clear, preempt, preempt_abort, register_move, replace_lost\n" 8947"-a set the All Target Ports (ALL_TG_PT) bit\n" 8948"-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n" 8949"-k key specify the Reservation Key\n" 8950"-K sa_key specify the Service Action Reservation Key\n" 8951"-p set the Activate Persist Through Power Loss bit\n" 8952"-R rtp specify the Relative Target Port\n" 8953"-s scope specify the scope: lun, extent, element or a number\n" 8954"-S specify Transport ID for register, requires -I\n" 8955"-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n" 8956" ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n" 8957"-U unregister the current initiator for register_move\n" 8958"attrib arguments:\n" 8959"-r action specify attr_values, attr_list, lv_list, part_list, or\n" 8960" supp_attr\n" 8961"-w attr specify an attribute to write, one -w argument per attr\n" 8962"-a attr_num only display this attribute number\n" 8963"-c get cached attributes\n" 8964"-e elem_addr request attributes for the given element in a changer\n" 8965"-F form1,form2 output format, comma separated list: text_esc, text_raw,\n" 8966" nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n" 8967" field_none, field_desc, field_num, field_size, field_rw\n" 8968"-p partition request attributes for the given partition\n" 8969"-s start_attr request attributes starting at the given number\n" 8970"-T elem_type specify the element type (used with -e)\n" 8971"-V logical_vol specify the logical volume ID\n" 8972"opcodes arguments:\n" 8973"-o opcode specify the individual opcode to list\n" 8974"-s service_action specify the service action for the opcode\n" 8975"-N do not return SCSI error for unsupported SA\n" 8976"-T request nominal and recommended timeout values\n" 8977); 8978#endif /* MINIMALISTIC */ 8979} 8980 8981int 8982main(int argc, char **argv) 8983{ 8984 int c; 8985 char *device = NULL; 8986 int unit = 0; 8987 struct cam_device *cam_dev = NULL; 8988 int timeout = 0, retry_count = 1; 8989 camcontrol_optret optreturn; 8990 char *tstr; 8991 const char *mainopt = "C:En:t:u:v"; 8992 const char *subopt = NULL; 8993 char combinedopt[256]; 8994 int error = 0, optstart = 2; 8995 int devopen = 1; 8996#ifndef MINIMALISTIC 8997 path_id_t bus; 8998 target_id_t target; 8999 lun_id_t lun; 9000#endif /* MINIMALISTIC */ 9001 9002 cmdlist = CAM_CMD_NONE; 9003 arglist = CAM_ARG_NONE; 9004 9005 if (argc < 2) { 9006 usage(0); 9007 exit(1); 9008 } 9009 9010 /* 9011 * Get the base option. 9012 */ 9013 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt); 9014 9015 if (optreturn == CC_OR_AMBIGUOUS) { 9016 warnx("ambiguous option %s", argv[1]); 9017 usage(0); 9018 exit(1); 9019 } else if (optreturn == CC_OR_NOT_FOUND) { 9020 warnx("option %s not found", argv[1]); 9021 usage(0); 9022 exit(1); 9023 } 9024 9025 /* 9026 * Ahh, getopt(3) is a pain. 9027 * 9028 * This is a gross hack. There really aren't many other good 9029 * options (excuse the pun) for parsing options in a situation like 9030 * this. getopt is kinda braindead, so you end up having to run 9031 * through the options twice, and give each invocation of getopt 9032 * the option string for the other invocation. 9033 * 9034 * You would think that you could just have two groups of options. 9035 * The first group would get parsed by the first invocation of 9036 * getopt, and the second group would get parsed by the second 9037 * invocation of getopt. It doesn't quite work out that way. When 9038 * the first invocation of getopt finishes, it leaves optind pointing 9039 * to the argument _after_ the first argument in the second group. 9040 * So when the second invocation of getopt comes around, it doesn't 9041 * recognize the first argument it gets and then bails out. 9042 * 9043 * A nice alternative would be to have a flag for getopt that says 9044 * "just keep parsing arguments even when you encounter an unknown 9045 * argument", but there isn't one. So there's no real clean way to 9046 * easily parse two sets of arguments without having one invocation 9047 * of getopt know about the other. 9048 * 9049 * Without this hack, the first invocation of getopt would work as 9050 * long as the generic arguments are first, but the second invocation 9051 * (in the subfunction) would fail in one of two ways. In the case 9052 * where you don't set optreset, it would fail because optind may be 9053 * pointing to the argument after the one it should be pointing at. 9054 * In the case where you do set optreset, and reset optind, it would 9055 * fail because getopt would run into the first set of options, which 9056 * it doesn't understand. 9057 * 9058 * All of this would "sort of" work if you could somehow figure out 9059 * whether optind had been incremented one option too far. The 9060 * mechanics of that, however, are more daunting than just giving 9061 * both invocations all of the expect options for either invocation. 9062 * 9063 * Needless to say, I wouldn't mind if someone invented a better 9064 * (non-GPL!) command line parsing interface than getopt. I 9065 * wouldn't mind if someone added more knobs to getopt to make it 9066 * work better. Who knows, I may talk myself into doing it someday, 9067 * if the standards weenies let me. As it is, it just leads to 9068 * hackery like this and causes people to avoid it in some cases. 9069 * 9070 * KDM, September 8th, 1998 9071 */ 9072 if (subopt != NULL) 9073 sprintf(combinedopt, "%s%s", mainopt, subopt); 9074 else 9075 sprintf(combinedopt, "%s", mainopt); 9076 9077 /* 9078 * For these options we do not parse optional device arguments and 9079 * we do not open a passthrough device. 9080 */ 9081 if ((cmdlist == CAM_CMD_RESCAN) 9082 || (cmdlist == CAM_CMD_RESET) 9083 || (cmdlist == CAM_CMD_DEVTREE) 9084 || (cmdlist == CAM_CMD_USAGE) 9085 || (cmdlist == CAM_CMD_DEBUG)) 9086 devopen = 0; 9087 9088#ifndef MINIMALISTIC 9089 if ((devopen == 1) 9090 && (argc > 2 && argv[2][0] != '-')) { 9091 char name[30]; 9092 int rv; 9093 9094 if (isdigit(argv[2][0])) { 9095 /* device specified as bus:target[:lun] */ 9096 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist); 9097 if (rv < 2) 9098 errx(1, "numeric device specification must " 9099 "be either bus:target, or " 9100 "bus:target:lun"); 9101 /* default to 0 if lun was not specified */ 9102 if ((arglist & CAM_ARG_LUN) == 0) { 9103 lun = 0; 9104 arglist |= CAM_ARG_LUN; 9105 } 9106 optstart++; 9107 } else { 9108 if (cam_get_device(argv[2], name, sizeof name, &unit) 9109 == -1) 9110 errx(1, "%s", cam_errbuf); 9111 device = strdup(name); 9112 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT; 9113 optstart++; 9114 } 9115 } 9116#endif /* MINIMALISTIC */ 9117 /* 9118 * Start getopt processing at argv[2/3], since we've already 9119 * accepted argv[1..2] as the command name, and as a possible 9120 * device name. 9121 */ 9122 optind = optstart; 9123 9124 /* 9125 * Now we run through the argument list looking for generic 9126 * options, and ignoring options that possibly belong to 9127 * subfunctions. 9128 */ 9129 while ((c = getopt(argc, argv, combinedopt))!= -1){ 9130 switch(c) { 9131 case 'C': 9132 retry_count = strtol(optarg, NULL, 0); 9133 if (retry_count < 0) 9134 errx(1, "retry count %d is < 0", 9135 retry_count); 9136 arglist |= CAM_ARG_RETRIES; 9137 break; 9138 case 'E': 9139 arglist |= CAM_ARG_ERR_RECOVER; 9140 break; 9141 case 'n': 9142 arglist |= CAM_ARG_DEVICE; 9143 tstr = optarg; 9144 while (isspace(*tstr) && (*tstr != '\0')) 9145 tstr++; 9146 device = (char *)strdup(tstr); 9147 break; 9148 case 't': 9149 timeout = strtol(optarg, NULL, 0); 9150 if (timeout < 0) 9151 errx(1, "invalid timeout %d", timeout); 9152 /* Convert the timeout from seconds to ms */ 9153 timeout *= 1000; 9154 arglist |= CAM_ARG_TIMEOUT; 9155 break; 9156 case 'u': 9157 arglist |= CAM_ARG_UNIT; 9158 unit = strtol(optarg, NULL, 0); 9159 break; 9160 case 'v': 9161 arglist |= CAM_ARG_VERBOSE; 9162 break; 9163 default: 9164 break; 9165 } 9166 } 9167 9168#ifndef MINIMALISTIC 9169 /* 9170 * For most commands we'll want to open the passthrough device 9171 * associated with the specified device. In the case of the rescan 9172 * commands, we don't use a passthrough device at all, just the 9173 * transport layer device. 9174 */ 9175 if (devopen == 1) { 9176 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0) 9177 && (((arglist & CAM_ARG_DEVICE) == 0) 9178 || ((arglist & CAM_ARG_UNIT) == 0))) { 9179 errx(1, "subcommand \"%s\" requires a valid device " 9180 "identifier", argv[1]); 9181 } 9182 9183 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))? 9184 cam_open_btl(bus, target, lun, O_RDWR, NULL) : 9185 cam_open_spec_device(device,unit,O_RDWR,NULL))) 9186 == NULL) 9187 errx(1,"%s", cam_errbuf); 9188 } 9189#endif /* MINIMALISTIC */ 9190 9191 /* 9192 * Reset optind to 2, and reset getopt, so these routines can parse 9193 * the arguments again. 9194 */ 9195 optind = optstart; 9196 optreset = 1; 9197 9198 switch(cmdlist) { 9199#ifndef MINIMALISTIC 9200 case CAM_CMD_DEVLIST: 9201 error = getdevlist(cam_dev); 9202 break; 9203 case CAM_CMD_HPA: 9204 error = atahpa(cam_dev, retry_count, timeout, 9205 argc, argv, combinedopt); 9206 break; 9207#endif /* MINIMALISTIC */ 9208 case CAM_CMD_DEVTREE: 9209 error = getdevtree(argc, argv, combinedopt); 9210 break; 9211#ifndef MINIMALISTIC 9212 case CAM_CMD_TUR: 9213 error = testunitready(cam_dev, retry_count, timeout, 0); 9214 break; 9215 case CAM_CMD_INQUIRY: 9216 error = scsidoinquiry(cam_dev, argc, argv, combinedopt, 9217 retry_count, timeout); 9218 break; 9219 case CAM_CMD_IDENTIFY: 9220 error = ataidentify(cam_dev, retry_count, timeout); 9221 break; 9222 case CAM_CMD_STARTSTOP: 9223 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT, 9224 arglist & CAM_ARG_EJECT, retry_count, 9225 timeout); 9226 break; 9227#endif /* MINIMALISTIC */ 9228 case CAM_CMD_RESCAN: 9229 error = dorescan_or_reset(argc, argv, 1); 9230 break; 9231 case CAM_CMD_RESET: 9232 error = dorescan_or_reset(argc, argv, 0); 9233 break; 9234#ifndef MINIMALISTIC 9235 case CAM_CMD_READ_DEFECTS: 9236 error = readdefects(cam_dev, argc, argv, combinedopt, 9237 retry_count, timeout); 9238 break; 9239 case CAM_CMD_MODE_PAGE: 9240 modepage(cam_dev, argc, argv, combinedopt, 9241 retry_count, timeout); 9242 break; 9243 case CAM_CMD_SCSI_CMD: 9244 error = scsicmd(cam_dev, argc, argv, combinedopt, 9245 retry_count, timeout); 9246 break; 9247 case CAM_CMD_SMP_CMD: 9248 error = smpcmd(cam_dev, argc, argv, combinedopt, 9249 retry_count, timeout); 9250 break; 9251 case CAM_CMD_SMP_RG: 9252 error = smpreportgeneral(cam_dev, argc, argv, 9253 combinedopt, retry_count, 9254 timeout); 9255 break; 9256 case CAM_CMD_SMP_PC: 9257 error = smpphycontrol(cam_dev, argc, argv, combinedopt, 9258 retry_count, timeout); 9259 break; 9260 case CAM_CMD_SMP_PHYLIST: 9261 error = smpphylist(cam_dev, argc, argv, combinedopt, 9262 retry_count, timeout); 9263 break; 9264 case CAM_CMD_SMP_MANINFO: 9265 error = smpmaninfo(cam_dev, argc, argv, combinedopt, 9266 retry_count, timeout); 9267 break; 9268 case CAM_CMD_DEBUG: 9269 error = camdebug(argc, argv, combinedopt); 9270 break; 9271 case CAM_CMD_TAG: 9272 error = tagcontrol(cam_dev, argc, argv, combinedopt); 9273 break; 9274 case CAM_CMD_RATE: 9275 error = ratecontrol(cam_dev, retry_count, timeout, 9276 argc, argv, combinedopt); 9277 break; 9278 case CAM_CMD_FORMAT: 9279 error = scsiformat(cam_dev, argc, argv, 9280 combinedopt, retry_count, timeout); 9281 break; 9282 case CAM_CMD_REPORTLUNS: 9283 error = scsireportluns(cam_dev, argc, argv, 9284 combinedopt, retry_count, 9285 timeout); 9286 break; 9287 case CAM_CMD_READCAP: 9288 error = scsireadcapacity(cam_dev, argc, argv, 9289 combinedopt, retry_count, 9290 timeout); 9291 break; 9292 case CAM_CMD_IDLE: 9293 case CAM_CMD_STANDBY: 9294 case CAM_CMD_SLEEP: 9295 error = atapm(cam_dev, argc, argv, 9296 combinedopt, retry_count, timeout); 9297 break; 9298 case CAM_CMD_APM: 9299 case CAM_CMD_AAM: 9300 error = ataaxm(cam_dev, argc, argv, 9301 combinedopt, retry_count, timeout); 9302 break; 9303 case CAM_CMD_SECURITY: 9304 error = atasecurity(cam_dev, retry_count, timeout, 9305 argc, argv, combinedopt); 9306 break; 9307 case CAM_CMD_DOWNLOAD_FW: 9308 error = fwdownload(cam_dev, argc, argv, combinedopt, 9309 arglist & CAM_ARG_VERBOSE, retry_count, timeout); 9310 break; 9311 case CAM_CMD_SANITIZE: 9312 error = scsisanitize(cam_dev, argc, argv, 9313 combinedopt, retry_count, timeout); 9314 break; 9315 case CAM_CMD_PERSIST: 9316 error = scsipersist(cam_dev, argc, argv, combinedopt, 9317 retry_count, timeout, arglist & CAM_ARG_VERBOSE, 9318 arglist & CAM_ARG_ERR_RECOVER); 9319 break; 9320 case CAM_CMD_ATTRIB: 9321 error = scsiattrib(cam_dev, argc, argv, combinedopt, 9322 retry_count, timeout, arglist & CAM_ARG_VERBOSE, 9323 arglist & CAM_ARG_ERR_RECOVER); 9324 break; 9325 case CAM_CMD_OPCODES: 9326 error = scsiopcodes(cam_dev, argc, argv, combinedopt, 9327 retry_count, timeout, arglist & CAM_ARG_VERBOSE); 9328 break; 9329 case CAM_CMD_REPROBE: 9330 error = scsireprobe(cam_dev); 9331 break; 9332 9333#endif /* MINIMALISTIC */ 9334 case CAM_CMD_USAGE: 9335 usage(1); 9336 break; 9337 default: 9338 usage(0); 9339 error = 1; 9340 break; 9341 } 9342 9343 if (cam_dev != NULL) 9344 cam_close_device(cam_dev); 9345 9346 exit(error); 9347} 9348