smartmontools  SVN Rev 5304
Utility to control and monitor storage systems with "S.M.A.R.T."
os_openbsd.cpp
Go to the documentation of this file.
1 /*
2  * os_openbsd.cpp
3  *
4  * Home page of code is: https://www.smartmontools.org
5  *
6  * Copyright (C) 2004-10 David Snyder
7  *
8  * Derived from os_netbsd.cpp by Sergey Svishchev, Copyright (C) 2003-8
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12 
13 #include "config.h"
14 
15 #include "atacmds.h"
16 #include "scsicmds.h"
17 #include "utility.h"
18 #include "os_openbsd.h"
19 
20 #include <sys/utsname.h>
21 #include <errno.h>
22 #include <sys/stat.h>
23 #include <util.h>
24 
25 const char * os_openbsd_cpp_cvsid = "$Id: os_openbsd.cpp 5215 2021-04-07 06:42:07Z samm2 $"
27 
28 #define ARGUSED(x) ((void)(x))
29 
30 /////////////////////////////////////////////////////////////////////////////
31 
32 namespace os_openbsd { // No need to publish anything, name provided for Doxygen
33 
34 static const char *net_dev_prefix = "/dev/";
35 static const char *net_dev_ata_disk = "wd";
36 static const char *net_dev_scsi_disk = "sd";
37 static const char *net_dev_scsi_tape = "st";
38 
39 /////////////////////////////////////////////////////////////////////////////
40 /// Implement shared open/close routines with old functions.
41 
43 : virtual public /*implements*/ smart_device
44 {
45 public:
48  m_fd(-1) { }
49 
50  virtual ~openbsd_smart_device();
51 
52  virtual bool is_open() const;
53 
54  virtual bool open();
55 
56  virtual bool close();
57 
58 protected:
59  /// Return filedesc for derived classes.
60  int get_fd() const
61  { return m_fd; }
62 
63  void set_fd(int fd)
64  { m_fd = fd; }
65 
66 private:
67  int m_fd; ///< filedesc, -1 if not open.
68 };
69 
71 {
72  if (m_fd >= 0)
74 }
75 
77 {
78  return (m_fd >= 0);
79 }
80 
81 
83 {
84  const char *dev = get_dev_name();
85  int fd;
86 
87  if (is_scsi()) {
88  fd = ::open(dev,O_RDWR|O_NONBLOCK);
89 
90  if (fd < 0 && errno == EROFS)
91  fd = ::open(dev,O_RDONLY|O_NONBLOCK);
92  if (fd < 0) {
93  set_err(errno);
94  return false;
95  }
96  } else if (is_ata()) {
97  if ((fd = ::open(dev,O_RDWR|O_NONBLOCK))<0) {
98  set_err(errno);
99  return false;
100  }
101  } else
102  return false;
103 
104  set_fd(fd);
105  return true;
106 }
107 
109 {
110  int failed = 0;
111  // close device, if open
112  if (is_open())
113  failed=::close(get_fd());
114 
115  set_fd(-1);
116 
117  if(failed) return false;
118  else return true;
119 }
120 
121 /////////////////////////////////////////////////////////////////////////////
122 /// Implement standard ATA support
123 
125 : public /*implements*/ ata_device,
126  public /*extends*/ openbsd_smart_device
127 {
128 public:
129  openbsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type);
130  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
131 
132 protected:
133  virtual int do_cmd(struct atareq* request, bool is_48bit_cmd);
134 };
135 
136 openbsd_ata_device::openbsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
137 : smart_device(intf, dev_name, "ata", req_type),
139 {
140 }
141 
142 int openbsd_ata_device::do_cmd( struct atareq* request, bool is_48bit_cmd)
143 {
144  int fd = get_fd(), ret;
145  ARGUSED(is_48bit_cmd); // no support for 48 bit commands in the ATAIOCCOMMAND
146  ret = ioctl(fd, ATAIOCCOMMAND, request);
147  if (ret) set_err(errno);
148  return ret;
149 }
150 
152 {
153  bool ata_48bit = false; // no ata_48bit_support via ATAIOCCOMMAND
154 
155  if (!ata_cmd_is_ok(in,
156  true, // data_out_support
157  true, // multi_sector_support
158  ata_48bit)
159  ) {
160  set_err(ENOSYS, "48-bit ATA commands not implemented");
161  return false;
162  }
163 
164  struct atareq req;
165 
166  memset(&req, 0, sizeof(req));
167  req.command = in.in_regs.command;
168  req.features = in.in_regs.features;
169  req.sec_count = in.in_regs.sector_count;
170  req.sec_num = in.in_regs.lba_low;
171  req.head = in.in_regs.device;
172  req.cylinder = in.in_regs.lba_mid | (in.in_regs.lba_high << 8);
173  req.timeout = SCSI_TIMEOUT_DEFAULT * 1000;
174 
175  switch (in.direction) {
176  case ata_cmd_in::no_data:
177  req.flags = ATACMD_READREG;
178  break;
179  case ata_cmd_in::data_in:
180  req.flags = ATACMD_READ | ATACMD_READREG;
181  req.databuf = (char *)in.buffer;
182  req.datalen = in.size;
183  break;
185  req.flags = ATACMD_WRITE | ATACMD_READREG;
186  req.databuf = (char *)in.buffer;
187  req.datalen = in.size;
188  break;
189  default:
190  return set_err(ENOSYS);
191  }
192 
193  clear_err();
194  errno = 0;
195  if (do_cmd(&req, in.in_regs.is_48bit_cmd()))
196  return false;
197  if (req.retsts != ATACMD_OK)
198  return set_err(EIO, "request failed, error code 0x%02x", req.retsts);
199 
200  out.out_regs.error = req.error;
201  out.out_regs.sector_count = req.sec_count;
202  out.out_regs.lba_low = req.sec_num;
203  out.out_regs.device = req.head;
204  out.out_regs.lba_mid = req.cylinder;
205  out.out_regs.lba_high = req.cylinder >> 8;
206  out.out_regs.status = req.command;
207 
208  return true;
209 }
210 
211 /////////////////////////////////////////////////////////////////////////////
212 /// Standard SCSI support
213 
215 : public /*implements*/ scsi_device,
216  public /*extends*/ openbsd_smart_device
217 {
218 public:
219  openbsd_scsi_device(smart_interface * intf, const char * dev_name, const char * req_type, bool scanning = false);
220 
221  virtual smart_device * autodetect_open() override;
222 
223  virtual bool scsi_pass_through(scsi_cmnd_io * iop) override;
224 
225 private:
226  bool m_scanning; ///< true if created within scan_smart_devices
227 };
228 
230  const char * dev_name, const char * req_type, bool scanning /* = false */)
231 : smart_device(intf, dev_name, "scsi", req_type),
233  m_scanning(scanning)
234 {
235 }
236 
238 {
239  struct scsireq sc;
240  int fd = get_fd();
241 
242  if (scsi_debugmode) {
243  unsigned int k;
244  const unsigned char * ucp = iop->cmnd;
245  const char * np;
246 
247  np = scsi_get_opcode_name(ucp[0]);
248  pout(" [%s: ", np ? np : "<unknown opcode>");
249  for (k = 0; k < iop->cmnd_len; ++k)
250  pout("%02x ", ucp[k]);
251  if ((scsi_debugmode > 1) &&
252  (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
253  int trunc = (iop->dxfer_len > 256) ? 1 : 0;
254 
255  pout("]\n Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
256  (trunc ? " [only first 256 bytes shown]" : ""));
257  dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
258  }
259  else
260  pout("]\n");
261  }
262 
263  memset(&sc, 0, sizeof(sc));
264  memcpy(sc.cmd, iop->cmnd, iop->cmnd_len);
265  sc.cmdlen = iop->cmnd_len;
266  sc.databuf = (char *)iop->dxferp;
267  sc.datalen = iop->dxfer_len;
268  sc.senselen = iop->max_sense_len;
269  sc.timeout = (iop->timeout == 0 ? 60 : iop->timeout) * 1000;
270  sc.flags =
271  (iop->dxfer_dir == DXFER_NONE ? SCCMD_READ :
272  (iop->dxfer_dir == DXFER_FROM_DEVICE ? SCCMD_READ : SCCMD_WRITE));
273 
274  if (ioctl(fd, SCIOCCOMMAND, &sc) < 0) {
275  if (scsi_debugmode) {
276  pout(" error sending SCSI ccb\n");
277  }
278  return set_err(EIO);
279  }
280  iop->resid = sc.datalen - sc.datalen_used;
281  iop->scsi_status = sc.status;
282  if (iop->sensep) {
283  memcpy(iop->sensep, sc.sense, sc.senselen_used);
284  iop->resp_sense_len = sc.senselen_used;
285  }
286  if (scsi_debugmode) {
287  int trunc;
288 
289  pout(" status=0\n");
290  trunc = (iop->dxfer_len > 256) ? 1 : 0;
291 
292  pout(" Incoming data, len=%d%s:\n", (int) iop->dxfer_len,
293  (trunc ? " [only first 256 bytes shown]" : ""));
294  dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len), 1);
295  }
296  // XXX we probably need error handling here
297  return true;
298 }
299 
300 /////////////////////////////////////////////////////////////////////////////
301 ///// SCSI open with autodetection support
302 
304 {
305  // Open device
306  if (!open())
307  return this;
308 
309  // No Autodetection if device type was specified by user
310  bool sat_only = false;
311  if (*get_req_type()) {
312  // Detect SAT if device object was created by scan_smart_devices().
313  if (!(m_scanning && !strcmp(get_req_type(), "sat")))
314  return this;
315  sat_only = true;
316  }
317 
318  // The code below is based on smartd.cpp:SCSIFilterKnown()
319 
320  // Get INQUIRY
321  unsigned char req_buff[64] = {0, };
322  int req_len = 36;
323  if (scsiStdInquiry(this, req_buff, req_len)) {
324  // Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices
325  // watch this spot ... other devices could lock up here
326  req_len = 64;
327  if (scsiStdInquiry(this, req_buff, req_len)) {
328  // device doesn't like INQUIRY commands
329  close();
330  set_err(EIO, "INQUIRY failed");
331  return this;
332  }
333  }
334 
335  int avail_len = req_buff[4] + 5;
336  int len = (avail_len < req_len ? avail_len : req_len);
337  if (len < 36) {
338  if (sat_only) {
339  close();
340  set_err(EIO, "INQUIRY too short for SAT");
341  }
342  return this;
343  }
344 
345  // Use INQUIRY to detect type
346 
347  // SAT or USB, skip MFI controllers because of bugs
348  {
349  smart_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
350  if (newdev) {
351  // NOTE: 'this' is now owned by '*newdev'
352  return newdev;
353  }
354  }
355 
356  // Nothing special found
357 
358  if (sat_only) {
359  close();
360  set_err(EIO, "Not a SAT device");
361  }
362  return this;
363 }
364 
365 /////////////////////////////////////////////////////////////////////////////
366 /// Implement platform interface with old functions.
367 
369 : public /*implements*/ smart_interface
370 {
371 public:
372  virtual std::string get_os_version_str() override;
373 
374  virtual std::string get_app_examples(const char * appname) override;
375 
376  virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
377  const char * pattern = 0) override;
378 
379 protected:
380  virtual ata_device * get_ata_device(const char * name, const char * type) override;
381 
382  virtual scsi_device * get_scsi_device(const char * name, const char * type) override;
383 
384  virtual smart_device * autodetect_smart_device(const char * name) override;
385 
386  virtual smart_device * get_custom_smart_device(const char * name, const char * type) override;
387 
388  virtual std::string get_valid_custom_dev_types_str() override;
389 
390 private:
391  int get_dev_names(char ***, const char *);
392 };
393 
394 
395 //////////////////////////////////////////////////////////////////////
396 
398 {
399  struct utsname osname;
400  uname(&osname);
401  return strprintf("%s %s %s", osname.sysname, osname.release, osname.machine);
402 }
403 
404 std::string openbsd_smart_interface::get_app_examples(const char * appname)
405 {
406  if (!strcmp(appname, "smartctl")) {
407  char p;
408 
409  p = 'a' + getrawpartition();
410  return strprintf(
411  "=================================================== SMARTCTL EXAMPLES =====\n\n"
412  " smartctl -a /dev/wd0%c (Prints all SMART information)\n\n"
413  " smartctl --smart=on --offlineauto=on --saveauto=on /dev/wd0%c\n"
414  " (Enables SMART on first disk)\n\n"
415  " smartctl -t long /dev/wd0%c (Executes extended disk self-test)\n\n"
416  " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/wd0%c\n"
417  " (Prints Self-Test & Attribute errors)\n"
418  " smartctl -a /dev/wd0%c (Prints all SMART information)\n"
419  " smartctl -s on -o on -S on /dev/wd0%c (Enables SMART on first disk)\n"
420  " smartctl -t long /dev/wd0%c (Executes extended disk self-test)\n"
421  " smartctl -A -l selftest -q errorsonly /dev/wd0%c"
422  " (Prints Self-Test & Attribute errors)\n",
423  p, p, p, p, p, p, p, p);
424  }
425  return "";
426 }
427 ata_device * openbsd_smart_interface::get_ata_device(const char * name, const char * type)
428 {
429  return new openbsd_ata_device(this, name, type);
430 }
431 
432 scsi_device * openbsd_smart_interface::get_scsi_device(const char * name, const char * type)
433 {
434  return new openbsd_scsi_device(this, name, type);
435 }
436 
437 int openbsd_smart_interface::get_dev_names(char ***names, const char *prefix)
438 {
439  char *disknames, *p, **mp;
440  int n = 0;
441  int sysctl_mib[2];
442  size_t sysctl_len;
443 
444  *names = NULL;
445 
446  sysctl_mib[0] = CTL_HW;
447  sysctl_mib[1] = HW_DISKNAMES;
448  if (-1 == sysctl(sysctl_mib, 2, NULL, &sysctl_len, NULL, 0)) {
449  pout("Failed to get value of sysctl `hw.disknames'\n");
450  return -1;
451  }
452  if (!(disknames = (char *)malloc(sysctl_len))) {
453  pout("Out of memory constructing scan device list\n");
454  return -1;
455  }
456  if (-1 == sysctl(sysctl_mib, 2, disknames, &sysctl_len, NULL, 0)) {
457  pout("Failed to get value of sysctl `hw.disknames'\n");
458  return -1;
459  }
460  if (!(mp = (char **) calloc(strlen(disknames) / 2, sizeof(char *)))) {
461  pout("Out of memory constructing scan device list\n");
462  return -1;
463  }
464 
465  for (p = strtok(disknames, ","); p; p = strtok(NULL, ",")) {
466  if (strncmp(p, prefix, strlen(prefix))) {
467  continue;
468  }
469  char * u = strchr(p, ':');
470  if (u)
471  *u = 0;
472  mp[n] = (char *)malloc(strlen(net_dev_prefix) + strlen(p) + 2);
473  if (!mp[n]) {
474  pout("Out of memory constructing scan device list\n");
475  return -1;
476  }
477  sprintf(mp[n], "%s%s%c", net_dev_prefix, p, 'a' + getrawpartition());
478  n++;
479  }
480 
481  char ** tmp = (char **)realloc(mp, n * (sizeof(char *)));
482  if (NULL == tmp) {
483  pout("Out of memory constructing scan device list\n");
484  free(mp);
485  return -1;
486  }
487  else
488  mp = tmp;
489  *names = mp;
490  return n;
491 }
492 
493 
495  const char * type, const char * pattern /*= 0*/)
496  {
497  if (pattern) {
498  set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
499  return false;
500  }
501 
502  if (type == NULL)
503  type = "";
504 
505  bool scan_ata = !*type || !strcmp(type, "ata");
506  bool scan_scsi = !*type || !strcmp(type, "scsi") || !strcmp(type, "sat");
507 
508  // Make namelists
509  char * * atanames = 0; int numata = 0;
510  if (scan_ata) {
511  numata = get_dev_names(&atanames, net_dev_ata_disk);
512  if (numata < 0) {
513  set_err(ENOMEM);
514  return false;
515  }
516  }
517 
518  char * * scsinames = 0; int numscsi = 0;
519  char * * scsitapenames = 0; int numscsitape = 0;
520  if (scan_scsi) {
521  numscsi = get_dev_names(&scsinames, net_dev_scsi_disk);
522  if (numscsi < 0) {
523  set_err(ENOMEM);
524  return false;
525  }
526  numscsitape = get_dev_names(&scsitapenames, net_dev_scsi_tape);
527  if (numscsitape < 0) {
528  set_err(ENOMEM);
529  return false;
530  }
531  }
532 
533  // Add to devlist
534  int i;
535  for (i = 0; i < numata; i++) {
536  ata_device * atadev = get_ata_device(atanames[i], type);
537  if (atadev)
538  devlist.push_back(atadev);
539  free(atanames[i]);
540  }
541  if(numata) free(atanames);
542 
543  for (i = 0; i < numscsi; i++) {
544  scsi_device * scsidev = new openbsd_scsi_device(this, scsinames[i], type, true /*scanning*/);
545  if (scsidev)
546  devlist.push_back(scsidev);
547  free(scsinames[i]);
548  }
549  if(numscsi) free(scsinames);
550 
551  for (i = 0; i < numscsitape; i++) {
552  scsi_device * scsidev = get_scsi_device(scsitapenames[i], type);
553  if (scsidev)
554  devlist.push_back(scsidev);
555  free(scsitapenames[i]);
556  }
557  if(numscsitape) free(scsitapenames);
558 
559  return true;
560 }
561 
563 {
564  const char * test_name = name;
565 
566  // if dev_name null, or string length zero
567  if (!name || !*name)
568  return 0;
569 
570  // Dereference symlinks
571  struct stat st;
572  std::string pathbuf;
573  if (!lstat(name, &st) && S_ISLNK(st.st_mode)) {
574  char * p = realpath(name, (char *)0);
575  if (p) {
576  pathbuf = p;
577  free(p);
578  test_name = pathbuf.c_str();
579  }
580  }
581 
582  if (str_starts_with(test_name, net_dev_prefix)) {
583  test_name += strlen(net_dev_prefix);
584  if (!strncmp(net_dev_ata_disk, test_name, strlen(net_dev_ata_disk)))
585  return get_ata_device(name, "ata");
586  if (!strncmp(net_dev_scsi_disk, test_name, strlen(net_dev_scsi_disk))) {
587  // XXX Try to detect possible USB->(S)ATA bridge
588  // XXX get USB vendor ID, product ID and version from sd(4)/umass(4).
589  // XXX check sat device via get_usb_dev_type_by_id().
590 
591  // No USB bridge found, assume regular SCSI or SAT device
592  return get_scsi_device(name, "");
593  }
594  if (!strncmp(net_dev_scsi_tape, test_name, strlen(net_dev_scsi_tape)))
595  return get_scsi_device(name, "scsi");
596  }
597  // device type unknown
598  return 0;
599 }
600 
601 
602 smart_device * openbsd_smart_interface::get_custom_smart_device(const char * name, const char * type)
603 {
604  ARGUSED(name);
605  ARGUSED(type);
606  return 0;
607 }
608 
610 {
611  return "";
612 }
613 
614 } // namespace
615 
616 /////////////////////////////////////////////////////////////////////////////
617 /// Initialize platform interface and register with smi()
618 
620 {
621  static os_openbsd::openbsd_smart_interface the_interface;
622  smart_interface::set(&the_interface);
623 }
ATA device access.
bool ata_cmd_is_ok(const ata_cmd_in &in, bool data_out_support=false, bool multi_sector_support=false, bool ata_48bit_support=false)
Check command input parameters (old version).
Implement standard ATA support.
Definition: os_openbsd.cpp:127
virtual int do_cmd(struct atareq *request, bool is_48bit_cmd)
Definition: os_openbsd.cpp:142
openbsd_ata_device(smart_interface *intf, const char *dev_name, const char *req_type)
Definition: os_openbsd.cpp:136
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: os_openbsd.cpp:151
Standard SCSI support.
Definition: os_openbsd.cpp:217
openbsd_scsi_device(smart_interface *intf, const char *dev_name, const char *req_type, bool scanning=false)
Definition: os_openbsd.cpp:229
virtual bool scsi_pass_through(scsi_cmnd_io *iop) override
SCSI pass through.
Definition: os_openbsd.cpp:237
virtual smart_device * autodetect_open() override
Open device with autodetection support.
Definition: os_openbsd.cpp:303
bool m_scanning
true if created within scan_smart_devices
Definition: os_openbsd.cpp:226
Implement shared open/close routines with old functions.
Definition: os_openbsd.cpp:44
int m_fd
filedesc, -1 if not open.
Definition: os_openbsd.cpp:67
virtual bool close()
Close device, return false on error.
Definition: os_openbsd.cpp:108
virtual bool is_open() const
Return true if device is open.
Definition: os_openbsd.cpp:76
int get_fd() const
Return filedesc for derived classes.
Definition: os_openbsd.cpp:60
virtual bool open()
Open device, return false on error.
Definition: os_openbsd.cpp:82
Implement platform interface with old functions.
Definition: os_openbsd.cpp:370
virtual std::string get_os_version_str() override
Return info string about build host and/or OS version.
Definition: os_openbsd.cpp:397
virtual smart_device * get_custom_smart_device(const char *name, const char *type) override
Return device for platform specific 'type'.
Definition: os_openbsd.cpp:602
int get_dev_names(char ***, const char *)
Definition: os_openbsd.cpp:437
virtual bool scan_smart_devices(smart_device_list &devlist, const char *type, const char *pattern=0) override
Fill 'devlist' with devices of some 'type' with device names specified by some optional 'pattern'.
Definition: os_openbsd.cpp:494
virtual std::string get_valid_custom_dev_types_str() override
Return valid 'type' args accepted by above.
Definition: os_openbsd.cpp:609
virtual ata_device * get_ata_device(const char *name, const char *type) override
Return standard ATA device.
Definition: os_openbsd.cpp:427
virtual smart_device * autodetect_smart_device(const char *name) override
Autodetect device if no device type specified.
Definition: os_openbsd.cpp:562
virtual scsi_device * get_scsi_device(const char *name, const char *type) override
Return standard SCSI device.
Definition: os_openbsd.cpp:432
virtual std::string get_app_examples(const char *appname) override
Return example string for program 'appname'.
Definition: os_openbsd.cpp:404
SCSI device access.
List of devices for DEVICESCAN.
void push_back(smart_device *dev)
Base class for all devices.
Definition: dev_interface.h:33
bool is_scsi() const
Return true if SCSI device.
Definition: dev_interface.h:89
const char * get_req_type() const
Get type requested by user, empty if none.
smart_interface * smi()
Get interface which produced this object.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
const char * get_dev_name() const
Get device (path)name.
bool is_ata() const
Return true if ATA device.
Definition: dev_interface.h:86
void clear_err()
Clear last error info.
The platform interface abstraction.
static void set(smart_interface *intf)
Set interface to use, must be called from init().
static void init()
Initialize platform interface and register with smi().
Definition: dev_legacy.cpp:334
virtual ata_device * autodetect_sat_device(scsi_device *scsidev, const unsigned char *inqdata, unsigned inqsize)
Try to detect a SAT device behind a SCSI interface.
Definition: scsiata.cpp:1482
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
static const char * net_dev_scsi_disk
Definition: os_openbsd.cpp:36
static const char * net_dev_ata_disk
Definition: os_openbsd.cpp:35
static const char * net_dev_prefix
Definition: os_openbsd.cpp:34
static const char * net_dev_scsi_tape
Definition: os_openbsd.cpp:37
#define ARGUSED(x)
Definition: os_openbsd.cpp:28
const char * os_openbsd_cpp_cvsid
Definition: os_openbsd.cpp:25
#define OS_OPENBSD_H_CVSID
Definition: os_openbsd.h:16
int scsiStdInquiry(scsi_device *device, uint8_t *pBuf, int bufLen)
Definition: scsicmds.cpp:870
const char * scsi_get_opcode_name(uint8_t opcode)
Definition: scsicmds.cpp:233
void dStrHex(const uint8_t *up, int len, int no_ascii)
Definition: scsicmds.cpp:78
unsigned char scsi_debugmode
Definition: scsicmds.cpp:45
#define DXFER_NONE
Definition: scsicmds.h:96
#define DXFER_FROM_DEVICE
Definition: scsicmds.h:97
#define SCSI_TIMEOUT_DEFAULT
Definition: scsicmds.h:352
#define DXFER_TO_DEVICE
Definition: scsicmds.h:98
void pout(const char *fmt,...)
Definition: smartd.cpp:1308
ATA pass through input parameters.
enum ata_cmd_in::@29 direction
I/O direction.
void * buffer
Pointer to data buffer.
ata_in_regs_48bit in_regs
Input registers.
unsigned size
Size of buffer.
ATA pass through output parameters.
ata_out_regs_48bit out_regs
Output registers.
bool is_48bit_cmd() const
Return true if 48-bit command.
ata_register device
ata_register lba_high
ata_register sector_count
ata_register lba_low
ata_register features
ata_register command
ata_register lba_mid
ata_register sector_count
ata_register lba_low
ata_register lba_mid
ata_register error
ata_register lba_high
ata_register device
ata_register status
uint8_t * sensep
Definition: scsicmds.h:108
uint8_t * dxferp
Definition: scsicmds.h:106
int dxfer_dir
Definition: scsicmds.h:104
size_t cmnd_len
Definition: scsicmds.h:103
size_t resp_sense_len
Definition: scsicmds.h:112
size_t dxfer_len
Definition: scsicmds.h:107
size_t max_sense_len
Definition: scsicmds.h:110
uint8_t scsi_status
Definition: scsicmds.h:113
uint8_t * cmnd
Definition: scsicmds.h:102
unsigned timeout
Definition: scsicmds.h:111
std::string strprintf(const char *fmt,...)
Definition: utility.cpp:772
bool str_starts_with(const char *str, const char *prefix)
Definition: utility.h:51