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