Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Oct 1997 13:20:54 -0700 (PDT)
From:      mdean <mdean@best.com>
To:        freebsd-hackers@freebsd.org
Subject:   Seeking suggestions on how read/write buffering should be handled for maximum generality.
Message-ID:  <Pine.SGI.3.95.971014125733.1726A-100000@shellx.best.com>

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

I have a digital I/O board, and I am in the middle of writing a driver for
it. I have a device node for each 8 bit i/o port and the direction (whether
output or input) is set by the O_ flags during open. The writes are not
buffered a simple outb() is excuted to set the lines. Similarily an inb()
will read the lines on a port, however it has a feature called change of
state where you get an interrupt any time an input changes. I let the user
enable or disable this for each of the six ports on the board through and
ioctl() but it is disabled by default.

How should I handle writes: 

If the user sends me a write with say 50 bytes, should I go ahead and just
spew it all out (through 50 outb()), for myself I would never send more
than 1 byte at a time, but there is not way to throttle output through the
8255 hardware in mode 0 (the only mode this board operates in).

Read routine handling is a bit more complicated, insofar: If a user asks
for one byte on a polled input port I give them whatever inb() reads right
then, If they ask for 50 should I just read it 50 times into my driver
buffer (1024 bytes) and then uiomove it to them, even though for most apps
I can think of all the bytes will always be the same.

What about for input ports set to interrupt input, when an interrupt is
received do an inb() and if the input has changed from last time it was
read put it in the buffer? This makes kind of sense.  When the user goes to
read an interrupt driven port should I block if there is nothing there, or
give them what inb() reads at that time. If so, then why should I even have
a buffer? If there is something there should I give them the buffer + 1
byte of what inb() reads right then?


These questions are not a matter of how to implement this all, but I just
want to get an idead of what someone other than me might want to use the
board for and what facillites they would want to have the driver implement.

I have also tried to think of ways to implement timed I/O, like a way to
throttle the writes using the system clock. Unfortunately everything I've
thought of would end up being in some way inflexible, It would be much
better to do such things from userspace.  One of my applications would be
to set a bit on a port to low wait 37ms and set it high, not a big problem
if implemented as a feature of the driver, but it makes it non-general. I
really think that usleep() should be reimplemented to actually sleep
something measurably close to the times it claims 40ms != 37ms when you
talking about something controlled that puts out quite amount of heat. If
you end up turning it on for 40ms when you only need 37ms in my case it
will eventually melt, wheras with 37ms it approach steady state heat
transfer where the controlled device is not having a meltdown. Were not
talking about doing something a lot of times per second, just that it is
timed accurately. Can i help this by aquiring a 1000hz timer in my driver
and using it to wakeup a rtprioed process sleeping on select(). I know for
instance that I can easily (I have done this) as part of the driver code
where I acuired timer0 at 10000hz without a noticeable increase in
interrupt %cpu. The whole problem with acquire_timer0() is that I am pretty
sure only one driver can hold onto the timer at a particular frequency at
one time, so If you need more than one to do things like this (which is
messy anyway and should be done in userspace, you're pretty much screwed).

Any suggestions?
I am not on the hackers mailing list --- please cc to me





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.SGI.3.95.971014125733.1726A-100000>