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.
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.
4)
If an application calls "read(fd, buffer, len)" with len = 17,
then the instance will block until 16 bytes become are available - then the
instance will deliver the data to the application and "ssize_t read()" (will
note "QQQ" and) will returns 16.
The application (like cat) will now call "read(fd, buffer, len)" with len =
1.
In the instance, "ssize_t read()" will (remove the note) and return -EINVAL,
since a message must have a multiple of 16 bytes.
Is this a standard, correct behavior?
I would especially like to know about 3), where the driver notes "QQQ", so
that it knows that the application definitely has at least 16 bytes, and
that further read calls should NOT BLOCK.
Thanks,
Albert