Exemplo n.º 1
0
VOID
SoundInDeferred(
    IN    PKDPC pDpc,
    IN OUT PDEVICE_OBJECT pDeviceObject,
    IN    PIRP pIrp,
    IN    PVOID Context
)
/*++

Routine Description:

    Dpc routine for wave input device

    Collect the data from the DMA buffer and pass it to the application's
    buffer(s).

Arguments:


Return Value:

    None.

--*/
{
    PLOCAL_DEVICE_INFO pLDI;
    PGLOBAL_DEVICE_INFO pGDI;

    pLDI = (PLOCAL_DEVICE_INFO)pDeviceObject->DeviceExtension;
    pGDI = pLDI->pGlobalInfo;

    //
    // Acquire the spin lock before we mess with the list
    //

    GlobalEnter(pGDI);

    //
    // Fill in any buffers we can
    //

    dprintf4(pGDI->NextHalf == LowerHalf ? "dpc():L" : "dpc():U");


    //
    // Zero bytes taken out of new buffer
    //

    if( pGDI->DMABuffer[pGDI->NextHalf].nBytes == DMA_BUFFER_SIZE / 2)
	pGDI->DMABuffer[pGDI->NextHalf].nBytes = 0;

    //
    // Request input without posting the last buffer
    //

    sndFlush(pGDI, pGDI->NextHalf);
    sndFillInputBuffers(pLDI, pGDI->NextHalf);

    //
    // Restart this buffer's DMA
    //
    sndReStartDMA(pGDI, pGDI->NextHalf);

    //
    // Move on to next half
    //
    pGDI->NextHalf = UpperHalf + LowerHalf - pGDI->NextHalf;

    //
    // Release the spin lock
    //

    GlobalLeave(pGDI);

    return;

    DBG_UNREFERENCED_PARAMETER(pDpc);
    DBG_UNREFERENCED_PARAMETER(Context);
    DBG_UNREFERENCED_PARAMETER(pIrp);
}
Exemplo n.º 2
0
NTSTATUS
sndWaveRecord(
    IN OUT PLOCAL_DEVICE_INFO pLDI,
    IN OUT PIRP pIrp,
    IN     PIO_STACK_LOCATION pIrpStack
)
/*++

Routine Description:

    Add another buffer for recording.

    The wave header is the buffer parameter to the IOCTL.
    This routine just adds the buffer to the queue (of Irps)
    and returns - setting pending status.

Arguments:

    pLDI - our local device information
    pIrp - The IO request packet we're processing
    pIrpStack - the current stack location

Return Value:

    Irp Status.

--*/

{
    NTSTATUS Status;

    Status = STATUS_PENDING;


    //
    // confirm we are doing this on an input device!
    //

    if (pLDI->DeviceType != WAVE_IN) {
        dprintf1("Attempt to record on output device");
        return STATUS_NOT_SUPPORTED;
    }

    //
    // Inform debuggers that 0 length buffers are rather strange
    //

    if (pIrpStack->Parameters.Read.Length == 0) {
        dprintf1("Wave play buffer is zero length");
    }

    //
    // Set return data length to 0 for now
    //

    pIrp->IoStatus.Information = 0;

    //
    // Put the request in the queue.
    //

    //
    // Acquire the spin lock
    //

    GlobalEnter(pLDI->pGlobalInfo);

    //
    // Set Irp status.  Before we try and process it
    //
    pIrp->IoStatus.Status = STATUS_PENDING;
    Status = STATUS_PENDING;
    IoMarkIrpPending(pIrp);

    //
    // Add our buffer to the queue
    //

    InsertTailList(&pLDI->QueueHead, &pIrp->Tail.Overlay.ListEntry);
    dprintf5("irp added");

    //
    // See if we can satisfy some requests straight away
    //

    if (pLDI->State == WAVE_DD_RECORDING) {
        sndFillInputBuffers(pLDI, UpperHalf + LowerHalf -
                            pLDI->pGlobalInfo->NextHalf);
    }

    //
    // Ok to release the spin lock now
    //

    GlobalLeave(pLDI->pGlobalInfo);

    //
    // Mark this request as pending completion.
    // The Dpc deferred procedure call routine does the rest.
    //

    return Status;
}
Exemplo n.º 3
0
NTSTATUS
sndClose(
    IN OUT PLOCAL_DEVICE_INFO pLDI
)
/*++

Routine Description:

    Close the requested device

        Note - we close immediately, there is no waiting for the device.

Arguments:

    pLDI - pointer to our local device info

Return Value:

    STATUS_SUCCESS        if OK otherwise
    STATUS_INTERNAL_ERROR

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;
    PGLOBAL_DEVICE_INFO pGDI;

    pGDI = pLDI->pGlobalInfo;

    //
    // Acquire the spin lock
    //

    GlobalEnter(pGDI)


    //
    // Call the device reset function to complete any
    // pending i/o requests and terminate any current
    // requests in progress
    //

    switch (pLDI->DeviceType) {
    case WAVE_IN:
    case WAVE_OUT:

        //
        // Check this is valid call
        //
        ASSERT(pLDI->DeviceBusy == 2);

        pGDI->Usage = SoundInterruptUsageIdle;
        if (pLDI->DeviceType) {

            //
            // Restore the line in input if necessary
            //

            sndSetInputVolume(pGDI);
        }
        break;

    default:
        dprintf1("Bogus device type for close request");
        Status = STATUS_INTERNAL_ERROR;
        break;
    }

    //
    // return the device to it's idle state
    //

    if (Status == STATUS_SUCCESS) {
        pLDI->DeviceBusy = FALSE;
        dprintf3("Device closed");
    }

#ifdef MIPSSND_TAIL_BUG

    // Since the Device is now closed we can set the Output Volume
    // just in case someone wants to play CDs or listen to Linein

    sndSetOutputVolume( pGDI );

#endif // MIPSSND_TAIL_BUG

    //
    // Release the spin lock
    //

    GlobalLeave(pGDI);

    return Status;
}
Exemplo n.º 4
0
NTSTATUS
sndCleanUp(
    IN OUT PLOCAL_DEVICE_INFO pLDI
)
/*++

Routine Description:

    Clean up the requested device

Arguments:

    pLDI - pointer to our local device info

Return Value:

    STATUS_SUCCESS        if OK otherwise
    STATUS_INTERNAL_ERROR

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;
    PGLOBAL_DEVICE_INFO pGDI;

    pGDI = pLDI->pGlobalInfo;

    //
    // Acquire the spin lock
    //

    GlobalEnter(pGDI)

    if (pLDI->DeviceType == WAVE_IN || pLDI->DeviceType == WAVE_OUT) {

        //
        // Check this is valid call
        //

        ASSERT(pLDI->DeviceBusy == TRUE);

        //
        // Call the device reset function to complete any
        // pending i/o requests and terminate any current
        // requests in progress
        //

        switch (pLDI->DeviceType) {

        case WAVE_IN:

            sndStopWaveInput(pLDI);

            //
            // Reset position to start and free any pending Irps.
            //
            sndFreeQ(pLDI, &pLDI->QueueHead, STATUS_CANCELLED);
            pLDI->SampleNumber = 0;

            break;

        case WAVE_OUT:

            //
            // If anything is in the queue then free it.
            // beware that the final block of a request may still be
            // being dma'd when we get this call.  We now kill this as well
            // because we've changed such that the if the application thinks
            // all the requests are complete then they are complete.
            //

            if (pGDI->DMABusy) {

                #ifdef MIPSSND_TAIL_BUG

                //
                // Turn off the headphone and Lineout to avoid end clicks
                //
                sndMute(pGDI);

                // We could also mute by turning of the headphone
                // But mute using volume "sounds" better.
                // sndHeadphoneControl(pGDI, OFF);
                // sndLineoutControl(pGDI, OFF);

                #endif // MIPSSND_TAIL_BUG

                sndStopDMA(pGDI);
            }

            sndResetOutput(pLDI);

            if (pGDI->pIrpPause) {
                pGDI->pIrpPause->IoStatus.Status = STATUS_SUCCESS;
                IoCompleteRequest(pGDI->pIrpPause, IO_SOUND_INCREMENT);
                pGDI->pIrpPause = NULL;
            }

            break;
        }
        //
        // return the device to it's idle state
        //

        if (Status == STATUS_SUCCESS) {
            pLDI->State = 0;
            pLDI->DeviceBusy = 2;
            dprintf3("Device closing");
        }
    }

    if ( pLDI->DeviceType != WAVE_IN && pLDI->DeviceType != WAVE_OUT ){
        dprintf1("Bogus device type for cleanup request");
        Status = STATUS_INTERNAL_ERROR;
    }


#ifdef MIPSSND_TAIL_BUG

    // Since the Device is now closed we can set the Output Volume
    // just in case someone wants to play CDs or listen to Linein

    sndSetOutputVolume( pGDI );

#endif // MIPSSND_TAIL_BUG

    //
    // Release the spin lock
    //

    GlobalLeave(pGDI);

    return Status;
}
Exemplo n.º 5
0
int FAMGMultiGrid::Construct()
{
    FAMGGrid *g, *cg;
    int level, nnc, nn, ilu, cgilu, leave;
	DOUBLE coarsefrac = 0.0, t, time, cgtime;
	FAMGLeaveInfo myleaveinfo;

    // read parameter
    const int cgnodes = FAMGGetParameter()->Getcgnodes();
#ifdef ModelP
    const int cgminnodespe = FAMGGetParameter()->Getcgminnodespe();
#endif
    const int cglevels = FAMGGetParameter()->Getcglevels();
    const double mincoarse = FAMGGetParameter()->Getmincoarse();
    const int gamma = FAMGGetParameter()->Getgamma();
	if ((strcmp("ilut",FAMGGetParameter()->Getpresmoother()) == 0)
		|| (strcmp("ilut",FAMGGetParameter()->Getpostsmoother()) == 0))  
	{
		ilu = 1; 
	}
	else ilu = 0;
	if (strcmp("ilut",FAMGGetParameter()->Getcgsmoother()) == 0)
	{
		cgilu = 1;
	}
	else cgilu = 0;

	g = grid[0];
#ifdef FAMG_SPARSE_BLOCK
    g->SmoothTV(); 
#else
    g->SmoothTV();
#endif
    FAMGMarkHeap(FAMG_FROM_TOP); // release in Deconstruct
    for(level = 0; level < FAMGMAXGRIDS-1; level++)
    {
		time = CURRENT_TIME;
        // g->SmoothTV();
#ifdef ModelP
		nn  = g->GetNrMasterVectors();	// we are interested only in the master vectors
#else
        nn = g->GetN();
#endif
	
		leave = 0;

		myleaveinfo.coarsefrac = coarsefrac;
		myleaveinfo.cgnodes = nn;
#ifdef ModelP
		myleaveinfo.cgminnodespe = nn;
		GlobalLeave( &myleaveinfo );
#endif

#ifdef XFERTIMING
		XFERTIMING_algtime = 0.0;
		XFERTIMING_algtime_start = CURRENT_TIME;
#endif

		if( myleaveinfo.coarsefrac > mincoarse )
		{
			leave = 1;
			#ifdef ModelP
			if( me==master )	
			#endif
				cout << "FAMG finished; coarsening rate " << 1.0/myleaveinfo.coarsefrac << " < " << 1.0/mincoarse << endl; 
		}

		if( level >= cglevels )
		{
			leave = 1;
			#ifdef ModelP
			if( me==master )	
			#endif
				cout << "FAMG finished; levels " << level << " >= " << cglevels << endl; 
		}

		if( myleaveinfo.cgnodes <= cgnodes )
		{
			leave = 1;
			#ifdef ModelP
			if( me==master )	
			#endif
				cout << "FAMG finished; cg nodes " << myleaveinfo.cgnodes << " <= " << cgnodes << endl; 
		}

#ifdef ModelP
		if( myleaveinfo.cgminnodespe < cgminnodespe )
		{
			leave = 1;
			if( me==master )	
				cout << "FAMG finished; min cg nodes per PE " << myleaveinfo.cgminnodespe << " <= " << cgminnodespe << endl; 
		}
#endif

        if (leave)
			break;

        if (gamma < 1) return 0;	// ModelP: simple return because gamma is known to all processors
#ifdef ModelP
//prv(-level,0);
		g->ConstructOverlap();
//prv(-level,0);
		assert(g->GetNrMasterVectors() == nn );
#endif
        g->Stencil();

#ifdef FAMG_ILU
        if(ilu)
        {
            if (g->ILUTDecomp(0)) 
				RETURN(1);
        }
#endif


#ifdef FAMG_SPARSE_BLOCK
        if (g->ConstructDiagonalInverse()) 
			RETURN(1);       
#endif
        if (g->ConstructTransfer()) 
			RETURN(1);       

#ifdef FAMG_SPARSE_BLOCK
        //        if (g->ConstructDiagonalLump()) 
		// 	RETURN(1);       
#endif

		cgtime = CURRENT_TIME;

        nnc = (g->GetN())-(g->GetNF());
        cg = (FAMGGrid *) FAMGGetMem(sizeof(FAMGGrid),FAMG_FROM_TOP);
        if(cg == NULL)
			RETURN(1);
        if(cg->Init(nnc,*g))
			RETURN(1);
        if(cg->Construct(g))
			RETURN(1);
        grid[n] = cg;
        g = cg;
        n++;
//printf("after Galerkin:\n");
//prm(0,0);prm(0,1); prim(0);
//prm(-1,0);
//prv(-level-1,0);

// for debugging: print some consistent and inconsistent matrices:
//GRID *tmpgrid = cg->GetugGrid();
//int tmplevel = GLEVEL(tmpgrid);
//MATDATA_DESC *tmpA = ((FAMGugMatrix*)cg->GetMatrix())->GetMatDesc();
//MATDATA_DESC *tmpACons = ((FAMGugMatrix*)cg->GetConsMatrix())->GetMatDesc();
//prvGeom(tmplevel,0); primGeom(tmplevel+1); prmGeom(tmplevel,MD_SCALCMP(tmpA));
//if (dmatcopy(MYMG(tmpgrid),tmplevel,tmplevel,ALL_VECTORS,tmpACons,tmpA) != NUM_OK) assert(0);
//if (l_matrix_consistent(tmpgrid,tmpACons,MAT_CONS) != NUM_OK) assert(0);
//prvGeom(tmplevel,0); primGeom(tmplevel+1); prmGeom(tmplevel,MD_SCALCMP(tmpACons));

		t = CURRENT_TIME;
		time = t - time;
		cgtime = t - cgtime;
#ifdef XFERTIMING
		XFERTIMING_algtime += t - XFERTIMING_algtime_start;
#endif

#ifdef ModelP
		cout << me << ": ";
		nnc = cg->GetNrMasterVectors();	// we are interested only in the master vectors
#endif
		coarsefrac = (double)nnc/nn;
		if( nnc <= 0 )
			coarsefrac = 0.000000999;	// dummy
		cout << "amglevel " << -level << " coarsening rate " << 1.0/coarsefrac << " time "<<time<<' '<<cgtime;
#ifdef XFERTIMING
		cout << ' '<<XFERTIMING_algtime;
#endif
		cout << endl;
    }


    if(level == FAMGMAXGRIDS-1)
    {
        ostrstream ostr; ostr << __FILE__ << ", line " << __LINE__ << ": maximum number of levels reached. " << endl;
        FAMGWarning(ostr);
    }
	
    g->Stencil();
#ifdef FAMG_ILU	
    if(cgilu)
    {
        if (g->ILUTDecomp(1)) RETURN(1);
    }
#endif
	
    return 0;
}
Exemplo n.º 6
0
NTSTATUS
sndIoctlGetState(
    IN OUT PLOCAL_DEVICE_INFO pLDI,
    IN    PIRP pIrp,
    IN    PIO_STACK_LOCATION IrpStack
)
/*++

Routine Description:

    Get the current state of the device and return it to the caller.
    This code is COMMON for :
       Wave out
       Wave in

Arguments:

    pLDI - Pointer to our own device data
    pIrp - Pointer to the IO Request Packet
    IrpStack - Pointer to current stack location

Return Value:

     Status to put into request packet by caller.

--*/
{
    PULONG pState;

    if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) {
        dprintf1("Supplied buffer too small for requested data");
        return STATUS_BUFFER_TOO_SMALL;
    }

    //
    // say how much we're sending back
    //

    pIrp->IoStatus.Information = sizeof(ULONG);

    //
    // cast the buffer address to the pointer type we want
    //

    pState = (PULONG)pIrp->AssociatedIrp.SystemBuffer;

    //
    // fill in the info
    //

    GlobalEnter(pLDI->pGlobalInfo);

    //
    // We don't bother to maintain the WAVE_DD_IDLE state internally
    // for Wave output
    //

    if (pLDI->State == WAVE_DD_PLAYING &&
        pLDI->DeviceType == WAVE_OUT &&
        !pLDI->pGlobalInfo->DMABusy) {
        *pState = WAVE_DD_IDLE;
    } else {
        *pState = pLDI->State;
    }

    GlobalLeave(pLDI->pGlobalInfo);

    return STATUS_SUCCESS;
}
Exemplo n.º 7
0
NTSTATUS
sndIoctlSetState(
    IN OUT PLOCAL_DEVICE_INFO pLDI,
    IN     PIRP pIrp,
    IN     PIO_STACK_LOCATION IrpStack
)
/*++

Routine Description:

    Set the current state of the device and return it to the caller.
    This code is COMMON for :
       Wave out
       Wave in

Arguments:

    pLDI - Pointer to our own device data
    pIrp - Pointer to the IO Request Packet
    IrpStack - Pointer to current stack location

Return Value:

     Status to put into request packet by caller.

--*/
{
    PULONG pState;
    NTSTATUS Status = STATUS_SUCCESS;

    if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) {
        dprintf1("Supplied buffer too small for expected data");
        return STATUS_BUFFER_TOO_SMALL;
    }

    //
    // say how much we're sending back
    //

    pIrp->IoStatus.Information = 0;

    //
    // cast the buffer address to the pointer type we want
    //

    pState = (PULONG)pIrp->AssociatedIrp.SystemBuffer;

    //
    // Acquire the spin lock
    //

    GlobalEnter(pLDI->pGlobalInfo);

    //
    // See if we are an input or output device
    //

    switch (pLDI->DeviceType) {
    case WAVE_IN:
        Status = sndSetWaveInputState(pLDI, *pState);
        break;

    case WAVE_OUT:
        Status = sndSetWaveOutputState(pLDI, *pState, pIrp);
        break;

    default:
        dprintf1("Bogus device type");
        Status = STATUS_INTERNAL_ERROR;
        break;
    }

    //
    // Release the spin lock
    //

    GlobalLeave(pLDI->pGlobalInfo);

    return Status;
}