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