mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:33:10 +00:00
[USBCCGP]
- Start implement USB Composite generic parent driver which is used for USB composite devices - Start implement FDO initialization, needs to implement parsing of usb interface assocaition descriptor to complete FDO initialization svn path=/branches/usb-bringup-trunk/; revision=55195
This commit is contained in:
parent
e33d8f1ee5
commit
1cede4f077
8 changed files with 964 additions and 0 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
add_subdirectory(usbccgp)
|
||||||
add_subdirectory(usbd)
|
add_subdirectory(usbd)
|
||||||
add_subdirectory(usbehci_new)
|
add_subdirectory(usbehci_new)
|
||||||
add_subdirectory(usbhub_new)
|
add_subdirectory(usbhub_new)
|
||||||
|
|
13
drivers/usb/usbccgp/CMakeLists.txt
Normal file
13
drivers/usb/usbccgp/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
add_definitions(-DDEBUG_MODE)
|
||||||
|
|
||||||
|
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
|
||||||
|
|
||||||
|
add_library(usbccgp SHARED descriptor.c fdo.c misc.c pdo.c usbccgp.c usbccgp.rc)
|
||||||
|
|
||||||
|
target_link_libraries(usbccgp ${PSEH_LIB})
|
||||||
|
|
||||||
|
set_module_type(usbccgp kernelmodedriver)
|
||||||
|
add_importlibs(usbccgp ntoskrnl hal usbd)
|
||||||
|
|
||||||
|
add_cd_file(TARGET usbccgp DESTINATION reactos/system32/drivers NO_CAB FOR all)
|
386
drivers/usb/usbccgp/descriptor.c
Normal file
386
drivers/usb/usbccgp/descriptor.c
Normal file
|
@ -0,0 +1,386 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/usb/usbccgp/descriptor.c
|
||||||
|
* PURPOSE: USB device driver.
|
||||||
|
* PROGRAMMERS:
|
||||||
|
* Michael Martin (michael.martin@reactos.org)
|
||||||
|
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||||
|
* Cameron Gutman
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "usbccgp.h"
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
USBCCGP_GetDescriptor(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN UCHAR DescriptorType,
|
||||||
|
IN ULONG DescriptorLength,
|
||||||
|
IN UCHAR DescriptorIndex,
|
||||||
|
IN LANGID LanguageId,
|
||||||
|
OUT PVOID *OutDescriptor)
|
||||||
|
{
|
||||||
|
PURB Urb;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PVOID Descriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity checks
|
||||||
|
//
|
||||||
|
ASSERT(DeviceObject);
|
||||||
|
ASSERT(OutDescriptor);
|
||||||
|
ASSERT(DescriptorLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
// first allocate descriptor buffer
|
||||||
|
//
|
||||||
|
Descriptor = AllocateItem(NonPagedPool, DescriptorLength);
|
||||||
|
if (!Descriptor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocate urb
|
||||||
|
//
|
||||||
|
Urb = (PURB) AllocateItem(NonPagedPool, sizeof(URB));
|
||||||
|
if (!Urb)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
FreeItem(Descriptor);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize urb
|
||||||
|
//
|
||||||
|
UsbBuildGetDescriptorRequest(Urb,
|
||||||
|
sizeof(Urb->UrbControlDescriptorRequest),
|
||||||
|
DescriptorType,
|
||||||
|
DescriptorIndex,
|
||||||
|
LanguageId,
|
||||||
|
Descriptor,
|
||||||
|
NULL,
|
||||||
|
DescriptorLength,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// submit urb
|
||||||
|
//
|
||||||
|
Status = USBCCGP_SyncUrbRequest(DeviceObject, Urb);
|
||||||
|
|
||||||
|
//
|
||||||
|
// free urb
|
||||||
|
//
|
||||||
|
FreeItem(Urb);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// store result
|
||||||
|
//
|
||||||
|
*OutDescriptor = Descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_GetDescriptors(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
USHORT DescriptorLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// first get device descriptor
|
||||||
|
//
|
||||||
|
Status = USBCCGP_GetDescriptor(DeviceExtension->NextDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to get device descriptor
|
||||||
|
//
|
||||||
|
DeviceExtension->DeviceDescriptor = NULL;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// now get basic configuration descriptor
|
||||||
|
//
|
||||||
|
Status = USBCCGP_GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to get configuration descriptor
|
||||||
|
//
|
||||||
|
FreeItem(DeviceExtension->DeviceDescriptor);
|
||||||
|
DeviceExtension->DeviceDescriptor = NULL;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// backup length
|
||||||
|
//
|
||||||
|
DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// release basic descriptor
|
||||||
|
//
|
||||||
|
FreeItem(DeviceExtension->ConfigurationDescriptor);
|
||||||
|
DeviceExtension->ConfigurationDescriptor = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocate full descriptor
|
||||||
|
//
|
||||||
|
Status = USBCCGP_GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to get configuration descriptor
|
||||||
|
//
|
||||||
|
FreeItem(DeviceExtension->DeviceDescriptor);
|
||||||
|
DeviceExtension->DeviceDescriptor = NULL;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
USBCCGP_ScanConfigurationDescriptor(
|
||||||
|
IN OUT PFDO_DEVICE_EXTENSION FDODeviceExtension,
|
||||||
|
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
|
||||||
|
{
|
||||||
|
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
|
||||||
|
ULONG InterfaceIndex = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity checks
|
||||||
|
//
|
||||||
|
ASSERT(ConfigurationDescriptor);
|
||||||
|
ASSERT(ConfigurationDescriptor->bNumInterfaces);
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocate array holding the interface descriptors
|
||||||
|
//
|
||||||
|
FDODeviceExtension->InterfaceList = AllocateItem(NonPagedPool, sizeof(USB_CONFIGURATION_DESCRIPTOR) * (ConfigurationDescriptor->bNumInterfaces + 1));
|
||||||
|
if (!FDODeviceExtension->InterfaceList)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// parse configuration descriptor
|
||||||
|
//
|
||||||
|
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, InterfaceIndex, 0, -1, -1, -1);
|
||||||
|
if (InterfaceDescriptor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// store in interface list
|
||||||
|
//
|
||||||
|
FDODeviceExtension->InterfaceList[FDODeviceExtension->InterfaceListCount].InterfaceDescriptor = InterfaceDescriptor;
|
||||||
|
FDODeviceExtension->InterfaceListCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next interface
|
||||||
|
//
|
||||||
|
InterfaceIndex++;
|
||||||
|
|
||||||
|
}while(InterfaceIndex < ConfigurationDescriptor->bNumInterfaces);
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
ASSERT(FDODeviceExtension->InterfaceListCount);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
|
||||||
|
{
|
||||||
|
DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
|
||||||
|
DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength);
|
||||||
|
DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
|
||||||
|
DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
|
||||||
|
DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
|
||||||
|
DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
|
||||||
|
DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
|
||||||
|
DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
|
||||||
|
DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_SelectInterface(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PFDO_DEVICE_EXTENSION DeviceExtension,
|
||||||
|
IN ULONG InterfaceIndex)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PURB Urb;
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocate urb
|
||||||
|
//
|
||||||
|
Urb = AllocateItem(NonPagedPool, sizeof(struct _URB_SELECT_INTERFACE));
|
||||||
|
if (!Urb)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// now prepare interface urb
|
||||||
|
//
|
||||||
|
UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bInterfaceNumber, DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bAlternateSetting);
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy interface information structure back - as offset for SelectConfiguration / SelectInterface request do differ
|
||||||
|
//
|
||||||
|
RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceList[InterfaceIndex].Interface, DeviceExtension->InterfaceList[InterfaceIndex].Interface->Length);
|
||||||
|
|
||||||
|
//
|
||||||
|
// now select the interface
|
||||||
|
//
|
||||||
|
Status = USBCCGP_SyncUrbRequest(DeviceExtension->NextDeviceObject, Urb);
|
||||||
|
|
||||||
|
//
|
||||||
|
// did it succeeed
|
||||||
|
//
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// update configuration info
|
||||||
|
//
|
||||||
|
ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceList[InterfaceIndex].Interface->Length);
|
||||||
|
RtlCopyMemory(DeviceExtension->InterfaceList[InterfaceIndex].Interface, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// free urb
|
||||||
|
//
|
||||||
|
FreeItem(Urb);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_SelectConfiguration(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PFDO_DEVICE_EXTENSION DeviceExtension)
|
||||||
|
{
|
||||||
|
PUSBD_INTERFACE_INFORMATION InterfaceInformation;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PURB Urb;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
//
|
||||||
|
// now scan configuration descriptors
|
||||||
|
//
|
||||||
|
Status = USBCCGP_ScanConfigurationDescriptor(DeviceExtension, DeviceExtension->ConfigurationDescriptor);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to scan
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// now allocate the urb
|
||||||
|
//
|
||||||
|
Urb = USBD_CreateConfigurationRequestEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->InterfaceList);
|
||||||
|
if (!Urb)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// submit urb
|
||||||
|
//
|
||||||
|
Status = USBCCGP_SyncUrbRequest(DeviceExtension->NextDeviceObject, Urb);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to set configuration
|
||||||
|
//
|
||||||
|
DPRINT1("USBCCGP_SyncUrbRequest failed to set interface %x\n", Status);
|
||||||
|
ExFreePool(Urb);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// get interface information
|
||||||
|
//
|
||||||
|
InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
|
||||||
|
|
||||||
|
for(Index = 0; Index < DeviceExtension->InterfaceListCount; Index++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// allocate buffer to store interface information
|
||||||
|
//
|
||||||
|
DeviceExtension->InterfaceList[Index].Interface = AllocateItem(NonPagedPool, InterfaceInformation[Index].Length);
|
||||||
|
if (!DeviceExtension->InterfaceList[Index].Interface)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy interface information
|
||||||
|
//
|
||||||
|
RtlCopyMemory(DeviceExtension->InterfaceList[Index].Interface, InterfaceInformation, InterfaceInformation->Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// store pipe handle
|
||||||
|
//
|
||||||
|
DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// free interface list & urb
|
||||||
|
//
|
||||||
|
ExFreePool(Urb);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
289
drivers/usb/usbccgp/fdo.c
Normal file
289
drivers/usb/usbccgp/fdo.c
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/usb/usbccgp/fdo.c
|
||||||
|
* PURPOSE: USB device driver.
|
||||||
|
* PROGRAMMERS:
|
||||||
|
* Michael Martin (michael.martin@reactos.org)
|
||||||
|
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||||
|
* Cameron Gutman
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "usbccgp.h"
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
FDO_QueryCapabilitiesCompletionRoutine(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// set event
|
||||||
|
//
|
||||||
|
KeSetEvent((PRKEVENT)Context, 0, FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// completion is done in the HidClassFDO_QueryCapabilities routine
|
||||||
|
//
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FDO_QueryCapabilities(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN OUT PDEVICE_CAPABILITIES Capabilities)
|
||||||
|
{
|
||||||
|
PIRP Irp;
|
||||||
|
KEVENT Event;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
//
|
||||||
|
// init event
|
||||||
|
//
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// now allocte the irp
|
||||||
|
//
|
||||||
|
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// get next stack location
|
||||||
|
//
|
||||||
|
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// init stack location
|
||||||
|
//
|
||||||
|
IoStack->MajorFunction = IRP_MJ_PNP;
|
||||||
|
IoStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
|
||||||
|
IoStack->Parameters.DeviceCapabilities.Capabilities = Capabilities;
|
||||||
|
|
||||||
|
//
|
||||||
|
// set completion routine
|
||||||
|
//
|
||||||
|
IoSetCompletionRoutine(Irp, FDO_QueryCapabilitiesCompletionRoutine, (PVOID)&Event, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// init capabilities
|
||||||
|
//
|
||||||
|
RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
|
||||||
|
Capabilities->Size = sizeof(DEVICE_CAPABILITIES);
|
||||||
|
Capabilities->Version = 1; // FIXME hardcoded constant
|
||||||
|
Capabilities->Address = MAXULONG;
|
||||||
|
Capabilities->UINumber = MAXULONG;
|
||||||
|
|
||||||
|
//
|
||||||
|
// pnp irps have default completion code
|
||||||
|
//
|
||||||
|
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
//
|
||||||
|
// call lower device
|
||||||
|
//
|
||||||
|
Status = IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// wait for completion
|
||||||
|
//
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// get status
|
||||||
|
//
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// complete request
|
||||||
|
//
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FDO_DeviceRelations(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FDO_StartDevice(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
//
|
||||||
|
// first start lower device
|
||||||
|
//
|
||||||
|
Status = USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to start lower device
|
||||||
|
//
|
||||||
|
DPRINT1("FDO_StartDevice lower device failed to start with %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get descriptors
|
||||||
|
Status = USBCCGP_GetDescriptors(DeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
// failed to start lower device
|
||||||
|
DPRINT1("FDO_StartDevice failed to get descriptors with %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get capabilities
|
||||||
|
Status = FDO_QueryCapabilities(DeviceObject, &FDODeviceExtension->Capabilities);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
// failed to start lower device
|
||||||
|
DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now select the configuration
|
||||||
|
Status = USBCCGP_SelectConfiguration(DeviceObject, FDODeviceExtension);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
// failed to select interface
|
||||||
|
DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: parse usb interface association descriptor
|
||||||
|
// and create PDO for each function
|
||||||
|
//
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FDO_HandlePnp(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
|
|
||||||
|
// get device extension
|
||||||
|
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
ASSERT(FDODeviceExtension->Common.IsFDO);
|
||||||
|
|
||||||
|
|
||||||
|
// get stack location
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
switch(IoStack->MinorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MN_START_DEVICE:
|
||||||
|
{
|
||||||
|
Status = FDO_StartDevice(DeviceObject, Irp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
|
{
|
||||||
|
Status = FDO_DeviceRelations(DeviceObject, Irp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IRP_MN_QUERY_CAPABILITIES:
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// copy capabilities
|
||||||
|
//
|
||||||
|
RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
|
||||||
|
Status = USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// surprise removal ok
|
||||||
|
//
|
||||||
|
IoStack->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// forward irp to next device object
|
||||||
|
//
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// complete request
|
||||||
|
//
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FDO_Dispatch(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* get stack location */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
switch(IoStack->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_PNP:
|
||||||
|
return FDO_HandlePnp(DeviceObject, Irp);
|
||||||
|
default:
|
||||||
|
DPRINT1("FDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction);
|
||||||
|
ASSERT(FALSE);
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
24
drivers/usb/usbccgp/pdo.c
Normal file
24
drivers/usb/usbccgp/pdo.c
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/usb/usbccgp/fdo.c
|
||||||
|
* PURPOSE: USB device driver.
|
||||||
|
* PROGRAMMERS:
|
||||||
|
* Michael Martin (michael.martin@reactos.org)
|
||||||
|
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||||
|
* Cameron Gutman
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "usbccgp.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PDO_Dispatch(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
150
drivers/usb/usbccgp/usbccgp.c
Normal file
150
drivers/usb/usbccgp/usbccgp.c
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/usb/usbccgp/fdo.c
|
||||||
|
* PURPOSE: USB device driver.
|
||||||
|
* PROGRAMMERS:
|
||||||
|
* Michael Martin (michael.martin@reactos.org)
|
||||||
|
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||||
|
* Cameron Gutman
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "usbccgp.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// driver verifier
|
||||||
|
//
|
||||||
|
DRIVER_ADD_DEVICE USBCCGP_AddDevice;
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
USBCCGP_AddDevice(
|
||||||
|
PDRIVER_OBJECT DriverObject,
|
||||||
|
PDEVICE_OBJECT PhysicalDeviceObject)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
|
|
||||||
|
// lets create the device
|
||||||
|
Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_USB, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &DeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
// failed to create device
|
||||||
|
DPRINT1("USBCCGP_AddDevice failed to create device with %x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get device extension
|
||||||
|
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
// init device extension
|
||||||
|
RtlZeroMemory(FDODeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
|
||||||
|
FDODeviceExtension->Common.IsFDO = TRUE;
|
||||||
|
FDODeviceExtension->DriverObject = DriverObject;
|
||||||
|
FDODeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
|
||||||
|
FDODeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
|
||||||
|
if (!FDODeviceExtension->NextDeviceObject)
|
||||||
|
{
|
||||||
|
// failed to attach
|
||||||
|
DPRINT1("USBCCGP_AddDevice failed to attach device\n");
|
||||||
|
IoDeleteDevice(DeviceObject);
|
||||||
|
return STATUS_DEVICE_REMOVED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set device flags
|
||||||
|
DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
|
||||||
|
|
||||||
|
// device is initialized
|
||||||
|
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
|
// device initialized
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
USBCCGP_CreateClose(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
|
|
||||||
|
// get common device extension
|
||||||
|
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
// is it a fdo
|
||||||
|
if (DeviceExtension->IsFDO)
|
||||||
|
{
|
||||||
|
// forward and forget
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
// get fdo
|
||||||
|
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
// call lower driver
|
||||||
|
return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// pdo not supported
|
||||||
|
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
USBCCGP_Dispatch(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
|
||||||
|
// get common device extension
|
||||||
|
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
// get current stack location
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
if (IoStack->MajorFunction == IRP_MJ_CREATE || IoStack->MajorFunction == IRP_MJ_CLOSE)
|
||||||
|
{
|
||||||
|
// dispatch to default handler
|
||||||
|
return USBCCGP_CreateClose(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DeviceExtension->IsFDO)
|
||||||
|
{
|
||||||
|
// handle request for FDO
|
||||||
|
return FDO_Dispatch(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// handle request for PDO
|
||||||
|
return PDO_Dispatch(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DriverEntry(
|
||||||
|
PDRIVER_OBJECT DriverObject,
|
||||||
|
PUNICODE_STRING RegistryPath)
|
||||||
|
{
|
||||||
|
|
||||||
|
// initialize driver object
|
||||||
|
DriverObject->DriverExtension->AddDevice = USBCCGP_AddDevice;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = USBCCGP_Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBCCGP_Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBCCGP_Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = USBCCGP_Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_POWER] = USBCCGP_Dispatch;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_PNP] = USBCCGP_Dispatch;
|
||||||
|
|
||||||
|
// FIMXE query GenericCompositeUSBDeviceString
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
96
drivers/usb/usbccgp/usbccgp.h
Normal file
96
drivers/usb/usbccgp/usbccgp.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#ifndef USBEHCI_H__
|
||||||
|
#define USBEHCI_H__
|
||||||
|
|
||||||
|
#include <ntddk.h>
|
||||||
|
#define YDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
#include <hubbusif.h>
|
||||||
|
#include <usbbusif.h>
|
||||||
|
#include <usbioctl.h>
|
||||||
|
#include <usbdlib.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME:
|
||||||
|
// #include <usbprotocoldefs.h>
|
||||||
|
//
|
||||||
|
#include <usb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <wdmguid.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BOOLEAN IsFDO; // is device a FDO or PDO
|
||||||
|
}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
COMMON_DEVICE_EXTENSION Common; // shared with PDO
|
||||||
|
PDRIVER_OBJECT DriverObject; // driver object
|
||||||
|
PDEVICE_OBJECT PhysicalDeviceObject; // physical device object
|
||||||
|
PDEVICE_OBJECT NextDeviceObject; // lower device object
|
||||||
|
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor; // usb device descriptor
|
||||||
|
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; // usb configuration descriptor
|
||||||
|
DEVICE_CAPABILITIES Capabilities; // device capabilities
|
||||||
|
PUSBD_INTERFACE_LIST_ENTRY InterfaceList; // interface list
|
||||||
|
ULONG InterfaceListCount; // interface list count
|
||||||
|
USBD_CONFIGURATION_HANDLE ConfigurationHandle; // configuration handle
|
||||||
|
}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
#define USBCCPG_TAG 'cbsu'
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
COMMON_DEVICE_EXTENSION Common; // shared with FDO
|
||||||
|
|
||||||
|
}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
/* descriptor.c */
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_GetDescriptors(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_SelectConfiguration(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PFDO_DEVICE_EXTENSION DeviceExtension);
|
||||||
|
|
||||||
|
/* misc.c */
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
USBCCGP_SyncForwardIrp(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
USBCCGP_SyncUrbRequest(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
OUT PURB UrbRequest);
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
AllocateItem(
|
||||||
|
IN POOL_TYPE PoolType,
|
||||||
|
IN ULONG ItemSize);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FreeItem(
|
||||||
|
IN PVOID Item);
|
||||||
|
|
||||||
|
/* fdo.c */
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FDO_Dispatch(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp);
|
||||||
|
|
||||||
|
/* pdo.c */
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PDO_Dispatch(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
5
drivers/usb/usbccgp/usbccgp.rc
Normal file
5
drivers/usb/usbccgp/usbccgp.rc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#define REACTOS_VERSION_DLL
|
||||||
|
#define REACTOS_STR_FILE_DESCRIPTION "USBCCGP Driver\0"
|
||||||
|
#define REACTOS_STR_INTERNAL_NAME "usccpg\0"
|
||||||
|
#define REACTOS_STR_ORIGINAL_FILENAME "usbccpg.sys\0"
|
||||||
|
#include <reactos/version.rc>
|
Loading…
Add table
Add a link
Reference in a new issue