svn commit: r237056 - in user/andre/tcp_workqueue/sys: amd64/acpica amd64/amd64 amd64/include arm/arm arm/at91 arm/econa arm/include arm/mv arm/s3c2xx0 arm/sa11x0 arm/xscale/ixp425 arm/xscale/pxa c...

Andre Oppermann andre at FreeBSD.org
Thu Jun 14 10:48:42 UTC 2012


Author: andre
Date: Thu Jun 14 10:48:41 2012
New Revision: 237056
URL: http://svn.freebsd.org/changeset/base/237056

Log:
  Integrate from HEAD @r237055.

Modified:
  user/andre/tcp_workqueue/sys/amd64/acpica/acpi_wakecode.S
  user/andre/tcp_workqueue/sys/amd64/amd64/cpu_switch.S
  user/andre/tcp_workqueue/sys/amd64/amd64/mp_machdep.c
  user/andre/tcp_workqueue/sys/amd64/include/pcb.h
  user/andre/tcp_workqueue/sys/arm/arm/machdep.c
  user/andre/tcp_workqueue/sys/arm/at91/at91_machdep.c
  user/andre/tcp_workqueue/sys/arm/econa/econa_machdep.c
  user/andre/tcp_workqueue/sys/arm/include/machdep.h
  user/andre/tcp_workqueue/sys/arm/mv/mv_machdep.c
  user/andre/tcp_workqueue/sys/arm/mv/std.mv
  user/andre/tcp_workqueue/sys/arm/s3c2xx0/s3c24x0_machdep.c
  user/andre/tcp_workqueue/sys/arm/sa11x0/assabet_machdep.c
  user/andre/tcp_workqueue/sys/arm/xscale/ixp425/avila_machdep.c
  user/andre/tcp_workqueue/sys/arm/xscale/pxa/pxa_machdep.c
  user/andre/tcp_workqueue/sys/conf/options.arm
  user/andre/tcp_workqueue/sys/dev/ath/if_ath.c
  user/andre/tcp_workqueue/sys/dev/ath/if_ath_sysctl.c
  user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.c
  user/andre/tcp_workqueue/sys/dev/ath/if_athvar.h
  user/andre/tcp_workqueue/sys/dev/pci/pci_pci.c
  user/andre/tcp_workqueue/sys/i386/acpica/acpi_wakecode.S
  user/andre/tcp_workqueue/sys/i386/i386/swtch.s
  user/andre/tcp_workqueue/sys/i386/include/pcb.h
  user/andre/tcp_workqueue/sys/kern/kern_descrip.c
  user/andre/tcp_workqueue/sys/kern/uipc_usrreq.c
  user/andre/tcp_workqueue/sys/kern/vfs_syscalls.c
  user/andre/tcp_workqueue/sys/netinet/libalias/libalias.3
  user/andre/tcp_workqueue/sys/netinet/sctp_indata.c
  user/andre/tcp_workqueue/sys/netinet/sctp_indata.h
  user/andre/tcp_workqueue/sys/netinet/sctp_input.c
  user/andre/tcp_workqueue/sys/netinet/sctp_input.h
  user/andre/tcp_workqueue/sys/netinet/sctp_output.c
  user/andre/tcp_workqueue/sys/netinet/sctp_output.h
  user/andre/tcp_workqueue/sys/netinet/sctputil.c
  user/andre/tcp_workqueue/sys/netinet/sctputil.h
  user/andre/tcp_workqueue/sys/netinet6/sctp6_usrreq.c
  user/andre/tcp_workqueue/sys/netsmb/smb_dev.c
  user/andre/tcp_workqueue/sys/sys/cdefs.h
  user/andre/tcp_workqueue/sys/sys/filedesc.h
  user/andre/tcp_workqueue/sys/x86/acpica/acpi_wakeup.c
Directory Properties:
  user/andre/tcp_workqueue/sys/   (props changed)
  user/andre/tcp_workqueue/sys/conf/   (props changed)

Modified: user/andre/tcp_workqueue/sys/amd64/acpica/acpi_wakecode.S
==============================================================================
--- user/andre/tcp_workqueue/sys/amd64/acpica/acpi_wakecode.S	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/amd64/acpica/acpi_wakecode.S	Thu Jun 14 10:48:41 2012	(r237056)
@@ -220,7 +220,6 @@ wakeup_64:
 	mov	%ax, %ds
 
 	/* Restore arguments. */
-	movq	wakeup_cr3 - wakeup_start(%rbx), %rsi
 	movq	wakeup_pcb - wakeup_start(%rbx), %rdi
 	movq	wakeup_ret - wakeup_start(%rbx), %rax
 
@@ -273,10 +272,6 @@ bootgdtdesc:
 	.long	bootgdt - wakeup_start	/* Offset plus %ds << 4 */
 
 	ALIGN_DATA
-wakeup_cr4:		/* not used */
-	.quad	0
-wakeup_cr3:
-	.quad	0
 wakeup_pcb:
 	.quad	0
 wakeup_ret:

Modified: user/andre/tcp_workqueue/sys/amd64/amd64/cpu_switch.S
==============================================================================
--- user/andre/tcp_workqueue/sys/amd64/amd64/cpu_switch.S	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/amd64/amd64/cpu_switch.S	Thu Jun 14 10:48:41 2012	(r237056)
@@ -394,12 +394,13 @@ ENTRY(savectx)
 END(savectx)
 
 /*
- * resumectx(pcb in %rdi, cr3 in %rsi)
+ * resumectx(pcb)
  * Resuming processor state from pcb.
  */     
 ENTRY(resumectx)
 	/* Switch to KPML4phys. */
-	movq	%rsi,%cr3
+	movq	KPML4phys,%rax
+	movq	%rax,%cr3
 
 	/* Force kernel segment registers. */
 	movl	$KDSEL,%eax

Modified: user/andre/tcp_workqueue/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- user/andre/tcp_workqueue/sys/amd64/amd64/mp_machdep.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/amd64/amd64/mp_machdep.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -1429,9 +1429,6 @@ cpususpend_handler(void)
 		CPU_SET_ATOMIC(cpu, &suspended_cpus);
 	} else {
 		pmap_init_pat();
-#if 0
-		load_cr3(susppcbs[cpu]->pcb_cr3);
-#endif
 		initializecpu();
 		PCPU_SET(switchtime, 0);
 		PCPU_SET(switchticks, ticks);

Modified: user/andre/tcp_workqueue/sys/amd64/include/pcb.h
==============================================================================
--- user/andre/tcp_workqueue/sys/amd64/include/pcb.h	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/amd64/include/pcb.h	Thu Jun 14 10:48:41 2012	(r237056)
@@ -100,7 +100,7 @@ struct pcb {
 	register_t	pcb_xsmask;
 
 	/* fpu context for suspend/resume */
-	void *		pcb_fpususpend;
+	void		*pcb_fpususpend;
 
 	struct savefpu	*pcb_save;
 

Modified: user/andre/tcp_workqueue/sys/arm/arm/machdep.c
==============================================================================
--- user/andre/tcp_workqueue/sys/arm/arm/machdep.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/arm/arm/machdep.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_pager.h>
 
 #include <machine/armreg.h>
+#include <machine/atags.h>
 #include <machine/cpu.h>
 #include <machine/machdep.h>
 #include <machine/md_var.h>
@@ -110,6 +111,20 @@ extern int *end;
 extern vm_offset_t ksym_start, ksym_end;
 #endif
 
+#if defined(LINUX_BOOT_ABI)
+#define LBABI_MAX_BANKS	10
+
+uint32_t board_id;
+struct arm_lbabi_tag *atag_list;
+uint32_t revision;
+uint64_t serial;
+char linux_command_line[LBABI_MAX_COMMAND_LINE + 1];
+char atags[LBABI_MAX_COMMAND_LINE * 2];
+uint32_t memstart[LBABI_MAX_BANKS];
+uint32_t memsize[LBABI_MAX_BANKS];
+uint32_t membanks;
+#endif
+
 void
 sendsig(catcher, ksi, mask)
 	sig_t catcher;
@@ -663,10 +678,51 @@ makectx(struct trapframe *tf, struct pcb
 }
 
 /*
+ * Make a standard dump_avail array.  Can't make the phys_avail
+ * since we need to do that after we call pmap_bootstrap, but this
+ * is needed before pmap_boostrap.
+ *
+ * ARM_USE_SMALL_ALLOC uses dump_avail, so it must be filled before
+ * calling pmap_bootstrap.
+ */
+void
+arm_dump_avail_init(vm_offset_t memsize, size_t max)
+{
+#ifdef LINUX_BOOT_ABI
+	/*
+	 * Linux boot loader passes us the actual banks of memory, so use them
+	 * to construct the dump_avail array.
+	 */
+	if (membanks > 0) 
+	{
+		int i, j;
+
+		if (max < (membanks + 1) * 2)
+			panic("dump_avail[%d] too small for %d banks\n",
+			    max, membanks);
+		for (j = 0, i = 0; i < membanks; i++) {
+			dump_avail[j++] = round_page(memstart[i]);
+			dump_avail[j++] = trunc_page(memstart[i] + memsize[i]);
+		}
+		dump_avail[j++] = 0;
+		dump_avail[j++] = 0;
+		return;
+	}
+#endif
+	if (max < 4)
+		panic("dump_avail too small\n");
+
+	dump_avail[0] = round_page(PHYSADDR);
+	dump_avail[1] = trunc_page(PHYSADDR + memsize);
+	dump_avail[2] = 0;
+	dump_avail[3] = 0;
+}
+
+/*
  * Fake up a boot descriptor table
  */
 vm_offset_t
-fake_preload_metadata(void)
+fake_preload_metadata(struct arm_boot_params *abp __unused)
 {
 #ifdef DDB
 	vm_offset_t zstart = 0, zend = 0;
@@ -712,6 +768,139 @@ fake_preload_metadata(void)
 	return (lastaddr);
 }
 
+#if defined(LINUX_BOOT_ABI)
+vm_offset_t
+linux_parse_boot_param(struct arm_boot_params *abp)
+{
+	struct arm_lbabi_tag *walker;
+
+	/*
+	 * Linux boot ABI: r0 = 0, r1 is the board type (!= 0) and r2
+	 * is atags or dtb pointer.  If all of these aren't satisfied,
+	 * then punt.
+	 */
+	if (!(abp->abp_r0 == 0 && abp->abp_r1 != 0 && abp->abp_r2 != 0))
+		return 0;
+
+	board_id = abp->abp_r1;
+	walker = (struct arm_lbabi_tag *)
+	    (abp->abp_r2 + KERNVIRTADDR - KERNPHYSADDR);
+
+	/* xxx - Need to also look for binary device tree */
+	if (ATAG_TAG(walker) != ATAG_CORE)
+		return 0;
+
+	atag_list = walker;
+	while (ATAG_TAG(walker) != ATAG_NONE) {
+		switch (ATAG_TAG(walker)) {
+		case ATAG_CORE:
+			break;
+		case ATAG_MEM:
+			if (membanks < LBABI_MAX_BANKS) {
+				memstart[membanks] = walker->u.tag_mem.start;
+				memsize[membanks] = walker->u.tag_mem.size;
+			}
+			membanks++;
+			break;
+		case ATAG_INITRD2:
+			break;
+		case ATAG_SERIAL:
+			serial = walker->u.tag_sn.low |
+			    ((uint64_t)walker->u.tag_sn.high << 32);
+			break;
+		case ATAG_REVISION:
+			revision = walker->u.tag_rev.rev;
+			break;
+		case ATAG_CMDLINE:
+			/* XXX open question: Parse this for boothowto? */
+			bcopy(walker->u.tag_cmd.command, linux_command_line,
+			      ATAG_SIZE(walker));
+			break;
+		default:
+			break;
+		}
+		walker = ATAG_NEXT(walker);
+	}
+
+	/* Save a copy for later */
+	bcopy(atag_list, atags,
+	    (char *)walker - (char *)atag_list + ATAG_SIZE(walker));
+
+	return fake_preload_metadata(abp);
+}
+#endif
+
+#if defined(FREEBSD_BOOT_LOADER)
+vm_offset_t
+freebsd_parse_boot_param(struct arm_boot_params *abp)
+{
+	vm_offset_t lastaddr = 0;
+	void *mdp;
+	void *kmdp;
+
+	/*
+	 * Mask metadata pointer: it is supposed to be on page boundary. If
+	 * the first argument (mdp) doesn't point to a valid address the
+	 * bootloader must have passed us something else than the metadata
+	 * ptr, so we give up.  Also give up if we cannot find metadta section
+	 * the loader creates that we get all this data out of.
+	 */
+
+	if ((mdp = (void *)(abp->abp_r0 & ~PAGE_MASK)) == NULL)
+		return 0;
+	preload_metadata = mdp;
+	kmdp = preload_search_by_type("elf kernel");
+	if (kmdp == NULL)
+		return 0;
+
+	boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
+	kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
+	lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
+#ifdef DDB
+	ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
+	ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
+#endif
+	preload_addr_relocate = KERNVIRTADDR - KERNPHYSADDR;
+	return lastaddr;
+}
+#endif
+
+vm_offset_t
+default_parse_boot_param(struct arm_boot_params *abp)
+{
+	vm_offset_t lastaddr;
+
+#if defined(LINUX_BOOT_ABI)
+	if ((lastaddr = linux_parse_boot_param(abp)) != 0)
+		return lastaddr;
+#endif
+#if defined(FREEBSD_BOOT_LOADER)
+	if ((lastaddr = freebsd_parse_boot_param(abp)) != 0)
+		return lastaddr;
+#endif
+	/* Fall back to hardcoded metadata. */
+	lastaddr = fake_preload_metadata(abp);
+
+	return lastaddr;
+}
+
+/*
+ * Stub version of the boot parameter parsing routine.  We are
+ * called early in initarm, before even VM has been initialized.
+ * This routine needs to preserve any data that the boot loader
+ * has passed in before the kernel starts to grow past the end
+ * of the BSS, traditionally the place boot-loaders put this data.
+ *
+ * Since this is called so early, things that depend on the vm system
+ * being setup (including access to some SoC's serial ports), about
+ * all that can be done in this routine is to copy the arguments.
+ *
+ * This is the default boot parameter parsing routine.  Individual
+ * kernels/boards can override this weak function with one of their
+ * own.  We just fake metadata...
+ */
+__weak_reference(default_parse_boot_param, parse_boot_param);
+
 /*
  * Initialize proc0
  */

Modified: user/andre/tcp_workqueue/sys/arm/at91/at91_machdep.c
==============================================================================
--- user/andre/tcp_workqueue/sys/arm/at91/at91_machdep.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/arm/at91/at91_machdep.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -392,8 +392,8 @@ initarm(struct arm_boot_params *abp)
 	uint32_t memsize;
 	vm_offset_t lastaddr;
 
+	lastaddr = parse_boot_param(abp);
 	set_cpufuncs();
-	lastaddr = fake_preload_metadata();
 	pcpu_init(pcpup, 0, sizeof(struct pcpu));
 	PCPU_SET(curthread, &thread0);
 
@@ -552,19 +552,8 @@ initarm(struct arm_boot_params *abp)
 	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
 
 	pmap_curmaxkvaddr = afterkern + L1_S_SIZE * (KERNEL_PT_KERN_NUM - 1);
-
-	/*
-	 * ARM_USE_SMALL_ALLOC uses dump_avail, so it must be filled before
-	 * calling pmap_bootstrap.
-	 */
-	dump_avail[0] = PHYSADDR;
-	dump_avail[1] = PHYSADDR + memsize;
-	dump_avail[2] = 0;
-	dump_avail[3] = 0;
-
-	pmap_bootstrap(freemempos,
-	    KERNVIRTADDR + 3 * memsize,
-	    &kernel_l1pt);
+	arm_dump_avail_init(memsize, sizeof(dump_avail)/sizeof(dump_avail[0]));
+	pmap_bootstrap(freemempos, KERNVIRTADDR + 3 * memsize, &kernel_l1pt);
 	msgbufp = (void*)msgbufpv.pv_va;
 	msgbufinit(msgbufp, msgbufsize);
 	mutex_init();

Modified: user/andre/tcp_workqueue/sys/arm/econa/econa_machdep.c
==============================================================================
--- user/andre/tcp_workqueue/sys/arm/econa/econa_machdep.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/arm/econa/econa_machdep.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -194,9 +194,8 @@ initarm(struct arm_boot_params *abp)
 	int mem_info;
 
 	boothowto = RB_VERBOSE;
-
+	lastaddr = parse_boot_param(abp);
 	set_cpufuncs();
-	lastaddr = fake_preload_metadata();
 	pcpu_init(pcpup, 0, sizeof(struct pcpu));
 	PCPU_SET(curthread, &thread0);
 
@@ -343,19 +342,8 @@ initarm(struct arm_boot_params *abp)
 	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
 
 	pmap_curmaxkvaddr = afterkern + L1_S_SIZE * (KERNEL_PT_KERN_NUM - 1);
-
-	/*
-	 * ARM_USE_SMALL_ALLOC uses dump_avail, so it must be filled before
-	 * calling pmap_bootstrap.
-	 */
-	dump_avail[0] = PHYSADDR;
-	dump_avail[1] = PHYSADDR + memsize;
-	dump_avail[2] = 0;
-	dump_avail[3] = 0;
-
-	pmap_bootstrap(freemempos,
-	    KERNVIRTADDR + 3 * memsize,
-	    &kernel_l1pt);
+	arm_dump_avail_init(memsize, sizeof(dump_avail) / sizeof(dump_avail[0]));
+	pmap_bootstrap(freemempos, KERNVIRTADDR + 3 * memsize, &kernel_l1pt);
 
 	msgbufp = (void*)msgbufpv.pv_va;
 	msgbufinit(msgbufp, msgbufsize);

Modified: user/andre/tcp_workqueue/sys/arm/include/machdep.h
==============================================================================
--- user/andre/tcp_workqueue/sys/arm/include/machdep.h	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/arm/include/machdep.h	Thu Jun 14 10:48:41 2012	(r237056)
@@ -6,11 +6,21 @@
 
 /* misc prototypes used by the many arm machdeps */
 void arm_lock_cache_line(vm_offset_t);
-vm_offset_t fake_preload_metadata(void);
 void init_proc0(vm_offset_t kstack);
 void halt(void);
 void data_abort_handler(trapframe_t *);
 void prefetch_abort_handler(trapframe_t *);
 void undefinedinstruction_bounce(trapframe_t *);
 
+/* Early boot related helper functions */
+struct arm_boot_params;
+vm_offset_t default_parse_boot_param(struct arm_boot_params *abp);
+vm_offset_t freebsd_parse_boot_param(struct arm_boot_params *abp);
+vm_offset_t linux_parse_boot_param(struct arm_boot_params *abp);
+vm_offset_t fake_preload_metadata(struct arm_boot_params *abp);
+vm_offset_t parse_boot_param(struct arm_boot_params *abp);
+
+/* Setup standard arrays */
+void arm_dump_avail_init( vm_offset_t memsize, size_t max);
+
 #endif /* !_MACHINE_MACHDEP_H_ */

Modified: user/andre/tcp_workqueue/sys/arm/mv/mv_machdep.c
==============================================================================
--- user/andre/tcp_workqueue/sys/arm/mv/mv_machdep.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/arm/mv/mv_machdep.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -311,47 +311,22 @@ initarm(struct arm_boot_params *abp)
 	vm_offset_t dtbp, freemempos, l2_start, lastaddr;
 	uint32_t memsize, l2size;
 	void *kmdp;
-	void *mdp;
 	u_int l1pagetable;
 	int i = 0, j = 0, err_devmap = 0;
 
-	mdp = (void *)abp->abp_r0;
-	kmdp = NULL;
-	lastaddr = 0;
+        lastaddr = parse_boot_param(abp);
 	memsize = 0;
-	dtbp = (vm_offset_t)NULL;
-
 	set_cpufuncs();
 
 	/*
-	 * Mask metadata pointer: it is supposed to be on page boundary. If
-	 * the first argument (mdp) doesn't point to a valid address the
-	 * bootloader must have passed us something else than the metadata
-	 * ptr... In this case we want to fall back to some built-in settings.
-	 */
-	mdp = (void *)((uint32_t)mdp & ~PAGE_MASK);
-
-	/* Parse metadata and fetch parameters */
-	if (mdp != NULL) {
-		preload_metadata = mdp;
-		kmdp = preload_search_by_type("elf kernel");
-		if (kmdp != NULL) {
-			boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
-			kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
-			dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
-			lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND,
-			    vm_offset_t);
-#ifdef DDB
-			ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
-			ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
-#endif
-		}
-
-		preload_addr_relocate = KERNVIRTADDR - KERNPHYSADDR;
-	} else {
-		/* Fall back to hardcoded metadata. */
-		lastaddr = fake_preload_metadata();
-	}
+	 * Find the dtb passed in by the boot loader.
+	 */
+        kmdp = preload_search_by_type("elf kernel");
+        if (kmdp != NULL)
+		dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
+	else
+		dtbp = (vm_offset_t)NULL;
+		
 
 #if defined(FDT_DTB_STATIC)
 	/*
@@ -577,12 +552,7 @@ initarm(struct arm_boot_params *abp)
 	init_proc0(kernelstack.pv_va);
 
 	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
-
-	dump_avail[0] = 0;
-	dump_avail[1] = memsize;
-	dump_avail[2] = 0;
-	dump_avail[3] = 0;
-
+	arm_dump_avail_init(memsize, sizeof(dump_avail) / sizeof(dump_avail[0]));
 	pmap_bootstrap(freemempos, pmap_bootstrap_lastaddr, &kernel_l1pt);
 	msgbufp = (void *)msgbufpv.pv_va;
 	msgbufinit(msgbufp, msgbufsize);

Modified: user/andre/tcp_workqueue/sys/arm/mv/std.mv
==============================================================================
--- user/andre/tcp_workqueue/sys/arm/mv/std.mv	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/arm/mv/std.mv	Thu Jun 14 10:48:41 2012	(r237056)
@@ -3,3 +3,4 @@
 files		"../mv/files.mv"
 cpu		CPU_ARM9E
 makeoptions	CONF_CFLAGS="-march=armv5te"
+options		FREEBSD_BOOT_LOADER

Modified: user/andre/tcp_workqueue/sys/arm/s3c2xx0/s3c24x0_machdep.c
==============================================================================
--- user/andre/tcp_workqueue/sys/arm/s3c2xx0/s3c24x0_machdep.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/arm/s3c2xx0/s3c24x0_machdep.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -244,10 +244,9 @@ initarm(struct arm_boot_params *abp)
 	int i;
 	uint32_t memsize;
 
+	boothowto = 0;  /* Likely not needed */
+	lastaddr = parse_boot_param(abp);
 	i = 0;
-
-	boothowto = 0;
-
 	set_cpufuncs();
 	cpufuncs.cf_sleep = s3c24x0_sleep;
 	lastaddr = fake_preload_metadata();
@@ -410,18 +409,8 @@ initarm(struct arm_boot_params *abp)
 	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
 
 	pmap_curmaxkvaddr = afterkern + 0x100000 * (KERNEL_PT_KERN_NUM - 1);
-	/*
-	 * ARM_USE_SMALL_ALLOC uses dump_avail, so it must be filled before
-	 * calling pmap_bootstrap.
-	 */
-	dump_avail[0] = PHYSADDR;
-	dump_avail[1] = PHYSADDR + memsize;
-	dump_avail[2] = 0;
-	dump_avail[3] = 0;
-					
-	pmap_bootstrap(freemempos,
-	    KERNVIRTADDR + 3 * memsize,
-	    &kernel_l1pt);
+	arm_dump_avail_init(memsize, sizeof(dump_avail) / sizeof(dump_avail[0]));
+	pmap_bootstrap(freemempos, KERNVIRTADDR + 3 * memsize, &kernel_l1pt);
 	msgbufp = (void*)msgbufpv.pv_va;
 	msgbufinit(msgbufp, msgbufsize);
 	mutex_init();

Modified: user/andre/tcp_workqueue/sys/arm/sa11x0/assabet_machdep.c
==============================================================================
--- user/andre/tcp_workqueue/sys/arm/sa11x0/assabet_machdep.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/arm/sa11x0/assabet_machdep.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -215,10 +215,10 @@ initarm(struct arm_boot_params *abp)
 	uint32_t memsize = 32 * 1024 * 1024;
 	sa1110_uart_vaddr = SACOM1_VBASE;
 
-	boothowto = RB_VERBOSE | RB_SINGLE;
+	boothowto = RB_VERBOSE | RB_SINGLE;     /* Default value */
+	lastaddr = parse_boot_param(abp);
 	cninit();
 	set_cpufuncs();
-	lastaddr = fake_preload_metadata();
 	physmem = memsize / PAGE_SIZE;
 	pc = &__pcpu;
 	pcpu_init(pc, 0, sizeof(struct pcpu));

Modified: user/andre/tcp_workqueue/sys/arm/xscale/ixp425/avila_machdep.c
==============================================================================
--- user/andre/tcp_workqueue/sys/arm/xscale/ixp425/avila_machdep.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/arm/xscale/ixp425/avila_machdep.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -446,11 +446,7 @@ initarm(struct arm_boot_params *abp)
 	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
 
 	pmap_curmaxkvaddr = afterkern + PAGE_SIZE;
-	dump_avail[0] = PHYSADDR;
-	dump_avail[1] = PHYSADDR + memsize;
-	dump_avail[2] = 0;
-	dump_avail[3] = 0;
-
+	arm_dump_avail_init(memsize, sizeof(dump_avail) / sizeof(dump_avail[0]));
 	pmap_bootstrap(pmap_curmaxkvaddr, 0xd0000000, &kernel_l1pt);
 	msgbufp = (void*)msgbufpv.pv_va;
 	msgbufinit(msgbufp, msgbufsize);

Modified: user/andre/tcp_workqueue/sys/arm/xscale/pxa/pxa_machdep.c
==============================================================================
--- user/andre/tcp_workqueue/sys/arm/xscale/pxa/pxa_machdep.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/arm/xscale/pxa/pxa_machdep.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -174,8 +174,8 @@ initarm(struct arm_boot_params *abp)
 	int i, j;
 	uint32_t memsize[PXA2X0_SDRAM_BANKS], memstart[PXA2X0_SDRAM_BANKS];
 
-	lastaddr = parse_boot_param(abp);
 	set_cpufuncs();
+	lastaddr = fake_preload_metadata();
 	pcpu_init(pcpup, 0, sizeof(struct pcpu));
 	PCPU_SET(curthread, &thread0);
 

Modified: user/andre/tcp_workqueue/sys/conf/options.arm
==============================================================================
--- user/andre/tcp_workqueue/sys/conf/options.arm	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/conf/options.arm	Thu Jun 14 10:48:41 2012	(r237056)
@@ -16,9 +16,11 @@ CPU_XSCALE_IXP425	opt_global.h
 CPU_XSCALE_IXP435	opt_global.h
 CPU_XSCALE_PXA2X0	opt_global.h
 FLASHADDR		opt_global.h
+FREEBSD_BOOT_LOADER	opt_global.h
 IXP4XX_FLASH_SIZE	opt_global.h
 KERNPHYSADDR		opt_global.h
 KERNVIRTADDR		opt_global.h
+LINUX_BOOT_ABI		opt_global.h
 LOADERRAMADDR		opt_global.h
 PHYSADDR		opt_global.h
 QEMU_WORKAROUNDS	opt_global.h

Modified: user/andre/tcp_workqueue/sys/dev/ath/if_ath.c
==============================================================================
--- user/andre/tcp_workqueue/sys/dev/ath/if_ath.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/dev/ath/if_ath.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -524,7 +524,9 @@ ath_attach(u_int16_t devid, struct ath_s
 		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
 		| IEEE80211_C_SHSLOT		/* short slot time supported */
 		| IEEE80211_C_WPA		/* capable of WPA1+WPA2 */
+#ifndef	ATH_ENABLE_11N
 		| IEEE80211_C_BGSCAN		/* capable of bg scanning */
+#endif
 		| IEEE80211_C_TXFRAG		/* handle tx frags */
 #ifdef	ATH_ENABLE_DFS
 		| IEEE80211_C_DFS		/* Enable radar detection */
@@ -660,12 +662,6 @@ ath_attach(u_int16_t devid, struct ath_s
 		(void) ath_hal_settxchainmask(sc->sc_ah, tx_chainmask);
 	}
 
-	/*
-	 * The if_ath 11n support is completely not ready for normal use.
-	 * Enabling this option will likely break everything and everything.
-	 * Don't think of doing that unless you know what you're doing.
-	 */
-
 #ifdef	ATH_ENABLE_11N
 	/*
 	 * Query HT capabilities
@@ -2239,8 +2235,22 @@ _ath_getbuf_locked(struct ath_softc *sc,
 	if (bf != NULL && (bf->bf_flags & ATH_BUF_BUSY) == 0) {
 		if (btype == ATH_BUFTYPE_MGMT)
 			TAILQ_REMOVE(&sc->sc_txbuf_mgmt, bf, bf_list);
-		else
+		else {
 			TAILQ_REMOVE(&sc->sc_txbuf, bf, bf_list);
+			sc->sc_txbuf_cnt--;
+
+			/*
+			 * This shuldn't happen; however just to be
+			 * safe print a warning and fudge the txbuf
+			 * count.
+			 */
+			if (sc->sc_txbuf_cnt < 0) {
+				device_printf(sc->sc_dev,
+				    "%s: sc_txbuf_cnt < 0?\n",
+				    __func__);
+				sc->sc_txbuf_cnt = 0;
+			}
+		}
 	} else
 		bf = NULL;
 
@@ -2367,6 +2377,7 @@ ath_start(struct ifnet *ifp)
 		    "%s: sc_inreset_cnt > 0; bailing\n", __func__);
 		ATH_PCU_UNLOCK(sc);
 		IF_LOCK(&ifp->if_snd);
+		sc->sc_stats.ast_tx_qstop++;
 		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 		IF_UNLOCK(&ifp->if_snd);
 		return;
@@ -2375,6 +2386,17 @@ ath_start(struct ifnet *ifp)
 	ATH_PCU_UNLOCK(sc);
 
 	for (;;) {
+		ATH_TXBUF_LOCK(sc);
+		if (sc->sc_txbuf_cnt <= sc->sc_txq_data_minfree) {
+			/* XXX increment counter? */
+			ATH_TXBUF_UNLOCK(sc);
+			IF_LOCK(&ifp->if_snd);
+			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+			IF_UNLOCK(&ifp->if_snd);
+			break;
+		}
+		ATH_TXBUF_UNLOCK(sc);
+		
 		/*
 		 * Grab a TX buffer and associated resources.
 		 */
@@ -2883,6 +2905,7 @@ ath_desc_alloc(struct ath_softc *sc)
 		ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
 		return error;
 	}
+	sc->sc_txbuf_cnt = ath_txbuf;
 
 	error = ath_descdma_setup(sc, &sc->sc_txdma_mgmt, &sc->sc_txbuf_mgmt,
 			"tx_mgmt", ath_txbuf_mgmt, ATH_TXDESC);
@@ -3686,8 +3709,17 @@ ath_returnbuf_tail(struct ath_softc *sc,
 
 	if (bf->bf_flags & ATH_BUF_MGMT)
 		TAILQ_INSERT_TAIL(&sc->sc_txbuf_mgmt, bf, bf_list);
-	else
+	else {
 		TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
+		sc->sc_txbuf_cnt++;
+		if (sc->sc_txbuf_cnt > ath_txbuf) {
+			device_printf(sc->sc_dev,
+			    "%s: sc_txbuf_cnt > %d?\n",
+			    __func__,
+			    ath_txbuf);
+			sc->sc_txbuf_cnt = ath_txbuf;
+		}
+	}
 }
 
 void
@@ -3698,8 +3730,17 @@ ath_returnbuf_head(struct ath_softc *sc,
 
 	if (bf->bf_flags & ATH_BUF_MGMT)
 		TAILQ_INSERT_HEAD(&sc->sc_txbuf_mgmt, bf, bf_list);
-	else
+	else {
 		TAILQ_INSERT_HEAD(&sc->sc_txbuf, bf, bf_list);
+		sc->sc_txbuf_cnt++;
+		if (sc->sc_txbuf_cnt > ATH_TXBUF) {
+			device_printf(sc->sc_dev,
+			    "%s: sc_txbuf_cnt > %d?\n",
+			    __func__,
+			    ATH_TXBUF);
+			sc->sc_txbuf_cnt = ATH_TXBUF;
+		}
+	}
 }
 
 /*

Modified: user/andre/tcp_workqueue/sys/dev/ath/if_ath_sysctl.c
==============================================================================
--- user/andre/tcp_workqueue/sys/dev/ath/if_ath_sysctl.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/dev/ath/if_ath_sysctl.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -374,8 +374,8 @@ ath_sysctl_txagg(SYSCTL_HANDLER_ARGS)
 		t++;
 	}
 	ATH_TXBUF_UNLOCK(sc);
-	printf("Total TX buffers: %d; Total TX buffers busy: %d\n",
-	    t, i);
+	printf("Total TX buffers: %d; Total TX buffers busy: %d (%d)\n",
+	    t, i, sc->sc_txbuf_cnt);
 
 	i = t = 0;
 	ATH_TXBUF_LOCK(sc);
@@ -620,12 +620,11 @@ ath_sysctlattach(struct ath_softc *sc)
 		"tid_hwq_hi", CTLFLAG_RW, &sc->sc_tid_hwq_hi, 0,
 		"");
 
-#if 0
 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
 		"txq_data_minfree", CTLFLAG_RW, &sc->sc_txq_data_minfree,
 		0, "Minimum free buffers before adding a data frame"
 		" to the TX queue");
-#endif
+
 	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
 		"txq_mcastq_maxdepth", CTLFLAG_RW,
 		&sc->sc_txq_mcastq_maxdepth, 0,

Modified: user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.c
==============================================================================
--- user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -1308,7 +1308,28 @@ ath_tx_normal_setup(struct ath_softc *sc
 		return EIO;
 	}
 
-	/* Check if the TXQ wouldn't match what the hardware TXQ is! */
+	/*
+	 * There are two known scenarios where the frame AC doesn't match
+	 * what the destination TXQ is.
+	 *
+	 * + non-QoS frames (eg management?) that the net80211 stack has
+	 *   assigned a higher AC to, but since it's a non-QoS TID, it's
+	 *   being thrown into TID 16.  TID 16 gets the AC_BE queue.
+	 *   It's quite possible that management frames should just be
+	 *   direct dispatched to hardware rather than go via the software
+	 *   queue; that should be investigated in the future.  There are
+	 *   some specific scenarios where this doesn't make sense, mostly
+	 *   surrounding ADDBA request/response - hence why that is special
+	 *   cased.
+	 *
+	 * + Multicast frames going into the VAP mcast queue.  That shows up
+	 *   as "TXQ 11".
+	 *
+	 * This driver should eventually support separate TID and TXQ locking,
+	 * allowing for arbitrary AC frames to appear on arbitrary software
+	 * queues, being queued to the "correct" hardware queue when needed.
+	 */
+#if 0
 	if (txq != sc->sc_ac2q[pri]) {
 		device_printf(sc->sc_dev,
 		    "%s: txq=%p (%d), pri=%d, pri txq=%p (%d)\n",
@@ -1319,6 +1340,7 @@ ath_tx_normal_setup(struct ath_softc *sc
 		    sc->sc_ac2q[pri],
 		    sc->sc_ac2q[pri]->axq_qnum);
 	}
+#endif
 
 	/*
 	 * Calculate miscellaneous flags.

Modified: user/andre/tcp_workqueue/sys/dev/ath/if_athvar.h
==============================================================================
--- user/andre/tcp_workqueue/sys/dev/ath/if_athvar.h	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/dev/ath/if_athvar.h	Thu Jun 14 10:48:41 2012	(r237056)
@@ -211,15 +211,16 @@ struct ath_buf {
 
 	/* This state is kept to support software retries and aggregation */
 	struct {
-		int bfs_seqno;		/* sequence number of this packet */
-		int bfs_retries;	/* retry count */
-		uint16_t bfs_tid;	/* packet TID (or TID_MAX for no QoS) */
-		uint16_t bfs_pri;	/* packet AC priority */
-		struct ath_txq *bfs_txq;	/* eventual dest hardware TXQ */
-		uint16_t bfs_pktdur;	/* packet duration (at current rate?) */
-		uint16_t bfs_nframes;	/* number of frames in aggregate */
+		uint16_t bfs_seqno;	/* sequence number of this packet */
 		uint16_t bfs_ndelim;	/* number of delims for padding */
 
+		uint8_t bfs_retries;	/* retry count */
+		uint8_t bfs_tid;	/* packet TID (or TID_MAX for no QoS) */
+		uint8_t bfs_nframes;	/* number of frames in aggregate */
+		uint8_t bfs_pri;	/* packet AC priority */
+
+		struct ath_txq *bfs_txq;	/* eventual dest hardware TXQ */
+
 		u_int32_t bfs_aggr:1,		/* part of aggregate? */
 		    bfs_aggrburst:1,	/* part of aggregate burst? */
 		    bfs_isretried:1,	/* retried frame? */
@@ -501,6 +502,7 @@ struct ath_softc {
 
 	struct ath_descdma	sc_txdma;	/* TX descriptors */
 	ath_bufhead		sc_txbuf;	/* transmit buffer */
+	int			sc_txbuf_cnt;	/* how many buffers avail */
 	struct ath_descdma	sc_txdma_mgmt;	/* mgmt TX descriptors */
 	ath_bufhead		sc_txbuf_mgmt;	/* mgmt transmit buffer */
 	struct mtx		sc_txbuflock;	/* txbuf lock */

Modified: user/andre/tcp_workqueue/sys/dev/pci/pci_pci.c
==============================================================================
--- user/andre/tcp_workqueue/sys/dev/pci/pci_pci.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/dev/pci/pci_pci.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -893,9 +893,9 @@ pcib_grow_window(struct pcib_softc *sc, 
 	if (start < rman_get_start(w->res)) {
 		if (rman_first_free_region(&w->rman, &start_free, &end_free) !=
 		    0 || start_free != rman_get_start(w->res))
-			end_free = rman_get_start(w->res) - 1;
+			end_free = rman_get_start(w->res);
 		if (end_free > end)
-			end_free = end;
+			end_free = end + 1;
 
 		/* Move end_free down until it is properly aligned. */
 		end_free &= ~(align - 1);
@@ -913,7 +913,7 @@ pcib_grow_window(struct pcib_softc *sc, 
 			if (bootverbose)
 				printf("\tfront candidate range: %#lx-%#lx\n",
 				    front, end_free);
-			front &= (1ul << w->step) - 1;
+			front &= ~(1ul << w->step) - 1;
 			front = rman_get_start(w->res) - front;
 		} else
 			front = 0;

Modified: user/andre/tcp_workqueue/sys/i386/acpica/acpi_wakecode.S
==============================================================================
--- user/andre/tcp_workqueue/sys/i386/acpica/acpi_wakecode.S	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/i386/acpica/acpi_wakecode.S	Thu Jun 14 10:48:41 2012	(r237056)
@@ -142,8 +142,8 @@ wakeup_32:
 	mov	%ax, %ds
 
 	/* Get PCB and return address. */
-	movl	wakeup_pcb - wakeup_start(%ebx), %esi
-	movl	wakeup_ret - wakeup_start(%ebx), %edi
+	movl	wakeup_pcb - wakeup_start(%ebx), %ecx
+	movl	wakeup_ret - wakeup_start(%ebx), %edx
 
 	/* Restore CR4 and CR3. */
 	movl	wakeup_cr4 - wakeup_start(%ebx), %eax
@@ -166,7 +166,7 @@ wakeup_32:
 	jmp	1f
 1:
 	/* Jump to return address. */
-	jmp	*%edi
+	jmp	*%edx
 
 	.data
 

Modified: user/andre/tcp_workqueue/sys/i386/i386/swtch.s
==============================================================================
--- user/andre/tcp_workqueue/sys/i386/i386/swtch.s	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/i386/i386/swtch.s	Thu Jun 14 10:48:41 2012	(r237056)
@@ -460,13 +460,10 @@ ENTRY(savectx)
 END(savectx)
 
 /*
- * resumectx(pcb in %esi)
+ * resumectx(pcb) __fastcall
  * Resuming processor state from pcb.
  */
 ENTRY(resumectx)
-	/* Fetch PCB. */
-	movl	%esi,%ecx
-
 	/* Restore GDT. */
 	lgdt	PCB_GDT(%ecx)
 

Modified: user/andre/tcp_workqueue/sys/i386/include/pcb.h
==============================================================================
--- user/andre/tcp_workqueue/sys/i386/include/pcb.h	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/i386/include/pcb.h	Thu Jun 14 10:48:41 2012	(r237056)
@@ -97,7 +97,7 @@ struct trapframe;
 
 void	makectx(struct trapframe *, struct pcb *);
 int	savectx(struct pcb *) __returns_twice;
-void	resumectx(struct pcb *);
+void	resumectx(struct pcb *) __fastcall;
 #endif
 
 #endif /* _I386_PCB_H_ */

Modified: user/andre/tcp_workqueue/sys/kern/kern_descrip.c
==============================================================================
--- user/andre/tcp_workqueue/sys/kern/kern_descrip.c	Thu Jun 14 10:35:21 2012	(r237055)
+++ user/andre/tcp_workqueue/sys/kern/kern_descrip.c	Thu Jun 14 10:48:41 2012	(r237056)
@@ -119,7 +119,7 @@ static int	closefp(struct filedesc *fdp,
 static int	do_dup(struct thread *td, int flags, int old, int new,
     register_t *retval);
 static int	fd_first_free(struct filedesc *, int, int);
-static int	fd_last_used(struct filedesc *, int, int);
+static int	fd_last_used(struct filedesc *, int);
 static void	fdgrowtable(struct filedesc *, int);
 static void	fdunused(struct filedesc *fdp, int fd);
 static void	fdused(struct filedesc *fdp, int fd);
@@ -189,8 +189,9 @@ void	(*mq_fdclose)(struct thread *td, in
 static struct mtx	fdesc_mtx;
 
 /*
- * Find the first zero bit in the given bitmap, starting at low and not
- * exceeding size - 1.
+ * If low >= size, just return low. Otherwise find the first zero bit in the
+ * given bitmap, starting at low and not exceeding size - 1. Return size if
+ * not found.
  */
 static int
 fd_first_free(struct filedesc *fdp, int low, int size)
@@ -216,19 +217,16 @@ fd_first_free(struct filedesc *fdp, int 
 }
 
 /*
- * Find the highest non-zero bit in the given bitmap, starting at low and
- * not exceeding size - 1.
+ * Find the highest non-zero bit in the given bitmap, starting at 0 and
+ * not exceeding size - 1. Return -1 if not found.
  */
 static int
-fd_last_used(struct filedesc *fdp, int low, int size)
+fd_last_used(struct filedesc *fdp, int size)
 {
 	NDSLOTTYPE *map = fdp->fd_map;
 	NDSLOTTYPE mask;
 	int off, minoff;
 
-	if (low >= size)
-		return (-1);
-
 	off = NDSLOT(size);
 	if (size % NDENTRIES) {
 		mask = ~(~(NDSLOTTYPE)0 << (size % NDENTRIES));
@@ -236,16 +234,16 @@ fd_last_used(struct filedesc *fdp, int l
 			return (off * NDENTRIES + flsl(mask) - 1);
 		--off;
 	}
-	for (minoff = NDSLOT(low); off >= minoff; --off)
+	for (minoff = NDSLOT(0); off >= minoff; --off)
 		if (map[off] != 0)
 			return (off * NDENTRIES + flsl(map[off]) - 1);
-	return (low - 1);
+	return (-1);
 }
 
 static int
 fdisused(struct filedesc *fdp, int fd)
 {
-        KASSERT((unsigned int)fd < fdp->fd_nfiles,
+        KASSERT(fd >= 0 && fd < fdp->fd_nfiles,
             ("file descriptor %d out of range (0, %d)", fd, fdp->fd_nfiles));
 	return ((fdp->fd_map[NDSLOT(fd)] & NDBIT(fd)) != 0);
 }
@@ -285,7 +283,7 @@ fdunused(struct filedesc *fdp, int fd)
 	if (fd < fdp->fd_freefile)
 		fdp->fd_freefile = fd;
 	if (fd == fdp->fd_lastfile)
-		fdp->fd_lastfile = fd_last_used(fdp, 0, fd);
+		fdp->fd_lastfile = fd_last_used(fdp, fd);
 }
 
 /*
@@ -435,7 +433,7 @@ fdtofp(int fd, struct filedesc *fdp)
 
 	FILEDESC_LOCK_ASSERT(fdp);
 
-	if ((unsigned)fd >= fdp->fd_nfiles)
+	if (fd < 0 || fd >= fdp->fd_nfiles)
 		return (NULL);
 
 	return (fdp->fd_ofiles[fd]);
@@ -679,7 +677,7 @@ kern_fcntl(struct thread *td, int fd, in
 		vfslocked = 0;
 		/* Check for race with close */
 		FILEDESC_SLOCK(fdp);
-		if ((unsigned) fd >= fdp->fd_nfiles ||
+		if (fd < 0 || fd >= fdp->fd_nfiles ||
 		    fp != fdp->fd_ofiles[fd]) {
 			FILEDESC_SUNLOCK(fdp);
 			flp->l_whence = SEEK_SET;
@@ -1199,7 +1197,7 @@ kern_close(td, fd)
 	AUDIT_SYSCLOSE(td, fd);
 
 	FILEDESC_XLOCK(fdp);
-	if ((unsigned)fd >= fdp->fd_nfiles ||
+	if (fd < 0 || fd >= fdp->fd_nfiles ||
 	    (fp = fdp->fd_ofiles[fd]) == NULL) {
 		FILEDESC_XUNLOCK(fdp);
 		return (EBADF);
@@ -1461,7 +1459,7 @@ fdalloc(struct thread *td, int minfd, in
 {
 	struct proc *p = td->td_proc;
 	struct filedesc *fdp = p->p_fd;
-	int fd = -1, maxfd;
+	int fd = -1, maxfd, allocfd;
 #ifdef RACCT
 	int error;
 #endif
@@ -1476,32 +1474,33 @@ fdalloc(struct thread *td, int minfd, in
 	PROC_UNLOCK(p);
 
 	/*
-	 * Search the bitmap for a free descriptor.  If none is found, try
-	 * to grow the file table.  Keep at it until we either get a file
-	 * descriptor or run into process or system limits.
+	 * Search the bitmap for a free descriptor starting at minfd.
+	 * If none is found, grow the file table.
 	 */
-	for (;;) {
-		fd = fd_first_free(fdp, minfd, fdp->fd_nfiles);
-		if (fd >= maxfd)
-			return (EMFILE);
-		if (fd < fdp->fd_nfiles)
-			break;
+	fd = fd_first_free(fdp, minfd, fdp->fd_nfiles);
+	if (fd >= maxfd)
+		return (EMFILE);
+	if (fd >= fdp->fd_nfiles) {
+		allocfd = min(fd * 2, maxfd);
 #ifdef RACCT
 		PROC_LOCK(p);
-		error = racct_set(p, RACCT_NOFILE,
-		    min(fdp->fd_nfiles * 2, maxfd));
+		error = racct_set(p, RACCT_NOFILE, allocfd);
 		PROC_UNLOCK(p);
 		if (error != 0)
 			return (EMFILE);
 #endif
-		fdgrowtable(fdp, min(fdp->fd_nfiles * 2, maxfd));
+		/*
+		 * fd is already equal to first free descriptor >= minfd, so
+		 * we only need to grow the table and we are done.
+		 */
+		fdgrowtable(fdp, allocfd);
 	}
 
 	/*
 	 * Perform some sanity checks, then mark the file descriptor as
 	 * used and return it to the caller.
 	 */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-user mailing list