#include "usbaudio.h"
+#define PACKET_COUNT 10
+
+
NTSTATUS
GetMaxPacketSizeForInterface(
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
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);
+ UrbSize = GET_ISO_URB_SIZE(PACKET_COUNT);
/* allocate urb */
Urb = AllocFunction(UrbSize);
Urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_START_ISO_TRANSFER_ASAP;
Urb->UrbIsochronousTransfer.TransferBufferLength = BufferLength;
Urb->UrbIsochronousTransfer.TransferBuffer = Buffer;
- Urb->UrbIsochronousTransfer.NumberOfPackets = PacketCount;
+ Urb->UrbIsochronousTransfer.NumberOfPackets = PACKET_COUNT;
- for (Index = 0; Index < PacketCount; Index++)
+ for (Index = 0; Index < PACKET_COUNT; Index++)
{
Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * MaxPacketSize;
}
}
+NTSTATUS
+UsbAudioSetMuteOff(
+ IN PKSPIN Pin)
+{
+ PURB Urb;
+ PVOID SampleRateBuffer;
+ PPIN_CONTEXT PinContext;
+ NTSTATUS Status;
+
+ /* allocate sample rate buffer */
+ SampleRateBuffer = AllocFunction(sizeof(ULONG));
+ if (!SampleRateBuffer)
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* allocate urb */
+ Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
+ if (!Urb)
+ {
+ /* no memory */
+ FreeFunction(SampleRateBuffer);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* FIXME: determine controls and format urb */
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_INTERFACE,
+ sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
+ USBD_TRANSFER_DIRECTION_OUT,
+ 0,
+ 0x01,
+ 0x100,
+ 0x300,
+ SampleRateBuffer,
+ NULL,
+ 1,
+ NULL);
+
+ /* get pin context */
+ PinContext = Pin->Context;
+
+ /* submit urb */
+ Status = SubmitUrbSync(PinContext->LowerDevice, Urb);
+
+ DPRINT1("UsbAudioSetMuteOff Pin %p Status %x\n", Pin, Status);
+ FreeFunction(Urb);
+ FreeFunction(SampleRateBuffer);
+ return Status;
+}
+
+NTSTATUS
+UsbAudioSetVolume(
+ IN PKSPIN Pin)
+{
+ PURB Urb;
+ PUCHAR SampleRateBuffer;
+ PPIN_CONTEXT PinContext;
+ NTSTATUS Status;
+
+ /* allocate sample rate buffer */
+ SampleRateBuffer = AllocFunction(sizeof(ULONG));
+ if (!SampleRateBuffer)
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* allocate urb */
+ Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
+ if (!Urb)
+ {
+ /* no memory */
+ FreeFunction(SampleRateBuffer);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* FIXME: determine controls and format urb */
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_INTERFACE,
+ sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
+ USBD_TRANSFER_DIRECTION_OUT,
+ 0,
+ 0x01,
+ 0x200,
+ 0x300,
+ SampleRateBuffer,
+ NULL,
+ 2,
+ NULL);
+
+ /* get pin context */
+ PinContext = Pin->Context;
+
+ SampleRateBuffer[0] = 0xC2;
+ SampleRateBuffer[1] = 0xFE;
+ /* submit urb */
+ Status = SubmitUrbSync(PinContext->LowerDevice, Urb);
+
+ DPRINT1("UsbAudioSetVolume Pin %p Status %x\n", Pin, Status);
+ FreeFunction(Urb);
+ FreeFunction(SampleRateBuffer);
+ return Status;
+}
NTSTATUS
UsbAudioSetFormat(
return STATUS_INSUFFICIENT_RESOURCES;
}
- /* format urb */
+ /* FIXME: determine controls and format urb */
UsbBuildVendorRequest(Urb,
URB_FUNCTION_CLASS_ENDPOINT,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,
- 0x01,
+ 0x01, // SET_CUR
0x100,
0x81, //FIXME bEndpointAddress
SampleRateBuffer,
return Status;
}
+VOID
+NTAPI
+CaptureGateOnWorkItem(
+ _In_ PVOID Context)
+{
+ PKSPIN Pin;
+ PPIN_CONTEXT PinContext;
+ PKSGATE Gate;
+ ULONG Count;
+
+ /* get pin */
+ Pin = Context;
+
+ /* get pin context */
+ PinContext = Pin->Context;
+
+ do
+ {
+ /* acquire processing mutex */
+ KsPinAcquireProcessingMutex(Pin);
+
+ /* get pin control gate */
+ Gate = KsPinGetAndGate(Pin);
+
+ /* turn input on */
+ KsGateTurnInputOn(Gate);
+
+ /* schedule processing */
+ KsPinAttemptProcessing(Pin, TRUE);
+
+ /* release processing mutex */
+ KsPinReleaseProcessingMutex(Pin);
+
+ /* decrement worker count */
+ Count = KsDecrementCountedWorker(PinContext->CaptureWorker);
+ } while (Count);
+}
+
+
+
+VOID
+CaptureInitializeUrbAndIrp(
+ IN PKSPIN Pin,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack;
+ PURB Urb;
+ PUCHAR TransferBuffer;
+ ULONG Index;
+ PPIN_CONTEXT PinContext;
+
+ /* get pin context */
+ PinContext = Pin->Context;
+
+ /* 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;
+ Irp->Tail.Overlay.DriverContext[1] = NULL;
+
+ /* 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);
+
+ RtlZeroMemory(Urb, GET_ISO_URB_SIZE(PACKET_COUNT));
+
+ /* 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 = PACKET_COUNT;
+ Urb->UrbIsochronousTransfer.StartFrame = 0;
+
+ for (Index = 0; Index < PACKET_COUNT; Index++)
+ {
+ Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * PinContext->DeviceExtension->InterfaceInfo->Pipes[0].MaximumPacketSize;
+ }
+}
+
+
+VOID
+NTAPI
+CaptureAvoidPipeStarvationWorker(
+ _In_ PVOID Context)
+{
+ PKSPIN Pin;
+ PPIN_CONTEXT PinContext;
+ KIRQL OldLevel;
+ PLIST_ENTRY CurEntry;
+ PIRP Irp;
+
+ /* get pin */
+ Pin = Context;
+
+ /* get pin context */
+ PinContext = Pin->Context;
+
+ /* acquire spin lock */
+ KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
+
+ if (!IsListEmpty(&PinContext->IrpListHead))
+ {
+ /* sanity check */
+ ASSERT(!IsListEmpty(&PinContext->IrpListHead));
+
+ /* 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);
+
+ /* reinitialize irp and urb */
+ CaptureInitializeUrbAndIrp(Pin, Irp);
+
+ KsDecrementCountedWorker(PinContext->StarvationWorker);
+
+ /* call driver */
+ IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
+ }
+ else
+ {
+ /* release lock */
+ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
+
+ KsDecrementCountedWorker(PinContext->StarvationWorker);
+ }
+}
+
+
+
NTSTATUS
InitCapturePin(
IN PKSPIN Pin)
PPIN_CONTEXT PinContext;
PIO_STACK_LOCATION IoStack;
PKSALLOCATOR_FRAMING_EX Framing;
+ PKSGATE Gate;
+
/* set sample rate */
Status = UsbAudioSetFormat(Pin);
/* lets get maximum packet size */
MaximumPacketSize = GetMaxPacketSizeForInterface(PinContext->DeviceExtension->ConfigurationDescriptor, PinContext->InterfaceDescriptor, Pin->DataFlow);
+ /* initialize work item for capture worker */
+ ExInitializeWorkItem(&PinContext->CaptureWorkItem, CaptureGateOnWorkItem, (PVOID)Pin);
+
+ /* register worker */
+ Status = KsRegisterCountedWorker(CriticalWorkQueue, &PinContext->CaptureWorkItem, &PinContext->CaptureWorker);
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ return Status;
+ }
+
+ /* initialize work item */
+ ExInitializeWorkItem(&PinContext->StarvationWorkItem, CaptureAvoidPipeStarvationWorker, (PVOID)Pin);
+
+ /* register worker */
+ Status = KsRegisterCountedWorker(CriticalWorkQueue, &PinContext->StarvationWorkItem, &PinContext->StarvationWorker);
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ KsUnregisterWorker(PinContext->CaptureWorker);
+ }
+
/* lets edit framing struct */
Framing = (PKSALLOCATOR_FRAMING_EX)Pin->Descriptor->AllocatorFraming;
Framing->FramingItem[0].PhysicalRange.MinFrameSize =
MaximumPacketSize;
/* calculate buffer size 8 irps * 10 iso packets * max packet size */
- BufferSize = 8 * 10 * MaximumPacketSize;
+ BufferSize = 8 * PACKET_COUNT * MaximumPacketSize;
/* allocate pin capture buffer */
+ PinContext->BufferSize = BufferSize;
PinContext->Buffer = AllocFunction(BufferSize);
if (!PinContext->Buffer)
{
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;
}
- DPRINT1("InitCapturePin Irp %p\n", Irp);
+ /* 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;
+
+ IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE);
+
/* insert into irp list */
InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
/* add to object bag*/
- KsAddItemToObjectBag(Pin->Bag, Irp, IoFreeIrp);
+ KsAddItemToObjectBag(Pin->Bag, Irp, ExFreePool);
/* FIXME select correct pipe handle */
Status = UsbAudioAllocCaptureUrbIso(PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle,
MaximumPacketSize,
- &PinContext->Buffer[MaximumPacketSize * 10 * Index],
- MaximumPacketSize * 10,
+ &PinContext->Buffer[MaximumPacketSize * PACKET_COUNT * Index],
+ MaximumPacketSize * PACKET_COUNT,
&Urb);
+ DPRINT1("InitCapturePin Irp %p Urb %p\n", Irp, Urb);
+
if (NT_SUCCESS(Status))
{
/* get next stack location */
return Status;
}
}
+
+ /* get process control gate */
+ Gate = KsPinGetAndGate(Pin);
+
+ /* turn input off */
+ KsGateTurnInputOff(Gate);
+
return Status;
}
}
+
+
NTSTATUS
NTAPI
USBAudioPinCreate(
Pin->Context = PinContext;
/* lets edit allocator framing struct */
- Status = _KsEdit(Pin->Bag, &Pin->Descriptor, sizeof(KSPIN_DESCRIPTOR_EX), sizeof(KSPIN_DESCRIPTOR_EX), USBAUDIO_TAG);
+ Status = _KsEdit(Pin->Bag, (PVOID*)&Pin->Descriptor, sizeof(KSPIN_DESCRIPTOR_EX), sizeof(KSPIN_DESCRIPTOR_EX), USBAUDIO_TAG);
if (NT_SUCCESS(Status))
{
- Status = _KsEdit(Pin->Bag, &Pin->Descriptor->AllocatorFraming, sizeof(KSALLOCATOR_FRAMING_EX), sizeof(KSALLOCATOR_FRAMING_EX), USBAUDIO_TAG);
+ Status = _KsEdit(Pin->Bag, (PVOID*)&Pin->Descriptor->AllocatorFraming, sizeof(KSALLOCATOR_FRAMING_EX), sizeof(KSALLOCATOR_FRAMING_EX), USBAUDIO_TAG);
ASSERT(Status == STATUS_SUCCESS);
}
+ /* FIXME move to build filter topology*/
+ UsbAudioSetMuteOff(Pin);
+ UsbAudioSetVolume(Pin);
/* select streaming interface */
Status = USBAudioSelectAudioStreamingInterface(PinContext, PinContext->DeviceExtension, PinContext->DeviceExtension->ConfigurationDescriptor);
PKSPIN Pin;
PPIN_CONTEXT PinContext;
KIRQL OldLevel;
+ PURB Urb;
/* get pin context */
Pin = Context;
PinContext = Pin->Context;
+ /* get urb */
+ Urb = Irp->Tail.Overlay.DriverContext[0];
+
/* acquire lock */
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
- /* insert entry into done list */
- InsertTailList(&PinContext->DoneIrpListHead, &Irp->Tail.Overlay.ListEntry);
+ if (!NT_SUCCESS(Urb->UrbIsochronousTransfer.Hdr.Status))
+ {
+ //DPRINT("UsbAudioCaptureComplete Irp %p Urb %p Status %x Packet Status %x\n", Irp, Urb, Urb->UrbIsochronousTransfer.Hdr.Status, Urb->UrbIsochronousTransfer.IsoPacket[0].Status);
- /* release lock */
- KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
+ /* insert entry into ready list */
+ InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
+
+ /* release lock */
+ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
+
+ KsIncrementCountedWorker(PinContext->StarvationWorker);
+ }
+ else
+ {
+ /* insert entry into done list */
+ InsertTailList(&PinContext->DoneIrpListHead, &Irp->Tail.Overlay.ListEntry);
+
+ /* release lock */
+ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
- DPRINT1("UsbAudioCaptureComplete Irp %p\n", Irp);
+ KsIncrementCountedWorker(PinContext->CaptureWorker);
+ }
/* done */
return STATUS_MORE_PROCESSING_REQUIRED;
PIRP Irp;
PIO_STACK_LOCATION IoStack;
PURB Urb;
- PUCHAR TransferBuffer;
- ULONG Index, Offset;
+ PUCHAR TransferBuffer, OutBuffer;
+ ULONG Offset, Length;
+ NTSTATUS Status;
+ PKSGATE Gate;
+ //DPRINT1("PinCaptureProcess\n");
LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin, KSSTREAM_POINTER_STATE_LOCKED);
if (LeadingStreamPointer == NULL)
+ {
+ /* get process control gate */
+ Gate = KsPinGetAndGate(Pin);
+
+ /* shutdown processing */
+ KsGateTurnInputOff(Gate);
+
return STATUS_SUCCESS;
+ }
/* get pin context */
PinContext = Pin->Context;
Urb = (PURB)Irp->Tail.Overlay.DriverContext[0];
ASSERT(Urb);
- Offset = 0;
- for (Index = 0; Index < Urb->UrbIsochronousTransfer.NumberOfPackets; Index++)
+ Offset = PtrToUlong(Irp->Tail.Overlay.DriverContext[1]);
+
+ /* get transfer buffer */
+ TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
+
+ /* get target buffer */
+ OutBuffer = (PUCHAR)LeadingStreamPointer->StreamHeader->Data;
+
+ /* calculate length */
+ Length = min(LeadingStreamPointer->OffsetOut.Count - LeadingStreamPointer->StreamHeader->DataUsed, Urb->UrbIsochronousTransfer.TransferBufferLength - Offset);
+
+ /* FIXME copy each packet extra */
+ /* copy audio bytes */
+ RtlCopyMemory((PUCHAR)&OutBuffer[LeadingStreamPointer->StreamHeader->DataUsed], &TransferBuffer[Offset], Length);
+
+ //DPRINT1("Irp %p Urb %p OutBuffer %p TransferBuffer %p Offset %lu Remaining %lu TransferBufferLength %lu Length %lu\n", Irp, Urb, OutBuffer, TransferBuffer, Offset, LeadingStreamPointer->OffsetOut.Remaining, Urb->UrbIsochronousTransfer.TransferBufferLength, Length);
+
+ /* adjust streampointer */
+ LeadingStreamPointer->StreamHeader->DataUsed += Length;
+
+ if (Length == LeadingStreamPointer->OffsetOut.Remaining)
{
- /* add offset */
- Offset += Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset;
+ KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, Length, TRUE);
- /* get transfer buffer */
- TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
+ /* acquire spin lock */
+ KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
- /* 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);
- LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin, KSSTREAM_POINTER_STATE_LOCKED);
- if (LeadingStreamPointer == NULL)
- {
- /* FIXME handle half processed packets */
- //ASSERT(FALSE);
- break;
- }
+ /* adjust offset */
+ Irp->Tail.Overlay.DriverContext[1] = UlongToPtr(Length);
- ASSERT(LeadingStreamPointer->OffsetOut.Remaining >= Urb->UrbIsochronousTransfer.IsoPacket[Index].Length);
+ /* reinsert into processed list */
+ InsertHeadList(&PinContext->DoneIrpListHead, &Irp->Tail.Overlay.ListEntry);
- /* copy buffer */
- RtlCopyMemory((PUCHAR)LeadingStreamPointer->OffsetOut.Data, &TransferBuffer[Offset], Urb->UrbIsochronousTransfer.IsoPacket[Index].Length);
- }
+ /* release lock */
+ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
- if (LeadingStreamPointer->OffsetOut.Remaining == Urb->UrbIsochronousTransfer.IsoPacket[Index].Length)
+ LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin, KSSTREAM_POINTER_STATE_LOCKED);
+ if (LeadingStreamPointer == NULL)
{
- KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, Urb->UrbIsochronousTransfer.IsoPacket[Index].Length, TRUE);
- LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin, KSSTREAM_POINTER_STATE_LOCKED);
- if (LeadingStreamPointer == NULL)
- break;
+ /* no more work to be done*/
+ return STATUS_PENDING;
}
else
{
- KsStreamPointerAdvanceOffsets(LeadingStreamPointer, 0, Urb->UrbIsochronousTransfer.IsoPacket[Index].Length, FALSE);
+ /* resume work on this irp */
+ continue;
}
}
+ else
+ {
+ Status = KsStreamPointerAdvanceOffsets(LeadingStreamPointer, 0, Length, FALSE);
+ ASSERT(Length == Urb->UrbIsochronousTransfer.TransferBufferLength - Offset);
+ }
+
/* 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)
- break;
}
while (!IsListEmpty(&PinContext->IrpListHead))
/* 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);
+ /* reinitialize irp and urb */
+ CaptureInitializeUrbAndIrp(Pin, Irp);
- /* init stack location */
- 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);
-
- DPRINT1("PinCaptureProcess Irp %p\n", Irp);
IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
/* acquire spin lock */
if (LeadingStreamPointer != NULL)
KsStreamPointerUnlock(LeadingStreamPointer, FALSE);
- return STATUS_SUCCESS;
+ /* get process control gate */
+ Gate = KsPinGetAndGate(Pin);
+
+ /* shutdown processing */
+ KsGateTurnInputOff(Gate);
+
+ return STATUS_PENDING;
}
PPIN_CONTEXT PinContext;
PLIST_ENTRY CurEntry;
PIRP Irp;
- PIO_STACK_LOCATION IoStack;
- NTSTATUS Status;
KIRQL OldLevel;
/* get pin context */
/* get irp offset */
Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
-
- /* get next stack location */
- IoStack = IoGetNextIrpStackLocation(Irp);
-
- /* init stack location */
- 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);
- DPRINT1("StartCaptureIsocTransfer Irp %p\n", Irp);
- Status = IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
+ /* reinitialize irp and urb */
+ CaptureInitializeUrbAndIrp(Pin, Irp);
+
+ DPRINT("StartCaptureIsocTransfer Irp %p\n", Irp);
+ IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
/* acquire spin lock */
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);