Compartilhar via


Manipulando sequências de Client-Implemented

As funções de retorno de chamada de evento EvtSpbControllerLock e EvtSpbControllerUnlock opcionais executam operações complementares. A função EvtSpbControllerLock é um manipulador para solicitações de IOCTL_SPB_LOCK_CONTROLLER . A função EvtSpbControllerUnlock é um manipulador para solicitações IOCTL_SPB_UNLOCK_CONTROLLER . Um cliente (ou seja, o driver de um dispositivo periférico no barramento) envia essas solicitações para iniciar e encerrar sequências de transferência de E/S. A maioria dos drivers de controlador SPB não dá suporte a solicitações de IOCTL_SPB_LOCK_CONTROLLER e IOCTL_SPB_UNLOCK_CONTROLLER e, portanto, não implementa as funções EvtSpbControllerLock e EvtSpbControllerUnlock .

Um cliente pode executar uma sequência de transferência de E/S como uma série de solicitações de transferência simples (ou seja, solicitações de IRP_MJ_READ e IRP_MJ_WRITE ). A primeira transferência na sequência deve ser precedida por uma solicitação de IOCTL_SPB_LOCK_CONTROLLER — essa solicitação informa ao driver do controlador SPB para bloquear o barramento durante a sequência de transferência de E/S. A última transferência deve ser seguida por uma solicitação de IOCTL_SPB_UNLOCK_CONTROLLER , que informa ao motorista para desbloquear o ônibus. Esse tipo de sequência de transferência de E/S é chamado de sequência implementada pelo cliente para distingui-la de uma sequência de solicitação única, que usa uma solicitação IOCTL_SPB_EXECUTE_SEQUENCE em vez de solicitações de IOCTL_SPB_LOCK_CONTROLLER e IOCTL_SPB_UNLOCK_CONTROLLER .

Enquanto o driver de um dispositivo periférico mantém um bloqueio no ônibus, o controlador de barramento permite o acesso a nenhum outro dispositivo periférico no barramento. Os detalhes da operação de bloqueio de barramento dependem do tipo de barramento. Para um controlador I2C, uma alteração na direção de transferência (uma leitura seguida de uma gravação ou vice-versa) requer uma operação de reinicialização I2C. Para um controlador SPI, a seleção de chip para o dispositivo de destino deve permanecer afirmada enquanto o bloqueio do controlador permanece em vigor. Para obter mais informações, consulte Operações de barramento atômico.

O suporte para sequências de transferência implementadas pelo cliente é opcional. O driver do controlador SPB deve alegar dar suporte a eles somente se o controlador puder fazer o seguinte:

  • Bloqueie o barramento durante a sequência implementada pelo cliente.
  • Desbloqueie o ônibus a qualquer momento. Por exemplo, se ocorrer uma solicitação de desbloqueio entre transferências de bytes, o controlador deverá ser capaz de desbloquear o barramento sem esperar a próxima transferência de bytes pelo barramento.

Enquanto o barramento está bloqueado, o cliente pode enviar uma sequência arbitrária de solicitações de transferência simples. Ou seja, a sequência pode ter um comprimento arbitrário e pode ser qualquer combinação de leituras e gravações.

Para indicar suporte para sequências implementadas pelo cliente, um driver de controlador SPB implementa uma função EvtSpbControllerUnlock . Se o driver implementar essa função, a extensão de estrutura do SPB (SpbCx) aceitará IOCTL_SPB_LOCK_CONTROLLER e IOCTL_SPB_UNLOCK_CONTROLLER solicitações de clientes. Caso contrário, o SpbCx falhará nessas solicitações concluindo-as com o código de status STATUS_NOT_SUPPORTED.

Um driver de controlador SPB que implementa uma função EvtSpbControllerUnlock não é necessário para implementar uma função EvtSpbControllerLock . No entanto, um driver de controlador SPB que implementa uma função EvtSpbControllerLock também deve implementar uma função EvtSpbControllerUnlock .

Se o driver implementar uma função EvtSpbControllerUnlock , mas não uma função EvtSpbControllerLock , o SpbCx chamará a função EvtSpbControllerUnlock para lidar com solicitações IOCTL_SPB_UNLOCK_CONTROLLER , mas simplesmente concluirá IOCTL_SPB_LOCK_CONTROLLER solicitações com STATUS_SUCCESS códigos de status.

Seu driver tem duas maneiras de detectar o início de uma sequência implementada pelo cliente. Primeiro, se o driver implementar uma função EvtSpbControllerLock , o SpbCx chamará essa função para lidar com uma IOCTL_SPB_LOCK_CONTROLLER solicitações de um cliente. O driver pode confiar nessa chamada que ocorre antes da primeira solicitação de transferência em uma sequência. Segundo, se o driver não implementar uma função EvtSpbControllerLock , o driver poderá chamar o método SpbRequestGetParameters quando o driver manipular uma solicitação de transferência simples do cliente. Para indicar que a transferência solicitada é a primeira transferência em uma sequência, esse método define o membro Position na estrutura de saída do método como SpbRequestSequencePositionFirst.

O retorno de chamada EvtSpbControllerUnlock é a única maneira que um driver pode determinar quando uma sequência termina. Um driver que não implementa uma função EvtSpbControllerUnlock não pode dar suporte a sequências implementadas pelo cliente.