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