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