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