Annotation of kernel/bsd/netat/atp_read.c, revision 1.1.1.1

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