blob: fc07a050faa8afd2db7f130d874a663644494771 (
plain)
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
|
/*
* megaraid.h
*
* Home page of code is: http://www.smartmontools.org
*
* Copyright (C) 2008 Jordan Hargrave
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
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
|