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