1/*
2   3w-sas.h -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
3
4   Written By: Adam Radford <linuxraid@lsi.com>
5
6   Copyright (C) 2009 LSI Corporation.
7
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.
11
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.
16
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.
27
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
36
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
40
41   Bugs/Comments/Suggestions should be mailed to:
42   linuxraid@lsi.com
43
44   For more information, goto:
45   http://www.lsi.com
46*/
47
48#ifndef _3W_SAS_H
49#define _3W_SAS_H
50
51/* AEN severity table */
52static char *twl_aen_severity_table[] =
53{
54	"None", "ERROR", "WARNING", "INFO", "DEBUG", NULL
55};
56
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
78
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
84
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
92
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 */
99
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
105
106/* Misc defines */
107#define TW_SECTOR_SIZE                        512
108#define TW_MAX_UNITS			      32
109#define TW_INIT_MESSAGE_CREDITS		      0x100
110#define TW_INIT_COMMAND_PACKET_SIZE	      0x3
111#define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED  0x6
112#define TW_EXTENDED_INIT_CONNECT	      0x2
113#define TW_BASE_FW_SRL			      24
114#define TW_BASE_FW_BRANCH		      0
115#define TW_BASE_FW_BUILD		      1
116#define TW_Q_LENGTH			      256
117#define TW_Q_START			      0
118#define TW_MAX_SLOT			      32
119#define TW_MAX_RESET_TRIES		      2
120#define TW_MAX_CMDS_PER_LUN		      254
121#define TW_MAX_AEN_DRAIN		      255
122#define TW_IN_RESET                           2
123#define TW_USING_MSI			      3
124#define TW_IN_ATTENTION_LOOP		      4
125#define TW_MAX_SECTORS                        256
126#define TW_MAX_CDB_LEN                        16
127#define TW_IOCTL_CHRDEV_TIMEOUT               60 /* 60 seconds */
128#define TW_IOCTL_CHRDEV_FREE                  -1
129#define TW_COMMAND_OFFSET                     128 /* 128 bytes */
130#define TW_VERSION_TABLE                      0x0402
131#define TW_TIMEKEEP_TABLE		      0x040A
132#define TW_INFORMATION_TABLE		      0x0403
133#define TW_PARAM_FWVER			      3
134#define TW_PARAM_FWVER_LENGTH		      16
135#define TW_PARAM_BIOSVER		      4
136#define TW_PARAM_BIOSVER_LENGTH		      16
137#define TW_PARAM_MODEL			      8
138#define TW_PARAM_MODEL_LENGTH		      16
139#define TW_PARAM_PHY_SUMMARY_TABLE	      1
140#define TW_PARAM_PHYCOUNT		      2
141#define TW_PARAM_PHYCOUNT_LENGTH	      1
142#define TW_IOCTL_FIRMWARE_PASS_THROUGH        0x108  // Used by smartmontools
143#define TW_ALLOCATION_LENGTH		      128
144#define TW_SENSE_DATA_LENGTH		      18
145#define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED   0x10a
146#define TW_ERROR_INVALID_FIELD_IN_CDB	      0x10d
147#define TW_ERROR_UNIT_OFFLINE                 0x128
148#define TW_MESSAGE_SOURCE_CONTROLLER_ERROR    3
149#define TW_MESSAGE_SOURCE_CONTROLLER_EVENT    4
150#define TW_DRIVER 			      6
151#ifndef PCI_DEVICE_ID_3WARE_9750
152#define PCI_DEVICE_ID_3WARE_9750 0x1010
153#endif
154
155/* Bitmask macros to eliminate bitfields */
156
157/* opcode: 5, reserved: 3 */
158#define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f))
159#define TW_OP_OUT(x) (x & 0x1f)
160
161/* opcode: 5, sgloffset: 3 */
162#define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))
163#define TW_SGL_OUT(x) ((x >> 5) & 0x7)
164
165/* severity: 3, reserved: 5 */
166#define TW_SEV_OUT(x) (x & 0x7)
167
168/* not_mfa: 1, reserved: 7, status: 8, request_id: 16 */
169#define TW_RESID_OUT(x) ((x >> 16) & 0xffff)
170#define TW_NOTMFA_OUT(x) (x & 0x1)
171
172/* request_id: 12, lun: 4 */
173#define TW_REQ_LUN_IN(lun, request_id) (((lun << 12) & 0xf000) | (request_id & 0xfff))
174#define TW_LUN_OUT(lun) ((lun >> 12) & 0xf)
175
176/* Register access macros */
177#define TWL_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_STATUS)
178#define TWL_HOBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPL)
179#define TWL_HOBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPH)
180#define TWL_HOBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDB)
181#define TWL_HOBDBC_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDBC)
182#define TWL_HIMASK_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIMASK)
183#define TWL_HISTAT_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HISTAT)
184#define TWL_HIBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPH)
185#define TWL_HIBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPL)
186#define TWL_HIBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBDB)
187#define TWL_SCRPD3_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_SCRPD3)
188#define TWL_MASK_INTERRUPTS(x) (writel(~0, TWL_HIMASK_REG_ADDR(tw_dev)))
189#define TWL_UNMASK_INTERRUPTS(x) (writel(~TWL_HISTATUS_VALID_INTERRUPT, TWL_HIMASK_REG_ADDR(tw_dev)))
190#define TWL_CLEAR_DB_INTERRUPT(x) (writel(~0, TWL_HOBDBC_REG_ADDR(tw_dev)))
191#define TWL_SOFT_RESET(x) (writel(TWL_ISSUE_SOFT_RESET, TWL_HIBDB_REG_ADDR(tw_dev)))
192
193/* Macros */
194#define TW_PRINTK(h,a,b,c) { \
195if (h) \
196printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \
197else \
198printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \
199}
200#define TW_MAX_LUNS 16
201#define TW_COMMAND_SIZE (sizeof(dma_addr_t) > 4 ? 6 : 4)
202#define TW_LIBERATOR_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 46 : 92)
203#define TW_LIBERATOR_MAX_SGL_LENGTH_OLD (sizeof(dma_addr_t) > 4 ? 47 : 94)
204#define TW_PADDING_LENGTH_LIBERATOR 136
205#define TW_PADDING_LENGTH_LIBERATOR_OLD 132
206#define TW_CPU_TO_SGL(x) (sizeof(dma_addr_t) > 4 ? cpu_to_le64(x) : cpu_to_le32(x))
207
208#pragma pack(1)
209
210/* SGL entry */
211typedef struct TAG_TW_SG_Entry_ISO {
212	dma_addr_t address;
213	dma_addr_t length;
214} TW_SG_Entry_ISO;
215
216/* Old Command Packet with ISO SGL */
217typedef struct TW_Command {
218	unsigned char opcode__sgloffset;
219	unsigned char size;
220	unsigned char request_id;
221	unsigned char unit__hostid;
222	/* Second DWORD */
223	unsigned char status;
224	unsigned char flags;
225	union {
226		unsigned short block_count;
227		unsigned short parameter_count;
228	} byte6_offset;
229	union {
230		struct {
231			u32 lba;
232			TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];
233			unsigned char padding[TW_PADDING_LENGTH_LIBERATOR_OLD];
234		} io;
235		struct {
236			TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];
237			u32 padding;
238			unsigned char padding2[TW_PADDING_LENGTH_LIBERATOR_OLD];
239		} param;
240	} byte8_offset;
241} TW_Command;
242
243/* New Command Packet with ISO SGL */
244typedef struct TAG_TW_Command_Apache {
245	unsigned char opcode__reserved;
246	unsigned char unit;
247	unsigned short request_id__lunl;
248	unsigned char status;
249	unsigned char sgl_offset;
250	unsigned short sgl_entries__lunh;
251	unsigned char cdb[16];
252	TW_SG_Entry_ISO sg_list[TW_LIBERATOR_MAX_SGL_LENGTH];
253	unsigned char padding[TW_PADDING_LENGTH_LIBERATOR];
254} TW_Command_Apache;
255
256/* New command packet header */
257typedef struct TAG_TW_Command_Apache_Header {
258	unsigned char sense_data[TW_SENSE_DATA_LENGTH];
259	struct {
260		char reserved[4];
261		unsigned short error;
262		unsigned char padding;
263		unsigned char severity__reserved;
264	} status_block;
265	unsigned char err_specific_desc[98];
266	struct {
267		unsigned char size_header;
268		unsigned short request_id;
269		unsigned char size_sense;
270	} header_desc;
271} TW_Command_Apache_Header;
272
273/* This struct is a union of the 2 command packets */
274typedef struct TAG_TW_Command_Full {
275	TW_Command_Apache_Header header;
276	union {
277		TW_Command oldcommand;
278		TW_Command_Apache newcommand;
279	} command;
280} TW_Command_Full;
281
282/* Initconnection structure */
283typedef struct TAG_TW_Initconnect {
284	unsigned char opcode__reserved;
285	unsigned char size;
286	unsigned char request_id;
287	unsigned char res2;
288	unsigned char status;
289	unsigned char flags;
290	unsigned short message_credits;
291	u32 features;
292	unsigned short fw_srl;
293	unsigned short fw_arch_id;
294	unsigned short fw_branch;
295	unsigned short fw_build;
296	u32 result;
297} TW_Initconnect;
298
299/* Event info structure */
300typedef struct TAG_TW_Event
301{
302	unsigned int sequence_id;
303	unsigned int time_stamp_sec;
304	unsigned short aen_code;
305	unsigned char severity;
306	unsigned char retrieved;
307	unsigned char repeat_count;
308	unsigned char parameter_len;
309	unsigned char parameter_data[98];
310} TW_Event;
311
312typedef struct TAG_TW_Ioctl_Driver_Command {
313	unsigned int control_code;
314	unsigned int status;
315	unsigned int unique_id;
316	unsigned int sequence_id;
317	unsigned int os_specific;
318	unsigned int buffer_length;
319} TW_Ioctl_Driver_Command;
320
321typedef struct TAG_TW_Ioctl_Apache {
322	TW_Ioctl_Driver_Command driver_command;
323        char padding[488];
324	TW_Command_Full firmware_command;
325	char data_buffer[1];
326} TW_Ioctl_Buf_Apache;
327
328/* GetParam descriptor */
329typedef struct {
330	unsigned short	table_id;
331	unsigned short	parameter_id;
332	unsigned short	parameter_size_bytes;
333	unsigned short  actual_parameter_size_bytes;
334	unsigned char	data[1];
335} TW_Param_Apache;
336
337/* Compatibility information structure */
338typedef struct TAG_TW_Compatibility_Info
339{
340	char driver_version[32];
341	unsigned short working_srl;
342	unsigned short working_branch;
343	unsigned short working_build;
344	unsigned short driver_srl_high;
345	unsigned short driver_branch_high;
346	unsigned short driver_build_high;
347	unsigned short driver_srl_low;
348	unsigned short driver_branch_low;
349	unsigned short driver_build_low;
350	unsigned short fw_on_ctlr_srl;
351	unsigned short fw_on_ctlr_branch;
352	unsigned short fw_on_ctlr_build;
353} TW_Compatibility_Info;
354
355#pragma pack()
356
357typedef struct TAG_TW_Device_Extension {
358	void                     __iomem *base_addr;
359	unsigned long	       	*generic_buffer_virt[TW_Q_LENGTH];
360	dma_addr_t	       	generic_buffer_phys[TW_Q_LENGTH];
361	TW_Command_Full	       	*command_packet_virt[TW_Q_LENGTH];
362	dma_addr_t		command_packet_phys[TW_Q_LENGTH];
363	TW_Command_Apache_Header *sense_buffer_virt[TW_Q_LENGTH];
364	dma_addr_t		sense_buffer_phys[TW_Q_LENGTH];
365	struct pci_dev		*tw_pci_dev;
366	struct scsi_cmnd	*srb[TW_Q_LENGTH];
367	unsigned char		free_queue[TW_Q_LENGTH];
368	unsigned char		free_head;
369	unsigned char		free_tail;
370	int     		state[TW_Q_LENGTH];
371	unsigned int		posted_request_count;
372	unsigned int		max_posted_request_count;
373	unsigned int		max_sgl_entries;
374	unsigned int		sgl_entries;
375	unsigned int		num_resets;
376	unsigned int		sector_count;
377	unsigned int		max_sector_count;
378	unsigned int		aen_count;
379	struct Scsi_Host	*host;
380	long			flags;
381	TW_Event                *event_queue[TW_Q_LENGTH];
382	unsigned char           error_index;
383	unsigned int            error_sequence_id;
384	int			chrdev_request_id;
385	wait_queue_head_t	ioctl_wqueue;
386	struct mutex		ioctl_lock;
387	TW_Compatibility_Info	tw_compat_info;
388	char			online;
389} TW_Device_Extension;
390
391#endif /* _3W_SAS_H */
392
393