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