Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+54 −15
Original line number Diff line number Diff line
/*
 * 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;

	if (pm8001_ha->chip_id == chip_8001) {
		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
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;

	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.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));
		(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;

	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.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);
/**
@@ -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;

	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.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);
/**
@@ -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;

	if (pm8001_ha->chip_id == chip_8001) {
		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);

@@ -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,
+15 −4
Original line number Diff line number Diff line
/*
 * 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 */
+128 −85
Original line number Diff line number Diff line
@@ -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,
};
+42 −6
Original line number Diff line number Diff line
/*
 * 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);
+81 −11
Original line number Diff line number Diff line
@@ -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