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