[USBEHCI_NEW]

- Change interface to return real async queue head
- Set the async queue head register after the controller has been started
- Enable async queue in StartController
- Port DumpDeviceDescriptor from mjmartin usbehci driver
- Remove pseudo queue head from usb queue, instead use the real async queue head exported from IUSBHardwareDevice 
- Get physical address for transfer data in BuildControlTransferQueueHead
- Retrieving device descriptor now ~works, currently stops at setting device address (needs more work)

svn path=/branches/usb-bringup/; revision=51476
This commit is contained in:
Johannes Anderwald 2011-04-28 15:16:33 +00:00
parent 8df637b778
commit ede1d48da4
5 changed files with 82 additions and 36 deletions

View file

@ -68,7 +68,7 @@ public:
VOID SetAsyncListRegister(ULONG PhysicalAddress); VOID SetAsyncListRegister(ULONG PhysicalAddress);
VOID SetPeriodicListRegister(ULONG PhysicalAddress); VOID SetPeriodicListRegister(ULONG PhysicalAddress);
ULONG GetAsyncListRegister(); struct _QUEUE_HEAD * GetAsyncListQueueHead();
ULONG GetPeriodicListRegister(); ULONG GetPeriodicListRegister();
VOID SetStatusChangeEndpointCallBack(PVOID CallBack, PVOID Context); VOID SetStatusChangeEndpointCallBack(PVOID CallBack, PVOID Context);
@ -423,8 +423,6 @@ CUSBHardwareDevice::PnpStart(
InitializeListHead(&AsyncQueueHead->LinkedQueueHeads); InitializeListHead(&AsyncQueueHead->LinkedQueueHeads);
SetAsyncListRegister(AsyncQueueHead->PhysicalAddr);
// //
// Initialize the UsbQueue now that we have an AdapterObject. // Initialize the UsbQueue now that we have an AdapterObject.
// //
@ -439,7 +437,24 @@ CUSBHardwareDevice::PnpStart(
// Start the controller // Start the controller
// //
DPRINT1("Starting Controller\n"); DPRINT1("Starting Controller\n");
return StartController(); Status = StartController();
//
// check for success
//
if (NT_SUCCESS(Status))
{
//
// set async list head
//
SetAsyncListRegister(AsyncQueueHead->PhysicalAddr);
}
//
// done
//
return Status;
} }
NTSTATUS NTSTATUS
@ -553,7 +568,7 @@ CUSBHardwareDevice::StartController(void)
// //
GetCommandRegister(&UsbCmd); GetCommandRegister(&UsbCmd);
UsbCmd.PeriodicEnable = FALSE; UsbCmd.PeriodicEnable = FALSE;
UsbCmd.AsyncEnable = FALSE; //FIXME: Need USB Memory Manager UsbCmd.AsyncEnable = TRUE; //FIXME: Need USB Memory Manager
UsbCmd.IntThreshold = 1; UsbCmd.IntThreshold = 1;
// FIXME: Set framelistsize when periodic is implemented. // FIXME: Set framelistsize when periodic is implemented.
@ -876,10 +891,10 @@ CUSBHardwareDevice::SetPeriodicListRegister(
EHCI_WRITE_REGISTER_ULONG(EHCI_PERIODICLISTBASE, PhysicalAddress); EHCI_WRITE_REGISTER_ULONG(EHCI_PERIODICLISTBASE, PhysicalAddress);
} }
ULONG struct _QUEUE_HEAD *
CUSBHardwareDevice::GetAsyncListRegister() CUSBHardwareDevice::GetAsyncListQueueHead()
{ {
return AsyncQueueHead->PhysicalAddr; return AsyncQueueHead;
} }
ULONG CUSBHardwareDevice::GetPeriodicListRegister() ULONG CUSBHardwareDevice::GetPeriodicListRegister()
@ -994,6 +1009,7 @@ EhciDefferedRoutine(
// controller reported error // controller reported error
// //
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
PC_ASSERT(FALSE);
} }
// //

View file

@ -268,7 +268,7 @@ DECLARE_INTERFACE_(IUSBHardwareDevice, IUnknown)
// //
// Description: Returns the memory address used in the Asynchronous Register // Description: Returns the memory address used in the Asynchronous Register
// //
virtual ULONG GetAsyncListRegister() = 0; virtual struct _QUEUE_HEAD * GetAsyncListQueueHead() = 0;
//----------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------
// //

View file

@ -73,6 +73,7 @@ public:
virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN ULONG BufferLength, IN OUT PMDL Mdl); virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN ULONG BufferLength, IN OUT PMDL Mdl);
virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex); virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex);
virtual NTSTATUS CreateDeviceDescriptor(); virtual NTSTATUS CreateDeviceDescriptor();
virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor);
// constructor / destructor // constructor / destructor
CUSBDevice(IUnknown *OuterUnknown){} CUSBDevice(IUnknown *OuterUnknown){}
@ -342,6 +343,11 @@ CUSBDevice::SetDeviceAddress(
return Status; return Status;
} }
//
// lets have a short nap
//
KeStallExecutionProcessor(300);
// //
// back up old address // back up old address
// //
@ -370,6 +376,8 @@ CUSBDevice::SetDeviceAddress(
return Status; return Status;
} }
PC_ASSERT(FALSE);
// //
// sanity checks // sanity checks
// //
@ -629,6 +637,14 @@ CUSBDevice::CreateDeviceDescriptor()
// //
IoFreeMdl(Mdl); IoFreeMdl(Mdl);
if (NT_SUCCESS(Status))
{
//
// informal dbg print
//
DumpDeviceDescriptor(&m_DeviceDescriptor);
}
// //
// done // done
// //
@ -866,6 +882,26 @@ CUSBDevice::GetConfigurationDescriptors(
} }
VOID
CUSBDevice::DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
{
DPRINT1("Dumping Device Descriptor %x\n", DeviceDescriptor);
DPRINT1("bLength %x\n", DeviceDescriptor->bLength);
DPRINT1("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType);
DPRINT1("bcdUSB %x\n", DeviceDescriptor->bcdUSB);
DPRINT1("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass);
DPRINT1("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass);
DPRINT1("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol);
DPRINT1("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0);
DPRINT1("idVendor %x\n", DeviceDescriptor->idVendor);
DPRINT1("idProduct %x\n", DeviceDescriptor->idProduct);
DPRINT1("bcdDevice %x\n", DeviceDescriptor->bcdDevice);
DPRINT1("iManufacturer %x\n", DeviceDescriptor->iManufacturer);
DPRINT1("iProduct %x\n", DeviceDescriptor->iProduct);
DPRINT1("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber);
DPRINT1("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
}
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
NTSTATUS NTSTATUS
CreateUSBDevice( CreateUSBDevice(

View file

@ -51,7 +51,6 @@ protected:
KSPIN_LOCK m_Lock; KSPIN_LOCK m_Lock;
PDMA_ADAPTER m_Adapter; PDMA_ADAPTER m_Adapter;
PQUEUE_HEAD AsyncListQueueHead; PQUEUE_HEAD AsyncListQueueHead;
PQUEUE_HEAD PendingListQueueHead;
LIST_ENTRY m_CompletedRequestAsyncList; LIST_ENTRY m_CompletedRequestAsyncList;
// queue head manipulation functions // queue head manipulation functions
@ -109,34 +108,18 @@ CUSBQueue::Initialize(
// //
// Get the AsyncQueueHead // Get the AsyncQueueHead
// //
AsyncListQueueHead = (PQUEUE_HEAD)Hardware->GetAsyncListRegister(); AsyncListQueueHead = (PQUEUE_HEAD)Hardware->GetAsyncListQueueHead();
//
// Create the PendingListQueueHead from NONPAGEDPOOL. It will never be linked into the Asynclist Schedule
//
PendingListQueueHead = (PQUEUE_HEAD)ExAllocatePoolWithTag(NonPagedPool, sizeof(QUEUE_HEAD), TAG_USBEHCI);
if (!PendingListQueueHead)
{
DPRINT1("Pool Allocation failed!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
// //
// Initialize the List Head // Initialize the List Head
// //
InitializeListHead(&PendingListQueueHead->LinkedQueueHeads); InitializeListHead(&AsyncListQueueHead->LinkedQueueHeads);
//
// fake the queue head as the first queue head
//
PendingListQueueHead->PhysicalAddr = ((ULONG_PTR)AsyncListQueueHead | QH_TYPE_QH);
// //
// Initialize completed async list head // Initialize completed async list head
// //
InitializeListHead(&m_CompletedRequestAsyncList); InitializeListHead(&m_CompletedRequestAsyncList);
return Status; return Status;
} }
@ -223,7 +206,7 @@ CUSBQueue::AddUSBRequest(
// //
// Add it to the pending list // Add it to the pending list
// //
LinkQueueHead(PendingListQueueHead, QueueHead); LinkQueueHead(AsyncListQueueHead, QueueHead);
} }
@ -300,7 +283,7 @@ CUSBQueue::LinkQueueHead(
Entry = NewQueueHead->LinkedQueueHeads.Flink; Entry = NewQueueHead->LinkedQueueHeads.Flink;
NextQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads); NextQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
ASSERT(NextQueueHead == HeadQueueHead); ASSERT(NextQueueHead == HeadQueueHead);
NewQueueHead->HorizontalLinkPointer = NextQueueHead->PhysicalAddr; NewQueueHead->HorizontalLinkPointer = (NextQueueHead->PhysicalAddr | QH_TYPE_QH);
} }
// //
@ -520,7 +503,7 @@ CUSBQueue::QueueHeadCompletion(
// //
// add to pending list // add to pending list
// //
LinkQueueHead(PendingListQueueHead, NewQueueHead); LinkQueueHead(AsyncListQueueHead, NewQueueHead);
} }
else else
{ {
@ -549,9 +532,9 @@ CUSBQueue::ProcessAsyncList(
// //
// walk async list // walk async list
// //
Entry = PendingListQueueHead->LinkedQueueHeads.Flink; Entry = AsyncListQueueHead->LinkedQueueHeads.Flink;
while(Entry != &PendingListQueueHead->LinkedQueueHeads) while(Entry != &AsyncListQueueHead->LinkedQueueHeads)
{ {
// //
// get queue head structure // get queue head structure
@ -574,6 +557,8 @@ CUSBQueue::ProcessAsyncList(
// //
Entry = Entry->Flink; Entry = Entry->Flink;
DPRINT1("Request %p QueueHead %p Complete %d\n", Request, QueueHead, Request->IsQueueHeadComplete(QueueHead));
// //
// check if queue head is complete // check if queue head is complete
// //
@ -604,6 +589,9 @@ CUSBQueue::InterruptCallback(
IN NTSTATUS Status, IN NTSTATUS Status,
OUT PULONG ShouldRingDoorBell) OUT PULONG ShouldRingDoorBell)
{ {
DPRINT1("CUSBQueue::InterruptCallback\n");
// //
// iterate asynchronous list // iterate asynchronous list
// //
@ -671,6 +659,8 @@ CUSBQueue::CompleteAsyncRequests()
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
PQUEUE_HEAD CurrentQH; PQUEUE_HEAD CurrentQH;
DPRINT1("CUSBQueue::CompleteAsyncRequests\n");
// //
// first acquire request lock // first acquire request lock
// //

View file

@ -603,6 +603,12 @@ CUSBRequest::BuildControlTransferQueueHead(
m_TransferDescriptors[1]->Token.Bits.PIDCode = PID_CODE_IN_TOKEN; m_TransferDescriptors[1]->Token.Bits.PIDCode = PID_CODE_IN_TOKEN;
m_TransferDescriptors[1]->Token.Bits.TotalBytesToTransfer = m_TransferBufferLength; m_TransferDescriptors[1]->Token.Bits.TotalBytesToTransfer = m_TransferBufferLength;
//
// FIXME: check if the request spawns over a page -> fill other members
//
PC_ASSERT(m_TransferBufferLength <= PAGE_SIZE);
m_TransferDescriptors[1]->BufferPointer[0] = MmGetPhysicalAddress(MmGetMdlVirtualAddress(m_TransferBufferMDL)).LowPart;
// //
// setup out descriptor // setup out descriptor
// //
@ -845,12 +851,11 @@ NTSTATUS
CUSBRequest::BuildSetupPacket() CUSBRequest::BuildSetupPacket()
{ {
NTSTATUS Status; NTSTATUS Status;
PHYSICAL_ADDRESS PhysicalAddress;
// //
// allocate common buffer setup packet // allocate common buffer setup packet
// //
Status = m_DmaManager->Allocate(sizeof(USB_DEFAULT_PIPE_SETUP_PACKET), (PVOID*)&m_DescriptorPacket, &PhysicalAddress); Status = m_DmaManager->Allocate(sizeof(USB_DEFAULT_PIPE_SETUP_PACKET), (PVOID*)&m_DescriptorPacket, &m_DescriptorSetupPacket);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// //
@ -865,7 +870,6 @@ CUSBRequest::BuildSetupPacket()
// copy setup packet // copy setup packet
// //
RtlCopyMemory(m_DescriptorPacket, m_SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); RtlCopyMemory(m_DescriptorPacket, m_SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
m_DescriptorSetupPacket = PhysicalAddress;
} }
else else
{ {