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