|
|
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.