mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 13:51:44 +00:00
[SCSI] mvumi: Add support for Marvell SAS/SATA RAID-on-Chip(ROC) 88RC9580
[jejb: fix up for spelling correction patch] Signed-off-by: Shun Fu <fushun@marvell.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
08bc166d0f
commit
bd756ddea1
1093
drivers/scsi/mvumi.c
1093
drivers/scsi/mvumi.c
File diff suppressed because it is too large
Load Diff
@ -34,51 +34,87 @@
|
||||
#define MV_DRIVER_NAME "mvumi"
|
||||
#define PCI_VENDOR_ID_MARVELL_2 0x1b4b
|
||||
#define PCI_DEVICE_ID_MARVELL_MV9143 0x9143
|
||||
#define PCI_DEVICE_ID_MARVELL_MV9580 0x9580
|
||||
|
||||
#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)
|
||||
|
||||
enum mvumi_qc_result {
|
||||
MV_QUEUE_COMMAND_RESULT_SENT = 0,
|
||||
MV_QUEUE_COMMAND_RESULT_SENT = 0,
|
||||
MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
|
||||
};
|
||||
|
||||
struct mvumi_hw_regs {
|
||||
/* For CPU */
|
||||
void *main_int_cause_reg;
|
||||
void *enpointa_mask_reg;
|
||||
void *enpointb_mask_reg;
|
||||
void *rstoutn_en_reg;
|
||||
void *ctrl_sts_reg;
|
||||
void *rstoutn_mask_reg;
|
||||
void *sys_soft_rst_reg;
|
||||
|
||||
/* For Doorbell */
|
||||
void *pciea_to_arm_drbl_reg;
|
||||
void *arm_to_pciea_drbl_reg;
|
||||
void *arm_to_pciea_mask_reg;
|
||||
void *pciea_to_arm_msg0;
|
||||
void *pciea_to_arm_msg1;
|
||||
void *arm_to_pciea_msg0;
|
||||
void *arm_to_pciea_msg1;
|
||||
|
||||
/* reset register */
|
||||
void *reset_request;
|
||||
void *reset_enable;
|
||||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
struct mvumi_dyn_list_entry {
|
||||
u32 src_low_addr;
|
||||
u32 src_high_addr;
|
||||
u32 if_length;
|
||||
u32 reserve;
|
||||
};
|
||||
|
||||
#define SCSI_CMD_MARVELL_SPECIFIC 0xE1
|
||||
#define CDB_CORE_MODULE 0x1
|
||||
#define CDB_CORE_SHUTDOWN 0xB
|
||||
|
||||
enum {
|
||||
/*******************************************/
|
||||
|
||||
/* ARM Mbus Registers Map */
|
||||
|
||||
/*******************************************/
|
||||
CPU_MAIN_INT_CAUSE_REG = 0x20200,
|
||||
CPU_MAIN_IRQ_MASK_REG = 0x20204,
|
||||
CPU_MAIN_FIQ_MASK_REG = 0x20208,
|
||||
CPU_ENPOINTA_MASK_REG = 0x2020C,
|
||||
CPU_ENPOINTB_MASK_REG = 0x20210,
|
||||
|
||||
INT_MAP_COMAERR = 1 << 6,
|
||||
INT_MAP_COMAIN = 1 << 7,
|
||||
INT_MAP_COMAOUT = 1 << 8,
|
||||
INT_MAP_COMBERR = 1 << 9,
|
||||
INT_MAP_COMBIN = 1 << 10,
|
||||
INT_MAP_COMBOUT = 1 << 11,
|
||||
|
||||
INT_MAP_COMAINT = (INT_MAP_COMAOUT | INT_MAP_COMAERR),
|
||||
INT_MAP_COMBINT = (INT_MAP_COMBOUT | INT_MAP_COMBIN | INT_MAP_COMBERR),
|
||||
|
||||
INT_MAP_DL_PCIEA2CPU = 1 << 0,
|
||||
INT_MAP_DL_CPU2PCIEA = 1 << 1,
|
||||
|
||||
/***************************************/
|
||||
|
||||
/* ARM Doorbell Registers Map */
|
||||
|
||||
/***************************************/
|
||||
CPU_PCIEA_TO_ARM_DRBL_REG = 0x20400,
|
||||
CPU_PCIEA_TO_ARM_MASK_REG = 0x20404,
|
||||
CPU_ARM_TO_PCIEA_DRBL_REG = 0x20408,
|
||||
CPU_ARM_TO_PCIEA_MASK_REG = 0x2040C,
|
||||
|
||||
DRBL_HANDSHAKE = 1 << 0,
|
||||
DRBL_SOFT_RESET = 1 << 1,
|
||||
DRBL_BUS_CHANGE = 1 << 2,
|
||||
@ -86,46 +122,6 @@ enum {
|
||||
DRBL_MU_RESET = 1 << 4,
|
||||
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
|
||||
*/
|
||||
@ -137,15 +133,23 @@ enum {
|
||||
CMD_FLAG_DATA_IN = 1 << 3,
|
||||
/* 1-host write data */
|
||||
CMD_FLAG_DATA_OUT = 1 << 4,
|
||||
|
||||
SCSI_CMD_MARVELL_SPECIFIC = 0xE1,
|
||||
CDB_CORE_SHUTDOWN = 0xB,
|
||||
CMD_FLAG_PRDT_IN_HOST = 1 << 5,
|
||||
};
|
||||
|
||||
#define APICDB0_EVENT 0xF4
|
||||
#define APICDB1_EVENT_GETEVENT 0
|
||||
#define APICDB1_HOST_GETEVENT 1
|
||||
#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 {
|
||||
u32 time_stamp;
|
||||
u32 sequence_no;
|
||||
@ -172,8 +176,14 @@ struct mvumi_events_wq {
|
||||
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 SGD_EOT (1L << 27)
|
||||
#define SGD_EOT_CP (1L << 22)
|
||||
|
||||
struct mvumi_sgl {
|
||||
u32 baseaddr_l;
|
||||
@ -181,6 +191,39 @@ struct mvumi_sgl {
|
||||
u32 flags;
|
||||
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 list_head entry;
|
||||
@ -197,7 +240,7 @@ enum resource_type {
|
||||
};
|
||||
|
||||
struct mvumi_sense_data {
|
||||
u8 error_eode:7;
|
||||
u8 error_code:7;
|
||||
u8 valid:1;
|
||||
u8 segment_number;
|
||||
u8 sense_key:4;
|
||||
@ -220,6 +263,7 @@ struct mvumi_sense_data {
|
||||
struct mvumi_cmd {
|
||||
struct list_head queue_pointer;
|
||||
struct mvumi_msg_frame *frame;
|
||||
dma_addr_t frame_phys;
|
||||
struct scsi_cmnd *scmd;
|
||||
atomic_t sync_cmd;
|
||||
void *data_buf;
|
||||
@ -393,7 +437,8 @@ struct mvumi_hs_page2 {
|
||||
u16 frame_length;
|
||||
|
||||
u8 host_type;
|
||||
u8 reserved[3];
|
||||
u8 host_cap;
|
||||
u8 reserved[2];
|
||||
struct version_info host_ver;
|
||||
u32 system_io_bus;
|
||||
u32 slot_number;
|
||||
@ -435,8 +480,17 @@ struct mvumi_tag {
|
||||
unsigned short size;
|
||||
};
|
||||
|
||||
struct mvumi_device {
|
||||
struct list_head list;
|
||||
struct scsi_device *sdev;
|
||||
u64 wwid;
|
||||
u8 dev_type;
|
||||
int id;
|
||||
};
|
||||
|
||||
struct mvumi_hba {
|
||||
void *base_addr[MAX_BASE_ADDRESS];
|
||||
u32 pci_base[MAX_BASE_ADDRESS];
|
||||
void *mmio;
|
||||
struct list_head cmd_pool;
|
||||
struct Scsi_Host *shost;
|
||||
@ -449,6 +503,9 @@ struct mvumi_hba {
|
||||
void *ib_list;
|
||||
dma_addr_t ib_list_phys;
|
||||
|
||||
void *ib_frame;
|
||||
dma_addr_t ib_frame_phys;
|
||||
|
||||
void *ob_list;
|
||||
dma_addr_t ob_list_phys;
|
||||
|
||||
@ -477,12 +534,14 @@ struct mvumi_hba {
|
||||
unsigned char hba_total_pages;
|
||||
unsigned char fw_flag;
|
||||
unsigned char request_id_enabled;
|
||||
unsigned char eot_flag;
|
||||
unsigned short hba_capability;
|
||||
unsigned short io_seq;
|
||||
|
||||
unsigned int ib_cur_slot;
|
||||
unsigned int ob_cur_slot;
|
||||
unsigned int fw_state;
|
||||
struct mutex sas_discovery_mutex;
|
||||
|
||||
struct list_head ob_data_list;
|
||||
struct list_head free_ob_list;
|
||||
@ -491,14 +550,24 @@ struct mvumi_hba {
|
||||
|
||||
struct mvumi_tag tag_pool;
|
||||
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 {
|
||||
void (*fire_cmd)(struct mvumi_hba *, struct mvumi_cmd *);
|
||||
void (*enable_intr)(void *) ;
|
||||
void (*disable_intr)(void *);
|
||||
int (*clear_intr)(void *);
|
||||
unsigned int (*read_fw_status_reg)(void *);
|
||||
void (*fire_cmd) (struct mvumi_hba *, struct mvumi_cmd *);
|
||||
void (*enable_intr) (struct mvumi_hba *);
|
||||
void (*disable_intr) (struct mvumi_hba *);
|
||||
int (*clear_intr) (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;
|
||||
|
Loading…
Reference in New Issue
Block a user