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