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