Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Nov 1998 12:00:02 -0800 (PST)
From:      myers@iname.com
To:        freebsd-hackers@FreeBSD.ORG
Subject:   Non-kernel hacker needs serial help!
Message-ID:  <199811252000.MAA01573@sol.>

next in thread | raw e-mail | index | archive | help


Folks:

Help a non-kernel hacker out here.  I've got an ancient HP DeskWriter
printer with a serial interface.  It came off a Macintosh.  Specs are
57.6K, 8N1.  Under Win98, I can make it print, but only after
manually specifying a slowed transfer rate from the UART (under
"Advanced Port Settings", or something like that).  However, I can't
make it print at all from my FreeBSD box.

Or rather, it will print, but only the first two inches or so of the
first page.  After that, it just hangs.

So, I speculate: Macs must have a non-standard H/W handshaking
protocol.  The FreeBSD box never sees a "buffer full" message from the
printer, so it blindly blasts out the bits, but the printer barfs on
them, and ends up flushing its buffer and giving up.  It only makes it
through two inches of output before dying.

My solution: introduce a delay into the serial port output stream, just
like Win98 lets me do.  I go kernel hacking.  I locate
/usr/src/sys/i386/isa/sio.c, find the function siointr1, and throw in
two DELAY(1000) statements, like this:

in function siointr1...


                        if (com->tx_fifo_size > 1) { 
                                u_int   ocount; 
 
                                ocount = com->obufq.l_tail - ioptr; 
                                if (ocount > com->tx_fifo_size) 
                                        ocount = com->tx_fifo_size; 
                                com->bytes_out += ocount; 
                                do { 
                                  outb(com->data_port, *ioptr++); 
                                /* dcm, 11/25/98 */ 
----->                            DELAY(1000); 
                                } while (--ocount != 0); 
                        } else { 
                                outb(com->data_port, *ioptr++); 
                                ++com->bytes_out; 
                                /* dcm, 11/25/98 */ 
----->                          DELAY(1000); 
                        } 



Why DELAY(1000)?  Who knows?  This is blind hacking!  But know what? 
It works!  Long documents now print out fine from my DeskWriter.  But,
those of you who *are* kernel hackers are probably snickering in the
background at the moment.  Unlike me, you realized that introducing a
delay at this point in the code (interrupt mode, I'm presuming) stalls
processing for everything else.  Network transfers, for example, become
annoyingly slow while this box is printing.

My question, to make a long story short: what is the "proper" way to
slow down the serial ports in the manner I've described, without bogging
down all other interrupt processing?

Thanks for reading this far.

-David.




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199811252000.MAA01573>