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