Re: Driver "Read" standard usage ('protocol')

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux