Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> Шелезяки —> NetMos NM9845

Мультипортовая плата (шесть com-портов) под FreeBSD

Автор: lissyara.


    Понадобилось (для модемного пула - на специализированную железку контора не разориться - вот и лепим из чего есть) полтора десятка com-портов на одном компе. Закупили две платы неизвестной конструкции и производителя. На чипах написано "MosChip semiconductor - MCS9845CV" - по 6 портов на каждой. Поставили в старый сервак (там стояли исовые мультипортовые платы - в жизни таких не видел, сами порты выводились шлейфом типа IDE-шного на отдельную плату), тока его это не спасло - как глючило, так и продолжало. Назрело решение - пора менять win2000, что там стоял пять лет (на компе постоянно подключенном к инету!) на что-то более существенное. Собрали другой сервак, накатил FreeBSD6.1, тут и началось веселье - ункновн девайс:
pci0: <simple comms, UART> at device 10.0 (no driver attached)

   Ладно, это победилось влёт - пересборкой ядра (можно подгрузить модуль) с такой опцией:
device          puc

   После перезагрузки, получили такую картину в dmesg:
puc0: <NetMos NM9845 Quad UART> port 0xd400-0xd407,0xd800-0xd807,0xdc00-0xdc07,
0xe000-0xe007,0xe400-0xe407,0xe800-0xe80f irq 11 at device 10.0 on pci0
sio4: <NetMos NM9845 Quad UART> on puc0
sio4: type 16550A
sio4: unable to activate interrupt in fast mode - using normal mode
sio5: <NetMos NM9845 Quad UART> on puc0
sio5: type 16550A
sio5: unable to activate interrupt in fast mode - using normal mode
sio6: <NetMos NM9845 Quad UART> on puc0
sio6: type 16550A
sio6: unable to activate interrupt in fast mode - using normal mode
sio7: <NetMos NM9845 Quad UART> on puc0
sio7: type 16550A
sio7: unable to activate interrupt in fast mode - using normal mode

   Мда... Мало того что ругается, так и портов всего четыре, хотя на плате их шесть :)). Причём в перечислении портов (строка: port 0xd400-0xd407, 0xd800-0xd807, 0xdc00-0xdc07, 0xe000-0xe007, 0xe400-0xe407, 0xe800-0xe80f), их там все шесть. Посмотрел инфу о шине PCI:
/usr/home/lissyara/>pciconf -lv | grep --after-context=4 puc0
puc0@pci0:9:0:  class=0x070002 card=0x00061000 chip=0x98459710 rev=0x01 hdr=0x00
    vendor   = 'MosChip Semiconductors (Was: Netmos Technology)'
    device   = 'Nm9845 Parallel/Serial Port Adapter'
    class    = simple comms
    subclass = UART
/usr/home/lissyara/>

   Легче не стало :)). Пришлось рыться в исходных кодах ядра, по строке из dmesg:
/usr/home/lissyara/>cd /usr/src/
/usr/src/>find . -exec grep -l "NetMos NM9845 Quad UART" {} \;
./sys/dev/puc/pucdata.c

   В С++ ничё не понимаю, но посмотреть надо было - как-то уже сталкивался с интересными опциями, которые были просто закомменчены - иногда нестабильно работало. В этом файле была такая секция:
        /* NetMos 4S0P PCI: 4S, 0P */
        {   "NetMos NM9845 Quad UART",
            {   0x9710, 0x9845, 0,      0       },
            {   0xffff, 0xffff, 0,      0       },
            {
                { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ },
                { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ },
                { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ },
                { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ },
            },
        },

   Несмотря на моё незнание данного языка программирования, первая идея при взгляде на этот кусок и соседний, где описывался восьми портовый адаптер - это добавить ещё две строки, описывающие два неопределившихся порта. Получилось так:
        /* NetMos 4S0P PCI: 4S, 0P */
        {   "NetMos MSC9845CV HEXA UART",
            {   0x9710, 0x9845, 0,      0       },
            {   0xffff, 0xffff, 0,      0       },
            {
                { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ },
                { PUC_PORT_TYPE_COM, 0x14, 0x00, COM_FREQ },
                { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ },
                { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ },
// next 2 line added
                { PUC_PORT_TYPE_COM, 0x20, 0x00, COM_FREQ },
                { PUC_PORT_TYPE_COM, 0x24, 0x00, COM_FREQ },
            },
        },

   Я поправил название чипа, и добавил две строки для портов. Заодно, вычитал в LINT про ругань, что была на прерывания. Надо было добавить ещё одну опцию:
options         PUC_FASTINTR

   Пересобираем ядро, перезагружаемся, смотрим dmesg:
puc0: <NetMos MSC9845CV HEXA UART> port 0xd400-0xd407,0xd800-0xd807,0xdc00-0xdc07,
0xe000-0xe007,0xe400-0xe407,0xe800-0xe80f irq 11 at device 9.0 on pci0
sio4: <NetMos MSC9845CV HEXA UART> on puc0
sio4: type 16550A
sio5: <NetMos MSC9845CV HEXA UART> on puc0
sio5: type 16550A
sio6: <NetMos MSC9845CV HEXA UART> on puc0
sio6: type 16550A
sio7: <NetMos MSC9845CV HEXA UART> on puc0
sio7: type 16550A
sio8: <NetMos MSC9845CV HEXA UART> on puc0
sio8: type 16550A
sio9: <NetMos MSC9845CV HEXA UART> on puc0
sio9: type 16550A

   Ну и всё. Главное при пересборках ядра не забывать про этот момент.

P.S. На самом деле, я уже насобирал несколько версий ядра - хотел сделать патч, чтобы отличать адаптеры. Неполучается. Слишком одинаковые... Щас собирается последняя версия, с количеством портов - 8 шт - хочу проверить как он себя поведёт при отсутсвующих портах (на плате-то их всего шесть). Если всё нормально - напишу в баг-лист FreeBSD предложение о увеличении количества портов в драйвере.



размещено: 2006-11-25,
последнее обновление: 2006-12-21,
автор: lissyara


butcher, 2006-12-20 в 15:38:04

Если есть время, наложите вот этот патч в дополнение к вашим исправлениям и покажите, что система выводит при загрузке:
+++ puc_pci.c   Wed Dec 20 15:36:02 2006
@@ -123,6 +123,8 @@
   desc = puc_find_description(v1, d1, v2, d2);
   if (desc == NULL)
       return (ENXIO);
+   device_printf(dev, "Vendor: %04X, Device: %04X, SubVendor: %04X, "
+                   "SubDevice: %04X\n", v1, d1, v2, d2);
   device_set_desc(dev, desc->name);
   return (BUS_PROBE_DEFAULT);
}

DS, 2007-03-23 в 22:46:55

Даташит на 9845:
http://www.moschip.com/data/products/NM9845/Data%20Sheet_9845.pdf

Количество комов хранится в младшем ниббле SubsystemID, количество LPT - в старшем ниббле.

Есть еще одна тонкость - прерывание карты ни в коем случае не должно быть зашаренным с кем-то еще, иначе будут проблемы.

tankistua, 2009-08-20 в 20:36:34

у меня от подгрузки модуля 7.2 выпадает в дамп - хочу попробовать в ядро вкомпилить, еще вариант - переставить в другой слот.

tankistua, 2009-08-21 в 18:58:58

завелась у меня на 7.2 карточка, надо было только я ядро вкомпилить. Неправильно чуток завелась - у меня нет lpt-порта, но главное что работает.

puc0@pci0:1:1:0:        class=0x070002 card=0x00041000 chip=0x98459710 rev=0x01 hdr=0x00
   vendor     = 'MosChip Semiconductors (Was: Netmos Technology)'
   device     = 'Nm9845 Parallel/Serial Port Adapter'
   class      = simple comms
   subclass   = UART

alik, 2009-12-03 в 13:41:46

Как раз сейчас этим и занимаюсь, очень приятно что уже существует такая статья!



 

  Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
  Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.177 секунд
Из них PHP: 25%; SQL: 75%; Число SQL-запросов: 77 шт.
Исходный размер: 23967; Сжатая: 6733