camcontrol.c revision 350774
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 350774 2019-08-08 18:48:48Z 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 : 1000, 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 default: 5197 *devtype = CC_DT_UNKNOWN; 5198 goto bailout; 5199 break; /*NOTREACHED*/ 5200 } 5201 5202 /* 5203 * Check for the ATA Information VPD page (0x89). If this is an 5204 * ATA device behind a SCSI to ATA translation layer, this VPD page 5205 * should be present. 5206 * 5207 * If that VPD page isn't present, or we get an error back from the 5208 * INQUIRY command, we'll just treat it as a normal SCSI device. 5209 */ 5210 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count, 5211 timeout, verbosemode); 5212 if (retval == 1) 5213 *devtype = CC_DT_ATA_BEHIND_SCSI; 5214 else 5215 *devtype = CC_DT_SCSI; 5216 5217 retval = 0; 5218 5219bailout: 5220 return (retval); 5221} 5222 5223int 5224build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags, 5225 uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features, 5226 uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary, 5227 uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage, 5228 size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout, 5229 int is48bit, camcontrol_devtype devtype) 5230{ 5231 int retval = 0; 5232 5233 if (devtype == CC_DT_ATA) { 5234 cam_fill_ataio(&ccb->ataio, 5235 /*retries*/ retry_count, 5236 /*cbfcnp*/ NULL, 5237 /*flags*/ flags, 5238 /*tag_action*/ tag_action, 5239 /*data_ptr*/ data_ptr, 5240 /*dxfer_len*/ dxfer_len, 5241 /*timeout*/ timeout); 5242 if (is48bit || lba > ATA_MAX_28BIT_LBA) 5243 ata_48bit_cmd(&ccb->ataio, command, features, lba, 5244 sector_count); 5245 else 5246 ata_28bit_cmd(&ccb->ataio, command, features, lba, 5247 sector_count); 5248 5249 if (auxiliary != 0) { 5250 ccb->ataio.ata_flags |= ATA_FLAG_AUX; 5251 ccb->ataio.aux = auxiliary; 5252 } 5253 5254 if (ata_flags & AP_FLAG_CHK_COND) 5255 ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; 5256 5257 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA) 5258 ccb->ataio.cmd.flags |= CAM_ATAIO_DMA; 5259 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA) 5260 ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA; 5261 } else { 5262 if (is48bit || lba > ATA_MAX_28BIT_LBA) 5263 protocol |= AP_EXTEND; 5264 5265 retval = scsi_ata_pass(&ccb->csio, 5266 /*retries*/ retry_count, 5267 /*cbfcnp*/ NULL, 5268 /*flags*/ flags, 5269 /*tag_action*/ tag_action, 5270 /*protocol*/ protocol, 5271 /*ata_flags*/ ata_flags, 5272 /*features*/ features, 5273 /*sector_count*/ sector_count, 5274 /*lba*/ lba, 5275 /*command*/ command, 5276 /*device*/ 0, 5277 /*icc*/ 0, 5278 /*auxiliary*/ auxiliary, 5279 /*control*/ 0, 5280 /*data_ptr*/ data_ptr, 5281 /*dxfer_len*/ dxfer_len, 5282 /*cdb_storage*/ cdb_storage, 5283 /*cdb_storage_len*/ cdb_storage_len, 5284 /*minimum_cmd_size*/ 0, 5285 /*sense_len*/ sense_len, 5286 /*timeout*/ timeout); 5287 } 5288 5289 return (retval); 5290} 5291 5292int 5293get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error, 5294 uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status) 5295{ 5296 int retval = 0; 5297 5298 switch (ccb->ccb_h.func_code) { 5299 case XPT_SCSI_IO: { 5300 uint8_t opcode; 5301 int error_code = 0, sense_key = 0, asc = 0, ascq = 0; 5302 5303 /* 5304 * In this case, we have SCSI ATA PASS-THROUGH command, 12 5305 * or 16 byte, and need to see what 5306 */ 5307 if (ccb->ccb_h.flags & CAM_CDB_POINTER) 5308 opcode = ccb->csio.cdb_io.cdb_ptr[0]; 5309 else 5310 opcode = ccb->csio.cdb_io.cdb_bytes[0]; 5311 if ((opcode != ATA_PASS_12) 5312 && (opcode != ATA_PASS_16)) { 5313 retval = 1; 5314 warnx("%s: unsupported opcode %02x", __func__, opcode); 5315 goto bailout; 5316 } 5317 5318 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key, 5319 &asc, &ascq); 5320 /* Note: the _ccb() variant returns 0 for an error */ 5321 if (retval == 0) { 5322 retval = 1; 5323 goto bailout; 5324 } else 5325 retval = 0; 5326 5327 switch (error_code) { 5328 case SSD_DESC_CURRENT_ERROR: 5329 case SSD_DESC_DEFERRED_ERROR: { 5330 struct scsi_sense_data_desc *sense; 5331 struct scsi_sense_ata_ret_desc *desc; 5332 uint8_t *desc_ptr; 5333 5334 sense = (struct scsi_sense_data_desc *) 5335 &ccb->csio.sense_data; 5336 5337 desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len - 5338 ccb->csio.sense_resid, SSD_DESC_ATA); 5339 if (desc_ptr == NULL) { 5340 cam_error_print(dev, ccb, CAM_ESF_ALL, 5341 CAM_EPF_ALL, stderr); 5342 retval = 1; 5343 goto bailout; 5344 } 5345 desc = (struct scsi_sense_ata_ret_desc *)desc_ptr; 5346 5347 *error = desc->error; 5348 *count = (desc->count_15_8 << 8) | 5349 desc->count_7_0; 5350 *lba = ((uint64_t)desc->lba_47_40 << 40) | 5351 ((uint64_t)desc->lba_39_32 << 32) | 5352 ((uint64_t)desc->lba_31_24 << 24) | 5353 (desc->lba_23_16 << 16) | 5354 (desc->lba_15_8 << 8) | 5355 desc->lba_7_0; 5356 *device = desc->device; 5357 *status = desc->status; 5358 5359 /* 5360 * If the extend bit isn't set, the result is for a 5361 * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte 5362 * command without the extend bit set. This means 5363 * that the device is supposed to return 28-bit 5364 * status. The count field is only 8 bits, and the 5365 * LBA field is only 8 bits. 5366 */ 5367 if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){ 5368 *count &= 0xff; 5369 *lba &= 0x0fffffff; 5370 } 5371 break; 5372 } 5373 case SSD_CURRENT_ERROR: 5374 case SSD_DEFERRED_ERROR: { 5375#if 0 5376 struct scsi_sense_data_fixed *sense; 5377#endif 5378 /* 5379 * XXX KDM need to support fixed sense data. 5380 */ 5381 warnx("%s: Fixed sense data not supported yet", 5382 __func__); 5383 retval = 1; 5384 goto bailout; 5385 break; /*NOTREACHED*/ 5386 } 5387 default: 5388 retval = 1; 5389 goto bailout; 5390 break; 5391 } 5392 5393 break; 5394 } 5395 case XPT_ATA_IO: { 5396 struct ata_res *res; 5397 5398 /* 5399 * In this case, we have an ATA command, and we need to 5400 * fill in the requested values from the result register 5401 * set. 5402 */ 5403 res = &ccb->ataio.res; 5404 *error = res->error; 5405 *status = res->status; 5406 *device = res->device; 5407 *count = res->sector_count; 5408 *lba = (res->lba_high << 16) | 5409 (res->lba_mid << 8) | 5410 (res->lba_low); 5411 if (res->flags & CAM_ATAIO_48BIT) { 5412 *count |= (res->sector_count_exp << 8); 5413 *lba |= ((uint64_t)res->lba_low_exp << 24) | 5414 ((uint64_t)res->lba_mid_exp << 32) | 5415 ((uint64_t)res->lba_high_exp << 40); 5416 } else { 5417 *lba |= (res->device & 0xf) << 24; 5418 } 5419 break; 5420 } 5421 default: 5422 retval = 1; 5423 break; 5424 } 5425bailout: 5426 return (retval); 5427} 5428 5429static void 5430cpi_print(struct ccb_pathinq *cpi) 5431{ 5432 char adapter_str[1024]; 5433 uint64_t i; 5434 5435 snprintf(adapter_str, sizeof(adapter_str), 5436 "%s%d:", cpi->dev_name, cpi->unit_number); 5437 5438 fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str, 5439 cpi->version_num); 5440 5441 for (i = 1; i < UINT8_MAX; i = i << 1) { 5442 const char *str; 5443 5444 if ((i & cpi->hba_inquiry) == 0) 5445 continue; 5446 5447 fprintf(stdout, "%s supports ", adapter_str); 5448 5449 switch(i) { 5450 case PI_MDP_ABLE: 5451 str = "MDP message"; 5452 break; 5453 case PI_WIDE_32: 5454 str = "32 bit wide SCSI"; 5455 break; 5456 case PI_WIDE_16: 5457 str = "16 bit wide SCSI"; 5458 break; 5459 case PI_SDTR_ABLE: 5460 str = "SDTR message"; 5461 break; 5462 case PI_LINKED_CDB: 5463 str = "linked CDBs"; 5464 break; 5465 case PI_TAG_ABLE: 5466 str = "tag queue messages"; 5467 break; 5468 case PI_SOFT_RST: 5469 str = "soft reset alternative"; 5470 break; 5471 case PI_SATAPM: 5472 str = "SATA Port Multiplier"; 5473 break; 5474 default: 5475 str = "unknown PI bit set"; 5476 break; 5477 } 5478 fprintf(stdout, "%s\n", str); 5479 } 5480 5481 for (i = 1; i < UINT32_MAX; i = i << 1) { 5482 const char *str; 5483 5484 if ((i & cpi->hba_misc) == 0) 5485 continue; 5486 5487 fprintf(stdout, "%s ", adapter_str); 5488 5489 switch(i) { 5490 case PIM_ATA_EXT: 5491 str = "can understand ata_ext requests"; 5492 break; 5493 case PIM_EXTLUNS: 5494 str = "64bit extended LUNs supported"; 5495 break; 5496 case PIM_SCANHILO: 5497 str = "bus scans from high ID to low ID"; 5498 break; 5499 case PIM_NOREMOVE: 5500 str = "removable devices not included in scan"; 5501 break; 5502 case PIM_NOINITIATOR: 5503 str = "initiator role not supported"; 5504 break; 5505 case PIM_NOBUSRESET: 5506 str = "user has disabled initial BUS RESET or" 5507 " controller is in target/mixed mode"; 5508 break; 5509 case PIM_NO_6_BYTE: 5510 str = "do not send 6-byte commands"; 5511 break; 5512 case PIM_SEQSCAN: 5513 str = "scan bus sequentially"; 5514 break; 5515 case PIM_UNMAPPED: 5516 str = "unmapped I/O supported"; 5517 break; 5518 case PIM_NOSCAN: 5519 str = "does its own scanning"; 5520 break; 5521 default: 5522 str = "unknown PIM bit set"; 5523 break; 5524 } 5525 fprintf(stdout, "%s\n", str); 5526 } 5527 5528 for (i = 1; i < UINT16_MAX; i = i << 1) { 5529 const char *str; 5530 5531 if ((i & cpi->target_sprt) == 0) 5532 continue; 5533 5534 fprintf(stdout, "%s supports ", adapter_str); 5535 switch(i) { 5536 case PIT_PROCESSOR: 5537 str = "target mode processor mode"; 5538 break; 5539 case PIT_PHASE: 5540 str = "target mode phase cog. mode"; 5541 break; 5542 case PIT_DISCONNECT: 5543 str = "disconnects in target mode"; 5544 break; 5545 case PIT_TERM_IO: 5546 str = "terminate I/O message in target mode"; 5547 break; 5548 case PIT_GRP_6: 5549 str = "group 6 commands in target mode"; 5550 break; 5551 case PIT_GRP_7: 5552 str = "group 7 commands in target mode"; 5553 break; 5554 default: 5555 str = "unknown PIT bit set"; 5556 break; 5557 } 5558 5559 fprintf(stdout, "%s\n", str); 5560 } 5561 fprintf(stdout, "%s HBA engine count: %d\n", adapter_str, 5562 cpi->hba_eng_cnt); 5563 fprintf(stdout, "%s maximum target: %d\n", adapter_str, 5564 cpi->max_target); 5565 fprintf(stdout, "%s maximum LUN: %d\n", adapter_str, 5566 cpi->max_lun); 5567 fprintf(stdout, "%s highest path ID in subsystem: %d\n", 5568 adapter_str, cpi->hpath_id); 5569 fprintf(stdout, "%s initiator ID: %d\n", adapter_str, 5570 cpi->initiator_id); 5571 fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid); 5572 fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid); 5573 fprintf(stdout, "%s HBA vendor ID: 0x%04x\n", 5574 adapter_str, cpi->hba_vendor); 5575 fprintf(stdout, "%s HBA device ID: 0x%04x\n", 5576 adapter_str, cpi->hba_device); 5577 fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n", 5578 adapter_str, cpi->hba_subvendor); 5579 fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n", 5580 adapter_str, cpi->hba_subdevice); 5581 fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id); 5582 fprintf(stdout, "%s base transfer speed: ", adapter_str); 5583 if (cpi->base_transfer_speed > 1000) 5584 fprintf(stdout, "%d.%03dMB/sec\n", 5585 cpi->base_transfer_speed / 1000, 5586 cpi->base_transfer_speed % 1000); 5587 else 5588 fprintf(stdout, "%dKB/sec\n", 5589 (cpi->base_transfer_speed % 1000) * 1000); 5590 fprintf(stdout, "%s maximum transfer size: %u bytes\n", 5591 adapter_str, cpi->maxio); 5592} 5593 5594static int 5595get_print_cts(struct cam_device *device, int user_settings, int quiet, 5596 struct ccb_trans_settings *cts) 5597{ 5598 int retval; 5599 union ccb *ccb; 5600 5601 retval = 0; 5602 ccb = cam_getccb(device); 5603 5604 if (ccb == NULL) { 5605 warnx("get_print_cts: error allocating ccb"); 5606 return (1); 5607 } 5608 5609 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); 5610 5611 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; 5612 5613 if (user_settings == 0) 5614 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS; 5615 else 5616 ccb->cts.type = CTS_TYPE_USER_SETTINGS; 5617 5618 if (cam_send_ccb(device, ccb) < 0) { 5619 perror("error sending XPT_GET_TRAN_SETTINGS CCB"); 5620 if (arglist & CAM_ARG_VERBOSE) 5621 cam_error_print(device, ccb, CAM_ESF_ALL, 5622 CAM_EPF_ALL, stderr); 5623 retval = 1; 5624 goto get_print_cts_bailout; 5625 } 5626 5627 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5628 warnx("XPT_GET_TRANS_SETTINGS CCB failed"); 5629 if (arglist & CAM_ARG_VERBOSE) 5630 cam_error_print(device, ccb, CAM_ESF_ALL, 5631 CAM_EPF_ALL, stderr); 5632 retval = 1; 5633 goto get_print_cts_bailout; 5634 } 5635 5636 if (quiet == 0) 5637 cts_print(device, &ccb->cts); 5638 5639 if (cts != NULL) 5640 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings)); 5641 5642get_print_cts_bailout: 5643 5644 cam_freeccb(ccb); 5645 5646 return (retval); 5647} 5648 5649static int 5650ratecontrol(struct cam_device *device, int task_attr, int retry_count, 5651 int timeout, int argc, char **argv, char *combinedopt) 5652{ 5653 int c; 5654 union ccb *ccb; 5655 int user_settings = 0; 5656 int retval = 0; 5657 int disc_enable = -1, tag_enable = -1; 5658 int mode = -1; 5659 int offset = -1; 5660 double syncrate = -1; 5661 int bus_width = -1; 5662 int quiet = 0; 5663 int change_settings = 0, send_tur = 0; 5664 struct ccb_pathinq cpi; 5665 5666 ccb = cam_getccb(device); 5667 if (ccb == NULL) { 5668 warnx("ratecontrol: error allocating ccb"); 5669 return (1); 5670 } 5671 while ((c = getopt(argc, argv, combinedopt)) != -1) { 5672 switch(c){ 5673 case 'a': 5674 send_tur = 1; 5675 break; 5676 case 'c': 5677 user_settings = 0; 5678 break; 5679 case 'D': 5680 if (strncasecmp(optarg, "enable", 6) == 0) 5681 disc_enable = 1; 5682 else if (strncasecmp(optarg, "disable", 7) == 0) 5683 disc_enable = 0; 5684 else { 5685 warnx("-D argument \"%s\" is unknown", optarg); 5686 retval = 1; 5687 goto ratecontrol_bailout; 5688 } 5689 change_settings = 1; 5690 break; 5691 case 'M': 5692 mode = ata_string2mode(optarg); 5693 if (mode < 0) { 5694 warnx("unknown mode '%s'", optarg); 5695 retval = 1; 5696 goto ratecontrol_bailout; 5697 } 5698 change_settings = 1; 5699 break; 5700 case 'O': 5701 offset = strtol(optarg, NULL, 0); 5702 if (offset < 0) { 5703 warnx("offset value %d is < 0", offset); 5704 retval = 1; 5705 goto ratecontrol_bailout; 5706 } 5707 change_settings = 1; 5708 break; 5709 case 'q': 5710 quiet++; 5711 break; 5712 case 'R': 5713 syncrate = atof(optarg); 5714 if (syncrate < 0) { 5715 warnx("sync rate %f is < 0", syncrate); 5716 retval = 1; 5717 goto ratecontrol_bailout; 5718 } 5719 change_settings = 1; 5720 break; 5721 case 'T': 5722 if (strncasecmp(optarg, "enable", 6) == 0) 5723 tag_enable = 1; 5724 else if (strncasecmp(optarg, "disable", 7) == 0) 5725 tag_enable = 0; 5726 else { 5727 warnx("-T argument \"%s\" is unknown", optarg); 5728 retval = 1; 5729 goto ratecontrol_bailout; 5730 } 5731 change_settings = 1; 5732 break; 5733 case 'U': 5734 user_settings = 1; 5735 break; 5736 case 'W': 5737 bus_width = strtol(optarg, NULL, 0); 5738 if (bus_width < 0) { 5739 warnx("bus width %d is < 0", bus_width); 5740 retval = 1; 5741 goto ratecontrol_bailout; 5742 } 5743 change_settings = 1; 5744 break; 5745 default: 5746 break; 5747 } 5748 } 5749 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi); 5750 /* 5751 * Grab path inquiry information, so we can determine whether 5752 * or not the initiator is capable of the things that the user 5753 * requests. 5754 */ 5755 ccb->ccb_h.func_code = XPT_PATH_INQ; 5756 if (cam_send_ccb(device, ccb) < 0) { 5757 perror("error sending XPT_PATH_INQ CCB"); 5758 if (arglist & CAM_ARG_VERBOSE) { 5759 cam_error_print(device, ccb, CAM_ESF_ALL, 5760 CAM_EPF_ALL, stderr); 5761 } 5762 retval = 1; 5763 goto ratecontrol_bailout; 5764 } 5765 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5766 warnx("XPT_PATH_INQ CCB failed"); 5767 if (arglist & CAM_ARG_VERBOSE) { 5768 cam_error_print(device, ccb, CAM_ESF_ALL, 5769 CAM_EPF_ALL, stderr); 5770 } 5771 retval = 1; 5772 goto ratecontrol_bailout; 5773 } 5774 bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq)); 5775 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); 5776 if (quiet == 0) { 5777 fprintf(stdout, "%s parameters:\n", 5778 user_settings ? "User" : "Current"); 5779 } 5780 retval = get_print_cts(device, user_settings, quiet, &ccb->cts); 5781 if (retval != 0) 5782 goto ratecontrol_bailout; 5783 5784 if (arglist & CAM_ARG_VERBOSE) 5785 cpi_print(&cpi); 5786 5787 if (change_settings) { 5788 int didsettings = 0; 5789 struct ccb_trans_settings_spi *spi = NULL; 5790 struct ccb_trans_settings_pata *pata = NULL; 5791 struct ccb_trans_settings_sata *sata = NULL; 5792 struct ccb_trans_settings_ata *ata = NULL; 5793 struct ccb_trans_settings_scsi *scsi = NULL; 5794 5795 if (ccb->cts.transport == XPORT_SPI) 5796 spi = &ccb->cts.xport_specific.spi; 5797 if (ccb->cts.transport == XPORT_ATA) 5798 pata = &ccb->cts.xport_specific.ata; 5799 if (ccb->cts.transport == XPORT_SATA) 5800 sata = &ccb->cts.xport_specific.sata; 5801 if (ccb->cts.protocol == PROTO_ATA) 5802 ata = &ccb->cts.proto_specific.ata; 5803 if (ccb->cts.protocol == PROTO_SCSI) 5804 scsi = &ccb->cts.proto_specific.scsi; 5805 ccb->cts.xport_specific.valid = 0; 5806 ccb->cts.proto_specific.valid = 0; 5807 if (spi && disc_enable != -1) { 5808 spi->valid |= CTS_SPI_VALID_DISC; 5809 if (disc_enable == 0) 5810 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; 5811 else 5812 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 5813 didsettings++; 5814 } 5815 if (tag_enable != -1) { 5816 if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) { 5817 warnx("HBA does not support tagged queueing, " 5818 "so you cannot modify tag settings"); 5819 retval = 1; 5820 goto ratecontrol_bailout; 5821 } 5822 if (ata) { 5823 ata->valid |= CTS_SCSI_VALID_TQ; 5824 if (tag_enable == 0) 5825 ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB; 5826 else 5827 ata->flags |= CTS_ATA_FLAGS_TAG_ENB; 5828 didsettings++; 5829 } else if (scsi) { 5830 scsi->valid |= CTS_SCSI_VALID_TQ; 5831 if (tag_enable == 0) 5832 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; 5833 else 5834 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 5835 didsettings++; 5836 } 5837 } 5838 if (spi && offset != -1) { 5839 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5840 warnx("HBA is not capable of changing offset"); 5841 retval = 1; 5842 goto ratecontrol_bailout; 5843 } 5844 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 5845 spi->sync_offset = offset; 5846 didsettings++; 5847 } 5848 if (spi && syncrate != -1) { 5849 int prelim_sync_period; 5850 5851 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5852 warnx("HBA is not capable of changing " 5853 "transfer rates"); 5854 retval = 1; 5855 goto ratecontrol_bailout; 5856 } 5857 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 5858 /* 5859 * The sync rate the user gives us is in MHz. 5860 * We need to translate it into KHz for this 5861 * calculation. 5862 */ 5863 syncrate *= 1000; 5864 /* 5865 * Next, we calculate a "preliminary" sync period 5866 * in tenths of a nanosecond. 5867 */ 5868 if (syncrate == 0) 5869 prelim_sync_period = 0; 5870 else 5871 prelim_sync_period = 10000000 / syncrate; 5872 spi->sync_period = 5873 scsi_calc_syncparam(prelim_sync_period); 5874 didsettings++; 5875 } 5876 if (sata && syncrate != -1) { 5877 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5878 warnx("HBA is not capable of changing " 5879 "transfer rates"); 5880 retval = 1; 5881 goto ratecontrol_bailout; 5882 } 5883 if (!user_settings) { 5884 warnx("You can modify only user rate " 5885 "settings for SATA"); 5886 retval = 1; 5887 goto ratecontrol_bailout; 5888 } 5889 sata->revision = ata_speed2revision(syncrate * 100); 5890 if (sata->revision < 0) { 5891 warnx("Invalid rate %f", syncrate); 5892 retval = 1; 5893 goto ratecontrol_bailout; 5894 } 5895 sata->valid |= CTS_SATA_VALID_REVISION; 5896 didsettings++; 5897 } 5898 if ((pata || sata) && mode != -1) { 5899 if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { 5900 warnx("HBA is not capable of changing " 5901 "transfer rates"); 5902 retval = 1; 5903 goto ratecontrol_bailout; 5904 } 5905 if (!user_settings) { 5906 warnx("You can modify only user mode " 5907 "settings for ATA/SATA"); 5908 retval = 1; 5909 goto ratecontrol_bailout; 5910 } 5911 if (pata) { 5912 pata->mode = mode; 5913 pata->valid |= CTS_ATA_VALID_MODE; 5914 } else { 5915 sata->mode = mode; 5916 sata->valid |= CTS_SATA_VALID_MODE; 5917 } 5918 didsettings++; 5919 } 5920 /* 5921 * The bus_width argument goes like this: 5922 * 0 == 8 bit 5923 * 1 == 16 bit 5924 * 2 == 32 bit 5925 * Therefore, if you shift the number of bits given on the 5926 * command line right by 4, you should get the correct 5927 * number. 5928 */ 5929 if (spi && bus_width != -1) { 5930 /* 5931 * We might as well validate things here with a 5932 * decipherable error message, rather than what 5933 * will probably be an indecipherable error message 5934 * by the time it gets back to us. 5935 */ 5936 if ((bus_width == 16) 5937 && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) { 5938 warnx("HBA does not support 16 bit bus width"); 5939 retval = 1; 5940 goto ratecontrol_bailout; 5941 } else if ((bus_width == 32) 5942 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) { 5943 warnx("HBA does not support 32 bit bus width"); 5944 retval = 1; 5945 goto ratecontrol_bailout; 5946 } else if ((bus_width != 8) 5947 && (bus_width != 16) 5948 && (bus_width != 32)) { 5949 warnx("Invalid bus width %d", bus_width); 5950 retval = 1; 5951 goto ratecontrol_bailout; 5952 } 5953 spi->valid |= CTS_SPI_VALID_BUS_WIDTH; 5954 spi->bus_width = bus_width >> 4; 5955 didsettings++; 5956 } 5957 if (didsettings == 0) { 5958 goto ratecontrol_bailout; 5959 } 5960 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; 5961 if (cam_send_ccb(device, ccb) < 0) { 5962 perror("error sending XPT_SET_TRAN_SETTINGS CCB"); 5963 if (arglist & CAM_ARG_VERBOSE) { 5964 cam_error_print(device, ccb, CAM_ESF_ALL, 5965 CAM_EPF_ALL, stderr); 5966 } 5967 retval = 1; 5968 goto ratecontrol_bailout; 5969 } 5970 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5971 warnx("XPT_SET_TRANS_SETTINGS CCB failed"); 5972 if (arglist & CAM_ARG_VERBOSE) { 5973 cam_error_print(device, ccb, CAM_ESF_ALL, 5974 CAM_EPF_ALL, stderr); 5975 } 5976 retval = 1; 5977 goto ratecontrol_bailout; 5978 } 5979 } 5980 if (send_tur) { 5981 retval = testunitready(device, task_attr, retry_count, timeout, 5982 (arglist & CAM_ARG_VERBOSE) ? 0 : 1); 5983 /* 5984 * If the TUR didn't succeed, just bail. 5985 */ 5986 if (retval != 0) { 5987 if (quiet == 0) 5988 fprintf(stderr, "Test Unit Ready failed\n"); 5989 goto ratecontrol_bailout; 5990 } 5991 } 5992 if ((change_settings || send_tur) && !quiet && 5993 (ccb->cts.transport == XPORT_ATA || 5994 ccb->cts.transport == XPORT_SATA || send_tur)) { 5995 fprintf(stdout, "New parameters:\n"); 5996 retval = get_print_cts(device, user_settings, 0, NULL); 5997 } 5998 5999ratecontrol_bailout: 6000 cam_freeccb(ccb); 6001 return (retval); 6002} 6003 6004static int 6005scsiformat(struct cam_device *device, int argc, char **argv, 6006 char *combinedopt, int task_attr, int retry_count, int timeout) 6007{ 6008 union ccb *ccb; 6009 int c; 6010 int ycount = 0, quiet = 0; 6011 int error = 0, retval = 0; 6012 int use_timeout = 10800 * 1000; 6013 int immediate = 1; 6014 struct format_defect_list_header fh; 6015 u_int8_t *data_ptr = NULL; 6016 u_int32_t dxfer_len = 0; 6017 u_int8_t byte2 = 0; 6018 int num_warnings = 0; 6019 int reportonly = 0; 6020 6021 ccb = cam_getccb(device); 6022 6023 if (ccb == NULL) { 6024 warnx("scsiformat: error allocating ccb"); 6025 return (1); 6026 } 6027 6028 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6029 6030 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6031 switch(c) { 6032 case 'q': 6033 quiet++; 6034 break; 6035 case 'r': 6036 reportonly = 1; 6037 break; 6038 case 'w': 6039 immediate = 0; 6040 break; 6041 case 'y': 6042 ycount++; 6043 break; 6044 } 6045 } 6046 6047 if (reportonly) 6048 goto doreport; 6049 6050 if (quiet == 0) { 6051 fprintf(stdout, "You are about to REMOVE ALL DATA from the " 6052 "following device:\n"); 6053 6054 error = scsidoinquiry(device, argc, argv, combinedopt, 6055 task_attr, retry_count, timeout); 6056 6057 if (error != 0) { 6058 warnx("scsiformat: error sending inquiry"); 6059 goto scsiformat_bailout; 6060 } 6061 } 6062 6063 if (ycount == 0) { 6064 if (!get_confirmation()) { 6065 error = 1; 6066 goto scsiformat_bailout; 6067 } 6068 } 6069 6070 if (timeout != 0) 6071 use_timeout = timeout; 6072 6073 if (quiet == 0) { 6074 fprintf(stdout, "Current format timeout is %d seconds\n", 6075 use_timeout / 1000); 6076 } 6077 6078 /* 6079 * If the user hasn't disabled questions and didn't specify a 6080 * timeout on the command line, ask them if they want the current 6081 * timeout. 6082 */ 6083 if ((ycount == 0) 6084 && (timeout == 0)) { 6085 char str[1024]; 6086 int new_timeout = 0; 6087 6088 fprintf(stdout, "Enter new timeout in seconds or press\n" 6089 "return to keep the current timeout [%d] ", 6090 use_timeout / 1000); 6091 6092 if (fgets(str, sizeof(str), stdin) != NULL) { 6093 if (str[0] != '\0') 6094 new_timeout = atoi(str); 6095 } 6096 6097 if (new_timeout != 0) { 6098 use_timeout = new_timeout * 1000; 6099 fprintf(stdout, "Using new timeout value %d\n", 6100 use_timeout / 1000); 6101 } 6102 } 6103 6104 /* 6105 * Keep this outside the if block below to silence any unused 6106 * variable warnings. 6107 */ 6108 bzero(&fh, sizeof(fh)); 6109 6110 /* 6111 * If we're in immediate mode, we've got to include the format 6112 * header 6113 */ 6114 if (immediate != 0) { 6115 fh.byte2 = FU_DLH_IMMED; 6116 data_ptr = (u_int8_t *)&fh; 6117 dxfer_len = sizeof(fh); 6118 byte2 = FU_FMT_DATA; 6119 } else if (quiet == 0) { 6120 fprintf(stdout, "Formatting..."); 6121 fflush(stdout); 6122 } 6123 6124 scsi_format_unit(&ccb->csio, 6125 /* retries */ retry_count, 6126 /* cbfcnp */ NULL, 6127 /* tag_action */ task_attr, 6128 /* byte2 */ byte2, 6129 /* ileave */ 0, 6130 /* data_ptr */ data_ptr, 6131 /* dxfer_len */ dxfer_len, 6132 /* sense_len */ SSD_FULL_SIZE, 6133 /* timeout */ use_timeout); 6134 6135 /* Disable freezing the device queue */ 6136 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6137 6138 if (arglist & CAM_ARG_ERR_RECOVER) 6139 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6140 6141 if (((retval = cam_send_ccb(device, ccb)) < 0) 6142 || ((immediate == 0) 6143 && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) { 6144 const char errstr[] = "error sending format command"; 6145 6146 if (retval < 0) 6147 warn(errstr); 6148 else 6149 warnx(errstr); 6150 6151 if (arglist & CAM_ARG_VERBOSE) { 6152 cam_error_print(device, ccb, CAM_ESF_ALL, 6153 CAM_EPF_ALL, stderr); 6154 } 6155 error = 1; 6156 goto scsiformat_bailout; 6157 } 6158 6159 /* 6160 * If we ran in non-immediate mode, we already checked for errors 6161 * above and printed out any necessary information. If we're in 6162 * immediate mode, we need to loop through and get status 6163 * information periodically. 6164 */ 6165 if (immediate == 0) { 6166 if (quiet == 0) { 6167 fprintf(stdout, "Format Complete\n"); 6168 } 6169 goto scsiformat_bailout; 6170 } 6171 6172doreport: 6173 do { 6174 cam_status status; 6175 6176 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6177 6178 /* 6179 * There's really no need to do error recovery or 6180 * retries here, since we're just going to sit in a 6181 * loop and wait for the device to finish formatting. 6182 */ 6183 scsi_test_unit_ready(&ccb->csio, 6184 /* retries */ 0, 6185 /* cbfcnp */ NULL, 6186 /* tag_action */ task_attr, 6187 /* sense_len */ SSD_FULL_SIZE, 6188 /* timeout */ 5000); 6189 6190 /* Disable freezing the device queue */ 6191 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6192 6193 retval = cam_send_ccb(device, ccb); 6194 6195 /* 6196 * If we get an error from the ioctl, bail out. SCSI 6197 * errors are expected. 6198 */ 6199 if (retval < 0) { 6200 warn("error sending CAMIOCOMMAND ioctl"); 6201 if (arglist & CAM_ARG_VERBOSE) { 6202 cam_error_print(device, ccb, CAM_ESF_ALL, 6203 CAM_EPF_ALL, stderr); 6204 } 6205 error = 1; 6206 goto scsiformat_bailout; 6207 } 6208 6209 status = ccb->ccb_h.status & CAM_STATUS_MASK; 6210 6211 if ((status != CAM_REQ_CMP) 6212 && (status == CAM_SCSI_STATUS_ERROR) 6213 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 6214 struct scsi_sense_data *sense; 6215 int error_code, sense_key, asc, ascq; 6216 6217 sense = &ccb->csio.sense_data; 6218 scsi_extract_sense_len(sense, ccb->csio.sense_len - 6219 ccb->csio.sense_resid, &error_code, &sense_key, 6220 &asc, &ascq, /*show_errors*/ 1); 6221 6222 /* 6223 * According to the SCSI-2 and SCSI-3 specs, a 6224 * drive that is in the middle of a format should 6225 * return NOT READY with an ASC of "logical unit 6226 * not ready, format in progress". The sense key 6227 * specific bytes will then be a progress indicator. 6228 */ 6229 if ((sense_key == SSD_KEY_NOT_READY) 6230 && (asc == 0x04) && (ascq == 0x04)) { 6231 uint8_t sks[3]; 6232 6233 if ((scsi_get_sks(sense, ccb->csio.sense_len - 6234 ccb->csio.sense_resid, sks) == 0) 6235 && (quiet == 0)) { 6236 uint32_t val; 6237 u_int64_t percentage; 6238 6239 val = scsi_2btoul(&sks[1]); 6240 percentage = 10000ull * val; 6241 6242 fprintf(stdout, 6243 "\rFormatting: %ju.%02u %% " 6244 "(%u/%d) done", 6245 (uintmax_t)(percentage / 6246 (0x10000 * 100)), 6247 (unsigned)((percentage / 6248 0x10000) % 100), 6249 val, 0x10000); 6250 fflush(stdout); 6251 } else if ((quiet == 0) 6252 && (++num_warnings <= 1)) { 6253 warnx("Unexpected SCSI Sense Key " 6254 "Specific value returned " 6255 "during format:"); 6256 scsi_sense_print(device, &ccb->csio, 6257 stderr); 6258 warnx("Unable to print status " 6259 "information, but format will " 6260 "proceed."); 6261 warnx("will exit when format is " 6262 "complete"); 6263 } 6264 sleep(1); 6265 } else { 6266 warnx("Unexpected SCSI error during format"); 6267 cam_error_print(device, ccb, CAM_ESF_ALL, 6268 CAM_EPF_ALL, stderr); 6269 error = 1; 6270 goto scsiformat_bailout; 6271 } 6272 6273 } else if (status != CAM_REQ_CMP) { 6274 warnx("Unexpected CAM status %#x", status); 6275 if (arglist & CAM_ARG_VERBOSE) 6276 cam_error_print(device, ccb, CAM_ESF_ALL, 6277 CAM_EPF_ALL, stderr); 6278 error = 1; 6279 goto scsiformat_bailout; 6280 } 6281 6282 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); 6283 6284 if (quiet == 0) 6285 fprintf(stdout, "\nFormat Complete\n"); 6286 6287scsiformat_bailout: 6288 6289 cam_freeccb(ccb); 6290 6291 return (error); 6292} 6293 6294static int 6295scsisanitize(struct cam_device *device, int argc, char **argv, 6296 char *combinedopt, int task_attr, int retry_count, int timeout) 6297{ 6298 union ccb *ccb; 6299 u_int8_t action = 0; 6300 int c; 6301 int ycount = 0, quiet = 0; 6302 int error = 0, retval = 0; 6303 int use_timeout = 10800 * 1000; 6304 int immediate = 1; 6305 int invert = 0; 6306 int passes = 0; 6307 int ause = 0; 6308 int fd = -1; 6309 const char *pattern = NULL; 6310 u_int8_t *data_ptr = NULL; 6311 u_int32_t dxfer_len = 0; 6312 u_int8_t byte2 = 0; 6313 int num_warnings = 0; 6314 int reportonly = 0; 6315 6316 ccb = cam_getccb(device); 6317 6318 if (ccb == NULL) { 6319 warnx("scsisanitize: error allocating ccb"); 6320 return (1); 6321 } 6322 6323 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6324 6325 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6326 switch(c) { 6327 case 'a': 6328 if (strcasecmp(optarg, "overwrite") == 0) 6329 action = SSZ_SERVICE_ACTION_OVERWRITE; 6330 else if (strcasecmp(optarg, "block") == 0) 6331 action = SSZ_SERVICE_ACTION_BLOCK_ERASE; 6332 else if (strcasecmp(optarg, "crypto") == 0) 6333 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE; 6334 else if (strcasecmp(optarg, "exitfailure") == 0) 6335 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE; 6336 else { 6337 warnx("invalid service operation \"%s\"", 6338 optarg); 6339 error = 1; 6340 goto scsisanitize_bailout; 6341 } 6342 break; 6343 case 'c': 6344 passes = strtol(optarg, NULL, 0); 6345 if (passes < 1 || passes > 31) { 6346 warnx("invalid passes value %d", passes); 6347 error = 1; 6348 goto scsisanitize_bailout; 6349 } 6350 break; 6351 case 'I': 6352 invert = 1; 6353 break; 6354 case 'P': 6355 pattern = optarg; 6356 break; 6357 case 'q': 6358 quiet++; 6359 break; 6360 case 'U': 6361 ause = 1; 6362 break; 6363 case 'r': 6364 reportonly = 1; 6365 break; 6366 case 'w': 6367 immediate = 0; 6368 break; 6369 case 'y': 6370 ycount++; 6371 break; 6372 } 6373 } 6374 6375 if (reportonly) 6376 goto doreport; 6377 6378 if (action == 0) { 6379 warnx("an action is required"); 6380 error = 1; 6381 goto scsisanitize_bailout; 6382 } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) { 6383 struct scsi_sanitize_parameter_list *pl; 6384 struct stat sb; 6385 ssize_t sz, amt; 6386 6387 if (pattern == NULL) { 6388 warnx("overwrite action requires -P argument"); 6389 error = 1; 6390 goto scsisanitize_bailout; 6391 } 6392 fd = open(pattern, O_RDONLY); 6393 if (fd < 0) { 6394 warn("cannot open pattern file %s", pattern); 6395 error = 1; 6396 goto scsisanitize_bailout; 6397 } 6398 if (fstat(fd, &sb) < 0) { 6399 warn("cannot stat pattern file %s", pattern); 6400 error = 1; 6401 goto scsisanitize_bailout; 6402 } 6403 sz = sb.st_size; 6404 if (sz > SSZPL_MAX_PATTERN_LENGTH) { 6405 warnx("pattern file size exceeds maximum value %d", 6406 SSZPL_MAX_PATTERN_LENGTH); 6407 error = 1; 6408 goto scsisanitize_bailout; 6409 } 6410 dxfer_len = sizeof(*pl) + sz; 6411 data_ptr = calloc(1, dxfer_len); 6412 if (data_ptr == NULL) { 6413 warnx("cannot allocate parameter list buffer"); 6414 error = 1; 6415 goto scsisanitize_bailout; 6416 } 6417 6418 amt = read(fd, data_ptr + sizeof(*pl), sz); 6419 if (amt < 0) { 6420 warn("cannot read pattern file"); 6421 error = 1; 6422 goto scsisanitize_bailout; 6423 } else if (amt != sz) { 6424 warnx("short pattern file read"); 6425 error = 1; 6426 goto scsisanitize_bailout; 6427 } 6428 6429 pl = (struct scsi_sanitize_parameter_list *)data_ptr; 6430 if (passes == 0) 6431 pl->byte1 = 1; 6432 else 6433 pl->byte1 = passes; 6434 if (invert != 0) 6435 pl->byte1 |= SSZPL_INVERT; 6436 scsi_ulto2b(sz, pl->length); 6437 } else { 6438 const char *arg; 6439 6440 if (passes != 0) 6441 arg = "-c"; 6442 else if (invert != 0) 6443 arg = "-I"; 6444 else if (pattern != NULL) 6445 arg = "-P"; 6446 else 6447 arg = NULL; 6448 if (arg != NULL) { 6449 warnx("%s argument only valid with overwrite " 6450 "operation", arg); 6451 error = 1; 6452 goto scsisanitize_bailout; 6453 } 6454 } 6455 6456 if (quiet == 0) { 6457 fprintf(stdout, "You are about to REMOVE ALL DATA from the " 6458 "following device:\n"); 6459 6460 error = scsidoinquiry(device, argc, argv, combinedopt, 6461 task_attr, retry_count, timeout); 6462 6463 if (error != 0) { 6464 warnx("scsisanitize: error sending inquiry"); 6465 goto scsisanitize_bailout; 6466 } 6467 } 6468 6469 if (ycount == 0) { 6470 if (!get_confirmation()) { 6471 error = 1; 6472 goto scsisanitize_bailout; 6473 } 6474 } 6475 6476 if (timeout != 0) 6477 use_timeout = timeout; 6478 6479 if (quiet == 0) { 6480 fprintf(stdout, "Current sanitize timeout is %d seconds\n", 6481 use_timeout / 1000); 6482 } 6483 6484 /* 6485 * If the user hasn't disabled questions and didn't specify a 6486 * timeout on the command line, ask them if they want the current 6487 * timeout. 6488 */ 6489 if ((ycount == 0) 6490 && (timeout == 0)) { 6491 char str[1024]; 6492 int new_timeout = 0; 6493 6494 fprintf(stdout, "Enter new timeout in seconds or press\n" 6495 "return to keep the current timeout [%d] ", 6496 use_timeout / 1000); 6497 6498 if (fgets(str, sizeof(str), stdin) != NULL) { 6499 if (str[0] != '\0') 6500 new_timeout = atoi(str); 6501 } 6502 6503 if (new_timeout != 0) { 6504 use_timeout = new_timeout * 1000; 6505 fprintf(stdout, "Using new timeout value %d\n", 6506 use_timeout / 1000); 6507 } 6508 } 6509 6510 byte2 = action; 6511 if (ause != 0) 6512 byte2 |= SSZ_UNRESTRICTED_EXIT; 6513 if (immediate != 0) 6514 byte2 |= SSZ_IMMED; 6515 6516 scsi_sanitize(&ccb->csio, 6517 /* retries */ retry_count, 6518 /* cbfcnp */ NULL, 6519 /* tag_action */ task_attr, 6520 /* byte2 */ byte2, 6521 /* control */ 0, 6522 /* data_ptr */ data_ptr, 6523 /* dxfer_len */ dxfer_len, 6524 /* sense_len */ SSD_FULL_SIZE, 6525 /* timeout */ use_timeout); 6526 6527 /* Disable freezing the device queue */ 6528 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6529 6530 if (arglist & CAM_ARG_ERR_RECOVER) 6531 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6532 6533 if (cam_send_ccb(device, ccb) < 0) { 6534 warn("error sending sanitize command"); 6535 error = 1; 6536 goto scsisanitize_bailout; 6537 } 6538 6539 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6540 struct scsi_sense_data *sense; 6541 int error_code, sense_key, asc, ascq; 6542 6543 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 6544 CAM_SCSI_STATUS_ERROR) { 6545 sense = &ccb->csio.sense_data; 6546 scsi_extract_sense_len(sense, ccb->csio.sense_len - 6547 ccb->csio.sense_resid, &error_code, &sense_key, 6548 &asc, &ascq, /*show_errors*/ 1); 6549 6550 if (sense_key == SSD_KEY_ILLEGAL_REQUEST && 6551 asc == 0x20 && ascq == 0x00) 6552 warnx("sanitize is not supported by " 6553 "this device"); 6554 else 6555 warnx("error sanitizing this device"); 6556 } else 6557 warnx("error sanitizing this device"); 6558 6559 if (arglist & CAM_ARG_VERBOSE) { 6560 cam_error_print(device, ccb, CAM_ESF_ALL, 6561 CAM_EPF_ALL, stderr); 6562 } 6563 error = 1; 6564 goto scsisanitize_bailout; 6565 } 6566 6567 /* 6568 * If we ran in non-immediate mode, we already checked for errors 6569 * above and printed out any necessary information. If we're in 6570 * immediate mode, we need to loop through and get status 6571 * information periodically. 6572 */ 6573 if (immediate == 0) { 6574 if (quiet == 0) { 6575 fprintf(stdout, "Sanitize Complete\n"); 6576 } 6577 goto scsisanitize_bailout; 6578 } 6579 6580doreport: 6581 do { 6582 cam_status status; 6583 6584 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6585 6586 /* 6587 * There's really no need to do error recovery or 6588 * retries here, since we're just going to sit in a 6589 * loop and wait for the device to finish sanitizing. 6590 */ 6591 scsi_test_unit_ready(&ccb->csio, 6592 /* retries */ 0, 6593 /* cbfcnp */ NULL, 6594 /* tag_action */ task_attr, 6595 /* sense_len */ SSD_FULL_SIZE, 6596 /* timeout */ 5000); 6597 6598 /* Disable freezing the device queue */ 6599 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6600 6601 retval = cam_send_ccb(device, ccb); 6602 6603 /* 6604 * If we get an error from the ioctl, bail out. SCSI 6605 * errors are expected. 6606 */ 6607 if (retval < 0) { 6608 warn("error sending CAMIOCOMMAND ioctl"); 6609 if (arglist & CAM_ARG_VERBOSE) { 6610 cam_error_print(device, ccb, CAM_ESF_ALL, 6611 CAM_EPF_ALL, stderr); 6612 } 6613 error = 1; 6614 goto scsisanitize_bailout; 6615 } 6616 6617 status = ccb->ccb_h.status & CAM_STATUS_MASK; 6618 6619 if ((status != CAM_REQ_CMP) 6620 && (status == CAM_SCSI_STATUS_ERROR) 6621 && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { 6622 struct scsi_sense_data *sense; 6623 int error_code, sense_key, asc, ascq; 6624 6625 sense = &ccb->csio.sense_data; 6626 scsi_extract_sense_len(sense, ccb->csio.sense_len - 6627 ccb->csio.sense_resid, &error_code, &sense_key, 6628 &asc, &ascq, /*show_errors*/ 1); 6629 6630 /* 6631 * According to the SCSI-3 spec, a drive that is in the 6632 * middle of a sanitize should return NOT READY with an 6633 * ASC of "logical unit not ready, sanitize in 6634 * progress". The sense key specific bytes will then 6635 * be a progress indicator. 6636 */ 6637 if ((sense_key == SSD_KEY_NOT_READY) 6638 && (asc == 0x04) && (ascq == 0x1b)) { 6639 uint8_t sks[3]; 6640 6641 if ((scsi_get_sks(sense, ccb->csio.sense_len - 6642 ccb->csio.sense_resid, sks) == 0) 6643 && (quiet == 0)) { 6644 int val; 6645 u_int64_t percentage; 6646 6647 val = scsi_2btoul(&sks[1]); 6648 percentage = 10000 * val; 6649 6650 fprintf(stdout, 6651 "\rSanitizing: %ju.%02u %% " 6652 "(%d/%d) done", 6653 (uintmax_t)(percentage / 6654 (0x10000 * 100)), 6655 (unsigned)((percentage / 6656 0x10000) % 100), 6657 val, 0x10000); 6658 fflush(stdout); 6659 } else if ((quiet == 0) 6660 && (++num_warnings <= 1)) { 6661 warnx("Unexpected SCSI Sense Key " 6662 "Specific value returned " 6663 "during sanitize:"); 6664 scsi_sense_print(device, &ccb->csio, 6665 stderr); 6666 warnx("Unable to print status " 6667 "information, but sanitze will " 6668 "proceed."); 6669 warnx("will exit when sanitize is " 6670 "complete"); 6671 } 6672 sleep(1); 6673 } else { 6674 warnx("Unexpected SCSI error during sanitize"); 6675 cam_error_print(device, ccb, CAM_ESF_ALL, 6676 CAM_EPF_ALL, stderr); 6677 error = 1; 6678 goto scsisanitize_bailout; 6679 } 6680 6681 } else if (status != CAM_REQ_CMP) { 6682 warnx("Unexpected CAM status %#x", status); 6683 if (arglist & CAM_ARG_VERBOSE) 6684 cam_error_print(device, ccb, CAM_ESF_ALL, 6685 CAM_EPF_ALL, stderr); 6686 error = 1; 6687 goto scsisanitize_bailout; 6688 } 6689 } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); 6690 6691 if (quiet == 0) 6692 fprintf(stdout, "\nSanitize Complete\n"); 6693 6694scsisanitize_bailout: 6695 if (fd >= 0) 6696 close(fd); 6697 if (data_ptr != NULL) 6698 free(data_ptr); 6699 cam_freeccb(ccb); 6700 6701 return (error); 6702} 6703 6704static int 6705scsireportluns(struct cam_device *device, int argc, char **argv, 6706 char *combinedopt, int task_attr, int retry_count, int timeout) 6707{ 6708 union ccb *ccb; 6709 int c, countonly, lunsonly; 6710 struct scsi_report_luns_data *lundata; 6711 int alloc_len; 6712 uint8_t report_type; 6713 uint32_t list_len, i, j; 6714 int retval; 6715 6716 retval = 0; 6717 lundata = NULL; 6718 report_type = RPL_REPORT_DEFAULT; 6719 ccb = cam_getccb(device); 6720 6721 if (ccb == NULL) { 6722 warnx("%s: error allocating ccb", __func__); 6723 return (1); 6724 } 6725 6726 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6727 6728 countonly = 0; 6729 lunsonly = 0; 6730 6731 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6732 switch (c) { 6733 case 'c': 6734 countonly++; 6735 break; 6736 case 'l': 6737 lunsonly++; 6738 break; 6739 case 'r': 6740 if (strcasecmp(optarg, "default") == 0) 6741 report_type = RPL_REPORT_DEFAULT; 6742 else if (strcasecmp(optarg, "wellknown") == 0) 6743 report_type = RPL_REPORT_WELLKNOWN; 6744 else if (strcasecmp(optarg, "all") == 0) 6745 report_type = RPL_REPORT_ALL; 6746 else { 6747 warnx("%s: invalid report type \"%s\"", 6748 __func__, optarg); 6749 retval = 1; 6750 goto bailout; 6751 } 6752 break; 6753 default: 6754 break; 6755 } 6756 } 6757 6758 if ((countonly != 0) 6759 && (lunsonly != 0)) { 6760 warnx("%s: you can only specify one of -c or -l", __func__); 6761 retval = 1; 6762 goto bailout; 6763 } 6764 /* 6765 * According to SPC-4, the allocation length must be at least 16 6766 * bytes -- enough for the header and one LUN. 6767 */ 6768 alloc_len = sizeof(*lundata) + 8; 6769 6770retry: 6771 6772 lundata = malloc(alloc_len); 6773 6774 if (lundata == NULL) { 6775 warn("%s: error mallocing %d bytes", __func__, alloc_len); 6776 retval = 1; 6777 goto bailout; 6778 } 6779 6780 scsi_report_luns(&ccb->csio, 6781 /*retries*/ retry_count, 6782 /*cbfcnp*/ NULL, 6783 /*tag_action*/ task_attr, 6784 /*select_report*/ report_type, 6785 /*rpl_buf*/ lundata, 6786 /*alloc_len*/ alloc_len, 6787 /*sense_len*/ SSD_FULL_SIZE, 6788 /*timeout*/ timeout ? timeout : 5000); 6789 6790 /* Disable freezing the device queue */ 6791 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 6792 6793 if (arglist & CAM_ARG_ERR_RECOVER) 6794 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 6795 6796 if (cam_send_ccb(device, ccb) < 0) { 6797 warn("error sending REPORT LUNS command"); 6798 6799 if (arglist & CAM_ARG_VERBOSE) 6800 cam_error_print(device, ccb, CAM_ESF_ALL, 6801 CAM_EPF_ALL, stderr); 6802 6803 retval = 1; 6804 goto bailout; 6805 } 6806 6807 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 6808 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 6809 retval = 1; 6810 goto bailout; 6811 } 6812 6813 6814 list_len = scsi_4btoul(lundata->length); 6815 6816 /* 6817 * If we need to list the LUNs, and our allocation 6818 * length was too short, reallocate and retry. 6819 */ 6820 if ((countonly == 0) 6821 && (list_len > (alloc_len - sizeof(*lundata)))) { 6822 alloc_len = list_len + sizeof(*lundata); 6823 free(lundata); 6824 goto retry; 6825 } 6826 6827 if (lunsonly == 0) 6828 fprintf(stdout, "%u LUN%s found\n", list_len / 8, 6829 ((list_len / 8) > 1) ? "s" : ""); 6830 6831 if (countonly != 0) 6832 goto bailout; 6833 6834 for (i = 0; i < (list_len / 8); i++) { 6835 int no_more; 6836 6837 no_more = 0; 6838 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) { 6839 if (j != 0) 6840 fprintf(stdout, ","); 6841 switch (lundata->luns[i].lundata[j] & 6842 RPL_LUNDATA_ATYP_MASK) { 6843 case RPL_LUNDATA_ATYP_PERIPH: 6844 if ((lundata->luns[i].lundata[j] & 6845 RPL_LUNDATA_PERIPH_BUS_MASK) != 0) 6846 fprintf(stdout, "%d:", 6847 lundata->luns[i].lundata[j] & 6848 RPL_LUNDATA_PERIPH_BUS_MASK); 6849 else if ((j == 0) 6850 && ((lundata->luns[i].lundata[j+2] & 6851 RPL_LUNDATA_PERIPH_BUS_MASK) == 0)) 6852 no_more = 1; 6853 6854 fprintf(stdout, "%d", 6855 lundata->luns[i].lundata[j+1]); 6856 break; 6857 case RPL_LUNDATA_ATYP_FLAT: { 6858 uint8_t tmplun[2]; 6859 tmplun[0] = lundata->luns[i].lundata[j] & 6860 RPL_LUNDATA_FLAT_LUN_MASK; 6861 tmplun[1] = lundata->luns[i].lundata[j+1]; 6862 6863 fprintf(stdout, "%d", scsi_2btoul(tmplun)); 6864 no_more = 1; 6865 break; 6866 } 6867 case RPL_LUNDATA_ATYP_LUN: 6868 fprintf(stdout, "%d:%d:%d", 6869 (lundata->luns[i].lundata[j+1] & 6870 RPL_LUNDATA_LUN_BUS_MASK) >> 5, 6871 lundata->luns[i].lundata[j] & 6872 RPL_LUNDATA_LUN_TARG_MASK, 6873 lundata->luns[i].lundata[j+1] & 6874 RPL_LUNDATA_LUN_LUN_MASK); 6875 break; 6876 case RPL_LUNDATA_ATYP_EXTLUN: { 6877 int field_len_code, eam_code; 6878 6879 eam_code = lundata->luns[i].lundata[j] & 6880 RPL_LUNDATA_EXT_EAM_MASK; 6881 field_len_code = (lundata->luns[i].lundata[j] & 6882 RPL_LUNDATA_EXT_LEN_MASK) >> 4; 6883 6884 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK) 6885 && (field_len_code == 0x00)) { 6886 fprintf(stdout, "%d", 6887 lundata->luns[i].lundata[j+1]); 6888 } else if ((eam_code == 6889 RPL_LUNDATA_EXT_EAM_NOT_SPEC) 6890 && (field_len_code == 0x03)) { 6891 uint8_t tmp_lun[8]; 6892 6893 /* 6894 * This format takes up all 8 bytes. 6895 * If we aren't starting at offset 0, 6896 * that's a bug. 6897 */ 6898 if (j != 0) { 6899 fprintf(stdout, "Invalid " 6900 "offset %d for " 6901 "Extended LUN not " 6902 "specified format", j); 6903 no_more = 1; 6904 break; 6905 } 6906 bzero(tmp_lun, sizeof(tmp_lun)); 6907 bcopy(&lundata->luns[i].lundata[j+1], 6908 &tmp_lun[1], sizeof(tmp_lun) - 1); 6909 fprintf(stdout, "%#jx", 6910 (intmax_t)scsi_8btou64(tmp_lun)); 6911 no_more = 1; 6912 } else { 6913 fprintf(stderr, "Unknown Extended LUN" 6914 "Address method %#x, length " 6915 "code %#x", eam_code, 6916 field_len_code); 6917 no_more = 1; 6918 } 6919 break; 6920 } 6921 default: 6922 fprintf(stderr, "Unknown LUN address method " 6923 "%#x\n", lundata->luns[i].lundata[0] & 6924 RPL_LUNDATA_ATYP_MASK); 6925 break; 6926 } 6927 /* 6928 * For the flat addressing method, there are no 6929 * other levels after it. 6930 */ 6931 if (no_more != 0) 6932 break; 6933 } 6934 fprintf(stdout, "\n"); 6935 } 6936 6937bailout: 6938 6939 cam_freeccb(ccb); 6940 6941 free(lundata); 6942 6943 return (retval); 6944} 6945 6946static int 6947scsireadcapacity(struct cam_device *device, int argc, char **argv, 6948 char *combinedopt, int task_attr, int retry_count, int timeout) 6949{ 6950 union ccb *ccb; 6951 int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly; 6952 struct scsi_read_capacity_data rcap; 6953 struct scsi_read_capacity_data_long rcaplong; 6954 uint64_t maxsector; 6955 uint32_t block_len; 6956 int retval; 6957 int c; 6958 6959 blocksizeonly = 0; 6960 humanize = 0; 6961 longonly = 0; 6962 numblocks = 0; 6963 quiet = 0; 6964 sizeonly = 0; 6965 baseten = 0; 6966 retval = 0; 6967 6968 ccb = cam_getccb(device); 6969 6970 if (ccb == NULL) { 6971 warnx("%s: error allocating ccb", __func__); 6972 return (1); 6973 } 6974 6975 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 6976 6977 while ((c = getopt(argc, argv, combinedopt)) != -1) { 6978 switch (c) { 6979 case 'b': 6980 blocksizeonly++; 6981 break; 6982 case 'h': 6983 humanize++; 6984 baseten = 0; 6985 break; 6986 case 'H': 6987 humanize++; 6988 baseten++; 6989 break; 6990 case 'l': 6991 longonly++; 6992 break; 6993 case 'N': 6994 numblocks++; 6995 break; 6996 case 'q': 6997 quiet++; 6998 break; 6999 case 's': 7000 sizeonly++; 7001 break; 7002 default: 7003 break; 7004 } 7005 } 7006 7007 if ((blocksizeonly != 0) 7008 && (numblocks != 0)) { 7009 warnx("%s: you can only specify one of -b or -N", __func__); 7010 retval = 1; 7011 goto bailout; 7012 } 7013 7014 if ((blocksizeonly != 0) 7015 && (sizeonly != 0)) { 7016 warnx("%s: you can only specify one of -b or -s", __func__); 7017 retval = 1; 7018 goto bailout; 7019 } 7020 7021 if ((humanize != 0) 7022 && (quiet != 0)) { 7023 warnx("%s: you can only specify one of -h/-H or -q", __func__); 7024 retval = 1; 7025 goto bailout; 7026 } 7027 7028 if ((humanize != 0) 7029 && (blocksizeonly != 0)) { 7030 warnx("%s: you can only specify one of -h/-H or -b", __func__); 7031 retval = 1; 7032 goto bailout; 7033 } 7034 7035 if (longonly != 0) 7036 goto long_only; 7037 7038 scsi_read_capacity(&ccb->csio, 7039 /*retries*/ retry_count, 7040 /*cbfcnp*/ NULL, 7041 /*tag_action*/ task_attr, 7042 &rcap, 7043 SSD_FULL_SIZE, 7044 /*timeout*/ timeout ? timeout : 5000); 7045 7046 /* Disable freezing the device queue */ 7047 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 7048 7049 if (arglist & CAM_ARG_ERR_RECOVER) 7050 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 7051 7052 if (cam_send_ccb(device, ccb) < 0) { 7053 warn("error sending READ CAPACITY command"); 7054 7055 if (arglist & CAM_ARG_VERBOSE) 7056 cam_error_print(device, ccb, CAM_ESF_ALL, 7057 CAM_EPF_ALL, stderr); 7058 7059 retval = 1; 7060 goto bailout; 7061 } 7062 7063 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 7064 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 7065 retval = 1; 7066 goto bailout; 7067 } 7068 7069 maxsector = scsi_4btoul(rcap.addr); 7070 block_len = scsi_4btoul(rcap.length); 7071 7072 /* 7073 * A last block of 2^32-1 means that the true capacity is over 2TB, 7074 * and we need to issue the long READ CAPACITY to get the real 7075 * capacity. Otherwise, we're all set. 7076 */ 7077 if (maxsector != 0xffffffff) 7078 goto do_print; 7079 7080long_only: 7081 scsi_read_capacity_16(&ccb->csio, 7082 /*retries*/ retry_count, 7083 /*cbfcnp*/ NULL, 7084 /*tag_action*/ task_attr, 7085 /*lba*/ 0, 7086 /*reladdr*/ 0, 7087 /*pmi*/ 0, 7088 /*rcap_buf*/ (uint8_t *)&rcaplong, 7089 /*rcap_buf_len*/ sizeof(rcaplong), 7090 /*sense_len*/ SSD_FULL_SIZE, 7091 /*timeout*/ timeout ? timeout : 5000); 7092 7093 /* Disable freezing the device queue */ 7094 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 7095 7096 if (arglist & CAM_ARG_ERR_RECOVER) 7097 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 7098 7099 if (cam_send_ccb(device, ccb) < 0) { 7100 warn("error sending READ CAPACITY (16) command"); 7101 7102 if (arglist & CAM_ARG_VERBOSE) 7103 cam_error_print(device, ccb, CAM_ESF_ALL, 7104 CAM_EPF_ALL, stderr); 7105 7106 retval = 1; 7107 goto bailout; 7108 } 7109 7110 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 7111 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 7112 retval = 1; 7113 goto bailout; 7114 } 7115 7116 maxsector = scsi_8btou64(rcaplong.addr); 7117 block_len = scsi_4btoul(rcaplong.length); 7118 7119do_print: 7120 if (blocksizeonly == 0) { 7121 /* 7122 * Humanize implies !quiet, and also implies numblocks. 7123 */ 7124 if (humanize != 0) { 7125 char tmpstr[6]; 7126 int64_t tmpbytes; 7127 int ret; 7128 7129 tmpbytes = (maxsector + 1) * block_len; 7130 ret = humanize_number(tmpstr, sizeof(tmpstr), 7131 tmpbytes, "", HN_AUTOSCALE, 7132 HN_B | HN_DECIMAL | 7133 ((baseten != 0) ? 7134 HN_DIVISOR_1000 : 0)); 7135 if (ret == -1) { 7136 warnx("%s: humanize_number failed!", __func__); 7137 retval = 1; 7138 goto bailout; 7139 } 7140 fprintf(stdout, "Device Size: %s%s", tmpstr, 7141 (sizeonly == 0) ? ", " : "\n"); 7142 } else if (numblocks != 0) { 7143 fprintf(stdout, "%s%ju%s", (quiet == 0) ? 7144 "Blocks: " : "", (uintmax_t)maxsector + 1, 7145 (sizeonly == 0) ? ", " : "\n"); 7146 } else { 7147 fprintf(stdout, "%s%ju%s", (quiet == 0) ? 7148 "Last Block: " : "", (uintmax_t)maxsector, 7149 (sizeonly == 0) ? ", " : "\n"); 7150 } 7151 } 7152 if (sizeonly == 0) 7153 fprintf(stdout, "%s%u%s\n", (quiet == 0) ? 7154 "Block Length: " : "", block_len, (quiet == 0) ? 7155 " bytes" : ""); 7156bailout: 7157 cam_freeccb(ccb); 7158 7159 return (retval); 7160} 7161 7162static int 7163smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, 7164 int retry_count, int timeout) 7165{ 7166 int c, error = 0; 7167 union ccb *ccb; 7168 uint8_t *smp_request = NULL, *smp_response = NULL; 7169 int request_size = 0, response_size = 0; 7170 int fd_request = 0, fd_response = 0; 7171 char *datastr = NULL; 7172 struct get_hook hook; 7173 int retval; 7174 int flags = 0; 7175 7176 /* 7177 * Note that at the moment we don't support sending SMP CCBs to 7178 * devices that aren't probed by CAM. 7179 */ 7180 ccb = cam_getccb(device); 7181 if (ccb == NULL) { 7182 warnx("%s: error allocating CCB", __func__); 7183 return (1); 7184 } 7185 7186 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7187 7188 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7189 switch (c) { 7190 case 'R': 7191 arglist |= CAM_ARG_CMD_IN; 7192 response_size = strtol(optarg, NULL, 0); 7193 if (response_size <= 0) { 7194 warnx("invalid number of response bytes %d", 7195 response_size); 7196 error = 1; 7197 goto smpcmd_bailout; 7198 } 7199 hook.argc = argc - optind; 7200 hook.argv = argv + optind; 7201 hook.got = 0; 7202 optind++; 7203 datastr = cget(&hook, NULL); 7204 /* 7205 * If the user supplied "-" instead of a format, he 7206 * wants the data to be written to stdout. 7207 */ 7208 if ((datastr != NULL) 7209 && (datastr[0] == '-')) 7210 fd_response = 1; 7211 7212 smp_response = (u_int8_t *)malloc(response_size); 7213 if (smp_response == NULL) { 7214 warn("can't malloc memory for SMP response"); 7215 error = 1; 7216 goto smpcmd_bailout; 7217 } 7218 break; 7219 case 'r': 7220 arglist |= CAM_ARG_CMD_OUT; 7221 request_size = strtol(optarg, NULL, 0); 7222 if (request_size <= 0) { 7223 warnx("invalid number of request bytes %d", 7224 request_size); 7225 error = 1; 7226 goto smpcmd_bailout; 7227 } 7228 hook.argc = argc - optind; 7229 hook.argv = argv + optind; 7230 hook.got = 0; 7231 datastr = cget(&hook, NULL); 7232 smp_request = (u_int8_t *)malloc(request_size); 7233 if (smp_request == NULL) { 7234 warn("can't malloc memory for SMP request"); 7235 error = 1; 7236 goto smpcmd_bailout; 7237 } 7238 bzero(smp_request, request_size); 7239 /* 7240 * If the user supplied "-" instead of a format, he 7241 * wants the data to be read from stdin. 7242 */ 7243 if ((datastr != NULL) 7244 && (datastr[0] == '-')) 7245 fd_request = 1; 7246 else 7247 buff_encode_visit(smp_request, request_size, 7248 datastr, 7249 iget, &hook); 7250 optind += hook.got; 7251 break; 7252 default: 7253 break; 7254 } 7255 } 7256 7257 /* 7258 * If fd_data is set, and we're writing to the device, we need to 7259 * read the data the user wants written from stdin. 7260 */ 7261 if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) { 7262 ssize_t amt_read; 7263 int amt_to_read = request_size; 7264 u_int8_t *buf_ptr = smp_request; 7265 7266 for (amt_read = 0; amt_to_read > 0; 7267 amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) { 7268 if (amt_read == -1) { 7269 warn("error reading data from stdin"); 7270 error = 1; 7271 goto smpcmd_bailout; 7272 } 7273 amt_to_read -= amt_read; 7274 buf_ptr += amt_read; 7275 } 7276 } 7277 7278 if (((arglist & CAM_ARG_CMD_IN) == 0) 7279 || ((arglist & CAM_ARG_CMD_OUT) == 0)) { 7280 warnx("%s: need both the request (-r) and response (-R) " 7281 "arguments", __func__); 7282 error = 1; 7283 goto smpcmd_bailout; 7284 } 7285 7286 flags |= CAM_DEV_QFRZDIS; 7287 7288 cam_fill_smpio(&ccb->smpio, 7289 /*retries*/ retry_count, 7290 /*cbfcnp*/ NULL, 7291 /*flags*/ flags, 7292 /*smp_request*/ smp_request, 7293 /*smp_request_len*/ request_size, 7294 /*smp_response*/ smp_response, 7295 /*smp_response_len*/ response_size, 7296 /*timeout*/ timeout ? timeout : 5000); 7297 7298 ccb->smpio.flags = SMP_FLAG_NONE; 7299 7300 if (((retval = cam_send_ccb(device, ccb)) < 0) 7301 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7302 const char warnstr[] = "error sending command"; 7303 7304 if (retval < 0) 7305 warn(warnstr); 7306 else 7307 warnx(warnstr); 7308 7309 if (arglist & CAM_ARG_VERBOSE) { 7310 cam_error_print(device, ccb, CAM_ESF_ALL, 7311 CAM_EPF_ALL, stderr); 7312 } 7313 } 7314 7315 if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) 7316 && (response_size > 0)) { 7317 if (fd_response == 0) { 7318 buff_decode_visit(smp_response, response_size, 7319 datastr, arg_put, NULL); 7320 fprintf(stdout, "\n"); 7321 } else { 7322 ssize_t amt_written; 7323 int amt_to_write = response_size; 7324 u_int8_t *buf_ptr = smp_response; 7325 7326 for (amt_written = 0; (amt_to_write > 0) && 7327 (amt_written = write(STDOUT_FILENO, buf_ptr, 7328 amt_to_write)) > 0;){ 7329 amt_to_write -= amt_written; 7330 buf_ptr += amt_written; 7331 } 7332 if (amt_written == -1) { 7333 warn("error writing data to stdout"); 7334 error = 1; 7335 goto smpcmd_bailout; 7336 } else if ((amt_written == 0) 7337 && (amt_to_write > 0)) { 7338 warnx("only wrote %u bytes out of %u", 7339 response_size - amt_to_write, 7340 response_size); 7341 } 7342 } 7343 } 7344smpcmd_bailout: 7345 if (ccb != NULL) 7346 cam_freeccb(ccb); 7347 7348 if (smp_request != NULL) 7349 free(smp_request); 7350 7351 if (smp_response != NULL) 7352 free(smp_response); 7353 7354 return (error); 7355} 7356 7357static int 7358smpreportgeneral(struct cam_device *device, int argc, char **argv, 7359 char *combinedopt, int retry_count, int timeout) 7360{ 7361 union ccb *ccb; 7362 struct smp_report_general_request *request = NULL; 7363 struct smp_report_general_response *response = NULL; 7364 struct sbuf *sb = NULL; 7365 int error = 0; 7366 int c, long_response = 0; 7367 int retval; 7368 7369 /* 7370 * Note that at the moment we don't support sending SMP CCBs to 7371 * devices that aren't probed by CAM. 7372 */ 7373 ccb = cam_getccb(device); 7374 if (ccb == NULL) { 7375 warnx("%s: error allocating CCB", __func__); 7376 return (1); 7377 } 7378 7379 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7380 7381 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7382 switch (c) { 7383 case 'l': 7384 long_response = 1; 7385 break; 7386 default: 7387 break; 7388 } 7389 } 7390 request = malloc(sizeof(*request)); 7391 if (request == NULL) { 7392 warn("%s: unable to allocate %zd bytes", __func__, 7393 sizeof(*request)); 7394 error = 1; 7395 goto bailout; 7396 } 7397 7398 response = malloc(sizeof(*response)); 7399 if (response == NULL) { 7400 warn("%s: unable to allocate %zd bytes", __func__, 7401 sizeof(*response)); 7402 error = 1; 7403 goto bailout; 7404 } 7405 7406try_long: 7407 smp_report_general(&ccb->smpio, 7408 retry_count, 7409 /*cbfcnp*/ NULL, 7410 request, 7411 /*request_len*/ sizeof(*request), 7412 (uint8_t *)response, 7413 /*response_len*/ sizeof(*response), 7414 /*long_response*/ long_response, 7415 timeout); 7416 7417 if (((retval = cam_send_ccb(device, ccb)) < 0) 7418 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7419 const char warnstr[] = "error sending command"; 7420 7421 if (retval < 0) 7422 warn(warnstr); 7423 else 7424 warnx(warnstr); 7425 7426 if (arglist & CAM_ARG_VERBOSE) { 7427 cam_error_print(device, ccb, CAM_ESF_ALL, 7428 CAM_EPF_ALL, stderr); 7429 } 7430 error = 1; 7431 goto bailout; 7432 } 7433 7434 /* 7435 * If the device supports the long response bit, try again and see 7436 * if we can get all of the data. 7437 */ 7438 if ((response->long_response & SMP_RG_LONG_RESPONSE) 7439 && (long_response == 0)) { 7440 ccb->ccb_h.status = CAM_REQ_INPROG; 7441 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7442 long_response = 1; 7443 goto try_long; 7444 } 7445 7446 /* 7447 * XXX KDM detect and decode SMP errors here. 7448 */ 7449 sb = sbuf_new_auto(); 7450 if (sb == NULL) { 7451 warnx("%s: error allocating sbuf", __func__); 7452 goto bailout; 7453 } 7454 7455 smp_report_general_sbuf(response, sizeof(*response), sb); 7456 7457 if (sbuf_finish(sb) != 0) { 7458 warnx("%s: sbuf_finish", __func__); 7459 goto bailout; 7460 } 7461 7462 printf("%s", sbuf_data(sb)); 7463 7464bailout: 7465 if (ccb != NULL) 7466 cam_freeccb(ccb); 7467 7468 if (request != NULL) 7469 free(request); 7470 7471 if (response != NULL) 7472 free(response); 7473 7474 if (sb != NULL) 7475 sbuf_delete(sb); 7476 7477 return (error); 7478} 7479 7480static struct camcontrol_opts phy_ops[] = { 7481 {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL}, 7482 {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL}, 7483 {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL}, 7484 {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL}, 7485 {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL}, 7486 {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL}, 7487 {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL}, 7488 {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL}, 7489 {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL}, 7490 {NULL, 0, 0, NULL} 7491}; 7492 7493static int 7494smpphycontrol(struct cam_device *device, int argc, char **argv, 7495 char *combinedopt, int retry_count, int timeout) 7496{ 7497 union ccb *ccb; 7498 struct smp_phy_control_request *request = NULL; 7499 struct smp_phy_control_response *response = NULL; 7500 int long_response = 0; 7501 int retval = 0; 7502 int phy = -1; 7503 uint32_t phy_operation = SMP_PC_PHY_OP_NOP; 7504 int phy_op_set = 0; 7505 uint64_t attached_dev_name = 0; 7506 int dev_name_set = 0; 7507 uint32_t min_plr = 0, max_plr = 0; 7508 uint32_t pp_timeout_val = 0; 7509 int slumber_partial = 0; 7510 int set_pp_timeout_val = 0; 7511 int c; 7512 7513 /* 7514 * Note that at the moment we don't support sending SMP CCBs to 7515 * devices that aren't probed by CAM. 7516 */ 7517 ccb = cam_getccb(device); 7518 if (ccb == NULL) { 7519 warnx("%s: error allocating CCB", __func__); 7520 return (1); 7521 } 7522 7523 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7524 7525 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7526 switch (c) { 7527 case 'a': 7528 case 'A': 7529 case 's': 7530 case 'S': { 7531 int enable = -1; 7532 7533 if (strcasecmp(optarg, "enable") == 0) 7534 enable = 1; 7535 else if (strcasecmp(optarg, "disable") == 0) 7536 enable = 2; 7537 else { 7538 warnx("%s: Invalid argument %s", __func__, 7539 optarg); 7540 retval = 1; 7541 goto bailout; 7542 } 7543 switch (c) { 7544 case 's': 7545 slumber_partial |= enable << 7546 SMP_PC_SAS_SLUMBER_SHIFT; 7547 break; 7548 case 'S': 7549 slumber_partial |= enable << 7550 SMP_PC_SAS_PARTIAL_SHIFT; 7551 break; 7552 case 'a': 7553 slumber_partial |= enable << 7554 SMP_PC_SATA_SLUMBER_SHIFT; 7555 break; 7556 case 'A': 7557 slumber_partial |= enable << 7558 SMP_PC_SATA_PARTIAL_SHIFT; 7559 break; 7560 default: 7561 warnx("%s: programmer error", __func__); 7562 retval = 1; 7563 goto bailout; 7564 break; /*NOTREACHED*/ 7565 } 7566 break; 7567 } 7568 case 'd': 7569 attached_dev_name = (uintmax_t)strtoumax(optarg, 7570 NULL,0); 7571 dev_name_set = 1; 7572 break; 7573 case 'l': 7574 long_response = 1; 7575 break; 7576 case 'm': 7577 /* 7578 * We don't do extensive checking here, so this 7579 * will continue to work when new speeds come out. 7580 */ 7581 min_plr = strtoul(optarg, NULL, 0); 7582 if ((min_plr == 0) 7583 || (min_plr > 0xf)) { 7584 warnx("%s: invalid link rate %x", 7585 __func__, min_plr); 7586 retval = 1; 7587 goto bailout; 7588 } 7589 break; 7590 case 'M': 7591 /* 7592 * We don't do extensive checking here, so this 7593 * will continue to work when new speeds come out. 7594 */ 7595 max_plr = strtoul(optarg, NULL, 0); 7596 if ((max_plr == 0) 7597 || (max_plr > 0xf)) { 7598 warnx("%s: invalid link rate %x", 7599 __func__, max_plr); 7600 retval = 1; 7601 goto bailout; 7602 } 7603 break; 7604 case 'o': { 7605 camcontrol_optret optreturn; 7606 cam_argmask argnums; 7607 const char *subopt; 7608 7609 if (phy_op_set != 0) { 7610 warnx("%s: only one phy operation argument " 7611 "(-o) allowed", __func__); 7612 retval = 1; 7613 goto bailout; 7614 } 7615 7616 phy_op_set = 1; 7617 7618 /* 7619 * Allow the user to specify the phy operation 7620 * numerically, as well as with a name. This will 7621 * future-proof it a bit, so options that are added 7622 * in future specs can be used. 7623 */ 7624 if (isdigit(optarg[0])) { 7625 phy_operation = strtoul(optarg, NULL, 0); 7626 if ((phy_operation == 0) 7627 || (phy_operation > 0xff)) { 7628 warnx("%s: invalid phy operation %#x", 7629 __func__, phy_operation); 7630 retval = 1; 7631 goto bailout; 7632 } 7633 break; 7634 } 7635 optreturn = getoption(phy_ops, optarg, &phy_operation, 7636 &argnums, &subopt); 7637 7638 if (optreturn == CC_OR_AMBIGUOUS) { 7639 warnx("%s: ambiguous option %s", __func__, 7640 optarg); 7641 usage(0); 7642 retval = 1; 7643 goto bailout; 7644 } else if (optreturn == CC_OR_NOT_FOUND) { 7645 warnx("%s: option %s not found", __func__, 7646 optarg); 7647 usage(0); 7648 retval = 1; 7649 goto bailout; 7650 } 7651 break; 7652 } 7653 case 'p': 7654 phy = atoi(optarg); 7655 break; 7656 case 'T': 7657 pp_timeout_val = strtoul(optarg, NULL, 0); 7658 if (pp_timeout_val > 15) { 7659 warnx("%s: invalid partial pathway timeout " 7660 "value %u, need a value less than 16", 7661 __func__, pp_timeout_val); 7662 retval = 1; 7663 goto bailout; 7664 } 7665 set_pp_timeout_val = 1; 7666 break; 7667 default: 7668 break; 7669 } 7670 } 7671 7672 if (phy == -1) { 7673 warnx("%s: a PHY (-p phy) argument is required",__func__); 7674 retval = 1; 7675 goto bailout; 7676 } 7677 7678 if (((dev_name_set != 0) 7679 && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME)) 7680 || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME) 7681 && (dev_name_set == 0))) { 7682 warnx("%s: -d name and -o setdevname arguments both " 7683 "required to set device name", __func__); 7684 retval = 1; 7685 goto bailout; 7686 } 7687 7688 request = malloc(sizeof(*request)); 7689 if (request == NULL) { 7690 warn("%s: unable to allocate %zd bytes", __func__, 7691 sizeof(*request)); 7692 retval = 1; 7693 goto bailout; 7694 } 7695 7696 response = malloc(sizeof(*response)); 7697 if (response == NULL) { 7698 warn("%s: unable to allocate %zd bytes", __func__, 7699 sizeof(*response)); 7700 retval = 1; 7701 goto bailout; 7702 } 7703 7704 smp_phy_control(&ccb->smpio, 7705 retry_count, 7706 /*cbfcnp*/ NULL, 7707 request, 7708 sizeof(*request), 7709 (uint8_t *)response, 7710 sizeof(*response), 7711 long_response, 7712 /*expected_exp_change_count*/ 0, 7713 phy, 7714 phy_operation, 7715 (set_pp_timeout_val != 0) ? 1 : 0, 7716 attached_dev_name, 7717 min_plr, 7718 max_plr, 7719 slumber_partial, 7720 pp_timeout_val, 7721 timeout); 7722 7723 if (((retval = cam_send_ccb(device, ccb)) < 0) 7724 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7725 const char warnstr[] = "error sending command"; 7726 7727 if (retval < 0) 7728 warn(warnstr); 7729 else 7730 warnx(warnstr); 7731 7732 if (arglist & CAM_ARG_VERBOSE) { 7733 /* 7734 * Use CAM_EPF_NORMAL so we only get one line of 7735 * SMP command decoding. 7736 */ 7737 cam_error_print(device, ccb, CAM_ESF_ALL, 7738 CAM_EPF_NORMAL, stderr); 7739 } 7740 retval = 1; 7741 goto bailout; 7742 } 7743 7744 /* XXX KDM print out something here for success? */ 7745bailout: 7746 if (ccb != NULL) 7747 cam_freeccb(ccb); 7748 7749 if (request != NULL) 7750 free(request); 7751 7752 if (response != NULL) 7753 free(response); 7754 7755 return (retval); 7756} 7757 7758static int 7759smpmaninfo(struct cam_device *device, int argc, char **argv, 7760 char *combinedopt, int retry_count, int timeout) 7761{ 7762 union ccb *ccb; 7763 struct smp_report_manuf_info_request request; 7764 struct smp_report_manuf_info_response response; 7765 struct sbuf *sb = NULL; 7766 int long_response = 0; 7767 int retval = 0; 7768 int c; 7769 7770 /* 7771 * Note that at the moment we don't support sending SMP CCBs to 7772 * devices that aren't probed by CAM. 7773 */ 7774 ccb = cam_getccb(device); 7775 if (ccb == NULL) { 7776 warnx("%s: error allocating CCB", __func__); 7777 return (1); 7778 } 7779 7780 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 7781 7782 while ((c = getopt(argc, argv, combinedopt)) != -1) { 7783 switch (c) { 7784 case 'l': 7785 long_response = 1; 7786 break; 7787 default: 7788 break; 7789 } 7790 } 7791 bzero(&request, sizeof(request)); 7792 bzero(&response, sizeof(response)); 7793 7794 smp_report_manuf_info(&ccb->smpio, 7795 retry_count, 7796 /*cbfcnp*/ NULL, 7797 &request, 7798 sizeof(request), 7799 (uint8_t *)&response, 7800 sizeof(response), 7801 long_response, 7802 timeout); 7803 7804 if (((retval = cam_send_ccb(device, ccb)) < 0) 7805 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 7806 const char warnstr[] = "error sending command"; 7807 7808 if (retval < 0) 7809 warn(warnstr); 7810 else 7811 warnx(warnstr); 7812 7813 if (arglist & CAM_ARG_VERBOSE) { 7814 cam_error_print(device, ccb, CAM_ESF_ALL, 7815 CAM_EPF_ALL, stderr); 7816 } 7817 retval = 1; 7818 goto bailout; 7819 } 7820 7821 sb = sbuf_new_auto(); 7822 if (sb == NULL) { 7823 warnx("%s: error allocating sbuf", __func__); 7824 goto bailout; 7825 } 7826 7827 smp_report_manuf_info_sbuf(&response, sizeof(response), sb); 7828 7829 if (sbuf_finish(sb) != 0) { 7830 warnx("%s: sbuf_finish", __func__); 7831 goto bailout; 7832 } 7833 7834 printf("%s", sbuf_data(sb)); 7835 7836bailout: 7837 7838 if (ccb != NULL) 7839 cam_freeccb(ccb); 7840 7841 if (sb != NULL) 7842 sbuf_delete(sb); 7843 7844 return (retval); 7845} 7846 7847static int 7848getdevid(struct cam_devitem *item) 7849{ 7850 int retval = 0; 7851 union ccb *ccb = NULL; 7852 7853 struct cam_device *dev; 7854 7855 dev = cam_open_btl(item->dev_match.path_id, 7856 item->dev_match.target_id, 7857 item->dev_match.target_lun, O_RDWR, NULL); 7858 7859 if (dev == NULL) { 7860 warnx("%s", cam_errbuf); 7861 retval = 1; 7862 goto bailout; 7863 } 7864 7865 item->device_id_len = 0; 7866 7867 ccb = cam_getccb(dev); 7868 if (ccb == NULL) { 7869 warnx("%s: error allocating CCB", __func__); 7870 retval = 1; 7871 goto bailout; 7872 } 7873 7874 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai); 7875 7876 /* 7877 * On the first try, we just probe for the size of the data, and 7878 * then allocate that much memory and try again. 7879 */ 7880retry: 7881 ccb->ccb_h.func_code = XPT_DEV_ADVINFO; 7882 ccb->ccb_h.flags = CAM_DIR_IN; 7883 ccb->cdai.flags = CDAI_FLAG_NONE; 7884 ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID; 7885 ccb->cdai.bufsiz = item->device_id_len; 7886 if (item->device_id_len != 0) 7887 ccb->cdai.buf = (uint8_t *)item->device_id; 7888 7889 if (cam_send_ccb(dev, ccb) < 0) { 7890 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__); 7891 retval = 1; 7892 goto bailout; 7893 } 7894 7895 if (ccb->ccb_h.status != CAM_REQ_CMP) { 7896 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status); 7897 retval = 1; 7898 goto bailout; 7899 } 7900 7901 if (item->device_id_len == 0) { 7902 /* 7903 * This is our first time through. Allocate the buffer, 7904 * and then go back to get the data. 7905 */ 7906 if (ccb->cdai.provsiz == 0) { 7907 warnx("%s: invalid .provsiz field returned with " 7908 "XPT_GDEV_ADVINFO CCB", __func__); 7909 retval = 1; 7910 goto bailout; 7911 } 7912 item->device_id_len = ccb->cdai.provsiz; 7913 item->device_id = malloc(item->device_id_len); 7914 if (item->device_id == NULL) { 7915 warn("%s: unable to allocate %d bytes", __func__, 7916 item->device_id_len); 7917 retval = 1; 7918 goto bailout; 7919 } 7920 ccb->ccb_h.status = CAM_REQ_INPROG; 7921 goto retry; 7922 } 7923 7924bailout: 7925 if (dev != NULL) 7926 cam_close_device(dev); 7927 7928 if (ccb != NULL) 7929 cam_freeccb(ccb); 7930 7931 return (retval); 7932} 7933 7934/* 7935 * XXX KDM merge this code with getdevtree()? 7936 */ 7937static int 7938buildbusdevlist(struct cam_devlist *devlist) 7939{ 7940 union ccb ccb; 7941 int bufsize, fd = -1; 7942 struct dev_match_pattern *patterns; 7943 struct cam_devitem *item = NULL; 7944 int skip_device = 0; 7945 int retval = 0; 7946 7947 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { 7948 warn("couldn't open %s", XPT_DEVICE); 7949 return (1); 7950 } 7951 7952 bzero(&ccb, sizeof(union ccb)); 7953 7954 ccb.ccb_h.path_id = CAM_XPT_PATH_ID; 7955 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; 7956 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; 7957 7958 ccb.ccb_h.func_code = XPT_DEV_MATCH; 7959 bufsize = sizeof(struct dev_match_result) * 100; 7960 ccb.cdm.match_buf_len = bufsize; 7961 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); 7962 if (ccb.cdm.matches == NULL) { 7963 warnx("can't malloc memory for matches"); 7964 close(fd); 7965 return (1); 7966 } 7967 ccb.cdm.num_matches = 0; 7968 ccb.cdm.num_patterns = 2; 7969 ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) * 7970 ccb.cdm.num_patterns; 7971 7972 patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len); 7973 if (patterns == NULL) { 7974 warnx("can't malloc memory for patterns"); 7975 retval = 1; 7976 goto bailout; 7977 } 7978 7979 ccb.cdm.patterns = patterns; 7980 bzero(patterns, ccb.cdm.pattern_buf_len); 7981 7982 patterns[0].type = DEV_MATCH_DEVICE; 7983 patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH; 7984 patterns[0].pattern.device_pattern.path_id = devlist->path_id; 7985 patterns[1].type = DEV_MATCH_PERIPH; 7986 patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH; 7987 patterns[1].pattern.periph_pattern.path_id = devlist->path_id; 7988 7989 /* 7990 * We do the ioctl multiple times if necessary, in case there are 7991 * more than 100 nodes in the EDT. 7992 */ 7993 do { 7994 unsigned int i; 7995 7996 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { 7997 warn("error sending CAMIOCOMMAND ioctl"); 7998 retval = 1; 7999 goto bailout; 8000 } 8001 8002 if ((ccb.ccb_h.status != CAM_REQ_CMP) 8003 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) 8004 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { 8005 warnx("got CAM error %#x, CDM error %d\n", 8006 ccb.ccb_h.status, ccb.cdm.status); 8007 retval = 1; 8008 goto bailout; 8009 } 8010 8011 for (i = 0; i < ccb.cdm.num_matches; i++) { 8012 switch (ccb.cdm.matches[i].type) { 8013 case DEV_MATCH_DEVICE: { 8014 struct device_match_result *dev_result; 8015 8016 dev_result = 8017 &ccb.cdm.matches[i].result.device_result; 8018 8019 if (dev_result->flags & 8020 DEV_RESULT_UNCONFIGURED) { 8021 skip_device = 1; 8022 break; 8023 } else 8024 skip_device = 0; 8025 8026 item = malloc(sizeof(*item)); 8027 if (item == NULL) { 8028 warn("%s: unable to allocate %zd bytes", 8029 __func__, sizeof(*item)); 8030 retval = 1; 8031 goto bailout; 8032 } 8033 bzero(item, sizeof(*item)); 8034 bcopy(dev_result, &item->dev_match, 8035 sizeof(*dev_result)); 8036 STAILQ_INSERT_TAIL(&devlist->dev_queue, item, 8037 links); 8038 8039 if (getdevid(item) != 0) { 8040 retval = 1; 8041 goto bailout; 8042 } 8043 break; 8044 } 8045 case DEV_MATCH_PERIPH: { 8046 struct periph_match_result *periph_result; 8047 8048 periph_result = 8049 &ccb.cdm.matches[i].result.periph_result; 8050 8051 if (skip_device != 0) 8052 break; 8053 item->num_periphs++; 8054 item->periph_matches = realloc( 8055 item->periph_matches, 8056 item->num_periphs * 8057 sizeof(struct periph_match_result)); 8058 if (item->periph_matches == NULL) { 8059 warn("%s: error allocating periph " 8060 "list", __func__); 8061 retval = 1; 8062 goto bailout; 8063 } 8064 bcopy(periph_result, &item->periph_matches[ 8065 item->num_periphs - 1], 8066 sizeof(*periph_result)); 8067 break; 8068 } 8069 default: 8070 fprintf(stderr, "%s: unexpected match " 8071 "type %d\n", __func__, 8072 ccb.cdm.matches[i].type); 8073 retval = 1; 8074 goto bailout; 8075 break; /*NOTREACHED*/ 8076 } 8077 } 8078 } while ((ccb.ccb_h.status == CAM_REQ_CMP) 8079 && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); 8080bailout: 8081 8082 if (fd != -1) 8083 close(fd); 8084 8085 free(patterns); 8086 8087 free(ccb.cdm.matches); 8088 8089 if (retval != 0) 8090 freebusdevlist(devlist); 8091 8092 return (retval); 8093} 8094 8095static void 8096freebusdevlist(struct cam_devlist *devlist) 8097{ 8098 struct cam_devitem *item, *item2; 8099 8100 STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) { 8101 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem, 8102 links); 8103 free(item->device_id); 8104 free(item->periph_matches); 8105 free(item); 8106 } 8107} 8108 8109static struct cam_devitem * 8110findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr) 8111{ 8112 struct cam_devitem *item; 8113 8114 STAILQ_FOREACH(item, &devlist->dev_queue, links) { 8115 struct scsi_vpd_id_descriptor *idd; 8116 8117 /* 8118 * XXX KDM look for LUN IDs as well? 8119 */ 8120 idd = scsi_get_devid(item->device_id, 8121 item->device_id_len, 8122 scsi_devid_is_sas_target); 8123 if (idd == NULL) 8124 continue; 8125 8126 if (scsi_8btou64(idd->identifier) == sasaddr) 8127 return (item); 8128 } 8129 8130 return (NULL); 8131} 8132 8133static int 8134smpphylist(struct cam_device *device, int argc, char **argv, 8135 char *combinedopt, int retry_count, int timeout) 8136{ 8137 struct smp_report_general_request *rgrequest = NULL; 8138 struct smp_report_general_response *rgresponse = NULL; 8139 struct smp_discover_request *disrequest = NULL; 8140 struct smp_discover_response *disresponse = NULL; 8141 struct cam_devlist devlist; 8142 union ccb *ccb; 8143 int long_response = 0; 8144 int num_phys = 0; 8145 int quiet = 0; 8146 int retval; 8147 int i, c; 8148 8149 /* 8150 * Note that at the moment we don't support sending SMP CCBs to 8151 * devices that aren't probed by CAM. 8152 */ 8153 ccb = cam_getccb(device); 8154 if (ccb == NULL) { 8155 warnx("%s: error allocating CCB", __func__); 8156 return (1); 8157 } 8158 8159 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 8160 STAILQ_INIT(&devlist.dev_queue); 8161 8162 rgrequest = malloc(sizeof(*rgrequest)); 8163 if (rgrequest == NULL) { 8164 warn("%s: unable to allocate %zd bytes", __func__, 8165 sizeof(*rgrequest)); 8166 retval = 1; 8167 goto bailout; 8168 } 8169 8170 rgresponse = malloc(sizeof(*rgresponse)); 8171 if (rgresponse == NULL) { 8172 warn("%s: unable to allocate %zd bytes", __func__, 8173 sizeof(*rgresponse)); 8174 retval = 1; 8175 goto bailout; 8176 } 8177 8178 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8179 switch (c) { 8180 case 'l': 8181 long_response = 1; 8182 break; 8183 case 'q': 8184 quiet = 1; 8185 break; 8186 default: 8187 break; 8188 } 8189 } 8190 8191 smp_report_general(&ccb->smpio, 8192 retry_count, 8193 /*cbfcnp*/ NULL, 8194 rgrequest, 8195 /*request_len*/ sizeof(*rgrequest), 8196 (uint8_t *)rgresponse, 8197 /*response_len*/ sizeof(*rgresponse), 8198 /*long_response*/ long_response, 8199 timeout); 8200 8201 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 8202 8203 if (((retval = cam_send_ccb(device, ccb)) < 0) 8204 || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { 8205 const char warnstr[] = "error sending command"; 8206 8207 if (retval < 0) 8208 warn(warnstr); 8209 else 8210 warnx(warnstr); 8211 8212 if (arglist & CAM_ARG_VERBOSE) { 8213 cam_error_print(device, ccb, CAM_ESF_ALL, 8214 CAM_EPF_ALL, stderr); 8215 } 8216 retval = 1; 8217 goto bailout; 8218 } 8219 8220 num_phys = rgresponse->num_phys; 8221 8222 if (num_phys == 0) { 8223 if (quiet == 0) 8224 fprintf(stdout, "%s: No Phys reported\n", __func__); 8225 retval = 1; 8226 goto bailout; 8227 } 8228 8229 devlist.path_id = device->path_id; 8230 8231 retval = buildbusdevlist(&devlist); 8232 if (retval != 0) 8233 goto bailout; 8234 8235 if (quiet == 0) { 8236 fprintf(stdout, "%d PHYs:\n", num_phys); 8237 fprintf(stdout, "PHY Attached SAS Address\n"); 8238 } 8239 8240 disrequest = malloc(sizeof(*disrequest)); 8241 if (disrequest == NULL) { 8242 warn("%s: unable to allocate %zd bytes", __func__, 8243 sizeof(*disrequest)); 8244 retval = 1; 8245 goto bailout; 8246 } 8247 8248 disresponse = malloc(sizeof(*disresponse)); 8249 if (disresponse == NULL) { 8250 warn("%s: unable to allocate %zd bytes", __func__, 8251 sizeof(*disresponse)); 8252 retval = 1; 8253 goto bailout; 8254 } 8255 8256 for (i = 0; i < num_phys; i++) { 8257 struct cam_devitem *item; 8258 struct device_match_result *dev_match; 8259 char vendor[16], product[48], revision[16]; 8260 char tmpstr[256]; 8261 int j; 8262 8263 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); 8264 8265 ccb->ccb_h.status = CAM_REQ_INPROG; 8266 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 8267 8268 smp_discover(&ccb->smpio, 8269 retry_count, 8270 /*cbfcnp*/ NULL, 8271 disrequest, 8272 sizeof(*disrequest), 8273 (uint8_t *)disresponse, 8274 sizeof(*disresponse), 8275 long_response, 8276 /*ignore_zone_group*/ 0, 8277 /*phy*/ i, 8278 timeout); 8279 8280 if (((retval = cam_send_ccb(device, ccb)) < 0) 8281 || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) 8282 && (disresponse->function_result != SMP_FR_PHY_VACANT))) { 8283 const char warnstr[] = "error sending command"; 8284 8285 if (retval < 0) 8286 warn(warnstr); 8287 else 8288 warnx(warnstr); 8289 8290 if (arglist & CAM_ARG_VERBOSE) { 8291 cam_error_print(device, ccb, CAM_ESF_ALL, 8292 CAM_EPF_ALL, stderr); 8293 } 8294 retval = 1; 8295 goto bailout; 8296 } 8297 8298 if (disresponse->function_result == SMP_FR_PHY_VACANT) { 8299 if (quiet == 0) 8300 fprintf(stdout, "%3d <vacant>\n", i); 8301 continue; 8302 } 8303 8304 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) { 8305 item = NULL; 8306 } else { 8307 item = findsasdevice(&devlist, 8308 scsi_8btou64(disresponse->attached_sas_address)); 8309 } 8310 8311 if ((quiet == 0) 8312 || (item != NULL)) { 8313 fprintf(stdout, "%3d 0x%016jx", i, 8314 (uintmax_t)scsi_8btou64( 8315 disresponse->attached_sas_address)); 8316 if (item == NULL) { 8317 fprintf(stdout, "\n"); 8318 continue; 8319 } 8320 } else if (quiet != 0) 8321 continue; 8322 8323 dev_match = &item->dev_match; 8324 8325 if (dev_match->protocol == PROTO_SCSI) { 8326 cam_strvis(vendor, dev_match->inq_data.vendor, 8327 sizeof(dev_match->inq_data.vendor), 8328 sizeof(vendor)); 8329 cam_strvis(product, dev_match->inq_data.product, 8330 sizeof(dev_match->inq_data.product), 8331 sizeof(product)); 8332 cam_strvis(revision, dev_match->inq_data.revision, 8333 sizeof(dev_match->inq_data.revision), 8334 sizeof(revision)); 8335 sprintf(tmpstr, "<%s %s %s>", vendor, product, 8336 revision); 8337 } else if ((dev_match->protocol == PROTO_ATA) 8338 || (dev_match->protocol == PROTO_SATAPM)) { 8339 cam_strvis(product, dev_match->ident_data.model, 8340 sizeof(dev_match->ident_data.model), 8341 sizeof(product)); 8342 cam_strvis(revision, dev_match->ident_data.revision, 8343 sizeof(dev_match->ident_data.revision), 8344 sizeof(revision)); 8345 sprintf(tmpstr, "<%s %s>", product, revision); 8346 } else { 8347 sprintf(tmpstr, "<>"); 8348 } 8349 fprintf(stdout, " %-33s ", tmpstr); 8350 8351 /* 8352 * If we have 0 periphs, that's a bug... 8353 */ 8354 if (item->num_periphs == 0) { 8355 fprintf(stdout, "\n"); 8356 continue; 8357 } 8358 8359 fprintf(stdout, "("); 8360 for (j = 0; j < item->num_periphs; j++) { 8361 if (j > 0) 8362 fprintf(stdout, ","); 8363 8364 fprintf(stdout, "%s%d", 8365 item->periph_matches[j].periph_name, 8366 item->periph_matches[j].unit_number); 8367 8368 } 8369 fprintf(stdout, ")\n"); 8370 } 8371bailout: 8372 if (ccb != NULL) 8373 cam_freeccb(ccb); 8374 8375 free(rgrequest); 8376 8377 free(rgresponse); 8378 8379 free(disrequest); 8380 8381 free(disresponse); 8382 8383 freebusdevlist(&devlist); 8384 8385 return (retval); 8386} 8387 8388static int 8389atapm_proc_resp(struct cam_device *device, union ccb *ccb) 8390{ 8391 struct ata_res *res; 8392 8393 res = &ccb->ataio.res; 8394 if (res->status & ATA_STATUS_ERROR) { 8395 if (arglist & CAM_ARG_VERBOSE) { 8396 cam_error_print(device, ccb, CAM_ESF_ALL, 8397 CAM_EPF_ALL, stderr); 8398 printf("error = 0x%02x, sector_count = 0x%04x, " 8399 "device = 0x%02x, status = 0x%02x\n", 8400 res->error, res->sector_count, 8401 res->device, res->status); 8402 } 8403 8404 return (1); 8405 } 8406 8407 if (arglist & CAM_ARG_VERBOSE) { 8408 fprintf(stdout, "%s%d: Raw native check power data:\n", 8409 device->device_name, device->dev_unit_num); 8410 /* res is 4 byte aligned */ 8411 dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res)); 8412 8413 printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, " 8414 "status = 0x%02x\n", res->error, res->sector_count, 8415 res->device, res->status); 8416 } 8417 8418 printf("%s%d: ", device->device_name, device->dev_unit_num); 8419 switch (res->sector_count) { 8420 case 0x00: 8421 printf("Standby mode\n"); 8422 break; 8423 case 0x40: 8424 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n"); 8425 break; 8426 case 0x41: 8427 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n"); 8428 break; 8429 case 0x80: 8430 printf("Idle mode\n"); 8431 break; 8432 case 0xff: 8433 printf("Active or Idle mode\n"); 8434 break; 8435 default: 8436 printf("Unknown mode 0x%02x\n", res->sector_count); 8437 break; 8438 } 8439 8440 return (0); 8441} 8442 8443static int 8444atapm(struct cam_device *device, int argc, char **argv, 8445 char *combinedopt, int retry_count, int timeout) 8446{ 8447 union ccb *ccb; 8448 int retval = 0; 8449 int t = -1; 8450 int c; 8451 u_int8_t ata_flags = 0; 8452 u_char cmd, sc; 8453 8454 ccb = cam_getccb(device); 8455 8456 if (ccb == NULL) { 8457 warnx("%s: error allocating ccb", __func__); 8458 return (1); 8459 } 8460 8461 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8462 switch (c) { 8463 case 't': 8464 t = atoi(optarg); 8465 break; 8466 default: 8467 break; 8468 } 8469 } 8470 if (strcmp(argv[1], "idle") == 0) { 8471 if (t == -1) 8472 cmd = ATA_IDLE_IMMEDIATE; 8473 else 8474 cmd = ATA_IDLE_CMD; 8475 } else if (strcmp(argv[1], "standby") == 0) { 8476 if (t == -1) 8477 cmd = ATA_STANDBY_IMMEDIATE; 8478 else 8479 cmd = ATA_STANDBY_CMD; 8480 } else if (strcmp(argv[1], "powermode") == 0) { 8481 cmd = ATA_CHECK_POWER_MODE; 8482 ata_flags = AP_FLAG_CHK_COND; 8483 t = -1; 8484 } else { 8485 cmd = ATA_SLEEP; 8486 t = -1; 8487 } 8488 8489 if (t < 0) 8490 sc = 0; 8491 else if (t <= (240 * 5)) 8492 sc = (t + 4) / 5; 8493 else if (t <= (252 * 5)) 8494 /* special encoding for 21 minutes */ 8495 sc = 252; 8496 else if (t <= (11 * 30 * 60)) 8497 sc = (t - 1) / (30 * 60) + 241; 8498 else 8499 sc = 253; 8500 8501 retval = ata_do_cmd(device, 8502 ccb, 8503 /*retries*/retry_count, 8504 /*flags*/CAM_DIR_NONE, 8505 /*protocol*/AP_PROTO_NON_DATA, 8506 /*ata_flags*/ata_flags, 8507 /*tag_action*/MSG_SIMPLE_Q_TAG, 8508 /*command*/cmd, 8509 /*features*/0, 8510 /*lba*/0, 8511 /*sector_count*/sc, 8512 /*data_ptr*/NULL, 8513 /*dxfer_len*/0, 8514 /*timeout*/timeout ? timeout : 30 * 1000, 8515 /*quiet*/1); 8516 8517 cam_freeccb(ccb); 8518 8519 if (retval || cmd != ATA_CHECK_POWER_MODE) 8520 return (retval); 8521 8522 return (atapm_proc_resp(device, ccb)); 8523} 8524 8525static int 8526ataaxm(struct cam_device *device, int argc, char **argv, 8527 char *combinedopt, int retry_count, int timeout) 8528{ 8529 union ccb *ccb; 8530 int retval = 0; 8531 int l = -1; 8532 int c; 8533 u_char cmd, sc; 8534 8535 ccb = cam_getccb(device); 8536 8537 if (ccb == NULL) { 8538 warnx("%s: error allocating ccb", __func__); 8539 return (1); 8540 } 8541 8542 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8543 switch (c) { 8544 case 'l': 8545 l = atoi(optarg); 8546 break; 8547 default: 8548 break; 8549 } 8550 } 8551 sc = 0; 8552 if (strcmp(argv[1], "apm") == 0) { 8553 if (l == -1) 8554 cmd = 0x85; 8555 else { 8556 cmd = 0x05; 8557 sc = l; 8558 } 8559 } else /* aam */ { 8560 if (l == -1) 8561 cmd = 0xC2; 8562 else { 8563 cmd = 0x42; 8564 sc = l; 8565 } 8566 } 8567 8568 retval = ata_do_28bit_cmd(device, 8569 ccb, 8570 /*retries*/retry_count, 8571 /*flags*/CAM_DIR_NONE, 8572 /*protocol*/AP_PROTO_NON_DATA, 8573 /*tag_action*/MSG_SIMPLE_Q_TAG, 8574 /*command*/ATA_SETFEATURES, 8575 /*features*/cmd, 8576 /*lba*/0, 8577 /*sector_count*/sc, 8578 /*data_ptr*/NULL, 8579 /*dxfer_len*/0, 8580 /*timeout*/timeout ? timeout : 30 * 1000, 8581 /*quiet*/1); 8582 8583 cam_freeccb(ccb); 8584 return (retval); 8585} 8586 8587int 8588scsigetopcodes(struct cam_device *device, int opcode_set, int opcode, 8589 int show_sa_errors, int sa_set, int service_action, 8590 int timeout_desc, int task_attr, int retry_count, int timeout, 8591 int verbosemode, uint32_t *fill_len, uint8_t **data_ptr) 8592{ 8593 union ccb *ccb = NULL; 8594 uint8_t *buf = NULL; 8595 uint32_t alloc_len = 0, num_opcodes; 8596 uint32_t valid_len = 0; 8597 uint32_t avail_len = 0; 8598 struct scsi_report_supported_opcodes_all *all_hdr; 8599 struct scsi_report_supported_opcodes_one *one; 8600 int options = 0; 8601 int retval = 0; 8602 8603 /* 8604 * Make it clear that we haven't yet allocated or filled anything. 8605 */ 8606 *fill_len = 0; 8607 *data_ptr = NULL; 8608 8609 ccb = cam_getccb(device); 8610 if (ccb == NULL) { 8611 warnx("couldn't allocate CCB"); 8612 retval = 1; 8613 goto bailout; 8614 } 8615 8616 /* cam_getccb cleans up the header, caller has to zero the payload */ 8617 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 8618 8619 if (opcode_set != 0) { 8620 options |= RSO_OPTIONS_OC; 8621 num_opcodes = 1; 8622 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN; 8623 } else { 8624 num_opcodes = 256; 8625 alloc_len = sizeof(*all_hdr) + (num_opcodes * 8626 sizeof(struct scsi_report_supported_opcodes_descr)); 8627 } 8628 8629 if (timeout_desc != 0) { 8630 options |= RSO_RCTD; 8631 alloc_len += num_opcodes * 8632 sizeof(struct scsi_report_supported_opcodes_timeout); 8633 } 8634 8635 if (sa_set != 0) { 8636 options |= RSO_OPTIONS_OC_SA; 8637 if (show_sa_errors != 0) 8638 options &= ~RSO_OPTIONS_OC; 8639 } 8640 8641retry_alloc: 8642 if (buf != NULL) { 8643 free(buf); 8644 buf = NULL; 8645 } 8646 8647 buf = malloc(alloc_len); 8648 if (buf == NULL) { 8649 warn("Unable to allocate %u bytes", alloc_len); 8650 retval = 1; 8651 goto bailout; 8652 } 8653 bzero(buf, alloc_len); 8654 8655 scsi_report_supported_opcodes(&ccb->csio, 8656 /*retries*/ retry_count, 8657 /*cbfcnp*/ NULL, 8658 /*tag_action*/ task_attr, 8659 /*options*/ options, 8660 /*req_opcode*/ opcode, 8661 /*req_service_action*/ service_action, 8662 /*data_ptr*/ buf, 8663 /*dxfer_len*/ alloc_len, 8664 /*sense_len*/ SSD_FULL_SIZE, 8665 /*timeout*/ timeout ? timeout : 10000); 8666 8667 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; 8668 8669 if (retry_count != 0) 8670 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; 8671 8672 if (cam_send_ccb(device, ccb) < 0) { 8673 perror("error sending REPORT SUPPORTED OPERATION CODES"); 8674 retval = 1; 8675 goto bailout; 8676 } 8677 8678 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 8679 if (verbosemode != 0) 8680 cam_error_print(device, ccb, CAM_ESF_ALL, 8681 CAM_EPF_ALL, stderr); 8682 retval = 1; 8683 goto bailout; 8684 } 8685 8686 valid_len = ccb->csio.dxfer_len - ccb->csio.resid; 8687 8688 if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL) 8689 && (valid_len >= sizeof(*all_hdr))) { 8690 all_hdr = (struct scsi_report_supported_opcodes_all *)buf; 8691 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr); 8692 } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL) 8693 && (valid_len >= sizeof(*one))) { 8694 uint32_t cdb_length; 8695 8696 one = (struct scsi_report_supported_opcodes_one *)buf; 8697 cdb_length = scsi_2btoul(one->cdb_length); 8698 avail_len = sizeof(*one) + cdb_length; 8699 if (one->support & RSO_ONE_CTDP) { 8700 struct scsi_report_supported_opcodes_timeout *td; 8701 8702 td = (struct scsi_report_supported_opcodes_timeout *) 8703 &buf[avail_len]; 8704 if (valid_len >= (avail_len + sizeof(td->length))) { 8705 avail_len += scsi_2btoul(td->length) + 8706 sizeof(td->length); 8707 } else { 8708 avail_len += sizeof(*td); 8709 } 8710 } 8711 } 8712 8713 /* 8714 * avail_len could be zero if we didn't get enough data back from 8715 * thet target to determine 8716 */ 8717 if ((avail_len != 0) 8718 && (avail_len > valid_len)) { 8719 alloc_len = avail_len; 8720 goto retry_alloc; 8721 } 8722 8723 *fill_len = valid_len; 8724 *data_ptr = buf; 8725bailout: 8726 if (retval != 0) 8727 free(buf); 8728 8729 cam_freeccb(ccb); 8730 8731 return (retval); 8732} 8733 8734static int 8735scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set, 8736 int req_sa, uint8_t *buf, uint32_t valid_len) 8737{ 8738 struct scsi_report_supported_opcodes_one *one; 8739 struct scsi_report_supported_opcodes_timeout *td; 8740 uint32_t cdb_len = 0, td_len = 0; 8741 const char *op_desc = NULL; 8742 unsigned int i; 8743 int retval = 0; 8744 8745 one = (struct scsi_report_supported_opcodes_one *)buf; 8746 8747 /* 8748 * If we don't have the full single opcode descriptor, no point in 8749 * continuing. 8750 */ 8751 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one, 8752 cdb_length)) { 8753 warnx("Only %u bytes returned, not enough to verify support", 8754 valid_len); 8755 retval = 1; 8756 goto bailout; 8757 } 8758 8759 op_desc = scsi_op_desc(req_opcode, &device->inq_data); 8760 8761 printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN", 8762 req_opcode); 8763 if (sa_set != 0) 8764 printf(", SA 0x%x", req_sa); 8765 printf(": "); 8766 8767 switch (one->support & RSO_ONE_SUP_MASK) { 8768 case RSO_ONE_SUP_UNAVAIL: 8769 printf("No command support information currently available\n"); 8770 break; 8771 case RSO_ONE_SUP_NOT_SUP: 8772 printf("Command not supported\n"); 8773 retval = 1; 8774 goto bailout; 8775 break; /*NOTREACHED*/ 8776 case RSO_ONE_SUP_AVAIL: 8777 printf("Command is supported, complies with a SCSI standard\n"); 8778 break; 8779 case RSO_ONE_SUP_VENDOR: 8780 printf("Command is supported, vendor-specific " 8781 "implementation\n"); 8782 break; 8783 default: 8784 printf("Unknown command support flags 0x%#x\n", 8785 one->support & RSO_ONE_SUP_MASK); 8786 break; 8787 } 8788 8789 /* 8790 * If we don't have the CDB length, it isn't exactly an error, the 8791 * command probably isn't supported. 8792 */ 8793 if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one, 8794 cdb_usage)) 8795 goto bailout; 8796 8797 cdb_len = scsi_2btoul(one->cdb_length); 8798 8799 /* 8800 * If our valid data doesn't include the full reported length, 8801 * return. The caller should have detected this and adjusted his 8802 * allocation length to get all of the available data. 8803 */ 8804 if (valid_len < sizeof(*one) + cdb_len) { 8805 retval = 1; 8806 goto bailout; 8807 } 8808 8809 /* 8810 * If all we have is the opcode, there is no point in printing out 8811 * the usage bitmap. 8812 */ 8813 if (cdb_len <= 1) { 8814 retval = 1; 8815 goto bailout; 8816 } 8817 8818 printf("CDB usage bitmap:"); 8819 for (i = 0; i < cdb_len; i++) { 8820 printf(" %02x", one->cdb_usage[i]); 8821 } 8822 printf("\n"); 8823 8824 /* 8825 * If we don't have a timeout descriptor, we're done. 8826 */ 8827 if ((one->support & RSO_ONE_CTDP) == 0) 8828 goto bailout; 8829 8830 /* 8831 * If we don't have enough valid length to include the timeout 8832 * descriptor length, we're done. 8833 */ 8834 if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length))) 8835 goto bailout; 8836 8837 td = (struct scsi_report_supported_opcodes_timeout *) 8838 &buf[sizeof(*one) + cdb_len]; 8839 td_len = scsi_2btoul(td->length); 8840 td_len += sizeof(td->length); 8841 8842 /* 8843 * If we don't have the full timeout descriptor, we're done. 8844 */ 8845 if (td_len < sizeof(*td)) 8846 goto bailout; 8847 8848 /* 8849 * If we don't have enough valid length to contain the full timeout 8850 * descriptor, we're done. 8851 */ 8852 if (valid_len < (sizeof(*one) + cdb_len + td_len)) 8853 goto bailout; 8854 8855 printf("Timeout information:\n"); 8856 printf("Command-specific: 0x%02x\n", td->cmd_specific); 8857 printf("Nominal timeout: %u seconds\n", 8858 scsi_4btoul(td->nominal_time)); 8859 printf("Recommended timeout: %u seconds\n", 8860 scsi_4btoul(td->recommended_time)); 8861 8862bailout: 8863 return (retval); 8864} 8865 8866static int 8867scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf, 8868 uint32_t valid_len) 8869{ 8870 struct scsi_report_supported_opcodes_all *hdr; 8871 struct scsi_report_supported_opcodes_descr *desc; 8872 uint32_t avail_len = 0, used_len = 0; 8873 uint8_t *cur_ptr; 8874 int retval = 0; 8875 8876 if (valid_len < sizeof(*hdr)) { 8877 warnx("%s: not enough returned data (%u bytes) opcode list", 8878 __func__, valid_len); 8879 retval = 1; 8880 goto bailout; 8881 } 8882 hdr = (struct scsi_report_supported_opcodes_all *)buf; 8883 avail_len = scsi_4btoul(hdr->length); 8884 avail_len += sizeof(hdr->length); 8885 /* 8886 * Take the lesser of the amount of data the drive claims is 8887 * available, and the amount of data the HBA says was returned. 8888 */ 8889 avail_len = MIN(avail_len, valid_len); 8890 8891 used_len = sizeof(hdr->length); 8892 8893 printf("%-6s %4s %8s ", 8894 "Opcode", "SA", "CDB len" ); 8895 8896 if (td_req != 0) 8897 printf("%5s %6s %6s ", "CS", "Nom", "Rec"); 8898 printf(" Description\n"); 8899 8900 while ((avail_len - used_len) > sizeof(*desc)) { 8901 struct scsi_report_supported_opcodes_timeout *td; 8902 uint32_t td_len; 8903 const char *op_desc = NULL; 8904 8905 cur_ptr = &buf[used_len]; 8906 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr; 8907 8908 op_desc = scsi_op_desc(desc->opcode, &device->inq_data); 8909 if (op_desc == NULL) 8910 op_desc = "UNKNOWN"; 8911 8912 printf("0x%02x %#4x %8u ", desc->opcode, 8913 scsi_2btoul(desc->service_action), 8914 scsi_2btoul(desc->cdb_length)); 8915 8916 used_len += sizeof(*desc); 8917 8918 if ((desc->flags & RSO_CTDP) == 0) { 8919 printf(" %s\n", op_desc); 8920 continue; 8921 } 8922 8923 /* 8924 * If we don't have enough space to fit a timeout 8925 * descriptor, then we're done. 8926 */ 8927 if (avail_len - used_len < sizeof(*td)) { 8928 used_len = avail_len; 8929 printf(" %s\n", op_desc); 8930 continue; 8931 } 8932 cur_ptr = &buf[used_len]; 8933 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr; 8934 td_len = scsi_2btoul(td->length); 8935 td_len += sizeof(td->length); 8936 8937 used_len += td_len; 8938 /* 8939 * If the given timeout descriptor length is less than what 8940 * we understand, skip it. 8941 */ 8942 if (td_len < sizeof(*td)) { 8943 printf(" %s\n", op_desc); 8944 continue; 8945 } 8946 8947 printf(" 0x%02x %6u %6u %s\n", td->cmd_specific, 8948 scsi_4btoul(td->nominal_time), 8949 scsi_4btoul(td->recommended_time), op_desc); 8950 } 8951bailout: 8952 return (retval); 8953} 8954 8955static int 8956scsiopcodes(struct cam_device *device, int argc, char **argv, 8957 char *combinedopt, int task_attr, int retry_count, int timeout, 8958 int verbosemode) 8959{ 8960 int c; 8961 uint32_t opcode = 0, service_action = 0; 8962 int td_set = 0, opcode_set = 0, sa_set = 0; 8963 int show_sa_errors = 1; 8964 uint32_t valid_len = 0; 8965 uint8_t *buf = NULL; 8966 char *endptr; 8967 int retval = 0; 8968 8969 while ((c = getopt(argc, argv, combinedopt)) != -1) { 8970 switch (c) { 8971 case 'N': 8972 show_sa_errors = 0; 8973 break; 8974 case 'o': 8975 opcode = strtoul(optarg, &endptr, 0); 8976 if (*endptr != '\0') { 8977 warnx("Invalid opcode \"%s\", must be a number", 8978 optarg); 8979 retval = 1; 8980 goto bailout; 8981 } 8982 if (opcode > 0xff) { 8983 warnx("Invalid opcode 0x%#x, must be between" 8984 "0 and 0xff inclusive", opcode); 8985 retval = 1; 8986 goto bailout; 8987 } 8988 opcode_set = 1; 8989 break; 8990 case 's': 8991 service_action = strtoul(optarg, &endptr, 0); 8992 if (*endptr != '\0') { 8993 warnx("Invalid service action \"%s\", must " 8994 "be a number", optarg); 8995 retval = 1; 8996 goto bailout; 8997 } 8998 if (service_action > 0xffff) { 8999 warnx("Invalid service action 0x%#x, must " 9000 "be between 0 and 0xffff inclusive", 9001 service_action); 9002 retval = 1; 9003 } 9004 sa_set = 1; 9005 break; 9006 case 'T': 9007 td_set = 1; 9008 break; 9009 default: 9010 break; 9011 } 9012 } 9013 9014 if ((sa_set != 0) 9015 && (opcode_set == 0)) { 9016 warnx("You must specify an opcode with -o if a service " 9017 "action is given"); 9018 retval = 1; 9019 goto bailout; 9020 } 9021 retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors, 9022 sa_set, service_action, td_set, task_attr, 9023 retry_count, timeout, verbosemode, &valid_len, 9024 &buf); 9025 if (retval != 0) 9026 goto bailout; 9027 9028 if ((opcode_set != 0) 9029 || (sa_set != 0)) { 9030 retval = scsiprintoneopcode(device, opcode, sa_set, 9031 service_action, buf, valid_len); 9032 } else { 9033 retval = scsiprintopcodes(device, td_set, buf, valid_len); 9034 } 9035 9036bailout: 9037 free(buf); 9038 9039 return (retval); 9040} 9041 9042#endif /* MINIMALISTIC */ 9043 9044static int 9045scsireprobe(struct cam_device *device) 9046{ 9047 union ccb *ccb; 9048 int retval = 0; 9049 9050 ccb = cam_getccb(device); 9051 9052 if (ccb == NULL) { 9053 warnx("%s: error allocating ccb", __func__); 9054 return (1); 9055 } 9056 9057 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); 9058 9059 ccb->ccb_h.func_code = XPT_REPROBE_LUN; 9060 9061 if (cam_send_ccb(device, ccb) < 0) { 9062 warn("error sending XPT_REPROBE_LUN CCB"); 9063 retval = 1; 9064 goto bailout; 9065 } 9066 9067 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 9068 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); 9069 retval = 1; 9070 goto bailout; 9071 } 9072 9073bailout: 9074 cam_freeccb(ccb); 9075 9076 return (retval); 9077} 9078 9079void 9080usage(int printlong) 9081{ 9082 9083 fprintf(printlong ? stdout : stderr, 9084"usage: camcontrol <command> [device id][generic args][command args]\n" 9085" camcontrol devlist [-b] [-v]\n" 9086#ifndef MINIMALISTIC 9087" camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n" 9088" camcontrol tur [dev_id][generic args]\n" 9089" camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n" 9090" camcontrol identify [dev_id][generic args] [-v]\n" 9091" camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n" 9092" camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n" 9093" [-q] [-s] [-l]\n" 9094" camcontrol start [dev_id][generic args]\n" 9095" camcontrol stop [dev_id][generic args]\n" 9096" camcontrol load [dev_id][generic args]\n" 9097" camcontrol eject [dev_id][generic args]\n" 9098" camcontrol reprobe [dev_id][generic args]\n" 9099#endif /* MINIMALISTIC */ 9100" camcontrol rescan <all | bus[:target:lun] | dev_id>\n" 9101" camcontrol reset <all | bus[:target:lun] | dev_id>\n" 9102#ifndef MINIMALISTIC 9103" camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n" 9104" [-q][-s][-S offset][-X]\n" 9105" camcontrol modepage [dev_id][generic args] <-m page | -l>\n" 9106" [-P pagectl][-e | -b][-d]\n" 9107" camcontrol cmd [dev_id][generic args]\n" 9108" <-a cmd [args] | -c cmd [args]>\n" 9109" [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n" 9110" camcontrol smpcmd [dev_id][generic args]\n" 9111" <-r len fmt [args]> <-R len fmt [args]>\n" 9112" camcontrol smprg [dev_id][generic args][-l]\n" 9113" camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n" 9114" [-o operation][-d name][-m rate][-M rate]\n" 9115" [-T pp_timeout][-a enable|disable]\n" 9116" [-A enable|disable][-s enable|disable]\n" 9117" [-S enable|disable]\n" 9118" camcontrol smpphylist [dev_id][generic args][-l][-q]\n" 9119" camcontrol smpmaninfo [dev_id][generic args][-l]\n" 9120" camcontrol debug [-I][-P][-T][-S][-X][-c]\n" 9121" <all|bus[:target[:lun]]|off>\n" 9122" camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n" 9123" camcontrol negotiate [dev_id][generic args] [-a][-c]\n" 9124" [-D <enable|disable>][-M mode][-O offset]\n" 9125" [-q][-R syncrate][-v][-T <enable|disable>]\n" 9126" [-U][-W bus_width]\n" 9127" camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n" 9128" camcontrol sanitize [dev_id][generic args]\n" 9129" [-a overwrite|block|crypto|exitfailure]\n" 9130" [-c passes][-I][-P pattern][-q][-U][-r][-w]\n" 9131" [-y]\n" 9132" camcontrol idle [dev_id][generic args][-t time]\n" 9133" camcontrol standby [dev_id][generic args][-t time]\n" 9134" camcontrol sleep [dev_id][generic args]\n" 9135" camcontrol powermode [dev_id][generic args]\n" 9136" camcontrol apm [dev_id][generic args][-l level]\n" 9137" camcontrol aam [dev_id][generic args][-l level]\n" 9138" camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n" 9139" [-s][-y]\n" 9140" camcontrol security [dev_id][generic args]\n" 9141" <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n" 9142" [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n" 9143" [-U <user|master>] [-y]\n" 9144" camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n" 9145" [-q] [-s max_sectors] [-U pwd] [-y]\n" 9146" camcontrol persist [dev_id][generic args] <-i action|-o action>\n" 9147" [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n" 9148" [-s scope][-S][-T type][-U]\n" 9149" camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n" 9150" [-a attr_num][-c][-e elem][-F form1,form1]\n" 9151" [-p part][-s start][-T type][-V vol]\n" 9152" camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n" 9153" [-N][-T]\n" 9154" camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n" 9155" [-o rep_opts] [-P print_opts]\n" 9156" camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n" 9157" [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n" 9158" [-S power_src] [-T timer]\n" 9159" camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n" 9160" <-s <-f format -T time | -U >>\n" 9161" \n" 9162#endif /* MINIMALISTIC */ 9163" camcontrol help\n"); 9164 if (!printlong) 9165 return; 9166#ifndef MINIMALISTIC 9167 fprintf(stdout, 9168"Specify one of the following options:\n" 9169"devlist list all CAM devices\n" 9170"periphlist list all CAM peripheral drivers attached to a device\n" 9171"tur send a test unit ready to the named device\n" 9172"inquiry send a SCSI inquiry command to the named device\n" 9173"identify send a ATA identify command to the named device\n" 9174"reportluns send a SCSI report luns command to the device\n" 9175"readcap send a SCSI read capacity command to the device\n" 9176"start send a Start Unit command to the device\n" 9177"stop send a Stop Unit command to the device\n" 9178"load send a Start Unit command to the device with the load bit set\n" 9179"eject send a Stop Unit command to the device with the eject bit set\n" 9180"reprobe update capacity information of the given device\n" 9181"rescan rescan all buses, the given bus, bus:target:lun or device\n" 9182"reset reset all buses, the given bus, bus:target:lun or device\n" 9183"defects read the defect list of the specified device\n" 9184"modepage display or edit (-e) the given mode page\n" 9185"cmd send the given SCSI command, may need -i or -o as well\n" 9186"smpcmd send the given SMP command, requires -o and -i\n" 9187"smprg send the SMP Report General command\n" 9188"smppc send the SMP PHY Control command, requires -p\n" 9189"smpphylist display phys attached to a SAS expander\n" 9190"smpmaninfo send the SMP Report Manufacturer Info command\n" 9191"debug turn debugging on/off for a bus, target, or lun, or all devices\n" 9192"tags report or set the number of transaction slots for a device\n" 9193"negotiate report or set device negotiation parameters\n" 9194"format send the SCSI FORMAT UNIT command to the named device\n" 9195"sanitize send the SCSI SANITIZE command to the named device\n" 9196"idle send the ATA IDLE command to the named device\n" 9197"standby send the ATA STANDBY command to the named device\n" 9198"sleep send the ATA SLEEP command to the named device\n" 9199"powermode send the ATA CHECK POWER MODE command to the named device\n" 9200"fwdownload program firmware of the named device with the given image\n" 9201"security report or send ATA security commands to the named device\n" 9202"persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n" 9203"attrib send the SCSI READ or WRITE ATTRIBUTE commands\n" 9204"opcodes send the SCSI REPORT SUPPORTED OPCODES command\n" 9205"zone manage Zoned Block (Shingled) devices\n" 9206"epc send ATA Extended Power Conditions commands\n" 9207"timestamp report or set the device's timestamp\n" 9208"help this message\n" 9209"Device Identifiers:\n" 9210"bus:target specify the bus and target, lun defaults to 0\n" 9211"bus:target:lun specify the bus, target and lun\n" 9212"deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n" 9213"Generic arguments:\n" 9214"-v be verbose, print out sense information\n" 9215"-t timeout command timeout in seconds, overrides default timeout\n" 9216"-n dev_name specify device name, e.g. \"da\", \"cd\"\n" 9217"-u unit specify unit number, e.g. \"0\", \"5\"\n" 9218"-E have the kernel attempt to perform SCSI error recovery\n" 9219"-C count specify the SCSI command retry count (needs -E to work)\n" 9220"-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n" 9221"modepage arguments:\n" 9222"-l list all available mode pages\n" 9223"-m page specify the mode page to view or edit\n" 9224"-e edit the specified mode page\n" 9225"-b force view to binary mode\n" 9226"-d disable block descriptors for mode sense\n" 9227"-P pgctl page control field 0-3\n" 9228"defects arguments:\n" 9229"-f format specify defect list format (block, bfi or phys)\n" 9230"-G get the grown defect list\n" 9231"-P get the permanent defect list\n" 9232"inquiry arguments:\n" 9233"-D get the standard inquiry data\n" 9234"-S get the serial number\n" 9235"-R get the transfer rate, etc.\n" 9236"reportluns arguments:\n" 9237"-c only report a count of available LUNs\n" 9238"-l only print out luns, and not a count\n" 9239"-r <reporttype> specify \"default\", \"wellknown\" or \"all\"\n" 9240"readcap arguments\n" 9241"-b only report the blocksize\n" 9242"-h human readable device size, base 2\n" 9243"-H human readable device size, base 10\n" 9244"-N print the number of blocks instead of last block\n" 9245"-q quiet, print numbers only\n" 9246"-s only report the last block/device size\n" 9247"cmd arguments:\n" 9248"-c cdb [args] specify the SCSI CDB\n" 9249"-i len fmt specify input data and input data format\n" 9250"-o len fmt [args] specify output data and output data fmt\n" 9251"smpcmd arguments:\n" 9252"-r len fmt [args] specify the SMP command to be sent\n" 9253"-R len fmt [args] specify SMP response format\n" 9254"smprg arguments:\n" 9255"-l specify the long response format\n" 9256"smppc arguments:\n" 9257"-p phy specify the PHY to operate on\n" 9258"-l specify the long request/response format\n" 9259"-o operation specify the phy control operation\n" 9260"-d name set the attached device name\n" 9261"-m rate set the minimum physical link rate\n" 9262"-M rate set the maximum physical link rate\n" 9263"-T pp_timeout set the partial pathway timeout value\n" 9264"-a enable|disable enable or disable SATA slumber\n" 9265"-A enable|disable enable or disable SATA partial phy power\n" 9266"-s enable|disable enable or disable SAS slumber\n" 9267"-S enable|disable enable or disable SAS partial phy power\n" 9268"smpphylist arguments:\n" 9269"-l specify the long response format\n" 9270"-q only print phys with attached devices\n" 9271"smpmaninfo arguments:\n" 9272"-l specify the long response format\n" 9273"debug arguments:\n" 9274"-I CAM_DEBUG_INFO -- scsi commands, errors, data\n" 9275"-T CAM_DEBUG_TRACE -- routine flow tracking\n" 9276"-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n" 9277"-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n" 9278"tags arguments:\n" 9279"-N tags specify the number of tags to use for this device\n" 9280"-q be quiet, don't report the number of tags\n" 9281"-v report a number of tag-related parameters\n" 9282"negotiate arguments:\n" 9283"-a send a test unit ready after negotiation\n" 9284"-c report/set current negotiation settings\n" 9285"-D <arg> \"enable\" or \"disable\" disconnection\n" 9286"-M mode set ATA mode\n" 9287"-O offset set command delay offset\n" 9288"-q be quiet, don't report anything\n" 9289"-R syncrate synchronization rate in MHz\n" 9290"-T <arg> \"enable\" or \"disable\" tagged queueing\n" 9291"-U report/set user negotiation settings\n" 9292"-W bus_width set the bus width in bits (8, 16 or 32)\n" 9293"-v also print a Path Inquiry CCB for the controller\n" 9294"format arguments:\n" 9295"-q be quiet, don't print status messages\n" 9296"-r run in report only mode\n" 9297"-w don't send immediate format command\n" 9298"-y don't ask any questions\n" 9299"sanitize arguments:\n" 9300"-a operation operation mode: overwrite, block, crypto or exitfailure\n" 9301"-c passes overwrite passes to perform (1 to 31)\n" 9302"-I invert overwrite pattern after each pass\n" 9303"-P pattern path to overwrite pattern file\n" 9304"-q be quiet, don't print status messages\n" 9305"-r run in report only mode\n" 9306"-U run operation in unrestricted completion exit mode\n" 9307"-w don't send immediate sanitize command\n" 9308"-y don't ask any questions\n" 9309"idle/standby arguments:\n" 9310"-t <arg> number of seconds before respective state.\n" 9311"fwdownload arguments:\n" 9312"-f fw_image path to firmware image file\n" 9313"-q don't print informational messages, only errors\n" 9314"-s run in simulation mode\n" 9315"-v print info for every firmware segment sent to device\n" 9316"-y don't ask any questions\n" 9317"security arguments:\n" 9318"-d pwd disable security using the given password for the selected\n" 9319" user\n" 9320"-e pwd erase the device using the given pwd for the selected user\n" 9321"-f freeze the security configuration of the specified device\n" 9322"-h pwd enhanced erase the device using the given pwd for the\n" 9323" selected user\n" 9324"-k pwd unlock the device using the given pwd for the selected\n" 9325" user\n" 9326"-l <high|maximum> specifies which security level to set: high or maximum\n" 9327"-q be quiet, do not print any status messages\n" 9328"-s pwd password the device (enable security) using the given\n" 9329" pwd for the selected user\n" 9330"-T timeout overrides the timeout (seconds) used for erase operation\n" 9331"-U <user|master> specifies which user to set: user or master\n" 9332"-y don't ask any questions\n" 9333"hpa arguments:\n" 9334"-f freeze the HPA configuration of the device\n" 9335"-l lock the HPA configuration of the device\n" 9336"-P make the HPA max sectors persist\n" 9337"-p pwd Set the HPA configuration password required for unlock\n" 9338" calls\n" 9339"-q be quiet, do not print any status messages\n" 9340"-s sectors configures the maximum user accessible sectors of the\n" 9341" device\n" 9342"-U pwd unlock the HPA configuration of the device\n" 9343"-y don't ask any questions\n" 9344"persist arguments:\n" 9345"-i action specify read_keys, read_reservation, report_cap, or\n" 9346" read_full_status\n" 9347"-o action specify register, register_ignore, reserve, release,\n" 9348" clear, preempt, preempt_abort, register_move, replace_lost\n" 9349"-a set the All Target Ports (ALL_TG_PT) bit\n" 9350"-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n" 9351"-k key specify the Reservation Key\n" 9352"-K sa_key specify the Service Action Reservation Key\n" 9353"-p set the Activate Persist Through Power Loss bit\n" 9354"-R rtp specify the Relative Target Port\n" 9355"-s scope specify the scope: lun, extent, element or a number\n" 9356"-S specify Transport ID for register, requires -I\n" 9357"-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n" 9358" ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n" 9359"-U unregister the current initiator for register_move\n" 9360"attrib arguments:\n" 9361"-r action specify attr_values, attr_list, lv_list, part_list, or\n" 9362" supp_attr\n" 9363"-w attr specify an attribute to write, one -w argument per attr\n" 9364"-a attr_num only display this attribute number\n" 9365"-c get cached attributes\n" 9366"-e elem_addr request attributes for the given element in a changer\n" 9367"-F form1,form2 output format, comma separated list: text_esc, text_raw,\n" 9368" nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n" 9369" field_none, field_desc, field_num, field_size, field_rw\n" 9370"-p partition request attributes for the given partition\n" 9371"-s start_attr request attributes starting at the given number\n" 9372"-T elem_type specify the element type (used with -e)\n" 9373"-V logical_vol specify the logical volume ID\n" 9374"opcodes arguments:\n" 9375"-o opcode specify the individual opcode to list\n" 9376"-s service_action specify the service action for the opcode\n" 9377"-N do not return SCSI error for unsupported SA\n" 9378"-T request nominal and recommended timeout values\n" 9379"zone arguments:\n" 9380"-c cmd required: rz, open, close, finish, or rwp\n" 9381"-a apply the action to all zones\n" 9382"-l LBA specify the zone starting LBA\n" 9383"-o rep_opts report zones options: all, empty, imp_open, exp_open,\n" 9384" closed, full, ro, offline, reset, nonseq, nonwp\n" 9385"-P print_opt report zones printing: normal, summary, script\n" 9386"epc arguments:\n" 9387"-c cmd required: restore, goto, timer, state, enable, disable,\n" 9388" source, status, list\n" 9389"-d disable power mode (timer, state)\n" 9390"-D delayed entry (goto)\n" 9391"-e enable power mode (timer, state)\n" 9392"-H hold power mode (goto)\n" 9393"-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n" 9394" state, goto)\n" 9395"-P only display power mode (status)\n" 9396"-r rst_src restore settings from: default, saved (restore)\n" 9397"-s save mode (timer, state, restore)\n" 9398"-S power_src set power source: battery, nonbattery (source)\n" 9399"-T timer set timer, seconds, .1 sec resolution (timer)\n" 9400"timestamp arguments:\n" 9401"-r report the timestamp of the device\n" 9402"-f format report the timestamp of the device with the given\n" 9403" strftime(3) format string\n" 9404"-m report the timestamp of the device as milliseconds since\n" 9405" January 1st, 1970\n" 9406"-U report the time with UTC instead of the local time zone\n" 9407"-s set the timestamp of the device\n" 9408"-f format the format of the time string passed into strptime(3)\n" 9409"-T time the time value passed into strptime(3)\n" 9410"-U set the timestamp of the device to UTC time\n" 9411); 9412#endif /* MINIMALISTIC */ 9413} 9414 9415int 9416main(int argc, char **argv) 9417{ 9418 int c; 9419 char *device = NULL; 9420 int unit = 0; 9421 struct cam_device *cam_dev = NULL; 9422 int timeout = 0, retry_count = 1; 9423 camcontrol_optret optreturn; 9424 char *tstr; 9425 const char *mainopt = "C:En:Q:t:u:v"; 9426 const char *subopt = NULL; 9427 char combinedopt[256]; 9428 int error = 0, optstart = 2; 9429 int task_attr = MSG_SIMPLE_Q_TAG; 9430 int devopen = 1; 9431#ifndef MINIMALISTIC 9432 path_id_t bus; 9433 target_id_t target; 9434 lun_id_t lun; 9435#endif /* MINIMALISTIC */ 9436 9437 cmdlist = CAM_CMD_NONE; 9438 arglist = CAM_ARG_NONE; 9439 9440 if (argc < 2) { 9441 usage(0); 9442 exit(1); 9443 } 9444 9445 /* 9446 * Get the base option. 9447 */ 9448 optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt); 9449 9450 if (optreturn == CC_OR_AMBIGUOUS) { 9451 warnx("ambiguous option %s", argv[1]); 9452 usage(0); 9453 exit(1); 9454 } else if (optreturn == CC_OR_NOT_FOUND) { 9455 warnx("option %s not found", argv[1]); 9456 usage(0); 9457 exit(1); 9458 } 9459 9460 /* 9461 * Ahh, getopt(3) is a pain. 9462 * 9463 * This is a gross hack. There really aren't many other good 9464 * options (excuse the pun) for parsing options in a situation like 9465 * this. getopt is kinda braindead, so you end up having to run 9466 * through the options twice, and give each invocation of getopt 9467 * the option string for the other invocation. 9468 * 9469 * You would think that you could just have two groups of options. 9470 * The first group would get parsed by the first invocation of 9471 * getopt, and the second group would get parsed by the second 9472 * invocation of getopt. It doesn't quite work out that way. When 9473 * the first invocation of getopt finishes, it leaves optind pointing 9474 * to the argument _after_ the first argument in the second group. 9475 * So when the second invocation of getopt comes around, it doesn't 9476 * recognize the first argument it gets and then bails out. 9477 * 9478 * A nice alternative would be to have a flag for getopt that says 9479 * "just keep parsing arguments even when you encounter an unknown 9480 * argument", but there isn't one. So there's no real clean way to 9481 * easily parse two sets of arguments without having one invocation 9482 * of getopt know about the other. 9483 * 9484 * Without this hack, the first invocation of getopt would work as 9485 * long as the generic arguments are first, but the second invocation 9486 * (in the subfunction) would fail in one of two ways. In the case 9487 * where you don't set optreset, it would fail because optind may be 9488 * pointing to the argument after the one it should be pointing at. 9489 * In the case where you do set optreset, and reset optind, it would 9490 * fail because getopt would run into the first set of options, which 9491 * it doesn't understand. 9492 * 9493 * All of this would "sort of" work if you could somehow figure out 9494 * whether optind had been incremented one option too far. The 9495 * mechanics of that, however, are more daunting than just giving 9496 * both invocations all of the expect options for either invocation. 9497 * 9498 * Needless to say, I wouldn't mind if someone invented a better 9499 * (non-GPL!) command line parsing interface than getopt. I 9500 * wouldn't mind if someone added more knobs to getopt to make it 9501 * work better. Who knows, I may talk myself into doing it someday, 9502 * if the standards weenies let me. As it is, it just leads to 9503 * hackery like this and causes people to avoid it in some cases. 9504 * 9505 * KDM, September 8th, 1998 9506 */ 9507 if (subopt != NULL) 9508 sprintf(combinedopt, "%s%s", mainopt, subopt); 9509 else 9510 sprintf(combinedopt, "%s", mainopt); 9511 9512 /* 9513 * For these options we do not parse optional device arguments and 9514 * we do not open a passthrough device. 9515 */ 9516 if ((cmdlist == CAM_CMD_RESCAN) 9517 || (cmdlist == CAM_CMD_RESET) 9518 || (cmdlist == CAM_CMD_DEVTREE) 9519 || (cmdlist == CAM_CMD_USAGE) 9520 || (cmdlist == CAM_CMD_DEBUG)) 9521 devopen = 0; 9522 9523#ifndef MINIMALISTIC 9524 if ((devopen == 1) 9525 && (argc > 2 && argv[2][0] != '-')) { 9526 char name[30]; 9527 int rv; 9528 9529 if (isdigit(argv[2][0])) { 9530 /* device specified as bus:target[:lun] */ 9531 rv = parse_btl(argv[2], &bus, &target, &lun, &arglist); 9532 if (rv < 2) 9533 errx(1, "numeric device specification must " 9534 "be either bus:target, or " 9535 "bus:target:lun"); 9536 /* default to 0 if lun was not specified */ 9537 if ((arglist & CAM_ARG_LUN) == 0) { 9538 lun = 0; 9539 arglist |= CAM_ARG_LUN; 9540 } 9541 optstart++; 9542 } else { 9543 if (cam_get_device(argv[2], name, sizeof name, &unit) 9544 == -1) 9545 errx(1, "%s", cam_errbuf); 9546 device = strdup(name); 9547 arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT; 9548 optstart++; 9549 } 9550 } 9551#endif /* MINIMALISTIC */ 9552 /* 9553 * Start getopt processing at argv[2/3], since we've already 9554 * accepted argv[1..2] as the command name, and as a possible 9555 * device name. 9556 */ 9557 optind = optstart; 9558 9559 /* 9560 * Now we run through the argument list looking for generic 9561 * options, and ignoring options that possibly belong to 9562 * subfunctions. 9563 */ 9564 while ((c = getopt(argc, argv, combinedopt))!= -1){ 9565 switch(c) { 9566 case 'C': 9567 retry_count = strtol(optarg, NULL, 0); 9568 if (retry_count < 0) 9569 errx(1, "retry count %d is < 0", 9570 retry_count); 9571 arglist |= CAM_ARG_RETRIES; 9572 break; 9573 case 'E': 9574 arglist |= CAM_ARG_ERR_RECOVER; 9575 break; 9576 case 'n': 9577 arglist |= CAM_ARG_DEVICE; 9578 tstr = optarg; 9579 while (isspace(*tstr) && (*tstr != '\0')) 9580 tstr++; 9581 device = (char *)strdup(tstr); 9582 break; 9583 case 'Q': { 9584 char *endptr; 9585 int table_entry = 0; 9586 9587 tstr = optarg; 9588 while (isspace(*tstr) && (*tstr != '\0')) 9589 tstr++; 9590 if (isdigit(*tstr)) { 9591 task_attr = strtol(tstr, &endptr, 0); 9592 if (*endptr != '\0') { 9593 errx(1, "Invalid queue option " 9594 "%s", tstr); 9595 } 9596 } else { 9597 size_t table_size; 9598 scsi_nv_status status; 9599 9600 table_size = sizeof(task_attrs) / 9601 sizeof(task_attrs[0]); 9602 status = scsi_get_nv(task_attrs, 9603 table_size, tstr, &table_entry, 9604 SCSI_NV_FLAG_IG_CASE); 9605 if (status == SCSI_NV_FOUND) 9606 task_attr = task_attrs[ 9607 table_entry].value; 9608 else { 9609 errx(1, "%s option %s", 9610 (status == SCSI_NV_AMBIGUOUS)? 9611 "ambiguous" : "invalid", 9612 tstr); 9613 } 9614 } 9615 break; 9616 } 9617 case 't': 9618 timeout = strtol(optarg, NULL, 0); 9619 if (timeout < 0) 9620 errx(1, "invalid timeout %d", timeout); 9621 /* Convert the timeout from seconds to ms */ 9622 timeout *= 1000; 9623 arglist |= CAM_ARG_TIMEOUT; 9624 break; 9625 case 'u': 9626 arglist |= CAM_ARG_UNIT; 9627 unit = strtol(optarg, NULL, 0); 9628 break; 9629 case 'v': 9630 arglist |= CAM_ARG_VERBOSE; 9631 break; 9632 default: 9633 break; 9634 } 9635 } 9636 9637#ifndef MINIMALISTIC 9638 /* 9639 * For most commands we'll want to open the passthrough device 9640 * associated with the specified device. In the case of the rescan 9641 * commands, we don't use a passthrough device at all, just the 9642 * transport layer device. 9643 */ 9644 if (devopen == 1) { 9645 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0) 9646 && (((arglist & CAM_ARG_DEVICE) == 0) 9647 || ((arglist & CAM_ARG_UNIT) == 0))) { 9648 errx(1, "subcommand \"%s\" requires a valid device " 9649 "identifier", argv[1]); 9650 } 9651 9652 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))? 9653 cam_open_btl(bus, target, lun, O_RDWR, NULL) : 9654 cam_open_spec_device(device,unit,O_RDWR,NULL))) 9655 == NULL) 9656 errx(1,"%s", cam_errbuf); 9657 } 9658#endif /* MINIMALISTIC */ 9659 9660 /* 9661 * Reset optind to 2, and reset getopt, so these routines can parse 9662 * the arguments again. 9663 */ 9664 optind = optstart; 9665 optreset = 1; 9666 9667 switch(cmdlist) { 9668#ifndef MINIMALISTIC 9669 case CAM_CMD_DEVLIST: 9670 error = getdevlist(cam_dev); 9671 break; 9672 case CAM_CMD_HPA: 9673 error = atahpa(cam_dev, retry_count, timeout, 9674 argc, argv, combinedopt); 9675 break; 9676#endif /* MINIMALISTIC */ 9677 case CAM_CMD_DEVTREE: 9678 error = getdevtree(argc, argv, combinedopt); 9679 break; 9680#ifndef MINIMALISTIC 9681 case CAM_CMD_TUR: 9682 error = testunitready(cam_dev, task_attr, retry_count, 9683 timeout, 0); 9684 break; 9685 case CAM_CMD_INQUIRY: 9686 error = scsidoinquiry(cam_dev, argc, argv, combinedopt, 9687 task_attr, retry_count, timeout); 9688 break; 9689 case CAM_CMD_IDENTIFY: 9690 error = ataidentify(cam_dev, retry_count, timeout); 9691 break; 9692 case CAM_CMD_STARTSTOP: 9693 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT, 9694 arglist & CAM_ARG_EJECT, task_attr, 9695 retry_count, timeout); 9696 break; 9697#endif /* MINIMALISTIC */ 9698 case CAM_CMD_RESCAN: 9699 error = dorescan_or_reset(argc, argv, 1); 9700 break; 9701 case CAM_CMD_RESET: 9702 error = dorescan_or_reset(argc, argv, 0); 9703 break; 9704#ifndef MINIMALISTIC 9705 case CAM_CMD_READ_DEFECTS: 9706 error = readdefects(cam_dev, argc, argv, combinedopt, 9707 task_attr, retry_count, timeout); 9708 break; 9709 case CAM_CMD_MODE_PAGE: 9710 modepage(cam_dev, argc, argv, combinedopt, 9711 task_attr, retry_count, timeout); 9712 break; 9713 case CAM_CMD_SCSI_CMD: 9714 error = scsicmd(cam_dev, argc, argv, combinedopt, 9715 task_attr, retry_count, timeout); 9716 break; 9717 case CAM_CMD_SMP_CMD: 9718 error = smpcmd(cam_dev, argc, argv, combinedopt, 9719 retry_count, timeout); 9720 break; 9721 case CAM_CMD_SMP_RG: 9722 error = smpreportgeneral(cam_dev, argc, argv, 9723 combinedopt, retry_count, 9724 timeout); 9725 break; 9726 case CAM_CMD_SMP_PC: 9727 error = smpphycontrol(cam_dev, argc, argv, combinedopt, 9728 retry_count, timeout); 9729 break; 9730 case CAM_CMD_SMP_PHYLIST: 9731 error = smpphylist(cam_dev, argc, argv, combinedopt, 9732 retry_count, timeout); 9733 break; 9734 case CAM_CMD_SMP_MANINFO: 9735 error = smpmaninfo(cam_dev, argc, argv, combinedopt, 9736 retry_count, timeout); 9737 break; 9738 case CAM_CMD_DEBUG: 9739 error = camdebug(argc, argv, combinedopt); 9740 break; 9741 case CAM_CMD_TAG: 9742 error = tagcontrol(cam_dev, argc, argv, combinedopt); 9743 break; 9744 case CAM_CMD_RATE: 9745 error = ratecontrol(cam_dev, task_attr, retry_count, 9746 timeout, argc, argv, combinedopt); 9747 break; 9748 case CAM_CMD_FORMAT: 9749 error = scsiformat(cam_dev, argc, argv, 9750 combinedopt, task_attr, retry_count, 9751 timeout); 9752 break; 9753 case CAM_CMD_REPORTLUNS: 9754 error = scsireportluns(cam_dev, argc, argv, 9755 combinedopt, task_attr, 9756 retry_count, timeout); 9757 break; 9758 case CAM_CMD_READCAP: 9759 error = scsireadcapacity(cam_dev, argc, argv, 9760 combinedopt, task_attr, 9761 retry_count, timeout); 9762 break; 9763 case CAM_CMD_IDLE: 9764 case CAM_CMD_STANDBY: 9765 case CAM_CMD_SLEEP: 9766 case CAM_CMD_POWER_MODE: 9767 error = atapm(cam_dev, argc, argv, 9768 combinedopt, retry_count, timeout); 9769 break; 9770 case CAM_CMD_APM: 9771 case CAM_CMD_AAM: 9772 error = ataaxm(cam_dev, argc, argv, 9773 combinedopt, retry_count, timeout); 9774 break; 9775 case CAM_CMD_SECURITY: 9776 error = atasecurity(cam_dev, retry_count, timeout, 9777 argc, argv, combinedopt); 9778 break; 9779 case CAM_CMD_DOWNLOAD_FW: 9780 error = fwdownload(cam_dev, argc, argv, combinedopt, 9781 arglist & CAM_ARG_VERBOSE, task_attr, retry_count, 9782 timeout); 9783 break; 9784 case CAM_CMD_SANITIZE: 9785 error = scsisanitize(cam_dev, argc, argv, 9786 combinedopt, task_attr, 9787 retry_count, timeout); 9788 break; 9789 case CAM_CMD_PERSIST: 9790 error = scsipersist(cam_dev, argc, argv, combinedopt, 9791 task_attr, retry_count, timeout, 9792 arglist & CAM_ARG_VERBOSE, 9793 arglist & CAM_ARG_ERR_RECOVER); 9794 break; 9795 case CAM_CMD_ATTRIB: 9796 error = scsiattrib(cam_dev, argc, argv, combinedopt, 9797 task_attr, retry_count, timeout, 9798 arglist & CAM_ARG_VERBOSE, 9799 arglist & CAM_ARG_ERR_RECOVER); 9800 break; 9801 case CAM_CMD_OPCODES: 9802 error = scsiopcodes(cam_dev, argc, argv, combinedopt, 9803 task_attr, retry_count, timeout, 9804 arglist & CAM_ARG_VERBOSE); 9805 break; 9806 case CAM_CMD_REPROBE: 9807 error = scsireprobe(cam_dev); 9808 break; 9809 case CAM_CMD_ZONE: 9810 error = zone(cam_dev, argc, argv, combinedopt, 9811 task_attr, retry_count, timeout, 9812 arglist & CAM_ARG_VERBOSE); 9813 break; 9814 case CAM_CMD_EPC: 9815 error = epc(cam_dev, argc, argv, combinedopt, 9816 retry_count, timeout, arglist & CAM_ARG_VERBOSE); 9817 break; 9818 case CAM_CMD_TIMESTAMP: 9819 error = timestamp(cam_dev, argc, argv, combinedopt, 9820 task_attr, retry_count, timeout, 9821 arglist & CAM_ARG_VERBOSE); 9822 break; 9823#endif /* MINIMALISTIC */ 9824 case CAM_CMD_USAGE: 9825 usage(1); 9826 break; 9827 default: 9828 usage(0); 9829 error = 1; 9830 break; 9831 } 9832 9833 if (cam_dev != NULL) 9834 cam_close_device(cam_dev); 9835 9836 exit(error); 9837} 9838