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