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