#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
{
/* 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;
}
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})
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();
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
//
// 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");
return STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS
-CUSBHardwareDevice::HandlePower(
- PIRP Irp)
-{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
-}
-
NTSTATUS
CUSBHardwareDevice::GetDeviceDetails(
OUT OPTIONAL PUSHORT VendorId,
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(
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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);
-}
#ifndef INTERFACES_HPP
#define INTERFACES_HPP
+#include "libusb.h"
+
//---------------------------------------------------------------------------
//
// Object Hierachy
//
-//=========================================================================================
-//
-// 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;
-//=========================================================================================
-//
-// class IUSBHardwareDevice
-//
-// Description: This class provides access to the usb hardware controller
-//
-
struct IDMAMemoryManager;
struct IUSBQueue;
-DECLARE_INTERFACE_(IUSBHardwareDevice, IUnknown)
-{
- 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;
-
-//-----------------------------------------------------------------------------------------
+// class IUSBHardwareDevice
//
-// ReleaseLock
+// Description: This class provides access to the usb hardware controller
//
-// Description: releases the device lock
-
- virtual void ReleaseDeviceLock(KIRQL OldLevel) = 0;
-
-};
-typedef IUSBHardwareDevice *PUSBHARDWAREDEVICE;
+#define DEFINE_ABSTRACT_USBUHCIHARDWAREDEVICE() \
+ STDMETHOD_(VOID, GetQueueHead)( THIS_ \
+ IN ULONG QueueHeadIndex, \
+ IN struct _UHCI_QUEUE_HEAD **OutQueueHead) PURE;
+#define IMP_IUHCIHARDWAREDEVICE \
+ STDMETHODIMP_(VOID) GetQueueHead( \
+ IN ULONG QueueHeadIndex, \
+ IN struct _UHCI_QUEUE_HEAD **OutQueueHead);
-//=========================================================================================
-//
-// 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)
+DECLARE_INTERFACE_(IUHCIHardwareDevice, IUSBHardwareDevice)
{
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;
-
+ DEFINE_ABSTRACT_USBHARDWAREDEVICE()
+ DEFINE_ABSTRACT_USBUHCIHARDWAREDEVICE()
};
-typedef IDMAMemoryManager *PDMAMEMORYMANAGER;
-
+typedef IUHCIHardwareDevice *PUHCIHARDWAREDEVICE;
//=========================================================================================
//
// CancelCallback routine is invoked.
//
-DECLARE_INTERFACE_(IUSBRequest, IUnknown)
-{
- 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;
-};
-
-
-typedef IUSBRequest *PUSBREQUEST;
-
-//=========================================================================================
-//
-// class IUSBQueue
-//
-// Description: This class manages pending requests
-//
-
-DECLARE_INTERFACE_(IUSBQueue, 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()
-
-//-----------------------------------------------------------------------------------------
-//
-// 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_USBREQUEST()
+ DEFINE_ABSTRACT_USBUHCIREQUEST()
};
-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;
+typedef IUHCIRequest *PUHCIREQUEST;
//=========================================================================================
//
-// class IDispatchIrp
+// class IUSBQueue
//
-// Description: This class is used to handle irp dispatch requests
+// Description: This class manages pending 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;
+#define DEFINE_ABSTRACT_USBUHCIQUEUE() \
+ STDMETHOD_(VOID, TransferInterrupt)( \
+ IN UCHAR ErrorInterrupt) PURE;
-//=========================================================================================
-//
-// class IUSBDevice
-//
-// Description: This class is used to abstract details of a usb device
-//
+#define IMP_IUHCIQUEUE \
+ STDMETHODIMP_(VOID) TransferInterrupt( \
+ IN UCHAR ErrorInterrupt);
-DECLARE_INTERFACE_(IUSBDevice, IUnknown)
+DECLARE_INTERFACE_(IUHCIQueue, IUSBQueue)
{
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;
-
-
+ DEFINE_ABSTRACT_USBQUEUE()
+ DEFINE_ABSTRACT_USBUHCIQUEUE()
};
-typedef IUSBDevice *PUSBDEVICE;
+typedef IUHCIQueue *PUHCIQUEUE;
#endif
+++ /dev/null
-/*
- * 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;
-}
-
+++ /dev/null
-/*
- * 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;
-}
-
+++ /dev/null
-/*
- * 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();
-
- }
-}
-
+++ /dev/null
-/*
- * 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;
-}
-
#include "usbuhci.h"
#include "hardware.h"
-class CUSBQueue : public IUSBQueue
+class CUSBQueue : public IUHCIQueue
{
public:
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
}
// 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);
protected:
LONG m_Ref; // reference count
KSPIN_LOCK m_Lock; // list lock
- PUSBHARDWAREDEVICE m_Hardware; // hardware
+ PUHCIHARDWAREDEVICE m_Hardware; // hardware
};
IN PDMAMEMORYMANAGER MemManager,
IN OPTIONAL PKSPIN_LOCK Lock)
{
- //
- // initialize spinlock
- //
- KeInitializeSpinLock(&m_Lock);
//
// store hardware
//
- m_Hardware = Hardware;
+ m_Hardware = PUHCIHARDWAREDEVICE(Hardware);
- return STATUS_SUCCESS;
-}
-
-ULONG
-CUSBQueue::GetPendingRequestCount()
-{
//
- // Loop through the pending list and iterrate one for each QueueHead that
- // has a IRP to complete.
+ // initialize spinlock
//
-
- return 0;
+ KeInitializeSpinLock(&m_Lock);
+ return STATUS_SUCCESS;
}
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)
{
//
NTSTATUS
CUSBQueue::AddUSBRequest(
- IUSBRequest * Request)
+ IUSBRequest * Req)
{
PUHCI_QUEUE_HEAD NewQueueHead;
NTSTATUS Status;
+ PUHCIREQUEST Request;
+
+ // get request
+ Request = (PUHCIREQUEST)Req;
//
// get queue head
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);
IN PUHCI_QUEUE_HEAD PreviousQueueHead,
OUT PUHCI_QUEUE_HEAD *NextQueueHead)
{
- PUSBREQUEST Request;
+ PUHCIREQUEST Request;
PUHCI_QUEUE_HEAD NewQueueHead;
NTSTATUS Status;
//
// the queue head is complete, is the transfer now completed?
//
- Request = (PUSBREQUEST)QueueHead->Request;
+ Request = (PUHCIREQUEST)QueueHead->Request;
ASSERT(Request);
//
#include "usbuhci.h"
#include "hardware.h"
-class CUSBRequest : public IUSBRequest
+class CUSBRequest : public IUHCIRequest
{
public:
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
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();
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)
{
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
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;
m_DmaManager = DmaManager;
m_TotalBytesTransferred = 0;
- m_DeviceSpeed = DeviceSpeed;
+ m_DeviceSpeed = Device->GetSpeed();
//
// get current irp stack location
}
-//-----------------------------------------------------------------------------------------
-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(
PUHCI_TRANSFER_DESCRIPTOR Descriptor, NextDescriptor;
ULONG ErrorCount;
UCHAR DataToggle = 0;
+ ULONG Index = 0;
//
// grab first transfer descriptor
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;
}
}
//
// 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
//
// stall detected
//
- DPRINT1("[USBUHCI] Stall detected\n");
+ DPRINT1("[USBUHCI] Stall detected Descriptor %p Index %lu\n", Descriptor, Index);
m_UrbStatusCode = USBD_STATUS_STALL_PID;
}
}
// move to next
//
Descriptor = NextDescriptor;
+ Index++;
}
//
#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
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;
+ /* initialize driver object*/
+ 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);
+ }
+}
#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
(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
//
//
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