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