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