|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25:
26: #include <adsp_local.h>
27:
28: /*
29: * FillSendQueue
30: *
31: * INPUTS:
32: * sp stream
33: * OUTPUTS:
34: * none
35: */
36: int FillSendQueue(sp, pb) /* (CCBPtr sp) */
37: register CCBPtr sp;
38: register struct adspcmd *pb; /* The write PB we're playing with */
39: {
40: gbuf_t *mb, *nmb;
41: char *dest; /* Destination for data to copy */
42: char *src; /* Source of data to copy */
43: int eom; /* True if should set eom in header */
44: int cnt; /* # of bytes to copy from param block */
45: int s;
46: int err;
47:
48: err = 0;
49: /*
50: * Copy user data based on information in the paramater block
51: */
52: cnt = pb->u.ioParams.reqCount - pb->u.ioParams.actCount;
53: if (pb->u.ioParams.dataPtr)
54: src = (char *)&pb->u.ioParams.dataPtr[pb->u.ioParams.actCount];
55: eom = pb->u.ioParams.eom ? F_EOM : 0;
56:
57: if (cnt == 0 && eom == 0) /* Nothing to do here, complete it */
58: goto unlink;
59:
60: mb = pb->mp;
61: nmb = gbuf_cont(mb);
62: if (gbuf_len(mb) > sizeof(struct adspcmd)) {
63: if ((nmb = gbuf_dupb(mb)) == 0) {
64: gbuf_wset(mb,sizeof(struct adspcmd));
65: err = errDSPQueueSize;
66: goto unlink;
67: }
68: gbuf_wset(mb,sizeof(struct adspcmd));
69: gbuf_rinc(nmb,sizeof(struct adspcmd));
70: gbuf_cont(nmb) = gbuf_cont(mb);
71: } else if (nmb == 0) {
72: if ((nmb = gbuf_alloc(1, PRI_LO)) == 0) {
73: err = errENOBUFS;
74: goto unlink;
75: }
76: }
77: gbuf_cont(mb) = 0;
78:
79: ATDISABLE(s, sp->lock);
80: sp->sData = 1; /* note that there is data to send */
81: if (mb = sp->csbuf_mb) { /* add to the current message */
82: gbuf_linkb(mb, nmb);
83: } else
84: sp->csbuf_mb = nmb; /* mark the buffer we are currently filling */
85: if (eom) {
86: if (mb = sp->sbuf_mb) {
87: while (gbuf_next(mb))
88: mb = gbuf_next(mb);
89: gbuf_next(mb) = sp->csbuf_mb; /* add the current item */
90: } else
91: sp->sbuf_mb = sp->csbuf_mb;
92: sp->csbuf_mb = 0; /* if its done, no current buffer */
93: }
94: pb->u.ioParams.actCount += cnt; /* Update count field in param blk */
95: ATENABLE(s, sp->lock);
96:
97: if (pb->u.ioParams.actCount == pb->u.ioParams.reqCount) {
98: /* Write is complete */
99: unlink:
100: if (pb->u.ioParams.flush) /* flush the send Q? */
101: sp->writeFlush = 1;
102:
103: pb->ioResult = err;
104: if (err) {
105: gbuf_set_type(pb->mp, MSG_ERROR);
106: *gbuf_rptr(pb->mp) = EIO;
107: gbuf_wset(pb->mp,1);
108: completepb(sp, pb);
109: } else
110: gbuf_freem(pb->mp);
111: }
112:
113: return 0;
114: }
115:
116: /*
117: * dspWrite
118: *
119: * INPUTS:
120: * --> ccbRefNum refnum of connection end
121: * --> reqCount requested number of bytes to write
122: * --> dataPtr pointer to buffer for reading bytes into
123: * --> eom one if end-of-message, zero otherwise
124: *
125: * OUTPUTS:
126: * <-- actCount actual number of bytes written
127: *
128: * ERRORS:
129: * errRefNum bad connection refnum
130: * errState connection is not open
131: * errAborted request aborted by Remove or Close call
132: */
133: int adspWrite(sp, pb) /* (DSPPBPtr pb) */
134: CCBPtr sp;
135: struct adspcmd *pb;
136: {
137: OSErr err;
138: int s;
139:
140: if (sp == 0) {
141: pb->ioResult = errRefNum;
142: return EINVAL; /* no stream, so drop the message */
143: }
144:
145: ATDISABLE(s, sp->lock);
146: if (sp->state != sOpen) { /* Not allowed */
147: pb->ioResult = errState;
148: ATENABLE(s, sp->lock);
149: gbuf_set_type(pb->mp, MSG_ERROR);
150: *gbuf_rptr(pb->mp) = ENOTCONN;
151: gbuf_wset(pb->mp,1);
152: completepb(sp, pb);
153: return 0;
154: }
155:
156: pb->u.ioParams.actCount = 0; /* Set # of bytes so far to zero */
157: ATENABLE(s, sp->lock);
158:
159: FillSendQueue(sp, pb); /* Copy from write param block to send queue */
160:
161: CheckSend(sp); /* See if we should send anything */
162: return 0;
163:
164: }
165:
166: #ifdef notdef
167: int adsp_check = 1;
168:
169: CheckQueue(sp)
170: CCBPtr sp;
171: {
172: register gbuf_t *mp, *tmp;
173: unsigned char current;
174: int current_valid = 0;
175:
176: if (adsp_check == 0)
177: return;
178: if (mp = sp->sbuf_mb) {
179: current = *mp->b_rptr;
180: current_valid = 1;
181: while (mp) {
182: tmp = mp;
183: while (tmp) {
184: current = CheckData(tmp->b_rptr, tmp->b_wptr - tmp->b_rptr,
185: current);
186: tmp = tmp->b_cont;
187: }
188: mp = mp->b_next;
189: }
190: }
191: if (mp = sp->csbuf_mb) {
192: if (current_valid == 0)
193: current = *mp->b_rptr;
194: tmp = mp;
195: while (tmp) {
196: current = CheckData(tmp->b_rptr, tmp->b_wptr - tmp->b_rptr,
197: current);
198: tmp = tmp->b_cont;
199: }
200: }
201: }
202:
203:
204: int adsp_bad_block_count;
205: char *adsp_bad_block;
206:
207: CheckData(block, size, current)
208: char *block;
209: int size;
210: u_char current;
211: {
212: register int anError = 0;
213: register int i;
214:
215: for (i = 0; i < size; i++) {
216: if ((block[i] & 0xff) != (current & 0xff)) {
217: if (!anError) {
218: adsp_bad_block = block;
219: }
220: anError++;
221: }
222: current++;
223: }
224:
225: if (anError) {
226: adsp_bad_block_count++;
227: }
228: return current;
229: }
230: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.