[USBDRIVER]

- Fix an off-by-one error in the probing code
- Scan all PCI buses instead of just the first two
- Fix a horrible bug that resulted in reinitializing EHCI controllers as UHCI controllers which caused a crash on VirtualBox (with _MULTI_UHCI)
- Implement support for multiple EHCI controllers and enable support for multiple UHCI controllers (greatly increases compatibility with real hardware because the first controller detected is often internal)

svn path=/trunk/; revision=47136
This commit is contained in:
Cameron Gutman 2010-05-08 21:53:57 +00:00
parent 438916ee96
commit 1bd675f802
3 changed files with 29 additions and 19 deletions

View file

@ -3461,18 +3461,19 @@ ehci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER d
PDEVICE_OBJECT pdev; PDEVICE_OBJECT pdev;
BYTE buffer[sizeof(PCI_COMMON_CONFIG)]; BYTE buffer[sizeof(PCI_COMMON_CONFIG)];
PEHCI_DEVICE_EXTENSION pdev_ext; PEHCI_DEVICE_EXTENSION pdev_ext;
LONG count = 0;
slot_num.u.AsULONG = 0; slot_num.u.AsULONG = 0;
pci_config = (PPCI_COMMON_CONFIG) buffer; pci_config = (PPCI_COMMON_CONFIG) buffer;
pdev = NULL; pdev = NULL;
//scan the bus to find ehci controller //scan the PCI buses to find ehci controller
for(bus = 0; bus < 3; bus++) /* enum bus0-bus2 */ for (bus = 0; bus <= PCI_MAX_BRIDGE_NUMBER; bus++) //Yes, it should be <=
{ {
for(i = 0; i < PCI_MAX_DEVICES; i++) for(i = 0; i <= PCI_MAX_DEVICES; i++)
{ {
slot_num.u.bits.DeviceNumber = i; slot_num.u.bits.DeviceNumber = i;
for(j = 0; j < PCI_MAX_FUNCTIONS; j++) for(j = 0; j <= PCI_MAX_FUNCTION; j++)
{ {
slot_num.u.bits.FunctionNumber = j; slot_num.u.bits.FunctionNumber = j;
@ -3490,9 +3491,12 @@ ehci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER d
{ {
//well, we find our usb host controller( EHCI ), create device //well, we find our usb host controller( EHCI ), create device
pdev = ehci_alloc(drvr_obj, reg_path, ((bus << 8) | (i << 3) | j), dev_mgr); pdev = ehci_alloc(drvr_obj, reg_path, ((bus << 8) | (i << 3) | j), dev_mgr);
if (pdev)
if (!pdev) #ifdef _MULTI_EHCI
continue; count++;
#else
goto LBL_LOOPOUT;
#endif
} }
} }
@ -3501,6 +3505,11 @@ ehci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER d
} }
} }
#ifndef _MULTI_EHCI
LBL_LOOPOUT:
#endif
DbgPrint("Found %d EHCI controllers\n", count);
if (pdev) if (pdev)
{ {
pdev_ext = pdev->DeviceExtension; pdev_ext = pdev->DeviceExtension;

View file

@ -626,13 +626,13 @@ uhci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER d
count = 0; count = 0;
pdev = NULL; pdev = NULL;
//scan the bus to find uhci controller //scan the PCI buses to find uhci controller
for(bus = 0; bus < 3; bus++) /* enum bus0-bus2 */ for (bus = 0; bus <= PCI_MAX_BRIDGE_NUMBER; bus++)
{ {
for(i = 0; i < PCI_MAX_DEVICES; i++) for(i = 0; i <= PCI_MAX_DEVICES; i++)
{ {
slot_num.u.bits.DeviceNumber = i; slot_num.u.bits.DeviceNumber = i;
for(j = 0; j < PCI_MAX_FUNCTIONS; j++) for(j = 0; j <= PCI_MAX_FUNCTION; j++)
{ {
slot_num.u.bits.FunctionNumber = j; slot_num.u.bits.FunctionNumber = j;
@ -645,18 +645,15 @@ uhci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER d
if (ret == 2) /*no device on the slot */ if (ret == 2) /*no device on the slot */
break; break;
if (pci_config->BaseClass == 0x0c && pci_config->SubClass == 0x03) if (pci_config->BaseClass == 0x0c && pci_config->SubClass == 0x03 &&
pci_config->ProgIf == 0x00)
{ {
// well, we find our usb host controller, create device // well, we find our usb host controller, create device
#ifdef _MULTI_UHCI
{
pdev = uhci_alloc(drvr_obj, reg_path, ((bus << 8) | (i << 3) | j), dev_mgr);
if (pdev)
count++;
}
#else
pdev = uhci_alloc(drvr_obj, reg_path, ((bus << 8) | (i << 3) | j), dev_mgr); pdev = uhci_alloc(drvr_obj, reg_path, ((bus << 8) | (i << 3) | j), dev_mgr);
if (pdev) if (pdev)
#ifdef _MULTI_UHCI
count++;
#else
goto LBL_LOOPOUT; goto LBL_LOOPOUT;
#endif #endif
} }
@ -669,6 +666,8 @@ uhci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUSB_DEV_MANAGER d
#ifndef _MULTI_UHCI #ifndef _MULTI_UHCI
LBL_LOOPOUT: LBL_LOOPOUT:
#endif #endif
DbgPrint("Found %d UHCI controllers\n", count);
if (pdev) if (pdev)
{ {
pdev_ext = pdev->DeviceExtension; pdev_ext = pdev->DeviceExtension;

View file

@ -2,6 +2,8 @@
<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd"> <!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
<module name="usbdriver" type="kernelmodedriver" installbase="system32/drivers" installname="usbdriver.sys"> <module name="usbdriver" type="kernelmodedriver" installbase="system32/drivers" installname="usbdriver.sys">
<define name="INCLUDE_EHCI" /> <define name="INCLUDE_EHCI" />
<define name="_MULTI_UHCI" />
<define name="_MULTI_EHCI" />
<define name="_X86" /> <define name="_X86" />
<include base="usbdriver">.</include> <include base="usbdriver">.</include>
<library>ntoskrnl</library> <library>ntoskrnl</library>