NTSTATUS
VIOSerialPortEvtDeviceD0Exit(
    IN  WDFDEVICE Device,
    IN  WDF_POWER_DEVICE_STATE TargetState
    )
{
    PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(Device)->port;
    PPORT_BUFFER buf;
    PSINGLE_LIST_ENTRY iter;

    UNREFERENCED_PARAMETER(TargetState);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s\n", __FUNCTION__);

    WdfIoQueuePurge(Port->ReadQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT);
    WdfIoQueuePurge(Port->WriteQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT);
    WdfIoQueuePurge(Port->IoctlQueue, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT);

    VIOSerialDisableInterruptQueue(GetInQueue(Port));

    WdfSpinLockAcquire(Port->InBufLock);
    VIOSerialDiscardPortDataLocked(Port);
    Port->InBuf = NULL;
    WdfSpinLockRelease(Port->InBufLock);

    WdfSpinLockAcquire(Port->OutVqLock);
    VIOSerialReclaimConsumedBuffers(Port);
    WdfSpinLockRelease(Port->OutVqLock);

    while (buf = (PPORT_BUFFER)VirtIODeviceDetachUnusedBuf(GetInQueue(Port)))
    {
        VIOSerialFreeBuffer(buf);
    }

    iter = PopEntryList(&Port->WriteBuffersList);
    while (iter != NULL)
    {
        PWRITE_BUFFER_ENTRY entry = CONTAINING_RECORD(iter,
            WRITE_BUFFER_ENTRY, ListEntry);

        ExFreePoolWithTag(entry->Buffer, VIOSERIAL_DRIVER_MEMORY_TAG);
        ExFreePoolWithTag(entry, VIOSERIAL_DRIVER_MEMORY_TAG);

        iter = PopEntryList(&Port->WriteBuffersList);
    };

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s\n", __FUNCTION__);

    return STATUS_SUCCESS;
}
Beispiel #2
0
VOID FfbActiveSet(
	BOOLEAN active,
	int id,
	PDEVICE_EXTENSION    pDevContext
	)
{

	size_t szarry, szelement;
	int sz;

	// Check id
	szarry    = sizeof(pDevContext->FfbEnable);
	szelement = sizeof(pDevContext->FfbEnable[0]);
	sz = szarry/szelement;
	if (id<1 || id>sz)
		return;


	// Has there been a change? if not do nothing
	// NO
	if (active == pDevContext->FfbEnable[id-1])
		return;

	// YES
	if (active)
	{ // FFB Activated
		////////////  ReadQ /////////////////////////////////////////
		// Start queue
		WdfIoQueueStart(pDevContext->FfbReadQ[id - 1]);

		////////////  WriteQ /////////////////////////////////////////
		// Start queue
		WdfIoQueueStart(pDevContext->FfbWriteQ[id - 1]);

		// Mark FFB as active
		pDevContext->FfbEnable[id-1] = TRUE;
	}
	else
	{ // FFB Deactivated
		pDevContext->FfbEnable[id-1] = FALSE;

		// Purge queues
		WdfIoQueuePurge(pDevContext->FfbWriteQ[id - 1], NULL, NULL);
		WdfIoQueuePurge(pDevContext->FfbReadQ[id - 1], NULL, NULL);
	};

}
Beispiel #3
0
VOID
SerialPurgeRequests(
    IN WDFQUEUE QueueToClean,
    IN WDFREQUEST *CurrentOpRequest
    )

/*++

Routine Description:

    This function is used to cancel all queued and the current irps
    for reads or for writes. Called at DPC level.

Arguments:

    QueueToClean - A pointer to the queue which we're going to clean out.

    CurrentOpRequest - Pointer to a pointer to the current request.

Return Value:

    None.

--*/

{
    NTSTATUS status;
    PREQUEST_CONTEXT reqContext;

    WdfIoQueuePurge(QueueToClean, WDF_NO_EVENT_CALLBACK, WDF_NO_CONTEXT);

    //
    // The queue is clean.  Now go after the current if
    // it's there.
    //

    if (*CurrentOpRequest) {

        PFN_WDF_REQUEST_CANCEL CancelRoutine;

        reqContext = SerialGetRequestContext(*CurrentOpRequest);
        CancelRoutine = reqContext->CancelRoutine;
        //
        // Clear the common cancel routine but don't clear the reference because the
        // request specific cancel routine called below will clear the reference.
        //
        status = SerialClearCancelRoutine(*CurrentOpRequest, FALSE);
        if (NT_SUCCESS(status)) {
            //
            // Let us just call the CancelRoutine to start the next request.
            //
            if(CancelRoutine) {
                CancelRoutine(*CurrentOpRequest);
            }
        }
    }
}
Beispiel #4
0
NTSTATUS
  CyEvtDeviceReleaseHardware (
    IN WDFDEVICE  Device,
    IN WDFCMRESLIST  ResourcesTranslated
    )
{
	PDEVICE_CONTEXT  pDeviceContext;
	NTSTATUS NTStatus = STATUS_SUCCESS;
	WDF_IO_QUEUE_STATE queueStatus;

	PAGED_CODE();

    CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Start CyEvtDeviceReleaseHardware\n");

    pDeviceContext = CyGetDeviceContext(Device);
	
	if(pDeviceContext->bIsMultiplInterface)
	{
		if(pDeviceContext->MultipleInterfacePair)
			ExFreePoolWithTag(pDeviceContext->MultipleInterfacePair,CYMEM_TAG);
	}
	
	
	/*The default queue does not stop even after device get disconnected and due to this the application device IO which are dependent on the driver
	  get stuck at that point and application hangs. To roslve this issue the queue should be stopped once the device is disconnected.*/
	WdfIoQueueStop(
			pDeviceContext->hQueue,
			EvtIoQueueState, 
			WDF_NO_CONTEXT 
			);	 
	WdfIoQueuePurge(
			pDeviceContext->hQueue,
			EvtIoQueueState, 
			WDF_NO_CONTEXT 
			);

	/*
	queueStatus = WdfIoQueueGetState(pDeviceContext->hQueue, NULL, NULL);
	CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Queue Purge states :%d\n",(WDF_IO_QUEUE_PURGED(queueStatus)) ? TRUE : FALSE);
	CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Queue Ready states :%d\n",(WDF_IO_QUEUE_READY(queueStatus)) ? TRUE : FALSE);
	CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Queue Drain states :%d\n",(WDF_IO_QUEUE_DRAINED(queueStatus)) ? TRUE : FALSE);
	CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Queue Stopped states :%d\n",(WDF_IO_QUEUE_STOPPED(queueStatus)) ? TRUE : FALSE);
    CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Queue IDLE states :%d\n",(WDF_IO_QUEUE_IDLE(queueStatus)) ? TRUE : FALSE);
	*/

	CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "End CyEvtDeviceReleaseHardware\n");

	return NTStatus;
}