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