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