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