есть железяка, которая умеет делать цепочечные ДМА трансферы т.е. ей дается адрес первой структуры с параметрами трансфера (адреса источника и приемника и размер передачи), в конце которой может быть указатель на следующую структуру и т.д. ... задача: передавать в эту железяку чересстрочную информацию, размер одной строки 702*4 байт, количество строк на передачу - 288, но расположены "через одну"... имхо это уже плохо т.к. не кратно размеру страницы в 4 кб и больше ее половины ... скорость передачи - 50 таких блоков в секунду... вопрос: в ДДК указано, что объем одного трансфера ограничен произведением PAGE_SIZE, которая в хедерах строго 4096 байт и количества маппирующих регистров ДМА контроллера (которое отдается в IoGetDmaAdapter( IN OUT PULONG NumberOfMapRegisters) ), если железяка умеет цепочечные трансферы, то работает ли это ограничение ? пока что удалось выяснить - ограничение похоже где-то в нутрях Вынь: даже если успешно работает создание девайса : Код (Text): RtlZeroMemory(&deviceDescription, sizeof(deviceDescription)); deviceDescription.Version= DEVICE_DESCRIPTION_VERSION; deviceDescription.Master= TRUE; deviceDescription.ScatterGather= FALSE; deviceDescription.BusNumber= pDeviceExt->DDPool[0].ulBus; deviceDescription.InterfaceType= PCIBus; deviceDescription.Dma32BitAddresses= TRUE; deviceDescription.MaximumLength= (1024 * 1024 - 1) * sizeof(ULONG); pDeviceExt->DmaOp.ulMaxMapRegisters = 256; pDeviceExt->DmaOp.pDmaAdapter = (PDMA_ADAPTER)HalGetAdapter(&deviceDescription, &pDeviceExt->DmaOp.ulMaxMapRegisters); с заявленными 256 мапными регистрами (в исходном варианте драйвера было 8) и соотв 4 Мб максимальным трансфером (deviceDescription.MaximumLength), то потом когда перед трансфером получается физ адрес источника : Код (Text): physAddr = pDevExt->DmaOp.pDmaAdapter->DmaOperations->MapTransfer(pDevExt->DmaOp.pDmaAdapter, pDevExt->DmaOp.pirpDmaTransfer->MdlAddress, pDevExt->DmaOp.pMapRegisterBase, pDevExt->DmaOp.CurrentVa, &pDevExt->DmaOp.Length, TRUE); маздайка скидывает &pDevExt->DmaOp.Length до PAGE_SIZE*8 т.е. до 8 мапных регистров ... если я после этого вручную опять скручиваю &pDevExt->DmaOp.Length до например PAGE_SIZE*16, то в трансференных данных половина нормальная, а вторая половина - "мусор" т.е. что-то похоже с мапными регистрами таки связано и когда ДМА контроллер начинает читать дальше PAGE_SIZE*8 ему откуда-то подсовывают какую-то фигню... где-бы почитать как работает ДМА в х86 ? пока что после некоторого медитирования с ДДК показалось, что ДМА контроллер девайса после того, как ему дали параметры трансфера (физический адрес начала трансфера в основной памяти) начинает спрашивать данные у наплатного ДМА х86 контроллера, а у того "страничная" организация по 4 кб и ему на каждую страницу надо держать "маппирующие регистры" которых немного (т.е. 8) и соотв когда у маздайки заказывают параметры трансфера она проверяет какой на самом деле стоит контроллер основной платы и ограничивает размер трансфера 8 страницами... пока что не понятно - почему если заказывается физический адрес, то всеравно используется "страничность" ? при создании ДМА контроллера есть флаг scatter/gather support - это и есть указание, что девайс умеет цепочечные трансферы делать ? а как тогда решается вопрос сколько на каждый трансфер в цепочке "маппирующих регистров" уйдет и когда они будут обновляться если количество трансферов в цепочке не ограничено и размер каждого трансфера вообщем тоже...
Вы разберитесь, нужен ли Вам DMA контроллер. Например, PCI bus masters не используют его, и при обнаружении устройства windows не рапортует о DMA каналах (можно порытся в менеджере устройств, посмотреть ресурсы, используемые различным оборудованием). Настройка DMA происходит через регистры платы. Например, PCI плата А поддерживает scatter/gather передачу на 16 буферов. У этой платы будет скоре всего 16 регистров, куда нужно записать физические адреса кусков буферов. Дальше в управляющий регистр какой нибудь битик "поехали". По окнчанию цикла - прерывание. Из устройств, использующих DMA контроллер, могу вспомнить только FDD и LPT порт. К тому же стандартный DMA контроллер - 16 битный.
а на какой шине плата? scatter/gather support - это возможность железки передавать данные на фрагментированную (как правило кусочки, размером PAGE_SIZE) физ. память.
>Вы разберитесь, нужен ли Вам DMA контроллер. я про тот ДМА, который на доп плате стоит - он работает мостом между PCI и нутряной памятью платы... >Например, PCI плата А поддерживает scatter/gather передачу на 16 буферов. У этой платы будет скоре всего 16 регистров, куда нужно записать физические адреса кусков буферов. Дальше в управляющий регистр какой нибудь битик "поехали". По окнчанию цикла - прерывание. тут побольше возможностей - в регистры контроллера можно прописать только параметры первого трансфера, и адрес следующего дескриптора, который хранится в ОЗУ, а ОЗУ может быть много Мб ... но тут никакие мапные регистры не используются... >а на какой шине плата? честно как и указано : deviceDescription.InterfaceType= PCIBus; deviceDescription.Dma32BitAddresses= TRUE; вообщем погуглив немного нашел объяснение глюков и продолжение пути : в маздайке непрерывный исходный буфер в виртуальных 4 Гб памяти на самом деле состоит из мелких кусов по PAGE_SIZE*8 (не более ?), которые раскиданы по всей физ ОЗУ... и соотв у ДМА контроллера один непрерывный трансфер и ограничен этим значением... но по слухам эту траблу можно пофиксить выделив непрерывный и неперемещаемый кусок физ памяти из драйвера - этим и займусь пока...
говорит о том что Ваше устройство использует BusMaster DMA, а встроенный в системной плате ДМА конроллер вообще курит, тк не может использоваться PCI устройством (...хотя вообще-то может, но только через одно место) Скорее так, непрерывный исходный буфер виртальной памяти может состять из фрагментов(а), размером, кратным PAGE_SIZE. Кстати, возможность железки передавать данные в такую фрагментированную память и зовется Scatter/Gather. Советую почитать вот эту статью: http://www.microsoft.com/whdc/driver/kernel/dma.mspx