Annotation of embedaddon/smartmontools/os_linux.h, revision 1.1.1.2
1.1 misho 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
1.1.1.2 ! misho 27: * (for example COPYING); if not, write to the Free Software Foundation,
! 28: * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1.1 misho 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:
1.1.1.2 ! misho 41: #define OS_LINUX_H_CVSID "$Id: os_linux.h 3728 2012-12-13 17:57:50Z chrfranke $\n"
1.1 misho 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_ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>