34 printf(
"=================================================== SMARTCTL EXAMPLES =====\n\n"
35 " smartctl -a /dev/rdsk/c0t0d0s0 (Prints all SMART information)\n\n"
36 " smartctl --smart=on --offlineauto=on --saveauto=on /dev/rdsk/c0t0d0s0\n"
37 " (Enables SMART on first disk)\n\n"
38 " smartctl -t long /dev/rdsk/c0t0d0s0 (Executes extended disk self-test)\n\n"
39 " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/rdsk/c0t0d0s0\n"
40 " (Prints Self-Test & Attribute errors)\n"
58isdevtype(
const char *dev_name,
const char *table[],
int tsize)
60 char devpath[MAXPATHLEN];
64 if (realpath(dev_name, devpath) == NULL)
67 if ((basename = strrchr(devpath,
'/')) == NULL)
72 for (i = 0; i < tsize; i++) {
73 int l = strlen(table[i]);
74 if (strncmp(basename, table[i], l) == 0 && basename[l] ==
'@')
95 return CONTROLLER_SCSI;
97 return CONTROLLER_ATA;
99 return CONTROLLER_UNKNOWN;
113 res->
names =
static_cast<char**
>(realloc(res->
names, res->
maxnames * sizeof (
char *)));
114 if (res->
names == NULL)
125 char pathbuf[MAXPATHLEN];
129 int isdisk = strstr(dir,
"dsk") != NULL;
132 len = snprintf(pathbuf,
sizeof (pathbuf),
"%s/", dir);
133 if (len >=
sizeof (pathbuf))
140 while ((de = readdir(dp)) != NULL) {
141 if (de->d_name[0] ==
'.')
144 if (strlen(de->d_name) + len >= sizeof (pathbuf))
149 p = strstr(de->d_name,
"s0");
151 if (p == NULL || p[2] !=
'\0')
155 for (p = de->d_name; *p; p++)
156 if (!isdigit((
int)(*p)))
161 strcpy(&pathbuf[len], de->d_name);
162 if (testfun(pathbuf)) {
163 if (
addpath(pathbuf, res) == -1) {
181 if (strcmp(name,
"SCSI") == 0) {
186 }
else if (strcmp(name,
"ATA") == 0) {
196 res.
names =
static_cast<char**
>(realloc(res.
names, res.
nnames * sizeof (
char *)));
199 *devlist = res.
names;
206 if (!strcmp(type,
"SCSI"))
207 return open(pathname, O_RDWR | O_NONBLOCK);
208 else if (!strcmp(type,
"ATA"))
209 return open(pathname, O_RDONLY | O_NONBLOCK);
222 pout(
"Device type 'ata' not implemented, try '-d sat' or '-d sat,12' instead.\n");
228#include <sys/scsi/generic/commands.h>
229#include <sys/scsi/generic/status.h>
230#include <sys/scsi/impl/types.h>
231#include <sys/scsi/impl/uscsi.h>
236 struct uscsi_cmd uscsi;
240 const unsigned char * ucp = iop->
cmnd;
244 pout(
" [%s: ", np ? np :
"<unknown opcode>");
245 for (k = 0; k < (int)iop->
cmnd_len; ++k)
246 pout(
"%02x ", ucp[k]);
250 int trunc = (iop->
dxfer_len > 256) ? 1 : 0;
253 (trunc ?
" [only first 256 bytes shown]" :
""));
257 memset(&uscsi, 0,
sizeof (uscsi));
259 uscsi.uscsi_cdb =
reinterpret_cast<char*
>(iop->
cmnd);
262 uscsi.uscsi_timeout = 60;
264 uscsi.uscsi_timeout = iop->
timeout;
265 uscsi.uscsi_bufaddr =
reinterpret_cast<char*
>(iop->
dxferp);
267 uscsi.uscsi_rqbuf =
reinterpret_cast<char*
>(iop->
sensep);
273 uscsi.uscsi_flags = USCSI_READ;
276 uscsi.uscsi_flags = USCSI_WRITE;
281 uscsi.uscsi_flags |= (USCSI_ISOLATE | USCSI_RQENABLE | USCSI_SILENT);
283 if (ioctl(fd, USCSICMD, &uscsi)) {
286 if (! ((EIO == err) && uscsi.uscsi_status))
292 iop->
resid = uscsi.uscsi_resid;
300 iop->
sensep && (len > 3)) {
301 if ((iop->
sensep[0] & 0x7f) > 0x71)
302 pout(
" status=%x: [desc] sense_key=%x asc=%x ascq=%x\n",
306 pout(
" status=%x: sense_key=%x asc=%x ascq=%x\n",
310 pout(
" >>> Sense buffer, len=%d:\n", len);
320 trunc = (len > 256) ? 1 : 0;
321 pout(
" Incoming data, len=%d%s:\n", len,
322 (trunc ?
" [only first 256 bytes shown]" :
""));
static int addpath(const char *path, struct pathlist *res)
static int isatadev(const char *path)
int make_device_names(char ***devlist, const char *name)
static const char * uscsidrvrs[]
static int isdevtype(const char *dev_name, const char *table[], int tsize)
const char * os_solaris_cpp_cvsid
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io *iop, int report)
int deviceopen(const char *pathname, char *type)
static int grokdir(const char *dir, struct pathlist *res, int testfun(const char *))
static const char * atadrvrs[]
int guess_device_type(const char *dev_name)
void print_smartctl_examples()
int ata_command_interface(int, smart_command_set, int, char *)
static int isscsidev(const char *path)
void dStrHex(const uint8_t *up, int len, int no_ascii)
const char * scsi_get_opcode_name(const uint8_t *cdbp)
#define DXFER_FROM_DEVICE
#define SCSI_STATUS_CHECK_CONDITION
void pout(const char *fmt,...)