smartmontools  SVN Rev 4321
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 4257 2016-03-27 23:32:54Z 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  // FIXME:
401  // 48bit commands are broken in ATACAM before r242422/HEAD
402  // and may cause system hang
403  // Waiting for MFC to make sure that bug is fixed,
404  // later version check needs to be added
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 
410  memset(&ccb, 0, sizeof(ccb));
411 
412  if (request->count == 0)
413  camflags = CAM_DIR_NONE;
414  else if (request->flags & ATA_CMD_READ)
415  camflags = CAM_DIR_IN;
416  else
417  camflags = CAM_DIR_OUT;
418 
419  cam_fill_ataio(&ccb.ataio,
420  0,
421  NULL,
422  camflags,
423  MSG_SIMPLE_Q_TAG,
424  (u_int8_t*)request->data,
425  request->count,
426  request->timeout * 1000); // timeout in seconds
427 
428  ccb.ataio.cmd.flags = CAM_ATAIO_NEEDRESULT |
429  (is_48bit_cmd ? CAM_ATAIO_48BIT : 0);
430  // ata_28bit_cmd
431  ccb.ataio.cmd.command = request->u.ata.command;
432  ccb.ataio.cmd.features = request->u.ata.feature;
433  ccb.ataio.cmd.lba_low = request->u.ata.lba;
434  ccb.ataio.cmd.lba_mid = request->u.ata.lba >> 8;
435  ccb.ataio.cmd.lba_high = request->u.ata.lba >> 16;
436  // ata_48bit cmd
437  ccb.ataio.cmd.lba_low_exp = request->u.ata.lba >> 24;
438  ccb.ataio.cmd.lba_mid_exp = request->u.ata.lba >> 32;
439  ccb.ataio.cmd.lba_high_exp = request->u.ata.lba >> 40;
440  ccb.ataio.cmd.device = 0x40 | ((request->u.ata.lba >> 24) & 0x0f);
441  ccb.ataio.cmd.sector_count = request->u.ata.count;
442  ccb.ataio.cmd.sector_count_exp = request->u.ata.count >> 8;;
443 
444  ccb.ccb_h.flags |= CAM_DEV_QFRZDIS;
445 
446  if (cam_send_ccb(m_camdev, &ccb) < 0) {
447  set_err(EIO, "cam_send_ccb failed");
448  return -1;
449  }
450 
451  if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
452  if(scsi_debugmode > 0)
453  cam_error_print(m_camdev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
454  set_err(EIO);
455  return -1;
456  }
457 
458  request->u.ata.lba =
459  ((u_int64_t)(ccb.ataio.res.lba_low)) |
460  ((u_int64_t)(ccb.ataio.res.lba_mid) << 8) |
461  ((u_int64_t)(ccb.ataio.res.lba_high) << 16) |
462  ((u_int64_t)(ccb.ataio.res.lba_low_exp) << 24) |
463  ((u_int64_t)(ccb.ataio.res.lba_mid_exp) << 32) |
464  ((u_int64_t)(ccb.ataio.res.lba_high_exp) << 40);
465 
466  request->u.ata.count = ccb.ataio.res.sector_count | (ccb.ataio.res.sector_count_exp << 8);
467  request->error = ccb.ataio.res.error;
468 
469  return 0;
470 }
471 
472 #endif
473 
474 /////////////////////////////////////////////////////////////////////////////
475 /// NVMe support
476 
478 : public /*implements*/ nvme_device,
479  public /*extends*/ freebsd_smart_device
480 {
481 public:
482  freebsd_nvme_device(smart_interface * intf, const char * dev_name,
483  const char * req_type, unsigned nsid);
484 
485  virtual bool open();
486 
487  virtual bool nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & out);
488 };
489 
491  const char * req_type, unsigned nsid)
492 : smart_device(intf, dev_name, "nvme", req_type),
493  nvme_device(nsid),
495 {
496 }
497 
499 {
500  const char *dev = get_dev_name();
501  if (!strnstr(dev, NVME_CTRLR_PREFIX, strlen(NVME_CTRLR_PREFIX))) {
502  set_err(EINVAL, "NVMe controller controller/namespace ids must begin with '%s'",
504  return false;
505  }
506 
507  int nsid = -1, ctrlid = -1;
508  char tmp;
509 
510  if(sscanf(dev, NVME_CTRLR_PREFIX"%d%c", &ctrlid, &tmp) == 1)
511  {
512  if(ctrlid < 0) {
513  set_err(EINVAL, "Invalid NVMe controller number");
514  return false;
515  }
516  nsid = 0xFFFFFFFF; // broadcast id
517  }
518  else if (sscanf(dev, NVME_CTRLR_PREFIX"%d"NVME_NS_PREFIX"%d%c",
519  &ctrlid, &nsid, &tmp) == 2)
520  {
521  if(ctrlid < 0 || nsid < 0) {
522  set_err(EINVAL, "Invalid NVMe controller/namespace number");
523  return false;
524  }
525  }
526  else {
527  set_err(EINVAL, "Invalid NVMe controller/namespace syntax");
528  return false;
529  }
530 
531  // we should always open controller, not namespace device
532  char full_path[64];
533  snprintf(full_path, sizeof(full_path), NVME_CTRLR_PREFIX"%d", ctrlid);
534 
535  int fd;
536  if ((fd = ::open(full_path, O_RDWR))<0) {
537  set_err(errno);
538  return false;
539  }
540  set_fd(fd);
541 
542  if (!get_nsid()) {
543  set_nsid(nsid);
544  }
545 
546  return true;
547 }
548 
550 {
551  // nvme_passthru_cmd pt;
552  struct nvme_pt_command pt;
553  memset(&pt, 0, sizeof(pt));
554 
555  pt.cmd.opc = in.opcode;
556  pt.cmd.nsid = in.nsid;
557  pt.buf = in.buffer;
558  pt.len = in.size;
559  pt.cmd.cdw10 = in.cdw10;
560  pt.cmd.cdw11 = in.cdw11;
561  pt.cmd.cdw12 = in.cdw12;
562  pt.cmd.cdw13 = in.cdw13;
563  pt.cmd.cdw14 = in.cdw14;
564  pt.cmd.cdw15 = in.cdw15;
565  pt.is_read = 1; // should we use in.direction()?
566 
567  int status = ioctl(get_fd(), NVME_PASSTHROUGH_CMD, &pt);
568 
569  if (status < 0)
570  return set_err(errno, "NVME_PASSTHROUGH_CMD: %s", strerror(errno));
571 
572  out.result=pt.cpl.cdw0; // Command specific result (DW0)
573 
574  if (nvme_completion_is_error(&pt.cpl))
575  return set_nvme_err(out, nvme_completion_is_error(&pt.cpl));
576 
577  return true;
578 }
579 
580 /////////////////////////////////////////////////////////////////////////////
581 /// Implement AMCC/3ware RAID support
582 
584 : public /*implements*/ ata_device,
585  public /*extends*/ freebsd_smart_device
586 {
587 public:
588  freebsd_escalade_device(smart_interface * intf, const char * dev_name,
589  int escalade_type, int disknum);
590 
591 protected:
592  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
593  virtual bool open();
594 
595 private:
596  int m_escalade_type; ///< Type string for escalade_command_interface().
597  int m_disknum; ///< Disk number.
598 };
599 
601  int escalade_type, int disknum)
602 : smart_device(intf, dev_name, "3ware", "3ware"),
604  m_escalade_type(escalade_type), m_disknum(disknum)
605 {
606  set_info().info_name = strprintf("%s [3ware_disk_%02d]", dev_name, disknum);
607 }
608 
610 {
611  const char *dev = get_dev_name();
612  int fd;
613 
614  if ((fd = ::open(dev,O_RDWR))<0) {
615  set_err(errno);
616  return false;
617  }
618  set_fd(fd);
619  return true;
620 }
621 
623 {
624  // to hold true file descriptor
625  int fd = get_fd();
626 
627  if (!ata_cmd_is_ok(in,
628  true, // data_out_support
629  false, // TODO: multi_sector_support
630  true) // ata_48bit_support
631  )
632  return false;
633 
634  struct twe_usercommand* cmd_twe = NULL;
635  TW_OSLI_IOCTL_NO_DATA_BUF* cmd_twa = NULL;
636  TWE_Command_ATA* ata = NULL;
637 
638  // Used by both the SCSI and char interfaces
639  char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];
640 
641  if (m_disknum < 0) {
643  return -1;
644  }
645 
646  memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);
647 
649  cmd_twa = (TW_OSLI_IOCTL_NO_DATA_BUF*)ioctl_buffer;
650  cmd_twa->pdata = ((TW_OSLI_IOCTL_WITH_PAYLOAD*)cmd_twa)->payload.data_buf;
651  cmd_twa->driver_pkt.buffer_length = in.size;
652  // using "old" packet format to speak with SATA devices
653  ata = (TWE_Command_ATA*)&cmd_twa->cmd_pkt.command.cmd_pkt_7k;
655  cmd_twe = (struct twe_usercommand*)ioctl_buffer;
656  ata = &cmd_twe->tu_command.ata;
657  } else {
658  return set_err(ENOSYS,
659  "Unrecognized escalade_type %d in linux_3ware_command_interface(disk %d)\n"
660  "Please contact " PACKAGE_BUGREPORT "\n", (int)m_escalade_type, m_disknum);
661  }
662 
663  ata->opcode = TWE_OP_ATA_PASSTHROUGH;
664 
665  // Same for (almost) all commands - but some reset below
666  ata->request_id = 0xFF;
667  ata->unit = m_disknum;
668  ata->status = 0;
669  ata->flags = 0x1;
670  ata->size = 0x5; // TODO: multisector support
671  // Set registers
672  {
673  const ata_in_regs_48bit & r = in.in_regs;
674  ata->features = r.features_16;
675  ata->sector_count = r.sector_count_16;
676  ata->sector_num = r.lba_low_16;
677  ata->cylinder_lo = r.lba_mid_16;
678  ata->cylinder_hi = r.lba_high_16;
679  ata->drive_head = r.device;
680  ata->command = r.command;
681  }
682 
683  // Is this a command that reads or returns 512 bytes?
684  // passthru->param values are:
685  // 0x0 - non data command without TFR write check,
686  // 0x8 - non data command with TFR write check,
687  // 0xD - data command that returns data to host from device
688  // 0xF - data command that writes data from host to device
689  // passthru->size values are 0x5 for non-data and 0x07 for data
690  bool readdata = false;
691  if (in.direction == ata_cmd_in::data_in) {
693  cmd_twe->tu_data = in.buffer;
694  cmd_twe->tu_size = 512;
695  }
696 
697  readdata=true;
698  ata->sgl_offset = 0x5;
699  ata->param = 0xD;
700  // For 64-bit to work correctly, up the size of the command packet
701  // in dwords by 1 to account for the 64-bit single sgl 'address'
702  // field. Note that this doesn't agree with the typedefs but it's
703  // right (agree with kernel driver behavior/typedefs).
704  // if (sizeof(long)==8)
705  // ata->size++;
706  }
707  else if (in.direction == ata_cmd_in::no_data) {
708  // Non data command -- but doesn't use large sector
709  // count register values.
710  ata->sgl_offset = 0x0;
711  ata->param = 0x8;
712  ata->sector_count = 0x0;
713  }
714  else if (in.direction == ata_cmd_in::data_out) {
715  ata->sgl_offset = 0x5;
716  ata->param = 0xF; // PIO data write
718  cmd_twe->tu_data = in.buffer;
719  cmd_twe->tu_size = 512;
720  }
722  memcpy(cmd_twa->pdata, in.buffer, in.size);
723  }
724  }
725  else
726  return set_err(EINVAL);
727 
728  // 3WARE controller can NOT have packet device internally
730  return set_err(ENODEV, "No drive on port %d", m_disknum);
731  }
732 
733  // Now send the command down through an ioctl()
734  int ioctlreturn;
736  ioctlreturn=ioctl(fd,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);
737  } else {
738  ioctlreturn=ioctl(fd,TWEIO_COMMAND,cmd_twe);
739  }
740 
741  // Deal with the different error cases
742  if (ioctlreturn) {
743  return set_err(EIO);
744  }
745 
746  // See if the ATA command failed. Now that we have returned from
747  // the ioctl() call, if passthru is valid, then:
748  // - ata->status contains the 3ware controller STATUS
749  // - ata->command contains the ATA STATUS register
750  // - ata->features contains the ATA ERROR register
751  //
752  // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
753  // If bit 0 (error bit) is set, then ATA ERROR register is valid.
754  // While we *might* decode the ATA ERROR register, at the moment it
755  // doesn't make much sense: we don't care in detail why the error
756  // happened.
757 
758  if (ata->status || (ata->command & 0x21)) {
759  if (scsi_debugmode)
760  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);
761  return set_err(EIO);
762  }
763 
764  // If this is a read data command, copy data to output buffer
765  if (readdata) {
767  memcpy(in.buffer, cmd_twa->pdata, in.size);
769  memcpy(in.buffer, cmd_twe->tu_data, in.size); // untested
770  }
771  }
772  // Return register values
773  if (ata) {
774  ata_out_regs_48bit & r = out.out_regs;
775  r.error = ata->features;
776  r.sector_count_16 = ata->sector_count;
777  r.lba_low_16 = ata->sector_num;
778  r.lba_mid_16 = ata->cylinder_lo;
779  r.lba_high_16 = ata->cylinder_hi;
780  r.device = ata->drive_head;
781  r.status = ata->command;
782  }
783  // look for nonexistent devices/ports
785  && !nonempty((unsigned char *)in.buffer, in.size)) {
786  return set_err(ENODEV, "No drive on port %d", m_disknum);
787  }
788  return true;
789 }
790 
791 
792 /////////////////////////////////////////////////////////////////////////////
793 /// Implement Highpoint RAID support with old functions
794 
796 : public /*implements*/ ata_device_with_command_set,
797  public /*extends*/ freebsd_smart_device
798 {
799 public:
800  freebsd_highpoint_device(smart_interface * intf, const char * dev_name,
801  unsigned char controller, unsigned char channel, unsigned char port);
802 
803 protected:
804  virtual int ata_command_interface(smart_command_set command, int select, char * data);
805  virtual bool open();
806 
807 private:
808  unsigned char m_hpt_data[3]; ///< controller/channel/port
809 };
810 
811 
813  unsigned char controller, unsigned char channel, unsigned char port)
814 : smart_device(intf, dev_name, "hpt", "hpt"),
816 {
817  m_hpt_data[0] = controller; m_hpt_data[1] = channel; m_hpt_data[2] = port;
818  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]);
819 }
820 
822 {
823  const char *dev = get_dev_name();
824  int fd;
825 
826  if ((fd = ::open(dev,O_RDWR))<0) {
827  set_err(errno);
828  return false;
829  }
830  set_fd(fd);
831  return true;
832 }
833 
835 {
836  int fd=get_fd();
837  int ids[2];
838  HPT_IOCTL_PARAM param;
839  HPT_CHANNEL_INFO_V2 info;
840  unsigned char* buff[512 + 2 * sizeof(HPT_PASS_THROUGH_HEADER)];
841  PHPT_PASS_THROUGH_HEADER pide_pt_hdr, pide_pt_hdr_out;
842 
843  // get internal deviceid
844  ids[0] = m_hpt_data[0] - 1;
845  ids[1] = m_hpt_data[1] - 1;
846 
847  memset(&param, 0, sizeof(HPT_IOCTL_PARAM));
848 
849  param.magic = HPT_IOCTL_MAGIC;
851  param.in = (unsigned char *)ids;
852  param.in_size = sizeof(unsigned int) * 2;
853  param.out = (unsigned char *)&info;
854  param.out_size = sizeof(HPT_CHANNEL_INFO_V2);
855 
856  if (m_hpt_data[2]==1) {
858  param.out_size = sizeof(HPT_CHANNEL_INFO);
859  }
860  if (ioctl(fd, HPT_DO_IOCONTROL, &param)!=0 ||
861  info.devices[m_hpt_data[2]-1]==0) {
862  return -1;
863  }
864 
865  // perform smart action
866  memset(buff, 0, 512 + 2 * sizeof(HPT_PASS_THROUGH_HEADER));
867  pide_pt_hdr = (PHPT_PASS_THROUGH_HEADER)buff;
868 
869  pide_pt_hdr->lbamid = 0x4f;
870  pide_pt_hdr->lbahigh = 0xc2;
871  pide_pt_hdr->command = ATA_SMART_CMD;
872  pide_pt_hdr->id = info.devices[m_hpt_data[2] - 1];
873 
874  switch (command){
875  case READ_VALUES:
876  pide_pt_hdr->feature=ATA_SMART_READ_VALUES;
877  pide_pt_hdr->protocol=HPT_READ;
878  break;
879  case READ_THRESHOLDS:
880  pide_pt_hdr->feature=ATA_SMART_READ_THRESHOLDS;
881  pide_pt_hdr->protocol=HPT_READ;
882  break;
883  case READ_LOG:
884  pide_pt_hdr->feature=ATA_SMART_READ_LOG_SECTOR;
885  pide_pt_hdr->lbalow=select;
886  pide_pt_hdr->protocol=HPT_READ;
887  break;
888  case IDENTIFY:
889  pide_pt_hdr->command=ATA_IDENTIFY_DEVICE;
890  pide_pt_hdr->protocol=HPT_READ;
891  break;
892  case ENABLE:
893  pide_pt_hdr->feature=ATA_SMART_ENABLE;
894  break;
895  case DISABLE:
896  pide_pt_hdr->feature=ATA_SMART_DISABLE;
897  break;
898  case AUTO_OFFLINE:
899  pide_pt_hdr->feature=ATA_SMART_AUTO_OFFLINE;
900  pide_pt_hdr->sectorcount=select;
901  break;
902  case AUTOSAVE:
903  pide_pt_hdr->feature=ATA_SMART_AUTOSAVE;
904  pide_pt_hdr->sectorcount=select;
905  break;
906  case IMMEDIATE_OFFLINE:
907  pide_pt_hdr->feature=ATA_SMART_IMMEDIATE_OFFLINE;
908  pide_pt_hdr->lbalow=select;
909  break;
910  case STATUS_CHECK:
911  case STATUS:
912  pide_pt_hdr->feature=ATA_SMART_STATUS;
913  break;
914  case CHECK_POWER_MODE:
915  pide_pt_hdr->command=ATA_CHECK_POWER_MODE;
916  break;
917  case WRITE_LOG:
918  memcpy(buff+sizeof(HPT_PASS_THROUGH_HEADER), data, 512);
919  pide_pt_hdr->feature=ATA_SMART_WRITE_LOG_SECTOR;
920  pide_pt_hdr->lbalow=select;
921  pide_pt_hdr->protocol=HPT_WRITE;
922  break;
923  default:
924  pout("Unrecognized command %d in highpoint_command_interface()\n"
925  "Please contact " PACKAGE_BUGREPORT "\n", command);
926  errno=ENOSYS;
927  return -1;
928  }
929  if (pide_pt_hdr->protocol!=0) {
930  pide_pt_hdr->sectors = 1;
931  pide_pt_hdr->sectorcount = 1;
932  }
933 
934  memset(&param, 0, sizeof(HPT_IOCTL_PARAM));
935 
936  param.magic = HPT_IOCTL_MAGIC;
938  param.in = (unsigned char *)buff;
939  param.in_size = sizeof(HPT_PASS_THROUGH_HEADER) + (pide_pt_hdr->protocol==HPT_READ ? 0 : pide_pt_hdr->sectors * 512);
940  param.out = (unsigned char *)buff+param.in_size;
941  param.out_size = sizeof(HPT_PASS_THROUGH_HEADER) + (pide_pt_hdr->protocol==HPT_READ ? pide_pt_hdr->sectors * 512 : 0);
942 
943  pide_pt_hdr_out = (PHPT_PASS_THROUGH_HEADER)param.out;
944 
945  if ((ioctl(fd, HPT_DO_IOCONTROL, &param)!=0) ||
946  (pide_pt_hdr_out->command & 1)) {
947  return -1;
948  }
949 
950  if (command==STATUS_CHECK)
951  {
952  unsigned const char normal_lo=0x4f, normal_hi=0xc2;
953  unsigned const char failed_lo=0xf4, failed_hi=0x2c;
954  unsigned char low,high;
955 
956  high = pide_pt_hdr_out->lbahigh;
957  low = pide_pt_hdr_out->lbamid;
958 
959  // Cyl low and Cyl high unchanged means "Good SMART status"
960  if (low==normal_lo && high==normal_hi)
961  return 0;
962 
963  // These values mean "Bad SMART status"
964  if (low==failed_lo && high==failed_hi)
965  return 1;
966 
967  // We haven't gotten output that makes sense; print out some debugging info
968  char buf[512];
969  snprintf(buf, sizeof(buf),
970  "CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
971  (int)pide_pt_hdr_out->command,
972  (int)pide_pt_hdr_out->feature,
973  (int)pide_pt_hdr_out->sectorcount,
974  (int)pide_pt_hdr_out->lbalow,
975  (int)pide_pt_hdr_out->lbamid,
976  (int)pide_pt_hdr_out->lbahigh,
977  (int)pide_pt_hdr_out->sectors);
978  printwarning(BAD_SMART,buf);
979  }
980  else if (command==CHECK_POWER_MODE)
981  data[0] = pide_pt_hdr_out->sectorcount & 0xff;
982  else if (pide_pt_hdr->protocol==HPT_READ)
983  memcpy(data, (unsigned char *)buff + 2 * sizeof(HPT_PASS_THROUGH_HEADER),
984  pide_pt_hdr->sectors * 512);
985  return 0;
986 }
987 
988 
989 /////////////////////////////////////////////////////////////////////////////
990 /// Standard SCSI support
991 
993 : public /*implements*/ scsi_device,
994  public /*extends*/ freebsd_smart_device
995 {
996 public:
997  freebsd_scsi_device(smart_interface * intf, const char * dev_name, const char * req_type);
998 
999  virtual smart_device * autodetect_open();
1000 
1001  virtual bool scsi_pass_through(scsi_cmnd_io * iop);
1002 
1003  virtual bool open();
1004 
1005  virtual bool close();
1006 
1007 private:
1008  struct cam_device *m_camdev;
1009 };
1010 
1012  const char *dev = get_dev_name();
1013 
1014  if ((m_camdev = cam_open_device(dev, O_RDWR)) == NULL) {
1015  set_err(errno);
1016  return false;
1017  }
1018  set_fd(m_camdev->fd);
1019  return true;
1020 }
1021 
1023  cam_close_device(m_camdev);
1024  set_fd(-1);
1025  return true;
1026 }
1027 
1029  const char * dev_name, const char * req_type)
1030 : smart_device(intf, dev_name, "scsi", req_type),
1032  m_camdev(0)
1033 {
1034 }
1035 
1036 
1038 {
1039  union ccb *ccb;
1040 
1041  if (scsi_debugmode) {
1042  unsigned int k;
1043  const unsigned char * ucp = iop->cmnd;
1044  const char * np;
1045 
1046  np = scsi_get_opcode_name(ucp[0]);
1047  pout(" [%s: ", np ? np : "<unknown opcode>");
1048  for (k = 0; k < iop->cmnd_len; ++k)
1049  pout("%02x ", ucp[k]);
1050  if ((scsi_debugmode > 1) &&
1051  (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
1052  int trunc = (iop->dxfer_len > 256) ? 1 : 0;
1053 
1054  pout("]\n Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
1055  (trunc ? " [only first 256 bytes shown]" : ""));
1056  dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
1057  }
1058  else
1059  pout("]\n");
1060  }
1061 
1062  if(m_camdev==NULL) {
1063  if (scsi_debugmode)
1064  pout(" error: camdev=0!\n");
1065  return set_err(ENOTTY);
1066  }
1067 
1068  if (!(ccb = cam_getccb(m_camdev))) {
1069  if (scsi_debugmode)
1070  pout(" error allocating ccb\n");
1071  return set_err(ENOMEM);
1072  }
1073 
1074  // mfi SAT layer is known to be buggy
1075  if(!strcmp("mfi",m_camdev->sim_name)) {
1076  if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) {
1077  // Controller does not return ATA output registers in SAT sense data
1078  if (iop->cmnd[2] & (1 << 5)) // chk_cond
1079  return set_err(ENOSYS, "ATA return descriptor not supported by controller firmware");
1080  }
1081  // SMART WRITE LOG SECTOR causing media errors
1082  if ((iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16
1083  && iop->cmnd[14] == ATA_SMART_CMD && iop->cmnd[3]==0 &&
1084  iop->cmnd[4] == ATA_SMART_WRITE_LOG_SECTOR) ||
1085  (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12
1086  && iop->cmnd[9] == ATA_SMART_CMD && iop->cmnd[3] == ATA_SMART_WRITE_LOG_SECTOR))
1087  {
1089  return set_err(ENOSYS, "SMART WRITE LOG SECTOR may cause problems, try with -T permissive to force");
1090  }
1091  }
1092  // clear out structure, except for header that was filled in for us
1093  bzero(&(&ccb->ccb_h)[1],
1094  sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
1095 
1096  cam_fill_csio(&ccb->csio,
1097  /* retries */ 1,
1098  /* cbfcnp */ NULL,
1099  /* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),
1100  /* tagaction */ MSG_SIMPLE_Q_TAG,
1101  /* dataptr */ iop->dxferp,
1102  /* datalen */ iop->dxfer_len,
1103  /* senselen */ iop->max_sense_len,
1104  /* cdblen */ iop->cmnd_len,
1105  /* timout (converted to seconds) */ iop->timeout*1000);
1106  memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
1107 
1108  if (cam_send_ccb(m_camdev,ccb) < 0) {
1109  if (scsi_debugmode) {
1110  pout(" error sending SCSI ccb\n");
1111  cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
1112  }
1113  cam_freeccb(ccb);
1114  return set_err(EIO);
1115  }
1116 
1117  if (scsi_debugmode) {
1118  pout(" CAM status=0x%x, SCSI status=0x%x, resid=0x%x\n",
1119  ccb->ccb_h.status, ccb->csio.scsi_status, ccb->csio.resid);
1120  if ((scsi_debugmode > 1) && (DXFER_FROM_DEVICE == iop->dxfer_dir)) {
1121  int trunc, len;
1122 
1123  len = iop->dxfer_len - ccb->csio.resid;
1124  trunc = (len > 256) ? 1 : 0;
1125  if (len > 0) {
1126  pout(" Incoming data, len=%d%s:\n", len,
1127  (trunc ? " [only first 256 bytes shown]" : ""));
1128  dStrHex(iop->dxferp, (trunc ? 256 : len), 1);
1129  }
1130  else
1131  pout(" Incoming data trimmed to nothing by resid\n");
1132  }
1133  }
1134 
1135  if (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR)) {
1136  if (scsi_debugmode)
1137  cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
1138  cam_freeccb(ccb);
1139  return set_err(EIO);
1140  }
1141 
1142  iop->resid = ccb->csio.resid;
1143  iop->scsi_status = ccb->csio.scsi_status;
1144  if (iop->sensep && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0) {
1145  if (scsi_debugmode)
1146  pout(" sense_len=0x%x, sense_resid=0x%x\n",
1147  ccb->csio.sense_len, ccb->csio.sense_resid);
1148  iop->resp_sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
1149  /* Some SCSI controller device drivers miscalculate the sense_resid
1150  field so cap resp_sense_len on max_sense_len. */
1151  if (iop->resp_sense_len > iop->max_sense_len)
1152  iop->resp_sense_len = iop->max_sense_len;
1153  if (iop->resp_sense_len > 0) {
1154  memcpy(iop->sensep, &(ccb->csio.sense_data), iop->resp_sense_len);
1155  if (scsi_debugmode) {
1156  if (scsi_debugmode > 1) {
1157  pout(" >>> Sense buffer, len=%zu:\n", iop->resp_sense_len);
1158  dStrHex(iop->sensep, iop->resp_sense_len, 1);
1159  }
1160  if ((iop->sensep[0] & 0x7f) > 0x71)
1161  pout(" status=0x%x: [desc] sense_key=0x%x asc=0x%x ascq=0x%x\n",
1162  iop->scsi_status, iop->sensep[1] & 0xf,
1163  iop->sensep[2], iop->sensep[3]);
1164  else
1165  pout(" status=0x%x: sense_key=0x%x asc=0x%x ascq=0x%x\n",
1166  iop->scsi_status, iop->sensep[2] & 0xf,
1167  iop->sensep[12], iop->sensep[13]);
1168  }
1169  }
1170  else if (scsi_debugmode)
1171  pout(" status=0x%x\n", iop->scsi_status);
1172  }
1173  else if (scsi_debugmode)
1174  pout(" status=0x%x\n", iop->scsi_status);
1175 
1176  cam_freeccb(ccb);
1177 
1178  // mfip replacing PDT of the device so response does not make a sense
1179  // this sets PDT to 00h - direct-access block device
1180  if((!strcmp("mfi", m_camdev->sim_name) || !strcmp("mpt", m_camdev->sim_name))
1181  && iop->cmnd[0] == INQUIRY) {
1182  if (scsi_debugmode) {
1183  pout(" device on %s controller, patching PDT\n", m_camdev->sim_name);
1184  }
1185  iop->dxferp[0] = iop->dxferp[0] & 0xe0;
1186  }
1187 
1188  return true;
1189 }
1190 
1191 
1192 /////////////////////////////////////////////////////////////////////////////
1193 /// Areca RAID support
1194 
1195 ///////////////////////////////////////////////////////////////////
1196 // SATA(ATA) device behind Areca RAID Controller
1198 : public /*implements*/ areca_ata_device,
1199  public /*extends*/ freebsd_smart_device
1200 {
1201 public:
1202  freebsd_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
1203  virtual smart_device * autodetect_open();
1204  virtual bool arcmsr_lock();
1205  virtual bool arcmsr_unlock();
1206  virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop);
1207 };
1208 
1209 ///////////////////////////////////////////////////////////////////
1210 // SAS(SCSI) device behind Areca RAID Controller
1212 : public /*implements*/ areca_scsi_device,
1213  public /*extends*/ freebsd_smart_device
1214 {
1215 public:
1216  freebsd_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
1217  virtual smart_device * autodetect_open();
1218  virtual bool arcmsr_lock();
1219  virtual bool arcmsr_unlock();
1220  virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop);
1221 };
1222 
1223 
1224 // Areca RAID Controller(SATA Disk)
1225 freebsd_areca_ata_device::freebsd_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
1226 : smart_device(intf, dev_name, "areca", "areca"),
1228 {
1229  set_disknum(disknum);
1230  set_encnum(encnum);
1231  set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
1232 }
1233 
1234 
1236 {
1237  // autodetect device type
1238  int is_ata = arcmsr_get_dev_type();
1239  if(is_ata < 0)
1240  {
1241  set_err(EIO);
1242  return this;
1243  }
1244 
1245  if(is_ata == 1)
1246  {
1247  // SATA device
1248  return this;
1249  }
1250 
1251  // SAS device
1253  close();
1254  delete this;
1255  newdev->open(); // TODO: Can possibly pass open fd
1256 
1257  return newdev.release();
1258 }
1259 
1261 {
1262  int ioctlreturn = 0;
1263 
1264  if(!is_open()) {
1265  if(!open()){
1266  }
1267  }
1268 
1269  ioctlreturn = ioctl(get_fd(), ((sSRB_BUFFER *)(iop->dxferp))->srbioctl.ControlCode, iop->dxferp);
1270  if (ioctlreturn)
1271  {
1272  // errors found
1273  return -1;
1274  }
1275 
1276  return ioctlreturn;
1277 }
1278 
1280 {
1281  return true;
1282 }
1283 
1284 
1286 {
1287  return true;
1288 }
1289 
1290 
1291 // Areca RAID Controller(SAS Device)
1292 freebsd_areca_scsi_device::freebsd_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
1293 : smart_device(intf, dev_name, "areca", "areca"),
1295 {
1296  set_disknum(disknum);
1297  set_encnum(encnum);
1298  set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
1299 }
1300 
1302 {
1303  return this;
1304 }
1305 
1307 {
1308  int ioctlreturn = 0;
1309 
1310  if(!is_open()) {
1311  if(!open()){
1312  }
1313  }
1314  ioctlreturn = ioctl(get_fd(), ((sSRB_BUFFER *)(iop->dxferp))->srbioctl.ControlCode, iop->dxferp);
1315  if (ioctlreturn)
1316  {
1317  // errors found
1318  return -1;
1319  }
1320 
1321  return ioctlreturn;
1322 }
1323 
1325 {
1326  return true;
1327 }
1328 
1329 
1331 {
1332  return true;
1333 }
1334 
1335 
1336 /////////////////////////////////////////////////////////////////////////////
1337 /// Implement CCISS RAID support with old functions
1338 
1340 : public /*implements*/ scsi_device,
1341  public /*extends*/ freebsd_smart_device
1342 {
1343 public:
1344  freebsd_cciss_device(smart_interface * intf, const char * name, unsigned char disknum);
1345 
1346  virtual bool scsi_pass_through(scsi_cmnd_io * iop);
1347  virtual bool open();
1348 
1349 private:
1350  unsigned char m_disknum; ///< Disk number.
1351 };
1352 
1354 {
1355  const char *dev = get_dev_name();
1356  int fd;
1357  if ((fd = ::open(dev,O_RDWR))<0) {
1358  set_err(errno);
1359  return false;
1360  }
1361  set_fd(fd);
1362  return true;
1363 }
1364 
1366  const char * dev_name, unsigned char disknum)
1367 : smart_device(intf, dev_name, "cciss", "cciss"),
1369  m_disknum(disknum)
1370 {
1371  set_info().info_name = strprintf("%s [cciss_disk_%02d]", dev_name, disknum);
1372 }
1373 
1375 {
1376  int status = cciss_io_interface(get_fd(), m_disknum, iop, scsi_debugmode);
1377  if (status < 0)
1378  return set_err(-status);
1379  return true;
1380  // not reached
1381  return true;
1382 }
1383 
1384 
1385 /////////////////////////////////////////////////////////////////////////////
1386 /// SCSI open with autodetection support
1387 
1389 {
1390  // Open device
1391  if (!open())
1392  return this;
1393 
1394  // No Autodetection if device type was specified by user
1395  if (*get_req_type())
1396  return this;
1397 
1398  // The code below is based on smartd.cpp:SCSIFilterKnown()
1399 
1400  // Get INQUIRY
1401  unsigned char req_buff[64] = {0, };
1402  int req_len = 36;
1403  if (scsiStdInquiry(this, req_buff, req_len)) {
1404  // Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices
1405  // watch this spot ... other devices could lock up here
1406  req_len = 64;
1407  if (scsiStdInquiry(this, req_buff, req_len)) {
1408  // device doesn't like INQUIRY commands
1409  close();
1410  set_err(EIO, "INQUIRY failed");
1411  return this;
1412  }
1413  }
1414 
1415  int avail_len = req_buff[4] + 5;
1416  int len = (avail_len < req_len ? avail_len : req_len);
1417  if (len < 36)
1418  return this;
1419 
1420  // Use INQUIRY to detect type
1421 
1422  // 3ware ?
1423  if (!memcmp(req_buff + 8, "3ware", 5) || !memcmp(req_buff + 8, "AMCC", 4) ||
1424  !strcmp("tws",m_camdev->sim_name) || !strcmp("twa",m_camdev->sim_name)) {
1425  close();
1426  set_err(EINVAL, "3ware/LSI controller, please try adding '-d 3ware,N',\n"
1427  "you may need to replace %s with /dev/twaN, /dev/tweN or /dev/twsN", get_dev_name());
1428  return this;
1429  }
1430 
1431  // SAT or USB, skip MFI controllers because of bugs
1432  {
1433  smart_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
1434  if (newdev) {
1435  // NOTE: 'this' is now owned by '*newdev'
1436  if(!strcmp("mfi",m_camdev->sim_name)) {
1437  newdev->close();
1438  newdev->set_err(ENOSYS, "SATA device detected,\n"
1439  "MegaRAID SAT layer is reportedly buggy, use '-d sat' to try anyhow");
1440  }
1441  return newdev;
1442  }
1443  }
1444 
1445  // Nothing special found
1446  return this;
1447 }
1448 
1449 
1450 /////////////////////////////////////////////////////////////////////////////
1451 /// Implement platform interface with old functions.
1452 
1454 : public /*implements*/ smart_interface
1455 {
1456 public:
1457  virtual std::string get_os_version_str();
1458 
1459  virtual std::string get_app_examples(const char * appname);
1460 
1461  virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
1462  const char * pattern = 0);
1463 
1464 protected:
1465  virtual ata_device * get_ata_device(const char * name, const char * type);
1466 
1467 #if FREEBSDVER > 800100
1468  virtual ata_device * get_atacam_device(const char * name, const char * type);
1469 #endif
1470 
1471  virtual scsi_device * get_scsi_device(const char * name, const char * type);
1472 
1473  virtual nvme_device * get_nvme_device(const char * name, const char * type,
1474  unsigned nsid);
1475 
1476  virtual smart_device * autodetect_smart_device(const char * name);
1477 
1478  virtual smart_device * get_custom_smart_device(const char * name, const char * type);
1479 
1480  virtual std::string get_valid_custom_dev_types_str();
1481 };
1482 
1483 
1484 //////////////////////////////////////////////////////////////////////
1485 
1487 {
1488  struct utsname osname;
1489  uname(&osname);
1490  return strprintf("%s %s %s", osname.sysname, osname.release, osname.machine);
1491 }
1492 
1493 std::string freebsd_smart_interface::get_app_examples(const char * appname)
1494 {
1495  if (!strcmp(appname, "smartctl"))
1496  return smartctl_examples;
1497  return "";
1498 }
1499 
1500 ata_device * freebsd_smart_interface::get_ata_device(const char * name, const char * type)
1501 {
1502  return new freebsd_ata_device(this, name, type);
1503 }
1504 
1505 #if FREEBSDVER > 800100
1506 ata_device * freebsd_smart_interface::get_atacam_device(const char * name, const char * type)
1507 {
1508  return new freebsd_atacam_device(this, name, type);
1509 }
1510 #endif
1511 
1512 scsi_device * freebsd_smart_interface::get_scsi_device(const char * name, const char * type)
1513 {
1514  return new freebsd_scsi_device(this, name, type);
1515 }
1516 
1517 nvme_device * freebsd_smart_interface::get_nvme_device(const char * name, const char * type,
1518  unsigned nsid)
1519 {
1520  return new freebsd_nvme_device(this, name, type, nsid);
1521 }
1522 
1523 // we are using CAM subsystem XPT enumerator to found all CAM (scsi/usb/ada/...)
1524 // devices on system despite of it's names
1525 //
1526 // If any errors occur, leave errno set as it was returned by the
1527 // system call, and return <0.
1528 //
1529 // arguments:
1530 // names: resulting array
1531 // show_all - export duplicate device name or not
1532 //
1533 // Return values:
1534 // -1: error
1535 // >=0: number of discovered devices
1536 
1537 bool get_dev_names_cam(std::vector<std::string> & names, bool show_all)
1538 {
1539  int fd;
1540  if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
1541  if (errno == ENOENT) /* There are no CAM device on this computer */
1542  return 0;
1543  int serrno = errno;
1544  pout("%s control device couldn't opened: %s\n", XPT_DEVICE, strerror(errno));
1545  errno = serrno;
1546  return false;
1547  }
1548 
1549  union ccb ccb;
1550  bzero(&ccb, sizeof(union ccb));
1551 
1552  ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
1553  ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1554  ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1555 
1556  ccb.ccb_h.func_code = XPT_DEV_MATCH;
1557  int bufsize = sizeof(struct dev_match_result) * MAX_NUM_DEV;
1558  ccb.cdm.match_buf_len = bufsize;
1559  // TODO: Use local buffer instead of malloc() if possible
1560  ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
1561  bzero(ccb.cdm.matches,bufsize); // clear ccb.cdm.matches structure
1562 
1563  if (ccb.cdm.matches == NULL) {
1564  close(fd);
1565  throw std::bad_alloc();
1566  }
1567  ccb.cdm.num_matches = 0;
1568  ccb.cdm.num_patterns = 0;
1569  ccb.cdm.pattern_buf_len = 0;
1570 
1571  /*
1572  * We do the ioctl multiple times if necessary, in case there are
1573  * more than MAX_NUM_DEV nodes in the EDT.
1574  */
1575  int skip_device = 0, skip_bus = 0, changed = 0; // TODO: bool
1576  std::string devname;
1577  do {
1578  if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
1579  int serrno = errno;
1580  pout("error sending CAMIOCOMMAND ioctl: %s\n", strerror(errno));
1581  free(ccb.cdm.matches);
1582  close(fd);
1583  errno = serrno;
1584  return false;
1585  }
1586 
1587  if ((ccb.ccb_h.status != CAM_REQ_CMP)
1588  || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
1589  && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
1590  pout("got CAM error %#x, CDM error %d\n", ccb.ccb_h.status, ccb.cdm.status);
1591  free(ccb.cdm.matches);
1592  close(fd);
1593  errno = ENXIO;
1594  return false;
1595  }
1596 
1597  for (unsigned i = 0; i < ccb.cdm.num_matches; i++) {
1598  struct device_match_result *dev_result;
1599  struct periph_match_result *periph_result;
1600 
1601  if (ccb.cdm.matches[i].type == DEV_MATCH_BUS) {
1602  struct bus_match_result *bus_result;
1603 
1604  bus_result = &ccb.cdm.matches[i].result.bus_result;
1605 
1606  if (strcmp(bus_result->dev_name,"xpt") == 0) /* skip XPT bus at all */
1607  skip_bus = 1;
1608  else
1609  skip_bus = 0;
1610  changed = 1;
1611  } else if (ccb.cdm.matches[i].type == DEV_MATCH_DEVICE) {
1612  dev_result = &ccb.cdm.matches[i].result.device_result;
1613 
1614  if (dev_result->flags & DEV_RESULT_UNCONFIGURED || skip_bus == 1)
1615  skip_device = 1;
1616  else
1617  skip_device = 0;
1618 
1619  // /* Shall we skip non T_DIRECT devices ? */
1620  // if (dev_result->inq_data.device != T_DIRECT)
1621  // skip_device = 1;
1622  changed = 1;
1623  } else if (ccb.cdm.matches[i].type == DEV_MATCH_PERIPH &&
1624  (skip_device == 0 || show_all)) {
1625  /* One device may be populated as many peripherals (pass0 & da0 for example).
1626  * We are searching for best name
1627  */
1628  periph_result = &ccb.cdm.matches[i].result.periph_result;
1629  /* Prefer non-"pass" names */
1630  if (devname.empty() || strncmp(periph_result->periph_name, "pass", 4) != 0) {
1631  devname = strprintf("%s%s%d", _PATH_DEV, periph_result->periph_name, periph_result->unit_number);
1632  }
1633  changed = 0;
1634  };
1635  if ((changed == 1 || show_all) && !devname.empty()) {
1636  names.push_back(devname);
1637  devname.erase();
1638  changed = 0;
1639  };
1640  }
1641 
1642  } while ((ccb.ccb_h.status == CAM_REQ_CMP) && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
1643 
1644  if (!devname.empty())
1645  names.push_back(devname);
1646 
1647  free(ccb.cdm.matches);
1648  close(fd);
1649  return true;
1650 }
1651 
1652 // we are using ATA subsystem enumerator to found all ATA devices on system
1653 // despite of it's names
1654 //
1655 // If any errors occur, leave errno set as it was returned by the
1656 // system call, and return <0.
1657 
1658 // Return values:
1659 // -1: error
1660 // >=0: number of discovered devices
1661 int get_dev_names_ata(char*** names) {
1662  struct ata_ioc_devices devices;
1663  int fd=-1,maxchannel,serrno=-1,n=0;
1664  char **mp = NULL;
1665 
1666  *names=NULL;
1667 
1668  if ((fd = open(ATA_DEVICE, O_RDWR)) < 0) {
1669  if (errno == ENOENT) /* There are no ATA device on this computer */
1670  return 0;
1671  serrno = errno;
1672  pout("%s control device can't be opened: %s\n", ATA_DEVICE, strerror(errno));
1673  n = -1;
1674  goto end;
1675  };
1676 
1677  if (ioctl(fd, IOCATAGMAXCHANNEL, &maxchannel) < 0) {
1678  serrno = errno;
1679  pout("ioctl(IOCATAGMAXCHANNEL) on /dev/ata failed: %s\n", strerror(errno));
1680  n = -1;
1681  goto end;
1682  };
1683 
1684  // allocate space for up to MAX_NUM_DEV number of ATA devices
1685  mp = (char **)calloc(MAX_NUM_DEV, sizeof(char*));
1686  if (mp == NULL) {
1687  serrno=errno;
1688  pout("Out of memory constructing scan device list (on line %d)\n", __LINE__);
1689  n = -1;
1690  goto end;
1691  };
1692 
1693  for (devices.channel = 0; devices.channel < maxchannel && n < MAX_NUM_DEV; devices.channel++) {
1694  int j;
1695 
1696  if (ioctl(fd, IOCATADEVICES, &devices) < 0) {
1697  if (errno == ENXIO)
1698  continue; /* such channel not exist */
1699  pout("ioctl(IOCATADEVICES) on %s channel %d failed: %s\n", ATA_DEVICE, devices.channel, strerror(errno));
1700  n = -1;
1701  goto end;
1702  };
1703  for (j=0;j<=1 && n<MAX_NUM_DEV;j++) {
1704  if (devices.name[j][0] != '\0') {
1705  asprintf(mp+n, "%s%s", _PATH_DEV, devices.name[j]);
1706  if (mp[n] == NULL) {
1707  pout("Out of memory constructing scan ATA device list (on line %d)\n", __LINE__);
1708  n = -1;
1709  goto end;
1710  };
1711  n++;
1712  };
1713  };
1714  };
1715  if (n <= 0)
1716  goto end;
1717  mp = (char **)reallocf(mp,n*(sizeof (char*))); // shrink to correct size
1718  if (mp == NULL) {
1719  serrno=errno;
1720  pout("Out of memory constructing scan device list (on line %d)\n", __LINE__);
1721  n = -1;
1722  goto end;
1723  };
1724 
1725 end:
1726  if (fd>=0)
1727  close(fd);
1728  if (n <= 0) {
1729  free(mp);
1730  mp = NULL;
1731  }
1732 
1733  *names=mp;
1734 
1735  if (serrno>-1)
1736  errno=serrno;
1737  return n;
1738 }
1739 
1740 
1741 
1743  const char * type, const char * pattern /*= 0*/)
1744 {
1745  if (pattern) {
1746  set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
1747  return false;
1748  }
1749 
1750  // Make namelists
1751  char * * atanames = 0; int numata = 0;
1752  if (!type || !strcmp(type, "ata")) {
1753  numata = get_dev_names_ata(&atanames);
1754  if (numata < 0) {
1755  set_err(ENOMEM);
1756  return false;
1757  }
1758  }
1759 
1760  std::vector<std::string> scsinames;
1761  if (!type || !strcmp(type, "scsi")) { // do not export duplicated names
1762  if (!get_dev_names_cam(scsinames, false)) {
1763  set_err(errno);
1764  return false;
1765  }
1766  }
1767 
1768  // Add to devlist
1769  int i;
1770  if (type==NULL)
1771  type="";
1772  for (i = 0; i < numata; i++) {
1773  ata_device * atadev = get_ata_device(atanames[i], type);
1774  if (atadev)
1775  devlist.push_back(atadev);
1776  free(atanames[i]);
1777  }
1778  if(numata) free(atanames);
1779 
1780  for (i = 0; i < (int)scsinames.size(); i++) {
1781  if(!*type) { // try USB autodetection if no type specified
1782  smart_device * smartdev = autodetect_smart_device(scsinames[i].c_str());
1783  if(smartdev)
1784  devlist.push_back(smartdev);
1785  }
1786  else {
1787  scsi_device * scsidev = get_scsi_device(scsinames[i].c_str(), type);
1788  if (scsidev)
1789  devlist.push_back(scsidev);
1790  }
1791  }
1792  return true;
1793 }
1794 
1795 
1796 #if (FREEBSDVER < 800000) // without this build fail on FreeBSD 8
1797 static char done[USB_MAX_DEVICES];
1798 
1799 static int usbdevinfo(int f, int a, int rec, int busno, unsigned short & vendor_id,
1800  unsigned short & product_id, unsigned short & version)
1801 {
1802 
1803  struct usb_device_info di;
1804  int e, p, i;
1805  char devname[256];
1806 
1807  snprintf(devname, sizeof(devname),"umass%d",busno);
1808 
1809  di.udi_addr = a;
1810  e = ioctl(f, USB_DEVICEINFO, &di);
1811  if (e) {
1812  if (errno != ENXIO)
1813  printf("addr %d: I/O error\n", a);
1814  return 0;
1815  }
1816  done[a] = 1;
1817 
1818  // list devices
1819  for (i = 0; i < USB_MAX_DEVNAMES; i++) {
1820  if (di.udi_devnames[i][0]) {
1821  if(strcmp(di.udi_devnames[i],devname)==0) {
1822  // device found!
1823  vendor_id = di.udi_vendorNo;
1824  product_id = di.udi_productNo;
1825  version = di.udi_releaseNo;
1826  return 1;
1827  // FIXME
1828  }
1829  }
1830  }
1831  if (!rec)
1832  return 0;
1833  for (p = 0; p < di.udi_nports; p++) {
1834  int s = di.udi_ports[p];
1835  if (s >= USB_MAX_DEVICES) {
1836  continue;
1837  }
1838  if (s == 0)
1839  printf("addr 0 should never happen!\n");
1840  else {
1841  if(usbdevinfo(f, s, 1, busno, vendor_id, product_id, version)) return 1;
1842  }
1843  }
1844  return 0;
1845 }
1846 #endif
1847 
1848 
1849 static int usbdevlist(int busno,unsigned short & vendor_id,
1850  unsigned short & product_id, unsigned short & version)
1851 {
1852 #if (FREEBSDVER >= 800000) // libusb2 interface
1853  struct libusb20_device *pdev = NULL;
1854  struct libusb20_backend *pbe;
1855  uint32_t matches = 0;
1856  char buf[128]; // do not change!
1857  char devname[128];
1858  uint8_t n;
1859  struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
1860 
1861  pbe = libusb20_be_alloc_default();
1862 
1863  while ((pdev = libusb20_be_device_foreach(pbe, pdev))) {
1864  matches++;
1865 
1866  if (libusb20_dev_open(pdev, 0)) {
1867  warnx("libusb20_dev_open: could not open device");
1868  return 0;
1869  }
1870 
1871  pdesc=libusb20_dev_get_device_desc(pdev);
1872 
1873  snprintf(devname, sizeof(devname),"umass%d:",busno);
1874  for (n = 0; n != 255; n++) {
1875  if (libusb20_dev_get_iface_desc(pdev, n, buf, sizeof(buf)))
1876  break;
1877  if (buf[0] == 0)
1878  continue;
1879  if(strncmp(buf,devname,strlen(devname))==0){
1880  // found!
1881  vendor_id = pdesc->idVendor;
1882  product_id = pdesc->idProduct;
1883  version = pdesc->bcdDevice;
1884  libusb20_dev_close(pdev);
1885  libusb20_be_free(pbe);
1886  return 1;
1887  }
1888  }
1889 
1890  libusb20_dev_close(pdev);
1891  }
1892 
1893  if (matches == 0) {
1894  printf("No device match or lack of permissions.\n");
1895  }
1896 
1897  libusb20_be_free(pbe);
1898 
1899  return false;
1900 #else // freebsd < 8.0 USB stack, ioctl interface
1901 
1902  int i, a, rc;
1903  char buf[50];
1904  int ncont;
1905 
1906  for (ncont = 0, i = 0; i < 10; i++) {
1907  snprintf(buf, sizeof(buf), "%s%d", USBDEV, i);
1908  int f = open(buf, O_RDONLY);
1909  if (f >= 0) {
1910  memset(done, 0, sizeof done);
1911  for (a = 1; a < USB_MAX_DEVICES; a++) {
1912  if (!done[a]) {
1913  rc = usbdevinfo(f, a, 1, busno,vendor_id, product_id, version);
1914  if(rc) return 1;
1915  }
1916 
1917  }
1918  close(f);
1919  } else {
1920  if (errno == ENOENT || errno == ENXIO)
1921  continue;
1922  warn("%s", buf);
1923  }
1924  ncont++;
1925  }
1926  return 0;
1927 #endif
1928 }
1929 
1931 {
1932  unsigned short vendor_id = 0, product_id = 0, version = 0;
1933  struct cam_device *cam_dev;
1934  union ccb ccb;
1935  int bus=-1;
1936  int i;
1937  const char * test_name = name;
1938 
1939  // if dev_name null, or string length zero
1940  if (!name || !*name)
1941  return 0;
1942 
1943  // Dereference symlinks
1944  struct stat st;
1945  std::string pathbuf;
1946  if (!lstat(name, &st) && S_ISLNK(st.st_mode)) {
1947  char * p = realpath(name, (char *)0);
1948  if (p) {
1949  pathbuf = p;
1950  free(p);
1951  test_name = pathbuf.c_str();
1952  }
1953  }
1954 
1955  // check ATA bus
1956  char * * atanames = 0; int numata = 0;
1957  numata = get_dev_names_ata(&atanames);
1958  if (numata > 0) {
1959  // check ATA/ATAPI devices
1960  for (i = 0; i < numata; i++) {
1961  if(!strcmp(atanames[i],test_name)) {
1962  for (int c = i; c < numata; c++) free(atanames[c]);
1963  free(atanames);
1964  return new freebsd_ata_device(this, test_name, "");
1965  }
1966  else free(atanames[i]);
1967  }
1968  if(numata) free(atanames);
1969  }
1970  else {
1971  if (numata < 0)
1972  pout("Unable to get ATA device list\n");
1973  }
1974 
1975  // check CAM
1976  std::vector<std::string> scsinames;
1977  if (!get_dev_names_cam(scsinames, true))
1978  pout("Unable to get CAM device list\n");
1979  else if (!scsinames.empty()) {
1980  // check all devices on CAM bus
1981  for (i = 0; i < (int)scsinames.size(); i++) {
1982  if(strcmp(scsinames[i].c_str(), test_name)==0)
1983  { // our disk device is CAM
1984  if(strncmp(scsinames[i].c_str(), "/dev/pmp", strlen("/dev/pmp")) == 0) {
1985  pout("Skipping port multiplier [%s]\n", scsinames[i].c_str());
1986  set_err(EINVAL);
1987  return 0;
1988  }
1989  if ((cam_dev = cam_open_device(test_name, O_RDWR)) == NULL) {
1990  // open failure
1991  set_err(errno);
1992  return 0;
1993  }
1994  // zero the payload
1995  bzero(&(&ccb.ccb_h)[1], PATHINQ_SETTINGS_SIZE);
1996  ccb.ccb_h.func_code = XPT_PATH_INQ; // send PATH_INQ to the device
1997  if (ioctl(cam_dev->fd, CAMIOCOMMAND, &ccb) == -1) {
1998  warn("Get Transfer Settings CCB failed\n"
1999  "%s", strerror(errno));
2000  cam_close_device(cam_dev);
2001  return 0;
2002  }
2003  // now check if we are working with USB device, see umass.c
2004  if(strcmp(ccb.cpi.dev_name,"umass-sim") == 0) { // USB device found
2005  usbdevlist(bus,vendor_id, product_id, version);
2006  int bus=ccb.cpi.unit_number; // unit_number will match umass number
2007  cam_close_device(cam_dev);
2008  if(usbdevlist(bus,vendor_id, product_id, version)){
2009  const char * usbtype = get_usb_dev_type_by_id(vendor_id, product_id, version);
2010  if (usbtype)
2011  return get_sat_device(usbtype, new freebsd_scsi_device(this, test_name, ""));
2012  }
2013  return 0;
2014  }
2015 #if FREEBSDVER > 800100
2016  // check if we have ATA device connected to CAM (ada)
2017  if(ccb.cpi.protocol == PROTO_ATA){
2018  cam_close_device(cam_dev);
2019  return new freebsd_atacam_device(this, test_name, "");
2020  }
2021 #endif
2022  // close cam device, we don`t need it anymore
2023  cam_close_device(cam_dev);
2024  // handle as usual scsi
2025  return new freebsd_scsi_device(this, test_name, "");
2026  }
2027  }
2028  }
2029  // device is LSI raid supported by mfi driver
2030  if(!strncmp("/dev/mfid", test_name, strlen("/dev/mfid")))
2031  set_err(EINVAL, "To monitor disks on LSI RAID load mfip.ko module and run 'smartctl -a /dev/passX' to show SMART information");
2032 
2033  // form /dev/nvme* or nvme*
2034  if(!strncmp("/dev/nvme", test_name, strlen("/dev/nvme")))
2035  return new freebsd_nvme_device(this, name, "", 0 /* use default nsid */);
2036 
2037  // device type unknown
2038  return 0;
2039 }
2040 
2041 
2043 {
2044  int disknum = -1, n1 = -1, n2 = -1;
2045 
2046  if (sscanf(type, "3ware,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
2047  // 3Ware ?
2048  static const char * fbsd_dev_twe_ctrl = "/dev/twe";
2049  static const char * fbsd_dev_twa_ctrl = "/dev/twa";
2050  static const char * fbsd_dev_tws_ctrl = "/dev/tws";
2051  int contr = -1;
2052 
2053  if (n2 != (int)strlen(type)) {
2054  set_err(EINVAL, "Option -d 3ware,N requires N to be a non-negative integer");
2055  return 0;
2056  }
2057  if (!(0 <= disknum && disknum <= 127)) {
2058  set_err(EINVAL, "Option -d 3ware,N (N=%d) must have 0 <= N <= 127", disknum);
2059  return 0;
2060  }
2061 
2062  // guess 3ware device type based on device name
2063  if (str_starts_with(name, fbsd_dev_twa_ctrl) ||
2064  str_starts_with(name, fbsd_dev_tws_ctrl) ) {
2066  }
2067  if (!strncmp(fbsd_dev_twe_ctrl, name, strlen(fbsd_dev_twe_ctrl))){
2069  }
2070 
2071  if(contr == -1){
2072  set_err(EINVAL, "3ware controller type unknown, use %sX, %sX or %sX devices",
2073  fbsd_dev_twe_ctrl, fbsd_dev_twa_ctrl, fbsd_dev_tws_ctrl);
2074  return 0;
2075  }
2076  return new freebsd_escalade_device(this, name, contr, disknum);
2077  }
2078 
2079  // Highpoint ?
2080  int controller = -1, channel = -1; disknum = 1;
2081  n1 = n2 = -1; int n3 = -1;
2082  if (sscanf(type, "hpt,%n%d/%d%n/%d%n", &n1, &controller, &channel, &n2, &disknum, &n3) >= 2 || n1 == 4) {
2083  int len = strlen(type);
2084  if (!(n2 == len || n3 == len)) {
2085  set_err(EINVAL, "Option '-d hpt,L/M/N' supports 2-3 items");
2086  return 0;
2087  }
2088  if (!(1 <= controller && controller <= 8)) {
2089  set_err(EINVAL, "Option '-d hpt,L/M/N' invalid controller id L supplied");
2090  return 0;
2091  }
2092  if (!(1 <= channel && channel <= 128)) {
2093  set_err(EINVAL, "Option '-d hpt,L/M/N' invalid channel number M supplied");
2094  return 0;
2095  }
2096  if (!(1 <= disknum && disknum <= 15)) {
2097  set_err(EINVAL, "Option '-d hpt,L/M/N' invalid pmport number N supplied");
2098  return 0;
2099  }
2100  return new freebsd_highpoint_device(this, name, controller, channel, disknum);
2101  }
2102 
2103  // CCISS ?
2104  disknum = n1 = n2 = -1;
2105  if (sscanf(type, "cciss,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
2106  if (n2 != (int)strlen(type)) {
2107  set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer");
2108  return 0;
2109  }
2110  if (!(0 <= disknum && disknum <= 127)) {
2111  set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
2112  return 0;
2113  }
2114  return get_sat_device("sat,auto", new freebsd_cciss_device(this, name, disknum));
2115  }
2116 #if FREEBSDVER > 800100
2117  // adaX devices ?
2118  if(!strcmp(type,"atacam"))
2119  return new freebsd_atacam_device(this, name, "");
2120 #endif
2121  // Areca?
2122  disknum = n1 = n2 = -1;
2123  int encnum = 1;
2124  if (sscanf(type, "areca,%n%d/%d%n", &n1, &disknum, &encnum, &n2) >= 1 || n1 == 6) {
2125  if (!(1 <= disknum && disknum <= 128)) {
2126  set_err(EINVAL, "Option -d areca,N/E (N=%d) must have 1 <= N <= 128", disknum);
2127  return 0;
2128  }
2129  if (!(1 <= encnum && encnum <= 8)) {
2130  set_err(EINVAL, "Option -d areca,N/E (E=%d) must have 1 <= E <= 8", encnum);
2131  return 0;
2132  }
2133  return new freebsd_areca_ata_device(this, name, disknum, encnum);
2134  }
2135 
2136  return 0;
2137 }
2138 
2140 {
2141  return "3ware,N, hpt,L/M/N, cciss,N, areca,N/E"
2142 #if FREEBSDVER > 800100
2143  ", atacam"
2144 #endif
2145  ;
2146 }
2147 
2148 } // namespace
2149 
2150 /////////////////////////////////////////////////////////////////////////////
2151 /// Initialize platform interface and register with smi()
2152 
2153 void smart_interface::init()
2154 {
2155  static os_freebsd::freebsd_smart_interface the_interface;
2156  smart_interface::set(&the_interface);
2157 }
bool get_dev_names_cam(std::vector< std::string > &names, bool show_all)
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:100
#define ATA_SMART_WRITE_LOG_SECTOR
Definition: atacmds.h:101
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:812
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:834
union tw_cl_command_packet::@44 command
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:549
#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:1564
freebsd_escalade_device(smart_interface *intf, const char *dev_name, int escalade_type, int disknum)
Definition: os_freebsd.cpp:600
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:498
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:1487
#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:583
#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:104
int m_escalade_type
Type string for escalade_command_interface().
Definition: os_freebsd.cpp:596
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:97
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:821
#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:628
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
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:808
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:795
List of devices for DEVICESCAN.
enum ata_cmd_in::@27 direction
I/O direction.
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
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:1152
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:1133
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:95
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:108
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:96
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:1594
#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:99
#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.
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:490
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:103
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:992
std::string strprintf(const char *fmt,...)
Definition: utility.cpp:745
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:622
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:609
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:105