]> git.proxmox.com Git - mirror_smartmontools-debian.git/blob - os_linux.h
import smartmontools 7.0
[mirror_smartmontools-debian.git] / os_linux.h
1 /*
2 * os_linux.h
3 *
4 * Home page of code is: http://www.smartmontools.org
5 *
6 * Copyright (C) 2003-8 Bruce Allen
7 *
8 * Derived from code that was
9 *
10 * Written By: Adam Radford <linux@3ware.com>
11 * Modifications By: Joel Jacobson <linux@3ware.com>
12 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
13 * Brad Strand <linux@3ware.com>
14 *
15 * Copyright (C) 1999-2003 3ware Inc.
16 *
17 * Kernel compatibility By: Andre Hedrick <andre@suse.com>
18 * Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com>
19 *
20 * SPDX-License-Identifier: GPL-2.0-or-later
21 */
22
23
24 #ifndef OS_LINUX_H_
25 #define OS_LINUX_H_
26
27 #define OS_LINUX_H_CVSID "$Id: os_linux.h 4842 2018-12-02 16:07:26Z chrfranke $\n"
28
29 /*
30 The following definitions/macros/prototypes are used for three
31 different interfaces, referred to as "the three cases" below.
32 CONTROLLER_3WARE_678K -- 6000, 7000, and 8000 controllers via /dev/sd?
33 CONTROLLER_3WARE_678K_CHAR -- 6000, 7000, and 8000 controllers via /dev/twe?
34 CONTROLLER_3WARE_9000_CHAR -- 9000 controllers via /dev/twa?
35 */
36
37 // USED FOR ALL THREE CASES
38
39 #define u32 unsigned int
40 #define TW_OP_ATA_PASSTHRU 0x11
41 #define MAX(x,y) ( (x)>(y)?(x):(y) )
42
43 #pragma pack(1)
44 /* Scatter gather list entry */
45 typedef struct TAG_TW_SG_Entry {
46 unsigned int address;
47 unsigned int length;
48 } TW_SG_Entry;
49
50 /* Command header for ATA pass-thru. Note that for different
51 drivers/interfaces the length of sg_list (here TW_ATA_PASS_SGL_MAX)
52 is different. But it can be taken as same for all three cases
53 because it's never used to define any other structures, and we
54 never use anything in the sg_list or beyond! */
55
56 #define TW_ATA_PASS_SGL_MAX 60
57
58 typedef struct TAG_TW_Passthru {
59 struct {
60 unsigned char opcode:5;
61 unsigned char sgloff:3;
62 } byte0;
63 unsigned char size;
64 unsigned char request_id;
65 unsigned char unit;
66 unsigned char status; // On return, contains 3ware STATUS register
67 unsigned char flags;
68 unsigned short param;
69 unsigned short features; // On return, contains ATA ERROR register
70 unsigned short sector_count;
71 unsigned short sector_num;
72 unsigned short cylinder_lo;
73 unsigned short cylinder_hi;
74 unsigned char drive_head;
75 unsigned char command; // On return, contains ATA STATUS register
76 TW_SG_Entry sg_list[TW_ATA_PASS_SGL_MAX];
77 unsigned char padding[12];
78 } TW_Passthru;
79
80 // the following are for the SCSI interface only
81
82 // Ioctl buffer: Note that this defn has changed in kernel tree...
83 // Total size is 1041 bytes -- this is really weird
84
85 #define TW_IOCTL 0x80
86 #define TW_ATA_PASSTHRU 0x1e
87
88 // Adam -- should this be #pramga packed? Otherwise table_id gets
89 // moved for byte alignment. Without packing, input passthru for SCSI
90 // ioctl is 31 bytes in. With packing it is 30 bytes in.
91 typedef struct TAG_TW_Ioctl {
92 int input_length;
93 int output_length;
94 unsigned char cdb[16];
95 unsigned char opcode;
96 // This one byte of padding is missing from the typedefs in the
97 // kernel code, but it is indeed present. We put it explicitly
98 // here, so that the structure can be packed. Adam agrees with
99 // this.
100 unsigned char packing;
101 unsigned short table_id;
102 unsigned char parameter_id;
103 unsigned char parameter_size_bytes;
104 unsigned char unit_index;
105 // Size up to here is 30 bytes + 1 padding!
106 unsigned char input_data[499];
107 // Reserve lots of extra space for commands that set Sector Count
108 // register to large values
109 unsigned char output_data[512]; // starts 530 bytes in!
110 // two more padding bytes here if structure NOT packed.
111 } TW_Ioctl;
112
113 /* Ioctl buffer output -- SCSI interface only! */
114 typedef struct TAG_TW_Output {
115 int padding[2];
116 char output_data[512];
117 } TW_Output;
118
119 // What follows is needed for 9000 char interface only
120
121 #define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108
122 #define TW_MAX_SGL_LENGTH_9000 61
123
124 typedef struct TAG_TW_Ioctl_Driver_Command_9000 {
125 unsigned int control_code;
126 unsigned int status;
127 unsigned int unique_id;
128 unsigned int sequence_id;
129 unsigned int os_specific;
130 unsigned int buffer_length;
131 } TW_Ioctl_Driver_Command_9000;
132
133 /* Command Packet */
134 typedef struct TW_Command_9000 {
135 /* First DWORD */
136 struct {
137 unsigned char opcode:5;
138 unsigned char sgl_offset:3;
139 } byte0;
140 unsigned char size;
141 unsigned char request_id;
142 struct {
143 unsigned char unit:4;
144 unsigned char host_id:4;
145 } byte3;
146 /* Second DWORD */
147 unsigned char status;
148 unsigned char flags;
149 union {
150 unsigned short block_count;
151 unsigned short parameter_count;
152 unsigned short message_credits;
153 } byte6;
154 union {
155 struct {
156 u32 lba;
157 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000];
158 u32 padding;
159 } io;
160 struct {
161 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000];
162 u32 padding[2];
163 } param;
164 struct {
165 u32 response_queue_pointer;
166 u32 padding[125]; /* pad entire structure to 512 bytes */
167 } init_connection;
168 struct {
169 char version[504];
170 } ioctl_miniport_version;
171 } byte8;
172 } TW_Command_9000;
173
174 /* Command Packet for 9000+ controllers */
175 typedef struct TAG_TW_Command_Apache {
176 struct {
177 unsigned char opcode:5;
178 unsigned char reserved:3;
179 } command;
180 unsigned char unit;
181 unsigned short request_id;
182 unsigned char sense_length;
183 unsigned char sgl_offset;
184 unsigned short sgl_entries;
185 unsigned char cdb[16];
186 TW_SG_Entry sg_list[TW_MAX_SGL_LENGTH_9000];
187 } TW_Command_Apache;
188
189 /* New command packet header */
190 typedef struct TAG_TW_Command_Apache_Header {
191 unsigned char sense_data[18];
192 struct {
193 char reserved[4];
194 unsigned short error;
195 unsigned char status;
196 struct {
197 unsigned char severity:3;
198 unsigned char reserved:5;
199 } substatus_block;
200 } status_block;
201 unsigned char err_specific_desc[102];
202 } TW_Command_Apache_Header;
203
204 /* This struct is a union of the 2 command packets */
205 typedef struct TAG_TW_Command_Full_9000 {
206 TW_Command_Apache_Header header;
207 union {
208 TW_Command_9000 oldcommand;
209 TW_Command_Apache newcommand;
210 } command;
211 unsigned char padding[384]; /* Pad to 1024 bytes */
212 } TW_Command_Full_9000;
213
214 typedef struct TAG_TW_Ioctl_Apache {
215 TW_Ioctl_Driver_Command_9000 driver_command;
216 char padding[488];
217 TW_Command_Full_9000 firmware_command;
218 char data_buffer[1];
219 // three bytes of padding here if structure not packed!
220 } TW_Ioctl_Buf_Apache;
221
222
223
224 // START OF DEFINITIONS FOR THE CHARACTER INTERFACE TO THE
225 // 6000/7000/8000 drivers
226
227 #define TW_MAX_SGL_LENGTH 62
228 #define TW_CMD_PACKET_WITH_DATA 0x1f
229
230 /* Command Packet */
231 typedef struct TW_Command {
232 /* First DWORD */
233 struct {
234 unsigned char opcode:5;
235 unsigned char sgl_offset:3;
236 } byte0;
237 unsigned char size;
238 unsigned char request_id;
239 struct {
240 unsigned char unit:4;
241 unsigned char host_id:4;
242 } byte3;
243 /* Second DWORD */
244 unsigned char status;
245 unsigned char flags;
246 union {
247 unsigned short block_count;
248 unsigned short parameter_count;
249 unsigned short message_credits;
250 } byte6;
251 union {
252 struct {
253 u32 lba;
254 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
255 u32 padding; /* pad to 512 bytes */
256 } io;
257 struct {
258 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
259 u32 padding[2];
260 } param;
261 struct {
262 u32 response_queue_pointer;
263 u32 padding[125];
264 } init_connection;
265 struct {
266 char version[504];
267 } ioctl_miniport_version;
268 } byte8;
269 } TW_Command;
270
271 typedef struct TAG_TW_New_Ioctl {
272 unsigned int data_buffer_length;
273 unsigned char padding [508];
274 TW_Command firmware_command;
275 char data_buffer[1];
276 // three bytes of padding here
277 } TW_New_Ioctl;
278 #pragma pack()
279
280 #if 0
281 // Useful for checking/understanding packing of 3ware data structures
282 // above.
283 void my(int x, char *y){
284 printf("The size of %30s is: %5d\n",y, x);
285 return;
286 }
287
288 int main() {
289 TW_Ioctl tmp;
290 my(sizeof(TW_SG_Entry),"TW_SG_Entry");
291 my(sizeof(TW_Passthru),"TW_Passthru");
292 my(sizeof(TW_Ioctl),"TW_Ioctl");
293 my(sizeof(TW_Output),"TW_Output");
294 my(sizeof(TW_Ioctl_Driver_Command_9000),"TW_Ioctl_Driver_Command_9000");
295 my(sizeof(TW_Command_9000),"TW_Command_9000");
296 my(sizeof(TW_Command_Apache),"TW_Command_Apache");
297 my(sizeof(TW_Command_Apache_Header),"TW_Command_Apache_Header");
298 my(sizeof(TW_Command_Full_9000),"TW_Command_Full_9000");
299 my(sizeof(TW_Ioctl_Buf_Apache),"TW_Ioctl_Buf_Apache");
300 my(sizeof(TW_Command),"TW_Command");
301 my(sizeof(TW_New_Ioctl),"TW_New_Ioctl");
302 printf("TW_Ioctl.table_id - start = %d (irrelevant)\n",
303 (void *)&tmp.table_id - (void *)&tmp);
304 printf("TW_Ioctl.input_data - start = %d (input passthru location)\n",
305 (void *)&tmp.input_data - (void *)&tmp);
306 printf("TW_Ioctl.output_data - start = %d (irrelevant)\n",
307 (void *)&tmp.output_data - (void *)&tmp);
308 return 0;
309 }
310 #endif
311
312 // The following definitions are from hdreg.h in the kernel source
313 // tree. They don't carry any Copyright statements, but I think they
314 // are primarily from Mark Lord and Andre Hedrick.
315 typedef unsigned char task_ioreg_t;
316
317 typedef struct hd_drive_task_hdr {
318 task_ioreg_t data;
319 task_ioreg_t feature;
320 task_ioreg_t sector_count;
321 task_ioreg_t sector_number;
322 task_ioreg_t low_cylinder;
323 task_ioreg_t high_cylinder;
324 task_ioreg_t device_head;
325 task_ioreg_t command;
326 } task_struct_t;
327
328 typedef union ide_reg_valid_s {
329 unsigned all : 16;
330 struct {
331 unsigned data : 1;
332 unsigned error_feature : 1;
333 unsigned sector : 1;
334 unsigned nsector : 1;
335 unsigned lcyl : 1;
336 unsigned hcyl : 1;
337 unsigned select : 1;
338 unsigned status_command : 1;
339 unsigned data_hob : 1;
340 unsigned error_feature_hob : 1;
341 unsigned sector_hob : 1;
342 unsigned nsector_hob : 1;
343 unsigned lcyl_hob : 1;
344 unsigned hcyl_hob : 1;
345 unsigned select_hob : 1;
346 unsigned control_hob : 1;
347 } b;
348 } ide_reg_valid_t;
349
350 typedef struct ide_task_request_s {
351 task_ioreg_t io_ports[8];
352 task_ioreg_t hob_ports[8];
353 ide_reg_valid_t out_flags;
354 ide_reg_valid_t in_flags;
355 int data_phase;
356 int req_cmd;
357 unsigned long out_size;
358 unsigned long in_size;
359 } ide_task_request_t;
360
361 #define TASKFILE_NO_DATA 0x0000
362 #define TASKFILE_IN 0x0001
363 #define TASKFILE_OUT 0x0004
364 #define HDIO_DRIVE_TASK_HDR_SIZE 8*sizeof(task_ioreg_t)
365 #define IDE_DRIVE_TASK_NO_DATA 0
366 #define IDE_DRIVE_TASK_IN 2
367 #define IDE_DRIVE_TASK_OUT 3
368 #define HDIO_DRIVE_CMD 0x031f
369 #define HDIO_DRIVE_TASK 0x031e
370 #define HDIO_DRIVE_TASKFILE 0x031d
371 #define HDIO_GET_IDENTITY 0x030d
372
373 #define HPTIO_CTL 0x03ff // ioctl interface for HighPoint raid device
374
375 #endif /* OS_LINUX_H_ */