aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/vmm/amd/svm.c98
-rw-r--r--sys/amd64/vmm/amd/svm_msr.c7
-rw-r--r--sys/amd64/vmm/intel/vmx_msr.c7
-rw-r--r--sys/amd64/vmm/vmm_instruction_emul.c16
-rw-r--r--sys/amd64/vmm/x86.c51
-rw-r--r--sys/amd64/vmm/x86.h13
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_uart.h10
-rw-r--r--sys/arm/amlogic/aml8726/uart_dev_aml8726.c51
-rw-r--r--sys/arm/arm/cpufunc_asm_armv7.S3
-rw-r--r--sys/arm/arm/elf_machdep.c12
-rw-r--r--sys/arm/arm/generic_timer.c2
-rw-r--r--sys/arm/arm/machdep.c2
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c59
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_fb.c416
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_fbd.c263
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_mbox.c174
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h153
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_sdhci.c9
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_vcbus.h12
-rw-r--r--sys/arm/conf/AML872633
-rw-r--r--sys/arm/conf/ARMADAXP31
-rw-r--r--sys/arm/conf/ATMEL35
-rw-r--r--sys/arm/conf/AVILA1
-rw-r--r--sys/arm/conf/BEAGLEBONE32
-rw-r--r--sys/arm/conf/BWCT1
-rw-r--r--sys/arm/conf/CAMBRIA1
-rw-r--r--sys/arm/conf/CNS11XXNAS1
-rw-r--r--sys/arm/conf/CRB1
-rw-r--r--sys/arm/conf/CUBIEBOARD32
-rw-r--r--sys/arm/conf/CUBIEBOARD232
-rw-r--r--sys/arm/conf/DB-78XXX1
-rw-r--r--sys/arm/conf/DB-88F5XXX1
-rw-r--r--sys/arm/conf/DB-88F6XXX1
-rw-r--r--sys/arm/conf/DOCKSTAR1
-rw-r--r--sys/arm/conf/DREAMPLUG-10011
-rw-r--r--sys/arm/conf/EA32501
-rw-r--r--sys/arm/conf/EB92001
-rw-r--r--sys/arm/conf/EFIKA_MX31
-rw-r--r--sys/arm/conf/EP802191
-rw-r--r--sys/arm/conf/ETHERNUT51
-rw-r--r--sys/arm/conf/EXYNOS5.common1
-rw-r--r--sys/arm/conf/GUMSTIX1
-rw-r--r--sys/arm/conf/HL2001
-rw-r--r--sys/arm/conf/HL2011
-rw-r--r--sys/arm/conf/IMX5331
-rw-r--r--sys/arm/conf/IMX631
-rw-r--r--sys/arm/conf/IQ312441
-rw-r--r--sys/arm/conf/KB920X1
-rw-r--r--sys/arm/conf/LN2410SBC1
-rw-r--r--sys/arm/conf/NSLU1
-rw-r--r--sys/arm/conf/PANDABOARD32
-rw-r--r--sys/arm/conf/QILA9G201
-rw-r--r--sys/arm/conf/RK318832
-rw-r--r--sys/arm/conf/RPI-B32
-rw-r--r--sys/arm/conf/RPI240
-rw-r--r--sys/arm/conf/SAM9260EK33
-rw-r--r--sys/arm/conf/SAM9G20EK104
-rw-r--r--sys/arm/conf/SAM9X25EK1
-rw-r--r--sys/arm/conf/SHEEVAPLUG1
-rw-r--r--sys/arm/conf/SN9G451
-rw-r--r--sys/arm/conf/SOCKIT.common32
-rw-r--r--sys/arm/conf/TS78001
-rw-r--r--sys/arm/conf/VERSATILEPB32
-rw-r--r--sys/arm/conf/VIRT34
-rw-r--r--sys/arm/conf/VYBRID32
-rw-r--r--sys/arm/conf/ZEDBOARD31
-rw-r--r--sys/arm/conf/std.arm5
-rw-r--r--sys/arm/conf/std.armv638
-rw-r--r--sys/arm/freescale/imx/imx6_anatop.c64
-rw-r--r--sys/arm/freescale/imx/imx6_ccm.c14
-rw-r--r--sys/arm/freescale/imx/imx6_ccmreg.h2
-rw-r--r--sys/arm/freescale/imx/imx_ccmvar.h4
-rw-r--r--sys/arm64/arm64/nexus.c4
-rw-r--r--sys/boot/efi/boot1/Makefile3
-rw-r--r--sys/boot/efi/libefi/Makefile3
-rw-r--r--sys/boot/efi/loader/Makefile6
-rw-r--r--sys/boot/efi/loader/arch/arm64/Makefile.inc2
-rw-r--r--sys/boot/efi/loader/main.c3
-rw-r--r--sys/boot/sparc64/loader/main.c6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c8
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c7
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c7
-rw-r--r--sys/conf/files.powerpc1
-rw-r--r--sys/conf/options1
-rw-r--r--sys/dev/mrsas/mrsas.c312
-rw-r--r--sys/dev/mrsas/mrsas.h214
-rw-r--r--sys/dev/mrsas/mrsas_cam.c150
-rw-r--r--sys/dev/mrsas/mrsas_fp.c202
-rw-r--r--sys/dev/mrsas/mrsas_ioctl.c22
-rw-r--r--sys/dev/mrsas/mrsas_ioctl.h6
-rw-r--r--sys/dev/mrsas/mrsas_linux.c5
-rw-r--r--sys/dev/nand/nfc_rb.c275
-rw-r--r--sys/dev/ofw/ofwbus.c11
-rw-r--r--sys/dev/pccbb/pccbb_pci.c21
-rw-r--r--sys/dev/pci/pci_iov.c2
-rw-r--r--sys/dev/usb/serial/u3g.c1
-rw-r--r--sys/dev/usb/serial/uftdi.c1
-rw-r--r--sys/dev/usb/serial/usb_serial.c5
-rw-r--r--sys/dev/usb/usbdevs2
-rw-r--r--sys/dev/wpi/if_wpi.c461
-rw-r--r--sys/dev/wpi/if_wpi_debug.h11
-rw-r--r--sys/dev/wpi/if_wpireg.h36
-rw-r--r--sys/dev/wpi/if_wpivar.h27
-rw-r--r--sys/geom/part/g_part_mbr.c3
-rw-r--r--sys/kern/kern_shutdown.c6
-rw-r--r--sys/kern/kern_tc.c39
-rw-r--r--sys/kern/subr_nvlist.c165
-rw-r--r--sys/kern/subr_nvpair.c5
-rw-r--r--sys/net/if_types.h16
-rw-r--r--sys/net80211/ieee80211_adhoc.c9
-rw-r--r--sys/net80211/ieee80211_freebsd.h4
-rw-r--r--sys/net80211/ieee80211_node.c64
-rw-r--r--sys/netinet6/in6.c9
-rw-r--r--sys/netinet6/in6_ifattach.c4
-rw-r--r--sys/netinet6/nd6.c8
-rw-r--r--sys/netinet6/nd6_nbr.c6
-rw-r--r--sys/netpfil/ipfw/ip_fw_table.c8
-rw-r--r--sys/ofed/include/linux/linux_idr.c30
-rw-r--r--sys/sys/diskmbr.h6
-rw-r--r--sys/sys/nv.h10
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/timepps.h18
-rw-r--r--sys/vm/swap_pager.c79
-rw-r--r--sys/vm/vnode_pager.c23
-rw-r--r--sys/x86/include/specialreg.h5
126 files changed, 2736 insertions, 1836 deletions
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index 7cc13ca3fcf9..20e8f765cb9a 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -564,6 +564,19 @@ svm_vminit(struct vm *vm, pmap_t pmap)
return (svm_sc);
}
+/*
+ * Collateral for a generic SVM VM-exit.
+ */
+static void
+vm_exit_svm(struct vm_exit *vme, uint64_t code, uint64_t info1, uint64_t info2)
+{
+
+ vme->exitcode = VM_EXITCODE_SVM;
+ vme->u.svm.exitcode = code;
+ vme->u.svm.exitinfo1 = info1;
+ vme->u.svm.exitinfo2 = info2;
+}
+
static int
svm_cpl(struct vmcb_state *state)
{
@@ -1080,6 +1093,76 @@ clear_nmi_blocking(struct svm_softc *sc, int vcpu)
KASSERT(!error, ("%s: error %d setting intr_shadow", __func__, error));
}
+#define EFER_MBZ_BITS 0xFFFFFFFFFFFF0200UL
+
+static int
+svm_write_efer(struct svm_softc *sc, int vcpu, uint64_t newval, bool *retu)
+{
+ struct vm_exit *vme;
+ struct vmcb_state *state;
+ uint64_t changed, lma, oldval;
+ int error;
+
+ state = svm_get_vmcb_state(sc, vcpu);
+
+ oldval = state->efer;
+ VCPU_CTR2(sc->vm, vcpu, "wrmsr(efer) %#lx/%#lx", oldval, newval);
+
+ newval &= ~0xFE; /* clear the Read-As-Zero (RAZ) bits */
+ changed = oldval ^ newval;
+
+ if (newval & EFER_MBZ_BITS)
+ goto gpf;
+
+ /* APMv2 Table 14-5 "Long-Mode Consistency Checks" */
+ if (changed & EFER_LME) {
+ if (state->cr0 & CR0_PG)
+ goto gpf;
+ }
+
+ /* EFER.LMA = EFER.LME & CR0.PG */
+ if ((newval & EFER_LME) != 0 && (state->cr0 & CR0_PG) != 0)
+ lma = EFER_LMA;
+ else
+ lma = 0;
+
+ if ((newval & EFER_LMA) != lma)
+ goto gpf;
+
+ if (newval & EFER_NXE) {
+ if (!vm_cpuid_capability(sc->vm, vcpu, VCC_NO_EXECUTE))
+ goto gpf;
+ }
+
+ /*
+ * XXX bhyve does not enforce segment limits in 64-bit mode. Until
+ * this is fixed flag guest attempt to set EFER_LMSLE as an error.
+ */
+ if (newval & EFER_LMSLE) {
+ vme = vm_exitinfo(sc->vm, vcpu);
+ vm_exit_svm(vme, VMCB_EXIT_MSR, 1, 0);
+ *retu = true;
+ return (0);
+ }
+
+ if (newval & EFER_FFXSR) {
+ if (!vm_cpuid_capability(sc->vm, vcpu, VCC_FFXSR))
+ goto gpf;
+ }
+
+ if (newval & EFER_TCE) {
+ if (!vm_cpuid_capability(sc->vm, vcpu, VCC_TCE))
+ goto gpf;
+ }
+
+ error = svm_setreg(sc, vcpu, VM_REG_GUEST_EFER, newval);
+ KASSERT(error == 0, ("%s: error %d updating efer", __func__, error));
+ return (0);
+gpf:
+ vm_inject_gp(sc->vm, vcpu);
+ return (0);
+}
+
static int
emulate_wrmsr(struct svm_softc *sc, int vcpu, u_int num, uint64_t val,
bool *retu)
@@ -1089,7 +1172,7 @@ emulate_wrmsr(struct svm_softc *sc, int vcpu, u_int num, uint64_t val,
if (lapic_msr(num))
error = lapic_wrmsr(sc->vm, vcpu, num, val, retu);
else if (num == MSR_EFER)
- error = svm_setreg(sc, vcpu, VM_REG_GUEST_EFER, val);
+ error = svm_write_efer(sc, vcpu, val, retu);
else
error = svm_wrmsr(sc, vcpu, num, val, retu);
@@ -1189,19 +1272,6 @@ nrip_valid(uint64_t exitcode)
}
}
-/*
- * Collateral for a generic SVM VM-exit.
- */
-static void
-vm_exit_svm(struct vm_exit *vme, uint64_t code, uint64_t info1, uint64_t info2)
-{
-
- vme->exitcode = VM_EXITCODE_SVM;
- vme->u.svm.exitcode = code;
- vme->u.svm.exitinfo1 = info1;
- vme->u.svm.exitinfo2 = info2;
-}
-
static int
svm_vmexit(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit)
{
diff --git a/sys/amd64/vmm/amd/svm_msr.c b/sys/amd64/vmm/amd/svm_msr.c
index d3a6fe8ec7c8..088751a16728 100644
--- a/sys/amd64/vmm/amd/svm_msr.c
+++ b/sys/amd64/vmm/amd/svm_msr.c
@@ -110,6 +110,10 @@ svm_rdmsr(struct svm_softc *sc, int vcpu, u_int num, uint64_t *result,
int error = 0;
switch (num) {
+ case MSR_MCG_CAP:
+ case MSR_MCG_STATUS:
+ *result = 0;
+ break;
case MSR_MTRRcap:
case MSR_MTRRdefType:
case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
@@ -135,6 +139,9 @@ svm_wrmsr(struct svm_softc *sc, int vcpu, u_int num, uint64_t val, bool *retu)
int error = 0;
switch (num) {
+ case MSR_MCG_CAP:
+ case MSR_MCG_STATUS:
+ break; /* ignore writes */
case MSR_MTRRcap:
vm_inject_gp(sc->vm, vcpu);
break;
diff --git a/sys/amd64/vmm/intel/vmx_msr.c b/sys/amd64/vmm/intel/vmx_msr.c
index 526b0d1db2aa..3091f687d2c0 100644
--- a/sys/amd64/vmm/intel/vmx_msr.c
+++ b/sys/amd64/vmm/intel/vmx_msr.c
@@ -395,6 +395,10 @@ vmx_rdmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t *val, bool *retu)
error = 0;
switch (num) {
+ case MSR_MCG_CAP:
+ case MSR_MCG_STATUS:
+ *val = 0;
+ break;
case MSR_MTRRcap:
case MSR_MTRRdefType:
case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
@@ -433,6 +437,9 @@ vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu)
error = 0;
switch (num) {
+ case MSR_MCG_CAP:
+ case MSR_MCG_STATUS:
+ break; /* ignore writes */
case MSR_MTRRcap:
vm_inject_gp(vmx->vm, vcpuid);
break;
diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c
index 71723654d54f..c83f3e0ba7e9 100644
--- a/sys/amd64/vmm/vmm_instruction_emul.c
+++ b/sys/amd64/vmm/vmm_instruction_emul.c
@@ -178,14 +178,20 @@ static const struct vie_op one_byte_opcodes[256] = {
.op_byte = 0x23,
.op_type = VIE_OP_TYPE_AND,
},
+ [0x80] = {
+ /* Group 1 extended opcode */
+ .op_byte = 0x80,
+ .op_type = VIE_OP_TYPE_GROUP1,
+ .op_flags = VIE_OP_F_IMM8,
+ },
[0x81] = {
- /* XXX Group 1 extended opcode */
+ /* Group 1 extended opcode */
.op_byte = 0x81,
.op_type = VIE_OP_TYPE_GROUP1,
.op_flags = VIE_OP_F_IMM,
},
[0x83] = {
- /* XXX Group 1 extended opcode */
+ /* Group 1 extended opcode */
.op_byte = 0x83,
.op_type = VIE_OP_TYPE_GROUP1,
.op_flags = VIE_OP_F_IMM8,
@@ -1066,9 +1072,13 @@ emulate_cmp(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
rflags2 = getcc(size, op1, op2);
break;
+ case 0x80:
case 0x81:
case 0x83:
/*
+ * 80 /7 cmp r/m8, imm8
+ * REX + 80 /7 cmp r/m8, imm8
+ *
* 81 /7 cmp r/m16, imm16
* 81 /7 cmp r/m32, imm32
* REX.W + 81 /7 cmp r/m64, imm32 sign-extended to 64
@@ -1084,6 +1094,8 @@ emulate_cmp(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
* the status flags.
*
*/
+ if (vie->op.op_byte == 0x80)
+ size = 1;
/* get the first operand */
error = memread(vm, vcpuid, gpa, &op1, size, arg);
diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c
index 45e08b562ced..525e1d9b912f 100644
--- a/sys/amd64/vmm/x86.c
+++ b/sys/amd64/vmm/x86.c
@@ -230,10 +230,11 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
regs[1] |= (vcpu_id << CPUID_0000_0001_APICID_SHIFT);
/*
- * Don't expose VMX, SpeedStep or TME capability.
+ * Don't expose VMX, SpeedStep, TME or SMX capability.
* Advertise x2APIC capability and Hypervisor guest.
*/
regs[2] &= ~(CPUID2_VMX | CPUID2_EST | CPUID2_TM2);
+ regs[2] &= ~(CPUID2_SMX);
regs[2] |= CPUID2_HV;
@@ -285,17 +286,20 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
* Hide thermal monitoring
*/
regs[3] &= ~(CPUID_ACPI | CPUID_TM);
-
+
/*
- * Machine check handling is done in the host.
+ * Hide the debug store capability.
*/
- regs[3] &= ~(CPUID_MCA | CPUID_MCE);
-
- /*
- * Hide the debug store capability.
- */
regs[3] &= ~CPUID_DS;
+ /*
+ * Advertise the Machine Check and MTRR capability.
+ *
+ * Some guest OSes (e.g. Windows) will not boot if
+ * these features are absent.
+ */
+ regs[3] |= (CPUID_MCA | CPUID_MCE | CPUID_MTRR);
+
logical_cpus = threads_per_core * cores_per_package;
regs[1] &= ~CPUID_HTT_CORES;
regs[1] |= (logical_cpus & 0xff) << 16;
@@ -484,3 +488,34 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
return (1);
}
+
+bool
+vm_cpuid_capability(struct vm *vm, int vcpuid, enum vm_cpuid_capability cap)
+{
+ bool rv;
+
+ KASSERT(cap > 0 && cap < VCC_LAST, ("%s: invalid vm_cpu_capability %d",
+ __func__, cap));
+
+ /*
+ * Simply passthrough the capabilities of the host cpu for now.
+ */
+ rv = false;
+ switch (cap) {
+ case VCC_NO_EXECUTE:
+ if (amd_feature & AMDID_NX)
+ rv = true;
+ break;
+ case VCC_FFXSR:
+ if (amd_feature & AMDID_FFXSR)
+ rv = true;
+ break;
+ case VCC_TCE:
+ if (amd_feature2 & AMDID2_TCE)
+ rv = true;
+ break;
+ default:
+ panic("%s: unknown vm_cpu_capability %d", __func__, cap);
+ }
+ return (rv);
+}
diff --git a/sys/amd64/vmm/x86.h b/sys/amd64/vmm/x86.h
index 8401c15f989a..6f99d52931d7 100644
--- a/sys/amd64/vmm/x86.h
+++ b/sys/amd64/vmm/x86.h
@@ -62,4 +62,17 @@
int x86_emulate_cpuid(struct vm *vm, int vcpu_id, uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx);
+enum vm_cpuid_capability {
+ VCC_NONE,
+ VCC_NO_EXECUTE,
+ VCC_FFXSR,
+ VCC_TCE,
+ VCC_LAST
+};
+
+/*
+ * Return 'true' if the capability 'cap' is enabled in this virtual cpu
+ * and 'false' otherwise.
+ */
+bool vm_cpuid_capability(struct vm *vm, int vcpuid, enum vm_cpuid_capability);
#endif
diff --git a/sys/arm/amlogic/aml8726/aml8726_uart.h b/sys/arm/amlogic/aml8726/aml8726_uart.h
index ee633253390e..fbdd657fb2ca 100644
--- a/sys/arm/amlogic/aml8726/aml8726_uart.h
+++ b/sys/arm/amlogic/aml8726/aml8726_uart.h
@@ -94,4 +94,14 @@
#define AML_UART_MISC_RECV_IRQ_CNT_MASK 0xff
#define AML_UART_MISC_RECV_IRQ_CNT_SHIFT 0
+/*
+ * The new baud rate register is available on the
+ * aml8726-m6 and later.
+ */
+#define AML_UART_NEW_BAUD_REG 20
+#define AML_UART_NEW_BAUD_USE_XTAL_CLK (1 << 24)
+#define AML_UART_NEW_BAUD_RATE_EN (1 << 23)
+#define AML_UART_NEW_BAUD_RATE_MASK (0x7fffff << 0)
+#define AML_UART_NEW_BAUD_RATE_SHIFT 0
+
#endif /* _ARM_AMLOGIC_AML8726_UART_H */
diff --git a/sys/arm/amlogic/aml8726/uart_dev_aml8726.c b/sys/arm/amlogic/aml8726/uart_dev_aml8726.c
index 1dda52f42d18..5d21fb05569b 100644
--- a/sys/arm/amlogic/aml8726/uart_dev_aml8726.c
+++ b/sys/arm/amlogic/aml8726/uart_dev_aml8726.c
@@ -31,8 +31,8 @@
* uarts. For example ... though UART A as a 128 byte FIFO, the
* others only have a 64 byte FIFO.
*
- * Also, it's assumed that register 5 (the new baud rate register
- * present on the aml8726-m6) has not been activated.
+ * Also, it's assumed that the USE_XTAL_CLK feature (available on
+ * the aml8726-m6 and later) has not been activated.
*/
#include <sys/cdefs.h>
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <dev/uart/uart_cpu_fdt.h>
#include <dev/uart/uart_bus.h>
+#include <arm/amlogic/aml8726/aml8726_soc.h>
#include <arm/amlogic/aml8726/aml8726_uart.h>
#include "uart_if.h"
@@ -89,7 +90,7 @@ aml8726_uart_divisor(int rclk, int baudrate)
/* integer version of (rclk / baudrate + .5) */
divisor = ((rclk << 1) + baudrate) / (baudrate << 1);
- if (divisor == 0 || divisor >= 65536)
+ if (divisor == 0)
return (0);
actual_baud = rclk / divisor;
@@ -109,6 +110,7 @@ aml8726_uart_param(struct uart_bas *bas, int baudrate, int databits, int stopbit
{
uint32_t cr;
uint32_t mr;
+ uint32_t nbr;
int divisor;
cr = uart_getreg(bas, AML_UART_CONTROL_REG);
@@ -147,8 +149,29 @@ aml8726_uart_param(struct uart_bas *bas, int baudrate, int databits, int stopbit
/* Set baudrate. */
if (baudrate > 0 && bas->rclk != 0) {
divisor = aml8726_uart_divisor(bas->rclk / 4, baudrate) - 1;
- if (divisor > 0xffff)
- return (EINVAL);
+
+ switch (aml8726_soc_hw_rev) {
+ case AML_SOC_HW_REV_M6:
+ case AML_SOC_HW_REV_M8:
+ case AML_SOC_HW_REV_M8B:
+ if (divisor > (AML_UART_NEW_BAUD_RATE_MASK >>
+ AML_UART_NEW_BAUD_RATE_SHIFT))
+ return (EINVAL);
+
+ nbr = uart_getreg(bas, AML_UART_NEW_BAUD_REG);
+ nbr &= ~(AML_UART_NEW_BAUD_USE_XTAL_CLK |
+ AML_UART_NEW_BAUD_RATE_MASK);
+ nbr |= AML_UART_NEW_BAUD_RATE_EN |
+ (divisor << AML_UART_NEW_BAUD_RATE_SHIFT);
+ uart_setreg(bas, AML_UART_NEW_BAUD_REG, nbr);
+
+ divisor = 0;
+ break;
+ default:
+ if (divisor > 0xffff)
+ return (EINVAL);
+ break;
+ }
cr &= ~AML_UART_CONTROL_BAUD_MASK;
cr |= (divisor & AML_UART_CONTROL_BAUD_MASK);
@@ -187,7 +210,7 @@ aml8726_uart_init(struct uart_bas *bas, int baudrate, int databits, int stopbits
uint32_t cr;
uint32_t mr;
- aml8726_uart_param(bas, baudrate, databits, stopbits, parity);
+ (void)aml8726_uart_param(bas, baudrate, databits, stopbits, parity);
cr = uart_getreg(bas, AML_UART_CONTROL_REG);
/* Disable all interrupt sources. */
@@ -466,7 +489,7 @@ aml8726_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
{
struct uart_bas *bas;
int baudrate, divisor, error;
- uint32_t cr, mr;
+ uint32_t cr, mr, nbr;
bas = &sc->sc_bas;
uart_lock(sc->sc_hwmtx);
@@ -483,6 +506,20 @@ aml8726_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
divisor = ((mr >> AML_UART_MISC_BAUD_EXT_SHIFT) <<
AML_UART_CONTROL_BAUD_WIDTH) | cr;
+ switch (aml8726_soc_hw_rev) {
+ case AML_SOC_HW_REV_M6:
+ case AML_SOC_HW_REV_M8:
+ case AML_SOC_HW_REV_M8B:
+ nbr = uart_getreg(bas, AML_UART_NEW_BAUD_REG);
+ if ((nbr & AML_UART_NEW_BAUD_RATE_EN) != 0) {
+ divisor = (nbr & AML_UART_NEW_BAUD_RATE_MASK) >>
+ AML_UART_NEW_BAUD_RATE_SHIFT;
+ }
+ break;
+ default:
+ break;
+ }
+
baudrate = bas->rclk / 4 / (divisor + 1);
if (baudrate > 0)
*(int*)data = baudrate;
diff --git a/sys/arm/arm/cpufunc_asm_armv7.S b/sys/arm/arm/cpufunc_asm_armv7.S
index 25f052fd5553..7016d7eeffb0 100644
--- a/sys/arm/arm/cpufunc_asm_armv7.S
+++ b/sys/arm/arm/cpufunc_asm_armv7.S
@@ -266,6 +266,9 @@ END(armv7_icache_sync_all)
ENTRY_NP(armv7_icache_sync_range)
ldr ip, .Larmv7_icache_line_size
ldr ip, [ip]
+ sub r3, ip, #1 /* Address need not be aligned, but */
+ and r2, r0, r3 /* round length up if op spans line */
+ add r1, r1, r2 /* boundary: len += addr & linemask; */
.Larmv7_sync_next:
mcr CP15_DCCMVAC(r0)
mcr CP15_ICIMVAU(r0)
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index 9085d6799ac8..598decc3ff81 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -105,7 +105,6 @@ elf32_arm_abi_supported(struct image_params *imgp)
{
const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
-#ifdef __ARM_EABI__
/*
* When configured for EABI, FreeBSD supports EABI vesions 4 and 5.
*/
@@ -115,17 +114,6 @@ elf32_arm_abi_supported(struct image_params *imgp)
EF_ARM_EABI_VERSION(hdr->e_flags), imgp->args->fname);
return (FALSE);
}
-#else
- /*
- * When configured for OABI, that's all we do, so reject EABI binaries.
- */
- if (EF_ARM_EABI_VERSION(hdr->e_flags) != EF_ARM_EABI_VERSION_UNKNOWN) {
- if (bootverbose)
- uprintf("Attempting to execute EABI binary (rev %d) image %s",
- EF_ARM_EABI_VERSION(hdr->e_flags), imgp->args->fname);
- return (FALSE);
- }
-#endif
return (TRUE);
}
diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index d246a8732808..56db9cadfe2e 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -31,7 +31,7 @@
*/
/**
- * Cortex-A15 (and probably A7) Generic Timer
+ * Cortex-A7, Cortex-A15, ARMv8 and later Generic Timer
*/
#include <sys/cdefs.h>
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 68d31a94a520..a76e18a45c40 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -1055,7 +1055,6 @@ kenv_next(char *cp)
static void
print_kenv(void)
{
- int len;
char *cp;
debugf("loader passed (static) kenv:\n");
@@ -1065,7 +1064,6 @@ print_kenv(void)
}
debugf(" kern_envp = 0x%08x\n", (uint32_t)kern_envp);
- len = 0;
for (cp = kern_envp; cp != NULL; cp = kenv_next(cp))
debugf(" %x %s\n", (uint32_t)cp, cp);
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
index 2ea5b495c5c6..ab0f9014fb74 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (C) 2013-2014 Daisuke Aoyama <aoyama@peach.ne.jp>
+ * Copyright (C) 2013-2015 Daisuke Aoyama <aoyama@peach.ne.jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -60,21 +60,28 @@ __FBSDID("$FreeBSD$");
#define DPRINTF(fmt, ...)
#endif
-#define HZ2MHZ(freq) ((freq) / (1000 * 1000))
-#define MHZ2HZ(freq) ((freq) * (1000 * 1000))
-#define OFFSET2MVOLT(val) (1200 + ((val) * 25))
-#define MVOLT2OFFSET(val) (((val) - 1200) / 25)
-
-#define DEFAULT_ARM_FREQUENCY 700
-#define DEFAULT_CORE_FREQUENCY 250
-#define DEFAULT_SDRAM_FREQUENCY 400
-#define DEFAULT_LOWEST_FREQ 300
-#define TRANSITION_LATENCY 1000
-#define MIN_OVER_VOLTAGE -16
-#define MAX_OVER_VOLTAGE 6
-#define MSG_ERROR -999999999
-#define MHZSTEP 100
-#define HZSTEP (MHZ2HZ(MHZSTEP))
+#define HZ2MHZ(freq) ((freq) / (1000 * 1000))
+#define MHZ2HZ(freq) ((freq) * (1000 * 1000))
+
+#ifdef SOC_BCM2836
+#define OFFSET2MVOLT(val) (((val) / 1000))
+#define MVOLT2OFFSET(val) (((val) * 1000))
+#define DEFAULT_ARM_FREQUENCY 600
+#define DEFAULT_LOWEST_FREQ 600
+#else
+#define OFFSET2MVOLT(val) (1200 + ((val) * 25))
+#define MVOLT2OFFSET(val) (((val) - 1200) / 25)
+#define DEFAULT_ARM_FREQUENCY 700
+#define DEFAULT_LOWEST_FREQ 300
+#endif
+#define DEFAULT_CORE_FREQUENCY 250
+#define DEFAULT_SDRAM_FREQUENCY 400
+#define TRANSITION_LATENCY 1000
+#define MIN_OVER_VOLTAGE -16
+#define MAX_OVER_VOLTAGE 6
+#define MSG_ERROR -999999999
+#define MHZSTEP 100
+#define HZSTEP (MHZ2HZ(MHZSTEP))
#define TZ_ZEROC 2732
#define VC_LOCK(sc) do { \
@@ -1740,6 +1747,23 @@ bcm2835_cpufreq_make_freq_list(device_t dev, struct cf_setting *sets,
if (min_freq > cpufreq_lowest_freq)
min_freq = cpufreq_lowest_freq;
+#ifdef SOC_BCM2836
+ /* XXX RPi2 have only 900/600MHz */
+ idx = 0;
+ volts = sc->min_voltage_core;
+ sets[idx].freq = freq;
+ sets[idx].volts = volts;
+ sets[idx].lat = TRANSITION_LATENCY;
+ sets[idx].dev = dev;
+ idx++;
+ if (freq != min_freq) {
+ sets[idx].freq = min_freq;
+ sets[idx].volts = volts;
+ sets[idx].lat = TRANSITION_LATENCY;
+ sets[idx].dev = dev;
+ idx++;
+ }
+#else
/* from freq to min_freq */
for (idx = 0; idx < *count && freq >= min_freq; idx++) {
if (freq > sc->arm_min_freq)
@@ -1752,7 +1776,8 @@ bcm2835_cpufreq_make_freq_list(device_t dev, struct cf_setting *sets,
sets[idx].dev = dev;
freq -= MHZSTEP;
}
- *count = ++idx;
+#endif
+ *count = idx;
return (0);
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_fb.c b/sys/arm/broadcom/bcm2835/bcm2835_fb.c
index 3270da1a1a4c..6e6cfdaf6b62 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_fb.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_fb.c
@@ -29,46 +29,27 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/bio.h>
#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/endian.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
+#include <sys/kdb.h>
#include <sys/kernel.h>
-#include <sys/kthread.h>
-#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
-#include <sys/mutex.h>
-#include <sys/queue.h>
-#include <sys/resource.h>
-#include <sys/rman.h>
-#include <sys/time.h>
-#include <sys/timetc.h>
-#include <sys/fbio.h>
-#include <sys/consio.h>
-
-#include <sys/kdb.h>
-#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
-#include <machine/resource.h>
-#include <machine/intr.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <dev/fb/fbreg.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
-
-#include <dev/fb/fbreg.h>
#include <dev/syscons/syscons.h>
-#include <arm/broadcom/bcm2835/bcm2835_mbox.h>
-#include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
+#include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
#include "mbox_if.h"
-#define BCMFB_FONT_HEIGHT 16
-
struct argb {
uint8_t a;
uint8_t r;
@@ -101,40 +82,15 @@ static u_char mouse_pointer[16] = {
0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
};
-#define FB_WIDTH 640
-#define FB_HEIGHT 480
-#define FB_DEPTH 24
-
-struct bcm_fb_config {
- uint32_t xres;
- uint32_t yres;
- uint32_t vxres;
- uint32_t vyres;
- uint32_t pitch;
- uint32_t bpp;
- uint32_t xoffset;
- uint32_t yoffset;
- /* Filled by videocore */
- uint32_t base;
- uint32_t screen_size;
-};
+#define BCMFB_FONT_HEIGHT 16
+#define BCMFB_FONT_WIDTH 8
+#define FB_WIDTH 640
+#define FB_HEIGHT 480
+#define FB_DEPTH 24
struct bcmsc_softc {
- device_t dev;
- struct cdev * cdev;
- struct mtx mtx;
- bus_dma_tag_t dma_tag;
- bus_dmamap_t dma_map;
- struct bcm_fb_config* fb_config;
- bus_addr_t fb_config_phys;
- struct intr_config_hook init_hook;
-
-};
-
-struct video_adapter_softc {
/* Videoadpater part */
video_adapter_t va;
- int console;
intptr_t fb_addr;
intptr_t fb_paddr;
@@ -149,199 +105,75 @@ struct video_adapter_softc {
unsigned int ymargin;
unsigned char *font;
+ int fbswap;
int initialized;
};
-static struct bcmsc_softc *bcmsc_softc;
-static struct video_adapter_softc va_softc;
-
-#define bcm_fb_lock(_sc) mtx_lock(&(_sc)->mtx)
-#define bcm_fb_unlock(_sc) mtx_unlock(&(_sc)->mtx)
-#define bcm_fb_lock_assert(sc) mtx_assert(&(_sc)->mtx, MA_OWNED)
+static struct bcmsc_softc bcmsc;
static int bcm_fb_probe(device_t);
static int bcm_fb_attach(device_t);
-static void bcm_fb_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err);
static void bcmfb_update_margins(video_adapter_t *adp);
static int bcmfb_configure(int);
-static void
-bcm_fb_init(void *arg)
-{
- struct bcmsc_softc *sc = arg;
- struct video_adapter_softc *va_sc = &va_softc;
- int err;
- volatile struct bcm_fb_config* fb_config = sc->fb_config;
- phandle_t node;
- pcell_t cell;
- device_t mbox;
-
- node = ofw_bus_get_node(sc->dev);
-
- fb_config->xres = 0;
- fb_config->yres = 0;
- fb_config->bpp = 0;
-
- if ((OF_getprop(node, "broadcom,width", &cell, sizeof(cell))) > 0)
- fb_config->xres = (int)fdt32_to_cpu(cell);
- if (fb_config->xres == 0)
- fb_config->xres = FB_WIDTH;
-
- if ((OF_getprop(node, "broadcom,height", &cell, sizeof(cell))) > 0)
- fb_config->yres = (uint32_t)fdt32_to_cpu(cell);
- if (fb_config->yres == 0)
- fb_config->yres = FB_HEIGHT;
-
- if ((OF_getprop(node, "broadcom,depth", &cell, sizeof(cell))) > 0)
- fb_config->bpp = (uint32_t)fdt32_to_cpu(cell);
- if (fb_config->bpp == 0)
- fb_config->bpp = FB_DEPTH;
-
- fb_config->vxres = 0;
- fb_config->vyres = 0;
- fb_config->xoffset = 0;
- fb_config->yoffset = 0;
- fb_config->base = 0;
- fb_config->pitch = 0;
- fb_config->screen_size = 0;
-
- bus_dmamap_sync(sc->dma_tag, sc->dma_map,
- BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-
- mbox = devclass_get_device(devclass_find("mbox"), 0);
- if (mbox) {
- MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_FB, sc->fb_config_phys);
- MBOX_READ(mbox, BCM2835_MBOX_CHAN_FB, &err);
- }
- bus_dmamap_sync(sc->dma_tag, sc->dma_map,
- BUS_DMASYNC_POSTREAD);
-
- if (fb_config->base != 0) {
- device_printf(sc->dev, "%dx%d(%dx%d@%d,%d) %dbpp\n",
- fb_config->xres, fb_config->yres,
- fb_config->vxres, fb_config->vyres,
- fb_config->xoffset, fb_config->yoffset,
- fb_config->bpp);
-
-
- device_printf(sc->dev, "pitch %d, base 0x%08x, screen_size %d\n",
- fb_config->pitch, fb_config->base,
- fb_config->screen_size);
-
- va_sc->fb_addr = (intptr_t)pmap_mapdev(fb_config->base, fb_config->screen_size);
- va_sc->fb_paddr = fb_config->base;
- va_sc->fb_size = fb_config->screen_size;
- va_sc->depth = fb_config->bpp;
- va_sc->stride = fb_config->pitch;
-
- va_sc->width = fb_config->xres;
- va_sc->height = fb_config->yres;
- bcmfb_update_margins(&va_sc->va);
- }
- else {
- device_printf(sc->dev, "Failed to set framebuffer info\n");
- }
-
- config_intrhook_disestablish(&sc->init_hook);
-}
-
static int
bcm_fb_probe(device_t dev)
{
- int error = 0;
+ int error;
if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-fb"))
return (ENXIO);
-
device_set_desc(dev, "BCM2835 framebuffer device");
-
error = sc_probe_unit(device_get_unit(dev),
device_get_flags(dev) | SC_AUTODETECT_KBD);
if (error != 0)
return (error);
-
return (BUS_PROBE_DEFAULT);
}
static int
bcm_fb_attach(device_t dev)
{
- struct bcmsc_softc *sc = device_get_softc(dev);
- int dma_size = sizeof(struct bcm_fb_config);
- int err;
-
- if (bcmsc_softc)
- return (ENXIO);
+ struct bcm2835_fb_config fb;
+ struct bcmsc_softc *sc;
- bcmsc_softc = sc;
-
- sc->dev = dev;
- mtx_init(&sc->mtx, "bcm2835fb", "fb", MTX_DEF);
-
- err = bus_dma_tag_create(
- bus_get_dma_tag(sc->dev),
- PAGE_SIZE, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- dma_size, 1, /* maxsize, nsegments */
- dma_size, 0, /* maxsegsize, flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->dma_tag);
-
- err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->fb_config,
- 0, &sc->dma_map);
- if (err) {
- device_printf(dev, "cannot allocate framebuffer\n");
- goto fail;
- }
-
- err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->fb_config,
- dma_size, bcm_fb_dmamap_cb, &sc->fb_config_phys, BUS_DMA_NOWAIT);
-
- if (err) {
- device_printf(dev, "cannot load DMA map\n");
- goto fail;
- }
+ sc = (struct bcmsc_softc *)vid_get_adapter(vid_find_adapter(
+ "bcmfb", 0));
+ if (sc != NULL)
+ device_set_softc(dev, sc);
+ else
+ sc = device_get_softc(dev);
- err = (sc_attach_unit(device_get_unit(dev),
- device_get_flags(dev) | SC_AUTODETECT_KBD));
+ memset(&fb, 0, sizeof(fb));
+ if (bcm2835_mbox_fb_get_w_h(dev, &fb) != 0)
+ return (ENXIO);
+ fb.bpp = FB_DEPTH;
+ if (bcm2835_mbox_fb_init(dev, &fb) != 0)
+ return (ENXIO);
- if (err) {
+ sc->fb_addr = (intptr_t)pmap_mapdev(fb.base, fb.size);
+ sc->fb_paddr = fb.base;
+ sc->fb_size = fb.size;
+ sc->depth = fb.bpp;
+ sc->stride = fb.pitch;
+ sc->width = fb.xres;
+ sc->height = fb.yres;
+ bcmfb_update_margins(&sc->va);
+
+ if (sc_attach_unit(device_get_unit(dev),
+ device_get_flags(dev) | SC_AUTODETECT_KBD) != 0) {
device_printf(dev, "failed to attach syscons\n");
- goto fail;
+ return (ENXIO);
}
- /*
- * We have to wait until interrupts are enabled.
- * Mailbox relies on it to get data from VideoCore
- */
- sc->init_hook.ich_func = bcm_fb_init;
- sc->init_hook.ich_arg = sc;
-
- if (config_intrhook_establish(&sc->init_hook) != 0) {
- device_printf(dev, "failed to establish intrhook\n");
- return (ENOMEM);
- }
+ device_printf(dev, "%dx%d(%dx%d@%d,%d) %dbpp\n", fb.xres, fb.yres,
+ fb.vxres, fb.vyres, fb.xoffset, fb.yoffset, fb.bpp);
+ device_printf(dev,
+ "fbswap: %d, pitch %d, base 0x%08x, screen_size %d\n",
+ sc->fbswap, fb.pitch, fb.base, fb.size);
return (0);
-
-fail:
- return (ENXIO);
-}
-
-
-static void
-bcm_fb_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
-{
- bus_addr_t *addr;
-
- if (err)
- return;
-
- addr = (bus_addr_t*)arg;
- *addr = PHYS_TO_VCBUS(segs[0].ds_addr);
}
static device_method_t bcm_fb_methods[] = {
@@ -504,13 +336,13 @@ bcmrend_set_cursor(scr_stat* scp, int base, int height, int blink)
static void
bcmrend_draw_cursor(scr_stat* scp, int off, int blink, int on, int flip)
{
- video_adapter_t* adp = scp->sc->adp;
- struct video_adapter_softc *sc;
- int row, col;
+ int bytes, col, i, j, row;
+ struct bcmsc_softc *sc;
uint8_t *addr;
- int i, j, bytes;
+ video_adapter_t *adp;
- sc = (struct video_adapter_softc *)adp;
+ adp = scp->sc->adp;
+ sc = (struct bcmsc_softc *)adp;
if (scp->curs_attr.height <= 0)
return;
@@ -529,8 +361,7 @@ bcmrend_draw_cursor(scr_stat* scp, int off, int blink, int on, int flip)
+ (row + sc->ymargin)*(sc->stride)
+ (sc->depth/8) * (col + sc->xmargin);
- bytes = sc->depth/8;
-
+ bytes = sc->depth / 8;
/* our cursor consists of simply inverting the char under it */
for (i = 0; i < adp->va_info.vi_cheight; i++) {
for (j = 0; j < adp->va_info.vi_cwidth; j++) {
@@ -577,56 +408,80 @@ extern u_char dflt_font_16[];
static void
bcmfb_update_margins(video_adapter_t *adp)
{
- struct video_adapter_softc *sc;
+ struct bcmsc_softc *sc;
video_info_t *vi;
- sc = (struct video_adapter_softc *)adp;
+ sc = (struct bcmsc_softc *)adp;
vi = &adp->va_info;
sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
- sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
+ sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight)) / 2;
}
static int
bcmfb_configure(int flags)
{
- struct video_adapter_softc *va_sc;
-
- va_sc = &va_softc;
- phandle_t display, root;
+ char bootargs[2048], *n, *p, *v;
pcell_t cell;
+ phandle_t chosen, display, root;
+ struct bcmsc_softc *sc;
- if (va_sc->initialized)
+ sc = &bcmsc;
+ if (sc->initialized)
return (0);
- va_sc->width = 0;
- va_sc->height = 0;
+ sc->width = 0;
+ sc->height = 0;
/*
* It seems there is no way to let syscons framework know
* that framebuffer resolution has changed. So just try
- * to fetch data from FDT and go with defaults if failed
+ * to fetch data from FDT bootargs, FDT display data and
+ * finally go with defaults if everything else has failed.
*/
+ chosen = OF_finddevice("/chosen");
+ if (chosen != 0 &&
+ OF_getprop(chosen, "bootargs", &bootargs, sizeof(bootargs)) > 0) {
+ p = bootargs;
+ while ((v = strsep(&p, " ")) != NULL) {
+ if (*v == '\0')
+ continue;
+ n = strsep(&v, "=");
+ if (strcmp(n, "bcm2708_fb.fbwidth") == 0 && v != NULL)
+ sc->width = (unsigned int)strtol(v, NULL, 0);
+ else if (strcmp(n, "bcm2708_fb.fbheight") == 0 &&
+ v != NULL)
+ sc->height = (unsigned int)strtol(v, NULL, 0);
+ else if (strcmp(n, "bcm2708_fb.fbswap") == 0 &&
+ v != NULL)
+ if (*v == '1')
+ sc->fbswap = 1;
+ }
+ }
+
root = OF_finddevice("/");
if ((root != 0) &&
(display = fdt_find_compatible(root, "broadcom,bcm2835-fb", 1))) {
- if ((OF_getprop(display, "broadcom,width",
- &cell, sizeof(cell))) > 0)
- va_sc->width = (int)fdt32_to_cpu(cell);
+ if (sc->width == 0) {
+ if ((OF_getprop(display, "broadcom,width",
+ &cell, sizeof(cell))) > 0)
+ sc->width = (int)fdt32_to_cpu(cell);
+ }
- if ((OF_getprop(display, "broadcom,height",
- &cell, sizeof(cell))) > 0)
- va_sc->height = (int)fdt32_to_cpu(cell);
+ if (sc->height == 0) {
+ if ((OF_getprop(display, "broadcom,height",
+ &cell, sizeof(cell))) > 0)
+ sc->height = (int)fdt32_to_cpu(cell);
+ }
}
- if (va_sc->width == 0)
- va_sc->width = FB_WIDTH;
- if (va_sc->height == 0)
- va_sc->height = FB_HEIGHT;
-
- bcmfb_init(0, &va_sc->va, 0);
+ if (sc->width == 0)
+ sc->width = FB_WIDTH;
+ if (sc->height == 0)
+ sc->height = FB_HEIGHT;
- va_sc->initialized = 1;
+ bcmfb_init(0, &sc->va, 0);
+ sc->initialized = 1;
return (0);
}
@@ -641,20 +496,19 @@ bcmfb_probe(int unit, video_adapter_t **adp, void *arg, int flags)
static int
bcmfb_init(int unit, video_adapter_t *adp, int flags)
{
- struct video_adapter_softc *sc;
+ struct bcmsc_softc *sc;
video_info_t *vi;
- sc = (struct video_adapter_softc *)adp;
+ sc = (struct bcmsc_softc *)adp;
vi = &adp->va_info;
vid_init_struct(adp, "bcmfb", -1, unit);
sc->font = dflt_font_16;
vi->vi_cheight = BCMFB_FONT_HEIGHT;
- vi->vi_cwidth = 8;
-
- vi->vi_width = sc->width/8;
- vi->vi_height = sc->height/vi->vi_cheight;
+ vi->vi_cwidth = BCMFB_FONT_WIDTH;
+ vi->vi_width = sc->width / vi->vi_cwidth;
+ vi->vi_height = sc->height / vi->vi_cheight;
/*
* Clamp width/height to syscons maximums
@@ -665,8 +519,7 @@ bcmfb_init(int unit, video_adapter_t *adp, int flags)
vi->vi_height = ROW;
sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
- sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
-
+ sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight)) / 2;
adp->va_window = (vm_offset_t) bcmfb_static_window;
adp->va_flags |= V_ADP_FONT /* | V_ADP_COLOR | V_ADP_MODECHANGE */;
@@ -706,8 +559,9 @@ static int
bcmfb_load_font(video_adapter_t *adp, int page, int size, int width,
u_char *data, int c, int count)
{
- struct video_adapter_softc *sc = (struct video_adapter_softc *)adp;
+ struct bcmsc_softc *sc;
+ sc = (struct bcmsc_softc *)adp;
sc->font = data;
return (0);
@@ -780,9 +634,9 @@ static int
bcmfb_blank_display(video_adapter_t *adp, int mode)
{
- struct video_adapter_softc *sc;
+ struct bcmsc_softc *sc;
- sc = (struct video_adapter_softc *)adp;
+ sc = (struct bcmsc_softc *)adp;
if (sc && sc->fb_addr)
memset((void*)sc->fb_addr, 0, sc->fb_size);
@@ -793,9 +647,9 @@ static int
bcmfb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
int prot, vm_memattr_t *memattr)
{
- struct video_adapter_softc *sc;
+ struct bcmsc_softc *sc;
- sc = (struct video_adapter_softc *)adp;
+ sc = (struct bcmsc_softc *)adp;
/*
* This might be a legacy VGA mem request: if so, just point it at the
@@ -812,10 +666,10 @@ bcmfb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
static int
bcmfb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
{
- struct video_adapter_softc *sc;
+ struct bcmsc_softc *sc;
struct fbtype *fb;
- sc = (struct video_adapter_softc *)adp;
+ sc = (struct bcmsc_softc *)adp;
switch (cmd) {
case FBIOGTYPE:
@@ -897,16 +751,13 @@ bcmfb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
static int
bcmfb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
{
- struct video_adapter_softc *sc;
- int row;
- int col;
- int i, j, k;
- uint8_t *addr;
+ int bytes, col, i, j, k, row;
+ struct bcmsc_softc *sc;
u_char *p;
- uint8_t fg, bg, color;
+ uint8_t *addr, fg, bg, color;
uint16_t rgb;
- sc = (struct video_adapter_softc *)adp;
+ sc = (struct bcmsc_softc *)adp;
if (sc->fb_addr == 0)
return (0);
@@ -921,6 +772,7 @@ bcmfb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
fg = a & 0xf ;
bg = (a >> 4) & 0xf;
+ bytes = sc->depth / 8;
for (i = 0; i < BCMFB_FONT_HEIGHT; i++) {
for (j = 0, k = 7; j < 8; j++, k--) {
if ((p[i] & (1 << k)) == 0)
@@ -930,22 +782,32 @@ bcmfb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
switch (sc->depth) {
case 32:
- addr[4*j+0] = bcmfb_palette[color].r;
- addr[4*j+1] = bcmfb_palette[color].g;
- addr[4*j+2] = bcmfb_palette[color].b;
- addr[4*j+3] = bcmfb_palette[color].a;
- break;
case 24:
- addr[3*j] = bcmfb_palette[color].r;
- addr[3*j+1] = bcmfb_palette[color].g;
- addr[3*j+2] = bcmfb_palette[color].b;
+ if (sc->fbswap) {
+ addr[bytes * j + 0] =
+ bcmfb_palette[color].b;
+ addr[bytes * j + 1] =
+ bcmfb_palette[color].g;
+ addr[bytes * j + 2] =
+ bcmfb_palette[color].r;
+ } else {
+ addr[bytes * j + 0] =
+ bcmfb_palette[color].r;
+ addr[bytes * j + 1] =
+ bcmfb_palette[color].g;
+ addr[bytes * j + 2] =
+ bcmfb_palette[color].b;
+ }
+ if (sc->depth == 32)
+ addr[bytes * j + 3] =
+ bcmfb_palette[color].a;
break;
case 16:
rgb = (bcmfb_palette[color].r >> 3) << 11;
rgb |= (bcmfb_palette[color].g >> 2) << 5;
rgb |= (bcmfb_palette[color].b >> 3);
- addr[2*j] = rgb & 0xff;
- addr[2*j + 1] = (rgb >> 8) & 0xff;
+ addr[bytes * j] = rgb & 0xff;
+ addr[bytes * j + 1] = (rgb >> 8) & 0xff;
default:
/* Not supported yet */
break;
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
index f41e6e26c0e9..34a7af8a07b6 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
@@ -35,170 +35,35 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bio.h>
#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/endian.h>
+#include <sys/fbio.h>
#include <sys/kernel.h>
-#include <sys/kthread.h>
-#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
-#include <sys/mutex.h>
-#include <sys/queue.h>
-#include <sys/resource.h>
-#include <sys/rman.h>
-#include <sys/time.h>
-#include <sys/timetc.h>
-#include <sys/fbio.h>
-#include <sys/consio.h>
-
-#include <sys/kdb.h>
#include <vm/vm.h>
#include <vm/pmap.h>
-#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/cpufunc.h>
-#include <machine/fdt.h>
-#include <machine/resource.h>
-#include <machine/intr.h>
-
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/fb/fbreg.h>
#include <dev/vt/vt.h>
+#include <dev/vt/colors/vt_termcolors.h>
-#include <arm/broadcom/bcm2835/bcm2835_mbox.h>
-#include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
+#include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
#include "fb_if.h"
#include "mbox_if.h"
-#define FB_WIDTH 640
-#define FB_HEIGHT 480
-#define FB_DEPTH 24
-
-struct bcm_fb_config {
- uint32_t xres;
- uint32_t yres;
- uint32_t vxres;
- uint32_t vyres;
- uint32_t pitch;
- uint32_t bpp;
- uint32_t xoffset;
- uint32_t yoffset;
- /* Filled by videocore */
- uint32_t base;
- uint32_t screen_size;
-};
+#define FB_DEPTH 24
struct bcmsc_softc {
- device_t dev;
struct fb_info *info;
- bus_dma_tag_t dma_tag;
- bus_dmamap_t dma_map;
- struct bcm_fb_config* fb_config;
- bus_addr_t fb_config_phys;
- struct intr_config_hook init_hook;
};
static int bcm_fb_probe(device_t);
static int bcm_fb_attach(device_t);
-static void bcm_fb_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg,
- int err);
-
-static void
-bcm_fb_init(void *arg)
-{
- volatile struct bcm_fb_config *fb_config;
- struct bcmsc_softc *sc;
- struct fb_info *info;
- phandle_t node;
- pcell_t cell;
- device_t mbox;
- device_t fbd;
- int err = 0;
-
- sc = arg;
- fb_config = sc->fb_config;
- node = ofw_bus_get_node(sc->dev);
-
- fb_config->xres = 0;
- fb_config->yres = 0;
- fb_config->bpp = 0;
- fb_config->vxres = 0;
- fb_config->vyres = 0;
- fb_config->xoffset = 0;
- fb_config->yoffset = 0;
- fb_config->base = 0;
- fb_config->pitch = 0;
- fb_config->screen_size = 0;
-
- if ((OF_getprop(node, "broadcom,width", &cell, sizeof(cell))) > 0)
- fb_config->xres = (int)fdt32_to_cpu(cell);
- if (fb_config->xres == 0)
- fb_config->xres = FB_WIDTH;
-
- if ((OF_getprop(node, "broadcom,height", &cell, sizeof(cell))) > 0)
- fb_config->yres = (uint32_t)fdt32_to_cpu(cell);
- if (fb_config->yres == 0)
- fb_config->yres = FB_HEIGHT;
-
- if ((OF_getprop(node, "broadcom,depth", &cell, sizeof(cell))) > 0)
- fb_config->bpp = (uint32_t)fdt32_to_cpu(cell);
- if (fb_config->bpp == 0)
- fb_config->bpp = FB_DEPTH;
-
- bus_dmamap_sync(sc->dma_tag, sc->dma_map,
- BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-
- mbox = devclass_get_device(devclass_find("mbox"), 0);
- if (mbox) {
- MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_FB, sc->fb_config_phys);
- MBOX_READ(mbox, BCM2835_MBOX_CHAN_FB, &err);
- }
- bus_dmamap_sync(sc->dma_tag, sc->dma_map,
- BUS_DMASYNC_POSTREAD);
-
- if (fb_config->base != 0) {
- device_printf(sc->dev, "%dx%d(%dx%d@%d,%d) %dbpp\n",
- fb_config->xres, fb_config->yres,
- fb_config->vxres, fb_config->vyres,
- fb_config->xoffset, fb_config->yoffset,
- fb_config->bpp);
-
- device_printf(sc->dev, "pitch %d, base 0x%08x, screen_size %d\n",
- fb_config->pitch, fb_config->base,
- fb_config->screen_size);
-
- info = malloc(sizeof(struct fb_info), M_DEVBUF,
- M_WAITOK | M_ZERO);
- info->fb_name = device_get_nameunit(sc->dev);
- info->fb_vbase = (intptr_t)pmap_mapdev(fb_config->base,
- fb_config->screen_size);
- info->fb_pbase = fb_config->base;
- info->fb_size = fb_config->screen_size;
- info->fb_bpp = info->fb_depth = fb_config->bpp;
- info->fb_stride = fb_config->pitch;
- info->fb_width = fb_config->xres;
- info->fb_height = fb_config->yres;
-
- sc->info = info;
-
- fbd = device_add_child(sc->dev, "fbd",
- device_get_unit(sc->dev));
- if (fbd == NULL)
- device_printf(sc->dev, "Failed to add fbd child\n");
- else if (device_probe_and_attach(fbd) != 0)
- device_printf(sc->dev, "Failed to attach fbd device\n");
- } else {
- device_printf(sc->dev, "Failed to set framebuffer info\n");
- }
-
- config_intrhook_disestablish(&sc->init_hook);
-}
static int
bcm_fb_probe(device_t dev)
@@ -214,66 +79,82 @@ bcm_fb_probe(device_t dev)
static int
bcm_fb_attach(device_t dev)
{
- struct bcmsc_softc *sc = device_get_softc(dev);
- int dma_size = sizeof(struct bcm_fb_config);
- int err;
-
- sc->dev = dev;
+ char bootargs[2048], *n, *p, *v;
+ device_t fbd;
+ int fbswap;
+ phandle_t chosen;
+ struct bcm2835_fb_config fb;
+ struct bcmsc_softc *sc;
+ struct fb_info *info;
- err = bus_dma_tag_create(
- bus_get_dma_tag(sc->dev),
- PAGE_SIZE, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- dma_size, 1, /* maxsize, nsegments */
- dma_size, 0, /* maxsegsize, flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->dma_tag);
+ sc = device_get_softc(dev);
+ memset(&fb, 0, sizeof(fb));
+ if (bcm2835_mbox_fb_get_w_h(dev, &fb) != 0)
+ return (ENXIO);
+ fb.bpp = FB_DEPTH;
+ if (bcm2835_mbox_fb_init(dev, &fb) != 0)
+ return (ENXIO);
- err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->fb_config, 0,
- &sc->dma_map);
- if (err) {
- device_printf(dev, "cannot allocate framebuffer\n");
- goto fail;
+ info = malloc(sizeof(struct fb_info), M_DEVBUF, M_WAITOK | M_ZERO);
+ info->fb_name = device_get_nameunit(dev);
+ info->fb_vbase = (intptr_t)pmap_mapdev(fb.base, fb.size);
+ info->fb_pbase = fb.base;
+ info->fb_size = fb.size;
+ info->fb_bpp = info->fb_depth = fb.bpp;
+ info->fb_stride = fb.pitch;
+ info->fb_width = fb.xres;
+ info->fb_height = fb.yres;
+ sc->info = info;
+
+ /* Newer firmware versions needs an inverted color palette. */
+ fbswap = 0;
+ chosen = OF_finddevice("/chosen");
+ if (chosen != 0 &&
+ OF_getprop(chosen, "bootargs", &bootargs, sizeof(bootargs)) > 0) {
+ p = bootargs;
+ while ((v = strsep(&p, " ")) != NULL) {
+ if (*v == '\0')
+ continue;
+ n = strsep(&v, "=");
+ if (strcmp(n, "bcm2708_fb.fbswap") == 0 && v != NULL)
+ if (*v == '1')
+ fbswap = 1;
+ }
+ }
+ if (fbswap) {
+ switch (info->fb_bpp) {
+ case 24:
+ vt_generate_cons_palette(info->fb_cmap,
+ COLOR_FORMAT_RGB, 0xff, 0, 0xff, 8, 0xff, 16);
+ info->fb_cmsize = 16;
+ break;
+ case 32:
+ vt_generate_cons_palette(info->fb_cmap,
+ COLOR_FORMAT_RGB, 0xff, 16, 0xff, 8, 0xff, 0);
+ info->fb_cmsize = 16;
+ break;
+ }
}
- err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->fb_config,
- dma_size, bcm_fb_dmamap_cb, &sc->fb_config_phys, BUS_DMA_NOWAIT);
-
- if (err) {
- device_printf(dev, "cannot load DMA map\n");
- goto fail;
+ fbd = device_add_child(dev, "fbd", device_get_unit(dev));
+ if (fbd == NULL) {
+ device_printf(dev, "Failed to add fbd child\n");
+ free(info, M_DEVBUF);
+ return (ENXIO);
+ } else if (device_probe_and_attach(fbd) != 0) {
+ device_printf(dev, "Failed to attach fbd device\n");
+ device_delete_child(dev, fbd);
+ free(info, M_DEVBUF);
+ return (ENXIO);
}
- /*
- * We have to wait until interrupts are enabled.
- * Mailbox relies on it to get data from VideoCore
- */
- sc->init_hook.ich_func = bcm_fb_init;
- sc->init_hook.ich_arg = sc;
-
- if (config_intrhook_establish(&sc->init_hook) != 0) {
- device_printf(dev, "failed to establish intrhook\n");
- return (ENOMEM);
- }
+ device_printf(dev, "%dx%d(%dx%d@%d,%d) %dbpp\n", fb.xres, fb.yres,
+ fb.vxres, fb.vyres, fb.xoffset, fb.yoffset, fb.bpp);
+ device_printf(dev,
+ "fbswap: %d, pitch %d, base 0x%08x, screen_size %d\n",
+ fbswap, fb.pitch, fb.base, fb.size);
return (0);
-
-fail:
- return (ENXIO);
-}
-
-static void
-bcm_fb_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
-{
- bus_addr_t *addr;
-
- if (err)
- return;
-
- addr = (bus_addr_t*)arg;
- *addr = PHYS_TO_VCBUS(segs[0].ds_addr);
}
static struct fb_info *
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
index af600cac3448..5940ad66a241 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
@@ -318,6 +318,47 @@ bcm2835_mbox_init_dma(device_t dev, size_t len, bus_dma_tag_t *tag,
return (buf);
}
+static int
+bcm2835_mbox_err(device_t dev, bus_addr_t msg_phys, uint32_t resp_phys,
+ struct bcm2835_mbox_hdr *msg, size_t len)
+{
+ int idx;
+ struct bcm2835_mbox_tag_hdr *tag;
+ uint8_t *last;
+
+ if ((uint32_t)msg_phys != resp_phys) {
+ device_printf(dev, "response channel mismatch\n");
+ return (EIO);
+ }
+ if (msg->code != BCM2835_MBOX_CODE_RESP_SUCCESS) {
+ device_printf(dev, "mbox response error\n");
+ return (EIO);
+ }
+
+ /* Loop until the end tag. */
+ tag = (struct bcm2835_mbox_tag_hdr *)(msg + 1);
+ last = (uint8_t *)msg + len;
+ for (idx = 0; tag->tag != 0; idx++) {
+ if ((tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE) == 0) {
+ device_printf(dev, "tag %d response error\n", idx);
+ return (EIO);
+ }
+ /* Clear the response bit. */
+ tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;
+
+ /* Next tag. */
+ tag = (struct bcm2835_mbox_tag_hdr *)((uint8_t *)tag +
+ sizeof(*tag) + tag->val_buf_size);
+
+ if ((uint8_t *)tag > last) {
+ device_printf(dev, "mbox buffer size error\n");
+ return (EIO);
+ }
+ }
+
+ return (0);
+}
+
int
bcm2835_mbox_set_power_state(device_t dev, uint32_t device_id, boolean_t on)
{
@@ -413,3 +454,136 @@ bcm2835_mbox_get_clock_rate(device_t dev, uint32_t clock_id, uint32_t *hz)
return (0);
}
+
+int
+bcm2835_mbox_fb_get_w_h(device_t dev, struct bcm2835_fb_config *fb)
+{
+ device_t mbox;
+ int err;
+ bus_dma_tag_t msg_tag;
+ bus_dmamap_t msg_map;
+ bus_addr_t msg_phys;
+ struct msg_fb_get_w_h *msg;
+ uint32_t reg;
+
+ /* get mbox device */
+ mbox = devclass_get_device(devclass_find("mbox"), 0);
+ if (mbox == NULL) {
+ device_printf(dev, "can't find mbox\n");
+ return (ENXIO);
+ }
+
+ /* Allocate memory for the message */
+ msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map,
+ &msg_phys);
+ if (msg == NULL)
+ return (ENOMEM);
+
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ BCM2835_MBOX_INIT_TAG(&msg->physical_w_h, GET_PHYSICAL_W_H);
+ msg->physical_w_h.tag_hdr.val_len = 0;
+ BCM2835_MBOX_INIT_TAG(&msg->virtual_w_h, GET_VIRTUAL_W_H);
+ msg->virtual_w_h.tag_hdr.val_len = 0;
+ BCM2835_MBOX_INIT_TAG(&msg->offset, GET_VIRTUAL_OFFSET);
+ msg->offset.tag_hdr.val_len = 0;
+ msg->end_tag = 0;
+
+ bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREWRITE);
+ MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys);
+ bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTWRITE);
+
+ bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREREAD);
+ MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &reg);
+ bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTREAD);
+
+ err = bcm2835_mbox_err(dev, msg_phys, reg, &msg->hdr, sizeof(*msg));
+ if (err == 0) {
+ fb->xres = msg->physical_w_h.body.resp.width;
+ fb->yres = msg->physical_w_h.body.resp.height;
+ fb->vxres = msg->virtual_w_h.body.resp.width;
+ fb->vyres = msg->virtual_w_h.body.resp.height;
+ fb->xoffset = msg->offset.body.resp.x;
+ fb->yoffset = msg->offset.body.resp.y;
+ }
+
+ bus_dmamap_unload(msg_tag, msg_map);
+ bus_dmamem_free(msg_tag, msg, msg_map);
+ bus_dma_tag_destroy(msg_tag);
+
+ return (err);
+}
+
+int
+bcm2835_mbox_fb_init(device_t dev, struct bcm2835_fb_config *fb)
+{
+ device_t mbox;
+ int err;
+ bus_dma_tag_t msg_tag;
+ bus_dmamap_t msg_map;
+ bus_addr_t msg_phys;
+ struct msg_fb_setup *msg;
+ uint32_t reg;
+
+ /* get mbox device */
+ mbox = devclass_get_device(devclass_find("mbox"), 0);
+ if (mbox == NULL) {
+ device_printf(dev, "can't find mbox\n");
+ return (ENXIO);
+ }
+
+ /* Allocate memory for the message */
+ msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map,
+ &msg_phys);
+ if (msg == NULL)
+ return (ENOMEM);
+
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ BCM2835_MBOX_INIT_TAG(&msg->physical_w_h, SET_PHYSICAL_W_H);
+ msg->physical_w_h.body.req.width = fb->xres;
+ msg->physical_w_h.body.req.height = fb->yres;
+ BCM2835_MBOX_INIT_TAG(&msg->virtual_w_h, SET_VIRTUAL_W_H);
+ msg->virtual_w_h.body.req.width = fb->vxres;
+ msg->virtual_w_h.body.req.height = fb->vyres;
+ BCM2835_MBOX_INIT_TAG(&msg->offset, GET_VIRTUAL_OFFSET);
+ msg->offset.body.req.x = fb->xoffset;
+ msg->offset.body.req.y = fb->yoffset;
+ BCM2835_MBOX_INIT_TAG(&msg->depth, SET_DEPTH);
+ msg->depth.body.req.bpp = fb->bpp;
+ BCM2835_MBOX_INIT_TAG(&msg->alpha, SET_ALPHA_MODE);
+ msg->alpha.body.req.alpha = BCM2835_MBOX_ALPHA_MODE_IGNORED;
+ BCM2835_MBOX_INIT_TAG(&msg->buffer, ALLOCATE_BUFFER);
+ msg->buffer.body.req.alignment = PAGE_SIZE;
+ BCM2835_MBOX_INIT_TAG(&msg->pitch, GET_PITCH);
+ msg->end_tag = 0;
+
+ bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREWRITE);
+ MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys);
+ bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTWRITE);
+
+ bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREREAD);
+ MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &reg);
+ bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTREAD);
+
+ err = bcm2835_mbox_err(dev, msg_phys, reg, &msg->hdr, sizeof(*msg));
+ if (err == 0) {
+ fb->xres = msg->physical_w_h.body.resp.width;
+ fb->yres = msg->physical_w_h.body.resp.height;
+ fb->vxres = msg->virtual_w_h.body.resp.width;
+ fb->vyres = msg->virtual_w_h.body.resp.height;
+ fb->xoffset = msg->offset.body.resp.x;
+ fb->yoffset = msg->offset.body.resp.y;
+ fb->pitch = msg->pitch.body.resp.pitch;
+ fb->base = msg->buffer.body.resp.fb_address;
+ fb->size = msg->buffer.body.resp.fb_size;
+ }
+
+ bus_dmamap_unload(msg_tag, msg_map);
+ bus_dmamem_free(msg_tag, msg, msg_map);
+ bus_dma_tag_destroy(msg_tag);
+
+ return (err);
+}
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h b/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
index 76f2a16130b6..a425f2a024ce 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
+++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
@@ -52,6 +52,12 @@ struct bcm2835_mbox_tag_hdr {
uint32_t val_len;
};
+#define BCM2835_MBOX_INIT_TAG(tag_, tagid_) do { \
+ (tag_)->tag_hdr.tag = BCM2835_MBOX_TAG_##tagid_; \
+ (tag_)->tag_hdr.val_buf_size = sizeof((tag_)->body); \
+ (tag_)->tag_hdr.val_len = sizeof((tag_)->body.req); \
+} while (0)
+
#define BCM2835_MBOX_POWER_ID_EMMC 0x00000000
#define BCM2835_MBOX_POWER_ID_UART0 0x00000001
#define BCM2835_MBOX_POWER_ID_UART1 0x00000002
@@ -322,4 +328,151 @@ struct msg_get_max_temperature {
uint32_t end_tag;
};
+#define BCM2835_MBOX_TAG_GET_PHYSICAL_W_H 0x00040003
+#define BCM2835_MBOX_TAG_SET_PHYSICAL_W_H 0x00048003
+#define BCM2835_MBOX_TAG_GET_VIRTUAL_W_H 0x00040004
+#define BCM2835_MBOX_TAG_SET_VIRTUAL_W_H 0x00048004
+
+struct bcm2835_mbox_tag_fb_w_h {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t width;
+ uint32_t height;
+ } req;
+ struct {
+ uint32_t width;
+ uint32_t height;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_DEPTH 0x00040005
+#define BCM2835_MBOX_TAG_SET_DEPTH 0x00048005
+
+struct bcm2835_mbox_tag_depth {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t bpp;
+ } req;
+ struct {
+ uint32_t bpp;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_ALPHA_MODE 0x00040007
+#define BCM2835_MBOX_TAG_SET_ALPHA_MODE 0x00048007
+
+#define BCM2835_MBOX_ALPHA_MODE_0_OPAQUE 0
+#define BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT 1
+#define BCM2835_MBOX_ALPHA_MODE_IGNORED 2
+
+struct bcm2835_mbox_tag_alpha_mode {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t alpha;
+ } req;
+ struct {
+ uint32_t alpha;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET 0x00040009
+#define BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET 0x00048009
+
+struct bcm2835_mbox_tag_virtual_offset {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t x;
+ uint32_t y;
+ } req;
+ struct {
+ uint32_t x;
+ uint32_t y;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_PITCH 0x00040008
+
+struct bcm2835_mbox_tag_pitch {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ } req;
+ struct {
+ uint32_t pitch;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_ALLOCATE_BUFFER 0x00040001
+
+struct bcm2835_mbox_tag_allocate_buffer {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t alignment;
+ } req;
+ struct {
+ uint32_t fb_address;
+ uint32_t fb_size;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_RELEASE_BUFFER 0x00048001
+
+struct bcm2835_mbox_tag_release_buffer {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ } req;
+ struct {
+ } resp;
+ } body;
+};
+
+struct bcm2835_fb_config {
+ uint32_t xres;
+ uint32_t yres;
+ uint32_t vxres;
+ uint32_t vyres;
+ uint32_t xoffset;
+ uint32_t yoffset;
+ uint32_t bpp;
+ uint32_t pitch;
+ uint32_t base;
+ uint32_t size;
+};
+
+struct msg_fb_get_w_h {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_fb_w_h physical_w_h;
+ struct bcm2835_mbox_tag_fb_w_h virtual_w_h;
+ struct bcm2835_mbox_tag_virtual_offset offset;
+ uint32_t end_tag;
+};
+
+int bcm2835_mbox_fb_get_w_h(device_t, struct bcm2835_fb_config *);
+
+struct msg_fb_setup {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_fb_w_h physical_w_h;
+ struct bcm2835_mbox_tag_fb_w_h virtual_w_h;
+ struct bcm2835_mbox_tag_virtual_offset offset;
+ struct bcm2835_mbox_tag_depth depth;
+ struct bcm2835_mbox_tag_alpha_mode alpha;
+ struct bcm2835_mbox_tag_allocate_buffer buffer;
+ struct bcm2835_mbox_tag_pitch pitch;
+ uint32_t end_tag;
+};
+
+int bcm2835_mbox_fb_init(device_t, struct bcm2835_fb_config *);
+
#endif /* _BCM2835_MBOX_PROP_H_ */
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
index 1024a48e7fa2..e950ec6913b3 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
@@ -68,15 +68,8 @@ __FBSDID("$FreeBSD$");
#define dprintf(fmt, args...)
#endif
-/* DMA doesn't yet work with the bcm3826 */
-#ifdef SOC_BCM2836
-#define PIO_MODE 1
-#else
-#define PIO_MODE 0
-#endif
-
static int bcm2835_sdhci_hs = 1;
-static int bcm2835_sdhci_pio_mode = PIO_MODE;
+static int bcm2835_sdhci_pio_mode = 0;
TUNABLE_INT("hw.bcm2835.sdhci.hs", &bcm2835_sdhci_hs);
TUNABLE_INT("hw.bcm2835.sdhci.pio_mode", &bcm2835_sdhci_pio_mode);
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h b/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
index cb871f23bf9e..7b79b1ab5ea4 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
+++ b/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
@@ -37,14 +37,20 @@
#define BCM2835_VCBUS_IO_BASE 0x7E000000
#define BCM2835_VCBUS_SDRAM_UNCACHED 0xC0000000
+#ifdef SOC_BCM2836
+#define BCM2835_ARM_IO_BASE 0x3f000000
+#define BCM2835_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_UNCACHED
+#else
#define BCM2835_ARM_IO_BASE 0x20000000
-#define BCM2835_ARM_IO_SIZE 0x02000000
+#define BCM2835_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_CACHED
+#endif
+#define BCM2835_ARM_IO_SIZE 0x01000000
/*
* Convert physical address to VC bus address. Should be used
* when submitting address over mailbox interface
*/
-#define PHYS_TO_VCBUS(pa) ((pa) + BCM2835_VCBUS_SDRAM_CACHED)
+#define PHYS_TO_VCBUS(pa) ((pa) + BCM2835_VCBUS_SDRAM_BASE)
/* Check whether pa bellong top IO window */
#define BCM2835_ARM_IS_IO(pa) (((pa) >= BCM2835_ARM_IO_BASE) && \
@@ -61,6 +67,6 @@
* when address is returned by VC over mailbox interface. e.g.
* framebuffer base
*/
-#define VCBUS_TO_PHYS(vca) ((vca) - BCM2835_VCBUS_SDRAM_CACHED)
+#define VCBUS_TO_PHYS(vca) ((vca) - BCM2835_VCBUS_SDRAM_BASE)
#endif /* _BCM2835_VCBUS_H_ */
diff --git a/sys/arm/conf/AML8726 b/sys/arm/conf/AML8726
index 7272db4b08a2..a6b4a8e4cdc8 100644
--- a/sys/arm/conf/AML8726
+++ b/sys/arm/conf/AML8726
@@ -19,43 +19,14 @@
# $FreeBSD$
ident AML8726
+
+include "std.armv6"
include "../amlogic/aml8726/std.aml8726"
options HZ=100
options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
options LINUX_BOOT_ABI
-options VFP # Enable floating point hardware support
options SMP # Enable multiple cores
# Debugging
diff --git a/sys/arm/conf/ARMADAXP b/sys/arm/conf/ARMADAXP
index f611e09da882..ed4aa2ddc5a8 100644
--- a/sys/arm/conf/ARMADAXP
+++ b/sys/arm/conf/ARMADAXP
@@ -19,6 +19,8 @@
# $FreeBSD$
ident MV-88F78XX0
+
+include "std.armv6"
include "../mv/armadaxp/std.mv78x60"
options SOC_MV_ARMADAXP
@@ -26,36 +28,7 @@ options SOC_MV_ARMADAXP
makeoptions WERROR="-Werror"
options HZ=1000
-#options SCHED_ULE # ULE scheduler
options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options VFP # Enable floating point hardware support
options SMP # Enable multiple cores
# Debugging for use in -current
diff --git a/sys/arm/conf/ATMEL b/sys/arm/conf/ATMEL
index 572cf4a1ce5e..2e8da7d1ac81 100644
--- a/sys/arm/conf/ATMEL
+++ b/sys/arm/conf/ATMEL
@@ -6,6 +6,7 @@
ident ATMEL
+include "std.arm"
include "../at91/std.atmel"
# Typical values for most SoCs and board configurations. Will not work for
@@ -77,10 +78,24 @@ options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
#options MAC # TrustedBSD MAC Framework
#options INCLUDE_CONFIG_FILE # Include this file in kernel
-# required for netbooting
+# Debugging support. Always need this:
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
+options DDB # Enable the kernel debugger
+options GDB # Support remote GDB
+#options DEADLKRES # Enable the deadlock resolver
+#options INVARIANTS # Enable calls of extra sanity checking
+#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+#options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+#options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones
+
+# NFS root from boopt/dhcp
options BOOTP
-options BOOTP_COMPAT
options BOOTP_NFSROOT
+options BOOTP_COMPAT
options BOOTP_NFSV3
options BOOTP_WIRED_TO=ate0
@@ -94,20 +109,6 @@ options NO_SWAPPING
options NO_SYSCTL_DESCR
options RWLOCK_NOINLINE
-# Debugging support. Always need this:
-options KDB # Enable kernel debugger support.
-# For minimum debugger support (stable branch) use:
-options KDB_TRACE # Print a stack trace for a panic.
-# For full debugger support use this instead:
-options DDB # Support DDB.
-options GDB # Support remote GDB.
-#options DEADLKRES # Enable the deadlock resolver
-#options INVARIANTS # Enable calls of extra sanity checking
-#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-#options WITNESS # Enable checks to detect deadlocks and cycles
-#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
-#options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones
-
# The `bpf' device enables the Berkeley Packet Filter.
# Be aware of the administrative consequences of enabling this!
# Note that 'bpf' is required for DHCP.
@@ -115,7 +116,7 @@ device bpf # Berkeley packet filter
# Ethernet
device mii # Minimal MII support
-device ate # Atmel AT91 Ethernet friver
+device ate # Atmel AT91 Ethernet driver
# I2C
device at91_twi # Atmel AT91 Two-wire Interface
diff --git a/sys/arm/conf/AVILA b/sys/arm/conf/AVILA
index cbf27a2b6334..b356b353768c 100644
--- a/sys/arm/conf/AVILA
+++ b/sys/arm/conf/AVILA
@@ -20,6 +20,7 @@
ident AVILA
+include "std.arm"
include "../xscale/ixp425/std.ixp425"
# NB: memory mapping is defined in std.avila
include "../xscale/ixp425/std.avila"
diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE
index 8234533b87ef..997a62ee5240 100644
--- a/sys/arm/conf/BEAGLEBONE
+++ b/sys/arm/conf/BEAGLEBONE
@@ -23,6 +23,7 @@
ident BEAGLEBONE
+include "std.armv6"
include "../ti/am335x/std.am335x"
makeoptions MODULES_EXTRA="dtb/am335x"
@@ -35,38 +36,7 @@ makeoptions MODULES_EXTRA+="opensolaris dtrace dtrace/lockstat dtrace/profile dt
options HZ=100
options SCHED_4BSD # 4BSD scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options PLATFORM
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/BWCT b/sys/arm/conf/BWCT
index a9e0e784361e..d483a00ea68d 100644
--- a/sys/arm/conf/BWCT
+++ b/sys/arm/conf/BWCT
@@ -21,6 +21,7 @@
ident BWCT
+include "std.arm"
options VERBOSE_INIT_ARM
include "../at91/std.bwct"
diff --git a/sys/arm/conf/CAMBRIA b/sys/arm/conf/CAMBRIA
index af29b2306425..1cf7fb918469 100644
--- a/sys/arm/conf/CAMBRIA
+++ b/sys/arm/conf/CAMBRIA
@@ -20,6 +20,7 @@
ident CAMBRIA
+include "std.arm"
include "../xscale/ixp425/std.ixp435"
# NB: memory mapping is defined in std.avila
include "../xscale/ixp425/std.avila"
diff --git a/sys/arm/conf/CNS11XXNAS b/sys/arm/conf/CNS11XXNAS
index 5ba221700c01..d906a2b00054 100644
--- a/sys/arm/conf/CNS11XXNAS
+++ b/sys/arm/conf/CNS11XXNAS
@@ -20,6 +20,7 @@
ident CNS11XXNAS
+include "std.arm"
#options PHYSADDR=0x10000000
#options KERNPHYSADDR=0x10200000
#options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
diff --git a/sys/arm/conf/CRB b/sys/arm/conf/CRB
index 641ba9f3f0f3..f5cc9322b410 100644
--- a/sys/arm/conf/CRB
+++ b/sys/arm/conf/CRB
@@ -19,6 +19,7 @@
ident CRB
+include "std.arm"
options PHYSADDR=0x00000000
options KERNPHYSADDR=0x00200000
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
diff --git a/sys/arm/conf/CUBIEBOARD b/sys/arm/conf/CUBIEBOARD
index 945f0ae6fbcf..8f856bd279bf 100644
--- a/sys/arm/conf/CUBIEBOARD
+++ b/sys/arm/conf/CUBIEBOARD
@@ -21,41 +21,11 @@
ident CUBIEBOARD
+include "std.armv6"
include "../allwinner/std.a10"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/CUBIEBOARD2 b/sys/arm/conf/CUBIEBOARD2
index d370dda954fa..15d028f9271e 100644
--- a/sys/arm/conf/CUBIEBOARD2
+++ b/sys/arm/conf/CUBIEBOARD2
@@ -21,41 +21,11 @@
ident CUBIEBOARD2
+include "std.armv6"
include "../allwinner/a20/std.a20"
options HZ=100
options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
options SMP # Enable multiple cores
# Debugging for use in -current
diff --git a/sys/arm/conf/DB-78XXX b/sys/arm/conf/DB-78XXX
index 4fee206e8ff5..2e7fa3605759 100644
--- a/sys/arm/conf/DB-78XXX
+++ b/sys/arm/conf/DB-78XXX
@@ -5,6 +5,7 @@
#
ident DB-88F78XX
+include "std.arm"
include "../mv/discovery/std.db78xxx"
options SOC_MV_DISCOVERY
diff --git a/sys/arm/conf/DB-88F5XXX b/sys/arm/conf/DB-88F5XXX
index 6ccb360bd4d9..7cc06a0407f8 100644
--- a/sys/arm/conf/DB-88F5XXX
+++ b/sys/arm/conf/DB-88F5XXX
@@ -5,6 +5,7 @@
#
ident DB-88F5XXX
+include "std.arm"
include "../mv/orion/std.db88f5xxx"
options SOC_MV_ORION
diff --git a/sys/arm/conf/DB-88F6XXX b/sys/arm/conf/DB-88F6XXX
index c59f1c1130da..afec0e726534 100644
--- a/sys/arm/conf/DB-88F6XXX
+++ b/sys/arm/conf/DB-88F6XXX
@@ -5,6 +5,7 @@
#
ident DB-88F6XXX
+include "std.arm"
include "../mv/kirkwood/std.db88f6xxx"
options SOC_MV_KIRKWOOD
diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR
index aea158ca8911..c6308cd905e7 100644
--- a/sys/arm/conf/DOCKSTAR
+++ b/sys/arm/conf/DOCKSTAR
@@ -21,6 +21,7 @@
ident DOCKSTAR
+include "std.arm"
include "../mv/kirkwood/std.db88f6xxx"
makeoptions FDT_DTS_FILE=dockstar.dts
diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001
index 0448d4f95646..f97b5642529f 100644
--- a/sys/arm/conf/DREAMPLUG-1001
+++ b/sys/arm/conf/DREAMPLUG-1001
@@ -24,6 +24,7 @@
ident DREAMPLUG-1001
+include "std.arm"
include "../mv/kirkwood/std.db88f6xxx"
makeoptions FDT_DTS_FILE=dreamplug-1001.dts
diff --git a/sys/arm/conf/EA3250 b/sys/arm/conf/EA3250
index d2d691b32129..bcb8276a94b2 100644
--- a/sys/arm/conf/EA3250
+++ b/sys/arm/conf/EA3250
@@ -5,6 +5,7 @@
#
ident EA3250
+include "std.arm"
include "../lpc/std.lpc"
hints "EA3250.hints"
diff --git a/sys/arm/conf/EB9200 b/sys/arm/conf/EB9200
index a5ec5eb52f1d..bf0c41b1feca 100644
--- a/sys/arm/conf/EB9200
+++ b/sys/arm/conf/EB9200
@@ -16,6 +16,7 @@
ident EB9200
+include "std.arm"
include "../at91/std.eb9200"
# The AT91 platform doesn't use /boot/loader, so we have to statically wire
# hints.
diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX
index a4690f6964fc..81edae855f6d 100644
--- a/sys/arm/conf/EFIKA_MX
+++ b/sys/arm/conf/EFIKA_MX
@@ -20,6 +20,7 @@
ident EFIKA_MX
+include "std.armv6"
include "../freescale/imx/std.imx51"
makeoptions WITHOUT_MODULES="ahc"
@@ -27,43 +28,13 @@ makeoptions WITHOUT_MODULES="ahc"
options SOC_IMX51
options SCHED_4BSD # 4BSD scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
#options MD_ROOT # MD is a potential root device
-options NFSCL # Network Filesystem Client
#options NFSD # Network Filesystem Server
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options GEOM_LABEL # Provides labelization
#options COMPAT_FREEBSD5 # Compatible with FreeBSD5
#options COMPAT_FREEBSD6 # Compatible with FreeBSD6
#options COMPAT_FREEBSD7 # Compatible with FreeBSD7
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options PLATFORM
options INCLUDE_CONFIG_FILE # Include this file in kernel
-options VFP # Enable floating point hardware support
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/EP80219 b/sys/arm/conf/EP80219
index 35bcb17641f1..6f2bef8b090c 100644
--- a/sys/arm/conf/EP80219
+++ b/sys/arm/conf/EP80219
@@ -19,6 +19,7 @@
ident EP80219
+include "std.arm"
options PHYSADDR=0xa0000000
options KERNPHYSADDR=0xa0200000
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
diff --git a/sys/arm/conf/ETHERNUT5 b/sys/arm/conf/ETHERNUT5
index 376336a23329..f01ea0d138a0 100644
--- a/sys/arm/conf/ETHERNUT5
+++ b/sys/arm/conf/ETHERNUT5
@@ -21,6 +21,7 @@
ident ETHERNUT5
+include "std.arm"
include "../at91/std.ethernut5"
# To statically compile in device wiring instead of /boot/device.hints
diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common
index cd6e76fb2b39..2f9693582c85 100644
--- a/sys/arm/conf/EXYNOS5.common
+++ b/sys/arm/conf/EXYNOS5.common
@@ -20,6 +20,7 @@
makeoptions WERROR="-Werror"
+include "std.armv6"
options HZ=100
options SCHED_ULE # ULE scheduler
options PREEMPTION # Enable kernel thread preemption
diff --git a/sys/arm/conf/GUMSTIX b/sys/arm/conf/GUMSTIX
index 97d0ac7468d3..9ba6155cc3d8 100644
--- a/sys/arm/conf/GUMSTIX
+++ b/sys/arm/conf/GUMSTIX
@@ -19,6 +19,7 @@
# $FreeBSD$
ident GUMSTIX
+include "std.arm"
cpu CPU_XSCALE_PXA2X0
# This probably wants to move somewhere else. Maybe we can create a basic
diff --git a/sys/arm/conf/HL200 b/sys/arm/conf/HL200
index 3c0f4e880ce8..8d22da5943a5 100644
--- a/sys/arm/conf/HL200
+++ b/sys/arm/conf/HL200
@@ -21,6 +21,7 @@
ident HL200
+include "std.arm"
include "../at91/std.hl200"
#To statically compile in device wiring instead of /boot/device.hints
diff --git a/sys/arm/conf/HL201 b/sys/arm/conf/HL201
index 6a477af80982..4ec6da36fcd6 100644
--- a/sys/arm/conf/HL201
+++ b/sys/arm/conf/HL201
@@ -21,6 +21,7 @@
ident HL201
+include "std.arm"
include "../at91/std.hl201"
makeoptions MODULES_OVERRIDE=""
diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53
index 9f78f303d76a..3275bfc93377 100644
--- a/sys/arm/conf/IMX53
+++ b/sys/arm/conf/IMX53
@@ -20,47 +20,18 @@
ident IMX53
+include "std.armv6"
include "../freescale/imx/std.imx53"
options SOC_IMX53
options SCHED_4BSD # 4BSD scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
#options NFSD # Network Filesystem Server
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options GEOM_LABEL # Provides labelization
#options COMPAT_FREEBSD5 # Compatible with FreeBSD5
#options COMPAT_FREEBSD6 # Compatible with FreeBSD6
#options COMPAT_FREEBSD7 # Compatible with FreeBSD7
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options PLATFORM
options INCLUDE_CONFIG_FILE # Include this file in kernel
-options VFP # Enable floating point hardware support
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6
index f1baf296667b..5ead99b2bf4c 100644
--- a/sys/arm/conf/IMX6
+++ b/sys/arm/conf/IMX6
@@ -19,45 +19,16 @@
# $FreeBSD$
ident IMX6
+include "std.armv6"
include "../freescale/imx/std.imx6"
options SOC_IMX6
options HZ=500 # Scheduling quantum is 2 milliseconds.
options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
#options NFSD # Network Filesystem Server
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options GEOM_LABEL # Provides labelization
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options INCLUDE_CONFIG_FILE # Include this file in kernel
options PLATFORM
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
options SMP # Enable multiple cores
# Debugging for use in -current
diff --git a/sys/arm/conf/IQ31244 b/sys/arm/conf/IQ31244
index 2066fb85c695..403a0c2e8f9b 100644
--- a/sys/arm/conf/IQ31244
+++ b/sys/arm/conf/IQ31244
@@ -19,6 +19,7 @@
ident IQ31244
+include "std.arm"
options PHYSADDR=0xa0000000
options KERNPHYSADDR=0xa0200000
options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm
diff --git a/sys/arm/conf/KB920X b/sys/arm/conf/KB920X
index 1fc23be2b45c..6d91ad80e0c0 100644
--- a/sys/arm/conf/KB920X
+++ b/sys/arm/conf/KB920X
@@ -22,6 +22,7 @@
ident KB920X
+include "std.arm"
include "../at91/std.kb920x"
# The AT91 platform doesn't use /boot/loader, so we have to statically wire
# hints.
diff --git a/sys/arm/conf/LN2410SBC b/sys/arm/conf/LN2410SBC
index b2f64a0a7717..ae3c62a94fac 100644
--- a/sys/arm/conf/LN2410SBC
+++ b/sys/arm/conf/LN2410SBC
@@ -19,6 +19,7 @@
ident LN2410SBC
+include "std.arm"
include "../samsung/s3c2xx0/std.ln2410sbc"
#To statically compile in device wiring instead of /boot/device.hints
#hints "GENERIC.hints" # Default places to look for devices.
diff --git a/sys/arm/conf/NSLU b/sys/arm/conf/NSLU
index e12c5a583846..00a29028bc32 100644
--- a/sys/arm/conf/NSLU
+++ b/sys/arm/conf/NSLU
@@ -21,6 +21,7 @@
ident NSLU
+include "std.arm"
# XXX What is defined in std.avila does not exactly match the following:
#options PHYSADDR=0x10000000
#options KERNPHYSADDR=0x10200000
diff --git a/sys/arm/conf/PANDABOARD b/sys/arm/conf/PANDABOARD
index e0b5d149d318..e58c953b5632 100644
--- a/sys/arm/conf/PANDABOARD
+++ b/sys/arm/conf/PANDABOARD
@@ -27,42 +27,12 @@ ident PANDABOARD
hints "PANDABOARD.hints"
+include "std.armv6"
include "../ti/omap4/pandaboard/std.pandaboard"
options HZ=100
options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options PLATFORM
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
options SMP # Enable multiple cores
# Debugging for use in -current
diff --git a/sys/arm/conf/QILA9G20 b/sys/arm/conf/QILA9G20
index 7559c31079f0..2f9b6093272b 100644
--- a/sys/arm/conf/QILA9G20
+++ b/sys/arm/conf/QILA9G20
@@ -22,6 +22,7 @@
ident QILA9G20
+include "std.arm"
include "../at91/std.qila9g20"
#To statically compile in device wiring instead of /boot/device.hints
diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188
index 64065d30d70a..46bc334ec02f 100644
--- a/sys/arm/conf/RK3188
+++ b/sys/arm/conf/RK3188
@@ -20,41 +20,11 @@
ident RK3188
+include "std.armv6"
include "../rockchip/std.rk30xx"
options HZ=100
options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
options SMP # Enable multiple cores
# Debugging for use in -current
diff --git a/sys/arm/conf/RPI-B b/sys/arm/conf/RPI-B
index 0604a975d297..309a499d0094 100644
--- a/sys/arm/conf/RPI-B
+++ b/sys/arm/conf/RPI-B
@@ -20,43 +20,13 @@
ident RPI-B
+include "std.armv6"
include "../broadcom/bcm2835/std.rpi"
include "../broadcom/bcm2835/std.bcm2835"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options PLATFORM
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/RPI2 b/sys/arm/conf/RPI2
index 18d97d7ae21d..dbb67d976460 100644
--- a/sys/arm/conf/RPI2
+++ b/sys/arm/conf/RPI2
@@ -1,5 +1,5 @@
#
-# RPI-B -- Custom configuration for the Raspberry Pi
+# RPI2 -- Custom configuration for the Raspberry Pi 2
#
# For more information on this file, please read the config(5) manual page,
# and/or the handbook section on Kernel Configuration Files:
@@ -18,45 +18,15 @@
#
# $FreeBSD$
-ident RPI-B
+ident RPI2
+include "std.armv6"
include "../broadcom/bcm2835/std.rpi"
include "../broadcom/bcm2835/std.bcm2836"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options PLATFORM
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
@@ -130,8 +100,8 @@ device smsc
device spibus
device bcm2835_spi
-#device vchiq
-#device sound
+device vchiq
+device sound
# Flattened Device Tree
options FDT # Configure using FDT/DTB data
diff --git a/sys/arm/conf/SAM9260EK b/sys/arm/conf/SAM9260EK
index 7e88ee1fb8be..30680c509516 100644
--- a/sys/arm/conf/SAM9260EK
+++ b/sys/arm/conf/SAM9260EK
@@ -21,6 +21,7 @@
ident SAM9260EK
+include "std.arm"
include "../at91/std.sam9260ek"
# To statically compile in device wiring instead of /boot/device.hints
@@ -72,10 +73,24 @@ options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
#options MAC # TrustedBSD MAC Framework
#options INCLUDE_CONFIG_FILE # Include this file in kernel
-# required for netbooting
+# Debugging support. Always need this:
+#options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
+#options DDB # Enable the kernel debugger
+#options GDB # Support remote GDB
+#options DEADLKRES # Enable the deadlock resolver
+#options INVARIANTS # Enable calls of extra sanity checking
+#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+#options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+#options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones
+
+# NFS root from boopt/dhcp
#options BOOTP
-#options BOOTP_COMPAT
#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=ate0
@@ -92,20 +107,6 @@ options NO_SWAPPING
options NO_SYSCTL_DESCR
options RWLOCK_NOINLINE
-# Debugging support. Always need this:
-#options KDB # Enable kernel debugger support.
-# For minimum debugger support (stable branch) use:
-#options KDB_TRACE # Print a stack trace for a panic.
-# For full debugger support use this instead:
-#options DDB # Support DDB.
-#options GDB # Support remote GDB.
-#options DEADLKRES # Enable the deadlock resolver
-#options INVARIANTS # Enable calls of extra sanity checking
-#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-#options WITNESS # Enable checks to detect deadlocks and cycles
-#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
-#options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones
-
# The `bpf' device enables the Berkeley Packet Filter.
# Be aware of the administrative consequences of enabling this!
# Note that 'bpf' is required for DHCP.
diff --git a/sys/arm/conf/SAM9G20EK b/sys/arm/conf/SAM9G20EK
index 7f3d15c15384..4d961c7beeea 100644
--- a/sys/arm/conf/SAM9G20EK
+++ b/sys/arm/conf/SAM9G20EK
@@ -19,6 +19,7 @@
ident SAM9G20EK
+include "std.arm"
include "../at91/std.sam9g20ek"
#To statically compile in device wiring instead of /boot/device.hints
@@ -26,14 +27,10 @@ hints "SAM9G20EK.hints"
makeoptions MODULES_OVERRIDE=""
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options DDB
-options KDB
options SCHED_4BSD # 4BSD scheduler
options INET # InterNETworking
#options INET6 # IPv6 communications protocols
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
options TMPFS # Efficient memory filesystem
options FFS # Berkeley Fast Filesystem
#options SOFTUPDATES # Enable FFS soft updates support
@@ -46,77 +43,80 @@ options NFSCL # Network Filesystem Client
#options NFSD # Network Filesystem Server
#options NFSLOCKD # Network Lock Manager
#options NFS_ROOT # NFS usable as /, requires NFSCL
-#options BOOTP_NFSROOT
-#options BOOTP
-#options BOOTP_NFSV3
-#options BOOTP_WIRED_TO=ate0
-#options BOOTP_COMPAT
-
-options ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
-
-options ALT_BREAK_TO_DEBUGGER
-
#options MSDOSFS # MSDOS Filesystem
#options CD9660 # ISO 9660 Filesystem
#options PROCFS # Process filesystem (requires PSEUDOFS)
#options PSEUDOFS # Pseudo-filesystem framework
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
#options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
#options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
-options MUTEX_NOINLINE
-options RWLOCK_NOINLINE
-options NO_FFS_SNAPSHOT
-options NO_SWAPPING
-# Debugging for use in -current
+# Debugging support. Always need this:
+options KDB # Enable kernel debugger support
+options DDB # Enable the kernel debugger
#options INVARIANTS # Enable calls of extra sanity checking
#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
#options WITNESS # Enable checks to detect deadlocks and cycles
#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
#options DIAGNOSTIC
-device random
-device loop
-device bpf
-device ether
-device md
+# NFS root from boopt/dhcp
+#options BOOTP
+#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
+#options BOOTP_NFSV3
+#options BOOTP_WIRED_TO=ate0
-device uart # Serial Ports
+options ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
+
+# kernel/memory size reduction
+options MUTEX_NOINLINE
+options NO_FFS_SNAPSHOT
+options NO_SWAPPING
+options NO_SYSCTL_DESCR
+options RWLOCK_NOINLINE
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device bpf # Berkeley packet filter
# Ethernet
-device ate # Ethernet Driver
-device mii
+device mii # Minimal MII support
+device ate # Atmel AT91 Ethernet driver
option AT91_ATE_USE_RMII
-device at91_twi # TWI: Two Wire Interface (EEPROM)
-device at91_wdt # WDT: Watchdog timer
+# I2C
+device at91_twi # Atmel AT91 Two-wire Interface
+device iic # I2C generic I/O device driver
+device iicbus # I2C bus system
+device icee
-# NAND Flash - Reference design has Samsung 256MB but others possible
-device nand # NAND interface on CS3
+# MMC/SD
+device at91_mci # Atmel AT91 Multimedia Card Interface
+options AT91_MCI_HAS_4WIRE
+options AT91_MCI_SLOT_B
+device mmc # MMC/SD bus
+device mmcsd # MMC/SD memory card
+# DataFlash
# NOTE: SPI DataFlash and mci/mmc/mmcsd have hardware
# confilict on this card. Use one or the other.
# see board_sam9g20ek.c
-
-# SPI: Data Flash
-#device at91_spi # SPI:
-#device spibus
+#device at91_spi # Atmel AT91 Serial Peripheral Interface
+#device spibus # SPI bus
#device at45d # at45db642 and maybe others
-# MMC/SD
-device at91_mci
-device mmc
-device mmcsd
-option AT91_MCI_SLOT_B
-option AT91_MCI_HAS_4WIRE
-
-# iic
-device iic
-device iicbus
-device icee
+# Pseudo devices.
+device loop # Network loopback
+device random # Entropy device
+device ether # Ethernet support
+device md # Memory "disks"
# SCSI peripherals
device scbus # SCSI bus (required for ATA/SCSI)
@@ -124,8 +124,12 @@ device da # Direct Access (disks)
device cd # CD
device pass # Passthrough device (direct ATA/SCSI access)
+# Serial (COM) ports
+device uart # Multi-uart driver
+options ALT_BREAK_TO_DEBUGGER
+
# USB support
-device ohci # OHCI localbus->USB interface
+device ohci # OHCI USB interface
device usb # USB Bus (required)
device umass # Disks/Mass storage - Requires scbus and da
device uhid # "Human Interface Devices"
@@ -154,3 +158,9 @@ device uhid # "Human Interface Devices"
#device wlan_ccmp # 802.11 CCMP support
#device wlan_tkip # 802.11 TKIP support
#device wlan_amrr # AMRR transmit rate control algorithm
+
+# watchdog
+device at91_wdt # Atmel AT91 Watchdog Timer
+
+# NAND Flash - Reference design has Samsung 256MB but others possible
+device nand # NAND interface on CS3
diff --git a/sys/arm/conf/SAM9X25EK b/sys/arm/conf/SAM9X25EK
index 419e45631abe..49afe99fdb84 100644
--- a/sys/arm/conf/SAM9X25EK
+++ b/sys/arm/conf/SAM9X25EK
@@ -21,6 +21,7 @@
ident SAM9X25EK
+include "std.arm"
include "../at91/std.sam9x25ek"
#To statically compile in device wiring instead of /boot/device.hints
diff --git a/sys/arm/conf/SHEEVAPLUG b/sys/arm/conf/SHEEVAPLUG
index 9d8ea269892e..e013e7502a35 100644
--- a/sys/arm/conf/SHEEVAPLUG
+++ b/sys/arm/conf/SHEEVAPLUG
@@ -6,6 +6,7 @@
#NO_UNIVERSE
ident SHEEVAPLUG
+include "std.arm"
include "../mv/kirkwood/std.db88f6xxx"
options SOC_MV_KIRKWOOD
diff --git a/sys/arm/conf/SN9G45 b/sys/arm/conf/SN9G45
index dec6681986d4..bf46503afd0b 100644
--- a/sys/arm/conf/SN9G45
+++ b/sys/arm/conf/SN9G45
@@ -21,6 +21,7 @@
ident SN9G45
+include "std.arm"
include "../at91/std.sn9g45"
#To statically compile in device wiring instead of /boot/device.hints
diff --git a/sys/arm/conf/SOCKIT.common b/sys/arm/conf/SOCKIT.common
index ac71169d343c..eb87fd6e9f13 100644
--- a/sys/arm/conf/SOCKIT.common
+++ b/sys/arm/conf/SOCKIT.common
@@ -18,6 +18,7 @@
#
# $FreeBSD$
+include "std.armv6"
include "../altera/socfpga/std.socfpga"
makeoptions MODULES_OVERRIDE=""
@@ -26,37 +27,6 @@ makeoptions WERROR="-Werror"
options HZ=100
options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
options SMP # Enable multiple cores
# Debugging for use in -current
diff --git a/sys/arm/conf/TS7800 b/sys/arm/conf/TS7800
index 87a40d588f8f..ab9fe5beee02 100644
--- a/sys/arm/conf/TS7800
+++ b/sys/arm/conf/TS7800
@@ -5,6 +5,7 @@
#
ident TS7800
+include "std.arm"
include "../mv/orion/std.ts7800"
options SOC_MV_ORION
diff --git a/sys/arm/conf/VERSATILEPB b/sys/arm/conf/VERSATILEPB
index c02d18c19819..182e56ce3af8 100644
--- a/sys/arm/conf/VERSATILEPB
+++ b/sys/arm/conf/VERSATILEPB
@@ -22,6 +22,7 @@ ident VERSATILEPB
machine arm armv6
cpu CPU_ARM1176
+include "std.armv6"
files "../versatile/files.versatile"
makeoptions MODULES_OVERRIDE=""
@@ -33,38 +34,7 @@ options PHYSADDR=0x00000000
options HZ=100
options SCHED_4BSD # 4BSD scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
options LINUX_BOOT_ABI # Process metadata passed from Linux boot loaders
-options VFP # Enable floating point hardware support
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/VIRT b/sys/arm/conf/VIRT
index c4f9405c550b..0f67b84023b2 100644
--- a/sys/arm/conf/VIRT
+++ b/sys/arm/conf/VIRT
@@ -20,44 +20,12 @@
ident VIRT
+include "std.armv6"
include "../qemu/std.virt"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options GEOM_LABEL # Provides labelization
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options PLATFORM
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
-options ARM_NEW_PMAP # Enable the new v6 pmap
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
diff --git a/sys/arm/conf/VYBRID b/sys/arm/conf/VYBRID
index eda4815d76ec..8fb01985ced2 100644
--- a/sys/arm/conf/VYBRID
+++ b/sys/arm/conf/VYBRID
@@ -19,44 +19,14 @@
# $FreeBSD$
ident VYBRID
+include "std.armv6"
include "../freescale/vybrid/std.vybrid"
makeoptions WERROR="-Werror"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
#options NANDFS # NAND Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
#options SMP # Enable multiple cores
# Debugging for use in -current
diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD
index 94148f4eb40f..7c108a19fc48 100644
--- a/sys/arm/conf/ZEDBOARD
+++ b/sys/arm/conf/ZEDBOARD
@@ -21,40 +21,11 @@
ident ZEDBOARD
+include "std.armv6"
include "../xilinx/zedboard/std.zedboard"
options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options QUOTA # Enable disk quotas for UFS
-options NFSCL # Network Filesystem Client
#options NFSSD # Network Filesystem Server
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options TMPFS # Efficient memory filesystem
-options GEOM_PART_GPT # GUID Partition Tables
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
-options VFP # Enable floating point hardware support
options SMP # Enable multiple cores
# Debugging for use in -current
diff --git a/sys/arm/conf/std.arm b/sys/arm/conf/std.arm
new file mode 100644
index 000000000000..88675f095e83
--- /dev/null
+++ b/sys/arm/conf/std.arm
@@ -0,0 +1,5 @@
+# Standard kernel config items for all ARMv4/v5 systems.
+#
+# $FreeBSD$
+
+
diff --git a/sys/arm/conf/std.armv6 b/sys/arm/conf/std.armv6
new file mode 100644
index 000000000000..c06ceae93009
--- /dev/null
+++ b/sys/arm/conf/std.armv6
@@ -0,0 +1,38 @@
+# Standard kernel config items for all ARMv6/v7 systems.
+#
+# $FreeBSD$
+
+options PREEMPTION # Enable kernel thread preemption
+options INET # InterNETworking
+options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
+options FFS # Berkeley Fast Filesystem
+options SOFTUPDATES # Enable FFS soft updates support
+options UFS_ACL # Support for access control lists
+options UFS_DIRHASH # Improve performance on big directories
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
+options MSDOSFS # MSDOS Filesystem
+options CD9660 # ISO 9660 Filesystem
+options PROCFS # Process filesystem (requires PSEUDOFS)
+options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
+options GEOM_LABEL # Provides labelization
+options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
+options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
+options KTRACE # ktrace(1) support
+options SYSVSHM # SYSV-style shared memory
+options SYSVMSG # SYSV-style message queues
+options SYSVSEM # SYSV-style semaphores
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+
+options ARM_NEW_PMAP # Use new pmap code.
diff --git a/sys/arm/freescale/imx/imx6_anatop.c b/sys/arm/freescale/imx/imx6_anatop.c
index a3845011395c..16a09d3ab83b 100644
--- a/sys/arm/freescale/imx/imx6_anatop.c
+++ b/sys/arm/freescale/imx/imx6_anatop.c
@@ -71,6 +71,7 @@ __FBSDID("$FreeBSD$");
#include <arm/arm/mpcore_timervar.h>
#include <arm/freescale/fsl_ocotpreg.h>
#include <arm/freescale/fsl_ocotpvar.h>
+#include <arm/freescale/imx/imx_ccmvar.h>
#include <arm/freescale/imx/imx6_anatopreg.h>
#include <arm/freescale/imx/imx6_anatopvar.h>
@@ -116,12 +117,16 @@ static struct imx6_anatop_softc *imx6_anatop_sc;
/*
* Table of "operating points".
* These are combinations of frequency and voltage blessed by Freescale.
+ * While the datasheet says the ARM voltage can be as low as 925mV at
+ * 396MHz, it also says that the ARM and SOC voltages can't differ by
+ * more than 200mV, and the minimum SOC voltage is 1150mV, so that
+ * dictates the 950mV entry in this table.
*/
static struct oppt {
uint32_t mhz;
uint32_t mv;
} imx6_oppt_table[] = {
-/* { 396, 925}, XXX: need functional ccm code for this speed */
+ { 396, 950},
{ 792, 1150},
{ 852, 1225},
{ 996, 1225},
@@ -158,14 +163,15 @@ imx6_anatop_write_4(bus_size_t offset, uint32_t value)
static void
vdd_set(struct imx6_anatop_softc *sc, int mv)
{
- int newtarg, oldtarg;
+ int newtarg, newtargSoc, oldtarg;
uint32_t delay, pmureg;
static boolean_t init_done = false;
/*
* The datasheet says VDD_PU and VDD_SOC must be equal, and VDD_ARM
- * can't be more than 50mV above or 200mV below them. For now to keep
- * things simple we set all three to the same value.
+ * can't be more than 50mV above or 200mV below them. We keep them the
+ * same except in the case of the lowest operating point, which is
+ * handled as a special case below.
*/
pmureg = imx6_anatop_read_4(IMX6_ANALOG_PMU_REG_CORE);
@@ -180,19 +186,29 @@ vdd_set(struct imx6_anatop_softc *sc, int mv)
newtarg = (mv - 700) / 25;
/*
+ * The SOC voltage can't go below 1150mV, and thus because of the 200mV
+ * rule, the ARM voltage can't go below 950mV. The 950 is encoded in
+ * our oppt table, here we handle the SOC 1150 rule as a special case.
+ * (1150-700/25=18).
+ */
+ newtargSoc = (newtarg < 18) ? 18 : newtarg;
+
+ /*
* The first time through the 3 voltages might not be equal so use a
* long conservative delay. After that we need to delay 3uS for every
- * 25mV step upward. No need to delay at all when lowering.
+ * 25mV step upward; we actually delay 6uS because empirically, it works
+ * and the 3uS per step recommended by the docs doesn't (3uS fails when
+ * going from 400->1200, but works for smaller changes).
*/
if (init_done) {
if (newtarg == oldtarg)
return;
else if (newtarg > oldtarg)
- delay = (newtarg - oldtarg) * 3;
+ delay = (newtarg - oldtarg) * 6;
else
delay = 0;
} else {
- delay = 700 / 25 * 3;
+ delay = (700 / 25) * 6;
init_done = true;
}
@@ -205,7 +221,7 @@ vdd_set(struct imx6_anatop_softc *sc, int mv)
pmureg |= newtarg << IMX6_ANALOG_PMU_REG0_TARG_SHIFT;
pmureg |= newtarg << IMX6_ANALOG_PMU_REG1_TARG_SHIFT;
- pmureg |= newtarg << IMX6_ANALOG_PMU_REG2_TARG_SHIFT;
+ pmureg |= newtargSoc << IMX6_ANALOG_PMU_REG2_TARG_SHIFT;
imx6_anatop_write_4(IMX6_ANALOG_PMU_REG_CORE, pmureg);
DELAY(delay);
@@ -213,24 +229,29 @@ vdd_set(struct imx6_anatop_softc *sc, int mv)
}
static inline uint32_t
-cpufreq_mhz_from_div(struct imx6_anatop_softc *sc, uint32_t div)
+cpufreq_mhz_from_div(struct imx6_anatop_softc *sc, uint32_t corediv,
+ uint32_t plldiv)
{
- return (sc->refosc_mhz * (div / 2));
+ return ((sc->refosc_mhz * (plldiv / 2)) / (corediv + 1));
}
-static inline uint32_t
-cpufreq_mhz_to_div(struct imx6_anatop_softc *sc, uint32_t cpu_mhz)
+static inline void
+cpufreq_mhz_to_div(struct imx6_anatop_softc *sc, uint32_t cpu_mhz,
+ uint32_t *corediv, uint32_t *plldiv)
{
- return (cpu_mhz / (sc->refosc_mhz / 2));
+ *corediv = (cpu_mhz < 650) ? 1 : 0;
+ *plldiv = ((*corediv + 1) * cpu_mhz) / (sc->refosc_mhz / 2);
}
static inline uint32_t
cpufreq_actual_mhz(struct imx6_anatop_softc *sc, uint32_t cpu_mhz)
{
+ uint32_t corediv, plldiv;
- return (cpufreq_mhz_from_div(sc, cpufreq_mhz_to_div(sc, cpu_mhz)));
+ cpufreq_mhz_to_div(sc, cpu_mhz, &corediv, &plldiv);
+ return (cpufreq_mhz_from_div(sc, corediv, plldiv));
}
static struct oppt *
@@ -256,7 +277,7 @@ cpufreq_nearest_oppt(struct imx6_anatop_softc *sc, uint32_t cpu_newmhz)
static void
cpufreq_set_clock(struct imx6_anatop_softc * sc, struct oppt *op)
{
- uint32_t timeout, wrk32;
+ uint32_t corediv, plldiv, timeout, wrk32;
/* If increasing the frequency, we must first increase the voltage. */
if (op->mhz > sc->cpu_curmhz) {
@@ -272,6 +293,7 @@ cpufreq_set_clock(struct imx6_anatop_softc * sc, struct oppt *op)
* - Wait for the LOCK bit to come on; it takes ~50 loop iterations.
* - Turn off bypass mode; cpu should now be running at the new speed.
*/
+ cpufreq_mhz_to_div(sc, op->mhz, &corediv, &plldiv);
imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_CLR,
IMX6_ANALOG_CCM_PLL_ARM_CLK_SRC_MASK);
imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_SET,
@@ -279,7 +301,7 @@ cpufreq_set_clock(struct imx6_anatop_softc * sc, struct oppt *op)
wrk32 = imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM);
wrk32 &= ~IMX6_ANALOG_CCM_PLL_ARM_DIV_MASK;
- wrk32 |= cpufreq_mhz_to_div(sc, op->mhz);
+ wrk32 |= plldiv;
imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM, wrk32);
timeout = 10000;
@@ -290,6 +312,7 @@ cpufreq_set_clock(struct imx6_anatop_softc * sc, struct oppt *op)
imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_CLR,
IMX6_ANALOG_CCM_PLL_ARM_BYPASS);
+ imx_ccm_set_cacrr(corediv);
/* If lowering the frequency, it is now safe to lower the voltage. */
if (op->mhz < sc->cpu_curmhz)
@@ -297,7 +320,7 @@ cpufreq_set_clock(struct imx6_anatop_softc * sc, struct oppt *op)
sc->cpu_curmhz = op->mhz;
/* Tell the mpcore timer that its frequency has changed. */
- arm_tmr_change_frequency(
+ arm_tmr_change_frequency(
cpufreq_actual_mhz(sc, sc->cpu_curmhz) * 1000000 / 2);
}
@@ -748,11 +771,12 @@ imx6_anatop_probe(device_t dev)
uint32_t
imx6_get_cpu_clock()
{
- uint32_t div;
+ uint32_t corediv, plldiv;
- div = imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM) &
+ corediv = imx_ccm_get_cacrr();
+ plldiv = imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM) &
IMX6_ANALOG_CCM_PLL_ARM_DIV_MASK;
- return (cpufreq_mhz_from_div(imx6_anatop_sc, div));
+ return (cpufreq_mhz_from_div(imx6_anatop_sc, corediv, plldiv));
}
static device_method_t imx6_anatop_methods[] = {
diff --git a/sys/arm/freescale/imx/imx6_ccm.c b/sys/arm/freescale/imx/imx6_ccm.c
index 8d7f14f13076..488c55ab2a2f 100644
--- a/sys/arm/freescale/imx/imx6_ccm.c
+++ b/sys/arm/freescale/imx/imx6_ccm.c
@@ -320,6 +320,20 @@ imx_ccm_ahb_hz(void)
return (132000000);
}
+uint32_t
+imx_ccm_get_cacrr(void)
+{
+
+ return (RD4(ccm_sc, CCM_CACCR));
+}
+
+void
+imx_ccm_set_cacrr(uint32_t divisor)
+{
+
+ WR4(ccm_sc, CCM_CACCR, divisor);
+}
+
static device_method_t ccm_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ccm_probe),
diff --git a/sys/arm/freescale/imx/imx6_ccmreg.h b/sys/arm/freescale/imx/imx6_ccmreg.h
index 31d92caa6d4a..85dd372dacbd 100644
--- a/sys/arm/freescale/imx/imx6_ccmreg.h
+++ b/sys/arm/freescale/imx/imx6_ccmreg.h
@@ -29,6 +29,7 @@
#ifndef IMX6_CCMREG_H
#define IMX6_CCMREG_H
+#define CCM_CACCR 0x010
#define CCM_CSCMR1 0x01C
#define SSI1_CLK_SEL_S 10
#define SSI2_CLK_SEL_S 12
@@ -64,6 +65,5 @@
#define CCM_CCGR5 0x07C
#define CCM_CCGR6 0x080
#define CCM_CMEOR 0x088
-
#endif
diff --git a/sys/arm/freescale/imx/imx_ccmvar.h b/sys/arm/freescale/imx/imx_ccmvar.h
index f15943791c68..91a3e45daddb 100644
--- a/sys/arm/freescale/imx/imx_ccmvar.h
+++ b/sys/arm/freescale/imx/imx_ccmvar.h
@@ -53,4 +53,8 @@ void imx_ccm_usb_enable(device_t _usbdev);
void imx_ccm_usbphy_enable(device_t _phydev);
void imx_ccm_ssi_configure(device_t _ssidev);
+/* Routines to get and set the arm clock root divisor register. */
+uint32_t imx_ccm_get_cacrr(void);
+void imx_ccm_set_cacrr(uint32_t _divisor);
+
#endif
diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c
index bc3833036a10..d6c6d2b69f69 100644
--- a/sys/arm64/arm64/nexus.c
+++ b/sys/arm64/arm64/nexus.c
@@ -148,6 +148,10 @@ nexus_attach(device_t dev)
if (rman_init(&mem_rman) || rman_manage_region(&mem_rman, 0, ~0))
panic("nexus_probe mem_rman");
+ /* Add the ofwbus device */
+ /* ARM64TODO: Alternatively add acpi */
+ nexus_add_child(dev, 10, "ofwbus", 0);
+
/*
* First, deal with the children we know about already
*/
diff --git a/sys/boot/efi/boot1/Makefile b/sys/boot/efi/boot1/Makefile
index e61106340b4e..a955bdf38905 100644
--- a/sys/boot/efi/boot1/Makefile
+++ b/sys/boot/efi/boot1/Makefile
@@ -33,6 +33,9 @@ FILESMODE_boot1.efi= ${BINMODE}
LDSCRIPT= ${.CURDIR}/../loader/arch/${MACHINE}/ldscript.${MACHINE}
LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared
+.if ${MACHINE_CPUARCH} == "aarch64"
+CFLAGS+= -msoft-float -mgeneral-regs-only
+.endif
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
CFLAGS+= -fPIC
LDFLAGS+= -Wl,-znocombreloc
diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile
index 88ca242dd0af..d248927c2b90 100644
--- a/sys/boot/efi/libefi/Makefile
+++ b/sys/boot/efi/libefi/Makefile
@@ -6,6 +6,9 @@ INTERNALLIB=
SRCS= delay.c efi_console.c efinet.c efipart.c errno.c handles.c \
libefi.c time.c
+.if ${MACHINE_CPUARCH} == "aarch64"
+CFLAGS+= -msoft-float -mgeneral-regs-only
+.endif
.if ${MACHINE_ARCH} == "amd64"
CFLAGS+= -fPIC -mno-red-zone
.endif
diff --git a/sys/boot/efi/loader/Makefile b/sys/boot/efi/loader/Makefile
index 5585f78e3129..06e76a90a051 100644
--- a/sys/boot/efi/loader/Makefile
+++ b/sys/boot/efi/loader/Makefile
@@ -38,6 +38,12 @@ CFLAGS+= -I${.CURDIR}/../../..
CFLAGS+= -I${.CURDIR}/../../i386/libi386
CFLAGS+= -DNO_PCI -DEFI
+# make buildenv doesn't set DESTDIR, this means LIBSTAND
+# will be wrong when crossbuilding.
+.if exists(${.OBJDIR}/../../../../lib/libstand/libstand.a)
+LIBSTAND= ${.OBJDIR}/../../../../lib/libstand/libstand.a
+.endif
+
.if ${MK_FORTH} != "no"
BOOT_FORTH= yes
CFLAGS+= -DBOOT_FORTH
diff --git a/sys/boot/efi/loader/arch/arm64/Makefile.inc b/sys/boot/efi/loader/arch/arm64/Makefile.inc
index e5064cc0fffe..82d8cef1b227 100644
--- a/sys/boot/efi/loader/arch/arm64/Makefile.inc
+++ b/sys/boot/efi/loader/arch/arm64/Makefile.inc
@@ -7,3 +7,5 @@ SRCS+= exec.c \
.PATH: ${.CURDIR}/../../arm64/libarm64
CFLAGS+=-I${.CURDIR}/../../arm64/libarm64
SRCS+= cache.c
+
+CFLAGS+= -msoft-float -mgeneral-regs-only
diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c
index 93c6059deea9..8044db5b0167 100644
--- a/sys/boot/efi/loader/main.c
+++ b/sys/boot/efi/loader/main.c
@@ -59,6 +59,7 @@ EFI_GUID dxe = DXE_SERVICES_TABLE_GUID;
EFI_GUID hoblist = HOB_LIST_TABLE_GUID;
EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID;
EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID;
+EFI_GUID fdtdtb = FDT_TABLE_GUID;
EFI_STATUS
main(int argc, CHAR16 *argv[])
@@ -287,6 +288,8 @@ command_configuration(int argc, char *argv[])
printf("Memory Type Information Table");
else if (!memcmp(guid, &debugimg, sizeof(EFI_GUID)))
printf("Debug Image Info Table");
+ else if (!memcmp(guid, &fdtdtb, sizeof(EFI_GUID)))
+ printf("FDT Table");
else
printf("Unknown Table (%s)", guid_to_string(guid));
printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c
index 44c4d212a522..ae1e5597a3c8 100644
--- a/sys/boot/sparc64/loader/main.c
+++ b/sys/boot/sparc64/loader/main.c
@@ -101,7 +101,7 @@ static inline u_long itlb_get_data_sun4u(u_int, u_int);
static int itlb_enter_sun4u(u_int, u_long data, vm_offset_t);
static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t);
static void itlb_relocate_locked0_sun4u(void);
-extern vm_offset_t md_load(char *, vm_offset_t *);
+extern vm_offset_t md_load(char *, vm_offset_t *, vm_offset_t *);
static int sparc64_autoload(void);
static ssize_t sparc64_readin(const int, vm_offset_t, const size_t);
static ssize_t sparc64_copyin(const void *, vm_offset_t, size_t);
@@ -340,7 +340,7 @@ static int
__elfN(exec)(struct preloaded_file *fp)
{
struct file_metadata *fmp;
- vm_offset_t mdp;
+ vm_offset_t mdp, dtbp;
Elf_Addr entry;
Elf_Ehdr *e;
int error;
@@ -349,7 +349,7 @@ __elfN(exec)(struct preloaded_file *fp)
return (EFTYPE);
e = (Elf_Ehdr *)&fmp->md_data;
- if ((error = md_load(fp->f_args, &mdp)) != 0)
+ if ((error = md_load(fp->f_args, &mdp, &dtbp)) != 0)
return (error);
printf("jumping to kernel entry at %#lx.\n", e->e_entry);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
index d74c2cf88203..cbccad359c3f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
@@ -2010,7 +2010,7 @@ dmu_recv_end_check(void *arg, dmu_tx_t *tx)
error = dsl_dataset_hold_obj(dp, obj, FTAG,
&snap);
if (error != 0)
- return (error);
+ break;
if (snap->ds_dir != origin_head->ds_dir)
error = SET_ERROR(EINVAL);
if (error == 0) {
@@ -2020,7 +2020,11 @@ dmu_recv_end_check(void *arg, dmu_tx_t *tx)
obj = dsl_dataset_phys(snap)->ds_prev_snap_obj;
dsl_dataset_rele(snap, FTAG);
if (error != 0)
- return (error);
+ break;
+ }
+ if (error != 0) {
+ dsl_dataset_rele(origin_head, FTAG);
+ return (error);
}
}
error = dsl_dataset_clone_swap_check_impl(drc->drc_ds,
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
index 3fb66c864ee9..c8e3105ff0b2 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
@@ -261,10 +261,6 @@ VTOZ(vnode_t *vp)
} \
}
-/* Called on entry to each ZFS vnode and vfs operation that can not return EIO */
-#define ZFS_ENTER_NOERROR(zfsvfs) \
- rrm_enter(&(zfsvfs)->z_teardown_lock, RW_READER, FTAG)
-
/* Must be called before exiting the vop */
#define ZFS_EXIT(zfsvfs) rrm_exit(&(zfsvfs)->z_teardown_lock, FTAG)
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 415db9edbe52..5824828c7a07 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -1239,9 +1239,6 @@ zfs_domount(vfs_t *vfsp, char *osname)
}
vfs_mountedfrom(vfsp, osname);
- /* Grab extra reference. */
- VERIFY(VFS_ROOT(vfsp, LK_EXCLUSIVE, &vp) == 0);
- VOP_UNLOCK(vp, 0);
if (!zfsvfs->z_issnap)
zfsctl_create(zfsvfs);
@@ -1819,7 +1816,7 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp)
znode_t *rootzp;
int error;
- ZFS_ENTER_NOERROR(zfsvfs);
+ ZFS_ENTER(zfsvfs);
error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
if (error == 0)
@@ -1994,7 +1991,7 @@ zfs_umount(vfs_t *vfsp, int fflag)
/*
* Flush all the files.
*/
- ret = vflush(vfsp, 1, (fflag & MS_FORCE) ? FORCECLOSE : 0, td);
+ ret = vflush(vfsp, 0, (fflag & MS_FORCE) ? FORCECLOSE : 0, td);
if (ret != 0) {
if (!zfsvfs->z_issnap) {
zfsctl_create(zfsvfs);
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 8696b3664b3d..67210ff59de4 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -248,7 +248,7 @@ freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfss
{
struct statfs *buf, *sp;
struct statfs32 stat32;
- size_t count, size;
+ size_t count, size, copycount;
int error;
count = uap->bufsize / sizeof(struct statfs32);
@@ -256,12 +256,13 @@ freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfss
error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE, uap->flags);
if (size > 0) {
sp = buf;
- while (count > 0 && error == 0) {
+ copycount = count;
+ while (copycount > 0 && error == 0) {
copy_statfs(sp, &stat32);
error = copyout(&stat32, uap->buf, sizeof(stat32));
sp++;
uap->buf++;
- count--;
+ copycount--;
}
free(buf, M_TEMP);
}
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index 92f41019b427..1a67f5c7dd8d 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -43,6 +43,7 @@ dev/iicbus/ds1775.c optional ds1775 powermac
dev/iicbus/max6690.c optional max6690 powermac
dev/kbd/kbd.c optional sc | vt
dev/nand/nfc_fsl.c optional nand mpc85xx
+dev/nand/nfc_rb.c optional nand mpc85xx
# ofw can be either aim or fdt: fdt case handled in files. aim only powerpc specific.
dev/ofw/openfirm.c optional aim
dev/ofw/openfirmio.c optional aim
diff --git a/sys/conf/options b/sys/conf/options
index b6987173e6fc..6d2a0fa160dd 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -692,6 +692,7 @@ ACPI_DEBUG opt_acpi.h
ACPI_MAX_TASKS opt_acpi.h
ACPI_MAX_THREADS opt_acpi.h
ACPI_DMAR opt_acpi.h
+DEV_ACPI opt_acpi.h
# ISA support
DEV_ISA opt_isa.h
diff --git a/sys/dev/mrsas/mrsas.c b/sys/dev/mrsas/mrsas.c
index 1fa94f1393ef..6f63c6eef363 100644
--- a/sys/dev/mrsas/mrsas.c
+++ b/sys/dev/mrsas/mrsas.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
@@ -81,16 +82,19 @@ static int mrsas_init_fw(struct mrsas_softc *sc);
static int mrsas_setup_raidmap(struct mrsas_softc *sc);
static int mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex);
static int mrsas_clear_intr(struct mrsas_softc *sc);
-static int
-mrsas_get_ctrl_info(struct mrsas_softc *sc,
- struct mrsas_ctrl_info *ctrl_info);
-static int
+static int mrsas_get_ctrl_info(struct mrsas_softc *sc);
+static void mrsas_update_ext_vd_details(struct mrsas_softc *sc);
+static int
mrsas_issue_blocked_abort_cmd(struct mrsas_softc *sc,
struct mrsas_mfi_cmd *cmd_to_abort);
+static struct mrsas_softc *
+mrsas_get_softc_instance(struct cdev *dev,
+ u_long cmd, caddr_t arg);
u_int32_t mrsas_read_reg(struct mrsas_softc *sc, int offset);
-u_int8_t
+u_int8_t
mrsas_build_mptmfi_passthru(struct mrsas_softc *sc,
struct mrsas_mfi_cmd *mfi_cmd);
+void mrsas_complete_outstanding_ioctls(struct mrsas_softc *sc);
int mrsas_transition_to_ready(struct mrsas_softc *sc, int ocr);
int mrsas_init_adapter(struct mrsas_softc *sc);
int mrsas_alloc_mpt_cmds(struct mrsas_softc *sc);
@@ -102,10 +106,10 @@ int mrsas_issue_dcmd(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd);
int mrsas_issue_polled(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd);
int mrsas_reset_ctrl(struct mrsas_softc *sc);
int mrsas_wait_for_outstanding(struct mrsas_softc *sc);
-int
+int
mrsas_issue_blocked_cmd(struct mrsas_softc *sc,
struct mrsas_mfi_cmd *cmd);
-int
+int
mrsas_alloc_tmp_dcmd(struct mrsas_softc *sc, struct mrsas_tmp_dcmd *tcmd,
int size);
void mrsas_release_mfi_cmd(struct mrsas_mfi_cmd *cmd);
@@ -122,17 +126,17 @@ void mrsas_teardown_intr(struct mrsas_softc *sc);
void mrsas_addr_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error);
void mrsas_kill_hba(struct mrsas_softc *sc);
void mrsas_aen_handler(struct mrsas_softc *sc);
-void
+void
mrsas_write_reg(struct mrsas_softc *sc, int offset,
u_int32_t value);
-void
+void
mrsas_fire_cmd(struct mrsas_softc *sc, u_int32_t req_desc_lo,
u_int32_t req_desc_hi);
void mrsas_free_ctlr_info_cmd(struct mrsas_softc *sc);
-void
+void
mrsas_complete_mptmfi_passthru(struct mrsas_softc *sc,
struct mrsas_mfi_cmd *cmd, u_int8_t status);
-void
+void
mrsas_map_mpt_cmd_status(struct mrsas_mpt_cmd *cmd, u_int8_t status,
u_int8_t extStatus);
struct mrsas_mfi_cmd *mrsas_get_mfi_cmd(struct mrsas_softc *sc);
@@ -175,9 +179,9 @@ typedef struct mrsas_ident {
} MRSAS_CTLR_ID;
MRSAS_CTLR_ID device_table[] = {
- {0x1000, MRSAS_TBOLT, 0xffff, 0xffff, "LSI Thunderbolt SAS Controller"},
- {0x1000, MRSAS_INVADER, 0xffff, 0xffff, "LSI Invader SAS Controller"},
- {0x1000, MRSAS_FURY, 0xffff, 0xffff, "LSI Fury SAS Controller"},
+ {0x1000, MRSAS_TBOLT, 0xffff, 0xffff, "AVAGO Thunderbolt SAS Controller"},
+ {0x1000, MRSAS_INVADER, 0xffff, 0xffff, "AVAGO Invader SAS Controller"},
+ {0x1000, MRSAS_FURY, 0xffff, 0xffff, "AVAGO Fury SAS Controller"},
{0, 0, 0, 0, NULL}
};
@@ -272,6 +276,7 @@ mrsas_disable_intr(struct mrsas_softc *sc)
u_int32_t mask = 0xFFFFFFFF;
u_int32_t status;
+ sc->mask_interrupts = 1;
mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask), mask);
/* Dummy read to force pci flush */
status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_mask));
@@ -283,6 +288,7 @@ mrsas_enable_intr(struct mrsas_softc *sc)
u_int32_t mask = MFI_FUSION_ENABLE_INTERRUPT_MASK;
u_int32_t status;
+ sc->mask_interrupts = 0;
mrsas_write_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status), ~0);
status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status));
@@ -352,7 +358,7 @@ mrsas_probe(device_t dev)
if ((id = mrsas_find_ident(dev)) != NULL) {
if (first_ctrl) {
- printf("LSI MegaRAID SAS FreeBSD mrsas driver version: %s\n",
+ printf("AVAGO MegaRAID SAS FreeBSD mrsas driver version: %s\n",
MRSAS_VERSION);
first_ctrl = 0;
}
@@ -460,6 +466,11 @@ mrsas_get_tunables(struct mrsas_softc *sc)
*/
TUNABLE_INT_FETCH("hw.mrsas.debug_level", &sc->mrsas_debug);
+ /*
+ * Grab the global variables.
+ */
+ TUNABLE_INT_FETCH("hw.mrsas.lb_pending_cmds", &sc->lb_pending_cmds);
+
/* Grab the unit-instance variables */
snprintf(tmpstr, sizeof(tmpstr), "dev.mrsas.%d.debug_level",
device_get_unit(sc->mrsas_dev));
@@ -1163,6 +1174,12 @@ mrsas_free_mem(struct mrsas_softc *sc)
*/
if (sc->mrsas_parent_tag != NULL)
bus_dma_tag_destroy(sc->mrsas_parent_tag);
+
+ /*
+ * Free ctrl_info memory
+ */
+ if (sc->ctrl_info != NULL)
+ free(sc->ctrl_info, M_MRSAS);
}
/*
@@ -1231,6 +1248,43 @@ mrsas_resume(device_t dev)
return (0);
}
+/**
+ * mrsas_get_softc_instance: Find softc instance based on cmd type
+ *
+ * This function will return softc instance based on cmd type.
+ * In some case, application fire ioctl on required management instance and
+ * do not provide host_no. Use cdev->si_drv1 to get softc instance for those
+ * case, else get the softc instance from host_no provided by application in
+ * user data.
+ */
+
+static struct mrsas_softc *
+mrsas_get_softc_instance(struct cdev *dev, u_long cmd, caddr_t arg)
+{
+ struct mrsas_softc *sc = NULL;
+ struct mrsas_iocpacket *user_ioc = (struct mrsas_iocpacket *)arg;
+
+ if (cmd == MRSAS_IOC_GET_PCI_INFO) {
+ sc = dev->si_drv1;
+ } else {
+ /*
+ * get the Host number & the softc from data sent by the
+ * Application
+ */
+ sc = mrsas_mgmt_info.sc_ptr[user_ioc->host_no];
+ if ((user_ioc->host_no >= mrsas_mgmt_info.max_index) || (sc == NULL)) {
+ if (sc == NULL)
+ mrsas_dprint(sc, MRSAS_FAULT,
+ "There is no Controller number %d .\n", user_ioc->host_no);
+ else
+ mrsas_dprint(sc, MRSAS_FAULT,
+ "Invalid Controller number %d .\n", user_ioc->host_no);
+ }
+ }
+
+ return sc;
+}
+
/*
* mrsas_ioctl: IOCtl commands entry point.
*
@@ -1243,19 +1297,12 @@ mrsas_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag,
{
struct mrsas_softc *sc;
int ret = 0, i = 0;
+ MRSAS_DRV_PCI_INFORMATION *pciDrvInfo;
- struct mrsas_iocpacket *user_ioc = (struct mrsas_iocpacket *)arg;
-
- /* get the Host number & the softc from data sent by the Application */
- sc = mrsas_mgmt_info.sc_ptr[user_ioc->host_no];
-
- if ((mrsas_mgmt_info.max_index == user_ioc->host_no) || (sc == NULL)) {
- printf("Please check the controller number\n");
- if (sc == NULL)
- printf("There is NO such Host no. %d\n", user_ioc->host_no);
-
+ sc = mrsas_get_softc_instance(dev, cmd, arg);
+ if (!sc)
return ENOENT;
- }
+
if (sc->remove_in_progress) {
mrsas_dprint(sc, MRSAS_INFO,
"Driver remove or shutdown called.\n");
@@ -1299,6 +1346,22 @@ do_ioctl:
case MRSAS_IOC_SCAN_BUS:
ret = mrsas_bus_scan(sc);
break;
+
+ case MRSAS_IOC_GET_PCI_INFO:
+ pciDrvInfo = (MRSAS_DRV_PCI_INFORMATION *) arg;
+ memset(pciDrvInfo, 0, sizeof(MRSAS_DRV_PCI_INFORMATION));
+ pciDrvInfo->busNumber = pci_get_bus(sc->mrsas_dev);
+ pciDrvInfo->deviceNumber = pci_get_slot(sc->mrsas_dev);
+ pciDrvInfo->functionNumber = pci_get_function(sc->mrsas_dev);
+ pciDrvInfo->domainID = pci_get_domain(sc->mrsas_dev);
+ mrsas_dprint(sc, MRSAS_INFO, "pci bus no: %d,"
+ "pci device no: %d, pci function no: %d,"
+ "pci domain ID: %d\n",
+ pciDrvInfo->busNumber, pciDrvInfo->deviceNumber,
+ pciDrvInfo->functionNumber, pciDrvInfo->domainID);
+ ret = 0;
+ break;
+
default:
mrsas_dprint(sc, MRSAS_TRACE, "IOCTL command 0x%lx is not handled\n", cmd);
ret = ENOENT;
@@ -1328,8 +1391,10 @@ mrsas_poll(struct cdev *dev, int poll_events, struct thread *td)
}
if (revents == 0) {
if (poll_events & (POLLIN | POLLRDNORM)) {
+ mtx_lock(&sc->aen_lock);
sc->mrsas_poll_waiting = 1;
selrecord(td, &sc->mrsas_select);
+ mtx_unlock(&sc->aen_lock);
}
}
return revents;
@@ -1387,6 +1452,9 @@ mrsas_isr(void *arg)
struct mrsas_softc *sc = irq_context->sc;
int status = 0;
+ if (sc->mask_interrupts)
+ return;
+
if (!sc->msix_vectors) {
status = mrsas_clear_intr(sc);
if (!status)
@@ -1424,7 +1492,7 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex)
MRSAS_RAID_SCSI_IO_REQUEST *scsi_io_req;
struct mrsas_mpt_cmd *cmd_mpt;
struct mrsas_mfi_cmd *cmd_mfi;
- u_int8_t arm, reply_descript_type;
+ u_int8_t reply_descript_type;
u_int16_t smid, num_completed;
u_int8_t status, extStatus;
union desc_value desc_val;
@@ -1462,8 +1530,7 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex)
device_id = cmd_mpt->ccb_ptr->ccb_h.target_id;
lbinfo = &sc->load_balance_info[device_id];
if (cmd_mpt->load_balance == MRSAS_LOAD_BALANCE_FLAG) {
- arm = lbinfo->raid1DevHandle[0] == scsi_io_req->DevHandle ? 0 : 1;
- mrsas_atomic_dec(&lbinfo->scsi_pending_cmds[arm]);
+ mrsas_atomic_dec(&lbinfo->scsi_pending_cmds[cmd_mpt->pd_r1_lb]);
cmd_mpt->load_balance &= ~MRSAS_LOAD_BALANCE_FLAG;
}
/* Fall thru and complete IO */
@@ -1608,8 +1675,8 @@ mrsas_map_mpt_cmd_status(struct mrsas_mpt_cmd *cmd, u_int8_t status, u_int8_t ex
static int
mrsas_alloc_mem(struct mrsas_softc *sc)
{
- u_int32_t verbuf_size, io_req_size, reply_desc_size, sense_size, chain_frame_size,
- evt_detail_size, count;
+ u_int32_t verbuf_size, io_req_size, reply_desc_size, sense_size,
+ chain_frame_size, evt_detail_size, count;
/*
* Allocate parent DMA tag
@@ -1861,34 +1928,6 @@ mrsas_setup_raidmap(struct mrsas_softc *sc)
{
int i;
- sc->drv_supported_vd_count =
- MRSAS_MAX_LD_CHANNELS * MRSAS_MAX_DEV_PER_CHANNEL;
- sc->drv_supported_pd_count =
- MRSAS_MAX_PD_CHANNELS * MRSAS_MAX_DEV_PER_CHANNEL;
-
- if (sc->max256vdSupport) {
- sc->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT;
- sc->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
- } else {
- sc->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
- sc->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
- }
-
-#if VD_EXT_DEBUG
- device_printf(sc->mrsas_dev, "FW supports: max256vdSupport = %s\n",
- sc->max256vdSupport ? "YES" : "NO");
- device_printf(sc->mrsas_dev, "FW supports %dVDs %dPDs\n"
- "DRIVER supports %dVDs %dPDs \n",
- sc->fw_supported_vd_count, sc->fw_supported_pd_count,
- sc->drv_supported_vd_count, sc->drv_supported_pd_count);
-#endif
-
- sc->old_map_sz = sizeof(MR_FW_RAID_MAP) +
- (sizeof(MR_LD_SPAN_MAP) * (sc->fw_supported_vd_count - 1));
- sc->new_map_sz = sizeof(MR_FW_RAID_MAP_EXT);
- sc->drv_map_sz = sizeof(MR_DRV_RAID_MAP) +
- (sizeof(MR_LD_SPAN_MAP) * (sc->drv_supported_vd_count - 1));
-
for (i = 0; i < 2; i++) {
sc->ld_drv_map[i] =
(void *)malloc(sc->drv_map_sz, M_MRSAS, M_NOWAIT);
@@ -1903,14 +1942,6 @@ mrsas_setup_raidmap(struct mrsas_softc *sc)
}
}
- sc->max_map_sz = max(sc->old_map_sz, sc->new_map_sz);
-
- if (sc->max256vdSupport)
- sc->current_map_sz = sc->new_map_sz;
- else
- sc->current_map_sz = sc->old_map_sz;
-
-
for (int i = 0; i < 2; i++) {
if (bus_dma_tag_create(sc->mrsas_parent_tag,
4, 0,
@@ -1970,7 +2001,7 @@ ABORT:
* get_pdlist, get_ld_list and max_sectors are currently not being used, it
* is left here as placeholder.
*/
-static int
+static int
mrsas_init_fw(struct mrsas_softc *sc)
{
@@ -1978,7 +2009,6 @@ mrsas_init_fw(struct mrsas_softc *sc)
u_int32_t max_sectors_1;
u_int32_t max_sectors_2;
u_int32_t tmp_sectors;
- struct mrsas_ctrl_info *ctrl_info;
u_int32_t scratch_pad_2;
int msix_enable = 0;
int fw_msix_count = 0;
@@ -2040,23 +2070,25 @@ mrsas_init_fw(struct mrsas_softc *sc)
device_printf(sc->mrsas_dev, "Allocate MFI cmd failed.\n");
return (1);
}
+ sc->ctrl_info = malloc(sizeof(struct mrsas_ctrl_info), M_MRSAS, M_NOWAIT);
+ if (!sc->ctrl_info) {
+ device_printf(sc->mrsas_dev, "Malloc for ctrl_info failed.\n");
+ return (1);
+ }
/*
* Get the controller info from FW, so that the MAX VD support
* availability can be decided.
*/
- ctrl_info = malloc(sizeof(struct mrsas_ctrl_info), M_MRSAS, M_NOWAIT);
- if (!ctrl_info)
- device_printf(sc->mrsas_dev, "Malloc for ctrl_info failed.\n");
-
- if (mrsas_get_ctrl_info(sc, ctrl_info)) {
+ if (mrsas_get_ctrl_info(sc)) {
device_printf(sc->mrsas_dev, "Unable to get FW ctrl_info.\n");
+ return (1);
}
- sc->max256vdSupport =
- (u_int8_t)ctrl_info->adapterOperations3.supportMaxExtLDs;
+ sc->secure_jbod_support =
+ (u_int8_t)sc->ctrl_info->adapterOperations3.supportSecurityonJBOD;
+
+ if (sc->secure_jbod_support)
+ device_printf(sc->mrsas_dev, "FW supports SED \n");
- if (ctrl_info->max_lds > 64) {
- sc->max256vdSupport = 1;
- }
if (mrsas_setup_raidmap(sc) != SUCCESS) {
device_printf(sc->mrsas_dev, "Set up RAID map failed.\n");
return (1);
@@ -2080,9 +2112,9 @@ mrsas_init_fw(struct mrsas_softc *sc)
* calculate max_sectors_1. So the number ended up as zero always.
*/
tmp_sectors = 0;
- max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
- ctrl_info->max_strips_per_io;
- max_sectors_2 = ctrl_info->max_request_size;
+ max_sectors_1 = (1 << sc->ctrl_info->stripe_sz_ops.min) *
+ sc->ctrl_info->max_strips_per_io;
+ max_sectors_2 = sc->ctrl_info->max_request_size;
tmp_sectors = min(max_sectors_1, max_sectors_2);
sc->max_sectors_per_req = sc->max_num_sge * MRSAS_PAGE_SIZE / 512;
@@ -2090,9 +2122,9 @@ mrsas_init_fw(struct mrsas_softc *sc)
sc->max_sectors_per_req = tmp_sectors;
sc->disableOnlineCtrlReset =
- ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
+ sc->ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
sc->UnevenSpanSupport =
- ctrl_info->adapterOperations2.supportUnevenSpans;
+ sc->ctrl_info->adapterOperations2.supportUnevenSpans;
if (sc->UnevenSpanSupport) {
device_printf(sc->mrsas_dev, "FW supports: UnevenSpanSupport=%x\n\n",
sc->UnevenSpanSupport);
@@ -2102,9 +2134,6 @@ mrsas_init_fw(struct mrsas_softc *sc)
else
sc->fast_path_io = 0;
}
- if (ctrl_info)
- free(ctrl_info, M_MRSAS);
-
return (0);
}
@@ -2136,7 +2165,7 @@ mrsas_init_adapter(struct mrsas_softc *sc)
max_cmd = sc->max_fw_cmds;
/* Determine allocation size of command frames */
- sc->reply_q_depth = ((max_cmd + 1 + 15) / 16 * 16);
+ sc->reply_q_depth = ((max_cmd + 1 + 15) / 16 * 16) * 2;
sc->request_alloc_sz = sizeof(MRSAS_REQUEST_DESCRIPTOR_UNION) * max_cmd;
sc->reply_alloc_sz = sizeof(MPI2_REPLY_DESCRIPTORS_UNION) * (sc->reply_q_depth);
sc->io_frames_alloc_sz = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE + (MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * (max_cmd + 1));
@@ -2281,7 +2310,9 @@ mrsas_ioc_init(struct mrsas_softc *sc)
init_frame->driver_ver_lo = (bus_addr_t)sc->verbuf_phys_addr;
init_frame->driver_ver_hi = 0;
}
+ init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb = 1;
init_frame->driver_operations.mfi_capabilities.support_max_255lds = 1;
+ init_frame->driver_operations.mfi_capabilities.security_protocol_cmds_fw = 1;
phys_addr = (bus_addr_t)sc->ioc_init_phys_mem + 1024;
init_frame->queue_info_new_phys_addr_lo = phys_addr;
init_frame->data_xfer_len = sizeof(Mpi2IOCInitRequest_t);
@@ -2423,7 +2454,7 @@ mrsas_alloc_mpt_cmds(struct mrsas_softc *sc)
* This functions fires the command to Firmware by writing to the
* inbound_low_queue_port and inbound_high_queue_port.
*/
-void
+void
mrsas_fire_cmd(struct mrsas_softc *sc, u_int32_t req_desc_lo,
u_int32_t req_desc_hi)
{
@@ -2703,7 +2734,6 @@ mrsas_reset_ctrl(struct mrsas_softc *sc)
/* Reset not supported, kill adapter */
mrsas_dprint(sc, MRSAS_OCR, "Reset not supported, killing adapter.\n");
mrsas_kill_hba(sc);
- sc->adprecovery = MRSAS_HW_CRITICAL_ERROR;
retval = FAIL;
goto out;
}
@@ -2788,10 +2818,6 @@ mrsas_reset_ctrl(struct mrsas_softc *sc)
mrsas_dprint(sc, MRSAS_OCR, "mrsas_ioc_init() failed!\n");
continue;
}
- mrsas_clear_bit(MRSAS_FUSION_IN_RESET, &sc->reset_flags);
- mrsas_enable_intr(sc);
- sc->adprecovery = MRSAS_HBA_OPERATIONAL;
-
/* Re-fire management commands */
for (j = 0; j < sc->max_fw_cmds; j++) {
mpt_cmd = sc->mpt_cmd_list[j];
@@ -2821,9 +2847,18 @@ mrsas_reset_ctrl(struct mrsas_softc *sc)
memset(sc->load_balance_info, 0,
sizeof(LD_LOAD_BALANCE_INFO) * MAX_LOGICAL_DRIVES_EXT);
+ if (mrsas_get_ctrl_info(sc)) {
+ mrsas_kill_hba(sc);
+ retval = FAIL;
+ goto out;
+ }
if (!mrsas_get_map_info(sc))
mrsas_sync_map_info(sc);
+ mrsas_clear_bit(MRSAS_FUSION_IN_RESET, &sc->reset_flags);
+ mrsas_enable_intr(sc);
+ sc->adprecovery = MRSAS_HBA_OPERATIONAL;
+
/* Adapter reset completed successfully */
device_printf(sc->mrsas_dev, "Reset successful\n");
retval = SUCCESS;
@@ -2854,11 +2889,43 @@ out:
void
mrsas_kill_hba(struct mrsas_softc *sc)
{
+ sc->adprecovery = MRSAS_HW_CRITICAL_ERROR;
+ pause("mrsas_kill_hba", 1000);
mrsas_dprint(sc, MRSAS_OCR, "%s\n", __func__);
mrsas_write_reg(sc, offsetof(mrsas_reg_set, doorbell),
MFI_STOP_ADP);
/* Flush */
mrsas_read_reg(sc, offsetof(mrsas_reg_set, doorbell));
+ mrsas_complete_outstanding_ioctls(sc);
+}
+
+/**
+ * mrsas_complete_outstanding_ioctls Complete pending IOCTLS after kill_hba
+ * input: Controller softc
+ *
+ * Returns void
+ */
+void
+mrsas_complete_outstanding_ioctls(struct mrsas_softc *sc)
+{
+ int i;
+ struct mrsas_mpt_cmd *cmd_mpt;
+ struct mrsas_mfi_cmd *cmd_mfi;
+ u_int32_t count, MSIxIndex;
+
+ count = sc->msix_vectors > 0 ? sc->msix_vectors : 1;
+ for (i = 0; i < sc->max_fw_cmds; i++) {
+ cmd_mpt = sc->mpt_cmd_list[i];
+
+ if (cmd_mpt->sync_cmd_idx != (u_int32_t)MRSAS_ULONG_MAX) {
+ cmd_mfi = sc->mfi_cmd_list[cmd_mpt->sync_cmd_idx];
+ if (cmd_mfi->sync_cmd && cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT) {
+ for (MSIxIndex = 0; MSIxIndex < count; MSIxIndex++)
+ mrsas_complete_mptmfi_passthru(sc, cmd_mfi,
+ cmd_mpt->io_request->RaidContext.status);
+ }
+ }
+ }
}
/*
@@ -2945,8 +3012,7 @@ mrsas_release_mfi_cmd(struct mrsas_mfi_cmd *cmd)
* supported by the FW.
*/
static int
-mrsas_get_ctrl_info(struct mrsas_softc *sc,
- struct mrsas_ctrl_info *ctrl_info)
+mrsas_get_ctrl_info(struct mrsas_softc *sc)
{
int retcode = 0;
struct mrsas_mfi_cmd *cmd;
@@ -2979,16 +3045,60 @@ mrsas_get_ctrl_info(struct mrsas_softc *sc,
dcmd->sgl.sge32[0].length = sizeof(struct mrsas_ctrl_info);
if (!mrsas_issue_polled(sc, cmd))
- memcpy(ctrl_info, sc->ctlr_info_mem, sizeof(struct mrsas_ctrl_info));
+ memcpy(sc->ctrl_info, sc->ctlr_info_mem, sizeof(struct mrsas_ctrl_info));
else
retcode = 1;
+ mrsas_update_ext_vd_details(sc);
+
mrsas_free_ctlr_info_cmd(sc);
mrsas_release_mfi_cmd(cmd);
return (retcode);
}
/*
+ * mrsas_update_ext_vd_details : Update details w.r.t Extended VD
+ * input:
+ * sc - Controller's softc
+*/
+static void
+mrsas_update_ext_vd_details(struct mrsas_softc *sc)
+{
+ sc->max256vdSupport =
+ sc->ctrl_info->adapterOperations3.supportMaxExtLDs;
+ /* Below is additional check to address future FW enhancement */
+ if (sc->ctrl_info->max_lds > 64)
+ sc->max256vdSupport = 1;
+
+ sc->drv_supported_vd_count = MRSAS_MAX_LD_CHANNELS
+ * MRSAS_MAX_DEV_PER_CHANNEL;
+ sc->drv_supported_pd_count = MRSAS_MAX_PD_CHANNELS
+ * MRSAS_MAX_DEV_PER_CHANNEL;
+ if (sc->max256vdSupport) {
+ sc->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT;
+ sc->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
+ } else {
+ sc->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
+ sc->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
+ }
+
+ sc->old_map_sz = sizeof(MR_FW_RAID_MAP) +
+ (sizeof(MR_LD_SPAN_MAP) *
+ (sc->fw_supported_vd_count - 1));
+ sc->new_map_sz = sizeof(MR_FW_RAID_MAP_EXT);
+ sc->drv_map_sz = sizeof(MR_DRV_RAID_MAP) +
+ (sizeof(MR_LD_SPAN_MAP) *
+ (sc->drv_supported_vd_count - 1));
+
+ sc->max_map_sz = max(sc->old_map_sz, sc->new_map_sz);
+
+ if (sc->max256vdSupport)
+ sc->current_map_sz = sc->new_map_sz;
+ else
+ sc->current_map_sz = sc->old_map_sz;
+}
+
+/*
* mrsas_alloc_ctlr_info_cmd: Allocates memory for controller info command
* input: Adapter soft state
*
@@ -3763,7 +3873,7 @@ mrsas_get_ld_list(struct mrsas_softc *sc)
* memory is initialized to all zeros upon successful loading of the dma
* mapped memory.
*/
-int
+int
mrsas_alloc_tmp_dcmd(struct mrsas_softc *sc,
struct mrsas_tmp_dcmd *tcmd, int size)
{
@@ -3996,10 +4106,12 @@ mrsas_complete_aen(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd)
*/
if ((!cmd->abort_aen) && (sc->remove_in_progress == 0)) {
sc->mrsas_aen_triggered = 1;
+ mtx_lock(&sc->aen_lock);
if (sc->mrsas_poll_waiting) {
sc->mrsas_poll_waiting = 0;
selwakeup(&sc->mrsas_select);
}
+ mtx_unlock(&sc->aen_lock);
} else
cmd->abort_aen = 0;
diff --git a/sys/dev/mrsas/mrsas.h b/sys/dev/mrsas/mrsas.h
index 37b6e952835c..1cfe89e00053 100644
--- a/sys/dev/mrsas/mrsas.h
+++ b/sys/dev/mrsas/mrsas.h
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Authors: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Authors: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
@@ -101,7 +102,7 @@ __FBSDID("$FreeBSD$");
*/
#define BYTE_ALIGNMENT 1
#define MRSAS_MAX_NAME_LENGTH 32
-#define MRSAS_VERSION "06.705.10.02-fbsd"
+#define MRSAS_VERSION "06.707.04.03-fbsd"
#define MRSAS_ULONG_MAX 0xFFFFFFFFFFFFFFFF
#define MRSAS_DEFAULT_TIMEOUT 0x14 /* Temporarily set */
#define DONE 0
@@ -813,9 +814,8 @@ typedef struct _MR_DRV_RAID_MAP_ALL {
typedef struct _LD_LOAD_BALANCE_INFO {
u_int8_t loadBalanceFlag;
u_int8_t reserved1;
- u_int16_t raid1DevHandle[2];
- mrsas_atomic_t scsi_pending_cmds[2];
- u_int64_t last_accessed_block[2];
+ mrsas_atomic_t scsi_pending_cmds[MAX_PHYSICAL_DEVICES];
+ u_int64_t last_accessed_block[MAX_PHYSICAL_DEVICES];
} LD_LOAD_BALANCE_INFO, *PLD_LOAD_BALANCE_INFO;
/* SPAN_SET is info caclulated from span info from Raid map per ld */
@@ -858,6 +858,9 @@ struct IO_REQUEST_INFO {
u_int8_t start_span;
u_int8_t reserved;
u_int64_t start_row;
+ /* span[7:5], arm[4:0] */
+ u_int8_t span_arm;
+ u_int8_t pd_after_lb;
};
typedef struct _MR_LD_TARGET_SYNC {
@@ -1315,6 +1318,13 @@ typedef enum _REGION_TYPE {
#define MRSAS_REQ_STATE_TRAN 2
#define MRSAS_REQ_STATE_COMPLETE 3
+typedef enum _MR_SCSI_CMD_TYPE {
+ READ_WRITE_LDIO = 0,
+ NON_READ_WRITE_LDIO = 1,
+ READ_WRITE_SYSPDIO = 2,
+ NON_READ_WRITE_SYSPDIO = 3,
+} MR_SCSI_CMD_TYPE;
+
enum mrsas_req_flags {
MRSAS_DIR_UNKNOWN = 0x1,
MRSAS_DIR_IN = 0x2,
@@ -1350,6 +1360,7 @@ struct mrsas_mpt_cmd {
u_int32_t sync_cmd_idx;
u_int32_t index;
u_int8_t flags;
+ u_int8_t pd_r1_lb;
u_int8_t load_balance;
bus_size_t length;
u_int32_t error_code;
@@ -1897,9 +1908,26 @@ struct mrsas_ctrl_info {
char reserved6[4]; /* 0x7E4 RESERVED FOR IOV */
struct { /* 0x7E8 */
- u_int32_t resrved:5;
+ u_int32_t supportPersonalityChange:2;
+ u_int32_t supportThermalPollInterval:1;
+ u_int32_t supportDisableImmediateIO:1;
+ u_int32_t supportT10RebuildAssist:1;
u_int32_t supportMaxExtLDs:1;
- u_int32_t reserved1:26;
+ u_int32_t supportCrashDump:1;
+ u_int32_t supportSwZone:1;
+ u_int32_t supportDebugQueue:1;
+ u_int32_t supportNVCacheErase:1;
+ u_int32_t supportForceTo512e:1;
+ u_int32_t supportHOQRebuild:1;
+ u_int32_t supportAllowedOpsforDrvRemoval:1;
+ u_int32_t supportDrvActivityLEDSetting:1;
+ u_int32_t supportNVDRAM:1;
+ u_int32_t supportForceFlash:1;
+ u_int32_t supportDisableSESMonitoring:1;
+ u_int32_t supportCacheBypassModes:1;
+ u_int32_t supportSecurityonJBOD:1;
+ u_int32_t discardCacheDuringLDDelete:1;
+ u_int32_t reserved:12;
} adapterOperations3;
u_int8_t pad[0x800 - 0x7EC]; /* 0x7EC */
@@ -1970,7 +1998,10 @@ typedef union _MFI_CAPABILITIES {
u_int32_t support_additional_msix:1;
u_int32_t support_fastpath_wb:1;
u_int32_t support_max_255lds:1;
- u_int32_t reserved:28;
+ u_int32_t support_ndrive_r1_lb:1;
+ u_int32_t support_core_affinity:1;
+ u_int32_t security_protocol_cmds_fw:1;
+ u_int32_t reserved:25;
} mfi_capabilities;
u_int32_t reg;
} MFI_CAPABILITIES;
@@ -2413,6 +2444,167 @@ struct mrsas_mgmt_info {
int max_index;
};
+#define PCI_TYPE0_ADDRESSES 6
+#define PCI_TYPE1_ADDRESSES 2
+#define PCI_TYPE2_ADDRESSES 5
+
+typedef struct _MRSAS_DRV_PCI_COMMON_HEADER {
+ u_int16_t vendorID;
+ //(ro)
+ u_int16_t deviceID;
+ //(ro)
+ u_int16_t command;
+ //Device control
+ u_int16_t status;
+ u_int8_t revisionID;
+ //(ro)
+ u_int8_t progIf;
+ //(ro)
+ u_int8_t subClass;
+ //(ro)
+ u_int8_t baseClass;
+ //(ro)
+ u_int8_t cacheLineSize;
+ //(ro +)
+ u_int8_t latencyTimer;
+ //(ro +)
+ u_int8_t headerType;
+ //(ro)
+ u_int8_t bist;
+ //Built in self test
+
+ union {
+ struct _MRSAS_DRV_PCI_HEADER_TYPE_0 {
+ u_int32_t baseAddresses[PCI_TYPE0_ADDRESSES];
+ u_int32_t cis;
+ u_int16_t subVendorID;
+ u_int16_t subSystemID;
+ u_int32_t romBaseAddress;
+ u_int8_t capabilitiesPtr;
+ u_int8_t reserved1[3];
+ u_int32_t reserved2;
+ u_int8_t interruptLine;
+ u_int8_t interruptPin;
+ //(ro)
+ u_int8_t minimumGrant;
+ //(ro)
+ u_int8_t maximumLatency;
+ //(ro)
+ } type0;
+
+ /*
+ * PCI to PCI Bridge
+ */
+
+ struct _MRSAS_DRV_PCI_HEADER_TYPE_1 {
+ u_int32_t baseAddresses[PCI_TYPE1_ADDRESSES];
+ u_int8_t primaryBus;
+ u_int8_t secondaryBus;
+ u_int8_t subordinateBus;
+ u_int8_t secondaryLatency;
+ u_int8_t ioBase;
+ u_int8_t ioLimit;
+ u_int16_t secondaryStatus;
+ u_int16_t memoryBase;
+ u_int16_t memoryLimit;
+ u_int16_t prefetchBase;
+ u_int16_t prefetchLimit;
+ u_int32_t prefetchBaseUpper32;
+ u_int32_t prefetchLimitUpper32;
+ u_int16_t ioBaseUpper16;
+ u_int16_t ioLimitUpper16;
+ u_int8_t capabilitiesPtr;
+ u_int8_t reserved1[3];
+ u_int32_t romBaseAddress;
+ u_int8_t interruptLine;
+ u_int8_t interruptPin;
+ u_int16_t bridgeControl;
+ } type1;
+
+ /*
+ * PCI to CARDBUS Bridge
+ */
+
+ struct _MRSAS_DRV_PCI_HEADER_TYPE_2 {
+ u_int32_t socketRegistersBaseAddress;
+ u_int8_t capabilitiesPtr;
+ u_int8_t reserved;
+ u_int16_t secondaryStatus;
+ u_int8_t primaryBus;
+ u_int8_t secondaryBus;
+ u_int8_t subordinateBus;
+ u_int8_t secondaryLatency;
+ struct {
+ u_int32_t base;
+ u_int32_t limit;
+ } range [PCI_TYPE2_ADDRESSES - 1];
+ u_int8_t interruptLine;
+ u_int8_t interruptPin;
+ u_int16_t bridgeControl;
+ } type2;
+ } u;
+
+} MRSAS_DRV_PCI_COMMON_HEADER, *PMRSAS_DRV_PCI_COMMON_HEADER;
+
+#define MRSAS_DRV_PCI_COMMON_HEADER_SIZE sizeof(MRSAS_DRV_PCI_COMMON_HEADER) //64 bytes
+
+typedef struct _MRSAS_DRV_PCI_LINK_CAPABILITY {
+ union {
+ struct {
+ u_int32_t linkSpeed:4;
+ u_int32_t linkWidth:6;
+ u_int32_t aspmSupport:2;
+ u_int32_t losExitLatency:3;
+ u_int32_t l1ExitLatency:3;
+ u_int32_t rsvdp:6;
+ u_int32_t portNumber:8;
+ } bits;
+
+ u_int32_t asUlong;
+ } u;
+} MRSAS_DRV_PCI_LINK_CAPABILITY, *PMRSAS_DRV_PCI_LINK_CAPABILITY;
+
+#define MRSAS_DRV_PCI_LINK_CAPABILITY_SIZE sizeof(MRSAS_DRV_PCI_LINK_CAPABILITY)
+
+typedef struct _MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY {
+ union {
+ struct {
+ u_int16_t linkSpeed:4;
+ u_int16_t negotiatedLinkWidth:6;
+ u_int16_t linkTrainingError:1;
+ u_int16_t linkTraning:1;
+ u_int16_t slotClockConfig:1;
+ u_int16_t rsvdZ:3;
+ } bits;
+
+ u_int16_t asUshort;
+ } u;
+ u_int16_t reserved;
+} MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY, *PMRSAS_DRV_PCI_LINK_STATUS_CAPABILITY;
+
+#define MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY_SIZE sizeof(MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY)
+
+
+typedef struct _MRSAS_DRV_PCI_CAPABILITIES {
+ MRSAS_DRV_PCI_LINK_CAPABILITY linkCapability;
+ MRSAS_DRV_PCI_LINK_STATUS_CAPABILITY linkStatusCapability;
+} MRSAS_DRV_PCI_CAPABILITIES, *PMRSAS_DRV_PCI_CAPABILITIES;
+
+#define MRSAS_DRV_PCI_CAPABILITIES_SIZE sizeof(MRSAS_DRV_PCI_CAPABILITIES)
+
+/* PCI information */
+typedef struct _MRSAS_DRV_PCI_INFORMATION {
+ u_int32_t busNumber;
+ u_int8_t deviceNumber;
+ u_int8_t functionNumber;
+ u_int8_t interruptVector;
+ u_int8_t reserved1;
+ MRSAS_DRV_PCI_COMMON_HEADER pciHeaderInfo;
+ MRSAS_DRV_PCI_CAPABILITIES capability;
+ u_int32_t domainID;
+ u_int8_t reserved2[28];
+} MRSAS_DRV_PCI_INFORMATION, *PMRSAS_DRV_PCI_INFORMATION;
+
/*******************************************************************
* per-instance data
********************************************************************/
@@ -2476,6 +2668,7 @@ struct mrsas_softc {
int msix_vectors;
int msix_enable;
uint32_t msix_reg_offset[16];
+ uint8_t mask_interrupts;
struct mrsas_mpt_cmd **mpt_cmd_list;
struct mrsas_mfi_cmd **mfi_cmd_list;
TAILQ_HEAD(, mrsas_mpt_cmd) mrsas_mpt_cmd_list_head;
@@ -2519,6 +2712,7 @@ struct mrsas_softc {
bus_dmamap_t evt_detail_dmamap;
struct mrsas_evt_detail *evt_detail_mem;
bus_addr_t evt_detail_phys_addr;
+ struct mrsas_ctrl_info *ctrl_info;
bus_dma_tag_t ctlr_info_tag;
bus_dmamap_t ctlr_info_dmamap;
void *ctlr_info_mem;
@@ -2546,9 +2740,11 @@ struct mrsas_softc {
struct task ev_task;
u_int32_t CurLdCount;
u_int64_t reset_flags;
+ int lb_pending_cmds;
LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES_EXT];
LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
+ u_int8_t secure_jbod_support;
u_int8_t max256vdSupport;
u_int16_t fw_supported_vd_count;
u_int16_t fw_supported_pd_count;
diff --git a/sys/dev/mrsas/mrsas_cam.c b/sys/dev/mrsas/mrsas_cam.c
index 80ddc39e1635..08f90025ab57 100644
--- a/sys/dev/mrsas/mrsas_cam.c
+++ b/sys/dev/mrsas/mrsas_cam.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -57,17 +58,19 @@ __FBSDID("$FreeBSD$");
* Function prototypes
*/
int mrsas_cam_attach(struct mrsas_softc *sc);
-int mrsas_ldio_inq(struct cam_sim *sim, union ccb *ccb);
+int mrsas_find_io_type(struct cam_sim *sim, union ccb *ccb);
int mrsas_bus_scan(struct mrsas_softc *sc);
int mrsas_bus_scan_sim(struct mrsas_softc *sc, struct cam_sim *sim);
-int mrsas_map_request(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd);
int
+mrsas_map_request(struct mrsas_softc *sc,
+ struct mrsas_mpt_cmd *cmd, union ccb *ccb);
+int
mrsas_build_ldio(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
union ccb *ccb);
-int
+int
mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
union ccb *ccb, struct cam_sim *sim);
-int
+int
mrsas_setup_io(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
union ccb *ccb, u_int32_t device_id,
MRSAS_RAID_SCSI_IO_REQUEST * io_request);
@@ -77,10 +80,10 @@ void mrsas_cam_detach(struct mrsas_softc *sc);
void mrsas_release_mpt_cmd(struct mrsas_mpt_cmd *cmd);
void mrsas_unmap_request(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd);
void mrsas_cmd_done(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd);
-void
+void
mrsas_fire_cmd(struct mrsas_softc *sc, u_int32_t req_desc_lo,
u_int32_t req_desc_hi);
-void
+void
mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request,
u_int8_t cdb_len, struct IO_REQUEST_INFO *io_info, union ccb *ccb,
MR_DRV_RAID_MAP_ALL * local_map_ptr, u_int32_t ref_tag,
@@ -89,10 +92,10 @@ static void mrsas_freeze_simq(struct mrsas_mpt_cmd *cmd, struct cam_sim *sim);
static void mrsas_cam_poll(struct cam_sim *sim);
static void mrsas_action(struct cam_sim *sim, union ccb *ccb);
static void mrsas_scsiio_timeout(void *data);
-static void
+static void
mrsas_data_load_cb(void *arg, bus_dma_segment_t *segs,
int nseg, int error);
-static int32_t
+static int32_t
mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
union ccb *ccb);
struct mrsas_mpt_cmd *mrsas_get_mpt_cmd(struct mrsas_softc *sc);
@@ -112,9 +115,9 @@ MR_BuildRaidContext(struct mrsas_softc *sc,
extern u_int16_t
MR_LdSpanArrayGet(u_int32_t ld, u_int32_t span,
MR_DRV_RAID_MAP_ALL * map);
-extern u_int16_t
-mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo,
- struct IO_REQUEST_INFO *io_info);
+extern u_int16_t
+mrsas_get_updated_dev_handle(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info);
extern u_int8_t
megasas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm,
u_int64_t block, u_int32_t count);
@@ -315,7 +318,11 @@ mrsas_action(struct cam_sim *sim, union ccb *ccb)
ccb->cpi.version_num = 1;
ccb->cpi.hba_inquiry = 0;
ccb->cpi.target_sprt = 0;
+#if (__FreeBSD_version >= 902001)
+ ccb->cpi.hba_misc = PIM_UNMAPPED;
+#else
ccb->cpi.hba_misc = 0;
+#endif
ccb->cpi.hba_eng_cnt = 0;
ccb->cpi.max_lun = MRSAS_SCSI_MAX_LUNS;
ccb->cpi.unit_number = cam_sim_unit(sim);
@@ -323,7 +330,7 @@ mrsas_action(struct cam_sim *sim, union ccb *ccb)
ccb->cpi.initiator_id = MRSAS_SCSI_INITIATOR_ID;
ccb->cpi.base_transfer_speed = 150000;
strncpy(ccb->cpi.sim_vid, "FreeBSD", SIM_IDLEN);
- strncpy(ccb->cpi.hba_vid, "LSI", HBA_IDLEN);
+ strncpy(ccb->cpi.hba_vid, "AVAGO", HBA_IDLEN);
strncpy(ccb->cpi.dev_name, cam_sim_name(sim), DEV_IDLEN);
ccb->cpi.transport = XPORT_SPI;
ccb->cpi.transport_version = 2;
@@ -378,8 +385,13 @@ mrsas_scsiio_timeout(void *data)
* on OCR enable/disable property of Controller from ocr_thread
* context.
*/
+#if (__FreeBSD_version >= 1000510)
callout_reset_sbt(&cmd->cm_callout, SBT_1S * 600, 0,
- mrsas_scsiio_timeout, cmd, 0);
+ mrsas_scsiio_timeout, cmd, 0);
+#else
+ callout_reset(&cmd->cm_callout, (600000 * hz) / 1000,
+ mrsas_scsiio_timeout, cmd);
+#endif
sc->do_timedout_reset = 1;
if (sc->ocr_thread_active)
wakeup(&sc->ocr_chan);
@@ -425,8 +437,8 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
} else
cmd->flags = MRSAS_DIR_NONE; /* no data */
- /* For FreeBSD 10.0 and higher */
-#if (__FreeBSD_version >= 1000000)
+/* For FreeBSD 9.2 and higher */
+#if (__FreeBSD_version >= 902001)
/*
* XXX We don't yet support physical addresses here.
*/
@@ -455,6 +467,11 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
if (cmd->length)
cmd->data = csio->data_ptr;
break;
+ case CAM_DATA_BIO:
+ cmd->length = csio->dxfer_len;
+ if (cmd->length)
+ cmd->data = csio->data_ptr;
+ break;
default:
ccb->ccb_h.status = CAM_REQ_INVALID;
goto done;
@@ -499,7 +516,9 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
bcopy(csio->cdb_io.cdb_bytes, cmd->io_request->CDB.CDB32, csio->cdb_len);
mtx_lock(&sc->raidmap_lock);
- if (mrsas_ldio_inq(sim, ccb)) {
+ /* Check for IO type READ-WRITE targeted for Logical Volume */
+ if (mrsas_find_io_type(sim, ccb) == READ_WRITE_LDIO) {
+ /* Build READ-WRITE IO for Logical Volume */
if (mrsas_build_ldio(sc, cmd, ccb)) {
device_printf(sc->mrsas_dev, "Build LDIO failed.\n");
mtx_unlock(&sc->raidmap_lock);
@@ -530,8 +549,13 @@ mrsas_startio(struct mrsas_softc *sc, struct cam_sim *sim,
/*
* Start timer for IO timeout. Default timeout value is 90 second.
*/
- callout_reset_sbt(&cmd->cm_callout, SBT_1MS * sc->mrsas_io_timeout, 0,
+#if (__FreeBSD_version >= 1000510)
+ callout_reset_sbt(&cmd->cm_callout, SBT_1S * 600, 0,
mrsas_scsiio_timeout, cmd, 0);
+#else
+ callout_reset(&cmd->cm_callout, (600000 * hz) / 1000,
+ mrsas_scsiio_timeout, cmd);
+#endif
mrsas_atomic_inc(&sc->fw_outstanding);
if (mrsas_atomic_read(&sc->fw_outstanding) > sc->io_cmds_highwater)
@@ -546,20 +570,17 @@ done:
}
/*
- * mrsas_ldio_inq: Determines if IO is read/write or inquiry
+ * mrsas_find_io_type: Determines if IO is read/write or inquiry
* input: pointer to CAM Control Block
*
* This function determines if the IO is read/write or inquiry. It returns a 1
* if the IO is read/write and 0 if it is inquiry.
*/
-int
-mrsas_ldio_inq(struct cam_sim *sim, union ccb *ccb)
+int
+mrsas_find_io_type(struct cam_sim *sim, union ccb *ccb)
{
struct ccb_scsiio *csio = &(ccb->csio);
- if (cam_sim_bus(sim) == 1)
- return (0);
-
switch (csio->cdb_io.cdb_bytes[0]) {
case READ_10:
case WRITE_10:
@@ -569,9 +590,11 @@ mrsas_ldio_inq(struct cam_sim *sim, union ccb *ccb)
case WRITE_6:
case READ_16:
case WRITE_16:
- return 1;
+ return (cam_sim_bus(sim) ?
+ READ_WRITE_SYSPDIO : READ_WRITE_LDIO);
default:
- return 0;
+ return (cam_sim_bus(sim) ?
+ NON_READ_WRITE_SYSPDIO : NON_READ_WRITE_LDIO);
}
}
@@ -677,7 +700,7 @@ mrsas_build_ldio(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
io_request->DataLength = cmd->length;
- if (mrsas_map_request(sc, cmd) == SUCCESS) {
+ if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
if (cmd->sge_count > MRSAS_MAX_SGL) {
device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) exceeds"
"max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge);
@@ -824,9 +847,10 @@ mrsas_setup_io(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
if ((sc->load_balance_info[device_id].loadBalanceFlag) &&
(io_info.isRead)) {
io_info.devHandle =
- mrsas_get_updated_dev_handle(&sc->load_balance_info[device_id],
- &io_info);
+ mrsas_get_updated_dev_handle(sc,
+ &sc->load_balance_info[device_id], &io_info);
cmd->load_balance = MRSAS_LOAD_BALANCE_FLAG;
+ cmd->pd_r1_lb = io_info.pd_after_lb;
} else
cmd->load_balance = 0;
cmd->request_desc->SCSIIO.DevHandle = io_info.devHandle;
@@ -876,30 +900,49 @@ mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
device_id = ccb_h->target_id;
map_ptr = sc->ld_drv_map[(sc->map_id & 1)];
- /* Check if this is for system PD */
+ /*
+ * Check if this is RW for system PD or
+ * it's a NON RW for sys PD and there is NO secure jbod FW support
+ */
if (cam_sim_bus(sim) == 1 &&
sc->pd_list[device_id].driveState == MR_PD_STATE_SYSTEM) {
- io_request->Function = 0;
- io_request->DevHandle = map_ptr->raidMap.devHndlInfo[device_id].
- curDevHdl;
- io_request->RaidContext.timeoutValue = map_ptr->raidMap.fpPdIoTimeoutSec;
- io_request->RaidContext.regLockFlags = 0;
- io_request->RaidContext.regLockRowLBA = 0;
- io_request->RaidContext.regLockLength = 0;
- io_request->RaidContext.RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
- << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
- if ((sc->device_id == MRSAS_INVADER) || (sc->device_id == MRSAS_FURY))
- io_request->IoFlags |= MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
- cmd->request_desc->SCSIIO.RequestFlags =
- (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
- MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
- cmd->request_desc->SCSIIO.DevHandle =
+ io_request->DevHandle =
map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
+ io_request->RaidContext.RAIDFlags =
+ MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD <<
+ MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
+ cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
cmd->request_desc->SCSIIO.MSIxIndex =
sc->msix_vectors ? smp_processor_id() % sc->msix_vectors : 0;
+ if (sc->secure_jbod_support && (mrsas_find_io_type(sim, ccb) == NON_READ_WRITE_SYSPDIO)) {
+ /* system pd firmware path */
+ io_request->Function = MRSAS_MPI2_FUNCTION_LD_IO_REQUEST;
+ cmd->request_desc->SCSIIO.RequestFlags =
+ (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+ } else {
+ /* system pd fast path */
+ io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
+ io_request->RaidContext.timeoutValue = map_ptr->raidMap.fpPdIoTimeoutSec;
+ io_request->RaidContext.regLockFlags = 0;
+ io_request->RaidContext.regLockRowLBA = 0;
+ io_request->RaidContext.regLockLength = 0;
+
+ cmd->request_desc->SCSIIO.RequestFlags =
+ (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
+ MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+
+ /*
+ * NOTE - For system pd RW cmds only IoFlags will be FAST_PATH
+ * Because the NON RW cmds will now go via FW Queue
+ * and not the Exception queue
+ */
+ if ((sc->device_id == MRSAS_INVADER) || (sc->device_id == MRSAS_FURY))
+ io_request->IoFlags |= MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
+ }
} else {
+ /* FW path for SysPD or LD Non-RW (SCSI management commands) */
io_request->Function = MRSAS_MPI2_FUNCTION_LD_IO_REQUEST;
io_request->DevHandle = device_id;
cmd->request_desc->SCSIIO.RequestFlags =
@@ -911,7 +954,7 @@ mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
io_request->LUN[1] = ccb_h->target_lun & 0xF;
io_request->DataLength = cmd->length;
- if (mrsas_map_request(sc, cmd) == SUCCESS) {
+ if (mrsas_map_request(sc, cmd, ccb) == SUCCESS) {
if (cmd->sge_count > sc->max_num_sge) {
device_printf(sc->mrsas_dev, "Error: sge_count (0x%x) exceeds"
"max (0x%x) allowed\n", cmd->sge_count, sc->max_num_sge);
@@ -934,20 +977,25 @@ mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
* is built in the callback. If the bus dmamap load is not successful,
* cmd->error_code will contain the error code and a 1 is returned.
*/
-int
-mrsas_map_request(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd)
+int
+mrsas_map_request(struct mrsas_softc *sc,
+ struct mrsas_mpt_cmd *cmd, union ccb *ccb)
{
u_int32_t retcode = 0;
struct cam_sim *sim;
- int flag = BUS_DMA_NOWAIT;
sim = xpt_path_sim(cmd->ccb_ptr->ccb_h.path);
if (cmd->data != NULL) {
- mtx_lock(&sc->io_lock);
/* Map data buffer into bus space */
+ mtx_lock(&sc->io_lock);
+#if (__FreeBSD_version >= 902001)
+ retcode = bus_dmamap_load_ccb(sc->data_tag, cmd->data_dmamap, ccb,
+ mrsas_data_load_cb, cmd, 0);
+#else
retcode = bus_dmamap_load(sc->data_tag, cmd->data_dmamap, cmd->data,
- cmd->length, mrsas_data_load_cb, cmd, flag);
+ cmd->length, mrsas_data_load_cb, cmd, BUS_DMA_NOWAIT);
+#endif
mtx_unlock(&sc->io_lock);
if (retcode)
device_printf(sc->mrsas_dev, "bus_dmamap_load(): retcode = %d\n", retcode);
diff --git a/sys/dev/mrsas/mrsas_fp.c b/sys/dev/mrsas/mrsas_fp.c
index cd0d57f30774..7ae5662f15df 100644
--- a/sys/dev/mrsas/mrsas_fp.c
+++ b/sys/dev/mrsas/mrsas_fp.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
@@ -55,13 +56,13 @@ __FBSDID("$FreeBSD$");
*/
u_int8_t MR_ValidateMapInfo(struct mrsas_softc *sc);
u_int8_t
-mrsas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm,
- u_int64_t block, u_int32_t count);
-u_int8_t
+mrsas_get_best_arm_pd(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info);
+u_int8_t
MR_BuildRaidContext(struct mrsas_softc *sc,
struct IO_REQUEST_INFO *io_info,
RAID_CONTEXT * pRAID_Context, MR_DRV_RAID_MAP_ALL * map);
-u_int8_t
+u_int8_t
MR_GetPhyParams(struct mrsas_softc *sc, u_int32_t ld,
u_int64_t stripRow, u_int16_t stripRef, struct IO_REQUEST_INFO *io_info,
RAID_CONTEXT * pRAID_Context,
@@ -70,32 +71,32 @@ u_int16_t MR_TargetIdToLdGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map);
u_int32_t MR_LdBlockSizeGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map);
u_int16_t MR_GetLDTgtId(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map);
u_int16_t
-mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo,
- struct IO_REQUEST_INFO *io_info);
+mrsas_get_updated_dev_handle(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info);
u_int32_t mega_mod64(u_int64_t dividend, u_int32_t divisor);
-u_int32_t
+u_int32_t
MR_GetSpanBlock(u_int32_t ld, u_int64_t row, u_int64_t *span_blk,
MR_DRV_RAID_MAP_ALL * map, int *div_error);
u_int64_t mega_div64_32(u_int64_t dividend, u_int32_t divisor);
void
-mrsas_update_load_balance_params(MR_DRV_RAID_MAP_ALL * map,
- PLD_LOAD_BALANCE_INFO lbInfo);
-void
+mrsas_update_load_balance_params(struct mrsas_softc *sc,
+ MR_DRV_RAID_MAP_ALL * map, PLD_LOAD_BALANCE_INFO lbInfo);
+void
mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request,
u_int8_t cdb_len, struct IO_REQUEST_INFO *io_info, union ccb *ccb,
MR_DRV_RAID_MAP_ALL * local_map_ptr, u_int32_t ref_tag,
u_int32_t ld_block_size);
-static u_int16_t
+static u_int16_t
MR_LdSpanArrayGet(u_int32_t ld, u_int32_t span,
MR_DRV_RAID_MAP_ALL * map);
static u_int16_t MR_PdDevHandleGet(u_int32_t pd, MR_DRV_RAID_MAP_ALL * map);
-static u_int16_t
+static u_int16_t
MR_ArPdGet(u_int32_t ar, u_int32_t arm,
MR_DRV_RAID_MAP_ALL * map);
static MR_LD_SPAN *
MR_LdSpanPtrGet(u_int32_t ld, u_int32_t span,
MR_DRV_RAID_MAP_ALL * map);
-static u_int8_t
+static u_int8_t
MR_LdDataArmGet(u_int32_t ld, u_int32_t armIdx,
MR_DRV_RAID_MAP_ALL * map);
static MR_SPAN_BLOCK_INFO *
@@ -146,6 +147,8 @@ typedef u_int32_t REGION_LEN;
#define FALSE 0
#define TRUE 1
+#define LB_PENDING_CMDS_DEFAULT 4
+
/*
* Related Macros
@@ -376,10 +379,9 @@ MR_ValidateMapInfo(struct mrsas_softc *sc)
return 1;
}
if (sc->UnevenSpanSupport) {
- printf("Updating span set\n\n");
mr_update_span_set(drv_map, ldSpanInfo);
}
- mrsas_update_load_balance_params(drv_map, sc->load_balance_info);
+ mrsas_update_load_balance_params(sc, drv_map, sc->load_balance_info);
return 0;
}
@@ -566,12 +568,12 @@ get_row_from_strip(struct mrsas_softc *sc,
else
break;
}
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : Strip 0x%llx, span_set_Strip 0x%llx, span_set_Row 0x%llx "
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug : Strip 0x%llx, span_set_Strip 0x%llx, span_set_Row 0x%llx "
"data width 0x%llx span offset 0x%llx\n", (unsigned long long)strip,
(unsigned long long)span_set_Strip,
(unsigned long long)span_set_Row,
(unsigned long long)span_set->span_row_data_width, (unsigned long long)span_offset);
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : For strip 0x%llx row is 0x%llx\n", (unsigned long long)strip,
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug : For strip 0x%llx row is 0x%llx\n", (unsigned long long)strip,
(unsigned long long)span_set->data_row_start +
(unsigned long long)span_set_Row + (span_offset - 1));
return (span_set->data_row_start + span_set_Row + (span_offset - 1));
@@ -631,7 +633,7 @@ get_strip_from_row(struct mrsas_softc *sc,
}
}
}
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug - get_strip_from_row: returns invalid "
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug - get_strip_from_row: returns invalid "
"strip for ld=%x, row=%lx\n", ld, (long unsigned int)row);
return -1;
}
@@ -679,13 +681,13 @@ get_arm_from_strip(struct mrsas_softc *sc,
else
break;
}
- mrsas_dprint(sc, MRSAS_PRL11, "LSI PRL11: get_arm_from_strip: "
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO PRL11: get_arm_from_strip: "
"for ld=0x%x strip=0x%lx arm is 0x%x\n", ld,
(long unsigned int)strip, (strip_offset - span_offset));
return (strip_offset - span_offset);
}
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: - get_arm_from_strip: returns invalid arm"
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug: - get_arm_from_strip: returns invalid arm"
" for ld=%x strip=%lx\n", ld, (long unsigned int)strip);
return -1;
@@ -723,9 +725,11 @@ get_arm(struct mrsas_softc *sc, u_int32_t ld, u_int8_t span, u_int64_t stripe,
* This routine calculates the arm, span and block for the specified stripe and
* reference in stripe using spanset
*
- * Inputs : Logical drive number
- * stripRow: Stripe number
- * stripRef: Reference in stripe
+ * Inputs :
+ * sc - HBA instance
+ * ld - Logical drive number
+ * stripRow: Stripe number
+ * stripRef: Reference in stripe
*
* Outputs : span - Span number block - Absolute Block
* number in the physical disk
@@ -785,6 +789,7 @@ mr_spanset_get_phy_params(struct mrsas_softc *sc, u_int32_t ld, u_int64_t stripR
*pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+ io_info->span_arm = pRAID_Context->spanArm;
return retval;
}
@@ -831,7 +836,7 @@ MR_BuildRaidContext(struct mrsas_softc *sc, struct IO_REQUEST_INFO *io_info,
else if (sc->UnevenSpanSupport) {
io_info->IoforUnevenSpan = 1;
} else {
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: raid->rowDataSize is 0, but has SPAN[0] rowDataSize = 0x%0x,"
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug: raid->rowDataSize is 0, but has SPAN[0] rowDataSize = 0x%0x,"
" but there is _NO_ UnevenSpanSupport\n",
MR_LdSpanPtrGet(ld, 0, map)->spanRowDataSize);
return FALSE;
@@ -858,13 +863,13 @@ MR_BuildRaidContext(struct mrsas_softc *sc, struct IO_REQUEST_INFO *io_info,
startlba_span = (u_int8_t)mr_spanset_get_span_block(sc, ld, start_row,
pdBlock, map, &error_code);
if (error_code == 1) {
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: return from %s %d. Send IO w/o region lock.\n",
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug: return from %s %d. Send IO w/o region lock.\n",
__func__, __LINE__);
return FALSE;
}
}
if (startlba_span == SPAN_INVALID) {
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: return from %s %d for row 0x%llx,"
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug: return from %s %d for row 0x%llx,"
"start strip %llx endSrip %llx\n", __func__,
__LINE__, (unsigned long long)start_row,
(unsigned long long)start_strip,
@@ -873,12 +878,12 @@ MR_BuildRaidContext(struct mrsas_softc *sc, struct IO_REQUEST_INFO *io_info,
}
io_info->start_span = startlba_span;
io_info->start_row = start_row;
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: Check Span number from %s %d for row 0x%llx, "
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug: Check Span number from %s %d for row 0x%llx, "
" start strip 0x%llx endSrip 0x%llx span 0x%x\n",
__func__, __LINE__, (unsigned long long)start_row,
(unsigned long long)start_strip,
(unsigned long long)endStrip, startlba_span);
- mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : 1. start_row 0x%llx endRow 0x%llx Start span 0x%x\n",
+ mrsas_dprint(sc, MRSAS_PRL11, "AVAGO Debug : 1. start_row 0x%llx endRow 0x%llx Start span 0x%x\n",
(unsigned long long)start_row, (unsigned long long)endRow, startlba_span);
} else {
start_row = mega_div64_32(start_strip, raid->rowDataSize);
@@ -1042,7 +1047,7 @@ mr_update_span_set(MR_DRV_RAID_MAP_ALL * map, PLD_SPAN_INFO ldSpanInfo)
span_row_width +=
MR_LdSpanPtrGet(ld, count, map)->spanRowDataSize;
#if SPAN_DEBUG
- printf("LSI Debug span %x rowDataSize %x\n", count,
+ printf("AVAGO Debug span %x rowDataSize %x\n", count,
MR_LdSpanPtrGet(ld, count, map)->spanRowDataSize);
#endif
}
@@ -1097,46 +1102,38 @@ mr_update_span_set(MR_DRV_RAID_MAP_ALL * map, PLD_SPAN_INFO ldSpanInfo)
/*
* mrsas_update_load_balance_params: Update load balance parmas
- * Inputs: map pointer
- * Load balance info
+ * Inputs:
+ * sc - driver softc instance
+ * drv_map - driver RAID map
+ * lbInfo - Load balance info
*
* This function updates the load balance parameters for the LD config of a two
* drive optimal RAID-1.
*/
-void
-mrsas_update_load_balance_params(MR_DRV_RAID_MAP_ALL * map,
- PLD_LOAD_BALANCE_INFO lbInfo)
+void
+mrsas_update_load_balance_params(struct mrsas_softc *sc,
+ MR_DRV_RAID_MAP_ALL * drv_map, PLD_LOAD_BALANCE_INFO lbInfo)
{
int ldCount;
u_int16_t ld;
- u_int32_t pd, arRef;
MR_LD_RAID *raid;
- for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
- ld = MR_TargetIdToLdGet(ldCount, map);
- if (ld >= MAX_LOGICAL_DRIVES) {
+ if (sc->lb_pending_cmds > 128 || sc->lb_pending_cmds < 1)
+ sc->lb_pending_cmds = LB_PENDING_CMDS_DEFAULT;
+
+ for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES_EXT; ldCount++) {
+ ld = MR_TargetIdToLdGet(ldCount, drv_map);
+ if (ld >= MAX_LOGICAL_DRIVES_EXT) {
lbInfo[ldCount].loadBalanceFlag = 0;
continue;
}
- raid = MR_LdRaidGet(ld, map);
-
- /* Two drive Optimal RAID 1 */
- if ((raid->level == 1) && (raid->rowSize == 2) &&
- (raid->spanDepth == 1)
- && raid->ldState == MR_LD_STATE_OPTIMAL) {
- lbInfo[ldCount].loadBalanceFlag = 1;
-
- /* Get the array on which this span is present */
- arRef = MR_LdSpanArrayGet(ld, 0, map);
-
- /* Get the PD */
- pd = MR_ArPdGet(arRef, 0, map);
- /* Get dev handle from PD */
- lbInfo[ldCount].raid1DevHandle[0] = MR_PdDevHandleGet(pd, map);
- pd = MR_ArPdGet(arRef, 1, map);
- lbInfo[ldCount].raid1DevHandle[1] = MR_PdDevHandleGet(pd, map);
- } else
+ raid = MR_LdRaidGet(ld, drv_map);
+ if ((raid->level != 1) ||
+ (raid->ldState != MR_LD_STATE_OPTIMAL)) {
lbInfo[ldCount].loadBalanceFlag = 0;
+ continue;
+ }
+ lbInfo[ldCount].loadBalanceFlag = 1;
}
}
@@ -1152,7 +1149,7 @@ mrsas_update_load_balance_params(MR_DRV_RAID_MAP_ALL * map,
*
* Used to set the PD logical block address in CDB for FP IOs.
*/
-void
+void
mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request, u_int8_t cdb_len,
struct IO_REQUEST_INFO *io_info, union ccb *ccb,
MR_DRV_RAID_MAP_ALL * local_map_ptr, u_int32_t ref_tag,
@@ -1299,6 +1296,7 @@ mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request, u_int8_t cdb_len,
}
/* Fall through normal case, just load LBA here */
u_int8_t val = cdb[1] & 0xE0;
+
switch (cdb_len) {
case 6:
cdb[3] = (u_int8_t)(start_blk & 0xff);
@@ -1332,57 +1330,94 @@ mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request, u_int8_t cdb_len,
}
/*
- * mrsas_get_best_arm: Determine the best spindle arm
- * Inputs: Load balance info
+ * mrsas_get_best_arm_pd: Determine the best spindle arm
+ * Inputs:
+ * sc - HBA instance
+ * lbInfo - Load balance info
+ * io_info - IO request info
*
* This function determines and returns the best arm by looking at the
* parameters of the last PD access.
*/
-u_int8_t
-mrsas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm,
- u_int64_t block, u_int32_t count)
+u_int8_t
+mrsas_get_best_arm_pd(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info)
{
- u_int16_t pend0, pend1;
+ MR_LD_RAID *raid;
+ MR_DRV_RAID_MAP_ALL *drv_map;
+ u_int16_t pend0, pend1, ld;
u_int64_t diff0, diff1;
- u_int8_t bestArm;
+ u_int8_t bestArm, pd0, pd1, span, arm;
+ u_int32_t arRef, span_row_size;
+
+ u_int64_t block = io_info->ldStartBlock;
+ u_int32_t count = io_info->numBlocks;
+
+ span = ((io_info->span_arm & RAID_CTX_SPANARM_SPAN_MASK)
+ >> RAID_CTX_SPANARM_SPAN_SHIFT);
+ arm = (io_info->span_arm & RAID_CTX_SPANARM_ARM_MASK);
+
+ drv_map = sc->ld_drv_map[(sc->map_id & 1)];
+ ld = MR_TargetIdToLdGet(io_info->ldTgtId, drv_map);
+ raid = MR_LdRaidGet(ld, drv_map);
+ span_row_size = sc->UnevenSpanSupport ?
+ SPAN_ROW_SIZE(drv_map, ld, span) : raid->rowSize;
+
+ arRef = MR_LdSpanArrayGet(ld, span, drv_map);
+ pd0 = MR_ArPdGet(arRef, arm, drv_map);
+ pd1 = MR_ArPdGet(arRef, (arm + 1) >= span_row_size ?
+ (arm + 1 - span_row_size) : arm + 1, drv_map);
/* get the pending cmds for the data and mirror arms */
- pend0 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[0]);
- pend1 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[1]);
+ pend0 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[pd0]);
+ pend1 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[pd1]);
/* Determine the disk whose head is nearer to the req. block */
- diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[0]);
- diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[1]);
- bestArm = (diff0 <= diff1 ? 0 : 1);
+ diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]);
+ diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]);
+ bestArm = (diff0 <= diff1 ? arm : arm ^ 1);
- if ((bestArm == arm && pend0 > pend1 + 16) || (bestArm != arm && pend1 > pend0 + 16))
+ if ((bestArm == arm && pend0 > pend1 + sc->lb_pending_cmds) ||
+ (bestArm != arm && pend1 > pend0 + sc->lb_pending_cmds))
bestArm ^= 1;
/* Update the last accessed block on the correct pd */
- lbInfo->last_accessed_block[bestArm] = block + count - 1;
+ lbInfo->last_accessed_block[bestArm == arm ? pd0 : pd1] = block + count - 1;
+ io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | bestArm;
+ io_info->pd_after_lb = (bestArm == arm) ? pd0 : pd1;
+#if SPAN_DEBUG
+ if (arm != bestArm)
+ printf("AVAGO Debug R1 Load balance occur - span 0x%x arm 0x%x bestArm 0x%x "
+ "io_info->span_arm 0x%x\n",
+ span, arm, bestArm, io_info->span_arm);
+#endif
- return bestArm;
+ return io_info->pd_after_lb;
}
/*
* mrsas_get_updated_dev_handle: Get the update dev handle
- * Inputs: Load balance info io_info pointer
+ * Inputs:
+ * sc - Adapter instance soft state
+ * lbInfo - Load balance info
+ * io_info - io_info pointer
*
* This function determines and returns the updated dev handle.
*/
-u_int16_t
-mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo,
- struct IO_REQUEST_INFO *io_info)
+u_int16_t
+mrsas_get_updated_dev_handle(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info)
{
- u_int8_t arm, old_arm;
+ u_int8_t arm_pd;
u_int16_t devHandle;
+ MR_DRV_RAID_MAP_ALL *drv_map;
- old_arm = lbInfo->raid1DevHandle[0] == io_info->devHandle ? 0 : 1;
+ drv_map = sc->ld_drv_map[(sc->map_id & 1)];
/* get best new arm */
- arm = mrsas_get_best_arm(lbInfo, old_arm, io_info->ldStartBlock, io_info->numBlocks);
- devHandle = lbInfo->raid1DevHandle[arm];
- mrsas_atomic_inc(&lbInfo->scsi_pending_cmds[arm]);
+ arm_pd = mrsas_get_best_arm_pd(sc, lbInfo, io_info);
+ devHandle = MR_PdDevHandleGet(arm_pd, drv_map);
+ mrsas_atomic_inc(&lbInfo->scsi_pending_cmds[arm_pd]);
return devHandle;
}
@@ -1471,6 +1506,7 @@ MR_GetPhyParams(struct mrsas_softc *sc, u_int32_t ld,
*pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+ io_info->span_arm = pRAID_Context->spanArm;
return retval;
}
diff --git a/sys/dev/mrsas/mrsas_ioctl.c b/sys/dev/mrsas/mrsas_ioctl.c
index 8e2aead8e8a9..3c4dbf917cad 100644
--- a/sys/dev/mrsas/mrsas_ioctl.c
+++ b/sys/dev/mrsas/mrsas_ioctl.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
@@ -238,7 +239,7 @@ mrsas_passthru(struct mrsas_softc *sc, void *arg, u_long ioctlCmd)
}
sense_ptr =
(unsigned long *)((unsigned long)cmd->frame + user_ioc->sense_off);
- sense_ptr = ioctl_sense_mem;
+ *sense_ptr = ioctl_sense_phys_addr;
}
/*
* Set the sync_cmd flag so that the ISR knows not to complete this
@@ -296,13 +297,14 @@ out:
/*
* Release sense buffer
*/
- if (ioctl_sense_phys_addr)
- bus_dmamap_unload(ioctl_sense_tag, ioctl_sense_dmamap);
- if (ioctl_sense_mem != NULL)
- bus_dmamem_free(ioctl_sense_tag, ioctl_sense_mem, ioctl_sense_dmamap);
- if (ioctl_sense_tag != NULL)
- bus_dma_tag_destroy(ioctl_sense_tag);
-
+ if (user_ioc->sense_len) {
+ if (ioctl_sense_phys_addr)
+ bus_dmamap_unload(ioctl_sense_tag, ioctl_sense_dmamap);
+ if (ioctl_sense_mem != NULL)
+ bus_dmamem_free(ioctl_sense_tag, ioctl_sense_mem, ioctl_sense_dmamap);
+ if (ioctl_sense_tag != NULL)
+ bus_dma_tag_destroy(ioctl_sense_tag);
+ }
/*
* Release data buffers
*/
diff --git a/sys/dev/mrsas/mrsas_ioctl.h b/sys/dev/mrsas/mrsas_ioctl.h
index bf05a7d30532..c43fc6d4bf33 100644
--- a/sys/dev/mrsas/mrsas_ioctl.h
+++ b/sys/dev/mrsas/mrsas_ioctl.h
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
- * Support: freebsdraid@lsi.com
+ * Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
@@ -64,6 +65,7 @@ __FBSDID("$FreeBSD$");
* into a somewhat unique, 32-bit value.
*/
+#define MRSAS_IOC_GET_PCI_INFO _IOR('M', 7, MRSAS_DRV_PCI_INFORMATION)
#define MRSAS_IOC_FIRMWARE_PASS_THROUGH64 _IOWR('M', 1, struct mrsas_iocpacket)
#ifdef COMPAT_FREEBSD32
#define MRSAS_IOC_FIRMWARE_PASS_THROUGH32 _IOWR('M', 1, struct mrsas_iocpacket32)
diff --git a/sys/dev/mrsas/mrsas_linux.c b/sys/dev/mrsas/mrsas_linux.c
index 8a3db0bbd8d9..15f38c53e900 100644
--- a/sys/dev/mrsas/mrsas_linux.c
+++ b/sys/dev/mrsas/mrsas_linux.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Kashyap Desai,
* Copyright (c) 2014, LSI Corp. All rights reserved. Author: Kashyap Desai,
- * Sibananda Sahu Support: freebsdraid@lsi.com
+ * Sibananda Sahu Support: freebsdraid@avagotech.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,7 +32,7 @@
* those of the authors and should not be interpreted as representing
* official policies,either expressed or implied, of the FreeBSD Project.
*
- * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621
+ * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
* Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
*
*/
diff --git a/sys/dev/nand/nfc_rb.c b/sys/dev/nand/nfc_rb.c
new file mode 100644
index 000000000000..64f888a2a157
--- /dev/null
+++ b/sys/dev/nand/nfc_rb.c
@@ -0,0 +1,275 @@
+/*-
+ * Copyright (C) 2015 Justin Hibbits
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* RouterBoard 600/800 NAND controller driver. */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/time.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/nand/nand.h>
+#include <dev/nand/nandbus.h>
+#include "nfc_if.h"
+#include "gpio_if.h"
+
+#define RB_NAND_DATA (0x00)
+
+struct rb_nand_softc {
+ struct nand_softc nand_dev;
+ struct resource *sc_mem;
+ int rid;
+ device_t sc_gpio;
+ uint32_t sc_rdy_pin;
+ uint32_t sc_nce_pin;
+ uint32_t sc_cle_pin;
+ uint32_t sc_ale_pin;
+};
+
+static int rb_nand_attach(device_t);
+static int rb_nand_probe(device_t);
+static int rb_nand_send_command(device_t, uint8_t);
+static int rb_nand_send_address(device_t, uint8_t);
+static uint8_t rb_nand_read_byte(device_t);
+static void rb_nand_read_buf(device_t, void *, uint32_t);
+static void rb_nand_write_buf(device_t, void *, uint32_t);
+static int rb_nand_select_cs(device_t, uint8_t);
+static int rb_nand_read_rnb(device_t);
+
+static device_method_t rb_nand_methods[] = {
+ DEVMETHOD(device_probe, rb_nand_probe),
+ DEVMETHOD(device_attach, rb_nand_attach),
+
+ DEVMETHOD(nfc_send_command, rb_nand_send_command),
+ DEVMETHOD(nfc_send_address, rb_nand_send_address),
+ DEVMETHOD(nfc_read_byte, rb_nand_read_byte),
+ DEVMETHOD(nfc_read_buf, rb_nand_read_buf),
+ DEVMETHOD(nfc_write_buf, rb_nand_write_buf),
+ DEVMETHOD(nfc_select_cs, rb_nand_select_cs),
+ DEVMETHOD(nfc_read_rnb, rb_nand_read_rnb),
+
+ { 0, 0 },
+};
+
+static driver_t rb_nand_driver = {
+ "nand",
+ rb_nand_methods,
+ sizeof(struct rb_nand_softc),
+};
+
+static devclass_t rb_nand_devclass;
+DRIVER_MODULE(rb_nand, ofwbus, rb_nand_driver, rb_nand_devclass, 0, 0);
+
+#if 0
+static const struct nand_ecc_data rb_ecc = {
+ .eccsize = 6,
+ .eccmode = NAND_ECC_SOFT,
+ .eccbytes = 6,
+ .eccpositions = { 8, 9, 10, 13, 14, 15 },
+};
+#endif
+
+static int
+rb_nand_probe(device_t dev)
+{
+ const char *device_type;
+
+ device_type = ofw_bus_get_type(dev);
+
+ if (!device_type || strcmp(device_type, "rb,nand"))
+ return (ENXIO);
+
+ device_set_desc(dev, "RouterBoard 333/600/800 NAND controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+rb_nand_attach(device_t dev)
+{
+ struct rb_nand_softc *sc;
+ phandle_t node;
+ uint32_t ale[2],cle[2],nce[2],rdy[2];
+ int err;
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+
+ if (OF_getprop(node, "ale", ale, sizeof(ale)) <= 0) {
+ return (ENXIO);
+ }
+ if (OF_getprop(node, "cle", cle, sizeof(cle)) <= 0) {
+ return (ENXIO);
+ }
+ if (OF_getprop(node, "nce", nce, sizeof(nce)) <= 0) {
+ return (ENXIO);
+ }
+ if (OF_getprop(node, "rdy", rdy, sizeof(rdy)) <= 0) {
+ return (ENXIO);
+ }
+
+ if (ale[0] != cle[0] || ale[0] != nce[0] || ale[0] != rdy[0]) {
+ device_printf(dev, "GPIO handles for signals must match.\n");
+ return (ENXIO);
+ }
+ sc->sc_ale_pin = ale[1];
+ sc->sc_cle_pin = cle[1];
+ sc->sc_nce_pin = nce[1];
+ sc->sc_rdy_pin = rdy[1];
+
+ sc->sc_gpio = OF_device_from_xref(ale[0]);
+ if (sc->sc_gpio == NULL) {
+ device_printf(dev, "No GPIO resource found!\n");
+ return (ENXIO);
+ }
+
+ sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
+ RF_ACTIVE);
+ if (sc->sc_mem == NULL) {
+ device_printf(dev, "could not allocate resources!\n");
+ return (ENXIO);
+ }
+
+ nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL);
+
+ err = nandbus_create(dev);
+
+ return (err);
+}
+
+static int
+rb_nand_send_command(device_t dev, uint8_t command)
+{
+ struct rb_nand_softc *sc;
+
+ nand_debug(NDBG_DRV,"rb_nand: send command %x", command);
+
+ sc = device_get_softc(dev);
+ GPIO_PIN_SET(sc->sc_gpio, sc->sc_cle_pin, 1);
+ GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 0);
+ GPIO_PIN_SET(sc->sc_gpio, sc->sc_nce_pin, 0);
+ bus_write_1(sc->sc_mem, RB_NAND_DATA, command);
+ GPIO_PIN_SET(sc->sc_gpio, sc->sc_cle_pin, 0);
+ return (0);
+}
+
+static int
+rb_nand_send_address(device_t dev, uint8_t addr)
+{
+ struct rb_nand_softc *sc;
+
+ nand_debug(NDBG_DRV,"rb_nand: send address %x", addr);
+
+ sc = device_get_softc(dev);
+ GPIO_PIN_SET(sc->sc_gpio, sc->sc_cle_pin, 0);
+ GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 1);
+ GPIO_PIN_SET(sc->sc_gpio, sc->sc_nce_pin, 0);
+ bus_write_1(sc->sc_mem, RB_NAND_DATA, addr);
+ GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 0);
+ return (0);
+}
+
+static uint8_t
+rb_nand_read_byte(device_t dev)
+{
+ struct rb_nand_softc *sc;
+ uint8_t data;
+
+ sc = device_get_softc(dev);
+ data = bus_read_1(sc->sc_mem, RB_NAND_DATA);
+
+ nand_debug(NDBG_DRV,"rb_nand: read %x", data);
+
+ return (data);
+}
+
+static void
+rb_nand_read_buf(device_t dev, void* buf, uint32_t len)
+{
+ struct rb_nand_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ bus_read_region_1(sc->sc_mem, RB_NAND_DATA, buf, len);
+}
+
+static void
+rb_nand_write_buf(device_t dev, void* buf, uint32_t len)
+{
+ struct rb_nand_softc *sc;
+ int i;
+ uint8_t *b = (uint8_t*)buf;
+
+ sc = device_get_softc(dev);
+
+ for (i = 0; i < len; i++) {
+#ifdef NAND_DEBUG
+ if (!(i % 16))
+ printf("%s", i == 0 ? "rb_nand:\n" : "\n");
+ printf(" %x", b[i]);
+ if (i == len - 1)
+ printf("\n");
+#endif
+ bus_write_1(sc->sc_mem, RB_NAND_DATA, b[i]);
+ }
+}
+
+static int
+rb_nand_select_cs(device_t dev, uint8_t cs)
+{
+
+ if (cs > 0)
+ return (ENODEV);
+
+ return (0);
+}
+
+static int
+rb_nand_read_rnb(device_t dev)
+{
+ struct rb_nand_softc *sc;
+ uint32_t rdy_bit;
+
+ sc = device_get_softc(dev);
+ GPIO_PIN_GET(sc->sc_gpio, sc->sc_rdy_pin, &rdy_bit);
+
+ return (rdy_bit); /* ready */
+}
diff --git a/sys/dev/ofw/ofwbus.c b/sys/dev/ofw/ofwbus.c
index 6a81b6e1a7d5..670abff7e6f8 100644
--- a/sys/dev/ofw/ofwbus.c
+++ b/sys/dev/ofw/ofwbus.c
@@ -69,7 +69,9 @@ struct ofwbus_softc {
struct rman sc_mem_rman;
};
+#ifndef __aarch64__
static device_identify_t ofwbus_identify;
+#endif
static device_probe_t ofwbus_probe;
static device_attach_t ofwbus_attach;
static bus_alloc_resource_t ofwbus_alloc_resource;
@@ -78,7 +80,9 @@ static bus_release_resource_t ofwbus_release_resource;
static device_method_t ofwbus_methods[] = {
/* Device interface */
+#ifndef __aarch64__
DEVMETHOD(device_identify, ofwbus_identify),
+#endif
DEVMETHOD(device_probe, ofwbus_probe),
DEVMETHOD(device_attach, ofwbus_attach),
@@ -97,6 +101,7 @@ EARLY_DRIVER_MODULE(ofwbus, nexus, ofwbus_driver, ofwbus_devclass, 0, 0,
BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
MODULE_VERSION(ofwbus, 1);
+#ifndef __aarch64__
static void
ofwbus_identify(driver_t *driver, device_t parent)
{
@@ -108,11 +113,17 @@ ofwbus_identify(driver_t *driver, device_t parent)
if (device_find_child(parent, "ofwbus", -1) == NULL)
BUS_ADD_CHILD(parent, 0, "ofwbus", -1);
}
+#endif
static int
ofwbus_probe(device_t dev)
{
+#ifdef __aarch64__
+ if (OF_peer(0) == 0)
+ return (ENXIO);
+#endif
+
device_set_desc(dev, "Open Firmware Device Tree");
return (BUS_PROBE_NOWILDCARD);
}
diff --git a/sys/dev/pccbb/pccbb_pci.c b/sys/dev/pccbb/pccbb_pci.c
index 7dca418249fb..a82afa271ed0 100644
--- a/sys/dev/pccbb/pccbb_pci.c
+++ b/sys/dev/pccbb/pccbb_pci.c
@@ -502,10 +502,26 @@ cbb_chipinit(struct cbb_softc *sc)
* properly initialized.
*
* The TI125X parts have a different register.
+ *
+ * Note: Only the lower two nibbles matter. When set
+ * to 0, the MFUNC{0,1} pins are GPIO, which isn't
+ * going to work out too well because we specifically
+ * program these parts to parallel interrupt signalling
+ * elsewhere. We preserve the upper bits of this
+ * register since changing them have subtle side effects
+ * for different variants of the card and are
+ * extremely difficult to exaustively test.
+ *
+ * Also, the TI 1510/1520 changed the default for the MFUNC
+ * register from 0x0 to 0x1000 to enable IRQSER by default.
+ * We want to be careful to avoid overriding that, and the
+ * below test will do that. Should this check prove to be
+ * too permissive, we should just check against 0 and 0x1000
+ * and not touch it otherwise.
*/
mux = pci_read_config(sc->dev, CBBR_MFUNC, 4);
sysctrl = pci_read_config(sc->dev, CBBR_SYSCTRL, 4);
- if (mux == 0) {
+ if ((mux & (CBBM_MFUNC_PIN0 | CBBM_MFUNC_PIN1)) == 0) {
mux = (mux & ~CBBM_MFUNC_PIN0) |
CBBM_MFUNC_PIN0_INTA;
if ((sysctrl & CBBM_SYSCTRL_INTRTIE) == 0)
@@ -518,7 +534,8 @@ cbb_chipinit(struct cbb_softc *sc)
/*
* Disable zoom video. Some machines initialize this
* improperly and exerpience has shown that this helps
- * prevent strange behavior.
+ * prevent strange behavior. We don't support zoom
+ * video anyway, so no harm can come from this.
*/
pci_write_config(sc->dev, CBBR_MMCTRL, 0, 4);
break;
diff --git a/sys/dev/pci/pci_iov.c b/sys/dev/pci/pci_iov.c
index e256a5d126f1..4672e55e5996 100644
--- a/sys/dev/pci/pci_iov.c
+++ b/sys/dev/pci/pci_iov.c
@@ -386,7 +386,7 @@ pci_iov_parse_config(struct pcicfg_iov *iov, struct pci_iov_arg *arg,
if (error != 0)
goto out;
- config = nvlist_unpack(packed_config, arg->len);
+ config = nvlist_unpack(packed_config, arg->len, NV_FLAG_IGNORE_CASE);
if (config == NULL) {
error = EINVAL;
goto out;
diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index cd4cc1e59f73..88b8961e4734 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -522,6 +522,7 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = {
U3G_DEV(SIERRA, MC5727, 0),
U3G_DEV(SIERRA, MC5727_2, 0),
U3G_DEV(SIERRA, MC5728, 0),
+ U3G_DEV(SIERRA, MC7354, 0),
U3G_DEV(SIERRA, MC8700, 0),
U3G_DEV(SIERRA, MC8755, 0),
U3G_DEV(SIERRA, MC8755_2, 0),
diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
index 01595207ac92..c0dc79f18b11 100644
--- a/sys/dev/usb/serial/uftdi.c
+++ b/sys/dev/usb/serial/uftdi.c
@@ -497,6 +497,7 @@ static const STRUCT_USB_HOST_ID uftdi_devs[] = {
UFTDI_DEV(FTDI, SCS_DEVICE_5, 0),
UFTDI_DEV(FTDI, SCS_DEVICE_6, 0),
UFTDI_DEV(FTDI, SCS_DEVICE_7, 0),
+ UFTDI_DEV(FTDI, SCX8_USB_PHOENIX, 0),
UFTDI_DEV(FTDI, SDMUSBQSS, 0),
UFTDI_DEV(FTDI, SEMC_DSS20, 0),
UFTDI_DEV(FTDI, SERIAL_2232C, UFTDI_JTAG_CHECK_STRING),
diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c
index ae4ed3a4339b..46d08b5fedbf 100644
--- a/sys/dev/usb/serial/usb_serial.c
+++ b/sys/dev/usb/serial/usb_serial.c
@@ -415,8 +415,9 @@ ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
sc->sc_tty = tp;
sc->sc_pps.ppscap = PPS_CAPTUREBOTH;
- sc->sc_pps.mtx = sc->sc_mtx;
- pps_init(&sc->sc_pps);
+ sc->sc_pps.driver_abi = PPS_ABI_VERSION;
+ sc->sc_pps.driver_mtx = sc->sc_mtx;
+ pps_init_abi(&sc->sc_pps);
DPRINTF("ttycreate: %s\n", buf);
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index d972bdc7650d..abe2e6fcad03 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1872,6 +1872,7 @@ product FREECOM HDD 0xfc05 Classic SL Hard Drive
product FSC E5400 0x1009 PrismGT USB 2.0 WLAN
/* Future Technology Devices products */
+product FTDI SCX8_USB_PHOENIX 0x5259 SCx8 USB Phoenix interface
product FTDI SERIAL_8U100AX 0x8372 8U100AX Serial
product FTDI SERIAL_8U232AM 0x6001 8U232AM Serial
product FTDI SERIAL_8U232AM4 0x6004 8U232AM Serial
@@ -4029,6 +4030,7 @@ product SIERRA C22 0x6891 C22
product SIERRA E6892 0x6892 E6892
product SIERRA E6893 0x6893 E6893
product SIERRA MC8700 0x68A3 MC8700
+product SIERRA MC7354 0x6820 MC7354
product SIERRA AIRCARD875 0x6820 Aircard 875 HSDPA
product SIERRA AC313U 0x68aa Sierra Wireless AirCard 313U
product SIERRA TRUINSTALL 0x0fff Aircard Tru Installer
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index 9579c611a22e..7b438c7024b9 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -152,11 +152,14 @@ static int wpi_alloc_fwmem(struct wpi_softc *);
static void wpi_free_fwmem(struct wpi_softc *);
static int wpi_alloc_rx_ring(struct wpi_softc *);
static void wpi_update_rx_ring(struct wpi_softc *);
+static void wpi_update_rx_ring_ps(struct wpi_softc *);
static void wpi_reset_rx_ring(struct wpi_softc *);
static void wpi_free_rx_ring(struct wpi_softc *);
static int wpi_alloc_tx_ring(struct wpi_softc *, struct wpi_tx_ring *,
int);
static void wpi_update_tx_ring(struct wpi_softc *, struct wpi_tx_ring *);
+static void wpi_update_tx_ring_ps(struct wpi_softc *,
+ struct wpi_tx_ring *);
static void wpi_reset_tx_ring(struct wpi_softc *, struct wpi_tx_ring *);
static void wpi_free_tx_ring(struct wpi_softc *, struct wpi_tx_ring *);
static int wpi_read_eeprom(struct wpi_softc *,
@@ -171,9 +174,13 @@ static int wpi_setregdomain(struct ieee80211com *,
struct ieee80211_channel[]);
static int wpi_read_eeprom_group(struct wpi_softc *, int);
static int wpi_add_node_entry_adhoc(struct wpi_softc *);
-static void wpi_node_free(struct ieee80211_node *);
static struct ieee80211_node *wpi_node_alloc(struct ieee80211vap *,
const uint8_t mac[IEEE80211_ADDR_LEN]);
+static void wpi_node_free(struct ieee80211_node *);
+static void wpi_recv_mgmt(struct ieee80211_node *, struct mbuf *, int, int,
+ int);
+static void wpi_restore_node(void *, struct ieee80211_node *);
+static void wpi_restore_node_table(struct wpi_softc *, struct wpi_vap *);
static int wpi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void wpi_calib_timeout(void *);
static void wpi_rx_done(struct wpi_softc *, struct wpi_rx_desc *,
@@ -228,6 +235,7 @@ static uint16_t wpi_get_active_dwell_time(struct wpi_softc *,
static uint16_t wpi_limit_dwell(struct wpi_softc *, uint16_t);
static uint16_t wpi_get_passive_dwell_time(struct wpi_softc *,
struct ieee80211_channel *);
+static uint32_t wpi_get_scan_pause_time(uint32_t, uint16_t);
static int wpi_scan(struct wpi_softc *, struct ieee80211_channel *);
static int wpi_auth(struct wpi_softc *, struct ieee80211vap *);
static int wpi_config_beacon(struct wpi_vap *);
@@ -516,11 +524,13 @@ wpi_attach(device_t dev)
ic->ic_scan_start = wpi_scan_start;
ic->ic_scan_end = wpi_scan_end;
ic->ic_set_channel = wpi_set_channel;
- sc->sc_scan_curchan = ic->ic_scan_curchan;
ic->ic_scan_curchan = wpi_scan_curchan;
ic->ic_scan_mindwell = wpi_scan_mindwell;
ic->ic_setregdomain = wpi_setregdomain;
+ sc->sc_update_rx_ring = wpi_update_rx_ring;
+ sc->sc_update_tx_ring = wpi_update_tx_ring;
+
wpi_radiotap_attach(sc);
callout_init_mtx(&sc->calib_to, &sc->rxon_mtx, 0);
@@ -609,7 +619,12 @@ wpi_init_beacon(struct wpi_vap *wvp)
cmd->ofdm_mask = 0xff;
cmd->cck_mask = 0x0f;
cmd->lifetime = htole32(WPI_LIFETIME_INFINITE);
- cmd->flags = htole32(WPI_TX_AUTO_SEQ | WPI_TX_INSERT_TSTAMP);
+
+ /*
+ * XXX WPI_TX_AUTO_SEQ seems to be ignored - workaround this issue
+ * XXX by using WPI_TX_NEED_ACK instead (with some side effects).
+ */
+ cmd->flags = htole32(WPI_TX_NEED_ACK | WPI_TX_INSERT_TSTAMP);
bcn->code = WPI_CMD_SET_BEACON;
bcn->ac = WPI_CMD_QUEUE_NUM;
@@ -643,6 +658,8 @@ wpi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* Override with driver methods. */
vap->iv_key_set = wpi_key_set;
vap->iv_key_delete = wpi_key_delete;
+ wvp->wv_recv_mgmt = vap->iv_recv_mgmt;
+ vap->iv_recv_mgmt = wpi_recv_mgmt;
wvp->wv_newstate = vap->iv_newstate;
vap->iv_newstate = wpi_newstate;
vap->iv_update_beacon = wpi_update_beacon;
@@ -689,8 +706,6 @@ wpi_detach(device_t dev)
if (ifp != NULL) {
ic = ifp->if_l2com;
- ieee80211_draintask(ic, &sc->sc_reinittask);
- ieee80211_draintask(ic, &sc->sc_radiooff_task);
ieee80211_draintask(ic, &sc->sc_radioon_task);
ieee80211_draintask(ic, &sc->sc_start_task);
@@ -1086,6 +1101,12 @@ fail: wpi_free_rx_ring(sc);
static void
wpi_update_rx_ring(struct wpi_softc *sc)
{
+ WPI_WRITE(sc, WPI_FH_RX_WPTR, sc->rxq.cur & ~7);
+}
+
+static void
+wpi_update_rx_ring_ps(struct wpi_softc *sc)
+{
struct wpi_rx_ring *ring = &sc->rxq;
if (ring->update != 0) {
@@ -1093,14 +1114,15 @@ wpi_update_rx_ring(struct wpi_softc *sc)
return;
}
- if (WPI_READ(sc, WPI_UCODE_GP1) & WPI_UCODE_GP1_MAC_SLEEP) {
+ WPI_SETBITS(sc, WPI_GP_CNTRL, WPI_GP_CNTRL_MAC_ACCESS_REQ);
+ if (WPI_READ(sc, WPI_GP_CNTRL) & WPI_GP_CNTRL_SLEEP) {
DPRINTF(sc, WPI_DEBUG_PWRSAVE, "%s: wakeup request\n",
__func__);
-
- WPI_SETBITS(sc, WPI_GP_CNTRL, WPI_GP_CNTRL_MAC_ACCESS_REQ);
ring->update = 1;
- } else
- WPI_WRITE(sc, WPI_FH_RX_WPTR, ring->cur & ~7);
+ } else {
+ wpi_update_rx_ring(sc);
+ WPI_CLRBITS(sc, WPI_GP_CNTRL, WPI_GP_CNTRL_MAC_ACCESS_REQ);
+ }
}
static void
@@ -1244,19 +1266,27 @@ fail: wpi_free_tx_ring(sc, ring);
static void
wpi_update_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring)
{
+ WPI_WRITE(sc, WPI_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
+}
+
+static void
+wpi_update_tx_ring_ps(struct wpi_softc *sc, struct wpi_tx_ring *ring)
+{
+
if (ring->update != 0) {
/* Wait for INT_WAKEUP event. */
return;
}
- if (WPI_READ(sc, WPI_UCODE_GP1) & WPI_UCODE_GP1_MAC_SLEEP) {
+ WPI_SETBITS(sc, WPI_GP_CNTRL, WPI_GP_CNTRL_MAC_ACCESS_REQ);
+ if (WPI_READ(sc, WPI_GP_CNTRL) & WPI_GP_CNTRL_SLEEP) {
DPRINTF(sc, WPI_DEBUG_PWRSAVE, "%s (%d): requesting wakeup\n",
__func__, ring->qid);
-
- WPI_SETBITS(sc, WPI_GP_CNTRL, WPI_GP_CNTRL_MAC_ACCESS_REQ);
ring->update = 1;
- } else
- WPI_WRITE(sc, WPI_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
+ } else {
+ wpi_update_tx_ring(sc, ring);
+ WPI_CLRBITS(sc, WPI_GP_CNTRL, WPI_GP_CNTRL_MAC_ACCESS_REQ);
+ }
}
static void
@@ -1276,6 +1306,10 @@ wpi_reset_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring)
m_freem(data->m);
data->m = NULL;
}
+ if (data->ni != NULL) {
+ ieee80211_free_node(data->ni);
+ data->ni = NULL;
+ }
}
/* Clear TX descriptors. */
memset(ring->desc, 0, ring->desc_dma.size);
@@ -1651,6 +1685,72 @@ wpi_node_free(struct ieee80211_node *ni)
sc->sc_node_free(ni);
}
+static __inline int
+wpi_check_bss_filter(struct wpi_softc *sc)
+{
+ return (sc->rxon.filter & htole32(WPI_FILTER_BSS)) != 0;
+}
+
+static void
+wpi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, int rssi,
+ int nf)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct wpi_vap *wvp = WPI_VAP(vap);
+ uint64_t ni_tstamp, rx_tstamp;
+
+ wvp->wv_recv_mgmt(ni, m, subtype, rssi, nf);
+
+ if (vap->iv_opmode == IEEE80211_M_IBSS &&
+ vap->iv_state == IEEE80211_S_RUN &&
+ (subtype == IEEE80211_FC0_SUBTYPE_BEACON ||
+ subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) {
+ ni_tstamp = le64toh(ni->ni_tstamp.tsf);
+ rx_tstamp = le64toh(sc->rx_tstamp);
+
+ if (ni_tstamp >= rx_tstamp) {
+ DPRINTF(sc, WPI_DEBUG_STATE,
+ "ibss merge, tsf %ju tstamp %ju\n",
+ (uintmax_t)rx_tstamp, (uintmax_t)ni_tstamp);
+ (void) ieee80211_ibss_merge(ni);
+ }
+ }
+}
+
+static void
+wpi_restore_node(void *arg, struct ieee80211_node *ni)
+{
+ struct wpi_softc *sc = arg;
+ struct wpi_node *wn = WPI_NODE(ni);
+ int error;
+
+ WPI_NT_LOCK(sc);
+ if (wn->id != WPI_ID_UNDEFINED) {
+ wn->id = WPI_ID_UNDEFINED;
+ if ((error = wpi_add_ibss_node(sc, ni)) != 0) {
+ device_printf(sc->sc_dev,
+ "%s: could not add IBSS node, error %d\n",
+ __func__, error);
+ }
+ }
+ WPI_NT_UNLOCK(sc);
+}
+
+static void
+wpi_restore_node_table(struct wpi_softc *sc, struct wpi_vap *wvp)
+{
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+
+ /* Set group keys once. */
+ WPI_NT_LOCK(sc);
+ wvp->wv_gtk = 0;
+ WPI_NT_UNLOCK(sc);
+
+ ieee80211_iterate_nodes(&ic->ic_sta, wpi_restore_node, sc);
+ ieee80211_crypto_reload_keys(ic);
+}
+
/**
* Called by net80211 when ever there is a change to 80211 state machine
*/
@@ -1669,20 +1769,21 @@ wpi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
ieee80211_state_name[vap->iv_state],
ieee80211_state_name[nstate]);
- if (vap->iv_state == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
+ if (vap->iv_state == IEEE80211_S_RUN && nstate < IEEE80211_S_RUN) {
if ((error = wpi_set_pslevel(sc, 0, 0, 1)) != 0) {
device_printf(sc->sc_dev,
"%s: could not set power saving level\n",
__func__);
return error;
}
+
+ wpi_set_led(sc, WPI_LED_LINK, 1, 0);
}
switch (nstate) {
case IEEE80211_S_SCAN:
WPI_RXON_LOCK(sc);
- if ((sc->rxon.filter & htole32(WPI_FILTER_BSS)) &&
- vap->iv_opmode != IEEE80211_M_STA) {
+ if (wpi_check_bss_filter(sc) != 0) {
sc->rxon.filter &= ~htole32(WPI_FILTER_BSS);
if ((error = wpi_send_rxon(sc, 0, 1)) != 0) {
device_printf(sc->sc_dev,
@@ -1698,6 +1799,11 @@ wpi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* FALLTHROUGH */
case IEEE80211_S_AUTH:
/*
+ * NB: do not optimize AUTH -> AUTH state transmission -
+ * this will break powersave with non-QoS AP!
+ */
+
+ /*
* The node must be registered in the firmware before auth.
* Also the associd must be cleared on RUN -> ASSOC
* transitions.
@@ -1711,13 +1817,36 @@ wpi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
case IEEE80211_S_RUN:
/*
- * RUN -> RUN transition; Just restart the timers.
+ * RUN -> RUN transition:
+ * STA mode: Just restart the timers.
+ * IBSS mode: Process IBSS merge.
*/
if (vap->iv_state == IEEE80211_S_RUN) {
- WPI_RXON_LOCK(sc);
- wpi_calib_timeout(sc);
- WPI_RXON_UNLOCK(sc);
- break;
+ if (vap->iv_opmode != IEEE80211_M_IBSS) {
+ WPI_RXON_LOCK(sc);
+ wpi_calib_timeout(sc);
+ WPI_RXON_UNLOCK(sc);
+ break;
+ } else {
+ /*
+ * Drop the BSS_FILTER bit
+ * (there is no another way to change bssid).
+ */
+ WPI_RXON_LOCK(sc);
+ sc->rxon.filter &= ~htole32(WPI_FILTER_BSS);
+ if ((error = wpi_send_rxon(sc, 0, 1)) != 0) {
+ device_printf(sc->sc_dev,
+ "%s: could not send RXON\n",
+ __func__);
+ }
+ WPI_RXON_UNLOCK(sc);
+
+ /* Restore all what was lost. */
+ wpi_restore_node_table(sc, wvp);
+
+ /* XXX set conditionally? */
+ wpi_updateedca(ic);
+ }
}
/*
@@ -1749,7 +1878,7 @@ wpi_calib_timeout(void *arg)
{
struct wpi_softc *sc = arg;
- if (!(sc->rxon.filter & htole32(WPI_FILTER_BSS)))
+ if (wpi_check_bss_filter(sc) == 0)
return;
wpi_power_calibration(sc);
@@ -1843,7 +1972,7 @@ wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc,
goto fail1;
}
/* Discard frames that are too short. */
- if (len < sizeof (*wh)) {
+ if (len < sizeof (struct ieee80211_frame_ack)) {
DPRINTF(sc, WPI_DEBUG_RECV, "%s: frame too short: %d\n",
__func__, len);
goto fail1;
@@ -1904,7 +2033,12 @@ wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc,
m->m_flags |= M_WEP;
}
- ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
+ if (len >= sizeof(struct ieee80211_frame_min))
+ ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
+ else
+ ni = NULL;
+
+ sc->rx_tstamp = tail->tstamp;
if (ieee80211_radiotap_active(ic)) {
struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap;
@@ -1957,7 +2091,7 @@ wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
struct ieee80211vap *vap;
struct ieee80211com *ic;
uint32_t status = le32toh(stat->status);
- int ackfailcnt = stat->ackfailcnt / 2; /* wpi_mrr_setup() */
+ int ackfailcnt = stat->ackfailcnt / WPI_NTRIES_DEFAULT;
KASSERT(data->ni != NULL, ("no node"));
KASSERT(data->m != NULL, ("no mbuf"));
@@ -1966,7 +2100,7 @@ wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
DPRINTF(sc, WPI_DEBUG_XMIT, "%s: "
"qid %d idx %d retries %d btkillcnt %d rate %x duration %d "
- "status %x\n", __func__, desc->qid, desc->idx, ackfailcnt,
+ "status %x\n", __func__, desc->qid, desc->idx, stat->ackfailcnt,
stat->btkillcnt, stat->rate, le32toh(stat->duration), status);
/* Unmap and free mbuf. */
@@ -1980,7 +2114,7 @@ wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
/*
* Update rate control statistics for the node.
*/
- if ((status & 0xff) != 1) {
+ if (status & WPI_TX_STATUS_FAIL) {
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL);
@@ -1990,7 +2124,7 @@ wpi_tx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
}
- ieee80211_tx_complete(ni, m, (status & 0xff) != 1);
+ ieee80211_tx_complete(ni, m, (status & WPI_TX_STATUS_FAIL) != 0);
WPI_TXQ_STATE_LOCK(sc);
ring->queued -= 1;
@@ -2048,6 +2182,18 @@ wpi_cmd_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
}
wakeup(&ring->cmd[desc->idx]);
+
+ if (desc->type == WPI_CMD_SET_POWER_MODE) {
+ WPI_TXQ_LOCK(sc);
+ if (sc->sc_flags & WPI_PS_PATH) {
+ sc->sc_update_rx_ring = wpi_update_rx_ring_ps;
+ sc->sc_update_tx_ring = wpi_update_tx_ring_ps;
+ } else {
+ sc->sc_update_rx_ring = wpi_update_rx_ring;
+ sc->sc_update_tx_ring = wpi_update_tx_ring;
+ }
+ WPI_TXQ_UNLOCK(sc);
+ }
}
static void
@@ -2061,7 +2207,7 @@ wpi_notif_intr(struct wpi_softc *sc)
bus_dmamap_sync(sc->shared_dma.tag, sc->shared_dma.map,
BUS_DMASYNC_POSTREAD);
- hw = le32toh(sc->shared->next);
+ hw = le32toh(sc->shared->next) & 0xfff;
hw = (hw == 0) ? WPI_RX_RING_COUNT - 1 : hw - 1;
while (sc->rxq.cur != hw) {
@@ -2110,23 +2256,57 @@ wpi_notif_intr(struct wpi_softc *sc)
{
struct wpi_beacon_missed *miss =
(struct wpi_beacon_missed *)(desc + 1);
- uint32_t misses;
+ uint32_t expected, misses, received, threshold;
bus_dmamap_sync(sc->rxq.data_dmat, data->map,
BUS_DMASYNC_POSTREAD);
+
misses = le32toh(miss->consecutive);
+ expected = le32toh(miss->expected);
+ received = le32toh(miss->received);
+ threshold = MAX(2, vap->iv_bmissthreshold);
+
+ DPRINTF(sc, WPI_DEBUG_BMISS,
+ "%s: beacons missed %u(%u) (received %u/%u)\n",
+ __func__, misses, le32toh(miss->total), received,
+ expected);
+
+ if (misses >= threshold ||
+ (received == 0 && expected >= threshold)) {
+ WPI_RXON_LOCK(sc);
+ if (callout_pending(&sc->scan_timeout)) {
+ wpi_cmd(sc, WPI_CMD_SCAN_ABORT, NULL,
+ 0, 1);
+ }
+ WPI_RXON_UNLOCK(sc);
+ if (vap->iv_state == IEEE80211_S_RUN &&
+ (ic->ic_flags & IEEE80211_F_SCAN) == 0)
+ ieee80211_beacon_miss(ic);
+ }
- DPRINTF(sc, WPI_DEBUG_STATE,
- "%s: beacons missed %d/%d\n", __func__, misses,
- le32toh(miss->total));
+ break;
+ }
+#ifdef WPI_DEBUG
+ case WPI_BEACON_SENT:
+ {
+ struct wpi_tx_stat *stat =
+ (struct wpi_tx_stat *)(desc + 1);
+ uint64_t *tsf = (uint64_t *)(stat + 1);
+ uint32_t *mode = (uint32_t *)(tsf + 1);
+
+ bus_dmamap_sync(sc->rxq.data_dmat, data->map,
+ BUS_DMASYNC_POSTREAD);
- if (vap->iv_state == IEEE80211_S_RUN &&
- (ic->ic_flags & IEEE80211_F_SCAN) == 0 &&
- misses >= vap->iv_bmissthreshold)
- ieee80211_beacon_miss(ic);
+ DPRINTF(sc, WPI_DEBUG_BEACON,
+ "beacon sent: rts %u, ack %u, btkill %u, rate %u, "
+ "duration %u, status %x, tsf %ju, mode %x\n",
+ stat->rtsfailcnt, stat->ackfailcnt,
+ stat->btkillcnt, stat->rate, le32toh(stat->duration),
+ le32toh(stat->status), *tsf, *mode);
break;
}
+#endif
case WPI_UC_READY:
{
struct wpi_ucode_info *uc =
@@ -2163,46 +2343,53 @@ wpi_notif_intr(struct wpi_softc *sc)
WPI_NT_LOCK(sc);
wpi_clear_node_table(sc);
WPI_NT_UNLOCK(sc);
- ieee80211_runtask(ic, &sc->sc_radiooff_task);
+ taskqueue_enqueue(sc->sc_tq,
+ &sc->sc_radiooff_task);
return;
}
break;
}
+#ifdef WPI_DEBUG
case WPI_START_SCAN:
{
bus_dmamap_sync(sc->rxq.data_dmat, data->map,
BUS_DMASYNC_POSTREAD);
-#ifdef WPI_DEBUG
+
struct wpi_start_scan *scan =
(struct wpi_start_scan *)(desc + 1);
DPRINTF(sc, WPI_DEBUG_SCAN,
"%s: scanning channel %d status %x\n",
__func__, scan->chan, le32toh(scan->status));
-#endif
+
break;
}
+#endif
case WPI_STOP_SCAN:
{
bus_dmamap_sync(sc->rxq.data_dmat, data->map,
BUS_DMASYNC_POSTREAD);
-#ifdef WPI_DEBUG
+
struct wpi_stop_scan *scan =
(struct wpi_stop_scan *)(desc + 1);
+
DPRINTF(sc, WPI_DEBUG_SCAN,
"scan finished nchan=%d status=%d chan=%d\n",
scan->nchan, scan->status, scan->chan);
-#endif
+
WPI_RXON_LOCK(sc);
callout_stop(&sc->scan_timeout);
WPI_RXON_UNLOCK(sc);
- ieee80211_scan_next(vap);
+ if (scan->status == WPI_SCAN_ABORTED)
+ ieee80211_cancel_scan(vap);
+ else
+ ieee80211_scan_next(vap);
break;
}
}
if (sc->rxq.cur % 8 == 0) {
/* Tell the firmware what we have processed. */
- wpi_update_rx_ring(sc);
+ sc->sc_update_rx_ring(sc);
}
}
}
@@ -2233,9 +2420,8 @@ wpi_wakeup_intr(struct wpi_softc *sc)
wpi_update_tx_ring(sc, ring);
}
}
- WPI_TXQ_UNLOCK(sc);
-
WPI_CLRBITS(sc, WPI_GP_CNTRL, WPI_GP_CNTRL_MAC_ACCESS_REQ);
+ WPI_TXQ_UNLOCK(sc);
}
/*
@@ -2245,8 +2431,7 @@ wpi_wakeup_intr(struct wpi_softc *sc)
static void
wpi_debug_registers(struct wpi_softc *sc)
{
-#define COUNTOF(array) (sizeof(array) / sizeof(array[0]))
- int i;
+ size_t i;
static const uint32_t csr_tbl[] = {
WPI_HW_IF_CONFIG,
WPI_INT,
@@ -2273,7 +2458,7 @@ wpi_debug_registers(struct wpi_softc *sc)
DPRINTF(sc, WPI_DEBUG_REGISTER,"%s","\n");
- for (i = 0; i < COUNTOF(csr_tbl); i++) {
+ for (i = 0; i < nitems(csr_tbl); i++) {
DPRINTF(sc, WPI_DEBUG_REGISTER, " %-18s: 0x%08x ",
wpi_get_csr_string(csr_tbl[i]), WPI_READ(sc, csr_tbl[i]));
@@ -2283,7 +2468,7 @@ wpi_debug_registers(struct wpi_softc *sc)
DPRINTF(sc, WPI_DEBUG_REGISTER, "\n\n");
if (wpi_nic_lock(sc) == 0) {
- for (i = 0; i < COUNTOF(prph_tbl); i++) {
+ for (i = 0; i < nitems(prph_tbl); i++) {
DPRINTF(sc, WPI_DEBUG_REGISTER, " %-18s: 0x%08x ",
wpi_get_prph_string(prph_tbl[i]),
wpi_prph_read(sc, prph_tbl[i]));
@@ -2297,7 +2482,6 @@ wpi_debug_registers(struct wpi_softc *sc)
DPRINTF(sc, WPI_DEBUG_REGISTER,
"Cannot access internal registers.\n");
}
-#undef COUNTOF
}
#endif
@@ -2311,8 +2495,6 @@ wpi_fatal_intr(struct wpi_softc *sc)
{
struct wpi_fw_dump dump;
uint32_t i, offset, count;
- const uint32_t size_errmsg =
- (sizeof (wpi_fw_errmsg) / sizeof ((wpi_fw_errmsg)[0]));
/* Check that the error log address is valid. */
if (sc->errptr < WPI_FW_DATA_BASE ||
@@ -2342,7 +2524,7 @@ wpi_fatal_intr(struct wpi_softc *sc)
sizeof (dump) / sizeof (uint32_t));
printf(" error type = \"%s\" (0x%08X)\n",
- (dump.desc < size_errmsg) ?
+ (dump.desc < nitems(wpi_fw_errmsg)) ?
wpi_fw_errmsg[dump.desc] : "UNKNOWN",
dump.desc);
printf(" error data = 0x%08X\n",
@@ -2539,7 +2721,7 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
/* Kick TX ring. */
ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT;
- wpi_update_tx_ring(sc, ring);
+ sc->sc_update_tx_ring(sc, ring);
if (ring->qid < WPI_CMD_QUEUE_NUM) {
/* Mark TX ring as full if we reach a certain threshold. */
@@ -2597,7 +2779,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
/* Select EDCA Access Category and TX ring for this frame. */
if (IEEE80211_QOS_HAS_SEQ(wh)) {
- qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
+ qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
tid = qos & IEEE80211_QOS_TID;
} else {
qos = 0;
@@ -2658,6 +2840,8 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
flags |= WPI_TX_NEED_ACK;
}
+ if (!IEEE80211_QOS_HAS_SEQ(wh))
+ flags |= WPI_TX_AUTO_SEQ;
if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
flags |= WPI_TX_MORE_FRAG; /* Cannot happen yet. */
@@ -2705,9 +2889,6 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
tx->id = wn->id;
}
- if (type != IEEE80211_FC0_TYPE_MGT)
- tx->data_ntries = tp->maxretry;
-
if (k != NULL && !swcrypt) {
switch (k->wk_cipher->ic_cipher) {
case IEEE80211_CIPHER_AES_CCM:
@@ -2729,6 +2910,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
tx->ofdm_mask = 0xff;
tx->cck_mask = 0x0f;
tx->rts_ntries = 7;
+ tx->data_ntries = tp->maxretry;
tx_data.ni = ni;
tx_data.m = m;
@@ -2764,6 +2946,8 @@ wpi_tx_data_raw(struct wpi_softc *sc, struct mbuf *m,
rate = params->ibp_rate0;
flags = 0;
+ if (!IEEE80211_QOS_HAS_SEQ(wh))
+ flags |= WPI_TX_AUTO_SEQ;
if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
flags |= WPI_TX_NEED_ACK;
if (params->ibp_flags & IEEE80211_BPF_RTS)
@@ -3089,7 +3273,7 @@ wpi_cmd(struct wpi_softc *sc, int code, const void *buf, size_t size,
/* Kick command ring. */
ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT;
- wpi_update_tx_ring(sc, ring);
+ sc->sc_update_tx_ring(sc, ring);
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__);
@@ -3125,8 +3309,8 @@ wpi_mrr_setup(struct wpi_softc *sc)
/* Fallback to the immediate lower CCK rate (if any.) */
mrr.rates[i].next =
(i == WPI_RIDX_CCK1) ? WPI_RIDX_CCK1 : i - 1;
- /* Try one time at this rate before falling back to "next". */
- mrr.rates[i].ntries = 1;
+ /* Try twice at this rate before falling back to "next". */
+ mrr.rates[i].ntries = WPI_NTRIES_DEFAULT;
}
/* OFDM rates (not used with 802.11b). */
for (i = WPI_RIDX_OFDM6; i <= WPI_RIDX_OFDM54; i++) {
@@ -3138,8 +3322,8 @@ wpi_mrr_setup(struct wpi_softc *sc)
((ic->ic_curmode == IEEE80211_MODE_11A) ?
WPI_RIDX_OFDM6 : WPI_RIDX_CCK2) :
i - 1;
- /* Try one time at this rate before falling back to "next". */
- mrr.rates[i].ntries = 1;
+ /* Try twice at this rate before falling back to "next". */
+ mrr.rates[i].ntries = WPI_NTRIES_DEFAULT;
}
/* Setup MRR for control frames. */
mrr.which = htole32(WPI_MRR_CTL);
@@ -3590,8 +3774,13 @@ wpi_set_pslevel(struct wpi_softc *sc, uint8_t dtim, int level, int async)
pmgt = &wpi_pmgt[1][level];
memset(&cmd, 0, sizeof cmd);
- if (level != 0) /* not CAM */
+ WPI_TXQ_LOCK(sc);
+ if (level != 0) { /* not CAM */
cmd.flags |= htole16(WPI_PS_ALLOW_SLEEP);
+ sc->sc_flags |= WPI_PS_PATH;
+ } else
+ sc->sc_flags &= ~WPI_PS_PATH;
+ WPI_TXQ_UNLOCK(sc);
/* Retrieve PCIe Active State Power Management (ASPM). */
reg = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
if (!(reg & 0x1)) /* L0s Entry disabled. */
@@ -3644,7 +3833,7 @@ wpi_send_rxon(struct wpi_softc *sc, int assoc, int async)
if (async)
WPI_RXON_LOCK_ASSERT(sc);
- if (assoc && (sc->rxon.filter & htole32(WPI_FILTER_BSS))) {
+ if (assoc && wpi_check_bss_filter(sc) != 0) {
struct wpi_assoc rxon_assoc;
rxon_assoc.flags = sc->rxon.flags;
@@ -3710,7 +3899,7 @@ wpi_config(struct wpi_softc *sc)
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- uint32_t flags;
+ struct ieee80211_channel *c = ic->ic_curchan;
int error;
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
@@ -3734,9 +3923,9 @@ wpi_config(struct wpi_softc *sc)
IEEE80211_ADDR_COPY(sc->rxon.myaddr, vap->iv_myaddr);
/* Set default channel. */
- sc->rxon.chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
+ sc->rxon.chan = ieee80211_chan2ieee(ic, c);
sc->rxon.flags = htole32(WPI_RXON_TSF | WPI_RXON_CTS_TO_SELF);
- if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
+ if (IEEE80211_IS_CHAN_2GHZ(c))
sc->rxon.flags |= htole32(WPI_RXON_AUTO | WPI_RXON_24GHZ);
sc->rxon.filter = WPI_FILTER_MULTICAST;
@@ -3754,7 +3943,6 @@ wpi_config(struct wpi_softc *sc)
sc->rxon.filter |= WPI_FILTER_ASSOC | WPI_FILTER_PROMISC;
break;
case IEEE80211_M_AHDEMO:
- /* XXX workaround for passive channels selection */
sc->rxon.mode = WPI_MODE_HOSTAP;
break;
case IEEE80211_M_MONITOR:
@@ -3770,6 +3958,14 @@ wpi_config(struct wpi_softc *sc)
sc->rxon.cck_mask = 0x0f; /* not yet negotiated */
sc->rxon.ofdm_mask = 0xff; /* not yet negotiated */
+ /* XXX Current configuration may be unusable. */
+ if (IEEE80211_IS_CHAN_NOADHOC(c) && sc->rxon.mode == WPI_MODE_IBSS) {
+ device_printf(sc->sc_dev,
+ "%s: invalid channel (%d) selected for IBSS mode\n",
+ __func__, ieee80211_chan2ieee(ic, c));
+ return EINVAL;
+ }
+
if ((error = wpi_send_rxon(sc, 0, 0)) != 0) {
device_printf(sc->sc_dev, "%s: could not send RXON\n",
__func__);
@@ -3783,15 +3979,6 @@ wpi_config(struct wpi_softc *sc)
return error;
}
- /* Disable beacon notifications (unused). */
- flags = WPI_STATISTICS_BEACON_DISABLE;
- error = wpi_cmd(sc, WPI_CMD_GET_STATISTICS, &flags, sizeof flags, 1);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not disable beacon statistics, error %d\n", error);
- return error;
- }
-
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__);
return 0;
@@ -3813,7 +4000,7 @@ wpi_get_active_dwell_time(struct wpi_softc *sc,
}
/*
- * Limit the total dwell time to 85% of the beacon interval.
+ * Limit the total dwell time.
*
* Returns the dwell time in milliseconds.
*/
@@ -3838,11 +4025,11 @@ wpi_limit_dwell(struct wpi_softc *sc, uint16_t dwell_time)
if (bintval > 0) {
DPRINTF(sc, WPI_DEBUG_SCAN, "%s: bintval=%d\n", __func__,
bintval);
- return (MIN(WPI_PASSIVE_DWELL_BASE, ((bintval * 85) / 100)));
+ return (MIN(dwell_time, bintval - WPI_CHANNEL_TUNE_TIME * 2));
}
/* No association context? Default. */
- return (WPI_PASSIVE_DWELL_BASE);
+ return dwell_time;
}
static uint16_t
@@ -3859,6 +4046,18 @@ wpi_get_passive_dwell_time(struct wpi_softc *sc, struct ieee80211_channel *c)
return (wpi_limit_dwell(sc, passive));
}
+static uint32_t
+wpi_get_scan_pause_time(uint32_t time, uint16_t bintval)
+{
+ uint32_t mod = (time % bintval) * IEEE80211_DUR_TU;
+ uint32_t nbeacons = time / bintval;
+
+ if (mod > WPI_PAUSE_MAX_TIME)
+ mod = WPI_PAUSE_MAX_TIME;
+
+ return WPI_PAUSE_SCAN(nbeacons, mod);
+}
+
/*
* Send a scan request to the firmware.
*/
@@ -3877,7 +4076,7 @@ wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c)
struct ieee80211_rateset *rs;
uint16_t dwell_active, dwell_passive;
uint8_t *buf, *frm;
- int buflen, error, i, nssid;
+ int bgscan, bintval, buflen, error, i, nssid;
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
@@ -3888,10 +4087,16 @@ wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c)
if (callout_pending(&sc->scan_timeout)) {
device_printf(sc->sc_dev, "%s: called whilst scanning!\n",
__func__);
+ error = EAGAIN;
+ goto fail;
+ }
- DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__);
-
- return (EAGAIN);
+ bgscan = wpi_check_bss_filter(sc);
+ bintval = vap->iv_bss->ni_intval;
+ if (bgscan != 0 &&
+ bintval < WPI_QUIET_TIME_DEFAULT + WPI_CHANNEL_TUNE_TIME * 2) {
+ error = EOPNOTSUPP;
+ goto fail;
}
buf = malloc(WPI_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -3908,15 +4113,19 @@ wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c)
* Move to the next channel if no packets are received within 10 msecs
* after sending the probe request.
*/
- hdr->quiet_time = htole16(10); /* timeout in milliseconds */
- hdr->quiet_threshold = htole16(1); /* min # of packets */
- /*
- * Max needs to be greater than active and passive and quiet!
- * It's also in microseconds!
- */
- hdr->max_svc = htole32(250 * IEEE80211_DUR_TU);
- hdr->pause_svc = htole32((4 << 24) |
- (100 * IEEE80211_DUR_TU)); /* Hardcode for now */
+ hdr->quiet_time = htole16(WPI_QUIET_TIME_DEFAULT);
+ hdr->quiet_threshold = htole16(1);
+
+ if (bgscan != 0) {
+ /*
+ * Max needs to be greater than active and passive and quiet!
+ * It's also in microseconds!
+ */
+ hdr->max_svc = htole32(250 * IEEE80211_DUR_TU);
+ hdr->pause_svc = htole32(wpi_get_scan_pause_time(100,
+ bintval));
+ }
+
hdr->filter = htole32(WPI_FILTER_MULTICAST | WPI_FILTER_BEACON);
tx = (struct wpi_cmd_data *)(hdr + 1);
@@ -3998,8 +4207,8 @@ wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c)
dwell_passive = wpi_get_passive_dwell_time(sc, c);
/* Make sure they're valid. */
- if (dwell_passive <= dwell_active)
- dwell_passive = dwell_active + 1;
+ if (dwell_active > dwell_passive)
+ dwell_active = dwell_passive;
chan->active = htole16(dwell_active);
chan->passive = htole16(dwell_passive);
@@ -4015,6 +4224,20 @@ wpi_scan(struct wpi_softc *sc, struct ieee80211_channel *c)
chan->chan, IEEE80211_IS_CHAN_PASSIVE(c));
hdr->nchan++;
+
+ if (hdr->nchan == 1 && sc->rxon.chan == chan->chan) {
+ /* XXX Force probe request transmission. */
+ memcpy(chan + 1, chan, sizeof (struct wpi_scan_chan));
+
+ chan++;
+
+ /* Reduce unnecessary delay. */
+ chan->flags = 0;
+ chan->passive = chan->active = hdr->quiet_time;
+
+ hdr->nchan++;
+ }
+
chan++;
buflen = (uint8_t *)chan - buf;
@@ -4044,6 +4267,7 @@ wpi_auth(struct wpi_softc *sc, struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_node *ni = vap->iv_bss;
+ struct ieee80211_channel *c = ni->ni_chan;
int error;
WPI_RXON_LOCK(sc);
@@ -4054,18 +4278,18 @@ wpi_auth(struct wpi_softc *sc, struct ieee80211vap *vap)
sc->rxon.associd = 0;
sc->rxon.filter &= ~htole32(WPI_FILTER_BSS);
IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
- sc->rxon.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
+ sc->rxon.chan = ieee80211_chan2ieee(ic, c);
sc->rxon.flags = htole32(WPI_RXON_TSF | WPI_RXON_CTS_TO_SELF);
- if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
+ if (IEEE80211_IS_CHAN_2GHZ(c))
sc->rxon.flags |= htole32(WPI_RXON_AUTO | WPI_RXON_24GHZ);
if (ic->ic_flags & IEEE80211_F_SHSLOT)
sc->rxon.flags |= htole32(WPI_RXON_SHSLOT);
if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
sc->rxon.flags |= htole32(WPI_RXON_SHPREAMBLE);
- if (IEEE80211_IS_CHAN_A(ni->ni_chan)) {
+ if (IEEE80211_IS_CHAN_A(c)) {
sc->rxon.cck_mask = 0;
sc->rxon.ofdm_mask = 0x15;
- } else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {
+ } else if (IEEE80211_IS_CHAN_B(c)) {
sc->rxon.cck_mask = 0x03;
sc->rxon.ofdm_mask = 0;
} else {
@@ -4243,6 +4467,7 @@ wpi_run(struct wpi_softc *sc, struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_node *ni = vap->iv_bss;
+ struct ieee80211_channel *c = ni->ni_chan;
int error;
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
@@ -4254,7 +4479,7 @@ wpi_run(struct wpi_softc *sc, struct ieee80211vap *vap)
}
/* XXX kernel panic workaround */
- if (ni->ni_chan == IEEE80211_CHAN_ANYC) {
+ if (c == IEEE80211_CHAN_ANYC) {
device_printf(sc->sc_dev, "%s: incomplete configuration\n",
__func__);
return EINVAL;
@@ -4270,20 +4495,18 @@ wpi_run(struct wpi_softc *sc, struct ieee80211vap *vap)
WPI_RXON_LOCK(sc);
IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
sc->rxon.associd = htole16(IEEE80211_NODE_AID(ni));
- sc->rxon.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
+ sc->rxon.chan = ieee80211_chan2ieee(ic, c);
sc->rxon.flags = htole32(WPI_RXON_TSF | WPI_RXON_CTS_TO_SELF);
- if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
+ if (IEEE80211_IS_CHAN_2GHZ(c))
sc->rxon.flags |= htole32(WPI_RXON_AUTO | WPI_RXON_24GHZ);
- /* Short preamble and slot time are negotiated when associating. */
- sc->rxon.flags &= ~htole32(WPI_RXON_SHPREAMBLE | WPI_RXON_SHSLOT);
if (ic->ic_flags & IEEE80211_F_SHSLOT)
sc->rxon.flags |= htole32(WPI_RXON_SHSLOT);
if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
sc->rxon.flags |= htole32(WPI_RXON_SHPREAMBLE);
- if (IEEE80211_IS_CHAN_A(ni->ni_chan)) {
+ if (IEEE80211_IS_CHAN_A(c)) {
sc->rxon.cck_mask = 0;
sc->rxon.ofdm_mask = 0x15;
- } else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {
+ } else if (IEEE80211_IS_CHAN_B(c)) {
sc->rxon.cck_mask = 0x03;
sc->rxon.ofdm_mask = 0;
} else {
@@ -4619,7 +4842,7 @@ wpi_post_alive(struct wpi_softc *sc)
/* NB: Runtime firmware must be up and running. */
if (!(wpi_prph_read(sc, WPI_APMG_RFKILL) & 1)) {
- device_printf(sc->sc_dev,
+ device_printf(sc->sc_dev,
"RF switch: radio disabled (%s)\n", __func__);
wpi_nic_unlock(sc);
return EPERM; /* :-) */
@@ -4943,7 +5166,7 @@ wpi_apm_stop_master(struct wpi_softc *sc)
/* Stop busmaster DMA activity. */
WPI_SETBITS(sc, WPI_RESET, WPI_RESET_STOP_MASTER);
-
+
if ((WPI_READ(sc, WPI_GP_CNTRL) & WPI_GP_CNTRL_PS_MASK) ==
WPI_GP_CNTRL_MAC_PS)
return; /* Already asleep. */
@@ -5395,16 +5618,10 @@ wpi_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
int error;
WPI_RXON_LOCK(sc);
- if (sc->rxon.chan != ieee80211_chan2ieee(ic, ic->ic_curchan)) {
- error = wpi_scan(sc, ic->ic_curchan);
- WPI_RXON_UNLOCK(sc);
- if (error != 0)
- ieee80211_cancel_scan(vap);
- } else {
- WPI_RXON_UNLOCK(sc);
- /* Send probe request when associated. */
- sc->sc_scan_curchan(ss, maxdwell);
- }
+ error = wpi_scan(sc, ic->ic_curchan);
+ WPI_RXON_UNLOCK(sc);
+ if (error != 0)
+ ieee80211_cancel_scan(vap);
}
/**
diff --git a/sys/dev/wpi/if_wpi_debug.h b/sys/dev/wpi/if_wpi_debug.h
index 245bf59903cb..6b78acebb11f 100644
--- a/sys/dev/wpi/if_wpi_debug.h
+++ b/sys/dev/wpi/if_wpi_debug.h
@@ -43,6 +43,7 @@ enum {
WPI_DEBUG_KEY = 0x00020000, /* node key management */
WPI_DEBUG_EDCA = 0x00040000, /* WME info */
WPI_DEBUG_REGISTER = 0x00080000, /* print chipset register */
+ WPI_DEBUG_BMISS = 0x00100000, /* print number of missed beacons */
WPI_DEBUG_ANY = 0xffffffff
};
@@ -85,12 +86,12 @@ static const char *wpi_cmd_str(int cmd)
WPI_DESC(WPI_CMD_SET_LED);
WPI_DESC(WPI_CMD_SET_POWER_MODE);
WPI_DESC(WPI_CMD_SCAN);
+ WPI_DESC(WPI_CMD_SCAN_ABORT);
WPI_DESC(WPI_CMD_SET_BEACON);
WPI_DESC(WPI_CMD_TXPOWER);
WPI_DESC(WPI_CMD_BT_COEX);
default:
- KASSERT(1, ("Unknown Command: %d\n", cmd));
return "UNKNOWN CMD";
}
}
@@ -98,7 +99,7 @@ static const char *wpi_cmd_str(int cmd)
/*
* Translate CSR code to string
*/
-static const char *wpi_get_csr_string(int csr)
+static const char *wpi_get_csr_string(size_t csr)
{
switch (csr) {
WPI_DESC(WPI_HW_IF_CONFIG);
@@ -117,12 +118,12 @@ static const char *wpi_get_csr_string(int csr)
WPI_DESC(WPI_ANA_PLL);
WPI_DESC(WPI_DBG_HPET_MEM);
default:
- KASSERT(1, ("Unknown CSR: %d\n", csr));
+ KASSERT(0, ("Unknown CSR: %d\n", csr));
return "UNKNOWN CSR";
}
}
-static const char *wpi_get_prph_string(int prph)
+static const char *wpi_get_prph_string(size_t prph)
{
switch (prph) {
WPI_DESC(WPI_APMG_CLK_CTRL);
@@ -130,7 +131,7 @@ static const char *wpi_get_prph_string(int prph)
WPI_DESC(WPI_APMG_PCI_STT);
WPI_DESC(WPI_APMG_RFKILL);
default:
- KASSERT(1, ("Unknown register: %d\n", prph));
+ KASSERT(0, ("Unknown register: %d\n", prph));
return "UNKNOWN PRPH";
}
}
diff --git a/sys/dev/wpi/if_wpireg.h b/sys/dev/wpi/if_wpireg.h
index 7e60049a983a..b0aa35c992d5 100644
--- a/sys/dev/wpi/if_wpireg.h
+++ b/sys/dev/wpi/if_wpireg.h
@@ -256,6 +256,26 @@ struct wpi_tx_stat {
uint8_t rate;
uint32_t duration;
uint32_t status;
+#define WPI_TX_STATUS_SUCCESS 0x01
+#define WPI_TX_STATUS_DIRECT_DONE 0x02
+#define WPI_TX_STATUS_FAIL 0x80
+#define WPI_TX_STATUS_FAIL_SHORT_LIMIT 0x82
+#define WPI_TX_STATUS_FAIL_LONG_LIMIT 0x83
+#define WPI_TX_STATUS_FAIL_FIFO_UNDERRUN 0x84
+#define WPI_TX_STATUS_FAIL_MGMNT_ABORT 0x85
+#define WPI_TX_STATUS_FAIL_NEXT_FRAG 0x86
+#define WPI_TX_STATUS_FAIL_LIFE_EXPIRE 0x87
+#define WPI_TX_STATUS_FAIL_NODE_PS 0x88
+#define WPI_TX_STATUS_FAIL_ABORTED 0x89
+#define WPI_TX_STATUS_FAIL_BT_RETRY 0x8a
+#define WPI_TX_STATUS_FAIL_NODE_INVALID 0x8b
+#define WPI_TX_STATUS_FAIL_FRAG_DROPPED 0x8c
+#define WPI_TX_STATUS_FAIL_TID_DISABLE 0x8d
+#define WPI_TX_STATUS_FAIL_FRAME_FLUSHED 0x8e
+#define WPI_TX_STATUS_FAIL_INSUFFICIENT_CF_POLL 0x8f
+#define WPI_TX_STATUS_FAIL_TX_LOCKED 0x90
+#define WPI_TX_STATUS_FAIL_NO_BEACON_ON_RADAR 0x91
+
} __packed;
struct wpi_rx_desc {
@@ -332,6 +352,7 @@ struct wpi_tx_cmd {
#define WPI_CMD_SET_LED 72
#define WPI_CMD_SET_POWER_MODE 119
#define WPI_CMD_SCAN 128
+#define WPI_CMD_SCAN_ABORT 129
#define WPI_CMD_SET_BEACON 145
#define WPI_CMD_TXPOWER 151
#define WPI_CMD_BT_COEX 155
@@ -547,6 +568,8 @@ struct wpi_mrr_setup {
uint8_t plcp;
uint8_t flags;
uint8_t ntries;
+#define WPI_NTRIES_DEFAULT 2
+
uint8_t next;
} __packed rates[WPI_RIDX_MAX + 1];
} __packed;
@@ -589,12 +612,17 @@ struct wpi_scan_hdr {
uint16_t len;
uint8_t reserved1;
uint8_t nchan;
- uint16_t quiet_time;
- uint16_t quiet_threshold;
+ uint16_t quiet_time; /* timeout in milliseconds */
+#define WPI_QUIET_TIME_DEFAULT 10
+
+ uint16_t quiet_threshold; /* min # of packets */
uint16_t crc_threshold;
uint16_t reserved2;
uint32_t max_svc; /* background scans */
uint32_t pause_svc; /* background scans */
+#define WPI_PAUSE_MAX_TIME ((1 << 20) - 1)
+#define WPI_PAUSE_SCAN(nbeacons, time) ((nbeacons << 24) | time)
+
uint32_t flags;
uint32_t filter;
@@ -630,6 +658,7 @@ struct wpi_scan_chan {
#define WPI_PASSIVE_DWELL_TIME_2GHZ ( 20)
#define WPI_PASSIVE_DWELL_TIME_5GHZ ( 10)
#define WPI_PASSIVE_DWELL_BASE (100)
+#define WPI_CHANNEL_TUNE_TIME ( 6)
/* Structure for command WPI_CMD_TXPOWER. */
struct wpi_cmd_txpower {
@@ -697,6 +726,9 @@ struct wpi_start_scan {
struct wpi_stop_scan {
uint8_t nchan;
uint8_t status;
+#define WPI_SCAN_COMPLETED 1
+#define WPI_SCAN_ABORTED 2
+
uint8_t reserved;
uint8_t chan;
uint64_t tsf;
diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h
index 7c748250438e..7a65b721f6c4 100644
--- a/sys/dev/wpi/if_wpivar.h
+++ b/sys/dev/wpi/if_wpivar.h
@@ -121,17 +121,19 @@ struct wpi_buf {
};
struct wpi_vap {
- struct ieee80211vap wv_vap;
+ struct ieee80211vap wv_vap;
- struct wpi_buf wv_bcbuf;
- struct ieee80211_beacon_offsets wv_boff;
- struct mtx wv_mtx;
+ struct wpi_buf wv_bcbuf;
+ struct ieee80211_beacon_offsets wv_boff;
+ struct mtx wv_mtx;
- uint32_t wv_gtk;
-#define WPI_VAP_KEY(kid) (1 << kid)
+ uint32_t wv_gtk;
+#define WPI_VAP_KEY(kid) (1 << kid)
- int (*wv_newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
+ int (*wv_newstate)(struct ieee80211vap *,
+ enum ieee80211_state, int);
+ void (*wv_recv_mgmt)(struct ieee80211_node *,
+ struct mbuf *, int, int, int);
};
#define WPI_VAP(vap) ((struct wpi_vap *)(vap))
@@ -164,6 +166,9 @@ struct wpi_softc {
struct ifnet *sc_ifp;
int sc_debug;
+ int sc_flags;
+#define WPI_PS_PATH (1 << 0)
+
struct mtx sc_mtx;
struct mtx tx_mtx;
@@ -177,6 +182,7 @@ struct wpi_softc {
uint32_t txq_active;
struct wpi_rx_ring rxq;
+ uint64_t rx_tstamp;
/* TX Thermal Callibration. */
struct callout calib_to;
@@ -210,8 +216,9 @@ struct wpi_softc {
struct mtx nt_mtx;
void (*sc_node_free)(struct ieee80211_node *);
- void (*sc_scan_curchan)(struct ieee80211_scan_state *,
- unsigned long);
+ void (*sc_update_rx_ring)(struct wpi_softc *);
+ void (*sc_update_tx_ring)(struct wpi_softc *,
+ struct wpi_tx_ring *);
struct wpi_rx_radiotap_header sc_rxtap;
struct wpi_tx_radiotap_header sc_txtap;
diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c
index 5073398c954c..c340106ccb40 100644
--- a/sys/geom/part/g_part_mbr.c
+++ b/sys/geom/part/g_part_mbr.c
@@ -138,6 +138,9 @@ static struct g_part_mbr_alias {
{ DOSPTYP_PPCBOOT, G_PART_ALIAS_PREP_BOOT },
{ DOSPTYP_VMFS, G_PART_ALIAS_VMFS },
{ DOSPTYP_VMKDIAG, G_PART_ALIAS_VMKDIAG },
+ { DOSPTYP_APPLE_UFS, G_PART_ALIAS_APPLE_UFS },
+ { DOSPTYP_APPLE_BOOT, G_PART_ALIAS_APPLE_BOOT },
+ { DOSPTYP_HFS, G_PART_ALIAS_APPLE_HFS },
};
static int
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index 998ee150aebb..5125480a04ea 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -700,10 +700,8 @@ vpanic(const char *fmt, va_list ap)
}
/*
- * We set stop_scheduler here and not in the block above,
- * because we want to ensure that if panic has been called and
- * stop_scheduler_on_panic is true, then stop_scheduler will
- * always be set. Even if panic has been entered from kdb.
+ * Ensure that the scheduler is stopped while panicking, even if panic
+ * has been entered from kdb.
*/
td->td_stopsched = 1;
#endif
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 6264c64e975c..9dca0e80e5ea 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -1468,6 +1468,17 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, choice, CTLTYPE_STRING | CTLFLAG_RD,
* RFC 2783 PPS-API implementation.
*/
+/*
+ * Return true if the driver is aware of the abi version extensions in the
+ * pps_state structure, and it supports at least the given abi version number.
+ */
+static inline int
+abi_aware(struct pps_state *pps, int vers)
+{
+
+ return ((pps->kcmode & KCMODE_ABIFLAG) && pps->driver_abi >= vers);
+}
+
static int
pps_fetch(struct pps_fetch_args *fapi, struct pps_state *pps)
{
@@ -1497,10 +1508,17 @@ pps_fetch(struct pps_fetch_args *fapi, struct pps_state *pps)
cseq = pps->ppsinfo.clear_sequence;
while (aseq == pps->ppsinfo.assert_sequence &&
cseq == pps->ppsinfo.clear_sequence) {
- if (pps->mtx != NULL)
- err = msleep(pps, pps->mtx, PCATCH, "ppsfch", timo);
- else
+ if (abi_aware(pps, 1) && pps->driver_mtx != NULL) {
+ if (pps->flags & PPSFLAG_MTX_SPIN) {
+ err = msleep_spin(pps, pps->driver_mtx,
+ "ppsfch", timo);
+ } else {
+ err = msleep(pps, pps->driver_mtx, PCATCH,
+ "ppsfch", timo);
+ }
+ } else {
err = tsleep(pps, PCATCH, "ppsfch", timo);
+ }
if (err == EWOULDBLOCK && fapi->timeout.tv_sec == -1) {
continue;
} else if (err != 0) {
@@ -1590,7 +1608,8 @@ pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps)
return (EINVAL);
if (kapi->edge & ~pps->ppscap)
return (EINVAL);
- pps->kcmode = kapi->edge;
+ pps->kcmode = (kapi->edge & KCMODE_EDGEMASK) |
+ (pps->kcmode & KCMODE_ABIFLAG);
return (0);
#else
return (EOPNOTSUPP);
@@ -1611,6 +1630,18 @@ pps_init(struct pps_state *pps)
#ifdef FFCLOCK
pps->ppscap |= PPS_TSCLK_MASK;
#endif
+ pps->kcmode &= ~KCMODE_ABIFLAG;
+}
+
+void
+pps_init_abi(struct pps_state *pps)
+{
+
+ pps_init(pps);
+ if (pps->driver_abi > 0) {
+ pps->kcmode |= KCMODE_ABIFLAG;
+ pps->kernel_abi = PPS_ABI_VERSION;
+ }
}
void
diff --git a/sys/kern/subr_nvlist.c b/sys/kern/subr_nvlist.c
index f96b8905d869..40e49ffa9954 100644
--- a/sys/kern/subr_nvlist.c
+++ b/sys/kern/subr_nvlist.c
@@ -88,7 +88,7 @@ __FBSDID("$FreeBSD$");
#endif
#define NV_FLAG_PRIVATE_MASK (NV_FLAG_BIG_ENDIAN)
-#define NV_FLAG_PUBLIC_MASK (NV_FLAG_IGNORE_CASE)
+#define NV_FLAG_PUBLIC_MASK (NV_FLAG_IGNORE_CASE | NV_FLAG_NO_UNIQUE)
#define NV_FLAG_ALL_MASK (NV_FLAG_PRIVATE_MASK | NV_FLAG_PUBLIC_MASK)
#define NVLIST_MAGIC 0x6e766c /* "nvl" */
@@ -129,6 +129,8 @@ nvlist_create(int flags)
PJDLOG_ASSERT((flags & ~(NV_FLAG_PUBLIC_MASK)) == 0);
nvl = nv_malloc(sizeof(*nvl));
+ if (nvl == NULL)
+ return (NULL);
nvl->nvl_error = 0;
nvl->nvl_flags = flags;
nvl->nvl_parent = NULL;
@@ -774,7 +776,8 @@ failed:
}
static nvlist_t *
-nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds)
+nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds,
+ int flags)
{
const unsigned char *ptr;
nvlist_t *nvl, *retnvl, *tmpnvl;
@@ -782,6 +785,8 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds)
size_t left;
bool isbe;
+ PJDLOG_ASSERT((flags & ~(NV_FLAG_PUBLIC_MASK)) == 0);
+
left = size;
ptr = buf;
@@ -793,6 +798,10 @@ nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds)
ptr = nvlist_unpack_header(nvl, ptr, nfds, &isbe, &left);
if (ptr == NULL)
goto failed;
+ if (nvl->nvl_flags != flags) {
+ ERRNO_SET(EILSEQ);
+ goto failed;
+ }
while (left > 0) {
ptr = nvpair_unpack(isbe, ptr, &left, &nvp);
@@ -849,10 +858,10 @@ failed:
}
nvlist_t *
-nvlist_unpack(const void *buf, size_t size)
+nvlist_unpack(const void *buf, size_t size, int flags)
{
- return (nvlist_xunpack(buf, size, NULL, 0));
+ return (nvlist_xunpack(buf, size, NULL, 0, flags));
}
#ifndef _KERNEL
@@ -900,7 +909,7 @@ out:
}
nvlist_t *
-nvlist_recv(int sock)
+nvlist_recv(int sock, int flags)
{
struct nvlist_header nvlhdr;
nvlist_t *nvl, *ret;
@@ -937,7 +946,7 @@ nvlist_recv(int sock)
goto out;
}
- nvl = nvlist_xunpack(buf, size, fds, nfds);
+ nvl = nvlist_xunpack(buf, size, fds, nfds, flags);
if (nvl == NULL) {
ERRNO_SAVE();
for (i = 0; i < nfds; i++)
@@ -957,7 +966,7 @@ out:
}
nvlist_t *
-nvlist_xfer(int sock, nvlist_t *nvl)
+nvlist_xfer(int sock, nvlist_t *nvl, int flags)
{
if (nvlist_send(sock, nvl) < 0) {
@@ -965,7 +974,7 @@ nvlist_xfer(int sock, nvlist_t *nvl)
return (NULL);
}
nvlist_destroy(nvl);
- return (nvlist_recv(sock));
+ return (nvlist_recv(sock, flags));
}
#endif
@@ -1067,10 +1076,12 @@ nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp)
ERRNO_SET(nvlist_error(nvl));
return;
}
- if (nvlist_exists(nvl, nvpair_name(nvp))) {
- nvl->nvl_error = EEXIST;
- ERRNO_SET(nvlist_error(nvl));
- return;
+ if ((nvl->nvl_flags & NV_FLAG_NO_UNIQUE) == 0) {
+ if (nvlist_exists(nvl, nvpair_name(nvp))) {
+ nvl->nvl_error = EEXIST;
+ ERRNO_SET(nvlist_error(nvl));
+ return;
+ }
}
newnvp = nvpair_clone(nvp);
@@ -1133,45 +1144,8 @@ nvlist_add_null(nvlist_t *nvl, const char *name)
}
void
-nvlist_add_bool(nvlist_t *nvl, const char *name, bool value)
-{
- nvpair_t *nvp;
-
- if (nvlist_error(nvl) != 0) {
- ERRNO_SET(nvlist_error(nvl));
- return;
- }
-
- nvp = nvpair_create_bool(name, value);
- if (nvp == NULL) {
- nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- ERRNO_SET(nvl->nvl_error);
- } else {
- nvlist_move_nvpair(nvl, nvp);
- }
-}
-
-void
-nvlist_add_number(nvlist_t *nvl, const char *name, uint64_t value)
-{
- nvpair_t *nvp;
-
- if (nvlist_error(nvl) != 0) {
- ERRNO_SET(nvlist_error(nvl));
- return;
- }
-
- nvp = nvpair_create_number(name, value);
- if (nvp == NULL) {
- nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- ERRNO_SET(nvl->nvl_error);
- } else {
- nvlist_move_nvpair(nvl, nvp);
- }
-}
-
-void
-nvlist_add_string(nvlist_t *nvl, const char *name, const char *value)
+nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value,
+ size_t size)
{
nvpair_t *nvp;
@@ -1180,7 +1154,7 @@ nvlist_add_string(nvlist_t *nvl, const char *name, const char *value)
return;
}
- nvp = nvpair_create_string(name, value);
+ nvp = nvpair_create_binary(name, value, size);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
ERRNO_SET(nvl->nvl_error);
@@ -1189,63 +1163,36 @@ nvlist_add_string(nvlist_t *nvl, const char *name, const char *value)
}
}
-void
-nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *value)
-{
- nvpair_t *nvp;
-
- if (nvlist_error(nvl) != 0) {
- ERRNO_SET(nvlist_error(nvl));
- return;
- }
- nvp = nvpair_create_nvlist(name, value);
- if (nvp == NULL) {
- nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- ERRNO_SET(nvl->nvl_error);
- } else {
- nvlist_move_nvpair(nvl, nvp);
- }
+#define NVLIST_ADD(vtype, type) \
+void \
+nvlist_add_##type(nvlist_t *nvl, const char *name, vtype value) \
+{ \
+ nvpair_t *nvp; \
+ \
+ if (nvlist_error(nvl) != 0) { \
+ ERRNO_SET(nvlist_error(nvl)); \
+ return; \
+ } \
+ \
+ nvp = nvpair_create_##type(name, value); \
+ if (nvp == NULL) { \
+ nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); \
+ ERRNO_SET(nvl->nvl_error); \
+ } else { \
+ nvlist_move_nvpair(nvl, nvp); \
+ } \
}
+NVLIST_ADD(bool, bool)
+NVLIST_ADD(uint64_t, number)
+NVLIST_ADD(const char *, string)
+NVLIST_ADD(const nvlist_t *, nvlist)
#ifndef _KERNEL
-void
-nvlist_add_descriptor(nvlist_t *nvl, const char *name, int value)
-{
- nvpair_t *nvp;
-
- if (nvlist_error(nvl) != 0) {
- errno = nvlist_error(nvl);
- return;
- }
-
- nvp = nvpair_create_descriptor(name, value);
- if (nvp == NULL)
- nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
- else
- nvlist_move_nvpair(nvl, nvp);
-}
+NVLIST_ADD(int, descriptor);
#endif
-void
-nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value,
- size_t size)
-{
- nvpair_t *nvp;
-
- if (nvlist_error(nvl) != 0) {
- ERRNO_SET(nvlist_error(nvl));
- return;
- }
-
- nvp = nvpair_create_binary(name, value, size);
- if (nvp == NULL) {
- nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- ERRNO_SET(nvl->nvl_error);
- } else {
- nvlist_move_nvpair(nvl, nvp);
- }
-}
+#undef NVLIST_ADD
void
nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp)
@@ -1259,11 +1206,13 @@ nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp)
ERRNO_SET(nvlist_error(nvl));
return;
}
- if (nvlist_exists(nvl, nvpair_name(nvp))) {
- nvpair_free(nvp);
- nvl->nvl_error = EEXIST;
- ERRNO_SET(nvl->nvl_error);
- return;
+ if ((nvl->nvl_flags & NV_FLAG_NO_UNIQUE) == 0) {
+ if (nvlist_exists(nvl, nvpair_name(nvp))) {
+ nvpair_free(nvp);
+ nvl->nvl_error = EEXIST;
+ ERRNO_SET(nvl->nvl_error);
+ return;
+ }
}
nvpair_insert(&nvl->nvl_head, nvp, nvl);
diff --git a/sys/kern/subr_nvpair.c b/sys/kern/subr_nvpair.c
index b0fc322190f3..cde08e6004c9 100644
--- a/sys/kern/subr_nvpair.c
+++ b/sys/kern/subr_nvpair.c
@@ -143,7 +143,8 @@ nvpair_insert(struct nvl_head *head, nvpair_t *nvp, nvlist_t *nvl)
NVPAIR_ASSERT(nvp);
PJDLOG_ASSERT(nvp->nvp_list == NULL);
- PJDLOG_ASSERT(!nvlist_exists(nvl, nvpair_name(nvp)));
+ PJDLOG_ASSERT((nvlist_flags(nvl) & NV_FLAG_NO_UNIQUE) != 0 ||
+ !nvlist_exists(nvl, nvpair_name(nvp)));
TAILQ_INSERT_TAIL(head, nvp, nvp_next);
nvp->nvp_list = nvl;
@@ -733,7 +734,7 @@ nvpair_allocv(const char *name, int type, uint64_t data, size_t datasize)
if (nvp != NULL) {
nvp->nvp_name = (char *)(nvp + 1);
memcpy(nvp->nvp_name, name, namelen);
- nvp->nvp_name[namelen + 1] = '\0';
+ nvp->nvp_name[namelen] = '\0';
nvp->nvp_type = type;
nvp->nvp_data = data;
nvp->nvp_datasize = datasize;
diff --git a/sys/net/if_types.h b/sys/net/if_types.h
index df019e062e45..92e101ac6af4 100644
--- a/sys/net/if_types.h
+++ b/sys/net/if_types.h
@@ -254,4 +254,20 @@ typedef enum {
IFT_PFLOG = 0xf6, /* PF packet filter logging */
IFT_PFSYNC = 0xf7, /* PF packet filter synchronization */
} ifType;
+
+/*
+ * Some (broken) software uses #ifdef IFT_TYPE to check whether
+ * an operating systems supports certain interface type. Lack of
+ * ifdef leads to a piece of functionality compiled out.
+ */
+#ifndef BURN_BRIDGES
+#define IFT_BRIDGE IFT_BRIDGE
+#define IFT_PPP IFT_PPP
+#define IFT_PROPVIRTUAL IFT_PROPVIRTUAL
+#define IFT_L2VLAN IFT_L2VLAN
+#define IFT_L3IPVLAN IFT_L3IPVLAN
+#define IFT_IEEE1394 IFT_IEEE1394
+#define IFT_INFINIBAND IFT_INFINIBAND
+#endif
+
#endif /* !_NET_IF_TYPES_H_ */
diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
index c1b4b518a289..049d952970fa 100644
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -229,6 +229,8 @@ adhoc_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
}
#endif
break;
+ case IEEE80211_S_RUN: /* IBSS merge */
+ break;
default:
goto invalid;
}
@@ -369,7 +371,10 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
/*
* Validate the bssid.
*/
- if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bss->ni_bssid) &&
+ if (!(type == IEEE80211_FC0_TYPE_MGT &&
+ (subtype == IEEE80211_FC0_SUBTYPE_BEACON ||
+ subtype == IEEE80211_FC0_SUBTYPE_PROBE_REQ)) &&
+ !IEEE80211_ADDR_EQ(bssid, vap->iv_bss->ni_bssid) &&
!IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) {
/* not interested in */
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
@@ -409,7 +414,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
}
IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
ni->ni_noise = nf;
- if (HAS_SEQ(type)) {
+ if (HAS_SEQ(type) && IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
uint8_t tid = ieee80211_gettid(wh);
if (IEEE80211_QOS_HAS_SEQ(wh) &&
TID_TO_WME_AC(tid) >= WME_AC_VI)
diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
index 711bac348234..aa21f3b9e218 100644
--- a/sys/net80211/ieee80211_freebsd.h
+++ b/sys/net80211/ieee80211_freebsd.h
@@ -355,8 +355,8 @@ wlan_##name##_modevent(module_t mod, int type, void *unused) \
case MOD_UNLOAD: \
case MOD_QUIESCE: \
if (nrefs) { \
- printf("wlan_##name: still in use (%u dynamic refs)\n",\
- nrefs); \
+ printf("wlan_" #name ": still in use " \
+ "(%u dynamic refs)\n", nrefs); \
return EBUSY; \
} \
if (type == MOD_UNLOAD) { \
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index 9fc4cd4d3157..c84f9a8e5685 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -93,6 +93,8 @@ static void node_getmimoinfo(const struct ieee80211_node *,
static void _ieee80211_free_node(struct ieee80211_node *);
+static void node_reclaim(struct ieee80211_node_table *nt,
+ struct ieee80211_node *ni);
static void ieee80211_node_table_init(struct ieee80211com *ic,
struct ieee80211_node_table *nt, const char *name,
int inact, int keymaxix);
@@ -719,9 +721,15 @@ ieee80211_sta_join1(struct ieee80211_node *selbs)
IEEE80211_ADDR_EQ(obss->ni_macaddr, selbs->ni_macaddr));
vap->iv_bss = selbs; /* NB: caller assumed to bump refcnt */
if (obss != NULL) {
+ struct ieee80211_node_table *nt = obss->ni_table;
+
copy_bss(selbs, obss);
ieee80211_node_decref(obss); /* iv_bss reference */
- ieee80211_free_node(obss); /* station table reference */
+
+ IEEE80211_NODE_LOCK(nt);
+ node_reclaim(nt, obss); /* station table reference */
+ IEEE80211_NODE_UNLOCK(nt);
+
obss = NULL; /* NB: guard against later use */
}
@@ -871,7 +879,7 @@ ieee80211_sta_leave(struct ieee80211_node *ni)
void
ieee80211_node_deauth(struct ieee80211_node *ni, int reason)
{
- /* NB: bump the refcnt to be sure temporay nodes are not reclaimed */
+ /* NB: bump the refcnt to be sure temporary nodes are not reclaimed */
ieee80211_ref_node(ni);
if (ni->ni_associd != 0)
IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DEAUTH, reason);
@@ -1749,6 +1757,28 @@ _ieee80211_free_node(struct ieee80211_node *ni)
ni->ni_ic->ic_node_free(ni);
}
+/*
+ * Clear any entry in the unicast key mapping table.
+ */
+static int
+node_clear_keyixmap(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
+{
+ ieee80211_keyix keyix;
+
+ keyix = ni->ni_ucastkey.wk_rxkeyix;
+ if (nt->nt_keyixmap != NULL && keyix < nt->nt_keyixmax &&
+ nt->nt_keyixmap[keyix] == ni) {
+ IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,
+ "%s: %p<%s> clear key map entry %u\n",
+ __func__, ni, ether_sprintf(ni->ni_macaddr), keyix);
+ nt->nt_keyixmap[keyix] = NULL;
+ ieee80211_node_decref(ni);
+ return 1;
+ }
+
+ return 0;
+}
+
void
#ifdef IEEE80211_DEBUG_REFCNT
ieee80211_free_node_debug(struct ieee80211_node *ni, const char *func, int line)
@@ -1770,24 +1800,9 @@ ieee80211_free_node(struct ieee80211_node *ni)
* Last reference, reclaim state.
*/
_ieee80211_free_node(ni);
- } else if (ieee80211_node_refcnt(ni) == 1 &&
- nt->nt_keyixmap != NULL) {
- ieee80211_keyix keyix;
- /*
- * Check for a last reference in the key mapping table.
- */
- keyix = ni->ni_ucastkey.wk_rxkeyix;
- if (keyix < nt->nt_keyixmax &&
- nt->nt_keyixmap[keyix] == ni) {
- IEEE80211_DPRINTF(ni->ni_vap,
- IEEE80211_MSG_NODE,
- "%s: %p<%s> clear key map entry", __func__,
- ni, ether_sprintf(ni->ni_macaddr));
- nt->nt_keyixmap[keyix] = NULL;
- ieee80211_node_decref(ni); /* XXX needed? */
+ } else if (ieee80211_node_refcnt(ni) == 1)
+ if (node_clear_keyixmap(nt, ni))
_ieee80211_free_node(ni);
- }
- }
IEEE80211_NODE_UNLOCK(nt);
} else {
if (ieee80211_node_dectestref(ni))
@@ -1855,7 +1870,6 @@ ieee80211_node_delucastkey(struct ieee80211_node *ni)
static void
node_reclaim(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
{
- ieee80211_keyix keyix;
IEEE80211_NODE_LOCK_ASSERT(nt);
@@ -1870,15 +1884,7 @@ node_reclaim(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
* table. We cannot depend on the mapping table entry
* being cleared because the node may not be free'd.
*/
- keyix = ni->ni_ucastkey.wk_rxkeyix;
- if (nt->nt_keyixmap != NULL && keyix < nt->nt_keyixmax &&
- nt->nt_keyixmap[keyix] == ni) {
- IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,
- "%s: %p<%s> clear key map entry %u\n",
- __func__, ni, ether_sprintf(ni->ni_macaddr), keyix);
- nt->nt_keyixmap[keyix] = NULL;
- ieee80211_node_decref(ni); /* NB: don't need free */
- }
+ (void)node_clear_keyixmap(nt, ni);
if (!ieee80211_node_dectestref(ni)) {
/*
* Other references are present, just remove the
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index be5106aa3ec7..d2570c4a2b1b 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1997,18 +1997,9 @@ in6_if2idlen(struct ifnet *ifp)
{
switch (ifp->if_type) {
case IFT_ETHER: /* RFC2464 */
-#ifdef IFT_PROPVIRTUAL
case IFT_PROPVIRTUAL: /* XXX: no RFC. treat it as ether */
-#endif
-#ifdef IFT_L2VLAN
case IFT_L2VLAN: /* ditto */
-#endif
-#ifdef IFT_IEEE80211
case IFT_IEEE80211: /* ditto */
-#endif
-#ifdef IFT_MIP
- case IFT_MIP: /* ditto */
-#endif
case IFT_INFINIBAND:
return (64);
case IFT_FDDI: /* RFC2467 */
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 06d931b297c6..8c25e982cdeb 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -274,9 +274,7 @@ found:
case IFT_ISO88025:
case IFT_ATM:
case IFT_IEEE1394:
-#ifdef IFT_IEEE80211
case IFT_IEEE80211:
-#endif
/* IEEE802/EUI64 cases - what others? */
/* IEEE1394 uses 16byte length address starting with EUI64 */
if (addrlen > 8)
@@ -338,9 +336,7 @@ found:
break;
case IFT_GIF:
-#ifdef IFT_STF
case IFT_STF:
-#endif
/*
* RFC2893 says: "SHOULD use IPv4 address as ifid source".
* however, IPv4 address is not very suitable as unique
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index a344d6a2ae1d..83dda1a18427 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -2145,12 +2145,8 @@ nd6_need_cache(struct ifnet *ifp)
case IFT_ETHER:
case IFT_FDDI:
case IFT_IEEE1394:
-#ifdef IFT_L2VLAN
case IFT_L2VLAN:
-#endif
-#ifdef IFT_IEEE80211
case IFT_IEEE80211:
-#endif
case IFT_INFINIBAND:
case IFT_BRIDGE:
case IFT_PROPVIRTUAL:
@@ -2235,12 +2231,8 @@ nd6_storelladdr(struct ifnet *ifp, struct mbuf *m,
switch (ifp->if_type) {
case IFT_ETHER:
case IFT_FDDI:
-#ifdef IFT_L2VLAN
case IFT_L2VLAN:
-#endif
-#ifdef IFT_IEEE80211
case IFT_IEEE80211:
-#endif
case IFT_BRIDGE:
case IFT_ISO88025:
ETHER_MAP_IPV6_MULTICAST(&SIN6(dst)->sin6_addr,
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 4b160f74f805..a4ae618bb37d 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -1149,12 +1149,8 @@ nd6_ifptomac(struct ifnet *ifp)
case IFT_ETHER:
case IFT_FDDI:
case IFT_IEEE1394:
-#ifdef IFT_L2VLAN
case IFT_L2VLAN:
-#endif
-#ifdef IFT_IEEE80211
case IFT_IEEE80211:
-#endif
case IFT_INFINIBAND:
case IFT_BRIDGE:
case IFT_ISO88025:
@@ -1549,9 +1545,7 @@ nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp)
case IFT_FDDI:
case IFT_ATM:
case IFT_IEEE1394:
-#ifdef IFT_IEEE80211
case IFT_IEEE80211:
-#endif
case IFT_INFINIBAND:
in6 = ia->ia_addr.sin6_addr;
if (in6_get_hw_ifid(ifp, &in6) == 0 &&
diff --git a/sys/netpfil/ipfw/ip_fw_table.c b/sys/netpfil/ipfw/ip_fw_table.c
index ca4e0e4c3ea9..f9425415c3c4 100644
--- a/sys/netpfil/ipfw/ip_fw_table.c
+++ b/sys/netpfil/ipfw/ip_fw_table.c
@@ -597,19 +597,21 @@ restart:
/* Pass stack buffer by default */
ta_buf_m = ta_buf;
error = prepare_batch_buffer(ch, ta, tei, count, OP_ADD, &ta_buf_m);
- if (error != 0)
- goto cleanup;
IPFW_UH_WLOCK(ch);
+ del_toperation_state(ch, &ts);
/* Drop reference we've used in first search */
tc->no.refcnt--;
+ /* Check prepare_batch_buffer() error */
+ if (error != 0)
+ goto cleanup;
+
/*
* Check if table swap has happened.
* (so table algo might be changed).
* Restart operation to achieve consistent behavior.
*/
- del_toperation_state(ch, &ts);
if (ts.modified != 0)
goto restart;
diff --git a/sys/ofed/include/linux/linux_idr.c b/sys/ofed/include/linux/linux_idr.c
index 809e1784e5b7..a692fb8e7ecd 100644
--- a/sys/ofed/include/linux/linux_idr.c
+++ b/sys/ofed/include/linux/linux_idr.c
@@ -185,27 +185,37 @@ out:
return (res);
}
-void *
-idr_find(struct idr *idr, int id)
+static inline void *
+idr_find_locked(struct idr *idr, int id)
{
struct idr_layer *il;
void *res;
int layer;
- res = NULL;
+ mtx_assert(&idr->lock, MA_OWNED);
+
id &= MAX_ID_MASK;
- mtx_lock(&idr->lock);
+ res = NULL;
il = idr->top;
layer = idr->layers - 1;
if (il == NULL || id > idr_max(idr))
- goto out;
+ return (NULL);
while (layer && il) {
il = il->ary[idr_pos(id, layer)];
layer--;
}
if (il != NULL)
res = il->ary[id & IDR_MASK];
-out:
+ return (res);
+}
+
+void *
+idr_find(struct idr *idr, int id)
+{
+ void *res;
+
+ mtx_lock(&idr->lock);
+ res = idr_find_locked(idr, id);
mtx_unlock(&idr->lock);
return (res);
}
@@ -331,13 +341,13 @@ idr_get_new(struct idr *idr, void *ptr, int *idp)
}
error = 0;
out:
- mtx_unlock(&idr->lock);
#ifdef INVARIANTS
- if (error == 0 && idr_find(idr, id) != ptr) {
+ if (error == 0 && idr_find_locked(idr, id) != ptr) {
panic("idr_get_new: Failed for idr %p, id %d, ptr %p\n",
idr, id, ptr);
}
#endif
+ mtx_unlock(&idr->lock);
return (error);
}
@@ -438,12 +448,12 @@ restart:
}
error = 0;
out:
- mtx_unlock(&idr->lock);
#ifdef INVARIANTS
- if (error == 0 && idr_find(idr, id) != ptr) {
+ if (error == 0 && idr_find_locked(idr, id) != ptr) {
panic("idr_get_new_above: Failed for idr %p, id %d, ptr %p\n",
idr, id, ptr);
}
#endif
+ mtx_unlock(&idr->lock);
return (error);
}
diff --git a/sys/sys/diskmbr.h b/sys/sys/diskmbr.h
index cb05ffa5462c..5f49eb9e8d06 100644
--- a/sys/sys/diskmbr.h
+++ b/sys/sys/diskmbr.h
@@ -51,11 +51,13 @@
#define DOSPTYP_EXTLBA 0x0f /* DOS extended partition */
#define DOSPTYP_PPCBOOT 0x41 /* PReP/CHRP boot partition */
#define DOSPTYP_LDM 0x42 /* Win2k dynamic extended partition */
-#define DOSPTYP_386BSD 0xa5 /* 386BSD partition type */
-#define DOSPTYP_HFS 0xaf /* HFS/HFS+ partition type */
#define DOSPTYP_LINSWP 0x82 /* Linux swap partition */
#define DOSPTYP_LINUX 0x83 /* Linux partition */
#define DOSPTYP_LINLVM 0x8e /* Linux LVM partition */
+#define DOSPTYP_386BSD 0xa5 /* 386BSD partition type */
+#define DOSPTYP_APPLE_UFS 0xa8 /* Apple Mac OS X boot */
+#define DOSPTYP_APPLE_BOOT 0xab /* Apple Mac OS X UFS */
+#define DOSPTYP_HFS 0xaf /* HFS/HFS+ partition type */
#define DOSPTYP_PMBR 0xee /* GPT Protective MBR */
#define DOSPTYP_EFI 0xef /* EFI FAT parition */
#define DOSPTYP_VMFS 0xfb /* VMware VMFS partition */
diff --git a/sys/sys/nv.h b/sys/sys/nv.h
index 5c342dced820..fa5d1385eaf6 100644
--- a/sys/sys/nv.h
+++ b/sys/sys/nv.h
@@ -64,6 +64,10 @@ typedef struct nvlist nvlist_t;
* Perform case-insensitive lookups of provided names.
*/
#define NV_FLAG_IGNORE_CASE 0x01
+/*
+ * Names don't have to be unique.
+ */
+#define NV_FLAG_NO_UNIQUE 0x02
#if defined(_KERNEL) && defined(MALLOC_DECLARE)
MALLOC_DECLARE(M_NVLIST);
@@ -87,11 +91,11 @@ void nvlist_fdump(const nvlist_t *nvl, FILE *fp);
size_t nvlist_size(const nvlist_t *nvl);
void *nvlist_pack(const nvlist_t *nvl, size_t *sizep);
-nvlist_t *nvlist_unpack(const void *buf, size_t size);
+nvlist_t *nvlist_unpack(const void *buf, size_t size, int flags);
int nvlist_send(int sock, const nvlist_t *nvl);
-nvlist_t *nvlist_recv(int sock);
-nvlist_t *nvlist_xfer(int sock, nvlist_t *nvl);
+nvlist_t *nvlist_recv(int sock, int flags);
+nvlist_t *nvlist_xfer(int sock, nvlist_t *nvl, int flags);
const char *nvlist_next(const nvlist_t *nvl, int *typep, void **cookiep);
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 867dbf1b8807..bc722df6f25a 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1100071 /* Master, propagated to newvers */
+#define __FreeBSD_version 1100072 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/timepps.h b/sys/sys/timepps.h
index ae4b84d17d77..d472c804dc43 100644
--- a/sys/sys/timepps.h
+++ b/sys/sys/timepps.h
@@ -135,6 +135,13 @@ struct pps_kcbind_args {
struct mtx;
+#define KCMODE_EDGEMASK 0x03
+#define KCMODE_ABIFLAG 0x80000000 /* Internal use: abi-aware driver. */
+
+#define PPS_ABI_VERSION 1
+
+#define PPSFLAG_MTX_SPIN 0x01 /* Driver mtx is MTX_SPIN type. */
+
struct pps_state {
/* Capture information. */
struct timehands *capth;
@@ -142,9 +149,6 @@ struct pps_state {
unsigned capgen;
unsigned capcount;
- /* pointer to mutex protecting this state, if any */
- struct mtx *mtx;
-
/* State information. */
pps_params_t ppsparam;
pps_info_t ppsinfo;
@@ -153,11 +157,19 @@ struct pps_state {
int ppscap;
struct timecounter *ppstc;
unsigned ppscount[3];
+ /*
+ * The following fields are valid if the driver calls pps_init_abi().
+ */
+ uint16_t driver_abi; /* Driver sets before pps_init_abi(). */
+ uint16_t kernel_abi; /* Kernel sets during pps_init_abi(). */
+ struct mtx *driver_mtx; /* Optional, valid if non-NULL. */
+ uint32_t flags;
};
void pps_capture(struct pps_state *pps);
void pps_event(struct pps_state *pps, int event);
void pps_init(struct pps_state *pps);
+void pps_init_abi(struct pps_state *pps);
int pps_ioctl(unsigned long cmd, caddr_t data, struct pps_state *pps);
void hardpps(struct timespec *tsp, long nsec);
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 15e5b245a82c..9a83989a894a 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -328,17 +328,16 @@ static int nsw_wcount_async; /* limit write buffers / asynchronous */
static int nsw_wcount_async_max;/* assigned maximum */
static int nsw_cluster_max; /* maximum VOP I/O allowed */
+static int sysctl_swap_async_max(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_vm, OID_AUTO, swap_async_max, CTLTYPE_INT | CTLFLAG_RW,
+ NULL, 0, sysctl_swap_async_max, "I", "Maximum running async swap ops");
+
static struct swblock **swhash;
static int swhash_mask;
static struct mtx swhash_mtx;
-static int swap_async_max = 4; /* maximum in-progress async I/O's */
static struct sx sw_alloc_sx;
-
-SYSCTL_INT(_vm, OID_AUTO, swap_async_max,
- CTLFLAG_RW, &swap_async_max, 0, "Maximum running async swap ops");
-
/*
* "named" and "unnamed" anon region objects. Try to reduce the overhead
* of searching a named list by hashing it just a little.
@@ -1350,39 +1349,6 @@ swap_pager_putpages(vm_object_t object, vm_page_t *m, int count,
/*
* Step 2
*
- * Update nsw parameters from swap_async_max sysctl values.
- * Do not let the sysop crash the machine with bogus numbers.
- */
- mtx_lock(&pbuf_mtx);
- if (swap_async_max != nsw_wcount_async_max) {
- int n;
-
- /*
- * limit range
- */
- if ((n = swap_async_max) > nswbuf / 2)
- n = nswbuf / 2;
- if (n < 1)
- n = 1;
- swap_async_max = n;
-
- /*
- * Adjust difference ( if possible ). If the current async
- * count is too low, we may not be able to make the adjustment
- * at this time.
- */
- n -= nsw_wcount_async_max;
- if (nsw_wcount_async + n >= 0) {
- nsw_wcount_async += n;
- nsw_wcount_async_max += n;
- wakeup(&nsw_wcount_async);
- }
- }
- mtx_unlock(&pbuf_mtx);
-
- /*
- * Step 3
- *
* Assign swap blocks and issue I/O. We reallocate swap on the fly.
* The page is left dirty until the pageout operation completes
* successfully.
@@ -2835,3 +2801,40 @@ swaponvp(struct thread *td, struct vnode *vp, u_long nblks)
NODEV, 0);
return (0);
}
+
+static int
+sysctl_swap_async_max(SYSCTL_HANDLER_ARGS)
+{
+ int error, new, n;
+
+ new = nsw_wcount_async_max;
+ error = sysctl_handle_int(oidp, &new, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+
+ if (new > nswbuf / 2 || new < 1)
+ return (EINVAL);
+
+ mtx_lock(&pbuf_mtx);
+ while (nsw_wcount_async_max != new) {
+ /*
+ * Adjust difference. If the current async count is too low,
+ * we will need to sqeeze our update slowly in. Sleep with a
+ * higher priority than getpbuf() to finish faster.
+ */
+ n = new - nsw_wcount_async_max;
+ if (nsw_wcount_async + n >= 0) {
+ nsw_wcount_async += n;
+ nsw_wcount_async_max += n;
+ wakeup(&nsw_wcount_async);
+ } else {
+ nsw_wcount_async_max -= nsw_wcount_async;
+ nsw_wcount_async = 0;
+ msleep(&nsw_wcount_async, &pbuf_mtx, PSWP,
+ "swpsysctl", 0);
+ }
+ }
+ mtx_unlock(&pbuf_mtx);
+
+ return (0);
+}
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index 2878dc3b0b9b..c59f81adae82 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -340,16 +340,21 @@ vnode_pager_haspage(vm_object_t object, vm_pindex_t pindex, int *before,
*before += poff;
}
if (after) {
- int numafter;
+ /*
+ * The BMAP vop can report a partial block in the
+ * 'after', but must not report blocks after EOF.
+ * Assert the latter, and truncate 'after' in case
+ * of the former.
+ */
+ KASSERT((reqblock + *after) * pagesperblock <
+ roundup2(object->size, pagesperblock),
+ ("%s: reqblock %jd after %d size %ju", __func__,
+ (intmax_t )reqblock, *after,
+ (uintmax_t )object->size));
*after *= pagesperblock;
- numafter = pagesperblock - (poff + 1);
- if (IDX_TO_OFF(pindex + numafter) >
- object->un_pager.vnp.vnp_size) {
- numafter =
- OFF_TO_IDX(object->un_pager.vnp.vnp_size) -
- pindex;
- }
- *after += numafter;
+ *after += pagesperblock - (poff + 1);
+ if (pindex + *after >= object->size)
+ *after = object->size - 1 - pindex;
}
} else {
if (before) {
diff --git a/sys/x86/include/specialreg.h b/sys/x86/include/specialreg.h
index 60f46fb68e59..a771fffaea57 100644
--- a/sys/x86/include/specialreg.h
+++ b/sys/x86/include/specialreg.h
@@ -82,6 +82,9 @@
#define EFER_LMA 0x000000400 /* Long mode active (R) */
#define EFER_NXE 0x000000800 /* PTE No-Execute bit enable (R/W) */
#define EFER_SVM 0x000001000 /* SVM enable bit for AMD, reserved for Intel */
+#define EFER_LMSLE 0x000002000 /* Long Mode Segment Limit Enable */
+#define EFER_FFXSR 0x000004000 /* Fast FXSAVE/FSRSTOR */
+#define EFER_TCE 0x000008000 /* Translation Cache Extension */
/*
* Intel Extended Features registers
@@ -191,7 +194,7 @@
#define AMDID_MP 0x00080000
#define AMDID_NX 0x00100000
#define AMDID_EXT_MMX 0x00400000
-#define AMDID_FFXSR 0x01000000
+#define AMDID_FFXSR 0x02000000
#define AMDID_PAGE1GB 0x04000000
#define AMDID_RDTSCP 0x08000000
#define AMDID_LM 0x20000000