From 8895dae5d073f982f456c979a699d2570d51583f Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 29 Sep 2016 22:19:34 +0000 Subject: [PATCH] [USBAUDIO] - implement GetMaxPacketSizeForInterface, UsbAudioAllocCaptureUrbIso, InitCapturePin svn path=/trunk/; revision=72865 --- reactos/drivers/usb/usbaudio/pin.c | 161 +++++++++++++++++++++++- reactos/drivers/usb/usbaudio/usbaudio.h | 8 +- 2 files changed, 161 insertions(+), 8 deletions(-) diff --git a/reactos/drivers/usb/usbaudio/pin.c b/reactos/drivers/usb/usbaudio/pin.c index 924c5bd3e9b..9daecd47040 100644 --- a/reactos/drivers/usb/usbaudio/pin.c +++ b/reactos/drivers/usb/usbaudio/pin.c @@ -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 */ diff --git a/reactos/drivers/usb/usbaudio/usbaudio.h b/reactos/drivers/usb/usbaudio/usbaudio.h index ee754b7bf7b..41daedef8ca 100644 --- a/reactos/drivers/usb/usbaudio/usbaudio.h +++ b/reactos/drivers/usb/usbaudio/usbaudio.h @@ -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; -- 2.17.1