4 * Home page of code is: http://www.smartmontools.org
6 * Copyright (C) 2003-10 Eduard Martinescu
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)
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/>.
19 #include <sys/types.h>
25 #include <cam/scsi/scsi_message.h>
26 #include <cam/scsi/scsi_pass.h>
27 #if defined(__DragonFly__)
37 #include <sys/utsname.h>
41 // set by /usr/include/sys/ata.h, suppress warning
42 #undef ATA_READ_LOG_EXT
47 #include "os_freebsd.h"
49 #include "dev_interface.h"
50 #include "dev_ata_cmd_set.h"
51 #include "dev_areca.h"
53 #define USBDEV "/dev/usb"
54 #if defined(__FreeBSD_version)
56 // This way we define one variable for the GNU/kFreeBSD and FreeBSD
57 #define FREEBSDVER __FreeBSD_version
59 #define FREEBSDVER __FreeBSD_kernel_version
62 #if (FREEBSDVER >= 800000)
63 #include <libusb20_desc.h>
65 #elif defined(__DragonFly__)
66 #include <bus/usb/usb.h>
67 #include <bus/usb/usbhid.h>
69 #include <dev/usb/usb.h>
70 #include <dev/usb/usbhid.h>
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
76 #define CONTROLLER_3WARE_9000_CHAR 0x01
77 #define CONTROLLER_3WARE_678K_CHAR 0x02
79 #ifndef PATHINQ_SETTINGS_SIZE
80 #define PATHINQ_SETTINGS_SIZE 128
83 const char *os_XXXX_c_cvsid
="$Id: os_freebsd.cpp 4257 2016-03-27 23:32:54Z samm2 $" \
84 ATACMDS_H_CVSID CCISS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID
;
88 #define NO_DISK_3WARE 2
92 // Utility function for printing warnings
93 void printwarning(int msgNo
, const char* extra
) {
95 if (msgNo
>= 0 && msgNo
<= MAX_MSG
) {
96 static int printed
[] = {0,0,0,0};
97 if (!printed
[msgNo
]) {
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",
102 "Error SMART Status command failed\nPlease get assistance from \n" PACKAGE_HOMEPAGE
"\nRegister values returned from SMART Status command are:\n",
104 "You must specify a DISK # for 3ware drives with -d 3ware,<n> where <n> begins with 1 for first disk drive\n",
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"
110 pout("%s", message
[msgNo
]);
118 // Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
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) )
125 #define ATA_DEVICE "/dev/ata"
128 #define ARGUSED(x) ((void)(x))
130 extern unsigned char failuretest_permissive
;
132 /////////////////////////////////////////////////////////////////////////////
134 namespace os_freebsd
{ // No need to publish anything, name provided for Doxygen
136 /////////////////////////////////////////////////////////////////////////////
137 /// Implement shared open/close routines with old functions.
139 class freebsd_smart_device
140 : virtual public /*implements*/ smart_device
143 explicit freebsd_smart_device()
144 : smart_device(never_called
),
147 virtual ~freebsd_smart_device() throw();
149 virtual bool is_open() const;
153 virtual bool close();
156 /// Return filedesc for derived classes.
164 int m_fd
; ///< filedesc, -1 if not open.
168 static inline void * reallocf(void *ptr
, size_t size
) {
169 void *rv
= realloc(ptr
, size
);
170 if((rv
== NULL
) && (size
!= 0))
176 freebsd_smart_device::~freebsd_smart_device() throw()
179 os_freebsd::freebsd_smart_device::close();
182 // migration from the old_style
183 unsigned char m_controller_type
;
184 unsigned char m_controller_port
;
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"
210 bool freebsd_smart_device::is_open() const
216 bool freebsd_smart_device::open()
218 const char *dev
= get_dev_name();
219 if ((m_fd
= ::open(dev
,O_RDONLY
))<0) {
226 bool freebsd_smart_device::close()
229 // close device, if open
231 failed
=::close(get_fd());
235 if(failed
) return false;
239 /////////////////////////////////////////////////////////////////////////////
240 /// Implement standard ATA support
242 class freebsd_ata_device
243 : public /*implements*/ ata_device
,
244 public /*extends*/ freebsd_smart_device
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
);
251 virtual int do_cmd(struct ata_ioc_request
* request
, bool is_48bit_cmd
);
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
),
256 freebsd_smart_device()
260 int freebsd_ata_device::do_cmd( struct ata_ioc_request
* request
, bool is_48bit_cmd
)
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
);
271 bool freebsd_ata_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
273 bool ata_48bit
= false; // no ata_48bit_support via IOCATAREQUEST
274 if(!strcmp("atacam",get_dev_type())) // enable for atacam interface
277 if (!ata_cmd_is_ok(in
,
278 true, // data_out_support
279 true, // multi_sector_support
282 set_err(ENOSYS
, "48-bit ATA commands not implemented for legacy controllers");
286 struct ata_ioc_request request
;
287 bzero(&request
,sizeof(struct ata_ioc_request
));
289 request
.timeout
=SCSI_TIMEOUT_DEFAULT
;
290 request
.u
.ata
.command
=in
.in_regs
.command
;
291 request
.u
.ata
.feature
=in
.in_regs
.features
;
293 request
.u
.ata
.count
= in
.in_regs
.sector_count_16
;
294 request
.u
.ata
.lba
= in
.in_regs
.lba_48
;
296 switch (in
.direction
) {
297 case ata_cmd_in::no_data
:
298 request
.flags
=ATA_CMD_CONTROL
;
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
;
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
;
311 return set_err(ENOSYS
);
316 if (do_cmd(&request
, in
.in_regs
.is_48bit_cmd()))
319 return set_err(EIO
, "request failed, error code 0x%02x", request
.error
);
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
;
326 // Command specific processing
327 if (in
.in_regs
.command
== ATA_SMART_CMD
328 && in
.in_regs
.features
== ATA_SMART_STATUS
329 && in
.out_needed
.lba_high
)
331 unsigned const char normal_lo
=0x4f, normal_hi
=0xc2;
332 unsigned const char failed_lo
=0xf4, failed_hi
=0x2c;
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
))
340 // We haven't gotten output that makes sense; print out some debugging info
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),
351 printwarning(BAD_SMART
,buf
);
352 out
.out_regs
.lba_high
= failed_hi
;
353 out
.out_regs
.lba_mid
= failed_lo
;
360 #if FREEBSDVER > 800100
361 class freebsd_atacam_device
: public freebsd_ata_device
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
)
369 virtual bool close();
373 struct cam_device
*m_camdev
;
375 virtual int do_cmd( struct ata_ioc_request
* request
, bool is_48bit_cmd
);
378 bool freebsd_atacam_device::open(){
379 const char *dev
= get_dev_name();
381 if ((m_camdev
= cam_open_device(dev
, O_RDWR
)) == NULL
) {
385 set_fd(m_camdev
->fd
);
389 bool freebsd_atacam_device::close(){
390 cam_close_device(m_camdev
);
395 int freebsd_atacam_device::do_cmd( struct ata_ioc_request
* request
, bool is_48bit_cmd
)
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");
410 memset(&ccb
, 0, sizeof(ccb
));
412 if (request
->count
== 0)
413 camflags
= CAM_DIR_NONE
;
414 else if (request
->flags
& ATA_CMD_READ
)
415 camflags
= CAM_DIR_IN
;
417 camflags
= CAM_DIR_OUT
;
419 cam_fill_ataio(&ccb
.ataio
,
424 (u_int8_t
*)request
->data
,
426 request
->timeout
* 1000); // timeout in seconds
428 ccb
.ataio
.cmd
.flags
= CAM_ATAIO_NEEDRESULT
|
429 (is_48bit_cmd
? CAM_ATAIO_48BIT
: 0);
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;
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;;
444 ccb
.ccb_h
.flags
|= CAM_DEV_QFRZDIS
;
446 if (cam_send_ccb(m_camdev
, &ccb
) < 0) {
447 set_err(EIO
, "cam_send_ccb failed");
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
);
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);
466 request
->u
.ata
.count
= ccb
.ataio
.res
.sector_count
| (ccb
.ataio
.res
.sector_count_exp
<< 8);
467 request
->error
= ccb
.ataio
.res
.error
;
474 /////////////////////////////////////////////////////////////////////////////
477 class freebsd_nvme_device
478 : public /*implements*/ nvme_device
,
479 public /*extends*/ freebsd_smart_device
482 freebsd_nvme_device(smart_interface
* intf
, const char * dev_name
,
483 const char * req_type
, unsigned nsid
);
487 virtual bool nvme_pass_through(const nvme_cmd_in
& in
, nvme_cmd_out
& out
);
490 freebsd_nvme_device::freebsd_nvme_device(smart_interface
* intf
, const char * dev_name
,
491 const char * req_type
, unsigned nsid
)
492 : smart_device(intf
, dev_name
, "nvme", req_type
),
494 freebsd_smart_device()
498 bool freebsd_nvme_device::open()
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'",
507 int nsid
= -1, ctrlid
= -1;
510 if(sscanf(dev
, NVME_CTRLR_PREFIX
"%d%c", &ctrlid
, &tmp
) == 1)
513 set_err(EINVAL
, "Invalid NVMe controller number");
516 nsid
= 0xFFFFFFFF; // broadcast id
518 else if (sscanf(dev
, NVME_CTRLR_PREFIX
"%d"NVME_NS_PREFIX
"%d%c",
519 &ctrlid
, &nsid
, &tmp
) == 2)
521 if(ctrlid
< 0 || nsid
< 0) {
522 set_err(EINVAL
, "Invalid NVMe controller/namespace number");
527 set_err(EINVAL
, "Invalid NVMe controller/namespace syntax");
531 // we should always open controller, not namespace device
533 snprintf(full_path
, sizeof(full_path
), NVME_CTRLR_PREFIX
"%d", ctrlid
);
536 if ((fd
= ::open(full_path
, O_RDWR
))<0) {
549 bool freebsd_nvme_device::nvme_pass_through(const nvme_cmd_in
& in
, nvme_cmd_out
& out
)
551 // nvme_passthru_cmd pt;
552 struct nvme_pt_command pt
;
553 memset(&pt
, 0, sizeof(pt
));
555 pt
.cmd
.opc
= in
.opcode
;
556 pt
.cmd
.nsid
= in
.nsid
;
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()?
567 int status
= ioctl(get_fd(), NVME_PASSTHROUGH_CMD
, &pt
);
570 return set_err(errno
, "NVME_PASSTHROUGH_CMD: %s", strerror(errno
));
572 out
.result
=pt
.cpl
.cdw0
; // Command specific result (DW0)
574 if (nvme_completion_is_error(&pt
.cpl
))
575 return set_nvme_err(out
, nvme_completion_is_error(&pt
.cpl
));
580 /////////////////////////////////////////////////////////////////////////////
581 /// Implement AMCC/3ware RAID support
583 class freebsd_escalade_device
584 : public /*implements*/ ata_device
,
585 public /*extends*/ freebsd_smart_device
588 freebsd_escalade_device(smart_interface
* intf
, const char * dev_name
,
589 int escalade_type
, int disknum
);
592 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
);
596 int m_escalade_type
; ///< Type string for escalade_command_interface().
597 int m_disknum
; ///< Disk number.
600 freebsd_escalade_device::freebsd_escalade_device(smart_interface
* intf
, const char * dev_name
,
601 int escalade_type
, int disknum
)
602 : smart_device(intf
, dev_name
, "3ware", "3ware"),
603 freebsd_smart_device(),
604 m_escalade_type(escalade_type
), m_disknum(disknum
)
606 set_info().info_name
= strprintf("%s [3ware_disk_%02d]", dev_name
, disknum
);
609 bool freebsd_escalade_device::open()
611 const char *dev
= get_dev_name();
614 if ((fd
= ::open(dev
,O_RDWR
))<0) {
622 bool freebsd_escalade_device::ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
)
624 // to hold true file descriptor
627 if (!ata_cmd_is_ok(in
,
628 true, // data_out_support
629 false, // TODO: multi_sector_support
630 true) // ata_48bit_support
634 struct twe_usercommand
* cmd_twe
= NULL
;
635 TW_OSLI_IOCTL_NO_DATA_BUF
* cmd_twa
= NULL
;
636 TWE_Command_ATA
* ata
= NULL
;
638 // Used by both the SCSI and char interfaces
639 char ioctl_buffer
[TW_IOCTL_BUFFER_SIZE
];
642 printwarning(NO_DISK_3WARE
,NULL
);
646 memset(ioctl_buffer
, 0, TW_IOCTL_BUFFER_SIZE
);
648 if (m_escalade_type
==CONTROLLER_3WARE_9000_CHAR
) {
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
;
654 } else if (m_escalade_type
==CONTROLLER_3WARE_678K_CHAR
) {
655 cmd_twe
= (struct twe_usercommand
*)ioctl_buffer
;
656 ata
= &cmd_twe
->tu_command
.ata
;
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
);
663 ata
->opcode
= TWE_OP_ATA_PASSTHROUGH
;
665 // Same for (almost) all commands - but some reset below
666 ata
->request_id
= 0xFF;
667 ata
->unit
= m_disknum
;
670 ata
->size
= 0x5; // TODO: multisector support
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
;
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
) {
692 if (m_escalade_type
==CONTROLLER_3WARE_678K_CHAR
) {
693 cmd_twe
->tu_data
= in
.buffer
;
694 cmd_twe
->tu_size
= 512;
698 ata
->sgl_offset
= 0x5;
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)
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;
712 ata
->sector_count
= 0x0;
714 else if (in
.direction
== ata_cmd_in::data_out
) {
715 ata
->sgl_offset
= 0x5;
716 ata
->param
= 0xF; // PIO data write
717 if (m_escalade_type
==CONTROLLER_3WARE_678K_CHAR
) {
718 cmd_twe
->tu_data
= in
.buffer
;
719 cmd_twe
->tu_size
= 512;
721 else if (m_escalade_type
==CONTROLLER_3WARE_9000_CHAR
) {
722 memcpy(cmd_twa
->pdata
, in
.buffer
, in
.size
);
726 return set_err(EINVAL
);
728 // 3WARE controller can NOT have packet device internally
729 if (in
.in_regs
.command
== ATA_IDENTIFY_PACKET_DEVICE
) {
730 return set_err(ENODEV
, "No drive on port %d", m_disknum
);
733 // Now send the command down through an ioctl()
735 if (m_escalade_type
==CONTROLLER_3WARE_9000_CHAR
) {
736 ioctlreturn
=ioctl(fd
,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH
,cmd_twa
);
738 ioctlreturn
=ioctl(fd
,TWEIO_COMMAND
,cmd_twe
);
741 // Deal with the different error cases
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
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
758 if (ata
->status
|| (ata
->command
& 0x21)) {
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
);
764 // If this is a read data command, copy data to output buffer
766 if (m_escalade_type
==CONTROLLER_3WARE_9000_CHAR
)
767 memcpy(in
.buffer
, cmd_twa
->pdata
, in
.size
);
768 else if(m_escalade_type
==CONTROLLER_3WARE_678K_CHAR
) {
769 memcpy(in
.buffer
, cmd_twe
->tu_data
, in
.size
); // untested
772 // Return register values
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
;
783 // look for nonexistent devices/ports
784 if (in
.in_regs
.command
== ATA_IDENTIFY_DEVICE
785 && !nonempty((unsigned char *)in
.buffer
, in
.size
)) {
786 return set_err(ENODEV
, "No drive on port %d", m_disknum
);
792 /////////////////////////////////////////////////////////////////////////////
793 /// Implement Highpoint RAID support with old functions
795 class freebsd_highpoint_device
796 : public /*implements*/ ata_device_with_command_set
,
797 public /*extends*/ freebsd_smart_device
800 freebsd_highpoint_device(smart_interface
* intf
, const char * dev_name
,
801 unsigned char controller
, unsigned char channel
, unsigned char port
);
804 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
808 unsigned char m_hpt_data
[3]; ///< controller/channel/port
812 freebsd_highpoint_device::freebsd_highpoint_device(smart_interface
* intf
, const char * dev_name
,
813 unsigned char controller
, unsigned char channel
, unsigned char port
)
814 : smart_device(intf
, dev_name
, "hpt", "hpt"),
815 freebsd_smart_device()
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]);
821 bool freebsd_highpoint_device::open()
823 const char *dev
= get_dev_name();
826 if ((fd
= ::open(dev
,O_RDWR
))<0) {
834 int freebsd_highpoint_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
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
;
843 // get internal deviceid
844 ids
[0] = m_hpt_data
[0] - 1;
845 ids
[1] = m_hpt_data
[1] - 1;
847 memset(¶m
, 0, sizeof(HPT_IOCTL_PARAM
));
849 param
.magic
= HPT_IOCTL_MAGIC
;
850 param
.ctrl_code
= HPT_IOCTL_GET_CHANNEL_INFO_V2
;
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
);
856 if (m_hpt_data
[2]==1) {
857 param
.ctrl_code
= HPT_IOCTL_GET_CHANNEL_INFO
;
858 param
.out_size
= sizeof(HPT_CHANNEL_INFO
);
860 if (ioctl(fd
, HPT_DO_IOCONTROL
, ¶m
)!=0 ||
861 info
.devices
[m_hpt_data
[2]-1]==0) {
865 // perform smart action
866 memset(buff
, 0, 512 + 2 * sizeof(HPT_PASS_THROUGH_HEADER
));
867 pide_pt_hdr
= (PHPT_PASS_THROUGH_HEADER
)buff
;
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];
876 pide_pt_hdr
->feature
=ATA_SMART_READ_VALUES
;
877 pide_pt_hdr
->protocol
=HPT_READ
;
879 case READ_THRESHOLDS
:
880 pide_pt_hdr
->feature
=ATA_SMART_READ_THRESHOLDS
;
881 pide_pt_hdr
->protocol
=HPT_READ
;
884 pide_pt_hdr
->feature
=ATA_SMART_READ_LOG_SECTOR
;
885 pide_pt_hdr
->lbalow
=select
;
886 pide_pt_hdr
->protocol
=HPT_READ
;
889 pide_pt_hdr
->command
=ATA_IDENTIFY_DEVICE
;
890 pide_pt_hdr
->protocol
=HPT_READ
;
893 pide_pt_hdr
->feature
=ATA_SMART_ENABLE
;
896 pide_pt_hdr
->feature
=ATA_SMART_DISABLE
;
899 pide_pt_hdr
->feature
=ATA_SMART_AUTO_OFFLINE
;
900 pide_pt_hdr
->sectorcount
=select
;
903 pide_pt_hdr
->feature
=ATA_SMART_AUTOSAVE
;
904 pide_pt_hdr
->sectorcount
=select
;
906 case IMMEDIATE_OFFLINE
:
907 pide_pt_hdr
->feature
=ATA_SMART_IMMEDIATE_OFFLINE
;
908 pide_pt_hdr
->lbalow
=select
;
912 pide_pt_hdr
->feature
=ATA_SMART_STATUS
;
914 case CHECK_POWER_MODE
:
915 pide_pt_hdr
->command
=ATA_CHECK_POWER_MODE
;
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
;
924 pout("Unrecognized command %d in highpoint_command_interface()\n"
925 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
929 if (pide_pt_hdr
->protocol
!=0) {
930 pide_pt_hdr
->sectors
= 1;
931 pide_pt_hdr
->sectorcount
= 1;
934 memset(¶m
, 0, sizeof(HPT_IOCTL_PARAM
));
936 param
.magic
= HPT_IOCTL_MAGIC
;
937 param
.ctrl_code
= HPT_IOCTL_IDE_PASS_THROUGH
;
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);
943 pide_pt_hdr_out
= (PHPT_PASS_THROUGH_HEADER
)param
.out
;
945 if ((ioctl(fd
, HPT_DO_IOCONTROL
, ¶m
)!=0) ||
946 (pide_pt_hdr_out
->command
& 1)) {
950 if (command
==STATUS_CHECK
)
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
;
956 high
= pide_pt_hdr_out
->lbahigh
;
957 low
= pide_pt_hdr_out
->lbamid
;
959 // Cyl low and Cyl high unchanged means "Good SMART status"
960 if (low
==normal_lo
&& high
==normal_hi
)
963 // These values mean "Bad SMART status"
964 if (low
==failed_lo
&& high
==failed_hi
)
967 // We haven't gotten output that makes sense; print out some debugging info
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
);
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);
989 /////////////////////////////////////////////////////////////////////////////
990 /// Standard SCSI support
992 class freebsd_scsi_device
993 : public /*implements*/ scsi_device
,
994 public /*extends*/ freebsd_smart_device
997 freebsd_scsi_device(smart_interface
* intf
, const char * dev_name
, const char * req_type
);
999 virtual smart_device
* autodetect_open();
1001 virtual bool scsi_pass_through(scsi_cmnd_io
* iop
);
1003 virtual bool open();
1005 virtual bool close();
1008 struct cam_device
*m_camdev
;
1011 bool freebsd_scsi_device::open(){
1012 const char *dev
= get_dev_name();
1014 if ((m_camdev
= cam_open_device(dev
, O_RDWR
)) == NULL
) {
1018 set_fd(m_camdev
->fd
);
1022 bool freebsd_scsi_device::close(){
1023 cam_close_device(m_camdev
);
1028 freebsd_scsi_device::freebsd_scsi_device(smart_interface
* intf
,
1029 const char * dev_name
, const char * req_type
)
1030 : smart_device(intf
, dev_name
, "scsi", req_type
),
1031 freebsd_smart_device(),
1037 bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io
* iop
)
1041 if (scsi_debugmode
) {
1043 const unsigned char * ucp
= iop
->cmnd
;
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;
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);
1062 if(m_camdev
==NULL
) {
1064 pout(" error: camdev=0!\n");
1065 return set_err(ENOTTY
);
1068 if (!(ccb
= cam_getccb(m_camdev
))) {
1070 pout(" error allocating ccb\n");
1071 return set_err(ENOMEM
);
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");
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
))
1088 if(!failuretest_permissive
)
1089 return set_err(ENOSYS
, "SMART WRITE LOG SECTOR may cause problems, try with -T permissive to force");
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
));
1096 cam_fill_csio(&ccb
->csio
,
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
);
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
);
1114 return set_err(EIO
);
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
)) {
1123 len
= iop
->dxfer_len
- ccb
->csio
.resid
;
1124 trunc
= (len
> 256) ? 1 : 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);
1131 pout(" Incoming data trimmed to nothing by resid\n");
1135 if (((ccb
->ccb_h
.status
& CAM_STATUS_MASK
) != CAM_REQ_CMP
) && ((ccb
->ccb_h
.status
& CAM_STATUS_MASK
) != CAM_SCSI_STATUS_ERROR
)) {
1137 cam_error_print(m_camdev
,ccb
,CAM_ESF_ALL
,CAM_EPF_ALL
,stderr
);
1139 return set_err(EIO
);
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) {
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);
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]);
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]);
1170 else if (scsi_debugmode
)
1171 pout(" status=0x%x\n", iop
->scsi_status
);
1173 else if (scsi_debugmode
)
1174 pout(" status=0x%x\n", iop
->scsi_status
);
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
);
1185 iop
->dxferp
[0] = iop
->dxferp
[0] & 0xe0;
1192 /////////////////////////////////////////////////////////////////////////////
1193 /// Areca RAID support
1195 ///////////////////////////////////////////////////////////////////
1196 // SATA(ATA) device behind Areca RAID Controller
1197 class freebsd_areca_ata_device
1198 : public /*implements*/ areca_ata_device
,
1199 public /*extends*/ freebsd_smart_device
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
);
1209 ///////////////////////////////////////////////////////////////////
1210 // SAS(SCSI) device behind Areca RAID Controller
1211 class freebsd_areca_scsi_device
1212 : public /*implements*/ areca_scsi_device
,
1213 public /*extends*/ freebsd_smart_device
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
);
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"),
1227 freebsd_smart_device()
1229 set_disknum(disknum
);
1231 set_info().info_name
= strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name
, disknum
, encnum
);
1235 smart_device
* freebsd_areca_ata_device::autodetect_open()
1237 // autodetect device type
1238 int is_ata
= arcmsr_get_dev_type();
1252 smart_device_auto_ptr
newdev(new freebsd_areca_scsi_device(smi(), get_dev_name(), get_disknum(), get_encnum()));
1255 newdev
->open(); // TODO: Can possibly pass open fd
1257 return newdev
.release();
1260 int freebsd_areca_ata_device::arcmsr_do_scsi_io(struct scsi_cmnd_io
* iop
)
1262 int ioctlreturn
= 0;
1269 ioctlreturn
= ioctl(get_fd(), ((sSRB_BUFFER
*)(iop
->dxferp
))->srbioctl
.ControlCode
, iop
->dxferp
);
1279 bool freebsd_areca_ata_device::arcmsr_lock()
1285 bool freebsd_areca_ata_device::arcmsr_unlock()
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"),
1294 freebsd_smart_device()
1296 set_disknum(disknum
);
1298 set_info().info_name
= strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name
, disknum
, encnum
);
1301 smart_device
* freebsd_areca_scsi_device::autodetect_open()
1306 int freebsd_areca_scsi_device::arcmsr_do_scsi_io(struct scsi_cmnd_io
* iop
)
1308 int ioctlreturn
= 0;
1314 ioctlreturn
= ioctl(get_fd(), ((sSRB_BUFFER
*)(iop
->dxferp
))->srbioctl
.ControlCode
, iop
->dxferp
);
1324 bool freebsd_areca_scsi_device::arcmsr_lock()
1330 bool freebsd_areca_scsi_device::arcmsr_unlock()
1336 /////////////////////////////////////////////////////////////////////////////
1337 /// Implement CCISS RAID support with old functions
1339 class freebsd_cciss_device
1340 : public /*implements*/ scsi_device
,
1341 public /*extends*/ freebsd_smart_device
1344 freebsd_cciss_device(smart_interface
* intf
, const char * name
, unsigned char disknum
);
1346 virtual bool scsi_pass_through(scsi_cmnd_io
* iop
);
1347 virtual bool open();
1350 unsigned char m_disknum
; ///< Disk number.
1353 bool freebsd_cciss_device::open()
1355 const char *dev
= get_dev_name();
1357 if ((fd
= ::open(dev
,O_RDWR
))<0) {
1365 freebsd_cciss_device::freebsd_cciss_device(smart_interface
* intf
,
1366 const char * dev_name
, unsigned char disknum
)
1367 : smart_device(intf
, dev_name
, "cciss", "cciss"),
1368 freebsd_smart_device(),
1371 set_info().info_name
= strprintf("%s [cciss_disk_%02d]", dev_name
, disknum
);
1374 bool freebsd_cciss_device::scsi_pass_through(scsi_cmnd_io
* iop
)
1376 int status
= cciss_io_interface(get_fd(), m_disknum
, iop
, scsi_debugmode
);
1378 return set_err(-status
);
1385 /////////////////////////////////////////////////////////////////////////////
1386 /// SCSI open with autodetection support
1388 smart_device
* freebsd_scsi_device::autodetect_open()
1394 // No Autodetection if device type was specified by user
1395 if (*get_req_type())
1398 // The code below is based on smartd.cpp:SCSIFilterKnown()
1401 unsigned char req_buff
[64] = {0, };
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
1407 if (scsiStdInquiry(this, req_buff
, req_len
)) {
1408 // device doesn't like INQUIRY commands
1410 set_err(EIO
, "INQUIRY failed");
1415 int avail_len
= req_buff
[4] + 5;
1416 int len
= (avail_len
< req_len
? avail_len
: req_len
);
1420 // Use INQUIRY to detect type
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
)) {
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());
1431 // SAT or USB, skip MFI controllers because of bugs
1433 smart_device
* newdev
= smi()->autodetect_sat_device(this, req_buff
, len
);
1435 // NOTE: 'this' is now owned by '*newdev'
1436 if(!strcmp("mfi",m_camdev
->sim_name
)) {
1438 newdev
->set_err(ENOSYS
, "SATA device detected,\n"
1439 "MegaRAID SAT layer is reportedly buggy, use '-d sat' to try anyhow");
1445 // Nothing special found
1450 /////////////////////////////////////////////////////////////////////////////
1451 /// Implement platform interface with old functions.
1453 class freebsd_smart_interface
1454 : public /*implements*/ smart_interface
1457 virtual std::string
get_os_version_str();
1459 virtual std::string
get_app_examples(const char * appname
);
1461 virtual bool scan_smart_devices(smart_device_list
& devlist
, const char * type
,
1462 const char * pattern
= 0);
1465 virtual ata_device
* get_ata_device(const char * name
, const char * type
);
1467 #if FREEBSDVER > 800100
1468 virtual ata_device
* get_atacam_device(const char * name
, const char * type
);
1471 virtual scsi_device
* get_scsi_device(const char * name
, const char * type
);
1473 virtual nvme_device
* get_nvme_device(const char * name
, const char * type
,
1476 virtual smart_device
* autodetect_smart_device(const char * name
);
1478 virtual smart_device
* get_custom_smart_device(const char * name
, const char * type
);
1480 virtual std::string
get_valid_custom_dev_types_str();
1484 //////////////////////////////////////////////////////////////////////
1486 std::string
freebsd_smart_interface::get_os_version_str()
1488 struct utsname osname
;
1490 return strprintf("%s %s %s", osname
.sysname
, osname
.release
, osname
.machine
);
1493 std::string
freebsd_smart_interface::get_app_examples(const char * appname
)
1495 if (!strcmp(appname
, "smartctl"))
1496 return smartctl_examples
;
1500 ata_device
* freebsd_smart_interface::get_ata_device(const char * name
, const char * type
)
1502 return new freebsd_ata_device(this, name
, type
);
1505 #if FREEBSDVER > 800100
1506 ata_device
* freebsd_smart_interface::get_atacam_device(const char * name
, const char * type
)
1508 return new freebsd_atacam_device(this, name
, type
);
1512 scsi_device
* freebsd_smart_interface::get_scsi_device(const char * name
, const char * type
)
1514 return new freebsd_scsi_device(this, name
, type
);
1517 nvme_device
* freebsd_smart_interface::get_nvme_device(const char * name
, const char * type
,
1520 return new freebsd_nvme_device(this, name
, type
, nsid
);
1523 // we are using CAM subsystem XPT enumerator to found all CAM (scsi/usb/ada/...)
1524 // devices on system despite of it's names
1526 // If any errors occur, leave errno set as it was returned by the
1527 // system call, and return <0.
1530 // names: resulting array
1531 // show_all - export duplicate device name or not
1535 // >=0: number of discovered devices
1537 bool get_dev_names_cam(std::vector
<std::string
> & names
, bool show_all
)
1540 if ((fd
= open(XPT_DEVICE
, O_RDWR
)) == -1) {
1541 if (errno
== ENOENT
) /* There are no CAM device on this computer */
1544 pout("%s control device couldn't opened: %s\n", XPT_DEVICE
, strerror(errno
));
1550 bzero(&ccb
, sizeof(union ccb
));
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
;
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
1563 if (ccb
.cdm
.matches
== NULL
) {
1565 throw std::bad_alloc();
1567 ccb
.cdm
.num_matches
= 0;
1568 ccb
.cdm
.num_patterns
= 0;
1569 ccb
.cdm
.pattern_buf_len
= 0;
1572 * We do the ioctl multiple times if necessary, in case there are
1573 * more than MAX_NUM_DEV nodes in the EDT.
1575 int skip_device
= 0, skip_bus
= 0, changed
= 0; // TODO: bool
1576 std::string devname
;
1578 if (ioctl(fd
, CAMIOCOMMAND
, &ccb
) == -1) {
1580 pout("error sending CAMIOCOMMAND ioctl: %s\n", strerror(errno
));
1581 free(ccb
.cdm
.matches
);
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
);
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
;
1601 if (ccb
.cdm
.matches
[i
].type
== DEV_MATCH_BUS
) {
1602 struct bus_match_result
*bus_result
;
1604 bus_result
= &ccb
.cdm
.matches
[i
].result
.bus_result
;
1606 if (strcmp(bus_result
->dev_name
,"xpt") == 0) /* skip XPT bus at all */
1611 } else if (ccb
.cdm
.matches
[i
].type
== DEV_MATCH_DEVICE
) {
1612 dev_result
= &ccb
.cdm
.matches
[i
].result
.device_result
;
1614 if (dev_result
->flags
& DEV_RESULT_UNCONFIGURED
|| skip_bus
== 1)
1619 // /* Shall we skip non T_DIRECT devices ? */
1620 // if (dev_result->inq_data.device != T_DIRECT)
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
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
);
1635 if ((changed
== 1 || show_all
) && !devname
.empty()) {
1636 names
.push_back(devname
);
1642 } while ((ccb
.ccb_h
.status
== CAM_REQ_CMP
) && (ccb
.cdm
.status
== CAM_DEV_MATCH_MORE
));
1644 if (!devname
.empty())
1645 names
.push_back(devname
);
1647 free(ccb
.cdm
.matches
);
1652 // we are using ATA subsystem enumerator to found all ATA devices on system
1653 // despite of it's names
1655 // If any errors occur, leave errno set as it was returned by the
1656 // system call, and return <0.
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;
1668 if ((fd
= open(ATA_DEVICE
, O_RDWR
)) < 0) {
1669 if (errno
== ENOENT
) /* There are no ATA device on this computer */
1672 pout("%s control device can't be opened: %s\n", ATA_DEVICE
, strerror(errno
));
1677 if (ioctl(fd
, IOCATAGMAXCHANNEL
, &maxchannel
) < 0) {
1679 pout("ioctl(IOCATAGMAXCHANNEL) on /dev/ata failed: %s\n", strerror(errno
));
1684 // allocate space for up to MAX_NUM_DEV number of ATA devices
1685 mp
= (char **)calloc(MAX_NUM_DEV
, sizeof(char*));
1688 pout("Out of memory constructing scan device list (on line %d)\n", __LINE__
);
1693 for (devices
.channel
= 0; devices
.channel
< maxchannel
&& n
< MAX_NUM_DEV
; devices
.channel
++) {
1696 if (ioctl(fd
, IOCATADEVICES
, &devices
) < 0) {
1698 continue; /* such channel not exist */
1699 pout("ioctl(IOCATADEVICES) on %s channel %d failed: %s\n", ATA_DEVICE
, devices
.channel
, strerror(errno
));
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__
);
1717 mp
= (char **)reallocf(mp
,n
*(sizeof (char*))); // shrink to correct size
1720 pout("Out of memory constructing scan device list (on line %d)\n", __LINE__
);
1742 bool freebsd_smart_interface::scan_smart_devices(smart_device_list
& devlist
,
1743 const char * type
, const char * pattern
/*= 0*/)
1746 set_err(EINVAL
, "DEVICESCAN with pattern not implemented yet");
1751 char * * atanames
= 0; int numata
= 0;
1752 if (!type
|| !strcmp(type
, "ata")) {
1753 numata
= get_dev_names_ata(&atanames
);
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)) {
1772 for (i
= 0; i
< numata
; i
++) {
1773 ata_device
* atadev
= get_ata_device(atanames
[i
], type
);
1775 devlist
.push_back(atadev
);
1778 if(numata
) free(atanames
);
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());
1784 devlist
.push_back(smartdev
);
1787 scsi_device
* scsidev
= get_scsi_device(scsinames
[i
].c_str(), type
);
1789 devlist
.push_back(scsidev
);
1796 #if (FREEBSDVER < 800000) // without this build fail on FreeBSD 8
1797 static char done
[USB_MAX_DEVICES
];
1799 static int usbdevinfo(int f
, int a
, int rec
, int busno
, unsigned short & vendor_id
,
1800 unsigned short & product_id
, unsigned short & version
)
1803 struct usb_device_info di
;
1807 snprintf(devname
, sizeof(devname
),"umass%d",busno
);
1810 e
= ioctl(f
, USB_DEVICEINFO
, &di
);
1813 printf("addr %d: I/O error\n", a
);
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) {
1823 vendor_id
= di
.udi_vendorNo
;
1824 product_id
= di
.udi_productNo
;
1825 version
= di
.udi_releaseNo
;
1833 for (p
= 0; p
< di
.udi_nports
; p
++) {
1834 int s
= di
.udi_ports
[p
];
1835 if (s
>= USB_MAX_DEVICES
) {
1839 printf("addr 0 should never happen!\n");
1841 if(usbdevinfo(f
, s
, 1, busno
, vendor_id
, product_id
, version
)) return 1;
1849 static int usbdevlist(int busno
,unsigned short & vendor_id
,
1850 unsigned short & product_id
, unsigned short & version
)
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!
1859 struct LIBUSB20_DEVICE_DESC_DECODED
*pdesc
;
1861 pbe
= libusb20_be_alloc_default();
1863 while ((pdev
= libusb20_be_device_foreach(pbe
, pdev
))) {
1866 if (libusb20_dev_open(pdev
, 0)) {
1867 warnx("libusb20_dev_open: could not open device");
1871 pdesc
=libusb20_dev_get_device_desc(pdev
);
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
)))
1879 if(strncmp(buf
,devname
,strlen(devname
))==0){
1881 vendor_id
= pdesc
->idVendor
;
1882 product_id
= pdesc
->idProduct
;
1883 version
= pdesc
->bcdDevice
;
1884 libusb20_dev_close(pdev
);
1885 libusb20_be_free(pbe
);
1890 libusb20_dev_close(pdev
);
1894 printf("No device match or lack of permissions.\n");
1897 libusb20_be_free(pbe
);
1900 #else // freebsd < 8.0 USB stack, ioctl interface
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
);
1910 memset(done
, 0, sizeof done
);
1911 for (a
= 1; a
< USB_MAX_DEVICES
; a
++) {
1913 rc
= usbdevinfo(f
, a
, 1, busno
,vendor_id
, product_id
, version
);
1920 if (errno
== ENOENT
|| errno
== ENXIO
)
1930 smart_device
* freebsd_smart_interface::autodetect_smart_device(const char * name
)
1932 unsigned short vendor_id
= 0, product_id
= 0, version
= 0;
1933 struct cam_device
*cam_dev
;
1937 const char * test_name
= name
;
1939 // if dev_name null, or string length zero
1940 if (!name
|| !*name
)
1943 // Dereference symlinks
1945 std::string pathbuf
;
1946 if (!lstat(name
, &st
) && S_ISLNK(st
.st_mode
)) {
1947 char * p
= realpath(name
, (char *)0);
1951 test_name
= pathbuf
.c_str();
1956 char * * atanames
= 0; int numata
= 0;
1957 numata
= get_dev_names_ata(&atanames
);
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
]);
1964 return new freebsd_ata_device(this, test_name
, "");
1966 else free(atanames
[i
]);
1968 if(numata
) free(atanames
);
1972 pout("Unable to get ATA device list\n");
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());
1989 if ((cam_dev
= cam_open_device(test_name
, O_RDWR
)) == NULL
) {
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
);
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
);
2011 return get_sat_device(usbtype
, new freebsd_scsi_device(this, test_name
, ""));
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
, "");
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
, "");
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");
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 */);
2037 // device type unknown
2042 smart_device
* freebsd_smart_interface::get_custom_smart_device(const char * name
, const char * type
)
2044 int disknum
= -1, n1
= -1, n2
= -1;
2046 if (sscanf(type
, "3ware,%n%d%n", &n1
, &disknum
, &n2
) == 1 || n1
== 6) {
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";
2053 if (n2
!= (int)strlen(type
)) {
2054 set_err(EINVAL
, "Option -d 3ware,N requires N to be a non-negative integer");
2057 if (!(0 <= disknum
&& disknum
<= 127)) {
2058 set_err(EINVAL
, "Option -d 3ware,N (N=%d) must have 0 <= N <= 127", disknum
);
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
) ) {
2065 contr
=CONTROLLER_3WARE_9000_CHAR
;
2067 if (!strncmp(fbsd_dev_twe_ctrl
, name
, strlen(fbsd_dev_twe_ctrl
))){
2068 contr
=CONTROLLER_3WARE_678K_CHAR
;
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
);
2076 return new freebsd_escalade_device(this, name
, contr
, disknum
);
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");
2088 if (!(1 <= controller
&& controller
<= 8)) {
2089 set_err(EINVAL
, "Option '-d hpt,L/M/N' invalid controller id L supplied");
2092 if (!(1 <= channel
&& channel
<= 128)) {
2093 set_err(EINVAL
, "Option '-d hpt,L/M/N' invalid channel number M supplied");
2096 if (!(1 <= disknum
&& disknum
<= 15)) {
2097 set_err(EINVAL
, "Option '-d hpt,L/M/N' invalid pmport number N supplied");
2100 return new freebsd_highpoint_device(this, name
, controller
, channel
, disknum
);
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");
2110 if (!(0 <= disknum
&& disknum
<= 127)) {
2111 set_err(EINVAL
, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum
);
2114 return get_sat_device("sat,auto", new freebsd_cciss_device(this, name
, disknum
));
2116 #if FREEBSDVER > 800100
2118 if(!strcmp(type
,"atacam"))
2119 return new freebsd_atacam_device(this, name
, "");
2122 disknum
= n1
= n2
= -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
);
2129 if (!(1 <= encnum
&& encnum
<= 8)) {
2130 set_err(EINVAL
, "Option -d areca,N/E (E=%d) must have 1 <= E <= 8", encnum
);
2133 return new freebsd_areca_ata_device(this, name
, disknum
, encnum
);
2139 std::string
freebsd_smart_interface::get_valid_custom_dev_types_str()
2141 return "3ware,N, hpt,L/M/N, cciss,N, areca,N/E"
2142 #if FREEBSDVER > 800100
2150 /////////////////////////////////////////////////////////////////////////////
2151 /// Initialize platform interface and register with smi()
2153 void smart_interface::init()
2155 static os_freebsd::freebsd_smart_interface the_interface
;
2156 smart_interface::set(&the_interface
);