Annotation of XNU/bsd/netat/adsp_Write.c, revision 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.