Author: mjmartin
Date: Wed Apr 13 04:48:50 2011
New Revision: 51327
URL:
http://svn.reactos.org/svn/reactos?rev=51327&view=rev
Log:
[USB\USBEHCI]
- Implement ExecuteTransfer to replace SubmitTransfer.
- Start implentation for BulkTransfers and needed DMA. This needs much more work to be
done correctly. We will get to it.
- Implement URB_FUNCTION_CLASS_INTERFACE.
- Add comments.
Change 3 of 3.
Modified:
trunk/reactos/drivers/usb/usbehci/irp.c
trunk/reactos/drivers/usb/usbehci/pdo.c
trunk/reactos/drivers/usb/usbehci/transfer.c
trunk/reactos/drivers/usb/usbehci/transfer.h
Modified: trunk/reactos/drivers/usb/usbehci/irp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/irp.c?…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/irp.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/irp.c [iso-8859-1] Wed Apr 13 04:48:50 2011
@@ -70,12 +70,16 @@
NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
ULONG_PTR Information = 0;
PIO_STACK_LOCATION Stack;
PUSB_DEVICE UsbDevice = NULL;
+ PEHCI_HOST_CONTROLLER hcd;
URB *Urb;
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)
PdoDeviceExtension->ControllerFdo->DeviceExtension;
+
+ hcd = &FdoDeviceExtension->hcd;
Stack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(Stack);
@@ -105,16 +109,62 @@
{
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
{
- DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER UsbDevice %x\n",
UsbDevice);
+ PUSB_ENDPOINT_DESCRIPTOR EndPointDesc;
+ int i;
+
+ for (i = 0; i <
UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints; i++)
+ {
+ EndPointDesc =
(PUSB_ENDPOINT_DESCRIPTOR)&UsbDevice->ActiveInterface->EndPoints[i]->EndPointDescriptor;
+ DPRINT("EndPoint %d Handle %x\n", i,
&UsbDevice->ActiveInterface->EndPoints[i]->EndPointDescriptor);
+ DPRINT("bmAttributes %x\n", EndPointDesc->bmAttributes);
+ DPRINT("EndPoint is transfer type %x\n",
EndPointDesc->bmAttributes & 0x0F);
+ }
+ DPRINT("UsbDevice %x, Handle %x\n", UsbDevice,
Urb->UrbBulkOrInterruptTransfer.PipeHandle);
if
(&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor !=
Urb->UrbBulkOrInterruptTransfer.PipeHandle)
{
- DPRINT1("Invalid Parameter, Expected EndPointDescriptor of %x, but
got %x\n",
&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor,
Urb->UrbBulkOrInterruptTransfer.PipeHandle);
- Status = STATUS_INVALID_PARAMETER;
+ DPRINT("HubDevice %x, UsbDevice %x\n",
PdoDeviceExtension->UsbDevices[0], UsbDevice);
+ if (Urb->UrbBulkOrInterruptTransfer.TransferFlags &
USBD_TRANSFER_DIRECTION_IN)
+ DPRINT1("USBD_TRANSFER_DIRECTION_IN\n");
+ if (Urb->UrbBulkOrInterruptTransfer.TransferFlags &
USBD_TRANSFER_DIRECTION_OUT)
+ DPRINT1("USBD_TRANSFER_DIRECTION_OUT\n");
+ if (Urb->UrbBulkOrInterruptTransfer.TransferFlags &
USBD_SHORT_TRANSFER_OK)
+ DPRINT1("USBD_SHORT_TRANSFER_OK\n");
+ EndPointDesc =
(PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
+ DPRINT("EndPoint is transfer type %x\n",
EndPointDesc->bmAttributes & 0x0F);
+ DPRINT("Endpoint Address %x\n",
EndPointDesc->bEndpointAddress & 0x0F);
+ if ((EndPointDesc->bmAttributes & 0x0F) ==
USB_ENDPOINT_TYPE_BULK)
+ {
+ IoMarkIrpPending(Irp);
+ Status = STATUS_PENDING;
+
+ ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+ UsbDevice,
+ Urb->UrbBulkOrInterruptTransfer.PipeHandle,
+ NULL,
+ Urb->UrbBulkOrInterruptTransfer.TransferFlags,
+ Urb->UrbBulkOrInterruptTransfer.TransferBuffer ?
+ Urb->UrbBulkOrInterruptTransfer.TransferBuffer
:
+
(PVOID)Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL,
+ Urb->UrbBulkOrInterruptTransfer.TransferBuffer ?
+
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength : 0,
+ Irp);
+ }
+ else
+ {
+ DPRINT1("Transfer Type not implemented yet!\n");
+ /* FAKE IT */
+ Status = STATUS_SUCCESS;
+ }
+
+ break;
+ }
+ if (!Urb->UrbBulkOrInterruptTransfer.TransferBuffer)
+ {
+ DPRINT1("TransferBuffer is NULL!\n");
ASSERT(FALSE);
break;
}
- ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer,
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
if (UsbDevice == PdoDeviceExtension->UsbDevices[0])
@@ -122,9 +172,9 @@
if (Urb->UrbBulkOrInterruptTransfer.TransferFlags &
(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
{
LONG i;
- for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++)
- {
- if (PdoDeviceExtension->Ports[i].PortChange)
+ for (i = 0; i < hcd->ECHICaps.HCSParams.PortCount; i++)
+ {
+ if (hcd->Ports[i].PortChange)
{
DPRINT1("Inform hub driver that port %d has
changed\n", i+1);
((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) &
7);
@@ -177,10 +227,7 @@
}
if (UsbDevice == PdoDeviceExtension->UsbDevices[0])
{
- DPRINT1("ROOTHUB!\n");
BufPtr =
(PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer;
-
- DPRINT1("Length %x\n",
Urb->UrbControlDescriptorRequest.TransferBufferLength);
/* Copy the Device Descriptor */
RtlCopyMemory(BufPtr, &UsbDevice->DeviceDescriptor,
sizeof(USB_DEVICE_DESCRIPTOR));
@@ -193,11 +240,17 @@
BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb,
&CtrlSetup);
IoMarkIrpPending(Irp);
Status = STATUS_PENDING;
- SubmitControlTransfer(&FdoDeviceExtension->hcd,
- &CtrlSetup,
-
Urb->UrbControlDescriptorRequest.TransferBuffer,
-
Urb->UrbControlDescriptorRequest.TransferBufferLength,
- Irp);
+ ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+ UsbDevice,
+ 0,
+ &CtrlSetup,
+ 0,
+ Urb->UrbControlDescriptorRequest.TransferBuffer ?
+
Urb->UrbControlDescriptorRequest.TransferBuffer :
+
(PVOID)Urb->UrbControlDescriptorRequest.TransferBufferMDL,
+ Urb->UrbControlDescriptorRequest.TransferBuffer ?
+
Urb->UrbControlDescriptorRequest.TransferBufferLength : 0,
+ Irp);
break;
}
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
@@ -270,12 +323,17 @@
BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb,
&CtrlSetup);
IoMarkIrpPending(Irp);
Status = STATUS_PENDING;
-
- SubmitControlTransfer(&FdoDeviceExtension->hcd,
- &CtrlSetup,
-
Urb->UrbControlDescriptorRequest.TransferBuffer,
-
Urb->UrbControlDescriptorRequest.TransferBufferLength,
- Irp);
+ ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+ UsbDevice,
+ 0,
+ &CtrlSetup,
+ 0,
+ Urb->UrbControlDescriptorRequest.TransferBuffer ?
+
Urb->UrbControlDescriptorRequest.TransferBuffer :
+
(PVOID)Urb->UrbControlDescriptorRequest.TransferBufferMDL,
+ Urb->UrbControlDescriptorRequest.TransferBuffer ?
+
Urb->UrbControlDescriptorRequest.TransferBufferLength : 0,
+ Irp);
break;
}
default:
@@ -290,17 +348,17 @@
PUSBD_INTERFACE_INFORMATION InterfaceInfo;
LONG iCount, pCount;
- DPRINT1("Selecting Configuration\n");
- DPRINT1("ConfigurationHandle
%x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
+ DPRINT("Selecting Configuration\n");
+ DPRINT("ConfigurationHandle
%x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
+
if (Urb->UrbSelectConfiguration.ConfigurationDescriptor)
{
Urb->UrbSelectConfiguration.ConfigurationHandle =
&UsbDevice->ActiveConfig->ConfigurationDescriptor;
- DPRINT1("ConfigHandle %x\n",
Urb->UrbSelectConfiguration.ConfigurationHandle);
- ASSERT(FALSE);
+ DPRINT("ConfigHandle %x\n",
Urb->UrbSelectConfiguration.ConfigurationHandle);
InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
- DPRINT1("Length %x\n", InterfaceInfo->Length);
- DPRINT1("NumberOfPipes %x\n",
InterfaceInfo->NumberOfPipes);
+ DPRINT("Length %x\n", InterfaceInfo->Length);
+ DPRINT("NumberOfPipes %x\n", InterfaceInfo->NumberOfPipes);
for (iCount = 0; iCount <
Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; iCount++)
{
@@ -324,6 +382,29 @@
InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo +
InterfaceInfo->Length);
if (InterfaceInfo->Length == 0) break;
}
+
+ if (UsbDevice != PdoDeviceExtension->UsbDevices[0])
+ {
+ DPRINT("Setting Configuration!\n");
+ BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb,
&CtrlSetup);
+ IoMarkIrpPending(Irp);
+ Status = STATUS_PENDING;
+ DPRINT1("Input Buffer %x, MDL %x\n",
Urb->UrbBulkOrInterruptTransfer.TransferBuffer,
(PVOID)Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
+
+ ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+ UsbDevice,
+ 0,
+ &CtrlSetup,
+ 0,
+ NULL,
+ 0,
+ Irp);
+ break;
+ }
+ else
+ {
+ DPRINT1("Hub only has one configuration.\n");
+ }
}
else
{
@@ -334,7 +415,6 @@
}
case URB_FUNCTION_SELECT_INTERFACE:
{
- USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
PUSBD_INTERFACE_INFORMATION InterfaceInfo;
int i;
@@ -353,12 +433,14 @@
BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb,
&CtrlSetup);
IoMarkIrpPending(Irp);
Status = STATUS_PENDING;
-
- SubmitControlTransfer(&FdoDeviceExtension->hcd,
- &CtrlSetup,
- NULL,
- 0,
- Irp);
+ ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+ UsbDevice,
+ 0,
+ &CtrlSetup,
+ 0,
+ NULL,
+ 0,
+ Irp);
break;
}
case URB_FUNCTION_CLASS_DEVICE:
@@ -425,7 +507,6 @@
}
else
{
- /* FIXME: Handle this correctly */
UsbHubDescr->bDescriptorLength =
sizeof(USB_HUB_DESCRIPTOR);
UsbHubDescr->bDescriptorType = 0x29;
break;
@@ -433,7 +514,7 @@
DPRINT1("USB_DEVICE_CLASS_HUB request\n");
UsbHubDescr->bDescriptorLength =
sizeof(USB_HUB_DESCRIPTOR);
UsbHubDescr->bDescriptorType = 0x29;
- UsbHubDescr->bNumberOfPorts =
PdoDeviceExtension->NumberOfPorts;
+ UsbHubDescr->bNumberOfPorts =
hcd->ECHICaps.HCSParams.PortCount;
UsbHubDescr->wHubCharacteristics = 0x0012;
UsbHubDescr->bPowerOnToPowerGood = 0x01;
UsbHubDescr->bHubControlCurrent = 0x00;
@@ -480,10 +561,10 @@
DPRINT("USB_REQUEST_GET_STATUS Port %d\n",
Urb->UrbControlVendorClassRequest.Index);
ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
- DPRINT("PortStatus %x\n",
PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus);
- DPRINT("PortChange %x\n",
PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange);
- ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] =
PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
- ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] =
PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
+ DPRINT("PortStatus %x\n",
hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus);
+ DPRINT("PortChange %x\n",
hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange);
+ ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] =
hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
+ ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] =
hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
break;
}
case USB_REQUEST_CLEAR_FEATURE:
@@ -492,12 +573,12 @@
{
case C_PORT_CONNECTION:
DPRINT("C_PORT_CONNECTION\n");
-
PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange
&= ~USB_PORT_STATUS_CONNECT;
+
hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &=
~USB_PORT_STATUS_CONNECT;
break;
case C_PORT_RESET:
DPRINT("C_PORT_RESET\n");
-
PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange
&= ~USB_PORT_STATUS_RESET;
-
PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |=
USB_PORT_STATUS_ENABLE;
+
hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &=
~USB_PORT_STATUS_RESET;
+
hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |=
USB_PORT_STATUS_ENABLE;
break;
default:
DPRINT("Unknown Value for Clear Feature %x \n",
Urb->UrbControlVendorClassRequest.Value);
@@ -507,46 +588,49 @@
}
case USB_REQUEST_SET_FEATURE:
{
- DPRINT("USB_REQUEST_SET_FEATURE Port %d, value %x\n",
Urb->UrbControlVendorClassRequest.Index,
+ DPRINT1("USB_REQUEST_SET_FEATURE Port %d, value %x\n",
Urb->UrbControlVendorClassRequest.Index,
Urb->UrbControlVendorClassRequest.Value);
switch(Urb->UrbControlVendorClassRequest.Value)
{
case PORT_RESET:
{
- DPRINT("Port Reset %d\n",
Urb->UrbControlVendorClassRequest.Index-1);
-
PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange |=
USB_PORT_STATUS_RESET;
-
PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus
&= ~USB_PORT_STATUS_ENABLE;
- ResetPort(&FdoDeviceExtension->hcd,
Urb->UrbControlVendorClassRequest.Index-1);
+ DPRINT1("Port Reset %d\n",
Urb->UrbControlVendorClassRequest.Index-1);
+
hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange |=
USB_PORT_STATUS_RESET;
+
hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus &=
~USB_PORT_STATUS_ENABLE;
+ ResetPort(hcd,
Urb->UrbControlVendorClassRequest.Index-1);
break;
}
case PORT_ENABLE:
{
- DPRINT("PORT_ENABLE not implemented\n");
+ DPRINT1("PORT_ENABLE not implemented\n");
break;
}
case PORT_POWER:
{
- DPRINT("PORT_POWER not implemented\n");
+ DPRINT1("PORT_POWER not implemented\n");
break;
}
default:
{
- DPRINT("Unknown Set Feature!\n");
- break;
- }
- }
-
- if
(!(PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus
& 0x8000))
+ DPRINT1("Unknown Set Feature!\n");
+ break;
+ }
+ }
+
+ if
(!(hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus & 0x8000))
+ {
+ DPRINT1("------ PortStatus %x\n",
hcd->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus);
+ DPRINT1("Calling CompletePendingURBRequest\n");
+
CompletePendingURBRequest(PdoDeviceExtension);
-
+ }
break;
}
case USB_REQUEST_SET_ADDRESS:
{
DPRINT1("USB_REQUEST_SET_ADDRESS\n");
- ASSERT(FALSE);
break;
}
case USB_REQUEST_GET_DESCRIPTOR:
@@ -606,7 +690,35 @@
}
case URB_FUNCTION_CLASS_INTERFACE:
{
+ USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
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);
+ 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;
+
+ IoMarkIrpPending(Irp);
+ Status = STATUS_PENDING;
+ ExecuteTransfer(FdoDeviceExtension->DeviceObject,
+ UsbDevice,
+ 0,
+ &CtrlSetup,
+ 0,
+ Urb->UrbControlVendorClassRequest.TransferBuffer ?
+ Urb->UrbControlVendorClassRequest.TransferBuffer :
+
(PVOID)Urb->UrbControlVendorClassRequest.TransferBufferMDL,
+ Urb->UrbControlVendorClassRequest.TransferBuffer ?
+ Urb->UrbControlVendorClassRequest.TransferBufferLength
: 0,
+ Irp);
break;
}
default:
@@ -632,8 +744,9 @@
if (IsListEmpty(&DeviceExtension->IrpQueue))
{
- DPRINT1("There should have been one SCE request pending\n");
+ DPRINT1("There should have been one SCE request pending. Did the usbhub
driver load?\n");
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
+ ASSERT(FALSE);
return;
}
NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);
Modified: trunk/reactos/drivers/usb/usbehci/pdo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/pdo.c?…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/pdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/pdo.c [iso-8859-1] Wed Apr 13 04:48:50 2011
@@ -47,12 +47,8 @@
0x01, /* bNumInterfaces; (1) */
0x23, /* bConfigurationValue; */
0x00, /* iConfiguration; */
- 0x40, /* bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: reserved */
- 0x00 /* MaxPower; */
+ 0x40, /* bmAttributes; */
+ 0x00 /* MaxPower; */
};
const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] =
@@ -66,7 +62,7 @@
0x09, /* bInterfaceClass; HUB_CLASSCODE */
0x01, /* bInterfaceSubClass; */
0x00, /* bInterfaceProtocol: */
- 0x00 /* iInterface; */
+ 0x00 /* iInterface; */
};
const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR [] =
@@ -88,12 +84,14 @@
PIO_STACK_LOCATION Stack = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ULONG_PTR Information = 0;
+ PEHCI_HOST_CONTROLLER hcd;
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)
PdoDeviceExtension->ControllerFdo->DeviceExtension;
ASSERT(PdoDeviceExtension->Common.IsFdo == FALSE);
+ hcd = &FdoDeviceExtension->hcd;
Stack = IoGetCurrentIrpStackLocation(Irp);
switch(Stack->Parameters.DeviceIoControl.IoControlCode)
@@ -108,13 +106,18 @@
UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
+ /* If there was no device passed then this URB is for the RootHub */
if (UsbDevice == NULL)
UsbDevice = PdoDeviceExtension->UsbDevices[0];
+ /* Check if it is a Status Change Endpoint (SCE). The Hub Driver sends this
request and miniports mark the IRP pending
+ if there is no changes on any of the ports. When the DPC of miniport
routine detects changes this IRP will be completed.
+ Based on XEN PV Usb Drivers */
+
if ((Urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER)
&&
(UsbDevice == PdoDeviceExtension->UsbDevices[0]))
{
- DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER on SCE\n");
+ DPRINT("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER on SCE\n");
if (Urb->UrbBulkOrInterruptTransfer.PipeHandle !=
&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor)
{
DPRINT1("PipeHandle doesnt match SCE PipeHandle\n");
@@ -123,12 +126,23 @@
/* Queue the Irp first */
QueueURBRequest(PdoDeviceExtension, Irp);
- /* Check if there is any connected devices */
- for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++)
- {
- if (PdoDeviceExtension->Ports[i].PortChange == 0x01)
+ /* Check for port changes */
+ if (EnumControllerPorts(hcd) == FALSE)
+ {
+ DPRINT("No port change\n");
+ Status = STATUS_PENDING;
+ IoMarkIrpPending(Irp);
+ break;
+ }
+
+ /* If we reached this point then port status has changed, so check
+ which port */
+ for (i = 0; i < hcd->ECHICaps.HCSParams.PortCount; i++)
+ {
+ if (hcd->Ports[i].PortChange == 0x01)
{
- DPRINT1("Inform hub driver that port %d has changed\n",
i+1);
+ DPRINT1("On SCE request: Inform hub driver that port %d has
changed\n", i+1);
+ ASSERT(FALSE);
((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] =
1 << ((i + 1) & 7);
Information = 0;
Status = STATUS_SUCCESS;
@@ -143,15 +157,11 @@
}
}
if (Status == STATUS_SUCCESS) break;
- DPRINT1("Queueing IRP\n");
+
IoMarkIrpPending(Irp);
Status = STATUS_PENDING;
break;
}
- else
- {
- DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB send to device %x\n",
UsbDevice);
- }
Status = HandleUrbRequest(PdoDeviceExtension, Irp);
@@ -186,7 +196,7 @@
}
case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
{
- DPRINT("Ehci: IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n",
Stack->Parameters.Others.Argument2);
+ DPRINT1("Ehci: IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n",
Stack->Parameters.Others.Argument2);
if (Stack->Parameters.Others.Argument1)
{
/* Return the root hubs devicehandle */
@@ -202,12 +212,12 @@
}
case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
{
- DPRINT("Ehci: IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n",
IOCTL_INTERNAL_USB_GET_HUB_COUNT);
+ DPRINT1("Ehci: IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n",
IOCTL_INTERNAL_USB_GET_HUB_COUNT);
ASSERT(Stack->Parameters.Others.Argument1 != NULL);
if (Stack->Parameters.Others.Argument1)
{
- /* FIXME: Determine the number of hubs between the usb device and root
hub */
- DPRINT1("RootHubCount %x\n",
*(PULONG)Stack->Parameters.Others.Argument1);
+ /* FIXME: Determine the number of hubs between the usb device and root
hub.
+ For now we have at least one. */
*(PULONG)Stack->Parameters.Others.Argument1 = 1;
}
Status = STATUS_SUCCESS;
@@ -235,15 +245,14 @@
}
case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
{
- DPRINT("Ehci: IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO Arg1 %x, Arg2
%x\n", Stack->Parameters.Others.Argument1,
Stack->Parameters.Others.Argument2);
+ DPRINT("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n");
+ /* DDK documents that both the PDO and FDO are returned. However, while
writing the UsbHub driver it was determine
+ that this was not the case. Windows usbehci driver gives the Pdo in both
Arguments. Which makes sense as upper level
+ drivers should not be communicating with FDO. */
if (Stack->Parameters.Others.Argument1)
*(PVOID *)Stack->Parameters.Others.Argument1 =
FdoDeviceExtension->Pdo;
-
- /* Windows usbehci driver gives the Pdo in both Arguments. */
if (Stack->Parameters.Others.Argument2)
- //*(PVOID *)Stack->Parameters.Others.Argument2 =
IoGetAttachedDeviceReference(FdoDeviceExtension->DeviceObject);
*(PVOID *)Stack->Parameters.Others.Argument2 =
FdoDeviceExtension->Pdo;
-
Information = 0;
Status = STATUS_SUCCESS;
break;
@@ -254,8 +263,6 @@
DPRINT1("Ehci: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
/* FIXME: Set Callback for safe power down */
CallBackInfo = Stack->Parameters.DeviceIoControl.Type3InputBuffer;
- DPRINT1("IdleCallback %x\n", CallBackInfo->IdleCallback);
- DPRINT1("IdleContext %x\n", CallBackInfo->IdleContext);
PdoDeviceExtension->IdleCallback = CallBackInfo->IdleCallback;
PdoDeviceExtension->IdleContext = CallBackInfo->IdleContext;
@@ -300,6 +307,7 @@
}
case BusQueryHardwareIDs:
{
+ /* FIXME: Build from Device Vendor and Device ID */
Index += swprintf(&Buffer[Index],
L"USB\\ROOT_HUB20&VID8086&PID265C&REV0000") + 1;
Index += swprintf(&Buffer[Index],
L"USB\\ROOT_HUB20&VID8086&PID265C") + 1;
Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20") + 1;
@@ -388,7 +396,6 @@
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
UNICODE_STRING InterfaceSymLinkName;
- LONG i;
DPRINT1("Ehci: PDO StartDevice\n");
PdoDeviceExtension =
(PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -397,15 +404,6 @@
/* Create the root hub */
RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);
- for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++)
- {
- PdoDeviceExtension->Ports[i].PortStatus = 0x8000;
- PdoDeviceExtension->Ports[i].PortChange = 0;
-
- if (!FdoDeviceExtension->hcd.ECHICaps.HCSParams.PortPowerControl)
- PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_POWER;
- }
-
RtlCopyMemory(&RootHubDevice->DeviceDescriptor,
ROOTHUB2_DEVICE_DESCRIPTOR,
sizeof(ROOTHUB2_DEVICE_DESCRIPTOR));
@@ -413,7 +411,8 @@
RootHubDevice->DeviceDescriptor.idVendor =
FdoDeviceExtension->VendorId;
RootHubDevice->DeviceDescriptor.idProduct =
FdoDeviceExtension->DeviceId;
- /* FIXME: Do something better below */
+ /* Here config, interfaces and descriptors are stored. This was duplicated
from XEN PV Usb Drivers implementation.
+ Not sure that it is really needed as the information can be queueried from
the device. */
RootHubDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
sizeof(PVOID) *
RootHubDevice->DeviceDescriptor.bNumConfigurations,
@@ -483,11 +482,11 @@
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
PdoDeviceExtension =
(PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- DPRINT1("BusRelations!!!!!\n");
+ DPRINT("BusRelations!!!!!\n");
/* The hub driver has created the new device object and reported to
pnp, as a result the pnp manager
- has resent this IRP and type, so leave the next SCE request
pending until a new device arrives.
- Is there a better way to do this */
+ has sent this IRP and type, so leave the next SCE request pending
until a new device arrives.
+ Is there a better way to do this? */
ExAcquireFastMutex(&PdoDeviceExtension->ListLock);
PdoDeviceExtension->HaltQueue = TRUE;
ExReleaseFastMutex(&PdoDeviceExtension->ListLock);
@@ -531,7 +530,7 @@
DeviceCapabilities->UINumber = 0;
DeviceCapabilities->DeviceD2 = 1;
- /* FIXME */
+ /* FIXME: Verify these settings are correct */
DeviceCapabilities->HardwareDisabled = FALSE;
//DeviceCapabilities->NoDisplayInUI = FALSE;
DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
Modified: trunk/reactos/drivers/usb/usbehci/transfer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/transf…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/transfer.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/transfer.c [iso-8859-1] Wed Apr 13 04:48:50 2011
@@ -7,9 +7,20 @@
* Michael Martin (michael.martin(a)reactos.org)
*/
+/* All QueueHeads, Descriptors and pipe setup packets used by control transfers are
allocated from common buffer.
+ The routines in physmem manages this buffer. Each allocation is aligned to 32bits,
which is requirement of USB 2.0. */
+
#include "transfer.h"
#include <debug.h>
+
+typedef struct _MAPREGISTERCALLBACKINFO
+{
+ PVOID MapRegisterBase;
+ KEVENT Event;
+}MAPREGISTERCALLBACKINFO, *PMAPREGISTERCALLBACKINFO;
+
+/* Fills CtrlSetup parameter with values based on Urb */
VOID
BuildSetupPacketFromURB(PEHCI_HOST_CONTROLLER hcd, PURB Urb,
PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup)
{
@@ -76,6 +87,7 @@
/* SET CONFIG */
case URB_FUNCTION_SELECT_CONFIGURATION:
+ DPRINT1("Bulding data for Select Config\n");
CtrlSetup->bRequest = USB_REQUEST_SET_CONFIGURATION;
CtrlSetup->wValue.W =
Urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue;
CtrlSetup->wIndex.W = 0;
@@ -131,18 +143,86 @@
}
}
-BOOLEAN
-SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
- PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
- PVOID TransferBuffer,
- ULONG TransferBufferLength,
- PIRP IrpToComplete)
+/* Build a Bulk Transfer with a max transfer of 3 descriptors which each has 5 pointers
to one page of memory, paged align of course */
+PQUEUE_HEAD
+BuildBulkTransfer(PEHCI_HOST_CONTROLLER hcd,
+ ULONG DeviceAddress,
+ USBD_PIPE_HANDLE PipeHandle,
+ UCHAR PidDirection,
+ PMDL pMdl,
+ BOOLEAN FreeMdl)
{
PQUEUE_HEAD QueueHead;
PQUEUE_TRANSFER_DESCRIPTOR Descriptor[3];
- ULONG MdlPhysicalAddr;
- PKEVENT Event = NULL;
- PMDL pMdl = NULL;
+ ULONG MdlByteCount = MmGetMdlByteCount(pMdl);
+ ULONG NeededDescriptorCount = 1;
+ int i;
+
+ QueueHead = CreateQueueHead(hcd);
+ QueueHead->EndPointCharacteristics.DeviceAddress = DeviceAddress;
+
+ if (PipeHandle)
+ {
+ QueueHead->EndPointCharacteristics.EndPointNumber =
((PUSB_ENDPOINT_DESCRIPTOR)PipeHandle)->bEndpointAddress & 0x0F;
+ QueueHead->EndPointCharacteristics.MaximumPacketLength =
((PUSB_ENDPOINT_DESCRIPTOR)PipeHandle)->wMaxPacketSize;
+ }
+
+ QueueHead->FreeMdl = FreeMdl;
+ QueueHead->Mdl = pMdl;
+
+ /* FIXME: This is totally screwed */
+ /* Calculate how many descriptors would be needed to transfer this buffer */
+ if (pMdl)
+ {
+ if (MdlByteCount < (PAGE_SIZE * 5))
+ NeededDescriptorCount = 1;
+ else if (MdlByteCount < (PAGE_SIZE * 10))
+ NeededDescriptorCount = 2;
+ else if (MdlByteCount < (PAGE_SIZE * 15))
+ NeededDescriptorCount = 3;
+ else
+ ASSERT(FALSE);
+ }
+ /* Limiter Transfers to PAGE_SIZE * 5 * 3, Three Descriptors */
+
+ QueueHead->NumberOfTransferDescriptors = NeededDescriptorCount;
+ for (i=0; i< NeededDescriptorCount;i++)
+ {
+ Descriptor[i] = CreateDescriptor(hcd,
+ PidDirection,
+ 0);
+ Descriptor[i]->AlternateNextPointer =
QueueHead->DeadDescriptor->PhysicalAddr;
+
+ if (i > 0)
+ {
+ Descriptor[i-1]->NextDescriptor = Descriptor[i];
+ Descriptor[i]->PreviousDescriptor = Descriptor[i-1];
+ Descriptor[i-1]->NextPointer = Descriptor[i]->PhysicalAddr;
+ }
+ }
+
+ Descriptor[0]->Token.Bits.InterruptOnComplete = TRUE;
+
+ /* Save the first descriptor in the QueueHead */
+ QueueHead->FirstTransferDescriptor = Descriptor[0];
+ QueueHead->NextPointer = Descriptor[0]->PhysicalAddr;
+
+ return QueueHead;
+}
+
+
+/* Builds a QueueHead with 2 to 3 descriptors needed for control transfer
+ 2 descriptors used for and control request that doesnt return data, such as SetAddress
*/
+PQUEUE_HEAD
+BuildControlTransfer(PEHCI_HOST_CONTROLLER hcd,
+ ULONG DeviceAddress,
+ USBD_PIPE_HANDLE PipeHandle,
+ PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
+ PMDL pMdl,
+ BOOLEAN FreeMdl)
+{
+ PQUEUE_HEAD QueueHead;
+ PQUEUE_TRANSFER_DESCRIPTOR Descriptor[3];
PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetupVA, CtrlPhysicalPA;
CtrlSetupVA = (PUSB_DEFAULT_PIPE_SETUP_PACKET)AllocateMemory(hcd,
@@ -150,57 +230,45 @@
(ULONG*)&CtrlPhysicalPA);
RtlCopyMemory(CtrlSetupVA, CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
- /* If no Irp then wait on completion */
- if (IrpToComplete == NULL)
- {
- Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
- KeInitializeEvent(Event, NotificationEvent, FALSE);
- }
-
- if (TransferBuffer)
- {
- /* Allocate Mdl for Buffer */
- pMdl = IoAllocateMdl(TransferBuffer,
- TransferBufferLength,
- FALSE,
- FALSE,
- NULL);
-
- /* Lock Physical Pages */
- MmBuildMdlForNonPagedPool(pMdl);
- //MmProbeAndLockPages(pMdl, KernelMode, IoReadAccess);
-
- MdlPhysicalAddr = MmGetPhysicalAddress((PVOID)TransferBuffer).LowPart;
- }
QueueHead = CreateQueueHead(hcd);
+ QueueHead->EndPointCharacteristics.DeviceAddress = DeviceAddress;
+ if (PipeHandle)
+ QueueHead->EndPointCharacteristics.EndPointNumber =
((PUSB_ENDPOINT_DESCRIPTOR)PipeHandle)->bEndpointAddress & 0x0F;
+
+ QueueHead->Token.Bits.DataToggle = TRUE;
+ QueueHead->FreeMdl = FreeMdl;
+ QueueHead->Mdl = pMdl;
Descriptor[0] = CreateDescriptor(hcd,
PID_CODE_SETUP_TOKEN,
sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
- Descriptor[0]->Token.Bits.InterruptOnComplete = FALSE;
Descriptor[0]->Token.Bits.DataToggle = FALSE;
-
/* Save the first descriptor */
- QueueHead->TransferDescriptor = Descriptor[0];
-
- if (TransferBuffer)
+ QueueHead->FirstTransferDescriptor = Descriptor[0];
+
+ if (pMdl)
{
Descriptor[1] = CreateDescriptor(hcd,
PID_CODE_IN_TOKEN,
- TransferBufferLength);
- }
-
- Descriptor[2] = CreateDescriptor(hcd,
- PID_CODE_OUT_TOKEN,
- 0);
-
- Descriptor[1]->Token.Bits.InterruptOnComplete = FALSE;
+ MmGetMdlByteCount(pMdl));
+
+ Descriptor[2] = CreateDescriptor(hcd,
+ PID_CODE_OUT_TOKEN,
+ 0);
+ }
+ else
+ {
+ Descriptor[2] = CreateDescriptor(hcd,
+ PID_CODE_IN_TOKEN,
+ 0);
+ }
+
+ Descriptor[2]->Token.Bits.InterruptOnComplete = TRUE;
/* Link the descriptors */
-
- if (TransferBuffer)
+ if (pMdl)
{
Descriptor[0]->NextDescriptor = Descriptor[1];
Descriptor[1]->NextDescriptor = Descriptor[2];
@@ -213,35 +281,267 @@
Descriptor[2]->PreviousDescriptor = Descriptor[0];
}
- /* Assign the descritors buffers */
+ /* Assign the descriptor buffers */
Descriptor[0]->BufferPointer[0] = (ULONG)CtrlPhysicalPA;
-
- if (TransferBuffer)
- {
- Descriptor[1]->BufferPointer[0] = MdlPhysicalAddr;
+ Descriptor[0]->BufferPointerVA[0] = (ULONG)CtrlSetupVA;
+
+ if (pMdl)
+ {
Descriptor[0]->NextPointer = Descriptor[1]->PhysicalAddr;
- Descriptor[1]->NextPointer = Descriptor[2]->PhysicalAddr;
+ Descriptor[0]->AlternateNextPointer = Descriptor[2]->PhysicalAddr;
+ Descriptor[1]->NextPointer = Descriptor[2]->PhysicalAddr;
+ Descriptor[1]->AlternateNextPointer = Descriptor[2]->PhysicalAddr;
}
else
{
Descriptor[0]->NextPointer = Descriptor[2]->PhysicalAddr;
+ Descriptor[0]->AlternateNextPointer = Descriptor[2]->PhysicalAddr;
}
QueueHead->NextPointer = Descriptor[0]->PhysicalAddr;
+ if (pMdl)
+ QueueHead->NumberOfTransferDescriptors = 3;
+ else
+ QueueHead->NumberOfTransferDescriptors = 2;
+ return QueueHead;
+}
+
+
+IO_ALLOCATION_ACTION NTAPI MapRegisterCallBack(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID MapRegisterBase,
+ PVOID Context)
+{
+ PMAPREGISTERCALLBACKINFO CallBackInfo = (PMAPREGISTERCALLBACKINFO)Context;
+
+ CallBackInfo->MapRegisterBase = MapRegisterBase;
+
+ KeSetEvent(&CallBackInfo->Event, IO_NO_INCREMENT, FALSE);
+ return KeepObject;
+}
+
+
+NTSTATUS
+ExecuteTransfer(PDEVICE_OBJECT DeviceObject,
+ PUSB_DEVICE UsbDevice,
+ USBD_PIPE_HANDLE PipeHandle,
+ PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
+ ULONG TransferFlags,
+ PVOID TransferBufferOrMdl,
+ ULONG TransferBufferLength,
+ PIRP IrpToComplete)
+{
+ PUSB_ENDPOINT_DESCRIPTOR EndPointDesc = NULL;
+ PEHCI_HOST_CONTROLLER hcd;
+ PQUEUE_HEAD QueueHead;
+ PKEVENT CompleteEvent = NULL;
+ PMAPREGISTERCALLBACKINFO CallBackInfo;
+ LARGE_INTEGER TimeOut;
+ PMDL pMdl = NULL;
+ BOOLEAN FreeMdl = FALSE;
+ PVOID VirtualAddressOfMdl;
+ ULONG NumberOfMapRegisters;
+ KIRQL OldIrql;
+ NTSTATUS Status = STATUS_SUCCESS;
+ UCHAR EndPointType, PidDirection;
+ BOOLEAN IsReadOp = TRUE;
+ ULONG TransferBtyesOffset, CurrentTransferBytes;
+ PQUEUE_TRANSFER_DESCRIPTOR Descriptor;
+ PHYSICAL_ADDRESS PhysicalAddr;
+ int i,j;
+
+ hcd = &((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->hcd;
+
+ /* If no Irp then we will need to wait on completion */
+ if (IrpToComplete == NULL)
+ {
+ CompleteEvent = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
+ KeInitializeEvent(CompleteEvent, NotificationEvent, FALSE);
+ }
+
+ CallBackInfo = ExAllocatePool(NonPagedPool, sizeof(MAPREGISTERCALLBACKINFO));
+ CallBackInfo->MapRegisterBase = 0;
+
+ KeInitializeEvent(&CallBackInfo->Event, NotificationEvent, FALSE);
+
+ /* Determine EndPoint Type */
+ if (!PipeHandle)
+ {
+ EndPointType = USB_ENDPOINT_TYPE_CONTROL;
+ }
+ else
+ {
+ EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)PipeHandle;
+ EndPointType = EndPointDesc->bmAttributes & 0x0F;
+ }
+
+ if (TransferBufferOrMdl)
+ {
+ /* Create MDL for Buffer */
+ if (TransferBufferLength)
+ {
+ pMdl = IoAllocateMdl(TransferBufferOrMdl,
+ TransferBufferLength,
+ FALSE,
+ FALSE,
+ NULL);
+ /* UEHCI created the MDL so it needs to free it */
+ FreeMdl = TRUE;
+ }
+ else
+ {
+ pMdl = TransferBufferOrMdl;
+ }
+ MmBuildMdlForNonPagedPool(pMdl);
+ }
+
+ switch (EndPointType)
+ {
+ case USB_ENDPOINT_TYPE_CONTROL:
+ {
+ QueueHead = BuildControlTransfer(hcd,
+ UsbDevice->Address,
+ PipeHandle,
+ CtrlSetup,
+ pMdl,
+ FreeMdl);
+ IsReadOp = TRUE;
+ break;
+ }
+ case USB_ENDPOINT_TYPE_BULK:
+ {
+ PidDirection = EndPointDesc->bEndpointAddress >> 7;
+ if (PidDirection)
+ IsReadOp = FALSE;
+
+ QueueHead = BuildBulkTransfer(hcd,
+ UsbDevice->Address,
+ PipeHandle,
+ PidDirection,
+ pMdl,
+ FreeMdl);
+
+ break;
+ }
+ case USB_ENDPOINT_TYPE_INTERRUPT:
+ {
+ DPRINT1("Interrupt Endpoints not implemented yet!\n");
+ break;
+ }
+ case USB_ENDPOINT_TYPE_ISOCHRONOUS:
+ {
+ DPRINT1("Isochronous Endpoints not implemented yet!\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unknown Endpoint type!!\n");
+ break;
+ }
+ }
QueueHead->IrpToComplete = IrpToComplete;
- QueueHead->MdlToFree = pMdl;
- QueueHead->Event = Event;
-
- /* Link in the QueueHead */
- LinkQueueHead(hcd, QueueHead);
-
+ QueueHead->Event = CompleteEvent;
+
+ if (!pMdl)
+ {
+ ASSERT(QueueHead->NumberOfTransferDescriptors == 2);
+ LinkQueueHead(hcd, QueueHead);
+ if (IrpToComplete == NULL)
+ {
+ DPRINT1("Waiting For Completion %x!\n", CompleteEvent);
+ TimeOut.QuadPart = -10000000;
+ KeWaitForSingleObject(CompleteEvent, Suspended, KernelMode, FALSE,
NULL);//&TimeOut);
+ DPRINT1("Request Completed\n");
+ ExFreePool(CompleteEvent);
+ }
+ return Status;
+ }
+ //ASSERT(FALSE);
+
+ KeFlushIoBuffers(pMdl, IsReadOp, TRUE);
+ NumberOfMapRegisters = 15;
+
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+
hcd->pDmaAdapter->DmaOperations->AllocateAdapterChannel(hcd->pDmaAdapter,
+
((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ControllerFdo,
+ NumberOfMapRegisters,
+ MapRegisterCallBack,
+ (PVOID)CallBackInfo);
+ KeLowerIrql(OldIrql);
+ DPRINT1("Waiting for AdapterChannel\n");
+ KeWaitForSingleObject(&CallBackInfo->Event, Suspended, KernelMode, FALSE,
NULL);
+ DPRINT1("Dma controller ready!\n");
+ DPRINT1("Getting address for MDL %x\n", pMdl);
+
+ VirtualAddressOfMdl = MmGetMdlVirtualAddress(pMdl);
+
+ TransferBtyesOffset = 0;
+ while (TransferBtyesOffset < MmGetMdlByteCount(pMdl))
+ {
+ CurrentTransferBytes = MmGetMdlByteCount(pMdl);
+ Descriptor = QueueHead->FirstTransferDescriptor;
+ if ((Descriptor->Token.Bits.PIDCode == PID_CODE_SETUP_TOKEN) &&
(QueueHead->NumberOfTransferDescriptors == 3))
+ {
+ DPRINT1("QueueHead is for endpoint 0\n");
+ DPRINT1("MapRegisterBase %x\n", CallBackInfo->MapRegisterBase);
+ DPRINT1("VirtualAddressOfMdl %x, TransferBytesOffset %x\n",
VirtualAddressOfMdl, TransferBtyesOffset);
+ Descriptor = Descriptor->NextDescriptor;
+ PhysicalAddr =
hcd->pDmaAdapter->DmaOperations->MapTransfer(hcd->pDmaAdapter,
+ pMdl,
+
CallBackInfo->MapRegisterBase,
+
(PVOID)((ULONG_PTR)VirtualAddressOfMdl + TransferBtyesOffset),
+
&CurrentTransferBytes,
+ !IsReadOp);
+ DPRINT1("BufferPointer[0] = %x\n", PhysicalAddr.LowPart);
+ Descriptor->BufferPointer[0] = PhysicalAddr.LowPart;
+ DPRINT1("CurrentTransferBytes %x\n", CurrentTransferBytes);
+ TransferBtyesOffset += CurrentTransferBytes;
+ LinkQueueHead(hcd, QueueHead);
+ break;
+ }
+ DPRINT1("PID_CODE_SETUP_TOKEN %x, PidDirection %x, NumDesc %x\n",
PID_CODE_SETUP_TOKEN, PidDirection, QueueHead->NumberOfTransferDescriptors);
+ for (i=0; i<QueueHead->NumberOfTransferDescriptors; i++)
+ {
+ if (Descriptor->Token.Bits.PIDCode != PID_CODE_SETUP_TOKEN)
+ {
+ for (j=0; j<5; j++)
+ {
+ PhysicalAddr =
hcd->pDmaAdapter->DmaOperations->MapTransfer(hcd->pDmaAdapter,
+ pMdl,
+
CallBackInfo->MapRegisterBase,
+
(PVOID)((ULONG_PTR)VirtualAddressOfMdl + TransferBtyesOffset),
+
&CurrentTransferBytes,
+
!IsReadOp);
+ DPRINT1("BufferPointer[%d] = %x\n", j,
PhysicalAddr.LowPart);
+ Descriptor->BufferPointer[j] = PhysicalAddr.LowPart;
+ TransferBtyesOffset += CurrentTransferBytes;
+ if (TransferBtyesOffset >= MmGetMdlByteCount(pMdl))
+ break;
+ }
+ }
+ Descriptor = Descriptor->NextDescriptor;
+ }
+ LinkQueueHead(hcd, QueueHead);
+ break;
+ }
+
+ if (TransferBtyesOffset < MmGetMdlByteCount(pMdl)) ASSERT(FALSE);
if (IrpToComplete == NULL)
{
- DPRINT1("Waiting For Completion %x!\n", Event);
- KeWaitForSingleObject(Event, Suspended, KernelMode, FALSE, NULL);
- ExFreePool(Event);
- }
-
- return TRUE;
+ DPRINT1("Waiting For Completion %x!\n", CompleteEvent);
+ TimeOut.QuadPart = -10000000;
+ KeWaitForSingleObject(CompleteEvent, Suspended, KernelMode, FALSE,
NULL);//&TimeOut);
+ DPRINT1("Request Completed\n");
+ ExFreePool(CompleteEvent);
+ }
+
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+ hcd->pDmaAdapter->DmaOperations->FreeMapRegisters(hcd->pDmaAdapter,
+ CallBackInfo->MapRegisterBase,
+ NumberOfMapRegisters);
+
+ hcd->pDmaAdapter->DmaOperations->FreeAdapterChannel (hcd->pDmaAdapter);
+ KeLowerIrql(OldIrql);
+ return Status;
}
Modified: trunk/reactos/drivers/usb/usbehci/transfer.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/transf…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/transfer.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/transfer.h [iso-8859-1] Wed Apr 13 04:48:50 2011
@@ -3,18 +3,37 @@
#include "hardware.h"
#include "hwiface.h"
#include "physmem.h"
+#include "usbehci.h"
#include <usb.h>
#include <ntddk.h>
-BOOLEAN
-SubmitControlTransfer(PEHCI_HOST_CONTROLLER hcd,
- PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
- PVOID TransferBuffer,
- ULONG TransferBufferLength,
- PIRP IrpToComplete);
+PQUEUE_HEAD
+BuildControlTransfer(PEHCI_HOST_CONTROLLER hcd,
+ ULONG DeviceAddress,
+ USBD_PIPE_HANDLE PipeHandle,
+ PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
+ PMDL pMdl,
+ BOOLEAN FreeMdl);
+
+PQUEUE_HEAD
+BuildBulkTransfer(PEHCI_HOST_CONTROLLER hcd,
+ ULONG DeviceAddress,
+ USBD_PIPE_HANDLE PipeHandle,
+ UCHAR PidDirection,
+ PMDL pMdl,
+ BOOLEAN FreeMdl);
VOID
BuildSetupPacketFromURB(PEHCI_HOST_CONTROLLER hcd,
PURB Urb,
PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup);
+NTSTATUS
+ExecuteTransfer(PDEVICE_OBJECT DeviceObject,
+ PUSB_DEVICE UsbDevice,
+ USBD_PIPE_HANDLE PipeHandle,
+ PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup,
+ ULONG TransferFlags,
+ PVOID TransferBufferOrMdl,
+ ULONG TransferBufferLength,
+ PIRP IrpToComplete);