Author: mjmartin
Date: Fri Apr 29 13:16:03 2011
New Revision: 51493
URL:
http://svn.reactos.org/svn/reactos?rev=51493&view=rev
Log:
[USBEHCI_NEW]
- Fix a type causing CommitIrp to fail.
- Add a sanity check in StatusChangeEndpointCallBack to check that a pending SCE irp is
queued.
- Start Implementing Bulk Transfers. Needs more work.
Modified:
branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.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] Fri Apr
29 13:16:03 2011
@@ -761,6 +761,8 @@
IN OUT PIRP Irp,
PURB Urb)
{
+ PUSBDEVICE UsbDevice;
+ PUSB_ENDPOINT_DESCRIPTOR EndPointDesc = NULL;
//
// First check if the request is for the Status Change Endpoint
//
@@ -779,13 +781,45 @@
//
// Else pend the IRP, to be completed when a device connects or disconnects.
//
+ DPRINT1("Pending SCE Irp\n");;
m_PendingSCEIrp = Irp;
IoMarkIrpPending(Irp);
return STATUS_PENDING;
}
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
+ //
+ // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer Request
+ //
+ EndPointDesc =
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
+
+ switch(EndPointDesc->bmAttributes & 0x0F)
+ {
+ case USB_ENDPOINT_TYPE_CONTROL:
+ DPRINT1("Control Transfer is not expected!!!\n");
+ return STATUS_INVALID_DEVICE_REQUEST;
+ case USB_ENDPOINT_TYPE_BULK:
+ DPRINT1("Initiating Bulk Transfer\n");
+ break;
+ case USB_ENDPOINT_TYPE_ISOCHRONOUS:
+ case USB_ENDPOINT_TYPE_INTERRUPT:
+ DPRINT1("Not Supported\n");
+ break;
+ default:
+ DPRINT1("Unknown EndPoint Type!\n");
+ break;
+ }
+
+ //
+ // check if this is a valid usb device handle
+ //
+ PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+
+ //
+ // get device
+ //
+ UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+ return UsbDevice->SubmitIrp(Irp);
}
//-----------------------------------------------------------------------------------------
@@ -3068,13 +3102,18 @@
ASSERT(This);
- DPRINT1("SCE Notification!\n");
Irp = This->m_PendingSCEIrp;
+ if (!Irp)
+ {
+ DPRINT1("There was no pending IRP for SCE. Did the usb hub 2.0 driver
(usbhub2) load?\n");
+ return;
+ }
+
This->m_PendingSCEIrp = NULL;
-
This->QueryStatusChageEndpoint(Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
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] Fri Apr 29
13:16:03 2011
@@ -456,7 +456,7 @@
NTSTATUS Status;
PUSBREQUEST Request;
- if (!m_Queue || m_DmaManager)
+ if (!m_Queue || !m_DmaManager)
{
//
// no queue, wtf?
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] Fri Apr 29
13:16:03 2011
@@ -53,6 +53,7 @@
// local functions
ULONG InternalGetTransferType();
+ UCHAR InternalGetPidDirection();
NTSTATUS BuildControlTransferQueueHead(PQUEUE_HEAD * OutHead);
NTSTATUS BuildBulkTransferQueueHead(PQUEUE_HEAD * OutHead);
NTSTATUS CreateDescriptor(PQUEUE_TRANSFER_DESCRIPTOR *OutDescriptor);
@@ -205,6 +206,8 @@
PC_ASSERT(DmaManager);
PC_ASSERT(Irp);
+ m_DmaManager = DmaManager;
+
//
// get current irp stack location
//
@@ -245,20 +248,49 @@
if (Urb->UrbBulkOrInterruptTransfer.TransferBufferLength)
{
//
- // FIXME: it must have an MDL
+ // Check if there is a MDL
//
- PC_ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
+ if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
+ {
+ //
+ // Create one using TransferBuffer
+ //
+ DPRINT1("Creating Mdl from Urb Buffer\n");
+ m_TransferBufferMDL =
IoAllocateMdl(Urb->UrbBulkOrInterruptTransfer.TransferBuffer,
+
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
+ FALSE,
+ FALSE,
+ NULL);
+
+ if (!m_TransferBufferMDL)
+ {
+ //
+ // failed to allocate mdl
+ //
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // build mdl for non paged pool
+ // FIXME: Does hub driver already do this when passing MDL?
+ //
+ MmBuildMdlForNonPagedPool(m_TransferBufferMDL);
+ }
+ else
+ {
+ m_TransferBufferMDL =
Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL;
+ }
+
+ //
+ // save buffer length
+ //
+ m_TransferBufferLength =
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
//
// get endpoint descriptor
//
m_EndpointDescriptor =
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
- //
- // get mdl buffer
- //
- m_TransferBufferMDL =
Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL;
- m_TransferBufferLength =
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
}
break;
}
@@ -317,6 +349,18 @@
Urb->UrbHeader.Status = UrbStatusCode;
//
+ // Check if the MDL was created
+ //
+
+ if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
+ {
+ //
+ // Free Mdl
+ //
+ IoFreeMdl(m_TransferBufferMDL);
+ }
+
+ //
// check if the request was successfull
//
if (!NT_SUCCESS(NtStatusCode))
@@ -536,6 +580,35 @@
return TransferType;
}
+UCHAR
+CUSBRequest::InternalGetPidDirection()
+{
+ PIO_STACK_LOCATION IoStack;
+ PURB Urb;
+ PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+
+ ASSERT(m_Irp);
+ //
+ // get stack location
+ //
+ IoStack = IoGetCurrentIrpStackLocation(m_Irp);
+
+ //
+ // get urb
+ //
+ Urb = (PURB)IoStack->Parameters.Others.Argument1;
+
+ //
+ // cast to end point
+ //
+ EndpointDescriptor =
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
+
+ //
+ // end point is defined in the low byte of bmAttributes
+ //
+ return (EndpointDescriptor->bmAttributes & USB_ENDPOINT_DIRECTION_MASK);
+}
+
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBRequest::BuildControlTransferQueueHead(
@@ -705,8 +778,123 @@
CUSBRequest::BuildBulkTransferQueueHead(
PQUEUE_HEAD * OutHead)
{
- UNIMPLEMENTED
+ NTSTATUS Status;
+ ULONG NumTransferDescriptors, TransferBufferRounded, NumPages, Index, FailIndex;
+ PQUEUE_HEAD QueueHead;
+
+ //
+ // 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);
+
+ //
+ // 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;
+
+ //
+ // Allocated transfer descriptors
+ //
+ for (Index = 0; Index < NumTransferDescriptors; Index++)
+ {
+ Status = CreateDescriptor(&m_TransferDescriptors[Index]);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // Failed to allocate transfer descriptors
+ //
+
+ //
+ // Free QueueHead
+ //
+ FreeQueueHead(QueueHead);
+
+ //
+ // Free Descriptors
+ // FIXME: Implement FreeDescriptors
+ //
+ //for (FailIndex = 0; FailIndex < Index; FailIndex++)
+ //FreeDescriptor(m_TransferDescriptors[FailIndex]);
+
+ return Status;
+ }
+
+ //
+ // Go ahead and link descriptors
+ //
+ if (Index > 0)
+ {
+ m_TransferDescriptors[Index - 1]->NextPointer =
m_TransferDescriptors[Index]->PhysicalAddr;
+ }
+
+ }
+
+ //
+ // Initialize the QueueHead
+ //
+ QueueHead->EndPointCharacteristics.DeviceAddress = GetDeviceAddress();
+
+ if (m_EndpointDescriptor)
+ {
+ //
+ // Set endpoint address and max packet length
+ //
+ QueueHead->EndPointCharacteristics.EndPointNumber =
m_EndpointDescriptor->bEndpointAddress & 0x0F;
+ QueueHead->EndPointCharacteristics.MaximumPacketLength =
m_EndpointDescriptor->wMaxPacketSize;
+ }
+
+ 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);
+
+
+ return STATUS_SUCCESS;
}
//----------------------------------------------------------------------------------------
@@ -764,6 +952,7 @@
// allocate queue head
//
Status = m_DmaManager->Allocate(sizeof(QUEUE_HEAD), (PVOID*)&QueueHead,
&QueueHeadPhysicalAddress);
+
if (!NT_SUCCESS(Status))
{
//
@@ -1225,12 +1414,12 @@
//
// check for serious error
//
- PC_ASSERT(m_TransferDescriptors[Index]->Token.Bits.Halted == 0);
+ //PC_ASSERT(m_TransferDescriptors[Index]->Token.Bits.Halted == 0);
//
// the transfer descriptor should be in the same state as the queue head
//
- PC_ASSERT(m_TransferDescriptors[Index]->Token.Bits.Active == 0);
+ //PC_ASSERT(m_TransferDescriptors[Index]->Token.Bits.Active == 0);
}
}