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