Author: janderwald
Date: Sat Apr 30 08:04:35 2011
New Revision: 51501
URL:
http://svn.reactos.org/svn/reactos?rev=51501&view=rev
Log:
[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
Modified:
branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp
branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp
branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
Modified: branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp [iso-8859-1]
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp [iso-8859-1] Sat Apr
30 08:04:35 2011
@@ -65,6 +65,7 @@
NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb);
NTSTATUS HandleSelectInterface(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);
friend VOID StatusChangeEndpointCallBack(PVOID Context);
@@ -1355,6 +1356,70 @@
DPRINT1("CHubController::HandleGetDescriptor DescriptorType %x
unimplemented\n", Urb->UrbControlDescriptorRequest.DescriptorType);
break;
}
+
+ //
+ // done
+ //
+ 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
@@ -1419,6 +1484,9 @@
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
Status = HandleBulkOrInterruptTransfer(Irp, Urb);
break;
+ case URB_FUNCTION_CLASS_INTERFACE:
+ Status = HandleClassInterface(Irp, Urb);
+ break;
default:
DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT
IMPLEMENTED\n", Urb->UrbHeader.Function);
break;
Modified: branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] Sat Apr 30
08:04:35 2011
@@ -785,7 +785,7 @@
//
// Description: submits an irp containing an urb
- virtual NTSTATUS SubmitIrp(PIRP Urb) = 0;
+ virtual NTSTATUS SubmitIrp(PIRP Irp) = 0;
//-----------------------------------------------------------------------------------------
//
Modified: branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp [iso-8859-1]
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp [iso-8859-1] Sat Apr
30 08:04:35 2011
@@ -136,7 +136,7 @@
// sanity checks
//
ASSERT(Size < PAGE_SIZE);
- ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+ //ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
//
// align request
Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] Sat Apr 30
08:04:35 2011
@@ -484,6 +484,11 @@
Status = Request->InitializeWithIrp(m_DmaManager, Irp);
//
+ // mark irp as pending
+ //
+ IoMarkIrpPending(Irp);
+
+ //
// now add the request
//
Status = m_Queue->AddUSBRequest(Request);
@@ -500,7 +505,7 @@
//
// done
//
- return Status;
+ return STATUS_PENDING;
}
//----------------------------------------------------------------------------------------
@@ -1199,6 +1204,16 @@
//
// 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;
if
(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes
& (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT))
Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] Sat Apr 30
08:04:35 2011
@@ -371,6 +371,8 @@
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
// if yes dont complete irp yet
@@ -604,9 +606,9 @@
EndpointDescriptor =
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
//
- // end point is defined in the low byte of bmAttributes
- //
- return (EndpointDescriptor->bmAttributes & USB_ENDPOINT_DIRECTION_MASK);
+ // end point is defined in the low byte of bEndpointAddress
+ //
+ return (EndpointDescriptor->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK)
>> 7;
}
//----------------------------------------------------------------------------------------
@@ -779,8 +781,11 @@
PQUEUE_HEAD * OutHead)
{
NTSTATUS Status;
- ULONG NumTransferDescriptors, TransferBufferRounded, NumPages, Index, FailIndex;
PQUEUE_HEAD QueueHead;
+ ULONG TransferDescriptorCount, Index;
+ ULONG BytesAvailable, BufferIndex;
+ PVOID Base;
+ ULONG PageOffset;
//
// Allocate the queue head
@@ -801,38 +806,33 @@
PC_ASSERT(QueueHead);
//
- // Determine number of transfer descriptors needed. Max size is 3 * 5 Pages
- // FIXME: Do we need anything bigger?
- //
- TransferBufferRounded = ROUND_TO_PAGES(m_TransferBufferLength);
- NumPages = Index = 0;
- 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);
- 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
- //
- if (NumTransferDescriptors > 3) NumTransferDescriptors = 3;
+ // FIXME: support more than one descriptor
+ //
+ PC_ASSERT(m_TransferBufferLength < PAGE_SIZE * 5);
+ PC_ASSERT(m_TransferBufferLength);
+
+ TransferDescriptorCount = 1;
+
+ //
+ // get virtual base of mdl
+ //
+ 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
//
- for (Index = 0; Index < NumTransferDescriptors; Index++)
+ for (Index = 0; Index < TransferDescriptorCount; Index++)
{
Status = CreateDescriptor(&m_TransferDescriptors[Index]);
if (!NT_SUCCESS(Status))
@@ -850,10 +850,130 @@
// Free Descriptors
// FIXME: Implement FreeDescriptors
//
- //for (FailIndex = 0; FailIndex < Index; FailIndex++)
- //FreeDescriptor(m_TransferDescriptors[FailIndex]);
-
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;
+ }
+ }
}
//
@@ -863,8 +983,26 @@
{
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
@@ -881,19 +1019,20 @@
}
QueueHead->Token.Bits.DataToggle = TRUE;
-
- //
- // Setup descriptors
- //
- m_TransferDescriptors[0]->Token.Bits.PIDCode = InternalGetPidDirection();
- //m_TransferDescriptors[0]->Token.Bits.TotalBytesToTransfer = ???
- //m_TransferDescriptors[0]->Token.Bits.DataToggle = FALSE;
-
- m_TransferDescriptors[Index]->Token.Bits.InterruptOnComplete = TRUE;
-
- ASSERT(m_TransferBufferMDL);
-
-
+
+ //
+ // link descriptor with queue head
+ //
+ QueueHead->NextPointer = m_TransferDescriptors[0]->PhysicalAddr;
+
+ //
+ // store result
+ //
+ *OutHead = QueueHead;
+
+ //
+ // done
+ //
return STATUS_SUCCESS;
}
@@ -1351,6 +1490,7 @@
//
// 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_TransferDescriptors[0] = 0;
}