Author: janderwald
Date: Wed Feb 8 22:06:00 2012
New Revision: 55502
URL:
http://svn.reactos.org/svn/reactos?rev=55502&view=rev
Log:
[EHCI]
- Add back old implementation for testing purposes (if'd out)
- Display more status field of queue head / transfer descriptor
- Dump queue head when a halted queue is detected
- Display data toggle status
Modified:
branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_request.cpp
Modified: branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_request.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1]
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] Wed
Feb 8 22:06:00 2012
@@ -662,10 +662,20 @@
//
PageOffset = BYTE_OFFSET(TransferBuffer);
- //
- // move to next page
- //
- TransferBuffer = (PVOID)ROUND_TO_PAGES(TransferBuffer);
+ if (PageOffset != 0)
+ {
+ //
+ // move to next page
+ //
+ TransferBuffer = (PVOID)ROUND_TO_PAGES(TransferBuffer);
+ }
+ else
+ {
+ //
+ // move to next page
+ //
+ TransferBuffer = (PVOID)((ULONG_PTR)TransferBuffer + PAGE_SIZE);
+ }
//
// calculate buffer length
@@ -678,7 +688,7 @@
CurrentDescriptor->Token.Bits.TotalBytesToTransfer += BufferLength;
CurrentDescriptor->TotalBytesToTransfer += BufferLength;
Length += BufferLength;
- DPRINT1("Index %lu Length %lu\n", Index, Length);
+ DPRINT1("Index %lu Length %lu Buffer %p\n", Index, Length,
TransferBuffer);
//
// decrement available byte count
@@ -690,6 +700,17 @@
// end reached
//
break;
+ }
+
+ //
+ // sanity check
+ //
+ if (Index > 1)
+ {
+ //
+ // no equal buffers
+ //
+ ASSERT(CurrentDescriptor->BufferPointer[Index] !=
CurrentDescriptor->BufferPointer[Index-1]);
}
//
@@ -785,6 +806,7 @@
//
break;
}
+ break;
}while(TRUE);
if (OutFirstDescriptor)
@@ -1011,6 +1033,21 @@
DPRINT1("QueueHead AlternateNextPointer %x\n",
QueueHead->AlternateNextPointer);
DPRINT1("QueueHead NextPointer %x\n", QueueHead->NextPointer);
+ DPRINT1("QueueHead HubAddr %x\n",
QueueHead->EndPointCharacteristics.ControlEndPointFlag);
+ DPRINT1("QueueHead DeviceAddress %x\n",
QueueHead->EndPointCharacteristics.DeviceAddress);
+ DPRINT1("QueueHead EndPointNumber %x\n",
QueueHead->EndPointCharacteristics.EndPointNumber);
+ DPRINT1("QueueHead EndPointSpeed %x\n",
QueueHead->EndPointCharacteristics.EndPointSpeed);
+ DPRINT1("QueueHead HeadOfReclamation %x\n",
QueueHead->EndPointCharacteristics.HeadOfReclamation);
+ DPRINT1("QueueHead InactiveOnNextTransaction %x\n",
QueueHead->EndPointCharacteristics.InactiveOnNextTransaction);
+ DPRINT1("QueueHead MaximumPacketLength %x\n",
QueueHead->EndPointCharacteristics.MaximumPacketLength);
+ DPRINT1("QueueHead NakCountReload %x\n",
QueueHead->EndPointCharacteristics.NakCountReload);
+ DPRINT1("QueueHead QEDTDataToggleControl %x\n",
QueueHead->EndPointCharacteristics.QEDTDataToggleControl);
+ DPRINT1("QueueHead HubAddr %x\n",
QueueHead->EndPointCapabilities.HubAddr);
+ DPRINT1("QueueHead InterruptScheduleMask %x\n",
QueueHead->EndPointCapabilities.InterruptScheduleMask);
+ DPRINT1("QueueHead NumberOfTransactionPerFrame %x\n",
QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame);
+ DPRINT1("QueueHead PortNumber %x\n",
QueueHead->EndPointCapabilities.PortNumber);
+ DPRINT1("QueueHead SplitCompletionMask %x\n",
QueueHead->EndPointCapabilities.SplitCompletionMask);
+
Entry = QueueHead->TransferDescriptorListHead.Flink;
while(Entry != &QueueHead->TransferDescriptorListHead)
{
@@ -1021,12 +1058,22 @@
DPRINT1("TransferDescriptor %lu Addr %x\n", Index,
Descriptor->PhysicalAddr);
DPRINT1("TransferDescriptor %lu Next %x\n", Index,
Descriptor->NextPointer);
- DPRINT1("TransferDescriptor %lu AlternativeNext %x\n", Index,
Descriptor->AlternateNextPointer);
- DPRINT1("TransferDescriptor %lu Pid %x\n", Index,
Descriptor->Token.Bits.PIDCode);
+ DPRINT1("TransferDescriptor %lu AlternateNextPointer %x\n", Index,
Descriptor->AlternateNextPointer);
+ DPRINT1("TransferDescriptor %lu Active %lu\n", Index,
Descriptor->Token.Bits.Active);
+ DPRINT1("TransferDescriptor %lu BabbleDetected %lu\n", Index,
Descriptor->Token.Bits.BabbleDetected);
+ DPRINT1("TransferDescriptor %lu CurrentPage %lu\n", Index,
Descriptor->Token.Bits.CurrentPage);
+ DPRINT1("TransferDescriptor %lu DataBufferError %lu\n", Index,
Descriptor->Token.Bits.DataBufferError);
+ DPRINT1("TransferDescriptor %lu DataToggle %lu\n", Index,
Descriptor->Token.Bits.DataToggle);
+ DPRINT1("TransferDescriptor %lu ErrorCounter %lu\n", Index,
Descriptor->Token.Bits.ErrorCounter);
+ DPRINT1("TransferDescriptor %lu Halted %lu\n", Index,
Descriptor->Token.Bits.Halted);
+ DPRINT1("TransferDescriptor %lu InterruptOnComplete %x\n", Index,
Descriptor->Token.Bits.InterruptOnComplete);
+ DPRINT1("TransferDescriptor %lu MissedMicroFrame %lu\n", Index,
Descriptor->Token.Bits.MissedMicroFrame);
+ DPRINT1("TransferDescriptor %lu PIDCode %lu\n", Index,
Descriptor->Token.Bits.PIDCode);
+ DPRINT1("TransferDescriptor %lu PingState %lu\n", Index,
Descriptor->Token.Bits.PingState);
+ DPRINT1("TransferDescriptor %lu SplitTransactionState %lu\n", Index,
Descriptor->Token.Bits.SplitTransactionState);
DPRINT1("TransferDescriptor %lu TotalBytesToTransfer %lu\n", Index,
Descriptor->Token.Bits.TotalBytesToTransfer);
- DPRINT1("TransferDescriptor %lu InterruptOnComplete %lu\n", Index,
Descriptor->Token.Bits.InterruptOnComplete);
-
- DPRINT1("TransferDescriptor %lu DataToggle %x\n", Index,
Descriptor->Token.Bits.DataToggle);
+ DPRINT1("TransferDescriptor %lu TransactionError %lu\n", Index,
Descriptor->Token.Bits.TransactionError);
+
DPRINT1("TransferDescriptor %lu Buffer Pointer 0 %x\n", Index,
Descriptor->BufferPointer[0]);
DPRINT1("TransferDescriptor %lu Buffer Pointer 1 %x\n", Index,
Descriptor->BufferPointer[1]);
DPRINT1("TransferDescriptor %lu Buffer Pointer 2 %x\n", Index,
Descriptor->BufferPointer[2]);
@@ -1035,8 +1082,6 @@
Entry = Entry->Flink;
Index++;
}
-
-
}
@@ -1045,6 +1090,303 @@
CUSBRequest::BuildBulkTransferQueueHead(
PQUEUE_HEAD * OutHead)
{
+#if 0
+ NTSTATUS Status;
+ PQUEUE_HEAD QueueHead;
+ ULONG TransferDescriptorCount, Index;
+ ULONG BytesAvailable, BufferIndex;
+ PVOID Base;
+ ULONG PageOffset, CurrentTransferBufferLength;
+ PQUEUE_TRANSFER_DESCRIPTOR m_TransferDescriptors[3];
+
+ //
+ // Allocate the queue head
+ //
+ Status = CreateQueueHead(&QueueHead);
+
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to allocate queue heads
+ //
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // sanity checks
+ //
+ PC_ASSERT(QueueHead);
+ PC_ASSERT(m_TransferBufferLength);
+
+ //
+ // Max default of 3 descriptors
+ //
+ TransferDescriptorCount = 3;
+
+ //
+ // get virtual base of mdl
+ //
+ Base = MmGetSystemAddressForMdlSafe(m_TransferBufferMDL, NormalPagePriority);
+
+ //
+ // Increase the size of last transfer, 0 in case this is the first
+ //
+ Base = (PVOID)((ULONG_PTR)Base + m_TransferBufferLengthCompleted);
+
+ PC_ASSERT(m_EndpointDescriptor);
+ PC_ASSERT(Base);
+
+ //
+ // Get the offset from page size
+ //
+ PageOffset = BYTE_OFFSET(Base);
+
+ //
+ // PageOffset should only be > 0 if this is the first transfer for this requests
+ //
+ if ((PageOffset != 0) && (m_TransferBufferLengthCompleted != 0))
+ {
+ ASSERT(FALSE);
+ }
+
+ //
+ // Calculate the size of this transfer
+ //
+ if ((PageOffset != 0) && ((m_TransferBufferLength -
m_TransferBufferLengthCompleted) >= (PAGE_SIZE * 4) + PageOffset))
+ {
+ CurrentTransferBufferLength = (PAGE_SIZE * 4) + PageOffset;
+ }
+ else if ((m_TransferBufferLength - m_TransferBufferLengthCompleted) >= PAGE_SIZE *
5)
+ {
+ CurrentTransferBufferLength = PAGE_SIZE * 5;
+ }
+ else
+ CurrentTransferBufferLength = (m_TransferBufferLength -
m_TransferBufferLengthCompleted);
+
+ //
+ // Add current transfer length to transfer length completed
+ //
+ m_TransferBufferLengthCompleted += CurrentTransferBufferLength;
+ BytesAvailable = CurrentTransferBufferLength;
+ DPRINT("CurrentTransferBufferLength %x, m_TransferBufferLengthCompleted
%x\n", CurrentTransferBufferLength, m_TransferBufferLengthCompleted);
+
+ DPRINT("EndPointAddress %x\n",
m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress);
+ DPRINT("EndPointDirection %x\n",
USB_ENDPOINT_DIRECTION_IN(m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress));
+
+ DPRINT("Request %p Base Address %p TransferBytesLength %lu MDL %p\n", this,
Base, BytesAvailable, m_TransferBufferMDL);
+ DPRINT("InternalGetPidDirection() %d EndPointAddress %x\n",
InternalGetPidDirection(), m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress
& 0x0F);
+ DPRINT("Irp %p QueueHead %p\n", m_Irp, QueueHead);
+
+ //PC_ASSERT(InternalGetPidDirection() ==
USB_ENDPOINT_DIRECTION_IN(m_EndpointDescriptor->bEndpointAddress));
+
+ //
+ // Allocated transfer descriptors
+ //
+ for (Index = 0; Index < TransferDescriptorCount; Index++)
+ {
+ Status = CreateDescriptor(&m_TransferDescriptors[Index]);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // Failed to allocate transfer descriptors
+ //
+
+ //
+ // Free QueueHead
+ //
+ FreeQueueHead(QueueHead);
+
+ //
+ // Free Descriptors
+ // FIXME: Implement FreeDescriptors
+ //
+ return Status;
+ }
+
+ //
+ // sanity check
+ //
+ PC_ASSERT(BytesAvailable);
+
+ //
+ // now setup transfer buffers
+ //
+ for(BufferIndex = 0; BufferIndex < 5; BufferIndex++)
+ {
+ //
+ // If this is the first buffer of the first descriptor and there is a
PageOffset
+ //
+ if ((BufferIndex == 0) && (PageOffset != 0) && (Index == 0))
+ {
+ //
+ // use physical address
+ //
+ m_TransferDescriptors[Index]->BufferPointer[0] =
MmGetPhysicalAddress(Base).LowPart;
+
+ //
+ // move to next page
+ //
+ Base = (PVOID)ROUND_TO_PAGES(Base);
+
+ //
+ // increment transfer bytes
+ //
+ if (CurrentTransferBufferLength > PAGE_SIZE - PageOffset)
+ m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer =
PAGE_SIZE - PageOffset;
+ else
+ m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer =
CurrentTransferBufferLength;
+
+ //
+ // decrement available byte count
+ //
+ BytesAvailable -=
m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer;
+
+ DPRINT("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
+ {
+ //
+ // 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;
+
+ DPRINT("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 as this is the last partial or full page
+ //
+ DPRINT("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;
+ }
+ }
+
+ //
+ // Check if all bytes have been consumed
+ //
+ if (BytesAvailable == 0)
+ break;
+ }
+
+ //
+ // store transfer bytes of descriptor
+ //
+ m_TransferDescriptors[Index]->TotalBytesToTransfer =
m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer;
+
+ //
+ // Go ahead and link descriptors
+ //
+ if (Index > 0)
+ {
+ 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;
+
+ InsertTailList(&QueueHead->TransferDescriptorListHead,
&m_TransferDescriptors[Index]->DescriptorEntry);
+
+ m_TransferDescriptors[Index]->Token.Bits.DataToggle =
m_EndpointDescriptor->DataToggle;
+ m_EndpointDescriptor->DataToggle = !m_EndpointDescriptor->DataToggle;
+
+ //
+ // FIXME need dead queue transfer descriptor?
+ //
+
+ //
+ // Check if all bytes have been consumed
+ //
+ if (BytesAvailable == 0)
+ break;
+ }
+
+ //
+ // all bytes should have been consumed
+ //
+ PC_ASSERT(BytesAvailable == 0);
+
+ //
+ // Initialize the QueueHead
+ //
+ 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;
+ }
+
+ QueueHead->Token.Bits.DataToggle = TRUE;
+
+ //
+ // link descriptor with queue head
+ //
+ QueueHead->NextPointer = m_TransferDescriptors[0]->PhysicalAddr;
+
+ //
+ // store result
+ //
+ *OutHead = QueueHead;
+
+ //
+ // done
+ //
+ return STATUS_SUCCESS;
+#else
NTSTATUS Status;
PQUEUE_HEAD QueueHead;
PVOID Base;
@@ -1087,6 +1429,8 @@
// sanity check
//
ASSERT(m_EndpointDescriptor);
+
+ DPRINT1("Before EndPoint %p DataToggle %x\n", m_EndpointDescriptor,
m_EndpointDescriptor->DataToggle);
//
// build bulk transfer descriptor chain
@@ -1104,7 +1448,8 @@
//
// FIXME: handle errors
//
- ASSERT(ChainDescriptorLength == m_TransferBufferLength);
+ //ASSERT(ChainDescriptorLength == m_TransferBufferLength);
+ DPRINT1("Afterwards: EndPoint %p DataToggle %x\n", m_EndpointDescriptor,
m_EndpointDescriptor->DataToggle);
//
// move to next offset
@@ -1141,13 +1486,13 @@
//
// dump status
//
- //DPRINT1("bEndpoint %x\n",
m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress);
- //DumpQueueHead(QueueHead);
+ DumpQueueHead(QueueHead);
//
// done
//
return STATUS_SUCCESS;
+#endif
}
//----------------------------------------------------------------------------------------
@@ -1655,6 +2000,7 @@
// error occured
//
DPRINT1("Found halted queue head %p\n", QueueHead);
+ DumpQueueHead(QueueHead);
ASSERT(FALSE);
return TRUE;
}