1 /* 2 * megaraid.h 3 * 4 * Home page of code is: http://www.smartmontools.org 5 * 6 * Copyright (C) 2008 Jordan Hargrave 7 * 8 * SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10 11 int megaraid_io_interface(int device, int target, struct scsi_cmnd_io *, int); 12 13 #undef u32 14 15 #define u8 uint8_t 16 #define u16 uint16_t 17 #define u32 uint32_t 18 #define u64 uint64_t 19 20 /*====================================================== 21 * PERC2/3/4 Passthrough SCSI Command Interface 22 * 23 * Contents from: 24 * drivers/scsi/megaraid/megaraid_ioctl.h 25 * drivers/scsi/megaraid/mbox_defs.h 26 *======================================================*/ 27 #define MEGAIOC_MAGIC 'm' 28 #define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0, struct uioctl_t) 29 30 /* Following subopcode work for opcode == 0x82 */ 31 #define MKADAP(adapno) (MEGAIOC_MAGIC << 8 | adapno) 32 #define MEGAIOC_QNADAP 'm' 33 #define MEGAIOC_QDRVRVER 'e' 34 #define MEGAIOC_QADAPINFO 'g' 35 36 #define MEGA_MBOXCMD_PASSTHRU 0x03 37 38 #define MAX_REQ_SENSE_LEN 0x20 39 #define MAX_CDB_LEN 10 40 41 typedef struct 42 { 43 uint8_t timeout : 3; 44 uint8_t ars : 1; 45 uint8_t reserved : 3; 46 uint8_t islogical : 1; 47 uint8_t logdrv; 48 uint8_t channel; 49 uint8_t target; 50 uint8_t queuetag; 51 uint8_t queueaction; 52 uint8_t cdb[MAX_CDB_LEN]; 53 uint8_t cdblen; 54 uint8_t reqsenselen; 55 uint8_t reqsensearea[MAX_REQ_SENSE_LEN]; 56 uint8_t numsgelements; 57 uint8_t scsistatus; 58 uint32_t dataxferaddr; 59 uint32_t dataxferlen; 60 } __attribute__((packed)) mega_passthru; 61 62 typedef struct 63 { 64 uint8_t cmd; 65 uint8_t cmdid; 66 uint8_t opcode; 67 uint8_t subopcode; 68 uint32_t lba; 69 uint32_t xferaddr; 70 uint8_t logdrv; 71 uint8_t resvd[3]; 72 uint8_t numstatus; 73 uint8_t status; 74 } __attribute__((packed)) megacmd_t; 75 76 typedef union { 77 uint8_t *pointer; 78 uint8_t pad[8]; 79 } ptr_t; 80 81 // The above definition assumes sizeof(void*) <= 8. 82 // This assumption also exists in the linux megaraid device driver. 83 // So define a macro to check expected size of ptr_t at compile time using 84 // a dummy typedef. On size mismatch, compiler reports a negative array 85 // size. If you see an error message of this form, it means that 86 // you have an unexpected pointer size on your platform and can not 87 // use megaraid support in smartmontools. 88 typedef char assert_sizeof_ptr_t[sizeof(ptr_t) == 8 ? 1 : -1]; 89 90 struct uioctl_t 91 { 92 uint32_t inlen; 93 uint32_t outlen; 94 union { 95 uint8_t fca[16]; 96 struct { 97 uint8_t opcode; 98 uint8_t subopcode; 99 uint16_t adapno; 100 ptr_t buffer; 101 uint32_t length; 102 } __attribute__((packed)) fcs; 103 } __attribute__((packed)) ui; 104 105 megacmd_t mbox; 106 mega_passthru pthru; 107 ptr_t data; 108 } __attribute__((packed)); 109 110 /*=================================================== 111 * PERC5/6 Passthrough SCSI Command Interface 112 * 113 * Contents from: 114 * drivers/scsi/megaraid/megaraid_sas.h 115 *===================================================*/ 116 #define MEGASAS_MAGIC 'M' 117 #define MEGASAS_IOC_FIRMWARE _IOWR(MEGASAS_MAGIC, 1, struct megasas_iocpacket) 118 119 #define MFI_CMD_PD_SCSI_IO 0x04 120 #define MFI_CMD_DCMD 0x05 121 #define MFI_FRAME_SGL64 0x02 122 #define MFI_STAT_OK 0x00 123 #define MFI_DCMD_PD_GET_LIST 0x02010000 124 /* 125 * Number of mailbox bytes in DCMD message frame 126 */ 127 #define MFI_MBOX_SIZE 12 128 #define MAX_IOCTL_SGE 16 129 #define MFI_FRAME_DIR_NONE 0x0000 130 #define MFI_FRAME_DIR_WRITE 0x0008 131 #define MFI_FRAME_DIR_READ 0x0010 132 #define MFI_FRAME_DIR_BOTH 0x0018 133 134 #define MAX_SYS_PDS 240 135 136 struct megasas_sge32 { 137 138 u32 phys_addr; 139 u32 length; 140 141 } __attribute__ ((packed)); 142 143 struct megasas_sge64 { 144 145 u64 phys_addr; 146 u32 length; 147 148 } __attribute__ ((packed)); 149 150 union megasas_sgl { 151 152 struct megasas_sge32 sge32[1]; 153 struct megasas_sge64 sge64[1]; 154 155 } __attribute__ ((packed)); 156 157 struct megasas_header { 158 159 u8 cmd; /*00h */ 160 u8 sense_len; /*01h */ 161 u8 cmd_status; /*02h */ 162 u8 scsi_status; /*03h */ 163 164 u8 target_id; /*04h */ 165 u8 lun; /*05h */ 166 u8 cdb_len; /*06h */ 167 u8 sge_count; /*07h */ 168 169 u32 context; /*08h */ 170 u32 pad_0; /*0Ch */ 171 172 u16 flags; /*10h */ 173 u16 timeout; /*12h */ 174 u32 data_xferlen; /*14h */ 175 176 } __attribute__ ((packed)); 177 178 struct megasas_pthru_frame { 179 180 u8 cmd; /*00h */ 181 u8 sense_len; /*01h */ 182 u8 cmd_status; /*02h */ 183 u8 scsi_status; /*03h */ 184 185 u8 target_id; /*04h */ 186 u8 lun; /*05h */ 187 u8 cdb_len; /*06h */ 188 u8 sge_count; /*07h */ 189 190 u32 context; /*08h */ 191 u32 pad_0; /*0Ch */ 192 193 u16 flags; /*10h */ 194 u16 timeout; /*12h */ 195 u32 data_xfer_len; /*14h */ 196 197 u32 sense_buf_phys_addr_lo; /*18h */ 198 u32 sense_buf_phys_addr_hi; /*1Ch */ 199 200 u8 cdb[16]; /*20h */ 201 union megasas_sgl sgl; /*30h */ 202 203 } __attribute__ ((packed)); 204 205 struct megasas_dcmd_frame { 206 207 u8 cmd; /*00h */ 208 u8 reserved_0; /*01h */ 209 u8 cmd_status; /*02h */ 210 u8 reserved_1[4]; /*03h */ 211 u8 sge_count; /*07h */ 212 213 u32 context; /*08h */ 214 u32 pad_0; /*0Ch */ 215 216 u16 flags; /*10h */ 217 u16 timeout; /*12h */ 218 219 u32 data_xfer_len; /*14h */ 220 u32 opcode; /*18h */ 221 222 union { /*1Ch */ 223 u8 b[12]; 224 u16 s[6]; 225 u32 w[3]; 226 } mbox; 227 228 union megasas_sgl sgl; /*28h */ 229 230 } __attribute__ ((packed)); 231 232 struct megasas_iocpacket { 233 u16 host_no; 234 u16 __pad1; 235 u32 sgl_off; 236 u32 sge_count; 237 u32 sense_off; 238 u32 sense_len; 239 union { 240 u8 raw[128]; 241 struct megasas_header hdr; 242 struct megasas_pthru_frame pthru; 243 struct megasas_dcmd_frame dcmd; 244 } frame; 245 246 struct iovec sgl[MAX_IOCTL_SGE]; 247 } __attribute__ ((packed)); 248 249 struct megasas_pd_address { 250 u16 device_id; 251 u16 encl_device_id; 252 u8 encl_index; 253 u8 slot_number; 254 u8 scsi_dev_type; /* 0 = disk */ 255 u8 connect_port_bitmap; 256 u64 sas_addr[2]; 257 } __attribute__ ((packed)); 258 259 struct megasas_pd_list { 260 u32 size; 261 u32 count; 262 struct megasas_pd_address addr[MAX_SYS_PDS]; 263 } __attribute__ ((packed)); 264 265 #undef u8 266 #undef u16 267 #undef u32 268 #undef u64 269 270