20#include <sys/utsname.h>
28#define ARGUSED(x) ((void)(x))
88 fd =
::open(dev,O_RDWR|O_NONBLOCK);
90 if (fd < 0 && errno == EROFS)
91 fd =
::open(dev,O_RDONLY|O_NONBLOCK);
97 if ((fd =
::open(dev,O_RDWR|O_NONBLOCK))<0) {
117 if(failed)
return false;
133 virtual int do_cmd(
struct atareq* request,
bool is_48bit_cmd);
146 ret = ioctl(fd, ATAIOCCOMMAND, request);
153 bool ata_48bit =
false;
160 set_err(ENOSYS,
"48-bit ATA commands not implemented");
166 memset(&req, 0,
sizeof(req));
177 req.flags = ATACMD_READREG;
180 req.flags = ATACMD_READ | ATACMD_READREG;
181 req.databuf = (
char *)in.
buffer;
182 req.datalen = in.
size;
185 req.flags = ATACMD_WRITE | ATACMD_READREG;
186 req.databuf = (
char *)in.
buffer;
187 req.datalen = in.
size;
197 if (req.retsts != ATACMD_OK)
198 return set_err(EIO,
"request failed, error code 0x%02x", req.retsts);
230 const char * dev_name,
const char * req_type,
bool scanning )
244 const unsigned char * ucp = iop->
cmnd;
248 pout(
" [%s: ", np ? np :
"<unknown opcode>");
250 pout(
"%02x ", ucp[k]);
253 int trunc = (iop->
dxfer_len > 256) ? 1 : 0;
256 (trunc ?
" [only first 256 bytes shown]" :
""));
263 memset(&sc, 0,
sizeof(sc));
266 sc.databuf = (
char *)iop->
dxferp;
274 if (ioctl(fd, SCIOCCOMMAND, &sc) < 0) {
276 pout(
" error sending SCSI ccb\n");
280 iop->
resid = sc.datalen - sc.datalen_used;
283 memcpy(iop->
sensep, sc.sense, sc.senselen_used);
293 (trunc ?
" [only first 256 bytes shown]" :
""));
310 bool sat_only =
false;
321 unsigned char req_buff[64] = {0, };
330 set_err(EIO,
"INQUIRY failed");
335 int avail_len = req_buff[4] + 5;
336 int len = (avail_len < req_len ? avail_len : req_len);
340 set_err(EIO,
"INQUIRY too short for SAT");
360 set_err(EIO,
"Not a SAT device");
377 const char * pattern = 0)
override;
399 struct utsname osname;
401 return strprintf(
"%s %s %s", osname.sysname, osname.release, osname.machine);
406 if (!strcmp(appname,
"smartctl")) {
409 p =
'a' + getrawpartition();
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);
439 char *disknames, *p, **mp;
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");
452 if (!(disknames = (
char *)malloc(sysctl_len))) {
453 pout(
"Out of memory constructing scan device list\n");
456 if (-1 == sysctl(sysctl_mib, 2, disknames, &sysctl_len, NULL, 0)) {
457 pout(
"Failed to get value of sysctl `hw.disknames'\n");
460 if (!(mp = (
char **) calloc(strlen(disknames) / 2,
sizeof(
char *)))) {
461 pout(
"Out of memory constructing scan device list\n");
465 for (p = strtok(disknames,
","); p; p = strtok(NULL,
",")) {
466 if (strncmp(p, prefix, strlen(prefix))) {
469 char * u = strchr(p,
':');
474 pout(
"Out of memory constructing scan device list\n");
477 sprintf(mp[n],
"%s%s%c",
net_dev_prefix, p,
'a' + getrawpartition());
481 char ** tmp = (
char **)realloc(mp, n * (
sizeof(
char *)));
483 pout(
"Out of memory constructing scan device list\n");
495 const char * type,
const char * pattern )
498 set_err(EINVAL,
"DEVICESCAN with pattern not implemented yet");
505 bool scan_ata = !*type || !strcmp(type,
"ata");
506 bool scan_scsi = !*type || !strcmp(type,
"scsi") || !strcmp(type,
"sat");
509 char * * atanames = 0;
int numata = 0;
518 char * * scsinames = 0;
int numscsi = 0;
519 char * * scsitapenames = 0;
int numscsitape = 0;
527 if (numscsitape < 0) {
535 for (i = 0; i < numata; i++) {
541 if(numata) free(atanames);
543 for (i = 0; i < numscsi; i++) {
549 if(numscsi) free(scsinames);
551 for (i = 0; i < numscsitape; i++) {
555 free(scsitapenames[i]);
557 if(numscsitape) free(scsitapenames);
564 const char * test_name = name;
573 if (!lstat(name, &st) && S_ISLNK(st.st_mode)) {
574 char * p = realpath(name, (
char *)0);
578 test_name = pathbuf.c_str();
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.
virtual int do_cmd(struct atareq *request, bool is_48bit_cmd)
openbsd_ata_device(smart_interface *intf, const char *dev_name, const char *req_type)
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
openbsd_scsi_device(smart_interface *intf, const char *dev_name, const char *req_type, bool scanning=false)
virtual bool scsi_pass_through(scsi_cmnd_io *iop) override
SCSI pass through.
virtual smart_device * autodetect_open() override
Open device with autodetection support.
bool m_scanning
true if created within scan_smart_devices
Implement shared open/close routines with old functions.
int m_fd
filedesc, -1 if not open.
virtual bool close()
Close device, return false on error.
virtual bool is_open() const
Return true if device is open.
int get_fd() const
Return filedesc for derived classes.
virtual bool open()
Open device, return false on error.
virtual ~openbsd_smart_device()
Implement platform interface with old functions.
virtual std::string get_os_version_str() override
Return info string about build host and/or OS version.
virtual smart_device * get_custom_smart_device(const char *name, const char *type) override
Return device for platform specific 'type'.
int get_dev_names(char ***, const char *)
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'.
virtual std::string get_valid_custom_dev_types_str() override
Return valid 'type' args accepted by above.
virtual ata_device * get_ata_device(const char *name, const char *type) override
Return standard ATA device.
virtual smart_device * autodetect_smart_device(const char *name) override
Autodetect device if no device type specified.
virtual scsi_device * get_scsi_device(const char *name, const char *type) override
Return standard SCSI device.
virtual std::string get_app_examples(const char *appname) override
Return example string for program 'appname'.
List of devices for DEVICESCAN.
void push_back(smart_device *dev)
Base class for all devices.
bool is_scsi() const
Return true if SCSI device.
smart_interface * smi()
Get interface which produced this object.
const char * get_req_type() const
Get type requested by user, empty if none.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
bool is_ata() const
Return true if ATA device.
const char * get_dev_name() const
Get device (path)name.
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().
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.
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
static const char * net_dev_ata_disk
static const char * net_dev_prefix
static const char * net_dev_scsi_tape
const char * os_openbsd_cpp_cvsid
#define OS_OPENBSD_H_CVSID
int scsiStdInquiry(scsi_device *device, uint8_t *pBuf, int bufLen)
void dStrHex(const uint8_t *up, int len, int no_ascii)
unsigned char scsi_debugmode
const char * scsi_get_opcode_name(const uint8_t *cdbp)
#define DXFER_FROM_DEVICE
#define SCSI_TIMEOUT_DEFAULT
void pout(const char *fmt,...)
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 sector_count
ata_register sector_count
std::string strprintf(const char *fmt,...)
bool str_starts_with(const char *str, const char *prefix)