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