]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - os_linux.h
Imported smartmontools-5.37
[mirror_smartmontools-debian.git] / os_linux.h
CommitLineData
832b75ed
GG
1/*
2 * os_linux.h
3 *
4 * Home page of code is: http://smartmontools.sourceforge.net
5 *
6 * Copyright (C) 2003-6 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>
4d59bff9 12 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
832b75ed
GG
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
28 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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
4d59bff9 41#define OS_LINUX_H_CVSID "$Id: os_linux.h,v 1.25 2006/08/25 06:06:25 sxzzsf Exp $\n"
832b75ed
GG
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 */
59typedef 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
72typedef 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 struct {
80 unsigned char aport:4;
81 unsigned char host_id:4;
82 } byte3;
83 unsigned char status; // On return, contains 3ware STATUS register
84 unsigned char flags;
85 unsigned short param;
86 unsigned short features; // On return, contains ATA ERROR register
87 unsigned short sector_count;
88 unsigned short sector_num;
89 unsigned short cylinder_lo;
90 unsigned short cylinder_hi;
91 unsigned char drive_head;
92 unsigned char command; // On return, contains ATA STATUS register
93 TW_SG_Entry sg_list[TW_ATA_PASS_SGL_MAX];
94 unsigned char padding[12];
95} TW_Passthru;
96
97// the following are for the SCSI interface only
98
99// Ioctl buffer: Note that this defn has changed in kernel tree...
100// Total size is 1041 bytes -- this is really weird
101
102#define TW_IOCTL 0x80
103#define TW_ATA_PASSTHRU 0x1e
104
105// Adam -- should this be #pramga packed? Otherwise table_id gets
106// moved for byte alignment. Without packing, input passthru for SCSI
107// ioctl is 31 bytes in. With packing it is 30 bytes in.
108typedef struct TAG_TW_Ioctl {
109 int input_length;
110 int output_length;
111 unsigned char cdb[16];
112 unsigned char opcode;
113 // This one byte of padding is missing from the typedefs in the
114 // kernel code, but it is indeed present. We put it explicitly
115 // here, so that the structure can be packed. Adam agrees with
116 // this.
117 unsigned char packing;
118 unsigned short table_id;
119 unsigned char parameter_id;
120 unsigned char parameter_size_bytes;
121 unsigned char unit_index;
122 // Size up to here is 30 bytes + 1 padding!
123 unsigned char input_data[499];
124 // Reserve lots of extra space for commands that set Sector Count
125 // register to large values
126 unsigned char output_data[512]; // starts 530 bytes in!
127 // two more padding bytes here if structure NOT packed.
128} TW_Ioctl;
129
130/* Ioctl buffer output -- SCSI interface only! */
131typedef struct TAG_TW_Output {
132 int padding[2];
133 char output_data[512];
134} TW_Output;
135
136// What follows is needed for 9000 char interface only
137
138#define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108
139#define TW_MAX_SGL_LENGTH_9000 61
140
141typedef struct TAG_TW_Ioctl_Driver_Command_9000 {
142 unsigned int control_code;
143 unsigned int status;
144 unsigned int unique_id;
145 unsigned int sequence_id;
146 unsigned int os_specific;
147 unsigned int buffer_length;
148} TW_Ioctl_Driver_Command_9000;
149
150/* Command Packet */
151typedef struct TW_Command_9000 {
152 /* First DWORD */
153 struct {
154 unsigned char opcode:5;
155 unsigned char sgl_offset:3;
156 } byte0;
157 unsigned char size;
158 unsigned char request_id;
159 struct {
160 unsigned char unit:4;
161 unsigned char host_id:4;
162 } byte3;
163 /* Second DWORD */
164 unsigned char status;
165 unsigned char flags;
166 union {
167 unsigned short block_count;
168 unsigned short parameter_count;
169 unsigned short message_credits;
170 } byte6;
171 union {
172 struct {
173 u32 lba;
174 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000];
175 u32 padding;
176 } io;
177 struct {
178 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000];
179 u32 padding[2];
180 } param;
181 struct {
182 u32 response_queue_pointer;
183 u32 padding[125]; /* pad entire structure to 512 bytes */
184 } init_connection;
185 struct {
186 char version[504];
187 } ioctl_miniport_version;
188 } byte8;
189} TW_Command_9000;
190
191/* Command Packet for 9000+ controllers */
192typedef struct TAG_TW_Command_Apache {
193 struct {
194 unsigned char opcode:5;
195 unsigned char reserved:3;
196 } command;
197 unsigned char unit;
198 unsigned short request_id;
199 unsigned char sense_length;
200 unsigned char sgl_offset;
201 unsigned short sgl_entries;
202 unsigned char cdb[16];
203 TW_SG_Entry sg_list[TW_MAX_SGL_LENGTH_9000];
204} TW_Command_Apache;
205
206/* New command packet header */
207typedef struct TAG_TW_Command_Apache_Header {
208 unsigned char sense_data[18];
209 struct {
210 char reserved[4];
211 unsigned short error;
212 unsigned char status;
213 struct {
214 unsigned char severity:3;
215 unsigned char reserved:5;
216 } substatus_block;
217 } status_block;
218 unsigned char err_specific_desc[102];
219} TW_Command_Apache_Header;
220
221/* This struct is a union of the 2 command packets */
222typedef struct TAG_TW_Command_Full_9000 {
223 TW_Command_Apache_Header header;
224 union {
225 TW_Command_9000 oldcommand;
226 TW_Command_Apache newcommand;
227 } command;
228 unsigned char padding[384]; /* Pad to 1024 bytes */
229} TW_Command_Full_9000;
230
231typedef struct TAG_TW_Ioctl_Apache {
232 TW_Ioctl_Driver_Command_9000 driver_command;
233 char padding[488];
234 TW_Command_Full_9000 firmware_command;
235 char data_buffer[1];
236 // three bytes of padding here if structure not packed!
237} TW_Ioctl_Buf_Apache;
238
239
240
241// START OF DEFINITIONS FOR THE CHARACTER INTERFACE TO THE
242// 6000/7000/8000 drivers
243
244#define TW_MAX_SGL_LENGTH 62
245#define TW_CMD_PACKET_WITH_DATA 0x1f
246
247/* Command Packet */
248typedef struct TW_Command {
249 /* First DWORD */
250 struct {
251 unsigned char opcode:5;
252 unsigned char sgl_offset:3;
253 } byte0;
254 unsigned char size;
255 unsigned char request_id;
256 struct {
257 unsigned char unit:4;
258 unsigned char host_id:4;
259 } byte3;
260 /* Second DWORD */
261 unsigned char status;
262 unsigned char flags;
263 union {
264 unsigned short block_count;
265 unsigned short parameter_count;
266 unsigned short message_credits;
267 } byte6;
268 union {
269 struct {
270 u32 lba;
271 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
272 u32 padding; /* pad to 512 bytes */
273 } io;
274 struct {
275 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
276 u32 padding[2];
277 } param;
278 struct {
279 u32 response_queue_pointer;
280 u32 padding[125];
281 } init_connection;
282 struct {
283 char version[504];
284 } ioctl_miniport_version;
285 } byte8;
286} TW_Command;
287
288typedef struct TAG_TW_New_Ioctl {
289 unsigned int data_buffer_length;
290 unsigned char padding [508];
291 TW_Command firmware_command;
292 char data_buffer[1];
293 // three bytes of padding here
294} TW_New_Ioctl;
295#pragma pack()
296
297#if 0
298// Useful for checking/understanding packing of 3ware data structures
299// above.
300void my(int x, char *y){
301 printf("The size of %30s is: %5d\n",y, x);
302 return;
303}
304
305int main() {
306 TW_Ioctl tmp;
307 my(sizeof(TW_SG_Entry),"TW_SG_Entry");
308 my(sizeof(TW_Passthru),"TW_Passthru");
309 my(sizeof(TW_Ioctl),"TW_Ioctl");
310 my(sizeof(TW_Output),"TW_Output");
311 my(sizeof(TW_Ioctl_Driver_Command_9000),"TW_Ioctl_Driver_Command_9000");
312 my(sizeof(TW_Command_9000),"TW_Command_9000");
313 my(sizeof(TW_Command_Apache),"TW_Command_Apache");
314 my(sizeof(TW_Command_Apache_Header),"TW_Command_Apache_Header");
315 my(sizeof(TW_Command_Full_9000),"TW_Command_Full_9000");
316 my(sizeof(TW_Ioctl_Buf_Apache),"TW_Ioctl_Buf_Apache");
317 my(sizeof(TW_Command),"TW_Command");
318 my(sizeof(TW_New_Ioctl),"TW_New_Ioctl");
319 printf("TW_Ioctl.table_id - start = %d (irrelevant)\n",
320 (void *)&tmp.table_id - (void *)&tmp);
321 printf("TW_Ioctl.input_data - start = %d (input passthru location)\n",
322 (void *)&tmp.input_data - (void *)&tmp);
323 printf("TW_Ioctl.output_data - start = %d (irrelevant)\n",
324 (void *)&tmp.output_data - (void *)&tmp);
325 return 0;
326}
327#endif
328
329// The following definitions are from hdreg.h in the kernel source
330// tree. They don't carry any Copyright statements, but I think they
331// are primarily from Mark Lord and Andre Hedrick.
332typedef unsigned char task_ioreg_t;
333
334typedef struct hd_drive_task_hdr {
335 task_ioreg_t data;
336 task_ioreg_t feature;
337 task_ioreg_t sector_count;
338 task_ioreg_t sector_number;
339 task_ioreg_t low_cylinder;
340 task_ioreg_t high_cylinder;
341 task_ioreg_t device_head;
342 task_ioreg_t command;
343} task_struct_t;
344
345typedef union ide_reg_valid_s {
346 unsigned all : 16;
347 struct {
348 unsigned data : 1;
349 unsigned error_feature : 1;
350 unsigned sector : 1;
351 unsigned nsector : 1;
352 unsigned lcyl : 1;
353 unsigned hcyl : 1;
354 unsigned select : 1;
355 unsigned status_command : 1;
356 unsigned data_hob : 1;
357 unsigned error_feature_hob : 1;
358 unsigned sector_hob : 1;
359 unsigned nsector_hob : 1;
360 unsigned lcyl_hob : 1;
361 unsigned hcyl_hob : 1;
362 unsigned select_hob : 1;
363 unsigned control_hob : 1;
364 } b;
365} ide_reg_valid_t;
366
367typedef struct ide_task_request_s {
368 task_ioreg_t io_ports[8];
369 task_ioreg_t hob_ports[8];
370 ide_reg_valid_t out_flags;
371 ide_reg_valid_t in_flags;
372 int data_phase;
373 int req_cmd;
374 unsigned long out_size;
375 unsigned long in_size;
376} ide_task_request_t;
377
378#define TASKFILE_NO_DATA 0x0000
379#define TASKFILE_IN 0x0001
380#define TASKFILE_OUT 0x0004
381#define HDIO_DRIVE_TASK_HDR_SIZE 8*sizeof(task_ioreg_t)
382#define IDE_DRIVE_TASK_NO_DATA 0
383#define IDE_DRIVE_TASK_IN 2
384#define IDE_DRIVE_TASK_OUT 3
385#define HDIO_DRIVE_CMD 0x031f
386#define HDIO_DRIVE_TASK 0x031e
387#define HDIO_DRIVE_TASKFILE 0x031d
388#define HDIO_GET_IDENTITY 0x030d
389
4d59bff9
GG
390#define HPTIO_CTL 0x03ff // ioctl interface for HighPoint raid device
391
832b75ed 392#endif /* OS_LINUX_H_ */