2010-02-10 12:21:23 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* FILE: drivers/usb/usbehci/usbiffn.c
|
|
|
|
* PURPOSE: Direct Call Interface Functions.
|
|
|
|
* PROGRAMMERS:
|
2010-09-15 13:16:59 +00:00
|
|
|
* Michael Martin (michael.martin@reactos.org)
|
2010-02-10 12:21:23 +00:00
|
|
|
*/
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
/* Many of these direct calls are documented on http://www.osronline.com */
|
|
|
|
|
2010-02-10 12:21:23 +00:00
|
|
|
#include "usbehci.h"
|
2010-04-05 12:23:30 +00:00
|
|
|
#include <hubbusif.h>
|
|
|
|
#include <usbbusif.h>
|
2011-04-13 04:43:25 +00:00
|
|
|
#include "hardware.h"
|
2011-01-01 12:20:19 +00:00
|
|
|
#include "transfer.h"
|
2010-04-14 14:46:10 +00:00
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
PVOID InternalCreateUsbDevice(ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub)
|
2010-04-14 14:46:10 +00:00
|
|
|
{
|
|
|
|
PUSB_DEVICE UsbDevicePointer = NULL;
|
2010-09-05 18:43:17 +00:00
|
|
|
|
2010-04-14 14:46:10 +00:00
|
|
|
UsbDevicePointer = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEVICE), USB_POOL_TAG);
|
|
|
|
|
|
|
|
if (!UsbDevicePointer)
|
|
|
|
{
|
|
|
|
DPRINT1("Out of memory\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
RtlZeroMemory(UsbDevicePointer, sizeof(USB_DEVICE));
|
|
|
|
|
|
|
|
if ((Hub) && (!Parent))
|
|
|
|
{
|
|
|
|
DPRINT1("This is the root hub\n");
|
|
|
|
}
|
|
|
|
|
2011-01-01 12:20:19 +00:00
|
|
|
UsbDevicePointer->Port = Port - 1;
|
2010-04-14 14:46:10 +00:00
|
|
|
UsbDevicePointer->ParentDevice = Parent;
|
|
|
|
|
|
|
|
UsbDevicePointer->IsHub = Hub;
|
|
|
|
|
|
|
|
return UsbDevicePointer;
|
|
|
|
}
|
2010-02-10 12:21:23 +00:00
|
|
|
|
|
|
|
VOID
|
|
|
|
USB_BUSIFFN
|
|
|
|
InterfaceReference(PVOID BusContext)
|
|
|
|
{
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: InterfaceReference called\n");
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
USB_BUSIFFN
|
|
|
|
InterfaceDereference(PVOID BusContext)
|
|
|
|
{
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: InterfaceDereference called\n");
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Bus Interface Hub V5 Functions */
|
|
|
|
|
2011-01-01 12:20:19 +00:00
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
/* Hub Driver calls this routine for each new device it is informed about on USB Bus
|
|
|
|
osronline documents that this is where the device address is assigned. It also
|
|
|
|
states the same for InitializeUsbDevice. This function only gets the device descriptor
|
|
|
|
from the device and checks that the members for device are correct. */
|
|
|
|
|
2010-02-10 12:21:23 +00:00
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
CreateUsbDevice(PVOID BusContext,
|
|
|
|
PUSB_DEVICE_HANDLE *NewDevice,
|
|
|
|
PUSB_DEVICE_HANDLE HubDeviceHandle,
|
|
|
|
USHORT PortStatus, USHORT PortNumber)
|
|
|
|
{
|
2010-04-14 14:46:10 +00:00
|
|
|
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
2011-04-13 04:43:25 +00:00
|
|
|
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
|
|
|
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
|
|
|
PEHCI_HOST_CONTROLLER hcd;
|
2010-04-14 14:46:10 +00:00
|
|
|
PUSB_DEVICE UsbDevice;
|
2011-04-13 04:43:25 +00:00
|
|
|
LONG i;
|
2011-01-01 12:20:19 +00:00
|
|
|
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: CreateUsbDevice: HubDeviceHandle %x, PortStatus %x, PortNumber %x\n", HubDeviceHandle, PortStatus, PortNumber);
|
2011-04-13 04:43:25 +00:00
|
|
|
|
|
|
|
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
|
|
|
|
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
|
|
|
|
|
|
|
|
hcd = &FdoDeviceExtension->hcd;
|
2010-07-06 12:02:33 +00:00
|
|
|
|
|
|
|
if (PdoDeviceExtension->UsbDevices[0] != HubDeviceHandle)
|
|
|
|
{
|
|
|
|
DPRINT1("Not a valid HubDeviceHandle\n");
|
|
|
|
return STATUS_DEVICE_NOT_CONNECTED;
|
|
|
|
}
|
2010-04-07 10:25:36 +00:00
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
UsbDevice = NULL;
|
2010-04-14 14:46:10 +00:00
|
|
|
/* Add it to the list */
|
2011-04-13 04:43:25 +00:00
|
|
|
for (i=0; i < MAX_USB_DEVICES; i++)
|
2010-04-14 14:46:10 +00:00
|
|
|
{
|
|
|
|
if (PdoDeviceExtension->UsbDevices[i] == NULL)
|
|
|
|
{
|
2011-04-13 04:43:25 +00:00
|
|
|
PdoDeviceExtension->UsbDevices[i] = InternalCreateUsbDevice(PortNumber, HubDeviceHandle, FALSE);
|
|
|
|
|
|
|
|
if (!PdoDeviceExtension->UsbDevices[i])
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
UsbDevice = PdoDeviceExtension->UsbDevices[i];
|
2010-07-03 11:40:58 +00:00
|
|
|
break;
|
2010-04-14 14:46:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
/* Check that a device was created */
|
|
|
|
if (!UsbDevice)
|
|
|
|
{
|
|
|
|
DPRINT1("Too many usb devices attached. Max is %d\n", MAX_USB_DEVICES);
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
hcd->Ports[PortNumber - 1].PortStatus = PortStatus;
|
|
|
|
|
|
|
|
/* Get the device descriptor */
|
|
|
|
CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
|
|
|
CtrlSetup.wValue.LowByte = 0;
|
|
|
|
CtrlSetup.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE;
|
|
|
|
CtrlSetup.wIndex.W = 0;
|
|
|
|
CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR);
|
|
|
|
CtrlSetup.bmRequestType.B = 0x80;
|
|
|
|
ExecuteTransfer(FdoDeviceExtension->DeviceObject,
|
|
|
|
UsbDevice,
|
|
|
|
0,
|
|
|
|
&CtrlSetup,
|
|
|
|
0,
|
|
|
|
&UsbDevice->DeviceDescriptor,
|
|
|
|
sizeof(USB_DEVICE_DESCRIPTOR),
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* Check status and bLength and bDescriptor members */
|
|
|
|
if ((UsbDevice->DeviceDescriptor.bLength != 0x12) || (UsbDevice->DeviceDescriptor.bDescriptorType != 0x1))
|
|
|
|
{
|
|
|
|
return STATUS_DEVICE_DATA_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
DumpDeviceDescriptor(&UsbDevice->DeviceDescriptor);
|
2010-07-03 11:40:58 +00:00
|
|
|
|
2010-04-14 14:46:10 +00:00
|
|
|
/* Return it */
|
|
|
|
*NewDevice = UsbDevice;
|
2010-02-10 12:21:23 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
/* Assigns the device an address, gets the configuration, interface, and endpoint descriptors
|
|
|
|
from the device. All this data is saved as part of this driver */
|
|
|
|
|
2010-02-10 12:21:23 +00:00
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
|
|
|
|
{
|
2010-04-05 12:23:30 +00:00
|
|
|
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
2010-04-14 14:46:10 +00:00
|
|
|
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
|
|
|
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
2011-04-13 04:43:25 +00:00
|
|
|
USB_DEVICE_DESCRIPTOR DeviceDesc;
|
2010-04-14 14:46:10 +00:00
|
|
|
PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc;
|
|
|
|
PUSB_INTERFACE_DESCRIPTOR InterfaceDesc;
|
|
|
|
PUSB_ENDPOINT_DESCRIPTOR EndpointDesc;
|
|
|
|
PUSB_DEVICE UsbDevice;
|
|
|
|
PVOID Buffer;
|
|
|
|
PUCHAR Ptr;
|
2011-04-13 04:43:25 +00:00
|
|
|
UCHAR NewAddress = 0;
|
|
|
|
|
|
|
|
LONG i, j, k, InitAttept;
|
2010-04-14 14:46:10 +00:00
|
|
|
|
2010-04-05 12:23:30 +00:00
|
|
|
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
|
2010-04-14 14:46:10 +00:00
|
|
|
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
|
2010-07-06 12:02:33 +00:00
|
|
|
|
|
|
|
UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
|
|
|
|
|
|
|
|
if (!UsbDevice)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid DeviceHandle or device not connected\n");
|
|
|
|
return STATUS_DEVICE_NOT_CONNECTED;
|
|
|
|
}
|
2010-04-14 14:46:10 +00:00
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
for (i=0; i<127; i++)
|
|
|
|
{
|
|
|
|
if (UsbDevice == PdoDeviceExtension->UsbDevices[i])
|
|
|
|
{
|
|
|
|
NewAddress = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT(NewAddress);
|
|
|
|
|
|
|
|
/* Linux drivers make 3 attemps to set the device address because of problems with some devices. Do the same */
|
|
|
|
InitAttept = 0;
|
|
|
|
while (InitAttept < 3)
|
|
|
|
{
|
|
|
|
/* Set the device address */
|
|
|
|
CtrlSetup.bmRequestType.B = 0x00;
|
|
|
|
CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS;
|
|
|
|
CtrlSetup.wValue.W = NewAddress;
|
|
|
|
CtrlSetup.wIndex.W = 0;
|
|
|
|
CtrlSetup.wLength = 0;
|
2011-01-06 17:46:59 +00:00
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
DPRINT1("Setting Address to %x\n", NewAddress);
|
|
|
|
ExecuteTransfer(PdoDeviceExtension->ControllerFdo,
|
|
|
|
UsbDevice,
|
|
|
|
0,
|
|
|
|
&CtrlSetup,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL);
|
2011-01-06 17:46:59 +00:00
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
KeStallExecutionProcessor(300 * InitAttept);
|
|
|
|
|
|
|
|
/* Send 0 length packet to endpoint 0 for ack */
|
|
|
|
/*
|
|
|
|
ExecuteTransfer(PdoDeviceExtension->ControllerFdo,
|
|
|
|
UsbDevice,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
*/
|
2011-01-06 17:46:59 +00:00
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
|
|
|
CtrlSetup.wValue.LowByte = 0;
|
|
|
|
CtrlSetup.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE;
|
|
|
|
CtrlSetup.wIndex.W = 0;
|
|
|
|
CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR);
|
|
|
|
CtrlSetup.bmRequestType.B = 0x80;
|
|
|
|
|
|
|
|
UsbDevice->Address = NewAddress;
|
|
|
|
ExecuteTransfer(FdoDeviceExtension->DeviceObject,
|
|
|
|
UsbDevice,
|
|
|
|
0,
|
|
|
|
&CtrlSetup,
|
|
|
|
0,
|
|
|
|
&DeviceDesc,
|
|
|
|
sizeof(USB_DEVICE_DESCRIPTOR),
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
DPRINT1("Length %d, DescriptorType %d\n", DeviceDesc.bLength, DeviceDesc.bDescriptorType);
|
|
|
|
if ((DeviceDesc.bLength == 0x12) && (DeviceDesc.bDescriptorType == 0x01))
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* If the descriptor was not gotten */
|
|
|
|
UsbDevice->Address = 0;
|
|
|
|
InitAttept++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (InitAttept == 3)
|
2011-01-01 12:20:19 +00:00
|
|
|
{
|
2011-04-13 04:43:25 +00:00
|
|
|
DPRINT1("Unable to initialize usb device connected on port %d!\n", UsbDevice->Port);
|
|
|
|
/* FIXME: Should the memory allocated for this device be deleted? */
|
2011-01-01 12:20:19 +00:00
|
|
|
return STATUS_DEVICE_DATA_ERROR;
|
|
|
|
}
|
2011-04-13 04:43:25 +00:00
|
|
|
DumpDeviceDescriptor(&DeviceDesc);
|
2011-01-06 17:46:59 +00:00
|
|
|
|
2010-04-14 14:46:10 +00:00
|
|
|
if (UsbDevice->DeviceDescriptor.bNumConfigurations == 0)
|
2010-07-06 12:02:33 +00:00
|
|
|
{
|
2011-01-01 12:20:19 +00:00
|
|
|
DPRINT1("Device on port %d has no configurations!\n", UsbDevice->Port);
|
2011-04-13 04:43:25 +00:00
|
|
|
/* FIXME: Should the memory allocated for this device be deleted? */
|
2010-04-14 14:46:10 +00:00
|
|
|
return STATUS_DEVICE_DATA_ERROR;
|
2010-07-06 12:02:33 +00:00
|
|
|
}
|
2010-04-14 14:46:10 +00:00
|
|
|
UsbDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
|
|
|
|
sizeof(PVOID) * UsbDevice->DeviceDescriptor.bNumConfigurations,
|
|
|
|
USB_POOL_TAG);
|
|
|
|
|
|
|
|
if (!UsbDevice->Configs)
|
2010-04-05 12:23:30 +00:00
|
|
|
{
|
2010-04-14 14:46:10 +00:00
|
|
|
DPRINT1("Out of memory\n");
|
2011-04-13 04:43:25 +00:00
|
|
|
/* FIXME: Should the memory allocated for this device be deleted? */
|
2010-04-14 14:46:10 +00:00
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
2011-01-01 12:20:19 +00:00
|
|
|
Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, USB_POOL_TAG);
|
|
|
|
|
|
|
|
if (!Buffer)
|
|
|
|
{
|
|
|
|
DPRINT1("Out of memory\n");
|
2011-04-13 04:43:25 +00:00
|
|
|
/* FIXME: Should the memory allocated for this device be deleted? */
|
2011-01-01 12:20:19 +00:00
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ptr = Buffer;
|
2011-01-06 17:46:59 +00:00
|
|
|
|
2010-04-14 14:46:10 +00:00
|
|
|
for (i = 0; i < UsbDevice->DeviceDescriptor.bNumConfigurations; i++)
|
|
|
|
{
|
|
|
|
/* Get the Device Configuration Descriptor */
|
|
|
|
CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
|
|
|
|
CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
|
2011-01-01 12:20:19 +00:00
|
|
|
CtrlSetup.bmRequestType._BM.Reserved = 0;
|
2010-04-14 14:46:10 +00:00
|
|
|
CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
|
|
|
|
CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
|
|
|
CtrlSetup.wValue.LowByte = 0;
|
|
|
|
CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE;
|
|
|
|
CtrlSetup.wIndex.W = 0;
|
|
|
|
CtrlSetup.wLength = PAGE_SIZE;
|
2011-04-13 04:43:25 +00:00
|
|
|
ExecuteTransfer(PdoDeviceExtension->ControllerFdo,
|
|
|
|
UsbDevice,
|
|
|
|
0,
|
|
|
|
&CtrlSetup,
|
|
|
|
0,
|
|
|
|
Buffer,
|
|
|
|
PAGE_SIZE,
|
|
|
|
NULL);
|
2010-04-14 14:46:10 +00:00
|
|
|
|
|
|
|
ConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)Ptr;
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
DumpFullConfigurationDescriptor(ConfigDesc);
|
2010-04-14 14:46:10 +00:00
|
|
|
ASSERT(ConfigDesc->wTotalLength <= PAGE_SIZE);
|
|
|
|
|
|
|
|
UsbDevice->Configs[i] = ExAllocatePoolWithTag(NonPagedPool,
|
|
|
|
sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ConfigDesc->bNumInterfaces,
|
|
|
|
USB_POOL_TAG);
|
|
|
|
UsbDevice->Configs[i]->Device = UsbDevice;
|
2010-09-05 18:43:17 +00:00
|
|
|
|
2010-04-14 14:46:10 +00:00
|
|
|
RtlCopyMemory(&UsbDevice->Configs[0]->ConfigurationDescriptor,
|
|
|
|
ConfigDesc, sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
|
|
|
Ptr += ConfigDesc->bLength;
|
|
|
|
|
|
|
|
for (j = 0; j < ConfigDesc->bNumInterfaces; j++)
|
2010-04-05 12:23:30 +00:00
|
|
|
{
|
2010-04-14 14:46:10 +00:00
|
|
|
InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) Ptr;
|
|
|
|
UsbDevice->Configs[i]->Interfaces[j] = ExAllocatePoolWithTag(NonPagedPool,
|
|
|
|
sizeof(USB_INTERFACE) + sizeof(PVOID) * InterfaceDesc->bNumEndpoints,
|
|
|
|
USB_POOL_TAG);
|
|
|
|
RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->InterfaceDescriptor,
|
|
|
|
InterfaceDesc,
|
|
|
|
sizeof(USB_INTERFACE_DESCRIPTOR));
|
|
|
|
|
|
|
|
Ptr += InterfaceDesc->bLength;
|
|
|
|
|
|
|
|
for (k = 0; k < InterfaceDesc->bNumEndpoints; k++)
|
|
|
|
{
|
|
|
|
EndpointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Ptr;
|
|
|
|
UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k] = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_ENDPOINT), USB_POOL_TAG);
|
|
|
|
RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k]->EndPointDescriptor,
|
|
|
|
EndpointDesc, sizeof(USB_ENDPOINT_DESCRIPTOR));
|
2011-01-06 17:46:59 +00:00
|
|
|
Ptr += sizeof(USB_ENDPOINT_DESCRIPTOR);
|
2010-04-14 14:46:10 +00:00
|
|
|
}
|
2010-04-05 12:23:30 +00:00
|
|
|
}
|
|
|
|
}
|
2010-04-14 14:46:10 +00:00
|
|
|
|
|
|
|
UsbDevice->ActiveConfig = UsbDevice->Configs[0];
|
|
|
|
UsbDevice->ActiveInterface = UsbDevice->Configs[0]->Interfaces[0];
|
2011-01-01 12:20:19 +00:00
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
UsbDevice->DeviceState = DEVICEINTIALIZED;
|
2011-01-06 17:46:59 +00:00
|
|
|
|
2011-01-01 12:20:19 +00:00
|
|
|
return STATUS_SUCCESS;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
/* Return the descriptors that will fit. Descriptors were saved when the InitializeUsbDevice function was called */
|
2010-02-10 12:21:23 +00:00
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
GetUsbDescriptors(PVOID BusContext,
|
|
|
|
PUSB_DEVICE_HANDLE DeviceHandle,
|
|
|
|
PUCHAR DeviceDescriptorBuffer,
|
|
|
|
PULONG DeviceDescriptorBufferLength,
|
2010-04-14 14:46:10 +00:00
|
|
|
PUCHAR ConfigDescriptorBuffer,
|
2010-02-10 12:21:23 +00:00
|
|
|
PULONG ConfigDescriptorBufferLength)
|
|
|
|
{
|
2010-04-14 14:46:10 +00:00
|
|
|
PUSB_DEVICE UsbDevice;
|
2011-01-01 12:20:19 +00:00
|
|
|
DPRINT1("Ehci: GetUsbDescriptor %x, %x, %x, %x\n", DeviceDescriptorBuffer, *DeviceDescriptorBufferLength,
|
|
|
|
ConfigDescriptorBuffer, *ConfigDescriptorBufferLength);
|
2010-04-14 14:46:10 +00:00
|
|
|
|
2010-07-06 12:02:33 +00:00
|
|
|
UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
|
|
|
|
|
|
|
|
if (!UsbDevice)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid DeviceHandle or device not connected\n");
|
|
|
|
return STATUS_DEVICE_NOT_CONNECTED;
|
|
|
|
}
|
|
|
|
|
2010-04-14 14:46:10 +00:00
|
|
|
if ((DeviceDescriptorBuffer) && (DeviceDescriptorBufferLength))
|
|
|
|
{
|
|
|
|
RtlCopyMemory(DeviceDescriptorBuffer, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
|
|
|
|
*DeviceDescriptorBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
|
|
|
|
}
|
2010-09-05 18:43:17 +00:00
|
|
|
|
2010-04-14 14:46:10 +00:00
|
|
|
if ((ConfigDescriptorBuffer) && (ConfigDescriptorBufferLength))
|
|
|
|
{
|
|
|
|
RtlCopyMemory(ConfigDescriptorBuffer, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
|
|
|
*ConfigDescriptorBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
|
|
|
|
}
|
|
|
|
|
2010-02-10 12:21:23 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
/* Documented http://www.osronline.com/ddkx/buses/usbinterkr_1m7m.htm */
|
2010-02-10 12:21:23 +00:00
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
RemoveUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, ULONG Flags)
|
|
|
|
{
|
2010-07-03 11:40:58 +00:00
|
|
|
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
|
|
|
PUSB_DEVICE UsbDevice;
|
|
|
|
LONG i, j, k;
|
|
|
|
|
|
|
|
DPRINT1("RemoveUsbDevice called, DeviceHandle %x, Flags %x\n", DeviceHandle, Flags);
|
|
|
|
|
|
|
|
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
|
|
|
|
|
2010-07-06 12:02:33 +00:00
|
|
|
UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
|
2010-07-03 11:40:58 +00:00
|
|
|
|
2010-07-06 12:02:33 +00:00
|
|
|
if (!UsbDevice)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid DeviceHandle or device not connected\n");
|
2010-07-03 11:40:58 +00:00
|
|
|
return STATUS_DEVICE_NOT_CONNECTED;
|
2010-07-06 12:02:33 +00:00
|
|
|
}
|
2010-07-03 11:40:58 +00:00
|
|
|
|
|
|
|
switch (Flags)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
DPRINT1("Number of Configurations %d\n", UsbDevice->DeviceDescriptor.bNumConfigurations);
|
|
|
|
for (i = 0; i < UsbDevice->DeviceDescriptor.bNumConfigurations; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < UsbDevice->Configs[i]->ConfigurationDescriptor.bNumInterfaces; j++)
|
|
|
|
{
|
|
|
|
for (k = 0; k < UsbDevice->Configs[i]->Interfaces[j]->InterfaceDescriptor.bNumEndpoints; k++)
|
|
|
|
{
|
|
|
|
ExFreePool(UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k]);
|
|
|
|
}
|
|
|
|
ExFreePool(UsbDevice->Configs[i]->Interfaces[j]);
|
|
|
|
}
|
|
|
|
ExFreePool(UsbDevice->Configs[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < 127; i++)
|
|
|
|
{
|
|
|
|
if (PdoDeviceExtension->UsbDevices[i] == UsbDevice)
|
|
|
|
PdoDeviceExtension->UsbDevices[i] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ExFreePool(UsbDevice);
|
|
|
|
break;
|
|
|
|
case USBD_MARK_DEVICE_BUSY:
|
2011-01-06 17:46:59 +00:00
|
|
|
UsbDevice->DeviceState |= DEVICEBUSY;
|
|
|
|
/* Fall through */
|
|
|
|
case USBD_KEEP_DEVICE_DATA:
|
|
|
|
UsbDevice->DeviceState |= DEVICEREMOVED;
|
2010-07-03 11:40:58 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DPRINT1("Unknown Remove Flags %x\n", Flags);
|
|
|
|
}
|
2010-04-14 14:46:10 +00:00
|
|
|
return STATUS_SUCCESS;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
/* Documented at http://www.osronline.com/ddkx/buses/usbinterkr_01te.htm */
|
2010-02-10 12:21:23 +00:00
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
RestoreUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE OldDeviceHandle, PUSB_DEVICE_HANDLE NewDeviceHandle)
|
|
|
|
{
|
2011-01-06 17:46:59 +00:00
|
|
|
PUSB_DEVICE OldUsbDevice;
|
|
|
|
PUSB_DEVICE NewUsbDevice;
|
2011-04-13 04:43:25 +00:00
|
|
|
PUSB_CONFIGURATION ConfigToDelete;
|
|
|
|
int i;
|
2011-01-06 17:46:59 +00:00
|
|
|
|
|
|
|
DPRINT1("Ehci: RestoreUsbDevice %x, %x, %x\n", BusContext, OldDeviceHandle, NewDeviceHandle);
|
2011-04-13 04:43:25 +00:00
|
|
|
ASSERT(FALSE);
|
2011-01-06 17:46:59 +00:00
|
|
|
OldUsbDevice = DeviceHandleToUsbDevice(BusContext, OldDeviceHandle);
|
|
|
|
NewUsbDevice = DeviceHandleToUsbDevice(BusContext, NewDeviceHandle);
|
|
|
|
|
|
|
|
if (!OldUsbDevice)
|
|
|
|
{
|
|
|
|
DPRINT1("OldDeviceHandle is invalid\n");
|
|
|
|
return STATUS_DEVICE_NOT_CONNECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(OldUsbDevice->DeviceState & DEVICEREMOVED))
|
|
|
|
{
|
|
|
|
DPRINT1("UsbDevice is not marked as Removed!\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!NewUsbDevice)
|
|
|
|
{
|
|
|
|
DPRINT1("NewDeviceHandle is invalid\n");
|
|
|
|
return STATUS_DEVICE_NOT_CONNECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((OldUsbDevice->DeviceDescriptor.idVendor == NewUsbDevice->DeviceDescriptor.idVendor) &&
|
|
|
|
(OldUsbDevice->DeviceDescriptor.idProduct == NewUsbDevice->DeviceDescriptor.idProduct))
|
|
|
|
{
|
|
|
|
NewUsbDevice->DeviceState &= ~DEVICEBUSY;
|
|
|
|
NewUsbDevice->DeviceState &= ~DEVICEREMOVED;
|
|
|
|
|
|
|
|
NewUsbDevice->ActiveConfig = OldUsbDevice->ActiveConfig;
|
|
|
|
NewUsbDevice->ActiveInterface = OldUsbDevice->ActiveInterface;
|
|
|
|
|
|
|
|
for (i = 0; i < NewUsbDevice->DeviceDescriptor.bNumConfigurations; i++)
|
|
|
|
{
|
|
|
|
ConfigToDelete = NewUsbDevice->Configs[i];
|
|
|
|
ASSERT(OldUsbDevice->Configs[i]);
|
|
|
|
NewUsbDevice->Configs[i] = OldUsbDevice->Configs[i];
|
|
|
|
OldUsbDevice->Configs[i] = ConfigToDelete;
|
|
|
|
}
|
|
|
|
|
|
|
|
RemoveUsbDevice(BusContext, OldDeviceHandle, 0);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT1("VendorId or ProductId did not match!\n");
|
|
|
|
return STATUS_DEVICE_NOT_CONNECTED;
|
|
|
|
}
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
/* FIXME: Research this */
|
2010-02-10 12:21:23 +00:00
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
GetPortHackFlags(PVOID BusContext, PULONG Flags)
|
|
|
|
{
|
2011-01-01 12:20:19 +00:00
|
|
|
DPRINT1("Ehci: GetPortHackFlags not implemented. %x, %x\n", BusContext, Flags);
|
2010-04-07 10:25:36 +00:00
|
|
|
return STATUS_NOT_SUPPORTED;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
QueryDeviceInformation(PVOID BusContext,
|
|
|
|
PUSB_DEVICE_HANDLE DeviceHandle,
|
|
|
|
PVOID DeviceInformationBuffer,
|
|
|
|
ULONG DeviceInformationBufferLength,
|
|
|
|
PULONG LengthReturned)
|
|
|
|
{
|
2010-04-05 12:23:30 +00:00
|
|
|
PUSB_DEVICE_INFORMATION_0 DeviceInfo = DeviceInformationBuffer;
|
2010-07-06 12:02:33 +00:00
|
|
|
PUSB_DEVICE UsbDevice;
|
2010-04-05 12:23:30 +00:00
|
|
|
ULONG SizeNeeded;
|
|
|
|
LONG i;
|
|
|
|
|
2011-01-01 12:20:19 +00:00
|
|
|
DPRINT1("Ehci: QueryDeviceInformation (%x, %x, %x, %d, %x\n", BusContext, DeviceHandle, DeviceInformationBuffer,
|
|
|
|
DeviceInformationBufferLength, LengthReturned);
|
2010-04-05 12:23:30 +00:00
|
|
|
|
2010-07-06 12:02:33 +00:00
|
|
|
UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
|
|
|
|
|
|
|
|
if (!UsbDevice)
|
2010-04-05 12:23:30 +00:00
|
|
|
{
|
2010-07-06 12:02:33 +00:00
|
|
|
DPRINT1("Invalid DeviceHandle or device not connected\n");
|
|
|
|
return STATUS_DEVICE_NOT_CONNECTED;
|
2010-04-05 12:23:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SizeNeeded = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints]);
|
|
|
|
*LengthReturned = SizeNeeded;
|
|
|
|
|
|
|
|
DeviceInfo->ActualLength = SizeNeeded;
|
|
|
|
|
|
|
|
if (DeviceInformationBufferLength < SizeNeeded)
|
|
|
|
{
|
|
|
|
DPRINT1("Buffer to small\n");
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DeviceInfo->InformationLevel != 0)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid Param\n");
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2011-01-06 17:46:59 +00:00
|
|
|
DeviceInfo->HubAddress = 0;
|
2010-04-05 12:23:30 +00:00
|
|
|
DeviceInfo->DeviceAddress = UsbDevice->Address;
|
|
|
|
DeviceInfo->DeviceSpeed = UsbDevice->DeviceSpeed;
|
|
|
|
DeviceInfo->DeviceType = UsbDevice->DeviceType;
|
2011-01-06 17:46:59 +00:00
|
|
|
|
|
|
|
if (!UsbDevice->DeviceState)
|
|
|
|
{
|
|
|
|
DeviceInfo->CurrentConfigurationValue = 0;
|
|
|
|
DeviceInfo->NumberOfOpenPipes = 0;
|
|
|
|
DeviceInfo->PortNumber = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DeviceInfo->CurrentConfigurationValue = UsbDevice->ActiveConfig->ConfigurationDescriptor.bConfigurationValue;
|
|
|
|
/* FIXME: Use correct number of open pipes instead of all available */
|
|
|
|
DeviceInfo->NumberOfOpenPipes = UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints;
|
|
|
|
DeviceInfo->PortNumber = UsbDevice->Port;
|
|
|
|
}
|
2010-04-05 12:23:30 +00:00
|
|
|
|
|
|
|
RtlCopyMemory(&DeviceInfo->DeviceDescriptor, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
|
|
|
|
|
|
|
|
for (i = 0; i < UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints; i++)
|
|
|
|
{
|
2011-01-01 12:20:19 +00:00
|
|
|
RtlCopyMemory(&DeviceInfo->PipeList[i].EndpointDescriptor,
|
|
|
|
&UsbDevice->ActiveInterface->EndPoints[i]->EndPointDescriptor,
|
|
|
|
sizeof(USB_ENDPOINT_DESCRIPTOR));
|
2010-04-05 12:23:30 +00:00
|
|
|
}
|
2010-02-10 12:21:23 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
GetControllerInformation(PVOID BusContext,
|
|
|
|
PVOID ControllerInformationBuffer,
|
|
|
|
ULONG ControllerInformationBufferLength,
|
|
|
|
PULONG LengthReturned)
|
|
|
|
{
|
2010-04-05 12:23:30 +00:00
|
|
|
PUSB_CONTROLLER_INFORMATION_0 ControllerInfo;
|
|
|
|
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: GetControllerInformation called\n");
|
2010-04-14 14:46:10 +00:00
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
if (!LengthReturned)
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
2010-04-05 12:23:30 +00:00
|
|
|
ControllerInfo = ControllerInformationBuffer;
|
|
|
|
|
|
|
|
if (ControllerInformationBufferLength < sizeof(USB_CONTROLLER_INFORMATION_0))
|
|
|
|
{
|
|
|
|
DPRINT1("Buffer to small\n");
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ControllerInfo->InformationLevel != 0)
|
|
|
|
{
|
|
|
|
DPRINT1("InformationLevel other than 0 not supported\n");
|
|
|
|
return STATUS_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
ControllerInfo->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
|
|
|
|
ControllerInfo->SelectiveSuspendEnabled = FALSE;
|
|
|
|
ControllerInfo->IsHighSpeedController = TRUE;
|
|
|
|
|
|
|
|
*LengthReturned = ControllerInfo->ActualLength;
|
|
|
|
|
2010-02-10 12:21:23 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
ControllerSelectiveSuspend(PVOID BusContext, BOOLEAN Enable)
|
|
|
|
{
|
2011-01-01 12:20:19 +00:00
|
|
|
DPRINT1("Ehci: ControllerSelectiveSuspend not implemented\n");
|
2010-04-05 12:23:30 +00:00
|
|
|
return STATUS_NOT_SUPPORTED;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
GetExtendedHubInformation(PVOID BusContext,
|
|
|
|
PDEVICE_OBJECT HubPhysicalDeviceObject,
|
|
|
|
PVOID HubInformationBuffer,
|
|
|
|
ULONG HubInformationBufferLength,
|
|
|
|
PULONG LengthReturned)
|
|
|
|
{
|
|
|
|
|
|
|
|
PUSB_EXTHUB_INFORMATION_0 UsbExtHubInfo = HubInformationBuffer;
|
|
|
|
PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
|
|
|
|
PFDO_DEVICE_EXTENSION FdoDeviceExntension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
|
|
|
|
LONG i;
|
2011-01-01 12:20:19 +00:00
|
|
|
DPRINT1("Ehci: GetExtendedHubInformation BusContext %x, PDO %x, InformationBuffer %x\n",
|
|
|
|
BusContext, HubPhysicalDeviceObject, HubInformationBuffer);
|
|
|
|
|
2010-02-10 12:21:23 +00:00
|
|
|
/* Set the default return value */
|
|
|
|
*LengthReturned = 0;
|
2010-09-05 18:43:17 +00:00
|
|
|
|
2011-01-01 12:20:19 +00:00
|
|
|
DPRINT("InformationLevel %x\n", UsbExtHubInfo->InformationLevel);
|
2010-09-05 18:43:17 +00:00
|
|
|
|
|
|
|
/* Caller is suppose to have set InformationLevel to 0. However usbehci from MS seems to ignore this */
|
2010-02-10 12:21:23 +00:00
|
|
|
if (UsbExtHubInfo->InformationLevel != 0)
|
|
|
|
{
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("InformationLevel should really be set to 0. Ignoring\n");
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
2011-01-06 17:46:59 +00:00
|
|
|
UsbExtHubInfo->NumberOfPorts = FdoDeviceExntension->hcd.ECHICaps.HCSParams.PortCount;
|
2010-02-10 12:21:23 +00:00
|
|
|
|
|
|
|
for (i=0; i < UsbExtHubInfo->NumberOfPorts; i++)
|
|
|
|
{
|
|
|
|
UsbExtHubInfo->Port[i].PhysicalPortNumber = i + 1;
|
2011-01-06 17:46:59 +00:00
|
|
|
UsbExtHubInfo->Port[i].PortLabelNumber = i + 1;
|
2010-02-10 12:21:23 +00:00
|
|
|
UsbExtHubInfo->Port[i].VidOverride = 0;
|
|
|
|
UsbExtHubInfo->Port[i].PidOverride = 0;
|
2011-01-06 17:46:59 +00:00
|
|
|
UsbExtHubInfo->Port[i].PortAttributes = USB_PORTATTR_SHARED_USB2;// | USB_PORTATTR_OWNED_BY_CC;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*LengthReturned = FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
GetRootHubSymbolicName(PVOID BusContext,
|
|
|
|
PVOID HubSymNameBuffer,
|
|
|
|
ULONG HubSymNameBufferLength,
|
|
|
|
PULONG HubSymNameActualLength)
|
|
|
|
{
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: GetRootHubSymbolicName called\n");
|
2010-04-05 12:23:30 +00:00
|
|
|
|
2010-04-14 14:46:10 +00:00
|
|
|
if (HubSymNameBufferLength < 16)
|
2010-04-05 12:23:30 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
2010-04-14 14:46:10 +00:00
|
|
|
RtlCopyMemory(HubSymNameBuffer, L"ROOT_HUB", HubSymNameBufferLength);
|
|
|
|
*HubSymNameActualLength = 16;
|
2010-04-05 12:23:30 +00:00
|
|
|
|
2010-02-10 12:21:23 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
PVOID
|
|
|
|
USB_BUSIFFN
|
|
|
|
GetDeviceBusContext(PVOID HubBusContext, PVOID DeviceHandle)
|
|
|
|
{
|
2010-07-06 12:02:33 +00:00
|
|
|
PUSB_DEVICE UsbDevice;
|
|
|
|
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: GetDeviceBusContext called\n");
|
2010-07-06 12:02:33 +00:00
|
|
|
UsbDevice = DeviceHandleToUsbDevice(HubBusContext, DeviceHandle);
|
|
|
|
|
|
|
|
if (!UsbDevice)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid DeviceHandle or device not connected\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-02-10 12:21:23 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
Initialize20Hub(PVOID BusContext, PUSB_DEVICE_HANDLE HubDeviceHandle, ULONG TtCount)
|
|
|
|
{
|
2011-01-01 12:20:19 +00:00
|
|
|
DPRINT1("Ehci: Initialize20Hub called, HubDeviceHandle: %x, TtCount %x\n", HubDeviceHandle, TtCount);
|
2010-04-07 10:25:36 +00:00
|
|
|
/* FIXME: */
|
|
|
|
/* Create the Irp Queue for SCE */
|
|
|
|
/* Should queue be created for each device or each enpoint??? */
|
2010-02-10 12:21:23 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
RootHubInitNotification(PVOID BusContext, PVOID CallbackContext, PRH_INIT_CALLBACK CallbackRoutine)
|
|
|
|
{
|
2010-02-21 11:34:54 +00:00
|
|
|
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: RootHubInitNotification %x, %x, %x\n", BusContext, CallbackContext, CallbackRoutine);
|
2010-02-21 11:34:54 +00:00
|
|
|
|
2010-02-23 11:20:15 +00:00
|
|
|
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
|
2010-02-21 11:34:54 +00:00
|
|
|
PdoDeviceExtension->CallbackContext = CallbackContext;
|
|
|
|
PdoDeviceExtension->CallbackRoutine = CallbackRoutine;
|
2010-04-14 14:46:10 +00:00
|
|
|
if (PdoDeviceExtension->CallbackRoutine)
|
|
|
|
{
|
|
|
|
DPRINT1("Called Callbackrountine\n");
|
|
|
|
PdoDeviceExtension->CallbackRoutine(PdoDeviceExtension->CallbackContext);
|
|
|
|
DPRINT1("Done Callbackrountine\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT1("PdoDeviceExtension->CallbackRoutine is NULL!\n");
|
|
|
|
}
|
|
|
|
|
2010-02-10 12:21:23 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
USB_BUSIFFN
|
|
|
|
FlushTransfers(PVOID BusContext, PVOID DeviceHandle)
|
|
|
|
{
|
2010-07-06 12:02:33 +00:00
|
|
|
PUSB_DEVICE UsbDevice;
|
|
|
|
UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
|
|
|
|
|
|
|
|
if (!UsbDevice)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid DeviceHandle or device not connected\n");
|
|
|
|
}
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
DPRINT1("FlushTransfers not implemented.\n");
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
USB_BUSIFFN
|
|
|
|
SetDeviceHandleData(PVOID BusContext, PVOID DeviceHandle, PDEVICE_OBJECT UsbDevicePdo)
|
|
|
|
{
|
2011-01-06 17:46:59 +00:00
|
|
|
PUSB_DEVICE UsbDevice;
|
|
|
|
|
|
|
|
DPRINT1("Ehci: SetDeviceHandleData %x, %x, %x\n", BusContext, DeviceHandle, UsbDevicePdo);
|
|
|
|
UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
|
|
|
|
if (!UsbDevice)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid DeviceHandle or device not connected\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
UsbDevice->UsbDevicePdo = UsbDevicePdo;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* USB_BUS_INTERFACE_USBDI_V2 Functions */
|
|
|
|
|
2010-04-05 12:23:30 +00:00
|
|
|
VOID
|
2010-02-10 12:21:23 +00:00
|
|
|
USB_BUSIFFN
|
|
|
|
GetUSBDIVersion(PVOID BusContext, PUSBD_VERSION_INFORMATION VersionInformation, PULONG HcdCapabilites)
|
|
|
|
{
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: GetUSBDIVersion called\n");
|
2010-04-05 12:23:30 +00:00
|
|
|
return;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
QueryBusTime(PVOID BusContext, PULONG CurrentFrame)
|
|
|
|
{
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: QueryBusTime called\n");
|
2010-04-07 10:25:36 +00:00
|
|
|
return STATUS_NOT_SUPPORTED;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
SubmitIsoOutUrb(PVOID BusContext, PURB Urb)
|
|
|
|
{
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: SubmitIsoOutUrb called\n");
|
2010-04-07 10:25:36 +00:00
|
|
|
return STATUS_NOT_SUPPORTED;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
QueryBusInformation(PVOID BusContext,
|
|
|
|
ULONG Level,
|
|
|
|
PVOID BusInformationBuffer,
|
|
|
|
PULONG BusInformationBufferLength,
|
|
|
|
PULONG BusInformationActualLength)
|
|
|
|
{
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: QueryBusInformation called\n");
|
2010-04-07 10:25:36 +00:00
|
|
|
return STATUS_NOT_SUPPORTED;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
USB_BUSIFFN
|
2010-02-10 12:25:35 +00:00
|
|
|
IsDeviceHighSpeed(PVOID BusContext)
|
2010-02-10 12:21:23 +00:00
|
|
|
{
|
2010-09-05 18:43:17 +00:00
|
|
|
DPRINT1("Ehci: IsDeviceHighSpeed called\n");
|
2010-02-10 12:21:23 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
USB_BUSIFFN
|
|
|
|
EnumLogEntry(PVOID BusContext, ULONG DriverTag, ULONG EnumTag, ULONG P1, ULONG P2)
|
|
|
|
{
|
2011-01-06 17:46:59 +00:00
|
|
|
DPRINT1("Ehci: EnumLogEntry called %x, %x, %x, %x\n", DriverTag, EnumTag, P1, P2);
|
2011-04-13 04:43:25 +00:00
|
|
|
|
2010-07-06 12:02:33 +00:00
|
|
|
return STATUS_SUCCESS;
|
2010-02-10 12:21:23 +00:00
|
|
|
}
|