]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netat/atp_write.c
xnu-792.17.14.tar.gz
[apple/xnu.git] / bsd / netat / atp_write.c
index 4c510abe1aad3309e0f694096951e4f4e00c4ecf..34d18be4bc998019682cf421d7afb5d61d1123e3 100644 (file)
@@ -1,23 +1,29 @@
 /*
  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  *     Copyright (c) 1996-1998 Apple Computer, Inc.
@@ -74,6 +80,9 @@ extern struct atp_rcb_qhead atp_need_rel;
 extern int atp_inited;
 extern struct atp_state *atp_used_list;
 extern asp_scb_t *scb_free_list;
+extern atlock_t atpgen_lock;
+extern atlock_t atpall_lock;
+extern atlock_t atptmo_lock;
 
 extern gbuf_t *scb_resource_m;
 extern gbuf_t *atp_resource_m;
@@ -136,7 +145,7 @@ atp_wput(gref, m)
        register gbuf_t *m;
 {
        register ioc_t    *iocbp;
-       int i, xcnt;
+       int i, xcnt, s;
        struct atp_state *atp;
        struct atp_trans *trp;
        struct atp_rcb   *rcbp;
@@ -234,16 +243,18 @@ atp_wput(gref, m)
                                atp->atp_msgq = 0;
                        }
 
+                       ATDISABLE(s, atp->atp_lock);
                        /*
                         *      search for the corresponding rcb
                         */
                        for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) {
-                           if (rcbp->rc_tid == UAS_VALUE_NTOH(athp->tid) &&
+                           if (rcbp->rc_tid == UAS_VALUE(athp->tid) &&
                                rcbp->rc_socket.node == ddp->dst_node &&
                                rcbp->rc_socket.net == NET_VALUE(ddp->dst_net) &&
                                rcbp->rc_socket.socket == ddp->dst_socket)
                                break;
                        }
+                       ATENABLE(s, atp->atp_lock);
 
                        /*
                         *      If it has already been sent then return an error
@@ -264,11 +275,13 @@ atp_wput(gref, m)
                            rcbp->rc_socket.socket = ddp->dst_socket;
                            rcbp->rc_socket.node = ddp->dst_node;
                            rcbp->rc_socket.net = NET_VALUE(ddp->dst_net);
-                           rcbp->rc_tid = UAS_VALUE_NTOH(athp->tid);
+                           rcbp->rc_tid = UAS_VALUE(athp->tid);
                            rcbp->rc_bitmap = 0xff;
                            rcbp->rc_xo = 0;
+                           ATDISABLE(s, atp->atp_lock);
                            rcbp->rc_state = RCB_SENDING;
                            ATP_Q_APPEND(atp->atp_rcb, rcbp, rc_list);
+                           ATENABLE(s, atp->atp_lock);
                        }
                        xcnt = get_bds_entries(m2);
                        if ((i = atp_unpack_bdsp(atp, m2, rcbp, xcnt, FALSE))) {
@@ -296,6 +309,7 @@ atp_wput(gref, m)
                        /*
                         *      search for a waiting request
                         */
+                       ATDISABLE(s, atp->atp_lock);
                        if ((rcbp = atp->atp_attached.head)) {
                            /*
                             *  Got one, move it to the active response Q
@@ -312,11 +326,13 @@ atp_wput(gref, m)
                                 */
                                atp_rcb_free(rcbp);
                            }
+                           ATENABLE(s, atp->atp_lock);
                            atp_iocack(atp, m);
                        } else {
                                /*
                                 *      None available - can out
                                 */
+                               ATENABLE(s, atp->atp_lock);
                                atp_iocnak(atp, m, EAGAIN);
                        }
                        break;
@@ -333,13 +349,16 @@ atp_wput(gref, m)
                        i = *(int *)gbuf_rptr(gbuf_cont(m));
                        gbuf_freem(gbuf_cont(m));
                        gbuf_cont(m) = NULL;
+                       ATDISABLE(s, atp->atp_lock);
                        for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) {
                          if (trp->tr_tid == i)
                                break;
                        }
-                       if (trp == NULL)
+                       if (trp == NULL) {
+                               ATENABLE(s, atp->atp_lock);
                                atp_iocnak(atp, m, ENOENT);
-                       else {
+                       } else {
+                               ATENABLE(s, atp->atp_lock);
                                atp_free(trp);
                                atp_iocack(atp, m);
                        }
@@ -417,7 +436,7 @@ register struct atp_trans *trp;
                gbuf_wset(m,TOTAL_ATP_HDR_SIZE);
                ddp = AT_DDP_HDR(m);
                ddp->type = DDP_ATP;
-               UAS_ASSIGN_HTON(ddp->checksum, 0);
+               UAS_ASSIGN(ddp->checksum, 0);
                ddp->dst_socket = trp->tr_socket.socket;
                ddp->dst_node = trp->tr_socket.node;
                NET_ASSIGN(ddp->dst_net, trp->tr_socket.net);
@@ -430,7 +449,7 @@ register struct atp_trans *trp;
                athp = AT_ATP_HDR(m);
                ATP_CLEAR_CONTROL(athp);
                athp->cmd = ATP_CMD_TREL;
-               UAS_ASSIGN_HTON(athp->tid, trp->tr_tid);
+               UAS_ASSIGN(athp->tid, trp->tr_tid);
        }
 
        return (m);
@@ -441,7 +460,7 @@ void atp_send_replies(atp, rcbp)
      register struct atp_rcb   *rcbp;
 {       register gbuf_t *m;
        register int     i, len;
-       int              s_gen, cnt, err, offset, space;
+       int              s_gen, s, cnt, err, offset, space;
        unsigned char *m0_rptr = NULL, *m0_wptr = NULL;
        register at_atp_t *athp;
        register struct atpBDS *bdsp;
@@ -455,8 +474,11 @@ void atp_send_replies(atp, rcbp)
        };
        struct timeval timenow;
 
-       if (rcbp->rc_queue != atp)
+       ATDISABLE(s, atp->atp_lock);
+       if (rcbp->rc_queue != atp) {
+               ATENABLE(s, atp->atp_lock);
                return;
+       }
        if (rcbp->rc_not_sent_bitmap == 0)
                goto nothing_to_send;
 
@@ -544,17 +566,21 @@ void atp_send_replies(atp, rcbp)
                 */
                bdsp++;
        }
-       if (mlist)
+       if (mlist) {
+               ATENABLE(s, atp->atp_lock);
                DDP_OUTPUT(mlist);
-       
+               ATDISABLE(s, atp->atp_lock);
+       }
 
 nothing_to_send:
        /*
         *      If all replies from this reply block have been sent then 
         *              remove it from the queue and mark it so
         */
-       if (rcbp->rc_queue != atp)
+       if (rcbp->rc_queue != atp) {
+               ATENABLE(s, atp->atp_lock);
                return;
+       }
        rcbp->rc_rep_waiting = 0;
 
        /*
@@ -569,6 +595,7 @@ nothing_to_send:
         */
        if (rcbp->rc_xo && rcbp->rc_state != RCB_RELEASED) {
                getmicrouptime(&timenow);
+               ATDISABLE(s_gen, atpgen_lock);
                if (rcbp->rc_timestamp == 0) {
                        rcbp->rc_timestamp = timenow.tv_sec;
                        if (rcbp->rc_timestamp == 0)
@@ -576,8 +603,10 @@ nothing_to_send:
                        ATP_Q_APPEND(atp_need_rel, rcbp, rc_tlist);
                }
                rcbp->rc_state = RCB_RESPONSE_FULL;
+               ATENABLE(s_gen, atpgen_lock);
        } else
                atp_rcb_free(rcbp);
+       ATENABLE(s, atp->atp_lock);
 } /* atp_send_replies */
 
 
@@ -665,7 +694,7 @@ atp_unpack_bdsp(atp, m, rcbp, cnt, wait)
        register         gbuf_t        *m2, *m1, *m0, *mhdr;
        caddr_t         lastPage;
     at_atp_t    *athp;
-       int             i, len;
+       int             i, len, s_gen;
        at_socket       src_socket;
        
        struct ddp_atp {
@@ -811,11 +840,13 @@ atp_unpack_bdsp(atp, m, rcbp, cnt, wait)
 l_send:
        if (rcbp->rc_xo) {
                getmicrouptime(&timenow);
+               ATDISABLE(s_gen, atpgen_lock);
                if (rcbp->rc_timestamp == 0) {
                        if ((rcbp->rc_timestamp = timenow.tv_sec) == 0)
                                rcbp->rc_timestamp = 1;
                        ATP_Q_APPEND(atp_need_rel, rcbp, rc_tlist);
                }
+               ATENABLE(s_gen, atpgen_lock);
        }
 
        DDP_OUTPUT(mlist);
@@ -837,6 +868,7 @@ int atp_bind(gref, sVal, flag)
        unsigned char inpC, sNextUsed = 0;
        unsigned int sMin, sMax, sSav;
        struct atp_state *atp;
+       int s;
 
        atp = (struct atp_state *)gref->info;
        if (atp->dflag)
@@ -844,6 +876,7 @@ int atp_bind(gref, sVal, flag)
 
        sMax = ATP_SOCKET_LAST;
        sMin = ATP_SOCKET_FIRST;
+       ATDISABLE(s, atpgen_lock);
        if (flag && (*flag == 3)) {
                sMin += 40;
                if (sMin < sNext) {
@@ -856,6 +889,7 @@ int atp_bind(gref, sVal, flag)
             ((sVal > sMax) || (sVal < 2) || (sVal == 6) || 
              (ddp_socket_inuse(sVal, DDP_ATP) &&
               (atp_inputQ[sVal] != (gref_t *)1)))) {
+               ATENABLE(s, atpgen_lock);
                return 0;
        }
 
@@ -885,6 +919,7 @@ again:
                                sNext = 0;
                                *flag = (unsigned char)sSav;
                        }
+                       ATENABLE(s, atpgen_lock);
                        return 0;
                }
        }
@@ -898,6 +933,7 @@ again:
                        sNext = 0;
        }
 
+       ATENABLE(s, atpgen_lock);
        return (int)sVal;
 }
 
@@ -906,16 +942,19 @@ void atp_req_ind(atp, mioc)
        register gbuf_t *mioc;
 {
        register struct atp_rcb *rcbp;
+       int s;
 
        if ((rcbp = atp->atp_attached.head) != 0) {
                gbuf_cont(mioc) = rcbp->rc_ioctl;
                rcbp->rc_ioctl = NULL;
+               ATDISABLE(s, atp->atp_lock);
                if (rcbp->rc_xo) {
                        ATP_Q_REMOVE(atp->atp_attached, rcbp, rc_list);
                        rcbp->rc_state = RCB_NOTIFIED;
                        ATP_Q_APPEND(atp->atp_rcb, rcbp, rc_list);
                } else
                        atp_rcb_free(rcbp);
+               ATENABLE(s, atp->atp_lock);
                if (gbuf_cont(mioc))
                  ((ioc_t *)gbuf_rptr(mioc))->ioc_count = gbuf_msgsize(gbuf_cont(mioc));
                else
@@ -968,6 +1007,7 @@ void atp_cancel_req(gref, tid)
        gref_t *gref;
        unsigned short tid;
 {
+       int s;
        struct atp_state *atp;
        struct atp_trans *trp;
 
@@ -975,10 +1015,12 @@ void atp_cancel_req(gref, tid)
        if (atp->dflag)
                atp = (struct atp_state *)atp->atp_msgq;
 
+       ATDISABLE(s, atp->atp_lock);
        for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) {
            if (trp->tr_tid == tid)
                        break;
        }
+       ATENABLE(s, atp->atp_lock);
        if (trp != NULL)
                atp_free(trp);
 }
@@ -990,7 +1032,9 @@ void
 atp_dequeue_atp(atp)
        struct atp_state *atp;
 {
+       int s;
 
+       ATDISABLE(s, atpall_lock);
        if (atp == atp_used_list) {
                if ((atp_used_list = atp->atp_trans_waiting) != 0)
                        atp->atp_trans_waiting->atp_rcb_waiting = 0;
@@ -1002,6 +1046,7 @@ atp_dequeue_atp(atp)
 
        atp->atp_trans_waiting = 0;
        atp->atp_rcb_waiting = 0;
+       ATENABLE(s, atpall_lock);
 }
 
 void
@@ -1010,11 +1055,15 @@ atp_timout(func, trp, ticks)
        struct atp_trans *trp;
        int ticks;
 {
+       int s;
        unsigned int sum;
        struct atp_trans *curr_trp, *prev_trp;
 
-       if (trp->tr_tmo_func)
+       ATDISABLE(s, atptmo_lock);
+       if (trp->tr_tmo_func) {
+               ATENABLE(s, atptmo_lock);
                return;
+       }
 
        trp->tr_tmo_func = func;
        trp->tr_tmo_delta = 1+(ticks>>5);
@@ -1022,6 +1071,7 @@ atp_timout(func, trp, ticks)
        if (trp_tmo_list == 0) {
                trp->tr_tmo_next = trp->tr_tmo_prev = 0;
                trp_tmo_list = trp;
+               ATENABLE(s, atptmo_lock);
                return;
        }
 
@@ -1055,6 +1105,7 @@ atp_timout(func, trp, ticks)
                trp_tmo_list->tr_tmo_prev = trp;
                trp_tmo_list = trp;
        }
+       ATENABLE(s, atptmo_lock);
 }
 
 void
@@ -1062,9 +1113,13 @@ atp_untimout(func, trp)
        void (*func)();
        struct atp_trans *trp;
 {
+       int s;
 
-       if (trp->tr_tmo_func == 0)
+       ATDISABLE(s, atptmo_lock);
+       if (trp->tr_tmo_func == 0) {
+               ATENABLE(s, atptmo_lock);
                return;
+       }
 
        if (trp_tmo_list == trp) {
                if ((trp_tmo_list = trp->tr_tmo_next) != 0) {
@@ -1078,6 +1133,7 @@ atp_untimout(func, trp)
                }
        }
        trp->tr_tmo_func = 0;
+       ATENABLE(s, atptmo_lock);
 }
 
 void
@@ -1093,9 +1149,11 @@ void
 atp_trp_clock(arg)
        void *arg;
 {
+       int s;
        struct atp_trans *trp;
        void (*tr_tmo_func)();
 
+       ATDISABLE(s, atptmo_lock);
        if (trp_tmo_list)
                trp_tmo_list->tr_tmo_delta--;
        while (((trp = trp_tmo_list) != 0) && (trp_tmo_list->tr_tmo_delta == 0)) {
@@ -1103,9 +1161,12 @@ atp_trp_clock(arg)
                        trp_tmo_list->tr_tmo_prev = 0;
                if ((tr_tmo_func = trp->tr_tmo_func) != 0) {
                        trp->tr_tmo_func = 0;
+                       ATENABLE(s, atptmo_lock);
                        (*tr_tmo_func)(trp);
+                       ATDISABLE(s, atptmo_lock);
                }
        }
+       ATENABLE(s, atptmo_lock);
 
        timeout(atp_trp_clock_locked, (void *)arg, (1<<5));
 }
@@ -1122,9 +1183,8 @@ atp_send_req(gref, mioc)
        register at_ddp_t *ddp;
        gbuf_t *m, *m2, *bds;
        struct atp_set_default *sdb;
-       int old;
+       int s, old;
        unsigned int timer;
-       u_short         temp_net;
 
        atp = (struct atp_state *)((struct atp_state *)gref->info)->atp_msgq;
        iocbp = (ioc_t *)gbuf_rptr(mioc);
@@ -1172,7 +1232,7 @@ l_retry:
         */
        athp = AT_ATP_HDR(m2);
        athp->cmd = ATP_CMD_TREQ;
-       UAS_ASSIGN_HTON(athp->tid, trp->tr_tid);
+       UAS_ASSIGN(athp->tid, trp->tr_tid);
        athp->eom = 0;
        athp->sts = 0;
        trp->tr_xo = athp->xo;
@@ -1185,8 +1245,7 @@ l_retry:
        trp->tr_socket.net = NET_VALUE(ddp->dst_net);
        trp->tr_local_socket = atp->atp_socket_no;
        trp->tr_local_node = ddp->src_node;
-       temp_net = NET_VALUE(ddp->src_net);
-       NET_ASSIGN_NOSWAP(trp->tr_local_net, temp_net);
+       NET_NET(trp->tr_local_net, ddp->src_net);
 
 #ifdef NOT_YET
        /* save the local information in the gref */
@@ -1199,7 +1258,9 @@ l_retry:
        /*
         *      Put us in the transaction waiting queue
         */
+       ATDISABLE(s, atp->atp_lock);
        ATP_Q_APPEND(atp->atp_trans_wait, trp, tr_list);
+       ATENABLE(s, atp->atp_lock);
 
        /*
         * Send the message and set the timer   
@@ -1241,7 +1302,6 @@ void atp_send_rsp(gref, m, wait)
        register at_atp_t *athp;
        register at_ddp_t *ddp;
        int s, xcnt;
-       u_short temp_net;
 
        atp = (struct atp_state *)gref->info;
        if (atp->dflag)
@@ -1252,8 +1312,9 @@ void atp_send_rsp(gref, m, wait)
        /*
         *      search for the corresponding rcb
         */
+       ATDISABLE(s, atp->atp_lock);
        for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) {
-           if ( (rcbp->rc_tid == UAS_VALUE_NTOH(athp->tid)) &&
+           if ( (rcbp->rc_tid == UAS_VALUE(athp->tid)) &&
                        (rcbp->rc_socket.node == ddp->dst_node) &&
                        (rcbp->rc_socket.net == NET_VALUE(ddp->dst_net)) &&
                        (rcbp->rc_socket.socket == ddp->dst_socket) )
@@ -1265,9 +1326,11 @@ void atp_send_rsp(gref, m, wait)
         */
        if ((rcbp && (rcbp->rc_state != RCB_NOTIFIED)) ||
                        (rcbp == NULL && athp->xo) ) {
+               ATENABLE(s, atp->atp_lock);
                gbuf_freem(m);
                return;
        }
+       ATENABLE(s, atp->atp_lock);
 
        if (rcbp == NULL) { /* a response is being sent for an ALO transaction */
            if ((rcbp = atp_rcb_alloc(atp)) == NULL) {
@@ -1278,15 +1341,16 @@ void atp_send_rsp(gref, m, wait)
            rcbp->rc_socket.socket = ddp->dst_socket;
            rcbp->rc_socket.node = ddp->dst_node;
            rcbp->rc_socket.net = NET_VALUE(ddp->dst_net);
-           rcbp->rc_tid = UAS_VALUE_NTOH(athp->tid);
+           rcbp->rc_tid = UAS_VALUE(athp->tid);
            rcbp->rc_bitmap = 0xff;
            rcbp->rc_xo = 0;
            rcbp->rc_state = RCB_RESPONSE_FULL;
+           ATDISABLE(s, atp->atp_lock);
            ATP_Q_APPEND(atp->atp_rcb, rcbp, rc_list);
+               ATENABLE(s, atp->atp_lock);
        }
        else if (ddp->src_node == 0) {
-               temp_net = NET_VALUE_NOSWAP(rcbp->rc_local_net);
-               NET_ASSIGN(ddp->src_net, temp_net);
+               NET_NET(ddp->src_net, rcbp->rc_local_net);
                ddp->src_node = rcbp->rc_local_node;
        }
 
@@ -1384,7 +1448,7 @@ _ATPsndreq(fd, buf, len, nowait, err, proc)
        void *proc;
 {
        gref_t *gref;
-       int rc;
+       int s, rc;
        unsigned short tid;
        unsigned int timer;
        register struct atp_state *atp;
@@ -1408,6 +1472,13 @@ _ATPsndreq(fd, buf, len, nowait, err, proc)
                return -1;
        }
 
+       if (len < atpBDSsize + sizeof(struct atp_set_default) + TOTAL_ATP_HDR_SIZE ||
+               len > atpBDSsize + sizeof(struct atp_set_default) + TOTAL_ATP_HDR_SIZE + 
+               ATP_DATA_SIZE) {
+               file_drop(fd);
+               *err = EINVAL;
+               return -1;
+       }
 
        while ((mioc = gbuf_alloc(sizeof(ioc_t), PRI_MED)) == 0) {
                struct timespec ts;
@@ -1415,7 +1486,9 @@ _ATPsndreq(fd, buf, len, nowait, err, proc)
                ts.tv_sec = 0;
                ts.tv_nsec = 100 *1000 * NSEC_PER_USEC;
 
+               ATDISABLE(s, atp->atp_delay_lock);
                rc = msleep(&atp->atp_delay_event, atalk_mutex, PSOCK | PCATCH, "atpmioc", &ts);
+               ATENABLE(s, atp->atp_delay_lock);
                if (rc != 0) {
                        *err = rc;
                        file_drop(fd);
@@ -1431,7 +1504,9 @@ _ATPsndreq(fd, buf, len, nowait, err, proc)
         ts.tv_sec = 0;
         ts.tv_nsec = 100 *1000 * NSEC_PER_USEC;
 
+               ATDISABLE(s, atp->atp_delay_lock);
                rc = msleep(&atp->atp_delay_event, atalk_mutex, PSOCK | PCATCH, "atpm2", &ts);
+               ATENABLE(s, atp->atp_delay_lock);
                if (rc != 0) {
                        gbuf_freeb(mioc);
                        file_drop(fd);
@@ -1472,7 +1547,9 @@ _ATPsndreq(fd, buf, len, nowait, err, proc)
         ts.tv_sec = 0;
         ts.tv_nsec = 100 *1000 * NSEC_PER_USEC;
 
+               ATDISABLE(s, atp->atp_delay_lock);
                rc = msleep(&atp->atp_delay_event, atalk_mutex, PSOCK | PCATCH, "atptrp", &ts);
+               ATENABLE(s, atp->atp_delay_lock);
                if (rc != 0) {
                        gbuf_freem(mioc);
                        file_drop(fd);
@@ -1498,7 +1575,7 @@ _ATPsndreq(fd, buf, len, nowait, err, proc)
         */
        athp = AT_ATP_HDR(m2);
        athp->cmd = ATP_CMD_TREQ;
-       UAS_ASSIGN_HTON(athp->tid, trp->tr_tid);
+       UAS_ASSIGN(athp->tid, trp->tr_tid);
        athp->eom = 0;
        athp->sts = 0;
        trp->tr_xo = athp->xo;
@@ -1523,7 +1600,9 @@ _ATPsndreq(fd, buf, len, nowait, err, proc)
        /*
         *      Put us in the transaction waiting queue
         */
+       ATDISABLE(s, atp->atp_lock);
        ATP_Q_APPEND(atp->atp_trans_wait, trp, tr_list);
+       ATENABLE(s, atp->atp_lock);
 
        /*
         * Send the message and set the timer   
@@ -1544,18 +1623,21 @@ _ATPsndreq(fd, buf, len, nowait, err, proc)
        /*
         * wait for the transaction to complete
         */
+       ATDISABLE(s, trp->tr_lock);
        while ((trp->tr_state != TRANS_DONE) && (trp->tr_state != TRANS_FAILED) &&
                                (trp->tr_state != TRANS_ABORTING)) {
                trp->tr_rsp_wait = 1;
                rc = msleep(&trp->tr_event, atalk_mutex, PSOCK | PCATCH, "atpsndreq", 0);
                if (rc != 0) {
                        trp->tr_rsp_wait = 0;
+                       ATENABLE(s, trp->tr_lock);
                        file_drop(fd);
                        *err = rc;
                        return -1;
                }
        }
        trp->tr_rsp_wait = 0;
+       ATENABLE(s, trp->tr_lock);
 
 
        if (trp->tr_state == TRANS_FAILED || trp->tr_state == TRANS_ABORTING) {
@@ -1638,6 +1720,11 @@ _ATPsndrsp(fd, respbuff, resplen, datalen, err, proc)
        /*
         * allocate buffer and copy in the response info
         */
+       if (resplen < 0 || resplen > TOTAL_ATP_HDR_SIZE + sizeof(struct atpBDS)*ATP_TRESP_MAX) {
+               file_drop(fd);
+               *err = EINVAL;
+               return -1;
+       }
        if ((m = gbuf_alloc_wait(resplen, TRUE)) == 0) {
                *err = ENOMEM;
                file_drop(fd);
@@ -1667,6 +1754,12 @@ _ATPsndrsp(fd, respbuff, resplen, datalen, err, proc)
        }
        
        for (size = 0, count = 0; count < bds_cnt; count++) {
+               if (UAS_VALUE(bdsp[count].bdsBuffSz) > ATP_DATA_SIZE) {
+                       gbuf_freem(m);
+                       *err = EINVAL;
+                       file_drop(fd);
+                       return -1;
+               }
                size += UAS_VALUE(bdsp[count].bdsBuffSz);
        }
        if (size > datalen) {                           
@@ -1737,7 +1830,7 @@ _ATPgetreq(fd, buf, buflen, err, proc)
        register struct atp_state *atp;
        register struct atp_rcb *rcbp;
        register gbuf_t *m, *m_head;
-       int size, len;
+       int s, size, len;
 
        if ((*err = atalk_getref(0, fd, &gref, proc, 1)) != 0)
                return -1;
@@ -1751,6 +1844,13 @@ _ATPgetreq(fd, buf, buflen, err, proc)
                return -1;
        }
 
+       if (buflen < DDP_X_HDR_SIZE + ATP_HDR_SIZE) {
+               file_drop(fd);
+               *err = EINVAL;
+               return -1;
+       }
+
+       ATDISABLE(s, atp->atp_lock);
        if ((rcbp = atp->atp_attached.head) != NULL) {
            /*
             * Got one, move it to the active response Q
@@ -1768,6 +1868,7 @@ _ATPgetreq(fd, buf, buflen, err, proc)
                         */
                        atp_rcb_free(rcbp);
                }
+               ATENABLE(s, atp->atp_lock);
 
                /*
                 * copyout the request data, including the protocol header
@@ -1785,6 +1886,7 @@ _ATPgetreq(fd, buf, buflen, err, proc)
                file_drop(fd);
                return size;
        }
+       ATENABLE(s, atp->atp_lock);
 
        file_drop(fd);
        return -1;
@@ -1800,7 +1902,7 @@ _ATPgetrsp(fd, bdsp, err, proc)
        gref_t *gref;
        register struct atp_state *atp;
        register struct atp_trans *trp;
-       int tid;
+       int s, tid;
        char bds[atpBDSsize];
 
        if ((*err = atalk_getref(0, fd, &gref, proc, 1)) != 0)
@@ -1815,6 +1917,7 @@ _ATPgetrsp(fd, bdsp, err, proc)
                return -1;
        }
 
+       ATDISABLE(s, atp->atp_lock);
        for (trp = atp->atp_trans_wait.head; trp; trp = trp->tr_list.next) {
                dPrintf(D_M_ATP, D_L_INFO,
                        ("ATPgetrsp: atp:0x%x, trp:0x%x, state:%d\n",
@@ -1822,6 +1925,7 @@ _ATPgetrsp(fd, bdsp, err, proc)
 
                switch (trp->tr_state) {
                case TRANS_DONE:
+               ATENABLE(s, atp->atp_lock);
                        if ((*err = copyin(CAST_USER_ADDR_T(bdsp),
                                        (caddr_t)bds, sizeof(bds))) != 0) {
                                atp_free(trp);
@@ -1846,6 +1950,7 @@ _ATPgetrsp(fd, bdsp, err, proc)
                        /*
                         * transaction timed out, return error
                         */
+               ATENABLE(s, atp->atp_lock);
                        atp_free(trp);
                        file_drop(fd);
                        *err = ETIMEDOUT;
@@ -1855,6 +1960,7 @@ _ATPgetrsp(fd, bdsp, err, proc)
                        continue;
            }
        }
+       ATENABLE(s, atp->atp_lock);
 
        file_drop(fd);
        *err = EINVAL;
@@ -1866,6 +1972,7 @@ atp_drop_req(gref, m)
        gref_t *gref;
        gbuf_t *m;
 {
+       int s;
        struct atp_state *atp;
        struct atp_rcb *rcbp;
        at_atp_t *athp;
@@ -1880,8 +1987,9 @@ atp_drop_req(gref, m)
        /*
         *      search for the corresponding rcb
         */
+       ATDISABLE(s, atp->atp_lock);
        for (rcbp = atp->atp_rcb.head; rcbp; rcbp = rcbp->rc_list.next) {
-           if ( (rcbp->rc_tid == UAS_VALUE_NTOH(athp->tid)) &&
+           if ( (rcbp->rc_tid == UAS_VALUE(athp->tid)) &&
                        (rcbp->rc_socket.node == ddp->src_node) &&
                        (rcbp->rc_socket.net == NET_VALUE(ddp->src_net)) &&
                        (rcbp->rc_socket.socket == ddp->src_socket) )
@@ -1893,6 +2001,7 @@ atp_drop_req(gref, m)
         */
        if (rcbp)
                atp_rcb_free(rcbp);
+       ATENABLE(s, atp->atp_lock);
 
        gbuf_freem(m);
 }