Merge commit '9276b3991ba20d5a5660887ba81b0bc7bed25a0c'
[unleashed.git] / share / man / man9f / bufcall.9f
blobdadc4f2169928fdbcc3765381fb5ab699114cf9c
1 '\" te
2 .\" Copyright (c) 2006, Sun Microsystems, Inc.  All Rights Reserved.
3 .\" Copyright 1989 AT&T
4 .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
5 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
6 .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
7 .TH BUFCALL 9F "Jan 16, 2006"
8 .SH NAME
9 bufcall \- call a function when a buffer becomes available
10 .SH SYNOPSIS
11 .LP
12 .nf
13 #include <sys/types.h>
14 #include <sys/stream.h>
18 \fBbufcall_id_t\fR \fBbufcall\fR(\fBsize_t\fR \fIsize\fR, \fBuint_t\fR \fIpri\fR, \fBvoid \fR\fI*func\fRvoid \fI*arg\fR,
19     \fBvoid\fR \fI*arg\fR);
20 .fi
22 .SH INTERFACE LEVEL
23 .sp
24 .LP
25 Architecture independent level 1 (DDI/DKI).
26 .SH PARAMETERS
27 .sp
28 .ne 2
29 .na
30 \fB\fIsize\fR\fR
31 .ad
32 .RS 8n
33 Number of bytes required for the buffer.
34 .RE
36 .sp
37 .ne 2
38 .na
39 \fB\fIpri\fR\fR
40 .ad
41 .RS 8n
42 Priority of the \fBallocb\fR(9F) allocation request (not used).
43 .RE
45 .sp
46 .ne 2
47 .na
48 \fB\fIfunc\fR\fR
49 .ad
50 .RS 8n
51 Function or driver routine to be called when a buffer becomes available.
52 .RE
54 .sp
55 .ne 2
56 .na
57 \fB\fIarg\fR\fR
58 .ad
59 .RS 8n
60 Argument to the function to be called when a buffer becomes available.
61 .RE
63 .SH DESCRIPTION
64 .sp
65 .LP
66 The \fBbufcall()\fR function serves as a \fBtimeout\fR(9F) call of
67 indeterminate length. When a buffer allocation request fails, \fBbufcall()\fR
68 can be used to schedule the routine \fIfunc\fR, to be called with the argument
69 \fIarg\fR when a buffer becomes available. \fIfunc\fR may call \fBallocb()\fR
70 or it may do something else.
71 .SH RETURN VALUES
72 .sp
73 .LP
74 If successful, \fBbufcall()\fR returns a \fBbufcall\fR \fBID\fR that can be
75 used in a call to \fBunbufcall()\fR to cancel the request. If the
76 \fBbufcall()\fR scheduling fails, \fIfunc\fR is never called and \fB0\fR is
77 returned.
78 .SH CONTEXT
79 .sp
80 .LP
81 The \fBbufcall()\fR function can be called from user, interrupt, or kernel
82 context.
83 .SH EXAMPLES
84 .LP
85 \fBExample 1 \fRCalling a function when a buffer becomes available:
86 .sp
87 .LP
88 The purpose of this \fBsrv\fR(9E) service routine is to add a header to all
89 \fBM_DATA\fR messages. Service routines must process all messages on their
90 queues before returning, or arrange to be rescheduled
92 .sp
93 .LP
94 While there are messages to be processed (line 13), check to see if it is a
95 high priority message or a normal priority message that can be sent on (line
96 14). Normal priority message that cannot be sent are put back on the message
97 queue (line 34). If the message was a high priority one, or if it was normal
98 priority and \fBcanputnext\fR(9F) succeeded, then send all but \fBM_DATA\fR
99 messages to the next module with \fBputnext\fR(9F) (line 16).
103 For \fBM_DATA\fR messages, try to allocate a buffer large enough to hold the
104 header (line 18). If no such buffer is available, the service routine must be
105 rescheduled for a time when a buffer is available. The original message is put
106 back on the queue (line 20) and \fBbufcall\fR (line 21) is used to attempt the
107 rescheduling. It will succeed if the rescheduling succeeds, indicating that
108 qenable will be called subsequently with the argument \fIq\fR once a buffer of
109 the specified size (\fBsizeof (struct hdr)\fR) becomes available. If it does,
110 \fBqenable\fR(9F) will put \fIq\fR on the list of queues to have their service
111 routines called. If \fBbufcall()\fR fails, \fBtimeout\fR(9F) (line 22) is used
112 to try again in about a half second.
116 If the buffer allocation was successful, initialize the header (lines 25-28),
117 make the message type \fBM_PROTO\fR (line 29), link the \fBM_DATA\fR message to
118 it (line 30), and pass it on (line 31).
122 Note that this example ignores the bookkeeping needed to handle \fBbufcall()\fR
123 and \fBtimeout\fR(9F) cancellation for ones that are still outstanding at close
124 time.
127 .in +2
129  \fB1  struct hdr {
130  2     unsigned int h_size;
131  3     int          h_version;
132  4  };
134  6  void xxxsrv(q)
135  7     queue_t *q;
136  8  {
137  9     mblk_t *bp;
138 10     mblk_t *mp;
139 11     struct hdr *hp;
141 13     while ((mp = getq(q)) != NULL) { /* get next message */
142 14         if (mp->b_datap->db_type >= QPCTL || /* if high priority */
143                  canputnext(q)) {       /* normal & can be passed */
144 15            if (mp->b_datap->db_type != M_DATA)
145 16                 putnext(q, mp);      /* send all but M_DATA */
146 17            else {
147 18                bp = allocb(sizeof(struct hdr), BPRI_LO);
148 19                if (bp == NULL) {     /* if unsuccessful */
149 20                     putbq(q, mp);    /* put it back */
150 21                     if (!bufcall(sizeof(struct hdr), BPRI_LO,
151                            qenable, q)) /* try to reschedule */
152 22                         timeout(qenable, q, drv_usectohz(500000));
153 23                        return (0);
154 24                 }
155 25                 hp = (struct hdr *)bp->b_wptr;
156 26                 hp->h_size = msgdsize(mp);   /* initialize header */
157 27                 hp->h_version = 1;
158 28                 bp->b_wptr += sizeof(struct hdr);
159 29                 bp->b_datap->db_type = M_PROTO;/* make M_PROTO  */
160 30                 bp->b_cont = mp;     /* link it */
161 31                 putnext(q, bp);      /* pass it on */
162 32            }
163 33         } else {     /* normal priority, canputnext failed */
164 34           putbq(q, mp);      /* put back on the message queue */
165 35           return (0);
166 36         }
167 37        }
168         return (0);
169 38  }\fR
171 .in -2
173 .SH SEE ALSO
176 \fBsrv\fR(9E), \fBallocb\fR(9F), \fBcanputnext\fR(9F), \fBesballoc\fR(9F),
177 \fBesbbcall\fR(9F), \fBputnext\fR(9F), \fBqenable\fR(9F), \fBtestb\fR(9F),
178 \fBtimeout\fR(9F), \fBunbufcall\fR(9F)
181 \fIWriting Device Drivers\fR
184 \fISTREAMS Programming Guide\fR
185 .SH WARNINGS
188 Even when \fIfunc\fR is called by \fBbufcall()\fR, \fBallocb\fR(9F) can fail if
189 another module or driver had allocated the memory before \fIfunc\fR was able to
190 call \fBallocb\fR(9F).