[SCSI] pm80xx: Added SPCv/ve specific ids, variables and modify for SPC
authorSakthivel K <Sakthivel.SaravananKamalRaju@pmcs.com>
Wed, 17 Apr 2013 10:56:36 +0000 (16:26 +0530)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 10 May 2013 14:47:45 +0000 (07:47 -0700)
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: Sakthivel K <Sakthivel.SaravananKamalRaju@pmcs.com>
Signed-off-by: Anand Kumar S <AnandKumar.Santhanam@pmcs.com>
Acked-by: Jack Wang <jack_wang@usish.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/pm8001/pm8001_ctl.c
drivers/scsi/pm8001/pm8001_defs.h
drivers/scsi/pm8001/pm8001_hwi.c
drivers/scsi/pm8001/pm8001_init.c
drivers/scsi/pm8001/pm8001_sas.h

index 45bc197bc22f2a45c46f5176cabefddc69e077f2..ae2b1242d0ace6f9bf7e5f01d04d2cbf406fbeda 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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,
index c3d20c8d4abe3724308182697a558dac7440a07a..b25f87c8f4698be4e77c4f2a493e548fa442d698 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
 
 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 */
index b8dd05074abb4f61faebbe0af12bd3074fd8b930..9846ee64838430f24ab416624596a5c6c0af6e52 100644 (file)
 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,
 };
-
index 3d5e522e00fc8ae93a4c9344731f960fa42c0006..f3234b2a0d796c38ef733f5b8fb9797f6bd1f237 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
 
 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 @@ err_out_enable:
        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);
index 11008205aeb331c9b86be09deb8c26733cd133b2..37a339e6a3a49590d54d802c2d316e2ca9c41fee 100644 (file)
@@ -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