From ff46d90618147a15a0bc3bb66b9d28cdb5d4595a Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Wed, 28 Sep 2016 20:31:32 +0000 Subject: [PATCH] [USBAUDIO] - implement USBAudioSelectAudioStreamingInterface svn path=/trunk/; revision=72843 --- reactos/drivers/usb/usbaudio/filter.c | 1 + reactos/drivers/usb/usbaudio/pin.c | 248 ++++++++++++++++++------ reactos/drivers/usb/usbaudio/usbaudio.c | 8 - 3 files changed, 187 insertions(+), 70 deletions(-) diff --git a/reactos/drivers/usb/usbaudio/filter.c b/reactos/drivers/usb/usbaudio/filter.c index f270afc46b7..fe76f5550b4 100644 --- a/reactos/drivers/usb/usbaudio/filter.c +++ b/reactos/drivers/usb/usbaudio/filter.c @@ -136,6 +136,7 @@ USBAudioFilterCreate( FilterContext->LowerDevice = Device->NextDeviceObject; Filter->Context = FilterContext; + DPRINT("USBAudioFilterCreate FilterContext %p LowerDevice %p DeviceExtension %p\n", FilterContext, FilterContext->LowerDevice, FilterContext->DeviceExtension); KsAddItemToObjectBag(Filter->Bag, FilterContext, ExFreePool); return STATUS_SUCCESS; } diff --git a/reactos/drivers/usb/usbaudio/pin.c b/reactos/drivers/usb/usbaudio/pin.c index e9d5c05a76e..f0a50dad416 100644 --- a/reactos/drivers/usb/usbaudio/pin.c +++ b/reactos/drivers/usb/usbaudio/pin.c @@ -9,6 +9,167 @@ #include "usbaudio.h" +NTSTATUS +UsbAudioSetFormat( + IN PKSPIN Pin) +{ + PURB Urb; + PUCHAR SampleRateBuffer; + PPIN_CONTEXT PinContext; + NTSTATUS Status; + PKSDATAFORMAT_WAVEFORMATEX WaveFormatEx; + + /* allocate sample rate buffer */ + SampleRateBuffer = AllocFunction(sizeof(ULONG)); + if (!SampleRateBuffer) + { + /* no memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + if (IsEqualGUIDAligned(&Pin->ConnectionFormat->MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) && + IsEqualGUIDAligned(&Pin->ConnectionFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) && + IsEqualGUIDAligned(&Pin->ConnectionFormat->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) + { + WaveFormatEx = (PKSDATAFORMAT_WAVEFORMATEX)Pin->ConnectionFormat; + SampleRateBuffer[0] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 16) & 0xFF; + SampleRateBuffer[1] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 8) & 0xFF; + SampleRateBuffer[2] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 0) & 0xFF; + + /* TODO: verify connection format */ + } + else + { + /* not supported yet*/ + UNIMPLEMENTED; + FreeFunction(SampleRateBuffer); + return STATUS_INVALID_PARAMETER; + } + + /* allocate urb */ + Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); + if (!Urb) + { + /* no memory */ + FreeFunction(SampleRateBuffer); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* format urb */ + UsbBuildVendorRequest(Urb, + URB_FUNCTION_CLASS_ENDPOINT, + sizeof(URB), + USBD_TRANSFER_DIRECTION_OUT, + 0, + 0x01, + 0x100, + 0x81, //FIXME bEndpointAddress + SampleRateBuffer, + NULL, + 3, + NULL); + + /* get pin context */ + PinContext = Pin->Context; + DbgBreakPoint(); + /* submit urb */ + Status = SubmitUrbSync(PinContext->LowerDevice, Urb); + + DPRINT1("USBAudioPinSetDataFormat Pin %p Status %x\n", Pin, Status); + FreeFunction(Urb); + FreeFunction(SampleRateBuffer); + return Status; +} + +NTSTATUS +USBAudioSelectAudioStreamingInterface( + IN PDEVICE_EXTENSION DeviceExtension, + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor) +{ + PURB Urb; + PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + NTSTATUS Status; + + /* grab interface descriptor */ + InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); + if (!InterfaceDescriptor) + { + /* no such interface */ + return STATUS_INVALID_PARAMETER; + } + + /* select the first interface with audio streaming and non zero num of endpoints */ + while (InterfaceDescriptor != NULL) + { + if (InterfaceDescriptor->bInterfaceSubClass == 0x02 /* AUDIO_STREAMING */ && InterfaceDescriptor->bNumEndpoints > 0) + { + break; + } + InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); + } + + if (!InterfaceDescriptor) + { + /* no such interface */ + return STATUS_INVALID_PARAMETER; + } + + Urb = AllocFunction(GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints)); + if (!Urb) + { + /* no memory */ + return USBD_STATUS_INSUFFICIENT_RESOURCES; + } + + /* now prepare interface urb */ + UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting); + + /* copy interface information */ + RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceInfo, DeviceExtension->InterfaceInfo->Length); + + /* set configuration handle */ + Urb->UrbSelectInterface.ConfigurationHandle = DeviceExtension->ConfigurationHandle; + + /* now select the interface */ + Status = SubmitUrbSync(DeviceExtension->LowerDevice, Urb); + + DPRINT1("USBAudioSelectAudioStreamingInterface Status %x UrbStatus %x\n", Status, Urb->UrbSelectInterface.Hdr.Status); + + /* did it succeeed */ + if (NT_SUCCESS(Status)) + { + /* update configuration info */ + ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceInfo->Length); + RtlCopyMemory(DeviceExtension->InterfaceInfo, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length); + } + + /* free urb */ + FreeFunction(Urb); + return Status; +} + +NTSTATUS +InitCapturePin( + IN PKSPIN Pin) +{ + NTSTATUS Status; + + /* set sample rate */ + Status = UsbAudioSetFormat(Pin); + + /* TODO: init pin */ + return Status; +} + +NTSTATUS +InitStreamPin( + IN PKSPIN Pin) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + + NTSTATUS NTAPI USBAudioPinCreate( @@ -18,6 +179,7 @@ USBAudioPinCreate( PKSFILTER Filter; PFILTER_CONTEXT FilterContext; PPIN_CONTEXT PinContext; + NTSTATUS Status; Filter = KsPinGetParentFilter(Pin); if (Filter == NULL) @@ -44,6 +206,25 @@ USBAudioPinCreate( /* store pin context*/ Pin->Context = PinContext; + /* select streaming interface */ + Status = USBAudioSelectAudioStreamingInterface(PinContext->DeviceExtension, PinContext->DeviceExtension->ConfigurationDescriptor); + if (!NT_SUCCESS(Status)) + { + /* failed */ + return Status; + } + + if (Pin->DataFlow == KSPIN_DATAFLOW_OUT) + { + /* init capture pin */ + Status = InitCapturePin(Pin); + } + else + { + /* audio streaming pin*/ + Status = InitStreamPin(Pin); + } + return STATUS_SUCCESS; } @@ -63,7 +244,6 @@ NTAPI USBAudioPinProcess( _In_ PKSPIN Pin) { - UNIMPLEMENTED return STATUS_SUCCESS; } @@ -85,70 +265,14 @@ USBAudioPinSetDataFormat( _In_ const KSDATARANGE* DataRange, _In_opt_ const KSATTRIBUTE_LIST* AttributeRange) { - PURB Urb; - PUCHAR SampleRateBuffer; - PPIN_CONTEXT PinContext; - NTSTATUS Status; - PKSDATAFORMAT_WAVEFORMATEX WaveFormatEx; - - /* allocate sample rate buffer */ - SampleRateBuffer = AllocFunction(sizeof(ULONG)); - if (!SampleRateBuffer) + if (OldFormat == NULL) { - /* no memory */ - return STATUS_INSUFFICIENT_RESOURCES; + /* TODO: verify connection format */ + UNIMPLEMENTED + return STATUS_SUCCESS; } - if (IsEqualGUIDAligned(&Pin->ConnectionFormat->MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) && - IsEqualGUIDAligned(&Pin->ConnectionFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) && - IsEqualGUIDAligned(&Pin->ConnectionFormat->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) - { - WaveFormatEx = (PKSDATAFORMAT_WAVEFORMATEX)Pin->ConnectionFormat; - SampleRateBuffer[0] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 16) & 0xFF; - SampleRateBuffer[1] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 8) & 0xFF; - SampleRateBuffer[2] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 0) & 0xFF; - } - else - { - /* not supported yet*/ - UNIMPLEMENTED; - FreeFunction(SampleRateBuffer); - return STATUS_INVALID_PARAMETER; - } - - /* allocate urb */ - Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); - if (!Urb) - { - /* no memory */ - FreeFunction(SampleRateBuffer); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* format urb */ - UsbBuildVendorRequest(Urb, - URB_FUNCTION_CLASS_ENDPOINT, - sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), - USBD_TRANSFER_DIRECTION_OUT, - 0, - 0x01, - 0x100, - 0x81, //bEndpointAddress - SampleRateBuffer, - NULL, - 3, - NULL); - - /* get pin context */ - PinContext = Pin->Context; - DbgBreakPoint(); - /* submit urb */ - Status = SubmitUrbSync(PinContext->LowerDevice, Urb); - - DPRINT1("USBAudioPinSetDataFormat Pin %p Status %x\n", Pin, Status); - FreeFunction(Urb); - FreeFunction(SampleRateBuffer); - return Status; + return UsbAudioSetFormat(Pin); } NTSTATUS diff --git a/reactos/drivers/usb/usbaudio/usbaudio.c b/reactos/drivers/usb/usbaudio/usbaudio.c index 04619c166a9..01ac7d0c180 100644 --- a/reactos/drivers/usb/usbaudio/usbaudio.c +++ b/reactos/drivers/usb/usbaudio/usbaudio.c @@ -79,14 +79,6 @@ SubmitUrbSync( if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - } - - // complete request - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - if (Status == STATUS_PENDING) - { - // get final status Status = IoStatus.Status; }