On 8/21/07, Erik Mouw <mouw@xxxxxxxxxxxx> wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > On Tue, Aug 21, 2007 at 03:35:21PM +0200, anon... anon.al wrote: > > Driver "Read" standard usage ('protocol') > > > > Concerning "read", I would like to ask if there are specific standard > > guidelines for using it, without bending it in a non-standard way: > > > > > > A driver controls a Hardware-device (HW-device) which makes "16-byte > > messages" available from time to time. If the HW-device has a "16-byte > > message" available, it signals this via interrupt, causing the driver's > > interrupt handler to load the message into the next slot in the driver's > > Ring-Buffer (from where applications can then get the message). > > > > _____________ > > |m1 |m2 | | - Ring-Buffer in driver > > ------------- > > > > Message m3 will be loaded into the last slot. > > Message m4 will overwrite m1. > > etc. > > > > Each message: 16 bytes > > > > > > 1) > > If an application calls "read(fd, buffer, len)" with len < 16 > > then "ssize_t read()" will return -EINVAL, since a message must have a > > multiple of 16 bytes. > > > > 2) BLOCKING: > > If an application calls "read(fd, buffer, len)" with len = 16, > > then the driver will run an instance of driver code ("ssize_t read()") on > > behalf of the application. If a "16-byte message" is available in the > > Ring-Buffer, it is delivered to the application and "ssize_t read()" returns > > 16. If no data is available in the Ring-Buffer, the instance will sleep > > until an interrupt signals that the HW-device has new data (16 bytes). That > > will cause the interrupt handler to load this 16-byte message to the next > > free slot in the Ring-Buffer. The interrupt handler will then wake the > > application's instance, so that it can deliver the message (from the > > Ring-Buffer Slot) to the application. "ssize_t read()" then returns 16. > > > > 3) > > If an application calls "read(fd, buffer, len)" with len = 32, > > then the "application's driver instance" will sleep until a "16-byte > > message" is available in the Ring-Buffer. Then the instance will deliver > > those 16 bytes to the application. > > > > If in the mean time, a second "16-byte message" has now become available, > > the instance delivers this 2nd "16-byte message" to the application and > > "ssize_t read()" returns 32. > > If however, no second "16-bytes message" is available, the instance notes > > that it has only provided 16 of 32 bytes (note "QQQ"- marker) and "ssize_t > > read()" returns 16. > > > > The application will then (like cat) call "read(fd, buffer, len)" again, > > with len = 16, to receive the remaining 16 bytes. If a new "16-byte message" > > is available, it is delivered to the application (then the note "QQQ" is > > removed) and "ssize_t read()" returns 16. > > OTHERWISE: If still no new data was available the INSTANCE DOES NOT SLEEP > > (since it has noted "QQQ") and "ssize_t read()" will (remove the note "QQQ") > > and then return 0. > > When read() returns 0 it has the special meaning that you reached the > end of file (see read(2)). You simply cannot return 0 without breaking > over 25 years of established Unix semantics. Am just beginning with this stuff, and you might be wondering "where am I coming from" with this stuff: -> If I use cat, on my driver, it expects 4096 bytes (on my machine), meaning it will block continuously until it has got all that data. But that is not what I want. I want to test my driver (I thought I'd use cat), and get back at least one message with cat's blocking read. Because in reality, the HW-device will never reach EOF, it will supply new messages until "the end of time". I don't want my cat to wait for ever... ... is my intuition correct, that cat is the wrong thing to use, for testing this driver... > > > The application then knows that no new data is available. Nonetheless, if > > the application still wants the next 16 bytes, it will start a new round, > > again calling "read(fd, buffer, len)" with len = 16, which will now cause > > the instance to block (note removed), until these 16 bytes are available. > > No, the applications now knows that there is no more data available and > exits. Yes, that is actually what I want(ed). In this point in time, the application has received at least one message and now there's no additional message left. (This may change in 5 seconds, if a new msg arrives) But I think I do see your point: I think I have to develop my own cat, which uses 2 flags: mycat --step=16 --num=32 mycat -s16 -n32 which uses 1 blocking read: "read(fd, buffer, len)", len = step = 16 followed by 1 nonblocking read: "read(fd, buffer, len)", len = 16 = (num-step) In other words: put the desired functionality into the application, and not code the driver for a specific application - cat. Hope this makes sense? [snip] > > If you don't want the application to block, implement ->poll in your > driver and let the application use select(). > I'll have a good look at poll and select. Thanks you -Albert -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ