[USBAUDIO]

- implement GetMaxPacketSizeForInterface, UsbAudioAllocCaptureUrbIso, InitCapturePin

svn path=/trunk/; revision=72865
This commit is contained in:
Johannes Anderwald 2016-09-29 22:19:34 +00:00
parent ad3aa035db
commit 8895dae5d0
2 changed files with 161 additions and 8 deletions

View file

@ -9,6 +9,90 @@
#include "usbaudio.h"
NTSTATUS
GetMaxPacketSizeForInterface(
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
IN PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor,
KSPIN_DATAFLOW DataFlow)
{
PUSB_COMMON_DESCRIPTOR CommonDescriptor;
PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
/* loop descriptors */
CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
ASSERT(InterfaceDescriptor->bNumEndpoints > 0);
while (CommonDescriptor)
{
if (CommonDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE)
{
EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)CommonDescriptor;
return EndpointDescriptor->wMaxPacketSize;
}
if (CommonDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
{
/* reached next interface descriptor */
break;
}
if ((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
break;
CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
}
/* default to 100 */
return 100;
}
NTSTATUS
UsbAudioAllocCaptureUrbIso(
IN USBD_PIPE_HANDLE PipeHandle,
IN ULONG MaxPacketSize,
IN PVOID Buffer,
IN ULONG BufferLength,
OUT PURB * OutUrb)
{
PURB Urb;
ULONG PacketCount;
ULONG UrbSize;
ULONG Index;
/* calculate packet count */
PacketCount = BufferLength / MaxPacketSize;
/* calculate urb size*/
UrbSize = GET_ISO_URB_SIZE(PacketCount);
/* allocate urb */
Urb = AllocFunction(UrbSize);
if (!Urb)
{
/* no memory */
return STATUS_INSUFFICIENT_RESOURCES;
}
/* init urb */
Urb->UrbIsochronousTransfer.Hdr.Function = URB_FUNCTION_ISOCH_TRANSFER;
Urb->UrbIsochronousTransfer.Hdr.Length = UrbSize;
Urb->UrbIsochronousTransfer.PipeHandle = PipeHandle;
Urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_START_ISO_TRANSFER_ASAP;
Urb->UrbIsochronousTransfer.TransferBufferLength = BufferLength;
Urb->UrbIsochronousTransfer.TransferBuffer = Buffer;
Urb->UrbIsochronousTransfer.NumberOfPackets = PacketCount;
for (Index = 0; Index < PacketCount; Index++)
{
Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * MaxPacketSize;
}
*OutUrb = Urb;
return STATUS_SUCCESS;
}
NTSTATUS
UsbAudioSetFormat(
IN PKSPIN Pin)
@ -83,6 +167,7 @@ UsbAudioSetFormat(
NTSTATUS
USBAudioSelectAudioStreamingInterface(
IN PPIN_CONTEXT PinContext,
IN PDEVICE_EXTENSION DeviceExtension,
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
{
@ -98,7 +183,7 @@ USBAudioSelectAudioStreamingInterface(
return STATUS_INVALID_PARAMETER;
}
/* select the first interface with audio streaming and non zero num of endpoints */
/* FIXME selects the first interface with audio streaming and non zero num of endpoints */
while (InterfaceDescriptor != NULL)
{
if (InterfaceDescriptor->bInterfaceSubClass == 0x02 /* AUDIO_STREAMING */ && InterfaceDescriptor->bNumEndpoints > 0)
@ -127,9 +212,6 @@ USBAudioSelectAudioStreamingInterface(
/* 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);
@ -141,6 +223,7 @@ USBAudioSelectAudioStreamingInterface(
/* update configuration info */
ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceInfo->Length);
RtlCopyMemory(DeviceExtension->InterfaceInfo, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length);
PinContext->InterfaceDescriptor = InterfaceDescriptor;
}
/* free urb */
@ -153,11 +236,76 @@ InitCapturePin(
IN PKSPIN Pin)
{
NTSTATUS Status;
ULONG Index;
ULONG BufferSize;
ULONG MaximumPacketSize;
PIRP Irp;
PURB Urb;
PPIN_CONTEXT PinContext;
PIO_STACK_LOCATION IoStack;
/* set sample rate */
Status = UsbAudioSetFormat(Pin);
if (!NT_SUCCESS(Status))
{
/* failed */
return Status;
}
/* TODO: init pin */
/* get pin context */
PinContext = Pin->Context;
DbgBreakPoint();
MaximumPacketSize = GetMaxPacketSizeForInterface(PinContext->DeviceExtension->ConfigurationDescriptor, PinContext->InterfaceDescriptor, Pin->DataFlow);
/* calculate buffer size 8 irps * 10 iso packets * max packet size */
BufferSize = 8 * 10 * MaximumPacketSize;
/* allocate pin capture buffer */
PinContext->Buffer = AllocFunction(BufferSize);
if (!PinContext->Buffer)
{
/* no memory */
return STATUS_INSUFFICIENT_RESOURCES;
}
KsAddItemToObjectBag(Pin->Bag, PinContext->Buffer, ExFreePool);
/* init irps */
for (Index = 0; Index < 8; Index++)
{
/* allocate irp */
Irp = IoAllocateIrp(PinContext->DeviceExtension->LowerDevice->StackSize, FALSE);
if (!Irp)
{
/* no memory */
return STATUS_INSUFFICIENT_RESOURCES;
}
/* insert into irp list */
InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
/* add to object bag*/
KsAddItemToObjectBag(Pin->Bag, Irp, IoFreeIrp);
Status = UsbAudioAllocCaptureUrbIso(PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle,
MaximumPacketSize,
&PinContext->Buffer[MaximumPacketSize * 10 * Index],
MaximumPacketSize * 10,
&Urb);
if (NT_SUCCESS(Status))
{
/* get next stack location */
IoStack = IoGetNextIrpStackLocation(Irp);
/* store urb */
IoStack->Parameters.Others.Argument1 = Urb;
}
else
{
/* failed */
return Status;
}
}
return Status;
}
@ -202,12 +350,13 @@ USBAudioPinCreate(
/* init pin context */
PinContext->DeviceExtension = FilterContext->DeviceExtension;
PinContext->LowerDevice = FilterContext->LowerDevice;
InitializeListHead(&PinContext->IrpListHead);
/* store pin context*/
Pin->Context = PinContext;
/* select streaming interface */
Status = USBAudioSelectAudioStreamingInterface(PinContext->DeviceExtension, PinContext->DeviceExtension->ConfigurationDescriptor);
Status = USBAudioSelectAudioStreamingInterface(PinContext, PinContext->DeviceExtension, PinContext->DeviceExtension->ConfigurationDescriptor);
if (!NT_SUCCESS(Status))
{
/* failed */

View file

@ -119,8 +119,12 @@ typedef struct
typedef struct
{
PDEVICE_EXTENSION DeviceExtension; /* device extension */
PDEVICE_OBJECT LowerDevice; /* lower device*/
PDEVICE_EXTENSION DeviceExtension; /* device extension */
PDEVICE_OBJECT LowerDevice; /* lower device*/
LIST_ENTRY IrpListHead; /* irp list*/
PUCHAR Buffer; /* iso buffer*/
ULONG BufferSize; /* iso buffer size */
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; /* interface descriptor */
}PIN_CONTEXT, *PPIN_CONTEXT;