]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/camcontrol/camcontrol.c
Import riscv DTS files
[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((void*)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                         warnx("SANITIZE STATUS EXT failed, "
6671                             "sanitize may still run.");
6672                         return (1);
6673                 }
6674                 if (count & 0x4000) {
6675                         if (quiet == 0) {
6676                                 val = lba & 0xffff;
6677                                 perc = 10000 * val;
6678                                 fprintf(stdout,
6679                                     "Sanitizing: %u.%02u%% (%d/%d)\r",
6680                                     (perc / (0x10000 * 100)),
6681                                     ((perc / 0x10000) % 100),
6682                                     val, 0x10000);
6683                                 fflush(stdout);
6684                         }
6685                         sleep(1);
6686                 } else if ((count & 0x8000) == 0) {
6687                         warnx("Sanitize complete with an error.     ");
6688                         return (1);
6689                 } else
6690                         break;
6691         } while (1);
6692         return (0);
6693 }
6694
6695 static int
6696 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6697 {
6698         int warnings = 0, retval;
6699         cam_status status;
6700         u_int val, perc;
6701
6702         do {
6703                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6704
6705                 /*
6706                  * There's really no need to do error recovery or
6707                  * retries here, since we're just going to sit in a
6708                  * loop and wait for the device to finish sanitizing.
6709                  */
6710                 scsi_test_unit_ready(&ccb->csio,
6711                                      /* retries */ 0,
6712                                      /* cbfcnp */ NULL,
6713                                      /* tag_action */ task_attr,
6714                                      /* sense_len */ SSD_FULL_SIZE,
6715                                      /* timeout */ 5000);
6716
6717                 /* Disable freezing the device queue */
6718                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6719
6720                 retval = cam_send_ccb(device, ccb);
6721
6722                 /*
6723                  * If we get an error from the ioctl, bail out.  SCSI
6724                  * errors are expected.
6725                  */
6726                 if (retval < 0) {
6727                         warn("error sending TEST UNIT READY command");
6728                         return (1);
6729                 }
6730
6731                 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6732                 if ((status == CAM_SCSI_STATUS_ERROR) &&
6733                     ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6734                         struct scsi_sense_data *sense;
6735                         int error_code, sense_key, asc, ascq;
6736
6737                         sense = &ccb->csio.sense_data;
6738                         scsi_extract_sense_len(sense, ccb->csio.sense_len -
6739                             ccb->csio.sense_resid, &error_code, &sense_key,
6740                             &asc, &ascq, /*show_errors*/ 1);
6741
6742                         /*
6743                          * According to the SCSI-3 spec, a drive that is in the
6744                          * middle of a sanitize should return NOT READY with an
6745                          * ASC of "logical unit not ready, sanitize in
6746                          * progress". The sense key specific bytes will then
6747                          * be a progress indicator.
6748                          */
6749                         if ((sense_key == SSD_KEY_NOT_READY)
6750                          && (asc == 0x04) && (ascq == 0x1b)) {
6751                                 uint8_t sks[3];
6752
6753                                 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6754                                      ccb->csio.sense_resid, sks) == 0)
6755                                  && (quiet == 0)) {
6756                                         val = scsi_2btoul(&sks[1]);
6757                                         perc = 10000 * val;
6758                                         fprintf(stdout,
6759                                             "Sanitizing: %u.%02u%% (%d/%d)\r",
6760                                             (perc / (0x10000 * 100)),
6761                                             ((perc / 0x10000) % 100),
6762                                             val, 0x10000);
6763                                         fflush(stdout);
6764                                 } else if ((quiet == 0) && (++warnings <= 1)) {
6765                                         warnx("Unexpected SCSI Sense Key "
6766                                               "Specific value returned "
6767                                               "during sanitize:");
6768                                         scsi_sense_print(device, &ccb->csio,
6769                                                          stderr);
6770                                         warnx("Unable to print status "
6771                                               "information, but sanitze will "
6772                                               "proceed.");
6773                                         warnx("will exit when sanitize is "
6774                                               "complete");
6775                                 }
6776                                 sleep(1);
6777                         } else {
6778                                 warnx("Unexpected SCSI error during sanitize");
6779                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6780                                                 CAM_EPF_ALL, stderr);
6781                                 return (1);
6782                         }
6783
6784                 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6785                         warnx("Unexpected CAM status %#x", status);
6786                         if (arglist & CAM_ARG_VERBOSE)
6787                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6788                                                 CAM_EPF_ALL, stderr);
6789                         return (1);
6790                 }
6791         } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6792         return (0);
6793 }
6794
6795 static int
6796 sanitize(struct cam_device *device, int argc, char **argv,
6797              char *combinedopt, int task_attr, int retry_count, int timeout)
6798 {
6799         union ccb *ccb;
6800         u_int8_t action = 0;
6801         int c;
6802         int ycount = 0, quiet = 0;
6803         int error = 0;
6804         int use_timeout;
6805         int immediate = 1;
6806         int invert = 0;
6807         int passes = 0;
6808         int ause = 0;
6809         int fd = -1;
6810         const char *pattern = NULL;
6811         u_int8_t *data_ptr = NULL;
6812         u_int32_t dxfer_len = 0;
6813         uint8_t byte2;
6814         uint16_t feature, count;
6815         uint64_t lba;
6816         int reportonly = 0;
6817         camcontrol_devtype dt;
6818
6819         /*
6820          * Get the device type, request no I/O be done to do this.
6821          */
6822         error = get_device_type(device, -1, 0, 0, &dt);
6823         if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6824                 warnx("sanitize: can't get device type");
6825                 return (1);
6826         }
6827
6828         ccb = cam_getccb(device);
6829
6830         if (ccb == NULL) {
6831                 warnx("sanitize: error allocating ccb");
6832                 return (1);
6833         }
6834
6835         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6836
6837         while ((c = getopt(argc, argv, combinedopt)) != -1) {
6838                 switch(c) {
6839                 case 'a':
6840                         if (strcasecmp(optarg, "overwrite") == 0)
6841                                 action = SSZ_SERVICE_ACTION_OVERWRITE;
6842                         else if (strcasecmp(optarg, "block") == 0)
6843                                 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6844                         else if (strcasecmp(optarg, "crypto") == 0)
6845                                 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6846                         else if (strcasecmp(optarg, "exitfailure") == 0)
6847                                 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6848                         else {
6849                                 warnx("invalid service operation \"%s\"",
6850                                       optarg);
6851                                 error = 1;
6852                                 goto sanitize_bailout;
6853                         }
6854                         break;
6855                 case 'c':
6856                         passes = strtol(optarg, NULL, 0);
6857                         if (passes < 1 || passes > 31) {
6858                                 warnx("invalid passes value %d", passes);
6859                                 error = 1;
6860                                 goto sanitize_bailout;
6861                         }
6862                         break;
6863                 case 'I':
6864                         invert = 1;
6865                         break;
6866                 case 'P':
6867                         pattern = optarg;
6868                         break;
6869                 case 'q':
6870                         quiet++;
6871                         break;
6872                 case 'U':
6873                         ause = 1;
6874                         break;
6875                 case 'r':
6876                         reportonly = 1;
6877                         break;
6878                 case 'w':
6879                         /* ATA supports only immediate commands. */
6880                         if (dt == CC_DT_SCSI)
6881                                 immediate = 0;
6882                         break;
6883                 case 'y':
6884                         ycount++;
6885                         break;
6886                 }
6887         }
6888
6889         if (reportonly)
6890                 goto doreport;
6891
6892         if (action == 0) {
6893                 warnx("an action is required");
6894                 error = 1;
6895                 goto sanitize_bailout;
6896         } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6897                 struct scsi_sanitize_parameter_list *pl;
6898                 struct stat sb;
6899                 ssize_t sz, amt;
6900
6901                 if (pattern == NULL) {
6902                         warnx("overwrite action requires -P argument");
6903                         error = 1;
6904                         goto sanitize_bailout;
6905                 }
6906                 fd = open(pattern, O_RDONLY);
6907                 if (fd < 0) {
6908                         warn("cannot open pattern file %s", pattern);
6909                         error = 1;
6910                         goto sanitize_bailout;
6911                 }
6912                 if (fstat(fd, &sb) < 0) {
6913                         warn("cannot stat pattern file %s", pattern);
6914                         error = 1;
6915                         goto sanitize_bailout;
6916                 }
6917                 sz = sb.st_size;
6918                 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6919                         warnx("pattern file size exceeds maximum value %d",
6920                               SSZPL_MAX_PATTERN_LENGTH);
6921                         error = 1;
6922                         goto sanitize_bailout;
6923                 }
6924                 dxfer_len = sizeof(*pl) + sz;
6925                 data_ptr = calloc(1, dxfer_len);
6926                 if (data_ptr == NULL) {
6927                         warnx("cannot allocate parameter list buffer");
6928                         error = 1;
6929                         goto sanitize_bailout;
6930                 }
6931
6932                 amt = read(fd, data_ptr + sizeof(*pl), sz);
6933                 if (amt < 0) {
6934                         warn("cannot read pattern file");
6935                         error = 1;
6936                         goto sanitize_bailout;
6937                 } else if (amt != sz) {
6938                         warnx("short pattern file read");
6939                         error = 1;
6940                         goto sanitize_bailout;
6941                 }
6942
6943                 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6944                 if (passes == 0)
6945                         pl->byte1 = 1;
6946                 else
6947                         pl->byte1 = passes;
6948                 if (invert != 0)
6949                         pl->byte1 |= SSZPL_INVERT;
6950                 scsi_ulto2b(sz, pl->length);
6951         } else {
6952                 const char *arg;
6953
6954                 if (passes != 0)
6955                         arg = "-c";
6956                 else if (invert != 0)
6957                         arg = "-I";
6958                 else if (pattern != NULL)
6959                         arg = "-P";
6960                 else
6961                         arg = NULL;
6962                 if (arg != NULL) {
6963                         warnx("%s argument only valid with overwrite "
6964                               "operation", arg);
6965                         error = 1;
6966                         goto sanitize_bailout;
6967                 }
6968         }
6969
6970         if (quiet == 0 && ycount == 0) {
6971                 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6972                         "following device:\n");
6973
6974                 if (dt == CC_DT_SCSI) {
6975                         error = scsidoinquiry(device, argc, argv, combinedopt,
6976                                               task_attr, retry_count, timeout);
6977                 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
6978                         struct ata_params *ident_buf;
6979                         error = ata_do_identify(device, retry_count, timeout,
6980                                                 ccb, &ident_buf);
6981                         if (error == 0) {
6982                                 printf("%s%d: ", device->device_name,
6983                                     device->dev_unit_num);
6984                                 ata_print_ident(ident_buf);
6985                                 free(ident_buf);
6986                         }
6987                 } else
6988                         error = 1;
6989
6990                 if (error != 0) {
6991                         warnx("sanitize: error sending inquiry");
6992                         goto sanitize_bailout;
6993                 }
6994         }
6995
6996         if (ycount == 0) {
6997                 if (!get_confirmation()) {
6998                         error = 1;
6999                         goto sanitize_bailout;
7000                 }
7001         }
7002
7003         if (timeout != 0)
7004                 use_timeout = timeout;
7005         else
7006                 use_timeout = (immediate ? 10 : 10800) * 1000;
7007
7008         if (immediate == 0 && quiet == 0) {
7009                 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7010                         use_timeout / 1000);
7011         }
7012
7013         /*
7014          * If the user hasn't disabled questions and didn't specify a
7015          * timeout on the command line, ask them if they want the current
7016          * timeout.
7017          */
7018         if (immediate == 0 && ycount == 0 && timeout == 0) {
7019                 char str[1024];
7020                 int new_timeout = 0;
7021
7022                 fprintf(stdout, "Enter new timeout in seconds or press\n"
7023                         "return to keep the current timeout [%d] ",
7024                         use_timeout / 1000);
7025
7026                 if (fgets(str, sizeof(str), stdin) != NULL) {
7027                         if (str[0] != '\0')
7028                                 new_timeout = atoi(str);
7029                 }
7030
7031                 if (new_timeout != 0) {
7032                         use_timeout = new_timeout * 1000;
7033                         fprintf(stdout, "Using new timeout value %d\n",
7034                                 use_timeout / 1000);
7035                 }
7036         }
7037
7038         if (dt == CC_DT_SCSI) {
7039                 byte2 = action;
7040                 if (ause != 0)
7041                         byte2 |= SSZ_UNRESTRICTED_EXIT;
7042                 if (immediate != 0)
7043                         byte2 |= SSZ_IMMED;
7044                 scsi_sanitize(&ccb->csio,
7045                               /* retries */ retry_count,
7046                               /* cbfcnp */ NULL,
7047                               /* tag_action */ task_attr,
7048                               /* byte2 */ byte2,
7049                               /* control */ 0,
7050                               /* data_ptr */ data_ptr,
7051                               /* dxfer_len */ dxfer_len,
7052                               /* sense_len */ SSD_FULL_SIZE,
7053                               /* timeout */ use_timeout);
7054
7055                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7056                 if (arglist & CAM_ARG_ERR_RECOVER)
7057                         ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7058                 if (cam_send_ccb(device, ccb) < 0) {
7059                         warn("error sending sanitize command");
7060                         error = 1;
7061                         goto sanitize_bailout;
7062                 }
7063         } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7064                 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7065                         feature = 0x14; /* OVERWRITE EXT */
7066                         lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7067                         count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7068                         if (invert)
7069                                 count |= 0x80; /* INVERT PATTERN */
7070                         if (ause)
7071                                 count |= 0x10; /* FAILURE MODE */
7072                 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7073                         feature = 0x12; /* BLOCK ERASE EXT */
7074                         lba = 0x0000426B4572;
7075                         count = 0;
7076                         if (ause)
7077                                 count |= 0x10; /* FAILURE MODE */
7078                 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7079                         feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7080                         lba = 0x000043727970;
7081                         count = 0;
7082                         if (ause)
7083                                 count |= 0x10; /* FAILURE MODE */
7084                 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7085                         feature = 0x00; /* SANITIZE STATUS EXT */
7086                         lba = 0;
7087                         count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7088                 } else {
7089                         error = 1;
7090                         goto sanitize_bailout;
7091                 }
7092
7093                 error = ata_do_cmd(device,
7094                                    ccb,
7095                                    retry_count,
7096                                    /*flags*/CAM_DIR_NONE,
7097                                    /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7098                                    /*ata_flags*/0,
7099                                    /*tag_action*/MSG_SIMPLE_Q_TAG,
7100                                    /*command*/ATA_SANITIZE,
7101                                    /*features*/feature,
7102                                    /*lba*/lba,
7103                                    /*sector_count*/count,
7104                                    /*data_ptr*/NULL,
7105                                    /*dxfer_len*/0,
7106                                    /*timeout*/ use_timeout,
7107                                    /*is48bit*/1);
7108         }
7109
7110         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7111                 struct scsi_sense_data *sense;
7112                 int error_code, sense_key, asc, ascq;
7113
7114                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7115                     CAM_SCSI_STATUS_ERROR) {
7116                         sense = &ccb->csio.sense_data;
7117                         scsi_extract_sense_len(sense, ccb->csio.sense_len -
7118                             ccb->csio.sense_resid, &error_code, &sense_key,
7119                             &asc, &ascq, /*show_errors*/ 1);
7120
7121                         if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7122                             asc == 0x20 && ascq == 0x00)
7123                                 warnx("sanitize is not supported by "
7124                                       "this device");
7125                         else
7126                                 warnx("error sanitizing this device");
7127                 } else
7128                         warnx("error sanitizing this device");
7129
7130                 if (arglist & CAM_ARG_VERBOSE) {
7131                         cam_error_print(device, ccb, CAM_ESF_ALL,
7132                                         CAM_EPF_ALL, stderr);
7133                 }
7134                 error = 1;
7135                 goto sanitize_bailout;
7136         }
7137
7138         /*
7139          * If we ran in non-immediate mode, we already checked for errors
7140          * above and printed out any necessary information.  If we're in
7141          * immediate mode, we need to loop through and get status
7142          * information periodically.
7143          */
7144         if (immediate == 0) {
7145                 if (quiet == 0) {
7146                         fprintf(stdout, "Sanitize Complete\n");
7147                 }
7148                 goto sanitize_bailout;
7149         }
7150
7151 doreport:
7152         if (dt == CC_DT_SCSI) {
7153                 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7154         } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7155                 error = sanitize_wait_ata(device, ccb, quiet, dt);
7156         } else
7157                 error = 1;
7158         if (error == 0 && quiet == 0)
7159                 fprintf(stdout, "Sanitize Complete                      \n");
7160
7161 sanitize_bailout:
7162         if (fd >= 0)
7163                 close(fd);
7164         if (data_ptr != NULL)
7165                 free(data_ptr);
7166         cam_freeccb(ccb);
7167
7168         return (error);
7169 }
7170
7171 static int
7172 scsireportluns(struct cam_device *device, int argc, char **argv,
7173                char *combinedopt, int task_attr, int retry_count, int timeout)
7174 {
7175         union ccb *ccb;
7176         int c, countonly, lunsonly;
7177         struct scsi_report_luns_data *lundata;
7178         int alloc_len;
7179         uint8_t report_type;
7180         uint32_t list_len, i, j;
7181         int retval;
7182
7183         retval = 0;
7184         lundata = NULL;
7185         report_type = RPL_REPORT_DEFAULT;
7186         ccb = cam_getccb(device);
7187
7188         if (ccb == NULL) {
7189                 warnx("%s: error allocating ccb", __func__);
7190                 return (1);
7191         }
7192
7193         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7194
7195         countonly = 0;
7196         lunsonly = 0;
7197
7198         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7199                 switch (c) {
7200                 case 'c':
7201                         countonly++;
7202                         break;
7203                 case 'l':
7204                         lunsonly++;
7205                         break;
7206                 case 'r':
7207                         if (strcasecmp(optarg, "default") == 0)
7208                                 report_type = RPL_REPORT_DEFAULT;
7209                         else if (strcasecmp(optarg, "wellknown") == 0)
7210                                 report_type = RPL_REPORT_WELLKNOWN;
7211                         else if (strcasecmp(optarg, "all") == 0)
7212                                 report_type = RPL_REPORT_ALL;
7213                         else {
7214                                 warnx("%s: invalid report type \"%s\"",
7215                                       __func__, optarg);
7216                                 retval = 1;
7217                                 goto bailout;
7218                         }
7219                         break;
7220                 default:
7221                         break;
7222                 }
7223         }
7224
7225         if ((countonly != 0)
7226          && (lunsonly != 0)) {
7227                 warnx("%s: you can only specify one of -c or -l", __func__);
7228                 retval = 1;
7229                 goto bailout;
7230         }
7231         /*
7232          * According to SPC-4, the allocation length must be at least 16
7233          * bytes -- enough for the header and one LUN.
7234          */
7235         alloc_len = sizeof(*lundata) + 8;
7236
7237 retry:
7238
7239         lundata = malloc(alloc_len);
7240
7241         if (lundata == NULL) {
7242                 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7243                 retval = 1;
7244                 goto bailout;
7245         }
7246
7247         scsi_report_luns(&ccb->csio,
7248                          /*retries*/ retry_count,
7249                          /*cbfcnp*/ NULL,
7250                          /*tag_action*/ task_attr,
7251                          /*select_report*/ report_type,
7252                          /*rpl_buf*/ lundata,
7253                          /*alloc_len*/ alloc_len,
7254                          /*sense_len*/ SSD_FULL_SIZE,
7255                          /*timeout*/ timeout ? timeout : 5000);
7256
7257         /* Disable freezing the device queue */
7258         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7259
7260         if (arglist & CAM_ARG_ERR_RECOVER)
7261                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7262
7263         if (cam_send_ccb(device, ccb) < 0) {
7264                 warn("error sending REPORT LUNS command");
7265                 retval = 1;
7266                 goto bailout;
7267         }
7268
7269         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7270                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7271                 retval = 1;
7272                 goto bailout;
7273         }
7274
7275
7276         list_len = scsi_4btoul(lundata->length);
7277
7278         /*
7279          * If we need to list the LUNs, and our allocation
7280          * length was too short, reallocate and retry.
7281          */
7282         if ((countonly == 0)
7283          && (list_len > (alloc_len - sizeof(*lundata)))) {
7284                 alloc_len = list_len + sizeof(*lundata);
7285                 free(lundata);
7286                 goto retry;
7287         }
7288
7289         if (lunsonly == 0)
7290                 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7291                         ((list_len / 8) > 1) ? "s" : "");
7292
7293         if (countonly != 0)
7294                 goto bailout;
7295
7296         for (i = 0; i < (list_len / 8); i++) {
7297                 int no_more;
7298
7299                 no_more = 0;
7300                 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7301                         if (j != 0)
7302                                 fprintf(stdout, ",");
7303                         switch (lundata->luns[i].lundata[j] &
7304                                 RPL_LUNDATA_ATYP_MASK) {
7305                         case RPL_LUNDATA_ATYP_PERIPH:
7306                                 if ((lundata->luns[i].lundata[j] &
7307                                     RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7308                                         fprintf(stdout, "%d:",
7309                                                 lundata->luns[i].lundata[j] &
7310                                                 RPL_LUNDATA_PERIPH_BUS_MASK);
7311                                 else if ((j == 0)
7312                                       && ((lundata->luns[i].lundata[j+2] &
7313                                           RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7314                                         no_more = 1;
7315
7316                                 fprintf(stdout, "%d",
7317                                         lundata->luns[i].lundata[j+1]);
7318                                 break;
7319                         case RPL_LUNDATA_ATYP_FLAT: {
7320                                 uint8_t tmplun[2];
7321                                 tmplun[0] = lundata->luns[i].lundata[j] &
7322                                         RPL_LUNDATA_FLAT_LUN_MASK;
7323                                 tmplun[1] = lundata->luns[i].lundata[j+1];
7324
7325                                 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7326                                 no_more = 1;
7327                                 break;
7328                         }
7329                         case RPL_LUNDATA_ATYP_LUN:
7330                                 fprintf(stdout, "%d:%d:%d",
7331                                         (lundata->luns[i].lundata[j+1] &
7332                                         RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7333                                         lundata->luns[i].lundata[j] &
7334                                         RPL_LUNDATA_LUN_TARG_MASK,
7335                                         lundata->luns[i].lundata[j+1] &
7336                                         RPL_LUNDATA_LUN_LUN_MASK);
7337                                 break;
7338                         case RPL_LUNDATA_ATYP_EXTLUN: {
7339                                 int field_len_code, eam_code;
7340
7341                                 eam_code = lundata->luns[i].lundata[j] &
7342                                         RPL_LUNDATA_EXT_EAM_MASK;
7343                                 field_len_code = (lundata->luns[i].lundata[j] &
7344                                         RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7345
7346                                 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7347                                  && (field_len_code == 0x00)) {
7348                                         fprintf(stdout, "%d",
7349                                                 lundata->luns[i].lundata[j+1]);
7350                                 } else if ((eam_code ==
7351                                             RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7352                                         && (field_len_code == 0x03)) {
7353                                         uint8_t tmp_lun[8];
7354
7355                                         /*
7356                                          * This format takes up all 8 bytes.
7357                                          * If we aren't starting at offset 0,
7358                                          * that's a bug.
7359                                          */
7360                                         if (j != 0) {
7361                                                 fprintf(stdout, "Invalid "
7362                                                         "offset %d for "
7363                                                         "Extended LUN not "
7364                                                         "specified format", j);
7365                                                 no_more = 1;
7366                                                 break;
7367                                         }
7368                                         bzero(tmp_lun, sizeof(tmp_lun));
7369                                         bcopy(&lundata->luns[i].lundata[j+1],
7370                                               &tmp_lun[1], sizeof(tmp_lun) - 1);
7371                                         fprintf(stdout, "%#jx",
7372                                                (intmax_t)scsi_8btou64(tmp_lun));
7373                                         no_more = 1;
7374                                 } else {
7375                                         fprintf(stderr, "Unknown Extended LUN"
7376                                                 "Address method %#x, length "
7377                                                 "code %#x", eam_code,
7378                                                 field_len_code);
7379                                         no_more = 1;
7380                                 }
7381                                 break;
7382                         }
7383                         default:
7384                                 fprintf(stderr, "Unknown LUN address method "
7385                                         "%#x\n", lundata->luns[i].lundata[0] &
7386                                         RPL_LUNDATA_ATYP_MASK);
7387                                 break;
7388                         }
7389                         /*
7390                          * For the flat addressing method, there are no
7391                          * other levels after it.
7392                          */
7393                         if (no_more != 0)
7394                                 break;
7395                 }
7396                 fprintf(stdout, "\n");
7397         }
7398
7399 bailout:
7400
7401         cam_freeccb(ccb);
7402
7403         free(lundata);
7404
7405         return (retval);
7406 }
7407
7408 static int
7409 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7410                  char *combinedopt, int task_attr, int retry_count, int timeout)
7411 {
7412         union ccb *ccb;
7413         int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7414         struct scsi_read_capacity_data rcap;
7415         struct scsi_read_capacity_data_long rcaplong;
7416         uint64_t maxsector;
7417         uint32_t block_len;
7418         int retval;
7419         int c;
7420
7421         blocksizeonly = 0;
7422         humanize = 0;
7423         longonly = 0;
7424         numblocks = 0;
7425         quiet = 0;
7426         sizeonly = 0;
7427         baseten = 0;
7428         retval = 0;
7429
7430         ccb = cam_getccb(device);
7431
7432         if (ccb == NULL) {
7433                 warnx("%s: error allocating ccb", __func__);
7434                 return (1);
7435         }
7436
7437         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7438
7439         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7440                 switch (c) {
7441                 case 'b':
7442                         blocksizeonly++;
7443                         break;
7444                 case 'h':
7445                         humanize++;
7446                         baseten = 0;
7447                         break;
7448                 case 'H':
7449                         humanize++;
7450                         baseten++;
7451                         break;
7452                 case 'l':
7453                         longonly++;
7454                         break;
7455                 case 'N':
7456                         numblocks++;
7457                         break;
7458                 case 'q':
7459                         quiet++;
7460                         break;
7461                 case 's':
7462                         sizeonly++;
7463                         break;
7464                 default:
7465                         break;
7466                 }
7467         }
7468
7469         if ((blocksizeonly != 0)
7470          && (numblocks != 0)) {
7471                 warnx("%s: you can only specify one of -b or -N", __func__);
7472                 retval = 1;
7473                 goto bailout;
7474         }
7475
7476         if ((blocksizeonly != 0)
7477          && (sizeonly != 0)) {
7478                 warnx("%s: you can only specify one of -b or -s", __func__);
7479                 retval = 1;
7480                 goto bailout;
7481         }
7482
7483         if ((humanize != 0)
7484          && (quiet != 0)) {
7485                 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7486                 retval = 1;
7487                 goto bailout;
7488         }
7489
7490         if ((humanize != 0)
7491          && (blocksizeonly != 0)) {
7492                 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7493                 retval = 1;
7494                 goto bailout;
7495         }
7496
7497         if (longonly != 0)
7498                 goto long_only;
7499
7500         scsi_read_capacity(&ccb->csio,
7501                            /*retries*/ retry_count,
7502                            /*cbfcnp*/ NULL,
7503                            /*tag_action*/ task_attr,
7504                            &rcap,
7505                            SSD_FULL_SIZE,
7506                            /*timeout*/ timeout ? timeout : 5000);
7507
7508         /* Disable freezing the device queue */
7509         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7510
7511         if (arglist & CAM_ARG_ERR_RECOVER)
7512                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7513
7514         if (cam_send_ccb(device, ccb) < 0) {
7515                 warn("error sending READ CAPACITY command");
7516                 retval = 1;
7517                 goto bailout;
7518         }
7519
7520         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7521                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7522                 retval = 1;
7523                 goto bailout;
7524         }
7525
7526         maxsector = scsi_4btoul(rcap.addr);
7527         block_len = scsi_4btoul(rcap.length);
7528
7529         /*
7530          * A last block of 2^32-1 means that the true capacity is over 2TB,
7531          * and we need to issue the long READ CAPACITY to get the real
7532          * capacity.  Otherwise, we're all set.
7533          */
7534         if (maxsector != 0xffffffff)
7535                 goto do_print;
7536
7537 long_only:
7538         scsi_read_capacity_16(&ccb->csio,
7539                               /*retries*/ retry_count,
7540                               /*cbfcnp*/ NULL,
7541                               /*tag_action*/ task_attr,
7542                               /*lba*/ 0,
7543                               /*reladdr*/ 0,
7544                               /*pmi*/ 0,
7545                               /*rcap_buf*/ (uint8_t *)&rcaplong,
7546                               /*rcap_buf_len*/ sizeof(rcaplong),
7547                               /*sense_len*/ SSD_FULL_SIZE,
7548                               /*timeout*/ timeout ? timeout : 5000);
7549
7550         /* Disable freezing the device queue */
7551         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7552
7553         if (arglist & CAM_ARG_ERR_RECOVER)
7554                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7555
7556         if (cam_send_ccb(device, ccb) < 0) {
7557                 warn("error sending READ CAPACITY (16) command");
7558                 retval = 1;
7559                 goto bailout;
7560         }
7561
7562         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7563                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7564                 retval = 1;
7565                 goto bailout;
7566         }
7567
7568         maxsector = scsi_8btou64(rcaplong.addr);
7569         block_len = scsi_4btoul(rcaplong.length);
7570
7571 do_print:
7572         if (blocksizeonly == 0) {
7573                 /*
7574                  * Humanize implies !quiet, and also implies numblocks.
7575                  */
7576                 if (humanize != 0) {
7577                         char tmpstr[6];
7578                         int64_t tmpbytes;
7579                         int ret;
7580
7581                         tmpbytes = (maxsector + 1) * block_len;
7582                         ret = humanize_number(tmpstr, sizeof(tmpstr),
7583                                               tmpbytes, "", HN_AUTOSCALE,
7584                                               HN_B | HN_DECIMAL |
7585                                               ((baseten != 0) ?
7586                                               HN_DIVISOR_1000 : 0));
7587                         if (ret == -1) {
7588                                 warnx("%s: humanize_number failed!", __func__);
7589                                 retval = 1;
7590                                 goto bailout;
7591                         }
7592                         fprintf(stdout, "Device Size: %s%s", tmpstr,
7593                                 (sizeonly == 0) ?  ", " : "\n");
7594                 } else if (numblocks != 0) {
7595                         fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7596                                 "Blocks: " : "", (uintmax_t)maxsector + 1,
7597                                 (sizeonly == 0) ? ", " : "\n");
7598                 } else {
7599                         fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7600                                 "Last Block: " : "", (uintmax_t)maxsector,
7601                                 (sizeonly == 0) ? ", " : "\n");
7602                 }
7603         }
7604         if (sizeonly == 0)
7605                 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7606                         "Block Length: " : "", block_len, (quiet == 0) ?
7607                         " bytes" : "");
7608 bailout:
7609         cam_freeccb(ccb);
7610
7611         return (retval);
7612 }
7613
7614 static int
7615 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7616        int retry_count, int timeout)
7617 {
7618         int c, error = 0;
7619         union ccb *ccb;
7620         uint8_t *smp_request = NULL, *smp_response = NULL;
7621         int request_size = 0, response_size = 0;
7622         int fd_request = 0, fd_response = 0;
7623         char *datastr = NULL;
7624         struct get_hook hook;
7625         int retval;
7626         int flags = 0;
7627
7628         /*
7629          * Note that at the moment we don't support sending SMP CCBs to
7630          * devices that aren't probed by CAM.
7631          */
7632         ccb = cam_getccb(device);
7633         if (ccb == NULL) {
7634                 warnx("%s: error allocating CCB", __func__);
7635                 return (1);
7636         }
7637
7638         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7639
7640         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7641                 switch (c) {
7642                 case 'R':
7643                         arglist |= CAM_ARG_CMD_IN;
7644                         response_size = strtol(optarg, NULL, 0);
7645                         if (response_size <= 0) {
7646                                 warnx("invalid number of response bytes %d",
7647                                       response_size);
7648                                 error = 1;
7649                                 goto smpcmd_bailout;
7650                         }
7651                         hook.argc = argc - optind;
7652                         hook.argv = argv + optind;
7653                         hook.got = 0;
7654                         optind++;
7655                         datastr = cget(&hook, NULL);
7656                         /*
7657                          * If the user supplied "-" instead of a format, he
7658                          * wants the data to be written to stdout.
7659                          */
7660                         if ((datastr != NULL)
7661                          && (datastr[0] == '-'))
7662                                 fd_response = 1;
7663
7664                         smp_response = (u_int8_t *)malloc(response_size);
7665                         if (smp_response == NULL) {
7666                                 warn("can't malloc memory for SMP response");
7667                                 error = 1;
7668                                 goto smpcmd_bailout;
7669                         }
7670                         break;
7671                 case 'r':
7672                         arglist |= CAM_ARG_CMD_OUT;
7673                         request_size = strtol(optarg, NULL, 0);
7674                         if (request_size <= 0) {
7675                                 warnx("invalid number of request bytes %d",
7676                                       request_size);
7677                                 error = 1;
7678                                 goto smpcmd_bailout;
7679                         }
7680                         hook.argc = argc - optind;
7681                         hook.argv = argv + optind;
7682                         hook.got = 0;
7683                         datastr = cget(&hook, NULL);
7684                         smp_request = (u_int8_t *)malloc(request_size);
7685                         if (smp_request == NULL) {
7686                                 warn("can't malloc memory for SMP request");
7687                                 error = 1;
7688                                 goto smpcmd_bailout;
7689                         }
7690                         bzero(smp_request, request_size);
7691                         /*
7692                          * If the user supplied "-" instead of a format, he
7693                          * wants the data to be read from stdin.
7694                          */
7695                         if ((datastr != NULL)
7696                          && (datastr[0] == '-'))
7697                                 fd_request = 1;
7698                         else
7699                                 buff_encode_visit(smp_request, request_size,
7700                                                   datastr,
7701                                                   iget, &hook);
7702                         optind += hook.got;
7703                         break;
7704                 default:
7705                         break;
7706                 }
7707         }
7708
7709         /*
7710          * If fd_data is set, and we're writing to the device, we need to
7711          * read the data the user wants written from stdin.
7712          */
7713         if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7714                 ssize_t amt_read;
7715                 int amt_to_read = request_size;
7716                 u_int8_t *buf_ptr = smp_request;
7717
7718                 for (amt_read = 0; amt_to_read > 0;
7719                      amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7720                         if (amt_read == -1) {
7721                                 warn("error reading data from stdin");
7722                                 error = 1;
7723                                 goto smpcmd_bailout;
7724                         }
7725                         amt_to_read -= amt_read;
7726                         buf_ptr += amt_read;
7727                 }
7728         }
7729
7730         if (((arglist & CAM_ARG_CMD_IN) == 0)
7731          || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7732                 warnx("%s: need both the request (-r) and response (-R) "
7733                       "arguments", __func__);
7734                 error = 1;
7735                 goto smpcmd_bailout;
7736         }
7737
7738         flags |= CAM_DEV_QFRZDIS;
7739
7740         cam_fill_smpio(&ccb->smpio,
7741                        /*retries*/ retry_count,
7742                        /*cbfcnp*/ NULL,
7743                        /*flags*/ flags,
7744                        /*smp_request*/ smp_request,
7745                        /*smp_request_len*/ request_size,
7746                        /*smp_response*/ smp_response,
7747                        /*smp_response_len*/ response_size,
7748                        /*timeout*/ timeout ? timeout : 5000);
7749
7750         ccb->smpio.flags = SMP_FLAG_NONE;
7751
7752         if (((retval = cam_send_ccb(device, ccb)) < 0)
7753          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7754                 const char warnstr[] = "error sending command";
7755
7756                 if (retval < 0)
7757                         warn(warnstr);
7758                 else
7759                         warnx(warnstr);
7760
7761                 if (arglist & CAM_ARG_VERBOSE) {
7762                         cam_error_print(device, ccb, CAM_ESF_ALL,
7763                                         CAM_EPF_ALL, stderr);
7764                 }
7765         }
7766
7767         if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7768          && (response_size > 0)) {
7769                 if (fd_response == 0) {
7770                         buff_decode_visit(smp_response, response_size,
7771                                           datastr, arg_put, NULL);
7772                         fprintf(stdout, "\n");
7773                 } else {
7774                         ssize_t amt_written;
7775                         int amt_to_write = response_size;
7776                         u_int8_t *buf_ptr = smp_response;
7777
7778                         for (amt_written = 0; (amt_to_write > 0) &&
7779                              (amt_written = write(STDOUT_FILENO, buf_ptr,
7780                                                   amt_to_write)) > 0;){
7781                                 amt_to_write -= amt_written;
7782                                 buf_ptr += amt_written;
7783                         }
7784                         if (amt_written == -1) {
7785                                 warn("error writing data to stdout");
7786                                 error = 1;
7787                                 goto smpcmd_bailout;
7788                         } else if ((amt_written == 0)
7789                                 && (amt_to_write > 0)) {
7790                                 warnx("only wrote %u bytes out of %u",
7791                                       response_size - amt_to_write,
7792                                       response_size);
7793                         }
7794                 }
7795         }
7796 smpcmd_bailout:
7797         if (ccb != NULL)
7798                 cam_freeccb(ccb);
7799
7800         if (smp_request != NULL)
7801                 free(smp_request);
7802
7803         if (smp_response != NULL)
7804                 free(smp_response);
7805
7806         return (error);
7807 }
7808
7809 static int
7810 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7811        int retry_count, int timeout)
7812 {
7813         int c, error = 0;
7814         union ccb *ccb;
7815         int32_t mmc_opcode = 0, mmc_arg = 0;
7816         int32_t mmc_flags = -1;
7817         int retval;
7818         int is_write = 0;
7819         int is_bw_4 = 0, is_bw_1 = 0;
7820         int is_highspeed = 0, is_stdspeed = 0;
7821         int is_info_request = 0;
7822         int flags = 0;
7823         uint8_t mmc_data_byte = 0;
7824
7825         /* For IO_RW_EXTENDED command */
7826         uint8_t *mmc_data = NULL;
7827         struct mmc_data mmc_d;
7828         int mmc_data_len = 0;
7829
7830         /*
7831          * Note that at the moment we don't support sending SMP CCBs to
7832          * devices that aren't probed by CAM.
7833          */
7834         ccb = cam_getccb(device);
7835         if (ccb == NULL) {
7836                 warnx("%s: error allocating CCB", __func__);
7837                 return (1);
7838         }
7839
7840         bzero(&(&ccb->ccb_h)[1],
7841               sizeof(union ccb) - sizeof(struct ccb_hdr));
7842
7843         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7844                 switch (c) {
7845                 case '4':
7846                         is_bw_4 = 1;
7847                         break;
7848                 case '1':
7849                         is_bw_1 = 1;
7850                         break;
7851                 case 'S':
7852                         if (!strcmp(optarg, "high"))
7853                                 is_highspeed = 1;
7854                         else
7855                                 is_stdspeed = 1;
7856                         break;
7857                 case 'I':
7858                         is_info_request = 1;
7859                         break;
7860                 case 'c':
7861                         mmc_opcode = strtol(optarg, NULL, 0);
7862                         if (mmc_opcode < 0) {
7863                                 warnx("invalid MMC opcode %d",
7864                                       mmc_opcode);
7865                                 error = 1;
7866                                 goto mmccmd_bailout;
7867                         }
7868                         break;
7869                 case 'a':
7870                         mmc_arg = strtol(optarg, NULL, 0);
7871                         if (mmc_arg < 0) {
7872                                 warnx("invalid MMC arg %d",
7873                                       mmc_arg);
7874                                 error = 1;
7875                                 goto mmccmd_bailout;
7876                         }
7877                         break;
7878                 case 'f':
7879                         mmc_flags = strtol(optarg, NULL, 0);
7880                         if (mmc_flags < 0) {
7881                                 warnx("invalid MMC flags %d",
7882                                       mmc_flags);
7883                                 error = 1;
7884                                 goto mmccmd_bailout;
7885                         }
7886                         break;
7887                 case 'l':
7888                         mmc_data_len = strtol(optarg, NULL, 0);
7889                         if (mmc_data_len <= 0) {
7890                                 warnx("invalid MMC data len %d",
7891                                       mmc_data_len);
7892                                 error = 1;
7893                                 goto mmccmd_bailout;
7894                         }
7895                         break;
7896                 case 'W':
7897                         is_write = 1;
7898                         break;
7899                 case 'b':
7900                         mmc_data_byte = strtol(optarg, NULL, 0);
7901                         break;
7902                 default:
7903                         break;
7904                 }
7905         }
7906         flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7907
7908         /* If flags are left default, supply the right flags */
7909         if (mmc_flags < 0)
7910                 switch (mmc_opcode) {
7911                 case MMC_GO_IDLE_STATE:
7912                         mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7913                         break;
7914                 case IO_SEND_OP_COND:
7915                         mmc_flags = MMC_RSP_R4;
7916                         break;
7917                 case SD_SEND_RELATIVE_ADDR:
7918                         mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7919                         break;
7920                 case MMC_SELECT_CARD:
7921                         mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7922                         mmc_arg = mmc_arg << 16;
7923                         break;
7924                 case SD_IO_RW_DIRECT:
7925                         mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7926                         mmc_arg = SD_IO_RW_ADR(mmc_arg);
7927                         if (is_write)
7928                                 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7929                         break;
7930                 case SD_IO_RW_EXTENDED:
7931                         mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7932                         mmc_arg = SD_IO_RW_ADR(mmc_arg);
7933                         int len_arg = mmc_data_len;
7934                         if (mmc_data_len == 512)
7935                                 len_arg = 0;
7936
7937                         // Byte mode
7938                         mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7939                         // Block mode
7940 //                        mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7941                         break;
7942                 default:
7943                         mmc_flags = MMC_RSP_R1;
7944                         break;
7945                 }
7946
7947         // Switch bus width instead of sending IO command
7948         if (is_bw_4 || is_bw_1) {
7949                 struct ccb_trans_settings_mmc *cts;
7950                 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7951                 ccb->ccb_h.flags = 0;
7952                 cts = &ccb->cts.proto_specific.mmc;
7953                 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7954                 cts->ios_valid = MMC_BW;
7955                 if (((retval = cam_send_ccb(device, ccb)) < 0)
7956                     || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7957                         warn("Error sending command");
7958                 } else {
7959                         printf("Parameters set OK\n");
7960                 }
7961                 cam_freeccb(ccb);
7962                 return (retval);
7963         }
7964
7965         // Switch bus speed instead of sending IO command
7966         if (is_stdspeed || is_highspeed) {
7967                 struct ccb_trans_settings_mmc *cts;
7968                 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7969                 ccb->ccb_h.flags = 0;
7970                 cts = &ccb->cts.proto_specific.mmc;
7971                 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7972                 cts->ios_valid = MMC_BT;
7973                 if (((retval = cam_send_ccb(device, ccb)) < 0)
7974                     || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7975                         warn("Error sending command");
7976                 } else {
7977                         printf("Speed set OK (HS: %d)\n", is_highspeed);
7978                 }
7979                 cam_freeccb(ccb);
7980                 return (retval);
7981         }
7982
7983         // Get information about controller and its settings
7984         if (is_info_request) {
7985                 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
7986                 ccb->ccb_h.flags = 0;
7987                 struct ccb_trans_settings_mmc *cts;
7988                 cts = &ccb->cts.proto_specific.mmc;
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                         return (retval);
7993                 }
7994                 printf("Host controller information\n");
7995                 printf("Host OCR: 0x%x\n", cts->host_ocr);
7996                 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
7997                 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
7998                 printf("Supported bus width: ");
7999                 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8000                         printf(" 4 bit\n");
8001                 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8002                         printf(" 8 bit\n");
8003                 printf("\nCurrent settings:\n");
8004                 printf("Bus width: ");
8005                 switch (cts->ios.bus_width) {
8006                 case bus_width_1:
8007                         printf("1 bit\n");
8008                         break;
8009                 case bus_width_4:
8010                         printf("4 bit\n");
8011                         break;
8012                 case bus_width_8:
8013                         printf("8 bit\n");
8014                         break;
8015                 }
8016                 printf("Freq: %d.%03d MHz%s\n",
8017                        cts->ios.clock / 1000000,
8018                        (cts->ios.clock / 1000) % 1000,
8019                        cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8020                 return (0);
8021         }
8022
8023         printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8024
8025         if (mmc_data_len > 0) {
8026                 flags |= CAM_DIR_IN;
8027                 mmc_data = malloc(mmc_data_len);
8028                 memset(mmc_data, 0, mmc_data_len);
8029                 memset(&mmc_d, 0, sizeof(mmc_d));
8030                 mmc_d.len = mmc_data_len;
8031                 mmc_d.data = mmc_data;
8032                 mmc_d.flags = MMC_DATA_READ;
8033         } else flags |= CAM_DIR_NONE;
8034
8035         cam_fill_mmcio(&ccb->mmcio,
8036                        /*retries*/ retry_count,
8037                        /*cbfcnp*/ NULL,
8038                        /*flags*/ flags,
8039                        /*mmc_opcode*/ mmc_opcode,
8040                        /*mmc_arg*/ mmc_arg,
8041                        /*mmc_flags*/ mmc_flags,
8042                        /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8043                        /*timeout*/ timeout ? timeout : 5000);
8044
8045         if (((retval = cam_send_ccb(device, ccb)) < 0)
8046          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8047                 const char warnstr[] = "error sending command";
8048
8049                 if (retval < 0)
8050                         warn(warnstr);
8051                 else
8052                         warnx(warnstr);
8053
8054                 if (arglist & CAM_ARG_VERBOSE) {
8055                         cam_error_print(device, ccb, CAM_ESF_ALL,
8056                                         CAM_EPF_ALL, stderr);
8057                 }
8058         }
8059
8060         if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8061                 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8062                        ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8063                        ccb->mmcio.cmd.resp[1],
8064                        ccb->mmcio.cmd.resp[2],
8065                        ccb->mmcio.cmd.resp[3]);
8066
8067                 switch (mmc_opcode) {
8068                 case SD_IO_RW_DIRECT:
8069                         printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8070                                SD_R5_DATA(ccb->mmcio.cmd.resp),
8071                                (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8072                         break;
8073                 case SD_IO_RW_EXTENDED:
8074                         printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8075                         hexdump(mmc_data, mmc_data_len, NULL, 0);
8076                         break;
8077                 case SD_SEND_RELATIVE_ADDR:
8078                         printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8079                         break;
8080                 default:
8081                         printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8082                 }
8083         }
8084 mmccmd_bailout:
8085         if (ccb != NULL)
8086                 cam_freeccb(ccb);
8087
8088         if (mmc_data_len > 0 && mmc_data != NULL)
8089                 free(mmc_data);
8090
8091         return (error);
8092 }
8093
8094 static int
8095 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8096                  char *combinedopt, int retry_count, int timeout)
8097 {
8098         union ccb *ccb;
8099         struct smp_report_general_request *request = NULL;
8100         struct smp_report_general_response *response = NULL;
8101         struct sbuf *sb = NULL;
8102         int error = 0;
8103         int c, long_response = 0;
8104         int retval;
8105
8106         /*
8107          * Note that at the moment we don't support sending SMP CCBs to
8108          * devices that aren't probed by CAM.
8109          */
8110         ccb = cam_getccb(device);
8111         if (ccb == NULL) {
8112                 warnx("%s: error allocating CCB", __func__);
8113                 return (1);
8114         }
8115
8116         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8117
8118         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8119                 switch (c) {
8120                 case 'l':
8121                         long_response = 1;
8122                         break;
8123                 default:
8124                         break;
8125                 }
8126         }
8127         request = malloc(sizeof(*request));
8128         if (request == NULL) {
8129                 warn("%s: unable to allocate %zd bytes", __func__,
8130                      sizeof(*request));
8131                 error = 1;
8132                 goto bailout;
8133         }
8134
8135         response = malloc(sizeof(*response));
8136         if (response == NULL) {
8137                 warn("%s: unable to allocate %zd bytes", __func__,
8138                      sizeof(*response));
8139                 error = 1;
8140                 goto bailout;
8141         }
8142
8143 try_long:
8144         smp_report_general(&ccb->smpio,
8145                            retry_count,
8146                            /*cbfcnp*/ NULL,
8147                            request,
8148                            /*request_len*/ sizeof(*request),
8149                            (uint8_t *)response,
8150                            /*response_len*/ sizeof(*response),
8151                            /*long_response*/ long_response,
8152                            timeout);
8153
8154         if (((retval = cam_send_ccb(device, ccb)) < 0)
8155          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8156                 const char warnstr[] = "error sending command";
8157
8158                 if (retval < 0)
8159                         warn(warnstr);
8160                 else
8161                         warnx(warnstr);
8162
8163                 if (arglist & CAM_ARG_VERBOSE) {
8164                         cam_error_print(device, ccb, CAM_ESF_ALL,
8165                                         CAM_EPF_ALL, stderr);
8166                 }
8167                 error = 1;
8168                 goto bailout;
8169         }
8170
8171         /*
8172          * If the device supports the long response bit, try again and see
8173          * if we can get all of the data.
8174          */
8175         if ((response->long_response & SMP_RG_LONG_RESPONSE)
8176          && (long_response == 0)) {
8177                 ccb->ccb_h.status = CAM_REQ_INPROG;
8178                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8179                 long_response = 1;
8180                 goto try_long;
8181         }
8182
8183         /*
8184          * XXX KDM detect and decode SMP errors here.
8185          */
8186         sb = sbuf_new_auto();
8187         if (sb == NULL) {
8188                 warnx("%s: error allocating sbuf", __func__);
8189                 goto bailout;
8190         }
8191
8192         smp_report_general_sbuf(response, sizeof(*response), sb);
8193
8194         if (sbuf_finish(sb) != 0) {
8195                 warnx("%s: sbuf_finish", __func__);
8196                 goto bailout;
8197         }
8198
8199         printf("%s", sbuf_data(sb));
8200
8201 bailout:
8202         if (ccb != NULL)
8203                 cam_freeccb(ccb);
8204
8205         if (request != NULL)
8206                 free(request);
8207
8208         if (response != NULL)
8209                 free(response);
8210
8211         if (sb != NULL)
8212                 sbuf_delete(sb);
8213
8214         return (error);
8215 }
8216
8217 static struct camcontrol_opts phy_ops[] = {
8218         {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8219         {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8220         {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8221         {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8222         {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8223         {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8224         {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8225         {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8226         {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8227         {NULL, 0, 0, NULL}
8228 };
8229
8230 static int
8231 smpphycontrol(struct cam_device *device, int argc, char **argv,
8232               char *combinedopt, int retry_count, int timeout)
8233 {
8234         union ccb *ccb;
8235         struct smp_phy_control_request *request = NULL;
8236         struct smp_phy_control_response *response = NULL;
8237         int long_response = 0;
8238         int retval = 0;
8239         int phy = -1;
8240         uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8241         int phy_op_set = 0;
8242         uint64_t attached_dev_name = 0;
8243         int dev_name_set = 0;
8244         uint32_t min_plr = 0, max_plr = 0;
8245         uint32_t pp_timeout_val = 0;
8246         int slumber_partial = 0;
8247         int set_pp_timeout_val = 0;
8248         int c;
8249
8250         /*
8251          * Note that at the moment we don't support sending SMP CCBs to
8252          * devices that aren't probed by CAM.
8253          */
8254         ccb = cam_getccb(device);
8255         if (ccb == NULL) {
8256                 warnx("%s: error allocating CCB", __func__);
8257                 return (1);
8258         }
8259
8260         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8261
8262         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8263                 switch (c) {
8264                 case 'a':
8265                 case 'A':
8266                 case 's':
8267                 case 'S': {
8268                         int enable = -1;
8269
8270                         if (strcasecmp(optarg, "enable") == 0)
8271                                 enable = 1;
8272                         else if (strcasecmp(optarg, "disable") == 0)
8273                                 enable = 2;
8274                         else {
8275                                 warnx("%s: Invalid argument %s", __func__,
8276                                       optarg);
8277                                 retval = 1;
8278                                 goto bailout;
8279                         }
8280                         switch (c) {
8281                         case 's':
8282                                 slumber_partial |= enable <<
8283                                                    SMP_PC_SAS_SLUMBER_SHIFT;
8284                                 break;
8285                         case 'S':
8286                                 slumber_partial |= enable <<
8287                                                    SMP_PC_SAS_PARTIAL_SHIFT;
8288                                 break;
8289                         case 'a':
8290                                 slumber_partial |= enable <<
8291                                                    SMP_PC_SATA_SLUMBER_SHIFT;
8292                                 break;
8293                         case 'A':
8294                                 slumber_partial |= enable <<
8295                                                    SMP_PC_SATA_PARTIAL_SHIFT;
8296                                 break;
8297                         default:
8298                                 warnx("%s: programmer error", __func__);
8299                                 retval = 1;
8300                                 goto bailout;
8301                                 break; /*NOTREACHED*/
8302                         }
8303                         break;
8304                 }
8305                 case 'd':
8306                         attached_dev_name = (uintmax_t)strtoumax(optarg,
8307                                                                  NULL,0);
8308                         dev_name_set = 1;
8309                         break;
8310                 case 'l':
8311                         long_response = 1;
8312                         break;
8313                 case 'm':
8314                         /*
8315                          * We don't do extensive checking here, so this
8316                          * will continue to work when new speeds come out.
8317                          */
8318                         min_plr = strtoul(optarg, NULL, 0);
8319                         if ((min_plr == 0)
8320                          || (min_plr > 0xf)) {
8321                                 warnx("%s: invalid link rate %x",
8322                                       __func__, min_plr);
8323                                 retval = 1;
8324                                 goto bailout;
8325                         }
8326                         break;
8327                 case 'M':
8328                         /*
8329                          * We don't do extensive checking here, so this
8330                          * will continue to work when new speeds come out.
8331                          */
8332                         max_plr = strtoul(optarg, NULL, 0);
8333                         if ((max_plr == 0)
8334                          || (max_plr > 0xf)) {
8335                                 warnx("%s: invalid link rate %x",
8336                                       __func__, max_plr);
8337                                 retval = 1;
8338                                 goto bailout;
8339                         }
8340                         break;
8341                 case 'o': {
8342                         camcontrol_optret optreturn;
8343                         cam_argmask argnums;
8344                         const char *subopt;
8345
8346                         if (phy_op_set != 0) {
8347                                 warnx("%s: only one phy operation argument "
8348                                       "(-o) allowed", __func__);
8349                                 retval = 1;
8350                                 goto bailout;
8351                         }
8352
8353                         phy_op_set = 1;
8354
8355                         /*
8356                          * Allow the user to specify the phy operation
8357                          * numerically, as well as with a name.  This will
8358                          * future-proof it a bit, so options that are added
8359                          * in future specs can be used.
8360                          */
8361                         if (isdigit(optarg[0])) {
8362                                 phy_operation = strtoul(optarg, NULL, 0);
8363                                 if ((phy_operation == 0)
8364                                  || (phy_operation > 0xff)) {
8365                                         warnx("%s: invalid phy operation %#x",
8366                                               __func__, phy_operation);
8367                                         retval = 1;
8368                                         goto bailout;
8369                                 }
8370                                 break;
8371                         }
8372                         optreturn = getoption(phy_ops, optarg, &phy_operation,
8373                                               &argnums, &subopt);
8374
8375                         if (optreturn == CC_OR_AMBIGUOUS) {
8376                                 warnx("%s: ambiguous option %s", __func__,
8377                                       optarg);
8378                                 usage(0);
8379                                 retval = 1;
8380                                 goto bailout;
8381                         } else if (optreturn == CC_OR_NOT_FOUND) {
8382                                 warnx("%s: option %s not found", __func__,
8383                                       optarg);
8384                                 usage(0);
8385                                 retval = 1;
8386                                 goto bailout;
8387                         }
8388                         break;
8389                 }
8390                 case 'p':
8391                         phy = atoi(optarg);
8392                         break;
8393                 case 'T':
8394                         pp_timeout_val = strtoul(optarg, NULL, 0);
8395                         if (pp_timeout_val > 15) {
8396                                 warnx("%s: invalid partial pathway timeout "
8397                                       "value %u, need a value less than 16",
8398                                       __func__, pp_timeout_val);
8399                                 retval = 1;
8400                                 goto bailout;
8401                         }
8402                         set_pp_timeout_val = 1;
8403                         break;
8404                 default:
8405                         break;
8406                 }
8407         }
8408
8409         if (phy == -1) {
8410                 warnx("%s: a PHY (-p phy) argument is required",__func__);
8411                 retval = 1;
8412                 goto bailout;
8413         }
8414
8415         if (((dev_name_set != 0)
8416           && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8417          || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8418           && (dev_name_set == 0))) {
8419                 warnx("%s: -d name and -o setdevname arguments both "
8420                       "required to set device name", __func__);
8421                 retval = 1;
8422                 goto bailout;
8423         }
8424
8425         request = malloc(sizeof(*request));
8426         if (request == NULL) {
8427                 warn("%s: unable to allocate %zd bytes", __func__,
8428                      sizeof(*request));
8429                 retval = 1;
8430                 goto bailout;
8431         }
8432
8433         response = malloc(sizeof(*response));
8434         if (response == NULL) {
8435                 warn("%s: unable to allocate %zd bytes", __func__,
8436                      sizeof(*response));
8437                 retval = 1;
8438                 goto bailout;
8439         }
8440
8441         smp_phy_control(&ccb->smpio,
8442                         retry_count,
8443                         /*cbfcnp*/ NULL,
8444                         request,
8445                         sizeof(*request),
8446                         (uint8_t *)response,
8447                         sizeof(*response),
8448                         long_response,
8449                         /*expected_exp_change_count*/ 0,
8450                         phy,
8451                         phy_operation,
8452                         (set_pp_timeout_val != 0) ? 1 : 0,
8453                         attached_dev_name,
8454                         min_plr,
8455                         max_plr,
8456                         slumber_partial,
8457                         pp_timeout_val,
8458                         timeout);
8459
8460         if (((retval = cam_send_ccb(device, ccb)) < 0)
8461          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8462                 const char warnstr[] = "error sending command";
8463
8464                 if (retval < 0)
8465                         warn(warnstr);
8466                 else
8467                         warnx(warnstr);
8468
8469                 if (arglist & CAM_ARG_VERBOSE) {
8470                         /*
8471                          * Use CAM_EPF_NORMAL so we only get one line of
8472                          * SMP command decoding.
8473                          */
8474                         cam_error_print(device, ccb, CAM_ESF_ALL,
8475                                         CAM_EPF_NORMAL, stderr);
8476                 }
8477                 retval = 1;
8478                 goto bailout;
8479         }
8480
8481         /* XXX KDM print out something here for success? */
8482 bailout:
8483         if (ccb != NULL)
8484                 cam_freeccb(ccb);
8485
8486         if (request != NULL)
8487                 free(request);
8488
8489         if (response != NULL)
8490                 free(response);
8491
8492         return (retval);
8493 }
8494
8495 static int
8496 smpmaninfo(struct cam_device *device, int argc, char **argv,
8497            char *combinedopt, int retry_count, int timeout)
8498 {
8499         union ccb *ccb;
8500         struct smp_report_manuf_info_request request;
8501         struct smp_report_manuf_info_response response;
8502         struct sbuf *sb = NULL;
8503         int long_response = 0;
8504         int retval = 0;
8505         int c;
8506
8507         /*
8508          * Note that at the moment we don't support sending SMP CCBs to
8509          * devices that aren't probed by CAM.
8510          */
8511         ccb = cam_getccb(device);
8512         if (ccb == NULL) {
8513                 warnx("%s: error allocating CCB", __func__);
8514                 return (1);
8515         }
8516
8517         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8518
8519         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8520                 switch (c) {
8521                 case 'l':
8522                         long_response = 1;
8523                         break;
8524                 default:
8525                         break;
8526                 }
8527         }
8528         bzero(&request, sizeof(request));
8529         bzero(&response, sizeof(response));
8530
8531         smp_report_manuf_info(&ccb->smpio,
8532                               retry_count,
8533                               /*cbfcnp*/ NULL,
8534                               &request,
8535                               sizeof(request),
8536                               (uint8_t *)&response,
8537                               sizeof(response),
8538                               long_response,
8539                               timeout);
8540
8541         if (((retval = cam_send_ccb(device, ccb)) < 0)
8542          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8543                 const char warnstr[] = "error sending command";
8544
8545                 if (retval < 0)
8546                         warn(warnstr);
8547                 else
8548                         warnx(warnstr);
8549
8550                 if (arglist & CAM_ARG_VERBOSE) {
8551                         cam_error_print(device, ccb, CAM_ESF_ALL,
8552                                         CAM_EPF_ALL, stderr);
8553                 }
8554                 retval = 1;
8555                 goto bailout;
8556         }
8557
8558         sb = sbuf_new_auto();
8559         if (sb == NULL) {
8560                 warnx("%s: error allocating sbuf", __func__);
8561                 goto bailout;
8562         }
8563
8564         smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8565
8566         if (sbuf_finish(sb) != 0) {
8567                 warnx("%s: sbuf_finish", __func__);
8568                 goto bailout;
8569         }
8570
8571         printf("%s", sbuf_data(sb));
8572
8573 bailout:
8574
8575         if (ccb != NULL)
8576                 cam_freeccb(ccb);
8577
8578         if (sb != NULL)
8579                 sbuf_delete(sb);
8580
8581         return (retval);
8582 }
8583
8584 static int
8585 getdevid(struct cam_devitem *item)
8586 {
8587         int retval = 0;
8588         union ccb *ccb = NULL;
8589
8590         struct cam_device *dev;
8591
8592         dev = cam_open_btl(item->dev_match.path_id,
8593                            item->dev_match.target_id,
8594                            item->dev_match.target_lun, O_RDWR, NULL);
8595
8596         if (dev == NULL) {
8597                 warnx("%s", cam_errbuf);
8598                 retval = 1;
8599                 goto bailout;
8600         }
8601
8602         item->device_id_len = 0;
8603
8604         ccb = cam_getccb(dev);
8605         if (ccb == NULL) {
8606                 warnx("%s: error allocating CCB", __func__);
8607                 retval = 1;
8608                 goto bailout;
8609         }
8610
8611         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8612
8613         /*
8614          * On the first try, we just probe for the size of the data, and
8615          * then allocate that much memory and try again.
8616          */
8617 retry:
8618         ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8619         ccb->ccb_h.flags = CAM_DIR_IN;
8620         ccb->cdai.flags = CDAI_FLAG_NONE;
8621         ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8622         ccb->cdai.bufsiz = item->device_id_len;
8623         if (item->device_id_len != 0)
8624                 ccb->cdai.buf = (uint8_t *)item->device_id;
8625
8626         if (cam_send_ccb(dev, ccb) < 0) {
8627                 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8628                 retval = 1;
8629                 goto bailout;
8630         }
8631
8632         if (ccb->ccb_h.status != CAM_REQ_CMP) {
8633                 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8634                 retval = 1;
8635                 goto bailout;
8636         }
8637
8638         if (item->device_id_len == 0) {
8639                 /*
8640                  * This is our first time through.  Allocate the buffer,
8641                  * and then go back to get the data.
8642                  */
8643                 if (ccb->cdai.provsiz == 0) {
8644                         warnx("%s: invalid .provsiz field returned with "
8645                              "XPT_GDEV_ADVINFO CCB", __func__);
8646                         retval = 1;
8647                         goto bailout;
8648                 }
8649                 item->device_id_len = ccb->cdai.provsiz;
8650                 item->device_id = malloc(item->device_id_len);
8651                 if (item->device_id == NULL) {
8652                         warn("%s: unable to allocate %d bytes", __func__,
8653                              item->device_id_len);
8654                         retval = 1;
8655                         goto bailout;
8656                 }
8657                 ccb->ccb_h.status = CAM_REQ_INPROG;
8658                 goto retry;
8659         }
8660
8661 bailout:
8662         if (dev != NULL)
8663                 cam_close_device(dev);
8664
8665         if (ccb != NULL)
8666                 cam_freeccb(ccb);
8667
8668         return (retval);
8669 }
8670
8671 /*
8672  * XXX KDM merge this code with getdevtree()?
8673  */
8674 static int
8675 buildbusdevlist(struct cam_devlist *devlist)
8676 {
8677         union ccb ccb;
8678         int bufsize, fd = -1;
8679         struct dev_match_pattern *patterns;
8680         struct cam_devitem *item = NULL;
8681         int skip_device = 0;
8682         int retval = 0;
8683
8684         if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8685                 warn("couldn't open %s", XPT_DEVICE);
8686                 return (1);
8687         }
8688
8689         bzero(&ccb, sizeof(union ccb));
8690
8691         ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8692         ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8693         ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8694
8695         ccb.ccb_h.func_code = XPT_DEV_MATCH;
8696         bufsize = sizeof(struct dev_match_result) * 100;
8697         ccb.cdm.match_buf_len = bufsize;
8698         ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8699         if (ccb.cdm.matches == NULL) {
8700                 warnx("can't malloc memory for matches");
8701                 close(fd);
8702                 return (1);
8703         }
8704         ccb.cdm.num_matches = 0;
8705         ccb.cdm.num_patterns = 2;
8706         ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8707                 ccb.cdm.num_patterns;
8708
8709         patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8710         if (patterns == NULL) {
8711                 warnx("can't malloc memory for patterns");
8712                 retval = 1;
8713                 goto bailout;
8714         }
8715
8716         ccb.cdm.patterns = patterns;
8717         bzero(patterns, ccb.cdm.pattern_buf_len);
8718
8719         patterns[0].type = DEV_MATCH_DEVICE;
8720         patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8721         patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8722         patterns[1].type = DEV_MATCH_PERIPH;
8723         patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8724         patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8725
8726         /*
8727          * We do the ioctl multiple times if necessary, in case there are
8728          * more than 100 nodes in the EDT.
8729          */
8730         do {
8731                 unsigned int i;
8732
8733                 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8734                         warn("error sending CAMIOCOMMAND ioctl");
8735                         retval = 1;
8736                         goto bailout;
8737                 }
8738
8739                 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8740                  || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8741                     && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8742                         warnx("got CAM error %#x, CDM error %d\n",
8743                               ccb.ccb_h.status, ccb.cdm.status);
8744                         retval = 1;
8745                         goto bailout;
8746                 }
8747
8748                 for (i = 0; i < ccb.cdm.num_matches; i++) {
8749                         switch (ccb.cdm.matches[i].type) {
8750                         case DEV_MATCH_DEVICE: {
8751                                 struct device_match_result *dev_result;
8752
8753                                 dev_result =
8754                                      &ccb.cdm.matches[i].result.device_result;
8755
8756                                 if (dev_result->flags &
8757                                     DEV_RESULT_UNCONFIGURED) {
8758                                         skip_device = 1;
8759                                         break;
8760                                 } else
8761                                         skip_device = 0;
8762
8763                                 item = malloc(sizeof(*item));
8764                                 if (item == NULL) {
8765                                         warn("%s: unable to allocate %zd bytes",
8766                                              __func__, sizeof(*item));
8767                                         retval = 1;
8768                                         goto bailout;
8769                                 }
8770                                 bzero(item, sizeof(*item));
8771                                 bcopy(dev_result, &item->dev_match,
8772                                       sizeof(*dev_result));
8773                                 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8774                                                    links);
8775
8776                                 if (getdevid(item) != 0) {
8777                                         retval = 1;
8778                                         goto bailout;
8779                                 }
8780                                 break;
8781                         }
8782                         case DEV_MATCH_PERIPH: {
8783                                 struct periph_match_result *periph_result;
8784
8785                                 periph_result =
8786                                       &ccb.cdm.matches[i].result.periph_result;
8787
8788                                 if (skip_device != 0)
8789                                         break;
8790                                 item->num_periphs++;
8791                                 item->periph_matches = realloc(
8792                                         item->periph_matches,
8793                                         item->num_periphs *
8794                                         sizeof(struct periph_match_result));
8795                                 if (item->periph_matches == NULL) {
8796                                         warn("%s: error allocating periph "
8797                                              "list", __func__);
8798                                         retval = 1;
8799                                         goto bailout;
8800                                 }
8801                                 bcopy(periph_result, &item->periph_matches[
8802                                       item->num_periphs - 1],
8803                                       sizeof(*periph_result));
8804                                 break;
8805                         }
8806                         default:
8807                                 fprintf(stderr, "%s: unexpected match "
8808                                         "type %d\n", __func__,
8809                                         ccb.cdm.matches[i].type);
8810                                 retval = 1;
8811                                 goto bailout;
8812                                 break; /*NOTREACHED*/
8813                         }
8814                 }
8815         } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8816                 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8817 bailout:
8818
8819         if (fd != -1)
8820                 close(fd);
8821
8822         free(patterns);
8823
8824         free(ccb.cdm.matches);
8825
8826         if (retval != 0)
8827                 freebusdevlist(devlist);
8828
8829         return (retval);
8830 }
8831
8832 static void
8833 freebusdevlist(struct cam_devlist *devlist)
8834 {
8835         struct cam_devitem *item, *item2;
8836
8837         STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8838                 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8839                               links);
8840                 free(item->device_id);
8841                 free(item->periph_matches);
8842                 free(item);
8843         }
8844 }
8845
8846 static struct cam_devitem *
8847 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8848 {
8849         struct cam_devitem *item;
8850
8851         STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8852                 struct scsi_vpd_id_descriptor *idd;
8853
8854                 /*
8855                  * XXX KDM look for LUN IDs as well?
8856                  */
8857                 idd = scsi_get_devid(item->device_id,
8858                                            item->device_id_len,
8859                                            scsi_devid_is_sas_target);
8860                 if (idd == NULL)
8861                         continue;
8862
8863                 if (scsi_8btou64(idd->identifier) == sasaddr)
8864                         return (item);
8865         }
8866
8867         return (NULL);
8868 }
8869
8870 static int
8871 smpphylist(struct cam_device *device, int argc, char **argv,
8872            char *combinedopt, int retry_count, int timeout)
8873 {
8874         struct smp_report_general_request *rgrequest = NULL;
8875         struct smp_report_general_response *rgresponse = NULL;
8876         struct smp_discover_request *disrequest = NULL;
8877         struct smp_discover_response *disresponse = NULL;
8878         struct cam_devlist devlist;
8879         union ccb *ccb;
8880         int long_response = 0;
8881         int num_phys = 0;
8882         int quiet = 0;
8883         int retval;
8884         int i, c;
8885
8886         /*
8887          * Note that at the moment we don't support sending SMP CCBs to
8888          * devices that aren't probed by CAM.
8889          */
8890         ccb = cam_getccb(device);
8891         if (ccb == NULL) {
8892                 warnx("%s: error allocating CCB", __func__);
8893                 return (1);
8894         }
8895
8896         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8897         STAILQ_INIT(&devlist.dev_queue);
8898
8899         rgrequest = malloc(sizeof(*rgrequest));
8900         if (rgrequest == NULL) {
8901                 warn("%s: unable to allocate %zd bytes", __func__,
8902                      sizeof(*rgrequest));
8903                 retval = 1;
8904                 goto bailout;
8905         }
8906
8907         rgresponse = malloc(sizeof(*rgresponse));
8908         if (rgresponse == NULL) {
8909                 warn("%s: unable to allocate %zd bytes", __func__,
8910                      sizeof(*rgresponse));
8911                 retval = 1;
8912                 goto bailout;
8913         }
8914
8915         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8916                 switch (c) {
8917                 case 'l':
8918                         long_response = 1;
8919                         break;
8920                 case 'q':
8921                         quiet = 1;
8922                         break;
8923                 default:
8924                         break;
8925                 }
8926         }
8927
8928         smp_report_general(&ccb->smpio,
8929                            retry_count,
8930                            /*cbfcnp*/ NULL,
8931                            rgrequest,
8932                            /*request_len*/ sizeof(*rgrequest),
8933                            (uint8_t *)rgresponse,
8934                            /*response_len*/ sizeof(*rgresponse),
8935                            /*long_response*/ long_response,
8936                            timeout);
8937
8938         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8939
8940         if (((retval = cam_send_ccb(device, ccb)) < 0)
8941          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8942                 const char warnstr[] = "error sending command";
8943
8944                 if (retval < 0)
8945                         warn(warnstr);
8946                 else
8947                         warnx(warnstr);
8948
8949                 if (arglist & CAM_ARG_VERBOSE) {
8950                         cam_error_print(device, ccb, CAM_ESF_ALL,
8951                                         CAM_EPF_ALL, stderr);
8952                 }
8953                 retval = 1;
8954                 goto bailout;
8955         }
8956
8957         num_phys = rgresponse->num_phys;
8958
8959         if (num_phys == 0) {
8960                 if (quiet == 0)
8961                         fprintf(stdout, "%s: No Phys reported\n", __func__);
8962                 retval = 1;
8963                 goto bailout;
8964         }
8965
8966         devlist.path_id = device->path_id;
8967
8968         retval = buildbusdevlist(&devlist);
8969         if (retval != 0)
8970                 goto bailout;
8971
8972         if (quiet == 0) {
8973                 fprintf(stdout, "%d PHYs:\n", num_phys);
8974                 fprintf(stdout, "PHY  Attached SAS Address\n");
8975         }
8976
8977         disrequest = malloc(sizeof(*disrequest));
8978         if (disrequest == NULL) {
8979                 warn("%s: unable to allocate %zd bytes", __func__,
8980                      sizeof(*disrequest));
8981                 retval = 1;
8982                 goto bailout;
8983         }
8984
8985         disresponse = malloc(sizeof(*disresponse));
8986         if (disresponse == NULL) {
8987                 warn("%s: unable to allocate %zd bytes", __func__,
8988                      sizeof(*disresponse));
8989                 retval = 1;
8990                 goto bailout;
8991         }
8992
8993         for (i = 0; i < num_phys; i++) {
8994                 struct cam_devitem *item;
8995                 struct device_match_result *dev_match;
8996                 char vendor[16], product[48], revision[16];
8997                 char tmpstr[256];
8998                 int j;
8999
9000                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9001
9002                 ccb->ccb_h.status = CAM_REQ_INPROG;
9003                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9004
9005                 smp_discover(&ccb->smpio,
9006                              retry_count,
9007                              /*cbfcnp*/ NULL,
9008                              disrequest,
9009                              sizeof(*disrequest),
9010                              (uint8_t *)disresponse,
9011                              sizeof(*disresponse),
9012                              long_response,
9013                              /*ignore_zone_group*/ 0,
9014                              /*phy*/ i,
9015                              timeout);
9016
9017                 if (((retval = cam_send_ccb(device, ccb)) < 0)
9018                  || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9019                   && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9020                         const char warnstr[] = "error sending command";
9021
9022                         if (retval < 0)
9023                                 warn(warnstr);
9024                         else
9025                                 warnx(warnstr);
9026
9027                         if (arglist & CAM_ARG_VERBOSE) {
9028                                 cam_error_print(device, ccb, CAM_ESF_ALL,
9029                                                 CAM_EPF_ALL, stderr);
9030                         }
9031                         retval = 1;
9032                         goto bailout;
9033                 }
9034
9035                 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9036                         if (quiet == 0)
9037                                 fprintf(stdout, "%3d  <vacant>\n", i);
9038                         continue;
9039                 }
9040
9041                 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9042                         item = NULL;
9043                 } else {
9044                         item = findsasdevice(&devlist,
9045                             scsi_8btou64(disresponse->attached_sas_address));
9046                 }
9047
9048                 if ((quiet == 0)
9049                  || (item != NULL)) {
9050                         fprintf(stdout, "%3d  0x%016jx", i,
9051                                 (uintmax_t)scsi_8btou64(
9052                                 disresponse->attached_sas_address));
9053                         if (item == NULL) {
9054                                 fprintf(stdout, "\n");
9055                                 continue;
9056                         }
9057                 } else if (quiet != 0)
9058                         continue;
9059
9060                 dev_match = &item->dev_match;
9061
9062                 if (dev_match->protocol == PROTO_SCSI) {
9063                         cam_strvis(vendor, dev_match->inq_data.vendor,
9064                                    sizeof(dev_match->inq_data.vendor),
9065                                    sizeof(vendor));
9066                         cam_strvis(product, dev_match->inq_data.product,
9067                                    sizeof(dev_match->inq_data.product),
9068                                    sizeof(product));
9069                         cam_strvis(revision, dev_match->inq_data.revision,
9070                                    sizeof(dev_match->inq_data.revision),
9071                                    sizeof(revision));
9072                         sprintf(tmpstr, "<%s %s %s>", vendor, product,
9073                                 revision);
9074                 } else if ((dev_match->protocol == PROTO_ATA)
9075                         || (dev_match->protocol == PROTO_SATAPM)) {
9076                         cam_strvis(product, dev_match->ident_data.model,
9077                                    sizeof(dev_match->ident_data.model),
9078                                    sizeof(product));
9079                         cam_strvis(revision, dev_match->ident_data.revision,
9080                                    sizeof(dev_match->ident_data.revision),
9081                                    sizeof(revision));
9082                         sprintf(tmpstr, "<%s %s>", product, revision);
9083                 } else {
9084                         sprintf(tmpstr, "<>");
9085                 }
9086                 fprintf(stdout, "   %-33s ", tmpstr);
9087
9088                 /*
9089                  * If we have 0 periphs, that's a bug...
9090                  */
9091                 if (item->num_periphs == 0) {
9092                         fprintf(stdout, "\n");
9093                         continue;
9094                 }
9095
9096                 fprintf(stdout, "(");
9097                 for (j = 0; j < item->num_periphs; j++) {
9098                         if (j > 0)
9099                                 fprintf(stdout, ",");
9100
9101                         fprintf(stdout, "%s%d",
9102                                 item->periph_matches[j].periph_name,
9103                                 item->periph_matches[j].unit_number);
9104
9105                 }
9106                 fprintf(stdout, ")\n");
9107         }
9108 bailout:
9109         if (ccb != NULL)
9110                 cam_freeccb(ccb);
9111
9112         free(rgrequest);
9113
9114         free(rgresponse);
9115
9116         free(disrequest);
9117
9118         free(disresponse);
9119
9120         freebusdevlist(&devlist);
9121
9122         return (retval);
9123 }
9124
9125 static int
9126 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9127 {
9128         uint8_t error = 0, ata_device = 0, status = 0;
9129         uint16_t count = 0;
9130         uint64_t lba = 0;
9131         int retval;
9132
9133         retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9134             &status);
9135         if (retval == 1) {
9136                 if (arglist & CAM_ARG_VERBOSE) {
9137                         cam_error_print(device, ccb, CAM_ESF_ALL,
9138                                         CAM_EPF_ALL, stderr);
9139                 }
9140                 warnx("Can't get ATA command status");
9141                 return (retval);
9142         }
9143
9144         if (status & ATA_STATUS_ERROR) {
9145                 cam_error_print(device, ccb, CAM_ESF_ALL,
9146                     CAM_EPF_ALL, stderr);
9147                 return (1);
9148         }
9149
9150         printf("%s%d: ", device->device_name, device->dev_unit_num);
9151         switch (count) {
9152         case 0x00:
9153                 printf("Standby mode\n");
9154                 break;
9155         case 0x01:
9156                 printf("Standby_y mode\n");
9157                 break;
9158         case 0x40:
9159                 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9160                 break;
9161         case 0x41:
9162                 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9163                 break;
9164         case 0x80:
9165                 printf("Idle mode\n");
9166                 break;
9167         case 0x81:
9168                 printf("Idle_a mode\n");
9169                 break;
9170         case 0x82:
9171                 printf("Idle_b mode\n");
9172                 break;
9173         case 0x83:
9174                 printf("Idle_c mode\n");
9175                 break;
9176         case 0xff:
9177                 printf("Active or Idle mode\n");
9178                 break;
9179         default:
9180                 printf("Unknown mode 0x%02x\n", count);
9181                 break;
9182         }
9183
9184         return (0);
9185 }
9186
9187 static int
9188 atapm(struct cam_device *device, int argc, char **argv,
9189                  char *combinedopt, int retry_count, int timeout)
9190 {
9191         union ccb *ccb;
9192         int retval = 0;
9193         int t = -1;
9194         int c;
9195         u_int8_t ata_flags = 0;
9196         u_char cmd, sc;
9197
9198         ccb = cam_getccb(device);
9199
9200         if (ccb == NULL) {
9201                 warnx("%s: error allocating ccb", __func__);
9202                 return (1);
9203         }
9204
9205         while ((c = getopt(argc, argv, combinedopt)) != -1) {
9206                 switch (c) {
9207                 case 't':
9208                         t = atoi(optarg);
9209                         break;
9210                 default:
9211                         break;
9212                 }
9213         }
9214         if (strcmp(argv[1], "idle") == 0) {
9215                 if (t == -1)
9216                         cmd = ATA_IDLE_IMMEDIATE;
9217                 else
9218                         cmd = ATA_IDLE_CMD;
9219         } else if (strcmp(argv[1], "standby") == 0) {
9220                 if (t == -1)
9221                         cmd = ATA_STANDBY_IMMEDIATE;
9222                 else
9223                         cmd = ATA_STANDBY_CMD;
9224         } else if (strcmp(argv[1], "powermode") == 0) {
9225                 cmd = ATA_CHECK_POWER_MODE;
9226                 ata_flags = AP_FLAG_CHK_COND;
9227                 t = -1;
9228         } else {
9229                 cmd = ATA_SLEEP;
9230                 t = -1;
9231         }
9232
9233         if (t < 0)
9234                 sc = 0;
9235         else if (t <= (240 * 5))
9236                 sc = (t + 4) / 5;
9237         else if (t <= (252 * 5))
9238                 /* special encoding for 21 minutes */
9239                 sc = 252;
9240         else if (t <= (11 * 30 * 60))
9241                 sc = (t - 1) / (30 * 60) + 241;
9242         else
9243                 sc = 253;
9244
9245         retval = ata_do_cmd(device,
9246             ccb,
9247             /*retries*/retry_count,
9248             /*flags*/CAM_DIR_NONE,
9249             /*protocol*/AP_PROTO_NON_DATA,
9250             /*ata_flags*/ata_flags,
9251             /*tag_action*/MSG_SIMPLE_Q_TAG,
9252             /*command*/cmd,
9253             /*features*/0,
9254             /*lba*/0,
9255             /*sector_count*/sc,
9256             /*data_ptr*/NULL,
9257             /*dxfer_len*/0,
9258             /*timeout*/timeout ? timeout : 30 * 1000,
9259             /*force48bit*/0);
9260
9261         cam_freeccb(ccb);
9262
9263         if (retval || cmd != ATA_CHECK_POWER_MODE)
9264                 return (retval);
9265
9266         return (atapm_proc_resp(device, ccb));
9267 }
9268
9269 static int
9270 ataaxm(struct cam_device *device, int argc, char **argv,
9271                  char *combinedopt, int retry_count, int timeout)
9272 {
9273         union ccb *ccb;
9274         int retval = 0;
9275         int l = -1;
9276         int c;
9277         u_char cmd, sc;
9278
9279         ccb = cam_getccb(device);
9280
9281         if (ccb == NULL) {
9282                 warnx("%s: error allocating ccb", __func__);
9283                 return (1);
9284         }
9285
9286         while ((c = getopt(argc, argv, combinedopt)) != -1) {
9287                 switch (c) {
9288                 case 'l':
9289                         l = atoi(optarg);
9290                         break;
9291                 default:
9292                         break;
9293                 }
9294         }
9295         sc = 0;
9296         if (strcmp(argv[1], "apm") == 0) {
9297                 if (l == -1)
9298                         cmd = 0x85;
9299                 else {
9300                         cmd = 0x05;
9301                         sc = l;
9302                 }
9303         } else /* aam */ {
9304                 if (l == -1)
9305                         cmd = 0xC2;
9306                 else {
9307                         cmd = 0x42;
9308                         sc = l;
9309                 }
9310         }
9311
9312         retval = ata_do_cmd(device,
9313             ccb,
9314             /*retries*/retry_count,
9315             /*flags*/CAM_DIR_NONE,
9316             /*protocol*/AP_PROTO_NON_DATA,
9317             /*ata_flags*/0,
9318             /*tag_action*/MSG_SIMPLE_Q_TAG,
9319             /*command*/ATA_SETFEATURES,
9320             /*features*/cmd,
9321             /*lba*/0,
9322             /*sector_count*/sc,
9323             /*data_ptr*/NULL,
9324             /*dxfer_len*/0,
9325             /*timeout*/timeout ? timeout : 30 * 1000,
9326             /*force48bit*/0);
9327
9328         cam_freeccb(ccb);
9329         return (retval);
9330 }
9331
9332 int
9333 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9334                int show_sa_errors, int sa_set, int service_action,
9335                int timeout_desc, int task_attr, int retry_count, int timeout,
9336                int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9337 {
9338         union ccb *ccb = NULL;
9339         uint8_t *buf = NULL;
9340         uint32_t alloc_len = 0, num_opcodes;
9341         uint32_t valid_len = 0;
9342         uint32_t avail_len = 0;
9343         struct scsi_report_supported_opcodes_all *all_hdr;
9344         struct scsi_report_supported_opcodes_one *one;
9345         int options = 0;
9346         int retval = 0;
9347
9348         /*
9349          * Make it clear that we haven't yet allocated or filled anything.
9350          */
9351         *fill_len = 0;
9352         *data_ptr = NULL;
9353
9354         ccb = cam_getccb(device);
9355         if (ccb == NULL) {
9356                 warnx("couldn't allocate CCB");
9357                 retval = 1;
9358                 goto bailout;
9359         }
9360
9361         /* cam_getccb cleans up the header, caller has to zero the payload */
9362         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9363
9364         if (opcode_set != 0) {
9365                 options |= RSO_OPTIONS_OC;
9366                 num_opcodes = 1;
9367                 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9368         } else {
9369                 num_opcodes = 256;
9370                 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9371                     sizeof(struct scsi_report_supported_opcodes_descr));
9372         }
9373
9374         if (timeout_desc != 0) {
9375                 options |= RSO_RCTD;
9376                 alloc_len += num_opcodes *
9377                     sizeof(struct scsi_report_supported_opcodes_timeout);
9378         }
9379
9380         if (sa_set != 0) {
9381                 options |= RSO_OPTIONS_OC_SA;
9382                 if (show_sa_errors != 0)
9383                         options &= ~RSO_OPTIONS_OC;
9384         }
9385
9386 retry_alloc:
9387         if (buf != NULL) {
9388                 free(buf);
9389                 buf = NULL;
9390         }
9391
9392         buf = malloc(alloc_len);
9393         if (buf == NULL) {
9394                 warn("Unable to allocate %u bytes", alloc_len);
9395                 retval = 1;
9396                 goto bailout;
9397         }
9398         bzero(buf, alloc_len);
9399
9400         scsi_report_supported_opcodes(&ccb->csio,
9401                                       /*retries*/ retry_count,
9402                                       /*cbfcnp*/ NULL,
9403                                       /*tag_action*/ task_attr,
9404                                       /*options*/ options,
9405                                       /*req_opcode*/ opcode,
9406                                       /*req_service_action*/ service_action,
9407                                       /*data_ptr*/ buf,
9408                                       /*dxfer_len*/ alloc_len,
9409                                       /*sense_len*/ SSD_FULL_SIZE,
9410                                       /*timeout*/ timeout ? timeout : 10000);
9411
9412         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9413
9414         if (retry_count != 0)
9415                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9416
9417         if (cam_send_ccb(device, ccb) < 0) {
9418                 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9419                 retval = 1;
9420                 goto bailout;
9421         }
9422
9423         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9424                 if (verbosemode != 0)
9425                         cam_error_print(device, ccb, CAM_ESF_ALL,
9426                                         CAM_EPF_ALL, stderr);
9427                 retval = 1;
9428                 goto bailout;
9429         }
9430
9431         valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9432
9433         if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9434          && (valid_len >= sizeof(*all_hdr))) {
9435                 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9436                 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9437         } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9438                 && (valid_len >= sizeof(*one))) {
9439                 uint32_t cdb_length;
9440
9441                 one = (struct scsi_report_supported_opcodes_one *)buf;
9442                 cdb_length = scsi_2btoul(one->cdb_length);
9443                 avail_len = sizeof(*one) + cdb_length;
9444                 if (one->support & RSO_ONE_CTDP) {
9445                         struct scsi_report_supported_opcodes_timeout *td;
9446
9447                         td = (struct scsi_report_supported_opcodes_timeout *)
9448                             &buf[avail_len];
9449                         if (valid_len >= (avail_len + sizeof(td->length))) {
9450                                 avail_len += scsi_2btoul(td->length) +
9451                                     sizeof(td->length);
9452                         } else {
9453                                 avail_len += sizeof(*td);
9454                         }
9455                 }
9456         }
9457
9458         /*
9459          * avail_len could be zero if we didn't get enough data back from
9460          * thet target to determine
9461          */
9462         if ((avail_len != 0)
9463          && (avail_len > valid_len)) {
9464                 alloc_len = avail_len;
9465                 goto retry_alloc;
9466         }
9467
9468         *fill_len = valid_len;
9469         *data_ptr = buf;
9470 bailout:
9471         if (retval != 0)
9472                 free(buf);
9473
9474         cam_freeccb(ccb);
9475
9476         return (retval);
9477 }
9478
9479 static int
9480 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9481                    int req_sa, uint8_t *buf, uint32_t valid_len)
9482 {
9483         struct scsi_report_supported_opcodes_one *one;
9484         struct scsi_report_supported_opcodes_timeout *td;
9485         uint32_t cdb_len = 0, td_len = 0;
9486         const char *op_desc = NULL;
9487         unsigned int i;
9488         int retval = 0;
9489
9490         one = (struct scsi_report_supported_opcodes_one *)buf;
9491
9492         /*
9493          * If we don't have the full single opcode descriptor, no point in
9494          * continuing.
9495          */
9496         if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9497             cdb_length)) {
9498                 warnx("Only %u bytes returned, not enough to verify support",
9499                       valid_len);
9500                 retval = 1;
9501                 goto bailout;
9502         }
9503
9504         op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9505
9506         printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9507                req_opcode);
9508         if (sa_set != 0)
9509                 printf(", SA 0x%x", req_sa);
9510         printf(": ");
9511
9512         switch (one->support & RSO_ONE_SUP_MASK) {
9513         case RSO_ONE_SUP_UNAVAIL:
9514                 printf("No command support information currently available\n");
9515                 break;
9516         case RSO_ONE_SUP_NOT_SUP:
9517                 printf("Command not supported\n");
9518                 retval = 1;
9519                 goto bailout;
9520                 break; /*NOTREACHED*/
9521         case RSO_ONE_SUP_AVAIL:
9522                 printf("Command is supported, complies with a SCSI standard\n");
9523                 break;
9524         case RSO_ONE_SUP_VENDOR:
9525                 printf("Command is supported, vendor-specific "
9526                        "implementation\n");
9527                 break;
9528         default:
9529                 printf("Unknown command support flags 0x%#x\n",
9530                        one->support & RSO_ONE_SUP_MASK);
9531                 break;
9532         }
9533
9534         /*
9535          * If we don't have the CDB length, it isn't exactly an error, the
9536          * command probably isn't supported.
9537          */
9538         if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9539             cdb_usage))
9540                 goto bailout;
9541
9542         cdb_len = scsi_2btoul(one->cdb_length);
9543
9544         /*
9545          * If our valid data doesn't include the full reported length,
9546          * return.  The caller should have detected this and adjusted his
9547          * allocation length to get all of the available data.
9548          */
9549         if (valid_len < sizeof(*one) + cdb_len) {
9550                 retval = 1;
9551                 goto bailout;
9552         }
9553
9554         /*
9555          * If all we have is the opcode, there is no point in printing out
9556          * the usage bitmap.
9557          */
9558         if (cdb_len <= 1) {
9559                 retval = 1;
9560                 goto bailout;
9561         }
9562
9563         printf("CDB usage bitmap:");
9564         for (i = 0; i < cdb_len; i++) {
9565                 printf(" %02x", one->cdb_usage[i]);
9566         }
9567         printf("\n");
9568
9569         /*
9570          * If we don't have a timeout descriptor, we're done.
9571          */
9572         if ((one->support & RSO_ONE_CTDP) == 0)
9573                 goto bailout;
9574
9575         /*
9576          * If we don't have enough valid length to include the timeout
9577          * descriptor length, we're done.
9578          */
9579         if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9580                 goto bailout;
9581
9582         td = (struct scsi_report_supported_opcodes_timeout *)
9583             &buf[sizeof(*one) + cdb_len];
9584         td_len = scsi_2btoul(td->length);
9585         td_len += sizeof(td->length);
9586
9587         /*
9588          * If we don't have the full timeout descriptor, we're done.
9589          */
9590         if (td_len < sizeof(*td))
9591                 goto bailout;
9592
9593         /*
9594          * If we don't have enough valid length to contain the full timeout
9595          * descriptor, we're done.
9596          */
9597         if (valid_len < (sizeof(*one) + cdb_len + td_len))
9598                 goto bailout;
9599
9600         printf("Timeout information:\n");
9601         printf("Command-specific:    0x%02x\n", td->cmd_specific);
9602         printf("Nominal timeout:     %u seconds\n",
9603                scsi_4btoul(td->nominal_time));
9604         printf("Recommended timeout: %u seconds\n",
9605                scsi_4btoul(td->recommended_time));
9606
9607 bailout:
9608         return (retval);
9609 }
9610
9611 static int
9612 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9613                  uint32_t valid_len)
9614 {
9615         struct scsi_report_supported_opcodes_all *hdr;
9616         struct scsi_report_supported_opcodes_descr *desc;
9617         uint32_t avail_len = 0, used_len = 0;
9618         uint8_t *cur_ptr;
9619         int retval = 0;
9620
9621         if (valid_len < sizeof(*hdr)) {
9622                 warnx("%s: not enough returned data (%u bytes) opcode list",
9623                       __func__, valid_len);
9624                 retval = 1;
9625                 goto bailout;
9626         }
9627         hdr = (struct scsi_report_supported_opcodes_all *)buf;
9628         avail_len = scsi_4btoul(hdr->length);
9629         avail_len += sizeof(hdr->length);
9630         /*
9631          * Take the lesser of the amount of data the drive claims is
9632          * available, and the amount of data the HBA says was returned.
9633          */
9634         avail_len = MIN(avail_len, valid_len);
9635
9636         used_len = sizeof(hdr->length);
9637
9638         printf("%-6s %4s %8s ",
9639                "Opcode", "SA", "CDB len" );
9640
9641         if (td_req != 0)
9642                 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9643         printf(" Description\n");
9644
9645         while ((avail_len - used_len) > sizeof(*desc)) {
9646                 struct scsi_report_supported_opcodes_timeout *td;
9647                 uint32_t td_len;
9648                 const char *op_desc = NULL;
9649
9650                 cur_ptr = &buf[used_len];
9651                 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9652
9653                 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9654                 if (op_desc == NULL)
9655                         op_desc = "UNKNOWN";
9656
9657                 printf("0x%02x   %#4x %8u ", desc->opcode,
9658                        scsi_2btoul(desc->service_action),
9659                        scsi_2btoul(desc->cdb_length));
9660
9661                 used_len += sizeof(*desc);
9662
9663                 if ((desc->flags & RSO_CTDP) == 0) {
9664                         printf(" %s\n", op_desc);
9665                         continue;
9666                 }
9667
9668                 /*
9669                  * If we don't have enough space to fit a timeout
9670                  * descriptor, then we're done.
9671                  */
9672                 if (avail_len - used_len < sizeof(*td)) {
9673                         used_len = avail_len;
9674                         printf(" %s\n", op_desc);
9675                         continue;
9676                 }
9677                 cur_ptr = &buf[used_len];
9678                 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9679                 td_len = scsi_2btoul(td->length);
9680                 td_len += sizeof(td->length);
9681
9682                 used_len += td_len;
9683                 /*
9684                  * If the given timeout descriptor length is less than what
9685                  * we understand, skip it.
9686                  */
9687                 if (td_len < sizeof(*td)) {
9688                         printf(" %s\n", op_desc);
9689                         continue;
9690                 }
9691
9692                 printf(" 0x%02x %6u %6u  %s\n", td->cmd_specific,
9693                        scsi_4btoul(td->nominal_time),
9694                        scsi_4btoul(td->recommended_time), op_desc);
9695         }
9696 bailout:
9697         return (retval);
9698 }
9699
9700 static int
9701 scsiopcodes(struct cam_device *device, int argc, char **argv,
9702             char *combinedopt, int task_attr, int retry_count, int timeout,
9703             int verbosemode)
9704 {
9705         int c;
9706         uint32_t opcode = 0, service_action = 0;
9707         int td_set = 0, opcode_set = 0, sa_set = 0;
9708         int show_sa_errors = 1;
9709         uint32_t valid_len = 0;
9710         uint8_t *buf = NULL;
9711         char *endptr;
9712         int retval = 0;
9713
9714         while ((c = getopt(argc, argv, combinedopt)) != -1) {
9715                 switch (c) {
9716                 case 'N':
9717                         show_sa_errors = 0;
9718                         break;
9719                 case 'o':
9720                         opcode = strtoul(optarg, &endptr, 0);
9721                         if (*endptr != '\0') {
9722                                 warnx("Invalid opcode \"%s\", must be a number",
9723                                       optarg);
9724                                 retval = 1;
9725                                 goto bailout;
9726                         }
9727                         if (opcode > 0xff) {
9728                                 warnx("Invalid opcode 0x%#x, must be between"
9729                                       "0 and 0xff inclusive", opcode);
9730                                 retval = 1;
9731                                 goto bailout;
9732                         }
9733                         opcode_set = 1;
9734                         break;
9735                 case 's':
9736                         service_action = strtoul(optarg, &endptr, 0);
9737                         if (*endptr != '\0') {
9738                                 warnx("Invalid service action \"%s\", must "
9739                                       "be a number", optarg);
9740                                 retval = 1;
9741                                 goto bailout;
9742                         }
9743                         if (service_action > 0xffff) {
9744                                 warnx("Invalid service action 0x%#x, must "
9745                                       "be between 0 and 0xffff inclusive",
9746                                       service_action);
9747                                 retval = 1;
9748                         }
9749                         sa_set = 1;
9750                         break;
9751                 case 'T':
9752                         td_set = 1;
9753                         break;
9754                 default:
9755                         break;
9756                 }
9757         }
9758
9759         if ((sa_set != 0)
9760          && (opcode_set == 0)) {
9761                 warnx("You must specify an opcode with -o if a service "
9762                       "action is given");
9763                 retval = 1;
9764                 goto bailout;
9765         }
9766         retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9767                                 sa_set, service_action, td_set, task_attr,
9768                                 retry_count, timeout, verbosemode, &valid_len,
9769                                 &buf);
9770         if (retval != 0)
9771                 goto bailout;
9772
9773         if ((opcode_set != 0)
9774          || (sa_set != 0)) {
9775                 retval = scsiprintoneopcode(device, opcode, sa_set,
9776                                             service_action, buf, valid_len);
9777         } else {
9778                 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9779         }
9780
9781 bailout:
9782         free(buf);
9783
9784         return (retval);
9785 }
9786
9787
9788 static int
9789 reprobe(struct cam_device *device)
9790 {
9791         union ccb *ccb;
9792         int retval = 0;
9793
9794         ccb = cam_getccb(device);
9795
9796         if (ccb == NULL) {
9797                 warnx("%s: error allocating ccb", __func__);
9798                 return (1);
9799         }
9800
9801         CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9802
9803         ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9804
9805         if (cam_send_ccb(device, ccb) < 0) {
9806                 warn("error sending XPT_REPROBE_LUN CCB");
9807                 retval = 1;
9808                 goto bailout;
9809         }
9810
9811         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9812                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9813                 retval = 1;
9814                 goto bailout;
9815         }
9816
9817 bailout:
9818         cam_freeccb(ccb);
9819
9820         return (retval);
9821 }
9822
9823 void
9824 usage(int printlong)
9825 {
9826
9827         fprintf(printlong ? stdout : stderr,
9828 "usage:  camcontrol <command>  [device id][generic args][command args]\n"
9829 "        camcontrol devlist    [-b] [-v]\n"
9830 "        camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9831 "        camcontrol tur        [dev_id][generic args]\n"
9832 "        camcontrol inquiry    [dev_id][generic args] [-D] [-S] [-R]\n"
9833 "        camcontrol identify   [dev_id][generic args] [-v]\n"
9834 "        camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9835 "        camcontrol readcap    [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9836 "                              [-q] [-s] [-l]\n"
9837 "        camcontrol start      [dev_id][generic args]\n"
9838 "        camcontrol stop       [dev_id][generic args]\n"
9839 "        camcontrol load       [dev_id][generic args]\n"
9840 "        camcontrol eject      [dev_id][generic args]\n"
9841 "        camcontrol reprobe    [dev_id][generic args]\n"
9842 "        camcontrol rescan     <all | bus[:target:lun] | dev_id>\n"
9843 "        camcontrol reset      <all | bus[:target:lun] | dev_id>\n"
9844 "        camcontrol defects    [dev_id][generic args] <-f format> [-P][-G]\n"
9845 "                              [-q][-s][-S offset][-X]\n"
9846 "        camcontrol modepage   [dev_id][generic args] <-m page | -l>\n"
9847 "                              [-P pagectl][-e | -b][-d]\n"
9848 "        camcontrol cmd        [dev_id][generic args]\n"
9849 "                              <-a cmd [args] | -c cmd [args]>\n"
9850 "                              [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9851 "        camcontrol smpcmd     [dev_id][generic args]\n"
9852 "                              <-r len fmt [args]> <-R len fmt [args]>\n"
9853 "        camcontrol smprg      [dev_id][generic args][-l]\n"
9854 "        camcontrol smppc      [dev_id][generic args] <-p phy> [-l]\n"
9855 "                              [-o operation][-d name][-m rate][-M rate]\n"
9856 "                              [-T pp_timeout][-a enable|disable]\n"
9857 "                              [-A enable|disable][-s enable|disable]\n"
9858 "                              [-S enable|disable]\n"
9859 "        camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9860 "        camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9861 "        camcontrol debug      [-I][-P][-T][-S][-X][-c]\n"
9862 "                              <all|dev_id|bus[:target[:lun]]|off>\n"
9863 "        camcontrol tags       [dev_id][generic args] [-N tags] [-q] [-v]\n"
9864 "        camcontrol negotiate  [dev_id][generic args] [-a][-c]\n"
9865 "                              [-D <enable|disable>][-M mode][-O offset]\n"
9866 "                              [-q][-R syncrate][-v][-T <enable|disable>]\n"
9867 "                              [-U][-W bus_width]\n"
9868 "        camcontrol format     [dev_id][generic args][-q][-r][-w][-y]\n"
9869 "        camcontrol sanitize   [dev_id][generic args]\n"
9870 "                              [-a overwrite|block|crypto|exitfailure]\n"
9871 "                              [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9872 "                              [-y]\n"
9873 "        camcontrol idle       [dev_id][generic args][-t time]\n"
9874 "        camcontrol standby    [dev_id][generic args][-t time]\n"
9875 "        camcontrol sleep      [dev_id][generic args]\n"
9876 "        camcontrol powermode  [dev_id][generic args]\n"
9877 "        camcontrol apm        [dev_id][generic args][-l level]\n"
9878 "        camcontrol aam        [dev_id][generic args][-l level]\n"
9879 "        camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9880 "                              [-s][-y]\n"
9881 "        camcontrol security   [dev_id][generic args]\n"
9882 "                              <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9883 "                              [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9884 "                              [-U <user|master>] [-y]\n"
9885 "        camcontrol hpa        [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9886 "                              [-q] [-s max_sectors] [-U pwd] [-y]\n"
9887 "        camcontrol ama        [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9888 "        camcontrol persist    [dev_id][generic args] <-i action|-o action>\n"
9889 "                              [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9890 "                              [-s scope][-S][-T type][-U]\n"
9891 "        camcontrol attrib     [dev_id][generic args] <-r action|-w attr>\n"
9892 "                              [-a attr_num][-c][-e elem][-F form1,form1]\n"
9893 "                              [-p part][-s start][-T type][-V vol]\n"
9894 "        camcontrol opcodes    [dev_id][generic args][-o opcode][-s SA]\n"
9895 "                              [-N][-T]\n"
9896 "        camcontrol zone       [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9897 "                              [-o rep_opts] [-P print_opts]\n"
9898 "        camcontrol epc        [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9899 "                              [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9900 "                              [-S power_src] [-T timer]\n"
9901 "        camcontrol timestamp  [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9902 "                              <-s <-f format -T time | -U >>\n"
9903 "        camcontrol devtype    [dev_id]\n"
9904 "                              \n"
9905 "        camcontrol help\n");
9906         if (!printlong)
9907                 return;
9908         fprintf(stdout,
9909 "Specify one of the following options:\n"
9910 "devlist     list all CAM devices\n"
9911 "periphlist  list all CAM peripheral drivers attached to a device\n"
9912 "tur         send a test unit ready to the named device\n"
9913 "inquiry     send a SCSI inquiry command to the named device\n"
9914 "identify    send a ATA identify command to the named device\n"
9915 "reportluns  send a SCSI report luns command to the device\n"
9916 "readcap     send a SCSI read capacity command to the device\n"
9917 "start       send a Start Unit command to the device\n"
9918 "stop        send a Stop Unit command to the device\n"
9919 "load        send a Start Unit command to the device with the load bit set\n"
9920 "eject       send a Stop Unit command to the device with the eject bit set\n"
9921 "reprobe     update capacity information of the given device\n"
9922 "rescan      rescan all buses, the given bus, bus:target:lun or device\n"
9923 "reset       reset all buses, the given bus, bus:target:lun or device\n"
9924 "defects     read the defect list of the specified device\n"
9925 "modepage    display or edit (-e) the given mode page\n"
9926 "cmd         send the given SCSI command, may need -i or -o as well\n"
9927 "smpcmd      send the given SMP command, requires -o and -i\n"
9928 "smprg       send the SMP Report General command\n"
9929 "smppc       send the SMP PHY Control command, requires -p\n"
9930 "smpphylist  display phys attached to a SAS expander\n"
9931 "smpmaninfo  send the SMP Report Manufacturer Info command\n"
9932 "debug       turn debugging on/off for a bus, target, or lun, or all devices\n"
9933 "tags        report or set the number of transaction slots for a device\n"
9934 "negotiate   report or set device negotiation parameters\n"
9935 "format      send the SCSI FORMAT UNIT command to the named device\n"
9936 "sanitize    send the SCSI SANITIZE command to the named device\n"
9937 "idle        send the ATA IDLE command to the named device\n"
9938 "standby     send the ATA STANDBY command to the named device\n"
9939 "sleep       send the ATA SLEEP command to the named device\n"
9940 "powermode   send the ATA CHECK POWER MODE command to the named device\n"
9941 "fwdownload  program firmware of the named device with the given image\n"
9942 "security    report or send ATA security commands to the named device\n"
9943 "persist     send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9944 "attrib      send the SCSI READ or WRITE ATTRIBUTE commands\n"
9945 "opcodes     send the SCSI REPORT SUPPORTED OPCODES command\n"
9946 "zone        manage Zoned Block (Shingled) devices\n"
9947 "epc         send ATA Extended Power Conditions commands\n"
9948 "timestamp   report or set the device's timestamp\n"
9949 "devtype     report the type of device\n"
9950 "help        this message\n"
9951 "Device Identifiers:\n"
9952 "bus:target        specify the bus and target, lun defaults to 0\n"
9953 "bus:target:lun    specify the bus, target and lun\n"
9954 "deviceUNIT        specify the device name, like \"da4\" or \"cd2\"\n"
9955 "Generic arguments:\n"
9956 "-v                be verbose, print out sense information\n"
9957 "-t timeout        command timeout in seconds, overrides default timeout\n"
9958 "-n dev_name       specify device name, e.g. \"da\", \"cd\"\n"
9959 "-u unit           specify unit number, e.g. \"0\", \"5\"\n"
9960 "-E                have the kernel attempt to perform SCSI error recovery\n"
9961 "-C count          specify the SCSI command retry count (needs -E to work)\n"
9962 "-Q task_attr      specify ordered, simple or head tag type for SCSI cmds\n"
9963 "modepage arguments:\n"
9964 "-l                list all available mode pages\n"
9965 "-m page           specify the mode page to view or edit\n"
9966 "-e                edit the specified mode page\n"
9967 "-b                force view to binary mode\n"
9968 "-d                disable block descriptors for mode sense\n"
9969 "-P pgctl          page control field 0-3\n"
9970 "defects arguments:\n"
9971 "-f format         specify defect list format (block, bfi or phys)\n"
9972 "-G                get the grown defect list\n"
9973 "-P                get the permanent defect list\n"
9974 "inquiry arguments:\n"
9975 "-D                get the standard inquiry data\n"
9976 "-S                get the serial number\n"
9977 "-R                get the transfer rate, etc.\n"
9978 "reportluns arguments:\n"
9979 "-c                only report a count of available LUNs\n"
9980 "-l                only print out luns, and not a count\n"
9981 "-r <reporttype>   specify \"default\", \"wellknown\" or \"all\"\n"
9982 "readcap arguments\n"
9983 "-b                only report the blocksize\n"
9984 "-h                human readable device size, base 2\n"
9985 "-H                human readable device size, base 10\n"
9986 "-N                print the number of blocks instead of last block\n"
9987 "-q                quiet, print numbers only\n"
9988 "-s                only report the last block/device size\n"
9989 "cmd arguments:\n"
9990 "-c cdb [args]     specify the SCSI CDB\n"
9991 "-i len fmt        specify input data and input data format\n"
9992 "-o len fmt [args] specify output data and output data fmt\n"
9993 "smpcmd arguments:\n"
9994 "-r len fmt [args] specify the SMP command to be sent\n"
9995 "-R len fmt [args] specify SMP response format\n"
9996 "smprg arguments:\n"
9997 "-l                specify the long response format\n"
9998 "smppc arguments:\n"
9999 "-p phy            specify the PHY to operate on\n"
10000 "-l                specify the long request/response format\n"
10001 "-o operation      specify the phy control operation\n"
10002 "-d name           set the attached device name\n"
10003 "-m rate           set the minimum physical link rate\n"
10004 "-M rate           set the maximum physical link rate\n"
10005 "-T pp_timeout     set the partial pathway timeout value\n"
10006 "-a enable|disable enable or disable SATA slumber\n"
10007 "-A enable|disable enable or disable SATA partial phy power\n"
10008 "-s enable|disable enable or disable SAS slumber\n"
10009 "-S enable|disable enable or disable SAS partial phy power\n"
10010 "smpphylist arguments:\n"
10011 "-l                specify the long response format\n"
10012 "-q                only print phys with attached devices\n"
10013 "smpmaninfo arguments:\n"
10014 "-l                specify the long response format\n"
10015 "debug arguments:\n"
10016 "-I                CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10017 "-T                CAM_DEBUG_TRACE -- routine flow tracking\n"
10018 "-S                CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10019 "-c                CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10020 "tags arguments:\n"
10021 "-N tags           specify the number of tags to use for this device\n"
10022 "-q                be quiet, don't report the number of tags\n"
10023 "-v                report a number of tag-related parameters\n"
10024 "negotiate arguments:\n"
10025 "-a                send a test unit ready after negotiation\n"
10026 "-c                report/set current negotiation settings\n"
10027 "-D <arg>          \"enable\" or \"disable\" disconnection\n"
10028 "-M mode           set ATA mode\n"
10029 "-O offset         set command delay offset\n"
10030 "-q                be quiet, don't report anything\n"
10031 "-R syncrate       synchronization rate in MHz\n"
10032 "-T <arg>          \"enable\" or \"disable\" tagged queueing\n"
10033 "-U                report/set user negotiation settings\n"
10034 "-W bus_width      set the bus width in bits (8, 16 or 32)\n"
10035 "-v                also print a Path Inquiry CCB for the controller\n"
10036 "format arguments:\n"
10037 "-q                be quiet, don't print status messages\n"
10038 "-r                run in report only mode\n"
10039 "-w                don't send immediate format command\n"
10040 "-y                don't ask any questions\n"
10041 "sanitize arguments:\n"
10042 "-a operation      operation mode: overwrite, block, crypto or exitfailure\n"
10043 "-c passes         overwrite passes to perform (1 to 31)\n"
10044 "-I                invert overwrite pattern after each pass\n"
10045 "-P pattern        path to overwrite pattern file\n"
10046 "-q                be quiet, don't print status messages\n"
10047 "-r                run in report only mode\n"
10048 "-U                run operation in unrestricted completion exit mode\n"
10049 "-w                don't send immediate sanitize command\n"
10050 "-y                don't ask any questions\n"
10051 "idle/standby arguments:\n"
10052 "-t <arg>          number of seconds before respective state.\n"
10053 "fwdownload arguments:\n"
10054 "-f fw_image       path to firmware image file\n"
10055 "-q                don't print informational messages, only errors\n"
10056 "-s                run in simulation mode\n"
10057 "-v                print info for every firmware segment sent to device\n"
10058 "-y                don't ask any questions\n"
10059 "security arguments:\n"
10060 "-d pwd            disable security using the given password for the selected\n"
10061 "                  user\n"
10062 "-e pwd            erase the device using the given pwd for the selected user\n"
10063 "-f                freeze the security configuration of the specified device\n"
10064 "-h pwd            enhanced erase the device using the given pwd for the\n"
10065 "                  selected user\n"
10066 "-k pwd            unlock the device using the given pwd for the selected\n"
10067 "                  user\n"
10068 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10069 "-q                be quiet, do not print any status messages\n"
10070 "-s pwd            password the device (enable security) using the given\n"
10071 "                  pwd for the selected user\n"
10072 "-T timeout        overrides the timeout (seconds) used for erase operation\n"
10073 "-U <user|master>  specifies which user to set: user or master\n"
10074 "-y                don't ask any questions\n"
10075 "hpa arguments:\n"
10076 "-f                freeze the HPA configuration of the device\n"
10077 "-l                lock the HPA configuration of the device\n"
10078 "-P                make the HPA max sectors persist\n"
10079 "-p pwd            Set the HPA configuration password required for unlock\n"
10080 "                  calls\n"
10081 "-q                be quiet, do not print any status messages\n"
10082 "-s sectors        configures the maximum user accessible sectors of the\n"
10083 "                  device\n"
10084 "-U pwd            unlock the HPA configuration of the device\n"
10085 "-y                don't ask any questions\n"
10086 "ama arguments:\n"
10087 "-f                freeze the AMA configuration of the device\n"
10088 "-q                be quiet, do not print any status messages\n"
10089 "-s sectors        configures the maximum user accessible sectors of the\n"
10090 "                  device\n"
10091 "persist arguments:\n"
10092 "-i action         specify read_keys, read_reservation, report_cap, or\n"
10093 "                  read_full_status\n"
10094 "-o action         specify register, register_ignore, reserve, release,\n"
10095 "                  clear, preempt, preempt_abort, register_move, replace_lost\n"
10096 "-a                set the All Target Ports (ALL_TG_PT) bit\n"
10097 "-I tid            specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10098 "-k key            specify the Reservation Key\n"
10099 "-K sa_key         specify the Service Action Reservation Key\n"
10100 "-p                set the Activate Persist Through Power Loss bit\n"
10101 "-R rtp            specify the Relative Target Port\n"
10102 "-s scope          specify the scope: lun, extent, element or a number\n"
10103 "-S                specify Transport ID for register, requires -I\n"
10104 "-T res_type       specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10105 "                  ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10106 "-U                unregister the current initiator for register_move\n"
10107 "attrib arguments:\n"
10108 "-r action         specify attr_values, attr_list, lv_list, part_list, or\n"
10109 "                  supp_attr\n"
10110 "-w attr           specify an attribute to write, one -w argument per attr\n"
10111 "-a attr_num       only display this attribute number\n"
10112 "-c                get cached attributes\n"
10113 "-e elem_addr      request attributes for the given element in a changer\n"
10114 "-F form1,form2    output format, comma separated list: text_esc, text_raw,\n"
10115 "                  nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10116 "                  field_none, field_desc, field_num, field_size, field_rw\n"
10117 "-p partition      request attributes for the given partition\n"
10118 "-s start_attr     request attributes starting at the given number\n"
10119 "-T elem_type      specify the element type (used with -e)\n"
10120 "-V logical_vol    specify the logical volume ID\n"
10121 "opcodes arguments:\n"
10122 "-o opcode         specify the individual opcode to list\n"
10123 "-s service_action specify the service action for the opcode\n"
10124 "-N                do not return SCSI error for unsupported SA\n"
10125 "-T                request nominal and recommended timeout values\n"
10126 "zone arguments:\n"
10127 "-c cmd            required: rz, open, close, finish, or rwp\n"
10128 "-a                apply the action to all zones\n"
10129 "-l LBA            specify the zone starting LBA\n"
10130 "-o rep_opts       report zones options: all, empty, imp_open, exp_open,\n"
10131 "                  closed, full, ro, offline, reset, nonseq, nonwp\n"
10132 "-P print_opt      report zones printing:  normal, summary, script\n"
10133 "epc arguments:\n"
10134 "-c cmd            required: restore, goto, timer, state, enable, disable,\n"
10135 "                  source, status, list\n"
10136 "-d                disable power mode (timer, state)\n"
10137 "-D                delayed entry (goto)\n"
10138 "-e                enable power mode (timer, state)\n"
10139 "-H                hold power mode (goto)\n"
10140 "-p power_cond     Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10141 "                  state, goto)\n"
10142 "-P                only display power mode (status)\n"
10143 "-r rst_src        restore settings from: default, saved (restore)\n"
10144 "-s                save mode (timer, state, restore)\n"
10145 "-S power_src      set power source: battery, nonbattery (source)\n"
10146 "-T timer          set timer, seconds, .1 sec resolution (timer)\n"
10147 "timestamp arguments:\n"
10148 "-r                report the timestamp of the device\n"
10149 "-f format         report the timestamp of the device with the given\n"
10150 "                  strftime(3) format string\n"
10151 "-m                report the timestamp of the device as milliseconds since\n"
10152 "                  January 1st, 1970\n"
10153 "-U                report the time with UTC instead of the local time zone\n"
10154 "-s                set the timestamp of the device\n"
10155 "-f format         the format of the time string passed into strptime(3)\n"
10156 "-T time           the time value passed into strptime(3)\n"
10157 "-U                set the timestamp of the device to UTC time\n"
10158 );
10159 }
10160
10161 int
10162 main(int argc, char **argv)
10163 {
10164         int c;
10165         char *device = NULL;
10166         int unit = 0;
10167         struct cam_device *cam_dev = NULL;
10168         int timeout = 0, retry_count = 1;
10169         camcontrol_optret optreturn;
10170         char *tstr;
10171         const char *mainopt = "C:En:Q:t:u:v";
10172         const char *subopt = NULL;
10173         char combinedopt[256];
10174         int error = 0, optstart = 2;
10175         int task_attr = MSG_SIMPLE_Q_TAG;
10176         int devopen = 1;
10177         path_id_t bus;
10178         target_id_t target;
10179         lun_id_t lun;
10180
10181         cmdlist = CAM_CMD_NONE;
10182         arglist = CAM_ARG_NONE;
10183
10184         if (argc < 2) {
10185                 usage(0);
10186                 exit(1);
10187         }
10188
10189         /*
10190          * Get the base option.
10191          */
10192         optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10193
10194         if (optreturn == CC_OR_AMBIGUOUS) {
10195                 warnx("ambiguous option %s", argv[1]);
10196                 usage(0);
10197                 exit(1);
10198         } else if (optreturn == CC_OR_NOT_FOUND) {
10199                 warnx("option %s not found", argv[1]);
10200                 usage(0);
10201                 exit(1);
10202         }
10203
10204         /*
10205          * Ahh, getopt(3) is a pain.
10206          *
10207          * This is a gross hack.  There really aren't many other good
10208          * options (excuse the pun) for parsing options in a situation like
10209          * this.  getopt is kinda braindead, so you end up having to run
10210          * through the options twice, and give each invocation of getopt
10211          * the option string for the other invocation.
10212          *
10213          * You would think that you could just have two groups of options.
10214          * The first group would get parsed by the first invocation of
10215          * getopt, and the second group would get parsed by the second
10216          * invocation of getopt.  It doesn't quite work out that way.  When
10217          * the first invocation of getopt finishes, it leaves optind pointing
10218          * to the argument _after_ the first argument in the second group.
10219          * So when the second invocation of getopt comes around, it doesn't
10220          * recognize the first argument it gets and then bails out.
10221          *
10222          * A nice alternative would be to have a flag for getopt that says
10223          * "just keep parsing arguments even when you encounter an unknown
10224          * argument", but there isn't one.  So there's no real clean way to
10225          * easily parse two sets of arguments without having one invocation
10226          * of getopt know about the other.
10227          *
10228          * Without this hack, the first invocation of getopt would work as
10229          * long as the generic arguments are first, but the second invocation
10230          * (in the subfunction) would fail in one of two ways.  In the case
10231          * where you don't set optreset, it would fail because optind may be
10232          * pointing to the argument after the one it should be pointing at.
10233          * In the case where you do set optreset, and reset optind, it would
10234          * fail because getopt would run into the first set of options, which
10235          * it doesn't understand.
10236          *
10237          * All of this would "sort of" work if you could somehow figure out
10238          * whether optind had been incremented one option too far.  The
10239          * mechanics of that, however, are more daunting than just giving
10240          * both invocations all of the expect options for either invocation.
10241          *
10242          * Needless to say, I wouldn't mind if someone invented a better
10243          * (non-GPL!) command line parsing interface than getopt.  I
10244          * wouldn't mind if someone added more knobs to getopt to make it
10245          * work better.  Who knows, I may talk myself into doing it someday,
10246          * if the standards weenies let me.  As it is, it just leads to
10247          * hackery like this and causes people to avoid it in some cases.
10248          *
10249          * KDM, September 8th, 1998
10250          */
10251         if (subopt != NULL)
10252                 sprintf(combinedopt, "%s%s", mainopt, subopt);
10253         else
10254                 sprintf(combinedopt, "%s", mainopt);
10255
10256         /*
10257          * For these options we do not parse optional device arguments and
10258          * we do not open a passthrough device.
10259          */
10260         if ((cmdlist == CAM_CMD_RESCAN)
10261          || (cmdlist == CAM_CMD_RESET)
10262          || (cmdlist == CAM_CMD_DEVTREE)
10263          || (cmdlist == CAM_CMD_USAGE)
10264          || (cmdlist == CAM_CMD_DEBUG))
10265                 devopen = 0;
10266
10267         if ((devopen == 1)
10268          && (argc > 2 && argv[2][0] != '-')) {
10269                 char name[30];
10270                 int rv;
10271
10272                 if (isdigit(argv[2][0])) {
10273                         /* device specified as bus:target[:lun] */
10274                         rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10275                         if (rv < 2)
10276                                 errx(1, "numeric device specification must "
10277                                      "be either bus:target, or "
10278                                      "bus:target:lun");
10279                         /* default to 0 if lun was not specified */
10280                         if ((arglist & CAM_ARG_LUN) == 0) {
10281                                 lun = 0;
10282                                 arglist |= CAM_ARG_LUN;
10283                         }
10284                         optstart++;
10285                 } else {
10286                         if (cam_get_device(argv[2], name, sizeof name, &unit)
10287                             == -1)
10288                                 errx(1, "%s", cam_errbuf);
10289                         device = strdup(name);
10290                         arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10291                         optstart++;
10292                 }
10293         }
10294         /*
10295          * Start getopt processing at argv[2/3], since we've already
10296          * accepted argv[1..2] as the command name, and as a possible
10297          * device name.
10298          */
10299         optind = optstart;
10300
10301         /*
10302          * Now we run through the argument list looking for generic
10303          * options, and ignoring options that possibly belong to
10304          * subfunctions.
10305          */
10306         while ((c = getopt(argc, argv, combinedopt))!= -1){
10307                 switch(c) {
10308                         case 'C':
10309                                 retry_count = strtol(optarg, NULL, 0);
10310                                 if (retry_count < 0)
10311                                         errx(1, "retry count %d is < 0",
10312                                              retry_count);
10313                                 arglist |= CAM_ARG_RETRIES;
10314                                 break;
10315                         case 'E':
10316                                 arglist |= CAM_ARG_ERR_RECOVER;
10317                                 break;
10318                         case 'n':
10319                                 arglist |= CAM_ARG_DEVICE;
10320                                 tstr = optarg;
10321                                 while (isspace(*tstr) && (*tstr != '\0'))
10322                                         tstr++;
10323                                 device = (char *)strdup(tstr);
10324                                 break;
10325                         case 'Q': {
10326                                 char *endptr;
10327                                 int table_entry = 0;
10328
10329                                 tstr = optarg;
10330                                 while (isspace(*tstr) && (*tstr != '\0'))
10331                                         tstr++;
10332                                 if (isdigit(*tstr)) {
10333                                         task_attr = strtol(tstr, &endptr, 0);
10334                                         if (*endptr != '\0') {
10335                                                 errx(1, "Invalid queue option "
10336                                                     "%s", tstr);
10337                                         }
10338                                 } else {
10339                                         size_t table_size;
10340                                         scsi_nv_status status;
10341
10342                                         table_size = sizeof(task_attrs) /
10343                                                      sizeof(task_attrs[0]);
10344                                         status = scsi_get_nv(task_attrs,
10345                                             table_size, tstr, &table_entry,
10346                                             SCSI_NV_FLAG_IG_CASE);
10347                                         if (status == SCSI_NV_FOUND)
10348                                                 task_attr = task_attrs[
10349                                                     table_entry].value;
10350                                         else {
10351                                                 errx(1, "%s option %s",
10352                                                   (status == SCSI_NV_AMBIGUOUS)?
10353                                                     "ambiguous" : "invalid",
10354                                                     tstr);
10355                                         }
10356                                 }
10357                                 break;
10358                         }
10359                         case 't':
10360                                 timeout = strtol(optarg, NULL, 0);
10361                                 if (timeout < 0)
10362                                         errx(1, "invalid timeout %d", timeout);
10363                                 /* Convert the timeout from seconds to ms */
10364                                 timeout *= 1000;
10365                                 arglist |= CAM_ARG_TIMEOUT;
10366                                 break;
10367                         case 'u':
10368                                 arglist |= CAM_ARG_UNIT;
10369                                 unit = strtol(optarg, NULL, 0);
10370                                 break;
10371                         case 'v':
10372                                 arglist |= CAM_ARG_VERBOSE;
10373                                 break;
10374                         default:
10375                                 break;
10376                 }
10377         }
10378
10379         /*
10380          * For most commands we'll want to open the passthrough device
10381          * associated with the specified device.  In the case of the rescan
10382          * commands, we don't use a passthrough device at all, just the
10383          * transport layer device.
10384          */
10385         if (devopen == 1) {
10386                 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10387                  && (((arglist & CAM_ARG_DEVICE) == 0)
10388                   || ((arglist & CAM_ARG_UNIT) == 0))) {
10389                         errx(1, "subcommand \"%s\" requires a valid device "
10390                              "identifier", argv[1]);
10391                 }
10392
10393                 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10394                                 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10395                                 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10396                      == NULL)
10397                         errx(1,"%s", cam_errbuf);
10398         }
10399
10400         /*
10401          * Reset optind to 2, and reset getopt, so these routines can parse
10402          * the arguments again.
10403          */
10404         optind = optstart;
10405         optreset = 1;
10406
10407         switch(cmdlist) {
10408         case CAM_CMD_DEVLIST:
10409                 error = getdevlist(cam_dev);
10410                 break;
10411         case CAM_CMD_HPA:
10412                 error = atahpa(cam_dev, retry_count, timeout,
10413                                argc, argv, combinedopt);
10414                 break;
10415         case CAM_CMD_AMA:
10416                 error = ataama(cam_dev, retry_count, timeout,
10417                                argc, argv, combinedopt);
10418                 break;
10419         case CAM_CMD_DEVTREE:
10420                 error = getdevtree(argc, argv, combinedopt);
10421                 break;
10422         case CAM_CMD_DEVTYPE:
10423                 error = getdevtype(cam_dev);
10424                 break;
10425         case CAM_CMD_TUR:
10426                 error = testunitready(cam_dev, task_attr, retry_count,
10427                     timeout, 0);
10428                 break;
10429         case CAM_CMD_INQUIRY:
10430                 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10431                                       task_attr, retry_count, timeout);
10432                 break;
10433         case CAM_CMD_IDENTIFY:
10434                 error = identify(cam_dev, retry_count, timeout);
10435                 break;
10436         case CAM_CMD_STARTSTOP:
10437                 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10438                                   arglist & CAM_ARG_EJECT, task_attr,
10439                                   retry_count, timeout);
10440                 break;
10441         case CAM_CMD_RESCAN:
10442                 error = dorescan_or_reset(argc, argv, 1);
10443                 break;
10444         case CAM_CMD_RESET:
10445                 error = dorescan_or_reset(argc, argv, 0);
10446                 break;
10447         case CAM_CMD_READ_DEFECTS:
10448                 error = readdefects(cam_dev, argc, argv, combinedopt,
10449                                     task_attr, retry_count, timeout);
10450                 break;
10451         case CAM_CMD_MODE_PAGE:
10452                 modepage(cam_dev, argc, argv, combinedopt,
10453                          task_attr, retry_count, timeout);
10454                 break;
10455         case CAM_CMD_SCSI_CMD:
10456                 error = scsicmd(cam_dev, argc, argv, combinedopt,
10457                                 task_attr, retry_count, timeout);
10458                 break;
10459         case CAM_CMD_MMCSD_CMD:
10460                 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10461                                         retry_count, timeout);
10462                 break;
10463         case CAM_CMD_SMP_CMD:
10464                 error = smpcmd(cam_dev, argc, argv, combinedopt,
10465                                retry_count, timeout);
10466                 break;
10467         case CAM_CMD_SMP_RG:
10468                 error = smpreportgeneral(cam_dev, argc, argv,
10469                                          combinedopt, retry_count,
10470                                          timeout);
10471                 break;
10472         case CAM_CMD_SMP_PC:
10473                 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10474                                       retry_count, timeout);
10475                 break;
10476         case CAM_CMD_SMP_PHYLIST:
10477                 error = smpphylist(cam_dev, argc, argv, combinedopt,
10478                                    retry_count, timeout);
10479                 break;
10480         case CAM_CMD_SMP_MANINFO:
10481                 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10482                                    retry_count, timeout);
10483                 break;
10484         case CAM_CMD_DEBUG:
10485                 error = camdebug(argc, argv, combinedopt);
10486                 break;
10487         case CAM_CMD_TAG:
10488                 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10489                 break;
10490         case CAM_CMD_RATE:
10491                 error = ratecontrol(cam_dev, task_attr, retry_count,
10492                                     timeout, argc, argv, combinedopt);
10493                 break;
10494         case CAM_CMD_FORMAT:
10495                 error = scsiformat(cam_dev, argc, argv,
10496                                    combinedopt, task_attr, retry_count,
10497                                    timeout);
10498                 break;
10499         case CAM_CMD_REPORTLUNS:
10500                 error = scsireportluns(cam_dev, argc, argv,
10501                                        combinedopt, task_attr,
10502                                        retry_count, timeout);
10503                 break;
10504         case CAM_CMD_READCAP:
10505                 error = scsireadcapacity(cam_dev, argc, argv,
10506                                          combinedopt, task_attr,
10507                                          retry_count, timeout);
10508                 break;
10509         case CAM_CMD_IDLE:
10510         case CAM_CMD_STANDBY:
10511         case CAM_CMD_SLEEP:
10512         case CAM_CMD_POWER_MODE:
10513                 error = atapm(cam_dev, argc, argv,
10514                               combinedopt, retry_count, timeout);
10515                 break;
10516         case CAM_CMD_APM:
10517         case CAM_CMD_AAM:
10518                 error = ataaxm(cam_dev, argc, argv,
10519                               combinedopt, retry_count, timeout);
10520                 break;
10521         case CAM_CMD_SECURITY:
10522                 error = atasecurity(cam_dev, retry_count, timeout,
10523                                     argc, argv, combinedopt);
10524                 break;
10525         case CAM_CMD_DOWNLOAD_FW:
10526                 error = fwdownload(cam_dev, argc, argv, combinedopt,
10527                     arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10528                     timeout);
10529                 break;
10530         case CAM_CMD_SANITIZE:
10531                 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10532                                  retry_count, timeout);
10533                 break;
10534         case CAM_CMD_PERSIST:
10535                 error = scsipersist(cam_dev, argc, argv, combinedopt,
10536                     task_attr, retry_count, timeout,
10537                     arglist & CAM_ARG_VERBOSE,
10538                     arglist & CAM_ARG_ERR_RECOVER);
10539                 break;
10540         case CAM_CMD_ATTRIB:
10541                 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10542                     task_attr, retry_count, timeout,
10543                     arglist & CAM_ARG_VERBOSE,
10544                     arglist & CAM_ARG_ERR_RECOVER);
10545                 break;
10546         case CAM_CMD_OPCODES:
10547                 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10548                     task_attr, retry_count, timeout,
10549                     arglist & CAM_ARG_VERBOSE);
10550                 break;
10551         case CAM_CMD_REPROBE:
10552                 error = reprobe(cam_dev);
10553                 break;
10554         case CAM_CMD_ZONE:
10555                 error = zone(cam_dev, argc, argv, combinedopt,
10556                     task_attr, retry_count, timeout,
10557                     arglist & CAM_ARG_VERBOSE);
10558                 break;
10559         case CAM_CMD_EPC:
10560                 error = epc(cam_dev, argc, argv, combinedopt,
10561                     retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10562                 break;
10563         case CAM_CMD_TIMESTAMP:
10564                 error = timestamp(cam_dev, argc, argv, combinedopt,
10565                     task_attr, retry_count, timeout,
10566                     arglist & CAM_ARG_VERBOSE);
10567                 break;
10568         case CAM_CMD_USAGE:
10569                 usage(1);
10570                 break;
10571         default:
10572                 usage(0);
10573                 error = 1;
10574                 break;
10575         }
10576
10577         if (cam_dev != NULL)
10578                 cam_close_device(cam_dev);
10579
10580         exit(error);
10581 }