Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problems with IOblix serial ports

13 views
Skip to first unread message

John Klos

unread,
May 18, 2010, 1:18:36 PM5/18/10
to
Hi,

I just got an IOblix four port serial and two port parallel card for my
Amiga, but I get a panic when I try to send the first character. I run cu,
press a key on the keyboard, and get:

uvm_fault(0x334350, 0x1518000, 0x1) -> 0xe
type 8, code [mmu,,ssw]: 1468200
trap type 8, code = 1468200, v = 1518000
pid = 520, lid = 1, pc = 01518000, ps = 2700, sfc = 1, dfc = 1
Registers:
0 1 2 3 4 5 6 7
dreg: 01518000 00000001 00000004 00000001 00006E7A 000033D4 00000000 00000000
areg: 01518000 0024AF20 00006C4A 0000699C 0000326C 0000335C 0BF8DC44 0DFFE7E0

Kernel stack (0BF8DACC):
F8DACC: 0029CF12 0BF8DBE0 00000080 0BF8DB50 0029D462 00000008 01468200 01518000
F8DAEC: 0BF8DBE0 0BD90070 00000000 00000000 00000000 00000000 00000001 00000000
F8DB0C: 00000000 00000000 00000001 00000000 00000000 00000008 00000000 00000000
F8DB2C: 00000000 00000000 0CA1D680 09DA4C40 00000001 01518000 00334350 0000000E
F8DB4C: 00000003 0BF8DBC8 0029DAEC 00000008 01468200 01518000 0BF8DBE0 0BED27E0
F8DB6C: 00000000 00000000 08216000 00000000 0000013A 0BED07E0 00000001 00000000
F8DB8C: 00000000 00000000 00000000 00000000 00000000 00000008 00000000 00000000
F8DBAC: 00000000 00000000 0BED27E0 0CA1D680 00000000 00000000 00000000 0BF8DC44
F8DBCC: 00002060 0BF8DBE0 00000008 01468200 01518000 01518000 00000001 00000004
F8DBEC: 00000001 00006E7A 000033D4 00000000 00000000 01518000 0024AF20 00006C4A
F8DC0C: 0000699C 0000326C 0000335C 0BF8DC44 0DFFE7E0 00000000 27000151 80004008
F8DC2C: 01518000 01468200 002675C8 09D70D80 09D70D80 00000000 0BF8DC70 00002378
F8DC4C: 09D70D80 09D70DD4 00002410 00002700 003484B8 0024AF98 24100009 1CF60078
F8DC6C: 00002000 0BF8DC9C 00093628 00002410 00000000 00000001 0B0A2F18 0B0A2F50
F8DC8C: 00002410 00CB5400 00000001 00000001 0BF8DCA8 001DA73E 0B0A30C0 0BF8DD40
F8DCAC: 001DB698 0B0A30C0 0000000C 00000001 00000000 0D000000 0820C000 0BF8A000
panic: MMU fault
Begin traceback...
?(?)
panic(2ec86a,bf8db50,29d462,8,1468200) at 0
panictrap(8,1468200,1518000,bf8dbe0) + 72
trapmmufault(8,1468200,1518000,bf8dbe0,bed27e0,0,0) + 4a6
trap(bf8dbe0,8,1468200,1518000) + 5ba
_prop_dictionary_keysym32_pool(9d70d80) + 11cec98
lev6intr(?)
_spl(2410) + 74
comstart(b0a30c0) + 23a
ttstart(b0a30c0) + 1c
ttwrite(b0a30c0,bf8de80,10) + 45e
comwrite(2000,bf8de80,10) + 9c
cdev_write(2000,bf8de80,10) + 4c
spec_write(bf8de0c) + 76
ufsspec_write(bf8de0c) + 66
VOP_WRITE(bee6338,bf8de80,10,9d898fc) + 56
vn_write(b981b40,b981b40,bf8de80,9d898fc,1) + 114
dofilewrite(3,b981b40,dffe833,1,b981b40,1,bf8df18) + 7e
sys_write(bed27e0,bf8df20,bf8df18) + 7e
sy_call(2f990c,bed27e0,bf8df20,bf8df18) + 22
syscall_plain(4,bed27e0,bf8dfb4) + 112
syscall(4) + 11c
trap0() + e
End traceback...

I tried this with a GENERIC NetBSD 5 kernel, too, and there was no
change, and I also made sure I had IOBZCLOCK=24000000 in my kernel config
because I have an older board.

Any ideas? Is anyone else using an IOblix nowadays?

Thanks,
John Klos

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-...@muc.de

Frank Wille

unread,
May 18, 2010, 4:04:51 PM5/18/10
to
John Klos wrote:

> I just got an IOblix four port serial and two port parallel card for my
> Amiga, but I get a panic when I try to send the first character. I run
> cu, press a key on the keyboard, and get:
>
> uvm_fault(0x334350, 0x1518000, 0x1) -> 0xe
> type 8, code [mmu,,ssw]: 1468200
> trap type 8, code = 1468200, v = 1518000
> pid = 520, lid = 1, pc = 01518000, ps = 2700, sfc = 1, dfc = 1
> Registers:
> 0 1 2 3 4 5 6
> 7 dreg: 01518000 00000001 00000004 00000001
> 00006E7A 000033D4 00000000 00000000 areg: 01518000 0024AF20 00006C4A
> 0000699C 0000326C 0000335C 0BF8DC44 0DFFE7E0

I'm not that familiar with the output generated by the amiga port, but by
looking at the source it seems like the kernel tried to execute an
instruction at 0x01518000, ran into a MMU-exception, and uvm failed to map
a page for this address.

I guess this address is completely illegal, but to be honest I'm not sure
which address space the kernel is using. I remember that user programs
start at 0x2000, folllowed by the heap, shared objects are loaded from
0x08000000 on and the stack grows downwards from 0x0e000000.


> MMU fault Begin traceback...
> ?(?)
> panic(2ec86a,bf8db50,29d462,8,1468200) at 0
> panictrap(8,1468200,1518000,bf8dbe0) + 72
> trapmmufault(8,1468200,1518000,bf8dbe0,bed27e0,0,0) + 4a6
> trap(bf8dbe0,8,1468200,1518000) + 5ba
> _prop_dictionary_keysym32_pool(9d70d80) + 11cec98
> lev6intr(?)

It happened probably during a level 6 interrupt, caused by your IOblix card.
Those a standard ns8250/16550-compatible com(4) ports, which means that
comintr() from dev/ic/com.c would be called immediately, which certainly
doesn't have a major problem.

_prop_dictionary_keysym32_pool is not a function, but a common symbol,
AFAIK. Don't know whether the stack frame can be trusted here.


> I tried this with a GENERIC NetBSD 5 kernel, too, and there was no
> change, and I also made sure I had IOBZCLOCK=24000000 in my kernel
> config because I have an older board.

Any chance to test a much older kernel, like NetBSD 4 or 3?

(I always have a bad consience when any Amiga/68k bug pops up, because of my
amigappc modifications ;)


> Any ideas? Is anyone else using an IOblix nowadays?

I have never seen one. I have a MFC2 lying around, but it worked last time I
checked.

I assume the bug is reproduceable? Does it happen with any of the four
serial ports, but not with the internal ser(4)?

In any case such a bug will be hard to fix without the hardware.
When you have the time to debug it, you should enter some printf() into
comintr() to understand what happens and to locate the crash.

--
Frank Wille

John Klos

unread,
May 18, 2010, 7:09:40 PM5/18/10
to
Hello,

> It happened probably during a level 6 interrupt, caused by your IOblix card.
> Those a standard ns8250/16550-compatible com(4) ports, which means that
> comintr() from dev/ic/com.c would be called immediately, which certainly
> doesn't have a major problem.

Now for strangeness... I added a simple printf in the beginning of
the comintr routine in com.c, as you suggested, and it doesn't panic now.
I removed it, made a new kernel, got a panic... Strange...

The built-in serial port works fine, as that's what I'm using for the
console right now. Also, this card is replacing a Multiface card, so I
know the mfc ports work fine. I just wanted more ports.

Some more testing shows that a really short printf around line 1864 (after
(if (COM_ISALIVE(sc) == 0)) doesn't affect anything (it still panics on
the first character), but a longer printf allows the use of the port for a
little while. I'm just pressing on the keyboard, so I'd guess it's just
changing the timing a little, and I'd guess that any sort of full-speed
serial usage would be much faster than my keyboard repeat rate.

Does anyone have any clue why a printf in that area changes things? A
delay() doesn't...

John

John Klos

unread,
May 18, 2010, 8:04:16 PM5/18/10
to
Hi,

One part of the problem turned out to be the lpt port(s). My card only has
one lpt chip (78C36; the second one is an option on these boards), but the
kernel was configuring two lpt ports:

lpt0 at iobl0 port 0x0200 ipl 6
lpt1 at iobl0 port 0x0300 ipl 6

with lpt0 in the kernel config instead of lpt*, it still paniced when I
tried to use the com ports, but with neither lpt0 nor lpt*, the com ports
work fine, so I assume that there's a problem with the lpt port driver. I
wouldn't have any way to test an lpt port, anyhow.

Any ideas?

Thanks,
John

Frank Wille

unread,
May 20, 2010, 2:31:25 PM5/20/10
to
John Klos wrote:

> One part of the problem turned out to be the lpt port(s). My card only
> has one lpt chip (78C36; the second one is an option on these boards),
> but the kernel was configuring two lpt ports:
>
> lpt0 at iobl0 port 0x0200 ipl 6
> lpt1 at iobl0 port 0x0300 ipl 6
>
> with lpt0 in the kernel config instead of lpt*, it still paniced when I
> tried to use the com ports, but with neither lpt0 nor lpt*, the com
> ports work fine, so I assume that there's a problem with the lpt port
> driver.

All IOblix devices, the com ports and the lpt ports install a level 6
insterrupt handler. So when you get an interrupt from one of your com ports
all handlers (4 x comintr() and 2 x lptintr()) might be called until the
first confirmed having handled the interrupt.

Which means when the lpt-handlers are before the com-handlers in the isr
queue, they will be called first and might cause a crash when something bad
happens (ok, this doesn't explain your success with printf in comintr).


> I wouldn't have any way to test an lpt port, anyhow.

I guess nobody ever tested it. I found a message from Ignatios in the
cvs-log where he wrote that IOblix lpt is untested. But I think he tested
the serial port without panics.


> Any ideas?

You could continue to explore the problem in two directions:

- Debug lptintr(). Although not used, the lptintr() will probably be called
on each level 6 interrupt.

- Revert busfuncs.c to 1.10, simple_busfuncs.c to 1.5 and
amiga_bus_simple_4.c to 1.5. This will make sure I didn't introduce a bug
there.

--
Frank Wille

Michael L. Hitch

unread,
May 20, 2010, 2:58:20 PM5/20/10
to
On Thu, 20 May 2010, Frank Wille wrote:

> All IOblix devices, the com ports and the lpt ports install a level 6
> insterrupt handler. So when you get an interrupt from one of your com ports
> all handlers (4 x comintr() and 2 x lptintr()) might be called until the
> first confirmed having handled the interrupt.
>
> Which means when the lpt-handlers are before the com-handlers in the isr
> queue, they will be called first and might cause a crash when something bad
> happens (ok, this doesn't explain your success with printf in comintr).
>
>
>> I wouldn't have any way to test an lpt port, anyhow.
>
> I guess nobody ever tested it. I found a message from Ignatios in the
> cvs-log where he wrote that IOblix lpt is untested. But I think he tested
> the serial port without panics.
>
>
>> Any ideas?

I see one possibility...

ioblix_zbus.c() sets supa.supio_arg = iobzclock before configuring the
attached devices. Then lpt_supio.c sets sc->sc_intack = (void
*)supa->supio_arg when the lpt device is attached. The interrupt routine
does:
if (sc->sc_intack)
(*sc->sc_intack)(p);

Oops...

--
Michael L. Hitch mhi...@montana.edu
Computer Consultant
Information Technology Center
Montana State University Bozeman, MT USA

Frank Wille

unread,
May 20, 2010, 4:32:34 PM5/20/10
to
On Thu, 20 May 2010 12:58:20 -0600 (MDT)
"Michael L. Hitch" <mhi...@lightning.msu.montana.edu> wrote:

> ioblix_zbus.c() sets supa.supio_arg = iobzclock before configuring the
> attached devices. Then lpt_supio.c sets sc->sc_intack = (void
> *)supa->supio_arg when the lpt device is attached. The interrupt routine
> does:
> if (sc->sc_intack)
> (*sc->sc_intack)(p);
>
> Oops...

Uh yes, you're absolutely right! Just a few hours ago I wondered about
the same line, but then I thought: "no danger, because iobzd->arg is
0 for the lpt board". But in reality always IOBZCLOCK is assigned! :P

That perfactly explains the panic with lpt!

Michael L. Hitch

unread,
May 20, 2010, 4:41:44 PM5/20/10
to
On Thu, 20 May 2010, Frank Wille wrote:

> Uh yes, you're absolutely right! Just a few hours ago I wondered about
> the same line, but then I thought: "no danger, because iobzd->arg is
> 0 for the lpt board". But in reality always IOBZCLOCK is assigned! :P
>
> That perfactly explains the panic with lpt!

I've done some decoding of the stack dump in the original messages, and
it seems to match up extremely close to that call in lpt_supio_intr().

I think a fix would be to conditionally set supio_arg based on
iobzd->arg (i.e. set supio_arg to 0 if iobzd->arg is 0, othersize set it
to the clock value).

--
Michael L. Hitch mhi...@montana.edu
Computer Consultant
Information Technology Center
Montana State University Bozeman, MT USA

--

Frank Wille

unread,
May 21, 2010, 3:36:40 AM5/21/10
to
On Thu, 20 May 2010 14:41:44 -0600 (MDT)

"Michael L. Hitch" <mhi...@lightning.msu.montana.edu> wrote:

> [...]


> I think a fix would be to conditionally set supio_arg based on
> iobzd->arg (i.e. set supio_arg to 0 if iobzd->arg is 0, othersize set
> it to the clock value).

Yes. Maybe John wants to try it? When the following patch works, somebody
can commit it:

--- ioblix_zbus.c 2 Feb 2010 19:03:31 -0000 1.15
+++ ioblix_zbus.c 21 May 2010 07:32:33 -0000
@@ -130,7 +130,7 @@
while (iobzd->name) {
supa.supio_name = iobzd->name;
supa.supio_iobase = iobzd->off;
- supa.supio_arg = iobzclock /* XXX iobzd->arg */;
+ supa.supio_arg = iobzd->arg ? iobzclock : 0 /* XXX iobzd->arg */;
config_found(self, &supa, iobzprint); /* XXX */
++iobzd;

John Klos

unread,
May 21, 2010, 1:26:17 PM5/21/10
to
Hi,

> Yes. Maybe John wants to try it? When the following patch works, somebody
> can commit it:
>
> --- ioblix_zbus.c 2 Feb 2010 19:03:31 -0000 1.15
> +++ ioblix_zbus.c 21 May 2010 07:32:33 -0000
> @@ -130,7 +130,7 @@
> while (iobzd->name) {
> supa.supio_name = iobzd->name;
> supa.supio_iobase = iobzd->off;
> - supa.supio_arg = iobzclock /* XXX iobzd->arg */;
> + supa.supio_arg = iobzd->arg ? iobzclock : 0 /* XXX iobzd->arg */;
> config_found(self, &supa, iobzprint); /* XXX */
> ++iobzd;

Thank you, Frank. I'll test it, hopefully later today, and if everything
works, I'll commit it.

John
--
Those who profess to favor freedom, and yet deprecate agitation, are
pmen who want rain without thunder and lightning. They want the ocean
without the roar of its many waters.
-- Frederick Douglass

John Klos

unread,
May 24, 2010, 3:24:59 AM5/24/10
to
>> - supa.supio_arg = iobzclock /* XXX iobzd->arg */;
>> + supa.supio_arg = iobzd->arg ? iobzclock : 0 /* XXX
>> iobzd->arg */;

That fixes one problem. However, another is that the baud rates aren't
calculated properly. I had set IOBZCLOCK=24000000 in the kernel
configuration file, but for some reason I had to manually change it in
ioblix_zbus.c for it to work properly. Then, the baud rate set had to be
four times the desired baud rate - to communicate with another 9600 baud
port I had to set the baud to 38400.

I'll have to look at that tomorrow.

Thanks,
John

Frank Wille

unread,
May 25, 2010, 5:59:55 AM5/25/10
to
John Klos wrote:

> That fixes one problem. However, another is that the baud rates aren't
> calculated properly. I had set IOBZCLOCK=24000000 in the kernel
> configuration file, but for some reason I had to manually change it in
> ioblix_zbus.c for it to work properly.

There is an

#include "opt_iobzclock.h"

missing, in ioblix_zbus.c. This header file contains your IOBZCLOCK define.
So if you commit the changes, please include this line.


> Then, the baud rate set had to
> be four times the desired baud rate - to communicate with another 9600
> baud port I had to set the baud to 38400.

And this problem was still present after you had set IOBZCLOCK directly in
ioblix_zbus.c ?

--
_ Frank Wille (fr...@phoenix.owl.de)
_ // http://sun.hasenbraten.de/~frank/
\X/ Phx @ #AmigaGer

John Klos

unread,
May 25, 2010, 1:19:54 PM5/25/10
to
> There is an
>
> #include "opt_iobzclock.h"
>
> missing, in ioblix_zbus.c. This header file contains your IOBZCLOCK define.
> So if you commit the changes, please include this line.

Ah, makes sense.

>> Then, the baud rate set had to
>> be four times the desired baud rate - to communicate with another 9600
>> baud port I had to set the baud to 38400.
>
> And this problem was still present after you had set IOBZCLOCK directly in
> ioblix_zbus.c ?

Yes. Before setting it, I couldn't get any meaningful characters across
the serial link because, I'm assuming, the baud rate wasn't correct.

Thanks,
John

Frank Wille

unread,
May 25, 2010, 2:17:59 PM5/25/10
to
John Klos wrote:

>>> [...] to communicate with another


>>> 9600 baud port I had to set the baud to 38400.
>>
>> And this problem was still present after you had set IOBZCLOCK
>> directly in ioblix_zbus.c ?
>
> Yes. Before setting it, I couldn't get any meaningful characters across
> the serial link because, I'm assuming, the baud rate wasn't correct.

When 24000000 gives you a factor 4, what happens when you set IOBZCLOCK to
6000000?

--
Frank Wille

John Klos

unread,
May 25, 2010, 3:15:43 PM5/25/10
to
> When 24000000 gives you a factor 4, what happens when you set IOBZCLOCK to
> 6000000?

That's exactly what I was planning to try when I put the board back in...
I'll post back shortly.

Thanks,
John

John Klos

unread,
May 25, 2010, 5:41:47 PM5/25/10
to
> When 24000000 gives you a factor 4, what happens when you set IOBZCLOCK to
> 6000000?

With the clock set to 6000000, I get:

reva: {2} cu -f -s 115200 -l /dev/ttyC0
cu: unsupported speed 115200
reva: {3} cu -f -s 57600 -l /dev/ttyC0
cu: unsupported speed 57600
reva: {4} cu -f -s 38400 -l /dev/ttyC0
Connected
?????????????????????????????????????????????????????????????????

I tried every baud rate on the other end from 300 baud to 230400, and I
just got question marks or nothing.

Hmmm...

John

John Klos

unread,
May 25, 2010, 6:16:56 PM5/25/10
to
Followup: 38400 baud on the IOblix port works with 9600 on the other end,
as do any lower baud rates (tried 19200, 9600, 4800 and 1200), but 57600
and 115200 don't work.

I suppose I'll have to use the A2232 for 115200.

Patrick made these nice division tables. Perhaps someone can explain how
we're getting some of these baud rates from a 24 MHz oscillator? Or is
9615 baud close enough to 9600 that it doesn't matter much?

I can see why the 22.1184 MHz oscillator is preferred...

Crystal at 24.000000MHz
300 5000 0.00%
600 2500 0.00%
1200 1250 0.00%
2400 625 0.00%
4800 312 50.00%
7200 208 33.33%
9600 156 25.00%
14400 104 16.66%
19200 78 12.50%
28800 52 8.33%
38400 39 6.25%
57600 26 4.16%
76800 19 53.12%
115200 13 2.08%
230400 6 51.04%
460800 3 25.52%
921600 1 16.15%

Crystal at 22.118400MHz
300 4608 0.00%
600 2304 0.00%
1200 1152 0.00%
2400 576 0.00%
4800 288 0.00%
7200 192 0.00%
9600 144 0.00%
14400 96 0.00%
19200 72 0.00%
28800 48 0.00%
38400 36 0.00%
57600 24 0.00%
76800 18 0.00%
115200 12 0.00%
230400 6 0.00%
460800 3 0.00%
921600 1 3.39%

Thanks,

Frank Wille

unread,
May 26, 2010, 8:32:41 AM5/26/10
to
On Tue, 25 May 2010 22:16:56 +0000 (UTC)
John Klos <jo...@klos.com> wrote:

> Followup: 38400 baud on the IOblix port works with 9600 on the other
> end, as do any lower baud rates (tried 19200, 9600, 4800 and 1200),
> but 57600 and 115200 don't work.

That's a strange problem indeed, so I collected some information about
the IOBlix board.

It uses a ST16C654 chip for the serial ports and I downloaded the
datasheet for it. Maybe it is not 100% compatible to our MI com(4) driver?

So you might try to add
options COM_16650
to your config file, to improve things (which should be included in the
GENERIC file, when it really helps). I'm not absolutely sure about this,
but from the com.c source it seems that most(all?) 16650 functions are
supported by the 16C654.

There is a very interesting feature I found in the datasheet:

The ST16C654 has a built-in clock-divider function, which divides the
output baud rate either by 1 or by 4 (!). Sounds familiar? ;)
It is contolled by bit 7 of the MCR register, which seems unused in com(4),
as far as I could see.

After a reset this bit should be zero, which means divide by 1. But
something in your system (maybe com(4)?) sets it to 1, enabling divide by 4.

Setting MCR-bit7 could be correct, because when not dividing by 4 some
important baud rates are not available:

MCR Bit7=1 Bit7=0
50 200
300 1200
600 2400
1200 4800
2400 9600
4800 19.2K
9600 38.4k
19.2k 76.8k
38.4k 153.6k
57.6k 230.4k
115.2k 460.8k

So the error seems to be that com(4) doesn't take the 16654-specific
clock-divider into account, while calculating the clock for the baud
rate you have set. That could be fixed in comspeed().

A simple solution would be to reset the bit to zero, but then you won't
get 115200 neither, according to the table above.

For a clean solution com(4) should be able to detect a 16654 first, but I
don't know how to do it. Are there any differences to detect? In the worst
case we have to create a new option, like COM_16654.

Maybe you want to make some experiments first? Print/reset this bit at
various places? Test with a factor 4 in comspeed(). Then we could even
move this discussion to a MI list, like tech-kern or tech-misc?


> Patrick made these nice division tables. Perhaps someone can explain
> how we're getting some of these baud rates from a 24 MHz oscillator?
> Or is 9615 baud close enough to 9600 that it doesn't matter much?

That's a tolerance below 2%, not 25% as in your first table (or I
misunderstood something).

The com(4) driver accepts tolerances up to 3% (COM_TOLERANCE). So this
should be safe.

--
Frank Wille

Bernd Ernesti

unread,
May 26, 2010, 1:54:19 PM5/26/10
to
On Wed, May 26, 2010 at 02:32:41PM +0200, Frank Wille wrote:
> On Tue, 25 May 2010 22:16:56 +0000 (UTC)
> John Klos <jo...@klos.com> wrote:
>
> > Followup: 38400 baud on the IOblix port works with 9600 on the other
> > end, as do any lower baud rates (tried 19200, 9600, 4800 and 1200),
> > but 57600 and 115200 don't work.
>
> That's a strange problem indeed, so I collected some information about
> the IOBlix board.
>
> It uses a ST16C654 chip for the serial ports and I downloaded the
> datasheet for it. Maybe it is not 100% compatible to our MI com(4) driver?

There was a mail in March from KIYOHARA Takashi about 115200 support for com(4):
http://mail-index.netbsd.org/current-users/2010/03/01/msg012772.html

It was mainly for the 16950.

Bernd

John Klos

unread,
May 26, 2010, 5:04:26 PM5/26/10
to
> So you might try to add
> options COM_16650
> to your config file, to improve things (which should be included in the
> GENERIC file, when it really helps). I'm not absolutely sure about this,
> but from the com.c source it seems that most(all?) 16650 functions are
> supported by the 16C654.

I've added this, but didn't see any changes. It was pointed out to me by a
different brother that the 16C654 should be considered distinct:

"DON'T use the 16550 datasheet to determine the characteristics for the
16550 as applying to the 16654. The 550 is a National Semiconductor part
and copied by dozens of companies. The 1665x is a Startec/Exar part,
copied by only a few companies. It is a much newer part and probably
faster."

In com.c it's mentioned that there are other features (such as automatic
hardware flow control) on the StarTech versions and that the National
Semiconductor part is handled differently in several respects as compared
with the StarTech. I did notice that the GENERIC kernel shows:

com0 at iobl0 port 0x0108 ipl 6: ns16650a, working fifo
...

whereas the new kernel with COM_16650 shows:

com0 at iobl0 port 0x0108 ipl 6: st16650a, working fifo
...

Is MCR-bit7 per port, or is it set for the entire chip?

> For a clean solution com(4) should be able to detect a 16654 first, but I
> don't know how to do it. Are there any differences to detect? In the worst
> case we have to create a new option, like COM_16654.

In the case of the IOblix, we could always assume 16654. Patrick or Mike -
what do you recommend regarding detecting a 16654 as compared with a
16550?

> Maybe you want to make some experiments first? Print/reset this bit at
> various places? Test with a factor 4 in comspeed(). Then we could even
> move this discussion to a MI list, like tech-kern or tech-misc?

Will do.

>> Patrick made these nice division tables. Perhaps someone can explain
>> how we're getting some of these baud rates from a 24 MHz oscillator?
>> Or is 9615 baud close enough to 9600 that it doesn't matter much?
>

> That's a tolerance below 2%, not 25% as in your first table (or I
> misunderstood something).

The percentages were the amount of remainder left.

> The com(4) driver accepts tolerances up to 3% (COM_TOLERANCE). So this
> should be safe.

Gotcha.

Thanks very much! I'll report back when I've done a few more tests.

Frank Wille

unread,
May 27, 2010, 6:29:05 AM5/27/10
to
On Wed, 26 May 2010 21:04:26 +0000 (UTC)
John Klos <jo...@ziaspace.com> wrote:

> > So you might try to add
> > options COM_16650
> > to your config file, to improve things (which should be included in
> > the GENERIC file, when it really helps). I'm not absolutely sure
> > about this, but from the com.c source it seems that most(all?)
> > 16650 functions are supported by the 16C654.
>

> I've added this, but didn't see any changes.

Probably the 16650 support is currently broken.


> It was pointed out to me
> by a different brother that the 16C654 should be considered distinct:
>
> "DON'T use the 16550 datasheet to determine the characteristics for
> the 16550 as applying to the 16654.

That's correct. So defining COM_16650 is the right thing to do. Maybe
it needs some additional fixes.


> In com.c it's mentioned that there are other features (such as
> automatic hardware flow control) on the StarTech versions and that
> the National Semiconductor part is handled differently in several
> respects as compared with the StarTech.

Indeed.

Bernd Ernesti pointed to a relevant thread from Takashi Kiyohara where
he probably fixed a bug with 16650 hardware flow control. He also
multiplied the sc_frequency by 4 (although in the wrong case as it
seems?), which will match the hardware prescaler (MCR bit 7).


> Is MCR-bit7 per port, or is it set for the entire chip?

It's per port. The MCR register belongs to the 8 byte register set which
is the same for each port.


> > For a clean solution com(4) should be able to detect a 16654 first,
> > but I don't know how to do it. Are there any differences to detect?
> > In the worst case we have to create a new option, like COM_16654.
>

> In the case of the IOblix, we could always assume 16654. Patrick or
> Mike - what do you recommend regarding detecting a 16654 as compared
> with a 16550?

I have downloaded an Exar ST16650 PDF and I'm quite sure that all chips
of the ST1665x series have an identical register layout (also the same
32-byte FIFO and hardware flow control).

So we only have to fix COM_16650.


> Thanks very much! I'll report back when I've done a few more tests.

Thanks. You may want to try the following patch:

Index: comreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/comreg.h,v
retrieving revision 1.15
diff -u -r1.15 comreg.h
--- comreg.h 28 Apr 2008 22:00:01 -0000 1.15
+++ comreg.h 27 May 2010 10:22:41 -0000
@@ -98,6 +98,7 @@
#define LCR_5BITS 0x00 /* 5 bits */

/* modem control register */
+#define MCR_PRESCALE 0x80 /* 16650/16950: Baud rate prescaler select */
#define MCR_TCR_TLR 0x40 /* OMAP: enables access to the TCR & TLR regs */
#define MCR_XONENABLE 0x20 /* OMAP XON_EN */
#define MCR_LOOPBACK 0x10 /* Loop test: echos from TX to RX */
Index: com.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/com.c,v
retrieving revision 1.297
diff -u -r1.297 com.c
--- com.c 19 Apr 2010 18:24:26 -0000 1.297
+++ com.c 27 May 2010 10:23:03 -0000
@@ -465,6 +465,8 @@
sc->sc_fifolen = 0;
} else {
SET(sc->sc_hwflags, COM_HW_FLOW);
+ SET(sc->sc_mcr, MCR_PRESCALE);
+ sc->sc_frequency *= 4;
sc->sc_fifolen = 32;
}
} else
@@ -1477,8 +1479,8 @@
KASSERT(sc->sc_type != COM_TYPE_AU1x00);
KASSERT(sc->sc_type != COM_TYPE_16550_NOERS);
/* no EFR on alchemy */
- CSR_WRITE_1(regsp, COM_REG_EFR, sc->sc_efr);
CSR_WRITE_1(regsp, COM_REG_LCR, LCR_EERS);
+ CSR_WRITE_1(regsp, COM_REG_EFR, sc->sc_efr);
}
if (sc->sc_type == COM_TYPE_AU1x00) {
/* alchemy has single separate 16-bit clock divisor register */


--
Frank Wille

Frank Wille

unread,
May 27, 2010, 4:09:38 PM5/27/10
to
Bernd Ernesti wrote:

> There was a mail in March from KIYOHARA Takashi about 115200 support
> for com(4):
http://mail-index.netbsd.org/current-users/2010/03/01/msg012772.html
>
> It was mainly for the 16950.

It also contains at least one fix for the 16650 (hardware flow-control), as
far as I could see. Why didn't he ever commit that?

--
Frank Wille

Bernd Ernesti

unread,
May 27, 2010, 4:36:29 PM5/27/10
to
On Thu, May 27, 2010 at 10:09:38PM +0200, Frank Wille wrote:
> Bernd Ernesti wrote:
>
> > There was a mail in March from KIYOHARA Takashi about 115200 support
> > for com(4):
> http://mail-index.netbsd.org/current-users/2010/03/01/msg012772.html
> >
> > It was mainly for the 16950.
>
> It also contains at least one fix for the 16650 (hardware flow-control), as
> far as I could see. Why didn't he ever commit that?

You have to ask him.
I wanted to test it on my PCIe card but had not time for it.

Bernd

P.S. Please respect a Mail-Followup-To header.

John Klos

unread,
May 28, 2010, 2:43:40 PM5/28/10
to

Thank you, Frank. This didn't work as is; it seems that we want to
divide sc_frequency by four, not multiply by four (we set 38400, we get
9600), so changing the *= to /= made it work.

Next...

cu: unsupported speed 230400
reva: {4} cu -f -l /dev/ttyC0 -s 115200
cu: unsupported speed 115200
reva: {5} cu -f -l /dev/ttyC0 -s 57600
cu: unsupported speed 57600

Thanks!

Frank Wille

unread,
May 28, 2010, 7:16:24 PM5/28/10
to
On Fri, 28 May 2010 18:43:40 +0000 (UTC)
John Klos <jo...@ziaspace.com> wrote:

> Thank you, Frank. This didn't work as is; it seems that we want to
> divide sc_frequency by four, not multiply by four (we set 38400, we get
> 9600), so changing the *= to /= made it work.

Ah, yes! My fault.


> Next...
>
> cu: unsupported speed 230400

According to the datasheet you cannot use anything higher than 115200
when the prescaler is enabled. But maybe the table is only valid for
a specific clock rate (7.3728 MHz was mentioned there). I'm not sure...


> reva: {4} cu -f -l /dev/ttyC0 -s 115200

> cu: unsupported speed 115200


> reva: {5} cu -f -l /dev/ttyC0 -s 57600
> cu: unsupported speed 57600

I guess your 24 MHz clock exceeds the 3% tolerance for these speeds.
You can print the calculated deviation (err) in the comspeed() function
of dev/ic/com.c, just before this line:
if (err > COM_TOLERANCE)

Your last option might be to disable the prescaler...
CLR(sc->sc_mcr, MCR_PRESCALE);
CSR_WRITE_1(regsp, COM_REG_MCR, sc->sc_mcr);
...and remove the sc->sc_frequency /= 4 again, and see if there are more
useful baud rates in range.

--
Frank Wille

0 new messages