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>