Annotation of XNU/bsd/netat/atp_read.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: /*
                     23:  *     Copyright (c) 1996-1998 Apple Computer, Inc.
                     24:  *     All Rights Reserved.
                     25:  */
                     26: 
                     27: /*    Modified for MP, 1996 by Tuyen Nguyen
                     28:  *   Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
                     29:  */
                     30: #include <sys/errno.h>
                     31: #include <sys/types.h>
                     32: #include <sys/param.h>
                     33: #include <machine/spl.h>
                     34: #include <sys/systm.h>
                     35: #include <sys/kernel.h>
                     36: #include <sys/proc.h>
                     37: #include <sys/filedesc.h>
                     38: #include <sys/fcntl.h>
                     39: #include <sys/mbuf.h>
                     40: #include <sys/ioctl.h>
                     41: #include <sys/malloc.h>
                     42: #include <sys/socket.h>
                     43: 
                     44: #include <netat/sysglue.h>
                     45: #include <netat/appletalk.h>
                     46: #include <netat/ddp.h>
                     47: #include <netat/at_pcb.h>
                     48: #include <netat/atp.h>
                     49: #include <netat/debug.h>
                     50: 
                     51: static void atp_trans_complete();
                     52: void atp_x_done();
                     53: extern void atp_req_timeout();
                     54: 
                     55: /*
                     56:  *     Decide what to do about received messages
                     57:  *     Version 1.7 of atp_read.c on 89/02/09 17:53:16
                     58:  */
                     59: 
                     60: void atp_treq_event(gref)
                     61: register gref_t *gref;
                     62: {
                     63:        register gbuf_t *m;
                     64:        register struct atp_state *atp;
                     65: 
                     66:        atp = (struct atp_state *)gref->info;   
                     67:        if (atp->dflag)
                     68:                atp = (struct atp_state *)atp->atp_msgq;
                     69: 
                     70:        if (atp->dflag) {
                     71:                if ((m = gbuf_alloc(sizeof(ioc_t), PRI_HI)) != NULL) {
                     72:                        gbuf_set_type(m, MSG_IOCTL);
                     73:                        gbuf_wset(m,sizeof(ioc_t));
                     74:                        ((ioc_t *)gbuf_rptr(m))->ioc_cmd = AT_ATP_GET_POLL;
                     75:                        atp_wput(gref, m);
                     76:                }
                     77:        }
                     78:        else if ((m = gbuf_alloc(1, PRI_HI)) != NULL) {
                     79:                *gbuf_rptr(m) = 0;
                     80:                gbuf_wset(m,1);
                     81:                atalk_putnext(gref, m);
                     82:        }
                     83: 
                     84:        if (m == 0)
                     85:                timeout(atp_treq_event, gref, 10);
                     86: }
                     87: 
                     88: void atp_rput(gref, m)
                     89: gref_t  *gref;
                     90: gbuf_t   *m;
                     91: {
                     92:        register at_atp_t *athp;
                     93:        register struct atp_state *atp;
                     94:        register int s, s_gen;
                     95:        gbuf_t *m_asp = NULL;
                     96: 
                     97:        atp = (struct atp_state *)gref->info;   
                     98:        if (atp->dflag)
                     99:                atp = (struct atp_state *)atp->atp_msgq;
                    100: 
                    101:        switch(gbuf_type(m)) {
                    102:        case MSG_DATA:
                    103:            /*
                    104:             *  Decode the message, make sure it is an atp
                    105:             *          message
                    106:             */
                    107:            if (((AT_DDP_HDR(m))->type != DDP_ATP) ||
                    108:                        (atp->atp_flags & ATP_CLOSING)) {
                    109:                gbuf_freem(m);
                    110:                dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR), 
                    111:                        ("atp_rput: dropping MSG, not atp\n"));
                    112:                break;
                    113:            }
                    114: 
                    115:            athp = AT_ATP_HDR(m);
                    116:            dPrintf(D_M_ATP_LOW, D_L_INPUT,
                    117:                    ("atp_rput MSG_DATA: %s (%d)\n", 
                    118:                    (athp->cmd == ATP_CMD_TRESP)? "TRESP":
                    119:                    (athp->cmd == ATP_CMD_TREL)? "TREL":
                    120:                    (athp->cmd == ATP_CMD_TREQ)? "TREQ": "unknown",
                    121:                    athp->cmd));
                    122:            trace_mbufs(D_M_ATP_LOW, "  r", m);
                    123: 
                    124:            switch (athp->cmd) {
                    125: 
                    126:            case ATP_CMD_TRESP:
                    127:            {   
                    128:                register struct atp_trans *trp;
                    129:                register int    seqno;
                    130:                register at_ddp_t       *ddp;
                    131: 
                    132:                /*
                    133:                 * we just got a response, find the trans record
                    134:                 */
                    135: 
                    136:                ATDISABLE(s, atp->atp_lock);
                    137:                for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) {
                    138:                    if (trp->tr_tid == UAS_VALUE(athp->tid))
                    139:                        break;
                    140:                }
                    141: 
                    142:                /*
                    143:                 *      If we can't find one then ignore the message
                    144:                 */
                    145:                seqno = athp->bitmap;
                    146:                if (trp == NULL) {
                    147:                ATENABLE(s, atp->atp_lock);
                    148:                ddp = AT_DDP_HDR(m);
                    149:                    dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR),
                    150:                ("atp_rput: dropping TRESP, no trp,tid=%d,loc=%d,rem=%d.%d,seqno=%d\n",
                    151:                            UAS_VALUE(athp->tid),
                    152:                            ddp->dst_socket,ddp->src_node,ddp->src_socket,seqno));
                    153:                    gbuf_freem(m);
                    154:                    return;
                    155:                }
                    156: 
                    157:                /*
                    158:                 * If no longer valid, drop it
                    159:                 */
                    160:                if (trp->tr_state == TRANS_FAILED) {
                    161:                ATENABLE(s, atp->atp_lock);
                    162:                ddp = AT_DDP_HDR(m);
                    163:                    dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR),
                    164:                ("atp_rput: dropping TRESP, failed trp,tid=%d,loc=%d,rem=%d.%d\n",
                    165:                            UAS_VALUE(athp->tid),
                    166:                            ddp->dst_socket, ddp->src_node, ddp->src_socket));
                    167:                    gbuf_freem(m);
                    168:                    return;
                    169:                }
                    170: 
                    171:                /*
                    172:                 * If we have already received it, ignore it
                    173:                 */
                    174:                if (!(trp->tr_bitmap&atp_mask[seqno]) || trp->tr_rcv[seqno]) {
                    175:                ATENABLE(s, atp->atp_lock);
                    176:                ddp = AT_DDP_HDR(m);
                    177:                    dPrintf(D_M_ATP_LOW, (D_L_INPUT|D_L_ERROR),
                    178:                ("atp_rput: dropping TRESP, duplicate,tid=%d,loc=%d,rem=%d.%d,seqno=%d\n",
                    179:                            UAS_VALUE(athp->tid),
                    180:                            ddp->dst_socket, ddp->src_node, ddp->src_socket, seqno));
                    181:                    gbuf_freem(m);
                    182:                    return;
                    183:                }
                    184: 
                    185:                /*
                    186:                 * Update the received packet bitmap
                    187:                 */
                    188:                if (athp->eom)
                    189:                    trp->tr_bitmap &= atp_lomask[seqno];
                    190:                else
                    191:                    trp->tr_bitmap &= ~atp_mask[seqno];
                    192: 
                    193:                /*
                    194:                 *      Save the message in the trans record
                    195:                 */
                    196:                trp->tr_rcv[seqno] = m;
                    197: 
                    198:                /*
                    199:                 *      If it isn't the first message then
                    200:                 *              can the header
                    201:                 */
                    202:                if (seqno)
                    203:                    gbuf_rinc(m,DDP_X_HDR_SIZE);
                    204: 
                    205:                /*
                    206:                 *      If we now have all the responses then return
                    207:                 *              the message to the user
                    208:                 */
                    209:                if (trp->tr_bitmap == 0) {
                    210:                    ATENABLE(s, atp->atp_lock);
                    211: 
                    212:                    /*
                    213:                     *  Cancel the request timer and any
                    214:                     *          pending transmits
                    215:                     */
                    216:                    atp_untimout(atp_req_timeout, trp);
                    217: 
                    218:                    /*
                    219:                     *  Send the results back to the user
                    220:                     */
                    221:                    atp_x_done(trp);
                    222:                    return;
                    223:                }
                    224:                if (athp->sts) {
                    225:                    /*
                    226:                     *  If they want treq again, send them
                    227:                     */
                    228:                    ATENABLE(s, atp->atp_lock);
                    229:                    atp_untimout(atp_req_timeout, trp);
                    230:                    atp_send(trp);
                    231:                    return;
                    232:                }
                    233:                ATENABLE(s, atp->atp_lock);
                    234:                return;
                    235:            }
                    236: 
                    237:            case ATP_CMD_TREL:
                    238:            {   register struct atp_rcb *rcbp;
                    239:                register at_ddp_t       *ddp;
                    240: 
                    241:                /*
                    242:                 *      Search for a matching transaction
                    243:                 */
                    244:                ddp = AT_DDP_HDR(m);
                    245: 
                    246:                ATDISABLE(s, atp->atp_lock);
                    247:                for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) {
                    248:                    if (rcbp->rc_tid == UAS_VALUE(athp->tid) &&
                    249:                        rcbp->rc_socket.node == ddp->src_node &&
                    250:                        rcbp->rc_socket.net == NET_VALUE(ddp->src_net) &&
                    251:                        rcbp->rc_socket.socket == ddp->src_socket) {
                    252:                            /*
                    253:                             *  Mark the rcb released
                    254:                             */
                    255:                            rcbp->rc_not_sent_bitmap = 0;
                    256:                            if (rcbp->rc_state == RCB_SENDING)
                    257:                                rcbp->rc_state = RCB_RELEASED;
                    258:                            else
                    259:                                {
                    260:                                ddp = 0;
                    261:                                atp_rcb_free(rcbp);
                    262:                                ATENABLE(s, atp->atp_lock);
                    263:                                }
                    264:                            break;
                    265:                    }
                    266:                }
                    267: 
                    268:                if (ddp)
                    269:                        ATENABLE(s, atp->atp_lock);
                    270:                gbuf_freem(m);
                    271:                return;
                    272:           }
                    273: 
                    274: 
                    275:           case ATP_CMD_TREQ:
                    276:           {    register struct atp_rcb *rcbp;
                    277:                register at_ddp_t       *ddp;
                    278:                gbuf_t                  *m2;
                    279: 
                    280:                /*
                    281:                 *      If it is a request message, first 
                    282:                 *      check to see
                    283:                 *      if matches something in our active
                    284:                 *      request queue
                    285:                 */
                    286:                ddp = AT_DDP_HDR(m);
                    287: 
                    288:                ATDISABLE(s, atp->atp_lock);
                    289:                for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) {
                    290:                    if (rcbp->rc_tid == UAS_VALUE(athp->tid) &&
                    291:                        rcbp->rc_socket.node == ddp->src_node &&
                    292:                        rcbp->rc_socket.net == NET_VALUE(ddp->src_net) &&
                    293:                        rcbp->rc_socket.socket == ddp->src_socket)
                    294:                        break;
                    295:                }
                    296:                /*
                    297:                 *      If this is a new req then do 
                    298:                 *      something with it
                    299:                 */
                    300:                if (rcbp == NULL) {
                    301:                    /*
                    302:                     * see if it matches something in the
                    303:                     * attached request queue
                    304:                     * if it does, just release the message
                    305:                     * and go on about our buisness
                    306:                     */
                    307:                                        /* we just did this, why do again? -jjs 4-10-95 */
                    308:                    for (rcbp = atp->atp_attached.head; rcbp; rcbp = rcbp->rc_list.next) {
                    309:                        if (rcbp->rc_tid == UAS_VALUE(athp->tid) &&
                    310:                            rcbp->rc_socket.node == ddp->src_node &&
                    311:                            rcbp->rc_socket.net == NET_VALUE(ddp->src_net) &&
                    312:                            rcbp->rc_socket.socket == ddp->src_socket) {
                    313:                            ATENABLE(s, atp->atp_lock);
                    314:                            gbuf_freem(m);
                    315:                            dPrintf(D_M_ATP_LOW, D_L_INPUT, 
                    316:                                    ("atp_rput: dropping TREQ, matches req queue\n"));
                    317:                            return;
                    318:                        }
                    319:                    }
                    320: 
                    321:                        /*
                    322:                         * assume someone is interested in 
                    323:                         * in an asynchronous incoming request
                    324:                         */
                    325:                        ATENABLE(s, atp->atp_lock);
                    326:                        if ((rcbp = atp_rcb_alloc(atp)) == NULL) {
                    327:                            gbuf_freem(m);
                    328:                            return;
                    329:                        }
                    330:                        rcbp->rc_state = RCB_UNQUEUED;
                    331:                        ATDISABLE(s, atp->atp_lock);
                    332: 
                    333:                    rcbp->rc_local_node = ddp->dst_node;
                    334:                    NET_NET(rcbp->rc_local_net, ddp->dst_net);
                    335:                    rcbp->rc_socket.socket = ddp->src_socket;
                    336:                    rcbp->rc_socket.node = ddp->src_node;
                    337:                    rcbp->rc_socket.net = NET_VALUE(ddp->src_net);
                    338:                    rcbp->rc_tid = UAS_VALUE(athp->tid);
                    339:                    rcbp->rc_bitmap = athp->bitmap;
                    340:                    rcbp->rc_not_sent_bitmap = athp->bitmap;
                    341:                    rcbp->rc_xo = athp->xo;
                    342:                    /*
                    343:                     *  if async then send it as
                    344:                     *          data
                    345:                     *  otherwise, it is a synchronous ioctl so
                    346:                     *          complete it
                    347:                     */
                    348:                        if (atp->dflag) { /* for ASP? */
                    349:                          if ((m2 = gbuf_alloc(sizeof(ioc_t), PRI_HI))) {
                    350:                            gbuf_set_type(m2, MSG_DATA);
                    351:                            gbuf_wset(m2,sizeof(ioc_t));
                    352:                            ((ioc_t *)gbuf_rptr(m2))->ioc_cmd = AT_ATP_GET_POLL;
                    353:                            m_asp = m2;
                    354:                          }
                    355:                        } else if ((m2 = gbuf_alloc(1, PRI_HI))) {
                    356:                            *gbuf_rptr(m2) = 0;
                    357:                            gbuf_wset(m2,1);
                    358:                            atalk_putnext(gref, m2);
                    359:                        }
                    360:                        if (m2 == 0) {
                    361:                                dPrintf(D_M_ATP,D_L_WARNING,
                    362:                                        ("atp_rput: out of buffer for TREQ\n"));
                    363:                                timeout(atp_treq_event, gref, 10);
                    364:                        }
                    365:                        rcbp->rc_ioctl = m;
                    366: 
                    367:                        /*
                    368:                         *      move it to the attached list
                    369:                         */
                    370:                        dPrintf(D_M_ATP_LOW, D_L_INPUT, 
                    371:                                ("atp_rput: moving to attached list\n"));
                    372:                        rcbp->rc_state = RCB_PENDING;
                    373:                        ATP_Q_APPEND(atp->atp_attached, rcbp, rc_list);
                    374:                        if (m_asp != NULL) {
                    375:                            ATENABLE(s, atp->atp_lock);
                    376:                            atp_req_ind(atp, m_asp);
                    377:                            return;
                    378:                        }
                    379:                } else {
                    380:                    dPrintf(D_M_ATP_LOW, D_L_INPUT, 
                    381:                            ("atp_rput: found match, state:%d\n",
                    382:                            rcbp->rc_state));
                    383: 
                    384:                    /*
                    385:                     *  Otherwise we have found a matching request
                    386:                     *          look for what to do
                    387:                     */
                    388:                    switch (rcbp->rc_state) {
                    389:                    case RCB_RESPONDING:
                    390:                    case RCB_RESPONSE_FULL:
                    391:                        /*
                    392:                         *      If it is one we have in progress 
                    393:                         *              (either have all the responses
                    394:                         *              or are waiting for them)
                    395:                         *              update the bitmap and resend
                    396:                         *              the replies
                    397:                         */
                    398:                        ATDISABLE(s_gen, atpgen_lock);
                    399:                        if (rcbp->rc_timestamp) {
                    400:                          rcbp->rc_timestamp = time.tv_sec;
                    401:                          if (rcbp->rc_timestamp == 0)
                    402:                            rcbp->rc_timestamp = 1;
                    403:                        }
                    404:                        ATENABLE(s_gen, atpgen_lock);
                    405:                        rcbp->rc_bitmap = athp->bitmap;
                    406:                        rcbp->rc_not_sent_bitmap = athp->bitmap;
                    407:                        ATENABLE(s, atp->atp_lock);
                    408:                        gbuf_freem(m);
                    409:                        atp_reply(rcbp);
                    410:                        return;
                    411: 
                    412:                    case RCB_RELEASED:
                    413:                    default:
                    414:                        /*
                    415:                         *      If we have a release or
                    416:                         *      we haven't sent any data yet
                    417:                         *      ignore the request
                    418:                         */
                    419:                        ATENABLE(s, atp->atp_lock);
                    420:                        gbuf_freem(m);
                    421:                        return;
                    422:                    }
                    423:                }
                    424:                ATENABLE(s, atp->atp_lock);
                    425:                return;
                    426:           }
                    427: 
                    428:            default:
                    429:                gbuf_freem(m);
                    430:                break;
                    431:           }      
                    432:           break;
                    433: 
                    434:        case MSG_IOCACK:
                    435:                if (atp->dflag)
                    436:                        asp_ack_reply(gref, m);
                    437:                else
                    438:                        atalk_putnext(gref, m);
                    439:                break;
                    440: 
                    441:        case MSG_IOCNAK:
                    442:                if (atp->dflag)
                    443:                        asp_nak_reply(gref, m);
                    444:                else
                    445:                        atalk_putnext(gref, m);
                    446:                break;
                    447: 
                    448:        default:
                    449:                gbuf_freem(m);
                    450:        }
                    451: } /* atp_rput */
                    452: 
                    453: void
                    454: atp_x_done(trp)
                    455: register struct atp_trans *trp;
                    456: {
                    457:        struct atp_state *atp;
                    458:         gbuf_t  *m;
                    459: 
                    460:        if ( !trp->tr_xo)
                    461:                atp_trans_complete(trp);
                    462:        else {
                    463:                /*
                    464:                 *      If execute once send a release
                    465:                 */
                    466:                if ((m = (gbuf_t *)atp_build_release(trp)) != NULL) {
                    467:                        AT_DDP_HDR(m)->src_socket = ((struct atp_state *)
                    468:                            trp->tr_queue)->atp_socket_no;
                    469:                        DDP_OUTPUT(m);
                    470:                        /*
                    471:                         *      Now send back the transaction reply to the process
                    472:                         *              or notify the process if required
                    473:                         */
                    474:                        atp_trans_complete(trp);
                    475:                } else {
                    476: 
                    477:                        atp = trp->tr_queue;
                    478:                        trp->tr_state = TRANS_RELEASE;
                    479:                        timeout(atp_x_done, trp, 10);
                    480:                }
                    481:        }
                    482: }
                    483: 
                    484: static void
                    485: atp_trans_complete(trp) 
                    486: register struct atp_trans *trp;
                    487: {      register gbuf_t *m;
                    488:        register int    type;
                    489:        struct atp_state *atp;
                    490: 
                    491:        /* we could gbuf_freem(trp->tr_xmt) here if were not planning to
                    492:           re-use the mbuf later */
                    493:        m = trp->tr_xmt;               
                    494:        trp->tr_xmt = NULL;
                    495:        trp->tr_state = TRANS_DONE;
                    496: 
                    497:        if (gbuf_cont(m) == NULL)  /* issued via the new interface */
                    498:                type = AT_ATP_ISSUE_REQUEST_NOTE;
                    499:        else {
                    500:                type = ((ioc_t *)(gbuf_rptr(m)))->ioc_cmd;
                    501:                /*
                    502:                 * free any data following the ioctl blk
                    503:                 */
                    504:                gbuf_freem(gbuf_cont(m));
                    505:                gbuf_cont(m) = NULL;
                    506:        }
                    507:        dPrintf(D_M_ATP_LOW, D_L_INPUT, ("atp_trans_comp: trp=0x%x type = %s\n", 
                    508:                (u_int) trp,
                    509:                (type==AT_ATP_ISSUE_REQUEST)? "AT_ATP_ISSUE_REQUEST":
                    510:                (type==AT_ATP_ISSUE_REQUEST_NOTE)? "AT_ATP_ISSUE_REQUEST_NOTE" :
                    511:                "unknown"));
                    512: 
                    513:        switch(type) {
                    514:        case AT_ATP_ISSUE_REQUEST:
                    515:         atp = trp->tr_queue;
                    516:         if (atp->dflag) {
                    517:                ((ioc_t *)gbuf_rptr(m))->ioc_count = 0;
                    518:                ((ioc_t *)gbuf_rptr(m))->ioc_error = 0;
                    519:                ((ioc_t *)gbuf_rptr(m))->ioc_rval = trp->tr_tid;
                    520:                ((ioc_t *)gbuf_rptr(m))->ioc_cmd = AT_ATP_REQUEST_COMPLETE;
                    521:                gbuf_set_type(m, MSG_IOCTL);
                    522:                atp_rsp_ind(trp, m);
                    523:         } else {
                    524:          if (trp->tr_bdsp == NULL) {
                    525:                gbuf_freem(m);
                    526:                if (trp->tr_rsp_wait)
                    527:                        thread_wakeup(&trp->tr_event);
                    528:          } else {
                    529:                gbuf_set_type(m, MSG_IOCACK);
                    530:                ((ioc_t *)gbuf_rptr(m))->ioc_count = 0;
                    531:                ((ioc_t *)gbuf_rptr(m))->ioc_error = 0;
                    532:                ((ioc_t *)gbuf_rptr(m))->ioc_rval = 0;
                    533:                atalk_putnext(trp->tr_queue->atp_gref, m);
                    534:          }
                    535:         }
                    536:         break;
                    537: 
                    538:        case AT_ATP_ISSUE_REQUEST_NOTE:
                    539:                gbuf_wset(m,1);
                    540:                *gbuf_rptr(m) = 1;
                    541:                gbuf_set_type(m, MSG_DATA);
                    542:                atalk_putnext(trp->tr_queue->atp_gref, m);
                    543:                break;
                    544:        }
                    545: } /* atp_trans_complete */

unix.superglobalmegacorp.com

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