/*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#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>
#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>
+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);
+
+int _ATrw(struct fileproc *, enum uio_rw, struct uio *, vfs_context_t);
+
extern struct atpcb ddp_head;
extern lck_mtx_t * atalk_mutex;
-
-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 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);
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,
- (int *)&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,
&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,
+ &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 );
+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;
return rc;
}
-int _ATclose(fg, proc)
- struct fileglob *fg;
- struct proc *proc;
+int _ATclose(
+ struct fileglob *fg,
+ __unused vfs_context_t ctx)
{
int err;
gref_t *gref;
return err;
}
-int _ATrw(fp, rw, uio, p)
- void *fp;
+int _ATrw(fp, rw, uio, ctx)
+ struct fileproc *fp;
enum uio_rw rw;
struct uio *uio;
- struct proc *p;
+ vfs_context_t ctx;
{
int err, len, clen = 0, res;
gref_t *gref;
gbuf_t *m, *mhead, *mprev;
+ proc_t p = vfs_context_proc(ctx);
/* no need to get/drop iocount as the fp already has one */
if ((err = atalk_getref_locked(fp, 0, &gref, p, 1)) != 0)
return 0;
} /* _ATrw */
-int _ATread(fp, uio, cred, flags, p)
- struct fileproc *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;
atalk_lock();
- stat = _ATrw(fp, UIO_READ, uio, p);
+ stat = _ATrw(fp, UIO_READ, uio, ctx);
atalk_unlock();
return stat;
}
-int _ATwrite(fp, uio, cred, flags, p)
- struct fileproc *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;
atalk_lock();
- stat = _ATrw(fp, UIO_WRITE, uio, p);
+ stat = _ATrw(fp, UIO_WRITE, uio, ctx);
atalk_unlock();
return stat;
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;
return err;
}
-int _ATselect(fp, which, wql, proc)
+int _ATselect(fp, which, wql, ctx)
struct fileproc *fp;
int which;
void * wql;
- struct proc *proc;
+ vfs_context_t ctx;
{
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.
return rc;
}
-int _ATkqfilter(fp, kn, p)
- struct fileproc *fp;
- struct knote *kn;
- struct proc *p;
+int _ATkqfilter(
+ __unused struct fileproc *fp,
+ __unused struct knote *kn,
+ __unused vfs_context_t ctx)
{
return (EOPNOTSUPP);
}
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;
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;
gbuf_t *m;
gref_t *gref, *gref_array;
return rc;
}
\f
-/*
- 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;
- void (*extfree)(caddr_t , u_int, caddr_t);
- u_int extsize;
- caddr_t 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)
- caddr_t buf;
- u_int size;
- caddr_t 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));
- }
}
/*
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) {
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, 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);
/* 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);
len -= buf_len;
goto l_cont;
- } else
- return 1;
+ }
+
+ return 1;
}
/*