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