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