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