diff --git a/reactos/drivers/usb/usbohci/usbohci.cpp b/reactos/drivers/usb/usbohci/usbohci.cpp index 0d02c029210..9077210ac61 100644 --- a/reactos/drivers/usb/usbohci/usbohci.cpp +++ b/reactos/drivers/usb/usbohci/usbohci.cpp @@ -10,117 +10,6 @@ #include "usbohci.h" -// -// driver verifier -// -DRIVER_ADD_DEVICE OHCI_AddDevice; - -NTSTATUS -NTAPI -OHCI_AddDevice( - PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT PhysicalDeviceObject) -{ - NTSTATUS Status; - PHCDCONTROLLER HcdController; - - DPRINT("OHCI_AddDevice\n"); - - /* first create the controller object */ - Status = CreateHCDController(&HcdController); - if (!NT_SUCCESS(Status)) - { - /* failed to create hcd */ - DPRINT1("AddDevice: Failed to create hcd with %x\n", Status); - return Status; - } - - /* initialize the hcd */ - Status = HcdController->Initialize(NULL, // FIXME - DriverObject, - PhysicalDeviceObject); - - /* check for success */ - if (!NT_SUCCESS(Status)) - { - /* failed to initialize device */ - DPRINT1("AddDevice: failed to initialize\n"); - - /* release object */ - HcdController->Release(); - } - - return Status; - -} - -NTSTATUS -NTAPI -OHCI_Dispatch( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -{ - PCOMMON_DEVICE_EXTENSION DeviceExtension; - PIO_STACK_LOCATION IoStack; - NTSTATUS Status; - - // - // get common device extension - // - DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - // - // get current stack location - // - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // - // sanity checks - // - PC_ASSERT(DeviceExtension->Dispatcher); - - switch(IoStack->MajorFunction) - { - case IRP_MJ_PNP: - { - // - // dispatch pnp - // - return DeviceExtension->Dispatcher->HandlePnp(DeviceObject, Irp); - } - - case IRP_MJ_POWER: - { - // - // dispatch pnp - // - return DeviceExtension->Dispatcher->HandlePower(DeviceObject, Irp); - } - case IRP_MJ_INTERNAL_DEVICE_CONTROL: - case IRP_MJ_DEVICE_CONTROL: - { - // - // dispatch pnp - // - return DeviceExtension->Dispatcher->HandleDeviceControl(DeviceObject, Irp); - } - default: - { - DPRINT1("OHCI_Dispatch> Major %lu Minor %lu unhandeled\n", IoStack->MajorFunction, IoStack->MinorFunction); - Status = STATUS_SUCCESS; - } - } - - // - // complete request - // - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return Status; -} - extern "C" NTSTATUS @@ -131,15 +20,14 @@ DriverEntry( { /* initialize driver object*/ - DriverObject->DriverExtension->AddDevice = OHCI_AddDevice; - - DriverObject->MajorFunction[IRP_MJ_CREATE] = OHCI_Dispatch; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = OHCI_Dispatch; - DriverObject->MajorFunction[IRP_MJ_CLEANUP] = OHCI_Dispatch; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OHCI_Dispatch; - DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = OHCI_Dispatch; - DriverObject->MajorFunction[IRP_MJ_PNP] = OHCI_Dispatch; + DriverObject->DriverExtension->AddDevice = USBLIB_AddDevice; + DriverObject->MajorFunction[IRP_MJ_CREATE] = USBLIB_Dispatch; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBLIB_Dispatch; + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = USBLIB_Dispatch; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBLIB_Dispatch; + DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = USBLIB_Dispatch; + DriverObject->MajorFunction[IRP_MJ_PNP] = USBLIB_Dispatch; return STATUS_SUCCESS; } diff --git a/reactos/drivers/usb/usbuhci/CMakeLists.txt b/reactos/drivers/usb/usbuhci/CMakeLists.txt index 68c04e092f4..5bd4ecaab6c 100644 --- a/reactos/drivers/usb/usbuhci/CMakeLists.txt +++ b/reactos/drivers/usb/usbuhci/CMakeLists.txt @@ -4,20 +4,18 @@ set_cpp() remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) +include_directories( + ${REACTOS_SOURCE_DIR}/lib/drivers/libusb) + add_library(usbuhci SHARED usbuhci.cpp - usb_device.cpp usb_request.cpp usb_queue.cpp - hcd_controller.cpp hardware.cpp - misc.cpp - purecall.cpp - hub_controller.cpp - memory_manager.cpp usbuhci.rc) target_link_libraries(usbuhci + libusb libcntpr ${PSEH_LIB}) diff --git a/reactos/drivers/usb/usbuhci/hardware.cpp b/reactos/drivers/usb/usbuhci/hardware.cpp index de0d5f4674e..d5e3489df1e 100644 --- a/reactos/drivers/usb/usbuhci/hardware.cpp +++ b/reactos/drivers/usb/usbuhci/hardware.cpp @@ -65,32 +65,13 @@ public: return m_Ref; } // com - NTSTATUS Initialize(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT FunctionalDeviceObject, PDEVICE_OBJECT PhysicalDeviceObject, PDEVICE_OBJECT LowerDeviceObject); - NTSTATUS PnpStart(PCM_RESOURCE_LIST RawResources, PCM_RESOURCE_LIST TranslatedResources); - NTSTATUS PnpStop(void); - NTSTATUS HandlePower(PIRP Irp); - NTSTATUS GetDeviceDetails(PUSHORT VendorId, PUSHORT DeviceId, PULONG NumberOfPorts, PULONG Speed); - VOID HeadEndpointDescriptorModified(ULONG HeadType); - - - NTSTATUS GetDMA(OUT struct IDMAMemoryManager **m_DmaManager); - NTSTATUS GetUSBQueue(OUT struct IUSBQueue **OutUsbQueue); + IMP_IUSBHARDWAREDEVICE + IMP_IUHCIHARDWAREDEVICE + // local NTSTATUS StartController(); NTSTATUS StopController(); NTSTATUS ResetController(); - NTSTATUS ResetPort(ULONG PortIndex); - - NTSTATUS GetPortStatus(ULONG PortId, OUT USHORT *PortStatus, OUT USHORT *PortChange); - NTSTATUS ClearPortStatus(ULONG PortId, ULONG Status); - NTSTATUS SetPortFeature(ULONG PortId, ULONG Feature); - VOID SetStatusChangeEndpointCallBack(PVOID CallBack, PVOID Context); - VOID GetQueueHead(ULONG QueueHeadIndex, PUHCI_QUEUE_HEAD *OutQueueHead); - - - KIRQL AcquireDeviceLock(void); - VOID ReleaseDeviceLock(KIRQL OldLevel); - // local VOID GlobalReset(); BOOLEAN InterruptService(); NTSTATUS InitializeController(); @@ -127,7 +108,7 @@ protected: ULONG m_MapRegisters; // map registers count USHORT m_VendorID; // vendor id USHORT m_DeviceID; // device id - PUSBQUEUE m_UsbQueue; // usb request queue + PUHCIQUEUE m_UsbQueue; // usb request queue ULONG m_NumberOfPorts; // number of ports PDMAMEMORYMANAGER m_MemoryManager; // memory manager HD_INIT_CALLBACK* m_SCECallBack; // status change callback routine @@ -191,7 +172,7 @@ CUSBHardwareDevice::Initialize( // // Create the UsbQueue class that will handle the Asynchronous and Periodic Schedules // - Status = CreateUSBQueue(&m_UsbQueue); + Status = CreateUSBQueue((PUSBQUEUE*)&m_UsbQueue); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create UsbQueue!\n"); @@ -412,14 +393,6 @@ CUSBHardwareDevice::PnpStop(void) return STATUS_NOT_IMPLEMENTED; } -NTSTATUS -CUSBHardwareDevice::HandlePower( - PIRP Irp) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS CUSBHardwareDevice::GetDeviceDetails( OUT OPTIONAL PUSHORT VendorId, @@ -1232,29 +1205,6 @@ CUSBHardwareDevice::SetStatusChangeEndpointCallBack( m_SCEContext = Context; } -KIRQL -CUSBHardwareDevice::AcquireDeviceLock(void) -{ - KIRQL OldLevel; - - // - // acquire lock - // - KeAcquireSpinLock(&m_Lock, &OldLevel); - - // - // return old irql - // - return OldLevel; -} - -VOID -CUSBHardwareDevice::ReleaseDeviceLock( - KIRQL OldLevel) -{ - KeReleaseSpinLock(&m_Lock, OldLevel); -} - BOOLEAN NTAPI InterruptServiceRoutine( diff --git a/reactos/drivers/usb/usbuhci/hcd_controller.cpp b/reactos/drivers/usb/usbuhci/hcd_controller.cpp deleted file mode 100644 index fe57f21e8df..00000000000 --- a/reactos/drivers/usb/usbuhci/hcd_controller.cpp +++ /dev/null @@ -1,781 +0,0 @@ -/* - * PROJECT: ReactOS Universal Serial Bus Host Controller Interface - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/usb/usbuhci/hcd_controller.cpp - * PURPOSE: USB UHCI device driver. - * PROGRAMMERS: - * Michael Martin (michael.martin@reactos.org) - * Johannes Anderwald (johannes.anderwald@reactos.org) - */ - -#define INITGUID -#include "usbuhci.h" - -class CHCDController : public IHCDController, - public IDispatchIrp -{ -public: - STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - - // IHCDController interface functions - NTSTATUS Initialize(IN PROOTHDCCONTROLLER RootHCDController, IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject); - - // IDispatchIrp interface functions - NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp); - NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp); - NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp); - - // local functions - NTSTATUS CreateFDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject); - NTSTATUS SetSymbolicLink(BOOLEAN Enable); - - // constructor / destructor - CHCDController(IUnknown *OuterUnknown){} - virtual ~CHCDController(){} - -protected: - LONG m_Ref; - PROOTHDCCONTROLLER m_RootController; - PDRIVER_OBJECT m_DriverObject; - PDEVICE_OBJECT m_PhysicalDeviceObject; - PDEVICE_OBJECT m_FunctionalDeviceObject; - PDEVICE_OBJECT m_NextDeviceObject; - PUSBHARDWAREDEVICE m_Hardware; - PHUBCONTROLLER m_HubController; - ULONG m_FDODeviceNumber; -}; - -//================================================================================================= -// COM -// -NTSTATUS -STDMETHODCALLTYPE -CHCDController::QueryInterface( - IN REFIID refiid, - OUT PVOID* Output) -{ - return STATUS_UNSUCCESSFUL; -} - -//------------------------------------------------------------------------------------------------- -NTSTATUS -CHCDController::Initialize( - IN PROOTHDCCONTROLLER RootHCDController, - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT PhysicalDeviceObject) -{ - NTSTATUS Status; - PCOMMON_DEVICE_EXTENSION DeviceExtension; - - // - // create usb hardware - // - Status = CreateUSBHardware(&m_Hardware); - if (!NT_SUCCESS(Status)) - { - // - // failed to create hardware object - // - DPRINT1("Failed to create hardware object\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // initialize members - // - m_DriverObject = DriverObject; - m_PhysicalDeviceObject = PhysicalDeviceObject; - m_RootController = RootHCDController; - - // - // create FDO - // - Status = CreateFDO(m_DriverObject, &m_FunctionalDeviceObject); - if (!NT_SUCCESS(Status)) - { - // - // failed to create PDO - // - return Status; - } - - // - // now attach to device stack - // - m_NextDeviceObject = IoAttachDeviceToDeviceStack(m_FunctionalDeviceObject, m_PhysicalDeviceObject); - if (!m_NextDeviceObject) - { - // - // failed to attach to device stack - // - IoDeleteDevice(m_FunctionalDeviceObject); - m_FunctionalDeviceObject = 0; - - return STATUS_NO_SUCH_DEVICE; - } - - // - // initialize hardware object - // - Status = m_Hardware->Initialize(m_DriverObject, m_FunctionalDeviceObject, m_PhysicalDeviceObject, m_NextDeviceObject); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to initialize hardware object %x\n", Status); - - // - // failed to initialize hardware object, detach from device stack - // - IoDetachDevice(m_NextDeviceObject); - - // - // now delete the device - // - IoDeleteDevice(m_FunctionalDeviceObject); - - // - // nullify pointers :) - // - m_FunctionalDeviceObject = 0; - m_NextDeviceObject = 0; - - return Status; - } - - - // - // set device flags - // - m_FunctionalDeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE; - - - // - // get device extension - // - DeviceExtension = (PCOMMON_DEVICE_EXTENSION)m_FunctionalDeviceObject->DeviceExtension; - PC_ASSERT(DeviceExtension); - - // - // initialize device extension - // - DeviceExtension->IsFDO = TRUE; - DeviceExtension->IsHub = FALSE; - DeviceExtension->Dispatcher = PDISPATCHIRP(this); - - // - // device is initialized - // - m_FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; - - - // - // is there a root controller - // - if (m_RootController) - { - // - // add reference - // - m_RootController->AddRef(); - - // - // register with controller - // - m_RootController->RegisterHCD(this); - } - - - // - // done - // - return STATUS_SUCCESS; -} - -//------------------------------------------------------------------------------------------------- -NTSTATUS -CHCDController::HandleDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PCOMMON_DEVICE_EXTENSION DeviceExtension; - NTSTATUS Status = STATUS_NOT_IMPLEMENTED; - PUSB_HCD_DRIVERKEY_NAME DriverKey; - ULONG ResultLength; - - // - // get current stack location - // - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // - // get device extension - // - DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - // - // sanity check - // - PC_ASSERT(DeviceExtension->IsFDO); - - DPRINT("HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu\n", - IoStack->Parameters.DeviceIoControl.IoControlCode, - IoStack->Parameters.DeviceIoControl.InputBufferLength, - IoStack->Parameters.DeviceIoControl.OutputBufferLength); - - // - // perform ioctl for FDO - // - if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_HCD_DRIVERKEY_NAME) - { - // - // check if sizee is at least >= USB_HCD_DRIVERKEY_NAME - // - if(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(USB_HCD_DRIVERKEY_NAME)) - { - // - // get device property size - // - Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, 0, NULL, &ResultLength); - - // - // get input buffer - // - DriverKey = (PUSB_HCD_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer; - - // - // check result - // - if (Status == STATUS_BUFFER_TOO_SMALL) - { - // - // does the caller provide enough buffer space - // - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= ResultLength) - { - // - // it does - // - Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG), DriverKey->DriverKeyName, &ResultLength); - - if (NT_SUCCESS(Status)) - { - // - // informal debug print - // - DPRINT1("Result %S\n", DriverKey->DriverKeyName); - } - } - - // - // store result - // - DriverKey->ActualLength = ResultLength + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + sizeof(WCHAR); - Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength; - Status = STATUS_SUCCESS; - } - } - else - { - // - // buffer is certainly too small - // - Status = STATUS_BUFFER_OVERFLOW; - Irp->IoStatus.Information = sizeof(USB_HCD_DRIVERKEY_NAME); - } - } - else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_ROOT_HUB_NAME) - { - // - // check if sizee is at least >= USB_HCD_DRIVERKEY_NAME - // - if(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(USB_HCD_DRIVERKEY_NAME)) - { - // - // sanity check - // - PC_ASSERT(m_HubController); - - // - // get input buffer - // - DriverKey = (PUSB_HCD_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer; - - // - // get symbolic link - // - Status = m_HubController->GetHubControllerSymbolicLink(IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG), DriverKey->DriverKeyName, &ResultLength); - - - if (NT_SUCCESS(Status)) - { - // - // null terminate it - // - PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG) - sizeof(WCHAR) >= ResultLength); - - DriverKey->DriverKeyName[ResultLength / sizeof(WCHAR)] = L'\0'; - DPRINT1("Result %S\n", DriverKey->DriverKeyName); - } - - // - // store result - // - DriverKey->ActualLength = ResultLength + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + sizeof(WCHAR); - Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength; - Status = STATUS_SUCCESS; - } - else - { - // - // buffer is certainly too small - // - Status = STATUS_BUFFER_OVERFLOW; - Irp->IoStatus.Information = sizeof(USB_HCD_DRIVERKEY_NAME); - } - } - - // - // complete the request - // - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - // - // done - // - return Status; -} - -NTSTATUS -CHCDController::HandlePnp( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PCOMMON_DEVICE_EXTENSION DeviceExtension; - PCM_RESOURCE_LIST RawResourceList; - PCM_RESOURCE_LIST TranslatedResourceList; - PDEVICE_RELATIONS DeviceRelations; - NTSTATUS Status; - - // - // get device extension - // - DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - // - // sanity check - // - PC_ASSERT(DeviceExtension->IsFDO); - - // - // get current stack location - // - IoStack = IoGetCurrentIrpStackLocation(Irp); - - switch(IoStack->MinorFunction) - { - case IRP_MN_START_DEVICE: - { - DPRINT("CHCDController::HandlePnp IRP_MN_START FDO\n"); - - // - // first start lower device object - // - Status = SyncForwardIrp(m_NextDeviceObject, Irp); - - if (NT_SUCCESS(Status)) - { - // - // operation succeeded, lets start the device - // - RawResourceList = IoStack->Parameters.StartDevice.AllocatedResources; - TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated; - - if (m_Hardware) - { - // - // start the hardware - // - Status = m_Hardware->PnpStart(RawResourceList, TranslatedResourceList); - } - - // - // enable symbolic link - // - Status = SetSymbolicLink(TRUE); - } - - DPRINT("CHCDController::HandlePnp IRP_MN_START FDO: Status %x\n", Status); - break; - } - case IRP_MN_QUERY_DEVICE_RELATIONS: - { - DPRINT("CHCDController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %lx\n", IoStack->Parameters.QueryDeviceRelations.Type); - - if (m_HubController == NULL) - { - // - // create hub controller - // - Status = CreateHubController(&m_HubController); - if (!NT_SUCCESS(Status)) - { - // - // failed to create hub controller - // - break; - } - - // - // initialize hub controller - // - Status = m_HubController->Initialize(m_DriverObject, PHCDCONTROLLER(this), m_Hardware, TRUE, 0 /* FIXME*/); - if (!NT_SUCCESS(Status)) - { - // - // failed to initialize hub controller - // - break; - } - - // - // add reference to prevent it from getting deleting while hub driver adds / removes references - // - m_HubController->AddRef(); - } - - if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations) - { - // - // allocate device relations - // - DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS)); - - if (!DeviceRelations) - { - // - // no memory - // - Status = STATUS_INSUFFICIENT_RESOURCES; - break; - } - - // - // init device relations - // - DeviceRelations->Count = 1; - Status = m_HubController->GetHubControllerDeviceObject(&DeviceRelations->Objects [0]); - - // - // sanity check - // - PC_ASSERT(Status == STATUS_SUCCESS); - - ObReferenceObject(DeviceRelations->Objects [0]); - - // - // store result - // - Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; - Status = STATUS_SUCCESS; - } - else - { - // - // not supported - // - Status = STATUS_NOT_SUPPORTED; - } - break; - } - case IRP_MN_STOP_DEVICE: - { - DPRINT("CHCDController::HandlePnp IRP_MN_STOP_DEVICE\n"); - - if (m_Hardware) - { - // - // stop the hardware - // - Status = m_Hardware->PnpStop(); - } - else - { - // - // fake success - // - Status = STATUS_SUCCESS; - } - - if (NT_SUCCESS(Status)) - { - // - // stop lower device - // - Status = SyncForwardIrp(m_NextDeviceObject, Irp); - } - break; - } - case IRP_MN_QUERY_REMOVE_DEVICE: - case IRP_MN_QUERY_STOP_DEVICE: - { -#if 0 - // - // sure - // - Irp->IoStatus.Status = STATUS_SUCCESS; - - // - // forward irp to next device object - // - IoSkipCurrentIrpStackLocation(Irp); - return IoCallDriver(m_NextDeviceObject, Irp); -#else - DPRINT1("Denying controller removal due to reinitialization bugs\n"); - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; -#endif - } - case IRP_MN_REMOVE_DEVICE: - { - DPRINT("CHCDController::HandlePnp IRP_MN_REMOVE_DEVICE FDO\n"); - - // - // delete the symbolic link - // - SetSymbolicLink(FALSE); - - // - // forward irp to next device object - // - IoSkipCurrentIrpStackLocation(Irp); - IoCallDriver(m_NextDeviceObject, Irp); - - // - // detach device from device stack - // - IoDetachDevice(m_NextDeviceObject); - - // - // delete device - // - IoDeleteDevice(m_FunctionalDeviceObject); - - return STATUS_SUCCESS; - } - default: - { - // - // forward irp to next device object - // - IoSkipCurrentIrpStackLocation(Irp); - return IoCallDriver(m_NextDeviceObject, Irp); - } - } - - // - // store result and complete request - // - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return Status; -} - -NTSTATUS -CHCDController::HandlePower( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - UNIMPLEMENTED - - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -CHCDController::CreateFDO( - PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT * OutDeviceObject) -{ - WCHAR CharDeviceName[64]; - NTSTATUS Status; - ULONG UsbDeviceNumber = 0; - UNICODE_STRING DeviceName; - - while (TRUE) - { - // - // construct device name - // - swprintf(CharDeviceName, L"\\Device\\USBFDO-%d", UsbDeviceNumber); - - // - // initialize device name - // - RtlInitUnicodeString(&DeviceName, CharDeviceName); - - // - // create device - // - Status = IoCreateDevice(DriverObject, - sizeof(COMMON_DEVICE_EXTENSION), - &DeviceName, - FILE_DEVICE_CONTROLLER, - 0, - FALSE, - OutDeviceObject); - - // - // check for success - // - if (NT_SUCCESS(Status)) - break; - - // - // is there a device object with that same name - // - if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION)) - { - // - // Try the next name - // - UsbDeviceNumber++; - continue; - } - - // - // bail out on other errors - // - if (!NT_SUCCESS(Status)) - { - DPRINT1("CreateFDO: Failed to create %wZ, Status %x\n", &DeviceName, Status); - return Status; - } - } - - // - // store FDO number - // - m_FDODeviceNumber = UsbDeviceNumber; - - DPRINT("CreateFDO: DeviceName %wZ\n", &DeviceName); - - /* done */ - return Status; -} - -NTSTATUS -CHCDController::SetSymbolicLink( - BOOLEAN Enable) -{ - NTSTATUS Status; - WCHAR LinkName[32]; - WCHAR FDOName[32]; - UNICODE_STRING Link, FDO; - - if (Enable) - { - // - // create legacy link - // - swprintf(LinkName, L"\\DosDevices\\HCD%d", m_FDODeviceNumber); - swprintf(FDOName, L"\\Device\\USBFDO-%d", m_FDODeviceNumber); - RtlInitUnicodeString(&Link, LinkName); - RtlInitUnicodeString(&FDO, FDOName); - - // - // create symbolic link - // - Status = IoCreateSymbolicLink(&Link, &FDO); - - if (!NT_SUCCESS(Status)) - { - // - // FIXME: handle me - // - ASSERT(0); - } - } - else - { - // - // create legacy link - // - swprintf(LinkName, L"\\DosDevices\\HCD%d", m_FDODeviceNumber); - RtlInitUnicodeString(&Link, LinkName); - - // - // now delete the symbolic link - // - Status = IoDeleteSymbolicLink(&Link); - - if (!NT_SUCCESS(Status)) - { - // - // FIXME: handle me - // - ASSERT(0); - } - } - - // - // done - // - return Status; -} - -NTSTATUS -CreateHCDController( - PHCDCONTROLLER *OutHcdController) -{ - PHCDCONTROLLER This; - - // - // allocate controller - // - This = new(NonPagedPool, TAG_USBUHCI) CHCDController(0); - if (!This) - { - // - // failed to allocate - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // add reference count - // - This->AddRef(); - - // - // return result - // - *OutHcdController = (PHCDCONTROLLER)This; - - // - // done - // - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/usb/usbuhci/hub_controller.cpp b/reactos/drivers/usb/usbuhci/hub_controller.cpp deleted file mode 100644 index 7d7492ac28e..00000000000 --- a/reactos/drivers/usb/usbuhci/hub_controller.cpp +++ /dev/null @@ -1,3742 +0,0 @@ -/* - * PROJECT: ReactOS Universal Serial Bus Host Controller Interface - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/usb/usbuhci/hub_controller.cpp - * PURPOSE: USB UHCI device driver. - * PROGRAMMERS: - * Michael Martin (michael.martin@reactos.org) - * Johannes Anderwald (johannes.anderwald@reactos.org) - */ - -#define INITGUID -#include "usbuhci.h" - -VOID StatusChangeEndpointCallBack( - PVOID Context); - -class CHubController : public IHubController, - public IDispatchIrp -{ -public: - STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - - // IHubController interface functions - virtual NTSTATUS Initialize(IN PDRIVER_OBJECT DriverObject, IN PHCDCONTROLLER Controller, IN PUSBHARDWAREDEVICE Device, IN BOOLEAN IsRootHubDevice, IN ULONG DeviceAddress); - virtual NTSTATUS GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject); - virtual NTSTATUS GetHubControllerSymbolicLink(ULONG BufferLength, PVOID Buffer, PULONG RequiredLength); - - // IDispatchIrp interface functions - virtual NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp); - virtual NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp); - virtual NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp); - - // local functions - NTSTATUS HandleQueryInterface(PIO_STACK_LOCATION IoStack); - NTSTATUS SetDeviceInterface(BOOLEAN bEnable); - NTSTATUS CreatePDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject); - PUSBHARDWAREDEVICE GetUsbHardware(); - ULONG AcquireDeviceAddress(); - VOID ReleaseDeviceAddress(ULONG DeviceAddress); - BOOLEAN ValidateUsbDevice(PUSBDEVICE UsbDevice); - NTSTATUS AddUsbDevice(PUSBDEVICE UsbDevice); - NTSTATUS RemoveUsbDevice(PUSBDEVICE UsbDevice); - VOID SetNotification(PVOID CallbackContext, PRH_INIT_CALLBACK CallbackRoutine); - // internal ioctl routines - NTSTATUS HandleGetDescriptor(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleGetDescriptorFromInterface(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleClassDevice(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleGetStatusFromDevice(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleSelectInterface(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleClassInterface(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleClassEndpoint(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleIsochronousTransfer(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleClearStall(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleSyncResetAndClearStall(IN OUT PIRP Irp, PURB Urb); - NTSTATUS HandleAbortPipe(IN OUT PIRP Irp, PURB Urb); - - friend VOID StatusChangeEndpointCallBack(PVOID Context); - - // constructor / destructor - CHubController(IUnknown *OuterUnknown){} - virtual ~CHubController(){} - -protected: - LONG m_Ref; - PHCDCONTROLLER m_Controller; - PUSBHARDWAREDEVICE m_Hardware; - BOOLEAN m_IsRootHubDevice; - ULONG m_DeviceAddress; - - BOOLEAN m_InterfaceEnabled; - UNICODE_STRING m_HubDeviceInterfaceString; - - PDEVICE_OBJECT m_HubControllerDeviceObject; - PDRIVER_OBJECT m_DriverObject; - - PVOID m_HubCallbackContext; - PRH_INIT_CALLBACK m_HubCallbackRoutine; - - USB_DEVICE_DESCRIPTOR m_DeviceDescriptor; - - KSPIN_LOCK m_Lock; - RTL_BITMAP m_DeviceAddressBitmap; - PULONG m_DeviceAddressBitmapBuffer; - LIST_ENTRY m_UsbDeviceList; - PIRP m_PendingSCEIrp; - - //Internal Functions - BOOLEAN QueryStatusChageEndpoint(PIRP Irp); -}; - -typedef struct -{ - LIST_ENTRY Entry; - PUSBDEVICE Device; -}USBDEVICE_ENTRY, *PUSBDEVICE_ENTRY; - -/* Lifted from Linux with slight changes */ -const UCHAR ROOTHUB2_DEVICE_DESCRIPTOR [] = -{ - 0x12, /* bLength; */ - USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType; Device */ - 0x00, 0x20, /* bcdUSB; v1.1 */ - USB_DEVICE_CLASS_HUB, /* bDeviceClass; HUB_CLASSCODE */ - 0x01, /* bDeviceSubClass; */ - 0x00, /* bDeviceProtocol; [ low/full speeds only ] */ - 0x08, /* bMaxPacketSize0; 8 Bytes */ - /* Fill Vendor and Product in when init root hub */ - 0x00, 0x00, /* idVendor; */ - 0x00, 0x00, /* idProduct; */ - 0x00, 0x00, /* bcdDevice */ - 0x00, /* iManufacturer; */ - 0x00, /* iProduct; */ - 0x00, /* iSerialNumber; */ - 0x01 /* bNumConfigurations; */ - -}; - -const USB_CONFIGURATION_DESCRIPTOR ROOTHUB2_CONFIGURATION_DESCRIPTOR = -{ - sizeof(USB_CONFIGURATION_DESCRIPTOR), - USB_CONFIGURATION_DESCRIPTOR_TYPE, - sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR), - 1, - 1, - 0, - 0x40, /* self powered */ - 0x0 -}; - -const USB_INTERFACE_DESCRIPTOR ROOTHUB2_INTERFACE_DESCRIPTOR = -{ - sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType; Interface */ - 0, /* bInterfaceNumber; */ - 0, /* bAlternateSetting; */ - 0x1, /* bNumEndpoints; */ - 0x09, /* bInterfaceClass; HUB_CLASSCODE */ - 0x01, /* bInterfaceSubClass; */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface; */ -}; - -const USB_ENDPOINT_DESCRIPTOR ROOTHUB2_ENDPOINT_DESCRIPTOR = -{ - sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x81, /* bEndPointAddress */ - USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ - 0x01, /* wMaxPacketSize */ - 0xC /* bInterval */ -}; - -//---------------------------------------------------------------------------------------- -NTSTATUS -STDMETHODCALLTYPE -CHubController::QueryInterface( - IN REFIID refiid, - OUT PVOID* Output) -{ - return STATUS_UNSUCCESSFUL; -} -//---------------------------------------------------------------------------------------- -NTSTATUS -CHubController::Initialize( - IN PDRIVER_OBJECT DriverObject, - IN PHCDCONTROLLER Controller, - IN PUSBHARDWAREDEVICE Device, - IN BOOLEAN IsRootHubDevice, - IN ULONG DeviceAddress) -{ - NTSTATUS Status; - PCOMMON_DEVICE_EXTENSION DeviceExtension; - USHORT VendorID, DeviceID; - ULONG Dummy1; - - DPRINT("CHubController::Initialize\n"); - - // - // initialize members - // - m_Controller = Controller; - m_Hardware = Device; - m_IsRootHubDevice = IsRootHubDevice; - m_DeviceAddress = DeviceAddress; - m_DriverObject = DriverObject; - KeInitializeSpinLock(&m_Lock); - InitializeListHead(&m_UsbDeviceList); - - // - // allocate device address bitmap buffer - // - m_DeviceAddressBitmapBuffer = (PULONG)ExAllocatePoolWithTag(NonPagedPool, 16, TAG_USBUHCI); - if (!m_DeviceAddressBitmapBuffer) - { - // - // no memory - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // initialize device address bitmap - // - RtlInitializeBitMap(&m_DeviceAddressBitmap, m_DeviceAddressBitmapBuffer, 128); - RtlClearAllBits(&m_DeviceAddressBitmap); - - - // - // create PDO - // - Status = CreatePDO(m_DriverObject, &m_HubControllerDeviceObject); - if (!NT_SUCCESS(Status)) - { - // - // failed to create hub device object - // - return Status; - } - - // - // get device extension - // - DeviceExtension = (PCOMMON_DEVICE_EXTENSION)m_HubControllerDeviceObject->DeviceExtension; - - // - // initialize device extension - // - DeviceExtension->IsFDO = FALSE; - DeviceExtension->IsHub = TRUE; //FIXME - DeviceExtension->Dispatcher = PDISPATCHIRP(this); - - // - // intialize device descriptor - // - C_ASSERT(sizeof(USB_DEVICE_DESCRIPTOR) == sizeof(ROOTHUB2_DEVICE_DESCRIPTOR)); - RtlMoveMemory(&m_DeviceDescriptor, ROOTHUB2_DEVICE_DESCRIPTOR, sizeof(USB_DEVICE_DESCRIPTOR)); - - if (NT_SUCCESS(m_Hardware->GetDeviceDetails(&VendorID, &DeviceID, &Dummy1, &Dummy1))) - { - // - // update device descriptor - // - m_DeviceDescriptor.idVendor = VendorID; - m_DeviceDescriptor.idProduct = DeviceID; - m_DeviceDescriptor.bcdUSB = 0x110; //FIXME - } - - // - // Set the SCE Callback that the Hardware Device will call on port status change - // - Device->SetStatusChangeEndpointCallBack((PVOID)StatusChangeEndpointCallBack, this); - - // - // clear init flag - // - m_HubControllerDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; - - return STATUS_SUCCESS; -} - -// -// Queries the ports to see if there has been a device connected or removed. -// -BOOLEAN -CHubController::QueryStatusChageEndpoint( - PIRP Irp) -{ - ULONG PortCount, PortId; - PIO_STACK_LOCATION IoStack; - USHORT PortStatus, PortChange; - PURB Urb; - PUCHAR TransferBuffer; - UCHAR Changed = FALSE; - - // - // get current stack location - // - IoStack = IoGetCurrentIrpStackLocation(Irp); - ASSERT(IoStack); - - // - // Get the Urb - // - Urb = (PURB)IoStack->Parameters.Others.Argument1; - ASSERT(Urb); - - // - // Get the number of ports and check each one for device connected - // - m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL); - DPRINT("SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, Urb->UrbBulkOrInterruptTransfer.TransferFlags, Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL); - - TransferBuffer = (PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer; - - // - // Loop the ports - // - for (PortId = 0; PortId < PortCount; PortId++) - { - m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange); - - DPRINT("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange); - - - // - // If theres a flag in PortChange return TRUE so the SCE Irp will be completed - // - if (PortChange != 0) - { - DPRINT1("Change state on port %d\n", PortId); - // Set the value for the port number - *TransferBuffer = 1 << ((PortId + 1) & 7); - Changed = TRUE; - } - } - - return Changed; -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject) -{ - // - // store controller object - // - *HubDeviceObject = m_HubControllerDeviceObject; - - return STATUS_SUCCESS; -} -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::GetHubControllerSymbolicLink( - ULONG BufferLength, - PVOID Buffer, - PULONG RequiredLength) -{ - if (!m_InterfaceEnabled) - { - // - // device interface not yet enabled - // - return STATUS_UNSUCCESSFUL; - } - - if (BufferLength < (ULONG)m_HubDeviceInterfaceString.Length - 8) - { - // - // buffer too small - // length is without '\??\' - // - *RequiredLength = m_HubDeviceInterfaceString.Length- 8; - - // - // done - // - return STATUS_BUFFER_OVERFLOW; - } - - // - // copy symbolic link - // - RtlCopyMemory(Buffer, &m_HubDeviceInterfaceString.Buffer[4], m_HubDeviceInterfaceString.Length - 8); - - // - // store length, length is without '\??\' - // - *RequiredLength = m_HubDeviceInterfaceString.Length - 8; - - // - // done - // - return STATUS_SUCCESS; -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandlePnp( - IN PDEVICE_OBJECT DeviceObject, - IN OUT PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PCOMMON_DEVICE_EXTENSION DeviceExtension; - PDEVICE_CAPABILITIES DeviceCapabilities; - PPNP_BUS_INFORMATION BusInformation; - PDEVICE_RELATIONS DeviceRelations; - NTSTATUS Status; - ULONG Index = 0, Length; - USHORT VendorID, DeviceID; - ULONG HiSpeed, NumPorts; - WCHAR Buffer[300]; - LPWSTR DeviceName; - - // - // get device extension - // - DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - // - // sanity check - // - ASSERT(DeviceExtension->IsFDO == FALSE); - - // - // get current stack location - // - IoStack = IoGetCurrentIrpStackLocation(Irp); - - switch(IoStack->MinorFunction) - { - case IRP_MN_START_DEVICE: - { - DPRINT("CHubController::HandlePnp IRP_MN_START_DEVICE\n"); - // - // register device interface - // - Status = SetDeviceInterface(TRUE); - break; - } - case IRP_MN_QUERY_STOP_DEVICE: - case IRP_MN_QUERY_REMOVE_DEVICE: - { - // - // sure - // - Status = STATUS_SUCCESS; - break; - } - case IRP_MN_QUERY_ID: - { - DPRINT("CHubController::HandlePnp IRP_MN_QUERY_ID Type %x\n", IoStack->Parameters.QueryId.IdType); - - if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID) - { - if (m_Hardware) - { - // - // query device id - // - Status = m_Hardware->GetDeviceDetails(&VendorID, &DeviceID, &NumPorts, &HiSpeed); - - if (HiSpeed == 0x200) - { - // - // USB 2.0 hub - // - swprintf(Buffer, L"USB\\ROOT_HUB20"); - } - else - { - // - // USB 1.1 hub - // - swprintf(Buffer, L"USB\\ROOT_HUB"); - } - - DPRINT("Name %S\n", Buffer); - - // - // calculate length - // - Length = (wcslen(Buffer) + 1); - - // - // allocate buffer - // - DeviceName = (LPWSTR)ExAllocatePoolWithTag(PagedPool, Length * sizeof(WCHAR), TAG_USBUHCI); - - if (!DeviceName) - { - // - // no memory - // - Status = STATUS_INSUFFICIENT_RESOURCES; - break; - } - - // - // copy device name - // - wcscpy(DeviceName, Buffer); - - // - // store result - // - Irp->IoStatus.Information = (ULONG_PTR)DeviceName; - Status = STATUS_SUCCESS; - break; - } - Status = STATUS_UNSUCCESSFUL; - PC_ASSERT(0); - break; - } - - if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs) - { - if (m_Hardware) - { - // - // query device id - // - Status = m_Hardware->GetDeviceDetails(&VendorID, &DeviceID, &NumPorts, &HiSpeed); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("CHubController::HandlePnp> failed to get hardware id %x\n", Status); - VendorID = 0x8086; - DeviceID = 0x3A37; - } - - if (HiSpeed == 0x200) - { - // - // USB 2.0 hub - // - Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID%04x&PID%04x&REV0000", VendorID, DeviceID) + 1; - Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID%04x&PID%04x", VendorID, DeviceID) + 1; - Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20") + 1; - } - else - { - // - // USB 1.1 hub - // - Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB&VID%04x&PID%04x&REV0000", VendorID, DeviceID) + 1; - Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB&VID%04x&PID%04x", VendorID, DeviceID) + 1; - Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB") + 1; - } - - Buffer[Index] = UNICODE_NULL; - Index++; - - - DPRINT("Name %S\n", Buffer); - - // - // allocate buffer - // - DeviceName = (LPWSTR)ExAllocatePoolWithTag(PagedPool, Index * sizeof(WCHAR), TAG_USBUHCI); - - if (!DeviceName) - { - // - // no memory - // - Status = STATUS_INSUFFICIENT_RESOURCES; - break; - } - - // - // copy device name - // - RtlMoveMemory(DeviceName, Buffer, Index * sizeof(WCHAR)); - - // - // store result - // - Irp->IoStatus.Information = (ULONG_PTR)DeviceName; - Status = STATUS_SUCCESS; - break; - } - } - Status = STATUS_SUCCESS; - break; - } - case IRP_MN_QUERY_CAPABILITIES: - { - DPRINT("CHubController::HandlePnp IRP_MN_QUERY_CAPABILITIES\n"); - - DeviceCapabilities = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities; - - DeviceCapabilities->LockSupported = FALSE; - DeviceCapabilities->EjectSupported = FALSE; - DeviceCapabilities->Removable = FALSE; - DeviceCapabilities->DockDevice = FALSE; - DeviceCapabilities->UniqueID = FALSE; - DeviceCapabilities->SilentInstall = FALSE; - DeviceCapabilities->RawDeviceOK = FALSE; - DeviceCapabilities->SurpriseRemovalOK = FALSE; - DeviceCapabilities->Address = 0; - DeviceCapabilities->UINumber = 0; - DeviceCapabilities->DeviceD2 = 1; - - /* FIXME */ - DeviceCapabilities->HardwareDisabled = FALSE; - DeviceCapabilities->NoDisplayInUI = FALSE; - DeviceCapabilities->DeviceState[0] = PowerDeviceD0; - for (Index = 1; Index < PowerSystemMaximum; Index++) - DeviceCapabilities->DeviceState[Index] = PowerDeviceD3; - DeviceCapabilities->DeviceWake = PowerDeviceUnspecified; - DeviceCapabilities->D1Latency = 0; - DeviceCapabilities->D2Latency = 0; - DeviceCapabilities->D3Latency = 0; - - Status = STATUS_SUCCESS; - break; - } - case IRP_MN_QUERY_INTERFACE: - { - DPRINT("CHubController::HandlePnp IRP_MN_QUERY_INTERFACE\n"); - - // - // handle device interface requests - // - Status = HandleQueryInterface(IoStack); - break; - } - case IRP_MN_REMOVE_DEVICE: - { - DPRINT("CHubController::HandlePnp IRP_MN_REMOVE_DEVICE\n"); - - // - // deactivate device interface for BUS PDO - // - SetDeviceInterface(FALSE); - - // - // complete the request first - // - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - // - // now delete device - // - IoDeleteDevice(m_HubControllerDeviceObject); - - // - // nullify pointer - // - m_HubControllerDeviceObject = 0; - - // - // done - // - return STATUS_SUCCESS; - } - case IRP_MN_QUERY_DEVICE_RELATIONS: - { - DPRINT("CHubController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %x\n", IoStack->Parameters.QueryDeviceRelations.Type); - - if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation) - { - // - // allocate device relations - // - DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(PagedPool, sizeof(DEVICE_RELATIONS), TAG_USBUHCI); - if (!DeviceRelations) - { - // - // no memory - // - Status = STATUS_INSUFFICIENT_RESOURCES; - break; - } - - // - // initialize device relations - // - DeviceRelations->Count = 1; - DeviceRelations->Objects[0] = DeviceObject; - ObReferenceObject(DeviceObject); - - // - // done - // - Status = STATUS_SUCCESS; - Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; - } - else - { - // - // not handled - // - Status = Irp->IoStatus.Status; - } - break; - } - case IRP_MN_QUERY_BUS_INFORMATION: - { - DPRINT("CHubController::HandlePnp IRP_MN_QUERY_BUS_INFORMATION\n"); - - // - // allocate buffer for bus information - // - BusInformation = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION)); - if (BusInformation) - { - // - // copy BUS guid - // - RtlMoveMemory(&BusInformation->BusTypeGuid, &GUID_BUS_TYPE_USB, sizeof(GUID)); - - // - // set bus type - // - BusInformation->LegacyBusType = PNPBus; - BusInformation->BusNumber = 0; - - Status = STATUS_SUCCESS; - Irp->IoStatus.Information = (ULONG_PTR)BusInformation; - } - else - { - // - // no memory - // - Status = STATUS_INSUFFICIENT_RESOURCES; - } - break; - } - case IRP_MN_STOP_DEVICE: - { - DPRINT("CHubController::HandlePnp IRP_MN_STOP_DEVICE\n"); - // - // stop device - // - Status = STATUS_SUCCESS; - break; - } - default: - { - // - // ignore request with default status - // - Status = Irp->IoStatus.Status; - break; - } - } - - // - // complete request - // - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - // - // done - // - return Status; -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandlePower( - IN PDEVICE_OBJECT DeviceObject, - IN OUT PIRP Irp) -{ - UNIMPLEMENTED - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleIsochronousTransfer( - IN OUT PIRP Irp, - PURB Urb) -{ - PUSBDEVICE UsbDevice; - PUSB_ENDPOINT_DESCRIPTOR EndPointDesc = NULL; - - // - // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer Request - // - EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbIsochronousTransfer.PipeHandle; - - if (!EndPointDesc) - { - DPRINT1("No EndpointDesc\n"); - Urb->UrbIsochronousTransfer.Hdr.Status = USBD_STATUS_INVALID_PIPE_HANDLE; - return STATUS_INVALID_PARAMETER; - } - - // - // sanity checks - // - ASSERT(EndPointDesc); - ASSERT((EndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_ISOCHRONOUS); - - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleIsochronousTransfer invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - return UsbDevice->SubmitIrp(Irp); -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleBulkOrInterruptTransfer( - IN OUT PIRP Irp, - PURB Urb) -{ - PUSBDEVICE UsbDevice; - PUSB_ENDPOINT_DESCRIPTOR EndPointDesc = NULL; - // - // First check if the request is for the Status Change Endpoint - // - - // - // Is the Request for the root hub - // - if (Urb->UrbHeader.UsbdDeviceHandle == 0) - { - ASSERT(m_PendingSCEIrp == NULL); - if (QueryStatusChageEndpoint(Irp)) - { - StatusChangeEndpointCallBack(this); - return STATUS_SUCCESS; - } - - // - // Else pend the IRP, to be completed when a device connects or disconnects. - // - DPRINT("Pending SCE Irp\n");; - m_PendingSCEIrp = Irp; - IoMarkIrpPending(Irp); - return STATUS_PENDING; - } - - // - // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer Request - // - EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle; - - // - // sanity checks - // - ASSERT(EndPointDesc); - ASSERT((EndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK || (EndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT); - - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleBuldOrInterruptTransfer invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - return UsbDevice->SubmitIrp(Irp); -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleClassOther( - IN OUT PIRP Irp, - PURB Urb) -{ - NTSTATUS Status = STATUS_NOT_IMPLEMENTED; - USHORT PortStatus = 0, PortChange = 0; - PUSHORT Buffer; - ULONG NumPort; - ULONG PortId; - - DPRINT("CHubController::HandleClassOther> Request %x Value %x\n", Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value); - - // - // get number of ports available - // - Status = m_Hardware->GetDeviceDetails(NULL, NULL, &NumPort, NULL); - PC_ASSERT(Status == STATUS_SUCCESS); - - // - // sanity check - // - PC_ASSERT(Urb->UrbControlVendorClassRequest.Index - 1 < (USHORT)NumPort); - - // - // port range reported start from 1 -n - // convert back port id so it matches the hardware - // - PortId = Urb->UrbControlVendorClassRequest.Index - 1; - - // - // check request code - // - switch(Urb->UrbControlVendorClassRequest.Request) - { - case USB_REQUEST_GET_STATUS: - { - // - // sanity check - // - PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength == sizeof(USHORT) * 2); - PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer); - - // - // get port status - // - Status = m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange); - - if (NT_SUCCESS(Status)) - { - // - // request contains buffer of 2 ushort which are used from submitting port status and port change status - // - DPRINT("PortId %x PortStatus %x PortChange %x\n", PortId, PortStatus, PortChange); - Buffer = (PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer; - - // - // store status, then port change - // - *Buffer = PortStatus; - Buffer++; - *Buffer = PortChange; - } - - // - // done - // - break; - } - case USB_REQUEST_CLEAR_FEATURE: - { - switch (Urb->UrbControlVendorClassRequest.Value) - { - case C_PORT_CONNECTION: - Status = m_Hardware->ClearPortStatus(PortId, C_PORT_CONNECTION); - break; - case C_PORT_RESET: - Status= m_Hardware->ClearPortStatus(PortId, C_PORT_RESET); - break; - default: - DPRINT("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value); - break; - } - - break; - } - case USB_REQUEST_SET_FEATURE: - { - // - // request set feature - // - switch(Urb->UrbControlVendorClassRequest.Value) - { - case PORT_ENABLE: - { - // - // port enable - // - Status = m_Hardware->SetPortFeature(PortId, PORT_ENABLE); - break; - } - - case PORT_SUSPEND: - { - // - // set suspend port feature - // - Status = m_Hardware->SetPortFeature(PortId, PORT_SUSPEND); - break; - } - case PORT_POWER: - { - // - // set power feature on port - // - Status = m_Hardware->SetPortFeature(PortId, PORT_POWER); - break; - } - - case PORT_RESET: - { - // - // reset port feature - // - Status = m_Hardware->SetPortFeature(PortId, PORT_RESET); - break; - } - default: - DPRINT1("Unsupported request id %x\n", Urb->UrbControlVendorClassRequest.Value); - PC_ASSERT(FALSE); - } - break; - } - default: - DPRINT1("CHubController::HandleClassOther Unknown request code %x\n", Urb->UrbControlVendorClassRequest.Request); - PC_ASSERT(0); - Status = STATUS_INVALID_DEVICE_REQUEST; - } - return Status; -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleSelectConfiguration( - IN OUT PIRP Irp, - PURB Urb) -{ - PUSBDEVICE UsbDevice; - PUSBD_INTERFACE_INFORMATION InterfaceInfo; - - // - // is the request for the Root Hub - // - if (Urb->UrbHeader.UsbdDeviceHandle == NULL) - { - // - // FIXME: support setting device to unconfigured state - // - PC_ASSERT(Urb->UrbSelectConfiguration.ConfigurationDescriptor); - - // - // set device handle - // - Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&ROOTHUB2_CONFIGURATION_DESCRIPTOR; - - // - // copy interface info - // - InterfaceInfo = &Urb->UrbSelectConfiguration.Interface; - - InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)&ROOTHUB2_INTERFACE_DESCRIPTOR; - InterfaceInfo->Class = ROOTHUB2_INTERFACE_DESCRIPTOR.bInterfaceClass; - InterfaceInfo->SubClass = ROOTHUB2_INTERFACE_DESCRIPTOR.bInterfaceSubClass; - InterfaceInfo->Protocol = ROOTHUB2_INTERFACE_DESCRIPTOR.bInterfaceProtocol; - InterfaceInfo->Reserved = 0; - - // - // sanity check - // - PC_ASSERT(InterfaceInfo->NumberOfPipes == 1); - - // - // copy pipe info - // - InterfaceInfo->Pipes[0].MaximumPacketSize = ROOTHUB2_ENDPOINT_DESCRIPTOR.wMaxPacketSize; - InterfaceInfo->Pipes[0].EndpointAddress = ROOTHUB2_ENDPOINT_DESCRIPTOR.bEndpointAddress; - InterfaceInfo->Pipes[0].Interval = ROOTHUB2_ENDPOINT_DESCRIPTOR.bInterval; - InterfaceInfo->Pipes[0].PipeType = (USBD_PIPE_TYPE)(ROOTHUB2_ENDPOINT_DESCRIPTOR.bmAttributes & USB_ENDPOINT_TYPE_MASK); - InterfaceInfo->Pipes[0].PipeHandle = (PVOID)&ROOTHUB2_ENDPOINT_DESCRIPTOR; - - return STATUS_SUCCESS; - } - else - { - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleSelectConfiguration invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - // - // select configuration - // - return UsbDevice->SelectConfiguration(Urb->UrbSelectConfiguration.ConfigurationDescriptor, &Urb->UrbSelectConfiguration.Interface, &Urb->UrbSelectConfiguration.ConfigurationHandle); - } -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleSelectInterface( - IN OUT PIRP Irp, - PURB Urb) -{ - PUSBDEVICE UsbDevice; - - // - // sanity check - // - PC_ASSERT(Urb->UrbSelectInterface.ConfigurationHandle); - - // - // is the request for the Root Hub - // - if (Urb->UrbHeader.UsbdDeviceHandle == NULL) - { - // - // no op for root hub - // - return STATUS_SUCCESS; - } - else - { - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleSelectInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - // - // select interface - // - return UsbDevice->SelectInterface(Urb->UrbSelectInterface.ConfigurationHandle, &Urb->UrbSelectInterface.Interface); - } -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleGetStatusFromDevice( - IN OUT PIRP Irp, - PURB Urb) -{ - PUSHORT DeviceStatus; - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - NTSTATUS Status; - PUSBDEVICE UsbDevice; - - // - // sanity checks - // - PC_ASSERT(Urb->UrbControlGetStatusRequest.Index == 0); - PC_ASSERT(Urb->UrbControlGetStatusRequest.TransferBufferLength >= sizeof(USHORT)); - PC_ASSERT(Urb->UrbControlGetStatusRequest.TransferBuffer); - - // - // get status buffer - // - DeviceStatus = (PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer; - - - if (Urb->UrbHeader.UsbdDeviceHandle == NULL) - { - // - // FIXME need more flags ? - // - *DeviceStatus = USB_PORT_STATUS_CONNECT; - return STATUS_SUCCESS; - } - - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleGetStatusFromDevice invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - - // - // generate setup packet - // - CtrlSetup.bRequest = USB_REQUEST_GET_STATUS; - CtrlSetup.wValue.LowByte = 0; - CtrlSetup.wValue.HiByte = 0; - CtrlSetup.wIndex.W = Urb->UrbControlGetStatusRequest.Index; - CtrlSetup.wLength = (USHORT)Urb->UrbControlGetStatusRequest.TransferBufferLength; - CtrlSetup.bmRequestType.B = 0x80; - - // - // submit setup packet - // - Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer); - ASSERT(Status == STATUS_SUCCESS); - DPRINT("CHubController::HandleGetStatusFromDevice Status %x Length %lu DeviceStatus %x\n", Status, Urb->UrbControlDescriptorRequest.TransferBufferLength, *DeviceStatus); - - // - // done - // - return Status; -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleClassDevice( - IN OUT PIRP Irp, - IN OUT PURB Urb) -{ - NTSTATUS Status = STATUS_NOT_IMPLEMENTED; - PUSB_HUB_DESCRIPTOR UsbHubDescriptor; - ULONG PortCount, Dummy2; - USHORT Dummy1; - PUSBDEVICE UsbDevice; - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - - DPRINT("CHubController::HandleClassDevice Request %x Class %x\n", Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value >> 8); - - // - // check class request type - // - switch(Urb->UrbControlVendorClassRequest.Request) - { - case USB_REQUEST_GET_STATUS: - { - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("USB_REQUEST_GET_STATUS invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - - // - // generate setup packet - // - CtrlSetup.bRequest = USB_REQUEST_GET_STATUS; - CtrlSetup.wValue.LowByte = Urb->UrbControlVendorClassRequest.Index; - CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value; - CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index; - CtrlSetup.wLength = (USHORT)Urb->UrbControlGetStatusRequest.TransferBufferLength; - CtrlSetup.bmRequestType.B = 0xA0; - - // - // submit setup packet - // - Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer); - ASSERT(Status == STATUS_SUCCESS); - break; - } - case USB_REQUEST_GET_DESCRIPTOR: - { - switch (Urb->UrbControlVendorClassRequest.Value >> 8) - { - case USB_DEVICE_CLASS_RESERVED: // FALL THROUGH - case USB_DEVICE_CLASS_HUB: - { - // - // sanity checks - // - PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer); - PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR)); - - // - // get hub descriptor - // - UsbHubDescriptor = (PUSB_HUB_DESCRIPTOR)Urb->UrbControlVendorClassRequest.TransferBuffer; - - // - // one hub is handled - // - UsbHubDescriptor->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR); - Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR); - - // - // type should 0x29 according to msdn - // - UsbHubDescriptor->bDescriptorType = 0x29; - - // - // get port count - // - Status = m_Hardware->GetDeviceDetails(&Dummy1, &Dummy1, &PortCount, &Dummy2); - PC_ASSERT(Status == STATUS_SUCCESS); - - // - // FIXME: retrieve values - // - UsbHubDescriptor->bNumberOfPorts = (UCHAR)PortCount; - UsbHubDescriptor->wHubCharacteristics = 0x00; - UsbHubDescriptor->bPowerOnToPowerGood = 0x01; - UsbHubDescriptor->bHubControlCurrent = 0x00; - - // - // done - // - Status = STATUS_SUCCESS; - break; - } - default: - DPRINT1("CHubController::HandleClassDevice Class %x not implemented\n", Urb->UrbControlVendorClassRequest.Value >> 8); - break; - } - break; - } - default: - DPRINT1("CHubController::HandleClassDevice Type %x not implemented\n", Urb->UrbControlVendorClassRequest.Request); - } - - return Status; -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleGetDescriptorFromInterface( - IN OUT PIRP Irp, - IN OUT PURB Urb) -{ - PUSBDEVICE UsbDevice; - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - NTSTATUS Status; - - // - // sanity check - // - ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength); - ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); - - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleGetDescriptorFromInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - // - // generate setup packet - // - CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; - CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index; - CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType; - CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId; - CtrlSetup.wLength = (USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength; - CtrlSetup.bmRequestType.B = 0x81; - - // - // submit setup packet - // - Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer); - ASSERT(Status == STATUS_SUCCESS); - - // - // done - // - return Status; -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleGetDescriptor( - IN OUT PIRP Irp, - IN OUT PURB Urb) -{ - NTSTATUS Status = STATUS_NOT_IMPLEMENTED; - PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - PUCHAR Buffer; - PUSBDEVICE UsbDevice; - ULONG Length; - - DPRINT("CHubController::HandleGetDescriptor\n"); - - // - // check descriptor type - // - switch(Urb->UrbControlDescriptorRequest.DescriptorType) - { - case USB_DEVICE_DESCRIPTOR_TYPE: - { - // - // sanity check - // - PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR)); - PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); - - if (Urb->UrbHeader.UsbdDeviceHandle == NULL) - { - // - // copy root hub device descriptor - // - RtlCopyMemory((PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); - Status = STATUS_SUCCESS; - } - else - { - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleGetDescriptor invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - // - // retrieve device descriptor from device - // - UsbDevice->GetDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer); - Status = STATUS_SUCCESS; - } - break; - } - case USB_CONFIGURATION_DESCRIPTOR_TYPE: - { - // - // sanity checks - // - PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); - PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR)); - - if (Urb->UrbHeader.UsbdDeviceHandle == NULL) - { - // - // request is for the root bus controller - // - RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, &ROOTHUB2_CONFIGURATION_DESCRIPTOR, sizeof(USB_CONFIGURATION_DESCRIPTOR)); - - // - // get configuration descriptor, very retarded! - // - ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer; - - // - // check if buffer can hold interface and endpoint descriptor - // - if (ConfigurationDescriptor->wTotalLength > Urb->UrbControlDescriptorRequest.TransferBufferLength) - { - // - // buffer too small - // - Status = STATUS_SUCCESS; - ASSERT(FALSE); - break; - } - - // - // copy interface descriptor template - // - Buffer = (PUCHAR)(ConfigurationDescriptor + 1); - RtlCopyMemory(Buffer, &ROOTHUB2_INTERFACE_DESCRIPTOR, sizeof(USB_INTERFACE_DESCRIPTOR)); - - // - // copy end point descriptor template - // - Buffer += sizeof(USB_INTERFACE_DESCRIPTOR); - RtlCopyMemory(Buffer, &ROOTHUB2_ENDPOINT_DESCRIPTOR, sizeof(USB_ENDPOINT_DESCRIPTOR)); - - // - // done - // - Status = STATUS_SUCCESS; - - } - else - { - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("USB_CONFIGURATION_DESCRIPTOR_TYPE invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - if (sizeof(USB_CONFIGURATION_DESCRIPTOR) > Urb->UrbControlDescriptorRequest.TransferBufferLength) - { - // - // buffer too small - // - Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->GetConfigurationDescriptorsLength(); - - // - // bail out - // - Status = STATUS_SUCCESS; - break; - } - - // - // perform work in IUSBDevice - // - UsbDevice->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength, &Length); - - // - // store result size - // - Urb->UrbControlDescriptorRequest.TransferBufferLength = Length; - Status = STATUS_SUCCESS; - } - break; - } - case USB_STRING_DESCRIPTOR_TYPE: - { - // - // sanity check - // - PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); - PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength); - - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("USB_STRING_DESCRIPTOR_TYPE invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - // - // generate setup packet - // - CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; - CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index; - CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType; - CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId; - CtrlSetup.wLength = (USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength; - CtrlSetup.bmRequestType.B = 0x80; - - // - // submit setup packet - // - Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer); - break; - } - default: - DPRINT1("CHubController::HandleGetDescriptor DescriptorType %x unimplemented\n", Urb->UrbControlDescriptorRequest.DescriptorType); - break; - } - - // - // done - // - return Status; -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleClassEndpoint( - IN OUT PIRP Irp, - IN OUT PURB Urb) -{ - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - NTSTATUS Status; - PUSBDEVICE UsbDevice; - - // - // sanity check - // - PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer); - PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength); - PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle); - - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleClassEndpoint invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - - DPRINT1("URB_FUNCTION_CLASS_ENDPOINT\n"); - DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags); - DPRINT1("TransferBufferLength %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength); - DPRINT1("TransferBuffer %x\n", Urb->UrbControlVendorClassRequest.TransferBuffer); - DPRINT1("TransferBufferMDL %x\n", Urb->UrbControlVendorClassRequest.TransferBufferMDL); - DPRINT1("RequestTypeReservedBits %x\n", Urb->UrbControlVendorClassRequest.RequestTypeReservedBits); - DPRINT1("Request %x\n", Urb->UrbControlVendorClassRequest.Request); - DPRINT1("Value %x\n", Urb->UrbControlVendorClassRequest.Value); - DPRINT1("Index %x\n", Urb->UrbControlVendorClassRequest.Index); - - // - // initialize setup packet - // - CtrlSetup.bmRequestType.B = 0x22; //FIXME: Const. - CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request; - CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value; - CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index; - CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength; - - if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN) - { - // - // data direction is device to host - // - CtrlSetup.bmRequestType.B |= 0x80; - } - - - // - // issue request - // - Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer); - - // - // assert on failure - // - PC_ASSERT(NT_SUCCESS(Status)); - - - // - // done - // - return Status; -} - -NTSTATUS -CHubController::HandleSyncResetAndClearStall( - IN OUT PIRP Irp, - IN OUT PURB Urb) -{ - NTSTATUS Status = STATUS_SUCCESS; - PUSB_ENDPOINT EndpointDescriptor; - ULONG Type; - - // - // sanity check - // - PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle); - PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST)); - PC_ASSERT(Urb->UrbPipeRequest.PipeHandle); - - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleAbortPipe invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get endpoint descriptor - // - EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbPipeRequest.PipeHandle; - - // - // abort pipe - // - Status = HandleAbortPipe(Irp, Urb); - if (!NT_SUCCESS(Status)) - { - // - // abort pipe failed - // - DPRINT1("[USBUHCI] AbortPipe failed with %x\n", Status); - } - - // - // get type - // - Type = (EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK); - if (Type != USB_ENDPOINT_TYPE_ISOCHRONOUS) - { - // - // clear stall - // - Status = HandleClearStall(Irp, Urb); - } - DPRINT1("URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL Status %x\n", Status); - - // - // reset data toggle - // - EndpointDescriptor->DataToggle = 0; - - // - // done - // - return Status; -} - -NTSTATUS -CHubController::HandleAbortPipe( - IN OUT PIRP Irp, - IN OUT PURB Urb) -{ - NTSTATUS Status; - PUSBDEVICE UsbDevice; - PUSB_ENDPOINT EndpointDescriptor; - - // - // sanity check - // - PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle); - PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST)); - PC_ASSERT(Urb->UrbPipeRequest.PipeHandle); - - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleAbortPipe invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get endpoint descriptor - // - EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbPipeRequest.PipeHandle; - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - - // - // issue request - // - Status = UsbDevice->AbortPipe(EndpointDescriptor); - DPRINT1("URB_FUNCTION_ABORT_PIPE Status %x\n", Status); - - // - // done - // - return Status; -} - - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleClearStall( - IN OUT PIRP Irp, - IN OUT PURB Urb) -{ - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - NTSTATUS Status; - PUSBDEVICE UsbDevice; - PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor; - - - // - // sanity check - // - PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle); - PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST)); - PC_ASSERT(Urb->UrbPipeRequest.PipeHandle); - - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleClearStall invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get endpoint descriptor - // - EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbPipeRequest.PipeHandle; - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - DPRINT1("URB_FUNCTION_SYNC_CLEAR_STALL\n"); - - // - // initialize setup packet - // - CtrlSetup.bmRequestType.B = 0x02; - CtrlSetup.bRequest = USB_REQUEST_CLEAR_FEATURE; - CtrlSetup.wValue.W = USB_FEATURE_ENDPOINT_STALL; - CtrlSetup.wIndex.W = EndpointDescriptor->bEndpointAddress; - CtrlSetup.wLength = 0; - CtrlSetup.wValue.W = 0; - - // - // issue request - // - Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, 0, 0); - - DPRINT1("URB_FUNCTION_CLEAR_STALL Status %x\n", Status); - - // - // done - // - return Status; -} - - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleClassInterface( - IN OUT PIRP Irp, - IN OUT PURB Urb) -{ - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - NTSTATUS Status; - PUSBDEVICE UsbDevice; - - // - // sanity check - // - //ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer || Urb->UrbControlVendorClassRequest.TransferBufferMDL); - //ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength); - PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle); - - // - // check if this is a valid usb device handle - // - if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle))) - { - DPRINT1("HandleClassInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device - // - UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - - DPRINT1("URB_FUNCTION_CLASS_INTERFACE\n"); - DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags); - DPRINT1("TransferBufferLength %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength); - DPRINT1("TransferBuffer %x\n", Urb->UrbControlVendorClassRequest.TransferBuffer); - DPRINT1("TransferBufferMDL %x\n", Urb->UrbControlVendorClassRequest.TransferBufferMDL); - DPRINT1("RequestTypeReservedBits %x\n", Urb->UrbControlVendorClassRequest.RequestTypeReservedBits); - DPRINT1("Request %x\n", Urb->UrbControlVendorClassRequest.Request); - DPRINT1("Value %x\n", Urb->UrbControlVendorClassRequest.Value); - DPRINT1("Index %x\n", Urb->UrbControlVendorClassRequest.Index); - - // - // initialize setup packet - // - CtrlSetup.bmRequestType.B = 0x21; - CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request; - CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value; - CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index; - CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength; - - if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN) - { - // - // data direction is device to host - // - CtrlSetup.bmRequestType.B |= 0x80; - } - - // - // issue request - // - Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer); - - // - // assert on failure - // - if (!NT_SUCCESS(Status)) - { - // - // display error - // - DPRINT1("URB_FUNCTION_CLASS_INTERFACE failed with Urb Status %x\n", Urb->UrbHeader.Status); - } - - // - // done - // - return Status; -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::HandleDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN OUT PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PCOMMON_DEVICE_EXTENSION DeviceExtension; - PURB Urb; - NTSTATUS Status = STATUS_NOT_IMPLEMENTED; - - // - // get current stack location - // - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // - // get device extension - // - DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - // - // determine which request should be performed - // - switch(IoStack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_INTERNAL_USB_SUBMIT_URB: - { - // - // get urb - // - Urb = (PURB)IoStack->Parameters.Others.Argument1; - PC_ASSERT(Urb); - - switch (Urb->UrbHeader.Function) - { - case URB_FUNCTION_SYNC_RESET_PIPE: - case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL: - Status = HandleSyncResetAndClearStall(Irp, Urb); - break; - case URB_FUNCTION_ABORT_PIPE: - Status = HandleAbortPipe(Irp, Urb); - break; - case URB_FUNCTION_SYNC_CLEAR_STALL: - Status = HandleClearStall(Irp, Urb); - break; - case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE: - Status = HandleGetDescriptorFromInterface(Irp, Urb); - break; - case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: - Status = HandleGetDescriptor(Irp, Urb); - break; - case URB_FUNCTION_CLASS_DEVICE: - Status = HandleClassDevice(Irp, Urb); - break; - case URB_FUNCTION_GET_STATUS_FROM_DEVICE: - Status = HandleGetStatusFromDevice(Irp, Urb); - break; - case URB_FUNCTION_SELECT_CONFIGURATION: - Status = HandleSelectConfiguration(Irp, Urb); - break; - case URB_FUNCTION_SELECT_INTERFACE: - Status = HandleSelectInterface(Irp, Urb); - break; - case URB_FUNCTION_CLASS_OTHER: - Status = HandleClassOther(Irp, Urb); - break; - case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: - Status = HandleBulkOrInterruptTransfer(Irp, Urb); - break; - case URB_FUNCTION_ISOCH_TRANSFER: - Status = HandleIsochronousTransfer(Irp, Urb); - break; - case URB_FUNCTION_CLASS_INTERFACE: - Status = HandleClassInterface(Irp, Urb); - break; - case URB_FUNCTION_CLASS_ENDPOINT: - Status = HandleClassEndpoint(Irp, Urb); - break; - default: - DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function); - break; - } - // - // request completed - // - break; - } - case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE: - { - DPRINT("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %p\n", this); - - if (IoStack->Parameters.Others.Argument1) - { - // - // store object as device handle - // - *(PVOID *)IoStack->Parameters.Others.Argument1 = (PVOID)this; - Status = STATUS_SUCCESS; - } - else - { - // - // mis-behaving hub driver - // - Status = STATUS_INVALID_DEVICE_REQUEST; - } - - // - // request completed - // - break; - } - case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO: - { - DPRINT("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n"); - - // - // this is the first request send, it delivers the PDO to the caller - // - if (IoStack->Parameters.Others.Argument1) - { - // - // store root hub pdo object - // - *(PVOID *)IoStack->Parameters.Others.Argument1 = DeviceObject; - } - - if (IoStack->Parameters.Others.Argument2) - { - // - // documentation claims to deliver the hcd controller object, although it is wrong - // - *(PVOID *)IoStack->Parameters.Others.Argument2 = DeviceObject; - } - - // - // request completed - // - Status = STATUS_SUCCESS; - break; - } - case IOCTL_INTERNAL_USB_GET_HUB_COUNT: - { - DPRINT("IOCTL_INTERNAL_USB_GET_HUB_COUNT\n"); - - // - // after IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO is delivered, the usbhub driver - // requests this ioctl to deliver the number of presents. - - if (IoStack->Parameters.Others.Argument1) - { - // - // FIXME / verify: there is only one hub - // - *(PULONG)IoStack->Parameters.Others.Argument1 = 1; - } - - // - // request completed - // - Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof(ULONG); - break; - } - case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: - { - DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION UNIMPLEMENTED\n"); - Status = STATUS_SUCCESS; - break; - } - default: - { - DPRINT1("HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu NOT IMPLEMENTED\n", - IoStack->Parameters.DeviceIoControl.IoControlCode, - IoStack->Parameters.DeviceIoControl.InputBufferLength, - IoStack->Parameters.DeviceIoControl.OutputBufferLength); - break; - } - } - if (Status != STATUS_PENDING) - { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - - return Status; -} - -//----------------------------------------------------------------------------------------- -PUSBHARDWAREDEVICE -CHubController::GetUsbHardware() -{ - return m_Hardware; -} - -//----------------------------------------------------------------------------------------- -ULONG -CHubController::AcquireDeviceAddress() -{ - KIRQL OldLevel; - ULONG DeviceAddress; - - // - // acquire device lock - // - KeAcquireSpinLock(&m_Lock, &OldLevel); - - // - // find address - // - DeviceAddress = RtlFindClearBits(&m_DeviceAddressBitmap, 1, 0); - if (DeviceAddress != MAXULONG) - { - // - // reserve address - // - RtlSetBits(&m_DeviceAddressBitmap, DeviceAddress, 1); - - // - // device addresses start from 0x1 - 0xFF - // - DeviceAddress++; - } - - // - // release spin lock - // - KeReleaseSpinLock(&m_Lock, OldLevel); - - // - // return device address - // - return DeviceAddress; -} -//----------------------------------------------------------------------------------------- -VOID -CHubController::ReleaseDeviceAddress( - ULONG DeviceAddress) -{ - KIRQL OldLevel; - - // - // acquire device lock - // - KeAcquireSpinLock(&m_Lock, &OldLevel); - - // - // sanity check - // - PC_ASSERT(DeviceAddress != 0); - - // - // convert back to bit number - // - DeviceAddress--; - - // - // clear bit - // - RtlClearBits(&m_DeviceAddressBitmap, DeviceAddress, 1); - - // - // release lock - // - KeReleaseSpinLock(&m_Lock, OldLevel); -} -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::RemoveUsbDevice( - PUSBDEVICE UsbDevice) -{ - PUSBDEVICE_ENTRY DeviceEntry; - PLIST_ENTRY Entry; - NTSTATUS Status = STATUS_UNSUCCESSFUL; - KIRQL OldLevel; - - // - // acquire lock - // - KeAcquireSpinLock(&m_Lock, &OldLevel); - - // - // point to first entry - // - Entry = m_UsbDeviceList.Flink; - - // - // find matching entry - // - while(Entry != &m_UsbDeviceList) - { - // - // get entry - // - DeviceEntry = (PUSBDEVICE_ENTRY)CONTAINING_RECORD(Entry, USBDEVICE_ENTRY, Entry); - - // - // is it current entry - // - if (DeviceEntry->Device == UsbDevice) - { - // - // remove entry - // - RemoveEntryList(Entry); - - // - // free entry - // - ExFreePoolWithTag(DeviceEntry, TAG_USBUHCI); - - // - // done - // - Status = STATUS_SUCCESS; - break; - } - - // - // goto next device - // - Entry = Entry->Flink; - } - - // - // release lock - // - KeReleaseSpinLock(&m_Lock, OldLevel); - - // - // return result - // - return Status; -} -//----------------------------------------------------------------------------------------- -BOOLEAN -CHubController::ValidateUsbDevice(PUSBDEVICE UsbDevice) -{ - PUSBDEVICE_ENTRY DeviceEntry; - PLIST_ENTRY Entry; - KIRQL OldLevel; - BOOLEAN Result = FALSE; - - // - // acquire lock - // - KeAcquireSpinLock(&m_Lock, &OldLevel); - - // - // point to first entry - // - Entry = m_UsbDeviceList.Flink; - - // - // find matching entry - // - while(Entry != &m_UsbDeviceList) - { - // - // get entry - // - DeviceEntry = (PUSBDEVICE_ENTRY)CONTAINING_RECORD(Entry, USBDEVICE_ENTRY, Entry); - - // - // is it current entry - // - if (DeviceEntry->Device == UsbDevice) - { - // - // device is valid - // - Result = TRUE; - break; - } - - // - // goto next device - // - Entry = Entry->Flink; - } - - // - // release lock - // - KeReleaseSpinLock(&m_Lock, OldLevel); - - // - // return result - // - return Result; - -} - -//----------------------------------------------------------------------------------------- -NTSTATUS -CHubController::AddUsbDevice( - PUSBDEVICE UsbDevice) -{ - PUSBDEVICE_ENTRY DeviceEntry; - KIRQL OldLevel; - - // - // allocate device entry - // - DeviceEntry = (PUSBDEVICE_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(USBDEVICE_ENTRY), TAG_USBUHCI); - if (!DeviceEntry) - { - // - // no memory - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // initialize entry - // - DeviceEntry->Device = UsbDevice; - - // - // acquire lock - // - KeAcquireSpinLock(&m_Lock, &OldLevel); - - // - // insert entry - // - InsertTailList(&m_UsbDeviceList, &DeviceEntry->Entry); - - // - // release spin lock - // - KeReleaseSpinLock(&m_Lock, OldLevel); - - // - // done - // - return STATUS_SUCCESS; -} - -//----------------------------------------------------------------------------------------- -VOID -CHubController::SetNotification( - PVOID CallbackContext, - PRH_INIT_CALLBACK CallbackRoutine) -{ - KIRQL OldLevel; - - // - // acquire hub controller lock - // - KeAcquireSpinLock(&m_Lock, &OldLevel); - - // - // now set the callback routine and context of the hub - // - m_HubCallbackContext = CallbackContext; - m_HubCallbackRoutine = CallbackRoutine; - - // - // release hub controller lock - // - KeReleaseSpinLock(&m_Lock, OldLevel); -} - -//================================================================================================= -// -// Generic Interface functions -// -VOID -USB_BUSIFFN -USBI_InterfaceReference( - PVOID BusContext) -{ - CHubController * Controller = (CHubController*)BusContext; - - DPRINT("USBH_InterfaceReference\n"); - - // - // add reference - // - Controller->AddRef(); -} - -VOID -USB_BUSIFFN -USBI_InterfaceDereference( - PVOID BusContext) -{ - CHubController * Controller = (CHubController*)BusContext; - - DPRINT("USBH_InterfaceDereference\n"); - - // - // release - // - Controller->Release(); -} -//================================================================================================= -// -// USB Hub Interface functions -// -NTSTATUS -USB_BUSIFFN -USBHI_CreateUsbDevice( - PVOID BusContext, - PUSB_DEVICE_HANDLE *NewDevice, - PUSB_DEVICE_HANDLE HubDeviceHandle, - USHORT PortStatus, - USHORT PortNumber) -{ - PUSBDEVICE NewUsbDevice; - CHubController * Controller; - NTSTATUS Status; - - DPRINT("USBHI_CreateUsbDevice PortStatus %x\n", PortStatus); - - // - // first get hub controller - // - Controller = (CHubController *)BusContext; - - // - // sanity check - // - PC_ASSERT(Controller); - PC_ASSERT(BusContext == HubDeviceHandle); - - // - // now allocate usb device - // - Status = CreateUSBDevice(&NewUsbDevice); - - // - // check for success - // - if (!NT_SUCCESS(Status)) - { - // - // release controller - // - Controller->Release(); - DPRINT1("USBHI_CreateUsbDevice: failed to create usb device %x\n", Status); - return Status; - } - - // - // now initialize device - // - Status = NewUsbDevice->Initialize(PHUBCONTROLLER(Controller), Controller->GetUsbHardware(),PVOID(Controller), PortNumber, PortStatus); - - // - // check for success - // - if (!NT_SUCCESS(Status)) - { - // - // release usb device - // - NewUsbDevice->Release(); - DPRINT1("USBHI_CreateUsbDevice: failed to initialize usb device %x\n", Status); - return Status; - } - - // - // insert into list - // - Status = Controller->AddUsbDevice(NewUsbDevice); - // - // check for success - // - if (!NT_SUCCESS(Status)) - { - // - // release usb device - // - NewUsbDevice->Release(); - - DPRINT1("USBHI_CreateUsbDevice: failed to add usb device %x\n", Status); - return Status; - } - - // - // store the handle - // - *NewDevice = NewUsbDevice; - - // - // done - // - return STATUS_SUCCESS; -} - -NTSTATUS -USB_BUSIFFN -USBHI_InitializeUsbDevice( - PVOID BusContext, - PUSB_DEVICE_HANDLE DeviceHandle) -{ - PUSBDEVICE UsbDevice; - CHubController * Controller; - ULONG DeviceAddress; - NTSTATUS Status; - ULONG Index = 0; - - DPRINT("USBHI_InitializeUsbDevice\n"); - - // - // first get controller - // - Controller = (CHubController *)BusContext; - PC_ASSERT(Controller); - - // - // get device object - // - UsbDevice = (PUSBDEVICE)DeviceHandle; - PC_ASSERT(UsbDevice); - - // - // validate device handle - // - if (!Controller->ValidateUsbDevice(UsbDevice)) - { - DPRINT1("USBHI_InitializeUsbDevice invalid device handle %p\n", DeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // now reserve an address - // - DeviceAddress = Controller->AcquireDeviceAddress(); - - // - // is the device address valid - // - if (DeviceAddress == MAXULONG) - { - // - // failed to get an device address from the device address pool - // - DPRINT1("USBHI_InitializeUsbDevice failed to get device address\n"); - return STATUS_DEVICE_DATA_ERROR; - } - - do - { - // - // now set the device address - // - Status = UsbDevice->SetDeviceAddress((UCHAR)DeviceAddress); - - if (NT_SUCCESS(Status)) - break; - - }while(Index++ < 3 ); - - // - // check for failure - // - if (!NT_SUCCESS(Status)) - { - // - // failed to set device address - // - DPRINT1("USBHI_InitializeUsbDevice failed to set address with %x\n", Status); - - // - // release address - // - Controller->ReleaseDeviceAddress(DeviceAddress); - - // - // return error - // - return STATUS_DEVICE_DATA_ERROR; - } - - // - // done - // - return STATUS_SUCCESS; -} - -NTSTATUS -USB_BUSIFFN -USBHI_GetUsbDescriptors( - PVOID BusContext, - PUSB_DEVICE_HANDLE DeviceHandle, - PUCHAR DeviceDescriptorBuffer, - PULONG DeviceDescriptorBufferLength, - PUCHAR ConfigDescriptorBuffer, - PULONG ConfigDescriptorBufferLength) -{ - PUSBDEVICE UsbDevice; - CHubController * Controller; - - DPRINT("USBHI_GetUsbDescriptors\n"); - - // - // sanity check - // - PC_ASSERT(DeviceDescriptorBuffer); - PC_ASSERT(DeviceDescriptorBufferLength); - PC_ASSERT(*DeviceDescriptorBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR)); - PC_ASSERT(ConfigDescriptorBufferLength); - PC_ASSERT(*ConfigDescriptorBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR)); - - // - // first get controller - // - Controller = (CHubController *)BusContext; - PC_ASSERT(Controller); - - - // - // get device object - // - UsbDevice = (PUSBDEVICE)DeviceHandle; - PC_ASSERT(UsbDevice); - - // - // validate device handle - // - if (!Controller->ValidateUsbDevice(UsbDevice)) - { - DPRINT1("USBHI_GetUsbDescriptors invalid device handle %p\n", DeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // get device descriptor - // - UsbDevice->GetDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)DeviceDescriptorBuffer); - - // - // store result length - // - *DeviceDescriptorBufferLength = sizeof(USB_DEVICE_DESCRIPTOR); - - // - // get configuration descriptor - // - UsbDevice->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer, *ConfigDescriptorBufferLength, ConfigDescriptorBufferLength); - - // - // complete the request - // - return STATUS_SUCCESS; -} - -NTSTATUS -USB_BUSIFFN -USBHI_RemoveUsbDevice( - PVOID BusContext, - PUSB_DEVICE_HANDLE DeviceHandle, - ULONG Flags) -{ - PUSBDEVICE UsbDevice; - CHubController * Controller; - NTSTATUS Status; - - DPRINT("USBHI_RemoveUsbDevice\n"); - - // - // first get controller - // - Controller = (CHubController *)BusContext; - PC_ASSERT(Controller); - - // - // get device object - // - UsbDevice = (PUSBDEVICE)DeviceHandle; - PC_ASSERT(UsbDevice); - - // - // validate device handle - // - if (!Controller->ValidateUsbDevice(UsbDevice)) - { - DPRINT1("USBHI_RemoveUsbDevice invalid device handle %p\n", DeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // check if there were flags passed - // - if (Flags & USBD_KEEP_DEVICE_DATA || Flags & USBD_MARK_DEVICE_BUSY) - { - // - // ignore flags for now - // - return STATUS_SUCCESS; - } - - // - // remove device - // - Status = Controller->RemoveUsbDevice(UsbDevice); - if (!NT_SUCCESS(Status)) - { - // - // invalid device handle - // - DPRINT1("USBHI_RemoveUsbDevice Invalid device handle %p\n", UsbDevice); - PC_ASSERT(0); - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // release usb device - // - UsbDevice->Release(); - - // - // done - // - return STATUS_SUCCESS; -} - -NTSTATUS -USB_BUSIFFN -USBHI_RestoreUsbDevice( - PVOID BusContext, - PUSB_DEVICE_HANDLE OldDeviceHandle, - PUSB_DEVICE_HANDLE NewDeviceHandle) -{ - PUSBDEVICE OldUsbDevice, NewUsbDevice; - CHubController * Controller; - - DPRINT("USBHI_RestoreUsbDevice\n"); - - // - // first get controller - // - Controller = (CHubController *)BusContext; - PC_ASSERT(Controller); - - // - // get device object - // - OldUsbDevice = (PUSBDEVICE)OldDeviceHandle; - NewUsbDevice = (PUSBDEVICE)NewDeviceHandle; - PC_ASSERT(OldUsbDevice); - PC_ASSERT(NewDeviceHandle); - - // - // validate device handle - // - PC_ASSERT(Controller->ValidateUsbDevice(NewUsbDevice)); - PC_ASSERT(Controller->ValidateUsbDevice(OldUsbDevice)); - - DPRINT("NewUsbDevice: DeviceAddress %x\n", NewUsbDevice->GetDeviceAddress()); - DPRINT("OldUsbDevice: DeviceAddress %x\n", OldUsbDevice->GetDeviceAddress()); - - // - // remove old device handle - // - USBHI_RemoveUsbDevice(BusContext, OldDeviceHandle, 0); - - return STATUS_SUCCESS; -} - -NTSTATUS -USB_BUSIFFN -USBHI_QueryDeviceInformation( - PVOID BusContext, - PUSB_DEVICE_HANDLE DeviceHandle, - PVOID DeviceInformationBuffer, - ULONG DeviceInformationBufferLength, - PULONG LengthReturned) -{ - PUSB_DEVICE_INFORMATION_0 DeviceInfo; - PUSBDEVICE UsbDevice; - CHubController * Controller; - - DPRINT("USBHI_QueryDeviceInformation %p\n", BusContext); - - // - // sanity check - // - PC_ASSERT(DeviceInformationBufferLength >= sizeof(USB_DEVICE_INFORMATION_0)); - PC_ASSERT(DeviceInformationBuffer); - PC_ASSERT(LengthReturned); - - // - // get controller object - // - Controller = (CHubController*)BusContext; - PC_ASSERT(Controller); - - // - // get device object - // - UsbDevice = (PUSBDEVICE)DeviceHandle; - PC_ASSERT(UsbDevice); - - if (BusContext != DeviceHandle) - { - // - // validate device handle - // - if (!Controller->ValidateUsbDevice(UsbDevice)) - { - DPRINT1("USBHI_QueryDeviceInformation invalid device handle %p\n", DeviceHandle); - - // - // invalid device handle - // - return STATUS_DEVICE_NOT_CONNECTED; - } - - // - // access information buffer - // - DeviceInfo = (PUSB_DEVICE_INFORMATION_0)DeviceInformationBuffer; - - // - // initialize with default values - // - DeviceInfo->InformationLevel = 0; - DeviceInfo->ActualLength = sizeof(USB_DEVICE_INFORMATION_0); - DeviceInfo->PortNumber = UsbDevice->GetPort(); - DeviceInfo->CurrentConfigurationValue = UsbDevice->GetConfigurationValue(); - DeviceInfo->DeviceAddress = UsbDevice->GetDeviceAddress(); - DeviceInfo->HubAddress = 0; //FIXME - DeviceInfo->DeviceSpeed = UsbDevice->GetSpeed(); - DeviceInfo->DeviceType = UsbDevice->GetType(); - DeviceInfo->NumberOfOpenPipes = 0; //FIXME - - // - // get device descriptor - // - UsbDevice->GetDeviceDescriptor(&DeviceInfo->DeviceDescriptor); - - // - // FIXME return pipe information - // - - // - // store result length - // - *LengthReturned = sizeof(USB_DEVICE_INFORMATION_0); - - return STATUS_SUCCESS; - } - - // - // access information buffer - // - DeviceInfo = (PUSB_DEVICE_INFORMATION_0)DeviceInformationBuffer; - - // - // initialize with default values - // - DeviceInfo->InformationLevel = 0; - DeviceInfo->ActualLength = sizeof(USB_DEVICE_INFORMATION_0); - DeviceInfo->PortNumber = 0; - DeviceInfo->CurrentConfigurationValue = 0; //FIXME; - DeviceInfo->DeviceAddress = 0; - DeviceInfo->HubAddress = 0; //FIXME - DeviceInfo->DeviceSpeed = UsbFullSpeed; //FIXME - DeviceInfo->DeviceType = Usb11Device; //FIXME - DeviceInfo->NumberOfOpenPipes = 0; //FIXME - - // - // get device descriptor - // - RtlMoveMemory(&DeviceInfo->DeviceDescriptor, ROOTHUB2_DEVICE_DESCRIPTOR, sizeof(USB_DEVICE_DESCRIPTOR)); - - // - // FIXME return pipe information - // - - // - // store result length - // -#ifdef _MSC_VER - *LengthReturned = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[DeviceInfo->NumberOfOpenPipes]); -#else - *LengthReturned = sizeof(USB_DEVICE_INFORMATION_0) + (DeviceInfo->NumberOfOpenPipes > 1 ? (DeviceInfo->NumberOfOpenPipes - 1) * sizeof(USB_PIPE_INFORMATION_0) : 0); -#endif - // - // done - // - return STATUS_SUCCESS; -} - -NTSTATUS -USB_BUSIFFN -USBHI_GetControllerInformation( - PVOID BusContext, - PVOID ControllerInformationBuffer, - ULONG ControllerInformationBufferLength, - PULONG LengthReturned) -{ - PUSB_CONTROLLER_INFORMATION_0 ControllerInfo; - - DPRINT("USBHI_GetControllerInformation\n"); - - // - // sanity checks - // - PC_ASSERT(ControllerInformationBuffer); - PC_ASSERT(ControllerInformationBufferLength >= sizeof(USB_CONTROLLER_INFORMATION_0)); - - // - // get controller info buffer - // - ControllerInfo = (PUSB_CONTROLLER_INFORMATION_0)ControllerInformationBuffer; - - // - // FIXME only version 0 is supported for now - // - PC_ASSERT(ControllerInfo->InformationLevel == 0); - - // - // fill in information - // - ControllerInfo->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0); - ControllerInfo->SelectiveSuspendEnabled = FALSE; //FIXME - ControllerInfo->IsHighSpeedController = FALSE; - - // - // set length returned - // - *LengthReturned = ControllerInfo->ActualLength; - - // - // done - // - return STATUS_SUCCESS; -} - -NTSTATUS -USB_BUSIFFN -USBHI_ControllerSelectiveSuspend( - PVOID BusContext, - BOOLEAN Enable) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -USB_BUSIFFN -USBHI_GetExtendedHubInformation( - PVOID BusContext, - PDEVICE_OBJECT HubPhysicalDeviceObject, - PVOID HubInformationBuffer, - ULONG HubInformationBufferLength, - PULONG LengthReturned) -{ - PUSB_EXTHUB_INFORMATION_0 HubInfo; - CHubController * Controller; - PUSBHARDWAREDEVICE Hardware; - ULONG Index; - ULONG NumPort, Dummy2; - USHORT Dummy1; - NTSTATUS Status; - - DPRINT("USBHI_GetExtendedHubInformation\n"); - - // - // sanity checks - // - PC_ASSERT(HubInformationBuffer); - PC_ASSERT(HubInformationBufferLength == sizeof(USB_EXTHUB_INFORMATION_0)); - PC_ASSERT(LengthReturned); - - // - // get hub controller - // - Controller = (CHubController *)BusContext; - PC_ASSERT(Controller); - - // - // get usb hardware device - // - Hardware = Controller->GetUsbHardware(); - - // - // retrieve number of ports - // - Status = Hardware->GetDeviceDetails(&Dummy1, &Dummy1, &NumPort, &Dummy2); - if (!NT_SUCCESS(Status)) - { - // - // failed to get hardware details, ouch ;) - // - DPRINT1("USBHI_GetExtendedHubInformation failed to get hardware details with %x\n", Status); - return Status; - } - - // - // get hub information buffer - // - HubInfo = (PUSB_EXTHUB_INFORMATION_0)HubInformationBuffer; - - // - // initialize hub information - // - HubInfo->InformationLevel = 0; - - // - // store port count - // - HubInfo->NumberOfPorts = NumPort; - - // - // initialize port information - // - for(Index = 0; Index < NumPort; Index++) - { - HubInfo->Port[Index].PhysicalPortNumber = Index + 1; - HubInfo->Port[Index].PortLabelNumber = Index + 1; - HubInfo->Port[Index].VidOverride = 0; - HubInfo->Port[Index].PidOverride = 0; - HubInfo->Port[Index].PortAttributes = 0; //FIXME - } - - // - // store result length - // -#ifdef _MSC_VER - *LengthReturned = FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[HubInfo->NumberOfPorts]); -#else - *LengthReturned = FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port) + sizeof(USB_EXTPORT_INFORMATION_0) * HubInfo->NumberOfPorts; -#endif - - // - // done - // - return STATUS_SUCCESS; -} - -NTSTATUS -USB_BUSIFFN -USBHI_GetRootHubSymbolicName( - PVOID BusContext, - PVOID HubSymNameBuffer, - ULONG HubSymNameBufferLength, - PULONG HubSymNameActualLength) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -PVOID -USB_BUSIFFN -USBHI_GetDeviceBusContext( - PVOID HubBusContext, - PVOID DeviceHandle) -{ - UNIMPLEMENTED - return NULL; -} - -NTSTATUS -USB_BUSIFFN -USBHI_RootHubInitNotification( - PVOID BusContext, - PVOID CallbackContext, - PRH_INIT_CALLBACK CallbackRoutine) -{ - CHubController * Controller; - - DPRINT("USBHI_RootHubInitNotification %p \n", CallbackContext); - - // - // get controller object - // - Controller = (CHubController*)BusContext; - PC_ASSERT(Controller); - - // - // set notification routine - // - Controller->SetNotification(CallbackContext, CallbackRoutine); - - // - // FIXME: determine when to perform callback - // - CallbackRoutine(CallbackContext); - - // - // done - // - return STATUS_SUCCESS; -} - -VOID -USB_BUSIFFN -USBHI_FlushTransfers( - PVOID BusContext, - PVOID DeviceHandle) -{ - UNIMPLEMENTED -} - -VOID -USB_BUSIFFN -USBHI_SetDeviceHandleData( - PVOID BusContext, - PVOID DeviceHandle, - PDEVICE_OBJECT UsbDevicePdo) -{ - PUSBDEVICE UsbDevice; - CHubController * Controller; - - // - // get controller - // - Controller = (CHubController *)BusContext; - PC_ASSERT(Controller); - - // - // get device handle - // - UsbDevice = (PUSBDEVICE)DeviceHandle; - - // - // validate device handle - // - if (!Controller->ValidateUsbDevice(UsbDevice)) - { - DPRINT1("USBHI_SetDeviceHandleData DeviceHandle %p is invalid\n", DeviceHandle); - - // - // invalid handle - // - return; - } - else - { - // - // usbhub sends this request as a part of the Pnp startup sequence - // looks like we need apply a dragon voodoo to fixup the device stack - // otherwise usbhub will cause a bugcheck - // - DPRINT("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo); - - // - // sanity check - // - PC_ASSERT(UsbDevicePdo->AttachedDevice); - - // - // should be usbstor - // fixup device stack voodoo part #2 - // - UsbDevicePdo->AttachedDevice->StackSize++; - - // - // set device handle data - // - UsbDevice->SetDeviceHandleData(UsbDevicePdo); - } -} - -//================================================================================================= -// -// USB Device Interface functions -// - -VOID -USB_BUSIFFN -USBDI_GetUSBDIVersion( - PVOID BusContext, - PUSBD_VERSION_INFORMATION VersionInformation, - PULONG HcdCapabilites) -{ - CHubController * Controller; - PUSBHARDWAREDEVICE Device; - ULONG Speed, Dummy2; - USHORT Dummy1; - - DPRINT("USBDI_GetUSBDIVersion\n"); - - // - // get controller - // - Controller = (CHubController*)BusContext; - - // - // get usb hardware - // - Device = Controller->GetUsbHardware(); - PC_ASSERT(Device); - - if (VersionInformation) - { - // - // windows xp supported - // - VersionInformation->USBDI_Version = 0x00000500; - - // - // get device speed - // - Device->GetDeviceDetails(&Dummy1, &Dummy1, &Dummy2, &Speed); - - // - // store speed details - // - VersionInformation->Supported_USB_Version = Speed; - } - - // - // no flags supported - // - *HcdCapabilites = 0; -} - -NTSTATUS -USB_BUSIFFN -USBDI_QueryBusTime( - PVOID BusContext, - PULONG CurrentFrame) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -USB_BUSIFFN -USBDI_SubmitIsoOutUrb( - PVOID BusContext, - PURB Urb) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -USB_BUSIFFN -USBDI_QueryBusInformation( - PVOID BusContext, - ULONG Level, - PVOID BusInformationBuffer, - PULONG BusInformationBufferLength, - PULONG BusInformationActualLength) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -BOOLEAN -USB_BUSIFFN -USBDI_IsDeviceHighSpeed( - PVOID BusContext) -{ - CHubController * Controller; - PUSBHARDWAREDEVICE Device; - ULONG Speed, Dummy2; - USHORT Dummy1; - - DPRINT("USBDI_IsDeviceHighSpeed\n"); - - // - // get controller - // - Controller = (CHubController*)BusContext; - - // - // get usb hardware - // - Device = Controller->GetUsbHardware(); - PC_ASSERT(Device); - - // - // get device speed - // - Device->GetDeviceDetails(&Dummy1, &Dummy1, &Dummy2, &Speed); - - // - // USB 2.0 equals 0x200 - // - return (Speed == 0x200); -} - -NTSTATUS -USB_BUSIFFN -USBDI_EnumLogEntry( - PVOID BusContext, - ULONG DriverTag, - ULONG EnumTag, - ULONG P1, - ULONG P2) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -CHubController::HandleQueryInterface( - PIO_STACK_LOCATION IoStack) -{ - PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub; - PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI; - UNICODE_STRING GuidBuffer; - NTSTATUS Status; - - if (IsEqualGUIDAligned(*IoStack->Parameters.QueryInterface.InterfaceType, USB_BUS_INTERFACE_HUB_GUID)) - { - // - // get request parameters - // - InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)IoStack->Parameters.QueryInterface.Interface; - InterfaceHub->Version = IoStack->Parameters.QueryInterface.Version; - - // - // check version - // - if (IoStack->Parameters.QueryInterface.Version >= 6) - { - DPRINT1("USB_BUS_INTERFACE_HUB_GUID version %x not supported!\n", IoStack->Parameters.QueryInterface.Version); - - // - // version not supported - // - return STATUS_NOT_SUPPORTED; - } - - // - // Interface version 0 - // - if (IoStack->Parameters.QueryInterface.Version >= 0) - { - InterfaceHub->Size = IoStack->Parameters.QueryInterface.Size; - InterfaceHub->BusContext = PVOID(this); - InterfaceHub->InterfaceReference = USBI_InterfaceReference; - InterfaceHub->InterfaceDereference = USBI_InterfaceDereference; - } - - // - // Interface version 1 - // - if (IoStack->Parameters.QueryInterface.Version >= 1) - { - InterfaceHub->CreateUsbDevice = USBHI_CreateUsbDevice; - InterfaceHub->InitializeUsbDevice = USBHI_InitializeUsbDevice; - InterfaceHub->GetUsbDescriptors = USBHI_GetUsbDescriptors; - InterfaceHub->RemoveUsbDevice = USBHI_RemoveUsbDevice; - InterfaceHub->RestoreUsbDevice = USBHI_RestoreUsbDevice; - InterfaceHub->QueryDeviceInformation = USBHI_QueryDeviceInformation; - } - - // - // Interface version 2 - // - if (IoStack->Parameters.QueryInterface.Version >= 2) - { - InterfaceHub->GetControllerInformation = USBHI_GetControllerInformation; - InterfaceHub->ControllerSelectiveSuspend = USBHI_ControllerSelectiveSuspend; - InterfaceHub->GetExtendedHubInformation = USBHI_GetExtendedHubInformation; - InterfaceHub->GetRootHubSymbolicName = USBHI_GetRootHubSymbolicName; - InterfaceHub->GetDeviceBusContext = USBHI_GetDeviceBusContext; - } - - // - // Interface version 3 - // - if (IoStack->Parameters.QueryInterface.Version >= 3) - { - InterfaceHub->RootHubInitNotification = USBHI_RootHubInitNotification; - } - - // - // Interface version 4 - // - if (IoStack->Parameters.QueryInterface.Version >= 4) - { - InterfaceHub->FlushTransfers = USBHI_FlushTransfers; - } - - // - // Interface version 5 - // - if (IoStack->Parameters.QueryInterface.Version >= 5) - { - InterfaceHub->SetDeviceHandleData = USBHI_SetDeviceHandleData; - } - - // - // request completed - // - return STATUS_SUCCESS; - } - else if (IsEqualGUIDAligned(*IoStack->Parameters.QueryInterface.InterfaceType, USB_BUS_INTERFACE_USBDI_GUID)) - { - // - // get request parameters - // - InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) IoStack->Parameters.QueryInterface.Interface; - InterfaceDI->Version = IoStack->Parameters.QueryInterface.Version; - - // - // check version - // - if (IoStack->Parameters.QueryInterface.Version >= 3) - { - DPRINT1("USB_BUS_INTERFACE_USBDI_GUID version %x not supported!\n", IoStack->Parameters.QueryInterface.Version); - - // - // version not supported - // - return STATUS_NOT_SUPPORTED; - } - - // - // interface version 0 - // - if (IoStack->Parameters.QueryInterface.Version >= 0) - { - InterfaceDI->Size = IoStack->Parameters.QueryInterface.Size; - InterfaceDI->BusContext = PVOID(this); - InterfaceDI->InterfaceReference = USBI_InterfaceReference; - InterfaceDI->InterfaceDereference = USBI_InterfaceDereference; - InterfaceDI->GetUSBDIVersion = USBDI_GetUSBDIVersion; - InterfaceDI->QueryBusTime = USBDI_QueryBusTime; - InterfaceDI->SubmitIsoOutUrb = USBDI_SubmitIsoOutUrb; - InterfaceDI->QueryBusInformation = USBDI_QueryBusInformation; - } - - // - // interface version 1 - // - if (IoStack->Parameters.QueryInterface.Version >= 1) - { - InterfaceDI->IsDeviceHighSpeed = USBDI_IsDeviceHighSpeed; - } - - // - // interface version 2 - // - if (IoStack->Parameters.QueryInterface.Version >= 2) - { - InterfaceDI->EnumLogEntry = USBDI_EnumLogEntry; - } - - // - // request completed - // - return STATUS_SUCCESS; - } - else - { - // - // convert guid to string - // - Status = RtlStringFromGUID(*IoStack->Parameters.QueryInterface.InterfaceType, &GuidBuffer); - if (NT_SUCCESS(Status)) - { - // - // print interface - // - DPRINT1("HandleQueryInterface UNKNOWN INTERFACE GUID: %wZ Version %x\n", &GuidBuffer, IoStack->Parameters.QueryInterface.Version); - - // - // free guid buffer - // - RtlFreeUnicodeString(&GuidBuffer); - } - } - return STATUS_NOT_SUPPORTED; -} - -NTSTATUS -CHubController::SetDeviceInterface( - BOOLEAN Enable) -{ - NTSTATUS Status = STATUS_SUCCESS; - - if (Enable) - { - // - // register device interface - // - Status = IoRegisterDeviceInterface(m_HubControllerDeviceObject, &GUID_DEVINTERFACE_USB_HUB, 0, &m_HubDeviceInterfaceString); - - if (NT_SUCCESS(Status)) - { - // - // now enable the device interface - // - Status = IoSetDeviceInterfaceState(&m_HubDeviceInterfaceString, TRUE); - - // - // enable interface - // - m_InterfaceEnabled = TRUE; - } - } - else if (m_InterfaceEnabled) - { - // - // disable device interface - // - Status = IoSetDeviceInterfaceState(&m_HubDeviceInterfaceString, FALSE); - - if (NT_SUCCESS(Status)) - { - // - // now delete interface string - // - RtlFreeUnicodeString(&m_HubDeviceInterfaceString); - } - - // - // disable interface - // - m_InterfaceEnabled = FALSE; - } - - // - // done - // - return STATUS_SUCCESS; -} - -NTSTATUS -CHubController::CreatePDO( - PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT * OutDeviceObject) -{ - WCHAR CharDeviceName[64]; - NTSTATUS Status; - ULONG UsbDeviceNumber = 0; - UNICODE_STRING DeviceName; - - while (TRUE) - { - // - // construct device name - // - swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber); - - // - // initialize device name - // - RtlInitUnicodeString(&DeviceName, CharDeviceName); - - // - // create device - // - Status = IoCreateDevice(DriverObject, - sizeof(COMMON_DEVICE_EXTENSION), - &DeviceName, - FILE_DEVICE_CONTROLLER, - 0, - FALSE, - OutDeviceObject); - - /* check for success */ - if (NT_SUCCESS(Status)) - break; - - // - // is there a device object with that same name - // - if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION)) - { - // - // Try the next name - // - UsbDeviceNumber++; - continue; - } - - // - // bail out on other errors - // - if (!NT_SUCCESS(Status)) - { - DPRINT1("CreatePDO: Failed to create %wZ, Status %x\n", &DeviceName, Status); - return Status; - } - } - - DPRINT("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName); - - // - // fixup device stack voodoo part #1 - // - (*OutDeviceObject)->StackSize++; - - /* done */ - return Status; -} - - - -NTSTATUS -CreateHubController( - PHUBCONTROLLER *OutHcdController) -{ - PHUBCONTROLLER This; - - // - // allocate controller - // - This = new(NonPagedPool, TAG_USBUHCI) CHubController(0); - if (!This) - { - // - // failed to allocate - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // add reference count - // - This->AddRef(); - - // - // return result - // - *OutHcdController = (PHUBCONTROLLER)This; - - // - // done - // - return STATUS_SUCCESS; -} - -VOID StatusChangeEndpointCallBack(PVOID Context) -{ - CHubController* This; - PIRP Irp; - This = (CHubController*)Context; - - ASSERT(This); - - Irp = This->m_PendingSCEIrp; - if (!Irp) - { - DPRINT("There was no pending IRP for SCE. Did the usb hub 2.0 driver (usbhub2) load?\n"); - return; - } - - This->m_PendingSCEIrp = NULL; - This->QueryStatusChageEndpoint(Irp); - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); -} diff --git a/reactos/drivers/usb/usbuhci/interfaces.h b/reactos/drivers/usb/usbuhci/interfaces.h index 609b8d3fc90..55781a10bcf 100644 --- a/reactos/drivers/usb/usbuhci/interfaces.h +++ b/reactos/drivers/usb/usbuhci/interfaces.h @@ -2,6 +2,8 @@ #ifndef INTERFACES_HPP #define INTERFACES_HPP +#include "libusb.h" + //--------------------------------------------------------------------------- // // Object Hierachy @@ -30,85 +32,10 @@ // -//========================================================================================= -// -// class IRootHCDController -// -// Description: This class serves as the root host controller. The host controller mantains -// a list of registered controllers and provides support functions for the host controllers - -struct IHCDController; -struct _USB_ENDPOINT; - -DECLARE_INTERFACE_(IRootHCDController, IUnknown) -{ - DEFINE_ABSTRACT_UNKNOWN() - -//----------------------------------------------------------------------------------------- -// -// Initialize -// -// Description: This function initializes the root host controller. It allocates the resources -// required to manage the registered controllers - - virtual NTSTATUS Initialize() = 0; - -//----------------------------------------------------------------------------------------- -// -// RegisterHCD -// -// Description: this function registers a host controller with the root host controller - - virtual NTSTATUS RegisterHCD(struct IHCDController * Controller) = 0; - -//----------------------------------------------------------------------------------------- -// -// UnregisterHCD -// -// Description: this function unregistes a host controller - - virtual NTSTATUS UnregisterHCD(struct IHCDController * Controller) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetControllerCount -// -// Description: returns the number of host controllers registered - - virtual ULONG GetControllerCount() = 0; - -}; - -typedef IRootHCDController *PROOTHDCCONTROLLER; - -//========================================================================================= -// -// class IHCDController -// -// Description: This class is used to manage a single USB host controller -// - -DECLARE_INTERFACE_(IHCDController, IUnknown) -{ - DEFINE_ABSTRACT_UNKNOWN() - -//----------------------------------------------------------------------------------------- -// -// Initialize -// -// Description: This function initializes the IHCDController implementation. -// It creates an IUSBHardwareDevice object and initializes it. It also registeres itself with -// the IRootHCDController -// - virtual NTSTATUS Initialize(IN PROOTHDCCONTROLLER RootHCDController, - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT PhysicalDeviceObject) = 0; - -}; - -typedef IHCDController *PHCDCONTROLLER; - struct _UHCI_QUEUE_HEAD; +struct IDMAMemoryManager; +struct IUSBQueue; + //========================================================================================= // // class IUSBHardwareDevice @@ -116,221 +43,24 @@ struct _UHCI_QUEUE_HEAD; // Description: This class provides access to the usb hardware controller // -struct IDMAMemoryManager; -struct IUSBQueue; +#define DEFINE_ABSTRACT_USBUHCIHARDWAREDEVICE() \ + STDMETHOD_(VOID, GetQueueHead)( THIS_ \ + IN ULONG QueueHeadIndex, \ + IN struct _UHCI_QUEUE_HEAD **OutQueueHead) PURE; -DECLARE_INTERFACE_(IUSBHardwareDevice, IUnknown) +#define IMP_IUHCIHARDWAREDEVICE \ + STDMETHODIMP_(VOID) GetQueueHead( \ + IN ULONG QueueHeadIndex, \ + IN struct _UHCI_QUEUE_HEAD **OutQueueHead); + +DECLARE_INTERFACE_(IUHCIHardwareDevice, IUSBHardwareDevice) { DEFINE_ABSTRACT_UNKNOWN() - -//----------------------------------------------------------------------------------------- -// -// Initialize -// -// Description: Initializes the usb device controller - - virtual NTSTATUS Initialize(PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT FunctionalDeviceObject, - PDEVICE_OBJECT PhysicalDeviceObject, - PDEVICE_OBJECT LowerDeviceObject) = 0; - -//----------------------------------------------------------------------------------------- -// -// PnpStart -// -// Description: handles pnp start request from device. It registeres the interrupt, -// sets up the ports and prepares the device. It then starts the controller - - virtual NTSTATUS PnpStart(PCM_RESOURCE_LIST RawResources, - PCM_RESOURCE_LIST TranslatedResources) = 0; - -//----------------------------------------------------------------------------------------- -// -// PnpStop -// -// Description: handles pnp stop request from device. It unregisteres the interrupt, releases ports and dma object. - - virtual NTSTATUS PnpStop(void) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetDeviceDetails -// -// Description: returns the device details such as vendor id, device id, number of ports and speed - - virtual NTSTATUS GetDeviceDetails(OUT OPTIONAL PUSHORT VendorId, - OUT OPTIONAL PUSHORT DeviceId, - OUT OPTIONAL PULONG NumberOfPorts, - OUT OPTIONAL PULONG Speed) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetUSBQueue -// -// Description: returns interface to internal IUSBQueue -// Interface is reference counted, you need to call release method when you are done with it -// Do not call Initialize on IUSBQueue, the object is already initialized - - virtual NTSTATUS GetUSBQueue(OUT struct IUSBQueue **OutUsbQueue) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetDMA -// -// Description: returns the DMA object which can be used to allocate memory from the common buffer - - virtual NTSTATUS GetDMA(OUT struct IDMAMemoryManager **OutDMAMemoryManager) = 0; - - -//----------------------------------------------------------------------------------------- -// -// ResetController() -// -// Description: this function resets the controller -// Returns STATUS_SUCCESS when the controller was successfully reset - - virtual NTSTATUS ResetController() = 0; - -//----------------------------------------------------------------------------------------- -// -// StartController -// -// Description: this functions starts controller allowing interrupts for device connects/removal, and execution of -// Periodic and Asynchronous Schedules. -// - - virtual NTSTATUS StartController() = 0; - -//----------------------------------------------------------------------------------------- -// -// StopController -// -// Description: this functions stops controller disabling interrupts for device connects/removal, and execution of -// Periodic and Asynchronous Schedules. -// - - virtual NTSTATUS StopController() = 0; - -//----------------------------------------------------------------------------------------- -// -// ResetPort -// -// Description: this functions resets the port on the controller -// - - virtual NTSTATUS ResetPort(ULONG PortNumber) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetPortStatus -// -// Description: this functions return status and change state of port -// - virtual NTSTATUS GetPortStatus(ULONG PortId, OUT USHORT *PortStatus, OUT USHORT *PortChange) = 0; - -//----------------------------------------------------------------------------------------- -// -// ClearPortStatus -// -// Description: Clears Status of Port, for example Connection, Enable and Reset -// - virtual NTSTATUS ClearPortStatus(ULONG PortId, ULONG Status) = 0; - -//----------------------------------------------------------------------------------------- -// -// SetPortFeature -// -// Description: this functions Sets Feature on Port, for example Enable, Power and Reset -// - virtual NTSTATUS SetPortFeature(ULONG PortId, ULONG Feature) = 0; - -//----------------------------------------------------------------------------------------- -// -// SetStatusChangeEndpointCallBack -// -// Description: Used to callback to the hub controller when SCE detected -// - virtual VOID SetStatusChangeEndpointCallBack(PVOID CallBack,PVOID Context) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetQueueHead -// -// Description: gets a queue head with the specified queue head index -// - virtual VOID GetQueueHead(ULONG QueueHeadIndex, struct _UHCI_QUEUE_HEAD **OutQueueHead) = 0; - - -//----------------------------------------------------------------------------------------- -// -// AcquireDeviceLock -// -// Description: acquires the device lock - - virtual KIRQL AcquireDeviceLock(void) = 0; - -//----------------------------------------------------------------------------------------- -// -// ReleaseLock -// -// Description: releases the device lock - - virtual void ReleaseDeviceLock(KIRQL OldLevel) = 0; - + DEFINE_ABSTRACT_USBHARDWAREDEVICE() + DEFINE_ABSTRACT_USBUHCIHARDWAREDEVICE() }; -typedef IUSBHardwareDevice *PUSBHARDWAREDEVICE; - - -//========================================================================================= -// -// class IDMAMemoryManager -// -// Description: This class provides access to the dma buffer. It provides methods to -// allocate and free from the dma buffer -// - -DECLARE_INTERFACE_(IDMAMemoryManager, IUnknown) -{ - DEFINE_ABSTRACT_UNKNOWN() - -//----------------------------------------------------------------------------------------- -// -// Initialize -// -// Description: initializes the memory manager - - virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Device, - IN PKSPIN_LOCK Lock, - IN ULONG DmaBufferSize, - IN PVOID VirtualBase, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG DefaultBlockSize) = 0; - -//----------------------------------------------------------------------------------------- -// -// Allocate -// -// Description: allocates block of memory from allocator - - virtual NTSTATUS Allocate(IN ULONG Size, - OUT PVOID *OutVirtualBase, - OUT PPHYSICAL_ADDRESS OutPhysicalAddress) = 0; - - -//----------------------------------------------------------------------------------------- -// -// Free -// -// Description: releases memory block - - virtual NTSTATUS Release(IN PVOID VirtualBase, - IN ULONG Size) = 0; - -}; - -typedef IDMAMemoryManager *PDMAMEMORYMANAGER; - +typedef IUHCIHardwareDevice *PUHCIHARDWAREDEVICE; //========================================================================================= // @@ -345,118 +75,44 @@ typedef IDMAMemoryManager *PDMAMEMORYMANAGER; // CancelCallback routine is invoked. // -DECLARE_INTERFACE_(IUSBRequest, IUnknown) + + +#define DEFINE_ABSTRACT_USBUHCIREQUEST() \ + STDMETHOD_(NTSTATUS, GetEndpointDescriptor)( THIS_ \ + IN struct _UHCI_QUEUE_HEAD**OutDescriptor) PURE; \ + \ + STDMETHOD_(UCHAR, GetInterval)( THIS) PURE; \ + \ + STDMETHOD_(USB_DEVICE_SPEED, GetDeviceSpeed)( THIS) PURE; \ + \ + STDMETHOD_(VOID, CompletionCallback)( THIS) PURE; \ + \ + STDMETHOD_(VOID, FreeEndpointDescriptor)( THIS_ \ + IN struct _UHCI_QUEUE_HEAD *OutDescriptor) PURE; + + +#define IMP_IUHCIREQUEST \ + STDMETHODIMP_(NTSTATUS) GetEndpointDescriptor(THIS_ \ + IN struct _UHCI_QUEUE_HEAD**OutDescriptor); \ + \ + STDMETHODIMP_(UCHAR) GetInterval(THIS); \ + \ + STDMETHODIMP_(USB_DEVICE_SPEED) GetDeviceSpeed(THIS); \ + \ + STDMETHODIMP_(VOID) CompletionCallback(THIS); \ + \ + STDMETHODIMP_(VOID) FreeEndpointDescriptor(THIS_ \ + IN struct _UHCI_QUEUE_HEAD * OutDescriptor); + +DECLARE_INTERFACE_(IUHCIRequest, IUSBRequest) { DEFINE_ABSTRACT_UNKNOWN() - -//----------------------------------------------------------------------------------------- -// -// InitializeWithSetupPacket -// -// Description: initializes the request packet with an setup packet -// If there is a TransferBuffer, the TransferBufferLength contains the length of the buffer - - - virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, - IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, - IN UCHAR DeviceAddress, - IN OPTIONAL struct _USB_ENDPOINT *EndpointDescriptor, - IN USB_DEVICE_SPEED DeviceSpeed, - IN OUT ULONG TransferBufferLength, - IN OUT PMDL TransferBuffer) = 0; - -//----------------------------------------------------------------------------------------- -// -// InitializeWithIrp -// -// Description: initializes the request with an IRP -// The irp contains an URB block which contains all necessary information - - virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager, - IN OUT PIRP Irp, - IN USB_DEVICE_SPEED DeviceSpeed) = 0; - -//----------------------------------------------------------------------------------------- -// -// IsRequestComplete -// -// Description: returns true when the request has been completed -// Should be called after the CompletionCallback has been invoked -// This function is called by IUSBQueue after queue head has been completed -// If the function returns true, IUSBQueue will then call ShouldReleaseRequestAfterCompletion -// If that function returns also true, it calls Release() to delete the IUSBRequest - - virtual BOOLEAN IsRequestComplete() = 0; - -//----------------------------------------------------------------------------------------- -// -// GetTransferType -// -// Description: returns the type of the request: control, bulk, iso, interrupt - - virtual ULONG GetTransferType() = 0; - -//----------------------------------------------------------------------------------------- -// -// GetEndpointDescriptor -// -// Description: returns the general transfer descriptor - - virtual NTSTATUS GetEndpointDescriptor(struct _UHCI_QUEUE_HEAD ** OutDescriptor) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetResultStatus -// -// Description: returns the status code of the result -// Note: this function will block the caller untill the request has been completed - - virtual VOID GetResultStatus(OUT OPTIONAL NTSTATUS * NtStatusCode, - OUT OPTIONAL PULONG UrbStatusCode) = 0; - -//----------------------------------------------------------------------------------------- -// -// IsRequestInitialized -// -// Description: returns true when the request has been successfully initialized using InitializeXXX methods - - virtual BOOLEAN IsRequestInitialized() = 0; - -//----------------------------------------------------------------------------------------- -// -// GetInterruptInterval -// -// Description: returns interval of the iso / interrupt - - virtual UCHAR GetInterval() = 0; - -//----------------------------------------------------------------------------------------- -// -// GetDeviceSpeed -// -// Description: returns device speed - - virtual USB_DEVICE_SPEED GetDeviceSpeed() = 0; - -//----------------------------------------------------------------------------------------- -// -// CompletionCallback -// -// Description: notifies request that the endpoint descriptor is complete - - virtual VOID CompletionCallback() = 0; - -//----------------------------------------------------------------------------------------- -// -// FreeEndpointDescriptor -// -// Description: frees the associated endpoint descriptor and its general descriptors - - virtual VOID FreeEndpointDescriptor(struct _UHCI_QUEUE_HEAD * OutDescriptor) = 0; + DEFINE_ABSTRACT_USBREQUEST() + DEFINE_ABSTRACT_USBUHCIREQUEST() }; -typedef IUSBRequest *PUSBREQUEST; +typedef IUHCIRequest *PUHCIREQUEST; //========================================================================================= // @@ -465,336 +121,21 @@ typedef IUSBRequest *PUSBREQUEST; // Description: This class manages pending requests // -DECLARE_INTERFACE_(IUSBQueue, IUnknown) +#define DEFINE_ABSTRACT_USBUHCIQUEUE() \ + STDMETHOD_(VOID, TransferInterrupt)( \ + IN UCHAR ErrorInterrupt) PURE; + +#define IMP_IUHCIQUEUE \ + STDMETHODIMP_(VOID) TransferInterrupt( \ + IN UCHAR ErrorInterrupt); + +DECLARE_INTERFACE_(IUHCIQueue, IUSBQueue) { DEFINE_ABSTRACT_UNKNOWN() - -//----------------------------------------------------------------------------------------- -// -// Initialize -// -// Description: initializes the object - - virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Hardware, - IN PDMA_ADAPTER AdapterObject, - IN PDMAMEMORYMANAGER MemManager, - IN OPTIONAL PKSPIN_LOCK Lock) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetPendingRequestCount -// -// Description: returns the number of pending requests true from IsRequestComplete - - virtual ULONG GetPendingRequestCount() = 0; - -//----------------------------------------------------------------------------------------- -// -// AddUSBRequest -// -// Description: adds an usb request to the queue. -// Returns status success when successful - - virtual NTSTATUS AddUSBRequest(IUSBRequest * Request) = 0; - -//----------------------------------------------------------------------------------------- -// -// CancelRequests() -// -// Description: cancels all requests - - virtual NTSTATUS CancelRequests() = 0; - -//----------------------------------------------------------------------------------------- -// -// CreateUSBRequest -// -// Description: creates an usb request - - virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest) = 0; - - -//----------------------------------------------------------------------------------------- -// -// AbortDevicePipe -// -// Description: aborts all pending requsts of an device - - virtual NTSTATUS AbortDevicePipe(UCHAR DeviceAddress, IN struct _USB_ENDPOINT * EndpointDescriptor) = 0; - -//----------------------------------------------------------------------------------------- -// -// TransferInterrupt -// -// Description: informs the queue that a interrupt completed - - virtual VOID TransferInterrupt(UCHAR ErrorInterrupt) = 0; - + DEFINE_ABSTRACT_USBQUEUE() + DEFINE_ABSTRACT_USBUHCIQUEUE() }; -typedef IUSBQueue *PUSBQUEUE; - -//========================================================================================= -// -// class IHubController -// -// Description: This class implements a hub controller -// - -DECLARE_INTERFACE_(IHubController, IUnknown) -{ - DEFINE_ABSTRACT_UNKNOWN() - -//---------------------------------------------------------------------------------------- -// -// Initialize -// -// Description: Initializes the hub controller - - virtual NTSTATUS Initialize(IN PDRIVER_OBJECT DriverObject, - IN PHCDCONTROLLER Controller, - IN PUSBHARDWAREDEVICE Device, - IN BOOLEAN IsRootHubDevice, - IN ULONG DeviceAddress) = 0; - -//---------------------------------------------------------------------------------------- -// -// GetHubControllerDeviceObject -// -// Description: Returns the hub controller device object - - virtual NTSTATUS GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject) = 0; - -//---------------------------------------------------------------------------------------- -// -// GetHubControllerSymbolicLink -// -// Description: Returns the symbolic link of the root hub - - virtual NTSTATUS GetHubControllerSymbolicLink(ULONG BufferLength, PVOID Buffer, PULONG RequiredLength) = 0; - - -}; - -typedef IHubController *PHUBCONTROLLER; - -//========================================================================================= -// -// class IDispatchIrp -// -// Description: This class is used to handle irp dispatch requests -// - -DECLARE_INTERFACE_(IDispatchIrp, IUnknown) -{ - DEFINE_ABSTRACT_UNKNOWN() - -//----------------------------------------------------------------------------------------- -// -// HandlePnp -// -// Description: This function handles all pnp requests - - virtual NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject, - IN OUT PIRP Irp) = 0; - -//----------------------------------------------------------------------------------------- -// -// HandlePower -// -// Description: This function handles all power pnp requests -// - virtual NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject, - IN OUT PIRP Irp) = 0; - -//----------------------------------------------------------------------------------------- -// -// HandleDeviceControl -// -// Description: handles device io control requests - - virtual NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, - IN OUT PIRP Irp) = 0; -}; - -typedef IDispatchIrp *PDISPATCHIRP; - -//========================================================================================= -// -// class IUSBDevice -// -// Description: This class is used to abstract details of a usb device -// - -DECLARE_INTERFACE_(IUSBDevice, IUnknown) -{ - DEFINE_ABSTRACT_UNKNOWN() - -//---------------------------------------------------------------------------------------- -// -// Initialize -// -// Description: Initializes the usb device - - virtual NTSTATUS Initialize(IN PHUBCONTROLLER HubController, - IN PUSBHARDWAREDEVICE Device, - IN PVOID Parent, - IN ULONG Port, - IN ULONG PortStatus) = 0; - -//----------------------------------------------------------------------------------------- -// -// IsHub -// -// Description: returns true when device is a hub - - virtual BOOLEAN IsHub() = 0; - -//----------------------------------------------------------------------------------------- -// -// GetParent -// -// Description: gets the parent device of the this device - - virtual NTSTATUS GetParent(PVOID * Parent) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetDeviceAddress -// -// Description: gets the device address of the this device - - virtual UCHAR GetDeviceAddress() = 0; - - -//----------------------------------------------------------------------------------------- -// -// GetPort -// -// Description: gets the port to which this device is connected - - virtual ULONG GetPort() = 0; - -//----------------------------------------------------------------------------------------- -// -// GetSpeed -// -// Description: gets the speed of the device - - virtual USB_DEVICE_SPEED GetSpeed() = 0; - -//----------------------------------------------------------------------------------------- -// -// GetType -// -// Description: gets the type of the device, either 1.1 or 2.0 device - - virtual USB_DEVICE_TYPE GetType() = 0; - -//----------------------------------------------------------------------------------------- -// -// GetState -// -// Description: gets the device state - - virtual ULONG GetState() = 0; - -//----------------------------------------------------------------------------------------- -// -// SetDeviceHandleData -// -// Description: sets device handle data - - virtual void SetDeviceHandleData(PVOID Data) = 0; - -//----------------------------------------------------------------------------------------- -// -// SetDeviceAddress -// -// Description: sets device handle data - - virtual NTSTATUS SetDeviceAddress(UCHAR DeviceAddress) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetDeviceDescriptor -// -// Description: sets device handle data - - virtual void GetDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetConfigurationValue -// -// Description: gets current selected configuration index - - virtual UCHAR GetConfigurationValue() = 0; - -//----------------------------------------------------------------------------------------- -// -// SubmitIrp -// -// Description: submits an irp containing an urb - - virtual NTSTATUS SubmitIrp(PIRP Irp) = 0; - -//----------------------------------------------------------------------------------------- -// -// GetConfigurationDescriptors -// -// Description: returns one or more configuration descriptors - - virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer, - IN ULONG BufferLength, - OUT PULONG OutBufferLength) = 0; - -//----------------------------------------------------------------------------------------- -// -// Description: returns length of configuration descriptors -// - virtual ULONG GetConfigurationDescriptorsLength() = 0; - -//----------------------------------------------------------------------------------------- -// -// SubmitSetupPacket -// -// Description: submits an setup packet. The usb device will then create an usb request from it and submit it to the queue - - virtual NTSTATUS SubmitSetupPacket(IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, - IN OUT ULONG BufferLength, - OUT PVOID Buffer) = 0; - -//----------------------------------------------------------------------------------------- -// -// SelectConfiguration -// -// Description: selects a configuration - - virtual NTSTATUS SelectConfiguration(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, - IN PUSBD_INTERFACE_INFORMATION Interface, - OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle) = 0; - -//----------------------------------------------------------------------------------------- -// -// SelectConfiguration -// -// Description: selects a interface of an configuration - - virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE ConfigurationHandle, - IN OUT PUSBD_INTERFACE_INFORMATION Interface) = 0; - -//----------------------------------------------------------------------------------------- -// -// AbortPipe -// -// Description: aborts all pending requsts of an device - - virtual NTSTATUS AbortPipe(IN struct _USB_ENDPOINT * EndpointDescriptor) = 0; - - -}; - -typedef IUSBDevice *PUSBDEVICE; +typedef IUHCIQueue *PUHCIQUEUE; #endif diff --git a/reactos/drivers/usb/usbuhci/memory_manager.cpp b/reactos/drivers/usb/usbuhci/memory_manager.cpp deleted file mode 100644 index c515b0b3787..00000000000 --- a/reactos/drivers/usb/usbuhci/memory_manager.cpp +++ /dev/null @@ -1,369 +0,0 @@ -/* - * PROJECT: ReactOS Universal Serial Bus Host Controller Interface - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/usb/usbuhci/memory_manager.cpp - * PURPOSE: USB UHCI device driver. - * PROGRAMMERS: - * Michael Martin (michael.martin@reactos.org) - * Johannes Anderwald (johannes.anderwald@reactos.org) - */ - -#include "usbuhci.h" - -class CDMAMemoryManager : public IDMAMemoryManager -{ -public: - STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - - // IDMAMemoryManager interface functions - virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Device, IN PKSPIN_LOCK Lock, IN ULONG DmaBufferSize, IN PVOID VirtualBase, IN PHYSICAL_ADDRESS PhysicalAddress, IN ULONG DefaultBlockSize); - virtual NTSTATUS Allocate(IN ULONG Size, OUT PVOID *OutVirtualBase, OUT PPHYSICAL_ADDRESS OutPhysicalAddress); - virtual NTSTATUS Release(IN PVOID VirtualBase, IN ULONG Size); - - // constructor / destructor - CDMAMemoryManager(IUnknown *OuterUnknown){} - virtual ~CDMAMemoryManager(){} - -protected: - LONG m_Ref; - PUSBHARDWAREDEVICE m_Device; - PKSPIN_LOCK m_Lock; - LONG m_DmaBufferSize; - PVOID m_VirtualBase; - PHYSICAL_ADDRESS m_PhysicalAddress; - ULONG m_BlockSize; - - PULONG m_BitmapBuffer; - RTL_BITMAP m_Bitmap; -}; - -//---------------------------------------------------------------------------------------- -NTSTATUS -STDMETHODCALLTYPE -CDMAMemoryManager::QueryInterface( - IN REFIID refiid, - OUT PVOID* Output) -{ - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -CDMAMemoryManager::Initialize( - IN PUSBHARDWAREDEVICE Device, - IN PKSPIN_LOCK Lock, - IN ULONG DmaBufferSize, - IN PVOID VirtualBase, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG DefaultBlockSize) -{ - ULONG BitmapLength; - - // - // sanity checks - // - PC_ASSERT(DmaBufferSize >= PAGE_SIZE); - PC_ASSERT(DmaBufferSize % PAGE_SIZE == 0); - PC_ASSERT(DefaultBlockSize == 32 || DefaultBlockSize == 64 || DefaultBlockSize == 128); - - // - // calculate bitmap length - // - BitmapLength = (DmaBufferSize / DefaultBlockSize) / 8; - - // - // allocate bitmap buffer - // - m_BitmapBuffer = (PULONG)ExAllocatePoolWithTag(NonPagedPool, BitmapLength, TAG_USBUHCI); - if (!m_BitmapBuffer) - { - // - // no memory - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // initialize bitmap - // - RtlInitializeBitMap(&m_Bitmap, m_BitmapBuffer, BitmapLength * 8); - - // - // clear all bits - // - RtlClearAllBits(&m_Bitmap); - - // - // initialize rest of memory allocator - // - m_PhysicalAddress = PhysicalAddress; - m_VirtualBase = VirtualBase; - m_DmaBufferSize = DmaBufferSize; - m_BitmapBuffer = m_BitmapBuffer; - m_Lock = Lock; - m_BlockSize = DefaultBlockSize; - - /* done */ - return STATUS_SUCCESS; -} - -NTSTATUS -CDMAMemoryManager::Allocate( - IN ULONG Size, - OUT PVOID *OutVirtualAddress, - OUT PPHYSICAL_ADDRESS OutPhysicalAddress) -{ - ULONG Length, BlockCount, FreeIndex, StartPage, EndPage; - KIRQL OldLevel; - ULONG BlocksPerPage; - - // - // sanity checks - // - ASSERT(Size <= PAGE_SIZE); - //ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - - // - // align request - // - Length = (Size + m_BlockSize -1) & ~(m_BlockSize -1); - - // - // sanity check - // - ASSERT(Length); - - // - // convert to block count - // - BlockCount = Length / m_BlockSize; - - // - // acquire lock - // - KeAcquireSpinLock(m_Lock, &OldLevel); - - // - // helper variable - // - BlocksPerPage = PAGE_SIZE / m_BlockSize; - - // - // start search - // - FreeIndex = 0; - do - { - // - // search for an free index - // - FreeIndex = RtlFindClearBits(&m_Bitmap, BlockCount, FreeIndex); - - // - // check if there was a block found - // - if (FreeIndex == MAXULONG) - { - // - // no free block found - // - break; - } - - // - // check that the allocation does not spawn over page boundaries - // - StartPage = (FreeIndex * m_BlockSize); - StartPage = (StartPage != 0 ? StartPage / PAGE_SIZE : 0); - EndPage = ((FreeIndex + BlockCount) * m_BlockSize) / PAGE_SIZE; - - // - // does the request start and end on the same page - // - if (StartPage == EndPage) - { - // - // reserve block - // - RtlSetBits(&m_Bitmap, FreeIndex, BlockCount); - - // - // reserve block - // - break; - } - else if ((BlockCount == BlocksPerPage) && (FreeIndex % BlocksPerPage == 0)) - { - // - // the request equals PAGE_SIZE and is aligned at page boundary - // reserve block - // - RtlSetBits(&m_Bitmap, FreeIndex, BlockCount); - - // - // reserve block - // - break; - } - else - { - // - // request spawned over page boundary - // restart search on next page - // - FreeIndex = (EndPage * PAGE_SIZE) / m_BlockSize; - } - } - while(TRUE); - - // - // release lock - // - KeReleaseSpinLock(m_Lock, OldLevel); - - // - // did allocation succeed - // - if (FreeIndex == MAXULONG) - { - // - // failed to allocate block, requestor must retry - // - return STATUS_UNSUCCESSFUL; - } - - // - // return result - // - *OutVirtualAddress = (PVOID)((ULONG_PTR)m_VirtualBase + FreeIndex * m_BlockSize); - OutPhysicalAddress->QuadPart = m_PhysicalAddress.QuadPart + FreeIndex * m_BlockSize; - - // - // clear block - // - RtlZeroMemory(*OutVirtualAddress, Length); - - // - // done - // - return STATUS_SUCCESS; -} - -NTSTATUS -CDMAMemoryManager::Release( - IN PVOID VirtualAddress, - IN ULONG Size) -{ - KIRQL OldLevel; - ULONG BlockOffset = 0, BlockLength, BlockCount; - - // - // sanity checks - // - PC_ASSERT(VirtualAddress); - PC_ASSERT((ULONG_PTR)VirtualAddress >= (ULONG_PTR)m_VirtualBase); - PC_ASSERT((ULONG_PTR)m_VirtualBase + m_DmaBufferSize > (ULONG_PTR)m_VirtualBase); - - // - // calculate block length - // - BlockLength = ((ULONG_PTR)VirtualAddress - (ULONG_PTR)m_VirtualBase); - - // - // check if its the first block - // - if (BlockLength) - { - // - // divide by base block size - // - BlockOffset = BlockLength / m_BlockSize; - } - - // - // align length to block size - // - Size = (Size + m_BlockSize - 1) & ~(m_BlockSize - 1); - - // - // convert to blocks - // - BlockCount = Size / m_BlockSize; - ASSERT(BlockCount); - - // - // acquire lock - // - KeAcquireSpinLock(m_Lock, &OldLevel); - - // - // sanity check - // - ASSERT(RtlAreBitsSet(&m_Bitmap, BlockOffset, BlockCount)); - - // - // release buffer - // - RtlClearBits(&m_Bitmap, BlockOffset, BlockCount); - - // - // release lock - // - KeReleaseSpinLock(m_Lock, OldLevel); - - // - // done - // - return STATUS_SUCCESS; -} - -NTSTATUS -CreateDMAMemoryManager( - PDMAMEMORYMANAGER *OutMemoryManager) -{ - CDMAMemoryManager* This; - - // - // allocate controller - // - This = new(NonPagedPool, TAG_USBUHCI) CDMAMemoryManager(0); - if (!This) - { - // - // failed to allocate - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // add reference count - // - This->AddRef(); - - // - // return result - // - *OutMemoryManager = (PDMAMEMORYMANAGER)This; - - // - // done - // - return STATUS_SUCCESS; -} - diff --git a/reactos/drivers/usb/usbuhci/misc.cpp b/reactos/drivers/usb/usbuhci/misc.cpp deleted file mode 100644 index 5136f32773e..00000000000 --- a/reactos/drivers/usb/usbuhci/misc.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * PROJECT: ReactOS Universal Serial Bus Host Controller Interface - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/usb/usbuhci/misc.cpp - * PURPOSE: USB UHCI device driver. - * PROGRAMMERS: - * Michael Martin (michael.martin@reactos.org) - * Johannes Anderwald (johannes.anderwald@reactos.org) - */ - -#include "usbuhci.h" - -// -// driver verifier -// -IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine; - -NTSTATUS -NTAPI -SyncForwardIrpCompletionRoutine( - PDEVICE_OBJECT DeviceObject, - PIRP Irp, - PVOID Context) -{ - if (Irp->PendingReturned) - { - KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); - } - return STATUS_MORE_PROCESSING_REQUIRED; -} - -NTSTATUS -NTAPI -SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - KEVENT Event; - NTSTATUS Status; - - // - // initialize event - // - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - // - // copy irp stack location - // - IoCopyCurrentIrpStackLocationToNext(Irp); - - // - // set completion routine - // - IoSetCompletionRoutine(Irp, SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE); - - - // - // call driver - // - Status = IoCallDriver(DeviceObject, Irp); - - - // - // check if pending - // - if (Status == STATUS_PENDING) - { - // - // wait for the request to finish - // - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - - // - // copy status code - // - Status = Irp->IoStatus.Status; - } - - // - // done - // - return Status; -} - -NTSTATUS -NTAPI -GetBusInterface( - PDEVICE_OBJECT DeviceObject, - PBUS_INTERFACE_STANDARD busInterface) -{ - KEVENT Event; - NTSTATUS Status; - PIRP Irp; - IO_STATUS_BLOCK IoStatus; - PIO_STACK_LOCATION Stack; - - if ((!DeviceObject) || (!busInterface)) - return STATUS_UNSUCCESSFUL; - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, - DeviceObject, - NULL, - 0, - NULL, - &Event, - &IoStatus); - - if (Irp == NULL) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - - Stack=IoGetNextIrpStackLocation(Irp); - Stack->MajorFunction = IRP_MJ_PNP; - Stack->MinorFunction = IRP_MN_QUERY_INTERFACE; - Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD); - Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_BUS_INTERFACE_STANDARD; - Stack->Parameters.QueryInterface.Version = 1; - Stack->Parameters.QueryInterface.Interface = (PINTERFACE)busInterface; - Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL; - Irp->IoStatus.Status=STATUS_NOT_SUPPORTED ; - - Status=IoCallDriver(DeviceObject, Irp); - - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - - Status=IoStatus.Status; - } - - return Status; -} - diff --git a/reactos/drivers/usb/usbuhci/purecall.cpp b/reactos/drivers/usb/usbuhci/purecall.cpp deleted file mode 100644 index d27ae996176..00000000000 --- a/reactos/drivers/usb/usbuhci/purecall.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * PROJECT: ReactOS Universal Serial Bus Host Controller Interface - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/usb/usbuhci/purecall.cpp - * PURPOSE: USB UHCI device driver. - * PROGRAMMERS: - * Michael Martin (michael.martin@reactos.org) - * Johannes Anderwald (johannes.anderwald@reactos.org) - */ - -#include "usbuhci.h" - - -extern "C" { - void - __cxa_pure_virtual() - { - // put error handling here - - DbgBreakPoint(); - - } -} - diff --git a/reactos/drivers/usb/usbuhci/usb_device.cpp b/reactos/drivers/usb/usbuhci/usb_device.cpp deleted file mode 100644 index 195147bcc7e..00000000000 --- a/reactos/drivers/usb/usbuhci/usb_device.cpp +++ /dev/null @@ -1,1435 +0,0 @@ -/* - * PROJECT: ReactOS Universal Serial Bus Host Controller Interface - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/usb/usbuhci/usb_device.cpp - * PURPOSE: USB UHCI device driver. - * PROGRAMMERS: - * Michael Martin (michael.martin@reactos.org) - * Johannes Anderwald (johannes.anderwald@reactos.org) - */ - -#define INITGUID -#include "usbuhci.h" - -class CUSBDevice : public IUSBDevice -{ -public: - STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - - // IUSBDevice interface functions - virtual NTSTATUS Initialize(IN PHUBCONTROLLER HubController, IN PUSBHARDWAREDEVICE Device, IN PVOID Parent, IN ULONG Port, IN ULONG PortStatus); - virtual BOOLEAN IsHub(); - virtual NTSTATUS GetParent(PVOID * Parent); - virtual UCHAR GetDeviceAddress(); - virtual ULONG GetPort(); - virtual USB_DEVICE_SPEED GetSpeed(); - virtual USB_DEVICE_TYPE GetType(); - virtual ULONG GetState(); - virtual void SetDeviceHandleData(PVOID Data); - virtual NTSTATUS SetDeviceAddress(UCHAR DeviceAddress); - virtual void GetDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor); - virtual UCHAR GetConfigurationValue(); - virtual NTSTATUS SubmitIrp(PIRP Irp); - virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer, IN ULONG BufferLength, OUT PULONG OutBufferLength); - virtual ULONG GetConfigurationDescriptorsLength(); - virtual NTSTATUS SubmitSetupPacket(IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, OUT ULONG BufferLength, OUT PVOID Buffer); - virtual NTSTATUS SelectConfiguration(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN PUSBD_INTERFACE_INFORMATION Interface, OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle); - virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE ConfigurationHandle, IN OUT PUSBD_INTERFACE_INFORMATION Interface); - virtual NTSTATUS AbortPipe(IN struct _USB_ENDPOINT * EndpointDescriptor); - - - // local function - virtual NTSTATUS CommitIrp(PIRP Irp); - virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl); - virtual NTSTATUS CreateConfigurationDescriptor(UCHAR ConfigurationIndex); - virtual NTSTATUS CreateDeviceDescriptor(); - virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor); - virtual VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor); - - // constructor / destructor - CUSBDevice(IUnknown *OuterUnknown){} - virtual ~CUSBDevice(); - -protected: - LONG m_Ref; - PHUBCONTROLLER m_HubController; - PUSBHARDWAREDEVICE m_Device; - PVOID m_Parent; - ULONG m_Port; - UCHAR m_DeviceAddress; - PVOID m_Data; - UCHAR m_ConfigurationIndex; - KSPIN_LOCK m_Lock; - USB_DEVICE_DESCRIPTOR m_DeviceDescriptor; - ULONG m_PortStatus; - PUSBQUEUE m_Queue; - PDMAMEMORYMANAGER m_DmaManager; - - PUSB_CONFIGURATION m_ConfigurationDescriptors; -}; - -CUSBDevice::~CUSBDevice() -{ - ULONG Index, InterfaceIndex, EndpointIndex; - //NTSTATUS Status; - - if (!m_ConfigurationDescriptors) - { - // - // nothing to do - // - return; - } - - - // - // clean up resources - // - for(Index = 0; Index < m_DeviceDescriptor.bNumConfigurations; Index++) - { - for(InterfaceIndex = 0; InterfaceIndex < m_ConfigurationDescriptors[Index].ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++) - { - // - // are there any endpoint descriptors - // - for(EndpointIndex = 0; EndpointIndex < m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints; EndpointIndex++) - { - // - // abort pipe - // - //Status = AbortPipe((PUSB_ENDPOINT_DESCRIPTOR)&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints[EndpointIndex]); - //DPRINT1("[USBUHCI] Deleting Device Abort Pipe Status %x\n", Status); - } - - if (m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints) - { - // - // free endpoints - // - ExFreePool(m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints); - } - } - - if (m_ConfigurationDescriptors[Index].ConfigurationDescriptor->bNumInterfaces) - { - // - // free interface descriptors - // - ExFreePool(m_ConfigurationDescriptors[Index].Interfaces); - } - - if (m_ConfigurationDescriptors[Index].ConfigurationDescriptor) - { - // - // free configuration descriptor - // - ExFreePool(m_ConfigurationDescriptors[Index].ConfigurationDescriptor); - } - } - - // - // free configuration descriptor - // - ExFreePool(m_ConfigurationDescriptors); -} - - - -//---------------------------------------------------------------------------------------- -NTSTATUS -STDMETHODCALLTYPE -CUSBDevice::QueryInterface( - IN REFIID refiid, - OUT PVOID* Output) -{ - return STATUS_UNSUCCESSFUL; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::Initialize( - IN PHUBCONTROLLER HubController, - IN PUSBHARDWAREDEVICE Device, - IN PVOID Parent, - IN ULONG Port, - IN ULONG PortStatus) -{ - NTSTATUS Status; - - // - // initialize members - // - m_HubController = HubController; - m_Device = Device; - m_Parent = Parent; - m_Port = Port; - m_PortStatus = PortStatus; - - // - // initialize device lock - // - KeInitializeSpinLock(&m_Lock); - - // - // no device address has been set yet - // - m_DeviceAddress = 0; - - // - // get usb request queue - // - Status = m_Device->GetUSBQueue(&m_Queue); - if (!NT_SUCCESS(Status)) - { - // - // failed to get usb queue - // - DPRINT1("CUSBDevice::Initialize GetUsbQueue failed with %x\n", Status); - return Status; - } - - // - // get dma manager - // - Status = m_Device->GetDMA(&m_DmaManager); - if (!NT_SUCCESS(Status)) - { - // - // failed to get dma manager - // - DPRINT1("CUSBDevice::Initialize GetDMA failed with %x\n", Status); - return Status; - } - - // - // sanity check - // - PC_ASSERT(m_DmaManager); - - // - // get device descriptor - // - Status = CreateDeviceDescriptor(); - if (!NT_SUCCESS(Status)) - { - // - // failed to get device descriptor - // - DPRINT1("CUSBDevice::Initialize Failed to get device descriptor with %x\n", Status); - return Status; - } - - // - // done - // - return Status; -} - -//---------------------------------------------------------------------------------------- -BOOLEAN -CUSBDevice::IsHub() -{ - // - // USB Standard Device Class see http://www.usb.org/developers/defined_class/#BaseClass09h - // for details - // - return (m_DeviceDescriptor.bDeviceClass == 0x09 && m_DeviceDescriptor.bDeviceSubClass == 0x00); -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::GetParent( - PVOID * Parent) -{ - // - // returns parent - // - *Parent = m_Parent; - - // - // done - // - return STATUS_SUCCESS; -} - -//---------------------------------------------------------------------------------------- -UCHAR -CUSBDevice::GetDeviceAddress() -{ - // - // get device address - // - return m_DeviceAddress; -} - -//---------------------------------------------------------------------------------------- -ULONG -CUSBDevice::GetPort() -{ - // - // get port to which this device is connected to - // - return m_Port; -} - -//---------------------------------------------------------------------------------------- -USB_DEVICE_SPEED -CUSBDevice::GetSpeed() -{ - if (m_PortStatus & USB_PORT_STATUS_LOW_SPEED) - { - // - // low speed device - // - return UsbLowSpeed; - } - else if (m_PortStatus & USB_PORT_STATUS_HIGH_SPEED) - { - // - // high speed device - // - return UsbHighSpeed; - } - - // - // default to full speed - // - return UsbFullSpeed; -} - -//---------------------------------------------------------------------------------------- -USB_DEVICE_TYPE -CUSBDevice::GetType() -{ - // - // device is encoded into bcdUSB - // - if (m_DeviceDescriptor.bcdUSB == 0x110) - { - // - // USB 1.1 device - // - return Usb11Device; - } - else if (m_DeviceDescriptor.bcdUSB == 0x200) - { - // - // USB 2.0 device - // - return Usb20Device; - } - - DPRINT1("CUSBDevice::GetType Unknown bcdUSB Type %x\n", m_DeviceDescriptor.bcdUSB); - //PC_ASSERT(FALSE); - - return Usb11Device; -} - -//---------------------------------------------------------------------------------------- -ULONG -CUSBDevice::GetState() -{ - UNIMPLEMENTED - return FALSE; -} - -//---------------------------------------------------------------------------------------- -void -CUSBDevice::SetDeviceHandleData( - PVOID Data) -{ - // - // set device data, for debugging issues - // - m_Data = Data; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::SetDeviceAddress( - UCHAR DeviceAddress) -{ - PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - NTSTATUS Status; - UCHAR OldAddress; - UCHAR Index; - - DPRINT1("CUSBDevice::SetDeviceAddress Address %d\n", DeviceAddress); - - CtrlSetup = (PUSB_DEFAULT_PIPE_SETUP_PACKET)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET), TAG_USBUHCI); - if (!CtrlSetup) - return STATUS_INSUFFICIENT_RESOURCES; - - // - // zero request - // - RtlZeroMemory(CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); - - // - // initialize request - // - CtrlSetup->bRequest = USB_REQUEST_SET_ADDRESS; - CtrlSetup->wValue.W = (USHORT)DeviceAddress; - - // - // set device address - // - Status = CommitSetupPacket(CtrlSetup, 0, 0, 0); - - // - // free setup packet - // - ExFreePoolWithTag(CtrlSetup, TAG_USBUHCI); - - // - // check for success - // - if (!NT_SUCCESS(Status)) - { - // - // failed to set device address - // - DPRINT1("CUSBDevice::SetDeviceAddress> failed to set device address with %x Address %x\n", Status, DeviceAddress); - return Status; - } - - // - // lets have a short nap - // - KeStallExecutionProcessor(300); - - // - // back up old address - // - OldAddress = m_DeviceAddress; - - // - // store new device address - // - m_DeviceAddress = DeviceAddress; - - // - // check that setting device address succeeded by retrieving the device descriptor - // - Status = CreateDeviceDescriptor(); - if (!NT_SUCCESS(Status)) - { - // - // failed to retrieve device descriptor - // - DPRINT1("CUSBbDevice::SetDeviceAddress> failed to retrieve device descriptor with device address set Error %x\n", Status); - m_DeviceAddress = OldAddress; - - // - // return error status - // - return Status; - } - - // - // sanity checks - // - PC_ASSERT(m_DeviceDescriptor.bNumConfigurations); - - // - // allocate configuration descriptor - // - m_ConfigurationDescriptors = (PUSB_CONFIGURATION) ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_CONFIGURATION) * m_DeviceDescriptor.bNumConfigurations, TAG_USBUHCI); - - // - // zero configuration descriptor - // - RtlZeroMemory(m_ConfigurationDescriptors, sizeof(USB_CONFIGURATION) * m_DeviceDescriptor.bNumConfigurations); - - // - // retrieve the configuration descriptors - // - for(Index = 0; Index < m_DeviceDescriptor.bNumConfigurations; Index++) - { - // - // retrieve configuration descriptors from device - // - Status = CreateConfigurationDescriptor(Index); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CUSBDevice::SetDeviceAddress> failed to retrieve configuration %lu\n", Index); - break; - } - } - - // - // done - // - return Status; - -} - -//---------------------------------------------------------------------------------------- -void -CUSBDevice::GetDeviceDescriptor( - PUSB_DEVICE_DESCRIPTOR DeviceDescriptor) -{ - RtlMoveMemory(DeviceDescriptor, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); -} - -//---------------------------------------------------------------------------------------- -UCHAR -CUSBDevice::GetConfigurationValue() -{ - // - // return configuration index - // - return m_ConfigurationIndex; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::CommitIrp( - PIRP Irp) -{ - NTSTATUS Status; - PUSBREQUEST Request; - - if (!m_Queue || !m_DmaManager) - { - // - // no queue, wtf? - // - DPRINT1("CUSBDevice::CommitUrb> no queue / dma !!!\n"); - return STATUS_UNSUCCESSFUL; - } - - // - // build usb request - // - Status = m_Queue->CreateUSBRequest(&Request); - if (!NT_SUCCESS(Status)) - { - // - // failed to build request - // - DPRINT1("CUSBDevice::CommitSetupPacket> CreateUSBRequest failed with %x\n", Status); - return Status; - } - - // - // initialize request - // - Status = Request->InitializeWithIrp(m_DmaManager, Irp, GetSpeed()); - - // - // mark irp as pending - // - IoMarkIrpPending(Irp); - - // - // now add the request - // - Status = m_Queue->AddUSBRequest(Request); - if (!NT_SUCCESS(Status)) - { - // - // failed to add request - // - DPRINT1("CUSBDevice::CommitSetupPacket> failed add request to queue with %x\n", Status); - Request->Release(); - return Status; - } - - // - // done - // - return STATUS_PENDING; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::SubmitIrp( - PIRP Irp) -{ - KIRQL OldLevel; - NTSTATUS Status; - - // - // acquire device lock - // - KeAcquireSpinLock(&m_Lock, &OldLevel); - - // - // commit urb - // - Status = CommitIrp(Irp); - - // - // release lock - // - KeReleaseSpinLock(&m_Lock, OldLevel); - - return Status; -} -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::CommitSetupPacket( - IN PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, - IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor, - IN ULONG BufferLength, - IN OUT PMDL Mdl) -{ - NTSTATUS Status; - PUSBREQUEST Request; - - if (!m_Queue) - { - // - // no queue, wtf? - // - DPRINT1("CUSBDevice::CommitSetupPacket> no queue!!!\n"); - return STATUS_UNSUCCESSFUL; - } - - // - // build usb request - // - Status = m_Queue->CreateUSBRequest(&Request); - if (!NT_SUCCESS(Status)) - { - // - // failed to build request - // - DPRINT1("CUSBDevice::CommitSetupPacket> CreateUSBRequest failed with %x\n", Status); - return Status; - } - - // - // initialize request - // - Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, m_DeviceAddress, (struct _USB_ENDPOINT*)EndpointDescriptor, GetSpeed(), BufferLength, Mdl); - if (!NT_SUCCESS(Status)) - { - // - // failed to initialize request - // - DPRINT1("CUSBDevice::CommitSetupPacket> failed to initialize usb request with %x\n", Status); - Request->Release(); - return Status; - } - - // - // now add the request - // - Status = m_Queue->AddUSBRequest(Request); - if (!NT_SUCCESS(Status)) - { - // - // failed to add request - // - DPRINT1("CUSBDevice::CommitSetupPacket> failed add request to queue with %x\n", Status); - Request->Release(); - return Status; - } - - // - // get the result code when the operation has been finished - // - Request->GetResultStatus(&Status, NULL); - - // - // release request - // - Request->Release(); - - // - // done - // - return Status; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::CreateDeviceDescriptor() -{ - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - PMDL Mdl; - NTSTATUS Status; - PVOID DeviceDescriptor; - - // - // allocate descriptor page aligned - // - DeviceDescriptor = ExAllocatePool(NonPagedPool, PAGE_SIZE); - if (!DeviceDescriptor) - { - // - // no memory - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // zero descriptor - // - RtlZeroMemory(DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); - RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); - - // - // setup request - // - CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; - CtrlSetup.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; - CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR); - CtrlSetup.bmRequestType.B = 0x80; - - // - // allocate mdl describing the device descriptor - // - Mdl = IoAllocateMdl(DeviceDescriptor, PAGE_SIZE, FALSE, FALSE, 0); - if (!Mdl) - { - // - // failed to allocate mdl - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // build mdl for non paged pool - // - MmBuildMdlForNonPagedPool(Mdl); - - // - // commit setup packet - // - Status = CommitSetupPacket(&CtrlSetup, 0, sizeof(USB_DEVICE_DESCRIPTOR), Mdl); - - // - // now free the mdl - // - IoFreeMdl(Mdl); - - if (NT_SUCCESS(Status)) - { - // - // informal dbg print - // - RtlCopyMemory(&m_DeviceDescriptor, DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); - DumpDeviceDescriptor(&m_DeviceDescriptor); - } - - // - // free buffer - // - ExFreePool(DeviceDescriptor); - - // - // done - // - return Status; - -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::CreateConfigurationDescriptor( - UCHAR Index) -{ - PVOID Buffer; - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - NTSTATUS Status; - PMDL Mdl; - ULONG InterfaceIndex, EndPointIndex; - PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; - PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; - PUSB_ENDPOINT_DESCRIPTOR EndPointDescriptor; - - - // - // sanity checks - // - PC_ASSERT(m_ConfigurationDescriptors); - - // - // first allocate a buffer which should be enough to store all different interfaces and endpoints - // - Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, TAG_USBUHCI); - if (!Buffer) - { - // - // failed to allocate buffer - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // build setup packet - // - 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 = Index; - CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; - CtrlSetup.wIndex.W = 0; - CtrlSetup.wLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); - - // - // now build MDL describing the buffer - // - Mdl = IoAllocateMdl(Buffer, PAGE_SIZE, FALSE, FALSE, 0); - if (!Mdl) - { - // - // failed to allocate mdl - // - ExFreePoolWithTag(Buffer, TAG_USBUHCI); - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // build mdl for non paged pool - // - MmBuildMdlForNonPagedPool(Mdl); - - // - // commit packet - // - Status = CommitSetupPacket(&CtrlSetup, 0, sizeof(USB_CONFIGURATION_DESCRIPTOR), Mdl); - if (!NT_SUCCESS(Status)) - { - // - // failed to issue request, cleanup - // - IoFreeMdl(Mdl); - ExFreePool(Buffer); - return Status; - } - - // - // get configuration descriptor - // - ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Buffer; - - // - // sanity checks - // - ASSERT(ConfigurationDescriptor->bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR)); - ASSERT(ConfigurationDescriptor->wTotalLength <= PAGE_SIZE); - ASSERT(ConfigurationDescriptor->bNumInterfaces); - ASSERT(ConfigurationDescriptor->wTotalLength); - ASSERT(ConfigurationDescriptor->bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE); - - // - // informal debug print - // - DumpConfigurationDescriptor(ConfigurationDescriptor); - - // - // build setup packet - // - 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 = Index; - CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; - CtrlSetup.wIndex.W = 0; - CtrlSetup.wLength = ConfigurationDescriptor->wTotalLength; - - // - // commit packet - // - Status = CommitSetupPacket(&CtrlSetup, 0, ConfigurationDescriptor->wTotalLength, Mdl); - if (!NT_SUCCESS(Status)) - { - // - // failed to issue request, cleanup - // - IoFreeMdl(Mdl); - ExFreePool(Buffer); - return Status; - } - - // - // now free the mdl - // - IoFreeMdl(Mdl); - - - // - // sanity check - // - ASSERT(ConfigurationDescriptor->bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR)); - ASSERT(ConfigurationDescriptor->wTotalLength <= PAGE_SIZE); - ASSERT(ConfigurationDescriptor->bNumInterfaces); - ASSERT(ConfigurationDescriptor->wTotalLength); - ASSERT(ConfigurationDescriptor->bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE); - - - // - // request is complete, initialize configuration descriptor - // - m_ConfigurationDescriptors[Index].ConfigurationDescriptor = ConfigurationDescriptor; - - // - // now allocate interface descriptors - // - m_ConfigurationDescriptors[Index].Interfaces = (PUSB_INTERFACE)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_INTERFACE) * ConfigurationDescriptor->bNumInterfaces, TAG_USBUHCI); - if (!m_ConfigurationDescriptors[Index].Interfaces) - { - // - // failed to allocate interface descriptors - // - ExFreePool(Buffer); - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // zero interface descriptor - // - RtlZeroMemory(m_ConfigurationDescriptors[Index].Interfaces, sizeof(USB_INTERFACE) * ConfigurationDescriptor->bNumInterfaces); - - // - // get first interface descriptor - // - InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)(ConfigurationDescriptor + 1); - - // - // setup interface descriptors - // - for(InterfaceIndex = 0; InterfaceIndex < ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++) - { - while(InterfaceDescriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE && InterfaceDescriptor->bLength != sizeof(USB_INTERFACE_DESCRIPTOR)) - { - // - // move to next descriptor - // - ASSERT(InterfaceDescriptor->bLength); - InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); - } - - // - // sanity checks - // - ASSERT(InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE); - ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR)); - ASSERT(InterfaceDescriptor->bNumEndpoints); - - // - // copy current interface descriptor - // - RtlCopyMemory(&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor, InterfaceDescriptor, InterfaceDescriptor->bLength); - - // - // allocate end point descriptors - // - m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints = (PUSB_ENDPOINT)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_ENDPOINT) * InterfaceDescriptor->bNumEndpoints, TAG_USBUHCI); - if (!m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints) - { - // - // failed to allocate endpoint - // - Status = STATUS_INSUFFICIENT_RESOURCES; - break; - } - - // - // zero memory - // - RtlZeroMemory(m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints, sizeof(USB_ENDPOINT) * InterfaceDescriptor->bNumEndpoints); - - // - // initialize end point descriptors - // - EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)(InterfaceDescriptor + 1); - - for(EndPointIndex = 0; EndPointIndex < InterfaceDescriptor->bNumEndpoints; EndPointIndex++) - { - // - // skip other descriptors - // - while(EndPointDescriptor->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE && EndPointDescriptor->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR)) - { - // - // assert when next interface descriptor is reached before the next endpoint - // - ASSERT(EndPointDescriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE); - ASSERT(EndPointDescriptor->bLength); - - DPRINT1("InterfaceDescriptor bNumEndpoints %x EndpointIndex %x Skipping Descriptor Type %x\n", InterfaceDescriptor->bNumEndpoints, EndPointIndex, EndPointDescriptor->bDescriptorType); - // - // move to next descriptor - // - EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndPointDescriptor + EndPointDescriptor->bLength); - } - - // - // sanity check - // - ASSERT(EndPointDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE); - ASSERT(EndPointDescriptor->bLength == sizeof(USB_ENDPOINT_DESCRIPTOR)); - - // - // copy endpoint descriptor - // - RtlCopyMemory(&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints[EndPointIndex].EndPointDescriptor, EndPointDescriptor, EndPointDescriptor->bLength); - - // - // move to next offset - // - EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndPointDescriptor + EndPointDescriptor->bLength); - } - - // - // update interface descriptor offset - // - InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)EndPointDescriptor; - } - - // - // done - // - return Status; -} -//---------------------------------------------------------------------------------------- -VOID -CUSBDevice::GetConfigurationDescriptors( - IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer, - IN ULONG BufferLength, - OUT PULONG OutBufferLength) -{ - // - // sanity check - // - PC_ASSERT(BufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR)); - PC_ASSERT(ConfigDescriptorBuffer); - PC_ASSERT(OutBufferLength); - - // - // reset copied length - // - *OutBufferLength = 0; - - // - // FIXME: support multiple configurations - // - PC_ASSERT(m_DeviceDescriptor.bNumConfigurations == 1); - - // - // copy configuration descriptor - // - RtlCopyMemory(ConfigDescriptorBuffer, m_ConfigurationDescriptors[0].ConfigurationDescriptor, min(m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength, BufferLength)); - *OutBufferLength = m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength; -} - -//---------------------------------------------------------------------------------------- -ULONG -CUSBDevice::GetConfigurationDescriptorsLength() -{ - // - // FIXME: support multiple configurations - // - PC_ASSERT(m_DeviceDescriptor.bNumConfigurations == 1); - return m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength; -} -//---------------------------------------------------------------------------------------- -VOID -CUSBDevice::DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor) -{ - DPRINT("Dumping Device Descriptor %x\n", DeviceDescriptor); - DPRINT("bLength %x\n", DeviceDescriptor->bLength); - DPRINT("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType); - DPRINT("bcdUSB %x\n", DeviceDescriptor->bcdUSB); - DPRINT("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass); - DPRINT("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass); - DPRINT("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol); - DPRINT("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0); - DPRINT("idVendor %x\n", DeviceDescriptor->idVendor); - DPRINT("idProduct %x\n", DeviceDescriptor->idProduct); - DPRINT("bcdDevice %x\n", DeviceDescriptor->bcdDevice); - DPRINT("iManufacturer %x\n", DeviceDescriptor->iManufacturer); - DPRINT("iProduct %x\n", DeviceDescriptor->iProduct); - DPRINT("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber); - DPRINT("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations); -} - -//---------------------------------------------------------------------------------------- -VOID -CUSBDevice::DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor) -{ - DPRINT("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor); - DPRINT("bLength %x\n", ConfigurationDescriptor->bLength); - DPRINT("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType); - DPRINT("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength); - DPRINT("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces); - DPRINT("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue); - DPRINT("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration); - DPRINT("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes); - DPRINT("MaxPower %x\n", ConfigurationDescriptor->MaxPower); -} -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::SubmitSetupPacket( - IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, - IN OUT ULONG BufferLength, - OUT PVOID Buffer) -{ - NTSTATUS Status; - PMDL Mdl = NULL; - - if (BufferLength) - { - // - // allocate mdl - // - Mdl = IoAllocateMdl(Buffer, BufferLength, FALSE, FALSE, 0); - if (!Mdl) - { - // - // no memory - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // HACK HACK HACK: assume the buffer is build from non paged pool - // - MmBuildMdlForNonPagedPool(Mdl); - } - - // - // commit setup packet - // - Status = CommitSetupPacket(SetupPacket, 0, BufferLength, Mdl); - - if (Mdl != NULL) - { - // - // free mdl - // - IoFreeMdl(Mdl); - } - - // - // done - // - return Status; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::SelectConfiguration( - IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, - IN PUSBD_INTERFACE_INFORMATION InterfaceInfo, - OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle) -{ - ULONG InterfaceIndex, PipeIndex; - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - NTSTATUS Status; - UCHAR bConfigurationValue = 0; - ULONG ConfigurationIndex = 0, Index; - UCHAR Found = FALSE; - - - if (ConfigurationDescriptor) - { - // - // find configuration index - // - for(Index = 0; Index < m_DeviceDescriptor.bNumConfigurations; Index++) - { - if (m_ConfigurationDescriptors[Index].ConfigurationDescriptor->bConfigurationValue == ConfigurationDescriptor->bConfigurationValue) - { - // - // found configuration index - // - ConfigurationIndex = Index; - Found = TRUE; - } - } - - if (!Found) - { - DPRINT1("[USBUHCI] invalid configuration value %lu\n", ConfigurationDescriptor->bConfigurationValue); - return STATUS_INVALID_PARAMETER; - } - - // - // sanity check - // - ASSERT(ConfigurationDescriptor->bNumInterfaces <= m_ConfigurationDescriptors[ConfigurationIndex].ConfigurationDescriptor->bNumInterfaces); - - // - // get configuration value - // - bConfigurationValue = ConfigurationDescriptor->bConfigurationValue; - } - - // - // now build setup packet - // - RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); - CtrlSetup.bRequest = USB_REQUEST_SET_CONFIGURATION; - CtrlSetup.wValue.W = bConfigurationValue; - - // - // select configuration - // - Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0); - - if (!ConfigurationDescriptor) - { - // - // unconfigure request - // - DPRINT1("CUsbDevice::SelectConfiguration Unconfigure Request Status %x\n", Status); - m_ConfigurationIndex = 0; - return Status; - } - - // - // informal debug print - // - DPRINT1("CUsbDevice::SelectConfiguration New Configuration %x Old Configuration %x Result %x\n", ConfigurationDescriptor->iConfiguration, m_ConfigurationIndex, Status); - if (!NT_SUCCESS(Status)) - { - // - // failed - // - return Status; - } - - // - // store new configuration device index - // - m_ConfigurationIndex = ConfigurationIndex; - - // - // store configuration handle - // - *ConfigurationHandle = &m_ConfigurationDescriptors[ConfigurationIndex]; - - // - // copy interface info and pipe info - // - for(InterfaceIndex = 0; InterfaceIndex < ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++) - { - // - // sanity check: is the info pre-layed out - // - PC_ASSERT(InterfaceInfo->NumberOfPipes == m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints); - PC_ASSERT(InterfaceInfo->Length != 0); -#ifdef _MSC_VER - PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes])); -#endif - - // - // copy interface info - // - InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)&m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex]; - InterfaceInfo->Class = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceClass; - InterfaceInfo->SubClass = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceSubClass; - InterfaceInfo->Protocol = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceProtocol; - InterfaceInfo->Reserved = 0; - - // - // copy endpoint info - // - for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++) - { - // - // copy pipe info - // - InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.wMaxPacketSize; - InterfaceInfo->Pipes[PipeIndex].EndpointAddress = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress; - InterfaceInfo->Pipes[PipeIndex].Interval = m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bInterval; - InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes; - InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)&m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor; - - // - // data toggle is reset on configuration requests - // - m_ConfigurationDescriptors[ConfigurationIndex].Interfaces[InterfaceIndex].EndPoints[PipeIndex].DataToggle = FALSE; - } - - // - // move offset - // - InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)PtrToUlong(InterfaceInfo) + InterfaceInfo->Length); - } - - // - // done - // - return Status; -} - -//---------------------------------------------------------------------------------------- -NTSTATUS -CUSBDevice::SelectInterface( - IN USBD_CONFIGURATION_HANDLE ConfigurationHandle, - IN OUT PUSBD_INTERFACE_INFORMATION InterfaceInfo) -{ - PUSB_CONFIGURATION Configuration; - ULONG PipeIndex; - USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; - NTSTATUS Status; - - // - // get configuration struct - // - Configuration = (PUSB_CONFIGURATION)ConfigurationHandle; - - // - // sanity check - // - ASSERT(Configuration->ConfigurationDescriptor->bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE); - ASSERT(Configuration->ConfigurationDescriptor->bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR)); - ASSERT(Configuration->ConfigurationDescriptor->iConfiguration < m_DeviceDescriptor.bNumConfigurations); - ASSERT(&m_ConfigurationDescriptors[Configuration->ConfigurationDescriptor->iConfiguration] == Configuration); - - // - // initialize setup packet - // - RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); - CtrlSetup.bRequest = USB_REQUEST_SET_INTERFACE; - CtrlSetup.wValue.W = Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bAlternateSetting; - CtrlSetup.wIndex.W = Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bInterfaceNumber; - CtrlSetup.bmRequestType.B = 0x01; - - // - // issue request - // - Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0); - - // - // informal debug print - // - DPRINT1("CUSBDevice::SelectInterface AlternateSetting %x InterfaceNumber %x Status %x\n", InterfaceInfo->AlternateSetting, InterfaceInfo->InterfaceNumber, Status); - if (!NT_SUCCESS(Status)) - { - // - // failed to select interface - // - return Status; - } - - - // - // sanity checks - // - PC_ASSERT(Configuration->ConfigurationDescriptor->bNumInterfaces > InterfaceInfo->InterfaceNumber); - PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bNumEndpoints == InterfaceInfo->NumberOfPipes); -#ifdef _MSC_VER - PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes])); -#endif - - // - // copy pipe handles - // - for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++) - { - // - // copy pipe handle - // - DPRINT1("PipeIndex %lu\n", PipeIndex); - DPRINT1("EndpointAddress %x\n", InterfaceInfo->Pipes[PipeIndex].EndpointAddress); - DPRINT1("Interval %d\n", InterfaceInfo->Pipes[PipeIndex].Interval); - DPRINT1("MaximumPacketSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize); - DPRINT1("MaximumTransferSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumTransferSize); - DPRINT1("PipeFlags %d\n", InterfaceInfo->Pipes[PipeIndex].PipeFlags); - DPRINT1("PipeType %dd\n", InterfaceInfo->Pipes[PipeIndex].PipeType); - DPRINT1("UsbEndPoint %x\n", Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress); - PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress == InterfaceInfo->Pipes[PipeIndex].EndpointAddress); - - InterfaceInfo->Pipes[PipeIndex].PipeHandle = &Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor; - - // - // data toggle is reset on select interface requests - // - m_ConfigurationDescriptors[Configuration->ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].DataToggle = FALSE; - - if (Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes & (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT)) - { - // - // FIXME: check if enough bandwidth is available - // - } - } - - - // - // done - // - return Status; -} - -NTSTATUS -CUSBDevice::AbortPipe( - IN struct _USB_ENDPOINT *EndpointDescriptor) -{ - // - // let it handle usb queue - // - ASSERT(m_Queue); - ASSERT(m_DeviceAddress); - - // - // done - // - return m_Queue->AbortDevicePipe(m_DeviceAddress, EndpointDescriptor); -} - - -//---------------------------------------------------------------------------------------- -NTSTATUS -CreateUSBDevice( - PUSBDEVICE *OutDevice) -{ - CUSBDevice * This; - - // - // allocate controller - // - This = new(NonPagedPool, TAG_USBUHCI) CUSBDevice(0); - if (!This) - { - // - // failed to allocate - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // add reference count - // - This->AddRef(); - - // - // return result - // - *OutDevice = (PUSBDEVICE)This; - - // - // done - // - return STATUS_SUCCESS; -} - diff --git a/reactos/drivers/usb/usbuhci/usb_queue.cpp b/reactos/drivers/usb/usbuhci/usb_queue.cpp index b505794f829..6c7beb4c856 100644 --- a/reactos/drivers/usb/usbuhci/usb_queue.cpp +++ b/reactos/drivers/usb/usbuhci/usb_queue.cpp @@ -11,7 +11,7 @@ #include "usbuhci.h" #include "hardware.h" -class CUSBQueue : public IUSBQueue +class CUSBQueue : public IUHCIQueue { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); @@ -34,14 +34,8 @@ public: } // com - virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Hardware, PDMA_ADAPTER AdapterObject, IN PDMAMEMORYMANAGER MemManager, IN OPTIONAL PKSPIN_LOCK Lock); - virtual ULONG GetPendingRequestCount(); - virtual NTSTATUS AddUSBRequest(IUSBRequest * Request); - virtual NTSTATUS CancelRequests(); - virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest); - virtual NTSTATUS AbortDevicePipe(UCHAR DeviceAddress, IN struct _USB_ENDPOINT * EndpointDescriptor); - virtual VOID TransferInterrupt(UCHAR ErrorInterrupt); - + IMP_IUSBQUEUE + IMP_IUHCIQUEUE // local VOID LinkQueueHead(PUHCI_QUEUE_HEAD QueueHead, PUHCI_QUEUE_HEAD NextQueueHead); @@ -58,7 +52,7 @@ public: protected: LONG m_Ref; // reference count KSPIN_LOCK m_Lock; // list lock - PUSBHARDWAREDEVICE m_Hardware; // hardware + PUHCIHARDWAREDEVICE m_Hardware; // hardware }; @@ -88,42 +82,31 @@ CUSBQueue::Initialize( IN PDMAMEMORYMANAGER MemManager, IN OPTIONAL PKSPIN_LOCK Lock) { - // - // initialize spinlock - // - KeInitializeSpinLock(&m_Lock); // // store hardware // - m_Hardware = Hardware; + m_Hardware = PUHCIHARDWAREDEVICE(Hardware); + // + // initialize spinlock + // + KeInitializeSpinLock(&m_Lock); return STATUS_SUCCESS; } -ULONG -CUSBQueue::GetPendingRequestCount() -{ - // - // Loop through the pending list and iterrate one for each QueueHead that - // has a IRP to complete. - // - - return 0; -} - NTSTATUS CUSBQueue::AddQueueHead( PUHCI_QUEUE_HEAD NewQueueHead) { - PUSBREQUEST Request; + PUHCIREQUEST Request; PUHCI_QUEUE_HEAD QueueHead = NULL; // // get request // - Request = (PUSBREQUEST)NewQueueHead->Request; + Request = (PUHCIREQUEST)NewQueueHead->Request; if (!Request) { // @@ -194,10 +177,14 @@ CUSBQueue::AddQueueHead( NTSTATUS CUSBQueue::AddUSBRequest( - IUSBRequest * Request) + IUSBRequest * Req) { PUHCI_QUEUE_HEAD NewQueueHead; NTSTATUS Status; + PUHCIREQUEST Request; + + // get request + Request = (PUHCIREQUEST)Req; // // get queue head @@ -247,24 +234,19 @@ CUSBQueue::UnLinkQueueHead( PreviousQueueHead->NextLogicalDescriptor = QueueHeadToRemove->NextLogicalDescriptor; } - -NTSTATUS -CUSBQueue::CancelRequests() -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS CUSBQueue::AbortDevicePipe( IN UCHAR DeviceAddress, - IN struct _USB_ENDPOINT *EndpointDescriptor) + IN PUSB_ENDPOINT_DESCRIPTOR EndDescriptor) { KIRQL OldLevel; PUHCI_TRANSFER_DESCRIPTOR Descriptor; PUHCI_QUEUE_HEAD QueueHead, PreviousQueueHead = NULL; UCHAR EndpointAddress, EndpointDeviceAddress; + PUSB_ENDPOINT EndpointDescriptor; + // get descriptor + EndpointDescriptor = (PUSB_ENDPOINT)EndDescriptor; // acquire lock KeAcquireSpinLock(&m_Lock, &OldLevel); @@ -412,7 +394,7 @@ CUSBQueue::QueueHeadCleanup( IN PUHCI_QUEUE_HEAD PreviousQueueHead, OUT PUHCI_QUEUE_HEAD *NextQueueHead) { - PUSBREQUEST Request; + PUHCIREQUEST Request; PUHCI_QUEUE_HEAD NewQueueHead; NTSTATUS Status; @@ -430,7 +412,7 @@ CUSBQueue::QueueHeadCleanup( // // the queue head is complete, is the transfer now completed? // - Request = (PUSBREQUEST)QueueHead->Request; + Request = (PUHCIREQUEST)QueueHead->Request; ASSERT(Request); // diff --git a/reactos/drivers/usb/usbuhci/usb_request.cpp b/reactos/drivers/usb/usbuhci/usb_request.cpp index aa1e07f24ca..9125336d5d5 100644 --- a/reactos/drivers/usb/usbuhci/usb_request.cpp +++ b/reactos/drivers/usb/usbuhci/usb_request.cpp @@ -13,7 +13,7 @@ #include "usbuhci.h" #include "hardware.h" -class CUSBRequest : public IUSBRequest +class CUSBRequest : public IUHCIRequest { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); @@ -35,19 +35,9 @@ public: return m_Ref; } - // IUSBRequest interface functions - virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, IN OPTIONAL struct _USB_ENDPOINT * EndpointDescriptor, IN USB_DEVICE_SPEED DeviceSpeed, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer); - virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager, IN OUT PIRP Irp, IN USB_DEVICE_SPEED DeviceSpeed); - virtual BOOLEAN IsRequestComplete(); - virtual ULONG GetTransferType(); - virtual NTSTATUS GetEndpointDescriptor(struct _UHCI_QUEUE_HEAD ** OutQueueHead); - virtual VOID GetResultStatus(OUT OPTIONAL NTSTATUS *NtStatusCode, OUT OPTIONAL PULONG UrbStatusCode); - virtual BOOLEAN IsRequestInitialized(); - virtual BOOLEAN IsQueueHeadComplete(struct _QUEUE_HEAD * QueueHead); - virtual UCHAR GetInterval(); - virtual USB_DEVICE_SPEED GetDeviceSpeed(); - virtual VOID CompletionCallback(); - virtual VOID FreeEndpointDescriptor(struct _UHCI_QUEUE_HEAD * OutDescriptor); + // com + IMP_IUSBREQUEST + IMP_IUHCIREQUEST // local functions ULONG InternalGetTransferType(); @@ -160,9 +150,8 @@ NTSTATUS CUSBRequest::InitializeWithSetupPacket( IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, - IN UCHAR DeviceAddress, + IN PUSBDEVICE Device, IN OPTIONAL struct _USB_ENDPOINT * EndpointDescriptor, - IN USB_DEVICE_SPEED DeviceSpeed, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer) { @@ -179,10 +168,10 @@ CUSBRequest::InitializeWithSetupPacket( m_SetupPacket = SetupPacket; m_TransferBufferLength = TransferBufferLength; m_TransferBufferMDL = TransferBuffer; - m_DeviceAddress = DeviceAddress; + m_DeviceAddress = Device->GetDeviceAddress(); m_EndpointDescriptor = EndpointDescriptor; m_TotalBytesTransferred = 0; - m_DeviceSpeed = DeviceSpeed; + m_DeviceSpeed = Device->GetSpeed(); // // Set Length Completed to 0 @@ -215,8 +204,8 @@ CUSBRequest::InitializeWithSetupPacket( NTSTATUS CUSBRequest::InitializeWithIrp( IN PDMAMEMORYMANAGER DmaManager, - IN OUT PIRP Irp, - IN USB_DEVICE_SPEED DeviceSpeed) + IN PUSBDEVICE Device, + IN OUT PIRP Irp) { PIO_STACK_LOCATION IoStack; PURB Urb; @@ -229,7 +218,7 @@ CUSBRequest::InitializeWithIrp( m_DmaManager = DmaManager; m_TotalBytesTransferred = 0; - m_DeviceSpeed = DeviceSpeed; + m_DeviceSpeed = Device->GetSpeed(); // // get current irp stack location @@ -684,32 +673,6 @@ CUSBRequest::GetResultStatus( } -//----------------------------------------------------------------------------------------- -BOOLEAN -CUSBRequest::IsRequestInitialized() -{ - if (m_Irp || m_SetupPacket) - { - // - // request is initialized - // - return TRUE; - } - - // - // request is not initialized - // - return FALSE; -} - -//----------------------------------------------------------------------------------------- -BOOLEAN -CUSBRequest::IsQueueHeadComplete( - struct _QUEUE_HEAD * QueueHead) -{ - UNIMPLEMENTED - return TRUE; -} //----------------------------------------------------------------------------------------- NTSTATUS CUSBRequest::CreateDescriptor( @@ -1248,6 +1211,7 @@ CUSBRequest::FreeEndpointDescriptor( PUHCI_TRANSFER_DESCRIPTOR Descriptor, NextDescriptor; ULONG ErrorCount; UCHAR DataToggle = 0; + ULONG Index = 0; // // grab first transfer descriptor @@ -1278,22 +1242,22 @@ CUSBRequest::FreeEndpointDescriptor( if (Descriptor->Status & TD_STATUS_ERROR_BUFFER) { - DPRINT1("[USBUHCI] Buffer Error detected in descriptor %p\n", Descriptor); + DPRINT1("[USBUHCI] Buffer Error detected in descriptor %p Index %lu\n", Descriptor, Index); m_UrbStatusCode = USBD_STATUS_DATA_BUFFER_ERROR; } else if (Descriptor->Status & TD_STATUS_ERROR_TIMEOUT) { - DPRINT1("[USBUHCI] Timeout detected in descriptor %p\n", Descriptor); + DPRINT1("[USBUHCI] Timeout detected in descriptor %p Index %lu\n", Descriptor, Index); m_UrbStatusCode = USBD_STATUS_TIMEOUT; } else if (Descriptor->Status & TD_STATUS_ERROR_NAK) { - DPRINT1("[USBUHCI] Unexpected pid detected in descriptor %p\n", Descriptor); + DPRINT1("[USBUHCI] Unexpected pid detected in descriptor %p Index %lu\n", Descriptor, Index); m_UrbStatusCode = USBD_STATUS_UNEXPECTED_PID; } else if (Descriptor->Status & TD_STATUS_ERROR_BITSTUFF) { - DPRINT1("[USBUHCI] BitStuff detected in descriptor %p\n", Descriptor); + DPRINT1("[USBUHCI] BitStuff detected in descriptor %p Index %lu\n", Descriptor, Index); m_UrbStatusCode = USBD_STATUS_BTSTUFF; } } @@ -1302,7 +1266,7 @@ CUSBRequest::FreeEndpointDescriptor( // // babble error // - DPRINT1("[USBUHCI] Babble detected in descriptor %p\n", Descriptor); + DPRINT1("[USBUHCI] Babble detected in descriptor %p Index %lu\n", Descriptor, Index); m_UrbStatusCode = USBD_STATUS_BABBLE_DETECTED; } else @@ -1310,7 +1274,7 @@ CUSBRequest::FreeEndpointDescriptor( // // stall detected // - DPRINT1("[USBUHCI] Stall detected\n"); + DPRINT1("[USBUHCI] Stall detected Descriptor %p Index %lu\n", Descriptor, Index); m_UrbStatusCode = USBD_STATUS_STALL_PID; } } @@ -1341,6 +1305,7 @@ CUSBRequest::FreeEndpointDescriptor( // move to next // Descriptor = NextDescriptor; + Index++; } // diff --git a/reactos/drivers/usb/usbuhci/usbuhci.cpp b/reactos/drivers/usb/usbuhci/usbuhci.cpp index d2fe36f0fdf..b4110fc54ec 100644 --- a/reactos/drivers/usb/usbuhci/usbuhci.cpp +++ b/reactos/drivers/usb/usbuhci/usbuhci.cpp @@ -10,116 +10,6 @@ #include "usbuhci.h" -// -// driver verifier -// -DRIVER_ADD_DEVICE UHCI_AddDevice; - -NTSTATUS -NTAPI -UHCI_AddDevice( - PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT PhysicalDeviceObject) -{ - NTSTATUS Status; - PHCDCONTROLLER HcdController; - - DPRINT1("UHCI_AddDevice\n"); - - /* first create the controller object */ - Status = CreateHCDController(&HcdController); - if (!NT_SUCCESS(Status)) - { - /* failed to create hcd */ - DPRINT1("AddDevice: Failed to create hcd with %x\n", Status); - return Status; - } - - /* initialize the hcd */ - Status = HcdController->Initialize(NULL, // FIXME - DriverObject, - PhysicalDeviceObject); - - /* check for success */ - if (!NT_SUCCESS(Status)) - { - /* failed to initialize device */ - DPRINT1("AddDevice: failed to initialize\n"); - - /* release object */ - HcdController->Release(); - } - - return Status; - -} - -NTSTATUS -NTAPI -UHCI_Dispatch( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -{ - PCOMMON_DEVICE_EXTENSION DeviceExtension; - PIO_STACK_LOCATION IoStack; - NTSTATUS Status; - - // - // get common device extension - // - DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - // - // get current stack location - // - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // - // sanity checks - // - PC_ASSERT(DeviceExtension->Dispatcher); - - switch(IoStack->MajorFunction) - { - case IRP_MJ_PNP: - { - // - // dispatch pnp - // - return DeviceExtension->Dispatcher->HandlePnp(DeviceObject, Irp); - } - - case IRP_MJ_POWER: - { - // - // dispatch pnp - // - return DeviceExtension->Dispatcher->HandlePower(DeviceObject, Irp); - } - case IRP_MJ_INTERNAL_DEVICE_CONTROL: - case IRP_MJ_DEVICE_CONTROL: - { - // - // dispatch pnp - // - return DeviceExtension->Dispatcher->HandleDeviceControl(DeviceObject, Irp); - } - default: - { - DPRINT1("UHCI_Dispatch> Major %lu Minor %lu unhandeled\n", IoStack->MajorFunction, IoStack->MinorFunction); - Status = STATUS_SUCCESS; - } - } - - // - // complete request - // - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; -} - extern "C" NTSTATUS @@ -128,16 +18,22 @@ DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { - DPRINT1("[UHCI] Driver Entry\n"); + /* initialize driver object*/ - DriverObject->DriverExtension->AddDevice = UHCI_AddDevice; - - DriverObject->MajorFunction[IRP_MJ_CREATE] = UHCI_Dispatch; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = UHCI_Dispatch; - DriverObject->MajorFunction[IRP_MJ_CLEANUP] = UHCI_Dispatch; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = UHCI_Dispatch; - DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = UHCI_Dispatch; - DriverObject->MajorFunction[IRP_MJ_PNP] = UHCI_Dispatch; + DriverObject->DriverExtension->AddDevice = USBLIB_AddDevice; + DriverObject->MajorFunction[IRP_MJ_CREATE] = USBLIB_Dispatch; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBLIB_Dispatch; + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = USBLIB_Dispatch; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBLIB_Dispatch; + DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = USBLIB_Dispatch; + DriverObject->MajorFunction[IRP_MJ_PNP] = USBLIB_Dispatch; return STATUS_SUCCESS; } + +extern "C" { + void free(void * ptr) + { + ExFreePool(ptr); + } +} diff --git a/reactos/drivers/usb/usbuhci/usbuhci.h b/reactos/drivers/usb/usbuhci/usbuhci.h index 3754373db42..c4e131dde8b 100644 --- a/reactos/drivers/usb/usbuhci/usbuhci.h +++ b/reactos/drivers/usb/usbuhci/usbuhci.h @@ -46,17 +46,10 @@ extern #define C_PORT_OVER_CURRENT 19 #define C_PORT_RESET 20 -typedef struct -{ - BOOLEAN IsFDO; // is device a FDO or PDO - BOOLEAN IsHub; // is device a hub / child - not yet used - PDISPATCHIRP Dispatcher; // dispatches the code -}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION; - // // tag for allocations // -#define TAG_USBUHCI 'ICHO' +#define TAG_USBUHCI 'ICHU' // // assert for c++ - taken from portcls @@ -65,38 +58,11 @@ typedef struct (VOID)((!(exp)) ? \ RtlAssert((PVOID) #exp, (PVOID)__FILE__, __LINE__, NULL ), FALSE : TRUE) -// -// hcd_controller.cpp -// -NTSTATUS CreateHCDController(PHCDCONTROLLER *HcdController); - // // hardware.cpp // NTSTATUS CreateUSBHardware(PUSBHARDWAREDEVICE *OutHardware); -// -// misc.cpp -// -NTSTATUS NTAPI SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp); -NTSTATUS NTAPI GetBusInterface(PDEVICE_OBJECT DeviceObject, PBUS_INTERFACE_STANDARD busInterface); - -// -// root_hub_controller.cpp -// -NTSTATUS CreateHubController(PHUBCONTROLLER * OutHubController); - -// -// memory_manager.cpp -// -NTSTATUS CreateDMAMemoryManager(PDMAMEMORYMANAGER *OutMemoryManager); - - -// -// usb_device.cpp -// -NTSTATUS CreateUSBDevice(PUSBDEVICE *OutDevice); - // // usb_queue.cpp // @@ -107,26 +73,4 @@ NTSTATUS CreateUSBQueue(PUSBQUEUE *OutUsbQueue); // NTSTATUS InternalCreateUSBRequest(PUSBREQUEST *OutRequest); - -typedef struct _USB_ENDPOINT -{ - USB_ENDPOINT_DESCRIPTOR EndPointDescriptor; - UCHAR HubAddress; - UCHAR HubPort; - UCHAR DataToggle; -} USB_ENDPOINT, *PUSB_ENDPOINT; - -typedef struct _USB_INTERFACE -{ - USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; - USB_ENDPOINT *EndPoints; -} USB_INTERFACE, *PUSB_INTERFACE; - -typedef struct _USB_CONFIGURATION -{ - PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; - USB_INTERFACE *Interfaces; -} USB_CONFIGURATION, *PUSB_CONFIGURATION; - - #endif