[USBEHCI_NEW]

- Invoke status change callback at passive level
- Fill out usb descriptor struct instead passing everything in char array
- Use 1 byte interrupt endpoint packet size for hub for now
- Fill in interface information when SelectConfiguration request is passed. Fixes sce callback and pool corruptions
- Return device descriptor in USBHI_QueryDeviceInformation
- Tested in WinXP with special pool enabled & overrun support

svn path=/branches/usb-bringup/; revision=51572
This commit is contained in:
Johannes Anderwald 2011-05-04 11:49:00 +00:00
parent 9cbc4f8f60
commit c2b34a98be
3 changed files with 117 additions and 55 deletions

View file

@ -20,13 +20,18 @@ InterruptServiceRoutine(
IN PKINTERRUPT Interrupt,
IN PVOID ServiceContext);
VOID NTAPI
VOID
NTAPI
EhciDefferedRoutine(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2);
VOID
NTAPI
StatusChangeWorkItemRoutine(PVOID Context);
class CUSBHardwareDevice : public IUSBHardwareDevice
{
public:
@ -81,7 +86,7 @@ public:
// friend function
friend BOOLEAN NTAPI InterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext);
friend VOID NTAPI EhciDefferedRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);
friend VOID NTAPI StatusChangeWorkItemRoutine(PVOID Context);
// constructor / destructor
CUSBHardwareDevice(IUnknown *OuterUnknown){}
virtual ~CUSBHardwareDevice(){}
@ -110,6 +115,7 @@ protected:
PVOID m_SCEContext; // status change callback routine context
BOOLEAN m_DoorBellRingInProgress; // door bell ring in progress
EHCI_PORT_STATUS m_PortStatus[16]; // port status
WORK_QUEUE_ITEM m_StatusChangeWorkItem; // work item for status change callback
// set command
VOID SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
@ -190,6 +196,11 @@ CUSBHardwareDevice::Initialize(
//
KeInitializeSpinLock(&m_Lock);
//
// intialize status change work item
//
ExInitializeWorkItem(&m_StatusChangeWorkItem, StatusChangeWorkItemRoutine, PVOID(this));
m_VendorID = 0;
m_DeviceID = 0;
@ -774,7 +785,7 @@ CUSBHardwareDevice::ClearPortStatus(
{
ULONG Value;
DPRINT("CUSBHardwareDevice::ClearPortStatus\n");
DPRINT("CUSBHardwareDevice::ClearPortStatus PortId %x Feature %x\n", PortId, Status);
if (PortId > m_Capabilities.HCSParams.PortCount)
return STATUS_UNSUCCESSFUL;
@ -1112,9 +1123,9 @@ EhciDefferedRoutine(
if (This->m_SCECallBack != NULL)
{
//
// issue callback
// queue work item for processing
//
This->m_SCECallBack(This->m_SCEContext);
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
}
}
else
@ -1131,6 +1142,29 @@ EhciDefferedRoutine(
return;
}
VOID
NTAPI
StatusChangeWorkItemRoutine(
PVOID Context)
{
//
// cast to hardware object
//
CUSBHardwareDevice * This = (CUSBHardwareDevice*)Context;
//
// is there a callback
//
if (This->m_SCECallBack)
{
//
// issue callback
//
This->m_SCECallBack(This->m_SCEContext);
}
}
NTSTATUS
CreateUSBHardware(
PUSBHARDWAREDEVICE *OutHardware)

View file

@ -129,42 +129,39 @@ const UCHAR ROOTHUB2_DEVICE_DESCRIPTOR [] =
};
const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR [] =
const USB_CONFIGURATION_DESCRIPTOR ROOTHUB2_CONFIGURATION_DESCRIPTOR =
{
/* one configuration */
0x09, /* bLength; */
0x02, /* bDescriptorType; Configuration */
0x19, 0x00, /* wTotalLength; */
0x01, /* bNumInterfaces; (1) */
0x23, /* bConfigurationValue; */
0x00, /* iConfiguration; */
0x40, /* bmAttributes; */
0x00 /* MaxPower; */
sizeof(USB_CONFIGURATION_DESCRIPTOR),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
1,
1,
0,
0x40, /* self powered */
0x0
};
const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] =
const USB_INTERFACE_DESCRIPTOR ROOTHUB2_INTERFACE_DESCRIPTOR =
{
/* one interface */
0x09, /* bLength: Interface; */
0x04, /* bDescriptorType; Interface */
0x00, /* bInterfaceNumber; */
0x00, /* bAlternateSetting; */
0x01, /* bNumEndpoints; */
0x09, /* bInterfaceClass; HUB_CLASSCODE */
0x01, /* bInterfaceSubClass; */
0x00, /* bInterfaceProtocol: */
0x00 /* iInterface; */
sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType; Interface */
0, /* bInterfaceNumber; */
0, /* bAlternateSetting; */
0x1, /* bNumEndpoints; */
0x09, /* bInterfaceClass; HUB_CLASSCODE */
0x01, /* bInterfaceSubClass; */
0x00, /* bInterfaceProtocol: */
0x00, /* iInterface; */
};
const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR [] =
const USB_ENDPOINT_DESCRIPTOR ROOTHUB2_ENDPOINT_DESCRIPTOR =
{
/* one endpoint (status change endpoint) */
0x07, /* bLength; */
0x05, /* bDescriptorType; Endpoint */
0x81, /* bEndpointAddress; IN Endpoint 1 */
0x03, /* bmAttributes; Interrupt */
0x08, 0x00, /* wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
0xFF /* bInterval; (255ms -- usb 2.0 spec) */
sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
0x81, /* bEndPointAddress */
USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
0x01, /* wMaxPacketSize */
0xC /* bInterval */
};
//----------------------------------------------------------------------------------------
@ -266,12 +263,12 @@ CHubController::Initialize(
// Set the SCE Callback that the Hardware Device will call on port status change
//
Device->SetStatusChangeEndpointCallBack((PVOID)StatusChangeEndpointCallBack, this);
//
// clear init flag
//
m_HubControllerDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}
@ -286,6 +283,8 @@ CHubController::QueryStatusChageEndpoint(
PIO_STACK_LOCATION IoStack;
USHORT PortStatus, PortChange;
PURB Urb;
PUCHAR TransferBuffer;
UCHAR Changed = FALSE;
//
// get current stack location
@ -303,8 +302,9 @@ CHubController::QueryStatusChageEndpoint(
// Get the number of ports and check each one for device connected
//
m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL);
DPRINT1("SCE Request\n");
((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 0;
DPRINT1("SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, Urb->UrbBulkOrInterruptTransfer.TransferFlags, Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
TransferBuffer = (PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer;
for (PortId = 0; PortId < PortCount; PortId++)
{
m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
@ -318,14 +318,15 @@ CHubController::QueryStatusChageEndpoint(
{
DPRINT1("Device is connected on port %d\n", PortId);
// Set the value for the port number
((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((PortId + 1) & 7);
*TransferBuffer = 1 << ((PortId + 1) & 7);
Changed = TRUE;
}
}
//
// If there were changes then return TRUE
//
if (((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] != 0)
if (Changed != 0)
return TRUE;
return FALSE;
@ -835,7 +836,7 @@ CHubController::HandleClassOther(
ULONG NumPort;
ULONG PortId;
//DPRINT1("CHubController::HandleClassOther> Request %x Value %x not implemented\n", Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value);
DPRINT("CHubController::HandleClassOther> Request %x Value %x\n", Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value);
//
// get number of ports available
@ -877,6 +878,7 @@ CHubController::HandleClassOther(
//
// request contains buffer of 2 ushort which are used from submitting port status and port change status
//
DPRINT("PortId %x PortStatus %x PortChange %x\n", PortId, PortStatus, PortChange);
Buffer = (PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer;
//
@ -973,6 +975,7 @@ CHubController::HandleSelectConfiguration(
PURB Urb)
{
PUSBDEVICE UsbDevice;
PUSBD_INTERFACE_INFORMATION InterfaceInfo;
//
// is the request for the Root Hub
@ -987,11 +990,33 @@ CHubController::HandleSelectConfiguration(
//
// set device handle
//
Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)ROOTHUB2_CONFIGURATION_DESCRIPTOR;
Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&ROOTHUB2_CONFIGURATION_DESCRIPTOR;
//
// TODO: copy interface info
// copy interface info
//
InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)&ROOTHUB2_INTERFACE_DESCRIPTOR;
InterfaceInfo->Class = ROOTHUB2_INTERFACE_DESCRIPTOR.bInterfaceClass;
InterfaceInfo->SubClass = ROOTHUB2_INTERFACE_DESCRIPTOR.bInterfaceSubClass;
InterfaceInfo->Protocol = ROOTHUB2_INTERFACE_DESCRIPTOR.bInterfaceProtocol;
InterfaceInfo->Reserved = 0;
//
// sanity check
//
PC_ASSERT(InterfaceInfo->NumberOfPipes == 1);
//
// copy pipe info
//
InterfaceInfo->Pipes[0].MaximumPacketSize = ROOTHUB2_ENDPOINT_DESCRIPTOR.wMaxPacketSize;
InterfaceInfo->Pipes[0].EndpointAddress = ROOTHUB2_ENDPOINT_DESCRIPTOR.bEndpointAddress;
InterfaceInfo->Pipes[0].Interval = ROOTHUB2_ENDPOINT_DESCRIPTOR.bInterval;
InterfaceInfo->Pipes[0].PipeType = (USBD_PIPE_TYPE)(ROOTHUB2_ENDPOINT_DESCRIPTOR.bmAttributes & USB_ENDPOINT_TYPE_MASK);
InterfaceInfo->Pipes[0].PipeHandle = (PVOID)&ROOTHUB2_ENDPOINT_DESCRIPTOR;
return STATUS_SUCCESS;
}
else
@ -1098,6 +1123,8 @@ CHubController::HandleClassDevice(
ULONG PortCount, Dummy2;
USHORT Dummy1;
DPRINT("CHubController::HandleClassDevice Request %x Class %x\n", Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value >> 8);
//
// check class request type
//
@ -1142,7 +1169,7 @@ CHubController::HandleClassDevice(
// FIXME: retrieve values
//
UsbHubDescriptor->bNumberOfPorts = (UCHAR)PortCount;
UsbHubDescriptor->wHubCharacteristics = 0x0012;
UsbHubDescriptor->wHubCharacteristics = 0x00;
UsbHubDescriptor->bPowerOnToPowerGood = 0x01;
UsbHubDescriptor->bHubControlCurrent = 0x00;
@ -1177,6 +1204,8 @@ CHubController::HandleGetDescriptor(
PUSBDEVICE UsbDevice;
ULONG Length;
DPRINT("CHubController::HandleGetDescriptor\n");
//
// check descriptor type
//
@ -1231,8 +1260,7 @@ CHubController::HandleGetDescriptor(
//
// request is for the root bus controller
//
C_ASSERT(sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR) == sizeof(USB_CONFIGURATION_DESCRIPTOR));
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, ROOTHUB2_CONFIGURATION_DESCRIPTOR, sizeof(USB_CONFIGURATION_DESCRIPTOR));
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, &ROOTHUB2_CONFIGURATION_DESCRIPTOR, sizeof(USB_CONFIGURATION_DESCRIPTOR));
//
// get configuration descriptor, very retarded!
@ -1248,6 +1276,7 @@ CHubController::HandleGetDescriptor(
// buffer too small
//
Status = STATUS_SUCCESS;
ASSERT(FALSE);
break;
}
@ -1255,15 +1284,13 @@ CHubController::HandleGetDescriptor(
// copy interface descriptor template
//
Buffer = (PUCHAR)(ConfigurationDescriptor + 1);
C_ASSERT(sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR) == sizeof(USB_INTERFACE_DESCRIPTOR));
RtlCopyMemory(Buffer, ROOTHUB2_INTERFACE_DESCRIPTOR, sizeof(USB_INTERFACE_DESCRIPTOR));
RtlCopyMemory(Buffer, &ROOTHUB2_INTERFACE_DESCRIPTOR, sizeof(USB_INTERFACE_DESCRIPTOR));
//
// copy end point descriptor template
//
Buffer += sizeof(USB_INTERFACE_DESCRIPTOR);
C_ASSERT(sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR) == sizeof(USB_ENDPOINT_DESCRIPTOR));
RtlCopyMemory(Buffer, ROOTHUB2_ENDPOINT_DESCRIPTOR, sizeof(USB_ENDPOINT_DESCRIPTOR));
RtlCopyMemory(Buffer, &ROOTHUB2_ENDPOINT_DESCRIPTOR, sizeof(USB_ENDPOINT_DESCRIPTOR));
//
// done
@ -1498,7 +1525,7 @@ CHubController::HandleDeviceControl(
}
case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
{
DPRINT("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
DPRINT("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %p\n", this);
if (IoStack->Parameters.Others.Argument1)
{
@ -2392,8 +2419,9 @@ USBHI_QueryDeviceInformation(
DeviceInfo->NumberOfOpenPipes = 0; //FIXME
//
// FIXME get device descriptor
// get device descriptor
//
RtlMoveMemory(&DeviceInfo->DeviceDescriptor, ROOTHUB2_DEVICE_DESCRIPTOR, sizeof(USB_DEVICE_DESCRIPTOR));
//
// FIXME return pipe information
@ -2402,7 +2430,7 @@ USBHI_QueryDeviceInformation(
//
// store result length
//
*LengthReturned = sizeof(USB_DEVICE_INFORMATION_0);
*LengthReturned = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[DeviceInfo->NumberOfOpenPipes]);
//
// done
@ -2587,7 +2615,7 @@ USBHI_Initialize20Hub(
PUSB_DEVICE_HANDLE HubDeviceHandle,
ULONG TtCount)
{
UNIMPLEMENTED
DPRINT("USBHI_Initialize20Hub HubDeviceHandle %p UNIMPLEMENTED TtCount %lu\n", HubDeviceHandle, TtCount);
return STATUS_SUCCESS;
}
@ -2600,7 +2628,7 @@ USBHI_RootHubInitNotification(
{
CHubController * Controller;
DPRINT1("USBHI_RootHubInitNotification\n");
DPRINT("USBHI_RootHubInitNotification %p \n", CallbackContext);
//
// get controller object

View file

@ -2,7 +2,7 @@
#define USBEHCI_H__
#include <ntddk.h>
#define NDEBUG
#define YDEBUG
#include <debug.h>
#include <hubbusif.h>
#include <usbbusif.h>