Método IPortWavePciStream::GetMapping (portcls.h)
O GetMapping
método obtém um mapeamento do driver de porta e associa uma marca ao mapeamento.
Sintaxe
NTSTATUS GetMapping(
[in] PVOID Tag,
[out] PPHYSICAL_ADDRESS PhysicalAddress,
[out] PVOID *VirtualAddress,
[out] PULONG ByteCount,
[out] PULONG Flags
);
Parâmetros
[in] Tag
Especifica um valor de marca a ser associado ao mapeamento. O driver de porta pode usar essa marca em uma chamada IMiniportWavePciStream::RevokeMappings subsequente para identificar o mapeamento na lista de mapeamentos a serem revogados. O driver de miniporto usa a marca para identificar o mapeamento na chamada IPortWavePciStream::ReleaseMapping que libera o mapeamento.
[out] PhysicalAddress
Ponteiro de saída para o endereço físico. Esse parâmetro aponta para uma variável de ponteiro alocada pelo chamador na qual o método grava o endereço físico do mapeamento. Especifique um valor de ponteiro válido e não NULL para esse parâmetro.
[out] VirtualAddress
Ponteiro de saída para o endereço virtual. Esse parâmetro aponta para uma variável de ponteiro alocada pelo chamador na qual o método grava o endereço virtual do mapeamento. Especifique um valor de ponteiro válido e não NULL para esse parâmetro.
[out] ByteCount
Ponteiro de saída para a contagem de bytes. Esse parâmetro aponta para uma variável ULONG alocada pelo chamador na qual o método grava o número de bytes no mapeamento. Especifique um valor de ponteiro válido e não NULL para esse parâmetro.
[out] Flags
Ponteiro de saída para o sinalizador status. Esse parâmetro aponta para uma variável ULONG alocada pelo chamador na qual o método grava um sinalizador status. Especifique um valor de ponteiro válido e não NULL para esse parâmetro. Um valor de sinalizador diferente de zero indica que o mapeamento adquirido nessa chamada é o último mapeamento em um pacote de E/S. Esse sinalizador pode ser usado para sinalizar que o hardware deve interromper o driver de miniporto quando for feito com esse mapeamento. Em resposta à interrupção, o driver de miniporto pode obter novos mapeamentos para entregar ao hardware. O driver de miniporte não é obrigado a usar o sinalizador dessa maneira.
Retornar valor
GetMapping
retornará STATUS_SUCCESS se a chamada tiver sido bem-sucedida. Caso contrário, o método retorna um código de erro apropriado. A tabela a seguir mostra alguns dos possíveis códigos de retorno status.
Código de retorno | Descrição |
---|---|
|
Um mapeamento não está disponível imediatamente, mas o driver de porta chamará IMiniportWavePciStream::MappingAvailable quando um mapeamento estiver disponível. |
Comentários
Os mapeamentos obtidos por meio do GetMapping
método devem ser liberados chamando IPortWavePciStream::ReleaseMapping , a menos que sejam revogados pelo driver de porta. O driver de porta pode revogar mapeamentos chamando o método IMiniportWavePciStream::RevokeMappings do fluxo.
O armazenamento de buffer para um fluxo reproduzido por meio do pino de renderização de um driver de miniport é anexado a um ou mais IRPs. Cada IRP contém uma parte do armazenamento de buffer para o fluxo. O armazenamento de buffer de cada IRP é contíguo na memória virtual, mas as páginas de memória que compõem o buffer não são mapeadas em geral para locais contíguos na memória física. Embora um driver possa usar a E/S programada para acessar o buffer por meio de seu mapeamento na memória virtual, um controlador de DMA requer mapeamentos físicos.
O driver de porta WavePci usa o GetMapping
método para expor o buffer ao driver de miniporto como uma sequência de mapeamentos físicos. Um mapeamento típico é uma página de memória ou menos em tamanho, embora um mapeamento possa exceder o tamanho da página se duas ou mais páginas ocuparem locais adjacentes na memória física.
A chamada inicial para GetMapping
gera o mapeamento no início do buffer. Cada chamada sucessiva para GetMapping
apresenta o próximo mapeamento sequencial no buffer. Depois de chegar ao final do buffer, a próxima GetMapping
chamada gera o mapeamento no início do buffer e a sequência de mapeamento se repete.
O endereço de memória virtual do modo kernel do mapeamento é gerado por meio do parâmetro VirtualAddress . O driver de miniporto usa esse endereço para acessar o mapeamento sob controle de programa direto. A página que contém o mapeamento está bloqueada e nenhuma falha de página pode ocorrer quando o driver acessa o mapeamento. O controlador de DMA master do barramento do dispositivo de áudio usa o endereço que é gerado por meio do parâmetro PhysicalAddress para acessar o mapeamento.
O parâmetro Tag é um valor PVOID que o chamador opta por identificar exclusivamente o mapeamento:
- O driver de porta pode usar essa marca para identificar o mapeamento em uma chamada subsequente para IMiniportWavePciStream::RevokeMappings.
- O driver de miniporto pode usar essa marca para identificar o mapeamento em uma chamada subsequente para IPortWavePciStream::ReleaseMapping.
Um driver de miniporto WavePci típico mantém um registro de cada mapeamento recebido. A marca pode ser um ponteiro para um registro ou um índice em uma matriz de registros, por exemplo, dependendo da implementação. O único requisito para uma marca é que ela seja um valor que pode ser convertido no tipo PVOID.
O parâmetro Flags indica se a chamada para GetMapping
recuperar o mapeamento final na parte do buffer de dados de áudio anexada ao IRP de mapeamento atual. Quando Flags indica que um mapeamento é o último mapeamento em um IRP, um driver de miniporto pode armar uma interrupção de hardware para disparar quando o driver de miniporto terminar de reproduzir esse mapeamento. Quando a interrupção é disparada, esse evento informa ao driver de miniporto que ele precisa adquirir mais mapeamentos para adicionar à sua fila de DMA. O parâmetro Flags normalmente é usado por um driver de miniporto que gerencia um único fluxo de reprodução do driver do sistema KMixer. O KMixer usa vários IRPs de mapeamento (no mínimo três na implementação atual do KMixer) para armazenar em buffer um único fluxo de reprodução. Portanto, se o driver de miniporto gerar uma interrupção de hardware sempre que o controlador de DMA terminar com o mapeamento final em um IRP, as interrupções deverão ocorrer com frequência suficiente para impedir que a fila de DMA passe fome.
O parâmetro Flags normalmente é ignorado por drivers de miniporto que gerenciam um ou mais fluxos acelerados por hardware do DirectSound (consulte Aceleração de hardware directSound no áudio WDM). No caso de um buffer DirectSound, todo o buffer pode ser anexado a um único IRP. Se o buffer for grande e o driver de miniporte agendar uma interrupção de hardware somente quando chegar ao final do buffer, as interrupções ocorrerão tão distantes que a fila de DMA poderá morrer de fome. Além disso, se o driver estiver gerenciando um grande número de fluxos, agendar uma interrupção de hardware sempre que o parâmetro Flags sinalizar uma condição de mapeamento final em um fluxo poderá gerar tantas interrupções que o desempenho pode ser degradado. Nessas circunstâncias, o driver de miniporte não deve depender de interrupções de hardware para adquirir mapeamentos. Em vez disso, ele deve agendar que os DPCs do temporizador ocorram em intervalos regulares para adquirir mapeamentos.
É mais provável que um driver de miniporte chame GetMapping
durante uma chamada para o método SetState, Service ou MappingAvailable do objeto de fluxo do miniport (consulte IMiniportWavePciStream).
Para evitar possíveis deadlocks, o driver do adaptador deve evitar manter um bloqueio de rotação durante sua chamada para GetMapping
. Consulte o driver de áudio de exemplo ac97 no WDK (Microsoft Windows Driver Kit) para obter um exemplo de código que usa um bloqueio de rotação para serializar acessos a estruturas de dados compartilhadas e periféricos em um sistema multiprocessador. O código de exemplo chama KeReleaseSpinLock antes de chamar GetMapping
e chamar KeAcquireSpinLock depois de chamar GetMapping
. Entre as chamadas para liberar e adquirir o bloqueio de rotação, o thread do driver não deve assumir que ele tem acesso exclusivo aos dados ou periféricos protegidos pelo bloqueio de rotação. A ferramenta Verificador de Driver verifica se há bloqueios de rotação ativos durante as chamadas para GetMapping
; se detectar um, ele gerará um bug 0xC4 (detecção de deadlock) marcar.
Embora o tamanho de um mapeamento típico seja uma página de memória ou menos, um único mapeamento poderá exceder o tamanho da página se uma parte de um buffer de áudio ocupar duas ou mais páginas contíguas na memória física. Mapeamentos maiores podem criar problemas para hardware de DMA com falhas de design que limitam o tamanho do bloco. Por exemplo, se um controlador DMA puder lidar com um tamanho máximo de bloco de uma única página e GetMapping
gerar um mapeamento maior que uma página, o driver de miniporte deverá dividir o mapeamento em blocos menores que o hardware de DMA pode manipular. Se o número resultante de blocos exceder o número de registros de mapa disponíveis no hardware de DMA, o driver não poderá enfileirar todos os blocos em uma única operação de DMA de dispersão/coleta. Quando isso ocorre, o driver deve acompanhar a parte não enfileirada do mapeamento e iniciar transferências de DMA dos blocos restantes posteriormente, quando registros de mapa adicionais se tornarem disponíveis.
No Windows 98/Me, Windows 2000, Windows XP e Windows Server 2003, o GetMapping
método nunca gera um mapeamento que abrange mais de 16 páginas. Esse limite pode mudar em versões futuras do Windows.
Para obter mais informações sobre mapeamentos, consulte Latência WavePci.
Requisitos
Requisito | Valor |
---|---|
Plataforma de Destino | Universal |
Cabeçalho | portcls.h (inclua Portcls.h) |
IRQL | <=DISPATCH_LEVEL |
Confira também
IMiniportWavePciStream::GetAllocatorFraming
IMiniportWavePciStream::MappingAvailable
IMiniportWavePciStream::RevokeMappings