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