diff options
| -rw-r--r-- | drivers/usb/host/ehci-pci.c | 41 | 
1 files changed, 40 insertions, 1 deletions
| diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 29af02dc5..001d141e0 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -19,6 +19,7 @@   */  #include <common.h> +#include <errno.h>  #include <pci.h>  #include <usb.h> @@ -32,6 +33,35 @@ static struct pci_device_id ehci_pci_ids[] = {  	{0x12D8, 0x400F},	/* Pericom */  	{0, 0}  }; +#else +static pci_dev_t ehci_find_class(void) +{ +	int bus; +	int devnum; +	pci_dev_t bdf; +	uint32_t class; + +	for (bus = 0; bus <= pci_last_busno(); bus++) { +		for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES-1; devnum++) { +			pci_read_config_dword(PCI_BDF(bus, devnum, 0), +					      PCI_CLASS_REVISION, &class); +			if (class >> 16 == 0xffff) +				continue; + +			for (bdf = PCI_BDF(bus, devnum, 0); +					bdf <= PCI_BDF(bus, devnum, +						PCI_MAX_PCI_FUNCTIONS - 1); +					bdf += PCI_BDF(0, 0, 1)) { +				pci_read_config_dword(bdf, PCI_CLASS_REVISION, +						      &class); +				if (class >> 8 == PCI_CLASS_SERIAL_USB_EHCI) +					return bdf; +			} +		} +	} + +	return -ENODEV; +}  #endif  /* @@ -41,9 +71,14 @@ static struct pci_device_id ehci_pci_ids[] = {  int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)  {  	pci_dev_t pdev; +	uint32_t cmd; +#ifdef CONFIG_PCI_EHCI_DEVICE  	pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE); -	if (pdev == -1) { +#else +	pdev = ehci_find_class(); +#endif +	if (pdev < 0) {  		printf("EHCI host controller not found\n");  		return -1;  	} @@ -57,6 +92,10 @@ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)  			(uint32_t)*hccr, (uint32_t)*hcor,  			(uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); +	/* enable busmaster */ +	pci_read_config_dword(pdev, PCI_COMMAND, &cmd); +	cmd |= PCI_COMMAND_MASTER; +	pci_write_config_dword(pdev, PCI_COMMAND, cmd);  	return 0;  } |