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. * Copyright (c) 2008-2009 USI Co., Ltd.
* All rights reserved. * All rights reserved.
...@@ -58,8 +58,13 @@ static ssize_t pm8001_ctl_mpi_interface_rev_show(struct device *cdev, ...@@ -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 sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
if (pm8001_ha->chip_id == chip_8001) {
return snprintf(buf, PAGE_SIZE, "%d\n", return snprintf(buf, PAGE_SIZE, "%d\n",
pm8001_ha->main_cfg_tbl.interface_rev); 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 static
DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL); 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, ...@@ -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 sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
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", 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.pm80xx_tbl.firmware_rev >> 24),
(u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 16), (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 16),
(u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 8), (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 8),
(u8)(pm8001_ha->main_cfg_tbl.firmware_rev)); (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev));
}
} }
static DEVICE_ATTR(fw_version, S_IRUGO, pm8001_ctl_fw_version_show, NULL); 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, ...@@ -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 sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
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", return snprintf(buf, PAGE_SIZE, "%d\n",
pm8001_ha->main_cfg_tbl.max_out_io); 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); 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, ...@@ -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 sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
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", return snprintf(buf, PAGE_SIZE, "%04d\n",
(u16)(pm8001_ha->main_cfg_tbl.max_sgl >> 16)); (u16)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_sgl >> 16)
);
}
} }
static DEVICE_ATTR(max_devices, S_IRUGO, pm8001_ctl_max_devices_show, NULL); 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, ...@@ -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 sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
if (pm8001_ha->chip_id == chip_8001) {
return snprintf(buf, PAGE_SIZE, "%04d\n", return snprintf(buf, PAGE_SIZE, "%04d\n",
pm8001_ha->main_cfg_tbl.max_sgl & 0x0000FFFF); 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); 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, ...@@ -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 Scsi_Host *shost = class_to_shost(cdev);
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; 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); return show_sas_spec_support_status(mode, buf);
} }
static DEVICE_ATTR(sas_spec_support, S_IRUGO, 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. * Copyright (c) 2008-2009 USI Co., Ltd.
* All rights reserved. * All rights reserved.
...@@ -43,6 +43,10 @@ ...@@ -43,6 +43,10 @@
enum chip_flavors { enum chip_flavors {
chip_8001, chip_8001,
chip_8008,
chip_8009,
chip_8018,
chip_8019
}; };
#define USI_MAX_MEMCNT 9 #define USI_MAX_MEMCNT 9
#define PM8001_MAX_DMA_SG SG_ALL #define PM8001_MAX_DMA_SG SG_ALL
...@@ -69,12 +73,19 @@ enum port_type { ...@@ -69,12 +73,19 @@ enum port_type {
#define PM8001_MPI_QUEUE 1024 /* maximum mpi queue entries */ #define PM8001_MPI_QUEUE 1024 /* maximum mpi queue entries */
#define PM8001_MAX_INB_NUM 1 #define PM8001_MAX_INB_NUM 1
#define PM8001_MAX_OUTB_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 */ #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 */ /* unchangeable hardware details */
#define PM8001_MAX_PHYS 8 /* max. possible phys */ #define PM8001_MAX_PHYS 16 /* max. possible phys */
#define PM8001_MAX_PORTS 8 /* max. possible ports */ #define PM8001_MAX_PORTS 16 /* max. possible ports */
#define PM8001_MAX_DEVICES 1024 /* max supported device */ #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 { enum memory_region_num {
AAP1 = 0x0, /* application acceleration processor */ AAP1 = 0x0, /* application acceleration processor */
......
...@@ -50,32 +50,39 @@ ...@@ -50,32 +50,39 @@
static void read_main_config_table(struct pm8001_hba_info *pm8001_ha) static void read_main_config_table(struct pm8001_hba_info *pm8001_ha)
{ {
void __iomem *address = pm8001_ha->main_cfg_tbl_addr; void __iomem *address = pm8001_ha->main_cfg_tbl_addr;
pm8001_ha->main_cfg_tbl.signature = pm8001_mr32(address, 0x00); pm8001_ha->main_cfg_tbl.pm8001_tbl.signature =
pm8001_ha->main_cfg_tbl.interface_rev = pm8001_mr32(address, 0x04); pm8001_mr32(address, 0x00);
pm8001_ha->main_cfg_tbl.firmware_rev = pm8001_mr32(address, 0x08); pm8001_ha->main_cfg_tbl.pm8001_tbl.interface_rev =
pm8001_ha->main_cfg_tbl.max_out_io = pm8001_mr32(address, 0x0C); pm8001_mr32(address, 0x04);
pm8001_ha->main_cfg_tbl.max_sgl = pm8001_mr32(address, 0x10); pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev =
pm8001_ha->main_cfg_tbl.ctrl_cap_flag = pm8001_mr32(address, 0x14); pm8001_mr32(address, 0x08);
pm8001_ha->main_cfg_tbl.gst_offset = pm8001_mr32(address, 0x18); pm8001_ha->main_cfg_tbl.pm8001_tbl.max_out_io =
pm8001_ha->main_cfg_tbl.inbound_queue_offset = 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_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_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); pm8001_mr32(address, MAIN_HDA_FLAGS_OFFSET);
/* read analog Setting offset from the configuration table */ /* 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); pm8001_mr32(address, MAIN_ANALOG_SETUP_OFFSET);
/* read Error Dump Offset and Length */ /* 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_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_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_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); pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_LENGTH);
} }
...@@ -86,31 +93,56 @@ static void read_main_config_table(struct pm8001_hba_info *pm8001_ha) ...@@ -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) static void read_general_status_table(struct pm8001_hba_info *pm8001_ha)
{ {
void __iomem *address = pm8001_ha->general_stat_tbl_addr; void __iomem *address = pm8001_ha->general_stat_tbl_addr;
pm8001_ha->gs_tbl.gst_len_mpistate = pm8001_mr32(address, 0x00); pm8001_ha->gs_tbl.pm8001_tbl.gst_len_mpistate =
pm8001_ha->gs_tbl.iq_freeze_state0 = pm8001_mr32(address, 0x04); pm8001_mr32(address, 0x00);
pm8001_ha->gs_tbl.iq_freeze_state1 = pm8001_mr32(address, 0x08); pm8001_ha->gs_tbl.pm8001_tbl.iq_freeze_state0 =
pm8001_ha->gs_tbl.msgu_tcnt = pm8001_mr32(address, 0x0C); pm8001_mr32(address, 0x04);
pm8001_ha->gs_tbl.iop_tcnt = pm8001_mr32(address, 0x10); pm8001_ha->gs_tbl.pm8001_tbl.iq_freeze_state1 =
pm8001_ha->gs_tbl.reserved = pm8001_mr32(address, 0x14); pm8001_mr32(address, 0x08);
pm8001_ha->gs_tbl.phy_state[0] = pm8001_mr32(address, 0x18); pm8001_ha->gs_tbl.pm8001_tbl.msgu_tcnt =
pm8001_ha->gs_tbl.phy_state[1] = pm8001_mr32(address, 0x1C); pm8001_mr32(address, 0x0C);
pm8001_ha->gs_tbl.phy_state[2] = pm8001_mr32(address, 0x20); pm8001_ha->gs_tbl.pm8001_tbl.iop_tcnt =
pm8001_ha->gs_tbl.phy_state[3] = pm8001_mr32(address, 0x24); pm8001_mr32(address, 0x10);
pm8001_ha->gs_tbl.phy_state[4] = pm8001_mr32(address, 0x28); pm8001_ha->gs_tbl.pm8001_tbl.rsvd =
pm8001_ha->gs_tbl.phy_state[5] = pm8001_mr32(address, 0x2C); pm8001_mr32(address, 0x14);
pm8001_ha->gs_tbl.phy_state[6] = pm8001_mr32(address, 0x30); pm8001_ha->gs_tbl.pm8001_tbl.phy_state[0] =
pm8001_ha->gs_tbl.phy_state[7] = pm8001_mr32(address, 0x34); pm8001_mr32(address, 0x18);
pm8001_ha->gs_tbl.reserved1 = pm8001_mr32(address, 0x38); pm8001_ha->gs_tbl.pm8001_tbl.phy_state[1] =
pm8001_ha->gs_tbl.reserved2 = pm8001_mr32(address, 0x3C); pm8001_mr32(address, 0x1C);
pm8001_ha->gs_tbl.reserved3 = pm8001_mr32(address, 0x40); pm8001_ha->gs_tbl.pm8001_tbl.phy_state[2] =
pm8001_ha->gs_tbl.recover_err_info[0] = pm8001_mr32(address, 0x44); pm8001_mr32(address, 0x20);
pm8001_ha->gs_tbl.recover_err_info[1] = pm8001_mr32(address, 0x48); pm8001_ha->gs_tbl.pm8001_tbl.phy_state[3] =
pm8001_ha->gs_tbl.recover_err_info[2] = pm8001_mr32(address, 0x4C); pm8001_mr32(address, 0x24);
pm8001_ha->gs_tbl.recover_err_info[3] = pm8001_mr32(address, 0x50); pm8001_ha->gs_tbl.pm8001_tbl.phy_state[4] =
pm8001_ha->gs_tbl.recover_err_info[4] = pm8001_mr32(address, 0x54); pm8001_mr32(address, 0x28);
pm8001_ha->gs_tbl.recover_err_info[5] = pm8001_mr32(address, 0x58); pm8001_ha->gs_tbl.pm8001_tbl.phy_state[5] =
pm8001_ha->gs_tbl.recover_err_info[6] = pm8001_mr32(address, 0x5C); pm8001_mr32(address, 0x2C);
pm8001_ha->gs_tbl.recover_err_info[7] = pm8001_mr32(address, 0x60); 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) ...@@ -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) static void init_default_table_values(struct pm8001_hba_info *pm8001_ha)
{ {
int qn = 1;
int i; int i;
u32 offsetib, offsetob; u32 offsetib, offsetob;
void __iomem *addressib = pm8001_ha->inbnd_q_tbl_addr; void __iomem *addressib = pm8001_ha->inbnd_q_tbl_addr;
void __iomem *addressob = pm8001_ha->outbnd_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.pm8001_tbl.inbound_q_nppd_hppd = 0;
pm8001_ha->main_cfg_tbl.outbound_hw_event_pid0_3 = 0; pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.outbound_hw_event_pid4_7 = 0; pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid0_3 = 0; pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid4_7 = 0; pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid4_7 = 0;
pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid0_3 = 0; pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ITNexus_event_pid0_3 =
pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid4_7 = 0; 0;
pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid0_3 = 0; pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ITNexus_event_pid4_7 =
pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid4_7 = 0; 0;
pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid0_3 = 0; pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ssp_event_pid0_3 = 0;
pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid4_7 = 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.upper_event_log_addr = 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->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->memoryMap.region[AAP1].phys_addr_lo;
pm8001_ha->main_cfg_tbl.event_log_size = PM8001_EVENT_LOG_SIZE; pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_size =
pm8001_ha->main_cfg_tbl.event_log_option = 0x01; PM8001_EVENT_LOG_SIZE;
pm8001_ha->main_cfg_tbl.upper_iop_event_log_addr = 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->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->memoryMap.region[IOP].phys_addr_lo;
pm8001_ha->main_cfg_tbl.iop_event_log_size = PM8001_EVENT_LOG_SIZE; pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_size =
pm8001_ha->main_cfg_tbl.iop_event_log_option = 0x01; PM8001_EVENT_LOG_SIZE;
pm8001_ha->main_cfg_tbl.fatal_err_interrupt = 0x01; pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_option = 0x01;
for (i = 0; i < qn; i++) { 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_ha->inbnd_q_tbl[i].element_pri_size_cnt =
PM8001_MPI_QUEUE | (64 << 16) | (0x00<<30); PM8001_MPI_QUEUE | (64 << 16) | (0x00<<30);
pm8001_ha->inbnd_q_tbl[i].upper_base_addr = 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) ...@@ -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].producer_idx = 0;
pm8001_ha->inbnd_q_tbl[i].consumer_index = 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_ha->outbnd_q_tbl[i].element_size_cnt =
PM8001_MPI_QUEUE | (64 << 16) | (0x01<<30); PM8001_MPI_QUEUE | (64 << 16) | (0x01<<30);
pm8001_ha->outbnd_q_tbl[i].upper_base_addr = 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) ...@@ -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; void __iomem *address = pm8001_ha->main_cfg_tbl_addr;
pm8001_mw32(address, 0x24, 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_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_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_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_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_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_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_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_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_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_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_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_mw32(address, 0x54,
pm8001_ha->main_cfg_tbl.lower_event_log_addr); pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_event_log_addr);
pm8001_mw32(address, 0x58, pm8001_ha->main_cfg_tbl.event_log_size); pm8001_mw32(address, 0x58,
pm8001_mw32(address, 0x5C, pm8001_ha->main_cfg_tbl.event_log_option); 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_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_mw32(address, 0x64,
pm8001_ha->main_cfg_tbl.lower_iop_event_log_addr); pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_iop_event_log_addr);
pm8001_mw32(address, 0x68, pm8001_ha->main_cfg_tbl.iop_event_log_size); pm8001_mw32(address, 0x68,
pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_size);
pm8001_mw32(address, 0x6C, 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_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 = { ...@@ -4706,4 +4750,3 @@ const struct pm8001_dispatch pm8001_8001_dispatch = {
.set_dev_state_req = pm8001_chip_set_dev_state_req, .set_dev_state_req = pm8001_chip_set_dev_state_req,
.sas_re_init_req = pm8001_chip_sas_re_initialization, .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. * Copyright (c) 2008-2009 USI Co., Ltd.
* All rights reserved. * All rights reserved.
...@@ -44,8 +44,12 @@ ...@@ -44,8 +44,12 @@
static struct scsi_transport_template *pm8001_stt; 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[] = { 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; static int pm8001_id;
...@@ -843,14 +847,45 @@ static int pm8001_pci_resume(struct pci_dev *pdev) ...@@ -843,14 +847,45 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
return rc; 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[] = { 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), PCI_DEVICE(0x117c, 0x0042),
.driver_data = chip_8001 .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 */ {} /* terminate list */
}; };
...@@ -902,7 +937,8 @@ module_init(pm8001_init); ...@@ -902,7 +937,8 @@ module_init(pm8001_init);
module_exit(pm8001_exit); module_exit(pm8001_exit);
MODULE_AUTHOR("Jack Wang <jack_wang@usish.com>"); 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_VERSION(DRV_VERSION);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, pm8001_pci_table); MODULE_DEVICE_TABLE(pci, pm8001_pci_table);
......
...@@ -173,6 +173,7 @@ struct pm8001_dispatch { ...@@ -173,6 +173,7 @@ struct pm8001_dispatch {
}; };
struct pm8001_chip_info { struct pm8001_chip_info {
u32 encrypt;
u32 n_phy; u32 n_phy;
const struct pm8001_dispatch *dispatch; const struct pm8001_dispatch *dispatch;
}; };
...@@ -256,7 +257,20 @@ struct mpi_mem_req { ...@@ -256,7 +257,20 @@ struct mpi_mem_req {
struct mpi_mem region[USI_MAX_MEMCNT]; 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 signature;
u32 interface_rev; u32 interface_rev;
u32 firmware_rev; u32 firmware_rev;
...@@ -292,19 +306,67 @@ struct main_cfg_table { ...@@ -292,19 +306,67 @@ struct main_cfg_table {
u32 fatal_err_dump_length1; u32 fatal_err_dump_length1;
u32 hda_mode_flag; u32 hda_mode_flag;
u32 anolog_setup_table_offset; 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 gst_len_mpistate;
u32 iq_freeze_state0; u32 iq_freeze_state0;
u32 iq_freeze_state1; u32 iq_freeze_state1;
u32 msgu_tcnt; u32 msgu_tcnt;
u32 iop_tcnt; u32 iop_tcnt;
u32 reserved; u32 rsvd;
u32 phy_state[8]; u32 phy_state[8];
u32 reserved1; u32 gpio_input_val;
u32 reserved2; u32 rsvd1[2];
u32 reserved3; 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]; u32 recover_err_info[8];
} pm80xx_tbl;
}; };
struct inbound_queue_table { struct inbound_queue_table {
u32 element_pri_size_cnt; u32 element_pri_size_cnt;
...@@ -351,15 +413,21 @@ struct pm8001_hba_info { ...@@ -351,15 +413,21 @@ struct pm8001_hba_info {
struct device *dev; struct device *dev;
struct pm8001_hba_memspace io_mem[6]; struct pm8001_hba_memspace io_mem[6];
struct mpi_mem_req memoryMap; struct mpi_mem_req memoryMap;
struct encrypt encrypt_info; /* support encryption */
void __iomem *msg_unit_tbl_addr;/*Message Unit Table Addr*/ void __iomem *msg_unit_tbl_addr;/*Message Unit Table Addr*/
void __iomem *main_cfg_tbl_addr;/*Main Config Table Addr*/ void __iomem *main_cfg_tbl_addr;/*Main Config Table Addr*/
void __iomem *general_stat_tbl_addr;/*General Status 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 *inbnd_q_tbl_addr;/*Inbound Queue Config Table Addr*/
void __iomem *outbnd_q_tbl_addr;/*Outbound Queue Config Table Addr*/ void __iomem *outbnd_q_tbl_addr;/*Outbound Queue Config Table Addr*/
struct main_cfg_table main_cfg_tbl; void __iomem *pspa_q_tbl_addr;
struct general_status_table gs_tbl; /*MPI SAS PHY attributes Queue Config Table Addr*/
struct inbound_queue_table inbnd_q_tbl[PM8001_MAX_INB_NUM]; void __iomem *ivt_tbl_addr; /*MPI IVT Table Addr */
struct outbound_queue_table outbnd_q_tbl[PM8001_MAX_OUTB_NUM]; 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]; u8 sas_addr[SAS_ADDR_SIZE];
struct sas_ha_struct *sas;/* SCSI/SAS glue */ struct sas_ha_struct *sas;/* SCSI/SAS glue */
struct Scsi_Host *shost; struct Scsi_Host *shost;
...@@ -372,10 +440,12 @@ struct pm8001_hba_info { ...@@ -372,10 +440,12 @@ struct pm8001_hba_info {
struct pm8001_port port[PM8001_MAX_PHYS]; struct pm8001_port port[PM8001_MAX_PHYS];
u32 id; u32 id;
u32 irq; u32 irq;
u32 iomb_size; /* SPC and SPCV IOMB size */
struct pm8001_device *devices; struct pm8001_device *devices;
struct pm8001_ccb_info *ccb_info; struct pm8001_ccb_info *ccb_info;
#ifdef PM8001_USE_MSIX #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()*/ int number_of_intr;/*will be used in remove()*/
#endif #endif
#ifdef PM8001_USE_TASKLET #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