Skip to contentSkip to conversation

PCI fixes for 2.6.7

PATCH New Greg KH 1 participant 12 messages Jun 24, 2004

Subsystems (7)
Documentation PowerPC ACPI PCI +3 more subsystems
lore
Share & tools
lore

Greg KH

author
#0 lore raw

PATCH 1/1 PCI fixes for 2.6.7

Hi,

Here are some small PCI patches for 2.6.7. They include some pci id fixes, quirk fixups, and pci hotplug driver updates. They have all been in the last few -mm releases.

Please pull from:

	bk://kernel.bkbits.net/gregkh/linux/pci-2.6

thanks,

greg k-h

p.s. I'll send these as patches in response to this email to lkml for those who want to see them.

 Documentation/pci.txt                  |    5 
 Documentation/power/pci.txt            |    8 
 arch/i386/kernel/dmi_scan.c            |   59 +++++
 arch/i386/pci/irq.c                    |   27 ++
 drivers/pci/hotplug/pciehp_ctrl.c      |  147 ++++----------
 drivers/pci/hotplug/pciehp_hpc.c       |    4 
 drivers/pci/hotplug/pciehprm_acpi.c    |   22 +-
 drivers/pci/hotplug/pciehprm_nonacpi.c |   18 +
 drivers/pci/hotplug/rpadlpar_core.c    |   28 --
 drivers/pci/hotplug/rpaphp.h           |   28 ++
 drivers/pci/hotplug/rpaphp_core.c      |  199 +++++++++++++-------
 drivers/pci/hotplug/rpaphp_pci.c       |  328 ++++++++++++++++++++++-----------
 drivers/pci/hotplug/rpaphp_slot.c      |  136 +++++++++++--
 drivers/pci/hotplug/rpaphp_vio.c       |    6 
 drivers/pci/hotplug/shpchp.h           |    1 
 drivers/pci/hotplug/shpchp_ctrl.c      |   60 ++----
 drivers/pci/hotplug/shpchp_pci.c       |    1 
 drivers/pci/hotplug/shpchprm_acpi.c    |   22 +-
 drivers/pci/hotplug/shpchprm_nonacpi.c |   18 +
 drivers/pci/msi.c                      |   10 -
 drivers/pci/pci.c                      |    2 
 drivers/pci/quirks.c                   |    1 
 include/linux/pci_ids.h                |   54 +++--
 23 files changed, 781 insertions(+), 403 deletions(-)

-----

<ossi:kde.org>:
o PCI: (one more) PCI quirk for SMBus bridge on Asus P4 boards

Bjorn Helgaas:
o PCI: clarify pci.txt wrt IRQ allocation

Daniel Ritz:
o PCI: fix irq routing on acer travelmate 360 laptop

Dely Sy:
o Fixes for hot-plug drivers (updated)

Linda Xie:
o PCI Hotplug: rpaphp.patch -- multi-function devices not handled correctly

Roger Luethi:
o PCI: Fix off-by-one in pci_enable_wake
o PCI: Fix PME bits in pci.txt

Roland Dreier:
o PCI: Fix MSI-X setup

Stephen Hemminger:
o PCI: add id's for sk98 driver
o PCI: fix out of order entry in pci_ids.h
o PCI: remove duplicate in pci_ids.h

author
#1 lore raw

PATCH 1/1 PCI fixes for 2.6.7

ChangeSet 1.1722.103.1, 2004/06/04 15:01:07-07:00, [email protected]

[PATCH] Fixes for hot-plug drivers (updated)

Here is the updated patch (against 2.6.7-rc1) for the shpchp and pciehp drivers that fixes the following issues:
- proper LED status when latch is open or card is not present while the user tries to power up the slot; (reported by D. Keck)
- check if kmalloc() return NULL before proceeding in acpi_get__hpp(); (provided by L. Capitulino)
- add up(&ctrl->crit_sect) before return in error cases in several places;
- proper handling of resources when there are other onboard devices behind the p2p bridge that has the hot-plug capabaility;
- need to check negotiated link width in check_lnk_status();
- cleanup board_added() in pciehp

 drivers/pci/hotplug/pciehp_ctrl.c      |  147 +++++++++++----------------------
 drivers/pci/hotplug/pciehp_hpc.c       |    4 
 drivers/pci/hotplug/pciehprm_acpi.c    |   22 +++-
 drivers/pci/hotplug/pciehprm_nonacpi.c |   18 ++--
 drivers/pci/hotplug/shpchp.h           |    1 
 drivers/pci/hotplug/shpchp_ctrl.c      |   60 +++++--------
 drivers/pci/hotplug/shpchp_pci.c       |    1 
 drivers/pci/hotplug/shpchprm_acpi.c    |   22 +++-
 drivers/pci/hotplug/shpchprm_nonacpi.c |   18 ++--
 9 files changed, 137 insertions(+), 156 deletions(-)
drivers/pci/hotplug/pciehp_ctrl.c +49 -98
diff -Nru a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -1058,6 +1058,34 @@
    hotplug controller logic
  */
 
+static void set_slot_off(struct controller *ctrl, struct slot * pslot)
+{
+	/* Wait for exclusive access to hardware */
+	down(&ctrl->crit_sect);
+
+	/* turn off slot, turn on Amber LED, turn off Green LED */
+	if (pslot->hpc_ops->power_off_slot(pslot)) {   
+		err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
+		up(&ctrl->crit_sect);
+		return;
+	}
+	wait_for_ctrl_irq (ctrl);
+
+	pslot->hpc_ops->green_led_off(pslot);   
+	
+	wait_for_ctrl_irq (ctrl);
+
+	/* turn on Amber LED */
+	if (pslot->hpc_ops->set_attention_status(pslot, 1)) {   
+		err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
+		up(&ctrl->crit_sect);
+		return;
+	}
+	wait_for_ctrl_irq (ctrl);
+
+	/* Done with exclusive hardware access */
+	up(&ctrl->crit_sect);
+}
 
 /**
  * board_added - Called after a board has been added to the system.
@@ -1071,7 +1099,7 @@
 	u8 hp_slot;
 	int index;
 	u32 temp_register = 0xFFFFFFFF;
-	u32 retval, rc = 0;
+	u32 rc = 0;
 	struct pci_func *new_func = NULL;
 	struct slot *p_slot;
 	struct resource_lists res_lists;
@@ -1086,8 +1114,10 @@
 
 	/* Power on slot */
 	rc = p_slot->hpc_ops->power_on_slot(p_slot);
-	if (rc)
+	if (rc) {
+		up(&ctrl->crit_sect);
 		return -1;
+	}
 
 	/* Wait for the command to complete */
 	wait_for_ctrl_irq (ctrl);
@@ -1105,11 +1135,12 @@
 	wait_for_ctrl_irq (ctrl);
 	dbg("%s: afterlong_delay\n", __FUNCTION__);
 
-	/*  Make this to check for link training status */
+	/*  Check link training status */
 	rc = p_slot->hpc_ops->check_lnk_status(ctrl);  
 	if (rc) {
 		err("%s: Failed to check link status\n", __FUNCTION__);
-		return -1;
+		set_slot_off(ctrl, p_slot);
+		return rc;
 	}
 
 	dbg("%s: func status = %x\n", __FUNCTION__, func->status);
@@ -1159,36 +1190,7 @@
 		pciehp_resource_sort_and_combine(&(ctrl->bus_head));
 
 		if (rc) {
-			/* Wait for exclusive access to hardware */
-			down(&ctrl->crit_sect);
-
-			/* turn off slot, turn on Amber LED, turn off Green LED */
-			retval = p_slot->hpc_ops->power_off_slot(p_slot);   
-			/* In PCI Express, just power off slot */
-			if (retval) {
-				err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
-				return retval;
-			}
-			/* Wait for the command to complete */
-			wait_for_ctrl_irq (ctrl);
-
-			p_slot->hpc_ops->green_led_off(p_slot);   
-			
-			/* Wait for the command to complete */
-			wait_for_ctrl_irq (ctrl);
-
-			/* turn on Amber LED */
-			retval = p_slot->hpc_ops->set_attention_status(p_slot, 1);   
-			if (retval) {
-				err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
-				return retval;
-			}
-			/* Wait for the command to complete */
-			wait_for_ctrl_irq (ctrl);
-
-			/* Done with exclusive hardware access */
-			up(&ctrl->crit_sect);
-
+			set_slot_off(ctrl, p_slot);
 			return rc;
 		}
 		pciehp_save_slot_config(ctrl, func);
@@ -1223,37 +1225,8 @@
 		up(&ctrl->crit_sect);
 
 	} else {
-		/* Wait for exclusive access to hardware */
-		down(&ctrl->crit_sect);
-
-		/* turn off slot, turn on Amber LED, turn off Green LED */
-		retval = p_slot->hpc_ops->power_off_slot(p_slot);   
-		/* In PCI Express, just power off slot */
-		if (retval) {
-			err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
-			return retval;
-		}
-		/* Wait for the command to complete */
-		wait_for_ctrl_irq (ctrl);
-
-		p_slot->hpc_ops->green_led_off(p_slot);   
-		
-		/* Wait for the command to complete */
-		wait_for_ctrl_irq (ctrl);
-
-		/* turn on Amber LED */
-		retval = p_slot->hpc_ops->set_attention_status(p_slot, 1);   
-		if (retval) {
-			err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
-			return retval;
-		}
-		/* Wait for the command to complete */
-		wait_for_ctrl_irq (ctrl);
-
-		/* Done with exclusive hardware access */
-		up(&ctrl->crit_sect);
-
-		return rc;
+		set_slot_off(ctrl, p_slot);
+		return -1;
 	}
 	return 0;
 }
@@ -1320,6 +1293,7 @@
 	rc = p_slot->hpc_ops->power_off_slot(p_slot);
 	if (rc) {
 		err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
+		up(&ctrl->crit_sect);
 		return rc;
 	}
 	/* Wait for the command to complete */
@@ -1406,7 +1380,6 @@
 {
 	struct slot *p_slot = (struct slot *) slot;
 	u8 getstatus;
-	int rc;
 	
 	pushbutton_pending = 0;
 
@@ -1420,23 +1393,7 @@
 		p_slot->state = POWEROFF_STATE;
 		dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
 
-		if (pciehp_disable_slot(p_slot)) {
-			/* Wait for exclusive access to hardware */
-			down(&p_slot->ctrl->crit_sect);
-
-			/* Turn on the Attention LED */
-			rc = p_slot->hpc_ops->set_attention_status(p_slot, 1);
-			if (rc) {
-				err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__);
-				return;
-			}
-	
-			/* Wait for the command to complete */
-			wait_for_ctrl_irq (p_slot->ctrl);
-
-			/* Done with exclusive hardware access */
-			up(&p_slot->ctrl->crit_sect);
-		}
+		pciehp_disable_slot(p_slot);
 		p_slot->state = STATIC_STATE;
 	} else {
 		p_slot->state = POWERON_STATE;
@@ -1446,15 +1403,6 @@
 			/* Wait for exclusive access to hardware */
 			down(&p_slot->ctrl->crit_sect);
 
-			/* Turn off the green LED */
-			rc = p_slot->hpc_ops->set_attention_status(p_slot, 1);
-			if (rc) {
-				err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__);
-				return;
-			}
-			/* Wait for the command to complete */
-			wait_for_ctrl_irq (p_slot->ctrl);
-			
 			p_slot->hpc_ops->green_led_off(p_slot);
 
 			/* Wait for the command to complete */
@@ -1664,7 +1612,10 @@
 					down(&ctrl->crit_sect);
 
 					p_slot->hpc_ops->set_attention_status(p_slot, 1);
+					wait_for_ctrl_irq (ctrl);
+						
 					p_slot->hpc_ops->green_led_off(p_slot);
+					wait_for_ctrl_irq (ctrl);
 
 					/* Done with exclusive hardware access */
 					up(&ctrl->crit_sect);
@@ -1701,21 +1652,21 @@
 	if (rc || !getstatus) {
 		info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
 		up(&p_slot->ctrl->crit_sect);
-		return 0;
+		return 1;
 	}
 	
 	rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
 	if (rc || getstatus) {
 		info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
 		up(&p_slot->ctrl->crit_sect);
-		return 0;
+		return 1;
 	}
 	
 	rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
 	if (rc || getstatus) {
 		info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
 		up(&p_slot->ctrl->crit_sect);
-		return 0;
+		return 1;
 	}
 	up(&p_slot->ctrl->crit_sect);
 
@@ -1788,21 +1739,21 @@
 	if (ret || !getstatus) {
 		info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
 		up(&p_slot->ctrl->crit_sect);
-		return 0;
+		return 1;
 	}
 
 	ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
 	if (ret || getstatus) {
 		info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
 		up(&p_slot->ctrl->crit_sect);
-		return 0;
+		return 1;
 	}
 
 	ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
 	if (ret || !getstatus) {
 		info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
 		up(&p_slot->ctrl->crit_sect);
-		return 0;
+		return 1;
 	}
 	up(&p_slot->ctrl->crit_sect);
 
drivers/pci/hotplug/pciehp_hpc.c +3 -1
diff -Nru a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
@@ -349,7 +349,9 @@
 		return retval;
 	}
 
-	if ( (lnk_status & (LNK_TRN | LNK_TRN_ERR)) == 0x0C00) {
+	dbg("%s: lnk_status = %x\n", __FUNCTION__, lnk_status);
+	if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) || 
+		!(lnk_status & NEG_LINK_WD)) {
 		err("%s : Link Training Error occurs \n", __FUNCTION__);
 		retval = -1;
 		return retval;
drivers/pci/hotplug/pciehprm_acpi.c +17 -5
diff -Nru a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -218,6 +218,10 @@
 	}
 
 	ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
+	if (!ab->_hpp) {
+		err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name);
+		goto free_and_return;
+	}
 	memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
 
 	ab->_hpp->cache_line_size	= nui[0];
@@ -1393,7 +1397,7 @@
 
 static int bind_pci_resources_to_slots ( struct controller *ctrl)
 {
-	struct pci_func *func;
+	struct pci_func *func, new_func;
 	int busn = ctrl->slot_bus;
 	int devn, funn;
 	u32	vid;
@@ -1411,11 +1415,19 @@
 			if (vid != 0xFFFFFFFF) {
 				dbg("%s: vid = %x\n", __FUNCTION__, vid);
 				func = pciehp_slot_find(busn, devn, funn);
-				if (!func)
-					continue;
-				configure_existing_function(ctrl, func);
+				if (!func) {
+					memset(&new_func, 0, sizeof(struct pci_func));
+					new_func.bus = busn;
+					new_func.device = devn;
+					new_func.function = funn;
+					new_func.is_a_board = 1;
+					configure_existing_function(ctrl, &new_func);
+					pciehprm_dump_func_res(&new_func);
+				} else {
+					configure_existing_function(ctrl, func);
+					pciehprm_dump_func_res(func);
+				}
 				dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
-				pciehprm_dump_func_res(func);
 			}
 		}
 	}
drivers/pci/hotplug/pciehprm_nonacpi.c +13 -5
diff -Nru a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -276,7 +276,7 @@
 
 static int bind_pci_resources_to_slots ( struct controller *ctrl)
 {
-	struct pci_func *func;
+	struct pci_func *func, new_func;
 	int busn = ctrl->slot_bus;
 	int devn, funn;
 	u32	vid;
@@ -297,11 +297,19 @@
 				vid, busn, devn, funn);
 				func = pciehp_slot_find(busn, devn, funn);
 				dbg("%s: func = %p\n", __FUNCTION__,func);
-				if (!func)
-					continue;
-				configure_existing_function(ctrl, func);
+				if (!func) {
+					memset(&new_func, 0, sizeof(struct pci_func));
+					new_func.bus = busn;
+					new_func.device = devn;
+					new_func.function = funn;
+					new_func.is_a_board = 1;
+					configure_existing_function(ctrl, &new_func);
+					phprm_dump_func_res(&new_func);
+				} else {
+					configure_existing_function(ctrl, func);
+					phprm_dump_func_res(func);
+				}
 				dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
-				phprm_dump_func_res(func);
 			}
 		}
 	}
drivers/pci/hotplug/shpchp.h +1 -0
diff -Nru a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
@@ -61,6 +61,7 @@
 	u8 configured;
 	u8 switch_save;
 	u8 presence_save;
+	u8 pwr_save;
 	u32 base_length[0x06];
 	u8 base_type[0x06];
 	u16 reserved2;
drivers/pci/hotplug/shpchp_ctrl.c +23 -37

171 lines not on this page · raw message

drivers/pci/hotplug/shpchp_pci.c +1 -0
diff -Nru a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
@@ -263,6 +263,7 @@
 				new_slot->function = (u8) function;
 				new_slot->is_a_board = 1;
 				new_slot->switch_save = 0x10;
+				new_slot->pwr_save = 1;
 				/* In case of unsupported board */
 				new_slot->status = DevError;
 				new_slot->pci_dev = pci_find_slot(new_slot->bus,
drivers/pci/hotplug/shpchprm_acpi.c +17 -5
diff -Nru a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
@@ -218,6 +218,10 @@
 	}
 
 	ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
+	if (!ab->_hpp) {
+		err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name);
+		goto free_and_return;
+	}
 	memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
 
 	ab->_hpp->cache_line_size	= nui[0];
@@ -1391,7 +1395,7 @@
 
 static int bind_pci_resources_to_slots ( struct controller *ctrl)
 {
-	struct pci_func *func;
+	struct pci_func *func, new_func;
 	int busn = ctrl->bus;
 	int devn, funn;
 	u32	vid;
@@ -1406,11 +1410,19 @@
 
 			if (vid != 0xFFFFFFFF) {
 				func = shpchp_slot_find(busn, devn, funn);
-				if (!func)
-					continue;
-				configure_existing_function(ctrl, func);
+				if (!func) {
+					memset(&new_func, 0, sizeof(struct pci_func));
+					new_func.bus = busn;
+					new_func.device = devn;
+					new_func.function = funn;
+					new_func.is_a_board = 1;
+					configure_existing_function(ctrl, &new_func);
+					shpchprm_dump_func_res(&new_func);
+				} else {
+					configure_existing_function(ctrl, func);
+					shpchprm_dump_func_res(func);
+				}
 				dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
-				shpchprm_dump_func_res(func);
 			}
 		}
 	}
drivers/pci/hotplug/shpchprm_nonacpi.c +13 -5
diff -Nru a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
@@ -208,7 +208,7 @@
 
 static int bind_pci_resources_to_slots ( struct controller *ctrl)
 {
-	struct pci_func *func;
+	struct pci_func *func, new_func;
 	int busn = ctrl->slot_bus;
 	int devn, funn;
 	u32	vid;
@@ -226,11 +226,19 @@
 
 			if (vid != 0xFFFFFFFF) {
 				func = shpchp_slot_find(busn, devn, funn);
-				if (!func)
-					continue;
-				configure_existing_function(ctrl, func);
+				if (!func) {
+					memset(&new_func, 0, sizeof(struct pci_func));
+					new_func.bus = busn;
+					new_func.device = devn;
+					new_func.function = funn;
+					new_func.is_a_board = 1;
+					configure_existing_function(ctrl, &new_func);
+					phprm_dump_func_res(&new_func);
+				} else {
+					configure_existing_function(ctrl, func);
+					phprm_dump_func_res(func);
+				}
 				dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
-				phprm_dump_func_res(func);
 			}
 		}
 	}
author
#2 lore raw

ChangeSet 1.1722.103.2, 2004/06/08 14:28:46-07:00, [email protected]

[PATCH] PCI: fix irq routing on acer travelmate 360 laptop

Fixes interrupt routing on acer travelmate 360 notebooks. it looks like the bios assigned the wrong pirq value for the cardbus bridge. just assigning irq 10 to all devices with pirq 0x63 would break second usb port. pirq 0x68 seems to be right one for cardbus.

 arch/i386/kernel/dmi_scan.c |   29 +++++++++++++++++++++++++++++
 arch/i386/pci/irq.c         |    9 +++++++++
 2 files changed, 38 insertions(+)
arch/i386/kernel/dmi_scan.c +29 -0
diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
@@ -360,6 +360,21 @@
 }
 
 /*
+ * Work around broken Acer TravelMate 360 Notebooks which assign Cardbus to
+ * IRQ 11 even though it is actually wired to IRQ 10
+ */
+static __init int fix_acer_tm360_irqrouting(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_PCI
+	extern int acer_tm360_irqrouting;
+	if (acer_tm360_irqrouting == 0) {
+		acer_tm360_irqrouting = 1;
+		printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident);
+	}
+#endif
+	return 0;
+}
+/*
  *  Check for clue free BIOS implementations who use
  *  the following QA technique
  *
@@ -844,6 +859,13 @@
 			MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"),
 			MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736")
 			} },
+
+	{ fix_acer_tm360_irqrouting, "Acer TravelMate 36x Laptop", {
+			MATCH(DMI_SYS_VENDOR, "Acer"),
+			MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
+			NO_MATCH, NO_MATCH
+			} },
+
  
 
 	/*
@@ -1033,6 +1055,13 @@
 			MATCH(DMI_BOARD_NAME, "PR-DLS"),
 			MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
 			MATCH(DMI_BIOS_DATE, "03/21/2003") }},
+
+ 	{ disable_acpi_pci, "Acer TravelMate 36x Laptop", {
+ 			MATCH(DMI_SYS_VENDOR, "Acer"),
+ 			MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
+ 			NO_MATCH, NO_MATCH
+ 			} },
+
 #endif
 
 	{ NULL, }
arch/i386/pci/irq.c +9 -0
diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
@@ -23,6 +23,7 @@
 #define PIRQ_VERSION 0x0100
 
 int broken_hp_bios_irq9;
+int acer_tm360_irqrouting;
 
 static struct irq_routing_table *pirq_table;
 
@@ -743,6 +744,14 @@
 		dev->irq = 11;
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
 		r->set(pirq_router_dev, dev, pirq, 11);
+	}
+
+	/* same for Acer Travelmate 360, but with CB and irq 11 -> 10 */
+	if (acer_tm360_irqrouting && dev->irq == 11 && dev->vendor == PCI_VENDOR_ID_O2) {
+		pirq = 0x68;
+		mask = 0x400;
+		dev->irq = r->get(pirq_router_dev, dev, pirq);
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 	}
 
 	/*
author
#3 lore raw

ChangeSet 1.1722.103.3, 2004/06/11 17:15:00-07:00, [email protected]

[PATCH] PCI: clarify pci.txt wrt IRQ allocation

I think we should make it explicit that PCI IRQs shouldn't be relied upon until after pci_enable_device(). This patch:

    ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.7-rc3/2.6.7-rc3-mm1/broken-out/bk-acpi.patch

does PCI interrupt routing (based on ACPI _PRT) and IRQ allocation at pci_enable_device()-time.

(To avoid breaking things in 2.6, the above patch still allocates all PCI IRQs in pci_acpi_init(), before any drivers are initialized. But that shouldn't be needed by correct drivers, and I'd like to remove it in 2.7.)

 Documentation/pci.txt |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
Documentation/pci.txt +3 -2
diff -Nru a/Documentation/pci.txt b/Documentation/pci.txt
@@ -166,8 +166,9 @@
 ~~~~~~~~~~~~~~~~~~~
    Before you do anything with the device you've found, you need to enable
 it by calling pci_enable_device() which enables I/O and memory regions of
-the device, assigns missing resources if needed and wakes up the device
-if it was in suspended state. Please note that this function can fail.
+the device, allocates an IRQ if necessary, assigns missing resources if
+needed and wakes up the device if it was in suspended state. Please note
+that this function can fail.
 
    If you want to use the device in bus mastering mode, call pci_set_master()
 which enables the bus master bit in PCI_COMMAND register and also fixes
author
#4 lore raw

ChangeSet 1.1722.103.4, 2004/06/11 17:15:38-07:00, [email protected]

[PATCH] PCI Hotplug: rpaphp.patch -- multi-function devices not handled correctly

I made changes to rpaphp code, so it can handle multi-fuction devices correctly. The problem is that the pci_dev field of slot struct can only record one pci_dev of the devices of a multi-fuction card. I changed pci_dev (a single pci_dev type pointer) to pci_funcs( a list of pci_dev type pointers). I rewrote some of the config/unconfig code to support the slot struct change.

Along with above changes, I added LDRSLOT(logical I/O slot) support. We need LDRSLOT support for DLPAR I/O. A card in a LDRSLOT can't be physically removed, but can be logically removed from one partiton and reassinged to another partition.

I also merged rpaphp changes from ames tree.

 drivers/pci/hotplug/rpadlpar_core.c |   28 ---
 drivers/pci/hotplug/rpaphp.h        |   28 ++-
 drivers/pci/hotplug/rpaphp_core.c   |  199 +++++++++++++++------
 drivers/pci/hotplug/rpaphp_pci.c    |  328 +++++++++++++++++++++++++-----------
 drivers/pci/hotplug/rpaphp_slot.c   |  136 ++++++++++++--
 drivers/pci/hotplug/rpaphp_vio.c    |    6 
 6 files changed, 508 insertions(+), 217 deletions(-)
drivers/pci/hotplug/rpadlpar_core.c +5 -23
diff -Nru a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
@@ -24,25 +24,6 @@
 
 static DECLARE_MUTEX(rpadlpar_sem);
 
-static inline int is_hotplug_capable(struct device_node *dn)
-{
-	unsigned char *ptr = get_property(dn, "ibm,fw-pci-hot-plug-ctrl", NULL);
-
-	return (int) (ptr != NULL);
-}
-
-static char *get_node_drc_name(struct device_node *dn)
-{
-	char *ptr = NULL;
-	int *drc_names;
-
-	drc_names = (int *) get_property(dn, "ibm,drc-names", NULL);
-	if (drc_names)
-		ptr = (char *) &drc_names[1];
-
-	return ptr;
-}
-
 static struct device_node *find_php_slot_vio_node(char *drc_name)
 {
 	struct device_node *child;
@@ -53,9 +34,9 @@
 		return NULL;
 
 	for (child = of_get_next_child(parent, NULL);
-	     child; child = of_get_next_child(parent, child)) {
+		child; child = of_get_next_child(parent, child)) {
 		loc_code = get_property(child, "ibm,loc-code", NULL);
-		if (loc_code && !strcmp(loc_code, drc_name))
+		if (loc_code && !strncmp(loc_code, drc_name, strlen(drc_name)))
 			return child;
 	}
 
@@ -69,7 +50,7 @@
 
 	while ((np = of_find_node_by_type(np, "pci")))
 		if (is_hotplug_capable(np)) {
-			name = get_node_drc_name(np);
+			name = rpaphp_get_drc_name(np);
 			if (name && (!strcmp(drc_name, name)))
 				break;
 		}
@@ -324,6 +305,7 @@
 	}
 
 	/* Remove pci bus */
+
 	if (dlpar_pci_remove_bus(bridge_dev)) {
 		printk(KERN_ERR "%s: unable to remove pci bus %s\n",
 			__FUNCTION__, drc_name);
@@ -364,7 +346,7 @@
 		rc = -EINVAL;
 		goto exit;
 	}
-
+	
 	switch (slot->dev_type) {
 		case PCI_DEV:
 			rc = dlpar_remove_pci_slot(slot, drc_name);
drivers/pci/hotplug/rpaphp.h +22 -6
diff -Nru a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
@@ -30,6 +30,9 @@
 #include <linux/pci.h>
 #include "pci_hotplug.h"
 
+#define	HOTPLUG	1
+#define	EMBEDDED 0
+
 #define DR_INDICATOR 9002
 #define DR_ENTITY_SENSE 9003
 
@@ -73,6 +76,11 @@
 #define	CONFIGURED	1
 #define	EMPTY		0
 
+struct rpaphp_pci_func {
+	struct pci_dev *pci_dev;
+	struct list_head sibling;
+};
+
 /*
  * struct slot - slot information for each *physical* slot
  */
@@ -83,14 +91,13 @@
 	u32 power_domain;
 	char *name;
 	char *location;
+	u8 removable;
 	struct device_node *dn;	/* slot's device_node in OFDT */
-	/* dn has phb info */
+				/* dn has phb info */
 	struct pci_dev *bridge;	/* slot's pci_dev in pci_devices */
 	union {
-		struct pci_dev *pci_dev;	/* pci_dev of device in this slot */
-		/* it will be used for unconfig */
-		/* NULL if slot is empty */
-		struct vio_dev *vio_dev;	/* vio_dev of the device in this slot */
+		struct list_head pci_funcs; /* pci_devs in PCI slot */ 
+		struct vio_dev *vio_dev; /* vio_dev in VIO slot */
 	} dev;
 	u8 dev_type;		/* VIO or PCI */
 	struct hotplug_slot *hotplug_slot;
@@ -101,6 +108,13 @@
 extern struct list_head rpaphp_slot_head;
 extern int num_slots;
 
+static inline int is_hotplug_capable(struct device_node *dn)
+{
+	unsigned char *ptr = get_property(dn, "ibm,fw-pci-hot-plug-ctrl", NULL);
+
+	return (int) (ptr != NULL);
+}
+
 /* function prototypes */
 
 /* rpaphp_pci.c */
@@ -110,10 +124,12 @@
 extern int register_pci_slot(struct slot *slot);
 extern int rpaphp_unconfig_pci_adapter(struct slot *slot);
 extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
+extern struct hotplug_slot *rpaphp_find_hotplug_slot(struct pci_dev *dev);
 
 /* rpaphp_core.c */
 extern int rpaphp_add_slot(struct device_node *dn);
 extern int rpaphp_remove_slot(struct slot *slot);
+extern char *rpaphp_get_drc_name(struct device_node *dn);
 
 /* rpaphp_vio.c */
 extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value);
@@ -125,8 +141,8 @@
 extern void dealloc_slot_struct(struct slot *slot);
 extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain);
 extern int register_slot(struct slot *slot);
+extern int deregister_slot(struct slot *slot);
 extern int rpaphp_get_power_status(struct slot *slot, u8 * value);
 extern int rpaphp_set_attention_status(struct slot *slot, u8 status);
-extern void rpaphp_sysfs_remove_attr_location(struct hotplug_slot *slot);
 	
 #endif				/* _PPC64PHP_H */
drivers/pci/hotplug/rpaphp_core.c +137 -62

302 lines not on this page · raw message

drivers/pci/hotplug/rpaphp_pci.c +228 -100

470 lines not on this page · raw message

drivers/pci/hotplug/rpaphp_slot.c +113 -23

208 lines not on this page · raw message

drivers/pci/hotplug/rpaphp_vio.c +3 -3
diff -Nru a/drivers/pci/hotplug/rpaphp_vio.c b/drivers/pci/hotplug/rpaphp_vio.c
@@ -74,11 +74,11 @@
 	int rc = 1;
 	struct slot *slot = NULL;
 	
+	name = rpaphp_get_drc_name(dn);
+	if (!name)
+		goto exit_rc;
 	index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL);
 	if (!index)
-		goto exit_rc;
-	name = get_property(dn, "ibm,loc-code", NULL);
-	if (!name)
 		goto exit_rc;
 	if (!(slot = alloc_slot_struct(dn, *index, name, 0))) {
 		rc = -ENOMEM;
author
#5 lore raw

ChangeSet 1.1722.103.5, 2004/06/14 11:08:54-07:00, [email protected]

[PATCH] PCI: Fix PME bits in pci.txt

 Documentation/power/pci.txt |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
Documentation/power/pci.txt +4 -4
diff -Nru a/Documentation/power/pci.txt b/Documentation/power/pci.txt
@@ -286,11 +286,11 @@
 +------------------+
 |  Bit  |  State   |
 +------------------+
-|  15   |   D0     |
-|  14   |   D1     |
+|  11   |   D0     |
+|  12   |   D1     |
 |  13   |   D2     |
-|  12   |   D3hot  |
-|  11   |   D3cold |
+|  14   |   D3hot  |
+|  15   |   D3cold |
 +------------------+
 
 A device can use this to enable wake events:
author
#6 lore raw

ChangeSet 1.1722.103.6, 2004/06/14 11:11:45-07:00, [email protected]

[PATCH] PCI: Fix off-by-one in pci_enable_wake

Fix off-by-one in pci_enable_wake.
Bit field location determined by mask, not value.

 drivers/pci/pci.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)
drivers/pci/pci.c +1 -1
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
@@ -442,7 +442,7 @@
 	pci_read_config_word(dev,pm+PCI_PM_PMC,&value);
 
 	value &= PCI_PM_CAP_PME_MASK;
-	value >>= ffs(value);   /* First bit of mask */
+	value >>= ffs(PCI_PM_CAP_PME_MASK) - 1;   /* First bit of mask */
 
 	/* Check if it can generate PME# from requested state. */
 	if (!value || !(value & (1 << state))) 
author
#7 lore raw

ChangeSet 1.1823.1.7, 2004/06/22 16:57:06-07:00, [email protected]

[PATCH] PCI: Fix MSI-X setup

msix_capability_init() puts the offset of the MSI-X capability into pos, then uses pos as a loop index to clear the MSI-X vector table, and then tries to use pos as the offset again, which results in writing the MSI-X enable bit off into space.

This patch fixes that by adding a new loop index variable and using that to clear the vector table.

 drivers/pci/msi.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)
drivers/pci/msi.c +5 -5
diff -Nru a/drivers/pci/msi.c b/drivers/pci/msi.c
@@ -569,7 +569,7 @@
 	struct msi_desc *entry;
 	struct msg_address address;
 	struct msg_data data;
-	int vector = 0, pos, dev_msi_cap;
+	int vector = 0, pos, dev_msi_cap, i;
 	u32 phys_addr, table_offset;
 	u32 control;
 	u8 bir;
@@ -629,12 +629,12 @@
 	writel(address.hi_address, base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
 	writel(*(u32*)&data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
 	/* Initialize all entries from 1 up to 0 */
-	for (pos = 1; pos < dev_msi_cap; pos++) {
-		writel(0, base + pos * PCI_MSIX_ENTRY_SIZE +
+	for (i = 1; i < dev_msi_cap; i++) {
+		writel(0, base + i * PCI_MSIX_ENTRY_SIZE +
 			PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
-		writel(0, base + pos * PCI_MSIX_ENTRY_SIZE +
+		writel(0, base + i * PCI_MSIX_ENTRY_SIZE +
 			PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
-		writel(0, base + pos * PCI_MSIX_ENTRY_SIZE +
+		writel(0, base + i * PCI_MSIX_ENTRY_SIZE +
 			PCI_MSIX_ENTRY_DATA_OFFSET);
 	}
 	attach_msi_entry(entry, vector);
author
#8 lore raw

ChangeSet 1.1823.1.8, 2004/06/22 16:57:48-07:00, [email protected]

[PATCH] PCI: remove duplicate in pci_ids.h

Get rid of duplicate entry, one is in the middle of the file with duplicate at the end

 include/linux/pci_ids.h |    3 ---
 1 files changed, 3 deletions(-)
include/linux/pci_ids.h +0 -3
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
@@ -2272,6 +2272,3 @@
 #define PCI_DEVICE_ID_MICROGATE_SCC	0x0020
 #define PCI_DEVICE_ID_MICROGATE_SCA	0x0030
 #define PCI_DEVICE_ID_MICROGATE_USC2	0x0210
-
-#define PCI_VENDOR_ID_HINT		0x3388
-#define PCI_DEVICE_ID_HINT_VXPROII_IDE	0x8013
author
#9 lore raw

ChangeSet 1.1823.1.9, 2004/06/22 16:58:27-07:00, [email protected]

[PATCH] PCI: fix out of order entry in pci_ids.h

The last entry in pci_ids.h is out of order, someone wasn't reading the comment to keep it sorted.

 include/linux/pci_ids.h |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)
include/linux/pci_ids.h +6 -6
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
@@ -1769,6 +1769,12 @@
 #define PCI_DEVICE_ID_CCD_B00C		0xb00c
 #define PCI_DEVICE_ID_CCD_B100		0xb100
 
+#define PCI_VENDOR_ID_MICROGATE		0x13c0
+#define PCI_DEVICE_ID_MICROGATE_USC	0x0010
+#define PCI_DEVICE_ID_MICROGATE_SCC	0x0020
+#define PCI_DEVICE_ID_MICROGATE_SCA	0x0030
+#define PCI_DEVICE_ID_MICROGATE_USC2	0x0210
+
 #define PCI_VENDOR_ID_3WARE		0x13C1
 #define PCI_DEVICE_ID_3WARE_1000	0x1000
 #define PCI_DEVICE_ID_3WARE_7000	0x1001
@@ -2266,9 +2272,3 @@
 #define PCI_DEVICE_ID_ARK_STING		0xa091
 #define PCI_DEVICE_ID_ARK_STINGARK	0xa099
 #define PCI_DEVICE_ID_ARK_2000MT	0xa0a1
-
-#define PCI_VENDOR_ID_MICROGATE		0x13c0
-#define PCI_DEVICE_ID_MICROGATE_USC	0x0010
-#define PCI_DEVICE_ID_MICROGATE_SCC	0x0020
-#define PCI_DEVICE_ID_MICROGATE_SCA	0x0030
-#define PCI_DEVICE_ID_MICROGATE_USC2	0x0210
author
#10 lore raw

ChangeSet 1.1823.1.10, 2004/06/22 16:59:02-07:00, [email protected]

[PATCH] PCI: add id's for sk98 driver

Redoing the sk98 driver to correct pci model. These are (most of) the entries it uses.

 include/linux/pci_ids.h |   12 ++++++++++++
 1 files changed, 12 insertions(+)
include/linux/pci_ids.h +12 -0
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
@@ -967,12 +967,14 @@
 
 #define PCI_VENDOR_ID_3COM		0x10b7
 #define PCI_DEVICE_ID_3COM_3C985	0x0001
+#define PCI_DEVICE_ID_3COM_3C940	0x1700
 #define PCI_DEVICE_ID_3COM_3C339	0x3390
 #define PCI_DEVICE_ID_3COM_3C359	0x3590
 #define PCI_DEVICE_ID_3COM_3C590	0x5900
 #define PCI_DEVICE_ID_3COM_3C595TX	0x5950
 #define PCI_DEVICE_ID_3COM_3C595T4	0x5951
 #define PCI_DEVICE_ID_3COM_3C595MII	0x5952
+#define PCI_DEVICE_ID_3COM_3C940B	0x80eb
 #define PCI_DEVICE_ID_3COM_3C900TPO	0x9000
 #define PCI_DEVICE_ID_3COM_3C900COMBO	0x9001
 #define PCI_DEVICE_ID_3COM_3C905TX	0x9050
@@ -1420,6 +1422,9 @@
 #define PCI_DEVICE_ID_RICOH_RL5C476	0x0476
 #define PCI_DEVICE_ID_RICOH_RL5C478	0x0478
 
+#define PCI_VENDOR_ID_DLINK		0x1186
+#define PCI_DEVICE_ID_DLINK_DGE510T	0x4c00
+
 #define PCI_VENDOR_ID_ARTOP		0x1191
 #define PCI_DEVICE_ID_ARTOP_ATP8400	0x0004
 #define PCI_DEVICE_ID_ARTOP_ATP850UF	0x0005
@@ -1735,6 +1740,9 @@
 #define PCI_VENDOR_ID_KAWASAKI		0x136b
 #define PCI_DEVICE_ID_MCHIP_KL5A72002	0xff01
 
+#define PCI_VENDOR_ID_CNET		0x1371
+#define PCI_DEVICE_ID_CNET_GIGACARD	0x434e
+
 #define PCI_VENDOR_ID_LMC		0x1376
 #define PCI_DEVICE_ID_LMC_HSSI		0x0003
 #define PCI_DEVICE_ID_LMC_DS3		0x0004
@@ -1918,6 +1926,10 @@
 #define PCI_DEVICE_ID_FARSITE_T4U       0x0640
 #define PCI_DEVICE_ID_FARSITE_TE1       0x1610
 #define PCI_DEVICE_ID_FARSITE_TE1C      0x1612
+
+#define PCI_VENDOR_ID_LINKSYS		0x1737
+#define PCI_DEVICE_ID_LINKSYS_EG1032	0x1032
+#define PCI_DEVICE_ID_LINKSYS_EG1064	0x1064
 
 #define PCI_VENDOR_ID_ALTIMA		0x173b
 #define PCI_DEVICE_ID_ALTIMA_AC1000	0x03e8
author
#11 lore raw

ChangeSet 1.1823.1.11, 2004/06/23 16:59:52-07:00, [email protected]

[PATCH] PCI: (one more) PCI quirk for SMBus bridge on Asus P4 boards

my board has one of those "clever" bioses that hide the smbus. this tiny patch adds it to the Bad Guy List (TM).

 drivers/pci/quirks.c |    1 +
 1 files changed, 1 insertion(+)
drivers/pci/quirks.c +1 -0
diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c
@@ -705,6 +705,7 @@
 		}
 	if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB)
 		switch(dev->subsystem_device) {
+ 		case 0x80b1: /* P4GE-V */
 		case 0x80b2: /* P4PE */
  		case 0x8093: /* P4B533-V */
 			asus_hides_smbus = 1;