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