1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
/*
* dev_areca.h
*
* Home page of code is: https://www.smartmontools.org
*
* Copyright (C) 2012 Hank Wu <hank@areca.com.tw>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef DEV_ARECA_H
#define DEV_ARECA_H
#define DEV_ARECA_H_CVSID "$Id: dev_areca.h 5198 2021-02-01 20:36:02Z chrfranke $"
/////////////////////////////////////////////////////////////////////////////
/// Areca RAID support
/* GENERIC ARECA IO CONTROL CODE*/
enum _GENERIC_ARCMSR_CMDS
{
ARCMSR_READ_RQBUFFER = 0,
ARCMSR_WRITE_WQBUFFER,
ARCMSR_CLEAR_RQBUFFER,
ARCMSR_CLEAR_WQBUFFER,
ARCMSR_RETURN_CODE_3F,
ARCMSR_CMD_TOTAL
};
#define ARECA_SIG_STR "ARCMSR"
#if defined(_WIN32) || defined(__CYGWIN__)
#define ARCMSR_IOCTL_READ_RQBUFFER 0x90002004
#define ARCMSR_IOCTL_WRITE_WQBUFFER 0x90002008
#define ARCMSR_IOCTL_CLEAR_RQBUFFER 0x9000200C
#define ARCMSR_IOCTL_CLEAR_WQBUFFER 0x90002010
#define ARCMSR_IOCTL_RETURN_CODE_3F 0x90002018
#elif defined(__linux__)
/*DeviceType*/
#define ARECA_SATA_RAID 0x90000000
/*FunctionCode*/
#define FUNCTION_READ_RQBUFFER 0x0801
#define FUNCTION_WRITE_WQBUFFER 0x0802
#define FUNCTION_CLEAR_RQBUFFER 0x0803
#define FUNCTION_CLEAR_WQBUFFER 0x0804
#define FUNCTION_RETURN_CODE_3F 0x0806
/* ARECA IO CONTROL CODE*/
#define ARCMSR_IOCTL_READ_RQBUFFER (ARECA_SATA_RAID | FUNCTION_READ_RQBUFFER)
#define ARCMSR_IOCTL_WRITE_WQBUFFER (ARECA_SATA_RAID | FUNCTION_WRITE_WQBUFFER)
#define ARCMSR_IOCTL_CLEAR_RQBUFFER (ARECA_SATA_RAID | FUNCTION_CLEAR_RQBUFFER)
#define ARCMSR_IOCTL_CLEAR_WQBUFFER (ARECA_SATA_RAID | FUNCTION_CLEAR_WQBUFFER)
#define ARCMSR_IOCTL_RETURN_CODE_3F (ARECA_SATA_RAID | FUNCTION_RETURN_CODE_3F)
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/ioctl.h> // _IOWR
/*FunctionCode*/
#define FUNCTION_READ_RQBUFFER 0x0801
#define FUNCTION_WRITE_WQBUFFER 0x0802
#define FUNCTION_CLEAR_RQBUFFER 0x0803
#define FUNCTION_CLEAR_WQBUFFER 0x0804
#define FUNCTION_RETURN_CODE_3F 0x0806
/* ARECA IO CONTROL CODE*/
#define ARCMSR_IOCTL_READ_RQBUFFER _IOWR('F', FUNCTION_READ_RQBUFFER, sSRB_BUFFER)
#define ARCMSR_IOCTL_WRITE_WQBUFFER _IOWR('F', FUNCTION_WRITE_WQBUFFER, sSRB_BUFFER)
#define ARCMSR_IOCTL_CLEAR_RQBUFFER _IOWR('F', FUNCTION_CLEAR_RQBUFFER, sSRB_BUFFER)
#define ARCMSR_IOCTL_CLEAR_WQBUFFER _IOWR('F', FUNCTION_CLEAR_WQBUFFER, sSRB_BUFFER)
#define ARCMSR_IOCTL_RETURN_CODE_3F _IOWR('F', FUNCTION_RETURN_CODE_3F, sSRB_BUFFER)
#endif
// The SRB_IO_CONTROL & SRB_BUFFER structures are used to communicate(to/from) to areca driver
typedef struct _ARCMSR_IO_HDR
{
unsigned int HeaderLength;
unsigned char Signature[8];
unsigned int Timeout;
unsigned int ControlCode;
unsigned int ReturnCode;
unsigned int Length;
} sARCMSR_IO_HDR;
typedef struct _SRB_BUFFER
{
sARCMSR_IO_HDR srbioctl;
unsigned char ioctldatabuffer[1032]; // the buffer to put the command data to/from firmware
} sSRB_BUFFER;
class generic_areca_device :
virtual public smart_device
{
public:
generic_areca_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
~generic_areca_device();
/////////////////////////////////////////////////////////////////////
// OS-dependent functions
virtual bool arcmsr_lock() = 0;
virtual bool arcmsr_unlock() = 0;
virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop) = 0;
/////////////////////////////////////////////////////////////////////
// OS-independent functions
virtual int arcmsr_command_handler(unsigned long arcmsr_cmd, unsigned char *data, int data_len);
virtual int arcmsr_ui_handler(unsigned char *areca_packet, int areca_packet_len, unsigned char *result);
virtual bool arcmsr_probe();
virtual int arcmsr_get_dev_type();
virtual int arcmsr_get_controller_type();
virtual bool arcmsr_scsi_pass_through(scsi_cmnd_io * iop);
virtual bool arcmsr_ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
protected:
generic_areca_device()
: smart_device(never_called),
m_disknum(-1), m_encnum(-1)
{ }
void set_disknum(int disknum)
{m_disknum = disknum;}
void set_encnum(int encnum)
{m_encnum = encnum;}
int get_disknum()
{return m_disknum;}
int get_encnum()
{return m_encnum;}
private:
int m_disknum; ///< Disk number.
int m_encnum; ///< Enclosure number.
};
// SATA(ATA) device behind Areca RAID Controller
class areca_ata_device
: public ata_device,
public generic_areca_device
{
public:
areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
~areca_ata_device();
bool arcmsr_lock() override { return true; }
bool arcmsr_unlock() override { return true; }
int arcmsr_do_scsi_io(struct scsi_cmnd_io * /* iop */) override
{
return -1;
}
protected:
areca_ata_device(): smart_device(never_called)
{
}
virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
};
// SAS(SCSI) device behind Areca RAID Controller
class areca_scsi_device
: public scsi_device,
public generic_areca_device
{
public:
areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
~areca_scsi_device();
bool arcmsr_lock() override { return true; }
bool arcmsr_unlock() override { return true; }
int arcmsr_do_scsi_io(struct scsi_cmnd_io * /* iop */) override
{
return -1;
}
protected:
areca_scsi_device(): smart_device(never_called)
{
}
virtual bool scsi_pass_through(scsi_cmnd_io * iop) override;
};
#endif
|