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

View file

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

View file

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

View file

@ -257,9 +257,9 @@ IInterruptSync_fnConnect(
&This->Lock,
Descriptor->u.Interrupt.Vector,
Descriptor->u.Interrupt.Level,
Descriptor->u.Interrupt.Level, //FIXME
Descriptor->Flags,
TRUE,
Descriptor->u.Interrupt.Level,
(Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED),
(Descriptor->Flags != CM_RESOURCE_INTERRUPT_LATCHED),
Descriptor->u.Interrupt.Affinity,
FALSE);
@ -347,7 +347,7 @@ PcNewInterruptSync(
DPRINT("PcNewInterruptSync entered OutInterruptSync %p OuterUnknown %p ResourceList %p ResourceIndex %u Mode %d\n",
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;
if (ResourceIndex > ResourceList->lpVtbl->NumberOfEntriesOfType(ResourceList, CmResourceTypeInterrupt))

View file

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

View file

@ -38,6 +38,7 @@ typedef struct
ULONG PreCompleted;
ULONG PostCompleted;
ULONG Delay;
}IPortPinWaveCyclicImpl;
@ -114,7 +115,8 @@ static
VOID
UpdateCommonBuffer(
IPortPinWaveCyclicImpl * This,
ULONG Position)
ULONG Position,
ULONG MaxTransferCount)
{
ULONG BufferLength;
ULONG BytesToCopy;
@ -123,6 +125,8 @@ UpdateCommonBuffer(
NTSTATUS Status;
BufferLength = Position - This->CommonBufferOffset;
BufferLength = min(BufferLength, MaxTransferCount);
while(BufferLength)
{
Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize);
@ -131,7 +135,6 @@ UpdateCommonBuffer(
BytesToCopy = min(BufferLength, BufferSize);
if (This->Capture)
{
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
@ -158,16 +161,18 @@ static
VOID
UpdateCommonBufferOverlap(
IPortPinWaveCyclicImpl * This,
ULONG Position)
ULONG Position,
ULONG MaxTransferCount)
{
ULONG BufferLength;
ULONG BufferLength, Length, Gap;
ULONG BytesToCopy;
ULONG BufferSize;
PUCHAR Buffer;
NTSTATUS Status;
BufferLength = This->CommonBufferSize - This->CommonBufferOffset;
BufferLength = Gap = This->CommonBufferSize - This->CommonBufferOffset;
BufferLength = Length = min(BufferLength, MaxTransferCount);
while(BufferLength)
{
Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize);
@ -196,8 +201,18 @@ UpdateCommonBufferOverlap(
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
@ -232,6 +247,11 @@ SetStreamWorkerRoutine(
This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue); //FIX function name
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)
{
UpdateCommonBufferOverlap(This, Position);
UpdateCommonBufferOverlap(This, Position, This->FrameSize);
}
else if (Position >= This->CommonBufferOffset)
{
UpdateCommonBuffer(This, Position);
UpdateCommonBuffer(This, Position, This->FrameSize);
}
}
@ -431,6 +451,7 @@ IPortPinWaveCyclic_HandleKsProperty(
{
PKSSTATE State = (PKSSTATE)Irp->UserBuffer;
ASSERT_IRQL(DISPATCH_LEVEL);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTATE))
{
Irp->IoStatus.Information = sizeof(KSSTATE);
@ -674,9 +695,6 @@ CloseStreamRoutine(
IN PVOID Context)
{
PMINIPORTWAVECYCLICSTREAM Stream;
NTSTATUS Status;
ISubdevice *ISubDevice;
PSUBDEVICE_DESCRIPTOR Descriptor;
IPortPinWaveCyclicImpl * This;
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)
{
ExFreePool(This->Format);
@ -751,20 +756,21 @@ IPortPinWaveCyclic_fnClose(
if (This->Stream)
{
/* allocate a close context */
Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
if (!Ctx)
{
DPRINT1("Failed to allocate stream context\n");
goto cleanup;
}
/* allocate work context */
Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
if (!Ctx->WorkItem)
{
DPRINT1("Failed to allocate work item\n");
goto cleanup;
}
/* setup the close context */
Ctx->Irp = Irp;
Ctx->Pin = (PVOID)This;
@ -772,6 +778,9 @@ IPortPinWaveCyclic_fnClose(
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
/* remove member from service group */
This->ServiceGroup->lpVtbl->RemoveMember(This->ServiceGroup, (PSERVICESINK)&This->lpVtblServiceSink);
/* defer work item */
IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx);
/* Return result */
@ -910,7 +919,7 @@ IPortPinWaveCyclic_fnFastWrite(
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;
@ -1057,6 +1066,8 @@ IPortPinWaveCyclic_fnInit(
This->CommonBufferSize = This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel);
This->CommonBuffer = This->DmaChannel->lpVtbl->SystemAddress(This->DmaChannel);
This->Capture = Capture;
/* delay of 10 milisec */
This->Delay = Int32x32To64(10, -10000);
Status = This->Stream->lpVtbl->SetNotificationFreq(This->Stream, 10, &This->FrameSize);

View file

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