File: /usr/src/linux/drivers/scsi/3w-xxxx.h
1 /*
2 3w-xxxx.h -- 3ware Storage Controller device driver for Linux.
3
4 Written By: Adam Radford <linux@3ware.com>
5 Modifications By: Joel Jacobson <linux@3ware.com>
6 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
7
8 Copyright (C) 1999-2001 3ware Inc.
9
10 Kernel compatablity By: Andre Hedrick <andre@suse.com>
11 Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com>
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; version 2 of the License.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 NO WARRANTY
23 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
24 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
25 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
26 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
27 solely responsible for determining the appropriateness of using and
28 distributing the Program and assumes all risks associated with its
29 exercise of rights under this Agreement, including but not limited to
30 the risks and costs of program errors, damage to or loss of data,
31 programs or equipment, and unavailability or interruption of operations.
32
33 DISCLAIMER OF LIABILITY
34 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
35 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
37 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
38 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
39 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
40 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
41
42 You should have received a copy of the GNU General Public License
43 along with this program; if not, write to the Free Software
44 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
45
46 Bugs/Comments/Suggestions should be mailed to:
47 linux@3ware.com
48
49 For more information, goto:
50 http://www.3ware.com
51 */
52
53 #ifndef _3W_XXXX_H
54 #define _3W_XXXX_H
55
56 #include <linux/version.h>
57 #include <linux/types.h>
58 #include <linux/kdev_t.h>
59
60 /* Control register bit definitions */
61 #define TW_CONTROL_CLEAR_HOST_INTERRUPT 0x00080000
62 #define TW_CONTROL_CLEAR_ATTENTION_INTERRUPT 0x00040000
63 #define TW_CONTROL_MASK_COMMAND_INTERRUPT 0x00020000
64 #define TW_CONTROL_MASK_RESPONSE_INTERRUPT 0x00010000
65 #define TW_CONTROL_UNMASK_COMMAND_INTERRUPT 0x00008000
66 #define TW_CONTROL_UNMASK_RESPONSE_INTERRUPT 0x00004000
67 #define TW_CONTROL_CLEAR_ERROR_STATUS 0x00000200
68 #define TW_CONTROL_ISSUE_SOFT_RESET 0x00000100
69 #define TW_CONTROL_ENABLE_INTERRUPTS 0x00000080
70 #define TW_CONTROL_DISABLE_INTERRUPTS 0x00000040
71 #define TW_CONTROL_ISSUE_HOST_INTERRUPT 0x00000020
72 #define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000
73
74 /* Status register bit definitions */
75 #define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000
76 #define TW_STATUS_MINOR_VERSION_MASK 0x0F000000
77 #define TW_STATUS_PCI_PARITY_ERROR 0x00800000
78 #define TW_STATUS_QUEUE_ERROR 0x00400000
79 #define TW_STATUS_MICROCONTROLLER_ERROR 0x00200000
80 #define TW_STATUS_PCI_ABORT 0x00100000
81 #define TW_STATUS_HOST_INTERRUPT 0x00080000
82 #define TW_STATUS_ATTENTION_INTERRUPT 0x00040000
83 #define TW_STATUS_COMMAND_INTERRUPT 0x00020000
84 #define TW_STATUS_RESPONSE_INTERRUPT 0x00010000
85 #define TW_STATUS_COMMAND_QUEUE_FULL 0x00008000
86 #define TW_STATUS_RESPONSE_QUEUE_EMPTY 0x00004000
87 #define TW_STATUS_MICROCONTROLLER_READY 0x00002000
88 #define TW_STATUS_COMMAND_QUEUE_EMPTY 0x00001000
89 #define TW_STATUS_ALL_INTERRUPTS 0x000F0000
90 #define TW_STATUS_CLEARABLE_BITS 0x00D00000
91 #define TW_STATUS_EXPECTED_BITS 0x00002000
92 #define TW_STATUS_UNEXPECTED_BITS 0x00F80000
93
94 /* RESPONSE QUEUE BIT DEFINITIONS */
95 #define TW_RESPONSE_ID_MASK 0x00000FF0
96
97 /* PCI related defines */
98 #define TW_IO_ADDRESS_RANGE 0xD
99 #define TW_DEVICE_NAME "3ware Storage Controller"
100 #define TW_VENDOR_ID (0x13C1) /* 3ware */
101 #define TW_DEVICE_ID (0x1000) /* Storage Controller */
102 #define TW_DEVICE_ID2 (0x1001) /* 7000 series controller */
103 #define TW_NUMDEVICES 2
104 #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
105
106 /* Command packet opcodes */
107 #define TW_OP_NOP 0x0
108 #define TW_OP_INIT_CONNECTION 0x1
109 #define TW_OP_READ 0x2
110 #define TW_OP_WRITE 0x3
111 #define TW_OP_VERIFY 0x4
112 #define TW_OP_GET_PARAM 0x12
113 #define TW_OP_SET_PARAM 0x13
114 #define TW_OP_SECTOR_INFO 0x1a
115 #define TW_OP_AEN_LISTEN 0x1c
116 #define TW_CMD_PACKET 0x1d
117
118 /* Asynchronous Event Notification (AEN) Codes */
119 #define TW_AEN_QUEUE_EMPTY 0x0000
120 #define TW_AEN_SOFT_RESET 0x0001
121 #define TW_AEN_DEGRADED_MIRROR 0x0002
122 #define TW_AEN_CONTROLLER_ERROR 0x0003
123 #define TW_AEN_REBUILD_FAIL 0x0004
124 #define TW_AEN_REBUILD_DONE 0x0005
125 #define TW_AEN_QUEUE_FULL 0x00ff
126 #define TW_AEN_TABLE_UNDEFINED 0x15
127 #define TW_AEN_APORT_TIMEOUT 0x0009
128 #define TW_AEN_DRIVE_ERROR 0x000A
129 #define TW_AEN_SMART_FAIL 0x000F
130 #define TW_AEN_SBUF_FAIL 0x0024
131
132 /* Misc defines */
133 #define TW_ALIGNMENT 0x200 /* 16 D-WORDS */
134 #define TW_MAX_UNITS 16
135 #define TW_COMMAND_ALIGNMENT_MASK 0x1ff
136 #define TW_INIT_MESSAGE_CREDITS 0x100
137 #define TW_INIT_COMMAND_PACKET_SIZE 0x3
138 #define TW_POLL_MAX_RETRIES 20000
139 #define TW_MAX_SGL_LENGTH 62
140 #define TW_Q_LENGTH 16
141 #define TW_Q_START 0
142 #define TW_MAX_SLOT 32
143 #define TW_MAX_PCI_BUSES 255
144 #define TW_MAX_RESET_TRIES 3
145 #define TW_UNIT_INFORMATION_TABLE_BASE 0x300
146 #define TW_MAX_CMDS_PER_LUN (TW_Q_LENGTH-2)/TW_MAX_UNITS
147 #define TW_BLOCK_SIZE 0x200 /* 512-byte blocks */
148 #define TW_IOCTL 0x80
149 #define TW_MAX_AEN_TRIES 100
150 #define TW_UNIT_ONLINE 1
151 #define TW_IN_INTR 1
152 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,7)
153 #define TW_MAX_SECTORS 256
154 #else
155 #define TW_MAX_SECTORS 128
156 #endif
157 #define TW_AEN_WAIT_TIME 1000
158
159 /* Macros */
160 #define TW_STATUS_ERRORS(x) \
161 (((x & TW_STATUS_PCI_ABORT) || \
162 (x & TW_STATUS_PCI_PARITY_ERROR) || \
163 (x & TW_STATUS_QUEUE_ERROR) || \
164 (x & TW_STATUS_MICROCONTROLLER_ERROR)) && \
165 (x & TW_STATUS_MICROCONTROLLER_READY))
166
167 #ifdef TW_DEBUG
168 #define dprintk(msg...) printk(msg)
169 #else
170 #define dprintk(msg...) do { } while(0);
171 #endif
172
173 /* Scatter Gather List Entry */
174 typedef struct TAG_TW_SG_Entry {
175 unsigned long address;
176 unsigned long length;
177 } TW_SG_Entry;
178
179 typedef unsigned char TW_Sector[512];
180
181 /* Command Packet */
182 typedef struct TW_Command {
183 /* First DWORD */
184 struct {
185 unsigned char opcode:5;
186 unsigned char sgl_offset:3;
187 } byte0;
188 unsigned char size;
189 unsigned char request_id;
190 struct {
191 unsigned char unit:4;
192 unsigned char host_id:4;
193 } byte3;
194 /* Second DWORD */
195 unsigned char status;
196 unsigned char flags;
197 union {
198 unsigned short block_count;
199 unsigned short parameter_count;
200 unsigned short message_credits;
201 } byte6;
202 union {
203 struct {
204 unsigned long lba;
205 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
206 unsigned long padding; /* pad to 512 bytes */
207 } io;
208 struct {
209 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
210 unsigned long padding[2];
211 } param;
212 struct {
213 unsigned long response_queue_pointer;
214 unsigned long padding[125];
215 } init_connection;
216 struct {
217 char version[504];
218 } ioctl_miniport_version;
219 } byte8;
220 } TW_Command;
221
222 typedef struct TAG_TW_Ioctl {
223 int buffer;
224 unsigned char opcode;
225 unsigned short table_id;
226 unsigned char parameter_id;
227 unsigned char parameter_size_bytes;
228 unsigned char data[1];
229 } TW_Ioctl;
230
231 /* GetParam descriptor */
232 typedef struct {
233 unsigned short table_id;
234 unsigned char parameter_id;
235 unsigned char parameter_size_bytes;
236 unsigned char data[1];
237 } TW_Param, *PTW_Param;
238
239 /* Response queue */
240 typedef union TAG_TW_Response_Queue {
241 struct {
242 u32 undefined_1: 4;
243 u32 response_id: 8;
244 u32 undefined_2: 20;
245 } u;
246 u32 value;
247 } TW_Response_Queue;
248
249 typedef struct TAG_TW_Registers {
250 u32 base_addr;
251 u32 control_reg_addr;
252 u32 status_reg_addr;
253 u32 command_que_addr;
254 u32 response_que_addr;
255 } TW_Registers;
256
257 typedef struct TAG_TW_Info {
258 char *buffer;
259 int length;
260 int offset;
261 int position;
262 } TW_Info;
263
264 typedef enum TAG_TW_Cmd_State {
265 TW_S_INITIAL, /* Initial state */
266 TW_S_STARTED, /* Id in use */
267 TW_S_POSTED, /* Posted to the controller */
268 TW_S_PENDING, /* Waiting to be posted in isr */
269 TW_S_COMPLETED, /* Completed by isr */
270 TW_S_FINISHED, /* I/O completely done */
271 } TW_Cmd_State;
272
273 typedef struct TAG_TW_Device_Extension {
274 TW_Registers registers;
275 u32 *alignment_virtual_address[TW_Q_LENGTH];
276 u32 alignment_physical_address[TW_Q_LENGTH];
277 u32 *bounce_buffer[TW_Q_LENGTH];
278 int is_unit_present[TW_MAX_UNITS];
279 int is_raid_five[TW_MAX_UNITS];
280 int num_units;
281 int num_raid_five;
282 u32 *command_packet_virtual_address[TW_Q_LENGTH];
283 u32 command_packet_physical_address[TW_Q_LENGTH];
284 struct pci_dev *tw_pci_dev;
285 Scsi_Cmnd *srb[TW_Q_LENGTH];
286 unsigned char free_queue[TW_Q_LENGTH];
287 unsigned char free_head;
288 unsigned char free_tail;
289 unsigned char pending_queue[TW_Q_LENGTH];
290 unsigned char pending_head;
291 unsigned char pending_tail;
292 TW_Cmd_State state[TW_Q_LENGTH];
293 u32 posted_request_count;
294 u32 max_posted_request_count;
295 u32 request_count_marked_pending;
296 u32 pending_request_count;
297 u32 max_pending_request_count;
298 u32 max_sgl_entries;
299 u32 sgl_entries;
300 u32 num_aborts;
301 u32 num_resets;
302 u32 sector_count;
303 u32 max_sector_count;
304 u32 aen_count;
305 struct Scsi_Host *host;
306 spinlock_t tw_lock;
307 unsigned char ioctl_size[TW_Q_LENGTH];
308 unsigned short aen_queue[TW_Q_LENGTH];
309 unsigned char aen_head;
310 unsigned char aen_tail;
311 long flags; /* long req'd for set_bit --RR */
312 } TW_Device_Extension;
313
314 /* Function prototypes */
315 int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id);
316 int tw_aen_drain_queue(TW_Device_Extension *tw_dev);
317 int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id);
318 int tw_allocate_memory(TW_Device_Extension *tw_dev, int request_id, int size, int which);
319 int tw_check_bits(u32 status_reg_value);
320 int tw_check_errors(TW_Device_Extension *tw_dev);
321 void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev);
322 void tw_clear_host_interrupt(TW_Device_Extension *tw_dev);
323 void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value);
324 void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit);
325 void tw_disable_interrupts(TW_Device_Extension *tw_dev);
326 int tw_empty_response_que(TW_Device_Extension *tw_dev);
327 void tw_enable_interrupts(TW_Device_Extension *tw_dev);
328 int tw_findcards(Scsi_Host_Template *tw_host);
329 void tw_free_device_extension(TW_Device_Extension *tw_dev);
330 int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits);
331 int tw_initialize_device_extension(TW_Device_Extension *tw_dev);
332 int tw_initialize_units(TW_Device_Extension *tw_dev);
333 int tw_ioctl(TW_Device_Extension *tw_dev, int request_id);
334 int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id);
335 void tw_mask_command_interrupt(TW_Device_Extension *tw_dev);
336 int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds);
337 int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id);
338 int tw_reset_device_extension(TW_Device_Extension *tw_dev);
339 int tw_reset_sequence(TW_Device_Extension *tw_dev);
340 int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[]);
341 int tw_scsi_detect(Scsi_Host_Template *tw_host);
342 int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt);
343 int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt);
344 int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int inode, int inout);
345 int tw_scsi_queue(Scsi_Cmnd *cmd, void (*done) (Scsi_Cmnd *));
346 int tw_scsi_release(struct Scsi_Host *tw_host);
347 int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id);
348 int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id);
349 int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id);
350 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id);
351 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id);
352 int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id);
353 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id);
354 int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
355 unsigned char *val);
356 int tw_setup_irq(TW_Device_Extension *tw_dev);
357 int tw_shutdown_device(TW_Device_Extension *tw_dev);
358 void tw_soft_reset(TW_Device_Extension *tw_dev);
359 int tw_state_request_finish(TW_Device_Extension *tw_dev,int request_id);
360 int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id);
361 void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev);
362
363 /* Scsi_Host_Template Initializer */
364 #define TWXXXX { \
365 next : NULL, \
366 module : NULL, \
367 proc_name : "3w-xxxx", \
368 proc_info : tw_scsi_proc_info, \
369 name : "3ware Storage Controller", \
370 detect : tw_scsi_detect, \
371 release : tw_scsi_release, \
372 info : NULL, \
373 ioctl : NULL, \
374 command : NULL, \
375 queuecommand : tw_scsi_queue, \
376 eh_strategy_handler : NULL, \
377 eh_abort_handler : tw_scsi_eh_abort, \
378 eh_device_reset_handler : NULL, \
379 eh_bus_reset_handler : NULL, \
380 eh_host_reset_handler : tw_scsi_eh_reset, \
381 abort : NULL, \
382 reset : NULL, \
383 slave_attach : NULL, \
384 bios_param : tw_scsi_biosparam, \
385 can_queue : TW_Q_LENGTH, \
386 this_id: -1, \
387 sg_tablesize : TW_MAX_SGL_LENGTH, \
388 cmd_per_lun: TW_MAX_CMDS_PER_LUN, \
389 present : 0, \
390 unchecked_isa_dma : 0, \
391 use_clustering : ENABLE_CLUSTERING, \
392 use_new_eh_code : 1, \
393 emulated : 1 \
394 }
395 #endif /* _3W_XXXX_H */
396