Bug#270376: PCMCIA Nic stops working after upgrading to 2.6.6/7/8

Daniel Ritz daniel.ritz at gmx.ch
Thu Apr 7 17:44:30 EDT 2005


On Tuesday 05 April 2005 08:56, Jefferson Cowart wrote:
> Sorry for the delay in sending this. I ended up getting back later than
> expected. In any case the hexdumps are below. Please let me know if you need
> anything else.

also sorry for the delay :)

> 
> Under 2.6.5-bk1
> ===============
> (/proc/bus/pci/00/07.0)
> 0000000 104c ac17 0007 0210 0002 0607 a820 0082
> 0000010 8000 000c 00a0 0200 0100 b004 0000 1000
> 0000020 f000 103f 0000 1040 f000 107f 4400 0000
> 0000030 44fc 0000 4800 0000 48fc 0000 010a 0540
> 0000040 0000 0000 0001 0000 0000 0000 0000 0000
> 0000050 0000 0000 0000 0000 0000 0000 0000 0000
> *
> 0000080 7020 2800 0000 0000 0000 0000 3822 0ba4

               ^
there you go. the intrtie bit is set. this means that both functions
use INTA to signal the interrupts. but the BIOS is broken and assigned
a different irq to function 1 compared to function 0. 
so the reason it broke when the irq-routing patch was merged is that
irqs are actually probed to see if they work or if the routing needs
some tuning...

the attached patch should fix it. it's untested 'cos i don't have a
laptop with TI bridge anymore...but it's simple

rgds
-daniel

-----

[PATCH] yenta TI: align irq of func1 to func0 if INTRTIE is set

make sure that if the INTRTIE bit is set both functions of the
cardbus bridge use the same IRQ before doing any probing...
[ yes i hate the TI bridges for the fact that they are very flexible
  so that so many BIOS vendors get it wrong. ]

Signed-off-by: Daniel Ritz <daniel.ritz at gmx.ch>

--- 1.22/drivers/pcmcia/ti113x.h	2005-03-11 21:32:12 +01:00
+++ edited/drivers/pcmcia/ti113x.h	2005-04-07 23:14:40 +02:00
@@ -442,6 +442,25 @@
 }
 
 
+/* changes the irq of func1 to match that of func0 */
+static int ti12xx_align_irqs(struct yenta_socket *socket, int *old_irq)
+{
+	struct pci_dev *func0;
+
+	/* find func0 device */
+	func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
+	if (!func0)
+		return 0;
+
+	if (old_irq)
+		*old_irq = socket->cb_irq;
+	socket->cb_irq = socket->dev->irq = func0->irq;
+
+	pci_dev_put(func0);
+
+	return 1;
+}
+
 /*
  * ties INTA and INTB together. also changes the devices irq to that of
  * the function 0 device. call from func1 only.
@@ -449,26 +468,22 @@
  */
 static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq)
 {
-	struct pci_dev *func0;
 	u32 sysctl;
+	int ret;
 
 	sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
 	if (sysctl & TI122X_SCR_INTRTIE)
 		return 0;
 
-	/* find func0 device */
-	func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07);
-	if (!func0)
+	/* align */
+	ret = ti12xx_align_irqs(socket, old_irq);
+	if (!ret)
 		return 0;
 
-	/* change the interrupt to match func0, tie 'em up */
-	*old_irq = socket->cb_irq;
-	socket->cb_irq = socket->dev->irq = func0->irq;
+	/* tie */
 	sysctl |= TI122X_SCR_INTRTIE;
 	config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl);
 
-	pci_dev_put(func0);
-
 	return 1;
 }
 
@@ -489,7 +504,7 @@
  */
 static void ti12xx_irqroute_func1(struct yenta_socket *socket)
 {
-	u32 mfunc, mfunc_old, devctl;
+	u32 mfunc, mfunc_old, devctl, sysctl;
 	int pci_irq_status;
 
 	mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
@@ -497,6 +512,11 @@
 	printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
 	       pci_name(socket->dev), mfunc, devctl);
 
+	/* if IRQs are configured as tied, align irq of func1 with func0 */
+	sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
+	if (sysctl & TI122X_SCR_INTRTIE)
+		ti12xx_align_irqs(socket, NULL);
+	
 	/* make sure PCI interrupts are enabled before probing */
 	ti_init(socket);
 




More information about the linux-pcmcia mailing list