mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 11:21:51 +00:00
[USBEHCI_NEW]
- Port URB_FUNCTION_CLASS_INTERFACE from mjmartin usbehci driver - Fix typo in interface declaration - Disable assert for now - Return irp status pending when irp is added to the queue - Fix bug in InternalGetPidDirection - More work on the bulk transfers, not yet working svn path=/branches/usb-bringup/; revision=51501
This commit is contained in:
parent
bdfaf318b8
commit
547ea14508
5 changed files with 265 additions and 42 deletions
|
@ -65,6 +65,7 @@ public:
|
||||||
NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb);
|
NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb);
|
||||||
NTSTATUS HandleSelectInterface(IN OUT PIRP Irp, PURB Urb);
|
NTSTATUS HandleSelectInterface(IN OUT PIRP Irp, PURB Urb);
|
||||||
NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
|
NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
|
||||||
|
NTSTATUS HandleClassInterface(IN OUT PIRP Irp, PURB Urb);
|
||||||
NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
|
NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
|
||||||
|
|
||||||
friend VOID StatusChangeEndpointCallBack(PVOID Context);
|
friend VOID StatusChangeEndpointCallBack(PVOID Context);
|
||||||
|
@ -1362,6 +1363,70 @@ CHubController::HandleGetDescriptor(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::HandleClassInterface(
|
||||||
|
IN OUT PIRP Irp,
|
||||||
|
IN OUT PURB Urb)
|
||||||
|
{
|
||||||
|
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PUSBDEVICE UsbDevice;
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
|
||||||
|
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength);
|
||||||
|
PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
|
||||||
|
|
||||||
|
//
|
||||||
|
// check if this is a valid usb device handle
|
||||||
|
//
|
||||||
|
PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device
|
||||||
|
//
|
||||||
|
UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
|
||||||
|
|
||||||
|
|
||||||
|
DPRINT1("URB_FUNCTION_CLASS_INTERFACE\n");
|
||||||
|
DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
|
||||||
|
DPRINT1("TransferBufferLength %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength);
|
||||||
|
DPRINT1("TransferBuffer %x\n", Urb->UrbControlVendorClassRequest.TransferBuffer);
|
||||||
|
DPRINT1("TransferBufferMDL %x\n", Urb->UrbControlVendorClassRequest.TransferBufferMDL);
|
||||||
|
DPRINT1("RequestTypeReservedBits %x\n", Urb->UrbControlVendorClassRequest.RequestTypeReservedBits);
|
||||||
|
DPRINT1("Request %x\n", Urb->UrbControlVendorClassRequest.Request);
|
||||||
|
DPRINT1("Value %x\n", Urb->UrbControlVendorClassRequest.Value);
|
||||||
|
DPRINT1("Index %x\n", Urb->UrbControlVendorClassRequest.Index);
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize setup packet
|
||||||
|
//
|
||||||
|
CtrlSetup.bmRequestType.B = 0xa1; //FIXME: Const.
|
||||||
|
CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
|
||||||
|
CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
|
||||||
|
CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
|
||||||
|
CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// issue request
|
||||||
|
//
|
||||||
|
Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// assert on failure
|
||||||
|
//
|
||||||
|
PC_ASSERT(NT_SUCCESS(Status));
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CHubController::HandleDeviceControl(
|
CHubController::HandleDeviceControl(
|
||||||
|
@ -1419,6 +1484,9 @@ CHubController::HandleDeviceControl(
|
||||||
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
|
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
|
||||||
Status = HandleBulkOrInterruptTransfer(Irp, Urb);
|
Status = HandleBulkOrInterruptTransfer(Irp, Urb);
|
||||||
break;
|
break;
|
||||||
|
case URB_FUNCTION_CLASS_INTERFACE:
|
||||||
|
Status = HandleClassInterface(Irp, Urb);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
|
DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -785,7 +785,7 @@ DECLARE_INTERFACE_(IUSBDevice, IUnknown)
|
||||||
//
|
//
|
||||||
// Description: submits an irp containing an urb
|
// Description: submits an irp containing an urb
|
||||||
|
|
||||||
virtual NTSTATUS SubmitIrp(PIRP Urb) = 0;
|
virtual NTSTATUS SubmitIrp(PIRP Irp) = 0;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
|
|
@ -136,7 +136,7 @@ CDMAMemoryManager::Allocate(
|
||||||
// sanity checks
|
// sanity checks
|
||||||
//
|
//
|
||||||
ASSERT(Size < PAGE_SIZE);
|
ASSERT(Size < PAGE_SIZE);
|
||||||
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
//ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||||
|
|
||||||
//
|
//
|
||||||
// align request
|
// align request
|
||||||
|
|
|
@ -483,6 +483,11 @@ CUSBDevice::CommitIrp(
|
||||||
//
|
//
|
||||||
Status = Request->InitializeWithIrp(m_DmaManager, Irp);
|
Status = Request->InitializeWithIrp(m_DmaManager, Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// mark irp as pending
|
||||||
|
//
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
|
|
||||||
//
|
//
|
||||||
// now add the request
|
// now add the request
|
||||||
//
|
//
|
||||||
|
@ -500,7 +505,7 @@ CUSBDevice::CommitIrp(
|
||||||
//
|
//
|
||||||
// done
|
// done
|
||||||
//
|
//
|
||||||
return Status;
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------
|
||||||
|
@ -1199,6 +1204,16 @@ CUSBDevice::SelectInterface(
|
||||||
//
|
//
|
||||||
// copy pipe handle
|
// copy pipe handle
|
||||||
//
|
//
|
||||||
|
DPRINT1("PipeIndex %lu\n", PipeIndex);
|
||||||
|
DPRINT1("EndpointAddress %x\n", InterfaceInfo->Pipes[PipeIndex].EndpointAddress);
|
||||||
|
DPRINT1("Interval %d\n", InterfaceInfo->Pipes[PipeIndex].Interval);
|
||||||
|
DPRINT1("MaximumPacketSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize);
|
||||||
|
DPRINT1("MaximumTransferSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumTransferSize);
|
||||||
|
DPRINT1("PipeFlags %d\n", InterfaceInfo->Pipes[PipeIndex].PipeFlags);
|
||||||
|
DPRINT1("PipeType %dd\n", InterfaceInfo->Pipes[PipeIndex].PipeType);
|
||||||
|
DPRINT1("UsbEndPoint %x\n", Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress);
|
||||||
|
PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress == InterfaceInfo->Pipes[PipeIndex].EndpointAddress);
|
||||||
|
|
||||||
InterfaceInfo->Pipes[PipeIndex].PipeHandle = &Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor;
|
InterfaceInfo->Pipes[PipeIndex].PipeHandle = &Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor;
|
||||||
|
|
||||||
if (Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes & (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT))
|
if (Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes & (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT))
|
||||||
|
|
|
@ -371,6 +371,8 @@ CUSBRequest::CompletionCallback(
|
||||||
Urb->UrbHeader.Length = 0;
|
Urb->UrbHeader.Length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT1("Request %p Completing Irp %p NtStatusCode %x UrbStatusCode %x\n", this, m_Irp, NtStatusCode, UrbStatusCode);
|
||||||
|
|
||||||
//
|
//
|
||||||
// FIXME: check if the transfer was split
|
// FIXME: check if the transfer was split
|
||||||
// if yes dont complete irp yet
|
// if yes dont complete irp yet
|
||||||
|
@ -604,9 +606,9 @@ CUSBRequest::InternalGetPidDirection()
|
||||||
EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
|
EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
|
||||||
|
|
||||||
//
|
//
|
||||||
// end point is defined in the low byte of bmAttributes
|
// end point is defined in the low byte of bEndpointAddress
|
||||||
//
|
//
|
||||||
return (EndpointDescriptor->bmAttributes & USB_ENDPOINT_DIRECTION_MASK);
|
return (EndpointDescriptor->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------
|
||||||
|
@ -779,8 +781,11 @@ CUSBRequest::BuildBulkTransferQueueHead(
|
||||||
PQUEUE_HEAD * OutHead)
|
PQUEUE_HEAD * OutHead)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG NumTransferDescriptors, TransferBufferRounded, NumPages, Index, FailIndex;
|
|
||||||
PQUEUE_HEAD QueueHead;
|
PQUEUE_HEAD QueueHead;
|
||||||
|
ULONG TransferDescriptorCount, Index;
|
||||||
|
ULONG BytesAvailable, BufferIndex;
|
||||||
|
PVOID Base;
|
||||||
|
ULONG PageOffset;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate the queue head
|
// Allocate the queue head
|
||||||
|
@ -801,38 +806,33 @@ CUSBRequest::BuildBulkTransferQueueHead(
|
||||||
PC_ASSERT(QueueHead);
|
PC_ASSERT(QueueHead);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Determine number of transfer descriptors needed. Max size is 3 * 5 Pages
|
// FIXME: support more than one descriptor
|
||||||
// FIXME: Do we need anything bigger?
|
|
||||||
//
|
//
|
||||||
TransferBufferRounded = ROUND_TO_PAGES(m_TransferBufferLength);
|
PC_ASSERT(m_TransferBufferLength < PAGE_SIZE * 5);
|
||||||
NumPages = Index = 0;
|
PC_ASSERT(m_TransferBufferLength);
|
||||||
NumTransferDescriptors = 1;
|
|
||||||
while (TransferBufferRounded > 0)
|
|
||||||
{
|
|
||||||
TransferBufferRounded -= PAGE_SIZE;
|
|
||||||
NumPages++;
|
|
||||||
Index++;
|
|
||||||
if (Index == 5)
|
|
||||||
{
|
|
||||||
NumTransferDescriptors++;
|
|
||||||
Index = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT1("Need TransferDescriptors %x, Pages %x\n", NumTransferDescriptors, NumPages);
|
TransferDescriptorCount = 1;
|
||||||
DPRINT1("This is the end of the line!!!!!!!!\n");
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
//FIXME: Below needs work.
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// FIXME: Handle transfers greater than 5 * PAGE_SIZE * 3
|
// get virtual base of mdl
|
||||||
//
|
//
|
||||||
if (NumTransferDescriptors > 3) NumTransferDescriptors = 3;
|
Base = MmGetMdlVirtualAddress(m_TransferBufferMDL);
|
||||||
|
BytesAvailable = m_TransferBufferLength;
|
||||||
|
|
||||||
|
PC_ASSERT(m_EndpointDescriptor);
|
||||||
|
|
||||||
|
DPRINT1("EndPointAddress %x\n", m_EndpointDescriptor->bEndpointAddress);
|
||||||
|
DPRINT1("EndPointDirection %x\n", USB_ENDPOINT_DIRECTION_IN(m_EndpointDescriptor->bEndpointAddress));
|
||||||
|
|
||||||
|
DPRINT1("Request %p Base Address %p TransferBytesLength %lu\n", this, Base, BytesAvailable);
|
||||||
|
DPRINT1("InternalGetPidDirection() %d EndPointAddress %x\n", InternalGetPidDirection(), m_EndpointDescriptor->bEndpointAddress & 0x0F);
|
||||||
|
|
||||||
|
//PC_ASSERT(InternalGetPidDirection() == USB_ENDPOINT_DIRECTION_IN(m_EndpointDescriptor->bEndpointAddress));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocated transfer descriptors
|
// Allocated transfer descriptors
|
||||||
//
|
//
|
||||||
for (Index = 0; Index < NumTransferDescriptors; Index++)
|
for (Index = 0; Index < TransferDescriptorCount; Index++)
|
||||||
{
|
{
|
||||||
Status = CreateDescriptor(&m_TransferDescriptors[Index]);
|
Status = CreateDescriptor(&m_TransferDescriptors[Index]);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -850,12 +850,132 @@ CUSBRequest::BuildBulkTransferQueueHead(
|
||||||
// Free Descriptors
|
// Free Descriptors
|
||||||
// FIXME: Implement FreeDescriptors
|
// FIXME: Implement FreeDescriptors
|
||||||
//
|
//
|
||||||
//for (FailIndex = 0; FailIndex < Index; FailIndex++)
|
|
||||||
//FreeDescriptor(m_TransferDescriptors[FailIndex]);
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
PC_ASSERT(BytesAvailable);
|
||||||
|
|
||||||
|
//
|
||||||
|
// now setup transfer buffers
|
||||||
|
//
|
||||||
|
for(BufferIndex = 0; BufferIndex < 5; BufferIndex++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// setup buffer
|
||||||
|
//
|
||||||
|
if (BufferIndex == 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// use physical address
|
||||||
|
//
|
||||||
|
m_TransferDescriptors[Index]->BufferPointer[0] = MmGetPhysicalAddress(Base).LowPart;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get offset within page
|
||||||
|
//
|
||||||
|
PageOffset = BYTE_OFFSET(m_TransferDescriptors[Index]->BufferPointer[0]);
|
||||||
|
|
||||||
|
//
|
||||||
|
// check if request fills another page
|
||||||
|
//
|
||||||
|
if (PageOffset + BytesAvailable >= PAGE_SIZE)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// move to next page
|
||||||
|
//
|
||||||
|
Base = (PVOID)ROUND_TO_PAGES(Base);
|
||||||
|
|
||||||
|
//
|
||||||
|
// increment transfer bytes
|
||||||
|
//
|
||||||
|
m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer = PAGE_SIZE - PageOffset;
|
||||||
|
|
||||||
|
//
|
||||||
|
// decrement available byte count
|
||||||
|
//
|
||||||
|
BytesAvailable -= m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer;
|
||||||
|
|
||||||
|
DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
|
||||||
|
BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// request ends on the first buffer page
|
||||||
|
//
|
||||||
|
m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer = BytesAvailable;
|
||||||
|
BytesAvailable = 0;
|
||||||
|
|
||||||
|
DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
|
||||||
|
BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// the following pages always start on byte zero of each page
|
||||||
|
//
|
||||||
|
PC_ASSERT(((ULONG_PTR)Base & (PAGE_SIZE-1)) == 0);
|
||||||
|
|
||||||
|
if (BytesAvailable >= PAGE_SIZE)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// store address
|
||||||
|
//
|
||||||
|
m_TransferDescriptors[Index]->BufferPointer[BufferIndex] = MmGetPhysicalAddress(Base).LowPart;
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next page
|
||||||
|
//
|
||||||
|
Base = (PVOID)((ULONG_PTR)Base + PAGE_SIZE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// increment transfer descriptor bytes
|
||||||
|
//
|
||||||
|
m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer += PAGE_SIZE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// decrement available byte count
|
||||||
|
//
|
||||||
|
BytesAvailable -= PAGE_SIZE;
|
||||||
|
|
||||||
|
DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
|
||||||
|
BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PC_ASSERT(BytesAvailable);
|
||||||
|
|
||||||
|
//
|
||||||
|
// store address
|
||||||
|
//
|
||||||
|
m_TransferDescriptors[Index]->BufferPointer[BufferIndex] = MmGetPhysicalAddress(Base).LowPart;
|
||||||
|
|
||||||
|
//
|
||||||
|
// increment transfer descriptor bytes
|
||||||
|
//
|
||||||
|
m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer += BytesAvailable;
|
||||||
|
|
||||||
|
//
|
||||||
|
// decrement available byte count
|
||||||
|
//
|
||||||
|
BytesAvailable -= BytesAvailable;
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
DPRINT1("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
|
||||||
|
BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Go ahead and link descriptors
|
// Go ahead and link descriptors
|
||||||
//
|
//
|
||||||
|
@ -863,9 +983,27 @@ CUSBRequest::BuildBulkTransferQueueHead(
|
||||||
{
|
{
|
||||||
m_TransferDescriptors[Index - 1]->NextPointer = m_TransferDescriptors[Index]->PhysicalAddr;
|
m_TransferDescriptors[Index - 1]->NextPointer = m_TransferDescriptors[Index]->PhysicalAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// setup direction
|
||||||
|
//
|
||||||
|
m_TransferDescriptors[Index]->Token.Bits.PIDCode = InternalGetPidDirection();
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: performance penality?
|
||||||
|
//
|
||||||
|
m_TransferDescriptors[Index]->Token.Bits.InterruptOnComplete = TRUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME need dead queue transfer descriptor?
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// all bytes should have been consumed
|
||||||
|
//
|
||||||
|
PC_ASSERT(BytesAvailable == 0);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize the QueueHead
|
// Initialize the QueueHead
|
||||||
//
|
//
|
||||||
|
@ -881,19 +1019,20 @@ CUSBRequest::BuildBulkTransferQueueHead(
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueHead->Token.Bits.DataToggle = TRUE;
|
QueueHead->Token.Bits.DataToggle = TRUE;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setup descriptors
|
// link descriptor with queue head
|
||||||
//
|
//
|
||||||
m_TransferDescriptors[0]->Token.Bits.PIDCode = InternalGetPidDirection();
|
QueueHead->NextPointer = m_TransferDescriptors[0]->PhysicalAddr;
|
||||||
//m_TransferDescriptors[0]->Token.Bits.TotalBytesToTransfer = ???
|
|
||||||
//m_TransferDescriptors[0]->Token.Bits.DataToggle = FALSE;
|
|
||||||
|
|
||||||
m_TransferDescriptors[Index]->Token.Bits.InterruptOnComplete = TRUE;
|
//
|
||||||
|
// store result
|
||||||
|
//
|
||||||
|
*OutHead = QueueHead;
|
||||||
|
|
||||||
ASSERT(m_TransferBufferMDL);
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1351,6 +1490,7 @@ CUSBRequest::FreeQueueHead(
|
||||||
//
|
//
|
||||||
// release transfer descriptors
|
// release transfer descriptors
|
||||||
//
|
//
|
||||||
|
DPRINT1("m_TransferDescriptor[0] Length %lu\n", m_TransferDescriptors[0]->Token.Bits.TotalBytesToTransfer);
|
||||||
m_DmaManager->Release(m_TransferDescriptors[0], sizeof(QUEUE_TRANSFER_DESCRIPTOR));
|
m_DmaManager->Release(m_TransferDescriptors[0], sizeof(QUEUE_TRANSFER_DESCRIPTOR));
|
||||||
m_TransferDescriptors[0] = 0;
|
m_TransferDescriptors[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue