Serial device driver msg blocks lost

Serial device driver msg blocks lost

Post by Hugh Swa » Mon, 17 May 1999 04:00:00

I am developing a driver for a multiport serial card under Solaris x86.
One of the integration tests is giving me a problem. The test involves
connecting two ports with a null-modem cable, cat'ing a test file out
to one port, cat'ing the other port to a receive file and then comparing
files. This works fine with hardware and software flow control at speeds
up to 115.2kbps, but sometimes at 230.4kbps and invariably at 460.8kbps
blocks of data are missing.

According to gathered stats, the tx port is sending the correct number
of chars. On the receive side, the correct number of chars are dumped
into a ring buffer at rx interrupt time and a polling function later
puts the correct number of chars into msg blocks and send them upstream.
Neither canput or putq (rq ) ever indicate any problem.

This happens with and without ldterm and ttcompat modules pushed.
Is it possible that the stream head is silently discarding msg blocks?
Any other advice?

"Boing" said Zebedee.


1. how to coordinate ioctl and block I/O requests in a block device driver

I am writing a block device driver with a raw (character device)
interface just as described in any book on Unix device driver
programming.  But unlike the examples in these books (and *like*
most real-life disk drivers), mine also has to do ioctls through
its raw device.  A couple of months ago I posted a question how
to coordinate, in this context the execution of ioctl requests
and of block read/write requests.

Meanwhile, I hit upon the source of a "real" disk driver which
solved the problem as follows:

In the ioctl function, it just stores its arguments in static
variables.  It then queues, through a call to the strategy routine,
a private static buf structure which exists for this sole purpose,
and finally does an iowait() on this buf.  Of course it makes sure
that any further ioctl calls are put to sleep until this special
buf is free again.

The start routine checks, for each buf it dequeues, whether its
address is that of this special buf.  If so, it executes the ioctl
function from the stored arguments and then calls iodone() on the
buf normally, waking up the process that called the ioctl function.

It seems to work, but I am not quite comfortable with it yet.
Is this how it is normally done?  Do you see any flaws in this
scheme?  Could iowait() and iodone() expect something in the buf
structure that the fake buf doesn't have, or do something to it
that will cause problems if the buf isn't a real one created by the
kernel or by physio()?  Could it create a problem that b_bcount is
zero if the ioctl function hasn't any data to transfer?  I once
noticed that iomap() panics if called for a buf with b_bcount==0,
which at the time seemed like an excessive reaction to me; but
iowait() and iodone() don't seem to mind.

Any comments welcome.


Tilman Schmidt                              Phone:  +49 221 8299 275
Sema Group Deutschland GmbH                 Fax:    +49 221 8299 266

2. net driver stuff (yet more)

3. Serial mouse only works during installation in graphics mode, problem with 'serial device driver'

4. FTP to NT Fails

5. lost blocks caused by full device

6. RAM disk size > 1.44 MB ?

7. Lost my /dev/hdb Block Special Device

8. RH6.0/pppd - unknown host: *

9. character device, block device , raw device?

10. Conflict between loop block device and serial mouse, help needed

11. Lost serial driver?

12. Losing Time with Device Driver

13. Device driver calling another device driver.