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