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