Document d_poll() and d_select().
This commit is contained in:
parent
8be4630691
commit
082f0d19a9
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=2942
2 changed files with 190 additions and 4 deletions
|
|
@ -6,7 +6,7 @@
|
||||||
++
|
++
|
||||||
++ Copyright Eric L. Hernes - Wednesday, August 2, 1995
|
++ Copyright Eric L. Hernes - Wednesday, August 2, 1995
|
||||||
++
|
++
|
||||||
++ $Id: ddwg.sgml,v 1.4 1997-10-03 20:53:38 wosch Exp $
|
++ $Id: ddwg.sgml,v 1.5 1998-06-12 13:59:49 eivind Exp $
|
||||||
++
|
++
|
||||||
++ Sgml doc for something
|
++ Sgml doc for something
|
||||||
-->
|
-->
|
||||||
|
|
@ -153,7 +153,100 @@ is limited to one page (4k on the i386).
|
||||||
<sect3> d_stop()
|
<sect3> d_stop()
|
||||||
<sect3> d_reset()
|
<sect3> d_reset()
|
||||||
<sect3> d_devtotty()
|
<sect3> d_devtotty()
|
||||||
<sect3> d_select()
|
<sect3> d_poll() (3.0+) or d_select() (2.2)
|
||||||
|
<p>
|
||||||
|
d_poll()'s argument list is as follows:
|
||||||
|
<code>
|
||||||
|
void
|
||||||
|
d_poll(dev_t dev, int events, struct proc *p)
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<p> d_poll() is used to find out if a device is ready for IO. An
|
||||||
|
example is waiting for data to become available from the network, or
|
||||||
|
waiting for the user to press a key. This correspond to the poll()
|
||||||
|
call in userland.
|
||||||
|
|
||||||
|
<p>The d_poll() call should check for the events specified in the
|
||||||
|
event mask. If none of the requested events are active, but they may
|
||||||
|
become active later, it should record this for the kernel's later
|
||||||
|
persual. d_poll() does this by calling selrecord() with a selinfo
|
||||||
|
structure for this device. The sum of all these activities look
|
||||||
|
something like this:
|
||||||
|
|
||||||
|
<code>
|
||||||
|
static struct my_softc {
|
||||||
|
struct queue rx_queue; /* As example only - not required */
|
||||||
|
struct queue tx_queue; /* As example only - not required */
|
||||||
|
struct selinfo selp; /* Required */
|
||||||
|
} my_softc[NMYDEV];
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
static int
|
||||||
|
mydevpoll(dev_t dev, int events, struct proc *p)
|
||||||
|
{
|
||||||
|
int revents = 0; /* Events we found */
|
||||||
|
int s;
|
||||||
|
struct my_softc *sc = &my_softc[dev];
|
||||||
|
|
||||||
|
/* We can only check for IN and OUT */
|
||||||
|
if ((events & (POLLIN|POLLOUT)) == 0)
|
||||||
|
return(POLLNVAL);
|
||||||
|
|
||||||
|
s = splhigh();
|
||||||
|
/* Writes are if the transmit queue can take them */
|
||||||
|
if ((events & POLLOUT) &&
|
||||||
|
!IF_QFULL(sc->tx_queue))
|
||||||
|
revents |= POLLOUT;
|
||||||
|
/* ... while reads are OK if we have any data */
|
||||||
|
if ((events & POLLIN) &&
|
||||||
|
!IF_QEMPTY(sc->rx_queue))
|
||||||
|
revents |= POLLIN;
|
||||||
|
if (revents == 0)
|
||||||
|
selrecord(p, &sc->selp);
|
||||||
|
splx(s);
|
||||||
|
return revents;
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
d_select() is used in 2.2 and previous versions of FreeBSD. Instead
|
||||||
|
of 'events' it take a single int 'rw', which can be FREAD for reads
|
||||||
|
(as in POLLIN above), FWRITE for write (as in POLLOUT above), and 0
|
||||||
|
for 'exception' - something exceptional happened, like a card being
|
||||||
|
inserted or removed for the pccard driver.
|
||||||
|
|
||||||
|
<p>For select, the above code fragment would look like this:
|
||||||
|
<code>
|
||||||
|
static int
|
||||||
|
mydevselect(dev_t dev, int rw, struct proc *p)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
int s;
|
||||||
|
struct my_softc *sc = &my_softc[dev];
|
||||||
|
|
||||||
|
s = splhigh();
|
||||||
|
switch (rw) {
|
||||||
|
case FWRITE:
|
||||||
|
/* Writes are if the transmit queue can take them */
|
||||||
|
if (!IF_QFULL(sc->tx_queue))
|
||||||
|
ret = 1;
|
||||||
|
break;
|
||||||
|
case FREAD:
|
||||||
|
/* ... while reads are OK if we have any data */
|
||||||
|
if (!IF_QEMPTY(sc->rx_queue))
|
||||||
|
ret = 1;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
/* This driver never get any exceptions */
|
||||||
|
break;
|
||||||
|
if(ret == 0)
|
||||||
|
selrecord(p, &sc->selp);
|
||||||
|
splx(s);
|
||||||
|
return(revents);
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
|
||||||
<sect3> d_mmap()
|
<sect3> d_mmap()
|
||||||
<sect3> d_strategy()
|
<sect3> d_strategy()
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
++
|
++
|
||||||
++ Copyright Eric L. Hernes - Wednesday, August 2, 1995
|
++ Copyright Eric L. Hernes - Wednesday, August 2, 1995
|
||||||
++
|
++
|
||||||
++ $Id: ddwg.sgml,v 1.4 1997-10-03 20:53:38 wosch Exp $
|
++ $Id: ddwg.sgml,v 1.5 1998-06-12 13:59:49 eivind Exp $
|
||||||
++
|
++
|
||||||
++ Sgml doc for something
|
++ Sgml doc for something
|
||||||
-->
|
-->
|
||||||
|
|
@ -153,7 +153,100 @@ is limited to one page (4k on the i386).
|
||||||
<sect3> d_stop()
|
<sect3> d_stop()
|
||||||
<sect3> d_reset()
|
<sect3> d_reset()
|
||||||
<sect3> d_devtotty()
|
<sect3> d_devtotty()
|
||||||
<sect3> d_select()
|
<sect3> d_poll() (3.0+) or d_select() (2.2)
|
||||||
|
<p>
|
||||||
|
d_poll()'s argument list is as follows:
|
||||||
|
<code>
|
||||||
|
void
|
||||||
|
d_poll(dev_t dev, int events, struct proc *p)
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<p> d_poll() is used to find out if a device is ready for IO. An
|
||||||
|
example is waiting for data to become available from the network, or
|
||||||
|
waiting for the user to press a key. This correspond to the poll()
|
||||||
|
call in userland.
|
||||||
|
|
||||||
|
<p>The d_poll() call should check for the events specified in the
|
||||||
|
event mask. If none of the requested events are active, but they may
|
||||||
|
become active later, it should record this for the kernel's later
|
||||||
|
persual. d_poll() does this by calling selrecord() with a selinfo
|
||||||
|
structure for this device. The sum of all these activities look
|
||||||
|
something like this:
|
||||||
|
|
||||||
|
<code>
|
||||||
|
static struct my_softc {
|
||||||
|
struct queue rx_queue; /* As example only - not required */
|
||||||
|
struct queue tx_queue; /* As example only - not required */
|
||||||
|
struct selinfo selp; /* Required */
|
||||||
|
} my_softc[NMYDEV];
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
static int
|
||||||
|
mydevpoll(dev_t dev, int events, struct proc *p)
|
||||||
|
{
|
||||||
|
int revents = 0; /* Events we found */
|
||||||
|
int s;
|
||||||
|
struct my_softc *sc = &my_softc[dev];
|
||||||
|
|
||||||
|
/* We can only check for IN and OUT */
|
||||||
|
if ((events & (POLLIN|POLLOUT)) == 0)
|
||||||
|
return(POLLNVAL);
|
||||||
|
|
||||||
|
s = splhigh();
|
||||||
|
/* Writes are if the transmit queue can take them */
|
||||||
|
if ((events & POLLOUT) &&
|
||||||
|
!IF_QFULL(sc->tx_queue))
|
||||||
|
revents |= POLLOUT;
|
||||||
|
/* ... while reads are OK if we have any data */
|
||||||
|
if ((events & POLLIN) &&
|
||||||
|
!IF_QEMPTY(sc->rx_queue))
|
||||||
|
revents |= POLLIN;
|
||||||
|
if (revents == 0)
|
||||||
|
selrecord(p, &sc->selp);
|
||||||
|
splx(s);
|
||||||
|
return revents;
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
d_select() is used in 2.2 and previous versions of FreeBSD. Instead
|
||||||
|
of 'events' it take a single int 'rw', which can be FREAD for reads
|
||||||
|
(as in POLLIN above), FWRITE for write (as in POLLOUT above), and 0
|
||||||
|
for 'exception' - something exceptional happened, like a card being
|
||||||
|
inserted or removed for the pccard driver.
|
||||||
|
|
||||||
|
<p>For select, the above code fragment would look like this:
|
||||||
|
<code>
|
||||||
|
static int
|
||||||
|
mydevselect(dev_t dev, int rw, struct proc *p)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
int s;
|
||||||
|
struct my_softc *sc = &my_softc[dev];
|
||||||
|
|
||||||
|
s = splhigh();
|
||||||
|
switch (rw) {
|
||||||
|
case FWRITE:
|
||||||
|
/* Writes are if the transmit queue can take them */
|
||||||
|
if (!IF_QFULL(sc->tx_queue))
|
||||||
|
ret = 1;
|
||||||
|
break;
|
||||||
|
case FREAD:
|
||||||
|
/* ... while reads are OK if we have any data */
|
||||||
|
if (!IF_QEMPTY(sc->rx_queue))
|
||||||
|
ret = 1;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
/* This driver never get any exceptions */
|
||||||
|
break;
|
||||||
|
if(ret == 0)
|
||||||
|
selrecord(p, &sc->selp);
|
||||||
|
splx(s);
|
||||||
|
return(revents);
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
|
||||||
<sect3> d_mmap()
|
<sect3> d_mmap()
|
||||||
<sect3> d_strategy()
|
<sect3> d_strategy()
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue