From eb204e920dc087eaf34dbedd5e03cd52e94a8fae Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 7 Oct 2016 17:30:27 +0000 Subject: [PATCH] [USBAUDIO] - use IoInitializeIrp over IoAllocateIrp - reinitialize irp and urb when resubmitting it - usbaudio now successfully transfers stream irps (not yet fully working) svn path=/trunk/; revision=72925 --- reactos/drivers/usb/usbaudio/filter.c | 1 + reactos/drivers/usb/usbaudio/pin.c | 141 ++++++++++++++++++-------- 2 files changed, 98 insertions(+), 44 deletions(-) diff --git a/reactos/drivers/usb/usbaudio/filter.c b/reactos/drivers/usb/usbaudio/filter.c index fe76f5550b4..a1af3eab672 100644 --- a/reactos/drivers/usb/usbaudio/filter.c +++ b/reactos/drivers/usb/usbaudio/filter.c @@ -450,6 +450,7 @@ USBAudioPinBuildDescriptors( /* irp sinks / sources can be instantiated */ Pins[Index].InstancesPossible = 1; + Pins[Index].InstancesNecessary = 1; } else { diff --git a/reactos/drivers/usb/usbaudio/pin.c b/reactos/drivers/usb/usbaudio/pin.c index c4a034d604c..f573e8721b4 100644 --- a/reactos/drivers/usb/usbaudio/pin.c +++ b/reactos/drivers/usb/usbaudio/pin.c @@ -8,6 +8,7 @@ */ #include "usbaudio.h" +#include NTSTATUS GetMaxPacketSizeForInterface( @@ -283,6 +284,7 @@ InitCapturePin( BufferSize = 8 * 10 * MaximumPacketSize; /* allocate pin capture buffer */ + PinContext->BufferSize = BufferSize; PinContext->Buffer = AllocFunction(BufferSize); if (!PinContext->Buffer) { @@ -295,13 +297,28 @@ InitCapturePin( for (Index = 0; Index < 8; Index++) { /* allocate irp */ - Irp = IoAllocateIrp(PinContext->DeviceExtension->LowerDevice->StackSize, FALSE); + Irp = AllocFunction(IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize)); if (!Irp) { /* no memory */ return STATUS_INSUFFICIENT_RESOURCES; } + /* initialize irp */ + IoInitializeIrp(Irp, IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize), PinContext->DeviceExtension->LowerDevice->StackSize); + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + Irp->IoStatus.Information = 0; + Irp->Flags = 0; + Irp->UserBuffer = NULL; + + IoStack = IoGetNextIrpStackLocation(Irp); + IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice; + IoStack->Parameters.Others.Argument2 = NULL; + IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; + + DPRINT1("InitCapturePin Irp %p\n", Irp); /* insert into irp list */ InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry); @@ -433,11 +450,22 @@ UsbAudioCaptureComplete( PKSPIN Pin; PPIN_CONTEXT PinContext; KIRQL OldLevel; + PURB Urb; + PIO_STACK_LOCATION IoStack; + /* get pin context */ Pin = Context; PinContext = Pin->Context; + /* get stack location */ + IoStack = IoGetNextIrpStackLocation(Irp); + + /* get urb */ + Urb = Irp->Tail.Overlay.DriverContext[0]; + + //DPRINT("UsbAudioCaptureComplete Irp %p Urb %p\n", Irp, Urb); + /* acquire lock */ KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel); @@ -447,8 +475,6 @@ UsbAudioCaptureComplete( /* release lock */ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel); - DPRINT1("UsbAudioCaptureComplete Irp %p\n", Irp); - /* done */ return STATUS_MORE_PROCESSING_REQUIRED; } @@ -464,8 +490,10 @@ PinCaptureProcess( PIRP Irp; PIO_STACK_LOCATION IoStack; PURB Urb; - PUCHAR TransferBuffer; - ULONG Index, Offset; + PUCHAR TransferBuffer, OutBuffer; + ULONG Index, Offset, MaximumPacketSize, Length; + NTSTATUS Status; + //PUSHORT SoundBuffer; LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin, KSSTREAM_POINTER_STATE_LOCKED); if (LeadingStreamPointer == NULL) @@ -502,56 +530,48 @@ PinCaptureProcess( /* get transfer buffer */ TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer; - /* copy data */ - if (LeadingStreamPointer->OffsetOut.Remaining >= Urb->UrbIsochronousTransfer.IsoPacket[Index].Length) - { - /* copy buffer */ - RtlCopyMemory((PUCHAR)LeadingStreamPointer->OffsetOut.Data, &TransferBuffer[Offset], Urb->UrbIsochronousTransfer.IsoPacket[Index].Length); - } - else - { - /* advance to next frame */ - KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, 0, TRUE); + /* get target buffer */ + OutBuffer = (PUCHAR)LeadingStreamPointer->StreamHeader->Data; + + /* calculate length */ + Length = min(LeadingStreamPointer->OffsetOut.Count - LeadingStreamPointer->StreamHeader->DataUsed, Urb->UrbIsochronousTransfer.IsoPacket[Index].Length); + + //DPRINT1("DataUsed %lu Count %lu Remaining %lu Copying %lu Data %p\n", LeadingStreamPointer->StreamHeader->DataUsed, LeadingStreamPointer->OffsetOut.Count, LeadingStreamPointer->OffsetOut.Remaining, Length, LeadingStreamPointer->OffsetOut.Data); + + /* copy buffer */ + RtlCopyMemory((PUCHAR)&OutBuffer[LeadingStreamPointer->StreamHeader->DataUsed], &TransferBuffer[Offset], Length); + + LeadingStreamPointer->StreamHeader->DataUsed += Length; + + if (Length == LeadingStreamPointer->OffsetOut.Remaining) { + KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, Length, TRUE); + LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin, KSSTREAM_POINTER_STATE_LOCKED); if (LeadingStreamPointer == NULL) { /* FIXME handle half processed packets */ //ASSERT(FALSE); - break; - } + //DPRINT1("Warning: ignoring %lu packets\n", Urb->UrbIsochronousTransfer.NumberOfPackets - Index); - ASSERT(LeadingStreamPointer->OffsetOut.Remaining >= Urb->UrbIsochronousTransfer.IsoPacket[Index].Length); + /* acquire spin lock */ + KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel); - /* copy buffer */ - RtlCopyMemory((PUCHAR)LeadingStreamPointer->OffsetOut.Data, &TransferBuffer[Offset], Urb->UrbIsochronousTransfer.IsoPacket[Index].Length); - } + InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry); - if (LeadingStreamPointer->OffsetOut.Remaining == Urb->UrbIsochronousTransfer.IsoPacket[Index].Length) - { - KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, Urb->UrbIsochronousTransfer.IsoPacket[Index].Length, TRUE); - LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin, KSSTREAM_POINTER_STATE_LOCKED); - if (LeadingStreamPointer == NULL) - break; + KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel); + return STATUS_SUCCESS; + } } else { - KsStreamPointerAdvanceOffsets(LeadingStreamPointer, 0, Urb->UrbIsochronousTransfer.IsoPacket[Index].Length, FALSE); + Status = KsStreamPointerAdvanceOffsets(LeadingStreamPointer, 0, Length, FALSE); } } + /* acquire spin lock */ KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel); - /* get next stack location */ - IoStack = IoGetNextIrpStackLocation(Irp); - - /* init stack location */ - IoStack->Parameters.Others.Argument1 = Urb; - IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; - IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; - - IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE); - InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry); if (LeadingStreamPointer == NULL) @@ -563,22 +583,51 @@ PinCaptureProcess( /* remove entry from list */ CurEntry = RemoveHeadList(&PinContext->IrpListHead); + /* release lock */ + KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel); + /* get irp offset */ Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry); - /* get next stack location */ - IoStack = IoGetNextIrpStackLocation(Irp); + /* backup urb and transferbuffer */ + Urb = Irp->Tail.Overlay.DriverContext[0]; + TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer; + + /* initialize irp */ + IoInitializeIrp(Irp, IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize), PinContext->DeviceExtension->LowerDevice->StackSize); + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + Irp->IoStatus.Information = 0; + Irp->Flags = 0; + Irp->UserBuffer = NULL; + Irp->Tail.Overlay.DriverContext[0] = Urb; /* init stack location */ + IoStack = IoGetNextIrpStackLocation(Irp); + IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice; + IoStack->Parameters.Others.Argument1 = Urb; + IoStack->Parameters.Others.Argument2 = NULL; IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE); - /* release lock */ - KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel); + RtlZeroMemory(Urb, GET_ISO_URB_SIZE(10)); + + /* init urb */ + Urb->UrbIsochronousTransfer.Hdr.Function = URB_FUNCTION_ISOCH_TRANSFER; + Urb->UrbIsochronousTransfer.Hdr.Length = GET_ISO_URB_SIZE(10); + Urb->UrbIsochronousTransfer.PipeHandle = PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle; + Urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_START_ISO_TRANSFER_ASAP; + Urb->UrbIsochronousTransfer.TransferBufferLength = PinContext->DeviceExtension->InterfaceInfo->Pipes[0].MaximumPacketSize * 10; + Urb->UrbIsochronousTransfer.TransferBuffer = TransferBuffer; + Urb->UrbIsochronousTransfer.NumberOfPackets = 10; + + for (Index = 0; Index < 10; Index++) + { + Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * 100; + } - DPRINT1("PinCaptureProcess Irp %p\n", Irp); IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp); /* acquire spin lock */ @@ -651,6 +700,7 @@ StartCaptureIsocTransfer( PPIN_CONTEXT PinContext; PLIST_ENTRY CurEntry; PIRP Irp; + PURB Urb; PIO_STACK_LOCATION IoStack; NTSTATUS Status; KIRQL OldLevel; @@ -677,12 +727,15 @@ StartCaptureIsocTransfer( IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; + /* backup urb */ + Urb = Irp->Tail.Overlay.DriverContext[0] = IoStack->Parameters.Others.Argument1; + IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE); /* release lock */ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel); - DPRINT1("StartCaptureIsocTransfer Irp %p\n", Irp); + DPRINT("StartCaptureIsocTransfer Irp %p Urb %p TransferBuffer %p\n", Irp, Urb, Urb->UrbIsochronousTransfer.TransferBuffer); Status = IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp); /* acquire spin lock */ -- 2.17.1