]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/camcontrol/camcontrol.c
Initialize page/subpage in case of `modepage -d`.
[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 = 0, 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                         if (page < 0 || page > 0x3f)
4579                                 errx(1, "invalid mode page %d", page);
4580                         if (subpage < 0 || subpage > 0xff)
4581                                 errx(1, "invalid mode subpage %d", subpage);
4582                         break;
4583                 case 'D':
4584                         desc = 1;
4585                         break;
4586                 case 'L':
4587                         llbaa = 1;
4588                         break;
4589                 case 'P':
4590                         pc = strtol(optarg, NULL, 0);
4591                         if ((pc < 0) || (pc > 3))
4592                                 errx(1, "invalid page control field %d", pc);
4593                         break;
4594                 default:
4595                         break;
4596                 }
4597         }
4598
4599         if (desc && page == -1)
4600                 page = SMS_ALL_PAGES_PAGE;
4601
4602         if (page == -1 && list == 0)
4603                 errx(1, "you must specify a mode page!");
4604
4605         if (dbd && desc)
4606                 errx(1, "-d and -D are incompatible!");
4607
4608         if (llbaa && cdb_len != 10)
4609                 errx(1, "LLBAA bit is not present in MODE SENSE(6)!");
4610
4611         if (list != 0) {
4612                 mode_list(device, cdb_len, dbd, pc, list > 1, task_attr,
4613                     retry_count, timeout);
4614         } else {
4615                 mode_edit(device, cdb_len, desc, dbd, llbaa, pc, page, subpage,
4616                     edit, binary, task_attr, retry_count, timeout);
4617         }
4618 }
4619
4620 static int
4621 scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
4622         int task_attr, int retry_count, int timeout)
4623 {
4624         union ccb *ccb;
4625         u_int32_t flags = CAM_DIR_NONE;
4626         u_int8_t *data_ptr = NULL;
4627         u_int8_t cdb[20];
4628         u_int8_t atacmd[12];
4629         struct get_hook hook;
4630         int c, data_bytes = 0, valid_bytes;
4631         int cdb_len = 0;
4632         int atacmd_len = 0;
4633         int dmacmd = 0;
4634         int fpdmacmd = 0;
4635         int need_res = 0;
4636         char *datastr = NULL, *tstr, *resstr = NULL;
4637         int error = 0;
4638         int fd_data = 0, fd_res = 0;
4639         int retval;
4640
4641         ccb = cam_getccb(device);
4642
4643         if (ccb == NULL) {
4644                 warnx("scsicmd: error allocating ccb");
4645                 return (1);
4646         }
4647
4648         CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
4649
4650         while ((c = getopt(argc, argv, combinedopt)) != -1) {
4651                 switch(c) {
4652                 case 'a':
4653                         tstr = optarg;
4654                         while (isspace(*tstr) && (*tstr != '\0'))
4655                                 tstr++;
4656                         hook.argc = argc - optind;
4657                         hook.argv = argv + optind;
4658                         hook.got = 0;
4659                         atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr,
4660                                                     iget, &hook);
4661                         /*
4662                          * Increment optind by the number of arguments the
4663                          * encoding routine processed.  After each call to
4664                          * getopt(3), optind points to the argument that
4665                          * getopt should process _next_.  In this case,
4666                          * that means it points to the first command string
4667                          * argument, if there is one.  Once we increment
4668                          * this, it should point to either the next command
4669                          * line argument, or it should be past the end of
4670                          * the list.
4671                          */
4672                         optind += hook.got;
4673                         break;
4674                 case 'c':
4675                         tstr = optarg;
4676                         while (isspace(*tstr) && (*tstr != '\0'))
4677                                 tstr++;
4678                         hook.argc = argc - optind;
4679                         hook.argv = argv + optind;
4680                         hook.got = 0;
4681                         cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr,
4682                                                     iget, &hook);
4683                         /*
4684                          * Increment optind by the number of arguments the
4685                          * encoding routine processed.  After each call to
4686                          * getopt(3), optind points to the argument that
4687                          * getopt should process _next_.  In this case,
4688                          * that means it points to the first command string
4689                          * argument, if there is one.  Once we increment
4690                          * this, it should point to either the next command
4691                          * line argument, or it should be past the end of
4692                          * the list.
4693                          */
4694                         optind += hook.got;
4695                         break;
4696                 case 'd':
4697                         dmacmd = 1;
4698                         break;
4699                 case 'f':
4700                         fpdmacmd = 1;
4701                         break;
4702                 case 'i':
4703                         if (arglist & CAM_ARG_CMD_OUT) {
4704                                 warnx("command must either be "
4705                                       "read or write, not both");
4706                                 error = 1;
4707                                 goto scsicmd_bailout;
4708                         }
4709                         arglist |= CAM_ARG_CMD_IN;
4710                         flags = CAM_DIR_IN;
4711                         data_bytes = strtol(optarg, NULL, 0);
4712                         if (data_bytes <= 0) {
4713                                 warnx("invalid number of input bytes %d",
4714                                       data_bytes);
4715                                 error = 1;
4716                                 goto scsicmd_bailout;
4717                         }
4718                         hook.argc = argc - optind;
4719                         hook.argv = argv + optind;
4720                         hook.got = 0;
4721                         optind++;
4722                         datastr = cget(&hook, NULL);
4723                         /*
4724                          * If the user supplied "-" instead of a format, he
4725                          * wants the data to be written to stdout.
4726                          */
4727                         if ((datastr != NULL)
4728                          && (datastr[0] == '-'))
4729                                 fd_data = 1;
4730
4731                         data_ptr = (u_int8_t *)malloc(data_bytes);
4732                         if (data_ptr == NULL) {
4733                                 warnx("can't malloc memory for data_ptr");
4734                                 error = 1;
4735                                 goto scsicmd_bailout;
4736                         }
4737                         break;
4738                 case 'o':
4739                         if (arglist & CAM_ARG_CMD_IN) {
4740                                 warnx("command must either be "
4741                                       "read or write, not both");
4742                                 error = 1;
4743                                 goto scsicmd_bailout;
4744                         }
4745                         arglist |= CAM_ARG_CMD_OUT;
4746                         flags = CAM_DIR_OUT;
4747                         data_bytes = strtol(optarg, NULL, 0);
4748                         if (data_bytes <= 0) {
4749                                 warnx("invalid number of output bytes %d",
4750                                       data_bytes);
4751                                 error = 1;
4752                                 goto scsicmd_bailout;
4753                         }
4754                         hook.argc = argc - optind;
4755                         hook.argv = argv + optind;
4756                         hook.got = 0;
4757                         datastr = cget(&hook, NULL);
4758                         data_ptr = (u_int8_t *)malloc(data_bytes);
4759                         if (data_ptr == NULL) {
4760                                 warnx("can't malloc memory for data_ptr");
4761                                 error = 1;
4762                                 goto scsicmd_bailout;
4763                         }
4764                         bzero(data_ptr, data_bytes);
4765                         /*
4766                          * If the user supplied "-" instead of a format, he
4767                          * wants the data to be read from stdin.
4768                          */
4769                         if ((datastr != NULL)
4770                          && (datastr[0] == '-'))
4771                                 fd_data = 1;
4772                         else
4773                                 buff_encode_visit(data_ptr, data_bytes, datastr,
4774                                                   iget, &hook);
4775                         optind += hook.got;
4776                         break;
4777                 case 'r':
4778                         need_res = 1;
4779                         hook.argc = argc - optind;
4780                         hook.argv = argv + optind;
4781                         hook.got = 0;
4782                         resstr = cget(&hook, NULL);
4783                         if ((resstr != NULL) && (resstr[0] == '-'))
4784                                 fd_res = 1;
4785                         optind += hook.got;
4786                         break;
4787                 default:
4788                         break;
4789                 }
4790         }
4791
4792         /*
4793          * If fd_data is set, and we're writing to the device, we need to
4794          * read the data the user wants written from stdin.
4795          */
4796         if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) {
4797                 ssize_t amt_read;
4798                 int amt_to_read = data_bytes;
4799                 u_int8_t *buf_ptr = data_ptr;
4800
4801                 for (amt_read = 0; amt_to_read > 0;
4802                      amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
4803                         if (amt_read == -1) {
4804                                 warn("error reading data from stdin");
4805                                 error = 1;
4806                                 goto scsicmd_bailout;
4807                         }
4808                         amt_to_read -= amt_read;
4809                         buf_ptr += amt_read;
4810                 }
4811         }
4812
4813         if (arglist & CAM_ARG_ERR_RECOVER)
4814                 flags |= CAM_PASS_ERR_RECOVER;
4815
4816         /* Disable freezing the device queue */
4817         flags |= CAM_DEV_QFRZDIS;
4818
4819         if (cdb_len) {
4820                 /*
4821                  * This is taken from the SCSI-3 draft spec.
4822                  * (T10/1157D revision 0.3)
4823                  * The top 3 bits of an opcode are the group code.
4824                  * The next 5 bits are the command code.
4825                  * Group 0:  six byte commands
4826                  * Group 1:  ten byte commands
4827                  * Group 2:  ten byte commands
4828                  * Group 3:  reserved
4829                  * Group 4:  sixteen byte commands
4830                  * Group 5:  twelve byte commands
4831                  * Group 6:  vendor specific
4832                  * Group 7:  vendor specific
4833                  */
4834                 switch((cdb[0] >> 5) & 0x7) {
4835                         case 0:
4836                                 cdb_len = 6;
4837                                 break;
4838                         case 1:
4839                         case 2:
4840                                 cdb_len = 10;
4841                                 break;
4842                         case 3:
4843                         case 6:
4844                         case 7:
4845                                 /* computed by buff_encode_visit */
4846                                 break;
4847                         case 4:
4848                                 cdb_len = 16;
4849                                 break;
4850                         case 5:
4851                                 cdb_len = 12;
4852                                 break;
4853                 }
4854
4855                 /*
4856                  * We should probably use csio_build_visit or something like that
4857                  * here, but it's easier to encode arguments as you go.  The
4858                  * alternative would be skipping the CDB argument and then encoding
4859                  * it here, since we've got the data buffer argument by now.
4860                  */
4861                 bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len);
4862
4863                 cam_fill_csio(&ccb->csio,
4864                       /*retries*/ retry_count,
4865                       /*cbfcnp*/ NULL,
4866                       /*flags*/ flags,
4867                       /*tag_action*/ task_attr,
4868                       /*data_ptr*/ data_ptr,
4869                       /*dxfer_len*/ data_bytes,
4870                       /*sense_len*/ SSD_FULL_SIZE,
4871                       /*cdb_len*/ cdb_len,
4872                       /*timeout*/ timeout ? timeout : 5000);
4873         } else {
4874                 atacmd_len = 12;
4875                 bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len);
4876                 if (need_res)
4877                         ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
4878                 if (dmacmd)
4879                         ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
4880                 if (fpdmacmd)
4881                         ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
4882
4883                 cam_fill_ataio(&ccb->ataio,
4884                       /*retries*/ retry_count,
4885                       /*cbfcnp*/ NULL,
4886                       /*flags*/ flags,
4887                       /*tag_action*/ 0,
4888                       /*data_ptr*/ data_ptr,
4889                       /*dxfer_len*/ data_bytes,
4890                       /*timeout*/ timeout ? timeout : 5000);
4891         }
4892
4893         if (((retval = cam_send_ccb(device, ccb)) < 0)
4894          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
4895                 const char warnstr[] = "error sending command";
4896
4897                 if (retval < 0)
4898                         warn(warnstr);
4899                 else
4900                         warnx(warnstr);
4901
4902                 if (arglist & CAM_ARG_VERBOSE) {
4903                         cam_error_print(device, ccb, CAM_ESF_ALL,
4904                                         CAM_EPF_ALL, stderr);
4905                 }
4906
4907                 error = 1;
4908                 goto scsicmd_bailout;
4909         }
4910
4911         if (atacmd_len && need_res) {
4912                 if (fd_res == 0) {
4913                         buff_decode_visit(&ccb->ataio.res.status, 11, resstr,
4914                                           arg_put, NULL);
4915                         fprintf(stdout, "\n");
4916                 } else {
4917                         fprintf(stdout,
4918                             "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
4919                             ccb->ataio.res.status,
4920                             ccb->ataio.res.error,
4921                             ccb->ataio.res.lba_low,
4922                             ccb->ataio.res.lba_mid,
4923                             ccb->ataio.res.lba_high,
4924                             ccb->ataio.res.device,
4925                             ccb->ataio.res.lba_low_exp,
4926                             ccb->ataio.res.lba_mid_exp,
4927                             ccb->ataio.res.lba_high_exp,
4928                             ccb->ataio.res.sector_count,
4929                             ccb->ataio.res.sector_count_exp);
4930                         fflush(stdout);
4931                 }
4932         }
4933
4934         if (cdb_len)
4935                 valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid;
4936         else
4937                 valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid;
4938         if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
4939          && (arglist & CAM_ARG_CMD_IN)
4940          && (valid_bytes > 0)) {
4941                 if (fd_data == 0) {
4942                         buff_decode_visit(data_ptr, valid_bytes, datastr,
4943                                           arg_put, NULL);
4944                         fprintf(stdout, "\n");
4945                 } else {
4946                         ssize_t amt_written;
4947                         int amt_to_write = valid_bytes;
4948                         u_int8_t *buf_ptr = data_ptr;
4949
4950                         for (amt_written = 0; (amt_to_write > 0) &&
4951                              (amt_written =write(1, buf_ptr,amt_to_write))> 0;){
4952                                 amt_to_write -= amt_written;
4953                                 buf_ptr += amt_written;
4954                         }
4955                         if (amt_written == -1) {
4956                                 warn("error writing data to stdout");
4957                                 error = 1;
4958                                 goto scsicmd_bailout;
4959                         } else if ((amt_written == 0)
4960                                 && (amt_to_write > 0)) {
4961                                 warnx("only wrote %u bytes out of %u",
4962                                       valid_bytes - amt_to_write, valid_bytes);
4963                         }
4964                 }
4965         }
4966
4967 scsicmd_bailout:
4968
4969         if ((data_bytes > 0) && (data_ptr != NULL))
4970                 free(data_ptr);
4971
4972         cam_freeccb(ccb);
4973
4974         return (error);
4975 }
4976
4977 static int
4978 camdebug(int argc, char **argv, char *combinedopt)
4979 {
4980         int c, fd;
4981         path_id_t bus = CAM_BUS_WILDCARD;
4982         target_id_t target = CAM_TARGET_WILDCARD;
4983         lun_id_t lun = CAM_LUN_WILDCARD;
4984         char *tstr;
4985         union ccb ccb;
4986         int error = 0, rv;
4987
4988         bzero(&ccb, sizeof(union ccb));
4989
4990         while ((c = getopt(argc, argv, combinedopt)) != -1) {
4991                 switch(c) {
4992                 case 'I':
4993                         arglist |= CAM_ARG_DEBUG_INFO;
4994                         ccb.cdbg.flags |= CAM_DEBUG_INFO;
4995                         break;
4996                 case 'P':
4997                         arglist |= CAM_ARG_DEBUG_PERIPH;
4998                         ccb.cdbg.flags |= CAM_DEBUG_PERIPH;
4999                         break;
5000                 case 'S':
5001                         arglist |= CAM_ARG_DEBUG_SUBTRACE;
5002                         ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE;
5003                         break;
5004                 case 'T':
5005                         arglist |= CAM_ARG_DEBUG_TRACE;
5006                         ccb.cdbg.flags |= CAM_DEBUG_TRACE;
5007                         break;
5008                 case 'X':
5009                         arglist |= CAM_ARG_DEBUG_XPT;
5010                         ccb.cdbg.flags |= CAM_DEBUG_XPT;
5011                         break;
5012                 case 'c':
5013                         arglist |= CAM_ARG_DEBUG_CDB;
5014                         ccb.cdbg.flags |= CAM_DEBUG_CDB;
5015                         break;
5016                 case 'p':
5017                         arglist |= CAM_ARG_DEBUG_PROBE;
5018                         ccb.cdbg.flags |= CAM_DEBUG_PROBE;
5019                         break;
5020                 default:
5021                         break;
5022                 }
5023         }
5024
5025         argc -= optind;
5026         argv += optind;
5027
5028         if (argc <= 0) {
5029                 warnx("you must specify \"off\", \"all\" or a bus,");
5030                 warnx("bus:target, bus:target:lun or periph");
5031                 return (1);
5032         }
5033
5034         tstr = *argv;
5035         while (isspace(*tstr) && (*tstr != '\0'))
5036                 tstr++;
5037
5038         if (strncmp(tstr, "off", 3) == 0) {
5039                 ccb.cdbg.flags = CAM_DEBUG_NONE;
5040                 arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH|
5041                              CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE|
5042                              CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE);
5043         } else {
5044                 rv = parse_btl(tstr, &bus, &target, &lun, &arglist);
5045                 if (rv < 1) {
5046                         warnx("you must specify \"all\", \"off\", or a bus,");
5047                         warnx("bus:target, bus:target:lun or periph to debug");
5048                         return (1);
5049                 }
5050         }
5051
5052         if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
5053                 warnx("error opening transport layer device %s", XPT_DEVICE);
5054                 warn("%s", XPT_DEVICE);
5055                 return (1);
5056         }
5057
5058         ccb.ccb_h.func_code = XPT_DEBUG;
5059         ccb.ccb_h.path_id = bus;
5060         ccb.ccb_h.target_id = target;
5061         ccb.ccb_h.target_lun = lun;
5062
5063         if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
5064                 warn("CAMIOCOMMAND ioctl failed");
5065                 error = 1;
5066         } else {
5067                 if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==
5068                      CAM_FUNC_NOTAVAIL) {
5069                         warnx("CAM debugging not available");
5070                         warnx("you need to put options CAMDEBUG in"
5071                               " your kernel config file!");
5072                         error = 1;
5073                 } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) !=
5074                             CAM_REQ_CMP) {
5075                         warnx("XPT_DEBUG CCB failed with status %#x",
5076                               ccb.ccb_h.status);
5077                         error = 1;
5078                 } else {
5079                         if (ccb.cdbg.flags == CAM_DEBUG_NONE) {
5080                                 fprintf(stderr,
5081                                         "Debugging turned off\n");
5082                         } else {
5083                                 fprintf(stderr,
5084                                         "Debugging enabled for "
5085                                         "%d:%d:%jx\n",
5086                                         bus, target, (uintmax_t)lun);
5087                         }
5088                 }
5089         }
5090         close(fd);
5091
5092         return (error);
5093 }
5094
5095 static int
5096 tagcontrol(struct cam_device *device, int argc, char **argv,
5097            char *combinedopt)
5098 {
5099         int c;
5100         union ccb *ccb;
5101         int numtags = -1;
5102         int retval = 0;
5103         int quiet = 0;
5104         char pathstr[1024];
5105
5106         ccb = cam_getccb(device);
5107
5108         if (ccb == NULL) {
5109                 warnx("tagcontrol: error allocating ccb");
5110                 return (1);
5111         }
5112
5113         while ((c = getopt(argc, argv, combinedopt)) != -1) {
5114                 switch(c) {
5115                 case 'N':
5116                         numtags = strtol(optarg, NULL, 0);
5117                         if (numtags < 0) {
5118                                 warnx("tag count %d is < 0", numtags);
5119                                 retval = 1;
5120                                 goto tagcontrol_bailout;
5121                         }
5122                         break;
5123                 case 'q':
5124                         quiet++;
5125                         break;
5126                 default:
5127                         break;
5128                 }
5129         }
5130
5131         cam_path_string(device, pathstr, sizeof(pathstr));
5132
5133         if (numtags >= 0) {
5134                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs);
5135                 ccb->ccb_h.func_code = XPT_REL_SIMQ;
5136                 ccb->ccb_h.flags = CAM_DEV_QFREEZE;
5137                 ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS;
5138                 ccb->crs.openings = numtags;
5139
5140
5141                 if (cam_send_ccb(device, ccb) < 0) {
5142                         warn("error sending XPT_REL_SIMQ CCB");
5143                         retval = 1;
5144                         goto tagcontrol_bailout;
5145                 }
5146
5147                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5148                         warnx("XPT_REL_SIMQ CCB failed");
5149                         cam_error_print(device, ccb, CAM_ESF_ALL,
5150                                         CAM_EPF_ALL, stderr);
5151                         retval = 1;
5152                         goto tagcontrol_bailout;
5153                 }
5154
5155
5156                 if (quiet == 0)
5157                         fprintf(stdout, "%stagged openings now %d\n",
5158                                 pathstr, ccb->crs.openings);
5159         }
5160
5161         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds);
5162
5163         ccb->ccb_h.func_code = XPT_GDEV_STATS;
5164
5165         if (cam_send_ccb(device, ccb) < 0) {
5166                 warn("error sending XPT_GDEV_STATS CCB");
5167                 retval = 1;
5168                 goto tagcontrol_bailout;
5169         }
5170
5171         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5172                 warnx("XPT_GDEV_STATS CCB failed");
5173                 cam_error_print(device, ccb, CAM_ESF_ALL,
5174                                 CAM_EPF_ALL, stderr);
5175                 retval = 1;
5176                 goto tagcontrol_bailout;
5177         }
5178
5179         if (arglist & CAM_ARG_VERBOSE) {
5180                 fprintf(stdout, "%s", pathstr);
5181                 fprintf(stdout, "dev_openings  %d\n", ccb->cgds.dev_openings);
5182                 fprintf(stdout, "%s", pathstr);
5183                 fprintf(stdout, "dev_active    %d\n", ccb->cgds.dev_active);
5184                 fprintf(stdout, "%s", pathstr);
5185                 fprintf(stdout, "allocated     %d\n", ccb->cgds.allocated);
5186                 fprintf(stdout, "%s", pathstr);
5187                 fprintf(stdout, "queued        %d\n", ccb->cgds.queued);
5188                 fprintf(stdout, "%s", pathstr);
5189                 fprintf(stdout, "held          %d\n", ccb->cgds.held);
5190                 fprintf(stdout, "%s", pathstr);
5191                 fprintf(stdout, "mintags       %d\n", ccb->cgds.mintags);
5192                 fprintf(stdout, "%s", pathstr);
5193                 fprintf(stdout, "maxtags       %d\n", ccb->cgds.maxtags);
5194         } else {
5195                 if (quiet == 0) {
5196                         fprintf(stdout, "%s", pathstr);
5197                         fprintf(stdout, "device openings: ");
5198                 }
5199                 fprintf(stdout, "%d\n", ccb->cgds.dev_openings +
5200                         ccb->cgds.dev_active);
5201         }
5202
5203 tagcontrol_bailout:
5204
5205         cam_freeccb(ccb);
5206         return (retval);
5207 }
5208
5209 static void
5210 cts_print(struct cam_device *device, struct ccb_trans_settings *cts)
5211 {
5212         char pathstr[1024];
5213
5214         cam_path_string(device, pathstr, sizeof(pathstr));
5215
5216         if (cts->transport == XPORT_SPI) {
5217                 struct ccb_trans_settings_spi *spi =
5218                     &cts->xport_specific.spi;
5219
5220                 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
5221
5222                         fprintf(stdout, "%ssync parameter: %d\n", pathstr,
5223                                 spi->sync_period);
5224
5225                         if (spi->sync_offset != 0) {
5226                                 u_int freq;
5227
5228                                 freq = scsi_calc_syncsrate(spi->sync_period);
5229                                 fprintf(stdout, "%sfrequency: %d.%03dMHz\n",
5230                                         pathstr, freq / 1000, freq % 1000);
5231                         }
5232                 }
5233
5234                 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
5235                         fprintf(stdout, "%soffset: %d\n", pathstr,
5236                             spi->sync_offset);
5237                 }
5238
5239                 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
5240                         fprintf(stdout, "%sbus width: %d bits\n", pathstr,
5241                                 (0x01 << spi->bus_width) * 8);
5242                 }
5243
5244                 if (spi->valid & CTS_SPI_VALID_DISC) {
5245                         fprintf(stdout, "%sdisconnection is %s\n", pathstr,
5246                                 (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ?
5247                                 "enabled" : "disabled");
5248                 }
5249         }
5250         if (cts->transport == XPORT_FC) {
5251                 struct ccb_trans_settings_fc *fc =
5252                     &cts->xport_specific.fc;
5253
5254                 if (fc->valid & CTS_FC_VALID_WWNN)
5255                         fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr,
5256                             (long long) fc->wwnn);
5257                 if (fc->valid & CTS_FC_VALID_WWPN)
5258                         fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr,
5259                             (long long) fc->wwpn);
5260                 if (fc->valid & CTS_FC_VALID_PORT)
5261                         fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port);
5262                 if (fc->valid & CTS_FC_VALID_SPEED)
5263                         fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5264                             pathstr, fc->bitrate / 1000, fc->bitrate % 1000);
5265         }
5266         if (cts->transport == XPORT_SAS) {
5267                 struct ccb_trans_settings_sas *sas =
5268                     &cts->xport_specific.sas;
5269
5270                 if (sas->valid & CTS_SAS_VALID_SPEED)
5271                         fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n",
5272                             pathstr, sas->bitrate / 1000, sas->bitrate % 1000);
5273         }
5274         if (cts->transport == XPORT_ATA) {
5275                 struct ccb_trans_settings_pata *pata =
5276                     &cts->xport_specific.ata;
5277
5278                 if ((pata->valid & CTS_ATA_VALID_MODE) != 0) {
5279                         fprintf(stdout, "%sATA mode: %s\n", pathstr,
5280                                 ata_mode2string(pata->mode));
5281                 }
5282                 if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) {
5283                         fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5284                                 pata->atapi);
5285                 }
5286                 if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) {
5287                         fprintf(stdout, "%sPIO transaction length: %d\n",
5288                                 pathstr, pata->bytecount);
5289                 }
5290         }
5291         if (cts->transport == XPORT_SATA) {
5292                 struct ccb_trans_settings_sata *sata =
5293                     &cts->xport_specific.sata;
5294
5295                 if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) {
5296                         fprintf(stdout, "%sSATA revision: %d.x\n", pathstr,
5297                                 sata->revision);
5298                 }
5299                 if ((sata->valid & CTS_SATA_VALID_MODE) != 0) {
5300                         fprintf(stdout, "%sATA mode: %s\n", pathstr,
5301                                 ata_mode2string(sata->mode));
5302                 }
5303                 if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) {
5304                         fprintf(stdout, "%sATAPI packet length: %d\n", pathstr,
5305                                 sata->atapi);
5306                 }
5307                 if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) {
5308                         fprintf(stdout, "%sPIO transaction length: %d\n",
5309                                 pathstr, sata->bytecount);
5310                 }
5311                 if ((sata->valid & CTS_SATA_VALID_PM) != 0) {
5312                         fprintf(stdout, "%sPMP presence: %d\n", pathstr,
5313                                 sata->pm_present);
5314                 }
5315                 if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) {
5316                         fprintf(stdout, "%sNumber of tags: %d\n", pathstr,
5317                                 sata->tags);
5318                 }
5319                 if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) {
5320                         fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr,
5321                                 sata->caps);
5322                 }
5323         }
5324         if (cts->protocol == PROTO_ATA) {
5325                 struct ccb_trans_settings_ata *ata=
5326                     &cts->proto_specific.ata;
5327
5328                 if (ata->valid & CTS_ATA_VALID_TQ) {
5329                         fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5330                                 (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ?
5331                                 "enabled" : "disabled");
5332                 }
5333         }
5334         if (cts->protocol == PROTO_SCSI) {
5335                 struct ccb_trans_settings_scsi *scsi=
5336                     &cts->proto_specific.scsi;
5337
5338                 if (scsi->valid & CTS_SCSI_VALID_TQ) {
5339                         fprintf(stdout, "%stagged queueing: %s\n", pathstr,
5340                                 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ?
5341                                 "enabled" : "disabled");
5342                 }
5343         }
5344 #ifdef WITH_NVME
5345         if (cts->protocol == PROTO_NVME) {
5346                 struct ccb_trans_settings_nvme *nvmex =
5347                     &cts->xport_specific.nvme;
5348
5349                 if (nvmex->valid & CTS_NVME_VALID_SPEC) {
5350                         fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr,
5351                             NVME_MAJOR(nvmex->spec),
5352                             NVME_MINOR(nvmex->spec));
5353                 }
5354                 if (nvmex->valid & CTS_NVME_VALID_LINK) {
5355                         fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr,
5356                             nvmex->lanes, nvmex->max_lanes);
5357                         fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr,
5358                             nvmex->speed, nvmex->max_speed);
5359                 }
5360         }
5361 #endif
5362 }
5363
5364 /*
5365  * Get a path inquiry CCB for the specified device.
5366  */
5367 static int
5368 get_cpi(struct cam_device *device, struct ccb_pathinq *cpi)
5369 {
5370         union ccb *ccb;
5371         int retval = 0;
5372
5373         ccb = cam_getccb(device);
5374         if (ccb == NULL) {
5375                 warnx("get_cpi: couldn't allocate CCB");
5376                 return (1);
5377         }
5378         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi);
5379         ccb->ccb_h.func_code = XPT_PATH_INQ;
5380         if (cam_send_ccb(device, ccb) < 0) {
5381                 warn("get_cpi: error sending Path Inquiry CCB");
5382                 retval = 1;
5383                 goto get_cpi_bailout;
5384         }
5385         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5386                 if (arglist & CAM_ARG_VERBOSE)
5387                         cam_error_print(device, ccb, CAM_ESF_ALL,
5388                                         CAM_EPF_ALL, stderr);
5389                 retval = 1;
5390                 goto get_cpi_bailout;
5391         }
5392         bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq));
5393
5394 get_cpi_bailout:
5395         cam_freeccb(ccb);
5396         return (retval);
5397 }
5398
5399 /*
5400  * Get a get device CCB for the specified device.
5401  */
5402 static int
5403 get_cgd(struct cam_device *device, struct ccb_getdev *cgd)
5404 {
5405         union ccb *ccb;
5406         int retval = 0;
5407
5408         ccb = cam_getccb(device);
5409         if (ccb == NULL) {
5410                 warnx("get_cgd: couldn't allocate CCB");
5411                 return (1);
5412         }
5413         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd);
5414         ccb->ccb_h.func_code = XPT_GDEV_TYPE;
5415         if (cam_send_ccb(device, ccb) < 0) {
5416                 warn("get_cgd: error sending Get type information CCB");
5417                 retval = 1;
5418                 goto get_cgd_bailout;
5419         }
5420         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5421                 if (arglist & CAM_ARG_VERBOSE)
5422                         cam_error_print(device, ccb, CAM_ESF_ALL,
5423                                         CAM_EPF_ALL, stderr);
5424                 retval = 1;
5425                 goto get_cgd_bailout;
5426         }
5427         bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev));
5428
5429 get_cgd_bailout:
5430         cam_freeccb(ccb);
5431         return (retval);
5432 }
5433
5434 /*
5435  * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an
5436  * error.
5437  */
5438 int
5439 dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count,
5440                  int timeout, int verbosemode)
5441 {
5442         union ccb *ccb = NULL;
5443         struct scsi_vpd_supported_page_list sup_pages;
5444         int i;
5445         int retval = 0;
5446
5447         ccb = cam_getccb(dev);
5448         if (ccb == NULL) {
5449                 warn("Unable to allocate CCB");
5450                 retval = -1;
5451                 goto bailout;
5452         }
5453
5454         /* cam_getccb cleans up the header, caller has to zero the payload */
5455         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
5456
5457         bzero(&sup_pages, sizeof(sup_pages));
5458
5459         scsi_inquiry(&ccb->csio,
5460                      /*retries*/ retry_count,
5461                      /*cbfcnp*/ NULL,
5462                      /* tag_action */ MSG_SIMPLE_Q_TAG,
5463                      /* inq_buf */ (u_int8_t *)&sup_pages,
5464                      /* inq_len */ sizeof(sup_pages),
5465                      /* evpd */ 1,
5466                      /* page_code */ SVPD_SUPPORTED_PAGE_LIST,
5467                      /* sense_len */ SSD_FULL_SIZE,
5468                      /* timeout */ timeout ? timeout : 5000);
5469
5470         /* Disable freezing the device queue */
5471         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
5472
5473         if (retry_count != 0)
5474                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
5475
5476         if (cam_send_ccb(dev, ccb) < 0) {
5477                 cam_freeccb(ccb);
5478                 ccb = NULL;
5479                 retval = -1;
5480                 goto bailout;
5481         }
5482
5483         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
5484                 if (verbosemode != 0)
5485                         cam_error_print(dev, ccb, CAM_ESF_ALL,
5486                                         CAM_EPF_ALL, stderr);
5487                 retval = -1;
5488                 goto bailout;
5489         }
5490
5491         for (i = 0; i < sup_pages.length; i++) {
5492                 if (sup_pages.list[i] == page_id) {
5493                         retval = 1;
5494                         goto bailout;
5495                 }
5496         }
5497 bailout:
5498         if (ccb != NULL)
5499                 cam_freeccb(ccb);
5500
5501         return (retval);
5502 }
5503
5504 /*
5505  * devtype is filled in with the type of device.
5506  * Returns 0 for success, non-zero for failure.
5507  */
5508 int
5509 get_device_type(struct cam_device *dev, int retry_count, int timeout,
5510                     int verbosemode, camcontrol_devtype *devtype)
5511 {
5512         struct ccb_getdev cgd;
5513         int retval;
5514
5515         retval = get_cgd(dev, &cgd);
5516         if (retval != 0)
5517                 goto bailout;
5518
5519         switch (cgd.protocol) {
5520         case PROTO_SCSI:
5521                 break;
5522         case PROTO_ATA:
5523         case PROTO_ATAPI:
5524         case PROTO_SATAPM:
5525                 *devtype = CC_DT_ATA;
5526                 goto bailout;
5527                 break; /*NOTREACHED*/
5528         case PROTO_NVME:
5529                 *devtype = CC_DT_NVME;
5530                 goto bailout;
5531                 break; /*NOTREACHED*/
5532         case PROTO_MMCSD:
5533                 *devtype = CC_DT_MMCSD;
5534                 goto bailout;
5535                 break; /*NOTREACHED*/
5536         default:
5537                 *devtype = CC_DT_UNKNOWN;
5538                 goto bailout;
5539                 break; /*NOTREACHED*/
5540         }
5541
5542         if (retry_count == -1) {
5543                 /*
5544                  * For a retry count of -1, used only the cached data to avoid
5545                  * I/O to the drive. Sending the identify command to the drive
5546                  * can cause issues for SATL attachaed drives since identify is
5547                  * not an NCQ command.
5548                  */
5549                 if (cgd.ident_data.config != 0)
5550                         *devtype = CC_DT_SATL;
5551                 else
5552                         *devtype = CC_DT_SCSI;
5553         } else {
5554                 /*
5555                  * Check for the ATA Information VPD page (0x89).  If this is an
5556                  * ATA device behind a SCSI to ATA translation layer (SATL),
5557                  * this VPD page should be present.
5558                  *
5559                  * If that VPD page isn't present, or we get an error back from
5560                  * the INQUIRY command, we'll just treat it as a normal SCSI
5561                  * device.
5562                  */
5563                 retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count,
5564                     timeout, verbosemode);
5565                 if (retval == 1)
5566                         *devtype = CC_DT_SATL;
5567                 else
5568                         *devtype = CC_DT_SCSI;
5569         }
5570         retval = 0;
5571
5572 bailout:
5573         return (retval);
5574 }
5575
5576 int
5577 build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags,
5578     uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features,
5579     uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary,
5580     uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage,
5581     size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout,
5582     int is48bit, camcontrol_devtype devtype)
5583 {
5584         int retval = 0;
5585
5586         if (devtype == CC_DT_ATA) {
5587                 cam_fill_ataio(&ccb->ataio,
5588                     /*retries*/ retry_count,
5589                     /*cbfcnp*/ NULL,
5590                     /*flags*/ flags,
5591                     /*tag_action*/ tag_action,
5592                     /*data_ptr*/ data_ptr,
5593                     /*dxfer_len*/ dxfer_len,
5594                     /*timeout*/ timeout);
5595                 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5596                         ata_48bit_cmd(&ccb->ataio, command, features, lba,
5597                             sector_count);
5598                 else
5599                         ata_28bit_cmd(&ccb->ataio, command, features, lba,
5600                             sector_count);
5601
5602                 if (auxiliary != 0) {
5603                         ccb->ataio.ata_flags |= ATA_FLAG_AUX;
5604                         ccb->ataio.aux = auxiliary;
5605                 }
5606
5607                 if (ata_flags & AP_FLAG_CHK_COND)
5608                         ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT;
5609
5610                 if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA)
5611                         ccb->ataio.cmd.flags |= CAM_ATAIO_DMA;
5612                 else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA)
5613                         ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA;
5614         } else {
5615                 if (is48bit || lba > ATA_MAX_28BIT_LBA)
5616                         protocol |= AP_EXTEND;
5617
5618                 retval = scsi_ata_pass(&ccb->csio,
5619                     /*retries*/ retry_count,
5620                     /*cbfcnp*/ NULL,
5621                     /*flags*/ flags,
5622                     /*tag_action*/ tag_action,
5623                     /*protocol*/ protocol,
5624                     /*ata_flags*/ ata_flags,
5625                     /*features*/ features,
5626                     /*sector_count*/ sector_count,
5627                     /*lba*/ lba,
5628                     /*command*/ command,
5629                     /*device*/ 0,
5630                     /*icc*/ 0,
5631                     /*auxiliary*/ auxiliary,
5632                     /*control*/ 0,
5633                     /*data_ptr*/ data_ptr,
5634                     /*dxfer_len*/ dxfer_len,
5635                     /*cdb_storage*/ cdb_storage,
5636                     /*cdb_storage_len*/ cdb_storage_len,
5637                     /*minimum_cmd_size*/ 0,
5638                     /*sense_len*/ sense_len,
5639                     /*timeout*/ timeout);
5640         }
5641
5642         return (retval);
5643 }
5644
5645 /*
5646  * Returns: 0 -- success, 1 -- error, 2 -- lba truncated,
5647  *          4 -- count truncated, 6 -- lba and count truncated.
5648  */
5649 int
5650 get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error,
5651                uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status)
5652 {
5653         int retval;
5654
5655         switch (ccb->ccb_h.func_code) {
5656         case XPT_SCSI_IO: {
5657                 uint8_t opcode;
5658                 int error_code = 0, sense_key = 0, asc = 0, ascq = 0;
5659                 u_int sense_len;
5660
5661                 /*
5662                  * In this case, we have SCSI ATA PASS-THROUGH command, 12
5663                  * or 16 byte, and need to see what
5664                  */
5665                 if (ccb->ccb_h.flags & CAM_CDB_POINTER)
5666                         opcode = ccb->csio.cdb_io.cdb_ptr[0];
5667                 else
5668                         opcode = ccb->csio.cdb_io.cdb_bytes[0];
5669                 if ((opcode != ATA_PASS_12)
5670                  && (opcode != ATA_PASS_16)) {
5671                         warnx("%s: unsupported opcode %02x", __func__, opcode);
5672                         return (1);
5673                 }
5674
5675                 retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key,
5676                                                 &asc, &ascq);
5677                 /* Note: the _ccb() variant returns 0 for an error */
5678                 if (retval == 0)
5679                         return (1);
5680
5681                 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
5682                 switch (error_code) {
5683                 case SSD_DESC_CURRENT_ERROR:
5684                 case SSD_DESC_DEFERRED_ERROR: {
5685                         struct scsi_sense_data_desc *sense;
5686                         struct scsi_sense_ata_ret_desc *desc;
5687                         uint8_t *desc_ptr;
5688
5689                         sense = (struct scsi_sense_data_desc *)
5690                             &ccb->csio.sense_data;
5691
5692                         desc_ptr = scsi_find_desc(sense, sense_len,
5693                             SSD_DESC_ATA);
5694                         if (desc_ptr == NULL) {
5695                                 cam_error_print(dev, ccb, CAM_ESF_ALL,
5696                                     CAM_EPF_ALL, stderr);
5697                                 return (1);
5698                         }
5699                         desc = (struct scsi_sense_ata_ret_desc *)desc_ptr;
5700
5701                         *error = desc->error;
5702                         *count = (desc->count_15_8 << 8) |
5703                                   desc->count_7_0;
5704                         *lba = ((uint64_t)desc->lba_47_40 << 40) |
5705                                ((uint64_t)desc->lba_39_32 << 32) |
5706                                ((uint64_t)desc->lba_31_24 << 24) |
5707                                (desc->lba_23_16 << 16) |
5708                                (desc->lba_15_8  <<  8) |
5709                                 desc->lba_7_0;
5710                         *device = desc->device;
5711                         *status = desc->status;
5712
5713                         /*
5714                          * If the extend bit isn't set, the result is for a
5715                          * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte
5716                          * command without the extend bit set.  This means
5717                          * that the device is supposed to return 28-bit
5718                          * status.  The count field is only 8 bits, and the
5719                          * LBA field is only 8 bits.
5720                          */
5721                         if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){
5722                                 *count &= 0xff;
5723                                 *lba &= 0x0fffffff;
5724                         }
5725                         break;
5726                 }
5727                 case SSD_CURRENT_ERROR:
5728                 case SSD_DEFERRED_ERROR: {
5729                         uint64_t val;
5730
5731                         /*
5732                          * In my understanding of SAT-5 specification, saying:
5733                          * "without interpreting the contents of the STATUS",
5734                          * this should not happen if CK_COND was set, but it
5735                          * does at least for some devices, so try to revert.
5736                          */
5737                         if ((sense_key == SSD_KEY_ABORTED_COMMAND) &&
5738                             (asc == 0) && (ascq == 0)) {
5739                                 *status = ATA_STATUS_ERROR;
5740                                 *error = ATA_ERROR_ABORT;
5741                                 *device = 0;
5742                                 *count = 0;
5743                                 *lba = 0;
5744                                 return (0);
5745                         }
5746
5747                         if ((sense_key != SSD_KEY_RECOVERED_ERROR) ||
5748                             (asc != 0x00) || (ascq != 0x1d))
5749                                 return (1);
5750
5751                         val = 0;
5752                         scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5753                             SSD_DESC_INFO, &val, NULL);
5754                         *error = (val >> 24) & 0xff;
5755                         *status = (val >> 16) & 0xff;
5756                         *device = (val >> 8) & 0xff;
5757                         *count = val & 0xff;
5758
5759                         val = 0;
5760                         scsi_get_sense_info(&ccb->csio.sense_data, sense_len,
5761                             SSD_DESC_COMMAND, &val, NULL);
5762                         *lba = ((val >> 16) & 0xff) | (val & 0xff00) |
5763                                 ((val & 0xff) << 16);
5764
5765                         /* Report UPPER NONZERO bits as errors 2, 4 and 6. */
5766                         return ((val >> 28) & 0x06);
5767                 }
5768                 default:
5769                         return (1);
5770                 }
5771
5772                 break;
5773         }
5774         case XPT_ATA_IO: {
5775                 struct ata_res *res;
5776
5777                 /* Only some statuses return ATA result register set. */
5778                 if (cam_ccb_status(ccb) != CAM_REQ_CMP &&
5779                     cam_ccb_status(ccb) != CAM_ATA_STATUS_ERROR)
5780                         return (1);
5781
5782                 res = &ccb->ataio.res;
5783                 *error = res->error;
5784                 *status = res->status;
5785                 *device = res->device;
5786                 *count = res->sector_count;
5787                 *lba = (res->lba_high << 16) |
5788                        (res->lba_mid << 8) |
5789                        (res->lba_low);
5790                 if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
5791                         *count |= (res->sector_count_exp << 8);
5792                         *lba |= ((uint64_t)res->lba_low_exp << 24) |
5793                                 ((uint64_t)res->lba_mid_exp << 32) |
5794                                 ((uint64_t)res->lba_high_exp << 40);
5795                 } else {
5796                         *lba |= (res->device & 0xf) << 24;
5797                 }
5798                 break;
5799         }
5800         default:
5801                 return (1);
5802         }
5803         return (0);
5804 }
5805
5806 static void
5807 cpi_print(struct ccb_pathinq *cpi)
5808 {
5809         char adapter_str[1024];
5810         uint64_t i;
5811
5812         snprintf(adapter_str, sizeof(adapter_str),
5813                  "%s%d:", cpi->dev_name, cpi->unit_number);
5814
5815         fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str,
5816                 cpi->version_num);
5817
5818         for (i = 1; i < UINT8_MAX; i = i << 1) {
5819                 const char *str;
5820
5821                 if ((i & cpi->hba_inquiry) == 0)
5822                         continue;
5823
5824                 fprintf(stdout, "%s supports ", adapter_str);
5825
5826                 switch(i) {
5827                 case PI_MDP_ABLE:
5828                         str = "MDP message";
5829                         break;
5830                 case PI_WIDE_32:
5831                         str = "32 bit wide SCSI";
5832                         break;
5833                 case PI_WIDE_16:
5834                         str = "16 bit wide SCSI";
5835                         break;
5836                 case PI_SDTR_ABLE:
5837                         str = "SDTR message";
5838                         break;
5839                 case PI_LINKED_CDB:
5840                         str = "linked CDBs";
5841                         break;
5842                 case PI_TAG_ABLE:
5843                         str = "tag queue messages";
5844                         break;
5845                 case PI_SOFT_RST:
5846                         str = "soft reset alternative";
5847                         break;
5848                 case PI_SATAPM:
5849                         str = "SATA Port Multiplier";
5850                         break;
5851                 default:
5852                         str = "unknown PI bit set";
5853                         break;
5854                 }
5855                 fprintf(stdout, "%s\n", str);
5856         }
5857
5858         for (i = 1; i < UINT32_MAX; i = i << 1) {
5859                 const char *str;
5860
5861                 if ((i & cpi->hba_misc) == 0)
5862                         continue;
5863
5864                 fprintf(stdout, "%s ", adapter_str);
5865
5866                 switch(i) {
5867                 case PIM_ATA_EXT:
5868                         str = "can understand ata_ext requests";
5869                         break;
5870                 case PIM_EXTLUNS:
5871                         str = "64bit extended LUNs supported";
5872                         break;
5873                 case PIM_SCANHILO:
5874                         str = "bus scans from high ID to low ID";
5875                         break;
5876                 case PIM_NOREMOVE:
5877                         str = "removable devices not included in scan";
5878                         break;
5879                 case PIM_NOINITIATOR:
5880                         str = "initiator role not supported";
5881                         break;
5882                 case PIM_NOBUSRESET:
5883                         str = "user has disabled initial BUS RESET or"
5884                               " controller is in target/mixed mode";
5885                         break;
5886                 case PIM_NO_6_BYTE:
5887                         str = "do not send 6-byte commands";
5888                         break;
5889                 case PIM_SEQSCAN:
5890                         str = "scan bus sequentially";
5891                         break;
5892                 case PIM_UNMAPPED:
5893                         str = "unmapped I/O supported";
5894                         break;
5895                 case PIM_NOSCAN:
5896                         str = "does its own scanning";
5897                         break;
5898                 default:
5899                         str = "unknown PIM bit set";
5900                         break;
5901                 }
5902                 fprintf(stdout, "%s\n", str);
5903         }
5904
5905         for (i = 1; i < UINT16_MAX; i = i << 1) {
5906                 const char *str;
5907
5908                 if ((i & cpi->target_sprt) == 0)
5909                         continue;
5910
5911                 fprintf(stdout, "%s supports ", adapter_str);
5912                 switch(i) {
5913                 case PIT_PROCESSOR:
5914                         str = "target mode processor mode";
5915                         break;
5916                 case PIT_PHASE:
5917                         str = "target mode phase cog. mode";
5918                         break;
5919                 case PIT_DISCONNECT:
5920                         str = "disconnects in target mode";
5921                         break;
5922                 case PIT_TERM_IO:
5923                         str = "terminate I/O message in target mode";
5924                         break;
5925                 case PIT_GRP_6:
5926                         str = "group 6 commands in target mode";
5927                         break;
5928                 case PIT_GRP_7:
5929                         str = "group 7 commands in target mode";
5930                         break;
5931                 default:
5932                         str = "unknown PIT bit set";
5933                         break;
5934                 }
5935
5936                 fprintf(stdout, "%s\n", str);
5937         }
5938         fprintf(stdout, "%s HBA engine count: %d\n", adapter_str,
5939                 cpi->hba_eng_cnt);
5940         fprintf(stdout, "%s maximum target: %d\n", adapter_str,
5941                 cpi->max_target);
5942         fprintf(stdout, "%s maximum LUN: %d\n", adapter_str,
5943                 cpi->max_lun);
5944         fprintf(stdout, "%s highest path ID in subsystem: %d\n",
5945                 adapter_str, cpi->hpath_id);
5946         fprintf(stdout, "%s initiator ID: %d\n", adapter_str,
5947                 cpi->initiator_id);
5948         fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid);
5949         fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid);
5950         fprintf(stdout, "%s HBA vendor ID: 0x%04x\n",
5951             adapter_str, cpi->hba_vendor);
5952         fprintf(stdout, "%s HBA device ID: 0x%04x\n",
5953             adapter_str, cpi->hba_device);
5954         fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n",
5955             adapter_str, cpi->hba_subvendor);
5956         fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n",
5957             adapter_str, cpi->hba_subdevice);
5958         fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id);
5959         fprintf(stdout, "%s base transfer speed: ", adapter_str);
5960         if (cpi->base_transfer_speed > 1000)
5961                 fprintf(stdout, "%d.%03dMB/sec\n",
5962                         cpi->base_transfer_speed / 1000,
5963                         cpi->base_transfer_speed % 1000);
5964         else
5965                 fprintf(stdout, "%dKB/sec\n",
5966                         (cpi->base_transfer_speed % 1000) * 1000);
5967         fprintf(stdout, "%s maximum transfer size: %u bytes\n",
5968             adapter_str, cpi->maxio);
5969 }
5970
5971 static int
5972 get_print_cts(struct cam_device *device, int user_settings, int quiet,
5973               struct ccb_trans_settings *cts)
5974 {
5975         int retval;
5976         union ccb *ccb;
5977
5978         retval = 0;
5979         ccb = cam_getccb(device);
5980
5981         if (ccb == NULL) {
5982                 warnx("get_print_cts: error allocating ccb");
5983                 return (1);
5984         }
5985
5986         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
5987
5988         ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
5989
5990         if (user_settings == 0)
5991                 ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS;
5992         else
5993                 ccb->cts.type = CTS_TYPE_USER_SETTINGS;
5994
5995         if (cam_send_ccb(device, ccb) < 0) {
5996                 warn("error sending XPT_GET_TRAN_SETTINGS CCB");
5997                 retval = 1;
5998                 goto get_print_cts_bailout;
5999         }
6000
6001         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6002                 warnx("XPT_GET_TRANS_SETTINGS CCB failed");
6003                 if (arglist & CAM_ARG_VERBOSE)
6004                         cam_error_print(device, ccb, CAM_ESF_ALL,
6005                                         CAM_EPF_ALL, stderr);
6006                 retval = 1;
6007                 goto get_print_cts_bailout;
6008         }
6009
6010         if (quiet == 0)
6011                 cts_print(device, &ccb->cts);
6012
6013         if (cts != NULL)
6014                 bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings));
6015
6016 get_print_cts_bailout:
6017
6018         cam_freeccb(ccb);
6019
6020         return (retval);
6021 }
6022
6023 static int
6024 ratecontrol(struct cam_device *device, int task_attr, int retry_count,
6025             int timeout, int argc, char **argv, char *combinedopt)
6026 {
6027         int c;
6028         union ccb *ccb;
6029         int user_settings = 0;
6030         int retval = 0;
6031         int disc_enable = -1, tag_enable = -1;
6032         int mode = -1;
6033         int offset = -1;
6034         double syncrate = -1;
6035         int bus_width = -1;
6036         int quiet = 0;
6037         int change_settings = 0, send_tur = 0;
6038         struct ccb_pathinq cpi;
6039
6040         ccb = cam_getccb(device);
6041         if (ccb == NULL) {
6042                 warnx("ratecontrol: error allocating ccb");
6043                 return (1);
6044         }
6045         while ((c = getopt(argc, argv, combinedopt)) != -1) {
6046                 switch(c){
6047                 case 'a':
6048                         send_tur = 1;
6049                         break;
6050                 case 'c':
6051                         user_settings = 0;
6052                         break;
6053                 case 'D':
6054                         if (strncasecmp(optarg, "enable", 6) == 0)
6055                                 disc_enable = 1;
6056                         else if (strncasecmp(optarg, "disable", 7) == 0)
6057                                 disc_enable = 0;
6058                         else {
6059                                 warnx("-D argument \"%s\" is unknown", optarg);
6060                                 retval = 1;
6061                                 goto ratecontrol_bailout;
6062                         }
6063                         change_settings = 1;
6064                         break;
6065                 case 'M':
6066                         mode = ata_string2mode(optarg);
6067                         if (mode < 0) {
6068                                 warnx("unknown mode '%s'", optarg);
6069                                 retval = 1;
6070                                 goto ratecontrol_bailout;
6071                         }
6072                         change_settings = 1;
6073                         break;
6074                 case 'O':
6075                         offset = strtol(optarg, NULL, 0);
6076                         if (offset < 0) {
6077                                 warnx("offset value %d is < 0", offset);
6078                                 retval = 1;
6079                                 goto ratecontrol_bailout;
6080                         }
6081                         change_settings = 1;
6082                         break;
6083                 case 'q':
6084                         quiet++;
6085                         break;
6086                 case 'R':
6087                         syncrate = atof(optarg);
6088                         if (syncrate < 0) {
6089                                 warnx("sync rate %f is < 0", syncrate);
6090                                 retval = 1;
6091                                 goto ratecontrol_bailout;
6092                         }
6093                         change_settings = 1;
6094                         break;
6095                 case 'T':
6096                         if (strncasecmp(optarg, "enable", 6) == 0)
6097                                 tag_enable = 1;
6098                         else if (strncasecmp(optarg, "disable", 7) == 0)
6099                                 tag_enable = 0;
6100                         else {
6101                                 warnx("-T argument \"%s\" is unknown", optarg);
6102                                 retval = 1;
6103                                 goto ratecontrol_bailout;
6104                         }
6105                         change_settings = 1;
6106                         break;
6107                 case 'U':
6108                         user_settings = 1;
6109                         break;
6110                 case 'W':
6111                         bus_width = strtol(optarg, NULL, 0);
6112                         if (bus_width < 0) {
6113                                 warnx("bus width %d is < 0", bus_width);
6114                                 retval = 1;
6115                                 goto ratecontrol_bailout;
6116                         }
6117                         change_settings = 1;
6118                         break;
6119                 default:
6120                         break;
6121                 }
6122         }
6123         /*
6124          * Grab path inquiry information, so we can determine whether
6125          * or not the initiator is capable of the things that the user
6126          * requests.
6127          */
6128         if ((retval = get_cpi(device, &cpi)) != 0)
6129                 goto ratecontrol_bailout;
6130         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts);
6131         if (quiet == 0) {
6132                 fprintf(stdout, "%s parameters:\n",
6133                     user_settings ? "User" : "Current");
6134         }
6135         retval = get_print_cts(device, user_settings, quiet, &ccb->cts);
6136         if (retval != 0)
6137                 goto ratecontrol_bailout;
6138
6139         if (arglist & CAM_ARG_VERBOSE)
6140                 cpi_print(&cpi);
6141
6142         if (change_settings) {
6143                 int didsettings = 0;
6144                 struct ccb_trans_settings_spi *spi = NULL;
6145                 struct ccb_trans_settings_pata *pata = NULL;
6146                 struct ccb_trans_settings_sata *sata = NULL;
6147                 struct ccb_trans_settings_ata *ata = NULL;
6148                 struct ccb_trans_settings_scsi *scsi = NULL;
6149
6150                 if (ccb->cts.transport == XPORT_SPI)
6151                         spi = &ccb->cts.xport_specific.spi;
6152                 if (ccb->cts.transport == XPORT_ATA)
6153                         pata = &ccb->cts.xport_specific.ata;
6154                 if (ccb->cts.transport == XPORT_SATA)
6155                         sata = &ccb->cts.xport_specific.sata;
6156                 if (ccb->cts.protocol == PROTO_ATA)
6157                         ata = &ccb->cts.proto_specific.ata;
6158                 if (ccb->cts.protocol == PROTO_SCSI)
6159                         scsi = &ccb->cts.proto_specific.scsi;
6160                 ccb->cts.xport_specific.valid = 0;
6161                 ccb->cts.proto_specific.valid = 0;
6162                 if (spi && disc_enable != -1) {
6163                         spi->valid |= CTS_SPI_VALID_DISC;
6164                         if (disc_enable == 0)
6165                                 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
6166                         else
6167                                 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
6168                         didsettings++;
6169                 }
6170                 if (tag_enable != -1) {
6171                         if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) {
6172                                 warnx("HBA does not support tagged queueing, "
6173                                       "so you cannot modify tag settings");
6174                                 retval = 1;
6175                                 goto ratecontrol_bailout;
6176                         }
6177                         if (ata) {
6178                                 ata->valid |= CTS_SCSI_VALID_TQ;
6179                                 if (tag_enable == 0)
6180                                         ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
6181                                 else
6182                                         ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
6183                                 didsettings++;
6184                         } else if (scsi) {
6185                                 scsi->valid |= CTS_SCSI_VALID_TQ;
6186                                 if (tag_enable == 0)
6187                                         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
6188                                 else
6189                                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
6190                                 didsettings++;
6191                         }
6192                 }
6193                 if (spi && offset != -1) {
6194                         if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6195                                 warnx("HBA is not capable of changing offset");
6196                                 retval = 1;
6197                                 goto ratecontrol_bailout;
6198                         }
6199                         spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
6200                         spi->sync_offset = offset;
6201                         didsettings++;
6202                 }
6203                 if (spi && syncrate != -1) {
6204                         int prelim_sync_period;
6205
6206                         if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6207                                 warnx("HBA is not capable of changing "
6208                                       "transfer rates");
6209                                 retval = 1;
6210                                 goto ratecontrol_bailout;
6211                         }
6212                         spi->valid |= CTS_SPI_VALID_SYNC_RATE;
6213                         /*
6214                          * The sync rate the user gives us is in MHz.
6215                          * We need to translate it into KHz for this
6216                          * calculation.
6217                          */
6218                         syncrate *= 1000;
6219                         /*
6220                          * Next, we calculate a "preliminary" sync period
6221                          * in tenths of a nanosecond.
6222                          */
6223                         if (syncrate == 0)
6224                                 prelim_sync_period = 0;
6225                         else
6226                                 prelim_sync_period = 10000000 / syncrate;
6227                         spi->sync_period =
6228                                 scsi_calc_syncparam(prelim_sync_period);
6229                         didsettings++;
6230                 }
6231                 if (sata && syncrate != -1) {
6232                         if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6233                                 warnx("HBA is not capable of changing "
6234                                       "transfer rates");
6235                                 retval = 1;
6236                                 goto ratecontrol_bailout;
6237                         }
6238                         if  (!user_settings) {
6239                                 warnx("You can modify only user rate "
6240                                     "settings for SATA");
6241                                 retval = 1;
6242                                 goto ratecontrol_bailout;
6243                         }
6244                         sata->revision = ata_speed2revision(syncrate * 100);
6245                         if (sata->revision < 0) {
6246                                 warnx("Invalid rate %f", syncrate);
6247                                 retval = 1;
6248                                 goto ratecontrol_bailout;
6249                         }
6250                         sata->valid |= CTS_SATA_VALID_REVISION;
6251                         didsettings++;
6252                 }
6253                 if ((pata || sata) && mode != -1) {
6254                         if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) {
6255                                 warnx("HBA is not capable of changing "
6256                                       "transfer rates");
6257                                 retval = 1;
6258                                 goto ratecontrol_bailout;
6259                         }
6260                         if  (!user_settings) {
6261                                 warnx("You can modify only user mode "
6262                                     "settings for ATA/SATA");
6263                                 retval = 1;
6264                                 goto ratecontrol_bailout;
6265                         }
6266                         if (pata) {
6267                                 pata->mode = mode;
6268                                 pata->valid |= CTS_ATA_VALID_MODE;
6269                         } else {
6270                                 sata->mode = mode;
6271                                 sata->valid |= CTS_SATA_VALID_MODE;
6272                         }
6273                         didsettings++;
6274                 }
6275                 /*
6276                  * The bus_width argument goes like this:
6277                  * 0 == 8 bit
6278                  * 1 == 16 bit
6279                  * 2 == 32 bit
6280                  * Therefore, if you shift the number of bits given on the
6281                  * command line right by 4, you should get the correct
6282                  * number.
6283                  */
6284                 if (spi && bus_width != -1) {
6285                         /*
6286                          * We might as well validate things here with a
6287                          * decipherable error message, rather than what
6288                          * will probably be an indecipherable error message
6289                          * by the time it gets back to us.
6290                          */
6291                         if ((bus_width == 16)
6292                          && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) {
6293                                 warnx("HBA does not support 16 bit bus width");
6294                                 retval = 1;
6295                                 goto ratecontrol_bailout;
6296                         } else if ((bus_width == 32)
6297                                 && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) {
6298                                 warnx("HBA does not support 32 bit bus width");
6299                                 retval = 1;
6300                                 goto ratecontrol_bailout;
6301                         } else if ((bus_width != 8)
6302                                 && (bus_width != 16)
6303                                 && (bus_width != 32)) {
6304                                 warnx("Invalid bus width %d", bus_width);
6305                                 retval = 1;
6306                                 goto ratecontrol_bailout;
6307                         }
6308                         spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
6309                         spi->bus_width = bus_width >> 4;
6310                         didsettings++;
6311                 }
6312                 if  (didsettings == 0) {
6313                         goto ratecontrol_bailout;
6314                 }
6315                 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
6316                 if (cam_send_ccb(device, ccb) < 0) {
6317                         warn("error sending XPT_SET_TRAN_SETTINGS CCB");
6318                         retval = 1;
6319                         goto ratecontrol_bailout;
6320                 }
6321                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
6322                         warnx("XPT_SET_TRANS_SETTINGS CCB failed");
6323                         if (arglist & CAM_ARG_VERBOSE) {
6324                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6325                                                 CAM_EPF_ALL, stderr);
6326                         }
6327                         retval = 1;
6328                         goto ratecontrol_bailout;
6329                 }
6330         }
6331         if (send_tur) {
6332                 retval = testunitready(device, task_attr, retry_count, timeout,
6333                                        (arglist & CAM_ARG_VERBOSE) ? 0 : 1);
6334                 /*
6335                  * If the TUR didn't succeed, just bail.
6336                  */
6337                 if (retval != 0) {
6338                         if (quiet == 0)
6339                                 fprintf(stderr, "Test Unit Ready failed\n");
6340                         goto ratecontrol_bailout;
6341                 }
6342         }
6343         if ((change_settings || send_tur) && !quiet &&
6344             (ccb->cts.transport == XPORT_ATA ||
6345              ccb->cts.transport == XPORT_SATA || send_tur)) {
6346                 fprintf(stdout, "New parameters:\n");
6347                 retval = get_print_cts(device, user_settings, 0, NULL);
6348         }
6349
6350 ratecontrol_bailout:
6351         cam_freeccb(ccb);
6352         return (retval);
6353 }
6354
6355 static int
6356 scsiformat(struct cam_device *device, int argc, char **argv,
6357            char *combinedopt, int task_attr, int retry_count, int timeout)
6358 {
6359         union ccb *ccb;
6360         int c;
6361         int ycount = 0, quiet = 0;
6362         int error = 0, retval = 0;
6363         int use_timeout = 10800 * 1000;
6364         int immediate = 1;
6365         struct format_defect_list_header fh;
6366         u_int8_t *data_ptr = NULL;
6367         u_int32_t dxfer_len = 0;
6368         u_int8_t byte2 = 0;
6369         int num_warnings = 0;
6370         int reportonly = 0;
6371
6372         ccb = cam_getccb(device);
6373
6374         if (ccb == NULL) {
6375                 warnx("scsiformat: error allocating ccb");
6376                 return (1);
6377         }
6378
6379         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6380
6381         while ((c = getopt(argc, argv, combinedopt)) != -1) {
6382                 switch(c) {
6383                 case 'q':
6384                         quiet++;
6385                         break;
6386                 case 'r':
6387                         reportonly = 1;
6388                         break;
6389                 case 'w':
6390                         immediate = 0;
6391                         break;
6392                 case 'y':
6393                         ycount++;
6394                         break;
6395                 }
6396         }
6397
6398         if (reportonly)
6399                 goto doreport;
6400
6401         if (quiet == 0 && ycount == 0) {
6402                 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6403                         "following device:\n");
6404
6405                 error = scsidoinquiry(device, argc, argv, combinedopt,
6406                                       task_attr, retry_count, timeout);
6407
6408                 if (error != 0) {
6409                         warnx("scsiformat: error sending inquiry");
6410                         goto scsiformat_bailout;
6411                 }
6412         }
6413
6414         if (ycount == 0) {
6415                 if (!get_confirmation()) {
6416                         error = 1;
6417                         goto scsiformat_bailout;
6418                 }
6419         }
6420
6421         if (timeout != 0)
6422                 use_timeout = timeout;
6423
6424         if (quiet == 0) {
6425                 fprintf(stdout, "Current format timeout is %d seconds\n",
6426                         use_timeout / 1000);
6427         }
6428
6429         /*
6430          * If the user hasn't disabled questions and didn't specify a
6431          * timeout on the command line, ask them if they want the current
6432          * timeout.
6433          */
6434         if ((ycount == 0)
6435          && (timeout == 0)) {
6436                 char str[1024];
6437                 int new_timeout = 0;
6438
6439                 fprintf(stdout, "Enter new timeout in seconds or press\n"
6440                         "return to keep the current timeout [%d] ",
6441                         use_timeout / 1000);
6442
6443                 if (fgets(str, sizeof(str), stdin) != NULL) {
6444                         if (str[0] != '\0')
6445                                 new_timeout = atoi(str);
6446                 }
6447
6448                 if (new_timeout != 0) {
6449                         use_timeout = new_timeout * 1000;
6450                         fprintf(stdout, "Using new timeout value %d\n",
6451                                 use_timeout / 1000);
6452                 }
6453         }
6454
6455         /*
6456          * Keep this outside the if block below to silence any unused
6457          * variable warnings.
6458          */
6459         bzero(&fh, sizeof(fh));
6460
6461         /*
6462          * If we're in immediate mode, we've got to include the format
6463          * header
6464          */
6465         if (immediate != 0) {
6466                 fh.byte2 = FU_DLH_IMMED;
6467                 data_ptr = (u_int8_t *)&fh;
6468                 dxfer_len = sizeof(fh);
6469                 byte2 = FU_FMT_DATA;
6470         } else if (quiet == 0) {
6471                 fprintf(stdout, "Formatting...");
6472                 fflush(stdout);
6473         }
6474
6475         scsi_format_unit(&ccb->csio,
6476                          /* retries */ retry_count,
6477                          /* cbfcnp */ NULL,
6478                          /* tag_action */ task_attr,
6479                          /* byte2 */ byte2,
6480                          /* ileave */ 0,
6481                          /* data_ptr */ data_ptr,
6482                          /* dxfer_len */ dxfer_len,
6483                          /* sense_len */ SSD_FULL_SIZE,
6484                          /* timeout */ use_timeout);
6485
6486         /* Disable freezing the device queue */
6487         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6488
6489         if (arglist & CAM_ARG_ERR_RECOVER)
6490                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6491
6492         if (((retval = cam_send_ccb(device, ccb)) < 0)
6493          || ((immediate == 0)
6494            && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
6495                 const char errstr[] = "error sending format command";
6496
6497                 if (retval < 0)
6498                         warn(errstr);
6499                 else
6500                         warnx(errstr);
6501
6502                 if (arglist & CAM_ARG_VERBOSE) {
6503                         cam_error_print(device, ccb, CAM_ESF_ALL,
6504                                         CAM_EPF_ALL, stderr);
6505                 }
6506                 error = 1;
6507                 goto scsiformat_bailout;
6508         }
6509
6510         /*
6511          * If we ran in non-immediate mode, we already checked for errors
6512          * above and printed out any necessary information.  If we're in
6513          * immediate mode, we need to loop through and get status
6514          * information periodically.
6515          */
6516         if (immediate == 0) {
6517                 if (quiet == 0) {
6518                         fprintf(stdout, "Format Complete\n");
6519                 }
6520                 goto scsiformat_bailout;
6521         }
6522
6523 doreport:
6524         do {
6525                 cam_status status;
6526
6527                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6528
6529                 /*
6530                  * There's really no need to do error recovery or
6531                  * retries here, since we're just going to sit in a
6532                  * loop and wait for the device to finish formatting.
6533                  */
6534                 scsi_test_unit_ready(&ccb->csio,
6535                                      /* retries */ 0,
6536                                      /* cbfcnp */ NULL,
6537                                      /* tag_action */ task_attr,
6538                                      /* sense_len */ SSD_FULL_SIZE,
6539                                      /* timeout */ 5000);
6540
6541                 /* Disable freezing the device queue */
6542                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6543
6544                 retval = cam_send_ccb(device, ccb);
6545
6546                 /*
6547                  * If we get an error from the ioctl, bail out.  SCSI
6548                  * errors are expected.
6549                  */
6550                 if (retval < 0) {
6551                         warn("error sending TEST UNIT READY command");
6552                         error = 1;
6553                         goto scsiformat_bailout;
6554                 }
6555
6556                 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6557
6558                 if ((status != CAM_REQ_CMP)
6559                  && (status == CAM_SCSI_STATUS_ERROR)
6560                  && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6561                         struct scsi_sense_data *sense;
6562                         int error_code, sense_key, asc, ascq;
6563
6564                         sense = &ccb->csio.sense_data;
6565                         scsi_extract_sense_len(sense, ccb->csio.sense_len -
6566                             ccb->csio.sense_resid, &error_code, &sense_key,
6567                             &asc, &ascq, /*show_errors*/ 1);
6568
6569                         /*
6570                          * According to the SCSI-2 and SCSI-3 specs, a
6571                          * drive that is in the middle of a format should
6572                          * return NOT READY with an ASC of "logical unit
6573                          * not ready, format in progress".  The sense key
6574                          * specific bytes will then be a progress indicator.
6575                          */
6576                         if ((sense_key == SSD_KEY_NOT_READY)
6577                          && (asc == 0x04) && (ascq == 0x04)) {
6578                                 uint8_t sks[3];
6579
6580                                 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6581                                      ccb->csio.sense_resid, sks) == 0)
6582                                  && (quiet == 0)) {
6583                                         uint32_t val;
6584                                         u_int64_t percentage;
6585
6586                                         val = scsi_2btoul(&sks[1]);
6587                                         percentage = 10000ull * val;
6588
6589                                         fprintf(stdout,
6590                                                 "\rFormatting:  %ju.%02u %% "
6591                                                 "(%u/%d) done",
6592                                                 (uintmax_t)(percentage /
6593                                                 (0x10000 * 100)),
6594                                                 (unsigned)((percentage /
6595                                                 0x10000) % 100),
6596                                                 val, 0x10000);
6597                                         fflush(stdout);
6598                                 } else if ((quiet == 0)
6599                                         && (++num_warnings <= 1)) {
6600                                         warnx("Unexpected SCSI Sense Key "
6601                                               "Specific value returned "
6602                                               "during format:");
6603                                         scsi_sense_print(device, &ccb->csio,
6604                                                          stderr);
6605                                         warnx("Unable to print status "
6606                                               "information, but format will "
6607                                               "proceed.");
6608                                         warnx("will exit when format is "
6609                                               "complete");
6610                                 }
6611                                 sleep(1);
6612                         } else {
6613                                 warnx("Unexpected SCSI error during format");
6614                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6615                                                 CAM_EPF_ALL, stderr);
6616                                 error = 1;
6617                                 goto scsiformat_bailout;
6618                         }
6619
6620                 } else if (status != CAM_REQ_CMP) {
6621                         warnx("Unexpected CAM status %#x", status);
6622                         if (arglist & CAM_ARG_VERBOSE)
6623                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6624                                                 CAM_EPF_ALL, stderr);
6625                         error = 1;
6626                         goto scsiformat_bailout;
6627                 }
6628
6629         } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6630
6631         if (quiet == 0)
6632                 fprintf(stdout, "\nFormat Complete\n");
6633
6634 scsiformat_bailout:
6635
6636         cam_freeccb(ccb);
6637
6638         return (error);
6639 }
6640
6641 static int
6642 sanitize_wait_ata(struct cam_device *device, union ccb *ccb, int quiet,
6643     camcontrol_devtype devtype)
6644 {
6645         int retval;
6646         uint8_t error = 0, ata_device = 0, status = 0;
6647         uint16_t count = 0;
6648         uint64_t lba = 0;
6649         u_int val, perc;
6650
6651         do {
6652                 retval = build_ata_cmd(ccb,
6653                              /*retries*/ 0,
6654                              /*flags*/ CAM_DIR_NONE,
6655                              /*tag_action*/ MSG_SIMPLE_Q_TAG,
6656                              /*protocol*/ AP_PROTO_NON_DATA,
6657                              /*ata_flags*/ AP_FLAG_CHK_COND,
6658                              /*features*/ 0x00, /* SANITIZE STATUS EXT */
6659                              /*sector_count*/ 0,
6660                              /*lba*/ 0,
6661                              /*command*/ ATA_SANITIZE,
6662                              /*auxiliary*/ 0,
6663                              /*data_ptr*/ NULL,
6664                              /*dxfer_len*/ 0,
6665                              /*cdb_storage*/ NULL,
6666                              /*cdb_storage_len*/ 0,
6667                              /*sense_len*/ SSD_FULL_SIZE,
6668                              /*timeout*/ 10000,
6669                              /*is48bit*/ 1,
6670                              /*devtype*/ devtype);
6671                 if (retval != 0) {
6672                         warnx("%s: build_ata_cmd() failed, likely "
6673                             "programmer error", __func__);
6674                         return (1);
6675                 }
6676
6677                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6678                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
6679                 retval = cam_send_ccb(device, ccb);
6680                 if (retval != 0) {
6681                         warn("error sending SANITIZE STATUS EXT command");
6682                         return (1);
6683                 }
6684
6685                 retval = get_ata_status(device, ccb, &error, &count, &lba,
6686                     &ata_device, &status);
6687                 if (retval != 0) {
6688                         warnx("Can't get SANITIZE STATUS EXT status, "
6689                             "sanitize may still run.");
6690                         return (retval);
6691                 }
6692                 if (status & ATA_STATUS_ERROR) {
6693                         warnx("SANITIZE STATUS EXT failed, "
6694                             "sanitize may still run.");
6695                         return (1);
6696                 }
6697                 if (count & 0x4000) {
6698                         if (quiet == 0) {
6699                                 val = lba & 0xffff;
6700                                 perc = 10000 * val;
6701                                 fprintf(stdout,
6702                                     "Sanitizing: %u.%02u%% (%d/%d)\r",
6703                                     (perc / (0x10000 * 100)),
6704                                     ((perc / 0x10000) % 100),
6705                                     val, 0x10000);
6706                                 fflush(stdout);
6707                         }
6708                         sleep(1);
6709                 } else if ((count & 0x8000) == 0) {
6710                         warnx("Sanitize complete with an error.     ");
6711                         return (1);
6712                 } else
6713                         break;
6714         } while (1);
6715         return (0);
6716 }
6717
6718 static int
6719 sanitize_wait_scsi(struct cam_device *device, union ccb *ccb, int task_attr, int quiet)
6720 {
6721         int warnings = 0, retval;
6722         cam_status status;
6723         u_int val, perc;
6724
6725         do {
6726                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6727
6728                 /*
6729                  * There's really no need to do error recovery or
6730                  * retries here, since we're just going to sit in a
6731                  * loop and wait for the device to finish sanitizing.
6732                  */
6733                 scsi_test_unit_ready(&ccb->csio,
6734                                      /* retries */ 0,
6735                                      /* cbfcnp */ NULL,
6736                                      /* tag_action */ task_attr,
6737                                      /* sense_len */ SSD_FULL_SIZE,
6738                                      /* timeout */ 5000);
6739
6740                 /* Disable freezing the device queue */
6741                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
6742
6743                 retval = cam_send_ccb(device, ccb);
6744
6745                 /*
6746                  * If we get an error from the ioctl, bail out.  SCSI
6747                  * errors are expected.
6748                  */
6749                 if (retval < 0) {
6750                         warn("error sending TEST UNIT READY command");
6751                         return (1);
6752                 }
6753
6754                 status = ccb->ccb_h.status & CAM_STATUS_MASK;
6755                 if ((status == CAM_SCSI_STATUS_ERROR) &&
6756                     ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
6757                         struct scsi_sense_data *sense;
6758                         int error_code, sense_key, asc, ascq;
6759
6760                         sense = &ccb->csio.sense_data;
6761                         scsi_extract_sense_len(sense, ccb->csio.sense_len -
6762                             ccb->csio.sense_resid, &error_code, &sense_key,
6763                             &asc, &ascq, /*show_errors*/ 1);
6764
6765                         /*
6766                          * According to the SCSI-3 spec, a drive that is in the
6767                          * middle of a sanitize should return NOT READY with an
6768                          * ASC of "logical unit not ready, sanitize in
6769                          * progress". The sense key specific bytes will then
6770                          * be a progress indicator.
6771                          */
6772                         if ((sense_key == SSD_KEY_NOT_READY)
6773                          && (asc == 0x04) && (ascq == 0x1b)) {
6774                                 uint8_t sks[3];
6775
6776                                 if ((scsi_get_sks(sense, ccb->csio.sense_len -
6777                                      ccb->csio.sense_resid, sks) == 0)
6778                                  && (quiet == 0)) {
6779                                         val = scsi_2btoul(&sks[1]);
6780                                         perc = 10000 * val;
6781                                         fprintf(stdout,
6782                                             "Sanitizing: %u.%02u%% (%d/%d)\r",
6783                                             (perc / (0x10000 * 100)),
6784                                             ((perc / 0x10000) % 100),
6785                                             val, 0x10000);
6786                                         fflush(stdout);
6787                                 } else if ((quiet == 0) && (++warnings <= 1)) {
6788                                         warnx("Unexpected SCSI Sense Key "
6789                                               "Specific value returned "
6790                                               "during sanitize:");
6791                                         scsi_sense_print(device, &ccb->csio,
6792                                                          stderr);
6793                                         warnx("Unable to print status "
6794                                               "information, but sanitze will "
6795                                               "proceed.");
6796                                         warnx("will exit when sanitize is "
6797                                               "complete");
6798                                 }
6799                                 sleep(1);
6800                         } else {
6801                                 warnx("Unexpected SCSI error during sanitize");
6802                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6803                                                 CAM_EPF_ALL, stderr);
6804                                 return (1);
6805                         }
6806
6807                 } else if (status != CAM_REQ_CMP && status != CAM_REQUEUE_REQ) {
6808                         warnx("Unexpected CAM status %#x", status);
6809                         if (arglist & CAM_ARG_VERBOSE)
6810                                 cam_error_print(device, ccb, CAM_ESF_ALL,
6811                                                 CAM_EPF_ALL, stderr);
6812                         return (1);
6813                 }
6814         } while ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
6815         return (0);
6816 }
6817
6818 static int
6819 sanitize(struct cam_device *device, int argc, char **argv,
6820              char *combinedopt, int task_attr, int retry_count, int timeout)
6821 {
6822         union ccb *ccb;
6823         u_int8_t action = 0;
6824         int c;
6825         int ycount = 0, quiet = 0;
6826         int error = 0;
6827         int use_timeout;
6828         int immediate = 1;
6829         int invert = 0;
6830         int passes = 0;
6831         int ause = 0;
6832         int fd = -1;
6833         const char *pattern = NULL;
6834         u_int8_t *data_ptr = NULL;
6835         u_int32_t dxfer_len = 0;
6836         uint8_t byte2;
6837         uint16_t feature, count;
6838         uint64_t lba;
6839         int reportonly = 0;
6840         camcontrol_devtype dt;
6841
6842         /*
6843          * Get the device type, request no I/O be done to do this.
6844          */
6845         error = get_device_type(device, -1, 0, 0, &dt);
6846         if (error != 0 || (unsigned)dt > CC_DT_UNKNOWN) {
6847                 warnx("sanitize: can't get device type");
6848                 return (1);
6849         }
6850
6851         ccb = cam_getccb(device);
6852
6853         if (ccb == NULL) {
6854                 warnx("sanitize: error allocating ccb");
6855                 return (1);
6856         }
6857
6858         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
6859
6860         while ((c = getopt(argc, argv, combinedopt)) != -1) {
6861                 switch(c) {
6862                 case 'a':
6863                         if (strcasecmp(optarg, "overwrite") == 0)
6864                                 action = SSZ_SERVICE_ACTION_OVERWRITE;
6865                         else if (strcasecmp(optarg, "block") == 0)
6866                                 action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
6867                         else if (strcasecmp(optarg, "crypto") == 0)
6868                                 action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
6869                         else if (strcasecmp(optarg, "exitfailure") == 0)
6870                                 action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
6871                         else {
6872                                 warnx("invalid service operation \"%s\"",
6873                                       optarg);
6874                                 error = 1;
6875                                 goto sanitize_bailout;
6876                         }
6877                         break;
6878                 case 'c':
6879                         passes = strtol(optarg, NULL, 0);
6880                         if (passes < 1 || passes > 31) {
6881                                 warnx("invalid passes value %d", passes);
6882                                 error = 1;
6883                                 goto sanitize_bailout;
6884                         }
6885                         break;
6886                 case 'I':
6887                         invert = 1;
6888                         break;
6889                 case 'P':
6890                         pattern = optarg;
6891                         break;
6892                 case 'q':
6893                         quiet++;
6894                         break;
6895                 case 'U':
6896                         ause = 1;
6897                         break;
6898                 case 'r':
6899                         reportonly = 1;
6900                         break;
6901                 case 'w':
6902                         /* ATA supports only immediate commands. */
6903                         if (dt == CC_DT_SCSI)
6904                                 immediate = 0;
6905                         break;
6906                 case 'y':
6907                         ycount++;
6908                         break;
6909                 }
6910         }
6911
6912         if (reportonly)
6913                 goto doreport;
6914
6915         if (action == 0) {
6916                 warnx("an action is required");
6917                 error = 1;
6918                 goto sanitize_bailout;
6919         } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
6920                 struct scsi_sanitize_parameter_list *pl;
6921                 struct stat sb;
6922                 ssize_t sz, amt;
6923
6924                 if (pattern == NULL) {
6925                         warnx("overwrite action requires -P argument");
6926                         error = 1;
6927                         goto sanitize_bailout;
6928                 }
6929                 fd = open(pattern, O_RDONLY);
6930                 if (fd < 0) {
6931                         warn("cannot open pattern file %s", pattern);
6932                         error = 1;
6933                         goto sanitize_bailout;
6934                 }
6935                 if (fstat(fd, &sb) < 0) {
6936                         warn("cannot stat pattern file %s", pattern);
6937                         error = 1;
6938                         goto sanitize_bailout;
6939                 }
6940                 sz = sb.st_size;
6941                 if (sz > SSZPL_MAX_PATTERN_LENGTH) {
6942                         warnx("pattern file size exceeds maximum value %d",
6943                               SSZPL_MAX_PATTERN_LENGTH);
6944                         error = 1;
6945                         goto sanitize_bailout;
6946                 }
6947                 dxfer_len = sizeof(*pl) + sz;
6948                 data_ptr = calloc(1, dxfer_len);
6949                 if (data_ptr == NULL) {
6950                         warnx("cannot allocate parameter list buffer");
6951                         error = 1;
6952                         goto sanitize_bailout;
6953                 }
6954
6955                 amt = read(fd, data_ptr + sizeof(*pl), sz);
6956                 if (amt < 0) {
6957                         warn("cannot read pattern file");
6958                         error = 1;
6959                         goto sanitize_bailout;
6960                 } else if (amt != sz) {
6961                         warnx("short pattern file read");
6962                         error = 1;
6963                         goto sanitize_bailout;
6964                 }
6965
6966                 pl = (struct scsi_sanitize_parameter_list *)data_ptr;
6967                 if (passes == 0)
6968                         pl->byte1 = 1;
6969                 else
6970                         pl->byte1 = passes;
6971                 if (invert != 0)
6972                         pl->byte1 |= SSZPL_INVERT;
6973                 scsi_ulto2b(sz, pl->length);
6974         } else {
6975                 const char *arg;
6976
6977                 if (passes != 0)
6978                         arg = "-c";
6979                 else if (invert != 0)
6980                         arg = "-I";
6981                 else if (pattern != NULL)
6982                         arg = "-P";
6983                 else
6984                         arg = NULL;
6985                 if (arg != NULL) {
6986                         warnx("%s argument only valid with overwrite "
6987                               "operation", arg);
6988                         error = 1;
6989                         goto sanitize_bailout;
6990                 }
6991         }
6992
6993         if (quiet == 0 && ycount == 0) {
6994                 fprintf(stdout, "You are about to REMOVE ALL DATA from the "
6995                         "following device:\n");
6996
6997                 if (dt == CC_DT_SCSI) {
6998                         error = scsidoinquiry(device, argc, argv, combinedopt,
6999                                               task_attr, retry_count, timeout);
7000                 } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7001                         struct ata_params *ident_buf;
7002                         error = ata_do_identify(device, retry_count, timeout,
7003                                                 ccb, &ident_buf);
7004                         if (error == 0) {
7005                                 printf("%s%d: ", device->device_name,
7006                                     device->dev_unit_num);
7007                                 ata_print_ident(ident_buf);
7008                                 free(ident_buf);
7009                         }
7010                 } else
7011                         error = 1;
7012
7013                 if (error != 0) {
7014                         warnx("sanitize: error sending inquiry");
7015                         goto sanitize_bailout;
7016                 }
7017         }
7018
7019         if (ycount == 0) {
7020                 if (!get_confirmation()) {
7021                         error = 1;
7022                         goto sanitize_bailout;
7023                 }
7024         }
7025
7026         if (timeout != 0)
7027                 use_timeout = timeout;
7028         else
7029                 use_timeout = (immediate ? 10 : 10800) * 1000;
7030
7031         if (immediate == 0 && quiet == 0) {
7032                 fprintf(stdout, "Current sanitize timeout is %d seconds\n",
7033                         use_timeout / 1000);
7034         }
7035
7036         /*
7037          * If the user hasn't disabled questions and didn't specify a
7038          * timeout on the command line, ask them if they want the current
7039          * timeout.
7040          */
7041         if (immediate == 0 && ycount == 0 && timeout == 0) {
7042                 char str[1024];
7043                 int new_timeout = 0;
7044
7045                 fprintf(stdout, "Enter new timeout in seconds or press\n"
7046                         "return to keep the current timeout [%d] ",
7047                         use_timeout / 1000);
7048
7049                 if (fgets(str, sizeof(str), stdin) != NULL) {
7050                         if (str[0] != '\0')
7051                                 new_timeout = atoi(str);
7052                 }
7053
7054                 if (new_timeout != 0) {
7055                         use_timeout = new_timeout * 1000;
7056                         fprintf(stdout, "Using new timeout value %d\n",
7057                                 use_timeout / 1000);
7058                 }
7059         }
7060
7061         if (dt == CC_DT_SCSI) {
7062                 byte2 = action;
7063                 if (ause != 0)
7064                         byte2 |= SSZ_UNRESTRICTED_EXIT;
7065                 if (immediate != 0)
7066                         byte2 |= SSZ_IMMED;
7067                 scsi_sanitize(&ccb->csio,
7068                               /* retries */ retry_count,
7069                               /* cbfcnp */ NULL,
7070                               /* tag_action */ task_attr,
7071                               /* byte2 */ byte2,
7072                               /* control */ 0,
7073                               /* data_ptr */ data_ptr,
7074                               /* dxfer_len */ dxfer_len,
7075                               /* sense_len */ SSD_FULL_SIZE,
7076                               /* timeout */ use_timeout);
7077
7078                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7079                 if (arglist & CAM_ARG_ERR_RECOVER)
7080                         ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7081                 if (cam_send_ccb(device, ccb) < 0) {
7082                         warn("error sending sanitize command");
7083                         error = 1;
7084                         goto sanitize_bailout;
7085                 }
7086         } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7087                 if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
7088                         feature = 0x14; /* OVERWRITE EXT */
7089                         lba = 0x4F5700000000 | scsi_4btoul(data_ptr + 4);
7090                         count = (passes == 0) ? 1 : (passes >= 16) ? 0 : passes;
7091                         if (invert)
7092                                 count |= 0x80; /* INVERT PATTERN */
7093                         if (ause)
7094                                 count |= 0x10; /* FAILURE MODE */
7095                 } else if (action == SSZ_SERVICE_ACTION_BLOCK_ERASE) {
7096                         feature = 0x12; /* BLOCK ERASE EXT */
7097                         lba = 0x0000426B4572;
7098                         count = 0;
7099                         if (ause)
7100                                 count |= 0x10; /* FAILURE MODE */
7101                 } else if (action == SSZ_SERVICE_ACTION_CRYPTO_ERASE) {
7102                         feature = 0x11; /* CRYPTO SCRAMBLE EXT */
7103                         lba = 0x000043727970;
7104                         count = 0;
7105                         if (ause)
7106                                 count |= 0x10; /* FAILURE MODE */
7107                 } else if (action == SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE) {
7108                         feature = 0x00; /* SANITIZE STATUS EXT */
7109                         lba = 0;
7110                         count = 1; /* CLEAR SANITIZE OPERATION FAILED */
7111                 } else {
7112                         error = 1;
7113                         goto sanitize_bailout;
7114                 }
7115
7116                 error = ata_do_cmd(device,
7117                                    ccb,
7118                                    retry_count,
7119                                    /*flags*/CAM_DIR_NONE,
7120                                    /*protocol*/AP_PROTO_NON_DATA | AP_EXTEND,
7121                                    /*ata_flags*/0,
7122                                    /*tag_action*/MSG_SIMPLE_Q_TAG,
7123                                    /*command*/ATA_SANITIZE,
7124                                    /*features*/feature,
7125                                    /*lba*/lba,
7126                                    /*sector_count*/count,
7127                                    /*data_ptr*/NULL,
7128                                    /*dxfer_len*/0,
7129                                    /*timeout*/ use_timeout,
7130                                    /*is48bit*/1);
7131         }
7132
7133         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7134                 struct scsi_sense_data *sense;
7135                 int error_code, sense_key, asc, ascq;
7136
7137                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
7138                     CAM_SCSI_STATUS_ERROR) {
7139                         sense = &ccb->csio.sense_data;
7140                         scsi_extract_sense_len(sense, ccb->csio.sense_len -
7141                             ccb->csio.sense_resid, &error_code, &sense_key,
7142                             &asc, &ascq, /*show_errors*/ 1);
7143
7144                         if (sense_key == SSD_KEY_ILLEGAL_REQUEST &&
7145                             asc == 0x20 && ascq == 0x00)
7146                                 warnx("sanitize is not supported by "
7147                                       "this device");
7148                         else
7149                                 warnx("error sanitizing this device");
7150                 } else
7151                         warnx("error sanitizing this device");
7152
7153                 if (arglist & CAM_ARG_VERBOSE) {
7154                         cam_error_print(device, ccb, CAM_ESF_ALL,
7155                                         CAM_EPF_ALL, stderr);
7156                 }
7157                 error = 1;
7158                 goto sanitize_bailout;
7159         }
7160
7161         /*
7162          * If we ran in non-immediate mode, we already checked for errors
7163          * above and printed out any necessary information.  If we're in
7164          * immediate mode, we need to loop through and get status
7165          * information periodically.
7166          */
7167         if (immediate == 0) {
7168                 if (quiet == 0) {
7169                         fprintf(stdout, "Sanitize Complete\n");
7170                 }
7171                 goto sanitize_bailout;
7172         }
7173
7174 doreport:
7175         if (dt == CC_DT_SCSI) {
7176                 error = sanitize_wait_scsi(device, ccb, task_attr, quiet);
7177         } else if (dt == CC_DT_ATA || dt == CC_DT_SATL) {
7178                 error = sanitize_wait_ata(device, ccb, quiet, dt);
7179         } else
7180                 error = 1;
7181         if (error == 0 && quiet == 0)
7182                 fprintf(stdout, "Sanitize Complete                      \n");
7183
7184 sanitize_bailout:
7185         if (fd >= 0)
7186                 close(fd);
7187         if (data_ptr != NULL)
7188                 free(data_ptr);
7189         cam_freeccb(ccb);
7190
7191         return (error);
7192 }
7193
7194 static int
7195 scsireportluns(struct cam_device *device, int argc, char **argv,
7196                char *combinedopt, int task_attr, int retry_count, int timeout)
7197 {
7198         union ccb *ccb;
7199         int c, countonly, lunsonly;
7200         struct scsi_report_luns_data *lundata;
7201         int alloc_len;
7202         uint8_t report_type;
7203         uint32_t list_len, i, j;
7204         int retval;
7205
7206         retval = 0;
7207         lundata = NULL;
7208         report_type = RPL_REPORT_DEFAULT;
7209         ccb = cam_getccb(device);
7210
7211         if (ccb == NULL) {
7212                 warnx("%s: error allocating ccb", __func__);
7213                 return (1);
7214         }
7215
7216         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7217
7218         countonly = 0;
7219         lunsonly = 0;
7220
7221         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7222                 switch (c) {
7223                 case 'c':
7224                         countonly++;
7225                         break;
7226                 case 'l':
7227                         lunsonly++;
7228                         break;
7229                 case 'r':
7230                         if (strcasecmp(optarg, "default") == 0)
7231                                 report_type = RPL_REPORT_DEFAULT;
7232                         else if (strcasecmp(optarg, "wellknown") == 0)
7233                                 report_type = RPL_REPORT_WELLKNOWN;
7234                         else if (strcasecmp(optarg, "all") == 0)
7235                                 report_type = RPL_REPORT_ALL;
7236                         else {
7237                                 warnx("%s: invalid report type \"%s\"",
7238                                       __func__, optarg);
7239                                 retval = 1;
7240                                 goto bailout;
7241                         }
7242                         break;
7243                 default:
7244                         break;
7245                 }
7246         }
7247
7248         if ((countonly != 0)
7249          && (lunsonly != 0)) {
7250                 warnx("%s: you can only specify one of -c or -l", __func__);
7251                 retval = 1;
7252                 goto bailout;
7253         }
7254         /*
7255          * According to SPC-4, the allocation length must be at least 16
7256          * bytes -- enough for the header and one LUN.
7257          */
7258         alloc_len = sizeof(*lundata) + 8;
7259
7260 retry:
7261
7262         lundata = malloc(alloc_len);
7263
7264         if (lundata == NULL) {
7265                 warn("%s: error mallocing %d bytes", __func__, alloc_len);
7266                 retval = 1;
7267                 goto bailout;
7268         }
7269
7270         scsi_report_luns(&ccb->csio,
7271                          /*retries*/ retry_count,
7272                          /*cbfcnp*/ NULL,
7273                          /*tag_action*/ task_attr,
7274                          /*select_report*/ report_type,
7275                          /*rpl_buf*/ lundata,
7276                          /*alloc_len*/ alloc_len,
7277                          /*sense_len*/ SSD_FULL_SIZE,
7278                          /*timeout*/ timeout ? timeout : 5000);
7279
7280         /* Disable freezing the device queue */
7281         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7282
7283         if (arglist & CAM_ARG_ERR_RECOVER)
7284                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7285
7286         if (cam_send_ccb(device, ccb) < 0) {
7287                 warn("error sending REPORT LUNS command");
7288                 retval = 1;
7289                 goto bailout;
7290         }
7291
7292         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7293                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7294                 retval = 1;
7295                 goto bailout;
7296         }
7297
7298
7299         list_len = scsi_4btoul(lundata->length);
7300
7301         /*
7302          * If we need to list the LUNs, and our allocation
7303          * length was too short, reallocate and retry.
7304          */
7305         if ((countonly == 0)
7306          && (list_len > (alloc_len - sizeof(*lundata)))) {
7307                 alloc_len = list_len + sizeof(*lundata);
7308                 free(lundata);
7309                 goto retry;
7310         }
7311
7312         if (lunsonly == 0)
7313                 fprintf(stdout, "%u LUN%s found\n", list_len / 8,
7314                         ((list_len / 8) > 1) ? "s" : "");
7315
7316         if (countonly != 0)
7317                 goto bailout;
7318
7319         for (i = 0; i < (list_len / 8); i++) {
7320                 int no_more;
7321
7322                 no_more = 0;
7323                 for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) {
7324                         if (j != 0)
7325                                 fprintf(stdout, ",");
7326                         switch (lundata->luns[i].lundata[j] &
7327                                 RPL_LUNDATA_ATYP_MASK) {
7328                         case RPL_LUNDATA_ATYP_PERIPH:
7329                                 if ((lundata->luns[i].lundata[j] &
7330                                     RPL_LUNDATA_PERIPH_BUS_MASK) != 0)
7331                                         fprintf(stdout, "%d:",
7332                                                 lundata->luns[i].lundata[j] &
7333                                                 RPL_LUNDATA_PERIPH_BUS_MASK);
7334                                 else if ((j == 0)
7335                                       && ((lundata->luns[i].lundata[j+2] &
7336                                           RPL_LUNDATA_PERIPH_BUS_MASK) == 0))
7337                                         no_more = 1;
7338
7339                                 fprintf(stdout, "%d",
7340                                         lundata->luns[i].lundata[j+1]);
7341                                 break;
7342                         case RPL_LUNDATA_ATYP_FLAT: {
7343                                 uint8_t tmplun[2];
7344                                 tmplun[0] = lundata->luns[i].lundata[j] &
7345                                         RPL_LUNDATA_FLAT_LUN_MASK;
7346                                 tmplun[1] = lundata->luns[i].lundata[j+1];
7347
7348                                 fprintf(stdout, "%d", scsi_2btoul(tmplun));
7349                                 no_more = 1;
7350                                 break;
7351                         }
7352                         case RPL_LUNDATA_ATYP_LUN:
7353                                 fprintf(stdout, "%d:%d:%d",
7354                                         (lundata->luns[i].lundata[j+1] &
7355                                         RPL_LUNDATA_LUN_BUS_MASK) >> 5,
7356                                         lundata->luns[i].lundata[j] &
7357                                         RPL_LUNDATA_LUN_TARG_MASK,
7358                                         lundata->luns[i].lundata[j+1] &
7359                                         RPL_LUNDATA_LUN_LUN_MASK);
7360                                 break;
7361                         case RPL_LUNDATA_ATYP_EXTLUN: {
7362                                 int field_len_code, eam_code;
7363
7364                                 eam_code = lundata->luns[i].lundata[j] &
7365                                         RPL_LUNDATA_EXT_EAM_MASK;
7366                                 field_len_code = (lundata->luns[i].lundata[j] &
7367                                         RPL_LUNDATA_EXT_LEN_MASK) >> 4;
7368
7369                                 if ((eam_code == RPL_LUNDATA_EXT_EAM_WK)
7370                                  && (field_len_code == 0x00)) {
7371                                         fprintf(stdout, "%d",
7372                                                 lundata->luns[i].lundata[j+1]);
7373                                 } else if ((eam_code ==
7374                                             RPL_LUNDATA_EXT_EAM_NOT_SPEC)
7375                                         && (field_len_code == 0x03)) {
7376                                         uint8_t tmp_lun[8];
7377
7378                                         /*
7379                                          * This format takes up all 8 bytes.
7380                                          * If we aren't starting at offset 0,
7381                                          * that's a bug.
7382                                          */
7383                                         if (j != 0) {
7384                                                 fprintf(stdout, "Invalid "
7385                                                         "offset %d for "
7386                                                         "Extended LUN not "
7387                                                         "specified format", j);
7388                                                 no_more = 1;
7389                                                 break;
7390                                         }
7391                                         bzero(tmp_lun, sizeof(tmp_lun));
7392                                         bcopy(&lundata->luns[i].lundata[j+1],
7393                                               &tmp_lun[1], sizeof(tmp_lun) - 1);
7394                                         fprintf(stdout, "%#jx",
7395                                                (intmax_t)scsi_8btou64(tmp_lun));
7396                                         no_more = 1;
7397                                 } else {
7398                                         fprintf(stderr, "Unknown Extended LUN"
7399                                                 "Address method %#x, length "
7400                                                 "code %#x", eam_code,
7401                                                 field_len_code);
7402                                         no_more = 1;
7403                                 }
7404                                 break;
7405                         }
7406                         default:
7407                                 fprintf(stderr, "Unknown LUN address method "
7408                                         "%#x\n", lundata->luns[i].lundata[0] &
7409                                         RPL_LUNDATA_ATYP_MASK);
7410                                 break;
7411                         }
7412                         /*
7413                          * For the flat addressing method, there are no
7414                          * other levels after it.
7415                          */
7416                         if (no_more != 0)
7417                                 break;
7418                 }
7419                 fprintf(stdout, "\n");
7420         }
7421
7422 bailout:
7423
7424         cam_freeccb(ccb);
7425
7426         free(lundata);
7427
7428         return (retval);
7429 }
7430
7431 static int
7432 scsireadcapacity(struct cam_device *device, int argc, char **argv,
7433                  char *combinedopt, int task_attr, int retry_count, int timeout)
7434 {
7435         union ccb *ccb;
7436         int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly;
7437         struct scsi_read_capacity_data rcap;
7438         struct scsi_read_capacity_data_long rcaplong;
7439         uint64_t maxsector;
7440         uint32_t block_len;
7441         int retval;
7442         int c;
7443
7444         blocksizeonly = 0;
7445         humanize = 0;
7446         longonly = 0;
7447         numblocks = 0;
7448         quiet = 0;
7449         sizeonly = 0;
7450         baseten = 0;
7451         retval = 0;
7452
7453         ccb = cam_getccb(device);
7454
7455         if (ccb == NULL) {
7456                 warnx("%s: error allocating ccb", __func__);
7457                 return (1);
7458         }
7459
7460         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
7461
7462         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7463                 switch (c) {
7464                 case 'b':
7465                         blocksizeonly++;
7466                         break;
7467                 case 'h':
7468                         humanize++;
7469                         baseten = 0;
7470                         break;
7471                 case 'H':
7472                         humanize++;
7473                         baseten++;
7474                         break;
7475                 case 'l':
7476                         longonly++;
7477                         break;
7478                 case 'N':
7479                         numblocks++;
7480                         break;
7481                 case 'q':
7482                         quiet++;
7483                         break;
7484                 case 's':
7485                         sizeonly++;
7486                         break;
7487                 default:
7488                         break;
7489                 }
7490         }
7491
7492         if ((blocksizeonly != 0)
7493          && (numblocks != 0)) {
7494                 warnx("%s: you can only specify one of -b or -N", __func__);
7495                 retval = 1;
7496                 goto bailout;
7497         }
7498
7499         if ((blocksizeonly != 0)
7500          && (sizeonly != 0)) {
7501                 warnx("%s: you can only specify one of -b or -s", __func__);
7502                 retval = 1;
7503                 goto bailout;
7504         }
7505
7506         if ((humanize != 0)
7507          && (quiet != 0)) {
7508                 warnx("%s: you can only specify one of -h/-H or -q", __func__);
7509                 retval = 1;
7510                 goto bailout;
7511         }
7512
7513         if ((humanize != 0)
7514          && (blocksizeonly != 0)) {
7515                 warnx("%s: you can only specify one of -h/-H or -b", __func__);
7516                 retval = 1;
7517                 goto bailout;
7518         }
7519
7520         if (longonly != 0)
7521                 goto long_only;
7522
7523         scsi_read_capacity(&ccb->csio,
7524                            /*retries*/ retry_count,
7525                            /*cbfcnp*/ NULL,
7526                            /*tag_action*/ task_attr,
7527                            &rcap,
7528                            SSD_FULL_SIZE,
7529                            /*timeout*/ timeout ? timeout : 5000);
7530
7531         /* Disable freezing the device queue */
7532         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7533
7534         if (arglist & CAM_ARG_ERR_RECOVER)
7535                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7536
7537         if (cam_send_ccb(device, ccb) < 0) {
7538                 warn("error sending READ CAPACITY command");
7539                 retval = 1;
7540                 goto bailout;
7541         }
7542
7543         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7544                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7545                 retval = 1;
7546                 goto bailout;
7547         }
7548
7549         maxsector = scsi_4btoul(rcap.addr);
7550         block_len = scsi_4btoul(rcap.length);
7551
7552         /*
7553          * A last block of 2^32-1 means that the true capacity is over 2TB,
7554          * and we need to issue the long READ CAPACITY to get the real
7555          * capacity.  Otherwise, we're all set.
7556          */
7557         if (maxsector != 0xffffffff)
7558                 goto do_print;
7559
7560 long_only:
7561         scsi_read_capacity_16(&ccb->csio,
7562                               /*retries*/ retry_count,
7563                               /*cbfcnp*/ NULL,
7564                               /*tag_action*/ task_attr,
7565                               /*lba*/ 0,
7566                               /*reladdr*/ 0,
7567                               /*pmi*/ 0,
7568                               /*rcap_buf*/ (uint8_t *)&rcaplong,
7569                               /*rcap_buf_len*/ sizeof(rcaplong),
7570                               /*sense_len*/ SSD_FULL_SIZE,
7571                               /*timeout*/ timeout ? timeout : 5000);
7572
7573         /* Disable freezing the device queue */
7574         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
7575
7576         if (arglist & CAM_ARG_ERR_RECOVER)
7577                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
7578
7579         if (cam_send_ccb(device, ccb) < 0) {
7580                 warn("error sending READ CAPACITY (16) command");
7581                 retval = 1;
7582                 goto bailout;
7583         }
7584
7585         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
7586                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
7587                 retval = 1;
7588                 goto bailout;
7589         }
7590
7591         maxsector = scsi_8btou64(rcaplong.addr);
7592         block_len = scsi_4btoul(rcaplong.length);
7593
7594 do_print:
7595         if (blocksizeonly == 0) {
7596                 /*
7597                  * Humanize implies !quiet, and also implies numblocks.
7598                  */
7599                 if (humanize != 0) {
7600                         char tmpstr[6];
7601                         int64_t tmpbytes;
7602                         int ret;
7603
7604                         tmpbytes = (maxsector + 1) * block_len;
7605                         ret = humanize_number(tmpstr, sizeof(tmpstr),
7606                                               tmpbytes, "", HN_AUTOSCALE,
7607                                               HN_B | HN_DECIMAL |
7608                                               ((baseten != 0) ?
7609                                               HN_DIVISOR_1000 : 0));
7610                         if (ret == -1) {
7611                                 warnx("%s: humanize_number failed!", __func__);
7612                                 retval = 1;
7613                                 goto bailout;
7614                         }
7615                         fprintf(stdout, "Device Size: %s%s", tmpstr,
7616                                 (sizeonly == 0) ?  ", " : "\n");
7617                 } else if (numblocks != 0) {
7618                         fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7619                                 "Blocks: " : "", (uintmax_t)maxsector + 1,
7620                                 (sizeonly == 0) ? ", " : "\n");
7621                 } else {
7622                         fprintf(stdout, "%s%ju%s", (quiet == 0) ?
7623                                 "Last Block: " : "", (uintmax_t)maxsector,
7624                                 (sizeonly == 0) ? ", " : "\n");
7625                 }
7626         }
7627         if (sizeonly == 0)
7628                 fprintf(stdout, "%s%u%s\n", (quiet == 0) ?
7629                         "Block Length: " : "", block_len, (quiet == 0) ?
7630                         " bytes" : "");
7631 bailout:
7632         cam_freeccb(ccb);
7633
7634         return (retval);
7635 }
7636
7637 static int
7638 smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7639        int retry_count, int timeout)
7640 {
7641         int c, error = 0;
7642         union ccb *ccb;
7643         uint8_t *smp_request = NULL, *smp_response = NULL;
7644         int request_size = 0, response_size = 0;
7645         int fd_request = 0, fd_response = 0;
7646         char *datastr = NULL;
7647         struct get_hook hook;
7648         int retval;
7649         int flags = 0;
7650
7651         /*
7652          * Note that at the moment we don't support sending SMP CCBs to
7653          * devices that aren't probed by CAM.
7654          */
7655         ccb = cam_getccb(device);
7656         if (ccb == NULL) {
7657                 warnx("%s: error allocating CCB", __func__);
7658                 return (1);
7659         }
7660
7661         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
7662
7663         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7664                 switch (c) {
7665                 case 'R':
7666                         arglist |= CAM_ARG_CMD_IN;
7667                         response_size = strtol(optarg, NULL, 0);
7668                         if (response_size <= 0) {
7669                                 warnx("invalid number of response bytes %d",
7670                                       response_size);
7671                                 error = 1;
7672                                 goto smpcmd_bailout;
7673                         }
7674                         hook.argc = argc - optind;
7675                         hook.argv = argv + optind;
7676                         hook.got = 0;
7677                         optind++;
7678                         datastr = cget(&hook, NULL);
7679                         /*
7680                          * If the user supplied "-" instead of a format, he
7681                          * wants the data to be written to stdout.
7682                          */
7683                         if ((datastr != NULL)
7684                          && (datastr[0] == '-'))
7685                                 fd_response = 1;
7686
7687                         smp_response = (u_int8_t *)malloc(response_size);
7688                         if (smp_response == NULL) {
7689                                 warn("can't malloc memory for SMP response");
7690                                 error = 1;
7691                                 goto smpcmd_bailout;
7692                         }
7693                         break;
7694                 case 'r':
7695                         arglist |= CAM_ARG_CMD_OUT;
7696                         request_size = strtol(optarg, NULL, 0);
7697                         if (request_size <= 0) {
7698                                 warnx("invalid number of request bytes %d",
7699                                       request_size);
7700                                 error = 1;
7701                                 goto smpcmd_bailout;
7702                         }
7703                         hook.argc = argc - optind;
7704                         hook.argv = argv + optind;
7705                         hook.got = 0;
7706                         datastr = cget(&hook, NULL);
7707                         smp_request = (u_int8_t *)malloc(request_size);
7708                         if (smp_request == NULL) {
7709                                 warn("can't malloc memory for SMP request");
7710                                 error = 1;
7711                                 goto smpcmd_bailout;
7712                         }
7713                         bzero(smp_request, request_size);
7714                         /*
7715                          * If the user supplied "-" instead of a format, he
7716                          * wants the data to be read from stdin.
7717                          */
7718                         if ((datastr != NULL)
7719                          && (datastr[0] == '-'))
7720                                 fd_request = 1;
7721                         else
7722                                 buff_encode_visit(smp_request, request_size,
7723                                                   datastr,
7724                                                   iget, &hook);
7725                         optind += hook.got;
7726                         break;
7727                 default:
7728                         break;
7729                 }
7730         }
7731
7732         /*
7733          * If fd_data is set, and we're writing to the device, we need to
7734          * read the data the user wants written from stdin.
7735          */
7736         if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) {
7737                 ssize_t amt_read;
7738                 int amt_to_read = request_size;
7739                 u_int8_t *buf_ptr = smp_request;
7740
7741                 for (amt_read = 0; amt_to_read > 0;
7742                      amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) {
7743                         if (amt_read == -1) {
7744                                 warn("error reading data from stdin");
7745                                 error = 1;
7746                                 goto smpcmd_bailout;
7747                         }
7748                         amt_to_read -= amt_read;
7749                         buf_ptr += amt_read;
7750                 }
7751         }
7752
7753         if (((arglist & CAM_ARG_CMD_IN) == 0)
7754          || ((arglist & CAM_ARG_CMD_OUT) == 0)) {
7755                 warnx("%s: need both the request (-r) and response (-R) "
7756                       "arguments", __func__);
7757                 error = 1;
7758                 goto smpcmd_bailout;
7759         }
7760
7761         flags |= CAM_DEV_QFRZDIS;
7762
7763         cam_fill_smpio(&ccb->smpio,
7764                        /*retries*/ retry_count,
7765                        /*cbfcnp*/ NULL,
7766                        /*flags*/ flags,
7767                        /*smp_request*/ smp_request,
7768                        /*smp_request_len*/ request_size,
7769                        /*smp_response*/ smp_response,
7770                        /*smp_response_len*/ response_size,
7771                        /*timeout*/ timeout ? timeout : 5000);
7772
7773         ccb->smpio.flags = SMP_FLAG_NONE;
7774
7775         if (((retval = cam_send_ccb(device, ccb)) < 0)
7776          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7777                 const char warnstr[] = "error sending command";
7778
7779                 if (retval < 0)
7780                         warn(warnstr);
7781                 else
7782                         warnx(warnstr);
7783
7784                 if (arglist & CAM_ARG_VERBOSE) {
7785                         cam_error_print(device, ccb, CAM_ESF_ALL,
7786                                         CAM_EPF_ALL, stderr);
7787                 }
7788         }
7789
7790         if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
7791          && (response_size > 0)) {
7792                 if (fd_response == 0) {
7793                         buff_decode_visit(smp_response, response_size,
7794                                           datastr, arg_put, NULL);
7795                         fprintf(stdout, "\n");
7796                 } else {
7797                         ssize_t amt_written;
7798                         int amt_to_write = response_size;
7799                         u_int8_t *buf_ptr = smp_response;
7800
7801                         for (amt_written = 0; (amt_to_write > 0) &&
7802                              (amt_written = write(STDOUT_FILENO, buf_ptr,
7803                                                   amt_to_write)) > 0;){
7804                                 amt_to_write -= amt_written;
7805                                 buf_ptr += amt_written;
7806                         }
7807                         if (amt_written == -1) {
7808                                 warn("error writing data to stdout");
7809                                 error = 1;
7810                                 goto smpcmd_bailout;
7811                         } else if ((amt_written == 0)
7812                                 && (amt_to_write > 0)) {
7813                                 warnx("only wrote %u bytes out of %u",
7814                                       response_size - amt_to_write,
7815                                       response_size);
7816                         }
7817                 }
7818         }
7819 smpcmd_bailout:
7820         if (ccb != NULL)
7821                 cam_freeccb(ccb);
7822
7823         if (smp_request != NULL)
7824                 free(smp_request);
7825
7826         if (smp_response != NULL)
7827                 free(smp_response);
7828
7829         return (error);
7830 }
7831
7832 static int
7833 mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt,
7834        int retry_count, int timeout)
7835 {
7836         int c, error = 0;
7837         union ccb *ccb;
7838         int32_t mmc_opcode = 0, mmc_arg = 0;
7839         int32_t mmc_flags = -1;
7840         int retval;
7841         int is_write = 0;
7842         int is_bw_4 = 0, is_bw_1 = 0;
7843         int is_highspeed = 0, is_stdspeed = 0;
7844         int is_info_request = 0;
7845         int flags = 0;
7846         uint8_t mmc_data_byte = 0;
7847
7848         /* For IO_RW_EXTENDED command */
7849         uint8_t *mmc_data = NULL;
7850         struct mmc_data mmc_d;
7851         int mmc_data_len = 0;
7852
7853         /*
7854          * Note that at the moment we don't support sending SMP CCBs to
7855          * devices that aren't probed by CAM.
7856          */
7857         ccb = cam_getccb(device);
7858         if (ccb == NULL) {
7859                 warnx("%s: error allocating CCB", __func__);
7860                 return (1);
7861         }
7862
7863         bzero(&(&ccb->ccb_h)[1],
7864               sizeof(union ccb) - sizeof(struct ccb_hdr));
7865
7866         while ((c = getopt(argc, argv, combinedopt)) != -1) {
7867                 switch (c) {
7868                 case '4':
7869                         is_bw_4 = 1;
7870                         break;
7871                 case '1':
7872                         is_bw_1 = 1;
7873                         break;
7874                 case 'S':
7875                         if (!strcmp(optarg, "high"))
7876                                 is_highspeed = 1;
7877                         else
7878                                 is_stdspeed = 1;
7879                         break;
7880                 case 'I':
7881                         is_info_request = 1;
7882                         break;
7883                 case 'c':
7884                         mmc_opcode = strtol(optarg, NULL, 0);
7885                         if (mmc_opcode < 0) {
7886                                 warnx("invalid MMC opcode %d",
7887                                       mmc_opcode);
7888                                 error = 1;
7889                                 goto mmccmd_bailout;
7890                         }
7891                         break;
7892                 case 'a':
7893                         mmc_arg = strtol(optarg, NULL, 0);
7894                         if (mmc_arg < 0) {
7895                                 warnx("invalid MMC arg %d",
7896                                       mmc_arg);
7897                                 error = 1;
7898                                 goto mmccmd_bailout;
7899                         }
7900                         break;
7901                 case 'f':
7902                         mmc_flags = strtol(optarg, NULL, 0);
7903                         if (mmc_flags < 0) {
7904                                 warnx("invalid MMC flags %d",
7905                                       mmc_flags);
7906                                 error = 1;
7907                                 goto mmccmd_bailout;
7908                         }
7909                         break;
7910                 case 'l':
7911                         mmc_data_len = strtol(optarg, NULL, 0);
7912                         if (mmc_data_len <= 0) {
7913                                 warnx("invalid MMC data len %d",
7914                                       mmc_data_len);
7915                                 error = 1;
7916                                 goto mmccmd_bailout;
7917                         }
7918                         break;
7919                 case 'W':
7920                         is_write = 1;
7921                         break;
7922                 case 'b':
7923                         mmc_data_byte = strtol(optarg, NULL, 0);
7924                         break;
7925                 default:
7926                         break;
7927                 }
7928         }
7929         flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */
7930
7931         /* If flags are left default, supply the right flags */
7932         if (mmc_flags < 0)
7933                 switch (mmc_opcode) {
7934                 case MMC_GO_IDLE_STATE:
7935                         mmc_flags = MMC_RSP_NONE | MMC_CMD_BC;
7936                         break;
7937                 case IO_SEND_OP_COND:
7938                         mmc_flags = MMC_RSP_R4;
7939                         break;
7940                 case SD_SEND_RELATIVE_ADDR:
7941                         mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR;
7942                         break;
7943                 case MMC_SELECT_CARD:
7944                         mmc_flags = MMC_RSP_R1B | MMC_CMD_AC;
7945                         mmc_arg = mmc_arg << 16;
7946                         break;
7947                 case SD_IO_RW_DIRECT:
7948                         mmc_flags = MMC_RSP_R5 | MMC_CMD_AC;
7949                         mmc_arg = SD_IO_RW_ADR(mmc_arg);
7950                         if (is_write)
7951                                 mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte);
7952                         break;
7953                 case SD_IO_RW_EXTENDED:
7954                         mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC;
7955                         mmc_arg = SD_IO_RW_ADR(mmc_arg);
7956                         int len_arg = mmc_data_len;
7957                         if (mmc_data_len == 512)
7958                                 len_arg = 0;
7959
7960                         // Byte mode
7961                         mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7962                         // Block mode
7963 //                        mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR;
7964                         break;
7965                 default:
7966                         mmc_flags = MMC_RSP_R1;
7967                         break;
7968                 }
7969
7970         // Switch bus width instead of sending IO command
7971         if (is_bw_4 || is_bw_1) {
7972                 struct ccb_trans_settings_mmc *cts;
7973                 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7974                 ccb->ccb_h.flags = 0;
7975                 cts = &ccb->cts.proto_specific.mmc;
7976                 cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1;
7977                 cts->ios_valid = MMC_BW;
7978                 if (((retval = cam_send_ccb(device, ccb)) < 0)
7979                     || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7980                         warn("Error sending command");
7981                 } else {
7982                         printf("Parameters set OK\n");
7983                 }
7984                 cam_freeccb(ccb);
7985                 return (retval);
7986         }
7987
7988         // Switch bus speed instead of sending IO command
7989         if (is_stdspeed || is_highspeed) {
7990                 struct ccb_trans_settings_mmc *cts;
7991                 ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
7992                 ccb->ccb_h.flags = 0;
7993                 cts = &ccb->cts.proto_specific.mmc;
7994                 cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal;
7995                 cts->ios_valid = MMC_BT;
7996                 if (((retval = cam_send_ccb(device, ccb)) < 0)
7997                     || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
7998                         warn("Error sending command");
7999                 } else {
8000                         printf("Speed set OK (HS: %d)\n", is_highspeed);
8001                 }
8002                 cam_freeccb(ccb);
8003                 return (retval);
8004         }
8005
8006         // Get information about controller and its settings
8007         if (is_info_request) {
8008                 ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
8009                 ccb->ccb_h.flags = 0;
8010                 struct ccb_trans_settings_mmc *cts;
8011                 cts = &ccb->cts.proto_specific.mmc;
8012                 if (((retval = cam_send_ccb(device, ccb)) < 0)
8013                     || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8014                         warn("Error sending command");
8015                         return (retval);
8016                 }
8017                 printf("Host controller information\n");
8018                 printf("Host OCR: 0x%x\n", cts->host_ocr);
8019                 printf("Min frequency: %u KHz\n", cts->host_f_min / 1000);
8020                 printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000);
8021                 printf("Supported bus width: ");
8022                 if (cts->host_caps & MMC_CAP_4_BIT_DATA)
8023                         printf(" 4 bit\n");
8024                 if (cts->host_caps & MMC_CAP_8_BIT_DATA)
8025                         printf(" 8 bit\n");
8026                 printf("\nCurrent settings:\n");
8027                 printf("Bus width: ");
8028                 switch (cts->ios.bus_width) {
8029                 case bus_width_1:
8030                         printf("1 bit\n");
8031                         break;
8032                 case bus_width_4:
8033                         printf("4 bit\n");
8034                         break;
8035                 case bus_width_8:
8036                         printf("8 bit\n");
8037                         break;
8038                 }
8039                 printf("Freq: %d.%03d MHz%s\n",
8040                        cts->ios.clock / 1000000,
8041                        (cts->ios.clock / 1000) % 1000,
8042                        cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : "");
8043                 return (0);
8044         }
8045
8046         printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags);
8047
8048         if (mmc_data_len > 0) {
8049                 flags |= CAM_DIR_IN;
8050                 mmc_data = malloc(mmc_data_len);
8051                 memset(mmc_data, 0, mmc_data_len);
8052                 memset(&mmc_d, 0, sizeof(mmc_d));
8053                 mmc_d.len = mmc_data_len;
8054                 mmc_d.data = mmc_data;
8055                 mmc_d.flags = MMC_DATA_READ;
8056         } else flags |= CAM_DIR_NONE;
8057
8058         cam_fill_mmcio(&ccb->mmcio,
8059                        /*retries*/ retry_count,
8060                        /*cbfcnp*/ NULL,
8061                        /*flags*/ flags,
8062                        /*mmc_opcode*/ mmc_opcode,
8063                        /*mmc_arg*/ mmc_arg,
8064                        /*mmc_flags*/ mmc_flags,
8065                        /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL,
8066                        /*timeout*/ timeout ? timeout : 5000);
8067
8068         if (((retval = cam_send_ccb(device, ccb)) < 0)
8069          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8070                 const char warnstr[] = "error sending command";
8071
8072                 if (retval < 0)
8073                         warn(warnstr);
8074                 else
8075                         warnx(warnstr);
8076
8077                 if (arglist & CAM_ARG_VERBOSE) {
8078                         cam_error_print(device, ccb, CAM_ESF_ALL,
8079                                         CAM_EPF_ALL, stderr);
8080                 }
8081         }
8082
8083         if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) {
8084                 printf("MMCIO: error %d, %08x %08x %08x %08x\n",
8085                        ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0],
8086                        ccb->mmcio.cmd.resp[1],
8087                        ccb->mmcio.cmd.resp[2],
8088                        ccb->mmcio.cmd.resp[3]);
8089
8090                 switch (mmc_opcode) {
8091                 case SD_IO_RW_DIRECT:
8092                         printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n",
8093                                SD_R5_DATA(ccb->mmcio.cmd.resp),
8094                                (ccb->mmcio.cmd.resp[0] >> 12) & 0x3);
8095                         break;
8096                 case SD_IO_RW_EXTENDED:
8097                         printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len);
8098                         hexdump(mmc_data, mmc_data_len, NULL, 0);
8099                         break;
8100                 case SD_SEND_RELATIVE_ADDR:
8101                         printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16);
8102                         break;
8103                 default:
8104                         printf("No command-specific decoder for CMD %d\n", mmc_opcode);
8105                 }
8106         }
8107 mmccmd_bailout:
8108         if (ccb != NULL)
8109                 cam_freeccb(ccb);
8110
8111         if (mmc_data_len > 0 && mmc_data != NULL)
8112                 free(mmc_data);
8113
8114         return (error);
8115 }
8116
8117 static int
8118 smpreportgeneral(struct cam_device *device, int argc, char **argv,
8119                  char *combinedopt, int retry_count, int timeout)
8120 {
8121         union ccb *ccb;
8122         struct smp_report_general_request *request = NULL;
8123         struct smp_report_general_response *response = NULL;
8124         struct sbuf *sb = NULL;
8125         int error = 0;
8126         int c, long_response = 0;
8127         int retval;
8128
8129         /*
8130          * Note that at the moment we don't support sending SMP CCBs to
8131          * devices that aren't probed by CAM.
8132          */
8133         ccb = cam_getccb(device);
8134         if (ccb == NULL) {
8135                 warnx("%s: error allocating CCB", __func__);
8136                 return (1);
8137         }
8138
8139         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8140
8141         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8142                 switch (c) {
8143                 case 'l':
8144                         long_response = 1;
8145                         break;
8146                 default:
8147                         break;
8148                 }
8149         }
8150         request = malloc(sizeof(*request));
8151         if (request == NULL) {
8152                 warn("%s: unable to allocate %zd bytes", __func__,
8153                      sizeof(*request));
8154                 error = 1;
8155                 goto bailout;
8156         }
8157
8158         response = malloc(sizeof(*response));
8159         if (response == NULL) {
8160                 warn("%s: unable to allocate %zd bytes", __func__,
8161                      sizeof(*response));
8162                 error = 1;
8163                 goto bailout;
8164         }
8165
8166 try_long:
8167         smp_report_general(&ccb->smpio,
8168                            retry_count,
8169                            /*cbfcnp*/ NULL,
8170                            request,
8171                            /*request_len*/ sizeof(*request),
8172                            (uint8_t *)response,
8173                            /*response_len*/ sizeof(*response),
8174                            /*long_response*/ long_response,
8175                            timeout);
8176
8177         if (((retval = cam_send_ccb(device, ccb)) < 0)
8178          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8179                 const char warnstr[] = "error sending command";
8180
8181                 if (retval < 0)
8182                         warn(warnstr);
8183                 else
8184                         warnx(warnstr);
8185
8186                 if (arglist & CAM_ARG_VERBOSE) {
8187                         cam_error_print(device, ccb, CAM_ESF_ALL,
8188                                         CAM_EPF_ALL, stderr);
8189                 }
8190                 error = 1;
8191                 goto bailout;
8192         }
8193
8194         /*
8195          * If the device supports the long response bit, try again and see
8196          * if we can get all of the data.
8197          */
8198         if ((response->long_response & SMP_RG_LONG_RESPONSE)
8199          && (long_response == 0)) {
8200                 ccb->ccb_h.status = CAM_REQ_INPROG;
8201                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8202                 long_response = 1;
8203                 goto try_long;
8204         }
8205
8206         /*
8207          * XXX KDM detect and decode SMP errors here.
8208          */
8209         sb = sbuf_new_auto();
8210         if (sb == NULL) {
8211                 warnx("%s: error allocating sbuf", __func__);
8212                 goto bailout;
8213         }
8214
8215         smp_report_general_sbuf(response, sizeof(*response), sb);
8216
8217         if (sbuf_finish(sb) != 0) {
8218                 warnx("%s: sbuf_finish", __func__);
8219                 goto bailout;
8220         }
8221
8222         printf("%s", sbuf_data(sb));
8223
8224 bailout:
8225         if (ccb != NULL)
8226                 cam_freeccb(ccb);
8227
8228         if (request != NULL)
8229                 free(request);
8230
8231         if (response != NULL)
8232                 free(response);
8233
8234         if (sb != NULL)
8235                 sbuf_delete(sb);
8236
8237         return (error);
8238 }
8239
8240 static struct camcontrol_opts phy_ops[] = {
8241         {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL},
8242         {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL},
8243         {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL},
8244         {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL},
8245         {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL},
8246         {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL},
8247         {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL},
8248         {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL},
8249         {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL},
8250         {NULL, 0, 0, NULL}
8251 };
8252
8253 static int
8254 smpphycontrol(struct cam_device *device, int argc, char **argv,
8255               char *combinedopt, int retry_count, int timeout)
8256 {
8257         union ccb *ccb;
8258         struct smp_phy_control_request *request = NULL;
8259         struct smp_phy_control_response *response = NULL;
8260         int long_response = 0;
8261         int retval = 0;
8262         int phy = -1;
8263         uint32_t phy_operation = SMP_PC_PHY_OP_NOP;
8264         int phy_op_set = 0;
8265         uint64_t attached_dev_name = 0;
8266         int dev_name_set = 0;
8267         uint32_t min_plr = 0, max_plr = 0;
8268         uint32_t pp_timeout_val = 0;
8269         int slumber_partial = 0;
8270         int set_pp_timeout_val = 0;
8271         int c;
8272
8273         /*
8274          * Note that at the moment we don't support sending SMP CCBs to
8275          * devices that aren't probed by CAM.
8276          */
8277         ccb = cam_getccb(device);
8278         if (ccb == NULL) {
8279                 warnx("%s: error allocating CCB", __func__);
8280                 return (1);
8281         }
8282
8283         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8284
8285         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8286                 switch (c) {
8287                 case 'a':
8288                 case 'A':
8289                 case 's':
8290                 case 'S': {
8291                         int enable = -1;
8292
8293                         if (strcasecmp(optarg, "enable") == 0)
8294                                 enable = 1;
8295                         else if (strcasecmp(optarg, "disable") == 0)
8296                                 enable = 2;
8297                         else {
8298                                 warnx("%s: Invalid argument %s", __func__,
8299                                       optarg);
8300                                 retval = 1;
8301                                 goto bailout;
8302                         }
8303                         switch (c) {
8304                         case 's':
8305                                 slumber_partial |= enable <<
8306                                                    SMP_PC_SAS_SLUMBER_SHIFT;
8307                                 break;
8308                         case 'S':
8309                                 slumber_partial |= enable <<
8310                                                    SMP_PC_SAS_PARTIAL_SHIFT;
8311                                 break;
8312                         case 'a':
8313                                 slumber_partial |= enable <<
8314                                                    SMP_PC_SATA_SLUMBER_SHIFT;
8315                                 break;
8316                         case 'A':
8317                                 slumber_partial |= enable <<
8318                                                    SMP_PC_SATA_PARTIAL_SHIFT;
8319                                 break;
8320                         default:
8321                                 warnx("%s: programmer error", __func__);
8322                                 retval = 1;
8323                                 goto bailout;
8324                                 break; /*NOTREACHED*/
8325                         }
8326                         break;
8327                 }
8328                 case 'd':
8329                         attached_dev_name = (uintmax_t)strtoumax(optarg,
8330                                                                  NULL,0);
8331                         dev_name_set = 1;
8332                         break;
8333                 case 'l':
8334                         long_response = 1;
8335                         break;
8336                 case 'm':
8337                         /*
8338                          * We don't do extensive checking here, so this
8339                          * will continue to work when new speeds come out.
8340                          */
8341                         min_plr = strtoul(optarg, NULL, 0);
8342                         if ((min_plr == 0)
8343                          || (min_plr > 0xf)) {
8344                                 warnx("%s: invalid link rate %x",
8345                                       __func__, min_plr);
8346                                 retval = 1;
8347                                 goto bailout;
8348                         }
8349                         break;
8350                 case 'M':
8351                         /*
8352                          * We don't do extensive checking here, so this
8353                          * will continue to work when new speeds come out.
8354                          */
8355                         max_plr = strtoul(optarg, NULL, 0);
8356                         if ((max_plr == 0)
8357                          || (max_plr > 0xf)) {
8358                                 warnx("%s: invalid link rate %x",
8359                                       __func__, max_plr);
8360                                 retval = 1;
8361                                 goto bailout;
8362                         }
8363                         break;
8364                 case 'o': {
8365                         camcontrol_optret optreturn;
8366                         cam_argmask argnums;
8367                         const char *subopt;
8368
8369                         if (phy_op_set != 0) {
8370                                 warnx("%s: only one phy operation argument "
8371                                       "(-o) allowed", __func__);
8372                                 retval = 1;
8373                                 goto bailout;
8374                         }
8375
8376                         phy_op_set = 1;
8377
8378                         /*
8379                          * Allow the user to specify the phy operation
8380                          * numerically, as well as with a name.  This will
8381                          * future-proof it a bit, so options that are added
8382                          * in future specs can be used.
8383                          */
8384                         if (isdigit(optarg[0])) {
8385                                 phy_operation = strtoul(optarg, NULL, 0);
8386                                 if ((phy_operation == 0)
8387                                  || (phy_operation > 0xff)) {
8388                                         warnx("%s: invalid phy operation %#x",
8389                                               __func__, phy_operation);
8390                                         retval = 1;
8391                                         goto bailout;
8392                                 }
8393                                 break;
8394                         }
8395                         optreturn = getoption(phy_ops, optarg, &phy_operation,
8396                                               &argnums, &subopt);
8397
8398                         if (optreturn == CC_OR_AMBIGUOUS) {
8399                                 warnx("%s: ambiguous option %s", __func__,
8400                                       optarg);
8401                                 usage(0);
8402                                 retval = 1;
8403                                 goto bailout;
8404                         } else if (optreturn == CC_OR_NOT_FOUND) {
8405                                 warnx("%s: option %s not found", __func__,
8406                                       optarg);
8407                                 usage(0);
8408                                 retval = 1;
8409                                 goto bailout;
8410                         }
8411                         break;
8412                 }
8413                 case 'p':
8414                         phy = atoi(optarg);
8415                         break;
8416                 case 'T':
8417                         pp_timeout_val = strtoul(optarg, NULL, 0);
8418                         if (pp_timeout_val > 15) {
8419                                 warnx("%s: invalid partial pathway timeout "
8420                                       "value %u, need a value less than 16",
8421                                       __func__, pp_timeout_val);
8422                                 retval = 1;
8423                                 goto bailout;
8424                         }
8425                         set_pp_timeout_val = 1;
8426                         break;
8427                 default:
8428                         break;
8429                 }
8430         }
8431
8432         if (phy == -1) {
8433                 warnx("%s: a PHY (-p phy) argument is required",__func__);
8434                 retval = 1;
8435                 goto bailout;
8436         }
8437
8438         if (((dev_name_set != 0)
8439           && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME))
8440          || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME)
8441           && (dev_name_set == 0))) {
8442                 warnx("%s: -d name and -o setdevname arguments both "
8443                       "required to set device name", __func__);
8444                 retval = 1;
8445                 goto bailout;
8446         }
8447
8448         request = malloc(sizeof(*request));
8449         if (request == NULL) {
8450                 warn("%s: unable to allocate %zd bytes", __func__,
8451                      sizeof(*request));
8452                 retval = 1;
8453                 goto bailout;
8454         }
8455
8456         response = malloc(sizeof(*response));
8457         if (response == NULL) {
8458                 warn("%s: unable to allocate %zd bytes", __func__,
8459                      sizeof(*response));
8460                 retval = 1;
8461                 goto bailout;
8462         }
8463
8464         smp_phy_control(&ccb->smpio,
8465                         retry_count,
8466                         /*cbfcnp*/ NULL,
8467                         request,
8468                         sizeof(*request),
8469                         (uint8_t *)response,
8470                         sizeof(*response),
8471                         long_response,
8472                         /*expected_exp_change_count*/ 0,
8473                         phy,
8474                         phy_operation,
8475                         (set_pp_timeout_val != 0) ? 1 : 0,
8476                         attached_dev_name,
8477                         min_plr,
8478                         max_plr,
8479                         slumber_partial,
8480                         pp_timeout_val,
8481                         timeout);
8482
8483         if (((retval = cam_send_ccb(device, ccb)) < 0)
8484          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8485                 const char warnstr[] = "error sending command";
8486
8487                 if (retval < 0)
8488                         warn(warnstr);
8489                 else
8490                         warnx(warnstr);
8491
8492                 if (arglist & CAM_ARG_VERBOSE) {
8493                         /*
8494                          * Use CAM_EPF_NORMAL so we only get one line of
8495                          * SMP command decoding.
8496                          */
8497                         cam_error_print(device, ccb, CAM_ESF_ALL,
8498                                         CAM_EPF_NORMAL, stderr);
8499                 }
8500                 retval = 1;
8501                 goto bailout;
8502         }
8503
8504         /* XXX KDM print out something here for success? */
8505 bailout:
8506         if (ccb != NULL)
8507                 cam_freeccb(ccb);
8508
8509         if (request != NULL)
8510                 free(request);
8511
8512         if (response != NULL)
8513                 free(response);
8514
8515         return (retval);
8516 }
8517
8518 static int
8519 smpmaninfo(struct cam_device *device, int argc, char **argv,
8520            char *combinedopt, int retry_count, int timeout)
8521 {
8522         union ccb *ccb;
8523         struct smp_report_manuf_info_request request;
8524         struct smp_report_manuf_info_response response;
8525         struct sbuf *sb = NULL;
8526         int long_response = 0;
8527         int retval = 0;
8528         int c;
8529
8530         /*
8531          * Note that at the moment we don't support sending SMP CCBs to
8532          * devices that aren't probed by CAM.
8533          */
8534         ccb = cam_getccb(device);
8535         if (ccb == NULL) {
8536                 warnx("%s: error allocating CCB", __func__);
8537                 return (1);
8538         }
8539
8540         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8541
8542         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8543                 switch (c) {
8544                 case 'l':
8545                         long_response = 1;
8546                         break;
8547                 default:
8548                         break;
8549                 }
8550         }
8551         bzero(&request, sizeof(request));
8552         bzero(&response, sizeof(response));
8553
8554         smp_report_manuf_info(&ccb->smpio,
8555                               retry_count,
8556                               /*cbfcnp*/ NULL,
8557                               &request,
8558                               sizeof(request),
8559                               (uint8_t *)&response,
8560                               sizeof(response),
8561                               long_response,
8562                               timeout);
8563
8564         if (((retval = cam_send_ccb(device, ccb)) < 0)
8565          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8566                 const char warnstr[] = "error sending command";
8567
8568                 if (retval < 0)
8569                         warn(warnstr);
8570                 else
8571                         warnx(warnstr);
8572
8573                 if (arglist & CAM_ARG_VERBOSE) {
8574                         cam_error_print(device, ccb, CAM_ESF_ALL,
8575                                         CAM_EPF_ALL, stderr);
8576                 }
8577                 retval = 1;
8578                 goto bailout;
8579         }
8580
8581         sb = sbuf_new_auto();
8582         if (sb == NULL) {
8583                 warnx("%s: error allocating sbuf", __func__);
8584                 goto bailout;
8585         }
8586
8587         smp_report_manuf_info_sbuf(&response, sizeof(response), sb);
8588
8589         if (sbuf_finish(sb) != 0) {
8590                 warnx("%s: sbuf_finish", __func__);
8591                 goto bailout;
8592         }
8593
8594         printf("%s", sbuf_data(sb));
8595
8596 bailout:
8597
8598         if (ccb != NULL)
8599                 cam_freeccb(ccb);
8600
8601         if (sb != NULL)
8602                 sbuf_delete(sb);
8603
8604         return (retval);
8605 }
8606
8607 static int
8608 getdevid(struct cam_devitem *item)
8609 {
8610         int retval = 0;
8611         union ccb *ccb = NULL;
8612
8613         struct cam_device *dev;
8614
8615         dev = cam_open_btl(item->dev_match.path_id,
8616                            item->dev_match.target_id,
8617                            item->dev_match.target_lun, O_RDWR, NULL);
8618
8619         if (dev == NULL) {
8620                 warnx("%s", cam_errbuf);
8621                 retval = 1;
8622                 goto bailout;
8623         }
8624
8625         item->device_id_len = 0;
8626
8627         ccb = cam_getccb(dev);
8628         if (ccb == NULL) {
8629                 warnx("%s: error allocating CCB", __func__);
8630                 retval = 1;
8631                 goto bailout;
8632         }
8633
8634         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai);
8635
8636         /*
8637          * On the first try, we just probe for the size of the data, and
8638          * then allocate that much memory and try again.
8639          */
8640 retry:
8641         ccb->ccb_h.func_code = XPT_DEV_ADVINFO;
8642         ccb->ccb_h.flags = CAM_DIR_IN;
8643         ccb->cdai.flags = CDAI_FLAG_NONE;
8644         ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID;
8645         ccb->cdai.bufsiz = item->device_id_len;
8646         if (item->device_id_len != 0)
8647                 ccb->cdai.buf = (uint8_t *)item->device_id;
8648
8649         if (cam_send_ccb(dev, ccb) < 0) {
8650                 warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__);
8651                 retval = 1;
8652                 goto bailout;
8653         }
8654
8655         if (ccb->ccb_h.status != CAM_REQ_CMP) {
8656                 warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status);
8657                 retval = 1;
8658                 goto bailout;
8659         }
8660
8661         if (item->device_id_len == 0) {
8662                 /*
8663                  * This is our first time through.  Allocate the buffer,
8664                  * and then go back to get the data.
8665                  */
8666                 if (ccb->cdai.provsiz == 0) {
8667                         warnx("%s: invalid .provsiz field returned with "
8668                              "XPT_GDEV_ADVINFO CCB", __func__);
8669                         retval = 1;
8670                         goto bailout;
8671                 }
8672                 item->device_id_len = ccb->cdai.provsiz;
8673                 item->device_id = malloc(item->device_id_len);
8674                 if (item->device_id == NULL) {
8675                         warn("%s: unable to allocate %d bytes", __func__,
8676                              item->device_id_len);
8677                         retval = 1;
8678                         goto bailout;
8679                 }
8680                 ccb->ccb_h.status = CAM_REQ_INPROG;
8681                 goto retry;
8682         }
8683
8684 bailout:
8685         if (dev != NULL)
8686                 cam_close_device(dev);
8687
8688         if (ccb != NULL)
8689                 cam_freeccb(ccb);
8690
8691         return (retval);
8692 }
8693
8694 /*
8695  * XXX KDM merge this code with getdevtree()?
8696  */
8697 static int
8698 buildbusdevlist(struct cam_devlist *devlist)
8699 {
8700         union ccb ccb;
8701         int bufsize, fd = -1;
8702         struct dev_match_pattern *patterns;
8703         struct cam_devitem *item = NULL;
8704         int skip_device = 0;
8705         int retval = 0;
8706
8707         if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
8708                 warn("couldn't open %s", XPT_DEVICE);
8709                 return (1);
8710         }
8711
8712         bzero(&ccb, sizeof(union ccb));
8713
8714         ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
8715         ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
8716         ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
8717
8718         ccb.ccb_h.func_code = XPT_DEV_MATCH;
8719         bufsize = sizeof(struct dev_match_result) * 100;
8720         ccb.cdm.match_buf_len = bufsize;
8721         ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
8722         if (ccb.cdm.matches == NULL) {
8723                 warnx("can't malloc memory for matches");
8724                 close(fd);
8725                 return (1);
8726         }
8727         ccb.cdm.num_matches = 0;
8728         ccb.cdm.num_patterns = 2;
8729         ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) *
8730                 ccb.cdm.num_patterns;
8731
8732         patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len);
8733         if (patterns == NULL) {
8734                 warnx("can't malloc memory for patterns");
8735                 retval = 1;
8736                 goto bailout;
8737         }
8738
8739         ccb.cdm.patterns = patterns;
8740         bzero(patterns, ccb.cdm.pattern_buf_len);
8741
8742         patterns[0].type = DEV_MATCH_DEVICE;
8743         patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH;
8744         patterns[0].pattern.device_pattern.path_id = devlist->path_id;
8745         patterns[1].type = DEV_MATCH_PERIPH;
8746         patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH;
8747         patterns[1].pattern.periph_pattern.path_id = devlist->path_id;
8748
8749         /*
8750          * We do the ioctl multiple times if necessary, in case there are
8751          * more than 100 nodes in the EDT.
8752          */
8753         do {
8754                 unsigned int i;
8755
8756                 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
8757                         warn("error sending CAMIOCOMMAND ioctl");
8758                         retval = 1;
8759                         goto bailout;
8760                 }
8761
8762                 if ((ccb.ccb_h.status != CAM_REQ_CMP)
8763                  || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
8764                     && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
8765                         warnx("got CAM error %#x, CDM error %d\n",
8766                               ccb.ccb_h.status, ccb.cdm.status);
8767                         retval = 1;
8768                         goto bailout;
8769                 }
8770
8771                 for (i = 0; i < ccb.cdm.num_matches; i++) {
8772                         switch (ccb.cdm.matches[i].type) {
8773                         case DEV_MATCH_DEVICE: {
8774                                 struct device_match_result *dev_result;
8775
8776                                 dev_result =
8777                                      &ccb.cdm.matches[i].result.device_result;
8778
8779                                 if (dev_result->flags &
8780                                     DEV_RESULT_UNCONFIGURED) {
8781                                         skip_device = 1;
8782                                         break;
8783                                 } else
8784                                         skip_device = 0;
8785
8786                                 item = malloc(sizeof(*item));
8787                                 if (item == NULL) {
8788                                         warn("%s: unable to allocate %zd bytes",
8789                                              __func__, sizeof(*item));
8790                                         retval = 1;
8791                                         goto bailout;
8792                                 }
8793                                 bzero(item, sizeof(*item));
8794                                 bcopy(dev_result, &item->dev_match,
8795                                       sizeof(*dev_result));
8796                                 STAILQ_INSERT_TAIL(&devlist->dev_queue, item,
8797                                                    links);
8798
8799                                 if (getdevid(item) != 0) {
8800                                         retval = 1;
8801                                         goto bailout;
8802                                 }
8803                                 break;
8804                         }
8805                         case DEV_MATCH_PERIPH: {
8806                                 struct periph_match_result *periph_result;
8807
8808                                 periph_result =
8809                                       &ccb.cdm.matches[i].result.periph_result;
8810
8811                                 if (skip_device != 0)
8812                                         break;
8813                                 item->num_periphs++;
8814                                 item->periph_matches = realloc(
8815                                         item->periph_matches,
8816                                         item->num_periphs *
8817                                         sizeof(struct periph_match_result));
8818                                 if (item->periph_matches == NULL) {
8819                                         warn("%s: error allocating periph "
8820                                              "list", __func__);
8821                                         retval = 1;
8822                                         goto bailout;
8823                                 }
8824                                 bcopy(periph_result, &item->periph_matches[
8825                                       item->num_periphs - 1],
8826                                       sizeof(*periph_result));
8827                                 break;
8828                         }
8829                         default:
8830                                 fprintf(stderr, "%s: unexpected match "
8831                                         "type %d\n", __func__,
8832                                         ccb.cdm.matches[i].type);
8833                                 retval = 1;
8834                                 goto bailout;
8835                                 break; /*NOTREACHED*/
8836                         }
8837                 }
8838         } while ((ccb.ccb_h.status == CAM_REQ_CMP)
8839                 && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
8840 bailout:
8841
8842         if (fd != -1)
8843                 close(fd);
8844
8845         free(patterns);
8846
8847         free(ccb.cdm.matches);
8848
8849         if (retval != 0)
8850                 freebusdevlist(devlist);
8851
8852         return (retval);
8853 }
8854
8855 static void
8856 freebusdevlist(struct cam_devlist *devlist)
8857 {
8858         struct cam_devitem *item, *item2;
8859
8860         STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) {
8861                 STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem,
8862                               links);
8863                 free(item->device_id);
8864                 free(item->periph_matches);
8865                 free(item);
8866         }
8867 }
8868
8869 static struct cam_devitem *
8870 findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr)
8871 {
8872         struct cam_devitem *item;
8873
8874         STAILQ_FOREACH(item, &devlist->dev_queue, links) {
8875                 struct scsi_vpd_id_descriptor *idd;
8876
8877                 /*
8878                  * XXX KDM look for LUN IDs as well?
8879                  */
8880                 idd = scsi_get_devid(item->device_id,
8881                                            item->device_id_len,
8882                                            scsi_devid_is_sas_target);
8883                 if (idd == NULL)
8884                         continue;
8885
8886                 if (scsi_8btou64(idd->identifier) == sasaddr)
8887                         return (item);
8888         }
8889
8890         return (NULL);
8891 }
8892
8893 static int
8894 smpphylist(struct cam_device *device, int argc, char **argv,
8895            char *combinedopt, int retry_count, int timeout)
8896 {
8897         struct smp_report_general_request *rgrequest = NULL;
8898         struct smp_report_general_response *rgresponse = NULL;
8899         struct smp_discover_request *disrequest = NULL;
8900         struct smp_discover_response *disresponse = NULL;
8901         struct cam_devlist devlist;
8902         union ccb *ccb;
8903         int long_response = 0;
8904         int num_phys = 0;
8905         int quiet = 0;
8906         int retval;
8907         int i, c;
8908
8909         /*
8910          * Note that at the moment we don't support sending SMP CCBs to
8911          * devices that aren't probed by CAM.
8912          */
8913         ccb = cam_getccb(device);
8914         if (ccb == NULL) {
8915                 warnx("%s: error allocating CCB", __func__);
8916                 return (1);
8917         }
8918
8919         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
8920         STAILQ_INIT(&devlist.dev_queue);
8921
8922         rgrequest = malloc(sizeof(*rgrequest));
8923         if (rgrequest == NULL) {
8924                 warn("%s: unable to allocate %zd bytes", __func__,
8925                      sizeof(*rgrequest));
8926                 retval = 1;
8927                 goto bailout;
8928         }
8929
8930         rgresponse = malloc(sizeof(*rgresponse));
8931         if (rgresponse == NULL) {
8932                 warn("%s: unable to allocate %zd bytes", __func__,
8933                      sizeof(*rgresponse));
8934                 retval = 1;
8935                 goto bailout;
8936         }
8937
8938         while ((c = getopt(argc, argv, combinedopt)) != -1) {
8939                 switch (c) {
8940                 case 'l':
8941                         long_response = 1;
8942                         break;
8943                 case 'q':
8944                         quiet = 1;
8945                         break;
8946                 default:
8947                         break;
8948                 }
8949         }
8950
8951         smp_report_general(&ccb->smpio,
8952                            retry_count,
8953                            /*cbfcnp*/ NULL,
8954                            rgrequest,
8955                            /*request_len*/ sizeof(*rgrequest),
8956                            (uint8_t *)rgresponse,
8957                            /*response_len*/ sizeof(*rgresponse),
8958                            /*long_response*/ long_response,
8959                            timeout);
8960
8961         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
8962
8963         if (((retval = cam_send_ccb(device, ccb)) < 0)
8964          || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) {
8965                 const char warnstr[] = "error sending command";
8966
8967                 if (retval < 0)
8968                         warn(warnstr);
8969                 else
8970                         warnx(warnstr);
8971
8972                 if (arglist & CAM_ARG_VERBOSE) {
8973                         cam_error_print(device, ccb, CAM_ESF_ALL,
8974                                         CAM_EPF_ALL, stderr);
8975                 }
8976                 retval = 1;
8977                 goto bailout;
8978         }
8979
8980         num_phys = rgresponse->num_phys;
8981
8982         if (num_phys == 0) {
8983                 if (quiet == 0)
8984                         fprintf(stdout, "%s: No Phys reported\n", __func__);
8985                 retval = 1;
8986                 goto bailout;
8987         }
8988
8989         devlist.path_id = device->path_id;
8990
8991         retval = buildbusdevlist(&devlist);
8992         if (retval != 0)
8993                 goto bailout;
8994
8995         if (quiet == 0) {
8996                 fprintf(stdout, "%d PHYs:\n", num_phys);
8997                 fprintf(stdout, "PHY  Attached SAS Address\n");
8998         }
8999
9000         disrequest = malloc(sizeof(*disrequest));
9001         if (disrequest == NULL) {
9002                 warn("%s: unable to allocate %zd bytes", __func__,
9003                      sizeof(*disrequest));
9004                 retval = 1;
9005                 goto bailout;
9006         }
9007
9008         disresponse = malloc(sizeof(*disresponse));
9009         if (disresponse == NULL) {
9010                 warn("%s: unable to allocate %zd bytes", __func__,
9011                      sizeof(*disresponse));
9012                 retval = 1;
9013                 goto bailout;
9014         }
9015
9016         for (i = 0; i < num_phys; i++) {
9017                 struct cam_devitem *item;
9018                 struct device_match_result *dev_match;
9019                 char vendor[16], product[48], revision[16];
9020                 char tmpstr[256];
9021                 int j;
9022
9023                 CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio);
9024
9025                 ccb->ccb_h.status = CAM_REQ_INPROG;
9026                 ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9027
9028                 smp_discover(&ccb->smpio,
9029                              retry_count,
9030                              /*cbfcnp*/ NULL,
9031                              disrequest,
9032                              sizeof(*disrequest),
9033                              (uint8_t *)disresponse,
9034                              sizeof(*disresponse),
9035                              long_response,
9036                              /*ignore_zone_group*/ 0,
9037                              /*phy*/ i,
9038                              timeout);
9039
9040                 if (((retval = cam_send_ccb(device, ccb)) < 0)
9041                  || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
9042                   && (disresponse->function_result != SMP_FR_PHY_VACANT))) {
9043                         const char warnstr[] = "error sending command";
9044
9045                         if (retval < 0)
9046                                 warn(warnstr);
9047                         else
9048                                 warnx(warnstr);
9049
9050                         if (arglist & CAM_ARG_VERBOSE) {
9051                                 cam_error_print(device, ccb, CAM_ESF_ALL,
9052                                                 CAM_EPF_ALL, stderr);
9053                         }
9054                         retval = 1;
9055                         goto bailout;
9056                 }
9057
9058                 if (disresponse->function_result == SMP_FR_PHY_VACANT) {
9059                         if (quiet == 0)
9060                                 fprintf(stdout, "%3d  <vacant>\n", i);
9061                         continue;
9062                 }
9063
9064                 if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) {
9065                         item = NULL;
9066                 } else {
9067                         item = findsasdevice(&devlist,
9068                             scsi_8btou64(disresponse->attached_sas_address));
9069                 }
9070
9071                 if ((quiet == 0)
9072                  || (item != NULL)) {
9073                         fprintf(stdout, "%3d  0x%016jx", i,
9074                                 (uintmax_t)scsi_8btou64(
9075                                 disresponse->attached_sas_address));
9076                         if (item == NULL) {
9077                                 fprintf(stdout, "\n");
9078                                 continue;
9079                         }
9080                 } else if (quiet != 0)
9081                         continue;
9082
9083                 dev_match = &item->dev_match;
9084
9085                 if (dev_match->protocol == PROTO_SCSI) {
9086                         cam_strvis(vendor, dev_match->inq_data.vendor,
9087                                    sizeof(dev_match->inq_data.vendor),
9088                                    sizeof(vendor));
9089                         cam_strvis(product, dev_match->inq_data.product,
9090                                    sizeof(dev_match->inq_data.product),
9091                                    sizeof(product));
9092                         cam_strvis(revision, dev_match->inq_data.revision,
9093                                    sizeof(dev_match->inq_data.revision),
9094                                    sizeof(revision));
9095                         sprintf(tmpstr, "<%s %s %s>", vendor, product,
9096                                 revision);
9097                 } else if ((dev_match->protocol == PROTO_ATA)
9098                         || (dev_match->protocol == PROTO_SATAPM)) {
9099                         cam_strvis(product, dev_match->ident_data.model,
9100                                    sizeof(dev_match->ident_data.model),
9101                                    sizeof(product));
9102                         cam_strvis(revision, dev_match->ident_data.revision,
9103                                    sizeof(dev_match->ident_data.revision),
9104                                    sizeof(revision));
9105                         sprintf(tmpstr, "<%s %s>", product, revision);
9106                 } else {
9107                         sprintf(tmpstr, "<>");
9108                 }
9109                 fprintf(stdout, "   %-33s ", tmpstr);
9110
9111                 /*
9112                  * If we have 0 periphs, that's a bug...
9113                  */
9114                 if (item->num_periphs == 0) {
9115                         fprintf(stdout, "\n");
9116                         continue;
9117                 }
9118
9119                 fprintf(stdout, "(");
9120                 for (j = 0; j < item->num_periphs; j++) {
9121                         if (j > 0)
9122                                 fprintf(stdout, ",");
9123
9124                         fprintf(stdout, "%s%d",
9125                                 item->periph_matches[j].periph_name,
9126                                 item->periph_matches[j].unit_number);
9127
9128                 }
9129                 fprintf(stdout, ")\n");
9130         }
9131 bailout:
9132         if (ccb != NULL)
9133                 cam_freeccb(ccb);
9134
9135         free(rgrequest);
9136
9137         free(rgresponse);
9138
9139         free(disrequest);
9140
9141         free(disresponse);
9142
9143         freebusdevlist(&devlist);
9144
9145         return (retval);
9146 }
9147
9148 static int
9149 atapm_proc_resp(struct cam_device *device, union ccb *ccb)
9150 {
9151         uint8_t error = 0, ata_device = 0, status = 0;
9152         uint16_t count = 0;
9153         uint64_t lba = 0;
9154         int retval;
9155
9156         retval = get_ata_status(device, ccb, &error, &count, &lba, &ata_device,
9157             &status);
9158         if (retval == 1) {
9159                 if (arglist & CAM_ARG_VERBOSE) {
9160                         cam_error_print(device, ccb, CAM_ESF_ALL,
9161                                         CAM_EPF_ALL, stderr);
9162                 }
9163                 warnx("Can't get ATA command status");
9164                 return (retval);
9165         }
9166
9167         if (status & ATA_STATUS_ERROR) {
9168                 cam_error_print(device, ccb, CAM_ESF_ALL,
9169                     CAM_EPF_ALL, stderr);
9170                 return (1);
9171         }
9172
9173         printf("%s%d: ", device->device_name, device->dev_unit_num);
9174         switch (count) {
9175         case 0x00:
9176                 printf("Standby mode\n");
9177                 break;
9178         case 0x01:
9179                 printf("Standby_y mode\n");
9180                 break;
9181         case 0x40:
9182                 printf("NV Cache Power Mode and the spindle is spun down or spinning down\n");
9183                 break;
9184         case 0x41:
9185                 printf("NV Cache Power Mode and the spindle is spun up or spinning up\n");
9186                 break;
9187         case 0x80:
9188                 printf("Idle mode\n");
9189                 break;
9190         case 0x81:
9191                 printf("Idle_a mode\n");
9192                 break;
9193         case 0x82:
9194                 printf("Idle_b mode\n");
9195                 break;
9196         case 0x83:
9197                 printf("Idle_c mode\n");
9198                 break;
9199         case 0xff:
9200                 printf("Active or Idle mode\n");
9201                 break;
9202         default:
9203                 printf("Unknown mode 0x%02x\n", count);
9204                 break;
9205         }
9206
9207         return (0);
9208 }
9209
9210 static int
9211 atapm(struct cam_device *device, int argc, char **argv,
9212                  char *combinedopt, int retry_count, int timeout)
9213 {
9214         union ccb *ccb;
9215         int retval = 0;
9216         int t = -1;
9217         int c;
9218         u_int8_t ata_flags = 0;
9219         u_char cmd, sc;
9220
9221         ccb = cam_getccb(device);
9222
9223         if (ccb == NULL) {
9224                 warnx("%s: error allocating ccb", __func__);
9225                 return (1);
9226         }
9227
9228         while ((c = getopt(argc, argv, combinedopt)) != -1) {
9229                 switch (c) {
9230                 case 't':
9231                         t = atoi(optarg);
9232                         break;
9233                 default:
9234                         break;
9235                 }
9236         }
9237         if (strcmp(argv[1], "idle") == 0) {
9238                 if (t == -1)
9239                         cmd = ATA_IDLE_IMMEDIATE;
9240                 else
9241                         cmd = ATA_IDLE_CMD;
9242         } else if (strcmp(argv[1], "standby") == 0) {
9243                 if (t == -1)
9244                         cmd = ATA_STANDBY_IMMEDIATE;
9245                 else
9246                         cmd = ATA_STANDBY_CMD;
9247         } else if (strcmp(argv[1], "powermode") == 0) {
9248                 cmd = ATA_CHECK_POWER_MODE;
9249                 ata_flags = AP_FLAG_CHK_COND;
9250                 t = -1;
9251         } else {
9252                 cmd = ATA_SLEEP;
9253                 t = -1;
9254         }
9255
9256         if (t < 0)
9257                 sc = 0;
9258         else if (t <= (240 * 5))
9259                 sc = (t + 4) / 5;
9260         else if (t <= (252 * 5))
9261                 /* special encoding for 21 minutes */
9262                 sc = 252;
9263         else if (t <= (11 * 30 * 60))
9264                 sc = (t - 1) / (30 * 60) + 241;
9265         else
9266                 sc = 253;
9267
9268         retval = ata_do_cmd(device,
9269             ccb,
9270             /*retries*/retry_count,
9271             /*flags*/CAM_DIR_NONE,
9272             /*protocol*/AP_PROTO_NON_DATA,
9273             /*ata_flags*/ata_flags,
9274             /*tag_action*/MSG_SIMPLE_Q_TAG,
9275             /*command*/cmd,
9276             /*features*/0,
9277             /*lba*/0,
9278             /*sector_count*/sc,
9279             /*data_ptr*/NULL,
9280             /*dxfer_len*/0,
9281             /*timeout*/timeout ? timeout : 30 * 1000,
9282             /*force48bit*/0);
9283
9284         cam_freeccb(ccb);
9285
9286         if (retval || cmd != ATA_CHECK_POWER_MODE)
9287                 return (retval);
9288
9289         return (atapm_proc_resp(device, ccb));
9290 }
9291
9292 static int
9293 ataaxm(struct cam_device *device, int argc, char **argv,
9294                  char *combinedopt, int retry_count, int timeout)
9295 {
9296         union ccb *ccb;
9297         int retval = 0;
9298         int l = -1;
9299         int c;
9300         u_char cmd, sc;
9301
9302         ccb = cam_getccb(device);
9303
9304         if (ccb == NULL) {
9305                 warnx("%s: error allocating ccb", __func__);
9306                 return (1);
9307         }
9308
9309         while ((c = getopt(argc, argv, combinedopt)) != -1) {
9310                 switch (c) {
9311                 case 'l':
9312                         l = atoi(optarg);
9313                         break;
9314                 default:
9315                         break;
9316                 }
9317         }
9318         sc = 0;
9319         if (strcmp(argv[1], "apm") == 0) {
9320                 if (l == -1)
9321                         cmd = 0x85;
9322                 else {
9323                         cmd = 0x05;
9324                         sc = l;
9325                 }
9326         } else /* aam */ {
9327                 if (l == -1)
9328                         cmd = 0xC2;
9329                 else {
9330                         cmd = 0x42;
9331                         sc = l;
9332                 }
9333         }
9334
9335         retval = ata_do_cmd(device,
9336             ccb,
9337             /*retries*/retry_count,
9338             /*flags*/CAM_DIR_NONE,
9339             /*protocol*/AP_PROTO_NON_DATA,
9340             /*ata_flags*/0,
9341             /*tag_action*/MSG_SIMPLE_Q_TAG,
9342             /*command*/ATA_SETFEATURES,
9343             /*features*/cmd,
9344             /*lba*/0,
9345             /*sector_count*/sc,
9346             /*data_ptr*/NULL,
9347             /*dxfer_len*/0,
9348             /*timeout*/timeout ? timeout : 30 * 1000,
9349             /*force48bit*/0);
9350
9351         cam_freeccb(ccb);
9352         return (retval);
9353 }
9354
9355 int
9356 scsigetopcodes(struct cam_device *device, int opcode_set, int opcode,
9357                int show_sa_errors, int sa_set, int service_action,
9358                int timeout_desc, int task_attr, int retry_count, int timeout,
9359                int verbosemode, uint32_t *fill_len, uint8_t **data_ptr)
9360 {
9361         union ccb *ccb = NULL;
9362         uint8_t *buf = NULL;
9363         uint32_t alloc_len = 0, num_opcodes;
9364         uint32_t valid_len = 0;
9365         uint32_t avail_len = 0;
9366         struct scsi_report_supported_opcodes_all *all_hdr;
9367         struct scsi_report_supported_opcodes_one *one;
9368         int options = 0;
9369         int retval = 0;
9370
9371         /*
9372          * Make it clear that we haven't yet allocated or filled anything.
9373          */
9374         *fill_len = 0;
9375         *data_ptr = NULL;
9376
9377         ccb = cam_getccb(device);
9378         if (ccb == NULL) {
9379                 warnx("couldn't allocate CCB");
9380                 retval = 1;
9381                 goto bailout;
9382         }
9383
9384         /* cam_getccb cleans up the header, caller has to zero the payload */
9385         CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
9386
9387         if (opcode_set != 0) {
9388                 options |= RSO_OPTIONS_OC;
9389                 num_opcodes = 1;
9390                 alloc_len = sizeof(*one) + CAM_MAX_CDBLEN;
9391         } else {
9392                 num_opcodes = 256;
9393                 alloc_len = sizeof(*all_hdr) + (num_opcodes *
9394                     sizeof(struct scsi_report_supported_opcodes_descr));
9395         }
9396
9397         if (timeout_desc != 0) {
9398                 options |= RSO_RCTD;
9399                 alloc_len += num_opcodes *
9400                     sizeof(struct scsi_report_supported_opcodes_timeout);
9401         }
9402
9403         if (sa_set != 0) {
9404                 options |= RSO_OPTIONS_OC_SA;
9405                 if (show_sa_errors != 0)
9406                         options &= ~RSO_OPTIONS_OC;
9407         }
9408
9409 retry_alloc:
9410         if (buf != NULL) {
9411                 free(buf);
9412                 buf = NULL;
9413         }
9414
9415         buf = malloc(alloc_len);
9416         if (buf == NULL) {
9417                 warn("Unable to allocate %u bytes", alloc_len);
9418                 retval = 1;
9419                 goto bailout;
9420         }
9421         bzero(buf, alloc_len);
9422
9423         scsi_report_supported_opcodes(&ccb->csio,
9424                                       /*retries*/ retry_count,
9425                                       /*cbfcnp*/ NULL,
9426                                       /*tag_action*/ task_attr,
9427                                       /*options*/ options,
9428                                       /*req_opcode*/ opcode,
9429                                       /*req_service_action*/ service_action,
9430                                       /*data_ptr*/ buf,
9431                                       /*dxfer_len*/ alloc_len,
9432                                       /*sense_len*/ SSD_FULL_SIZE,
9433                                       /*timeout*/ timeout ? timeout : 10000);
9434
9435         ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
9436
9437         if (retry_count != 0)
9438                 ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
9439
9440         if (cam_send_ccb(device, ccb) < 0) {
9441                 warn("error sending REPORT SUPPORTED OPERATION CODES command");
9442                 retval = 1;
9443                 goto bailout;
9444         }
9445
9446         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9447                 if (verbosemode != 0)
9448                         cam_error_print(device, ccb, CAM_ESF_ALL,
9449                                         CAM_EPF_ALL, stderr);
9450                 retval = 1;
9451                 goto bailout;
9452         }
9453
9454         valid_len = ccb->csio.dxfer_len - ccb->csio.resid;
9455
9456         if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL)
9457          && (valid_len >= sizeof(*all_hdr))) {
9458                 all_hdr = (struct scsi_report_supported_opcodes_all *)buf;
9459                 avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr);
9460         } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL)
9461                 && (valid_len >= sizeof(*one))) {
9462                 uint32_t cdb_length;
9463
9464                 one = (struct scsi_report_supported_opcodes_one *)buf;
9465                 cdb_length = scsi_2btoul(one->cdb_length);
9466                 avail_len = sizeof(*one) + cdb_length;
9467                 if (one->support & RSO_ONE_CTDP) {
9468                         struct scsi_report_supported_opcodes_timeout *td;
9469
9470                         td = (struct scsi_report_supported_opcodes_timeout *)
9471                             &buf[avail_len];
9472                         if (valid_len >= (avail_len + sizeof(td->length))) {
9473                                 avail_len += scsi_2btoul(td->length) +
9474                                     sizeof(td->length);
9475                         } else {
9476                                 avail_len += sizeof(*td);
9477                         }
9478                 }
9479         }
9480
9481         /*
9482          * avail_len could be zero if we didn't get enough data back from
9483          * thet target to determine
9484          */
9485         if ((avail_len != 0)
9486          && (avail_len > valid_len)) {
9487                 alloc_len = avail_len;
9488                 goto retry_alloc;
9489         }
9490
9491         *fill_len = valid_len;
9492         *data_ptr = buf;
9493 bailout:
9494         if (retval != 0)
9495                 free(buf);
9496
9497         cam_freeccb(ccb);
9498
9499         return (retval);
9500 }
9501
9502 static int
9503 scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set,
9504                    int req_sa, uint8_t *buf, uint32_t valid_len)
9505 {
9506         struct scsi_report_supported_opcodes_one *one;
9507         struct scsi_report_supported_opcodes_timeout *td;
9508         uint32_t cdb_len = 0, td_len = 0;
9509         const char *op_desc = NULL;
9510         unsigned int i;
9511         int retval = 0;
9512
9513         one = (struct scsi_report_supported_opcodes_one *)buf;
9514
9515         /*
9516          * If we don't have the full single opcode descriptor, no point in
9517          * continuing.
9518          */
9519         if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9520             cdb_length)) {
9521                 warnx("Only %u bytes returned, not enough to verify support",
9522                       valid_len);
9523                 retval = 1;
9524                 goto bailout;
9525         }
9526
9527         op_desc = scsi_op_desc(req_opcode, &device->inq_data);
9528
9529         printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN",
9530                req_opcode);
9531         if (sa_set != 0)
9532                 printf(", SA 0x%x", req_sa);
9533         printf(": ");
9534
9535         switch (one->support & RSO_ONE_SUP_MASK) {
9536         case RSO_ONE_SUP_UNAVAIL:
9537                 printf("No command support information currently available\n");
9538                 break;
9539         case RSO_ONE_SUP_NOT_SUP:
9540                 printf("Command not supported\n");
9541                 retval = 1;
9542                 goto bailout;
9543                 break; /*NOTREACHED*/
9544         case RSO_ONE_SUP_AVAIL:
9545                 printf("Command is supported, complies with a SCSI standard\n");
9546                 break;
9547         case RSO_ONE_SUP_VENDOR:
9548                 printf("Command is supported, vendor-specific "
9549                        "implementation\n");
9550                 break;
9551         default:
9552                 printf("Unknown command support flags 0x%#x\n",
9553                        one->support & RSO_ONE_SUP_MASK);
9554                 break;
9555         }
9556
9557         /*
9558          * If we don't have the CDB length, it isn't exactly an error, the
9559          * command probably isn't supported.
9560          */
9561         if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one,
9562             cdb_usage))
9563                 goto bailout;
9564
9565         cdb_len = scsi_2btoul(one->cdb_length);
9566
9567         /*
9568          * If our valid data doesn't include the full reported length,
9569          * return.  The caller should have detected this and adjusted his
9570          * allocation length to get all of the available data.
9571          */
9572         if (valid_len < sizeof(*one) + cdb_len) {
9573                 retval = 1;
9574                 goto bailout;
9575         }
9576
9577         /*
9578          * If all we have is the opcode, there is no point in printing out
9579          * the usage bitmap.
9580          */
9581         if (cdb_len <= 1) {
9582                 retval = 1;
9583                 goto bailout;
9584         }
9585
9586         printf("CDB usage bitmap:");
9587         for (i = 0; i < cdb_len; i++) {
9588                 printf(" %02x", one->cdb_usage[i]);
9589         }
9590         printf("\n");
9591
9592         /*
9593          * If we don't have a timeout descriptor, we're done.
9594          */
9595         if ((one->support & RSO_ONE_CTDP) == 0)
9596                 goto bailout;
9597
9598         /*
9599          * If we don't have enough valid length to include the timeout
9600          * descriptor length, we're done.
9601          */
9602         if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length)))
9603                 goto bailout;
9604
9605         td = (struct scsi_report_supported_opcodes_timeout *)
9606             &buf[sizeof(*one) + cdb_len];
9607         td_len = scsi_2btoul(td->length);
9608         td_len += sizeof(td->length);
9609
9610         /*
9611          * If we don't have the full timeout descriptor, we're done.
9612          */
9613         if (td_len < sizeof(*td))
9614                 goto bailout;
9615
9616         /*
9617          * If we don't have enough valid length to contain the full timeout
9618          * descriptor, we're done.
9619          */
9620         if (valid_len < (sizeof(*one) + cdb_len + td_len))
9621                 goto bailout;
9622
9623         printf("Timeout information:\n");
9624         printf("Command-specific:    0x%02x\n", td->cmd_specific);
9625         printf("Nominal timeout:     %u seconds\n",
9626                scsi_4btoul(td->nominal_time));
9627         printf("Recommended timeout: %u seconds\n",
9628                scsi_4btoul(td->recommended_time));
9629
9630 bailout:
9631         return (retval);
9632 }
9633
9634 static int
9635 scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf,
9636                  uint32_t valid_len)
9637 {
9638         struct scsi_report_supported_opcodes_all *hdr;
9639         struct scsi_report_supported_opcodes_descr *desc;
9640         uint32_t avail_len = 0, used_len = 0;
9641         uint8_t *cur_ptr;
9642         int retval = 0;
9643
9644         if (valid_len < sizeof(*hdr)) {
9645                 warnx("%s: not enough returned data (%u bytes) opcode list",
9646                       __func__, valid_len);
9647                 retval = 1;
9648                 goto bailout;
9649         }
9650         hdr = (struct scsi_report_supported_opcodes_all *)buf;
9651         avail_len = scsi_4btoul(hdr->length);
9652         avail_len += sizeof(hdr->length);
9653         /*
9654          * Take the lesser of the amount of data the drive claims is
9655          * available, and the amount of data the HBA says was returned.
9656          */
9657         avail_len = MIN(avail_len, valid_len);
9658
9659         used_len = sizeof(hdr->length);
9660
9661         printf("%-6s %4s %8s ",
9662                "Opcode", "SA", "CDB len" );
9663
9664         if (td_req != 0)
9665                 printf("%5s %6s %6s ", "CS", "Nom", "Rec");
9666         printf(" Description\n");
9667
9668         while ((avail_len - used_len) > sizeof(*desc)) {
9669                 struct scsi_report_supported_opcodes_timeout *td;
9670                 uint32_t td_len;
9671                 const char *op_desc = NULL;
9672
9673                 cur_ptr = &buf[used_len];
9674                 desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr;
9675
9676                 op_desc = scsi_op_desc(desc->opcode, &device->inq_data);
9677                 if (op_desc == NULL)
9678                         op_desc = "UNKNOWN";
9679
9680                 printf("0x%02x   %#4x %8u ", desc->opcode,
9681                        scsi_2btoul(desc->service_action),
9682                        scsi_2btoul(desc->cdb_length));
9683
9684                 used_len += sizeof(*desc);
9685
9686                 if ((desc->flags & RSO_CTDP) == 0) {
9687                         printf(" %s\n", op_desc);
9688                         continue;
9689                 }
9690
9691                 /*
9692                  * If we don't have enough space to fit a timeout
9693                  * descriptor, then we're done.
9694                  */
9695                 if (avail_len - used_len < sizeof(*td)) {
9696                         used_len = avail_len;
9697                         printf(" %s\n", op_desc);
9698                         continue;
9699                 }
9700                 cur_ptr = &buf[used_len];
9701                 td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr;
9702                 td_len = scsi_2btoul(td->length);
9703                 td_len += sizeof(td->length);
9704
9705                 used_len += td_len;
9706                 /*
9707                  * If the given timeout descriptor length is less than what
9708                  * we understand, skip it.
9709                  */
9710                 if (td_len < sizeof(*td)) {
9711                         printf(" %s\n", op_desc);
9712                         continue;
9713                 }
9714
9715                 printf(" 0x%02x %6u %6u  %s\n", td->cmd_specific,
9716                        scsi_4btoul(td->nominal_time),
9717                        scsi_4btoul(td->recommended_time), op_desc);
9718         }
9719 bailout:
9720         return (retval);
9721 }
9722
9723 static int
9724 scsiopcodes(struct cam_device *device, int argc, char **argv,
9725             char *combinedopt, int task_attr, int retry_count, int timeout,
9726             int verbosemode)
9727 {
9728         int c;
9729         uint32_t opcode = 0, service_action = 0;
9730         int td_set = 0, opcode_set = 0, sa_set = 0;
9731         int show_sa_errors = 1;
9732         uint32_t valid_len = 0;
9733         uint8_t *buf = NULL;
9734         char *endptr;
9735         int retval = 0;
9736
9737         while ((c = getopt(argc, argv, combinedopt)) != -1) {
9738                 switch (c) {
9739                 case 'N':
9740                         show_sa_errors = 0;
9741                         break;
9742                 case 'o':
9743                         opcode = strtoul(optarg, &endptr, 0);
9744                         if (*endptr != '\0') {
9745                                 warnx("Invalid opcode \"%s\", must be a number",
9746                                       optarg);
9747                                 retval = 1;
9748                                 goto bailout;
9749                         }
9750                         if (opcode > 0xff) {
9751                                 warnx("Invalid opcode 0x%#x, must be between"
9752                                       "0 and 0xff inclusive", opcode);
9753                                 retval = 1;
9754                                 goto bailout;
9755                         }
9756                         opcode_set = 1;
9757                         break;
9758                 case 's':
9759                         service_action = strtoul(optarg, &endptr, 0);
9760                         if (*endptr != '\0') {
9761                                 warnx("Invalid service action \"%s\", must "
9762                                       "be a number", optarg);
9763                                 retval = 1;
9764                                 goto bailout;
9765                         }
9766                         if (service_action > 0xffff) {
9767                                 warnx("Invalid service action 0x%#x, must "
9768                                       "be between 0 and 0xffff inclusive",
9769                                       service_action);
9770                                 retval = 1;
9771                         }
9772                         sa_set = 1;
9773                         break;
9774                 case 'T':
9775                         td_set = 1;
9776                         break;
9777                 default:
9778                         break;
9779                 }
9780         }
9781
9782         if ((sa_set != 0)
9783          && (opcode_set == 0)) {
9784                 warnx("You must specify an opcode with -o if a service "
9785                       "action is given");
9786                 retval = 1;
9787                 goto bailout;
9788         }
9789         retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors,
9790                                 sa_set, service_action, td_set, task_attr,
9791                                 retry_count, timeout, verbosemode, &valid_len,
9792                                 &buf);
9793         if (retval != 0)
9794                 goto bailout;
9795
9796         if ((opcode_set != 0)
9797          || (sa_set != 0)) {
9798                 retval = scsiprintoneopcode(device, opcode, sa_set,
9799                                             service_action, buf, valid_len);
9800         } else {
9801                 retval = scsiprintopcodes(device, td_set, buf, valid_len);
9802         }
9803
9804 bailout:
9805         free(buf);
9806
9807         return (retval);
9808 }
9809
9810
9811 static int
9812 reprobe(struct cam_device *device)
9813 {
9814         union ccb *ccb;
9815         int retval = 0;
9816
9817         ccb = cam_getccb(device);
9818
9819         if (ccb == NULL) {
9820                 warnx("%s: error allocating ccb", __func__);
9821                 return (1);
9822         }
9823
9824         CCB_CLEAR_ALL_EXCEPT_HDR(ccb);
9825
9826         ccb->ccb_h.func_code = XPT_REPROBE_LUN;
9827
9828         if (cam_send_ccb(device, ccb) < 0) {
9829                 warn("error sending XPT_REPROBE_LUN CCB");
9830                 retval = 1;
9831                 goto bailout;
9832         }
9833
9834         if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
9835                 cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
9836                 retval = 1;
9837                 goto bailout;
9838         }
9839
9840 bailout:
9841         cam_freeccb(ccb);
9842
9843         return (retval);
9844 }
9845
9846 void
9847 usage(int printlong)
9848 {
9849
9850         fprintf(printlong ? stdout : stderr,
9851 "usage:  camcontrol <command>  [device id][generic args][command args]\n"
9852 "        camcontrol devlist    [-b] [-v]\n"
9853 "        camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n"
9854 "        camcontrol tur        [dev_id][generic args]\n"
9855 "        camcontrol inquiry    [dev_id][generic args] [-D] [-S] [-R]\n"
9856 "        camcontrol identify   [dev_id][generic args] [-v]\n"
9857 "        camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n"
9858 "        camcontrol readcap    [dev_id][generic args] [-b] [-h] [-H] [-N]\n"
9859 "                              [-q] [-s] [-l]\n"
9860 "        camcontrol start      [dev_id][generic args]\n"
9861 "        camcontrol stop       [dev_id][generic args]\n"
9862 "        camcontrol load       [dev_id][generic args]\n"
9863 "        camcontrol eject      [dev_id][generic args]\n"
9864 "        camcontrol reprobe    [dev_id][generic args]\n"
9865 "        camcontrol rescan     <all | bus[:target:lun] | dev_id>\n"
9866 "        camcontrol reset      <all | bus[:target:lun] | dev_id>\n"
9867 "        camcontrol defects    [dev_id][generic args] <-f format> [-P][-G]\n"
9868 "                              [-q][-s][-S offset][-X]\n"
9869 "        camcontrol modepage   [dev_id][generic args] <-m page | -l>\n"
9870 "                              [-P pagectl][-e | -b][-d]\n"
9871 "        camcontrol cmd        [dev_id][generic args]\n"
9872 "                              <-a cmd [args] | -c cmd [args]>\n"
9873 "                              [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n"
9874 "        camcontrol smpcmd     [dev_id][generic args]\n"
9875 "                              <-r len fmt [args]> <-R len fmt [args]>\n"
9876 "        camcontrol smprg      [dev_id][generic args][-l]\n"
9877 "        camcontrol smppc      [dev_id][generic args] <-p phy> [-l]\n"
9878 "                              [-o operation][-d name][-m rate][-M rate]\n"
9879 "                              [-T pp_timeout][-a enable|disable]\n"
9880 "                              [-A enable|disable][-s enable|disable]\n"
9881 "                              [-S enable|disable]\n"
9882 "        camcontrol smpphylist [dev_id][generic args][-l][-q]\n"
9883 "        camcontrol smpmaninfo [dev_id][generic args][-l]\n"
9884 "        camcontrol debug      [-I][-P][-T][-S][-X][-c]\n"
9885 "                              <all|dev_id|bus[:target[:lun]]|off>\n"
9886 "        camcontrol tags       [dev_id][generic args] [-N tags] [-q] [-v]\n"
9887 "        camcontrol negotiate  [dev_id][generic args] [-a][-c]\n"
9888 "                              [-D <enable|disable>][-M mode][-O offset]\n"
9889 "                              [-q][-R syncrate][-v][-T <enable|disable>]\n"
9890 "                              [-U][-W bus_width]\n"
9891 "        camcontrol format     [dev_id][generic args][-q][-r][-w][-y]\n"
9892 "        camcontrol sanitize   [dev_id][generic args]\n"
9893 "                              [-a overwrite|block|crypto|exitfailure]\n"
9894 "                              [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
9895 "                              [-y]\n"
9896 "        camcontrol idle       [dev_id][generic args][-t time]\n"
9897 "        camcontrol standby    [dev_id][generic args][-t time]\n"
9898 "        camcontrol sleep      [dev_id][generic args]\n"
9899 "        camcontrol powermode  [dev_id][generic args]\n"
9900 "        camcontrol apm        [dev_id][generic args][-l level]\n"
9901 "        camcontrol aam        [dev_id][generic args][-l level]\n"
9902 "        camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n"
9903 "                              [-s][-y]\n"
9904 "        camcontrol security   [dev_id][generic args]\n"
9905 "                              <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n"
9906 "                              [-l <high|maximum>] [-q] [-s pwd] [-T timeout]\n"
9907 "                              [-U <user|master>] [-y]\n"
9908 "        camcontrol hpa        [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n"
9909 "                              [-q] [-s max_sectors] [-U pwd] [-y]\n"
9910 "        camcontrol ama        [dev_id][generic args] [-f] [-q] [-s max_sectors]\n"
9911 "        camcontrol persist    [dev_id][generic args] <-i action|-o action>\n"
9912 "                              [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n"
9913 "                              [-s scope][-S][-T type][-U]\n"
9914 "        camcontrol attrib     [dev_id][generic args] <-r action|-w attr>\n"
9915 "                              [-a attr_num][-c][-e elem][-F form1,form1]\n"
9916 "                              [-p part][-s start][-T type][-V vol]\n"
9917 "        camcontrol opcodes    [dev_id][generic args][-o opcode][-s SA]\n"
9918 "                              [-N][-T]\n"
9919 "        camcontrol zone       [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n"
9920 "                              [-o rep_opts] [-P print_opts]\n"
9921 "        camcontrol epc        [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
9922 "                              [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
9923 "                              [-S power_src] [-T timer]\n"
9924 "        camcontrol timestamp  [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
9925 "                              <-s <-f format -T time | -U >>\n"
9926 "        camcontrol devtype    [dev_id]\n"
9927 "                              \n"
9928 "        camcontrol help\n");
9929         if (!printlong)
9930                 return;
9931         fprintf(stdout,
9932 "Specify one of the following options:\n"
9933 "devlist     list all CAM devices\n"
9934 "periphlist  list all CAM peripheral drivers attached to a device\n"
9935 "tur         send a test unit ready to the named device\n"
9936 "inquiry     send a SCSI inquiry command to the named device\n"
9937 "identify    send a ATA identify command to the named device\n"
9938 "reportluns  send a SCSI report luns command to the device\n"
9939 "readcap     send a SCSI read capacity command to the device\n"
9940 "start       send a Start Unit command to the device\n"
9941 "stop        send a Stop Unit command to the device\n"
9942 "load        send a Start Unit command to the device with the load bit set\n"
9943 "eject       send a Stop Unit command to the device with the eject bit set\n"
9944 "reprobe     update capacity information of the given device\n"
9945 "rescan      rescan all buses, the given bus, bus:target:lun or device\n"
9946 "reset       reset all buses, the given bus, bus:target:lun or device\n"
9947 "defects     read the defect list of the specified device\n"
9948 "modepage    display or edit (-e) the given mode page\n"
9949 "cmd         send the given SCSI command, may need -i or -o as well\n"
9950 "smpcmd      send the given SMP command, requires -o and -i\n"
9951 "smprg       send the SMP Report General command\n"
9952 "smppc       send the SMP PHY Control command, requires -p\n"
9953 "smpphylist  display phys attached to a SAS expander\n"
9954 "smpmaninfo  send the SMP Report Manufacturer Info command\n"
9955 "debug       turn debugging on/off for a bus, target, or lun, or all devices\n"
9956 "tags        report or set the number of transaction slots for a device\n"
9957 "negotiate   report or set device negotiation parameters\n"
9958 "format      send the SCSI FORMAT UNIT command to the named device\n"
9959 "sanitize    send the SCSI SANITIZE command to the named device\n"
9960 "idle        send the ATA IDLE command to the named device\n"
9961 "standby     send the ATA STANDBY command to the named device\n"
9962 "sleep       send the ATA SLEEP command to the named device\n"
9963 "powermode   send the ATA CHECK POWER MODE command to the named device\n"
9964 "fwdownload  program firmware of the named device with the given image\n"
9965 "security    report or send ATA security commands to the named device\n"
9966 "persist     send the SCSI PERSISTENT RESERVE IN or OUT commands\n"
9967 "attrib      send the SCSI READ or WRITE ATTRIBUTE commands\n"
9968 "opcodes     send the SCSI REPORT SUPPORTED OPCODES command\n"
9969 "zone        manage Zoned Block (Shingled) devices\n"
9970 "epc         send ATA Extended Power Conditions commands\n"
9971 "timestamp   report or set the device's timestamp\n"
9972 "devtype     report the type of device\n"
9973 "help        this message\n"
9974 "Device Identifiers:\n"
9975 "bus:target        specify the bus and target, lun defaults to 0\n"
9976 "bus:target:lun    specify the bus, target and lun\n"
9977 "deviceUNIT        specify the device name, like \"da4\" or \"cd2\"\n"
9978 "Generic arguments:\n"
9979 "-v                be verbose, print out sense information\n"
9980 "-t timeout        command timeout in seconds, overrides default timeout\n"
9981 "-n dev_name       specify device name, e.g. \"da\", \"cd\"\n"
9982 "-u unit           specify unit number, e.g. \"0\", \"5\"\n"
9983 "-E                have the kernel attempt to perform SCSI error recovery\n"
9984 "-C count          specify the SCSI command retry count (needs -E to work)\n"
9985 "-Q task_attr      specify ordered, simple or head tag type for SCSI cmds\n"
9986 "modepage arguments:\n"
9987 "-l                list all available mode pages\n"
9988 "-m page           specify the mode page to view or edit\n"
9989 "-e                edit the specified mode page\n"
9990 "-b                force view to binary mode\n"
9991 "-d                disable block descriptors for mode sense\n"
9992 "-P pgctl          page control field 0-3\n"
9993 "defects arguments:\n"
9994 "-f format         specify defect list format (block, bfi or phys)\n"
9995 "-G                get the grown defect list\n"
9996 "-P                get the permanent defect list\n"
9997 "inquiry arguments:\n"
9998 "-D                get the standard inquiry data\n"
9999 "-S                get the serial number\n"
10000 "-R                get the transfer rate, etc.\n"
10001 "reportluns arguments:\n"
10002 "-c                only report a count of available LUNs\n"
10003 "-l                only print out luns, and not a count\n"
10004 "-r <reporttype>   specify \"default\", \"wellknown\" or \"all\"\n"
10005 "readcap arguments\n"
10006 "-b                only report the blocksize\n"
10007 "-h                human readable device size, base 2\n"
10008 "-H                human readable device size, base 10\n"
10009 "-N                print the number of blocks instead of last block\n"
10010 "-q                quiet, print numbers only\n"
10011 "-s                only report the last block/device size\n"
10012 "cmd arguments:\n"
10013 "-c cdb [args]     specify the SCSI CDB\n"
10014 "-i len fmt        specify input data and input data format\n"
10015 "-o len fmt [args] specify output data and output data fmt\n"
10016 "smpcmd arguments:\n"
10017 "-r len fmt [args] specify the SMP command to be sent\n"
10018 "-R len fmt [args] specify SMP response format\n"
10019 "smprg arguments:\n"
10020 "-l                specify the long response format\n"
10021 "smppc arguments:\n"
10022 "-p phy            specify the PHY to operate on\n"
10023 "-l                specify the long request/response format\n"
10024 "-o operation      specify the phy control operation\n"
10025 "-d name           set the attached device name\n"
10026 "-m rate           set the minimum physical link rate\n"
10027 "-M rate           set the maximum physical link rate\n"
10028 "-T pp_timeout     set the partial pathway timeout value\n"
10029 "-a enable|disable enable or disable SATA slumber\n"
10030 "-A enable|disable enable or disable SATA partial phy power\n"
10031 "-s enable|disable enable or disable SAS slumber\n"
10032 "-S enable|disable enable or disable SAS partial phy power\n"
10033 "smpphylist arguments:\n"
10034 "-l                specify the long response format\n"
10035 "-q                only print phys with attached devices\n"
10036 "smpmaninfo arguments:\n"
10037 "-l                specify the long response format\n"
10038 "debug arguments:\n"
10039 "-I                CAM_DEBUG_INFO -- scsi commands, errors, data\n"
10040 "-T                CAM_DEBUG_TRACE -- routine flow tracking\n"
10041 "-S                CAM_DEBUG_SUBTRACE -- internal routine command flow\n"
10042 "-c                CAM_DEBUG_CDB -- print out SCSI CDBs only\n"
10043 "tags arguments:\n"
10044 "-N tags           specify the number of tags to use for this device\n"
10045 "-q                be quiet, don't report the number of tags\n"
10046 "-v                report a number of tag-related parameters\n"
10047 "negotiate arguments:\n"
10048 "-a                send a test unit ready after negotiation\n"
10049 "-c                report/set current negotiation settings\n"
10050 "-D <arg>          \"enable\" or \"disable\" disconnection\n"
10051 "-M mode           set ATA mode\n"
10052 "-O offset         set command delay offset\n"
10053 "-q                be quiet, don't report anything\n"
10054 "-R syncrate       synchronization rate in MHz\n"
10055 "-T <arg>          \"enable\" or \"disable\" tagged queueing\n"
10056 "-U                report/set user negotiation settings\n"
10057 "-W bus_width      set the bus width in bits (8, 16 or 32)\n"
10058 "-v                also print a Path Inquiry CCB for the controller\n"
10059 "format arguments:\n"
10060 "-q                be quiet, don't print status messages\n"
10061 "-r                run in report only mode\n"
10062 "-w                don't send immediate format command\n"
10063 "-y                don't ask any questions\n"
10064 "sanitize arguments:\n"
10065 "-a operation      operation mode: overwrite, block, crypto or exitfailure\n"
10066 "-c passes         overwrite passes to perform (1 to 31)\n"
10067 "-I                invert overwrite pattern after each pass\n"
10068 "-P pattern        path to overwrite pattern file\n"
10069 "-q                be quiet, don't print status messages\n"
10070 "-r                run in report only mode\n"
10071 "-U                run operation in unrestricted completion exit mode\n"
10072 "-w                don't send immediate sanitize command\n"
10073 "-y                don't ask any questions\n"
10074 "idle/standby arguments:\n"
10075 "-t <arg>          number of seconds before respective state.\n"
10076 "fwdownload arguments:\n"
10077 "-f fw_image       path to firmware image file\n"
10078 "-q                don't print informational messages, only errors\n"
10079 "-s                run in simulation mode\n"
10080 "-v                print info for every firmware segment sent to device\n"
10081 "-y                don't ask any questions\n"
10082 "security arguments:\n"
10083 "-d pwd            disable security using the given password for the selected\n"
10084 "                  user\n"
10085 "-e pwd            erase the device using the given pwd for the selected user\n"
10086 "-f                freeze the security configuration of the specified device\n"
10087 "-h pwd            enhanced erase the device using the given pwd for the\n"
10088 "                  selected user\n"
10089 "-k pwd            unlock the device using the given pwd for the selected\n"
10090 "                  user\n"
10091 "-l <high|maximum> specifies which security level to set: high or maximum\n"
10092 "-q                be quiet, do not print any status messages\n"
10093 "-s pwd            password the device (enable security) using the given\n"
10094 "                  pwd for the selected user\n"
10095 "-T timeout        overrides the timeout (seconds) used for erase operation\n"
10096 "-U <user|master>  specifies which user to set: user or master\n"
10097 "-y                don't ask any questions\n"
10098 "hpa arguments:\n"
10099 "-f                freeze the HPA configuration of the device\n"
10100 "-l                lock the HPA configuration of the device\n"
10101 "-P                make the HPA max sectors persist\n"
10102 "-p pwd            Set the HPA configuration password required for unlock\n"
10103 "                  calls\n"
10104 "-q                be quiet, do not print any status messages\n"
10105 "-s sectors        configures the maximum user accessible sectors of the\n"
10106 "                  device\n"
10107 "-U pwd            unlock the HPA configuration of the device\n"
10108 "-y                don't ask any questions\n"
10109 "ama arguments:\n"
10110 "-f                freeze the AMA configuration of the device\n"
10111 "-q                be quiet, do not print any status messages\n"
10112 "-s sectors        configures the maximum user accessible sectors of the\n"
10113 "                  device\n"
10114 "persist arguments:\n"
10115 "-i action         specify read_keys, read_reservation, report_cap, or\n"
10116 "                  read_full_status\n"
10117 "-o action         specify register, register_ignore, reserve, release,\n"
10118 "                  clear, preempt, preempt_abort, register_move, replace_lost\n"
10119 "-a                set the All Target Ports (ALL_TG_PT) bit\n"
10120 "-I tid            specify a Transport ID, e.g.: sas,0x1234567812345678\n"
10121 "-k key            specify the Reservation Key\n"
10122 "-K sa_key         specify the Service Action Reservation Key\n"
10123 "-p                set the Activate Persist Through Power Loss bit\n"
10124 "-R rtp            specify the Relative Target Port\n"
10125 "-s scope          specify the scope: lun, extent, element or a number\n"
10126 "-S                specify Transport ID for register, requires -I\n"
10127 "-T res_type       specify the reservation type: read_shared, wr_ex, rd_ex,\n"
10128 "                  ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n"
10129 "-U                unregister the current initiator for register_move\n"
10130 "attrib arguments:\n"
10131 "-r action         specify attr_values, attr_list, lv_list, part_list, or\n"
10132 "                  supp_attr\n"
10133 "-w attr           specify an attribute to write, one -w argument per attr\n"
10134 "-a attr_num       only display this attribute number\n"
10135 "-c                get cached attributes\n"
10136 "-e elem_addr      request attributes for the given element in a changer\n"
10137 "-F form1,form2    output format, comma separated list: text_esc, text_raw,\n"
10138 "                  nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n"
10139 "                  field_none, field_desc, field_num, field_size, field_rw\n"
10140 "-p partition      request attributes for the given partition\n"
10141 "-s start_attr     request attributes starting at the given number\n"
10142 "-T elem_type      specify the element type (used with -e)\n"
10143 "-V logical_vol    specify the logical volume ID\n"
10144 "opcodes arguments:\n"
10145 "-o opcode         specify the individual opcode to list\n"
10146 "-s service_action specify the service action for the opcode\n"
10147 "-N                do not return SCSI error for unsupported SA\n"
10148 "-T                request nominal and recommended timeout values\n"
10149 "zone arguments:\n"
10150 "-c cmd            required: rz, open, close, finish, or rwp\n"
10151 "-a                apply the action to all zones\n"
10152 "-l LBA            specify the zone starting LBA\n"
10153 "-o rep_opts       report zones options: all, empty, imp_open, exp_open,\n"
10154 "                  closed, full, ro, offline, reset, nonseq, nonwp\n"
10155 "-P print_opt      report zones printing:  normal, summary, script\n"
10156 "epc arguments:\n"
10157 "-c cmd            required: restore, goto, timer, state, enable, disable,\n"
10158 "                  source, status, list\n"
10159 "-d                disable power mode (timer, state)\n"
10160 "-D                delayed entry (goto)\n"
10161 "-e                enable power mode (timer, state)\n"
10162 "-H                hold power mode (goto)\n"
10163 "-p power_cond     Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n"
10164 "                  state, goto)\n"
10165 "-P                only display power mode (status)\n"
10166 "-r rst_src        restore settings from: default, saved (restore)\n"
10167 "-s                save mode (timer, state, restore)\n"
10168 "-S power_src      set power source: battery, nonbattery (source)\n"
10169 "-T timer          set timer, seconds, .1 sec resolution (timer)\n"
10170 "timestamp arguments:\n"
10171 "-r                report the timestamp of the device\n"
10172 "-f format         report the timestamp of the device with the given\n"
10173 "                  strftime(3) format string\n"
10174 "-m                report the timestamp of the device as milliseconds since\n"
10175 "                  January 1st, 1970\n"
10176 "-U                report the time with UTC instead of the local time zone\n"
10177 "-s                set the timestamp of the device\n"
10178 "-f format         the format of the time string passed into strptime(3)\n"
10179 "-T time           the time value passed into strptime(3)\n"
10180 "-U                set the timestamp of the device to UTC time\n"
10181 );
10182 }
10183
10184 int
10185 main(int argc, char **argv)
10186 {
10187         int c;
10188         char *device = NULL;
10189         int unit = 0;
10190         struct cam_device *cam_dev = NULL;
10191         int timeout = 0, retry_count = 1;
10192         camcontrol_optret optreturn;
10193         char *tstr;
10194         const char *mainopt = "C:En:Q:t:u:v";
10195         const char *subopt = NULL;
10196         char combinedopt[256];
10197         int error = 0, optstart = 2;
10198         int task_attr = MSG_SIMPLE_Q_TAG;
10199         int devopen = 1;
10200         path_id_t bus;
10201         target_id_t target;
10202         lun_id_t lun;
10203
10204         cmdlist = CAM_CMD_NONE;
10205         arglist = CAM_ARG_NONE;
10206
10207         if (argc < 2) {
10208                 usage(0);
10209                 exit(1);
10210         }
10211
10212         /*
10213          * Get the base option.
10214          */
10215         optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt);
10216
10217         if (optreturn == CC_OR_AMBIGUOUS) {
10218                 warnx("ambiguous option %s", argv[1]);
10219                 usage(0);
10220                 exit(1);
10221         } else if (optreturn == CC_OR_NOT_FOUND) {
10222                 warnx("option %s not found", argv[1]);
10223                 usage(0);
10224                 exit(1);
10225         }
10226
10227         /*
10228          * Ahh, getopt(3) is a pain.
10229          *
10230          * This is a gross hack.  There really aren't many other good
10231          * options (excuse the pun) for parsing options in a situation like
10232          * this.  getopt is kinda braindead, so you end up having to run
10233          * through the options twice, and give each invocation of getopt
10234          * the option string for the other invocation.
10235          *
10236          * You would think that you could just have two groups of options.
10237          * The first group would get parsed by the first invocation of
10238          * getopt, and the second group would get parsed by the second
10239          * invocation of getopt.  It doesn't quite work out that way.  When
10240          * the first invocation of getopt finishes, it leaves optind pointing
10241          * to the argument _after_ the first argument in the second group.
10242          * So when the second invocation of getopt comes around, it doesn't
10243          * recognize the first argument it gets and then bails out.
10244          *
10245          * A nice alternative would be to have a flag for getopt that says
10246          * "just keep parsing arguments even when you encounter an unknown
10247          * argument", but there isn't one.  So there's no real clean way to
10248          * easily parse two sets of arguments without having one invocation
10249          * of getopt know about the other.
10250          *
10251          * Without this hack, the first invocation of getopt would work as
10252          * long as the generic arguments are first, but the second invocation
10253          * (in the subfunction) would fail in one of two ways.  In the case
10254          * where you don't set optreset, it would fail because optind may be
10255          * pointing to the argument after the one it should be pointing at.
10256          * In the case where you do set optreset, and reset optind, it would
10257          * fail because getopt would run into the first set of options, which
10258          * it doesn't understand.
10259          *
10260          * All of this would "sort of" work if you could somehow figure out
10261          * whether optind had been incremented one option too far.  The
10262          * mechanics of that, however, are more daunting than just giving
10263          * both invocations all of the expect options for either invocation.
10264          *
10265          * Needless to say, I wouldn't mind if someone invented a better
10266          * (non-GPL!) command line parsing interface than getopt.  I
10267          * wouldn't mind if someone added more knobs to getopt to make it
10268          * work better.  Who knows, I may talk myself into doing it someday,
10269          * if the standards weenies let me.  As it is, it just leads to
10270          * hackery like this and causes people to avoid it in some cases.
10271          *
10272          * KDM, September 8th, 1998
10273          */
10274         if (subopt != NULL)
10275                 sprintf(combinedopt, "%s%s", mainopt, subopt);
10276         else
10277                 sprintf(combinedopt, "%s", mainopt);
10278
10279         /*
10280          * For these options we do not parse optional device arguments and
10281          * we do not open a passthrough device.
10282          */
10283         if ((cmdlist == CAM_CMD_RESCAN)
10284          || (cmdlist == CAM_CMD_RESET)
10285          || (cmdlist == CAM_CMD_DEVTREE)
10286          || (cmdlist == CAM_CMD_USAGE)
10287          || (cmdlist == CAM_CMD_DEBUG))
10288                 devopen = 0;
10289
10290         if ((devopen == 1)
10291          && (argc > 2 && argv[2][0] != '-')) {
10292                 char name[30];
10293                 int rv;
10294
10295                 if (isdigit(argv[2][0])) {
10296                         /* device specified as bus:target[:lun] */
10297                         rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
10298                         if (rv < 2)
10299                                 errx(1, "numeric device specification must "
10300                                      "be either bus:target, or "
10301                                      "bus:target:lun");
10302                         /* default to 0 if lun was not specified */
10303                         if ((arglist & CAM_ARG_LUN) == 0) {
10304                                 lun = 0;
10305                                 arglist |= CAM_ARG_LUN;
10306                         }
10307                         optstart++;
10308                 } else {
10309                         if (cam_get_device(argv[2], name, sizeof name, &unit)
10310                             == -1)
10311                                 errx(1, "%s", cam_errbuf);
10312                         device = strdup(name);
10313                         arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT;
10314                         optstart++;
10315                 }
10316         }
10317         /*
10318          * Start getopt processing at argv[2/3], since we've already
10319          * accepted argv[1..2] as the command name, and as a possible
10320          * device name.
10321          */
10322         optind = optstart;
10323
10324         /*
10325          * Now we run through the argument list looking for generic
10326          * options, and ignoring options that possibly belong to
10327          * subfunctions.
10328          */
10329         while ((c = getopt(argc, argv, combinedopt))!= -1){
10330                 switch(c) {
10331                         case 'C':
10332                                 retry_count = strtol(optarg, NULL, 0);
10333                                 if (retry_count < 0)
10334                                         errx(1, "retry count %d is < 0",
10335                                              retry_count);
10336                                 arglist |= CAM_ARG_RETRIES;
10337                                 break;
10338                         case 'E':
10339                                 arglist |= CAM_ARG_ERR_RECOVER;
10340                                 break;
10341                         case 'n':
10342                                 arglist |= CAM_ARG_DEVICE;
10343                                 tstr = optarg;
10344                                 while (isspace(*tstr) && (*tstr != '\0'))
10345                                         tstr++;
10346                                 device = (char *)strdup(tstr);
10347                                 break;
10348                         case 'Q': {
10349                                 char *endptr;
10350                                 int table_entry = 0;
10351
10352                                 tstr = optarg;
10353                                 while (isspace(*tstr) && (*tstr != '\0'))
10354                                         tstr++;
10355                                 if (isdigit(*tstr)) {
10356                                         task_attr = strtol(tstr, &endptr, 0);
10357                                         if (*endptr != '\0') {
10358                                                 errx(1, "Invalid queue option "
10359                                                     "%s", tstr);
10360                                         }
10361                                 } else {
10362                                         size_t table_size;
10363                                         scsi_nv_status status;
10364
10365                                         table_size = sizeof(task_attrs) /
10366                                                      sizeof(task_attrs[0]);
10367                                         status = scsi_get_nv(task_attrs,
10368                                             table_size, tstr, &table_entry,
10369                                             SCSI_NV_FLAG_IG_CASE);
10370                                         if (status == SCSI_NV_FOUND)
10371                                                 task_attr = task_attrs[
10372                                                     table_entry].value;
10373                                         else {
10374                                                 errx(1, "%s option %s",
10375                                                   (status == SCSI_NV_AMBIGUOUS)?
10376                                                     "ambiguous" : "invalid",
10377                                                     tstr);
10378                                         }
10379                                 }
10380                                 break;
10381                         }
10382                         case 't':
10383                                 timeout = strtol(optarg, NULL, 0);
10384                                 if (timeout < 0)
10385                                         errx(1, "invalid timeout %d", timeout);
10386                                 /* Convert the timeout from seconds to ms */
10387                                 timeout *= 1000;
10388                                 arglist |= CAM_ARG_TIMEOUT;
10389                                 break;
10390                         case 'u':
10391                                 arglist |= CAM_ARG_UNIT;
10392                                 unit = strtol(optarg, NULL, 0);
10393                                 break;
10394                         case 'v':
10395                                 arglist |= CAM_ARG_VERBOSE;
10396                                 break;
10397                         default:
10398                                 break;
10399                 }
10400         }
10401
10402         /*
10403          * For most commands we'll want to open the passthrough device
10404          * associated with the specified device.  In the case of the rescan
10405          * commands, we don't use a passthrough device at all, just the
10406          * transport layer device.
10407          */
10408         if (devopen == 1) {
10409                 if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0)
10410                  && (((arglist & CAM_ARG_DEVICE) == 0)
10411                   || ((arglist & CAM_ARG_UNIT) == 0))) {
10412                         errx(1, "subcommand \"%s\" requires a valid device "
10413                              "identifier", argv[1]);
10414                 }
10415
10416                 if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))?
10417                                 cam_open_btl(bus, target, lun, O_RDWR, NULL) :
10418                                 cam_open_spec_device(device,unit,O_RDWR,NULL)))
10419                      == NULL)
10420                         errx(1,"%s", cam_errbuf);
10421         }
10422
10423         /*
10424          * Reset optind to 2, and reset getopt, so these routines can parse
10425          * the arguments again.
10426          */
10427         optind = optstart;
10428         optreset = 1;
10429
10430         switch(cmdlist) {
10431         case CAM_CMD_DEVLIST:
10432                 error = getdevlist(cam_dev);
10433                 break;
10434         case CAM_CMD_HPA:
10435                 error = atahpa(cam_dev, retry_count, timeout,
10436                                argc, argv, combinedopt);
10437                 break;
10438         case CAM_CMD_AMA:
10439                 error = ataama(cam_dev, retry_count, timeout,
10440                                argc, argv, combinedopt);
10441                 break;
10442         case CAM_CMD_DEVTREE:
10443                 error = getdevtree(argc, argv, combinedopt);
10444                 break;
10445         case CAM_CMD_DEVTYPE:
10446                 error = getdevtype(cam_dev);
10447                 break;
10448         case CAM_CMD_TUR:
10449                 error = testunitready(cam_dev, task_attr, retry_count,
10450                     timeout, 0);
10451                 break;
10452         case CAM_CMD_INQUIRY:
10453                 error = scsidoinquiry(cam_dev, argc, argv, combinedopt,
10454                                       task_attr, retry_count, timeout);
10455                 break;
10456         case CAM_CMD_IDENTIFY:
10457                 error = identify(cam_dev, retry_count, timeout);
10458                 break;
10459         case CAM_CMD_STARTSTOP:
10460                 error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT,
10461                                   arglist & CAM_ARG_EJECT, task_attr,
10462                                   retry_count, timeout);
10463                 break;
10464         case CAM_CMD_RESCAN:
10465                 error = dorescan_or_reset(argc, argv, 1);
10466                 break;
10467         case CAM_CMD_RESET:
10468                 error = dorescan_or_reset(argc, argv, 0);
10469                 break;
10470         case CAM_CMD_READ_DEFECTS:
10471                 error = readdefects(cam_dev, argc, argv, combinedopt,
10472                                     task_attr, retry_count, timeout);
10473                 break;
10474         case CAM_CMD_MODE_PAGE:
10475                 modepage(cam_dev, argc, argv, combinedopt,
10476                          task_attr, retry_count, timeout);
10477                 break;
10478         case CAM_CMD_SCSI_CMD:
10479                 error = scsicmd(cam_dev, argc, argv, combinedopt,
10480                                 task_attr, retry_count, timeout);
10481                 break;
10482         case CAM_CMD_MMCSD_CMD:
10483                 error = mmcsdcmd(cam_dev, argc, argv, combinedopt,
10484                                         retry_count, timeout);
10485                 break;
10486         case CAM_CMD_SMP_CMD:
10487                 error = smpcmd(cam_dev, argc, argv, combinedopt,
10488                                retry_count, timeout);
10489                 break;
10490         case CAM_CMD_SMP_RG:
10491                 error = smpreportgeneral(cam_dev, argc, argv,
10492                                          combinedopt, retry_count,
10493                                          timeout);
10494                 break;
10495         case CAM_CMD_SMP_PC:
10496                 error = smpphycontrol(cam_dev, argc, argv, combinedopt,
10497                                       retry_count, timeout);
10498                 break;
10499         case CAM_CMD_SMP_PHYLIST:
10500                 error = smpphylist(cam_dev, argc, argv, combinedopt,
10501                                    retry_count, timeout);
10502                 break;
10503         case CAM_CMD_SMP_MANINFO:
10504                 error = smpmaninfo(cam_dev, argc, argv, combinedopt,
10505                                    retry_count, timeout);
10506                 break;
10507         case CAM_CMD_DEBUG:
10508                 error = camdebug(argc, argv, combinedopt);
10509                 break;
10510         case CAM_CMD_TAG:
10511                 error = tagcontrol(cam_dev, argc, argv, combinedopt);
10512                 break;
10513         case CAM_CMD_RATE:
10514                 error = ratecontrol(cam_dev, task_attr, retry_count,
10515                                     timeout, argc, argv, combinedopt);
10516                 break;
10517         case CAM_CMD_FORMAT:
10518                 error = scsiformat(cam_dev, argc, argv,
10519                                    combinedopt, task_attr, retry_count,
10520                                    timeout);
10521                 break;
10522         case CAM_CMD_REPORTLUNS:
10523                 error = scsireportluns(cam_dev, argc, argv,
10524                                        combinedopt, task_attr,
10525                                        retry_count, timeout);
10526                 break;
10527         case CAM_CMD_READCAP:
10528                 error = scsireadcapacity(cam_dev, argc, argv,
10529                                          combinedopt, task_attr,
10530                                          retry_count, timeout);
10531                 break;
10532         case CAM_CMD_IDLE:
10533         case CAM_CMD_STANDBY:
10534         case CAM_CMD_SLEEP:
10535         case CAM_CMD_POWER_MODE:
10536                 error = atapm(cam_dev, argc, argv,
10537                               combinedopt, retry_count, timeout);
10538                 break;
10539         case CAM_CMD_APM:
10540         case CAM_CMD_AAM:
10541                 error = ataaxm(cam_dev, argc, argv,
10542                               combinedopt, retry_count, timeout);
10543                 break;
10544         case CAM_CMD_SECURITY:
10545                 error = atasecurity(cam_dev, retry_count, timeout,
10546                                     argc, argv, combinedopt);
10547                 break;
10548         case CAM_CMD_DOWNLOAD_FW:
10549                 error = fwdownload(cam_dev, argc, argv, combinedopt,
10550                     arglist & CAM_ARG_VERBOSE, task_attr, retry_count,
10551                     timeout);
10552                 break;
10553         case CAM_CMD_SANITIZE:
10554                 error = sanitize(cam_dev, argc, argv, combinedopt, task_attr,
10555                                  retry_count, timeout);
10556                 break;
10557         case CAM_CMD_PERSIST:
10558                 error = scsipersist(cam_dev, argc, argv, combinedopt,
10559                     task_attr, retry_count, timeout,
10560                     arglist & CAM_ARG_VERBOSE,
10561                     arglist & CAM_ARG_ERR_RECOVER);
10562                 break;
10563         case CAM_CMD_ATTRIB:
10564                 error = scsiattrib(cam_dev, argc, argv, combinedopt,
10565                     task_attr, retry_count, timeout,
10566                     arglist & CAM_ARG_VERBOSE,
10567                     arglist & CAM_ARG_ERR_RECOVER);
10568                 break;
10569         case CAM_CMD_OPCODES:
10570                 error = scsiopcodes(cam_dev, argc, argv, combinedopt,
10571                     task_attr, retry_count, timeout,
10572                     arglist & CAM_ARG_VERBOSE);
10573                 break;
10574         case CAM_CMD_REPROBE:
10575                 error = reprobe(cam_dev);
10576                 break;
10577         case CAM_CMD_ZONE:
10578                 error = zone(cam_dev, argc, argv, combinedopt,
10579                     task_attr, retry_count, timeout,
10580                     arglist & CAM_ARG_VERBOSE);
10581                 break;
10582         case CAM_CMD_EPC:
10583                 error = epc(cam_dev, argc, argv, combinedopt,
10584                     retry_count, timeout, arglist & CAM_ARG_VERBOSE);
10585                 break;
10586         case CAM_CMD_TIMESTAMP:
10587                 error = timestamp(cam_dev, argc, argv, combinedopt,
10588                     task_attr, retry_count, timeout,
10589                     arglist & CAM_ARG_VERBOSE);
10590                 break;
10591         case CAM_CMD_USAGE:
10592                 usage(1);
10593                 break;
10594         default:
10595                 usage(0);
10596                 error = 1;
10597                 break;
10598         }
10599
10600         if (cam_dev != NULL)
10601                 cam_close_device(cam_dev);
10602
10603         exit(error);
10604 }