Commit e5742101 authored by Sakthivel K's avatar Sakthivel K Committed by James Bottomley

[SCSI] pm80xx: Added SPCv/ve specific ids, variables and modify for SPC

Updated pci id table with device, vendor, subdevice and subvendor ids
for 8081, 8088, 8089 SAS/SATA controllers. Added SPCv/ve related macros.
Updated macros, hba info structure and other structures for SPCv/ve.
Update of structure and variable names for SPC hardware functionalities.
Signed-off-by: default avatarSakthivel K <Sakthivel.SaravananKamalRaju@pmcs.com>
Signed-off-by: default avatarAnand Kumar S <AnandKumar.Santhanam@pmcs.com>
Acked-by: default avatarJack Wang <jack_wang@usish.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 6a7252fd
/*
* PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
* PMC-Sierra 8001/8081/8088/8089 SAS/SATA based host adapters driver
*
* Copyright (c) 2008-2009 USI Co., Ltd.
* All rights reserved.
......@@ -58,8 +58,13 @@ static ssize_t pm8001_ctl_mpi_interface_rev_show(struct device *cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
return snprintf(buf, PAGE_SIZE, "%d\n",
pm8001_ha->main_cfg_tbl.interface_rev);
if (pm8001_ha->chip_id == chip_8001) {
return snprintf(buf, PAGE_SIZE, "%d\n",
pm8001_ha->main_cfg_tbl.pm8001_tbl.interface_rev);
} else {
return snprintf(buf, PAGE_SIZE, "%d\n",
pm8001_ha->main_cfg_tbl.pm80xx_tbl.interface_rev);
}
}
static
DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL);
......@@ -78,11 +83,19 @@ static ssize_t pm8001_ctl_fw_version_show(struct device *cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
(u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 24),
(u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 16),
(u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 8),
(u8)(pm8001_ha->main_cfg_tbl.firmware_rev));
if (pm8001_ha->chip_id == chip_8001) {
return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
(u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 24),
(u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 16),
(u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 8),
(u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev));
} else {
return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 24),
(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 16),
(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 8),
(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev));
}
}
static DEVICE_ATTR(fw_version, S_IRUGO, pm8001_ctl_fw_version_show, NULL);
/**
......@@ -99,8 +112,13 @@ static ssize_t pm8001_ctl_max_out_io_show(struct device *cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
return snprintf(buf, PAGE_SIZE, "%d\n",
pm8001_ha->main_cfg_tbl.max_out_io);
if (pm8001_ha->chip_id == chip_8001) {
return snprintf(buf, PAGE_SIZE, "%d\n",
pm8001_ha->main_cfg_tbl.pm8001_tbl.max_out_io);
} else {
return snprintf(buf, PAGE_SIZE, "%d\n",
pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io);
}
}
static DEVICE_ATTR(max_out_io, S_IRUGO, pm8001_ctl_max_out_io_show, NULL);
/**
......@@ -117,8 +135,15 @@ static ssize_t pm8001_ctl_max_devices_show(struct device *cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
return snprintf(buf, PAGE_SIZE, "%04d\n",
(u16)(pm8001_ha->main_cfg_tbl.max_sgl >> 16));
if (pm8001_ha->chip_id == chip_8001) {
return snprintf(buf, PAGE_SIZE, "%04d\n",
(u16)(pm8001_ha->main_cfg_tbl.pm8001_tbl.max_sgl >> 16)
);
} else {
return snprintf(buf, PAGE_SIZE, "%04d\n",
(u16)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_sgl >> 16)
);
}
}
static DEVICE_ATTR(max_devices, S_IRUGO, pm8001_ctl_max_devices_show, NULL);
/**
......@@ -136,8 +161,15 @@ static ssize_t pm8001_ctl_max_sg_list_show(struct device *cdev,
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
return snprintf(buf, PAGE_SIZE, "%04d\n",
pm8001_ha->main_cfg_tbl.max_sgl & 0x0000FFFF);
if (pm8001_ha->chip_id == chip_8001) {
return snprintf(buf, PAGE_SIZE, "%04d\n",
pm8001_ha->main_cfg_tbl.pm8001_tbl.max_sgl & 0x0000FFFF
);
} else {
return snprintf(buf, PAGE_SIZE, "%04d\n",
pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_sgl & 0x0000FFFF
);
}
}
static DEVICE_ATTR(max_sg_list, S_IRUGO, pm8001_ctl_max_sg_list_show, NULL);
......@@ -173,7 +205,14 @@ static ssize_t pm8001_ctl_sas_spec_support_show(struct device *cdev,
struct Scsi_Host *shost = class_to_shost(cdev);
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
mode = (pm8001_ha->main_cfg_tbl.ctrl_cap_flag & 0xfe000000)>>25;
/* fe000000 means supports SAS2.1 */
if (pm8001_ha->chip_id == chip_8001)
mode = (pm8001_ha->main_cfg_tbl.pm8001_tbl.ctrl_cap_flag &
0xfe000000)>>25;
else
/* fe000000 means supports SAS2.1 */
mode = (pm8001_ha->main_cfg_tbl.pm80xx_tbl.ctrl_cap_flag &
0xfe000000)>>25;
return show_sas_spec_support_status(mode, buf);
}
static DEVICE_ATTR(sas_spec_support, S_IRUGO,
......
/*
* PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
* PMC-Sierra 8001/8081/8088/8089 SAS/SATA based host adapters driver
*
* Copyright (c) 2008-2009 USI Co., Ltd.
* All rights reserved.
......@@ -43,6 +43,10 @@
enum chip_flavors {
chip_8001,
chip_8008,
chip_8009,
chip_8018,
chip_8019
};
#define USI_MAX_MEMCNT 9
#define PM8001_MAX_DMA_SG SG_ALL
......@@ -69,12 +73,19 @@ enum port_type {
#define PM8001_MPI_QUEUE 1024 /* maximum mpi queue entries */
#define PM8001_MAX_INB_NUM 1
#define PM8001_MAX_OUTB_NUM 1
#define PM8001_MAX_SPCV_INB_NUM 1
#define PM8001_MAX_SPCV_OUTB_NUM 4
#define PM8001_CAN_QUEUE 508 /* SCSI Queue depth */
/* Inbound/Outbound queue size */
#define IOMB_SIZE_SPC 64
#define IOMB_SIZE_SPCV 128
/* unchangeable hardware details */
#define PM8001_MAX_PHYS 8 /* max. possible phys */
#define PM8001_MAX_PORTS 8 /* max. possible ports */
#define PM8001_MAX_DEVICES 1024 /* max supported device */
#define PM8001_MAX_PHYS 16 /* max. possible phys */
#define PM8001_MAX_PORTS 16 /* max. possible ports */
#define PM8001_MAX_DEVICES 2048 /* max supported device */
#define PM8001_MAX_MSIX_VEC 64 /* max msi-x int for spcv/ve */
enum memory_region_num {
AAP1 = 0x0, /* application acceleration processor */
......
......@@ -50,32 +50,39 @@
static void read_main_config_table(struct pm8001_hba_info *pm8001_ha)
{
void __iomem *address = pm8001_ha->main_cfg_tbl_addr;
pm8001_ha->main_cfg_tbl.signature = pm8001_mr32(address, 0x00);
pm8001_ha->main_cfg_tbl.interface_rev = pm8001_mr32(address, 0x04);
pm8001_ha->main_cfg_tbl.firmware_rev = pm8001_mr32(address, 0x08);
pm8001_ha->main_cfg_tbl.max_out_io = pm8001_mr32(address, 0x0C);
pm8001_ha->main_cfg_tbl.max_sgl = pm8001_mr32(address, 0x10);
pm8001_ha->main_cfg_tbl.ctrl_cap_flag = pm8001_mr32(address, 0x14);
pm8001_ha->main_cfg_tbl.gst_offset = pm8001_mr32(address, 0x18);
pm8001_ha->main_cfg_tbl.inbound_queue_offset =
pm8001_ha->main_cfg_tbl.pm8001_tbl.signature =
pm8001_mr32(address, 0x00);
pm8001_ha->main_cfg_tbl.pm8001_tbl.interface_rev =
pm8001_mr32(address, 0x04);
pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev =
pm8001_mr32(address, 0x08);
pm8001_ha->main_cfg_tbl.pm8001_tbl.max_out_io =
pm8001_mr32(address, 0x0C);
pm8001_ha->main_cfg_tbl.pm8001_tbl.max_sgl =
pm8001_mr32(address, 0x10);
pm8001_ha->main_cfg_tbl.pm8001_tbl.ctrl_cap_flag =
pm8001_mr32(address, 0x14);
pm8001_ha->main_cfg_tbl.pm8001_tbl.gst_offset =
pm8001_mr32(address, 0x18);
pm8001_ha->main_cfg_tbl.pm8001_tbl.inbound_queue_offset =
pm8001_mr32(address, MAIN_IBQ_OFFSET);
pm8001_ha->main_cfg_tbl.outbound_queue_offset =
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_queue_offset =
pm8001_mr32(address, MAIN_OBQ_OFFSET);
pm8001_ha->main_cfg_tbl.hda_mode_flag =
pm8001_ha->main_cfg_tbl.pm8001_tbl.hda_mode_flag =
pm8001_mr32(address, MAIN_HDA_FLAGS_OFFSET);
/* read analog Setting offset from the configuration table */
pm8001_ha->main_cfg_tbl.anolog_setup_table_offset =
pm8001_ha->main_cfg_tbl.pm8001_tbl.anolog_setup_table_offset =
pm8001_mr32(address, MAIN_ANALOG_SETUP_OFFSET);
/* read Error Dump Offset and Length */
pm8001_ha->main_cfg_tbl.fatal_err_dump_offset0 =
pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_offset0 =
pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_OFFSET);
pm8001_ha->main_cfg_tbl.fatal_err_dump_length0 =
pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_length0 =
pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_LENGTH);
pm8001_ha->main_cfg_tbl.fatal_err_dump_offset1 =
pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_offset1 =
pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_OFFSET);
pm8001_ha->main_cfg_tbl.fatal_err_dump_length1 =
pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_length1 =
pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_LENGTH);
}
......@@ -86,31 +93,56 @@ static void read_main_config_table(struct pm8001_hba_info *pm8001_ha)
static void read_general_status_table(struct pm8001_hba_info *pm8001_ha)
{
void __iomem *address = pm8001_ha->general_stat_tbl_addr;
pm8001_ha->gs_tbl.gst_len_mpistate = pm8001_mr32(address, 0x00);
pm8001_ha->gs_tbl.iq_freeze_state0 = pm8001_mr32(address, 0x04);
pm8001_ha->gs_tbl.iq_freeze_state1 = pm8001_mr32(address, 0x08);
pm8001_ha->gs_tbl.msgu_tcnt = pm8001_mr32(address, 0x0C);
pm8001_ha->gs_tbl.iop_tcnt = pm8001_mr32(address, 0x10);
pm8001_ha->gs_tbl.reserved = pm8001_mr32(address, 0x14);
pm8001_ha->gs_tbl.phy_state[0] = pm8001_mr32(address, 0x18);
pm8001_ha->gs_tbl.phy_state[1] = pm8001_mr32(address, 0x1C);
pm8001_ha->gs_tbl.phy_state[2] = pm8001_mr32(address, 0x20);
pm8001_ha->gs_tbl.phy_state[3] = pm8001_mr32(address, 0x24);
pm8001_ha->gs_tbl.phy_state[4] = pm8001_mr32(address, 0x28);
pm8001_ha->gs_tbl.phy_state[5] = pm8001_mr32(address, 0x2C);
pm8001_ha->gs_tbl.phy_state[6] = pm8001_mr32(address, 0x30);
pm8001_ha->gs_tbl.phy_state[7] = pm8001_mr32(address, 0x34);
pm8001_ha->gs_tbl.reserved1 = pm8001_mr32(address, 0x38);
pm8001_ha->gs_tbl.reserved2 = pm8001_mr32(address, 0x3C);
pm8001_ha->gs_tbl.reserved3 = pm8001_mr32(address, 0x40);
pm8001_ha->gs_tbl.recover_err_info[0] = pm8001_mr32(address, 0x44);
pm8001_ha->gs_tbl.recover_err_info[1] = pm8001_mr32(address, 0x48);
pm8001_ha->gs_tbl.recover_err_info[2] = pm8001_mr32(address, 0x4C);
pm8001_ha->gs_tbl.recover_err_info[3] = pm8001_mr32(address, 0x50);
pm8001_ha->gs_tbl.recover_err_info[4] = pm8001_mr32(address, 0x54);
pm8001_ha->gs_tbl.recover_err_info[5] = pm8001_mr32(address, 0x58);
pm8001_ha->gs_tbl.recover_err_info[6] = pm8001_mr32(address, 0x5C);
pm8001_ha->gs_tbl.recover_err_info[7] = pm8001_mr32(address, 0x60);
pm8001_ha->gs_tbl.pm8001_tbl.gst_len_mpistate =
pm8001_mr32(address, 0x00);
pm8001_ha->gs_tbl.pm8001_tbl.iq_freeze_state0 =
pm8001_mr32(address, 0x04);
pm8001_ha->gs_tbl.pm8001_tbl.iq_freeze_state1 =
pm8001_mr32(address, 0x08);
pm8001_ha->gs_tbl.pm8001_tbl.msgu_tcnt =
pm8001_mr32(address, 0x0C);
pm8001_ha->gs_tbl.pm8001_tbl.iop_tcnt =
pm8001_mr32(address, 0x10);
pm8001_ha->gs_tbl.pm8001_tbl.rsvd =
pm8001_mr32(address, 0x14);
pm8001_ha->gs_tbl.pm8001_tbl.phy_state[0] =
pm8001_mr32(address, 0x18);
pm8001_ha->gs_tbl.pm8001_tbl.phy_state[1] =
pm8001_mr32(address, 0x1C);
pm8001_ha->gs_tbl.pm8001_tbl.phy_state[2] =
pm8001_mr32(address, 0x20);
pm8001_ha->gs_tbl.pm8001_tbl.phy_state[3] =
pm8001_mr32(address, 0x24);
pm8001_ha->gs_tbl.pm8001_tbl.phy_state[4] =
pm8001_mr32(address, 0x28);
pm8001_ha->gs_tbl.pm8001_tbl.phy_state[5] =
pm8001_mr32(address, 0x2C);
pm8001_ha->gs_tbl.pm8001_tbl.phy_state[6] =
pm8001_mr32(address, 0x30);
pm8001_ha->gs_tbl.pm8001_tbl.phy_state[7] =
pm8001_mr32(address, 0x34);
pm8001_ha->gs_tbl.pm8001_tbl.gpio_input_val =
pm8001_mr32(address, 0x38);
pm8001_ha->gs_tbl.pm8001_tbl.rsvd1[0] =
pm8001_mr32(address, 0x3C);
pm8001_ha->gs_tbl.pm8001_tbl.rsvd1[1] =
pm8001_mr32(address, 0x40);
pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[0] =
pm8001_mr32(address, 0x44);
pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[1] =
pm8001_mr32(address, 0x48);
pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[2] =
pm8001_mr32(address, 0x4C);
pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[3] =
pm8001_mr32(address, 0x50);
pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[4] =
pm8001_mr32(address, 0x54);
pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[5] =
pm8001_mr32(address, 0x58);
pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[6] =
pm8001_mr32(address, 0x5C);
pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[7] =
pm8001_mr32(address, 0x60);
}
/**
......@@ -155,38 +187,41 @@ static void read_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha)
*/
static void init_default_table_values(struct pm8001_hba_info *pm8001_ha)
{
int qn = 1;
int i;
u32 offsetib, offsetob;
void __iomem *addressib = pm8001_ha->inbnd_q_tbl_addr;
void __iomem *addressob = pm8001_ha->outbnd_q_tbl_addr;
pm8001_ha->main_cfg_tbl.inbound_q_nppd_hppd = 0;
pm8001_ha->main_cfg_tbl.outbound_hw_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.outbound_hw_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.upper_event_log_addr =
pm8001_ha->main_cfg_tbl.pm8001_tbl.inbound_q_nppd_hppd = 0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ITNexus_event_pid0_3 =
0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ITNexus_event_pid4_7 =
0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ssp_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ssp_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_smp_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_smp_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_event_log_addr =
pm8001_ha->memoryMap.region[AAP1].phys_addr_hi;
pm8001_ha->main_cfg_tbl.lower_event_log_addr =
pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_event_log_addr =
pm8001_ha->memoryMap.region[AAP1].phys_addr_lo;
pm8001_ha->main_cfg_tbl.event_log_size = PM8001_EVENT_LOG_SIZE;
pm8001_ha->main_cfg_tbl.event_log_option = 0x01;
pm8001_ha->main_cfg_tbl.upper_iop_event_log_addr =
pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_size =
PM8001_EVENT_LOG_SIZE;
pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_option = 0x01;
pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_iop_event_log_addr =
pm8001_ha->memoryMap.region[IOP].phys_addr_hi;
pm8001_ha->main_cfg_tbl.lower_iop_event_log_addr =
pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_iop_event_log_addr =
pm8001_ha->memoryMap.region[IOP].phys_addr_lo;
pm8001_ha->main_cfg_tbl.iop_event_log_size = PM8001_EVENT_LOG_SIZE;
pm8001_ha->main_cfg_tbl.iop_event_log_option = 0x01;
pm8001_ha->main_cfg_tbl.fatal_err_interrupt = 0x01;
for (i = 0; i < qn; i++) {
pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_size =
PM8001_EVENT_LOG_SIZE;
pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_option = 0x01;
pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_interrupt = 0x01;
for (i = 0; i < PM8001_MAX_INB_NUM; i++) {
pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt =
PM8001_MPI_QUEUE | (64 << 16) | (0x00<<30);
pm8001_ha->inbnd_q_tbl[i].upper_base_addr =
......@@ -212,7 +247,7 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha)
pm8001_ha->inbnd_q_tbl[i].producer_idx = 0;
pm8001_ha->inbnd_q_tbl[i].consumer_index = 0;
}
for (i = 0; i < qn; i++) {
for (i = 0; i < PM8001_MAX_OUTB_NUM; i++) {
pm8001_ha->outbnd_q_tbl[i].element_size_cnt =
PM8001_MPI_QUEUE | (64 << 16) | (0x01<<30);
pm8001_ha->outbnd_q_tbl[i].upper_base_addr =
......@@ -250,42 +285,51 @@ static void update_main_config_table(struct pm8001_hba_info *pm8001_ha)
{
void __iomem *address = pm8001_ha->main_cfg_tbl_addr;
pm8001_mw32(address, 0x24,
pm8001_ha->main_cfg_tbl.inbound_q_nppd_hppd);
pm8001_ha->main_cfg_tbl.pm8001_tbl.inbound_q_nppd_hppd);
pm8001_mw32(address, 0x28,
pm8001_ha->main_cfg_tbl.outbound_hw_event_pid0_3);
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid0_3);
pm8001_mw32(address, 0x2C,
pm8001_ha->main_cfg_tbl.outbound_hw_event_pid4_7);
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid4_7);
pm8001_mw32(address, 0x30,
pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid0_3);
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid0_3);
pm8001_mw32(address, 0x34,
pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid4_7);
pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid4_7);
pm8001_mw32(address, 0x38,
pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid0_3);
pm8001_ha->main_cfg_tbl.pm8001_tbl.
outbound_tgt_ITNexus_event_pid0_3);
pm8001_mw32(address, 0x3C,
pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid4_7);
pm8001_ha->main_cfg_tbl.pm8001_tbl.
outbound_tgt_ITNexus_event_pid4_7);
pm8001_mw32(address, 0x40,
pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid0_3);
pm8001_ha->main_cfg_tbl.pm8001_tbl.
outbound_tgt_ssp_event_pid0_3);
pm8001_mw32(address, 0x44,
pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid4_7);
pm8001_ha->main_cfg_tbl.pm8001_tbl.
outbound_tgt_ssp_event_pid4_7);
pm8001_mw32(address, 0x48,
pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid0_3);
pm8001_ha->main_cfg_tbl.pm8001_tbl.
outbound_tgt_smp_event_pid0_3);
pm8001_mw32(address, 0x4C,
pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid4_7);
pm8001_ha->main_cfg_tbl.pm8001_tbl.
outbound_tgt_smp_event_pid4_7);
pm8001_mw32(address, 0x50,
pm8001_ha->main_cfg_tbl.upper_event_log_addr);
pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_event_log_addr);
pm8001_mw32(address, 0x54,
pm8001_ha->main_cfg_tbl.lower_event_log_addr);
pm8001_mw32(address, 0x58, pm8001_ha->main_cfg_tbl.event_log_size);
pm8001_mw32(address, 0x5C, pm8001_ha->main_cfg_tbl.event_log_option);
pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_event_log_addr);
pm8001_mw32(address, 0x58,
pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_size);
pm8001_mw32(address, 0x5C,
pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_option);
pm8001_mw32(address, 0x60,
pm8001_ha->main_cfg_tbl.upper_iop_event_log_addr);
pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_iop_event_log_addr);
pm8001_mw32(address, 0x64,
pm8001_ha->main_cfg_tbl.lower_iop_event_log_addr);
pm8001_mw32(address, 0x68, pm8001_ha->main_cfg_tbl.iop_event_log_size);
pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_iop_event_log_addr);
pm8001_mw32(address, 0x68,
pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_size);
pm8001_mw32(address, 0x6C,
pm8001_ha->main_cfg_tbl.iop_event_log_option);
pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_option);
pm8001_mw32(address, 0x70,
pm8001_ha->main_cfg_tbl.fatal_err_interrupt);
pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_interrupt);
}
/**
......@@ -4706,4 +4750,3 @@ const struct pm8001_dispatch pm8001_8001_dispatch = {
.set_dev_state_req = pm8001_chip_set_dev_state_req,
.sas_re_init_req = pm8001_chip_sas_re_initialization,
};
/*
* PMC-Sierra SPC 8001 SAS/SATA based host adapters driver
* PMC-Sierra PM8001/8081/8088/8089 SAS/SATA based host adapters driver
*
* Copyright (c) 2008-2009 USI Co., Ltd.
* All rights reserved.
......@@ -44,8 +44,12 @@
static struct scsi_transport_template *pm8001_stt;
/**
* chip info structure to identify chip key functionality as
* encryption available/not, no of ports, hw specific function ref
*/
static const struct pm8001_chip_info pm8001_chips[] = {
[chip_8001] = { 8, &pm8001_8001_dispatch,},
[chip_8001] = {0, 8, &pm8001_8001_dispatch,},
};
static int pm8001_id;
......@@ -843,14 +847,45 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
return rc;
}
/* update of pci device, vendor id and driver data with
* unique value for each of the controller
*/
static struct pci_device_id pm8001_pci_table[] = {
{
PCI_VDEVICE(PMC_Sierra, 0x8001), chip_8001
},
{ PCI_VDEVICE(PMC_Sierra, 0x8001), chip_8001 },
{
PCI_DEVICE(0x117c, 0x0042),
.driver_data = chip_8001
},
/* Support for SPC/SPCv/SPCve controllers */
{ PCI_VDEVICE(ADAPTEC2, 0x8001), chip_8001 },
{ PCI_VDEVICE(PMC_Sierra, 0x8008), chip_8008 },
{ PCI_VDEVICE(ADAPTEC2, 0x8008), chip_8008 },
{ PCI_VDEVICE(PMC_Sierra, 0x8018), chip_8018 },
{ PCI_VDEVICE(ADAPTEC2, 0x8018), chip_8018 },
{ PCI_VDEVICE(PMC_Sierra, 0x8009), chip_8009 },
{ PCI_VDEVICE(ADAPTEC2, 0x8009), chip_8009 },
{ PCI_VDEVICE(PMC_Sierra, 0x8019), chip_8019 },
{ PCI_VDEVICE(ADAPTEC2, 0x8019), chip_8019 },
{ PCI_VENDOR_ID_ADAPTEC2, 0x8081,
PCI_VENDOR_ID_ADAPTEC2, 0x0400, 0, 0, chip_8001 },
{ PCI_VENDOR_ID_ADAPTEC2, 0x8081,
PCI_VENDOR_ID_ADAPTEC2, 0x0800, 0, 0, chip_8001 },
{ PCI_VENDOR_ID_ADAPTEC2, 0x8088,
PCI_VENDOR_ID_ADAPTEC2, 0x0008, 0, 0, chip_8008 },
{ PCI_VENDOR_ID_ADAPTEC2, 0x8088,
PCI_VENDOR_ID_ADAPTEC2, 0x0800, 0, 0, chip_8008 },
{ PCI_VENDOR_ID_ADAPTEC2, 0x8089,
PCI_VENDOR_ID_ADAPTEC2, 0x0008, 0, 0, chip_8009 },
{ PCI_VENDOR_ID_ADAPTEC2, 0x8089,
PCI_VENDOR_ID_ADAPTEC2, 0x0800, 0, 0, chip_8009 },
{ PCI_VENDOR_ID_ADAPTEC2, 0x8088,
PCI_VENDOR_ID_ADAPTEC2, 0x0016, 0, 0, chip_8018 },
{ PCI_VENDOR_ID_ADAPTEC2, 0x8088,
PCI_VENDOR_ID_ADAPTEC2, 0x1600, 0, 0, chip_8018 },
{ PCI_VENDOR_ID_ADAPTEC2, 0x8089,
PCI_VENDOR_ID_ADAPTEC2, 0x0016, 0, 0, chip_8019 },
{ PCI_VENDOR_ID_ADAPTEC2, 0x8089,
PCI_VENDOR_ID_ADAPTEC2, 0x1600, 0, 0, chip_8019 },
{} /* terminate list */
};
......@@ -902,7 +937,8 @@ module_init(pm8001_init);
module_exit(pm8001_exit);
MODULE_AUTHOR("Jack Wang <jack_wang@usish.com>");
MODULE_DESCRIPTION("PMC-Sierra PM8001 SAS/SATA controller driver");
MODULE_DESCRIPTION(
"PMC-Sierra PM8001/8081/8088/8089 SAS/SATA controller driver");
MODULE_VERSION(DRV_VERSION);
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, pm8001_pci_table);
......
......@@ -173,6 +173,7 @@ struct pm8001_dispatch {
};
struct pm8001_chip_info {
u32 encrypt;
u32 n_phy;
const struct pm8001_dispatch *dispatch;
};
......@@ -256,7 +257,20 @@ struct mpi_mem_req {
struct mpi_mem region[USI_MAX_MEMCNT];
};
struct main_cfg_table {
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 {
u32 signature;
u32 interface_rev;
u32 firmware_rev;
......@@ -292,19 +306,67 @@ struct main_cfg_table {
u32 fatal_err_dump_length1;
u32 hda_mode_flag;
u32 anolog_setup_table_offset;
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;
u32 rsvd[10];
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;
} pm80xx_tbl;
};
struct general_status_table {
union general_status_table {
struct {
u32 gst_len_mpistate;
u32 iq_freeze_state0;
u32 iq_freeze_state1;
u32 msgu_tcnt;
u32 iop_tcnt;
u32 reserved;
u32 rsvd;
u32 phy_state[8];
u32 reserved1;
u32 reserved2;
u32 reserved3;
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];
u32 recover_err_info[8];
} pm80xx_tbl;
};
struct inbound_queue_table {
u32 element_pri_size_cnt;
......@@ -351,15 +413,21 @@ struct pm8001_hba_info {
struct device *dev;
struct pm8001_hba_memspace io_mem[6];
struct mpi_mem_req memoryMap;
struct encrypt encrypt_info; /* support encryption */
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*/
struct main_cfg_table main_cfg_tbl;
struct general_status_table gs_tbl;
struct inbound_queue_table inbnd_q_tbl[PM8001_MAX_INB_NUM];
struct outbound_queue_table outbnd_q_tbl[PM8001_MAX_OUTB_NUM];
void __iomem *pspa_q_tbl_addr;
/*MPI SAS PHY attributes Queue Config Table Addr*/
void __iomem *ivt_tbl_addr; /*MPI IVT Table Addr */
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 */
u8 sas_addr[SAS_ADDR_SIZE];
struct sas_ha_struct *sas;/* SCSI/SAS glue */
struct Scsi_Host *shost;
......@@ -372,10 +440,12 @@ struct pm8001_hba_info {
struct pm8001_port port[PM8001_MAX_PHYS];
u32 id;
u32 irq;
u32 iomb_size; /* SPC and SPCV IOMB size */
struct pm8001_device *devices;
struct pm8001_ccb_info *ccb_info;
#ifdef PM8001_USE_MSIX
struct msix_entry msix_entries[16];/*for msi-x interrupt*/
struct msix_entry msix_entries[PM8001_MAX_MSIX_VEC];
/*for msi-x interrupt*/
int number_of_intr;/*will be used in remove()*/
#endif
#ifdef PM8001_USE_TASKLET
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment