From alan@linux.intel.com Mon Oct 26 14:47:54 2009 From: Alan Cox Date: Tue, 06 Oct 2009 15:47:22 +0100 Subject: Staging: et131x: extract the eeprom setup logic from initpci To: greg@kroah.com Message-ID: <20091006144705.8604.2907.stgit@localhost.localdomain> This puts all the eeprom handling in one place and cleans up the interfaces Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_eeprom.c | 73 +++++++++++++++++++++++++++++++- drivers/staging/et131x/et1310_eeprom.h | 5 -- drivers/staging/et131x/et131x_initpci.c | 67 ----------------------------- 3 files changed, 73 insertions(+), 72 deletions(-) --- a/drivers/staging/et131x/et1310_eeprom.c +++ b/drivers/staging/et131x/et1310_eeprom.c @@ -132,7 +132,7 @@ static int eeprom_wait_ready(struct pci_ * * Returns 1 for a successful write. */ -int eeprom_write(struct et131x_adapter *etdev, u32 addr, u8 data) +static int eeprom_write(struct et131x_adapter *etdev, u32 addr, u8 data) { struct pci_dev *pdev = etdev->pdev; int index = 0; @@ -264,7 +264,7 @@ int eeprom_write(struct et131x_adapter * * * Returns 1 for a successful read */ -int eeprom_read(struct et131x_adapter *etdev, u32 addr, u8 *pdata) +static int eeprom_read(struct et131x_adapter *etdev, u32 addr, u8 *pdata) { struct pci_dev *pdev = etdev->pdev; int err; @@ -312,3 +312,72 @@ int eeprom_read(struct et131x_adapter *e */ return (status & LBCIF_STATUS_ACK_ERROR) ? -EIO : 0; } + +int et131x_init_eeprom(struct et131x_adapter *etdev) +{ + struct pci_dev *pdev = etdev->pdev; + u8 eestatus; + + /* We first need to check the EEPROM Status code located at offset + * 0xB2 of config space + */ + pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, + &eestatus); + + /* THIS IS A WORKAROUND: + * I need to call this function twice to get my card in a + * LG M1 Express Dual running. I tried also a msleep before this + * function, because I thougth there could be some time condidions + * but it didn't work. Call the whole function twice also work. + */ + if (pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, &eestatus)) { + dev_err(&pdev->dev, + "Could not read PCI config space for EEPROM Status\n"); + return -EIO; + } + + /* Determine if the error(s) we care about are present. If they are + * present we need to fail. + */ + if (eestatus & 0x4C) { + int write_failed = 0; + if (pdev->revision == 0x01) { + int i; + static const u8 eedata[4] = { 0xFE, 0x13, 0x10, 0xFF }; + + /* Re-write the first 4 bytes if we have an eeprom + * present and the revision id is 1, this fixes the + * corruption seen with 1310 B Silicon + */ + for (i = 0; i < 3; i++) + if (eeprom_write(etdev, i, eedata[i]) < 0) + write_failed = 1; + } + if (pdev->revision != 0x01 || write_failed) { + dev_err(&pdev->dev, + "Fatal EEPROM Status Error - 0x%04x\n", eestatus); + + /* This error could mean that there was an error + * reading the eeprom or that the eeprom doesn't exist. + * We will treat each case the same and not try to gather + * additional information that normally would come from the + * eeprom, like MAC Address + */ + etdev->has_eeprom = 0; + return -EIO; + } + } + etdev->has_eeprom = 1; + + /* Read the EEPROM for information regarding LED behavior. Refer to + * ET1310_phy.c, et131x_xcvr_init(), for its use. + */ + eeprom_read(etdev, 0x70, &etdev->eepromData[0]); + eeprom_read(etdev, 0x71, &etdev->eepromData[1]); + + if (etdev->eepromData[0] != 0xcd) + /* Disable all optional features */ + etdev->eepromData[1] = 0x00; + + return 0; +} --- a/drivers/staging/et131x/et1310_eeprom.h +++ b/drivers/staging/et131x/et1310_eeprom.h @@ -98,9 +98,6 @@ /* Forward declaration of the private adapter structure */ struct et131x_adapter; -int eeprom_write(struct et131x_adapter *adapter, u32 unAddress, - u8 bData); -int eeprom_read(struct et131x_adapter *adapter, u32 unAddress, - u8 *pbData); +int et131x_init_eeprom(struct et131x_adapter *etdev); #endif /* _ET1310_EEPROM_H_ */ --- a/drivers/staging/et131x/et131x_initpci.c +++ b/drivers/staging/et131x/et131x_initpci.c @@ -140,10 +140,8 @@ MODULE_PARM_DESC(et131x_speed_set, int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev) { int result; - uint8_t eepromStat; uint8_t maxPayload = 0; uint8_t read_size_reg; - u8 rev; /* Allow disabling of Non-Maskable Interrupts in I/O space, to * support validation. @@ -160,71 +158,8 @@ int et131x_find_adapter(struct et131x_ad outb(ET1310_NMI_DISABLE, RegisterVal); } - /* We first need to check the EEPROM Status code located at offset - * 0xB2 of config space - */ - result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, - &eepromStat); - - /* THIS IS A WORKAROUND: - * I need to call this function twice to get my card in a - * LG M1 Express Dual running. I tried also a msleep before this - * function, because I thougth there could be some time condidions - * but it didn't work. Call the whole function twice also work. - */ - result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS, - &eepromStat); - if (result != PCIBIOS_SUCCESSFUL) { - dev_err(&pdev->dev, "Could not read PCI config space for " - "EEPROM Status\n"); - return -EIO; - } - - /* Determine if the error(s) we care about are present. If they are - * present, we need to fail. - */ - if (eepromStat & 0x4C) { - result = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); - if (result != PCIBIOS_SUCCESSFUL) { - dev_err(&pdev->dev, - "Could not read PCI config space for " - "Revision ID\n"); - return -EIO; - } else if (rev == 0x01) { - int32_t nLoop; - uint8_t temp[4] = { 0xFE, 0x13, 0x10, 0xFF }; - - /* Re-write the first 4 bytes if we have an eeprom - * present and the revision id is 1, this fixes the - * corruption seen with 1310 B Silicon - */ - for (nLoop = 0; nLoop < 3; nLoop++) { - eeprom_write(adapter, nLoop, temp[nLoop]); - } - } - - dev_err(&pdev->dev, "Fatal EEPROM Status Error - 0x%04x\n", eepromStat); - - /* This error could mean that there was an error reading the - * eeprom or that the eeprom doesn't exist. We will treat - * each case the same and not try to gather additional - * information that normally would come from the eeprom, like - * MAC Address - */ - adapter->has_eeprom = 0; + if (et131x_init_eeprom(adapter) < 0) return -EIO; - } else - adapter->has_eeprom = 1; - - /* Read the EEPROM for information regarding LED behavior. Refer to - * ET1310_phy.c, et131x_xcvr_init(), for its use. - */ - eeprom_read(adapter, 0x70, &adapter->eepromData[0]); - eeprom_read(adapter, 0x71, &adapter->eepromData[1]); - - if (adapter->eepromData[0] != 0xcd) - /* Disable all optional features */ - adapter->eepromData[1] = 0x00; /* Let's set up the PORT LOGIC Register. First we need to know what * the max_payload_size is