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