mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
[USBOHCI]
- Remove dead code - Silence traces - Pass status & DoneHead as parameters to dpc routine - Move IUSBRequest cleanup code into new function and use it for bulk / control transfer cleanup - Fix bugs in AllocateEndpointDescriptor. It did not take the device address into account. It also did not respect the direction of the descriptor - Implement support for bulk transfer requests - Handle irp completion in CompletionCallback - Tested in Windows XP SP3 + Vbox 4.04 + USB2.0 disabled + ReactOS usbstor + USB mass storage device - OHCI Mass storage support is now also ready - Next interrupt transfers svn path=/branches/usb-bringup/; revision=51917
This commit is contained in:
parent
2c6077dc50
commit
667b425b6c
5 changed files with 392 additions and 79 deletions
|
@ -697,8 +697,6 @@ CUSBHardwareDevice::HeadEndpointDescriptorModified(
|
|||
//
|
||||
// notify controller
|
||||
//
|
||||
//WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_HEAD_ED_OFFSET), m_ControlEndpointDescriptor->NextPhysicalEndpoint);
|
||||
//WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_CURRENT_ED_OFFSET), m_ControlEndpointDescriptor->NextPhysicalEndpoint);
|
||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), Value | OHCI_CONTROL_LIST_FILLED);
|
||||
}
|
||||
else if (Type == USB_ENDPOINT_TYPE_BULK)
|
||||
|
@ -708,12 +706,6 @@ CUSBHardwareDevice::HeadEndpointDescriptorModified(
|
|||
//
|
||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), Value | OHCI_BULK_LIST_FILLED);
|
||||
}
|
||||
|
||||
Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET));
|
||||
|
||||
|
||||
DPRINT1("HeadEndpointDescriptorModified Value %x Type %x\n", Value, Type);
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -1191,7 +1183,7 @@ InterruptServiceRoutine(
|
|||
//
|
||||
This = (CUSBHardwareDevice*) ServiceContext;
|
||||
|
||||
DPRINT1("InterruptServiceRoutine\n");
|
||||
DPRINT("InterruptServiceRoutine\n");
|
||||
|
||||
//
|
||||
// get done head
|
||||
|
@ -1246,6 +1238,7 @@ InterruptServiceRoutine(
|
|||
// head completed
|
||||
//
|
||||
Acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
|
||||
This->m_HCCA->DoneHead = 0;
|
||||
}
|
||||
|
||||
if (Status & OHCI_RESUME_DETECTED)
|
||||
|
@ -1296,8 +1289,8 @@ InterruptServiceRoutine(
|
|||
//
|
||||
// defer processing
|
||||
//
|
||||
DPRINT1("Status %x\n", Status);
|
||||
KeInsertQueueDpc(&This->m_IntDpcObject, This, (PVOID)Status);
|
||||
DPRINT("Status %x Acknowledge %x\n", Status, Acknowledge);
|
||||
KeInsertQueueDpc(&This->m_IntDpcObject, (PVOID)Status, (PVOID)(DoneHead & ~1));
|
||||
|
||||
//
|
||||
// interrupt handled
|
||||
|
@ -1321,23 +1314,14 @@ OhciDefferedRoutine(
|
|||
//
|
||||
// get parameters
|
||||
//
|
||||
This = (CUSBHardwareDevice*) SystemArgument1;
|
||||
CStatus = (ULONG) SystemArgument2;
|
||||
This = (CUSBHardwareDevice*)DeferredContext;
|
||||
CStatus = (ULONG) SystemArgument1;
|
||||
DoneHead = (ULONG)SystemArgument2;
|
||||
|
||||
DPRINT1("OhciDefferedRoutine Status %x\n", CStatus);
|
||||
DPRINT("OhciDefferedRoutine Status %x\n", CStatus);
|
||||
|
||||
if (CStatus & OHCI_WRITEBACK_DONE_HEAD)
|
||||
{
|
||||
//
|
||||
// descriptor completion, get done head
|
||||
//
|
||||
DoneHead = This->m_HCCA->DoneHead;
|
||||
|
||||
//
|
||||
// clear out lower bits, ed are 16 byte aligned
|
||||
//
|
||||
DoneHead &= ~0xF;
|
||||
|
||||
//
|
||||
// notify queue of event
|
||||
//
|
||||
|
|
|
@ -216,6 +216,8 @@ typedef struct _OHCI_ENDPOINT_DESCRIPTOR
|
|||
#define OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(s) ((s) << 16)
|
||||
#define OHCI_ENDPOINT_LOW_SPEED 0x00002000
|
||||
#define OHCI_ENDPOINT_FULL_SPEED 0x00000000
|
||||
#define OHCI_ENDPOINT_DIRECTION_OUT 0x00000800
|
||||
#define OHCI_ENDPOINT_DIRECTION_IN 0x00001000
|
||||
|
||||
//
|
||||
// Maximum port count set by OHCI
|
||||
|
|
|
@ -443,6 +443,14 @@ DECLARE_INTERFACE_(IUSBRequest, IUnknown)
|
|||
// Description: notifies request that the endpoint descriptor is complete
|
||||
|
||||
virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor) = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
//
|
||||
// FreeEndpointDescriptor
|
||||
//
|
||||
// Description: frees the associated endpoint descriptor and its general descriptors
|
||||
|
||||
virtual VOID FreeEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
// local functions
|
||||
BOOLEAN IsTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress);
|
||||
NTSTATUS FindTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress, OUT POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR *OutPreviousEndpointDescriptor);
|
||||
VOID CleanupEndpointDescriptor(POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, POHCI_ENDPOINT_DESCRIPTOR PreviousEndpointDescriptor);
|
||||
|
||||
// constructor / destructor
|
||||
CUSBQueue(IUnknown *OuterUnknown){}
|
||||
|
@ -127,7 +128,7 @@ CUSBQueue::AddUSBRequest(
|
|||
POHCI_ENDPOINT_DESCRIPTOR HeadDescriptor;
|
||||
POHCI_ENDPOINT_DESCRIPTOR Descriptor;
|
||||
|
||||
DPRINT1("CUSBQueue::AddUSBRequest\n");
|
||||
DPRINT("CUSBQueue::AddUSBRequest\n");
|
||||
|
||||
//
|
||||
// sanity check
|
||||
|
@ -146,11 +147,11 @@ CUSBQueue::AddUSBRequest(
|
|||
{
|
||||
case USB_ENDPOINT_TYPE_ISOCHRONOUS:
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
/* NOT IMPLEMENTED IN QUEUE */
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
|
@ -228,12 +229,14 @@ CUSBQueue::AddUSBRequest(
|
|||
Descriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
|
||||
//HeadDescriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
|
||||
|
||||
DPRINT("Request %x Logical %x added to queue Queue %p Logical %x\n", Descriptor, Descriptor->PhysicalAddress.LowPart, HeadDescriptor, HeadDescriptor->PhysicalAddress.LowPart);
|
||||
|
||||
|
||||
//
|
||||
// notify hardware of our request
|
||||
//
|
||||
m_Hardware->HeadEndpointDescriptorModified(Type);
|
||||
|
||||
DPRINT1("Request %x %x added to queue\n", Descriptor, Descriptor->PhysicalAddress);
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -356,6 +359,47 @@ CUSBQueue::IsTransferDescriptorInEndpoint(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
CUSBQueue::CleanupEndpointDescriptor(
|
||||
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor,
|
||||
POHCI_ENDPOINT_DESCRIPTOR PreviousEndpointDescriptor)
|
||||
{
|
||||
PUSBREQUEST Request;
|
||||
|
||||
//
|
||||
// FIXME: verify unlinking process
|
||||
//
|
||||
PreviousEndpointDescriptor->NextDescriptor = EndpointDescriptor->NextDescriptor;
|
||||
PreviousEndpointDescriptor->NextPhysicalEndpoint = EndpointDescriptor->NextPhysicalEndpoint;
|
||||
|
||||
//
|
||||
// get corresponding request
|
||||
//
|
||||
Request = PUSBREQUEST(EndpointDescriptor->Request);
|
||||
ASSERT(Request);
|
||||
|
||||
//
|
||||
// notify of completion
|
||||
//
|
||||
Request->CompletionCallback(EndpointDescriptor);
|
||||
|
||||
//
|
||||
// free endpoint descriptor
|
||||
//
|
||||
Request->FreeEndpointDescriptor(EndpointDescriptor);
|
||||
|
||||
//
|
||||
// FIXME: check if complete
|
||||
//
|
||||
//ASSERT(Request->IsRequestComplete());
|
||||
|
||||
//
|
||||
// release request
|
||||
//
|
||||
Request->Release();
|
||||
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CUSBQueue::TransferDescriptorCompletionCallback(
|
||||
|
@ -363,7 +407,8 @@ CUSBQueue::TransferDescriptorCompletionCallback(
|
|||
{
|
||||
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, PreviousEndpointDescriptor;
|
||||
NTSTATUS Status;
|
||||
PUSBREQUEST Request;
|
||||
|
||||
DPRINT("CUSBQueue::TransferDescriptorCompletionCallback transfer descriptor %x\n", TransferDescriptorLogicalAddress);
|
||||
|
||||
//
|
||||
// find transfer descriptor in control list
|
||||
|
@ -372,32 +417,39 @@ CUSBQueue::TransferDescriptorCompletionCallback(
|
|||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// FIXME: make sure this is ok
|
||||
// unlink descriptor
|
||||
// cleanup endpoint
|
||||
//
|
||||
PreviousEndpointDescriptor->NextDescriptor = EndpointDescriptor->NextDescriptor;
|
||||
PreviousEndpointDescriptor->NextPhysicalEndpoint = EndpointDescriptor->NextPhysicalEndpoint;
|
||||
CleanupEndpointDescriptor(EndpointDescriptor, PreviousEndpointDescriptor);
|
||||
|
||||
//
|
||||
// get corresponding request
|
||||
// done
|
||||
//
|
||||
Request = PUSBREQUEST(EndpointDescriptor->Request);
|
||||
|
||||
//
|
||||
// notify of completion
|
||||
//
|
||||
Request->CompletionCallback(EndpointDescriptor);
|
||||
|
||||
//
|
||||
// FIXME: check if complete
|
||||
//
|
||||
ASSERT(Request->IsRequestComplete());
|
||||
//
|
||||
// release request
|
||||
//
|
||||
Request->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// find transfer descriptor in bulk list
|
||||
//
|
||||
Status = FindTransferDescriptorInEndpoint(m_BulkHeadEndpointDescriptor, TransferDescriptorLogicalAddress, &EndpointDescriptor, &PreviousEndpointDescriptor);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// cleanup endpoint
|
||||
//
|
||||
CleanupEndpointDescriptor(EndpointDescriptor, PreviousEndpointDescriptor);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// hardware reported dead endpoint completed
|
||||
//
|
||||
DPRINT1("CUSBQueue::TransferDescriptorCompletionCallback invalid transfer descriptor %x\n", TransferDescriptorLogicalAddress);
|
||||
ASSERT(FALSE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
virtual BOOLEAN IsRequestInitialized();
|
||||
virtual BOOLEAN IsQueueHeadComplete(struct _QUEUE_HEAD * QueueHead);
|
||||
virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor);
|
||||
virtual VOID FreeEndpointDescriptor(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor);
|
||||
|
||||
// local functions
|
||||
ULONG InternalGetTransferType();
|
||||
|
@ -53,6 +54,7 @@ public:
|
|||
NTSTATUS BuildSetupPacket();
|
||||
NTSTATUS BuildSetupPacketFromURB();
|
||||
NTSTATUS BuildControlTransferDescriptor(POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor);
|
||||
NTSTATUS BuildBulkInterruptEndpoint(POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor);
|
||||
NTSTATUS CreateGeneralTransferDescriptor(POHCI_GENERAL_TD* OutDescriptor, ULONG BufferSize);
|
||||
VOID FreeDescriptor(POHCI_GENERAL_TD Descriptor);
|
||||
NTSTATUS AllocateEndpointDescriptor(OUT POHCI_ENDPOINT_DESCRIPTOR *OutDescriptor);
|
||||
|
@ -606,10 +608,36 @@ CUSBRequest::AllocateEndpointDescriptor(
|
|||
//
|
||||
// append device address and endpoint number
|
||||
//
|
||||
Descriptor->Flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(m_DeviceAddress);
|
||||
Descriptor->Flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(GetDeviceAddress());
|
||||
Descriptor->Flags |= OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(GetEndpointAddress());
|
||||
Descriptor->Flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(GetMaxPacketSize());
|
||||
|
||||
//
|
||||
// is there an endpoint descriptor
|
||||
//
|
||||
if (m_EndpointDescriptor)
|
||||
{
|
||||
//
|
||||
// check direction
|
||||
//
|
||||
if (USB_ENDPOINT_DIRECTION_OUT(m_EndpointDescriptor->bEndpointAddress))
|
||||
{
|
||||
//
|
||||
// direction out
|
||||
//
|
||||
Descriptor->Flags |= OHCI_ENDPOINT_DIRECTION_OUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// direction in
|
||||
//
|
||||
Descriptor->Flags |= OHCI_ENDPOINT_DIRECTION_IN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FIXME: detect type
|
||||
//
|
||||
|
@ -631,6 +659,198 @@ CUSBRequest::AllocateEndpointDescriptor(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CUSBRequest::BuildBulkInterruptEndpoint(
|
||||
POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor)
|
||||
{
|
||||
POHCI_GENERAL_TD FirstDescriptor, PreviousDescriptor = NULL, CurrentDescriptor, LastDescriptor;
|
||||
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
|
||||
ULONG BufferSize, CurrentSize, Direction, MaxLengthInPage;
|
||||
NTSTATUS Status;
|
||||
PVOID Buffer;
|
||||
|
||||
//
|
||||
// allocate endpoint descriptor
|
||||
//
|
||||
Status = AllocateEndpointDescriptor(&EndpointDescriptor);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to create setup descriptor
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// allocate transfer descriptor for last descriptor
|
||||
//
|
||||
Status = CreateGeneralTransferDescriptor(&LastDescriptor, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to create transfer descriptor
|
||||
//
|
||||
m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// get buffer size
|
||||
//
|
||||
BufferSize = m_TransferBufferLength;
|
||||
ASSERT(BufferSize);
|
||||
ASSERT(m_TransferBufferMDL);
|
||||
|
||||
//
|
||||
// get buffer
|
||||
//
|
||||
Buffer = MmGetSystemAddressForMdlSafe(m_TransferBufferMDL, NormalPagePriority);
|
||||
ASSERT(Buffer);
|
||||
|
||||
if (InternalGetPidDirection())
|
||||
{
|
||||
//
|
||||
// input direction
|
||||
//
|
||||
Direction = OHCI_TD_DIRECTION_PID_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// output direction
|
||||
//
|
||||
Direction = OHCI_TD_DIRECTION_PID_OUT;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
//
|
||||
// get current buffersize
|
||||
//
|
||||
CurrentSize = min(8192, BufferSize);
|
||||
|
||||
//
|
||||
// get page offset
|
||||
//
|
||||
MaxLengthInPage = PAGE_SIZE - BYTE_OFFSET(Buffer);
|
||||
|
||||
//
|
||||
// get minimum from current page size
|
||||
//
|
||||
CurrentSize = min(CurrentSize, MaxLengthInPage);
|
||||
ASSERT(CurrentSize);
|
||||
|
||||
//
|
||||
// allocate transfer descriptor
|
||||
//
|
||||
Status = CreateGeneralTransferDescriptor(&CurrentDescriptor, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to create transfer descriptor
|
||||
// TODO: cleanup
|
||||
//
|
||||
ASSERT(FALSE);
|
||||
m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
|
||||
FreeDescriptor(LastDescriptor);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize descriptor
|
||||
//
|
||||
CurrentDescriptor->Flags = Direction | OHCI_TD_BUFFER_ROUNDING | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) | OHCI_TD_TOGGLE_CARRY;
|
||||
|
||||
//
|
||||
// store physical address of buffer
|
||||
//
|
||||
CurrentDescriptor->BufferPhysical = MmGetPhysicalAddress(Buffer).LowPart;
|
||||
CurrentDescriptor->LastPhysicalByteAddress = CurrentDescriptor->BufferPhysical + CurrentSize - 1;
|
||||
|
||||
//
|
||||
// is there a previous descriptor
|
||||
//
|
||||
if (PreviousDescriptor)
|
||||
{
|
||||
//
|
||||
// link descriptors
|
||||
//
|
||||
PreviousDescriptor->NextLogicalDescriptor = (PVOID)CurrentDescriptor;
|
||||
PreviousDescriptor->NextPhysicalDescriptor = CurrentDescriptor->PhysicalAddress.LowPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// it is the first descriptor
|
||||
//
|
||||
FirstDescriptor = CurrentDescriptor;
|
||||
}
|
||||
|
||||
DPRINT("PreviousDescriptor %p CurrentDescriptor %p Buffer Logical %p Physical %x Last Physical %x CurrentSize %lu\n", PreviousDescriptor, CurrentDescriptor, CurrentDescriptor->BufferLogical, CurrentDescriptor->BufferPhysical, CurrentDescriptor->LastPhysicalByteAddress, CurrentSize);
|
||||
|
||||
//
|
||||
// set previous descriptor
|
||||
//
|
||||
PreviousDescriptor = CurrentDescriptor;
|
||||
|
||||
//
|
||||
// subtract buffer size
|
||||
//
|
||||
BufferSize -= CurrentSize;
|
||||
|
||||
//
|
||||
// increment buffer offset
|
||||
//
|
||||
Buffer = (PVOID)((ULONG_PTR)Buffer + CurrentSize);
|
||||
|
||||
}while(BufferSize);
|
||||
|
||||
//
|
||||
// first descriptor has no carry bit
|
||||
//
|
||||
FirstDescriptor->Flags &= ~OHCI_TD_TOGGLE_CARRY;
|
||||
|
||||
//
|
||||
// fixme: toggle
|
||||
//
|
||||
FirstDescriptor->Flags |= OHCI_TD_TOGGLE_0;
|
||||
|
||||
//
|
||||
// clear interrupt mask for last transfer descriptor
|
||||
//
|
||||
CurrentDescriptor->Flags &= ~OHCI_TD_INTERRUPT_MASK;
|
||||
|
||||
//
|
||||
// fire interrupt as soon transfer is finished
|
||||
//
|
||||
CurrentDescriptor->Flags |= OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
|
||||
|
||||
//
|
||||
// link last data descriptor to last descriptor
|
||||
//
|
||||
CurrentDescriptor->NextLogicalDescriptor = LastDescriptor;
|
||||
CurrentDescriptor->NextPhysicalDescriptor = LastDescriptor->PhysicalAddress.LowPart;
|
||||
|
||||
//
|
||||
// now link descriptor to endpoint
|
||||
//
|
||||
EndpointDescriptor->HeadPhysicalDescriptor = FirstDescriptor->PhysicalAddress.LowPart;
|
||||
EndpointDescriptor->TailPhysicalDescriptor = LastDescriptor->PhysicalAddress.LowPart;
|
||||
EndpointDescriptor->HeadLogicalDescriptor = FirstDescriptor;
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
*OutEndpointDescriptor = EndpointDescriptor;
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CUSBRequest::BuildControlTransferDescriptor(
|
||||
POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor)
|
||||
|
@ -639,8 +859,6 @@ CUSBRequest::BuildControlTransferDescriptor(
|
|||
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT1("CUSBRequest::BuildControlTransferDescriptor\n");
|
||||
|
||||
//
|
||||
// allocate endpoint descriptor
|
||||
//
|
||||
|
@ -695,7 +913,6 @@ CUSBRequest::BuildControlTransferDescriptor(
|
|||
return Status;
|
||||
}
|
||||
|
||||
|
||||
if (m_TransferBufferLength)
|
||||
{
|
||||
//
|
||||
|
@ -729,6 +946,7 @@ CUSBRequest::BuildControlTransferDescriptor(
|
|||
//
|
||||
DataDescriptor->BufferPhysical = MmGetPhysicalAddress(MmGetMdlVirtualAddress(m_TransferBufferMDL)).LowPart;
|
||||
DataDescriptor->LastPhysicalByteAddress = DataDescriptor->BufferPhysical + m_TransferBufferLength - 1;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -849,12 +1067,8 @@ CUSBRequest::GetEndpointDescriptor(
|
|||
Status = BuildControlTransferDescriptor((POHCI_ENDPOINT_DESCRIPTOR*)OutDescriptor);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
DPRINT1("USB_ENDPOINT_TYPE_BULK not implemented\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED; //BuildBulkTransferQueueHead(OutDescriptor);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
DPRINT1("USB_ENDPOINT_TYPE_INTERRUPT not implemented\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
Status = BuildBulkInterruptEndpoint(OutDescriptor);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_ISOCHRONOUS:
|
||||
DPRINT1("USB_ENDPOINT_TYPE_ISOCHRONOUS not implemented\n");
|
||||
|
@ -919,32 +1133,24 @@ CUSBRequest::GetResultStatus(
|
|||
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CUSBRequest::CompletionCallback(
|
||||
CUSBRequest::FreeEndpointDescriptor(
|
||||
struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor)
|
||||
{
|
||||
POHCI_GENERAL_TD TransferDescriptor, NextTransferDescriptor;
|
||||
|
||||
DPRINT1("CUSBRequest::CompletionCallback\n");
|
||||
|
||||
//
|
||||
// set status code
|
||||
//
|
||||
m_NtStatusCode = STATUS_SUCCESS;
|
||||
m_UrbStatusCode = USBD_STATUS_SUCCESS;
|
||||
|
||||
ASSERT(!m_Irp);
|
||||
|
||||
//
|
||||
// FIXME: cleanup descriptors
|
||||
//
|
||||
DPRINT("CUSBRequest::FreeEndpointDescriptor EndpointDescriptor %p Logical %x\n", OutDescriptor, OutDescriptor->PhysicalAddress.LowPart);
|
||||
|
||||
//
|
||||
// get first general transfer descriptor
|
||||
//
|
||||
TransferDescriptor = (POHCI_GENERAL_TD)OutDescriptor->HeadLogicalDescriptor;
|
||||
|
||||
//
|
||||
// release endpoint descriptor
|
||||
//
|
||||
m_DmaManager->Release(OutDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
|
||||
|
||||
while(TransferDescriptor)
|
||||
{
|
||||
//
|
||||
|
@ -963,6 +1169,8 @@ CUSBRequest::CompletionCallback(
|
|||
m_DmaManager->Release(TransferDescriptor->BufferLogical, TransferDescriptor->BufferSize);
|
||||
}
|
||||
|
||||
DPRINT("CUSBRequest::FreeEndpointDescriptor Descriptor %p Logical %x Buffer Physical %x EndAddress %x\n", TransferDescriptor, TransferDescriptor->PhysicalAddress.LowPart, TransferDescriptor->BufferPhysical, TransferDescriptor->LastPhysicalByteAddress);
|
||||
|
||||
//
|
||||
// release descriptor
|
||||
//
|
||||
|
@ -974,16 +1182,75 @@ CUSBRequest::CompletionCallback(
|
|||
TransferDescriptor = NextTransferDescriptor;
|
||||
}
|
||||
|
||||
//
|
||||
// release endpoint descriptor
|
||||
//
|
||||
m_DmaManager->Release(OutDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
|
||||
}
|
||||
|
||||
VOID
|
||||
CUSBRequest::CompletionCallback(
|
||||
struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor)
|
||||
{
|
||||
POHCI_GENERAL_TD TransferDescriptor, NextTransferDescriptor;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PURB Urb;
|
||||
|
||||
DPRINT("CUSBRequest::CompletionCallback Descriptor %p PhysicalAddress %x\n", OutDescriptor, OutDescriptor->PhysicalAddress.LowPart);
|
||||
|
||||
//
|
||||
// signal completion event
|
||||
// set status code
|
||||
//
|
||||
PC_ASSERT(m_CompletionEvent);
|
||||
KeSetEvent(m_CompletionEvent, 0, FALSE);
|
||||
m_NtStatusCode = STATUS_SUCCESS;
|
||||
m_UrbStatusCode = USBD_STATUS_SUCCESS;
|
||||
|
||||
if (m_Irp)
|
||||
{
|
||||
//
|
||||
// set irp completion status
|
||||
//
|
||||
m_Irp->IoStatus.Status = STATUS_SUCCESS; //FIXME
|
||||
|
||||
//
|
||||
// get current irp stack location
|
||||
//
|
||||
IoStack = IoGetCurrentIrpStackLocation(m_Irp);
|
||||
|
||||
//
|
||||
// get urb
|
||||
//
|
||||
Urb = (PURB)IoStack->Parameters.Others.Argument1;
|
||||
|
||||
//
|
||||
// store urb status
|
||||
//
|
||||
Urb->UrbHeader.Status = USBD_STATUS_SUCCESS; //FIXME
|
||||
|
||||
//
|
||||
// Check if the MDL was created
|
||||
//
|
||||
if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
|
||||
{
|
||||
//
|
||||
// Free Mdl
|
||||
//
|
||||
IoFreeMdl(m_TransferBufferMDL);
|
||||
}
|
||||
|
||||
//
|
||||
// FIXME: support status and calculate length
|
||||
//
|
||||
|
||||
//
|
||||
// FIXME: check if the transfer was split
|
||||
// if yes dont complete irp yet
|
||||
//
|
||||
IoCompleteRequest(m_Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// signal completion event
|
||||
//
|
||||
PC_ASSERT(m_CompletionEvent);
|
||||
KeSetEvent(m_CompletionEvent, 0, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue