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