2 * Marvell UMI head file
4 * Copyright 2011 Marvell. <jyli@marvell.com>
6 * This file is licensed under GPLv2.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; version 2 of the
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 #define MAX_BASE_ADDRESS 6
32 #define VER_BUILD 1500
34 #define MV_DRIVER_NAME "mvumi"
35 #define PCI_VENDOR_ID_MARVELL_2 0x1b4b
36 #define PCI_DEVICE_ID_MARVELL_MV9143 0x9143
37 #define PCI_DEVICE_ID_MARVELL_MV9580 0x9580
39 #define MVUMI_INTERNAL_CMD_WAIT_TIME 45
40 #define MVUMI_INQUIRY_LENGTH 44
41 #define MVUMI_INQUIRY_UUID_OFF 36
42 #define MVUMI_INQUIRY_UUID_LEN 8
44 #define IS_DMA64 (sizeof(dma_addr_t) == 8)
46 enum mvumi_qc_result
{
47 MV_QUEUE_COMMAND_RESULT_SENT
= 0,
48 MV_QUEUE_COMMAND_RESULT_NO_RESOURCE
,
51 struct mvumi_hw_regs
{
53 void *main_int_cause_reg
;
54 void *enpointa_mask_reg
;
55 void *enpointb_mask_reg
;
58 void *rstoutn_mask_reg
;
59 void *sys_soft_rst_reg
;
62 void *pciea_to_arm_drbl_reg
;
63 void *arm_to_pciea_drbl_reg
;
64 void *arm_to_pciea_mask_reg
;
65 void *pciea_to_arm_msg0
;
66 void *pciea_to_arm_msg1
;
67 void *arm_to_pciea_msg0
;
68 void *arm_to_pciea_msg1
;
74 /* For Message Unit */
77 void *inb_aval_count_basel
;
78 void *inb_aval_count_baseh
;
79 void *inb_write_pointer
;
80 void *inb_read_pointer
;
81 void *outb_list_basel
;
82 void *outb_list_baseh
;
83 void *outb_copy_basel
;
84 void *outb_copy_baseh
;
85 void *outb_copy_pointer
;
86 void *outb_read_pointer
;
90 void *outb_coal_timeout
;
92 /* Bit setting for HW */
97 u32 int_drbl_int_mask
;
98 u32 int_main_int_mask
;
99 u32 cl_pointer_toggle
;
100 u32 cl_slot_num_mask
;
106 struct mvumi_dyn_list_entry
{
113 #define SCSI_CMD_MARVELL_SPECIFIC 0xE1
114 #define CDB_CORE_MODULE 0x1
115 #define CDB_CORE_SHUTDOWN 0xB
118 DRBL_HANDSHAKE
= 1 << 0,
119 DRBL_SOFT_RESET
= 1 << 1,
120 DRBL_BUS_CHANGE
= 1 << 2,
121 DRBL_EVENT_NOTIFY
= 1 << 3,
122 DRBL_MU_RESET
= 1 << 4,
123 DRBL_HANDSHAKE_ISR
= DRBL_HANDSHAKE
,
126 * Command flag is the flag for the CDB command itself
128 /* 1-non data; 0-data command */
129 CMD_FLAG_NON_DATA
= 1 << 0,
130 CMD_FLAG_DMA
= 1 << 1,
131 CMD_FLAG_PIO
= 1 << 2,
132 /* 1-host read data */
133 CMD_FLAG_DATA_IN
= 1 << 3,
134 /* 1-host write data */
135 CMD_FLAG_DATA_OUT
= 1 << 4,
136 CMD_FLAG_PRDT_IN_HOST
= 1 << 5,
139 #define APICDB0_EVENT 0xF4
140 #define APICDB1_EVENT_GETEVENT 0
141 #define APICDB1_HOST_GETEVENT 1
142 #define MAX_EVENTS_RETURNED 6
144 #define DEVICE_OFFLINE 0
145 #define DEVICE_ONLINE 1
147 struct mvumi_hotplug_event
{
153 struct mvumi_driver_event
{
161 u8 sense_data_length
;
166 struct mvumi_event_req
{
168 unsigned char reserved
[3];
169 struct mvumi_driver_event events
[MAX_EVENTS_RETURNED
];
172 struct mvumi_events_wq
{
173 struct work_struct work_q
;
174 struct mvumi_hba
*mhba
;
179 #define HS_CAPABILITY_SUPPORT_COMPACT_SG (1U << 4)
180 #define HS_CAPABILITY_SUPPORT_PRD_HOST (1U << 5)
181 #define HS_CAPABILITY_SUPPORT_DYN_SRC (1U << 6)
182 #define HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF (1U << 14)
184 #define MVUMI_MAX_SG_ENTRY 32
185 #define SGD_EOT (1L << 27)
186 #define SGD_EOT_CP (1L << 22)
194 struct mvumi_compact_sgl
{
200 #define GET_COMPACT_SGD_SIZE(sgd) \
201 ((((struct mvumi_compact_sgl *)(sgd))->flags) & 0x3FFFFFL)
203 #define SET_COMPACT_SGD_SIZE(sgd, sz) do { \
204 (((struct mvumi_compact_sgl *)(sgd))->flags) &= ~0x3FFFFFL; \
205 (((struct mvumi_compact_sgl *)(sgd))->flags) |= (sz); \
207 #define sgd_getsz(_mhba, sgd, sz) do { \
208 if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
209 (sz) = GET_COMPACT_SGD_SIZE(sgd); \
211 (sz) = (sgd)->size; \
214 #define sgd_setsz(_mhba, sgd, sz) do { \
215 if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
216 SET_COMPACT_SGD_SIZE(sgd, sz); \
218 (sgd)->size = (sz); \
221 #define sgd_inc(_mhba, sgd) do { \
222 if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
223 sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 12); \
225 sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 16); \
229 struct list_head entry
;
233 unsigned short type
; /* enum Resource_Type */
238 RESOURCE_CACHED_MEMORY
= 0,
239 RESOURCE_UNCACHED_MEMORY
242 struct mvumi_sense_data
{
248 u8 incorrect_length
:1;
252 u8 additional_sense_length
;
253 u8 command_specific_information
[4];
254 u8 additional_sense_code
;
255 u8 additional_sense_code_qualifier
;
256 u8 field_replaceable_unit_code
;
257 u8 sense_key_specific
[3];
260 /* Request initiator must set the status to REQ_STATUS_PENDING. */
261 #define REQ_STATUS_PENDING 0x80
264 struct list_head queue_pointer
;
265 struct mvumi_msg_frame
*frame
;
266 dma_addr_t frame_phys
;
267 struct scsi_cmnd
*scmd
;
270 unsigned short request_id
;
271 unsigned char cmd_status
;
275 * the function type of the in bound frame
277 #define CL_FUN_SCSI_CMD 0x1
279 struct mvumi_msg_frame
{
286 u32 data_transfer_length
;
289 u8 cdb
[MAX_COMMAND_SIZE
];
294 * the respond flag for data_payload of the out bound frame
296 #define CL_RSP_FLAG_NODATA 0x0
297 #define CL_RSP_FLAG_SENSEDATA 0x1
299 struct mvumi_rsp_frame
{
303 u8 rsp_flag
; /* Indicates the type of Data_Payload.*/
308 struct mvumi_ob_data
{
309 struct list_head list
;
310 unsigned char data
[0];
313 struct version_info
{
320 #define FW_MAX_DELAY 30
321 #define MVUMI_FW_BUSY (1U << 0)
322 #define MVUMI_FW_ATTACH (1U << 1)
323 #define MVUMI_FW_ALLOC (1U << 2)
326 * State is the state of the MU
328 #define FW_STATE_IDLE 0
329 #define FW_STATE_STARTING 1
330 #define FW_STATE_HANDSHAKING 2
331 #define FW_STATE_STARTED 3
332 #define FW_STATE_ABORT 4
334 #define HANDSHAKE_SIGNATURE 0x5A5A5A5AL
335 #define HANDSHAKE_READYSTATE 0x55AA5AA5L
336 #define HANDSHAKE_DONESTATE 0x55AAA55AL
338 /* HandShake Status definition */
339 #define HS_STATUS_OK 1
340 #define HS_STATUS_ERR 2
341 #define HS_STATUS_INVALID 3
343 /* HandShake State/Cmd definition */
346 #define HS_S_PAGE_ADDR 3
347 #define HS_S_QUERY_PAGE 4
348 #define HS_S_SEND_PAGE 5
351 #define HS_PAGE_VERIFY_SIZE 128
353 #define HS_GET_STATE(a) (a & 0xFFFF)
354 #define HS_GET_STATUS(a) ((a & 0xFFFF0000) >> 16)
355 #define HS_SET_STATE(a, b) (a |= (b & 0xFFFF))
356 #define HS_SET_STATUS(a, b) (a |= ((b & 0xFFFF) << 16))
358 /* handshake frame */
359 struct mvumi_hs_frame
{
361 /* host information */
364 struct version_info host_ver
; /* bios or driver version */
366 /* controller information */
372 /* communication list configuration */
384 u64 seconds_since1970
;
387 struct mvumi_hs_header
{
391 u32 frame_content
[1];
395 * the page code type of the handshake header
397 #define HS_PAGE_FIRM_CAP 0x1
398 #define HS_PAGE_HOST_INFO 0x2
399 #define HS_PAGE_FIRM_CTL 0x3
400 #define HS_PAGE_CL_INFO 0x4
401 #define HS_PAGE_TOTAL 0x5
403 #define HSP_SIZE(i) sizeof(struct mvumi_hs_page##i)
405 #define HSP_MAX_SIZE ({ \
407 m1 = max(HSP_SIZE(1), HSP_SIZE(3)); \
408 m2 = max(HSP_SIZE(2), HSP_SIZE(4)); \
409 size = max(m1, m2); \
413 /* The format of the page code for Firmware capability */
414 struct mvumi_hs_page1
{
420 u16 max_devices_support
;
423 u32 max_transfer_size
;
424 struct version_info fw_ver
;
425 u8 cl_in_max_entry_size
;
426 u8 cl_out_max_entry_size
;
427 u8 cl_inout_list_depth
;
433 /* The format of the page code for Host information */
434 struct mvumi_hs_page2
{
442 struct version_info host_ver
;
447 u64 seconds_since1970
;
450 /* The format of the page code for firmware control */
451 struct mvumi_hs_page3
{
457 u32 host_bufferaddr_l
;
458 u32 host_bufferaddr_h
;
459 u32 host_eventaddr_l
;
460 u32 host_eventaddr_h
;
463 struct mvumi_hs_page4
{
478 unsigned short *stack
;
483 struct mvumi_device
{
484 struct list_head list
;
485 struct scsi_device
*sdev
;
492 void *base_addr
[MAX_BASE_ADDRESS
];
493 u32 pci_base
[MAX_BASE_ADDRESS
];
495 struct list_head cmd_pool
;
496 struct Scsi_Host
*shost
;
497 wait_queue_head_t int_cmd_wait_q
;
498 struct pci_dev
*pdev
;
499 unsigned int unique_id
;
500 atomic_t fw_outstanding
;
501 struct mvumi_instance_template
*instancet
;
504 dma_addr_t ib_list_phys
;
507 dma_addr_t ib_frame_phys
;
510 dma_addr_t ob_list_phys
;
513 dma_addr_t ib_shadow_phys
;
516 dma_addr_t ob_shadow_phys
;
518 void *handshake_page
;
519 dma_addr_t handshake_page_phys
;
521 unsigned int global_isr
;
522 unsigned int isr_status
;
524 unsigned short max_sge
;
525 unsigned short max_target_id
;
526 unsigned char *target_map
;
528 unsigned int list_num_io
;
529 unsigned int ib_max_size
;
530 unsigned int ob_max_size
;
531 unsigned int ib_max_size_setting
;
532 unsigned int ob_max_size_setting
;
533 unsigned int max_transfer_size
;
534 unsigned char hba_total_pages
;
535 unsigned char fw_flag
;
536 unsigned char request_id_enabled
;
537 unsigned char eot_flag
;
538 unsigned short hba_capability
;
539 unsigned short io_seq
;
541 unsigned int ib_cur_slot
;
542 unsigned int ob_cur_slot
;
543 unsigned int fw_state
;
544 struct mutex sas_discovery_mutex
;
546 struct list_head ob_data_list
;
547 struct list_head free_ob_list
;
548 struct list_head res_list
;
549 struct list_head waiting_req_list
;
551 struct mvumi_tag tag_pool
;
552 struct mvumi_cmd
**tag_cmd
;
553 struct mvumi_hw_regs
*regs
;
554 struct mutex device_lock
;
555 struct list_head mhba_dev_list
;
556 struct list_head shost_dev_list
;
557 struct task_struct
*dm_thread
;
561 struct mvumi_instance_template
{
562 void (*fire_cmd
) (struct mvumi_hba
*, struct mvumi_cmd
*);
563 void (*enable_intr
) (struct mvumi_hba
*);
564 void (*disable_intr
) (struct mvumi_hba
*);
565 int (*clear_intr
) (void *);
566 unsigned int (*read_fw_status_reg
) (struct mvumi_hba
*);
567 unsigned int (*check_ib_list
) (struct mvumi_hba
*);
568 int (*check_ob_list
) (struct mvumi_hba
*, unsigned int *,
570 int (*reset_host
) (struct mvumi_hba
*);
573 extern struct timezone sys_tz
;