mirror of
https://github.com/reactos/reactos.git
synced 2024-07-31 00:28:56 +00:00
[USBOHCI]
- Fix OHCI_ISO_TD structure. Fixes host system crashes in Windows XP - Fix multiple bugs in isochronous transfer implementation - Still not yet working, as the interrupt completion is not fired yet svn path=/branches/usb-bringup/; revision=51998
This commit is contained in:
parent
2231c8333a
commit
d2accc6c3e
|
@ -310,13 +310,22 @@ typedef struct _OHCI_ISO_TD_
|
||||||
ULONG BufferPhysical; // Physical page number of byte 0
|
ULONG BufferPhysical; // Physical page number of byte 0
|
||||||
ULONG NextPhysicalDescriptor; // Next isochronous transfer descriptor
|
ULONG NextPhysicalDescriptor; // Next isochronous transfer descriptor
|
||||||
ULONG LastPhysicalByteAddress; // Physical buffer end
|
ULONG LastPhysicalByteAddress; // Physical buffer end
|
||||||
ULONG Offset[OHCI_ITD_NOFFSET]; // Buffer offsets
|
USHORT Offset[OHCI_ITD_NOFFSET]; // Buffer offsets
|
||||||
|
|
||||||
// Software part
|
// Software part
|
||||||
PHYSICAL_ADDRESS PhysicalAddress; // Physical address of this descriptor
|
PHYSICAL_ADDRESS PhysicalAddress; // Physical address of this descriptor
|
||||||
struct _OHCI_ISO_TD_ * NextLogicalDescriptor; // Logical pointer next descriptor
|
struct _OHCI_ISO_TD_ * NextLogicalDescriptor; // Logical pointer next descriptor
|
||||||
}OHCI_ISO_TD, *POHCI_ISO_TD;
|
}OHCI_ISO_TD, *POHCI_ISO_TD;
|
||||||
|
|
||||||
|
C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, Flags) == 0);
|
||||||
|
C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, BufferPhysical) == 4);
|
||||||
|
C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, NextPhysicalDescriptor) == 8);
|
||||||
|
C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, LastPhysicalByteAddress) == 12);
|
||||||
|
C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, Offset) == 16);
|
||||||
|
C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, PhysicalAddress) == 32);
|
||||||
|
C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, NextLogicalDescriptor) == 40);
|
||||||
|
C_ASSERT(sizeof(OHCI_ISO_TD) == 48);
|
||||||
|
|
||||||
#define OHCI_ITD_GET_STARTING_FRAME(x) ((x) & 0x0000ffff)
|
#define OHCI_ITD_GET_STARTING_FRAME(x) ((x) & 0x0000ffff)
|
||||||
#define OHCI_ITD_SET_STARTING_FRAME(x) ((x) & 0xffff)
|
#define OHCI_ITD_SET_STARTING_FRAME(x) ((x) & 0xffff)
|
||||||
#define OHCI_ITD_GET_DELAY_INTERRUPT(x) (((x) >> 21) & 7)
|
#define OHCI_ITD_GET_DELAY_INTERRUPT(x) (((x) >> 21) & 7)
|
||||||
|
|
|
@ -43,8 +43,10 @@ public:
|
||||||
|
|
||||||
// local functions
|
// local functions
|
||||||
BOOLEAN IsTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress);
|
BOOLEAN IsTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress);
|
||||||
|
BOOLEAN IsTransferDescriptorInIsoEndpoint(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);
|
NTSTATUS FindTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress, OUT POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR *OutPreviousEndpointDescriptor);
|
||||||
NTSTATUS FindTransferDescriptorInInterruptHeadEndpoints(IN ULONG TransferDescriptorLogicalAddress, OUT POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR *OutPreviousEndpointDescriptor);
|
NTSTATUS FindTransferDescriptorInInterruptHeadEndpoints(IN ULONG TransferDescriptorLogicalAddress, OUT POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR *OutPreviousEndpointDescriptor);
|
||||||
|
NTSTATUS FindTransferDescriptorInIsochronousHeadEndpoints(IN ULONG TransferDescriptorLogicalAddress, OUT POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR *OutPreviousEndpointDescriptor);
|
||||||
|
|
||||||
VOID CleanupEndpointDescriptor(POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, POHCI_ENDPOINT_DESCRIPTOR PreviousEndpointDescriptor);
|
VOID CleanupEndpointDescriptor(POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, POHCI_ENDPOINT_DESCRIPTOR PreviousEndpointDescriptor);
|
||||||
POHCI_ENDPOINT_DESCRIPTOR FindInterruptEndpointDescriptor(UCHAR InterruptInterval);
|
POHCI_ENDPOINT_DESCRIPTOR FindInterruptEndpointDescriptor(UCHAR InterruptInterval);
|
||||||
|
@ -101,6 +103,8 @@ CUSBQueue::Initialize(
|
||||||
//
|
//
|
||||||
Hardware->GetControlHeadEndpointDescriptor(&m_ControlHeadEndpointDescriptor);
|
Hardware->GetControlHeadEndpointDescriptor(&m_ControlHeadEndpointDescriptor);
|
||||||
|
|
||||||
|
//
|
||||||
|
// get isochronous endpoint
|
||||||
//
|
//
|
||||||
Hardware->GetIsochronousHeadEndpointDescriptor(&m_IsoHeadEndpointDescriptor);
|
Hardware->GetIsochronousHeadEndpointDescriptor(&m_IsoHeadEndpointDescriptor);
|
||||||
|
|
||||||
|
@ -170,6 +174,7 @@ CUSBQueue::AddUSBRequest(
|
||||||
POHCI_ENDPOINT_DESCRIPTOR Descriptor;
|
POHCI_ENDPOINT_DESCRIPTOR Descriptor;
|
||||||
POHCI_ISO_TD CurrentDescriptor;
|
POHCI_ISO_TD CurrentDescriptor;
|
||||||
ULONG FrameNumber;
|
ULONG FrameNumber;
|
||||||
|
USHORT Frame;
|
||||||
|
|
||||||
DPRINT("CUSBQueue::AddUSBRequest\n");
|
DPRINT("CUSBQueue::AddUSBRequest\n");
|
||||||
|
|
||||||
|
@ -244,9 +249,9 @@ CUSBQueue::AddUSBRequest(
|
||||||
m_Hardware->GetCurrentFrameNumber(&FrameNumber);
|
m_Hardware->GetCurrentFrameNumber(&FrameNumber);
|
||||||
|
|
||||||
//
|
//
|
||||||
// increment frame number
|
// FIXME: increment frame number
|
||||||
//
|
//
|
||||||
FrameNumber++;
|
FrameNumber += 300;
|
||||||
|
|
||||||
//
|
//
|
||||||
// apply frame number to iso transfer descriptors
|
// apply frame number to iso transfer descriptors
|
||||||
|
@ -254,18 +259,19 @@ CUSBQueue::AddUSBRequest(
|
||||||
CurrentDescriptor = (POHCI_ISO_TD)Descriptor->HeadLogicalDescriptor;
|
CurrentDescriptor = (POHCI_ISO_TD)Descriptor->HeadLogicalDescriptor;
|
||||||
|
|
||||||
DPRINT1("ISO: NextFrameNumber %x\n", FrameNumber);
|
DPRINT1("ISO: NextFrameNumber %x\n", FrameNumber);
|
||||||
|
Frame = (FrameNumber & 0xFFFF);
|
||||||
|
|
||||||
while(CurrentDescriptor)
|
while(CurrentDescriptor)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// set current frame number
|
// set current frame number
|
||||||
//
|
//
|
||||||
CurrentDescriptor->Flags |= OHCI_ITD_SET_STARTING_FRAME(FrameNumber);
|
CurrentDescriptor->Flags |= OHCI_ITD_SET_STARTING_FRAME(Frame);
|
||||||
|
|
||||||
//
|
//
|
||||||
// move to next frame number
|
// move to next frame number
|
||||||
//
|
//
|
||||||
FrameNumber++;
|
Frame += OHCI_ITD_GET_FRAME_COUNT(CurrentDescriptor->Flags);
|
||||||
|
|
||||||
//
|
//
|
||||||
// move to next descriptor
|
// move to next descriptor
|
||||||
|
@ -274,16 +280,16 @@ CUSBQueue::AddUSBRequest(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// insert endpoint at end
|
|
||||||
//
|
|
||||||
LinkEndpoint(HeadDescriptor, Descriptor);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// set descriptor active
|
// set descriptor active
|
||||||
//
|
//
|
||||||
Descriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
|
Descriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
|
||||||
|
|
||||||
|
//
|
||||||
|
// insert endpoint at end
|
||||||
|
//
|
||||||
|
LinkEndpoint(HeadDescriptor, Descriptor);
|
||||||
|
|
||||||
if (Type == USB_ENDPOINT_TYPE_CONTROL || Type == USB_ENDPOINT_TYPE_BULK)
|
if (Type == USB_ENDPOINT_TYPE_CONTROL || Type == USB_ENDPOINT_TYPE_BULK)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -402,6 +408,97 @@ CUSBQueue::FindTransferDescriptorInInterruptHeadEndpoints(IN ULONG TransferDescr
|
||||||
return STATUS_NOT_FOUND;
|
return STATUS_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CUSBQueue::FindTransferDescriptorInIsochronousHeadEndpoints(
|
||||||
|
IN ULONG TransferDescriptorLogicalAddress,
|
||||||
|
OUT POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor,
|
||||||
|
OUT POHCI_ENDPOINT_DESCRIPTOR *OutPreviousEndpointDescriptor)
|
||||||
|
{
|
||||||
|
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
|
||||||
|
POHCI_ENDPOINT_DESCRIPTOR LastDescriptor = m_IsoHeadEndpointDescriptor;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// skip first endpoint head
|
||||||
|
//
|
||||||
|
EndpointDescriptor = (POHCI_ENDPOINT_DESCRIPTOR)m_IsoHeadEndpointDescriptor->NextDescriptor;
|
||||||
|
|
||||||
|
while(EndpointDescriptor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// check if the transfer descriptor is inside the list
|
||||||
|
//
|
||||||
|
if (IsTransferDescriptorInIsoEndpoint(EndpointDescriptor, TransferDescriptorLogicalAddress))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// found endpoint
|
||||||
|
//
|
||||||
|
*OutEndpointDescriptor = EndpointDescriptor;
|
||||||
|
*OutPreviousEndpointDescriptor = LastDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// store last endpoint
|
||||||
|
//
|
||||||
|
LastDescriptor = EndpointDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next
|
||||||
|
//
|
||||||
|
EndpointDescriptor = (POHCI_ENDPOINT_DESCRIPTOR)EndpointDescriptor->NextDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// failed to endpoint
|
||||||
|
//
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
CUSBQueue::IsTransferDescriptorInIsoEndpoint(
|
||||||
|
IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor,
|
||||||
|
IN ULONG TransferDescriptorLogicalAddress)
|
||||||
|
{
|
||||||
|
POHCI_ISO_TD Descriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get first general transfer descriptor
|
||||||
|
//
|
||||||
|
Descriptor = (POHCI_ISO_TD)EndpointDescriptor->HeadLogicalDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
ASSERT(Descriptor);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (Descriptor->PhysicalAddress.LowPart == TransferDescriptorLogicalAddress)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// found descriptor
|
||||||
|
//
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next
|
||||||
|
//
|
||||||
|
Descriptor = (POHCI_ISO_TD)Descriptor->NextLogicalDescriptor;
|
||||||
|
}while(Descriptor);
|
||||||
|
|
||||||
|
//
|
||||||
|
// no descriptor found
|
||||||
|
//
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
CUSBQueue::IsTransferDescriptorInEndpoint(
|
CUSBQueue::IsTransferDescriptorInEndpoint(
|
||||||
IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor,
|
IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor,
|
||||||
|
@ -476,6 +573,8 @@ CUSBQueue::CleanupEndpointDescriptor(
|
||||||
//
|
//
|
||||||
//ASSERT(Request->IsRequestComplete());
|
//ASSERT(Request->IsRequestComplete());
|
||||||
|
|
||||||
|
Request->FreeEndpointDescriptor(EndpointDescriptor);
|
||||||
|
|
||||||
//
|
//
|
||||||
// release request
|
// release request
|
||||||
//
|
//
|
||||||
|
@ -511,7 +610,7 @@ CUSBQueue::TransferDescriptorCompletionCallback(
|
||||||
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, PreviousEndpointDescriptor;
|
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, PreviousEndpointDescriptor;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("CUSBQueue::TransferDescriptorCompletionCallback transfer descriptor %x\n", TransferDescriptorLogicalAddress);
|
DPRINT1("CUSBQueue::TransferDescriptorCompletionCallback transfer descriptor %x\n", TransferDescriptorLogicalAddress);
|
||||||
|
|
||||||
//
|
//
|
||||||
// find transfer descriptor in control list
|
// find transfer descriptor in control list
|
||||||
|
@ -564,13 +663,30 @@ CUSBQueue::TransferDescriptorCompletionCallback(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// last try: find the descriptor in isochronous list
|
||||||
|
//
|
||||||
|
Status = FindTransferDescriptorInIsochronousHeadEndpoints(TransferDescriptorLogicalAddress, &EndpointDescriptor, &PreviousEndpointDescriptor);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// cleanup endpoint
|
||||||
|
//
|
||||||
|
DPRINT1("ISO endpoint complete\n");
|
||||||
|
ASSERT(FALSE);
|
||||||
|
CleanupEndpointDescriptor(EndpointDescriptor, PreviousEndpointDescriptor);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// hardware reported dead endpoint completed
|
// hardware reported dead endpoint completed
|
||||||
//
|
//
|
||||||
DPRINT("CUSBQueue::TransferDescriptorCompletionCallback invalid transfer descriptor %x\n", TransferDescriptorLogicalAddress);
|
DPRINT1("CUSBQueue::TransferDescriptorCompletionCallback invalid transfer descriptor %x\n", TransferDescriptorLogicalAddress);
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
POHCI_ENDPOINT_DESCRIPTOR
|
POHCI_ENDPOINT_DESCRIPTOR
|
||||||
|
|
|
@ -656,13 +656,12 @@ CUSBRequest::BuildIsochronousEndpoint(
|
||||||
{
|
{
|
||||||
POHCI_ISO_TD FirstDescriptor, PreviousDescriptor = NULL, CurrentDescriptor;
|
POHCI_ISO_TD FirstDescriptor, PreviousDescriptor = NULL, CurrentDescriptor;
|
||||||
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
|
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
|
||||||
ULONG Index = 0, SubIndex, NumberOfPackets, PageOffset;
|
ULONG Index = 0, SubIndex, NumberOfPackets, PageOffset, Page;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PURB Urb;
|
PURB Urb;
|
||||||
|
|
||||||
DPRINT1("cp\n");
|
|
||||||
//
|
//
|
||||||
// get current irp stack location
|
// get current irp stack location
|
||||||
//
|
//
|
||||||
|
@ -690,23 +689,27 @@ CUSBRequest::BuildIsochronousEndpoint(
|
||||||
//
|
//
|
||||||
// failed to create setup descriptor
|
// failed to create setup descriptor
|
||||||
//
|
//
|
||||||
|
ASSERT(FALSE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
DPRINT1("cp\n");
|
|
||||||
//
|
//
|
||||||
// get buffer
|
// get buffer
|
||||||
//
|
//
|
||||||
Buffer = MmGetSystemAddressForMdlSafe(m_TransferBufferMDL, NormalPagePriority);
|
Buffer = MmGetSystemAddressForMdlSafe(m_TransferBufferMDL, NormalPagePriority);
|
||||||
ASSERT(Buffer);
|
ASSERT(Buffer);
|
||||||
|
|
||||||
DPRINT1("cp\n");
|
//
|
||||||
|
// FIXME: support requests which spans serveral pages
|
||||||
|
//
|
||||||
|
ASSERT(ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(m_TransferBufferMDL), MmGetMdlByteCount(m_TransferBufferMDL)) <= 2);
|
||||||
|
|
||||||
while(Index < Urb->UrbIsochronousTransfer.NumberOfPackets)
|
while(Index < Urb->UrbIsochronousTransfer.NumberOfPackets)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// get number of packets remaining
|
// get number of packets remaining
|
||||||
//
|
//
|
||||||
NumberOfPackets = min(Urb->UrbIsochronousTransfer.NumberOfPackets - Index, OHCI_ITD_NOFFSET);
|
NumberOfPackets = min(Urb->UrbIsochronousTransfer.NumberOfPackets - Index, OHCI_ITD_NOFFSET);
|
||||||
DPRINT1("cp Number Packets %lu\n", NumberOfPackets);
|
|
||||||
//
|
//
|
||||||
// allocate iso descriptor
|
// allocate iso descriptor
|
||||||
//
|
//
|
||||||
|
@ -720,23 +723,29 @@ CUSBRequest::BuildIsochronousEndpoint(
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
DPRINT1("cp\n");
|
|
||||||
//
|
//
|
||||||
// initialize descriptor
|
// get physical page
|
||||||
//
|
//
|
||||||
CurrentDescriptor->BufferPhysical = (MmGetPhysicalAddress(Buffer).LowPart & ~ (PAGE_SIZE - 1));
|
Page = MmGetPhysicalAddress(Buffer).LowPart;
|
||||||
|
|
||||||
//
|
//
|
||||||
// get page offset
|
// get page offset
|
||||||
//
|
//
|
||||||
PageOffset = BYTE_OFFSET(MmGetPhysicalAddress(Buffer).LowPart);
|
PageOffset = MmGetMdlByteOffset(m_TransferBufferMDL);
|
||||||
DPRINT1("cp\n");
|
|
||||||
|
//
|
||||||
|
// initialize descriptor
|
||||||
|
//
|
||||||
|
CurrentDescriptor->BufferPhysical = Page - PageOffset;
|
||||||
|
|
||||||
for(SubIndex = 0; SubIndex < NumberOfPackets; SubIndex++)
|
for(SubIndex = 0; SubIndex < NumberOfPackets; SubIndex++)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// store buffer offset
|
// store buffer offset
|
||||||
//
|
//
|
||||||
CurrentDescriptor->Offset[SubIndex] = Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset + PageOffset;
|
CurrentDescriptor->Offset[SubIndex] = Urb->UrbIsochronousTransfer.IsoPacket[Index+SubIndex].Offset + PageOffset;
|
||||||
|
DPRINT1("Index %lu PacketOffset %lu FinalOffset %lu\n", SubIndex+Index, Urb->UrbIsochronousTransfer.IsoPacket[Index+SubIndex].Offset, CurrentDescriptor->Offset[SubIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -752,19 +761,14 @@ CUSBRequest::BuildIsochronousEndpoint(
|
||||||
//
|
//
|
||||||
// end of transfer
|
// end of transfer
|
||||||
//
|
//
|
||||||
CurrentDescriptor->LastPhysicalByteAddress = CurrentDescriptor->BufferPhysical + m_TransferBufferLength - 1;
|
CurrentDescriptor->LastPhysicalByteAddress = CurrentDescriptor->BufferPhysical + PageOffset + m_TransferBufferLength - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// use start address of next packet - 1
|
// use start address of next packet - 1
|
||||||
//
|
//
|
||||||
CurrentDescriptor->LastPhysicalByteAddress = CurrentDescriptor->BufferPhysical + PageOffset + Urb->UrbIsochronousTransfer.IsoPacket[Index + 1].Offset - 1;
|
CurrentDescriptor->LastPhysicalByteAddress = CurrentDescriptor->BufferPhysical + PageOffset + Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset - 1;
|
||||||
|
|
||||||
//
|
|
||||||
// move buffer to next address
|
|
||||||
//
|
|
||||||
Buffer = (PVOID)((ULONG_PTR)Buffer + Urb->UrbIsochronousTransfer.IsoPacket[Index + 1].Offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -790,8 +794,13 @@ CUSBRequest::BuildIsochronousEndpoint(
|
||||||
// store as previous descriptor
|
// store as previous descriptor
|
||||||
//
|
//
|
||||||
PreviousDescriptor = CurrentDescriptor;
|
PreviousDescriptor = CurrentDescriptor;
|
||||||
|
DPRINT1("Current Descriptor %p Logical %lx StartAddress %x EndAddress %x\n", CurrentDescriptor, CurrentDescriptor->PhysicalAddress.LowPart, CurrentDescriptor->BufferPhysical, CurrentDescriptor->LastPhysicalByteAddress);
|
||||||
|
|
||||||
|
//
|
||||||
|
// fire interrupt as soon transfer is finished
|
||||||
|
//
|
||||||
|
CurrentDescriptor->Flags |= OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE);
|
||||||
}
|
}
|
||||||
DPRINT1("cp\n");
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// clear interrupt mask for last transfer descriptor
|
// clear interrupt mask for last transfer descriptor
|
||||||
|
@ -814,7 +823,7 @@ CUSBRequest::BuildIsochronousEndpoint(
|
||||||
EndpointDescriptor->HeadPhysicalDescriptor = FirstDescriptor->PhysicalAddress.LowPart;
|
EndpointDescriptor->HeadPhysicalDescriptor = FirstDescriptor->PhysicalAddress.LowPart;
|
||||||
EndpointDescriptor->TailPhysicalDescriptor = CurrentDescriptor->PhysicalAddress.LowPart;
|
EndpointDescriptor->TailPhysicalDescriptor = CurrentDescriptor->PhysicalAddress.LowPart;
|
||||||
EndpointDescriptor->HeadLogicalDescriptor = FirstDescriptor;
|
EndpointDescriptor->HeadLogicalDescriptor = FirstDescriptor;
|
||||||
DPRINT1("cp\n");
|
|
||||||
//
|
//
|
||||||
// store result
|
// store result
|
||||||
//
|
//
|
||||||
|
@ -1451,48 +1460,95 @@ CUSBRequest::FreeEndpointDescriptor(
|
||||||
struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor)
|
struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor)
|
||||||
{
|
{
|
||||||
POHCI_GENERAL_TD TransferDescriptor, NextTransferDescriptor;
|
POHCI_GENERAL_TD TransferDescriptor, NextTransferDescriptor;
|
||||||
|
POHCI_ISO_TD IsoTransferDescriptor, IsoNextTransferDescriptor;
|
||||||
|
ULONG Index, PacketCount;
|
||||||
|
|
||||||
DPRINT("CUSBRequest::FreeEndpointDescriptor EndpointDescriptor %p Logical %x\n", OutDescriptor, OutDescriptor->PhysicalAddress.LowPart);
|
DPRINT("CUSBRequest::FreeEndpointDescriptor EndpointDescriptor %p Logical %x\n", OutDescriptor, OutDescriptor->PhysicalAddress.LowPart);
|
||||||
|
|
||||||
//
|
if (OutDescriptor->Flags & OHCI_ENDPOINT_ISOCHRONOUS_FORMAT)
|
||||||
// get first general transfer descriptor
|
|
||||||
//
|
|
||||||
TransferDescriptor = (POHCI_GENERAL_TD)OutDescriptor->HeadLogicalDescriptor;
|
|
||||||
|
|
||||||
//
|
|
||||||
// release endpoint descriptor
|
|
||||||
//
|
|
||||||
m_DmaManager->Release(OutDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
|
|
||||||
|
|
||||||
while(TransferDescriptor)
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// get next
|
// get first iso transfer descriptor
|
||||||
//
|
//
|
||||||
NextTransferDescriptor = (POHCI_GENERAL_TD)TransferDescriptor->NextLogicalDescriptor;
|
IsoTransferDescriptor = (POHCI_ISO_TD)OutDescriptor->HeadLogicalDescriptor;
|
||||||
|
|
||||||
//
|
//
|
||||||
// is there a buffer associated
|
// release endpoint descriptor
|
||||||
//
|
//
|
||||||
if (TransferDescriptor->BufferSize)
|
m_DmaManager->Release(OutDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
|
||||||
|
|
||||||
|
while(IsoTransferDescriptor)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// release buffer
|
// get next
|
||||||
//
|
//
|
||||||
m_DmaManager->Release(TransferDescriptor->BufferLogical, TransferDescriptor->BufferSize);
|
IsoNextTransferDescriptor = IsoTransferDescriptor->NextLogicalDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get packet count
|
||||||
|
//
|
||||||
|
PacketCount = OHCI_ITD_GET_FRAME_COUNT(IsoTransferDescriptor->Flags);
|
||||||
|
|
||||||
|
DPRINT1("CUSBRequest::FreeEndpointDescriptor Descriptor %p Logical %x Buffer Physical %x EndAddress %x PacketCount %lu\n", IsoTransferDescriptor, IsoTransferDescriptor->PhysicalAddress.LowPart, IsoTransferDescriptor->BufferPhysical, IsoTransferDescriptor->LastPhysicalByteAddress, PacketCount);
|
||||||
|
|
||||||
|
for(Index = 0; Index < PacketCount; Index++)
|
||||||
|
{
|
||||||
|
DPRINT1("PSW Index %lu Value %x\n", Index, IsoTransferDescriptor->Offset[Index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// release descriptor
|
||||||
|
//
|
||||||
|
m_DmaManager->Release(IsoTransferDescriptor, sizeof(OHCI_ISO_TD));
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next
|
||||||
|
//
|
||||||
|
IsoTransferDescriptor = IsoNextTransferDescriptor;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
DPRINT("CUSBRequest::FreeEndpointDescriptor Descriptor %p Logical %x Buffer Physical %x EndAddress %x\n", TransferDescriptor, TransferDescriptor->PhysicalAddress.LowPart, TransferDescriptor->BufferPhysical, TransferDescriptor->LastPhysicalByteAddress);
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// get first general transfer descriptor
|
||||||
|
//
|
||||||
|
TransferDescriptor = (POHCI_GENERAL_TD)OutDescriptor->HeadLogicalDescriptor;
|
||||||
|
|
||||||
//
|
//
|
||||||
// release descriptor
|
// release endpoint descriptor
|
||||||
//
|
//
|
||||||
m_DmaManager->Release(TransferDescriptor, sizeof(OHCI_GENERAL_TD));
|
m_DmaManager->Release(OutDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
|
||||||
|
|
||||||
//
|
while(TransferDescriptor)
|
||||||
// move to next
|
{
|
||||||
//
|
//
|
||||||
TransferDescriptor = NextTransferDescriptor;
|
// get next
|
||||||
|
//
|
||||||
|
NextTransferDescriptor = (POHCI_GENERAL_TD)TransferDescriptor->NextLogicalDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// is there a buffer associated
|
||||||
|
//
|
||||||
|
if (TransferDescriptor->BufferSize)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// release buffer
|
||||||
|
//
|
||||||
|
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
|
||||||
|
//
|
||||||
|
m_DmaManager->Release(TransferDescriptor, sizeof(OHCI_GENERAL_TD));
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next
|
||||||
|
//
|
||||||
|
TransferDescriptor = NextTransferDescriptor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue