2006-11-22 08:06:03

by Hidetoshi Seto

[permalink] [raw]
Subject: [PATCH 4/5] e1000 : Make Intel e1000 driver legacy I/O port free

This patch makes Intel e1000 driver legacy I/O port free.

Signed-off-by: Kenji Kaneshige <[email protected]>
Signed-off-by: Hidetoshi Seto <[email protected]>

---
drivers/net/e1000/e1000.h | 6 +
drivers/net/e1000/e1000_main.c | 146 ++++++++++++++++++++++-------------------
2 files changed, 83 insertions(+), 69 deletions(-)

Index: linux-2.6.19-rc6/drivers/net/e1000/e1000.h
===================================================================
--- linux-2.6.19-rc6.orig/drivers/net/e1000/e1000.h
+++ linux-2.6.19-rc6/drivers/net/e1000/e1000.h
@@ -75,8 +75,9 @@
#define BAR_1 1
#define BAR_5 5

-#define INTEL_E1000_ETHERNET_DEVICE(device_id) {\
- PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
+#define E1000_USE_IOPORT (1 << 0)
+#define INTEL_E1000_ETHERNET_DEVICE(device_id, flags) {\
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id), .driver_data = flags}

struct e1000_adapter;

@@ -342,6 +343,7 @@
boolean_t quad_port_a;
unsigned long flags;
uint32_t eeprom_wol;
+ int bars; /* BARs to be enabled */
};

enum e1000_state_t {
Index: linux-2.6.19-rc6/drivers/net/e1000/e1000_main.c
===================================================================
--- linux-2.6.19-rc6.orig/drivers/net/e1000/e1000_main.c
+++ linux-2.6.19-rc6/drivers/net/e1000/e1000_main.c
@@ -47,62 +47,62 @@
* {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
*/
static struct pci_device_id e1000_pci_tbl[] = {
- INTEL_E1000_ETHERNET_DEVICE(0x1000),
- INTEL_E1000_ETHERNET_DEVICE(0x1001),
- INTEL_E1000_ETHERNET_DEVICE(0x1004),
- INTEL_E1000_ETHERNET_DEVICE(0x1008),
- INTEL_E1000_ETHERNET_DEVICE(0x1009),
- INTEL_E1000_ETHERNET_DEVICE(0x100C),
- INTEL_E1000_ETHERNET_DEVICE(0x100D),
- INTEL_E1000_ETHERNET_DEVICE(0x100E),
- INTEL_E1000_ETHERNET_DEVICE(0x100F),
- INTEL_E1000_ETHERNET_DEVICE(0x1010),
- INTEL_E1000_ETHERNET_DEVICE(0x1011),
- INTEL_E1000_ETHERNET_DEVICE(0x1012),
- INTEL_E1000_ETHERNET_DEVICE(0x1013),
- INTEL_E1000_ETHERNET_DEVICE(0x1014),
- INTEL_E1000_ETHERNET_DEVICE(0x1015),
- INTEL_E1000_ETHERNET_DEVICE(0x1016),
- INTEL_E1000_ETHERNET_DEVICE(0x1017),
- INTEL_E1000_ETHERNET_DEVICE(0x1018),
- INTEL_E1000_ETHERNET_DEVICE(0x1019),
- INTEL_E1000_ETHERNET_DEVICE(0x101A),
- INTEL_E1000_ETHERNET_DEVICE(0x101D),
- INTEL_E1000_ETHERNET_DEVICE(0x101E),
- INTEL_E1000_ETHERNET_DEVICE(0x1026),
- INTEL_E1000_ETHERNET_DEVICE(0x1027),
- INTEL_E1000_ETHERNET_DEVICE(0x1028),
- INTEL_E1000_ETHERNET_DEVICE(0x1049),
- INTEL_E1000_ETHERNET_DEVICE(0x104A),
- INTEL_E1000_ETHERNET_DEVICE(0x104B),
- INTEL_E1000_ETHERNET_DEVICE(0x104C),
- INTEL_E1000_ETHERNET_DEVICE(0x104D),
- INTEL_E1000_ETHERNET_DEVICE(0x105E),
- INTEL_E1000_ETHERNET_DEVICE(0x105F),
- INTEL_E1000_ETHERNET_DEVICE(0x1060),
- INTEL_E1000_ETHERNET_DEVICE(0x1075),
- INTEL_E1000_ETHERNET_DEVICE(0x1076),
- INTEL_E1000_ETHERNET_DEVICE(0x1077),
- INTEL_E1000_ETHERNET_DEVICE(0x1078),
- INTEL_E1000_ETHERNET_DEVICE(0x1079),
- INTEL_E1000_ETHERNET_DEVICE(0x107A),
- INTEL_E1000_ETHERNET_DEVICE(0x107B),
- INTEL_E1000_ETHERNET_DEVICE(0x107C),
- INTEL_E1000_ETHERNET_DEVICE(0x107D),
- INTEL_E1000_ETHERNET_DEVICE(0x107E),
- INTEL_E1000_ETHERNET_DEVICE(0x107F),
- INTEL_E1000_ETHERNET_DEVICE(0x108A),
- INTEL_E1000_ETHERNET_DEVICE(0x108B),
- INTEL_E1000_ETHERNET_DEVICE(0x108C),
- INTEL_E1000_ETHERNET_DEVICE(0x1096),
- INTEL_E1000_ETHERNET_DEVICE(0x1098),
- INTEL_E1000_ETHERNET_DEVICE(0x1099),
- INTEL_E1000_ETHERNET_DEVICE(0x109A),
- INTEL_E1000_ETHERNET_DEVICE(0x10A4),
- INTEL_E1000_ETHERNET_DEVICE(0x10B5),
- INTEL_E1000_ETHERNET_DEVICE(0x10B9),
- INTEL_E1000_ETHERNET_DEVICE(0x10BA),
- INTEL_E1000_ETHERNET_DEVICE(0x10BB),
+ INTEL_E1000_ETHERNET_DEVICE(0x1000, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1001, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1004, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1008, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1009, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x100C, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x100D, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x100E, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x100F, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1010, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1011, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1012, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1013, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1014, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1015, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1016, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1017, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1018, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1019, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x101A, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x101D, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x101E, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1026, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1027, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1028, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1049, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x104A, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x104B, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x104C, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x104D, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x105E, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x105F, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1060, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1075, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1076, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1077, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1078, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x1079, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x107A, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x107B, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x107C, E1000_USE_IOPORT),
+ INTEL_E1000_ETHERNET_DEVICE(0x107D, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x107E, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x107F, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x108A, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x108B, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x108C, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1096, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1098, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x1099, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x109A, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x10A4, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x10B5, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x10B9, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x10BA, 0),
+ INTEL_E1000_ETHERNET_DEVICE(0x10BB, 0),
/* required last entry */
{0,}
};
@@ -735,7 +735,14 @@
int i, err, pci_using_dac;
uint16_t eeprom_data = 0;
uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
- if ((err = pci_enable_device(pdev)))
+ int bars;
+
+ if (ent->driver_data & E1000_USE_IOPORT)
+ bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
+ else
+ bars = pci_select_bars(pdev, IORESOURCE_MEM);
+
+ if ((err = pci_enable_device_bars(pdev, bars)))
return err;

if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
@@ -750,7 +757,8 @@
pci_using_dac = 0;
}

- if ((err = pci_request_regions(pdev, e1000_driver_name)))
+ err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
+ if (err)
goto err_pci_reg;

pci_set_master(pdev);
@@ -769,6 +777,7 @@
adapter->pdev = pdev;
adapter->hw.back = adapter;
adapter->msg_enable = (1 << debug) - 1;
+ adapter->bars = bars;

mmio_start = pci_resource_start(pdev, BAR_0);
mmio_len = pci_resource_len(pdev, BAR_0);
@@ -778,12 +787,15 @@
if (!adapter->hw.hw_addr)
goto err_ioremap;

- for (i = BAR_1; i <= BAR_5; i++) {
- if (pci_resource_len(pdev, i) == 0)
- continue;
- if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
- adapter->hw.io_base = pci_resource_start(pdev, i);
- break;
+ if (ent->driver_data & E1000_USE_IOPORT) {
+ for (i = BAR_1; i <= BAR_5; i++) {
+ if (pci_resource_len(pdev, i) == 0)
+ continue;
+ if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+ adapter->hw.io_base =
+ pci_resource_start(pdev, i);
+ break;
+ }
}
}

@@ -1050,7 +1062,7 @@
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);
@@ -1111,7 +1123,7 @@
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);

@@ -4824,7 +4836,7 @@

pci_set_power_state(pdev, PCI_D0);
e1000_pci_restore_state(adapter);
- if ((err = pci_enable_device(pdev))) {
+ if ((err = pci_enable_device_bars(pdev, adapter->bars))) {
printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n");
return err;
}


2006-11-22 08:56:54

by Arjan van de Ven

[permalink] [raw]
Subject: Re: [PATCH 4/5] e1000 : Make Intel e1000 driver legacy I/O port free

On Wed, 2006-11-22 at 17:06 +0900, Hidetoshi Seto wrote:
> static struct pci_device_id e1000_pci_tbl[] = {
> + INTEL_E1000_ETHERNET_DEVICE(0x1004, 0),
> + INTEL_E1000_ETHERNET_DEVICE(0x1008, E1000_USE_IOPORT),

Hi,

this has the unfortunate effect that it's now a lot harder to add PCI
ID's to this driver at runtime via sysfs ;(

Greetings,
Arjan van de Ven
--
if you want to mail me at work (you don't), use arjan (at) linux.intel.com
Test the interaction between Linux and your BIOS via http://www.linuxfirmwarekit.org

2006-11-22 13:54:27

by Matthew Wilcox

[permalink] [raw]
Subject: Re: [PATCH 4/5] e1000 : Make Intel e1000 driver legacy I/O port free

On Wed, Nov 22, 2006 at 09:56:49AM +0100, Arjan van de Ven wrote:
> On Wed, 2006-11-22 at 17:06 +0900, Hidetoshi Seto wrote:
> > static struct pci_device_id e1000_pci_tbl[] = {
> > + INTEL_E1000_ETHERNET_DEVICE(0x1004, 0),
> > + INTEL_E1000_ETHERNET_DEVICE(0x1008, E1000_USE_IOPORT),
>
> Hi,
>
> this has the unfortunate effect that it's now a lot harder to add PCI
> ID's to this driver at runtime via sysfs ;(

It does? Normally you get 0 passed in that field, so you'll just not
get io ports enabled ...

Need to set use_driver_data to get non-0 passed in that field.

2006-11-22 16:11:37

by Kok, Auke

[permalink] [raw]
Subject: Re: [PATCH 4/5] e1000 : Make Intel e1000 driver legacy I/O port free

Matthew Wilcox wrote:
> On Wed, Nov 22, 2006 at 09:56:49AM +0100, Arjan van de Ven wrote:
>> On Wed, 2006-11-22 at 17:06 +0900, Hidetoshi Seto wrote:
>>> static struct pci_device_id e1000_pci_tbl[] = {
>>> + INTEL_E1000_ETHERNET_DEVICE(0x1004, 0),
>>> + INTEL_E1000_ETHERNET_DEVICE(0x1008, E1000_USE_IOPORT),
>> Hi,
>>
>> this has the unfortunate effect that it's now a lot harder to add PCI
>> ID's to this driver at runtime via sysfs ;(
>
> It does? Normally you get 0 passed in that field, so you'll just not
> get io ports enabled ...
>
> Need to set use_driver_data to get non-0 passed in that field.

I think we want to condense the USE_IOPORT flag together with the other hardware feature
flags, as suggested by Jeff Garzik. This would save some headroom and leave the pci
device id table as it is.

Cheers,

Auke

2006-11-23 06:16:11

by Lu, Yinghai

[permalink] [raw]
Subject: Re: [PATCH 4/5] e1000 : Make Intel e1000 driver legacy I/O port free

On 11/22/06, Auke Kok <[email protected]> wrote:
> I think we want to condense the USE_IOPORT flag together with the other hardware

two cases
1. the IO port is not allocated by firmware, but
pci_assign_unassigned_resources will get that allocated.
2. the IO port is allocated by firmware, the bar will be retrieved by
pcibios_resource_survey.

so acctully the device already get the bar allocated in any case.

So what the purpose of this patch? the /poc/ioports hide ioport for the driver?

It seems need to add some pci_quirk to clear the bar for 2, and skip
the resource allocation for 1.

YH