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