e1000e: make ioport free
authorTaku Izumi <izumi.taku@jp.fujitsu.com>
Fri, 20 Jun 2008 02:57:02 +0000 (11:57 +0900)
committerJeff Garzik <jgarzik@redhat.com>
Sat, 28 Jun 2008 14:23:31 +0000 (10:23 -0400)
This patch makes e1000e driver ioport-free.
This corrects behavior in probe function so as not to request ioport
resources as long as they are not really needed.

Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
drivers/net/e1000e/e1000.h
drivers/net/e1000e/netdev.c

index d3bc6f8101fa7b90be4455d33821a9901a82d50e..4a4f62e002b2e05e6c16e9346022106b31355fa5 100644 (file)
@@ -283,6 +283,10 @@ struct e1000_adapter {
        unsigned long led_status;
 
        unsigned int flags;
+
+       /* for ioport free */
+       int bars;
+       int need_ioport;
 };
 
 struct e1000_info {
index ccb8ca2cbb2bc0c2696cf0ffebe71434ad8357d1..22f2fc906354d1370f586a60c83ac788be0dcf31 100644 (file)
@@ -4002,7 +4002,11 @@ static int e1000_resume(struct pci_dev *pdev)
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
        e1000e_disable_l1aspm(pdev);
-       err = pci_enable_device(pdev);
+
+       if (adapter->need_ioport)
+               err = pci_enable_device(pdev);
+       else
+               err = pci_enable_device_mem(pdev);
        if (err) {
                dev_err(&pdev->dev,
                        "Cannot enable PCI device from suspend\n");
@@ -4103,9 +4107,14 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
+       int err;
 
        e1000e_disable_l1aspm(pdev);
-       if (pci_enable_device(pdev)) {
+       if (adapter->need_ioport)
+               err = pci_enable_device(pdev);
+       else
+               err = pci_enable_device_mem(pdev);
+       if (err) {
                dev_err(&pdev->dev,
                        "Cannot re-enable PCI device after reset.\n");
                return PCI_ERS_RESULT_DISCONNECT;
@@ -4183,6 +4192,21 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
                  (pba_num >> 8), (pba_num & 0xff));
 }
 
+/**
+ * e1000e_is_need_ioport - determine if an adapter needs ioport resources or not
+ * @pdev: PCI device information struct
+ *
+ * Returns true if an adapters needs ioport resources
+ **/
+static int e1000e_is_need_ioport(struct pci_dev *pdev)
+{
+       switch (pdev->device) {
+       /* Currently there are no adapters that need ioport resources */
+       default:
+               return false;
+       }
+}
+
 /**
  * e1000_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -4208,9 +4232,19 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        int i, err, pci_using_dac;
        u16 eeprom_data = 0;
        u16 eeprom_apme_mask = E1000_EEPROM_APME;
+       int bars, need_ioport;
 
        e1000e_disable_l1aspm(pdev);
-       err = pci_enable_device(pdev);
+
+       /* do not allocate ioport bars when not needed */
+       need_ioport = e1000e_is_need_ioport(pdev);
+       if (need_ioport) {
+               bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
+               err = pci_enable_device(pdev);
+       } else {
+               bars = pci_select_bars(pdev, IORESOURCE_MEM);
+               err = pci_enable_device_mem(pdev);
+       }
        if (err)
                return err;
 
@@ -4233,7 +4267,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
                }
        }
 
-       err = pci_request_regions(pdev, e1000e_driver_name);
+       err = pci_request_selected_regions(pdev, bars, e1000e_driver_name);
        if (err)
                goto err_pci_reg;
 
@@ -4258,6 +4292,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        adapter->hw.adapter = adapter;
        adapter->hw.mac.type = ei->mac;
        adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
+       adapter->bars = bars;
+       adapter->need_ioport = need_ioport;
 
        mmio_start = pci_resource_start(pdev, 0);
        mmio_len = pci_resource_len(pdev, 0);
@@ -4497,7 +4533,7 @@ err_sw_init:
 err_ioremap:
        free_netdev(netdev);
 err_alloc_etherdev:
-       pci_release_regions(pdev);
+       pci_release_selected_regions(pdev, bars);
 err_pci_reg:
 err_dma:
        pci_disable_device(pdev);
@@ -4545,7 +4581,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
        iounmap(adapter->hw.hw_addr);
        if (adapter->hw.flash_address)
                iounmap(adapter->hw.flash_address);
-       pci_release_regions(pdev);
+       pci_release_selected_regions(pdev, adapter->bars);
 
        free_netdev(netdev);