LINUX.ORG.RU

Чтение с MMIO


0

0

Добрый день.
Мы создали PCI-плату, выполняющую определенные функции. И необходимо осуществить обмен данными этой платы с PC. При написании драйвера под линукс возникла следующая проблема:
//Определяем, какие порты у PCI устройства
board->PCI_mem_start=pci_resource_start(dev,0);
//Делаем проекцию на область памяти
board->virt_io_start=ioremap_nocache(board->PCI_mem_start,256*sizeof(int));
...................................
...................................
int i,k;
unsigned int temp[256];

for (i=0;i<40;i++){
printk(KERN_ALERT "Buffer %d.\n",i);
for (k=0;k<256;k++){
temp[k]=ioread32(board->virt_io_start+k*4);
printk(KERN_ALERT "Transaction %d. Received value 0x%x\n",k,temp[k]);
wait_event_interruptible_timeout(wait, 0, HZ/20);//Idle delay 50ms
}
}

Т.е. я пытаюсь считать с rapsody_board->virt_io_start области памяти данные в буфер temp. Вот этот код работает. Но!
если я комменчу строку "printk(KERN_ALERT "Transaction %d. Received value 0x%x\n",k,temp[k]);", ядро виснет на приеме случайного(!!!) номера буфера(бывает первого, бывает второго или третьего) со следующим call trace:
default_idle+0x27/0x39
cpu_idle+0x60/0x8e
start_kernel+0x27f/0x284
unknown_bootoption+0x0/0x194
Code: cc cc cc cc.....
EIP: ignore_int+0x1/0x41
Kernel panic- not syncing: Attempted to kill idle task

Если я вместо функции ioread32 применяю функцию memcpy_fromio(temp,board->virt_io_start,256*4), аналогично, зависает на случайном номере буфера с такой же ошибкой.

Запись в устройство ведется нормально с помощью функции memcpy_toio.

Замучался совсем. Помогите, в какую сторону копать и что смотреть.
Заранее благодарен


Стек не разрушаешь килобайтным массивом? Попробуй temp сделать указателем? и выделяй память kmalloc'ом.

mv ★★★★★
()

>Вот этот код работает. Но!
если я комменчу строку "printk(KERN_ALERT...
ядро виснет на приеме случайного(!!!) номера буфера
Если я вместо функции ioread32 применяю функцию memcpy_fromio(temp,board->virt_io_start,256*4), аналогично, зависает на случайном номере буфера с такой же ошибкой.

Задержку не пробовал увеличить ?

imhotep
()
Ответ на: комментарий от mv

Раньше было ядро 2.6.22 -аналогичная ошибка, теперь 2.6.24.
Система Debian lenny x86 (amd geode lx). Т.е. PC-104Plus плата.
На плате один PCI коннектор. Туда и вставляем наше устройство.

Раньше, на ядре 2.6.22 отлаживали на Pentium 4, была такая же проблема, но мы списали ее на то, что между материнской платой и PCI-макетом был длинный шлейф(под спецификацию не подходил)

SoIAm
() автор топика
Ответ на: комментарий от imhotep

В принципе с увеличением задержки всё более и более стабильно работает. Что честно говоря довольно странно. Ведь текущая задержка 50мс для одной транзакции PCI это зажирно. PCI должна справляться и за 1мкс считать слово.

Попробовал увеличить задержку до 200мс. Всё равно зависает, если без printk.

вот как printk влияет, не могу понять.
Может gcc заоптимизировал как-то странно, что при неиспользовании буфера temp в него криво пишются значения с порта?

SoIAm
() автор топика
Ответ на: комментарий от SoIAm

> Может gcc заоптимизировал как-то странно, что при неиспользовании буфера temp в него криво пишются значения с порта?

На вряд ли. Ну попробуй вместо printk поставить mb().

mv ★★★★★
()
Ответ на: комментарий от SoIAm

>как printk влияет, не могу понять.

Один из побочных эффектов printk - может надолго блокировать прерывания.

imhotep
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.