]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/camcontrol/camcontrol.c
sysctl(9): Fix a few mandoc related issues
[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                 char pass[sizeof(pwd->password)+1];
2462
2463                 /* pwd->password may not be null terminated */
2464                 pass[sizeof(pwd->password)] = '\0';
2465                 strncpy(pass, pwd->password, sizeof(pwd->password));
2466                 printf(" password='%s', user='%s'",
2467                         pass,
2468                         (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ?
2469                         "master" : "user");
2470
2471                 if (command == ATA_SECURITY_SET_PASSWORD) {
2472                         printf(", mode='%s'",
2473                                (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ?
2474                                "maximum" : "high");
2475                 }
2476         }
2477
2478         printf("\n");
2479 }
2480
2481 static int
2482 atasecurity_freeze(struct cam_device *device, union ccb *ccb,
2483                    int retry_count, u_int32_t timeout, int quiet)
2484 {
2485
2486         if (quiet == 0)
2487                 atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL);
2488
2489         return ata_do_cmd(device,
2490                           ccb,
2491                           retry_count,
2492                           /*flags*/CAM_DIR_NONE,
2493                           /*protocol*/AP_PROTO_NON_DATA,
2494                           /*ata_flags*/0,
2495                           /*tag_action*/MSG_SIMPLE_Q_TAG,
2496                           /*command*/ATA_SECURITY_FREEZE_LOCK,
2497                           /*features*/0,
2498                           /*lba*/0,
2499                           /*sector_count*/0,
2500                           /*data_ptr*/NULL,
2501                           /*dxfer_len*/0,
2502                           /*timeout*/timeout,
2503                           /*force48bit*/0);
2504 }
2505
2506 static int
2507 atasecurity_unlock(struct cam_device *device, union ccb *ccb,
2508                    int retry_count, u_int32_t timeout,
2509                    struct ata_security_password *pwd, int quiet)
2510 {
2511
2512         if (quiet == 0)
2513                 atasecurity_notify(ATA_SECURITY_UNLOCK, pwd);
2514
2515         return ata_do_cmd(device,
2516                           ccb,
2517                           retry_count,
2518                           /*flags*/CAM_DIR_OUT,
2519                           /*protocol*/AP_PROTO_PIO_OUT,
2520                           /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2521                             AP_FLAG_TLEN_SECT_CNT,
2522                           /*tag_action*/MSG_SIMPLE_Q_TAG,
2523                           /*command*/ATA_SECURITY_UNLOCK,
2524                           /*features*/0,
2525                           /*lba*/0,
2526                           /*sector_count*/sizeof(*pwd) / 512,
2527                           /*data_ptr*/(u_int8_t *)pwd,
2528                           /*dxfer_len*/sizeof(*pwd),
2529                           /*timeout*/timeout,
2530                           /*force48bit*/0);
2531 }
2532
2533 static int
2534 atasecurity_disable(struct cam_device *device, union ccb *ccb,
2535                     int retry_count, u_int32_t timeout,
2536                     struct ata_security_password *pwd, int quiet)
2537 {
2538
2539         if (quiet == 0)
2540                 atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd);
2541         return ata_do_cmd(device,
2542                           ccb,
2543                           retry_count,
2544                           /*flags*/CAM_DIR_OUT,
2545                           /*protocol*/AP_PROTO_PIO_OUT,
2546                           /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2547                             AP_FLAG_TLEN_SECT_CNT,
2548                           /*tag_action*/MSG_SIMPLE_Q_TAG,
2549                           /*command*/ATA_SECURITY_DISABLE_PASSWORD,
2550                           /*features*/0,
2551                           /*lba*/0,
2552                           /*sector_count*/sizeof(*pwd) / 512,
2553                           /*data_ptr*/(u_int8_t *)pwd,
2554                           /*dxfer_len*/sizeof(*pwd),
2555                           /*timeout*/timeout,
2556                           /*force48bit*/0);
2557 }
2558
2559
2560 static int
2561 atasecurity_erase_confirm(struct cam_device *device,
2562                           struct ata_params* ident_buf)
2563 {
2564
2565         printf("\nYou are about to ERASE ALL DATA from the following"
2566                " device:\n%s%d,%s%d: ", device->device_name,
2567                device->dev_unit_num, device->given_dev_name,
2568                device->given_unit_number);
2569         ata_print_ident(ident_buf);
2570
2571         for(;;) {
2572                 char str[50];
2573                 printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) ");
2574
2575                 if (fgets(str, sizeof(str), stdin) != NULL) {
2576                         if (strncasecmp(str, "yes", 3) == 0) {
2577                                 return (1);
2578                         } else if (strncasecmp(str, "no", 2) == 0) {
2579                                 return (0);
2580                         } else {
2581                                 printf("Please answer \"yes\" or "
2582                                        "\"no\"\n");
2583                         }
2584                 }
2585         }
2586
2587         /* NOTREACHED */
2588         return (0);
2589 }
2590
2591 static int
2592 atasecurity_erase(struct cam_device *device, union ccb *ccb,
2593                   int retry_count, u_int32_t timeout,
2594                   u_int32_t erase_timeout,
2595                   struct ata_security_password *pwd, int quiet)
2596 {
2597         int error;
2598
2599         if (quiet == 0)
2600                 atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL);
2601
2602         error = ata_do_cmd(device,
2603                            ccb,
2604                            retry_count,
2605                            /*flags*/CAM_DIR_NONE,
2606                            /*protocol*/AP_PROTO_NON_DATA,
2607                            /*ata_flags*/0,
2608                            /*tag_action*/MSG_SIMPLE_Q_TAG,
2609                            /*command*/ATA_SECURITY_ERASE_PREPARE,
2610                            /*features*/0,
2611                            /*lba*/0,
2612                            /*sector_count*/0,
2613                            /*data_ptr*/NULL,
2614                            /*dxfer_len*/0,
2615                            /*timeout*/timeout,
2616                            /*force48bit*/0);
2617
2618         if (error != 0)
2619                 return error;
2620
2621         if (quiet == 0)
2622                 atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd);
2623
2624         error = ata_do_cmd(device,
2625                            ccb,
2626                            retry_count,
2627                            /*flags*/CAM_DIR_OUT,
2628                            /*protocol*/AP_PROTO_PIO_OUT,
2629                            /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2630                             AP_FLAG_TLEN_SECT_CNT,
2631                            /*tag_action*/MSG_SIMPLE_Q_TAG,
2632                            /*command*/ATA_SECURITY_ERASE_UNIT,
2633                            /*features*/0,
2634                            /*lba*/0,
2635                            /*sector_count*/sizeof(*pwd) / 512,
2636                            /*data_ptr*/(u_int8_t *)pwd,
2637                            /*dxfer_len*/sizeof(*pwd),
2638                            /*timeout*/erase_timeout,
2639                            /*force48bit*/0);
2640
2641         if (error == 0 && quiet == 0)
2642                 printf("\nErase Complete\n");
2643
2644         return error;
2645 }
2646
2647 static int
2648 atasecurity_set_password(struct cam_device *device, union ccb *ccb,
2649                          int retry_count, u_int32_t timeout,
2650                          struct ata_security_password *pwd, int quiet)
2651 {
2652
2653         if (quiet == 0)
2654                 atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd);
2655
2656         return ata_do_cmd(device,
2657                           ccb,
2658                           retry_count,
2659                           /*flags*/CAM_DIR_OUT,
2660                           /*protocol*/AP_PROTO_PIO_OUT,
2661                           /*ata_flags*/AP_FLAG_BYT_BLOK_BLOCKS |
2662                            AP_FLAG_TLEN_SECT_CNT,
2663                           /*tag_action*/MSG_SIMPLE_Q_TAG,
2664                           /*command*/ATA_SECURITY_SET_PASSWORD,
2665                           /*features*/0,
2666                           /*lba*/0,
2667                           /*sector_count*/sizeof(*pwd) / 512,
2668                           /*data_ptr*/(u_int8_t *)pwd,
2669                           /*dxfer_len*/sizeof(*pwd),
2670                           /*timeout*/timeout,
2671                           /*force48bit*/0);
2672 }
2673
2674 static void
2675 atasecurity_print(struct ata_params *parm)
2676 {
2677
2678         printf("\nSecurity Option           Value\n");
2679         if (arglist & CAM_ARG_VERBOSE) {
2680                 printf("status                    %04x\n",
2681                        parm->security_status);
2682         }
2683         printf("supported                 %s\n",
2684                 parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no");
2685         if (!(parm->security_status & ATA_SECURITY_SUPPORTED))
2686                 return;
2687         printf("enabled                   %s\n",
2688                 parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no");
2689         printf("drive locked              %s\n",
2690                 parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no");
2691         printf("security config frozen    %s\n",
2692                 parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no");
2693         printf("count expired             %s\n",
2694                 parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no");
2695         printf("security level            %s\n",
2696                 parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high");
2697         printf("enhanced erase supported  %s\n",
2698                 parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no");
2699         printf("erase time                ");
2700         atasecurity_print_time(parm->erase_time);
2701         printf("\n");
2702         printf("enhanced erase time       ");
2703         atasecurity_print_time(parm->enhanced_erase_time);
2704         printf("\n");
2705         printf("master password rev       %04x%s\n",
2706                 parm->master_passwd_revision,
2707                 parm->master_passwd_revision == 0x0000 ||
2708                 parm->master_passwd_revision == 0xFFFF ?  " (unsupported)" : "");
2709 }
2710
2711 /*
2712  * Validates and copies the password in optarg to the passed buffer.
2713  * If the password in optarg is the same length as the buffer then
2714  * the data will still be copied but no null termination will occur.
2715  */
2716 static int
2717 ata_getpwd(u_int8_t *passwd, int max, char opt)
2718 {
2719         int len;
2720
2721         len = strlen(optarg);
2722         if (len > max) {
2723                 warnx("-%c password is too long", opt);
2724                 return (1);
2725         } else if (len == 0) {
2726                 warnx("-%c password is missing", opt);
2727                 return (1);
2728         } else if (optarg[0] == '-'){
2729                 warnx("-%c password starts with '-' (generic arg?)", opt);
2730                 return (1);
2731         } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) {
2732                 warnx("-%c password conflicts with existing password from -%c",
2733                       opt, pwd_opt);
2734                 return (1);
2735         }
2736
2737         /* Callers pass in a buffer which does NOT need to be terminated */
2738         strncpy(passwd, optarg, max);
2739         pwd_opt = opt;
2740
2741         return (0);
2742 }
2743
2744 enum {
2745         ATA_HPA_ACTION_PRINT,
2746         ATA_HPA_ACTION_SET_MAX,
2747         ATA_HPA_ACTION_SET_PWD,
2748         ATA_HPA_ACTION_LOCK,
2749         ATA_HPA_ACTION_UNLOCK,
2750         ATA_HPA_ACTION_FREEZE_LOCK
2751 };
2752
2753 static int
2754 atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf,
2755                    u_int64_t maxsize, int persist)
2756 {
2757         printf("\nYou are about to configure HPA to limit the user accessible\n"
2758                "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize,
2759                persist ? "persistently" : "temporarily",
2760                device->device_name, device->dev_unit_num,
2761                device->given_dev_name, device->given_unit_number);
2762         ata_print_ident(ident_buf);
2763
2764         for(;;) {
2765                 char str[50];
2766                 printf("\nAre you SURE you want to configure HPA? (yes/no) ");
2767
2768                 if (NULL != fgets(str, sizeof(str), stdin)) {
2769                         if (0 == strncasecmp(str, "yes", 3)) {
2770                                 return (1);
2771                         } else if (0 == strncasecmp(str, "no", 2)) {
2772                                 return (0);
2773                         } else {
2774                                 printf("Please answer \"yes\" or "
2775                                        "\"no\"\n");
2776                         }
2777                 }
2778         }
2779
2780         /* NOTREACHED */
2781         return (0);
2782 }
2783
2784 static int
2785 atahpa(struct cam_device *device, int retry_count, int timeout,
2786        int argc, char **argv, char *combinedopt)
2787 {
2788         union ccb *ccb;
2789         struct ata_params *ident_buf;
2790         struct ccb_getdev cgd;
2791         struct ata_set_max_pwd pwd;
2792         int error, confirm, quiet, c, action, actions, persist;
2793         int security, is48bit, pwdsize;
2794         u_int64_t hpasize, maxsize;
2795
2796         actions = 0;
2797         confirm = 0;
2798         quiet = 0;
2799         maxsize = 0;
2800         persist = 0;
2801         security = 0;
2802
2803         memset(&pwd, 0, sizeof(pwd));
2804
2805         /* default action is to print hpa information */
2806         action = ATA_HPA_ACTION_PRINT;
2807         pwdsize = sizeof(pwd.password);
2808
2809         while ((c = getopt(argc, argv, combinedopt)) != -1) {
2810                 switch(c){
2811                 case 's':
2812                         action = ATA_HPA_ACTION_SET_MAX;
2813                         maxsize = strtoumax(optarg, NULL, 0);
2814                         actions++;
2815                         break;
2816
2817                 case 'p':
2818                         if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2819                                 return (1);
2820                         action = ATA_HPA_ACTION_SET_PWD;
2821                         security = 1;
2822                         actions++;
2823                         break;
2824
2825                 case 'l':
2826                         action = ATA_HPA_ACTION_LOCK;
2827                         security = 1;
2828                         actions++;
2829                         break;
2830
2831                 case 'U':
2832                         if (ata_getpwd(pwd.password, pwdsize, c) != 0)
2833                                 return (1);
2834                         action = ATA_HPA_ACTION_UNLOCK;
2835                         security = 1;
2836                         actions++;
2837                         break;
2838
2839                 case 'f':
2840                         action = ATA_HPA_ACTION_FREEZE_LOCK;
2841                         security = 1;
2842                         actions++;
2843                         break;
2844
2845                 case 'P':
2846                         persist = 1;
2847                         break;
2848
2849                 case 'y':
2850                         confirm++;
2851                         break;
2852
2853                 case 'q':
2854                         quiet++;
2855                         break;
2856                 }
2857         }
2858
2859         if (actions > 1) {
2860                 warnx("too many hpa actions specified");
2861                 return (1);
2862         }
2863
2864         if (get_cgd(device, &cgd) != 0) {
2865                 warnx("couldn't get CGD");
2866                 return (1);
2867         }
2868
2869         ccb = cam_getccb(device);
2870         if (ccb == NULL) {
2871                 warnx("couldn't allocate CCB");
2872                 return (1);
2873         }
2874
2875         error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
2876         if (error != 0) {
2877                 cam_freeccb(ccb);
2878                 return (1);
2879         }
2880
2881         if (quiet == 0) {
2882                 printf("%s%d: ", device->device_name, device->dev_unit_num);
2883                 ata_print_ident(ident_buf);
2884                 camxferrate(device);
2885         }
2886
2887         if (action == ATA_HPA_ACTION_PRINT) {
2888                 hpasize = 0;
2889                 if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)
2890                         ata_read_native_max(device, retry_count, timeout, ccb,
2891                                     ident_buf, &hpasize);
2892                 atahpa_print(ident_buf, hpasize, 1);
2893
2894                 cam_freeccb(ccb);
2895                 free(ident_buf);
2896                 return (error);
2897         }
2898
2899         if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) {
2900                 warnx("HPA is not supported by this device");
2901                 cam_freeccb(ccb);
2902                 free(ident_buf);
2903                 return (1);
2904         }
2905
2906         if (security && !(ident_buf->support.command2 & ATA_SUPPORT_MAXSECURITY)) {
2907                 warnx("HPA Security is not supported by this device");
2908                 cam_freeccb(ccb);
2909                 free(ident_buf);
2910                 return (1);
2911         }
2912
2913         is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48;
2914
2915         /*
2916          * The ATA spec requires:
2917          * 1. Read native max addr is called directly before set max addr
2918          * 2. Read native max addr is NOT called before any other set max call
2919          */
2920         switch(action) {
2921         case ATA_HPA_ACTION_SET_MAX:
2922                 if (confirm == 0 &&
2923                     atahpa_set_confirm(device, ident_buf, maxsize,
2924                     persist) == 0) {
2925                         cam_freeccb(ccb);
2926                         free(ident_buf);
2927                         return (1);
2928                 }
2929
2930                 error = ata_read_native_max(device, retry_count, timeout,
2931                                             ccb, ident_buf, &hpasize);
2932                 if (error == 0) {
2933                         error = atahpa_set_max(device, retry_count, timeout,
2934                                                ccb, is48bit, maxsize, persist);
2935                         if (error == 0) {
2936                                 if (quiet == 0) {
2937                                         /* redo identify to get new values */
2938                                         error = ata_do_identify(device,
2939                                             retry_count, timeout, ccb,
2940                                             &ident_buf);
2941                                         atahpa_print(ident_buf, hpasize, 1);
2942                                 }
2943                                 /* Hint CAM to reprobe the device. */
2944                                 reprobe(device);
2945                         }
2946                 }
2947                 break;
2948
2949         case ATA_HPA_ACTION_SET_PWD:
2950                 error = atahpa_password(device, retry_count, timeout,
2951                                         ccb, is48bit, &pwd);
2952                 if (error == 0 && quiet == 0)
2953                         printf("HPA password has been set\n");
2954                 break;
2955
2956         case ATA_HPA_ACTION_LOCK:
2957                 error = atahpa_lock(device, retry_count, timeout,
2958                                     ccb, is48bit);
2959                 if (error == 0 && quiet == 0)
2960                         printf("HPA has been locked\n");
2961                 break;
2962
2963         case ATA_HPA_ACTION_UNLOCK:
2964                 error = atahpa_unlock(device, retry_count, timeout,
2965                                       ccb, is48bit, &pwd);
2966                 if (error == 0 && quiet == 0)
2967                         printf("HPA has been unlocked\n");
2968                 break;
2969
2970         case ATA_HPA_ACTION_FREEZE_LOCK:
2971                 error = atahpa_freeze_lock(device, retry_count, timeout,
2972                                            ccb, is48bit);
2973                 if (error == 0 && quiet == 0)
2974                         printf("HPA has been frozen\n");
2975                 break;
2976
2977         default:
2978                 errx(1, "Option currently not supported");
2979         }
2980
2981         cam_freeccb(ccb);
2982         free(ident_buf);
2983
2984         return (error);
2985 }
2986
2987 enum {
2988         ATA_AMA_ACTION_PRINT,
2989         ATA_AMA_ACTION_SET_MAX,
2990         ATA_AMA_ACTION_FREEZE_LOCK
2991 };
2992
2993 static int
2994 ataama(struct cam_device *device, int retry_count, int timeout,
2995        int argc, char **argv, char *combinedopt)
2996 {
2997         union ccb *ccb;
2998         struct ata_params *ident_buf;
2999         struct ccb_getdev cgd;
3000         int error, quiet, c, action, actions;
3001         u_int64_t nativesize, maxsize;
3002
3003         actions = 0;
3004         quiet = 0;
3005         maxsize = 0;
3006
3007         /* default action is to print AMA information */
3008         action = ATA_AMA_ACTION_PRINT;
3009
3010         while ((c = getopt(argc, argv, combinedopt)) != -1) {
3011                 switch(c){
3012                 case 's':
3013                         action = ATA_AMA_ACTION_SET_MAX;
3014                         maxsize = strtoumax(optarg, NULL, 0);
3015                         actions++;
3016                         break;
3017
3018                 case 'f':
3019                         action = ATA_AMA_ACTION_FREEZE_LOCK;
3020                         actions++;
3021                         break;
3022
3023                 case 'q':
3024                         quiet++;
3025                         break;
3026                 }
3027         }
3028
3029         if (actions > 1) {
3030                 warnx("too many AMA actions specified");
3031                 return (1);
3032         }
3033
3034         if (get_cgd(device, &cgd) != 0) {
3035                 warnx("couldn't get CGD");
3036                 return (1);
3037         }
3038
3039         ccb = cam_getccb(device);
3040         if (ccb == NULL) {
3041                 warnx("couldn't allocate CCB");
3042                 return (1);
3043         }
3044
3045         error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3046         if (error != 0) {
3047                 cam_freeccb(ccb);
3048                 return (1);
3049         }
3050
3051         if (quiet == 0) {
3052                 printf("%s%d: ", device->device_name, device->dev_unit_num);
3053                 ata_print_ident(ident_buf);
3054                 camxferrate(device);
3055         }
3056
3057         if (action == ATA_AMA_ACTION_PRINT) {
3058                 nativesize = 0;
3059                 if (ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)
3060                         ata_get_native_max(device, retry_count, timeout, ccb,
3061                                            &nativesize);
3062                 ataama_print(ident_buf, nativesize, 1);
3063
3064                 cam_freeccb(ccb);
3065                 free(ident_buf);
3066                 return (error);
3067         }
3068
3069         if (!(ident_buf->support2 & ATA_SUPPORT_AMAX_ADDR)) {
3070                 warnx("Accessible Max Address is not supported by this device");
3071                 cam_freeccb(ccb);
3072                 free(ident_buf);
3073                 return (1);
3074         }
3075
3076         switch(action) {
3077         case ATA_AMA_ACTION_SET_MAX:
3078                 error = ata_get_native_max(device, retry_count, timeout, ccb,
3079                                            &nativesize);
3080                 if (error == 0) {
3081                         error = ataama_set(device, retry_count, timeout,
3082                                        ccb, maxsize);
3083                         if (error == 0) {
3084                                 if (quiet == 0) {
3085                                         /* redo identify to get new values */
3086                                         error = ata_do_identify(device,
3087                                             retry_count, timeout, ccb,
3088                                             &ident_buf);
3089                                         ataama_print(ident_buf, nativesize, 1);
3090                                 }
3091                                 /* Hint CAM to reprobe the device. */
3092                                 reprobe(device);
3093                         }
3094                 }
3095                 break;
3096
3097         case ATA_AMA_ACTION_FREEZE_LOCK:
3098                 error = ataama_freeze(device, retry_count, timeout,
3099                                            ccb);
3100                 if (error == 0 && quiet == 0)
3101                         printf("Accessible Max Address has been frozen\n");
3102                 break;
3103
3104         default:
3105                 errx(1, "Option currently not supported");
3106         }
3107
3108         cam_freeccb(ccb);
3109         free(ident_buf);
3110
3111         return (error);
3112 }
3113
3114 static int
3115 atasecurity(struct cam_device *device, int retry_count, int timeout,
3116             int argc, char **argv, char *combinedopt)
3117 {
3118         union ccb *ccb;
3119         struct ata_params *ident_buf;
3120         int error, confirm, quiet, c, action, actions, setpwd;
3121         int security_enabled, erase_timeout, pwdsize;
3122         struct ata_security_password pwd;
3123
3124         actions = 0;
3125         setpwd = 0;
3126         erase_timeout = 0;
3127         confirm = 0;
3128         quiet = 0;
3129
3130         memset(&pwd, 0, sizeof(pwd));
3131
3132         /* default action is to print security information */
3133         action = ATA_SECURITY_ACTION_PRINT;
3134
3135         /* user is master by default as its safer that way */
3136         pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3137         pwdsize = sizeof(pwd.password);
3138
3139         while ((c = getopt(argc, argv, combinedopt)) != -1) {
3140                 switch(c){
3141                 case 'f':
3142                         action = ATA_SECURITY_ACTION_FREEZE;
3143                         actions++;
3144                         break;
3145
3146                 case 'U':
3147                         if (strcasecmp(optarg, "user") == 0) {
3148                                 pwd.ctrl |= ATA_SECURITY_PASSWORD_USER;
3149                                 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER;
3150                         } else if (strcasecmp(optarg, "master") == 0) {
3151                                 pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER;
3152                                 pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER;
3153                         } else {
3154                                 warnx("-U argument '%s' is invalid (must be "
3155                                       "'user' or 'master')", optarg);
3156                                 return (1);
3157                         }
3158                         break;
3159
3160                 case 'l':
3161                         if (strcasecmp(optarg, "high") == 0) {
3162                                 pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH;
3163                                 pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM;
3164                         } else if (strcasecmp(optarg, "maximum") == 0) {
3165                                 pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM;
3166                                 pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH;
3167                         } else {
3168                                 warnx("-l argument '%s' is unknown (must be "
3169                                       "'high' or 'maximum')", optarg);
3170                                 return (1);
3171                         }
3172                         break;
3173
3174                 case 'k':
3175                         if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3176                                 return (1);
3177                         action = ATA_SECURITY_ACTION_UNLOCK;
3178                         actions++;
3179                         break;
3180
3181                 case 'd':
3182                         if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3183                                 return (1);
3184                         action = ATA_SECURITY_ACTION_DISABLE;
3185                         actions++;
3186                         break;
3187
3188                 case 'e':
3189                         if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3190                                 return (1);
3191                         action = ATA_SECURITY_ACTION_ERASE;
3192                         actions++;
3193                         break;
3194
3195                 case 'h':
3196                         if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3197                                 return (1);
3198                         pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED;
3199                         action = ATA_SECURITY_ACTION_ERASE_ENHANCED;
3200                         actions++;
3201                         break;
3202
3203                 case 's':
3204                         if (ata_getpwd(pwd.password, pwdsize, c) != 0)
3205                                 return (1);
3206                         setpwd = 1;
3207                         if (action == ATA_SECURITY_ACTION_PRINT)
3208                                 action = ATA_SECURITY_ACTION_SET_PASSWORD;
3209                         /*
3210                          * Don't increment action as this can be combined
3211                          * with other actions.
3212                          */
3213                         break;
3214
3215                 case 'y':
3216                         confirm++;
3217                         break;
3218
3219                 case 'q':
3220                         quiet++;
3221                         break;
3222
3223                 case 'T':
3224                         erase_timeout = atoi(optarg) * 1000;
3225                         break;
3226                 }
3227         }
3228
3229         if (actions > 1) {
3230                 warnx("too many security actions specified");
3231                 return (1);
3232         }
3233
3234         if ((ccb = cam_getccb(device)) == NULL) {
3235                 warnx("couldn't allocate CCB");
3236                 return (1);
3237         }
3238
3239         error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf);
3240         if (error != 0) {
3241                 cam_freeccb(ccb);
3242                 return (1);
3243         }
3244
3245         if (quiet == 0) {
3246                 printf("%s%d: ", device->device_name, device->dev_unit_num);
3247                 ata_print_ident(ident_buf);
3248                 camxferrate(device);
3249         }
3250
3251         if (action == ATA_SECURITY_ACTION_PRINT) {
3252                 atasecurity_print(ident_buf);
3253                 free(ident_buf);
3254                 cam_freeccb(ccb);
3255                 return (0);
3256         }
3257
3258         if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) {
3259                 warnx("Security not supported");
3260                 free(ident_buf);
3261                 cam_freeccb(ccb);
3262                 return (1);
3263         }
3264
3265         /* default timeout 15 seconds the same as linux hdparm */
3266         timeout = timeout ? timeout : 15 * 1000;
3267
3268         security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED;
3269
3270         /* first set the password if requested */
3271         if (setpwd == 1) {
3272                 /* confirm we can erase before setting the password if erasing */
3273                 if (confirm == 0 &&
3274                     (action == ATA_SECURITY_ACTION_ERASE_ENHANCED ||
3275                     action == ATA_SECURITY_ACTION_ERASE) &&
3276                     atasecurity_erase_confirm(device, ident_buf) == 0) {
3277                         cam_freeccb(ccb);
3278                         free(ident_buf);
3279                         return (error);
3280                 }
3281
3282                 if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) {
3283                         pwd.revision = ident_buf->master_passwd_revision;
3284                         if (pwd.revision != 0 && pwd.revision != 0xfff &&
3285                             --pwd.revision == 0) {
3286                                 pwd.revision = 0xfffe;
3287                         }
3288                 }
3289                 error = atasecurity_set_password(device, ccb, retry_count,
3290                                                  timeout, &pwd, quiet);
3291                 if (error != 0) {
3292                         cam_freeccb(ccb);
3293                         free(ident_buf);
3294                         return (error);
3295                 }
3296                 security_enabled = 1;
3297         }
3298
3299         switch(action) {
3300         case ATA_SECURITY_ACTION_FREEZE:
3301                 error = atasecurity_freeze(device, ccb, retry_count,
3302                                            timeout, quiet);
3303                 break;
3304
3305         case ATA_SECURITY_ACTION_UNLOCK:
3306                 if (security_enabled) {
3307                         if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3308                                 error = atasecurity_unlock(device, ccb,
3309                                         retry_count, timeout, &pwd, quiet);
3310                         } else {
3311                                 warnx("Can't unlock, drive is not locked");
3312                                 error = 1;
3313                         }
3314                 } else {
3315                         warnx("Can't unlock, security is disabled");
3316                         error = 1;
3317                 }
3318                 break;
3319
3320         case ATA_SECURITY_ACTION_DISABLE:
3321                 if (security_enabled) {
3322                         /* First unlock the drive if its locked */
3323                         if (ident_buf->security_status & ATA_SECURITY_LOCKED) {
3324                                 error = atasecurity_unlock(device, ccb,
3325                                                            retry_count,
3326                                                            timeout,
3327                                                            &pwd,
3328                                                            quiet);
3329                         }
3330
3331                         if (error == 0) {
3332                                 error = atasecurity_disable(device,
3333                                                             ccb,
3334                                                             retry_count,
3335                                                             timeout,
3336                                                             &pwd,
3337                                                             quiet);
3338                         }
3339                 } else {
3340                         warnx("Can't disable security (already disabled)");
3341                         error = 1;
3342                 }
3343                 break;
3344
3345         case ATA_SECURITY_ACTION_ERASE:
3346                 if (security_enabled) {
3347                         if (erase_timeout == 0) {
3348                                 erase_timeout = atasecurity_erase_timeout_msecs(
3349                                     ident_buf->erase_time);
3350                         }
3351
3352                         error = atasecurity_erase(device, ccb, retry_count,
3353                             timeout, erase_timeout, &pwd, quiet);
3354                 } else {
3355                         warnx("Can't secure erase (security is disabled)");
3356                         error = 1;
3357                 }
3358                 break;
3359
3360         case ATA_SECURITY_ACTION_ERASE_ENHANCED:
3361                 if (security_enabled) {
3362                         if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) {
3363                                 if (erase_timeout == 0) {
3364                                         erase_timeout =
3365                                             atasecurity_erase_timeout_msecs(
3366                                                 ident_buf->enhanced_erase_time);
3367                                 }
3368
3369                                 error = atasecurity_erase(device, ccb,
3370                                                           retry_count, timeout,
3371                                                           erase_timeout, &pwd,
3372                                                           quiet);
3373                         } else {
3374                                 warnx("Enhanced erase is not supported");
3375                                 error = 1;
3376                         }
3377                 } else {
3378                         warnx("Can't secure erase (enhanced), "
3379                               "(security is disabled)");
3380                         error = 1;
3381                 }
3382                 break;
3383         }
3384
3385         cam_freeccb(ccb);
3386         free(ident_buf);
3387
3388         return (error);
3389 }
3390
3391 /*
3392  * Convert periph name into a bus, target and lun.
3393  *
3394  * Returns the number of parsed components, or 0.
3395  */
3396 static int
3397 parse_btl_name(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3398     cam_argmask *arglst)
3399 {
3400         int fd;
3401         union ccb ccb;
3402
3403         bzero(&ccb, sizeof(ccb));
3404         ccb.ccb_h.func_code = XPT_GDEVLIST;
3405         if (cam_get_device(tstr, ccb.cgdl.periph_name,
3406             sizeof(ccb.cgdl.periph_name), &ccb.cgdl.unit_number) == -1) {
3407                 warnx("%s", cam_errbuf);
3408                 return (0);
3409         }
3410
3411         /*
3412          * Attempt to get the passthrough device.  This ioctl will
3413          * fail if the device name is null, if the device doesn't
3414          * exist, or if the passthrough driver isn't in the kernel.
3415          */
3416         if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
3417                 warn("Unable to open %s", XPT_DEVICE);
3418                 return (0);
3419         }
3420         if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) {
3421                 warn("Unable to find bus:target:lun for device %s%d",
3422                     ccb.cgdl.periph_name, ccb.cgdl.unit_number);
3423                 close(fd);
3424                 return (0);
3425         }
3426         close(fd);
3427         if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3428                 const struct cam_status_entry *entry;
3429
3430                 entry = cam_fetch_status_entry(ccb.ccb_h.status);
3431                 warnx("Unable to find bus:target_lun for device %s%d, "
3432                     "CAM status: %s (%#x)",
3433                     ccb.cgdl.periph_name, ccb.cgdl.unit_number,
3434                     entry ? entry->status_text : "Unknown",
3435                     ccb.ccb_h.status);
3436                 return (0);
3437         }
3438
3439         /*
3440          * The kernel fills in the bus/target/lun.  We don't
3441          * need the passthrough device name and unit number since
3442          * we aren't going to open it.
3443          */
3444         *bus = ccb.ccb_h.path_id;
3445         *target = ccb.ccb_h.target_id;
3446         *lun = ccb.ccb_h.target_lun;
3447         *arglst |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN;
3448         return (3);
3449 }
3450
3451 /*
3452  * Parse out a bus, or a bus, target and lun in the following
3453  * format:
3454  * bus
3455  * bus:target
3456  * bus:target:lun
3457  *
3458  * Returns the number of parsed components, or 0.
3459  */
3460 static int
3461 parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun,
3462     cam_argmask *arglst)
3463 {
3464         char *tmpstr, *end;
3465         int convs = 0;
3466
3467         *bus = CAM_BUS_WILDCARD;
3468         *target = CAM_TARGET_WILDCARD;
3469         *lun = CAM_LUN_WILDCARD;
3470
3471         while (isspace(*tstr) && (*tstr != '\0'))
3472                 tstr++;
3473
3474         if (strncasecmp(tstr, "all", strlen("all")) == 0) {
3475                 arglist |= CAM_ARG_BUS;
3476                 return (1);
3477         }
3478
3479         if (!isdigit(*tstr))
3480                 return (parse_btl_name(tstr, bus, target, lun, arglst));
3481
3482         tmpstr = strsep(&tstr, ":");
3483         if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3484                 *bus = strtol(tmpstr, &end, 0);
3485                 if (*end != '\0')
3486                         return (0);
3487                 *arglst |= CAM_ARG_BUS;
3488                 convs++;
3489                 tmpstr = strsep(&tstr, ":");
3490                 if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3491                         *target = strtol(tmpstr, &end, 0);
3492                         if (*end != '\0')
3493                                 return (0);
3494                         *arglst |= CAM_ARG_TARGET;
3495                         convs++;
3496                         tmpstr = strsep(&tstr, ":");
3497                         if ((tmpstr != NULL) && (*tmpstr != '\0')) {
3498                                 *lun = strtoll(tmpstr, &end, 0);
3499                                 if (*end != '\0')
3500                                         return (0);
3501                                 *arglst |= CAM_ARG_LUN;
3502                                 convs++;
3503                         }
3504                 }
3505         }
3506
3507         return convs;
3508 }
3509
3510 static int
3511 dorescan_or_reset(int argc, char **argv, int rescan)
3512 {
3513         static const char must[] =
3514             "you must specify \"all\", a bus, a bus:target:lun or periph to %s";
3515         int rv, error = 0;
3516         path_id_t bus = CAM_BUS_WILDCARD;
3517         target_id_t target = CAM_TARGET_WILDCARD;
3518         lun_id_t lun = CAM_LUN_WILDCARD;
3519         char *tstr;
3520
3521         if (argc < 3) {
3522                 warnx(must, rescan? "rescan" : "reset");
3523                 return (1);
3524         }
3525
3526         tstr = argv[optind];
3527         while (isspace(*tstr) && (*tstr != '\0'))
3528                 tstr++;
3529         if (strncasecmp(tstr, "all", strlen("all")) == 0)
3530                 arglist |= CAM_ARG_BUS;
3531         else {
3532                 rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist);
3533                 if (rv != 1 && rv != 3) {
3534                         warnx(must, rescan ? "rescan" : "reset");
3535                         return (1);
3536                 }
3537         }
3538
3539         if (arglist & CAM_ARG_LUN)
3540                 error = scanlun_or_reset_dev(bus, target, lun, rescan);
3541         else
3542                 error = rescan_or_reset_bus(bus, rescan);
3543
3544         return (error);
3545 }
3546
3547 static int
3548 rescan_or_reset_bus(path_id_t bus, int rescan)
3549 {
3550         union ccb *ccb = NULL, *matchccb = NULL;
3551         int fd = -1, retval;
3552         int bufsize;
3553
3554         retval = 0;
3555
3556         if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3557                 warnx("error opening transport layer device %s", XPT_DEVICE);
3558                 warn("%s", XPT_DEVICE);
3559                 return (1);
3560         }
3561
3562         ccb = malloc(sizeof(*ccb));
3563         if (ccb == NULL) {
3564                 warn("failed to allocate CCB");
3565                 retval = 1;
3566                 goto bailout;
3567         }
3568         bzero(ccb, sizeof(*ccb));
3569
3570         if (bus != CAM_BUS_WILDCARD) {
3571                 ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
3572                 ccb->ccb_h.path_id = bus;
3573                 ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3574                 ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3575                 ccb->crcn.flags = CAM_FLAG_NONE;
3576
3577                 /* run this at a low priority */
3578                 ccb->ccb_h.pinfo.priority = 5;
3579
3580                 if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3581                         warn("CAMIOCOMMAND ioctl failed");
3582                         retval = 1;
3583                         goto bailout;
3584                 }
3585
3586                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3587                         fprintf(stdout, "%s of bus %d was successful\n",
3588                             rescan ? "Re-scan" : "Reset", bus);
3589                 } else {
3590                         fprintf(stdout, "%s of bus %d returned error %#x\n",
3591                                 rescan ? "Re-scan" : "Reset", bus,
3592                                 ccb->ccb_h.status & CAM_STATUS_MASK);
3593                         retval = 1;
3594                 }
3595
3596                 goto bailout;
3597         }
3598
3599
3600         /*
3601          * The right way to handle this is to modify the xpt so that it can
3602          * handle a wildcarded bus in a rescan or reset CCB.  At the moment
3603          * that isn't implemented, so instead we enumerate the buses and
3604          * send the rescan or reset to those buses in the case where the
3605          * given bus is -1 (wildcard).  We don't send a rescan or reset
3606          * to the xpt bus; sending a rescan to the xpt bus is effectively a
3607          * no-op, sending a rescan to the xpt bus would result in a status of
3608          * CAM_REQ_INVALID.
3609          */
3610         matchccb = malloc(sizeof(*matchccb));
3611         if (matchccb == NULL) {
3612                 warn("failed to allocate CCB");
3613                 retval = 1;
3614                 goto bailout;
3615         }
3616         bzero(matchccb, sizeof(*matchccb));
3617         matchccb->ccb_h.func_code = XPT_DEV_MATCH;
3618         matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
3619         bufsize = sizeof(struct dev_match_result) * 20;
3620         matchccb->cdm.match_buf_len = bufsize;
3621         matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
3622         if (matchccb->cdm.matches == NULL) {
3623                 warnx("can't malloc memory for matches");
3624                 retval = 1;
3625                 goto bailout;
3626         }
3627         matchccb->cdm.num_matches = 0;
3628
3629         matchccb->cdm.num_patterns = 1;
3630         matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
3631
3632         matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
3633                 matchccb->cdm.pattern_buf_len);
3634         if (matchccb->cdm.patterns == NULL) {
3635                 warnx("can't malloc memory for patterns");
3636                 retval = 1;
3637                 goto bailout;
3638         }
3639         matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
3640         matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
3641
3642         do {
3643                 unsigned int i;
3644
3645                 if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
3646                         warn("CAMIOCOMMAND ioctl failed");
3647                         retval = 1;
3648                         goto bailout;
3649                 }
3650
3651                 if ((matchccb->ccb_h.status != CAM_REQ_CMP)
3652                  || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
3653                    && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
3654                         warnx("got CAM error %#x, CDM error %d\n",
3655                               matchccb->ccb_h.status, matchccb->cdm.status);
3656                         retval = 1;
3657                         goto bailout;
3658                 }
3659
3660                 for (i = 0; i < matchccb->cdm.num_matches; i++) {
3661                         struct bus_match_result *bus_result;
3662
3663                         /* This shouldn't happen. */
3664                         if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
3665                                 continue;
3666
3667                         bus_result =&matchccb->cdm.matches[i].result.bus_result;
3668
3669                         /*
3670                          * We don't want to rescan or reset the xpt bus.
3671                          * See above.
3672                          */
3673                         if (bus_result->path_id == CAM_XPT_PATH_ID)
3674                                 continue;
3675
3676                         ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
3677                                                        XPT_RESET_BUS;
3678                         ccb->ccb_h.path_id = bus_result->path_id;
3679                         ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
3680                         ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
3681                         ccb->crcn.flags = CAM_FLAG_NONE;
3682
3683                         /* run this at a low priority */
3684                         ccb->ccb_h.pinfo.priority = 5;
3685
3686                         if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
3687                                 warn("CAMIOCOMMAND ioctl failed");
3688                                 retval = 1;
3689                                 goto bailout;
3690                         }
3691
3692                         if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
3693                                 fprintf(stdout, "%s of bus %d was successful\n",
3694                                         rescan? "Re-scan" : "Reset",
3695                                         bus_result->path_id);
3696                         } else {
3697                                 /*
3698                                  * Don't bail out just yet, maybe the other
3699                                  * rescan or reset commands will complete
3700                                  * successfully.
3701                                  */
3702                                 fprintf(stderr, "%s of bus %d returned error "
3703                                         "%#x\n", rescan? "Re-scan" : "Reset",
3704                                         bus_result->path_id,
3705                                         ccb->ccb_h.status & CAM_STATUS_MASK);
3706                                 retval = 1;
3707                         }
3708                 }
3709         } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
3710                  && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
3711
3712 bailout:
3713
3714         if (fd != -1)
3715                 close(fd);
3716
3717         if (matchccb != NULL) {
3718                 free(matchccb->cdm.patterns);
3719                 free(matchccb->cdm.matches);
3720                 free(matchccb);
3721         }
3722         free(ccb);
3723
3724         return (retval);
3725 }
3726
3727 static int
3728 scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan)
3729 {
3730         union ccb ccb;
3731         struct cam_device *device;
3732         int fd;
3733
3734         device = NULL;
3735
3736         if (bus == CAM_BUS_WILDCARD) {
3737                 warnx("invalid bus number %d", bus);
3738                 return (1);
3739         }
3740
3741         if (target == CAM_TARGET_WILDCARD) {
3742                 warnx("invalid target number %d", target);
3743                 return (1);
3744         }
3745
3746         if (lun == CAM_LUN_WILDCARD) {
3747                 warnx("invalid lun number %jx", (uintmax_t)lun);
3748                 return (1);
3749         }
3750
3751         fd = -1;
3752
3753         bzero(&ccb, sizeof(union ccb));
3754
3755         if (scan) {
3756                 if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
3757                         warnx("error opening transport layer device %s\n",
3758                             XPT_DEVICE);
3759                         warn("%s", XPT_DEVICE);
3760                         return (1);
3761                 }
3762         } else {
3763                 device = cam_open_btl(bus, target, lun, O_RDWR, NULL);
3764                 if (device == NULL) {
3765                         warnx("%s", cam_errbuf);
3766                         return (1);
3767                 }
3768         }
3769
3770         ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV;
3771         ccb.ccb_h.path_id = bus;
3772         ccb.ccb_h.target_id = target;
3773         ccb.ccb_h.target_lun = lun;
3774         ccb.ccb_h.timeout = 5000;
3775         ccb.crcn.flags = CAM_FLAG_NONE;
3776
3777         /* run this at a low priority */
3778         ccb.ccb_h.pinfo.priority = 5;
3779
3780         if (scan) {
3781                 if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
3782                         warn("CAMIOCOMMAND ioctl failed");
3783                         close(fd);
3784                         return (1);
3785                 }
3786         } else {
3787                 if (cam_send_ccb(device, &ccb) < 0) {
3788                         warn("error sending XPT_RESET_DEV CCB");
3789                         cam_close_device(device);
3790                         return (1);
3791                 }
3792         }
3793
3794         if (scan)
3795                 close(fd);
3796         else
3797                 cam_close_device(device);
3798
3799         /*
3800          * An error code of CAM_BDR_SENT is normal for a BDR request.
3801          */
3802         if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
3803          || ((!scan)
3804           && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) {
3805                 fprintf(stdout, "%s of %d:%d:%jx was successful\n",
3806                     scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun);
3807                 return (0);
3808         } else {
3809                 fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n",
3810                     scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun,
3811                     ccb.ccb_h.status & CAM_STATUS_MASK);
3812                 return (1);
3813         }
3814 }
3815
3816
3817 static struct scsi_nv defect_list_type_map[] = {
3818         { "block", SRDD10_BLOCK_FORMAT },
3819         { "extbfi", SRDD10_EXT_BFI_FORMAT },
3820         { "extphys", SRDD10_EXT_PHYS_FORMAT },
3821         { "longblock", SRDD10_LONG_BLOCK_FORMAT },
3822         { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT },
3823         { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT }
3824 };
3825
3826 static int
3827 readdefects(struct cam_device *device, int argc, char **argv,
3828             char *combinedopt, int task_attr, int retry_count, int timeout)
3829 {
3830         union ccb *ccb = NULL;
3831         struct scsi_read_defect_data_hdr_10 *hdr10 = NULL;
3832         struct scsi_read_defect_data_hdr_12 *hdr12 = NULL;
3833         size_t hdr_size = 0, entry_size = 0;
3834         int use_12byte = 0;
3835         int hex_format = 0;
3836         u_int8_t *defect_list = NULL;
3837         u_int8_t list_format = 0;
3838         int list_type_set = 0;
3839         u_int32_t dlist_length = 0;
3840         u_int32_t returned_length = 0, valid_len = 0;
3841         u_int32_t num_returned = 0, num_valid = 0;
3842         u_int32_t max_possible_size = 0, hdr_max = 0;
3843         u_int32_t starting_offset = 0;
3844         u_int8_t returned_format, returned_type;
3845         unsigned int i;
3846         int summary = 0, quiet = 0;
3847         int c, error = 0;
3848         int lists_specified = 0;
3849         int get_length = 1, first_pass = 1;
3850         int mads = 0;
3851
3852         while ((c = getopt(argc, argv, combinedopt)) != -1) {
3853                 switch(c){
3854                 case 'f':
3855                 {
3856                         scsi_nv_status status;
3857                         int entry_num = 0;
3858
3859                         status = scsi_get_nv(defect_list_type_map,
3860                             sizeof(defect_list_type_map) /
3861                             sizeof(defect_list_type_map[0]), optarg,
3862                             &entry_num, SCSI_NV_FLAG_IG_CASE);
3863
3864                         if (status == SCSI_NV_FOUND) {
3865                                 list_format = defect_list_type_map[
3866                                     entry_num].value;
3867                                 list_type_set = 1;
3868                         } else {
3869                                 warnx("%s: %s %s option %s", __func__,
3870                                     (status == SCSI_NV_AMBIGUOUS) ?
3871                                     "ambiguous" : "invalid", "defect list type",
3872                                     optarg);
3873                                 error = 1;
3874                                 goto defect_bailout;
3875                         }
3876                         break;
3877                 }
3878                 case 'G':
3879                         arglist |= CAM_ARG_GLIST;
3880                         break;
3881                 case 'P':
3882                         arglist |= CAM_ARG_PLIST;
3883                         break;
3884                 case 'q':
3885                         quiet = 1;
3886                         break;
3887                 case 's':
3888                         summary = 1;
3889                         break;
3890                 case 'S': {
3891                         char *endptr;
3892
3893                         starting_offset = strtoul(optarg, &endptr, 0);
3894                         if (*endptr != '\0') {
3895                                 error = 1;
3896                                 warnx("invalid starting offset %s", optarg);
3897                                 goto defect_bailout;
3898                         }
3899                         break;
3900                 }
3901                 case 'X':
3902                         hex_format = 1;
3903                         break;
3904                 default:
3905                         break;
3906                 }
3907         }
3908
3909         if (list_type_set == 0) {
3910                 error = 1;
3911                 warnx("no defect list format specified");
3912                 goto defect_bailout;
3913         }
3914
3915         if (arglist & CAM_ARG_PLIST) {
3916                 list_format |= SRDD10_PLIST;
3917                 lists_specified++;
3918         }
3919
3920         if (arglist & CAM_ARG_GLIST) {
3921                 list_format |= SRDD10_GLIST;
3922                 lists_specified++;
3923         }
3924
3925         /*
3926          * This implies a summary, and was the previous behavior.
3927          */
3928         if (lists_specified == 0)
3929                 summary = 1;
3930
3931         ccb = cam_getccb(device);
3932
3933 retry_12byte:
3934
3935         /*
3936          * We start off asking for just the header to determine how much
3937          * defect data is available.  Some Hitachi drives return an error
3938          * if you ask for more data than the drive has.  Once we know the
3939          * length, we retry the command with the returned length.
3940          */
3941         if (use_12byte == 0)
3942                 dlist_length = sizeof(*hdr10);
3943         else
3944                 dlist_length = sizeof(*hdr12);
3945
3946 retry:
3947         if (defect_list != NULL) {
3948                 free(defect_list);
3949                 defect_list = NULL;
3950         }
3951         defect_list = malloc(dlist_length);
3952         if (defect_list == NULL) {
3953                 warnx("can't malloc memory for defect list");
3954                 error = 1;
3955                 goto defect_bailout;
3956         }
3957
3958 next_batch:
3959         bzero(defect_list, dlist_length);
3960
3961         /*
3962          * cam_getccb() zeros the CCB header only.  So we need to zero the
3963          * payload portion of the ccb.
3964          */
3965         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
3966
3967         scsi_read_defects(&ccb->csio,
3968                           /*retries*/ retry_count,
3969                           /*cbfcnp*/ NULL,
3970                           /*tag_action*/ task_attr,
3971                           /*list_format*/ list_format,
3972                           /*addr_desc_index*/ starting_offset,
3973                           /*data_ptr*/ defect_list,
3974                           /*dxfer_len*/ dlist_length,
3975                           /*minimum_cmd_size*/ use_12byte ? 12 : 0,
3976                           /*sense_len*/ SSD_FULL_SIZE,
3977                           /*timeout*/ timeout ? timeout : 5000);
3978
3979         /* Disable freezing the device queue */
3980         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
3981
3982         if (cam_send_ccb(device, ccb) < 0) {
3983                 warn("error sending READ DEFECT DATA command");
3984                 error = 1;
3985                 goto defect_bailout;
3986         }
3987
3988         valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
3989
3990         if (use_12byte == 0) {
3991                 hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list;
3992                 hdr_size = sizeof(*hdr10);
3993                 hdr_max = SRDDH10_MAX_LENGTH;
3994
3995                 if (valid_len >= hdr_size) {
3996                         returned_length = scsi_2btoul(hdr10->length);
3997                         returned_format = hdr10->format;
3998                 } else {
3999                         returned_length = 0;
4000                         returned_format = 0;
4001                 }
4002         } else {
4003                 hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list;
4004                 hdr_size = sizeof(*hdr12);
4005                 hdr_max = SRDDH12_MAX_LENGTH;
4006
4007                 if (valid_len >= hdr_size) {
4008                         returned_length = scsi_4btoul(hdr12->length);
4009                         returned_format = hdr12->format;
4010                 } else {
4011                         returned_length = 0;
4012                         returned_format = 0;
4013                 }
4014         }
4015
4016         returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK;
4017         switch (returned_type) {
4018         case SRDD10_BLOCK_FORMAT:
4019                 entry_size = sizeof(struct scsi_defect_desc_block);
4020                 break;
4021         case SRDD10_LONG_BLOCK_FORMAT:
4022                 entry_size = sizeof(struct scsi_defect_desc_long_block);
4023                 break;
4024         case SRDD10_EXT_PHYS_FORMAT:
4025         case SRDD10_PHYSICAL_SECTOR_FORMAT:
4026                 entry_size = sizeof(struct scsi_defect_desc_phys_sector);
4027                 break;
4028         case SRDD10_EXT_BFI_FORMAT:
4029         case SRDD10_BYTES_FROM_INDEX_FORMAT:
4030                 entry_size = sizeof(struct scsi_defect_desc_bytes_from_index);
4031                 break;
4032         default:
4033                 warnx("Unknown defect format 0x%x\n", returned_type);
4034                 error = 1;
4035                 goto defect_bailout;
4036                 break;
4037         }
4038
4039         max_possible_size = (hdr_max / entry_size) * entry_size;
4040         num_returned = returned_length / entry_size;
4041         num_valid = min(returned_length, valid_len - hdr_size);
4042         num_valid /= entry_size;
4043
4044         if (get_length != 0) {
4045                 get_length = 0;
4046
4047                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
4048                      CAM_SCSI_STATUS_ERROR) {
4049                         struct scsi_sense_data *sense;
4050                         int error_code, sense_key, asc, ascq;
4051
4052                         sense = &ccb->csio.sense_data;
4053                         scsi_extract_sense_len(sense, ccb->csio.sense_len -
4054                             ccb->csio.sense_resid, &error_code, &sense_key,
4055                             &asc, &ascq, /*show_errors*/ 1);
4056
4057                         /*
4058                          * If the drive is reporting that it just doesn't
4059                          * support the defect list format, go ahead and use
4060                          * the length it reported.  Otherwise, the length
4061                          * may not be valid, so use the maximum.
4062                          */
4063                         if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4064                          && (asc == 0x1c) && (ascq == 0x00)
4065                          && (returned_length > 0)) {
4066                                 if ((use_12byte == 0)
4067                                  && (returned_length >= max_possible_size)) {
4068                                         get_length = 1;
4069                                         use_12byte = 1;
4070                                         goto retry_12byte;
4071                                 }
4072                                 dlist_length = returned_length + hdr_size;
4073                         } else if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4074                                 && (asc == 0x1f) && (ascq == 0x00)
4075                                 && (returned_length > 0)) {
4076                                 /* Partial defect list transfer */
4077                                 /*
4078                                  * Hitachi drives return this error
4079                                  * along with a partial defect list if they
4080                                  * have more defects than the 10 byte
4081                                  * command can support.  Retry with the 12
4082                                  * byte command.
4083                                  */
4084                                 if (use_12byte == 0) {
4085                                         get_length = 1;
4086                                         use_12byte = 1;
4087                                         goto retry_12byte;
4088                                 }
4089                                 dlist_length = returned_length + hdr_size;
4090                         } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST)
4091                                 && (asc == 0x24) && (ascq == 0x00)) {
4092                                 /* Invalid field in CDB */
4093                                 /*
4094                                  * SBC-3 says that if the drive has more
4095                                  * defects than can be reported with the
4096                                  * 10 byte command, it should return this
4097                                  * error and no data.  Retry with the 12
4098                                  * byte command.
4099                                  */
4100                                 if (use_12byte == 0) {
4101                                         get_length = 1;
4102                                         use_12byte = 1;
4103                                         goto retry_12byte;
4104                                 }
4105                                 dlist_length = returned_length + hdr_size;
4106                         } else {
4107                                 /*
4108                                  * If we got a SCSI error and no valid length,
4109                                  * just use the 10 byte maximum.  The 12
4110                                  * byte maximum is too large.
4111                                  */
4112                                 if (returned_length == 0)
4113                                         dlist_length = SRDD10_MAX_LENGTH;
4114                                 else {
4115                                         if ((use_12byte == 0)
4116                                          && (returned_length >=
4117                                              max_possible_size)) {
4118                                                 get_length = 1;
4119                                                 use_12byte = 1;
4120                                                 goto retry_12byte;
4121                                         }
4122                                         dlist_length = returned_length +
4123                                             hdr_size;
4124                                 }
4125                         }
4126                 } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) !=
4127                             CAM_REQ_CMP){
4128                         error = 1;
4129                         warnx("Error reading defect header");
4130                         if (arglist & CAM_ARG_VERBOSE)
4131                                 cam_error_print(device, ccb, CAM_ESF_ALL,
4132                                                 CAM_EPF_ALL, stderr);
4133                         goto defect_bailout;
4134                 } else {
4135                         if ((use_12byte == 0)
4136                          && (returned_length >= max_possible_size)) {
4137                                 get_length = 1;
4138                                 use_12byte = 1;
4139                                 goto retry_12byte;
4140                         }
4141                         dlist_length = returned_length + hdr_size;
4142                 }
4143                 if (summary != 0) {
4144                         fprintf(stdout, "%u", num_returned);
4145                         if (quiet == 0) {
4146                                 fprintf(stdout, " defect%s",
4147                                         (num_returned != 1) ? "s" : "");
4148                         }
4149                         fprintf(stdout, "\n");
4150
4151                         goto defect_bailout;
4152                 }
4153
4154                 /*
4155                  * We always limit the list length to the 10-byte maximum
4156                  * length (0xffff).  The reason is that some controllers
4157                  * can't handle larger I/Os, and we can transfer the entire
4158                  * 10 byte list in one shot.  For drives that support the 12
4159                  * byte read defects command, we'll step through the list
4160                  * by specifying a starting offset.  For drives that don't
4161                  * support the 12 byte command's starting offset, we'll
4162                  * just display the first 64K.
4163                  */
4164                 dlist_length = min(dlist_length, SRDD10_MAX_LENGTH);
4165
4166                 goto retry;
4167         }
4168
4169
4170         if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)
4171          && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
4172          && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
4173                 struct scsi_sense_data *sense;
4174                 int error_code, sense_key, asc, ascq;
4175
4176                 sense = &ccb->csio.sense_data;
4177                 scsi_extract_sense_len(sense, ccb->csio.sense_len -
4178                     ccb->csio.sense_resid, &error_code, &sense_key, &asc,
4179                     &ascq, /*show_errors*/ 1);
4180
4181                 /*
4182                  * According to the SCSI spec, if the disk doesn't support
4183                  * the requested format, it will generally return a sense
4184                  * key of RECOVERED ERROR, and an additional sense code
4185                  * of "DEFECT LIST NOT FOUND".  HGST drives also return
4186                  * Primary/Grown defect list not found errors.  So just
4187                  * check for an ASC of 0x1c.
4188                  */
4189                 if ((sense_key == SSD_KEY_RECOVERED_ERROR)
4190                  && (asc == 0x1c)) {
4191                         const char *format_str;
4192
4193                         format_str = scsi_nv_to_str(defect_list_type_map,
4194                             sizeof(defect_list_type_map) /
4195                             sizeof(defect_list_type_map[0]),
4196                             list_format & SRDD10_DLIST_FORMAT_MASK);
4197                         warnx("requested defect format %s not available",
4198                             format_str ? format_str : "unknown");
4199
4200                         format_str = scsi_nv_to_str(defect_list_type_map,
4201                             sizeof(defect_list_type_map) /
4202                             sizeof(defect_list_type_map[0]), returned_type);
4203                         if (format_str != NULL) {
4204                                 warnx("Device returned %s format",
4205                                     format_str);
4206                         } else {
4207                                 error = 1;
4208                                 warnx("Device returned unknown defect"
4209                                      " data format %#x", returned_type);
4210                                 goto defect_bailout;
4211                         }
4212                 } else {
4213                         error = 1;
4214                         warnx("Error returned from read defect data command");
4215                         if (arglist & CAM_ARG_VERBOSE)
4216                                 cam_error_print(device, ccb, CAM_ESF_ALL,
4217                                                 CAM_EPF_ALL, stderr);
4218                         goto defect_bailout;
4219                 }
4220         } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4221                 error = 1;
4222                 warnx("Error returned from read defect data command");
4223                 if (arglist & CAM_ARG_VERBOSE)
4224                         cam_error_print(device, ccb, CAM_ESF_ALL,
4225                                         CAM_EPF_ALL, stderr);
4226                 goto defect_bailout;
4227         }
4228
4229         if (first_pass != 0) {
4230                 fprintf(stderr, "Got %d defect", num_returned);
4231
4232                 if ((lists_specified == 0) || (num_returned == 0)) {
4233                         fprintf(stderr, "s.\n");
4234                         goto defect_bailout;
4235                 } else if (num_returned == 1)
4236                         fprintf(stderr, ":\n");
4237                 else
4238                         fprintf(stderr, "s:\n");
4239
4240                 first_pass = 0;
4241         }
4242
4243         /*
4244          * XXX KDM  I should probably clean up the printout format for the
4245          * disk defects.
4246          */
4247         switch (returned_type) {
4248         case SRDD10_PHYSICAL_SECTOR_FORMAT:
4249         case SRDD10_EXT_PHYS_FORMAT:
4250         {
4251                 struct scsi_defect_desc_phys_sector *dlist;
4252
4253                 dlist = (struct scsi_defect_desc_phys_sector *)
4254                         (defect_list + hdr_size);
4255
4256                 for (i = 0; i < num_valid; i++) {
4257                         uint32_t sector;
4258
4259                         sector = scsi_4btoul(dlist[i].sector);
4260                         if (returned_type == SRDD10_EXT_PHYS_FORMAT) {
4261                                 mads = (sector & SDD_EXT_PHYS_MADS) ?
4262                                        0 : 1;
4263                                 sector &= ~SDD_EXT_PHYS_FLAG_MASK;
4264                         }
4265                         if (hex_format == 0)
4266                                 fprintf(stdout, "%d:%d:%d%s",
4267                                         scsi_3btoul(dlist[i].cylinder),
4268                                         dlist[i].head,
4269                                         scsi_4btoul(dlist[i].sector),
4270                                         mads ? " - " : "\n");
4271                         else
4272                                 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4273                                         scsi_3btoul(dlist[i].cylinder),
4274                                         dlist[i].head,
4275                                         scsi_4btoul(dlist[i].sector),
4276                                         mads ? " - " : "\n");
4277                         mads = 0;
4278                 }
4279                 if (num_valid < num_returned) {
4280                         starting_offset += num_valid;
4281                         goto next_batch;
4282                 }
4283                 break;
4284         }
4285         case SRDD10_BYTES_FROM_INDEX_FORMAT:
4286         case SRDD10_EXT_BFI_FORMAT:
4287         {
4288                 struct scsi_defect_desc_bytes_from_index *dlist;
4289
4290                 dlist = (struct scsi_defect_desc_bytes_from_index *)
4291                         (defect_list + hdr_size);
4292
4293                 for (i = 0; i < num_valid; i++) {
4294                         uint32_t bfi;
4295
4296                         bfi = scsi_4btoul(dlist[i].bytes_from_index);
4297                         if (returned_type == SRDD10_EXT_BFI_FORMAT) {
4298                                 mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0;
4299                                 bfi &= ~SDD_EXT_BFI_FLAG_MASK;
4300                         }
4301                         if (hex_format == 0)
4302                                 fprintf(stdout, "%d:%d:%d%s",
4303                                         scsi_3btoul(dlist[i].cylinder),
4304                                         dlist[i].head,
4305                                         scsi_4btoul(dlist[i].bytes_from_index),
4306                                         mads ? " - " : "\n");
4307                         else
4308                                 fprintf(stdout, "0x%x:0x%x:0x%x%s",
4309                                         scsi_3btoul(dlist[i].cylinder),
4310                                         dlist[i].head,
4311                                         scsi_4btoul(dlist[i].bytes_from_index),
4312                                         mads ? " - " : "\n");
4313
4314                         mads = 0;
4315                 }
4316                 if (num_valid < num_returned) {
4317                         starting_offset += num_valid;
4318                         goto next_batch;
4319                 }
4320                 break;
4321         }
4322         case SRDDH10_BLOCK_FORMAT:
4323         {
4324                 struct scsi_defect_desc_block *dlist;
4325
4326                 dlist = (struct scsi_defect_desc_block *)
4327                         (defect_list + hdr_size);
4328
4329                 for (i = 0; i < num_valid; i++) {
4330                         if (hex_format == 0)
4331                                 fprintf(stdout, "%u\n",
4332                                         scsi_4btoul(dlist[i].address));
4333                         else
4334                                 fprintf(stdout, "0x%x\n",
4335                                         scsi_4btoul(dlist[i].address));
4336                 }
4337
4338                 if (num_valid < num_returned) {
4339                         starting_offset += num_valid;
4340                         goto next_batch;
4341                 }
4342
4343                 break;
4344         }
4345         case SRDD10_LONG_BLOCK_FORMAT:
4346         {
4347                 struct scsi_defect_desc_long_block *dlist;
4348
4349                 dlist = (struct scsi_defect_desc_long_block *)
4350                         (defect_list + hdr_size);
4351
4352                 for (i = 0; i < num_valid; i++) {
4353                         if (hex_format == 0)
4354                                 fprintf(stdout, "%ju\n",
4355                                         (uintmax_t)scsi_8btou64(
4356                                         dlist[i].address));
4357                         else
4358                                 fprintf(stdout, "0x%jx\n",
4359                                         (uintmax_t)scsi_8btou64(
4360                                         dlist[i].address));
4361                 }
4362
4363                 if (num_valid < num_returned) {
4364                         starting_offset += num_valid;
4365                         goto next_batch;
4366                 }
4367                 break;
4368         }
4369         default:
4370                 fprintf(stderr, "Unknown defect format 0x%x\n",
4371                         returned_type);
4372                 error = 1;
4373                 break;
4374         }
4375 defect_bailout:
4376
4377         if (defect_list != NULL)
4378                 free(defect_list);
4379
4380         if (ccb != NULL)
4381                 cam_freeccb(ccb);
4382
4383         return (error);
4384 }
4385
4386 #if 0
4387 void
4388 reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks)
4389 {
4390         union ccb *ccb;
4391
4392         ccb = cam_getccb(device);
4393
4394         cam_freeccb(ccb);
4395 }
4396 #endif
4397
4398 void
4399 mode_sense(struct cam_device *device, int *cdb_len, int dbd, int llbaa, int pc,
4400     int page, int subpage, int task_attr, int retry_count, int timeout,
4401     u_int8_t *data, int datalen)
4402 {
4403         union ccb *ccb;
4404         int error_code, sense_key, asc, ascq;
4405
4406         ccb = cam_getccb(device);
4407         if (ccb == NULL)
4408                 errx(1, "mode_sense: couldn't allocate CCB");
4409
4410 retry:
4411         /*
4412          * MODE SENSE(6) can't handle more then 255 bytes.  If there are more,
4413          * device must return error, so we should not get trucated data.
4414          */
4415         if (*cdb_len == 6 && datalen > 255)
4416                 datalen = 255;
4417
4418         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4419
4420         scsi_mode_sense_subpage(&ccb->csio,
4421                         /* retries */ retry_count,
4422                         /* cbfcnp */ NULL,
4423                         /* tag_action */ task_attr,
4424                         /* dbd */ dbd,
4425                         /* pc */ pc << 6,
4426                         /* page */ page,
4427                         /* subpage */ subpage,
4428                         /* param_buf */ data,
4429                         /* param_len */ datalen,
4430                         /* minimum_cmd_size */ *cdb_len,
4431                         /* sense_len */ SSD_FULL_SIZE,
4432                         /* timeout */ timeout ? timeout : 5000);
4433         if (llbaa && ccb->csio.cdb_len == 10) {
4434                 struct scsi_mode_sense_10 *cdb =
4435                     (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes;
4436                 cdb->byte2 |= SMS10_LLBAA;
4437         }
4438
4439         /* Record what CDB size the above function really set. */
4440         *cdb_len = ccb->csio.cdb_len;
4441
4442         if (arglist & CAM_ARG_ERR_RECOVER)
4443                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4444
4445         /* Disable freezing the device queue */
4446         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4447
4448         if (cam_send_ccb(device, ccb) < 0)
4449                 err(1, "error sending mode sense command");
4450
4451         /* In case of ILLEGEL REQUEST try to fall back to 6-byte command. */
4452         if (*cdb_len != 6 &&
4453             ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID ||
4454              (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)
4455               && sense_key == SSD_KEY_ILLEGAL_REQUEST))) {
4456                 *cdb_len = 6;
4457                 goto retry;
4458         }
4459
4460         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
4461                 if (arglist & CAM_ARG_VERBOSE) {
4462                         cam_error_print(device, ccb, CAM_ESF_ALL,
4463                                         CAM_EPF_ALL, stderr);
4464                 }
4465                 cam_freeccb(ccb);
4466                 cam_close_device(device);
4467                 errx(1, "mode sense command returned error");
4468         }
4469
4470         cam_freeccb(ccb);
4471 }
4472
4473 void
4474 mode_select(struct cam_device *device, int cdb_len, int save_pages,
4475     int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen)
4476 {
4477         union ccb *ccb;
4478         int retval;
4479
4480         ccb = cam_getccb(device);
4481
4482         if (ccb == NULL)
4483                 errx(1, "mode_select: couldn't allocate CCB");
4484
4485         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
4486
4487         scsi_mode_select_len(&ccb->csio,
4488                          /* retries */ retry_count,
4489                          /* cbfcnp */ NULL,
4490                          /* tag_action */ task_attr,
4491                          /* scsi_page_fmt */ 1,
4492                          /* save_pages */ save_pages,
4493                          /* param_buf */ data,
4494                          /* param_len */ datalen,
4495                          /* minimum_cmd_size */ cdb_len,
4496                          /* sense_len */ SSD_FULL_SIZE,
4497                          /* timeout */ timeout ? timeout : 5000);
4498
4499         if (arglist & CAM_ARG_ERR_RECOVER)
4500                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
4501
4502         /* Disable freezing the device queue */
4503         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
4504
4505         if (((retval = cam_send_ccb(device, ccb)) < 0)
4506          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4507                 if (arglist & CAM_ARG_VERBOSE) {
4508                         cam_error_print(device, ccb, CAM_ESF_ALL,
4509                                         CAM_EPF_ALL, stderr);
4510                 }
4511                 cam_freeccb(ccb);
4512                 cam_close_device(device);
4513
4514                 if (retval < 0)
4515                         err(1, "error sending mode select command");
4516                 else
4517                         errx(1, "error sending mode select command");
4518
4519         }
4520
4521         cam_freeccb(ccb);
4522 }
4523
4524 void
4525 modepage(struct cam_device *device, int argc, char **argv, char *combinedopt,
4526          int task_attr, int retry_count, int timeout)
4527 {
4528         char *str_subpage;
4529         int c, page = -1, subpage = 0, pc = 0, llbaa = 0;
4530         int binary = 0, cdb_len = 10, dbd = 0, desc = 0, edit = 0, list = 0;
4531
4532         while ((c = getopt(argc, argv, combinedopt)) != -1) {
4533                 switch(c) {
4534                 case '6':
4535                         cdb_len = 6;
4536                         break;
4537                 case 'b':
4538                         binary = 1;
4539                         break;
4540                 case 'd':
4541                         dbd = 1;
4542                         break;
4543                 case 'e':
4544                         edit = 1;
4545                         break;
4546                 case 'l':
4547                         list++;
4548                         break;
4549                 case 'm':
4550                         str_subpage = optarg;
4551                         strsep(&str_subpage, ",");
4552                         page = strtol(optarg, NULL, 0);
4553                         if (str_subpage)
4554                             subpage = strtol(str_subpage, NULL, 0);
4555                         if (page < 0 || page > 0x3f)
4556                                 errx(1, "invalid mode page %d", page);
4557                         if (subpage < 0 || subpage > 0xff)
4558                                 errx(1, "invalid mode subpage %d", subpage);
4559                         break;
4560                 case 'D':
4561                         desc = 1;
4562                         break;
4563                 case 'L':
4564                         llbaa = 1;
4565                         break;
4566                 case 'P':
4567                         pc = strtol(optarg, NULL, 0);
4568                         if ((pc < 0) || (pc > 3))
4569                                 errx(1, "invalid page control field %d", pc);
4570                         break;
4571                 default:
4572                         break;
4573                 }
4574         }
4575
4576         if (desc && page == -1)
4577                 page = SMS_ALL_PAGES_PAGE;
4578
4579         if (page == -1 && list == 0)
4580                 errx(1, "you must specify a mode page!");
4581
4582         if (dbd && desc)
4583                 errx(1, "-d and -D are incompatible!");
4584
4585         if (llbaa && cdb_len != 10)
4586                 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4587
4588         if (list != 0) {
4589                 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4590                     retry_count, timeout);
4591         } else {
4592                 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4593                     edit, binary, task_attr, retry_count, timeout);
4594         }
4595 }
4596
4597 static int
4598 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4599         int task_attr, int retry_count, int timeout)
4600 {
4601         union ccb *ccb;
4602         u_int32_t flags = CAM_DIR_NONE;
4603         u_int8_t *data_ptr = NULL;
4604         u_int8_t cdb[20];
4605         u_int8_t atacmd[12];
4606         struct get_hook hook;
4607         int c, data_bytes = 0, valid_bytes;
4608         int cdb_len = 0;
4609         int atacmd_len = 0;
4610         int dmacmd = 0;
4611         int fpdmacmd = 0;
4612         int need_res = 0;
4613         char *datastr = NULL, *tstr, *resstr = NULL;
4614         int error = 0;
4615         int fd_data = 0, fd_res = 0;
4616         int retval;
4617
4618         ccb = cam_getccb(device);
4619
4620         if (ccb == NULL) {
4621                 warnx("scsicmd: error allocating ccb");
4622                 return (1);
4623         }
4624
4625         CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4626
4627         while ((c = getopt(argc, argv, combinedopt)) != -1) {
4628                 switch(c) {
4629                 case 'a':
4630                         tstr = optarg;
4631                         while (isspace(*tstr) && (*tstr != '\0'))
4632                                 tstr++;
4633                         hook.argc = argc - optind;
4634                         hook.argv = argv + optind;
4635                         hook.got = 0;
4636                         atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4637                                                     iget, &hook);
4638                         /*
4639                          * Increment optind by the number of arguments the
4640                          * encoding routine processed.  After each call to
4641                          * getopt(3), optind points to the argument that
4642                          * getopt should process _next_.  In this case,
4643                          * that means it points to the first command string
4644                          * argument, if there is one.  Once we increment
4645                          * this, it should point to either the next command
4646                          * line argument, or it should be past the end of
4647                          * the list.
4648                          */
4649                         optind += hook.got;
4650                         break;
4651                 case 'c':
4652                         tstr = optarg;
4653                         while (isspace(*tstr) && (*tstr != '\0'))
4654                                 tstr++;
4655                         hook.argc = argc - optind;
4656                         hook.argv = argv + optind;
4657                         hook.got = 0;
4658                         cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4659                                                     iget, &hook);
4660                         /*
4661                          * Increment optind by the number of arguments the
4662                          * encoding routine processed.  After each call to
4663                          * getopt(3), optind points to the argument that
4664                          * getopt should process _next_.  In this case,
4665                          * that means it points to the first command string
4666                          * argument, if there is one.  Once we increment
4667                          * this, it should point to either the next command
4668                          * line argument, or it should be past the end of
4669                          * the list.
4670                          */
4671                         optind += hook.got;
4672                         break;
4673                 case 'd':
4674                         dmacmd = 1;
4675                         break;
4676                 case 'f':
4677                         fpdmacmd = 1;
4678                         break;
4679                 case 'i':
4680                         if (arglist & CAM_ARG_CMD_OUT) {
4681                                 warnx("command must either be "
4682                                       "read or write, not both");
4683                                 error = 1;
4684                                 goto scsicmd_bailout;
4685                         }
4686                         arglist |= CAM_ARG_CMD_IN;
4687                         flags = CAM_DIR_IN;
4688                         data_bytes = strtol(optarg, NULL, 0);
4689                         if (data_bytes <= 0) {
4690                                 warnx("invalid number of input bytes %d",
4691                                       data_bytes);
4692                                 error = 1;
4693                                 goto scsicmd_bailout;
4694                         }
4695                         hook.argc = argc - optind;
4696                         hook.argv = argv + optind;
4697                         hook.got = 0;
4698                         optind++;
4699                         datastr = cget(&hook, NULL);
4700                         /*
4701                          * If the user supplied "-" instead of a format, he
4702                          * wants the data to be written to stdout.
4703                          */
4704                         if ((datastr != NULL)
4705                          && (datastr[0] == '-'))
4706                                 fd_data = 1;
4707
4708                         data_ptr = (u_int8_t *)malloc(data_bytes);
4709                         if (data_ptr == NULL) {
4710                                 warnx("can't malloc memory for data_ptr");
4711                                 error = 1;
4712                                 goto scsicmd_bailout;
4713                         }
4714                         break;
4715                 case 'o':
4716                         if (arglist & CAM_ARG_CMD_IN) {
4717                                 warnx("command must either be "
4718                                       "read or write, not both");
4719                                 error = 1;
4720                                 goto scsicmd_bailout;
4721                         }
4722                         arglist |= CAM_ARG_CMD_OUT;
4723                         flags = CAM_DIR_OUT;
4724                         data_bytes = strtol(optarg, NULL, 0);
4725                         if (data_bytes <= 0) {
4726                                 warnx("invalid number of output bytes %d",
4727                                       data_bytes);
4728                                 error = 1;
4729                                 goto scsicmd_bailout;
4730                         }
4731                         hook.argc = argc - optind;
4732                         hook.argv = argv + optind;
4733                         hook.got = 0;
4734                         datastr = cget(&hook, NULL);
4735                         data_ptr = (u_int8_t *)malloc(data_bytes);
4736                         if (data_ptr == NULL) {
4737                                 warnx("can't malloc memory for data_ptr");
4738                                 error = 1;
4739                                 goto scsicmd_bailout;
4740                         }
4741                         bzero(data_ptr, data_bytes);
4742                         /*
4743                          * If the user supplied "-" instead of a format, he
4744                          * wants the data to be read from stdin.
4745                          */
4746                         if ((datastr != NULL)
4747                          && (datastr[0] == '-'))
4748                                 fd_data = 1;
4749                         else
4750                                 buff_encode_visit(data_ptr, data_bytes, datastr,
4751                                                   iget, &hook);
4752                         optind += hook.got;
4753                         break;
4754                 case 'r':
4755                         need_res = 1;
4756                         hook.argc = argc - optind;
4757                         hook.argv = argv + optind;
4758                         hook.got = 0;
4759                         resstr = cget(&hook, NULL);
4760                         if ((resstr != NULL) && (resstr[0] == '-'))
4761                                 fd_res = 1;
4762                         optind += hook.got;
4763                         break;
4764                 default:
4765                         break;
4766                 }
4767         }
4768
4769         /*
4770          * If fd_data is set, and we're writing to the device, we need to
4771          * read the data the user wants written from stdin.
4772          */
4773         if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4774                 ssize_t amt_read;
4775                 int amt_to_read = data_bytes;
4776                 u_int8_t *buf_ptr = data_ptr;
4777
4778                 for (amt_read = 0; amt_to_read > 0;
4779                      amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4780                         if (amt_read == -1) {
4781                                 warn("error reading data from stdin");
4782                                 error = 1;
4783                                 goto scsicmd_bailout;
4784                         }
4785                         amt_to_read -= amt_read;
4786                         buf_ptr += amt_read;
4787                 }
4788         }
4789
4790         if (arglist & CAM_ARG_ERR_RECOVER)
4791                 flags |= CAM_PASS_ERR_RECOVER;
4792
4793         /* Disable freezing the device queue */
4794         flags |= CAM_DEV_QFRZDIS;
4795
4796         if (cdb_len) {
4797                 /*
4798                  * This is taken from the SCSI-3 draft spec.
4799                  * (T10/1157D revision 0.3)
4800                  * The top 3 bits of an opcode are the group code.
4801                  * The next 5 bits are the command code.
4802                  * Group 0:  six byte commands
4803                  * Group 1:  ten byte commands
4804                  * Group 2:  ten byte commands
4805                  * Group 3:  reserved
4806                  * Group 4:  sixteen byte commands
4807                  * Group 5:  twelve byte commands
4808                  * Group 6:  vendor specific
4809                  * Group 7:  vendor specific
4810                  */
4811                 switch((cdb[0] >> 5) & 0x7) {
4812                         case 0:
4813                                 cdb_len = 6;
4814                                 break;
4815                         case 1:
4816                         case 2:
4817                                 cdb_len = 10;
4818                                 break;
4819                         case 3:
4820                         case 6:
4821                         case 7:
4822                                 /* computed by buff_encode_visit */
4823                                 break;
4824                         case 4:
4825                                 cdb_len = 16;
4826                                 break;
4827                         case 5:
4828                                 cdb_len = 12;
4829                                 break;
4830                 }
4831
4832                 /*
4833                  * We should probably use csio_build_visit or something like that
4834                  * here, but it's easier to encode arguments as you go.  The
4835                  * alternative would be skipping the CDB argument and then encoding
4836                  * it here, since we've got the data buffer argument by now.
4837                  */
4838                 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4839
4840                 cam_fill_csio(&ccb->csio,
4841                       /*retries*/ retry_count,
4842                       /*cbfcnp*/ NULL,
4843                       /*flags*/ flags,
4844                       /*tag_action*/ task_attr,
4845                       /*data_ptr*/ data_ptr,
4846                       /*dxfer_len*/ data_bytes,
4847                       /*sense_len*/ SSD_FULL_SIZE,
4848                       /*cdb_len*/ cdb_len,
4849                       /*timeout*/ timeout ? timeout : 5000);
4850         } else {
4851                 atacmd_len = 12;
4852                 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4853                 if (need_res)
4854                         ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4855                 if (dmacmd)
4856                         ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4857                 if (fpdmacmd)
4858                         ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4859
4860                 cam_fill_ataio(&ccb->ataio,
4861                       /*retries*/ retry_count,
4862                       /*cbfcnp*/ NULL,
4863                       /*flags*/ flags,
4864                       /*tag_action*/ 0,
4865                       /*data_ptr*/ data_ptr,
4866                       /*dxfer_len*/ data_bytes,
4867                       /*timeout*/ timeout ? timeout : 5000);
4868         }
4869
4870         if (((retval = cam_send_ccb(device, ccb)) < 0)
4871          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4872                 const char warnstr[] = "error sending command";
4873
4874                 if (retval < 0)
4875                         warn(warnstr);
4876                 else
4877                         warnx(warnstr);
4878
4879                 if (arglist & CAM_ARG_VERBOSE) {
4880                         cam_error_print(device, ccb, CAM_ESF_ALL,
4881                                         CAM_EPF_ALL, stderr);
4882                 }
4883
4884                 error = 1;
4885                 goto scsicmd_bailout;
4886         }
4887
4888         if (atacmd_len && need_res) {
4889                 if (fd_res == 0) {
4890                         buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4891                                           arg_put, NULL);
4892                         fprintf(stdout, "\n");
4893                 } else {
4894                         fprintf(stdout,
4895                             "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4896                             ccb->ataio.res.status,
4897                             ccb->ataio.res.error,
4898                             ccb->ataio.res.lba_low,
4899                             ccb->ataio.res.lba_mid,
4900                             ccb->ataio.res.lba_high,
4901                             ccb->ataio.res.device,
4902                             ccb->ataio.res.lba_low_exp,
4903                             ccb->ataio.res.lba_mid_exp,
4904                             ccb->ataio.res.lba_high_exp,
4905                             ccb->ataio.res.sector_count,
4906                             ccb->ataio.res.sector_count_exp);
4907                         fflush(stdout);
4908                 }
4909         }
4910
4911         if (cdb_len)
4912                 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4913         else
4914                 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4915         if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4916          && (arglist & CAM_ARG_CMD_IN)
4917          && (valid_bytes > 0)) {
4918                 if (fd_data == 0) {
4919                         buff_decode_visit(data_ptr, valid_bytes, datastr,
4920                                           arg_put, NULL);
4921                         fprintf(stdout, "\n");
4922                 } else {
4923                         ssize_t amt_written;
4924                         int amt_to_write = valid_bytes;
4925                         u_int8_t *buf_ptr = data_ptr;
4926
4927                         for (amt_written = 0; (amt_to_write > 0) &&
4928                              (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4929                                 amt_to_write -= amt_written;
4930                                 buf_ptr += amt_written;
4931                         }
4932                         if (amt_written == -1) {
4933                                 warn("error writing data to stdout");
4934                                 error = 1;
4935                                 goto scsicmd_bailout;
4936                         } else if ((amt_written == 0)
4937                                 && (amt_to_write > 0)) {
4938                                 warnx("only wrote %u bytes out of %u",
4939                                       valid_bytes - amt_to_write, valid_bytes);
4940                         }
4941                 }
4942         }
4943
4944 scsicmd_bailout:
4945
4946         if ((data_bytes > 0) && (data_ptr != NULL))
4947                 free(data_ptr);
4948
4949         cam_freeccb(ccb);
4950
4951         return (error);
4952 }
4953
4954 static int
4955 camdebug(int argc, char **argv, char *combinedopt)
4956 {
4957         int c, fd;
4958         path_id_t bus = CAM_BUS_WILDCARD;
4959         target_id_t target = CAM_TARGET_WILDCARD;
4960         lun_id_t lun = CAM_LUN_WILDCARD;
4961         char *tstr;
4962         union ccb ccb;
4963         int error = 0, rv;
4964
4965         bzero(&ccb, sizeof(union ccb));
4966
4967         while ((c = getopt(argc, argv, combinedopt)) != -1) {
4968                 switch(c) {
4969                 case 'I':
4970                         arglist |= CAM_ARG_DEBUG_INFO;
4971                         ccb.cdbg.flags |= CAM_DEBUG_INFO;
4972                         break;
4973                 case 'P':
4974                         arglist |= CAM_ARG_DEBUG_PERIPH;
4975                         ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4976                         break;
4977                 case 'S':
4978                         arglist |= CAM_ARG_DEBUG_SUBTRACE;
4979                         ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
4980                         break;
4981                 case 'T':
4982                         arglist |= CAM_ARG_DEBUG_TRACE;
4983                         ccb.cdbg.flags |= CAM_DEBUG_TRACE;
4984                         break;
4985                 case 'X':
4986                         arglist |= CAM_ARG_DEBUG_XPT;
4987                         ccb.cdbg.flags |= CAM_DEBUG_XPT;
4988                         break;
4989                 case 'c':
4990                         arglist |= CAM_ARG_DEBUG_CDB;
4991                         ccb.cdbg.flags |= CAM_DEBUG_CDB;
4992                         break;
4993                 case 'p':
4994                         arglist |= CAM_ARG_DEBUG_PROBE;
4995                         ccb.cdbg.flags |= CAM_DEBUG_PROBE;
4996                         break;
4997                 default:
4998                         break;
4999                 }
5000         }
5001
5002         argc -= optind;
5003         argv += optind;
5004
5005         if (argc <= 0) {
5006                 warnx("you must specify \"off\", \"all\" or a bus,");
5007                 warnx("bus:target, bus:target:lun or periph");
5008                 return (1);
5009         }
5010
5011         tstr = *argv;
5012         while (isspace(*tstr) && (*tstr != '\0'))
5013                 tstr++;
5014
5015         if (strncmp(tstr, "off", 3) == 0) {
5016                 ccb.cdbg.flags = CAM_DEBUG_NONE;
5017                 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5018                              CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5019                              CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5020         } else {
5021                 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5022                 if (rv < 1) {
5023                         warnx("you must specify \"all\", \"off\", or a bus,");
5024                         warnx("bus:target, bus:target:lun or periph to debug");
5025                         return (1);
5026                 }
5027         }
5028
5029         if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5030                 warnx("error opening transport layer device %s", XPT_DEVICE);
5031                 warn("%s", XPT_DEVICE);
5032                 return (1);
5033         }
5034
5035         ccb.ccb_h.func_code = XPT_DEBUG;
5036         ccb.ccb_h.path_id = bus;
5037         ccb.ccb_h.target_id = target;
5038         ccb.ccb_h.target_lun = lun;
5039
5040         if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5041                 warn("CAMIOCOMMAND ioctl failed");
5042                 error = 1;
5043         } else {
5044                 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5045                      CAM_FUNC_NOTAVAIL) {
5046                         warnx("CAM debugging not available");
5047                         warnx("you need to put options CAMDEBUG in"
5048                               " your kernel config file!");
5049                         error = 1;
5050                 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5051                             CAM_REQ_CMP) {
5052                         warnx("XPT_DEBUG CCB failed with status %#x",
5053                               ccb.ccb_h.status);
5054                         error = 1;
5055                 } else {
5056                         if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5057                                 fprintf(stderr,
5058                                         "Debugging turned off\n");
5059                         } else {
5060                                 fprintf(stderr,
5061                                         "Debugging enabled for "
5062                                         "%d:%d:%jx\n",
5063                                         bus, target, (uintmax_t)lun);
5064                         }
5065                 }
5066         }
5067         close(fd);
5068
5069         return (error);
5070 }
5071
5072 static int
5073 tagcontrol(struct cam_device *device, int argc, char **argv,
5074            char *combinedopt)
5075 {
5076         int c;
5077         union ccb *ccb;
5078         int numtags = -1;
5079         int retval = 0;
5080         int quiet = 0;
5081         char pathstr[1024];
5082
5083         ccb = cam_getccb(device);
5084
5085         if (ccb == NULL) {
5086                 warnx("tagcontrol: error allocating ccb");
5087                 return (1);
5088         }
5089
5090         while ((c = getopt(argc, argv, combinedopt)) != -1) {
5091                 switch(c) {
5092                 case 'N':
5093                         numtags = strtol(optarg, NULL, 0);
5094                         if (numtags < 0) {
5095                                 warnx("tag count %d is < 0", numtags);
5096                                 retval = 1;
5097                                 goto tagcontrol_bailout;
5098                         }
5099                         break;
5100                 case 'q':
5101                         quiet++;
5102                         break;
5103                 default:
5104                         break;
5105                 }
5106         }
5107
5108         cam_path_string(device, pathstr, sizeof(pathstr));
5109
5110         if (numtags >= 0) {
5111                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5112                 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5113                 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5114                 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5115                 ccb->crs.openings = numtags;
5116
5117
5118                 if (cam_send_ccb(device, ccb) < 0) {
5119                         warn("error sending XPT_REL_SIMQ CCB");
5120                         retval = 1;
5121                         goto tagcontrol_bailout;
5122                 }
5123
5124                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5125                         warnx("XPT_REL_SIMQ CCB failed");
5126                         cam_error_print(device, ccb, CAM_ESF_ALL,
5127                                         CAM_EPF_ALL, stderr);
5128                         retval = 1;
5129                         goto tagcontrol_bailout;
5130                 }
5131
5132
5133                 if (quiet == 0)
5134                         fprintf(stdout, "%stagged openings now %d\n",
5135                                 pathstr, ccb->crs.openings);
5136         }
5137
5138         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5139
5140         ccb->ccb_h.func_code = XPT_GDEV_STATS;
5141
5142         if (cam_send_ccb(device, ccb) < 0) {
5143                 warn("error sending XPT_GDEV_STATS CCB");
5144                 retval = 1;
5145                 goto tagcontrol_bailout;
5146         }
5147
5148         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5149                 warnx("XPT_GDEV_STATS CCB failed");
5150                 cam_error_print(device, ccb, CAM_ESF_ALL,
5151                                 CAM_EPF_ALL, stderr);
5152                 retval = 1;
5153                 goto tagcontrol_bailout;
5154         }
5155
5156         if (arglist & CAM_ARG_VERBOSE) {
5157                 fprintf(stdout, "%s", pathstr);
5158                 fprintf(stdout, "dev_openings  %d\n", ccb->cgds.dev_openings);
5159                 fprintf(stdout, "%s", pathstr);
5160                 fprintf(stdout, "dev_active    %d\n", ccb->cgds.dev_active);
5161                 fprintf(stdout, "%s", pathstr);
5162                 fprintf(stdout, "allocated     %d\n", ccb->cgds.allocated);
5163                 fprintf(stdout, "%s", pathstr);
5164                 fprintf(stdout, "queued        %d\n", ccb->cgds.queued);
5165                 fprintf(stdout, "%s", pathstr);
5166                 fprintf(stdout, "held          %d\n", ccb->cgds.held);
5167                 fprintf(stdout, "%s", pathstr);
5168                 fprintf(stdout, "mintags       %d\n", ccb->cgds.mintags);
5169                 fprintf(stdout, "%s", pathstr);
5170                 fprintf(stdout, "maxtags       %d\n", ccb->cgds.maxtags);
5171         } else {
5172                 if (quiet == 0) {
5173                         fprintf(stdout, "%s", pathstr);
5174                         fprintf(stdout, "device openings: ");
5175                 }
5176                 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5177                         ccb->cgds.dev_active);
5178         }
5179
5180 tagcontrol_bailout:
5181
5182         cam_freeccb(ccb);
5183         return (retval);
5184 }
5185
5186 static void
5187 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5188 {
5189         char pathstr[1024];
5190
5191         cam_path_string(device, pathstr, sizeof(pathstr));
5192
5193         if (cts->transport == XPORT_SPI) {
5194                 struct ccb_trans_settings_spi *spi =
5195                     &cts->xport_specific.spi;
5196
5197                 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5198
5199                         fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5200                                 spi->sync_period);
5201
5202                         if (spi->sync_offset != 0) {
5203                                 u_int freq;
5204
5205                                 freq = scsi_calc_syncsrate(spi->sync_period);
5206                                 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5207                                         pathstr, freq / 1000, freq % 1000);
5208                         }
5209                 }
5210
5211                 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5212                         fprintf(stdout, "%soffset: %d\n", pathstr,
5213                             spi->sync_offset);
5214                 }
5215
5216                 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5217                         fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5218                                 (0x01 << spi->bus_width) * 8);
5219                 }
5220
5221                 if (spi->valid & CTS_SPI_VALID_DISC) {
5222                         fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5223                                 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5224                                 "enabled" : "disabled");
5225                 }
5226         }
5227         if (cts->transport == XPORT_FC) {
5228                 struct ccb_trans_settings_fc *fc =
5229                     &cts->xport_specific.fc;
5230
5231                 if (fc->valid & CTS_FC_VALID_WWNN)
5232                         fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5233                             (long long) fc->wwnn);
5234                 if (fc->valid & CTS_FC_VALID_WWPN)
5235                         fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5236                             (long long) fc->wwpn);
5237                 if (fc->valid & CTS_FC_VALID_PORT)
5238                         fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5239                 if (fc->valid & CTS_FC_VALID_SPEED)
5240                         fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5241                             pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5242         }
5243         if (cts->transport == XPORT_SAS) {
5244                 struct ccb_trans_settings_sas *sas =
5245                     &cts->xport_specific.sas;
5246
5247                 if (sas->valid & CTS_SAS_VALID_SPEED)
5248                         fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5249                             pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5250         }
5251         if (cts->transport == XPORT_ATA) {
5252                 struct ccb_trans_settings_pata *pata =
5253                     &cts->xport_specific.ata;
5254
5255                 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5256                         fprintf(stdout, "%sATA mode: %s\n", pathstr,
5257                                 ata_mode2string(pata->mode));
5258                 }
5259                 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5260                         fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5261                                 pata->atapi);
5262                 }
5263                 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5264                         fprintf(stdout, "%sPIO transaction length: %d\n",
5265                                 pathstr, pata->bytecount);
5266                 }
5267         }
5268         if (cts->transport == XPORT_SATA) {
5269                 struct ccb_trans_settings_sata *sata =
5270                     &cts->xport_specific.sata;
5271
5272                 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5273                         fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5274                                 sata->revision);
5275                 }
5276                 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5277                         fprintf(stdout, "%sATA mode: %s\n", pathstr,
5278                                 ata_mode2string(sata->mode));
5279                 }
5280                 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5281                         fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5282                                 sata->atapi);
5283                 }
5284                 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5285                         fprintf(stdout, "%sPIO transaction length: %d\n",
5286                                 pathstr, sata->bytecount);
5287                 }
5288                 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5289                         fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5290                                 sata->pm_present);
5291                 }
5292                 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5293                         fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5294                                 sata->tags);
5295                 }
5296                 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5297                         fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5298                                 sata->caps);
5299                 }
5300         }
5301         if (cts->protocol == PROTO_ATA) {
5302                 struct ccb_trans_settings_ata *ata=
5303                     &cts->proto_specific.ata;
5304
5305                 if (ata->valid & CTS_ATA_VALID_TQ) {
5306                         fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5307                                 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5308                                 "enabled" : "disabled");
5309                 }
5310         }
5311         if (cts->protocol == PROTO_SCSI) {
5312                 struct ccb_trans_settings_scsi *scsi=
5313                     &cts->proto_specific.scsi;
5314
5315                 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5316                         fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5317                                 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5318                                 "enabled" : "disabled");
5319                 }
5320         }
5321 #ifdef WITH_NVME
5322         if (cts->protocol == PROTO_NVME) {
5323                 struct ccb_trans_settings_nvme *nvmex =
5324                     &cts->xport_specific.nvme;
5325
5326                 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5327                         fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5328                             NVME_MAJOR(nvmex->spec),
5329                             NVME_MINOR(nvmex->spec));
5330                 }
5331                 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5332                         fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5333                             nvmex->lanes, nvmex->max_lanes);
5334                         fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5335                             nvmex->speed, nvmex->max_speed);
5336                 }
5337         }
5338 #endif
5339 }
5340
5341 /*
5342  * Get a path inquiry CCB for the specified device.
5343  */
5344 static int
5345 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5346 {
5347         union ccb *ccb;
5348         int retval = 0;
5349
5350         ccb = cam_getccb(device);
5351         if (ccb == NULL) {
5352                 warnx("get_cpi: couldn't allocate CCB");
5353                 return (1);
5354         }
5355         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5356         ccb->ccb_h.func_code = XPT_PATH_INQ;
5357         if (cam_send_ccb(device, ccb) < 0) {
5358                 warn("get_cpi: error sending Path Inquiry CCB");
5359                 retval = 1;
5360                 goto get_cpi_bailout;
5361         }
5362         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5363                 if (arglist & CAM_ARG_VERBOSE)
5364                         cam_error_print(device, ccb, CAM_ESF_ALL,
5365                                         CAM_EPF_ALL, stderr);
5366                 retval = 1;
5367                 goto get_cpi_bailout;
5368         }
5369         bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5370
5371 get_cpi_bailout:
5372         cam_freeccb(ccb);
5373         return (retval);
5374 }
5375
5376 /*
5377  * Get a get device CCB for the specified device.
5378  */
5379 static int
5380 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5381 {
5382         union ccb *ccb;
5383         int retval = 0;
5384
5385         ccb = cam_getccb(device);
5386         if (ccb == NULL) {
5387                 warnx("get_cgd: couldn't allocate CCB");
5388                 return (1);
5389         }
5390         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5391         ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5392         if (cam_send_ccb(device, ccb) < 0) {
5393                 warn("get_cgd: error sending Get type information CCB");
5394                 retval = 1;
5395                 goto get_cgd_bailout;
5396         }
5397         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5398                 if (arglist & CAM_ARG_VERBOSE)
5399                         cam_error_print(device, ccb, CAM_ESF_ALL,
5400                                         CAM_EPF_ALL, stderr);
5401                 retval = 1;
5402                 goto get_cgd_bailout;
5403         }
5404         bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5405
5406 get_cgd_bailout:
5407         cam_freeccb(ccb);
5408         return (retval);
5409 }
5410
5411 /*
5412  * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5413  * error.
5414  */
5415 int
5416 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5417                  int timeout, int verbosemode)
5418 {
5419         union ccb *ccb = NULL;
5420         struct scsi_vpd_supported_page_list sup_pages;
5421         int i;
5422         int retval = 0;
5423
5424         ccb = cam_getccb(dev);
5425         if (ccb == NULL) {
5426                 warn("Unable to allocate CCB");
5427                 retval = -1;
5428                 goto bailout;
5429         }
5430
5431         /* cam_getccb cleans up the header, caller has to zero the payload */
5432         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5433
5434         bzero(&sup_pages, sizeof(sup_pages));
5435
5436         scsi_inquiry(&ccb->csio,
5437                      /*retries*/ retry_count,
5438                      /*cbfcnp*/ NULL,
5439                      /* tag_action */ MSG_SIMPLE_Q_TAG,
5440                      /* inq_buf */ (u_int8_t *)&sup_pages,
5441                      /* inq_len */ sizeof(sup_pages),
5442                      /* evpd */ 1,
5443                      /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5444                      /* sense_len */ SSD_FULL_SIZE,
5445                      /* timeout */ timeout ? timeout : 5000);
5446
5447         /* Disable freezing the device queue */
5448         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5449
5450         if (retry_count != 0)
5451                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5452
5453         if (cam_send_ccb(dev, ccb) < 0) {
5454                 cam_freeccb(ccb);
5455                 ccb = NULL;
5456                 retval = -1;
5457                 goto bailout;
5458         }
5459
5460         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5461                 if (verbosemode != 0)
5462                         cam_error_print(dev, ccb, CAM_ESF_ALL,
5463                                         CAM_EPF_ALL, stderr);
5464                 retval = -1;
5465                 goto bailout;
5466         }
5467
5468         for (i = 0; i < sup_pages.length; i++) {
5469                 if (sup_pages.list[i] == page_id) {
5470                         retval = 1;
5471                         goto bailout;
5472                 }
5473         }
5474 bailout:
5475         if (ccb != NULL)
5476                 cam_freeccb(ccb);
5477
5478         return (retval);
5479 }
5480
5481 /*
5482  * devtype is filled in with the type of device.
5483  * Returns 0 for success, non-zero for failure.
5484  */
5485 int
5486 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5487                     int verbosemode, camcontrol_devtype *devtype)
5488 {
5489         struct ccb_getdev cgd;
5490         int retval;
5491
5492         retval = get_cgd(dev, &cgd);
5493         if (retval != 0)
5494                 goto bailout;
5495
5496         switch (cgd.protocol) {
5497         case PROTO_SCSI:
5498                 break;
5499         case PROTO_ATA:
5500         case PROTO_ATAPI:
5501         case PROTO_SATAPM:
5502                 *devtype = CC_DT_ATA;
5503                 goto bailout;
5504                 break; /*NOTREACHED*/
5505         case PROTO_NVME:
5506                 *devtype = CC_DT_NVME;
5507                 goto bailout;
5508                 break; /*NOTREACHED*/
5509         case PROTO_MMCSD:
5510                 *devtype = CC_DT_MMCSD;
5511                 goto bailout;
5512                 break; /*NOTREACHED*/
5513         default:
5514                 *devtype = CC_DT_UNKNOWN;
5515                 goto bailout;
5516                 break; /*NOTREACHED*/
5517         }
5518
5519         if (retry_count == -1) {
5520                 /*
5521                  * For a retry count of -1, used only the cached data to avoid
5522                  * I/O to the drive. Sending the identify command to the drive
5523                  * can cause issues for SATL attachaed drives since identify is
5524                  * not an NCQ command.
5525                  */
5526                 if (cgd.ident_data.config != 0)
5527                         *devtype = CC_DT_SATL;
5528                 else
5529                         *devtype = CC_DT_SCSI;
5530         } else {
5531                 /*
5532                  * Check for the ATA Information VPD page (0x89).  If this is an
5533                  * ATA device behind a SCSI to ATA translation layer (SATL),
5534                  * this VPD page should be present.
5535                  *
5536                  * If that VPD page isn't present, or we get an error back from
5537                  * the INQUIRY command, we'll just treat it as a normal SCSI
5538                  * device.
5539                  */
5540                 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5541                     timeout, verbosemode);
5542                 if (retval == 1)
5543                         *devtype = CC_DT_SATL;
5544                 else
5545                         *devtype = CC_DT_SCSI;
5546         }
5547         retval = 0;
5548
5549 bailout:
5550         return (retval);
5551 }
5552
5553 int
5554 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5555     uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5556     uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5557     uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5558     size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5559     int is48bit, camcontrol_devtype devtype)
5560 {
5561         int retval = 0;
5562
5563         if (devtype == CC_DT_ATA) {
5564                 cam_fill_ataio(&ccb->ataio,
5565                     /*retries*/ retry_count,
5566                     /*cbfcnp*/ NULL,
5567                     /*flags*/ flags,
5568                     /*tag_action*/ tag_action,
5569                     /*data_ptr*/ data_ptr,
5570                     /*dxfer_len*/ dxfer_len,
5571                     /*timeout*/ timeout);
5572                 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5573                         ata_48bit_cmd(&ccb->ataio, command, features, lba,
5574                             sector_count);
5575                 else
5576                         ata_28bit_cmd(&ccb->ataio, command, features, lba,
5577                             sector_count);
5578
5579                 if (auxiliary != 0) {
5580                         ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5581                         ccb->ataio.aux = auxiliary;
5582                 }
5583
5584                 if (ata_flags & AP_FLAG_CHK_COND)
5585                         ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5586
5587                 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5588                         ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5589                 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5590                         ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5591         } else {
5592                 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5593                         protocol |= AP_EXTEND;
5594
5595                 retval = scsi_ata_pass(&ccb->csio,
5596                     /*retries*/ retry_count,
5597                     /*cbfcnp*/ NULL,
5598                     /*flags*/ flags,
5599                     /*tag_action*/ tag_action,
5600                     /*protocol*/ protocol,
5601                     /*ata_flags*/ ata_flags,
5602                     /*features*/ features,
5603                     /*sector_count*/ sector_count,
5604                     /*lba*/ lba,
5605                     /*command*/ command,
5606                     /*device*/ 0,
5607                     /*icc*/ 0,
5608                     /*auxiliary*/ auxiliary,
5609                     /*control*/ 0,
5610                     /*data_ptr*/ data_ptr,
5611                     /*dxfer_len*/ dxfer_len,
5612                     /*cdb_storage*/ cdb_storage,
5613                     /*cdb_storage_len*/ cdb_storage_len,
5614                     /*minimum_cmd_size*/ 0,
5615                     /*sense_len*/ sense_len,
5616                     /*timeout*/ timeout);
5617         }
5618
5619         return (retval);
5620 }
5621
5622 /*
5623  * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5624  *          4 -- count truncated, 6 -- lba and count truncated.
5625  */
5626 int
5627 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5628                uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5629 {
5630         int retval;
5631
5632         switch (ccb->ccb_h.func_code) {
5633         case XPT_SCSI_IO: {
5634                 uint8_t opcode;
5635                 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5636                 u_int sense_len;
5637
5638                 /*
5639                  * In this case, we have SCSI ATA PASS-THROUGH command, 12
5640                  * or 16 byte, and need to see what
5641                  */
5642                 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5643                         opcode = ccb->csio.cdb_io.cdb_ptr[0];
5644                 else
5645                         opcode = ccb->csio.cdb_io.cdb_bytes[0];
5646                 if ((opcode != ATA_PASS_12)
5647                  && (opcode != ATA_PASS_16)) {
5648                         warnx("%s: unsupported opcode %02x", __func__, opcode);
5649                         return (1);
5650                 }
5651
5652                 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5653                                                 &asc, &ascq);
5654                 /* Note: the _ccb() variant returns 0 for an error */
5655                 if (retval == 0)
5656                         return (1);
5657
5658                 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5659                 switch (error_code) {
5660                 case SSD_DESC_CURRENT_ERROR:
5661                 case SSD_DESC_DEFERRED_ERROR: {
5662                         struct scsi_sense_data_desc *sense;
5663                         struct scsi_sense_ata_ret_desc *desc;
5664                         uint8_t *desc_ptr;
5665
5666                         sense = (struct scsi_sense_data_desc *)
5667                             &ccb->csio.sense_data;
5668
5669                         desc_ptr = scsi_find_desc(sense, sense_len,
5670                             SSD_DESC_ATA);
5671                         if (desc_ptr == NULL) {
5672                                 cam_error_print(dev, ccb, CAM_ESF_ALL,
5673                                     CAM_EPF_ALL, stderr);
5674                                 return (1);
5675                         }
5676                         desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5677
5678                         *error = desc->error;
5679                         *count = (desc->count_15_8 << 8) |
5680                                   desc->count_7_0;
5681                         *lba = ((uint64_t)desc->lba_47_40 << 40) |
5682                                ((uint64_t)desc->lba_39_32 << 32) |
5683                                ((uint64_t)desc->lba_31_24 << 24) |
5684                                (desc->lba_23_16 << 16) |
5685                                (desc->lba_15_8  <<  8) |
5686                                 desc->lba_7_0;
5687                         *device = desc->device;
5688                         *status = desc->status;
5689
5690                         /*
5691                          * If the extend bit isn't set, the result is for a
5692                          * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5693                          * command without the extend bit set.  This means
5694                          * that the device is supposed to return 28-bit
5695                          * status.  The count field is only 8 bits, and the
5696                          * LBA field is only 8 bits.
5697                          */
5698                         if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5699                                 *count &= 0xff;
5700                                 *lba &= 0x0fffffff;
5701                         }
5702                         break;
5703                 }
5704                 case SSD_CURRENT_ERROR:
5705                 case SSD_DEFERRED_ERROR: {
5706                         uint64_t val;
5707
5708                         /*
5709                          * In my understanding of SAT-5 specification, saying:
5710                          * "without interpreting the contents of the STATUS",
5711                          * this should not happen if CK_COND was set, but it
5712                          * does at least for some devices, so try to revert.
5713                          */
5714                         if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5715                             (asc == 0) && (ascq == 0)) {
5716                                 *status = ATA_STATUS_ERROR;
5717                                 *error = ATA_ERROR_ABORT;
5718                                 *device = 0;
5719                                 *count = 0;
5720                                 *lba = 0;
5721                                 return (0);
5722                         }
5723
5724                         if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5725                             (asc != 0x00) || (ascq != 0x1d))
5726                                 return (1);
5727
5728                         val = 0;
5729                         scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5730                             SSD_DESC_INFO, &val, NULL);
5731                         *error = (val >> 24) & 0xff;
5732                         *status = (val >> 16) & 0xff;
5733                         *device = (val >> 8) & 0xff;
5734                         *count = val & 0xff;
5735
5736                         val = 0;
5737                         scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5738                             SSD_DESC_COMMAND, &val, NULL);
5739                         *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5740                                 ((val & 0xff) << 16);
5741
5742                         /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5743                         return ((val >> 28) & 0x06);
5744                 }
5745                 default:
5746                         return (1);
5747                 }
5748
5749                 break;
5750         }
5751         case XPT_ATA_IO: {
5752                 struct ata_res *res;
5753
5754                 /* Only some statuses return ATA result register set. */
5755                 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5756                     cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5757                         return (1);
5758
5759                 res = &ccb->ataio.res;
5760                 *error = res->error;
5761                 *status = res->status;
5762                 *device = res->device;
5763                 *count = res->sector_count;
5764                 *lba = (res->lba_high << 16) |
5765                        (res->lba_mid << 8) |
5766                        (res->lba_low);
5767                 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5768                         *count |= (res->sector_count_exp << 8);
5769                         *lba |= ((uint64_t)res->lba_low_exp << 24) |
5770                                 ((uint64_t)res->lba_mid_exp << 32) |
5771                                 ((uint64_t)res->lba_high_exp << 40);
5772                 } else {
5773                         *lba |= (res->device & 0xf) << 24;
5774                 }
5775                 break;
5776         }
5777         default:
5778                 return (1);
5779         }
5780         return (0);
5781 }
5782
5783 static void
5784 cpi_print(struct ccb_pathinq *cpi)
5785 {
5786         char adapter_str[1024];
5787         uint64_t i;
5788
5789         snprintf(adapter_str, sizeof(adapter_str),
5790                  "%s%d:", cpi->dev_name, cpi->unit_number);
5791
5792         fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5793                 cpi->version_num);
5794
5795         for (i = 1; i < UINT8_MAX; i = i << 1) {
5796                 const char *str;
5797
5798                 if ((i & cpi->hba_inquiry) == 0)
5799                         continue;
5800
5801                 fprintf(stdout, "%s supports ", adapter_str);
5802
5803                 switch(i) {
5804                 case PI_MDP_ABLE:
5805                         str = "MDP message";
5806                         break;
5807                 case PI_WIDE_32:
5808                         str = "32 bit wide SCSI";
5809                         break;
5810                 case PI_WIDE_16:
5811                         str = "16 bit wide SCSI";
5812                         break;
5813                 case PI_SDTR_ABLE:
5814                         str = "SDTR message";
5815                         break;
5816                 case PI_LINKED_CDB:
5817                         str = "linked CDBs";
5818                         break;
5819                 case PI_TAG_ABLE:
5820                         str = "tag queue messages";
5821                         break;
5822                 case PI_SOFT_RST:
5823                         str = "soft reset alternative";
5824                         break;
5825                 case PI_SATAPM:
5826                         str = "SATA Port Multiplier";
5827                         break;
5828                 default:
5829                         str = "unknown PI bit set";
5830                         break;
5831                 }
5832                 fprintf(stdout, "%s\n", str);
5833         }
5834
5835         for (i = 1; i < UINT32_MAX; i = i << 1) {
5836                 const char *str;
5837
5838                 if ((i & cpi->hba_misc) == 0)
5839                         continue;
5840
5841                 fprintf(stdout, "%s ", adapter_str);
5842
5843                 switch(i) {
5844                 case PIM_ATA_EXT:
5845                         str = "can understand ata_ext requests";
5846                         break;
5847                 case PIM_EXTLUNS:
5848                         str = "64bit extended LUNs supported";
5849                         break;
5850                 case PIM_SCANHILO:
5851                         str = "bus scans from high ID to low ID";
5852                         break;
5853                 case PIM_NOREMOVE:
5854                         str = "removable devices not included in scan";
5855                         break;
5856                 case PIM_NOINITIATOR:
5857                         str = "initiator role not supported";
5858                         break;
5859                 case PIM_NOBUSRESET:
5860                         str = "user has disabled initial BUS RESET or"
5861                               " controller is in target/mixed mode";
5862                         break;
5863                 case PIM_NO_6_BYTE:
5864                         str = "do not send 6-byte commands";
5865                         break;
5866                 case PIM_SEQSCAN:
5867                         str = "scan bus sequentially";
5868                         break;
5869                 case PIM_UNMAPPED:
5870                         str = "unmapped I/O supported";
5871                         break;
5872                 case PIM_NOSCAN:
5873                         str = "does its own scanning";
5874                         break;
5875                 default:
5876                         str = "unknown PIM bit set";
5877                         break;
5878                 }
5879                 fprintf(stdout, "%s\n", str);
5880         }
5881
5882         for (i = 1; i < UINT16_MAX; i = i << 1) {
5883                 const char *str;
5884
5885                 if ((i & cpi->target_sprt) == 0)
5886                         continue;
5887
5888                 fprintf(stdout, "%s supports ", adapter_str);
5889                 switch(i) {
5890                 case PIT_PROCESSOR:
5891                         str = "target mode processor mode";
5892                         break;
5893                 case PIT_PHASE:
5894                         str = "target mode phase cog. mode";
5895                         break;
5896                 case PIT_DISCONNECT:
5897                         str = "disconnects in target mode";
5898                         break;
5899                 case PIT_TERM_IO:
5900                         str = "terminate I/O message in target mode";
5901                         break;
5902                 case PIT_GRP_6:
5903                         str = "group 6 commands in target mode";
5904                         break;
5905                 case PIT_GRP_7:
5906                         str = "group 7 commands in target mode";
5907                         break;
5908                 default:
5909                         str = "unknown PIT bit set";
5910                         break;
5911                 }
5912
5913                 fprintf(stdout, "%s\n", str);
5914         }
5915         fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5916                 cpi->hba_eng_cnt);
5917         fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5918                 cpi->max_target);
5919         fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5920                 cpi->max_lun);
5921         fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5922                 adapter_str, cpi->hpath_id);
5923         fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5924                 cpi->initiator_id);
5925         fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5926         fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5927         fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5928             adapter_str, cpi->hba_vendor);
5929         fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5930             adapter_str, cpi->hba_device);
5931         fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5932             adapter_str, cpi->hba_subvendor);
5933         fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5934             adapter_str, cpi->hba_subdevice);
5935         fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5936         fprintf(stdout, "%s base transfer speed: ", adapter_str);
5937         if (cpi->base_transfer_speed > 1000)
5938                 fprintf(stdout, "%d.%03dMB/sec\n",
5939                         cpi->base_transfer_speed / 1000,
5940                         cpi->base_transfer_speed % 1000);
5941         else
5942                 fprintf(stdout, "%dKB/sec\n",
5943                         (cpi->base_transfer_speed % 1000) * 1000);
5944         fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5945             adapter_str, cpi->maxio);
5946 }
5947
5948 static int
5949 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5950               struct ccb_trans_settings *cts)
5951 {
5952         int retval;
5953         union ccb *ccb;
5954
5955         retval = 0;
5956         ccb = cam_getccb(device);
5957
5958         if (ccb == NULL) {
5959                 warnx("get_print_cts: error allocating ccb");
5960                 return (1);
5961         }
5962
5963         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5964
5965         ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5966
5967         if (user_settings == 0)
5968                 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5969         else
5970                 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5971
5972         if (cam_send_ccb(device, ccb) < 0) {
5973                 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5974                 retval = 1;
5975                 goto get_print_cts_bailout;
5976         }
5977
5978         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5979                 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
5980                 if (arglist & CAM_ARG_VERBOSE)
5981                         cam_error_print(device, ccb, CAM_ESF_ALL,
5982                                         CAM_EPF_ALL, stderr);
5983                 retval = 1;
5984                 goto get_print_cts_bailout;
5985         }
5986
5987         if (quiet == 0)
5988                 cts_print(device, &ccb->cts);
5989
5990         if (cts != NULL)
5991                 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
5992
5993 get_print_cts_bailout:
5994
5995         cam_freeccb(ccb);
5996
5997         return (retval);
5998 }
5999
6000 static int
6001 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6002             int timeout, int argc, char **argv, char *combinedopt)
6003 {
6004         int c;
6005         union ccb *ccb;
6006         int user_settings = 0;
6007         int retval = 0;
6008         int disc_enable = -1, tag_enable = -1;
6009         int mode = -1;
6010         int offset = -1;
6011         double syncrate = -1;
6012         int bus_width = -1;
6013         int quiet = 0;
6014         int change_settings = 0, send_tur = 0;
6015         struct ccb_pathinq cpi;
6016
6017         ccb = cam_getccb(device);
6018         if (ccb == NULL) {
6019                 warnx("ratecontrol: error allocating ccb");
6020                 return (1);
6021         }
6022         while ((c = getopt(argc, argv, combinedopt)) != -1) {
6023                 switch(c){
6024                 case 'a':
6025                         send_tur = 1;
6026                         break;
6027                 case 'c':
6028                         user_settings = 0;
6029                         break;
6030                 case 'D':
6031                         if (strncasecmp(optarg, "enable", 6) == 0)
6032                                 disc_enable = 1;
6033                         else if (strncasecmp(optarg, "disable", 7) == 0)
6034                                 disc_enable = 0;
6035                         else {
6036                                 warnx("-D argument \"%s\" is unknown", optarg);
6037                                 retval = 1;
6038                                 goto ratecontrol_bailout;
6039                         }
6040                         change_settings = 1;
6041                         break;
6042                 case 'M':
6043                         mode = ata_string2mode(optarg);
6044                         if (mode < 0) {
6045                                 warnx("unknown mode '%s'", optarg);
6046                                 retval = 1;
6047                                 goto ratecontrol_bailout;
6048                         }
6049                         change_settings = 1;
6050                         break;
6051                 case 'O':
6052                         offset = strtol(optarg, NULL, 0);
6053                         if (offset < 0) {
6054                                 warnx("offset value %d is < 0", offset);
6055                                 retval = 1;
6056                                 goto ratecontrol_bailout;
6057                         }
6058                         change_settings = 1;
6059                         break;
6060                 case 'q':
6061                         quiet++;
6062                         break;
6063                 case 'R':
6064                         syncrate = atof(optarg);
6065                         if (syncrate < 0) {
6066                                 warnx("sync rate %f is < 0", syncrate);
6067                                 retval = 1;
6068                                 goto ratecontrol_bailout;
6069                         }
6070                         change_settings = 1;
6071                         break;
6072                 case 'T':
6073                         if (strncasecmp(optarg, "enable", 6) == 0)
6074                                 tag_enable = 1;
6075                         else if (strncasecmp(optarg, "disable", 7) == 0)
6076                                 tag_enable = 0;
6077                         else {
6078                                 warnx("-T argument \"%s\" is unknown", optarg);
6079                                 retval = 1;
6080                                 goto ratecontrol_bailout;
6081                         }
6082                         change_settings = 1;
6083                         break;
6084                 case 'U':
6085                         user_settings = 1;
6086                         break;
6087                 case 'W':
6088                         bus_width = strtol(optarg, NULL, 0);
6089                         if (bus_width < 0) {
6090                                 warnx("bus width %d is < 0", bus_width);
6091                                 retval = 1;
6092                                 goto ratecontrol_bailout;
6093                         }
6094                         change_settings = 1;
6095                         break;
6096                 default:
6097                         break;
6098                 }
6099         }
6100         /*
6101          * Grab path inquiry information, so we can determine whether
6102          * or not the initiator is capable of the things that the user
6103          * requests.
6104          */
6105         if ((retval = get_cpi(device, &cpi)) != 0)
6106                 goto ratecontrol_bailout;
6107         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6108         if (quiet == 0) {
6109                 fprintf(stdout, "%s parameters:\n",
6110                     user_settings ? "User" : "Current");
6111         }
6112         retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6113         if (retval != 0)
6114                 goto ratecontrol_bailout;
6115
6116         if (arglist & CAM_ARG_VERBOSE)
6117                 cpi_print(&cpi);
6118
6119         if (change_settings) {
6120                 int didsettings = 0;
6121                 struct ccb_trans_settings_spi *spi = NULL;
6122                 struct ccb_trans_settings_pata *pata = NULL;
6123                 struct ccb_trans_settings_sata *sata = NULL;
6124                 struct ccb_trans_settings_ata *ata = NULL;
6125                 struct ccb_trans_settings_scsi *scsi = NULL;
6126
6127                 if (ccb->cts.transport == XPORT_SPI)
6128                         spi = &ccb->cts.xport_specific.spi;
6129                 if (ccb->cts.transport == XPORT_ATA)
6130                         pata = &ccb->cts.xport_specific.ata;
6131                 if (ccb->cts.transport == XPORT_SATA)
6132                         sata = &ccb->cts.xport_specific.sata;
6133                 if (ccb->cts.protocol == PROTO_ATA)
6134                         ata = &ccb->cts.proto_specific.ata;
6135                 if (ccb->cts.protocol == PROTO_SCSI)
6136                         scsi = &ccb->cts.proto_specific.scsi;
6137                 ccb->cts.xport_specific.valid = 0;
6138                 ccb->cts.proto_specific.valid = 0;
6139                 if (spi && disc_enable != -1) {
6140                         spi->valid |= CTS_SPI_VALID_DISC;
6141                         if (disc_enable == 0)
6142                                 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6143                         else
6144                                 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6145                         didsettings++;
6146                 }
6147                 if (tag_enable != -1) {
6148                         if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6149                                 warnx("HBA does not support tagged queueing, "
6150                                       "so you cannot modify tag settings");
6151                                 retval = 1;
6152                                 goto ratecontrol_bailout;
6153                         }
6154                         if (ata) {
6155                                 ata->valid |= CTS_SCSI_VALID_TQ;
6156                                 if (tag_enable == 0)
6157                                         ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6158                                 else
6159                                         ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6160                                 didsettings++;
6161                         } else if (scsi) {
6162                                 scsi->valid |= CTS_SCSI_VALID_TQ;
6163                                 if (tag_enable == 0)
6164                                         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6165                                 else
6166                                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6167                                 didsettings++;
6168                         }
6169                 }
6170                 if (spi && offset != -1) {
6171                         if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6172                                 warnx("HBA is not capable of changing offset");
6173                                 retval = 1;
6174                                 goto ratecontrol_bailout;
6175                         }
6176                         spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6177                         spi->sync_offset = offset;
6178                         didsettings++;
6179                 }
6180                 if (spi && syncrate != -1) {
6181                         int prelim_sync_period;
6182
6183                         if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6184                                 warnx("HBA is not capable of changing "
6185                                       "transfer rates");
6186                                 retval = 1;
6187                                 goto ratecontrol_bailout;
6188                         }
6189                         spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6190                         /*
6191                          * The sync rate the user gives us is in MHz.
6192                          * We need to translate it into KHz for this
6193                          * calculation.
6194                          */
6195                         syncrate *= 1000;
6196                         /*
6197                          * Next, we calculate a "preliminary" sync period
6198                          * in tenths of a nanosecond.
6199                          */
6200                         if (syncrate == 0)
6201                                 prelim_sync_period = 0;
6202                         else
6203                                 prelim_sync_period = 10000000 / syncrate;
6204                         spi->sync_period =
6205                                 scsi_calc_syncparam(prelim_sync_period);
6206                         didsettings++;
6207                 }
6208                 if (sata && syncrate != -1) {
6209                         if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6210                                 warnx("HBA is not capable of changing "
6211                                       "transfer rates");
6212                                 retval = 1;
6213                                 goto ratecontrol_bailout;
6214                         }
6215                         if  (!user_settings) {
6216                                 warnx("You can modify only user rate "
6217                                     "settings for SATA");
6218                                 retval = 1;
6219                                 goto ratecontrol_bailout;
6220                         }
6221                         sata->revision = ata_speed2revision(syncrate * 100);
6222                         if (sata->revision < 0) {
6223                                 warnx("Invalid rate %f", syncrate);
6224                                 retval = 1;
6225                                 goto ratecontrol_bailout;
6226                         }
6227                         sata->valid |= CTS_SATA_VALID_REVISION;
6228                         didsettings++;
6229                 }
6230                 if ((pata || sata) && mode != -1) {
6231                         if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6232                                 warnx("HBA is not capable of changing "
6233                                       "transfer rates");
6234                                 retval = 1;
6235                                 goto ratecontrol_bailout;
6236                         }
6237                         if  (!user_settings) {
6238                                 warnx("You can modify only user mode "
6239                                     "settings for ATA/SATA");
6240                                 retval = 1;
6241                                 goto ratecontrol_bailout;
6242                         }
6243                         if (pata) {
6244                                 pata->mode = mode;
6245                                 pata->valid |= CTS_ATA_VALID_MODE;
6246                         } else {
6247                                 sata->mode = mode;
6248                                 sata->valid |= CTS_SATA_VALID_MODE;
6249                         }
6250                         didsettings++;
6251                 }
6252                 /*
6253                  * The bus_width argument goes like this:
6254                  * 0 == 8 bit
6255                  * 1 == 16 bit
6256                  * 2 == 32 bit
6257                  * Therefore, if you shift the number of bits given on the
6258                  * command line right by 4, you should get the correct
6259                  * number.
6260                  */
6261                 if (spi && bus_width != -1) {
6262                         /*
6263                          * We might as well validate things here with a
6264                          * decipherable error message, rather than what
6265                          * will probably be an indecipherable error message
6266                          * by the time it gets back to us.
6267                          */
6268                         if ((bus_width == 16)
6269                          && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6270                                 warnx("HBA does not support 16 bit bus width");
6271                                 retval = 1;
6272                                 goto ratecontrol_bailout;
6273                         } else if ((bus_width == 32)
6274                                 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6275                                 warnx("HBA does not support 32 bit bus width");
6276                                 retval = 1;
6277                                 goto ratecontrol_bailout;
6278                         } else if ((bus_width != 8)
6279                                 && (bus_width != 16)
6280                                 && (bus_width != 32)) {
6281                                 warnx("Invalid bus width %d", bus_width);
6282                                 retval = 1;
6283                                 goto ratecontrol_bailout;
6284                         }
6285                         spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6286                         spi->bus_width = bus_width >> 4;
6287                         didsettings++;
6288                 }
6289                 if  (didsettings == 0) {
6290                         goto ratecontrol_bailout;
6291                 }
6292                 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6293                 if (cam_send_ccb(device, ccb) < 0) {
6294                         warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6295                         retval = 1;
6296                         goto ratecontrol_bailout;
6297                 }
6298                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6299                         warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6300                         if (arglist & CAM_ARG_VERBOSE) {
6301                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6302                                                 CAM_EPF_ALL, stderr);
6303                         }
6304                         retval = 1;
6305                         goto ratecontrol_bailout;
6306                 }
6307         }
6308         if (send_tur) {
6309                 retval = testunitready(device, task_attr, retry_count, timeout,
6310                                        (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6311                 /*
6312                  * If the TUR didn't succeed, just bail.
6313                  */
6314                 if (retval != 0) {
6315                         if (quiet == 0)
6316                                 fprintf(stderr, "Test Unit Ready failed\n");
6317                         goto ratecontrol_bailout;
6318                 }
6319         }
6320         if ((change_settings || send_tur) && !quiet &&
6321             (ccb->cts.transport == XPORT_ATA ||
6322              ccb->cts.transport == XPORT_SATA || send_tur)) {
6323                 fprintf(stdout, "New parameters:\n");
6324                 retval = get_print_cts(device, user_settings, 0, NULL);
6325         }
6326
6327 ratecontrol_bailout:
6328         cam_freeccb(ccb);
6329         return (retval);
6330 }
6331
6332 static int
6333 scsiformat(struct cam_device *device, int argc, char **argv,
6334            char *combinedopt, int task_attr, int retry_count, int timeout)
6335 {
6336         union ccb *ccb;
6337         int c;
6338         int ycount = 0, quiet = 0;
6339         int error = 0, retval = 0;
6340         int use_timeout = 10800 * 1000;
6341         int immediate = 1;
6342         struct format_defect_list_header fh;
6343         u_int8_t *data_ptr = NULL;
6344         u_int32_t dxfer_len = 0;
6345         u_int8_t byte2 = 0;
6346         int num_warnings = 0;
6347         int reportonly = 0;
6348
6349         ccb = cam_getccb(device);
6350
6351         if (ccb == NULL) {
6352                 warnx("scsiformat: error allocating ccb");
6353                 return (1);
6354         }
6355
6356         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6357
6358         while ((c = getopt(argc, argv, combinedopt)) != -1) {
6359                 switch(c) {
6360                 case 'q':
6361                         quiet++;
6362                         break;
6363                 case 'r':
6364                         reportonly = 1;
6365                         break;
6366                 case 'w':
6367                         immediate = 0;
6368                         break;
6369                 case 'y':
6370                         ycount++;
6371                         break;
6372                 }
6373         }
6374
6375         if (reportonly)
6376                 goto doreport;
6377
6378         if (quiet == 0 && ycount == 0) {
6379                 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6380                         "following device:\n");
6381
6382                 error = scsidoinquiry(device, argc, argv, combinedopt,
6383                                       task_attr, retry_count, timeout);
6384
6385                 if (error != 0) {
6386                         warnx("scsiformat: error sending inquiry");
6387                         goto scsiformat_bailout;
6388                 }
6389         }
6390
6391         if (ycount == 0) {
6392                 if (!get_confirmation()) {
6393                         error = 1;
6394                         goto scsiformat_bailout;
6395                 }
6396         }
6397
6398         if (timeout != 0)
6399                 use_timeout = timeout;
6400
6401         if (quiet == 0) {
6402                 fprintf(stdout, "Current format timeout is %d seconds\n",
6403                         use_timeout / 1000);
6404         }
6405
6406         /*
6407          * If the user hasn't disabled questions and didn't specify a
6408          * timeout on the command line, ask them if they want the current
6409          * timeout.
6410          */
6411         if ((ycount == 0)
6412          && (timeout == 0)) {
6413                 char str[1024];
6414                 int new_timeout = 0;
6415
6416                 fprintf(stdout, "Enter new timeout in seconds or press\n"
6417                         "return to keep the current timeout [%d] ",
6418                         use_timeout / 1000);
6419
6420                 if (fgets(str, sizeof(str), stdin) != NULL) {
6421                         if (str[0] != '\0')
6422                                 new_timeout = atoi(str);
6423                 }
6424
6425                 if (new_timeout != 0) {
6426                         use_timeout = new_timeout * 1000;
6427                         fprintf(stdout, "Using new timeout value %d\n",
6428                                 use_timeout / 1000);
6429                 }
6430         }
6431
6432         /*
6433          * Keep this outside the if block below to silence any unused
6434          * variable warnings.
6435          */
6436         bzero(&fh, sizeof(fh));
6437
6438         /*
6439          * If we're in immediate mode, we've got to include the format
6440          * header
6441          */
6442         if (immediate != 0) {
6443                 fh.byte2 = FU_DLH_IMMED;
6444                 data_ptr = (u_int8_t *)&fh;
6445                 dxfer_len = sizeof(fh);
6446                 byte2 = FU_FMT_DATA;
6447         } else if (quiet == 0) {
6448                 fprintf(stdout, "Formatting...");
6449                 fflush(stdout);
6450         }
6451
6452         scsi_format_unit(&ccb->csio,
6453                          /* retries */ retry_count,
6454                          /* cbfcnp */ NULL,
6455                          /* tag_action */ task_attr,
6456                          /* byte2 */ byte2,
6457                          /* ileave */ 0,
6458                          /* data_ptr */ data_ptr,
6459                          /* dxfer_len */ dxfer_len,
6460                          /* sense_len */ SSD_FULL_SIZE,
6461                          /* timeout */ use_timeout);
6462
6463         /* Disable freezing the device queue */
6464         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6465
6466         if (arglist & CAM_ARG_ERR_RECOVER)
6467                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6468
6469         if (((retval = cam_send_ccb(device, ccb)) < 0)
6470          || ((immediate == 0)
6471            && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6472                 const char errstr[] = "error sending format command";
6473
6474                 if (retval < 0)
6475                         warn(errstr);
6476                 else
6477                         warnx(errstr);
6478
6479                 if (arglist & CAM_ARG_VERBOSE) {
6480                         cam_error_print(device, ccb, CAM_ESF_ALL,
6481                                         CAM_EPF_ALL, stderr);
6482                 }
6483                 error = 1;
6484                 goto scsiformat_bailout;
6485         }
6486
6487         /*
6488          * If we ran in non-immediate mode, we already checked for errors
6489          * above and printed out any necessary information.  If we're in
6490          * immediate mode, we need to loop through and get status
6491          * information periodically.
6492          */
6493         if (immediate == 0) {
6494                 if (quiet == 0) {
6495                         fprintf(stdout, "Format Complete\n");
6496                 }
6497                 goto scsiformat_bailout;
6498         }
6499
6500 doreport:
6501         do {
6502                 cam_status status;
6503
6504                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6505
6506                 /*
6507                  * There's really no need to do error recovery or
6508                  * retries here, since we're just going to sit in a
6509                  * loop and wait for the device to finish formatting.
6510                  */
6511                 scsi_test_unit_ready(&ccb->csio,
6512                                      /* retries */ 0,
6513                                      /* cbfcnp */ NULL,
6514                                      /* tag_action */ task_attr,
6515                                      /* sense_len */ SSD_FULL_SIZE,
6516                                      /* timeout */ 5000);
6517
6518                 /* Disable freezing the device queue */
6519                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6520
6521                 retval = cam_send_ccb(device, ccb);
6522
6523                 /*
6524                  * If we get an error from the ioctl, bail out.  SCSI
6525                  * errors are expected.
6526                  */
6527                 if (retval < 0) {
6528                         warn("error sending TEST UNIT READY command");
6529                         error = 1;
6530                         goto scsiformat_bailout;
6531                 }
6532
6533                 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6534
6535                 if ((status != CAM_REQ_CMP)
6536                  && (status == CAM_SCSI_STATUS_ERROR)
6537                  && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6538                         struct scsi_sense_data *sense;
6539                         int error_code, sense_key, asc, ascq;
6540
6541                         sense = &ccb->csio.sense_data;
6542                         scsi_extract_sense_len(sense, ccb->csio.sense_len -
6543                             ccb->csio.sense_resid, &error_code, &sense_key,
6544                             &asc, &ascq, /*show_errors*/ 1);
6545
6546                         /*
6547                          * According to the SCSI-2 and SCSI-3 specs, a
6548                          * drive that is in the middle of a format should
6549                          * return NOT READY with an ASC of "logical unit
6550                          * not ready, format in progress".  The sense key
6551                          * specific bytes will then be a progress indicator.
6552                          */
6553                         if ((sense_key == SSD_KEY_NOT_READY)
6554                          && (asc == 0x04) && (ascq == 0x04)) {
6555                                 uint8_t sks[3];
6556
6557                                 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6558                                      ccb->csio.sense_resid, sks) == 0)
6559                                  && (quiet == 0)) {
6560                                         uint32_t val;
6561                                         u_int64_t percentage;
6562
6563                                         val = scsi_2btoul(&sks[1]);
6564                                         percentage = 10000ull * val;
6565
6566                                         fprintf(stdout,
6567                                                 "\rFormatting:  %ju.%02u %% "
6568                                                 "(%u/%d) done",
6569                                                 (uintmax_t)(percentage /
6570                                                 (0x10000 * 100)),
6571                                                 (unsigned)((percentage /
6572                                                 0x10000) % 100),
6573                                                 val, 0x10000);
6574                                         fflush(stdout);
6575                                 } else if ((quiet == 0)
6576                                         && (++num_warnings <= 1)) {
6577                                         warnx("Unexpected SCSI Sense Key "
6578                                               "Specific value returned "
6579                                               "during format:");
6580                                         scsi_sense_print(device, &ccb->csio,
6581                                                          stderr);
6582                                         warnx("Unable to print status "
6583                                               "information, but format will "
6584                                               "proceed.");
6585                                         warnx("will exit when format is "
6586                                               "complete");
6587                                 }
6588                                 sleep(1);
6589                         } else {
6590                                 warnx("Unexpected SCSI error during format");
6591                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6592                                                 CAM_EPF_ALL, stderr);
6593                                 error = 1;
6594                                 goto scsiformat_bailout;
6595                         }
6596
6597                 } else if (status != CAM_REQ_CMP) {
6598                         warnx("Unexpected CAM status %#x", status);
6599                         if (arglist & CAM_ARG_VERBOSE)
6600                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6601                                                 CAM_EPF_ALL, stderr);
6602                         error = 1;
6603                         goto scsiformat_bailout;
6604                 }
6605
6606         } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6607
6608         if (quiet == 0)
6609                 fprintf(stdout, "\nFormat Complete\n");
6610
6611 scsiformat_bailout:
6612
6613         cam_freeccb(ccb);
6614
6615         return (error);
6616 }
6617
6618 static int
6619 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6620     camcontrol_devtype devtype)
6621 {
6622         int retval;
6623         uint8_t error = 0, ata_device = 0, status = 0;
6624         uint16_t count = 0;
6625         uint64_t lba = 0;
6626         u_int val, perc;
6627
6628         do {
6629                 retval = build_ata_cmd(ccb,
6630                              /*retries*/ 0,
6631                              /*flags*/ CAM_DIR_NONE,
6632                              /*tag_action*/ MSG_SIMPLE_Q_TAG,
6633                              /*protocol*/ AP_PROTO_NON_DATA,
6634                              /*ata_flags*/ AP_FLAG_CHK_COND,
6635                              /*features*/ 0x00, /* SANITIZE STATUS EXT */
6636                              /*sector_count*/ 0,
6637                              /*lba*/ 0,
6638                              /*command*/ ATA_SANITIZE,
6639                              /*auxiliary*/ 0,
6640                              /*data_ptr*/ NULL,
6641                              /*dxfer_len*/ 0,
6642                              /*cdb_storage*/ NULL,
6643                              /*cdb_storage_len*/ 0,
6644                              /*sense_len*/ SSD_FULL_SIZE,
6645                              /*timeout*/ 10000,
6646                              /*is48bit*/ 1,
6647                              /*devtype*/ devtype);
6648                 if (retval != 0) {
6649                         warnx("%s: build_ata_cmd() failed, likely "
6650                             "programmer error", __func__);
6651                         return (1);
6652                 }
6653
6654                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6655                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6656                 retval = cam_send_ccb(device, ccb);
6657                 if (retval != 0) {
6658                         warn("error sending SANITIZE STATUS EXT command");
6659                         return (1);
6660                 }
6661
6662                 retval = get_ata_status(device, ccb, &error, &count, &lba,
6663                     &ata_device, &status);
6664                 if (retval != 0) {
6665                         warnx("Can't get SANITIZE STATUS EXT status, "
6666                             "sanitize may still run.");
6667                         return (retval);
6668                 }
6669                 if (status & ATA_STATUS_ERROR) {
6670                         if (error & ATA_ERROR_ABORT) {
6671                                 switch (lba & 0xff) {
6672                                 case 0x00:
6673                                         warnx("Reason not reported or sanitize failed.");
6674                                         return (1);
6675                                 case 0x01:
6676                                         warnx("Sanitize command unsuccessful.       ");
6677                                         return (1);
6678                                 case 0x02:
6679                                         warnx("Unsupported sanitize device command. ");
6680                                         return (1);
6681                                 case 0x03:
6682                                         warnx("Device is in sanitize frozen state.  ");
6683                                         return (1);
6684                                 case 0x04:
6685                                         warnx("Sanitize antifreeze lock is enabled. ");
6686                                         return (1);
6687                                 }
6688                         }
6689                         warnx("SANITIZE STATUS EXT failed, "
6690                             "sanitize may still run.");
6691                         return (1);
6692                 }
6693                 if (count & 0x4000) {
6694                         if (quiet == 0) {
6695                                 val = lba & 0xffff;
6696                                 perc = 10000 * val;
6697                                 fprintf(stdout,
6698                                     "Sanitizing: %u.%02u%% (%d/%d)\r",
6699                                     (perc / (0x10000 * 100)),
6700                                     ((perc / 0x10000) % 100),
6701                                     val, 0x10000);
6702                                 fflush(stdout);
6703                         }
6704                         sleep(1);
6705                 } else
6706                         break;
6707         } while (1);
6708         return (0);
6709 }
6710
6711 static int
6712 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6713 {
6714         int warnings = 0, retval;
6715         cam_status status;
6716         u_int val, perc;
6717
6718         do {
6719                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6720
6721                 /*
6722                  * There's really no need to do error recovery or
6723                  * retries here, since we're just going to sit in a
6724                  * loop and wait for the device to finish sanitizing.
6725                  */
6726                 scsi_test_unit_ready(&ccb->csio,
6727                                      /* retries */ 0,
6728                                      /* cbfcnp */ NULL,
6729                                      /* tag_action */ task_attr,
6730                                      /* sense_len */ SSD_FULL_SIZE,
6731                                      /* timeout */ 5000);
6732
6733                 /* Disable freezing the device queue */
6734                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6735
6736                 retval = cam_send_ccb(device, ccb);
6737
6738                 /*
6739                  * If we get an error from the ioctl, bail out.  SCSI
6740                  * errors are expected.
6741                  */
6742                 if (retval < 0) {
6743                         warn("error sending TEST UNIT READY command");
6744                         return (1);
6745                 }
6746
6747                 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6748                 if ((status == CAM_SCSI_STATUS_ERROR) &&
6749                     ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6750                         struct scsi_sense_data *sense;
6751                         int error_code, sense_key, asc, ascq;
6752
6753                         sense = &ccb->csio.sense_data;
6754                         scsi_extract_sense_len(sense, ccb->csio.sense_len -
6755                             ccb->csio.sense_resid, &error_code, &sense_key,
6756                             &asc, &ascq, /*show_errors*/ 1);
6757
6758                         /*
6759                          * According to the SCSI-3 spec, a drive that is in the
6760                          * middle of a sanitize should return NOT READY with an
6761                          * ASC of "logical unit not ready, sanitize in
6762                          * progress". The sense key specific bytes will then
6763                          * be a progress indicator.
6764                          */
6765                         if ((sense_key == SSD_KEY_NOT_READY)
6766                          && (asc == 0x04) && (ascq == 0x1b)) {
6767                                 uint8_t sks[3];
6768
6769                                 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6770                                      ccb->csio.sense_resid, sks) == 0)
6771                                  && (quiet == 0)) {
6772                                         val = scsi_2btoul(&sks[1]);
6773                                         perc = 10000 * val;
6774                                         fprintf(stdout,
6775                                             "Sanitizing: %u.%02u%% (%d/%d)\r",
6776                                             (perc / (0x10000 * 100)),
6777                                             ((perc / 0x10000) % 100),
6778                                             val, 0x10000);
6779                                         fflush(stdout);
6780                                 } else if ((quiet == 0) && (++warnings <= 1)) {
6781                                         warnx("Unexpected SCSI Sense Key "
6782                                               "Specific value returned "
6783                                               "during sanitize:");
6784                                         scsi_sense_print(device, &ccb->csio,
6785                                                          stderr);
6786                                         warnx("Unable to print status "
6787                                               "information, but sanitze will "
6788                                               "proceed.");
6789                                         warnx("will exit when sanitize is "
6790                                               "complete");
6791                                 }
6792                                 sleep(1);
6793                         } else {
6794                                 warnx("Unexpected SCSI error during sanitize");
6795                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6796                                                 CAM_EPF_ALL, stderr);
6797                                 return (1);
6798                         }
6799
6800                 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6801                         warnx("Unexpected CAM status %#x", status);
6802                         if (arglist & CAM_ARG_VERBOSE)
6803                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6804                                                 CAM_EPF_ALL, stderr);
6805                         return (1);
6806                 }
6807         } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6808         return (0);
6809 }
6810
6811 static int
6812 sanitize(struct cam_device *device, int argc, char **argv,
6813              char *combinedopt, int task_attr, int retry_count, int timeout)
6814 {
6815         union ccb *ccb;
6816         u_int8_t action = 0;
6817         int c;
6818         int ycount = 0, quiet = 0;
6819         int error = 0;
6820         int use_timeout;
6821         int immediate = 1;
6822         int invert = 0;
6823         int passes = 0;
6824         int ause = 0;
6825         int fd = -1;
6826         const char *pattern = NULL;
6827         u_int8_t *data_ptr = NULL;
6828         u_int32_t dxfer_len = 0;
6829         uint8_t byte2;
6830         uint16_t feature, count;
6831         uint64_t lba;
6832         int reportonly = 0;
6833         camcontrol_devtype dt;
6834
6835         /*
6836          * Get the device type, request no I/O be done to do this.
6837          */
6838         error = get_device_type(device, -1, 0, 0, &dt);
6839         if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6840                 warnx("sanitize: can't get device type");
6841                 return (1);
6842         }
6843
6844         ccb = cam_getccb(device);
6845
6846         if (ccb == NULL) {
6847                 warnx("sanitize: error allocating ccb");
6848                 return (1);
6849         }
6850
6851         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6852
6853         while ((c = getopt(argc, argv, combinedopt)) != -1) {
6854                 switch(c) {
6855                 case 'a':
6856                         if (strcasecmp(optarg, "overwrite") == 0)
6857                                 action = SSZ_SERVICE_ACTION_OVERWRITE;
6858                         else if (strcasecmp(optarg, "block") == 0)
6859                                 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6860                         else if (strcasecmp(optarg, "crypto") == 0)
6861                                 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6862                         else if (strcasecmp(optarg, "exitfailure") == 0)
6863                                 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6864                         else {
6865                                 warnx("invalid service operation \"%s\"",
6866                                       optarg);
6867                                 error = 1;
6868                                 goto sanitize_bailout;
6869                         }
6870                         break;
6871                 case 'c':
6872                         passes = strtol(optarg, NULL, 0);
6873                         if (passes < 1 || passes > 31) {
6874                                 warnx("invalid passes value %d", passes);
6875                                 error = 1;
6876                                 goto sanitize_bailout;
6877                         }
6878                         break;
6879                 case 'I':
6880                         invert = 1;
6881                         break;
6882                 case 'P':
6883                         pattern = optarg;
6884                         break;
6885                 case 'q':
6886                         quiet++;
6887                         break;
6888                 case 'U':
6889                         ause = 1;
6890                         break;
6891                 case 'r':
6892                         reportonly = 1;
6893                         break;
6894                 case 'w':
6895                         /* ATA supports only immediate commands. */
6896                         if (dt == CC_DT_SCSI)
6897                                 immediate = 0;
6898                         break;
6899                 case 'y':
6900                         ycount++;
6901                         break;
6902                 }
6903         }
6904
6905         if (reportonly)
6906                 goto doreport;
6907
6908         if (action == 0) {
6909                 warnx("an action is required");
6910                 error = 1;
6911                 goto sanitize_bailout;
6912         } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6913                 struct scsi_sanitize_parameter_list *pl;
6914                 struct stat sb;
6915                 ssize_t sz, amt;
6916
6917                 if (pattern == NULL) {
6918                         warnx("overwrite action requires -P argument");
6919                         error = 1;
6920                         goto sanitize_bailout;
6921                 }
6922                 fd = open(pattern, O_RDONLY);
6923                 if (fd < 0) {
6924                         warn("cannot open pattern file %s", pattern);
6925                         error = 1;
6926                         goto sanitize_bailout;
6927                 }
6928                 if (fstat(fd, &sb) < 0) {
6929                         warn("cannot stat pattern file %s", pattern);
6930                         error = 1;
6931                         goto sanitize_bailout;
6932                 }
6933                 sz = sb.st_size;
6934                 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6935                         warnx("pattern file size exceeds maximum value %d",
6936                               SSZPL_MAX_PATTERN_LENGTH);
6937                         error = 1;
6938                         goto sanitize_bailout;
6939                 }
6940                 dxfer_len = sizeof(*pl) + sz;
6941                 data_ptr = calloc(1, dxfer_len);
6942                 if (data_ptr == NULL) {
6943                         warnx("cannot allocate parameter list buffer");
6944                         error = 1;
6945                         goto sanitize_bailout;
6946                 }
6947
6948                 amt = read(fd, data_ptr + sizeof(*pl), sz);
6949                 if (amt < 0) {
6950                         warn("cannot read pattern file");
6951                         error = 1;
6952                         goto sanitize_bailout;
6953                 } else if (amt != sz) {
6954                         warnx("short pattern file read");
6955                         error = 1;
6956                         goto sanitize_bailout;
6957                 }
6958
6959                 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6960                 if (passes == 0)
6961                         pl->byte1 = 1;
6962                 else
6963                         pl->byte1 = passes;
6964                 if (invert != 0)
6965                         pl->byte1 |= SSZPL_INVERT;
6966                 scsi_ulto2b(sz, pl->length);
6967         } else {
6968                 const char *arg;
6969
6970                 if (passes != 0)
6971                         arg = "-c";
6972                 else if (invert != 0)
6973                         arg = "-I";
6974                 else if (pattern != NULL)
6975                         arg = "-P";
6976                 else
6977                         arg = NULL;
6978                 if (arg != NULL) {
6979                         warnx("%s argument only valid with overwrite "
6980                               "operation", arg);
6981                         error = 1;
6982                         goto sanitize_bailout;
6983                 }
6984         }
6985
6986         if (quiet == 0 && ycount == 0) {
6987                 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6988                         "following device:\n");
6989
6990                 if (dt == CC_DT_SCSI) {
6991                         error = scsidoinquiry(device, argc, argv, combinedopt,
6992                                               task_attr, retry_count, timeout);
6993                 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
6994                         struct ata_params *ident_buf;
6995                         error = ata_do_identify(device, retry_count, timeout,
6996                                                 ccb, &ident_buf);
6997                         if (error == 0) {
6998                                 printf("%s%d: ", device->device_name,
6999                                     device->dev_unit_num);
7000                                 ata_print_ident(ident_buf);
7001                                 free(ident_buf);
7002                         }
7003                 } else
7004                         error = 1;
7005
7006                 if (error != 0) {
7007                         warnx("sanitize: error sending inquiry");
7008                         goto sanitize_bailout;
7009                 }
7010         }
7011
7012         if (ycount == 0) {
7013                 if (!get_confirmation()) {
7014                         error = 1;
7015                         goto sanitize_bailout;
7016                 }
7017         }
7018
7019         if (timeout != 0)
7020                 use_timeout = timeout;
7021         else
7022                 use_timeout = (immediate ? 10 : 10800) * 1000;
7023
7024         if (immediate == 0 && quiet == 0) {
7025                 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7026                         use_timeout / 1000);
7027         }
7028
7029         /*
7030          * If the user hasn't disabled questions and didn't specify a
7031          * timeout on the command line, ask them if they want the current
7032          * timeout.
7033          */
7034         if (immediate == 0 && ycount == 0 && timeout == 0) {
7035                 char str[1024];
7036                 int new_timeout = 0;
7037
7038                 fprintf(stdout, "Enter new timeout in seconds or press\n"
7039                         "return to keep the current timeout [%d] ",
7040                         use_timeout / 1000);
7041
7042                 if (fgets(str, sizeof(str), stdin) != NULL) {
7043                         if (str[0] != '\0')
7044                                 new_timeout = atoi(str);
7045                 }
7046
7047                 if (new_timeout != 0) {
7048                         use_timeout = new_timeout * 1000;
7049                         fprintf(stdout, "Using new timeout value %d\n",
7050                                 use_timeout / 1000);
7051                 }
7052         }
7053
7054         if (dt == CC_DT_SCSI) {
7055                 byte2 = action;
7056                 if (ause != 0)
7057                         byte2 |= SSZ_UNRESTRICTED_EXIT;
7058                 if (immediate != 0)
7059                         byte2 |= SSZ_IMMED;
7060                 scsi_sanitize(&ccb->csio,
7061                               /* retries */ retry_count,
7062                               /* cbfcnp */ NULL,
7063                               /* tag_action */ task_attr,
7064                               /* byte2 */ byte2,
7065                               /* control */ 0,
7066                               /* data_ptr */ data_ptr,
7067                               /* dxfer_len */ dxfer_len,
7068                               /* sense_len */ SSD_FULL_SIZE,
7069                               /* timeout */ use_timeout);
7070
7071                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7072                 if (arglist & CAM_ARG_ERR_RECOVER)
7073                         ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7074                 if (cam_send_ccb(device, ccb) < 0) {
7075                         warn("error sending sanitize command");
7076                         error = 1;
7077                         goto sanitize_bailout;
7078                 }
7079         } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7080                 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7081                         feature = 0x14; /* OVERWRITE EXT */
7082                         lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7083                         count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7084                         if (invert)
7085                                 count |= 0x80; /* INVERT PATTERN */
7086                         if (ause)
7087                                 count |= 0x10; /* FAILURE MODE */
7088                 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7089                         feature = 0x12; /* BLOCK ERASE EXT */
7090                         lba = 0x0000426B4572;
7091                         count = 0;
7092                         if (ause)
7093                                 count |= 0x10; /* FAILURE MODE */
7094                 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7095                         feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7096                         lba = 0x000043727970;
7097                         count = 0;
7098                         if (ause)
7099                                 count |= 0x10; /* FAILURE MODE */
7100                 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7101                         feature = 0x00; /* SANITIZE STATUS EXT */
7102                         lba = 0;
7103                         count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7104                 } else {
7105                         error = 1;
7106                         goto sanitize_bailout;
7107                 }
7108
7109                 error = ata_do_cmd(device,
7110                                    ccb,
7111                                    retry_count,
7112                                    /*flags*/CAM_DIR_NONE,
7113                                    /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7114                                    /*ata_flags*/0,
7115                                    /*tag_action*/MSG_SIMPLE_Q_TAG,
7116                                    /*command*/ATA_SANITIZE,
7117                                    /*features*/feature,
7118                                    /*lba*/lba,
7119                                    /*sector_count*/count,
7120                                    /*data_ptr*/NULL,
7121                                    /*dxfer_len*/0,
7122                                    /*timeout*/ use_timeout,
7123                                    /*is48bit*/1);
7124         }
7125
7126         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7127                 struct scsi_sense_data *sense;
7128                 int error_code, sense_key, asc, ascq;
7129
7130                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7131                     CAM_SCSI_STATUS_ERROR) {
7132                         sense = &ccb->csio.sense_data;
7133                         scsi_extract_sense_len(sense, ccb->csio.sense_len -
7134                             ccb->csio.sense_resid, &error_code, &sense_key,
7135                             &asc, &ascq, /*show_errors*/ 1);
7136
7137                         if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7138                             asc == 0x20 && ascq == 0x00)
7139                                 warnx("sanitize is not supported by "
7140                                       "this device");
7141                         else
7142                                 warnx("error sanitizing this device");
7143                 } else
7144                         warnx("error sanitizing this device");
7145
7146                 if (arglist & CAM_ARG_VERBOSE) {
7147                         cam_error_print(device, ccb, CAM_ESF_ALL,
7148                                         CAM_EPF_ALL, stderr);
7149                 }
7150                 error = 1;
7151                 goto sanitize_bailout;
7152         }
7153
7154         /*
7155          * If we ran in non-immediate mode, we already checked for errors
7156          * above and printed out any necessary information.  If we're in
7157          * immediate mode, we need to loop through and get status
7158          * information periodically.
7159          */
7160         if (immediate == 0) {
7161                 if (quiet == 0) {
7162                         fprintf(stdout, "Sanitize Complete\n");
7163                 }
7164                 goto sanitize_bailout;
7165         }
7166
7167 doreport:
7168         if (dt == CC_DT_SCSI) {
7169                 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7170         } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7171                 error = sanitize_wait_ata(device, ccb, quiet, dt);
7172         } else
7173                 error = 1;
7174         if (error == 0 && quiet == 0)
7175                 fprintf(stdout, "Sanitize Complete                      \n");
7176
7177 sanitize_bailout:
7178         if (fd >= 0)
7179                 close(fd);
7180         if (data_ptr != NULL)
7181                 free(data_ptr);
7182         cam_freeccb(ccb);
7183
7184         return (error);
7185 }
7186
7187 static int
7188 scsireportluns(struct cam_device *device, int argc, char **argv,
7189                char *combinedopt, int task_attr, int retry_count, int timeout)
7190 {
7191         union ccb *ccb;
7192         int c, countonly, lunsonly;
7193         struct scsi_report_luns_data *lundata;
7194         int alloc_len;
7195         uint8_t report_type;
7196         uint32_t list_len, i, j;
7197         int retval;
7198
7199         retval = 0;
7200         lundata = NULL;
7201         report_type = RPL_REPORT_DEFAULT;
7202         ccb = cam_getccb(device);
7203
7204         if (ccb == NULL) {
7205                 warnx("%s: error allocating ccb", __func__);
7206                 return (1);
7207         }
7208
7209         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7210
7211         countonly = 0;
7212         lunsonly = 0;
7213
7214         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7215                 switch (c) {
7216                 case 'c':
7217                         countonly++;
7218                         break;
7219                 case 'l':
7220                         lunsonly++;
7221                         break;
7222                 case 'r':
7223                         if (strcasecmp(optarg, "default") == 0)
7224                                 report_type = RPL_REPORT_DEFAULT;
7225                         else if (strcasecmp(optarg, "wellknown") == 0)
7226                                 report_type = RPL_REPORT_WELLKNOWN;
7227                         else if (strcasecmp(optarg, "all") == 0)
7228                                 report_type = RPL_REPORT_ALL;
7229                         else {
7230                                 warnx("%s: invalid report type \"%s\"",
7231                                       __func__, optarg);
7232                                 retval = 1;
7233                                 goto bailout;
7234                         }
7235                         break;
7236                 default:
7237                         break;
7238                 }
7239         }
7240
7241         if ((countonly != 0)
7242          && (lunsonly != 0)) {
7243                 warnx("%s: you can only specify one of -c or -l", __func__);
7244                 retval = 1;
7245                 goto bailout;
7246         }
7247         /*
7248          * According to SPC-4, the allocation length must be at least 16
7249          * bytes -- enough for the header and one LUN.
7250          */
7251         alloc_len = sizeof(*lundata) + 8;
7252
7253 retry:
7254
7255         lundata = malloc(alloc_len);
7256
7257         if (lundata == NULL) {
7258                 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7259                 retval = 1;
7260                 goto bailout;
7261         }
7262
7263         scsi_report_luns(&ccb->csio,
7264                          /*retries*/ retry_count,
7265                          /*cbfcnp*/ NULL,
7266                          /*tag_action*/ task_attr,
7267                          /*select_report*/ report_type,
7268                          /*rpl_buf*/ lundata,
7269                          /*alloc_len*/ alloc_len,
7270                          /*sense_len*/ SSD_FULL_SIZE,
7271                          /*timeout*/ timeout ? timeout : 5000);
7272
7273         /* Disable freezing the device queue */
7274         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7275
7276         if (arglist & CAM_ARG_ERR_RECOVER)
7277                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7278
7279         if (cam_send_ccb(device, ccb) < 0) {
7280                 warn("error sending REPORT LUNS command");
7281                 retval = 1;
7282                 goto bailout;
7283         }
7284
7285         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7286                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7287                 retval = 1;
7288                 goto bailout;
7289         }
7290
7291
7292         list_len = scsi_4btoul(lundata->length);
7293
7294         /*
7295          * If we need to list the LUNs, and our allocation
7296          * length was too short, reallocate and retry.
7297          */
7298         if ((countonly == 0)
7299          && (list_len > (alloc_len - sizeof(*lundata)))) {
7300                 alloc_len = list_len + sizeof(*lundata);
7301                 free(lundata);
7302                 goto retry;
7303         }
7304
7305         if (lunsonly == 0)
7306                 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7307                         ((list_len / 8) > 1) ? "s" : "");
7308
7309         if (countonly != 0)
7310                 goto bailout;
7311
7312         for (i = 0; i < (list_len / 8); i++) {
7313                 int no_more;
7314
7315                 no_more = 0;
7316                 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7317                         if (j != 0)
7318                                 fprintf(stdout, ",");
7319                         switch (lundata->luns[i].lundata[j] &
7320                                 RPL_LUNDATA_ATYP_MASK) {
7321                         case RPL_LUNDATA_ATYP_PERIPH:
7322                                 if ((lundata->luns[i].lundata[j] &
7323                                     RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7324                                         fprintf(stdout, "%d:",
7325                                                 lundata->luns[i].lundata[j] &
7326                                                 RPL_LUNDATA_PERIPH_BUS_MASK);
7327                                 else if ((j == 0)
7328                                       && ((lundata->luns[i].lundata[j+2] &
7329                                           RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7330                                         no_more = 1;
7331
7332                                 fprintf(stdout, "%d",
7333                                         lundata->luns[i].lundata[j+1]);
7334                                 break;
7335                         case RPL_LUNDATA_ATYP_FLAT: {
7336                                 uint8_t tmplun[2];
7337                                 tmplun[0] = lundata->luns[i].lundata[j] &
7338                                         RPL_LUNDATA_FLAT_LUN_MASK;
7339                                 tmplun[1] = lundata->luns[i].lundata[j+1];
7340
7341                                 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7342                                 no_more = 1;
7343                                 break;
7344                         }
7345                         case RPL_LUNDATA_ATYP_LUN:
7346                                 fprintf(stdout, "%d:%d:%d",
7347                                         (lundata->luns[i].lundata[j+1] &
7348                                         RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7349                                         lundata->luns[i].lundata[j] &
7350                                         RPL_LUNDATA_LUN_TARG_MASK,
7351                                         lundata->luns[i].lundata[j+1] &
7352                                         RPL_LUNDATA_LUN_LUN_MASK);
7353                                 break;
7354                         case RPL_LUNDATA_ATYP_EXTLUN: {
7355                                 int field_len_code, eam_code;
7356
7357                                 eam_code = lundata->luns[i].lundata[j] &
7358                                         RPL_LUNDATA_EXT_EAM_MASK;
7359                                 field_len_code = (lundata->luns[i].lundata[j] &
7360                                         RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7361
7362                                 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7363                                  && (field_len_code == 0x00)) {
7364                                         fprintf(stdout, "%d",
7365                                                 lundata->luns[i].lundata[j+1]);
7366                                 } else if ((eam_code ==
7367                                             RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7368                                         && (field_len_code == 0x03)) {
7369                                         uint8_t tmp_lun[8];
7370
7371                                         /*
7372                                          * This format takes up all 8 bytes.
7373                                          * If we aren't starting at offset 0,
7374                                          * that's a bug.
7375                                          */
7376                                         if (j != 0) {
7377                                                 fprintf(stdout, "Invalid "
7378                                                         "offset %d for "
7379                                                         "Extended LUN not "
7380                                                         "specified format", j);
7381                                                 no_more = 1;
7382                                                 break;
7383                                         }
7384                                         bzero(tmp_lun, sizeof(tmp_lun));
7385                                         bcopy(&lundata->luns[i].lundata[j+1],
7386                                               &tmp_lun[1], sizeof(tmp_lun) - 1);
7387                                         fprintf(stdout, "%#jx",
7388                                                (intmax_t)scsi_8btou64(tmp_lun));
7389                                         no_more = 1;
7390                                 } else {
7391                                         fprintf(stderr, "Unknown Extended LUN"
7392                                                 "Address method %#x, length "
7393                                                 "code %#x", eam_code,
7394                                                 field_len_code);
7395                                         no_more = 1;
7396                                 }
7397                                 break;
7398                         }
7399                         default:
7400                                 fprintf(stderr, "Unknown LUN address method "
7401                                         "%#x\n", lundata->luns[i].lundata[0] &
7402                                         RPL_LUNDATA_ATYP_MASK);
7403                                 break;
7404                         }
7405                         /*
7406                          * For the flat addressing method, there are no
7407                          * other levels after it.
7408                          */
7409                         if (no_more != 0)
7410                                 break;
7411                 }
7412                 fprintf(stdout, "\n");
7413         }
7414
7415 bailout:
7416
7417         cam_freeccb(ccb);
7418
7419         free(lundata);
7420
7421         return (retval);
7422 }
7423
7424 static int
7425 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7426                  char *combinedopt, int task_attr, int retry_count, int timeout)
7427 {
7428         union ccb *ccb;
7429         int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7430         struct scsi_read_capacity_data rcap;
7431         struct scsi_read_capacity_data_long rcaplong;
7432         uint64_t maxsector;
7433         uint32_t block_len;
7434         int retval;
7435         int c;
7436
7437         blocksizeonly = 0;
7438         humanize = 0;
7439         longonly = 0;
7440         numblocks = 0;
7441         quiet = 0;
7442         sizeonly = 0;
7443         baseten = 0;
7444         retval = 0;
7445
7446         ccb = cam_getccb(device);
7447
7448         if (ccb == NULL) {
7449                 warnx("%s: error allocating ccb", __func__);
7450                 return (1);
7451         }
7452
7453         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7454
7455         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7456                 switch (c) {
7457                 case 'b':
7458                         blocksizeonly++;
7459                         break;
7460                 case 'h':
7461                         humanize++;
7462                         baseten = 0;
7463                         break;
7464                 case 'H':
7465                         humanize++;
7466                         baseten++;
7467                         break;
7468                 case 'l':
7469                         longonly++;
7470                         break;
7471                 case 'N':
7472                         numblocks++;
7473                         break;
7474                 case 'q':
7475                         quiet++;
7476                         break;
7477                 case 's':
7478                         sizeonly++;
7479                         break;
7480                 default:
7481                         break;
7482                 }
7483         }
7484
7485         if ((blocksizeonly != 0)
7486          && (numblocks != 0)) {
7487                 warnx("%s: you can only specify one of -b or -N", __func__);
7488                 retval = 1;
7489                 goto bailout;
7490         }
7491
7492         if ((blocksizeonly != 0)
7493          && (sizeonly != 0)) {
7494                 warnx("%s: you can only specify one of -b or -s", __func__);
7495                 retval = 1;
7496                 goto bailout;
7497         }
7498
7499         if ((humanize != 0)
7500          && (quiet != 0)) {
7501                 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7502                 retval = 1;
7503                 goto bailout;
7504         }
7505
7506         if ((humanize != 0)
7507          && (blocksizeonly != 0)) {
7508                 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7509                 retval = 1;
7510                 goto bailout;
7511         }
7512
7513         if (longonly != 0)
7514                 goto long_only;
7515
7516         scsi_read_capacity(&ccb->csio,
7517                            /*retries*/ retry_count,
7518                            /*cbfcnp*/ NULL,
7519                            /*tag_action*/ task_attr,
7520                            &rcap,
7521                            SSD_FULL_SIZE,
7522                            /*timeout*/ timeout ? timeout : 5000);
7523
7524         /* Disable freezing the device queue */
7525         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7526
7527         if (arglist & CAM_ARG_ERR_RECOVER)
7528                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7529
7530         if (cam_send_ccb(device, ccb) < 0) {
7531                 warn("error sending READ CAPACITY command");
7532                 retval = 1;
7533                 goto bailout;
7534         }
7535
7536         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7537                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7538                 retval = 1;
7539                 goto bailout;
7540         }
7541
7542         maxsector = scsi_4btoul(rcap.addr);
7543         block_len = scsi_4btoul(rcap.length);
7544
7545         /*
7546          * A last block of 2^32-1 means that the true capacity is over 2TB,
7547          * and we need to issue the long READ CAPACITY to get the real
7548          * capacity.  Otherwise, we're all set.
7549          */
7550         if (maxsector != 0xffffffff)
7551                 goto do_print;
7552
7553 long_only:
7554         scsi_read_capacity_16(&ccb->csio,
7555                               /*retries*/ retry_count,
7556                               /*cbfcnp*/ NULL,
7557                               /*tag_action*/ task_attr,
7558                               /*lba*/ 0,
7559                               /*reladdr*/ 0,
7560                               /*pmi*/ 0,
7561                               /*rcap_buf*/ (uint8_t *)&rcaplong,
7562                               /*rcap_buf_len*/ sizeof(rcaplong),
7563                               /*sense_len*/ SSD_FULL_SIZE,
7564                               /*timeout*/ timeout ? timeout : 5000);
7565
7566         /* Disable freezing the device queue */
7567         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7568
7569         if (arglist & CAM_ARG_ERR_RECOVER)
7570                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7571
7572         if (cam_send_ccb(device, ccb) < 0) {
7573                 warn("error sending READ CAPACITY (16) command");
7574                 retval = 1;
7575                 goto bailout;
7576         }
7577
7578         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7579                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7580                 retval = 1;
7581                 goto bailout;
7582         }
7583
7584         maxsector = scsi_8btou64(rcaplong.addr);
7585         block_len = scsi_4btoul(rcaplong.length);
7586
7587 do_print:
7588         if (blocksizeonly == 0) {
7589                 /*
7590                  * Humanize implies !quiet, and also implies numblocks.
7591                  */
7592                 if (humanize != 0) {
7593                         char tmpstr[6];
7594                         int64_t tmpbytes;
7595                         int ret;
7596
7597                         tmpbytes = (maxsector + 1) * block_len;
7598                         ret = humanize_number(tmpstr, sizeof(tmpstr),
7599                                               tmpbytes, "", HN_AUTOSCALE,
7600                                               HN_B | HN_DECIMAL |
7601                                               ((baseten != 0) ?
7602                                               HN_DIVISOR_1000 : 0));
7603                         if (ret == -1) {
7604                                 warnx("%s: humanize_number failed!", __func__);
7605                                 retval = 1;
7606                                 goto bailout;
7607                         }
7608                         fprintf(stdout, "Device Size: %s%s", tmpstr,
7609                                 (sizeonly == 0) ?  ", " : "\n");
7610                 } else if (numblocks != 0) {
7611                         fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7612                                 "Blocks: " : "", (uintmax_t)maxsector + 1,
7613                                 (sizeonly == 0) ? ", " : "\n");
7614                 } else {
7615                         fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7616                                 "Last Block: " : "", (uintmax_t)maxsector,
7617                                 (sizeonly == 0) ? ", " : "\n");
7618                 }
7619         }
7620         if (sizeonly == 0)
7621                 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7622                         "Block Length: " : "", block_len, (quiet == 0) ?
7623                         " bytes" : "");
7624 bailout:
7625         cam_freeccb(ccb);
7626
7627         return (retval);
7628 }
7629
7630 static int
7631 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7632        int retry_count, int timeout)
7633 {
7634         int c, error = 0;
7635         union ccb *ccb;
7636         uint8_t *smp_request = NULL, *smp_response = NULL;
7637         int request_size = 0, response_size = 0;
7638         int fd_request = 0, fd_response = 0;
7639         char *datastr = NULL;
7640         struct get_hook hook;
7641         int retval;
7642         int flags = 0;
7643
7644         /*
7645          * Note that at the moment we don't support sending SMP CCBs to
7646          * devices that aren't probed by CAM.
7647          */
7648         ccb = cam_getccb(device);
7649         if (ccb == NULL) {
7650                 warnx("%s: error allocating CCB", __func__);
7651                 return (1);
7652         }
7653
7654         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7655
7656         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7657                 switch (c) {
7658                 case 'R':
7659                         arglist |= CAM_ARG_CMD_IN;
7660                         response_size = strtol(optarg, NULL, 0);
7661                         if (response_size <= 0) {
7662                                 warnx("invalid number of response bytes %d",
7663                                       response_size);
7664                                 error = 1;
7665                                 goto smpcmd_bailout;
7666                         }
7667                         hook.argc = argc - optind;
7668                         hook.argv = argv + optind;
7669                         hook.got = 0;
7670                         optind++;
7671                         datastr = cget(&hook, NULL);
7672                         /*
7673                          * If the user supplied "-" instead of a format, he
7674                          * wants the data to be written to stdout.
7675                          */
7676                         if ((datastr != NULL)
7677                          && (datastr[0] == '-'))
7678                                 fd_response = 1;
7679
7680                         smp_response = (u_int8_t *)malloc(response_size);
7681                         if (smp_response == NULL) {
7682                                 warn("can't malloc memory for SMP response");
7683                                 error = 1;
7684                                 goto smpcmd_bailout;
7685                         }
7686                         break;
7687                 case 'r':
7688                         arglist |= CAM_ARG_CMD_OUT;
7689                         request_size = strtol(optarg, NULL, 0);
7690                         if (request_size <= 0) {
7691                                 warnx("invalid number of request bytes %d",
7692                                       request_size);
7693                                 error = 1;
7694                                 goto smpcmd_bailout;
7695                         }
7696                         hook.argc = argc - optind;
7697                         hook.argv = argv + optind;
7698                         hook.got = 0;
7699                         datastr = cget(&hook, NULL);
7700                         smp_request = (u_int8_t *)malloc(request_size);
7701                         if (smp_request == NULL) {
7702                                 warn("can't malloc memory for SMP request");
7703                                 error = 1;
7704                                 goto smpcmd_bailout;
7705                         }
7706                         bzero(smp_request, request_size);
7707                         /*
7708                          * If the user supplied "-" instead of a format, he
7709                          * wants the data to be read from stdin.
7710                          */
7711                         if ((datastr != NULL)
7712                          && (datastr[0] == '-'))
7713                                 fd_request = 1;
7714                         else
7715                                 buff_encode_visit(smp_request, request_size,
7716                                                   datastr,
7717                                                   iget, &hook);
7718                         optind += hook.got;
7719                         break;
7720                 default:
7721                         break;
7722                 }
7723         }
7724
7725         /*
7726          * If fd_data is set, and we're writing to the device, we need to
7727          * read the data the user wants written from stdin.
7728          */
7729         if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7730                 ssize_t amt_read;
7731                 int amt_to_read = request_size;
7732                 u_int8_t *buf_ptr = smp_request;
7733
7734                 for (amt_read = 0; amt_to_read > 0;
7735                      amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7736                         if (amt_read == -1) {
7737                                 warn("error reading data from stdin");
7738                                 error = 1;
7739                                 goto smpcmd_bailout;
7740                         }
7741                         amt_to_read -= amt_read;
7742                         buf_ptr += amt_read;
7743                 }
7744         }
7745
7746         if (((arglist & CAM_ARG_CMD_IN) == 0)
7747          || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7748                 warnx("%s: need both the request (-r) and response (-R) "
7749                       "arguments", __func__);
7750                 error = 1;
7751                 goto smpcmd_bailout;
7752         }
7753
7754         flags |= CAM_DEV_QFRZDIS;
7755
7756         cam_fill_smpio(&ccb->smpio,
7757                        /*retries*/ retry_count,
7758                        /*cbfcnp*/ NULL,
7759                        /*flags*/ flags,
7760                        /*smp_request*/ smp_request,
7761                        /*smp_request_len*/ request_size,
7762                        /*smp_response*/ smp_response,
7763                        /*smp_response_len*/ response_size,
7764                        /*timeout*/ timeout ? timeout : 5000);
7765
7766         ccb->smpio.flags = SMP_FLAG_NONE;
7767
7768         if (((retval = cam_send_ccb(device, ccb)) < 0)
7769          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7770                 const char warnstr[] = "error sending command";
7771
7772                 if (retval < 0)
7773                         warn(warnstr);
7774                 else
7775                         warnx(warnstr);
7776
7777                 if (arglist & CAM_ARG_VERBOSE) {
7778                         cam_error_print(device, ccb, CAM_ESF_ALL,
7779                                         CAM_EPF_ALL, stderr);
7780                 }
7781         }
7782
7783         if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7784          && (response_size > 0)) {
7785                 if (fd_response == 0) {
7786                         buff_decode_visit(smp_response, response_size,
7787                                           datastr, arg_put, NULL);
7788                         fprintf(stdout, "\n");
7789                 } else {
7790                         ssize_t amt_written;
7791                         int amt_to_write = response_size;
7792                         u_int8_t *buf_ptr = smp_response;
7793
7794                         for (amt_written = 0; (amt_to_write > 0) &&
7795                              (amt_written = write(STDOUT_FILENO, buf_ptr,
7796                                                   amt_to_write)) > 0;){
7797                                 amt_to_write -= amt_written;
7798                                 buf_ptr += amt_written;
7799                         }
7800                         if (amt_written == -1) {
7801                                 warn("error writing data to stdout");
7802                                 error = 1;
7803                                 goto smpcmd_bailout;
7804                         } else if ((amt_written == 0)
7805                                 && (amt_to_write > 0)) {
7806                                 warnx("only wrote %u bytes out of %u",
7807                                       response_size - amt_to_write,
7808                                       response_size);
7809                         }
7810                 }
7811         }
7812 smpcmd_bailout:
7813         if (ccb != NULL)
7814                 cam_freeccb(ccb);
7815
7816         if (smp_request != NULL)
7817                 free(smp_request);
7818
7819         if (smp_response != NULL)
7820                 free(smp_response);
7821
7822         return (error);
7823 }
7824
7825 static int
7826 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7827        int retry_count, int timeout)
7828 {
7829         int c, error = 0;
7830         union ccb *ccb;
7831         int32_t mmc_opcode = 0, mmc_arg = 0;
7832         int32_t mmc_flags = -1;
7833         int retval;
7834         int is_write = 0;
7835         int is_bw_4 = 0, is_bw_1 = 0;
7836         int is_frequency = 0;
7837         int is_highspeed = 0, is_stdspeed = 0;
7838         int is_info_request = 0;
7839         int flags = 0;
7840         uint8_t mmc_data_byte = 0;
7841         uint32_t mmc_frequency = 0;
7842
7843         /* For IO_RW_EXTENDED command */
7844         uint8_t *mmc_data = NULL;
7845         struct mmc_data mmc_d;
7846         int mmc_data_len = 0;
7847
7848         /*
7849          * Note that at the moment we don't support sending SMP CCBs to
7850          * devices that aren't probed by CAM.
7851          */
7852         ccb = cam_getccb(device);
7853         if (ccb == NULL) {
7854                 warnx("%s: error allocating CCB", __func__);
7855                 return (1);
7856         }
7857
7858         bzero(&(&ccb->ccb_h)[1],
7859               sizeof(union ccb) - sizeof(struct ccb_hdr));
7860
7861         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7862                 switch (c) {
7863                 case '4':
7864                         is_bw_4 = 1;
7865                         break;
7866                 case '1':
7867                         is_bw_1 = 1;
7868                         break;
7869                 case 'S':
7870                         if (!strcmp(optarg, "high"))
7871                                 is_highspeed = 1;
7872                         else
7873                                 is_stdspeed = 1;
7874                         break;
7875                 case 'I':
7876                         is_info_request = 1;
7877                         break;
7878                 case 'F':
7879                         is_frequency = 1;
7880                         mmc_frequency = strtol(optarg, NULL, 0);
7881                         break;
7882                 case 'c':
7883                         mmc_opcode = strtol(optarg, NULL, 0);
7884                         if (mmc_opcode < 0) {
7885                                 warnx("invalid MMC opcode %d",
7886                                       mmc_opcode);
7887                                 error = 1;
7888                                 goto mmccmd_bailout;
7889                         }
7890                         break;
7891                 case 'a':
7892                         mmc_arg = strtol(optarg, NULL, 0);
7893                         if (mmc_arg < 0) {
7894                                 warnx("invalid MMC arg %d",
7895                                       mmc_arg);
7896                                 error = 1;
7897                                 goto mmccmd_bailout;
7898                         }
7899                         break;
7900                 case 'f':
7901                         mmc_flags = strtol(optarg, NULL, 0);
7902                         if (mmc_flags < 0) {
7903                                 warnx("invalid MMC flags %d",
7904                                       mmc_flags);
7905                                 error = 1;
7906                                 goto mmccmd_bailout;
7907                         }
7908                         break;
7909                 case 'l':
7910                         mmc_data_len = strtol(optarg, NULL, 0);
7911                         if (mmc_data_len <= 0) {
7912                                 warnx("invalid MMC data len %d",
7913                                       mmc_data_len);
7914                                 error = 1;
7915                                 goto mmccmd_bailout;
7916                         }
7917                         break;
7918                 case 'W':
7919                         is_write = 1;
7920                         break;
7921                 case 'b':
7922                         mmc_data_byte = strtol(optarg, NULL, 0);
7923                         break;
7924                 default:
7925                         break;
7926                 }
7927         }
7928         flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7929
7930         /* If flags are left default, supply the right flags */
7931         if (mmc_flags < 0)
7932                 switch (mmc_opcode) {
7933                 case MMC_GO_IDLE_STATE:
7934                         mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7935                         break;
7936                 case IO_SEND_OP_COND:
7937                         mmc_flags = MMC_RSP_R4;
7938                         break;
7939                 case SD_SEND_RELATIVE_ADDR:
7940                         mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7941                         break;
7942                 case MMC_SELECT_CARD:
7943                         mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7944                         mmc_arg = mmc_arg << 16;
7945                         break;
7946                 case SD_IO_RW_DIRECT:
7947                         mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7948                         mmc_arg = SD_IO_RW_ADR(mmc_arg);
7949                         if (is_write)
7950                                 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7951                         break;
7952                 case SD_IO_RW_EXTENDED:
7953                         mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7954                         mmc_arg = SD_IO_RW_ADR(mmc_arg);
7955                         int len_arg = mmc_data_len;
7956                         if (mmc_data_len == 512)
7957                                 len_arg = 0;
7958
7959                         // Byte mode
7960                         mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7961                         // Block mode
7962 //                        mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7963                         break;
7964                 default:
7965                         mmc_flags = MMC_RSP_R1;
7966                         break;
7967                 }
7968
7969         // Switch bus width instead of sending IO command
7970         if (is_bw_4 || is_bw_1) {
7971                 struct ccb_trans_settings_mmc *cts;
7972                 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7973                 ccb->ccb_h.flags = 0;
7974                 cts = &ccb->cts.proto_specific.mmc;
7975                 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7976                 cts->ios_valid = MMC_BW;
7977                 if (((retval = cam_send_ccb(device, ccb)) < 0)
7978                     || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7979                         warn("Error sending command");
7980                 } else {
7981                         printf("Parameters set OK\n");
7982                 }
7983                 cam_freeccb(ccb);
7984                 return (retval);
7985         }
7986
7987         if (is_frequency) {
7988                 struct ccb_trans_settings_mmc *cts;
7989                 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7990                 ccb->ccb_h.flags = 0;
7991                 cts = &ccb->cts.proto_specific.mmc;
7992                 cts->ios.clock = mmc_frequency;
7993                 cts->ios_valid = MMC_CLK;
7994                 if (((retval = cam_send_ccb(device, ccb)) < 0)
7995                     || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7996                         warn("Error sending command");
7997                 } else {
7998                         printf("Parameters set OK\n");
7999                 }
8000                 cam_freeccb(ccb);
8001                 return (retval);
8002         }
8003
8004         // Switch bus speed instead of sending IO command
8005         if (is_stdspeed || is_highspeed) {
8006                 struct ccb_trans_settings_mmc *cts;
8007                 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
8008                 ccb->ccb_h.flags = 0;
8009                 cts = &ccb->cts.proto_specific.mmc;
8010                 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
8011                 cts->ios_valid = MMC_BT;
8012                 if (((retval = cam_send_ccb(device, ccb)) < 0)
8013                     || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8014                         warn("Error sending command");
8015                 } else {
8016                         printf("Speed set OK (HS: %d)\n", is_highspeed);
8017                 }
8018                 cam_freeccb(ccb);
8019                 return (retval);
8020         }
8021
8022         // Get information about controller and its settings
8023         if (is_info_request) {
8024                 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8025                 ccb->ccb_h.flags = 0;
8026                 struct ccb_trans_settings_mmc *cts;
8027                 cts = &ccb->cts.proto_specific.mmc;
8028                 if (((retval = cam_send_ccb(device, ccb)) < 0)
8029                     || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8030                         warn("Error sending command");
8031                         return (retval);
8032                 }
8033                 printf("Host controller information\n");
8034                 printf("Host OCR: 0x%x\n", cts->host_ocr);
8035                 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8036                 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8037                 printf("Supported bus width:\n");
8038                 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8039                         printf(" 4 bit\n");
8040                 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8041                         printf(" 8 bit\n");
8042
8043                 printf("Supported operating modes:\n");
8044                 if (cts->host_caps & MMC_CAP_HSPEED)
8045                         printf(" Can do High Speed transfers\n");
8046                 if (cts->host_caps & MMC_CAP_UHS_SDR12)
8047                         printf(" Can do UHS SDR12\n");
8048                 if (cts->host_caps & MMC_CAP_UHS_SDR25)
8049                         printf(" Can do UHS SDR25\n");
8050                 if (cts->host_caps & MMC_CAP_UHS_SDR50)
8051                         printf(" Can do UHS SDR50\n");
8052                 if (cts->host_caps & MMC_CAP_UHS_SDR104)
8053                         printf(" Can do UHS SDR104\n");
8054                 if (cts->host_caps & MMC_CAP_UHS_DDR50)
8055                         printf(" Can do UHS DDR50\n");
8056                 if (cts->host_caps & MMC_CAP_MMC_DDR52_120)
8057                         printf(" Can do eMMC DDR52 at 1.2V\n");
8058                 if (cts->host_caps & MMC_CAP_MMC_DDR52_180)
8059                         printf(" Can do eMMC DDR52 at 1.8V\n");
8060                 if (cts->host_caps & MMC_CAP_MMC_HS200_120)
8061                         printf(" Can do eMMC HS200 at 1.2V\n");
8062                 if (cts->host_caps & MMC_CAP_MMC_HS200_180)
8063                         printf(" Can do eMMC HS200 at 1.8V\n");
8064                 if (cts->host_caps & MMC_CAP_MMC_HS400_120)
8065                         printf(" Can do eMMC HS400 at 1.2V\n");
8066                 if (cts->host_caps & MMC_CAP_MMC_HS400_180)
8067                         printf(" Can do eMMC HS400 at 1.8V\n");
8068
8069                 printf("Supported VCCQ voltages:\n");
8070                 if (cts->host_caps & MMC_CAP_SIGNALING_120)
8071                         printf(" 1.2V\n");
8072                 if (cts->host_caps & MMC_CAP_SIGNALING_180)
8073                         printf(" 1.8V\n");
8074                 if (cts->host_caps & MMC_CAP_SIGNALING_330)
8075                         printf(" 3.3V\n");
8076
8077                 printf("Current settings:\n");
8078                 printf(" Bus width: ");
8079                 switch (cts->ios.bus_width) {
8080                 case bus_width_1:
8081                         printf("1 bit\n");
8082                         break;
8083                 case bus_width_4:
8084                         printf("4 bit\n");
8085                         break;
8086                 case bus_width_8:
8087                         printf("8 bit\n");
8088                         break;
8089                 }
8090                 printf(" Freq: %d.%03d MHz%s\n",
8091                        cts->ios.clock / 1000000,
8092                        (cts->ios.clock / 1000) % 1000,
8093                        cts->ios.timing == bus_timing_hs ? " (high-speed timing)" : "");
8094
8095                 printf(" VCCQ: ");
8096                 switch (cts->ios.vccq) {
8097                 case vccq_330:
8098                         printf("3.3V\n");
8099                         break;
8100                 case vccq_180:
8101                         printf("1.8V\n");
8102                         break;
8103                 case vccq_120:
8104                         printf("1.2V\n");
8105                         break;
8106                 }
8107                 return (0);
8108         }
8109
8110         printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8111
8112         if (mmc_data_len > 0) {
8113                 flags |= CAM_DIR_IN;
8114                 mmc_data = malloc(mmc_data_len);
8115                 memset(mmc_data, 0, mmc_data_len);
8116                 memset(&mmc_d, 0, sizeof(mmc_d));
8117                 mmc_d.len = mmc_data_len;
8118                 mmc_d.data = mmc_data;
8119                 mmc_d.flags = MMC_DATA_READ;
8120         } else flags |= CAM_DIR_NONE;
8121
8122         cam_fill_mmcio(&ccb->mmcio,
8123                        /*retries*/ retry_count,
8124                        /*cbfcnp*/ NULL,
8125                        /*flags*/ flags,
8126                        /*mmc_opcode*/ mmc_opcode,
8127                        /*mmc_arg*/ mmc_arg,
8128                        /*mmc_flags*/ mmc_flags,
8129                        /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8130                        /*timeout*/ timeout ? timeout : 5000);
8131
8132         if (((retval = cam_send_ccb(device, ccb)) < 0)
8133          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8134                 const char warnstr[] = "error sending command";
8135
8136                 if (retval < 0)
8137                         warn(warnstr);
8138                 else
8139                         warnx(warnstr);
8140
8141                 if (arglist & CAM_ARG_VERBOSE) {
8142                         cam_error_print(device, ccb, CAM_ESF_ALL,
8143                                         CAM_EPF_ALL, stderr);
8144                 }
8145         }
8146
8147         if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8148                 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8149                        ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8150                        ccb->mmcio.cmd.resp[1],
8151                        ccb->mmcio.cmd.resp[2],
8152                        ccb->mmcio.cmd.resp[3]);
8153
8154                 switch (mmc_opcode) {
8155                 case SD_IO_RW_DIRECT:
8156                         printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8157                                SD_R5_DATA(ccb->mmcio.cmd.resp),
8158                                (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8159                         break;
8160                 case SD_IO_RW_EXTENDED:
8161                         printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8162                         hexdump(mmc_data, mmc_data_len, NULL, 0);
8163                         break;
8164                 case SD_SEND_RELATIVE_ADDR:
8165                         printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8166                         break;
8167                 default:
8168                         printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8169                 }
8170         }
8171 mmccmd_bailout:
8172         if (ccb != NULL)
8173                 cam_freeccb(ccb);
8174
8175         if (mmc_data_len > 0 && mmc_data != NULL)
8176                 free(mmc_data);
8177
8178         return (error);
8179 }
8180
8181 static int
8182 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8183                  char *combinedopt, int retry_count, int timeout)
8184 {
8185         union ccb *ccb;
8186         struct smp_report_general_request *request = NULL;
8187         struct smp_report_general_response *response = NULL;
8188         struct sbuf *sb = NULL;
8189         int error = 0;
8190         int c, long_response = 0;
8191         int retval;
8192
8193         /*
8194          * Note that at the moment we don't support sending SMP CCBs to
8195          * devices that aren't probed by CAM.
8196          */
8197         ccb = cam_getccb(device);
8198         if (ccb == NULL) {
8199                 warnx("%s: error allocating CCB", __func__);
8200                 return (1);
8201         }
8202
8203         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8204
8205         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8206                 switch (c) {
8207                 case 'l':
8208                         long_response = 1;
8209                         break;
8210                 default:
8211                         break;
8212                 }
8213         }
8214         request = malloc(sizeof(*request));
8215         if (request == NULL) {
8216                 warn("%s: unable to allocate %zd bytes", __func__,
8217                      sizeof(*request));
8218                 error = 1;
8219                 goto bailout;
8220         }
8221
8222         response = malloc(sizeof(*response));
8223         if (response == NULL) {
8224                 warn("%s: unable to allocate %zd bytes", __func__,
8225                      sizeof(*response));
8226                 error = 1;
8227                 goto bailout;
8228         }
8229
8230 try_long:
8231         smp_report_general(&ccb->smpio,
8232                            retry_count,
8233                            /*cbfcnp*/ NULL,
8234                            request,
8235                            /*request_len*/ sizeof(*request),
8236                            (uint8_t *)response,
8237                            /*response_len*/ sizeof(*response),
8238                            /*long_response*/ long_response,
8239                            timeout);
8240
8241         if (((retval = cam_send_ccb(device, ccb)) < 0)
8242          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8243                 const char warnstr[] = "error sending command";
8244
8245                 if (retval < 0)
8246                         warn(warnstr);
8247                 else
8248                         warnx(warnstr);
8249
8250                 if (arglist & CAM_ARG_VERBOSE) {
8251                         cam_error_print(device, ccb, CAM_ESF_ALL,
8252                                         CAM_EPF_ALL, stderr);
8253                 }
8254                 error = 1;
8255                 goto bailout;
8256         }
8257
8258         /*
8259          * If the device supports the long response bit, try again and see
8260          * if we can get all of the data.
8261          */
8262         if ((response->long_response & SMP_RG_LONG_RESPONSE)
8263          && (long_response == 0)) {
8264                 ccb->ccb_h.status = CAM_REQ_INPROG;
8265                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8266                 long_response = 1;
8267                 goto try_long;
8268         }
8269
8270         /*
8271          * XXX KDM detect and decode SMP errors here.
8272          */
8273         sb = sbuf_new_auto();
8274         if (sb == NULL) {
8275                 warnx("%s: error allocating sbuf", __func__);
8276                 goto bailout;
8277         }
8278
8279         smp_report_general_sbuf(response, sizeof(*response), sb);
8280
8281         if (sbuf_finish(sb) != 0) {
8282                 warnx("%s: sbuf_finish", __func__);
8283                 goto bailout;
8284         }
8285
8286         printf("%s", sbuf_data(sb));
8287
8288 bailout:
8289         if (ccb != NULL)
8290                 cam_freeccb(ccb);
8291
8292         if (request != NULL)
8293                 free(request);
8294
8295         if (response != NULL)
8296                 free(response);
8297
8298         if (sb != NULL)
8299                 sbuf_delete(sb);
8300
8301         return (error);
8302 }
8303
8304 static struct camcontrol_opts phy_ops[] = {
8305         {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8306         {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8307         {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8308         {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8309         {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8310         {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8311         {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8312         {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8313         {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8314         {NULL, 0, 0, NULL}
8315 };
8316
8317 static int
8318 smpphycontrol(struct cam_device *device, int argc, char **argv,
8319               char *combinedopt, int retry_count, int timeout)
8320 {
8321         union ccb *ccb;
8322         struct smp_phy_control_request *request = NULL;
8323         struct smp_phy_control_response *response = NULL;
8324         int long_response = 0;
8325         int retval = 0;
8326         int phy = -1;
8327         uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8328         int phy_op_set = 0;
8329         uint64_t attached_dev_name = 0;
8330         int dev_name_set = 0;
8331         uint32_t min_plr = 0, max_plr = 0;
8332         uint32_t pp_timeout_val = 0;
8333         int slumber_partial = 0;
8334         int set_pp_timeout_val = 0;
8335         int c;
8336
8337         /*
8338          * Note that at the moment we don't support sending SMP CCBs to
8339          * devices that aren't probed by CAM.
8340          */
8341         ccb = cam_getccb(device);
8342         if (ccb == NULL) {
8343                 warnx("%s: error allocating CCB", __func__);
8344                 return (1);
8345         }
8346
8347         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8348
8349         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8350                 switch (c) {
8351                 case 'a':
8352                 case 'A':
8353                 case 's':
8354                 case 'S': {
8355                         int enable = -1;
8356
8357                         if (strcasecmp(optarg, "enable") == 0)
8358                                 enable = 1;
8359                         else if (strcasecmp(optarg, "disable") == 0)
8360                                 enable = 2;
8361                         else {
8362                                 warnx("%s: Invalid argument %s", __func__,
8363                                       optarg);
8364                                 retval = 1;
8365                                 goto bailout;
8366                         }
8367                         switch (c) {
8368                         case 's':
8369                                 slumber_partial |= enable <<
8370                                                    SMP_PC_SAS_SLUMBER_SHIFT;
8371                                 break;
8372                         case 'S':
8373                                 slumber_partial |= enable <<
8374                                                    SMP_PC_SAS_PARTIAL_SHIFT;
8375                                 break;
8376                         case 'a':
8377                                 slumber_partial |= enable <<
8378                                                    SMP_PC_SATA_SLUMBER_SHIFT;
8379                                 break;
8380                         case 'A':
8381                                 slumber_partial |= enable <<
8382                                                    SMP_PC_SATA_PARTIAL_SHIFT;
8383                                 break;
8384                         default:
8385                                 warnx("%s: programmer error", __func__);
8386                                 retval = 1;
8387                                 goto bailout;
8388                                 break; /*NOTREACHED*/
8389                         }
8390                         break;
8391                 }
8392                 case 'd':
8393                         attached_dev_name = (uintmax_t)strtoumax(optarg,
8394                                                                  NULL,0);
8395                         dev_name_set = 1;
8396                         break;
8397                 case 'l':
8398                         long_response = 1;
8399                         break;
8400                 case 'm':
8401                         /*
8402                          * We don't do extensive checking here, so this
8403                          * will continue to work when new speeds come out.
8404                          */
8405                         min_plr = strtoul(optarg, NULL, 0);
8406                         if ((min_plr == 0)
8407                          || (min_plr > 0xf)) {
8408                                 warnx("%s: invalid link rate %x",
8409                                       __func__, min_plr);
8410                                 retval = 1;
8411                                 goto bailout;
8412                         }
8413                         break;
8414                 case 'M':
8415                         /*
8416                          * We don't do extensive checking here, so this
8417                          * will continue to work when new speeds come out.
8418                          */
8419                         max_plr = strtoul(optarg, NULL, 0);
8420                         if ((max_plr == 0)
8421                          || (max_plr > 0xf)) {
8422                                 warnx("%s: invalid link rate %x",
8423                                       __func__, max_plr);
8424                                 retval = 1;
8425                                 goto bailout;
8426                         }
8427                         break;
8428                 case 'o': {
8429                         camcontrol_optret optreturn;
8430                         cam_argmask argnums;
8431                         const char *subopt;
8432
8433                         if (phy_op_set != 0) {
8434                                 warnx("%s: only one phy operation argument "
8435                                       "(-o) allowed", __func__);
8436                                 retval = 1;
8437                                 goto bailout;
8438                         }
8439
8440                         phy_op_set = 1;
8441
8442                         /*
8443                          * Allow the user to specify the phy operation
8444                          * numerically, as well as with a name.  This will
8445                          * future-proof it a bit, so options that are added
8446                          * in future specs can be used.
8447                          */
8448                         if (isdigit(optarg[0])) {
8449                                 phy_operation = strtoul(optarg, NULL, 0);
8450                                 if ((phy_operation == 0)
8451                                  || (phy_operation > 0xff)) {
8452                                         warnx("%s: invalid phy operation %#x",
8453                                               __func__, phy_operation);
8454                                         retval = 1;
8455                                         goto bailout;
8456                                 }
8457                                 break;
8458                         }
8459                         optreturn = getoption(phy_ops, optarg, &phy_operation,
8460                                               &argnums, &subopt);
8461
8462                         if (optreturn == CC_OR_AMBIGUOUS) {
8463                                 warnx("%s: ambiguous option %s", __func__,
8464                                       optarg);
8465                                 usage(0);
8466                                 retval = 1;
8467                                 goto bailout;
8468                         } else if (optreturn == CC_OR_NOT_FOUND) {
8469                                 warnx("%s: option %s not found", __func__,
8470                                       optarg);
8471                                 usage(0);
8472                                 retval = 1;
8473                                 goto bailout;
8474                         }
8475                         break;
8476                 }
8477                 case 'p':
8478                         phy = atoi(optarg);
8479                         break;
8480                 case 'T':
8481                         pp_timeout_val = strtoul(optarg, NULL, 0);
8482                         if (pp_timeout_val > 15) {
8483                                 warnx("%s: invalid partial pathway timeout "
8484                                       "value %u, need a value less than 16",
8485                                       __func__, pp_timeout_val);
8486                                 retval = 1;
8487                                 goto bailout;
8488                         }
8489                         set_pp_timeout_val = 1;
8490                         break;
8491                 default:
8492                         break;
8493                 }
8494         }
8495
8496         if (phy == -1) {
8497                 warnx("%s: a PHY (-p phy) argument is required",__func__);
8498                 retval = 1;
8499                 goto bailout;
8500         }
8501
8502         if (((dev_name_set != 0)
8503           && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8504          || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8505           && (dev_name_set == 0))) {
8506                 warnx("%s: -d name and -o setdevname arguments both "
8507                       "required to set device name", __func__);
8508                 retval = 1;
8509                 goto bailout;
8510         }
8511
8512         request = malloc(sizeof(*request));
8513         if (request == NULL) {
8514                 warn("%s: unable to allocate %zd bytes", __func__,
8515                      sizeof(*request));
8516                 retval = 1;
8517                 goto bailout;
8518         }
8519
8520         response = malloc(sizeof(*response));
8521         if (response == NULL) {
8522                 warn("%s: unable to allocate %zd bytes", __func__,
8523                      sizeof(*response));
8524                 retval = 1;
8525                 goto bailout;
8526         }
8527
8528         smp_phy_control(&ccb->smpio,
8529                         retry_count,
8530                         /*cbfcnp*/ NULL,
8531                         request,
8532                         sizeof(*request),
8533                         (uint8_t *)response,
8534                         sizeof(*response),
8535                         long_response,
8536                         /*expected_exp_change_count*/ 0,
8537                         phy,
8538                         phy_operation,
8539                         (set_pp_timeout_val != 0) ? 1 : 0,
8540                         attached_dev_name,
8541                         min_plr,
8542                         max_plr,
8543                         slumber_partial,
8544                         pp_timeout_val,
8545                         timeout);
8546
8547         if (((retval = cam_send_ccb(device, ccb)) < 0)
8548          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8549                 const char warnstr[] = "error sending command";
8550
8551                 if (retval < 0)
8552                         warn(warnstr);
8553                 else
8554                         warnx(warnstr);
8555
8556                 if (arglist & CAM_ARG_VERBOSE) {
8557                         /*
8558                          * Use CAM_EPF_NORMAL so we only get one line of
8559                          * SMP command decoding.
8560                          */
8561                         cam_error_print(device, ccb, CAM_ESF_ALL,
8562                                         CAM_EPF_NORMAL, stderr);
8563                 }
8564                 retval = 1;
8565                 goto bailout;
8566         }
8567
8568         /* XXX KDM print out something here for success? */
8569 bailout:
8570         if (ccb != NULL)
8571                 cam_freeccb(ccb);
8572
8573         if (request != NULL)
8574                 free(request);
8575
8576         if (response != NULL)
8577                 free(response);
8578
8579         return (retval);
8580 }
8581
8582 static int
8583 smpmaninfo(struct cam_device *device, int argc, char **argv,
8584            char *combinedopt, int retry_count, int timeout)
8585 {
8586         union ccb *ccb;
8587         struct smp_report_manuf_info_request request;
8588         struct smp_report_manuf_info_response response;
8589         struct sbuf *sb = NULL;
8590         int long_response = 0;
8591         int retval = 0;
8592         int c;
8593
8594         /*
8595          * Note that at the moment we don't support sending SMP CCBs to
8596          * devices that aren't probed by CAM.
8597          */
8598         ccb = cam_getccb(device);
8599         if (ccb == NULL) {
8600                 warnx("%s: error allocating CCB", __func__);
8601                 return (1);
8602         }
8603
8604         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8605
8606         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8607                 switch (c) {
8608                 case 'l':
8609                         long_response = 1;
8610                         break;
8611                 default:
8612                         break;
8613                 }
8614         }
8615         bzero(&request, sizeof(request));
8616         bzero(&response, sizeof(response));
8617
8618         smp_report_manuf_info(&ccb->smpio,
8619                               retry_count,
8620                               /*cbfcnp*/ NULL,
8621                               &request,
8622                               sizeof(request),
8623                               (uint8_t *)&response,
8624                               sizeof(response),
8625                               long_response,
8626                               timeout);
8627
8628         if (((retval = cam_send_ccb(device, ccb)) < 0)
8629          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8630                 const char warnstr[] = "error sending command";
8631
8632                 if (retval < 0)
8633                         warn(warnstr);
8634                 else
8635                         warnx(warnstr);
8636
8637                 if (arglist & CAM_ARG_VERBOSE) {
8638                         cam_error_print(device, ccb, CAM_ESF_ALL,
8639                                         CAM_EPF_ALL, stderr);
8640                 }
8641                 retval = 1;
8642                 goto bailout;
8643         }
8644
8645         sb = sbuf_new_auto();
8646         if (sb == NULL) {
8647                 warnx("%s: error allocating sbuf", __func__);
8648                 goto bailout;
8649         }
8650
8651         smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8652
8653         if (sbuf_finish(sb) != 0) {
8654                 warnx("%s: sbuf_finish", __func__);
8655                 goto bailout;
8656         }
8657
8658         printf("%s", sbuf_data(sb));
8659
8660 bailout:
8661
8662         if (ccb != NULL)
8663                 cam_freeccb(ccb);
8664
8665         if (sb != NULL)
8666                 sbuf_delete(sb);
8667
8668         return (retval);
8669 }
8670
8671 static int
8672 getdevid(struct cam_devitem *item)
8673 {
8674         int retval = 0;
8675         union ccb *ccb = NULL;
8676
8677         struct cam_device *dev;
8678
8679         dev = cam_open_btl(item->dev_match.path_id,
8680                            item->dev_match.target_id,
8681                            item->dev_match.target_lun, O_RDWR, NULL);
8682
8683         if (dev == NULL) {
8684                 warnx("%s", cam_errbuf);
8685                 retval = 1;
8686                 goto bailout;
8687         }
8688
8689         item->device_id_len = 0;
8690
8691         ccb = cam_getccb(dev);
8692         if (ccb == NULL) {
8693                 warnx("%s: error allocating CCB", __func__);
8694                 retval = 1;
8695                 goto bailout;
8696         }
8697
8698         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8699
8700         /*
8701          * On the first try, we just probe for the size of the data, and
8702          * then allocate that much memory and try again.
8703          */
8704 retry:
8705         ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8706         ccb->ccb_h.flags = CAM_DIR_IN;
8707         ccb->cdai.flags = CDAI_FLAG_NONE;
8708         ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8709         ccb->cdai.bufsiz = item->device_id_len;
8710         if (item->device_id_len != 0)
8711                 ccb->cdai.buf = (uint8_t *)item->device_id;
8712
8713         if (cam_send_ccb(dev, ccb) < 0) {
8714                 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8715                 retval = 1;
8716                 goto bailout;
8717         }
8718
8719         if (ccb->ccb_h.status != CAM_REQ_CMP) {
8720                 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8721                 retval = 1;
8722                 goto bailout;
8723         }
8724
8725         if (item->device_id_len == 0) {
8726                 /*
8727                  * This is our first time through.  Allocate the buffer,
8728                  * and then go back to get the data.
8729                  */
8730                 if (ccb->cdai.provsiz == 0) {
8731                         warnx("%s: invalid .provsiz field returned with "
8732                              "XPT_GDEV_ADVINFO CCB", __func__);
8733                         retval = 1;
8734                         goto bailout;
8735                 }
8736                 item->device_id_len = ccb->cdai.provsiz;
8737                 item->device_id = malloc(item->device_id_len);
8738                 if (item->device_id == NULL) {
8739                         warn("%s: unable to allocate %d bytes", __func__,
8740                              item->device_id_len);
8741                         retval = 1;
8742                         goto bailout;
8743                 }
8744                 ccb->ccb_h.status = CAM_REQ_INPROG;
8745                 goto retry;
8746         }
8747
8748 bailout:
8749         if (dev != NULL)
8750                 cam_close_device(dev);
8751
8752         if (ccb != NULL)
8753                 cam_freeccb(ccb);
8754
8755         return (retval);
8756 }
8757
8758 /*
8759  * XXX KDM merge this code with getdevtree()?
8760  */
8761 static int
8762 buildbusdevlist(struct cam_devlist *devlist)
8763 {
8764         union ccb ccb;
8765         int bufsize, fd = -1;
8766         struct dev_match_pattern *patterns;
8767         struct cam_devitem *item = NULL;
8768         int skip_device = 0;
8769         int retval = 0;
8770
8771         if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8772                 warn("couldn't open %s", XPT_DEVICE);
8773                 return (1);
8774         }
8775
8776         bzero(&ccb, sizeof(union ccb));
8777
8778         ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8779         ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8780         ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8781
8782         ccb.ccb_h.func_code = XPT_DEV_MATCH;
8783         bufsize = sizeof(struct dev_match_result) * 100;
8784         ccb.cdm.match_buf_len = bufsize;
8785         ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8786         if (ccb.cdm.matches == NULL) {
8787                 warnx("can't malloc memory for matches");
8788                 close(fd);
8789                 return (1);
8790         }
8791         ccb.cdm.num_matches = 0;
8792         ccb.cdm.num_patterns = 2;
8793         ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8794                 ccb.cdm.num_patterns;
8795
8796         patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8797         if (patterns == NULL) {
8798                 warnx("can't malloc memory for patterns");
8799                 retval = 1;
8800                 goto bailout;
8801         }
8802
8803         ccb.cdm.patterns = patterns;
8804         bzero(patterns, ccb.cdm.pattern_buf_len);
8805
8806         patterns[0].type = DEV_MATCH_DEVICE;
8807         patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8808         patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8809         patterns[1].type = DEV_MATCH_PERIPH;
8810         patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8811         patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8812
8813         /*
8814          * We do the ioctl multiple times if necessary, in case there are
8815          * more than 100 nodes in the EDT.
8816          */
8817         do {
8818                 unsigned int i;
8819
8820                 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8821                         warn("error sending CAMIOCOMMAND ioctl");
8822                         retval = 1;
8823                         goto bailout;
8824                 }
8825
8826                 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8827                  || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8828                     && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8829                         warnx("got CAM error %#x, CDM error %d\n",
8830                               ccb.ccb_h.status, ccb.cdm.status);
8831                         retval = 1;
8832                         goto bailout;
8833                 }
8834
8835                 for (i = 0; i < ccb.cdm.num_matches; i++) {
8836                         switch (ccb.cdm.matches[i].type) {
8837                         case DEV_MATCH_DEVICE: {
8838                                 struct device_match_result *dev_result;
8839
8840                                 dev_result =
8841                                      &ccb.cdm.matches[i].result.device_result;
8842
8843                                 if (dev_result->flags &
8844                                     DEV_RESULT_UNCONFIGURED) {
8845                                         skip_device = 1;
8846                                         break;
8847                                 } else
8848                                         skip_device = 0;
8849
8850                                 item = malloc(sizeof(*item));
8851                                 if (item == NULL) {
8852                                         warn("%s: unable to allocate %zd bytes",
8853                                              __func__, sizeof(*item));
8854                                         retval = 1;
8855                                         goto bailout;
8856                                 }
8857                                 bzero(item, sizeof(*item));
8858                                 bcopy(dev_result, &item->dev_match,
8859                                       sizeof(*dev_result));
8860                                 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8861                                                    links);
8862
8863                                 if (getdevid(item) != 0) {
8864                                         retval = 1;
8865                                         goto bailout;
8866                                 }
8867                                 break;
8868                         }
8869                         case DEV_MATCH_PERIPH: {
8870                                 struct periph_match_result *periph_result;
8871
8872                                 periph_result =
8873                                       &ccb.cdm.matches[i].result.periph_result;
8874
8875                                 if (skip_device != 0)
8876                                         break;
8877                                 item->num_periphs++;
8878                                 item->periph_matches = realloc(
8879                                         item->periph_matches,
8880                                         item->num_periphs *
8881                                         sizeof(struct periph_match_result));
8882                                 if (item->periph_matches == NULL) {
8883                                         warn("%s: error allocating periph "
8884                                              "list", __func__);
8885                                         retval = 1;
8886                                         goto bailout;
8887                                 }
8888                                 bcopy(periph_result, &item->periph_matches[
8889                                       item->num_periphs - 1],
8890                                       sizeof(*periph_result));
8891                                 break;
8892                         }
8893                         default:
8894                                 fprintf(stderr, "%s: unexpected match "
8895                                         "type %d\n", __func__,
8896                                         ccb.cdm.matches[i].type);
8897                                 retval = 1;
8898                                 goto bailout;
8899                                 break; /*NOTREACHED*/
8900                         }
8901                 }
8902         } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8903                 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8904 bailout:
8905
8906         if (fd != -1)
8907                 close(fd);
8908
8909         free(patterns);
8910
8911         free(ccb.cdm.matches);
8912
8913         if (retval != 0)
8914                 freebusdevlist(devlist);
8915
8916         return (retval);
8917 }
8918
8919 static void
8920 freebusdevlist(struct cam_devlist *devlist)
8921 {
8922         struct cam_devitem *item, *item2;
8923
8924         STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8925                 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8926                               links);
8927                 free(item->device_id);
8928                 free(item->periph_matches);
8929                 free(item);
8930         }
8931 }
8932
8933 static struct cam_devitem *
8934 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8935 {
8936         struct cam_devitem *item;
8937
8938         STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8939                 struct scsi_vpd_id_descriptor *idd;
8940
8941                 /*
8942                  * XXX KDM look for LUN IDs as well?
8943                  */
8944                 idd = scsi_get_devid(item->device_id,
8945                                            item->device_id_len,
8946                                            scsi_devid_is_sas_target);
8947                 if (idd == NULL)
8948                         continue;
8949
8950                 if (scsi_8btou64(idd->identifier) == sasaddr)
8951                         return (item);
8952         }
8953
8954         return (NULL);
8955 }
8956
8957 static int
8958 smpphylist(struct cam_device *device, int argc, char **argv,
8959            char *combinedopt, int retry_count, int timeout)
8960 {
8961         struct smp_report_general_request *rgrequest = NULL;
8962         struct smp_report_general_response *rgresponse = NULL;
8963         struct smp_discover_request *disrequest = NULL;
8964         struct smp_discover_response *disresponse = NULL;
8965         struct cam_devlist devlist;
8966         union ccb *ccb;
8967         int long_response = 0;
8968         int num_phys = 0;
8969         int quiet = 0;
8970         int retval;
8971         int i, c;
8972
8973         /*
8974          * Note that at the moment we don't support sending SMP CCBs to
8975          * devices that aren't probed by CAM.
8976          */
8977         ccb = cam_getccb(device);
8978         if (ccb == NULL) {
8979                 warnx("%s: error allocating CCB", __func__);
8980                 return (1);
8981         }
8982
8983         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8984         STAILQ_INIT(&devlist.dev_queue);
8985
8986         rgrequest = malloc(sizeof(*rgrequest));
8987         if (rgrequest == NULL) {
8988                 warn("%s: unable to allocate %zd bytes", __func__,
8989                      sizeof(*rgrequest));
8990                 retval = 1;
8991                 goto bailout;
8992         }
8993
8994         rgresponse = malloc(sizeof(*rgresponse));
8995         if (rgresponse == NULL) {
8996                 warn("%s: unable to allocate %zd bytes", __func__,
8997                      sizeof(*rgresponse));
8998                 retval = 1;
8999                 goto bailout;
9000         }
9001
9002         while ((c = getopt(argc, argv, combinedopt)) != -1) {
9003                 switch (c) {
9004                 case 'l':
9005                         long_response = 1;
9006                         break;
9007                 case 'q':
9008                         quiet = 1;
9009                         break;
9010                 default:
9011                         break;
9012                 }
9013         }
9014
9015         smp_report_general(&ccb->smpio,
9016                            retry_count,
9017                            /*cbfcnp*/ NULL,
9018                            rgrequest,
9019                            /*request_len*/ sizeof(*rgrequest),
9020                            (uint8_t *)rgresponse,
9021                            /*response_len*/ sizeof(*rgresponse),
9022                            /*long_response*/ long_response,
9023                            timeout);
9024
9025         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9026
9027         if (((retval = cam_send_ccb(device, ccb)) < 0)
9028          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
9029                 const char warnstr[] = "error sending command";
9030
9031                 if (retval < 0)
9032                         warn(warnstr);
9033                 else
9034                         warnx(warnstr);
9035
9036                 if (arglist & CAM_ARG_VERBOSE) {
9037                         cam_error_print(device, ccb, CAM_ESF_ALL,
9038                                         CAM_EPF_ALL, stderr);
9039                 }
9040                 retval = 1;
9041                 goto bailout;
9042         }
9043
9044         num_phys = rgresponse->num_phys;
9045
9046         if (num_phys == 0) {
9047                 if (quiet == 0)
9048                         fprintf(stdout, "%s: No Phys reported\n", __func__);
9049                 retval = 1;
9050                 goto bailout;
9051         }
9052
9053         devlist.path_id = device->path_id;
9054
9055         retval = buildbusdevlist(&devlist);
9056         if (retval != 0)
9057                 goto bailout;
9058
9059         if (quiet == 0) {
9060                 fprintf(stdout, "%d PHYs:\n", num_phys);
9061                 fprintf(stdout, "PHY  Attached SAS Address\n");
9062         }
9063
9064         disrequest = malloc(sizeof(*disrequest));
9065         if (disrequest == NULL) {
9066                 warn("%s: unable to allocate %zd bytes", __func__,
9067                      sizeof(*disrequest));
9068                 retval = 1;
9069                 goto bailout;
9070         }
9071
9072         disresponse = malloc(sizeof(*disresponse));
9073         if (disresponse == NULL) {
9074                 warn("%s: unable to allocate %zd bytes", __func__,
9075                      sizeof(*disresponse));
9076                 retval = 1;
9077                 goto bailout;
9078         }
9079
9080         for (i = 0; i < num_phys; i++) {
9081                 struct cam_devitem *item;
9082                 struct device_match_result *dev_match;
9083                 char vendor[16], product[48], revision[16];
9084                 char tmpstr[256];
9085                 int j;
9086
9087                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9088
9089                 ccb->ccb_h.status = CAM_REQ_INPROG;
9090                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9091
9092                 smp_discover(&ccb->smpio,
9093                              retry_count,
9094                              /*cbfcnp*/ NULL,
9095                              disrequest,
9096                              sizeof(*disrequest),
9097                              (uint8_t *)disresponse,
9098                              sizeof(*disresponse),
9099                              long_response,
9100                              /*ignore_zone_group*/ 0,
9101                              /*phy*/ i,
9102                              timeout);
9103
9104                 if (((retval = cam_send_ccb(device, ccb)) < 0)
9105                  || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9106                   && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9107                         const char warnstr[] = "error sending command";
9108
9109                         if (retval < 0)
9110                                 warn(warnstr);
9111                         else
9112                                 warnx(warnstr);
9113
9114                         if (arglist & CAM_ARG_VERBOSE) {
9115                                 cam_error_print(device, ccb, CAM_ESF_ALL,
9116                                                 CAM_EPF_ALL, stderr);
9117                         }
9118                         retval = 1;
9119                         goto bailout;
9120                 }
9121
9122                 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9123                         if (quiet == 0)
9124                                 fprintf(stdout, "%3d  <vacant>\n", i);
9125                         continue;
9126                 }
9127
9128                 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9129                         item = NULL;
9130                 } else {
9131                         item = findsasdevice(&devlist,
9132                             scsi_8btou64(disresponse->attached_sas_address));
9133                 }
9134
9135                 if ((quiet == 0)
9136                  || (item != NULL)) {
9137                         fprintf(stdout, "%3d  0x%016jx", i,
9138                                 (uintmax_t)scsi_8btou64(
9139                                 disresponse->attached_sas_address));
9140                         if (item == NULL) {
9141                                 fprintf(stdout, "\n");
9142                                 continue;
9143                         }
9144                 } else if (quiet != 0)
9145                         continue;
9146
9147                 dev_match = &item->dev_match;
9148
9149                 if (dev_match->protocol == PROTO_SCSI) {
9150                         cam_strvis(vendor, dev_match->inq_data.vendor,
9151                                    sizeof(dev_match->inq_data.vendor),
9152                                    sizeof(vendor));
9153                         cam_strvis(product, dev_match->inq_data.product,
9154                                    sizeof(dev_match->inq_data.product),
9155                                    sizeof(product));
9156                         cam_strvis(revision, dev_match->inq_data.revision,
9157                                    sizeof(dev_match->inq_data.revision),
9158                                    sizeof(revision));
9159                         sprintf(tmpstr, "<%s %s %s>", vendor, product,
9160                                 revision);
9161                 } else if ((dev_match->protocol == PROTO_ATA)
9162                         || (dev_match->protocol == PROTO_SATAPM)) {
9163                         cam_strvis(product, dev_match->ident_data.model,
9164                                    sizeof(dev_match->ident_data.model),
9165                                    sizeof(product));
9166                         cam_strvis(revision, dev_match->ident_data.revision,
9167                                    sizeof(dev_match->ident_data.revision),
9168                                    sizeof(revision));
9169                         sprintf(tmpstr, "<%s %s>", product, revision);
9170                 } else {
9171                         sprintf(tmpstr, "<>");
9172                 }
9173                 fprintf(stdout, "   %-33s ", tmpstr);
9174
9175                 /*
9176                  * If we have 0 periphs, that's a bug...
9177                  */
9178                 if (item->num_periphs == 0) {
9179                         fprintf(stdout, "\n");
9180                         continue;
9181                 }
9182
9183                 fprintf(stdout, "(");
9184                 for (j = 0; j < item->num_periphs; j++) {
9185                         if (j > 0)
9186                                 fprintf(stdout, ",");
9187
9188                         fprintf(stdout, "%s%d",
9189                                 item->periph_matches[j].periph_name,
9190                                 item->periph_matches[j].unit_number);
9191
9192                 }
9193                 fprintf(stdout, ")\n");
9194         }
9195 bailout:
9196         if (ccb != NULL)
9197                 cam_freeccb(ccb);
9198
9199         free(rgrequest);
9200
9201         free(rgresponse);
9202
9203         free(disrequest);
9204
9205         free(disresponse);
9206
9207         freebusdevlist(&devlist);
9208
9209         return (retval);
9210 }
9211
9212 static int
9213 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9214 {
9215         uint8_t error = 0, ata_device = 0, status = 0;
9216         uint16_t count = 0;
9217         uint64_t lba = 0;
9218         int retval;
9219
9220         retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9221             &status);
9222         if (retval == 1) {
9223                 if (arglist & CAM_ARG_VERBOSE) {
9224                         cam_error_print(device, ccb, CAM_ESF_ALL,
9225                                         CAM_EPF_ALL, stderr);
9226                 }
9227                 warnx("Can't get ATA command status");
9228                 return (retval);
9229         }
9230
9231         if (status & ATA_STATUS_ERROR) {
9232                 cam_error_print(device, ccb, CAM_ESF_ALL,
9233                     CAM_EPF_ALL, stderr);
9234                 return (1);
9235         }
9236
9237         printf("%s%d: ", device->device_name, device->dev_unit_num);
9238         switch (count) {
9239         case 0x00:
9240                 printf("Standby mode\n");
9241                 break;
9242         case 0x01:
9243                 printf("Standby_y mode\n");
9244                 break;
9245         case 0x40:
9246                 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9247                 break;
9248         case 0x41:
9249                 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9250                 break;
9251         case 0x80:
9252                 printf("Idle mode\n");
9253                 break;
9254         case 0x81:
9255                 printf("Idle_a mode\n");
9256                 break;
9257         case 0x82:
9258                 printf("Idle_b mode\n");
9259                 break;
9260         case 0x83:
9261                 printf("Idle_c mode\n");
9262                 break;
9263         case 0xff:
9264                 printf("Active or Idle mode\n");
9265                 break;
9266         default:
9267                 printf("Unknown mode 0x%02x\n", count);
9268                 break;
9269         }
9270
9271         return (0);
9272 }
9273
9274 static int
9275 atapm(struct cam_device *device, int argc, char **argv,
9276                  char *combinedopt, int retry_count, int timeout)
9277 {
9278         union ccb *ccb;
9279         int retval = 0;
9280         int t = -1;
9281         int c;
9282         u_int8_t ata_flags = 0;
9283         u_char cmd, sc;
9284
9285         ccb = cam_getccb(device);
9286
9287         if (ccb == NULL) {
9288                 warnx("%s: error allocating ccb", __func__);
9289                 return (1);
9290         }
9291
9292         while ((c = getopt(argc, argv, combinedopt)) != -1) {
9293                 switch (c) {
9294                 case 't':
9295                         t = atoi(optarg);
9296                         break;
9297                 default:
9298                         break;
9299                 }
9300         }
9301         if (strcmp(argv[1], "idle") == 0) {
9302                 if (t == -1)
9303                         cmd = ATA_IDLE_IMMEDIATE;
9304                 else
9305                         cmd = ATA_IDLE_CMD;
9306         } else if (strcmp(argv[1], "standby") == 0) {
9307                 if (t == -1)
9308                         cmd = ATA_STANDBY_IMMEDIATE;
9309                 else
9310                         cmd = ATA_STANDBY_CMD;
9311         } else if (strcmp(argv[1], "powermode") == 0) {
9312                 cmd = ATA_CHECK_POWER_MODE;
9313                 ata_flags = AP_FLAG_CHK_COND;
9314                 t = -1;
9315         } else {
9316                 cmd = ATA_SLEEP;
9317                 t = -1;
9318         }
9319
9320         if (t < 0)
9321                 sc = 0;
9322         else if (t <= (240 * 5))
9323                 sc = (t + 4) / 5;
9324         else if (t <= (252 * 5))
9325                 /* special encoding for 21 minutes */
9326                 sc = 252;
9327         else if (t <= (11 * 30 * 60))
9328                 sc = (t - 1) / (30 * 60) + 241;
9329         else
9330                 sc = 253;
9331
9332         retval = ata_do_cmd(device,
9333             ccb,
9334             /*retries*/retry_count,
9335             /*flags*/CAM_DIR_NONE,
9336             /*protocol*/AP_PROTO_NON_DATA,
9337             /*ata_flags*/ata_flags,
9338             /*tag_action*/MSG_SIMPLE_Q_TAG,
9339             /*command*/cmd,
9340             /*features*/0,
9341             /*lba*/0,
9342             /*sector_count*/sc,
9343             /*data_ptr*/NULL,
9344             /*dxfer_len*/0,
9345             /*timeout*/timeout ? timeout : 30 * 1000,
9346             /*force48bit*/0);
9347
9348         cam_freeccb(ccb);
9349
9350         if (retval || cmd != ATA_CHECK_POWER_MODE)
9351                 return (retval);
9352
9353         return (atapm_proc_resp(device, ccb));
9354 }
9355
9356 static int
9357 ataaxm(struct cam_device *device, int argc, char **argv,
9358                  char *combinedopt, int retry_count, int timeout)
9359 {
9360         union ccb *ccb;
9361         int retval = 0;
9362         int l = -1;
9363         int c;
9364         u_char cmd, sc;
9365
9366         ccb = cam_getccb(device);
9367
9368         if (ccb == NULL) {
9369                 warnx("%s: error allocating ccb", __func__);
9370                 return (1);
9371         }
9372
9373         while ((c = getopt(argc, argv, combinedopt)) != -1) {
9374                 switch (c) {
9375                 case 'l':
9376                         l = atoi(optarg);
9377                         break;
9378                 default:
9379                         break;
9380                 }
9381         }
9382         sc = 0;
9383         if (strcmp(argv[1], "apm") == 0) {
9384                 if (l == -1)
9385                         cmd = 0x85;
9386                 else {
9387                         cmd = 0x05;
9388                         sc = l;
9389                 }
9390         } else /* aam */ {
9391                 if (l == -1)
9392                         cmd = 0xC2;
9393                 else {
9394                         cmd = 0x42;
9395                         sc = l;
9396                 }
9397         }
9398
9399         retval = ata_do_cmd(device,
9400             ccb,
9401             /*retries*/retry_count,
9402             /*flags*/CAM_DIR_NONE,
9403             /*protocol*/AP_PROTO_NON_DATA,
9404             /*ata_flags*/0,
9405             /*tag_action*/MSG_SIMPLE_Q_TAG,
9406             /*command*/ATA_SETFEATURES,
9407             /*features*/cmd,
9408             /*lba*/0,
9409             /*sector_count*/sc,
9410             /*data_ptr*/NULL,
9411             /*dxfer_len*/0,
9412             /*timeout*/timeout ? timeout : 30 * 1000,
9413             /*force48bit*/0);
9414
9415         cam_freeccb(ccb);
9416         return (retval);
9417 }
9418
9419 int
9420 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9421                int show_sa_errors, int sa_set, int service_action,
9422                int timeout_desc, int task_attr, int retry_count, int timeout,
9423                int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9424 {
9425         union ccb *ccb = NULL;
9426         uint8_t *buf = NULL;
9427         uint32_t alloc_len = 0, num_opcodes;
9428         uint32_t valid_len = 0;
9429         uint32_t avail_len = 0;
9430         struct scsi_report_supported_opcodes_all *all_hdr;
9431         struct scsi_report_supported_opcodes_one *one;
9432         int options = 0;
9433         int retval = 0;
9434
9435         /*
9436          * Make it clear that we haven't yet allocated or filled anything.
9437          */
9438         *fill_len = 0;
9439         *data_ptr = NULL;
9440
9441         ccb = cam_getccb(device);
9442         if (ccb == NULL) {
9443                 warnx("couldn't allocate CCB");
9444                 retval = 1;
9445                 goto bailout;
9446         }
9447
9448         /* cam_getccb cleans up the header, caller has to zero the payload */
9449         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9450
9451         if (opcode_set != 0) {
9452                 options |= RSO_OPTIONS_OC;
9453                 num_opcodes = 1;
9454                 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9455         } else {
9456                 num_opcodes = 256;
9457                 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9458                     sizeof(struct scsi_report_supported_opcodes_descr));
9459         }
9460
9461         if (timeout_desc != 0) {
9462                 options |= RSO_RCTD;
9463                 alloc_len += num_opcodes *
9464                     sizeof(struct scsi_report_supported_opcodes_timeout);
9465         }
9466
9467         if (sa_set != 0) {
9468                 options |= RSO_OPTIONS_OC_SA;
9469                 if (show_sa_errors != 0)
9470                         options &= ~RSO_OPTIONS_OC;
9471         }
9472
9473 retry_alloc:
9474         if (buf != NULL) {
9475                 free(buf);
9476                 buf = NULL;
9477         }
9478
9479         buf = malloc(alloc_len);
9480         if (buf == NULL) {
9481                 warn("Unable to allocate %u bytes", alloc_len);
9482                 retval = 1;
9483                 goto bailout;
9484         }
9485         bzero(buf, alloc_len);
9486
9487         scsi_report_supported_opcodes(&ccb->csio,
9488                                       /*retries*/ retry_count,
9489                                       /*cbfcnp*/ NULL,
9490                                       /*tag_action*/ task_attr,
9491                                       /*options*/ options,
9492                                       /*req_opcode*/ opcode,
9493                                       /*req_service_action*/ service_action,
9494                                       /*data_ptr*/ buf,
9495                                       /*dxfer_len*/ alloc_len,
9496                                       /*sense_len*/ SSD_FULL_SIZE,
9497                                       /*timeout*/ timeout ? timeout : 10000);
9498
9499         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9500
9501         if (retry_count != 0)
9502                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9503
9504         if (cam_send_ccb(device, ccb) < 0) {
9505                 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9506                 retval = 1;
9507                 goto bailout;
9508         }
9509
9510         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9511                 if (verbosemode != 0)
9512                         cam_error_print(device, ccb, CAM_ESF_ALL,
9513                                         CAM_EPF_ALL, stderr);
9514                 retval = 1;
9515                 goto bailout;
9516         }
9517
9518         valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9519
9520         if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9521          && (valid_len >= sizeof(*all_hdr))) {
9522                 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9523                 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9524         } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9525                 && (valid_len >= sizeof(*one))) {
9526                 uint32_t cdb_length;
9527
9528                 one = (struct scsi_report_supported_opcodes_one *)buf;
9529                 cdb_length = scsi_2btoul(one->cdb_length);
9530                 avail_len = sizeof(*one) + cdb_length;
9531                 if (one->support & RSO_ONE_CTDP) {
9532                         struct scsi_report_supported_opcodes_timeout *td;
9533
9534                         td = (struct scsi_report_supported_opcodes_timeout *)
9535                             &buf[avail_len];
9536                         if (valid_len >= (avail_len + sizeof(td->length))) {
9537                                 avail_len += scsi_2btoul(td->length) +
9538                                     sizeof(td->length);
9539                         } else {
9540                                 avail_len += sizeof(*td);
9541                         }
9542                 }
9543         }
9544
9545         /*
9546          * avail_len could be zero if we didn't get enough data back from
9547          * thet target to determine
9548          */
9549         if ((avail_len != 0)
9550          && (avail_len > valid_len)) {
9551                 alloc_len = avail_len;
9552                 goto retry_alloc;
9553         }
9554
9555         *fill_len = valid_len;
9556         *data_ptr = buf;
9557 bailout:
9558         if (retval != 0)
9559                 free(buf);
9560
9561         cam_freeccb(ccb);
9562
9563         return (retval);
9564 }
9565
9566 static int
9567 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9568                    int req_sa, uint8_t *buf, uint32_t valid_len)
9569 {
9570         struct scsi_report_supported_opcodes_one *one;
9571         struct scsi_report_supported_opcodes_timeout *td;
9572         uint32_t cdb_len = 0, td_len = 0;
9573         const char *op_desc = NULL;
9574         unsigned int i;
9575         int retval = 0;
9576
9577         one = (struct scsi_report_supported_opcodes_one *)buf;
9578
9579         /*
9580          * If we don't have the full single opcode descriptor, no point in
9581          * continuing.
9582          */
9583         if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9584             cdb_length)) {
9585                 warnx("Only %u bytes returned, not enough to verify support",
9586                       valid_len);
9587                 retval = 1;
9588                 goto bailout;
9589         }
9590
9591         op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9592
9593         printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9594                req_opcode);
9595         if (sa_set != 0)
9596                 printf(", SA 0x%x", req_sa);
9597         printf(": ");
9598
9599         switch (one->support & RSO_ONE_SUP_MASK) {
9600         case RSO_ONE_SUP_UNAVAIL:
9601                 printf("No command support information currently available\n");
9602                 break;
9603         case RSO_ONE_SUP_NOT_SUP:
9604                 printf("Command not supported\n");
9605                 retval = 1;
9606                 goto bailout;
9607                 break; /*NOTREACHED*/
9608         case RSO_ONE_SUP_AVAIL:
9609                 printf("Command is supported, complies with a SCSI standard\n");
9610                 break;
9611         case RSO_ONE_SUP_VENDOR:
9612                 printf("Command is supported, vendor-specific "
9613                        "implementation\n");
9614                 break;
9615         default:
9616                 printf("Unknown command support flags 0x%#x\n",
9617                        one->support & RSO_ONE_SUP_MASK);
9618                 break;
9619         }
9620
9621         /*
9622          * If we don't have the CDB length, it isn't exactly an error, the
9623          * command probably isn't supported.
9624          */
9625         if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9626             cdb_usage))
9627                 goto bailout;
9628
9629         cdb_len = scsi_2btoul(one->cdb_length);
9630
9631         /*
9632          * If our valid data doesn't include the full reported length,
9633          * return.  The caller should have detected this and adjusted his
9634          * allocation length to get all of the available data.
9635          */
9636         if (valid_len < sizeof(*one) + cdb_len) {
9637                 retval = 1;
9638                 goto bailout;
9639         }
9640
9641         /*
9642          * If all we have is the opcode, there is no point in printing out
9643          * the usage bitmap.
9644          */
9645         if (cdb_len <= 1) {
9646                 retval = 1;
9647                 goto bailout;
9648         }
9649
9650         printf("CDB usage bitmap:");
9651         for (i = 0; i < cdb_len; i++) {
9652                 printf(" %02x", one->cdb_usage[i]);
9653         }
9654         printf("\n");
9655
9656         /*
9657          * If we don't have a timeout descriptor, we're done.
9658          */
9659         if ((one->support & RSO_ONE_CTDP) == 0)
9660                 goto bailout;
9661
9662         /*
9663          * If we don't have enough valid length to include the timeout
9664          * descriptor length, we're done.
9665          */
9666         if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9667                 goto bailout;
9668
9669         td = (struct scsi_report_supported_opcodes_timeout *)
9670             &buf[sizeof(*one) + cdb_len];
9671         td_len = scsi_2btoul(td->length);
9672         td_len += sizeof(td->length);
9673
9674         /*
9675          * If we don't have the full timeout descriptor, we're done.
9676          */
9677         if (td_len < sizeof(*td))
9678                 goto bailout;
9679
9680         /*
9681          * If we don't have enough valid length to contain the full timeout
9682          * descriptor, we're done.
9683          */
9684         if (valid_len < (sizeof(*one) + cdb_len + td_len))
9685                 goto bailout;
9686
9687         printf("Timeout information:\n");
9688         printf("Command-specific:    0x%02x\n", td->cmd_specific);
9689         printf("Nominal timeout:     %u seconds\n",
9690                scsi_4btoul(td->nominal_time));
9691         printf("Recommended timeout: %u seconds\n",
9692                scsi_4btoul(td->recommended_time));
9693
9694 bailout:
9695         return (retval);
9696 }
9697
9698 static int
9699 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9700                  uint32_t valid_len)
9701 {
9702         struct scsi_report_supported_opcodes_all *hdr;
9703         struct scsi_report_supported_opcodes_descr *desc;
9704         uint32_t avail_len = 0, used_len = 0;
9705         uint8_t *cur_ptr;
9706         int retval = 0;
9707
9708         if (valid_len < sizeof(*hdr)) {
9709                 warnx("%s: not enough returned data (%u bytes) opcode list",
9710                       __func__, valid_len);
9711                 retval = 1;
9712                 goto bailout;
9713         }
9714         hdr = (struct scsi_report_supported_opcodes_all *)buf;
9715         avail_len = scsi_4btoul(hdr->length);
9716         avail_len += sizeof(hdr->length);
9717         /*
9718          * Take the lesser of the amount of data the drive claims is
9719          * available, and the amount of data the HBA says was returned.
9720          */
9721         avail_len = MIN(avail_len, valid_len);
9722
9723         used_len = sizeof(hdr->length);
9724
9725         printf("%-6s %4s %8s ",
9726                "Opcode", "SA", "CDB len" );
9727
9728         if (td_req != 0)
9729                 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9730         printf(" Description\n");
9731
9732         while ((avail_len - used_len) > sizeof(*desc)) {
9733                 struct scsi_report_supported_opcodes_timeout *td;
9734                 uint32_t td_len;
9735                 const char *op_desc = NULL;
9736
9737                 cur_ptr = &buf[used_len];
9738                 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9739
9740                 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9741                 if (op_desc == NULL)
9742                         op_desc = "UNKNOWN";
9743
9744                 printf("0x%02x   %#4x %8u ", desc->opcode,
9745                        scsi_2btoul(desc->service_action),
9746                        scsi_2btoul(desc->cdb_length));
9747
9748                 used_len += sizeof(*desc);
9749
9750                 if ((desc->flags & RSO_CTDP) == 0) {
9751                         printf(" %s\n", op_desc);
9752                         continue;
9753                 }
9754
9755                 /*
9756                  * If we don't have enough space to fit a timeout
9757                  * descriptor, then we're done.
9758                  */
9759                 if (avail_len - used_len < sizeof(*td)) {
9760                         used_len = avail_len;
9761                         printf(" %s\n", op_desc);
9762                         continue;
9763                 }
9764                 cur_ptr = &buf[used_len];
9765                 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9766                 td_len = scsi_2btoul(td->length);
9767                 td_len += sizeof(td->length);
9768
9769                 used_len += td_len;
9770                 /*
9771                  * If the given timeout descriptor length is less than what
9772                  * we understand, skip it.
9773                  */
9774                 if (td_len < sizeof(*td)) {
9775                         printf(" %s\n", op_desc);
9776                         continue;
9777                 }
9778
9779                 printf(" 0x%02x %6u %6u  %s\n", td->cmd_specific,
9780                        scsi_4btoul(td->nominal_time),
9781                        scsi_4btoul(td->recommended_time), op_desc);
9782         }
9783 bailout:
9784         return (retval);
9785 }
9786
9787 static int
9788 scsiopcodes(struct cam_device *device, int argc, char **argv,
9789             char *combinedopt, int task_attr, int retry_count, int timeout,
9790             int verbosemode)
9791 {
9792         int c;
9793         uint32_t opcode = 0, service_action = 0;
9794         int td_set = 0, opcode_set = 0, sa_set = 0;
9795         int show_sa_errors = 1;
9796         uint32_t valid_len = 0;
9797         uint8_t *buf = NULL;
9798         char *endptr;
9799         int retval = 0;
9800
9801         while ((c = getopt(argc, argv, combinedopt)) != -1) {
9802                 switch (c) {
9803                 case 'N':
9804                         show_sa_errors = 0;
9805                         break;
9806                 case 'o':
9807                         opcode = strtoul(optarg, &endptr, 0);
9808                         if (*endptr != '\0') {
9809                                 warnx("Invalid opcode \"%s\", must be a number",
9810                                       optarg);
9811                                 retval = 1;
9812                                 goto bailout;
9813                         }
9814                         if (opcode > 0xff) {
9815                                 warnx("Invalid opcode 0x%#x, must be between"
9816                                       "0 and 0xff inclusive", opcode);
9817                                 retval = 1;
9818                                 goto bailout;
9819                         }
9820                         opcode_set = 1;
9821                         break;
9822                 case 's':
9823                         service_action = strtoul(optarg, &endptr, 0);
9824                         if (*endptr != '\0') {
9825                                 warnx("Invalid service action \"%s\", must "
9826                                       "be a number", optarg);
9827                                 retval = 1;
9828                                 goto bailout;
9829                         }
9830                         if (service_action > 0xffff) {
9831                                 warnx("Invalid service action 0x%#x, must "
9832                                       "be between 0 and 0xffff inclusive",
9833                                       service_action);
9834                                 retval = 1;
9835                         }
9836                         sa_set = 1;
9837                         break;
9838                 case 'T':
9839                         td_set = 1;
9840                         break;
9841                 default:
9842                         break;
9843                 }
9844         }
9845
9846         if ((sa_set != 0)
9847          && (opcode_set == 0)) {
9848                 warnx("You must specify an opcode with -o if a service "
9849                       "action is given");
9850                 retval = 1;
9851                 goto bailout;
9852         }
9853         retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9854                                 sa_set, service_action, td_set, task_attr,
9855                                 retry_count, timeout, verbosemode, &valid_len,
9856                                 &buf);
9857         if (retval != 0)
9858                 goto bailout;
9859
9860         if ((opcode_set != 0)
9861          || (sa_set != 0)) {
9862                 retval = scsiprintoneopcode(device, opcode, sa_set,
9863                                             service_action, buf, valid_len);
9864         } else {
9865                 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9866         }
9867
9868 bailout:
9869         free(buf);
9870
9871         return (retval);
9872 }
9873
9874
9875 static int
9876 reprobe(struct cam_device *device)
9877 {
9878         union ccb *ccb;
9879         int retval = 0;
9880
9881         ccb = cam_getccb(device);
9882
9883         if (ccb == NULL) {
9884                 warnx("%s: error allocating ccb", __func__);
9885                 return (1);
9886         }
9887
9888         CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9889
9890         ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9891
9892         if (cam_send_ccb(device, ccb) < 0) {
9893                 warn("error sending XPT_REPROBE_LUN CCB");
9894                 retval = 1;
9895                 goto bailout;
9896         }
9897
9898         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9899                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9900                 retval = 1;
9901                 goto bailout;
9902         }
9903
9904 bailout:
9905         cam_freeccb(ccb);
9906
9907         return (retval);
9908 }
9909
9910 void
9911 usage(int printlong)
9912 {
9913
9914         fprintf(printlong ? stdout : stderr,
9915 "usage:  camcontrol <command>  [device id][generic args][command args]\n"
9916 "        camcontrol devlist    [-b] [-v]\n"
9917 "        camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9918 "        camcontrol tur        [dev_id][generic args]\n"
9919 "        camcontrol inquiry    [dev_id][generic args] [-D] [-S] [-R]\n"
9920 "        camcontrol identify   [dev_id][generic args] [-v]\n"
9921 "        camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9922 "        camcontrol readcap    [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9923 "                              [-q] [-s] [-l]\n"
9924 "        camcontrol start      [dev_id][generic args]\n"
9925 "        camcontrol stop       [dev_id][generic args]\n"
9926 "        camcontrol load       [dev_id][generic args]\n"
9927 "        camcontrol eject      [dev_id][generic args]\n"
9928 "        camcontrol reprobe    [dev_id][generic args]\n"
9929 "        camcontrol rescan     <all | bus[:target:lun] | dev_id>\n"
9930 "        camcontrol reset      <all | bus[:target:lun] | dev_id>\n"
9931 "        camcontrol defects    [dev_id][generic args] <-f format> [-P][-G]\n"
9932 "                              [-q][-s][-S offset][-X]\n"
9933 "        camcontrol modepage   [dev_id][generic args] <-m page | -l>\n"
9934 "                              [-P pagectl][-e | -b][-d]\n"
9935 "        camcontrol cmd        [dev_id][generic args]\n"
9936 "                              <-a cmd [args] | -c cmd [args]>\n"
9937 "                              [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9938 "        camcontrol smpcmd     [dev_id][generic args]\n"
9939 "                              <-r len fmt [args]> <-R len fmt [args]>\n"
9940 "        camcontrol smprg      [dev_id][generic args][-l]\n"
9941 "        camcontrol smppc      [dev_id][generic args] <-p phy> [-l]\n"
9942 "                              [-o operation][-d name][-m rate][-M rate]\n"
9943 "                              [-T pp_timeout][-a enable|disable]\n"
9944 "                              [-A enable|disable][-s enable|disable]\n"
9945 "                              [-S enable|disable]\n"
9946 "        camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9947 "        camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9948 "        camcontrol debug      [-I][-P][-T][-S][-X][-c]\n"
9949 "                              <all|dev_id|bus[:target[:lun]]|off>\n"
9950 "        camcontrol tags       [dev_id][generic args] [-N tags] [-q] [-v]\n"
9951 "        camcontrol negotiate  [dev_id][generic args] [-a][-c]\n"
9952 "                              [-D <enable|disable>][-M mode][-O offset]\n"
9953 "                              [-q][-R syncrate][-v][-T <enable|disable>]\n"
9954 "                              [-U][-W bus_width]\n"
9955 "        camcontrol format     [dev_id][generic args][-q][-r][-w][-y]\n"
9956 "        camcontrol sanitize   [dev_id][generic args]\n"
9957 "                              [-a overwrite|block|crypto|exitfailure]\n"
9958 "                              [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9959 "                              [-y]\n"
9960 "        camcontrol idle       [dev_id][generic args][-t time]\n"
9961 "        camcontrol standby    [dev_id][generic args][-t time]\n"
9962 "        camcontrol sleep      [dev_id][generic args]\n"
9963 "        camcontrol powermode  [dev_id][generic args]\n"
9964 "        camcontrol apm        [dev_id][generic args][-l level]\n"
9965 "        camcontrol aam        [dev_id][generic args][-l level]\n"
9966 "        camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9967 "                              [-s][-y]\n"
9968 "        camcontrol security   [dev_id][generic args]\n"
9969 "                              <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9970 "                              [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9971 "                              [-U <user|master>] [-y]\n"
9972 "        camcontrol hpa        [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9973 "                              [-q] [-s max_sectors] [-U pwd] [-y]\n"
9974 "        camcontrol ama        [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9975 "        camcontrol persist    [dev_id][generic args] <-i action|-o action>\n"
9976 "                              [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9977 "                              [-s scope][-S][-T type][-U]\n"
9978 "        camcontrol attrib     [dev_id][generic args] <-r action|-w attr>\n"
9979 "                              [-a attr_num][-c][-e elem][-F form1,form1]\n"
9980 "                              [-p part][-s start][-T type][-V vol]\n"
9981 "        camcontrol opcodes    [dev_id][generic args][-o opcode][-s SA]\n"
9982 "                              [-N][-T]\n"
9983 "        camcontrol zone       [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9984 "                              [-o rep_opts] [-P print_opts]\n"
9985 "        camcontrol epc        [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9986 "                              [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9987 "                              [-S power_src] [-T timer]\n"
9988 "        camcontrol timestamp  [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9989 "                              <-s <-f format -T time | -U >>\n"
9990 "        camcontrol devtype    [dev_id]\n"
9991 "        camcontrol mmcsdcmd   [dev_id] [[-c mmc_opcode] [-a mmc_arg]\n"
9992 "                                  [-f mmc_flags] [-l data_len]\n"
9993 "                                  [-W [-b data_byte]]] |\n"
9994 "                              [-F frequency] |\n"
9995 "                              [-I]\n"
9996 "                              [-1 | -4]\n"
9997 "                              [-S high|normal]\n"
9998 "                              \n"
9999 "        camcontrol help\n");
10000         if (!printlong)
10001                 return;
10002         fprintf(stdout,
10003 "Specify one of the following options:\n"
10004 "devlist     list all CAM devices\n"
10005 "periphlist  list all CAM peripheral drivers attached to a device\n"
10006 "tur         send a test unit ready to the named device\n"
10007 "inquiry     send a SCSI inquiry command to the named device\n"
10008 "identify    send a ATA identify command to the named device\n"
10009 "reportluns  send a SCSI report luns command to the device\n"
10010 "readcap     send a SCSI read capacity command to the device\n"
10011 "start       send a Start Unit command to the device\n"
10012 "stop        send a Stop Unit command to the device\n"
10013 "load        send a Start Unit command to the device with the load bit set\n"
10014 "eject       send a Stop Unit command to the device with the eject bit set\n"
10015 "reprobe     update capacity information of the given device\n"
10016 "rescan      rescan all buses, the given bus, bus:target:lun or device\n"
10017 "reset       reset all buses, the given bus, bus:target:lun or device\n"
10018 "defects     read the defect list of the specified device\n"
10019 "modepage    display or edit (-e) the given mode page\n"
10020 "cmd         send the given SCSI command, may need -i or -o as well\n"
10021 "smpcmd      send the given SMP command, requires -o and -i\n"
10022 "smprg       send the SMP Report General command\n"
10023 "smppc       send the SMP PHY Control command, requires -p\n"
10024 "smpphylist  display phys attached to a SAS expander\n"
10025 "smpmaninfo  send the SMP Report Manufacturer Info command\n"
10026 "debug       turn debugging on/off for a bus, target, or lun, or all devices\n"
10027 "tags        report or set the number of transaction slots for a device\n"
10028 "negotiate   report or set device negotiation parameters\n"
10029 "format      send the SCSI FORMAT UNIT command to the named device\n"
10030 "sanitize    send the SCSI SANITIZE command to the named device\n"
10031 "idle        send the ATA IDLE command to the named device\n"
10032 "standby     send the ATA STANDBY command to the named device\n"
10033 "sleep       send the ATA SLEEP command to the named device\n"
10034 "powermode   send the ATA CHECK POWER MODE command to the named device\n"
10035 "fwdownload  program firmware of the named device with the given image\n"
10036 "security    report or send ATA security commands to the named device\n"
10037 "persist     send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
10038 "attrib      send the SCSI READ or WRITE ATTRIBUTE commands\n"
10039 "opcodes     send the SCSI REPORT SUPPORTED OPCODES command\n"
10040 "zone        manage Zoned Block (Shingled) devices\n"
10041 "epc         send ATA Extended Power Conditions commands\n"
10042 "timestamp   report or set the device's timestamp\n"
10043 "devtype     report the type of device\n"
10044 "mmcsdcmd    send the given MMC command, needs -c and -a as well\n"
10045 "help        this message\n"
10046 "Device Identifiers:\n"
10047 "bus:target        specify the bus and target, lun defaults to 0\n"
10048 "bus:target:lun    specify the bus, target and lun\n"
10049 "deviceUNIT        specify the device name, like \"da4\" or \"cd2\"\n"
10050 "Generic arguments:\n"
10051 "-v                be verbose, print out sense information\n"
10052 "-t timeout        command timeout in seconds, overrides default timeout\n"
10053 "-n dev_name       specify device name, e.g. \"da\", \"cd\"\n"
10054 "-u unit           specify unit number, e.g. \"0\", \"5\"\n"
10055 "-E                have the kernel attempt to perform SCSI error recovery\n"
10056 "-C count          specify the SCSI command retry count (needs -E to work)\n"
10057 "-Q task_attr      specify ordered, simple or head tag type for SCSI cmds\n"
10058 "modepage arguments:\n"
10059 "-l                list all available mode pages\n"
10060 "-m page           specify the mode page to view or edit\n"
10061 "-e                edit the specified mode page\n"
10062 "-b                force view to binary mode\n"
10063 "-d                disable block descriptors for mode sense\n"
10064 "-P pgctl          page control field 0-3\n"
10065 "defects arguments:\n"
10066 "-f format         specify defect list format (block, bfi or phys)\n"
10067 "-G                get the grown defect list\n"
10068 "-P                get the permanent defect list\n"
10069 "inquiry arguments:\n"
10070 "-D                get the standard inquiry data\n"
10071 "-S                get the serial number\n"
10072 "-R                get the transfer rate, etc.\n"
10073 "reportluns arguments:\n"
10074 "-c                only report a count of available LUNs\n"
10075 "-l                only print out luns, and not a count\n"
10076 "-r <reporttype>   specify \"default\", \"wellknown\" or \"all\"\n"
10077 "readcap arguments\n"
10078 "-b                only report the blocksize\n"
10079 "-h                human readable device size, base 2\n"
10080 "-H                human readable device size, base 10\n"
10081 "-N                print the number of blocks instead of last block\n"
10082 "-q                quiet, print numbers only\n"
10083 "-s                only report the last block/device size\n"
10084 "cmd arguments:\n"
10085 "-c cdb [args]     specify the SCSI CDB\n"
10086 "-i len fmt        specify input data and input data format\n"
10087 "-o len fmt [args] specify output data and output data fmt\n"
10088 "smpcmd arguments:\n"
10089 "-r len fmt [args] specify the SMP command to be sent\n"
10090 "-R len fmt [args] specify SMP response format\n"
10091 "smprg arguments:\n"
10092 "-l                specify the long response format\n"
10093 "smppc arguments:\n"
10094 "-p phy            specify the PHY to operate on\n"
10095 "-l                specify the long request/response format\n"
10096 "-o operation      specify the phy control operation\n"
10097 "-d name           set the attached device name\n"
10098 "-m rate           set the minimum physical link rate\n"
10099 "-M rate           set the maximum physical link rate\n"
10100 "-T pp_timeout     set the partial pathway timeout value\n"
10101 "-a enable|disable enable or disable SATA slumber\n"
10102 "-A enable|disable enable or disable SATA partial phy power\n"
10103 "-s enable|disable enable or disable SAS slumber\n"
10104 "-S enable|disable enable or disable SAS partial phy power\n"
10105 "smpphylist arguments:\n"
10106 "-l                specify the long response format\n"
10107 "-q                only print phys with attached devices\n"
10108 "smpmaninfo arguments:\n"
10109 "-l                specify the long response format\n"
10110 "debug arguments:\n"
10111 "-I                CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10112 "-T                CAM_DEBUG_TRACE -- routine flow tracking\n"
10113 "-S                CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10114 "-c                CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10115 "tags arguments:\n"
10116 "-N tags           specify the number of tags to use for this device\n"
10117 "-q                be quiet, don't report the number of tags\n"
10118 "-v                report a number of tag-related parameters\n"
10119 "negotiate arguments:\n"
10120 "-a                send a test unit ready after negotiation\n"
10121 "-c                report/set current negotiation settings\n"
10122 "-D <arg>          \"enable\" or \"disable\" disconnection\n"
10123 "-M mode           set ATA mode\n"
10124 "-O offset         set command delay offset\n"
10125 "-q                be quiet, don't report anything\n"
10126 "-R syncrate       synchronization rate in MHz\n"
10127 "-T <arg>          \"enable\" or \"disable\" tagged queueing\n"
10128 "-U                report/set user negotiation settings\n"
10129 "-W bus_width      set the bus width in bits (8, 16 or 32)\n"
10130 "-v                also print a Path Inquiry CCB for the controller\n"
10131 "format arguments:\n"
10132 "-q                be quiet, don't print status messages\n"
10133 "-r                run in report only mode\n"
10134 "-w                don't send immediate format command\n"
10135 "-y                don't ask any questions\n"
10136 "sanitize arguments:\n"
10137 "-a operation      operation mode: overwrite, block, crypto or exitfailure\n"
10138 "-c passes         overwrite passes to perform (1 to 31)\n"
10139 "-I                invert overwrite pattern after each pass\n"
10140 "-P pattern        path to overwrite pattern file\n"
10141 "-q                be quiet, don't print status messages\n"
10142 "-r                run in report only mode\n"
10143 "-U                run operation in unrestricted completion exit mode\n"
10144 "-w                don't send immediate sanitize command\n"
10145 "-y                don't ask any questions\n"
10146 "idle/standby arguments:\n"
10147 "-t <arg>          number of seconds before respective state.\n"
10148 "fwdownload arguments:\n"
10149 "-f fw_image       path to firmware image file\n"
10150 "-q                don't print informational messages, only errors\n"
10151 "-s                run in simulation mode\n"
10152 "-v                print info for every firmware segment sent to device\n"
10153 "-y                don't ask any questions\n"
10154 "security arguments:\n"
10155 "-d pwd            disable security using the given password for the selected\n"
10156 "                  user\n"
10157 "-e pwd            erase the device using the given pwd for the selected user\n"
10158 "-f                freeze the security configuration of the specified device\n"
10159 "-h pwd            enhanced erase the device using the given pwd for the\n"
10160 "                  selected user\n"
10161 "-k pwd            unlock the device using the given pwd for the selected\n"
10162 "                  user\n"
10163 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10164 "-q                be quiet, do not print any status messages\n"
10165 "-s pwd            password the device (enable security) using the given\n"
10166 "                  pwd for the selected user\n"
10167 "-T timeout        overrides the timeout (seconds) used for erase operation\n"
10168 "-U <user|master>  specifies which user to set: user or master\n"
10169 "-y                don't ask any questions\n"
10170 "hpa arguments:\n"
10171 "-f                freeze the HPA configuration of the device\n"
10172 "-l                lock the HPA configuration of the device\n"
10173 "-P                make the HPA max sectors persist\n"
10174 "-p pwd            Set the HPA configuration password required for unlock\n"
10175 "                  calls\n"
10176 "-q                be quiet, do not print any status messages\n"
10177 "-s sectors        configures the maximum user accessible sectors of the\n"
10178 "                  device\n"
10179 "-U pwd            unlock the HPA configuration of the device\n"
10180 "-y                don't ask any questions\n"
10181 "ama arguments:\n"
10182 "-f                freeze the AMA configuration of the device\n"
10183 "-q                be quiet, do not print any status messages\n"
10184 "-s sectors        configures the maximum user accessible sectors of the\n"
10185 "                  device\n"
10186 "persist arguments:\n"
10187 "-i action         specify read_keys, read_reservation, report_cap, or\n"
10188 "                  read_full_status\n"
10189 "-o action         specify register, register_ignore, reserve, release,\n"
10190 "                  clear, preempt, preempt_abort, register_move, replace_lost\n"
10191 "-a                set the All Target Ports (ALL_TG_PT) bit\n"
10192 "-I tid            specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10193 "-k key            specify the Reservation Key\n"
10194 "-K sa_key         specify the Service Action Reservation Key\n"
10195 "-p                set the Activate Persist Through Power Loss bit\n"
10196 "-R rtp            specify the Relative Target Port\n"
10197 "-s scope          specify the scope: lun, extent, element or a number\n"
10198 "-S                specify Transport ID for register, requires -I\n"
10199 "-T res_type       specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10200 "                  ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10201 "-U                unregister the current initiator for register_move\n"
10202 "attrib arguments:\n"
10203 "-r action         specify attr_values, attr_list, lv_list, part_list, or\n"
10204 "                  supp_attr\n"
10205 "-w attr           specify an attribute to write, one -w argument per attr\n"
10206 "-a attr_num       only display this attribute number\n"
10207 "-c                get cached attributes\n"
10208 "-e elem_addr      request attributes for the given element in a changer\n"
10209 "-F form1,form2    output format, comma separated list: text_esc, text_raw,\n"
10210 "                  nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10211 "                  field_none, field_desc, field_num, field_size, field_rw\n"
10212 "-p partition      request attributes for the given partition\n"
10213 "-s start_attr     request attributes starting at the given number\n"
10214 "-T elem_type      specify the element type (used with -e)\n"
10215 "-V logical_vol    specify the logical volume ID\n"
10216 "opcodes arguments:\n"
10217 "-o opcode         specify the individual opcode to list\n"
10218 "-s service_action specify the service action for the opcode\n"
10219 "-N                do not return SCSI error for unsupported SA\n"
10220 "-T                request nominal and recommended timeout values\n"
10221 "zone arguments:\n"
10222 "-c cmd            required: rz, open, close, finish, or rwp\n"
10223 "-a                apply the action to all zones\n"
10224 "-l LBA            specify the zone starting LBA\n"
10225 "-o rep_opts       report zones options: all, empty, imp_open, exp_open,\n"
10226 "                  closed, full, ro, offline, reset, nonseq, nonwp\n"
10227 "-P print_opt      report zones printing:  normal, summary, script\n"
10228 "epc arguments:\n"
10229 "-c cmd            required: restore, goto, timer, state, enable, disable,\n"
10230 "                  source, status, list\n"
10231 "-d                disable power mode (timer, state)\n"
10232 "-D                delayed entry (goto)\n"
10233 "-e                enable power mode (timer, state)\n"
10234 "-H                hold power mode (goto)\n"
10235 "-p power_cond     Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10236 "                  state, goto)\n"
10237 "-P                only display power mode (status)\n"
10238 "-r rst_src        restore settings from: default, saved (restore)\n"
10239 "-s                save mode (timer, state, restore)\n"
10240 "-S power_src      set power source: battery, nonbattery (source)\n"
10241 "-T timer          set timer, seconds, .1 sec resolution (timer)\n"
10242 "timestamp arguments:\n"
10243 "-r                report the timestamp of the device\n"
10244 "-f format         report the timestamp of the device with the given\n"
10245 "                  strftime(3) format string\n"
10246 "-m                report the timestamp of the device as milliseconds since\n"
10247 "                  January 1st, 1970\n"
10248 "-U                report the time with UTC instead of the local time zone\n"
10249 "-s                set the timestamp of the device\n"
10250 "-f format         the format of the time string passed into strptime(3)\n"
10251 "-T time           the time value passed into strptime(3)\n"
10252 "-U                set the timestamp of the device to UTC time\n"
10253 "mmcsdcmd arguments:\n"
10254 "-c mmc_cmd        MMC command to send to the card\n"
10255 "-a mmc_arg        Argument for the MMC command\n"
10256 "-f mmc_flag       Flags to set for the MMC command\n"
10257 "-l data_len       Expect data_len bytes of data in reply and display them\n"
10258 "-W                Fill the data buffer before invoking the MMC command\n"
10259 "-b data_byte      One byte of data to fill the data buffer with\n"
10260 "-F frequency      Operating frequency to set on the controller\n"
10261 "-4                Set bus width to 4 bit\n"
10262 "-1                Set bus width to 8 bit\n"
10263 "-S high | std     Set high-speed or standard timing\n"
10264 "-I                Display various card and host controller information\n"
10265 );
10266 }
10267
10268 int
10269 main(int argc, char **argv)
10270 {
10271         int c;
10272         char *device = NULL;
10273         int unit = 0;
10274         struct cam_device *cam_dev = NULL;
10275         int timeout = 0, retry_count = 1;
10276         camcontrol_optret optreturn;
10277         char *tstr;
10278         const char *mainopt = "C:En:Q:t:u:v";
10279         const char *subopt = NULL;
10280         char combinedopt[256];
10281         int error = 0, optstart = 2;
10282         int task_attr = MSG_SIMPLE_Q_TAG;
10283         int devopen = 1;
10284         path_id_t bus;
10285         target_id_t target;
10286         lun_id_t lun;
10287
10288         cmdlist = CAM_CMD_NONE;
10289         arglist = CAM_ARG_NONE;
10290
10291         if (argc < 2) {
10292                 usage(0);
10293                 exit(1);
10294         }
10295
10296         /*
10297          * Get the base option.
10298          */
10299         optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10300
10301         if (optreturn == CC_OR_AMBIGUOUS) {
10302                 warnx("ambiguous option %s", argv[1]);
10303                 usage(0);
10304                 exit(1);
10305         } else if (optreturn == CC_OR_NOT_FOUND) {
10306                 warnx("option %s not found", argv[1]);
10307                 usage(0);
10308                 exit(1);
10309         }
10310
10311         /*
10312          * Ahh, getopt(3) is a pain.
10313          *
10314          * This is a gross hack.  There really aren't many other good
10315          * options (excuse the pun) for parsing options in a situation like
10316          * this.  getopt is kinda braindead, so you end up having to run
10317          * through the options twice, and give each invocation of getopt
10318          * the option string for the other invocation.
10319          *
10320          * You would think that you could just have two groups of options.
10321          * The first group would get parsed by the first invocation of
10322          * getopt, and the second group would get parsed by the second
10323          * invocation of getopt.  It doesn't quite work out that way.  When
10324          * the first invocation of getopt finishes, it leaves optind pointing
10325          * to the argument _after_ the first argument in the second group.
10326          * So when the second invocation of getopt comes around, it doesn't
10327          * recognize the first argument it gets and then bails out.
10328          *
10329          * A nice alternative would be to have a flag for getopt that says
10330          * "just keep parsing arguments even when you encounter an unknown
10331          * argument", but there isn't one.  So there's no real clean way to
10332          * easily parse two sets of arguments without having one invocation
10333          * of getopt know about the other.
10334          *
10335          * Without this hack, the first invocation of getopt would work as
10336          * long as the generic arguments are first, but the second invocation
10337          * (in the subfunction) would fail in one of two ways.  In the case
10338          * where you don't set optreset, it would fail because optind may be
10339          * pointing to the argument after the one it should be pointing at.
10340          * In the case where you do set optreset, and reset optind, it would
10341          * fail because getopt would run into the first set of options, which
10342          * it doesn't understand.
10343          *
10344          * All of this would "sort of" work if you could somehow figure out
10345          * whether optind had been incremented one option too far.  The
10346          * mechanics of that, however, are more daunting than just giving
10347          * both invocations all of the expect options for either invocation.
10348          *
10349          * Needless to say, I wouldn't mind if someone invented a better
10350          * (non-GPL!) command line parsing interface than getopt.  I
10351          * wouldn't mind if someone added more knobs to getopt to make it
10352          * work better.  Who knows, I may talk myself into doing it someday,
10353          * if the standards weenies let me.  As it is, it just leads to
10354          * hackery like this and causes people to avoid it in some cases.
10355          *
10356          * KDM, September 8th, 1998
10357          */
10358         if (subopt != NULL)
10359                 sprintf(combinedopt, "%s%s", mainopt, subopt);
10360         else
10361                 sprintf(combinedopt, "%s", mainopt);
10362
10363         /*
10364          * For these options we do not parse optional device arguments and
10365          * we do not open a passthrough device.
10366          */
10367         if ((cmdlist == CAM_CMD_RESCAN)
10368          || (cmdlist == CAM_CMD_RESET)
10369          || (cmdlist == CAM_CMD_DEVTREE)
10370          || (cmdlist == CAM_CMD_USAGE)
10371          || (cmdlist == CAM_CMD_DEBUG))
10372                 devopen = 0;
10373
10374         if ((devopen == 1)
10375          && (argc > 2 && argv[2][0] != '-')) {
10376                 char name[30];
10377                 int rv;
10378
10379                 if (isdigit(argv[2][0])) {
10380                         /* device specified as bus:target[:lun] */
10381                         rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10382                         if (rv < 2)
10383                                 errx(1, "numeric device specification must "
10384                                      "be either bus:target, or "
10385                                      "bus:target:lun");
10386                         /* default to 0 if lun was not specified */
10387                         if ((arglist & CAM_ARG_LUN) == 0) {
10388                                 lun = 0;
10389                                 arglist |= CAM_ARG_LUN;
10390                         }
10391                         optstart++;
10392                 } else {
10393                         if (cam_get_device(argv[2], name, sizeof name, &unit)
10394                             == -1)
10395                                 errx(1, "%s", cam_errbuf);
10396                         device = strdup(name);
10397                         arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10398                         optstart++;
10399                 }
10400         }
10401         /*
10402          * Start getopt processing at argv[2/3], since we've already
10403          * accepted argv[1..2] as the command name, and as a possible
10404          * device name.
10405          */
10406         optind = optstart;
10407
10408         /*
10409          * Now we run through the argument list looking for generic
10410          * options, and ignoring options that possibly belong to
10411          * subfunctions.
10412          */
10413         while ((c = getopt(argc, argv, combinedopt))!= -1){
10414                 switch(c) {
10415                         case 'C':
10416                                 retry_count = strtol(optarg, NULL, 0);
10417                                 if (retry_count < 0)
10418                                         errx(1, "retry count %d is < 0",
10419                                              retry_count);
10420                                 arglist |= CAM_ARG_RETRIES;
10421                                 break;
10422                         case 'E':
10423                                 arglist |= CAM_ARG_ERR_RECOVER;
10424                                 break;
10425                         case 'n':
10426                                 arglist |= CAM_ARG_DEVICE;
10427                                 tstr = optarg;
10428                                 while (isspace(*tstr) && (*tstr != '\0'))
10429                                         tstr++;
10430                                 device = (char *)strdup(tstr);
10431                                 break;
10432                         case 'Q': {
10433                                 char *endptr;
10434                                 int table_entry = 0;
10435
10436                                 tstr = optarg;
10437                                 while (isspace(*tstr) && (*tstr != '\0'))
10438                                         tstr++;
10439                                 if (isdigit(*tstr)) {
10440                                         task_attr = strtol(tstr, &endptr, 0);
10441                                         if (*endptr != '\0') {
10442                                                 errx(1, "Invalid queue option "
10443                                                     "%s", tstr);
10444                                         }
10445                                 } else {
10446                                         size_t table_size;
10447                                         scsi_nv_status status;
10448
10449                                         table_size = sizeof(task_attrs) /
10450                                                      sizeof(task_attrs[0]);
10451                                         status = scsi_get_nv(task_attrs,
10452                                             table_size, tstr, &table_entry,
10453                                             SCSI_NV_FLAG_IG_CASE);
10454                                         if (status == SCSI_NV_FOUND)
10455                                                 task_attr = task_attrs[
10456                                                     table_entry].value;
10457                                         else {
10458                                                 errx(1, "%s option %s",
10459                                                   (status == SCSI_NV_AMBIGUOUS)?
10460                                                     "ambiguous" : "invalid",
10461                                                     tstr);
10462                                         }
10463                                 }
10464                                 break;
10465                         }
10466                         case 't':
10467                                 timeout = strtol(optarg, NULL, 0);
10468                                 if (timeout < 0)
10469                                         errx(1, "invalid timeout %d", timeout);
10470                                 /* Convert the timeout from seconds to ms */
10471                                 timeout *= 1000;
10472                                 arglist |= CAM_ARG_TIMEOUT;
10473                                 break;
10474                         case 'u':
10475                                 arglist |= CAM_ARG_UNIT;
10476                                 unit = strtol(optarg, NULL, 0);
10477                                 break;
10478                         case 'v':
10479                                 arglist |= CAM_ARG_VERBOSE;
10480                                 break;
10481                         default:
10482                                 break;
10483                 }
10484         }
10485
10486         /*
10487          * For most commands we'll want to open the passthrough device
10488          * associated with the specified device.  In the case of the rescan
10489          * commands, we don't use a passthrough device at all, just the
10490          * transport layer device.
10491          */
10492         if (devopen == 1) {
10493                 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10494                  && (((arglist & CAM_ARG_DEVICE) == 0)
10495                   || ((arglist & CAM_ARG_UNIT) == 0))) {
10496                         errx(1, "subcommand \"%s\" requires a valid device "
10497                              "identifier", argv[1]);
10498                 }
10499
10500                 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10501                                 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10502                                 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10503                      == NULL)
10504                         errx(1,"%s", cam_errbuf);
10505         }
10506
10507         /*
10508          * Reset optind to 2, and reset getopt, so these routines can parse
10509          * the arguments again.
10510          */
10511         optind = optstart;
10512         optreset = 1;
10513
10514         switch(cmdlist) {
10515         case CAM_CMD_DEVLIST:
10516                 error = getdevlist(cam_dev);
10517                 break;
10518         case CAM_CMD_HPA:
10519                 error = atahpa(cam_dev, retry_count, timeout,
10520                                argc, argv, combinedopt);
10521                 break;
10522         case CAM_CMD_AMA:
10523                 error = ataama(cam_dev, retry_count, timeout,
10524                                argc, argv, combinedopt);
10525                 break;
10526         case CAM_CMD_DEVTREE:
10527                 error = getdevtree(argc, argv, combinedopt);
10528                 break;
10529         case CAM_CMD_DEVTYPE:
10530                 error = getdevtype(cam_dev);
10531                 break;
10532         case CAM_CMD_TUR:
10533                 error = testunitready(cam_dev, task_attr, retry_count,
10534                     timeout, 0);
10535                 break;
10536         case CAM_CMD_INQUIRY:
10537                 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10538                                       task_attr, retry_count, timeout);
10539                 break;
10540         case CAM_CMD_IDENTIFY:
10541                 error = identify(cam_dev, retry_count, timeout);
10542                 break;
10543         case CAM_CMD_STARTSTOP:
10544                 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10545                                   arglist & CAM_ARG_EJECT, task_attr,
10546                                   retry_count, timeout);
10547                 break;
10548         case CAM_CMD_RESCAN:
10549                 error = dorescan_or_reset(argc, argv, 1);
10550                 break;
10551         case CAM_CMD_RESET:
10552                 error = dorescan_or_reset(argc, argv, 0);
10553                 break;
10554         case CAM_CMD_READ_DEFECTS:
10555                 error = readdefects(cam_dev, argc, argv, combinedopt,
10556                                     task_attr, retry_count, timeout);
10557                 break;
10558         case CAM_CMD_MODE_PAGE:
10559                 modepage(cam_dev, argc, argv, combinedopt,
10560                          task_attr, retry_count, timeout);
10561                 break;
10562         case CAM_CMD_SCSI_CMD:
10563                 error = scsicmd(cam_dev, argc, argv, combinedopt,
10564                                 task_attr, retry_count, timeout);
10565                 break;
10566         case CAM_CMD_MMCSD_CMD:
10567                 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10568                                         retry_count, timeout);
10569                 break;
10570         case CAM_CMD_SMP_CMD:
10571                 error = smpcmd(cam_dev, argc, argv, combinedopt,
10572                                retry_count, timeout);
10573                 break;
10574         case CAM_CMD_SMP_RG:
10575                 error = smpreportgeneral(cam_dev, argc, argv,
10576                                          combinedopt, retry_count,
10577                                          timeout);
10578                 break;
10579         case CAM_CMD_SMP_PC:
10580                 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10581                                       retry_count, timeout);
10582                 break;
10583         case CAM_CMD_SMP_PHYLIST:
10584                 error = smpphylist(cam_dev, argc, argv, combinedopt,
10585                                    retry_count, timeout);
10586                 break;
10587         case CAM_CMD_SMP_MANINFO:
10588                 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10589                                    retry_count, timeout);
10590                 break;
10591         case CAM_CMD_DEBUG:
10592                 error = camdebug(argc, argv, combinedopt);
10593                 break;
10594         case CAM_CMD_TAG:
10595                 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10596                 break;
10597         case CAM_CMD_RATE:
10598                 error = ratecontrol(cam_dev, task_attr, retry_count,
10599                                     timeout, argc, argv, combinedopt);
10600                 break;
10601         case CAM_CMD_FORMAT:
10602                 error = scsiformat(cam_dev, argc, argv,
10603                                    combinedopt, task_attr, retry_count,
10604                                    timeout);
10605                 break;
10606         case CAM_CMD_REPORTLUNS:
10607                 error = scsireportluns(cam_dev, argc, argv,
10608                                        combinedopt, task_attr,
10609                                        retry_count, timeout);
10610                 break;
10611         case CAM_CMD_READCAP:
10612                 error = scsireadcapacity(cam_dev, argc, argv,
10613                                          combinedopt, task_attr,
10614                                          retry_count, timeout);
10615                 break;
10616         case CAM_CMD_IDLE:
10617         case CAM_CMD_STANDBY:
10618         case CAM_CMD_SLEEP:
10619         case CAM_CMD_POWER_MODE:
10620                 error = atapm(cam_dev, argc, argv,
10621                               combinedopt, retry_count, timeout);
10622                 break;
10623         case CAM_CMD_APM:
10624         case CAM_CMD_AAM:
10625                 error = ataaxm(cam_dev, argc, argv,
10626                               combinedopt, retry_count, timeout);
10627                 break;
10628         case CAM_CMD_SECURITY:
10629                 error = atasecurity(cam_dev, retry_count, timeout,
10630                                     argc, argv, combinedopt);
10631                 break;
10632         case CAM_CMD_DOWNLOAD_FW:
10633                 error = fwdownload(cam_dev, argc, argv, combinedopt,
10634                     arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10635                     timeout);
10636                 break;
10637         case CAM_CMD_SANITIZE:
10638                 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10639                                  retry_count, timeout);
10640                 break;
10641         case CAM_CMD_PERSIST:
10642                 error = scsipersist(cam_dev, argc, argv, combinedopt,
10643                     task_attr, retry_count, timeout,
10644                     arglist & CAM_ARG_VERBOSE,
10645                     arglist & CAM_ARG_ERR_RECOVER);
10646                 break;
10647         case CAM_CMD_ATTRIB:
10648                 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10649                     task_attr, retry_count, timeout,
10650                     arglist & CAM_ARG_VERBOSE,
10651                     arglist & CAM_ARG_ERR_RECOVER);
10652                 break;
10653         case CAM_CMD_OPCODES:
10654                 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10655                     task_attr, retry_count, timeout,
10656                     arglist & CAM_ARG_VERBOSE);
10657                 break;
10658         case CAM_CMD_REPROBE:
10659                 error = reprobe(cam_dev);
10660                 break;
10661         case CAM_CMD_ZONE:
10662                 error = zone(cam_dev, argc, argv, combinedopt,
10663                     task_attr, retry_count, timeout,
10664                     arglist & CAM_ARG_VERBOSE);
10665                 break;
10666         case CAM_CMD_EPC:
10667                 error = epc(cam_dev, argc, argv, combinedopt,
10668                     retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10669                 break;
10670         case CAM_CMD_TIMESTAMP:
10671                 error = timestamp(cam_dev, argc, argv, combinedopt,
10672                     task_attr, retry_count, timeout,
10673                     arglist & CAM_ARG_VERBOSE);
10674                 break;
10675         case CAM_CMD_USAGE:
10676                 usage(1);
10677                 break;
10678         default:
10679                 usage(0);
10680                 error = 1;
10681                 break;
10682         }
10683
10684         if (cam_dev != NULL)
10685                 cam_close_device(cam_dev);
10686
10687         exit(error);
10688 }