2009-10-14 16:19:21 +08:00
/*
2013-04-17 16:37:02 +05:30
* PMC - Sierra PM8001 / 8081 / 8088 / 8089 SAS / SATA based host adapters driver
2009-10-14 16:19:21 +08:00
*
* Copyright ( c ) 2008 - 2009 USI Co . , Ltd .
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions , and the following disclaimer ,
* without modification .
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the " NO WARRANTY " disclaimer below
* ( " Disclaimer " ) and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution .
* 3. Neither the names of the above - listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* Alternatively , this software may be distributed under the terms of the
* GNU General Public License ( " GPL " ) version 2 as published by the Free
* Software Foundation .
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT ,
* STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES .
*
*/
# ifndef _PM8001_SAS_H_
# define _PM8001_SAS_H_
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/spinlock.h>
# include <linux/delay.h>
# include <linux/types.h>
# include <linux/ctype.h>
# include <linux/dma-mapping.h>
# include <linux/pci.h>
# include <linux/interrupt.h>
2011-01-24 14:57:29 +01:00
# include <linux/workqueue.h>
2009-10-14 16:19:21 +08:00
# include <scsi/libsas.h>
# include <scsi/scsi_tcq.h>
# include <scsi/sas_ata.h>
2011-07-26 16:09:06 -07:00
# include <linux/atomic.h>
2009-10-14 16:19:21 +08:00
# include "pm8001_defs.h"
2013-03-19 18:07:09 +05:30
# define DRV_NAME "pm80xx"
# define DRV_VERSION "0.1.37"
2009-12-07 17:23:11 +08:00
# define PM8001_FAIL_LOGGING 0x01 /* Error message logging */
2009-10-14 16:19:21 +08:00
# define PM8001_INIT_LOGGING 0x02 /* driver init logging */
# define PM8001_DISC_LOGGING 0x04 /* discovery layer logging */
# define PM8001_IO_LOGGING 0x08 /* I/O path logging */
2009-12-07 17:23:11 +08:00
# define PM8001_EH_LOGGING 0x10 /* libsas EH function logging*/
2009-10-14 16:19:21 +08:00
# define PM8001_IOCTL_LOGGING 0x20 /* IOCTL message logging */
# define PM8001_MSG_LOGGING 0x40 /* misc message logging */
2013-03-19 18:07:09 +05:30
# define pm8001_printk(format, arg...) printk(KERN_INFO "pm80xx %s %d:" \
format , __func__ , __LINE__ , # # arg )
2009-10-14 16:19:21 +08:00
# define PM8001_CHECK_LOGGING(HBA, LEVEL, CMD) \
do { \
if ( unlikely ( HBA - > logging_level & LEVEL ) ) \
do { \
CMD ; \
} while ( 0 ) ; \
} while ( 0 ) ;
# define PM8001_EH_DBG(HBA, CMD) \
PM8001_CHECK_LOGGING ( HBA , PM8001_EH_LOGGING , CMD )
# define PM8001_INIT_DBG(HBA, CMD) \
PM8001_CHECK_LOGGING ( HBA , PM8001_INIT_LOGGING , CMD )
# define PM8001_DISC_DBG(HBA, CMD) \
PM8001_CHECK_LOGGING ( HBA , PM8001_DISC_LOGGING , CMD )
# define PM8001_IO_DBG(HBA, CMD) \
PM8001_CHECK_LOGGING ( HBA , PM8001_IO_LOGGING , CMD )
# define PM8001_FAIL_DBG(HBA, CMD) \
PM8001_CHECK_LOGGING ( HBA , PM8001_FAIL_LOGGING , CMD )
# define PM8001_IOCTL_DBG(HBA, CMD) \
PM8001_CHECK_LOGGING ( HBA , PM8001_IOCTL_LOGGING , CMD )
# define PM8001_MSG_DBG(HBA, CMD) \
PM8001_CHECK_LOGGING ( HBA , PM8001_MSG_LOGGING , CMD )
# define PM8001_USE_TASKLET
# define PM8001_USE_MSIX
2009-12-07 17:23:08 +08:00
# define PM8001_READ_VPD
2009-10-14 16:19:21 +08:00
2013-05-07 14:44:06 -07:00
# define DEV_IS_EXPANDER(type) ((type == SAS_EDGE_EXPANDER_DEVICE) || (type == SAS_FANOUT_EXPANDER_DEVICE))
2013-09-03 15:09:42 +05:30
# define IS_SPCV_12G(dev) ((dev->device == 0X8074) \
| | ( dev - > device = = 0 X8076 ) \
| | ( dev - > device = = 0 X8077 ) )
2009-10-14 16:19:21 +08:00
# define PM8001_NAME_LENGTH 32 /* generic length of strings */
extern struct list_head hba_list ;
extern const struct pm8001_dispatch pm8001_8001_dispatch ;
2013-04-17 16:37:02 +05:30
extern const struct pm8001_dispatch pm8001_80xx_dispatch ;
2009-10-14 16:19:21 +08:00
struct pm8001_hba_info ;
struct pm8001_ccb_info ;
struct pm8001_device ;
2009-12-07 17:23:08 +08:00
/* define task management IU */
struct pm8001_tmf_task {
u8 tmf ;
u32 tag_of_task_to_be_managed ;
} ;
struct pm8001_ioctl_payload {
u32 signature ;
u16 major_function ;
u16 minor_function ;
u16 length ;
u16 status ;
u16 offset ;
u16 id ;
u8 * func_specific ;
} ;
2013-09-04 12:57:00 +05:30
# define MPI_FATAL_ERROR_TABLE_OFFSET_MASK 0xFFFFFF
# define MPI_FATAL_ERROR_TABLE_SIZE(value) ((0xFF000000 & value) >> SHIFT24)
# define MPI_FATAL_EDUMP_TABLE_LO_OFFSET 0x00 /* HNFBUFL */
# define MPI_FATAL_EDUMP_TABLE_HI_OFFSET 0x04 /* HNFBUFH */
# define MPI_FATAL_EDUMP_TABLE_LENGTH 0x08 /* HNFBLEN */
# define MPI_FATAL_EDUMP_TABLE_HANDSHAKE 0x0C /* FDDHSHK */
# define MPI_FATAL_EDUMP_TABLE_STATUS 0x10 /* FDDTSTAT */
# define MPI_FATAL_EDUMP_TABLE_ACCUM_LEN 0x14 /* ACCDDLEN */
# define MPI_FATAL_EDUMP_HANDSHAKE_RDY 0x1
# define MPI_FATAL_EDUMP_HANDSHAKE_BUSY 0x0
# define MPI_FATAL_EDUMP_TABLE_STAT_RSVD 0x0
# define MPI_FATAL_EDUMP_TABLE_STAT_DMA_FAILED 0x1
# define MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_MORE_DATA 0x2
# define MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE 0x3
# define TYPE_GSM_SPACE 1
# define TYPE_QUEUE 2
# define TYPE_FATAL 3
# define TYPE_NON_FATAL 4
# define TYPE_INBOUND 1
# define TYPE_OUTBOUND 2
struct forensic_data {
u32 data_type ;
union {
struct {
u32 direct_len ;
u32 direct_offset ;
void * direct_data ;
} gsm_buf ;
struct {
u16 queue_type ;
u16 queue_index ;
u32 direct_len ;
void * direct_data ;
} queue_buf ;
struct {
u32 direct_len ;
u32 direct_offset ;
u32 read_len ;
void * direct_data ;
} data_buf ;
} ;
} ;
/* bit31-26 - mask bar */
# define SCRATCH_PAD0_BAR_MASK 0xFC000000
/* bit25-0 - offset mask */
# define SCRATCH_PAD0_OFFSET_MASK 0x03FFFFFF
/* if AAP error state */
# define SCRATCH_PAD0_AAPERR_MASK 0xFFFFFFFF
/* Inbound doorbell bit7 */
# define SPCv_MSGU_CFG_TABLE_NONFATAL_DUMP 0x80
/* Inbound doorbell bit7 SPCV */
# define SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO 0x80
# define MAIN_MERRDCTO_MERRDCES 0xA0 /* DWORD 0x28) */
2009-10-14 16:19:21 +08:00
struct pm8001_dispatch {
char * name ;
int ( * chip_init ) ( struct pm8001_hba_info * pm8001_ha ) ;
2013-04-17 16:37:02 +05:30
int ( * chip_soft_rst ) ( struct pm8001_hba_info * pm8001_ha ) ;
2009-10-14 16:19:21 +08:00
void ( * chip_rst ) ( struct pm8001_hba_info * pm8001_ha ) ;
int ( * chip_ioremap ) ( struct pm8001_hba_info * pm8001_ha ) ;
void ( * chip_iounmap ) ( struct pm8001_hba_info * pm8001_ha ) ;
2013-02-27 20:27:43 +05:30
irqreturn_t ( * isr ) ( struct pm8001_hba_info * pm8001_ha , u8 vec ) ;
2009-10-14 16:19:21 +08:00
u32 ( * is_our_interupt ) ( struct pm8001_hba_info * pm8001_ha ) ;
2013-02-27 20:27:43 +05:30
int ( * isr_process_oq ) ( struct pm8001_hba_info * pm8001_ha , u8 vec ) ;
void ( * interrupt_enable ) ( struct pm8001_hba_info * pm8001_ha , u8 vec ) ;
void ( * interrupt_disable ) ( struct pm8001_hba_info * pm8001_ha , u8 vec ) ;
2009-10-14 16:19:21 +08:00
void ( * make_prd ) ( struct scatterlist * scatter , int nr , void * prd ) ;
int ( * smp_req ) ( struct pm8001_hba_info * pm8001_ha ,
struct pm8001_ccb_info * ccb ) ;
int ( * ssp_io_req ) ( struct pm8001_hba_info * pm8001_ha ,
struct pm8001_ccb_info * ccb ) ;
int ( * sata_req ) ( struct pm8001_hba_info * pm8001_ha ,
struct pm8001_ccb_info * ccb ) ;
int ( * phy_start_req ) ( struct pm8001_hba_info * pm8001_ha , u8 phy_id ) ;
int ( * phy_stop_req ) ( struct pm8001_hba_info * pm8001_ha , u8 phy_id ) ;
int ( * reg_dev_req ) ( struct pm8001_hba_info * pm8001_ha ,
struct pm8001_device * pm8001_dev , u32 flag ) ;
int ( * dereg_dev_req ) ( struct pm8001_hba_info * pm8001_ha , u32 device_id ) ;
int ( * phy_ctl_req ) ( struct pm8001_hba_info * pm8001_ha ,
u32 phy_id , u32 phy_op ) ;
int ( * task_abort ) ( struct pm8001_hba_info * pm8001_ha ,
struct pm8001_device * pm8001_dev , u8 flag , u32 task_tag ,
u32 cmd_tag ) ;
int ( * ssp_tm_req ) ( struct pm8001_hba_info * pm8001_ha ,
struct pm8001_ccb_info * ccb , struct pm8001_tmf_task * tmf ) ;
int ( * get_nvmd_req ) ( struct pm8001_hba_info * pm8001_ha , void * payload ) ;
int ( * set_nvmd_req ) ( struct pm8001_hba_info * pm8001_ha , void * payload ) ;
int ( * fw_flash_update_req ) ( struct pm8001_hba_info * pm8001_ha ,
void * payload ) ;
int ( * set_dev_state_req ) ( struct pm8001_hba_info * pm8001_ha ,
struct pm8001_device * pm8001_dev , u32 state ) ;
int ( * sas_diag_start_end_req ) ( struct pm8001_hba_info * pm8001_ha ,
u32 state ) ;
int ( * sas_diag_execute_req ) ( struct pm8001_hba_info * pm8001_ha ,
u32 state ) ;
2009-11-05 22:32:31 +08:00
int ( * sas_re_init_req ) ( struct pm8001_hba_info * pm8001_ha ) ;
2009-10-14 16:19:21 +08:00
} ;
struct pm8001_chip_info {
2013-04-17 16:26:36 +05:30
u32 encrypt ;
2009-10-14 16:19:21 +08:00
u32 n_phy ;
const struct pm8001_dispatch * dispatch ;
} ;
# define PM8001_CHIP_DISP (pm8001_ha->chip->dispatch)
struct pm8001_port {
struct asd_sas_port sas_port ;
2009-12-07 17:22:42 +08:00
u8 port_attached ;
u8 wide_port_phymap ;
u8 port_state ;
struct list_head list ;
2009-10-14 16:19:21 +08:00
} ;
struct pm8001_phy {
struct pm8001_hba_info * pm8001_ha ;
struct pm8001_port * port ;
struct asd_sas_phy sas_phy ;
struct sas_identify identify ;
struct scsi_device * sdev ;
u64 dev_sas_addr ;
u32 phy_type ;
struct completion * enable_completion ;
u32 frame_rcvd_size ;
u8 frame_rcvd [ 32 ] ;
u8 phy_attached ;
u8 phy_state ;
enum sas_linkrate minimum_linkrate ;
enum sas_linkrate maximum_linkrate ;
} ;
struct pm8001_device {
2013-05-07 14:44:06 -07:00
enum sas_device_type dev_type ;
2009-10-14 16:19:21 +08:00
struct domain_device * sas_device ;
u32 attached_phy ;
u32 id ;
struct completion * dcompletion ;
struct completion * setds_completion ;
u32 device_id ;
u32 running_req ;
} ;
struct pm8001_prd_imt {
__le32 len ;
__le32 e ;
} ;
struct pm8001_prd {
__le64 addr ; /* 64-bit buffer address */
struct pm8001_prd_imt im_len ; /* 64-bit length */
} __attribute__ ( ( packed ) ) ;
/*
* CCB ( Command Control Block )
*/
struct pm8001_ccb_info {
struct list_head entry ;
struct sas_task * task ;
u32 n_elem ;
u32 ccb_tag ;
dma_addr_t ccb_dma_handle ;
struct pm8001_device * device ;
struct pm8001_prd buf_prd [ PM8001_MAX_DMA_SG ] ;
struct fw_control_ex * fw_control_context ;
2012-01-17 11:52:24 -05:00
u8 open_retry ;
2009-10-14 16:19:21 +08:00
} ;
struct mpi_mem {
void * virt_ptr ;
dma_addr_t phys_addr ;
u32 phys_addr_hi ;
u32 phys_addr_lo ;
u32 total_len ;
u32 num_elements ;
u32 element_size ;
u32 alignment ;
} ;
struct mpi_mem_req {
/* The number of element in the mpiMemory array */
u32 count ;
/* The array of structures that define memroy regions*/
struct mpi_mem region [ USI_MAX_MEMCNT ] ;
} ;
2013-04-17 16:26:36 +05:30
struct encrypt {
u32 cipher_mode ;
u32 sec_mode ;
u32 status ;
u32 flag ;
} ;
struct sas_phy_attribute_table {
u32 phystart1_16 [ 16 ] ;
u32 outbound_hw_event_pid1_16 [ 16 ] ;
} ;
union main_cfg_table {
struct {
2009-10-14 16:19:21 +08:00
u32 signature ;
u32 interface_rev ;
u32 firmware_rev ;
u32 max_out_io ;
u32 max_sgl ;
u32 ctrl_cap_flag ;
u32 gst_offset ;
u32 inbound_queue_offset ;
u32 outbound_queue_offset ;
u32 inbound_q_nppd_hppd ;
u32 outbound_hw_event_pid0_3 ;
u32 outbound_hw_event_pid4_7 ;
u32 outbound_ncq_event_pid0_3 ;
u32 outbound_ncq_event_pid4_7 ;
u32 outbound_tgt_ITNexus_event_pid0_3 ;
u32 outbound_tgt_ITNexus_event_pid4_7 ;
u32 outbound_tgt_ssp_event_pid0_3 ;
u32 outbound_tgt_ssp_event_pid4_7 ;
u32 outbound_tgt_smp_event_pid0_3 ;
u32 outbound_tgt_smp_event_pid4_7 ;
u32 upper_event_log_addr ;
u32 lower_event_log_addr ;
u32 event_log_size ;
u32 event_log_option ;
u32 upper_iop_event_log_addr ;
u32 lower_iop_event_log_addr ;
u32 iop_event_log_size ;
u32 iop_event_log_option ;
u32 fatal_err_interrupt ;
u32 fatal_err_dump_offset0 ;
u32 fatal_err_dump_length0 ;
u32 fatal_err_dump_offset1 ;
u32 fatal_err_dump_length1 ;
u32 hda_mode_flag ;
u32 anolog_setup_table_offset ;
2013-04-17 16:26:36 +05:30
u32 rsvd [ 4 ] ;
} pm8001_tbl ;
struct {
u32 signature ;
u32 interface_rev ;
u32 firmware_rev ;
u32 max_out_io ;
u32 max_sgl ;
u32 ctrl_cap_flag ;
u32 gst_offset ;
u32 inbound_queue_offset ;
u32 outbound_queue_offset ;
u32 inbound_q_nppd_hppd ;
2013-03-19 18:08:08 +05:30
u32 rsvd [ 8 ] ;
u32 crc_core_dump ;
u32 rsvd1 ;
2013-04-17 16:26:36 +05:30
u32 upper_event_log_addr ;
u32 lower_event_log_addr ;
u32 event_log_size ;
u32 event_log_severity ;
u32 upper_pcs_event_log_addr ;
u32 lower_pcs_event_log_addr ;
u32 pcs_event_log_size ;
u32 pcs_event_log_severity ;
u32 fatal_err_interrupt ;
u32 fatal_err_dump_offset0 ;
u32 fatal_err_dump_length0 ;
u32 fatal_err_dump_offset1 ;
u32 fatal_err_dump_length1 ;
u32 gpio_led_mapping ;
u32 analog_setup_table_offset ;
u32 int_vec_table_offset ;
u32 phy_attr_table_offset ;
u32 port_recovery_timer ;
u32 interrupt_reassertion_delay ;
2013-09-04 12:57:00 +05:30
u32 fatal_n_non_fatal_dump ; /* 0x28 */
2013-04-17 16:26:36 +05:30
} pm80xx_tbl ;
2009-10-14 16:19:21 +08:00
} ;
2013-04-17 16:26:36 +05:30
union general_status_table {
struct {
2009-10-14 16:19:21 +08:00
u32 gst_len_mpistate ;
u32 iq_freeze_state0 ;
u32 iq_freeze_state1 ;
u32 msgu_tcnt ;
u32 iop_tcnt ;
2013-04-17 16:26:36 +05:30
u32 rsvd ;
2009-10-14 16:19:21 +08:00
u32 phy_state [ 8 ] ;
2013-04-17 16:26:36 +05:30
u32 gpio_input_val ;
u32 rsvd1 [ 2 ] ;
u32 recover_err_info [ 8 ] ;
} pm8001_tbl ;
struct {
u32 gst_len_mpistate ;
u32 iq_freeze_state0 ;
u32 iq_freeze_state1 ;
u32 msgu_tcnt ;
u32 iop_tcnt ;
u32 rsvd [ 9 ] ;
u32 gpio_input_val ;
u32 rsvd1 [ 2 ] ;
2009-10-14 16:19:21 +08:00
u32 recover_err_info [ 8 ] ;
2013-04-17 16:26:36 +05:30
} pm80xx_tbl ;
2009-10-14 16:19:21 +08:00
} ;
struct inbound_queue_table {
u32 element_pri_size_cnt ;
u32 upper_base_addr ;
u32 lower_base_addr ;
u32 ci_upper_base_addr ;
u32 ci_lower_base_addr ;
u32 pi_pci_bar ;
u32 pi_offset ;
u32 total_length ;
void * base_virt ;
void * ci_virt ;
u32 reserved ;
__le32 consumer_index ;
u32 producer_idx ;
} ;
struct outbound_queue_table {
u32 element_size_cnt ;
u32 upper_base_addr ;
u32 lower_base_addr ;
void * base_virt ;
u32 pi_upper_base_addr ;
u32 pi_lower_base_addr ;
u32 ci_pci_bar ;
u32 ci_offset ;
u32 total_length ;
void * pi_virt ;
u32 interrup_vec_cnt_delay ;
u32 dinterrup_to_pci_offset ;
__le32 producer_index ;
u32 consumer_idx ;
} ;
struct pm8001_hba_memspace {
void __iomem * memvirtaddr ;
u64 membase ;
u32 memsize ;
} ;
2013-11-11 15:28:14 +05:30
struct isr_param {
struct pm8001_hba_info * drv_inst ;
u32 irq_id ;
} ;
2009-10-14 16:19:21 +08:00
struct pm8001_hba_info {
char name [ PM8001_NAME_LENGTH ] ;
struct list_head list ;
unsigned long flags ;
spinlock_t lock ; /* host-wide lock */
2014-07-09 17:21:01 +05:30
spinlock_t bitmap_lock ;
2009-10-14 16:19:21 +08:00
struct pci_dev * pdev ; /* our device */
struct device * dev ;
struct pm8001_hba_memspace io_mem [ 6 ] ;
struct mpi_mem_req memoryMap ;
2013-04-17 16:26:36 +05:30
struct encrypt encrypt_info ; /* support encryption */
2013-09-04 12:57:00 +05:30
struct forensic_data forensic_info ;
u32 fatal_bar_loc ;
u32 forensic_last_offset ;
u32 fatal_forensic_shift_offset ;
u32 forensic_fatal_step ;
u32 evtlog_ib_offset ;
u32 evtlog_ob_offset ;
2009-10-14 16:19:21 +08:00
void __iomem * msg_unit_tbl_addr ; /*Message Unit Table Addr*/
void __iomem * main_cfg_tbl_addr ; /*Main Config Table Addr*/
void __iomem * general_stat_tbl_addr ; /*General Status Table Addr*/
void __iomem * inbnd_q_tbl_addr ; /*Inbound Queue Config Table Addr*/
void __iomem * outbnd_q_tbl_addr ; /*Outbound Queue Config Table Addr*/
2013-04-17 16:26:36 +05:30
void __iomem * pspa_q_tbl_addr ;
/*MPI SAS PHY attributes Queue Config Table Addr*/
void __iomem * ivt_tbl_addr ; /*MPI IVT Table Addr */
2013-09-04 12:57:00 +05:30
void __iomem * fatal_tbl_addr ; /*MPI IVT Table Addr */
2013-04-17 16:26:36 +05:30
union main_cfg_table main_cfg_tbl ;
union general_status_table gs_tbl ;
struct inbound_queue_table inbnd_q_tbl [ PM8001_MAX_SPCV_INB_NUM ] ;
struct outbound_queue_table outbnd_q_tbl [ PM8001_MAX_SPCV_OUTB_NUM ] ;
struct sas_phy_attribute_table phy_attr_table ;
/* MPI SAS PHY attributes */
2009-10-14 16:19:21 +08:00
u8 sas_addr [ SAS_ADDR_SIZE ] ;
struct sas_ha_struct * sas ; /* SCSI/SAS glue */
struct Scsi_Host * shost ;
u32 chip_id ;
const struct pm8001_chip_info * chip ;
struct completion * nvmd_completion ;
int tags_num ;
unsigned long * tags ;
struct pm8001_phy phy [ PM8001_MAX_PHYS ] ;
struct pm8001_port port [ PM8001_MAX_PHYS ] ;
u32 id ;
u32 irq ;
2013-04-17 16:26:36 +05:30
u32 iomb_size ; /* SPC and SPCV IOMB size */
2009-10-14 16:19:21 +08:00
struct pm8001_device * devices ;
struct pm8001_ccb_info * ccb_info ;
# ifdef PM8001_USE_MSIX
2013-04-17 16:26:36 +05:30
struct msix_entry msix_entries [ PM8001_MAX_MSIX_VEC ] ;
/*for msi-x interrupt*/
2009-10-14 16:19:21 +08:00
int number_of_intr ; /*will be used in remove()*/
# endif
# ifdef PM8001_USE_TASKLET
2013-11-11 15:28:14 +05:30
struct tasklet_struct tasklet [ PM8001_MAX_MSIX_VEC ] ;
2009-10-14 16:19:21 +08:00
# endif
u32 logging_level ;
u32 fw_status ;
2013-04-17 16:37:02 +05:30
u32 smp_exp_mode ;
2009-10-14 16:19:21 +08:00
const struct firmware * fw_image ;
2013-11-11 15:28:14 +05:30
struct isr_param irq_vector [ PM8001_MAX_MSIX_VEC ] ;
2009-10-14 16:19:21 +08:00
} ;
2011-01-24 14:57:29 +01:00
struct pm8001_work {
struct work_struct work ;
2009-10-14 16:19:21 +08:00
struct pm8001_hba_info * pm8001_ha ;
void * data ;
int handler ;
} ;
struct pm8001_fw_image_header {
u8 vender_id [ 8 ] ;
u8 product_id ;
u8 hardware_rev ;
u8 dest_partition ;
u8 reserved ;
u8 fw_rev [ 4 ] ;
__be32 image_length ;
__be32 image_crc ;
__be32 startup_entry ;
} __attribute__ ( ( packed , aligned ( 4 ) ) ) ;
2009-12-07 17:23:08 +08:00
2009-10-14 16:19:21 +08:00
/**
* FW Flash Update status values
*/
# define FLASH_UPDATE_COMPLETE_PENDING_REBOOT 0x00
# define FLASH_UPDATE_IN_PROGRESS 0x01
# define FLASH_UPDATE_HDR_ERR 0x02
# define FLASH_UPDATE_OFFSET_ERR 0x03
# define FLASH_UPDATE_CRC_ERR 0x04
# define FLASH_UPDATE_LENGTH_ERR 0x05
# define FLASH_UPDATE_HW_ERR 0x06
# define FLASH_UPDATE_DNLD_NOT_SUPPORTED 0x10
# define FLASH_UPDATE_DISABLED 0x11
2013-03-19 18:08:08 +05:30
# define NCQ_READ_LOG_FLAG 0x80000000
# define NCQ_ABORT_ALL_FLAG 0x40000000
# define NCQ_2ND_RLE_FLAG 0x20000000
2015-08-11 15:06:26 +05:30
/* Device states */
# define DS_OPERATIONAL 0x01
# define DS_PORT_IN_RESET 0x02
# define DS_IN_RECOVERY 0x03
# define DS_IN_ERROR 0x04
# define DS_NON_OPERATIONAL 0x07
2009-10-14 16:19:21 +08:00
/**
* brief param structure for firmware flash update .
*/
struct fw_flash_updata_info {
u32 cur_image_offset ;
u32 cur_image_len ;
u32 total_image_len ;
struct pm8001_prd sgl ;
} ;
struct fw_control_info {
u32 retcode ; /*ret code (status)*/
u32 phase ; /*ret code phase*/
u32 phaseCmplt ; /*percent complete for the current
update phase */
u32 version ; /*Hex encoded firmware version number*/
u32 offset ; /*Used for downloading firmware */
u32 len ; /*len of buffer*/
u32 size ; /* Used in OS VPD and Trace get size
operations . */
u32 reserved ; /* padding required for 64 bit
alignment */
u8 buffer [ 1 ] ; /* Start of buffer */
} ;
struct fw_control_ex {
struct fw_control_info * fw_control ;
void * buffer ; /* keep buffer pointer to be
2011-03-30 22:57:33 -03:00
freed when the response comes */
2009-10-14 16:19:21 +08:00
void * virtAddr ; /* keep virtual address of the data */
void * usrAddr ; /* keep virtual address of the
user data */
dma_addr_t phys_addr ;
u32 len ; /* len of buffer */
void * payload ; /* pointer to IOCTL Payload */
u8 inProgress ; /*if 1 - the IOCTL request is in
progress */
void * param1 ;
void * param2 ;
void * param3 ;
} ;
2011-01-24 14:57:29 +01:00
/* pm8001 workqueue */
extern struct workqueue_struct * pm8001_wq ;
2009-10-14 16:19:21 +08:00
/******************** function prototype *********************/
int pm8001_tag_alloc ( struct pm8001_hba_info * pm8001_ha , u32 * tag_out ) ;
void pm8001_tag_init ( struct pm8001_hba_info * pm8001_ha ) ;
u32 pm8001_get_ncq_tag ( struct sas_task * task , u32 * tag ) ;
void pm8001_ccb_task_free ( struct pm8001_hba_info * pm8001_ha ,
struct sas_task * task , struct pm8001_ccb_info * ccb , u32 ccb_idx ) ;
int pm8001_phy_control ( struct asd_sas_phy * sas_phy , enum phy_func func ,
void * funcdata ) ;
void pm8001_scan_start ( struct Scsi_Host * shost ) ;
int pm8001_scan_finished ( struct Scsi_Host * shost , unsigned long time ) ;
2014-11-05 10:36:28 +01:00
int pm8001_queue_command ( struct sas_task * task , gfp_t gfp_flags ) ;
2009-10-14 16:19:21 +08:00
int pm8001_abort_task ( struct sas_task * task ) ;
int pm8001_abort_task_set ( struct domain_device * dev , u8 * lun ) ;
int pm8001_clear_aca ( struct domain_device * dev , u8 * lun ) ;
int pm8001_clear_task_set ( struct domain_device * dev , u8 * lun ) ;
int pm8001_dev_found ( struct domain_device * dev ) ;
void pm8001_dev_gone ( struct domain_device * dev ) ;
int pm8001_lu_reset ( struct domain_device * dev , u8 * lun ) ;
int pm8001_I_T_nexus_reset ( struct domain_device * dev ) ;
2013-03-19 18:08:40 +05:30
int pm8001_I_T_nexus_event_handler ( struct domain_device * dev ) ;
2009-10-14 16:19:21 +08:00
int pm8001_query_task ( struct sas_task * task ) ;
2012-01-17 11:52:24 -05:00
void pm8001_open_reject_retry (
struct pm8001_hba_info * pm8001_ha ,
struct sas_task * task_to_close ,
struct pm8001_device * device_to_close ) ;
2009-10-14 16:19:21 +08:00
int pm8001_mem_alloc ( struct pci_dev * pdev , void * * virt_addr ,
dma_addr_t * pphys_addr , u32 * pphys_addr_hi , u32 * pphys_addr_lo ,
u32 mem_size , u32 align ) ;
2013-02-27 20:27:43 +05:30
void pm8001_chip_iounmap ( struct pm8001_hba_info * pm8001_ha ) ;
int pm8001_mpi_build_cmd ( struct pm8001_hba_info * pm8001_ha ,
struct inbound_queue_table * circularQ ,
u32 opCode , void * payload , u32 responseQueue ) ;
int pm8001_mpi_msg_free_get ( struct inbound_queue_table * circularQ ,
u16 messageSize , void * * messagePtr ) ;
u32 pm8001_mpi_msg_free_set ( struct pm8001_hba_info * pm8001_ha , void * pMsg ,
struct outbound_queue_table * circularQ , u8 bc ) ;
u32 pm8001_mpi_msg_consume ( struct pm8001_hba_info * pm8001_ha ,
struct outbound_queue_table * circularQ ,
void * * messagePtr1 , u8 * pBC ) ;
int pm8001_chip_set_dev_state_req ( struct pm8001_hba_info * pm8001_ha ,
struct pm8001_device * pm8001_dev , u32 state ) ;
int pm8001_chip_fw_flash_update_req ( struct pm8001_hba_info * pm8001_ha ,
void * payload ) ;
int pm8001_chip_fw_flash_update_build ( struct pm8001_hba_info * pm8001_ha ,
void * fw_flash_updata_info , u32 tag ) ;
int pm8001_chip_set_nvmd_req ( struct pm8001_hba_info * pm8001_ha , void * payload ) ;
int pm8001_chip_get_nvmd_req ( struct pm8001_hba_info * pm8001_ha , void * payload ) ;
int pm8001_chip_ssp_tm_req ( struct pm8001_hba_info * pm8001_ha ,
struct pm8001_ccb_info * ccb ,
struct pm8001_tmf_task * tmf ) ;
int pm8001_chip_abort_task ( struct pm8001_hba_info * pm8001_ha ,
struct pm8001_device * pm8001_dev ,
u8 flag , u32 task_tag , u32 cmd_tag ) ;
int pm8001_chip_dereg_dev_req ( struct pm8001_hba_info * pm8001_ha , u32 device_id ) ;
void pm8001_chip_make_sg ( struct scatterlist * scatter , int nr , void * prd ) ;
void pm8001_work_fn ( struct work_struct * work ) ;
int pm8001_handle_event ( struct pm8001_hba_info * pm8001_ha ,
void * data , int handler ) ;
void pm8001_mpi_set_dev_state_resp ( struct pm8001_hba_info * pm8001_ha ,
void * piomb ) ;
void pm8001_mpi_set_nvmd_resp ( struct pm8001_hba_info * pm8001_ha ,
void * piomb ) ;
void pm8001_mpi_get_nvmd_resp ( struct pm8001_hba_info * pm8001_ha ,
void * piomb ) ;
int pm8001_mpi_local_phy_ctl ( struct pm8001_hba_info * pm8001_ha ,
void * piomb ) ;
void pm8001_get_lrate_mode ( struct pm8001_phy * phy , u8 link_rate ) ;
void pm8001_get_attached_sas_addr ( struct pm8001_phy * phy , u8 * sas_addr ) ;
void pm8001_bytes_dmaed ( struct pm8001_hba_info * pm8001_ha , int i ) ;
int pm8001_mpi_reg_resp ( struct pm8001_hba_info * pm8001_ha , void * piomb ) ;
int pm8001_mpi_dereg_resp ( struct pm8001_hba_info * pm8001_ha , void * piomb ) ;
int pm8001_mpi_fw_flash_update_resp ( struct pm8001_hba_info * pm8001_ha ,
void * piomb ) ;
int pm8001_mpi_general_event ( struct pm8001_hba_info * pm8001_ha , void * piomb ) ;
int pm8001_mpi_task_abort_resp ( struct pm8001_hba_info * pm8001_ha , void * piomb ) ;
2013-03-19 18:08:08 +05:30
struct sas_task * pm8001_alloc_task ( void ) ;
void pm8001_task_done ( struct sas_task * task ) ;
void pm8001_free_task ( struct sas_task * task ) ;
void pm8001_tag_free ( struct pm8001_hba_info * pm8001_ha , u32 tag ) ;
struct pm8001_device * pm8001_find_dev ( struct pm8001_hba_info * pm8001_ha ,
u32 device_id ) ;
2013-03-19 18:08:40 +05:30
int pm80xx_set_thermal_config ( struct pm8001_hba_info * pm8001_ha ) ;
2013-02-27 20:27:43 +05:30
2012-01-17 09:18:57 -05:00
int pm8001_bar4_shift ( struct pm8001_hba_info * pm8001_ha , u32 shiftValue ) ;
2013-09-18 13:02:44 +05:30
void pm8001_set_phy_profile ( struct pm8001_hba_info * pm8001_ha ,
u32 length , u8 * buf ) ;
2013-09-04 12:57:00 +05:30
int pm80xx_bar4_shift ( struct pm8001_hba_info * pm8001_ha , u32 shiftValue ) ;
ssize_t pm80xx_get_fatal_dump ( struct device * cdev ,
struct device_attribute * attr , char * buf ) ;
ssize_t pm8001_get_gsm_dump ( struct device * cdev , u32 , char * buf ) ;
2009-10-14 16:19:21 +08:00
/* ctl shared API */
extern struct device_attribute * pm8001_host_attrs [ ] ;
2014-01-16 15:26:21 +05:30
static inline void
pm8001_ccb_task_free_done ( struct pm8001_hba_info * pm8001_ha ,
struct sas_task * task , struct pm8001_ccb_info * ccb ,
u32 ccb_idx )
{
pm8001_ccb_task_free ( pm8001_ha , task , ccb , ccb_idx ) ;
smp_mb ( ) ; /*in order to force CPU ordering*/
spin_unlock ( & pm8001_ha - > lock ) ;
task - > task_done ( task ) ;
spin_lock ( & pm8001_ha - > lock ) ;
}
2009-10-14 16:19:21 +08:00
# endif