Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Буфер DMA не выделяет 64 МB (WDM драйвер)  (Прочитано 5757 раз)
0 Пользователей и 1 Гость смотрят эту тему.
sabbatazh
Помогающий

ua
Offline Offline

« : 02-05-2013 08:57 » 

Здравствуйте Уважаемы Знатоки!!!
Попала мне в руки PCIe-плата работающая с высокочастотными сигналами и соответственно с большими объемами данных, ну и конечно к ней шел мануал, где сказано: необходимо выделить два буфера по 64 МB.
Так вот написал драйвер прикрутил ДМА и получилось, как полагается, выделяется 32 МB на буфер, код настройки ДМА и буфера привожу ниже:
Код:
#define MAX_DMA_LENGTH 0x2000000     // 0x2000000 - 32 MB
//#define MAX_DMA_LENGTH 0x4000000     // 0x4000000 - 64 MB
//...
NTSTATUS MDMAIDmaAdapterAllocate(PMDMAI_DEVICE_EXTENSION pdx)
{
    ULONG               NumMapRegisters;
    DEVICE_DESCRIPTION  DeviceDescription;

    KdPrint((DRIVERNAME " - Allocating DMA Adapter object...\n"));

    // Verify object not already created
if (pdx->DMAAdapter)
    {
        KdPrint(("ERROR - DMA Adapter object already exist, unable to allocate\n"));
        return STATUS_OBJECT_NAME_EXISTS;
    }

    // Clear device description
    RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION));

    // Set device DMA properties
    DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;      //перавя версия, нулевая исползуется только при IgnoreCounter = FALSE
    DeviceDescription.Master = TRUE;
    DeviceDescription.ScatterGather = FALSE;
    DeviceDescription.DemandMode = TRUE;
    DeviceDescription.AutoInitialize = FALSE;
    DeviceDescription.Dma32BitAddresses = TRUE;
    DeviceDescription.IgnoreCount = FALSE;//TRUE;
    DeviceDescription.Reserved1 = FALSE;
    DeviceDescription.Dma64BitAddresses = FALSE;
    //devDescr.DoNotUse2 = 0; //=devDescr.BusNumber - NotUsed in WDM
    DeviceDescription.DmaChannel = 0; //только для Slave устройств
    DeviceDescription.InterfaceType = PCIBus;
    DeviceDescription.DmaWidth = Width32Bits; // PCI default width
    DeviceDescription.DmaSpeed = Compatible;//не для мастера? (только если value only if the machine's ACPI BIOS supports it)... ничего не понял
    //devDescr.MaximumLength = ROUND_TO_PAGES(XXXXX/2);   
    DeviceDescription.MaximumLength =  PAGE_SIZE;    //в любом случае они просили округлить до PAGE_SIZE, да на здоровье!
    //devDescr.DmaPort = 0;   //говорят, что это устаревший параметр. но нужен для совместимости... для Legacy...
    // OS will assign map register count
    NumMapRegisters = 0;

    // Allocate a DMA adapter object
pdx->DMAAdapter = IoGetDmaAdapter(pdx->PhysicalDeviceObject, &DeviceDescription, &NumMapRegisters);

if (!pdx->DMAAdapter)
{
KdPrint(("ERROR - DMA Adapter allocation failed\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}

KdPrint((" MAX_DMA_LENGTH: %d, ROUND_TO_PAGES(MAX_DMA_LENGTH): %d \n", MAX_DMA_LENGTH, ROUND_TO_PAGES(MAX_DMA_LENGTH)));
//выделяем нужную память ДМА под каждый буфер...
m_DmaBuffer1  = pdx->DMAAdapter->DmaOperations->AllocateCommonBuffer(
    pdx->DMAAdapter, ROUND_TO_PAGES(MAX_DMA_LENGTH), &DmaPhysAddr1, FALSE);

m_DmaBuffer2  = pdx->DMAAdapter->DmaOperations->AllocateCommonBuffer(
    pdx->DMAAdapter, ROUND_TO_PAGES(MAX_DMA_LENGTH), &DmaPhysAddr2, FALSE);


if ((!m_DmaBuffer1)||(!m_DmaBuffer2))

pdx->DMAAdapter = NULL;
KdPrint((" Failed to allocate DMA buffer\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}

DmaBufferMemory1 = IoAllocateMdl(m_DmaBuffer1, ROUND_TO_PAGES(MAX_DMA_LENGTH), FALSE, FALSE, NULL);//ROUND_TO_PAGES(MAX_DMA_LENGTH)
DmaBufferMemory2 = IoAllocateMdl(m_DmaBuffer2, ROUND_TO_PAGES(MAX_DMA_LENGTH), FALSE, FALSE, NULL);

if ((DmaBufferMemory1 != NULL)||(DmaBufferMemory2 != NULL))
{ //MmBuildMdlForNonPagedPool заполняет массив номеров физических страниц и обновляет некоторые поля заголовка MDL.
KdPrint((DRIVERNAME " -  SHOW SIZE DMS 1:  %d \n", DmaBufferMemory1->Size));
MmBuildMdlForNonPagedPool(DmaBufferMemory1);
KdPrint((DRIVERNAME " -  SHOW SIZE DMS 2:  %d \n", DmaBufferMemory2->Size));
MmBuildMdlForNonPagedPool(DmaBufferMemory2);
}
else
{
KdPrint((" Failed to allocate MDL buffer \n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
//Получаем начальные адреса буферов ДМА...
uDmaPhysAddr1 = DmaPhysAddr1.LowPart;
KdPrint((DRIVERNAME " -  SHOW DMA 1 ADDRESS IN START %Xh\n", uDmaPhysAddr1));
uDmaPhysAddr2 = DmaPhysAddr2.LowPart;
KdPrint((DRIVERNAME " -  SHOW DMA 2 ADDRESS IN START %Xh\n", uDmaPhysAddr2));

if ((uDmaPhysAddr1 == 0)||(uDmaPhysAddr2 == 0))
{
KdPrint((" Failed to allocate uDmaPhysAddr \n"));
MDMAIDmaAdapterFree(pdx);
return STATUS_INSUFFICIENT_RESOURCES;
}

KdPrint((DRIVERNAME " - DMA Adapter init... OK!!! \n"));

    return STATUS_SUCCESS;
}
функция IoAllocateMdl не выделяет память для MDL.
 наверняка есть механизмы обхода такой ситуации?!
Как можно расширить буфер до 64 МВ???
чуть не забыл ОС ХР 32 бит...
Прошу Вашей помощи!
Огромное спасибо!
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 04-05-2013 19:46 » 

перезагрузить комп и выделять пока есть не дефрагментированная память.
либо сменить ОС. на XP ограничение на эту память более жесткое. 256м что ли.. в какой то теме приводил.. из первых трех приколотых что ли...
выделять такие объемы непрерывной памяти вообще проблематично. учитывая что ScatterGather = FALSE... это единственный метод.
« Последнее редактирование: 04-05-2013 19:56 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sabbatazh
Помогающий

ua
Offline Offline

« Ответ #2 : 06-05-2013 18:56 » 

Ochkarik, Спасибо! Читал про проблемы с выделением под ХР больше 32 МВ и пишут что можно обойти, а как, толком не объясняют!
Если будит прогресс отпишу!
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines