Annotation of XNU/bsd/netat/adsp_Write.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.