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