+ // mfip replacing PDT of the device so response does not make a sense
+ // this sets PDT to 00h - direct-access block device
+ if((!strcmp("mfi", m_camdev->sim_name) || !strcmp("mpt", m_camdev->sim_name))
+ && iop->cmnd[0] == INQUIRY) {
+ if (report > 0) {
+ pout("device on %s controller, patching PDT\n", m_camdev->sim_name);
+ }
+ iop->dxferp[0] = iop->dxferp[0] & 0xe0;
+ }
+
+ return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+/// Areca RAID support
+
+///////////////////////////////////////////////////////////////////
+// SATA(ATA) device behind Areca RAID Controller
+class freebsd_areca_ata_device
+: public /*implements*/ areca_ata_device,
+ public /*extends*/ freebsd_smart_device
+{
+public:
+ freebsd_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
+ virtual smart_device * autodetect_open();
+ virtual bool arcmsr_lock();
+ virtual bool arcmsr_unlock();
+ virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop);
+};
+
+///////////////////////////////////////////////////////////////////
+// SAS(SCSI) device behind Areca RAID Controller
+class freebsd_areca_scsi_device
+: public /*implements*/ areca_scsi_device,
+ public /*extends*/ freebsd_smart_device
+{
+public:
+ freebsd_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
+ virtual smart_device * autodetect_open();
+ virtual bool arcmsr_lock();
+ virtual bool arcmsr_unlock();
+ virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop);
+};
+
+
+// Areca RAID Controller(SATA Disk)
+freebsd_areca_ata_device::freebsd_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
+: smart_device(intf, dev_name, "areca", "areca"),
+ freebsd_smart_device("ATA")
+{
+ set_disknum(disknum);
+ set_encnum(encnum);
+ set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
+}
+
+
+smart_device * freebsd_areca_ata_device::autodetect_open()
+{
+ int is_ata = 1;
+
+ // autodetect device type
+ is_ata = arcmsr_get_dev_type();
+ if(is_ata < 0)
+ {
+ set_err(EIO);
+ return this;
+ }
+
+ if(is_ata == 1)
+ {
+ // SATA device
+ return this;
+ }
+
+ // SAS device
+ smart_device_auto_ptr newdev(new freebsd_areca_scsi_device(smi(), get_dev_name(), get_disknum(), get_encnum()));
+ close();
+ delete this;
+ newdev->open(); // TODO: Can possibly pass open fd
+
+ return newdev.release();
+}
+
+int freebsd_areca_ata_device::arcmsr_do_scsi_io(struct scsi_cmnd_io * iop)
+{
+ int ioctlreturn = 0;
+
+ if(!is_open()) {
+ if(!open()){
+ }
+ }
+
+ ioctlreturn = ioctl(get_fd(), ((sSRB_BUFFER *)(iop->dxferp))->srbioctl.ControlCode, iop->dxferp);
+ if (ioctlreturn)
+ {
+ // errors found
+ return -1;
+ }
+
+ return ioctlreturn;
+}
+
+bool freebsd_areca_ata_device::arcmsr_lock()
+{
+ return true;
+}
+
+
+bool freebsd_areca_ata_device::arcmsr_unlock()
+{
+ return true;
+}
+
+
+// Areca RAID Controller(SAS Device)
+freebsd_areca_scsi_device::freebsd_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
+: smart_device(intf, dev_name, "areca", "areca"),
+ freebsd_smart_device("SCSI")
+{
+ set_disknum(disknum);
+ set_encnum(encnum);
+ set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
+}
+
+smart_device * freebsd_areca_scsi_device::autodetect_open()
+{
+ return this;
+}
+
+int freebsd_areca_scsi_device::arcmsr_do_scsi_io(struct scsi_cmnd_io * iop)
+{
+ int ioctlreturn = 0;
+
+ if(!is_open()) {
+ if(!open()){
+ }
+ }
+ ioctlreturn = ioctl(get_fd(), ((sSRB_BUFFER *)(iop->dxferp))->srbioctl.ControlCode, iop->dxferp);
+ if (ioctlreturn)
+ {
+ // errors found
+ return -1;
+ }
+
+ return ioctlreturn;
+}
+
+bool freebsd_areca_scsi_device::arcmsr_lock()
+{
+ return true;
+}
+
+
+bool freebsd_areca_scsi_device::arcmsr_unlock()
+{