x86-64: support native xadd rwsem implementation
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / scsi / 3w-sas.h
blobd474892701d4540658a36b48edb7b903a8b9ba76
1 /*
2 3w-sas.h -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
4 Written By: Adam Radford <linuxraid@lsi.com>
6 Copyright (C) 2009 LSI Corporation.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; version 2 of the License.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 NO WARRANTY
18 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
19 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
20 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
21 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
22 solely responsible for determining the appropriateness of using and
23 distributing the Program and assumes all risks associated with its
24 exercise of rights under this Agreement, including but not limited to
25 the risks and costs of program errors, damage to or loss of data,
26 programs or equipment, and unavailability or interruption of operations.
28 DISCLAIMER OF LIABILITY
29 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
30 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
32 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
33 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
34 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
35 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37 You should have received a copy of the GNU General Public License
38 along with this program; if not, write to the Free Software
39 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 Bugs/Comments/Suggestions should be mailed to:
42 linuxraid@lsi.com
44 For more information, goto:
45 http://www.lsi.com
48 #ifndef _3W_SAS_H
49 #define _3W_SAS_H
51 /* AEN severity table */
52 static char *twl_aen_severity_table[] =
54 "None", "ERROR", "WARNING", "INFO", "DEBUG", NULL
57 /* Liberator register offsets */
58 #define TWL_STATUS 0x0 /* Status */
59 #define TWL_HIBDB 0x20 /* Inbound doorbell */
60 #define TWL_HISTAT 0x30 /* Host interrupt status */
61 #define TWL_HIMASK 0x34 /* Host interrupt mask */
62 #define TWL_HOBDB 0x9C /* Outbound doorbell */
63 #define TWL_HOBDBC 0xA0 /* Outbound doorbell clear */
64 #define TWL_SCRPD3 0xBC /* Scratchpad */
65 #define TWL_HIBQPL 0xC0 /* Host inbound Q low */
66 #define TWL_HIBQPH 0xC4 /* Host inbound Q high */
67 #define TWL_HOBQPL 0xC8 /* Host outbound Q low */
68 #define TWL_HOBQPH 0xCC /* Host outbound Q high */
69 #define TWL_HISTATUS_VALID_INTERRUPT 0xC
70 #define TWL_HISTATUS_ATTENTION_INTERRUPT 0x4
71 #define TWL_HISTATUS_RESPONSE_INTERRUPT 0x8
72 #define TWL_STATUS_OVERRUN_SUBMIT 0x2000
73 #define TWL_ISSUE_SOFT_RESET 0x100
74 #define TWL_CONTROLLER_READY 0x2000
75 #define TWL_DOORBELL_CONTROLLER_ERROR 0x200000
76 #define TWL_DOORBELL_ATTENTION_INTERRUPT 0x40000
77 #define TWL_PULL_MODE 0x1
79 /* Command packet opcodes used by the driver */
80 #define TW_OP_INIT_CONNECTION 0x1
81 #define TW_OP_GET_PARAM 0x12
82 #define TW_OP_SET_PARAM 0x13
83 #define TW_OP_EXECUTE_SCSI 0x10
85 /* Asynchronous Event Notification (AEN) codes used by the driver */
86 #define TW_AEN_QUEUE_EMPTY 0x0000
87 #define TW_AEN_SOFT_RESET 0x0001
88 #define TW_AEN_SYNC_TIME_WITH_HOST 0x031
89 #define TW_AEN_SEVERITY_ERROR 0x1
90 #define TW_AEN_SEVERITY_DEBUG 0x4
91 #define TW_AEN_NOT_RETRIEVED 0x1
93 /* Command state defines */
94 #define TW_S_INITIAL 0x1 /* Initial state */
95 #define TW_S_STARTED 0x2 /* Id in use */
96 #define TW_S_POSTED 0x4 /* Posted to the controller */
97 #define TW_S_COMPLETED 0x8 /* Completed by isr */
98 #define TW_S_FINISHED 0x10 /* I/O completely done */
100 /* Compatibility defines */
101 #define TW_9750_ARCH_ID 10
102 #define TW_CURRENT_DRIVER_SRL 40
103 #define TW_CURRENT_DRIVER_BUILD 0
104 #define TW_CURRENT_DRIVER_BRANCH 0
106 /* Phase defines */
107 #define TW_PHASE_INITIAL 0
108 #define TW_PHASE_SGLIST 2
110 /* Misc defines */
111 #define TW_SECTOR_SIZE 512
112 #define TW_MAX_UNITS 32
113 #define TW_INIT_MESSAGE_CREDITS 0x100
114 #define TW_INIT_COMMAND_PACKET_SIZE 0x3
115 #define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6
116 #define TW_EXTENDED_INIT_CONNECT 0x2
117 #define TW_BASE_FW_SRL 24
118 #define TW_BASE_FW_BRANCH 0
119 #define TW_BASE_FW_BUILD 1
120 #define TW_Q_LENGTH 256
121 #define TW_Q_START 0
122 #define TW_MAX_SLOT 32
123 #define TW_MAX_RESET_TRIES 2
124 #define TW_MAX_CMDS_PER_LUN 254
125 #define TW_MAX_AEN_DRAIN 255
126 #define TW_IN_RESET 2
127 #define TW_USING_MSI 3
128 #define TW_IN_ATTENTION_LOOP 4
129 #define TW_MAX_SECTORS 256
130 #define TW_MAX_CDB_LEN 16
131 #define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */
132 #define TW_IOCTL_CHRDEV_FREE -1
133 #define TW_COMMAND_OFFSET 128 /* 128 bytes */
134 #define TW_VERSION_TABLE 0x0402
135 #define TW_TIMEKEEP_TABLE 0x040A
136 #define TW_INFORMATION_TABLE 0x0403
137 #define TW_PARAM_FWVER 3
138 #define TW_PARAM_FWVER_LENGTH 16
139 #define TW_PARAM_BIOSVER 4
140 #define TW_PARAM_BIOSVER_LENGTH 16
141 #define TW_PARAM_MODEL 8
142 #define TW_PARAM_MODEL_LENGTH 16
143 #define TW_PARAM_PHY_SUMMARY_TABLE 1
144 #define TW_PARAM_PHYCOUNT 2
145 #define TW_PARAM_PHYCOUNT_LENGTH 1
146 #define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108 // Used by smartmontools
147 #define TW_ALLOCATION_LENGTH 128
148 #define TW_SENSE_DATA_LENGTH 18
149 #define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED 0x10a
150 #define TW_ERROR_INVALID_FIELD_IN_CDB 0x10d
151 #define TW_ERROR_UNIT_OFFLINE 0x128
152 #define TW_MESSAGE_SOURCE_CONTROLLER_ERROR 3
153 #define TW_MESSAGE_SOURCE_CONTROLLER_EVENT 4
154 #define TW_DRIVER 6
155 #ifndef PCI_DEVICE_ID_3WARE_9750
156 #define PCI_DEVICE_ID_3WARE_9750 0x1010
157 #endif
159 /* Bitmask macros to eliminate bitfields */
161 /* opcode: 5, reserved: 3 */
162 #define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f))
163 #define TW_OP_OUT(x) (x & 0x1f)
165 /* opcode: 5, sgloffset: 3 */
166 #define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))
167 #define TW_SGL_OUT(x) ((x >> 5) & 0x7)
169 /* severity: 3, reserved: 5 */
170 #define TW_SEV_OUT(x) (x & 0x7)
172 /* not_mfa: 1, reserved: 7, status: 8, request_id: 16 */
173 #define TW_RESID_OUT(x) ((x >> 16) & 0xffff)
174 #define TW_NOTMFA_OUT(x) (x & 0x1)
176 /* request_id: 12, lun: 4 */
177 #define TW_REQ_LUN_IN(lun, request_id) (((lun << 12) & 0xf000) | (request_id & 0xfff))
178 #define TW_LUN_OUT(lun) ((lun >> 12) & 0xf)
180 /* Register access macros */
181 #define TWL_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_STATUS)
182 #define TWL_HOBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPL)
183 #define TWL_HOBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPH)
184 #define TWL_HOBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDB)
185 #define TWL_HOBDBC_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDBC)
186 #define TWL_HIMASK_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIMASK)
187 #define TWL_HISTAT_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HISTAT)
188 #define TWL_HIBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPH)
189 #define TWL_HIBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPL)
190 #define TWL_HIBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBDB)
191 #define TWL_SCRPD3_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_SCRPD3)
192 #define TWL_MASK_INTERRUPTS(x) (writel(~0, TWL_HIMASK_REG_ADDR(tw_dev)))
193 #define TWL_UNMASK_INTERRUPTS(x) (writel(~TWL_HISTATUS_VALID_INTERRUPT, TWL_HIMASK_REG_ADDR(tw_dev)))
194 #define TWL_CLEAR_DB_INTERRUPT(x) (writel(~0, TWL_HOBDBC_REG_ADDR(tw_dev)))
195 #define TWL_SOFT_RESET(x) (writel(TWL_ISSUE_SOFT_RESET, TWL_HIBDB_REG_ADDR(tw_dev)))
197 /* Macros */
198 #define TW_PRINTK(h,a,b,c) { \
199 if (h) \
200 printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \
201 else \
202 printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \
204 #define TW_MAX_LUNS 16
205 #define TW_COMMAND_SIZE (sizeof(dma_addr_t) > 4 ? 6 : 4)
206 #define TW_LIBERATOR_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 46 : 92)
207 #define TW_LIBERATOR_MAX_SGL_LENGTH_OLD (sizeof(dma_addr_t) > 4 ? 47 : 94)
208 #define TW_PADDING_LENGTH_LIBERATOR 136
209 #define TW_PADDING_LENGTH_LIBERATOR_OLD 132
210 #define TW_CPU_TO_SGL(x) (sizeof(dma_addr_t) > 4 ? cpu_to_le64(x) : cpu_to_le32(x))
212 #pragma pack(1)
214 /* SGL entry */
215 typedef struct TAG_TW_SG_Entry_ISO {
216 dma_addr_t address;
217 dma_addr_t length;
218 } TW_SG_Entry_ISO;
220 /* Old Command Packet with ISO SGL */
221 typedef struct TW_Command {
222 unsigned char opcode__sgloffset;
223 unsigned char size;
224 unsigned char request_id;
225 unsigned char unit__hostid;
226 /* Second DWORD */
227 unsigned char status;
228 unsigned char flags;
229 union {
230 unsigned short block_count;
231 unsigned short parameter_count;
232 } byte6_offset;
233 union {
234 struct {
235 u32 lba;
236 TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];
237 unsigned char padding[TW_PADDING_LENGTH_LIBERATOR_OLD];
238 } io;
239 struct {
240 TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];
241 u32 padding;
242 unsigned char padding2[TW_PADDING_LENGTH_LIBERATOR_OLD];
243 } param;
244 } byte8_offset;
245 } TW_Command;
247 /* New Command Packet with ISO SGL */
248 typedef struct TAG_TW_Command_Apache {
249 unsigned char opcode__reserved;
250 unsigned char unit;
251 unsigned short request_id__lunl;
252 unsigned char status;
253 unsigned char sgl_offset;
254 unsigned short sgl_entries__lunh;
255 unsigned char cdb[16];
256 TW_SG_Entry_ISO sg_list[TW_LIBERATOR_MAX_SGL_LENGTH];
257 unsigned char padding[TW_PADDING_LENGTH_LIBERATOR];
258 } TW_Command_Apache;
260 /* New command packet header */
261 typedef struct TAG_TW_Command_Apache_Header {
262 unsigned char sense_data[TW_SENSE_DATA_LENGTH];
263 struct {
264 char reserved[4];
265 unsigned short error;
266 unsigned char padding;
267 unsigned char severity__reserved;
268 } status_block;
269 unsigned char err_specific_desc[98];
270 struct {
271 unsigned char size_header;
272 unsigned short request_id;
273 unsigned char size_sense;
274 } header_desc;
275 } TW_Command_Apache_Header;
277 /* This struct is a union of the 2 command packets */
278 typedef struct TAG_TW_Command_Full {
279 TW_Command_Apache_Header header;
280 union {
281 TW_Command oldcommand;
282 TW_Command_Apache newcommand;
283 } command;
284 } TW_Command_Full;
286 /* Initconnection structure */
287 typedef struct TAG_TW_Initconnect {
288 unsigned char opcode__reserved;
289 unsigned char size;
290 unsigned char request_id;
291 unsigned char res2;
292 unsigned char status;
293 unsigned char flags;
294 unsigned short message_credits;
295 u32 features;
296 unsigned short fw_srl;
297 unsigned short fw_arch_id;
298 unsigned short fw_branch;
299 unsigned short fw_build;
300 u32 result;
301 } TW_Initconnect;
303 /* Event info structure */
304 typedef struct TAG_TW_Event
306 unsigned int sequence_id;
307 unsigned int time_stamp_sec;
308 unsigned short aen_code;
309 unsigned char severity;
310 unsigned char retrieved;
311 unsigned char repeat_count;
312 unsigned char parameter_len;
313 unsigned char parameter_data[98];
314 } TW_Event;
316 typedef struct TAG_TW_Ioctl_Driver_Command {
317 unsigned int control_code;
318 unsigned int status;
319 unsigned int unique_id;
320 unsigned int sequence_id;
321 unsigned int os_specific;
322 unsigned int buffer_length;
323 } TW_Ioctl_Driver_Command;
325 typedef struct TAG_TW_Ioctl_Apache {
326 TW_Ioctl_Driver_Command driver_command;
327 char padding[488];
328 TW_Command_Full firmware_command;
329 char data_buffer[1];
330 } TW_Ioctl_Buf_Apache;
332 /* GetParam descriptor */
333 typedef struct {
334 unsigned short table_id;
335 unsigned short parameter_id;
336 unsigned short parameter_size_bytes;
337 unsigned short actual_parameter_size_bytes;
338 unsigned char data[1];
339 } TW_Param_Apache;
341 /* Compatibility information structure */
342 typedef struct TAG_TW_Compatibility_Info
344 char driver_version[32];
345 unsigned short working_srl;
346 unsigned short working_branch;
347 unsigned short working_build;
348 unsigned short driver_srl_high;
349 unsigned short driver_branch_high;
350 unsigned short driver_build_high;
351 unsigned short driver_srl_low;
352 unsigned short driver_branch_low;
353 unsigned short driver_build_low;
354 unsigned short fw_on_ctlr_srl;
355 unsigned short fw_on_ctlr_branch;
356 unsigned short fw_on_ctlr_build;
357 } TW_Compatibility_Info;
359 #pragma pack()
361 typedef struct TAG_TW_Device_Extension {
362 void __iomem *base_addr;
363 unsigned long *generic_buffer_virt[TW_Q_LENGTH];
364 dma_addr_t generic_buffer_phys[TW_Q_LENGTH];
365 TW_Command_Full *command_packet_virt[TW_Q_LENGTH];
366 dma_addr_t command_packet_phys[TW_Q_LENGTH];
367 TW_Command_Apache_Header *sense_buffer_virt[TW_Q_LENGTH];
368 dma_addr_t sense_buffer_phys[TW_Q_LENGTH];
369 struct pci_dev *tw_pci_dev;
370 struct scsi_cmnd *srb[TW_Q_LENGTH];
371 unsigned char free_queue[TW_Q_LENGTH];
372 unsigned char free_head;
373 unsigned char free_tail;
374 int state[TW_Q_LENGTH];
375 unsigned int posted_request_count;
376 unsigned int max_posted_request_count;
377 unsigned int max_sgl_entries;
378 unsigned int sgl_entries;
379 unsigned int num_resets;
380 unsigned int sector_count;
381 unsigned int max_sector_count;
382 unsigned int aen_count;
383 struct Scsi_Host *host;
384 long flags;
385 TW_Event *event_queue[TW_Q_LENGTH];
386 unsigned char error_index;
387 unsigned int error_sequence_id;
388 int chrdev_request_id;
389 wait_queue_head_t ioctl_wqueue;
390 struct mutex ioctl_lock;
391 TW_Compatibility_Info tw_compat_info;
392 char online;
393 } TW_Device_Extension;
395 #endif /* _3W_SAS_H */