Subject: different types of NetMos puc(4) devices
To: None <tech-kern@netbsd.org>
From: Pavel Cahyna <pcah8322@artax.karlin.mff.cuni.cz>
List: tech-kern
Date: 01/23/2006 17:22:00
Hello,

we recently bought two 6-port serial cards with a Nm9845CV chip. Then we
noticed that the card has the same PCI ID (0x9845) as the 4S1P which is
already supported by the puc(4) driver and NetBSD found 4 serial and one
parallel port. Then I looked at the NetMos site and discovered that this
chip has only 2 UARTs and is commonly used with another chips in either
4S, 4S1P and 6S configurations (see
http://www.moschip.com/data/products/NM9845/Application%20Note_9845.zip).

As one entry in pucdata.c is unable to cover three configurations, I
needed a way to distinguish between them. We already have a 4S1P card and
pcictl dump showed that there is only one difference: Subsystem ID, which
is 0x0006 for the 6S cards and 0x0014 for the 4S1P card.

Another problem is that the 2 "upper" ports in the 4S1P card do not work.
This is caused by the following lines in pucdata.c:

               { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ * 4 },
               { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ * 4 },

COM_FREQ * 4 is wrong, e.g. if I have getty running at 9600, I have to set
2400 baud for cu on the remote machine.

This entry was added by lukem, with a comment that all ports appear to
work. Unfortunately the card tested was different from mine and I suspect
that the subsystem ID would be again the only way to distinguish between
them.

The following patch fixes both problems for me. The subsystem ID for the
card which needs COM_FREQ * 4 should be added as another special case, if
somebody will find it.

I left the entry without subsystem ID at the end, hoping that it will
catch all the cards with an unknown ID.

To summarize: there are at least those variants of puc cards, all with the
same PCI id 0x9845:

4S1P: subsystem ID 0x0014
6S: subsystem ID 0x0006
4S1P, two ports need COM_FREQ * 4: subsystem ID unknown
4S (that's what OpenBSD founds): subsystem ID unknown

(BTW I tested only the serial ports.)

Pavel Cahyna

Index: pucdata.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pucdata.c,v
retrieving revision 1.40
diff -u -r1.40 pucdata.c
--- pucdata.c   27 Feb 2005 00:27:34 -0000      1.40
+++ pucdata.c   23 Jan 2006 16:13:36 -0000
@@ -938,13 +938,40 @@
 
        /* NetMos 4S1P PCI NM9845 : 4S, 1P */
        {   "NetMos NM9845 Quad UART and 1284 Printer port",
+           {   0x9710, 0x9845, 0x1000, 0x0014  },
+           {   0xffff, 0xffff, 0xffff, 0xffff  },
+           {
+               { 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 },
+               { PUC_PORT_TYPE_LPT, 0x20, 0x00, 0x00 },
+           },
+       },
+
+       /* NetMos 6S PCI 16C650 : 6S, 0P */
+       {   "NetMos NM9845 6 UART",
+           {   0x9710, 0x9845, 0x1000, 0x0006  },
+           {   0xffff, 0xffff, 0xffff, 0xffff  },
+           {
+               { 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 },
+               { PUC_PORT_TYPE_COM, 0x20, 0x00, COM_FREQ },
+               { PUC_PORT_TYPE_COM, 0x24, 0x00, COM_FREQ },
+           },
+       },
+
+       /* NetMos 4S1P PCI NM9845 : 4S, 1P */
+       {   "NetMos NM9845 Quad UART and 1284 Printer port (unknown type)",
            {   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 * 4 },
-               { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ * 4 },
+               { PUC_PORT_TYPE_COM, 0x18, 0x00, COM_FREQ },
+               { PUC_PORT_TYPE_COM, 0x1c, 0x00, COM_FREQ },
                { PUC_PORT_TYPE_LPT, 0x20, 0x00, 0x00 },
            },
        },