[PATCH] Fallback to PCI IRQs for TI bridges

Tim Small tim_small at yahoo.com
Tue May 13 02:24:41 BST 2003


Pavel Roskin wrote:

>>https://sourceforge.net/forum/forum.php?thread_id=863984&forum_id=43629
>>    
>>
>
>OK, my understanding is that your patch may be correct.  I'm not
>familiar with the internals of PCI implementation to judge.  However, it
>may happen that you only need pci_read_irq(dev) and nothing else.  You may
>want the attached patch that is less intrusive in terms of affected
>devices (as opposed to affected lines of code).
>  
>
OK, a couple of quick questions...  Why would you want to do these 
things for a PCI<->Cardbus bridge, but not for a PCI <-> PCMCIA bridge?  
In fact, I'm not very sure what the first line does at all, but I assume 
the second two lines are needed to populate the device structure with 
the codes that would be used by device drivers to search for the device 
(and /proc/pci etc.).  I'm pretty much stabbing around in the dark at 
the moment, so any explanation would be helpful ;-)..

+			pci_read_bases(dev, 1, 0);
+			pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
+			pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);



>>I'm referring back to this thread:
>>
>>http://lists.insecure.org/lists/linux-kernel/2003/Mar/0012.html
>>    
>>
>
>My patch may be needed as well, but it does a different thing - it
>reprograms bridge-specific registers to use PCI IRQ is ISA IRQ wasn't
>found.  Your patch fixes finding PCI IRQ for certain devices.
>  
>
Yep - there are two ways to wire up the interupt pins for this chip, you 
can either wire pins to the ISA IRQ lines, or wire (some of the same) 
pins to the PCI INTA, and INTB lines.  Since this card is a PCI slot 
device, it is wired up in the second way.  The pin outputs are 
switchable in software by programming some of the bridge registers.

I've just found this FreeBSD code - search for "pcic_pci_ti113x_func" in 
http://gatekeeper.dec.com/pub/BSD/FreeBSD/FreeBSD-stable/src/sys/pccard/pcic_pci.c

>My TI and Ricoh cards are listed as "CardBus bridge", so they have their
>IRQs determined from the PCI config space (if I understand the whole
>situation correctly).
>
>Your card identifies itself as a PCMCIA bridge, so
>the kernel doesn't know its PCI IRQ.  Reprogramming the bridge registers
>would be insufficient in this case.
>  
>
Hmm, where do the two IRQs (10, and 12) come from?  I was assuming the 
PCI setup code (BIOS or kernel) is setting up routing of the INT lines 
from the PCI slot to these IRQs?  I think the problem is that the 
chipset also has to be set up to deliver interrupts to the INT lines (as 
in above FreeBSD code), as I think this is how my particular card is 
wired up (rather than using IRQSER to deliver ISA IRQs over a PCI slot), 
not completely sure about that, but it would tie in with the behaviour I 
am seeing, and the w2k problem here:

http://support.microsoft.com/default.aspx?scid=kb;en-us;257458

>I don't see corresponding code in drivers/pci/pci.c in Linux 2.5.69.  It
>may happen that it will work for you without changes.
>  
>
I haven't tried 2.5.69 yet.  I will try this, and a bit more code 
hacking tomorrow, and I'll have a read of the 1131 datasheet to see how 
the 1031 differs.  Here are some docs, but I haven't had a chance to 
have a close look yet..

http://www-s.ti.com/sc/ds/pci1031.pdf   (datasheet)

http://www-s.ti.com/sc/ds/pci1131.pdf  (datasheet)

http://www-s.ti.com/sc/psheets/scpa007/scpa007.pdf  (1131 interrupt app 
note)


So I think I have to:

. Work out how to read/write the relevant registers to set up the IRQ 
routing.
.  See if there is some way to probe which interrupt scheme is being 
used, otherwise add the different schemes as a module option.

Does this sound sane?  Is there some way to get a yenta so generate a 
'test' interrupt, I wonder?


Thanks for the input!

Tim.

>------------------------------------------------------------------------
>
>--- linux.orig/drivers/pci/pci.c
>+++ linux/drivers/pci/pci.c
>@@ -1405,12 +1405,17 @@ int pci_setup_device(struct pci_dev * de
> 		break;
> 
> 	case PCI_HEADER_TYPE_CARDBUS:		    /* CardBus bridge header */
>-		if (class != PCI_CLASS_BRIDGE_CARDBUS)
>+		switch (class) {
>+		case PCI_CLASS_BRIDGE_CARDBUS:
>+			pci_read_bases(dev, 1, 0);
>+			pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
>+			pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
>+			/* fallthrough */
>+		case PCI_CLASS_BRIDGE_PCMCIA:
>+			pci_read_irq(dev);
>+		default:
> 			goto bad;
>-		pci_read_irq(dev);
>-		pci_read_bases(dev, 1, 0);
>-		pci_read_config_word(dev, PCI_CB_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
>-		pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
>+		}
> 		break;
> 
> 	default:				    /* unknown header */
>  
>





More information about the linux-pcmcia mailing list