mirror of
https://github.com/reactos/reactos.git
synced 2025-07-25 12:04:01 +00:00
[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:
parent
8df637b778
commit
ede1d48da4
5 changed files with 82 additions and 36 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
//
|
//
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue