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