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