Kernel Functions for Drivers bufcall(9F)
NAME
bufcall - call a function when a buffer becomes available
SYNOPSIS
#include
#include
bufcallidt bufcall(sizet size, uintt pri, void *funcvoid *arg,
void *arg);
INTERFACE LEVEL
Architecture independent level 1 (DI/DKI).
PARAMETERS
size Number of bytes required for the buffer.
pri Priority of the allocb(9F) allocation request (not
used).
func Function or driver routine to be called when a
buffer becomes available.
arg Argument to the function to be called when a buffer
becomes available.
DESCRIPTION
The bufcall() function serves as a timeout(9F) call of
indeterminate length. When a buffer allocation request
fails, bufcall() can be used to schedule the routine func,
to be called with the argument arg when a buffer becomes
available. func may call allocb() or it may do something
else.
RETURN VALUES
If successful, bufcall() returns a bufcall ID that can be
used in a call to unbufcall() to cancel the request. If the
bufcall() scheduling fails, func is never called and 0 is
returned.
CONTEXT
The bufcall() function can be called from user, interrupt,
or kernel context.
EXAMPLES
SunOS 5.11 Last change: 16 Jan 2006 1
Kernel Functions for Drivers bufcall(9F)
Example 1 Calling a function when a buffer becomes avail-
able:
The purpose of this srv(9E) service routine is to add a
header to all MDATA messages. Service routines must process
all messages on their queues before returning, or arrange to
be rescheduled
While there are messages to be processed (line 13), check to
see if it is a high priority message or a normal priority
message that can be sent on (line 14). Normal priority mes-
sage that cannot be sent are put back on the message queue
(line 34). If the message was a high priority one, or if it
was normal priority and canputnext(9F) succeeded, then send
all but MDATA messages to the next module with putnext(9F)
(line 16).
For MDATA messages, try to allocate a buffer large enough
to hold the header (line 18). If no such buffer is avail-
able, the service routine must be rescheduled for a time
when a buffer is available. The original message is put back
on the queue (line 20) and bufcall (line 21) is used to
attempt the rescheduling. It will succeed if the reschedul-
ing succeeds, indicating that qenable will be called subse-
quently with the argument q once a buffer of the specified
size (sizeof (struct hdr)) becomes available. If it does,
qenable(9F) will put q on the list of queues to have their
service routines called. If bufcall() fails, timeout(9F)
(line 22) is used to try again in about a half second.
If the buffer allocation was successful, initialize the
header (lines 25-28), make the message type MPROTO (line
29), link the MDATA message to it (line 30), and pass it on
(line 31).
Note that this example ignores the bookkeeping needed to
handle bufcall() and timeout(9F) cancellation for ones that
are still outstanding at close time.
1 struct hdr {
2 unsigned int hsize;
3 int hversion;
SunOS 5.11 Last change: 16 Jan 2006 2
Kernel Functions for Drivers bufcall(9F)
4 };
5
6 void xxxsrv(q)
7 queuet *q;
8 {
9 mblkt *bp;
10 mblkt *mp;
11 struct hdr *hp;
12
13 while ((mp = getq(q)) != NUL) { /* get next message */
14 if (mp->bdatap->dbtype >= QPCTL /* if high priority */
canputnext(q)) { /* normal & can be passed */
15 if (mp->bdatap->dbtype != MDATA)
16 putnext(q, mp); /* send all but MDATA */
17 else {
18 bp = allocb(sizeof(struct hdr), BPRILO);
19 if (bp == NUL) { /* if unsuccessful */
20 putbq(q, mp); /* put it back */
21 if (!bufcall(sizeof(struct hdr), BPRILO,
qenable, q)) /* try to reschedule */
22 timeout(qenable, q, drvusectohz(500000));
23 return (0);
24 }
25 hp = (struct hdr *)bp->bwptr;
26 hp->hsize = msgdsize(mp); /* initialize header */
27 hp->hversion = 1;
28 bp->bwptr ]= sizeof(struct hdr);
29 bp->bdatap->dbtype = MPROTO;/* make MPROTO */
30 bp->bcont = mp; /* link it */
31 putnext(q, bp); /* pass it on */
32 }
33 } else { /* normal priority, canputnext failed */
34 putbq(q, mp); /* put back on the message queue */
35 return (0);
36 }
37 }
return (0);
38 }
SEE ALSO
srv(9E), allocb(9F), canputnext(9F), esballoc(9F),
esbbcall(9F), putnext(9F), qenable(9F), testb(9F),
timeout(9F), unbufcall(9F)
Writing Device Drivers
STREAMS Programming Guide
SunOS 5.11 Last change: 16 Jan 2006 3
Kernel Functions for Drivers bufcall(9F)
WARNINGS
Even when func is called by bufcall(), allocb(9F) can fail
if another module or driver had allocated the memory before
func was able to call allocb(9F).
SunOS 5.11 Last change: 16 Jan 2006 4
|