Compartir a través de


Iniciar un dispositivo en un controlador de funciones

Un controlador de función establece una rutina de IoCompletion , pasa una solicitud de IRP_MN_START_DEVICE a la pila del dispositivo y pospone sus operaciones de inicio hasta que todos los controladores inferiores hayan terminado con el IRP. Consulte Posponing PnP IRP Processing Until Lower Drivers Finish (Posponing PnP IRP Processing Until Lower Drivers Finish ) para obtener información detallada sobre el uso de un evento de kernel y una rutina de IoCompletion para posponer el procesamiento de IRP.

Cuando su rutina DispatchPnP recupera el control después de que todos los controladores inferiores hayan terminado con irP, el controlador de función realiza sus tareas para iniciar el dispositivo. Un controlador de función inicia el dispositivo con un procedimiento similar al siguiente:

  1. Si un controlador inferior produjo un error en irP (IoCallDriver devolvió un error), no continúe procesando el IRP. Realice cualquier limpieza necesaria y vuelva de la rutina DispatchPnP (vaya al último paso de esta lista).

  2. Si los controladores inferiores procesaron el IRP correctamente, inicie el dispositivo.

    Los pasos exactos para iniciar un dispositivo varían de dispositivo a dispositivo. Estos pasos pueden incluir el espacio de E/S de asignación, la inicialización de registros de hardware, el establecimiento del dispositivo en el estado de alimentación D0 y la conexión de la interrupción con IoConnectInterrupt. Si el controlador reinicia un dispositivo después de una solicitud de IRP_MN_STOP_DEVICE , es posible que el controlador tenga el estado del dispositivo que se va a restaurar.

    El dispositivo debe estar encendido antes de que los controladores puedan acceder a él. Consulte Encendido de un dispositivo para obtener más información.

    Si el dispositivo debe estar habilitado para reactivación, su propietario de la directiva de energía (normalmente el controlador de funciones) debe enviar un IRP de espera o reactivación después de encender el dispositivo y antes de completar la solicitud de IRP_MN_START_DEVICE . Para obtener más información, consulte Envío de un IRP de espera o reactivación.

  3. Inicie irP en la cola de retención de IRP.

    Borre la marca de HOLD_NEW_REQUESTS definida por el controlador e inicie los IRP en la cola de retención de IRP. Los controladores deben hacerlo al iniciar un dispositivo por primera vez y al reiniciar un dispositivo después de una detención o detención de IRP de consulta. Consulte Mantener los IRP entrantes cuando un dispositivo está en pausa para obtener más información.

  4. [Opcional] Habilite las interfaces para el dispositivo mediante una llamada a IoSetDeviceInterfaceState.

    Habilite las interfaces, si las hay, que el controlador registró previamente en su rutina AddDevice (o en un INF o por otro componente, como un coinserdor).

    En Windows 2000 y versiones posteriores de Windows, el administrador de PnP no envía notificaciones de llegadas de la interfaz de dispositivo hasta que finalice el IRP de IRP_MN_START_DEVICE , lo que indica que todos los controladores del dispositivo han completado sus operaciones de inicio. El administrador de PnP también produce un error en las solicitudes de creación que llegan antes de que todos los controladores del dispositivo completen el IRP de inicio.

  5. Complete el IRP.

    La rutina ioCompletion del controlador de función devolvió STATUS_MORE_PROCESSING_REQUIRED, tal y como se describe en Posponing PnP IRP Processing Until Lower Drivers Finish,so the function driver's DispatchPnP routine must call IoCompleteRequest to resume el procesamiento de finalización de E/S.

    Si las operaciones de inicio del controlador de función se realizaron correctamente, el controlador establece Irp-IoStatus.Status> en STATUS_SUCCESS, llama a IoCompleteRequest con un aumento de prioridad de IO_NO_INCREMENT y devuelve STATUS_SUCCESS de su rutina DispatchPnP.

    Si el controlador de función encuentra un error durante sus operaciones de inicio, el controlador establece un estado de error en el IRP, llama a IoCompleteRequest con IO_NO_INCREMENT y devuelve el error de su rutina DispatchPnP .

    Si un controlador inferior no pudo irP (IoCallDriver devolvió un error), el controlador de función llama a IoCompleteRequest con IO_NO_INCREMENT y devuelve el error de IoCallDriver de su rutina DispatchPnP . El controlador de función no establece Irp-IoStatus.Status> en este caso porque el controlador inferior ya ha establecido el estado que produjo un error en el IRP.

Cuando un controlador de función recibe una solicitud de IRP_MN_START_DEVICE, debe examinar las estructuras en IrpSp-Parameters.StartDevice.AssignResources> e IrpSp-Parameters.StartDevice.AssignResourcesTranslated>, que describen los recursos sin procesar y traducidos, respectivamente, que el administrador de PnP ha asignado al dispositivo. Los controladores deben guardar una copia de cada lista de recursos en la extensión de dispositivo como ayuda de depuración.

Las listas de recursos se emparejan CM_RESOURCE_LIST estructuras, en las que cada elemento de la lista sin procesar corresponde al mismo elemento de la lista traducida. Por ejemplo, si AllocatedResources.List[0] describe un intervalo de puertos de E/S sin procesar, a continuación, AllocatedResourcesTranslated.List[0] describe el mismo intervalo después de la traducción. Cada recurso traducido incluye una dirección física y el tipo del recurso.

Si a un controlador se le asigna un recurso de memoria traducido (CmResourceTypeMemory), debe llamar a MmMapIoSpace para asignar la dirección física a una dirección virtual a través de la cual puede acceder a los registros del dispositivo. Para que un controlador funcione de forma independiente de la plataforma, debe comprobar cada recurso devuelto, traducido y asignarlo, si es necesario.

Un controlador de función debe hacer lo siguiente en respuesta a un IRP_MN_START_DEVICE para garantizar el acceso a todos los recursos del dispositivo:

  1. Copie IrpSp-Parameters.StartDevice.AllocatedResources> en la extensión del dispositivo.

  2. Copie IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated> en la extensión del dispositivo.

  3. En un bucle, inspeccione cada elemento descriptor en AllocatedResourcesTranslated. Si el tipo de recurso descriptor es CmResourceTypeMemory, llame a MmMapIoSpace y pase la dirección física y la longitud del recurso traducido.

Cuando el controlador recibe una solicitud de IRP_MN_STOP_DEVICE, IRP_MN_REMOVE_DEVICE o IRP_MN_SURPRISE_REMOVAL , debe liberar las asignaciones llamando a MmUnmapIoSpace en un bucle similar. El controlador también debe llamar a MmUnmapIoSpace si debe producir un error en la solicitud de IRP_MN_START_DEVICE .

Consulte Asignación de direcciones Bus-Relative a direcciones virtuales para obtener más información.