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