smartmontools  SVN Rev 4389
Utility to control and monitor storage systems with "S.M.A.R.T."
os_freebsd.cpp
Go to the documentation of this file.
1 /*
2  * os_freebsd.c
3  *
4  * Home page of code is: http://www.smartmontools.org
5  *
6  * Copyright (C) 2003-10 Eduard Martinescu
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * You should have received a copy of the GNU General Public License
14  * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17 
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <dirent.h>
21 #include <fcntl.h>
22 #include <err.h>
23 #include <errno.h>
24 #include <camlib.h>
25 #include <cam/scsi/scsi_message.h>
26 #include <cam/scsi/scsi_pass.h>
27 #if defined(__DragonFly__)
28 #include <sys/nata.h>
29 #else
30 #include <sys/ata.h>
31 #endif
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <glob.h>
35 #include <stddef.h>
36 #include <paths.h>
37 #include <sys/utsname.h>
38 
39 #include "config.h"
40 #include "int64.h"
41 // set by /usr/include/sys/ata.h, suppress warning
42 #undef ATA_READ_LOG_EXT
43 #include "atacmds.h"
44 #include "scsicmds.h"
45 #include "cciss.h"
46 #include "utility.h"
47 #include "os_freebsd.h"
48 
49 #include "dev_interface.h"
50 #include "dev_ata_cmd_set.h"
51 #include "dev_areca.h"
52 
53 #define USBDEV "/dev/usb"
54 #if defined(__FreeBSD_version)
55 
56 // This way we define one variable for the GNU/kFreeBSD and FreeBSD
57 #define FREEBSDVER __FreeBSD_version
58 #else
59 #define FREEBSDVER __FreeBSD_kernel_version
60 #endif
61 
62 #if (FREEBSDVER >= 800000)
63 #include <libusb20_desc.h>
64 #include <libusb20.h>
65 #elif defined(__DragonFly__)
66 #include <bus/usb/usb.h>
67 #include <bus/usb/usbhid.h>
68 #else
69 #include <dev/usb/usb.h>
70 #include <dev/usb/usbhid.h>
71 #endif
72 
73 // based on "/sys/dev/nvme/nvme.h" from FreeBSD kernel sources
74 #include "freebsd_nvme_ioctl.h" // NVME_PASSTHROUGH_CMD, nvme_completion_is_error
75 
76 #define CONTROLLER_3WARE_9000_CHAR 0x01
77 #define CONTROLLER_3WARE_678K_CHAR 0x02
78 
79 #ifndef PATHINQ_SETTINGS_SIZE
80 #define PATHINQ_SETTINGS_SIZE 128
81 #endif
82 
83 const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 4389 2017-01-30 18:43:11Z samm2 $" \
85 
86 #define NO_RETURN 0
87 #define BAD_SMART 1
88 #define NO_DISK_3WARE 2
89 #define BAD_KERNEL 3
90 #define MAX_MSG 3
91 
92 // Utility function for printing warnings
93 void printwarning(int msgNo, const char* extra) {
94 
95  if (msgNo >= 0 && msgNo <= MAX_MSG) {
96  static int printed[] = {0,0,0,0};
97  if (!printed[msgNo]) {
98 
99  static const char* message[]={
100  "The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n can not be retrieved with this version of ATAng, please do not rely on this value\nYou should update to at least 5.2\n",
101 
102  "Error SMART Status command failed\nPlease get assistance from \n" PACKAGE_HOMEPAGE "\nRegister values returned from SMART Status command are:\n",
103 
104  "You must specify a DISK # for 3ware drives with -d 3ware,<n> where <n> begins with 1 for first disk drive\n",
105 
106  "ATA support is not provided for this kernel version. Please ugrade to a recent 5-CURRENT kernel (post 09/01/2003 or so)\n"
107  };
108 
109  printed[msgNo] = 1;
110  pout("%s", message[msgNo]);
111  if (extra)
112  pout("%s",extra);
113  }
114  }
115  return;
116 }
117 
118 // Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
119 
120 #define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520
121 #define BUFFER_LEN_9000_CHAR ( sizeof(TW_OSLI_IOCTL_NO_DATA_BUF) + sizeof(TWE_Command) ) // 2048
122 #define TW_IOCTL_BUFFER_SIZE ( MAX(BUFFER_LEN_678K_CHAR, BUFFER_LEN_9000_CHAR) )
123 
124 #ifndef ATA_DEVICE
125 #define ATA_DEVICE "/dev/ata"
126 #endif
127 
128 #define ARGUSED(x) ((void)(x))
129 
130 extern unsigned char failuretest_permissive;
131 
132 /////////////////////////////////////////////////////////////////////////////
133 
134 namespace os_freebsd { // No need to publish anything, name provided for Doxygen
135 
136 /////////////////////////////////////////////////////////////////////////////
137 /// Implement shared open/close routines with old functions.
138 
140 : virtual public /*implements*/ smart_device
141 {
142 public:
145  m_fd(-1) { }
146 
147  virtual ~freebsd_smart_device() throw();
148 
149  virtual bool is_open() const;
150 
151  virtual bool open();
152 
153  virtual bool close();
154 
155 protected:
156  /// Return filedesc for derived classes.
157  int get_fd() const
158  { return m_fd; }
159 
160  void set_fd(int fd)
161  { m_fd = fd; }
162 
163 private:
164  int m_fd; ///< filedesc, -1 if not open.
165 };
166 
167 #ifdef __GLIBC__
168 static inline void * reallocf(void *ptr, size_t size) {
169  void *rv = realloc(ptr, size);
170  if((rv == NULL) && (size != 0))
171  free(ptr);
172  return rv;
173  }
174 #endif
175 
177 {
178  if (m_fd >= 0)
180 }
181 
182 // migration from the old_style
183 unsigned char m_controller_type;
184 unsigned char m_controller_port;
185 
186 // examples for smartctl
187 static const char smartctl_examples[] =
188  "=================================================== SMARTCTL EXAMPLES =====\n\n"
189  " smartctl -a /dev/ad0 (Prints all SMART information)\n\n"
190  " smartctl --smart=on --offlineauto=on --saveauto=on /dev/ad0\n"
191  " (Enables SMART on first disk)\n\n"
192  " smartctl -t long /dev/ad0 (Executes extended disk self-test)\n\n"
193  " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/ad0\n"
194  " (Prints Self-Test & Attribute errors)\n"
195  " (Prints Self-Test & Attribute errors)\n\n"
196  " smartctl -a --device=3ware,2 /dev/twa0\n"
197  " smartctl -a --device=3ware,2 /dev/twe0\n"
198  " smartctl -a --device=3ware,2 /dev/tws0\n"
199  " (Prints all SMART information for ATA disk on\n"
200  " third port of first 3ware RAID controller)\n"
201  " smartctl -a --device=cciss,0 /dev/ciss0\n"
202  " (Prints all SMART information for first disk \n"
203  " on Common Interface for SCSI-3 Support driver)\n"
204  " smartctl -a --device=areca,3/1 /dev/arcmsr0\n"
205  " (Prints all SMART information for 3rd disk in the 1st enclosure \n"
206  " on first ARECA RAID controller)\n"
207 
208  ;
209 
211 {
212  return (m_fd >= 0);
213 }
214 
215 
217 {
218  const char *dev = get_dev_name();
219  if ((m_fd = ::open(dev,O_RDONLY))<0) {
220  set_err(errno);
221  return false;
222  }
223  return true;
224 }
225 
227 {
228  int failed = 0;
229  // close device, if open
230  if (is_open())
231  failed=::close(get_fd());
232 
233  set_fd(-1);
234 
235  if(failed) return false;
236  else return true;
237 }
238 
239 /////////////////////////////////////////////////////////////////////////////
240 /// Implement standard ATA support
241 
243 : public /*implements*/ ata_device,
244  public /*extends*/ freebsd_smart_device
245 {
246 public:
247  freebsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type);
248  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
249 
250 protected:
251  virtual int do_cmd(struct ata_ioc_request* request, bool is_48bit_cmd);
252 };
253 
254 freebsd_ata_device::freebsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
255 : smart_device(intf, dev_name, "ata", req_type),
257 {
258 }
259 
260 int freebsd_ata_device::do_cmd( struct ata_ioc_request* request, bool is_48bit_cmd)
261 {
262  int fd = get_fd(), ret;
263  ARGUSED(is_48bit_cmd); // no support for 48 bit commands in the IOCATAREQUEST
264  ret = ioctl(fd, IOCATAREQUEST, request);
265  if (ret) set_err(errno);
266  return ret;
267 }
268 
269 
270 
272 {
273  bool ata_48bit = false; // no ata_48bit_support via IOCATAREQUEST
274  if(!strcmp("atacam",get_dev_type())) // enable for atacam interface
275  ata_48bit = true;
276 
277  if (!ata_cmd_is_ok(in,
278  true, // data_out_support
279  true, // multi_sector_support
280  ata_48bit)
281  ) {
282  set_err(ENOSYS, "48-bit ATA commands not implemented for legacy controllers");
283  return false;
284  }
285 
286  struct ata_ioc_request request;
287  bzero(&request,sizeof(struct ata_ioc_request));
288 
289  request.timeout=SCSI_TIMEOUT_DEFAULT;
290  request.u.ata.command=in.in_regs.command;
291  request.u.ata.feature=in.in_regs.features;
292 
293  request.u.ata.count = in.in_regs.sector_count_16;
294  request.u.ata.lba = in.in_regs.lba_48;
295 
296  switch (in.direction) {
297  case ata_cmd_in::no_data:
298  request.flags=ATA_CMD_CONTROL;
299  break;
300  case ata_cmd_in::data_in:
301  request.flags=ATA_CMD_READ | ATA_CMD_CONTROL;
302  request.data=(char *)in.buffer;
303  request.count=in.size;
304  break;
305  case ata_cmd_in::data_out:
306  request.flags=ATA_CMD_WRITE | ATA_CMD_CONTROL;
307  request.data=(char *)in.buffer;
308  request.count=in.size;
309  break;
310  default:
311  return set_err(ENOSYS);
312  }
313 
314  clear_err();
315  errno = 0;
316  if (do_cmd(&request, in.in_regs.is_48bit_cmd()))
317  return false;
318  if (request.error)
319  return set_err(EIO, "request failed, error code 0x%02x", request.error);
320 
321  out.out_regs.error = request.error;
322  out.out_regs.sector_count_16 = request.u.ata.count;
323  out.out_regs.lba_48 = request.u.ata.lba;
324 
325 
326  // Command specific processing
327  if (in.in_regs.command == ATA_SMART_CMD
329  && in.out_needed.lba_high)
330  {
331  unsigned const char normal_lo=0x4f, normal_hi=0xc2;
332  unsigned const char failed_lo=0xf4, failed_hi=0x2c;
333 
334  // Cyl low and Cyl high unchanged means "Good SMART status"
335  if (!(out.out_regs.lba_mid==normal_lo && out.out_regs.lba_high==normal_hi)
336  // These values mean "Bad SMART status"
337  && !(out.out_regs.lba_mid==failed_lo && out.out_regs.lba_high==failed_hi))
338 
339  {
340  // We haven't gotten output that makes sense; print out some debugging info
341  char buf[512];
342  snprintf(buf, sizeof(buf),
343  "CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
344  (int)request.u.ata.command,
345  (int)request.u.ata.feature,
346  (int)request.u.ata.count,
347  (int)((request.u.ata.lba) & 0xff),
348  (int)((request.u.ata.lba>>8) & 0xff),
349  (int)((request.u.ata.lba>>16) & 0xff),
350  (int)request.error);
351  printwarning(BAD_SMART,buf);
352  out.out_regs.lba_high = failed_hi;
353  out.out_regs.lba_mid = failed_lo;
354  }
355  }
356 
357  return true;
358 }
359 
360 #if FREEBSDVER > 800100
361 class freebsd_atacam_device : public freebsd_ata_device
362 {
363 public:
364  freebsd_atacam_device(smart_interface * intf, const char * dev_name, const char * req_type)
365  : smart_device(intf, dev_name, "atacam", req_type), freebsd_ata_device(intf, dev_name, req_type)
366  {}
367 
368  virtual bool open();
369  virtual bool close();
370 
371 protected:
372  int m_fd;
373  struct cam_device *m_camdev;
374 
375  virtual int do_cmd( struct ata_ioc_request* request , bool is_48bit_cmd);
376 };
377 
378 bool freebsd_atacam_device::open(){
379  const char *dev = get_dev_name();
380 
381  if ((m_camdev = cam_open_device(dev, O_RDWR)) == NULL) {
382  set_err(errno);
383  return false;
384  }
385  set_fd(m_camdev->fd);
386  return true;
387 }
388 
389 bool freebsd_atacam_device::close(){
390  cam_close_device(m_camdev);
391  set_fd(-1);
392  return true;
393 }
394 
395 int freebsd_atacam_device::do_cmd( struct ata_ioc_request* request, bool is_48bit_cmd)
396 {
397  union ccb ccb;
398  int camflags;
399 
400  // 48bit commands are broken in ATACAM before r242422/HEAD
401  // and may cause system hang
402  // First version with working support should be FreeBSD 9.2.0/RELEASE
403 
404 #if (FREEBSDVER < 902001)
405  if(!strcmp("ata",m_camdev->sim_name) && is_48bit_cmd) {
406  set_err(ENOSYS, "48-bit ATA commands not implemented for legacy controllers");
407  return -1;
408  }
409 #endif
410 
411  memset(&ccb, 0, sizeof(ccb));
412 
413  if (request->count == 0)
414  camflags = CAM_DIR_NONE;
415  else if (request->flags & ATA_CMD_READ)
416  camflags = CAM_DIR_IN;
417  else
418  camflags = CAM_DIR_OUT;
419 
420  cam_fill_ataio(&ccb.ataio,
421  0,
422  NULL,
423  camflags,
424  MSG_SIMPLE_Q_TAG,
425  (u_int8_t*)request->data,
426  request->count,
427  request->timeout * 1000); // timeout in seconds
428 
429  ccb.ataio.cmd.flags = CAM_ATAIO_NEEDRESULT |
430  (is_48bit_cmd ? CAM_ATAIO_48BIT : 0);
431  // ata_28bit_cmd
432  ccb.ataio.cmd.command = request->u.ata.command;
433  ccb.ataio.cmd.features = request->u.ata.feature;
434  ccb.ataio.cmd.lba_low = request->u.ata.lba;
435  ccb.ataio.cmd.lba_mid = request->u.ata.lba >> 8;
436  ccb.ataio.cmd.lba_high = request->u.ata.lba >> 16;
437  // ata_48bit cmd
438  ccb.ataio.cmd.lba_low_exp = request->u.ata.lba >> 24;
439  ccb.ataio.cmd.lba_mid_exp = request->u.ata.lba >> 32;
440  ccb.ataio.cmd.lba_high_exp = request->u.ata.lba >> 40;
441  ccb.ataio.cmd.device = 0x40 | ((request->u.ata.lba >> 24) & 0x0f);
442  ccb.ataio.cmd.sector_count = request->u.ata.count;
443  ccb.ataio.cmd.sector_count_exp = request->u.ata.count >> 8;;
444 
445  ccb.ccb_h.flags |= CAM_DEV_QFRZDIS;
446 
447  if (cam_send_ccb(m_camdev, &ccb) < 0) {
448  set_err(EIO, "cam_send_ccb failed");
449  return -1;
450  }
451 
452  if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
453  if(scsi_debugmode > 0)
454  cam_error_print(m_camdev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
455  set_err(EIO);
456  return -1;
457  }
458 
459  request->u.ata.lba =
460  ((u_int64_t)(ccb.ataio.res.lba_low)) |
461  ((u_int64_t)(ccb.ataio.res.lba_mid) << 8) |
462  ((u_int64_t)(ccb.ataio.res.lba_high) << 16) |
463  ((u_int64_t)(ccb.ataio.res.lba_low_exp) << 24) |
464  ((u_int64_t)(ccb.ataio.res.lba_mid_exp) << 32) |
465  ((u_int64_t)(ccb.ataio.res.lba_high_exp) << 40);
466 
467  request->u.ata.count = ccb.ataio.res.sector_count | (ccb.ataio.res.sector_count_exp << 8);
468  request->error = ccb.ataio.res.error;
469 
470  return 0;
471 }
472 
473 #endif
474 
475 /////////////////////////////////////////////////////////////////////////////
476 /// NVMe support
477 
479 : public /*implements*/ nvme_device,
480  public /*extends*/ freebsd_smart_device
481 {
482 public:
483  freebsd_nvme_device(smart_interface * intf, const char * dev_name,
484  const char * req_type, unsigned nsid);
485 
486  virtual bool open();
487 
488  virtual bool nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & out);
489 };
490 
492  const char * req_type, unsigned nsid)
493 : smart_device(intf, dev_name, "nvme", req_type),
494  nvme_device(nsid),
496 {
497 }
498 
500 {
501  const char *dev = get_dev_name();
502  if (!strnstr(dev, NVME_CTRLR_PREFIX, strlen(NVME_CTRLR_PREFIX))) {
503  set_err(EINVAL, "NVMe controller controller/namespace ids must begin with '%s'",
505  return false;
506  }
507 
508  int nsid = -1, ctrlid = -1;
509  char tmp;
510 
511  if(sscanf(dev, NVME_CTRLR_PREFIX"%d%c", &ctrlid, &tmp) == 1)
512  {
513  if(ctrlid < 0) {
514  set_err(EINVAL, "Invalid NVMe controller number");
515  return false;
516  }
517  nsid = 0xFFFFFFFF; // broadcast id
518  }
519  else if (sscanf(dev, NVME_CTRLR_PREFIX"%d"NVME_NS_PREFIX"%d%c",
520  &ctrlid, &nsid, &tmp) == 2)
521  {
522  if(ctrlid < 0 || nsid < 0) {
523  set_err(EINVAL, "Invalid NVMe controller/namespace number");
524  return false;
525  }
526  }
527  else {
528  set_err(EINVAL, "Invalid NVMe controller/namespace syntax");
529  return false;
530  }
531 
532  // we should always open controller, not namespace device
533  char full_path[64];
534  snprintf(full_path, sizeof(full_path), NVME_CTRLR_PREFIX"%d", ctrlid);
535 
536  int fd;
537  if ((fd = ::open(full_path, O_RDWR))<0) {
538  set_err(errno);
539  return false;
540  }
541  set_fd(fd);
542 
543  if (!get_nsid()) {
544  set_nsid(nsid);
545  }
546 
547  return true;
548 }
549 
551 {
552  // nvme_passthru_cmd pt;
553  struct nvme_pt_command pt;
554  memset(&pt, 0, sizeof(pt));
555 
556  pt.cmd.opc = in.opcode;
557  pt.cmd.nsid = in.nsid;
558  pt.buf = in.buffer;
559  pt.len = in.size;
560  pt.cmd.cdw10 = in.cdw10;
561  pt.cmd.cdw11 = in.cdw11;
562  pt.cmd.cdw12 = in.cdw12;
563  pt.cmd.cdw13 = in.cdw13;
564  pt.cmd.cdw14 = in.cdw14;
565  pt.cmd.cdw15 = in.cdw15;
566  pt.is_read = 1; // should we use in.direction()?
567 
568  int status = ioctl(get_fd(), NVME_PASSTHROUGH_CMD, &pt);
569 
570  if (status < 0)
571  return set_err(errno, "NVME_PASSTHROUGH_CMD: %s", strerror(errno));
572 
573  out.result=pt.cpl.cdw0; // Command specific result (DW0)
574 
575  if (nvme_completion_is_error(&pt.cpl))
576  return set_nvme_err(out, nvme_completion_is_error(&pt.cpl));
577 
578  return true;
579 }
580 
581 /////////////////////////////////////////////////////////////////////////////
582 /// Implement AMCC/3ware RAID support
583 
585 : public /*implements*/ ata_device,
586  public /*extends*/ freebsd_smart_device
587 {
588 public:
589  freebsd_escalade_device(smart_interface * intf, const char * dev_name,
590  int escalade_type, int disknum);
591 
592 protected:
593  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
594  virtual bool open();
595 
596 private:
597  int m_escalade_type; ///< Type string for escalade_command_interface().
598  int m_disknum; ///< Disk number.
599 };
600 
602  int escalade_type, int disknum)
603 : smart_device(intf, dev_name, "3ware", "3ware"),
605  m_escalade_type(escalade_type), m_disknum(disknum)
606 {
607  set_info().info_name = strprintf("%s [3ware_disk_%02d]", dev_name, disknum);
608 }
609 
611 {
612  const char *dev = get_dev_name();
613  int fd;
614 
615  if ((fd = ::open(dev,O_RDWR))<0) {
616  set_err(errno);
617  return false;
618  }
619  set_fd(fd);
620  return true;
621 }
622 
624 {
625  // to hold true file descriptor
626  int fd = get_fd();
627 
628  if (!ata_cmd_is_ok(in,
629  true, // data_out_support
630  false, // TODO: multi_sector_support
631  true) // ata_48bit_support
632  )
633  return false;
634 
635  struct twe_usercommand* cmd_twe = NULL;
636  TW_OSLI_IOCTL_NO_DATA_BUF* cmd_twa = NULL;
637  TWE_Command_ATA* ata = NULL;
638 
639  // Used by both the SCSI and char interfaces
640  char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];
641 
642  if (m_disknum < 0) {
644  return -1;
645  }
646 
647  memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);
648 
650  cmd_twa = (TW_OSLI_IOCTL_NO_DATA_BUF*)ioctl_buffer;
651  cmd_twa->pdata = ((TW_OSLI_IOCTL_WITH_PAYLOAD*)cmd_twa)->payload.data_buf;
652  cmd_twa->driver_pkt.buffer_length = in.size;
653  // using "old" packet format to speak with SATA devices
654  ata = (TWE_Command_ATA*)&cmd_twa->cmd_pkt.command.cmd_pkt_7k;
656  cmd_twe = (struct twe_usercommand*)ioctl_buffer;
657  ata = &cmd_twe->tu_command.ata;
658  } else {
659  return set_err(ENOSYS,
660  "Unrecognized escalade_type %d in linux_3ware_command_interface(disk %d)\n"
661  "Please contact " PACKAGE_BUGREPORT "\n", (int)m_escalade_type, m_disknum);
662  }
663 
664  ata->opcode = TWE_OP_ATA_PASSTHROUGH;
665 
666  // Same for (almost) all commands - but some reset below
667  ata->request_id = 0xFF;
668  ata->unit = m_disknum;
669  ata->status = 0;
670  ata->flags = 0x1;
671  ata->size = 0x5; // TODO: multisector support
672  // Set registers
673  {
674  const ata_in_regs_48bit & r = in.in_regs;
675  ata->features = r.features_16;
676  ata->sector_count = r.sector_count_16;
677  ata->sector_num = r.lba_low_16;
678  ata->cylinder_lo = r.lba_mid_16;
679  ata->cylinder_hi = r.lba_high_16;
680  ata->drive_head = r.device;
681  ata->command = r.command;
682  }
683 
684  // Is this a command that reads or returns 512 bytes?
685  // passthru->param values are:
686  // 0x0 - non data command without TFR write check,
687  // 0x8 - non data command with TFR write check,
688  // 0xD - data command that returns data to host from device
689  // 0xF - data command that writes data from host to device
690  // passthru->size values are 0x5 for non-data and 0x07 for data
691  bool readdata = false;
692  if (in.direction == ata_cmd_in::data_in) {
694  cmd_twe->tu_data = in.buffer;
695  cmd_twe->tu_size = 512;
696  }
697 
698  readdata=true;
699  ata->sgl_offset = 0x5;
700  ata->param = 0xD;
701  // For 64-bit to work correctly, up the size of the command packet
702  // in dwords by 1 to account for the 64-bit single sgl 'address'
703  // field. Note that this doesn't agree with the typedefs but it's
704  // right (agree with kernel driver behavior/typedefs).
705  // if (sizeof(long)==8)
706  // ata->size++;
707  }
708  else if (in.direction == ata_cmd_in::no_data) {
709  // Non data command -- but doesn't use large sector
710  // count register values.
711  ata->sgl_offset = 0x0;
712  ata->param = 0x8;
713  ata->sector_count = 0x0;
714  }
715  else if (in.direction == ata_cmd_in::data_out) {
716  ata->sgl_offset = 0x5;
717  ata->param = 0xF; // PIO data write
719  cmd_twe->tu_data = in.buffer;
720  cmd_twe->tu_size = 512;
721  }
723  memcpy(cmd_twa->pdata, in.buffer, in.size);
724  }
725  }
726  else
727  return set_err(EINVAL);
728 
729  // 3WARE controller can NOT have packet device internally
731  return set_err(ENODEV, "No drive on port %d", m_disknum);
732  }
733 
734  // Now send the command down through an ioctl()
735  int ioctlreturn;
737  ioctlreturn=ioctl(fd,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);
738  } else {
739  ioctlreturn=ioctl(fd,TWEIO_COMMAND,cmd_twe);
740  }
741 
742  // Deal with the different error cases
743  if (ioctlreturn) {
744  return set_err(EIO);
745  }
746 
747  // See if the ATA command failed. Now that we have returned from
748  // the ioctl() call, if passthru is valid, then:
749  // - ata->status contains the 3ware controller STATUS
750  // - ata->command contains the ATA STATUS register
751  // - ata->features contains the ATA ERROR register
752  //
753  // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
754  // If bit 0 (error bit) is set, then ATA ERROR register is valid.
755  // While we *might* decode the ATA ERROR register, at the moment it
756  // doesn't make much sense: we don't care in detail why the error
757  // happened.
758 
759  if (ata->status || (ata->command & 0x21)) {
760  if (scsi_debugmode)
761  pout("Command failed, ata.status=(0x%2.2x), ata.command=(0x%2.2x), ata.flags=(0x%2.2x)\n",ata->status,ata->command,ata->flags);
762  return set_err(EIO);
763  }
764 
765  // If this is a read data command, copy data to output buffer
766  if (readdata) {
768  memcpy(in.buffer, cmd_twa->pdata, in.size);
770  memcpy(in.buffer, cmd_twe->tu_data, in.size); // untested
771  }
772  }
773  // Return register values
774  if (ata) {
775  ata_out_regs_48bit & r = out.out_regs;
776  r.error = ata->features;
777  r.sector_count_16 = ata->sector_count;
778  r.lba_low_16 = ata->sector_num;
779  r.lba_mid_16 = ata->cylinder_lo;
780  r.lba_high_16 = ata->cylinder_hi;
781  r.device = ata->drive_head;
782  r.status = ata->command;
783  }
784  // look for nonexistent devices/ports
786  && !nonempty((unsigned char *)in.buffer, in.size)) {
787  return set_err(ENODEV, "No drive on port %d", m_disknum);
788  }
789  return true;
790 }
791 
792 
793 /////////////////////////////////////////////////////////////////////////////
794 /// Implement Highpoint RAID support with old functions
795 
797 : public /*implements*/ ata_device_with_command_set,
798  public /*extends*/ freebsd_smart_device
799 {
800 public:
801  freebsd_highpoint_device(smart_interface * intf, const char * dev_name,
802  unsigned char controller, unsigned char channel, unsigned char port);
803 
804 protected:
805  virtual int ata_command_interface(smart_command_set command, int select, char * data);
806  virtual bool open();
807 
808 private:
809  unsigned char m_hpt_data[3]; ///< controller/channel/port
810 };
811 
812 
814  unsigned char controller, unsigned char channel, unsigned char port)
815 : smart_device(intf, dev_name, "hpt", "hpt"),
817 {
818  m_hpt_data[0] = controller; m_hpt_data[1] = channel; m_hpt_data[2] = port;
819  set_info().info_name = strprintf("%s [hpt_disk_%u/%u/%u]", dev_name, m_hpt_data[0], m_hpt_data[1], m_hpt_data[2]);
820 }
821 
823 {
824  const char *dev = get_dev_name();
825  int fd;
826 
827  if ((fd = ::open(dev,O_RDWR))<0) {
828  set_err(errno);
829  return false;
830  }
831  set_fd(fd);
832  return true;
833 }
834 
836 {
837  int fd=get_fd();
838  int ids[2];
839  HPT_IOCTL_PARAM param;
840  HPT_CHANNEL_INFO_V2 info;
841  unsigned char* buff[512 + 2 * sizeof(HPT_PASS_THROUGH_HEADER)];
842  PHPT_PASS_THROUGH_HEADER pide_pt_hdr, pide_pt_hdr_out;
843 
844  // get internal deviceid
845  ids[0] = m_hpt_data[0] - 1;
846  ids[1] = m_hpt_data[1] - 1;
847 
848  memset(&param, 0, sizeof(HPT_IOCTL_PARAM));
849 
850  param.magic = HPT_IOCTL_MAGIC;
852  param.in = (unsigned char *)ids;
853  param.in_size = sizeof(unsigned int) * 2;
854  param.out = (unsigned char *)&info;
855  param.out_size = sizeof(HPT_CHANNEL_INFO_V2);
856 
857  if (m_hpt_data[2]==1) {
859  param.out_size = sizeof(HPT_CHANNEL_INFO);
860  }
861  if (ioctl(fd, HPT_DO_IOCONTROL, &param)!=0 ||
862  info.devices[m_hpt_data[2]-1]==0) {
863  return -1;
864  }
865 
866  // perform smart action
867  memset(buff, 0, 512 + 2 * sizeof(HPT_PASS_THROUGH_HEADER));
868  pide_pt_hdr = (PHPT_PASS_THROUGH_HEADER)buff;
869 
870  pide_pt_hdr->lbamid = 0x4f;
871  pide_pt_hdr->lbahigh = 0xc2;
872  pide_pt_hdr->command = ATA_SMART_CMD;
873  pide_pt_hdr->id = info.devices[m_hpt_data[2] - 1];
874 
875  switch (command){
876  case READ_VALUES:
877  pide_pt_hdr->feature=ATA_SMART_READ_VALUES;
878  pide_pt_hdr->protocol=HPT_READ;
879  break;
880  case READ_THRESHOLDS:
881  pide_pt_hdr->feature=ATA_SMART_READ_THRESHOLDS;
882  pide_pt_hdr->protocol=HPT_READ;
883  break;
884  case READ_LOG:
885  pide_pt_hdr->feature=ATA_SMART_READ_LOG_SECTOR;
886  pide_pt_hdr->lbalow=select;
887  pide_pt_hdr->protocol=HPT_READ;
888  break;
889  case IDENTIFY:
890  pide_pt_hdr->command=ATA_IDENTIFY_DEVICE;
891  pide_pt_hdr->protocol=HPT_READ;
892  break;
893  case ENABLE:
894  pide_pt_hdr->feature=ATA_SMART_ENABLE;
895  break;
896  case DISABLE:
897  pide_pt_hdr->feature=ATA_SMART_DISABLE;
898  break;
899  case AUTO_OFFLINE:
900  pide_pt_hdr->feature=ATA_SMART_AUTO_OFFLINE;
901  pide_pt_hdr->sectorcount=select;
902  break;
903  case AUTOSAVE:
904  pide_pt_hdr->feature=ATA_SMART_AUTOSAVE;
905  pide_pt_hdr->sectorcount=select;
906  break;
907  case IMMEDIATE_OFFLINE:
908  pide_pt_hdr->feature=ATA_SMART_IMMEDIATE_OFFLINE;
909  pide_pt_hdr->lbalow=select;
910  break;
911  case STATUS_CHECK:
912  case STATUS:
913  pide_pt_hdr->feature=ATA_SMART_STATUS;
914  break;
915  case CHECK_POWER_MODE:
916  pide_pt_hdr->command=ATA_CHECK_POWER_MODE;
917  break;
918  case WRITE_LOG:
919  memcpy(buff+sizeof(HPT_PASS_THROUGH_HEADER), data, 512);
920  pide_pt_hdr->feature=ATA_SMART_WRITE_LOG_SECTOR;
921  pide_pt_hdr->lbalow=select;
922  pide_pt_hdr->protocol=HPT_WRITE;
923  break;
924  default:
925  pout("Unrecognized command %d in highpoint_command_interface()\n"
926  "Please contact " PACKAGE_BUGREPORT "\n", command);
927  errno=ENOSYS;
928  return -1;
929  }
930  if (pide_pt_hdr->protocol!=0) {
931  pide_pt_hdr->sectors = 1;
932  pide_pt_hdr->sectorcount = 1;
933  }
934 
935  memset(&param, 0, sizeof(HPT_IOCTL_PARAM));
936 
937  param.magic = HPT_IOCTL_MAGIC;
939  param.in = (unsigned char *)buff;
940  param.in_size = sizeof(HPT_PASS_THROUGH_HEADER) + (pide_pt_hdr->protocol==HPT_READ ? 0 : pide_pt_hdr->sectors * 512);
941  param.out = (unsigned char *)buff+param.in_size;
942  param.out_size = sizeof(HPT_PASS_THROUGH_HEADER) + (pide_pt_hdr->protocol==HPT_READ ? pide_pt_hdr->sectors * 512 : 0);
943 
944  pide_pt_hdr_out = (PHPT_PASS_THROUGH_HEADER)param.out;
945 
946  if ((ioctl(fd, HPT_DO_IOCONTROL, &param)!=0) ||
947  (pide_pt_hdr_out->command & 1)) {
948  return -1;
949  }
950 
951  if (command==STATUS_CHECK)
952  {
953  unsigned const char normal_lo=0x4f, normal_hi=0xc2;
954  unsigned const char failed_lo=0xf4, failed_hi=0x2c;
955  unsigned char low,high;
956 
957  high = pide_pt_hdr_out->lbahigh;
958  low = pide_pt_hdr_out->lbamid;
959 
960  // Cyl low and Cyl high unchanged means "Good SMART status"
961  if (low==normal_lo && high==normal_hi)
962  return 0;
963 
964  // These values mean "Bad SMART status"
965  if (low==failed_lo && high==failed_hi)
966  return 1;
967 
968  // We haven't gotten output that makes sense; print out some debugging info
969  char buf[512];
970  snprintf(buf, sizeof(buf),
971  "CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
972  (int)pide_pt_hdr_out->command,
973  (int)pide_pt_hdr_out->feature,
974  (int)pide_pt_hdr_out->sectorcount,
975  (int)pide_pt_hdr_out->lbalow,
976  (int)pide_pt_hdr_out->lbamid,
977  (int)pide_pt_hdr_out->lbahigh,
978  (int)pide_pt_hdr_out->sectors);
979  printwarning(BAD_SMART,buf);
980  }
981  else if (command==CHECK_POWER_MODE)
982  data[0] = pide_pt_hdr_out->sectorcount & 0xff;
983  else if (pide_pt_hdr->protocol==HPT_READ)
984  memcpy(data, (unsigned char *)buff + 2 * sizeof(HPT_PASS_THROUGH_HEADER),
985  pide_pt_hdr->sectors * 512);
986  return 0;
987 }
988 
989 
990 /////////////////////////////////////////////////////////////////////////////
991 /// Standard SCSI support
992 
994 : public /*implements*/ scsi_device,
995  public /*extends*/ freebsd_smart_device
996 {
997 public:
998  freebsd_scsi_device(smart_interface * intf, const char * dev_name, const char * req_type);
999 
1000  virtual smart_device * autodetect_open();
1001 
1002  virtual bool scsi_pass_through(scsi_cmnd_io * iop);
1003 
1004  virtual bool open();
1005 
1006  virtual bool close();
1007 
1008 private:
1009  struct cam_device *m_camdev;
1010 };
1011 
1013  const char *dev = get_dev_name();
1014 
1015  if ((m_camdev = cam_open_device(dev, O_RDWR)) == NULL) {
1016  set_err(errno);
1017  return false;
1018  }
1019  set_fd(m_camdev->fd);
1020  return true;
1021 }
1022 
1024  cam_close_device(m_camdev);
1025  set_fd(-1);
1026  return true;
1027 }
1028 
1030  const char * dev_name, const char * req_type)
1031 : smart_device(intf, dev_name, "scsi", req_type),
1033  m_camdev(0)
1034 {
1035 }
1036 
1037 
1039 {
1040  union ccb *ccb;
1041 
1042  if (scsi_debugmode) {
1043  unsigned int k;
1044  const unsigned char * ucp = iop->cmnd;
1045  const char * np;
1046 
1047  np = scsi_get_opcode_name(ucp[0]);
1048  pout(" [%s: ", np ? np : "<unknown opcode>");
1049  for (k = 0; k < iop->cmnd_len; ++k)
1050  pout("%02x ", ucp[k]);
1051  if ((scsi_debugmode > 1) &&
1052  (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
1053  int trunc = (iop->dxfer_len > 256) ? 1 : 0;
1054 
1055  pout("]\n Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
1056  (trunc ? " [only first 256 bytes shown]" : ""));
1057  dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
1058  }
1059  else
1060  pout("]\n");
1061  }
1062 
1063  if(m_camdev==NULL) {
1064  if (scsi_debugmode)
1065  pout(" error: camdev=0!\n");
1066  return set_err(ENOTTY);
1067  }
1068 
1069  if (!(ccb = cam_getccb(m_camdev))) {
1070  if (scsi_debugmode)
1071  pout(" error allocating ccb\n");
1072  return set_err(ENOMEM);
1073  }
1074 
1075  // mfi SAT layer is known to be buggy
1076  if(!strcmp("mfi",m_camdev->sim_name)) {
1077  if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) {
1078  // Controller does not return ATA output registers in SAT sense data
1079  if (iop->cmnd[2] & (1 << 5)) // chk_cond
1080  return set_err(ENOSYS, "ATA return descriptor not supported by controller firmware");
1081  }
1082  // SMART WRITE LOG SECTOR causing media errors
1083  if ((iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16
1084  && iop->cmnd[14] == ATA_SMART_CMD && iop->cmnd[3]==0 &&
1085  iop->cmnd[4] == ATA_SMART_WRITE_LOG_SECTOR) ||
1086  (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12
1087  && iop->cmnd[9] == ATA_SMART_CMD && iop->cmnd[3] == ATA_SMART_WRITE_LOG_SECTOR))
1088  {
1090  return set_err(ENOSYS, "SMART WRITE LOG SECTOR may cause problems, try with -T permissive to force");
1091  }
1092  }
1093  // clear out structure, except for header that was filled in for us
1094  bzero(&(&ccb->ccb_h)[1],
1095  sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1096 
1097  cam_fill_csio(&ccb->csio,
1098  /* retries */ 1,
1099  /* cbfcnp */ NULL,
1100  /* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),
1101  /* tagaction */ MSG_SIMPLE_Q_TAG,
1102  /* dataptr */ iop->dxferp,
1103  /* datalen */ iop->dxfer_len,
1104  /* senselen */ iop->max_sense_len,
1105  /* cdblen */ iop->cmnd_len,
1106  /* timout (converted to seconds) */ iop->timeout*1000);
1107  memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
1108 
1109  if (cam_send_ccb(m_camdev,ccb) < 0) {
1110  if (scsi_debugmode) {
1111  pout(" error sending SCSI ccb\n");
1112  cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
1113  }
1114  cam_freeccb(ccb);
1115  return set_err(EIO);
1116  }
1117 
1118  if (scsi_debugmode) {
1119  pout(" CAM status=0x%x, SCSI status=0x%x, resid=0x%x\n",
1120  ccb->ccb_h.status, ccb->csio.scsi_status, ccb->csio.resid);
1121  if ((scsi_debugmode > 1) && (DXFER_FROM_DEVICE == iop->dxfer_dir)) {
1122  int trunc, len;
1123 
1124  len = iop->dxfer_len - ccb->csio.resid;
1125  trunc = (len > 256) ? 1 : 0;
1126  if (len > 0) {
1127  pout(" Incoming data, len=%d%s:\n", len,
1128  (trunc ? " [only first 256 bytes shown]" : ""));
1129  dStrHex(iop->dxferp, (trunc ? 256 : len), 1);
1130  }
1131  else
1132  pout(" Incoming data trimmed to nothing by resid\n");
1133  }
1134  }
1135 
1136  if (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR)) {
1137  if (scsi_debugmode)
1138  cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
1139  cam_freeccb(ccb);
1140  return set_err(EIO);
1141  }
1142 
1143  iop->resid = ccb->csio.resid;
1144  iop->scsi_status = ccb->csio.scsi_status;
1145  if (iop->sensep && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0) {
1146  if (scsi_debugmode)
1147  pout(" sense_len=0x%x, sense_resid=0x%x\n",
1148  ccb->csio.sense_len, ccb->csio.sense_resid);
1149  iop->resp_sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
1150  /* Some SCSI controller device drivers miscalculate the sense_resid
1151  field so cap resp_sense_len on max_sense_len. */
1152  if (iop->resp_sense_len > iop->max_sense_len)
1153  iop->resp_sense_len = iop->max_sense_len;
1154  if (iop->resp_sense_len > 0) {
1155  memcpy(iop->sensep, &(ccb->csio.sense_data), iop->resp_sense_len);
1156  if (scsi_debugmode) {
1157  if (scsi_debugmode > 1) {
1158  pout(" >>> Sense buffer, len=%zu:\n", iop->resp_sense_len);
1159  dStrHex(iop->sensep, iop->resp_sense_len, 1);
1160  }
1161  if ((iop->sensep[0] & 0x7f) > 0x71)
1162  pout(" status=0x%x: [desc] sense_key=0x%x asc=0x%x ascq=0x%x\n",
1163  iop->scsi_status, iop->sensep[1] & 0xf,
1164  iop->sensep[2], iop->sensep[3]);
1165  else
1166  pout(" status=0x%x: sense_key=0x%x asc=0x%x ascq=0x%x\n",
1167  iop->scsi_status, iop->sensep[2] & 0xf,
1168  iop->sensep[12], iop->sensep[13]);
1169  }
1170  }
1171  else if (scsi_debugmode)
1172  pout(" status=0x%x\n", iop->scsi_status);
1173  }
1174  else if (scsi_debugmode)
1175  pout(" status=0x%x\n", iop->scsi_status);
1176 
1177  cam_freeccb(ccb);
1178 
1179  // mfip replacing PDT of the device so response does not make a sense
1180  // this sets PDT to 00h - direct-access block device
1181  if((!strcmp("mfi", m_camdev->sim_name) || !strcmp("mpt", m_camdev->sim_name))
1182  && iop->cmnd[0] == INQUIRY) {
1183  if (scsi_debugmode) {
1184  pout(" device on %s controller, patching PDT\n", m_camdev->sim_name);
1185  }
1186  iop->dxferp[0] = iop->dxferp[0] & 0xe0;
1187  }
1188 
1189  return true;
1190 }
1191 
1192 
1193 /////////////////////////////////////////////////////////////////////////////
1194 /// Areca RAID support
1195 
1196 ///////////////////////////////////////////////////////////////////
1197 // SATA(ATA) device behind Areca RAID Controller
1199 : public /*implements*/ areca_ata_device,
1200  public /*extends*/ freebsd_smart_device
1201 {
1202 public:
1203  freebsd_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
1204  virtual smart_device * autodetect_open();
1205  virtual bool arcmsr_lock();
1206  virtual bool arcmsr_unlock();
1207  virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop);
1208 };
1209 
1210 ///////////////////////////////////////////////////////////////////
1211 // SAS(SCSI) device behind Areca RAID Controller
1213 : public /*implements*/ areca_scsi_device,
1214  public /*extends*/ freebsd_smart_device
1215 {
1216 public:
1217  freebsd_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
1218  virtual smart_device * autodetect_open();
1219  virtual bool arcmsr_lock();
1220  virtual bool arcmsr_unlock();
1221  virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop);
1222 };
1223 
1224 
1225 // Areca RAID Controller(SATA Disk)
1226 freebsd_areca_ata_device::freebsd_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
1227 : smart_device(intf, dev_name, "areca", "areca"),
1229 {
1230  set_disknum(disknum);
1231  set_encnum(encnum);
1232  set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
1233 }
1234 
1235 
1237 {
1238  // autodetect device type
1239  int is_ata = arcmsr_get_dev_type();
1240  if(is_ata < 0)
1241  {
1242  set_err(EIO);
1243  return this;
1244  }
1245 
1246  if(is_ata == 1)
1247  {
1248  // SATA device
1249  return this;
1250  }
1251 
1252  // SAS device
1254  close();
1255  delete this;
1256  newdev->open(); // TODO: Can possibly pass open fd
1257 
1258  return newdev.release();
1259 }
1260 
1262 {
1263  int ioctlreturn = 0;
1264 
1265  if(!is_open()) {
1266  if(!open()){
1267  }
1268  }
1269 
1270  ioctlreturn = ioctl(get_fd(), ((sSRB_BUFFER *)(iop->dxferp))->srbioctl.ControlCode, iop->dxferp);
1271  if (ioctlreturn)
1272  {
1273  // errors found
1274  return -1;
1275  }
1276 
1277  return ioctlreturn;
1278 }
1279 
1281 {
1282  return true;
1283 }
1284 
1285 
1287 {
1288  return true;
1289 }
1290 
1291 
1292 // Areca RAID Controller(SAS Device)
1293 freebsd_areca_scsi_device::freebsd_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
1294 : smart_device(intf, dev_name, "areca", "areca"),
1296 {
1297  set_disknum(disknum);
1298  set_encnum(encnum);
1299  set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
1300 }
1301 
1303 {
1304  return this;
1305 }
1306 
1308 {
1309  int ioctlreturn = 0;
1310 
1311  if(!is_open()) {
1312  if(!open()){
1313  }
1314  }
1315  ioctlreturn = ioctl(get_fd(), ((sSRB_BUFFER *)(iop->dxferp))->srbioctl.ControlCode, iop->dxferp);
1316  if (ioctlreturn)
1317  {
1318  // errors found
1319  return -1;
1320  }
1321 
1322  return ioctlreturn;
1323 }
1324 
1326 {
1327  return true;
1328 }
1329 
1330 
1332 {
1333  return true;
1334 }
1335 
1336 
1337 /////////////////////////////////////////////////////////////////////////////
1338 /// Implement CCISS RAID support with old functions
1339 
1341 : public /*implements*/ scsi_device,
1342  public /*extends*/ freebsd_smart_device
1343 {
1344 public:
1345  freebsd_cciss_device(smart_interface * intf, const char * name, unsigned char disknum);
1346 
1347  virtual bool scsi_pass_through(scsi_cmnd_io * iop);
1348  virtual bool open();
1349 
1350 private:
1351  unsigned char m_disknum; ///< Disk number.
1352 };
1353 
1355 {
1356  const char *dev = get_dev_name();
1357  int fd;
1358  if ((fd = ::open(dev,O_RDWR))<0) {
1359  set_err(errno);
1360  return false;
1361  }
1362  set_fd(fd);
1363  return true;
1364 }
1365 
1367  const char * dev_name, unsigned char disknum)
1368 : smart_device(intf, dev_name, "cciss", "cciss"),
1370  m_disknum(disknum)
1371 {
1372  set_info().info_name = strprintf("%s [cciss_disk_%02d]", dev_name, disknum);
1373 }
1374 
1376 {
1377  int status = cciss_io_interface(get_fd(), m_disknum, iop, scsi_debugmode);
1378  if (status < 0)
1379  return set_err(-status);
1380  return true;
1381  // not reached
1382  return true;
1383 }
1384 
1385 
1386 /////////////////////////////////////////////////////////////////////////////
1387 /// SCSI open with autodetection support
1388 
1390 {
1391  // Open device
1392  if (!open())
1393  return this;
1394 
1395  // No Autodetection if device type was specified by user
1396  if (*get_req_type())
1397  return this;
1398 
1399  // The code below is based on smartd.cpp:SCSIFilterKnown()
1400 
1401  // Get INQUIRY
1402  unsigned char req_buff[64] = {0, };
1403  int req_len = 36;
1404  if (scsiStdInquiry(this, req_buff, req_len)) {
1405  // Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices
1406  // watch this spot ... other devices could lock up here
1407  req_len = 64;
1408  if (scsiStdInquiry(this, req_buff, req_len)) {
1409  // device doesn't like INQUIRY commands
1410  close();
1411  set_err(EIO, "INQUIRY failed");
1412  return this;
1413  }
1414  }
1415 
1416  int avail_len = req_buff[4] + 5;
1417  int len = (avail_len < req_len ? avail_len : req_len);
1418  if (len < 36)
1419  return this;
1420 
1421  // Use INQUIRY to detect type
1422 
1423  // 3ware ?
1424  if (!memcmp(req_buff + 8, "3ware", 5) || !memcmp(req_buff + 8, "AMCC", 4) ||
1425  !strcmp("tws",m_camdev->sim_name) || !strcmp("twa",m_camdev->sim_name)) {
1426  close();
1427  set_err(EINVAL, "3ware/LSI controller, please try adding '-d 3ware,N',\n"
1428  "you may need to replace %s with /dev/twaN, /dev/tweN or /dev/twsN", get_dev_name());
1429  return this;
1430  }
1431 
1432  // SAT or USB, skip MFI controllers because of bugs
1433  {
1434  smart_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
1435  if (newdev) {
1436  // NOTE: 'this' is now owned by '*newdev'
1437  if(!strcmp("mfi",m_camdev->sim_name)) {
1438  newdev->close();
1439  newdev->set_err(ENOSYS, "SATA device detected,\n"
1440  "MegaRAID SAT layer is reportedly buggy, use '-d sat' to try anyhow");
1441  }
1442  return newdev;
1443  }
1444  }
1445 
1446  // Nothing special found
1447  return this;
1448 }
1449 
1450 
1451 /////////////////////////////////////////////////////////////////////////////
1452 /// Implement platform interface with old functions.
1453 
1455 : public /*implements*/ smart_interface
1456 {
1457 public:
1458  virtual std::string get_os_version_str();
1459 
1460  virtual std::string get_app_examples(const char * appname);
1461 
1462  virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
1463  const char * pattern = 0);
1464 
1465 protected:
1466  virtual ata_device * get_ata_device(const char * name, const char * type);
1467 
1468 #if FREEBSDVER > 800100
1469  virtual ata_device * get_atacam_device(const char * name, const char * type);
1470 #endif
1471 
1472  virtual scsi_device * get_scsi_device(const char * name, const char * type);
1473 
1474  virtual nvme_device * get_nvme_device(const char * name, const char * type,
1475  unsigned nsid);
1476 
1477  virtual smart_device * autodetect_smart_device(const char * name);
1478 
1479  virtual smart_device * get_custom_smart_device(const char * name, const char * type);
1480 
1481  virtual std::string get_valid_custom_dev_types_str();
1482 };
1483 
1484 
1485 //////////////////////////////////////////////////////////////////////
1486 
1488 {
1489  struct utsname osname;
1490  uname(&osname);
1491  return strprintf("%s %s %s", osname.sysname, osname.release, osname.machine);
1492 }
1493 
1494 std::string freebsd_smart_interface::get_app_examples(const char * appname)
1495 {
1496  if (!strcmp(appname, "smartctl"))
1497  return smartctl_examples;
1498  return "";
1499 }
1500 
1501 ata_device * freebsd_smart_interface::get_ata_device(const char * name, const char * type)
1502 {
1503  return new freebsd_ata_device(this, name, type);
1504 }
1505 
1506 #if FREEBSDVER > 800100
1507 ata_device * freebsd_smart_interface::get_atacam_device(const char * name, const char * type)
1508 {
1509  return new freebsd_atacam_device(this, name, type);
1510 }
1511 #endif
1512 
1513 scsi_device * freebsd_smart_interface::get_scsi_device(const char * name, const char * type)
1514 {
1515  return new freebsd_scsi_device(this, name, type);
1516 }
1517 
1518 nvme_device * freebsd_smart_interface::get_nvme_device(const char * name, const char * type,
1519  unsigned nsid)
1520 {
1521  return new freebsd_nvme_device(this, name, type, nsid);
1522 }
1523 
1524 // we are using CAM subsystem XPT enumerator to found all CAM (scsi/usb/ada/...)
1525 // devices on system despite of it's names
1526 //
1527 // If any errors occur, leave errno set as it was returned by the
1528 // system call, and return <0.
1529 //
1530 // arguments:
1531 // names: resulting array
1532 // show_all - export duplicate device name or not
1533 //
1534 // Return values:
1535 // -1: error
1536 // >=0: number of discovered devices
1537 
1538 bool get_dev_names_cam(std::vector<std::string> & names, bool show_all)
1539 {
1540  int fd;
1541  if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
1542  if (errno == ENOENT) /* There are no CAM device on this computer */
1543  return 0;
1544  int serrno = errno;
1545  pout("%s control device couldn't opened: %s\n", XPT_DEVICE, strerror(errno));
1546  errno = serrno;
1547  return false;
1548  }
1549 
1550  union ccb ccb;
1551  bzero(&ccb, sizeof(union ccb));
1552 
1553  ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
1554  ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1555  ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1556 
1557  ccb.ccb_h.func_code = XPT_DEV_MATCH;
1558  int bufsize = sizeof(struct dev_match_result) * MAX_NUM_DEV;
1559  ccb.cdm.match_buf_len = bufsize;
1560  // TODO: Use local buffer instead of malloc() if possible
1561  ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
1562  bzero(ccb.cdm.matches,bufsize); // clear ccb.cdm.matches structure
1563 
1564  if (ccb.cdm.matches == NULL) {
1565  close(fd);
1566  throw std::bad_alloc();
1567  }
1568  ccb.cdm.num_matches = 0;
1569  ccb.cdm.num_patterns = 0;
1570  ccb.cdm.pattern_buf_len = 0;
1571 
1572  /*
1573  * We do the ioctl multiple times if necessary, in case there are
1574  * more than MAX_NUM_DEV nodes in the EDT.
1575  */
1576  int skip_device = 0, skip_bus = 0, changed = 0; // TODO: bool
1577  std::string devname;
1578  do {
1579  if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1580  int serrno = errno;
1581  pout("error sending CAMIOCOMMAND ioctl: %s\n", strerror(errno));
1582  free(ccb.cdm.matches);
1583  close(fd);
1584  errno = serrno;
1585  return false;
1586  }
1587 
1588  if ((ccb.ccb_h.status != CAM_REQ_CMP)
1589  || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
1590  && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
1591  pout("got CAM error %#x, CDM error %d\n", ccb.ccb_h.status, ccb.cdm.status);
1592  free(ccb.cdm.matches);
1593  close(fd);
1594  errno = ENXIO;
1595  return false;
1596  }
1597 
1598  for (unsigned i = 0; i < ccb.cdm.num_matches; i++) {
1599  struct device_match_result *dev_result;
1600  struct periph_match_result *periph_result;
1601 
1602  if (ccb.cdm.matches[i].type == DEV_MATCH_BUS) {
1603  struct bus_match_result *bus_result;
1604 
1605  bus_result = &ccb.cdm.matches[i].result.bus_result;
1606 
1607  if (strcmp(bus_result->dev_name,"xpt") == 0) /* skip XPT bus at all */
1608  skip_bus = 1;
1609  else
1610  skip_bus = 0;
1611  changed = 1;
1612  } else if (ccb.cdm.matches[i].type == DEV_MATCH_DEVICE) {
1613  dev_result = &ccb.cdm.matches[i].result.device_result;
1614 
1615  if (dev_result->flags & DEV_RESULT_UNCONFIGURED || skip_bus == 1)
1616  skip_device = 1;
1617  else
1618  skip_device = 0;
1619 
1620  // /* Shall we skip non T_DIRECT devices ? */
1621  // if (dev_result->inq_data.device != T_DIRECT)
1622  // skip_device = 1;
1623  changed = 1;
1624  } else if (ccb.cdm.matches[i].type == DEV_MATCH_PERIPH &&
1625  (skip_device == 0 || show_all)) {
1626  /* One device may be populated as many peripherals (pass0 & da0 for example).
1627  * We are searching for best name
1628  */
1629  periph_result = &ccb.cdm.matches[i].result.periph_result;
1630  /* Prefer non-"pass" names */
1631  if (devname.empty() || strncmp(periph_result->periph_name, "pass", 4) != 0) {
1632  devname = strprintf("%s%s%d", _PATH_DEV, periph_result->periph_name, periph_result->unit_number);
1633  }
1634  changed = 0;
1635  };
1636  if ((changed == 1 || show_all) && !devname.empty()) {
1637  names.push_back(devname);
1638  devname.erase();
1639  changed = 0;
1640  };
1641  }
1642 
1643  } while ((ccb.ccb_h.status == CAM_REQ_CMP) && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
1644 
1645  if (!devname.empty())
1646  names.push_back(devname);
1647 
1648  free(ccb.cdm.matches);
1649  close(fd);
1650  return true;
1651 }
1652 
1653 // we are using ATA subsystem enumerator to found all ATA devices on system
1654 // despite of it's names
1655 //
1656 // If any errors occur, leave errno set as it was returned by the
1657 // system call, and return <0.
1658 
1659 // Return values:
1660 // -1: error
1661 // >=0: number of discovered devices
1662 int get_dev_names_ata(char*** names) {
1663  struct ata_ioc_devices devices;
1664  int fd=-1,maxchannel,serrno=-1,n=0;
1665  char **mp = NULL;
1666 
1667  *names=NULL;
1668 
1669  if ((fd = open(ATA_DEVICE, O_RDWR)) < 0) {
1670  if (errno == ENOENT) /* There are no ATA device on this computer */
1671  return 0;
1672  serrno = errno;
1673  pout("%s control device can't be opened: %s\n", ATA_DEVICE, strerror(errno));
1674  n = -1;
1675  goto end;
1676  };
1677 
1678  if (ioctl(fd, IOCATAGMAXCHANNEL, &maxchannel) < 0) {
1679  serrno = errno;
1680  pout("ioctl(IOCATAGMAXCHANNEL) on /dev/ata failed: %s\n", strerror(errno));
1681  n = -1;
1682  goto end;
1683  };
1684 
1685  // allocate space for up to MAX_NUM_DEV number of ATA devices
1686  mp = (char **)calloc(MAX_NUM_DEV, sizeof(char*));
1687  if (mp == NULL) {
1688  serrno=errno;
1689  pout("Out of memory constructing scan device list (on line %d)\n", __LINE__);
1690  n = -1;
1691  goto end;
1692  };
1693 
1694  for (devices.channel = 0; devices.channel < maxchannel && n < MAX_NUM_DEV; devices.channel++) {
1695  int j;
1696 
1697  if (ioctl(fd, IOCATADEVICES, &devices) < 0) {
1698  if (errno == ENXIO)
1699  continue; /* such channel not exist */
1700  pout("ioctl(IOCATADEVICES) on %s channel %d failed: %s\n", ATA_DEVICE, devices.channel, strerror(errno));
1701  n = -1;
1702  goto end;
1703  };
1704  for (j=0;j<=1 && n<MAX_NUM_DEV;j++) {
1705  if (devices.name[j][0] != '\0') {
1706  asprintf(mp+n, "%s%s", _PATH_DEV, devices.name[j]);
1707  if (mp[n] == NULL) {
1708  pout("Out of memory constructing scan ATA device list (on line %d)\n", __LINE__);
1709  n = -1;
1710  goto end;
1711  };
1712  n++;
1713  };
1714  };
1715  };
1716  if (n <= 0)
1717  goto end;
1718  mp = (char **)reallocf(mp,n*(sizeof (char*))); // shrink to correct size
1719  if (mp == NULL) {
1720  serrno=errno;
1721  pout("Out of memory constructing scan device list (on line %d)\n", __LINE__);
1722  n = -1;
1723  goto end;
1724  };
1725 
1726 end:
1727  if (fd>=0)
1728  close(fd);
1729  if (n <= 0) {
1730  free(mp);
1731  mp = NULL;
1732  }
1733 
1734  *names=mp;
1735 
1736  if (serrno>-1)
1737  errno=serrno;
1738  return n;
1739 }
1740 
1741 
1742 
1744  const char * type, const char * pattern /*= 0*/)
1745 {
1746  if (pattern) {
1747  set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
1748  return false;
1749  }
1750 
1751  // Make namelists
1752  char * * atanames = 0; int numata = 0;
1753  if (!type || !strcmp(type, "ata")) {
1754  numata = get_dev_names_ata(&atanames);
1755  if (numata < 0) {
1756  set_err(ENOMEM);
1757  return false;
1758  }
1759  }
1760 
1761  std::vector<std::string> scsinames;
1762  if (!type || !strcmp(type, "scsi")) { // do not export duplicated names
1763  if (!get_dev_names_cam(scsinames, false)) {
1764  set_err(errno);
1765  return false;
1766  }
1767  }
1768 
1769  // Add to devlist
1770  int i;
1771  if (type==NULL)
1772  type="";
1773  for (i = 0; i < numata; i++) {
1774  ata_device * atadev = get_ata_device(atanames[i], type);
1775  if (atadev)
1776  devlist.push_back(atadev);
1777  free(atanames[i]);
1778  }
1779  if(numata) free(atanames);
1780 
1781  for (i = 0; i < (int)scsinames.size(); i++) {
1782  if(!*type) { // try USB autodetection if no type specified
1783  smart_device * smartdev = autodetect_smart_device(scsinames[i].c_str());
1784  if(smartdev)
1785  devlist.push_back(smartdev);
1786  }
1787  else {
1788  scsi_device * scsidev = get_scsi_device(scsinames[i].c_str(), type);
1789  if (scsidev)
1790  devlist.push_back(scsidev);
1791  }
1792  }
1793  return true;
1794 }
1795 
1796 
1797 #if (FREEBSDVER < 800000) // without this build fail on FreeBSD 8
1798 static char done[USB_MAX_DEVICES];
1799 
1800 static int usbdevinfo(int f, int a, int rec, int busno, unsigned short & vendor_id,
1801  unsigned short & product_id, unsigned short & version)
1802 {
1803 
1804  struct usb_device_info di;
1805  int e, p, i;
1806  char devname[256];
1807 
1808  snprintf(devname, sizeof(devname),"umass%d",busno);
1809 
1810  di.udi_addr = a;
1811  e = ioctl(f, USB_DEVICEINFO, &di);
1812  if (e) {
1813  if (errno != ENXIO)
1814  printf("addr %d: I/O error\n", a);
1815  return 0;
1816  }
1817  done[a] = 1;
1818 
1819  // list devices
1820  for (i = 0; i < USB_MAX_DEVNAMES; i++) {
1821  if (di.udi_devnames[i][0]) {
1822  if(strcmp(di.udi_devnames[i],devname)==0) {
1823  // device found!
1824  vendor_id = di.udi_vendorNo;
1825  product_id = di.udi_productNo;
1826  version = di.udi_releaseNo;
1827  return 1;
1828  // FIXME
1829  }
1830  }
1831  }
1832  if (!rec)
1833  return 0;
1834  for (p = 0; p < di.udi_nports; p++) {
1835  int s = di.udi_ports[p];
1836  if (s >= USB_MAX_DEVICES) {
1837  continue;
1838  }
1839  if (s == 0)
1840  printf("addr 0 should never happen!\n");
1841  else {
1842  if(usbdevinfo(f, s, 1, busno, vendor_id, product_id, version)) return 1;
1843  }
1844  }
1845  return 0;
1846 }
1847 #endif
1848 
1849 
1850 static int usbdevlist(int busno,unsigned short & vendor_id,
1851  unsigned short & product_id, unsigned short & version)
1852 {
1853 #if (FREEBSDVER >= 800000) // libusb2 interface
1854  struct libusb20_device *pdev = NULL;
1855  struct libusb20_backend *pbe;
1856  uint32_t matches = 0;
1857  char buf[128]; // do not change!
1858  char devname[128];
1859  uint8_t n;
1860  struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
1861 
1862  pbe = libusb20_be_alloc_default();
1863 
1864  while ((pdev = libusb20_be_device_foreach(pbe, pdev))) {
1865  matches++;
1866 
1867  if (libusb20_dev_open(pdev, 0)) {
1868  warnx("libusb20_dev_open: could not open device");
1869  return 0;
1870  }
1871 
1872  pdesc=libusb20_dev_get_device_desc(pdev);
1873 
1874  snprintf(devname, sizeof(devname),"umass%d:",busno);
1875  for (n = 0; n != 255; n++) {
1876  if (libusb20_dev_get_iface_desc(pdev, n, buf, sizeof(buf)))
1877  break;
1878  if (buf[0] == 0)
1879  continue;
1880  if(strncmp(buf,devname,strlen(devname))==0){
1881  // found!
1882  vendor_id = pdesc->idVendor;
1883  product_id = pdesc->idProduct;
1884  version = pdesc->bcdDevice;
1885  libusb20_dev_close(pdev);
1886  libusb20_be_free(pbe);
1887  return 1;
1888  }
1889  }
1890 
1891  libusb20_dev_close(pdev);
1892  }
1893 
1894  if (matches == 0) {
1895  printf("No device match or lack of permissions.\n");
1896  }
1897 
1898  libusb20_be_free(pbe);
1899 
1900  return false;
1901 #else // freebsd < 8.0 USB stack, ioctl interface
1902 
1903  int i, a, rc;
1904  char buf[50];
1905  int ncont;
1906 
1907  for (ncont = 0, i = 0; i < 10; i++) {
1908  snprintf(buf, sizeof(buf), "%s%d", USBDEV, i);
1909  int f = open(buf, O_RDONLY);
1910  if (f >= 0) {
1911  memset(done, 0, sizeof done);
1912  for (a = 1; a < USB_MAX_DEVICES; a++) {
1913  if (!done[a]) {
1914  rc = usbdevinfo(f, a, 1, busno,vendor_id, product_id, version);
1915  if(rc) return 1;
1916  }
1917 
1918  }
1919  close(f);
1920  } else {
1921  if (errno == ENOENT || errno == ENXIO)
1922  continue;
1923  warn("%s", buf);
1924  }
1925  ncont++;
1926  }
1927  return 0;
1928 #endif
1929 }
1930 
1932 {
1933  unsigned short vendor_id = 0, product_id = 0, version = 0;
1934  struct cam_device *cam_dev;
1935  union ccb ccb;
1936  int bus=-1;
1937  int i;
1938  const char * test_name = name;
1939 
1940  memset(&ccb, 0, sizeof(ccb));
1941 
1942  // if dev_name null, or string length zero
1943  if (!name || !*name)
1944  return 0;
1945 
1946  // Dereference symlinks
1947  struct stat st;
1948  std::string pathbuf;
1949  if (!lstat(name, &st) && S_ISLNK(st.st_mode)) {
1950  char * p = realpath(name, (char *)0);
1951  if (p) {
1952  pathbuf = p;
1953  free(p);
1954  test_name = pathbuf.c_str();
1955  }
1956  }
1957 
1958  // check ATA bus
1959  char * * atanames = 0; int numata = 0;
1960  numata = get_dev_names_ata(&atanames);
1961  if (numata > 0) {
1962  // check ATA/ATAPI devices
1963  for (i = 0; i < numata; i++) {
1964  if(!strcmp(atanames[i],test_name)) {
1965  for (int c = i; c < numata; c++) free(atanames[c]);
1966  free(atanames);
1967  return new freebsd_ata_device(this, test_name, "");
1968  }
1969  else free(atanames[i]);
1970  }
1971  if(numata) free(atanames);
1972  }
1973  else {
1974  if (numata < 0)
1975  pout("Unable to get ATA device list\n");
1976  }
1977 
1978  // check CAM
1979  std::vector<std::string> scsinames;
1980  if (!get_dev_names_cam(scsinames, true))
1981  pout("Unable to get CAM device list\n");
1982  else if (!scsinames.empty()) {
1983  // check all devices on CAM bus
1984  for (i = 0; i < (int)scsinames.size(); i++) {
1985  if(strcmp(scsinames[i].c_str(), test_name)==0)
1986  { // our disk device is CAM
1987  if(strncmp(scsinames[i].c_str(), "/dev/pmp", strlen("/dev/pmp")) == 0) {
1988  pout("Skipping port multiplier [%s]\n", scsinames[i].c_str());
1989  set_err(EINVAL);
1990  return 0;
1991  }
1992  if ((cam_dev = cam_open_device(test_name, O_RDWR)) == NULL) {
1993  // open failure
1994  set_err(errno);
1995  return 0;
1996  }
1997  // zero the payload
1998  bzero(&(&ccb.ccb_h)[1], PATHINQ_SETTINGS_SIZE);
1999  ccb.ccb_h.func_code = XPT_PATH_INQ; // send PATH_INQ to the device
2000  if (ioctl(cam_dev->fd, CAMIOCOMMAND, &ccb) == -1) {
2001  warn("Get Transfer Settings CCB failed\n"
2002  "%s", strerror(errno));
2003  cam_close_device(cam_dev);
2004  return 0;
2005  }
2006  // now check if we are working with USB device, see umass.c
2007  if(strcmp(ccb.cpi.dev_name,"umass-sim") == 0) { // USB device found
2008  usbdevlist(bus,vendor_id, product_id, version);
2009  int bus=ccb.cpi.unit_number; // unit_number will match umass number
2010  cam_close_device(cam_dev);
2011  if(usbdevlist(bus,vendor_id, product_id, version)){
2012  const char * usbtype = get_usb_dev_type_by_id(vendor_id, product_id, version);
2013  if (usbtype)
2014  return get_sat_device(usbtype, new freebsd_scsi_device(this, test_name, ""));
2015  }
2016  return 0;
2017  }
2018 #if FREEBSDVER > 800100
2019  // check if we have ATA device connected to CAM (ada)
2020  if(ccb.cpi.protocol == PROTO_ATA){
2021  cam_close_device(cam_dev);
2022  return new freebsd_atacam_device(this, test_name, "");
2023  }
2024 #endif
2025  // close cam device, we don`t need it anymore
2026  cam_close_device(cam_dev);
2027  // handle as usual scsi
2028  return new freebsd_scsi_device(this, test_name, "");
2029  }
2030  }
2031  }
2032  // device is LSI raid supported by mfi driver
2033  if(!strncmp("/dev/mfid", test_name, strlen("/dev/mfid")))
2034  set_err(EINVAL, "To monitor disks on LSI RAID load mfip.ko module and run 'smartctl -a /dev/passX' to show SMART information");
2035 
2036  // form /dev/nvme* or nvme*
2037  if(!strncmp("/dev/nvme", test_name, strlen("/dev/nvme")))
2038  return new freebsd_nvme_device(this, name, "", 0 /* use default nsid */);
2039 
2040  // device type unknown
2041  return 0;
2042 }
2043 
2044 
2046 {
2047  int disknum = -1, n1 = -1, n2 = -1;
2048 
2049  if (sscanf(type, "3ware,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
2050  // 3Ware ?
2051  static const char * fbsd_dev_twe_ctrl = "/dev/twe";
2052  static const char * fbsd_dev_twa_ctrl = "/dev/twa";
2053  static const char * fbsd_dev_tws_ctrl = "/dev/tws";
2054  int contr = -1;
2055 
2056  if (n2 != (int)strlen(type)) {
2057  set_err(EINVAL, "Option -d 3ware,N requires N to be a non-negative integer");
2058  return 0;
2059  }
2060  if (!(0 <= disknum && disknum <= 127)) {
2061  set_err(EINVAL, "Option -d 3ware,N (N=%d) must have 0 <= N <= 127", disknum);
2062  return 0;
2063  }
2064 
2065  // guess 3ware device type based on device name
2066  if (str_starts_with(name, fbsd_dev_twa_ctrl) ||
2067  str_starts_with(name, fbsd_dev_tws_ctrl) ) {
2069  }
2070  if (!strncmp(fbsd_dev_twe_ctrl, name, strlen(fbsd_dev_twe_ctrl))){
2072  }
2073 
2074  if(contr == -1){
2075  set_err(EINVAL, "3ware controller type unknown, use %sX, %sX or %sX devices",
2076  fbsd_dev_twe_ctrl, fbsd_dev_twa_ctrl, fbsd_dev_tws_ctrl);
2077  return 0;
2078  }
2079  return new freebsd_escalade_device(this, name, contr, disknum);
2080  }
2081 
2082  // Highpoint ?
2083  int controller = -1, channel = -1; disknum = 1;
2084  n1 = n2 = -1; int n3 = -1;
2085  if (sscanf(type, "hpt,%n%d/%d%n/%d%n", &n1, &controller, &channel, &n2, &disknum, &n3) >= 2 || n1 == 4) {
2086  int len = strlen(type);
2087  if (!(n2 == len || n3 == len)) {
2088  set_err(EINVAL, "Option '-d hpt,L/M/N' supports 2-3 items");
2089  return 0;
2090  }
2091  if (!(1 <= controller && controller <= 8)) {
2092  set_err(EINVAL, "Option '-d hpt,L/M/N' invalid controller id L supplied");
2093  return 0;
2094  }
2095  if (!(1 <= channel && channel <= 128)) {
2096  set_err(EINVAL, "Option '-d hpt,L/M/N' invalid channel number M supplied");
2097  return 0;
2098  }
2099  if (!(1 <= disknum && disknum <= 15)) {
2100  set_err(EINVAL, "Option '-d hpt,L/M/N' invalid pmport number N supplied");
2101  return 0;
2102  }
2103  return new freebsd_highpoint_device(this, name, controller, channel, disknum);
2104  }
2105 
2106  // CCISS ?
2107  disknum = n1 = n2 = -1;
2108  if (sscanf(type, "cciss,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
2109  if (n2 != (int)strlen(type)) {
2110  set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer");
2111  return 0;
2112  }
2113  if (!(0 <= disknum && disknum <= 127)) {
2114  set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
2115  return 0;
2116  }
2117  return get_sat_device("sat,auto", new freebsd_cciss_device(this, name, disknum));
2118  }
2119 #if FREEBSDVER > 800100
2120  // adaX devices ?
2121  if(!strcmp(type,"atacam"))
2122  return new freebsd_atacam_device(this, name, "");
2123 #endif
2124  // Areca?
2125  disknum = n1 = n2 = -1;
2126  int encnum = 1;
2127  if (sscanf(type, "areca,%n%d/%d%n", &n1, &disknum, &encnum, &n2) >= 1 || n1 == 6) {
2128  if (!(1 <= disknum && disknum <= 128)) {
2129  set_err(EINVAL, "Option -d areca,N/E (N=%d) must have 1 <= N <= 128", disknum);
2130  return 0;
2131  }
2132  if (!(1 <= encnum && encnum <= 8)) {
2133  set_err(EINVAL, "Option -d areca,N/E (E=%d) must have 1 <= E <= 8", encnum);
2134  return 0;
2135  }
2136  return new freebsd_areca_ata_device(this, name, disknum, encnum);
2137  }
2138 
2139  return 0;
2140 }
2141 
2143 {
2144  return "3ware,N, hpt,L/M/N, cciss,N, areca,N/E"
2145 #if FREEBSDVER > 800100
2146  ", atacam"
2147 #endif
2148  ;
2149 }
2150 
2151 } // namespace
2152 
2153 /////////////////////////////////////////////////////////////////////////////
2154 /// Initialize platform interface and register with smi()
2155 
2156 void smart_interface::init()
2157 {
2158  static os_freebsd::freebsd_smart_interface the_interface;
2159  smart_interface::set(&the_interface);
2160 }
bool get_dev_names_cam(std::vector< std::string > &names, bool show_all)
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:103
#define ATA_SMART_WRITE_LOG_SECTOR
Definition: atacmds.h:104
Implement CCISS RAID support with old functions.
freebsd_highpoint_device(smart_interface *intf, const char *dev_name, unsigned char controller, unsigned char channel, unsigned char port)
Definition: os_freebsd.cpp:813
virtual int ata_command_interface(smart_command_set command, int select, char *data)
Old ATA interface called by ata_pass_through()
Definition: os_freebsd.cpp:835
virtual bool open()
Open device, return false on error.
virtual bool nvme_pass_through(const nvme_cmd_in &in, nvme_cmd_out &out)
NVMe pass through.
Definition: os_freebsd.cpp:550
#define TWEIO_COMMAND
Definition: os_freebsd.h:305
ata_reg_alias_16 sector_count_16
struct nvme_completion cpl
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:1563
freebsd_escalade_device(smart_interface *intf, const char *dev_name, int escalade_type, int disknum)
Definition: os_freebsd.cpp:601
u16 s[6]
Definition: megaraid.h:97
#define ATACMDS_H_CVSID
Definition: atacmds.h:28
ATA Input registers for 48-bit commands.
ata_out_regs_flags out_needed
True if output register value needed.
static char done[USB_MAX_DEVICES]
#define HPT_IOCTL_GET_CHANNEL_INFO
Definition: os_freebsd.h:566
ata_reg_alias_16 sector_count_16
u32 size
Definition: megaraid.h:79
#define SAT_ATA_PASSTHROUGH_12
Definition: scsicmds.h:99
unsigned char m_disknum
Disk number.
virtual bool open()
Open device, return false on error.
Definition: os_freebsd.cpp:499
const char * get_dev_type() const
Get device type.
freebsd_scsi_device(smart_interface *intf, const char *dev_name, const char *req_type)
UINT8 * sensep
Definition: scsicmds.h:122
void set_disknum(int disknum)
Definition: dev_areca.h:126
virtual ata_device * get_sat_device(const char *type, scsi_device *scsidev)
Return ATA->SCSI filter for a SAT or USB 'type'.
Definition: scsiata.cpp:1486
#define BAD_SMART
Definition: os_freebsd.cpp:87
ata_register error
#define HPT_READ
Definition: os_freebsd.h:570
#define ATA_SMART_CMD
Definition: atacmds.h:75
TWE_Command_ATA ata
Definition: os_freebsd.h:267
Implement AMCC/3ware RAID support.
Definition: os_freebsd.cpp:584
#define DXFER_FROM_DEVICE
Definition: scsicmds.h:111
Implement shared open/close routines with old functions.
Definition: os_freebsd.cpp:139
ata_reg_alias_48 lba_48
bool str_starts_with(const char *str, const char *prefix)
Definition: utility.h:57
#define OS_FREEBSD_H_CVSID
Definition: os_freebsd.h:85
unsigned char m_controller_type
Definition: os_freebsd.cpp:183
ata_reg_alias_16 lba_high_16
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.
Smart pointer class for device pointers.
virtual bool scsi_pass_through(scsi_cmnd_io *iop)
SCSI pass through.
virtual std::string get_os_version_str()
Return info string about build host and/or OS version.
ata_register device
#define PATHINQ_SETTINGS_SIZE
Definition: os_freebsd.cpp:80
struct _HPT_PASS_THROUGH_HEADER * PHPT_PASS_THROUGH_HEADER
const char * scsi_get_opcode_name(UINT8 opcode)
Definition: scsicmds.cpp:177
virtual bool close()=0
Close device, return false on error.
const char * os_XXXX_c_cvsid
Definition: os_freebsd.cpp:83
unsigned cdw11
unsigned timeout
Definition: scsicmds.h:125
void printwarning(int msgNo, const char *extra)
Definition: os_freebsd.cpp:93
#define ATA_SMART_DISABLE
Definition: atacmds.h:107
int m_escalade_type
Type string for escalade_command_interface().
Definition: os_freebsd.cpp:597
Adapter class to implement new ATA pass through old interface.
struct _HPT_PASS_THROUGH_HEADER HPT_PASS_THROUGH_HEADER
virtual nvme_device * get_nvme_device(const char *name, const char *type, unsigned nsid)
Return standard NVMe device.
NVMe pass through input parameters.
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)
ATA pass through.
Definition: os_freebsd.cpp:271
#define ATA_SMART_AUTOSAVE
Definition: atacmds.h:100
struct tw_cl_command_packet cmd_pkt
Definition: os_freebsd.h:539
int m_fd
filedesc, -1 if not open.
Definition: os_freebsd.cpp:164
device_info & set_info()
R/W access to device info struct.
#define snprintf
Definition: utility.h:68
virtual int arcmsr_get_dev_type()
Definition: dev_areca.cpp:350
virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io *iop)
virtual bool open()
Open device, return false on error.
Definition: os_freebsd.cpp:822
#define TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH
Definition: os_freebsd.h:544
ata_reg_alias_16 lba_high_16
void * buffer
Pointer to data buffer.
int get_dev_names_ata(char ***names)
virtual bool scan_smart_devices(smart_device_list &devlist, const char *type, const char *pattern=0)
Fill 'devlist' with devices of some 'type' with device names specified by some optional 'pattern'...
NVMe pass through output parameters.
virtual bool is_open() const
Return true if device is open.
Definition: os_freebsd.cpp:210
size_t resp_sense_len
Definition: scsicmds.h:126
void push_back(smart_device *dev)
#define INQUIRY
Definition: scsicmds.h:65
#define ATA_IDENTIFY_DEVICE
Definition: atacmds.h:72
ata_register lba_mid
virtual scsi_device * get_scsi_device(const char *name, const char *type)
Return standard SCSI device.
#define CONTROLLER_3WARE_9000_CHAR
Definition: os_freebsd.cpp:76
#define INT64_H_CVSID
Definition: int64.h:23
bool nonempty(const void *data, int size)
Definition: utility.cpp:633
virtual smart_device * autodetect_open()
Open device with autodetection support.
#define ATA_IDENTIFY_PACKET_DEVICE
Definition: atacmds.h:73
#define MAX_MSG
Definition: os_freebsd.cpp:90
#define HPT_WRITE
Definition: os_freebsd.h:571
uint32_t nsid
unsigned int in_size
Definition: os_freebsd.h:595
#define SCSICMDS_H_CVSID
Definition: scsicmds.h:33
Implement standard ATA support.
Definition: os_freebsd.cpp:242
ata_in_regs_48bit in_regs
Input registers.
unsigned char m_hpt_data[3]
controller/channel/port
Definition: os_freebsd.cpp:809
UINT8 * dxferp
Definition: scsicmds.h:120
ata_out_regs_48bit out_regs
Output registers.
int get_fd() const
Return filedesc for derived classes.
Definition: os_freebsd.cpp:157
UINT8 * cmnd
Definition: scsicmds.h:116
unsigned result
Command specific result (DW0)
ptr_t data
Definition: megaraid.h:94
#define NO_DISK_3WARE
Definition: os_freebsd.cpp:88
#define MAX_NUM_DEV
Definition: os_freebsd.h:87
Implement Highpoint RAID support with old functions.
Definition: os_freebsd.cpp:796
List of devices for DEVICESCAN.
static const char smartctl_examples[]
Definition: os_freebsd.cpp:187
device_type * release()
Return the pointer and release ownership.
#define ARGUSED(x)
Definition: os_freebsd.cpp:128
struct _HPT_CHANNEL_INFO_V2 HPT_CHANNEL_INFO_V2
#define HPT_DO_IOCONTROL
Definition: os_freebsd.h:600
#define ATA_CHECK_POWER_MODE
Definition: atacmds.h:71
virtual smart_device * autodetect_open()
SCSI open with autodetection support.
#define HPT_IOCTL_GET_CHANNEL_INFO_V2
Definition: os_freebsd.h:567
static void init()
Initialize platform interface and register with smi().
Definition: dev_legacy.cpp:341
enum ata_cmd_in::@29 direction
I/O direction.
The platform interface abstraction.
freebsd_cciss_device(smart_interface *intf, const char *name, unsigned char disknum)
struct nvme_command cmd
unsigned int ctrl_code
Definition: os_freebsd.h:593
NVMe device access.
static void set(smart_interface *intf)
Set interface to use, must be called from init().
void * buffer
Pointer to data buffer.
unsigned get_nsid() const
Get namespace id.
#define HPT_IOCTL_MAGIC
Definition: os_freebsd.h:573
#define NVME_NS_PREFIX
#define SAT_ATA_PASSTHROUGH_16
Definition: scsicmds.h:102
struct _HPT_CHANNEL_INFO HPT_CHANNEL_INFO
void dStrHex(const char *str, int len, int no_ascii)
Definition: scsicmds.cpp:87
unsigned char failuretest_permissive
Definition: smartctl.cpp:1198
unsigned int devices[PMPORT_PER_CHANNEL]
Definition: os_freebsd.h:588
unsigned char opcode
Opcode (CDW0 07:00)
unsigned char scsi_debugmode
Definition: scsicmds.cpp:54
#define CONTROLLER_3WARE_678K_CHAR
Definition: os_freebsd.cpp:77
ATA Output registers for 48-bit commands.
freebsd_areca_scsi_device(smart_interface *intf, const char *dev_name, int disknum, int encnum=1)
unsigned int out_size
Definition: os_freebsd.h:597
bool is_ata() const
Return true if ATA device.
Definition: dev_interface.h:93
void pout(const char *fmt,...)
Definition: smartctl.cpp:1179
size_t max_sense_len
Definition: scsicmds.h:124
unsigned int magic
Definition: os_freebsd.h:592
unsigned cdw12
ata_register status
int dxfer_dir
Definition: scsicmds.h:118
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
#define ATA_SMART_READ_VALUES
Definition: atacmds.h:98
void set_encnum(int encnum)
Definition: dev_areca.h:129
unsigned size
Size of buffer.
#define HPT_IOCTL_IDE_PASS_THROUGH
Definition: os_freebsd.h:568
unsigned cdw15
Cmd specific.
SCSI device access.
Definition: atacmds.h:55
ata_reg_alias_16 lba_mid_16
unsigned nsid
Namespace ID.
ata_register features
#define DXFER_NONE
Definition: scsicmds.h:110
virtual int do_cmd(struct ata_ioc_request *request, bool is_48bit_cmd)
Definition: os_freebsd.cpp:260
#define ATA_SMART_AUTO_OFFLINE
Definition: atacmds.h:111
static int usbdevlist(int busno, unsigned short &vendor_id, unsigned short &product_id, unsigned short &version)
smart_command_set
Definition: atacmds.h:48
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).
freebsd_areca_ata_device(smart_interface *intf, const char *dev_name, int disknum, int encnum=1)
virtual smart_device * autodetect_smart_device(const char *name)
Autodetect device if no device type specified.
#define DXFER_TO_DEVICE
Definition: scsicmds.h:112
#define ATA_SMART_READ_THRESHOLDS
Definition: atacmds.h:99
bool is_48bit_cmd() const
Return true if 48-bit command.
virtual const char * get_usb_dev_type_by_id(int vendor_id, int product_id, int version=-1)
Get type name for USB device with known VENDOR:PRODUCT ID.
Definition: scsiata.cpp:1593
#define CCISS_H_CVSID
Definition: cciss.h:4
#define TW_IOCTL_BUFFER_SIZE
Definition: os_freebsd.cpp:122
ata_reg_alias_16 lba_low_16
freebsd_ata_device(smart_interface *intf, const char *dev_name, const char *req_type)
Definition: os_freebsd.cpp:254
ata_register device
Base class for all devices.
Definition: dev_interface.h:39
virtual std::string get_app_examples(const char *appname)
Return example string for program 'appname'.
static int usbdevinfo(int f, int a, int rec, int busno, unsigned short &vendor_id, unsigned short &product_id, unsigned short &version)
#define USBDEV
Definition: os_freebsd.cpp:53
ata_reg_alias_16 lba_low_16
virtual bool close()
Close device, return false on error.
Definition: os_freebsd.cpp:226
size_t cmnd_len
Definition: scsicmds.h:117
ATA device access.
#define ATA_SMART_IMMEDIATE_OFFLINE
Definition: atacmds.h:102
#define ATA_DEVICE
Definition: os_freebsd.cpp:125
virtual smart_device * autodetect_open()
Open device with autodetection support.
virtual bool close()
Close device, return false on error.
unsigned size
Size of buffer.
virtual ata_device * get_ata_device(const char *name, const char *type)
Return standard ATA device.
union tw_cl_command_packet::@48 command
unsigned cdw13
ata_register command
virtual std::string get_valid_custom_dev_types_str()
Return valid 'type' args accepted by above.
UINT8 scsi_status
Definition: scsicmds.h:127
virtual bool open()
Open device, return false on error.
#define NVME_PASSTHROUGH_CMD
ATA pass through input parameters.
freebsd_nvme_device(smart_interface *intf, const char *dev_name, const char *req_type, unsigned nsid)
Definition: os_freebsd.cpp:491
unsigned cdw10
virtual smart_device * get_custom_smart_device(const char *name, const char *type)
Return device for platform specific 'type'.
#define ATA_SMART_ENABLE
Definition: atacmds.h:106
ata_reg_alias_16 lba_mid_16
int scsiStdInquiry(scsi_device *device, UINT8 *pBuf, int bufLen)
Definition: scsicmds.cpp:774
unsigned char m_controller_port
Definition: os_freebsd.cpp:184
Standard SCSI support.
Definition: os_freebsd.cpp:993
std::string strprintf(const char *fmt,...)
Definition: utility.cpp:750
Implement platform interface with old functions.
void set_nsid(unsigned nsid)
Set namespace id.
virtual bool scsi_pass_through(scsi_cmnd_io *iop)
SCSI pass through.
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)
ATA pass through.
Definition: os_freebsd.cpp:623
ata_register lba_high
smart_interface * smi()
Get interface which produced this object.
size_t dxfer_len
Definition: scsicmds.h:121
void clear_err()
Clear last error info.
struct tw_cl_driver_packet driver_pkt
Definition: os_freebsd.h:536
const char * get_dev_name() const
Get device (path)name.
virtual bool open()
Open device, return false on error.
Definition: os_freebsd.cpp:216
Definition: atacmds.h:50
std::string info_name
Informal name.
Definition: dev_interface.h:53
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
union tw_cl_command_7k cmd_pkt_7k
Definition: os_freebsd.h:476
const char * get_req_type() const
Get type requested by user, empty if none.
ata_reg_alias_16 features_16
struct cam_device * m_camdev
virtual bool open()
Open device, return false on error.
Definition: os_freebsd.cpp:610
ATA pass through output parameters.
#define SCSI_TIMEOUT_DEFAULT
Definition: scsicmds.h:307
TWE_Command tu_command
Definition: os_freebsd.h:300
#define UTILITY_H_CVSID
Definition: utility.h:28
#define nvme_completion_is_error(cpl)
#define NVME_CTRLR_PREFIX
unsigned cdw14
#define TWE_OP_ATA_PASSTHROUGH
Definition: os_freebsd.h:102
int cciss_io_interface(int device, int target, struct scsi_cmnd_io *iop, int report)
TW_UINT32 buffer_length
Definition: os_freebsd.h:516
ata_reg_alias_48 lba_48
virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io *iop)
#define ATA_SMART_STATUS
Definition: atacmds.h:108