mirror of
https://github.com/reactos/reactos.git
synced 2024-08-19 09:59:44 +00:00
[USBOHCI]
- Remove duplicated code [USBUHCI] - Use libusb svn path=/trunk/; revision=55909
This commit is contained in:
parent
300e78822d
commit
6a2de16a81
|
@ -10,117 +10,6 @@
|
||||||
|
|
||||||
#include "usbohci.h"
|
#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
|
extern
|
||||||
"C"
|
"C"
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -131,15 +20,14 @@ DriverEntry(
|
||||||
{
|
{
|
||||||
|
|
||||||
/* initialize driver object*/
|
/* initialize driver object*/
|
||||||
DriverObject->DriverExtension->AddDevice = OHCI_AddDevice;
|
DriverObject->DriverExtension->AddDevice = USBLIB_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->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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,20 +4,18 @@ set_cpp()
|
||||||
remove_definitions(-D_WIN32_WINNT=0x502)
|
remove_definitions(-D_WIN32_WINNT=0x502)
|
||||||
add_definitions(-D_WIN32_WINNT=0x600)
|
add_definitions(-D_WIN32_WINNT=0x600)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${REACTOS_SOURCE_DIR}/lib/drivers/libusb)
|
||||||
|
|
||||||
add_library(usbuhci SHARED
|
add_library(usbuhci SHARED
|
||||||
usbuhci.cpp
|
usbuhci.cpp
|
||||||
usb_device.cpp
|
|
||||||
usb_request.cpp
|
usb_request.cpp
|
||||||
usb_queue.cpp
|
usb_queue.cpp
|
||||||
hcd_controller.cpp
|
|
||||||
hardware.cpp
|
hardware.cpp
|
||||||
misc.cpp
|
|
||||||
purecall.cpp
|
|
||||||
hub_controller.cpp
|
|
||||||
memory_manager.cpp
|
|
||||||
usbuhci.rc)
|
usbuhci.rc)
|
||||||
|
|
||||||
target_link_libraries(usbuhci
|
target_link_libraries(usbuhci
|
||||||
|
libusb
|
||||||
libcntpr
|
libcntpr
|
||||||
${PSEH_LIB})
|
${PSEH_LIB})
|
||||||
|
|
||||||
|
|
|
@ -65,32 +65,13 @@ public:
|
||||||
return m_Ref;
|
return m_Ref;
|
||||||
}
|
}
|
||||||
// com
|
// com
|
||||||
NTSTATUS Initialize(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT FunctionalDeviceObject, PDEVICE_OBJECT PhysicalDeviceObject, PDEVICE_OBJECT LowerDeviceObject);
|
IMP_IUSBHARDWAREDEVICE
|
||||||
NTSTATUS PnpStart(PCM_RESOURCE_LIST RawResources, PCM_RESOURCE_LIST TranslatedResources);
|
IMP_IUHCIHARDWAREDEVICE
|
||||||
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);
|
|
||||||
|
|
||||||
|
// local
|
||||||
NTSTATUS StartController();
|
NTSTATUS StartController();
|
||||||
NTSTATUS StopController();
|
NTSTATUS StopController();
|
||||||
NTSTATUS ResetController();
|
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();
|
VOID GlobalReset();
|
||||||
BOOLEAN InterruptService();
|
BOOLEAN InterruptService();
|
||||||
NTSTATUS InitializeController();
|
NTSTATUS InitializeController();
|
||||||
|
@ -127,7 +108,7 @@ protected:
|
||||||
ULONG m_MapRegisters; // map registers count
|
ULONG m_MapRegisters; // map registers count
|
||||||
USHORT m_VendorID; // vendor id
|
USHORT m_VendorID; // vendor id
|
||||||
USHORT m_DeviceID; // device id
|
USHORT m_DeviceID; // device id
|
||||||
PUSBQUEUE m_UsbQueue; // usb request queue
|
PUHCIQUEUE m_UsbQueue; // usb request queue
|
||||||
ULONG m_NumberOfPorts; // number of ports
|
ULONG m_NumberOfPorts; // number of ports
|
||||||
PDMAMEMORYMANAGER m_MemoryManager; // memory manager
|
PDMAMEMORYMANAGER m_MemoryManager; // memory manager
|
||||||
HD_INIT_CALLBACK* m_SCECallBack; // status change callback routine
|
HD_INIT_CALLBACK* m_SCECallBack; // status change callback routine
|
||||||
|
@ -191,7 +172,7 @@ CUSBHardwareDevice::Initialize(
|
||||||
//
|
//
|
||||||
// Create the UsbQueue class that will handle the Asynchronous and Periodic Schedules
|
// 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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to create UsbQueue!\n");
|
DPRINT1("Failed to create UsbQueue!\n");
|
||||||
|
@ -412,14 +393,6 @@ CUSBHardwareDevice::PnpStop(void)
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CUSBHardwareDevice::HandlePower(
|
|
||||||
PIRP Irp)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CUSBHardwareDevice::GetDeviceDetails(
|
CUSBHardwareDevice::GetDeviceDetails(
|
||||||
OUT OPTIONAL PUSHORT VendorId,
|
OUT OPTIONAL PUSHORT VendorId,
|
||||||
|
@ -1232,29 +1205,6 @@ CUSBHardwareDevice::SetStatusChangeEndpointCallBack(
|
||||||
m_SCEContext = Context;
|
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
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
InterruptServiceRoutine(
|
InterruptServiceRoutine(
|
||||||
|
|
|
@ -1,781 +0,0 @@
|
||||||
/*
|
|
||||||
* PROJECT: ReactOS Universal Serial Bus Host Controller Interface
|
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
|
||||||
* FILE: drivers/usb/usbuhci/hcd_controller.cpp
|
|
||||||
* PURPOSE: USB UHCI device driver.
|
|
||||||
* PROGRAMMERS:
|
|
||||||
* Michael Martin (michael.martin@reactos.org)
|
|
||||||
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define INITGUID
|
|
||||||
#include "usbuhci.h"
|
|
||||||
|
|
||||||
class CHCDController : public IHCDController,
|
|
||||||
public IDispatchIrp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
|
||||||
|
|
||||||
STDMETHODIMP_(ULONG) AddRef()
|
|
||||||
{
|
|
||||||
InterlockedIncrement(&m_Ref);
|
|
||||||
return m_Ref;
|
|
||||||
}
|
|
||||||
STDMETHODIMP_(ULONG) Release()
|
|
||||||
{
|
|
||||||
InterlockedDecrement(&m_Ref);
|
|
||||||
|
|
||||||
if (!m_Ref)
|
|
||||||
{
|
|
||||||
delete this;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return m_Ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
// IHCDController interface functions
|
|
||||||
NTSTATUS Initialize(IN PROOTHDCCONTROLLER RootHCDController, IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject);
|
|
||||||
|
|
||||||
// IDispatchIrp interface functions
|
|
||||||
NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
|
||||||
NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
|
||||||
NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
|
||||||
|
|
||||||
// local functions
|
|
||||||
NTSTATUS CreateFDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject);
|
|
||||||
NTSTATUS SetSymbolicLink(BOOLEAN Enable);
|
|
||||||
|
|
||||||
// constructor / destructor
|
|
||||||
CHCDController(IUnknown *OuterUnknown){}
|
|
||||||
virtual ~CHCDController(){}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
LONG m_Ref;
|
|
||||||
PROOTHDCCONTROLLER m_RootController;
|
|
||||||
PDRIVER_OBJECT m_DriverObject;
|
|
||||||
PDEVICE_OBJECT m_PhysicalDeviceObject;
|
|
||||||
PDEVICE_OBJECT m_FunctionalDeviceObject;
|
|
||||||
PDEVICE_OBJECT m_NextDeviceObject;
|
|
||||||
PUSBHARDWAREDEVICE m_Hardware;
|
|
||||||
PHUBCONTROLLER m_HubController;
|
|
||||||
ULONG m_FDODeviceNumber;
|
|
||||||
};
|
|
||||||
|
|
||||||
//=================================================================================================
|
|
||||||
// COM
|
|
||||||
//
|
|
||||||
NTSTATUS
|
|
||||||
STDMETHODCALLTYPE
|
|
||||||
CHCDController::QueryInterface(
|
|
||||||
IN REFIID refiid,
|
|
||||||
OUT PVOID* Output)
|
|
||||||
{
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------------
|
|
||||||
NTSTATUS
|
|
||||||
CHCDController::Initialize(
|
|
||||||
IN PROOTHDCCONTROLLER RootHCDController,
|
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
|
||||||
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
|
|
||||||
//
|
|
||||||
// create usb hardware
|
|
||||||
//
|
|
||||||
Status = CreateUSBHardware(&m_Hardware);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// failed to create hardware object
|
|
||||||
//
|
|
||||||
DPRINT1("Failed to create hardware object\n");
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// initialize members
|
|
||||||
//
|
|
||||||
m_DriverObject = DriverObject;
|
|
||||||
m_PhysicalDeviceObject = PhysicalDeviceObject;
|
|
||||||
m_RootController = RootHCDController;
|
|
||||||
|
|
||||||
//
|
|
||||||
// create FDO
|
|
||||||
//
|
|
||||||
Status = CreateFDO(m_DriverObject, &m_FunctionalDeviceObject);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// failed to create PDO
|
|
||||||
//
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// now attach to device stack
|
|
||||||
//
|
|
||||||
m_NextDeviceObject = IoAttachDeviceToDeviceStack(m_FunctionalDeviceObject, m_PhysicalDeviceObject);
|
|
||||||
if (!m_NextDeviceObject)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// failed to attach to device stack
|
|
||||||
//
|
|
||||||
IoDeleteDevice(m_FunctionalDeviceObject);
|
|
||||||
m_FunctionalDeviceObject = 0;
|
|
||||||
|
|
||||||
return STATUS_NO_SUCH_DEVICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// initialize hardware object
|
|
||||||
//
|
|
||||||
Status = m_Hardware->Initialize(m_DriverObject, m_FunctionalDeviceObject, m_PhysicalDeviceObject, m_NextDeviceObject);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to initialize hardware object %x\n", Status);
|
|
||||||
|
|
||||||
//
|
|
||||||
// failed to initialize hardware object, detach from device stack
|
|
||||||
//
|
|
||||||
IoDetachDevice(m_NextDeviceObject);
|
|
||||||
|
|
||||||
//
|
|
||||||
// now delete the device
|
|
||||||
//
|
|
||||||
IoDeleteDevice(m_FunctionalDeviceObject);
|
|
||||||
|
|
||||||
//
|
|
||||||
// nullify pointers :)
|
|
||||||
//
|
|
||||||
m_FunctionalDeviceObject = 0;
|
|
||||||
m_NextDeviceObject = 0;
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// set device flags
|
|
||||||
//
|
|
||||||
m_FunctionalDeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// get device extension
|
|
||||||
//
|
|
||||||
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)m_FunctionalDeviceObject->DeviceExtension;
|
|
||||||
PC_ASSERT(DeviceExtension);
|
|
||||||
|
|
||||||
//
|
|
||||||
// initialize device extension
|
|
||||||
//
|
|
||||||
DeviceExtension->IsFDO = TRUE;
|
|
||||||
DeviceExtension->IsHub = FALSE;
|
|
||||||
DeviceExtension->Dispatcher = PDISPATCHIRP(this);
|
|
||||||
|
|
||||||
//
|
|
||||||
// device is initialized
|
|
||||||
//
|
|
||||||
m_FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// is there a root controller
|
|
||||||
//
|
|
||||||
if (m_RootController)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// add reference
|
|
||||||
//
|
|
||||||
m_RootController->AddRef();
|
|
||||||
|
|
||||||
//
|
|
||||||
// register with controller
|
|
||||||
//
|
|
||||||
m_RootController->RegisterHCD(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// done
|
|
||||||
//
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------------
|
|
||||||
NTSTATUS
|
|
||||||
CHCDController::HandleDeviceControl(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
PIO_STACK_LOCATION IoStack;
|
|
||||||
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
PUSB_HCD_DRIVERKEY_NAME DriverKey;
|
|
||||||
ULONG ResultLength;
|
|
||||||
|
|
||||||
//
|
|
||||||
// get current stack location
|
|
||||||
//
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
|
|
||||||
//
|
|
||||||
// get device extension
|
|
||||||
//
|
|
||||||
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
||||||
|
|
||||||
//
|
|
||||||
// sanity check
|
|
||||||
//
|
|
||||||
PC_ASSERT(DeviceExtension->IsFDO);
|
|
||||||
|
|
||||||
DPRINT("HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu\n",
|
|
||||||
IoStack->Parameters.DeviceIoControl.IoControlCode,
|
|
||||||
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
|
||||||
IoStack->Parameters.DeviceIoControl.OutputBufferLength);
|
|
||||||
|
|
||||||
//
|
|
||||||
// perform ioctl for FDO
|
|
||||||
//
|
|
||||||
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_HCD_DRIVERKEY_NAME)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// check if sizee is at least >= USB_HCD_DRIVERKEY_NAME
|
|
||||||
//
|
|
||||||
if(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(USB_HCD_DRIVERKEY_NAME))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// get device property size
|
|
||||||
//
|
|
||||||
Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, 0, NULL, &ResultLength);
|
|
||||||
|
|
||||||
//
|
|
||||||
// get input buffer
|
|
||||||
//
|
|
||||||
DriverKey = (PUSB_HCD_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer;
|
|
||||||
|
|
||||||
//
|
|
||||||
// check result
|
|
||||||
//
|
|
||||||
if (Status == STATUS_BUFFER_TOO_SMALL)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// does the caller provide enough buffer space
|
|
||||||
//
|
|
||||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= ResultLength)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// it does
|
|
||||||
//
|
|
||||||
Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG), DriverKey->DriverKeyName, &ResultLength);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// informal debug print
|
|
||||||
//
|
|
||||||
DPRINT1("Result %S\n", DriverKey->DriverKeyName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// store result
|
|
||||||
//
|
|
||||||
DriverKey->ActualLength = ResultLength + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + sizeof(WCHAR);
|
|
||||||
Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// buffer is certainly too small
|
|
||||||
//
|
|
||||||
Status = STATUS_BUFFER_OVERFLOW;
|
|
||||||
Irp->IoStatus.Information = sizeof(USB_HCD_DRIVERKEY_NAME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_ROOT_HUB_NAME)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// check if sizee is at least >= USB_HCD_DRIVERKEY_NAME
|
|
||||||
//
|
|
||||||
if(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(USB_HCD_DRIVERKEY_NAME))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// sanity check
|
|
||||||
//
|
|
||||||
PC_ASSERT(m_HubController);
|
|
||||||
|
|
||||||
//
|
|
||||||
// get input buffer
|
|
||||||
//
|
|
||||||
DriverKey = (PUSB_HCD_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer;
|
|
||||||
|
|
||||||
//
|
|
||||||
// get symbolic link
|
|
||||||
//
|
|
||||||
Status = m_HubController->GetHubControllerSymbolicLink(IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG), DriverKey->DriverKeyName, &ResultLength);
|
|
||||||
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// null terminate it
|
|
||||||
//
|
|
||||||
PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG) - sizeof(WCHAR) >= ResultLength);
|
|
||||||
|
|
||||||
DriverKey->DriverKeyName[ResultLength / sizeof(WCHAR)] = L'\0';
|
|
||||||
DPRINT1("Result %S\n", DriverKey->DriverKeyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// store result
|
|
||||||
//
|
|
||||||
DriverKey->ActualLength = ResultLength + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + sizeof(WCHAR);
|
|
||||||
Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// buffer is certainly too small
|
|
||||||
//
|
|
||||||
Status = STATUS_BUFFER_OVERFLOW;
|
|
||||||
Irp->IoStatus.Information = sizeof(USB_HCD_DRIVERKEY_NAME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// complete the request
|
|
||||||
//
|
|
||||||
Irp->IoStatus.Status = Status;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
|
|
||||||
//
|
|
||||||
// done
|
|
||||||
//
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CHCDController::HandlePnp(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
PIO_STACK_LOCATION IoStack;
|
|
||||||
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
|
||||||
PCM_RESOURCE_LIST RawResourceList;
|
|
||||||
PCM_RESOURCE_LIST TranslatedResourceList;
|
|
||||||
PDEVICE_RELATIONS DeviceRelations;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
//
|
|
||||||
// get device extension
|
|
||||||
//
|
|
||||||
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
||||||
|
|
||||||
//
|
|
||||||
// sanity check
|
|
||||||
//
|
|
||||||
PC_ASSERT(DeviceExtension->IsFDO);
|
|
||||||
|
|
||||||
//
|
|
||||||
// get current stack location
|
|
||||||
//
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
|
|
||||||
switch(IoStack->MinorFunction)
|
|
||||||
{
|
|
||||||
case IRP_MN_START_DEVICE:
|
|
||||||
{
|
|
||||||
DPRINT("CHCDController::HandlePnp IRP_MN_START FDO\n");
|
|
||||||
|
|
||||||
//
|
|
||||||
// first start lower device object
|
|
||||||
//
|
|
||||||
Status = SyncForwardIrp(m_NextDeviceObject, Irp);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// operation succeeded, lets start the device
|
|
||||||
//
|
|
||||||
RawResourceList = IoStack->Parameters.StartDevice.AllocatedResources;
|
|
||||||
TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
|
|
||||||
|
|
||||||
if (m_Hardware)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// start the hardware
|
|
||||||
//
|
|
||||||
Status = m_Hardware->PnpStart(RawResourceList, TranslatedResourceList);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// enable symbolic link
|
|
||||||
//
|
|
||||||
Status = SetSymbolicLink(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("CHCDController::HandlePnp IRP_MN_START FDO: Status %x\n", Status);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
|
||||||
{
|
|
||||||
DPRINT("CHCDController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %lx\n", IoStack->Parameters.QueryDeviceRelations.Type);
|
|
||||||
|
|
||||||
if (m_HubController == NULL)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// create hub controller
|
|
||||||
//
|
|
||||||
Status = CreateHubController(&m_HubController);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// failed to create hub controller
|
|
||||||
//
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// initialize hub controller
|
|
||||||
//
|
|
||||||
Status = m_HubController->Initialize(m_DriverObject, PHCDCONTROLLER(this), m_Hardware, TRUE, 0 /* FIXME*/);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// failed to initialize hub controller
|
|
||||||
//
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// add reference to prevent it from getting deleting while hub driver adds / removes references
|
|
||||||
//
|
|
||||||
m_HubController->AddRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// allocate device relations
|
|
||||||
//
|
|
||||||
DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
|
|
||||||
|
|
||||||
if (!DeviceRelations)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// no memory
|
|
||||||
//
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// init device relations
|
|
||||||
//
|
|
||||||
DeviceRelations->Count = 1;
|
|
||||||
Status = m_HubController->GetHubControllerDeviceObject(&DeviceRelations->Objects [0]);
|
|
||||||
|
|
||||||
//
|
|
||||||
// sanity check
|
|
||||||
//
|
|
||||||
PC_ASSERT(Status == STATUS_SUCCESS);
|
|
||||||
|
|
||||||
ObReferenceObject(DeviceRelations->Objects [0]);
|
|
||||||
|
|
||||||
//
|
|
||||||
// store result
|
|
||||||
//
|
|
||||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// not supported
|
|
||||||
//
|
|
||||||
Status = STATUS_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IRP_MN_STOP_DEVICE:
|
|
||||||
{
|
|
||||||
DPRINT("CHCDController::HandlePnp IRP_MN_STOP_DEVICE\n");
|
|
||||||
|
|
||||||
if (m_Hardware)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// stop the hardware
|
|
||||||
//
|
|
||||||
Status = m_Hardware->PnpStop();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// fake success
|
|
||||||
//
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// stop lower device
|
|
||||||
//
|
|
||||||
Status = SyncForwardIrp(m_NextDeviceObject, Irp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
|
||||||
case IRP_MN_QUERY_STOP_DEVICE:
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
//
|
|
||||||
// sure
|
|
||||||
//
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
//
|
|
||||||
// forward irp to next device object
|
|
||||||
//
|
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
|
||||||
return IoCallDriver(m_NextDeviceObject, Irp);
|
|
||||||
#else
|
|
||||||
DPRINT1("Denying controller removal due to reinitialization bugs\n");
|
|
||||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
case IRP_MN_REMOVE_DEVICE:
|
|
||||||
{
|
|
||||||
DPRINT("CHCDController::HandlePnp IRP_MN_REMOVE_DEVICE FDO\n");
|
|
||||||
|
|
||||||
//
|
|
||||||
// delete the symbolic link
|
|
||||||
//
|
|
||||||
SetSymbolicLink(FALSE);
|
|
||||||
|
|
||||||
//
|
|
||||||
// forward irp to next device object
|
|
||||||
//
|
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
|
||||||
IoCallDriver(m_NextDeviceObject, Irp);
|
|
||||||
|
|
||||||
//
|
|
||||||
// detach device from device stack
|
|
||||||
//
|
|
||||||
IoDetachDevice(m_NextDeviceObject);
|
|
||||||
|
|
||||||
//
|
|
||||||
// delete device
|
|
||||||
//
|
|
||||||
IoDeleteDevice(m_FunctionalDeviceObject);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// forward irp to next device object
|
|
||||||
//
|
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
|
||||||
return IoCallDriver(m_NextDeviceObject, Irp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// store result and complete request
|
|
||||||
//
|
|
||||||
Irp->IoStatus.Status = Status;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CHCDController::HandlePower(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CHCDController::CreateFDO(
|
|
||||||
PDRIVER_OBJECT DriverObject,
|
|
||||||
PDEVICE_OBJECT * OutDeviceObject)
|
|
||||||
{
|
|
||||||
WCHAR CharDeviceName[64];
|
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG UsbDeviceNumber = 0;
|
|
||||||
UNICODE_STRING DeviceName;
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// construct device name
|
|
||||||
//
|
|
||||||
swprintf(CharDeviceName, L"\\Device\\USBFDO-%d", UsbDeviceNumber);
|
|
||||||
|
|
||||||
//
|
|
||||||
// initialize device name
|
|
||||||
//
|
|
||||||
RtlInitUnicodeString(&DeviceName, CharDeviceName);
|
|
||||||
|
|
||||||
//
|
|
||||||
// create device
|
|
||||||
//
|
|
||||||
Status = IoCreateDevice(DriverObject,
|
|
||||||
sizeof(COMMON_DEVICE_EXTENSION),
|
|
||||||
&DeviceName,
|
|
||||||
FILE_DEVICE_CONTROLLER,
|
|
||||||
0,
|
|
||||||
FALSE,
|
|
||||||
OutDeviceObject);
|
|
||||||
|
|
||||||
//
|
|
||||||
// check for success
|
|
||||||
//
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
break;
|
|
||||||
|
|
||||||
//
|
|
||||||
// is there a device object with that same name
|
|
||||||
//
|
|
||||||
if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Try the next name
|
|
||||||
//
|
|
||||||
UsbDeviceNumber++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// bail out on other errors
|
|
||||||
//
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("CreateFDO: Failed to create %wZ, Status %x\n", &DeviceName, Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// store FDO number
|
|
||||||
//
|
|
||||||
m_FDODeviceNumber = UsbDeviceNumber;
|
|
||||||
|
|
||||||
DPRINT("CreateFDO: DeviceName %wZ\n", &DeviceName);
|
|
||||||
|
|
||||||
/* done */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CHCDController::SetSymbolicLink(
|
|
||||||
BOOLEAN Enable)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
WCHAR LinkName[32];
|
|
||||||
WCHAR FDOName[32];
|
|
||||||
UNICODE_STRING Link, FDO;
|
|
||||||
|
|
||||||
if (Enable)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// create legacy link
|
|
||||||
//
|
|
||||||
swprintf(LinkName, L"\\DosDevices\\HCD%d", m_FDODeviceNumber);
|
|
||||||
swprintf(FDOName, L"\\Device\\USBFDO-%d", m_FDODeviceNumber);
|
|
||||||
RtlInitUnicodeString(&Link, LinkName);
|
|
||||||
RtlInitUnicodeString(&FDO, FDOName);
|
|
||||||
|
|
||||||
//
|
|
||||||
// create symbolic link
|
|
||||||
//
|
|
||||||
Status = IoCreateSymbolicLink(&Link, &FDO);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// FIXME: handle me
|
|
||||||
//
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// create legacy link
|
|
||||||
//
|
|
||||||
swprintf(LinkName, L"\\DosDevices\\HCD%d", m_FDODeviceNumber);
|
|
||||||
RtlInitUnicodeString(&Link, LinkName);
|
|
||||||
|
|
||||||
//
|
|
||||||
// now delete the symbolic link
|
|
||||||
//
|
|
||||||
Status = IoDeleteSymbolicLink(&Link);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// FIXME: handle me
|
|
||||||
//
|
|
||||||
ASSERT(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// done
|
|
||||||
//
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CreateHCDController(
|
|
||||||
PHCDCONTROLLER *OutHcdController)
|
|
||||||
{
|
|
||||||
PHCDCONTROLLER This;
|
|
||||||
|
|
||||||
//
|
|
||||||
// allocate controller
|
|
||||||
//
|
|
||||||
This = new(NonPagedPool, TAG_USBUHCI) CHCDController(0);
|
|
||||||
if (!This)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// failed to allocate
|
|
||||||
//
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// add reference count
|
|
||||||
//
|
|
||||||
This->AddRef();
|
|
||||||
|
|
||||||
//
|
|
||||||
// return result
|
|
||||||
//
|
|
||||||
*OutHcdController = (PHCDCONTROLLER)This;
|
|
||||||
|
|
||||||
//
|
|
||||||
// done
|
|
||||||
//
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,8 @@
|
||||||
#ifndef INTERFACES_HPP
|
#ifndef INTERFACES_HPP
|
||||||
#define INTERFACES_HPP
|
#define INTERFACES_HPP
|
||||||
|
|
||||||
|
#include "libusb.h"
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Object Hierachy
|
// Object Hierachy
|
||||||
|
@ -30,85 +32,10 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
//=========================================================================================
|
|
||||||
//
|
|
||||||
// class IRootHCDController
|
|
||||||
//
|
|
||||||
// Description: This class serves as the root host controller. The host controller mantains
|
|
||||||
// a list of registered controllers and provides support functions for the host controllers
|
|
||||||
|
|
||||||
struct IHCDController;
|
|
||||||
struct _USB_ENDPOINT;
|
|
||||||
|
|
||||||
DECLARE_INTERFACE_(IRootHCDController, IUnknown)
|
|
||||||
{
|
|
||||||
DEFINE_ABSTRACT_UNKNOWN()
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Initialize
|
|
||||||
//
|
|
||||||
// Description: This function initializes the root host controller. It allocates the resources
|
|
||||||
// required to manage the registered controllers
|
|
||||||
|
|
||||||
virtual NTSTATUS Initialize() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// RegisterHCD
|
|
||||||
//
|
|
||||||
// Description: this function registers a host controller with the root host controller
|
|
||||||
|
|
||||||
virtual NTSTATUS RegisterHCD(struct IHCDController * Controller) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// UnregisterHCD
|
|
||||||
//
|
|
||||||
// Description: this function unregistes a host controller
|
|
||||||
|
|
||||||
virtual NTSTATUS UnregisterHCD(struct IHCDController * Controller) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetControllerCount
|
|
||||||
//
|
|
||||||
// Description: returns the number of host controllers registered
|
|
||||||
|
|
||||||
virtual ULONG GetControllerCount() = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef IRootHCDController *PROOTHDCCONTROLLER;
|
|
||||||
|
|
||||||
//=========================================================================================
|
|
||||||
//
|
|
||||||
// class IHCDController
|
|
||||||
//
|
|
||||||
// Description: This class is used to manage a single USB host controller
|
|
||||||
//
|
|
||||||
|
|
||||||
DECLARE_INTERFACE_(IHCDController, IUnknown)
|
|
||||||
{
|
|
||||||
DEFINE_ABSTRACT_UNKNOWN()
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Initialize
|
|
||||||
//
|
|
||||||
// Description: This function initializes the IHCDController implementation.
|
|
||||||
// It creates an IUSBHardwareDevice object and initializes it. It also registeres itself with
|
|
||||||
// the IRootHCDController
|
|
||||||
//
|
|
||||||
virtual NTSTATUS Initialize(IN PROOTHDCCONTROLLER RootHCDController,
|
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
|
||||||
IN PDEVICE_OBJECT PhysicalDeviceObject) = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef IHCDController *PHCDCONTROLLER;
|
|
||||||
|
|
||||||
struct _UHCI_QUEUE_HEAD;
|
struct _UHCI_QUEUE_HEAD;
|
||||||
|
struct IDMAMemoryManager;
|
||||||
|
struct IUSBQueue;
|
||||||
|
|
||||||
//=========================================================================================
|
//=========================================================================================
|
||||||
//
|
//
|
||||||
// class IUSBHardwareDevice
|
// class IUSBHardwareDevice
|
||||||
|
@ -116,221 +43,24 @@ struct _UHCI_QUEUE_HEAD;
|
||||||
// Description: This class provides access to the usb hardware controller
|
// Description: This class provides access to the usb hardware controller
|
||||||
//
|
//
|
||||||
|
|
||||||
struct IDMAMemoryManager;
|
#define DEFINE_ABSTRACT_USBUHCIHARDWAREDEVICE() \
|
||||||
struct IUSBQueue;
|
STDMETHOD_(VOID, GetQueueHead)( THIS_ \
|
||||||
|
IN ULONG QueueHeadIndex, \
|
||||||
|
IN struct _UHCI_QUEUE_HEAD **OutQueueHead) PURE;
|
||||||
|
|
||||||
DECLARE_INTERFACE_(IUSBHardwareDevice, IUnknown)
|
#define IMP_IUHCIHARDWAREDEVICE \
|
||||||
|
STDMETHODIMP_(VOID) GetQueueHead( \
|
||||||
|
IN ULONG QueueHeadIndex, \
|
||||||
|
IN struct _UHCI_QUEUE_HEAD **OutQueueHead);
|
||||||
|
|
||||||
|
DECLARE_INTERFACE_(IUHCIHardwareDevice, IUSBHardwareDevice)
|
||||||
{
|
{
|
||||||
DEFINE_ABSTRACT_UNKNOWN()
|
DEFINE_ABSTRACT_UNKNOWN()
|
||||||
|
DEFINE_ABSTRACT_USBHARDWAREDEVICE()
|
||||||
//-----------------------------------------------------------------------------------------
|
DEFINE_ABSTRACT_USBUHCIHARDWAREDEVICE()
|
||||||
//
|
|
||||||
// Initialize
|
|
||||||
//
|
|
||||||
// Description: Initializes the usb device controller
|
|
||||||
|
|
||||||
virtual NTSTATUS Initialize(PDRIVER_OBJECT DriverObject,
|
|
||||||
PDEVICE_OBJECT FunctionalDeviceObject,
|
|
||||||
PDEVICE_OBJECT PhysicalDeviceObject,
|
|
||||||
PDEVICE_OBJECT LowerDeviceObject) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PnpStart
|
|
||||||
//
|
|
||||||
// Description: handles pnp start request from device. It registeres the interrupt,
|
|
||||||
// sets up the ports and prepares the device. It then starts the controller
|
|
||||||
|
|
||||||
virtual NTSTATUS PnpStart(PCM_RESOURCE_LIST RawResources,
|
|
||||||
PCM_RESOURCE_LIST TranslatedResources) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PnpStop
|
|
||||||
//
|
|
||||||
// Description: handles pnp stop request from device. It unregisteres the interrupt, releases ports and dma object.
|
|
||||||
|
|
||||||
virtual NTSTATUS PnpStop(void) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetDeviceDetails
|
|
||||||
//
|
|
||||||
// Description: returns the device details such as vendor id, device id, number of ports and speed
|
|
||||||
|
|
||||||
virtual NTSTATUS GetDeviceDetails(OUT OPTIONAL PUSHORT VendorId,
|
|
||||||
OUT OPTIONAL PUSHORT DeviceId,
|
|
||||||
OUT OPTIONAL PULONG NumberOfPorts,
|
|
||||||
OUT OPTIONAL PULONG Speed) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetUSBQueue
|
|
||||||
//
|
|
||||||
// Description: returns interface to internal IUSBQueue
|
|
||||||
// Interface is reference counted, you need to call release method when you are done with it
|
|
||||||
// Do not call Initialize on IUSBQueue, the object is already initialized
|
|
||||||
|
|
||||||
virtual NTSTATUS GetUSBQueue(OUT struct IUSBQueue **OutUsbQueue) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetDMA
|
|
||||||
//
|
|
||||||
// Description: returns the DMA object which can be used to allocate memory from the common buffer
|
|
||||||
|
|
||||||
virtual NTSTATUS GetDMA(OUT struct IDMAMemoryManager **OutDMAMemoryManager) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// ResetController()
|
|
||||||
//
|
|
||||||
// Description: this function resets the controller
|
|
||||||
// Returns STATUS_SUCCESS when the controller was successfully reset
|
|
||||||
|
|
||||||
virtual NTSTATUS ResetController() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// StartController
|
|
||||||
//
|
|
||||||
// Description: this functions starts controller allowing interrupts for device connects/removal, and execution of
|
|
||||||
// Periodic and Asynchronous Schedules.
|
|
||||||
//
|
|
||||||
|
|
||||||
virtual NTSTATUS StartController() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// StopController
|
|
||||||
//
|
|
||||||
// Description: this functions stops controller disabling interrupts for device connects/removal, and execution of
|
|
||||||
// Periodic and Asynchronous Schedules.
|
|
||||||
//
|
|
||||||
|
|
||||||
virtual NTSTATUS StopController() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// ResetPort
|
|
||||||
//
|
|
||||||
// Description: this functions resets the port on the controller
|
|
||||||
//
|
|
||||||
|
|
||||||
virtual NTSTATUS ResetPort(ULONG PortNumber) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetPortStatus
|
|
||||||
//
|
|
||||||
// Description: this functions return status and change state of port
|
|
||||||
//
|
|
||||||
virtual NTSTATUS GetPortStatus(ULONG PortId, OUT USHORT *PortStatus, OUT USHORT *PortChange) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// ClearPortStatus
|
|
||||||
//
|
|
||||||
// Description: Clears Status of Port, for example Connection, Enable and Reset
|
|
||||||
//
|
|
||||||
virtual NTSTATUS ClearPortStatus(ULONG PortId, ULONG Status) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// SetPortFeature
|
|
||||||
//
|
|
||||||
// Description: this functions Sets Feature on Port, for example Enable, Power and Reset
|
|
||||||
//
|
|
||||||
virtual NTSTATUS SetPortFeature(ULONG PortId, ULONG Feature) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// SetStatusChangeEndpointCallBack
|
|
||||||
//
|
|
||||||
// Description: Used to callback to the hub controller when SCE detected
|
|
||||||
//
|
|
||||||
virtual VOID SetStatusChangeEndpointCallBack(PVOID CallBack,PVOID Context) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetQueueHead
|
|
||||||
//
|
|
||||||
// Description: gets a queue head with the specified queue head index
|
|
||||||
//
|
|
||||||
virtual VOID GetQueueHead(ULONG QueueHeadIndex, struct _UHCI_QUEUE_HEAD **OutQueueHead) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// AcquireDeviceLock
|
|
||||||
//
|
|
||||||
// Description: acquires the device lock
|
|
||||||
|
|
||||||
virtual KIRQL AcquireDeviceLock(void) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// ReleaseLock
|
|
||||||
//
|
|
||||||
// Description: releases the device lock
|
|
||||||
|
|
||||||
virtual void ReleaseDeviceLock(KIRQL OldLevel) = 0;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef IUSBHardwareDevice *PUSBHARDWAREDEVICE;
|
typedef IUHCIHardwareDevice *PUHCIHARDWAREDEVICE;
|
||||||
|
|
||||||
|
|
||||||
//=========================================================================================
|
|
||||||
//
|
|
||||||
// class IDMAMemoryManager
|
|
||||||
//
|
|
||||||
// Description: This class provides access to the dma buffer. It provides methods to
|
|
||||||
// allocate and free from the dma buffer
|
|
||||||
//
|
|
||||||
|
|
||||||
DECLARE_INTERFACE_(IDMAMemoryManager, IUnknown)
|
|
||||||
{
|
|
||||||
DEFINE_ABSTRACT_UNKNOWN()
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Initialize
|
|
||||||
//
|
|
||||||
// Description: initializes the memory manager
|
|
||||||
|
|
||||||
virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Device,
|
|
||||||
IN PKSPIN_LOCK Lock,
|
|
||||||
IN ULONG DmaBufferSize,
|
|
||||||
IN PVOID VirtualBase,
|
|
||||||
IN PHYSICAL_ADDRESS PhysicalAddress,
|
|
||||||
IN ULONG DefaultBlockSize) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Allocate
|
|
||||||
//
|
|
||||||
// Description: allocates block of memory from allocator
|
|
||||||
|
|
||||||
virtual NTSTATUS Allocate(IN ULONG Size,
|
|
||||||
OUT PVOID *OutVirtualBase,
|
|
||||||
OUT PPHYSICAL_ADDRESS OutPhysicalAddress) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Free
|
|
||||||
//
|
|
||||||
// Description: releases memory block
|
|
||||||
|
|
||||||
virtual NTSTATUS Release(IN PVOID VirtualBase,
|
|
||||||
IN ULONG Size) = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef IDMAMemoryManager *PDMAMEMORYMANAGER;
|
|
||||||
|
|
||||||
|
|
||||||
//=========================================================================================
|
//=========================================================================================
|
||||||
//
|
//
|
||||||
|
@ -345,118 +75,44 @@ typedef IDMAMemoryManager *PDMAMEMORYMANAGER;
|
||||||
// CancelCallback routine is invoked.
|
// CancelCallback routine is invoked.
|
||||||
//
|
//
|
||||||
|
|
||||||
DECLARE_INTERFACE_(IUSBRequest, IUnknown)
|
|
||||||
|
|
||||||
|
#define DEFINE_ABSTRACT_USBUHCIREQUEST() \
|
||||||
|
STDMETHOD_(NTSTATUS, GetEndpointDescriptor)( THIS_ \
|
||||||
|
IN struct _UHCI_QUEUE_HEAD**OutDescriptor) PURE; \
|
||||||
|
\
|
||||||
|
STDMETHOD_(UCHAR, GetInterval)( THIS) PURE; \
|
||||||
|
\
|
||||||
|
STDMETHOD_(USB_DEVICE_SPEED, GetDeviceSpeed)( THIS) PURE; \
|
||||||
|
\
|
||||||
|
STDMETHOD_(VOID, CompletionCallback)( THIS) PURE; \
|
||||||
|
\
|
||||||
|
STDMETHOD_(VOID, FreeEndpointDescriptor)( THIS_ \
|
||||||
|
IN struct _UHCI_QUEUE_HEAD *OutDescriptor) PURE;
|
||||||
|
|
||||||
|
|
||||||
|
#define IMP_IUHCIREQUEST \
|
||||||
|
STDMETHODIMP_(NTSTATUS) GetEndpointDescriptor(THIS_ \
|
||||||
|
IN struct _UHCI_QUEUE_HEAD**OutDescriptor); \
|
||||||
|
\
|
||||||
|
STDMETHODIMP_(UCHAR) GetInterval(THIS); \
|
||||||
|
\
|
||||||
|
STDMETHODIMP_(USB_DEVICE_SPEED) GetDeviceSpeed(THIS); \
|
||||||
|
\
|
||||||
|
STDMETHODIMP_(VOID) CompletionCallback(THIS); \
|
||||||
|
\
|
||||||
|
STDMETHODIMP_(VOID) FreeEndpointDescriptor(THIS_ \
|
||||||
|
IN struct _UHCI_QUEUE_HEAD * OutDescriptor);
|
||||||
|
|
||||||
|
DECLARE_INTERFACE_(IUHCIRequest, IUSBRequest)
|
||||||
{
|
{
|
||||||
DEFINE_ABSTRACT_UNKNOWN()
|
DEFINE_ABSTRACT_UNKNOWN()
|
||||||
|
DEFINE_ABSTRACT_USBREQUEST()
|
||||||
//-----------------------------------------------------------------------------------------
|
DEFINE_ABSTRACT_USBUHCIREQUEST()
|
||||||
//
|
|
||||||
// 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;
|
typedef IUHCIRequest *PUHCIREQUEST;
|
||||||
|
|
||||||
//=========================================================================================
|
//=========================================================================================
|
||||||
//
|
//
|
||||||
|
@ -465,336 +121,21 @@ typedef IUSBRequest *PUSBREQUEST;
|
||||||
// Description: This class manages pending requests
|
// Description: This class manages pending requests
|
||||||
//
|
//
|
||||||
|
|
||||||
DECLARE_INTERFACE_(IUSBQueue, IUnknown)
|
#define DEFINE_ABSTRACT_USBUHCIQUEUE() \
|
||||||
|
STDMETHOD_(VOID, TransferInterrupt)( \
|
||||||
|
IN UCHAR ErrorInterrupt) PURE;
|
||||||
|
|
||||||
|
#define IMP_IUHCIQUEUE \
|
||||||
|
STDMETHODIMP_(VOID) TransferInterrupt( \
|
||||||
|
IN UCHAR ErrorInterrupt);
|
||||||
|
|
||||||
|
DECLARE_INTERFACE_(IUHCIQueue, IUSBQueue)
|
||||||
{
|
{
|
||||||
DEFINE_ABSTRACT_UNKNOWN()
|
DEFINE_ABSTRACT_UNKNOWN()
|
||||||
|
DEFINE_ABSTRACT_USBQUEUE()
|
||||||
//-----------------------------------------------------------------------------------------
|
DEFINE_ABSTRACT_USBUHCIQUEUE()
|
||||||
//
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef IUSBQueue *PUSBQUEUE;
|
typedef IUHCIQueue *PUHCIQUEUE;
|
||||||
|
|
||||||
//=========================================================================================
|
|
||||||
//
|
|
||||||
// class IHubController
|
|
||||||
//
|
|
||||||
// Description: This class implements a hub controller
|
|
||||||
//
|
|
||||||
|
|
||||||
DECLARE_INTERFACE_(IHubController, IUnknown)
|
|
||||||
{
|
|
||||||
DEFINE_ABSTRACT_UNKNOWN()
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Initialize
|
|
||||||
//
|
|
||||||
// Description: Initializes the hub controller
|
|
||||||
|
|
||||||
virtual NTSTATUS Initialize(IN PDRIVER_OBJECT DriverObject,
|
|
||||||
IN PHCDCONTROLLER Controller,
|
|
||||||
IN PUSBHARDWAREDEVICE Device,
|
|
||||||
IN BOOLEAN IsRootHubDevice,
|
|
||||||
IN ULONG DeviceAddress) = 0;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetHubControllerDeviceObject
|
|
||||||
//
|
|
||||||
// Description: Returns the hub controller device object
|
|
||||||
|
|
||||||
virtual NTSTATUS GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject) = 0;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetHubControllerSymbolicLink
|
|
||||||
//
|
|
||||||
// Description: Returns the symbolic link of the root hub
|
|
||||||
|
|
||||||
virtual NTSTATUS GetHubControllerSymbolicLink(ULONG BufferLength, PVOID Buffer, PULONG RequiredLength) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef IHubController *PHUBCONTROLLER;
|
|
||||||
|
|
||||||
//=========================================================================================
|
|
||||||
//
|
|
||||||
// class IDispatchIrp
|
|
||||||
//
|
|
||||||
// Description: This class is used to handle irp dispatch requests
|
|
||||||
//
|
|
||||||
|
|
||||||
DECLARE_INTERFACE_(IDispatchIrp, IUnknown)
|
|
||||||
{
|
|
||||||
DEFINE_ABSTRACT_UNKNOWN()
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// HandlePnp
|
|
||||||
//
|
|
||||||
// Description: This function handles all pnp requests
|
|
||||||
|
|
||||||
virtual NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN OUT PIRP Irp) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// HandlePower
|
|
||||||
//
|
|
||||||
// Description: This function handles all power pnp requests
|
|
||||||
//
|
|
||||||
virtual NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN OUT PIRP Irp) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// HandleDeviceControl
|
|
||||||
//
|
|
||||||
// Description: handles device io control requests
|
|
||||||
|
|
||||||
virtual NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN OUT PIRP Irp) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef IDispatchIrp *PDISPATCHIRP;
|
|
||||||
|
|
||||||
//=========================================================================================
|
|
||||||
//
|
|
||||||
// class IUSBDevice
|
|
||||||
//
|
|
||||||
// Description: This class is used to abstract details of a usb device
|
|
||||||
//
|
|
||||||
|
|
||||||
DECLARE_INTERFACE_(IUSBDevice, IUnknown)
|
|
||||||
{
|
|
||||||
DEFINE_ABSTRACT_UNKNOWN()
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Initialize
|
|
||||||
//
|
|
||||||
// Description: Initializes the usb device
|
|
||||||
|
|
||||||
virtual NTSTATUS Initialize(IN PHUBCONTROLLER HubController,
|
|
||||||
IN PUSBHARDWAREDEVICE Device,
|
|
||||||
IN PVOID Parent,
|
|
||||||
IN ULONG Port,
|
|
||||||
IN ULONG PortStatus) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// IsHub
|
|
||||||
//
|
|
||||||
// Description: returns true when device is a hub
|
|
||||||
|
|
||||||
virtual BOOLEAN IsHub() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetParent
|
|
||||||
//
|
|
||||||
// Description: gets the parent device of the this device
|
|
||||||
|
|
||||||
virtual NTSTATUS GetParent(PVOID * Parent) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetDeviceAddress
|
|
||||||
//
|
|
||||||
// Description: gets the device address of the this device
|
|
||||||
|
|
||||||
virtual UCHAR GetDeviceAddress() = 0;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetPort
|
|
||||||
//
|
|
||||||
// Description: gets the port to which this device is connected
|
|
||||||
|
|
||||||
virtual ULONG GetPort() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetSpeed
|
|
||||||
//
|
|
||||||
// Description: gets the speed of the device
|
|
||||||
|
|
||||||
virtual USB_DEVICE_SPEED GetSpeed() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetType
|
|
||||||
//
|
|
||||||
// Description: gets the type of the device, either 1.1 or 2.0 device
|
|
||||||
|
|
||||||
virtual USB_DEVICE_TYPE GetType() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetState
|
|
||||||
//
|
|
||||||
// Description: gets the device state
|
|
||||||
|
|
||||||
virtual ULONG GetState() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// SetDeviceHandleData
|
|
||||||
//
|
|
||||||
// Description: sets device handle data
|
|
||||||
|
|
||||||
virtual void SetDeviceHandleData(PVOID Data) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// SetDeviceAddress
|
|
||||||
//
|
|
||||||
// Description: sets device handle data
|
|
||||||
|
|
||||||
virtual NTSTATUS SetDeviceAddress(UCHAR DeviceAddress) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetDeviceDescriptor
|
|
||||||
//
|
|
||||||
// Description: sets device handle data
|
|
||||||
|
|
||||||
virtual void GetDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetConfigurationValue
|
|
||||||
//
|
|
||||||
// Description: gets current selected configuration index
|
|
||||||
|
|
||||||
virtual UCHAR GetConfigurationValue() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// SubmitIrp
|
|
||||||
//
|
|
||||||
// Description: submits an irp containing an urb
|
|
||||||
|
|
||||||
virtual NTSTATUS SubmitIrp(PIRP Irp) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// GetConfigurationDescriptors
|
|
||||||
//
|
|
||||||
// Description: returns one or more configuration descriptors
|
|
||||||
|
|
||||||
virtual VOID GetConfigurationDescriptors(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer,
|
|
||||||
IN ULONG BufferLength,
|
|
||||||
OUT PULONG OutBufferLength) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Description: returns length of configuration descriptors
|
|
||||||
//
|
|
||||||
virtual ULONG GetConfigurationDescriptorsLength() = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// SubmitSetupPacket
|
|
||||||
//
|
|
||||||
// Description: submits an setup packet. The usb device will then create an usb request from it and submit it to the queue
|
|
||||||
|
|
||||||
virtual NTSTATUS SubmitSetupPacket(IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,
|
|
||||||
IN OUT ULONG BufferLength,
|
|
||||||
OUT PVOID Buffer) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// SelectConfiguration
|
|
||||||
//
|
|
||||||
// Description: selects a configuration
|
|
||||||
|
|
||||||
virtual NTSTATUS SelectConfiguration(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
|
|
||||||
IN PUSBD_INTERFACE_INFORMATION Interface,
|
|
||||||
OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// SelectConfiguration
|
|
||||||
//
|
|
||||||
// Description: selects a interface of an configuration
|
|
||||||
|
|
||||||
virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE ConfigurationHandle,
|
|
||||||
IN OUT PUSBD_INTERFACE_INFORMATION Interface) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// AbortPipe
|
|
||||||
//
|
|
||||||
// Description: aborts all pending requsts of an device
|
|
||||||
|
|
||||||
virtual NTSTATUS AbortPipe(IN struct _USB_ENDPOINT * EndpointDescriptor) = 0;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef IUSBDevice *PUSBDEVICE;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,369 +0,0 @@
|
||||||
/*
|
|
||||||
* PROJECT: ReactOS Universal Serial Bus Host Controller Interface
|
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
|
||||||
* FILE: drivers/usb/usbuhci/memory_manager.cpp
|
|
||||||
* PURPOSE: USB UHCI device driver.
|
|
||||||
* PROGRAMMERS:
|
|
||||||
* Michael Martin (michael.martin@reactos.org)
|
|
||||||
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "usbuhci.h"
|
|
||||||
|
|
||||||
class CDMAMemoryManager : public IDMAMemoryManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
|
||||||
|
|
||||||
STDMETHODIMP_(ULONG) AddRef()
|
|
||||||
{
|
|
||||||
InterlockedIncrement(&m_Ref);
|
|
||||||
return m_Ref;
|
|
||||||
}
|
|
||||||
STDMETHODIMP_(ULONG) Release()
|
|
||||||
{
|
|
||||||
InterlockedDecrement(&m_Ref);
|
|
||||||
|
|
||||||
if (!m_Ref)
|
|
||||||
{
|
|
||||||
delete this;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return m_Ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
// IDMAMemoryManager interface functions
|
|
||||||
virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Device, IN PKSPIN_LOCK Lock, IN ULONG DmaBufferSize, IN PVOID VirtualBase, IN PHYSICAL_ADDRESS PhysicalAddress, IN ULONG DefaultBlockSize);
|
|
||||||
virtual NTSTATUS Allocate(IN ULONG Size, OUT PVOID *OutVirtualBase, OUT PPHYSICAL_ADDRESS OutPhysicalAddress);
|
|
||||||
virtual NTSTATUS Release(IN PVOID VirtualBase, IN ULONG Size);
|
|
||||||
|
|
||||||
// constructor / destructor
|
|
||||||
CDMAMemoryManager(IUnknown *OuterUnknown){}
|
|
||||||
virtual ~CDMAMemoryManager(){}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
LONG m_Ref;
|
|
||||||
PUSBHARDWAREDEVICE m_Device;
|
|
||||||
PKSPIN_LOCK m_Lock;
|
|
||||||
LONG m_DmaBufferSize;
|
|
||||||
PVOID m_VirtualBase;
|
|
||||||
PHYSICAL_ADDRESS m_PhysicalAddress;
|
|
||||||
ULONG m_BlockSize;
|
|
||||||
|
|
||||||
PULONG m_BitmapBuffer;
|
|
||||||
RTL_BITMAP m_Bitmap;
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
NTSTATUS
|
|
||||||
STDMETHODCALLTYPE
|
|
||||||
CDMAMemoryManager::QueryInterface(
|
|
||||||
IN REFIID refiid,
|
|
||||||
OUT PVOID* Output)
|
|
||||||
{
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CDMAMemoryManager::Initialize(
|
|
||||||
IN PUSBHARDWAREDEVICE Device,
|
|
||||||
IN PKSPIN_LOCK Lock,
|
|
||||||
IN ULONG DmaBufferSize,
|
|
||||||
IN PVOID VirtualBase,
|
|
||||||
IN PHYSICAL_ADDRESS PhysicalAddress,
|
|
||||||
IN ULONG DefaultBlockSize)
|
|
||||||
{
|
|
||||||
ULONG BitmapLength;
|
|
||||||
|
|
||||||
//
|
|
||||||
// sanity checks
|
|
||||||
//
|
|
||||||
PC_ASSERT(DmaBufferSize >= PAGE_SIZE);
|
|
||||||
PC_ASSERT(DmaBufferSize % PAGE_SIZE == 0);
|
|
||||||
PC_ASSERT(DefaultBlockSize == 32 || DefaultBlockSize == 64 || DefaultBlockSize == 128);
|
|
||||||
|
|
||||||
//
|
|
||||||
// calculate bitmap length
|
|
||||||
//
|
|
||||||
BitmapLength = (DmaBufferSize / DefaultBlockSize) / 8;
|
|
||||||
|
|
||||||
//
|
|
||||||
// allocate bitmap buffer
|
|
||||||
//
|
|
||||||
m_BitmapBuffer = (PULONG)ExAllocatePoolWithTag(NonPagedPool, BitmapLength, TAG_USBUHCI);
|
|
||||||
if (!m_BitmapBuffer)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// no memory
|
|
||||||
//
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// initialize bitmap
|
|
||||||
//
|
|
||||||
RtlInitializeBitMap(&m_Bitmap, m_BitmapBuffer, BitmapLength * 8);
|
|
||||||
|
|
||||||
//
|
|
||||||
// clear all bits
|
|
||||||
//
|
|
||||||
RtlClearAllBits(&m_Bitmap);
|
|
||||||
|
|
||||||
//
|
|
||||||
// initialize rest of memory allocator
|
|
||||||
//
|
|
||||||
m_PhysicalAddress = PhysicalAddress;
|
|
||||||
m_VirtualBase = VirtualBase;
|
|
||||||
m_DmaBufferSize = DmaBufferSize;
|
|
||||||
m_BitmapBuffer = m_BitmapBuffer;
|
|
||||||
m_Lock = Lock;
|
|
||||||
m_BlockSize = DefaultBlockSize;
|
|
||||||
|
|
||||||
/* done */
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CDMAMemoryManager::Allocate(
|
|
||||||
IN ULONG Size,
|
|
||||||
OUT PVOID *OutVirtualAddress,
|
|
||||||
OUT PPHYSICAL_ADDRESS OutPhysicalAddress)
|
|
||||||
{
|
|
||||||
ULONG Length, BlockCount, FreeIndex, StartPage, EndPage;
|
|
||||||
KIRQL OldLevel;
|
|
||||||
ULONG BlocksPerPage;
|
|
||||||
|
|
||||||
//
|
|
||||||
// sanity checks
|
|
||||||
//
|
|
||||||
ASSERT(Size <= PAGE_SIZE);
|
|
||||||
//ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// align request
|
|
||||||
//
|
|
||||||
Length = (Size + m_BlockSize -1) & ~(m_BlockSize -1);
|
|
||||||
|
|
||||||
//
|
|
||||||
// sanity check
|
|
||||||
//
|
|
||||||
ASSERT(Length);
|
|
||||||
|
|
||||||
//
|
|
||||||
// convert to block count
|
|
||||||
//
|
|
||||||
BlockCount = Length / m_BlockSize;
|
|
||||||
|
|
||||||
//
|
|
||||||
// acquire lock
|
|
||||||
//
|
|
||||||
KeAcquireSpinLock(m_Lock, &OldLevel);
|
|
||||||
|
|
||||||
//
|
|
||||||
// helper variable
|
|
||||||
//
|
|
||||||
BlocksPerPage = PAGE_SIZE / m_BlockSize;
|
|
||||||
|
|
||||||
//
|
|
||||||
// start search
|
|
||||||
//
|
|
||||||
FreeIndex = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// search for an free index
|
|
||||||
//
|
|
||||||
FreeIndex = RtlFindClearBits(&m_Bitmap, BlockCount, FreeIndex);
|
|
||||||
|
|
||||||
//
|
|
||||||
// check if there was a block found
|
|
||||||
//
|
|
||||||
if (FreeIndex == MAXULONG)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// no free block found
|
|
||||||
//
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// check that the allocation does not spawn over page boundaries
|
|
||||||
//
|
|
||||||
StartPage = (FreeIndex * m_BlockSize);
|
|
||||||
StartPage = (StartPage != 0 ? StartPage / PAGE_SIZE : 0);
|
|
||||||
EndPage = ((FreeIndex + BlockCount) * m_BlockSize) / PAGE_SIZE;
|
|
||||||
|
|
||||||
//
|
|
||||||
// does the request start and end on the same page
|
|
||||||
//
|
|
||||||
if (StartPage == EndPage)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// reserve block
|
|
||||||
//
|
|
||||||
RtlSetBits(&m_Bitmap, FreeIndex, BlockCount);
|
|
||||||
|
|
||||||
//
|
|
||||||
// reserve block
|
|
||||||
//
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if ((BlockCount == BlocksPerPage) && (FreeIndex % BlocksPerPage == 0))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// the request equals PAGE_SIZE and is aligned at page boundary
|
|
||||||
// reserve block
|
|
||||||
//
|
|
||||||
RtlSetBits(&m_Bitmap, FreeIndex, BlockCount);
|
|
||||||
|
|
||||||
//
|
|
||||||
// reserve block
|
|
||||||
//
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// request spawned over page boundary
|
|
||||||
// restart search on next page
|
|
||||||
//
|
|
||||||
FreeIndex = (EndPage * PAGE_SIZE) / m_BlockSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(TRUE);
|
|
||||||
|
|
||||||
//
|
|
||||||
// release lock
|
|
||||||
//
|
|
||||||
KeReleaseSpinLock(m_Lock, OldLevel);
|
|
||||||
|
|
||||||
//
|
|
||||||
// did allocation succeed
|
|
||||||
//
|
|
||||||
if (FreeIndex == MAXULONG)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// failed to allocate block, requestor must retry
|
|
||||||
//
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// return result
|
|
||||||
//
|
|
||||||
*OutVirtualAddress = (PVOID)((ULONG_PTR)m_VirtualBase + FreeIndex * m_BlockSize);
|
|
||||||
OutPhysicalAddress->QuadPart = m_PhysicalAddress.QuadPart + FreeIndex * m_BlockSize;
|
|
||||||
|
|
||||||
//
|
|
||||||
// clear block
|
|
||||||
//
|
|
||||||
RtlZeroMemory(*OutVirtualAddress, Length);
|
|
||||||
|
|
||||||
//
|
|
||||||
// done
|
|
||||||
//
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CDMAMemoryManager::Release(
|
|
||||||
IN PVOID VirtualAddress,
|
|
||||||
IN ULONG Size)
|
|
||||||
{
|
|
||||||
KIRQL OldLevel;
|
|
||||||
ULONG BlockOffset = 0, BlockLength, BlockCount;
|
|
||||||
|
|
||||||
//
|
|
||||||
// sanity checks
|
|
||||||
//
|
|
||||||
PC_ASSERT(VirtualAddress);
|
|
||||||
PC_ASSERT((ULONG_PTR)VirtualAddress >= (ULONG_PTR)m_VirtualBase);
|
|
||||||
PC_ASSERT((ULONG_PTR)m_VirtualBase + m_DmaBufferSize > (ULONG_PTR)m_VirtualBase);
|
|
||||||
|
|
||||||
//
|
|
||||||
// calculate block length
|
|
||||||
//
|
|
||||||
BlockLength = ((ULONG_PTR)VirtualAddress - (ULONG_PTR)m_VirtualBase);
|
|
||||||
|
|
||||||
//
|
|
||||||
// check if its the first block
|
|
||||||
//
|
|
||||||
if (BlockLength)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// divide by base block size
|
|
||||||
//
|
|
||||||
BlockOffset = BlockLength / m_BlockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// align length to block size
|
|
||||||
//
|
|
||||||
Size = (Size + m_BlockSize - 1) & ~(m_BlockSize - 1);
|
|
||||||
|
|
||||||
//
|
|
||||||
// convert to blocks
|
|
||||||
//
|
|
||||||
BlockCount = Size / m_BlockSize;
|
|
||||||
ASSERT(BlockCount);
|
|
||||||
|
|
||||||
//
|
|
||||||
// acquire lock
|
|
||||||
//
|
|
||||||
KeAcquireSpinLock(m_Lock, &OldLevel);
|
|
||||||
|
|
||||||
//
|
|
||||||
// sanity check
|
|
||||||
//
|
|
||||||
ASSERT(RtlAreBitsSet(&m_Bitmap, BlockOffset, BlockCount));
|
|
||||||
|
|
||||||
//
|
|
||||||
// release buffer
|
|
||||||
//
|
|
||||||
RtlClearBits(&m_Bitmap, BlockOffset, BlockCount);
|
|
||||||
|
|
||||||
//
|
|
||||||
// release lock
|
|
||||||
//
|
|
||||||
KeReleaseSpinLock(m_Lock, OldLevel);
|
|
||||||
|
|
||||||
//
|
|
||||||
// done
|
|
||||||
//
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CreateDMAMemoryManager(
|
|
||||||
PDMAMEMORYMANAGER *OutMemoryManager)
|
|
||||||
{
|
|
||||||
CDMAMemoryManager* This;
|
|
||||||
|
|
||||||
//
|
|
||||||
// allocate controller
|
|
||||||
//
|
|
||||||
This = new(NonPagedPool, TAG_USBUHCI) CDMAMemoryManager(0);
|
|
||||||
if (!This)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// failed to allocate
|
|
||||||
//
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// add reference count
|
|
||||||
//
|
|
||||||
This->AddRef();
|
|
||||||
|
|
||||||
//
|
|
||||||
// return result
|
|
||||||
//
|
|
||||||
*OutMemoryManager = (PDMAMEMORYMANAGER)This;
|
|
||||||
|
|
||||||
//
|
|
||||||
// done
|
|
||||||
//
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,134 +0,0 @@
|
||||||
/*
|
|
||||||
* PROJECT: ReactOS Universal Serial Bus Host Controller Interface
|
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
|
||||||
* FILE: drivers/usb/usbuhci/misc.cpp
|
|
||||||
* PURPOSE: USB UHCI device driver.
|
|
||||||
* PROGRAMMERS:
|
|
||||||
* Michael Martin (michael.martin@reactos.org)
|
|
||||||
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "usbuhci.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// driver verifier
|
|
||||||
//
|
|
||||||
IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine;
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
SyncForwardIrpCompletionRoutine(
|
|
||||||
PDEVICE_OBJECT DeviceObject,
|
|
||||||
PIRP Irp,
|
|
||||||
PVOID Context)
|
|
||||||
{
|
|
||||||
if (Irp->PendingReturned)
|
|
||||||
{
|
|
||||||
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
|
|
||||||
}
|
|
||||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|
||||||
{
|
|
||||||
KEVENT Event;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
//
|
|
||||||
// initialize event
|
|
||||||
//
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
|
||||||
|
|
||||||
//
|
|
||||||
// copy irp stack location
|
|
||||||
//
|
|
||||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
|
||||||
|
|
||||||
//
|
|
||||||
// set completion routine
|
|
||||||
//
|
|
||||||
IoSetCompletionRoutine(Irp, SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// call driver
|
|
||||||
//
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// check if pending
|
|
||||||
//
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// wait for the request to finish
|
|
||||||
//
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// copy status code
|
|
||||||
//
|
|
||||||
Status = Irp->IoStatus.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// done
|
|
||||||
//
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
GetBusInterface(
|
|
||||||
PDEVICE_OBJECT DeviceObject,
|
|
||||||
PBUS_INTERFACE_STANDARD busInterface)
|
|
||||||
{
|
|
||||||
KEVENT Event;
|
|
||||||
NTSTATUS Status;
|
|
||||||
PIRP Irp;
|
|
||||||
IO_STATUS_BLOCK IoStatus;
|
|
||||||
PIO_STACK_LOCATION Stack;
|
|
||||||
|
|
||||||
if ((!DeviceObject) || (!busInterface))
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
|
||||||
|
|
||||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
|
|
||||||
DeviceObject,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
&Event,
|
|
||||||
&IoStatus);
|
|
||||||
|
|
||||||
if (Irp == NULL)
|
|
||||||
{
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack=IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->MajorFunction = IRP_MJ_PNP;
|
|
||||||
Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
|
|
||||||
Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
|
|
||||||
Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_BUS_INTERFACE_STANDARD;
|
|
||||||
Stack->Parameters.QueryInterface.Version = 1;
|
|
||||||
Stack->Parameters.QueryInterface.Interface = (PINTERFACE)busInterface;
|
|
||||||
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
|
|
||||||
Irp->IoStatus.Status=STATUS_NOT_SUPPORTED ;
|
|
||||||
|
|
||||||
Status=IoCallDriver(DeviceObject, Irp);
|
|
||||||
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
|
|
||||||
Status=IoStatus.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
* PROJECT: ReactOS Universal Serial Bus Host Controller Interface
|
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
|
||||||
* FILE: drivers/usb/usbuhci/purecall.cpp
|
|
||||||
* PURPOSE: USB UHCI device driver.
|
|
||||||
* PROGRAMMERS:
|
|
||||||
* Michael Martin (michael.martin@reactos.org)
|
|
||||||
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "usbuhci.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
void
|
|
||||||
__cxa_pure_virtual()
|
|
||||||
{
|
|
||||||
// put error handling here
|
|
||||||
|
|
||||||
DbgBreakPoint();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,7 +11,7 @@
|
||||||
#include "usbuhci.h"
|
#include "usbuhci.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
|
|
||||||
class CUSBQueue : public IUSBQueue
|
class CUSBQueue : public IUHCIQueue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
||||||
|
@ -34,14 +34,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// com
|
// com
|
||||||
virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Hardware, PDMA_ADAPTER AdapterObject, IN PDMAMEMORYMANAGER MemManager, IN OPTIONAL PKSPIN_LOCK Lock);
|
IMP_IUSBQUEUE
|
||||||
virtual ULONG GetPendingRequestCount();
|
IMP_IUHCIQUEUE
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
// local
|
// local
|
||||||
VOID LinkQueueHead(PUHCI_QUEUE_HEAD QueueHead, PUHCI_QUEUE_HEAD NextQueueHead);
|
VOID LinkQueueHead(PUHCI_QUEUE_HEAD QueueHead, PUHCI_QUEUE_HEAD NextQueueHead);
|
||||||
|
@ -58,7 +52,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
LONG m_Ref; // reference count
|
LONG m_Ref; // reference count
|
||||||
KSPIN_LOCK m_Lock; // list lock
|
KSPIN_LOCK m_Lock; // list lock
|
||||||
PUSBHARDWAREDEVICE m_Hardware; // hardware
|
PUHCIHARDWAREDEVICE m_Hardware; // hardware
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,42 +82,31 @@ CUSBQueue::Initialize(
|
||||||
IN PDMAMEMORYMANAGER MemManager,
|
IN PDMAMEMORYMANAGER MemManager,
|
||||||
IN OPTIONAL PKSPIN_LOCK Lock)
|
IN OPTIONAL PKSPIN_LOCK Lock)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// initialize spinlock
|
|
||||||
//
|
|
||||||
KeInitializeSpinLock(&m_Lock);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// store hardware
|
// store hardware
|
||||||
//
|
//
|
||||||
m_Hardware = Hardware;
|
m_Hardware = PUHCIHARDWAREDEVICE(Hardware);
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize spinlock
|
||||||
|
//
|
||||||
|
KeInitializeSpinLock(&m_Lock);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
|
||||||
CUSBQueue::GetPendingRequestCount()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Loop through the pending list and iterrate one for each QueueHead that
|
|
||||||
// has a IRP to complete.
|
|
||||||
//
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CUSBQueue::AddQueueHead(
|
CUSBQueue::AddQueueHead(
|
||||||
PUHCI_QUEUE_HEAD NewQueueHead)
|
PUHCI_QUEUE_HEAD NewQueueHead)
|
||||||
{
|
{
|
||||||
PUSBREQUEST Request;
|
PUHCIREQUEST Request;
|
||||||
PUHCI_QUEUE_HEAD QueueHead = NULL;
|
PUHCI_QUEUE_HEAD QueueHead = NULL;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// get request
|
// get request
|
||||||
//
|
//
|
||||||
Request = (PUSBREQUEST)NewQueueHead->Request;
|
Request = (PUHCIREQUEST)NewQueueHead->Request;
|
||||||
if (!Request)
|
if (!Request)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -194,10 +177,14 @@ CUSBQueue::AddQueueHead(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CUSBQueue::AddUSBRequest(
|
CUSBQueue::AddUSBRequest(
|
||||||
IUSBRequest * Request)
|
IUSBRequest * Req)
|
||||||
{
|
{
|
||||||
PUHCI_QUEUE_HEAD NewQueueHead;
|
PUHCI_QUEUE_HEAD NewQueueHead;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PUHCIREQUEST Request;
|
||||||
|
|
||||||
|
// get request
|
||||||
|
Request = (PUHCIREQUEST)Req;
|
||||||
|
|
||||||
//
|
//
|
||||||
// get queue head
|
// get queue head
|
||||||
|
@ -247,24 +234,19 @@ CUSBQueue::UnLinkQueueHead(
|
||||||
PreviousQueueHead->NextLogicalDescriptor = QueueHeadToRemove->NextLogicalDescriptor;
|
PreviousQueueHead->NextLogicalDescriptor = QueueHeadToRemove->NextLogicalDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CUSBQueue::CancelRequests()
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CUSBQueue::AbortDevicePipe(
|
CUSBQueue::AbortDevicePipe(
|
||||||
IN UCHAR DeviceAddress,
|
IN UCHAR DeviceAddress,
|
||||||
IN struct _USB_ENDPOINT *EndpointDescriptor)
|
IN PUSB_ENDPOINT_DESCRIPTOR EndDescriptor)
|
||||||
{
|
{
|
||||||
KIRQL OldLevel;
|
KIRQL OldLevel;
|
||||||
PUHCI_TRANSFER_DESCRIPTOR Descriptor;
|
PUHCI_TRANSFER_DESCRIPTOR Descriptor;
|
||||||
PUHCI_QUEUE_HEAD QueueHead, PreviousQueueHead = NULL;
|
PUHCI_QUEUE_HEAD QueueHead, PreviousQueueHead = NULL;
|
||||||
UCHAR EndpointAddress, EndpointDeviceAddress;
|
UCHAR EndpointAddress, EndpointDeviceAddress;
|
||||||
|
PUSB_ENDPOINT EndpointDescriptor;
|
||||||
|
|
||||||
|
// get descriptor
|
||||||
|
EndpointDescriptor = (PUSB_ENDPOINT)EndDescriptor;
|
||||||
|
|
||||||
// acquire lock
|
// acquire lock
|
||||||
KeAcquireSpinLock(&m_Lock, &OldLevel);
|
KeAcquireSpinLock(&m_Lock, &OldLevel);
|
||||||
|
@ -412,7 +394,7 @@ CUSBQueue::QueueHeadCleanup(
|
||||||
IN PUHCI_QUEUE_HEAD PreviousQueueHead,
|
IN PUHCI_QUEUE_HEAD PreviousQueueHead,
|
||||||
OUT PUHCI_QUEUE_HEAD *NextQueueHead)
|
OUT PUHCI_QUEUE_HEAD *NextQueueHead)
|
||||||
{
|
{
|
||||||
PUSBREQUEST Request;
|
PUHCIREQUEST Request;
|
||||||
PUHCI_QUEUE_HEAD NewQueueHead;
|
PUHCI_QUEUE_HEAD NewQueueHead;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -430,7 +412,7 @@ CUSBQueue::QueueHeadCleanup(
|
||||||
//
|
//
|
||||||
// the queue head is complete, is the transfer now completed?
|
// the queue head is complete, is the transfer now completed?
|
||||||
//
|
//
|
||||||
Request = (PUSBREQUEST)QueueHead->Request;
|
Request = (PUHCIREQUEST)QueueHead->Request;
|
||||||
ASSERT(Request);
|
ASSERT(Request);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "usbuhci.h"
|
#include "usbuhci.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
|
|
||||||
class CUSBRequest : public IUSBRequest
|
class CUSBRequest : public IUHCIRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
||||||
|
@ -35,19 +35,9 @@ public:
|
||||||
return m_Ref;
|
return m_Ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IUSBRequest interface functions
|
// com
|
||||||
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);
|
IMP_IUSBREQUEST
|
||||||
virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager, IN OUT PIRP Irp, IN USB_DEVICE_SPEED DeviceSpeed);
|
IMP_IUHCIREQUEST
|
||||||
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);
|
|
||||||
|
|
||||||
// local functions
|
// local functions
|
||||||
ULONG InternalGetTransferType();
|
ULONG InternalGetTransferType();
|
||||||
|
@ -160,9 +150,8 @@ NTSTATUS
|
||||||
CUSBRequest::InitializeWithSetupPacket(
|
CUSBRequest::InitializeWithSetupPacket(
|
||||||
IN PDMAMEMORYMANAGER DmaManager,
|
IN PDMAMEMORYMANAGER DmaManager,
|
||||||
IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,
|
IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,
|
||||||
IN UCHAR DeviceAddress,
|
IN PUSBDEVICE Device,
|
||||||
IN OPTIONAL struct _USB_ENDPOINT * EndpointDescriptor,
|
IN OPTIONAL struct _USB_ENDPOINT * EndpointDescriptor,
|
||||||
IN USB_DEVICE_SPEED DeviceSpeed,
|
|
||||||
IN OUT ULONG TransferBufferLength,
|
IN OUT ULONG TransferBufferLength,
|
||||||
IN OUT PMDL TransferBuffer)
|
IN OUT PMDL TransferBuffer)
|
||||||
{
|
{
|
||||||
|
@ -179,10 +168,10 @@ CUSBRequest::InitializeWithSetupPacket(
|
||||||
m_SetupPacket = SetupPacket;
|
m_SetupPacket = SetupPacket;
|
||||||
m_TransferBufferLength = TransferBufferLength;
|
m_TransferBufferLength = TransferBufferLength;
|
||||||
m_TransferBufferMDL = TransferBuffer;
|
m_TransferBufferMDL = TransferBuffer;
|
||||||
m_DeviceAddress = DeviceAddress;
|
m_DeviceAddress = Device->GetDeviceAddress();
|
||||||
m_EndpointDescriptor = EndpointDescriptor;
|
m_EndpointDescriptor = EndpointDescriptor;
|
||||||
m_TotalBytesTransferred = 0;
|
m_TotalBytesTransferred = 0;
|
||||||
m_DeviceSpeed = DeviceSpeed;
|
m_DeviceSpeed = Device->GetSpeed();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set Length Completed to 0
|
// Set Length Completed to 0
|
||||||
|
@ -215,8 +204,8 @@ CUSBRequest::InitializeWithSetupPacket(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CUSBRequest::InitializeWithIrp(
|
CUSBRequest::InitializeWithIrp(
|
||||||
IN PDMAMEMORYMANAGER DmaManager,
|
IN PDMAMEMORYMANAGER DmaManager,
|
||||||
IN OUT PIRP Irp,
|
IN PUSBDEVICE Device,
|
||||||
IN USB_DEVICE_SPEED DeviceSpeed)
|
IN OUT PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PURB Urb;
|
PURB Urb;
|
||||||
|
@ -229,7 +218,7 @@ CUSBRequest::InitializeWithIrp(
|
||||||
|
|
||||||
m_DmaManager = DmaManager;
|
m_DmaManager = DmaManager;
|
||||||
m_TotalBytesTransferred = 0;
|
m_TotalBytesTransferred = 0;
|
||||||
m_DeviceSpeed = DeviceSpeed;
|
m_DeviceSpeed = Device->GetSpeed();
|
||||||
|
|
||||||
//
|
//
|
||||||
// get current irp stack location
|
// get current irp stack location
|
||||||
|
@ -684,32 +673,6 @@ CUSBRequest::GetResultStatus(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
BOOLEAN
|
|
||||||
CUSBRequest::IsRequestInitialized()
|
|
||||||
{
|
|
||||||
if (m_Irp || m_SetupPacket)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// request is initialized
|
|
||||||
//
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// request is not initialized
|
|
||||||
//
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
BOOLEAN
|
|
||||||
CUSBRequest::IsQueueHeadComplete(
|
|
||||||
struct _QUEUE_HEAD * QueueHead)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CUSBRequest::CreateDescriptor(
|
CUSBRequest::CreateDescriptor(
|
||||||
|
@ -1248,6 +1211,7 @@ CUSBRequest::FreeEndpointDescriptor(
|
||||||
PUHCI_TRANSFER_DESCRIPTOR Descriptor, NextDescriptor;
|
PUHCI_TRANSFER_DESCRIPTOR Descriptor, NextDescriptor;
|
||||||
ULONG ErrorCount;
|
ULONG ErrorCount;
|
||||||
UCHAR DataToggle = 0;
|
UCHAR DataToggle = 0;
|
||||||
|
ULONG Index = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// grab first transfer descriptor
|
// grab first transfer descriptor
|
||||||
|
@ -1278,22 +1242,22 @@ CUSBRequest::FreeEndpointDescriptor(
|
||||||
|
|
||||||
if (Descriptor->Status & TD_STATUS_ERROR_BUFFER)
|
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;
|
m_UrbStatusCode = USBD_STATUS_DATA_BUFFER_ERROR;
|
||||||
}
|
}
|
||||||
else if (Descriptor->Status & TD_STATUS_ERROR_TIMEOUT)
|
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;
|
m_UrbStatusCode = USBD_STATUS_TIMEOUT;
|
||||||
}
|
}
|
||||||
else if (Descriptor->Status & TD_STATUS_ERROR_NAK)
|
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;
|
m_UrbStatusCode = USBD_STATUS_UNEXPECTED_PID;
|
||||||
}
|
}
|
||||||
else if (Descriptor->Status & TD_STATUS_ERROR_BITSTUFF)
|
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;
|
m_UrbStatusCode = USBD_STATUS_BTSTUFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1302,7 +1266,7 @@ CUSBRequest::FreeEndpointDescriptor(
|
||||||
//
|
//
|
||||||
// babble error
|
// 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;
|
m_UrbStatusCode = USBD_STATUS_BABBLE_DETECTED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1310,7 +1274,7 @@ CUSBRequest::FreeEndpointDescriptor(
|
||||||
//
|
//
|
||||||
// stall detected
|
// stall detected
|
||||||
//
|
//
|
||||||
DPRINT1("[USBUHCI] Stall detected\n");
|
DPRINT1("[USBUHCI] Stall detected Descriptor %p Index %lu\n", Descriptor, Index);
|
||||||
m_UrbStatusCode = USBD_STATUS_STALL_PID;
|
m_UrbStatusCode = USBD_STATUS_STALL_PID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1341,6 +1305,7 @@ CUSBRequest::FreeEndpointDescriptor(
|
||||||
// move to next
|
// move to next
|
||||||
//
|
//
|
||||||
Descriptor = NextDescriptor;
|
Descriptor = NextDescriptor;
|
||||||
|
Index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -10,116 +10,6 @@
|
||||||
|
|
||||||
#include "usbuhci.h"
|
#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
|
extern
|
||||||
"C"
|
"C"
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -128,16 +18,22 @@ DriverEntry(
|
||||||
PDRIVER_OBJECT DriverObject,
|
PDRIVER_OBJECT DriverObject,
|
||||||
PUNICODE_STRING RegistryPath)
|
PUNICODE_STRING RegistryPath)
|
||||||
{
|
{
|
||||||
DPRINT1("[UHCI] Driver Entry\n");
|
|
||||||
/* initialize driver object*/
|
/* initialize driver object*/
|
||||||
DriverObject->DriverExtension->AddDevice = UHCI_AddDevice;
|
DriverObject->DriverExtension->AddDevice = USBLIB_AddDevice;
|
||||||
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = UHCI_Dispatch;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = UHCI_Dispatch;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = UHCI_Dispatch;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = UHCI_Dispatch;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = UHCI_Dispatch;
|
|
||||||
DriverObject->MajorFunction[IRP_MJ_PNP] = UHCI_Dispatch;
|
|
||||||
|
|
||||||
|
DriverObject->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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void free(void * ptr)
|
||||||
|
{
|
||||||
|
ExFreePool(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -46,17 +46,10 @@ extern
|
||||||
#define C_PORT_OVER_CURRENT 19
|
#define C_PORT_OVER_CURRENT 19
|
||||||
#define C_PORT_RESET 20
|
#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
|
// tag for allocations
|
||||||
//
|
//
|
||||||
#define TAG_USBUHCI 'ICHO'
|
#define TAG_USBUHCI 'ICHU'
|
||||||
|
|
||||||
//
|
//
|
||||||
// assert for c++ - taken from portcls
|
// assert for c++ - taken from portcls
|
||||||
|
@ -65,38 +58,11 @@ typedef struct
|
||||||
(VOID)((!(exp)) ? \
|
(VOID)((!(exp)) ? \
|
||||||
RtlAssert((PVOID) #exp, (PVOID)__FILE__, __LINE__, NULL ), FALSE : TRUE)
|
RtlAssert((PVOID) #exp, (PVOID)__FILE__, __LINE__, NULL ), FALSE : TRUE)
|
||||||
|
|
||||||
//
|
|
||||||
// hcd_controller.cpp
|
|
||||||
//
|
|
||||||
NTSTATUS CreateHCDController(PHCDCONTROLLER *HcdController);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// hardware.cpp
|
// hardware.cpp
|
||||||
//
|
//
|
||||||
NTSTATUS CreateUSBHardware(PUSBHARDWAREDEVICE *OutHardware);
|
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
|
// usb_queue.cpp
|
||||||
//
|
//
|
||||||
|
@ -107,26 +73,4 @@ NTSTATUS CreateUSBQueue(PUSBQUEUE *OutUsbQueue);
|
||||||
//
|
//
|
||||||
NTSTATUS InternalCreateUSBRequest(PUSBREQUEST *OutRequest);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue