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