diff options
author | Eivind Eklund <eivind@FreeBSD.org> | 1998-06-12 13:59:49 +0000 |
---|---|---|
committer | Eivind Eklund <eivind@FreeBSD.org> | 1998-06-12 13:59:49 +0000 |
commit | 082f0d19a96c932a04740cbcb01f624dcc678cf3 (patch) | |
tree | b604bbf21c64e712c6be52e75c074a9d7a63822b /en_US.ISO_8859-1/tutorials | |
parent | 8be4630691ba765faefa2480740a47533aee55c4 (diff) | |
download | doc-082f0d19a96c932a04740cbcb01f624dcc678cf3.tar.gz doc-082f0d19a96c932a04740cbcb01f624dcc678cf3.zip |
Document d_poll() and d_select().
Notes
Notes:
svn path=/head/; revision=2942
Diffstat (limited to 'en_US.ISO_8859-1/tutorials')
-rw-r--r-- | en_US.ISO_8859-1/tutorials/ddwg/ddwg.sgml | 97 |
1 files changed, 95 insertions, 2 deletions
diff --git a/en_US.ISO_8859-1/tutorials/ddwg/ddwg.sgml b/en_US.ISO_8859-1/tutorials/ddwg/ddwg.sgml index 9cb25739aa..45a17506f7 100644 --- a/en_US.ISO_8859-1/tutorials/ddwg/ddwg.sgml +++ b/en_US.ISO_8859-1/tutorials/ddwg/ddwg.sgml @@ -6,7 +6,7 @@ ++ ++ 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 --> @@ -153,7 +153,100 @@ is limited to one page (4k on the i386). <sect3> d_stop() <sect3> d_reset() <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_strategy() <p> |