mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-29 19:26:33 +00:00
[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
This commit is contained in:
@@ -450,6 +450,7 @@ USBAudioPinBuildDescriptors(
|
||||
|
||||
/* irp sinks / sources can be instantiated */
|
||||
Pins[Index].InstancesPossible = 1;
|
||||
Pins[Index].InstancesNecessary = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include "usbaudio.h"
|
||||
#include <math.h>
|
||||
|
||||
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);
|
||||
|
||||
/* acquire spin lock */
|
||||
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
|
||||
|
||||
InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
|
||||
|
||||
KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ASSERT(LeadingStreamPointer->OffsetOut.Remaining >= Urb->UrbIsochronousTransfer.IsoPacket[Index].Length);
|
||||
|
||||
/* copy buffer */
|
||||
RtlCopyMemory((PUCHAR)LeadingStreamPointer->OffsetOut.Data, &TransferBuffer[Offset], Urb->UrbIsochronousTransfer.IsoPacket[Index].Length);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user