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