提交 bd756dde 编写于 作者: S Shun Fu 提交者: James Bottomley

[SCSI] mvumi: Add support for Marvell SAS/SATA RAID-on-Chip(ROC) 88RC9580

[jejb: fix up for spelling correction patch]
Signed-off-by: NShun Fu <fushun@marvell.com>
Signed-off-by: NJames Bottomley <JBottomley@Parallels.com>
上级 08bc166d
此差异已折叠。
...@@ -34,51 +34,87 @@ ...@@ -34,51 +34,87 @@
#define MV_DRIVER_NAME "mvumi" #define MV_DRIVER_NAME "mvumi"
#define PCI_VENDOR_ID_MARVELL_2 0x1b4b #define PCI_VENDOR_ID_MARVELL_2 0x1b4b
#define PCI_DEVICE_ID_MARVELL_MV9143 0x9143 #define PCI_DEVICE_ID_MARVELL_MV9143 0x9143
#define PCI_DEVICE_ID_MARVELL_MV9580 0x9580
#define MVUMI_INTERNAL_CMD_WAIT_TIME 45 #define MVUMI_INTERNAL_CMD_WAIT_TIME 45
#define MVUMI_INQUIRY_LENGTH 44
#define MVUMI_INQUIRY_UUID_OFF 36
#define MVUMI_INQUIRY_UUID_LEN 8
#define IS_DMA64 (sizeof(dma_addr_t) == 8) #define IS_DMA64 (sizeof(dma_addr_t) == 8)
enum mvumi_qc_result { enum mvumi_qc_result {
MV_QUEUE_COMMAND_RESULT_SENT = 0, MV_QUEUE_COMMAND_RESULT_SENT = 0,
MV_QUEUE_COMMAND_RESULT_NO_RESOURCE, MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
}; };
enum { struct mvumi_hw_regs {
/*******************************************/ /* For CPU */
void *main_int_cause_reg;
/* ARM Mbus Registers Map */ void *enpointa_mask_reg;
void *enpointb_mask_reg;
/*******************************************/ void *rstoutn_en_reg;
CPU_MAIN_INT_CAUSE_REG = 0x20200, void *ctrl_sts_reg;
CPU_MAIN_IRQ_MASK_REG = 0x20204, void *rstoutn_mask_reg;
CPU_MAIN_FIQ_MASK_REG = 0x20208, void *sys_soft_rst_reg;
CPU_ENPOINTA_MASK_REG = 0x2020C,
CPU_ENPOINTB_MASK_REG = 0x20210, /* For Doorbell */
void *pciea_to_arm_drbl_reg;
INT_MAP_COMAERR = 1 << 6, void *arm_to_pciea_drbl_reg;
INT_MAP_COMAIN = 1 << 7, void *arm_to_pciea_mask_reg;
INT_MAP_COMAOUT = 1 << 8, void *pciea_to_arm_msg0;
INT_MAP_COMBERR = 1 << 9, void *pciea_to_arm_msg1;
INT_MAP_COMBIN = 1 << 10, void *arm_to_pciea_msg0;
INT_MAP_COMBOUT = 1 << 11, void *arm_to_pciea_msg1;
INT_MAP_COMAINT = (INT_MAP_COMAOUT | INT_MAP_COMAERR), /* reset register */
INT_MAP_COMBINT = (INT_MAP_COMBOUT | INT_MAP_COMBIN | INT_MAP_COMBERR), void *reset_request;
void *reset_enable;
INT_MAP_DL_PCIEA2CPU = 1 << 0,
INT_MAP_DL_CPU2PCIEA = 1 << 1, /* For Message Unit */
void *inb_list_basel;
/***************************************/ void *inb_list_baseh;
void *inb_aval_count_basel;
void *inb_aval_count_baseh;
void *inb_write_pointer;
void *inb_read_pointer;
void *outb_list_basel;
void *outb_list_baseh;
void *outb_copy_basel;
void *outb_copy_baseh;
void *outb_copy_pointer;
void *outb_read_pointer;
void *inb_isr_cause;
void *outb_isr_cause;
void *outb_coal_cfg;
void *outb_coal_timeout;
/* Bit setting for HW */
u32 int_comaout;
u32 int_comaerr;
u32 int_dl_cpu2pciea;
u32 int_mu;
u32 int_drbl_int_mask;
u32 int_main_int_mask;
u32 cl_pointer_toggle;
u32 cl_slot_num_mask;
u32 clic_irq;
u32 clic_in_err;
u32 clic_out_err;
};
/* ARM Doorbell Registers Map */ struct mvumi_dyn_list_entry {
u32 src_low_addr;
u32 src_high_addr;
u32 if_length;
u32 reserve;
};
/***************************************/ #define SCSI_CMD_MARVELL_SPECIFIC 0xE1
CPU_PCIEA_TO_ARM_DRBL_REG = 0x20400, #define CDB_CORE_MODULE 0x1
CPU_PCIEA_TO_ARM_MASK_REG = 0x20404, #define CDB_CORE_SHUTDOWN 0xB
CPU_ARM_TO_PCIEA_DRBL_REG = 0x20408,
CPU_ARM_TO_PCIEA_MASK_REG = 0x2040C,
enum {
DRBL_HANDSHAKE = 1 << 0, DRBL_HANDSHAKE = 1 << 0,
DRBL_SOFT_RESET = 1 << 1, DRBL_SOFT_RESET = 1 << 1,
DRBL_BUS_CHANGE = 1 << 2, DRBL_BUS_CHANGE = 1 << 2,
...@@ -86,46 +122,6 @@ enum { ...@@ -86,46 +122,6 @@ enum {
DRBL_MU_RESET = 1 << 4, DRBL_MU_RESET = 1 << 4,
DRBL_HANDSHAKE_ISR = DRBL_HANDSHAKE, DRBL_HANDSHAKE_ISR = DRBL_HANDSHAKE,
CPU_PCIEA_TO_ARM_MSG0 = 0x20430,
CPU_PCIEA_TO_ARM_MSG1 = 0x20434,
CPU_ARM_TO_PCIEA_MSG0 = 0x20438,
CPU_ARM_TO_PCIEA_MSG1 = 0x2043C,
/*******************************************/
/* ARM Communication List Registers Map */
/*******************************************/
CLA_INB_LIST_BASEL = 0x500,
CLA_INB_LIST_BASEH = 0x504,
CLA_INB_AVAL_COUNT_BASEL = 0x508,
CLA_INB_AVAL_COUNT_BASEH = 0x50C,
CLA_INB_DESTI_LIST_BASEL = 0x510,
CLA_INB_DESTI_LIST_BASEH = 0x514,
CLA_INB_WRITE_POINTER = 0x518,
CLA_INB_READ_POINTER = 0x51C,
CLA_OUTB_LIST_BASEL = 0x530,
CLA_OUTB_LIST_BASEH = 0x534,
CLA_OUTB_SOURCE_LIST_BASEL = 0x538,
CLA_OUTB_SOURCE_LIST_BASEH = 0x53C,
CLA_OUTB_COPY_POINTER = 0x544,
CLA_OUTB_READ_POINTER = 0x548,
CLA_ISR_CAUSE = 0x560,
CLA_ISR_MASK = 0x564,
INT_MAP_MU = (INT_MAP_DL_CPU2PCIEA | INT_MAP_COMAINT),
CL_POINTER_TOGGLE = 1 << 12,
CLIC_IN_IRQ = 1 << 0,
CLIC_OUT_IRQ = 1 << 1,
CLIC_IN_ERR_IRQ = 1 << 8,
CLIC_OUT_ERR_IRQ = 1 << 12,
CL_SLOT_NUM_MASK = 0xFFF,
/* /*
* Command flag is the flag for the CDB command itself * Command flag is the flag for the CDB command itself
*/ */
...@@ -137,15 +133,23 @@ enum { ...@@ -137,15 +133,23 @@ enum {
CMD_FLAG_DATA_IN = 1 << 3, CMD_FLAG_DATA_IN = 1 << 3,
/* 1-host write data */ /* 1-host write data */
CMD_FLAG_DATA_OUT = 1 << 4, CMD_FLAG_DATA_OUT = 1 << 4,
CMD_FLAG_PRDT_IN_HOST = 1 << 5,
SCSI_CMD_MARVELL_SPECIFIC = 0xE1,
CDB_CORE_SHUTDOWN = 0xB,
}; };
#define APICDB0_EVENT 0xF4 #define APICDB0_EVENT 0xF4
#define APICDB1_EVENT_GETEVENT 0 #define APICDB1_EVENT_GETEVENT 0
#define APICDB1_HOST_GETEVENT 1
#define MAX_EVENTS_RETURNED 6 #define MAX_EVENTS_RETURNED 6
#define DEVICE_OFFLINE 0
#define DEVICE_ONLINE 1
struct mvumi_hotplug_event {
u16 size;
u8 dummy[2];
u8 bitmap[0];
};
struct mvumi_driver_event { struct mvumi_driver_event {
u32 time_stamp; u32 time_stamp;
u32 sequence_no; u32 sequence_no;
...@@ -172,8 +176,14 @@ struct mvumi_events_wq { ...@@ -172,8 +176,14 @@ struct mvumi_events_wq {
void *param; void *param;
}; };
#define HS_CAPABILITY_SUPPORT_COMPACT_SG (1U << 4)
#define HS_CAPABILITY_SUPPORT_PRD_HOST (1U << 5)
#define HS_CAPABILITY_SUPPORT_DYN_SRC (1U << 6)
#define HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF (1U << 14)
#define MVUMI_MAX_SG_ENTRY 32 #define MVUMI_MAX_SG_ENTRY 32
#define SGD_EOT (1L << 27) #define SGD_EOT (1L << 27)
#define SGD_EOT_CP (1L << 22)
struct mvumi_sgl { struct mvumi_sgl {
u32 baseaddr_l; u32 baseaddr_l;
...@@ -181,6 +191,39 @@ struct mvumi_sgl { ...@@ -181,6 +191,39 @@ struct mvumi_sgl {
u32 flags; u32 flags;
u32 size; u32 size;
}; };
struct mvumi_compact_sgl {
u32 baseaddr_l;
u32 baseaddr_h;
u32 flags;
};
#define GET_COMPACT_SGD_SIZE(sgd) \
((((struct mvumi_compact_sgl *)(sgd))->flags) & 0x3FFFFFL)
#define SET_COMPACT_SGD_SIZE(sgd, sz) do { \
(((struct mvumi_compact_sgl *)(sgd))->flags) &= ~0x3FFFFFL; \
(((struct mvumi_compact_sgl *)(sgd))->flags) |= (sz); \
} while (0)
#define sgd_getsz(_mhba, sgd, sz) do { \
if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
(sz) = GET_COMPACT_SGD_SIZE(sgd); \
else \
(sz) = (sgd)->size; \
} while (0)
#define sgd_setsz(_mhba, sgd, sz) do { \
if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
SET_COMPACT_SGD_SIZE(sgd, sz); \
else \
(sgd)->size = (sz); \
} while (0)
#define sgd_inc(_mhba, sgd) do { \
if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 12); \
else \
sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 16); \
} while (0)
struct mvumi_res { struct mvumi_res {
struct list_head entry; struct list_head entry;
...@@ -197,7 +240,7 @@ enum resource_type { ...@@ -197,7 +240,7 @@ enum resource_type {
}; };
struct mvumi_sense_data { struct mvumi_sense_data {
u8 error_eode:7; u8 error_code:7;
u8 valid:1; u8 valid:1;
u8 segment_number; u8 segment_number;
u8 sense_key:4; u8 sense_key:4;
...@@ -220,6 +263,7 @@ struct mvumi_sense_data { ...@@ -220,6 +263,7 @@ struct mvumi_sense_data {
struct mvumi_cmd { struct mvumi_cmd {
struct list_head queue_pointer; struct list_head queue_pointer;
struct mvumi_msg_frame *frame; struct mvumi_msg_frame *frame;
dma_addr_t frame_phys;
struct scsi_cmnd *scmd; struct scsi_cmnd *scmd;
atomic_t sync_cmd; atomic_t sync_cmd;
void *data_buf; void *data_buf;
...@@ -393,7 +437,8 @@ struct mvumi_hs_page2 { ...@@ -393,7 +437,8 @@ struct mvumi_hs_page2 {
u16 frame_length; u16 frame_length;
u8 host_type; u8 host_type;
u8 reserved[3]; u8 host_cap;
u8 reserved[2];
struct version_info host_ver; struct version_info host_ver;
u32 system_io_bus; u32 system_io_bus;
u32 slot_number; u32 slot_number;
...@@ -435,8 +480,17 @@ struct mvumi_tag { ...@@ -435,8 +480,17 @@ struct mvumi_tag {
unsigned short size; unsigned short size;
}; };
struct mvumi_device {
struct list_head list;
struct scsi_device *sdev;
u64 wwid;
u8 dev_type;
int id;
};
struct mvumi_hba { struct mvumi_hba {
void *base_addr[MAX_BASE_ADDRESS]; void *base_addr[MAX_BASE_ADDRESS];
u32 pci_base[MAX_BASE_ADDRESS];
void *mmio; void *mmio;
struct list_head cmd_pool; struct list_head cmd_pool;
struct Scsi_Host *shost; struct Scsi_Host *shost;
...@@ -449,6 +503,9 @@ struct mvumi_hba { ...@@ -449,6 +503,9 @@ struct mvumi_hba {
void *ib_list; void *ib_list;
dma_addr_t ib_list_phys; dma_addr_t ib_list_phys;
void *ib_frame;
dma_addr_t ib_frame_phys;
void *ob_list; void *ob_list;
dma_addr_t ob_list_phys; dma_addr_t ob_list_phys;
...@@ -477,12 +534,14 @@ struct mvumi_hba { ...@@ -477,12 +534,14 @@ struct mvumi_hba {
unsigned char hba_total_pages; unsigned char hba_total_pages;
unsigned char fw_flag; unsigned char fw_flag;
unsigned char request_id_enabled; unsigned char request_id_enabled;
unsigned char eot_flag;
unsigned short hba_capability; unsigned short hba_capability;
unsigned short io_seq; unsigned short io_seq;
unsigned int ib_cur_slot; unsigned int ib_cur_slot;
unsigned int ob_cur_slot; unsigned int ob_cur_slot;
unsigned int fw_state; unsigned int fw_state;
struct mutex sas_discovery_mutex;
struct list_head ob_data_list; struct list_head ob_data_list;
struct list_head free_ob_list; struct list_head free_ob_list;
...@@ -491,14 +550,24 @@ struct mvumi_hba { ...@@ -491,14 +550,24 @@ struct mvumi_hba {
struct mvumi_tag tag_pool; struct mvumi_tag tag_pool;
struct mvumi_cmd **tag_cmd; struct mvumi_cmd **tag_cmd;
struct mvumi_hw_regs *regs;
struct mutex device_lock;
struct list_head mhba_dev_list;
struct list_head shost_dev_list;
struct task_struct *dm_thread;
atomic_t pnp_count;
}; };
struct mvumi_instance_template { struct mvumi_instance_template {
void (*fire_cmd)(struct mvumi_hba *, struct mvumi_cmd *); void (*fire_cmd) (struct mvumi_hba *, struct mvumi_cmd *);
void (*enable_intr)(void *) ; void (*enable_intr) (struct mvumi_hba *);
void (*disable_intr)(void *); void (*disable_intr) (struct mvumi_hba *);
int (*clear_intr)(void *); int (*clear_intr) (void *);
unsigned int (*read_fw_status_reg)(void *); unsigned int (*read_fw_status_reg) (struct mvumi_hba *);
unsigned int (*check_ib_list) (struct mvumi_hba *);
int (*check_ob_list) (struct mvumi_hba *, unsigned int *,
unsigned int *);
int (*reset_host) (struct mvumi_hba *);
}; };
extern struct timezone sys_tz; extern struct timezone sys_tz;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册