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