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