summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2012-07-12 02:15:06 +0000
committerattilio <attilio@FreeBSD.org>2012-07-12 02:15:06 +0000
commitcc7c02f8bf91a669b803d07125980d38f96161f8 (patch)
treea8be73b1e54943d7b641db517dd1279f6f8a7510 /sys
parenta23ed68137cccbe53a9340dbc1de0779d2518589 (diff)
parent675a214708d3e1fb79cbcf6bd8a46e0f1cc4823d (diff)
downloadFreeBSD-src-cc7c02f8bf91a669b803d07125980d38f96161f8.zip
FreeBSD-src-cc7c02f8bf91a669b803d07125980d38f96161f8.tar.gz
Merge from vmcontention
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/fpu.c9
-rw-r--r--sys/amd64/amd64/machdep.c3
-rw-r--r--sys/amd64/amd64/mem.c2
-rw-r--r--sys/amd64/include/cpufunc.h10
-rw-r--r--sys/arm/at91/at91.c43
-rw-r--r--sys/arm/at91/at91_machdep.c106
-rw-r--r--sys/arm/at91/at91_mci.c2
-rw-r--r--sys/arm/at91/at91_pit.c35
-rw-r--r--sys/arm/at91/at91_pitreg.h8
-rw-r--r--sys/arm/at91/at91_reset.S7
-rw-r--r--sys/arm/at91/at91_rst.c61
-rw-r--r--sys/arm/at91/at91_rstreg.h10
-rw-r--r--sys/arm/at91/at91_st.c212
-rw-r--r--sys/arm/at91/at91_streg.h3
-rw-r--r--sys/arm/at91/at91reg.h2
-rw-r--r--sys/arm/at91/at91rm9200.c58
-rw-r--r--sys/arm/at91/at91rm92reg.h1
-rw-r--r--sys/arm/at91/at91sam9260.c59
-rw-r--r--sys/arm/at91/at91sam9260reg.h2
-rw-r--r--sys/arm/at91/at91sam9g20.c57
-rw-r--r--sys/arm/at91/at91sam9g20reg.h2
-rw-r--r--sys/arm/at91/at91sam9x25.c72
-rw-r--r--sys/arm/at91/at91sam9x25reg.h2
-rw-r--r--sys/arm/at91/at91soc.c51
-rw-r--r--sys/arm/at91/at91soc.h58
-rw-r--r--sys/arm/at91/at91var.h23
-rw-r--r--sys/arm/at91/files.at911
-rw-r--r--sys/arm/at91/uart_bus_at91usart.c15
-rw-r--r--sys/arm/at91/uart_cpu_at91rm9200usart.c2
-rw-r--r--sys/arm/conf/KB920X3
-rw-r--r--sys/arm/econa/econa_machdep.c5
-rw-r--r--sys/arm/mv/mv_machdep.c6
-rw-r--r--sys/arm/s3c2xx0/s3c24x0_machdep.c9
-rw-r--r--sys/arm/sa11x0/assabet_machdep.c5
-rw-r--r--sys/arm/xscale/i80321/ep80219_machdep.c5
-rw-r--r--sys/arm/xscale/i80321/iq31244_machdep.c5
-rw-r--r--sys/arm/xscale/i8134x/crb_machdep.c2
-rw-r--r--sys/arm/xscale/ixp425/avila_machdep.c5
-rw-r--r--sys/arm/xscale/pxa/pxa_machdep.c5
-rw-r--r--sys/arm/xscale/std.xscale2
-rw-r--r--sys/cam/ata/ata_all.c4
-rw-r--r--sys/cam/ata/ata_da.c4
-rw-r--r--sys/cam/scsi/scsi_da.c4
-rw-r--r--sys/conf/files2
-rw-r--r--sys/contrib/dev/acpica/changes.txt78
-rw-r--r--sys/contrib/dev/acpica/compiler/aslmain.c9
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbcmds.c101
-rw-r--r--sys/contrib/dev/acpica/components/debugger/dbinput.c4
-rw-r--r--sys/contrib/dev/acpica/components/events/evxfgpe.c14
-rw-r--r--sys/contrib/dev/acpica/components/executer/exprep.c4
-rw-r--r--sys/contrib/dev/acpica/components/executer/exresolv.c2
-rw-r--r--sys/contrib/dev/acpica/components/executer/exstore.c6
-rw-r--r--sys/contrib/dev/acpica/components/executer/exutils.c2
-rw-r--r--sys/contrib/dev/acpica/components/hardware/hwsleep.c25
-rw-r--r--sys/contrib/dev/acpica/components/hardware/hwxfsleep.c8
-rw-r--r--sys/contrib/dev/acpica/components/namespace/nspredef.c2
-rw-r--r--sys/contrib/dev/acpica/components/parser/psxface.c4
-rw-r--r--sys/contrib/dev/acpica/components/resources/rscreate.c6
-rw-r--r--sys/contrib/dev/acpica/components/resources/rsutils.c2
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbfadt.c31
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbinstal.c5
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbutils.c45
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbxface.c169
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbxfload.c415
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbxfroot.c2
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utdecode.c62
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utexcep.c174
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utglobal.c5
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utmisc.c80
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utobject.c6
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utresrc.c4
-rw-r--r--sys/contrib/dev/acpica/components/utilities/utxferror.c81
-rw-r--r--sys/contrib/dev/acpica/include/acdebug.h3
-rw-r--r--sys/contrib/dev/acpica/include/acexcep.h5
-rw-r--r--sys/contrib/dev/acpica/include/acglobal.h9
-rw-r--r--sys/contrib/dev/acpica/include/acmacros.h4
-rw-r--r--sys/contrib/dev/acpica/include/acobject.h4
-rw-r--r--sys/contrib/dev/acpica/include/acoutput.h4
-rw-r--r--sys/contrib/dev/acpica/include/acpixf.h36
-rw-r--r--sys/contrib/dev/acpica/include/actbl1.h2
-rw-r--r--sys/contrib/dev/acpica/include/platform/acenv.h2
-rw-r--r--sys/dev/agp/agp_i810.c3
-rw-r--r--sys/dev/ath/ath_hal/ah.c29
-rw-r--r--sys/dev/ath/ath_hal/ah.h20
-rw-r--r--sys/dev/ath/ath_hal/ah_debug.h5
-rw-r--r--sys/dev/ath/ath_hal/ah_desc.h26
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210.h4
-rw-r--r--sys/dev/ath/ath_hal/ar5210/ar5210_recv.c8
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211.h4
-rw-r--r--sys/dev/ath/ath_hal/ar5211/ar5211_recv.c8
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212.h4
-rw-r--r--sys/dev/ath/ath_hal/ar5212/ar5212_recv.c8
-rw-r--r--sys/dev/ath/if_ath.c61
-rw-r--r--sys/dev/ath/if_ath_debug.c10
-rw-r--r--sys/dev/ath/if_ath_debug.h8
-rw-r--r--sys/dev/ath/if_ath_misc.h9
-rw-r--r--sys/dev/ath/if_ath_rx.c82
-rw-r--r--sys/dev/ath/if_ath_rx.h8
-rw-r--r--sys/dev/ath/if_ath_rx_edma.c604
-rw-r--r--sys/dev/ath/if_ath_tx.c4
-rw-r--r--sys/dev/ath/if_athvar.h55
-rw-r--r--sys/dev/cxgbe/t4_sge.c8
-rw-r--r--sys/dev/mfi/mfi_disk.c1
-rw-r--r--sys/dev/mfi/mfivar.h1
-rw-r--r--sys/dev/usb/usb_pf.c186
-rw-r--r--sys/dev/usb/usbdevs5
-rw-r--r--sys/dev/usb/wlan/if_run.c2
-rw-r--r--sys/dev/virtio/balloon/virtio_balloon.c1
-rw-r--r--sys/dev/virtio/block/virtio_blk.c81
-rw-r--r--sys/dev/virtio/network/if_vtnet.c2
-rw-r--r--sys/dev/virtio/pci/virtio_pci.c619
-rw-r--r--sys/dev/virtio/pci/virtio_pci.h2
-rw-r--r--sys/dev/virtio/virtio.c37
-rw-r--r--sys/dev/virtio/virtio.h33
-rw-r--r--sys/dev/virtio/virtio_ring.h9
-rw-r--r--sys/dev/virtio/virtqueue.c87
-rw-r--r--sys/dev/virtio/virtqueue.h6
-rw-r--r--sys/fs/ntfs/ntfs_subr.c168
-rw-r--r--sys/fs/ntfs/ntfs_subr.h2
-rw-r--r--sys/fs/ntfs/ntfs_vfsops.c84
-rw-r--r--sys/fs/ntfs/ntfs_vnops.c130
-rw-r--r--sys/i386/i386/machdep.c3
-rw-r--r--sys/i386/i386/mem.c2
-rw-r--r--sys/i386/include/cpufunc.h10
-rw-r--r--sys/i386/isa/npx.c19
-rw-r--r--sys/kern/dtio_kdtrace.c232
-rw-r--r--sys/kern/kern_descrip.c32
-rw-r--r--sys/kern/kern_sig.c5
-rw-r--r--sys/kern/subr_devstat.c58
-rw-r--r--sys/kern/sys_process.c8
-rw-r--r--sys/mips/nlm/board.c2
-rw-r--r--sys/mips/nlm/dev/net/mdio.c55
-rw-r--r--sys/mips/nlm/hal/mdio.h1
-rw-r--r--sys/mips/nlm/xlp.h23
-rw-r--r--sys/mips/nlm/xlp_pci.c4
-rw-r--r--sys/modules/acpi/acpi/Makefile19
-rw-r--r--sys/modules/dtrace/Makefile1
-rw-r--r--sys/modules/dtrace/dtio/Makefile13
-rw-r--r--sys/modules/dtrace/dtraceall/dtraceall.c1
-rw-r--r--sys/net/if_bridge.c6
-rw-r--r--sys/net/if_epair.c38
-rw-r--r--sys/netinet/ipfw/ip_fw_log.c137
-rw-r--r--sys/netinet/sctp_output.c1
-rw-r--r--sys/netinet6/nd6.h2
-rw-r--r--sys/netsmb/smb_trantcp.c4
-rw-r--r--sys/pc98/pc98/machdep.c3
-rw-r--r--sys/powerpc/aim/mmu_oea.c36
-rw-r--r--sys/powerpc/aim/mmu_oea64.c4
-rw-r--r--sys/powerpc/booke/pmap.c2
-rw-r--r--sys/powerpc/powerpc/mmu_if.m2
-rw-r--r--sys/sys/dtrace_bsd.h19
-rw-r--r--sys/vm/vm_object.c9
152 files changed, 3717 insertions, 1855 deletions
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c
index 77e11bc..ca951ad 100644
--- a/sys/amd64/amd64/fpu.c
+++ b/sys/amd64/amd64/fpu.c
@@ -73,10 +73,6 @@ __FBSDID("$FreeBSD$");
#define fxrstor(addr) __asm __volatile("fxrstor %0" : : "m" (*(addr)))
#define fxsave(addr) __asm __volatile("fxsave %0" : "=m" (*(addr)))
#define ldmxcsr(csr) __asm __volatile("ldmxcsr %0" : : "m" (csr))
-#define start_emulating() __asm __volatile( \
- "smsw %%ax; orb %0,%%al; lmsw %%ax" \
- : : "n" (CR0_TS) : "ax")
-#define stop_emulating() __asm __volatile("clts")
static __inline void
xrstor(char *addr, uint64_t mask)
@@ -109,13 +105,14 @@ void fnstsw(caddr_t addr);
void fxsave(caddr_t addr);
void fxrstor(caddr_t addr);
void ldmxcsr(u_int csr);
-void start_emulating(void);
-void stop_emulating(void);
void xrstor(char *addr, uint64_t mask);
void xsave(char *addr, uint64_t mask);
#endif /* __GNUCLIKE_ASM && !lint */
+#define start_emulating() load_cr0(rcr0() | CR0_TS)
+#define stop_emulating() clts()
+
#define GET_FPU_CW(thread) ((thread)->td_pcb->pcb_save->sv_env.en_cw)
#define GET_FPU_SW(thread) ((thread)->td_pcb->pcb_save->sv_env.en_sw)
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 9580d79..8044fe5 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$");
#include <sys/linker.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/memrange.h>
#include <sys/msgbuf.h>
#include <sys/mutex.h>
#include <sys/pcpu.h>
@@ -206,6 +207,8 @@ struct pcpu __pcpu[MAXCPU];
struct mtx icu_lock;
+struct mem_range_softc mem_range_softc;
+
struct mtx dt_lock; /* lock for GDT and LDT */
static void
diff --git a/sys/amd64/amd64/mem.c b/sys/amd64/amd64/mem.c
index b86f5dd..abbbb21 100644
--- a/sys/amd64/amd64/mem.c
+++ b/sys/amd64/amd64/mem.c
@@ -72,8 +72,6 @@ __FBSDID("$FreeBSD$");
*/
MALLOC_DEFINE(M_MEMDESC, "memdesc", "memory range descriptors");
-struct mem_range_softc mem_range_softc;
-
/* ARGSUSED */
int
memrw(struct cdev *dev, struct uio *uio, int flags)
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index 829efc1..94d4133 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -107,6 +107,13 @@ clflush(u_long addr)
}
static __inline void
+clts(void)
+{
+
+ __asm __volatile("clts");
+}
+
+static __inline void
disable_intr(void)
{
__asm __volatile("cli" : : : "memory");
@@ -702,6 +709,9 @@ intr_restore(register_t rflags)
int breakpoint(void);
u_int bsfl(u_int mask);
u_int bsrl(u_int mask);
+void clflush(u_long addr);
+void clts(void);
+void cpuid_count(u_int ax, u_int cx, u_int *p);
void disable_intr(void);
void do_cpuid(u_int ax, u_int *p);
void enable_intr(void);
diff --git a/sys/arm/at91/at91.c b/sys/arm/at91/at91.c
index 877b746..da3aa72 100644
--- a/sys/arm/at91/at91.c
+++ b/sys/arm/at91/at91.c
@@ -270,10 +270,12 @@ at91_attach(device_t dev)
}
- /* Our device list will be added automatically by the cpu device
+ /*
+ * Our device list will be added automatically by the cpu device
* e.g. at91rm9200.c when it is identified. To ensure that the
* CPU and PMC are attached first any other "identified" devices
- * call BUS_ADD_CHILD(9) with an "order" of at least 2. */
+ * call BUS_ADD_CHILD(9) with an "order" of at least 2.
+ */
bus_generic_probe(dev);
bus_generic_attach(dev);
@@ -363,7 +365,7 @@ at91_setup_intr(device_t dev, device_t child,
struct at91_softc *sc = device_get_softc(dev);
int error;
- if (rman_get_start(ires) == sc->sc_irq_system && filt == NULL)
+ if (rman_get_start(ires) == AT91_IRQ_SYSTEM && filt == NULL)
panic("All system interrupt ISRs must be FILTER");
error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
filt, intr, arg, cookiep);
@@ -471,6 +473,41 @@ at91_eoi(void *unused)
IC_EOICR, 0);
}
+void
+at91_add_child(device_t dev, int prio, const char *name, int unit,
+ bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
+{
+ device_t kid;
+ struct at91_ivar *ivar;
+
+ kid = device_add_child_ordered(dev, prio, name, unit);
+ if (kid == NULL) {
+ printf("Can't add child %s%d ordered\n", name, unit);
+ return;
+ }
+ ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (ivar == NULL) {
+ device_delete_child(dev, kid);
+ printf("Can't add alloc ivar\n");
+ return;
+ }
+ device_set_ivars(kid, ivar);
+ resource_list_init(&ivar->resources);
+ if (irq0 != -1) {
+ bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
+ if (irq0 != AT91_IRQ_SYSTEM)
+ at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
+ }
+ if (irq1 != 0)
+ bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
+ if (irq2 != 0)
+ bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
+ if (addr != 0 && addr < AT91_BASE)
+ addr += AT91_BASE;
+ if (addr != 0)
+ bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
+}
+
static device_method_t at91_methods[] = {
DEVMETHOD(device_probe, at91_probe),
DEVMETHOD(device_attach, at91_attach),
diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c
index 23732ef..0bb79bd 100644
--- a/sys/arm/at91/at91_machdep.c
+++ b/sys/arm/at91/at91_machdep.c
@@ -90,6 +90,8 @@ __FBSDID("$FreeBSD$");
#include <arm/at91/at91board.h>
#include <arm/at91/at91var.h>
+#include <arm/at91/at91soc.h>
+#include <arm/at91/at91_usartreg.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91sam9g20reg.h>
@@ -115,10 +117,6 @@ extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-extern void *_end;
-
-extern int *end;
-
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
@@ -126,7 +124,6 @@ struct pcpu *pcpup = &__pcpu;
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
-vm_offset_t physical_pages;
struct pv_addr systempage;
struct pv_addr msgbufpv;
@@ -282,7 +279,7 @@ static const char *soc_subtype_name[] = {
[AT91_ST_SAM9X35] = "at91sam9x35",
};
-struct at91_soc_info soc_data;
+struct at91_soc_info soc_info;
/*
* Read the SoC ID from the CIDR register and try to match it against the
@@ -295,103 +292,117 @@ at91_try_id(uint32_t dbgu_base)
{
uint32_t socid;
- soc_data.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
+ soc_info.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
DBGU_C1R);
- socid = soc_data.cidr & ~AT91_CPU_VERSION_MASK;
+ socid = soc_info.cidr & ~AT91_CPU_VERSION_MASK;
- soc_data.type = AT91_T_NONE;
- soc_data.subtype = AT91_ST_NONE;
- soc_data.family = (soc_data.cidr & AT91_CPU_FAMILY_MASK) >> 20;
- soc_data.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
+ soc_info.type = AT91_T_NONE;
+ soc_info.subtype = AT91_ST_NONE;
+ soc_info.family = (soc_info.cidr & AT91_CPU_FAMILY_MASK) >> 20;
+ soc_info.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
DBGU_C2R);
switch (socid) {
case AT91_CPU_CAP9:
- soc_data.type = AT91_T_CAP9;
+ soc_info.type = AT91_T_CAP9;
break;
case AT91_CPU_RM9200:
- soc_data.type = AT91_T_RM9200;
+ soc_info.type = AT91_T_RM9200;
break;
case AT91_CPU_SAM9XE128:
case AT91_CPU_SAM9XE256:
case AT91_CPU_SAM9XE512:
case AT91_CPU_SAM9260:
- soc_data.type = AT91_T_SAM9260;
- if (soc_data.family == AT91_FAMILY_SAM9XE)
- soc_data.subtype = AT91_ST_SAM9XE;
+ soc_info.type = AT91_T_SAM9260;
+ if (soc_info.family == AT91_FAMILY_SAM9XE)
+ soc_info.subtype = AT91_ST_SAM9XE;
break;
case AT91_CPU_SAM9261:
- soc_data.type = AT91_T_SAM9261;
+ soc_info.type = AT91_T_SAM9261;
break;
case AT91_CPU_SAM9263:
- soc_data.type = AT91_T_SAM9263;
+ soc_info.type = AT91_T_SAM9263;
break;
case AT91_CPU_SAM9G10:
- soc_data.type = AT91_T_SAM9G10;
+ soc_info.type = AT91_T_SAM9G10;
break;
case AT91_CPU_SAM9G20:
- soc_data.type = AT91_T_SAM9G20;
+ soc_info.type = AT91_T_SAM9G20;
break;
case AT91_CPU_SAM9G45:
- soc_data.type = AT91_T_SAM9G45;
+ soc_info.type = AT91_T_SAM9G45;
break;
case AT91_CPU_SAM9N12:
- soc_data.type = AT91_T_SAM9N12;
+ soc_info.type = AT91_T_SAM9N12;
break;
case AT91_CPU_SAM9RL64:
- soc_data.type = AT91_T_SAM9RL;
+ soc_info.type = AT91_T_SAM9RL;
break;
case AT91_CPU_SAM9X5:
- soc_data.type = AT91_T_SAM9X5;
+ soc_info.type = AT91_T_SAM9X5;
break;
default:
return (0);
}
- switch (soc_data.type) {
+ switch (soc_info.type) {
case AT91_T_SAM9G45:
- switch (soc_data.exid) {
+ switch (soc_info.exid) {
case AT91_EXID_SAM9G45:
- soc_data.subtype = AT91_ST_SAM9G45;
+ soc_info.subtype = AT91_ST_SAM9G45;
break;
case AT91_EXID_SAM9G46:
- soc_data.subtype = AT91_ST_SAM9G46;
+ soc_info.subtype = AT91_ST_SAM9G46;
break;
case AT91_EXID_SAM9M10:
- soc_data.subtype = AT91_ST_SAM9M10;
+ soc_info.subtype = AT91_ST_SAM9M10;
break;
case AT91_EXID_SAM9M11:
- soc_data.subtype = AT91_ST_SAM9M11;
+ soc_info.subtype = AT91_ST_SAM9M11;
break;
}
break;
case AT91_T_SAM9X5:
- switch (soc_data.exid) {
+ switch (soc_info.exid) {
case AT91_EXID_SAM9G15:
- soc_data.subtype = AT91_ST_SAM9G15;
+ soc_info.subtype = AT91_ST_SAM9G15;
break;
case AT91_EXID_SAM9G25:
- soc_data.subtype = AT91_ST_SAM9G25;
+ soc_info.subtype = AT91_ST_SAM9G25;
break;
case AT91_EXID_SAM9G35:
- soc_data.subtype = AT91_ST_SAM9G35;
+ soc_info.subtype = AT91_ST_SAM9G35;
break;
case AT91_EXID_SAM9X25:
- soc_data.subtype = AT91_ST_SAM9X25;
+ soc_info.subtype = AT91_ST_SAM9X25;
break;
case AT91_EXID_SAM9X35:
- soc_data.subtype = AT91_ST_SAM9X35;
+ soc_info.subtype = AT91_ST_SAM9X35;
break;
}
break;
default:
break;
}
- snprintf(soc_data.name, sizeof(soc_data.name), "%s%s%s",
- soc_type_name[soc_data.type],
- soc_data.subtype == AT91_ST_NONE ? "" : " subtype ",
- soc_data.subtype == AT91_ST_NONE ? "" :
- soc_subtype_name[soc_data.subtype]);
+ /*
+ * Disable interrupts in the DBGU unit...
+ */
+ *(volatile uint32_t *)(AT91_BASE + dbgu_base + USART_IDR) = 0xffffffff;
+
+ /*
+ * Save the name for later...
+ */
+ snprintf(soc_info.name, sizeof(soc_info.name), "%s%s%s",
+ soc_type_name[soc_info.type],
+ soc_info.subtype == AT91_ST_NONE ? "" : " subtype ",
+ soc_info.subtype == AT91_ST_NONE ? "" :
+ soc_subtype_name[soc_info.subtype]);
+
+ /*
+ * try to get the matching CPU support.
+ */
+ soc_info.soc_data = at91_match_soc(soc_info.type, soc_info.subtype);
+
return (1);
}
@@ -544,6 +555,9 @@ initarm(struct arm_boot_params *abp)
cninit();
+ if (soc_info.soc_data == NULL)
+ printf("Warning: No soc support for %s found.\n", soc_info.name);
+
memsize = board_init();
physmem = memsize / PAGE_SIZE;
@@ -633,16 +647,16 @@ void
DELAY(int n)
{
- if (soc_data.delay)
- soc_data.delay(n);
+ if (soc_info.soc_data)
+ soc_info.soc_data->soc_delay(n);
}
void
cpu_reset(void)
{
- if (soc_data.reset)
- soc_data.reset();
+ if (soc_info.soc_data)
+ soc_info.soc_data->soc_reset();
while (1)
continue;
}
diff --git a/sys/arm/at91/at91_mci.c b/sys/arm/at91/at91_mci.c
index f69477e..196aa64 100644
--- a/sys/arm/at91/at91_mci.c
+++ b/sys/arm/at91/at91_mci.c
@@ -313,7 +313,7 @@ static int
at91_mci_is_mci1rev2xx(void)
{
- switch (soc_data.type) {
+ switch (soc_info.type) {
case AT91_T_SAM9260:
case AT91_T_SAM9263:
case AT91_T_CAP9:
diff --git a/sys/arm/at91/at91_pit.c b/sys/arm/at91/at91_pit.c
index 2a9656a..853dddc 100644
--- a/sys/arm/at91/at91_pit.c
+++ b/sys/arm/at91/at91_pit.c
@@ -59,7 +59,7 @@ static struct pit_softc {
} *sc;
static uint32_t timecount = 0;
-static unsigned at91pit_get_timecount(struct timecounter *tc);
+static unsigned at91_pit_get_timecount(struct timecounter *tc);
static int pit_intr(void *arg);
static inline uint32_t
@@ -76,8 +76,8 @@ WR4(struct pit_softc *sc, bus_size_t off, uint32_t val)
bus_write_4(sc->mem_res, off, val);
}
-static void
-at91pit_delay(int us)
+void
+at91_pit_delay(int us)
{
int32_t cnt, last, piv;
uint64_t pit_freq;
@@ -99,8 +99,8 @@ at91pit_delay(int us)
}
}
-static struct timecounter at91pit_timecounter = {
- at91pit_get_timecount, /* get_timecount */
+static struct timecounter at91_pit_timecounter = {
+ at91_pit_get_timecount, /* get_timecount */
NULL, /* no poll_pps */
0xffffffff, /* counter mask */
0 / PIT_PRESCALE, /* frequency */
@@ -109,7 +109,7 @@ static struct timecounter at91pit_timecounter = {
};
static int
-at91pit_probe(device_t dev)
+at91_pit_probe(device_t dev)
{
device_set_desc(dev, "AT91SAM9 PIT");
@@ -117,7 +117,7 @@ at91pit_probe(device_t dev)
}
static int
-at91pit_attach(device_t dev)
+at91_pit_attach(device_t dev)
{
void *ih;
int rid, err = 0;
@@ -148,32 +148,31 @@ at91pit_attach(device_t dev)
err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, pit_intr, NULL, NULL,
&ih);
- at91pit_timecounter.tc_frequency = at91_master_clock / PIT_PRESCALE;
- tc_init(&at91pit_timecounter);
+ at91_pit_timecounter.tc_frequency = at91_master_clock / PIT_PRESCALE;
+ tc_init(&at91_pit_timecounter);
/* Enable the PIT here. */
WR4(sc, PIT_MR, PIT_PIV(at91_master_clock / PIT_PRESCALE / hz) |
PIT_EN | PIT_IEN);
- soc_data.delay = at91pit_delay;
out:
return (err);
}
-static device_method_t at91pit_methods[] = {
- DEVMETHOD(device_probe, at91pit_probe),
- DEVMETHOD(device_attach, at91pit_attach),
+static device_method_t at91_pit_methods[] = {
+ DEVMETHOD(device_probe, at91_pit_probe),
+ DEVMETHOD(device_attach, at91_pit_attach),
DEVMETHOD_END
};
-static driver_t at91pit_driver = {
+static driver_t at91_pit_driver = {
"at91_pit",
- at91pit_methods,
+ at91_pit_methods,
sizeof(struct pit_softc),
};
-static devclass_t at91pit_devclass;
+static devclass_t at91_pit_devclass;
-DRIVER_MODULE(at91_pit, atmelarm, at91pit_driver, at91pit_devclass, NULL,
+DRIVER_MODULE(at91_pit, atmelarm, at91_pit_driver, at91_pit_devclass, NULL,
NULL);
static int
@@ -195,7 +194,7 @@ pit_intr(void *arg)
}
static unsigned
-at91pit_get_timecount(struct timecounter *tc)
+at91_pit_get_timecount(struct timecounter *tc)
{
uint32_t piir, icnt;
diff --git a/sys/arm/at91/at91_pitreg.h b/sys/arm/at91/at91_pitreg.h
index 7817c22..5e87e39 100644
--- a/sys/arm/at91/at91_pitreg.h
+++ b/sys/arm/at91/at91_pitreg.h
@@ -25,8 +25,8 @@
/* $FreeBSD$ */
-#ifndef ARM_AT91_AT91PITREG_H
-#define ARM_AT91_AT91PITREG_H
+#ifndef ARM_AT91_AT91_PITREG_H
+#define ARM_AT91_AT91_PITREG_H
#define PIT_MR 0x0
#define PIT_SR 0x4
@@ -42,4 +42,6 @@
/* PIT_SR */
#define PIT_PITS_DONE 1 /* interrupt done */
-#endif /* ARM_AT91_AT91PITREG_H */
+void at91_pit_delay(int us);
+
+#endif /* ARM_AT91_AT91_PITREG_H */
diff --git a/sys/arm/at91/at91_reset.S b/sys/arm/at91/at91_reset.S
index 6ff7da0..28703cc 100644
--- a/sys/arm/at91/at91_reset.S
+++ b/sys/arm/at91/at91_reset.S
@@ -1,13 +1,14 @@
#include <machine/asm.h>
#include <arm/at91/at91_rstreg.h>
+#include <arm/at91/at91reg.h>
#include <arm/at91/at91sam9g20reg.h>
__FBSDID("$FreeBSD$");
-#define SDRAM_TR (AT91SAM9G20_BASE + \
+#define SDRAM_TR (AT91_BASE + \
AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_TR)
-#define SDRAM_LPR (AT91SAM9G20_BASE + \
+#define SDRAM_LPR (AT91_BASE + \
AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_LPR)
-#define RSTC_RCR (AT91SAM9G20_BASE + \
+#define RSTC_RCR (AT91_BASE + \
AT91SAM9G20_RSTC_BASE + RST_CR)
/*
diff --git a/sys/arm/at91/at91_rst.c b/sys/arm/at91/at91_rst.c
index dbd041b..0879072 100644
--- a/sys/arm/at91/at91_rst.c
+++ b/sys/arm/at91/at91_rst.c
@@ -42,26 +42,26 @@ __FBSDID("$FreeBSD$");
#define RST_TIMEOUT (5) /* Seconds to hold NRST for hard reset */
#define RST_TICK (20) /* sample NRST at hz/RST_TICK intervals */
-static int at91rst_intr(void *arg);
+static int at91_rst_intr(void *arg);
-static struct at91rst_softc {
+static struct at91_rst_softc {
struct resource *mem_res; /* Memory resource */
struct resource *irq_res; /* IRQ resource */
void *intrhand; /* Interrupt handle */
struct callout tick_ch; /* Tick callout */
device_t sc_dev;
u_int shutdown; /* Shutdown in progress */
-} *at91rst_sc;
+} *at91_rst_sc;
static inline uint32_t
-RD4(struct at91rst_softc *sc, bus_size_t off)
+RD4(struct at91_rst_softc *sc, bus_size_t off)
{
return (bus_read_4(sc->mem_res, off));
}
static inline void
-WR4(struct at91rst_softc *sc, bus_size_t off, uint32_t val)
+WR4(struct at91_rst_softc *sc, bus_size_t off, uint32_t val)
{
bus_write_4(sc->mem_res, off, val);
@@ -70,17 +70,17 @@ WR4(struct at91rst_softc *sc, bus_size_t off, uint32_t val)
void cpu_reset_sam9g20(void) __attribute__((weak));
void cpu_reset_sam9g20(void) {}
-static void
-at91rst_cpu_reset(void)
+void
+at91_rst_cpu_reset(void)
{
- if (at91rst_sc) {
+ if (at91_rst_sc) {
cpu_reset_sam9g20(); /* May be null */
- WR4(at91rst_sc, RST_MR,
+ WR4(at91_rst_sc, RST_MR,
RST_MR_ERSTL(0xd) | RST_MR_URSTEN | RST_MR_KEY);
- WR4(at91rst_sc, RST_CR,
+ WR4(at91_rst_sc, RST_CR,
RST_CR_PROCRST |
RST_CR_PERRST |
RST_CR_EXTRST |
@@ -91,7 +91,7 @@ at91rst_cpu_reset(void)
}
static int
-at91rst_probe(device_t dev)
+at91_rst_probe(device_t dev)
{
device_set_desc(dev, "AT91SAM9 Reset Controller");
@@ -99,13 +99,13 @@ at91rst_probe(device_t dev)
}
static int
-at91rst_attach(device_t dev)
+at91_rst_attach(device_t dev)
{
- struct at91rst_softc *sc;
+ struct at91_rst_softc *sc;
const char *cause;
int rid, err;
- at91rst_sc = sc = device_get_softc(dev);
+ at91_rst_sc = sc = device_get_softc(dev);
sc->sc_dev = dev;
callout_init(&sc->tick_ch, 0);
@@ -129,11 +129,11 @@ at91rst_attach(device_t dev)
/* Activate the interrupt. */
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
- at91rst_intr, NULL, sc, &sc->intrhand);
+ at91_rst_intr, NULL, sc, &sc->intrhand);
if (err)
device_printf(dev, "could not establish interrupt handler.\n");
- WR4(at91rst_sc, RST_MR, RST_MR_ERSTL(0xd) | RST_MR_URSIEN | RST_MR_KEY);
+ WR4(at91_rst_sc, RST_MR, RST_MR_ERSTL(0xd) | RST_MR_URSIEN | RST_MR_KEY);
switch (RD4(sc, RST_SR) & RST_SR_RST_MASK) {
case RST_SR_RST_POW:
@@ -157,15 +157,14 @@ at91rst_attach(device_t dev)
}
device_printf(dev, "Reset cause: %s.\n", cause);
- soc_data.reset = at91rst_cpu_reset;
out:
return (err);
}
static void
-at91rst_tick(void *argp)
+at91_rst_tick(void *argp)
{
- struct at91rst_softc *sc = argp;
+ struct at91_rst_softc *sc = argp;
if (sc->shutdown++ >= RST_TIMEOUT * RST_TICK) {
/* User released the button in morre than RST_TIMEOUT */
@@ -176,36 +175,36 @@ at91rst_tick(void *argp)
device_printf(sc->sc_dev, "shutting down...\n");
shutdown_nice(0);
} else {
- callout_reset(&sc->tick_ch, hz/RST_TICK, at91rst_tick, sc);
+ callout_reset(&sc->tick_ch, hz/RST_TICK, at91_rst_tick, sc);
}
}
static int
-at91rst_intr(void *argp)
+at91_rst_intr(void *argp)
{
- struct at91rst_softc *sc = argp;
+ struct at91_rst_softc *sc = argp;
if (RD4(sc, RST_SR) & RST_SR_URSTS) {
if (sc->shutdown == 0)
- callout_reset(&sc->tick_ch, hz/RST_TICK, at91rst_tick, sc);
+ callout_reset(&sc->tick_ch, hz/RST_TICK, at91_rst_tick, sc);
return (FILTER_HANDLED);
}
return (FILTER_STRAY);
}
-static device_method_t at91rst_methods[] = {
- DEVMETHOD(device_probe, at91rst_probe),
- DEVMETHOD(device_attach, at91rst_attach),
+static device_method_t at91_rst_methods[] = {
+ DEVMETHOD(device_probe, at91_rst_probe),
+ DEVMETHOD(device_attach, at91_rst_attach),
DEVMETHOD_END
};
-static driver_t at91rst_driver = {
+static driver_t at91_rst_driver = {
"at91_rst",
- at91rst_methods,
- sizeof(struct at91rst_softc),
+ at91_rst_methods,
+ sizeof(struct at91_rst_softc),
};
-static devclass_t at91rst_devclass;
+static devclass_t at91_rst_devclass;
-DRIVER_MODULE(at91_rst, atmelarm, at91rst_driver, at91rst_devclass, NULL,
+DRIVER_MODULE(at91_rst, atmelarm, at91_rst_driver, at91_rst_devclass, NULL,
NULL);
diff --git a/sys/arm/at91/at91_rstreg.h b/sys/arm/at91/at91_rstreg.h
index f075b2c..ee64f14 100644
--- a/sys/arm/at91/at91_rstreg.h
+++ b/sys/arm/at91/at91_rstreg.h
@@ -25,8 +25,8 @@
/* $FreeBSD$ */
-#ifndef ARM_AT91_AT91RSTREG_H
-#define ARM_AT91_AT91RSTREG_H
+#ifndef ARM_AT91_AT91_RSTREG_H
+#define ARM_AT91_AT91_RSTREG_H
#define RST_CR 0x0 /* Control Register */
#define RST_SR 0x4 /* Status Register */
@@ -56,4 +56,8 @@
#define RST_MR_ERSTL(x) ((x)<<8) /* External reset length */
#define RST_MR_KEY (0xa5<<24)
-#endif /* ARM_AT91_AT91RSTREG_H */
+#ifndef __ASSEMBLER__
+void at91_rst_cpu_reset(void);
+#endif
+
+#endif /* ARM_AT91_AT91_RSTREG_H */
diff --git a/sys/arm/at91/at91_st.c b/sys/arm/at91/at91_st.c
index 6a3284e..a18be2e 100644
--- a/sys/arm/at91/at91_st.c
+++ b/sys/arm/at91/at91_st.c
@@ -43,24 +43,45 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/frame.h>
#include <machine/intr.h>
-#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91var.h>
#include <arm/at91/at91_streg.h>
+#include <arm/at91/at91rm92reg.h>
-static struct at91st_softc {
- bus_space_tag_t sc_st;
- bus_space_handle_t sc_sh;
- device_t sc_dev;
+static struct at91_st_softc {
+ struct resource * sc_irq_res;
+ struct resource * sc_mem_res;
+ void * sc_intrhand;
eventhandler_tag sc_wet; /* watchdog event handler tag */
} *timer_softc;
-#define RD4(off) \
- bus_space_read_4(timer_softc->sc_st, timer_softc->sc_sh, (off))
-#define WR4(off, val) \
- bus_space_write_4(timer_softc->sc_st, timer_softc->sc_sh, (off), (val))
+static inline uint32_t
+RD4(bus_size_t off)
+{
+
+ if (timer_softc == NULL) {
+ uint32_t *p = (uint32_t *)(AT91_BASE + AT91RM92_ST_BASE + off);
+
+ return *p;
+ }
+
+ return (bus_read_4(timer_softc->sc_mem_res, off));
+}
+
+static inline void
+WR4(bus_size_t off, uint32_t val)
+{
+
+ if (timer_softc == NULL) {
+ uint32_t *p = (uint32_t *)(AT91_BASE + AT91RM92_ST_BASE + off);
+
+ *p = val;
+ }
+ else
+ bus_write_4(timer_softc->sc_mem_res, off, val);
+}
-static void at91st_watchdog(void *, u_int, int *);
-static void at91st_initclocks(struct at91st_softc *);
+static void at91_st_watchdog(void *, u_int, int *);
+static void at91_st_initclocks(device_t , struct at91_st_softc *);
static inline int
st_crtr(void)
@@ -73,10 +94,10 @@ st_crtr(void)
return (cur1);
}
-static unsigned at91st_get_timecount(struct timecounter *tc);
+static unsigned at91_st_get_timecount(struct timecounter *tc);
-static struct timecounter at91st_timecounter = {
- at91st_get_timecount, /* get_timecount */
+static struct timecounter at91_st_timecounter = {
+ at91_st_get_timecount, /* get_timecount */
NULL, /* no poll_pps */
0xfffffu, /* counter_mask */
32768, /* frequency */
@@ -84,8 +105,21 @@ static struct timecounter at91st_timecounter = {
1000 /* quality */
};
-static void
-at91st_delay(int n)
+static int
+clock_intr(void *arg)
+{
+ struct trapframe *fp = arg;
+
+ /* The interrupt is shared, so we have to make sure it's for us. */
+ if (RD4(ST_SR) & ST_SR_PITS) {
+ hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
+ return (FILTER_HANDLED);
+ }
+ return (FILTER_STRAY);
+}
+
+void
+at91_st_delay(int n)
{
uint32_t start, end, cur;
@@ -104,8 +138,8 @@ at91st_delay(int n)
}
}
-static void
-at91st_cpu_reset(void)
+void
+at91_st_cpu_reset(void)
{
/*
* Reset the CPU by programmig the watchdog timer to reset the
@@ -119,63 +153,102 @@ at91st_cpu_reset(void)
}
static int
-at91st_probe(device_t dev)
+at91_st_probe(device_t dev)
{
device_set_desc(dev, "ST");
return (0);
}
+static void
+at91_st_deactivate(device_t dev)
+{
+ struct at91_st_softc *sc = timer_softc;
+
+ if (sc->sc_intrhand)
+ bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
+ sc->sc_intrhand = NULL;
+
+ if (sc->sc_irq_res)
+ bus_release_resource(dev, SYS_RES_IRQ,
+ rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
+ sc->sc_irq_res = NULL;
+
+ if (sc->sc_mem_res)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ rman_get_rid(sc->sc_mem_res), sc->sc_mem_res);
+ sc->sc_mem_res = NULL;
+}
+
static int
-at91st_attach(device_t dev)
+at91_st_activate(device_t dev)
{
- struct at91_softc *sc = device_get_softc(device_get_parent(dev));
+ int rid;
+ int err;
+ struct at91_st_softc *sc = timer_softc;
- timer_softc = device_get_softc(dev);
- timer_softc->sc_st = sc->sc_st;
- timer_softc->sc_dev = dev;
- if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_ST_BASE,
- AT91RM92_ST_SIZE, &timer_softc->sc_sh) != 0)
- panic("couldn't subregion timer registers");
- /*
- * Real time counter increments every clock cycle, need to set before
- * initializing clocks so that DELAY works.
- */
- WR4(ST_RTMR, 1);
+ rid = 0;
+ sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ err = ENOMEM;
+ if (sc->sc_mem_res == NULL)
+ goto out;
/* Disable all interrupts */
WR4(ST_IDR, 0xffffffff);
- /* disable watchdog timer */
- WR4(ST_WDMR, 0);
- soc_data.delay = at91st_delay;
- soc_data.reset = at91st_cpu_reset; // XXX kinda late to be setting this...
+
+ /* The system timer shares the system irq (1) */
+ rid = 0;
+ sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_ACTIVE | RF_SHAREABLE);
+ if (sc->sc_irq_res == NULL) {
+ printf("Unable to allocate irq for the system timer");
+ goto out;
+ }
+ err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_CLK, clock_intr,
+ NULL, NULL, &sc->sc_intrhand);
+out:
+ if (err != 0)
+ at91_st_deactivate(dev);
+ return (err);
+}
+
+static int
+at91_st_attach(device_t dev)
+{
+ int err;
+
+ timer_softc = device_get_softc(dev);
+ err = at91_st_activate(dev);
+ if (err)
+ return err;
timer_softc->sc_wet = EVENTHANDLER_REGISTER(watchdog_list,
- at91st_watchdog, dev, 0);
+ at91_st_watchdog, dev, 0);
device_printf(dev,
"watchdog registered, timeout intervall max. 64 sec\n");
- at91st_initclocks(timer_softc);
+ at91_st_initclocks(dev, timer_softc);
return (0);
}
-static device_method_t at91st_methods[] = {
- DEVMETHOD(device_probe, at91st_probe),
- DEVMETHOD(device_attach, at91st_attach),
+static device_method_t at91_st_methods[] = {
+ DEVMETHOD(device_probe, at91_st_probe),
+ DEVMETHOD(device_attach, at91_st_attach),
{0, 0},
};
-static driver_t at91st_driver = {
+static driver_t at91_st_driver = {
"at91_st",
- at91st_methods,
- sizeof(struct at91st_softc),
+ at91_st_methods,
+ sizeof(struct at91_st_softc),
};
-static devclass_t at91st_devclass;
+static devclass_t at91_st_devclass;
-DRIVER_MODULE(at91_st, atmelarm, at91st_driver, at91st_devclass, 0, 0);
+DRIVER_MODULE(at91_st, atmelarm, at91_st_driver, at91_st_devclass, 0, 0);
static unsigned
-at91st_get_timecount(struct timecounter *tc)
+at91_st_get_timecount(struct timecounter *tc)
{
return (st_crtr());
}
@@ -194,7 +267,7 @@ at91st_get_timecount(struct timecounter *tc)
* interval, I think this is the best solution.
*/
static void
-at91st_watchdog(void *argp, u_int cmd, int *error)
+at91_st_watchdog(void *argp, u_int cmd, int *error)
{
uint32_t wdog;
int t;
@@ -210,50 +283,31 @@ at91st_watchdog(void *argp, u_int cmd, int *error)
WR4(ST_CR, ST_CR_WDRST);
}
-static int
-clock_intr(void *arg)
-{
- struct trapframe *fp = arg;
-
- /* The interrupt is shared, so we have to make sure it's for us. */
- if (RD4(ST_SR) & ST_SR_PITS) {
- hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
- return (FILTER_HANDLED);
- }
- return (FILTER_STRAY);
-}
-
static void
-at91st_initclocks(struct at91st_softc *sc)
+at91_st_initclocks(device_t dev, struct at91_st_softc *sc)
{
int rel_value;
- struct resource *irq;
- int rid = 0;
- void *ih;
- device_t dev = sc->sc_dev;
+
+ /*
+ * Real time counter increments every clock cycle, need to set before
+ * initializing clocks so that DELAY works.
+ */
+ WR4(ST_RTMR, 1);
+ /* disable watchdog timer */
+ WR4(ST_WDMR, 0);
rel_value = 32768 / hz;
if (rel_value < 1)
rel_value = 1;
if (32768 % hz) {
- printf("Cannot get %d Hz clock; using %dHz\n", hz, 32768 / rel_value);
+ device_printf(dev, "Cannot get %d Hz clock; using %dHz\n", hz,
+ 32768 / rel_value);
hz = 32768 / rel_value;
tick = 1000000 / hz;
}
- /* Disable all interrupts. */
- WR4(ST_IDR, 0xffffffff);
- /* The system timer shares the system irq (1) */
- irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1, 1, 1,
- RF_ACTIVE | RF_SHAREABLE);
- if (!irq)
- panic("Unable to allocate irq for the system timer");
- else
- bus_setup_intr(dev, irq, INTR_TYPE_CLK,
- clock_intr, NULL, NULL, &ih);
-
WR4(ST_PIMR, rel_value);
/* Enable PITS interrupts. */
WR4(ST_IER, ST_SR_PITS);
- tc_init(&at91st_timecounter);
+ tc_init(&at91_st_timecounter);
}
diff --git a/sys/arm/at91/at91_streg.h b/sys/arm/at91/at91_streg.h
index 47b1419..48a63c3 100644
--- a/sys/arm/at91/at91_streg.h
+++ b/sys/arm/at91/at91_streg.h
@@ -55,4 +55,7 @@
/* ST_CRTR */
#define ST_CRTR_MASK 0xfffff /* 20-bit counter */
+void at91_st_delay(int n);
+void at91_st_cpu_reset(void);
+
#endif /* ARM_AT91_AT91STREG_H */
diff --git a/sys/arm/at91/at91reg.h b/sys/arm/at91/at91reg.h
index 475da60..e0aaa81 100644
--- a/sys/arm/at91/at91reg.h
+++ b/sys/arm/at91/at91reg.h
@@ -85,4 +85,6 @@
#define AT91_EXID_SAM9G25 0x00000003
#define AT91_EXID_SAM9X25 0x00000004
+#define AT91_IRQ_SYSTEM 1
+
#endif /* _AT91REG_H_ */
diff --git a/sys/arm/at91/at91rm9200.c b/sys/arm/at91/at91rm9200.c
index ddddb78..51627f0 100644
--- a/sys/arm/at91/at91rm9200.c
+++ b/sys/arm/at91/at91rm9200.c
@@ -38,10 +38,14 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <arm/at91/at91var.h>
+#include <arm/at91/at91reg.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91_pmcreg.h>
+#include <arm/at91/at91_streg.h>
#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91soc.h>
+
struct at91rm92_softc {
device_t dev;
@@ -49,8 +53,6 @@ struct at91rm92_softc {
bus_space_handle_t sc_sh;
bus_space_handle_t sc_sys_sh;
bus_space_handle_t sc_aic_sh;
- bus_space_handle_t sc_dbg_sh;
- bus_space_handle_t sc_matrix_sh;
};
/*
* Standard priority levels for the system. 0 is lowest and 7 is highest.
@@ -136,41 +138,6 @@ static const struct cpu_devs at91_devs[] =
};
static void
-at91_add_child(device_t dev, int prio, const char *name, int unit,
- bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
-{
- device_t kid;
- struct at91_ivar *ivar;
-
- kid = device_add_child_ordered(dev, prio, name, unit);
- if (kid == NULL) {
- printf("Can't add child %s%d ordered\n", name, unit);
- return;
- }
- ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (ivar == NULL) {
- device_delete_child(dev, kid);
- printf("Can't add alloc ivar\n");
- return;
- }
- device_set_ivars(kid, ivar);
- resource_list_init(&ivar->resources);
- if (irq0 != -1) {
- bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
- if (irq0 != AT91RM92_IRQ_SYSTEM)
- at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
- }
- if (irq1 != 0)
- bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
- if (irq2 != 0)
- bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
- if (addr != 0 && addr < AT91RM92_BASE)
- addr += AT91RM92_BASE;
- if (addr != 0)
- bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
-}
-
-static void
at91_cpu_add_builtin_children(device_t dev)
{
int i;
@@ -207,7 +174,7 @@ static int
at91_probe(device_t dev)
{
- device_set_desc(dev, soc_data.name);
+ device_set_desc(dev, soc_info.name);
return (0);
}
@@ -228,17 +195,12 @@ at91_attach(device_t dev)
AT91RM92_SYS_SIZE, &sc->sc_sys_sh) != 0)
panic("Enable to map system registers");
- if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_DBGU_BASE,
- AT91RM92_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
- panic("Enable to map DBGU registers");
-
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_AIC_BASE,
AT91RM92_AIC_SIZE, &sc->sc_aic_sh) != 0)
panic("Enable to map system registers");
/* XXX Hack to tell atmelarm about the AIC */
at91sc->sc_aic_sh = sc->sc_aic_sh;
- at91sc->sc_irq_system = AT91RM92_IRQ_SYSTEM;
for (i = 0; i < 32; i++) {
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
@@ -264,9 +226,6 @@ at91_attach(device_t dev)
/* Disable all interrupts for the SDRAM controller */
bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);
- /* Disable all interrupts for DBGU */
- bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
-
/* Update USB device port clock info */
clk = at91_pmc_clock_ref("udpck");
clk->pmc_mask = PMC_SCER_UDP;
@@ -321,3 +280,10 @@ static driver_t at91rm92_driver = {
static devclass_t at91rm92_devclass;
DRIVER_MODULE(at91rm920, atmelarm, at91rm92_driver, at91rm92_devclass, 0, 0);
+
+static struct at91_soc_data soc_data = {
+ .soc_delay = at91_st_delay,
+ .soc_reset = at91_st_cpu_reset
+};
+
+AT91_SOC(AT91_T_RM9200, &soc_data);
diff --git a/sys/arm/at91/at91rm92reg.h b/sys/arm/at91/at91rm92reg.h
index 129c01b..66fad34 100644
--- a/sys/arm/at91/at91rm92reg.h
+++ b/sys/arm/at91/at91rm92reg.h
@@ -70,7 +70,6 @@
* 0xf0000000 - 0xfffffffff : Peripherals
*/
-#define AT91RM92_BASE 0xd0000000
/* Usart */
#define AT91RM92_USART_SIZE 0x4000
diff --git a/sys/arm/at91/at91sam9260.c b/sys/arm/at91/at91sam9260.c
index c246abc..9ea0335 100644
--- a/sys/arm/at91/at91sam9260.c
+++ b/sys/arm/at91/at91sam9260.c
@@ -38,10 +38,14 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <arm/at91/at91var.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91soc.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91sam9260reg.h>
+#include <arm/at91/at91_pitreg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_rstreg.h>
struct at91sam9_softc {
device_t dev;
@@ -49,7 +53,6 @@ struct at91sam9_softc {
bus_space_handle_t sc_sh;
bus_space_handle_t sc_sys_sh;
bus_space_handle_t sc_aic_sh;
- bus_space_handle_t sc_dbg_sh;
bus_space_handle_t sc_matrix_sh;
};
@@ -129,41 +132,6 @@ static const struct cpu_devs at91_devs[] =
};
static void
-at91_add_child(device_t dev, int prio, const char *name, int unit,
- bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
-{
- device_t kid;
- struct at91_ivar *ivar;
-
- kid = device_add_child_ordered(dev, prio, name, unit);
- if (kid == NULL) {
- printf("Can't add child %s%d ordered\n", name, unit);
- return;
- }
- ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (ivar == NULL) {
- device_delete_child(dev, kid);
- printf("Can't add alloc ivar\n");
- return;
- }
- device_set_ivars(kid, ivar);
- resource_list_init(&ivar->resources);
- if (irq0 != -1) {
- bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
- if (irq0 != AT91SAM9260_IRQ_SYSTEM)
- at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
- }
- if (irq1 != 0)
- bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
- if (irq2 != 0)
- bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
- if (addr != 0 && addr < AT91SAM9260_BASE)
- addr += AT91SAM9260_BASE;
- if (addr != 0)
- bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
-}
-
-static void
at91_cpu_add_builtin_children(device_t dev)
{
int i;
@@ -197,7 +165,7 @@ static void
at91_identify(driver_t *drv, device_t parent)
{
- if (soc_data.type == AT91_T_SAM9260) {
+ if (soc_info.type == AT91_T_SAM9260) {
at91_add_child(parent, 0, "at91sam9260", 0, 0, 0, -1, 0, 0);
at91_cpu_add_builtin_children(parent);
}
@@ -207,7 +175,7 @@ static int
at91_probe(device_t dev)
{
- device_set_desc(dev, soc_data.name);
+ device_set_desc(dev, soc_info.name);
return (0);
}
@@ -228,17 +196,12 @@ at91_attach(device_t dev)
AT91SAM9260_SYS_SIZE, &sc->sc_sys_sh) != 0)
panic("Enable to map system registers");
- if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_DBGU_BASE,
- AT91SAM9260_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
- panic("Enable to map DBGU registers");
-
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9260_AIC_BASE,
AT91SAM9260_AIC_SIZE, &sc->sc_aic_sh) != 0)
panic("Enable to map system registers");
/* XXX Hack to tell atmelarm about the AIC */
at91sc->sc_aic_sh = sc->sc_aic_sh;
- at91sc->sc_irq_system = AT91SAM9260_IRQ_SYSTEM;
for (i = 0; i < 32; i++) {
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
@@ -258,9 +221,6 @@ at91_attach(device_t dev)
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
- /* Disable all interrupts for DBGU */
- bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
-
if (bus_space_subregion(sc->sc_st, sc->sc_sh,
AT91SAM9260_MATRIX_BASE, AT91SAM9260_MATRIX_SIZE,
&sc->sc_matrix_sh) != 0)
@@ -336,3 +296,10 @@ static devclass_t at91sam9260_devclass;
DRIVER_MODULE(at91sam9260, atmelarm, at91sam9260_driver, at91sam9260_devclass,
NULL, NULL);
+
+static struct at91_soc_data soc_data = {
+ .soc_delay = at91_pit_delay,
+ .soc_reset = at91_rst_cpu_reset
+};
+
+AT91_SOC(AT91_T_SAM9260, &soc_data);
diff --git a/sys/arm/at91/at91sam9260reg.h b/sys/arm/at91/at91sam9260reg.h
index 659a951..e04afb8 100644
--- a/sys/arm/at91/at91sam9260reg.h
+++ b/sys/arm/at91/at91sam9260reg.h
@@ -72,8 +72,6 @@
#define AT91_CHIPSELECT_7 0x80000000
-#define AT91SAM9260_BASE 0xd0000000
-
#define AT91SAM9260_EMAC_BASE 0xffc4000
#define AT91SAM9260_EMAC_SIZE 0x4000
diff --git a/sys/arm/at91/at91sam9g20.c b/sys/arm/at91/at91sam9g20.c
index 668b057..4b87ad0 100644
--- a/sys/arm/at91/at91sam9g20.c
+++ b/sys/arm/at91/at91sam9g20.c
@@ -38,10 +38,14 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <arm/at91/at91var.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91soc.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91_pitreg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_rstreg.h>
struct at91sam9_softc {
device_t dev;
@@ -49,7 +53,6 @@ struct at91sam9_softc {
bus_space_handle_t sc_sh;
bus_space_handle_t sc_sys_sh;
bus_space_handle_t sc_aic_sh;
- bus_space_handle_t sc_dbg_sh;
bus_space_handle_t sc_matrix_sh;
};
@@ -129,41 +132,6 @@ static const struct cpu_devs at91_devs[] =
};
static void
-at91_add_child(device_t dev, int prio, const char *name, int unit,
- bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
-{
- device_t kid;
- struct at91_ivar *ivar;
-
- kid = device_add_child_ordered(dev, prio, name, unit);
- if (kid == NULL) {
- printf("Can't add child %s%d ordered\n", name, unit);
- return;
- }
- ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (ivar == NULL) {
- device_delete_child(dev, kid);
- printf("Can't add alloc ivar\n");
- return;
- }
- device_set_ivars(kid, ivar);
- resource_list_init(&ivar->resources);
- if (irq0 != -1) {
- bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
- if (irq0 != AT91SAM9G20_IRQ_SYSTEM)
- at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
- }
- if (irq1 != 0)
- bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
- if (irq2 != 0)
- bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
- if (addr != 0 && addr < AT91SAM9G20_BASE)
- addr += AT91SAM9G20_BASE;
- if (addr != 0)
- bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
-}
-
-static void
at91_cpu_add_builtin_children(device_t dev)
{
int i;
@@ -214,7 +182,7 @@ static int
at91_probe(device_t dev)
{
- device_set_desc(dev, soc_data.name);
+ device_set_desc(dev, soc_info.name);
return (0);
}
@@ -239,17 +207,12 @@ at91_attach(device_t dev)
AT91SAM9G20_SYS_SIZE, &sc->sc_sys_sh) != 0)
panic("Enable to map system registers");
- if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_DBGU_BASE,
- AT91SAM9G20_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
- panic("Enable to map DBGU registers");
-
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9G20_AIC_BASE,
AT91SAM9G20_AIC_SIZE, &sc->sc_aic_sh) != 0)
panic("Enable to map system registers");
/* XXX Hack to tell atmelarm about the AIC */
at91sc->sc_aic_sh = sc->sc_aic_sh;
- at91sc->sc_irq_system = AT91SAM9G20_IRQ_SYSTEM;
for (i = 0; i < 32; i++) {
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
@@ -269,9 +232,6 @@ at91_attach(device_t dev)
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
- /* Disable all interrupts for DBGU */
- bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
-
if (bus_space_subregion(sc->sc_st, sc->sc_sh,
AT91SAM9G20_MATRIX_BASE, AT91SAM9G20_MATRIX_SIZE,
&sc->sc_matrix_sh) != 0)
@@ -338,3 +298,10 @@ static driver_t at91sam9_driver = {
static devclass_t at91sam9_devclass;
DRIVER_MODULE(at91sam, atmelarm, at91sam9_driver, at91sam9_devclass, 0, 0);
+
+static struct at91_soc_data soc_data = {
+ .soc_delay = at91_pit_delay,
+ .soc_reset = at91_rst_cpu_reset
+};
+
+AT91_SOC(AT91_T_SAM9G20, &soc_data);
diff --git a/sys/arm/at91/at91sam9g20reg.h b/sys/arm/at91/at91sam9g20reg.h
index 7311ade..ab686c3 100644
--- a/sys/arm/at91/at91sam9g20reg.h
+++ b/sys/arm/at91/at91sam9g20reg.h
@@ -73,8 +73,6 @@
#define AT91_CHIPSELECT_7 0x80000000
-#define AT91SAM9G20_BASE 0xd0000000
-
#define AT91SAM9G20_EMAC_BASE 0xffc4000
#define AT91SAM9G20_EMAC_SIZE 0x4000
diff --git a/sys/arm/at91/at91sam9x25.c b/sys/arm/at91/at91sam9x25.c
index fa19300..b84d30c 100644
--- a/sys/arm/at91/at91sam9x25.c
+++ b/sys/arm/at91/at91sam9x25.c
@@ -38,10 +38,14 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <arm/at91/at91var.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91soc.h>
#include <arm/at91/at91_aicreg.h>
#include <arm/at91/at91sam9x25reg.h>
+#include <arm/at91/at91_pitreg.h>
#include <arm/at91/at91_pmcreg.h>
#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_rstreg.h>
struct at91sam9x25_softc {
device_t dev;
@@ -49,8 +53,6 @@ struct at91sam9x25_softc {
bus_space_handle_t sc_sh;
bus_space_handle_t sc_sys_sh;
bus_space_handle_t sc_aic_sh;
- bus_space_handle_t sc_dbg_sh;
- bus_space_handle_t sc_matrix_sh;
};
/*
@@ -132,41 +134,6 @@ static const struct cpu_devs at91_devs[] =
};
static void
-at91_add_child(device_t dev, int prio, const char *name, int unit,
- bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
-{
- device_t kid;
- struct at91_ivar *ivar;
-
- kid = device_add_child_ordered(dev, prio, name, unit);
- if (kid == NULL) {
- printf("Can't add child %s%d ordered\n", name, unit);
- return;
- }
- ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (ivar == NULL) {
- device_delete_child(dev, kid);
- printf("Can't add alloc ivar\n");
- return;
- }
- device_set_ivars(kid, ivar);
- resource_list_init(&ivar->resources);
- if (irq0 != -1) {
- bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
- if (irq0 != AT91SAM9X25_IRQ_SYSTEM)
- at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
- }
- if (irq1 != 0)
- bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
- if (irq2 != 0)
- bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
- if (addr != 0 && addr < AT91SAM9X25_BASE)
- addr += AT91SAM9X25_BASE;
- if (addr != 0)
- bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
-}
-
-static void
at91_cpu_add_builtin_children(device_t dev)
{
int i;
@@ -207,7 +174,7 @@ static void
at91_identify(driver_t *drv, device_t parent)
{
- if (soc_data.type == AT91_T_SAM9X5 && soc_data.subtype == AT91_ST_SAM9X25) {
+ if (soc_info.type == AT91_T_SAM9X5 && soc_info.subtype == AT91_ST_SAM9X25) {
at91_add_child(parent, 0, "at91sam9x25", 0, 0, 0, -1, 0, 0);
at91_cpu_add_builtin_children(parent);
}
@@ -242,17 +209,12 @@ at91_attach(device_t dev)
AT91SAM9X25_SYS_SIZE, &sc->sc_sys_sh) != 0)
panic("Enable to map system registers");
- if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9X25_DBGU_BASE,
- AT91SAM9X25_DBGU_SIZE, &sc->sc_dbg_sh) != 0)
- panic("Enable to map DBGU registers");
-
if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91SAM9X25_AIC_BASE,
AT91SAM9X25_AIC_SIZE, &sc->sc_aic_sh) != 0)
panic("Enable to map system registers");
/* XXX Hack to tell atmelarm about the AIC */
at91sc->sc_aic_sh = sc->sc_aic_sh;
- at91sc->sc_irq_system = AT91SAM9X25_IRQ_SYSTEM;
for (i = 0; i < 32; i++) {
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR +
@@ -272,23 +234,6 @@ at91_attach(device_t dev)
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff);
bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff);
- /* Disable all interrupts for DBGU */
- bus_space_write_4(sc->sc_st, sc->sc_dbg_sh, 0x0c, 0xffffffff);
-
- if (bus_space_subregion(sc->sc_st, sc->sc_sh,
- AT91SAM9X25_MATRIX_BASE, AT91SAM9X25_MATRIX_SIZE,
- &sc->sc_matrix_sh) != 0)
- panic("Enable to map matrix registers");
-
-#if 0 /* wrong, placeholder */
- /* activate NAND*/
- i = bus_space_read_4(sc->sc_st, sc->sc_matrix_sh,
- AT91SAM9X25_EBICSA);
- bus_space_write_4(sc->sc_st, sc->sc_matrix_sh,
- AT91SAM9X25_EBICSA,
- i | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
-#endif
-
/* Update USB device port clock info */
clk = at91_pmc_clock_ref("udpck");
clk->pmc_mask = PMC_SCER_UDP_SAM9;
@@ -342,3 +287,10 @@ static driver_t at91sam9x25_driver = {
static devclass_t at91sam9x25_devclass;
DRIVER_MODULE(at91sam9x25, atmelarm, at91sam9x25_driver, at91sam9x25_devclass, 0, 0);
+
+static struct at91_soc_data soc_data = {
+ .soc_delay = at91_pit_delay,
+ .soc_reset = at91_rst_cpu_reset
+};
+
+AT91_SOC_SUB(AT91_T_SAM9X5, AT91_ST_SAM9X25, &soc_data);
diff --git a/sys/arm/at91/at91sam9x25reg.h b/sys/arm/at91/at91sam9x25reg.h
index e8bc0e5..d497e2b 100644
--- a/sys/arm/at91/at91sam9x25reg.h
+++ b/sys/arm/at91/at91sam9x25reg.h
@@ -73,8 +73,6 @@
#define AT91_CHIPSELECT_4 0x50000000
#define AT91_CHIPSELECT_5 0x60000000
-#define AT91SAM9X25_BASE 0xd0000000
-
#define AT91SAM9X25_EMAC_SIZE 0x4000
#define AT91SAM9X25_EMAC0_BASE 0x802c000
#define AT91SAM9X25_EMAC0_SIZE AT91SAM9X25_EMAC_SIZE
diff --git a/sys/arm/at91/at91soc.c b/sys/arm/at91/at91soc.c
new file mode 100644
index 0000000..7031e83
--- /dev/null
+++ b/sys/arm/at91/at91soc.c
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2012 Warner Losh. 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 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 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91soc.h>
+
+SET_DECLARE(at91_socs, const struct at91_soc);
+
+struct at91_soc_data *
+at91_match_soc(enum at91_soc_type type, enum at91_soc_subtype subtype)
+{
+ const struct at91_soc **socp;
+
+ SET_FOREACH(socp, at91_socs) {
+ if ((*socp)->soc_type != type)
+ continue;
+ if ((*socp)->soc_subtype != AT91_ST_ANY &&
+ (*socp)->soc_subtype != subtype)
+ continue;
+ return (*socp)->soc_data;
+ }
+ return NULL;
+}
diff --git a/sys/arm/at91/at91soc.h b/sys/arm/at91/at91soc.h
new file mode 100644
index 0000000..e2f4d41
--- /dev/null
+++ b/sys/arm/at91/at91soc.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2012 Warner Losh. 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 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 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.
+ */
+
+/* $FreeBSD$ */
+
+#ifndef _ARM_AT91_AT91SOC_H_
+#define _ARM_AT91_AT91SOC_H_
+
+#include <sys/linker_set.h>
+
+struct at91_soc {
+ enum at91_soc_type soc_type; /* Family of mail type of SoC */
+ enum at91_soc_subtype soc_subtype; /* More specific soc, if any */
+ struct at91_soc_data *soc_data;
+};
+
+// Make varadic
+#define AT91_SOC(type, data) \
+ static struct at91_soc this_soc = { \
+ .soc_type = type, \
+ .soc_subtype = AT91_ST_ANY, \
+ .soc_data = data, \
+ }; \
+ DATA_SET(at91_socs, this_soc);
+
+#define AT91_SOC_SUB(type, subtype, data) \
+ static struct at91_soc this_soc = { \
+ .soc_type = type, \
+ .soc_subtype = subtype, \
+ .soc_data = data, \
+ }; \
+ DATA_SET(at91_socs, this_soc);
+
+struct at91_soc_data *at91_match_soc(enum at91_soc_type, enum at91_soc_subtype);
+
+#endif /* _ARM_AT91_AT91SOC_H_ */
diff --git a/sys/arm/at91/at91var.h b/sys/arm/at91/at91var.h
index 7a3ce95..183b723 100644
--- a/sys/arm/at91/at91var.h
+++ b/sys/arm/at91/at91var.h
@@ -40,7 +40,6 @@ struct at91_softc {
bus_space_handle_t sc_aic_sh;
struct rman sc_irq_rman;
struct rman sc_mem_rman;
- uint32_t sc_irq_system;
};
struct at91_ivar {
@@ -75,6 +74,7 @@ enum at91_soc_type {
};
enum at91_soc_subtype {
+ AT91_ST_ANY = -1, /* Match any type */
AT91_ST_NONE = 0,
/* AT91RM9200 */
AT91_ST_RM9200_BGA,
@@ -105,6 +105,11 @@ enum at91_soc_family {
typedef void (*DELAY_t)(int);
typedef void (*cpu_reset_t)(void);
+struct at91_soc_data {
+ DELAY_t soc_delay;
+ cpu_reset_t soc_reset;
+};
+
struct at91_soc_info {
enum at91_soc_type type;
enum at91_soc_subtype subtype;
@@ -112,11 +117,10 @@ struct at91_soc_info {
uint32_t cidr;
uint32_t exid;
char name[AT91_SOC_NAME_MAX];
- DELAY_t delay;
- cpu_reset_t reset;
+ struct at91_soc_data *soc_data;
};
-extern struct at91_soc_info soc_data;
+extern struct at91_soc_info soc_info;
static inline int at91_is_rm92(void);
static inline int at91_is_sam9(void);
@@ -127,30 +131,33 @@ static inline int
at91_is_rm92(void)
{
- return (soc_data.type == AT91_T_RM9200);
+ return (soc_info.type == AT91_T_RM9200);
}
static inline int
at91_is_sam9(void)
{
- return (soc_data.family == AT91_FAMILY_SAM9);
+ return (soc_info.family == AT91_FAMILY_SAM9);
}
static inline int
at91_is_sam9xe(void)
{
- return (soc_data.family == AT91_FAMILY_SAM9XE);
+ return (soc_info.family == AT91_FAMILY_SAM9XE);
}
static inline int
at91_cpu_is(u_int cpu)
{
- return (soc_data.type == cpu);
+ return (soc_info.type == cpu);
}
+void at91_add_child(device_t dev, int prio, const char *name, int unit,
+ bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2);
+
extern uint32_t at91_irq_system;
extern uint32_t at91_master_clock;
void at91_pmc_init_clock(void);
diff --git a/sys/arm/at91/files.at91 b/sys/arm/at91/files.at91
index 0816901..8e3a75d 100644
--- a/sys/arm/at91/files.at91
+++ b/sys/arm/at91/files.at91
@@ -27,6 +27,7 @@ arm/at91/uart_dev_at91usart.c optional uart
#
# All the "systems on a chip" we support
#
+arm/at91/at91soc.c standard
arm/at91/at91rm9200.c optional at91rm9200
arm/at91/at91sam9260.c optional at91sam9260
arm/at91/at91sam9g20.c optional at91sam9g20
diff --git a/sys/arm/at91/uart_bus_at91usart.c b/sys/arm/at91/uart_bus_at91usart.c
index c5e3f82..b042537 100644
--- a/sys/arm/at91/uart_bus_at91usart.c
+++ b/sys/arm/at91/uart_bus_at91usart.c
@@ -42,33 +42,32 @@ __FBSDID("$FreeBSD$");
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
-#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91var.h>
#include "uart_if.h"
-static int usart_at91rm92_probe(device_t dev);
+static int usart_at91_probe(device_t dev);
extern struct uart_class at91_usart_class;
-static device_method_t usart_at91rm92_methods[] = {
+static device_method_t usart_at91_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, usart_at91rm92_probe),
+ DEVMETHOD(device_probe, usart_at91_probe),
DEVMETHOD(device_attach, uart_bus_attach),
DEVMETHOD(device_detach, uart_bus_detach),
{ 0, 0 }
};
-static driver_t usart_at91rm92_driver = {
+static driver_t usart_at91_driver = {
uart_driver_name,
- usart_at91rm92_methods,
+ usart_at91_methods,
sizeof(struct uart_softc),
};
extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
static int
-usart_at91rm92_probe(device_t dev)
+usart_at91_probe(device_t dev)
{
struct uart_softc *sc;
@@ -104,4 +103,4 @@ usart_at91rm92_probe(device_t dev)
}
-DRIVER_MODULE(uart, atmelarm, usart_at91rm92_driver, uart_devclass, 0, 0);
+DRIVER_MODULE(uart, atmelarm, usart_at91_driver, uart_devclass, 0, 0);
diff --git a/sys/arm/at91/uart_cpu_at91rm9200usart.c b/sys/arm/at91/uart_cpu_at91rm9200usart.c
index 098e368..cb39bf9 100644
--- a/sys/arm/at91/uart_cpu_at91rm9200usart.c
+++ b/sys/arm/at91/uart_cpu_at91rm9200usart.c
@@ -73,7 +73,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
* XXX: Not pretty, but will work because we map the needed addresses
* early.
*/
- di->bas.bsh = AT91RM92_BASE + AT91RM92_DBGU_BASE;
+ di->bas.bsh = AT91_BASE + AT91RM92_DBGU_BASE;
di->baudrate = 115200;
di->bas.regshft = 0;
di->bas.rclk = 0;
diff --git a/sys/arm/conf/KB920X b/sys/arm/conf/KB920X
index ea50c8b..d102f5f 100644
--- a/sys/arm/conf/KB920X
+++ b/sys/arm/conf/KB920X
@@ -24,7 +24,7 @@ include "../at91/std.kb920x"
# The AT91 platform doesn't use /boot/loader, so we have to statically wire
# hints.
hints "KB920X.hints"
-#makeoptions MODULES_OVERRIDE=""
+makeoptions MODULES_OVERRIDE=""
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
options DDB
@@ -137,6 +137,7 @@ device wlan_wep # 802.11 WEP support
device wlan_ccmp # 802.11 CCMP support
device wlan_tkip # 802.11 TKIP support
device wlan_amrr # AMRR transmit rate control algorithm
+
options IEEE80211_SUPPORT_MESH
options AH_SUPPORT_AR5416
diff --git a/sys/arm/econa/econa_machdep.c b/sys/arm/econa/econa_machdep.c
index 62c8a1b..de18fd1 100644
--- a/sys/arm/econa/econa_machdep.c
+++ b/sys/arm/econa/econa_machdep.c
@@ -103,10 +103,6 @@ extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-extern void *_end;
-
-extern int *end;
-
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
@@ -114,7 +110,6 @@ struct pcpu *pcpup = &__pcpu;
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
-vm_offset_t physical_pages;
struct pv_addr systempage;
struct pv_addr msgbufpv;
diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c
index bb08933..0c12aea 100644
--- a/sys/arm/mv/mv_machdep.c
+++ b/sys/arm/mv/mv_machdep.c
@@ -115,16 +115,11 @@ extern unsigned char _edata[];
extern unsigned char __bss_start[];
extern unsigned char _end[];
-#ifdef DDB
-extern vm_offset_t ksym_start, ksym_end;
-#endif
-
extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
extern vm_offset_t pmap_bootstrap_lastaddr;
-extern int *end;
struct pv_addr kernel_pt_table[KERNEL_PT_MAX];
struct pcpu __pcpu;
@@ -134,7 +129,6 @@ struct pcpu *pcpup = &__pcpu;
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
-vm_offset_t physical_pages;
vm_offset_t pmap_bootstrap_lastaddr;
const struct pmap_devmap *pmap_devmap_bootstrap_table;
diff --git a/sys/arm/s3c2xx0/s3c24x0_machdep.c b/sys/arm/s3c2xx0/s3c24x0_machdep.c
index caf4ba8..4f14c5c 100644
--- a/sys/arm/s3c2xx0/s3c24x0_machdep.c
+++ b/sys/arm/s3c2xx0/s3c24x0_machdep.c
@@ -118,10 +118,6 @@ extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-extern void *_end;
-
-extern int *end;
-
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
@@ -129,7 +125,6 @@ struct pcpu *pcpup = &__pcpu;
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
-vm_offset_t physical_pages;
struct pv_addr systempage;
struct pv_addr msgbufpv;
@@ -203,10 +198,6 @@ static const struct pmap_devmap s3c24x0_devmap[] = {
#define ioreg_read32(a) (*(volatile uint32_t *)(a))
#define ioreg_write32(a,v) (*(volatile uint32_t *)(a)=(v))
-#ifdef DDB
-extern vm_offset_t ksym_start, ksym_end;
-#endif
-
struct arm32_dma_range s3c24x0_range = {
.dr_sysbase = 0,
.dr_busbase = 0,
diff --git a/sys/arm/sa11x0/assabet_machdep.c b/sys/arm/sa11x0/assabet_machdep.c
index 9bc80d5..3a3e0f9 100644
--- a/sys/arm/sa11x0/assabet_machdep.c
+++ b/sys/arm/sa11x0/assabet_machdep.c
@@ -119,14 +119,10 @@ extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-extern void *_end;
-
extern vm_offset_t sa1110_uart_vaddr;
extern vm_offset_t sa1_cache_clean_addr;
-extern int *end;
-
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
@@ -140,7 +136,6 @@ vm_paddr_t dump_avail[4];
vm_paddr_t physical_start;
vm_paddr_t physical_end;
vm_paddr_t physical_freestart;
-vm_offset_t physical_pages;
struct pv_addr systempage;
struct pv_addr irqstack;
diff --git a/sys/arm/xscale/i80321/ep80219_machdep.c b/sys/arm/xscale/i80321/ep80219_machdep.c
index 0508244..fe781cc 100644
--- a/sys/arm/xscale/i80321/ep80219_machdep.c
+++ b/sys/arm/xscale/i80321/ep80219_machdep.c
@@ -115,10 +115,6 @@ extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-extern void *_end;
-
-extern int *end;
-
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
@@ -126,7 +122,6 @@ struct pcpu *pcpup = &__pcpu;
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
-vm_offset_t physical_pages;
struct pv_addr systempage;
struct pv_addr msgbufpv;
diff --git a/sys/arm/xscale/i80321/iq31244_machdep.c b/sys/arm/xscale/i80321/iq31244_machdep.c
index 9790c0b..e9f3fae 100644
--- a/sys/arm/xscale/i80321/iq31244_machdep.c
+++ b/sys/arm/xscale/i80321/iq31244_machdep.c
@@ -115,10 +115,6 @@ extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-extern void *_end;
-
-extern int *end;
-
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
@@ -126,7 +122,6 @@ struct pcpu *pcpup = &__pcpu;
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
-vm_offset_t physical_pages;
struct pv_addr systempage;
struct pv_addr msgbufpv;
diff --git a/sys/arm/xscale/i8134x/crb_machdep.c b/sys/arm/xscale/i8134x/crb_machdep.c
index 8567b17..2fa7ca1 100644
--- a/sys/arm/xscale/i8134x/crb_machdep.c
+++ b/sys/arm/xscale/i8134x/crb_machdep.c
@@ -117,7 +117,6 @@ extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-extern int *end;
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
@@ -126,7 +125,6 @@ struct pcpu *pcpup = &__pcpu;
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
-vm_offset_t physical_pages;
struct pv_addr systempage;
struct pv_addr msgbufpv;
diff --git a/sys/arm/xscale/ixp425/avila_machdep.c b/sys/arm/xscale/ixp425/avila_machdep.c
index 5c1819c..6c87510 100644
--- a/sys/arm/xscale/ixp425/avila_machdep.c
+++ b/sys/arm/xscale/ixp425/avila_machdep.c
@@ -119,10 +119,6 @@ extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-extern void *_end;
-
-extern int *end;
-
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
@@ -130,7 +126,6 @@ struct pcpu *pcpup = &__pcpu;
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
-vm_offset_t physical_pages;
struct pv_addr systempage;
struct pv_addr msgbufpv;
diff --git a/sys/arm/xscale/pxa/pxa_machdep.c b/sys/arm/xscale/pxa/pxa_machdep.c
index da5787a..d0e3f0c 100644
--- a/sys/arm/xscale/pxa/pxa_machdep.c
+++ b/sys/arm/xscale/pxa/pxa_machdep.c
@@ -115,10 +115,6 @@ extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-extern void *_end;
-
-extern int *end;
-
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
@@ -126,7 +122,6 @@ struct pcpu *pcpup = &__pcpu;
vm_paddr_t phys_avail[PXA2X0_SDRAM_BANKS * 2 + 4];
vm_paddr_t dump_avail[PXA2X0_SDRAM_BANKS * 2 + 4];
-vm_offset_t physical_pages;
struct pv_addr systempage;
struct pv_addr msgbufpv;
diff --git a/sys/arm/xscale/std.xscale b/sys/arm/xscale/std.xscale
index 2e5ea81..336000b 100644
--- a/sys/arm/xscale/std.xscale
+++ b/sys/arm/xscale/std.xscale
@@ -1,3 +1,3 @@
# $FreeBSD$
-machine arm armeb
+# machine arm armeb
options ARM_CACHE_LOCK_ENABLE
diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c
index 5faf68e..5135efb 100644
--- a/sys/cam/ata/ata_all.c
+++ b/sys/cam/ata/ata_all.c
@@ -171,8 +171,8 @@ ata_op_string(struct ata_cmd *cmd)
case 0xf2: return ("SECURITY_UNLOCK");
case 0xf3: return ("SECURITY_ERASE_PREPARE");
case 0xf4: return ("SECURITY_ERASE_UNIT");
- case 0xf5: return ("SECURITY_FREE_LOCK");
- case 0xf6: return ("SECURITY DISABLE PASSWORD");
+ case 0xf5: return ("SECURITY_FREEZE_LOCK");
+ case 0xf6: return ("SECURITY_DISABLE_PASSWORD");
case 0xf8: return ("READ_NATIVE_MAX_ADDRESS");
case 0xf9: return ("SET_MAX_ADDRESS");
}
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index ae40b3c..08c756e 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -368,9 +368,9 @@ TUNABLE_INT("kern.cam.ada.retry_count", &ada_retry_count);
SYSCTL_INT(_kern_cam_ada, OID_AUTO, default_timeout, CTLFLAG_RW,
&ada_default_timeout, 0, "Normal I/O timeout (in seconds)");
TUNABLE_INT("kern.cam.ada.default_timeout", &ada_default_timeout);
-SYSCTL_INT(_kern_cam_ada, OID_AUTO, ada_send_ordered, CTLFLAG_RW,
+SYSCTL_INT(_kern_cam_ada, OID_AUTO, send_ordered, CTLFLAG_RW,
&ada_send_ordered, 0, "Send Ordered Tags");
-TUNABLE_INT("kern.cam.ada.ada_send_ordered", &ada_send_ordered);
+TUNABLE_INT("kern.cam.ada.send_ordered", &ada_send_ordered);
SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_shutdown, CTLFLAG_RW,
&ada_spindown_shutdown, 0, "Spin down upon shutdown");
TUNABLE_INT("kern.cam.ada.spindown_shutdown", &ada_spindown_shutdown);
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index e842af6..8a5c72a 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -883,9 +883,9 @@ TUNABLE_INT("kern.cam.da.retry_count", &da_retry_count);
SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
&da_default_timeout, 0, "Normal I/O timeout (in seconds)");
TUNABLE_INT("kern.cam.da.default_timeout", &da_default_timeout);
-SYSCTL_INT(_kern_cam_da, OID_AUTO, da_send_ordered, CTLFLAG_RW,
+SYSCTL_INT(_kern_cam_da, OID_AUTO, send_ordered, CTLFLAG_RW,
&da_send_ordered, 0, "Send Ordered Tags");
-TUNABLE_INT("kern.cam.da.da_send_ordered", &da_send_ordered);
+TUNABLE_INT("kern.cam.da.send_ordered", &da_send_ordered);
/*
* DA_ORDEREDTAG_INTERVAL determines how often, relative
diff --git a/sys/conf/files b/sys/conf/files
index 76bd91c..c0c52da 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -412,6 +412,7 @@ contrib/dev/acpica/components/tables/tbfind.c optional acpi
contrib/dev/acpica/components/tables/tbinstal.c optional acpi
contrib/dev/acpica/components/tables/tbutils.c optional acpi
contrib/dev/acpica/components/tables/tbxface.c optional acpi
+contrib/dev/acpica/components/tables/tbxfload.c optional acpi
contrib/dev/acpica/components/tables/tbxfroot.c optional acpi
contrib/dev/acpica/components/utilities/utaddress.c optional acpi
contrib/dev/acpica/components/utilities/utalloc.c optional acpi
@@ -421,6 +422,7 @@ contrib/dev/acpica/components/utilities/utdebug.c optional acpi
contrib/dev/acpica/components/utilities/utdecode.c optional acpi
contrib/dev/acpica/components/utilities/utdelete.c optional acpi
contrib/dev/acpica/components/utilities/uteval.c optional acpi
+contrib/dev/acpica/components/utilities/utexcep.c optional acpi
contrib/dev/acpica/components/utilities/utglobal.c optional acpi
contrib/dev/acpica/components/utilities/utids.c optional acpi
contrib/dev/acpica/components/utilities/utinit.c optional acpi
diff --git a/sys/contrib/dev/acpica/changes.txt b/sys/contrib/dev/acpica/changes.txt
index 2123937..605e678 100644
--- a/sys/contrib/dev/acpica/changes.txt
+++ b/sys/contrib/dev/acpica/changes.txt
@@ -1,4 +1,82 @@
----------------------------------------
+11 July 2012. Summary of changes for version 20120711:
+
+This release is available at https://www.acpica.org/downloads The ACPI 5.0
+specification is available at www.acpi.info
+
+1) ACPICA Kernel-resident Subsystem:
+
+Fixed a possible fault in the return package object repair code. Fixes a
+problem that can occur when a lone package object is wrapped with an outer
+package object in order to force conformance to the ACPI specification. Can
+affect these predefined names: _ALR, _MLS, _PSS, _TRT, _TSS, _PRT, _HPX, _DLM,
+_CSD, _PSD, _TSD.
+
+Removed code to disable/enable bus master arbitration (ARB_DIS bit in the
+PM2_CNT register) in the ACPICA sleep/wake interfaces. Management of the
+ARB_DIS bit must be implemented in the host-dependent C3 processor power state
+support. Note, ARB_DIS is obsolete and only applies to older chipsets, both
+Intel and other vendors. (for Intel: ICH4-M and earlier)
+
+This change removes the code to disable/enable bus master arbitration during
+suspend/resume. Use of the ARB_DIS bit in the optional PM2_CNT register causes
+resume problems on some machines. The change has been in use for over seven
+years within Linux.
+
+Implemented two new external interfaces to support host-directed dynamic ACPI
+table load and unload. They are intended to simplify the host implementation
+of hot-plug support:
+ AcpiLoadTable: Load an SSDT from a buffer into the namespace.
+ AcpiUnloadParentTable: Unload an SSDT via a named object owned by the table.
+See the ACPICA reference for additional details. Adds one new file,
+components/tables/tbxfload.c
+
+Implemented and deployed two new interfaces for errors and warnings that are
+known to be caused by BIOS/firmware issues:
+ AcpiBiosError: Prints "ACPI Firmware Error" message.
+ AcpiBiosWarning: Prints "ACPI Firmware Warning" message.
+Deployed these new interfaces in the ACPICA Table Manager code for ACPI table
+and FADT errors. Additional deployment to be completed as appropriate in the
+future. The associated conditional macros are ACPI_BIOS_ERROR and
+ACPI_BIOS_WARNING. See the ACPICA reference for additional details. ACPICA BZ
+843.
+
+Implicit notify support: ensure that no memory allocation occurs within a
+critical region. This fix moves a memory allocation outside of the time that a
+spinlock is held. Fixes issues on systems that do not allow this behavior.
+Jung-uk Kim.
+
+Split exception code utilities and tables into a new file, utilities/utexcep.c
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug
+version of the code includes the debug output trace mechanism and has a much
+larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 93.1K Code, 25.1K Data, 118.2K Total
+ Debug Version: 172.9K Code, 73.6K Data, 246.5K Total
+ Current Release:
+ Non-Debug Version: 93.5K Code, 25.3K Data, 118.8K Total
+ Debug Version: 173.7K Code, 74.0K Data, 247.7K Total
+
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Fixed a parser problem for hosts where EOF is defined as -1 instead of
+0. Jung-uk Kim.
+
+Debugger: Enhanced the "tables" command to emit additional information about
+the current set of ACPI tables, including the owner ID and flags decode.
+
+Debugger: Reimplemented the "unload" command to use the new
+AcpiUnloadParentTable external interface. This command was disable previously
+due to need for an unload interface.
+
+AcpiHelp: Added a new option to decode ACPICA exception codes. The -e option
+will decode 16-bit hex status codes (ACPI_STATUS) to name strings.
+
+----------------------------------------
20 June 2012. Summary of changes for version 20120620:
This release is available at https://www.acpica.org/downloads
diff --git a/sys/contrib/dev/acpica/compiler/aslmain.c b/sys/contrib/dev/acpica/compiler/aslmain.c
index c17fc95..5a8fa2f 100644
--- a/sys/contrib/dev/acpica/compiler/aslmain.c
+++ b/sys/contrib/dev/acpica/compiler/aslmain.c
@@ -96,7 +96,7 @@ AslDoResponseFile (
#define ASL_TOKEN_SEPARATORS " \t\n"
-#define ASL_SUPPORTED_OPTIONS "@:2b|c|d^D:e:fgh^i|I:l^mno|p:P^r:s|t|T:G^v|w|x:z"
+#define ASL_SUPPORTED_OPTIONS "@:2b|c|d^D:e:fgh^i|I:l^mno|p:P^r:s|t|T:G^v^w|x:z"
/*******************************************************************************
@@ -119,6 +119,7 @@ Options (
printf ("\nGlobal:\n");
ACPI_OPTION ("-@ <file>", "Specify command file");
ACPI_OPTION ("-I <dir>", "Specify additional include directory");
+ ACPI_OPTION ("-v", "Display compiler version");
printf ("\nPreprocessor:\n");
ACPI_OPTION ("-D <symbol>", "Define symbol for preprocessor use");
@@ -751,9 +752,13 @@ AslDoOptions (
break;
- case 'v': /* Verbosity settings */
+ case 'v': /* Version and verbosity settings */
switch (AcpiGbl_Optarg[0])
{
+ case '^':
+ printf (ACPI_COMMON_SIGNON (ASL_COMPILER_NAME));
+ exit (0);
+
case 'a':
/* Disable All error/warning messages */
diff --git a/sys/contrib/dev/acpica/components/debugger/dbcmds.c b/sys/contrib/dev/acpica/components/debugger/dbcmds.c
index 033b1fd..2b18653 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbcmds.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbcmds.c
@@ -254,12 +254,53 @@ AcpiDbDisplayTableInfo (
ACPI_STATUS Status;
+ /* Header */
+
+ AcpiOsPrintf ("Idx ID Status Type Sig Address Len Header\n");
+
/* Walk the entire root table list */
for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
{
TableDesc = &AcpiGbl_RootTableList.Tables[i];
- AcpiOsPrintf ("%u ", i);
+
+ /* Index and Table ID */
+
+ AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId);
+
+ /* Decode the table flags */
+
+ if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED))
+ {
+ AcpiOsPrintf ("NotLoaded ");
+ }
+ else
+ {
+ AcpiOsPrintf (" Loaded ");
+ }
+
+ switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
+ {
+ case ACPI_TABLE_ORIGIN_UNKNOWN:
+ AcpiOsPrintf ("Unknown ");
+ break;
+
+ case ACPI_TABLE_ORIGIN_MAPPED:
+ AcpiOsPrintf ("Mapped ");
+ break;
+
+ case ACPI_TABLE_ORIGIN_ALLOCATED:
+ AcpiOsPrintf ("Allocated ");
+ break;
+
+ case ACPI_TABLE_ORIGIN_OVERRIDE:
+ AcpiOsPrintf ("Override ");
+ break;
+
+ default:
+ AcpiOsPrintf ("INVALID ");
+ break;
+ }
/* Make sure that the table is mapped */
@@ -290,55 +331,45 @@ AcpiDbDisplayTableInfo (
*
* FUNCTION: AcpiDbUnloadAcpiTable
*
- * PARAMETERS: TableArg - Name of the table to be unloaded
- * InstanceArg - Which instance of the table to unload (if
- * there are multiple tables of the same type)
+ * PARAMETERS: ObjectName - Namespace pathname for an object that
+ * is owned by the table to be unloaded
*
- * RETURN: Nonde
+ * RETURN: None
*
- * DESCRIPTION: Unload an ACPI table.
- * Instance is not implemented
+ * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
+ * by the table.
*
******************************************************************************/
void
AcpiDbUnloadAcpiTable (
- char *TableArg,
- char *InstanceArg)
+ char *ObjectName)
{
-/* TBD: Need to reimplement for new data structures */
-
-#if 0
- UINT32 i;
+ ACPI_NAMESPACE_NODE *Node;
ACPI_STATUS Status;
- /* Search all tables for the target type */
+ /* Translate name to an Named object */
- for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++)
+ Node = AcpiDbConvertToNode (ObjectName);
+ if (!Node)
{
- if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
- AcpiGbl_TableData[i].SigLength))
- {
- /* Found the table, unload it */
-
- Status = AcpiUnloadTable (i);
- if (ACPI_SUCCESS (Status))
- {
- AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
- }
- else
- {
- AcpiOsPrintf ("%s, while unloading [%s]\n",
- AcpiFormatException (Status), TableArg);
- }
-
- return;
- }
+ AcpiOsPrintf ("Could not find [%s] in namespace\n",
+ ObjectName);
+ return;
}
- AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
-#endif
+ Status = AcpiUnloadParentTable (ACPI_CAST_PTR (ACPI_HANDLE, Node));
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiOsPrintf ("Parent of [%s] (%p) unloaded and uninstalled\n",
+ ObjectName, Node);
+ }
+ else
+ {
+ AcpiOsPrintf ("%s, while unloading parent table of [%s]\n",
+ AcpiFormatException (Status), ObjectName);
+ }
}
diff --git a/sys/contrib/dev/acpica/components/debugger/dbinput.c b/sys/contrib/dev/acpica/components/debugger/dbinput.c
index e56fad9..f18398c 100644
--- a/sys/contrib/dev/acpica/components/debugger/dbinput.c
+++ b/sys/contrib/dev/acpica/components/debugger/dbinput.c
@@ -250,7 +250,7 @@ AcpiDbDisplayHelp (
AcpiOsPrintf (" Stack Display CPU stack usage\n");
AcpiOsPrintf (" Tables Info about current ACPI table(s)\n");
AcpiOsPrintf (" Tables Display info about loaded ACPI tables\n");
- AcpiOsPrintf (" Unload <TableSig> [Instance] Unload an ACPI table\n");
+ AcpiOsPrintf (" Unload <Namepath> Unload an ACPI table via namespace object\n");
AcpiOsPrintf (" ! <CommandNumber> Execute command from history buffer\n");
AcpiOsPrintf (" !! Execute last command again\n");
@@ -894,7 +894,7 @@ AcpiDbCommandDispatch (
break;
case CMD_UNLOAD:
- AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1]);
break;
case CMD_EXIT:
diff --git a/sys/contrib/dev/acpica/components/events/evxfgpe.c b/sys/contrib/dev/acpica/components/events/evxfgpe.c
index 3a43733..7befa99d 100644
--- a/sys/contrib/dev/acpica/components/events/evxfgpe.c
+++ b/sys/contrib/dev/acpica/components/events/evxfgpe.c
@@ -83,7 +83,7 @@ AcpiUpdateAllGpes (
ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE (AcpiUpdateGpes);
+ ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
@@ -298,7 +298,8 @@ AcpiSetupGpeForWake (
ACPI_STATUS Status;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_NAMESPACE_NODE *DeviceNode;
- ACPI_GPE_NOTIFY_INFO *NewNotify, *Notify;
+ ACPI_GPE_NOTIFY_INFO *Notify;
+ ACPI_GPE_NOTIFY_INFO *NewNotify;
ACPI_CPU_FLAGS Flags;
@@ -334,6 +335,11 @@ AcpiSetupGpeForWake (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
+ /*
+ * Allocate a new notify object up front, in case it is needed.
+ * Memory allocation while holding a spinlock is a big no-no
+ * on some hosts.
+ */
NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
if (!NewNotify)
{
@@ -401,8 +407,12 @@ AcpiSetupGpeForWake (
GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
Status = AE_OK;
+
UnlockAndExit:
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+
+ /* Delete the notify object if it was not used above */
+
if (NewNotify)
{
ACPI_FREE (NewNotify);
diff --git a/sys/contrib/dev/acpica/components/executer/exprep.c b/sys/contrib/dev/acpica/components/executer/exprep.c
index 993f75b..dc40831 100644
--- a/sys/contrib/dev/acpica/components/executer/exprep.c
+++ b/sys/contrib/dev/acpica/components/executer/exprep.c
@@ -418,8 +418,8 @@ AcpiExPrepCommonFieldObject (
*
* RETURN: Status
*
- * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT of type DefField and
- * connect it to the parent Node.
+ * DESCRIPTION: Construct an object of type ACPI_OPERAND_OBJECT with a
+ * subtype of DefField and connect it to the parent Node.
*
******************************************************************************/
diff --git a/sys/contrib/dev/acpica/components/executer/exresolv.c b/sys/contrib/dev/acpica/components/executer/exresolv.c
index bc29bde..15ac718 100644
--- a/sys/contrib/dev/acpica/components/executer/exresolv.c
+++ b/sys/contrib/dev/acpica/components/executer/exresolv.c
@@ -165,7 +165,7 @@ AcpiExResolveObjectToValue (
StackDesc = *StackPtr;
- /* This is an ACPI_OPERAND_OBJECT */
+ /* This is an object of type ACPI_OPERAND_OBJECT */
switch (StackDesc->Common.Type)
{
diff --git a/sys/contrib/dev/acpica/components/executer/exstore.c b/sys/contrib/dev/acpica/components/executer/exstore.c
index a66aa16..aeba0c3 100644
--- a/sys/contrib/dev/acpica/components/executer/exstore.c
+++ b/sys/contrib/dev/acpica/components/executer/exstore.c
@@ -68,15 +68,15 @@ AcpiExStoreObjectToIndex (
* FUNCTION: AcpiExStore
*
* PARAMETERS: *SourceDesc - Value to be stored
- * *DestDesc - Where to store it. Must be an NS node
- * or an ACPI_OPERAND_OBJECT of type
+ * *DestDesc - Where to store it. Must be an NS node
+ * or ACPI_OPERAND_OBJECT of type
* Reference;
* WalkState - Current walk state
*
* RETURN: Status
*
* DESCRIPTION: Store the value described by SourceDesc into the location
- * described by DestDesc. Called by various interpreter
+ * described by DestDesc. Called by various interpreter
* functions to store the result of an operation into
* the destination operand -- not just simply the actual "Store"
* ASL operator.
diff --git a/sys/contrib/dev/acpica/components/executer/exutils.c b/sys/contrib/dev/acpica/components/executer/exutils.c
index 45414ce..b2df4f8 100644
--- a/sys/contrib/dev/acpica/components/executer/exutils.c
+++ b/sys/contrib/dev/acpica/components/executer/exutils.c
@@ -121,7 +121,7 @@ AcpiExEnterInterpreter (
*
* DESCRIPTION: Reacquire the interpreter execution region from within the
* interpreter code. Failure to enter the interpreter region is a
- * fatal system error. Used in conjuction with
+ * fatal system error. Used in conjunction with
* RelinquishInterpreter
*
******************************************************************************/
diff --git a/sys/contrib/dev/acpica/components/hardware/hwsleep.c b/sys/contrib/dev/acpica/components/hardware/hwsleep.c
index f5a9eba..2a80c25 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwsleep.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwsleep.c
@@ -100,20 +100,6 @@ AcpiHwLegacySleep (
return_ACPI_STATUS (Status);
}
- if (SleepState != ACPI_STATE_S5)
- {
- /*
- * Disable BM arbitration. This feature is contained within an
- * optional register (PM2 Control), so ignore a BAD_ADDRESS
- * exception.
- */
- Status = AcpiWriteBitRegister (ACPI_BITREG_ARB_DISABLE, 1);
- if (ACPI_FAILURE (Status) && (Status != AE_BAD_ADDRESS))
- {
- return_ACPI_STATUS (Status);
- }
- }
-
/*
* 1) Disable/Clear all GPEs
* 2) Enable all wakeup GPEs
@@ -394,17 +380,6 @@ AcpiHwLegacyWake (
AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId,
ACPI_CLEAR_STATUS);
- /*
- * Enable BM arbitration. This feature is contained within an
- * optional register (PM2 Control), so ignore a BAD_ADDRESS
- * exception.
- */
- Status = AcpiWriteBitRegister (ACPI_BITREG_ARB_DISABLE, 0);
- if (ACPI_FAILURE (Status) && (Status != AE_BAD_ADDRESS))
- {
- return_ACPI_STATUS (Status);
- }
-
AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WORKING);
return_ACPI_STATUS (Status);
}
diff --git a/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c b/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
index fa6fec8..bd7abea 100644
--- a/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
+++ b/sys/contrib/dev/acpica/components/hardware/hwxfsleep.c
@@ -101,6 +101,14 @@ AcpiSetFirmwareWakingVector (
ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector);
+ /*
+ * According to the ACPI specification 2.0c and later, the 64-bit
+ * waking vector should be cleared and the 32-bit waking vector should
+ * be used, unless we want the wake-up code to be called by the BIOS in
+ * Protected Mode. Some systems (for example HP dv5-1004nr) are known
+ * to fail to resume if the 64-bit vector is used.
+ */
+
/* Set the 32-bit vector */
AcpiGbl_FACS->FirmwareWakingVector = PhysicalAddress;
diff --git a/sys/contrib/dev/acpica/components/namespace/nspredef.c b/sys/contrib/dev/acpica/components/namespace/nspredef.c
index 9ce2405..fd003fb 100644
--- a/sys/contrib/dev/acpica/components/namespace/nspredef.c
+++ b/sys/contrib/dev/acpica/components/namespace/nspredef.c
@@ -681,7 +681,7 @@ AcpiNsCheckPackage (
{
/* Create the new outer package and populate it */
- Status = AcpiNsWrapWithPackage (Data, *Elements, ReturnObjectPtr);
+ Status = AcpiNsWrapWithPackage (Data, ReturnObject, ReturnObjectPtr);
if (ACPI_FAILURE (Status))
{
return (Status);
diff --git a/sys/contrib/dev/acpica/components/parser/psxface.c b/sys/contrib/dev/acpica/components/parser/psxface.c
index 2cfd066..f65591e 100644
--- a/sys/contrib/dev/acpica/components/parser/psxface.c
+++ b/sys/contrib/dev/acpica/components/parser/psxface.c
@@ -348,8 +348,8 @@ AcpiPsExecuteMethod (
}
/*
- * Start method evaluation with an implicit return of zero. This is done
- * for Windows compatibility.
+ * Start method evaluation with an implicit return of zero.
+ * This is done for Windows compatibility.
*/
if (AcpiGbl_EnableInterpreterSlack)
{
diff --git a/sys/contrib/dev/acpica/components/resources/rscreate.c b/sys/contrib/dev/acpica/components/resources/rscreate.c
index dd1f6ae..5fb3294 100644
--- a/sys/contrib/dev/acpica/components/resources/rscreate.c
+++ b/sys/contrib/dev/acpica/components/resources/rscreate.c
@@ -209,8 +209,8 @@ AcpiRsCreateResourceList (
*
* FUNCTION: AcpiRsCreatePciRoutingTable
*
- * PARAMETERS: PackageObject - Pointer to an ACPI_OPERAND_OBJECT
- * package
+ * PARAMETERS: PackageObject - Pointer to a package containing one
+ * of more ACPI_OPERAND_OBJECTs
* OutputBuffer - Pointer to the user's buffer
*
* RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code.
@@ -218,7 +218,7 @@ AcpiRsCreateResourceList (
* AE_BUFFER_OVERFLOW and OutputBuffer->Length will point
* to the size buffer needed.
*
- * DESCRIPTION: Takes the ACPI_OPERAND_OBJECT package and creates a
+ * DESCRIPTION: Takes the ACPI_OPERAND_OBJECT package and creates a
* linked list of PCI interrupt descriptions
*
* NOTE: It is the caller's responsibility to ensure that the start of the
diff --git a/sys/contrib/dev/acpica/components/resources/rsutils.c b/sys/contrib/dev/acpica/components/resources/rsutils.c
index 083e350..9e4e16a 100644
--- a/sys/contrib/dev/acpica/components/resources/rsutils.c
+++ b/sys/contrib/dev/acpica/components/resources/rsutils.c
@@ -181,7 +181,7 @@ AcpiRsMoveData (
/*
* 16-, 32-, and 64-bit cases must use the move macros that perform
- * endian conversion and/or accomodate hardware that cannot perform
+ * endian conversion and/or accommodate hardware that cannot perform
* misaligned memory transfers
*/
case ACPI_RSC_MOVE16:
diff --git a/sys/contrib/dev/acpica/components/tables/tbfadt.c b/sys/contrib/dev/acpica/components/tables/tbfadt.c
index cbf8426..a4d8fa1 100644
--- a/sys/contrib/dev/acpica/components/tables/tbfadt.c
+++ b/sys/contrib/dev/acpica/components/tables/tbfadt.c
@@ -192,7 +192,7 @@ static ACPI_FADT_PM_INFO FadtPmInfoTable[] =
*
* PARAMETERS: GenericAddress - GAS struct to be initialized
* SpaceId - ACPI Space ID for this register
- * ByteWidth - Width of this register, in bytes
+ * ByteWidth - Width of this register
* Address - Address of the register
*
* RETURN: None
@@ -338,7 +338,7 @@ AcpiTbCreateLocalFadt (
*/
if (Length > sizeof (ACPI_TABLE_FADT))
{
- ACPI_WARNING ((AE_INFO,
+ ACPI_BIOS_WARNING ((AE_INFO,
"FADT (revision %u) is longer than ACPI 5.0 version, "
"truncating length %u to %u",
Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT)));
@@ -486,8 +486,9 @@ AcpiTbConvertFadt (
if (Address64->Address && Address32 &&
(Address64->Address != (UINT64) Address32))
{
- ACPI_ERROR ((AE_INFO,
- "32/64X address mismatch in %s: 0x%8.8X/0x%8.8X%8.8X, using 32",
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "32/64X address mismatch in FADT/%s: "
+ "0x%8.8X/0x%8.8X%8.8X, using 32",
FadtInfoTable[i].Name, Address32,
ACPI_FORMAT_UINT64 (Address64->Address)));
}
@@ -546,7 +547,7 @@ AcpiTbValidateFadt (
if (AcpiGbl_FADT.Facs &&
(AcpiGbl_FADT.XFacs != (UINT64) AcpiGbl_FADT.Facs))
{
- ACPI_WARNING ((AE_INFO,
+ ACPI_BIOS_WARNING ((AE_INFO,
"32/64X FACS address mismatch in FADT - "
"0x%8.8X/0x%8.8X%8.8X, using 32",
AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs)));
@@ -557,7 +558,7 @@ AcpiTbValidateFadt (
if (AcpiGbl_FADT.Dsdt &&
(AcpiGbl_FADT.XDsdt != (UINT64) AcpiGbl_FADT.Dsdt))
{
- ACPI_WARNING ((AE_INFO,
+ ACPI_BIOS_WARNING ((AE_INFO,
"32/64X DSDT address mismatch in FADT - "
"0x%8.8X/0x%8.8X%8.8X, using 32",
AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt)));
@@ -593,8 +594,8 @@ AcpiTbValidateFadt (
if (Address64->Address &&
(Address64->BitWidth != ACPI_MUL_8 (Length)))
{
- ACPI_WARNING ((AE_INFO,
- "32/64X length mismatch in %s: %u/%u",
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "32/64X length mismatch in FADT/%s: %u/%u",
Name, ACPI_MUL_8 (Length), Address64->BitWidth));
}
@@ -606,9 +607,9 @@ AcpiTbValidateFadt (
*/
if (!Address64->Address || !Length)
{
- ACPI_ERROR ((AE_INFO,
- "Required field %s has zero address and/or length:"
- " 0x%8.8X%8.8X/0x%X",
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "Required FADT field %s has zero address and/or length: "
+ "0x%8.8X%8.8X/0x%X",
Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
}
}
@@ -622,8 +623,8 @@ AcpiTbValidateFadt (
if ((Address64->Address && !Length) ||
(!Address64->Address && Length))
{
- ACPI_WARNING ((AE_INFO,
- "Optional field %s has zero address or length: "
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "Optional FADT field %s has zero address or length: "
"0x%8.8X%8.8X/0x%X",
Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
}
@@ -674,8 +675,8 @@ AcpiTbSetupFadtRegisters (
(FadtInfoTable[i].DefaultLength > 0) &&
(FadtInfoTable[i].DefaultLength != Target64->BitWidth))
{
- ACPI_WARNING ((AE_INFO,
- "Invalid length for %s: %u, using default %u",
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "Invalid length for FADT/%s: %u, using default %u",
FadtInfoTable[i].Name, Target64->BitWidth,
FadtInfoTable[i].DefaultLength));
diff --git a/sys/contrib/dev/acpica/components/tables/tbinstal.c b/sys/contrib/dev/acpica/components/tables/tbinstal.c
index b5a908c..f56144c 100644
--- a/sys/contrib/dev/acpica/components/tables/tbinstal.c
+++ b/sys/contrib/dev/acpica/components/tables/tbinstal.c
@@ -157,8 +157,9 @@ AcpiTbAddTable (
(!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
(ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
{
- ACPI_ERROR ((AE_INFO,
- "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx",
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "Table has invalid signature [%4.4s] (0x%8.8X), "
+ "must be SSDT or OEMx",
AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ?
TableDesc->Pointer->Signature : "????",
*(UINT32 *) TableDesc->Pointer->Signature));
diff --git a/sys/contrib/dev/acpica/components/tables/tbutils.c b/sys/contrib/dev/acpica/components/tables/tbutils.c
index d053b19..0c9ca76 100644
--- a/sys/contrib/dev/acpica/components/tables/tbutils.c
+++ b/sys/contrib/dev/acpica/components/tables/tbutils.c
@@ -287,8 +287,9 @@ AcpiTbVerifyChecksum (
if (Checksum)
{
- ACPI_WARNING ((AE_INFO,
- "Incorrect checksum in table [%4.4s] - 0x%2.2X, should be 0x%2.2X",
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
+ "should be 0x%2.2X",
Table->Signature, Table->Checksum,
(UINT8) (Table->Checksum - Checksum)));
@@ -356,8 +357,9 @@ AcpiTbCheckDsdtHeader (
if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
{
- ACPI_ERROR ((AE_INFO,
- "The DSDT has been corrupted or replaced - old, new headers below"));
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "The DSDT has been corrupted or replaced - "
+ "old, new headers below"));
AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
@@ -460,27 +462,12 @@ AcpiTbInstallTable (
return;
}
- /* Skip SSDT when DSDT is overriden */
-
- if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT) &&
- (AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags &
- ACPI_TABLE_ORIGIN_OVERRIDE))
- {
- ACPI_INFO ((AE_INFO,
- "%4.4s @ 0x%p Table override, replaced with:", ACPI_SIG_SSDT,
- ACPI_CAST_PTR (void, Address)));
- AcpiTbPrintTableHeader (
- AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Address,
- AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer);
- goto UnmapAndExit;
- }
-
/* If a particular signature is expected (DSDT/FACS), it must match */
if (Signature &&
!ACPI_COMPARE_NAME (Table->Signature, Signature))
{
- ACPI_ERROR ((AE_INFO,
+ ACPI_BIOS_ERROR ((AE_INFO,
"Invalid signature 0x%X for ACPI table, expected [%s]",
*ACPI_CAST_PTR (UINT32, Table->Signature), Signature));
goto UnmapAndExit;
@@ -498,6 +485,19 @@ AcpiTbInstallTable (
TableDesc->Flags = ACPI_TABLE_ORIGIN_MAPPED;
ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
+ /* When DSDT is overriden, assume SSDT is also overriden with it */
+
+ if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT) &&
+ (AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags &
+ ACPI_TABLE_ORIGIN_OVERRIDE))
+ {
+ TableDesc->Flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+ ACPI_INFO ((AE_INFO,
+ "%4.4s %p Logical table override, replaced with %4.4s",
+ ACPI_SIG_SSDT, ACPI_CAST_PTR (void, Address), ACPI_SIG_DSDT));
+ goto UnmapAndExit;
+ }
+
/*
* ACPI Table Override:
*
@@ -599,7 +599,7 @@ AcpiTbGetRootTableEntry (
{
/* Will truncate 64-bit address to 32 bits, issue warning */
- ACPI_WARNING ((AE_INFO,
+ ACPI_BIOS_WARNING ((AE_INFO,
"64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
" truncating",
ACPI_FORMAT_UINT64 (Address64)));
@@ -701,7 +701,8 @@ AcpiTbParseRootTable (
if (Length < sizeof (ACPI_TABLE_HEADER))
{
- ACPI_ERROR ((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", Length));
+ ACPI_BIOS_ERROR ((AE_INFO,
+ "Invalid table length 0x%X in RSDT/XSDT", Length));
return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
}
diff --git a/sys/contrib/dev/acpica/components/tables/tbxface.c b/sys/contrib/dev/acpica/components/tables/tbxface.c
index dc03a2c..f4a1e52 100644
--- a/sys/contrib/dev/acpica/components/tables/tbxface.c
+++ b/sys/contrib/dev/acpica/components/tables/tbxface.c
@@ -1,7 +1,6 @@
/******************************************************************************
*
- * Module Name: tbxface - Public interfaces to the ACPI subsystem
- * ACPI table oriented interfaces
+ * Module Name: tbxface - ACPI table oriented external interfaces
*
*****************************************************************************/
@@ -46,18 +45,11 @@
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
-#include <contrib/dev/acpica/include/acnamesp.h>
#include <contrib/dev/acpica/include/actables.h>
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbxface")
-/* Local prototypes */
-
-static ACPI_STATUS
-AcpiTbLoadNamespace (
- void);
-
/*******************************************************************************
*
@@ -458,165 +450,6 @@ ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
/*******************************************************************************
*
- * FUNCTION: AcpiTbLoadNamespace
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
- * the RSDT/XSDT.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiTbLoadNamespace (
- void)
-{
- ACPI_STATUS Status;
- UINT32 i;
- ACPI_TABLE_HEADER *NewDsdt;
-
-
- ACPI_FUNCTION_TRACE (TbLoadNamespace);
-
-
- (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
-
- /*
- * Load the namespace. The DSDT is required, but any SSDT and
- * PSDT tables are optional. Verify the DSDT.
- */
- if (!AcpiGbl_RootTableList.CurrentTableCount ||
- !ACPI_COMPARE_NAME (
- &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
- ACPI_SIG_DSDT) ||
- ACPI_FAILURE (AcpiTbVerifyTable (
- &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
- {
- Status = AE_NO_ACPI_TABLES;
- goto UnlockAndExit;
- }
-
- /*
- * Save the DSDT pointer for simple access. This is the mapped memory
- * address. We must take care here because the address of the .Tables
- * array can change dynamically as tables are loaded at run-time. Note:
- * .Pointer field is not validated until after call to AcpiTbVerifyTable.
- */
- AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
-
- /*
- * Optionally copy the entire DSDT to local memory (instead of simply
- * mapping it.) There are some BIOSs that corrupt or replace the original
- * DSDT, creating the need for this option. Default is FALSE, do not copy
- * the DSDT.
- */
- if (AcpiGbl_CopyDsdtLocally)
- {
- NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
- if (NewDsdt)
- {
- AcpiGbl_DSDT = NewDsdt;
- }
- }
-
- /*
- * Save the original DSDT header for detection of table corruption
- * and/or replacement of the DSDT from outside the OS.
- */
- ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
- sizeof (ACPI_TABLE_HEADER));
-
- (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
-
- /* Load and parse tables */
-
- Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
-
- /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
-
- (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
- for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
- {
- if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
- ACPI_SIG_SSDT) &&
- !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
- ACPI_SIG_PSDT)) ||
- ACPI_FAILURE (AcpiTbVerifyTable (
- &AcpiGbl_RootTableList.Tables[i])))
- {
- continue;
- }
-
- /* Skip SSDT when DSDT is overriden */
-
- if (ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
- ACPI_SIG_SSDT) &&
- (AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags &
- ACPI_TABLE_ORIGIN_OVERRIDE))
- {
- continue;
- }
-
- /* Ignore errors while loading tables, get as many as possible */
-
- (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
- (void) AcpiNsLoadTable (i, AcpiGbl_RootNode);
- (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
-
-UnlockAndExit:
- (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiLoadTables
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiLoadTables (
- void)
-{
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_TRACE (AcpiLoadTables);
-
-
- /* Load the namespace from the tables */
-
- Status = AcpiTbLoadNamespace ();
- if (ACPI_FAILURE (Status))
- {
- ACPI_EXCEPTION ((AE_INFO, Status,
- "While loading namespace from ACPI tables"));
- }
-
- return_ACPI_STATUS (Status);
-}
-
-ACPI_EXPORT_SYMBOL (AcpiLoadTables)
-
-
-/*******************************************************************************
- *
* FUNCTION: AcpiInstallTableHandler
*
* PARAMETERS: Handler - Table event handler
diff --git a/sys/contrib/dev/acpica/components/tables/tbxfload.c b/sys/contrib/dev/acpica/components/tables/tbxfload.c
new file mode 100644
index 0000000..a2cc15f
--- /dev/null
+++ b/sys/contrib/dev/acpica/components/tables/tbxfload.c
@@ -0,0 +1,415 @@
+/******************************************************************************
+ *
+ * Module Name: tbxfload - Table load/unload external interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#define __TBXFLOAD_C__
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbxfload")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiTbLoadNamespace (
+ void);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiLoadTables
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiLoadTables (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiLoadTables);
+
+
+ /* Load the namespace from the tables */
+
+ Status = AcpiTbLoadNamespace ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While loading namespace from ACPI tables"));
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiLoadTables)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbLoadNamespace
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
+ * the RSDT/XSDT.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiTbLoadNamespace (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+ ACPI_TABLE_HEADER *NewDsdt;
+
+
+ ACPI_FUNCTION_TRACE (TbLoadNamespace);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ /*
+ * Load the namespace. The DSDT is required, but any SSDT and
+ * PSDT tables are optional. Verify the DSDT.
+ */
+ if (!AcpiGbl_RootTableList.CurrentTableCount ||
+ !ACPI_COMPARE_NAME (
+ &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
+ ACPI_SIG_DSDT) ||
+ ACPI_FAILURE (AcpiTbVerifyTable (
+ &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
+ {
+ Status = AE_NO_ACPI_TABLES;
+ goto UnlockAndExit;
+ }
+
+ /*
+ * Save the DSDT pointer for simple access. This is the mapped memory
+ * address. We must take care here because the address of the .Tables
+ * array can change dynamically as tables are loaded at run-time. Note:
+ * .Pointer field is not validated until after call to AcpiTbVerifyTable.
+ */
+ AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
+
+ /*
+ * Optionally copy the entire DSDT to local memory (instead of simply
+ * mapping it.) There are some BIOSs that corrupt or replace the original
+ * DSDT, creating the need for this option. Default is FALSE, do not copy
+ * the DSDT.
+ */
+ if (AcpiGbl_CopyDsdtLocally)
+ {
+ NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
+ if (NewDsdt)
+ {
+ AcpiGbl_DSDT = NewDsdt;
+ }
+ }
+
+ /*
+ * Save the original DSDT header for detection of table corruption
+ * and/or replacement of the DSDT from outside the OS.
+ */
+ ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
+ sizeof (ACPI_TABLE_HEADER));
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+
+ /* Load and parse tables */
+
+ Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+ {
+ if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ ACPI_SIG_SSDT) &&
+ !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ ACPI_SIG_PSDT)) ||
+ ACPI_FAILURE (AcpiTbVerifyTable (
+ &AcpiGbl_RootTableList.Tables[i])))
+ {
+ continue;
+ }
+
+ /* Skip SSDT when it is overriden with DSDT */
+ if (ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ ACPI_SIG_SSDT) &&
+ (AcpiGbl_RootTableList.Tables[i].Flags &
+ ACPI_TABLE_ORIGIN_OVERRIDE))
+ {
+ continue;
+ }
+
+ /* Ignore errors while loading tables, get as many as possible */
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ (void) AcpiNsLoadTable (i, AcpiGbl_RootNode);
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiLoadTable
+ *
+ * PARAMETERS: Table - Pointer to a buffer containing the ACPI
+ * table to be loaded.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must
+ * be a valid ACPI table with a valid ACPI table header.
+ * Note1: Mainly intended to support hotplug addition of SSDTs.
+ * Note2: Does not copy the incoming table. User is reponsible
+ * to ensure that the table is not deleted or unmapped.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiLoadTable (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status;
+ ACPI_TABLE_DESC TableDesc;
+ UINT32 TableIndex;
+
+
+ ACPI_FUNCTION_TRACE (AcpiLoadTable);
+
+
+ /* Parameter validation */
+
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Init local table descriptor */
+
+ ACPI_MEMSET (&TableDesc, 0, sizeof (ACPI_TABLE_DESC));
+ TableDesc.Address = ACPI_PTR_TO_PHYSADDR (Table);
+ TableDesc.Pointer = Table;
+ TableDesc.Length = Table->Length;
+ TableDesc.Flags = ACPI_TABLE_ORIGIN_UNKNOWN;
+
+ /* Must acquire the interpreter lock during this operation */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Install the table and load it into the namespace */
+
+ ACPI_INFO ((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
+ Status = AcpiTbAddTable (&TableDesc, &TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiNsLoadTable (TableIndex, AcpiGbl_RootNode);
+
+ /* Invoke table handler if present */
+
+ if (AcpiGbl_TableHandler)
+ {
+ (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
+ AcpiGbl_TableHandlerContext);
+ }
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiLoadTable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUnloadParentTable
+ *
+ * PARAMETERS: Object - Handle to any namespace object owned by
+ * the table to be unloaded
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads
+ * the table and deletes all namespace objects associated with
+ * that table. Unloading of the DSDT is not allowed.
+ * Note: Mainly intended to support hotplug removal of SSDTs.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUnloadParentTable (
+ ACPI_HANDLE Object)
+{
+ ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Object);
+ ACPI_STATUS Status = AE_NOT_EXIST;
+ ACPI_OWNER_ID OwnerId;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (AcpiUnloadParentTable);
+
+
+ /* Parameter validation */
+
+ if (!Object)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * The node OwnerId is currently the same as the parent table ID.
+ * However, this could change in the future.
+ */
+ OwnerId = Node->OwnerId;
+ if (!OwnerId)
+ {
+ /* OwnerId==0 means DSDT is the owner. DSDT cannot be unloaded */
+
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /* Must acquire the interpreter lock during this operation */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Find the table in the global table list */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ if (OwnerId != AcpiGbl_RootTableList.Tables[i].OwnerId)
+ {
+ continue;
+ }
+
+ /*
+ * Allow unload of SSDT and OEMx tables only. Do not allow unload
+ * of the DSDT. No other types of tables should get here, since
+ * only these types can contain AML and thus are the only types
+ * that can create namespace objects.
+ */
+ if (ACPI_COMPARE_NAME (
+ AcpiGbl_RootTableList.Tables[i].Signature.Ascii,
+ ACPI_SIG_DSDT))
+ {
+ Status = AE_TYPE;
+ break;
+ }
+
+ /* Ensure the table is actually loaded */
+
+ if (!AcpiTbIsTableLoaded (i))
+ {
+ Status = AE_NOT_EXIST;
+ break;
+ }
+
+ /* Invoke table handler if present */
+
+ if (AcpiGbl_TableHandler)
+ {
+ (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD,
+ AcpiGbl_RootTableList.Tables[i].Pointer,
+ AcpiGbl_TableHandlerContext);
+ }
+
+ /*
+ * Delete all namespace objects owned by this table. Note that
+ * these objects can appear anywhere in the namespace by virtue
+ * of the AML "Scope" operator. Thus, we need to track ownership
+ * by an ID, not simply a position within the hierarchy.
+ */
+ Status = AcpiTbDeleteNamespaceByOwner (i);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+
+ Status = AcpiTbReleaseOwnerId (i);
+ AcpiTbSetTableLoadedFlag (i, FALSE);
+ break;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiUnloadParentTable)
diff --git a/sys/contrib/dev/acpica/components/tables/tbxfroot.c b/sys/contrib/dev/acpica/components/tables/tbxfroot.c
index c6ade4e..bcb7ba3 100644
--- a/sys/contrib/dev/acpica/components/tables/tbxfroot.c
+++ b/sys/contrib/dev/acpica/components/tables/tbxfroot.c
@@ -234,7 +234,7 @@ AcpiFindRootPointer (
/* A valid RSDP was not found */
- ACPI_ERROR ((AE_INFO, "A valid RSDP was not found"));
+ ACPI_BIOS_ERROR ((AE_INFO, "A valid RSDP was not found"));
return_ACPI_STATUS (AE_NOT_FOUND);
}
diff --git a/sys/contrib/dev/acpica/components/utilities/utdecode.c b/sys/contrib/dev/acpica/components/utilities/utdecode.c
index 689d495..ef423e9 100644
--- a/sys/contrib/dev/acpica/components/utilities/utdecode.c
+++ b/sys/contrib/dev/acpica/components/utilities/utdecode.c
@@ -51,47 +51,6 @@
ACPI_MODULE_NAME ("utdecode")
-/*******************************************************************************
- *
- * FUNCTION: AcpiFormatException
- *
- * PARAMETERS: Status - The ACPI_STATUS code to be formatted
- *
- * RETURN: A string containing the exception text. A valid pointer is
- * always returned.
- *
- * DESCRIPTION: This function translates an ACPI exception into an ASCII string
- * It is here instead of utxface.c so it is always present.
- *
- ******************************************************************************/
-
-const char *
-AcpiFormatException (
- ACPI_STATUS Status)
-{
- const char *Exception = NULL;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- Exception = AcpiUtValidateException (Status);
- if (!Exception)
- {
- /* Exception code was not recognized */
-
- ACPI_ERROR ((AE_INFO,
- "Unknown exception code: 0x%8.8X", Status));
-
- Exception = "UNKNOWN_STATUS_CODE";
- }
-
- return (ACPI_CAST_PTR (const char, Exception));
-}
-
-ACPI_EXPORT_SYMBOL (AcpiFormatException)
-
-
/*
* Properties of the ACPI Object Types, both internal and external.
* The table is indexed by values of ACPI_OBJECT_TYPE
@@ -180,16 +139,17 @@ AcpiUtHexToAsciiChar (
const char *AcpiGbl_RegionTypes[ACPI_NUM_PREDEFINED_REGIONS] =
{
- "SystemMemory",
- "SystemIO",
- "PCI_Config",
- "EmbeddedControl",
- "SMBus",
- "SystemCMOS",
- "PCIBARTarget",
- "IPMI",
- "GeneralPurposeIo",
- "GenericSerialBus"
+ "SystemMemory", /* 0x00 */
+ "SystemIO", /* 0x01 */
+ "PCI_Config", /* 0x02 */
+ "EmbeddedControl", /* 0x03 */
+ "SMBus", /* 0x04 */
+ "SystemCMOS", /* 0x05 */
+ "PCIBARTarget", /* 0x06 */
+ "IPMI", /* 0x07 */
+ "GeneralPurposeIo", /* 0x08 */
+ "GenericSerialBus", /* 0x09 */
+ "PCC" /* 0x0A */
};
diff --git a/sys/contrib/dev/acpica/components/utilities/utexcep.c b/sys/contrib/dev/acpica/components/utilities/utexcep.c
new file mode 100644
index 0000000..0f38227
--- /dev/null
+++ b/sys/contrib/dev/acpica/components/utilities/utexcep.c
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ *
+ * Module Name: utexcep - Exception code support
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+
+#define __UTEXCEP_C__
+
+#define ACPI_DEFINE_EXCEPTION_TABLE
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+
+
+#define _COMPONENT ACPI_UTILITIES
+ ACPI_MODULE_NAME ("utexcep")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiFormatException
+ *
+ * PARAMETERS: Status - The ACPI_STATUS code to be formatted
+ *
+ * RETURN: A string containing the exception text. A valid pointer is
+ * always returned.
+ *
+ * DESCRIPTION: This function translates an ACPI exception into an ASCII
+ * string. Returns "unknown status" string for invalid codes.
+ *
+ ******************************************************************************/
+
+const char *
+AcpiFormatException (
+ ACPI_STATUS Status)
+{
+ const char *Exception = NULL;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ Exception = AcpiUtValidateException (Status);
+ if (!Exception)
+ {
+ /* Exception code was not recognized */
+
+ ACPI_ERROR ((AE_INFO,
+ "Unknown exception code: 0x%8.8X", Status));
+
+ Exception = "UNKNOWN_STATUS_CODE";
+ }
+
+ return (ACPI_CAST_PTR (const char, Exception));
+}
+
+ACPI_EXPORT_SYMBOL (AcpiFormatException)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUtValidateException
+ *
+ * PARAMETERS: Status - The ACPI_STATUS code to be formatted
+ *
+ * RETURN: A string containing the exception text. NULL if exception is
+ * not valid.
+ *
+ * DESCRIPTION: This function validates and translates an ACPI exception into
+ * an ASCII string.
+ *
+ ******************************************************************************/
+
+const char *
+AcpiUtValidateException (
+ ACPI_STATUS Status)
+{
+ UINT32 SubStatus;
+ const char *Exception = NULL;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * Status is composed of two parts, a "type" and an actual code
+ */
+ SubStatus = (Status & ~AE_CODE_MASK);
+
+ switch (Status & AE_CODE_MASK)
+ {
+ case AE_CODE_ENVIRONMENTAL:
+
+ if (SubStatus <= AE_CODE_ENV_MAX)
+ {
+ Exception = AcpiGbl_ExceptionNames_Env [SubStatus];
+ }
+ break;
+
+ case AE_CODE_PROGRAMMER:
+
+ if (SubStatus <= AE_CODE_PGM_MAX)
+ {
+ Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus];
+ }
+ break;
+
+ case AE_CODE_ACPI_TABLES:
+
+ if (SubStatus <= AE_CODE_TBL_MAX)
+ {
+ Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus];
+ }
+ break;
+
+ case AE_CODE_AML:
+
+ if (SubStatus <= AE_CODE_AML_MAX)
+ {
+ Exception = AcpiGbl_ExceptionNames_Aml [SubStatus];
+ }
+ break;
+
+ case AE_CODE_CONTROL:
+
+ if (SubStatus <= AE_CODE_CTRL_MAX)
+ {
+ Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus];
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (ACPI_CAST_PTR (const char, Exception));
+}
diff --git a/sys/contrib/dev/acpica/components/utilities/utglobal.c b/sys/contrib/dev/acpica/components/utilities/utglobal.c
index 9e74d7d..5bb5991 100644
--- a/sys/contrib/dev/acpica/components/utilities/utglobal.c
+++ b/sys/contrib/dev/acpica/components/utilities/utglobal.c
@@ -211,8 +211,9 @@ ACPI_FIXED_EVENT_INFO AcpiGbl_FixedEventInfo[ACPI_NUM_FIXED_EVENTS] =
*
* RETURN: Status
*
- * DESCRIPTION: Init ACPICA globals. All globals that require specific
- * initialization should be initialized here!
+ * DESCRIPTION: Initialize ACPICA globals. All globals that require specific
+ * initialization should be initialized here. This allows for
+ * a warm restart.
*
******************************************************************************/
diff --git a/sys/contrib/dev/acpica/components/utilities/utmisc.c b/sys/contrib/dev/acpica/components/utilities/utmisc.c
index 62eb817..78cdbcd 100644
--- a/sys/contrib/dev/acpica/components/utilities/utmisc.c
+++ b/sys/contrib/dev/acpica/components/utilities/utmisc.c
@@ -92,86 +92,6 @@ UtConvertBackslashes (
/*******************************************************************************
*
- * FUNCTION: AcpiUtValidateException
- *
- * PARAMETERS: Status - The ACPI_STATUS code to be formatted
- *
- * RETURN: A string containing the exception text. NULL if exception is
- * not valid.
- *
- * DESCRIPTION: This function validates and translates an ACPI exception into
- * an ASCII string.
- *
- ******************************************************************************/
-
-const char *
-AcpiUtValidateException (
- ACPI_STATUS Status)
-{
- UINT32 SubStatus;
- const char *Exception = NULL;
-
-
- ACPI_FUNCTION_ENTRY ();
-
-
- /*
- * Status is composed of two parts, a "type" and an actual code
- */
- SubStatus = (Status & ~AE_CODE_MASK);
-
- switch (Status & AE_CODE_MASK)
- {
- case AE_CODE_ENVIRONMENTAL:
-
- if (SubStatus <= AE_CODE_ENV_MAX)
- {
- Exception = AcpiGbl_ExceptionNames_Env [SubStatus];
- }
- break;
-
- case AE_CODE_PROGRAMMER:
-
- if (SubStatus <= AE_CODE_PGM_MAX)
- {
- Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus];
- }
- break;
-
- case AE_CODE_ACPI_TABLES:
-
- if (SubStatus <= AE_CODE_TBL_MAX)
- {
- Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus];
- }
- break;
-
- case AE_CODE_AML:
-
- if (SubStatus <= AE_CODE_AML_MAX)
- {
- Exception = AcpiGbl_ExceptionNames_Aml [SubStatus];
- }
- break;
-
- case AE_CODE_CONTROL:
-
- if (SubStatus <= AE_CODE_CTRL_MAX)
- {
- Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus];
- }
- break;
-
- default:
- break;
- }
-
- return (ACPI_CAST_PTR (const char, Exception));
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: AcpiUtIsPciRootBridge
*
* PARAMETERS: Id - The HID/CID in string format
diff --git a/sys/contrib/dev/acpica/components/utilities/utobject.c b/sys/contrib/dev/acpica/components/utilities/utobject.c
index 9d90a39..09ff6cf 100644
--- a/sys/contrib/dev/acpica/components/utilities/utobject.c
+++ b/sys/contrib/dev/acpica/components/utilities/utobject.c
@@ -366,7 +366,7 @@ AcpiUtCreateStringObject (
*
* RETURN: TRUE if object is valid, FALSE otherwise
*
- * DESCRIPTION: Validate a pointer to be an ACPI_OPERAND_OBJECT
+ * DESCRIPTION: Validate a pointer to be of type ACPI_OPERAND_OBJECT
*
******************************************************************************/
@@ -392,7 +392,7 @@ AcpiUtValidInternalObject (
{
case ACPI_DESC_TYPE_OPERAND:
- /* The object appears to be a valid ACPI_OPERAND_OBJECT */
+ /* The object appears to be a valid ACPI_OPERAND_OBJECT */
return (TRUE);
@@ -473,7 +473,7 @@ AcpiUtDeleteObjectDesc (
ACPI_FUNCTION_TRACE_PTR (UtDeleteObjectDesc, Object);
- /* Object must be an ACPI_OPERAND_OBJECT */
+ /* Object must be of type ACPI_OPERAND_OBJECT */
if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
{
diff --git a/sys/contrib/dev/acpica/components/utilities/utresrc.c b/sys/contrib/dev/acpica/components/utilities/utresrc.c
index 494d3fe..a7c8fcc 100644
--- a/sys/contrib/dev/acpica/components/utilities/utresrc.c
+++ b/sys/contrib/dev/acpica/components/utilities/utresrc.c
@@ -1,6 +1,6 @@
/*******************************************************************************
*
- * Module Name: utresrc - Resource managment utilities
+ * Module Name: utresrc - Resource management utilities
*
******************************************************************************/
@@ -57,7 +57,7 @@
/*
* Strings used to decode resource descriptors.
- * Used by both the disasssembler and the debugger resource dump routines
+ * Used by both the disassembler and the debugger resource dump routines
*/
const char *AcpiGbl_BmDecode[] =
{
diff --git a/sys/contrib/dev/acpica/components/utilities/utxferror.c b/sys/contrib/dev/acpica/components/utilities/utxferror.c
index 09df461..0db86ab 100644
--- a/sys/contrib/dev/acpica/components/utilities/utxferror.c
+++ b/sys/contrib/dev/acpica/components/utilities/utxferror.c
@@ -87,6 +87,9 @@ extern FILE *AcpiGbl_OutputFile;
#define ACPI_MSG_WARNING "ACPI Warning: "
#define ACPI_MSG_INFO "ACPI: "
+#define ACPI_MSG_BIOS_ERROR "ACPI Firmware Error: "
+#define ACPI_MSG_BIOS_WARNING "ACPI Firmware Warning: "
+
/*
* Common message suffix
*/
@@ -257,6 +260,84 @@ AcpiInfo (
ACPI_EXPORT_SYMBOL (AcpiInfo)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiBiosError
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * Format - Printf format string + additional args
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print "ACPI Firmware Error" message with module/line/version
+ * info
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiBiosError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...)
+{
+ va_list ArgList;
+
+
+ ACPI_MSG_REDIRECT_BEGIN;
+ AcpiOsPrintf (ACPI_MSG_BIOS_ERROR);
+
+ va_start (ArgList, Format);
+ AcpiOsVprintf (Format, ArgList);
+ ACPI_MSG_SUFFIX;
+ va_end (ArgList);
+
+ ACPI_MSG_REDIRECT_END;
+}
+
+ACPI_EXPORT_SYMBOL (AcpiBiosError)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiBiosWarning
+ *
+ * PARAMETERS: ModuleName - Caller's module name (for error output)
+ * LineNumber - Caller's line number (for error output)
+ * Format - Printf format string + additional args
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print "ACPI Firmware Warning" message with module/line/version
+ * info
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiBiosWarning (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...)
+{
+ va_list ArgList;
+
+
+ ACPI_MSG_REDIRECT_BEGIN;
+ AcpiOsPrintf (ACPI_MSG_BIOS_WARNING);
+
+ va_start (ArgList, Format);
+ AcpiOsVprintf (Format, ArgList);
+ ACPI_MSG_SUFFIX;
+ va_end (ArgList);
+
+ ACPI_MSG_REDIRECT_END;
+}
+
+ACPI_EXPORT_SYMBOL (AcpiBiosWarning)
+
+
/*
* The remainder of this module contains internal error functions that may
* be configured out.
diff --git a/sys/contrib/dev/acpica/include/acdebug.h b/sys/contrib/dev/acpica/include/acdebug.h
index f89cf37..5c91c87 100644
--- a/sys/contrib/dev/acpica/include/acdebug.h
+++ b/sys/contrib/dev/acpica/include/acdebug.h
@@ -112,8 +112,7 @@ AcpiDbDisplayTemplate (
void
AcpiDbUnloadAcpiTable (
- char *TableArg,
- char *InstanceArg);
+ char *Name);
void
AcpiDbSendNotify (
diff --git a/sys/contrib/dev/acpica/include/acexcep.h b/sys/contrib/dev/acpica/include/acexcep.h
index 10f5a11..856a359 100644
--- a/sys/contrib/dev/acpica/include/acexcep.h
+++ b/sys/contrib/dev/acpica/include/acexcep.h
@@ -53,6 +53,7 @@
#define AE_CODE_ACPI_TABLES 0x2000
#define AE_CODE_AML 0x3000
#define AE_CODE_CONTROL 0x4000
+#define AE_CODE_MAX 0x4000
#define AE_CODE_MASK 0xF000
@@ -188,7 +189,7 @@
/* Exception strings for AcpiFormatException */
-#ifdef DEFINE_ACPI_GLOBALS
+#ifdef ACPI_DEFINE_EXCEPTION_TABLE
/*
* String versions of the exception codes above
@@ -307,6 +308,6 @@ char const *AcpiGbl_ExceptionNames_Ctrl[] =
"AE_CTRL_PARSE_PENDING"
};
-#endif /* ACPI GLOBALS */
+#endif /* EXCEPTION_TABLE */
#endif /* __ACEXCEP_H__ */
diff --git a/sys/contrib/dev/acpica/include/acglobal.h b/sys/contrib/dev/acpica/include/acglobal.h
index 5535c1d..1fc2bc6 100644
--- a/sys/contrib/dev/acpica/include/acglobal.h
+++ b/sys/contrib/dev/acpica/include/acglobal.h
@@ -287,17 +287,8 @@ ACPI_EXTERN UINT8 AcpiGbl_OsiData;
ACPI_EXTERN ACPI_INTERFACE_INFO *AcpiGbl_SupportedInterfaces;
ACPI_EXTERN ACPI_ADDRESS_RANGE *AcpiGbl_AddressRangeList[ACPI_ADDRESS_RANGE_MAX];
-
#ifndef DEFINE_ACPI_GLOBALS
-/* Exception codes */
-
-extern char const *AcpiGbl_ExceptionNames_Env[];
-extern char const *AcpiGbl_ExceptionNames_Pgm[];
-extern char const *AcpiGbl_ExceptionNames_Tbl[];
-extern char const *AcpiGbl_ExceptionNames_Aml[];
-extern char const *AcpiGbl_ExceptionNames_Ctrl[];
-
/* Other miscellaneous */
extern BOOLEAN AcpiGbl_Shutdown;
diff --git a/sys/contrib/dev/acpica/include/acmacros.h b/sys/contrib/dev/acpica/include/acmacros.h
index cdb9cb1..591bb6b 100644
--- a/sys/contrib/dev/acpica/include/acmacros.h
+++ b/sys/contrib/dev/acpica/include/acmacros.h
@@ -274,8 +274,8 @@
#define ACPI_INSERT_BITS(Target, Mask, Source) Target = ((Target & (~(Mask))) | (Source & Mask))
/*
- * An ACPI_NAMESPACE_NODE can appear in some contexts
- * where a pointer to an ACPI_OPERAND_OBJECT can also
+ * An object of type ACPI_NAMESPACE_NODE can appear in some contexts
+ * where a pointer to an object of type ACPI_OPERAND_OBJECT can also
* appear. This macro is used to distinguish them.
*
* The "Descriptor" field is the first field in both structures.
diff --git a/sys/contrib/dev/acpica/include/acobject.h b/sys/contrib/dev/acpica/include/acobject.h
index e0f4a52..daf1aff 100644
--- a/sys/contrib/dev/acpica/include/acobject.h
+++ b/sys/contrib/dev/acpica/include/acobject.h
@@ -123,8 +123,8 @@ typedef struct acpi_object_integer
/*
- * Note: The String and Buffer object must be identical through the Pointer
- * and Length elements. There is code that depends on this.
+ * Note: The String and Buffer object must be identical through the
+ * pointer and length elements. There is code that depends on this.
*
* Fields common to both Strings and Buffers
*/
diff --git a/sys/contrib/dev/acpica/include/acoutput.h b/sys/contrib/dev/acpica/include/acoutput.h
index a1d89d4..193d0ac 100644
--- a/sys/contrib/dev/acpica/include/acoutput.h
+++ b/sys/contrib/dev/acpica/include/acoutput.h
@@ -217,6 +217,8 @@
#define ACPI_WARNING(plist) AcpiWarning plist
#define ACPI_EXCEPTION(plist) AcpiException plist
#define ACPI_ERROR(plist) AcpiError plist
+#define ACPI_BIOS_WARNING(plist) AcpiBiosWarning plist
+#define ACPI_BIOS_ERROR(plist) AcpiBiosError plist
#define ACPI_DEBUG_OBJECT(obj,l,i) AcpiExDoDebugObject(obj,l,i)
#else
@@ -227,6 +229,8 @@
#define ACPI_WARNING(plist)
#define ACPI_EXCEPTION(plist)
#define ACPI_ERROR(plist)
+#define ACPI_BIOS_WARNING(plist)
+#define ACPI_BIOS_ERROR(plist)
#define ACPI_DEBUG_OBJECT(obj,l,i)
#endif /* ACPI_NO_ERROR_MESSAGES */
diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h
index 9e1bcf1..4fdc7c6 100644
--- a/sys/contrib/dev/acpica/include/acpixf.h
+++ b/sys/contrib/dev/acpica/include/acpixf.h
@@ -48,7 +48,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20120620
+#define ACPI_CA_VERSION 0x20120711
#include <contrib/dev/acpica/include/acconfig.h>
#include <contrib/dev/acpica/include/actypes.h>
@@ -201,6 +201,22 @@ AcpiFree (
/*
+ * ACPI table load/unload interfaces
+ */
+ACPI_STATUS
+AcpiLoadTable (
+ ACPI_TABLE_HEADER *Table);
+
+ACPI_STATUS
+AcpiUnloadParentTable (
+ ACPI_HANDLE Object);
+
+ACPI_STATUS
+AcpiLoadTables (
+ void);
+
+
+/*
* ACPI table manipulation interfaces
*/
ACPI_STATUS
@@ -212,10 +228,6 @@ AcpiFindRootPointer (
ACPI_SIZE *RsdpAddress);
ACPI_STATUS
-AcpiLoadTables (
- void);
-
-ACPI_STATUS
AcpiGetTableHeader (
ACPI_STRING Signature,
UINT32 Instance,
@@ -757,6 +769,20 @@ AcpiInfo (
const char *Format,
...) ACPI_PRINTF_LIKE(3);
+void ACPI_INTERNAL_VAR_XFACE
+AcpiBiosError (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...) ACPI_PRINTF_LIKE(3);
+
+void ACPI_INTERNAL_VAR_XFACE
+AcpiBiosWarning (
+ const char *ModuleName,
+ UINT32 LineNumber,
+ const char *Format,
+ ...) ACPI_PRINTF_LIKE(3);
+
/*
* Debug output
diff --git a/sys/contrib/dev/acpica/include/actbl1.h b/sys/contrib/dev/acpica/include/actbl1.h
index 824135d..c24178f 100644
--- a/sys/contrib/dev/acpica/include/actbl1.h
+++ b/sys/contrib/dev/acpica/include/actbl1.h
@@ -130,7 +130,7 @@ typedef struct acpi_table_bert
{
ACPI_TABLE_HEADER Header; /* Common ACPI table header */
UINT32 RegionLength; /* Length of the boot error region */
- UINT64 Address; /* Physical addresss of the error region */
+ UINT64 Address; /* Physical address of the error region */
} ACPI_TABLE_BERT;
diff --git a/sys/contrib/dev/acpica/include/platform/acenv.h b/sys/contrib/dev/acpica/include/platform/acenv.h
index 922e24a..e82d9bb 100644
--- a/sys/contrib/dev/acpica/include/platform/acenv.h
+++ b/sys/contrib/dev/acpica/include/platform/acenv.h
@@ -108,9 +108,9 @@
#endif
#ifdef ACPI_HELP_APP
-#define ACPI_DEBUG_OUTPUT
#define ACPI_APPLICATION
#define ACPI_SINGLE_THREADED
+#define ACPI_NO_ERROR_MESSAGES
#endif
/* Linkable ACPICA library */
diff --git a/sys/dev/agp/agp_i810.c b/sys/dev/agp/agp_i810.c
index 54ddfdc..c0f592c 100644
--- a/sys/dev/agp/agp_i810.c
+++ b/sys/dev/agp/agp_i810.c
@@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/resource.h>
+#include <machine/md_var.h>
#include <sys/rman.h>
MALLOC_DECLARE(M_AGP);
@@ -1438,7 +1439,7 @@ agp_i810_attach(device_t dev)
if (error)
return (error);
- if (ptoa((vm_paddr_t)realmem) >
+ if (ptoa((vm_paddr_t)Maxmem) >
(1ULL << sc->match->driver->busdma_addr_mask_sz) - 1) {
device_printf(dev, "agp_i810 does not support physical "
"memory above %ju.\n", (uintmax_t)(1ULL <<
diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c
index 5a8046d..dea1736 100644
--- a/sys/dev/ath/ath_hal/ah.c
+++ b/sys/dev/ath/ath_hal/ah.c
@@ -630,6 +630,34 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
case HAL_CAP_REG_FLAG:
*result = AH_PRIVATE(ah)->ah_currentRDext;
return HAL_OK;
+ case HAL_CAP_ENHANCED_DMA_SUPPORT:
+ return pCap->halEnhancedDmaSupport ? HAL_OK : HAL_ENOTSUPP;
+ case HAL_CAP_NUM_TXMAPS:
+ *result = pCap->halNumTxMaps;
+ return HAL_OK;
+ case HAL_CAP_TXDESCLEN:
+ *result = pCap->halTxDescLen;
+ return HAL_OK;
+ case HAL_CAP_TXSTATUSLEN:
+ *result = pCap->halTxStatusLen;
+ return HAL_OK;
+ case HAL_CAP_RXSTATUSLEN:
+ *result = pCap->halRxStatusLen;
+ return HAL_OK;
+ case HAL_CAP_RXFIFODEPTH:
+ switch (capability) {
+ case HAL_RX_QUEUE_HP:
+ *result = pCap->halRxHpFifoDepth;
+ return HAL_OK;
+ case HAL_RX_QUEUE_LP:
+ *result = pCap->halRxLpFifoDepth;
+ return HAL_OK;
+ default:
+ return HAL_ENOTSUPP;
+ }
+ case HAL_CAP_RXBUFSIZE:
+ case HAL_CAP_NUM_MR_RETRIES:
+ return HAL_EINVAL; /* XXX not yet */
case HAL_CAP_BT_COEX:
return pCap->halBtCoexSupport ? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_HT20_SGI:
@@ -667,6 +695,7 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
return pCap->halHasBBReadWar? HAL_OK : HAL_ENOTSUPP;
case HAL_CAP_SERIALISE_WAR: /* PCI register serialisation */
return pCap->halSerialiseRegWar ? HAL_OK : HAL_ENOTSUPP;
+
default:
return HAL_EINVAL;
}
diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h
index 9cc7e75..aa3e8b6 100644
--- a/sys/dev/ath/ath_hal/ah.h
+++ b/sys/dev/ath/ath_hal/ah.h
@@ -149,9 +149,14 @@ typedef enum {
HAL_CAP_TS = 72, /* 3 stream */
HAL_CAP_ENHANCED_DMA_SUPPORT = 75, /* DMA FIFO support */
+ HAL_CAP_NUM_TXMAPS = 76, /* Number of buffers in a transmit descriptor */
+ HAL_CAP_TXDESCLEN = 77, /* Length of transmit descriptor */
+ HAL_CAP_TXSTATUSLEN = 78, /* Length of transmit status descriptor */
+ HAL_CAP_RXSTATUSLEN = 79, /* Length of transmit status descriptor */
+ HAL_CAP_RXFIFODEPTH = 80, /* Receive hardware FIFO depth */
+ HAL_CAP_RXBUFSIZE = 81, /* Receive Buffer Length */
+ HAL_CAP_NUM_MR_RETRIES = 82, /* limit on multirate retries */
- HAL_CAP_RXBUFSIZE = 81,
- HAL_CAP_NUM_MR_RETRIES = 82,
HAL_CAP_OL_PWRCTRL = 84, /* Open loop TX power control */
HAL_CAP_BB_PANIC_WATCHDOG = 92,
@@ -210,7 +215,7 @@ typedef enum {
typedef enum {
HAL_RX_QUEUE_HP = 0, /* high priority recv queue */
- HAL_RX_QUEUE_LP = 0, /* low priority recv queue */
+ HAL_RX_QUEUE_LP = 1, /* low priority recv queue */
} HAL_RX_QUEUE;
#define HAL_NUM_RX_QUEUES 2 /* max possible # of queues */
@@ -404,7 +409,10 @@ typedef enum {
*/
typedef enum {
HAL_INT_RX = 0x00000001, /* Non-common mapping */
- HAL_INT_RXDESC = 0x00000002,
+ HAL_INT_RXDESC = 0x00000002, /* Legacy mapping */
+ HAL_INT_RXHP = 0x00000001, /* EDMA */
+ HAL_INT_RXLP = 0x00000002, /* EDMA */
+ HAL_INT_RXERR = 0x00000004,
HAL_INT_RXNOFRM = 0x00000008,
HAL_INT_RXEOL = 0x00000010,
HAL_INT_RXORN = 0x00000020,
@@ -1078,8 +1086,8 @@ struct ath_hal {
const struct ath_desc *ds, int *rates, int *tries);
/* Receive Functions */
- uint32_t __ahdecl(*ah_getRxDP)(struct ath_hal*);
- void __ahdecl(*ah_setRxDP)(struct ath_hal*, uint32_t rxdp);
+ uint32_t __ahdecl(*ah_getRxDP)(struct ath_hal*, HAL_RX_QUEUE);
+ void __ahdecl(*ah_setRxDP)(struct ath_hal*, uint32_t rxdp, HAL_RX_QUEUE);
void __ahdecl(*ah_enableReceive)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_stopDmaReceive)(struct ath_hal*);
void __ahdecl(*ah_startPcuReceive)(struct ath_hal*);
diff --git a/sys/dev/ath/ath_hal/ah_debug.h b/sys/dev/ath/ath_hal/ah_debug.h
index bd1a251..6cd2627 100644
--- a/sys/dev/ath/ath_hal/ah_debug.h
+++ b/sys/dev/ath/ath_hal/ah_debug.h
@@ -47,6 +47,11 @@ enum {
HAL_DEBUG_DIVERSITY = 0x00100000, /* diversity debugging */
HAL_DEBUG_DFS = 0x00200000, /* DFS debugging */
HAL_DEBUG_HANG = 0x00400000, /* BB/MAC hang debugging */
+ HAL_DEBUG_CALIBRATE = 0x00800000, /* setup calibration */
+ HAL_DEBUG_POWER_MGMT = 0x01000000, /* power calibration */
+ HAL_DEBUG_CHANNEL = 0x02000000,
+ HAL_DEBUG_QUEUE = 0x04000000,
+ HAL_DEBUG_PRINT_REG = 0x08000000,
HAL_DEBUG_UNMASKABLE = 0x80000000, /* always printed */
HAL_DEBUG_ANY = 0xffffffff
diff --git a/sys/dev/ath/ath_hal/ah_desc.h b/sys/dev/ath/ath_hal/ah_desc.h
index 48c7a3e..1203ebb 100644
--- a/sys/dev/ath/ath_hal/ah_desc.h
+++ b/sys/dev/ath/ath_hal/ah_desc.h
@@ -122,11 +122,12 @@ struct ath_rx_status {
int8_t rs_rssi_ext[3]; /* rx frame RSSI [ext, chain 0-2] */
uint8_t rs_isaggr; /* is part of the aggregate */
uint8_t rs_moreaggr; /* more frames in aggr to follow */
+ uint16_t rs_flags; /* misc flags */
uint8_t rs_num_delims; /* number of delims in aggr */
- uint8_t rs_flags; /* misc flags */
+ uint8_t rs_spare0; /* padding */
uint32_t rs_evm0; /* evm bytes */
uint32_t rs_evm1;
- uint32_t rs_evm2;
+ uint32_t rs_evm2;
uint32_t rs_evm3; /* needed for ar9300 and later */
uint32_t rs_evm4; /* needed for ar9300 and later */
#endif /* AH_SUPPORT_AR5416 */
@@ -138,16 +139,19 @@ struct ath_rx_status {
#define HAL_RXERR_FIFO 0x04 /* fifo overrun */
#define HAL_RXERR_DECRYPT 0x08 /* non-Michael decrypt error */
#define HAL_RXERR_MIC 0x10 /* Michael MIC decrypt error */
+#define HAL_RXERR_INCOMP 0x20 /* Rx Desc processing is incomplete */
+#define HAL_RXERR_KEYMISS 0x40 /* Key not found in keycache */
/* bits found in rs_flags */
-#define HAL_RX_MORE 0x01 /* more descriptors follow */
-#define HAL_RX_MORE_AGGR 0x02 /* more frames in aggr */
-#define HAL_RX_GI 0x04 /* full gi */
-#define HAL_RX_2040 0x08 /* 40 Mhz */
-#define HAL_RX_DELIM_CRC_PRE 0x10 /* crc error in delimiter pre */
-#define HAL_RX_DELIM_CRC_POST 0x20 /* crc error in delim after */
-#define HAL_RX_DECRYPT_BUSY 0x40 /* decrypt was too slow */
-#define HAL_RX_HI_RX_CHAIN 0x80 /* SM power save: hi Rx chain control */
+#define HAL_RX_MORE 0x0001 /* more descriptors follow */
+#define HAL_RX_MORE_AGGR 0x0002 /* more frames in aggr */
+#define HAL_RX_GI 0x0004 /* full gi */
+#define HAL_RX_2040 0x0008 /* 40 Mhz */
+#define HAL_RX_DELIM_CRC_PRE 0x0010 /* crc error in delimiter pre */
+#define HAL_RX_DELIM_CRC_POST 0x0020 /* crc error in delim after */
+#define HAL_RX_DECRYPT_BUSY 0x0040 /* decrypt was too slow */
+#define HAL_RX_HI_RX_CHAIN 0x0080 /* SM power save: hi Rx chain control */
+#define HAL_RX_IS_APSD 0x0100 /* Is ASPD trigger frame */
enum {
HAL_PHYERR_UNDERRUN = 0, /* Transmit underrun */
@@ -178,6 +182,8 @@ enum {
HAL_PHYERR_HT_CRC_ERROR = 34, /* */
HAL_PHYERR_HT_LENGTH_ILLEGAL = 35, /* */
HAL_PHYERR_HT_RATE_ILLEGAL = 36, /* */
+
+ HAL_PHYERR_SPECTRAL = 38,
};
/* value found in rs_keyix to mark invalid entries */
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210.h b/sys/dev/ath/ath_hal/ar5210/ar5210.h
index 68e3af5..657e250 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210.h
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210.h
@@ -180,8 +180,8 @@ extern void ar5210IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *);
extern HAL_BOOL ar5210GetTxCompletionRates(struct ath_hal *ah,
const struct ath_desc *, int *rates, int *tries);
-extern uint32_t ar5210GetRxDP(struct ath_hal *);
-extern void ar5210SetRxDP(struct ath_hal *, uint32_t rxdp);
+extern uint32_t ar5210GetRxDP(struct ath_hal *, HAL_RX_QUEUE);
+extern void ar5210SetRxDP(struct ath_hal *, uint32_t rxdp, HAL_RX_QUEUE);
extern void ar5210EnableReceive(struct ath_hal *);
extern HAL_BOOL ar5210StopDmaReceive(struct ath_hal *);
extern void ar5210StartPcuReceive(struct ath_hal *);
diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c b/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c
index bdb4d57..3a1220b 100644
--- a/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c
+++ b/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c
@@ -30,8 +30,10 @@
* Get the RXDP.
*/
uint32_t
-ar5210GetRxDP(struct ath_hal *ah)
+ar5210GetRxDP(struct ath_hal *ah, HAL_RX_QUEUE qtype)
{
+
+ HALASSERT(qtype == HAL_RX_QUEUE_HP);
return OS_REG_READ(ah, AR_RXDP);
}
@@ -39,8 +41,10 @@ ar5210GetRxDP(struct ath_hal *ah)
* Set the RxDP.
*/
void
-ar5210SetRxDP(struct ath_hal *ah, uint32_t rxdp)
+ar5210SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE qtype)
{
+
+ HALASSERT(qtype == HAL_RX_QUEUE_HP);
OS_REG_WRITE(ah, AR_RXDP, rxdp);
}
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211.h b/sys/dev/ath/ath_hal/ar5211/ar5211.h
index 122206b..1d6c8af 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211.h
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211.h
@@ -205,8 +205,8 @@ extern void ar5211IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *);
extern HAL_BOOL ar5211GetTxCompletionRates(struct ath_hal *ah,
const struct ath_desc *ds0, int *rates, int *tries);
-extern uint32_t ar5211GetRxDP(struct ath_hal *);
-extern void ar5211SetRxDP(struct ath_hal *, uint32_t rxdp);
+extern uint32_t ar5211GetRxDP(struct ath_hal *, HAL_RX_QUEUE);
+extern void ar5211SetRxDP(struct ath_hal *, uint32_t rxdp, HAL_RX_QUEUE);
extern void ar5211EnableReceive(struct ath_hal *);
extern HAL_BOOL ar5211StopDmaReceive(struct ath_hal *);
extern void ar5211StartPcuReceive(struct ath_hal *);
diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c b/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c
index 733559e..27c4835 100644
--- a/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c
+++ b/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c
@@ -30,8 +30,10 @@
* Get the RXDP.
*/
uint32_t
-ar5211GetRxDP(struct ath_hal *ah)
+ar5211GetRxDP(struct ath_hal *ah, HAL_RX_QUEUE qtype)
{
+
+ HALASSERT(qtype == HAL_RX_QUEUE_HP);
return OS_REG_READ(ah, AR_RXDP);
}
@@ -39,8 +41,10 @@ ar5211GetRxDP(struct ath_hal *ah)
* Set the RxDP.
*/
void
-ar5211SetRxDP(struct ath_hal *ah, uint32_t rxdp)
+ar5211SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE qtype)
{
+
+ HALASSERT(qtype == HAL_RX_QUEUE_HP);
OS_REG_WRITE(ah, AR_RXDP, rxdp);
HALASSERT(OS_REG_READ(ah, AR_RXDP) == rxdp);
}
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212.h b/sys/dev/ath/ath_hal/ar5212/ar5212.h
index d651691..a8b95d1 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212.h
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212.h
@@ -519,8 +519,8 @@ extern HAL_BOOL ar5212SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode,
extern HAL_POWER_MODE ar5212GetPowerMode(struct ath_hal *ah);
extern HAL_BOOL ar5212GetPowerStatus(struct ath_hal *ah);
-extern uint32_t ar5212GetRxDP(struct ath_hal *ath);
-extern void ar5212SetRxDP(struct ath_hal *ah, uint32_t rxdp);
+extern uint32_t ar5212GetRxDP(struct ath_hal *ath, HAL_RX_QUEUE);
+extern void ar5212SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE);
extern void ar5212EnableReceive(struct ath_hal *ah);
extern HAL_BOOL ar5212StopDmaReceive(struct ath_hal *ah);
extern void ar5212StartPcuReceive(struct ath_hal *ah);
diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c b/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c
index db4f93d..00b04ca 100644
--- a/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c
+++ b/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c
@@ -29,8 +29,10 @@
* Get the RXDP.
*/
uint32_t
-ar5212GetRxDP(struct ath_hal *ath)
+ar5212GetRxDP(struct ath_hal *ath, HAL_RX_QUEUE qtype)
{
+
+ HALASSERT(qtype == HAL_RX_QUEUE_HP);
return OS_REG_READ(ath, AR_RXDP);
}
@@ -38,8 +40,10 @@ ar5212GetRxDP(struct ath_hal *ath)
* Set the RxDP.
*/
void
-ar5212SetRxDP(struct ath_hal *ah, uint32_t rxdp)
+ar5212SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE qtype)
{
+
+ HALASSERT(qtype == HAL_RX_QUEUE_HP);
OS_REG_WRITE(ah, AR_RXDP, rxdp);
HALASSERT(OS_REG_READ(ah, AR_RXDP) == rxdp);
}
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index c5dc03f..965a1fd 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -116,9 +116,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ath/ath_tx99/ath_tx99.h>
#endif
-#define ATH_KTR_INTR KTR_SPARE4
-#define ATH_KTR_ERR KTR_SPARE3
-
/*
* ATH_BCBUF determines the number of vap's that can transmit
* beacons and also (currently) the number of vap's that can
@@ -157,8 +154,6 @@ static void ath_update_promisc(struct ifnet *);
static void ath_updateslot(struct ifnet *);
static void ath_bstuck_proc(void *, int);
static void ath_reset_proc(void *, int);
-static void ath_descdma_cleanup(struct ath_softc *sc,
- struct ath_descdma *, ath_bufhead *);
static int ath_desc_alloc(struct ath_softc *);
static void ath_desc_free(struct ath_softc *);
static struct ieee80211_node *ath_node_alloc(struct ieee80211vap *,
@@ -239,15 +234,15 @@ static int ath_anicalinterval = 100; /* ANI calibration - 100 msec */
SYSCTL_INT(_hw_ath, OID_AUTO, anical, CTLFLAG_RW, &ath_anicalinterval,
0, "ANI calibration (msecs)");
-static int ath_rxbuf = ATH_RXBUF; /* # rx buffers to allocate */
+int ath_rxbuf = ATH_RXBUF; /* # rx buffers to allocate */
SYSCTL_INT(_hw_ath, OID_AUTO, rxbuf, CTLFLAG_RW, &ath_rxbuf,
0, "rx buffers allocated");
TUNABLE_INT("hw.ath.rxbuf", &ath_rxbuf);
-static int ath_txbuf = ATH_TXBUF; /* # tx buffers to allocate */
+int ath_txbuf = ATH_TXBUF; /* # tx buffers to allocate */
SYSCTL_INT(_hw_ath, OID_AUTO, txbuf, CTLFLAG_RW, &ath_txbuf,
0, "tx buffers allocated");
TUNABLE_INT("hw.ath.txbuf", &ath_txbuf);
-static int ath_txbuf_mgmt = ATH_MGMT_TXBUF; /* # mgmt tx buffers to allocate */
+int ath_txbuf_mgmt = ATH_MGMT_TXBUF; /* # mgmt tx buffers to allocate */
SYSCTL_INT(_hw_ath, OID_AUTO, txbuf_mgmt, CTLFLAG_RW, &ath_txbuf_mgmt,
0, "tx (mgmt) buffers allocated");
TUNABLE_INT("hw.ath.txbuf_mgmt", &ath_txbuf_mgmt);
@@ -308,9 +303,10 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
*
* This is required before the descriptors are allocated.
*/
- if (ath_hal_hasedma(sc->sc_ah))
+ if (ath_hal_hasedma(sc->sc_ah)) {
+ sc->sc_isedma = 1;
ath_recv_setup_edma(sc);
- else
+ } else
ath_recv_setup_legacy(sc);
/*
@@ -378,6 +374,14 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
if_printf(ifp, "failed to allocate descriptors: %d\n", error);
goto bad;
}
+
+ error = ath_rxdma_setup(sc);
+ if (error != 0) {
+ if_printf(ifp, "failed to allocate RX descriptors: %d\n",
+ error);
+ goto bad;
+ }
+
callout_init_mtx(&sc->sc_cal_ch, &sc->sc_mtx, 0);
callout_init_mtx(&sc->sc_wd_ch, &sc->sc_mtx, 0);
@@ -854,6 +858,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
bad2:
ath_tx_cleanup(sc);
ath_desc_free(sc);
+ ath_rxdma_teardown(sc);
bad:
if (ah)
ath_hal_detach(ah);
@@ -896,6 +901,7 @@ ath_detach(struct ath_softc *sc)
ath_dfs_detach(sc);
ath_desc_free(sc);
+ ath_rxdma_teardown(sc);
ath_tx_cleanup(sc);
ath_hal_detach(sc->sc_ah); /* NB: sets chip in full sleep */
if_free(ifp);
@@ -1615,7 +1621,11 @@ ath_intr(void *arg)
/* bump tx trigger level */
ath_hal_updatetxtriglevel(ah, AH_TRUE);
}
- if (status & HAL_INT_RX) {
+ /*
+ * Handle both the legacy and RX EDMA interrupt bits.
+ * Note that HAL_INT_RXLP is also HAL_INT_RXDESC.
+ */
+ if (status & (HAL_INT_RX | HAL_INT_RXHP | HAL_INT_RXLP)) {
sc->sc_stats.ast_rx_intr++;
taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask);
}
@@ -1861,6 +1871,14 @@ ath_init(void *arg)
sc->sc_imask = HAL_INT_RX | HAL_INT_TX
| HAL_INT_RXEOL | HAL_INT_RXORN
| HAL_INT_FATAL | HAL_INT_GLOBAL;
+
+ /*
+ * Enable RX EDMA bits. Note these overlap with
+ * HAL_INT_RX and HAL_INT_RXDESC respectively.
+ */
+ if (sc->sc_isedma)
+ sc->sc_imask |= (HAL_INT_RXHP | HAL_INT_RXLP);
+
/*
* Enable MIB interrupts when there are hardware phy counters.
* Note we only do this (at the moment) for station mode.
@@ -2594,6 +2612,13 @@ ath_mode_init(struct ath_softc *sc)
/* configure operational mode */
ath_hal_setopmode(ah);
+ DPRINTF(sc, ATH_DEBUG_STATE | ATH_DEBUG_MODE,
+ "%s: ah=%p, ifp=%p, if_addr=%p\n",
+ __func__,
+ ah,
+ ifp,
+ (ifp == NULL) ? NULL : ifp->if_addr);
+
/* handle any link-level address change */
ath_hal_setmac(ah, IF_LLADDR(ifp));
@@ -2724,7 +2749,7 @@ ath_load_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
*paddr = segs->ds_addr;
}
-static int
+int
ath_descdma_setup(struct ath_softc *sc,
struct ath_descdma *dd, ath_bufhead *head,
const char *name, int nbuf, int ndesc)
@@ -2863,7 +2888,7 @@ fail0:
#undef ATH_DESC_4KB_BOUND_CHECK
}
-static void
+void
ath_descdma_cleanup(struct ath_softc *sc,
struct ath_descdma *dd, ath_bufhead *head)
{
@@ -2904,15 +2929,9 @@ ath_desc_alloc(struct ath_softc *sc)
{
int error;
- error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
- "rx", ath_rxbuf, 1);
- if (error != 0)
- return error;
-
error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf,
"tx", ath_txbuf, ATH_TXDESC);
if (error != 0) {
- ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
return error;
}
sc->sc_txbuf_cnt = ath_txbuf;
@@ -2920,7 +2939,6 @@ ath_desc_alloc(struct ath_softc *sc)
error = ath_descdma_setup(sc, &sc->sc_txdma_mgmt, &sc->sc_txbuf_mgmt,
"tx_mgmt", ath_txbuf_mgmt, ATH_TXDESC);
if (error != 0) {
- ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf);
return error;
}
@@ -2933,7 +2951,6 @@ ath_desc_alloc(struct ath_softc *sc)
error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
"beacon", ATH_BCBUF, 1);
if (error != 0) {
- ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf);
ath_descdma_cleanup(sc, &sc->sc_txdma_mgmt,
&sc->sc_txbuf_mgmt);
@@ -2950,8 +2967,6 @@ ath_desc_free(struct ath_softc *sc)
ath_descdma_cleanup(sc, &sc->sc_bdma, &sc->sc_bbuf);
if (sc->sc_txdma.dd_desc_len != 0)
ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf);
- if (sc->sc_rxdma.dd_desc_len != 0)
- ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
if (sc->sc_txdma_mgmt.dd_desc_len != 0)
ath_descdma_cleanup(sc, &sc->sc_txdma_mgmt,
&sc->sc_txbuf_mgmt);
diff --git a/sys/dev/ath/if_ath_debug.c b/sys/dev/ath/if_ath_debug.c
index 0b49a06..da898be 100644
--- a/sys/dev/ath/if_ath_debug.c
+++ b/sys/dev/ath/if_ath_debug.c
@@ -118,6 +118,16 @@ ath_printrxbuf(struct ath_softc *sc, const struct ath_buf *bf,
ds->ds_hw[2], ds->ds_hw[3], ds->ds_hw[4],
ds->ds_hw[5], ds->ds_hw[6], ds->ds_hw[7],
ds->ds_hw[8]);
+ } else if (ah->ah_magic == 0x19741014) {
+ printf(" %08x %08x %08x %08x %08x %08x %08x\n",
+ ds->ds_hw[2], ds->ds_hw[3], ds->ds_hw[4],
+ ds->ds_hw[5], ds->ds_hw[6], ds->ds_hw[7],
+ ds->ds_hw[8]);
+
+ printf(" %08x %08x %08x %08x %08x %08x %08x\n",
+ ds->ds_hw[9], ds->ds_hw[10], ds->ds_hw[11],
+ ds->ds_hw[12], ds->ds_hw[13], ds->ds_hw[14],
+ ds->ds_hw[15]);
}
}
}
diff --git a/sys/dev/ath/if_ath_debug.h b/sys/dev/ath/if_ath_debug.h
index ff514ce..2e6ebf5 100644
--- a/sys/dev/ath/if_ath_debug.h
+++ b/sys/dev/ath/if_ath_debug.h
@@ -64,9 +64,14 @@ enum {
ATH_DEBUG_SW_TX_RETRIES = 0x040000000ULL, /* software TX retries */
ATH_DEBUG_FATAL = 0x080000000ULL, /* fatal errors */
ATH_DEBUG_SW_TX_BAR = 0x100000000ULL, /* BAR TX */
+ ATH_DEBUG_EDMA_RX = 0x200000000ULL, /* RX EDMA state */
+
ATH_DEBUG_ANY = 0xffffffffffffffffULL
};
+#define ATH_KTR_INTR KTR_SPARE4
+#define ATH_KTR_ERR KTR_SPARE3
+
extern uint64_t ath_debug;
#define IFF_DUMPPKTS(sc, m) \
@@ -86,6 +91,9 @@ extern void ath_printrxbuf(struct ath_softc *, const struct ath_buf *bf,
extern void ath_printtxbuf(struct ath_softc *, const struct ath_buf *bf,
u_int qnum, u_int ix, int done);
#else /* ATH_DEBUG */
+#define ATH_KTR_INTR 0
+#define ATH_KTR_ERR 0
+
#define IFF_DUMPPKTS(sc, m) \
((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
#define DPRINTF(sc, m, fmt, ...) do { \
diff --git a/sys/dev/ath/if_ath_misc.h b/sys/dev/ath/if_ath_misc.h
index 4c1d24b..0a51fee 100644
--- a/sys/dev/ath/if_ath_misc.h
+++ b/sys/dev/ath/if_ath_misc.h
@@ -48,6 +48,10 @@
((((u_int8_t *)(p))[0] ) | (((u_int8_t *)(p))[1] << 8) | \
(((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24)))
+extern int ath_rxbuf;
+extern int ath_txbuf;
+extern int ath_txbuf_mgmt;
+
extern int ath_tx_findrix(const struct ath_softc *sc, uint8_t rate);
extern struct ath_buf * ath_getbuf(struct ath_softc *sc,
@@ -80,6 +84,11 @@ extern void ath_setdefantenna(struct ath_softc *sc, u_int antenna);
extern void ath_setslottime(struct ath_softc *sc);
+extern int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+ ath_bufhead *head, const char *name, int nbuf, int ndesc);
+extern void ath_descdma_cleanup(struct ath_softc *sc,
+ struct ath_descdma *dd, ath_bufhead *head);
+
/*
* This is only here so that the RX proc function can call it.
* It's very likely that the "start TX after RX" call should be
diff --git a/sys/dev/ath/if_ath_rx.c b/sys/dev/ath/if_ath_rx.c
index dd03fb9..eba6ba5 100644
--- a/sys/dev/ath/if_ath_rx.c
+++ b/sys/dev/ath/if_ath_rx.c
@@ -115,9 +115,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ath/ath_tx99/ath_tx99.h>
#endif
-#define ATH_KTR_INTR KTR_SPARE4
-#define ATH_KTR_ERR KTR_SPARE3
-
/*
* Calculate the receive filter according to the
* operating mode and state:
@@ -463,9 +460,9 @@ ath_handle_micerror(struct ieee80211com *ic,
}
}
-static int
+int
ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status,
- uint64_t tsf, int nf, struct ath_buf *bf)
+ uint64_t tsf, int nf, HAL_RX_QUEUE qtype, struct ath_buf *bf)
{
struct ath_hal *ah = sc->sc_ah;
struct mbuf *m = bf->bf_m;
@@ -475,6 +472,7 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status,
struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211_node *ni;
int is_good = 0;
+ struct ath_rx_edma *re = &sc->sc_rxedma[qtype];
/*
* Calculate the correct 64 bit TSF given
@@ -559,9 +557,9 @@ rx_error:
/*
* Cleanup any pending partial frame.
*/
- if (sc->sc_rxpending != NULL) {
- m_freem(sc->sc_rxpending);
- sc->sc_rxpending = NULL;
+ if (re->m_rxpending != NULL) {
+ m_freem(re->m_rxpending);
+ re->m_rxpending = NULL;
}
/*
* When a tap is present pass error frames
@@ -608,25 +606,25 @@ rx_accept:
* it for the next completed descriptor, it
* will be used to construct a jumbogram.
*/
- if (sc->sc_rxpending != NULL) {
+ if (re->m_rxpending != NULL) {
/* NB: max frame size is currently 2 clusters */
sc->sc_stats.ast_rx_toobig++;
- m_freem(sc->sc_rxpending);
+ m_freem(re->m_rxpending);
}
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = len;
- sc->sc_rxpending = m;
+ re->m_rxpending = m;
goto rx_next;
- } else if (sc->sc_rxpending != NULL) {
+ } else if (re->m_rxpending != NULL) {
/*
* This is the second part of a jumbogram,
* chain it to the first mbuf, adjust the
* frame length, and clear the rxpending state.
*/
- sc->sc_rxpending->m_next = m;
- sc->sc_rxpending->m_pkthdr.len += len;
- m = sc->sc_rxpending;
- sc->sc_rxpending = NULL;
+ re->m_rxpending->m_next = m;
+ re->m_rxpending->m_pkthdr.len += len;
+ m = re->m_rxpending;
+ re->m_rxpending = NULL;
} else {
/*
* Normal single-descriptor receive; setup
@@ -883,7 +881,7 @@ ath_rx_proc(struct ath_softc *sc, int resched)
/*
* Process a single frame.
*/
- if (ath_rx_pkt(sc, rs, status, tsf, nf, bf))
+ if (ath_rx_pkt(sc, rs, status, tsf, nf, HAL_RX_QUEUE_HP, bf))
ngood++;
rx_proc_next:
TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
@@ -916,7 +914,7 @@ rx_proc_next:
* Are there any net80211 buffer calls involved?
*/
bf = TAILQ_FIRST(&sc->sc_rxbuf);
- ath_hal_putrxbuf(ah, bf->bf_daddr);
+ ath_hal_putrxbuf(ah, bf->bf_daddr, HAL_RX_QUEUE_HP);
ath_hal_rxena(ah); /* enable recv descriptors */
ath_mode_init(sc); /* set filters, etc. */
ath_hal_startpcurecv(ah); /* re-enable PCU/DMA engine */
@@ -1002,7 +1000,7 @@ ath_legacy_stoprecv(struct ath_softc *sc, int dodelay)
device_printf(sc->sc_dev,
"%s: rx queue %p, link %p\n",
__func__,
- (caddr_t)(uintptr_t) ath_hal_getrxbuf(ah),
+ (caddr_t)(uintptr_t) ath_hal_getrxbuf(ah, HAL_RX_QUEUE_HP),
sc->sc_rxlink);
ix = 0;
TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
@@ -1016,9 +1014,16 @@ ath_legacy_stoprecv(struct ath_softc *sc, int dodelay)
}
}
#endif
- if (sc->sc_rxpending != NULL) {
- m_freem(sc->sc_rxpending);
- sc->sc_rxpending = NULL;
+ /*
+ * Free both high/low RX pending, just in case.
+ */
+ if (sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending != NULL) {
+ m_freem(sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending);
+ sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending = NULL;
+ }
+ if (sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending != NULL) {
+ m_freem(sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending);
+ sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending = NULL;
}
sc->sc_rxlink = NULL; /* just in case */
#undef PA2DESC
@@ -1034,7 +1039,8 @@ ath_legacy_startrecv(struct ath_softc *sc)
struct ath_buf *bf;
sc->sc_rxlink = NULL;
- sc->sc_rxpending = NULL;
+ sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending = NULL;
+ sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending = NULL;
TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
int error = ath_rxbuf_init(sc, bf);
if (error != 0) {
@@ -1046,13 +1052,38 @@ ath_legacy_startrecv(struct ath_softc *sc)
}
bf = TAILQ_FIRST(&sc->sc_rxbuf);
- ath_hal_putrxbuf(ah, bf->bf_daddr);
+ ath_hal_putrxbuf(ah, bf->bf_daddr, HAL_RX_QUEUE_HP);
ath_hal_rxena(ah); /* enable recv descriptors */
ath_mode_init(sc); /* set filters, etc. */
ath_hal_startpcurecv(ah); /* re-enable PCU/DMA engine */
return 0;
}
+static int
+ath_legacy_dma_rxsetup(struct ath_softc *sc)
+{
+ int error;
+
+ device_printf(sc->sc_dev, "%s: called\n", __func__);
+
+ error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
+ "rx", ath_rxbuf, 1);
+ if (error != 0)
+ return (error);
+
+ return (0);
+}
+
+static int
+ath_legacy_dma_rxteardown(struct ath_softc *sc)
+{
+
+ device_printf(sc->sc_dev, "%s: called\n", __func__);
+
+ if (sc->sc_rxdma.dd_desc_len != 0)
+ ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
+ return (0);
+}
void
ath_recv_setup_legacy(struct ath_softc *sc)
@@ -1065,4 +1096,7 @@ ath_recv_setup_legacy(struct ath_softc *sc)
sc->sc_rx.recv_flush = ath_legacy_flushrecv;
sc->sc_rx.recv_tasklet = ath_legacy_rx_tasklet;
sc->sc_rx.recv_rxbuf_init = ath_legacy_rxbuf_init;
+
+ sc->sc_rx.recv_setup = ath_legacy_dma_rxsetup;
+ sc->sc_rx.recv_teardown = ath_legacy_dma_rxteardown;
}
diff --git a/sys/dev/ath/if_ath_rx.h b/sys/dev/ath/if_ath_rx.h
index f99425e..504ff80 100644
--- a/sys/dev/ath/if_ath_rx.h
+++ b/sys/dev/ath/if_ath_rx.h
@@ -43,6 +43,10 @@ extern void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
(_sc)->sc_rx.recv_flush((_sc))
#define ath_rxbuf_init(_sc, _bf) \
(_sc)->sc_rx.recv_rxbuf_init((_sc), (_bf))
+#define ath_rxdma_setup(_sc) \
+ (_sc)->sc_rx.recv_setup(_sc)
+#define ath_rxdma_teardown(_sc) \
+ (_sc)->sc_rx.recv_teardown(_sc)
#if 0
extern int ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf);
@@ -52,6 +56,10 @@ extern void ath_stoprecv(struct ath_softc *sc, int dodelay);
extern int ath_startrecv(struct ath_softc *sc);
#endif
+extern int ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs,
+ HAL_STATUS status, uint64_t tsf, int nf, HAL_RX_QUEUE qtype,
+ struct ath_buf *bf);
+
extern void ath_recv_setup_legacy(struct ath_softc *sc);
#endif
diff --git a/sys/dev/ath/if_ath_rx_edma.c b/sys/dev/ath/if_ath_rx_edma.c
index dc9b1a9..9e3580d 100644
--- a/sys/dev/ath/if_ath_rx_edma.c
+++ b/sys/dev/ath/if_ath_rx_edma.c
@@ -117,6 +117,40 @@ __FBSDID("$FreeBSD$");
#include <dev/ath/if_ath_rx_edma.h>
+/*
+ * some general macros
+ */
+#define INCR(_l, _sz) (_l) ++; (_l) &= ((_sz) - 1)
+#define DECR(_l, _sz) (_l) --; (_l) &= ((_sz) - 1)
+
+MALLOC_DECLARE(M_ATHDEV);
+
+/*
+ * XXX TODO:
+ *
+ * + Add an RX lock, just to ensure we don't have things clash;
+ * + Make sure the FIFO is correctly flushed and reinitialised
+ * through a reset;
+ * + Handle the "kickpcu" state where the FIFO overflows.
+ * + Implement a "flush" routine, which doesn't push any
+ * new frames into the FIFO.
+ * + Verify multi-descriptor frames work!
+ * + There's a "memory use after free" which needs to be tracked down
+ * and fixed ASAP. I've seen this in the legacy path too, so it
+ * may be a generic RX path issue.
+ */
+
+/*
+ * XXX shuffle the function orders so these pre-declarations aren't
+ * required!
+ */
+static int ath_edma_rxfifo_alloc(struct ath_softc *sc, HAL_RX_QUEUE qtype,
+ int nbufs);
+static int ath_edma_rxfifo_flush(struct ath_softc *sc, HAL_RX_QUEUE qtype);
+static void ath_edma_rxbuf_free(struct ath_softc *sc, struct ath_buf *bf);
+static int ath_edma_recv_proc_queue(struct ath_softc *sc,
+ HAL_RX_QUEUE qtype, int dosched);
+
static void
ath_edma_stoprecv(struct ath_softc *sc, int dodelay)
{
@@ -128,25 +162,108 @@ ath_edma_stoprecv(struct ath_softc *sc, int dodelay)
DELAY(3000);
- if (sc->sc_rxpending != NULL) {
- m_freem(sc->sc_rxpending);
- sc->sc_rxpending = NULL;
+ /* Flush RX pending for each queue */
+ /* XXX should generic-ify this */
+ if (sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending) {
+ m_freem(sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending);
+ sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending = NULL;
+ }
+
+ if (sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending) {
+ m_freem(sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending);
+ sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending = NULL;
}
+}
- sc->sc_rxlink = NULL;
+/*
+ * Re-initialise the FIFO given the current buffer contents.
+ * Specifically, walk from head -> tail, pushing the FIFO contents
+ * back into the FIFO.
+ */
+static void
+ath_edma_reinit_fifo(struct ath_softc *sc, HAL_RX_QUEUE qtype)
+{
+ struct ath_rx_edma *re = &sc->sc_rxedma[qtype];
+ struct ath_buf *bf;
+ int i, j;
+
+ i = re->m_fifo_head;
+ for (j = 0; j < re->m_fifo_depth; j++) {
+ bf = re->m_fifo[i];
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX,
+ "%s: Q%d: pos=%i, addr=0x%jx\n",
+ __func__,
+ qtype,
+ i,
+ (uintmax_t)bf->bf_daddr);
+ ath_hal_putrxbuf(sc->sc_ah, bf->bf_daddr, qtype);
+ INCR(i, re->m_fifolen);
+ }
+
+ /* Ensure this worked out right */
+ if (i != re->m_fifo_tail) {
+ device_printf(sc->sc_dev, "%s: i (%d) != tail! (%d)\n",
+ __func__,
+ i,
+ re->m_fifo_tail);
+ }
}
+/*
+ * Start receive.
+ *
+ * XXX TODO: this needs to reallocate the FIFO entries when a reset
+ * occurs, in case the FIFO is filled up and no new descriptors get
+ * thrown into the FIFO.
+ */
static int
ath_edma_startrecv(struct ath_softc *sc)
{
struct ath_hal *ah = sc->sc_ah;
- sc->sc_rxlink = NULL;
- sc->sc_rxpending = NULL;
+ /* Enable RX FIFO */
+ ath_hal_rxena(ah);
+
+ /*
+ * Entries should only be written out if the
+ * FIFO is empty.
+ *
+ * XXX This isn't correct. I should be looking
+ * at the value of AR_RXDP_SIZE (0x0070) to determine
+ * how many entries are in here.
+ *
+ * A warm reset will clear the registers but not the FIFO.
+ *
+ * And I believe this is actually the address of the last
+ * handled buffer rather than the current FIFO pointer.
+ * So if no frames have been (yet) seen, we'll reinit the
+ * FIFO.
+ *
+ * I'll chase that up at some point.
+ */
+ if (ath_hal_getrxbuf(sc->sc_ah, HAL_RX_QUEUE_HP) == 0) {
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX,
+ "%s: Re-initing HP FIFO\n", __func__);
+ ath_edma_reinit_fifo(sc, HAL_RX_QUEUE_HP);
+ }
+ if (ath_hal_getrxbuf(sc->sc_ah, HAL_RX_QUEUE_LP) == 0) {
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX,
+ "%s: Re-initing LP FIFO\n", __func__);
+ ath_edma_reinit_fifo(sc, HAL_RX_QUEUE_LP);
+ }
+
+ /* Add up to m_fifolen entries in each queue */
+ /*
+ * These must occur after the above write so the FIFO buffers
+ * are pushed/tracked in the same order as the hardware will
+ * process them.
+ */
+ ath_edma_rxfifo_alloc(sc, HAL_RX_QUEUE_HP,
+ sc->sc_rxedma[HAL_RX_QUEUE_HP].m_fifolen);
+
+ ath_edma_rxfifo_alloc(sc, HAL_RX_QUEUE_LP,
+ sc->sc_rxedma[HAL_RX_QUEUE_LP].m_fifolen);
- /* XXX setup HP RX queue FIFO pointer */
- /* XXX setup LP RX queue FIFO pointer */
- /* XXX ath_hal_rxena() */
ath_mode_init(sc);
ath_hal_startpcurecv(ah);
return (0);
@@ -157,6 +274,123 @@ ath_edma_recv_flush(struct ath_softc *sc)
{
device_printf(sc->sc_dev, "%s: called\n", __func__);
+
+ ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_HP, 0);
+ ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_LP, 0);
+}
+
+/*
+ * Process frames from the current queue.
+ *
+ * TODO:
+ *
+ * + Add a "dosched" flag, so we don't reschedule any FIFO frames
+ * to the hardware or re-kick the PCU after 'kickpcu' is set.
+ *
+ * + Perhaps split "check FIFO contents" and "handle frames", so
+ * we can run the "check FIFO contents" in ath_intr(), but
+ * "handle frames" in the RX tasklet.
+ */
+static int
+ath_edma_recv_proc_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
+ int dosched)
+{
+ struct ath_rx_edma *re = &sc->sc_rxedma[qtype];
+ struct ath_rx_status *rs;
+ struct ath_desc *ds;
+ struct ath_buf *bf;
+ struct mbuf *m;
+ HAL_STATUS status;
+ struct ath_hal *ah = sc->sc_ah;
+ uint64_t tsf;
+ int16_t nf;
+ int ngood = 0;
+
+ tsf = ath_hal_gettsf64(ah);
+ nf = ath_hal_getchannoise(ah, sc->sc_curchan);
+ sc->sc_stats.ast_rx_noise = nf;
+
+ do {
+ bf = re->m_fifo[re->m_fifo_head];
+ /* This shouldn't occur! */
+ if (bf == NULL) {
+ device_printf(sc->sc_dev, "%s: Q%d: NULL bf?\n",
+ __func__,
+ qtype);
+ break;
+ }
+ m = bf->bf_m;
+ ds = bf->bf_desc;
+
+ /*
+ * Sync descriptor memory - this also syncs the buffer for us.
+ *
+ * EDMA descriptors are in cached memory.
+ */
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
+ BUS_DMASYNC_POSTREAD);
+ rs = &bf->bf_status.ds_rxstat;
+ status = ath_hal_rxprocdesc(ah, ds, bf->bf_daddr, NULL, rs);
+#ifdef ATH_DEBUG
+ if (sc->sc_debug & ATH_DEBUG_RECV_DESC)
+ ath_printrxbuf(sc, bf, 0, status == HAL_OK);
+#endif
+ if (status == HAL_EINPROGRESS)
+ break;
+
+ /*
+ * Completed descriptor.
+ *
+ * In the future we'll call ath_rx_pkt(), but it first
+ * has to be taught about EDMA RX queues (so it can
+ * access sc_rxpending correctly.)
+ */
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX,
+ "%s: Q%d: completed!\n", __func__, qtype);
+
+ /*
+ * Remove the FIFO entry!
+ */
+ re->m_fifo[re->m_fifo_head] = NULL;
+
+ /*
+ * Skip the RX descriptor status - start at the data offset
+ */
+ m_adj(m, sc->sc_rx_statuslen);
+
+ /* Handle the frame */
+ if (ath_rx_pkt(sc, rs, status, tsf, nf, qtype, bf))
+ ngood++;
+
+ /* Free the buffer/mbuf */
+ ath_edma_rxbuf_free(sc, bf);
+
+ /* Bump the descriptor FIFO stats */
+ INCR(re->m_fifo_head, re->m_fifolen);
+ re->m_fifo_depth--;
+ /* XXX check it doesn't fall below 0 */
+ } while (re->m_fifo_depth > 0);
+
+ /* Handle resched and kickpcu appropriately */
+ ATH_PCU_LOCK(sc);
+ if (dosched && sc->sc_kickpcu) {
+ CTR0(ATH_KTR_ERR, "ath_edma_recv_proc_queue(): kickpcu");
+ device_printf(sc->sc_dev, "%s: handled %d descriptors\n",
+ __func__, ngood);
+
+ /*
+ * XXX TODO: what should occur here? Just re-poke and
+ * re-enable the RX FIFO?
+ */
+ sc->sc_kickpcu = 0;
+ }
+ ATH_PCU_UNLOCK(sc);
+
+ /* Append some more fresh frames to the FIFO */
+ if (dosched)
+ ath_edma_rxfifo_alloc(sc, qtype, re->m_fifolen);
+
+ return (ngood);
}
static void
@@ -164,18 +398,336 @@ ath_edma_recv_tasklet(void *arg, int npending)
{
struct ath_softc *sc = (struct ath_softc *) arg;
- device_printf(sc->sc_dev, "%s: called; npending=%d\n",
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: called; npending=%d\n",
__func__,
npending);
- /* XXX TODO */
+
+ ATH_PCU_LOCK(sc);
+ if (sc->sc_inreset_cnt > 0) {
+ device_printf(sc->sc_dev, "%s: sc_inreset_cnt > 0; skipping\n",
+ __func__);
+ ATH_PCU_UNLOCK(sc);
+ return;
+ }
+ ATH_PCU_UNLOCK(sc);
+
+ ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_HP, 1);
+ ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_LP, 1);
}
+/*
+ * Allocate an RX mbuf for the given ath_buf and initialise
+ * it for EDMA.
+ *
+ * + Allocate a 4KB mbuf;
+ * + Setup the DMA map for the given buffer;
+ * + Keep a pointer to the start of the mbuf - that's where the
+ * descriptor lies;
+ * + Take a pointer to the start of the RX buffer, set the
+ * mbuf "start" to be there;
+ * + Return that.
+ */
static int
ath_edma_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
{
- device_printf(sc->sc_dev, "%s: called; bf=%p\n", __func__, bf);
- return (EIO);
+ struct mbuf *m;
+ int error;
+ int len;
+
+// device_printf(sc->sc_dev, "%s: called; bf=%p\n", __func__, bf);
+
+ m = m_getm(NULL, sc->sc_edma_bufsize, M_DONTWAIT, MT_DATA);
+ if (! m)
+ return (ENOBUFS); /* XXX ?*/
+
+ /* XXX warn/enforce alignment */
+
+ len = m->m_ext.ext_size;
+#if 0
+ device_printf(sc->sc_dev, "%s: called: m=%p, size=%d, mtod=%p\n",
+ __func__,
+ m,
+ len,
+ mtod(m, char *));
+#endif
+
+ m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
+
+ /*
+ * Create DMA mapping.
+ */
+ error = bus_dmamap_load_mbuf_sg(sc->sc_dmat,
+ bf->bf_dmamap, m, bf->bf_segs, &bf->bf_nseg, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ device_printf(sc->sc_dev, "%s: failed; error=%d\n",
+ __func__,
+ error);
+ m_freem(m);
+ return (error);
+ }
+
+ /*
+ * Populate ath_buf fields.
+ */
+
+ bf->bf_desc = mtod(m, struct ath_desc *);
+ bf->bf_daddr = bf->bf_segs[0].ds_addr;
+ bf->bf_lastds = bf->bf_desc; /* XXX only really for TX? */
+ bf->bf_m = m;
+
+ /* Zero the descriptor */
+ memset(bf->bf_desc, '\0', sc->sc_rx_statuslen);
+
+#if 0
+ /*
+ * Adjust mbuf header and length/size to compensate for the
+ * descriptor size.
+ */
+ m_adj(m, sc->sc_rx_statuslen);
+#endif
+
+ /* Finish! */
+
+ return (0);
+}
+
+static struct ath_buf *
+ath_edma_rxbuf_alloc(struct ath_softc *sc)
+{
+ struct ath_buf *bf;
+ int error;
+
+ /* Allocate buffer */
+ bf = TAILQ_FIRST(&sc->sc_rxbuf);
+ /* XXX shouldn't happen upon startup? */
+ if (bf == NULL)
+ return (NULL);
+
+ /* Remove it from the free list */
+ TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list);
+
+ /* Assign RX mbuf to it */
+ error = ath_edma_rxbuf_init(sc, bf);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "%s: bf=%p, rxbuf alloc failed! error=%d\n",
+ __func__,
+ bf,
+ error);
+ TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
+ return (NULL);
+ }
+
+ return (bf);
+}
+
+static void
+ath_edma_rxbuf_free(struct ath_softc *sc, struct ath_buf *bf)
+{
+
+ bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
+
+ if (bf->bf_m) {
+ m_freem(bf->bf_m);
+ bf->bf_m = NULL;
+ }
+
+ /* XXX lock? */
+ TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
+}
+
+/*
+ * Allocate up to 'n' entries and push them onto the hardware FIFO.
+ *
+ * Return how many entries were successfully pushed onto the
+ * FIFO.
+ */
+static int
+ath_edma_rxfifo_alloc(struct ath_softc *sc, HAL_RX_QUEUE qtype, int nbufs)
+{
+ struct ath_rx_edma *re = &sc->sc_rxedma[qtype];
+ struct ath_buf *bf;
+ int i;
+
+ /*
+ * Allocate buffers until the FIFO is full or nbufs is reached.
+ */
+ for (i = 0; i < nbufs && re->m_fifo_depth < re->m_fifolen; i++) {
+ /* Ensure the FIFO is already blank, complain loudly! */
+ if (re->m_fifo[re->m_fifo_tail] != NULL) {
+ device_printf(sc->sc_dev,
+ "%s: Q%d: fifo[%d] != NULL (%p)\n",
+ __func__,
+ qtype,
+ re->m_fifo_tail,
+ re->m_fifo[re->m_fifo_tail]);
+
+ /* Free the slot */
+ ath_edma_rxbuf_free(sc, re->m_fifo[re->m_fifo_tail]);
+ re->m_fifo_depth--;
+ /* XXX check it's not < 0 */
+ re->m_fifo[re->m_fifo_tail] = NULL;
+ }
+
+ bf = ath_edma_rxbuf_alloc(sc);
+ /* XXX should ensure the FIFO is not NULL? */
+ if (bf == NULL) {
+ device_printf(sc->sc_dev, "%s: Q%d: alloc failed?\n",
+ __func__,
+ qtype);
+ break;
+ }
+
+ re->m_fifo[re->m_fifo_tail] = bf;
+
+ /*
+ * Flush the descriptor contents before it's handed to the
+ * hardware.
+ */
+ bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
+ BUS_DMASYNC_PREREAD);
+
+ /* Write to the RX FIFO */
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: Q%d: putrxbuf=%p\n",
+ __func__,
+ qtype,
+ bf->bf_desc);
+ ath_hal_putrxbuf(sc->sc_ah, bf->bf_daddr, qtype);
+
+ re->m_fifo_depth++;
+ INCR(re->m_fifo_tail, re->m_fifolen);
+ }
+
+ /*
+ * Return how many were allocated.
+ */
+ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: Q%d: nbufs=%d, nalloced=%d\n",
+ __func__,
+ qtype,
+ nbufs,
+ i);
+ return (i);
+}
+
+static int
+ath_edma_rxfifo_flush(struct ath_softc *sc, HAL_RX_QUEUE qtype)
+{
+ struct ath_rx_edma *re = &sc->sc_rxedma[qtype];
+ int i;
+
+ for (i = 0; i < re->m_fifolen; i++) {
+ if (re->m_fifo[i] != NULL) {
+#ifdef ATH_DEBUG
+ struct ath_buf *bf = re->m_fifo[i];
+
+ if (sc->sc_debug & ATH_DEBUG_RECV_DESC)
+ ath_printrxbuf(sc, bf, 0, HAL_OK);
+#endif
+ ath_edma_rxbuf_free(sc, re->m_fifo[i]);
+ re->m_fifo[i] = NULL;
+ re->m_fifo_depth--;
+ }
+ }
+
+ if (re->m_rxpending != NULL) {
+ m_freem(re->m_rxpending);
+ re->m_rxpending = NULL;
+ }
+ re->m_fifo_head = re->m_fifo_tail = re->m_fifo_depth = 0;
+
+ return (0);
+}
+
+/*
+ * Setup the initial RX FIFO structure.
+ */
+static int
+ath_edma_setup_rxfifo(struct ath_softc *sc, HAL_RX_QUEUE qtype)
+{
+ struct ath_rx_edma *re = &sc->sc_rxedma[qtype];
+
+ if (! ath_hal_getrxfifodepth(sc->sc_ah, qtype, &re->m_fifolen)) {
+ device_printf(sc->sc_dev, "%s: qtype=%d, failed\n",
+ __func__,
+ qtype);
+ return (-EINVAL);
+ }
+ device_printf(sc->sc_dev, "%s: type=%d, FIFO depth = %d entries\n",
+ __func__,
+ qtype,
+ re->m_fifolen);
+
+ /* Allocate ath_buf FIFO array, pre-zero'ed */
+ re->m_fifo = malloc(sizeof(struct ath_buf *) * re->m_fifolen,
+ M_ATHDEV,
+ M_NOWAIT | M_ZERO);
+ if (re->m_fifo == NULL) {
+ device_printf(sc->sc_dev, "%s: malloc failed\n",
+ __func__);
+ return (-ENOMEM);
+ }
+
+ /*
+ * Set initial "empty" state.
+ */
+ re->m_rxpending = NULL;
+ re->m_fifo_head = re->m_fifo_tail = re->m_fifo_depth = 0;
+
+ return (0);
+}
+
+static int
+ath_edma_rxfifo_free(struct ath_softc *sc, HAL_RX_QUEUE qtype)
+{
+ struct ath_rx_edma *re = &sc->sc_rxedma[qtype];
+
+ device_printf(sc->sc_dev, "%s: called; qtype=%d\n",
+ __func__,
+ qtype);
+
+ free(re->m_fifo, M_ATHDEV);
+
+ return (0);
+}
+
+static int
+ath_edma_dma_rxsetup(struct ath_softc *sc)
+{
+ int error;
+
+ /* Create RX DMA tag */
+ /* Create RX ath_buf array */
+
+ error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
+ "rx", ath_rxbuf, 1);
+ if (error != 0)
+ return error;
+
+ (void) ath_edma_setup_rxfifo(sc, HAL_RX_QUEUE_HP);
+ (void) ath_edma_setup_rxfifo(sc, HAL_RX_QUEUE_LP);
+
+ return (0);
+}
+
+static int
+ath_edma_dma_rxteardown(struct ath_softc *sc)
+{
+
+ device_printf(sc->sc_dev, "%s: called\n", __func__);
+
+ ath_edma_rxfifo_flush(sc, HAL_RX_QUEUE_HP);
+ ath_edma_rxfifo_free(sc, HAL_RX_QUEUE_HP);
+
+ ath_edma_rxfifo_flush(sc, HAL_RX_QUEUE_LP);
+ ath_edma_rxfifo_free(sc, HAL_RX_QUEUE_LP);
+
+ /* Free RX ath_buf */
+ /* Free RX DMA tag */
+ if (sc->sc_rxdma.dd_desc_len != 0)
+ ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
+
+ return (0);
}
void
@@ -184,9 +736,35 @@ ath_recv_setup_edma(struct ath_softc *sc)
device_printf(sc->sc_dev, "DMA setup: EDMA\n");
+ /* Set buffer size to 4k */
+ sc->sc_edma_bufsize = 4096;
+
+ /* Configure the hardware with this */
+ (void) ath_hal_setrxbufsize(sc->sc_ah, sc->sc_edma_bufsize);
+
+ /* Fetch EDMA field and buffer sizes */
+ (void) ath_hal_getrxstatuslen(sc->sc_ah, &sc->sc_rx_statuslen);
+ (void) ath_hal_gettxdesclen(sc->sc_ah, &sc->sc_tx_desclen);
+ (void) ath_hal_gettxstatuslen(sc->sc_ah, &sc->sc_tx_statuslen);
+ (void) ath_hal_getntxmaps(sc->sc_ah, &sc->sc_tx_nmaps);
+
+ device_printf(sc->sc_dev, "RX status length: %d\n",
+ sc->sc_rx_statuslen);
+ device_printf(sc->sc_dev, "TX descriptor length: %d\n",
+ sc->sc_tx_desclen);
+ device_printf(sc->sc_dev, "TX status length: %d\n",
+ sc->sc_tx_statuslen);
+ device_printf(sc->sc_dev, "TX/RX buffer size: %d\n",
+ sc->sc_edma_bufsize);
+ device_printf(sc->sc_dev, "TX buffers per descriptor: %d\n",
+ sc->sc_tx_nmaps);
+
sc->sc_rx.recv_stop = ath_edma_stoprecv;
sc->sc_rx.recv_start = ath_edma_startrecv;
sc->sc_rx.recv_flush = ath_edma_recv_flush;
sc->sc_rx.recv_tasklet = ath_edma_recv_tasklet;
sc->sc_rx.recv_rxbuf_init = ath_edma_rxbuf_init;
+
+ sc->sc_rx.recv_setup = ath_edma_dma_rxsetup;
+ sc->sc_rx.recv_teardown = ath_edma_dma_rxteardown;
}
diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c
index 46efd61..934f9dc 100644
--- a/sys/dev/ath/if_ath_tx.c
+++ b/sys/dev/ath/if_ath_tx.c
@@ -3583,6 +3583,10 @@ ath_tx_aggr_comp_aggr(struct ath_softc *sc, struct ath_buf *bf_first,
"seq_st=%d\n",
__func__, hasba, tx_ok, isaggr, seq_st);
/* XXX TODO: schedule an interface reset */
+#ifdef ATH_DEBUG
+ ath_printtxbuf(sc, bf_first,
+ sc->sc_ac2q[atid->ac]->axq_qnum, 0, 0);
+#endif
}
/*
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index d622df5..7370e01 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -379,6 +379,20 @@ struct ath_rx_methods {
void (*recv_tasklet)(void *arg, int npending);
int (*recv_rxbuf_init)(struct ath_softc *sc,
struct ath_buf *bf);
+ int (*recv_setup)(struct ath_softc *sc);
+ int (*recv_teardown)(struct ath_softc *sc);
+};
+
+/*
+ * Represent the current state of the RX FIFO.
+ */
+struct ath_rx_edma {
+ struct ath_buf **m_fifo;
+ int m_fifolen;
+ int m_fifo_head;
+ int m_fifo_tail;
+ int m_fifo_depth;
+ struct mbuf *m_rxpending;
};
struct ath_softc {
@@ -395,6 +409,12 @@ struct ath_softc {
uint32_t sc_bssidmask; /* bssid mask */
struct ath_rx_methods sc_rx;
+ struct ath_rx_edma sc_rxedma[2]; /* HP/LP queues */
+ int sc_rx_statuslen;
+ int sc_tx_desclen;
+ int sc_tx_statuslen;
+ int sc_tx_nmaps; /* Number of TX maps */
+ int sc_edma_bufsize;
void (*sc_node_cleanup)(struct ieee80211_node *);
void (*sc_node_free)(struct ieee80211_node *);
@@ -439,7 +459,8 @@ struct ath_softc {
sc_setcca : 1,/* set/clr CCA with TDMA */
sc_resetcal : 1,/* reset cal state next trip */
sc_rxslink : 1,/* do self-linked final descriptor */
- sc_rxtsf32 : 1;/* RX dec TSF is 32 bits */
+ sc_rxtsf32 : 1,/* RX dec TSF is 32 bits */
+ sc_isedma : 1;/* supports EDMA */
uint32_t sc_eerd; /* regdomain from EEPROM */
uint32_t sc_eecc; /* country code from EEPROM */
/* rate tables */
@@ -510,7 +531,6 @@ struct ath_softc {
struct ath_descdma sc_rxdma; /* RX descriptors */
ath_bufhead sc_rxbuf; /* receive buffer */
- struct mbuf *sc_rxpending; /* pending receive data */
u_int32_t *sc_rxlink; /* link ptr in last RX desc */
struct task sc_rxtask; /* rx int processing */
u_int8_t sc_defant; /* current default antenna */
@@ -745,8 +765,8 @@ void ath_intr(void *);
((*(_ah)->ah_setMulticastFilter)((_ah), (_mfilt0), (_mfilt1)))
#define ath_hal_waitforbeacon(_ah, _bf) \
((*(_ah)->ah_waitForBeaconDone)((_ah), (_bf)->bf_daddr))
-#define ath_hal_putrxbuf(_ah, _bufaddr) \
- ((*(_ah)->ah_setRxDP)((_ah), (_bufaddr)))
+#define ath_hal_putrxbuf(_ah, _bufaddr, _rxq) \
+ ((*(_ah)->ah_setRxDP)((_ah), (_bufaddr), (_rxq)))
/* NB: common across all chips */
#define AR_TSF_L32 0x804c /* MAC local clock lower 32 bits */
#define ath_hal_gettsf32(_ah) \
@@ -763,8 +783,8 @@ void ath_intr(void *);
((*(_ah)->ah_getTxDP)((_ah), (_q)))
#define ath_hal_numtxpending(_ah, _q) \
((*(_ah)->ah_numTxPending)((_ah), (_q)))
-#define ath_hal_getrxbuf(_ah) \
- ((*(_ah)->ah_getRxDP)((_ah)))
+#define ath_hal_getrxbuf(_ah, _rxq) \
+ ((*(_ah)->ah_getRxDP)((_ah), (_rxq)))
#define ath_hal_txstart(_ah, _q) \
((*(_ah)->ah_startTxDma)((_ah), (_q)))
#define ath_hal_setchannel(_ah, _chan) \
@@ -953,11 +973,34 @@ void ath_intr(void *);
#define ath_hal_setintmit(_ah, _v) \
ath_hal_setcapability(_ah, HAL_CAP_INTMIT, \
HAL_CAP_INTMIT_ENABLE, _v, NULL)
+
+/* EDMA definitions */
#define ath_hal_hasedma(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_ENHANCED_DMA_SUPPORT, \
0, NULL) == HAL_OK)
+#define ath_hal_getrxfifodepth(_ah, _qtype, _req) \
+ (ath_hal_getcapability(_ah, HAL_CAP_RXFIFODEPTH, _qtype, _req) \
+ == HAL_OK)
+#define ath_hal_getntxmaps(_ah, _req) \
+ (ath_hal_getcapability(_ah, HAL_CAP_NUM_TXMAPS, 0, _req) \
+ == HAL_OK)
+#define ath_hal_gettxdesclen(_ah, _req) \
+ (ath_hal_getcapability(_ah, HAL_CAP_TXDESCLEN, 0, _req) \
+ == HAL_OK)
+#define ath_hal_gettxstatuslen(_ah, _req) \
+ (ath_hal_getcapability(_ah, HAL_CAP_TXSTATUSLEN, 0, _req) \
+ == HAL_OK)
+#define ath_hal_getrxstatuslen(_ah, _req) \
+ (ath_hal_getcapability(_ah, HAL_CAP_RXSTATUSLEN, 0, _req) \
+ == HAL_OK)
+#define ath_hal_setrxbufsize(_ah, _req) \
+ (ath_hal_setcapability(_ah, HAL_CAP_RXBUFSIZE, 0, _req, NULL) \
+ == HAL_OK)
+
#define ath_hal_getchannoise(_ah, _c) \
((*(_ah)->ah_getChanNoise)((_ah), (_c)))
+
+/* 802.11n HAL methods */
#define ath_hal_getrxchainmask(_ah, _prxchainmask) \
(ath_hal_getcapability(_ah, HAL_CAP_RX_CHAINMASK, 0, _prxchainmask))
#define ath_hal_gettxchainmask(_ah, _ptxchainmask) \
diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c
index 7d48fe9..4ded12d 100644
--- a/sys/dev/cxgbe/t4_sge.c
+++ b/sys/dev/cxgbe/t4_sge.c
@@ -401,14 +401,16 @@ first_vector(struct port_info *pi)
return (0);
for_each_port(sc, i) {
+ struct port_info *p = sc->port[i];
+
if (i == pi->port_id)
break;
#ifdef TCP_OFFLOAD
if (sc->flags & INTR_DIRECT)
- rc += pi->nrxq + pi->nofldrxq;
+ rc += p->nrxq + p->nofldrxq;
else
- rc += max(pi->nrxq, pi->nofldrxq);
+ rc += max(p->nrxq, p->nofldrxq);
#else
/*
* Not compiled with offload support and intr_count > 1. Only
@@ -419,7 +421,7 @@ first_vector(struct port_info *pi)
("%s: intr_count %d, !INTR_DIRECT", __func__,
sc->intr_count));
- rc += pi->nrxq;
+ rc += p->nrxq;
#endif
}
diff --git a/sys/dev/mfi/mfi_disk.c b/sys/dev/mfi/mfi_disk.c
index fc43e67..18ceb99 100644
--- a/sys/dev/mfi/mfi_disk.c
+++ b/sys/dev/mfi/mfi_disk.c
@@ -298,6 +298,7 @@ mfi_disk_complete(struct bio *bio)
hdr = bio->bio_driver1;
if (bio->bio_flags & BIO_ERROR) {
+ bio->bio_resid = bio->bio_bcount;
if (bio->bio_error == 0)
bio->bio_error = EIO;
disk_err(bio, "hard error", -1, 1);
diff --git a/sys/dev/mfi/mfivar.h b/sys/dev/mfi/mfivar.h
index d38fcc3..176a10a 100644
--- a/sys/dev/mfi/mfivar.h
+++ b/sys/dev/mfi/mfivar.h
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/taskqueue.h>
+#include "opt_mfi.h"
/*
* SCSI structures and definitions are used from here, but no linking
diff --git a/sys/dev/usb/usb_pf.c b/sys/dev/usb/usb_pf.c
index 6d65439..b7b29d7 100644
--- a/sys/dev/usb/usb_pf.c
+++ b/sys/dev/usb/usb_pf.c
@@ -44,8 +44,10 @@ __FBSDID("$FreeBSD$");
#include <sys/sockio.h>
#include <net/if.h>
#include <net/if_types.h>
+#include <net/if_clone.h>
#include <net/bpf.h>
#include <sys/sysctl.h>
+#include <net/route.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -58,35 +60,146 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usb_pf.h>
#include <dev/usb/usb_transfer.h>
-static int usb_no_pf;
-
-SYSCTL_INT(_hw_usb, OID_AUTO, no_pf, CTLFLAG_RW,
- &usb_no_pf, 0, "Set to disable USB packet filtering");
+#define USBUSNAME "usbus"
+
+static void usbpf_init(void);
+static void usbpf_uninit(void);
+static int usbpf_ioctl(struct ifnet *, u_long, caddr_t);
+static int usbpf_clone_match(struct if_clone *, const char *);
+static int usbpf_clone_create(struct if_clone *, char *, size_t, caddr_t);
+static int usbpf_clone_destroy(struct if_clone *, struct ifnet *);
+static struct usb_bus *usbpf_ifname2ubus(const char *);
+static uint32_t usbpf_aggregate_xferflags(struct usb_xfer_flags *);
+static uint32_t usbpf_aggregate_status(struct usb_xfer_flags_int *);
+static int usbpf_xfer_frame_is_read(struct usb_xfer *, uint32_t);
+static uint32_t usbpf_xfer_precompute_size(struct usb_xfer *, int);
+
+static struct if_clone usbpf_cloner = IFC_CLONE_INITIALIZER(
+ USBUSNAME, NULL, IF_MAXUNIT,
+ NULL, usbpf_clone_match, usbpf_clone_create, usbpf_clone_destroy);
+
+SYSINIT(usbpf_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_init, NULL);
+SYSUNINIT(usbpf_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_uninit, NULL);
+
+static void
+usbpf_init(void)
+{
-TUNABLE_INT("hw.usb.no_pf", &usb_no_pf);
+ if_clone_attach(&usbpf_cloner);
+}
-void
-usbpf_attach(struct usb_bus *ubus)
+static void
+usbpf_uninit(void)
{
- struct ifnet *ifp;
-
- if (usb_no_pf != 0) {
- ubus->ifp = NULL;
+ int devlcnt;
+ device_t *devlp;
+ devclass_t dc;
+ struct usb_bus *ubus;
+ int error;
+ int i;
+
+ if_clone_detach(&usbpf_cloner);
+
+ dc = devclass_find(USBUSNAME);
+ if (dc == NULL)
+ return;
+ error = devclass_get_devices(dc, &devlp, &devlcnt);
+ if (error)
return;
+ for (i = 0; i < devlcnt; i++) {
+ ubus = device_get_softc(devlp[i]);
+ if (ubus != NULL && ubus->ifp != NULL)
+ usbpf_clone_destroy(&usbpf_cloner, ubus->ifp);
}
+}
+
+static int
+usbpf_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+
+ /* No configuration allowed. */
+ return (EINVAL);
+}
+
+static struct usb_bus *
+usbpf_ifname2ubus(const char *ifname)
+{
+ device_t dev;
+ devclass_t dc;
+ int unit;
+ int error;
+
+ if (strncmp(ifname, USBUSNAME, sizeof(USBUSNAME) - 1) != 0)
+ return (NULL);
+ error = ifc_name2unit(ifname, &unit);
+ if (error || unit < 0)
+ return (NULL);
+ dc = devclass_find(USBUSNAME);
+ if (dc == NULL)
+ return (NULL);
+ dev = devclass_get_device(dc, unit);
+ if (dev == NULL)
+ return (NULL);
+
+ return (device_get_softc(dev));
+}
+
+static int
+usbpf_clone_match(struct if_clone *ifc, const char *name)
+{
+ struct usb_bus *ubus;
+
+ ubus = usbpf_ifname2ubus(name);
+ if (ubus == NULL)
+ return (0);
+ if (ubus->ifp != NULL)
+ return (0);
+
+ return (1);
+}
+static int
+usbpf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
+{
+ int error;
+ int unit;
+ struct ifnet *ifp;
+ struct usb_bus *ubus;
+
+ error = ifc_name2unit(name, &unit);
+ if (error)
+ return (error);
+ if (unit < 0)
+ return (EINVAL);
+
+ ubus = usbpf_ifname2ubus(name);
+ if (ubus == NULL)
+ return (1);
+ if (ubus->ifp != NULL)
+ return (1);
+
+ error = ifc_alloc_unit(ifc, &unit);
+ if (error) {
+ ifc_free_unit(ifc, unit);
+ device_printf(ubus->parent, "usbpf: Could not allocate "
+ "instance\n");
+ return (error);
+ }
ifp = ubus->ifp = if_alloc(IFT_USB);
if (ifp == NULL) {
+ ifc_free_unit(ifc, unit);
device_printf(ubus->parent, "usbpf: Could not allocate "
"instance\n");
- return;
+ return (ENOSPC);
}
-
- if_initname(ifp, "usbus", device_get_unit(ubus->bdev));
- ifp->if_flags = IFF_CANTCONFIG;
+ strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
+ ifp->if_softc = ubus;
+ ifp->if_dname = ifc->ifc_name;
+ ifp->if_dunit = unit;
+ ifp->if_ioctl = usbpf_ioctl;
if_attach(ifp);
- if_up(ifp);
-
+ ifp->if_flags |= IFF_UP;
+ rt_ifmsg(ifp);
/*
* XXX According to the specification of DLT_USB, it indicates
* packets beginning with USB setup header. But not sure all
@@ -94,6 +207,31 @@ usbpf_attach(struct usb_bus *ubus)
*/
bpfattach(ifp, DLT_USB, USBPF_HDR_LEN);
+ return (0);
+}
+
+static int
+usbpf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
+{
+ struct usb_bus *ubus;
+ int unit;
+
+ ubus = ifp->if_softc;
+ unit = ifp->if_dunit;
+
+ ubus->ifp = NULL;
+ bpfdetach(ifp);
+ if_detach(ifp);
+ if_free(ifp);
+ ifc_free_unit(ifc, unit);
+
+ return (0);
+}
+
+void
+usbpf_attach(struct usb_bus *ubus)
+{
+
if (bootverbose)
device_printf(ubus->parent, "usbpf: Attached\n");
}
@@ -101,15 +239,11 @@ usbpf_attach(struct usb_bus *ubus)
void
usbpf_detach(struct usb_bus *ubus)
{
- struct ifnet *ifp = ubus->ifp;
- if (ifp != NULL) {
- bpfdetach(ifp);
- if_down(ifp);
- if_detach(ifp);
- if_free(ifp);
- }
- ubus->ifp = NULL;
+ if (ubus->ifp != NULL)
+ usbpf_clone_destroy(&usbpf_cloner, ubus->ifp);
+ if (bootverbose)
+ device_printf(ubus->parent, "usbpf: Detached\n");
}
static uint32_t
@@ -259,8 +393,6 @@ usbpf_xfertap(struct usb_xfer *xfer, int type)
bus = xfer->xroot->bus;
/* sanity checks */
- if (usb_no_pf != 0)
- return;
if (bus->ifp == NULL)
return;
if (!bpf_peers_present(bus->ifp->if_bpf))
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 643964d..aedea58 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -2140,6 +2140,7 @@ product LOGITEC RT2870_1 0x0162 RT2870
product LOGITEC RT2870_2 0x0163 RT2870
product LOGITEC RT2870_3 0x0164 RT2870
product LOGITEC LANW300NU2 0x0166 LAN-W300N/U2
+product LOGITEC LANW150NU2 0x0168 LAN-W150N/U2
/* Longcheer Holdings, Ltd. products */
product LONGCHEER WM66 0x6061 Longcheer WM66 HSDPA
@@ -2204,7 +2205,8 @@ product MELCO RT2870_1 0x0148 RT2870
product MELCO RT2870_2 0x0150 RT2870
product MELCO WLIUCGN 0x015d WLI-UC-GN
product MELCO WLIUCG301N 0x016f WLI-UC-G301N
-product MELCO WLIUCGNM 0x01a2 WLI-UC-GNM
+product MELCO WLIUCGNM 0x01a2 WLI-UC-GNM
+product MELCO WLIUCGNM2 0x01ee WLI-UC-GNM2
/* Merlin products */
product MERLIN V620 0x1110 Merlin V620
@@ -2618,6 +2620,7 @@ product PLANEX2 GWUS54GD 0xed01 GW-US54GD
product PLANEX2 GWUSMM 0xed02 GW-USMM
product PLANEX2 RT2870 0xed06 RT2870
product PLANEX2 GWUSMICRON 0xed14 GW-USMicroN
+product PLANEX2 GWUSVALUEEZ 0xed17 GW-USValue-EZ
product PLANEX3 GWUS54GZ 0xab10 GW-US54GZ
product PLANEX3 GU1000T 0xab11 GU-1000T
product PLANEX3 GWUS54MINI 0xab13 GW-US54Mini
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index 94ac4ea..c3a714d 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -209,6 +209,7 @@ static const STRUCT_USB_HOST_ID run_devs[] = {
RUN_DEV(LOGITEC, RT2870_2),
RUN_DEV(LOGITEC, RT2870_3),
RUN_DEV(LOGITEC, LANW300NU2),
+ RUN_DEV(LOGITEC, LANW150NU2),
RUN_DEV(MELCO, RT2870_1),
RUN_DEV(MELCO, RT2870_2),
RUN_DEV(MELCO, WLIUCAG300N),
@@ -216,6 +217,7 @@ static const STRUCT_USB_HOST_ID run_devs[] = {
RUN_DEV(MELCO, WLIUCG301N),
RUN_DEV(MELCO, WLIUCGN),
RUN_DEV(MELCO, WLIUCGNM),
+ RUN_DEV(MELCO, WLIUCGNM2),
RUN_DEV(MOTOROLA4, RT2770),
RUN_DEV(MOTOROLA4, RT3070),
RUN_DEV(MSI, RT3070_1),
diff --git a/sys/dev/virtio/balloon/virtio_balloon.c b/sys/dev/virtio/balloon/virtio_balloon.c
index d589a73..9b45459 100644
--- a/sys/dev/virtio/balloon/virtio_balloon.c
+++ b/sys/dev/virtio/balloon/virtio_balloon.c
@@ -412,7 +412,6 @@ vtballoon_send_page_frames(struct vtballoon_softc *sc, struct virtqueue *vq,
* interrupt handler will wake us up.
*/
VTBALLOON_LOCK(sc);
-
while ((c = virtqueue_dequeue(vq, NULL)) == NULL)
msleep_spin(sc, VTBALLOON_MTX(sc), "vtbspf", 0);
VTBALLOON_UNLOCK(sc);
diff --git a/sys/dev/virtio/block/virtio_blk.c b/sys/dev/virtio/block/virtio_blk.c
index d05fa7a..d35421a 100644
--- a/sys/dev/virtio/block/virtio_blk.c
+++ b/sys/dev/virtio/block/virtio_blk.c
@@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
#include <sys/taskqueue.h>
#include <geom/geom_disk.h>
-#include <vm/uma.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -119,7 +118,7 @@ static int vtblk_shutdown(device_t);
static int vtblk_open(struct disk *);
static int vtblk_close(struct disk *);
static int vtblk_ioctl(struct disk *, u_long, void *, int,
- struct thread *);
+ struct thread *);
static int vtblk_dump(void *, void *, vm_offset_t, off_t, size_t);
static void vtblk_strategy(struct bio *);
@@ -193,7 +192,7 @@ TUNABLE_INT("hw.vtblk.no_ident", &vtblk_no_ident);
mtx_assert(VTBLK_MTX((_sc)), MA_NOTOWNED)
#define VTBLK_DISK_NAME "vtbd"
-#define VTBLK_QUIESCE_TIMEOUT (30 * hz)
+#define VTBLK_QUIESCE_TIMEOUT (30 * hz)
/*
* Each block request uses at least two segments - one for the header
@@ -201,8 +200,6 @@ TUNABLE_INT("hw.vtblk.no_ident", &vtblk_no_ident);
*/
#define VTBLK_MIN_SEGMENTS 2
-static uma_zone_t vtblk_req_zone;
-
static device_method_t vtblk_methods[] = {
/* Device methods. */
DEVMETHOD(device_probe, vtblk_probe),
@@ -236,19 +233,8 @@ vtblk_modevent(module_t mod, int type, void *unused)
switch (type) {
case MOD_LOAD:
- vtblk_req_zone = uma_zcreate("vtblk_request",
- sizeof(struct vtblk_request),
- NULL, NULL, NULL, NULL, 0, 0);
- break;
case MOD_QUIESCE:
case MOD_UNLOAD:
- if (uma_zone_get_cur(vtblk_req_zone) > 0)
- error = EBUSY;
- else if (type == MOD_UNLOAD) {
- uma_zdestroy(vtblk_req_zone);
- vtblk_req_zone = NULL;
- }
- break;
case MOD_SHUTDOWN:
break;
default:
@@ -316,7 +302,7 @@ vtblk_attach(device_t dev)
}
sc->vtblk_max_nsegs = vtblk_maximum_segments(sc, &blkcfg);
- if (sc->vtblk_max_nsegs <= VTBLK_MIN_SEGMENTS) {
+ if (sc->vtblk_max_nsegs <= VTBLK_MIN_SEGMENTS) {
error = EINVAL;
device_printf(dev, "fewer than minimum number of segments "
"allowed: %d\n", sc->vtblk_max_nsegs);
@@ -493,7 +479,6 @@ vtblk_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset,
int error;
dp = arg;
- error = 0;
if ((sc = dp->d_drv1) == NULL)
return (ENXIO);
@@ -539,7 +524,7 @@ vtblk_strategy(struct bio *bp)
return;
}
-#ifdef INVARIANTS
+#ifdef INVARIANTS
/*
* Prevent read/write buffers spanning too many segments from
* getting into the queue. This should only trip if d_maxsize
@@ -547,13 +532,13 @@ vtblk_strategy(struct bio *bp)
*/
if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
int nsegs, max_nsegs;
-
+
nsegs = sglist_count(bp->bio_data, bp->bio_bcount);
max_nsegs = sc->vtblk_max_nsegs - VTBLK_MIN_SEGMENTS;
KASSERT(nsegs <= max_nsegs,
- ("bio spanned too many segments: %d, max: %d",
- nsegs, max_nsegs));
+ ("bio %p spanned too many segments: %d, max: %d",
+ bp, nsegs, max_nsegs));
}
#endif
@@ -800,27 +785,22 @@ vtblk_execute_request(struct vtblk_softc *sc, struct vtblk_request *req)
VTBLK_LOCK_ASSERT(sc);
sglist_reset(sg);
- error = sglist_append(sg, &req->vbr_hdr,
- sizeof(struct virtio_blk_outhdr));
- KASSERT(error == 0, ("error adding header to sglist"));
- KASSERT(sg->sg_nseg == 1,
- ("header spanned multiple segments: %d", sg->sg_nseg));
+
+ sglist_append(sg, &req->vbr_hdr, sizeof(struct virtio_blk_outhdr));
if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
error = sglist_append(sg, bp->bio_data, bp->bio_bcount);
- KASSERT(error == 0, ("error adding buffer to sglist"));
+ if (error || sg->sg_nseg == sg->sg_maxseg)
+ panic("%s: data buffer too big bio:%p error:%d",
+ __FUNCTION__, bp, error);
/* BIO_READ means the host writes into our buffer. */
if (bp->bio_cmd == BIO_READ)
- writable += sg->sg_nseg - 1;
+ writable = sg->sg_nseg - 1;
}
- error = sglist_append(sg, &req->vbr_ack, sizeof(uint8_t));
- KASSERT(error == 0, ("error adding ack to sglist"));
writable++;
-
- KASSERT(sg->sg_nseg >= VTBLK_MIN_SEGMENTS,
- ("fewer than min segments: %d", sg->sg_nseg));
+ sglist_append(sg, &req->vbr_ack, sizeof(uint8_t));
readable = sg->sg_nseg - writable;
@@ -995,12 +975,10 @@ vtblk_flush_dump(struct vtblk_softc *sc)
static int
vtblk_poll_request(struct vtblk_softc *sc, struct vtblk_request *req)
{
- device_t dev;
struct virtqueue *vq;
struct vtblk_request *r;
int error;
- dev = sc->vtblk_dev;
vq = sc->vtblk_vq;
if (!virtqueue_empty(vq))
@@ -1013,12 +991,12 @@ vtblk_poll_request(struct vtblk_softc *sc, struct vtblk_request *req)
virtqueue_notify(vq);
r = virtqueue_poll(vq, NULL);
- KASSERT(r == req, ("unexpected request response"));
+ KASSERT(r == req, ("unexpected request response: %p/%p", r, req));
error = vtblk_request_error(req);
if (error && bootverbose) {
- device_printf(dev, "vtblk_poll_request: IO error: %d\n",
- error);
+ device_printf(sc->vtblk_dev,
+ "%s: IO error: %d\n", __FUNCTION__, error);
}
return (error);
@@ -1090,6 +1068,20 @@ vtblk_drain(struct vtblk_softc *sc)
vtblk_free_requests(sc);
}
+#ifdef INVARIANTS
+static void
+vtblk_request_invariants(struct vtblk_request *req)
+{
+ int hdr_nsegs, ack_nsegs;
+
+ hdr_nsegs = sglist_count(&req->vbr_hdr, sizeof(req->vbr_hdr));
+ ack_nsegs = sglist_count(&req->vbr_ack, sizeof(req->vbr_ack));
+
+ KASSERT(hdr_nsegs == 1, ("request header crossed page boundary"));
+ KASSERT(ack_nsegs == 1, ("request ack crossed page boundary"));
+}
+#endif
+
static int
vtblk_alloc_requests(struct vtblk_softc *sc)
{
@@ -1107,10 +1099,14 @@ vtblk_alloc_requests(struct vtblk_softc *sc)
nreqs /= VTBLK_MIN_SEGMENTS;
for (i = 0; i < nreqs; i++) {
- req = uma_zalloc(vtblk_req_zone, M_NOWAIT);
+ req = malloc(sizeof(struct vtblk_request), M_DEVBUF, M_NOWAIT);
if (req == NULL)
return (ENOMEM);
+#ifdef INVARIANTS
+ vtblk_request_invariants(req);
+#endif
+
sc->vtblk_request_count++;
vtblk_enqueue_request(sc, req);
}
@@ -1128,10 +1124,11 @@ vtblk_free_requests(struct vtblk_softc *sc)
while ((req = vtblk_dequeue_request(sc)) != NULL) {
sc->vtblk_request_count--;
- uma_zfree(vtblk_req_zone, req);
+ free(req, M_DEVBUF);
}
- KASSERT(sc->vtblk_request_count == 0, ("leaked requests"));
+ KASSERT(sc->vtblk_request_count == 0,
+ ("leaked requests: %d", sc->vtblk_request_count));
}
static struct vtblk_request *
diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index 64a82ac..e6fef90 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -748,11 +748,9 @@ vtnet_is_link_up(struct vtnet_softc *sc)
static void
vtnet_update_link_status(struct vtnet_softc *sc)
{
- device_t dev;
struct ifnet *ifp;
int link;
- dev = sc->vtnet_dev;
ifp = sc->vtnet_ifp;
link = vtnet_is_link_up(sc);
diff --git a/sys/dev/virtio/pci/virtio_pci.c b/sys/dev/virtio/pci/virtio_pci.c
index 56813e4..917ca84 100644
--- a/sys/dev/virtio/pci/virtio_pci.c
+++ b/sys/dev/virtio/pci/virtio_pci.c
@@ -57,12 +57,15 @@ struct vtpci_softc {
struct resource *vtpci_msix_res;
uint64_t vtpci_features;
uint32_t vtpci_flags;
-#define VIRTIO_PCI_FLAG_NO_MSI 0x0001
-#define VIRTIO_PCI_FLAG_MSI 0x0002
-#define VIRTIO_PCI_FLAG_NO_MSIX 0x0010
-#define VIRTIO_PCI_FLAG_MSIX 0x0020
-#define VIRTIO_PCI_FLAG_SHARED_MSIX 0x0040
-
+#define VTPCI_FLAG_NO_MSI 0x0001
+#define VTPCI_FLAG_NO_MSIX 0x0002
+#define VTPCI_FLAG_LEGACY 0x1000
+#define VTPCI_FLAG_MSI 0x2000
+#define VTPCI_FLAG_MSIX 0x4000
+#define VTPCI_FLAG_SHARED_MSIX 0x8000
+#define VTPCI_FLAG_ITYPE_MASK 0xF000
+
+ /* This "bus" will only ever have one child. */
device_t vtpci_child_dev;
struct virtio_feature_desc *vtpci_child_feat_desc;
@@ -80,7 +83,8 @@ struct vtpci_softc {
int vtpci_nvqs;
struct vtpci_virtqueue {
struct virtqueue *vq;
-
+ /* Device did not provide a callback for this virtqueue. */
+ int no_intr;
/* Index into vtpci_intr_res[] below. Unused, then -1. */
int ires_idx;
} vtpci_vqx[VIRTIO_MAX_VIRTQUEUES];
@@ -130,24 +134,39 @@ static void vtpci_describe_features(struct vtpci_softc *, const char *,
uint64_t);
static void vtpci_probe_and_attach_child(struct vtpci_softc *);
-static int vtpci_alloc_interrupts(struct vtpci_softc *, int, int,
- struct vq_alloc_info *);
-static int vtpci_alloc_intr_resources(struct vtpci_softc *, int,
- struct vq_alloc_info *);
-static int vtpci_alloc_msi(struct vtpci_softc *);
-static int vtpci_alloc_msix(struct vtpci_softc *, int);
+static int vtpci_alloc_msix(struct vtpci_softc *, int);
+static int vtpci_alloc_msi(struct vtpci_softc *);
+static int vtpci_alloc_intr_msix_pervq(struct vtpci_softc *);
+static int vtpci_alloc_intr_msix_shared(struct vtpci_softc *);
+static int vtpci_alloc_intr_msi(struct vtpci_softc *);
+static int vtpci_alloc_intr_legacy(struct vtpci_softc *);
+static int vtpci_alloc_intr_resources(struct vtpci_softc *);
+
+static int vtpci_setup_legacy_interrupt(struct vtpci_softc *,
+ enum intr_type);
+static int vtpci_setup_msix_interrupts(struct vtpci_softc *,
+ enum intr_type);
+static int vtpci_setup_interrupts(struct vtpci_softc *, enum intr_type);
+
static int vtpci_register_msix_vector(struct vtpci_softc *, int, int);
+static int vtpci_set_host_msix_vectors(struct vtpci_softc *);
+static int vtpci_reinit_virtqueue(struct vtpci_softc *, int);
static void vtpci_free_interrupts(struct vtpci_softc *);
static void vtpci_free_virtqueues(struct vtpci_softc *);
+static void vtpci_cleanup_setup_intr_attempt(struct vtpci_softc *);
static void vtpci_release_child_resources(struct vtpci_softc *);
static void vtpci_reset(struct vtpci_softc *);
+static void vtpci_select_virtqueue(struct vtpci_softc *, int);
+
static int vtpci_legacy_intr(void *);
static int vtpci_vq_shared_intr(void *);
static int vtpci_vq_intr(void *);
static int vtpci_config_intr(void *);
+#define vtpci_setup_msi_interrupt vtpci_setup_legacy_interrupt
+
/*
* I/O port read/write wrappers.
*/
@@ -252,7 +271,7 @@ vtpci_attach(device_t dev)
}
if (pci_find_cap(dev, PCIY_MSI, NULL) != 0)
- sc->vtpci_flags |= VIRTIO_PCI_FLAG_NO_MSI;
+ sc->vtpci_flags |= VTPCI_FLAG_NO_MSI;
if (pci_find_cap(dev, PCIY_MSIX, NULL) == 0) {
rid = PCIR_BAR(1);
@@ -261,7 +280,7 @@ vtpci_attach(device_t dev)
}
if (sc->vtpci_msix_res == NULL)
- sc->vtpci_flags |= VIRTIO_PCI_FLAG_NO_MSIX;
+ sc->vtpci_flags |= VTPCI_FLAG_NO_MSIX;
vtpci_reset(sc);
@@ -372,6 +391,16 @@ vtpci_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
switch (index) {
case VIRTIO_IVAR_DEVTYPE:
+ case VIRTIO_IVAR_SUBDEVICE:
+ *result = pci_get_subdevice(dev);
+ break;
+ case VIRTIO_IVAR_VENDOR:
+ *result = pci_get_vendor(dev);
+ break;
+ case VIRTIO_IVAR_DEVICE:
+ *result = pci_get_device(dev);
+ break;
+ case VIRTIO_IVAR_SUBVENDOR:
*result = pci_get_subdevice(dev);
break;
default:
@@ -442,102 +471,97 @@ vtpci_alloc_virtqueues(device_t dev, int flags, int nvqs,
struct vq_alloc_info *vq_info)
{
struct vtpci_softc *sc;
+ struct virtqueue *vq;
struct vtpci_virtqueue *vqx;
struct vq_alloc_info *info;
- int queue, error;
- uint16_t vq_size;
+ int idx, error;
+ uint16_t size;
sc = device_get_softc(dev);
+ error = 0;
- if (sc->vtpci_nvqs != 0 || nvqs <= 0 ||
- nvqs > VIRTIO_MAX_VIRTQUEUES)
+ if (sc->vtpci_nvqs != 0)
+ return (EALREADY);
+ if (nvqs <= 0 || nvqs > VIRTIO_MAX_VIRTQUEUES)
return (EINVAL);
- error = vtpci_alloc_interrupts(sc, flags, nvqs, vq_info);
- if (error) {
- device_printf(dev, "cannot allocate interrupts\n");
- return (error);
- }
+ if (flags & VIRTIO_ALLOC_VQS_DISABLE_MSIX)
+ sc->vtpci_flags |= VTPCI_FLAG_NO_MSIX;
- if (sc->vtpci_flags & VIRTIO_PCI_FLAG_MSIX) {
- error = vtpci_register_msix_vector(sc,
- VIRTIO_MSI_CONFIG_VECTOR, 0);
- if (error)
- return (error);
- }
-
- for (queue = 0; queue < nvqs; queue++) {
- vqx = &sc->vtpci_vqx[queue];
- info = &vq_info[queue];
+ for (idx = 0; idx < nvqs; idx++) {
+ vqx = &sc->vtpci_vqx[idx];
+ info = &vq_info[idx];
- vtpci_write_config_2(sc, VIRTIO_PCI_QUEUE_SEL, queue);
-
- vq_size = vtpci_read_config_2(sc, VIRTIO_PCI_QUEUE_NUM);
- error = virtqueue_alloc(dev, queue, vq_size,
- VIRTIO_PCI_VRING_ALIGN, 0xFFFFFFFFUL, info, &vqx->vq);
- if (error)
- return (error);
+ vtpci_select_virtqueue(sc, idx);
+ size = vtpci_read_config_2(sc, VIRTIO_PCI_QUEUE_NUM);
- if (sc->vtpci_flags & VIRTIO_PCI_FLAG_MSIX) {
- error = vtpci_register_msix_vector(sc,
- VIRTIO_MSI_QUEUE_VECTOR, vqx->ires_idx);
- if (error)
- return (error);
+ error = virtqueue_alloc(dev, idx, size, VIRTIO_PCI_VRING_ALIGN,
+ 0xFFFFFFFFUL, info, &vq);
+ if (error) {
+ device_printf(dev,
+ "cannot allocate virtqueue %d: %d\n", idx, error);
+ break;
}
vtpci_write_config_4(sc, VIRTIO_PCI_QUEUE_PFN,
- virtqueue_paddr(vqx->vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT);
+ virtqueue_paddr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT);
+
+ vqx->vq = *info->vqai_vq = vq;
+ vqx->no_intr = info->vqai_intr == NULL;
- *info->vqai_vq = vqx->vq;
sc->vtpci_nvqs++;
}
- return (0);
+ return (error);
}
static int
vtpci_setup_intr(device_t dev, enum intr_type type)
{
struct vtpci_softc *sc;
- struct vtpci_intr_resource *ires;
- struct vtpci_virtqueue *vqx;
- int i, flags, error;
+ int attempt, error;
sc = device_get_softc(dev);
- flags = type | INTR_MPSAFE;
- ires = &sc->vtpci_intr_res[0];
-
- if ((sc->vtpci_flags & VIRTIO_PCI_FLAG_MSIX) == 0) {
- error = bus_setup_intr(dev, ires->irq, flags,
- vtpci_legacy_intr, NULL, sc, &ires->intrhand);
-
- return (error);
- }
- error = bus_setup_intr(dev, ires->irq, flags, vtpci_config_intr,
- NULL, sc, &ires->intrhand);
- if (error)
- return (error);
+ for (attempt = 0; attempt < 5; attempt++) {
+ /*
+ * Start with the most desirable interrupt configuration and
+ * fallback towards less desirable ones.
+ */
+ switch (attempt) {
+ case 0:
+ error = vtpci_alloc_intr_msix_pervq(sc);
+ break;
+ case 1:
+ error = vtpci_alloc_intr_msix_shared(sc);
+ break;
+ case 2:
+ error = vtpci_alloc_intr_msi(sc);
+ break;
+ case 3:
+ error = vtpci_alloc_intr_legacy(sc);
+ break;
+ default:
+ device_printf(dev,
+ "exhausted all interrupt allocation attempts\n");
+ return (ENXIO);
+ }
- if (sc->vtpci_flags & VIRTIO_PCI_FLAG_SHARED_MSIX) {
- ires = &sc->vtpci_intr_res[1];
- error = bus_setup_intr(dev, ires->irq, flags,
- vtpci_vq_shared_intr, NULL, sc, &ires->intrhand);
+ if (error == 0 && vtpci_setup_interrupts(sc, type) == 0)
+ break;
- return (error);
+ vtpci_cleanup_setup_intr_attempt(sc);
}
- /* Setup an interrupt handler for each virtqueue. */
- for (i = 0; i < sc->vtpci_nvqs; i++) {
- vqx = &sc->vtpci_vqx[i];
- if (vqx->ires_idx < 1)
- continue;
-
- ires = &sc->vtpci_intr_res[vqx->ires_idx];
- error = bus_setup_intr(dev, ires->irq, flags,
- vtpci_vq_intr, NULL, vqx->vq, &ires->intrhand);
- if (error)
- return (error);
+ if (bootverbose) {
+ if (sc->vtpci_flags & VTPCI_FLAG_LEGACY)
+ device_printf(dev, "using legacy interrupt\n");
+ else if (sc->vtpci_flags & VTPCI_FLAG_MSI)
+ device_printf(dev, "using MSI interrupt\n");
+ else if (sc->vtpci_flags & VTPCI_FLAG_SHARED_MSIX)
+ device_printf(dev, "using shared MSIX interrupts\n");
+ else
+ device_printf(dev, "using per VQ MSIX interrupts\n");
}
return (0);
@@ -554,20 +578,19 @@ static int
vtpci_reinit(device_t dev, uint64_t features)
{
struct vtpci_softc *sc;
- struct vtpci_virtqueue *vqx;
- struct virtqueue *vq;
- int queue, error;
- uint16_t vq_size;
+ int idx, error;
sc = device_get_softc(dev);
/*
- * Redrive the device initialization. This is a bit of an abuse
- * of the specification, but both VirtualBox and QEMU/KVM seem
- * to play nice. We do not allow the host device to change from
- * what was originally negotiated beyond what the guest driver
- * changed (MSIX state should not change, number of virtqueues
- * and their size remain the same, etc).
+ * Redrive the device initialization. This is a bit of an abuse of
+ * the specification, but VirtualBox, QEMU/KVM, and BHyVe seem to
+ * play nice.
+ *
+ * We do not allow the host device to change from what was originally
+ * negotiated beyond what the guest driver changed. MSIX state should
+ * not change, number of virtqueues and their size remain the same, etc.
+ * This will need to be rethought when we want to support migration.
*/
if (vtpci_get_status(dev) != VIRTIO_CONFIG_STATUS_RESET)
@@ -582,34 +605,16 @@ vtpci_reinit(device_t dev, uint64_t features)
vtpci_negotiate_features(dev, features);
- if (sc->vtpci_flags & VIRTIO_PCI_FLAG_MSIX) {
- error = vtpci_register_msix_vector(sc,
- VIRTIO_MSI_CONFIG_VECTOR, 0);
+ for (idx = 0; idx < sc->vtpci_nvqs; idx++) {
+ error = vtpci_reinit_virtqueue(sc, idx);
if (error)
return (error);
}
- for (queue = 0; queue < sc->vtpci_nvqs; queue++) {
- vqx = &sc->vtpci_vqx[queue];
- vq = vqx->vq;
-
- KASSERT(vq != NULL, ("vq %d not allocated", queue));
- vtpci_write_config_2(sc, VIRTIO_PCI_QUEUE_SEL, queue);
-
- vq_size = vtpci_read_config_2(sc, VIRTIO_PCI_QUEUE_NUM);
- error = virtqueue_reinit(vq, vq_size);
+ if (sc->vtpci_flags & VTPCI_FLAG_MSIX) {
+ error = vtpci_set_host_msix_vectors(sc);
if (error)
return (error);
-
- if (sc->vtpci_flags & VIRTIO_PCI_FLAG_MSIX) {
- error = vtpci_register_msix_vector(sc,
- VIRTIO_MSI_QUEUE_VECTOR, vqx->ires_idx);
- if (error)
- return (error);
- }
-
- vtpci_write_config_4(sc, VIRTIO_PCI_QUEUE_PFN,
- virtqueue_paddr(vqx->vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT);
}
return (0);
@@ -744,7 +749,6 @@ vtpci_probe_and_attach_child(struct vtpci_softc *sc)
vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_FAILED);
vtpci_reset(sc);
vtpci_release_child_resources(sc);
-
/* Reset status for future attempt. */
vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_ACK);
} else
@@ -752,42 +756,126 @@ vtpci_probe_and_attach_child(struct vtpci_softc *sc)
}
static int
-vtpci_alloc_interrupts(struct vtpci_softc *sc, int flags, int nvqs,
- struct vq_alloc_info *vq_info)
+vtpci_alloc_msix(struct vtpci_softc *sc, int nvectors)
+{
+ device_t dev;
+ int nmsix, cnt, required;
+
+ dev = sc->vtpci_dev;
+
+ /* Allocate an additional vector for the config changes. */
+ required = nvectors + 1;
+
+ nmsix = pci_msix_count(dev);
+ if (nmsix < required)
+ return (1);
+
+ cnt = required;
+ if (pci_alloc_msix(dev, &cnt) == 0 && cnt >= required) {
+ sc->vtpci_nintr_res = required;
+ return (0);
+ }
+
+ pci_release_msi(dev);
+
+ return (1);
+}
+
+static int
+vtpci_alloc_msi(struct vtpci_softc *sc)
+{
+ device_t dev;
+ int nmsi, cnt, required;
+
+ dev = sc->vtpci_dev;
+ required = 1;
+
+ nmsi = pci_msi_count(dev);
+ if (nmsi < required)
+ return (1);
+
+ cnt = required;
+ if (pci_alloc_msi(dev, &cnt) == 0 && cnt >= required) {
+ sc->vtpci_nintr_res = required;
+ return (0);
+ }
+
+ pci_release_msi(dev);
+
+ return (1);
+}
+
+static int
+vtpci_alloc_intr_msix_pervq(struct vtpci_softc *sc)
{
int i, nvectors, error;
- /*
- * Only allocate a vector for virtqueues that are actually
- * expecting an interrupt.
- */
- for (nvectors = 0, i = 0; i < nvqs; i++)
- if (vq_info[i].vqai_intr != NULL)
+ if (vtpci_disable_msix != 0 ||
+ sc->vtpci_flags & VTPCI_FLAG_NO_MSIX)
+ return (ENOTSUP);
+
+ for (nvectors = 0, i = 0; i < sc->vtpci_nvqs; i++) {
+ if (sc->vtpci_vqx[i].no_intr == 0)
nvectors++;
+ }
+
+ error = vtpci_alloc_msix(sc, nvectors);
+ if (error)
+ return (error);
+
+ sc->vtpci_flags |= VTPCI_FLAG_MSIX;
+
+ return (0);
+}
+
+static int
+vtpci_alloc_intr_msix_shared(struct vtpci_softc *sc)
+{
+ int error;
if (vtpci_disable_msix != 0 ||
- sc->vtpci_flags & VIRTIO_PCI_FLAG_NO_MSIX ||
- flags & VIRTIO_ALLOC_VQS_DISABLE_MSIX ||
- vtpci_alloc_msix(sc, nvectors) != 0) {
- /*
- * Use MSI interrupts if available. Otherwise, we fallback
- * to legacy interrupts.
- */
- if ((sc->vtpci_flags & VIRTIO_PCI_FLAG_NO_MSI) == 0 &&
- vtpci_alloc_msi(sc) == 0)
- sc->vtpci_flags |= VIRTIO_PCI_FLAG_MSI;
+ sc->vtpci_flags & VTPCI_FLAG_NO_MSIX)
+ return (ENOTSUP);
- sc->vtpci_nintr_res = 1;
- }
+ error = vtpci_alloc_msix(sc, 1);
+ if (error)
+ return (error);
- error = vtpci_alloc_intr_resources(sc, nvqs, vq_info);
+ sc->vtpci_flags |= VTPCI_FLAG_MSIX | VTPCI_FLAG_SHARED_MSIX;
- return (error);
+ return (0);
}
static int
-vtpci_alloc_intr_resources(struct vtpci_softc *sc, int nvqs,
- struct vq_alloc_info *vq_info)
+vtpci_alloc_intr_msi(struct vtpci_softc *sc)
+{
+ int error;
+
+ /* Only BHyVe supports MSI. */
+ if (sc->vtpci_flags & VTPCI_FLAG_NO_MSI)
+ return (ENOTSUP);
+
+ error = vtpci_alloc_msi(sc);
+ if (error)
+ return (error);
+
+ sc->vtpci_flags |= VTPCI_FLAG_MSI;
+
+ return (0);
+}
+
+static int
+vtpci_alloc_intr_legacy(struct vtpci_softc *sc)
+{
+
+ sc->vtpci_flags |= VTPCI_FLAG_LEGACY;
+ sc->vtpci_nintr_res = 1;
+
+ return (0);
+}
+
+static int
+vtpci_alloc_intr_resources(struct vtpci_softc *sc)
{
device_t dev;
struct resource *irq;
@@ -795,14 +883,14 @@ vtpci_alloc_intr_resources(struct vtpci_softc *sc, int nvqs,
int i, rid, flags, res_idx;
dev = sc->vtpci_dev;
- flags = RF_ACTIVE;
- if ((sc->vtpci_flags &
- (VIRTIO_PCI_FLAG_MSI | VIRTIO_PCI_FLAG_MSIX)) == 0) {
+ if (sc->vtpci_flags & VTPCI_FLAG_LEGACY) {
rid = 0;
- flags |= RF_SHAREABLE;
- } else
+ flags = RF_ACTIVE | RF_SHAREABLE;
+ } else {
rid = 1;
+ flags = RF_ACTIVE;
+ }
for (i = 0; i < sc->vtpci_nintr_res; i++) {
irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, flags);
@@ -814,16 +902,16 @@ vtpci_alloc_intr_resources(struct vtpci_softc *sc, int nvqs,
}
/*
- * Map the virtqueue into the correct index in vq_intr_res[]. Note the
- * first index is reserved for configuration changes notifications.
+ * Map the virtqueue into the correct index in vq_intr_res[]. The
+ * first index is reserved for configuration changed notifications.
*/
- for (i = 0, res_idx = 1; i < nvqs; i++) {
+ for (i = 0, res_idx = 1; i < sc->vtpci_nvqs; i++) {
vqx = &sc->vtpci_vqx[i];
- if (sc->vtpci_flags & VIRTIO_PCI_FLAG_MSIX) {
- if (vq_info[i].vqai_intr == NULL)
+ if (sc->vtpci_flags & VTPCI_FLAG_MSIX) {
+ if (vqx->no_intr != 0)
vqx->ires_idx = -1;
- else if (sc->vtpci_flags & VIRTIO_PCI_FLAG_SHARED_MSIX)
+ else if (sc->vtpci_flags & VTPCI_FLAG_SHARED_MSIX)
vqx->ires_idx = res_idx;
else
vqx->ires_idx = res_idx++;
@@ -835,110 +923,180 @@ vtpci_alloc_intr_resources(struct vtpci_softc *sc, int nvqs,
}
static int
-vtpci_alloc_msi(struct vtpci_softc *sc)
+vtpci_setup_legacy_interrupt(struct vtpci_softc *sc, enum intr_type type)
{
device_t dev;
- int nmsi, cnt;
+ struct vtpci_intr_resource *ires;
+ int error;
dev = sc->vtpci_dev;
- nmsi = pci_msi_count(dev);
-
- if (nmsi < 1)
- return (1);
- cnt = 1;
- if (pci_alloc_msi(dev, &cnt) == 0 && cnt == 1)
- return (0);
+ ires = &sc->vtpci_intr_res[0];
+ error = bus_setup_intr(dev, ires->irq, type, vtpci_legacy_intr, NULL,
+ sc, &ires->intrhand);
- return (1);
+ return (error);
}
static int
-vtpci_alloc_msix(struct vtpci_softc *sc, int nvectors)
+vtpci_setup_msix_interrupts(struct vtpci_softc *sc, enum intr_type type)
{
device_t dev;
- int nmsix, cnt, required;
+ struct vtpci_intr_resource *ires;
+ struct vtpci_virtqueue *vqx;
+ int i, error;
dev = sc->vtpci_dev;
- nmsix = pci_msix_count(dev);
- if (nmsix < 1)
- return (1);
+ /*
+ * The first resource is used for configuration changed interrupts.
+ */
+ ires = &sc->vtpci_intr_res[0];
+ error = bus_setup_intr(dev, ires->irq, type, vtpci_config_intr,
+ NULL, sc, &ires->intrhand);
+ if (error)
+ return (error);
- /* An additional vector is needed for the config changes. */
- required = nvectors + 1;
- if (nmsix >= required) {
- cnt = required;
- if (pci_alloc_msix(dev, &cnt) == 0 && cnt >= required)
- goto out;
+ if (sc->vtpci_flags & VTPCI_FLAG_SHARED_MSIX) {
+ ires = &sc->vtpci_intr_res[1];
- pci_release_msi(dev);
+ error = bus_setup_intr(dev, ires->irq, type,
+ vtpci_vq_shared_intr, NULL, sc, &ires->intrhand);
+ if (error)
+ return (error);
+ } else {
+ /*
+ * Each remaining resource is assigned to a specific virtqueue.
+ */
+ for (i = 0; i < sc->vtpci_nvqs; i++) {
+ vqx = &sc->vtpci_vqx[i];
+ if (vqx->ires_idx < 1)
+ continue;
+
+ ires = &sc->vtpci_intr_res[vqx->ires_idx];
+ error = bus_setup_intr(dev, ires->irq, type,
+ vtpci_vq_intr, NULL, vqx->vq, &ires->intrhand);
+ if (error)
+ return (error);
+ }
}
- /* Attempt shared MSIX configuration. */
- required = 2;
- if (nmsix >= required) {
- cnt = required;
- if (pci_alloc_msix(dev, &cnt) == 0 && cnt >= required) {
- sc->vtpci_flags |= VIRTIO_PCI_FLAG_SHARED_MSIX;
- goto out;
- }
+ error = vtpci_set_host_msix_vectors(sc);
+ if (error)
+ return (error);
- pci_release_msi(dev);
- }
+ return (0);
+}
- return (1);
+static int
+vtpci_setup_interrupts(struct vtpci_softc *sc, enum intr_type type)
+{
+ int error;
-out:
- sc->vtpci_nintr_res = required;
- sc->vtpci_flags |= VIRTIO_PCI_FLAG_MSIX;
+ type |= INTR_MPSAFE;
+ KASSERT(sc->vtpci_flags & VTPCI_FLAG_ITYPE_MASK,
+ ("no interrupt type selected: %#x", sc->vtpci_flags));
- if (bootverbose) {
- if (sc->vtpci_flags & VIRTIO_PCI_FLAG_SHARED_MSIX)
- device_printf(dev, "using shared virtqueue MSIX\n");
- else
- device_printf(dev, "using per virtqueue MSIX\n");
- }
+ error = vtpci_alloc_intr_resources(sc);
+ if (error)
+ return (error);
- return (0);
+ if (sc->vtpci_flags & VTPCI_FLAG_LEGACY)
+ error = vtpci_setup_legacy_interrupt(sc, type);
+ else if (sc->vtpci_flags & VTPCI_FLAG_MSI)
+ error = vtpci_setup_msi_interrupt(sc, type);
+ else
+ error = vtpci_setup_msix_interrupts(sc, type);
+
+ return (error);
}
static int
vtpci_register_msix_vector(struct vtpci_softc *sc, int offset, int res_idx)
{
device_t dev;
- uint16_t vector;
+ uint16_t vector, rdvector;
dev = sc->vtpci_dev;
- if (offset != VIRTIO_MSI_CONFIG_VECTOR &&
- offset != VIRTIO_MSI_QUEUE_VECTOR)
- return (EINVAL);
-
if (res_idx != -1) {
- /* Map from rid to host vector. */
+ /* Map from guest rid to host vector. */
vector = sc->vtpci_intr_res[res_idx].rid - 1;
} else
vector = VIRTIO_MSI_NO_VECTOR;
- /* The first resource is special; make sure it is used correctly. */
+ /*
+ * Assert the first resource is always used for the configuration
+ * changed interrupts.
+ */
if (res_idx == 0) {
- KASSERT(vector == 0, ("unexpected config vector"));
- KASSERT(offset == VIRTIO_MSI_CONFIG_VECTOR,
- ("unexpected config offset"));
- }
+ KASSERT(vector == 0 && offset == VIRTIO_MSI_CONFIG_VECTOR,
+ ("bad first res use vector:%d offset:%d", vector, offset));
+ } else
+ KASSERT(offset == VIRTIO_MSI_QUEUE_VECTOR, ("bad offset"));
vtpci_write_config_2(sc, offset, vector);
- if (vtpci_read_config_2(sc, offset) != vector) {
- device_printf(dev, "insufficient host resources for "
- "MSIX interrupts\n");
+ /* Read vector to determine if the host had sufficient resources. */
+ rdvector = vtpci_read_config_2(sc, offset);
+ if (rdvector != vector) {
+ device_printf(dev,
+ "insufficient host resources for MSIX interrupts\n");
return (ENODEV);
}
return (0);
}
+static int
+vtpci_set_host_msix_vectors(struct vtpci_softc *sc)
+{
+ struct vtpci_virtqueue *vqx;
+ int idx, error;
+
+ error = vtpci_register_msix_vector(sc, VIRTIO_MSI_CONFIG_VECTOR, 0);
+ if (error)
+ return (error);
+
+ for (idx = 0; idx < sc->vtpci_nvqs; idx++) {
+ vqx = &sc->vtpci_vqx[idx];
+
+ vtpci_select_virtqueue(sc, idx);
+ error = vtpci_register_msix_vector(sc, VIRTIO_MSI_QUEUE_VECTOR,
+ vqx->ires_idx);
+ if (error)
+ return (error);
+ }
+
+ return (0);
+}
+
+static int
+vtpci_reinit_virtqueue(struct vtpci_softc *sc, int idx)
+{
+ struct vtpci_virtqueue *vqx;
+ struct virtqueue *vq;
+ int error;
+ uint16_t size;
+
+ vqx = &sc->vtpci_vqx[idx];
+ vq = vqx->vq;
+
+ KASSERT(vq != NULL, ("vq %d not allocated", idx));
+
+ vtpci_select_virtqueue(sc, idx);
+ size = vtpci_read_config_2(sc, VIRTIO_PCI_QUEUE_NUM);
+
+ error = virtqueue_reinit(vq, size);
+ if (error)
+ return (error);
+
+ vtpci_write_config_4(sc, VIRTIO_PCI_QUEUE_PFN,
+ virtqueue_paddr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT);
+
+ return (0);
+}
+
static void
vtpci_free_interrupts(struct vtpci_softc *sc)
{
@@ -947,15 +1105,8 @@ vtpci_free_interrupts(struct vtpci_softc *sc)
int i;
dev = sc->vtpci_dev;
- sc->vtpci_nintr_res = 0;
-
- if (sc->vtpci_flags & (VIRTIO_PCI_FLAG_MSI | VIRTIO_PCI_FLAG_MSIX)) {
- pci_release_msi(dev);
- sc->vtpci_flags &= ~(VIRTIO_PCI_FLAG_MSI |
- VIRTIO_PCI_FLAG_MSIX | VIRTIO_PCI_FLAG_SHARED_MSIX);
- }
- for (i = 0; i < 1 + VIRTIO_MAX_VIRTQUEUES; i++) {
+ for (i = 0; i < sc->vtpci_nintr_res; i++) {
ires = &sc->vtpci_intr_res[i];
if (ires->intrhand != NULL) {
@@ -971,6 +1122,12 @@ vtpci_free_interrupts(struct vtpci_softc *sc)
ires->rid = -1;
}
+
+ if (sc->vtpci_flags & (VTPCI_FLAG_MSI | VTPCI_FLAG_MSIX))
+ pci_release_msi(dev);
+
+ sc->vtpci_nintr_res = 0;
+ sc->vtpci_flags &= ~VTPCI_FLAG_ITYPE_MASK;
}
static void
@@ -979,16 +1136,33 @@ vtpci_free_virtqueues(struct vtpci_softc *sc)
struct vtpci_virtqueue *vqx;
int i;
+ for (i = 0; i < sc->vtpci_nvqs; i++) {
+ vqx = &sc->vtpci_vqx[i];
+
+ virtqueue_free(vqx->vq);
+ vqx->vq = NULL;
+ }
+
sc->vtpci_nvqs = 0;
+}
- for (i = 0; i < VIRTIO_MAX_VIRTQUEUES; i++) {
- vqx = &sc->vtpci_vqx[i];
+static void
+vtpci_cleanup_setup_intr_attempt(struct vtpci_softc *sc)
+{
+ int idx;
- if (vqx->vq != NULL) {
- virtqueue_free(vqx->vq);
- vqx->vq = NULL;
+ if (sc->vtpci_flags & VTPCI_FLAG_MSIX) {
+ vtpci_write_config_2(sc, VIRTIO_MSI_CONFIG_VECTOR,
+ VIRTIO_MSI_NO_VECTOR);
+
+ for (idx = 0; idx < sc->vtpci_nvqs; idx++) {
+ vtpci_select_virtqueue(sc, idx);
+ vtpci_write_config_2(sc, VIRTIO_MSI_QUEUE_VECTOR,
+ VIRTIO_MSI_NO_VECTOR);
}
}
+
+ vtpci_free_interrupts(sc);
}
static void
@@ -1010,6 +1184,13 @@ vtpci_reset(struct vtpci_softc *sc)
vtpci_set_status(sc->vtpci_dev, VIRTIO_CONFIG_STATUS_RESET);
}
+static void
+vtpci_select_virtqueue(struct vtpci_softc *sc, int idx)
+{
+
+ vtpci_write_config_2(sc, VIRTIO_PCI_QUEUE_SEL, idx);
+}
+
static int
vtpci_legacy_intr(void *xsc)
{
diff --git a/sys/dev/virtio/pci/virtio_pci.h b/sys/dev/virtio/pci/virtio_pci.h
index d8daa31..485cf4f 100644
--- a/sys/dev/virtio/pci/virtio_pci.h
+++ b/sys/dev/virtio/pci/virtio_pci.h
@@ -73,7 +73,7 @@
* configuration space.
*/
#define VIRTIO_PCI_CONFIG(sc) \
- (((sc)->vtpci_flags & VIRTIO_PCI_FLAG_MSIX) ? 24 : 20)
+ (((sc)->vtpci_flags & VTPCI_FLAG_MSIX) ? 24 : 20)
/*
* How many bits to shift physical queue address written to QUEUE_PFN.
diff --git a/sys/dev/virtio/virtio.c b/sys/dev/virtio/virtio.c
index e385575..1cac3c7 100644
--- a/sys/dev/virtio/virtio.c
+++ b/sys/dev/virtio/virtio.c
@@ -86,28 +86,6 @@ virtio_device_name(uint16_t devid)
return (NULL);
}
-int
-virtio_get_device_type(device_t dev)
-{
- uintptr_t devtype;
-
- devtype = -1;
-
- BUS_READ_IVAR(device_get_parent(dev), dev,
- VIRTIO_IVAR_DEVTYPE, &devtype);
-
- return ((int) devtype);
-}
-
-void
-virtio_set_feature_desc(device_t dev,
- struct virtio_feature_desc *feature_desc)
-{
-
- BUS_WRITE_IVAR(device_get_parent(dev), dev,
- VIRTIO_IVAR_FEATURE_DESC, (uintptr_t) feature_desc);
-}
-
void
virtio_describe(device_t dev, const char *msg,
uint64_t features, struct virtio_feature_desc *feature_desc)
@@ -184,6 +162,21 @@ virtio_feature_name(uint64_t val, struct virtio_feature_desc *feature_desc)
* VirtIO bus method wrappers.
*/
+void
+virtio_read_ivar(device_t dev, int ivar, uintptr_t *val)
+{
+
+ *val = -1;
+ BUS_READ_IVAR(device_get_parent(dev), dev, ivar, val);
+}
+
+void
+virtio_write_ivar(device_t dev, int ivar, uintptr_t val)
+{
+
+ BUS_WRITE_IVAR(device_get_parent(dev), dev, ivar, val);
+}
+
uint64_t
virtio_negotiate_features(device_t dev, uint64_t child_features)
{
diff --git a/sys/dev/virtio/virtio.h b/sys/dev/virtio/virtio.h
index e0ecfb9..8c22b12 100644
--- a/sys/dev/virtio/virtio.h
+++ b/sys/dev/virtio/virtio.h
@@ -91,6 +91,10 @@ struct vq_alloc_info;
*/
#define VIRTIO_IVAR_DEVTYPE 1
#define VIRTIO_IVAR_FEATURE_DESC 2
+#define VIRTIO_IVAR_VENDOR 3
+#define VIRTIO_IVAR_DEVICE 4
+#define VIRTIO_IVAR_SUBVENDOR 5
+#define VIRTIO_IVAR_SUBDEVICE 6
struct virtio_feature_desc {
uint64_t vfd_val;
@@ -98,15 +102,14 @@ struct virtio_feature_desc {
};
const char *virtio_device_name(uint16_t devid);
-int virtio_get_device_type(device_t dev);
-void virtio_set_feature_desc(device_t dev,
- struct virtio_feature_desc *feature_desc);
void virtio_describe(device_t dev, const char *msg,
uint64_t features, struct virtio_feature_desc *feature_desc);
/*
* VirtIO Bus Methods.
*/
+void virtio_read_ivar(device_t dev, int ivar, uintptr_t *val);
+void virtio_write_ivar(device_t dev, int ivar, uintptr_t val);
uint64_t virtio_negotiate_features(device_t dev, uint64_t child_features);
int virtio_alloc_virtqueues(device_t dev, int flags, int nvqs,
struct vq_alloc_info *info);
@@ -148,4 +151,28 @@ VIRTIO_RDWR_DEVICE_CONFIG(1, uint8_t);
VIRTIO_RDWR_DEVICE_CONFIG(2, uint16_t);
VIRTIO_RDWR_DEVICE_CONFIG(4, uint32_t);
+#define VIRTIO_READ_IVAR(name, ivar) \
+static inline int \
+__CONCAT(virtio_get_,name)(device_t dev) \
+{ \
+ uintptr_t val; \
+ virtio_read_ivar(dev, ivar, &val); \
+ return ((int) val); \
+}
+
+VIRTIO_READ_IVAR(device_type, VIRTIO_IVAR_DEVTYPE);
+VIRTIO_READ_IVAR(vendor, VIRTIO_IVAR_VENDOR);
+VIRTIO_READ_IVAR(device, VIRTIO_IVAR_DEVICE);
+VIRTIO_READ_IVAR(subvendor, VIRTIO_IVAR_SUBVENDOR);
+VIRTIO_READ_IVAR(subdevice, VIRTIO_IVAR_SUBDEVICE);
+
+#define VIRTIO_WRITE_IVAR(name, ivar) \
+static inline void \
+__CONCAT(virtio_set_,name)(device_t dev, void *val) \
+{ \
+ virtio_write_ivar(dev, ivar, (uintptr_t) val); \
+}
+
+VIRTIO_WRITE_IVAR(feature_desc, VIRTIO_IVAR_FEATURE_DESC);
+
#endif /* _VIRTIO_H_ */
diff --git a/sys/dev/virtio/virtio_ring.h b/sys/dev/virtio/virtio_ring.h
index 0d00013..8e902ab 100644
--- a/sys/dev/virtio/virtio_ring.h
+++ b/sys/dev/virtio/virtio_ring.h
@@ -120,8 +120,8 @@ struct vring {
* We publish the used event index at the end of the available ring, and vice
* versa. They are at the end for backwards compatibility.
*/
-#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
-#define vring_avail_event(vr) (*(uint16_t *)&(vr)->used->ring[(vr)->num])
+#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
+#define vring_avail_event(vr) (*(uint16_t *)&(vr)->used->ring[(vr)->num])
static inline int
vring_size(unsigned int num, unsigned long align)
@@ -129,10 +129,11 @@ vring_size(unsigned int num, unsigned long align)
int size;
size = num * sizeof(struct vring_desc);
- size += sizeof(struct vring_avail) + (num * sizeof(uint16_t));
+ size += sizeof(struct vring_avail) + (num * sizeof(uint16_t)) +
+ sizeof(uint16_t);
size = (size + align - 1) & ~(align - 1);
size += sizeof(struct vring_used) +
- (num * sizeof(struct vring_used_elem));
+ (num * sizeof(struct vring_used_elem)) + sizeof(uint16_t);
return (size);
}
diff --git a/sys/dev/virtio/virtqueue.c b/sys/dev/virtio/virtqueue.c
index 31f47d0..83d39ba 100644
--- a/sys/dev/virtio/virtqueue.c
+++ b/sys/dev/virtio/virtqueue.c
@@ -127,6 +127,7 @@ static uint16_t vq_ring_enqueue_segments(struct virtqueue *,
static int vq_ring_use_indirect(struct virtqueue *, int);
static void vq_ring_enqueue_indirect(struct virtqueue *, void *,
struct sglist *, int, int);
+static int vq_ring_enable_interrupt(struct virtqueue *, uint16_t);
static int vq_ring_must_notify_host(struct virtqueue *);
static void vq_ring_notify_host(struct virtqueue *);
static void vq_ring_free_chain(struct virtqueue *, uint16_t);
@@ -311,7 +312,7 @@ virtqueue_reinit(struct virtqueue *vq, uint16_t size)
/* Warn if the virtqueue was not properly cleaned up. */
if (vq->vq_free_cnt != vq->vq_nentries) {
device_printf(vq->vq_dev,
- "%s: warning, '%s' virtqueue not empty, "
+ "%s: warning '%s' virtqueue not empty, "
"leaking %d entries\n", __func__, vq->vq_name,
vq->vq_nentries - vq->vq_free_cnt);
}
@@ -390,6 +391,7 @@ virtqueue_full(struct virtqueue *vq)
void
virtqueue_notify(struct virtqueue *vq)
{
+
/* Ensure updated avail->idx is visible to host. */
mb();
@@ -428,58 +430,22 @@ int
virtqueue_enable_intr(struct virtqueue *vq)
{
- /*
- * Enable interrupts, making sure we get the latest
- * index of what's already been consumed.
- */
- vq->vq_ring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
- if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX)
- vring_used_event(&vq->vq_ring) = vq->vq_used_cons_idx;
- else
- vq->vq_ring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
-
- mb();
-
- /*
- * Additional items may have been consumed in the time between
- * since we last checked and enabled interrupts above. Let our
- * caller know so it processes the new entries.
- */
- if (vq->vq_used_cons_idx != vq->vq_ring.used->idx)
- return (1);
-
- return (0);
+ return (vq_ring_enable_interrupt(vq, 0));
}
int
virtqueue_postpone_intr(struct virtqueue *vq)
{
- uint16_t ndesc;
+ uint16_t ndesc, avail_idx;
/*
- * Postpone until at least half of the available descriptors
- * have been consumed.
- *
- * XXX Adaptive factor? (Linux uses 3/4)
+ * Request the next interrupt be postponed until at least half
+ * of the available descriptors have been consumed.
*/
- ndesc = (uint16_t)(vq->vq_ring.avail->idx - vq->vq_used_cons_idx) / 2;
+ avail_idx = vq->vq_ring.avail->idx;
+ ndesc = (uint16_t)(avail_idx - vq->vq_used_cons_idx) / 2;
- if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX)
- vring_used_event(&vq->vq_ring) = vq->vq_used_cons_idx + ndesc;
- else
- vq->vq_ring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
-
- mb();
-
- /*
- * Enough items may have already been consumed to meet our
- * threshold since we last checked. Let our caller know so
- * it processes the new entries.
- */
- if (virtqueue_nused(vq) > ndesc)
- return (1);
-
- return (0);
+ return (vq_ring_enable_interrupt(vq, ndesc));
}
void
@@ -752,6 +718,32 @@ vq_ring_enqueue_indirect(struct virtqueue *vq, void *cookie,
}
static int
+vq_ring_enable_interrupt(struct virtqueue *vq, uint16_t ndesc)
+{
+
+ /*
+ * Enable interrupts, making sure we get the latest index of
+ * what's already been consumed.
+ */
+ if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX)
+ vring_used_event(&vq->vq_ring) = vq->vq_used_cons_idx + ndesc;
+ else
+ vq->vq_ring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
+
+ mb();
+
+ /*
+ * Enough items may have already been consumed to meet our threshold
+ * since we last checked. Let our caller know so it processes the new
+ * entries.
+ */
+ if (virtqueue_nused(vq) > ndesc)
+ return (1);
+
+ return (0);
+}
+
+static int
vq_ring_must_notify_host(struct virtqueue *vq)
{
uint16_t new_idx, prev_idx, event_idx;
@@ -788,8 +780,8 @@ vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
VQ_RING_ASSERT_CHAIN_TERM(vq);
vq->vq_free_cnt += dxp->ndescs;
- dxp->ndescs--;
+#ifdef INVARIANTS
if ((dp->flags & VRING_DESC_F_INDIRECT) == 0) {
while (dp->flags & VRING_DESC_F_NEXT) {
VQ_RING_ASSERT_VALID_IDX(vq, dp->next);
@@ -797,7 +789,10 @@ vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
dxp->ndescs--;
}
}
- VQASSERT(vq, dxp->ndescs == 0, "failed to free entire desc chain");
+ VQASSERT(vq, dxp->ndescs == 1,
+ "failed to free entire desc chain, remaining: %d", dxp->ndescs);
+#endif
+ dxp->ndescs = 0;
/*
* We must append the existing free chain, if any, to the end of
diff --git a/sys/dev/virtio/virtqueue.h b/sys/dev/virtio/virtqueue.h
index a84d7a1..0296b8c 100644
--- a/sys/dev/virtio/virtqueue.h
+++ b/sys/dev/virtio/virtqueue.h
@@ -35,11 +35,7 @@ struct sglist;
/* Support for indirect buffer descriptors. */
#define VIRTIO_RING_F_INDIRECT_DESC (1 << 28)
-/* The guest publishes the used index for which it expects an interrupt
- * at the end of the avail ring. Host should ignore the avail->flags field.
- * The host publishes the avail index for which it expects a kick
- * at the end of the used ring. Guest should ignore the used->flags field.
- */
+/* Support to suppress interrupt until specific index is reached. */
#define VIRTIO_RING_F_EVENT_IDX (1 << 29)
/* Device callback for a virtqueue interrupt. */
diff --git a/sys/fs/ntfs/ntfs_subr.c b/sys/fs/ntfs/ntfs_subr.c
index 9d81f71..f3ac646 100644
--- a/sys/fs/ntfs/ntfs_subr.c
+++ b/sys/fs/ntfs/ntfs_subr.c
@@ -1353,174 +1353,6 @@ ntfs_filesize(
}
/*
- * This is one of write routine.
- */
-int
-ntfs_writeattr_plain(
- struct ntfsmount * ntmp,
- struct ntnode * ip,
- u_int32_t attrnum,
- char *attrname,
- off_t roff,
- size_t rsize,
- void *rdata,
- size_t * initp,
- struct uio *uio)
-{
- size_t init;
- int error = 0;
- off_t off = roff, left = rsize, towrite;
- caddr_t data = rdata;
- struct ntvattr *vap;
- *initp = 0;
-
- while (left) {
- error = ntfs_ntvattrget(ntmp, ip, attrnum, attrname,
- ntfs_btocn(off), &vap);
- if (error)
- return (error);
- towrite = MIN(left, ntfs_cntob(vap->va_vcnend + 1) - off);
- ddprintf(("ntfs_writeattr_plain: o: %d, s: %d (%d - %d)\n",
- (u_int32_t) off, (u_int32_t) towrite,
- (u_int32_t) vap->va_vcnstart,
- (u_int32_t) vap->va_vcnend));
- error = ntfs_writentvattr_plain(ntmp, ip, vap,
- off - ntfs_cntob(vap->va_vcnstart),
- towrite, data, &init, uio);
- if (error) {
- printf("ntfs_writeattr_plain: " \
- "ntfs_writentvattr_plain failed: o: %d, s: %d\n",
- (u_int32_t) off, (u_int32_t) towrite);
- printf("ntfs_writeattr_plain: attrib: %d - %d\n",
- (u_int32_t) vap->va_vcnstart,
- (u_int32_t) vap->va_vcnend);
- ntfs_ntvattrrele(vap);
- break;
- }
- ntfs_ntvattrrele(vap);
- left -= towrite;
- off += towrite;
- data = data + towrite;
- *initp += init;
- }
-
- return (error);
-}
-
-/*
- * This is one of write routine.
- *
- * ntnode should be locked.
- */
-int
-ntfs_writentvattr_plain(
- struct ntfsmount * ntmp,
- struct ntnode * ip,
- struct ntvattr * vap,
- off_t roff,
- size_t rsize,
- void *rdata,
- size_t * initp,
- struct uio *uio)
-{
- int error = 0;
- off_t off;
- int cnt;
- cn_t ccn, ccl, cn, left, cl;
- caddr_t data = rdata;
- struct buf *bp;
- size_t tocopy;
-
- *initp = 0;
-
- if ((vap->va_flag & NTFS_AF_INRUN) == 0) {
- printf("ntfs_writevattr_plain: CAN'T WRITE RES. ATTRIBUTE\n");
- return ENOTTY;
- }
-
- ddprintf(("ntfs_writentvattr_plain: data in run: %ld chains\n",
- vap->va_vruncnt));
-
- off = roff;
- left = rsize;
- ccl = 0;
- ccn = 0;
- cnt = 0;
- for (; left && (cnt < vap->va_vruncnt); cnt++) {
- ccn = vap->va_vruncn[cnt];
- ccl = vap->va_vruncl[cnt];
-
- ddprintf(("ntfs_writentvattr_plain: " \
- "left %d, cn: 0x%x, cl: %d, off: %d\n", \
- (u_int32_t) left, (u_int32_t) ccn, \
- (u_int32_t) ccl, (u_int32_t) off));
-
- if (ntfs_cntob(ccl) < off) {
- off -= ntfs_cntob(ccl);
- cnt++;
- continue;
- }
- if (!ccn && ip->i_number != NTFS_BOOTINO)
- continue; /* XXX */
-
- ccl -= ntfs_btocn(off);
- cn = ccn + ntfs_btocn(off);
- off = ntfs_btocnoff(off);
-
- while (left && ccl) {
- /*
- * Always read and write single clusters at a time -
- * we need to avoid requesting differently-sized
- * blocks at the same disk offsets to avoid
- * confusing the buffer cache.
- */
- tocopy = MIN(left, ntfs_cntob(1) - off);
- cl = ntfs_btocl(tocopy + off);
- KASSERT(cl == 1 && tocopy <= ntfs_cntob(1),
- ("single cluster limit mistake"));
- ddprintf(("ntfs_writentvattr_plain: write: " \
- "cn: 0x%x cl: %d, off: %d len: %d, left: %d\n",
- (u_int32_t) cn, (u_int32_t) cl,
- (u_int32_t) off, (u_int32_t) tocopy,
- (u_int32_t) left));
- if ((off == 0) && (tocopy == ntfs_cntob(cl)))
- {
- bp = getblk(ntmp->ntm_devvp, ntfs_cntobn(cn)
- * ntmp->ntm_multiplier,
- ntfs_cntob(cl), 0, 0, 0);
- clrbuf(bp);
- } else {
- error = bread(ntmp->ntm_devvp, ntfs_cntobn(cn)
- * ntmp->ntm_multiplier,
- ntfs_cntob(cl), NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
- }
- if (uio)
- uiomove(bp->b_data + off, tocopy, uio);
- else
- memcpy(bp->b_data + off, data, tocopy);
- bawrite(bp);
- data = data + tocopy;
- *initp += tocopy;
- off = 0;
- left -= tocopy;
- cn += cl;
- ccl -= cl;
- }
- }
-
- if (left) {
- printf("ntfs_writentvattr_plain: POSSIBLE RUN ERROR\n");
- error = EINVAL;
- }
-
- return (error);
-}
-
-/*
* This is one of read routines.
*
* ntnode should be locked.
diff --git a/sys/fs/ntfs/ntfs_subr.h b/sys/fs/ntfs/ntfs_subr.h
index ce46986..9ccbb42 100644
--- a/sys/fs/ntfs/ntfs_subr.h
+++ b/sys/fs/ntfs/ntfs_subr.h
@@ -99,8 +99,6 @@ void ntfs_ntref(struct ntnode *);
void ntfs_ntrele(struct ntnode *);
void ntfs_ntput(struct ntnode *);
int ntfs_loadntnode( struct ntfsmount *, struct ntnode * );
-int ntfs_writentvattr_plain(struct ntfsmount *, struct ntnode *, struct ntvattr *, off_t, size_t, void *, size_t *, struct uio *);
-int ntfs_writeattr_plain(struct ntfsmount *, struct ntnode *, u_int32_t, char *, off_t, size_t, void *, size_t *, struct uio *);
void ntfs_toupper_init(void);
void ntfs_toupper_destroy(void);
int ntfs_toupper_use(struct mount *, struct ntfsmount *);
diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c
index 20061cc..d664f2c 100644
--- a/sys/fs/ntfs/ntfs_vfsops.c
+++ b/sys/fs/ntfs/ntfs_vfsops.c
@@ -152,7 +152,6 @@ static int
ntfs_mount(struct mount *mp)
{
int err = 0, error;
- accmode_t accmode;
struct vnode *devvp;
struct nameidata ndp;
struct thread *td;
@@ -162,6 +161,11 @@ ntfs_mount(struct mount *mp)
if (vfs_filteropt(mp->mnt_optnew, ntfs_opts))
return (EINVAL);
+ /* Force mount as read-only. */
+ MNT_ILOCK(mp);
+ mp->mnt_flag |= MNT_RDONLY;
+ MNT_IUNLOCK(mp);
+
from = vfs_getopts(mp->mnt_optnew, "from", &error);
if (error)
return (error);
@@ -173,11 +177,10 @@ ntfs_mount(struct mount *mp)
if (mp->mnt_flag & MNT_UPDATE) {
if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) {
/* Process export requests in vfs_mount.c */
- goto success;
+ return (0);
} else {
printf("ntfs_mount(): MNT_UPDATE not supported\n");
- err = EINVAL;
- goto error_1;
+ return (EINVAL);
}
}
@@ -187,10 +190,8 @@ ntfs_mount(struct mount *mp)
*/
NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, from, td);
err = namei(&ndp);
- if (err) {
- /* can't get devvp!*/
- goto error_1;
- }
+ if (err)
+ return (err);
NDFREE(&ndp, NDF_ONLY_PNBUF);
devvp = ndp.ni_vp;
@@ -203,10 +204,7 @@ ntfs_mount(struct mount *mp)
* If mount by non-root, then verify that user has necessary
* permissions on the device.
*/
- accmode = VREAD;
- if ((mp->mnt_flag & MNT_RDONLY) == 0)
- accmode |= VWRITE;
- err = VOP_ACCESS(devvp, accmode, td->td_ucred, td);
+ err = VOP_ACCESS(devvp, VREAD, td->td_ucred, td);
if (err)
err = priv_check(td, PRIV_VFS_MOUNT_PERM);
if (err) {
@@ -214,52 +212,23 @@ ntfs_mount(struct mount *mp)
return (err);
}
- if (mp->mnt_flag & MNT_UPDATE) {
-#if 0
- /*
- ********************
- * UPDATE
- ********************
- */
-
- if (devvp != ntmp->um_devvp)
- err = EINVAL; /* needs translation */
- vput(devvp);
- if (err)
- return (err);
-#endif
- } else {
- /*
- ********************
- * NEW MOUNT
- ********************
- */
-
- /*
- * Since this is a new mount, we want the names for
- * the device and the mount point copied in. If an
- * error occurs, the mountpoint is discarded by the
- * upper level code. Note that vfs_mount() handles
- * copying the mountpoint f_mntonname for us, so we
- * don't have to do it here unless we want to set it
- * to something other than "path" for some rason.
- */
- /* Save "mounted from" info for mount point (NULL pad)*/
- vfs_mountedfrom(mp, from);
-
- err = ntfs_mountfs(devvp, mp, td);
- }
- if (err) {
- vrele(devvp);
- return (err);
- }
- goto success;
+ /*
+ * Since this is a new mount, we want the names for the device and
+ * the mount point copied in. If an error occurs, the mountpoint is
+ * discarded by the upper level code. Note that vfs_mount() handles
+ * copying the mountpoint f_mntonname for us, so we don't have to do
+ * it here unless we want to set it to something other than "path"
+ * for some rason.
+ */
-error_1: /* no state to back out*/
- /* XXX: missing NDFREE(&ndp, ...) */
+ err = ntfs_mountfs(devvp, mp, td);
+ if (err == 0) {
-success:
+ /* Save "mounted from" info for mount point. */
+ vfs_mountedfrom(mp, from);
+ } else
+ vrele(devvp);
return (err);
}
@@ -275,13 +244,12 @@ ntfs_mountfs(devvp, mp, td)
struct buf *bp;
struct ntfsmount *ntmp;
struct cdev *dev = devvp->v_rdev;
- int error, ronly, i, v;
+ int error, i, v;
struct vnode *vp;
struct g_consumer *cp;
struct g_provider *pp;
char *cs_ntfs, *cs_local;
- ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
DROP_GIANT();
g_topology_lock();
@@ -296,7 +264,7 @@ ntfs_mountfs(devvp, mp, td)
if ((pp != NULL) && ((pp->acr | pp->acw | pp->ace ) != 0))
error = EPERM;
else
- error = g_vfs_open(devvp, &cp, "ntfs", ronly ? 0 : 1);
+ error = g_vfs_open(devvp, &cp, "ntfs", 0);
g_topology_unlock();
PICKUP_GIANT();
diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c
index 8de8ca4..edcf137 100644
--- a/sys/fs/ntfs/ntfs_vnops.c
+++ b/sys/fs/ntfs/ntfs_vnops.c
@@ -67,7 +67,6 @@
#include <sys/unistd.h> /* for pathconf(2) constants */
static vop_read_t ntfs_read;
-static vop_write_t ntfs_write;
static vop_getattr_t ntfs_getattr;
static vop_inactive_t ntfs_inactive;
static vop_reclaim_t ntfs_reclaim;
@@ -78,7 +77,6 @@ static vop_open_t ntfs_open;
static vop_close_t ntfs_close;
static vop_readdir_t ntfs_readdir;
static vop_cachedlookup_t ntfs_lookup;
-static vop_fsync_t ntfs_fsync;
static vop_pathconf_t ntfs_pathconf;
static vop_vptofh_t ntfs_vptofh;
@@ -272,6 +270,7 @@ ntfs_strategy(ap)
register struct fnode *fp = VTOF(vp);
register struct ntnode *ip = FTONT(fp);
struct ntfsmount *ntmp = ip->i_mp;
+ u_int32_t toread;
int error;
dprintf(("ntfs_strategy: offset: %d, blkno: %d, lblkno: %d\n",
@@ -281,99 +280,33 @@ ntfs_strategy(ap)
dprintf(("strategy: bcount: %d flags: 0x%x\n",
(u_int32_t)bp->b_bcount,bp->b_flags));
- if (bp->b_iocmd == BIO_READ) {
- u_int32_t toread;
-
- if (ntfs_cntob(bp->b_blkno) >= fp->f_size) {
- clrbuf(bp);
- error = 0;
- } else {
- toread = MIN(bp->b_bcount,
- fp->f_size-ntfs_cntob(bp->b_blkno));
- dprintf(("ntfs_strategy: toread: %d, fsize: %d\n",
- toread,(u_int32_t)fp->f_size));
-
- error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
- fp->f_attrname, ntfs_cntob(bp->b_blkno),
- toread, bp->b_data, NULL);
-
- if (error) {
- printf("ntfs_strategy: ntfs_readattr failed\n");
- bp->b_error = error;
- bp->b_ioflags |= BIO_ERROR;
- }
+ KASSERT(bp->b_iocmd == BIO_READ, ("Invalid buffer\n"));
- bzero(bp->b_data + toread, bp->b_bcount - toread);
- }
+ if (ntfs_cntob(bp->b_blkno) >= fp->f_size) {
+ clrbuf(bp);
+ error = 0;
} else {
- size_t tmp;
- u_int32_t towrite;
+ toread = MIN(bp->b_bcount,
+ fp->f_size-ntfs_cntob(bp->b_blkno));
+ dprintf(("ntfs_strategy: toread: %d, fsize: %d\n",
+ toread,(u_int32_t)fp->f_size));
- if (ntfs_cntob(bp->b_blkno) + bp->b_bcount >= fp->f_size) {
- printf("ntfs_strategy: CAN'T EXTEND FILE\n");
- bp->b_error = error = EFBIG;
+ error = ntfs_readattr(ntmp, ip, fp->f_attrtype,
+ fp->f_attrname, ntfs_cntob(bp->b_blkno),
+ toread, bp->b_data, NULL);
+
+ if (error) {
+ printf("ntfs_strategy: ntfs_readattr failed\n");
+ bp->b_error = error;
bp->b_ioflags |= BIO_ERROR;
- } else {
- towrite = MIN(bp->b_bcount,
- fp->f_size-ntfs_cntob(bp->b_blkno));
- dprintf(("ntfs_strategy: towrite: %d, fsize: %d\n",
- towrite,(u_int32_t)fp->f_size));
-
- error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype,
- fp->f_attrname, ntfs_cntob(bp->b_blkno),towrite,
- bp->b_data, &tmp, NULL);
-
- if (error) {
- printf("ntfs_strategy: ntfs_writeattr fail\n");
- bp->b_error = error;
- bp->b_ioflags |= BIO_ERROR;
- }
}
+
+ bzero(bp->b_data + toread, bp->b_bcount - toread);
}
bufdone(bp);
return (0);
}
-static int
-ntfs_write(ap)
- struct vop_write_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct fnode *fp = VTOF(vp);
- register struct ntnode *ip = FTONT(fp);
- struct uio *uio = ap->a_uio;
- struct ntfsmount *ntmp = ip->i_mp;
- u_int64_t towrite;
- size_t written;
- int error;
-
- dprintf(("ntfs_write: ino: %d, off: %d resid: %d, segflg: %d\n",ip->i_number,(u_int32_t)uio->uio_offset,uio->uio_resid,uio->uio_segflg));
- dprintf(("ntfs_write: filesize: %d",(u_int32_t)fp->f_size));
-
- if (uio->uio_resid + uio->uio_offset > fp->f_size) {
- printf("ntfs_write: CAN'T WRITE BEYOND END OF FILE\n");
- return (EFBIG);
- }
-
- towrite = MIN(uio->uio_resid, fp->f_size - uio->uio_offset);
-
- dprintf((", towrite: %d\n",(u_int32_t)towrite));
-
- error = ntfs_writeattr_plain(ntmp, ip, fp->f_attrtype,
- fp->f_attrname, uio->uio_offset, towrite, NULL, &written, uio);
-#ifdef NTFS_DEBUG
- if (error)
- printf("ntfs_write: ntfs_writeattr failed: %d\n", error);
-#endif
-
- return (error);
-}
-
int
ntfs_access(ap)
struct vop_access_args /* {
@@ -390,7 +323,7 @@ ntfs_access(ap)
dprintf(("ntfs_access: %d\n",ip->i_number));
/*
- * Disallow write attempts on read-only filesystems;
+ * Disallow write attempts as we assume read-only filesystems;
* unless the file is a socket, fifo, or a block or
* character device resident on the filesystem.
*/
@@ -399,8 +332,8 @@ ntfs_access(ap)
case VDIR:
case VLNK:
case VREG:
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
+ return (EROFS);
+ default:
break;
}
}
@@ -630,7 +563,6 @@ ntfs_lookup(ap)
return (error);
if ((cnp->cn_flags & ISLASTCN) &&
- (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
return (EROFS);
@@ -679,24 +611,6 @@ ntfs_lookup(ap)
}
/*
- * Flush the blocks of a file to disk.
- *
- * This function is worthless for vnodes that represent directories. Maybe we
- * could just do a sync if they try an fsync on a directory file.
- */
-static int
-ntfs_fsync(ap)
- struct vop_fsync_args /* {
- struct vnode *a_vp;
- struct ucred *a_cred;
- int a_waitfor;
- struct thread *a_td;
- } */ *ap;
-{
- return (0);
-}
-
-/*
* Return POSIX pathconf information applicable to NTFS filesystem
*/
int
@@ -756,7 +670,6 @@ struct vop_vector ntfs_vnodeops = {
.vop_bmap = ntfs_bmap,
.vop_cachedlookup = ntfs_lookup,
.vop_close = ntfs_close,
- .vop_fsync = ntfs_fsync,
.vop_getattr = ntfs_getattr,
.vop_inactive = ntfs_inactive,
.vop_lookup = vfs_cache_lookup,
@@ -766,6 +679,5 @@ struct vop_vector ntfs_vnodeops = {
.vop_readdir = ntfs_readdir,
.vop_reclaim = ntfs_reclaim,
.vop_strategy = ntfs_strategy,
- .vop_write = ntfs_write,
.vop_vptofh = ntfs_vptofh,
};
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index de105f0..40c8c46 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$");
#include <sys/linker.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/memrange.h>
#include <sys/msgbuf.h>
#include <sys/mutex.h>
#include <sys/pcpu.h>
@@ -247,6 +248,8 @@ struct pcpu __pcpu[MAXCPU];
struct mtx icu_lock;
+struct mem_range_softc mem_range_softc;
+
static void
cpu_startup(dummy)
void *dummy;
diff --git a/sys/i386/i386/mem.c b/sys/i386/i386/mem.c
index dbbe242f..9c83f47 100644
--- a/sys/i386/i386/mem.c
+++ b/sys/i386/i386/mem.c
@@ -72,8 +72,6 @@ __FBSDID("$FreeBSD$");
*/
MALLOC_DEFINE(M_MEMDESC, "memdesc", "memory range descriptors");
-struct mem_range_softc mem_range_softc;
-
static struct sx memsxlock;
SX_SYSINIT(memsxlockinit, &memsxlock, "/dev/mem lock");
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h
index 7116f76..62d268d 100644
--- a/sys/i386/include/cpufunc.h
+++ b/sys/i386/include/cpufunc.h
@@ -97,6 +97,13 @@ clflush(u_long addr)
}
static __inline void
+clts(void)
+{
+
+ __asm __volatile("clts");
+}
+
+static __inline void
disable_intr(void)
{
#ifdef XEN
@@ -688,6 +695,9 @@ intr_restore(register_t eflags)
int breakpoint(void);
u_int bsfl(u_int mask);
u_int bsrl(u_int mask);
+void clflush(u_long addr);
+void clts(void);
+void cpuid_count(u_int ax, u_int cx, u_int *p);
void disable_intr(void);
void do_cpuid(u_int ax, u_int *p);
void enable_intr(void);
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index 0da580f..50c812c 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -100,15 +100,6 @@ __FBSDID("$FreeBSD$");
#define fxrstor(addr) __asm __volatile("fxrstor %0" : : "m" (*(addr)))
#define fxsave(addr) __asm __volatile("fxsave %0" : "=m" (*(addr)))
#endif
-#ifdef XEN
-#define start_emulating() (HYPERVISOR_fpu_taskswitch(1))
-#define stop_emulating() (HYPERVISOR_fpu_taskswitch(0))
-#else
-#define start_emulating() __asm __volatile( \
- "smsw %%ax; orb %0,%%al; lmsw %%ax" \
- : : "n" (CR0_TS) : "ax")
-#define stop_emulating() __asm __volatile("clts")
-#endif
#else /* !(__GNUCLIKE_ASM && !lint) */
void fldcw(u_short cw);
@@ -123,11 +114,17 @@ void frstor(caddr_t addr);
void fxsave(caddr_t addr);
void fxrstor(caddr_t addr);
#endif
-void start_emulating(void);
-void stop_emulating(void);
#endif /* __GNUCLIKE_ASM && !lint */
+#ifdef XEN
+#define start_emulating() (HYPERVISOR_fpu_taskswitch(1))
+#define stop_emulating() (HYPERVISOR_fpu_taskswitch(0))
+#else
+#define start_emulating() load_cr0(rcr0() | CR0_TS)
+#define stop_emulating() clts()
+#endif
+
#ifdef CPU_ENABLE_SSE
#define GET_FPU_CW(thread) \
(cpu_fxsr ? \
diff --git a/sys/kern/dtio_kdtrace.c b/sys/kern/dtio_kdtrace.c
new file mode 100644
index 0000000..cfac370
--- /dev/null
+++ b/sys/kern/dtio_kdtrace.c
@@ -0,0 +1,232 @@
+/*-
+ * Copyright (c) 2012 Advanced Computing Technologies LLC
+ * Written by George Neville-Neil gnn@freebsd.org
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#include <sys/dtrace.h>
+#include "../sys/dtrace_bsd.h"
+
+
+static int dtio_unload(void);
+static void dtio_getargdesc(void *, dtrace_id_t, void *,
+ dtrace_argdesc_t *);
+static void dtio_provide(void *, dtrace_probedesc_t *);
+static void dtio_destroy(void *, dtrace_id_t, void *);
+static void dtio_enable(void *, dtrace_id_t, void *);
+static void dtio_disable(void *, dtrace_id_t, void *);
+static void dtio_load(void *);
+
+static dtrace_pattr_t dtio_attr = {
+{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
+{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
+{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
+{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
+{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
+};
+
+static char *genunix = "genunix";
+
+/*
+ * Name strings.
+ */
+static char *dtio_start_str = "start";
+static char *dtio_done_str = "done";
+static char *dtio_wait_start_str = "wait-start";
+static char *dtio_wait_done_str = "wait-done";
+
+static dtrace_pops_t dtio_pops = {
+ dtio_provide,
+ NULL,
+ dtio_enable,
+ dtio_disable,
+ NULL,
+ NULL,
+ dtio_getargdesc,
+ NULL,
+ NULL,
+ dtio_destroy
+};
+
+static dtrace_provider_id_t dtio_id;
+
+extern uint32_t dtio_start_id;
+extern uint32_t dtio_done_id;
+extern uint32_t dtio_wait_start_id;
+extern uint32_t dtio_wait_done_id;
+
+static void
+dtio_getargdesc(void *arg, dtrace_id_t id, void *parg,
+ dtrace_argdesc_t *desc)
+{
+ const char *p = NULL;
+
+ switch (desc->dtargd_ndx) {
+ case 0:
+ p = "struct bio *";
+ break;
+ case 1:
+ p = "struct devstat *";
+ break;
+ default:
+ desc->dtargd_ndx = DTRACE_ARGNONE;
+ }
+
+ if (p != NULL)
+ strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native));
+}
+
+static void
+dtio_provide(void *arg, dtrace_probedesc_t *desc)
+{
+ if (desc != NULL)
+ return;
+
+ if (dtrace_probe_lookup(dtio_id, genunix, NULL,
+ dtio_start_str) == 0) {
+ dtio_start_id = dtrace_probe_create(dtio_id, genunix, NULL,
+ dtio_start_str, 0, NULL);
+ }
+ if (dtrace_probe_lookup(dtio_id, genunix, NULL, dtio_done_str) == 0) {
+ dtio_done_id = dtrace_probe_create(dtio_id, genunix, NULL,
+ dtio_done_str, 0, NULL);
+ }
+ if (dtrace_probe_lookup(dtio_id, genunix, NULL,
+ dtio_wait_start_str) == 0) {
+ dtio_wait_start_id = dtrace_probe_create(dtio_id, genunix,
+ NULL,
+ dtio_wait_start_str,
+ 0, NULL);
+ }
+ if (dtrace_probe_lookup(dtio_id, genunix, NULL,
+ dtio_wait_done_str) == 0) {
+ dtio_wait_done_id = dtrace_probe_create(dtio_id, genunix, NULL,
+ dtio_wait_done_str, 0, NULL);
+ }
+
+}
+
+static void
+dtio_destroy(void *arg, dtrace_id_t id, void *parg)
+{
+}
+
+static void
+dtio_enable(void *arg, dtrace_id_t id, void *parg)
+{
+ if (id == dtio_start_id)
+ dtrace_io_start_probe =
+ (dtrace_io_start_probe_func_t)dtrace_probe;
+ else if (id == dtio_done_id)
+ dtrace_io_done_probe =
+ (dtrace_io_done_probe_func_t)dtrace_probe;
+ else if (id == dtio_wait_start_id)
+ dtrace_io_wait_start_probe =
+ (dtrace_io_wait_start_probe_func_t)dtrace_probe;
+ else if (id == dtio_wait_done_id)
+ dtrace_io_wait_done_probe =
+ (dtrace_io_wait_done_probe_func_t)dtrace_probe;
+ else
+ printf("dtrace io provider: unknown ID\n");
+
+}
+
+static void
+dtio_disable(void *arg, dtrace_id_t id, void *parg)
+{
+ if (id == dtio_start_id)
+ dtrace_io_start_probe = NULL;
+ else if (id == dtio_done_id)
+ dtrace_io_done_probe = NULL;
+ else if (id == dtio_wait_start_id)
+ dtrace_io_wait_start_probe = NULL;
+ else if (id == dtio_wait_done_id)
+ dtrace_io_wait_done_probe = NULL;
+ else
+ printf("dtrace io provider: unknown ID\n");
+
+}
+
+static void
+dtio_load(void *dummy)
+{
+ if (dtrace_register("io", &dtio_attr, DTRACE_PRIV_USER, NULL,
+ &dtio_pops, NULL, &dtio_id) != 0)
+ return;
+}
+
+
+static int
+dtio_unload()
+{
+ dtrace_io_start_probe = NULL;
+ dtrace_io_done_probe = NULL;
+ dtrace_io_wait_start_probe = NULL;
+ dtrace_io_wait_done_probe = NULL;
+
+ return (dtrace_unregister(dtio_id));
+}
+
+static int
+dtio_modevent(module_t mod __unused, int type, void *data __unused)
+{
+ int error = 0;
+
+ switch (type) {
+ case MOD_LOAD:
+ break;
+
+ case MOD_UNLOAD:
+ break;
+
+ case MOD_SHUTDOWN:
+ break;
+
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+
+ return (error);
+}
+
+SYSINIT(dtio_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
+ dtio_load, NULL);
+SYSUNINIT(dtio_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
+ dtio_unload, NULL);
+
+DEV_MODULE(dtio, dtio_modevent, NULL);
+MODULE_VERSION(dtio, 1);
+MODULE_DEPEND(dtio, dtrace, 1, 1, 1);
+MODULE_DEPEND(dtio, opensolaris, 1, 1, 1);
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index a4b7580..f8e3f3d 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -2275,8 +2275,8 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags,
struct file *fp;
#ifdef CAPABILITIES
struct file *fp_fromcap;
- int error;
#endif
+ int error;
*fpp = NULL;
if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
@@ -2315,7 +2315,7 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags,
else
error = cap_funwrap_mmap(fp, needrights, maxprotp,
&fp_fromcap);
- if (error) {
+ if (error != 0) {
fdrop(fp, td);
return (error);
}
@@ -2341,13 +2341,29 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags,
/*
* FREAD and FWRITE failure return EBADF as per POSIX.
*/
- if ((flags == FREAD && (fp->f_flag & FREAD) == 0) ||
- (flags == FWRITE && (fp->f_flag & FWRITE) == 0) ||
- (flags == (FREAD | FEXEC) &&
- (((fp->f_flag & flags) == 0) || ((fp->f_flag & FWRITE) != 0)))) {
+ error = 0;
+ switch (flags) {
+ case FREAD:
+ case FWRITE:
+ if ((fp->f_flag & flags) == 0)
+ error = EBADF;
+ break;
+ case FEXEC:
+ if ((fp->f_flag & (FREAD | FEXEC)) == 0 ||
+ ((fp->f_flag & FWRITE) != 0))
+ error = EBADF;
+ break;
+ case 0:
+ break;
+ default:
+ KASSERT(0, ("wrong flags"));
+ }
+
+ if (error != 0) {
fdrop(fp, td);
- return (EBADF);
+ return (error);
}
+
*fpp = fp;
return (0);
}
@@ -2448,7 +2464,7 @@ int
fgetvp_exec(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp)
{
- return (_fgetvp(td, fd, FREAD | FEXEC, rights, NULL, vpp));
+ return (_fgetvp(td, fd, FEXEC, rights, NULL, vpp));
}
#ifdef notyet
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 52a0c40..2685a8b 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2436,9 +2436,10 @@ ptracestop(struct thread *td, int sig)
}
stopme:
thread_suspend_switch(td);
- if (!(p->p_flag & P_TRACED)) {
+ if (p->p_xthread == td)
+ p->p_xthread = NULL;
+ if (!(p->p_flag & P_TRACED))
break;
- }
if (td->td_dbgflags & TDB_SUSPEND) {
if (p->p_flag & P_SINGLE_EXIT)
break;
diff --git a/sys/kern/subr_devstat.c b/sys/kern/subr_devstat.c
index bbbfdbf..c44ef27 100644
--- a/sys/kern/subr_devstat.c
+++ b/sys/kern/subr_devstat.c
@@ -29,6 +29,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_kdtrace.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -44,6 +46,58 @@ __FBSDID("$FreeBSD$");
#include <machine/atomic.h>
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+
+dtrace_io_start_probe_func_t dtrace_io_start_probe;
+dtrace_io_done_probe_func_t dtrace_io_done_probe;
+dtrace_io_wait_start_probe_func_t dtrace_io_wait_start_probe;
+dtrace_io_wait_done_probe_func_t dtrace_io_wait_done_probe;
+
+uint32_t dtio_start_id;
+uint32_t dtio_done_id;
+uint32_t dtio_wait_start_id;
+uint32_t dtio_wait_done_id;
+
+#define DTRACE_DEVSTAT_START() \
+ if (dtrace_io_start_probe != NULL) \
+ (*dtrace_io_start_probe)(dtio_start_id, NULL, ds);
+
+#define DTRACE_DEVSTAT_BIO_START() \
+ if (dtrace_io_start_probe != NULL) \
+ (*dtrace_io_start_probe)(dtio_start_id, bp, ds);
+
+#define DTRACE_DEVSTAT_DONE() \
+ if (dtrace_io_done_probe != NULL) \
+ (*dtrace_io_done_probe)(dtio_done_id, NULL, ds);
+
+#define DTRACE_DEVSTAT_BIO_DONE() \
+ if (dtrace_io_done_probe != NULL) \
+ (*dtrace_io_done_probe)(dtio_done_id, bp, ds);
+
+#define DTRACE_DEVSTAT_WAIT_START() \
+ if (dtrace_io_wait_start_probe != NULL) \
+ (*dtrace_io_wait_start_probe)(dtio_wait_start_id, NULL, ds);
+
+#define DTRACE_DEVSTAT_WAIT_DONE() \
+ if (dtrace_io_wait_done_probe != NULL) \
+ (*dtrace_io_wait_done_probe)(dtio_wait_done_id, NULL, ds);
+
+#else /* ! KDTRACE_HOOKS */
+
+#define DTRACE_DEVSTAT_START()
+
+#define DTRACE_DEVSTAT_BIO_START()
+
+#define DTRACE_DEVSTAT_DONE()
+
+#define DTRACE_DEVSTAT_BIO_DONE()
+
+#define DTRACE_DEVSTAT_WAIT_START()
+
+#define DTRACE_DEVSTAT_WAIT_DONE()
+#endif /* KDTRACE_HOOKS */
+
static int devstat_num_devs;
static long devstat_generation = 1;
static int devstat_version = DEVSTAT_VERSION;
@@ -227,6 +281,7 @@ devstat_start_transaction(struct devstat *ds, struct bintime *now)
}
ds->start_count++;
atomic_add_rel_int(&ds->sequence0, 1);
+ DTRACE_DEVSTAT_START();
}
void
@@ -241,6 +296,7 @@ devstat_start_transaction_bio(struct devstat *ds, struct bio *bp)
binuptime(&bp->bio_t0);
devstat_start_transaction(ds, &bp->bio_t0);
+ DTRACE_DEVSTAT_BIO_START();
}
/*
@@ -312,6 +368,7 @@ devstat_end_transaction(struct devstat *ds, uint32_t bytes,
ds->end_count++;
atomic_add_rel_int(&ds->sequence0, 1);
+ DTRACE_DEVSTAT_DONE();
}
void
@@ -334,6 +391,7 @@ devstat_end_transaction_bio(struct devstat *ds, struct bio *bp)
devstat_end_transaction(ds, bp->bio_bcount - bp->bio_resid,
DEVSTAT_TAG_SIMPLE, flg, NULL, &bp->bio_t0);
+ DTRACE_DEVSTAT_BIO_DONE();
}
/*
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 9c6c204..10209ec 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -635,7 +635,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
struct iovec iov;
struct uio uio;
struct proc *curp, *p, *pp;
- struct thread *td2 = NULL;
+ struct thread *td2 = NULL, *td3;
struct ptrace_io_desc *piod = NULL;
struct ptrace_lwpinfo *pl;
int error, write, tmp, num;
@@ -953,10 +953,8 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
td2->td_xsig = data;
if (req == PT_DETACH) {
- struct thread *td3;
- FOREACH_THREAD_IN_PROC(p, td3) {
+ FOREACH_THREAD_IN_PROC(p, td3)
td3->td_dbgflags &= ~TDB_SUSPEND;
- }
}
/*
* unsuspend all threads, to not let a thread run,
@@ -967,6 +965,8 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG|P_WAITED);
thread_unsuspend(p);
PROC_SUNLOCK(p);
+ if (req == PT_ATTACH)
+ kern_psignal(p, data);
} else {
if (data)
kern_psignal(p, data);
diff --git a/sys/mips/nlm/board.c b/sys/mips/nlm/board.c
index b4b0439..c6fd59d 100644
--- a/sys/mips/nlm/board.c
+++ b/sys/mips/nlm/board.c
@@ -362,6 +362,8 @@ nlm_print_processor_info(void)
revstr = "A2"; break;
case 3:
revstr = "B0"; break;
+ case 4:
+ revstr = "B1"; break;
default:
revstr = "??"; break;
}
diff --git a/sys/mips/nlm/dev/net/mdio.c b/sys/mips/nlm/dev/net/mdio.c
index 362312f..ed2abe4 100644
--- a/sys/mips/nlm/dev/net/mdio.c
+++ b/sys/mips/nlm/dev/net/mdio.c
@@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$");
#include <mips/nlm/hal/nae.h>
#include <mips/nlm/hal/mdio.h>
+#include <mips/nlm/xlp.h>
+
/* Internal MDIO READ/WRITE Routines */
int
nlm_int_gmac_mdio_read(uint64_t nae_base, int bus, int block,
@@ -176,12 +178,7 @@ nlm_gmac_mdio_read(uint64_t nae_base, int bus, int block,
int intf_type, int phyaddr, int regidx)
{
uint32_t mdio_ld_cmd;
- uint32_t val;
-
- val = EXT_G_MDIO_CMD_SP |
- (phyaddr << EXT_G_MDIO_PHYADDR_POS) |
- (regidx << EXT_G_MDIO_REGADDR_POS) |
- EXT_G_MDIO_DIV;
+ uint32_t ctrlval;
mdio_ld_cmd = nlm_read_nae_reg(nae_base, NAE_REG(block, intf_type,
(EXT_G0_MDIO_CTRL + bus * 4)));
@@ -195,14 +192,22 @@ nlm_gmac_mdio_read(uint64_t nae_base, int bus, int block,
EXT_G_MDIO_STAT_MBSY);
}
- nlm_write_nae_reg(nae_base,
+ ctrlval = EXT_G_MDIO_CMD_SP |
+ (phyaddr << EXT_G_MDIO_PHYADDR_POS) |
+ (regidx << EXT_G_MDIO_REGADDR_POS);
+ if (nlm_is_xlp8xx_ax() || nlm_is_xlp8xx_b0() || nlm_is_xlp3xx_ax())
+ ctrlval |= EXT_G_MDIO_DIV;
+ else
+ ctrlval |= EXT_G_MDIO_DIV_WITH_HW_DIV64;
+
+ nlm_write_nae_reg(nae_base,
NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
- val);
+ ctrlval);
nlm_write_nae_reg(nae_base,
NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
- val | (1<<18));
-
+ ctrlval | (1<<18));
+ DELAY(1000);
/* poll master busy bit until it is not busy */
while(nlm_read_nae_reg(nae_base,
NAE_REG(block, intf_type, (EXT_G0_MDIO_RD_STAT + bus * 4))) &
@@ -210,7 +215,7 @@ nlm_gmac_mdio_read(uint64_t nae_base, int bus, int block,
nlm_write_nae_reg(nae_base,
NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
- val);
+ ctrlval);
/* Read the data back */
return nlm_read_nae_reg(nae_base,
@@ -236,11 +241,6 @@ nlm_gmac_mdio_write(uint64_t nae_base, int bus, int block,
uint32_t mdio_ld_cmd;
uint32_t ctrlval;
- ctrlval = EXT_G_MDIO_CMD_SP |
- (phyaddr << EXT_G_MDIO_PHYADDR_POS) |
- (regidx << EXT_G_MDIO_REGADDR_POS) |
- EXT_G_MDIO_DIV;
-
mdio_ld_cmd = nlm_read_nae_reg(nae_base, NAE_REG(block, intf_type,
(EXT_G0_MDIO_CTRL + bus * 4)));
if (mdio_ld_cmd & EXT_G_MDIO_CMD_LCD) {
@@ -258,6 +258,14 @@ nlm_gmac_mdio_write(uint64_t nae_base, int bus, int block,
NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL_DATA+bus*4)),
val);
+ ctrlval = EXT_G_MDIO_CMD_SP |
+ (phyaddr << EXT_G_MDIO_PHYADDR_POS) |
+ (regidx << EXT_G_MDIO_REGADDR_POS);
+ if (nlm_is_xlp8xx_ax() || nlm_is_xlp8xx_b0() || nlm_is_xlp3xx_ax())
+ ctrlval |= EXT_G_MDIO_DIV;
+ else
+ ctrlval |= EXT_G_MDIO_DIV_WITH_HW_DIV64;
+
nlm_write_nae_reg(nae_base,
NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
ctrlval);
@@ -265,6 +273,7 @@ nlm_gmac_mdio_write(uint64_t nae_base, int bus, int block,
nlm_write_nae_reg(nae_base,
NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
ctrlval | EXT_G_MDIO_CMD_LCD);
+ DELAY(1000);
/* poll master busy bit until it is not busy */
while(nlm_read_nae_reg(nae_base,
@@ -291,11 +300,17 @@ int
nlm_gmac_mdio_reset(uint64_t nae_base, int bus, int block,
int intf_type)
{
+ uint32_t ctrlval;
+
+ if (nlm_is_xlp8xx_ax() || nlm_is_xlp8xx_b0() || nlm_is_xlp3xx_ax())
+ ctrlval = EXT_G_MDIO_DIV;
+ else
+ ctrlval = EXT_G_MDIO_DIV_WITH_HW_DIV64;
+
nlm_write_nae_reg(nae_base,
- NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
- EXT_G_MDIO_MMRST | EXT_G_MDIO_DIV);
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL + bus * 4)),
+ EXT_G_MDIO_MMRST | ctrlval);
nlm_write_nae_reg(nae_base,
- NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL+bus*4)),
- EXT_G_MDIO_DIV);
+ NAE_REG(block, intf_type, (EXT_G0_MDIO_CTRL + bus * 4)), ctrlval);
return (0);
}
diff --git a/sys/mips/nlm/hal/mdio.h b/sys/mips/nlm/hal/mdio.h
index 6288391..a1e720b 100644
--- a/sys/mips/nlm/hal/mdio.h
+++ b/sys/mips/nlm/hal/mdio.h
@@ -81,6 +81,7 @@
#define EXT_G_MDIO_CMD_SC 0x00080000
#define EXT_G_MDIO_MMRST 0x00100000
#define EXT_G_MDIO_DIV 0x0000001E
+#define EXT_G_MDIO_DIV_WITH_HW_DIV64 0x00000010
#define EXT_G_MDIO_RD_STAT_MASK 0x0000FFFF
#define EXT_G_MDIO_STAT_LFV 0x00010000
diff --git a/sys/mips/nlm/xlp.h b/sys/mips/nlm/xlp.h
index 3414aed..832c951 100644
--- a/sys/mips/nlm/xlp.h
+++ b/sys/mips/nlm/xlp.h
@@ -57,6 +57,7 @@
#define XLP_REVISION_A1 0x01
#define XLP_REVISION_A2 0x02
#define XLP_REVISION_B0 0x03
+#define XLP_REVISION_B1 0x04
#ifndef LOCORE
/*
@@ -87,6 +88,16 @@ static __inline int nlm_is_xlp3xx(void)
return (nlm_processor_id() == CHIP_PROCESSOR_ID_XLP_3XX);
}
+static __inline int nlm_is_xlp3xx_ax(void)
+{
+ uint32_t procid = mips_rd_prid();
+ int prid = (procid >> 8) & 0xff;
+ int rev = procid & 0xff;
+
+ return (prid == CHIP_PROCESSOR_ID_XLP_3XX &&
+ rev < XLP_REVISION_B0);
+}
+
static __inline int nlm_is_xlp4xx(void)
{
int prid = nlm_processor_id();
@@ -116,5 +127,17 @@ static __inline int nlm_is_xlp8xx_ax(void)
(rev < XLP_REVISION_B0));
}
+static __inline int nlm_is_xlp8xx_b0(void)
+{
+ uint32_t procid = mips_rd_prid();
+ int prid = (procid >> 8) & 0xff;
+ int rev = procid & 0xff;
+
+ return ((prid == CHIP_PROCESSOR_ID_XLP_8XX ||
+ prid == CHIP_PROCESSOR_ID_XLP_432 ||
+ prid == CHIP_PROCESSOR_ID_XLP_416) &&
+ rev == XLP_REVISION_B0);
+}
+
#endif /* LOCORE */
#endif /* __NLM_XLP_H__ */
diff --git a/sys/mips/nlm/xlp_pci.c b/sys/mips/nlm/xlp_pci.c
index bd4fd4c..0610a15 100644
--- a/sys/mips/nlm/xlp_pci.c
+++ b/sys/mips/nlm/xlp_pci.c
@@ -507,13 +507,13 @@ xlp_pcib_hardware_swap_enable(int node, int link)
nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_MEM_BASE, bar);
bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEMEM_LIMIT0 + link);
- nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_MEM_LIM, bar);
+ nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_MEM_LIM, bar | 0xFFF);
bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEIO_BASE0 + link);
nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_IO_BASE, bar);
bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEIO_LIMIT0 + link);
- nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_IO_LIM, bar);
+ nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_IO_LIM, bar | 0xFFF);
}
static int
diff --git a/sys/modules/acpi/acpi/Makefile b/sys/modules/acpi/acpi/Makefile
index 6da186f..973d5d1 100644
--- a/sys/modules/acpi/acpi/Makefile
+++ b/sys/modules/acpi/acpi/Makefile
@@ -54,11 +54,11 @@ SRCS+= psargs.c psloop.c psopcode.c psparse.c psscope.c pstree.c psutils.c
SRCS+= pswalk.c psxface.c
SRCS+= rsaddr.c rscalc.c rscreate.c rsdump.c rsinfo.c rsio.c rsirq.c rslist.c
SRCS+= rsmemory.c rsmisc.c rsserial.c rsutils.c rsxface.c
-SRCS+= tbfadt.c tbfind.c tbinstal.c tbutils.c tbxface.c tbxfroot.c
+SRCS+= tbfadt.c tbfind.c tbinstal.c tbutils.c tbxface.c tbxfload.c tbxfroot.c
SRCS+= utaddress.c utalloc.c utcache.c utcopy.c utdebug.c utdecode.c
-SRCS+= utdelete.c uteval.c utglobal.c utids.c utinit.c utlock.c utmath.c
-SRCS+= utmisc.c utmutex.c utobject.c utosi.c utresrc.c utstate.c utxface.c
-SRCS+= utxferror.c
+SRCS+= utdelete.c uteval.c utexcep.c utglobal.c utids.c utinit.c utlock.c
+SRCS+= utmath.c utmisc.c utmutex.c utobject.c utosi.c utresrc.c utstate.c
+SRCS+= utxface.c utxferror.c
#SRCS+= utxfmutex.c
# OSPM layer and core hardware drivers
@@ -86,6 +86,9 @@ SRCS+= opt_kstack_pages.h opt_nfs.h opt_apic.h opt_compat.h opt_hwpmc_hooks.h
.if KTR
CFLAGS+=-DKTR
.endif
+.if SMP
+CFLAGS+=-DSMP
+.endif
.if ACPI_MAX_TASKS
CFLAGS+=-DACPI_MAX_TASKS=${ACPI_MAX_TASKS}
.endif
@@ -113,14 +116,6 @@ ASM_CFLAGS= -x assembler-with-cpp -DLOCORE ${CFLAGS}
NORMAL_S= ${CC} -c ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}
NM?= nm
-.if ${MACHINE_CPUARCH} == "amd64"
-.if !defined(KERNBUILDDIR)
-CFLAGS+=-DSMP
-.endif
-SRCS+= acpi_switch.S
-acpi_switch.o: acpi_switch.S
- ${NORMAL_S}
-.endif
acpi_wakecode.o: acpi_wakecode.S assym.s
${NORMAL_S}
acpi_wakecode.bin: acpi_wakecode.o
diff --git a/sys/modules/dtrace/Makefile b/sys/modules/dtrace/Makefile
index f8f3785..02423e9 100644
--- a/sys/modules/dtrace/Makefile
+++ b/sys/modules/dtrace/Makefile
@@ -9,6 +9,7 @@ SUBDIR= dtmalloc \
dtrace \
dtraceall \
dtrace_test \
+ dtio \
prototype \
sdt \
systrace
diff --git a/sys/modules/dtrace/dtio/Makefile b/sys/modules/dtrace/dtio/Makefile
new file mode 100644
index 0000000..ff68ce4
--- /dev/null
+++ b/sys/modules/dtrace/dtio/Makefile
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../kern
+
+KMOD= dtio
+SRCS= dtio_kdtrace.c \
+ vnode_if.h
+
+CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris \
+ -I${.CURDIR}/../../../cddl/contrib/opensolaris/uts/common \
+ -I${.CURDIR}/../../..
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/dtrace/dtraceall/dtraceall.c b/sys/modules/dtrace/dtraceall/dtraceall.c
index 61896bf..9d7a23d 100644
--- a/sys/modules/dtrace/dtraceall/dtraceall.c
+++ b/sys/modules/dtrace/dtraceall/dtraceall.c
@@ -65,6 +65,7 @@ MODULE_VERSION(dtraceall, 1);
MODULE_DEPEND(dtraceall, cyclic, 1, 1, 1);
MODULE_DEPEND(dtraceall, opensolaris, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtrace, 1, 1, 1);
+MODULE_DEPEND(dtraceall, dtio, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtmalloc, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtnfscl, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtnfsclient, 1, 1, 1);
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index b35559b..7f44bc2 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1811,8 +1811,10 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m)
m->m_flags &= ~M_VLANTAG;
}
- if (err == 0)
- dst_ifp->if_transmit(dst_ifp, m);
+ if ((err = dst_ifp->if_transmit(dst_ifp, m))) {
+ m_freem(m0);
+ break;
+ }
}
if (err == 0) {
diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
index fe22ed7..2a67e18 100644
--- a/sys/net/if_epair.c
+++ b/sys/net/if_epair.c
@@ -904,39 +904,41 @@ epair_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
if_link_state_change(oifp, LINK_STATE_DOWN);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
oifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+
+ /*
+ * Get rid of our second half. As the other of the two
+ * interfaces may reside in a different vnet, we need to
+ * switch before freeing them.
+ */
+ CURVNET_SET_QUIET(oifp->if_vnet);
ether_ifdetach(oifp);
- ether_ifdetach(ifp);
/*
* Wait for all packets to be dispatched to if_input.
- * The numbers can only go down as the interfaces are
+ * The numbers can only go down as the interface is
* detached so there is no need to use atomics.
*/
- DPRINTF("sca refcnt=%u scb refcnt=%u\n", sca->refcount, scb->refcount);
- EPAIR_REFCOUNT_ASSERT(sca->refcount == 1 && scb->refcount == 1,
- ("%s: ifp=%p sca->refcount!=1: %d || ifp=%p scb->refcount!=1: %d",
- __func__, ifp, sca->refcount, oifp, scb->refcount));
-
- /*
- * Get rid of our second half.
- */
+ DPRINTF("scb refcnt=%u\n", scb->refcount);
+ EPAIR_REFCOUNT_ASSERT(scb->refcount == 1,
+ ("%s: ifp=%p scb->refcount!=1: %d", __func__, oifp, scb->refcount));
oifp->if_softc = NULL;
error = if_clone_destroyif(ifc, oifp);
if (error)
panic("%s: if_clone_destroyif() for our 2nd iface failed: %d",
__func__, error);
+ if_free(oifp);
+ ifmedia_removeall(&scb->media);
+ free(scb, M_EPAIR);
+ CURVNET_RESTORE();
+ ether_ifdetach(ifp);
/*
- * Finish cleaning up. Free them and release the unit.
- * As the other of the two interfaces my reside in a different vnet,
- * we need to switch before freeing them.
+ * Wait for all packets to be dispatched to if_input.
*/
- CURVNET_SET_QUIET(oifp->if_vnet);
- if_free(oifp);
- CURVNET_RESTORE();
+ DPRINTF("sca refcnt=%u\n", sca->refcount);
+ EPAIR_REFCOUNT_ASSERT(sca->refcount == 1,
+ ("%s: ifp=%p sca->refcount!=1: %d", __func__, ifp, sca->refcount));
if_free(ifp);
ifmedia_removeall(&sca->media);
- ifmedia_removeall(&scb->media);
- free(scb, M_EPAIR);
free(sca, M_EPAIR);
ifc_free_unit(ifc, unit);
diff --git a/sys/netinet/ipfw/ip_fw_log.c b/sys/netinet/ipfw/ip_fw_log.c
index b9ed6b3..14eb2a2 100644
--- a/sys/netinet/ipfw/ip_fw_log.c
+++ b/sys/netinet/ipfw/ip_fw_log.c
@@ -44,8 +44,11 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
#include <net/ethernet.h> /* for ETHERTYPE_IP */
#include <net/if.h>
+#include <net/if_clone.h>
#include <net/vnet.h>
#include <net/if_types.h> /* for IFT_ETHER */
#include <net/bpf.h> /* for BPF */
@@ -90,6 +93,15 @@ ipfw_log_bpf(int onoff)
}
#else /* !WITHOUT_BPF */
static struct ifnet *log_if; /* hook to attach to bpf */
+static struct rwlock log_if_lock;
+#define LOGIF_LOCK_INIT(x) rw_init(&log_if_lock, "ipfw log_if lock")
+#define LOGIF_LOCK_DESTROY(x) rw_destroy(&log_if_lock)
+#define LOGIF_RLOCK(x) rw_rlock(&log_if_lock)
+#define LOGIF_RUNLOCK(x) rw_runlock(&log_if_lock)
+#define LOGIF_WLOCK(x) rw_wlock(&log_if_lock)
+#define LOGIF_WUNLOCK(x) rw_wunlock(&log_if_lock)
+
+#define IPFWNAME "ipfw"
/* we use this dummy function for all ifnet callbacks */
static int
@@ -116,37 +128,105 @@ ipfw_log_start(struct ifnet* ifp)
static const u_char ipfwbroadcastaddr[6] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+static int
+ipfw_log_clone_match(struct if_clone *ifc, const char *name)
+{
+
+ return (strncmp(name, IPFWNAME, sizeof(IPFWNAME) - 1) == 0);
+}
+
+static int
+ipfw_log_clone_create(struct if_clone *ifc, char *name, size_t len,
+ caddr_t params)
+{
+ int error;
+ int unit;
+ struct ifnet *ifp;
+
+ error = ifc_name2unit(name, &unit);
+ if (error)
+ return (error);
+
+ error = ifc_alloc_unit(ifc, &unit);
+ if (error)
+ return (error);
+
+ ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL) {
+ ifc_free_unit(ifc, unit);
+ return (ENOSPC);
+ }
+ ifp->if_dname = IPFWNAME;
+ ifp->if_dunit = unit;
+ snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", IPFWNAME, unit);
+ strlcpy(name, ifp->if_xname, len);
+ ifp->if_mtu = 65536;
+ ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_init = (void *)log_dummy;
+ ifp->if_ioctl = log_dummy;
+ ifp->if_start = ipfw_log_start;
+ ifp->if_output = ipfw_log_output;
+ ifp->if_addrlen = 6;
+ ifp->if_hdrlen = 14;
+ ifp->if_broadcastaddr = ipfwbroadcastaddr;
+ ifp->if_baudrate = IF_Mbps(10);
+
+ LOGIF_WLOCK();
+ if (log_if == NULL)
+ log_if = ifp;
+ else {
+ LOGIF_WUNLOCK();
+ if_free(ifp);
+ ifc_free_unit(ifc, unit);
+ return (EEXIST);
+ }
+ LOGIF_WUNLOCK();
+ if_attach(ifp);
+ bpfattach(ifp, DLT_EN10MB, 14);
+
+ return (0);
+}
+
+static int
+ipfw_log_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
+{
+ int unit;
+
+ if (ifp == NULL)
+ return (0);
+
+ LOGIF_WLOCK();
+ if (log_if != NULL && ifp == log_if)
+ log_if = NULL;
+ else {
+ LOGIF_WUNLOCK();
+ return (EINVAL);
+ }
+ LOGIF_WUNLOCK();
+
+ unit = ifp->if_dunit;
+ bpfdetach(ifp);
+ if_detach(ifp);
+ if_free(ifp);
+ ifc_free_unit(ifc, unit);
+
+ return (0);
+}
+
+static struct if_clone ipfw_log_cloner = IFC_CLONE_INITIALIZER(
+ IPFWNAME, NULL, IF_MAXUNIT,
+ NULL, ipfw_log_clone_match, ipfw_log_clone_create, ipfw_log_clone_destroy);
+
void
ipfw_log_bpf(int onoff)
{
- struct ifnet *ifp;
if (onoff) {
- if (log_if)
- return;
- ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL)
- return;
- if_initname(ifp, "ipfw", 0);
- ifp->if_mtu = 65536;
- ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = (void *)log_dummy;
- ifp->if_ioctl = log_dummy;
- ifp->if_start = ipfw_log_start;
- ifp->if_output = ipfw_log_output;
- ifp->if_addrlen = 6;
- ifp->if_hdrlen = 14;
- if_attach(ifp);
- ifp->if_broadcastaddr = ipfwbroadcastaddr;
- ifp->if_baudrate = IF_Mbps(10);
- bpfattach(ifp, DLT_EN10MB, 14);
- log_if = ifp;
+ LOGIF_LOCK_INIT();
+ if_clone_attach(&ipfw_log_cloner);
} else {
- if (log_if) {
- ether_ifdetach(log_if);
- if_free(log_if);
- }
- log_if = NULL;
+ if_clone_detach(&ipfw_log_cloner);
+ LOGIF_LOCK_DESTROY();
}
}
#endif /* !WITHOUT_BPF */
@@ -166,9 +246,11 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
if (V_fw_verbose == 0) {
#ifndef WITHOUT_BPF
-
- if (log_if == NULL || log_if->if_bpf == NULL)
+ LOGIF_RLOCK();
+ if (log_if == NULL || log_if->if_bpf == NULL) {
+ LOGIF_RUNLOCK();
return;
+ }
if (args->eh) /* layer2, use orig hdr */
BPF_MTAP2(log_if, args->eh, ETHER_HDR_LEN, m);
@@ -177,6 +259,7 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
* more info in the header.
*/
BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m);
+ LOGIF_RUNLOCK();
#endif /* !WITHOUT_BPF */
return;
}
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 41bc1c5..10e3959 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -5520,6 +5520,7 @@ do_a_abort:
case AF_INET6:
{
stc.addr_type = SCTP_IPV6_ADDRESS;
+ memcpy(&stc.address, &src6->sin6_addr, sizeof(struct in6_addr));
stc.scope_id = in6_getscope(&src6->sin6_addr);
if (sctp_is_address_on_local_host(src, vrf_id)) {
stc.loopback_scope = 1;
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index c44e704..eb0bd44 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -79,7 +79,7 @@ struct nd_ifinfo {
#define ND6_IFF_PERFORMNUD 0x1
#define ND6_IFF_ACCEPT_RTADV 0x2
-#define ND6_IFF_PREFER_SOURCE 0x4 /* XXX: not related to ND. */
+#define ND6_IFF_PREFER_SOURCE 0x4 /* Not used in FreeBSD. */
#define ND6_IFF_IFDISABLED 0x8 /* IPv6 operation is disabled due to
* DAD failure. (XXX: not ND-specific)
*/
diff --git a/sys/netsmb/smb_trantcp.c b/sys/netsmb/smb_trantcp.c
index c898451..ce52544 100644
--- a/sys/netsmb/smb_trantcp.c
+++ b/sys/netsmb/smb_trantcp.c
@@ -523,8 +523,10 @@ smb_nbst_connect(struct smb_vc *vcp, struct sockaddr *sap, struct thread *td)
return error;
getnanotime(&ts2);
timespecsub(&ts2, &ts1);
- if (ts2.tv_sec == 0 && ts2.tv_sec == 0)
+ if (ts2.tv_sec == 0) {
ts2.tv_sec = 1;
+ ts2.tv_nsec = 0;
+ }
nbp->nbp_timo = ts2;
timespecadd(&nbp->nbp_timo, &ts2);
timespecadd(&nbp->nbp_timo, &ts2);
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 88b1f20..38b7a28 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$");
#include <sys/linker.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/memrange.h>
#include <sys/msgbuf.h>
#include <sys/mutex.h>
#include <sys/pcpu.h>
@@ -216,6 +217,8 @@ struct pcpu __pcpu[MAXCPU];
struct mtx icu_lock;
+struct mem_range_softc mem_range_softc;
+
static void
cpu_startup(dummy)
void *dummy;
diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
index 9de65b7..93dfb46 100644
--- a/sys/powerpc/aim/mmu_oea.c
+++ b/sys/powerpc/aim/mmu_oea.c
@@ -300,7 +300,7 @@ void moea_init(mmu_t);
boolean_t moea_is_modified(mmu_t, vm_page_t);
boolean_t moea_is_prefaultable(mmu_t, pmap_t, vm_offset_t);
boolean_t moea_is_referenced(mmu_t, vm_page_t);
-boolean_t moea_ts_referenced(mmu_t, vm_page_t);
+int moea_ts_referenced(mmu_t, vm_page_t);
vm_offset_t moea_map(mmu_t, vm_offset_t *, vm_paddr_t, vm_paddr_t, int);
boolean_t moea_page_exists_quick(mmu_t, pmap_t, vm_page_t);
int moea_page_wired_mappings(mmu_t, vm_page_t);
@@ -1269,15 +1269,20 @@ moea_init(mmu_t mmu)
boolean_t
moea_is_referenced(mmu_t mmu, vm_page_t m)
{
+ boolean_t rv;
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
("moea_is_referenced: page %p is not managed", m));
- return (moea_query_bit(m, PTE_REF));
+ rw_wlock(&pvh_global_lock);
+ rv = moea_query_bit(m, PTE_REF);
+ rw_wunlock(&pvh_global_lock);
+ return (rv);
}
boolean_t
moea_is_modified(mmu_t mmu, vm_page_t m)
{
+ boolean_t rv;
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
("moea_is_modified: page %p is not managed", m));
@@ -1291,7 +1296,10 @@ moea_is_modified(mmu_t mmu, vm_page_t m)
if ((m->oflags & VPO_BUSY) == 0 &&
(m->aflags & PGA_WRITEABLE) == 0)
return (FALSE);
- return (moea_query_bit(m, PTE_CHG));
+ rw_wlock(&pvh_global_lock);
+ rv = moea_query_bit(m, PTE_CHG);
+ rw_wunlock(&pvh_global_lock);
+ return (rv);
}
boolean_t
@@ -1313,7 +1321,9 @@ moea_clear_reference(mmu_t mmu, vm_page_t m)
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
("moea_clear_reference: page %p is not managed", m));
+ rw_wlock(&pvh_global_lock);
moea_clear_bit(m, PTE_REF);
+ rw_wunlock(&pvh_global_lock);
}
void
@@ -1333,7 +1343,9 @@ moea_clear_modify(mmu_t mmu, vm_page_t m)
*/
if ((m->aflags & PGA_WRITEABLE) == 0)
return;
+ rw_wlock(&pvh_global_lock);
moea_clear_bit(m, PTE_CHG);
+ rw_wunlock(&pvh_global_lock);
}
/*
@@ -1400,13 +1412,17 @@ moea_remove_write(mmu_t mmu, vm_page_t m)
* should be tested and standardized at some point in the future for
* optimal aging of shared pages.
*/
-boolean_t
+int
moea_ts_referenced(mmu_t mmu, vm_page_t m)
{
+ int count;
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
("moea_ts_referenced: page %p is not managed", m));
- return (moea_clear_bit(m, PTE_REF));
+ rw_wlock(&pvh_global_lock);
+ count = moea_clear_bit(m, PTE_REF);
+ rw_wunlock(&pvh_global_lock);
+ return (count);
}
/*
@@ -1816,7 +1832,7 @@ moea_remove_all(mmu_t mmu, vm_page_t m)
moea_pvo_remove(pvo, -1);
PMAP_UNLOCK(pmap);
}
- if ((m->aflags & PGA_WRITEABLE) && moea_is_modified(mmu, m)) {
+ if ((m->aflags & PGA_WRITEABLE) && moea_query_bit(m, PTE_CHG)) {
moea_attr_clear(m, PTE_CHG);
vm_page_dirty(m);
}
@@ -2293,10 +2309,10 @@ moea_query_bit(vm_page_t m, int ptebit)
struct pvo_entry *pvo;
struct pte *pt;
+ rw_assert(&pvh_global_lock, RA_WLOCKED);
if (moea_attr_fetch(m) & ptebit)
return (TRUE);
- rw_wlock(&pvh_global_lock);
LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
/*
@@ -2305,7 +2321,6 @@ moea_query_bit(vm_page_t m, int ptebit)
*/
if (pvo->pvo_pte.pte.pte_lo & ptebit) {
moea_attr_save(m, ptebit);
- rw_wunlock(&pvh_global_lock);
return (TRUE);
}
}
@@ -2329,13 +2344,11 @@ moea_query_bit(vm_page_t m, int ptebit)
mtx_unlock(&moea_table_mutex);
if (pvo->pvo_pte.pte.pte_lo & ptebit) {
moea_attr_save(m, ptebit);
- rw_wunlock(&pvh_global_lock);
return (TRUE);
}
}
}
- rw_wunlock(&pvh_global_lock);
return (FALSE);
}
@@ -2346,7 +2359,7 @@ moea_clear_bit(vm_page_t m, int ptebit)
struct pvo_entry *pvo;
struct pte *pt;
- rw_wlock(&pvh_global_lock);
+ rw_assert(&pvh_global_lock, RA_WLOCKED);
/*
* Clear the cached value.
@@ -2380,7 +2393,6 @@ moea_clear_bit(vm_page_t m, int ptebit)
pvo->pvo_pte.pte.pte_lo &= ~ptebit;
}
- rw_wunlock(&pvh_global_lock);
return (count);
}
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index ada0833..31ca7c2 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -305,7 +305,7 @@ void moea64_init(mmu_t);
boolean_t moea64_is_modified(mmu_t, vm_page_t);
boolean_t moea64_is_prefaultable(mmu_t, pmap_t, vm_offset_t);
boolean_t moea64_is_referenced(mmu_t, vm_page_t);
-boolean_t moea64_ts_referenced(mmu_t, vm_page_t);
+int moea64_ts_referenced(mmu_t, vm_page_t);
vm_offset_t moea64_map(mmu_t, vm_offset_t *, vm_paddr_t, vm_paddr_t, int);
boolean_t moea64_page_exists_quick(mmu_t, pmap_t, vm_page_t);
int moea64_page_wired_mappings(mmu_t, vm_page_t);
@@ -1570,7 +1570,7 @@ moea64_remove_write(mmu_t mmu, vm_page_t m)
* should be tested and standardized at some point in the future for
* optimal aging of shared pages.
*/
-boolean_t
+int
moea64_ts_referenced(mmu_t mmu, vm_page_t m)
{
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index 8b27e6e..060a7f2 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -286,7 +286,7 @@ static void mmu_booke_init(mmu_t);
static boolean_t mmu_booke_is_modified(mmu_t, vm_page_t);
static boolean_t mmu_booke_is_prefaultable(mmu_t, pmap_t, vm_offset_t);
static boolean_t mmu_booke_is_referenced(mmu_t, vm_page_t);
-static boolean_t mmu_booke_ts_referenced(mmu_t, vm_page_t);
+static int mmu_booke_ts_referenced(mmu_t, vm_page_t);
static vm_offset_t mmu_booke_map(mmu_t, vm_offset_t *, vm_paddr_t, vm_paddr_t,
int);
static int mmu_booke_mincore(mmu_t, pmap_t, vm_offset_t,
diff --git a/sys/powerpc/powerpc/mmu_if.m b/sys/powerpc/powerpc/mmu_if.m
index 887e5e4..8cd6e52 100644
--- a/sys/powerpc/powerpc/mmu_if.m
+++ b/sys/powerpc/powerpc/mmu_if.m
@@ -387,7 +387,7 @@ METHOD boolean_t is_referenced {
*
* @retval int count of referenced bits
*/
-METHOD boolean_t ts_referenced {
+METHOD int ts_referenced {
mmu_t _mmu;
vm_page_t _pg;
};
diff --git a/sys/sys/dtrace_bsd.h b/sys/sys/dtrace_bsd.h
index eb348b2..2198b26 100644
--- a/sys/sys/dtrace_bsd.h
+++ b/sys/sys/dtrace_bsd.h
@@ -38,6 +38,8 @@ struct thread;
struct vattr;
struct vnode;
struct reg;
+struct devstat;
+struct bio;
/*
* Cyclic clock function type definition used to hook the cyclic
@@ -168,6 +170,23 @@ extern dtrace_nfsclient_nfs23_done_probe_func_t
extern dtrace_nfsclient_nfs23_done_probe_func_t
dtrace_nfscl_nfs234_done_probe;
+/* IO Provider hooks, really hook into devstat */
+typedef void (*dtrace_io_start_probe_func_t)(uint32_t, struct bio *,
+ struct devstat *);
+extern dtrace_io_start_probe_func_t dtrace_io_start_probe;
+
+typedef void (*dtrace_io_done_probe_func_t)(uint32_t, struct bio *,
+ struct devstat *);
+extern dtrace_io_done_probe_func_t dtrace_io_done_probe;
+
+typedef void (*dtrace_io_wait_start_probe_func_t)(uint32_t, uintptr_t *,
+ struct devstat *);
+extern dtrace_io_wait_start_probe_func_t dtrace_io_wait_start_probe;
+
+typedef void (*dtrace_io_wait_done_probe_func_t)(uint32_t, uintptr_t *,
+ struct devstat *);
+extern dtrace_io_wait_done_probe_func_t dtrace_io_wait_done_probe;
+
/*
* Functions which allow the dtrace module to check that the kernel
* hooks have been compiled with sufficient space for it's private
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 0751213..612dd96 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -1451,6 +1451,12 @@ retry:
/*
* Transfer any cached pages from orig_object to new_object.
+ * If swap_pager_copy() found swapped out pages within the
+ * specified range of orig_object, then it changed
+ * new_object's type to OBJT_SWAP when it transferred those
+ * pages to new_object. Otherwise, new_object's type
+ * should still be OBJT_DEFAULT and orig_object should not
+ * contain any cached pages within the specified range.
*/
if (!vm_object_cache_is_empty(orig_object)) {
start = offidxstart;
@@ -1811,6 +1817,9 @@ vm_object_collapse(vm_object_t object)
* swap_pager_copy() can sleep, in which case
* the backing_object's and object's locks are
* released and reacquired.
+ * Since swap_pager_copy() is being asked to
+ * destroy the source, it will change the
+ * backing_object's type to OBJT_DEFAULT.
*/
swap_pager_copy(
backing_object,
OpenPOWER on IntegriCloud