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