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?r... ============================================================================== --- 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?r... ============================================================================== --- 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/transfe... ============================================================================== --- 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@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/transfe... ============================================================================== --- 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);