Discussion:
Sunix 4056A PCI 4 port RS-232 card - only 2 ports configured
(too old to reply)
N.J. Mann
2011-05-22 11:28:26 UTC
Permalink
Hi,


I am trying to setup a console server, but I am having a problem with
the hardware. The RS-232 card I am using is a Sunix 4056A Universal PCI
4 port RS-232 card. However, only two ports are being configured, uart2
and uart3 - uart0 and uart1 are on the motherboard. I had assumed that
all I had to do was install the card, add puc(4) to my kernel and it
would just work.

uname:
------
FreeBSD 9.0-CURRENT #0: Thu May 19 15:01:10 UTC 2011 i386

I CVSup'ed about fours before then.


relevant parts of verbose dmesg:
--------------------------------
found-> vendor=0x1409, dev=0x7168, revid=0x01
domain=0, bus=0, slot=10, func=0
class=07-00-02, hdrtype=0x00, mfdev=0
cmdreg=0x0081, statreg=0x0280, cachelnsz=0 (dwords)
lattimer=0x00 (0 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
intpin=a, irq=3
map[10]: type I/O Port, range 32, base 0xe000, size 5, enabled
map[14]: type I/O Port, range 32, base 0xe400, size 4, enabled
pcib0: matched entry for 0.10.INTA
pcib0: slot 10 INTA hardwired to IRQ 18
[...]
puc0: <Timedia technology 4 Port Serial> port 0xe000-0xe01f,0xe400-0xe40f irq 18 at device 10.0 on pci0
ioapic0: routing intpin 18 (PCI IRQ 18) to lapic 0 vector 52
uart2: <16550 or compatible> on puc0
uart2: fast interrupt
uart3: <16550 or compatible> on puc0
uart3: fast interrupt


I can provide a full verbose dmesg if required, together with any other
information which may be relevant.

Any and all help gratefully received.


Cheers,
Nick.
--
John Baldwin
2011-05-23 14:33:23 UTC
Permalink
Post by N.J. Mann
Hi,
I am trying to setup a console server, but I am having a problem with
the hardware. The RS-232 card I am using is a Sunix 4056A Universal PCI
4 port RS-232 card. However, only two ports are being configured, uart2
and uart3 - uart0 and uart1 are on the motherboard. I had assumed that
all I had to do was install the card, add puc(4) to my kernel and it
would just work.
------
FreeBSD 9.0-CURRENT #0: Thu May 19 15:01:10 UTC 2011 i386
I CVSup'ed about fours before then.
--------------------------------
found-> vendor=0x1409, dev=0x7168, revid=0x01
domain=0, bus=0, slot=10, func=0
class=07-00-02, hdrtype=0x00, mfdev=0
cmdreg=0x0081, statreg=0x0280, cachelnsz=0 (dwords)
lattimer=0x00 (0 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
intpin=a, irq=3
map[10]: type I/O Port, range 32, base 0xe000, size 5, enabled
map[14]: type I/O Port, range 32, base 0xe400, size 4, enabled
pcib0: matched entry for 0.10.INTA
pcib0: slot 10 INTA hardwired to IRQ 18
[...]
puc0: <Timedia technology 4 Port Serial> port 0xe000-0xe01f,0xe400-0xe40f
irq 18 at device 10.0 on pci0
Post by N.J. Mann
ioapic0: routing intpin 18 (PCI IRQ 18) to lapic 0 vector 52
uart2: <16550 or compatible> on puc0
uart2: fast interrupt
uart3: <16550 or compatible> on puc0
uart3: fast interrupt
I can provide a full verbose dmesg if required, together with any other
information which may be relevant.
Any and all help gratefully received.
Hmm, for Timedia it looks like the puc(4) driver uses the subvendor device ID
to figure out how many ports your card has, but it does see 4 ports (the
device descrption is correct). Does 'devinfo -v' show any other child
devices of 'puc0' besides the two uart devices?
--
John Baldwin
N.J. Mann
2011-05-23 15:17:38 UTC
Permalink
Post by John Baldwin
Post by N.J. Mann
Hi,
I am trying to setup a console server, but I am having a problem with
the hardware. The RS-232 card I am using is a Sunix 4056A Universal PCI
4 port RS-232 card. However, only two ports are being configured, uart2
and uart3 - uart0 and uart1 are on the motherboard. I had assumed that
all I had to do was install the card, add puc(4) to my kernel and it
would just work.
------
FreeBSD 9.0-CURRENT #0: Thu May 19 15:01:10 UTC 2011 i386
I CVSup'ed about fours before then.
--------------------------------
found-> vendor=0x1409, dev=0x7168, revid=0x01
domain=0, bus=0, slot=10, func=0
class=07-00-02, hdrtype=0x00, mfdev=0
cmdreg=0x0081, statreg=0x0280, cachelnsz=0 (dwords)
lattimer=0x00 (0 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
intpin=a, irq=3
map[10]: type I/O Port, range 32, base 0xe000, size 5, enabled
map[14]: type I/O Port, range 32, base 0xe400, size 4, enabled
pcib0: matched entry for 0.10.INTA
pcib0: slot 10 INTA hardwired to IRQ 18
[...]
puc0: <Timedia technology 4 Port Serial> port 0xe000-0xe01f,0xe400-0xe40f
irq 18 at device 10.0 on pci0
ioapic0: routing intpin 18 (PCI IRQ 18) to lapic 0 vector 52
uart2: <16550 or compatible> on puc0
uart2: fast interrupt
uart3: <16550 or compatible> on puc0
uart3: fast interrupt
I can provide a full verbose dmesg if required, together with any other
information which may be relevant.
Any and all help gratefully received.
Hmm, for Timedia it looks like the puc(4) driver uses the subvendor device ID
to figure out how many ports your card has, but it does see 4 ports (the
device descrption is correct). Does 'devinfo -v' show any other child
devices of 'puc0' besides the two uart devices?
No.

puc0 pnpinfo vendor=0x1409 device=0x7168 subvendor=0x1409 subdevice=0x4056 class=0x070002 at slot=10 function=0
uart2
uart3

(If you want the complete output of devinfo just ask - I assumed from
your question you only wanted the puc-releated section.)

BTW I saw the patch for puc(4) you just posted to ***@. Is it worth
me trying that?

Many thanks.


Cheers,
Nick.
--
John Baldwin
2011-05-24 11:57:03 UTC
Permalink
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Hi,
I am trying to setup a console server, but I am having a problem with
the hardware. The RS-232 card I am using is a Sunix 4056A Universal PCI
4 port RS-232 card. However, only two ports are being configured, uart2
and uart3 - uart0 and uart1 are on the motherboard. I had assumed that
all I had to do was install the card, add puc(4) to my kernel and it
would just work.
------
FreeBSD 9.0-CURRENT #0: Thu May 19 15:01:10 UTC 2011 i386
I CVSup'ed about fours before then.
--------------------------------
found-> vendor=0x1409, dev=0x7168, revid=0x01
domain=0, bus=0, slot=10, func=0
class=07-00-02, hdrtype=0x00, mfdev=0
cmdreg=0x0081, statreg=0x0280, cachelnsz=0 (dwords)
lattimer=0x00 (0 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
intpin=a, irq=3
map[10]: type I/O Port, range 32, base 0xe000, size 5, enabled
map[14]: type I/O Port, range 32, base 0xe400, size 4, enabled
pcib0: matched entry for 0.10.INTA
pcib0: slot 10 INTA hardwired to IRQ 18
[...]
puc0: <Timedia technology 4 Port Serial> port 0xe000-0xe01f,0xe400-0xe40f
irq 18 at device 10.0 on pci0
ioapic0: routing intpin 18 (PCI IRQ 18) to lapic 0 vector 52
uart2: <16550 or compatible> on puc0
uart2: fast interrupt
uart3: <16550 or compatible> on puc0
uart3: fast interrupt
I can provide a full verbose dmesg if required, together with any other
information which may be relevant.
Any and all help gratefully received.
Hmm, for Timedia it looks like the puc(4) driver uses the subvendor device ID
to figure out how many ports your card has, but it does see 4 ports (the
device descrption is correct). Does 'devinfo -v' show any other child
devices of 'puc0' besides the two uart devices?
No.
puc0 pnpinfo vendor=0x1409 device=0x7168 subvendor=0x1409 subdevice=0x4056 class=0x070002 at slot=10 function=0
uart2
uart3
(If you want the complete output of devinfo just ask - I assumed from
your question you only wanted the puc-releated section.)
Yeah, this is all I wanted. Hmm, so from the description we can see that
it thinks you have 4 ports:

snprintf(desc, sizeof(desc),
"Timedia technology %d Port Serial", (int)sc->sc_cfg_data);

and the code that sets sc_cfg_data sets it to the number of supported ports
that PUC_CFG_GET_NPORTS returns:

case PUC_CFG_GET_NPORTS:
...
if (subdev == subdevs[dev].ids[id]) {
sc->sc_cfg_data = subdevs[dev].ports;
*res = sc->sc_cfg_data;
return (0);
}

You might need to just add some printfs to puc_bfe_attach(). It would be good
to see if the PUC_CFG_GET_NPORTS request in attach also returned 4 in res (the
description string is set in puc_bfe_probe()).
Post by N.J. Mann
me trying that?
That patch is just cosmetic. It would be nice to have it tested, but it
won't fix your bug.
--
John Baldwin
N.J. Mann
2011-05-24 15:58:40 UTC
Permalink
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Hi,
I am trying to setup a console server, but I am having a problem with
the hardware. The RS-232 card I am using is a Sunix 4056A Universal PCI
4 port RS-232 card. However, only two ports are being configured, uart2
and uart3 - uart0 and uart1 are on the motherboard. I had assumed that
all I had to do was install the card, add puc(4) to my kernel and it
would just work.
------
FreeBSD 9.0-CURRENT #0: Thu May 19 15:01:10 UTC 2011 i386
I CVSup'ed about fours before then.
--------------------------------
found-> vendor=0x1409, dev=0x7168, revid=0x01
domain=0, bus=0, slot=10, func=0
class=07-00-02, hdrtype=0x00, mfdev=0
cmdreg=0x0081, statreg=0x0280, cachelnsz=0 (dwords)
lattimer=0x00 (0 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
intpin=a, irq=3
map[10]: type I/O Port, range 32, base 0xe000, size 5, enabled
map[14]: type I/O Port, range 32, base 0xe400, size 4, enabled
pcib0: matched entry for 0.10.INTA
pcib0: slot 10 INTA hardwired to IRQ 18
[...]
puc0: <Timedia technology 4 Port Serial> port 0xe000-0xe01f,0xe400-0xe40f
irq 18 at device 10.0 on pci0
ioapic0: routing intpin 18 (PCI IRQ 18) to lapic 0 vector 52
uart2: <16550 or compatible> on puc0
uart2: fast interrupt
uart3: <16550 or compatible> on puc0
uart3: fast interrupt
I can provide a full verbose dmesg if required, together with any other
information which may be relevant.
Any and all help gratefully received.
Hmm, for Timedia it looks like the puc(4) driver uses the subvendor device ID
to figure out how many ports your card has, but it does see 4 ports (the
device descrption is correct). Does 'devinfo -v' show any other child
devices of 'puc0' besides the two uart devices?
No.
puc0 pnpinfo vendor=0x1409 device=0x7168 subvendor=0x1409 subdevice=0x4056 class=0x070002 at slot=10 function=0
uart2
uart3
(If you want the complete output of devinfo just ask - I assumed from
your question you only wanted the puc-releated section.)
Yeah, this is all I wanted. Hmm, so from the description we can see that
snprintf(desc, sizeof(desc),
"Timedia technology %d Port Serial", (int)sc->sc_cfg_data);
and the code that sets sc_cfg_data sets it to the number of supported ports
...
if (subdev == subdevs[dev].ids[id]) {
sc->sc_cfg_data = subdevs[dev].ports;
*res = sc->sc_cfg_data;
return (0);
}
The above code returns 4 each time it is called - three times.
Post by John Baldwin
You might need to just add some printfs to puc_bfe_attach(). It would be good
to see if the PUC_CFG_GET_NPORTS request in attach also returned 4 in res (the
description string is set in puc_bfe_probe()).
Okay, lots of printf's later. :-)

In put_bfe_attach() the second 'for' loop which starts with the comment
"Probe and attach our children." - puc.c line 352 - the call to
device_probe_and_attach passes for the first two ports, but fails for
the second two with an error code of 6. Does that make any sense to
you?


Cheers,
Nick.
--
John Baldwin
2011-05-24 17:42:08 UTC
Permalink
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Hi,
I am trying to setup a console server, but I am having a problem with
the hardware. The RS-232 card I am using is a Sunix 4056A Universal PCI
4 port RS-232 card. However, only two ports are being configured, uart2
and uart3 - uart0 and uart1 are on the motherboard. I had assumed that
all I had to do was install the card, add puc(4) to my kernel and it
would just work.
------
FreeBSD 9.0-CURRENT #0: Thu May 19 15:01:10 UTC 2011 i386
I CVSup'ed about fours before then.
--------------------------------
found-> vendor=0x1409, dev=0x7168, revid=0x01
domain=0, bus=0, slot=10, func=0
class=07-00-02, hdrtype=0x00, mfdev=0
cmdreg=0x0081, statreg=0x0280, cachelnsz=0 (dwords)
lattimer=0x00 (0 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
intpin=a, irq=3
map[10]: type I/O Port, range 32, base 0xe000, size 5, enabled
map[14]: type I/O Port, range 32, base 0xe400, size 4, enabled
pcib0: matched entry for 0.10.INTA
pcib0: slot 10 INTA hardwired to IRQ 18
[...]
puc0: <Timedia technology 4 Port Serial> port
0xe000-0xe01f,0xe400-0xe40f
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
irq 18 at device 10.0 on pci0
ioapic0: routing intpin 18 (PCI IRQ 18) to lapic 0 vector 52
uart2: <16550 or compatible> on puc0
uart2: fast interrupt
uart3: <16550 or compatible> on puc0
uart3: fast interrupt
I can provide a full verbose dmesg if required, together with any other
information which may be relevant.
Any and all help gratefully received.
Hmm, for Timedia it looks like the puc(4) driver uses the subvendor device ID
to figure out how many ports your card has, but it does see 4 ports (the
device descrption is correct). Does 'devinfo -v' show any other child
devices of 'puc0' besides the two uart devices?
No.
puc0 pnpinfo vendor=0x1409 device=0x7168 subvendor=0x1409
subdevice=0x4056 class=0x070002 at slot=10 function=0
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
uart2
uart3
(If you want the complete output of devinfo just ask - I assumed from
your question you only wanted the puc-releated section.)
Yeah, this is all I wanted. Hmm, so from the description we can see that
snprintf(desc, sizeof(desc),
"Timedia technology %d Port Serial", (int)sc->sc_cfg_data);
and the code that sets sc_cfg_data sets it to the number of supported ports
...
if (subdev == subdevs[dev].ids[id]) {
sc->sc_cfg_data = subdevs[dev].ports;
*res = sc->sc_cfg_data;
return (0);
}
The above code returns 4 each time it is called - three times.
Post by John Baldwin
You might need to just add some printfs to puc_bfe_attach(). It would be good
to see if the PUC_CFG_GET_NPORTS request in attach also returned 4 in res (the
description string is set in puc_bfe_probe()).
Okay, lots of printf's later. :-)
In put_bfe_attach() the second 'for' loop which starts with the comment
"Probe and attach our children." - puc.c line 352 - the call to
device_probe_and_attach passes for the first two ports, but fails for
the second two with an error code of 6. Does that make any sense to
you?
Ahh, can you comment out the 'device_delete_child' bit for now? It might be
worth adding some tracing to see if uart_puc_probe() is being called and if so
why it is failing.
--
John Baldwin
N.J. Mann
2011-05-24 20:01:17 UTC
Permalink
Post by N.J. Mann
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Hi,
I am trying to setup a console server, but I am having a problem
with
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
the hardware. The RS-232 card I am using is a Sunix 4056A Universal
PCI
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
4 port RS-232 card. However, only two ports are being configured,
uart2
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
and uart3 - uart0 and uart1 are on the motherboard. I had assumed
that
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
all I had to do was install the card, add puc(4) to my kernel and it
would just work.
------
FreeBSD 9.0-CURRENT #0: Thu May 19 15:01:10 UTC 2011 i386
I CVSup'ed about fours before then.
--------------------------------
found-> vendor=0x1409, dev=0x7168, revid=0x01
domain=0, bus=0, slot=10, func=0
class=07-00-02, hdrtype=0x00, mfdev=0
cmdreg=0x0081, statreg=0x0280, cachelnsz=0 (dwords)
lattimer=0x00 (0 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
intpin=a, irq=3
map[10]: type I/O Port, range 32, base 0xe000, size 5, enabled
map[14]: type I/O Port, range 32, base 0xe400, size 4, enabled
pcib0: matched entry for 0.10.INTA
pcib0: slot 10 INTA hardwired to IRQ 18
[...]
puc0: <Timedia technology 4 Port Serial> port
0xe000-0xe01f,0xe400-0xe40f
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
irq 18 at device 10.0 on pci0
ioapic0: routing intpin 18 (PCI IRQ 18) to lapic 0 vector 52
uart2: <16550 or compatible> on puc0
uart2: fast interrupt
uart3: <16550 or compatible> on puc0
uart3: fast interrupt
I can provide a full verbose dmesg if required, together with any
other
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
information which may be relevant.
Any and all help gratefully received.
Hmm, for Timedia it looks like the puc(4) driver uses the subvendor
device ID
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
to figure out how many ports your card has, but it does see 4 ports
(the
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
device descrption is correct). Does 'devinfo -v' show any other child
devices of 'puc0' besides the two uart devices?
No.
puc0 pnpinfo vendor=0x1409 device=0x7168 subvendor=0x1409
subdevice=0x4056 class=0x070002 at slot=10 function=0
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
uart2
uart3
(If you want the complete output of devinfo just ask - I assumed from
your question you only wanted the puc-releated section.)
Yeah, this is all I wanted. Hmm, so from the description we can see that
snprintf(desc, sizeof(desc),
"Timedia technology %d Port Serial", (int)sc->sc_cfg_data);
and the code that sets sc_cfg_data sets it to the number of supported
ports
Post by N.J. Mann
Post by John Baldwin
...
if (subdev == subdevs[dev].ids[id]) {
sc->sc_cfg_data = subdevs[dev].ports;
*res = sc->sc_cfg_data;
return (0);
}
The above code returns 4 each time it is called - three times.
Post by John Baldwin
You might need to just add some printfs to puc_bfe_attach(). It would be
good
Post by N.J. Mann
Post by John Baldwin
to see if the PUC_CFG_GET_NPORTS request in attach also returned 4 in res
(the
Post by N.J. Mann
Post by John Baldwin
description string is set in puc_bfe_probe()).
Okay, lots of printf's later. :-)
In put_bfe_attach() the second 'for' loop which starts with the comment
"Probe and attach our children." - puc.c line 352 - the call to
device_probe_and_attach passes for the first two ports, but fails for
the second two with an error code of 6. Does that make any sense to
you?
Ahh, can you comment out the 'device_delete_child' bit for now? It might be
worth adding some tracing to see if uart_puc_probe() is being called and if so
why it is failing.
I commented out device_delete_child and then added printf's in
uart_pub_probe() and uart_bus_probe. It is UART_PROBE which is
returning 6 for the second two ports. I must be missing something
because I cannot find where UART_PROBE is defined. Any chance of giving
me a clue? :-)

Many thanks.


Cheers,
Nick.
--
John Baldwin
2011-05-24 20:11:46 UTC
Permalink
Post by John Baldwin
Post by N.J. Mann
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Hi,
I am trying to setup a console server, but I am having a problem
with
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
the hardware. The RS-232 card I am using is a Sunix 4056A Universal
PCI
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
4 port RS-232 card. However, only two ports are being configured,
uart2
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
and uart3 - uart0 and uart1 are on the motherboard. I had assumed
that
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
all I had to do was install the card, add puc(4) to my kernel and it
would just work.
------
FreeBSD 9.0-CURRENT #0: Thu May 19 15:01:10 UTC 2011 i386
I CVSup'ed about fours before then.
--------------------------------
found-> vendor=0x1409, dev=0x7168, revid=0x01
domain=0, bus=0, slot=10, func=0
class=07-00-02, hdrtype=0x00, mfdev=0
cmdreg=0x0081, statreg=0x0280, cachelnsz=0 (dwords)
lattimer=0x00 (0 ns), mingnt=0x00 (0 ns), maxlat=0x00 (0 ns)
intpin=a, irq=3
map[10]: type I/O Port, range 32, base 0xe000, size 5, enabled
map[14]: type I/O Port, range 32, base 0xe400, size 4, enabled
pcib0: matched entry for 0.10.INTA
pcib0: slot 10 INTA hardwired to IRQ 18
[...]
puc0: <Timedia technology 4 Port Serial> port
0xe000-0xe01f,0xe400-0xe40f
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
irq 18 at device 10.0 on pci0
ioapic0: routing intpin 18 (PCI IRQ 18) to lapic 0 vector 52
uart2: <16550 or compatible> on puc0
uart2: fast interrupt
uart3: <16550 or compatible> on puc0
uart3: fast interrupt
I can provide a full verbose dmesg if required, together with any
other
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
information which may be relevant.
Any and all help gratefully received.
Hmm, for Timedia it looks like the puc(4) driver uses the subvendor
device ID
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
to figure out how many ports your card has, but it does see 4 ports
(the
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
Post by John Baldwin
device descrption is correct). Does 'devinfo -v' show any other child
devices of 'puc0' besides the two uart devices?
No.
puc0 pnpinfo vendor=0x1409 device=0x7168 subvendor=0x1409
subdevice=0x4056 class=0x070002 at slot=10 function=0
Post by N.J. Mann
Post by John Baldwin
Post by N.J. Mann
uart2
uart3
(If you want the complete output of devinfo just ask - I assumed from
your question you only wanted the puc-releated section.)
Yeah, this is all I wanted. Hmm, so from the description we can see that
snprintf(desc, sizeof(desc),
"Timedia technology %d Port Serial", (int)sc-
sc_cfg_data);
Post by N.J. Mann
Post by N.J. Mann
Post by John Baldwin
and the code that sets sc_cfg_data sets it to the number of supported
ports
Post by N.J. Mann
Post by John Baldwin
...
if (subdev == subdevs[dev].ids[id]) {
sc->sc_cfg_data = subdevs[dev].ports;
*res = sc->sc_cfg_data;
return (0);
}
The above code returns 4 each time it is called - three times.
Post by John Baldwin
You might need to just add some printfs to puc_bfe_attach(). It would be
good
Post by N.J. Mann
Post by John Baldwin
to see if the PUC_CFG_GET_NPORTS request in attach also returned 4 in res
(the
Post by N.J. Mann
Post by John Baldwin
description string is set in puc_bfe_probe()).
Okay, lots of printf's later. :-)
In put_bfe_attach() the second 'for' loop which starts with the comment
"Probe and attach our children." - puc.c line 352 - the call to
device_probe_and_attach passes for the first two ports, but fails for
the second two with an error code of 6. Does that make any sense to
you?
Ahh, can you comment out the 'device_delete_child' bit for now? It might be
worth adding some tracing to see if uart_puc_probe() is being called and if so
why it is failing.
I commented out device_delete_child and then added printf's in
uart_pub_probe() and uart_bus_probe. It is UART_PROBE which is
returning 6 for the second two ports. I must be missing something
because I cannot find where UART_PROBE is defined. Any chance of giving
me a clue? :-)
Ah, uart_puc_probe() always uses the 'uart_ns8250_class' uart driver which
is defined in uart_dev_ns8250.c. ns8250_bus_probe() is what you want to
instrument I think.
--
John Baldwin
N.J. Mann
2011-05-24 21:53:01 UTC
Permalink
In message <***@freebsd.org>,
John Baldwin (***@freebsd.org) wrote:
[snip]
Post by John Baldwin
Ah, uart_puc_probe() always uses the 'uart_ns8250_class' uart driver which
is defined in uart_dev_ns8250.c. ns8250_bus_probe() is what you want to
instrument I think.
ns8250_bus_probe() is called twice for each of the working devices as
follows:

UART2:
------
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 0
ns8250_bus_probe:: exit
..
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 193
ns8250_probe::uart_getreg REG_MCR = 8
ns8250_bus_probe:: exit

UART3
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 0
ns8250_bus_probe:: exit
..
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 193
ns8250_probe::uart_getreg REG_MCR = 8
ns8250_bus_probe:: exit

For the two devices that fail, ns8250_bus_probe() fails on the first
call:

UART4
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6

UART5
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6

The value returned for the read of REG_MCR is 64, or 0x40, which causes
the premature exit:

static int
ns8250_probe(struct uart_bas *bas)
{
u_char val;

/* Check known 0 bits that don't depend on DLAB. */
val = uart_getreg(bas, REG_IIR);
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
if (val & 0xe0)
return (ENXIO);

return (0);
}

Do you need to know the contents of 'bas'?

Many thanks.


Cheers,
Nick
--
John Baldwin
2011-05-25 13:48:11 UTC
Permalink
Post by N.J. Mann
[snip]
Post by John Baldwin
Ah, uart_puc_probe() always uses the 'uart_ns8250_class' uart driver which
is defined in uart_dev_ns8250.c. ns8250_bus_probe() is what you want to
instrument I think.
ns8250_bus_probe() is called twice for each of the working devices as
------
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 0
ns8250_bus_probe:: exit
...
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 193
ns8250_probe::uart_getreg REG_MCR = 8
ns8250_bus_probe:: exit
UART3
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 0
ns8250_bus_probe:: exit
...
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 193
ns8250_probe::uart_getreg REG_MCR = 8
ns8250_bus_probe:: exit
For the two devices that fail, ns8250_bus_probe() fails on the first
UART4
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
UART5
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
The value returned for the read of REG_MCR is 64, or 0x40, which causes
static int
ns8250_probe(struct uart_bas *bas)
{
u_char val;
/* Check known 0 bits that don't depend on DLAB. */
val = uart_getreg(bas, REG_IIR);
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
if (val & 0xe0)
return (ENXIO);
return (0);
}
Do you need to know the contents of 'bas'?
This goes beyond my level of knowledge. I've cc'd Marcel (author of uart) who
can hopefully help with this more.
--
John Baldwin
Marcel Moolenaar
2011-05-25 15:57:06 UTC
Permalink
On May 25, 2011, at 6:46 AM, John Baldwin wrote:

*snip*
Post by John Baldwin
Post by N.J. Mann
For the two devices that fail, ns8250_bus_probe() fails on the first
UART4
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
UART5
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
The value returned for the read of REG_MCR is 64, or 0x40, which causes
static int
ns8250_probe(struct uart_bas *bas)
{
u_char val;
/* Check known 0 bits that don't depend on DLAB. */
val = uart_getreg(bas, REG_IIR);
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
if (val & 0xe0)
return (ENXIO);
return (0);
}
Do you need to know the contents of 'bas'?
This goes beyond my level of knowledge. I've cc'd Marcel (author of uart) who
can hopefully help with this more.
The ns8250 family of UARTs typically have bits 5, 6 and 7 of the
MCR register reserved and thus hardwired to 0. The probe function
checks for that to make sure that the hardware looks enough like
a UART that we can claim it without hosing the box.

That said: newer chips in the family, like the ST16C850/XR16C850,
have given those bits a function:
bit 5 - Xon-Any enable
bit 6 - Infrared enable
bit 7 - Clock pre-scaler

It's unclear to me whether those bits are consistently defined
across the different implementations (for some reason I think
not) and it's also unclear to me whether the device will work
correctly with FreeBSD if we simply ignore those bits (again I
don't think this is always the case).

I think the first order of business from an architectural point
of view is to determine how much value register probing still has
on modern hardware. In the good old days, this was needed. If
we think it's not really needed anymore, then it makes sense to
loosen the grip so to speak.

For you, the first thing is to see whether the UART ports work
if you tweak the probe functions, like so:

Index: uart_dev_ns8250.c
===================================================================
--- uart_dev_ns8250.c (revision 222217)
+++ uart_dev_ns8250.c (working copy)
@@ -243,7 +243,7 @@
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
- if (val & 0xe0)
+ if (val & 0xa0)
return (ENXIO);

return (0);

Secondly, I'd like to know the vendor of the Quad-port UART. Either
it's Sunix's own implementation (this seems to be the case), or they
simply OEM someone else's. In any case: I'd like to see the datasheet
of the ASIC so as to understand the meaning/function of the bit.

FYI,
--
Marcel Moolenaar
***@xcllnt.net
N.J. Mann
2011-05-26 13:42:32 UTC
Permalink
Hi Marcel,
Post by Marcel Moolenaar
*snip*
Post by John Baldwin
Post by N.J. Mann
For the two devices that fail, ns8250_bus_probe() fails on the first
UART4
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
UART5
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
The value returned for the read of REG_MCR is 64, or 0x40, which causes
static int
ns8250_probe(struct uart_bas *bas)
{
u_char val;
/* Check known 0 bits that don't depend on DLAB. */
val = uart_getreg(bas, REG_IIR);
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
if (val & 0xe0)
return (ENXIO);
return (0);
}
Do you need to know the contents of 'bas'?
This goes beyond my level of knowledge. I've cc'd Marcel (author of uart) who
can hopefully help with this more.
The ns8250 family of UARTs typically have bits 5, 6 and 7 of the
MCR register reserved and thus hardwired to 0. The probe function
checks for that to make sure that the hardware looks enough like
a UART that we can claim it without hosing the box.
That said: newer chips in the family, like the ST16C850/XR16C850,
bit 5 - Xon-Any enable
bit 6 - Infrared enable
bit 7 - Clock pre-scaler
It's unclear to me whether those bits are consistently defined
across the different implementations (for some reason I think
not) and it's also unclear to me whether the device will work
correctly with FreeBSD if we simply ignore those bits (again I
don't think this is always the case).
I think the first order of business from an architectural point
of view is to determine how much value register probing still has
on modern hardware. In the good old days, this was needed. If
we think it's not really needed anymore, then it makes sense to
loosen the grip so to speak.
For you, the first thing is to see whether the UART ports work
Index: uart_dev_ns8250.c
===================================================================
--- uart_dev_ns8250.c (revision 222217)
+++ uart_dev_ns8250.c (working copy)
@@ -243,7 +243,7 @@
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
- if (val & 0xe0)
+ if (val & 0xa0)
return (ENXIO);
return (0);
I tried this and the result is that ports 3 and 4 now attach okay.
However, the baud rate of these two is wrong. If I select 9600 they
actually send and receive at 1200, i.e. eight times slower. The speed
setting for the first two ports is correct. (I checked all four ports at
9600, 38400 and 115200.)

Here are the relevant lines from a verbose dmesg. The ns8250_ lines are
debug printf's I added, with the register contents in hex.

%%%%%
puc0: <Timedia technology 4 Port Serial> port 0xe000-0xe01f,0xe400-0xe40f irq 18 at device 10.0 on pci0
puc_config_timedia::PUC_CFG_GET_NPORTS port=0 dev=1 id=1 res=4
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 0
ns8250_bus_probe:: exit
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = c1
ns8250_probe::uart_getreg REG_MCR = 8
ns8250_bus_probe:: exit
uart2: <16550 or compatible> on puc0
uart2: fast interrupt
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 0
ns8250_bus_probe:: exit
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = c1
ns8250_probe::uart_getreg REG_MCR = 8
ns8250_bus_probe:: exit
uart3: <16550 or compatible> on puc0
uart3: fast interrupt
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 40
ns8250_bus_probe:: exit
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 48
ns8250_bus_probe:: exit
uart4: <Non-standard ns8250 class UART with FIFOs> on puc0
uart4: fast interrupt
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 40
ns8250_bus_probe:: exit
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 48
ns8250_bus_probe:: exit
uart5: <Non-standard ns8250 class UART with FIFOs> on puc0
uart5: fast interrupt
%%%%%
Post by Marcel Moolenaar
Secondly, I'd like to know the vendor of the Quad-port UART. Either
it's Sunix's own implementation (this seems to be the case), or they
simply OEM someone else's. In any case: I'd like to see the datasheet
of the ASIC so as to understand the meaning/function of the bit.
I took the card out of the PC to see exactly what is on it. There are
three LSI chips, plus four RS-232 interface chips. The largest of the
LSI chips is a SUN1889 and it appears to connect to ports 1 and 2, and
to the PCI bus. The other two LSI chips are both SUN1699. The first of
these seems to be for port 3 and the second for port 4. I tried finding
data sheets for these chips on the web, but all I could find was
marketing leaflets for various single- and multi-port RS-232 and RS-422
interface cards. Perhaps you will have better luck in searching than I
did.

Best wishes.


Cheers,
Nick.
--
John Baldwin
2011-05-26 15:39:42 UTC
Permalink
Post by N.J. Mann
Hi Marcel,
Post by Marcel Moolenaar
*snip*
Post by John Baldwin
Post by N.J. Mann
For the two devices that fail, ns8250_bus_probe() fails on the first
UART4
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
UART5
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
The value returned for the read of REG_MCR is 64, or 0x40, which causes
static int
ns8250_probe(struct uart_bas *bas)
{
u_char val;
/* Check known 0 bits that don't depend on DLAB. */
val = uart_getreg(bas, REG_IIR);
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
if (val & 0xe0)
return (ENXIO);
return (0);
}
Do you need to know the contents of 'bas'?
This goes beyond my level of knowledge. I've cc'd Marcel (author of uart) who
can hopefully help with this more.
The ns8250 family of UARTs typically have bits 5, 6 and 7 of the
MCR register reserved and thus hardwired to 0. The probe function
checks for that to make sure that the hardware looks enough like
a UART that we can claim it without hosing the box.
That said: newer chips in the family, like the ST16C850/XR16C850,
bit 5 - Xon-Any enable
bit 6 - Infrared enable
bit 7 - Clock pre-scaler
It's unclear to me whether those bits are consistently defined
across the different implementations (for some reason I think
not) and it's also unclear to me whether the device will work
correctly with FreeBSD if we simply ignore those bits (again I
don't think this is always the case).
I think the first order of business from an architectural point
of view is to determine how much value register probing still has
on modern hardware. In the good old days, this was needed. If
we think it's not really needed anymore, then it makes sense to
loosen the grip so to speak.
For you, the first thing is to see whether the UART ports work
Index: uart_dev_ns8250.c
===================================================================
--- uart_dev_ns8250.c (revision 222217)
+++ uart_dev_ns8250.c (working copy)
@@ -243,7 +243,7 @@
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
- if (val & 0xe0)
+ if (val & 0xa0)
return (ENXIO);
return (0);
I tried this and the result is that ports 3 and 4 now attach okay.
However, the baud rate of these two is wrong. If I select 9600 they
actually send and receive at 1200, i.e. eight times slower. The speed
setting for the first two ports is correct. (I checked all four ports at
9600, 38400 and 115200.)
Ah, there are other reports of this:

http://lists.freebsd.org/pipermail/freebsd-stable/2010-April/056533.html

I think this patch should fix the timing issue:

Index: pucdata.c
===================================================================
--- pucdata.c (revision 222285)
+++ pucdata.c (working copy)
@@ -1292,6 +1292,12 @@ puc_config_timedia(struct puc_softc *sc, enum puc_
uint16_t subdev;

switch (cmd) {
+ case PUC_CFG_GET_CLOCK:
+ if (port < 2)
+ *res = DEFAULT_RCLK * 8;
+ else
+ *res = DEFAULT_RCLK;
+ return (0);
case PUC_CFG_GET_DESC:
snprintf(desc, sizeof(desc),
"Timedia technology %d Port Serial", (int)sc->sc_cfg_data);
--
John Baldwin
N.J. Mann
2011-05-26 20:22:47 UTC
Permalink
Post by John Baldwin
Post by N.J. Mann
Hi Marcel,
Post by Marcel Moolenaar
*snip*
Post by John Baldwin
Post by N.J. Mann
For the two devices that fail, ns8250_bus_probe() fails on the first
UART4
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
UART5
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
The value returned for the read of REG_MCR is 64, or 0x40, which causes
static int
ns8250_probe(struct uart_bas *bas)
{
u_char val;
/* Check known 0 bits that don't depend on DLAB. */
val = uart_getreg(bas, REG_IIR);
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
if (val & 0xe0)
return (ENXIO);
return (0);
}
Do you need to know the contents of 'bas'?
This goes beyond my level of knowledge. I've cc'd Marcel (author of
uart) who
Post by N.J. Mann
Post by Marcel Moolenaar
Post by John Baldwin
can hopefully help with this more.
The ns8250 family of UARTs typically have bits 5, 6 and 7 of the
MCR register reserved and thus hardwired to 0. The probe function
checks for that to make sure that the hardware looks enough like
a UART that we can claim it without hosing the box.
That said: newer chips in the family, like the ST16C850/XR16C850,
bit 5 - Xon-Any enable
bit 6 - Infrared enable
bit 7 - Clock pre-scaler
It's unclear to me whether those bits are consistently defined
across the different implementations (for some reason I think
not) and it's also unclear to me whether the device will work
correctly with FreeBSD if we simply ignore those bits (again I
don't think this is always the case).
I think the first order of business from an architectural point
of view is to determine how much value register probing still has
on modern hardware. In the good old days, this was needed. If
we think it's not really needed anymore, then it makes sense to
loosen the grip so to speak.
For you, the first thing is to see whether the UART ports work
Index: uart_dev_ns8250.c
===================================================================
--- uart_dev_ns8250.c (revision 222217)
+++ uart_dev_ns8250.c (working copy)
@@ -243,7 +243,7 @@
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
- if (val & 0xe0)
+ if (val & 0xa0)
return (ENXIO);
return (0);
I tried this and the result is that ports 3 and 4 now attach okay.
However, the baud rate of these two is wrong. If I select 9600 they
actually send and receive at 1200, i.e. eight times slower. The speed
setting for the first two ports is correct. (I checked all four ports at
9600, 38400 and 115200.)
http://lists.freebsd.org/pipermail/freebsd-stable/2010-April/056533.html
Index: pucdata.c
===================================================================
--- pucdata.c (revision 222285)
+++ pucdata.c (working copy)
@@ -1292,6 +1292,12 @@ puc_config_timedia(struct puc_softc *sc, enum puc_
uint16_t subdev;
switch (cmd) {
+ if (port < 2)
+ *res = DEFAULT_RCLK * 8;
+ else
+ *res = DEFAULT_RCLK;
+ return (0);
snprintf(desc, sizeof(desc),
"Timedia technology %d Port Serial", (int)sc->sc_cfg_data);
Yes, that fixed it. All ports are working correctly now.

Many thanks.


Cheers,
Nick.
--
Marcel Moolenaar
2011-05-26 16:36:32 UTC
Permalink
On May 26, 2011, at 6:42 AM, N.J. Mann wrote:

*snip*
Post by N.J. Mann
Post by Marcel Moolenaar
For you, the first thing is to see whether the UART ports work
Index: uart_dev_ns8250.c
===================================================================
--- uart_dev_ns8250.c (revision 222217)
+++ uart_dev_ns8250.c (working copy)
@@ -243,7 +243,7 @@
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
- if (val & 0xe0)
+ if (val & 0xa0)
return (ENXIO);
return (0);
I tried this and the result is that ports 3 and 4 now attach okay.
However, the baud rate of these two is wrong. If I select 9600 they
actually send and receive at 1200, i.e. eight times slower. The speed
setting for the first two ports is correct. (I checked all four ports at
9600, 38400 and 115200.)
See John's email for the baudrate issue.
Post by N.J. Mann
Post by Marcel Moolenaar
Secondly, I'd like to know the vendor of the Quad-port UART. Either
it's Sunix's own implementation (this seems to be the case), or they
simply OEM someone else's. In any case: I'd like to see the datasheet
of the ASIC so as to understand the meaning/function of the bit.
I took the card out of the PC to see exactly what is on it. There are
three LSI chips, plus four RS-232 interface chips. The largest of the
LSI chips is a SUN1889 and it appears to connect to ports 1 and 2, and
to the PCI bus. The other two LSI chips are both SUN1699. The first of
these seems to be for port 3 and the second for port 4. I tried finding
data sheets for these chips on the web, but all I could find was
marketing leaflets for various single- and multi-port RS-232 and RS-422
interface cards. Perhaps you will have better luck in searching than I
did.
Thanks! This what really useful. It seems that the SUN1699 has MCR
bit 6 set by default or it's even hardwired as 1. There have been
various reports on the FreeBSD mailing lists relating to the SUN1699
and how uart(4) doesn't attach due to the MCR having a value of 0x40.

Looking at the Sunix driver for Linux I cannot see any reference to
this bit at all. The code does not mask it out or force it to 1
either. So, from what I can tell, it has absolutely no meaning.

So, I'll change FreeBSD to just ignore this bit. There's even an open
PR for this:
http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/129663

Thanks a lot of working with us!
--
Marcel Moolenaar
***@xcllnt.net
N.J. Mann
2011-05-26 20:24:12 UTC
Permalink
Post by Marcel Moolenaar
*snip*
Post by N.J. Mann
Post by Marcel Moolenaar
For you, the first thing is to see whether the UART ports work
Index: uart_dev_ns8250.c
===================================================================
--- uart_dev_ns8250.c (revision 222217)
+++ uart_dev_ns8250.c (working copy)
@@ -243,7 +243,7 @@
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
- if (val & 0xe0)
+ if (val & 0xa0)
return (ENXIO);
return (0);
I tried this and the result is that ports 3 and 4 now attach okay.
However, the baud rate of these two is wrong. If I select 9600 they
actually send and receive at 1200, i.e. eight times slower. The speed
setting for the first two ports is correct. (I checked all four ports at
9600, 38400 and 115200.)
See John's email for the baudrate issue.
Post by N.J. Mann
Post by Marcel Moolenaar
Secondly, I'd like to know the vendor of the Quad-port UART. Either
it's Sunix's own implementation (this seems to be the case), or they
simply OEM someone else's. In any case: I'd like to see the datasheet
of the ASIC so as to understand the meaning/function of the bit.
I took the card out of the PC to see exactly what is on it. There are
three LSI chips, plus four RS-232 interface chips. The largest of the
LSI chips is a SUN1889 and it appears to connect to ports 1 and 2, and
to the PCI bus. The other two LSI chips are both SUN1699. The first of
these seems to be for port 3 and the second for port 4. I tried finding
data sheets for these chips on the web, but all I could find was
marketing leaflets for various single- and multi-port RS-232 and RS-422
interface cards. Perhaps you will have better luck in searching than I
did.
Thanks! This what really useful. It seems that the SUN1699 has MCR
bit 6 set by default or it's even hardwired as 1. There have been
various reports on the FreeBSD mailing lists relating to the SUN1699
and how uart(4) doesn't attach due to the MCR having a value of 0x40.
Looking at the Sunix driver for Linux I cannot see any reference to
this bit at all. The code does not mask it out or force it to 1
either. So, from what I can tell, it has absolutely no meaning.
So, I'll change FreeBSD to just ignore this bit. There's even an open
http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/129663
Thanks a lot of working with us!
John's latest patch has fixed the speed problem, so I now have a fully
working card.

%%%%%
puc0: <Timedia technology 4 Port Serial> port 0xdc00-0xdc1f,0xe000-0xe00f irq 17 at device 9.0 on pci0
ioapic0: routing intpin 17 (PCI IRQ 17) to lapic 0 vector 52
uart2: <16550 or compatible> on puc0
uart2: fast interrupt
uart3: <16550 or compatible> on puc0
uart3: fast interrupt
uart4: <16550 or compatible> on puc0
uart4: fast interrupt
uart5: <16550 or compatible> on puc0
uart5: fast interrupt
%%%%%

Many thanks.


Cheers,
Nick.
--

N.J. Mann
2011-05-26 13:12:52 UTC
Permalink
Hi John,
Post by John Baldwin
Post by N.J. Mann
[snip]
Post by John Baldwin
Ah, uart_puc_probe() always uses the 'uart_ns8250_class' uart driver which
is defined in uart_dev_ns8250.c. ns8250_bus_probe() is what you want to
instrument I think.
ns8250_bus_probe() is called twice for each of the working devices as
------
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 0
ns8250_bus_probe:: exit
...
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 193
ns8250_probe::uart_getreg REG_MCR = 8
ns8250_bus_probe:: exit
UART3
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 0
ns8250_bus_probe:: exit
...
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 193
ns8250_probe::uart_getreg REG_MCR = 8
ns8250_bus_probe:: exit
For the two devices that fail, ns8250_bus_probe() fails on the first
UART4
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
UART5
-----
ns8250_bus_probe:: entry
ns8250_probe::uart_getreg REG_IIR = 1
ns8250_probe::uart_getreg REG_MCR = 64
ns8250_bus_probe::ns8250_probe returned 6
The value returned for the read of REG_MCR is 64, or 0x40, which causes
static int
ns8250_probe(struct uart_bas *bas)
{
u_char val;
/* Check known 0 bits that don't depend on DLAB. */
val = uart_getreg(bas, REG_IIR);
if (val & 0x30)
return (ENXIO);
val = uart_getreg(bas, REG_MCR);
if (val & 0xe0)
return (ENXIO);
return (0);
}
Do you need to know the contents of 'bas'?
This goes beyond my level of knowledge. I've cc'd Marcel (author of uart) who
can hopefully help with this more.
Thank you for all your help. I now have all four ports working, but a
few things still need sorting out. I'll see if Marcel can help me.

Best wishes.


Cheers,
Nick.
--
Loading...