X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/43866e378188c25dd1e2208016ab3cbeb086ae6c..6d2010ae8f7a6078e10b361c6962983bab233e0f:/bsd/netat/sys_glue.c

diff --git a/bsd/netat/sys_glue.c b/bsd/netat/sys_glue.c
index c8a0f1149..acb307fbc 100644
--- a/bsd/netat/sys_glue.c
+++ b/bsd/netat/sys_glue.c
@@ -1,16 +1,19 @@
 /*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * 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.
+ * 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.
+ * 
+ * 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
@@ -20,7 +23,7 @@
  * 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) 1995 Apple Computer, Inc. 
@@ -38,12 +41,17 @@
 #include <sys/proc.h>
 #include <sys/filedesc.h>
 #include <sys/fcntl.h>
+#include <sys/file_internal.h>
 #include <sys/mbuf.h>
 #include <sys/ioctl.h>
 #include <sys/malloc.h>
+#include <kern/locks.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/ioccom.h>
+#include <sys/uio_internal.h>
+#include <sys/file.h>
+#include <sys/vnode.h>
 
 #include <sys/sysctl.h>
 
@@ -55,24 +63,29 @@
 #include <netat/at_pcb.h>
 #include <netat/at_var.h>
 #include <netat/routing_tables.h>
+#include <netat/adsp.h>
+#include <netat/adsp_internal.h>
+#include <netat/asp.h>
+#include <netat/atp.h>
 #include <netat/debug.h>
 
-extern struct atpcb ddp_head;
+int _ATkqfilter(struct fileproc *, struct knote *, vfs_context_t);
+int _ATselect(struct fileproc *, int, void *, vfs_context_t);
+int _ATioctl(struct fileproc *, u_long, caddr_t, vfs_context_t);
+int _ATwrite(struct fileproc *, struct uio *, int, vfs_context_t);
+int _ATread(struct fileproc *, struct uio *, int, vfs_context_t);
+int _ATclose(struct fileglob *, vfs_context_t);
 
-extern void 
-  ddp_putmsg(gref_t *gref, gbuf_t *m),
-  elap_wput(gref_t *gref, gbuf_t *m),
-  atp_wput(gref_t *gref, gbuf_t *m),
-  asp_wput(gref_t *gref, gbuf_t *m),
-#ifdef AURP_SUPPORT
-  aurp_wput(gref_t *gref, gbuf_t *m),
-#endif
-  adsp_wput(gref_t *gref, gbuf_t *m);
+int _ATrw(struct fileproc *, enum uio_rw, struct uio *, vfs_context_t);
+
+extern struct atpcb ddp_head;
+extern lck_mtx_t * atalk_mutex;
   
 int atp_free_cluster_timeout_set = 0;
 
+int gref_alloc(gref_t **);
+
 
-void atalk_putnext(gref_t *gref, gbuf_t *m);
 /* bms:  make gref_close non static so its callable from kernel */
 int gref_close(gref_t *gref);
 
@@ -80,16 +93,23 @@ SYSCTL_DECL(_net_appletalk);
 dbgBits_t dbgBits;
 SYSCTL_STRUCT(_net_appletalk, OID_AUTO, debug, CTLFLAG_WR, 
 	      &dbgBits, dbgBits, "AppleTalk Debug Flags");
-volatile int RouterMix = RT_MIX_DEFAULT; /* default for nbr of ppsec */
+int RouterMix = RT_MIX_DEFAULT; /* default for nbr of ppsec */
 SYSCTL_INT(_net_appletalk, OID_AUTO, routermix, CTLFLAG_WR, 
-	   &RouterMix, 0, "Appletalk RouterMix");
+			&RouterMix, 0, "Appletalk RouterMix");
 at_ddp_stats_t at_ddp_stats;		/* DDP statistics */
-SYSCTL_STRUCT(_net_appletalk, OID_AUTO, ddpstats, CTLFLAG_RD,
+SYSCTL_STRUCT(_net_appletalk, OID_AUTO, ddpstats, CTLFLAG_RD | CTLFLAG_LOCKED,
 	      &at_ddp_stats, at_ddp_stats, "AppleTalk DDP Stats");
+extern int atp_resp_seqno2big;
+SYSCTL_INT(_net_appletalk, OID_AUTO, atp_resp_seqno2big, CTLFLAG_RD | CTLFLAG_LOCKED,
+                        &atp_resp_seqno2big, 0, "Appletalk ATP seqno too big count");
+
+static void ioccmd_t_32_to_64( ioccmd_t *from_p, user_ioccmd_t *to_p );
+static void ioccmd_t_64_to_32( user_ioccmd_t *from_p, ioccmd_t *to_p );
 
-atlock_t refall_lock;
+extern lck_mtx_t *atalk_cluster_lock;
+caddr_t	atp_free_cluster_list = NULL;
 
-caddr_t	atp_free_cluster_list = 0;
+void gref_wput(gref_t *, gbuf_t *m);
 
 void gref_wput(gref, m)
 	gref_t *gref;
@@ -115,7 +135,7 @@ void gref_wput(gref, m)
 			gbuf_freem(gbuf_cont(m));
 			gbuf_cont(m) = 0;
 			((ioc_t *)gbuf_rptr(m))->ioc_rval = -1;
-			((ioc_t *)gbuf_rptr(m))->ioc_error = EPROTO;
+			((ioc_t *)gbuf_rptr(m))->ioc_error = EPROTOTYPE;
 			gbuf_set_type(m, MSG_IOCNAK);
 			atalk_putnext(gref, m);
 		} else
@@ -143,7 +163,9 @@ int _ATsocket(proto, err, proc)
 
 	case ATPROTO_ATP:
 	case ATPROTO_ASP:
+#ifdef AURP_SUPPORT
 	case ATPROTO_AURP:
+#endif
 	case ATPROTO_ADSP:
 		break;
 	default:
@@ -162,7 +184,7 @@ int _ATsocket(proto, err, proc)
 		return -1;
 	}
 	gref->proto = proto;
-	gref->pid = ((struct proc *)proc)->p_pid;
+	gref->pid = proc_pid((struct proc *)proc);
 
 	/* open the specified protocol */
 	switch (gref->proto) {
@@ -214,7 +236,7 @@ int _ATgetmsg(fd, ctlptr, datptr, flags, err, proc)
 	int rc = -1;
 	gref_t *gref;
 
-	if ((*err = atalk_getref(0, fd, &gref, proc)) == 0) {
+	if ((*err = atalk_getref(0, fd, &gref, proc, 1)) == 0) {
 		switch (gref->proto) {
 		case ATPROTO_ASP:
 			rc = ASPgetmsg(gref, ctlptr, datptr, NULL, flags, err); 
@@ -228,6 +250,7 @@ int _ATgetmsg(fd, ctlptr, datptr, flags, err, proc)
 			*err = EPROTONOSUPPORT; 
 			break;
 		}
+		file_drop(fd);
 	}
 
 /*	kprintf("_ATgetmsg: return=%d\n", *err);*/
@@ -245,76 +268,74 @@ int _ATputmsg(fd, ctlptr, datptr, flags, err, proc)
 	int rc = -1;
 	gref_t *gref;
 
-	if ((*err = atalk_getref(0, fd, &gref, proc)) == 0) {
+	if ((*err = atalk_getref(0, fd, &gref, proc, 1)) == 0) {
 		switch (gref->proto) {
 		case ATPROTO_ASP:
 			rc = ASPputmsg(gref, ctlptr, datptr, NULL, flags, err); break;
 		default:
 			*err = EPROTONOSUPPORT; break;
 		}
+		file_drop(fd);
 	}
 
 /*	kprintf("_ATputmsg: return=%d\n", *err); */
 	return rc;
 }
 
-int _ATclose(fp, proc)
-	struct file *fp;
-	struct proc *proc;
+int _ATclose(
+	struct fileglob *fg,
+	__unused vfs_context_t ctx)
 {
 	int err;
 	gref_t *gref;
 
-	if ((err = atalk_closeref(fp, &gref)) == 0) {
-	     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
+	if ((err = atalk_closeref(fg, &gref)) == 0) {
+		atalk_lock();
 	     (void)gref_close(gref);
-	     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
+		atalk_unlock();
 	}
 
 	return err;
 }
 
-int _ATrw(fp, rw, uio, ext)
-     void *fp;
+int _ATrw(fp, rw, uio, ctx)
+     struct fileproc *fp;
      enum uio_rw rw;
      struct uio *uio;
-     int ext;
+	 vfs_context_t ctx;
 {
-    int s, err, len, clen = 0, res;
+    int err, len, clen = 0, res;
     gref_t *gref;
     gbuf_t *m, *mhead, *mprev;
+	proc_t p = vfs_context_proc(ctx);
 
-    if ((err = atalk_getref(fp, 0, &gref, 0)) != 0)
+	/* no need to get/drop iocount as the fp already has one */
+    if ((err = atalk_getref_locked(fp, 0, &gref, p, 1)) != 0)
     	return err;
 
-    if ((len = uio->uio_resid) == 0)
+	// LP64todo - fix this!
+    if ((len = uio_resid(uio)) == 0)
     	return 0;
 
-    ATDISABLE(s, gref->lock);
 
     if (rw == UIO_READ) {
 	KERNEL_DEBUG(DBG_ADSP_ATRW, 0, gref, len, gref->rdhead, 0);
 	while ((gref->errno == 0) && ((mhead = gref->rdhead) == 0)) {
 		gref->sevents |= POLLMSG;
-		err = tsleep(&gref->event, PSOCK | PCATCH, "AT read", 0);
+		err = msleep(&gref->event, atalk_mutex, PSOCK | PCATCH, "AT read", 0);
 		gref->sevents &= ~POLLMSG;
-		if (err != 0) {
-			ATENABLE(s, gref->lock);
+		if (err != 0)
 			return err;
-		}
 		KERNEL_DEBUG(DBG_ADSP_ATRW, 1, gref, gref->rdhead, mhead, gbuf_next(mhead));
 	}
 
-	if (gref->errno) {
-		ATENABLE(s, gref->lock);
+	if (gref->errno)
 		return EPIPE;
-	}
 	if ((gref->rdhead = gbuf_next(mhead)) == 0)
 		gref->rdtail = 0;
 
 	KERNEL_DEBUG(DBG_ADSP_ATRW, 2, gref, gref->rdhead, mhead, gbuf_next(mhead));
 
-	ATENABLE(s, gref->lock);
 
 //##### LD TEST 08/05
 //	simple_lock(&gref->lock);
@@ -346,12 +367,10 @@ int _ATrw(fp, rw, uio, ext)
 			gbuf_cont(mprev) = 0;
 		else
 			mhead = 0;
-		ATDISABLE(s, gref->lock);
 		if (gref->rdhead == 0)
 			gref->rdtail = m;
 		gbuf_next(m) = gref->rdhead;
 		gref->rdhead = m;
-		ATENABLE(s, gref->lock);
 	}
 	if (mhead)
 		gbuf_freem(mhead);
@@ -362,16 +381,13 @@ int _ATrw(fp, rw, uio, ext)
 		while (!(*gref->writeable)(gref)) {
 			/* flow control on, wait to be enabled to write */ 
 			gref->sevents |= POLLSYNC;
-			err = tsleep(&gref->event, PSOCK | PCATCH, "AT write", 0);
+			err = msleep(&gref->event, atalk_mutex, PSOCK | PCATCH, "AT write", 0);
 			gref->sevents &= ~POLLSYNC;
-			if (err != 0) {
-				ATENABLE(s, gref->lock);
+			if (err != 0)
 				return err;
-			}
 		}
 	}
 
-	ATENABLE(s, gref->lock);
 
 	/* allocate a buffer to copy in the write data */
 	if ((m = gbuf_alloc(AT_WR_OFFSET+len, PRI_MED)) == 0)
@@ -396,34 +412,31 @@ int _ATrw(fp, rw, uio, ext)
   return 0;
 } /* _ATrw */
 
-int _ATread(fp, uio, cred, flags, p)
-	void *fp;
-	struct uio *uio;
-	void *cred;
-	int flags;
-	struct proc *p;
+int _ATread(
+	struct fileproc *fp,
+	struct uio *uio,
+	__unused int flags,
+	vfs_context_t ctx)
 {
      int stat;
 
-	thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-	stat = _ATrw(fp, UIO_READ, uio, 0);
-	thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
+	atalk_lock();
+	stat = _ATrw(fp, UIO_READ, uio, ctx);
+	atalk_unlock();
 	return stat;
 }
 
-int _ATwrite(fp, uio, cred, flags, p)
-	void *fp;
-	struct uio *uio;
-	void *cred;
-	int flags;
-	struct proc *p;
+int _ATwrite(
+	struct fileproc *fp,
+	struct uio *uio,
+	__unused int flags,
+	vfs_context_t ctx)
 {
-     int stat;
+	int stat;
 
-
-	thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-	stat = _ATrw(fp, UIO_WRITE, uio, 0);
-	thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
+	atalk_lock();
+	stat = _ATrw(fp, UIO_WRITE, uio, ctx);
+	atalk_unlock();
 
 	return stat;
 }
@@ -433,28 +446,44 @@ int _ATwrite(fp, uio, cred, flags, p)
 /* bms:  update to be callable from kernel */
 int at_ioctl(gref_t *gref, u_long cmd, caddr_t arg, int fromKernel)
 {
-    int s, err = 0, len;
+    int err = 0, len;
+    u_int size;
     gbuf_t *m, *mdata;
     ioc_t *ioc;
-    ioccmd_t ioccmd;
+    user_addr_t user_arg;
+    user_ioccmd_t user_ioccmd;
+	boolean_t is64bit;
 
     /* error if not for us */
     if ((cmd  & 0xffff) != 0xff99)
         return EOPNOTSUPP;
 
+	size = IOCPARM_LEN(cmd);
+	if (size != sizeof(user_addr_t))
+		return EINVAL;
+		
+	user_arg = *((user_addr_t *)arg);
+
     /* copy in ioc command info */
-/*
-    kprintf("at_ioctl: arg ioccmd.ic_cmd=%x ic_len=%x gref->lock=%x, gref->event=%x\n",
-        ((ioccmd_t *)arg)->ic_cmd, ((ioccmd_t *)arg)->ic_len, 
-        gref->lock, gref->event);
-*/
-    if (fromKernel)
-        bcopy (arg, &ioccmd, sizeof (ioccmd_t));
+    is64bit = proc_is64bit(current_proc());
+    if (fromKernel) {
+    	ioccmd_t	tmp;
+        bcopy (CAST_DOWN(caddr_t, user_arg), &tmp, sizeof (tmp));
+        ioccmd_t_32_to_64(&tmp, &user_ioccmd);
+    }
     else {
-    	if ((err = copyin((caddr_t)arg, (caddr_t)&ioccmd, sizeof(ioccmd_t))) != 0) { 
+		if (is64bit) {
+			err = copyin(user_arg, (caddr_t)&user_ioccmd, sizeof(user_ioccmd));
+    	}
+    	else {
+	    	ioccmd_t	tmp;
+			err = copyin(user_arg, (caddr_t)&tmp, sizeof(tmp));
+        	ioccmd_t_32_to_64(&tmp, &user_ioccmd);
+    	}
+    	if (err != 0) { 
 #ifdef APPLETALK_DEBUG
-			kprintf("at_ioctl: err = %d, copyin(%x, %x, %d)\n", err, 
-              		(caddr_t)arg, (caddr_t)&ioccmd, sizeof(ioccmd_t));
+			kprintf("at_ioctl: err = %d, copyin(%llx, %x, %d)\n", err, 
+              		user_arg, (caddr_t)&user_ioccmd, sizeof(user_ioccmd));
 #endif
             return err;
         } 
@@ -469,27 +498,27 @@ int at_ioctl(gref_t *gref, u_long cmd, caddr_t arg, int fromKernel)
 
     /* create the ioc command 
        second mbuf contains the actual ASP command */
-    if (ioccmd.ic_len) {
-        if ((gbuf_cont(m) = gbuf_alloc(ioccmd.ic_len, PRI_HI)) == 0) {
+    if (user_ioccmd.ic_len) {
+        if ((gbuf_cont(m) = gbuf_alloc(user_ioccmd.ic_len, PRI_HI)) == 0) {
             gbuf_freem(m);
 #ifdef APPLETALK_DEBUG
 			kprintf("at_ioctl: gbuf_alloc err=%d\n",ENOBUFS);
 #endif
             return ENOBUFS;
         }
-        gbuf_wset(gbuf_cont(m), ioccmd.ic_len);     /* mbuf->m_len */
+        gbuf_wset(gbuf_cont(m), user_ioccmd.ic_len);     /* mbuf->m_len */
         if (fromKernel)
-            bcopy (ioccmd.ic_dp, gbuf_rptr(gbuf_cont(m)), ioccmd.ic_len);
+            bcopy (CAST_DOWN(caddr_t, user_ioccmd.ic_dp), gbuf_rptr(gbuf_cont(m)), user_ioccmd.ic_len);
         else {
-            if ((err = copyin((caddr_t)ioccmd.ic_dp, (caddr_t)gbuf_rptr(gbuf_cont(m)), ioccmd.ic_len)) != 0) { 
+            if ((err = copyin(user_ioccmd.ic_dp, (caddr_t)gbuf_rptr(gbuf_cont(m)), user_ioccmd.ic_len)) != 0) { 
                 gbuf_freem(m);
                 return err;
             }
         }
     }
     ioc = (ioc_t *) gbuf_rptr(m);
-    ioc->ioc_cmd = ioccmd.ic_cmd;
-    ioc->ioc_count = ioccmd.ic_len;
+    ioc->ioc_cmd = user_ioccmd.ic_cmd;
+    ioc->ioc_count = user_ioccmd.ic_len;
     ioc->ioc_error = 0;
     ioc->ioc_rval = 0;
 
@@ -497,16 +526,14 @@ int at_ioctl(gref_t *gref, u_long cmd, caddr_t arg, int fromKernel)
 	gref_wput(gref, m);
 
     /* wait for the ioc ack */
-    ATDISABLE(s, gref->lock);
     while ((m = gref->ichead) == 0) {
         gref->sevents |= POLLPRI;
 #ifdef APPLETALK_DEBUG
 		kprintf("sleep gref = 0x%x\n", (unsigned)gref);
 #endif
-		err = tsleep(&gref->iocevent, PSOCK | PCATCH, "AT ioctl", 0);
+		err = msleep(&gref->iocevent, atalk_mutex, PSOCK | PCATCH, "AT ioctl", 0);
 		gref->sevents &= ~POLLPRI;
 		if (err != 0) {
-			ATENABLE(s, gref->lock);
 #ifdef APPLETALK_DEBUG
 			kprintf("at_ioctl: EINTR\n");
 #endif
@@ -520,7 +547,6 @@ int at_ioctl(gref_t *gref, u_long cmd, caddr_t arg, int fromKernel)
 
 	gref->ichead = gbuf_next(m);
 
-	ATENABLE(s, gref->lock);
 
 #ifdef APPLETALK_DEBUG
 	kprintf("at_ioctl: woke up from ioc sleep gref = 0x%x\n", 
@@ -530,19 +556,19 @@ int at_ioctl(gref_t *gref, u_long cmd, caddr_t arg, int fromKernel)
     /* process the ioc response */
     ioc = (ioc_t *) gbuf_rptr(m);
     if ((err = ioc->ioc_error) == 0) {
-        ioccmd.ic_timout = ioc->ioc_rval;
-        ioccmd.ic_len = 0;
+        user_ioccmd.ic_timout = ioc->ioc_rval;
+        user_ioccmd.ic_len = 0;
         mdata = gbuf_cont(m);
-        if (mdata && ioccmd.ic_dp) {
-            ioccmd.ic_len = gbuf_msgsize(mdata);
+        if (mdata && user_ioccmd.ic_dp) {
+            user_ioccmd.ic_len = gbuf_msgsize(mdata);
             for (len = 0; mdata; mdata = gbuf_cont(mdata)) {
                 if (fromKernel)
-                    bcopy (gbuf_rptr(mdata), &ioccmd.ic_dp[len], gbuf_len(mdata));
+                    bcopy (gbuf_rptr(mdata), CAST_DOWN(caddr_t, (user_ioccmd.ic_dp + len)), gbuf_len(mdata));
                 else {
-                    if ((err = copyout((caddr_t)gbuf_rptr(mdata), (caddr_t)&ioccmd.ic_dp[len], gbuf_len(mdata))) < 0) {
+                    if ((err = copyout((caddr_t)gbuf_rptr(mdata), (user_ioccmd.ic_dp + len), gbuf_len(mdata))) < 0) {
 #ifdef APPLETALK_DEBUG
 						kprintf("at_ioctl: len=%d error copyout=%d from=%x to=%x gbuf_len=%x\n",
-					 			len, err, (caddr_t)gbuf_rptr(mdata), (caddr_t)&ioccmd.ic_dp[len], gbuf_len(mdata));
+					 			len, err, (caddr_t)gbuf_rptr(mdata), (caddr_t)&user_ioccmd.ic_dp[len], gbuf_len(mdata));
 #endif
                         goto l_done;
                     }
@@ -551,14 +577,21 @@ int at_ioctl(gref_t *gref, u_long cmd, caddr_t arg, int fromKernel)
             }
         }
         
-        if (fromKernel)
-            bcopy (&ioccmd, arg, sizeof(ioccmd_t));
+        if (fromKernel) {
+			ioccmd_t	tmp;
+			ioccmd_t_64_to_32(&user_ioccmd, &tmp);
+ 			bcopy (&tmp, CAST_DOWN(caddr_t, user_arg), sizeof(tmp));
+        }
         else {
-            if ((err = copyout((caddr_t)&ioccmd, (caddr_t)arg, sizeof(ioccmd_t))) != 0) {
-#ifdef APPLETALK_DEBUG
-                kprintf("at_ioctl: error copyout2=%d from=%x to=%x len=%d\n",
-                         err, &ioccmd, arg, sizeof(ioccmd_t));
-#endif
+ 			if (is64bit) {
+				err = copyout((caddr_t)&user_ioccmd, user_arg, sizeof(user_ioccmd));
+			}
+			else {
+				ioccmd_t	tmp;
+				ioccmd_t_64_to_32(&user_ioccmd, &tmp);
+				err = copyout((caddr_t)&tmp, user_arg, sizeof(tmp));
+			}
+            if (err != 0) {
                 goto l_done;
             }
         }
@@ -570,17 +603,18 @@ l_done:
 	return err;
 } /* at_ioctl */
 
-int _ATioctl(fp, cmd, arg, proc)
-	void *fp;
-	u_long cmd;
-	register caddr_t arg;
-	void *proc;
+int _ATioctl(
+	struct fileproc *fp,
+	u_long cmd,
+	register caddr_t arg,
+	__unused vfs_context_t ctx)
 {
 	int err;
 	gref_t *gref;
 
-	thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-	if ((err = atalk_getref(fp, 0, &gref, 0)) != 0) {
+	atalk_lock();
+	/* No need to get a reference on fp as it already has one */
+	if ((err = atalk_getref_locked(fp, 0, &gref, 0, 0)) != 0) {
 #ifdef APPLETALK_DEBUG
 		kprintf("_ATioctl: atalk_getref err = %d\n", err);
 #endif
@@ -588,28 +622,36 @@ int _ATioctl(fp, cmd, arg, proc)
 	else
 	     err = at_ioctl(gref, cmd, arg, 0);
 
-	thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
+	atalk_unlock();
 
 	return err;
 }
 
-int _ATselect(fp, which, wql, proc)
-	struct file *fp;
+int _ATselect(fp, which, wql, ctx)
+	struct fileproc *fp;
 	int which;
 	void * wql;
-	struct proc *proc;
+	vfs_context_t ctx;
 {
-	int s, err, rc = 0;
+	int err, rc = 0;
 	gref_t *gref;
+	proc_t proc = vfs_context_proc(ctx);
+
+	/* Radar 4128949: Drop the proc_fd lock here to avoid lock inversion issues with the other AT calls
+      * select() is already holding a reference on the fd, so it won't go away during the time it is unlocked.
+      */
+	proc_fdunlock(proc);
 
-	thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-	err = atalk_getref(fp, 0, &gref, 0);
-	thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
+	atalk_lock();
+	/* no need to drop the iocount as select covers that */
+	err = atalk_getref_locked(fp, 0, &gref, 0, 0);
+	atalk_unlock();
 
+	/* Safe to re-grab the proc_fdlock at that point */
+	proc_fdlock(proc);
 	if (err != 0)
 		rc = 1;
 	else {
-	     ATDISABLE(s, gref->lock);
 	     if (which == FREAD) {
 		  if (gref->rdhead || (gref->readable && (*gref->readable)(gref)))
 		       rc = 1;
@@ -629,19 +671,24 @@ int _ATselect(fp, which, wql, proc)
 		  } else
 		       rc = 1;
 	     }
-	     ATENABLE(s, gref->lock);
 	}
 
 	return rc;
 }
 
+int _ATkqfilter(
+	__unused struct fileproc *fp,
+	__unused struct knote *kn,
+	__unused vfs_context_t ctx)
+{
+	return (EOPNOTSUPP);
+}
+
 void atalk_putnext(gref, m)
 	gref_t *gref;
 	gbuf_t *m;
 {
-	int s;
 
-	ATDISABLE(s, gref->lock);
 
 	/* *** potential leak? *** */
 	gbuf_next(m) = 0;
@@ -686,7 +733,6 @@ void atalk_putnext(gref, m)
 		    }
 	} /* switch gbuf_type(m) */
 
-	ATENABLE(s, gref->lock);
 } /* atalk_putnext */
 
 void atalk_enablew(gref)
@@ -699,9 +745,7 @@ void atalk_enablew(gref)
 void atalk_flush(gref)
 	gref_t *gref;
 {
-	int s;
 
-	ATDISABLE(s, gref->lock);
 	if (gref->rdhead) {
 		gbuf_freel(gref->rdhead);
 		gref->rdhead = 0;
@@ -710,7 +754,6 @@ void atalk_flush(gref)
 		gbuf_freel(gref->ichead);
 		gref->ichead = 0;
 	}
-	ATENABLE(s, gref->lock);
 }
 
 /*
@@ -721,8 +764,6 @@ void atalk_notify(gref, errno)
 	register gref_t *gref;
 	int errno;
 {
-	int s;
-	ATDISABLE(s, gref->lock);
 
 	if (gref->atpcb_socket) {
 	    /* For DDP --
@@ -753,43 +794,37 @@ void atalk_notify(gref, errno)
 		}
 	    }
 	}
-	ATENABLE(s, gref->lock);
 } /* atalk_notify */
 
 void atalk_notify_sel(gref)
 	gref_t *gref;
 {
-	int s;
 
-	ATDISABLE(s, gref->lock);
 	if (gref->sevents & POLLIN) {
 		gref->sevents &= ~POLLIN;
 		selwakeup(&gref->si);
 	}
-	ATENABLE(s, gref->lock);
 }
 
 int atalk_peek(gref, event)
 	gref_t *gref;
 	unsigned char *event;
 {
-	int s, rc;
+	int rc;
 
-	ATDISABLE(s, gref->lock);
 	if (gref->rdhead) {
 		*event = *gbuf_rptr(gref->rdhead);
 		rc = 0;
 	} else
 		rc = -1;
-	ATENABLE(s, gref->lock);
 
 	return rc;
 }
 
+#if 0
 static gbuf_t *trace_msg;
 
-void atalk_settrace(str, p1, p2, p3, p4, p5)
-	char *str;
+void atalk_settrace(char * str, p1, p2, p3, p4, p5)
 {
 	int len;
 	gbuf_t *m, *nextm;
@@ -819,23 +854,22 @@ void atalk_gettrace(m)
 		trace_msg = 0;
 	}
 }
+#endif /* 0 */
 
 #define GREF_PER_BLK 32
 static gref_t *gref_free_list = 0;
+extern gbuf_t *atp_resource_m;
 
 int gref_alloc(grefp)
 	gref_t **grefp;
 {
-	extern gbuf_t *atp_resource_m;
-	int i, s;
+	int i;
 	gbuf_t *m;
 	gref_t *gref, *gref_array;
 
 	*grefp = (gref_t *)NULL;
 
-	ATDISABLE(s, refall_lock);
 	if (gref_free_list == 0) {
-		ATENABLE(s, refall_lock);
 #ifdef APPLETALK_DEBUG
 		kprintf("gref_alloc: gbufalloc size=%d\n", GREF_PER_BLK*sizeof(gref_t));
 #endif
@@ -845,7 +879,6 @@ int gref_alloc(grefp)
 		gref_array = (gref_t *)gbuf_rptr(m);
 		for (i=0; i < GREF_PER_BLK-1; i++)
 			gref_array[i].atpcb_next = (gref_t *)&gref_array[i+1];
-		ATDISABLE(s, refall_lock);
 		gbuf_cont(m) = atp_resource_m;
 		atp_resource_m = m;
 		gref_array[i].atpcb_next = gref_free_list;
@@ -854,10 +887,6 @@ int gref_alloc(grefp)
 
 	gref = gref_free_list;
 	gref_free_list = gref->atpcb_next;
-	ATENABLE(s, refall_lock);
-	ATLOCKINIT(gref->lock);
-//### LD Test 08/05/98
-//	simple_lock_init(&gref->lock);
 	ATEVENTINIT(gref->event);
 	ATEVENTINIT(gref->iocevent);
 
@@ -871,7 +900,7 @@ int gref_alloc(grefp)
 /* bms:  make gref_close callable from kernel */
 int gref_close(gref_t *gref)
 {
-	int s, rc;
+	int rc;
 
 	switch (gref->proto) {
 
@@ -899,110 +928,73 @@ int gref_close(gref_t *gref)
 		selthreadclear(&gref->si);
 
 		/* from original gref_free() */
-		ATDISABLE(s, refall_lock);
 		bzero((char *)gref, sizeof(gref_t));
 		gref->atpcb_next = gref_free_list;
 		gref_free_list = gref;
-		ATENABLE(s, refall_lock);
 	}
 
 	return rc;
 }
 
-/* 
-   Buffer Routines
-
-   *** Some to be replaced with mbuf routines, some to be re-written
-       as mbuf routines (and moved to kern/uicp_mbuf.c or sys/mbuf.h?).
-   ***
-
-*/
-
-/*
- * LD 5/12/97 Added for MacOSX, defines a m_clattach function that:
- * "Allocates an mbuf structure and attaches an external cluster."
- */
-
-struct mbuf *m_clattach(extbuf, extfree, extsize, extarg, wait)
-	caddr_t extbuf;	
-	int (*extfree)();
-	int extsize;
-	int extarg;
-	int wait;
-{
-        struct mbuf *m;
-
-        if ((m = m_gethdr(wait, MSG_DATA)) == NULL)
-                return (NULL);
-
-        m->m_ext.ext_buf = extbuf;
-        m->m_ext.ext_free = extfree;
-        m->m_ext.ext_size = extsize;
-        m->m_ext.ext_arg = extarg;
-        m->m_ext.ext_refs.forward = 
-	  m->m_ext.ext_refs.backward = &m->m_ext.ext_refs;
-        m->m_data = extbuf;
-        m->m_flags |= M_EXT;
-
-        return (m);
-}
-
-
-
 /*
 	temp fix for bug 2731148  - until this code is re-written to use standard clusters
 	Deletes any free clusters on the free list.
 */
-void atp_delete_free_clusters()
+void atp_delete_free_clusters(__unused void *junk)
 {
 	caddr_t cluster;
 	caddr_t cluster_list;
-	
-	
+
 	/* check for free clusters on the free_cluster_list to be deleted */
-	MBUF_LOCK();	/* lock used by mbuf routines */
 
-		untimeout(&atp_delete_free_clusters, NULL);
-		atp_free_cluster_timeout_set = 0;
+	untimeout(&atp_delete_free_clusters, NULL);
 
-		cluster_list = atp_free_cluster_list;
-		atp_free_cluster_list = 0;
-		
-	MBUF_UNLOCK();
-	
-	while (cluster = cluster_list)
+	lck_mtx_lock(atalk_cluster_lock);
+
+	atp_free_cluster_timeout_set = 0;
+
+	cluster_list = atp_free_cluster_list;
+	atp_free_cluster_list = NULL;
+
+	lck_mtx_unlock(atalk_cluster_lock);
+
+	while ((cluster = cluster_list))
 	{
 		cluster_list = *((caddr_t*)cluster);
 		FREE(cluster, M_MCLUST);
 	}
-	
 }
 
 
 /* 
    Used as the "free" routine for over-size clusters allocated using
-   m_lgbuf_alloc(). Called by m_free while under MBUF_LOCK.
+   m_lgbuf_alloc().
 */
 
-void m_lgbuf_free(buf, size, arg)
-     void *buf;
-     int size, arg; /* not needed, but they're in m_free() */
+void m_lgbuf_free(caddr_t, u_int, caddr_t);
+
+void m_lgbuf_free(
+     caddr_t buf,
+     __unused u_int size,
+     __unused caddr_t arg) /* not needed, but they're in m_free() */
 {
-	/* FREE(buf, M_MCLUST); - can't free here - called from m_free while under lock */
-	
+	int t;
+
 	/* move to free_cluster_list to be deleted later */
 	caddr_t cluster = (caddr_t)buf;
-	
-	/* don't need a lock because this is only called called from m_free which */
-	/* is under MBUF_LOCK */
+
+	lck_mtx_lock(atalk_cluster_lock);
+
 	*((caddr_t*)cluster) = atp_free_cluster_list;
 	atp_free_cluster_list = cluster;
-	
-	if (atp_free_cluster_timeout_set == 0)
-	{
+
+	if ((t = atp_free_cluster_timeout_set) == 0)
 		atp_free_cluster_timeout_set = 1;
+
+	lck_mtx_unlock(atalk_cluster_lock);
+
+	if (t == 0)
 		timeout(&atp_delete_free_clusters, NULL, (1 * HZ));
-	}
 }
 
 /*
@@ -1016,8 +1008,17 @@ struct mbuf *m_lgbuf_alloc(size, wait)
 	struct mbuf *m;
 
 	if (atp_free_cluster_list)
-		atp_delete_free_clusters();	/* delete any free clusters on the free list */
-	
+		atp_delete_free_clusters(NULL);	/* delete any free clusters on the free list */
+
+	/* Radar 5398094 
+	 * check that the passed size is within admissible boundaries
+	 * The max data size being ASP of 4576 (8 * ATP_DATA_SIZE),
+	 * allow for extra space for control data
+	 */
+
+	if (size < 0 || size > (ATP_DATA_SIZE * 10))	
+		return(NULL);
+
 	/* If size is too large, allocate a cluster, otherwise, use the
 	   standard mbuf allocation routines.*/
 	if (size > MCLBYTES) {
@@ -1028,14 +1029,14 @@ struct mbuf *m_lgbuf_alloc(size, wait)
 			return(NULL);
 		}
 		if (NULL == 
-		    (m = m_clattach(buf, m_lgbuf_free, size, 0, 
+		    (m = m_clattach(NULL, MSG_DATA, buf, m_lgbuf_free, size, 0, 
 				    (wait)? M_WAIT: M_DONTWAIT))) {
-			m_lgbuf_free(buf);
+			m_lgbuf_free(buf, 0, 0);
 			return(NULL);
 		}
 	} else {
 		m = m_gethdr(((wait)? M_WAIT: M_DONTWAIT), MSG_DATA);
-		if (m && (size > MHLEN)) {
+		if (m && ((size_t)size > MHLEN)) {
 			MCLGET(m, ((wait)? M_WAIT: M_DONTWAIT));
 			if (!(m->m_flags & M_EXT)) {
 				(void)m_free(m);
@@ -1063,8 +1064,8 @@ gbuf_t *gbuf_alloc_wait(size, wait)
 	/* Standard mbuf allocation routines assume that the caller
 	   will set the size. */
 	if (m) {
-		(struct mbuf *)m->m_pkthdr.len = size;
-		(struct mbuf *)m->m_len = size;
+		m->m_pkthdr.len = size;
+		m->m_len = size;
 	}
 
 	return(m);
@@ -1223,8 +1224,9 @@ l_cont:	prev_m = 0;
 		len -= buf_len;
 		goto l_cont;
 
-	} else
-		return 1;
+	}
+
+	return 1;
 }
 
 /*
@@ -1311,3 +1313,20 @@ void ioc_ack(errno, m, gref)
 	atalk_putnext(gref, m);
 }
 
+
+static void ioccmd_t_32_to_64( ioccmd_t *from_p, user_ioccmd_t *to_p )
+{
+	to_p->ic_cmd = from_p->ic_cmd;
+	to_p->ic_timout = from_p->ic_timout;
+	to_p->ic_len = from_p->ic_len;
+	to_p->ic_dp = CAST_USER_ADDR_T(from_p->ic_dp);
+}
+
+
+static void ioccmd_t_64_to_32( user_ioccmd_t *from_p, ioccmd_t *to_p )
+{
+	to_p->ic_cmd = from_p->ic_cmd;
+	to_p->ic_timout = from_p->ic_timout;
+	to_p->ic_len = from_p->ic_len;
+	to_p->ic_dp = CAST_DOWN(caddr_t, from_p->ic_dp);
+}