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