Esempio n. 1
0
/*
 * @implemented
 */
VOID
NTAPI
IoFreeController(IN PCONTROLLER_OBJECT ControllerObject)
{
    PKDEVICE_QUEUE_ENTRY QueueEntry;
    PDEVICE_OBJECT DeviceObject;
    IO_ALLOCATION_ACTION Result;

    /* Remove the Queue */
    QueueEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue);
    if (QueueEntry)
    {
        /* Get the Device Object */
        DeviceObject = CONTAINING_RECORD(QueueEntry,
                                         DEVICE_OBJECT,
                                         Queue.Wcb.WaitQueueEntry);

        /* Call the routine */
        Result = DeviceObject->Queue.Wcb.DeviceRoutine(DeviceObject,
                                                       DeviceObject->CurrentIrp,
                                                       NULL,
                                                       DeviceObject->
                                                       Queue.Wcb.DeviceContext);
        /* Free the controller if this was requested */
        if (Result == DeallocateObject) IoFreeController(ControllerObject);
    }
}
Esempio n. 2
0
NTSTATUS
NTAPI
BeepCleanup(IN PDEVICE_OBJECT DeviceObject,
            IN PIRP Irp)
{
    KIRQL OldIrql, CancelIrql;
    PKDEVICE_QUEUE_ENTRY Packet;
    PIRP CurrentIrp;

    /* Raise IRQL and acquire the cancel lock */
    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
    IoAcquireCancelSpinLock(&CancelIrql);

    /* Get the current IRP */
    CurrentIrp = DeviceObject->CurrentIrp;
    DeviceObject->CurrentIrp = NULL;
    while (CurrentIrp)
    {
        /* Clear its cancel routine */
        (VOID)IoSetCancelRoutine(CurrentIrp, NULL);

        /* Cancel the IRP */
        CurrentIrp->IoStatus.Status = STATUS_CANCELLED;
        CurrentIrp->IoStatus.Information = 0;

        /* Release the cancel lock and complete it */
        IoReleaseCancelSpinLock(CancelIrql);
        IoCompleteRequest(CurrentIrp, IO_NO_INCREMENT);

        /* Reacquire the lock and get the next queue packet */
        IoAcquireCancelSpinLock(&CancelIrql);
        Packet = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
        if (Packet)
        {
            /* Get the IRP */
            CurrentIrp = CONTAINING_RECORD(Packet,
                                           IRP,
                                           Tail.Overlay.DeviceQueueEntry);
        }
        else
        {
            /* No more IRPs */
            CurrentIrp = NULL;
        }
    }

    /* Release lock and go back to low IRQL */
    IoReleaseCancelSpinLock(CancelIrql);
    KeLowerIrql(OldIrql);

    /* Complete the IRP */
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    /* Stop and beep and return */
    HalMakeBeep(0);
    return STATUS_SUCCESS;
}
Esempio n. 3
0
VOID
IoFreeAdapterChannel(
    IN PADAPTER_OBJECT AdapterObject
    )

/*++

Routine Description:

    This routine is invoked to deallocate the specified adapter object.
    Any map registers that were allocated are also automatically deallocated.
    No checks are made to ensure that the adapter is really allocated to
    a device object.  However, if it is not, then kernel will bugcheck.

    If another device is waiting in the queue to allocate the adapter object
    it will be pulled from the queue and its execution routine will be
    invoked.

Arguments:

    AdapterObject - Pointer to the adapter object to be deallocated.

Return Value:

    None.

--*/

{
    PKDEVICE_QUEUE_ENTRY Packet;
    PWAIT_CONTEXT_BLOCK Wcb;
    PADAPTER_OBJECT MasterAdapter;
    BOOLEAN Busy = FALSE;
    IO_ALLOCATION_ACTION Action;
    KIRQL Irql;
    LONG MapRegisterNumber;

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

    MasterAdapter = AdapterObject->MasterAdapter;

    //
    // Pull requests of the adapter's device wait queue as long as the
    // adapter is free and there are sufficient map registers available.
    //

    while( TRUE ) {

       //
       // Begin by checking to see whether there are any map registers that
       // need to be deallocated.  If so, then deallocate them now.
       //

       if (AdapterObject->NumberOfMapRegisters != 0) {
           IoFreeMapRegisters( AdapterObject,
                               AdapterObject->MapRegisterBase,
                               AdapterObject->NumberOfMapRegisters
                               );
       }

       //
       // Simply remove the next entry from the adapter's device wait queue.
       // If one was successfully removed, allocate any map registers that it
       // requires and invoke its execution routine.
       //

       Packet = KeRemoveDeviceQueue( &AdapterObject->ChannelWaitQueue );
       if (Packet == NULL) {

           //
           // There are no more requests break out of the loop.
           //

           break;
       }

       Wcb = CONTAINING_RECORD( Packet,
            WAIT_CONTEXT_BLOCK,
            WaitQueueEntry );

       AdapterObject->CurrentWcb = Wcb;
       AdapterObject->NumberOfMapRegisters = Wcb->NumberOfMapRegisters;

        //
        // Check to see whether this driver wishes to allocate any map
        // registers.  If so, then queue the device object to the master
        // adapter queue to wait for them to become available.  If the driver
        // wants map registers, ensure that this adapter has enough total
        // map registers to satisfy the request.
        //

        if (Wcb->NumberOfMapRegisters != 0 &&
            AdapterObject->MasterAdapter != NULL) {

            //
            // Lock the map register bit map and the adapter queue in the
            // master adapter object. The channel structure offset is used as
            // a hint for the register search.
            //

            Irql = KfAcquireSpinLock( &MasterAdapter->SpinLock );

            MapRegisterNumber = -1;

            if (IsListEmpty( &MasterAdapter->AdapterQueue)) {
               MapRegisterNumber = RtlFindClearBitsAndSet( MasterAdapter->MapRegisters,
                                                        Wcb->NumberOfMapRegisters,
                                                        0
                                                        );
            }
            if (MapRegisterNumber == -1) {

               //
               // There were not enough free map registers.  Queue this request
               // on the master adapter where is will wait until some registers
               // are deallocated.
               //

               InsertTailList( &MasterAdapter->AdapterQueue,
                               &AdapterObject->AdapterQueue
                               );
               Busy = 1;

            } else {

                AdapterObject->MapRegisterBase = ((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);

                }
            }

            KfReleaseSpinLock( &MasterAdapter->SpinLock, Irql );

        } else {

            AdapterObject->MapRegisterBase = NULL;
            AdapterObject->NumberOfMapRegisters = 0;

        }

        //
        // If there were either enough map registers available or no map
        // registers needed to be allocated, invoke the driver's execution
        // routine now.
        //

        if (!Busy) {
            AdapterObject->CurrentWcb = Wcb;
            Action = Wcb->DeviceRoutine( Wcb->DeviceObject,
                Wcb->CurrentIrp,
                AdapterObject->MapRegisterBase,
                Wcb->DeviceContext );

            //
            // If the execution routine would like to have the adapter
            // deallocated, then release the adapter object.
            //

            if (Action == KeepObject) {

               //
               // This request wants to keep the channel a while so break
               // out of the loop.
               //

               break;

            }

            //
            // If the driver wants to keep the map registers then set the
            // number allocated to 0.  This keeps the deallocation routine
            // from deallocating them.
            //

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

        } else {

           //
           // This request did not get the requested number of map registers so
           // out of the loop.
           //

           break;
        }
    }
}