aboutsummaryrefslogtreecommitdiffstats
path: root/pci
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-04-04 10:53:00 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2006-04-04 10:53:00 -0700
commit89db993763d7241db3f0b8760c71dcb0cf6e5d91 (patch)
treef5c163b34e79c4cf4317758bef9da95f3ad88b61 /pci
parentd39fbab34cc47f08bbc206ac10f5b61b32227da6 (diff)
downloadpatches-89db993763d7241db3f0b8760c71dcb0cf6e5d91.tar.gz
new pci and usb patches
Diffstat (limited to 'pci')
-rw-r--r--pci/acpiphp-configure-_prt-v3.patch128
-rw-r--r--pci/acpiphp-host-and-p2p-hotplug.patch31
-rw-r--r--pci/acpiphp-hotplug-slot-hotplug.patch268
-rw-r--r--pci/acpiphp-turn-off-slot-power-at-error-case.patch41
-rw-r--r--pci/pci-hotplug-tollhouse-hp-sgi-hotplug-driver-changes.patch123
-rw-r--r--pci/pci-legacy-i-o-port-free-driver-changes-to-generic-pci-code.patch186
-rw-r--r--pci/pci-legacy-i-o-port-free-driver-make-emulex-lpfc-driver-legacy-i-o-port-free.patch30
-rw-r--r--pci/pci-legacy-i-o-port-free-driver-make-intel-e1000-driver-legacy-i-o-port-free.patch200
-rw-r--r--pci/pci-legacy-i-o-port-free-driver-update-documentation-pci.txt.patch92
9 files changed, 1099 insertions, 0 deletions
diff --git a/pci/acpiphp-configure-_prt-v3.patch b/pci/acpiphp-configure-_prt-v3.patch
new file mode 100644
index 0000000000000..5524b97ef6bcd
--- /dev/null
+++ b/pci/acpiphp-configure-_prt-v3.patch
@@ -0,0 +1,128 @@
+From muneda.takahiro@jp.fujitsu.com Tue Mar 21 21:49:23 2006
+Date: Wed, 22 Mar 2006 14:49:09 +0900
+Message-ID: <87lkv3c9m2.wl%muneda.takahiro@jp.fujitsu.com>
+From: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>
+Cc: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+Subject: acpiphp: configure _PRT - V3
+
+Current acpiphp does not free acpi_device structs when the
+PCI devices are removed. When the PCI device is added,
+acpi_bus_add() fails because acpi_device struct has already
+exists. So, _PRT method does not evaluate.
+
+This patch fixes this issue.
+
+Signed-off-by: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/hotplug/acpiphp_glue.c | 71 +++++++++++++++++--------------------
+ 1 file changed, 33 insertions(+), 38 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp_glue.c
++++ gregkh-2.6/drivers/pci/hotplug/acpiphp_glue.c
+@@ -797,36 +797,6 @@ static unsigned char acpiphp_max_busnr(s
+ }
+
+
+-
+-/**
+- * get_func - get a pointer to acpiphp_func given a slot, device
+- * @slot: slot to search
+- * @dev: pci_dev struct to match.
+- *
+- * This function will increase the reference count of pci_dev,
+- * so callers should call pci_dev_put when complete.
+- *
+- */
+-static struct acpiphp_func *
+-get_func(struct acpiphp_slot *slot, struct pci_dev *dev)
+-{
+- struct acpiphp_func *func = NULL;
+- struct pci_bus *bus = slot->bridge->pci_bus;
+- struct pci_dev *pdev;
+-
+- list_for_each_entry(func, &slot->funcs, sibling) {
+- pdev = pci_get_slot(bus, PCI_DEVFN(slot->device,
+- func->function));
+- if (pdev) {
+- if (pdev == dev)
+- break;
+- pci_dev_put(pdev);
+- }
+- }
+- return func;
+-}
+-
+-
+ /**
+ * acpiphp_bus_add - add a new bus to acpi subsystem
+ * @func: acpiphp_func of the bridge
+@@ -872,6 +842,28 @@ acpiphp_bus_add_out:
+ }
+
+
++/**
++ * acpiphp_bus_trim - trim a bus from acpi subsystem
++ * @handle: handle to acpi namespace
++ *
++ */
++int acpiphp_bus_trim(acpi_handle handle)
++{
++ struct acpi_device *device;
++ int retval;
++
++ retval = acpi_bus_get_device(handle, &device);
++ if (retval) {
++ dbg("acpi_device not found\n");
++ return retval;
++ }
++
++ retval = acpi_bus_trim(device, 1);
++ if (retval)
++ err("cannot remove from acpi list\n");
++
++ return retval;
++}
+
+ /**
+ * enable_device - enable, configure a slot
+@@ -918,19 +910,17 @@ static int enable_device(struct acpiphp_
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
+ max = pci_scan_bridge(bus, dev, max, pass);
+- if (pass && dev->subordinate) {
++ if (pass && dev->subordinate)
+ pci_bus_size_bridges(dev->subordinate);
+- func = get_func(slot, dev);
+- if (func) {
+- acpiphp_bus_add(func);
+- /* side effect of get_func */
+- pci_dev_put(dev);
+- }
+- }
+ }
+ }
+ }
+
++ list_for_each (l, &slot->funcs) {
++ func = list_entry(l, struct acpiphp_func, sibling);
++ acpiphp_bus_add(func);
++ }
++
+ pci_bus_assign_resources(bus);
+ acpiphp_sanitize_bus(bus);
+ pci_enable_bridges(bus);
+@@ -967,6 +957,11 @@ static int disable_device(struct acpiphp
+
+ list_for_each (l, &slot->funcs) {
+ func = list_entry(l, struct acpiphp_func, sibling);
++
++ acpiphp_bus_trim(func->handle);
++ /* try to remove anyway.
++ * acpiphp_bus_add might have been failed */
++
+ if (!func->pci_dev)
+ continue;
+
diff --git a/pci/acpiphp-host-and-p2p-hotplug.patch b/pci/acpiphp-host-and-p2p-hotplug.patch
new file mode 100644
index 0000000000000..526cdb3d2122b
--- /dev/null
+++ b/pci/acpiphp-host-and-p2p-hotplug.patch
@@ -0,0 +1,31 @@
+From muneda.takahiro@jp.fujitsu.com Tue Mar 21 21:49:45 2006
+Date: Wed, 22 Mar 2006 14:49:27 +0900
+Message-ID: <87irq7c9lk.wl%muneda.takahiro@jp.fujitsu.com>
+From: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>
+Cc: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+Subject: acpiphp: host and p2p hotplug
+
+I encountered the problem that when there are some hotplug
+slots are under the host bridge, the hotplug slots under the
+p2p bridge are not treated as hotpluggable.
+
+This patch fixes this BUG.
+
+Signed-off-by: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/hotplug/acpiphp_glue.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp_glue.c
++++ gregkh-2.6/drivers/pci/hotplug/acpiphp_glue.c
+@@ -546,7 +546,6 @@ static int add_bridge(acpi_handle handle
+ if (detect_ejectable_slots(handle) > 0) {
+ dbg("found PCI host-bus bridge with hot-pluggable slots\n");
+ add_host_bridge(handle, pci_bus);
+- return 0;
+ }
+
+ /* search P2P bridges under this host bridge */
diff --git a/pci/acpiphp-hotplug-slot-hotplug.patch b/pci/acpiphp-hotplug-slot-hotplug.patch
new file mode 100644
index 0000000000000..9d67d21fba4bd
--- /dev/null
+++ b/pci/acpiphp-hotplug-slot-hotplug.patch
@@ -0,0 +1,268 @@
+From muneda.takahiro@jp.fujitsu.com Tue Mar 21 21:49:43 2006
+Date: Wed, 22 Mar 2006 14:49:20 +0900
+Message-ID: <87k6anc9lr.wl%muneda.takahiro@jp.fujitsu.com>
+From: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>
+Cc: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+Subject: acpiphp: hotplug slot hotplug
+
+o hotplug slots add
+ When the hot-added PCI device is p2p bridge, acpiphp calls
+ find_p2p_bridge() to add hotplug slots.
+
+o hotplug slots remove
+ When the hot-removing PCI device is p2p bridge, acpiphp
+ calls cleanup_p2p_bridge() to remove hotplug slots.
+
+o notify handler exchange
+ When the p2p bridge is added, acpiphp changes the notify
+ hanlder.
+ If no bridge device is inserted into the hotpluggable PCI
+ slot, acpiphp installs the notify handler for function.
+ After the p2p bridge hot-add, acpiphp has to install the
+ notify handler for bridge. Because, the role of the
+ handlers are not same. The hot-remove case is ditto.
+
+Signed-off-by: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/hotplug/acpiphp.h | 5 +
+ drivers/pci/hotplug/acpiphp_glue.c | 126 ++++++++++++++++++++++++++++++++++---
+ 2 files changed, 122 insertions(+), 9 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp.h
++++ gregkh-2.6/drivers/pci/hotplug/acpiphp.h
+@@ -75,6 +75,10 @@ struct acpiphp_bridge {
+ struct list_head list;
+ acpi_handle handle;
+ struct acpiphp_slot *slots;
++
++ /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */
++ struct acpiphp_func *func;
++
+ int type;
+ int nr_slots;
+
+@@ -122,6 +126,7 @@ struct acpiphp_slot {
+ */
+ struct acpiphp_func {
+ struct acpiphp_slot *slot; /* parent */
++ struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */
+
+ struct list_head sibling;
+ struct pci_dev *pci_dev;
+--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp_glue.c
++++ gregkh-2.6/drivers/pci/hotplug/acpiphp_glue.c
+@@ -319,6 +319,13 @@ static void init_bridge_misc(struct acpi
+
+ /* install notify handler */
+ if (bridge->type != BRIDGE_TYPE_HOST) {
++ if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) {
++ status = acpi_remove_notify_handler(bridge->func->handle,
++ ACPI_SYSTEM_NOTIFY,
++ handle_hotplug_event_func);
++ if (ACPI_FAILURE(status))
++ err("failed to remove notify handler\n");
++ }
+ status = acpi_install_notify_handler(bridge->handle,
+ ACPI_SYSTEM_NOTIFY,
+ handle_hotplug_event_bridge,
+@@ -331,6 +338,66 @@ static void init_bridge_misc(struct acpi
+ }
+
+
++/* find acpiphp_func from acpiphp_bridge */
++static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle)
++{
++ struct list_head *node, *l;
++ struct acpiphp_bridge *bridge;
++ struct acpiphp_slot *slot;
++ struct acpiphp_func *func;
++
++ list_for_each(node, &bridge_list) {
++ bridge = list_entry(node, struct acpiphp_bridge, list);
++ for (slot = bridge->slots; slot; slot = slot->next) {
++ list_for_each(l, &slot->funcs) {
++ func = list_entry(l, struct acpiphp_func,
++ sibling);
++ if (func->handle == handle)
++ return func;
++ }
++ }
++ }
++
++ return NULL;
++}
++
++
++static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge)
++{
++ acpi_handle dummy_handle;
++
++ if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
++ "_STA", &dummy_handle)))
++ bridge->flags |= BRIDGE_HAS_STA;
++
++ if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
++ "_EJ0", &dummy_handle)))
++ bridge->flags |= BRIDGE_HAS_EJ0;
++
++ if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
++ "_PS0", &dummy_handle)))
++ bridge->flags |= BRIDGE_HAS_PS0;
++
++ if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
++ "_PS3", &dummy_handle)))
++ bridge->flags |= BRIDGE_HAS_PS3;
++
++ /* is this ejectable p2p bridge? */
++ if (bridge->flags & BRIDGE_HAS_EJ0) {
++ struct acpiphp_func *func;
++
++ dbg("found ejectable p2p bridge\n");
++
++ /* make link between PCI bridge and PCI function */
++ func = acpiphp_bridge_handle_to_function(bridge->handle);
++ if (!func)
++ return;
++ bridge->func = func;
++ func->bridge = bridge;
++ }
++}
++
++
+ /* allocate and initialize host bridge data structure */
+ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
+ {
+@@ -364,6 +431,7 @@ static void add_p2p_bridge(acpi_handle *
+
+ bridge->type = BRIDGE_TYPE_P2P;
+ bridge->handle = handle;
++ config_p2p_bridge_flags(bridge);
+
+ bridge->pci_dev = pci_dev_get(pci_dev);
+ bridge->pci_bus = pci_dev->subordinate;
+@@ -423,7 +491,7 @@ find_p2p_bridge(acpi_handle handle, u32
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
+ find_p2p_bridge, dev->subordinate, NULL);
+ if (ACPI_FAILURE(status))
+- warn("find_p2p_bridge faied (error code = 0x%x)\n", status);
++ warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
+
+ out:
+ pci_dev_put(dev);
+@@ -486,7 +554,7 @@ static int add_bridge(acpi_handle handle
+ find_p2p_bridge, pci_bus, NULL);
+
+ if (ACPI_FAILURE(status))
+- warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
++ warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
+
+ return 0;
+ }
+@@ -516,6 +584,16 @@ static void cleanup_bridge(struct acpiph
+ if (ACPI_FAILURE(status))
+ err("failed to remove notify handler\n");
+
++ if ((bridge->type != BRIDGE_TYPE_HOST) &&
++ ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) {
++ status = acpi_install_notify_handler(bridge->func->handle,
++ ACPI_SYSTEM_NOTIFY,
++ handle_hotplug_event_func,
++ bridge->func);
++ if (ACPI_FAILURE(status))
++ err("failed to install interrupt notify handler\n");
++ }
++
+ slot = bridge->slots;
+ while (slot) {
+ struct acpiphp_slot *next = slot->next;
+@@ -549,6 +627,11 @@ cleanup_p2p_bridge(acpi_handle handle, u
+ {
+ struct acpiphp_bridge *bridge;
+
++ /* cleanup p2p bridges under this P2P bridge
++ in a depth-first manner */
++ acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
++ cleanup_p2p_bridge, NULL, NULL);
++
+ if (!(bridge = acpiphp_handle_to_bridge(handle)))
+ return AE_OK;
+ cleanup_bridge(bridge);
+@@ -559,15 +642,14 @@ static void remove_bridge(acpi_handle ha
+ {
+ struct acpiphp_bridge *bridge;
+
++ /* cleanup p2p bridges under this host bridge
++ in a depth-first manner */
++ acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
++ (u32)1, cleanup_p2p_bridge, NULL, NULL);
++
+ bridge = acpiphp_handle_to_bridge(handle);
+- if (bridge) {
++ if (bridge)
+ cleanup_bridge(bridge);
+- } else {
+- /* clean-up p2p bridges under this host bridge */
+- acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
+- ACPI_UINT32_MAX, cleanup_p2p_bridge,
+- NULL, NULL);
+- }
+ }
+
+ static struct pci_dev * get_apic_pci_info(acpi_handle handle)
+@@ -881,6 +963,7 @@ static int enable_device(struct acpiphp_
+ struct acpiphp_func *func;
+ int retval = 0;
+ int num, max, pass;
++ acpi_status status;
+
+ if (slot->flags & SLOT_ENABLED)
+ goto err_exit;
+@@ -933,6 +1016,17 @@ static int enable_device(struct acpiphp_
+ func = list_entry(l, struct acpiphp_func, sibling);
+ func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
+ func->function));
++ if (!func->pci_dev)
++ continue;
++
++ if (func->pci_dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
++ func->pci_dev->hdr_type != PCI_HEADER_TYPE_CARDBUS)
++ continue;
++
++ status = find_p2p_bridge(func->handle, (u32)1, bus, NULL);
++ if (ACPI_FAILURE(status))
++ warn("find_p2p_bridge failed (error code = 0x%x)\n",
++ status);
+ }
+
+ slot->flags |= SLOT_ENABLED;
+@@ -958,6 +1052,13 @@ static int disable_device(struct acpiphp
+ list_for_each (l, &slot->funcs) {
+ func = list_entry(l, struct acpiphp_func, sibling);
+
++ if (func->bridge) {
++ /* cleanup p2p bridges under this P2P bridge */
++ cleanup_p2p_bridge(func->bridge->handle,
++ (u32)1, NULL, NULL);
++ func->bridge = NULL;
++ }
++
+ acpiphp_bus_trim(func->handle);
+ /* try to remove anyway.
+ * acpiphp_bus_add might have been failed */
+@@ -1292,6 +1393,13 @@ static void handle_hotplug_event_bridge(
+ case ACPI_NOTIFY_EJECT_REQUEST:
+ /* request device eject */
+ dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
++ if ((bridge->type != BRIDGE_TYPE_HOST) &&
++ (bridge->flags & BRIDGE_HAS_EJ0)) {
++ struct acpiphp_slot *slot;
++ slot = bridge->func->slot;
++ if (!acpiphp_disable_slot(slot))
++ acpiphp_eject_slot(slot);
++ }
+ break;
+
+ case ACPI_NOTIFY_FREQUENCY_MISMATCH:
diff --git a/pci/acpiphp-turn-off-slot-power-at-error-case.patch b/pci/acpiphp-turn-off-slot-power-at-error-case.patch
new file mode 100644
index 0000000000000..1dd792b0fdc2d
--- /dev/null
+++ b/pci/acpiphp-turn-off-slot-power-at-error-case.patch
@@ -0,0 +1,41 @@
+From muneda.takahiro@jp.fujitsu.com Tue Mar 21 21:49:53 2006
+Date: Wed, 22 Mar 2006 14:49:33 +0900
+Message-ID: <87hd5rc9le.wl%muneda.takahiro@jp.fujitsu.com>
+From: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>
+Cc: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+Subject: acpiphp: turn off slot power at error case
+
+When acpiphp_enable_slot() is failed, acpiphp does not change
+the slot->flags. Therefore, when user tries to read power
+status, acpiphp_get_power_status() returns the enable status
+whether the slot is not really enabled.
+
+This patch fixes this BUG.
+
+Signed-off-by: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/hotplug/acpiphp_glue.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp_glue.c
++++ gregkh-2.6/drivers/pci/hotplug/acpiphp_glue.c
+@@ -1592,9 +1592,15 @@ int acpiphp_enable_slot(struct acpiphp_s
+ if (retval)
+ goto err_exit;
+
+- if (get_slot_status(slot) == ACPI_STA_ALL)
++ if (get_slot_status(slot) == ACPI_STA_ALL) {
+ /* configure all functions */
+ retval = enable_device(slot);
++ if (retval)
++ power_off_slot(slot);
++ } else {
++ dbg("%s: Slot status is not ACPI_STA_ALL\n", __FUNCTION__);
++ power_off_slot(slot);
++ }
+
+ err_exit:
+ mutex_unlock(&slot->crit_sect);
diff --git a/pci/pci-hotplug-tollhouse-hp-sgi-hotplug-driver-changes.patch b/pci/pci-hotplug-tollhouse-hp-sgi-hotplug-driver-changes.patch
new file mode 100644
index 0000000000000..6c79547130ad1
--- /dev/null
+++ b/pci/pci-hotplug-tollhouse-hp-sgi-hotplug-driver-changes.patch
@@ -0,0 +1,123 @@
+From prarit@sgi.com Tue Apr 4 06:26:54 2006
+Date: Tue, 4 Apr 2006 09:26:46 -0400
+From: Prarit Bhargava <prarit@sgi.com>
+To: <edwardsg@sgi.com>
+Cc: Prarit Bhargava <prarit@sgi.com>
+Message-Id: <20060404132641.10912.44536.sendpatchset@prarit.boston.redhat.com>
+Subject: PCI Hotplug: Tollhouse HP: SGI hotplug driver changes
+
+SGI hotplug driver changes required to support Tollhouse system PCI
+hotplug, and implements the PRF_HOTPLUG_SUPPORT feature bit.
+
+Signed-off-by: Prarit Bhargava <prarit@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/hotplug/sgi_hotplug.c | 42 +++++++++++++++++++-------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/sgi_hotplug.c
++++ gregkh-2.6/drivers/pci/hotplug/sgi_hotplug.c
+@@ -18,11 +18,13 @@
+ #include <linux/mutex.h>
+
+ #include <asm/sn/addrs.h>
++#include <asm/sn/geo.h>
+ #include <asm/sn/l1.h>
+ #include <asm/sn/module.h>
+ #include <asm/sn/pcibr_provider.h>
+ #include <asm/sn/pcibus_provider_defs.h>
+ #include <asm/sn/pcidev.h>
++#include <asm/sn/sn_feature_sets.h>
+ #include <asm/sn/sn_sal.h>
+ #include <asm/sn/types.h>
+
+@@ -102,8 +104,7 @@ static struct hotplug_slot_attribute sn_
+ static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
+ {
+ struct pcibus_info *pcibus_info;
+- int bricktype;
+- int bus_num;
++ u16 busnum, segment, ioboard_type;
+
+ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
+
+@@ -111,12 +112,14 @@ static int sn_pci_slot_valid(struct pci_
+ if (!(pcibus_info->pbi_valid_devices & (1 << device)))
+ return -EPERM;
+
+- bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid);
+- bus_num = pcibus_info->pbi_buscommon.bs_persist_busnum & 0xf;
++ ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
++ busnum = pcibus_info->pbi_buscommon.bs_persist_busnum;
++ segment = pci_domain_nr(pci_bus) & 0xf;
+
+ /* Do not allow hotplug operations on base I/O cards */
+- if ((bricktype == L1_BRICKTYPE_IX || bricktype == L1_BRICKTYPE_IA) &&
+- (bus_num == 1 && device != 1))
++ if ((ioboard_type == L1_BRICKTYPE_IX ||
++ ioboard_type == L1_BRICKTYPE_IA) &&
++ (segment == 1 && busnum == 0 && device != 1))
+ return -EPERM;
+
+ return 1;
+@@ -125,23 +128,23 @@ static int sn_pci_slot_valid(struct pci_
+ static int sn_pci_bus_valid(struct pci_bus *pci_bus)
+ {
+ struct pcibus_info *pcibus_info;
+- int asic_type;
+- int bricktype;
+-
+- pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
++ u32 asic_type;
++ u16 ioboard_type;
+
+ /* Don't register slots hanging off the TIOCA bus */
++ pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
+ asic_type = pcibus_info->pbi_buscommon.bs_asic_type;
+ if (asic_type == PCIIO_ASIC_TYPE_TIOCA)
+ return -EPERM;
+
+ /* Only register slots in I/O Bricks that support hotplug */
+- bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid);
+- switch (bricktype) {
++ ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
++ switch (ioboard_type) {
+ case L1_BRICKTYPE_IX:
+ case L1_BRICKTYPE_PX:
+ case L1_BRICKTYPE_IA:
+ case L1_BRICKTYPE_PA:
++ case L1_BOARDTYPE_PCIX3SLOT:
+ return 1;
+ break;
+ default:
+@@ -175,14 +178,11 @@ static int sn_hp_slot_private_alloc(stru
+ slot->pci_bus = pci_bus;
+ sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x",
+ pci_domain_nr(pci_bus),
+- ((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf,
++ ((u16)pcibus_info->pbi_buscommon.bs_persist_busnum),
+ device + 1);
+- sprintf(slot->physical_path, "module_%c%c%c%c%.2d",
+- '0'+RACK_GET_CLASS(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
+- '0'+RACK_GET_GROUP(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
+- '0'+RACK_GET_NUM(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
+- MODULE_GET_BTCHAR(pcibus_info->pbi_moduleid),
+- MODULE_GET_BPOS(pcibus_info->pbi_moduleid));
++
++ sn_generate_path(pci_bus, slot->physical_path);
++
+ slot->hotplug_slot = bss_hotplug_slot;
+ list_add(&slot->hp_list, &sn_hp_list);
+
+@@ -553,8 +553,8 @@ static int sn_pci_hotplug_init(void)
+ int rc;
+ int registered = 0;
+
+- if (sn_sal_rev() < SGI_HOTPLUG_PROM_REV) {
+- printk(KERN_ERR "%s: PROM version must be greater than 4.30\n",
++ if (!sn_prom_feature_available(PRF_HOTPLUG_SUPPORT)) {
++ printk(KERN_ERR "%s: PROM version does not support hotplug.\n",
+ __FUNCTION__);
+ return -EPERM;
+ }
diff --git a/pci/pci-legacy-i-o-port-free-driver-changes-to-generic-pci-code.patch b/pci/pci-legacy-i-o-port-free-driver-changes-to-generic-pci-code.patch
new file mode 100644
index 0000000000000..1ba3a760d752f
--- /dev/null
+++ b/pci/pci-legacy-i-o-port-free-driver-changes-to-generic-pci-code.patch
@@ -0,0 +1,186 @@
+From kaneshige.kenji@jp.fujitsu.com Sun Mar 26 21:37:51 2006
+Message-ID: <4427799E.1070902@jp.fujitsu.com>
+Date: Mon, 27 Mar 2006 14:35:26 +0900
+From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+To: Andrew Morton <akpm@osdl.org>
+CC: greg@kroah.com, linux-kernel@vger.kernel.org, linux-pci@atrey.karlin.mff.cuni.cz
+Subject: PCI: legacy I/O port free driver - Changes to generic PCI code
+
+This patch adds the following changes into generic PCI code especially
+for PCI legacy free drivers.
+
+ - Moved the following two things from pci_enable_device() into
+ pci_enable_device_bars(). By this change, we can use
+ pci_enable_device_bars() to enable only the specific regions.
+
+ o Call pci_fixup_device() on the device
+ o Set dev->is_enabled
+
+ - Added new field 'bars_enabled' into struct pci_device to
+ remember which BARs already enabled. This new field is
+ initialized at pci_enable_device_bars() time and cleared
+ at pci_disable_device() time.
+
+ - Changed pci_request_regions()/pci_release_regions() to
+ request/release only the regions which have already been
+ enabled.
+
+ - Added helper routine pci_select_bars() which makes proper mask
+ of BARs from the specified resource type. This would be very
+ helpful for users of pci_enable_device_bars().
+
+Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/pci-driver.c | 3 ++-
+ drivers/pci/pci.c | 47 ++++++++++++++++++++++++++++++++++++++++-------
+ include/linux/pci.h | 2 ++
+ 3 files changed, 44 insertions(+), 8 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/pci-driver.c
++++ gregkh-2.6/drivers/pci/pci-driver.c
+@@ -291,7 +291,8 @@ static void pci_default_resume(struct pc
+ pci_restore_state(pci_dev);
+ /* if the device was enabled before suspend, reenable */
+ if (pci_dev->is_enabled)
+- retval = pci_enable_device(pci_dev);
++ retval = pci_enable_device_bars(pci_dev,
++ pci_dev->bars_enabled);
+ /* if the device was busmaster before the suspend, make it busmaster again */
+ if (pci_dev->is_busmaster)
+ pci_set_master(pci_dev);
+--- gregkh-2.6.orig/drivers/pci/pci.c
++++ gregkh-2.6/drivers/pci/pci.c
+@@ -488,6 +488,9 @@ pci_enable_device_bars(struct pci_dev *d
+ err = pcibios_enable_device(dev, bars);
+ if (err < 0)
+ return err;
++ pci_fixup_device(pci_fixup_enable, dev);
++ dev->is_enabled = 1;
++ dev->bars_enabled = bars;
+ return 0;
+ }
+
+@@ -505,8 +508,6 @@ pci_enable_device(struct pci_dev *dev)
+ int err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
+ if (err)
+ return err;
+- pci_fixup_device(pci_fixup_enable, dev);
+- dev->is_enabled = 1;
+ return 0;
+ }
+
+@@ -541,6 +542,7 @@ pci_disable_device(struct pci_dev *dev)
+
+ pcibios_disable_device(dev);
+ dev->is_enabled = 0;
++ dev->bars_enabled = 0;
+ }
+
+ /**
+@@ -623,6 +625,12 @@ void pci_release_region(struct pci_dev *
+ {
+ if (pci_resource_len(pdev, bar) == 0)
+ return;
++ if (!(pdev->bars_enabled & (1 << bar))) {
++ dev_warn(&pdev->dev,
++ "Trying to release region #%d that is not enabled\n",
++ bar + 1);
++ return;
++ }
+ if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
+ release_region(pci_resource_start(pdev, bar),
+ pci_resource_len(pdev, bar));
+@@ -649,7 +657,12 @@ int pci_request_region(struct pci_dev *p
+ {
+ if (pci_resource_len(pdev, bar) == 0)
+ return 0;
+-
++ if (!(pdev->bars_enabled & (1 << bar))) {
++ dev_warn(&pdev->dev,
++ "Trying to request region #%d that is not enabled\n",
++ bar + 1);
++ goto err_out;
++ }
+ if (pci_resource_flags(pdev, bar) & IORESOURCE_IO) {
+ if (!request_region(pci_resource_start(pdev, bar),
+ pci_resource_len(pdev, bar), res_name))
+@@ -687,7 +700,8 @@ void pci_release_regions(struct pci_dev
+ int i;
+
+ for (i = 0; i < 6; i++)
+- pci_release_region(pdev, i);
++ if (pdev->bars_enabled & (1 << i))
++ pci_release_region(pdev, i);
+ }
+
+ /**
+@@ -708,13 +722,15 @@ int pci_request_regions(struct pci_dev *
+ int i;
+
+ for (i = 0; i < 6; i++)
+- if(pci_request_region(pdev, i, res_name))
+- goto err_out;
++ if (pdev->bars_enabled & (1 << i))
++ if(pci_request_region(pdev, i, res_name))
++ goto err_out;
+ return 0;
+
+ err_out:
+ while(--i >= 0)
+- pci_release_region(pdev, i);
++ if (pdev->bars_enabled & (1 << i))
++ pci_release_region(pdev, i);
+
+ return -EBUSY;
+ }
+@@ -889,6 +905,22 @@ pci_set_consistent_dma_mask(struct pci_d
+ }
+ #endif
+
++/**
++ * pci_select_bars - Make BAR mask from the type of resource
++ * @pdev: the PCI device for which BAR mask is made
++ * @flags: resource type mask to be selected
++ *
++ * This helper routine makes bar mask from the type of resource.
++ */
++int pci_select_bars(struct pci_dev *dev, unsigned long flags)
++{
++ int i, bars = 0;
++ for (i = 0; i < PCI_NUM_RESOURCES; i++)
++ if (pci_resource_flags(dev, i) & flags)
++ bars |= (1 << i);
++ return bars;
++}
++
+ static int __devinit pci_init(void)
+ {
+ struct pci_dev *dev = NULL;
+@@ -946,6 +978,7 @@ EXPORT_SYMBOL(pci_set_dma_mask);
+ EXPORT_SYMBOL(pci_set_consistent_dma_mask);
+ EXPORT_SYMBOL(pci_assign_resource);
+ EXPORT_SYMBOL(pci_find_parent_resource);
++EXPORT_SYMBOL(pci_select_bars);
+
+ EXPORT_SYMBOL(pci_set_power_state);
+ EXPORT_SYMBOL(pci_save_state);
+--- gregkh-2.6.orig/include/linux/pci.h
++++ gregkh-2.6/include/linux/pci.h
+@@ -169,6 +169,7 @@ struct pci_dev {
+ struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
+ int rom_attr_enabled; /* has display of the rom attribute been enabled? */
+ struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
++ int bars_enabled; /* BARs enabled */
+ };
+
+ #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)
+@@ -497,6 +498,7 @@ int pci_set_consistent_dma_mask(struct p
+ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
+ int pci_assign_resource(struct pci_dev *dev, int i);
+ void pci_restore_bars(struct pci_dev *dev);
++int pci_select_bars(struct pci_dev *dev, unsigned long flags);
+
+ /* ROM control related routines */
+ void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
diff --git a/pci/pci-legacy-i-o-port-free-driver-make-emulex-lpfc-driver-legacy-i-o-port-free.patch b/pci/pci-legacy-i-o-port-free-driver-make-emulex-lpfc-driver-legacy-i-o-port-free.patch
new file mode 100644
index 0000000000000..57e07c0570898
--- /dev/null
+++ b/pci/pci-legacy-i-o-port-free-driver-make-emulex-lpfc-driver-legacy-i-o-port-free.patch
@@ -0,0 +1,30 @@
+From kaneshige.kenji@jp.fujitsu.com Thu Mar 23 21:43:15 2006
+Message-ID: <44238546.6080401@jp.fujitsu.com>
+Date: Fri, 24 Mar 2006 14:36:06 +0900
+From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>
+CC: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>, Andrew Morton <akpm@osdl.org>
+Subject: PCI: legacy I/O port free driver - Make Emulex lpfc driver legacy I/O port free
+
+This patch makes Emulex lpfc driver legacy I/O port free.
+
+Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/lpfc/lpfc_init.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- gregkh-2.6.orig/drivers/scsi/lpfc/lpfc_init.c
++++ gregkh-2.6/drivers/scsi/lpfc/lpfc_init.c
+@@ -1434,8 +1434,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev,
+ int error = -ENODEV, retval;
+ int i;
+ uint16_t iotag;
++ int bars = pci_select_bars(pdev, IORESOURCE_MEM);
+
+- if (pci_enable_device(pdev))
++ if (pci_enable_device_bars(pdev, bars))
+ goto out;
+ if (pci_request_regions(pdev, LPFC_DRIVER_NAME))
+ goto out_disable_device;
diff --git a/pci/pci-legacy-i-o-port-free-driver-make-intel-e1000-driver-legacy-i-o-port-free.patch b/pci/pci-legacy-i-o-port-free-driver-make-intel-e1000-driver-legacy-i-o-port-free.patch
new file mode 100644
index 0000000000000..b7c2bb66a63ba
--- /dev/null
+++ b/pci/pci-legacy-i-o-port-free-driver-make-intel-e1000-driver-legacy-i-o-port-free.patch
@@ -0,0 +1,200 @@
+From kaneshige.kenji@jp.fujitsu.com Thu Mar 23 21:41:53 2006
+Message-ID: <442384EA.60606@jp.fujitsu.com>
+Date: Fri, 24 Mar 2006 14:34:34 +0900
+From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>
+CC: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>, Andrew Morton <akpm@osdl.org>
+Subject: PCI: legacy I/O port free driver - 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 <kaneshige.kenji@jp.fujitsu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/e1000/e1000.h | 6 +-
+ drivers/net/e1000/e1000_main.c | 123 ++++++++++++++++++++++-------------------
+ 2 files changed, 71 insertions(+), 58 deletions(-)
+
+--- gregkh-2.6.orig/drivers/net/e1000/e1000.h
++++ gregkh-2.6/drivers/net/e1000/e1000.h
+@@ -77,8 +77,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_NO_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;
+
+@@ -338,6 +339,7 @@ struct e1000_adapter {
+ #ifdef NETIF_F_TSO
+ boolean_t tso_force;
+ #endif
++ int bars; /* BARs to be enabled */
+ };
+
+
+--- gregkh-2.6.orig/drivers/net/e1000/e1000_main.c
++++ gregkh-2.6/drivers/net/e1000/e1000_main.c
+@@ -86,54 +86,54 @@ static char e1000_copyright[] = "Copyrig
+ * {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(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(0x10B5),
+- INTEL_E1000_ETHERNET_DEVICE(0x10B9),
++ INTEL_E1000_ETHERNET_DEVICE(0x1000, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x1001, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x1004, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x1008, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1009, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x100C, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x100D, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x100E, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x100F, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1010, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1011, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1012, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1013, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1014, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x1015, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1016, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1017, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1018, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1019, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x101A, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x101D, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x101E, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1026, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x1027, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x1028, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x105E, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x105F, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x1060, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x1075, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x1076, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1077, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1078, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1079, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x107A, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x107B, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x107C, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x107D, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x107E, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x107F, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x108A, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x108B, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x108C, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x1096, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1098, 0),
++ INTEL_E1000_ETHERNET_DEVICE(0x1099, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x109A, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x10B5, E1000_NO_IOPORT),
++ INTEL_E1000_ETHERNET_DEVICE(0x10B9, 0),
+ /* required last entry */
+ {0,}
+ };
+@@ -619,7 +619,14 @@ e1000_probe(struct pci_dev *pdev,
+ int i, err, pci_using_dac;
+ uint16_t eeprom_data;
+ uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
+- if ((err = pci_enable_device(pdev)))
++ int bars;
++
++ if (ent->driver_data & E1000_NO_IOPORT)
++ bars = pci_select_bars(pdev, IORESOURCE_MEM);
++ else
++ bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
++
++ if ((err = pci_enable_device_bars(pdev, bars)))
+ return err;
+
+ if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
+@@ -652,6 +659,7 @@ e1000_probe(struct pci_dev *pdev,
+ 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);
+@@ -662,12 +670,15 @@ e1000_probe(struct pci_dev *pdev,
+ 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_NO_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;
++ }
+ }
+ }
+
+@@ -4574,7 +4585,7 @@ e1000_resume(struct pci_dev *pdev)
+ if (retval)
+ DPRINTK(PROBE, ERR, "Error in setting power state\n");
+ e1000_pci_restore_state(adapter);
+- ret_val = pci_enable_device(pdev);
++ ret_val = pci_enable_device_bars(pdev, adapter->bars);
+ pci_set_master(pdev);
+
+ retval = pci_enable_wake(pdev, PCI_D3hot, 0);
diff --git a/pci/pci-legacy-i-o-port-free-driver-update-documentation-pci.txt.patch b/pci/pci-legacy-i-o-port-free-driver-update-documentation-pci.txt.patch
new file mode 100644
index 0000000000000..7956dc154be83
--- /dev/null
+++ b/pci/pci-legacy-i-o-port-free-driver-update-documentation-pci.txt.patch
@@ -0,0 +1,92 @@
+From kaneshige.kenji@jp.fujitsu.com Thu Mar 23 21:39:19 2006
+Message-ID: <44238469.8080009@jp.fujitsu.com>
+Date: Fri, 24 Mar 2006 14:32:25 +0900
+From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>
+CC: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>, Andrew Morton <akpm@osdl.org>
+Subject: PCI: legacy I/O port free driver - Update Documentation/pci.txt
+
+This patch adds the description about legacy I/O port free driver into
+Documentation/pci.txt.
+
+Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Signed-off-by: Grant Grundler <grundler@parisc-linux.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/pci.txt | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 67 insertions(+)
+
+--- gregkh-2.6.orig/Documentation/pci.txt
++++ gregkh-2.6/Documentation/pci.txt
+@@ -269,3 +269,70 @@ having sane locking.
+ pci_find_device() Superseded by pci_get_device()
+ pci_find_subsys() Superseded by pci_get_subsys()
+ pci_find_slot() Superseded by pci_get_slot()
++
++
++9. Legacy I/O port free driver
++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++Large servers may not be able to provide I/O port resources to all PCI
++devices. I/O Port space is only 64KB on Intel Architecture[1] and is
++likely also fragmented since the I/O base register of PCI-to-PCI
++bridge will usually be aligned to a 4KB boundary[2]. On such systems,
++pci_enable_device() and pci_request_regions() will fail when
++attempting to enable I/O Port regions that don't have I/O Port
++resources assigned.
++
++Fortunately, many PCI devices which request I/O Port resources also
++provide access to the same registers via MMIO BARs. These devices can
++be handled without using I/O port space and the drivers typically
++offer a CONFIG_ option to only use MMIO regions
++(e.g. CONFIG_TULIP_MMIO). PCI devices typically provide I/O port
++interface for legacy OSs and will work when I/O port resources are not
++assigned. The "PCI Local Bus Specification Revision 3.0" discusses
++this on p.44, "IMPLEMENTATION NOTE".
++
++If your PCI device driver doesn't need I/O port resources assigned to
++I/O Port BARs, you should use pci_enable_device_bars() instead of
++pci_enable_device() in order not to enable I/O port regions for the
++corresponding devices.
++
++[1] Some systems support 64KB I/O port space per PCI segment.
++[2] Some PCI-to-PCI bridges support optional 1KB aligned I/O base.
++
++
++10. MMIO Space and "Write Posting"
++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++Converting a driver from using I/O Port space to using MMIO space
++often requires some additional changes. Specifically, "write posting"
++needs to be handled. Most drivers (e.g. tg3, acenic, sym53c8xx_2)
++already do. I/O Port space guarantees write transactions reach the PCI
++device before the CPU can continue. Writes to MMIO space allow to CPU
++continue before the transaction reaches the PCI device. HW weenies
++call this "Write Posting" because the write completion is "posted" to
++the CPU before the transaction has reached it's destination.
++
++Thus, timing sensitive code should add readl() where the CPU is
++expected to wait before doing other work. The classic "bit banging"
++sequence works fine for I/O Port space:
++
++ for (i=8; --i; val >>= 1) {
++ outb(val & 1, ioport_reg); /* write bit */
++ udelay(10);
++ }
++
++The same sequence for MMIO space should be:
++
++ for (i=8; --i; val >>= 1) {
++ writeb(val & 1, mmio_reg); /* write bit */
++ readb(safe_mmio_reg); /* flush posted write */
++ udelay(10);
++ }
++
++It is important that "safe_mmio_reg" not have any side effects that
++interferes with the correct operation of the device.
++
++Another case to watch out for is when resetting a PCI device. Use PCI
++Configuration space reads to flush the writel(). This will gracefully
++handle the PCI master abort on all platforms if the PCI device is
++expected to not respond to a readl(). Most x86 platforms will allow
++MMIO reads to master abort (aka "Soft Fail") and return garbage
++(e.g. ~0). But many RISC platforms will crash (aka "Hard Fail").