#include <mach/mach_types.h>
#include <vm/vm_kern.h>
#include <mach/vm_prot.h>
#include <sys/param.h>
#include <sys/buf_internal.h>
#include <sys/clist.h>
#include <sys/mbuf.h>
#include <sys/systm.h>
#include <sys/tty.h>
#include <sys/vnode.h>
#include <sys/sysctl.h>
#include <dev/ppc/cons.h>
extern vm_map_t mb_map;
#if INET || INET6
extern u_long tcp_sendspace;
extern u_long tcp_recvspace;
#endif
void bsd_bufferinit(void) __attribute__((section("__TEXT, initcode")));
extern void md_prepare_for_shutdown(int, int, char *);
int bsd_mbuf_cluster_reserve(void);
#ifdef NBUF
int max_nbuf_headers = NBUF;
int niobuf_headers = NBUF / 2;
int nbuf_hashelements = NBUF;
int nbuf_headers = NBUF;
#else
int max_nbuf_headers = 0;
int niobuf_headers = 0;
int nbuf_hashelements = 0;
int nbuf_headers = 0;
#endif
SYSCTL_INT (_kern, OID_AUTO, nbuf, CTLFLAG_RD, &nbuf_headers, 0, "");
SYSCTL_INT (_kern, OID_AUTO, maxnbuf, CTLFLAG_RW, &max_nbuf_headers, 0, "");
__private_extern__ int customnbuf = 0;
int srv = 0;
int ncl = 0;
vm_map_t buffer_map;
vm_map_t bufferhdr_map;
extern void bsd_startupearly(void) __attribute__((section("__TEXT, initcode")));
void
bsd_startupearly(void)
{
vm_offset_t firstaddr;
vm_size_t size;
kern_return_t ret;
if (max_nbuf_headers == 0)
max_nbuf_headers = atop(sane_size / 50);
if ((customnbuf == 0) && (max_nbuf_headers > 16384))
max_nbuf_headers = 16384;
if (max_nbuf_headers < CONFIG_MIN_NBUF)
max_nbuf_headers = CONFIG_MIN_NBUF;
if ( (customnbuf == 0 ) && nbuf_hashelements == 0) {
nbuf_hashelements = atop(sane_size / 50);
if (nbuf_hashelements > 200000)
nbuf_hashelements = 200000;
} else
nbuf_hashelements = max_nbuf_headers;
if (niobuf_headers == 0)
niobuf_headers = max_nbuf_headers;
if (niobuf_headers > 4096)
niobuf_headers = 4096;
if (niobuf_headers < CONFIG_MIN_NIOBUF)
niobuf_headers = CONFIG_MIN_NIOBUF;
size = (max_nbuf_headers + niobuf_headers) * sizeof(struct buf);
size = round_page(size);
ret = kmem_suballoc(kernel_map,
&firstaddr,
size,
FALSE,
VM_FLAGS_ANYWHERE,
&bufferhdr_map);
if (ret != KERN_SUCCESS)
panic("Failed to create bufferhdr_map");
ret = kernel_memory_allocate(bufferhdr_map,
&firstaddr,
size,
0,
KMA_HERE | KMA_KOBJECT);
if (ret != KERN_SUCCESS)
panic("Failed to allocate bufferhdr_map");
buf_headers = (struct buf *) firstaddr;
bzero(buf_headers, size);
#if SOCKETS
{
int scale;
nmbclusters = bsd_mbuf_cluster_reserve() / MCLBYTES;
#if INET || INET6
if ((scale = nmbclusters / NMBCLUSTERS) > 1) {
tcp_sendspace *= scale;
tcp_recvspace *= scale;
if (tcp_sendspace > (64 * 1024))
tcp_sendspace = 64 * 1024;
if (tcp_recvspace > (64 * 1024))
tcp_recvspace = 64 * 1024;
}
#endif
}
#endif
desiredvnodes = (sane_size/65536) + 1024;
if (desiredvnodes > CONFIG_VNODES)
desiredvnodes = CONFIG_VNODES;
}
void
bsd_bufferinit(void)
{
kern_return_t ret;
cons.t_dev = makedev(12, 0);
bsd_startupearly();
#if SOCKETS
ret = kmem_suballoc(kernel_map,
(vm_offset_t *) & mbutl,
(vm_size_t) (nmbclusters * MCLBYTES),
FALSE,
VM_FLAGS_ANYWHERE,
&mb_map);
if (ret != KERN_SUCCESS)
panic("Failed to allocate mb_map\n");
#endif
bufinit();
}
int
bsd_mbuf_cluster_reserve(void)
{
if (sane_size > (64 * 1024 * 1024) || ncl) {
if ((nmbclusters = ncl) == 0) {
if ((nmbclusters = ((sane_size / 16)/MCLBYTES)) > 32768)
nmbclusters = 32768;
}
if (nmbclusters & 0x1)
--nmbclusters;
}
return (nmbclusters * MCLBYTES);
}