Есть PCI-ная железка. Под нее на 2.4 был написан модуль. В момент загрузки модуля читалось конф.пространство этой железки, откуда добывали адреса портов, памяти, и номер прерывания, необходимые этой железке. Все это благополучно захватывалось и работало.
При переходе на ядро 2.6 столкнулись с проблемой: номер прерывания читается не верный. Точнее не тот, что система определяет для этой платы. В итоге обработчик вешаем на одно прерывание, а в реале происходит другое.
Да, порты и память продолжают определяться правильно.
Как в 2.6 автоматически определить номер прерывания PCI-устройства?
На 2.4 работало, а на 2.6 - ....
[console]cat /var/log/boot.msg | grep irq
lspci -v[/console]
супер, только мне надо чтобы модуль сам мог определить этот IRQ. автоматически.
а найти его где-то и ручками потом в модуль передавать - не катит.
При переходе на ядро 2.6 столкнулись с проблемой: номер прерывания читается не верный. Точнее не тот, что система определяет для этой платы.
ну... вы пишете загадками. кусок кода можно? если страшно - посмотрите как сделано в свободных дровах (исходники есть в любом дистрибутиве, ну или ссылки на исходники).
На этапе регистрации модуля
Читаем номер IRQ из конфигурационного пространства:
where = 0x3c;
pci_read_config_byte(dev, where, &INT1);
// printk ("Interrupt1 %d\n", INT1);
Захватываем прерывание:
rezult = request_irq(INT1, interrupt6202, SA_SHIRQ, DEV_NAME, interrupt6202);
if ((rezult) && (mes==1) )
{
printk("Can't get IRQ line\n");
}
Так вот, прочитанное таким образом INT1 не совпадает с тем, что я нахожу описанным вами путем:
cat /var/log/boot.msg | grep irq
lspci -v
nihao
Вам не надо определять каждый раз IRQ. Просто узнайте какой именно IRQ Вам нужен и перепешите драйвер.
&INT1 чему равно?
К сожалению, надо. :(
Специфика работы такова, что внутренности железа могут видоизменяться . Соответственно, могут "поехать" и адреса портов, памяти, и IRQ.
Система с нашими железками и "дровами" поставляется разным клиентам в разные города. Не наездишься каждый раз настраивать.
И ведь на 2.4 все работало!!! Вот надо было им на 2.6 переходить! :[
К сожалению, надо. :(
Специфика работы такова, что внутренности железа могут видоизменяться . Соответственно, могут "поехать" и адреса портов, памяти, и IRQ.[
Хм... трудно такое представить, но даже если так, то сейчас у Вас будет конфликт с одним устройством, а потом с другим...
Диапазон IRQ-то хотя бы известен?
Вообще, я пытаюсь себе предствить как это должно работать, и что-то у меня не получается :o Адресация идет по шине, по так называемому ID PCI-устройства. Если и оно будет меняться, то чтобы ловить ваши прерывания, придется еще пару модулей написать wink
Вы когда делаете [console]lspci[/console]
то видете id устройства. Он выводится самым первым параметром.
Его так же можно увидеть, если сделать [console]hwinfo pci[/console]
то видете id устройства.
а что мешает открыть исходник и посмотреть? lspci который. мне мешает лень :)
[quote=UTe11ok]то видете id устройства.
а что мешает открыть исходник и посмотреть? lspci который. мне мешает лень :)[/quote]
Мне тоже мешает лень wink
У меня вывод lspci в 24 строчки. Сколько мне файлов-то с исходниками открыть придется? :rolleyes:
У меня вывод lspci в 24 строчки. Сколько мне файлов-то с исходниками открыть придется?
один наверное. ну или 2, если ошибётесь :)
какой? :O
какой?
не знаю. лень искать. у вас нет дистрибутива?
[quote=UTe11ok]какой?
не знаю.[/quote]
как узнаете, обязательно напишите!
Хм... трудно такое представить, но даже если так, то сейчас у Вас будет конфликт с одним устройством, а потом с другим...
Диапазон IRQ-то хотя бы известен?
Видимо, некорректно выразилась... :(
Видоизменяться могут внутренности самого компьютера: добавят\снимут какую-нибудь плату; "мою" железку переткнут из одного разъема в другой; или перезагрузят комп сначала без "моей" железки (мало ли, надо будет что-н протестировать), а потом опять перезагрузят, вставив "железку"... Внутри железки ничего, слава богу, не двигается.
В общем, правила хорошего тона требуют как можно большее автоматизирование. Чтобы пользователю не нужно было самому разыскивать ID номер платы, по нему определять IRQ, который и передавать уже в модуль для дальнейшей работы. (хотя, если клиент оставляет за собой право копаться во внутренностях компа ...)
Вы когда делаете [console]lspci[/console]
то видете id устройства. Он выводится самым первым параметром.
Вижу. Кроме того, могу его прочитать в конф. файле.
Самое непонятное то, что модуль-то давно и успешно работал под ядром 2.4
Что же такого сделали в 2.6?
Такое ощущение, что система переопределяет прерывания, назначенные "железке" при загрузке, но в конф.пространство этой "железки" никаких исправлений не вносит.
И по какому принципу она это все переопределяет? Может алгоритм какой есть? А может это "отключить" как-то можно?
Кстати, /proc/pci на своем компе не нашла. но это уже отдельная песня.
Хм... трудно такое представить, но даже если так, то сейчас у Вас будет конфликт с одним устройством, а потом с другим...
Диапазон IRQ-то хотя бы известен?
Видимо, некорректно выразилась... :(
Видоизменяться могут внутренности самого компьютера: добавят\снимут какую-нибудь плату; "мою" железку переткнут из одного разъема в другой; или перезагрузят комп сначала без "моей" железки (мало ли, надо будет что-н протестировать), а потом опять перезагрузят, вставив "железку"... Внутри железки ничего, слава богу, не двигается.
От этого IRQ не меняется.
В общем, правила хорошего тона требуют как можно большее автоматизирование. Чтобы пользователю не нужно было самому разыскивать ID номер платы, по нему определять IRQ, который и передавать уже в модуль для дальнейшей работы. (хотя, если клиент оставляет за собой право копаться во внутренностях компа ...)
Я не такой уж мостак в написание драйверов, но вроди бы номер irq прерыания определяется в драйвере (программный уровень), т.е. в модуле задан номер прерывания, и ядро об этом знает, и если поступает сигнал, то ядро вызывает этот модуль (передает ему управление).
Самое непонятное то, что модуль-то давно и успешно работал под ядром 2.4
Что же такого сделали в 2.6?
Ну вообще-то это два разных ядра. ОЧЕНЬ многое поменялось.
Такое ощущение, что система переопределяет прерывания, назначенные "железке" при загрузке, но в конф.пространство этой "железки" никаких исправлений не вносит.
И по какому принципу она это все переопределяет? Может алгоритм какой есть? А может это "отключить" как-то можно?
IRQ стандартны для каждой железки. Посмотрите сейчас свои irq прерывания, сравните их с теми, которые будут после перезагрузки.
Кстати, /proc/pci на своем компе не нашла. но это уже отдельная песня.
Может лучше так? wink
[console]cat /proc/interrupts[/console]
Попробуйте:
static struct pci_dev* pdevAI = NULL;
// поиск платы
pdevAI = pci_get_subsys(..., ..., ..., ..., pdevAI); //ID, SUBID ...
return pdevAI->irq; // возвращает номер прерывания
При переходе на ядро 2.6 столкнулись с проблемой: номер прерывания читается не верный. Точнее не тот, что система определяет для этой платы.
Кстати, при загрузке модуля, может прокатить - в качестве параметра тупо передать номер irq wink
Например:
[console]modprobe pcbit mem=0xd0000 irq=5[/console]
[quote=drBatty][quote=UTe11ok]какой?
не знаю.[/quote]
как узнаете, обязательно напишите![/quote]
исходник в слаке здесь:
source/a/pciutils/pciutils-2.2.10.tar.bz2
распакуете, и там lspci.c
щаз прелеплю (слака 12.2)
drBatty
Дык, стоп! Это не в ядре.