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