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