]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netat/atp_write.c
xnu-344.49.tar.gz
[apple/xnu.git] / bsd / netat / atp_write.c
index e0d84e9e1c0e1ed39e78f8e1e9252495a898e557..1eebbd18259113f04e0c609acebfb6e731fb9079 100644 (file)
@@ -3,19 +3,22 @@
  *
  * @APPLE_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.
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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. 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@
  */
@@ -456,7 +459,8 @@ void atp_send_replies(atp, rcbp)
        unsigned char *m0_rptr = NULL, *m0_wptr = NULL;
        register at_atp_t *athp;
        register struct atpBDS *bdsp;
-       register gbuf_t *m2, *m1, *m0;
+       register gbuf_t *m2, *m1, *m0, *m3;
+       caddr_t lastPage;
        gbuf_t *mprev, *mlist = 0;
        at_socket src_socket = (at_socket)atp->atp_socket_no;
        gbuf_t *rc_xmt[ATP_TRESP_MAX];
@@ -549,6 +553,24 @@ void atp_send_replies(atp, rcbp)
                        } else
                                gbuf_cont(m1) = 0;
                        gbuf_cont(m2) = m1;
+                               
+                       /* temp fix for page boundary problem  - bug# 2703163 */
+                       lastPage = (caddr_t)((int)(gbuf_wptr(m1) - 1) & ~PAGE_MASK);                    /* 4k page of last byte */
+                       if (lastPage != (caddr_t)((int)(gbuf_rptr(m1)) & ~PAGE_MASK)) {                 /* 1st byte and last on same page ? */
+                               if ((m3 = gbuf_dupb(m1)) == NULL) {
+                                       for (i = 0; i < cnt; i++)
+                                               if (rc_xmt[i])
+                                                       gbuf_freem(rc_xmt[i]);
+                                       (gbuf_rptr(m0)) = m0_rptr;
+                                       gbuf_wset(m0, (m0_wptr - m0_rptr));
+                                       goto nothing_to_send;
+                               }
+                               (gbuf_rptr(m3)) = lastPage;                                             /* new mbuf starts at beginning of page */
+                               gbuf_wset(m3, (gbuf_wptr(m1) - lastPage));              /* len = remaining data crossing over page boundary */
+                               gbuf_wset(m1, (lastPage - (gbuf_rptr(m1))));    /* adjust len of m1 */
+                               (gbuf_cont(m1)) = m3;
+                               (gbuf_cont(m3)) = 0;
+                       }
                  }
                }
 
@@ -689,10 +711,11 @@ atp_unpack_bdsp(atp, m, rcbp, cnt, wait)
        struct atp_state *atp;
         gbuf_t          *m;    /* ddp, atp and bdsp gbuf_t */
        register struct atp_rcb *rcbp;
-        register int    cnt, wait;
+    register int    cnt, wait;
 {
        register struct atpBDS *bdsp;
-       register gbuf_t        *m2, *m1, *m0;
+       register gbuf_t        *m2, *m1, *m0, *m3;
+       caddr_t lastPage;
         register at_atp_t        *athp;
        register int  i, len, s_gen;
        at_socket src_socket;
@@ -823,8 +846,26 @@ atp_unpack_bdsp(atp, m, rcbp, cnt, wait)
                        } else
                                gbuf_cont(m1) = 0;
                        gbuf_cont(m2) = m1;
+                       
+                       /* temp fix for page boundary problem  - bug# 2703163 */
+                       lastPage = (caddr_t)((int)(gbuf_wptr(m1) - 1) & ~PAGE_MASK);                    /* 4k page of last byte */
+                       if (lastPage != (caddr_t)((int)(gbuf_rptr(m1)) & ~PAGE_MASK)) {                 /* 1st byte and last on same page ? */
+                               if ((m3 = gbuf_dupb_wait(m1, wait)) == NULL) {
+                                       for (i = 0; i < cnt; i++)
+                                               if (rc_xmt[i])
+                                                       gbuf_freem(rc_xmt[i]);
+                                       (gbuf_rptr(m0)) = m0_rptr;
+                                       gbuf_wset(m0, (m0_wptr - m0_rptr));
+                                       return 0;
+                               }
+                               (gbuf_rptr(m3)) = lastPage;                                             /* new mbuf starts at beginning of page */
+                               gbuf_wset(m3, (gbuf_wptr(m1) - lastPage));              /* len = remaining data crossing over page boundary */
+                               gbuf_wset(m1, (lastPage - (gbuf_rptr(m1))));            /* adjust len of m1 */
+                               (gbuf_cont(m1)) = m3;
+                               (gbuf_cont(m3)) = 0;
                        }
                  }
+               }
 
                AT_DDP_HDR(m2)->src_socket = src_socket;
                dPrintf(D_M_ATP_LOW,D_L_INFO,
@@ -863,7 +904,7 @@ l_send:
 } /* atp_unpack_bdsp */
 
 #define ATP_SOCKET_LAST  (DDP_SOCKET_LAST-6)
-#define ATP_SOCKET_FIRST (DDP_SOCKET_1st_DYNAMIC-64)
+#define ATP_SOCKET_FIRST (DDP_SOCKET_1st_DYNAMIC)
 static unsigned int sNext = 0;
 
 int atp_bind(gref, sVal, flag)
@@ -1603,7 +1644,8 @@ _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)) {
+       while ((trp->tr_state != TRANS_DONE) && (trp->tr_state != TRANS_FAILED) &&
+                               (trp->tr_state != TRANS_ABORTING)) {
                trp->tr_rsp_wait = 1;
                rc = tsleep(&trp->tr_event, PSOCK | PCATCH, "atpsndreq", 0);
                if (rc != 0) {
@@ -1616,7 +1658,8 @@ _ATPsndreq(fd, buf, len, nowait, err, proc)
        trp->tr_rsp_wait = 0;
        ATENABLE(s, trp->tr_lock);
 
-       if (trp->tr_state == TRANS_FAILED) {
+
+       if (trp->tr_state == TRANS_FAILED || trp->tr_state == TRANS_ABORTING) {
                /*
                 * transaction timed out, return error
                 */
@@ -1674,14 +1717,9 @@ _ATPsndrsp(fd, respbuff, resplen, datalen, err, proc)
        /*
         * allocate buffer and copy in the response info
         */
-       while ((m = gbuf_alloc(resplen, PRI_MED)) == 0) {
-               ATDISABLE(s, atp->atp_delay_lock);
-               rc = tsleep(&atp->atp_delay_event, PSOCK | PCATCH, "atprspinfo", 10);
-               ATENABLE(s, atp->atp_delay_lock);
-               if (rc != 0) {
-                       *err = rc;
-                       return -1;
-               }
+       if ((m = gbuf_alloc_wait(resplen, TRUE)) == 0) {
+               *err = ENOMEM;
+               return -1;
        }
        if ((*err = copyin((caddr_t)respbuff, (caddr_t)gbuf_rptr(m), resplen)) != 0) {
                gbuf_freeb(m);
@@ -1698,15 +1736,10 @@ _ATPsndrsp(fd, respbuff, resplen, datalen, err, proc)
        /*
         * allocate buffer and copy in the response data
         */
-       while ((mdata = gbuf_alloc(datalen+len, PRI_MED)) == 0) {
-               ATDISABLE(s, atp->atp_delay_lock);
-               rc = tsleep(&atp->atp_delay_event, PSOCK | PCATCH, "atprspdata", 10);
-               ATENABLE(s, atp->atp_delay_lock);
-               if (rc != 0) {
-                       gbuf_freem(m);
-                       *err = rc;
-                       return -1;
-               }
+       if ((mdata = gbuf_alloc_wait(datalen+len, TRUE)) == 0) {
+               gbuf_freem(m);
+               *err = ENOMEM;
+               return -1;
        }
        gbuf_cont(m) = mdata;
        for (size=0; bdsp < (struct atpBDS *)gbuf_wptr(m); bdsp++) {