162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Marvell 88SE64xx/88SE94xx main function head file 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2007 Red Hat, Inc. 662306a36Sopenharmony_ci * Copyright 2008 Marvell. <kewei@marvell.com> 762306a36Sopenharmony_ci * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com> 862306a36Sopenharmony_ci*/ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef _MV_SAS_H_ 1162306a36Sopenharmony_ci#define _MV_SAS_H_ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/kernel.h> 1462306a36Sopenharmony_ci#include <linux/module.h> 1562306a36Sopenharmony_ci#include <linux/spinlock.h> 1662306a36Sopenharmony_ci#include <linux/delay.h> 1762306a36Sopenharmony_ci#include <linux/types.h> 1862306a36Sopenharmony_ci#include <linux/ctype.h> 1962306a36Sopenharmony_ci#include <linux/dma-mapping.h> 2062306a36Sopenharmony_ci#include <linux/pci.h> 2162306a36Sopenharmony_ci#include <linux/platform_device.h> 2262306a36Sopenharmony_ci#include <linux/interrupt.h> 2362306a36Sopenharmony_ci#include <linux/irq.h> 2462306a36Sopenharmony_ci#include <linux/slab.h> 2562306a36Sopenharmony_ci#include <linux/vmalloc.h> 2662306a36Sopenharmony_ci#include <asm/unaligned.h> 2762306a36Sopenharmony_ci#include <scsi/libsas.h> 2862306a36Sopenharmony_ci#include <scsi/scsi.h> 2962306a36Sopenharmony_ci#include <scsi/scsi_tcq.h> 3062306a36Sopenharmony_ci#include <scsi/sas_ata.h> 3162306a36Sopenharmony_ci#include "mv_defs.h" 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define DRV_NAME "mvsas" 3462306a36Sopenharmony_ci#define DRV_VERSION "0.8.16" 3562306a36Sopenharmony_ci#define MVS_ID_NOT_MAPPED 0x7f 3662306a36Sopenharmony_ci#define WIDE_PORT_MAX_PHY 4 3762306a36Sopenharmony_ci#define mv_printk(fmt, arg ...) \ 3862306a36Sopenharmony_ci printk(KERN_DEBUG"%s %d:" fmt, __FILE__, __LINE__, ## arg) 3962306a36Sopenharmony_ci#ifdef MV_DEBUG 4062306a36Sopenharmony_ci#define mv_dprintk(format, arg...) \ 4162306a36Sopenharmony_ci printk(KERN_DEBUG"%s %d:" format, __FILE__, __LINE__, ## arg) 4262306a36Sopenharmony_ci#else 4362306a36Sopenharmony_ci#define mv_dprintk(format, arg...) no_printk(format, ## arg) 4462306a36Sopenharmony_ci#endif 4562306a36Sopenharmony_ci#define MV_MAX_U32 0xffffffff 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ciextern int interrupt_coalescing; 4862306a36Sopenharmony_ciextern struct mvs_tgt_initiator mvs_tgt; 4962306a36Sopenharmony_ciextern struct mvs_info *tgt_mvi; 5062306a36Sopenharmony_ciextern const struct mvs_dispatch mvs_64xx_dispatch; 5162306a36Sopenharmony_ciextern const struct mvs_dispatch mvs_94xx_dispatch; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define bit(n) ((u64)1 << n) 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#define for_each_phy(__lseq_mask, __mc, __lseq) \ 5662306a36Sopenharmony_ci for ((__mc) = (__lseq_mask), (__lseq) = 0; \ 5762306a36Sopenharmony_ci (__mc) != 0 ; \ 5862306a36Sopenharmony_ci (++__lseq), (__mc) >>= 1) 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci#define MVS_PHY_ID (1U << sas_phy->id) 6162306a36Sopenharmony_ci#define MV_INIT_DELAYED_WORK(w, f, d) INIT_DELAYED_WORK(w, f) 6262306a36Sopenharmony_ci#define UNASSOC_D2H_FIS(id) \ 6362306a36Sopenharmony_ci ((void *) mvi->rx_fis + 0x100 * id) 6462306a36Sopenharmony_ci#define SATA_RECEIVED_FIS_LIST(reg_set) \ 6562306a36Sopenharmony_ci ((void *) mvi->rx_fis + mvi->chip->fis_offs + 0x100 * reg_set) 6662306a36Sopenharmony_ci#define SATA_RECEIVED_SDB_FIS(reg_set) \ 6762306a36Sopenharmony_ci (SATA_RECEIVED_FIS_LIST(reg_set) + 0x58) 6862306a36Sopenharmony_ci#define SATA_RECEIVED_D2H_FIS(reg_set) \ 6962306a36Sopenharmony_ci (SATA_RECEIVED_FIS_LIST(reg_set) + 0x40) 7062306a36Sopenharmony_ci#define SATA_RECEIVED_PIO_FIS(reg_set) \ 7162306a36Sopenharmony_ci (SATA_RECEIVED_FIS_LIST(reg_set) + 0x20) 7262306a36Sopenharmony_ci#define SATA_RECEIVED_DMA_FIS(reg_set) \ 7362306a36Sopenharmony_ci (SATA_RECEIVED_FIS_LIST(reg_set) + 0x00) 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cienum dev_status { 7662306a36Sopenharmony_ci MVS_DEV_NORMAL = 0x0, 7762306a36Sopenharmony_ci MVS_DEV_EH = 0x1, 7862306a36Sopenharmony_ci}; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cienum dev_reset { 8162306a36Sopenharmony_ci MVS_SOFT_RESET = 0, 8262306a36Sopenharmony_ci MVS_HARD_RESET = 1, 8362306a36Sopenharmony_ci MVS_PHY_TUNE = 2, 8462306a36Sopenharmony_ci}; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistruct mvs_info; 8762306a36Sopenharmony_cistruct mvs_prv_info; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistruct mvs_dispatch { 9062306a36Sopenharmony_ci char *name; 9162306a36Sopenharmony_ci int (*chip_init)(struct mvs_info *mvi); 9262306a36Sopenharmony_ci int (*spi_init)(struct mvs_info *mvi); 9362306a36Sopenharmony_ci int (*chip_ioremap)(struct mvs_info *mvi); 9462306a36Sopenharmony_ci void (*chip_iounmap)(struct mvs_info *mvi); 9562306a36Sopenharmony_ci irqreturn_t (*isr)(struct mvs_info *mvi, int irq, u32 stat); 9662306a36Sopenharmony_ci u32 (*isr_status)(struct mvs_info *mvi, int irq); 9762306a36Sopenharmony_ci void (*interrupt_enable)(struct mvs_info *mvi); 9862306a36Sopenharmony_ci void (*interrupt_disable)(struct mvs_info *mvi); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci u32 (*read_phy_ctl)(struct mvs_info *mvi, u32 port); 10162306a36Sopenharmony_ci void (*write_phy_ctl)(struct mvs_info *mvi, u32 port, u32 val); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci u32 (*read_port_cfg_data)(struct mvs_info *mvi, u32 port); 10462306a36Sopenharmony_ci void (*write_port_cfg_data)(struct mvs_info *mvi, u32 port, u32 val); 10562306a36Sopenharmony_ci void (*write_port_cfg_addr)(struct mvs_info *mvi, u32 port, u32 addr); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci u32 (*read_port_vsr_data)(struct mvs_info *mvi, u32 port); 10862306a36Sopenharmony_ci void (*write_port_vsr_data)(struct mvs_info *mvi, u32 port, u32 val); 10962306a36Sopenharmony_ci void (*write_port_vsr_addr)(struct mvs_info *mvi, u32 port, u32 addr); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci u32 (*read_port_irq_stat)(struct mvs_info *mvi, u32 port); 11262306a36Sopenharmony_ci void (*write_port_irq_stat)(struct mvs_info *mvi, u32 port, u32 val); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci u32 (*read_port_irq_mask)(struct mvs_info *mvi, u32 port); 11562306a36Sopenharmony_ci void (*write_port_irq_mask)(struct mvs_info *mvi, u32 port, u32 val); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci void (*command_active)(struct mvs_info *mvi, u32 slot_idx); 11862306a36Sopenharmony_ci void (*clear_srs_irq)(struct mvs_info *mvi, u8 reg_set, u8 clear_all); 11962306a36Sopenharmony_ci void (*issue_stop)(struct mvs_info *mvi, enum mvs_port_type type, 12062306a36Sopenharmony_ci u32 tfs); 12162306a36Sopenharmony_ci void (*start_delivery)(struct mvs_info *mvi, u32 tx); 12262306a36Sopenharmony_ci u32 (*rx_update)(struct mvs_info *mvi); 12362306a36Sopenharmony_ci void (*int_full)(struct mvs_info *mvi); 12462306a36Sopenharmony_ci u8 (*assign_reg_set)(struct mvs_info *mvi, u8 *tfs); 12562306a36Sopenharmony_ci void (*free_reg_set)(struct mvs_info *mvi, u8 *tfs); 12662306a36Sopenharmony_ci u32 (*prd_size)(void); 12762306a36Sopenharmony_ci u32 (*prd_count)(void); 12862306a36Sopenharmony_ci void (*make_prd)(struct scatterlist *scatter, int nr, void *prd); 12962306a36Sopenharmony_ci void (*detect_porttype)(struct mvs_info *mvi, int i); 13062306a36Sopenharmony_ci int (*oob_done)(struct mvs_info *mvi, int i); 13162306a36Sopenharmony_ci void (*fix_phy_info)(struct mvs_info *mvi, int i, 13262306a36Sopenharmony_ci struct sas_identify_frame *id); 13362306a36Sopenharmony_ci void (*phy_work_around)(struct mvs_info *mvi, int i); 13462306a36Sopenharmony_ci void (*phy_set_link_rate)(struct mvs_info *mvi, u32 phy_id, 13562306a36Sopenharmony_ci struct sas_phy_linkrates *rates); 13662306a36Sopenharmony_ci u32 (*phy_max_link_rate)(void); 13762306a36Sopenharmony_ci void (*phy_disable)(struct mvs_info *mvi, u32 phy_id); 13862306a36Sopenharmony_ci void (*phy_enable)(struct mvs_info *mvi, u32 phy_id); 13962306a36Sopenharmony_ci void (*phy_reset)(struct mvs_info *mvi, u32 phy_id, int hard); 14062306a36Sopenharmony_ci void (*stp_reset)(struct mvs_info *mvi, u32 phy_id); 14162306a36Sopenharmony_ci void (*clear_active_cmds)(struct mvs_info *mvi); 14262306a36Sopenharmony_ci u32 (*spi_read_data)(struct mvs_info *mvi); 14362306a36Sopenharmony_ci void (*spi_write_data)(struct mvs_info *mvi, u32 data); 14462306a36Sopenharmony_ci int (*spi_buildcmd)(struct mvs_info *mvi, 14562306a36Sopenharmony_ci u32 *dwCmd, 14662306a36Sopenharmony_ci u8 cmd, 14762306a36Sopenharmony_ci u8 read, 14862306a36Sopenharmony_ci u8 length, 14962306a36Sopenharmony_ci u32 addr 15062306a36Sopenharmony_ci ); 15162306a36Sopenharmony_ci int (*spi_issuecmd)(struct mvs_info *mvi, u32 cmd); 15262306a36Sopenharmony_ci int (*spi_waitdataready)(struct mvs_info *mvi, u32 timeout); 15362306a36Sopenharmony_ci void (*dma_fix)(struct mvs_info *mvi, u32 phy_mask, 15462306a36Sopenharmony_ci int buf_len, int from, void *prd); 15562306a36Sopenharmony_ci void (*tune_interrupt)(struct mvs_info *mvi, u32 time); 15662306a36Sopenharmony_ci void (*non_spec_ncq_error)(struct mvs_info *mvi); 15762306a36Sopenharmony_ci int (*gpio_write)(struct mvs_prv_info *mvs_prv, u8 reg_type, 15862306a36Sopenharmony_ci u8 reg_index, u8 reg_count, u8 *write_data); 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci}; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistruct mvs_chip_info { 16362306a36Sopenharmony_ci u32 n_host; 16462306a36Sopenharmony_ci u32 n_phy; 16562306a36Sopenharmony_ci u32 fis_offs; 16662306a36Sopenharmony_ci u32 fis_count; 16762306a36Sopenharmony_ci u32 srs_sz; 16862306a36Sopenharmony_ci u32 sg_width; 16962306a36Sopenharmony_ci u32 slot_width; 17062306a36Sopenharmony_ci const struct mvs_dispatch *dispatch; 17162306a36Sopenharmony_ci}; 17262306a36Sopenharmony_ci#define MVS_MAX_SG (1U << mvi->chip->sg_width) 17362306a36Sopenharmony_ci#define MVS_CHIP_SLOT_SZ (1U << mvi->chip->slot_width) 17462306a36Sopenharmony_ci#define MVS_RX_FISL_SZ \ 17562306a36Sopenharmony_ci (mvi->chip->fis_offs + (mvi->chip->fis_count * 0x100)) 17662306a36Sopenharmony_ci#define MVS_CHIP_DISP (mvi->chip->dispatch) 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistruct mvs_err_info { 17962306a36Sopenharmony_ci __le32 flags; 18062306a36Sopenharmony_ci __le32 flags2; 18162306a36Sopenharmony_ci}; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_cistruct mvs_cmd_hdr { 18462306a36Sopenharmony_ci __le32 flags; /* PRD tbl len; SAS, SATA ctl */ 18562306a36Sopenharmony_ci __le32 lens; /* cmd, max resp frame len */ 18662306a36Sopenharmony_ci __le32 tags; /* targ port xfer tag; tag */ 18762306a36Sopenharmony_ci __le32 data_len; /* data xfer len */ 18862306a36Sopenharmony_ci __le64 cmd_tbl; /* command table address */ 18962306a36Sopenharmony_ci __le64 open_frame; /* open addr frame address */ 19062306a36Sopenharmony_ci __le64 status_buf; /* status buffer address */ 19162306a36Sopenharmony_ci __le64 prd_tbl; /* PRD tbl address */ 19262306a36Sopenharmony_ci __le32 reserved[4]; 19362306a36Sopenharmony_ci}; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistruct mvs_port { 19662306a36Sopenharmony_ci struct asd_sas_port sas_port; 19762306a36Sopenharmony_ci u8 port_attached; 19862306a36Sopenharmony_ci u8 wide_port_phymap; 19962306a36Sopenharmony_ci struct list_head list; 20062306a36Sopenharmony_ci}; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_cistruct mvs_phy { 20362306a36Sopenharmony_ci struct mvs_info *mvi; 20462306a36Sopenharmony_ci struct mvs_port *port; 20562306a36Sopenharmony_ci struct asd_sas_phy sas_phy; 20662306a36Sopenharmony_ci struct sas_identify identify; 20762306a36Sopenharmony_ci struct scsi_device *sdev; 20862306a36Sopenharmony_ci struct timer_list timer; 20962306a36Sopenharmony_ci u64 dev_sas_addr; 21062306a36Sopenharmony_ci u64 att_dev_sas_addr; 21162306a36Sopenharmony_ci u32 att_dev_info; 21262306a36Sopenharmony_ci u32 dev_info; 21362306a36Sopenharmony_ci u32 phy_type; 21462306a36Sopenharmony_ci u32 phy_status; 21562306a36Sopenharmony_ci u32 irq_status; 21662306a36Sopenharmony_ci u32 frame_rcvd_size; 21762306a36Sopenharmony_ci u8 frame_rcvd[32]; 21862306a36Sopenharmony_ci u8 phy_attached; 21962306a36Sopenharmony_ci u8 phy_mode; 22062306a36Sopenharmony_ci u8 reserved[2]; 22162306a36Sopenharmony_ci u32 phy_event; 22262306a36Sopenharmony_ci enum sas_linkrate minimum_linkrate; 22362306a36Sopenharmony_ci enum sas_linkrate maximum_linkrate; 22462306a36Sopenharmony_ci}; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_cistruct mvs_device { 22762306a36Sopenharmony_ci struct list_head dev_entry; 22862306a36Sopenharmony_ci enum sas_device_type dev_type; 22962306a36Sopenharmony_ci struct mvs_info *mvi_info; 23062306a36Sopenharmony_ci struct domain_device *sas_device; 23162306a36Sopenharmony_ci u32 attached_phy; 23262306a36Sopenharmony_ci u32 device_id; 23362306a36Sopenharmony_ci u32 running_req; 23462306a36Sopenharmony_ci u8 taskfileset; 23562306a36Sopenharmony_ci u8 dev_status; 23662306a36Sopenharmony_ci u16 reserved; 23762306a36Sopenharmony_ci}; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci/* Generate PHY tunning parameters */ 24062306a36Sopenharmony_cistruct phy_tuning { 24162306a36Sopenharmony_ci /* 1 bit, transmitter emphasis enable */ 24262306a36Sopenharmony_ci u8 trans_emp_en:1; 24362306a36Sopenharmony_ci /* 4 bits, transmitter emphasis amplitude */ 24462306a36Sopenharmony_ci u8 trans_emp_amp:4; 24562306a36Sopenharmony_ci /* 3 bits, reserved space */ 24662306a36Sopenharmony_ci u8 Reserved_2bit_1:3; 24762306a36Sopenharmony_ci /* 5 bits, transmitter amplitude */ 24862306a36Sopenharmony_ci u8 trans_amp:5; 24962306a36Sopenharmony_ci /* 2 bits, transmitter amplitude adjust */ 25062306a36Sopenharmony_ci u8 trans_amp_adj:2; 25162306a36Sopenharmony_ci /* 1 bit, reserved space */ 25262306a36Sopenharmony_ci u8 resv_2bit_2:1; 25362306a36Sopenharmony_ci /* 2 bytes, reserved space */ 25462306a36Sopenharmony_ci u8 reserved[2]; 25562306a36Sopenharmony_ci}; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cistruct ffe_control { 25862306a36Sopenharmony_ci /* 4 bits, FFE Capacitor Select (value range 0~F) */ 25962306a36Sopenharmony_ci u8 ffe_cap_sel:4; 26062306a36Sopenharmony_ci /* 3 bits, FFE Resistor Select (value range 0~7) */ 26162306a36Sopenharmony_ci u8 ffe_rss_sel:3; 26262306a36Sopenharmony_ci /* 1 bit reserve*/ 26362306a36Sopenharmony_ci u8 reserved:1; 26462306a36Sopenharmony_ci}; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci/* 26762306a36Sopenharmony_ci * HBA_Info_Page is saved in Flash/NVRAM, total 256 bytes. 26862306a36Sopenharmony_ci * The data area is valid only Signature="MRVL". 26962306a36Sopenharmony_ci * If any member fills with 0xFF, the member is invalid. 27062306a36Sopenharmony_ci */ 27162306a36Sopenharmony_cistruct hba_info_page { 27262306a36Sopenharmony_ci /* Dword 0 */ 27362306a36Sopenharmony_ci /* 4 bytes, structure signature,should be "MRVL" at first initial */ 27462306a36Sopenharmony_ci u8 signature[4]; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci /* Dword 1-13 */ 27762306a36Sopenharmony_ci u32 reserved1[13]; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci /* Dword 14-29 */ 28062306a36Sopenharmony_ci /* 64 bytes, SAS address for each port */ 28162306a36Sopenharmony_ci u64 sas_addr[8]; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci /* Dword 30-31 */ 28462306a36Sopenharmony_ci /* 8 bytes for vanir 8 port PHY FFE seeting 28562306a36Sopenharmony_ci * BIT 0~3 : FFE Capacitor select(value range 0~F) 28662306a36Sopenharmony_ci * BIT 4~6 : FFE Resistor select(value range 0~7) 28762306a36Sopenharmony_ci * BIT 7: reserve. 28862306a36Sopenharmony_ci */ 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci struct ffe_control ffe_ctl[8]; 29162306a36Sopenharmony_ci /* Dword 32 -43 */ 29262306a36Sopenharmony_ci u32 reserved2[12]; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci /* Dword 44-45 */ 29562306a36Sopenharmony_ci /* 8 bytes, 0: 1.5G, 1: 3.0G, should be 0x01 at first initial */ 29662306a36Sopenharmony_ci u8 phy_rate[8]; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci /* Dword 46-53 */ 29962306a36Sopenharmony_ci /* 32 bytes, PHY tuning parameters for each PHY*/ 30062306a36Sopenharmony_ci struct phy_tuning phy_tuning[8]; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci /* Dword 54-63 */ 30362306a36Sopenharmony_ci u32 reserved3[10]; 30462306a36Sopenharmony_ci}; /* total 256 bytes */ 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_cistruct mvs_slot_info { 30762306a36Sopenharmony_ci struct list_head entry; 30862306a36Sopenharmony_ci union { 30962306a36Sopenharmony_ci struct sas_task *task; 31062306a36Sopenharmony_ci void *tdata; 31162306a36Sopenharmony_ci }; 31262306a36Sopenharmony_ci u32 n_elem; 31362306a36Sopenharmony_ci u32 tx; 31462306a36Sopenharmony_ci u32 slot_tag; 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci /* DMA buffer for storing cmd tbl, open addr frame, status buffer, 31762306a36Sopenharmony_ci * and PRD table 31862306a36Sopenharmony_ci */ 31962306a36Sopenharmony_ci void *buf; 32062306a36Sopenharmony_ci dma_addr_t buf_dma; 32162306a36Sopenharmony_ci void *response; 32262306a36Sopenharmony_ci struct mvs_port *port; 32362306a36Sopenharmony_ci struct mvs_device *device; 32462306a36Sopenharmony_ci void *open_frame; 32562306a36Sopenharmony_ci}; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistruct mvs_info { 32862306a36Sopenharmony_ci unsigned long flags; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci /* host-wide lock */ 33162306a36Sopenharmony_ci spinlock_t lock; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci /* our device */ 33462306a36Sopenharmony_ci struct pci_dev *pdev; 33562306a36Sopenharmony_ci struct device *dev; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci /* enhanced mode registers */ 33862306a36Sopenharmony_ci void __iomem *regs; 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci /* peripheral or soc registers */ 34162306a36Sopenharmony_ci void __iomem *regs_ex; 34262306a36Sopenharmony_ci u8 sas_addr[SAS_ADDR_SIZE]; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci /* SCSI/SAS glue */ 34562306a36Sopenharmony_ci struct sas_ha_struct *sas; 34662306a36Sopenharmony_ci struct Scsi_Host *shost; 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci /* TX (delivery) DMA ring */ 34962306a36Sopenharmony_ci __le32 *tx; 35062306a36Sopenharmony_ci dma_addr_t tx_dma; 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci /* cached next-producer idx */ 35362306a36Sopenharmony_ci u32 tx_prod; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci /* RX (completion) DMA ring */ 35662306a36Sopenharmony_ci __le32 *rx; 35762306a36Sopenharmony_ci dma_addr_t rx_dma; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci /* RX consumer idx */ 36062306a36Sopenharmony_ci u32 rx_cons; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci /* RX'd FIS area */ 36362306a36Sopenharmony_ci __le32 *rx_fis; 36462306a36Sopenharmony_ci dma_addr_t rx_fis_dma; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci /* DMA command header slots */ 36762306a36Sopenharmony_ci struct mvs_cmd_hdr *slot; 36862306a36Sopenharmony_ci dma_addr_t slot_dma; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci u32 chip_id; 37162306a36Sopenharmony_ci const struct mvs_chip_info *chip; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci unsigned long *rsvd_tags; 37462306a36Sopenharmony_ci /* further per-slot information */ 37562306a36Sopenharmony_ci struct mvs_phy phy[MVS_MAX_PHYS]; 37662306a36Sopenharmony_ci struct mvs_port port[MVS_MAX_PHYS]; 37762306a36Sopenharmony_ci u32 id; 37862306a36Sopenharmony_ci u64 sata_reg_set; 37962306a36Sopenharmony_ci struct list_head *hba_list; 38062306a36Sopenharmony_ci struct list_head soc_entry; 38162306a36Sopenharmony_ci struct list_head wq_list; 38262306a36Sopenharmony_ci unsigned long instance; 38362306a36Sopenharmony_ci u16 flashid; 38462306a36Sopenharmony_ci u32 flashsize; 38562306a36Sopenharmony_ci u32 flashsectSize; 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci void *addon; 38862306a36Sopenharmony_ci struct hba_info_page hba_info_param; 38962306a36Sopenharmony_ci struct mvs_device devices[MVS_MAX_DEVICES]; 39062306a36Sopenharmony_ci void *bulk_buffer; 39162306a36Sopenharmony_ci dma_addr_t bulk_buffer_dma; 39262306a36Sopenharmony_ci void *bulk_buffer1; 39362306a36Sopenharmony_ci dma_addr_t bulk_buffer_dma1; 39462306a36Sopenharmony_ci#define TRASH_BUCKET_SIZE 0x20000 39562306a36Sopenharmony_ci void *dma_pool; 39662306a36Sopenharmony_ci struct mvs_slot_info slot_info[]; 39762306a36Sopenharmony_ci}; 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_cistruct mvs_prv_info{ 40062306a36Sopenharmony_ci u8 n_host; 40162306a36Sopenharmony_ci u8 n_phy; 40262306a36Sopenharmony_ci u8 scan_finished; 40362306a36Sopenharmony_ci u8 reserve; 40462306a36Sopenharmony_ci struct mvs_info *mvi[2]; 40562306a36Sopenharmony_ci struct tasklet_struct mv_tasklet; 40662306a36Sopenharmony_ci}; 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_cistruct mvs_wq { 40962306a36Sopenharmony_ci struct delayed_work work_q; 41062306a36Sopenharmony_ci struct mvs_info *mvi; 41162306a36Sopenharmony_ci void *data; 41262306a36Sopenharmony_ci int handler; 41362306a36Sopenharmony_ci struct list_head entry; 41462306a36Sopenharmony_ci}; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_cistruct mvs_task_exec_info { 41762306a36Sopenharmony_ci struct sas_task *task; 41862306a36Sopenharmony_ci struct mvs_cmd_hdr *hdr; 41962306a36Sopenharmony_ci struct mvs_port *port; 42062306a36Sopenharmony_ci u32 tag; 42162306a36Sopenharmony_ci int n_elem; 42262306a36Sopenharmony_ci}; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci/******************** function prototype *********************/ 42562306a36Sopenharmony_civoid mvs_get_sas_addr(void *buf, u32 buflen); 42662306a36Sopenharmony_civoid mvs_iounmap(void __iomem *regs); 42762306a36Sopenharmony_ciint mvs_ioremap(struct mvs_info *mvi, int bar, int bar_ex); 42862306a36Sopenharmony_civoid mvs_phys_reset(struct mvs_info *mvi, u32 phy_mask, int hard); 42962306a36Sopenharmony_ciint mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, 43062306a36Sopenharmony_ci void *funcdata); 43162306a36Sopenharmony_civoid mvs_set_sas_addr(struct mvs_info *mvi, int port_id, u32 off_lo, 43262306a36Sopenharmony_ci u32 off_hi, u64 sas_addr); 43362306a36Sopenharmony_civoid mvs_scan_start(struct Scsi_Host *shost); 43462306a36Sopenharmony_ciint mvs_scan_finished(struct Scsi_Host *shost, unsigned long time); 43562306a36Sopenharmony_ciint mvs_queue_command(struct sas_task *task, gfp_t gfp_flags); 43662306a36Sopenharmony_ciint mvs_abort_task(struct sas_task *task); 43762306a36Sopenharmony_civoid mvs_port_formed(struct asd_sas_phy *sas_phy); 43862306a36Sopenharmony_civoid mvs_port_deformed(struct asd_sas_phy *sas_phy); 43962306a36Sopenharmony_ciint mvs_dev_found(struct domain_device *dev); 44062306a36Sopenharmony_civoid mvs_dev_gone(struct domain_device *dev); 44162306a36Sopenharmony_ciint mvs_lu_reset(struct domain_device *dev, u8 *lun); 44262306a36Sopenharmony_ciint mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags); 44362306a36Sopenharmony_ciint mvs_I_T_nexus_reset(struct domain_device *dev); 44462306a36Sopenharmony_ciint mvs_query_task(struct sas_task *task); 44562306a36Sopenharmony_civoid mvs_release_task(struct mvs_info *mvi, 44662306a36Sopenharmony_ci struct domain_device *dev); 44762306a36Sopenharmony_civoid mvs_do_release_task(struct mvs_info *mvi, int phy_no, 44862306a36Sopenharmony_ci struct domain_device *dev); 44962306a36Sopenharmony_civoid mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events); 45062306a36Sopenharmony_civoid mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); 45162306a36Sopenharmony_ciint mvs_int_rx(struct mvs_info *mvi, bool self_clear); 45262306a36Sopenharmony_cistruct mvs_device *mvs_find_dev_by_reg_set(struct mvs_info *mvi, u8 reg_set); 45362306a36Sopenharmony_ciint mvs_gpio_write(struct sas_ha_struct *, u8 reg_type, u8 reg_index, 45462306a36Sopenharmony_ci u8 reg_count, u8 *write_data); 45562306a36Sopenharmony_ci#endif 45662306a36Sopenharmony_ci 457