[SCSI] fusion - Adding pci recog support for Fibre 949X and 939X chips
authorMoore, Eric Dean <Eric.Moore@lsil.com>
Wed, 11 May 2005 23:46:52 +0000 (17:46 -0600)
committerJames Bottomley <jejb@mulgrave.(none)>
Fri, 20 May 2005 20:47:53 +0000 (15:47 -0500)
* adding pci id support for new Fibre chips, 949X and 939X
* adding errata workaround - disabling PIO access except during fwdlb.

Signed-off-by: Eric Moore <Eric.Moore@lsil.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptfc.c

index d2a3c08..673cdd9 100644 (file)
@@ -186,6 +186,26 @@ static void __exit    fusion_exit  (void);
 #define CHIPREG_PIO_WRITE32(addr,val)  outl(val, (unsigned long)addr)
 #define CHIPREG_PIO_READ32(addr)       inl((unsigned long)addr)
 
+static void
+pci_disable_io_access(struct pci_dev *pdev)
+{
+       u16 command_reg;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
+       command_reg &= ~1;
+       pci_write_config_word(pdev, PCI_COMMAND, command_reg);
+}
+
+static void
+pci_enable_io_access(struct pci_dev *pdev)
+{
+       u16 command_reg;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
+       command_reg |= 1;
+       pci_write_config_word(pdev, PCI_COMMAND, command_reg);
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
@@ -1161,6 +1181,16 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
                pcixcmd &= 0x8F;
                pci_write_config_byte(pdev, 0x6a, pcixcmd);
        }
+       else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
+               ioc->prod_name = "LSIFC939X";
+               ioc->bus_type = FC;
+               ioc->errata_flag_1064 = 1;
+       }
+       else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
+               ioc->prod_name = "LSIFC949X";
+               ioc->bus_type = FC;
+               ioc->errata_flag_1064 = 1;
+       }
        else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
                ioc->prod_name = "LSI53C1030";
                ioc->bus_type = SCSI;
@@ -1179,6 +1209,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
                ioc->bus_type = SCSI;
        }
 
+       if (ioc->errata_flag_1064)
+               pci_disable_io_access(pdev);
+
        sprintf(ioc->name, "ioc%d", ioc->id);
 
        spin_lock_init(&ioc->FreeQlock);
@@ -2667,7 +2700,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
        /* prevent a second downloadboot and memory free with alt_ioc */
        if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
                ioc->alt_ioc->cached_fw = NULL;
-       
+
        CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
        CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
@@ -2725,6 +2758,9 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
        /* Write the LoadStartAddress to the DiagRw Address Register
         * using Programmed IO
         */
+       if (ioc->errata_flag_1064)
+               pci_enable_io_access(ioc->pcidev);
+
        CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
        ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
                ioc->name, pFwHeader->LoadStartAddress));
@@ -2771,6 +2807,9 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
        CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
        CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
 
+       if (ioc->errata_flag_1064)
+               pci_disable_io_access(ioc->pcidev);
+
        diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
        ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
                ioc->name, diag0val));
index 2c4bb69..84ade73 100644 (file)
@@ -562,6 +562,13 @@ typedef struct _MPT_ADAPTER
        FCPortPage0_t            fc_port_page0[2];
        LANPage0_t               lan_cnfg_page0;
        LANPage1_t               lan_cnfg_page1;
+       /*  
+        * Description: errata_flag_1064
+        * If a PCIX read occurs within 1 or 2 cycles after the chip receives
+        * a split completion for a read data, an internal address pointer incorrectly
+        * increments by 32 bytes
+        */
+       int                      errata_flag_1064;      
        u8                       FirstWhoInit;
        u8                       upload_fw;     /* If set, do a fw upload */
        u8                       reload_fw;     /* Force a FW Reload on next reset */
index 11845fa..d8d6539 100644 (file)
@@ -134,6 +134,10 @@ static struct pci_device_id mptfc_pci_table[] = {
                PCI_ANY_ID, PCI_ANY_ID },
        { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
                PCI_ANY_ID, PCI_ANY_ID },
+       { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X,
+               PCI_ANY_ID, PCI_ANY_ID },
+       { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
+               PCI_ANY_ID, PCI_ANY_ID },
        {0}     /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, mptfc_pci_table);