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