//
// Link the LIST_ENTRYs
//
- ASSERT(IsListEmpty(&HeadQueueHead->LinkedQueueHeads));
+ //ASSERT(IsListEmpty(&HeadQueueHead->LinkedQueueHeads));
InsertTailList(&HeadQueueHead->LinkedQueueHeads, &NewQueueHead->LinkedQueueHeads);
//
//
Entry = NewQueueHead->LinkedQueueHeads.Blink;
LastQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
- ASSERT(LastQueueHead == HeadQueueHead);
+ //ASSERT(LastQueueHead == HeadQueueHead);
LastQueueHead->HorizontalLinkPointer = (NewQueueHead->PhysicalAddr | QH_TYPE_QH);
//
//
Entry = NewQueueHead->LinkedQueueHeads.Flink;
NextQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
- ASSERT(NextQueueHead == HeadQueueHead);
+ //ASSERT(NextQueueHead == HeadQueueHead);
NewQueueHead->HorizontalLinkPointer = (NextQueueHead->PhysicalAddr | QH_TYPE_QH);
//
KIRQL OldLevel;
PLIST_ENTRY Entry;
PQUEUE_HEAD CurrentQH;
- IUSBRequest *Request;
DPRINT("CUSBQueue::CompleteAsyncRequests\n");
//
CurrentQH = (PQUEUE_HEAD)CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
- //
- // Get the Request for this QueueHead
- //
- Request = (IUSBRequest*) CurrentQH->Request;
-
//
// release lock
//
IN UCHAR DeviceAddress,
IN PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor)
{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
+ KIRQL OldLevel;
+ PLIST_ENTRY Entry;
+ PQUEUE_HEAD QueueHead;
+ LIST_ENTRY ListHead;
+
+ //
+ // lock completed async list
+ //
+ KeAcquireSpinLock(m_Lock, &OldLevel);
+
+ DPRINT1("AbortDevicePipe DeviceAddress %x EndpointDescriptor %p Addr %x\n", DeviceAddress, EndpointDescriptor, EndpointDescriptor->bEndpointAddress);
+
+ //
+ // init list head
+ //
+ InitializeListHead(&ListHead);
+
+
+ //
+ // walk async list
+ //
+ ASSERT(AsyncListQueueHead);
+ Entry = AsyncListQueueHead->LinkedQueueHeads.Flink;
+
+ while(Entry != &AsyncListQueueHead->LinkedQueueHeads)
+ {
+ //
+ // get queue head structure
+ //
+ QueueHead = (PQUEUE_HEAD)CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+ ASSERT(QueueHead);
+
+ //
+ // move to next entry
+ //
+ Entry = Entry->Flink;
+
+ if (QueueHead->EndPointCharacteristics.DeviceAddress == DeviceAddress &&
+ QueueHead->EndPointCharacteristics.EndPointNumber == (EndpointDescriptor->bEndpointAddress & 0xF) && QueueHead->Token.Bits.Halted)
+ {
+ //
+ // unlink queue head
+ //
+ UnlinkQueueHead(QueueHead);
+
+ //
+ // add to temp list
+ //
+ InsertTailList(&ListHead, &QueueHead->LinkedQueueHeads);
+ }
+ }
+
+ //
+ // release lock
+ //
+ KeReleaseSpinLock(m_Lock, OldLevel);
+
+ while(!IsListEmpty(&ListHead))
+ {
+ //
+ // remove entry
+ //
+ Entry = RemoveHeadList(&ListHead);
+
+ //
+ // get queue head structure
+ //
+ QueueHead = (PQUEUE_HEAD)CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+ ASSERT(QueueHead);
+
+ //
+ // cleanup queue head
+ //
+ QueueHeadCleanup(QueueHead);
+ }
+ return STATUS_SUCCESS;
}
NTSTATUS BuildSetupPacket();
NTSTATUS BuildSetupPacketFromURB();
ULONG InternalCalculateTransferLength();
- NTSTATUS BuildTransferDescriptorChain(IN PQUEUE_HEAD QueueHead, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutFirstDescriptor, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutLastDescriptor, OUT PUCHAR OutDataToggle, OUT PULONG OutTransferBufferOffset);
+ NTSTATUS BuildTransferDescriptorChain(IN PQUEUE_HEAD QueueHead, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, IN PQUEUE_TRANSFER_DESCRIPTOR AlternativeDescriptor, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutFirstDescriptor, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutLastDescriptor, OUT PUCHAR OutDataToggle, OUT PULONG OutTransferBufferOffset);
VOID InitDescriptor(IN PQUEUE_TRANSFER_DESCRIPTOR CurrentDescriptor, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR DataToggle, OUT PULONG OutDescriptorLength);
VOID DumpQueueHead(IN PQUEUE_HEAD QueueHead);
-
// constructor / destructor
CUSBRequest(IUnknown *OuterUnknown){}
virtual ~CUSBRequest(){}
IN ULONG TransferBufferLength,
IN UCHAR PidCode,
IN UCHAR InitialDataToggle,
+ IN PQUEUE_TRANSFER_DESCRIPTOR AlternativeDescriptor,
OUT PQUEUE_TRANSFER_DESCRIPTOR * OutFirstDescriptor,
OUT PQUEUE_TRANSFER_DESCRIPTOR * OutLastDescriptor,
OUT PUCHAR OutDataToggle,
PQUEUE_TRANSFER_DESCRIPTOR FirstDescriptor = NULL, CurrentDescriptor, LastDescriptor = NULL;
NTSTATUS Status;
ULONG DescriptorLength, TransferBufferOffset = 0;
+ ULONG MaxPacketSize = 0, TransferSize;
+
+ //
+ // is there an endpoint descriptor
+ //
+ if (m_EndpointDescriptor)
+ {
+ //
+ // use endpoint packet size
+ //
+ MaxPacketSize = m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize;
+ }
+
do
{
//
// failed to allocate transfer descriptor
//
- ASSERT(FALSE);
- return Status;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if (MaxPacketSize)
+ {
+ //
+ // transfer size is minimum available buffer or endpoint size
+ //
+ TransferSize = min(TransferBufferLength - TransferBufferOffset, MaxPacketSize);
+ }
+ else
+ {
+ //
+ // use available buffer
+ //
+ TransferSize = TransferBufferLength - TransferBufferOffset;
}
//
//
InitDescriptor(CurrentDescriptor,
(PVOID)((ULONG_PTR)TransferBuffer + TransferBufferOffset),
- TransferBufferLength - TransferBufferOffset,
+ TransferSize,
PidCode,
InitialDataToggle,
&DescriptorLength);
//
// link to current descriptor
//
- LastDescriptor->AlternateNextPointer = CurrentDescriptor->PhysicalAddr;
LastDescriptor->NextPointer = CurrentDescriptor->PhysicalAddr;
LastDescriptor = CurrentDescriptor;
+
+ if (AlternativeDescriptor)
+ {
+ //
+ // link to alternative next pointer
+ //
+ LastDescriptor->AlternateNextPointer = AlternativeDescriptor->PhysicalAddr;
+ }
+
}
else
{
LastDescriptor = FirstDescriptor = CurrentDescriptor;
}
+ //
+ // flip data toggle
+ //
+ InitialDataToggle = !InitialDataToggle;
+
if(TransferBufferLength == TransferBufferOffset)
{
//
//
break;
}
+
}while(TRUE);
if (OutFirstDescriptor)
if (OutDataToggle)
{
- //
- // flip data toggle
- //
- InitialDataToggle = !InitialDataToggle;
-
//
// store result data toggle
//
//
QueueHead->EndPointCharacteristics.DeviceAddress = GetDeviceAddress();
- if (m_EndpointDescriptor)
- {
- //
- // set endpoint address and max packet length
- //
- QueueHead->EndPointCharacteristics.EndPointNumber = m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & 0x0F;
- QueueHead->EndPointCharacteristics.MaximumPacketLength = m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize;
- }
+ ASSERT(m_EndpointDescriptor == FALSE);
//
// init setup descriptor
m_TransferBufferLength,
InternalGetPidDirection(),
TRUE,
+ NULL,
&FirstDescriptor,
&LastDescriptor,
NULL,
//
ASSERT(m_EndpointDescriptor);
+ //
+ // use 4 * PAGE_SIZE at max for each new request
+ //
+ ULONG MaxTransferLength = min(4 * PAGE_SIZE, m_TransferBufferLength - m_TransferBufferLengthCompleted);
+
//
// build bulk transfer descriptor chain
//
Status = BuildTransferDescriptorChain(QueueHead,
Base,
- m_TransferBufferLength - m_TransferBufferLengthCompleted,
+ MaxTransferLength,
InternalGetPidDirection(),
m_EndpointDescriptor->DataToggle,
+ NULL,
&FirstDescriptor,
&LastDescriptor,
&m_EndpointDescriptor->DataToggle,
//
// FIXME: handle errors
//
- ASSERT(ChainDescriptorLength == m_TransferBufferLength);
+ //ASSERT(ChainDescriptorLength == m_TransferBufferLength);
//
// move to next offset
//
// Set NakCountReload to max value possible
//
- QueueHead->EndPointCharacteristics.NakCountReload = 0xF;
+ QueueHead->EndPointCharacteristics.NakCountReload = 0x3;
//
// Get the Initial Data Toggle from the QEDT
// FIXME: check if High Speed Device
//
QueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED;
- QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x03;
+ QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x01;
QueueHead->Token.DWord = 0;
QueueHead->Token.Bits.InterruptOnComplete = FALSE;