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