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