diff --git a/reactos/drivers/usb/usbehci/fdo.c b/reactos/drivers/usb/usbehci/fdo.c index 29cf7fad77a..1886f4ae119 100644 --- a/reactos/drivers/usb/usbehci/fdo.c +++ b/reactos/drivers/usb/usbehci/fdo.c @@ -7,38 +7,11 @@ * Michael Martin (michael.martin@reactos.org) */ -/* INCLUDES *******************************************************************/ +#include "hwiface.h" #include "usbehci.h" +#include "physmem.h" #include -VOID NTAPI -TimerDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2) -{ - PFDO_DEVICE_EXTENSION FdoDeviceExtension; - PPDO_DEVICE_EXTENSION PdoDeviceExtension; - ULONG tmp; - ULONG Base; - LONG i; - - FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeferredContext; - PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension; - - Base = (ULONG)FdoDeviceExtension->ResourceMemory; - - for (i = 0; i < FdoDeviceExtension->ECHICaps.HCSParams.PortCount; i++) - { - tmp = READ_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i))); - - if ((tmp & 0x04) && (!(PdoDeviceExtension->Ports[i].PortChange & USB_PORT_STATUS_RESET))) - { - DPRINT("Port %x is enabled\n", i); - PdoDeviceExtension->Ports[i].PortChange |= USB_PORT_STATUS_RESET; - CompletePendingURBRequest(PdoDeviceExtension); - } - } - return; -} - VOID NTAPI EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2) { @@ -46,7 +19,8 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO PPDO_DEVICE_EXTENSION PdoDeviceExtension; ULONG CStatus; ULONG tmp; - ULONG Base; + ULONG OpRegisters; + PEHCI_HOST_CONTROLLER hcd; LONG i; FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeferredContext; @@ -59,17 +33,122 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension; - Base = (ULONG)FdoDeviceExtension->ResourceMemory; + OpRegisters = (ULONG)FdoDeviceExtension->hcd.OpRegisters; + hcd = &FdoDeviceExtension->hcd; + CStatus = (ULONG) SystemArgument2; + + /* TD retired or Error */ + if (CStatus & (EHCI_STS_INT | EHCI_ERROR_INT)) + { + DPRINT("Asyn Complete!\n"); + ULONG CurrentAddr, OffSet; + PQUEUE_HEAD CompletedQH, NextQH; + PQUEUE_TRANSFER_DESCRIPTOR CompletedTD; + + /* AsyncListAddr Register will have the next QueueHead to execute */ + CurrentAddr = GetAsyncListQueueRegister(hcd); + + /* Calculate the VA for the next QueueHead */ + OffSet = CurrentAddr - (ULONG)FdoDeviceExtension->hcd.CommonBufferPA.LowPart; + NextQH = (PQUEUE_HEAD)((ULONG)FdoDeviceExtension->hcd.CommonBufferVA + OffSet); + + /* Get the previous QueueHead which is the QueueHead just completed */ + CompletedQH = NextQH->PreviousQueueHead; + ASSERT(CompletedQH); + DPRINT("CompletedQH %x\n", CompletedQH); + + //DumpQueueHead(CompletedQH); + + /* Free memory for the Descriptors */ + CompletedTD = CompletedQH->TransferDescriptor; + //DumpTransferDescriptor(CompletedTD); + FreeDescriptor(CompletedTD); + CompletedTD = CompletedTD->NextDescriptor; + //DumpTransferDescriptor(CompletedTD); + FreeDescriptor(CompletedTD); + CompletedTD = CompletedTD->NextDescriptor; + //DumpTransferDescriptor(CompletedTD); + FreeDescriptor(CompletedTD); + + /* If the Event is set then release waiter */ + if (CompletedQH->Event) + { + KeSetEvent(CompletedQH->Event, IO_NO_INCREMENT, FALSE); + } + + /* Free the Mdl */ + ASSERT(CompletedQH->MdlToFree); + IoFreeMdl(CompletedQH->MdlToFree); + + /* Is there an IRP that needs to be completed */ + if (CompletedQH->IrpToComplete) + { + PIRP Irp; + + Irp = CompletedQH->IrpToComplete; + + /* Check for error */ + if (CStatus & EHCI_ERROR_INT) + { + PIO_STACK_LOCATION Stack; + PURB Urb; + + Stack = IoGetCurrentIrpStackLocation(Irp); + ASSERT(Stack); + Urb = (PURB) Stack->Parameters.Others.Argument1; + ASSERT(FALSE); + /* Haled bit should be set */ + if (CompletedQH->Token.Bits.Halted) + { + if (CompletedQH->Token.Bits.DataBufferError) + { + DPRINT1("Data buffer error\n"); + Urb->UrbHeader.Status = USBD_STATUS_DATA_BUFFER_ERROR; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + } + else if (CompletedQH->Token.Bits.BabbleDetected) + { + DPRINT1("Babble Detected\n"); + Urb->UrbHeader.Status = USBD_STATUS_BABBLE_DETECTED; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + } + else + { + DPRINT1("Stall PID\n"); + Urb->UrbHeader.Status = USBD_STATUS_STALL_PID; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + } + } + } + else + { + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + DPRINT1("Completing Irp\n"); + + } + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + /* Unlink QueueHead */ + UnlinkQueueHead(hcd, CompletedQH); + /* Wait for a complete AsnycList tranversal before deleting? */ + DeleteQueueHead(CompletedQH); + } + /* Port Change */ if (CStatus & EHCI_STS_PCD) { /* Loop through the ports */ - for (i = 0; i < FdoDeviceExtension->ECHICaps.HCSParams.PortCount; i++) + for (i = 0; i < FdoDeviceExtension->hcd.ECHICaps.HCSParams.PortCount; i++) { - tmp = READ_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i))); + tmp = READ_REGISTER_ULONG((PULONG) ((OpRegisters + EHCI_PORTSC) + (4 * i))); /* Check for port change on this port */ if (tmp & 0x02) @@ -80,9 +159,9 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO DPRINT1("Device connected on port %d\n", i); /* Check if a companion host controller exists */ - if (FdoDeviceExtension->ECHICaps.HCSParams.CHCCount) + if (FdoDeviceExtension->hcd.ECHICaps.HCSParams.CHCCount) { - tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i))); + tmp = READ_REGISTER_ULONG((PULONG)((OpRegisters + EHCI_PORTSC) + (4 * i))); /* Port should be in disabled state, as per USB 2.0 specs */ if (tmp & 0x04) @@ -93,9 +172,9 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO /* Is this non high speed device */ if (tmp & 0x400) { - DPRINT1("Releasing ownership to companion host controller!\n"); + DPRINT1("Non HighSpeed device connected. Releasing ownership.\n"); /* Release ownership to companion host controller */ - WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), 0x4000); + WRITE_REGISTER_ULONG((PULONG) ((OpRegisters + EHCI_PORTSC) + (4 * i)), 0x2000); continue; } } @@ -111,13 +190,14 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO //KeStallExecutionProcessor(20); - tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i))); + tmp = READ_REGISTER_ULONG((PULONG)((OpRegisters + EHCI_PORTSC) + (4 * i))); PdoDeviceExtension->ChildDeviceCount++; PdoDeviceExtension->Ports[i].PortStatus &= ~0x8000; + PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_HIGH_SPEED; PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_CONNECT; PdoDeviceExtension->Ports[i].PortChange |= USB_PORT_STATUS_CONNECT; - + DPRINT1("Completing URB\n"); CompletePendingURBRequest(PdoDeviceExtension); } else @@ -125,13 +205,19 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO DPRINT1("Device disconnected on port %d\n", i); /* Clear status change */ - tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i))); + tmp = READ_REGISTER_ULONG((PULONG)((OpRegisters + EHCI_PORTSC) + (4 * i))); tmp |= 0x02; - WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), tmp); + WRITE_REGISTER_ULONG((PULONG) ((OpRegisters + EHCI_PORTSC) + (4 * i)), tmp); } } } } + + /* Asnyc Advance */ + if (CStatus & EHCI_STS_IAA) + { + DPRINT1("Async Advance!\n"); + } } BOOLEAN NTAPI @@ -139,17 +225,15 @@ InterruptService(PKINTERRUPT Interrupt, PVOID ServiceContext) { PFDO_DEVICE_EXTENSION FdoDeviceExtension; PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT) ServiceContext; - ULONG CurrentFrame; - ULONG Base; + PEHCI_HOST_CONTROLLER hcd; ULONG CStatus = 0; FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension; - Base = (ULONG)FdoDeviceExtension->ResourceMemory; + hcd = &FdoDeviceExtension->hcd; /* Read device status */ - CStatus = READ_REGISTER_ULONG ((PULONG) (Base + EHCI_USBSTS)); - CurrentFrame = READ_REGISTER_ULONG((PULONG) (Base + EHCI_FRINDEX)); + CStatus = ReadControllerStatus(hcd); CStatus &= (EHCI_ERROR_INT | EHCI_STS_INT | EHCI_STS_IAA | EHCI_STS_PCD | EHCI_STS_FLR); @@ -158,9 +242,9 @@ InterruptService(PKINTERRUPT Interrupt, PVOID ServiceContext) /* This interrupt isnt for us or not ready for it. */ return FALSE; } - + /* Clear status */ - WRITE_REGISTER_ULONG((PULONG) (Base + EHCI_USBSTS), CStatus); + ClearControllerStatus(hcd, CStatus); if (CStatus & EHCI_ERROR_INT) { @@ -179,239 +263,10 @@ InterruptService(PKINTERRUPT Interrupt, PVOID ServiceContext) /* FIXME: Reset the controller */ } - if (CStatus & EHCI_STS_INT) - { - FdoDeviceExtension->AsyncComplete = TRUE; - } - KeInsertQueueDpc(&FdoDeviceExtension->DpcObject, FdoDeviceExtension, (PVOID)CStatus); - return TRUE; } -BOOLEAN -ResetPort(PFDO_DEVICE_EXTENSION FdoDeviceExtension, UCHAR Port) -{ - ULONG Base; - ULONG tmp; - LARGE_INTEGER DueTime; - - DPRINT("Reset Port %x\n", Port); - - Base = (ULONG)FdoDeviceExtension->ResourceMemory; - - tmp = READ_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * Port))); - tmp |= 0x100; - WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * Port)), tmp); - - DueTime.QuadPart = -100; - - KeSetTimerEx(&FdoDeviceExtension->UpdateTimer, DueTime, 0, &FdoDeviceExtension->TimerDpcObject); - return TRUE; -} - -VOID -StopEhci(PDEVICE_OBJECT DeviceObject) -{ - PFDO_DEVICE_EXTENSION FdoDeviceExtension; - PEHCI_USBCMD_CONTENT UsbCmd; - ULONG base; - LONG tmp; - - DPRINT("Stopping Ehci controller\n"); - FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - base = (ULONG)FdoDeviceExtension->ResourceMemory; - - WRITE_REGISTER_ULONG((PULONG) (base + EHCI_USBINTR), 0); - - tmp = READ_REGISTER_ULONG((PULONG) (base + EHCI_USBCMD)); - UsbCmd = (PEHCI_USBCMD_CONTENT) & tmp; - UsbCmd->Run = 0; - WRITE_REGISTER_ULONG((PULONG) (base + EHCI_USBCMD), tmp); -} - -VOID -StartEhci(PDEVICE_OBJECT DeviceObject) -{ - PFDO_DEVICE_EXTENSION FdoDeviceExtension; - PEHCI_USBCMD_CONTENT UsbCmd; - PEHCI_USBSTS_CONTEXT usbsts; - NTSTATUS Status; - LONG tmp; - LONG tmp2; - ULONG base; - - DPRINT("Starting Ehci controller\n"); - FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - base = (ULONG)FdoDeviceExtension->ResourceMemory; - - tmp = READ_REGISTER_ULONG ((PULONG)(base + EHCI_USBCMD)); - - /* Stop the device */ - UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; - UsbCmd->Run = 0; - WRITE_REGISTER_ULONG ((PULONG)(base + EHCI_USBCMD), tmp); - - /* Wait for the device to stop */ - for (;;) - { - KeStallExecutionProcessor(10); - tmp = READ_REGISTER_ULONG((PULONG)(base + EHCI_USBSTS)); - usbsts = (PEHCI_USBSTS_CONTEXT)&tmp; - - if (usbsts->HCHalted) - { - break; - } - DPRINT("Waiting for Halt, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(base + EHCI_USBSTS))); - } - - tmp = READ_REGISTER_ULONG ((PULONG)(base + EHCI_USBCMD)); - - /* Reset the device */ - UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; - UsbCmd->HCReset = TRUE; - WRITE_REGISTER_ULONG ((PULONG)(base + EHCI_USBCMD), tmp); - - /* Wait for the device to reset */ - for (;;) - { - KeStallExecutionProcessor(10); - tmp = READ_REGISTER_ULONG((PULONG)(base + EHCI_USBCMD)); - UsbCmd = (PEHCI_USBCMD_CONTENT)&tmp; - - if (!UsbCmd->HCReset) - { - break; - } - DPRINT("Waiting for reset, USBCMD: %x\n", READ_REGISTER_ULONG ((PULONG)(base + EHCI_USBCMD))); - } - - UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; - - /* Disable Interrupts on the device */ - WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBINTR), 0); - /* Clear the Status */ - WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBSTS), 0x0000001f); - - WRITE_REGISTER_ULONG((PULONG)(base + EHCI_CTRLDSSEGMENT), 0); - - /* Set the Periodic Frame List */ - WRITE_REGISTER_ULONG((PULONG)(base + EHCI_PERIODICLISTBASE), FdoDeviceExtension->PeriodicFramListPhysAddr.LowPart); - /* Set the Async List Queue */ - WRITE_REGISTER_ULONG((PULONG) (base + EHCI_ASYNCLISTBASE), FdoDeviceExtension->AsyncListQueueHeadPtrPhysAddr.LowPart & ~(0x1f)); - - /* Set the ansync and periodic to disable */ - UsbCmd->PeriodicEnable = 0; - UsbCmd->AsyncEnable = 0; - WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBCMD), tmp); - - /* Set the threshold */ - UsbCmd->IntThreshold = 1; - WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBCMD), tmp); - - KeInitializeDpc(&FdoDeviceExtension->DpcObject, - EhciDefferedRoutine, - FdoDeviceExtension); - - KeInitializeDpc(&FdoDeviceExtension->TimerDpcObject, - TimerDefferedRoutine, - FdoDeviceExtension); - - - Status = IoConnectInterrupt(&FdoDeviceExtension->EhciInterrupt, - InterruptService, - FdoDeviceExtension->DeviceObject, - NULL, - FdoDeviceExtension->Vector, - FdoDeviceExtension->Irql, - FdoDeviceExtension->Irql, - FdoDeviceExtension->Mode, - FdoDeviceExtension->IrqShared, - FdoDeviceExtension->Affinity, - FALSE); - - /* Turn back on interrupts */ - WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBINTR), - EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR - | EHCI_USBINTR_FLROVR | EHCI_USBINTR_PC); - WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBINTR), - EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR - | EHCI_USBINTR_FLROVR | EHCI_USBINTR_PC); - - UsbCmd->Run = 1; - WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBCMD), tmp); - - /* Wait for the device to start */ - for (;;) - { - KeStallExecutionProcessor(10); - tmp2 = READ_REGISTER_ULONG((PULONG)(base + EHCI_USBSTS)); - usbsts = (PEHCI_USBSTS_CONTEXT)&tmp2; - - if (!usbsts->HCHalted) - { - break; - } - DPRINT("Waiting for start, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(base + EHCI_USBSTS))); - } - - /* Set all port routing to ECHI controller */ - WRITE_REGISTER_ULONG((PULONG)(base + EHCI_CONFIGFLAG), 1); -} - -VOID -GetCapabilities(PFDO_DEVICE_EXTENSION DeviceExtension, ULONG Base) -{ - PEHCI_CAPS PCap; - PEHCI_HCS_CONTENT PHCS; - LONG i; - - if (!DeviceExtension) - return; - - PCap = &DeviceExtension->ECHICaps; - - PCap->Length = READ_REGISTER_UCHAR((PUCHAR)Base); - PCap->Reserved = READ_REGISTER_UCHAR((PUCHAR)(Base + 1)); - PCap->HCIVersion = READ_REGISTER_USHORT((PUSHORT)(Base + 2)); - PCap->HCSParamsLong = READ_REGISTER_ULONG((PULONG)(Base + 4)); - PCap->HCCParams = READ_REGISTER_ULONG((PULONG)(Base + 8)); - - DPRINT("Length %d\n", PCap->Length); - DPRINT("Reserved %d\n", PCap->Reserved); - DPRINT("HCIVersion %x\n", PCap->HCIVersion); - DPRINT("HCSParams %x\n", PCap->HCSParamsLong); - DPRINT("HCCParams %x\n", PCap->HCCParams); - - if (PCap->HCCParams & 0x02) - DPRINT1("Frame list size is configurable\n"); - - if (PCap->HCCParams & 0x01) - DPRINT1("64bit address mode not supported!\n"); - - DPRINT1("Number of Ports: %d\n", PCap->HCSParams.PortCount); - - if (PCap->HCSParams.PortPowerControl) - DPRINT1("Port Power Control is enabled\n"); - - if (!PCap->HCSParams.CHCCount) - { - DPRINT1("Number of Companion Host controllers %x\n", PCap->HCSParams.CHCCount); - DPRINT1("Number of Ports Per CHC: %d\n", PCap->HCSParams.PortPerCHC); - } - - /* Copied from USBDRIVER in trunk */ - PHCS = (PEHCI_HCS_CONTENT)&DeviceExtension->ECHICaps.HCSParams; - if (PHCS->PortRouteRules) - { - for (i = 0; i < PCap->HCSParams.PortCount; i++) - { - PCap->PortRoute[i] = READ_REGISTER_UCHAR((PUCHAR) (Base + 12 + i)); - } - } -} - NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated) { @@ -427,62 +282,6 @@ StartDevice(PDEVICE_OBJECT DeviceObject, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PART FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION)); - DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; - DeviceDescription.Master = TRUE; - DeviceDescription.ScatterGather = TRUE; - DeviceDescription.Dma32BitAddresses = TRUE; - DeviceDescription.DmaWidth = 2; - DeviceDescription.InterfaceType = PCIBus; - DeviceDescription.MaximumLength = EHCI_MAX_SIZE_TRANSFER; - - FdoDeviceExtension->pDmaAdapter = IoGetDmaAdapter(FdoDeviceExtension->LowerDevice, - &DeviceDescription, - &FdoDeviceExtension->MapRegisters); - - if (FdoDeviceExtension->pDmaAdapter == NULL) - { - DPRINT1("IoGetDmaAdapter failed!\n"); - ASSERT(FALSE); - } - - /* Allocate Common Buffer for Periodic Frame List */ - FdoDeviceExtension->PeriodicFramList = - FdoDeviceExtension->pDmaAdapter->DmaOperations->AllocateCommonBuffer(FdoDeviceExtension->pDmaAdapter, - sizeof(ULONG) * 1024, &FdoDeviceExtension->PeriodicFramListPhysAddr, FALSE); - - if (FdoDeviceExtension->PeriodicFramList == NULL) - { - DPRINT1("FdoDeviceExtension->PeriodicFramList is null\n"); - return STATUS_UNSUCCESSFUL; - } - - /* Zeroize it */ - RtlZeroMemory(FdoDeviceExtension->PeriodicFramList, sizeof(ULONG) * 1024); - - ExInitializeFastMutex(&FdoDeviceExtension->FrameListMutex); - - /* Allocate Common Buffer for Async List Head Queue */ - FdoDeviceExtension->AsyncListQueueHeadPtr = - FdoDeviceExtension->pDmaAdapter->DmaOperations->AllocateCommonBuffer(FdoDeviceExtension->pDmaAdapter, - /* FIXME: Memory Size should be calculated using - structures sizes needed for queue head + 20480 (max data transfer */ - 20800, - &FdoDeviceExtension->AsyncListQueueHeadPtrPhysAddr, FALSE); - - if (FdoDeviceExtension->AsyncListQueueHeadPtr == NULL) - { - DPRINT1("Failed to allocate common buffer for AsyncListQueueHeadPtr!\n"); - return STATUS_UNSUCCESSFUL; - } - - /* Zeroize it */ - RtlZeroMemory(FdoDeviceExtension->AsyncListQueueHeadPtr, - /* FIXME: Same as FIXME above */ - 20800); - - ExInitializeFastMutex(&FdoDeviceExtension->AsyncListMutex); - Status = IoGetDeviceProperty(FdoDeviceExtension->LowerDevice, DevicePropertyAddress, sizeof(ULONG), @@ -531,26 +330,21 @@ StartDevice(PDEVICE_OBJECT DeviceObject, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PART } case CmResourceTypeMemory: { - ULONG ResourceBase = 0; - ULONG MemLength; + PVOID ResourceBase = 0; DPRINT("Mem Start: %x\n", resource->u.Memory.Start); DPRINT("Mem Length: %d\n", resource->u.Memory.Length); - ResourceBase = (ULONG) MmMapIoSpace(resource->u.Memory.Start, resource->u.Memory.Length, FALSE); + ResourceBase = MmMapIoSpace(resource->u.Memory.Start, resource->u.Memory.Length, FALSE); DPRINT("ResourceBase %x\n", ResourceBase); - - FdoDeviceExtension->ResourceBase = (PULONG) ResourceBase; - GetCapabilities(FdoDeviceExtension, (ULONG)ResourceBase); - FdoDeviceExtension->ResourceMemory = (PULONG)((ULONG)ResourceBase + FdoDeviceExtension->ECHICaps.Length); - DPRINT("ResourceMemory %x\n", FdoDeviceExtension->ResourceMemory); - if (FdoDeviceExtension->ResourceBase == NULL) + if (ResourceBase == NULL) { DPRINT1("MmMapIoSpace failed!!!!!!!!!\n"); } - MemLength = resource->u.Memory.Length; - FdoDeviceExtension->Size = MemLength; + GetCapabilities(&FdoDeviceExtension->hcd.ECHICaps, (ULONG)ResourceBase); + DPRINT1("hcd.ECHICaps.Length %x\n", FdoDeviceExtension->hcd.ECHICaps.Length); + FdoDeviceExtension->hcd.OpRegisters = (ULONG)((ULONG)ResourceBase + FdoDeviceExtension->hcd.ECHICaps.Length); break; } case CmResourceTypeDma: @@ -573,7 +367,90 @@ StartDevice(PDEVICE_OBJECT DeviceObject, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PART } } - StartEhci(DeviceObject); + KeInitializeDpc(&FdoDeviceExtension->DpcObject, + EhciDefferedRoutine, + FdoDeviceExtension); + + RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION)); + DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; + DeviceDescription.Master = TRUE; + DeviceDescription.ScatterGather = TRUE; + DeviceDescription.Dma32BitAddresses = TRUE; + DeviceDescription.DmaWidth = 2; + DeviceDescription.InterfaceType = PCIBus; + DeviceDescription.MaximumLength = EHCI_MAX_SIZE_TRANSFER; + + FdoDeviceExtension->pDmaAdapter = IoGetDmaAdapter(FdoDeviceExtension->LowerDevice, + &DeviceDescription, + &FdoDeviceExtension->MapRegisters); + + if (FdoDeviceExtension->pDmaAdapter == NULL) + { + DPRINT1("Ehci: IoGetDmaAdapter failed!\n"); + ASSERT(FALSE); + } + + /* Allocate Common Buffer for Periodic Frame List */ + FdoDeviceExtension->PeriodicFrameList.VirtualAddr = + FdoDeviceExtension->pDmaAdapter->DmaOperations->AllocateCommonBuffer(FdoDeviceExtension->pDmaAdapter, + sizeof(ULONG) * 1024, &FdoDeviceExtension->PeriodicFrameList.PhysicalAddr, FALSE); + + if (FdoDeviceExtension->PeriodicFrameList.VirtualAddr == NULL) + { + DPRINT1("Ehci: FdoDeviceExtension->PeriodicFramList is null\n"); + return STATUS_UNSUCCESSFUL; + } + + /* Zeroize it */ + RtlZeroMemory(FdoDeviceExtension->PeriodicFrameList.VirtualAddr, sizeof(ULONG) * 1024); + + ExInitializeFastMutex(&FdoDeviceExtension->FrameListMutex); + + /* Allocate pages for queueheads and descriptors */ + FdoDeviceExtension->hcd.CommonBufferVA = + FdoDeviceExtension->pDmaAdapter->DmaOperations->AllocateCommonBuffer(FdoDeviceExtension->pDmaAdapter, + PAGE_SIZE * 16, + &FdoDeviceExtension->hcd.CommonBufferPA, + FALSE); + + if (FdoDeviceExtension->hcd.CommonBufferVA == 0) + { + DPRINT1("Ehci: Failed to allocate common buffer!\n"); + return STATUS_UNSUCCESSFUL; + } + + FdoDeviceExtension->hcd.CommonBufferSize = PAGE_SIZE * 16; + + /* Zeroize it */ + RtlZeroMemory(FdoDeviceExtension->hcd.CommonBufferVA, + PAGE_SIZE * 16); + + /* Init SpinLock for host controller device lock */ + KeInitializeSpinLock(&FdoDeviceExtension->hcd.Lock); + + /* Reserved a Queue Head that will always be in the AsyncList Address Register */ + FdoDeviceExtension->hcd.AsyncListQueue = CreateQueueHead(&FdoDeviceExtension->hcd); + FdoDeviceExtension->hcd.AsyncListQueue->HorizontalLinkPointer = FdoDeviceExtension->hcd.AsyncListQueue->PhysicalAddr | QH_TYPE_QH; + FdoDeviceExtension->hcd.AsyncListQueue->EndPointCharacteristics.QEDTDataToggleControl = FALSE; + FdoDeviceExtension->hcd.AsyncListQueue->Token.Bits.InterruptOnComplete = FALSE; + + /* Ensure the controller is stopped */ + StopEhci(&FdoDeviceExtension->hcd); + + Status = IoConnectInterrupt(&FdoDeviceExtension->EhciInterrupt, + InterruptService, + FdoDeviceExtension->DeviceObject, + NULL, + FdoDeviceExtension->Vector, + FdoDeviceExtension->Irql, + FdoDeviceExtension->Irql, + FdoDeviceExtension->Mode, + FdoDeviceExtension->IrqShared, + FdoDeviceExtension->Affinity, + FALSE); + + StartEhci(&FdoDeviceExtension->hcd); + DPRINT1("AsycnAddr %x\n", GetAsyncListQueueRegister(&FdoDeviceExtension->hcd)); FdoDeviceExtension->DeviceState = DEVICESTARTED; return STATUS_SUCCESS; @@ -628,7 +505,7 @@ FdoQueryBusRelations( /* Bail on any other error */ if (!NT_SUCCESS(Status)) { - DPRINT1("UsbEhci: Failed to create PDO %wZ, Status %x\n", &DeviceName, Status); + DPRINT1("Ehci: Failed to create PDO %wZ, Status %x\n", &DeviceName, Status); return Status; } } @@ -639,7 +516,7 @@ FdoQueryBusRelations( PdoDeviceExtension->ControllerFdo = DeviceObject; PdoDeviceExtension->DeviceObject = Pdo; - PdoDeviceExtension->NumberOfPorts = DeviceExtension->ECHICaps.HCSParams.PortCount; + PdoDeviceExtension->NumberOfPorts = DeviceExtension->hcd.ECHICaps.HCSParams.PortCount; InitializeListHead(&PdoDeviceExtension->IrpQueue); KeInitializeSpinLock(&PdoDeviceExtension->IrpQueueLock); @@ -683,6 +560,7 @@ FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) case IRP_MN_START_DEVICE: { DPRINT1("Ehci: START_DEVICE\n"); + Irp->IoStatus.Status = STATUS_SUCCESS; Status = ForwardAndWait(DeviceObject, Irp); @@ -905,7 +783,7 @@ FdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) PUSB_DEVICE UsbDevice = NULL; URB *Urb; - /*FIXME: This should never be called by a miniport as the miniport should only be dealing with the pdo */ + /*FIXME: This should never be called by upper drivers as they should only be dealing with the pdo */ FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension; PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension; @@ -924,7 +802,7 @@ FdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) if (!UsbDevice) { - DPRINT1("Invalid DeviceHandle or device not connected\n"); + DPRINT1("Ehci: Invalid DeviceHandle or device not connected\n"); return STATUS_DEVICE_NOT_CONNECTED; } switch (Urb->UrbHeader.Function) @@ -946,7 +824,6 @@ FdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) { case USB_DEVICE_DESCRIPTOR_TYPE: { - /* FIXME: This probably not used for FDO and should be removed? */ DPRINT1("USB DEVICE DESC\n"); break; } @@ -954,55 +831,13 @@ FdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) DPRINT1("USB CONFIG DESC\n"); //break; case USB_STRING_DESCRIPTOR_TYPE: - DPRINT1("Usb String Descriptor\n"); { - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - PUSB_STRING_DESCRIPTOR UsbString; - BOOLEAN ResultOk; - - CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; - CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; - CtrlSetup.bmRequestType._BM.Reserved = 0; - CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST; - CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; - CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index; - CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType; - - if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_STRING_DESCRIPTOR_TYPE) - { - CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId; - RtlZeroMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength-1); - } - else - CtrlSetup.wIndex.W = 0; - - CtrlSetup.wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; - - ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, - Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength); - - if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_STRING_DESCRIPTOR_TYPE) - { - UsbString = Urb->UrbControlDescriptorRequest.TransferBuffer; - DPRINT1("Index %x\n", Urb->UrbControlDescriptorRequest.Index); - DPRINT1("BufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); - DPRINT1("Length %x\n", UsbString->bLength); - if (Urb->UrbControlDescriptorRequest.Index == 0) - { - DPRINT1("%x\n", (ULONG)Urb->UrbControlDescriptorRequest.TransferBuffer); - } - else - DPRINT1("String %S\n", &UsbString->bString); - } - UsbString = Urb->UrbControlDescriptorRequest.TransferBuffer; - Urb->UrbHeader.Status = USBD_STATUS_SUCCESS; - Status = STATUS_SUCCESS; - Information = UsbString->bLength; + DPRINT1("Usb String Descriptor\n"); break; } default: { - DPRINT1("Descriptor Type %x not supported!\n", Urb->UrbControlDescriptorRequest.DescriptorType); + DPRINT1("Ehci: Descriptor Type %x not supported!\n", Urb->UrbControlDescriptorRequest.DescriptorType); } } break; diff --git a/reactos/drivers/usb/usbehci/irp.c b/reactos/drivers/usb/usbehci/irp.c index 8bd51eaaeef..ead34f69e07 100644 --- a/reactos/drivers/usb/usbehci/irp.c +++ b/reactos/drivers/usb/usbehci/irp.c @@ -8,6 +8,19 @@ */ #include "usbehci.h" +#include "hwiface.h" +#include "physmem.h" +#include "transfer.h" + +VOID NTAPI +WorkerThread(IN PVOID Context) +{ + PWORKITEMDATA WorkItemData = (PWORKITEMDATA)Context; + + CompletePendingURBRequest((PPDO_DEVICE_EXTENSION)WorkItemData->Context); + + ExFreePool(WorkItemData); +} VOID RemoveUrbRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp) @@ -23,7 +36,8 @@ RequestURBCancel (PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) { KIRQL OldIrql = Irp->CancelIrql; IoReleaseCancelSpinLock(DISPATCH_LEVEL); - + DPRINT1("IRP CANCELLED\n"); + ASSERT(FALSE); KeAcquireSpinLockAtDpcLevel(&PdoDeviceExtension->IrpQueueLock); RemoveEntryList(&Irp->Tail.Overlay.ListEntry); @@ -40,7 +54,7 @@ QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp) KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &OldIrql); - if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL)) + if ((Irp->Cancel) && (IoSetCancelRoutine(Irp, RequestURBCancel))) { KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql); Irp->IoStatus.Status = STATUS_CANCELLED; @@ -67,7 +81,6 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) ASSERT(Stack); Urb = (PURB) Stack->Parameters.Others.Argument1; - ASSERT(Urb); Information = 0; @@ -92,9 +105,12 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) { case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: { + DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER UsbDevice %x\n", UsbDevice); 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; + ASSERT(FALSE); break; } @@ -128,6 +144,7 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) } case URB_FUNCTION_GET_STATUS_FROM_DEVICE: { + DPRINT1("URB_FUNCTION_GET_STATUS_FROM_DEVICE\n"); if (Urb->UrbControlGetStatusRequest.Index == 0) { ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL); @@ -143,25 +160,55 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) } case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: { + USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; + + DPRINT1("URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n"); switch(Urb->UrbControlDescriptorRequest.DescriptorType) { case USB_DEVICE_DESCRIPTOR_TYPE: { + PUCHAR BufPtr; + DPRINT1("Device Descr Type\n"); + if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR)) { Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR); } + 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)); + DumpDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer); + break; + } + ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer != NULL); - RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, - &UsbDevice->DeviceDescriptor, - Urb->UrbControlDescriptorRequest.TransferBufferLength); + + DPRINT("Calling BuildSetUpPacketFromUrb\n"); + BuildSetupPacketFromURB(&FdoDeviceExtension->hcd, Urb, &CtrlSetup); + DPRINT("SubmitControlTransfer\n"); + SubmitControlTransfer(&FdoDeviceExtension->hcd, + &CtrlSetup, + Urb->UrbControlDescriptorRequest.TransferBuffer, + Urb->UrbControlDescriptorRequest.TransferBufferLength, + Irp); + break; } case USB_CONFIGURATION_DESCRIPTOR_TYPE: { PUCHAR BufPtr; LONG i, j; - + DPRINT1("Config Descr Type\n"); + if (UsbDevice == PdoDeviceExtension->UsbDevices[0]) + { + DPRINT1("ROOTHUB!\n"); + } if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength) { Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength; @@ -171,7 +218,7 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) DPRINT1("TransferBufferLenth %x is too small!!!\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); if (Urb->UrbControlDescriptorRequest.TransferBufferLength < sizeof(USB_CONFIGURATION_DESCRIPTOR)) { - DPRINT("Configuration Descriptor cannot fit into given buffer!\n"); + DPRINT1("Configuration Descriptor cannot fit into given buffer!\n"); break; } } @@ -179,6 +226,8 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); BufPtr = (PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer; + DPRINT1("Length %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); + /* Copy the Configuration Descriptor */ RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)); @@ -193,31 +242,30 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) for (i = 0; i < UsbDevice->ActiveConfig->ConfigurationDescriptor.bNumInterfaces; i++) { /* Copy the Interface Descriptor */ - RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR)); + RtlCopyMemory(BufPtr, + &UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor, + sizeof(USB_INTERFACE_DESCRIPTOR)); BufPtr += sizeof(USB_INTERFACE_DESCRIPTOR); for (j = 0; j < UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor.bNumEndpoints; j++) { /* Copy the EndPoint Descriptor */ - RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->EndPoints[j]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR)); + RtlCopyMemory(BufPtr, + &UsbDevice->ActiveConfig->Interfaces[i]->EndPoints[j]->EndPointDescriptor, + sizeof(USB_ENDPOINT_DESCRIPTOR)); BufPtr += sizeof(USB_ENDPOINT_DESCRIPTOR); } } - + DumpFullConfigurationDescriptor((PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer); break; } case USB_STRING_DESCRIPTOR_TYPE: { - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - PUSB_STRING_DESCRIPTOR StringDesc; - BOOLEAN ResultOk; - - StringDesc = (PUSB_STRING_DESCRIPTOR) Urb->UrbControlDescriptorRequest.TransferBuffer; + DPRINT1("StringDescriptorType\n"); + DPRINT1("Urb->UrbControlDescriptorRequest.Index %x\n", Urb->UrbControlDescriptorRequest.Index); + DPRINT1("Urb->UrbControlDescriptorRequest.LanguageId %x\n", Urb->UrbControlDescriptorRequest.LanguageId); if (Urb->UrbControlDescriptorRequest.Index == 0) - DPRINT("Requesting LANGID's\n"); - - - RtlZeroMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength-1); + DPRINT1("Requesting LANGID's\n"); CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; @@ -229,8 +277,14 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId; CtrlSetup.wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; - ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, - Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength); + SubmitControlTransfer(&FdoDeviceExtension->hcd, + &CtrlSetup, + Urb->UrbControlDescriptorRequest.TransferBuffer, + Urb->UrbControlDescriptorRequest.TransferBufferLength, + Irp); + + IoMarkIrpPending(Irp); + Status = STATUS_PENDING; break; } default: @@ -245,8 +299,8 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) PUSBD_INTERFACE_INFORMATION InterfaceInfo; LONG iCount, pCount; - DPRINT("Selecting Configuration\n"); - DPRINT("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle); + DPRINT1("Selecting Configuration\n"); + DPRINT1("ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle); if (Urb->UrbSelectConfiguration.ConfigurationDescriptor) { @@ -254,6 +308,9 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle); InterfaceInfo = &Urb->UrbSelectConfiguration.Interface; + DPRINT1("Length %x\n", InterfaceInfo->Length); + DPRINT1("NumberOfPipes %x\n", InterfaceInfo->NumberOfPipes); + for (iCount = 0; iCount < Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; iCount++) { InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->ActiveInterface->InterfaceDescriptor; @@ -274,6 +331,7 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) /* InterfaceInfo->Pipes[j].PipeFlags = 0; */ } InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length); + if (InterfaceInfo->Length == 0) break; } } else @@ -284,6 +342,7 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) } case URB_FUNCTION_CLASS_DEVICE: { + DPRINT1("URB_FUNCTION_CLASS_DEVICE\n"); switch (Urb->UrbControlVendorClassRequest.Request) { case USB_REQUEST_GET_DESCRIPTOR: @@ -353,7 +412,7 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) DPRINT1("USB_DEVICE_CLASS_HUB request\n"); UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR); UsbHubDescr->bDescriptorType = 0x29; - UsbHubDescr->bNumberOfPorts = 0x08; + UsbHubDescr->bNumberOfPorts = PdoDeviceExtension->NumberOfPorts; UsbHubDescr->wHubCharacteristics = 0x0012; UsbHubDescr->bPowerOnToPowerGood = 0x01; UsbHubDescr->bHubControlCurrent = 0x00; @@ -383,6 +442,7 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) { DPRINT1("Unhandled URB request for class device\n"); Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION; + ASSERT(FALSE); } } break; @@ -390,13 +450,13 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) case URB_FUNCTION_CLASS_OTHER: { DPRINT("URB_FUNCTION_CLASS_OTHER\n"); - /* FIXME: Each one of these needs to make sure that the index value is a valid for the number of ports and return STATUS_UNSUCCESSFUL is not */ + /* FIXME: Each one of these needs to make sure that the index value is a valid for the number of ports and return STATUS_UNSUCCESSFUL if not */ switch (Urb->UrbControlVendorClassRequest.Request) { case USB_REQUEST_GET_STATUS: { - DPRINT("USB_REQUEST_GET_STATUS Port %d\n", Urb->UrbControlVendorClassRequest.Index); + DPRINT1("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); @@ -407,20 +467,23 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) } case USB_REQUEST_CLEAR_FEATURE: { - DPRINT("USB_REQUEST_CLEAR_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index, + DPRINT1("USB_REQUEST_CLEAR_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index, Urb->UrbControlVendorClassRequest.Value); switch (Urb->UrbControlVendorClassRequest.Value) { case C_PORT_CONNECTION: + DPRINT1("C_PORT_CONNECTION\n"); PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_CONNECT; break; case C_PORT_RESET: + DPRINT1("C_PORT_RESET\n"); PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_RESET; break; default: DPRINT1("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value); break; } + CompletePendingURBRequest(PdoDeviceExtension); break; } case USB_REQUEST_SET_FEATURE: @@ -432,32 +495,43 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) { case PORT_RESET: { - PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |= USB_PORT_STATUS_ENABLE; - ResetPort(FdoDeviceExtension, Urb->UrbControlVendorClassRequest.Index-1); + //PWORKITEMDATA WorkItemData; + PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |= USB_PORT_STATUS_ENABLE; + PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange |= USB_PORT_STATUS_RESET; + + ResetPort(&FdoDeviceExtension->hcd, Urb->UrbControlVendorClassRequest.Index-1); + //WorkItemData = ExAllocatePool(NonPagedPool, sizeof(WORKITEMDATA)); + //WorkItemData->Context = PdoDeviceExtension; + //ExInitializeWorkItem(&WorkItemData->WorkItem, (PWORKER_THREAD_ROUTINE)WorkerThread, (PVOID) WorkItemData) + //ExQueueWorkItem(&WorkItemData->WorkItem, DelayedWorkQueue); + //IoMarkIrpPending(Irp); + //Status = STATUS_PENDING; break; } case PORT_ENABLE: { - DPRINT1("PORT_ENABLE not implemented\n"); + DPRINT("PORT_ENABLE not implemented\n"); break; } case PORT_POWER: { - DPRINT1("PORT_POWER not implemented\n"); + DPRINT("PORT_POWER not implemented\n"); break; } default: { - DPRINT1("Unknown Set Feature!\n"); + DPRINT("Unknown Set Feature!\n"); break; } } + CompletePendingURBRequest(PdoDeviceExtension); break; } case USB_REQUEST_SET_ADDRESS: { DPRINT1("USB_REQUEST_SET_ADDRESS\n"); + ASSERT(FALSE); break; } case USB_REQUEST_GET_DESCRIPTOR: @@ -508,7 +582,6 @@ NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp) DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function); Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION; } - } Irp->IoStatus.Status = Status; @@ -539,8 +612,11 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry); if (!Irp) + { + DPRINT1("No IRP\n"); break; - + } + IoSetCancelRoutine(Irp, NULL); KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql); HandleUrbRequest(DeviceExtension, Irp); IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/reactos/drivers/usb/usbehci/pdo.c b/reactos/drivers/usb/usbehci/pdo.c index f8e83f4fbcd..0254fcc8204 100644 --- a/reactos/drivers/usb/usbehci/pdo.c +++ b/reactos/drivers/usb/usbehci/pdo.c @@ -55,7 +55,7 @@ const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR [] = 0x00 /* MaxPower; */ }; -const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] = +const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] = { /* one interface */ 0x09, /* bLength: Interface; */ @@ -80,31 +80,6 @@ const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR [] = 0xFF /* bInterval; (255ms -- usb 2.0 spec) */ }; -/* FIXME: Do something better */ -VOID NTAPI -UrbWorkerThread(PVOID Context) -{ - PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Context; - NTSTATUS Status; - LARGE_INTEGER DueTime; - PVOID PollEvents[] = { (PVOID) &PdoDeviceExtension->QueueDrainedEvent, (PVOID) &PdoDeviceExtension->Timer }; - - DueTime.QuadPart = 0; - KeInitializeTimerEx(&PdoDeviceExtension->Timer, SynchronizationTimer); - KeSetTimerEx(&PdoDeviceExtension->Timer, DueTime, 100, NULL); - - while (TRUE) - { - Status = KeWaitForMultipleObjects(2, PollEvents, WaitAll, Executive, KernelMode, FALSE, NULL, NULL); - - if (!PdoDeviceExtension->HaltQueue) - KeResetEvent(&PdoDeviceExtension->QueueDrainedEvent); - CompletePendingURBRequest(PdoDeviceExtension); - } - - DPRINT1("Thread terminated\n"); -} - NTSTATUS NTAPI PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) { @@ -139,7 +114,8 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) if ((Urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER) && (UsbDevice == PdoDeviceExtension->UsbDevices[0])) { - if (Urb->UrbBulkOrInterruptTransfer.PipeHandle == &UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor) + DPRINT1("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"); } @@ -172,6 +148,10 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) Status = STATUS_PENDING; break; } + else + { + DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB send to device %x\n", UsbDevice); + } Status = HandleUrbRequest(PdoDeviceExtension, Irp); @@ -419,10 +399,10 @@ PdoDispatchPnp( for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++) { - PdoDeviceExtension->Ports[i].PortStatus = USB_PORT_STATUS_HIGH_SPEED | 0x8000; + PdoDeviceExtension->Ports[i].PortStatus = 0x8000; PdoDeviceExtension->Ports[i].PortChange = 0; - if (!FdoDeviceExtension->ECHICaps.HCSParams.PortPowerControl) + if (!FdoDeviceExtension->hcd.ECHICaps.HCSParams.PortPowerControl) PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_POWER; } @@ -470,19 +450,6 @@ PdoDispatchPnp( PdoDeviceExtension->UsbDevices[0] = RootHubDevice; - /* Create a thread to handle the URB's */ -/* - Status = PsCreateSystemThread(&PdoDeviceExtension->ThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - NULL, - UrbWorkerThread, - (PVOID)PdoDeviceExtension); - - if (!NT_SUCCESS(Status)) - DPRINT1("Failed Thread Creation with Status: %x\n", Status); -*/ Status = IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_HUB, NULL, &InterfaceSymLinkName); if (!NT_SUCCESS(Status)) { diff --git a/reactos/drivers/usb/usbehci/urbreq.c b/reactos/drivers/usb/usbehci/urbreq.c deleted file mode 100644 index 8fdaf8149fb..00000000000 --- a/reactos/drivers/usb/usbehci/urbreq.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/usb/usbehci/urbreq.c - * PURPOSE: URB Related Functions. - * PROGRAMMERS: - * Michael Martin (michael.martin@reactos.org) - */ - -#include "usbehci.h" - -/* QueueHead must point to the base address in common buffer */ -PVOID -IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead, - PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD1, - PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD2, - PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD3, - PUSB_DEFAULT_PIPE_SETUP_PACKET *CtrlSetup, - PVOID *CtrlData, - ULONG Size) -{ - QueueHead->HorizontalLinkPointer = (ULONG)QueueHead | QH_TYPE_QH; - - /* Set NakCountReload to max value possible */ - QueueHead->EndPointCapabilities1.NakCountReload = 0xF; - - /* 1 for non high speed, 0 for high speed device */ - QueueHead->EndPointCapabilities1.ControlEndPointFlag = 0; - - QueueHead->EndPointCapabilities1.HeadOfReclamation = TRUE; - QueueHead->EndPointCapabilities1.MaximumPacketLength = 64; - - /* Get the Initial Data Toggle from the QEDT */ - QueueHead->EndPointCapabilities1.QEDTDataToggleControl = TRUE; - - /* HIGH SPEED DEVICE */ - QueueHead->EndPointCapabilities1.EndPointSpeed = QH_ENDPOINT_HIGHSPEED; - QueueHead->EndPointCapabilities1.EndPointNumber = 0; - - /* Only used for Periodic Schedule and Not High Speed devices. - Setting it to one result in undefined behavior for Async */ - QueueHead->EndPointCapabilities1.InactiveOnNextTransaction = 0; - - QueueHead->EndPointCapabilities1.DeviceAddress = 0; - QueueHead->EndPointCapabilities2.HubAddr = 0; - QueueHead->EndPointCapabilities2.NumberOfTransactionPerFrame = 0x01; - - /* 0 For Async, 1 for periodoc schedule */ - QueueHead->EndPointCapabilities2.InterruptScheduleMask = 0; - - QueueHead->EndPointCapabilities2.PortNumber = 0; - QueueHead->EndPointCapabilities2.SplitCompletionMask = 0; - QueueHead->CurrentLinkPointer = 0; - QueueHead->QETDPointer = TERMINATE_POINTER; - QueueHead->AlternateNextPointer = TERMINATE_POINTER; - QueueHead->Token.Bits.InterruptOnComplete = TRUE; - QueueHead->BufferPointer[0] = 0; - QueueHead->BufferPointer[1] = 0; - QueueHead->BufferPointer[2] = 0; - QueueHead->BufferPointer[3] = 0; - QueueHead->BufferPointer[4] = 0; - /* Queue Head Initialized */ - - /* Queue Transfer Descriptors must be 32 byte aligned and reside in continous physical memory */ - *CtrlTD1 = (PQUEUE_TRANSFER_DESCRIPTOR) (((ULONG)(QueueHead) + sizeof(QUEUE_HEAD) + 0x1F) & ~0x1F); - *CtrlTD2 = (PQUEUE_TRANSFER_DESCRIPTOR) (((ULONG)(*CtrlTD1) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0x1F) & ~0x1F); - *CtrlTD3 = (PQUEUE_TRANSFER_DESCRIPTOR) (((ULONG)(*CtrlTD2) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0x1F) & ~0x1F); - - /* Must be Page aligned */ - *CtrlSetup = (PUSB_DEFAULT_PIPE_SETUP_PACKET) (( (ULONG)(*CtrlTD3) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0xFFF) & ~0xFFF); - *CtrlData = (PVOID) (( (ULONG)(*CtrlSetup) + sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) + 0xFFF) & ~0xFFF); - - (*CtrlTD1)->NextPointer = TERMINATE_POINTER; - (*CtrlTD1)->AlternateNextPointer = TERMINATE_POINTER; - (*CtrlTD1)->BufferPointer[0] = (ULONG)MmGetPhysicalAddress((PVOID) (*CtrlSetup)).LowPart; - (*CtrlTD1)->Token.Bits.DataToggle = FALSE; - (*CtrlTD1)->Token.Bits.InterruptOnComplete = FALSE; - (*CtrlTD1)->Token.Bits.TotalBytesToTransfer = sizeof(USB_DEFAULT_PIPE_SETUP_PACKET); - (*CtrlTD1)->Token.Bits.ErrorCounter = 0x03; - (*CtrlTD1)->Token.Bits.PIDCode = PID_CODE_SETUP_TOKEN; - (*CtrlTD1)->Token.Bits.Active = TRUE; - - (*CtrlTD2)->NextPointer = TERMINATE_POINTER; - (*CtrlTD2)->AlternateNextPointer = TERMINATE_POINTER; - if (Size == 0) - (*CtrlTD2)->BufferPointer[0] = 0; - else - (*CtrlTD2)->BufferPointer[0] = (ULONG)MmGetPhysicalAddress((PVOID) (*CtrlData)).LowPart; - (*CtrlTD2)->Token.Bits.DataToggle = TRUE; - (*CtrlTD2)->Token.Bits.InterruptOnComplete = TRUE; - (*CtrlTD2)->Token.Bits.TotalBytesToTransfer = Size; - (*CtrlTD2)->Token.Bits.ErrorCounter = 0x03; - (*CtrlTD2)->Token.Bits.PIDCode = PID_CODE_IN_TOKEN; - (*CtrlTD2)->Token.Bits.Active = TRUE; - - (*CtrlTD1)->NextPointer = (ULONG)MmGetPhysicalAddress((PVOID)(*CtrlTD2)).LowPart; - - (*CtrlTD3)->NextPointer = TERMINATE_POINTER; - (*CtrlTD3)->AlternateNextPointer = TERMINATE_POINTER; - (*CtrlTD3)->BufferPointer[0] = 0; - (*CtrlTD3)->Token.Bits.Active = TRUE; - (*CtrlTD3)->Token.Bits.PIDCode = PID_CODE_OUT_TOKEN; - (*CtrlTD3)->Token.Bits.InterruptOnComplete = TRUE; - (*CtrlTD3)->Token.Bits.TotalBytesToTransfer = 0; - (*CtrlTD3)->Token.Bits.DataToggle = TRUE; - (*CtrlTD3)->Token.Bits.ErrorCounter = 0x03; - (*CtrlTD2)->NextPointer = (ULONG) MmGetPhysicalAddress((PVOID)(*CtrlTD3)).LowPart; - return NULL; -} - -BOOLEAN -ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG BufferLength) -{ - PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup = NULL; - PVOID CtrlData = NULL; - PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL; - PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL; - PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL; - - PQUEUE_HEAD QueueHead; - PEHCI_USBCMD_CONTENT UsbCmd; - PEHCI_USBSTS_CONTEXT UsbSts; - LONG Base; - LONG tmp; - - DPRINT1("ExecuteControlRequest: Buffer %x, Length %x\n", Buffer, BufferLength); - - ExAcquireFastMutex(&DeviceExtension->AsyncListMutex); - - Base = (ULONG) DeviceExtension->ResourceMemory; - - /* Set up the QUEUE HEAD in memory */ - QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr); - - /* Initialize the memory pointers */ - IntializeHeadQueueForStandardRequest(QueueHead, - &CtrlTD1, - &CtrlTD2, - &CtrlTD3, - &CtrlSetup, - (PVOID)&CtrlData, - BufferLength); - - QueueHead->EndPointCapabilities2.PortNumber = Port; - QueueHead->EndPointCapabilities1.DeviceAddress = Address; - - CtrlSetup->bmRequestType._BM.Recipient = SetupPacket->bmRequestType._BM.Recipient; - CtrlSetup->bmRequestType._BM.Type = SetupPacket->bmRequestType._BM.Type; - CtrlSetup->bmRequestType._BM.Dir = SetupPacket->bmRequestType._BM.Dir; - CtrlSetup->bRequest = SetupPacket->bRequest; - CtrlSetup->wValue.LowByte = SetupPacket->wValue.LowByte; - CtrlSetup->wValue.HiByte = SetupPacket->wValue.HiByte; - CtrlSetup->wIndex.W = SetupPacket->wIndex.W; - CtrlSetup->wLength = SetupPacket->wLength; - - tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD)); - UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; - UsbCmd->Run = FALSE; - WRITE_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD), tmp); - - /* Wait for the controller to halt */ - for (;;) - { - KeStallExecutionProcessor(10); - tmp = READ_REGISTER_ULONG((PULONG)(Base + EHCI_USBSTS)); - UsbSts = (PEHCI_USBSTS_CONTEXT)&tmp; - DPRINT("Waiting for Halt, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(Base + EHCI_USBSTS))); - if (UsbSts->HCHalted) - { - break; - } - } - - /* Set to TRUE on interrupt for async completion */ - DeviceExtension->AsyncComplete = FALSE; - QueueHead->QETDPointer = (ULONG) MmGetPhysicalAddress((PVOID)(CtrlTD1)).LowPart; - - tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD)); - UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; - UsbCmd->AsyncEnable = TRUE; - - WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp); - - tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD)); - UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; - - /* Interrupt on Async completion */ - UsbCmd->DoorBell = TRUE; - UsbCmd->Run = TRUE; - WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp); - - for (;;) - { - KeStallExecutionProcessor(100); - DPRINT("Waiting for completion!\n"); - if (DeviceExtension->AsyncComplete == TRUE) - break; - } - - UsbCmd->Run = FALSE; - WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp); - - if (SetupPacket->bmRequestType._BM.Dir == BMREQUEST_DEVICE_TO_HOST) - { - if ((Buffer) && (BufferLength)) - { - RtlCopyMemory(Buffer, CtrlData, BufferLength); - } - else - DPRINT1("Unable to copy data to buffer\n"); - } - - ExReleaseFastMutex(&DeviceExtension->AsyncListMutex); - - return TRUE; -} diff --git a/reactos/drivers/usb/usbehci/usbehci.c b/reactos/drivers/usb/usbehci/usbehci.c index a0cc00858ae..f88cde8b886 100644 --- a/reactos/drivers/usb/usbehci/usbehci.c +++ b/reactos/drivers/usb/usbehci/usbehci.c @@ -88,7 +88,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) DPRINT1("Driver Entry %wZ!\n", RegistryPath); DriverObject->DriverExtension->AddDevice = AddDevice; - DriverObject->MajorFunction[IRP_MJ_CREATE] = UsbEhciCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = UsbEhciClose; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = UsbEhciCleanup; diff --git a/reactos/drivers/usb/usbehci/usbehci.rbuild b/reactos/drivers/usb/usbehci/usbehci.rbuild index c5ace344e51..f30b683d498 100644 --- a/reactos/drivers/usb/usbehci/usbehci.rbuild +++ b/reactos/drivers/usb/usbehci/usbehci.rbuild @@ -4,12 +4,15 @@ ntoskrnl hal usbehci.c + hardware.c + physmem.c + hwiface.c + transfer.c fdo.c pdo.c common.c misc.c irp.c usbiffn.c - urbreq.c usbehci.rc diff --git a/reactos/drivers/usb/usbehci/usbiffn.c b/reactos/drivers/usb/usbehci/usbiffn.c index 4e9f4063f5a..9d2efddd31f 100644 --- a/reactos/drivers/usb/usbehci/usbiffn.c +++ b/reactos/drivers/usb/usbehci/usbiffn.c @@ -10,6 +10,7 @@ #include "usbehci.h" #include #include +#include "transfer.h" PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub) { @@ -30,8 +31,8 @@ PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent DPRINT1("This is the root hub\n"); } - UsbDevicePointer->Address = 0;// DeviceNumber; - UsbDevicePointer->Port = Port; + UsbDevicePointer->Address = 0;//DeviceNumber; + UsbDevicePointer->Port = Port - 1; UsbDevicePointer->ParentDevice = Parent; UsbDevicePointer->IsHub = Hub; @@ -55,6 +56,7 @@ InterfaceDereference(PVOID BusContext) /* Bus Interface Hub V5 Functions */ + NTSTATUS USB_BUSIFFN CreateUsbDevice(PVOID BusContext, @@ -65,6 +67,7 @@ CreateUsbDevice(PVOID BusContext, PPDO_DEVICE_EXTENSION PdoDeviceExtension; PUSB_DEVICE UsbDevice; LONG i = 0; + PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension; DPRINT1("Ehci: CreateUsbDevice: HubDeviceHandle %x, PortStatus %x, PortNumber %x\n", HubDeviceHandle, PortStatus, PortNumber); @@ -97,8 +100,6 @@ CreateUsbDevice(PVOID BusContext, return STATUS_SUCCESS; } -/* Called when SCE reports a change */ -/* FIXME: Do something better for memory */ NTSTATUS USB_BUSIFFN InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle) @@ -110,12 +111,10 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle) PUSB_INTERFACE_DESCRIPTOR InterfaceDesc; PUSB_ENDPOINT_DESCRIPTOR EndpointDesc; PUSB_DEVICE UsbDevice; - BOOLEAN ResultOk; PVOID Buffer; PUCHAR Ptr; LONG i, j, k; - DPRINT1("Ehci: InitializeUsbDevice called, device %x\n", DeviceHandle); PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension; FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension; @@ -127,59 +126,32 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle) return STATUS_DEVICE_NOT_CONNECTED; } - Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, USB_POOL_TAG); - - if (!Buffer) - { - DPRINT1("Out of memory\n"); - return STATUS_NO_MEMORY; - } - - Ptr = Buffer; - - /* Set the device address */ -/* - CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; - CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; - CtrlSetup.bmRequestType._BM.Reserved = 0; - CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_HOST_TO_DEVICE; - CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS; - CtrlSetup.wValue.W = UsbDevice->Address; - CtrlSetup.wIndex.W = 0; - CtrlSetup.wLength = 0; - - DPRINT1("Setting Address to %x\n", UsbDevice->Address); - ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, 0, UsbDevice->Port, NULL, 0); - -*/ - - /* Get the Device Descriptor */ - CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; - CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; - CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST; CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; CtrlSetup.wValue.LowByte = 0; CtrlSetup.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; CtrlSetup.wIndex.W = 0; - CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR); - - DPRINT1("Requesting Descriptor\n"); - ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, - &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); - - - DPRINT1("bLength %x\n", UsbDevice->DeviceDescriptor.bLength); - DPRINT1("bDescriptorType %x\n", UsbDevice->DeviceDescriptor.bDescriptorType); - DPRINT1("idVendor %x\n", UsbDevice->DeviceDescriptor.idVendor); - DPRINT1("idProduct %x\n", UsbDevice->DeviceDescriptor.idProduct); - DPRINT1("bNumDescriptors %x\n", UsbDevice->DeviceDescriptor.bNumConfigurations); - - if (UsbDevice->DeviceDescriptor.bNumConfigurations == 0) + CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR); + CtrlSetup.bmRequestType.B = 0x80; + + SubmitControlTransfer(&FdoDeviceExtension->hcd, + &CtrlSetup, + &UsbDevice->DeviceDescriptor, + sizeof(USB_DEVICE_DESCRIPTOR), + NULL); + + //DumpDeviceDescriptor(&UsbDevice->DeviceDescriptor); + + if (UsbDevice->DeviceDescriptor.bLength != 0x12) { - DPRINT1("No Configurations. That cant be good!\n"); + DPRINT1("Failed to get Device Descriptor from device connected on port %d\n", UsbDevice->Port); + return STATUS_DEVICE_DATA_ERROR; + } + + if (UsbDevice->DeviceDescriptor.bNumConfigurations == 0) + { + DPRINT1("Device on port %d has no configurations!\n", UsbDevice->Port); return STATUS_DEVICE_DATA_ERROR; } - UsbDevice->Configs = ExAllocatePoolWithTag(NonPagedPool, sizeof(PVOID) * UsbDevice->DeviceDescriptor.bNumConfigurations, USB_POOL_TAG); @@ -190,22 +162,38 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle) return STATUS_NO_MEMORY; } + Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, USB_POOL_TAG); + + if (!Buffer) + { + DPRINT1("Out of memory\n"); + return STATUS_NO_MEMORY; + } + + Ptr = Buffer; + for (i = 0; i < UsbDevice->DeviceDescriptor.bNumConfigurations; i++) { /* Get the Device Configuration Descriptor */ CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; + CtrlSetup.bmRequestType._BM.Reserved = 0; CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST; CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; CtrlSetup.wValue.LowByte = 0; CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; CtrlSetup.wIndex.W = 0; CtrlSetup.wLength = PAGE_SIZE; - - ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, Buffer, PAGE_SIZE); + + SubmitControlTransfer(&FdoDeviceExtension->hcd, + &CtrlSetup, + Buffer, + PAGE_SIZE, + NULL); ConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)Ptr; + //DumpFullConfigurationDescriptor(ConfigDesc); ASSERT(ConfigDesc->wTotalLength <= PAGE_SIZE); UsbDevice->Configs[i] = ExAllocatePoolWithTag(NonPagedPool, @@ -244,6 +232,26 @@ InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle) UsbDevice->ActiveInterface = UsbDevice->Configs[0]->Interfaces[0]; return STATUS_SUCCESS; + + /* Set the device address */ + CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; + CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; + CtrlSetup.bmRequestType._BM.Reserved = 0; + CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_HOST_TO_DEVICE; + CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS; + CtrlSetup.wValue.W = UsbDevice->Address; + CtrlSetup.wIndex.W = 0; + CtrlSetup.wLength = 0; + + DPRINT1("Setting Address to %x\n", UsbDevice->Address); + + SubmitControlTransfer(&FdoDeviceExtension->hcd, + &CtrlSetup, + NULL, + 0, + NULL); + + return STATUS_SUCCESS; } NTSTATUS @@ -256,7 +264,8 @@ GetUsbDescriptors(PVOID BusContext, PULONG ConfigDescriptorBufferLength) { PUSB_DEVICE UsbDevice; - DPRINT1("Ehci: GetUsbDescriptor %x, %x, %x, %x\n", DeviceDescriptorBuffer, *DeviceDescriptorBufferLength, ConfigDescriptorBuffer, *ConfigDescriptorBufferLength); + DPRINT1("Ehci: GetUsbDescriptor %x, %x, %x, %x\n", DeviceDescriptorBuffer, *DeviceDescriptorBufferLength, + ConfigDescriptorBuffer, *ConfigDescriptorBufferLength); UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle); @@ -345,7 +354,7 @@ NTSTATUS USB_BUSIFFN RestoreUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE OldDeviceHandle, PUSB_DEVICE_HANDLE NewDeviceHandle) { - DPRINT1("Ehci: RestoreUsbDevice called\n"); + DPRINT1("Ehci: RestoreUsbDevice not implemented! %x, %x, %x\n", BusContext, OldDeviceHandle, NewDeviceHandle); return STATUS_NOT_SUPPORTED; } @@ -353,7 +362,7 @@ NTSTATUS USB_BUSIFFN GetPortHackFlags(PVOID BusContext, PULONG Flags) { - DPRINT1("Ehci: GetPortHackFlags called\n"); + DPRINT1("Ehci: GetPortHackFlags not implemented. %x, %x\n", BusContext, Flags); return STATUS_NOT_SUPPORTED; } @@ -370,7 +379,8 @@ QueryDeviceInformation(PVOID BusContext, ULONG SizeNeeded; LONG i; - DPRINT1("Ehci: QueryDeviceInformation (%x, %x, %x, %d, %x\n", BusContext, DeviceHandle, DeviceInformationBuffer, DeviceInformationBufferLength, LengthReturned); + DPRINT1("Ehci: QueryDeviceInformation (%x, %x, %x, %d, %x\n", BusContext, DeviceHandle, DeviceInformationBuffer, + DeviceInformationBufferLength, LengthReturned); UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle); @@ -409,7 +419,9 @@ QueryDeviceInformation(PVOID BusContext, for (i = 0; i < UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints; i++) { - RtlCopyMemory(&DeviceInfo->PipeList[i].EndpointDescriptor, &UsbDevice->ActiveInterface->EndPoints[i]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR)); + RtlCopyMemory(&DeviceInfo->PipeList[i].EndpointDescriptor, + &UsbDevice->ActiveInterface->EndPoints[i]->EndPointDescriptor, + sizeof(USB_ENDPOINT_DESCRIPTOR)); } return STATUS_SUCCESS; } @@ -452,7 +464,7 @@ NTSTATUS USB_BUSIFFN ControllerSelectiveSuspend(PVOID BusContext, BOOLEAN Enable) { - DPRINT1("Ehci: ControllerSelectiveSuspend called\n"); + DPRINT1("Ehci: ControllerSelectiveSuspend not implemented\n"); return STATUS_NOT_SUPPORTED; } @@ -469,11 +481,13 @@ GetExtendedHubInformation(PVOID BusContext, PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension; PFDO_DEVICE_EXTENSION FdoDeviceExntension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension; LONG i; - DPRINT1("Ehci: GetExtendedHubInformation BusContext %x, PDO %x\n", BusContext, HubPhysicalDeviceObject); + DPRINT1("Ehci: GetExtendedHubInformation BusContext %x, PDO %x, InformationBuffer %x\n", + BusContext, HubPhysicalDeviceObject, HubInformationBuffer); + /* Set the default return value */ *LengthReturned = 0; - DPRINT1("InformationLevel %x\n", UsbExtHubInfo->InformationLevel); + DPRINT("InformationLevel %x\n", UsbExtHubInfo->InformationLevel); /* Caller is suppose to have set InformationLevel to 0. However usbehci from MS seems to ignore this */ if (UsbExtHubInfo->InformationLevel != 0) @@ -486,7 +500,7 @@ GetExtendedHubInformation(PVOID BusContext, for (i=0; i < UsbExtHubInfo->NumberOfPorts; i++) { UsbExtHubInfo->Port[i].PhysicalPortNumber = i + 1; - UsbExtHubInfo->Port[i].PortLabelNumber = FdoDeviceExntension->ECHICaps.HCSParams.PortCount; + UsbExtHubInfo->Port[i].PortLabelNumber = FdoDeviceExntension->hcd.ECHICaps.HCSParams.PortCount; UsbExtHubInfo->Port[i].VidOverride = 0; UsbExtHubInfo->Port[i].PidOverride = 0; UsbExtHubInfo->Port[i].PortAttributes = USB_PORTATTR_SHARED_USB2; @@ -536,7 +550,7 @@ NTSTATUS USB_BUSIFFN Initialize20Hub(PVOID BusContext, PUSB_DEVICE_HANDLE HubDeviceHandle, ULONG TtCount) { - DPRINT1("Ehci: Initialize20Hub called, HubDeviceHandle: %x\n", HubDeviceHandle); + DPRINT1("Ehci: Initialize20Hub called, HubDeviceHandle: %x, TtCount %x\n", HubDeviceHandle, TtCount); /* FIXME: */ /* Create the Irp Queue for SCE */ /* Should queue be created for each device or each enpoint??? */ @@ -586,7 +600,7 @@ VOID USB_BUSIFFN SetDeviceHandleData(PVOID BusContext, PVOID DeviceHandle, PDEVICE_OBJECT UsbDevicePdo) { - DPRINT1("Ehci: SetDeviceHandleData called\n"); + DPRINT1("Ehci: SetDeviceHandleData not implemented %x, %x, %x\n", BusContext, DeviceHandle, UsbDevicePdo); }