4 * Home page of code is: http://www.smartmontools.org
6 * Copyright (C) 2003-8 Bruce Allen
8 * Derived from code that was
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>
15 * Copyright (C) 1999-2003 3ware Inc.
17 * Kernel compatibility By: Andre Hedrick <andre@suse.com>
18 * Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com>
20 * SPDX-License-Identifier: GPL-2.0-or-later
27 #define OS_LINUX_H_CVSID "$Id: os_linux.h 4842 2018-12-02 16:07:26Z chrfranke $\n"
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?
37 // USED FOR ALL THREE CASES
39 #define u32 unsigned int
40 #define TW_OP_ATA_PASSTHRU 0x11
41 #define MAX(x,y) ( (x)>(y)?(x):(y) )
44 /* Scatter gather list entry */
45 typedef struct TAG_TW_SG_Entry
{
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! */
56 #define TW_ATA_PASS_SGL_MAX 60
58 typedef struct TAG_TW_Passthru
{
60 unsigned char opcode
:5;
61 unsigned char sgloff
:3;
64 unsigned char request_id
;
66 unsigned char status
; // On return, contains 3ware STATUS register
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];
80 // the following are for the SCSI interface only
82 // Ioctl buffer: Note that this defn has changed in kernel tree...
83 // Total size is 1041 bytes -- this is really weird
86 #define TW_ATA_PASSTHRU 0x1e
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
{
94 unsigned char cdb
[16];
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
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.
113 /* Ioctl buffer output -- SCSI interface only! */
114 typedef struct TAG_TW_Output
{
116 char output_data
[512];
119 // What follows is needed for 9000 char interface only
121 #define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108
122 #define TW_MAX_SGL_LENGTH_9000 61
124 typedef struct TAG_TW_Ioctl_Driver_Command_9000
{
125 unsigned int control_code
;
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
;
134 typedef struct TW_Command_9000
{
137 unsigned char opcode
:5;
138 unsigned char sgl_offset
:3;
141 unsigned char request_id
;
143 unsigned char unit
:4;
144 unsigned char host_id
:4;
147 unsigned char status
;
150 unsigned short block_count
;
151 unsigned short parameter_count
;
152 unsigned short message_credits
;
157 TW_SG_Entry sgl
[TW_MAX_SGL_LENGTH_9000
];
161 TW_SG_Entry sgl
[TW_MAX_SGL_LENGTH_9000
];
165 u32 response_queue_pointer
;
166 u32 padding
[125]; /* pad entire structure to 512 bytes */
170 } ioctl_miniport_version
;
174 /* Command Packet for 9000+ controllers */
175 typedef struct TAG_TW_Command_Apache
{
177 unsigned char opcode
:5;
178 unsigned char reserved
:3;
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
];
189 /* New command packet header */
190 typedef struct TAG_TW_Command_Apache_Header
{
191 unsigned char sense_data
[18];
194 unsigned short error
;
195 unsigned char status
;
197 unsigned char severity
:3;
198 unsigned char reserved
:5;
201 unsigned char err_specific_desc
[102];
202 } TW_Command_Apache_Header
;
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
;
208 TW_Command_9000 oldcommand
;
209 TW_Command_Apache newcommand
;
211 unsigned char padding
[384]; /* Pad to 1024 bytes */
212 } TW_Command_Full_9000
;
214 typedef struct TAG_TW_Ioctl_Apache
{
215 TW_Ioctl_Driver_Command_9000 driver_command
;
217 TW_Command_Full_9000 firmware_command
;
219 // three bytes of padding here if structure not packed!
220 } TW_Ioctl_Buf_Apache
;
224 // START OF DEFINITIONS FOR THE CHARACTER INTERFACE TO THE
225 // 6000/7000/8000 drivers
227 #define TW_MAX_SGL_LENGTH 62
228 #define TW_CMD_PACKET_WITH_DATA 0x1f
231 typedef struct TW_Command
{
234 unsigned char opcode
:5;
235 unsigned char sgl_offset
:3;
238 unsigned char request_id
;
240 unsigned char unit
:4;
241 unsigned char host_id
:4;
244 unsigned char status
;
247 unsigned short block_count
;
248 unsigned short parameter_count
;
249 unsigned short message_credits
;
254 TW_SG_Entry sgl
[TW_MAX_SGL_LENGTH
];
255 u32 padding
; /* pad to 512 bytes */
258 TW_SG_Entry sgl
[TW_MAX_SGL_LENGTH
];
262 u32 response_queue_pointer
;
267 } ioctl_miniport_version
;
271 typedef struct TAG_TW_New_Ioctl
{
272 unsigned int data_buffer_length
;
273 unsigned char padding
[508];
274 TW_Command firmware_command
;
276 // three bytes of padding here
281 // Useful for checking/understanding packing of 3ware data structures
283 void my(int x
, char *y
){
284 printf("The size of %30s is: %5d\n",y
, x
);
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
);
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
;
317 typedef struct hd_drive_task_hdr
{
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
;
328 typedef union ide_reg_valid_s
{
332 unsigned error_feature
: 1;
334 unsigned nsector
: 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;
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
;
357 unsigned long out_size
;
358 unsigned long in_size
;
359 } ide_task_request_t
;
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
373 #define HPTIO_CTL 0x03ff // ioctl interface for HighPoint raid device
375 #endif /* OS_LINUX_H_ */