smartmontools SVN Rev 5640
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 "nvmecmds.h"
18#include "utility.h"
19#include "os_openbsd.h"
20
21#include <sys/utsname.h>
22#include <errno.h>
23#include <sys/stat.h>
24#include <util.h>
25
26const char * os_openbsd_cpp_cvsid = "$Id: os_openbsd.cpp 5637 2024-11-18 14:30:27Z chrfranke $"
28
29#define ARGUSED(x) ((void)(x))
30
31// based on OpenBSD "/usr/include/dev/ic/nvmeio.h" && "/usr/include/dev/biovar.h"
32#include "openbsd_nvme_ioctl.h" // NVME_PASSTHROUGH_CMD, nvme_completion_is_error
33
34/////////////////////////////////////////////////////////////////////////////
35
36namespace os_openbsd { // No need to publish anything, name provided for Doxygen
37
38static const char *net_dev_prefix = "/dev/";
39
40bool sd_is_nvme(const char *dev)
41{
42 struct nvme_pt_cmd pt;
43 memset(&pt, 0, sizeof(pt));
45
46 int fd = ::open(dev, O_RDWR);
47 if (fd == -1)
48 return false;
49
50 int status = ioctl(fd, NVME_PASSTHROUGH_CMD, &pt);
51 close(fd);
52
53 return status != -1 || errno != ENOTTY;
54}
55
56static const char *net_dev_ata_disk = "wd";
57static const char *net_dev_scsi_disk = "sd";
58static const char *net_dev_scsi_tape = "st";
59
60/////////////////////////////////////////////////////////////////////////////
61/// Implement shared open/close routines with old functions.
62
64: virtual public /*implements*/ smart_device
65{
66public:
69 m_fd(-1) { }
70
71 virtual ~openbsd_smart_device();
72
73 virtual bool is_open() const;
74
75 virtual bool open();
76
77 virtual bool close();
78
79protected:
80 /// Return filedesc for derived classes.
81 int get_fd() const
82 { return m_fd; }
83
84 void set_fd(int fd)
85 { m_fd = fd; }
86
87private:
88 int m_fd; ///< filedesc, -1 if not open.
89};
90
92{
93 if (m_fd >= 0)
95}
96
98{
99 return (m_fd >= 0);
100}
101
102
104{
105 const char *dev = get_dev_name();
106 int fd;
107
108 if (is_scsi()) {
109 fd = ::open(dev,O_RDWR|O_NONBLOCK);
110
111 if (fd < 0 && errno == EROFS)
112 fd = ::open(dev,O_RDONLY|O_NONBLOCK);
113 if (fd < 0) {
114 set_err(errno);
115 return false;
116 }
117 } else if (is_ata()) {
118 if ((fd = ::open(dev,O_RDWR|O_NONBLOCK))<0) {
119 set_err(errno);
120 return false;
121 }
122 } else
123 return false;
124
125 set_fd(fd);
126 return true;
127}
128
130{
131 int failed = 0;
132 // close device, if open
133 if (is_open())
134 failed=::close(get_fd());
135
136 set_fd(-1);
137
138 if(failed) return false;
139 else return true;
140}
141
142/////////////////////////////////////////////////////////////////////////////
143/// Implement standard ATA support
144
146: public /*implements*/ ata_device,
147 public /*extends*/ openbsd_smart_device
148{
149public:
150 openbsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type);
151 virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
152
153protected:
154 virtual int do_cmd(struct atareq* request, bool is_48bit_cmd);
155};
156
157openbsd_ata_device::openbsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
158: smart_device(intf, dev_name, "ata", req_type),
160{
161}
162
163int openbsd_ata_device::do_cmd( struct atareq* request, bool is_48bit_cmd)
164{
165 int fd = get_fd(), ret;
166 ARGUSED(is_48bit_cmd); // no support for 48 bit commands in the ATAIOCCOMMAND
167 ret = ioctl(fd, ATAIOCCOMMAND, request);
168 if (ret) set_err(errno);
169 return ret;
170}
171
173{
174 bool ata_48bit = false; // no ata_48bit_support via ATAIOCCOMMAND
175
176 if (!ata_cmd_is_ok(in,
177 true, // data_out_support
178 true, // multi_sector_support
179 ata_48bit)
180 ) {
181 set_err(ENOSYS, "48-bit ATA commands not implemented");
182 return false;
183 }
184
185 struct atareq req;
186
187 memset(&req, 0, sizeof(req));
188 req.command = in.in_regs.command;
189 req.features = in.in_regs.features;
190 req.sec_count = in.in_regs.sector_count;
191 req.sec_num = in.in_regs.lba_low;
192 req.head = in.in_regs.device;
193 req.cylinder = in.in_regs.lba_mid | (in.in_regs.lba_high << 8);
194 req.timeout = SCSI_TIMEOUT_DEFAULT * 1000;
195
196 switch (in.direction) {
198 req.flags = ATACMD_READREG;
199 break;
201 req.flags = ATACMD_READ | ATACMD_READREG;
202 req.databuf = (char *)in.buffer;
203 req.datalen = in.size;
204 break;
206 req.flags = ATACMD_WRITE | ATACMD_READREG;
207 req.databuf = (char *)in.buffer;
208 req.datalen = in.size;
209 break;
210 default:
211 return set_err(ENOSYS);
212 }
213
214 clear_err();
215 errno = 0;
216 if (do_cmd(&req, in.in_regs.is_48bit_cmd()))
217 return false;
218 if (req.retsts != ATACMD_OK)
219 return set_err(EIO, "request failed, error code 0x%02x", req.retsts);
220
221 out.out_regs.error = req.error;
222 out.out_regs.sector_count = req.sec_count;
223 out.out_regs.lba_low = req.sec_num;
224 out.out_regs.device = req.head;
225 out.out_regs.lba_mid = req.cylinder;
226 out.out_regs.lba_high = req.cylinder >> 8;
227 out.out_regs.status = req.command;
228
229 return true;
230}
231
232/////////////////////////////////////////////////////////////////////////////
233/// NVMe support
234
236: public /*implements*/ nvme_device,
237 public /*extends*/ openbsd_smart_device
238{
239public:
240 openbsd_nvme_device(smart_interface * intf, const char * dev_name,
241 const char * req_type, unsigned nsid);
242
243 virtual bool open() override;
244
245 virtual bool nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & out) override;
246};
247
249 const char * req_type, unsigned nsid)
250: smart_device(intf, dev_name, "nvme", req_type),
253{
254}
255
257{
258 const char *dev = get_dev_name();
259 int fd;
260
261 if ((fd = ::open(dev, O_RDWR)) == -1) {
262 set_err(errno, "can't open sd device");
263 return false;
264 }
265
266 set_fd(fd);
267
268 return true;
269}
270
272{
273 struct nvme_pt_cmd pt;
274 struct nvme_pt_status ps;
275
276 memset(&ps, 0, sizeof(ps));
277 memset(&pt.pt_bio, 0, sizeof(pt.pt_bio));
278
279 pt.pt_opcode = in.opcode;
280 pt.pt_nsid = in.nsid;
281 pt.pt_databuf = (caddr_t)in.buffer;
282 pt.pt_databuflen = in.size;
283 pt.pt_cdw10 = in.cdw10;
284 pt.pt_cdw11 = in.cdw11;
285 pt.pt_cdw12 = in.cdw12;
286 pt.pt_cdw13 = in.cdw13;
287 pt.pt_cdw14 = in.cdw14;
288 pt.pt_cdw15 = in.cdw15;
289 pt.pt_status = (char *)&ps;
290 pt.pt_statuslen = sizeof(ps);
291
292 int status = ioctl(get_fd(), NVME_PASSTHROUGH_CMD, &pt);
293
294 if (status == -1)
295 return set_err(errno, "NVME_PASSTHROUGH_CMD: %s", strerror(errno));
296
297 out.result = 0; // cqe.cdw0 (Command specific result) is not provided
298
301
302 return true;
303}
304
305
306/////////////////////////////////////////////////////////////////////////////
307/// Standard SCSI support
308
310: public /*implements*/ scsi_device,
311 public /*extends*/ openbsd_smart_device
312{
313public:
314 openbsd_scsi_device(smart_interface * intf, const char * dev_name, const char * req_type, bool scanning = false);
315
316 virtual smart_device * autodetect_open() override;
317
318 virtual bool scsi_pass_through(scsi_cmnd_io * iop) override;
319
320private:
321 bool m_scanning; ///< true if created within scan_smart_devices
322};
323
325 const char * dev_name, const char * req_type, bool scanning /* = false */)
326: smart_device(intf, dev_name, "scsi", req_type),
328 m_scanning(scanning)
329{
330}
331
333{
334 struct scsireq sc;
335 int fd = get_fd();
336
337 if (scsi_debugmode) {
338 unsigned int k;
339 const unsigned char * ucp = iop->cmnd;
340 const char * np;
341
342 np = scsi_get_opcode_name(ucp);
343 pout(" [%s: ", np ? np : "<unknown opcode>");
344 for (k = 0; k < iop->cmnd_len; ++k)
345 pout("%02x ", ucp[k]);
346 if ((scsi_debugmode > 1) &&
347 (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
348 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
349
350 pout("]\n Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
351 (trunc ? " [only first 256 bytes shown]" : ""));
352 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
353 }
354 else
355 pout("]\n");
356 }
357
358 memset(&sc, 0, sizeof(sc));
359 memcpy(sc.cmd, iop->cmnd, iop->cmnd_len);
360 sc.cmdlen = iop->cmnd_len;
361 sc.databuf = (char *)iop->dxferp;
362 sc.datalen = iop->dxfer_len;
363 sc.senselen = iop->max_sense_len;
364 sc.timeout = (iop->timeout == 0 ? 60 : iop->timeout) * 1000;
365 sc.flags =
366 (iop->dxfer_dir == DXFER_NONE ? SCCMD_READ :
367 (iop->dxfer_dir == DXFER_FROM_DEVICE ? SCCMD_READ : SCCMD_WRITE));
368
369 if (ioctl(fd, SCIOCCOMMAND, &sc) < 0) {
370 if (scsi_debugmode) {
371 pout(" error sending SCSI ccb\n");
372 }
373 return set_err(EIO);
374 }
375 iop->resid = sc.datalen - sc.datalen_used;
376 iop->scsi_status = sc.status;
377 if (iop->sensep) {
378 memcpy(iop->sensep, sc.sense, sc.senselen_used);
379 iop->resp_sense_len = sc.senselen_used;
380 }
381 if (scsi_debugmode) {
382 int trunc;
383
384 pout(" status=0\n");
385 trunc = (iop->dxfer_len > 256) ? 1 : 0;
386
387 pout(" Incoming data, len=%d%s:\n", (int) iop->dxfer_len,
388 (trunc ? " [only first 256 bytes shown]" : ""));
389 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len), 1);
390 }
391 // XXX we probably need error handling here
392 return true;
393}
394
395/////////////////////////////////////////////////////////////////////////////
396///// SCSI open with autodetection support
397
399{
400 // Open device
401 if (!open())
402 return this;
403
404 // No Autodetection if device type was specified by user
405 bool sat_only = false;
406 if (*get_req_type()) {
407 // Detect SAT if device object was created by scan_smart_devices().
408 if (!(m_scanning && !strcmp(get_req_type(), "sat")))
409 return this;
410 sat_only = true;
411 }
412
413 // The code below is based on smartd.cpp:SCSIFilterKnown()
414
415 // Get INQUIRY
416 unsigned char req_buff[64] = {0, };
417 int req_len = 36;
418 if (scsiStdInquiry(this, req_buff, req_len)) {
419 // Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices
420 // watch this spot ... other devices could lock up here
421 req_len = 64;
422 if (scsiStdInquiry(this, req_buff, req_len)) {
423 // device doesn't like INQUIRY commands
424 close();
425 set_err(EIO, "INQUIRY failed");
426 return this;
427 }
428 }
429
430 int avail_len = req_buff[4] + 5;
431 int len = (avail_len < req_len ? avail_len : req_len);
432 if (len < 36) {
433 if (sat_only) {
434 close();
435 set_err(EIO, "INQUIRY too short for SAT");
436 }
437 return this;
438 }
439
440 // Use INQUIRY to detect type
441
442 // SAT or USB, skip MFI controllers because of bugs
443 {
444 smart_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
445 if (newdev) {
446 // NOTE: 'this' is now owned by '*newdev'
447 return newdev;
448 }
449 }
450
451 // Nothing special found
452
453 if (sat_only) {
454 close();
455 set_err(EIO, "Not a SAT device");
456 }
457 return this;
458}
459
460/////////////////////////////////////////////////////////////////////////////
461/// Implement platform interface with old functions.
462
464: public /*implements*/ smart_interface
465{
466public:
467 virtual std::string get_os_version_str() override;
468
469 virtual std::string get_app_examples(const char * appname) override;
470
471 virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
472 const char * pattern = 0) override;
473
474protected:
475 virtual ata_device * get_ata_device(const char * name, const char * type) override;
476
477 virtual scsi_device * get_scsi_device(const char * name, const char * type) override;
478
479 virtual nvme_device * get_nvme_device(const char * name, const char * type,
480 unsigned nsid) override;
481
482 virtual smart_device * autodetect_smart_device(const char * name) override;
483
484 virtual smart_device * get_custom_smart_device(const char * name, const char * type) override;
485
486 virtual std::string get_valid_custom_dev_types_str() override;
487
488private:
489 int get_dev_names(char ***, const char *);
490};
491
492
493//////////////////////////////////////////////////////////////////////
494
496{
497 struct utsname osname;
498 uname(&osname);
499 return strprintf("%s %s %s", osname.sysname, osname.release, osname.machine);
500}
501
502std::string openbsd_smart_interface::get_app_examples(const char * appname)
503{
504 if (!strcmp(appname, "smartctl")) {
505 char p;
506
507 p = 'a' + getrawpartition();
508 return strprintf(
509 "=================================================== SMARTCTL EXAMPLES =====\n\n"
510 " smartctl -a /dev/wd0%c (Prints all SMART information)\n\n"
511 " smartctl --smart=on --offlineauto=on --saveauto=on /dev/wd0%c\n"
512 " (Enables SMART on first disk)\n\n"
513 " smartctl -t long /dev/wd0%c (Executes extended disk self-test)\n\n"
514 " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/wd0%c\n"
515 " (Prints Self-Test & Attribute errors)\n"
516 " smartctl -a /dev/wd0%c (Prints all SMART information)\n"
517 " smartctl -s on -o on -S on /dev/wd0%c (Enables SMART on first disk)\n"
518 " smartctl -t long /dev/wd0%c (Executes extended disk self-test)\n"
519 " smartctl -A -l selftest -q errorsonly /dev/wd0%c"
520 " (Prints Self-Test & Attribute errors)\n",
521 p, p, p, p, p, p, p, p);
522 }
523 return "";
524}
525ata_device * openbsd_smart_interface::get_ata_device(const char * name, const char * type)
526{
527 return new openbsd_ata_device(this, name, type);
528}
529
530scsi_device * openbsd_smart_interface::get_scsi_device(const char * name, const char * type)
531{
532 return new openbsd_scsi_device(this, name, type);
533}
534
535nvme_device * openbsd_smart_interface::get_nvme_device(const char * name, const char * type, unsigned nsid)
536{
537 return new openbsd_nvme_device(this, name, type, nsid);
538}
539
540int openbsd_smart_interface::get_dev_names(char ***names, const char *prefix)
541{
542 char *disknames, *p, **mp;
543 int n = 0;
544 int sysctl_mib[2];
545 size_t sysctl_len;
546
547 *names = NULL;
548
549 sysctl_mib[0] = CTL_HW;
550 sysctl_mib[1] = HW_DISKNAMES;
551 if (-1 == sysctl(sysctl_mib, 2, NULL, &sysctl_len, NULL, 0)) {
552 pout("Failed to get value of sysctl `hw.disknames'\n");
553 return -1;
554 }
555 if (!(disknames = (char *)malloc(sysctl_len))) {
556 pout("Out of memory constructing scan device list\n");
557 return -1;
558 }
559 if (-1 == sysctl(sysctl_mib, 2, disknames, &sysctl_len, NULL, 0)) {
560 pout("Failed to get value of sysctl `hw.disknames'\n");
561 return -1;
562 }
563 if (!(mp = (char **) calloc(strlen(disknames) / 2, sizeof(char *)))) {
564 pout("Out of memory constructing scan device list\n");
565 return -1;
566 }
567
568 for (p = strtok(disknames, ","); p; p = strtok(NULL, ",")) {
569 if (strncmp(p, prefix, strlen(prefix))) {
570 continue;
571 }
572 char * u = strchr(p, ':');
573 if (u)
574 *u = 0;
575 mp[n] = (char *)malloc(strlen(net_dev_prefix) + strlen(p) + 2);
576 if (!mp[n]) {
577 pout("Out of memory constructing scan device list\n");
578 return -1;
579 }
580 sprintf(mp[n], "%s%s%c", net_dev_prefix, p, 'a' + getrawpartition());
581 n++;
582 }
583
584 char ** tmp = (char **)realloc(mp, n * (sizeof(char *)));
585 if (NULL == tmp) {
586 pout("Out of memory constructing scan device list\n");
587 free(mp);
588 return -1;
589 }
590 else
591 mp = tmp;
592 *names = mp;
593 return n;
594}
595
596
598 const char * type, const char * pattern /*= 0*/)
599 {
600 if (pattern) {
601 set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
602 return false;
603 }
604
605 if (type == NULL)
606 type = "";
607
608 bool scan_ata = !*type || !strcmp(type, "ata");
609 bool scan_scsi = !*type || !strcmp(type, "scsi") || !strcmp(type, "sat");
610 bool scan_nvme = !*type || !strcmp(type, "nvme");
611
612 // Make namelists
613 char * * atanames = 0; int numata = 0;
614 if (scan_ata) {
615 numata = get_dev_names(&atanames, net_dev_ata_disk);
616 if (numata < 0) {
617 set_err(ENOMEM);
618 return false;
619 }
620 }
621
622 char * * scsinames = 0; int numscsi = 0;
623 char * * scsitapenames = 0; int numscsitape = 0;
624 if (scan_scsi || scan_nvme) {
625 numscsi = get_dev_names(&scsinames, net_dev_scsi_disk);
626 if (numscsi < 0) {
627 set_err(ENOMEM);
628 return false;
629 }
630 numscsitape = get_dev_names(&scsitapenames, net_dev_scsi_tape);
631 if (numscsitape < 0) {
632 set_err(ENOMEM);
633 return false;
634 }
635 }
636
637 // Add to devlist
638 int i;
639 for (i = 0; i < numata; i++) {
640 ata_device * atadev = get_ata_device(atanames[i], type);
641 if (atadev)
642 devlist.push_back(atadev);
643 free(atanames[i]);
644 }
645 if(numata) free(atanames);
646
647 for (i = 0; i < numscsi; i++) {
648 if (sd_is_nvme(scsinames[i])) {
649 if (scan_nvme) {
650 nvme_device * nvmedev = new openbsd_nvme_device(this, scsinames[i], type, true /*scanning*/);
651 if (nvmedev)
652 devlist.push_back(nvmedev);
653 }
654 } else if (scan_scsi) {
655 scsi_device * scsidev = new openbsd_scsi_device(this, scsinames[i], type, true /*scanning*/);
656 if (scsidev)
657 devlist.push_back(scsidev);
658 }
659 free(scsinames[i]);
660 }
661 if(numscsi) free(scsinames);
662
663 for (i = 0; i < numscsitape; i++) {
664 scsi_device * scsidev = get_scsi_device(scsitapenames[i], type);
665 if (scsidev)
666 devlist.push_back(scsidev);
667 free(scsitapenames[i]);
668 }
669 if(numscsitape) free(scsitapenames);
670
671 return true;
672}
673
675{
676 const char * test_name = name;
677
678 // if dev_name null, or string length zero
679 if (!name || !*name)
680 return 0;
681
682 // Dereference symlinks
683 struct stat st;
684 std::string pathbuf;
685 if (!lstat(name, &st) && S_ISLNK(st.st_mode)) {
686 char * p = realpath(name, (char *)0);
687 if (p) {
688 pathbuf = p;
689 free(p);
690 test_name = pathbuf.c_str();
691 }
692 }
693
694 if (str_starts_with(test_name, net_dev_prefix)) {
695 test_name += strlen(net_dev_prefix);
696 if (!strncmp(net_dev_ata_disk, test_name, strlen(net_dev_ata_disk)))
697 return get_ata_device(name, "ata");
698 if (!strncmp(net_dev_scsi_disk, test_name, strlen(net_dev_scsi_disk))) {
699 // XXX Try to detect possible USB->(S)ATA bridge
700 // XXX get USB vendor ID, product ID and version from sd(4)/umass(4).
701 // XXX check sat device via get_usb_dev_type_by_id().
702
703 // No USB bridge found, decide if it's NVME or regular SCSI or SAT device
704 if (sd_is_nvme(name))
705 return get_nvme_device(name, "nvme", 0);
706 else
707 return get_scsi_device(name, "");
708 }
709 if (!strncmp(net_dev_scsi_tape, test_name, strlen(net_dev_scsi_tape)))
710 return get_scsi_device(name, "scsi");
711 }
712 // device type unknown
713 return 0;
714}
715
716
718{
719 ARGUSED(name);
720 ARGUSED(type);
721 return 0;
722}
723
725{
726 return "";
727}
728
729} // namespace
730
731/////////////////////////////////////////////////////////////////////////////
732/// Initialize platform interface and register with smi()
733
735{
736 static os_openbsd::openbsd_smart_interface the_interface;
737 smart_interface::set(&the_interface);
738}
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).
NVMe device access.
bool set_nvme_err(nvme_cmd_out &out, unsigned status, const char *msg=0)
Set last error number and message if pass-through returns NVMe error status.
Implement standard ATA support.
Definition: os_openbsd.cpp:148
virtual int do_cmd(struct atareq *request, bool is_48bit_cmd)
Definition: os_openbsd.cpp:163
openbsd_ata_device(smart_interface *intf, const char *dev_name, const char *req_type)
Definition: os_openbsd.cpp:157
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: os_openbsd.cpp:172
virtual bool nvme_pass_through(const nvme_cmd_in &in, nvme_cmd_out &out) override
NVMe pass through.
Definition: os_openbsd.cpp:271
openbsd_nvme_device(smart_interface *intf, const char *dev_name, const char *req_type, unsigned nsid)
Definition: os_openbsd.cpp:248
virtual bool open() override
Open device, return false on error.
Definition: os_openbsd.cpp:256
Standard SCSI support.
Definition: os_openbsd.cpp:312
openbsd_scsi_device(smart_interface *intf, const char *dev_name, const char *req_type, bool scanning=false)
Definition: os_openbsd.cpp:324
virtual bool scsi_pass_through(scsi_cmnd_io *iop) override
SCSI pass through.
Definition: os_openbsd.cpp:332
virtual smart_device * autodetect_open() override
Open device with autodetection support.
Definition: os_openbsd.cpp:398
bool m_scanning
true if created within scan_smart_devices
Definition: os_openbsd.cpp:321
Implement shared open/close routines with old functions.
Definition: os_openbsd.cpp:65
int m_fd
filedesc, -1 if not open.
Definition: os_openbsd.cpp:88
virtual bool close()
Close device, return false on error.
Definition: os_openbsd.cpp:129
virtual bool is_open() const
Return true if device is open.
Definition: os_openbsd.cpp:97
int get_fd() const
Return filedesc for derived classes.
Definition: os_openbsd.cpp:81
virtual bool open()
Open device, return false on error.
Definition: os_openbsd.cpp:103
Implement platform interface with old functions.
Definition: os_openbsd.cpp:465
virtual std::string get_os_version_str() override
Return info string about build host and/or OS version.
Definition: os_openbsd.cpp:495
virtual smart_device * get_custom_smart_device(const char *name, const char *type) override
Return device for platform specific 'type'.
Definition: os_openbsd.cpp:717
int get_dev_names(char ***, const char *)
Definition: os_openbsd.cpp:540
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:597
virtual std::string get_valid_custom_dev_types_str() override
Return valid 'type' args accepted by above.
Definition: os_openbsd.cpp:724
virtual ata_device * get_ata_device(const char *name, const char *type) override
Return standard ATA device.
Definition: os_openbsd.cpp:525
virtual smart_device * autodetect_smart_device(const char *name) override
Autodetect device if no device type specified.
Definition: os_openbsd.cpp:674
virtual scsi_device * get_scsi_device(const char *name, const char *type) override
Return standard SCSI device.
Definition: os_openbsd.cpp:530
virtual nvme_device * get_nvme_device(const char *name, const char *type, unsigned nsid) override
Return standard NVMe device.
Definition: os_openbsd.cpp:535
virtual std::string get_app_examples(const char *appname) override
Return example string for program 'appname'.
Definition: os_openbsd.cpp:502
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
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.
Definition: dev_interface.h:86
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().
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:1486
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
#define NVME_PASSTHROUGH_CMD
#define nvme_completion_is_error(cpl)
static const char * net_dev_scsi_disk
Definition: os_openbsd.cpp:57
static const char * net_dev_ata_disk
Definition: os_openbsd.cpp:56
bool sd_is_nvme(const char *dev)
Definition: os_openbsd.cpp:40
static const char * net_dev_prefix
Definition: os_openbsd.cpp:38
static const char * net_dev_scsi_tape
Definition: os_openbsd.cpp:58
@ nvme_admin_identify
Definition: nvmecmds.h:210
uint32_t nsid
#define ARGUSED(x)
Definition: os_darwin.cpp:39
const char * os_openbsd_cpp_cvsid
Definition: os_openbsd.cpp:26
#define OS_OPENBSD_H_CVSID
Definition: os_openbsd.h:16
int scsiStdInquiry(scsi_device *device, uint8_t *pBuf, int bufLen)
Definition: scsicmds.cpp:1163
void dStrHex(const uint8_t *up, int len, int no_ascii)
Definition: scsicmds.cpp:368
unsigned char scsi_debugmode
Definition: scsicmds.cpp:45
const char * scsi_get_opcode_name(const uint8_t *cdbp)
Definition: scsicmds.cpp:511
#define DXFER_NONE
Definition: scsicmds.h:108
#define DXFER_FROM_DEVICE
Definition: scsicmds.h:109
#define SCSI_TIMEOUT_DEFAULT
Definition: scsicmds.h:379
#define DXFER_TO_DEVICE
Definition: scsicmds.h:110
void pout(const char *fmt,...)
Definition: smartd.cpp:1347
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
NVMe pass through input parameters.
unsigned cdw10
unsigned cdw13
unsigned cdw11
unsigned char opcode
Opcode (CDW0 07:00)
unsigned size
Size of buffer.
unsigned cdw14
unsigned cdw15
Cmd specific.
unsigned nsid
Namespace ID.
unsigned cdw12
void * buffer
Pointer to data buffer.
NVMe pass through output parameters.
unsigned result
Command specific result (DW0)
struct bio pt_bio
uint32_t pt_databuflen
uint32_t pt_statuslen
uint8_t * sensep
Definition: scsicmds.h:123
uint8_t * dxferp
Definition: scsicmds.h:121
int dxfer_dir
Definition: scsicmds.h:119
size_t cmnd_len
Definition: scsicmds.h:118
size_t resp_sense_len
Definition: scsicmds.h:127
size_t dxfer_len
Definition: scsicmds.h:122
size_t max_sense_len
Definition: scsicmds.h:125
uint8_t scsi_status
Definition: scsicmds.h:128
uint8_t * cmnd
Definition: scsicmds.h:117
unsigned timeout
Definition: scsicmds.h:126
std::string strprintf(const char *fmt,...)
Definition: utility.cpp:799
bool str_starts_with(const char *str, const char *prefix)
Definition: utility.h:52