mirror of
https://github.com/reactos/reactos.git
synced 2024-07-06 04:35:07 +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
|
||||
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);
|
||||
DPRINT("Dumping Device Descriptor %x\n", DeviceDescriptor);
|
||||
DPRINT("bLength %x\n", DeviceDescriptor->bLength);
|
||||
DPRINT("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType);
|
||||
DPRINT("bcdUSB %x\n", DeviceDescriptor->bcdUSB);
|
||||
DPRINT("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass);
|
||||
DPRINT("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass);
|
||||
DPRINT("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol);
|
||||
DPRINT("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0);
|
||||
DPRINT("idVendor %x\n", DeviceDescriptor->idVendor);
|
||||
DPRINT("idProduct %x\n", DeviceDescriptor->idProduct);
|
||||
DPRINT("bcdDevice %x\n", DeviceDescriptor->bcdDevice);
|
||||
DPRINT("iManufacturer %x\n", DeviceDescriptor->iManufacturer);
|
||||
DPRINT("iProduct %x\n", DeviceDescriptor->iProduct);
|
||||
DPRINT("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber);
|
||||
DPRINT("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
VOID
|
||||
CUSBDevice::DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
|
||||
{
|
||||
DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
|
||||
DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength);
|
||||
DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
|
||||
DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
|
||||
DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
|
||||
DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
|
||||
DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
|
||||
DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
|
||||
DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
|
||||
DPRINT("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
|
||||
DPRINT("bLength %x\n", ConfigurationDescriptor->bLength);
|
||||
DPRINT("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
|
||||
DPRINT("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
|
||||
DPRINT("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
|
||||
DPRINT("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
|
||||
DPRINT("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
|
||||
DPRINT("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
|
||||
DPRINT("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
NTSTATUS
|
||||
|
|
|
@ -220,8 +220,8 @@ CUSBQueue::AddUSBRequest(
|
|||
//
|
||||
// add queue head
|
||||
//
|
||||
DPRINT1("AddUSBRequest Request %p\n", Request);
|
||||
DPRINT1("NewQueueHead %p\n", NewQueueHead);
|
||||
DPRINT("AddUSBRequest Request %p\n", Request);
|
||||
DPRINT("NewQueueHead %p\n", NewQueueHead);
|
||||
return AddQueueHead(NewQueueHead);
|
||||
}
|
||||
|
||||
|
@ -260,9 +260,49 @@ CUSBQueue::AbortDevicePipe(
|
|||
IN UCHAR DeviceAddress,
|
||||
IN struct _USB_ENDPOINT *EndpointDescriptor)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
KIRQL OldLevel;
|
||||
PUHCI_TRANSFER_DESCRIPTOR Descriptor;
|
||||
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
|
||||
|
@ -295,7 +335,7 @@ CUSBQueue::IsQueueHeadComplete(
|
|||
//
|
||||
// empty queue head
|
||||
//
|
||||
DPRINT1("QueueHead %p empty element physical\n", QueueHead);
|
||||
DPRINT("QueueHead %p empty element physical\n", QueueHead);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -396,7 +436,7 @@ CUSBQueue::QueueHeadCleanup(
|
|||
//
|
||||
// free queue head
|
||||
//
|
||||
DPRINT1("Request %p\n", Request);
|
||||
DPRINT("Request %p\n", Request);
|
||||
Request->FreeEndpointDescriptor(QueueHead);
|
||||
|
||||
//
|
||||
|
@ -467,7 +507,7 @@ CUSBQueue::TransferInterrupt(
|
|||
//
|
||||
// is queue head complete
|
||||
//
|
||||
DPRINT1("QueueHead %p\n", QueueHead);
|
||||
DPRINT("QueueHead %p\n", QueueHead);
|
||||
IsComplete = IsQueueHeadComplete(QueueHead);
|
||||
if (IsComplete)
|
||||
{
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
USHORT GetMaxPacketSize();
|
||||
NTSTATUS CreateDescriptor(PUHCI_TRANSFER_DESCRIPTOR *OutDescriptor, IN UCHAR PidCode, ULONG BufferLength);
|
||||
NTSTATUS BuildControlTransferDescriptor(IN PUHCI_QUEUE_HEAD * OutQueueHead);
|
||||
NTSTATUS BuildBulkInterruptTransferDescriptor(IN PUHCI_QUEUE_HEAD * OutQueueHead);
|
||||
NTSTATUS BuildQueueHead(OUT PUHCI_QUEUE_HEAD *OutQueueHead);
|
||||
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);
|
||||
|
@ -139,6 +140,9 @@ protected:
|
|||
//
|
||||
USB_DEVICE_SPEED m_DeviceSpeed;
|
||||
|
||||
// base
|
||||
PVOID m_Base;
|
||||
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
@ -607,14 +611,25 @@ CUSBRequest::GetEndpointDescriptor(
|
|||
struct _UHCI_QUEUE_HEAD ** OutQueueHead)
|
||||
{
|
||||
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
|
||||
//
|
||||
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))
|
||||
{
|
||||
|
@ -783,7 +798,7 @@ CUSBRequest::CreateDescriptor(
|
|||
// store address & endpoint number
|
||||
//
|
||||
Descriptor->Token |= GetEndpointAddress() << TD_TOKEN_ENDPTADDR_SHIFT;
|
||||
Descriptor->Token |= GetDeviceAddress() << 8 | PidCode;
|
||||
Descriptor->Token |= GetDeviceAddress() << TD_TOKEN_DEVADDR_SHIFT | PidCode;
|
||||
|
||||
if (BufferLength)
|
||||
{
|
||||
|
@ -991,6 +1006,70 @@ CUSBRequest::FreeDescriptor(
|
|||
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
|
||||
CUSBRequest::BuildControlTransferDescriptor(
|
||||
IN PUHCI_QUEUE_HEAD * OutQueueHead)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define USBOHCI_H__
|
||||
|
||||
#include <ntddk.h>
|
||||
#define YDEBUG
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#include <hubbusif.h>
|
||||
#include <usbbusif.h>
|
||||
|
|
Loading…
Reference in a new issue