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