Ejemplo n.º 1
0
VOID
sndStopDMA(
    IN    PGLOBAL_DEVICE_INFO pGDI
)
/*++

Routine Description:

    Stop the DMA at once by disabling the hardware
    Free the adapter channel.
    (Opposite of sndStartDMA).

Arguments:

    pGDI - pointer to global device info

Return Value:

    None

--*/
{

    //
    // Pass HALT DMA to the MIPSSND
    //

    if (pGDI->DMABusy) {
        KeSynchronizeExecution(pGDI->pInterrupt, StopDMA, pGDI);

        //
        // Flush our buffers
        //
        sndFlush(pGDI, 0);
        sndFlush(pGDI, 1);

        //
        // Stop the DMA controller
        //

        if (pGDI->Usage == SoundInterruptUsageWaveIn) {
                IoFreeAdapterChannel(pGDI->pAdapterObject[2]);
                IoFreeAdapterChannel(pGDI->pAdapterObject[3]);
        } else {
                IoFreeAdapterChannel(pGDI->pAdapterObject[0]);
                IoFreeAdapterChannel(pGDI->pAdapterObject[1]);
        }
    }

    dprintf4(" dma_stopped");


    //
    // Note our new state
    //

    pGDI->DMABusy = FALSE;
}
Ejemplo n.º 2
0
static VOID NTAPI
RWFreeAdapterChannel(PADAPTER_OBJECT AdapterObject)
/*
 * FUNCTION: Free the adapter DMA channel that we allocated
 * ARGUMENTS:
 *     AdapterObject: the object with the map registers to free
 * NOTES:
 *     - This function is primarily needed because IoFreeAdapterChannel wants to
 *       be called at DISPATCH_LEVEL
 */
{
    KIRQL Irql;

    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

    KeRaiseIrql(DISPATCH_LEVEL, &Irql);
    IoFreeAdapterChannel(AdapterObject);
    KeLowerIrql(Irql);
}
Ejemplo n.º 3
0
VOID
IoFreeMapRegisters(
   PADAPTER_OBJECT AdapterObject,
   PVOID MapRegisterBase,
   ULONG NumberOfMapRegisters
   )
/*++

Routine Description:

   This routine deallocates the map registers for the adapter.  If there are
   any queued adapter waiting for an attempt is made to allocate the next
   entry.

Arguments:

   AdapterObject - The adapter object to where the map register should be
        returned.

   MapRegisterBase - The map register base of the registers to be deallocated.

   NumberOfMapRegisters - The number of registers to be deallocated.

Return Value:

   None

--+*/
{
   PADAPTER_OBJECT MasterAdapter;
   LONG MapRegisterNumber;
   PWAIT_CONTEXT_BLOCK Wcb;
   PLIST_ENTRY Packet;
   IO_ALLOCATION_ACTION Action;
   KIRQL Irql;


    //
    // Begin by getting the address of the master adapter.
    //

    if (AdapterObject->MasterAdapter != NULL && MapRegisterBase != NULL) {

        MasterAdapter = AdapterObject->MasterAdapter;

    } else {

        //
        // There are no map registers to return.
        //

        return;
    }

   //
   // Strip no scatter/gather flag.
   //

   MapRegisterBase = (PVOID) ((ULONG) MapRegisterBase & ~NO_SCATTER_GATHER);

   MapRegisterNumber = (PTRANSLATION_ENTRY) MapRegisterBase -
        (PTRANSLATION_ENTRY) MasterAdapter->MapRegisterBase;

   //
   // Acquire the master adapter spinlock which locks the adapter queue and the
   // bit map for the map registers.
   //

   Irql = KfAcquireSpinLock(&MasterAdapter->SpinLock);

   //
   // Return the registers to the bit map.
   //

   RtlClearBits( MasterAdapter->MapRegisters,
                 MapRegisterNumber,
                 NumberOfMapRegisters
                 );

   //
   // Process any requests waiting for map registers in the adapter queue.
   // Requests are processed until a request cannot be satisfied or until
   // there are no more requests in the queue.
   //

   while(TRUE) {

      if ( IsListEmpty(&MasterAdapter->AdapterQueue) ){
         break;
      }

      Packet = RemoveHeadList( &MasterAdapter->AdapterQueue );
      AdapterObject = CONTAINING_RECORD( Packet,
                                         ADAPTER_OBJECT,
                                         AdapterQueue
                                         );
      Wcb = AdapterObject->CurrentWcb;

      //
      // Attempt to allocate map registers for this request. Use the previous
      // register base as a hint.
      //

      MapRegisterNumber = RtlFindClearBitsAndSet( MasterAdapter->MapRegisters,
                                               AdapterObject->NumberOfMapRegisters,
                                               MasterAdapter->NumberOfMapRegisters
                                               );

      if (MapRegisterNumber == -1) {

         //
         // There were not enough free map registers.  Put this request back on
         // the adapter queue where is came from.
         //

         InsertHeadList( &MasterAdapter->AdapterQueue,
                         &AdapterObject->AdapterQueue
                         );

         break;

      }

     KfReleaseSpinLock( &MasterAdapter->SpinLock, Irql );

     AdapterObject->MapRegisterBase = (PVOID) ((PTRANSLATION_ENTRY)
        MasterAdapter->MapRegisterBase + MapRegisterNumber);

     //
     // Set the no scatter/gather flag if scatter/gather not
     // supported.
     //

     if (!AdapterObject->ScatterGather) {

        AdapterObject->MapRegisterBase = (PVOID)
            ((ULONG) AdapterObject->MapRegisterBase | NO_SCATTER_GATHER);

     }

     //
     // Invoke the driver's execution routine now.
     //

      Action = Wcb->DeviceRoutine( Wcb->DeviceObject,
        Wcb->CurrentIrp,
        AdapterObject->MapRegisterBase,
        Wcb->DeviceContext );

      //
      // If the driver wishes to keep the map registers then set the number
      // allocated to zero and set the action to deallocate object.
      //

      if (Action == DeallocateObjectKeepRegisters) {
          AdapterObject->NumberOfMapRegisters = 0;
          Action = DeallocateObject;
      }

      //
      // If the driver would like to have the adapter deallocated,
      // then deallocate any map registers allocated and then release
      // the adapter object.
      //

      if (Action == DeallocateObject) {

             //
             // The map registers registers are deallocated here rather than in
             // IoFreeAdapterChannel.  This limits the number of times
             // this routine can be called recursively possibly overflowing
             // the stack.  The worst case occurs if there is a pending
             // request for the adapter that uses map registers and whos
             // excution routine decallocates the adapter.  In that case if there
             // are no requests in the master adapter queue, then IoFreeMapRegisters
             // will get called again.
             //

          if (AdapterObject->NumberOfMapRegisters != 0) {

             //
             // Deallocate the map registers and clear the count so that
             // IoFreeAdapterChannel will not deallocate them again.
             //

             Irql = KfAcquireSpinLock( &MasterAdapter->SpinLock );

             RtlClearBits( MasterAdapter->MapRegisters,
                           MapRegisterNumber,
                           AdapterObject->NumberOfMapRegisters
                           );

             AdapterObject->NumberOfMapRegisters = 0;

             KfReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
          }

          IoFreeAdapterChannel( AdapterObject );
      }

      Irql = KfAcquireSpinLock( &MasterAdapter->SpinLock );

   }

   KfReleaseSpinLock( &MasterAdapter->SpinLock, Irql );
}
Ejemplo n.º 4
0
dVoid kdi_LockUnlockDMA
(
/* INPUT PARAMETERS:  */

	KdiContextPtr kdi_context,
	dBoolean lock

/* UPDATE PARAMETERS: */

/* OUTPUT PARAMETERS: */

)

/* COMMENTS: *****************************************************************
 *
 * DEFINITIONS: *************************************************************/
{

/* DATA: ********************************************************************/

   KIRQL old_irql;

/* CODE: ********************************************************************/

	if (kdi_context->adapter_object) {

   	if (lock) {

         if (!kdi_context->adapter_locked) {

            /* Allocate an adapter channel for the I/O. */

            (dVoid) KeResetEvent(
               &kdi_context->allocate_adapter_channel_event );

            KeRaiseIrql( DISPATCH_LEVEL, &old_irql );


            IoAllocateAdapterChannel(
               kdi_context->adapter_object,
               kdi_context->device_object,
               kdi_context->number_of_map_registers,
               kdi_AllocateAdapterChannel,
               kdi_context );

            KeLowerIrql( old_irql );

            /* Wait for the adapter to be allocated.  No */
            /* timeout; we trust the system to do it */
            /* properly - so KeWaitForSingleObject can't */
            /* return an error. */

            (dVoid) KeWaitForSingleObject(
               &kdi_context->allocate_adapter_channel_event,
               Executive,
               KernelMode,
               dFALSE,
               (dSDDWordPtr) dNULL_PTR );

            kdi_context->adapter_locked = dTRUE;
         }

   	} else {

         if (kdi_context->adapter_locked) {

            /* Free the adapter channel that we just used. */

            KeRaiseIrql( DISPATCH_LEVEL, &old_irql );

            IoFreeAdapterChannel( kdi_context->adapter_object );

            KeLowerIrql( old_irql );

            kdi_context->adapter_locked = dFALSE;


         }
   	}
	}


	return;
}