[USBCCGP]

- Start implementing select configuration request

svn path=/branches/usb-bringup-trunk/; revision=55278
This commit is contained in:
Johannes Anderwald 2012-01-28 19:49:53 +00:00
parent 35f0f5f497
commit 312148342c
3 changed files with 150 additions and 3 deletions

View file

@ -279,6 +279,7 @@ FDO_CreateChildPdo(
PDODeviceExtension->FunctionDescriptor = &FDODeviceExtension->FunctionDescriptor[Index];
PDODeviceExtension->NextDeviceObject = DeviceObject;
PDODeviceExtension->FunctionIndex = Index;
PDODeviceExtension->ConfigurationHandle = FDODeviceExtension->ConfigurationHandle;
PDODeviceExtension->ConfigurationDescriptor = FDODeviceExtension->ConfigurationDescriptor;
RtlCopyMemory(&PDODeviceExtension->Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
RtlCopyMemory(&PDODeviceExtension->DeviceDescriptor, &FDODeviceExtension->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));

View file

@ -512,6 +512,137 @@ USBCCGP_BuildConfigurationDescriptor(
return STATUS_SUCCESS;
}
NTSTATUS
USBCCGP_PDOSelectConfiguration(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PURB Urb;
PUSBD_INTERFACE_INFORMATION InterfaceInformation;
ULONG InterfaceInformationCount, Index, InterfaceIndex;
PUSBD_INTERFACE_LIST_ENTRY Entry;
ULONG NeedSelect;
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
//
// get device extension
//
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// get urb
//
Urb = (PURB)IoStack->Parameters.Others.Argument1;
ASSERT(Urb);
//
// is there already an configuration handle
//
if (Urb->UrbSelectConfiguration.ConfigurationHandle)
{
//
// nothing to do
//
return STATUS_SUCCESS;
}
//
// count interface information
//
InterfaceInformationCount = 0;
InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
do
{
InterfaceInformationCount++;
InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + InterfaceInformation->Length);
}while((ULONG_PTR)InterfaceInformation < (ULONG_PTR)Urb + Urb->UrbSelectConfiguration.Hdr.Length);
//
// check all interfaces
//
InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
Index = 0;
Entry = NULL;
do
{
//
// search for the interface
//
for(InterfaceIndex = 0; InterfaceIndex < PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; InterfaceIndex++)
{
if (PDODeviceExtension->InterfaceList[InterfaceIndex].Interface->InterfaceNumber == InterfaceInformation->InterfaceNumber)
{
// found interface entry
Entry = &PDODeviceExtension->InterfaceList[InterfaceIndex];
break;
}
}
if (!Entry || Entry->InterfaceDescriptor)
{
//
// invalid parameter
//
ASSERT(FALSE);
return STATUS_INVALID_PARAMETER;
}
NeedSelect = FALSE;
if (Entry->InterfaceDescriptor->bAlternateSetting == InterfaceInformation->AlternateSetting)
{
for(InterfaceIndex = 0; Entry->InterfaceDescriptor->bNumEndpoints; InterfaceIndex++)
{
if (InterfaceInformation->Pipes[InterfaceIndex].MaximumTransferSize != Entry->Interface->Pipes[InterfaceIndex].MaximumTransferSize)
{
//
// changed interface
//
NeedSelect = TRUE;
}
}
}
else
{
//
// need select
//
NeedSelect = TRUE;
}
if (!NeedSelect)
{
//
// interface is already selected
//
ASSERT(InterfaceInformation->Length == Entry->Interface->Length);
RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
}
else
{
//
// FIXME select interface
//
UNIMPLEMENTED
ASSERT(FALSE);
}
//
// move to next information
//
InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + InterfaceInformation->Length);
Index++;
}while(Index < InterfaceInformationCount);
return STATUS_SUCCESS;
}
NTSTATUS
PDO_HandleInternalDeviceControl(
PDEVICE_OBJECT DeviceObject,
@ -539,11 +670,20 @@ PDO_HandleInternalDeviceControl(
//
Urb = (PURB)IoStack->Parameters.Others.Argument1;
ASSERT(Urb);
DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb->UrbHeader.Function);
if (Urb->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE)
if (Urb->UrbHeader.Function == URB_FUNCTION_SELECT_CONFIGURATION)
{
//
// select configuration
//
Status = USBCCGP_PDOSelectConfiguration(DeviceObject, Irp);
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
else if (Urb->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE)
{
DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb->UrbHeader.Function);
if(Urb->UrbControlDescriptorRequest.DescriptorType == USB_DEVICE_DESCRIPTOR_TYPE)
{
//
@ -581,6 +721,9 @@ PDO_HandleInternalDeviceControl(
return Status;
}
}
}

View file

@ -52,6 +52,9 @@ typedef struct
ULONG FunctionIndex; // function index
USB_DEVICE_DESCRIPTOR DeviceDescriptor; // usb device descriptor
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; // usb configuration descriptor
USBD_CONFIGURATION_HANDLE ConfigurationHandle; // configuration handle
PUSBD_INTERFACE_LIST_ENTRY InterfaceList; // interface list
ULONG InterfaceListCount; // interface list count
}PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
/* descriptor.c */