- Interrupt is only shareable if the type is latched

- Only transfer as maximum the FrameSize which was obtained by IMiniportWaveCyclicStream::SetNotficationFreq
- Remove the pin service group member before queing the workitem to close the stream

svn path=/trunk/; revision=41970
This commit is contained in:
Johannes Anderwald 2009-07-15 14:11:00 +00:00
parent 1996b84fae
commit 179d9487dd
7 changed files with 55 additions and 50 deletions

View file

@ -138,11 +138,6 @@ IPortFilterWaveCyclic_fnNewIrpTarget(
return Status; return Status;
} }
/* release existing pin */
if (This->Pins[ConnectDetails->PinId])
{
This->Pins[ConnectDetails->PinId]->lpVtbl->Release(This->Pins[ConnectDetails->PinId]);
}
/* store pin */ /* store pin */
This->Pins[ConnectDetails->PinId] = Pin; This->Pins[ConnectDetails->PinId] = Pin;
@ -409,6 +404,7 @@ IPortFilterWaveCyclic_fnFreePin(
{ {
if (This->Pins[Index] == Pin) if (This->Pins[Index] == Pin)
{ {
This->Descriptor->Factory.Instances[Index].CurrentPinInstanceCount--;
This->Pins[Index]->lpVtbl->Release(This->Pins[Index]); This->Pins[Index]->lpVtbl->Release(This->Pins[Index]);
This->Pins[Index] = NULL; This->Pins[Index] = NULL;
return STATUS_SUCCESS; return STATUS_SUCCESS;

View file

@ -138,11 +138,6 @@ IPortFilterWavePci_fnNewIrpTarget(
return Status; return Status;
} }
/* release existing pin */
if (This->Pins[ConnectDetails->PinId])
{
This->Pins[ConnectDetails->PinId]->lpVtbl->Release(This->Pins[ConnectDetails->PinId]);
}
/* store pin */ /* store pin */
This->Pins[ConnectDetails->PinId] = Pin; This->Pins[ConnectDetails->PinId] = Pin;

View file

@ -213,7 +213,7 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
STDMETHOD_(ULONG, NumMappings)(THIS); STDMETHOD_(ULONG, NumMappings)(THIS);
STDMETHOD_(ULONG, MinMappings)(THIS); STDMETHOD_(ULONG, NumData)(THIS);
STDMETHOD_(BOOL, MinimumDataAvailable)(THIS); STDMETHOD_(BOOL, MinimumDataAvailable)(THIS);

View file

@ -255,12 +255,12 @@ IInterruptSync_fnConnect(
IInterruptServiceRoutine, IInterruptServiceRoutine,
(PVOID)This, (PVOID)This,
&This->Lock, &This->Lock,
Descriptor->u.Interrupt.Vector, Descriptor->u.Interrupt.Vector,
Descriptor->u.Interrupt.Level, Descriptor->u.Interrupt.Level,
Descriptor->u.Interrupt.Level, //FIXME Descriptor->u.Interrupt.Level,
Descriptor->Flags, (Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED),
TRUE, (Descriptor->Flags != CM_RESOURCE_INTERRUPT_LATCHED),
Descriptor->u.Interrupt.Affinity, Descriptor->u.Interrupt.Affinity,
FALSE); FALSE);
DPRINT("IInterruptSync_fnConnect result %x\n", Status); DPRINT("IInterruptSync_fnConnect result %x\n", Status);
@ -347,7 +347,7 @@ PcNewInterruptSync(
DPRINT("PcNewInterruptSync entered OutInterruptSync %p OuterUnknown %p ResourceList %p ResourceIndex %u Mode %d\n", DPRINT("PcNewInterruptSync entered OutInterruptSync %p OuterUnknown %p ResourceList %p ResourceIndex %u Mode %d\n",
OutInterruptSync, OuterUnknown, ResourceList, ResourceIndex, Mode); OutInterruptSync, OuterUnknown, ResourceList, ResourceIndex, Mode);
if (!OutInterruptSync || !ResourceList || Mode > InterruptSyncModeRepeat || Mode < InterruptSyncModeNormal || Mode > InterruptSyncModeRepeat) if (!OutInterruptSync || !ResourceList || Mode < InterruptSyncModeNormal || Mode > InterruptSyncModeRepeat)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
if (ResourceIndex > ResourceList->lpVtbl->NumberOfEntriesOfType(ResourceList, CmResourceTypeInterrupt)) if (ResourceIndex > ResourceList->lpVtbl->NumberOfEntriesOfType(ResourceList, CmResourceTypeInterrupt))

View file

@ -296,10 +296,11 @@ IIrpQueue_fnNumMappings(
ULONG ULONG
NTAPI NTAPI
IIrpQueue_fnMinMappings( IIrpQueue_fnNumData(
IN IIrpQueue *iface) IN IIrpQueue *iface)
{ {
return 25; IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
return This->NumDataAvailable;
} }
@ -320,8 +321,9 @@ IIrpQueue_fnMinimumDataAvailable(
Result = TRUE; Result = TRUE;
} }
else else
{
Result = FALSE; Result = FALSE;
}
return Result; return Result;
} }
@ -345,6 +347,7 @@ IIrpQueue_fnUpdateFormat(
IIrpQueueImpl * This = (IIrpQueueImpl*)iface; IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
This->DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat; This->DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat;
This->StartStream = FALSE; This->StartStream = FALSE;
This->NumDataAvailable = 0;
} }
@ -483,7 +486,7 @@ static IIrpQueueVtbl vt_IIrpQueue =
IIrpQueue_fnGetMapping, IIrpQueue_fnGetMapping,
IIrpQueue_fnUpdateMapping, IIrpQueue_fnUpdateMapping,
IIrpQueue_fnNumMappings, IIrpQueue_fnNumMappings,
IIrpQueue_fnMinMappings, IIrpQueue_fnNumData,
IIrpQueue_fnMinimumDataAvailable, IIrpQueue_fnMinimumDataAvailable,
IIrpQueue_fnCancelBuffers, IIrpQueue_fnCancelBuffers,
IIrpQueue_fnUpdateFormat, IIrpQueue_fnUpdateFormat,

View file

@ -38,6 +38,7 @@ typedef struct
ULONG PreCompleted; ULONG PreCompleted;
ULONG PostCompleted; ULONG PostCompleted;
ULONG Delay;
}IPortPinWaveCyclicImpl; }IPortPinWaveCyclicImpl;
@ -114,7 +115,8 @@ static
VOID VOID
UpdateCommonBuffer( UpdateCommonBuffer(
IPortPinWaveCyclicImpl * This, IPortPinWaveCyclicImpl * This,
ULONG Position) ULONG Position,
ULONG MaxTransferCount)
{ {
ULONG BufferLength; ULONG BufferLength;
ULONG BytesToCopy; ULONG BytesToCopy;
@ -123,6 +125,8 @@ UpdateCommonBuffer(
NTSTATUS Status; NTSTATUS Status;
BufferLength = Position - This->CommonBufferOffset; BufferLength = Position - This->CommonBufferOffset;
BufferLength = min(BufferLength, MaxTransferCount);
while(BufferLength) while(BufferLength)
{ {
Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize); Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize);
@ -131,7 +135,6 @@ UpdateCommonBuffer(
BytesToCopy = min(BufferLength, BufferSize); BytesToCopy = min(BufferLength, BufferSize);
if (This->Capture) if (This->Capture)
{ {
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel, This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
@ -158,16 +161,18 @@ static
VOID VOID
UpdateCommonBufferOverlap( UpdateCommonBufferOverlap(
IPortPinWaveCyclicImpl * This, IPortPinWaveCyclicImpl * This,
ULONG Position) ULONG Position,
ULONG MaxTransferCount)
{ {
ULONG BufferLength; ULONG BufferLength, Length, Gap;
ULONG BytesToCopy; ULONG BytesToCopy;
ULONG BufferSize; ULONG BufferSize;
PUCHAR Buffer; PUCHAR Buffer;
NTSTATUS Status; NTSTATUS Status;
BufferLength = This->CommonBufferSize - This->CommonBufferOffset; BufferLength = Gap = This->CommonBufferSize - This->CommonBufferOffset;
BufferLength = Length = min(BufferLength, MaxTransferCount);
while(BufferLength) while(BufferLength)
{ {
Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize); Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize);
@ -196,8 +201,18 @@ UpdateCommonBufferOverlap(
BufferLength = This->CommonBufferSize - This->CommonBufferOffset; BufferLength = This->CommonBufferSize - This->CommonBufferOffset;
} }
This->CommonBufferOffset = 0;
UpdateCommonBuffer(This, Position); if (Gap == Length)
{
This->CommonBufferOffset = 0;
MaxTransferCount -= Length;
if (MaxTransferCount)
{
UpdateCommonBuffer(This, Position, MaxTransferCount);
}
}
} }
VOID VOID
@ -232,6 +247,11 @@ SetStreamWorkerRoutine(
This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX function name This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX function name
DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->PreCompleted, This->PostCompleted); DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->PreCompleted, This->PostCompleted);
} }
if (This->State == KSSTATE_RUN)
{
DPRINT1("State RUN %x MinAvailable %u\n", State, This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue));
}
} }
} }
@ -307,11 +327,11 @@ IServiceSink_fnRequestService(
if (Position < This->CommonBufferOffset) if (Position < This->CommonBufferOffset)
{ {
UpdateCommonBufferOverlap(This, Position); UpdateCommonBufferOverlap(This, Position, This->FrameSize);
} }
else if (Position >= This->CommonBufferOffset) else if (Position >= This->CommonBufferOffset)
{ {
UpdateCommonBuffer(This, Position); UpdateCommonBuffer(This, Position, This->FrameSize);
} }
} }
@ -431,6 +451,7 @@ IPortPinWaveCyclic_HandleKsProperty(
{ {
PKSSTATE State = (PKSSTATE)Irp->UserBuffer; PKSSTATE State = (PKSSTATE)Irp->UserBuffer;
ASSERT_IRQL(DISPATCH_LEVEL);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTATE)) if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTATE))
{ {
Irp->IoStatus.Information = sizeof(KSSTATE); Irp->IoStatus.Information = sizeof(KSSTATE);
@ -674,9 +695,6 @@ CloseStreamRoutine(
IN PVOID Context) IN PVOID Context)
{ {
PMINIPORTWAVECYCLICSTREAM Stream; PMINIPORTWAVECYCLICSTREAM Stream;
NTSTATUS Status;
ISubdevice *ISubDevice;
PSUBDEVICE_DESCRIPTOR Descriptor;
IPortPinWaveCyclicImpl * This; IPortPinWaveCyclicImpl * This;
PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context; PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
@ -691,19 +709,6 @@ CloseStreamRoutine(
} }
} }
This->ServiceGroup->lpVtbl->RemoveMember(This->ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink);
Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice);
if (NT_SUCCESS(Status))
{
Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
if (NT_SUCCESS(Status))
{
ISubDevice->lpVtbl->Release(ISubDevice);
Descriptor->Factory.Instances[This->ConnectDetails->PinId].CurrentPinInstanceCount--;
}
}
if (This->Format) if (This->Format)
{ {
ExFreePool(This->Format); ExFreePool(This->Format);
@ -751,20 +756,21 @@ IPortPinWaveCyclic_fnClose(
if (This->Stream) if (This->Stream)
{ {
/* allocate a close context */
Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS); Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
if (!Ctx) if (!Ctx)
{ {
DPRINT1("Failed to allocate stream context\n"); DPRINT1("Failed to allocate stream context\n");
goto cleanup; goto cleanup;
} }
/* allocate work context */
Ctx->WorkItem = IoAllocateWorkItem(DeviceObject); Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
if (!Ctx->WorkItem) if (!Ctx->WorkItem)
{ {
DPRINT1("Failed to allocate work item\n"); DPRINT1("Failed to allocate work item\n");
goto cleanup; goto cleanup;
} }
/* setup the close context */
Ctx->Irp = Irp; Ctx->Irp = Irp;
Ctx->Pin = (PVOID)This; Ctx->Pin = (PVOID)This;
@ -772,6 +778,9 @@ IPortPinWaveCyclic_fnClose(
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING; Irp->IoStatus.Status = STATUS_PENDING;
/* remove member from service group */
This->ServiceGroup->lpVtbl->RemoveMember(This->ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink);
/* defer work item */ /* defer work item */
IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx); IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx);
/* Return result */ /* Return result */
@ -910,7 +919,7 @@ IPortPinWaveCyclic_fnFastWrite(
InterlockedIncrement((PLONG)&This->TotalPackets); InterlockedIncrement((PLONG)&This->TotalPackets);
DPRINT1("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted); DPRINT("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u State %x MinData %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted, This->State, This->IrpQueue->lpVtbl->NumData(This->IrpQueue));
Packet = (PCONTEXT_WRITE)Buffer; Packet = (PCONTEXT_WRITE)Buffer;
@ -1057,6 +1066,8 @@ IPortPinWaveCyclic_fnInit(
This->CommonBufferSize = This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel); This->CommonBufferSize = This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel);
This->CommonBuffer = This->DmaChannel->lpVtbl->SystemAddress(This->DmaChannel); This->CommonBuffer = This->DmaChannel->lpVtbl->SystemAddress(This->DmaChannel);
This->Capture = Capture; This->Capture = Capture;
/* delay of 10 milisec */
This->Delay = Int32x32To64(10, -10000);
Status = This->Stream->lpVtbl->SetNotificationFreq(This->Stream, 10, &This->FrameSize); Status = This->Stream->lpVtbl->SetNotificationFreq(This->Stream, 10, &This->FrameSize);

View file

@ -238,7 +238,7 @@ ServiceGroupThread(IN PVOID StartContext)
break; break;
case STATUS_WAIT_1: case STATUS_WAIT_1:
PsTerminateSystemThread(STATUS_SUCCESS); PsTerminateSystemThread(STATUS_SUCCESS);
break; return;
} }
}while(TRUE); }while(TRUE);
} }