1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include <sys/errno.h>
32#include <sys/types.h>
33#include <sys/param.h>
34#include <machine/spl.h>
35#include <sys/systm.h>
36#include <sys/kernel.h>
37#include <sys/proc.h>
38#include <sys/filedesc.h>
39#include <sys/fcntl.h>
40#include <sys/mbuf.h>
41#include <sys/socket.h>
42#include <sys/socketvar.h>
43
44#include <netat/sysglue.h>
45#include <netat/appletalk.h>
46#include <netat/at_pcb.h>
47#include <netat/debug.h>
48#include <netat/adsp.h>
49#include <netat/adsp_internal.h>
50
51
52
53
54
55
56
57
58
59extern int adsp_check;
60
61int CheckReadQueue(sp)
62 register CCBPtr sp;
63{
64 register struct adspcmd *pb;
65 int s;
66 unsigned short cnt;
67 char eom = 0;
68 register gbuf_t *mp;
69 register gbuf_t *tmp;
70 gref_t *gref;
71
72 dPrintf(D_M_ADSP, D_L_TRACE, ("CheckReadQueue: sp=0x%x\n", (unsigned)sp));
73 KERNEL_DEBUG(DBG_ADSP_READ, 0, sp, sp->rbuf_mb, sp->rpb, sp->delay);
74 trace_mbufs(D_M_ADSP_LOW, " bCQR m", sp->rbuf_mb);
75 ATDISABLE(s, sp->lock);
76
77 while (sp->rData && (pb = sp->rpb)) {
78 dPrintf(D_M_ADSP, D_L_TRACE,
79 (" pb=0x%x, gref=0x%x, ioc=0x%x, reqCount=%d (have data)\n",
80 pb, pb->gref, pb->ioc, pb->u.ioParams.reqCount));
81 KERNEL_DEBUG(DBG_ADSP_READ, 1, pb, pb->gref, pb->ioc, pb->u.ioParams.reqCount);
82 if (pb->u.ioParams.reqCount == 0) {
83 pb->ioResult = 0;
84 sp->rpb = pb->qLink;
85 if (pb->ioc) {
86 KERNEL_DEBUG(DBG_ADSP_READ, 2, pb, pb->gref, pb->ioc, 0);
87 adspioc_ack(0, pb->ioc, pb->gref);
88 } else {
89 KERNEL_DEBUG(DBG_ADSP_READ, 3, pb, pb->gref, 0, 0);
90 completepb(sp, pb);
91 }
92 continue;
93 }
94
95
96 if (mp = sp->rbuf_mb) {
97 KERNEL_DEBUG(DBG_ADSP_READ, 4, pb, mp, gbuf_msgsize(mp), gbuf_next(mp));
98 sp->rbuf_mb = gbuf_next(mp);
99 gbuf_next(mp) = 0;
100 eom = 1;
101 } else if (mp = sp->crbuf_mb) {
102 KERNEL_DEBUG(DBG_ADSP_READ, 5, pb, mp, gbuf_msgsize(mp), gbuf_next(mp));
103 sp->crbuf_mb = 0;
104 eom = 0;
105 }
106
107
108
109
110 cnt = gbuf_msgsize(mp);
111 if (cnt > (unsigned short)(pb->u.ioParams.reqCount - pb->u.ioParams.actCount)) {
112 cnt = pb->u.ioParams.reqCount - pb->u.ioParams.actCount;
113
114 if (!(tmp = (gbuf_t *)m_split(mp, cnt, M_DONTWAIT))) {
115 cnt = 0;
116 tmp = mp;
117 }
118 if (eom) {
119 gbuf_next(tmp) = sp->rbuf_mb;
120 sp->rbuf_mb = tmp;
121 eom = 0;
122 } else
123 sp->crbuf_mb = tmp;
124 }
125 if (cnt) {
126 pb->u.ioParams.actCount += cnt;
127 gbuf_linkb(pb->mp, mp);
128 }
129
130 pb->u.ioParams.eom = eom;
131
132
133
134
135 if ((sp->rbuf_mb == 0) &&
136 (sp->crbuf_mb == 0))
137 sp->rData = 0;
138
139
140
141
142
143 if (eom || (pb->u.ioParams.actCount >= pb->u.ioParams.reqCount) ||
144 ((sp->state == sClosed) && (!sp->rData)) ) {
145
146
147
148
149 pb->ioResult = 0;
150 sp->rpb = pb->qLink;
151 if (pb->ioc) {
152 mp = gbuf_cont(pb->mp);
153 gbuf_cont(pb->mp) = 0;
154 gref = (gref_t *)pb->gref;
155 adspioc_ack(0, pb->ioc, pb->gref);
156 dPrintf(D_M_ADSP, D_L_TRACE, (" (pb->ioc) mp=%x\n", mp));
157 KERNEL_DEBUG(DBG_ADSP_READ, 0x0A, pb, mp,
158 gbuf_next(mp), gbuf_cont(mp));
159 SndMsgUp(gref, mp);
160 dPrintf(D_M_ADSP, D_L_TRACE,
161 (" (data) size req=%d\n", pb->u.ioParams.actCount));
162 KERNEL_DEBUG(DBG_ADSP_READ, 0x0B, pb, pb->ioc,
163 pb->u.ioParams.reqCount, pb->u.ioParams.actCount);
164 } else {
165 KERNEL_DEBUG(DBG_ADSP_READ, 0x0C, pb, sp,
166 pb->u.ioParams.actCount, sp->delay);
167 completepb(sp, pb);
168 }
169 }
170 }
171
172 if (pb = sp->rpb) {
173 dPrintf(D_M_ADSP, D_L_TRACE,
174 (" pb=0x%x, ioc=0x%x, reqCount=%d (no more data)\n",
175 pb, pb->ioc, pb->u.ioParams.reqCount));
176 KERNEL_DEBUG(DBG_ADSP_READ, 0x0D, pb, pb->ioc,
177 pb->u.ioParams.reqCount, pb->u.ioParams.actCount);
178
179 if (sp->state == sClosed) {
180 while (pb) {
181 KERNEL_DEBUG(DBG_ADSP_READ, 0x0E, pb, sp, pb->ioc, 0);
182 pb->ioResult = 0;
183 pb->u.ioParams.actCount = 0;
184 pb->u.ioParams.eom = 0;
185 sp->rpb = pb->qLink;
186 if (pb->ioc) {
187 adspioc_ack(0, pb->ioc, pb->gref);
188 } else {
189 completepb(sp, pb);
190 }
191 pb = sp->rpb;
192 }
193 } else if (pb->ioc) {
194
195 sp->rpb = pb->qLink;
196 pb->ioResult = 1;
197 tmp = gbuf_cont(pb->mp);
198 gbuf_cont(pb->mp) = 0;
199 if (mp = gbuf_copym(pb->mp)) {
200 KERNEL_DEBUG(DBG_ADSP_READ, 0x0F, pb, sp, pb->mp, 0);
201 adspioc_ack(0, pb->ioc, pb->gref);
202 pb = (struct adspcmd *)gbuf_rptr(mp);
203 pb->ioc = 0;
204 pb->mp = mp;
205 gbuf_cont(pb->mp) = tmp;
206 pb->qLink = sp->rpb;
207 sp->rpb = pb;
208 } else {
209
210
211
212
213
214 KERNEL_DEBUG(DBG_ADSP_READ, 0x10, pb, sp, pb->mp, 0);
215 if (tmp) {
216 sp->crbuf_mb = tmp;
217 sp->rData = 1;
218 }
219 pb->ioResult = errDSPQueueSize;
220 adspioc_ack(ENOBUFS, pb->ioc, pb->gref);
221 }
222 }
223 }
224
225
226
227
228
229
230
231 if (sp->rbufFull && (CalcRecvWdw(sp) > (sp->rbuflen >> 2))) {
232 sp->rbufFull = 0;
233 sp->sendDataAck = 1;
234 sp->callSend = 1;
235 }
236 ATENABLE(s, sp->lock);
237
238 KERNEL_DEBUG(DBG_ADSP_READ, 0x11, sp, 0, 0, 0);
239 trace_mbufs(D_M_ADSP_LOW, " eCQR m", sp->rbuf_mb);
240 return 0;
241}
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256int CheckAttn(sp, pb)
257 register CCBPtr sp;
258 register struct adspcmd *pb;
259{
260 int s;
261 gbuf_t *mp;
262 gref_t *gref;
263
264 dPrintf(D_M_ADSP, D_L_TRACE,
265 ("CheckAttn: sp=0x%x, pb=0x%x\n", (unsigned)sp, (unsigned)pb));
266
267 ATDISABLE(s, sp->lock);
268 if (mp = sp->attn_mb) {
269
270
271
272
273 gref = (gref_t *)pb->gref;
274 pb->u.attnParams.attnSize = sp->attnSize;
275 pb->u.attnParams.attnCode = sp->attnCode;
276 if (!sp->attnSize) {
277 gbuf_freem(mp);
278 mp = 0;
279 }
280 sp->userFlags &= ~eAttention;
281
282
283
284
285 sp->attn_mb = 0;
286 pb->ioResult = 0;
287 } else {
288
289
290
291 pb->u.attnParams.attnSize = 0;
292 pb->u.attnParams.attnCode = 0;
293 pb->ioResult = 1;
294 }
295 adspioc_ack(0, pb->ioc, pb->gref);
296 if (mp) {
297 SndMsgUp(gref, mp);
298 }
299 ATENABLE(s, sp->lock);
300 return 0;
301}
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320int adspRead(sp, pb)
321 register CCBPtr sp;
322 register struct adspcmd *pb;
323{
324 register gbuf_t *mp;
325 int s;
326
327 dPrintf(D_M_ADSP, D_L_TRACE,
328 ("adspRead: sp=0x%x, pb=0x%x\n", (unsigned)sp, (unsigned)pb));
329
330 KERNEL_DEBUG(DBG_ADSP_READ, 0x12, sp, pb, sp->state, sp->rData);
331
332 if (sp == 0) {
333 pb->ioResult = errRefNum;
334 return EINVAL;
335 }
336
337
338
339
340 ATDISABLE(s, sp->lock);
341 if (sp->state != sOpen && sp->state != sClosing && sp->state != sClosed) {
342 ATENABLE(s, sp->lock);
343 pb->ioResult = errState;
344 return EINVAL;
345 }
346 if (sp->rData && (sp->rpb == 0)) {
347 qAddToEnd(&sp->rpb, pb);
348 ATENABLE(s, sp->lock);
349 CheckReadQueue(sp);
350 } else if ((pb->u.ioParams.reqCount == 0) && (sp->rpb == 0)) {
351
352 ATENABLE(s, sp->lock);
353 pb->ioResult = 0;
354 adspioc_ack(0, pb->ioc, pb->gref);
355 return 0;
356 } else {
357 pb->ioResult = 1;
358 if (mp = gbuf_copym(pb->mp)) {
359 adspioc_ack(0, pb->ioc, pb->gref);
360 pb = (struct adspcmd *)gbuf_rptr(mp);
361 pb->ioc = 0;
362 pb->mp = mp;
363 qAddToEnd(&sp->rpb, pb);
364 ATENABLE(s, sp->lock);
365 } else {
366 ATENABLE(s, sp->lock);
367 pb->ioResult = errDSPQueueSize;
368 return ENOBUFS;
369 }
370 }
371
372 if (sp->callSend) {
373 CheckSend(sp);
374
375 }
376 return 0;
377}
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393int adspReadAttention(sp, pb)
394 register CCBPtr sp;
395 register struct adspcmd *pb;
396{
397 dPrintf(D_M_ADSP, D_L_TRACE,
398 ("adspReadAttention: sp=0x%x, pb=0x%x\n", (unsigned)sp, (unsigned)pb));
399 if (sp == 0) {
400 pb->ioResult = errRefNum;
401 return EINVAL;
402 }
403
404
405
406
407 if (sp->state != sOpen && sp->state != sClosing && sp->state != sClosed) {
408 pb->ioResult = errState;
409 return EINVAL;
410 }
411
412 CheckAttn(sp, pb);
413 CheckReadQueue(sp);
414 if (sp->callSend) {
415 CheckSend(sp);
416
417 }
418 return 0;
419}
420