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