On 03/28/00 Jim Segrave wrote:
> > It wasn't that simple. The PnP / PCI enumeration needs to be done
> > completely by the running OS to make things work.
> > 
> > But I thought that Linux did do PnP / PCI enumeration ? In that case a
> > interrupt should be assigned.
> 
> Well - I stuck some printk's in to see what was happening.
> When pci.c starts up, if finds the USB controller. The interrupt
> pin register is set to 4, the interrupt line register is set to
> 0xff. 

I had almost the same problem with my laptop.
I found some code snippets on a japanese site, put them toghether,
shaked and made them to work. You may find them useful and a
real kernel hacker could make them fit in the kernel tree.
The problem is that the USB controller is not fully initialized by
the BIOS. some BIOSes have an option for enabling the USB
controller, but mine didn't.
The module works with 2.2.14, may need porting to 2.3.x.

lupus

-- 
Paolo Molaro, Open Source Developer, Linuxcare, Inc.
+39.049.8043420 tel, +39.049.8043412 fax
[EMAIL PROTECTED], http://www.linuxcare.com/
Linuxcare. Support for the revolution.
INCLUDEDIR=/usr/include

CFLAGS= -D__KERNEL__ -DMODULE -O -Wall -I$(INCLUDEDIR)

usb-fix.o: usb-fix.c Makefile


#include <asm/io.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/pci.h>

int init_module (void) {
  struct pci_dev *dev=NULL;

  u8 route;
  u8 elcr2, type;
  int count=0;

  while ( (dev = pci_find_device( PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, dev)) ) {
    printk("found PCI 82371AB-0 \n");
	++count;
    pci_read_config_byte(dev, 0x63, &route); /* Get Routing of PIRQD */
    if ( route==0x80 ) { /* 80H=Routing disable */
      route = 0x09;
      pci_write_config_byte(dev, 0x63, route);
      pci_read_config_byte(dev, 0x63, &route);
      printk(" PIRQD route : %x \n", route);
    }
  }
  if (!count) {
	printk("no device found\n");
	return 0;
  }

  elcr2 = inb(0x4d1);   /* Port 0x4d1 : Edge/Level Control Register */
  printk(" ELCR2 : %0x ", elcr2);
  switch ( route ) {
    case 0x09 : elcr2 |= 0x02; break;
    case 0x0a : elcr2 |= 0x04; break;
    case 0x0b : elcr2 |= 0x08; break;
    case 0x0c : elcr2 |= 0x10; break;
    case 0x0e : elcr2 |= 0x40; break;
    case 0x0f : elcr2 |= 0x80; break;
  }
  outb(elcr2, 0x4d1);
  printk("-> %0x\n", elcr2);

  
  dev=NULL;
  for(;;) {
	dev = pci_find_class(PCI_CLASS_SERIAL_USB << 8, dev);
	if (!dev)
			break;
	pci_read_config_byte(dev, PCI_CLASS_PROG, &type);
	if (type != 0)
			continue;
    /* Allocate IRQ to USB Controller */
        if ( dev->device == PCI_DEVICE_ID_INTEL_82371AB_2 ) {
		  printk("Found USB with irq %d\n", dev->irq);
		  if (dev->irq != route) {
			printk("USB ir set to %d from %d\n", route, dev->irq);
      			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, route);
		  	dev->irq = route;
		  }
	}
  }
  return 0;
}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to