int megaraid_io_interface(int device, int target, struct scsi_cmnd_io *, int);
#undef u32
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define u64 uint64_t
/*======================================================
* PERC2/3/4 Passthrough SCSI Command Interface
*
* Contents from:
* drivers/scsi/megaraid/megaraid_ioctl.h
* drivers/scsi/megaraid/mbox_defs.h
*======================================================*/
#define MEGAIOC_MAGIC 'm'
#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0, struct uioctl_t)
/* Following subopcode work for opcode == 0x82 */
#define MKADAP(adapno) (MEGAIOC_MAGIC << 8 | adapno)
#define MEGAIOC_QNADAP 'm'
#define MEGAIOC_QDRVRVER 'e'
#define MEGAIOC_QADAPINFO 'g'
#define MEGA_MBOXCMD_PASSTHRU 0x03
#define MAX_REQ_SENSE_LEN 0x20
#define MAX_CDB_LEN 10
typedef struct
{
uint8_t timeout : 3;
uint8_t ars : 1;
uint8_t reserved : 3;
uint8_t islogical : 1;
uint8_t logdrv;
uint8_t channel;
uint8_t target;
uint8_t queuetag;
uint8_t queueaction;
uint8_t cdb[MAX_CDB_LEN];
uint8_t cdblen;
uint8_t reqsenselen;
uint8_t reqsensearea[MAX_REQ_SENSE_LEN];
uint8_t numsgelements;
uint8_t scsistatus;
uint32_t dataxferaddr;
uint32_t dataxferlen;
} __attribute__((packed)) mega_passthru;
typedef struct
{
uint8_t cmd;
uint8_t cmdid;
uint8_t opcode;
uint8_t subopcode;
uint32_t lba;
uint32_t xferaddr;
uint8_t logdrv;
uint8_t resvd[3];
uint8_t numstatus;
uint8_t status;
} __attribute__((packed)) megacmd_t;
typedef union {
uint8_t *pointer;
uint8_t pad[8];
} ptr_t;
// The above definition assumes sizeof(void*) <= 8.
// This assumption also exists in the linux megaraid device driver.
// So define a macro to check expected size of ptr_t at compile time using
// a dummy typedef. On size mismatch, compiler reports a negative array
// size. If you see an error message of this form, it means that
// you have an unexpected pointer size on your platform and can not
// use megaraid support in smartmontools.
typedef char assert_sizeof_ptr_t[sizeof(ptr_t) == 8 ? 1 : -1];
struct uioctl_t
{
uint32_t inlen;
uint32_t outlen;
union {
uint8_t fca[16];
struct {
uint8_t opcode;
uint8_t subopcode;
uint16_t adapno;
ptr_t buffer;
uint32_t length;
} __attribute__((packed)) fcs;
} __attribute__((packed)) ui;
megacmd_t mbox;
mega_passthru pthru;
ptr_t data;
} __attribute__((packed));
/*===================================================
* PERC5/6 Passthrough SCSI Command Interface
*
* Contents from:
* drivers/scsi/megaraid/megaraid_sas.h
*===================================================*/
#define MEGASAS_MAGIC 'M'
#define MEGASAS_IOC_FIRMWARE _IOWR(MEGASAS_MAGIC, 1, struct megasas_iocpacket)
#define MFI_CMD_PD_SCSI_IO 0x04
#define MFI_CMD_DCMD 0x05
#define MFI_FRAME_SGL64 0x02
#define MFI_STAT_OK 0x00
#define MFI_DCMD_PD_GET_LIST 0x02010000
/*
* Number of mailbox bytes in DCMD message frame
*/
#define MFI_MBOX_SIZE 12
#define MAX_IOCTL_SGE 16
#define MFI_FRAME_DIR_NONE 0x0000
#define MFI_FRAME_DIR_WRITE 0x0008
#define MFI_FRAME_DIR_READ 0x0010
#define MFI_FRAME_DIR_BOTH 0x0018
#define MAX_SYS_PDS 240
struct megasas_sge32 {
u32 phys_addr;
u32 length;
} __attribute__ ((packed));
struct megasas_sge64 {
u64 phys_addr;
u32 length;
} __attribute__ ((packed));
union megasas_sgl {
struct megasas_sge32 sge32[1];
struct megasas_sge64 sge64[1];
} __attribute__ ((packed));
struct megasas_header {
u8 cmd; /*00h */
u8 sense_len; /*01h */
u8 cmd_status; /*02h */
u8 scsi_status; /*03h */
u8 target_id; /*04h */
u8 lun; /*05h */
u8 cdb_len; /*06h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
u32 data_xferlen; /*14h */
} __attribute__ ((packed));
struct megasas_pthru_frame {
u8 cmd; /*00h */
u8 sense_len; /*01h */
u8 cmd_status; /*02h */
u8 scsi_status; /*03h */
u8 target_id; /*04h */
u8 lun; /*05h */
u8 cdb_len; /*06h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
u32 data_xfer_len; /*14h */
u32 sense_buf_phys_addr_lo; /*18h */
u32 sense_buf_phys_addr_hi; /*1Ch */
u8 cdb[16]; /*20h */
union megasas_sgl sgl; /*30h */
} __attribute__ ((packed));
struct megasas_dcmd_frame {
u8 cmd; /*00h */
u8 reserved_0; /*01h */
u8 cmd_status; /*02h */
u8 reserved_1[4]; /*03h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
u32 data_xfer_len; /*14h */
u32 opcode; /*18h */
union { /*1Ch */
u8 b[12];
u16 s[6];
u32 w[3];
} mbox;
union megasas_sgl sgl; /*28h */
} __attribute__ ((packed));
struct megasas_iocpacket {
u16 host_no;
u16 __pad1;
u32 sgl_off;
u32 sge_count;
u32 sense_off;
u32 sense_len;
union {
u8 raw[128];
struct megasas_header hdr;
struct megasas_pthru_frame pthru;
struct megasas_dcmd_frame dcmd;
} frame;
struct iovec sgl[MAX_IOCTL_SGE];
} __attribute__ ((packed));
struct megasas_pd_address {
u16 device_id;
u16 encl_device_id;
u8 encl_index;
u8 slot_number;
u8 scsi_dev_type; /* 0 = disk */
u8 connect_port_bitmap;
u64 sas_addr[2];
} __attribute__ ((packed));
struct megasas_pd_list {
u32 size;
u32 count;
struct megasas_pd_address addr[MAX_SYS_PDS];
} __attribute__ ((packed));
#undef u8
#undef u16
#undef u32
#undef u64
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>