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