mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 00:43:21 +00:00
[USBUHCI]
- Silence traces - Implement abort pipe - Implement support for interrupt transfers svn path=/trunk/; revision=55820
This commit is contained in:
parent
86ebeb35cc
commit
4b02150831
|
@ -1053,36 +1053,36 @@ CUSBDevice::GetConfigurationDescriptorsLength()
|
||||||
VOID
|
VOID
|
||||||
CUSBDevice::DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
|
CUSBDevice::DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
|
||||||
{
|
{
|
||||||
DPRINT1("Dumping Device Descriptor %x\n", DeviceDescriptor);
|
DPRINT("Dumping Device Descriptor %x\n", DeviceDescriptor);
|
||||||
DPRINT1("bLength %x\n", DeviceDescriptor->bLength);
|
DPRINT("bLength %x\n", DeviceDescriptor->bLength);
|
||||||
DPRINT1("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType);
|
DPRINT("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType);
|
||||||
DPRINT1("bcdUSB %x\n", DeviceDescriptor->bcdUSB);
|
DPRINT("bcdUSB %x\n", DeviceDescriptor->bcdUSB);
|
||||||
DPRINT1("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass);
|
DPRINT("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass);
|
||||||
DPRINT1("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass);
|
DPRINT("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass);
|
||||||
DPRINT1("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol);
|
DPRINT("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol);
|
||||||
DPRINT1("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0);
|
DPRINT("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0);
|
||||||
DPRINT1("idVendor %x\n", DeviceDescriptor->idVendor);
|
DPRINT("idVendor %x\n", DeviceDescriptor->idVendor);
|
||||||
DPRINT1("idProduct %x\n", DeviceDescriptor->idProduct);
|
DPRINT("idProduct %x\n", DeviceDescriptor->idProduct);
|
||||||
DPRINT1("bcdDevice %x\n", DeviceDescriptor->bcdDevice);
|
DPRINT("bcdDevice %x\n", DeviceDescriptor->bcdDevice);
|
||||||
DPRINT1("iManufacturer %x\n", DeviceDescriptor->iManufacturer);
|
DPRINT("iManufacturer %x\n", DeviceDescriptor->iManufacturer);
|
||||||
DPRINT1("iProduct %x\n", DeviceDescriptor->iProduct);
|
DPRINT("iProduct %x\n", DeviceDescriptor->iProduct);
|
||||||
DPRINT1("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber);
|
DPRINT("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber);
|
||||||
DPRINT1("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
|
DPRINT("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------
|
||||||
VOID
|
VOID
|
||||||
CUSBDevice::DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
|
CUSBDevice::DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
|
||||||
{
|
{
|
||||||
DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
|
DPRINT("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
|
||||||
DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength);
|
DPRINT("bLength %x\n", ConfigurationDescriptor->bLength);
|
||||||
DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
|
DPRINT("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
|
||||||
DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
|
DPRINT("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
|
||||||
DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
|
DPRINT("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
|
||||||
DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
|
DPRINT("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
|
||||||
DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
|
DPRINT("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
|
||||||
DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
|
DPRINT("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
|
||||||
DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
|
DPRINT("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -220,8 +220,8 @@ CUSBQueue::AddUSBRequest(
|
||||||
//
|
//
|
||||||
// add queue head
|
// add queue head
|
||||||
//
|
//
|
||||||
DPRINT1("AddUSBRequest Request %p\n", Request);
|
DPRINT("AddUSBRequest Request %p\n", Request);
|
||||||
DPRINT1("NewQueueHead %p\n", NewQueueHead);
|
DPRINT("NewQueueHead %p\n", NewQueueHead);
|
||||||
return AddQueueHead(NewQueueHead);
|
return AddQueueHead(NewQueueHead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,9 +260,49 @@ CUSBQueue::AbortDevicePipe(
|
||||||
IN UCHAR DeviceAddress,
|
IN UCHAR DeviceAddress,
|
||||||
IN struct _USB_ENDPOINT *EndpointDescriptor)
|
IN struct _USB_ENDPOINT *EndpointDescriptor)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
KIRQL OldLevel;
|
||||||
ASSERT(FALSE);
|
PUHCI_TRANSFER_DESCRIPTOR Descriptor;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PUHCI_QUEUE_HEAD QueueHead, PreviousQueueHead = NULL;
|
||||||
|
UCHAR EndpointAddress, EndpointDeviceAddress;
|
||||||
|
|
||||||
|
|
||||||
|
// acquire lock
|
||||||
|
KeAcquireSpinLock(&m_Lock, &OldLevel);
|
||||||
|
|
||||||
|
// get queue head
|
||||||
|
m_Hardware->GetQueueHead(UHCI_INTERRUPT_QUEUE, &QueueHead);
|
||||||
|
|
||||||
|
while(QueueHead)
|
||||||
|
{
|
||||||
|
// get descriptor
|
||||||
|
Descriptor = (PUHCI_TRANSFER_DESCRIPTOR)QueueHead->NextElementDescriptor;
|
||||||
|
|
||||||
|
if (Descriptor)
|
||||||
|
{
|
||||||
|
// extract endpoint address
|
||||||
|
EndpointAddress = (Descriptor->Token >> TD_TOKEN_ENDPTADDR_SHIFT) & 0x0F;
|
||||||
|
|
||||||
|
// extract device address
|
||||||
|
EndpointDeviceAddress = (Descriptor->Token >> TD_TOKEN_DEVADDR_SHIFT) & 0x7F;
|
||||||
|
|
||||||
|
// check if they match
|
||||||
|
if (EndpointAddress == (EndpointDescriptor->EndPointDescriptor.bEndpointAddress & 0x0F) &&
|
||||||
|
DeviceAddress == EndpointDeviceAddress)
|
||||||
|
{
|
||||||
|
// cleanup queue head
|
||||||
|
QueueHeadCleanup(QueueHead, PreviousQueueHead, &QueueHead);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to next queue head
|
||||||
|
PreviousQueueHead = QueueHead;
|
||||||
|
QueueHead = (PUHCI_QUEUE_HEAD)QueueHead->NextLogicalDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// release lock
|
||||||
|
KeReleaseSpinLock(&m_Lock, OldLevel);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -295,7 +335,7 @@ CUSBQueue::IsQueueHeadComplete(
|
||||||
//
|
//
|
||||||
// empty queue head
|
// empty queue head
|
||||||
//
|
//
|
||||||
DPRINT1("QueueHead %p empty element physical\n", QueueHead);
|
DPRINT("QueueHead %p empty element physical\n", QueueHead);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +436,7 @@ CUSBQueue::QueueHeadCleanup(
|
||||||
//
|
//
|
||||||
// free queue head
|
// free queue head
|
||||||
//
|
//
|
||||||
DPRINT1("Request %p\n", Request);
|
DPRINT("Request %p\n", Request);
|
||||||
Request->FreeEndpointDescriptor(QueueHead);
|
Request->FreeEndpointDescriptor(QueueHead);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -467,7 +507,7 @@ CUSBQueue::TransferInterrupt(
|
||||||
//
|
//
|
||||||
// is queue head complete
|
// is queue head complete
|
||||||
//
|
//
|
||||||
DPRINT1("QueueHead %p\n", QueueHead);
|
DPRINT("QueueHead %p\n", QueueHead);
|
||||||
IsComplete = IsQueueHeadComplete(QueueHead);
|
IsComplete = IsQueueHeadComplete(QueueHead);
|
||||||
if (IsComplete)
|
if (IsComplete)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,6 +59,7 @@ public:
|
||||||
USHORT GetMaxPacketSize();
|
USHORT GetMaxPacketSize();
|
||||||
NTSTATUS CreateDescriptor(PUHCI_TRANSFER_DESCRIPTOR *OutDescriptor, IN UCHAR PidCode, ULONG BufferLength);
|
NTSTATUS CreateDescriptor(PUHCI_TRANSFER_DESCRIPTOR *OutDescriptor, IN UCHAR PidCode, ULONG BufferLength);
|
||||||
NTSTATUS BuildControlTransferDescriptor(IN PUHCI_QUEUE_HEAD * OutQueueHead);
|
NTSTATUS BuildControlTransferDescriptor(IN PUHCI_QUEUE_HEAD * OutQueueHead);
|
||||||
|
NTSTATUS BuildBulkInterruptTransferDescriptor(IN PUHCI_QUEUE_HEAD * OutQueueHead);
|
||||||
NTSTATUS BuildQueueHead(OUT PUHCI_QUEUE_HEAD *OutQueueHead);
|
NTSTATUS BuildQueueHead(OUT PUHCI_QUEUE_HEAD *OutQueueHead);
|
||||||
VOID FreeDescriptor(IN PUHCI_TRANSFER_DESCRIPTOR Descriptor);
|
VOID FreeDescriptor(IN PUHCI_TRANSFER_DESCRIPTOR Descriptor);
|
||||||
NTSTATUS BuildTransferDescriptorChain(IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, OUT PUHCI_TRANSFER_DESCRIPTOR * OutFirstDescriptor, OUT PUHCI_TRANSFER_DESCRIPTOR * OutLastDescriptor, OUT PULONG OutTransferBufferOffset, OUT PUCHAR OutDataToggle);
|
NTSTATUS BuildTransferDescriptorChain(IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, OUT PUHCI_TRANSFER_DESCRIPTOR * OutFirstDescriptor, OUT PUHCI_TRANSFER_DESCRIPTOR * OutLastDescriptor, OUT PULONG OutTransferBufferOffset, OUT PUCHAR OutDataToggle);
|
||||||
|
@ -139,6 +140,9 @@ protected:
|
||||||
//
|
//
|
||||||
USB_DEVICE_SPEED m_DeviceSpeed;
|
USB_DEVICE_SPEED m_DeviceSpeed;
|
||||||
|
|
||||||
|
// base
|
||||||
|
PVOID m_Base;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------
|
||||||
|
@ -607,14 +611,25 @@ CUSBRequest::GetEndpointDescriptor(
|
||||||
struct _UHCI_QUEUE_HEAD ** OutQueueHead)
|
struct _UHCI_QUEUE_HEAD ** OutQueueHead)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||||
|
ULONG TransferType;
|
||||||
|
|
||||||
if (InternalGetTransferType() == USB_ENDPOINT_TYPE_CONTROL)
|
// get transfer type
|
||||||
|
TransferType = InternalGetTransferType();
|
||||||
|
|
||||||
|
if (TransferType == USB_ENDPOINT_TYPE_CONTROL)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// build queue head
|
// build queue head
|
||||||
//
|
//
|
||||||
Status = BuildControlTransferDescriptor(OutQueueHead);
|
Status = BuildControlTransferDescriptor(OutQueueHead);
|
||||||
}
|
}
|
||||||
|
else if (TransferType == USB_ENDPOINT_TYPE_INTERRUPT || TransferType == USB_ENDPOINT_TYPE_BULK)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// build queue head
|
||||||
|
//
|
||||||
|
Status = BuildBulkInterruptTransferDescriptor(OutQueueHead);
|
||||||
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -783,7 +798,7 @@ CUSBRequest::CreateDescriptor(
|
||||||
// store address & endpoint number
|
// store address & endpoint number
|
||||||
//
|
//
|
||||||
Descriptor->Token |= GetEndpointAddress() << TD_TOKEN_ENDPTADDR_SHIFT;
|
Descriptor->Token |= GetEndpointAddress() << TD_TOKEN_ENDPTADDR_SHIFT;
|
||||||
Descriptor->Token |= GetDeviceAddress() << 8 | PidCode;
|
Descriptor->Token |= GetDeviceAddress() << TD_TOKEN_DEVADDR_SHIFT | PidCode;
|
||||||
|
|
||||||
if (BufferLength)
|
if (BufferLength)
|
||||||
{
|
{
|
||||||
|
@ -991,6 +1006,70 @@ CUSBRequest::FreeDescriptor(
|
||||||
m_DmaManager->Release(Descriptor, sizeof(UHCI_TRANSFER_DESCRIPTOR));
|
m_DmaManager->Release(Descriptor, sizeof(UHCI_TRANSFER_DESCRIPTOR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CUSBRequest::BuildBulkInterruptTransferDescriptor(
|
||||||
|
IN PUHCI_QUEUE_HEAD * OutQueueHead)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PUHCI_QUEUE_HEAD QueueHead;
|
||||||
|
PUHCI_TRANSFER_DESCRIPTOR FirstDescriptor, LastDescriptor;
|
||||||
|
ULONG ChainDescriptorLength;
|
||||||
|
BOOLEAN Direction;
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG BufferSize;
|
||||||
|
|
||||||
|
// create queue head
|
||||||
|
Status = BuildQueueHead(&QueueHead);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
// failed to allocate descriptor
|
||||||
|
DPRINT1("[UHCI] Failed to create queue head\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get direction
|
||||||
|
Direction = InternalGetPidDirection();
|
||||||
|
|
||||||
|
if (!m_Base)
|
||||||
|
{
|
||||||
|
// get buffer base
|
||||||
|
m_Base = MmGetMdlVirtualAddress(m_TransferBufferMDL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get new buffer offset
|
||||||
|
Buffer = (PVOID)((ULONG_PTR)m_Base + m_TransferBufferLengthCompleted);
|
||||||
|
|
||||||
|
// FIXME determine buffer limit
|
||||||
|
BufferSize = min(m_TransferBufferLength - m_TransferBufferLengthCompleted, PAGE_SIZE);
|
||||||
|
|
||||||
|
// create descriptor chain
|
||||||
|
Status = BuildTransferDescriptorChain(Buffer,
|
||||||
|
BufferSize,
|
||||||
|
Direction ? TD_TOKEN_IN : TD_TOKEN_OUT,
|
||||||
|
m_EndpointDescriptor->DataToggle,
|
||||||
|
&FirstDescriptor,
|
||||||
|
&LastDescriptor,
|
||||||
|
&ChainDescriptorLength,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
// adjust buffer offset
|
||||||
|
m_TransferBufferLengthCompleted += ChainDescriptorLength;
|
||||||
|
|
||||||
|
// fire interrupt when the last descriptor is complete
|
||||||
|
LastDescriptor->Status |= TD_CONTROL_IOC;
|
||||||
|
LastDescriptor->LinkPhysical = TD_TERMINATE;
|
||||||
|
LastDescriptor->NextLogicalDescriptor = NULL;
|
||||||
|
|
||||||
|
// link queue head with first data descriptor descriptor
|
||||||
|
QueueHead->NextElementDescriptor = (PVOID)FirstDescriptor;
|
||||||
|
QueueHead->ElementPhysical = FirstDescriptor->PhysicalAddress;
|
||||||
|
|
||||||
|
// store result
|
||||||
|
*OutQueueHead = QueueHead;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CUSBRequest::BuildControlTransferDescriptor(
|
CUSBRequest::BuildControlTransferDescriptor(
|
||||||
IN PUHCI_QUEUE_HEAD * OutQueueHead)
|
IN PUHCI_QUEUE_HEAD * OutQueueHead)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define USBOHCI_H__
|
#define USBOHCI_H__
|
||||||
|
|
||||||
#include <ntddk.h>
|
#include <ntddk.h>
|
||||||
#define YDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <hubbusif.h>
|
#include <hubbusif.h>
|
||||||
#include <usbbusif.h>
|
#include <usbbusif.h>
|
||||||
|
|
Loading…
Reference in a new issue