summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/acpica/acpi_machdep.c244
-rw-r--r--sys/amd64/acpica/madt.c233
-rw-r--r--sys/amd64/amd64/machdep.c106
-rw-r--r--sys/amd64/amd64/pmap.c5
-rw-r--r--sys/amd64/amd64/trap.c10
-rw-r--r--sys/amd64/conf/NOTES10
-rw-r--r--sys/amd64/include/acpica_machdep.h3
-rw-r--r--sys/amd64/include/param.h2
-rw-r--r--sys/amd64/pci/pci_cfgreg.c16
-rw-r--r--sys/arm/include/param.h2
-rw-r--r--sys/cam/cam_periph.c7
-rw-r--r--sys/cam/scsi/scsi_target.c85
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/fletcher.c104
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c16
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c28
-rw-r--r--sys/compat/x86bios/x86bios.c196
-rw-r--r--sys/compat/x86bios/x86bios.h134
-rw-r--r--sys/compat/x86bios/x86bios_alloc.c81
-rw-r--r--sys/conf/NOTES2
-rw-r--r--sys/conf/files7
-rw-r--r--sys/conf/files.amd6414
-rw-r--r--sys/conf/files.i38614
-rw-r--r--sys/conf/newvers.sh44
-rw-r--r--sys/conf/options2
-rw-r--r--sys/contrib/x86emu/x86emu.c35
-rw-r--r--sys/contrib/x86emu/x86emu_util.c4
-rw-r--r--sys/dev/acpi_support/acpi_aiboost.c38
-rw-r--r--sys/dev/acpi_support/acpi_ibm.c6
-rw-r--r--sys/dev/acpica/acpi.c22
-rw-r--r--sys/dev/acpica/acpi_video.c3
-rw-r--r--sys/dev/acpica/acpivar.h5
-rw-r--r--sys/dev/ata/chipsets/ata-marvell.c25
-rw-r--r--sys/dev/atkbdc/atkbd.c60
-rw-r--r--sys/dev/de/if_de.c37
-rw-r--r--sys/dev/de/if_devar.h8
-rw-r--r--sys/dev/dpms/dpms.c102
-rw-r--r--sys/dev/fb/s3_pci.c1
-rw-r--r--sys/dev/fb/vesa.c520
-rw-r--r--sys/dev/hwpmc/pmc_events.h31
-rw-r--r--sys/dev/if_ndis/if_ndis.c5
-rw-r--r--sys/dev/isp/isp.c67
-rw-r--r--sys/dev/isp/isp_stds.h4
-rw-r--r--sys/dev/isp/isp_tpublic.h428
-rw-r--r--sys/dev/isp/ispmbox.h27
-rw-r--r--sys/dev/kbd/kbd.c28
-rw-r--r--sys/dev/mwl/if_mwl.c6
-rw-r--r--sys/dev/mxge/if_mxge.c158
-rw-r--r--sys/dev/mxge/if_mxge_var.h3
-rw-r--r--sys/dev/pci/pci.c26
-rw-r--r--sys/dev/pci/pcireg.h1
-rw-r--r--sys/dev/ppbus/vpo.c7
-rw-r--r--sys/dev/sound/pci/es137x.c35
-rw-r--r--sys/dev/sound/pci/es137x.h13
-rw-r--r--sys/dev/sound/pci/t4dwave.c96
-rw-r--r--sys/dev/syscons/syscons.c10
-rw-r--r--sys/dev/twa/tw_cl_io.c2
-rw-r--r--sys/dev/twa/tw_cl_share.h2
-rw-r--r--sys/dev/twe/twe.c2
-rw-r--r--sys/dev/twe/twevar.h2
-rw-r--r--sys/fs/procfs/procfs.c5
-rw-r--r--sys/fs/procfs/procfs.h1
-rw-r--r--sys/fs/procfs/procfs_osrel.c68
-rw-r--r--sys/geom/part/g_part.c4
-rw-r--r--sys/i386/acpica/acpi_machdep.c240
-rw-r--r--sys/i386/acpica/madt.c232
-rw-r--r--sys/i386/conf/NOTES8
-rw-r--r--sys/i386/i386/machdep.c40
-rw-r--r--sys/i386/i386/pmap.c5
-rw-r--r--sys/i386/i386/trap.c5
-rw-r--r--sys/i386/include/acpica_machdep.h3
-rw-r--r--sys/i386/include/param.h2
-rw-r--r--sys/i386/pci/pci_cfgreg.c14
-rw-r--r--sys/ia64/include/param.h2
-rw-r--r--sys/kern/kern_event.c7
-rw-r--r--sys/kern/kern_mib.c27
-rw-r--r--sys/kern/kern_umtx.c18
-rw-r--r--sys/kern/subr_acl_nfs4.c497
-rw-r--r--sys/kern/subr_bus.c2
-rw-r--r--sys/kern/subr_devstat.c43
-rw-r--r--sys/kern/subr_smp.c33
-rw-r--r--sys/kern/uipc_syscalls.c9
-rw-r--r--sys/mips/include/param.h2
-rw-r--r--sys/modules/Makefile5
-rw-r--r--sys/modules/procfs/Makefile1
-rw-r--r--sys/modules/x86bios/Makefile10
-rw-r--r--sys/modules/x86emu/Makefile8
-rw-r--r--sys/net/if.c4
-rw-r--r--sys/net/if_llatbl.c27
-rw-r--r--sys/net80211/ieee80211.h10
-rw-r--r--sys/net80211/ieee80211_hwmp.c155
-rw-r--r--sys/net80211/ieee80211_mesh.c112
-rw-r--r--sys/net80211/ieee80211_mesh.h47
-rw-r--r--sys/netinet/in_mcast.c6
-rw-r--r--sys/netinet/in_proto.c59
-rw-r--r--sys/netinet/sctp_asconf.c2
-rw-r--r--sys/netinet/sctp_bsd_addr.c14
-rw-r--r--sys/netinet/sctp_input.c2
-rw-r--r--sys/netinet/sctp_os_bsd.h26
-rw-r--r--sys/netinet/sctp_output.c36
-rw-r--r--sys/netinet/sctp_pcb.c73
-rw-r--r--sys/netinet/sctp_pcb.h2
-rw-r--r--sys/netinet/sctp_structs.h1
-rw-r--r--sys/netinet/sctp_sysctl.c2
-rw-r--r--sys/netinet/sctp_timer.c2
-rw-r--r--sys/netinet/sctp_usrreq.c2
-rw-r--r--sys/netinet/sctputil.c10
-rw-r--r--sys/netinet6/sctp6_usrreq.c8
-rw-r--r--sys/pci/intpm.c6
-rw-r--r--sys/powerpc/include/param.h2
-rw-r--r--sys/sparc64/conf/GENERIC1
-rw-r--r--sys/sparc64/include/param.h2
-rw-r--r--sys/sun4v/include/param.h2
-rw-r--r--sys/sys/event.h2
-rw-r--r--sys/sys/kbio.h7
-rw-r--r--sys/sys/mman.h1
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/smp.h1
-rw-r--r--sys/sys/systm.h1
-rw-r--r--sys/sys/vnode.h3
-rw-r--r--sys/teken/sequences1
-rw-r--r--sys/teken/teken.c8
-rw-r--r--sys/teken/teken.h2
-rw-r--r--sys/teken/teken_scs.h24
-rw-r--r--sys/teken/teken_subr.h13
-rw-r--r--sys/teken/teken_subr_compat.h14
-rw-r--r--sys/ufs/ufs/ufs_gjournal.c4
-rw-r--r--sys/vm/vm_mmap.c4
131 files changed, 3192 insertions, 1995 deletions
diff --git a/sys/amd64/acpica/acpi_machdep.c b/sys/amd64/acpica/acpi_machdep.c
index b902c12..0d866e8 100644
--- a/sys/amd64/acpica/acpi_machdep.c
+++ b/sys/amd64/acpica/acpi_machdep.c
@@ -32,8 +32,12 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/sysctl.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
#include <dev/acpica/acpivar.h>
@@ -100,6 +104,246 @@ acpi_cpu_c1()
}
/*
+ * Support for mapping ACPI tables during early boot. Currently this
+ * uses the crashdump map to map each table. However, the crashdump
+ * map is created in pmap_bootstrap() right after the direct map, so
+ * we should be able to just use pmap_mapbios() here instead.
+ *
+ * This makes the following assumptions about how we use this KVA:
+ * pages 0 and 1 are used to map in the header of each table found via
+ * the RSDT or XSDT and pages 2 to n are used to map in the RSDT or
+ * XSDT. This has to use 2 pages for the table headers in case a
+ * header spans a page boundary.
+ *
+ * XXX: We don't ensure the table fits in the available address space
+ * in the crashdump map.
+ */
+
+/*
+ * Map some memory using the crashdump map. 'offset' is an offset in
+ * pages into the crashdump map to use for the start of the mapping.
+ */
+static void *
+table_map(vm_paddr_t pa, int offset, vm_offset_t length)
+{
+ vm_offset_t va, off;
+ void *data;
+
+ off = pa & PAGE_MASK;
+ length = roundup(length + off, PAGE_SIZE);
+ pa = pa & PG_FRAME;
+ va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
+ (offset * PAGE_SIZE);
+ data = (void *)(va + off);
+ length -= PAGE_SIZE;
+ while (length > 0) {
+ va += PAGE_SIZE;
+ pa += PAGE_SIZE;
+ length -= PAGE_SIZE;
+ pmap_kenter(va, pa);
+ invlpg(va);
+ }
+ return (data);
+}
+
+/* Unmap memory previously mapped with table_map(). */
+static void
+table_unmap(void *data, vm_offset_t length)
+{
+ vm_offset_t va, off;
+
+ va = (vm_offset_t)data;
+ off = va & PAGE_MASK;
+ length = roundup(length + off, PAGE_SIZE);
+ va &= ~PAGE_MASK;
+ while (length > 0) {
+ pmap_kremove(va);
+ invlpg(va);
+ va += PAGE_SIZE;
+ length -= PAGE_SIZE;
+ }
+}
+
+/*
+ * Map a table at a given offset into the crashdump map. It first
+ * maps the header to determine the table length and then maps the
+ * entire table.
+ */
+static void *
+map_table(vm_paddr_t pa, int offset, const char *sig)
+{
+ ACPI_TABLE_HEADER *header;
+ vm_offset_t length;
+ void *table;
+
+ header = table_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
+ if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
+ table_unmap(header, sizeof(ACPI_TABLE_HEADER));
+ return (NULL);
+ }
+ length = header->Length;
+ table_unmap(header, sizeof(ACPI_TABLE_HEADER));
+ table = table_map(pa, offset, length);
+ if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
+ if (bootverbose)
+ printf("ACPI: Failed checksum for table %s\n", sig);
+ table_unmap(table, length);
+ return (NULL);
+ }
+ return (table);
+}
+
+/*
+ * See if a given ACPI table is the requested table. Returns the
+ * length of the able if it matches or zero on failure.
+ */
+static int
+probe_table(vm_paddr_t address, const char *sig)
+{
+ ACPI_TABLE_HEADER *table;
+
+ table = table_map(address, 0, sizeof(ACPI_TABLE_HEADER));
+ if (table == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map table at 0x%jx\n",
+ (uintmax_t)address);
+ return (0);
+ }
+ if (bootverbose)
+ printf("Table '%.4s' at 0x%jx\n", table->Signature,
+ (uintmax_t)address);
+
+ if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0) {
+ table_unmap(table, sizeof(ACPI_TABLE_HEADER));
+ return (0);
+ }
+ table_unmap(table, sizeof(ACPI_TABLE_HEADER));
+ return (1);
+}
+
+/*
+ * Try to map a table at a given physical address previously returned
+ * by acpi_find_table().
+ */
+void *
+acpi_map_table(vm_paddr_t pa, const char *sig)
+{
+
+ return (map_table(pa, 0, sig));
+}
+
+/* Unmap a table previously mapped via acpi_map_table(). */
+void
+acpi_unmap_table(void *table)
+{
+ ACPI_TABLE_HEADER *header;
+
+ header = (ACPI_TABLE_HEADER *)table;
+ table_unmap(table, header->Length);
+}
+
+/*
+ * Return the physical address of the requested table or zero if one
+ * is not found.
+ */
+vm_paddr_t
+acpi_find_table(const char *sig)
+{
+ ACPI_PHYSICAL_ADDRESS rsdp_ptr;
+ ACPI_TABLE_RSDP *rsdp;
+ ACPI_TABLE_RSDT *rsdt;
+ ACPI_TABLE_XSDT *xsdt;
+ ACPI_TABLE_HEADER *table;
+ vm_paddr_t addr;
+ int i, count;
+
+ if (resource_disabled("acpi", 0))
+ return (0);
+
+ /*
+ * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn
+ * calls pmap_mapbios() to find the RSDP, we assume that we can use
+ * pmap_mapbios() to map the RSDP.
+ */
+ if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
+ return (0);
+ rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
+ if (rsdp == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map RSDP\n");
+ return (0);
+ }
+
+ /*
+ * For ACPI >= 2.0, use the XSDT if it is available.
+ * Otherwise, use the RSDT. We map the XSDT or RSDT at page 2
+ * in the crashdump area. Pages 0 and 1 are used to map in the
+ * headers of candidate ACPI tables.
+ */
+ addr = 0;
+ if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
+ /*
+ * AcpiOsGetRootPointer only verifies the checksum for
+ * the version 1.0 portion of the RSDP. Version 2.0 has
+ * an additional checksum that we verify first.
+ */
+ if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
+ if (bootverbose)
+ printf("ACPI: RSDP failed extended checksum\n");
+ return (0);
+ }
+ xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
+ if (xsdt == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map XSDT\n");
+ return (0);
+ }
+ count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+ sizeof(UINT64);
+ for (i = 0; i < count; i++)
+ if (probe_table(xsdt->TableOffsetEntry[i], sig)) {
+ addr = xsdt->TableOffsetEntry[i];
+ break;
+ }
+ acpi_unmap_table(xsdt);
+ } else {
+ rsdt = map_table(rsdp->RsdtPhysicalAddress, 2, ACPI_SIG_RSDT);
+ if (rsdt == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map RSDT\n");
+ return (0);
+ }
+ count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+ sizeof(UINT32);
+ for (i = 0; i < count; i++)
+ if (probe_table(rsdt->TableOffsetEntry[i], sig)) {
+ addr = rsdt->TableOffsetEntry[i];
+ break;
+ }
+ acpi_unmap_table(rsdt);
+ }
+ pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
+ if (addr == 0) {
+ if (bootverbose)
+ printf("ACPI: No %s table found\n", sig);
+ return (0);
+ }
+ if (bootverbose)
+ printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr);
+
+ /*
+ * Verify that we can map the full table and that its checksum is
+ * correct, etc.
+ */
+ table = map_table(addr, 0, sig);
+ if (table == NULL)
+ return (0);
+ acpi_unmap_table(table);
+
+ return (addr);
+}
+
+/*
* ACPI nexus(4) driver.
*/
static int
diff --git a/sys/amd64/acpica/madt.c b/sys/amd64/acpica/madt.c
index b27f8e4..a409682 100644
--- a/sys/amd64/acpica/madt.c
+++ b/sys/amd64/acpica/madt.c
@@ -36,27 +36,19 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/smp.h>
-
#include <vm/vm.h>
-#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <machine/apicreg.h>
-#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
-#include <machine/md_var.h>
-#include <machine/specialreg.h>
#include <contrib/dev/acpica/include/acpi.h>
-#include <contrib/dev/acpica/include/accommon.h>
#include <contrib/dev/acpica/include/actables.h>
#include <dev/acpica/acpivar.h>
#include <dev/pci/pcivar.h>
-typedef void madt_entry_handler(ACPI_SUBTABLE_HEADER *entry, void *arg);
-
/* These two arrays are indexed by APIC IDs. */
struct ioapic_info {
void *io_apic;
@@ -79,8 +71,6 @@ static enum intr_polarity interrupt_polarity(UINT16 IntiFlags, UINT8 Source);
static enum intr_trigger interrupt_trigger(UINT16 IntiFlags, UINT8 Source);
static int madt_find_cpu(u_int acpi_id, u_int *apic_id);
static int madt_find_interrupt(int intr, void **apic, u_int *pin);
-static void *madt_map(vm_paddr_t pa, int offset, vm_offset_t length);
-static void *madt_map_table(vm_paddr_t pa, int offset, const char *sig);
static void madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg);
static void madt_parse_interrupt_override(
ACPI_MADT_INTERRUPT_OVERRIDE *intr);
@@ -92,13 +82,10 @@ static int madt_probe(void);
static int madt_probe_cpus(void);
static void madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
void *arg __unused);
-static int madt_probe_table(vm_paddr_t address);
static void madt_register(void *dummy);
static int madt_setup_local(void);
static int madt_setup_io(void);
-static void madt_unmap(void *data, vm_offset_t length);
-static void madt_unmap_table(void *table);
-static void madt_walk_table(madt_entry_handler *handler, void *arg);
+static void madt_walk_table(acpi_subtable_handler *handler, void *arg);
static struct apic_enumerator madt_enumerator = {
"MADT",
@@ -109,224 +96,30 @@ static struct apic_enumerator madt_enumerator = {
};
/*
- * Code to abuse the crashdump map to map in the tables for the early
- * probe. We cheat and make the following assumptions about how we
- * use this KVA: pages 0 and 1 are used to map in the header of each
- * table found via the RSDT or XSDT and pages 2 to n are used to map
- * in the RSDT or XSDT. We have to use 2 pages for the table headers
- * in case a header spans a page boundary. The offset is in pages;
- * the length is in bytes.
- */
-static void *
-madt_map(vm_paddr_t pa, int offset, vm_offset_t length)
-{
- vm_offset_t va, off;
- void *data;
-
- off = pa & PAGE_MASK;
- length = roundup(length + off, PAGE_SIZE);
- pa = pa & PG_FRAME;
- va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
- (offset * PAGE_SIZE);
- data = (void *)(va + off);
- length -= PAGE_SIZE;
- while (length > 0) {
- va += PAGE_SIZE;
- pa += PAGE_SIZE;
- length -= PAGE_SIZE;
- pmap_kenter(va, pa);
- invlpg(va);
- }
- return (data);
-}
-
-static void
-madt_unmap(void *data, vm_offset_t length)
-{
- vm_offset_t va, off;
-
- va = (vm_offset_t)data;
- off = va & PAGE_MASK;
- length = roundup(length + off, PAGE_SIZE);
- va &= ~PAGE_MASK;
- while (length > 0) {
- pmap_kremove(va);
- invlpg(va);
- va += PAGE_SIZE;
- length -= PAGE_SIZE;
- }
-}
-
-static void *
-madt_map_table(vm_paddr_t pa, int offset, const char *sig)
-{
- ACPI_TABLE_HEADER *header;
- vm_offset_t length;
- void *table;
-
- header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
- if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
- madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
- return (NULL);
- }
- length = header->Length;
- madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
- table = madt_map(pa, offset, length);
- if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
- if (bootverbose)
- printf("MADT: Failed checksum for table %s\n", sig);
- madt_unmap(table, length);
- return (NULL);
- }
- return (table);
-}
-
-static void
-madt_unmap_table(void *table)
-{
- ACPI_TABLE_HEADER *header;
-
- header = (ACPI_TABLE_HEADER *)table;
- madt_unmap(table, header->Length);
-}
-
-/*
* Look for an ACPI Multiple APIC Description Table ("APIC")
*/
static int
madt_probe(void)
{
- ACPI_PHYSICAL_ADDRESS rsdp_ptr;
- ACPI_TABLE_RSDP *rsdp;
- ACPI_TABLE_RSDT *rsdt;
- ACPI_TABLE_XSDT *xsdt;
- int i, count;
- if (resource_disabled("acpi", 0))
+ madt_physaddr = acpi_find_table(ACPI_SIG_MADT);
+ if (madt_physaddr == 0)
return (ENXIO);
-
- /*
- * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn
- * calls pmap_mapbios() to find the RSDP, we assume that we can use
- * pmap_mapbios() to map the RSDP.
- */
- if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
- return (ENXIO);
- rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
- if (rsdp == NULL) {
- if (bootverbose)
- printf("MADT: Failed to map RSDP\n");
- return (ENXIO);
- }
-
- /*
- * For ACPI >= 2.0, use the XSDT if it is available.
- * Otherwise, use the RSDT. We map the XSDT or RSDT at page 1
- * in the crashdump area. Page 0 is used to map in the
- * headers of candidate ACPI tables.
- */
- if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
- /*
- * AcpiOsGetRootPointer only verifies the checksum for
- * the version 1.0 portion of the RSDP. Version 2.0 has
- * an additional checksum that we verify first.
- */
- if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
- if (bootverbose)
- printf("MADT: RSDP failed extended checksum\n");
- return (ENXIO);
- }
- xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 2,
- ACPI_SIG_XSDT);
- if (xsdt == NULL) {
- if (bootverbose)
- printf("MADT: Failed to map XSDT\n");
- return (ENXIO);
- }
- count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
- sizeof(UINT64);
- for (i = 0; i < count; i++)
- if (madt_probe_table(xsdt->TableOffsetEntry[i]))
- break;
- madt_unmap_table(xsdt);
- } else {
- rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 2,
- ACPI_SIG_RSDT);
- if (rsdt == NULL) {
- if (bootverbose)
- printf("MADT: Failed to map RSDT\n");
- return (ENXIO);
- }
- count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
- sizeof(UINT32);
- for (i = 0; i < count; i++)
- if (madt_probe_table(rsdt->TableOffsetEntry[i]))
- break;
- madt_unmap_table(rsdt);
- }
- pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
- if (madt_physaddr == 0) {
- if (bootverbose)
- printf("MADT: No MADT table found\n");
- return (ENXIO);
- }
- if (bootverbose)
- printf("MADT: Found table at 0x%jx\n",
- (uintmax_t)madt_physaddr);
-
- /*
- * Verify that we can map the full table and that its checksum is
- * correct, etc.
- */
- madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT);
- if (madt == NULL)
- return (ENXIO);
- madt_unmap_table(madt);
- madt = NULL;
-
return (0);
}
/*
- * See if a given ACPI table is the MADT.
- */
-static int
-madt_probe_table(vm_paddr_t address)
-{
- ACPI_TABLE_HEADER *table;
-
- table = madt_map(address, 0, sizeof(ACPI_TABLE_HEADER));
- if (table == NULL) {
- if (bootverbose)
- printf("MADT: Failed to map table at 0x%jx\n",
- (uintmax_t)address);
- return (0);
- }
- if (bootverbose)
- printf("Table '%.4s' at 0x%jx\n", table->Signature,
- (uintmax_t)address);
-
- if (strncmp(table->Signature, ACPI_SIG_MADT, ACPI_NAME_SIZE) != 0) {
- madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
- return (0);
- }
- madt_physaddr = address;
- madt_length = table->Length;
- madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
- return (1);
-}
-
-/*
* Run through the MP table enumerating CPUs.
*/
static int
madt_probe_cpus(void)
{
- madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT);
+ madt = acpi_map_table(madt_physaddr, ACPI_SIG_MADT);
+ madt_length = madt->Header.Length;
KASSERT(madt != NULL, ("Unable to re-map MADT"));
madt_walk_table(madt_probe_cpus_handler, NULL);
- madt_unmap_table(madt);
+ acpi_unmap_table(madt);
madt = NULL;
return (0);
}
@@ -417,17 +210,11 @@ SYSINIT(madt_register, SI_SUB_TUNABLES - 1, SI_ORDER_FIRST,
* Call the handler routine for each entry in the MADT table.
*/
static void
-madt_walk_table(madt_entry_handler *handler, void *arg)
+madt_walk_table(acpi_subtable_handler *handler, void *arg)
{
- ACPI_SUBTABLE_HEADER *entry;
- u_char *p, *end;
-
- end = (u_char *)(madt) + madt->Header.Length;
- for (p = (u_char *)(madt + 1); p < end; ) {
- entry = (ACPI_SUBTABLE_HEADER *)p;
- handler(entry, arg);
- p += entry->Length;
- }
+
+ acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
+ handler, arg);
}
static void
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 0bfd7ad..95db5d2 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1192,6 +1192,77 @@ isa_irq_pending(void)
u_int basemem;
+static int
+add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
+{
+ int i, insert_idx, physmap_idx;
+
+ physmap_idx = *physmap_idxp;
+
+ if (boothowto & RB_VERBOSE)
+ printf("SMAP type=%02x base=%016lx len=%016lx\n",
+ smap->type, smap->base, smap->length);
+
+ if (smap->type != SMAP_TYPE_MEMORY)
+ return (1);
+
+ if (smap->length == 0)
+ return (0);
+
+ /*
+ * Find insertion point while checking for overlap. Start off by
+ * assuming the new entry will be added to the end.
+ */
+ insert_idx = physmap_idx + 2;
+ for (i = 0; i <= physmap_idx; i += 2) {
+ if (smap->base < physmap[i + 1]) {
+ if (smap->base + smap->length <= physmap[i]) {
+ insert_idx = i;
+ break;
+ }
+ if (boothowto & RB_VERBOSE)
+ printf(
+ "Overlapping memory regions, ignoring second region\n");
+ return (1);
+ }
+ }
+
+ /* See if we can prepend to the next entry. */
+ if (insert_idx <= physmap_idx &&
+ smap->base + smap->length == physmap[insert_idx]) {
+ physmap[insert_idx] = smap->base;
+ return (1);
+ }
+
+ /* See if we can append to the previous entry. */
+ if (insert_idx > 0 && smap->base == physmap[insert_idx - 1]) {
+ physmap[insert_idx - 1] += smap->length;
+ return (1);
+ }
+
+ physmap_idx += 2;
+ *physmap_idxp = physmap_idx;
+ if (physmap_idx == PHYSMAP_SIZE) {
+ printf(
+ "Too many segments in the physical address map, giving up\n");
+ return (0);
+ }
+
+ /*
+ * Move the last 'N' entries down to make room for the new
+ * entry if needed.
+ */
+ for (i = physmap_idx; i > insert_idx; i -= 2) {
+ physmap[i] = physmap[i - 2];
+ physmap[i + 1] = physmap[i - 1];
+ }
+
+ /* Insert the new entry. */
+ physmap[insert_idx] = smap->base;
+ physmap[insert_idx + 1] = smap->base + smap->length;
+ return (1);
+}
+
/*
* Populate the (physmap) array with base/bound pairs describing the
* available physical memory in the system, then test this memory and
@@ -1235,40 +1306,9 @@ getmemsize(caddr_t kmdp, u_int64_t first)
smapsize = *((u_int32_t *)smapbase - 1);
smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize);
- for (smap = smapbase; smap < smapend; smap++) {
- if (boothowto & RB_VERBOSE)
- printf("SMAP type=%02x base=%016lx len=%016lx\n",
- smap->type, smap->base, smap->length);
-
- if (smap->type != SMAP_TYPE_MEMORY)
- continue;
-
- if (smap->length == 0)
- continue;
-
- for (i = 0; i <= physmap_idx; i += 2) {
- if (smap->base < physmap[i + 1]) {
- if (boothowto & RB_VERBOSE)
- printf(
- "Overlapping or non-monotonic memory region, ignoring second region\n");
- continue;
- }
- }
-
- if (smap->base == physmap[physmap_idx + 1]) {
- physmap[physmap_idx + 1] += smap->length;
- continue;
- }
-
- physmap_idx += 2;
- if (physmap_idx == PHYSMAP_SIZE) {
- printf(
- "Too many segments in the physical address map, giving up\n");
+ for (smap = smapbase; smap < smapend; smap++)
+ if (!add_smap_entry(smap, physmap, &physmap_idx))
break;
- }
- physmap[physmap_idx] = smap->base;
- physmap[physmap_idx + 1] = smap->base + smap->length;
- }
/*
* Find the 'base memory' segment for SMP
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 4febfb3..1f377651 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -701,6 +701,11 @@ pmap_init(void)
* Are large page mappings enabled?
*/
TUNABLE_INT_FETCH("vm.pmap.pg_ps_enabled", &pg_ps_enabled);
+ if (pg_ps_enabled) {
+ KASSERT(MAXPAGESIZES > 1 && pagesizes[1] == 0,
+ ("pmap_init: can't assign to pagesizes[1]"));
+ pagesizes[1] = NBPDR;
+ }
/*
* Calculate the size of the pv head table for superpages.
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 65f761e..c97985d 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -253,6 +253,11 @@ trap(struct trapframe *frame)
}
#endif
+ if (type == T_RESERVED) {
+ trap_fatal(frame, 0);
+ goto out;
+ }
+
#ifdef HWPMC_HOOKS
/*
* CPU PMCs interrupt using an NMI. If the PMC module is
@@ -500,8 +505,11 @@ trap(struct trapframe *frame)
* XXX this should be fatal unless the kernel has
* registered such use.
*/
- fpudna();
printf("fpudna in kernel mode!\n");
+#ifdef KDB
+ kdb_backtrace();
+#endif
+ fpudna();
goto out;
case T_STKFLT: /* stack fault */
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index ada5e32..f3619cf 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -154,12 +154,17 @@ options AGP_DEBUG
#####################################################################
# HARDWARE DEVICE CONFIGURATION
-# To include support for VGA VESA video modes (depends on X86EMU)
+# To include support for VGA VESA video modes
options VESA
# Turn on extra debugging checks and output for VESA support.
options VESA_DEBUG
+device dpms # DPMS suspend & resume via VESA BIOS
+
+# x86 real mode BIOS emulator, required by atkbdc/dpms/vesa
+options X86BIOS
+
#
# Optional devices:
#
@@ -219,6 +224,9 @@ options VGA_WIDTH90 # support 90 column modes
# Debugging.
options VGA_DEBUG
+# Linear framebuffer driver for S3 VESA 1.2 cards. Works on top of VESA.
+device s3pci
+
# 3Dfx Voodoo Graphics, Voodoo II /dev/3dfx CDEV support. This will create
# the /dev/3dfx0 device to work with glide implementations. This should get
# linked to /dev/3dfx and /dev/voodoo. Note that this is not the same as
diff --git a/sys/amd64/include/acpica_machdep.h b/sys/amd64/include/acpica_machdep.h
index 76cc69e..9943af7 100644
--- a/sys/amd64/include/acpica_machdep.h
+++ b/sys/amd64/include/acpica_machdep.h
@@ -77,5 +77,8 @@ extern int acpi_release_global_lock(uint32_t *lock);
void acpi_SetDefaultIntrModel(int model);
void acpi_cpu_c1(void);
+void *acpi_map_table(vm_paddr_t pa, const char *sig);
+void acpi_unmap_table(void *table);
+vm_paddr_t acpi_find_table(const char *sig);
#endif /* __ACPICA_MACHDEP_H__ */
diff --git a/sys/amd64/include/param.h b/sys/amd64/include/param.h
index f9b6bd8..3ede601 100644
--- a/sys/amd64/include/param.h
+++ b/sys/amd64/include/param.h
@@ -108,6 +108,8 @@
#define NBPML4 (1ul<<PML4SHIFT)/* bytes/page map lev4 table */
#define PML4MASK (NBPML4-1)
+#define MAXPAGESIZES 3 /* maximum number of supported page sizes */
+
#define IOPAGES 2 /* pages of i/o permission bitmap */
#ifndef KSTACK_PAGES
diff --git a/sys/amd64/pci/pci_cfgreg.c b/sys/amd64/pci/pci_cfgreg.c
index be9e404..3e29a58 100644
--- a/sys/amd64/pci/pci_cfgreg.c
+++ b/sys/amd64/pci/pci_cfgreg.c
@@ -181,9 +181,9 @@ pci_cfgenable(unsigned bus, unsigned slot, unsigned func, int reg, int bytes)
{
int dataport = 0;
- if (bus <= PCI_BUSMAX && slot < 32 && func <= PCI_FUNCMAX &&
- reg <= PCI_REGMAX && bytes != 3 && (unsigned) bytes <= 4 &&
- (reg & (bytes - 1)) == 0) {
+ if (bus <= PCI_BUSMAX && slot <= PCI_SLOTMAX && func <= PCI_FUNCMAX &&
+ (unsigned)reg <= PCI_REGMAX && bytes != 3 &&
+ (unsigned)bytes <= 4 && (reg & (bytes - 1)) == 0) {
outl(CONF1_ADDR_PORT, (1 << 31) | (bus << 16) | (slot << 11)
| (func << 8) | (reg & ~0x03));
dataport = CONF1_DATA_PORT + (reg & 0x03);
@@ -281,7 +281,7 @@ pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus)
* fall back to using type 1 config access instead.
*/
if (pci_cfgregopen() != 0) {
- for (slot = 0; slot < 32; slot++) {
+ for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
val1 = pcireg_cfgread(0, slot, 0, 0, 4);
if (val1 == 0xffffffff)
continue;
@@ -309,8 +309,8 @@ pciereg_cfgread(int bus, unsigned slot, unsigned func, unsigned reg,
volatile vm_offset_t va;
int data = -1;
- if (bus < pcie_minbus || bus > pcie_maxbus || slot >= 32 ||
- func > PCI_FUNCMAX || reg >= 0x1000)
+ if (bus < pcie_minbus || bus > pcie_maxbus || slot > PCI_SLOTMAX ||
+ func > PCI_FUNCMAX || reg > PCIE_REGMAX)
return (-1);
va = PCIE_VADDR(pcie_base, reg, bus, slot, func);
@@ -336,8 +336,8 @@ pciereg_cfgwrite(int bus, unsigned slot, unsigned func, unsigned reg, int data,
{
volatile vm_offset_t va;
- if (bus < pcie_minbus || bus > pcie_maxbus || slot >= 32 ||
- func > PCI_FUNCMAX || reg >= 0x1000)
+ if (bus < pcie_minbus || bus > pcie_maxbus || slot > PCI_SLOTMAX ||
+ func > PCI_FUNCMAX || reg > PCIE_REGMAX)
return;
va = PCIE_VADDR(pcie_base, reg, bus, slot, func);
diff --git a/sys/arm/include/param.h b/sys/arm/include/param.h
index 2161103..1694bc4 100644
--- a/sys/arm/include/param.h
+++ b/sys/arm/include/param.h
@@ -92,6 +92,8 @@
#define NBPDR (1 << PDR_SHIFT)
#define NPDEPG (1 << (32 - PDR_SHIFT))
+#define MAXPAGESIZES 1 /* maximum number of supported page sizes */
+
#ifndef KSTACK_PAGES
#define KSTACK_PAGES 2
#endif /* !KSTACK_PAGES */
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index c4e0b04..9137c55 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -1034,8 +1034,13 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
cam_error_print(saved_ccb, CAM_ESF_ALL,
CAM_EPF_ALL);
#endif
- xpt_done_ccb = TRUE;
+ } else {
+ saved_ccb->ccb_h.status &=
+ ~CAM_STATUS_MASK;
+ saved_ccb->ccb_h.status |=
+ CAM_AUTOSENSE_FAIL;
}
+ xpt_done_ccb = TRUE;
}
}
bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb,
diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c
index 428c97b..939e3f7 100644
--- a/sys/cam/scsi/scsi_target.c
+++ b/sys/cam/scsi/scsi_target.c
@@ -42,6 +42,9 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/devicestat.h>
#include <sys/proc.h>
+/* Includes to support callout */
+#include <sys/types.h>
+#include <sys/systm.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@@ -50,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_sim.h>
#include <cam/scsi/scsi_targetio.h>
+
/* Transaction information attached to each CCB sent by the user */
struct targ_cmd_descr {
struct cam_periph_map_info mapinfo;
@@ -92,6 +96,8 @@ struct targ_softc {
targ_state state;
struct selinfo read_select;
struct devstat device_stats;
+ struct callout destroy_dev_callout;
+ struct mtx destroy_mtx;
};
static d_open_t targopen;
@@ -154,6 +160,7 @@ static void abort_all_pending(struct targ_softc *softc);
static void notify_user(struct targ_softc *softc);
static int targcamstatus(cam_status status);
static size_t targccblen(xpt_opcode func_code);
+static void targdestroy(void *);
static struct periph_driver targdriver =
{
@@ -211,10 +218,18 @@ targclose(struct cdev *dev, int flag, int fmt, struct thread *td)
int error;
softc = (struct targ_softc *)dev->si_drv1;
- if ((softc->periph == NULL) ||
- (softc->state & TARG_STATE_LUN_ENABLED) == 0) {
+ mtx_init(&softc->destroy_mtx, "targ_destroy", "SCSI Target dev destroy", MTX_DEF);
+ callout_init_mtx(&softc->destroy_dev_callout, &softc->destroy_mtx, CALLOUT_RETURNUNLOCKED);
+ if (softc->periph == NULL) {
+#if 0
destroy_dev(dev);
free(softc, M_TARG);
+#endif
+ printf("%s: destroying non-enabled target\n", __func__);
+ mtx_lock(&softc->destroy_mtx);
+ callout_reset(&softc->destroy_dev_callout, hz / 2,
+ (void *)targdestroy, (void *)dev);
+ mtx_unlock(&softc->destroy_mtx);
return (0);
}
@@ -226,18 +241,23 @@ targclose(struct cdev *dev, int flag, int fmt, struct thread *td)
cam_periph_acquire(periph);
cam_periph_lock(periph);
error = targdisable(softc);
- if (error == CAM_REQ_CMP) {
- dev->si_drv1 = 0;
- if (softc->periph != NULL) {
- cam_periph_invalidate(softc->periph);
- softc->periph = NULL;
- }
- destroy_dev(dev);
- free(softc, M_TARG);
+ if (softc->periph != NULL) {
+ cam_periph_invalidate(softc->periph);
+ softc->periph = NULL;
}
cam_periph_unlock(periph);
cam_periph_release(periph);
+#if 0
+ destroy_dev(dev);
+ free(softc, M_TARG);
+#endif
+
+ printf("%s: close finished error(%d)\n", __func__, error);
+ mtx_lock(&softc->destroy_mtx);
+ callout_reset(&softc->destroy_dev_callout, hz / 2,
+ (void *)targdestroy, (void *)dev);
+ mtx_unlock(&softc->destroy_mtx);
return (error);
}
@@ -821,7 +841,9 @@ targdone(struct cam_periph *periph, union ccb *done_ccb)
case XPT_CONT_TARGET_IO:
TAILQ_INSERT_TAIL(&softc->user_ccb_queue, &done_ccb->ccb_h,
periph_links.tqe);
+ cam_periph_unlock(softc->periph);
notify_user(softc);
+ cam_periph_lock(softc->periph);
break;
default:
panic("targdone: impossible xpt opcode %#x",
@@ -969,13 +991,19 @@ targgetccb(struct targ_softc *softc, xpt_opcode type, int priority)
int ccb_len;
ccb_len = targccblen(type);
- ccb = malloc(ccb_len, M_TARG, M_WAITOK);
+ ccb = malloc(ccb_len, M_TARG, M_NOWAIT);
CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("getccb %p\n", ccb));
-
+ if (ccb == NULL) {
+ return (ccb);
+ }
xpt_setup_ccb(&ccb->ccb_h, softc->path, priority);
ccb->ccb_h.func_code = type;
ccb->ccb_h.cbfcnp = targdone;
ccb->ccb_h.targ_descr = targgetdescr(softc);
+ if (ccb->ccb_h.targ_descr == NULL) {
+ free (ccb, M_TARG);
+ ccb = NULL;
+ }
return (ccb);
}
@@ -1013,8 +1041,10 @@ targgetdescr(struct targ_softc *softc)
struct targ_cmd_descr *descr;
descr = malloc(sizeof(*descr), M_TARG,
- M_WAITOK);
- descr->mapinfo.num_bufs_used = 0;
+ M_NOWAIT);
+ if (descr) {
+ descr->mapinfo.num_bufs_used = 0;
+ }
return (descr);
}
@@ -1094,8 +1124,11 @@ abort_all_pending(struct targ_softc *softc)
/* If we aborted anything from the work queue, wakeup user. */
if (!TAILQ_EMPTY(&softc->user_ccb_queue)
- || !TAILQ_EMPTY(&softc->abort_queue))
+ || !TAILQ_EMPTY(&softc->abort_queue)) {
+ cam_periph_unlock(softc->periph);
notify_user(softc);
+ cam_periph_lock(softc->periph);
+ }
}
/* Notify the user that data is ready */
@@ -1188,3 +1221,25 @@ targccblen(xpt_opcode func_code)
return (len);
}
+
+/*
+ * work around to destroy targ device
+ * outside of targclose
+ */
+static void
+targdestroy(void *dev)
+{
+ struct cdev *device = (struct cdev *)dev;
+ struct targ_softc *softc = (struct targ_softc *)device->si_drv1;
+
+#if 0
+ callout_stop(&softc->destroy_dev_callout);
+#endif
+
+ mtx_unlock(&softc->destroy_mtx);
+ mtx_destroy(&softc->destroy_mtx);
+ free(softc, M_TARG);
+ device->si_drv1 = 0;
+ destroy_dev(device);
+ printf("%s: destroyed dev\n", __func__);
+}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/fletcher.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/fletcher.c
index edda3c9..54247d7 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/fletcher.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/fletcher.c
@@ -19,11 +19,111 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Fletcher Checksums
+ * ------------------
+ *
+ * ZFS's 2nd and 4th order Fletcher checksums are defined by the following
+ * recurrence relations:
+ *
+ * a = a + f
+ * i i-1 i-1
+ *
+ * b = b + a
+ * i i-1 i
+ *
+ * c = c + b (fletcher-4 only)
+ * i i-1 i
+ *
+ * d = d + c (fletcher-4 only)
+ * i i-1 i
+ *
+ * Where
+ * a_0 = b_0 = c_0 = d_0 = 0
+ * and
+ * f_0 .. f_(n-1) are the input data.
+ *
+ * Using standard techniques, these translate into the following series:
+ *
+ * __n_ __n_
+ * \ | \ |
+ * a = > f b = > i * f
+ * n /___| n - i n /___| n - i
+ * i = 1 i = 1
+ *
+ *
+ * __n_ __n_
+ * \ | i*(i+1) \ | i*(i+1)*(i+2)
+ * c = > ------- f d = > ------------- f
+ * n /___| 2 n - i n /___| 6 n - i
+ * i = 1 i = 1
+ *
+ * For fletcher-2, the f_is are 64-bit, and [ab]_i are 64-bit accumulators.
+ * Since the additions are done mod (2^64), errors in the high bits may not
+ * be noticed. For this reason, fletcher-2 is deprecated.
+ *
+ * For fletcher-4, the f_is are 32-bit, and [abcd]_i are 64-bit accumulators.
+ * A conservative estimate of how big the buffer can get before we overflow
+ * can be estimated using f_i = 0xffffffff for all i:
+ *
+ * % bc
+ * f=2^32-1;d=0; for (i = 1; d<2^64; i++) { d += f*i*(i+1)*(i+2)/6 }; (i-1)*4
+ * 2264
+ * quit
+ * %
+ *
+ * So blocks of up to 2k will not overflow. Our largest block size is
+ * 128k, which has 32k 4-byte words, so we can compute the largest possible
+ * accumulators, then divide by 2^64 to figure the max amount of overflow:
+ *
+ * % bc
+ * a=b=c=d=0; f=2^32-1; for (i=1; i<=32*1024; i++) { a+=f; b+=a; c+=b; d+=c }
+ * a/2^64;b/2^64;c/2^64;d/2^64
+ * 0
+ * 0
+ * 1365
+ * 11186858
+ * quit
+ * %
+ *
+ * So a and b cannot overflow. To make sure each bit of input has some
+ * effect on the contents of c and d, we can look at what the factors of
+ * the coefficients in the equations for c_n and d_n are. The number of 2s
+ * in the factors determines the lowest set bit in the multiplier. Running
+ * through the cases for n*(n+1)/2 reveals that the highest power of 2 is
+ * 2^14, and for n*(n+1)*(n+2)/6 it is 2^15. So while some data may overflow
+ * the 64-bit accumulators, every bit of every f_i effects every accumulator,
+ * even for 128k blocks.
+ *
+ * If we wanted to make a stronger version of fletcher4 (fletcher4c?),
+ * we could do our calculations mod (2^32 - 1) by adding in the carries
+ * periodically, and store the number of carries in the top 32-bits.
+ *
+ * --------------------
+ * Checksum Performance
+ * --------------------
+ *
+ * There are two interesting components to checksum performance: cached and
+ * uncached performance. With cached data, fletcher-2 is about four times
+ * faster than fletcher-4. With uncached data, the performance difference is
+ * negligible, since the cost of a cache fill dominates the processing time.
+ * Even though fletcher-4 is slower than fletcher-2, it is still a pretty
+ * efficient pass over the data.
+ *
+ * In normal operation, the data which is being checksummed is in a buffer
+ * which has been filled either by:
+ *
+ * 1. a compression step, which will be mostly cached, or
+ * 2. a bcopy() or copyin(), which will be uncached (because the
+ * copy is cache-bypassing).
+ *
+ * For both cached and uncached data, both fletcher checksums are much faster
+ * than sha-256, and slower than 'off', which doesn't touch the data at all.
+ */
#include <sys/types.h>
#include <sys/sysmacros.h>
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
index bb1c9da..185f7d2 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
@@ -255,6 +255,7 @@ VTOZ(vnode_t *vp)
/*
* ZFS_ENTER() is called on entry to each ZFS vnode and vfs operation.
+ * ZFS_ENTER_NOERROR() is called when we can't return EIO.
* ZFS_EXIT() must be called before exitting the vop.
* ZFS_VERIFY_ZP() verifies the znode is valid.
*/
@@ -267,6 +268,9 @@ VTOZ(vnode_t *vp)
} \
}
+#define ZFS_ENTER_NOERROR(zfsvfs) \
+ rrw_enter(&(zfsvfs)->z_teardown_lock, RW_READER, FTAG)
+
#define ZFS_EXIT(zfsvfs) rrw_exit(&(zfsvfs)->z_teardown_lock, FTAG)
#define ZFS_VERIFY_ZP(zp) \
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
index 6331567..fbc8c45 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
@@ -76,7 +76,7 @@ enum zio_checksum {
ZIO_CHECKSUM_FUNCTIONS
};
-#define ZIO_CHECKSUM_ON_VALUE ZIO_CHECKSUM_FLETCHER_2
+#define ZIO_CHECKSUM_ON_VALUE ZIO_CHECKSUM_FLETCHER_4
#define ZIO_CHECKSUM_DEFAULT ZIO_CHECKSUM_ON
enum zio_compress {
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
index d466273..a43d85c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
@@ -1841,7 +1841,7 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
fgid = zfs_fuid_create_cred(zfsvfs,
ZFS_GROUP, tx, cr, fuidp);
#ifdef __FreeBSD__
- gid = parent->z_phys->zp_gid;
+ gid = fgid = parent->z_phys->zp_gid;
#else
gid = crgetgid(cr);
#endif
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 185d84b..b9a4b2f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -864,7 +864,7 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp)
znode_t *rootzp;
int error;
- ZFS_ENTER(zfsvfs);
+ ZFS_ENTER_NOERROR(zfsvfs);
error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp);
if (error == 0) {
@@ -898,6 +898,9 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
* 'z_parent' is self referential for non-snapshots.
*/
(void) dnlc_purge_vfsp(zfsvfs->z_parent->z_vfs, 0);
+#ifdef FREEBSD_NAMECACHE
+ cache_purgevfs(zfsvfs->z_parent->z_vfs);
+#endif
}
/*
@@ -1027,6 +1030,17 @@ zfs_umount(vfs_t *vfsp, int fflag)
ASSERT(zfsvfs->z_ctldir == NULL);
}
+ if (fflag & MS_FORCE) {
+ /*
+ * Mark file system as unmounted before calling
+ * vflush(FORCECLOSE). This way we ensure no future vnops
+ * will be called and risk operating on DOOMED vnodes.
+ */
+ rrw_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG);
+ zfsvfs->z_unmounted = B_TRUE;
+ rrw_exit(&zfsvfs->z_teardown_lock, FTAG);
+ }
+
/*
* Flush all the files.
*/
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
index 0753fe9..a761c81 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
@@ -4860,7 +4860,7 @@ zfs_freebsd_getacl(ap)
vsecattr_t vsecattr;
if (ap->a_type != ACL_TYPE_NFS4)
- return (EOPNOTSUPP);
+ return (EINVAL);
vsecattr.vsa_mask = VSA_ACE | VSA_ACECNT;
if (error = zfs_getsecattr(ap->a_vp, &vsecattr, 0, ap->a_cred, NULL))
@@ -4889,7 +4889,7 @@ zfs_freebsd_setacl(ap)
aclent_t *aaclp;
if (ap->a_type != ACL_TYPE_NFS4)
- return (EOPNOTSUPP);
+ return (EINVAL);
if (ap->a_aclp->acl_cnt < 1 || ap->a_aclp->acl_cnt > MAX_ACL_ENTRIES)
return (EINVAL);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
index 082198f..c43a850 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
@@ -890,17 +890,25 @@ again:
if (zp->z_unlinked) {
err = ENOENT;
} else {
- if ((vp = ZTOV(zp)) != NULL) {
- VI_LOCK(vp);
+ int dying = 0;
+
+ vp = ZTOV(zp);
+ if (vp == NULL)
+ dying = 1;
+ else {
+ VN_HOLD(vp);
if ((vp->v_iflag & VI_DOOMED) != 0) {
- VI_UNLOCK(vp);
- vp = NULL;
- } else
- VI_UNLOCK(vp);
+ dying = 1;
+ /*
+ * Don't VN_RELE() vnode here, because
+ * it can call vn_lock() which creates
+ * LOR between vnode lock and znode
+ * lock. We will VN_RELE() the vnode
+ * after droping znode lock.
+ */
+ }
}
- if (vp != NULL)
- VN_HOLD(vp);
- else {
+ if (dying) {
if (first) {
ZFS_LOG(1, "dying znode detected (zp=%p)", zp);
first = 0;
@@ -912,6 +920,8 @@ again:
dmu_buf_rele(db, NULL);
mutex_exit(&zp->z_lock);
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
+ if (vp != NULL)
+ VN_RELE(vp);
tsleep(zp, 0, "zcollide", 1);
goto again;
}
diff --git a/sys/compat/x86bios/x86bios.c b/sys/compat/x86bios/x86bios.c
new file mode 100644
index 0000000..b187ae9
--- /dev/null
+++ b/sys/compat/x86bios/x86bios.c
@@ -0,0 +1,196 @@
+/*-
+ * Written by paradox <ddkprog@yahoo.com>
+ * Public domain.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_x86bios.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/cpufunc.h>
+
+#include <contrib/x86emu/x86emu.h>
+#include <contrib/x86emu/x86emu_regs.h>
+#include <compat/x86bios/x86bios.h>
+
+u_char *pbiosMem = NULL;
+static u_char *pbiosStack = NULL;
+
+int busySegMap[5];
+
+static struct x86emu x86bios_emu;
+
+static struct mtx x86bios_lock;
+
+static uint8_t
+x86bios_emu_inb(struct x86emu *emu, uint16_t port)
+{
+
+ if (port == 0xb2) /* APM scratch register */
+ return (0);
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return (0);
+ return (inb(port));
+}
+
+static uint16_t
+x86bios_emu_inw(struct x86emu *emu, uint16_t port)
+{
+
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return (0);
+ return (inw(port));
+}
+
+static uint32_t
+x86bios_emu_inl(struct x86emu *emu, uint16_t port)
+{
+
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return (0);
+ return (inl(port));
+}
+
+static void
+x86bios_emu_outb(struct x86emu *emu, uint16_t port, uint8_t val)
+{
+
+ if (port == 0xb2) /* APM scratch register */
+ return;
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return;
+ outb(port, val);
+}
+
+static void
+x86bios_emu_outw(struct x86emu *emu, uint16_t port, uint16_t val)
+{
+
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return;
+ outw(port, val);
+}
+
+static void
+x86bios_emu_outl(struct x86emu *emu, uint16_t port, uint32_t val)
+{
+
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return;
+ outl(port, val);
+}
+
+void
+x86bios_intr(struct x86regs *regs, int intno)
+{
+
+ if (intno < 0 || intno > 255)
+ return;
+
+ if (bootverbose)
+ printf("Calling int 0x%x (ax=0x%04x bx=0x%04x "
+ "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n",
+ intno, regs->R_AX, regs->R_BX, regs->R_CX,
+ regs->R_DX, regs->R_ES, regs->R_DI);
+
+ mtx_lock_spin(&x86bios_lock);
+
+ memcpy(&x86bios_emu.x86, regs, sizeof(*regs));
+ x86emu_exec_intr(&x86bios_emu, intno);
+ memcpy(regs, &x86bios_emu.x86, sizeof(*regs));
+
+ mtx_unlock_spin(&x86bios_lock);
+
+ if (bootverbose)
+ printf("Exiting int 0x%x (ax=0x%04x bx=0x%04x "
+ "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n",
+ intno, regs->R_AX, regs->R_BX, regs->R_CX,
+ regs->R_DX, regs->R_ES, regs->R_DI);
+}
+
+void *
+x86bios_offset(uint32_t offs)
+{
+
+ return (pbiosMem + offs);
+}
+
+static void
+x86bios_init(void *arg __unused)
+{
+ int offs;
+
+ mtx_init(&x86bios_lock, "x86bios lock", NULL, MTX_SPIN);
+
+ /* Can pbiosMem be NULL here? */
+ pbiosMem = pmap_mapbios(0x0, MAPPED_MEMORY_SIZE);
+
+ memset(&x86bios_emu, 0, sizeof(x86bios_emu));
+ x86emu_init_default(&x86bios_emu);
+
+ x86bios_emu.emu_inb = x86bios_emu_inb;
+ x86bios_emu.emu_inw = x86bios_emu_inw;
+ x86bios_emu.emu_inl = x86bios_emu_inl;
+ x86bios_emu.emu_outb = x86bios_emu_outb;
+ x86bios_emu.emu_outw = x86bios_emu_outw;
+ x86bios_emu.emu_outl = x86bios_emu_outl;
+
+ x86bios_emu.mem_base = (char *)pbiosMem;
+ x86bios_emu.mem_size = MAPPED_MEMORY_SIZE;
+
+ memset(busySegMap, 0, sizeof(busySegMap));
+
+ pbiosStack = x86bios_alloc(1, &offs);
+}
+
+static void
+x86bios_uninit(void *arg __unused)
+{
+
+ x86bios_free(pbiosStack, 1);
+
+ if (pbiosMem)
+ pmap_unmapdev((vm_offset_t)pbiosMem,
+ MAPPED_MEMORY_SIZE);
+
+ mtx_destroy(&x86bios_lock);
+}
+
+static int
+x86bios_modevent(module_t mod __unused, int type, void *data __unused)
+{
+ int err = 0;
+
+ switch (type) {
+ case MOD_LOAD:
+ x86bios_init(NULL);
+ break;
+ case MOD_UNLOAD:
+ x86bios_uninit(NULL);
+ break;
+ default:
+ err = ENOTSUP;
+ break;
+ }
+
+ return (err);
+}
+
+static moduledata_t x86bios_mod = {
+ "x86bios",
+ x86bios_modevent,
+ NULL,
+};
+
+DECLARE_MODULE(x86bios, x86bios_mod, SI_SUB_CPU, SI_ORDER_ANY);
+MODULE_VERSION(x86bios, 1);
diff --git a/sys/compat/x86bios/x86bios.h b/sys/compat/x86bios/x86bios.h
new file mode 100644
index 0000000..35cbbce
--- /dev/null
+++ b/sys/compat/x86bios/x86bios.h
@@ -0,0 +1,134 @@
+/*-
+ * Written by paradox <ddkprog@yahoo.com>
+ * Public domain.
+ *
+ * x86 registers were borrowed from x86emu.h x86emu_regs.h
+ * for compatability.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _X86BIOS_H_
+#define _X86BIOS_H_
+
+#include <sys/types.h>
+#include <sys/endian.h>
+#include <sys/systm.h>
+
+#ifdef __BIG_ENDIAN__
+
+struct x86_register32 {
+ uint32_t e_reg;
+};
+
+struct x86_register16 {
+ uint16_t filler0;
+ uint16_t x_reg;
+};
+
+struct x86_register8 {
+ uint8_t filler0, filler1;
+ uint8_t h_reg, l_reg;
+};
+
+#else /* !__BIG_ENDIAN__ */
+
+struct x86_register32 {
+ uint32_t e_reg;
+};
+
+struct x86_register16 {
+ uint16_t x_reg;
+};
+
+struct x86_register8 {
+ uint8_t l_reg, h_reg;
+};
+
+#endif /* __BIG_ENDIAN__ */
+
+union x86_register {
+ struct x86_register32 I32_reg;
+ struct x86_register16 I16_reg;
+ struct x86_register8 I8_reg;
+};
+
+struct x86regs {
+ uint16_t padding; /* CS is unused. */
+ uint16_t register_ds;
+ uint16_t register_es;
+ uint16_t register_fs;
+ uint16_t register_gs;
+ uint16_t register_ss;
+ uint32_t register_flags;
+ union x86_register register_a;
+ union x86_register register_b;
+ union x86_register register_c;
+ union x86_register register_d;
+
+ union x86_register register_sp;
+ union x86_register register_bp;
+ union x86_register register_si;
+ union x86_register register_di;
+};
+
+typedef struct x86regs x86regs_t;
+
+/* 8 bit registers */
+#define R_AH register_a.I8_reg.h_reg
+#define R_AL register_a.I8_reg.l_reg
+#define R_BH register_b.I8_reg.h_reg
+#define R_BL register_b.I8_reg.l_reg
+#define R_CH register_c.I8_reg.h_reg
+#define R_CL register_c.I8_reg.l_reg
+#define R_DH register_d.I8_reg.h_reg
+#define R_DL register_d.I8_reg.l_reg
+
+/* 16 bit registers */
+#define R_AX register_a.I16_reg.x_reg
+#define R_BX register_b.I16_reg.x_reg
+#define R_CX register_c.I16_reg.x_reg
+#define R_DX register_d.I16_reg.x_reg
+
+/* 32 bit extended registers */
+#define R_EAX register_a.I32_reg.e_reg
+#define R_EBX register_b.I32_reg.e_reg
+#define R_ECX register_c.I32_reg.e_reg
+#define R_EDX register_d.I32_reg.e_reg
+
+/* special registers */
+#define R_SP register_sp.I16_reg.x_reg
+#define R_BP register_bp.I16_reg.x_reg
+#define R_SI register_si.I16_reg.x_reg
+#define R_DI register_di.I16_reg.x_reg
+#define R_FLG register_flags
+
+/* special registers */
+#define R_ESP register_sp.I32_reg.e_reg
+#define R_EBP register_bp.I32_reg.e_reg
+#define R_ESI register_si.I32_reg.e_reg
+#define R_EDI register_di.I32_reg.e_reg
+#define R_EFLG register_flags
+
+/* segment registers */
+#define R_DS register_ds
+#define R_SS register_ss
+#define R_ES register_es
+#define R_FS register_fs
+#define R_GS register_gs
+
+#define SEG_ADDR(x) (((x) >> 4) & 0x00F000)
+#define SEG_OFF(x) ((x) & 0x0FFFF)
+#define FARP(x) ((le32toh(x) & 0xffff) + ((le32toh(x) >> 12) & 0xffff00))
+
+#define MAPPED_MEMORY_SIZE (1024 * 1024)
+#define PAGE_RESERV (4096 * 5)
+
+__BEGIN_DECLS
+void *x86bios_alloc(int count, int *segs);
+void x86bios_free(void *pbuf, int count);
+void x86bios_intr(struct x86regs *regs, int intno);
+void *x86bios_offset(uint32_t offs);
+__END_DECLS
+
+#endif /* !_X86BIOS_H_ */
diff --git a/sys/compat/x86bios/x86bios_alloc.c b/sys/compat/x86bios/x86bios_alloc.c
new file mode 100644
index 0000000..0a364e7
--- /dev/null
+++ b/sys/compat/x86bios/x86bios_alloc.c
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (C) 1999 Egbert Eich
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of the authors not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. The authors makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * xserver/hw/xfree86/int10/generic.c
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <compat/x86bios/x86bios.h>
+
+extern u_char *pbiosMem;
+extern int busySegMap[5];
+
+void *
+x86bios_alloc(int count, int *segs)
+{
+ int i;
+ int j;
+
+ /* find the free segblock of page */
+ for (i = 0; i < (PAGE_RESERV - count); i++)
+ {
+ if (busySegMap[i] == 0)
+ {
+ /* find the capacity of segblock */
+ for (j = i; j < (i + count); j++)
+ {
+ if (busySegMap[j] == 1)
+ break;
+ }
+
+ if (j == (i + count))
+ break;
+ i += count;
+ }
+ }
+
+ if (i == (PAGE_RESERV - count))
+ return NULL;
+
+ /* make the segblock is used */
+ for (j = i; j < (i + count); j++)
+ busySegMap[i] = 1;
+
+ *segs = i * 4096;
+
+ return (pbiosMem + *segs);
+}
+
+void
+x86bios_free(void *pbuf, int count)
+{
+ int i;
+ int busySeg;
+
+ busySeg = ((u_char *)pbuf - pbiosMem) / 4096;
+
+ for (i = busySeg; i < (busySeg + count); i++)
+ busySegMap[i] = 0;
+}
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 69a80a5..1cba42f 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2757,5 +2757,3 @@ options AAC_DEBUG # Debugging levels:
options BROOKTREE_ALLOC_PAGES=(217*4+1)
options MAXFILES=999
-# x86 real mode emulator
-options X86EMU
diff --git a/sys/conf/files b/sys/conf/files
index c232c52..b31249f 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1792,6 +1792,7 @@ fs/procfs/procfs_ioctl.c optional procfs
fs/procfs/procfs_map.c optional procfs
fs/procfs/procfs_mem.c optional procfs
fs/procfs/procfs_note.c optional procfs
+fs/procfs/procfs_osrel.c optional procfs
fs/procfs/procfs_regs.c optional procfs
fs/procfs/procfs_rlimit.c optional procfs
fs/procfs/procfs_status.c optional procfs
@@ -2009,6 +2010,7 @@ kern/sched_ule.c optional sched_ule
kern/serdev_if.m standard
kern/stack_protector.c standard \
compile-with "${NORMAL_C:N-fstack-protector*}"
+kern/subr_acl_nfs4.c standard
kern/subr_acl_posix1e.c standard
kern/subr_autoconf.c standard
kern/subr_blist.c standard
@@ -2633,7 +2635,7 @@ ufs/ufs/ufs_acl.c optional ffs
ufs/ufs/ufs_bmap.c optional ffs
ufs/ufs/ufs_dirhash.c optional ffs
ufs/ufs/ufs_extattr.c optional ffs
-ufs/ufs/ufs_gjournal.c optional ffs
+ufs/ufs/ufs_gjournal.c optional ffs UFS_GJOURNAL
ufs/ufs/ufs_inode.c optional ffs
ufs/ufs/ufs_lookup.c optional ffs
ufs/ufs/ufs_quota.c optional ffs
@@ -2828,6 +2830,3 @@ dev/xen/netfront/netfront.c optional xen | xenhvm
dev/xen/xenpci/xenpci.c optional xenpci
dev/xen/xenpci/evtchn.c optional xenpci
dev/xen/xenpci/machine_reboot.c optional xenpci
-contrib/x86emu/x86emu.c optional x86emu
-contrib/x86emu/x86emu_util.c optional x86emu
-
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 01f5355..0721ea4 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -162,7 +162,7 @@ dev/atkbdc/atkbdc_subr.c optional atkbdc
dev/atkbdc/psm.c optional psm atkbdc
dev/coretemp/coretemp.c optional coretemp
dev/cpuctl/cpuctl.c optional cpuctl
-dev/dpms/dpms.c optional dpms x86emu
+dev/dpms/dpms.c optional dpms
# There are no systems with isa slots, so all ed isa entries should go..
dev/ed/if_ed_3c503.c optional ed isa ed_3c503
dev/ed/if_ed_isa.c optional ed isa
@@ -170,7 +170,8 @@ dev/ed/if_ed_wd80x3.c optional ed isa
dev/ed/if_ed_hpp.c optional ed isa ed_hpp
dev/ed/if_ed_sic.c optional ed isa ed_sic
dev/fb/fb.c optional fb | vga
-dev/fb/vesa.c optional vga vesa x86emu
+dev/fb/s3_pci.c optional s3pci
+dev/fb/vesa.c optional vga vesa
dev/fb/vga.c optional vga
dev/ichwd/ichwd.c optional ichwd
dev/if_ndis/if_ndis.c optional ndis
@@ -219,7 +220,7 @@ dev/sio/sio_puc.c optional sio puc
dev/speaker/spkr.c optional speaker
dev/syscons/apm/apm_saver.c optional apm_saver apm
dev/syscons/scterm-teken.c optional sc
-dev/syscons/scvesactl.c optional sc vga vesa x86emu
+dev/syscons/scvesactl.c optional sc vga vesa
dev/syscons/scvgarndr.c optional sc vga
dev/syscons/scvtb.c optional sc
dev/uart/uart_cpu_amd64.c optional uart
@@ -293,3 +294,10 @@ i386/cpufreq/p4tcc.c optional cpufreq
#
libkern/memmove.c standard
libkern/memset.c standard
+#
+# x86 real mode BIOS emulator, required by atkbdc/dpms/vesa
+#
+compat/x86bios/x86bios.c optional x86bios | atkbd | dpms | vesa
+compat/x86bios/x86bios_alloc.c optional x86bios | atkbd | dpms | vesa
+contrib/x86emu/x86emu.c optional x86bios | atkbd | dpms | vesa
+contrib/x86emu/x86emu_util.c optional x86bios | atkbd | dpms | vesa
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 0a16cee..ef6d590 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -150,14 +150,15 @@ dev/ctau/if_ct.c optional ctau
dev/cx/csigma.c optional cx
dev/cx/cxddk.c optional cx
dev/cx/if_cx.c optional cx
-dev/dpms/dpms.c optional dpms x86emu
+dev/dpms/dpms.c optional dpms
dev/ed/if_ed_3c503.c optional ed isa ed_3c503
dev/ed/if_ed_isa.c optional ed isa
dev/ed/if_ed_wd80x3.c optional ed isa
dev/ed/if_ed_hpp.c optional ed isa ed_hpp
dev/ed/if_ed_sic.c optional ed isa ed_sic
dev/fb/fb.c optional fb | vga
-dev/fb/vesa.c optional vga vesa x86emu
+dev/fb/s3_pci.c optional s3pci
+dev/fb/vesa.c optional vga vesa
dev/fb/vga.c optional vga
dev/fdc/fdc.c optional fdc
dev/fdc/fdc_acpi.c optional fdc
@@ -219,7 +220,7 @@ dev/sio/sio_puc.c optional sio puc
dev/speaker/spkr.c optional speaker
dev/syscons/apm/apm_saver.c optional apm_saver apm
dev/syscons/scterm-teken.c optional sc
-dev/syscons/scvesactl.c optional sc vga vesa x86emu
+dev/syscons/scvesactl.c optional sc vga vesa
dev/syscons/scvgarndr.c optional sc vga
dev/syscons/scvtb.c optional sc
dev/uart/uart_cpu_i386.c optional uart
@@ -377,3 +378,10 @@ i386/xbox/xbox.c optional xbox
i386/xbox/xboxfb.c optional xboxfb
dev/fb/boot_font.c optional xboxfb
i386/xbox/pic16l.s optional xbox
+#
+# x86 real mode BIOS emulator, required by atkbdc/dpms/vesa
+#
+compat/x86bios/x86bios.c optional x86bios | atkbd | dpms | vesa
+compat/x86bios/x86bios_alloc.c optional x86bios | atkbd | dpms | vesa
+contrib/x86emu/x86emu.c optional x86bios | atkbd | dpms | vesa
+contrib/x86emu/x86emu_util.c optional x86bios | atkbd | dpms | vesa
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 49e99fd..cabee5a 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -89,28 +89,54 @@ i=`${MAKE:-make} -V KERN_IDENT`
case "$d" in
*/sys/*)
+ SRCDIR=${d##*obj}
+ if [ -n "$MACHINE" ]; then
+ SRCDIR=${SRCDIR##/$MACHINE}
+ fi
+ SRCDIR=${SRCDIR%%/sys/*}
+
for dir in /bin /usr/bin /usr/local/bin; do
- if [ -x "${dir}/svnversion" ]; then
+ if [ -d "${SRCDIR}/sys/.svn" -a -x "${dir}/svnversion" ] ; then
svnversion=${dir}/svnversion
- SRCDIR=${d##*obj}
- if [ -n "$MACHINE" ]; then
- SRCDIR=${SRCDIR##/$MACHINE}
- fi
- SRCDIR=${SRCDIR%%/sys/*}
+ break
+ fi
+ if [ -d "${SRCDIR}/.git" -a -x "${dir}/git" ] ; then
+ git_cmd="${dir}/git --git-dir=${SRCDIR}/.git"
break
fi
done
- if [ -n "$svnversion" -a -d "${SRCDIR}/sys/.svn" ] ; then
+ if [ -n "$svnversion" ] ; then
svn=" r`cd ${SRCDIR}/sys && $svnversion`"
fi
+ if [ -n "$git_cmd" ] ; then
+ git=`$git_cmd rev-parse --verify --short HEAD 2>/dev/null`
+ svn=`$git_cmd svn find-rev $git 2>/dev/null`
+ if [ -n "$svn" ] ; then
+ svn=" r${svn}"
+ git="=${git}"
+ else
+ svn=`$git_cmd log | fgrep 'git-svn-id:' | head -1 | \
+ sed -n 's/^.*@\([0-9][0-9]*\).*$/\1/p'`
+ if [ -n $svn ] ; then
+ svn=" r${svn}"
+ git="+${git}"
+ else
+ git=" ${git}"
+ fi
+ fi
+ if $git_cmd --work-tree=${SRCDIR} diff-index \
+ --name-only HEAD | read dummy; then
+ git="${git}-dirty"
+ fi
+ fi
;;
esac
cat << EOF > vers.c
$COPYRIGHT
-#define SCCSSTR "@(#)${VERSION} #${v}${svn}: ${t}"
-#define VERSTR "${VERSION} #${v}${svn}: ${t}\\n ${u}@${h}:${d}\\n"
+#define SCCSSTR "@(#)${VERSION} #${v}${svn}${git}: ${t}"
+#define VERSTR "${VERSION} #${v}${svn}${git}: ${t}\\n ${u}@${h}:${d}\\n"
#define RELSTR "${RELEASE}"
char sccs[sizeof(SCCSSTR) > 128 ? sizeof(SCCSSTR) : 128] = SCCSSTR;
diff --git a/sys/conf/options b/sys/conf/options
index 4752fb8..1df09d7 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -838,4 +838,4 @@ SND_FEEDER_RATE_HP opt_snd.h
SND_PCM_64 opt_snd.h
SND_OLDSTEREO opt_snd.h
-X86EMU
+X86BIOS
diff --git a/sys/contrib/x86emu/x86emu.c b/sys/contrib/x86emu/x86emu.c
index a26044a..3e5a06a 100644
--- a/sys/contrib/x86emu/x86emu.c
+++ b/sys/contrib/x86emu/x86emu.c
@@ -1,6 +1,5 @@
/* $OpenBSD: x86emu.c,v 1.4 2009/06/18 14:19:21 pirofti Exp $ */
/* $NetBSD: x86emu.c,v 1.7 2009/02/03 19:26:29 joerg Exp $ */
-/* $FreeBSD$ */
/*
*
@@ -33,9 +32,8 @@
*
*/
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
#include <contrib/x86emu/x86emu.h>
#include <contrib/x86emu/x86emu_regs.h>
@@ -8335,32 +8333,3 @@ pop_long(struct x86emu *emu)
emu->x86.R_SP += 4;
return res;
}
-
-static int
-x86emu_modevent(module_t mod __unused, int type, void *data __unused)
-{
- int err = 0;
-
- switch (type) {
- case MOD_LOAD:
- break;
-
- case MOD_UNLOAD:
- break;
-
- default:
- err = ENOTSUP;
- break;
-
- }
- return (err);
-}
-
-static moduledata_t x86emu_mod = {
- "x86emu",
- x86emu_modevent,
- NULL,
-};
-
-DECLARE_MODULE(x86emu, x86emu_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
-MODULE_VERSION(x86emu, 1);
diff --git a/sys/contrib/x86emu/x86emu_util.c b/sys/contrib/x86emu/x86emu_util.c
index 41a9f72..4172f94 100644
--- a/sys/contrib/x86emu/x86emu_util.c
+++ b/sys/contrib/x86emu/x86emu_util.c
@@ -1,6 +1,5 @@
/* $OpenBSD: x86emu_util.c,v 1.5 2009/06/18 14:19:21 pirofti Exp $ */
/* $NetBSD: x86emu_util.c,v 1.2 2007/12/04 17:32:22 joerg Exp $ */
-/* $FreeBSD$ */
/*
*
@@ -33,6 +32,9 @@
*
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
#include <sys/endian.h>
diff --git a/sys/dev/acpi_support/acpi_aiboost.c b/sys/dev/acpi_support/acpi_aiboost.c
index 8fff872..a8fe9cc 100644
--- a/sys/dev/acpi_support/acpi_aiboost.c
+++ b/sys/dev/acpi_support/acpi_aiboost.c
@@ -46,7 +46,6 @@ ACPI_MODULE_NAME("AIBOOST")
#define DESCSTRLEN 32
struct acpi_aiboost_element{
- ACPI_HANDLE h;
uint32_t id;
char desc[DESCSTRLEN];
};
@@ -127,22 +126,23 @@ static ACPI_STATUS acpi_aiboost_getcomponent(device_t dev, char *name, struct a
for(i = 1 ; i < o->Package.Count; i++){
elem = &o->Package.Elements[i];
- if(elem->Type != ACPI_TYPE_ANY){
- printf("NOREF\n");
- goto error;
- }
- c->elem[ i - 1].h = elem->Reference.Handle;
-
- buf2.Pointer = NULL;
- buf2.Length = ACPI_ALLOCATE_BUFFER;
-
- status = AcpiEvaluateObject(c->elem[i - 1].h, NULL, NULL,
- &buf2);
- if(ACPI_FAILURE(status)){
- printf("FETCH OBJECT\n");
+ if (elem->Type == ACPI_TYPE_ANY) {
+ buf2.Pointer = NULL;
+ buf2.Length = ACPI_ALLOCATE_BUFFER;
+
+ status = AcpiEvaluateObject(elem->Reference.Handle,
+ NULL, NULL, &buf2);
+ if (ACPI_FAILURE(status)){
+ printf("FETCH OBJECT\n");
+ goto error;
+ }
+ subobj = buf2.Pointer;
+ } else if (elem->Type == ACPI_TYPE_PACKAGE)
+ subobj = elem;
+ else {
+ printf("NO PACKAGE\n");
goto error;
}
- subobj = buf2.Pointer;
if(ACPI_FAILURE(acpi_PkgInt32(subobj,0, &c->elem[i -1].id))){
printf("ID FAILED\n");
goto error;
@@ -151,15 +151,17 @@ static ACPI_STATUS acpi_aiboost_getcomponent(device_t dev, char *name, struct a
sizeof(c->elem[i - 1].desc));
if(ACPI_FAILURE(status)){
if(status == E2BIG){
- c->elem[i-1].desc[DESCSTRLEN-1] = 0;
+ c->elem[i - 1].desc[DESCSTRLEN-1] = 0;
}else{
printf("DESC FAILED %d\n", i-1);
goto error;
}
}
- if(buf2.Pointer)
- AcpiOsFree(buf2.Pointer);
+ if (buf2.Pointer) {
+ AcpiOsFree(buf2.Pointer);
+ buf2.Pointer = NULL;
+ }
}
if(buf.Pointer)
diff --git a/sys/dev/acpi_support/acpi_ibm.c b/sys/dev/acpi_support/acpi_ibm.c
index 0bf340d..25db9b0 100644
--- a/sys/dev/acpi_support/acpi_ibm.c
+++ b/sys/dev/acpi_support/acpi_ibm.c
@@ -288,7 +288,7 @@ static devclass_t acpi_ibm_devclass;
DRIVER_MODULE(acpi_ibm, acpi, acpi_ibm_driver, acpi_ibm_devclass,
0, 0);
MODULE_DEPEND(acpi_ibm, acpi, 1, 1, 1);
-static char *ibm_ids[] = {"IBM0057", "IBM0068", NULL};
+static char *ibm_ids[] = {"IBM0068", NULL};
static void
ibm_led(void *softc, int onoff)
@@ -356,8 +356,6 @@ acpi_ibm_attach(device_t dev)
}
sc->ec_handle = acpi_get_handle(sc->ec_dev);
- ACPI_SERIAL_BEGIN(ibm);
-
/* Get the sysctl tree */
sc->sysctl_ctx = device_get_sysctl_ctx(dev);
sc->sysctl_tree = device_get_sysctl_tree(dev);
@@ -404,8 +402,6 @@ acpi_ibm_attach(device_t dev)
"Thermal zones");
}
- ACPI_SERIAL_END(ibm);
-
/* Handle notifies */
AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY,
acpi_ibm_notify, dev);
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index d402274..b31f1e7 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -2244,6 +2244,28 @@ acpi_SetIntrModel(int model)
}
/*
+ * Walk subtables of a table and call a callback routine for each
+ * subtable. The caller should provide the first subtable and a
+ * pointer to the end of the table. This can be used to walk tables
+ * such as MADT and SRAT that use subtable entries.
+ */
+void
+acpi_walk_subtables(void *first, void *end, acpi_subtable_handler *handler,
+ void *arg)
+{
+ ACPI_SUBTABLE_HEADER *entry;
+
+ for (entry = first; (void *)entry < end; ) {
+ /* Avoid an infinite loop if we hit a bogus entry. */
+ if (entry->Length < sizeof(ACPI_SUBTABLE_HEADER))
+ return;
+
+ handler(entry, arg);
+ entry = ACPI_ADD_PTR(ACPI_SUBTABLE_HEADER, entry, entry->Length);
+ }
+}
+
+/*
* DEPRECATED. This interface has serious deficiencies and will be
* removed.
*
diff --git a/sys/dev/acpica/acpi_video.c b/sys/dev/acpica/acpi_video.c
index c095a40..e7e7d66 100644
--- a/sys/dev/acpica/acpi_video.c
+++ b/sys/dev/acpica/acpi_video.c
@@ -282,8 +282,7 @@ acpi_video_detach(device_t dev)
acpi_video_notify_handler);
ACPI_SERIAL_BEGIN(video);
- for (vo = STAILQ_FIRST(&sc->vid_outputs); vo != NULL; vo = vn) {
- vn = STAILQ_NEXT(vo, vo_next);
+ STAILQ_FOREACH_SAFE(vo, &sc->vid_outputs, vo_next, vn) {
acpi_video_vo_destroy(vo);
}
ACPI_SERIAL_END(video);
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
index 63eadea..f4d27e4 100644
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -307,6 +307,9 @@ void acpi_EnterDebugger(void);
ACPI_DEVINFO_PRESENT(x, ACPI_STA_PRESENT | ACPI_STA_FUNCTIONAL | \
ACPI_STA_BATT_PRESENT)
+/* Callback function type for walking subtables within a table. */
+typedef void acpi_subtable_handler(ACPI_SUBTABLE_HEADER *, void *);
+
BOOLEAN acpi_DeviceIsPresent(device_t dev);
BOOLEAN acpi_BatteryIsPresent(device_t dev);
ACPI_STATUS acpi_GetHandleInScope(ACPI_HANDLE parent, char *path,
@@ -340,6 +343,8 @@ void acpi_UserNotify(const char *subsystem, ACPI_HANDLE h,
int acpi_bus_alloc_gas(device_t dev, int *type, int *rid,
ACPI_GENERIC_ADDRESS *gas, struct resource **res,
u_int flags);
+void acpi_walk_subtables(void *first, void *end,
+ acpi_subtable_handler *handler, void *arg);
struct acpi_parse_resource_set {
void (*set_init)(device_t dev, void *arg, void **context);
diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c
index 0544e19..dd6b96f 100644
--- a/sys/dev/ata/chipsets/ata-marvell.c
+++ b/sys/dev/ata/chipsets/ata-marvell.c
@@ -227,6 +227,8 @@ ata_marvell_edma_ch_attach(device_t dev)
work = ch->dma.work_bus;
/* clear work area */
bzero(ch->dma.work, 1024+256);
+ bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
/* set legacy ATA resources */
for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
@@ -310,7 +312,11 @@ ata_marvell_edma_ch_attach(device_t dev)
static int
ata_marvell_edma_ch_detach(device_t dev)
{
+ struct ata_channel *ch = device_get_softc(dev);
+ if (ch->dma.work_tag && ch->dma.work_map)
+ bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
ata_dmafini(dev);
return (0);
}
@@ -344,8 +350,6 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
struct ata_channel *ch = device_get_softc(request->parent);
u_int32_t req_in;
u_int8_t *bytep;
- u_int16_t *wordp;
- u_int32_t *quadp;
int i;
int error, slot;
@@ -374,13 +378,14 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
slot = (((req_in & ~0xfffffc00) >> 5) + 0) & 0x1f;
bytep = (u_int8_t *)(ch->dma.work);
bytep += (slot << 5);
- wordp = (u_int16_t *)bytep;
- quadp = (u_int32_t *)bytep;
/* fill in this request */
- quadp[0] = (long)request->dma->sg_bus & 0xffffffff;
- quadp[1] = (u_int64_t)request->dma->sg_bus >> 32;
- wordp[4] = (request->flags & ATA_R_READ ? 0x01 : 0x00) | (request->tag<<1);
+ le32enc(bytep + 0 * sizeof(u_int32_t),
+ request->dma->sg_bus & 0xffffffff);
+ le32enc(bytep + 1 * sizeof(u_int32_t),
+ (u_int64_t)request->dma->sg_bus >> 32);
+ le16enc(bytep + 4 * sizeof(u_int16_t),
+ (request->flags & ATA_R_READ ? 0x01 : 0x00) | (request->tag << 1));
i = 10;
bytep[i++] = (request->u.ata.count >> 8) & 0xff;
@@ -409,6 +414,9 @@ ata_marvell_edma_begin_transaction(struct ata_request *request)
bytep[i++] = request->u.ata.command;
bytep[i++] = 0x90 | ATA_COMMAND;
+ bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
/* enable EDMA machinery if needed */
if (!(ATA_INL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch)) & 0x00000001)) {
ATA_OUTL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch), 0x00000001);
@@ -451,6 +459,8 @@ ata_marvell_edma_end_transaction(struct ata_request *request)
slot = (((rsp_in & ~0xffffff00) >> 3)) & 0x1f;
rsp_out &= 0xffffff00;
rsp_out += (slot << 3);
+ bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
response = (struct ata_marvell_response *)
(ch->dma.work + 1024 + (slot << 3));
@@ -525,6 +535,7 @@ ata_marvell_edma_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs,
prd[i].addrlo = htole32(segs[i].ds_addr);
prd[i].count = htole32(segs[i].ds_len);
prd[i].addrhi = htole32((u_int64_t)segs[i].ds_addr >> 32);
+ prd[i].reserved = 0;
}
prd[i - 1].count |= htole32(ATA_DMA_EOT);
KASSERT(nsegs <= ATA_DMA_ENTRIES, ("too many DMA segment entries\n"));
diff --git a/sys/dev/atkbdc/atkbd.c b/sys/dev/atkbdc/atkbd.c
index 0aae153..59d9632 100644
--- a/sys/dev/atkbdc/atkbd.c
+++ b/sys/dev/atkbdc/atkbd.c
@@ -44,10 +44,10 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/resource.h>
-#ifdef __i386__
+#if defined(__i386__) || defined(__amd64__)
#include <machine/md_var.h>
#include <machine/psl.h>
-#include <machine/vm86.h>
+#include <compat/x86bios/x86bios.h>
#include <machine/pc/bios.h>
#include <vm/vm.h>
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#include <isa/isareg.h>
-#endif /* __i386__ */
+#endif /* __i386__ || __amd64__ */
#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
@@ -1089,34 +1089,42 @@ atkbd_shutdown_final(void *v)
static int
get_typematic(keyboard_t *kbd)
{
-#ifdef __i386__
+#if defined(__i386__) || defined(__amd64__)
/*
* Only some systems allow us to retrieve the keyboard repeat
* rate previously set via the BIOS...
*/
- struct vm86frame vmf;
- u_int32_t p;
-
- bzero(&vmf, sizeof(vmf));
- vmf.vmf_ax = 0xc000;
- vm86_intcall(0x15, &vmf);
- if ((vmf.vmf_eflags & PSL_C) || vmf.vmf_ah)
- return ENODEV;
- p = BIOS_PADDRTOVADDR(((u_int32_t)vmf.vmf_es << 4) + vmf.vmf_bx);
- if ((readb(p + 6) & 0x40) == 0) /* int 16, function 0x09 supported? */
- return ENODEV;
- vmf.vmf_ax = 0x0900;
- vm86_intcall(0x16, &vmf);
- if ((vmf.vmf_al & 0x08) == 0) /* int 16, function 0x0306 supported? */
- return ENODEV;
- vmf.vmf_ax = 0x0306;
- vm86_intcall(0x16, &vmf);
- kbd->kb_delay1 = typematic_delay(vmf.vmf_bh << 5);
- kbd->kb_delay2 = typematic_rate(vmf.vmf_bl);
- return 0;
+ x86regs_t regs;
+ uint8_t *p;
+
+ /* Is BIOS system configuration table supported? */
+ bzero(&regs, sizeof(regs));
+ regs.R_AH = 0xc0;
+ x86bios_intr(&regs, 0x15);
+ if ((regs.R_FLG & PSL_C) != 0 || regs.R_AH != 0)
+ return (ENODEV);
+
+ /* Is int 16, function 0x09 supported? */
+ p = x86bios_offset((regs.R_ES << 4) + regs.R_BX);
+ if (readw(p) < 5 || (readb(p + 6) & 0x40) == 0)
+ return (ENODEV);
+
+ /* Is int 16, function 0x0306 supported? */
+ bzero(&regs, sizeof(regs));
+ regs.R_AH = 0x09;
+ x86bios_intr(&regs, 0x16);
+ if ((regs.R_AL & 0x08) == 0)
+ return (ENODEV);
+
+ bzero(&regs, sizeof(regs));
+ regs.R_AX = 0x0306;
+ x86bios_intr(&regs, 0x16);
+ kbd->kb_delay1 = typematic_delay(regs.R_BH << 5);
+ kbd->kb_delay2 = typematic_rate(regs.R_BL);
+ return (0);
#else
- return ENODEV;
-#endif /* __i386__ */
+ return (ENODEV);
+#endif /* __i386__ || __amd64__ */
}
static int
diff --git a/sys/dev/de/if_de.c b/sys/dev/de/if_de.c
index 2acf1a8..c3d2839 100644
--- a/sys/dev/de/if_de.c
+++ b/sys/dev/de/if_de.c
@@ -160,7 +160,7 @@ static void tulip_dma_map_rxbuf(void *, bus_dma_segment_t *, int,
static void
tulip_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
- u_int32_t *paddr;
+ bus_addr_t *paddr;
if (error)
return;
@@ -182,7 +182,7 @@ tulip_dma_map_rxbuf(void *arg, bus_dma_segment_t *segs, int nseg,
KASSERT(nseg == 1, ("too many DMA segments"));
KASSERT(segs[0].ds_len >= TULIP_RX_BUFLEN, ("receive buffer too small"));
- desc->d_addr1 = segs[0].ds_addr;
+ desc->d_addr1 = segs[0].ds_addr & 0xffffffff;
desc->d_length1 = TULIP_RX_BUFLEN;
#ifdef not_needed
/* These should already always be zero. */
@@ -3171,8 +3171,8 @@ tulip_reset(tulip_softc_t * const sc)
sc->tulip_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
- TULIP_CSR_WRITE(sc, csr_txlist, sc->tulip_txinfo.ri_dma_addr);
- TULIP_CSR_WRITE(sc, csr_rxlist, sc->tulip_rxinfo.ri_dma_addr);
+ TULIP_CSR_WRITE(sc, csr_txlist, sc->tulip_txinfo.ri_dma_addr & 0xffffffff);
+ TULIP_CSR_WRITE(sc, csr_rxlist, sc->tulip_rxinfo.ri_dma_addr & 0xffffffff);
TULIP_CSR_WRITE(sc, csr_busmode,
(1 << (3 /*pci_max_burst_len*/ + 8))
|TULIP_BUSMODE_CACHE_ALIGN8
@@ -3488,7 +3488,7 @@ tulip_rx_intr(tulip_softc_t * const sc)
struct mbuf *m0;
KASSERT(ms != NULL, ("no packet to accept"));
-#if defined(TULIP_COPY_RXDATA)
+#ifndef __NO_STRICT_ALIGNMENT
/*
* Copy the data into a new mbuf that is properly aligned. If
* we fail to allocate a new mbuf, then drop the packet. We will
@@ -3527,7 +3527,7 @@ tulip_rx_intr(tulip_softc_t * const sc)
*/
ms = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
-#if defined(TULIP_COPY_RXDATA)
+#ifndef __NO_STRICT_ALIGNMENT
skip_input:
#endif
if (ms == NULL) {
@@ -4016,9 +4016,9 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m)
eop = nextout;
eop->di_desc->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
eop->di_desc->d_status = d_status;
- eop->di_desc->d_addr1 = segs[segcnt].ds_addr;
+ eop->di_desc->d_addr1 = segs[segcnt].ds_addr & 0xffffffff;
eop->di_desc->d_length1 = segs[segcnt].ds_len;
- eop->di_desc->d_addr2 = segs[segcnt+1].ds_addr;
+ eop->di_desc->d_addr2 = segs[segcnt+1].ds_addr & 0xffffffff;
eop->di_desc->d_length2 = segs[segcnt+1].ds_len;
d_status = TULIP_DSTS_OWNER;
if (++nextout == ri->ri_last)
@@ -4028,7 +4028,7 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m)
eop = nextout;
eop->di_desc->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
eop->di_desc->d_status = d_status;
- eop->di_desc->d_addr1 = segs[segcnt].ds_addr;
+ eop->di_desc->d_addr1 = segs[segcnt].ds_addr & 0xffffffff;
eop->di_desc->d_length1 = segs[segcnt].ds_len;
eop->di_desc->d_addr2 = 0;
eop->di_desc->d_length2 = 0;
@@ -4194,7 +4194,7 @@ tulip_txput_setup(tulip_softc_t * const sc)
nextout->d_length2 = 0;
nextout->d_addr2 = 0;
nextout->d_length1 = sizeof(sc->tulip_setupdata);
- nextout->d_addr1 = sc->tulip_setup_dma_addr;
+ nextout->d_addr1 = sc->tulip_setup_dma_addr & 0xffffffff;
bus_dmamap_sync(sc->tulip_setup_tag, sc->tulip_setup_map,
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
TULIP_TXDESC_PRESYNC(ri);
@@ -4491,7 +4491,7 @@ tulip_busdma_freering(tulip_ringinfo_t *ri)
/* Allocate memory for a single descriptor ring. */
static int
tulip_busdma_allocring(device_t dev, tulip_softc_t * const sc, size_t count,
- bus_size_t maxsize, int nsegs, tulip_ringinfo_t *ri, const char *name)
+ bus_size_t align, int nsegs, tulip_ringinfo_t *ri, const char *name)
{
size_t size;
int error, i;
@@ -4499,7 +4499,7 @@ tulip_busdma_allocring(device_t dev, tulip_softc_t * const sc, size_t count,
/* First, setup a tag. */
ri->ri_max = count;
size = count * sizeof(tulip_desc_t);
- error = bus_dma_tag_create(NULL, PAGE_SIZE, 0, BUS_SPACE_MAXADDR_32BIT,
+ error = bus_dma_tag_create(NULL, 32, 0, BUS_SPACE_MAXADDR_32BIT,
BUS_SPACE_MAXADDR, NULL, NULL, size, 1, size, 0, NULL, NULL,
&ri->ri_ring_tag);
if (error) {
@@ -4527,9 +4527,9 @@ tulip_busdma_allocring(device_t dev, tulip_softc_t * const sc, size_t count,
}
/* Allocate a tag for the data buffers. */
- error = bus_dma_tag_create(NULL, 4, 0,
+ error = bus_dma_tag_create(NULL, align, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- maxsize, nsegs, TULIP_DATA_PER_DESC, 0, NULL, NULL, &ri->ri_data_tag);
+ MCLBYTES * nsegs, nsegs, MCLBYTES, 0, NULL, NULL, &ri->ri_data_tag);
if (error) {
device_printf(dev, "failed to allocate %s buffer dma tag\n", name);
return (error);
@@ -4563,6 +4563,7 @@ tulip_busdma_cleanup(tulip_softc_t * const sc)
if (sc->tulip_setupbuf != NULL) {
bus_dmamem_free(sc->tulip_setup_tag, sc->tulip_setupbuf,
sc->tulip_setup_map);
+ bus_dmamap_destroy(sc->tulip_setup_tag, sc->tulip_setup_map);
sc->tulip_setup_map = NULL;
sc->tulip_setupbuf = NULL;
}
@@ -4586,8 +4587,8 @@ tulip_busdma_init(device_t dev, tulip_softc_t * const sc)
/*
* Allocate space and dmamap for transmit ring.
*/
- error = tulip_busdma_allocring(dev, sc, TULIP_TXDESCS, TULIP_DATA_PER_DESC,
- TULIP_MAX_TXSEG, &sc->tulip_txinfo, "transmit");
+ error = tulip_busdma_allocring(dev, sc, TULIP_TXDESCS, 1, TULIP_MAX_TXSEG,
+ &sc->tulip_txinfo, "transmit");
if (error)
return (error);
@@ -4598,7 +4599,7 @@ tulip_busdma_init(device_t dev, tulip_softc_t * const sc)
* a waste in practice though as an ethernet frame can easily fit
* in TULIP_RX_BUFLEN bytes.
*/
- error = tulip_busdma_allocring(dev, sc, TULIP_RXDESCS, MCLBYTES, 1,
+ error = tulip_busdma_allocring(dev, sc, TULIP_RXDESCS, 4, 1,
&sc->tulip_rxinfo, "receive");
if (error)
return (error);
@@ -4606,7 +4607,7 @@ tulip_busdma_init(device_t dev, tulip_softc_t * const sc)
/*
* Allocate a DMA tag, memory, and map for setup descriptor
*/
- error = bus_dma_tag_create(NULL, 4, 0,
+ error = bus_dma_tag_create(NULL, 32, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
sizeof(sc->tulip_setupdata), 1, sizeof(sc->tulip_setupdata), 0,
NULL, NULL, &sc->tulip_setup_tag);
diff --git a/sys/dev/de/if_devar.h b/sys/dev/de/if_devar.h
index 3fd3410..b4feebc 100644
--- a/sys/dev/de/if_devar.h
+++ b/sys/dev/de/if_devar.h
@@ -104,7 +104,7 @@ typedef struct {
tulip_descinfo_t *ri_descinfo;
bus_dma_tag_t ri_ring_tag;
bus_dmamap_t ri_ring_map;
- uint32_t ri_dma_addr;
+ bus_addr_t ri_dma_addr;
bus_dma_tag_t ri_data_tag;
bus_dmamap_t *ri_data_maps;
} tulip_ringinfo_t;
@@ -134,11 +134,7 @@ typedef struct {
* architecture which can't handle unaligned accesses) because with
* 100Mb/s cards the copying is just too much of a hit.
*/
-#if !defined(__i386__)
-#define TULIP_COPY_RXDATA 1
-#endif
-#define TULIP_DATA_PER_DESC 2032
#define TULIP_TXTIMER 4
#define TULIP_RXDESCS 48
#define TULIP_TXDESCS 128
@@ -560,7 +556,7 @@ struct tulip_softc {
*/
bus_dma_tag_t tulip_setup_tag;
bus_dmamap_t tulip_setup_map;
- uint32_t tulip_setup_dma_addr;
+ bus_addr_t tulip_setup_dma_addr;
u_int32_t *tulip_setupbuf;
u_int32_t tulip_setupdata[192 / sizeof(u_int32_t)];
char tulip_boardid[24];
diff --git a/sys/dev/dpms/dpms.c b/sys/dev/dpms/dpms.c
index ac729f9..c0476c5 100644
--- a/sys/dev/dpms/dpms.c
+++ b/sys/dev/dpms/dpms.c
@@ -67,11 +67,7 @@ __FBSDID("$FreeBSD$");
#include <sys/libkern.h>
#include <sys/module.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-
-#include <contrib/x86emu/x86emu.h>
-#include <contrib/x86emu/x86emu_regs.h>
+#include <compat/x86bios/x86bios.h>
/*
* VESA DPMS States
@@ -94,9 +90,6 @@ struct dpms_softc {
int dpms_initial_state;
};
-static struct x86emu vesa_emu;
-static unsigned char *emumem = NULL;
-
static int dpms_attach(device_t);
static int dpms_detach(device_t);
static int dpms_get_supported_states(int *);
@@ -126,59 +119,7 @@ static driver_t dpms_driver = {
static devclass_t dpms_devclass;
DRIVER_MODULE(dpms, vgapci, dpms_driver, dpms_devclass, NULL, NULL);
-MODULE_DEPEND(dpms, x86emu, 1, 1, 1);
-
-static uint8_t
-vm86_emu_inb(struct x86emu *emu, uint16_t port)
-{
- if (port == 0xb2) /* APM scratch register */
- return 0;
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return 0;
- return inb(port);
-}
-
-static uint16_t
-vm86_emu_inw(struct x86emu *emu, uint16_t port)
-{
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return 0;
- return inw(port);
-}
-
-static uint32_t
-vm86_emu_inl(struct x86emu *emu, uint16_t port)
-{
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return 0;
- return inl(port);
-}
-
-static void
-vm86_emu_outb(struct x86emu *emu, uint16_t port, uint8_t val)
-{
- if (port == 0xb2) /* APM scratch register */
- return;
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return;
- outb(port, val);
-}
-
-static void
-vm86_emu_outw(struct x86emu *emu, uint16_t port, uint16_t val)
-{
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return;
- outw(port, val);
-}
-
-static void
-vm86_emu_outl(struct x86emu *emu, uint16_t port, uint32_t val)
-{
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return;
- outl(port, val);
-}
+MODULE_DEPEND(dpms, x86bios, 1, 1, 1);
static void
dpms_identify(driver_t *driver, device_t parent)
@@ -192,7 +133,6 @@ dpms_identify(driver_t *driver, device_t parent)
*/
if (devclass_get_device(dpms_devclass, 0) == NULL)
device_add_child(parent, "dpms", 0);
-
}
static int
@@ -200,21 +140,6 @@ dpms_probe(device_t dev)
{
int error, states;
- emumem = pmap_mapbios(0x0, 0xc00000);
-
- memset(&vesa_emu, 0, sizeof(vesa_emu));
- x86emu_init_default(&vesa_emu);
-
- vesa_emu.emu_inb = vm86_emu_inb;
- vesa_emu.emu_inw = vm86_emu_inw;
- vesa_emu.emu_inl = vm86_emu_inl;
- vesa_emu.emu_outb = vm86_emu_outb;
- vesa_emu.emu_outw = vm86_emu_outw;
- vesa_emu.emu_outl = vm86_emu_outl;
-
- vesa_emu.mem_base = (char *)emumem;
- vesa_emu.mem_size = 1024 * 1024;
-
error = dpms_get_supported_states(&states);
if (error)
return (error);
@@ -240,8 +165,6 @@ dpms_attach(device_t dev)
static int
dpms_detach(device_t dev)
{
- if (emumem)
- pmap_unmapdev((vm_offset_t)emumem, 0xc00000);
return (0);
}
@@ -267,17 +190,20 @@ dpms_resume(device_t dev)
static int
dpms_call_bios(int subfunction, int *bh)
{
- vesa_emu.x86.R_AX = VBE_DPMS_FUNCTION;
- vesa_emu.x86.R_BL = subfunction;
- vesa_emu.x86.R_BH = *bh;
- vesa_emu.x86.R_ES = 0;
- vesa_emu.x86.R_DI = 0;
- x86emu_exec_intr(&vesa_emu, 0x10);
-
- if ((vesa_emu.x86.R_EAX & 0xffff) != 0x004f)
+ x86regs_t regs;
+
+ bzero(&regs, sizeof(regs));
+ regs.R_AX = VBE_DPMS_FUNCTION;
+ regs.R_BL = subfunction;
+ regs.R_BH = *bh;
+ regs.R_ES = 0;
+ regs.R_DI = 0;
+ x86bios_intr(&regs, 0x10);
+
+ if ((regs.R_EAX & 0xffff) != 0x004f)
return (ENXIO);
- *bh = vesa_emu.x86.R_BH;
+ *bh = regs.R_BH;
return (0);
}
diff --git a/sys/dev/fb/s3_pci.c b/sys/dev/fb/s3_pci.c
index 45facc9..cfddf30 100644
--- a/sys/dev/fb/s3_pci.c
+++ b/sys/dev/fb/s3_pci.c
@@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#include <machine/md_var.h>
-#include <machine/vm86.h>
#include <machine/pc/bios.h>
#include <dev/fb/vesa.h>
diff --git a/sys/dev/fb/vesa.c b/sys/dev/fb/vesa.c
index 5a766dc..8a61368 100644
--- a/sys/dev/fb/vesa.c
+++ b/sys/dev/fb/vesa.c
@@ -45,16 +45,15 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#include <vm/pmap.h>
+#include <machine/pc/bios.h>
#include <dev/fb/vesa.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/vgareg.h>
#include <isa/isareg.h>
-#include <machine/cpufunc.h>
-#include <contrib/x86emu/x86emu.h>
-#include <contrib/x86emu/x86emu_regs.h>
+#include <compat/x86bios/x86bios.h>
#define VESA_VIA_CLE266 "VIA CLE266\r\n"
@@ -73,7 +72,7 @@ typedef struct adp_state adp_state_t;
/* VESA video adapter */
static video_adapter_t *vesa_adp = NULL;
static int vesa_state_buf_size = 0;
-#define VESA_X86EMU_BUFSIZE (3 * PAGE_SIZE)
+#define VESA_BIOS_BUFSIZE (3 * PAGE_SIZE)
/* VESA functions */
#if 0
@@ -106,8 +105,6 @@ static vi_bitblt_t vesa_bitblt;
static vi_diag_t vesa_diag;
static int vesa_bios_info(int level);
-static struct x86emu vesa_emu;
-
static video_switch_t vesavidsw = {
vesa_probe,
vesa_init,
@@ -197,6 +194,7 @@ static int vesa_bios_set_start(int x, int y);
static int vesa_map_gen_mode_num(int type, int color, int mode);
static int vesa_translate_flags(u_int16_t vflags);
static int vesa_translate_mmodel(u_int8_t vmodel);
+static int vesa_get_line_width(video_info_t *info);
static int vesa_bios_init(void);
static void vesa_clear_modes(video_info_t *info, int color);
static vm_offset_t vesa_map_buffer(u_int paddr, size_t size);
@@ -206,77 +204,6 @@ static void vesa_unmap_buffer(vm_offset_t vaddr, size_t size);
static int vesa_get_origin(video_adapter_t *adp, off_t *offset);
#endif
-#define SEG_ADDR(x) (((x) >> 4) & 0x00F000)
-#define SEG_OFF(x) ((x) & 0x0FFFF)
-
-#if _BYTE_ORDER == _LITTLE_ENDIAN
-#define B_O16(x) (x)
-#define B_O32(x) (x)
-#else
-#define B_O16(x) ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8))
-#define B_O32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \
- | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
-#endif
-
-#define L_ADD(x) (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00)
-#define FARP(p) (((unsigned)(p & 0xffff0000) >> 12) | (p & 0xffff))
-
-#define REALOFF(x) (x*4096)
-
-static unsigned char *emumem = NULL;
-
-static uint8_t
-vm86_emu_inb(struct x86emu *emu, uint16_t port)
-{
- if (port == 0xb2) /* APM scratch register */
- return 0;
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return 0;
- return inb(port);
-}
-
-static uint16_t
-vm86_emu_inw(struct x86emu *emu, uint16_t port)
-{
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return 0;
- return inw(port);
-}
-
-static uint32_t
-vm86_emu_inl(struct x86emu *emu, uint16_t port)
-{
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return 0;
- return inl(port);
-}
-
-static void
-vm86_emu_outb(struct x86emu *emu, uint16_t port, uint8_t val)
-{
- if (port == 0xb2) /* APM scratch register */
- return;
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return;
- outb(port, val);
-}
-
-static void
-vm86_emu_outw(struct x86emu *emu, uint16_t port, uint16_t val)
-{
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return;
- outw(port, val);
-}
-
-static void
-vm86_emu_outl(struct x86emu *emu, uint16_t port, uint32_t val)
-{
- if (port >= 0x80 && port < 0x88) /* POST status register */
- return;
- outl(port, val);
-}
-
static void
dump_buffer(u_char *buf, size_t len)
{
@@ -293,8 +220,12 @@ dump_buffer(u_char *buf, size_t len)
static int
int10_set_mode(int mode)
{
- vesa_emu.x86.R_EAX = 0x0000 | mode;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86regs_t regs;
+
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x0000 | mode;
+
+ x86bios_intr(&regs, 0x10);
return 0;
}
@@ -303,21 +234,29 @@ int10_set_mode(int mode)
static int
vesa_bios_get_mode(int mode, struct vesa_mode *vmode)
{
+ x86regs_t regs;
+ int offs;
u_char *buf;
- vesa_emu.x86.R_EAX = 0x4f01;
- vesa_emu.x86.R_ECX = mode;
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f01;
+ regs.R_ECX = mode;
+
+ buf = (u_char *)x86bios_alloc(1, &offs);
- buf = (emumem + REALOFF(3));
- vesa_emu.x86.R_ES = SEG_ADDR(REALOFF(3));
- vesa_emu.x86.R_DI = SEG_OFF(REALOFF(3));
+ regs.R_ES = SEG_ADDR(offs);
+ regs.R_DI = SEG_OFF(offs);
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ if ((regs.R_AX & 0xff) != 0x4f)
+ {
+ x86bios_free(buf, 1);
return 1;
+ }
bcopy(buf, vmode, sizeof(*vmode));
+ x86bios_free(buf, 1);
return 0;
}
@@ -325,62 +264,77 @@ vesa_bios_get_mode(int mode, struct vesa_mode *vmode)
static int
vesa_bios_set_mode(int mode)
{
- vesa_emu.x86.R_EAX = 0x4f02;
- vesa_emu.x86.R_EBX = mode;
+ x86regs_t regs;
+
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f02;
+ regs.R_EBX = mode;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
- return ((vesa_emu.x86.R_AX & 0xff) != 0x4f);
+ return ((regs.R_AX & 0xff) != 0x4f);
}
static int
vesa_bios_get_dac(void)
{
- vesa_emu.x86.R_EAX = 0x4f08;
- vesa_emu.x86.R_EBX = 1;
+ x86regs_t regs;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f08;
+ regs.R_EBX = 1;
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ x86bios_intr(&regs, 0x10);
+
+ if ((regs.R_AX & 0xff) != 0x4f)
return 6;
- return ((vesa_emu.x86.R_EBX >> 8) & 0x00ff);
+ return ((regs.R_EBX >> 8) & 0x00ff);
}
static int
vesa_bios_set_dac(int bits)
{
- vesa_emu.x86.R_EAX = 0x4f08;
- vesa_emu.x86.R_EBX = (bits << 8);
+ x86regs_t regs;
+
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f08;
+ regs.R_EBX = (bits << 8);
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ if ((regs.R_AX & 0xff) != 0x4f)
return 6;
- return ((vesa_emu.x86.R_EBX >> 8) & 0x00ff);
+ return ((regs.R_EBX >> 8) & 0x00ff);
}
static int
vesa_bios_save_palette(int start, int colors, u_char *palette, int bits)
{
+ x86regs_t regs;
+ int offs;
u_char *p;
int i;
- vesa_emu.x86.R_EAX = 0x4f09;
- vesa_emu.x86.R_EBX = 1;
- vesa_emu.x86.R_ECX = colors;
- vesa_emu.x86.R_EDX = start;
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f09;
+ regs.R_EBX = 1;
+ regs.R_ECX = colors;
+ regs.R_EDX = start;
- vesa_emu.x86.R_ES = SEG_ADDR(REALOFF(2));
- vesa_emu.x86.R_DI = SEG_OFF(REALOFF(2));
+ p = (u_char *)x86bios_alloc(1, &offs);
- p = emumem + REALOFF(2);
+ regs.R_ES = SEG_ADDR(offs);
+ regs.R_DI = SEG_OFF(offs);
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ if ((regs.R_AX & 0xff) != 0x4f)
+ {
+ x86bios_free(p, 1);
return 1;
+ }
bits = 8 - bits;
for (i = 0; i < colors; ++i) {
@@ -388,6 +342,8 @@ vesa_bios_save_palette(int start, int colors, u_char *palette, int bits)
palette[i*3 + 1] = p[i*4 + 1] << bits;
palette[i*3 + 2] = p[i*4] << bits;
}
+
+ x86bios_free(p, 1);
return 0;
}
@@ -395,23 +351,29 @@ static int
vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
int bits)
{
+ x86regs_t regs;
+ int offs;
u_char *p;
int i;
- vesa_emu.x86.R_EAX = 0x4f09;
- vesa_emu.x86.R_EBX = 1;
- vesa_emu.x86.R_ECX = colors;
- vesa_emu.x86.R_EDX = start;
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f09;
+ regs.R_EBX = 1;
+ regs.R_ECX = colors;
+ regs.R_EDX = start;
- vesa_emu.x86.R_ES = SEG_ADDR(REALOFF(2));
- vesa_emu.x86.R_DI = SEG_OFF(REALOFF(2));
+ p = (u_char *)x86bios_alloc(1, &offs);
- p = emumem + REALOFF(2);
+ regs.R_ES = SEG_ADDR(offs);
+ regs.R_DI = SEG_OFF(offs);
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ if ((regs.R_AX & 0xff) != 0x4f)
+ {
+ x86bios_free(p, 1);
return 1;
+ }
bits = 8 - bits;
for (i = 0; i < colors; ++i) {
@@ -419,16 +381,20 @@ vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
g[i] = p[i*4 + 1] << bits;
b[i] = p[i*4] << bits;
}
+
+ x86bios_free(p, 1);
return 0;
}
static int
vesa_bios_load_palette(int start, int colors, u_char *palette, int bits)
{
+ x86regs_t regs;
+ int offs;
u_char *p;
int i;
- p = (emumem + REALOFF(2));
+ p = (u_char *)x86bios_alloc(1, &offs);
bits = 8 - bits;
for (i = 0; i < colors; ++i) {
@@ -438,17 +404,20 @@ vesa_bios_load_palette(int start, int colors, u_char *palette, int bits)
p[i*4 + 3] = 0;
}
- vesa_emu.x86.R_EAX = 0x4f09;
- vesa_emu.x86.R_EBX = 0;
- vesa_emu.x86.R_ECX = colors;
- vesa_emu.x86.R_EDX = start;
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f09;
+ regs.R_EBX = 0;
+ regs.R_ECX = colors;
+ regs.R_EDX = start;
+
+ regs.R_ES = SEG_ADDR(offs);
+ regs.R_DI = SEG_OFF(offs);
- vesa_emu.x86.R_ES = SEG_ADDR(REALOFF(2));
- vesa_emu.x86.R_DI = SEG_OFF(REALOFF(2));
+ x86bios_intr(&regs, 0x10);
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_free(p, 1);
- return ((vesa_emu.x86.R_AX & 0xff) != 0x4f);
+ return ((regs.R_AX & 0xff) != 0x4f);
}
#ifdef notyet
@@ -456,10 +425,12 @@ static int
vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
int bits)
{
+ x86regs_t regs;
+ int offs;
u_char *p;
int i;
- p = (emumem + REALOFF(2));
+ p = (u_char *)x86bios_alloc(1, &offs);
bits = 8 - bits;
for (i = 0; i < colors; ++i) {
@@ -469,93 +440,111 @@ vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
p[i*4 + 3] = 0;
}
- vesa_emu.x86.R_EAX = 0x4f09;
- vesa_emu.x86.R_EBX = 0;
- vesa_emu.x86.R_ECX = colors;
- vesa_emu.x86.R_EDX = start;
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f09;
+ regs.R_EBX = 0;
+ regs.R_ECX = colors;
+ regs.R_EDX = start;
- vesa_emu.x86.R_ES = SEG_ADDR(REALOFF(2));
- vesa_emu.x86.R_DI = SEG_OFF(REALOFF(2));
+ regs.R_ES = SEG_ADDR(offs);
+ regs.R_DI = SEG_OFF(offs);
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
- return ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ x86bios_free(p, 1);
+
+ return ((regs.R_AX & 0xff) != 0x4f);
}
#endif
static int
vesa_bios_state_buf_size(void)
{
- vesa_emu.x86.R_EAX = 0x4f04;
- vesa_emu.x86.R_ECX = STATE_ALL;
- vesa_emu.x86.R_EDX = STATE_SIZE;
+ x86regs_t regs;
+
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f04;
+ regs.R_ECX = STATE_ALL;
+ regs.R_EDX = STATE_SIZE;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ if ((regs.R_AX & 0xff) != 0x4f)
return 0;
- return vesa_emu.x86.R_BX*64;
+ return regs.R_BX * 64;
}
static int
vesa_bios_save_restore(int code, void *p, size_t size)
{
+ x86regs_t regs;
+ int offs;
u_char *buf;
- if (size > VESA_X86EMU_BUFSIZE)
+ if (size > VESA_BIOS_BUFSIZE)
return (1);
- vesa_emu.x86.R_EAX = 0x4f04;
- vesa_emu.x86.R_ECX = STATE_ALL;
- vesa_emu.x86.R_EDX = code;
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f04;
+ regs.R_ECX = STATE_ALL;
+ regs.R_EDX = code;
- buf = emumem + REALOFF(2);
+ buf = (u_char *)x86bios_alloc(1, &offs);
- vesa_emu.x86.R_ES = SEG_ADDR(REALOFF(2));
- vesa_emu.x86.R_DI = SEG_OFF(REALOFF(2));
+ regs.R_ES = SEG_ADDR(offs);
+ regs.R_DI = SEG_OFF(offs);
bcopy(p, buf, size);
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
bcopy(buf, p, size);
- return ((vesa_emu.x86.R_AX & 0xff) != 0x4f);
+ x86bios_free(p, 1);
+
+ return ((regs.R_AX & 0xff) != 0x4f);
}
static int
vesa_bios_get_line_length(void)
{
- vesa_emu.x86.R_EAX = 0x4f06;
- vesa_emu.x86.R_EBX = 1;
+ x86regs_t regs;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f06;
+ regs.R_EBX = 1;
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ x86bios_intr(&regs, 0x10);
+
+ if ((regs.R_AX & 0xff) != 0x4f)
return -1;
- return vesa_emu.x86.R_BX;
+
+ return regs.R_BX;
}
static int
vesa_bios_set_line_length(int pixel, int *bytes, int *lines)
{
- vesa_emu.x86.R_EAX = 0x4f06;
- vesa_emu.x86.R_EBX = 0;
- vesa_emu.x86.R_ECX = pixel;
+ x86regs_t regs;
+
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f06;
+ regs.R_EBX = 0;
+ regs.R_ECX = pixel;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
#if VESA_DEBUG > 1
- printf("bx:%d, cx:%d, dx:%d\n", vesa_emu.x86.R_BX, vesa_emu.x86.R_CX, vesa_emu.x86.R_DX);
+ printf("bx:%d, cx:%d, dx:%d\n", regs.R_BX, regs.R_CX, regs.R_DX);
#endif
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ if ((regs.R_AX & 0xff) != 0x4f)
return -1;
if (bytes)
- *bytes = vesa_emu.x86.R_BX;
+ *bytes = regs.R_BX;
if (lines)
- *lines = vesa_emu.x86.R_DX;
+ *lines = regs.R_DX;
return 0;
}
@@ -564,16 +553,19 @@ vesa_bios_set_line_length(int pixel, int *bytes, int *lines)
static int
vesa_bios_get_start(int *x, int *y)
{
- vesa_emu.x86.R_EAX = 0x4f07;
- vesa_emu.x86.R_EBX = 1;
+ x86regs_t regs;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f07;
+ regs.R_EBX = 1;
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ x86bios_intr(&regs, 0x10);
+
+ if ((regs.R_AX & 0xff) != 0x4f)
return -1;
- *x = vesa_emu.x86.R_CX;
- *y = vesa_emu.x86.R_DX;
+ *x = regs.R_CX;
+ *y = regs.R_DX;
return 0;
}
@@ -582,14 +574,17 @@ vesa_bios_get_start(int *x, int *y)
static int
vesa_bios_set_start(int x, int y)
{
- vesa_emu.x86.R_EAX = 0x4f07;
- vesa_emu.x86.R_EBX = 0x80;
- vesa_emu.x86.R_EDX = y;
- vesa_emu.x86.R_ECX = x;
+ x86regs_t regs;
+
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f07;
+ regs.R_EBX = 0x80;
+ regs.R_EDX = y;
+ regs.R_ECX = x;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
- return ((vesa_emu.x86.R_AX & 0xff) != 0x4f);
+ return ((regs.R_AX & 0xff) != 0x4f);
}
/* map a generic video mode to a known mode */
@@ -660,11 +655,45 @@ vesa_translate_mmodel(u_int8_t vmodel)
}
static int
+vesa_get_line_width(video_info_t *info)
+{
+ int len;
+ int width;
+
+ width = info->vi_width;
+
+ if (info->vi_flags & V_INFO_GRAPHICS)
+ switch (info->vi_depth / info->vi_planes) {
+ case 1:
+ return (width / 8);
+ case 2:
+ return (width / 4);
+ case 4:
+ return (width / 2);
+ case 8:
+ return (width);
+ case 15:
+ case 16:
+ return (width * 2);
+ case 24:
+ case 32:
+ return (width * 4);
+ }
+
+ len = vesa_bios_get_line_length();
+
+ return (len > 0 ? len : width);
+}
+
+static int
vesa_bios_init(void)
{
static struct vesa_info buf;
struct vesa_mode vmode;
video_info_t *p;
+ x86regs_t regs;
+ size_t bsize;
+ int offs;
u_char *vmbuf;
int is_via_cle266;
int modes;
@@ -678,16 +707,17 @@ vesa_bios_init(void)
vesa_vmode_max = 0;
vesa_vmode[0].vi_mode = EOT;
- vmbuf = (emumem + REALOFF(2));
+ vmbuf = (u_char *)x86bios_alloc(1, &offs);
bcopy("VBE2", vmbuf, 4); /* try for VBE2 data */
- vesa_emu.x86.R_EAX = 0x4f00;
- vesa_emu.x86.R_ES = SEG_ADDR(REALOFF(2));
- vesa_emu.x86.R_DI = SEG_OFF(REALOFF(2));
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f00;
+ regs.R_ES = SEG_ADDR(offs);
+ regs.R_DI = SEG_OFF(offs);
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
- if (((vesa_emu.x86.R_AX & 0xff) != 0x4f) || bcmp("VESA", vmbuf, 4))
+ if (((regs.R_AX & 0xff) != 0x4f) || bcmp("VESA", vmbuf, 4))
return 1;
bcopy(vmbuf, &buf, sizeof(buf));
@@ -707,17 +737,17 @@ vesa_bios_init(void)
return 1;
}
- vesa_oemstr = (char *)(emumem + L_ADD(vesa_adp_info->v_oemstr));
+ vesa_oemstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_oemstr));
is_via_cle266 = strcmp(vesa_oemstr, VESA_VIA_CLE266) == 0;
if (vesa_adp_info->v_version >= 0x0200) {
- vesa_venderstr = (char *)(emumem+L_ADD(vesa_adp_info->v_venderstr));
- vesa_prodstr = (char *)(emumem+L_ADD(vesa_adp_info->v_prodstr));
- vesa_revstr = (char *)(emumem+L_ADD(vesa_adp_info->v_revstr));
+ vesa_venderstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_venderstr));
+ vesa_prodstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_prodstr));
+ vesa_revstr = (char *)x86bios_offset(FARP(vesa_adp_info->v_revstr));
}
- vesa_vmodetab = (u_int16_t *)(emumem+L_ADD(vesa_adp_info->v_modetable));
+ vesa_vmodetab = (uint16_t *)x86bios_offset(FARP(vesa_adp_info->v_modetable));
if (vesa_vmodetab == NULL)
return 1;
@@ -802,7 +832,7 @@ vesa_bios_init(void)
- vmode.v_lfb;
else
vesa_vmode[modes].vi_buffer_size
- = vmode.v_offscreen + vmode.v_offscreensize*1024
+ = vmode.v_offscreen + vmode.v_offscreensize * 1024;
#endif
vesa_vmode[modes].vi_mem_model
= vesa_translate_mmodel(vmode.v_memmodel);
@@ -840,9 +870,26 @@ vesa_bios_init(void)
vesa_vmode[modes].vi_flags
= vesa_translate_flags(vmode.v_modeattr) | V_INFO_VESA;
+
+ /* Does it have enough memory to support this mode? */
+ bsize = vesa_get_line_width(&vesa_vmode[modes]);
+ bsize *= vesa_vmode[modes].vi_height;
+ if (bsize > vesa_vmode[modes].vi_buffer_size) {
+#if VESA_DEBUG > 1
+ printf(
+ "Rejecting VESA %s mode: %d x %d x %d bpp attr = %x, not enough memory\n",
+ (vmode.v_modeattr & V_MODEGRAPHICS) != 0 ? "graphics" : "text",
+ vmode.v_width, vmode.v_height, vmode.v_bpp, vmode.v_modeattr);
+#endif
+ continue;
+ }
+
++modes;
}
vesa_vmode[modes].vi_mode = EOT;
+
+ x86bios_free(vmbuf, 1);
+
if (bootverbose)
printf("VESA: %d mode(s) found\n", modes);
@@ -870,7 +917,8 @@ vesa_map_buffer(u_int paddr, size_t size)
u_int off;
off = paddr - trunc_page(paddr);
- vaddr = (vm_offset_t)pmap_mapdev(paddr - off, size + off);
+ vaddr = (vm_offset_t)pmap_mapdev_attr(paddr - off, size + off,
+ PAT_WRITE_COMBINING);
#if VESA_DEBUG > 1
printf("vesa_map_buffer: paddr:%x vaddr:%tx size:%zx off:%x\n",
paddr, vaddr, size, off);
@@ -1048,7 +1096,6 @@ static int
vesa_set_mode(video_adapter_t *adp, int mode)
{
video_info_t info;
- int len;
if (adp != vesa_adp)
return (*prevvidsw->set_mode)(adp, mode);
@@ -1126,46 +1173,17 @@ vesa_set_mode(video_adapter_t *adp, int mode)
} else {
vesa_adp->va_buffer = 0;
vesa_adp->va_buffer_size = info.vi_buffer_size;
- vesa_adp->va_window = (vm_offset_t)(emumem+L_ADD(info.vi_window));
+ vesa_adp->va_window = BIOS_PADDRTOVADDR(info.vi_window);
vesa_adp->va_window_size = info.vi_window_size;
vesa_adp->va_window_gran = info.vi_window_gran;
}
vesa_adp->va_window_orig = 0;
- len = vesa_bios_get_line_length();
- if (len > 0) {
- vesa_adp->va_line_width = len;
- } else if (info.vi_flags & V_INFO_GRAPHICS) {
- switch (info.vi_depth/info.vi_planes) {
- case 1:
- vesa_adp->va_line_width = info.vi_width/8;
- break;
- case 2:
- vesa_adp->va_line_width = info.vi_width/4;
- break;
- case 4:
- vesa_adp->va_line_width = info.vi_width/2;
- break;
- case 8:
- default: /* shouldn't happen */
- vesa_adp->va_line_width = info.vi_width;
- break;
- case 15:
- case 16:
- vesa_adp->va_line_width = info.vi_width*2;
- break;
- case 24:
- case 32:
- vesa_adp->va_line_width = info.vi_width*4;
- break;
- }
- } else {
- vesa_adp->va_line_width = info.vi_width;
- }
+ vesa_adp->va_line_width = vesa_get_line_width(&info);
vesa_adp->va_disp_start.x = 0;
vesa_adp->va_disp_start.y = 0;
#if VESA_DEBUG > 0
- printf("vesa_set_mode(): vi_width:%d, len:%d, line_width:%d\n",
- info.vi_width, len, vesa_adp->va_line_width);
+ printf("vesa_set_mode(): vi_width:%d, line_width:%d\n",
+ info.vi_width, vesa_adp->va_line_width);
#endif
bcopy(&info, &vesa_adp->va_info, sizeof(vesa_adp->va_info));
@@ -1275,14 +1293,17 @@ vesa_load_state(video_adapter_t *adp, void *p)
static int
vesa_get_origin(video_adapter_t *adp, off_t *offset)
{
- vesa_emu.x86.R_EAX = 0x4f05;
- vesa_emu.x86.R_EBX = 0x10;
+ x86regs_t regs;
+
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f05;
+ regs.R_EBX = 0x10;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ x86bios_intr(&regs, 0x10);
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ if ((regs.R_AX & 0xff) != 0x4f)
return 1;
- *offset = vesa_emu.x86.DX*adp->va_window_gran;
+ *offset = regs.DX * adp->va_window_gran;
return 0;
}
@@ -1291,6 +1312,8 @@ vesa_get_origin(video_adapter_t *adp, off_t *offset)
static int
vesa_set_origin(video_adapter_t *adp, off_t offset)
{
+ x86regs_t regs;
+
/*
* This function should return as quickly as possible to
* maintain good performance of the system. For this reason,
@@ -1307,18 +1330,20 @@ vesa_set_origin(video_adapter_t *adp, off_t offset)
if (adp->va_window_gran == 0)
return 1;
- vesa_emu.x86.R_EAX = 0x4f05;
- vesa_emu.x86.R_EBX = 0;
- vesa_emu.x86.R_EDX = offset/adp->va_window_gran;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f05;
+ regs.R_EBX = 0;
+ regs.R_EDX = offset / adp->va_window_gran;
+ x86bios_intr(&regs, 0x10);
- if ((vesa_emu.x86.R_AX & 0xff) != 0x4f)
+ if ((regs.R_AX & 0xff) != 0x4f)
return 1;
- vesa_emu.x86.R_EAX = 0x4f05;
- vesa_emu.x86.R_EBX = 1;
- vesa_emu.x86.R_EDX = offset/adp->va_window_gran;
- x86emu_exec_intr(&vesa_emu, 0x10);
+ bzero(&regs, sizeof(regs));
+ regs.R_EAX = 0x4f05;
+ regs.R_EBX = 1;
+ regs.R_EDX = offset / adp->va_window_gran;
+ x86bios_intr(&regs, 0x10);
adp->va_window_orig = (offset/adp->va_window_gran)*adp->va_window_gran;
return 0; /* XXX */
@@ -1653,22 +1678,6 @@ vesa_load(void)
if (vesa_init_done)
return 0;
- /* Can `emumem' be NULL here? */
- emumem = pmap_mapbios(0x0, 0xc00000);
-
- memset(&vesa_emu, 0, sizeof(vesa_emu));
- x86emu_init_default(&vesa_emu);
-
- vesa_emu.emu_inb = vm86_emu_inb;
- vesa_emu.emu_inw = vm86_emu_inw;
- vesa_emu.emu_inl = vm86_emu_inl;
- vesa_emu.emu_outb = vm86_emu_outb;
- vesa_emu.emu_outw = vm86_emu_outw;
- vesa_emu.emu_outl = vm86_emu_outl;
-
- vesa_emu.mem_base = (char *)emumem;
- vesa_emu.mem_size = 1024 * 1024;
-
/* locate a VGA adapter */
s = spltty();
vesa_adp = NULL;
@@ -1716,9 +1725,6 @@ vesa_unload(void)
}
splx(s);
- if (emumem)
- pmap_unmapdev((vm_offset_t)emumem, 0xc00000);
-
return error;
}
@@ -1743,6 +1749,6 @@ static moduledata_t vesa_mod = {
};
DECLARE_MODULE(vesa, vesa_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
-MODULE_DEPEND(vesa, x86emu, 1, 1, 1);
+MODULE_DEPEND(vesa, x86bios, 1, 1, 1);
#endif /* VGA_NO_MODE_CHANGE */
diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h
index e7bc349..45ebc21 100644
--- a/sys/dev/hwpmc/pmc_events.h
+++ b/sys/dev/hwpmc/pmc_events.h
@@ -1979,6 +1979,30 @@ __PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
#define PMC_EV_TSC_FIRST PMC_EV_TSC_TSC
#define PMC_EV_TSC_LAST PMC_EV_TSC_TSC
+
+/*
+ * Intel XScale events from "Intel XScale Core Developer's Manual",
+ * January 2004, #27347302
+ */
+#define __PMC_EV_XSCALE() \
+ __PMC_EV(XSCALE, IC_FETCH) \
+ __PMC_EV(XSCALE, IC_MISS) \
+ __PMC_EV(XSCALE, DATA_DEPENDENCY_STALL) \
+ __PMC_EV(XSCALE, ITLB_MISS) \
+ __PMC_EV(XSCALE, DTLB_MISS) \
+ __PMC_EV(XSCALE, BRANCH_EXECUTED) \
+ __PMC_EV(XSCALE, BRANCH_MISPRED) \
+ __PMC_EV(XSCALE, INSTR_EXECUTED) \
+ __PMC_EV(XSCALE, DC_FULL_CYCLE) \
+ __PMC_EV(XSCALE, DC_FULL_CONTIG) \
+ __PMC_EV(XSCALE, DC_ACCESS) \
+ __PMC_EV(XSCALE, DC_MISS) \
+ __PMC_EV(XSCALE, DC_WRITEBACK) \
+ __PMC_EV(XSCALE, PC_CHANGE)
+
+#define PMC_EV_XSCALE_FIRST PMC_EV_XSCALE_IC_FETCH
+#define PMC_EV_XSCALE_LAST PMC_EV_XSCALE_PC_CHANGE
+
/*
* All known PMC events.
*
@@ -1996,6 +2020,7 @@ __PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
* 0x11000 0x0080 INTEL Pentium 4 events
* 0x11080 0x0080 INTEL Pentium MMX events
* 0x11100 0x0100 INTEL Pentium Pro/P-II/P-III/Pentium-M events
+ * 0x11200 0x00FF INTEL XScale events
*/
#define __PMC_EVENTS() \
__PMC_EV_BLOCK(TSC, 0x01000) \
@@ -2013,9 +2038,11 @@ __PMC_EV_ALIAS("SIMD_INT_64.SHUFFLE_MOVE", IAP_EVENT_FDH_40H)
__PMC_EV_BLOCK(P5, 0x11080) \
__PMC_EV_P5() \
__PMC_EV_BLOCK(P6, 0x11100) \
- __PMC_EV_P6()
+ __PMC_EV_P6() \
+ __PMC_EV_BLOCK(XSCALE, 0x11200) \
+ __PMC_EV_XSCALE()
#define PMC_EVENT_FIRST PMC_EV_TSC_TSC
-#define PMC_EVENT_LAST PMC_EV_P6_LAST
+#define PMC_EVENT_LAST PMC_EV_XSCALE_LAST
#endif /* _DEV_HWPMC_PMC_EVENTS_H_ */
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index cd23972..b153e65 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -1012,7 +1012,12 @@ static void
ndis_vap_delete(struct ieee80211vap *vap)
{
struct ndis_vap *nvp = NDIS_VAP(vap);
+ struct ieee80211com *ic = vap->iv_ic;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct ndis_softc *sc = ifp->if_softc;
+ ndis_stop(sc);
+ callout_drain(&sc->ndis_scan_callout);
ieee80211_vap_detach(vap);
free(nvp, M_80211_VAP);
}
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 50c1249..d13e208 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -63,7 +63,6 @@ __FBSDID("$FreeBSD$");
/*
* General defines
*/
-
#define MBOX_DELAY_COUNT 1000000 / 100
#define ISP_MARK_PORTDB(a, b, c) \
isp_prt(isp, ISP_LOGSANCFG, \
@@ -1547,24 +1546,18 @@ isp_fibre_init(ispsoftc_t *isp)
}
icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
- if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
- icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
- isp_prt(isp, ISP_LOGERR,
- "bad frame length (%d) from NVRAM- using %d",
- DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
+ if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
+ isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
}
icbp->icb_maxalloc = fcp->isp_maxalloc;
if (icbp->icb_maxalloc < 1) {
- isp_prt(isp, ISP_LOGERR,
- "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
+ isp_prt(isp, ISP_LOGERR, "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
icbp->icb_maxalloc = 16;
}
icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
if (icbp->icb_execthrottle < 1) {
- isp_prt(isp, ISP_LOGERR,
- "bad execution throttle of %d- using %d",
- DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
+ isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
}
icbp->icb_retry_delay = fcp->isp_retry_delay;
@@ -1658,18 +1651,18 @@ isp_fibre_init(ispsoftc_t *isp)
/*
* For 22XX > 2.1.26 && 23XX, set some options.
- * XXX: Probably okay for newer 2100 f/w too.
*/
if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
- /*
- * Turn on LIP F8 async event (1)
- * Turn on generate AE 8013 on all LIP Resets (2)
- * Disable LIP F7 switching (8)
- */
MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
- mbs.param[1] = 0xb;
+ mbs.param[1] = IFCOPT1_DISF7SWTCH|IFCOPT1_LIPASYNC|IFCOPT1_LIPF8;
mbs.param[2] = 0;
mbs.param[3] = 0;
+ if (ISP_FW_NEWER_THAN(isp, 3, 16, 0)) {
+ mbs.param[1] |= IFCOPT1_EQFQASYNC|IFCOPT1_CTIO_RETRY;
+ if (fcp->role & ISP_ROLE_TARGET) {
+ mbs.param[3] = IFCOPT3_NOPRLI;
+ }
+ }
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
return;
@@ -2093,8 +2086,7 @@ isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
* or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
*/
static int
-isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid,
- int flags, int gs)
+isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags, int gs)
{
mbreg_t mbs;
uint8_t q[QENTRY_LEN];
@@ -2771,15 +2763,21 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
/*
* Make sure we're okay for doing this right now.
*/
- if (fcp->isp_loopstate != LOOP_PDB_RCVD && fcp->isp_loopstate != LOOP_FSCAN_DONE && fcp->isp_loopstate != LOOP_LSCAN_DONE) {
- isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d", fcp->isp_loopstate);
+ if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
+ fcp->isp_loopstate != LOOP_FSCAN_DONE &&
+ fcp->isp_loopstate != LOOP_LSCAN_DONE) {
+ isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d",
+ fcp->isp_loopstate);
return (-1);
}
- if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT || fcp->isp_topo == TOPO_N_PORT) {
+ if (fcp->isp_topo == TOPO_FL_PORT ||
+ fcp->isp_topo == TOPO_NL_PORT ||
+ fcp->isp_topo == TOPO_N_PORT) {
if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
if (isp_scan_loop(isp, chan) != 0) {
- isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: isp_scan_loop failed");
+ isp_prt(isp, ISP_LOGWARN,
+ "isp_pdb_sync: isp_scan_loop failed");
return (-1);
}
}
@@ -2788,13 +2786,15 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
if (fcp->isp_loopstate < LOOP_FSCAN_DONE) {
if (isp_scan_fabric(isp, chan) != 0) {
- isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: isp_scan_fabric failed");
+ isp_prt(isp, ISP_LOGWARN,
+ "isp_pdb_sync: isp_scan_fabric failed");
return (-1);
}
}
}
- isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d Synchronizing PDBs", chan);
+ isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
+ "Chan %d Synchronizing PDBs", chan);
fcp->isp_loopstate = LOOP_SYNCING_PDB;
@@ -2823,7 +2823,11 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
lp->state = FC_PORTDB_STATE_NIL;
isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
if (lp->autologin == 0) {
- (void) isp_plogx(isp, chan, lp->handle, lp->portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 0);
+ (void) isp_plogx(isp, chan, lp->handle,
+ lp->portid,
+ PLOGX_FLG_CMD_LOGO |
+ PLOGX_FLG_IMPLICIT |
+ PLOGX_FLG_FREE_NPHDL, 0);
} else {
lp->autologin = 0;
}
@@ -3069,7 +3073,8 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
for (i = 0; i < MAX_FC_TARG; i++) {
lp = &fcp->portdb[i];
- if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
+ if (lp->state == FC_PORTDB_STATE_NIL ||
+ lp->target_mode) {
continue;
}
if (lp->node_wwn != tmp.node_wwn) {
@@ -3587,7 +3592,8 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
lp = &fcp->portdb[dbidx];
- if (lp->state != FC_PORTDB_STATE_PROBATIONAL || lp->target_mode) {
+ if (lp->state != FC_PORTDB_STATE_PROBATIONAL ||
+ lp->target_mode) {
continue;
}
if (lp->portid == portid) {
@@ -3824,7 +3830,8 @@ isp_scan_fabric(ispsoftc_t *isp, int chan)
if (fcp->portdb[dbidx].target_mode) {
continue;
}
- if (fcp->portdb[dbidx].node_wwn == wwnn && fcp->portdb[dbidx].port_wwn == wwpn) {
+ if (fcp->portdb[dbidx].node_wwn == wwnn &&
+ fcp->portdb[dbidx].port_wwn == wwpn) {
break;
}
}
diff --git a/sys/dev/isp/isp_stds.h b/sys/dev/isp/isp_stds.h
index d0a9812..2ed66cb 100644
--- a/sys/dev/isp/isp_stds.h
+++ b/sys/dev/isp/isp_stds.h
@@ -31,7 +31,6 @@
*/
#ifndef _ISP_STDS_H
#define _ISP_STDS_H
-
/*
* FC Frame Header
*
@@ -147,6 +146,7 @@ typedef struct {
#define FCP_SNSLEN_VALID 0x02
#define FCP_RSPLEN_VALID 0x01
+#define FCP_MAX_RSPLEN 0x08
/*
* FCP Response Code Definitions
* Source: NCITS T10, Project 1144D, Revision 08 (aka FCP2r08)
@@ -159,6 +159,8 @@ typedef struct {
#define FCP_RSPNS_EROFS 3
#define FCP_RSPNS_TMF_REJECT 4
#define FCP_RSPNS_TMF_FAILED 5
+#define FCP_RSPNS_TMF_SUCCEEDED 8
+#define FCP_RSPNS_TMF_INCORRECT_LUN 9
/* unconverted miscellany */
diff --git a/sys/dev/isp/isp_tpublic.h b/sys/dev/isp/isp_tpublic.h
deleted file mode 100644
index b16440b..0000000
--- a/sys/dev/isp/isp_tpublic.h
+++ /dev/null
@@ -1,428 +0,0 @@
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 1997-2007 by Matthew Jacob
- * 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.
- */
-/*
- * Host Adapter Public Target Interface Structures && Routines
- */
-
-#ifndef _ISP_TPUBLIC_H
-#define _ISP_TPUBLIC_H 1
-
-/*
- * Action codes set by the MD target driver for
- * the external layer to figure out what to do with.
- */
-typedef enum {
- QOUT_HBA_REG=0, /* the argument is a pointer to a hba_register_t */
- QOUT_ENABLE, /* the argument is a pointer to a enadis_t */
- QOUT_DISABLE, /* the argument is a pointer to a enadis_t */
- QOUT_TMD_START, /* the argument is a pointer to a tmd_cmd_t */
- QOUT_TMD_DONE, /* the argument is a pointer to a tmd_cmd_t */
- QOUT_NOTIFY, /* the argument is a pointer to a tmd_notify_t */
- QOUT_HBA_UNREG /* the argument is a pointer to a hba_register_t */
-} tact_e;
-
-/*
- * Action codes set by the external layer for the
- * MD driver to figure out what to do with.
- */
-typedef enum {
- QIN_HBA_REG=99, /* the argument is a pointer to a hba_register_t */
- QIN_GETINFO, /* the argument is a pointer to a info_t */
- QIN_SETINFO, /* the argument is a pointer to a info_t */
- QIN_GETDLIST, /* the argument is a pointer to a fc_dlist_t */
- QIN_ENABLE, /* the argument is a pointer to a enadis_t */
- QIN_DISABLE, /* the argument is a pointer to a enadis_t */
- QIN_TMD_CONT, /* the argument is a pointer to a tmd_cmd_t */
- QIN_TMD_FIN, /* the argument is a pointer to a tmd_cmd_t */
- QIN_NOTIFY_ACK, /* the argument is a pointer to a tmd_notify_t */
- QIN_HBA_UNREG, /* the argument is a pointer to a hba_register_t */
-} qact_e;
-
-/*
- * This structure is used to register to other software modules the
- * binding of an HBA identifier, driver name and instance and the
- * lun width capapbilities of this target driver. It's up to each
- * platform to figure out how it wants to do this, but a typical
- * sequence would be for the MD layer to find some external module's
- * entry point and start by sending a QOUT_HBA_REG with info filled
- * in, and the external module to call back with a QIN_HBA_REG that
- * passes back the corresponding information.
- */
-#define QR_VERSION 16
-typedef struct {
- /* NB: tags from here to r_version must never change */
- void * r_identity;
- void (*r_action)(qact_e, void *);
- char r_name[8];
- int r_inst;
- int r_version;
- uint32_t r_locator;
- uint32_t r_nchannels;
- enum { R_FC, R_SPI } r_type;
- void * r_private;
-} hba_register_t;
-
-/*
- * An information structure that is used to get or set per-channel transport layer parameters.
- */
-typedef struct {
- void * i_identity;
- enum { I_FC, I_SPI } i_type;
- int i_channel;
- int i_error;
- union {
- struct {
- uint64_t wwnn_nvram;
- uint64_t wwpn_nvram;
- uint64_t wwnn;
- uint64_t wwpn;
- } fc;
- struct {
- int iid;
- } spi;
- } i_id;
-} info_t;
-
-/*
- * An information structure to return a list of logged in WWPNs. FC specific.
- */
-typedef struct {
- void * d_identity;
- int d_channel;
- int d_error;
- int d_count;
- uint64_t * d_wwpns;
-} fc_dlist_t;
-/*
- * Notify structure
- */
-typedef enum {
- NT_ABORT_TASK=0x1000,
- NT_ABORT_TASK_SET,
- NT_CLEAR_ACA,
- NT_CLEAR_TASK_SET,
- NT_LUN_RESET,
- NT_TARGET_RESET,
- NT_BUS_RESET,
- NT_LIP_RESET,
- NT_LINK_UP,
- NT_LINK_DOWN,
- NT_LOGOUT,
- NT_HBA_RESET
-} tmd_ncode_t;
-
-typedef struct tmd_notify {
- void * nt_hba; /* HBA tag */
- uint64_t nt_iid; /* inititator id */
- uint64_t nt_tgt; /* target id */
- uint16_t nt_lun; /* logical unit */
- uint16_t : 15,
- nt_need_ack : 1; /* this notify needs an ACK */
- uint64_t nt_tagval; /* tag value */
- uint32_t nt_channel; /* channel id */
- tmd_ncode_t nt_ncode; /* action */
- void * nt_lreserved;
- void * nt_hreserved;
-} tmd_notify_t;
-#define LUN_ANY 0xffff
-#define TGT_ANY ((uint64_t) -1)
-#define INI_ANY ((uint64_t) -1)
-#define TAG_ANY ((uint64_t) 0)
-#define MATCH_TMD(tmd, iid, lun, tag) \
- ( \
- (tmd) && \
- (iid == INI_ANY || iid == tmd->cd_iid) && \
- (lun == LUN_ANY || lun == tmd->cd_lun) && \
- (tag == TAG_ANY || tag == tmd->cd_tagval) \
- )
-
-/*
- * A word about ENABLE/DISABLE: the argument is a pointer to a enadis_t
- * with en_hba, en_iid, en_chan, en_tgt and en_lun filled out.
- *
- * If an error occurs in either enabling or disabling the described lun
- * cd_error is set with an appropriate non-zero value.
- */
-typedef struct {
- void * en_private; /* for outer layer usage */
- void * en_hba; /* HBA tag */
- uint64_t en_iid; /* initiator ID */
- uint64_t en_tgt; /* target id */
- uint16_t en_lun; /* logical unit */
- uint16_t en_chan; /* channel on card */
- int en_error;
-} enadis_t;
-
-/*
- * Suggested Software Target Mode Command Handling structure.
- *
- * A note about terminology:
- *
- * MD stands for "Machine Dependent".
- *
- * This driver is structured in three layers: Outer MD, core, and inner MD.
- * The latter also is bus dependent (i.e., is cognizant of PCI bus issues
- * as well as platform issues).
- *
- *
- * "Outer Layer" means "Other Module"
- *
- * Some additional module that actually implements SCSI target command
- * policy is the recipient of incoming commands and the source of the
- * disposition for them.
- *
- * The command structure below is one suggested possible MD command structure,
- * but since the handling of thbis is entirely in the MD layer, there is
- * no explicit or implicit requirement that it be used.
- *
- * The cd_private tag should be used by the MD layer to keep a free list
- * of these structures. Code outside of this driver can then use this
- * to identify it's own unit structures. That is, when not on the MD
- * layer's freelist, the MD layer should shove into it the identifier
- * that the outer layer has for it- passed in on an initial QIN_HBA_REG
- * call (see below).
- *
- * The cd_hba tag is a tag that uniquely identifies the HBA this target
- * mode command is coming from. The outer layer has to pass this back
- * unchanged to avoid chaos.
- *
- * The cd_iid, cd_tgt, cd_lun and cd_port tags are used to identify the
- * id of the initiator who sent us a command, the target claim to be, the
- * lun on the target we claim to be, and the port instance (for multiple
- * port host adapters) that this applies to (consider it an extra port
- * parameter). The iid, tgt and lun values are deliberately chosen to be
- * fat so that, for example, World Wide Names can be used instead of
- * the units that the firmware uses (in the case where the MD
- * layer maintains a port database, for example).
- *
- * The cd_tagtype field specifies what kind of command tag type, if
- * any, has been sent with the command. Note that the Outer Layer
- * still needs to pass the tag handle through unchanged even
- * if the tag type is CD_UNTAGGED.
- *
- * The cd_cdb contains storage for the passed in command descriptor block.
- * There is no need to define length as the callee should be able to
- * figure this out.
- *
- * The tag cd_lflags are the flags set by the MD driver when it gets
- * command incoming or when it needs to inform any outside entities
- * that the last requested action failed.
- *
- * The tag cd_hflags should be set by any outside software to indicate
- * the validity of sense and status fields (defined below) and to indicate
- * the direction data is expected to move. It is an error to have both
- * CDFH_DATA_IN and CDFH_DATA_OUT set.
- *
- * If the CDFH_STSVALID flag is set, the command should be completed (after
- * sending any data and/or status). If CDFH_SNSVALID is set and the MD layer
- * can also handle sending the associated sense data (either back with an
- * FCP RESPONSE IU for Fibre Channel or otherwise automatically handling a
- * REQUEST SENSE from the initator for this target/lun), the MD layer will
- * set the CDFL_SENTSENSE flag on successful transmission of the sense data.
- * It is an error for the CDFH_SNSVALID bit to be set and CDFH_STSVALID not
- * to be set. It is an error for the CDFH_SNSVALID be set and the associated
- * SCSI status (cd_scsi_status) not be set to CHECK CONDITON.
- *
- * The tag cd_data points to a data segment to either be filled or
- * read from depending on the direction of data movement. The tag
- * is undefined if no data direction is set. The MD layer and outer
- * layers must agree on the meaning of cd_data and it is specifically
- * not defined here.
- *
- * The tag cd_totlen is the total data amount expected to be moved
- * over the life of the command. It may be set by the MD layer, possibly
- * from the datalen field of an FCP CMND IU unit. If it shows up in the outer
- * layers set to zero and the CDB indicates data should be moved, the outer
- * layer should set it to the amount expected to be moved.
- *
- * The tag cd_resid should be the total residual of data not transferred.
- * The outer layers need to set this at the begining of command processing
- * to equal cd_totlen. As data is successfully moved, this value is decreased.
- * At the end of a command, any nonzero residual indicates the number of bytes
- * requested by the command but not moved.
- *
- * The tag cd_xfrlen is the length of the currently active data transfer.
- * This allows several interations between any outside software and the
- * MD layer to move data.
- *
- * The reason that total length and total residual have to be tracked
- * is to keep track of relative offset.
- *
- * The tags cd_sense and cd_scsi_status are pretty obvious.
- *
- * The tag cd_error is to communicate between the MD layer and outer software
- * the current error conditions.
- *
- * The tag cd_lreserved, cd_hreserved are scratch areas for use for the MD
- * and outer layers respectively.
- *
- */
-
-#ifndef TMD_CDBLEN
-#define TMD_CDBLEN 16
-#endif
-#ifndef TMD_SENSELEN
-#define TMD_SENSELEN 18
-#endif
-#ifndef QCDS
-#define QCDS (sizeof (void *))
-#endif
-
-typedef struct tmd_cmd {
- void * cd_private; /* private data pointer */
- void * cd_hba; /* HBA tag */
- void * cd_data; /* 'pointer' to data */
- uint64_t cd_iid; /* initiator ID */
- uint64_t cd_tgt; /* target id */
- uint8_t cd_lun[8]; /* logical unit */
- uint64_t cd_tagval; /* tag value */
- uint32_t cd_channel; /* channel index */
- uint32_t cd_lflags; /* flags lower level sets */
- uint32_t cd_hflags; /* flags higher level sets */
- uint32_t cd_totlen; /* total data load */
- uint32_t cd_resid; /* total data residual */
- uint32_t cd_xfrlen; /* current data load */
- int32_t cd_error; /* current error */
- uint8_t cd_tagtype; /* tag type */
- uint8_t cd_scsi_status;
- uint8_t cd_sense[TMD_SENSELEN];
- uint8_t cd_cdb[TMD_CDBLEN];
- union {
- void * ptrs[QCDS / sizeof (void *)];
- uint64_t llongs[QCDS / sizeof (uint64_t)];
- uint32_t longs[QCDS / sizeof (uint32_t)];
- uint16_t shorts[QCDS / sizeof (uint16_t)];
- uint8_t bytes[QCDS];
- } cd_lreserved[4], cd_hreserved[4];
-} tmd_cmd_t;
-
-/* defined tags */
-#define CD_UNTAGGED 0
-#define CD_SIMPLE_TAG 1
-#define CD_ORDERED_TAG 2
-#define CD_HEAD_TAG 3
-#define CD_ACA_TAG 4
-
-#ifndef TMD_SIZE
-#define TMD_SIZE (sizeof (tmd_cmd_t))
-#endif
-
-#define L0LUN_TO_FLATLUN(lptr) ((((lptr)[0] & 0x3f) << 8) | ((lptr)[1]))
-#define FLATLUN_TO_L0LUN(lptr, lun) \
- (lptr)[1] = lun & 0xff; \
- if (sizeof (lun) == 1) { \
- (lptr)[0] = 0; \
- } else { \
- uint16_t nl = lun; \
- if (nl == LUN_ANY) { \
- (lptr)[0] = (nl >> 8) & 0xff; \
- } else if (nl < 256) { \
- (lptr)[0] = 0; \
- } else { \
- (lptr)[0] = 0x40 | ((nl >> 8) & 0x3f); \
- } \
- } \
- memset(&(lptr)[2], 0, 6)
-
-/*
- * Note that NODISC (obviously) doesn't apply to non-SPI transport.
- *
- * Note that knowing the data direction and lengh at the time of receipt of
- * a command from the initiator is a feature only of Fibre Channel.
- *
- * The CDFL_BIDIR is in anticipation of the adoption of some newer
- * features required by OSD.
- *
- * The principle selector for MD layer to know whether data is to
- * be transferred in any QOUT_TMD_CONT call is cd_xfrlen- the
- * flags CDFH_DATA_IN and CDFH_DATA_OUT define which direction.
- */
-#define CDFL_SNSVALID 0x01 /* sense data (from f/w) good */
-#define CDFL_SENTSTATUS 0x02 /* last action sent status */
-#define CDFL_DATA_IN 0x04 /* target (us) -> initiator (them) */
-#define CDFL_DATA_OUT 0x08 /* initiator (them) -> target (us) */
-#define CDFL_BIDIR 0x0C /* bidirectional data */
-#define CDFL_ERROR 0x10 /* last action ended in error */
-#define CDFL_NODISC 0x20 /* disconnects disabled */
-#define CDFL_SENTSENSE 0x40 /* last action sent sense data */
-#define CDFL_BUSY 0x80 /* this command is not on a free list */
-#define CDFL_PRIVATE 0xFF000000 /* private layer flags */
-
-#define CDFH_SNSVALID 0x01 /* sense data (from outer layer) good */
-#define CDFH_STSVALID 0x02 /* status valid */
-#define CDFH_DATA_IN 0x04 /* target (us) -> initiator (them) */
-#define CDFH_DATA_OUT 0x08 /* initiator (them) -> target (us) */
-#define CDFH_DATA_MASK 0x0C /* mask to cover data direction */
-#define CDFH_PRIVATE 0xFF000000 /* private layer flags */
-
-
-/*
- * A word about the START/CONT/DONE/FIN dance:
- *
- * When the HBA is enabled for receiving commands, one may show up
- * without notice. When that happens, the MD target mode driver
- * gets a tmd_cmd_t, fills it with the info that just arrived, and
- * calls the outer layer with a QOUT_TMD_START code and pointer to
- * the tmd_cmd_t.
- *
- * The outer layer decodes the command, fetches data, prepares stuff,
- * whatever, and starts by passing back the pointer with a QIN_TMD_CONT
- * code which causes the MD target mode driver to generate CTIOs to
- * satisfy whatever action needs to be taken. When those CTIOs complete,
- * the MD target driver sends the pointer to the cmd_tmd_t back with
- * a QOUT_TMD_DONE code. This repeats for as long as necessary. These
- * may not be done in parallel- they are sequential operations.
- *
- * The outer layer signals it wants to end the command by settings within
- * the tmd_cmd_t itself. When the final QIN_TMD_CONT is reported completed,
- * the outer layer frees the tmd_cmd_t by sending the pointer to it
- * back with a QIN_TMD_FIN code.
- *
- * The graph looks like:
- *
- * QOUT_TMD_START -> [ QIN_TMD_CONT -> QOUT_TMD_DONE ] * -> QIN_TMD_FIN.
- *
- */
-
-/*
- * Target handler functions.
- *
- * The MD target handler function (the outer layer calls this)
- * should be be prototyped like:
- *
- * void target_action(qact_e, void *arg)
- *
- * The outer layer target handler function (the MD layer calls this)
- * should be be prototyped like:
- *
- * void scsi_target_handler(tact_e, void *arg)
- */
-#endif /* _ISP_TPUBLIC_H */
-/*
- * vim:ts=4:sw=4:expandtab
- */
diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h
index 8f68937..2f9d152 100644
--- a/sys/dev/isp/ispmbox.h
+++ b/sys/dev/isp/ispmbox.h
@@ -26,6 +26,7 @@
* SUCH DAMAGE.
*
*/
+
/*
* Mailbox and Queue Entry Definitions for for Qlogic ISP SCSI adapters.
*/
@@ -245,12 +246,38 @@
#define ASYNC_RCV_ERR 0x8048
/*
+ * Firmware Options. There are a lot of them.
+ *
+ * IFCOPTN - ISP Fibre Channel Option Word N
+ */
+#define IFCOPT1_EQFQASYNC (1 << 13) /* enable QFULL notification */
+#define IFCOPT1_EAABSRCVD (1 << 12)
+#define IFCOPT1_RJTASYNC (1 << 11) /* enable 8018 notification */
+#define IFCOPT1_ENAPURE (1 << 10)
+#define IFCOPT1_ENA8017 (1 << 7)
+#define IFCOPT1_DISGPIO67 (1 << 6)
+#define IFCOPT1_LIPLOSSIMM (1 << 5)
+#define IFCOPT1_DISF7SWTCH (1 << 4)
+#define IFCOPT1_CTIO_RETRY (1 << 3)
+#define IFCOPT1_LIPASYNC (1 << 1)
+#define IFCOPT1_LIPF8 (1 << 0)
+
+#define IFCOPT2_LOOPBACK (1 << 1)
+#define IFCOPT2_ATIO3_ONLY (1 << 0)
+
+#define IFCOPT3_NOPRLI (1 << 4) /* disable automatic sending of PRLI on local loops */
+#define IFCOPT3_RNDASYNC (1 << 1)
+/*
* 2.01.31 2200 Only. Need Bit 13 in Mailbox 1 for Set Firmware Options
* mailbox command to enable this.
*/
#define ASYNC_QFULL_SENT 0x8049
/*
+ * Needs to be enabled
+ */
+#define ASYNC_AUTO_PLOGI_RJT 0x8018
+/*
* 24XX only
*/
#define ASYNC_RJT_SENT 0x8049
diff --git a/sys/dev/kbd/kbd.c b/sys/dev/kbd/kbd.c
index 851f677..0813676 100644
--- a/sys/dev/kbd/kbd.c
+++ b/sys/dev/kbd/kbd.c
@@ -728,7 +728,7 @@ genkbd_event(keyboard_t *kbd, int event, void *arg)
size_t len;
u_char *cp;
int mode;
- int c;
+ u_int c;
/* assert(KBD_IS_VALID(kbd)) */
sc = (genkbd_softc_t *)arg;
@@ -837,13 +837,14 @@ static int fkey_change_ok(fkeytab_t *, fkeyarg_t *, struct thread *);
int
genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
{
+#ifndef KBD_DISABLE_KEYMAP_LOAD
+ keymap_t *mapp;
+#endif
keyarg_t *keyp;
fkeyarg_t *fkeyp;
int s;
int i;
-#ifndef KBD_DISABLE_KEYMAP_LOAD
int error;
-#endif
s = spltty();
switch (cmd) {
@@ -869,18 +870,29 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
break;
case GIO_KEYMAP: /* get keyboard translation table */
- bcopy(kbd->kb_keymap, arg, sizeof(*kbd->kb_keymap));
- break;
+ error = copyout(kbd->kb_keymap, *(void **)arg,
+ sizeof(keymap_t));
+ splx(s);
+ return (error);
case PIO_KEYMAP: /* set keyboard translation table */
#ifndef KBD_DISABLE_KEYMAP_LOAD
- error = keymap_change_ok(kbd->kb_keymap, (keymap_t *)arg,
- curthread);
+ mapp = malloc(sizeof *mapp, M_TEMP, M_NOWAIT);
+ error = copyin(*(void **)arg, mapp, sizeof *mapp);
+ if (error != 0) {
+ splx(s);
+ free(mapp, M_TEMP);
+ return (error);
+ }
+
+ error = keymap_change_ok(kbd->kb_keymap, mapp, curthread);
if (error != 0) {
splx(s);
+ free(mapp, M_TEMP);
return (error);
}
bzero(kbd->kb_accentmap, sizeof(*kbd->kb_accentmap));
- bcopy(arg, kbd->kb_keymap, sizeof(*kbd->kb_keymap));
+ bcopy(mapp, kbd->kb_keymap, sizeof(*kbd->kb_keymap));
+ free(mapp, M_TEMP);
break;
#else
splx(s);
diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c
index 991bc79..4a1dc8a 100644
--- a/sys/dev/mwl/if_mwl.c
+++ b/sys/dev/mwl/if_mwl.c
@@ -304,7 +304,7 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
+ device_printf(sc->sc_dev, "cannot if_alloc()\n");
return ENOSPC;
}
ic = ifp->if_l2com;
@@ -2303,8 +2303,10 @@ mwl_dma_setup(struct mwl_softc *sc)
int error, i;
error = mwl_rxdma_setup(sc);
- if (error != 0)
+ if (error != 0) {
+ mwl_rxdma_cleanup(sc);
return error;
+ }
for (i = 0; i < MWL_NUM_TX_QUEUES; i++) {
error = mwl_txdma_setup(sc, &sc->sc_txq[i]);
diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index 88c3489..6e8ca67 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -106,6 +106,7 @@ static int mxge_max_slices = 1;
static int mxge_rss_hash_type = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
static int mxge_always_promisc = 0;
static int mxge_initial_mtu = ETHERMTU_JUMBO;
+static int mxge_throttle = 0;
static char *mxge_fw_unaligned = "mxge_ethp_z8e";
static char *mxge_fw_aligned = "mxge_eth_z8e";
static char *mxge_fw_rss_aligned = "mxge_rss_eth_z8e";
@@ -143,7 +144,7 @@ MODULE_DEPEND(mxge, zlib, 1, 1, 1);
static int mxge_load_firmware(mxge_softc_t *sc, int adopt);
static int mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data);
-static int mxge_close(mxge_softc_t *sc);
+static int mxge_close(mxge_softc_t *sc, int down);
static int mxge_open(mxge_softc_t *sc);
static void mxge_tick(void *arg);
@@ -596,10 +597,13 @@ static int
mxge_select_firmware(mxge_softc_t *sc)
{
int aligned = 0;
+ int force_firmware = mxge_force_firmware;
+ if (sc->throttle)
+ force_firmware = sc->throttle;
- if (mxge_force_firmware != 0) {
- if (mxge_force_firmware == 1)
+ if (force_firmware != 0) {
+ if (force_firmware == 1)
aligned = 1;
else
aligned = 0;
@@ -1305,8 +1309,7 @@ mxge_reset(mxge_softc_t *sc, int interrupts_setup)
ss->lro_queued = 0;
ss->lro_flushed = 0;
if (ss->fw_stats != NULL) {
- ss->fw_stats->valid = 0;
- ss->fw_stats->send_done_count = 0;
+ bzero(ss->fw_stats, sizeof *ss->fw_stats);
}
}
sc->rdma_tags_available = 15;
@@ -1314,10 +1317,48 @@ mxge_reset(mxge_softc_t *sc, int interrupts_setup)
mxge_change_promisc(sc, sc->ifp->if_flags & IFF_PROMISC);
mxge_change_pause(sc, sc->pause);
mxge_set_multicast_list(sc);
+ if (sc->throttle) {
+ cmd.data0 = sc->throttle;
+ if (mxge_send_cmd(sc, MXGEFW_CMD_SET_THROTTLE_FACTOR,
+ &cmd)) {
+ device_printf(sc->dev,
+ "can't enable throttle\n");
+ }
+ }
return status;
}
static int
+mxge_change_throttle(SYSCTL_HANDLER_ARGS)
+{
+ mxge_cmd_t cmd;
+ mxge_softc_t *sc;
+ int err;
+ unsigned int throttle;
+
+ sc = arg1;
+ throttle = sc->throttle;
+ err = sysctl_handle_int(oidp, &throttle, arg2, req);
+ if (err != 0) {
+ return err;
+ }
+
+ if (throttle == sc->throttle)
+ return 0;
+
+ if (throttle < MXGE_MIN_THROTTLE || throttle > MXGE_MAX_THROTTLE)
+ return EINVAL;
+
+ mtx_lock(&sc->driver_mtx);
+ cmd.data0 = throttle;
+ err = mxge_send_cmd(sc, MXGEFW_CMD_SET_THROTTLE_FACTOR, &cmd);
+ if (err == 0)
+ sc->throttle = throttle;
+ mtx_unlock(&sc->driver_mtx);
+ return err;
+}
+
+static int
mxge_change_intr_coal(SYSCTL_HANDLER_ARGS)
{
mxge_softc_t *sc;
@@ -1379,7 +1420,7 @@ mxge_change_lro_locked(mxge_softc_t *sc, int lro_cnt)
ifp->if_capenable |= IFCAP_LRO;
sc->lro_cnt = lro_cnt;
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- mxge_close(sc);
+ mxge_close(sc, 0);
err = mxge_open(sc);
}
return err;
@@ -1495,6 +1536,10 @@ mxge_add_sysctls(mxge_softc_t *sc)
"read_write_dma_MBs",
CTLFLAG_RD, &sc->read_write_dma,
0, "DMA concurrent Read/Write speed in MB/s");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO,
+ "watchdog_resets",
+ CTLFLAG_RD, &sc->watchdog_resets,
+ 0, "Number of times NIC was reset");
/* performance related tunables */
@@ -1505,6 +1550,12 @@ mxge_add_sysctls(mxge_softc_t *sc)
"I", "interrupt coalescing delay in usecs");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
+ "throttle",
+ CTLTYPE_INT|CTLFLAG_RW, sc,
+ 0, mxge_change_throttle,
+ "I", "transmit throttling");
+
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
"flow_control_enabled",
CTLTYPE_INT|CTLFLAG_RW, sc,
0, mxge_change_flow_control,
@@ -3600,7 +3651,7 @@ abort:
}
static int
-mxge_close(mxge_softc_t *sc)
+mxge_close(mxge_softc_t *sc, int down)
{
mxge_cmd_t cmd;
int err, old_down_cnt;
@@ -3617,21 +3668,23 @@ mxge_close(mxge_softc_t *sc)
}
#endif
sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- old_down_cnt = sc->down_cnt;
- wmb();
- err = mxge_send_cmd(sc, MXGEFW_CMD_ETHERNET_DOWN, &cmd);
- if (err) {
- device_printf(sc->dev, "Couldn't bring down link\n");
- }
- if (old_down_cnt == sc->down_cnt) {
- /* wait for down irq */
- DELAY(10 * sc->intr_coal_delay);
- }
- wmb();
- if (old_down_cnt == sc->down_cnt) {
- device_printf(sc->dev, "never got down irq\n");
+ if (!down) {
+ old_down_cnt = sc->down_cnt;
+ wmb();
+ err = mxge_send_cmd(sc, MXGEFW_CMD_ETHERNET_DOWN, &cmd);
+ if (err) {
+ device_printf(sc->dev,
+ "Couldn't bring down link\n");
+ }
+ if (old_down_cnt == sc->down_cnt) {
+ /* wait for down irq */
+ DELAY(10 * sc->intr_coal_delay);
+ }
+ wmb();
+ if (old_down_cnt == sc->down_cnt) {
+ device_printf(sc->dev, "never got down irq\n");
+ }
}
-
mxge_free_mbufs(sc);
return 0;
@@ -3684,8 +3737,9 @@ static int
mxge_watchdog_reset(mxge_softc_t *sc, int slice)
{
struct pci_devinfo *dinfo;
+ struct mxge_slice_state *ss;
mxge_tx_ring_t *tx;
- int err;
+ int err, running, s, num_tx_slices = 1;
uint32_t reboot;
uint16_t cmd;
@@ -3719,6 +3773,30 @@ mxge_watchdog_reset(mxge_softc_t *sc, int slice)
reboot = mxge_read_reboot(sc);
device_printf(sc->dev, "NIC rebooted, status = 0x%x\n",
reboot);
+ running = sc->ifp->if_drv_flags & IFF_DRV_RUNNING;
+ if (running) {
+
+ /*
+ * quiesce NIC so that TX routines will not try to
+ * xmit after restoration of BAR
+ */
+
+ /* Mark the link as down */
+ if (sc->link_state) {
+ sc->link_state = 0;
+ if_link_state_change(sc->ifp,
+ LINK_STATE_DOWN);
+ }
+#ifdef IFNET_BUF_RING
+ num_tx_slices = sc->num_slices;
+#endif
+ /* grab all TX locks to ensure no tx */
+ for (s = 0; s < num_tx_slices; s++) {
+ ss = &sc->ss[s];
+ mtx_lock(&ss->tx.mtx);
+ }
+ mxge_close(sc, 1);
+ }
/* restore PCI configuration space */
dinfo = device_get_ivars(sc->dev);
pci_cfg_restore(sc->dev, dinfo);
@@ -3726,10 +3804,22 @@ mxge_watchdog_reset(mxge_softc_t *sc, int slice)
/* and redo any changes we made to our config space */
mxge_setup_cfg_space(sc);
- if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) {
- mxge_close(sc);
- err = mxge_open(sc);
+ /* reload f/w */
+ err = mxge_load_firmware(sc, 0);
+ if (err) {
+ device_printf(sc->dev,
+ "Unable to re-load f/w\n");
}
+ if (running) {
+ if (!err)
+ err = mxge_open(sc);
+ /* release all TX locks */
+ for (s = 0; s < num_tx_slices; s++) {
+ ss = &sc->ss[s];
+ mtx_unlock(&ss->tx.mtx);
+ }
+ }
+ sc->watchdog_resets++;
} else {
tx = &sc->ss[slice].tx;
device_printf(sc->dev,
@@ -3745,6 +3835,9 @@ mxge_watchdog_reset(mxge_softc_t *sc, int slice)
be32toh(sc->ss->fw_stats->send_done_count));
device_printf(sc->dev, "not resetting\n");
}
+ if (err)
+ device_printf(sc->dev, "watchdog reset failed\n");
+
return (err);
}
@@ -3860,11 +3953,11 @@ mxge_change_mtu(mxge_softc_t *sc, int mtu)
old_mtu = ifp->if_mtu;
ifp->if_mtu = mtu;
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- mxge_close(sc);
+ mxge_close(sc, 0);
err = mxge_open(sc);
if (err != 0) {
ifp->if_mtu = old_mtu;
- mxge_close(sc);
+ mxge_close(sc, 0);
(void) mxge_open(sc);
}
}
@@ -3922,7 +4015,7 @@ mxge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- mxge_close(sc);
+ mxge_close(sc, 0);
}
}
mtx_unlock(&sc->driver_mtx);
@@ -4016,6 +4109,7 @@ mxge_fetch_tunables(mxge_softc_t *sc)
TUNABLE_INT_FETCH("hw.mxge.rss_hash_type", &mxge_rss_hash_type);
TUNABLE_INT_FETCH("hw.mxge.rss_hashtype", &mxge_rss_hash_type);
TUNABLE_INT_FETCH("hw.mxge.initial_mtu", &mxge_initial_mtu);
+ TUNABLE_INT_FETCH("hw.mxge.throttle", &mxge_throttle);
if (sc->lro_cnt != 0)
mxge_lro_cnt = sc->lro_cnt;
@@ -4033,6 +4127,12 @@ mxge_fetch_tunables(mxge_softc_t *sc)
if (mxge_initial_mtu > ETHERMTU_JUMBO ||
mxge_initial_mtu < ETHER_MIN_LEN)
mxge_initial_mtu = ETHERMTU_JUMBO;
+
+ if (mxge_throttle && mxge_throttle > MXGE_MAX_THROTTLE)
+ mxge_throttle = MXGE_MAX_THROTTLE;
+ if (mxge_throttle && mxge_throttle < MXGE_MIN_THROTTLE)
+ mxge_throttle = MXGE_MIN_THROTTLE;
+ sc->throttle = mxge_throttle;
}
@@ -4645,7 +4745,7 @@ mxge_detach(device_t dev)
mtx_lock(&sc->driver_mtx);
sc->dying = 1;
if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING)
- mxge_close(sc);
+ mxge_close(sc, 0);
mtx_unlock(&sc->driver_mtx);
ether_ifdetach(sc->ifp);
callout_drain(&sc->co_hdl);
diff --git a/sys/dev/mxge/if_mxge_var.h b/sys/dev/mxge/if_mxge_var.h
index 47c39b5..b25adb4 100644
--- a/sys/dev/mxge/if_mxge_var.h
+++ b/sys/dev/mxge/if_mxge_var.h
@@ -261,6 +261,7 @@ struct mxge_softc {
int fw_multicast_support;
int link_width;
int max_mtu;
+ int throttle;
int tx_defrag;
int media_flags;
int need_media_probe;
@@ -286,6 +287,8 @@ struct mxge_softc {
#define MXGE_PCI_REV_Z8ES 1
#define MXGE_XFP_COMPLIANCE_BYTE 131
#define MXGE_SFP_COMPLIANCE_BYTE 3
+#define MXGE_MIN_THROTTLE 416
+#define MXGE_MAX_THROTTLE 4096
#define MXGE_HIGHPART_TO_U32(X) \
(sizeof (X) == 8) ? ((uint32_t)((uint64_t)(X) >> 32)) : (0)
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 0b7b267..47aedbd 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -2149,62 +2149,38 @@ pci_disable_busmaster_method(device_t dev, device_t child)
int
pci_enable_io_method(device_t dev, device_t child, int space)
{
- uint16_t command;
uint16_t bit;
- char *error;
-
- bit = 0;
- error = NULL;
switch(space) {
case SYS_RES_IOPORT:
bit = PCIM_CMD_PORTEN;
- error = "port";
break;
case SYS_RES_MEMORY:
bit = PCIM_CMD_MEMEN;
- error = "memory";
break;
default:
return (EINVAL);
}
pci_set_command_bit(dev, child, bit);
- /* Some devices seem to need a brief stall here, what do to? */
- command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
- if (command & bit)
- return (0);
- device_printf(child, "failed to enable %s mapping!\n", error);
- return (ENXIO);
+ return (0);
}
int
pci_disable_io_method(device_t dev, device_t child, int space)
{
- uint16_t command;
uint16_t bit;
- char *error;
-
- bit = 0;
- error = NULL;
switch(space) {
case SYS_RES_IOPORT:
bit = PCIM_CMD_PORTEN;
- error = "port";
break;
case SYS_RES_MEMORY:
bit = PCIM_CMD_MEMEN;
- error = "memory";
break;
default:
return (EINVAL);
}
pci_clear_command_bit(dev, child, bit);
- command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
- if (command & bit) {
- device_printf(child, "failed to disable %s mapping!\n", error);
- return (ENXIO);
- }
return (0);
}
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index c7a7245..981d1e0 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -44,6 +44,7 @@
#define PCI_SLOTMAX 31 /* highest supported slot number */
#define PCI_FUNCMAX 7 /* highest supported function number */
#define PCI_REGMAX 255 /* highest supported config register addr. */
+#define PCIE_REGMAX 4095 /* highest supported config register addr. */
#define PCI_MAXHDRTYPE 2
/* PCI config header registers for all devices */
diff --git a/sys/dev/ppbus/vpo.c b/sys/dev/ppbus/vpo.c
index 4009178..673a785 100644
--- a/sys/dev/ppbus/vpo.c
+++ b/sys/dev/ppbus/vpo.c
@@ -176,9 +176,6 @@ vpo_attach(device_t dev)
return (ENXIO);
}
ppb_unlock(ppbus);
-
- /* all went ok */
-
vpo_cam_rescan(vpo); /* have CAM rescan the bus */
return (0);
@@ -194,12 +191,15 @@ vpo_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
static void
vpo_cam_rescan(struct vpo_data *vpo)
{
+ device_t ppbus = device_get_parent(vpo->vpo_dev);
struct cam_path *path;
union ccb *ccb = malloc(sizeof(union ccb), M_TEMP, M_WAITOK | M_ZERO);
+ ppb_lock(ppbus);
if (xpt_create_path(&path, xpt_periph, cam_sim_path(vpo->sim), 0, 0)
!= CAM_REQ_CMP) {
/* A failure is benign as the user can do a manual rescan */
+ ppb_unlock(ppbus);
free(ccb, M_TEMP);
return;
}
@@ -209,6 +209,7 @@ vpo_cam_rescan(struct vpo_data *vpo)
ccb->ccb_h.cbfcnp = vpo_cam_rescan_callback;
ccb->crcn.flags = CAM_FLAG_NONE;
xpt_action(ccb);
+ ppb_unlock(ppbus);
/* The scan is in progress now. */
}
diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c
index 3a62724..8d04f70 100644
--- a/sys/dev/sound/pci/es137x.c
+++ b/sys/dev/sound/pci/es137x.c
@@ -1,10 +1,33 @@
/*-
- * Support the ENSONIQ AudioPCI board and Creative Labs SoundBlaster PCI
- * boards based on the ES1370, ES1371 and ES1373 chips.
- *
* Copyright (c) 1999 Russell Cattelan <cattelan@thebarn.com>
+ * Copyright (c) 1998 Joachim Kuebart <joachim.kuebart@gmx.net>
+ * 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.
+ */
+
+/*-
* Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
- * Copyright (c) 1998 by Joachim Kuebart. All rights reserved.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,12 +63,14 @@
*/
/*
+ * Support the ENSONIQ AudioPCI board and Creative Labs SoundBlaster PCI
+ * boards based on the ES1370, ES1371 and ES1373 chips.
+ *
* Part of this code was heavily inspired by the linux driver from
* Thomas Sailer (sailer@ife.ee.ethz.ch)
* Just about everything has been touched and reworked in some way but
* the all the underlying sequences/timing/register values are from
* Thomas' code.
- *
*/
#ifdef HAVE_KERNEL_OPTION_HEADERS
diff --git a/sys/dev/sound/pci/es137x.h b/sys/dev/sound/pci/es137x.h
index 7e0225f..fb86a94 100644
--- a/sys/dev/sound/pci/es137x.h
+++ b/sys/dev/sound/pci/es137x.h
@@ -1,26 +1,21 @@
/*-
- * This supports the ENSONIQ AudioPCI board based on the ES1370.
- *
- * Copyright (c) 1998 Joachim Kuebart <joki@kuebart.stuttgart.netsurf.de>
+ * Copyright (c) 1998 Joachim Kuebart <joachim.kuebart@gmx.net>
* 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 immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
+ * 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.
- * 3. Absolutely no warranty of function or purpose is made by the author
- * Joachim Kuebart.
- * 4. Modifications may be freely made to this file if the above conditions
- * are met.
*
* $FreeBSD$
*/
+/* This supports the ENSONIQ AudioPCI board based on the ES1370. */
+
#ifndef _ES1370_REG_H
#define _ES1370_REG_H
diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c
index 086c4fe..8d9c4c6 100644
--- a/sys/dev/sound/pci/t4dwave.c
+++ b/sys/dev/sound/pci/t4dwave.c
@@ -45,18 +45,22 @@ SND_DECLARE_FILE("$FreeBSD$");
#define SPA_PCI_ID 0x70181039
#define TR_DEFAULT_BUFSZ 0x1000
+/* For ALi M5451 the DMA transfer size appears to be fixed to 64k. */
+#define ALI_BUFSZ 0x10000
+#define TR_BUFALGN 0x8
#define TR_TIMEOUT_CDC 0xffff
+#define TR_MAXHWCH 64
+#define ALI_MAXHWCH 32
#define TR_MAXPLAYCH 4
+#define ALI_MAXPLAYCH 1
/*
- * Though, it's not clearly documented in trident datasheet, trident
- * audio cards can't handle DMA addresses located above 1GB. The LBA
- * (loop begin address) register which holds DMA base address is 32bits
- * register.
- * But the MSB 2bits are used for other purposes(I guess it is really
- * bad idea). This effectivly limits the DMA address space up to 1GB.
+ * Though, it's not clearly documented in the 4DWAVE datasheet, the
+ * DX and NX chips can't handle DMA addresses located above 1GB as the
+ * LBA (loop begin address) register which holds the DMA base address
+ * is 32-bit, but the two MSBs are used for other purposes.
*/
-#define TR_MAXADDR ((1 << 30) - 1)
-
+#define TR_MAXADDR ((1U << 30) - 1)
+#define ALI_MAXADDR ((1U << 31) - 1)
struct tr_info;
@@ -97,6 +101,7 @@ struct tr_info {
struct mtx *lock;
+ u_int32_t hwchns;
u_int32_t playchns;
unsigned int bufsz;
@@ -398,7 +403,10 @@ tr_wrch(struct tr_chinfo *ch)
ch->ec &= 0x00000fff;
ch->alpha &= 0x00000fff;
ch->delta &= 0x0000ffff;
- ch->lba &= 0x3fffffff;
+ if (tr->type == ALI_PCI_ID)
+ ch->lba &= ALI_MAXADDR;
+ else
+ ch->lba &= TR_MAXADDR;
cr[1]=ch->lba;
cr[3]=(ch->fmc<<14) | (ch->rvol<<7) | (ch->cvol);
@@ -441,7 +449,10 @@ tr_rdch(struct tr_chinfo *ch)
snd_mtxunlock(tr->lock);
- ch->lba= (cr[1] & 0x3fffffff);
+ if (tr->type == ALI_PCI_ID)
+ ch->lba=(cr[1] & ALI_MAXADDR);
+ else
+ ch->lba=(cr[1] & TR_MAXADDR);
ch->fmc= (cr[3] & 0x0000c000) >> 14;
ch->rvol= (cr[3] & 0x00003f80) >> 7;
ch->cvol= (cr[3] & 0x0000007f);
@@ -628,7 +639,6 @@ trrchan_setformat(kobj_t obj, void *data, u_int32_t format)
tr_wr(tr, TR_REG_SBCTRL, i, 1);
return 0;
-
}
static u_int32_t
@@ -729,7 +739,7 @@ tr_intr(void *p)
intsrc = tr_rd(tr, TR_REG_MISCINT, 4);
if (intsrc & TR_INT_ADDR) {
chnum = 0;
- while (chnum < 64) {
+ while (chnum < tr->hwchns) {
mask = 0x00000001;
active = tr_rd(tr, (chnum < 32)? TR_REG_ADDRINTA : TR_REG_ADDRINTB, 4);
bufhalf = tr_rd(tr, (chnum < 32)? TR_REG_CSPF_A : TR_REG_CSPF_B, 4);
@@ -815,8 +825,13 @@ tr_pci_attach(device_t dev)
u_int32_t data;
struct tr_info *tr;
struct ac97_info *codec = 0;
+ bus_addr_t lowaddr;
int i, dacn;
char status[SND_STATUSLEN];
+#ifdef __sparc64__
+ device_t *children;
+ int nchildren;
+#endif
tr = malloc(sizeof(*tr), M_DEVBUF, M_WAITOK | M_ZERO);
tr->type = pci_get_devid(dev);
@@ -834,7 +849,7 @@ tr_pci_attach(device_t dev)
} else {
switch (tr->type) {
case ALI_PCI_ID:
- dacn = 1;
+ dacn = ALI_MAXPLAYCH;
break;
default:
dacn = TR_MAXPLAYCH;
@@ -859,8 +874,6 @@ tr_pci_attach(device_t dev)
goto bad;
}
- tr->bufsz = pcm_getbuffersize(dev, 4096, TR_DEFAULT_BUFSZ, 65536);
-
if (tr_init(tr) == -1) {
device_printf(dev, "unable to initialize the card\n");
goto bad;
@@ -879,12 +892,59 @@ tr_pci_attach(device_t dev)
goto bad;
}
- if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
+ if (tr->type == ALI_PCI_ID) {
+ /*
+ * The M5451 generates 31 bit of DMA and in order to do
+ * 32-bit DMA, the 31st bit can be set via its accompanying
+ * ISA bridge. Note that we can't predict whether bus_dma(9)
+ * will actually supply us with a 32-bit buffer and even when
+ * using a low address of BUS_SPACE_MAXADDR_32BIT for both
+ * we might end up with the play buffer being in the 32-bit
+ * range while the record buffer isn't or vice versa. So we
+ * limit enabling the 31st bit to sparc64, where the IOMMU
+ * guarantees that we're using a 32-bit address (and in turn
+ * requires it).
+ */
+ lowaddr = ALI_MAXADDR;
+#ifdef __sparc64__
+ if (device_get_children(device_get_parent(dev), &children,
+ &nchildren) == 0) {
+ for (i = 0; i < nchildren; i++) {
+ if (pci_get_devid(children[i]) == 0x153310b9) {
+ lowaddr = BUS_SPACE_MAXADDR_32BIT;
+ data = pci_read_config(children[i],
+ 0x7e, 1);
+ if (bootverbose)
+ device_printf(dev,
+ "M1533 0x7e: 0x%x -> ",
+ data);
+ data |= 0x1;
+ if (bootverbose)
+ printf("0x%x\n", data);
+ pci_write_config(children[i], 0x7e,
+ data, 1);
+ break;
+ }
+ }
+ }
+ free(children, M_TEMP);
+#endif
+ tr->hwchns = ALI_MAXHWCH;
+ tr->bufsz = ALI_BUFSZ;
+ } else {
+ lowaddr = TR_MAXADDR;
+ tr->hwchns = TR_MAXHWCH;
+ tr->bufsz = pcm_getbuffersize(dev, 4096, TR_DEFAULT_BUFSZ,
+ 65536);
+ }
+
+ if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev),
+ /*alignment*/TR_BUFALGN,
/*boundary*/0,
- /*lowaddr*/TR_MAXADDR,
+ /*lowaddr*/lowaddr,
/*highaddr*/BUS_SPACE_MAXADDR,
/*filter*/NULL, /*filterarg*/NULL,
- /*maxsize*/tr->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
+ /*maxsize*/tr->bufsz, /*nsegments*/1, /*maxsegz*/tr->bufsz,
/*flags*/0, /*lockfunc*/busdma_lock_mutex,
/*lockarg*/&Giant, &tr->parent_dmat) != 0) {
device_printf(dev, "unable to create dma tag\n");
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index e75db9d..c980958 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -634,14 +634,8 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
break;
case FKEY: /* function key, return string */
cp = kbdd_get_fkeystr(thiskbd, KEYCHAR(c), &len);
- if (cp != NULL) {
- if (ttydisc_can_bypass(cur_tty)) {
- ttydisc_rint_bypass(cur_tty, cp, len);
- } else {
- while (len-- > 0)
- ttydisc_rint(cur_tty, *cp++, 0);
- }
- }
+ if (cp != NULL)
+ ttydisc_rint_simple(cur_tty, cp, len);
break;
case MKEY: /* meta is active, prepend ESC */
ttydisc_rint(cur_tty, 0x1b, 0);
diff --git a/sys/dev/twa/tw_cl_io.c b/sys/dev/twa/tw_cl_io.c
index 162b1ea..6fea175 100644
--- a/sys/dev/twa/tw_cl_io.c
+++ b/sys/dev/twa/tw_cl_io.c
@@ -396,7 +396,7 @@ tw_cl_fw_passthru(struct tw_cl_ctlr_handle *ctlr_handle,
* non-zero-- failure
*/
TW_INT32
-tw_cl_ioctl(struct tw_cl_ctlr_handle *ctlr_handle, TW_INT32 cmd, TW_VOID *buf)
+tw_cl_ioctl(struct tw_cl_ctlr_handle *ctlr_handle, u_long cmd, TW_VOID *buf)
{
struct tw_cli_ctlr_context *ctlr =
(struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
diff --git a/sys/dev/twa/tw_cl_share.h b/sys/dev/twa/tw_cl_share.h
index 265ff77..e583818 100644
--- a/sys/dev/twa/tw_cl_share.h
+++ b/sys/dev/twa/tw_cl_share.h
@@ -565,7 +565,7 @@ extern TW_INT32 tw_cl_interrupt(struct tw_cl_ctlr_handle *ctlr_handle);
/* CL's ioctl handler. */
extern TW_INT32 tw_cl_ioctl(struct tw_cl_ctlr_handle *ctlr_handle,
- TW_INT32 cmd, TW_VOID *buf);
+ u_long cmd, TW_VOID *buf);
#ifdef TW_OSL_DEBUG
diff --git a/sys/dev/twe/twe.c b/sys/dev/twe/twe.c
index 59b5027..90dfa2e 100644
--- a/sys/dev/twe/twe.c
+++ b/sys/dev/twe/twe.c
@@ -487,7 +487,7 @@ twe_dump_blocks(struct twe_softc *sc, int unit, u_int32_t lba, void *data, int n
* Handle controller-specific control operations.
*/
int
-twe_ioctl(struct twe_softc *sc, int ioctlcmd, void *addr)
+twe_ioctl(struct twe_softc *sc, u_long ioctlcmd, void *addr)
{
struct twe_usercommand *tu = (struct twe_usercommand *)addr;
struct twe_paramcommand *tp = (struct twe_paramcommand *)addr;
diff --git a/sys/dev/twe/twevar.h b/sys/dev/twe/twevar.h
index 90391ad..2711ccc 100644
--- a/sys/dev/twe/twevar.h
+++ b/sys/dev/twe/twevar.h
@@ -150,7 +150,7 @@ extern void twe_startio(struct twe_softc *sc);
extern int twe_start(struct twe_request *tr);
extern int twe_dump_blocks(struct twe_softc *sc, int unit, /* crashdump block write */
u_int32_t lba, void *data, int nblks);
-extern int twe_ioctl(struct twe_softc *sc, int cmd,
+extern int twe_ioctl(struct twe_softc *sc, u_long cmd,
void *addr); /* handle user request */
extern void twe_describe_controller(struct twe_softc *sc); /* print controller info */
extern void twe_print_controller(struct twe_softc *sc);
diff --git a/sys/fs/procfs/procfs.c b/sys/fs/procfs/procfs.c
index 77d1dc6..8b69eb1 100644
--- a/sys/fs/procfs/procfs.c
+++ b/sys/fs/procfs/procfs.c
@@ -108,7 +108,8 @@ procfs_attr(PFS_ATTR_ARGS)
else if (strcmp(pn->pn_name, "mem") == 0 ||
strcmp(pn->pn_name, "regs") == 0 ||
strcmp(pn->pn_name, "dbregs") == 0 ||
- strcmp(pn->pn_name, "fpregs") == 0)
+ strcmp(pn->pn_name, "fpregs") == 0 ||
+ strcmp(pn->pn_name, "osrel") == 0)
vap->va_mode = 0600;
if (p != NULL) {
@@ -186,6 +187,8 @@ procfs_init(PFS_INIT_ARGS)
NULL, NULL, NULL, PFS_RD);
pfs_create_file(dir, "status", procfs_doprocstatus,
NULL, NULL, NULL, PFS_RD);
+ pfs_create_file(dir, "osrel", procfs_doosrel,
+ procfs_attr, procfs_candebug, NULL, PFS_RDWR);
pfs_create_link(dir, "file", procfs_doprocfile,
NULL, procfs_notsystem, NULL, 0);
diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h
index 48d4bca..2598224 100644
--- a/sys/fs/procfs/procfs.h
+++ b/sys/fs/procfs/procfs.h
@@ -39,6 +39,7 @@
#ifdef _KERNEL
int procfs_docurproc(PFS_FILL_ARGS);
+int procfs_doosrel(PFS_FILL_ARGS);
int procfs_doproccmdline(PFS_FILL_ARGS);
int procfs_doprocctl(PFS_FILL_ARGS);
int procfs_doprocdbregs(PFS_FILL_ARGS);
diff --git a/sys/fs/procfs/procfs_osrel.c b/sys/fs/procfs/procfs_osrel.c
new file mode 100644
index 0000000..d32bd6d
--- /dev/null
+++ b/sys/fs/procfs/procfs_osrel.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2009 Konstantin Belousov
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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/proc.h>
+#include <sys/sbuf.h>
+#include <sys/uio.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+int
+procfs_doosrel(PFS_FILL_ARGS)
+{
+ const char *pp;
+ int ov, osrel, i;
+
+ if (uio == NULL)
+ return (EOPNOTSUPP);
+ if (uio->uio_rw == UIO_READ) {
+ sbuf_printf(sb, "%d\n", p->p_osrel);
+ } else {
+ sbuf_trim(sb);
+ sbuf_finish(sb);
+ pp = sbuf_data(sb);
+ osrel = 0;
+ i = sbuf_len(sb);
+ while (i--) {
+ if (*pp < '0' || *pp > '9')
+ return (EINVAL);
+ ov = osrel * 10 + *pp++ - '0';
+ if (ov < osrel)
+ return (EINVAL);
+ osrel = ov;
+ }
+ p->p_osrel = osrel;
+ }
+ return (0);
+}
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index 78c3650..6e81a9c 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -480,6 +480,10 @@ g_part_ctl_add(struct gctl_req *req, struct g_part_parms *gpp)
gctl_error(req, "%d index '%d'", EEXIST, gpp->gpp_index);
return (EEXIST);
}
+ if (index > table->gpt_entries) {
+ gctl_error(req, "%d index '%d'", ENOSPC, index);
+ return (ENOSPC);
+ }
entry = (delent == NULL) ? g_malloc(table->gpt_scheme->gps_entrysz,
M_WAITOK | M_ZERO) : delent;
diff --git a/sys/i386/acpica/acpi_machdep.c b/sys/i386/acpica/acpi_machdep.c
index a0ef60f..ae23178 100644
--- a/sys/i386/acpica/acpi_machdep.c
+++ b/sys/i386/acpica/acpi_machdep.c
@@ -42,6 +42,8 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpiio.h>
@@ -558,6 +560,244 @@ acpi_cpu_c1()
}
/*
+ * Support for mapping ACPI tables during early boot. This abuses the
+ * crashdump map because the kernel cannot allocate KVA in
+ * pmap_mapbios() when this is used. This makes the following
+ * assumptions about how we use this KVA: pages 0 and 1 are used to
+ * map in the header of each table found via the RSDT or XSDT and
+ * pages 2 to n are used to map in the RSDT or XSDT. This has to use
+ * 2 pages for the table headers in case a header spans a page
+ * boundary.
+ *
+ * XXX: We don't ensure the table fits in the available address space
+ * in the crashdump map.
+ */
+
+/*
+ * Map some memory using the crashdump map. 'offset' is an offset in
+ * pages into the crashdump map to use for the start of the mapping.
+ */
+static void *
+table_map(vm_paddr_t pa, int offset, vm_offset_t length)
+{
+ vm_offset_t va, off;
+ void *data;
+
+ off = pa & PAGE_MASK;
+ length = roundup(length + off, PAGE_SIZE);
+ pa = pa & PG_FRAME;
+ va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
+ (offset * PAGE_SIZE);
+ data = (void *)(va + off);
+ length -= PAGE_SIZE;
+ while (length > 0) {
+ va += PAGE_SIZE;
+ pa += PAGE_SIZE;
+ length -= PAGE_SIZE;
+ pmap_kenter(va, pa);
+ invlpg(va);
+ }
+ return (data);
+}
+
+/* Unmap memory previously mapped with table_map(). */
+static void
+table_unmap(void *data, vm_offset_t length)
+{
+ vm_offset_t va, off;
+
+ va = (vm_offset_t)data;
+ off = va & PAGE_MASK;
+ length = roundup(length + off, PAGE_SIZE);
+ va &= ~PAGE_MASK;
+ while (length > 0) {
+ pmap_kremove(va);
+ invlpg(va);
+ va += PAGE_SIZE;
+ length -= PAGE_SIZE;
+ }
+}
+
+/*
+ * Map a table at a given offset into the crashdump map. It first
+ * maps the header to determine the table length and then maps the
+ * entire table.
+ */
+static void *
+map_table(vm_paddr_t pa, int offset, const char *sig)
+{
+ ACPI_TABLE_HEADER *header;
+ vm_offset_t length;
+ void *table;
+
+ header = table_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
+ if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
+ table_unmap(header, sizeof(ACPI_TABLE_HEADER));
+ return (NULL);
+ }
+ length = header->Length;
+ table_unmap(header, sizeof(ACPI_TABLE_HEADER));
+ table = table_map(pa, offset, length);
+ if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
+ if (bootverbose)
+ printf("ACPI: Failed checksum for table %s\n", sig);
+ table_unmap(table, length);
+ return (NULL);
+ }
+ return (table);
+}
+
+/*
+ * See if a given ACPI table is the requested table. Returns the
+ * length of the able if it matches or zero on failure.
+ */
+static int
+probe_table(vm_paddr_t address, const char *sig)
+{
+ ACPI_TABLE_HEADER *table;
+
+ table = table_map(address, 0, sizeof(ACPI_TABLE_HEADER));
+ if (table == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map table at 0x%jx\n",
+ (uintmax_t)address);
+ return (0);
+ }
+ if (bootverbose)
+ printf("Table '%.4s' at 0x%jx\n", table->Signature,
+ (uintmax_t)address);
+
+ if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0) {
+ table_unmap(table, sizeof(ACPI_TABLE_HEADER));
+ return (0);
+ }
+ table_unmap(table, sizeof(ACPI_TABLE_HEADER));
+ return (1);
+}
+
+/*
+ * Try to map a table at a given physical address previously returned
+ * by acpi_find_table().
+ */
+void *
+acpi_map_table(vm_paddr_t pa, const char *sig)
+{
+
+ return (map_table(pa, 0, sig));
+}
+
+/* Unmap a table previously mapped via acpi_map_table(). */
+void
+acpi_unmap_table(void *table)
+{
+ ACPI_TABLE_HEADER *header;
+
+ header = (ACPI_TABLE_HEADER *)table;
+ table_unmap(table, header->Length);
+}
+
+/*
+ * Return the physical address of the requested table or zero if one
+ * is not found.
+ */
+vm_paddr_t
+acpi_find_table(const char *sig)
+{
+ ACPI_PHYSICAL_ADDRESS rsdp_ptr;
+ ACPI_TABLE_RSDP *rsdp;
+ ACPI_TABLE_RSDT *rsdt;
+ ACPI_TABLE_XSDT *xsdt;
+ ACPI_TABLE_HEADER *table;
+ vm_paddr_t addr;
+ int i, count;
+
+ if (resource_disabled("acpi", 0))
+ return (0);
+
+ /*
+ * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn
+ * calls pmap_mapbios() to find the RSDP, we assume that we can use
+ * pmap_mapbios() to map the RSDP.
+ */
+ if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
+ return (0);
+ rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
+ if (rsdp == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map RSDP\n");
+ return (0);
+ }
+
+ /*
+ * For ACPI >= 2.0, use the XSDT if it is available.
+ * Otherwise, use the RSDT. We map the XSDT or RSDT at page 2
+ * in the crashdump area. Pages 0 and 1 are used to map in the
+ * headers of candidate ACPI tables.
+ */
+ addr = 0;
+ if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
+ /*
+ * AcpiOsGetRootPointer only verifies the checksum for
+ * the version 1.0 portion of the RSDP. Version 2.0 has
+ * an additional checksum that we verify first.
+ */
+ if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
+ if (bootverbose)
+ printf("ACPI: RSDP failed extended checksum\n");
+ return (0);
+ }
+ xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
+ if (xsdt == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map XSDT\n");
+ return (0);
+ }
+ count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+ sizeof(UINT64);
+ for (i = 0; i < count; i++)
+ if (probe_table(xsdt->TableOffsetEntry[i], sig)) {
+ addr = xsdt->TableOffsetEntry[i];
+ break;
+ }
+ acpi_unmap_table(xsdt);
+ } else {
+ rsdt = map_table(rsdp->RsdtPhysicalAddress, 2, ACPI_SIG_RSDT);
+ if (rsdt == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map RSDT\n");
+ return (0);
+ }
+ count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+ sizeof(UINT32);
+ for (i = 0; i < count; i++)
+ if (probe_table(rsdt->TableOffsetEntry[i], sig)) {
+ addr = rsdt->TableOffsetEntry[i];
+ break;
+ }
+ acpi_unmap_table(rsdt);
+ }
+ pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
+ if (addr == 0) {
+ if (bootverbose)
+ printf("ACPI: No %s table found\n", sig);
+ return (0);
+ }
+ if (bootverbose)
+ printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr);
+
+ /*
+ * Verify that we can map the full table and that its checksum is
+ * correct, etc.
+ */
+ table = map_table(addr, 0, sig);
+ if (table == NULL)
+ return (0);
+ acpi_unmap_table(table);
+
+ return (addr);
+}
+
+/*
* ACPI nexus(4) driver.
*/
static int
diff --git a/sys/i386/acpica/madt.c b/sys/i386/acpica/madt.c
index f9756ec..114fbc7 100644
--- a/sys/i386/acpica/madt.c
+++ b/sys/i386/acpica/madt.c
@@ -36,27 +36,19 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/smp.h>
-
#include <vm/vm.h>
-#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <machine/apicreg.h>
-#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
-#include <machine/md_var.h>
-#include <machine/specialreg.h>
#include <contrib/dev/acpica/include/acpi.h>
-#include <contrib/dev/acpica/include/accommon.h>
#include <contrib/dev/acpica/include/actables.h>
#include <dev/acpica/acpivar.h>
#include <dev/pci/pcivar.h>
-typedef void madt_entry_handler(ACPI_SUBTABLE_HEADER *entry, void *arg);
-
/* These two arrays are indexed by APIC IDs. */
struct ioapic_info {
void *io_apic;
@@ -79,8 +71,6 @@ static enum intr_polarity interrupt_polarity(UINT16 IntiFlags, UINT8 Source);
static enum intr_trigger interrupt_trigger(UINT16 IntiFlags, UINT8 Source);
static int madt_find_cpu(u_int acpi_id, u_int *apic_id);
static int madt_find_interrupt(int intr, void **apic, u_int *pin);
-static void *madt_map(vm_paddr_t pa, int offset, vm_offset_t length);
-static void *madt_map_table(vm_paddr_t pa, int offset, const char *sig);
static void madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg);
static void madt_parse_interrupt_override(
ACPI_MADT_INTERRUPT_OVERRIDE *intr);
@@ -92,13 +82,10 @@ static int madt_probe(void);
static int madt_probe_cpus(void);
static void madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
void *arg __unused);
-static int madt_probe_table(vm_paddr_t address);
static void madt_register(void *dummy);
static int madt_setup_local(void);
static int madt_setup_io(void);
-static void madt_unmap(void *data, vm_offset_t length);
-static void madt_unmap_table(void *table);
-static void madt_walk_table(madt_entry_handler *handler, void *arg);
+static void madt_walk_table(acpi_subtable_handler *handler, void *arg);
static struct apic_enumerator madt_enumerator = {
"MADT",
@@ -108,87 +95,6 @@ static struct apic_enumerator madt_enumerator = {
madt_setup_io
};
-/*
- * Code to abuse the crashdump map to map in the tables for the early
- * probe. We cheat and make the following assumptions about how we
- * use this KVA: pages 0 and 1 are used to map in the header of each
- * table found via the RSDT or XSDT and pages 2 to n are used to map
- * in the RSDT or XSDT. We have to use 2 pages for the table headers
- * in case a header spans a page boundary. The offset is in pages;
- * the length is in bytes.
- */
-static void *
-madt_map(vm_paddr_t pa, int offset, vm_offset_t length)
-{
- vm_offset_t va, off;
- void *data;
-
- off = pa & PAGE_MASK;
- length = roundup(length + off, PAGE_SIZE);
- pa = pa & PG_FRAME;
- va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
- (offset * PAGE_SIZE);
- data = (void *)(va + off);
- length -= PAGE_SIZE;
- while (length > 0) {
- va += PAGE_SIZE;
- pa += PAGE_SIZE;
- length -= PAGE_SIZE;
- pmap_kenter(va, pa);
- invlpg(va);
- }
- return (data);
-}
-
-static void
-madt_unmap(void *data, vm_offset_t length)
-{
- vm_offset_t va, off;
-
- va = (vm_offset_t)data;
- off = va & PAGE_MASK;
- length = roundup(length + off, PAGE_SIZE);
- va &= ~PAGE_MASK;
- while (length > 0) {
- pmap_kremove(va);
- invlpg(va);
- va += PAGE_SIZE;
- length -= PAGE_SIZE;
- }
-}
-
-static void *
-madt_map_table(vm_paddr_t pa, int offset, const char *sig)
-{
- ACPI_TABLE_HEADER *header;
- vm_offset_t length;
- void *table;
-
- header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
- if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
- madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
- return (NULL);
- }
- length = header->Length;
- madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
- table = madt_map(pa, offset, length);
- if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
- if (bootverbose)
- printf("MADT: Failed checksum for table %s\n", sig);
- madt_unmap(table, length);
- return (NULL);
- }
- return (table);
-}
-
-static void
-madt_unmap_table(void *table)
-{
- ACPI_TABLE_HEADER *header;
-
- header = (ACPI_TABLE_HEADER *)table;
- madt_unmap(table, header->Length);
-}
/*
* Look for an ACPI Multiple APIC Description Table ("APIC")
@@ -196,137 +102,25 @@ madt_unmap_table(void *table)
static int
madt_probe(void)
{
- ACPI_PHYSICAL_ADDRESS rsdp_ptr;
- ACPI_TABLE_RSDP *rsdp;
- ACPI_TABLE_RSDT *rsdt;
- ACPI_TABLE_XSDT *xsdt;
- int i, count;
-
- if (resource_disabled("acpi", 0))
- return (ENXIO);
-
- /*
- * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn
- * calls pmap_mapbios() to find the RSDP, we assume that we can use
- * pmap_mapbios() to map the RSDP.
- */
- if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
- return (ENXIO);
- rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
- if (rsdp == NULL) {
- if (bootverbose)
- printf("MADT: Failed to map RSDP\n");
- return (ENXIO);
- }
-
- /*
- * For ACPI >= 2.0, use the XSDT if it is available.
- * Otherwise, use the RSDT. We map the XSDT or RSDT at page 1
- * in the crashdump area. Page 0 is used to map in the
- * headers of candidate ACPI tables.
- */
- if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
- /*
- * AcpiOsGetRootPointer only verifies the checksum for
- * the version 1.0 portion of the RSDP. Version 2.0 has
- * an additional checksum that we verify first.
- */
- if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
- if (bootverbose)
- printf("MADT: RSDP failed extended checksum\n");
- return (ENXIO);
- }
- xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 2,
- ACPI_SIG_XSDT);
- if (xsdt == NULL) {
- if (bootverbose)
- printf("MADT: Failed to map XSDT\n");
- return (ENXIO);
- }
- count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
- sizeof(UINT64);
- for (i = 0; i < count; i++)
- if (madt_probe_table(xsdt->TableOffsetEntry[i]))
- break;
- madt_unmap_table(xsdt);
- } else {
- rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 2,
- ACPI_SIG_RSDT);
- if (rsdt == NULL) {
- if (bootverbose)
- printf("MADT: Failed to map RSDT\n");
- return (ENXIO);
- }
- count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
- sizeof(UINT32);
- for (i = 0; i < count; i++)
- if (madt_probe_table(rsdt->TableOffsetEntry[i]))
- break;
- madt_unmap_table(rsdt);
- }
- pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
- if (madt_physaddr == 0) {
- if (bootverbose)
- printf("MADT: No MADT table found\n");
- return (ENXIO);
- }
- if (bootverbose)
- printf("MADT: Found table at 0x%jx\n",
- (uintmax_t)madt_physaddr);
- /*
- * Verify that we can map the full table and that its checksum is
- * correct, etc.
- */
- madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT);
- if (madt == NULL)
+ madt_physaddr = acpi_find_table(ACPI_SIG_MADT);
+ if (madt_physaddr == 0)
return (ENXIO);
- madt_unmap_table(madt);
- madt = NULL;
-
return (0);
}
/*
- * See if a given ACPI table is the MADT.
- */
-static int
-madt_probe_table(vm_paddr_t address)
-{
- ACPI_TABLE_HEADER *table;
-
- table = madt_map(address, 0, sizeof(ACPI_TABLE_HEADER));
- if (table == NULL) {
- if (bootverbose)
- printf("MADT: Failed to map table at 0x%jx\n",
- (uintmax_t)address);
- return (0);
- }
- if (bootverbose)
- printf("Table '%.4s' at 0x%jx\n", table->Signature,
- (uintmax_t)address);
-
- if (strncmp(table->Signature, ACPI_SIG_MADT, ACPI_NAME_SIZE) != 0) {
- madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
- return (0);
- }
- madt_physaddr = address;
- madt_length = table->Length;
- madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
- return (1);
-}
-
-/*
* Run through the MP table enumerating CPUs.
*/
static int
madt_probe_cpus(void)
{
- madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT);
+ madt = acpi_map_table(madt_physaddr, ACPI_SIG_MADT);
+ madt_length = madt->Header.Length;
KASSERT(madt != NULL, ("Unable to re-map MADT"));
madt_walk_table(madt_probe_cpus_handler, NULL);
- madt_unmap_table(madt);
+ acpi_unmap_table(madt);
madt = NULL;
return (0);
}
@@ -416,17 +210,11 @@ SYSINIT(madt_register, SI_SUB_CPU - 1, SI_ORDER_SECOND, madt_register, NULL);
* Call the handler routine for each entry in the MADT table.
*/
static void
-madt_walk_table(madt_entry_handler *handler, void *arg)
+madt_walk_table(acpi_subtable_handler *handler, void *arg)
{
- ACPI_SUBTABLE_HEADER *entry;
- u_char *p, *end;
-
- end = (u_char *)(madt) + madt->Header.Length;
- for (p = (u_char *)(madt + 1); p < end; ) {
- entry = (ACPI_SUBTABLE_HEADER *)p;
- handler(entry, arg);
- p += entry->Length;
- }
+
+ acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
+ handler, arg);
}
static void
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 876224e..594c43a 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -353,7 +353,7 @@ options AGP_DEBUG
#####################################################################
# HARDWARE DEVICE CONFIGURATION
-# To include support for VGA VESA video modes (depends on X86EMU)
+# To include support for VGA VESA video modes
options VESA
# Turn on extra debugging checks and output for VESA support.
@@ -361,6 +361,9 @@ options VESA_DEBUG
device dpms # DPMS suspend & resume via VESA BIOS
+# x86 real mode BIOS emulator, required by atkbdc/dpms/vesa
+options X86BIOS
+
#
# The Numeric Processing eXtension driver. This is non-optional.
device npx
@@ -444,6 +447,9 @@ options VGA_WIDTH90 # support 90 column modes
# Debugging.
options VGA_DEBUG
+# Linear framebuffer driver for S3 VESA 1.2 cards. Works on top of VESA.
+device s3pci
+
# 3Dfx Voodoo Graphics, Voodoo II /dev/3dfx CDEV support. This will create
# the /dev/3dfx0 device to work with glide implementations. This should get
# linked to /dev/3dfx and /dev/voodoo. Note that this is not the same as
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 1a6b3c6..96c8f25 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -1946,7 +1946,7 @@ sdtossd(sd, ssd)
static int
add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
{
- int i, physmap_idx;
+ int i, insert_idx, physmap_idx;
physmap_idx = *physmap_idxp;
@@ -1968,17 +1968,34 @@ add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
}
#endif
+ /*
+ * Find insertion point while checking for overlap. Start off by
+ * assuming the new entry will be added to the end.
+ */
+ insert_idx = physmap_idx + 2;
for (i = 0; i <= physmap_idx; i += 2) {
if (smap->base < physmap[i + 1]) {
+ if (smap->base + smap->length <= physmap[i]) {
+ insert_idx = i;
+ break;
+ }
if (boothowto & RB_VERBOSE)
printf(
- "Overlapping or non-monotonic memory region, ignoring second region\n");
+ "Overlapping memory regions, ignoring second region\n");
return (1);
}
}
- if (smap->base == physmap[physmap_idx + 1]) {
- physmap[physmap_idx + 1] += smap->length;
+ /* See if we can prepend to the next entry. */
+ if (insert_idx <= physmap_idx &&
+ smap->base + smap->length == physmap[insert_idx]) {
+ physmap[insert_idx] = smap->base;
+ return (1);
+ }
+
+ /* See if we can append to the previous entry. */
+ if (insert_idx > 0 && smap->base == physmap[insert_idx - 1]) {
+ physmap[insert_idx - 1] += smap->length;
return (1);
}
@@ -1989,8 +2006,19 @@ add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
"Too many segments in the physical address map, giving up\n");
return (0);
}
- physmap[physmap_idx] = smap->base;
- physmap[physmap_idx + 1] = smap->base + smap->length;
+
+ /*
+ * Move the last 'N' entries down to make room for the new
+ * entry if needed.
+ */
+ for (i = physmap_idx; i > insert_idx; i -= 2) {
+ physmap[i] = physmap[i - 2];
+ physmap[i + 1] = physmap[i - 1];
+ }
+
+ /* Insert the new entry. */
+ physmap[insert_idx] = smap->base;
+ physmap[insert_idx + 1] = smap->base + smap->length;
return (1);
}
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index f3b4d99..7e3bc37 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -702,6 +702,11 @@ pmap_init(void)
* Are large page mappings enabled?
*/
TUNABLE_INT_FETCH("vm.pmap.pg_ps_enabled", &pg_ps_enabled);
+ if (pg_ps_enabled) {
+ KASSERT(MAXPAGESIZES > 1 && pagesizes[1] == 0,
+ ("pmap_init: can't assign to pagesizes[1]"));
+ pagesizes[1] = NBPDR;
+ }
/*
* Calculate the size of the pv head table for superpages.
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index f7064f0..f4df668 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -225,6 +225,11 @@ trap(struct trapframe *frame)
}
#endif
+ if (type == T_RESERVED) {
+ trap_fatal(frame, 0);
+ goto out;
+ }
+
#ifdef HWPMC_HOOKS
/*
* CPU PMCs interrupt using an NMI so we check for that first.
diff --git a/sys/i386/include/acpica_machdep.h b/sys/i386/include/acpica_machdep.h
index f90b213..d5bfe65 100644
--- a/sys/i386/include/acpica_machdep.h
+++ b/sys/i386/include/acpica_machdep.h
@@ -97,5 +97,8 @@ extern int acpi_release_global_lock(uint32_t *lock);
void acpi_SetDefaultIntrModel(int model);
void acpi_cpu_c1(void);
+void *acpi_map_table(vm_paddr_t pa, const char *sig);
+void acpi_unmap_table(void *table);
+vm_paddr_t acpi_find_table(const char *sig);
#endif /* __ACPICA_MACHDEP_H__ */
diff --git a/sys/i386/include/param.h b/sys/i386/include/param.h
index b6a527d..11ac12e 100644
--- a/sys/i386/include/param.h
+++ b/sys/i386/include/param.h
@@ -110,6 +110,8 @@
#define NBPDR (1<<PDRSHIFT) /* bytes/page dir */
#define PDRMASK (NBPDR-1)
+#define MAXPAGESIZES 2 /* maximum number of supported page sizes */
+
#define IOPAGES 2 /* pages of i/o permission bitmap */
#ifndef KSTACK_PAGES
diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c
index 20050e6..ae56990 100644
--- a/sys/i386/pci/pci_cfgreg.c
+++ b/sys/i386/pci/pci_cfgreg.c
@@ -299,9 +299,9 @@ pci_cfgenable(unsigned bus, unsigned slot, unsigned func, int reg, int bytes)
if (bus <= PCI_BUSMAX
&& slot < devmax
&& func <= PCI_FUNCMAX
- && reg <= PCI_REGMAX
+ && (unsigned)reg <= PCI_REGMAX
&& bytes != 3
- && (unsigned) bytes <= 4
+ && (unsigned)bytes <= 4
&& (reg & (bytes - 1)) == 0) {
switch (cfgmech) {
case CFGMECH_PCIE:
@@ -595,7 +595,7 @@ pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus)
* fall back to using type 1 config access instead.
*/
if (pci_cfgregopen() != 0) {
- for (slot = 0; slot < 32; slot++) {
+ for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
val1 = pcireg_cfgread(0, slot, 0, 0, 4);
if (val1 == 0xffffffff)
continue;
@@ -661,8 +661,8 @@ pciereg_cfgread(int bus, unsigned slot, unsigned func, unsigned reg,
vm_paddr_t pa, papage;
int data = -1;
- if (bus < pcie_minbus || bus > pcie_maxbus || slot >= 32 ||
- func > PCI_FUNCMAX || reg >= 0x1000 || bytes > 4 || bytes == 3)
+ if (bus < pcie_minbus || bus > pcie_maxbus || slot > PCI_SLOTMAX ||
+ func > PCI_FUNCMAX || reg > PCIE_REGMAX)
return (-1);
critical_enter();
@@ -695,8 +695,8 @@ pciereg_cfgwrite(int bus, unsigned slot, unsigned func, unsigned reg, int data,
volatile vm_offset_t va;
vm_paddr_t pa, papage;
- if (bus < pcie_minbus || bus > pcie_maxbus || slot >= 32 ||
- func > PCI_FUNCMAX || reg >= 0x1000)
+ if (bus < pcie_minbus || bus > pcie_maxbus || slot > PCI_SLOTMAX ||
+ func > PCI_FUNCMAX || reg > PCIE_REGMAX)
return;
critical_enter();
diff --git a/sys/ia64/include/param.h b/sys/ia64/include/param.h
index 8518020..331af7a 100644
--- a/sys/ia64/include/param.h
+++ b/sys/ia64/include/param.h
@@ -89,6 +89,8 @@
#define PAGE_MASK (PAGE_SIZE-1)
#define NPTEPG (PAGE_SIZE/(sizeof (pt_entry_t)))
+#define MAXPAGESIZES 1 /* maximum number of supported page sizes */
+
#ifndef KSTACK_PAGES
#define KSTACK_PAGES 4 /* pages of kernel stack */
#endif
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 8ce7621..86a950f 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -145,7 +145,8 @@ static int filt_timer(struct knote *kn, long hint);
static int filt_userattach(struct knote *kn);
static void filt_userdetach(struct knote *kn);
static int filt_user(struct knote *kn, long hint);
-static void filt_usertouch(struct knote *kn, struct kevent *kev, long type);
+static void filt_usertouch(struct knote *kn, struct kevent *kev,
+ u_long type);
static struct filterops file_filtops = {
.f_isfd = 1,
@@ -616,9 +617,9 @@ filt_user(struct knote *kn, __unused long hint)
}
static void
-filt_usertouch(struct knote *kn, struct kevent *kev, long type)
+filt_usertouch(struct knote *kn, struct kevent *kev, u_long type)
{
- int ffctrl;
+ u_int ffctrl;
switch (type) {
case EVENT_REGISTER:
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index d42d31d..04e4dc0 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -204,6 +204,33 @@ SYSCTL_PROC(_hw, HW_USERMEM, usermem, CTLTYPE_ULONG | CTLFLAG_RD,
SYSCTL_ULONG(_hw, OID_AUTO, availpages, CTLFLAG_RD, &physmem, 0, "");
+u_long pagesizes[MAXPAGESIZES] = { PAGE_SIZE };
+
+static int
+sysctl_hw_pagesizes(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+#ifdef SCTL_MASK32
+ int i;
+ uint32_t pagesizes32[MAXPAGESIZES];
+
+ if (req->flags & SCTL_MASK32) {
+ /*
+ * Recreate the "pagesizes" array with 32-bit elements. Truncate
+ * any page size greater than UINT32_MAX to zero.
+ */
+ for (i = 0; i < MAXPAGESIZES; i++)
+ pagesizes32[i] = (uint32_t)pagesizes[i];
+
+ error = SYSCTL_OUT(req, pagesizes32, sizeof(pagesizes32));
+ } else
+#endif
+ error = SYSCTL_OUT(req, pagesizes, sizeof(pagesizes));
+ return (error);
+}
+SYSCTL_PROC(_hw, OID_AUTO, pagesizes, CTLTYPE_ULONG | CTLFLAG_RD,
+ NULL, 0, sysctl_hw_pagesizes, "LU", "Supported page sizes");
+
static char machine_arch[] = MACHINE_ARCH;
SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD,
machine_arch, 0, "System architecture");
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index bcb60ed..2ab099d 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -2556,6 +2556,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo)
uint32_t flags;
int32_t state, oldstate;
int32_t blocked_writers;
+ int32_t blocked_readers;
int error;
uq = td->td_umtxq;
@@ -2564,6 +2565,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo)
if (error != 0)
return (error);
+ blocked_readers = 0;
for (;;) {
state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state));
while (!(state & URWLOCK_WRITE_OWNER) && URWLOCK_READER_COUNT(state) == 0) {
@@ -2575,8 +2577,18 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo)
state = oldstate;
}
- if (error)
+ if (error) {
+ if (!(state & (URWLOCK_WRITE_OWNER|URWLOCK_WRITE_WAITERS)) &&
+ blocked_readers != 0) {
+ umtxq_lock(&uq->uq_key);
+ umtxq_busy(&uq->uq_key);
+ umtxq_signal_queue(&uq->uq_key, INT_MAX, UMTX_SHARED_QUEUE);
+ umtxq_unbusy(&uq->uq_key);
+ umtxq_unlock(&uq->uq_key);
+ }
+
break;
+ }
/* grab monitor lock */
umtxq_lock(&uq->uq_key);
@@ -2627,7 +2639,9 @@ sleep:
break;
state = oldstate;
}
- }
+ blocked_readers = fuword32(&rwlock->rw_blocked_readers);
+ } else
+ blocked_readers = 0;
umtxq_lock(&uq->uq_key);
umtxq_unbusy(&uq->uq_key);
diff --git a/sys/kern/subr_acl_nfs4.c b/sys/kern/subr_acl_nfs4.c
index 85609b9..c3f4b65 100644
--- a/sys/kern/subr_acl_nfs4.c
+++ b/sys/kern/subr_acl_nfs4.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2008 Edward Tomasz Napierała <trasz@FreeBSD.org>
+ * Copyright (c) 2008-2009 Edward Tomasz Napierała <trasz@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,213 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#define KASSERT(a, b) assert(a)
#define CTASSERT(a)
-#endif
+#endif /* _KERNEL */
+
+#ifdef _KERNEL
+
+static struct {
+ accmode_t accmode;
+ int mask;
+} accmode2mask[] = {{VREAD, ACL_READ_DATA},
+ {VWRITE, ACL_WRITE_DATA},
+ {VAPPEND, ACL_APPEND_DATA},
+ {VEXEC, ACL_EXECUTE},
+ {VREAD_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
+ {VWRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
+ {VDELETE_CHILD, ACL_DELETE_CHILD},
+ {VREAD_ATTRIBUTES, ACL_READ_ATTRIBUTES},
+ {VWRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
+ {VDELETE, ACL_DELETE},
+ {VREAD_ACL, ACL_READ_ACL},
+ {VWRITE_ACL, ACL_WRITE_ACL},
+ {VWRITE_OWNER, ACL_WRITE_OWNER},
+ {VSYNCHRONIZE, ACL_SYNCHRONIZE},
+ {0, 0}};
+
+static int
+_access_mask_from_accmode(accmode_t accmode)
+{
+ int access_mask = 0, i;
+
+ for (i = 0; accmode2mask[i].accmode != 0; i++) {
+ if (accmode & accmode2mask[i].accmode)
+ access_mask |= accmode2mask[i].mask;
+ }
+
+ return (access_mask);
+}
+
+/*
+ * Return 0, iff access is allowed, 1 otherwise.
+ */
+static int
+_acl_denies(const struct acl *aclp, int access_mask, struct ucred *cred,
+ int file_uid, int file_gid, int *denied_explicitly)
+{
+ int i;
+ const struct acl_entry *entry;
+
+ if (denied_explicitly != NULL)
+ *denied_explicitly = 0;
+
+ KASSERT(aclp->acl_cnt > 0, ("aclp->acl_cnt > 0"));
+ KASSERT(aclp->acl_cnt <= ACL_MAX_ENTRIES,
+ ("aclp->acl_cnt <= ACL_MAX_ENTRIES"));
+
+ for (i = 0; i < aclp->acl_cnt; i++) {
+ entry = &(aclp->acl_entry[i]);
+
+ if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW &&
+ entry->ae_entry_type != ACL_ENTRY_TYPE_DENY)
+ continue;
+ if (entry->ae_flags & ACL_ENTRY_INHERIT_ONLY)
+ continue;
+ switch (entry->ae_tag) {
+ case ACL_USER_OBJ:
+ if (file_uid != cred->cr_uid)
+ continue;
+ break;
+ case ACL_USER:
+ if (entry->ae_id != cred->cr_uid)
+ continue;
+ break;
+ case ACL_GROUP_OBJ:
+ if (!groupmember(file_gid, cred))
+ continue;
+ break;
+ case ACL_GROUP:
+ if (!groupmember(entry->ae_id, cred))
+ continue;
+ break;
+ default:
+ KASSERT(entry->ae_tag == ACL_EVERYONE,
+ ("entry->ae_tag == ACL_EVERYONE"));
+ }
+
+ if (entry->ae_entry_type == ACL_ENTRY_TYPE_DENY) {
+ if (entry->ae_perm & access_mask) {
+ if (denied_explicitly != NULL)
+ *denied_explicitly = 1;
+ return (1);
+ }
+ }
+
+ access_mask &= ~(entry->ae_perm);
+ if (access_mask == 0)
+ return (0);
+ }
+
+ return (1);
+}
+
+int
+vaccess_acl_nfs4(enum vtype type, uid_t file_uid, gid_t file_gid,
+ struct acl *aclp, accmode_t accmode, struct ucred *cred, int *privused)
+{
+ accmode_t priv_granted = 0;
+ int denied, explicitly_denied, access_mask, is_directory,
+ must_be_owner = 0;
+
+ if (privused != NULL)
+ *privused = 0;
+
+ if (accmode & VADMIN)
+ must_be_owner = 1;
+
+ /*
+ * Ignore VSYNCHRONIZE permission.
+ */
+ accmode &= ~VSYNCHRONIZE;
+
+ access_mask = _access_mask_from_accmode(accmode);
+
+ if (type == VDIR)
+ is_directory = 1;
+ else
+ is_directory = 0;
+
+ /*
+ * File owner is always allowed to read and write the ACL
+ * and basic attributes. This is to prevent a situation
+ * where user would change ACL in a way that prevents him
+ * from undoing the change.
+ */
+ if (file_uid == cred->cr_uid)
+ access_mask &= ~(ACL_READ_ACL | ACL_WRITE_ACL |
+ ACL_READ_ATTRIBUTES | ACL_WRITE_ATTRIBUTES);
+
+ /*
+ * Ignore append permission for regular files; use write
+ * permission instead.
+ */
+ if (!is_directory && (access_mask & ACL_APPEND_DATA)) {
+ access_mask &= ~ACL_APPEND_DATA;
+ access_mask |= ACL_WRITE_DATA;
+ }
+
+ denied = _acl_denies(aclp, access_mask, cred, file_uid, file_gid,
+ &explicitly_denied);
+
+ if (must_be_owner) {
+ if (file_uid != cred->cr_uid)
+ denied = EPERM;
+ }
+
+ if (!denied)
+ return (0);
+
+ /*
+ * Access failed. Iff it was not denied explicitly and
+ * VEXPLICIT_DENY flag was specified, allow access.
+ */
+ if ((accmode & VEXPLICIT_DENY) && explicitly_denied == 0)
+ return (0);
+
+ accmode &= ~VEXPLICIT_DENY;
+
+ /*
+ * No match. Try to use privileges, if there are any.
+ */
+ if (is_directory) {
+ if ((accmode & VEXEC) && !priv_check_cred(cred,
+ PRIV_VFS_LOOKUP, 0))
+ priv_granted |= VEXEC;
+ } else {
+ if ((accmode & VEXEC) && !priv_check_cred(cred,
+ PRIV_VFS_EXEC, 0))
+ priv_granted |= VEXEC;
+ }
+
+ if ((accmode & VREAD) && !priv_check_cred(cred, PRIV_VFS_READ, 0))
+ priv_granted |= VREAD;
+
+ if ((accmode & (VWRITE | VAPPEND | VDELETE_CHILD)) &&
+ !priv_check_cred(cred, PRIV_VFS_WRITE, 0))
+ priv_granted |= (VWRITE | VAPPEND | VDELETE_CHILD);
+
+ if ((accmode & VADMIN_PERMS) &&
+ !priv_check_cred(cred, PRIV_VFS_ADMIN, 0))
+ priv_granted |= VADMIN_PERMS;
+
+ if ((accmode & VSTAT_PERMS) &&
+ !priv_check_cred(cred, PRIV_VFS_STAT, 0))
+ priv_granted |= VSTAT_PERMS;
+
+ if ((accmode & priv_granted) == accmode) {
+ if (privused != NULL)
+ *privused = 1;
+
+ return (0);
+ }
+
+ if (accmode & (VADMIN_PERMS | VDELETE_CHILD | VDELETE))
+ denied = EPERM;
+ else
+ denied = EACCES;
+
+ return (denied);
+}
+#endif /* _KERNEL */
static int
_acl_entry_matches(struct acl_entry *entry, acl_tag_t tag, acl_perm_t perm,
@@ -577,3 +783,290 @@ acl_nfs4_sync_mode_from_acl(mode_t *_mode, const struct acl *aclp)
*_mode = mode | (old_mode & ACL_PRESERVE_MASK);
}
+
+void
+acl_nfs4_compute_inherited_acl(const struct acl *parent_aclp,
+ struct acl *child_aclp, mode_t mode, int file_owner_id,
+ int is_directory)
+{
+ int i, flags;
+ const struct acl_entry *parent_entry;
+ struct acl_entry *entry, *copy;
+
+ KASSERT(child_aclp->acl_cnt == 0, ("child_aclp->acl_cnt == 0"));
+ KASSERT(parent_aclp->acl_cnt > 0, ("parent_aclp->acl_cnt > 0"));
+ KASSERT(parent_aclp->acl_cnt <= ACL_MAX_ENTRIES,
+ ("parent_aclp->acl_cnt <= ACL_MAX_ENTRIES"));
+
+ /*
+ * NFSv4 Minor Version 1, draft-ietf-nfsv4-minorversion1-03.txt
+ *
+ * 3.16.6.2. Applying the mode given to CREATE or OPEN
+ * to an inherited ACL
+ */
+
+ /*
+ * 1. Form an ACL that is the concatenation of all inheritable ACEs.
+ */
+ for (i = 0; i < parent_aclp->acl_cnt; i++) {
+ parent_entry = &(parent_aclp->acl_entry[i]);
+ flags = parent_entry->ae_flags;
+
+ /*
+ * Entry is not inheritable at all.
+ */
+ if ((flags & (ACL_ENTRY_DIRECTORY_INHERIT |
+ ACL_ENTRY_FILE_INHERIT)) == 0)
+ continue;
+
+ /*
+ * We're creating a file, but entry is not inheritable
+ * by files.
+ */
+ if (!is_directory && (flags & ACL_ENTRY_FILE_INHERIT) == 0)
+ continue;
+
+ /*
+ * Entry is inheritable only by files, but has NO_PROPAGATE
+ * flag set, and we're creating a directory, so it wouldn't
+ * propagate to any file in that directory anyway.
+ */
+ if (is_directory &&
+ (flags & ACL_ENTRY_DIRECTORY_INHERIT) == 0 &&
+ (flags & ACL_ENTRY_NO_PROPAGATE_INHERIT))
+ continue;
+
+ KASSERT(child_aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES,
+ ("child_aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES"));
+ child_aclp->acl_entry[child_aclp->acl_cnt] = *parent_entry;
+ child_aclp->acl_cnt++;
+ }
+
+ /*
+ * 2. For each entry in the new ACL, adjust its flags, possibly
+ * creating two entries in place of one.
+ */
+ for (i = 0; i < child_aclp->acl_cnt; i++) {
+ entry = &(child_aclp->acl_entry[i]);
+
+ /*
+ * This is not in the specification, but SunOS
+ * apparently does that.
+ */
+ if (((entry->ae_flags & ACL_ENTRY_NO_PROPAGATE_INHERIT) ||
+ !is_directory) &&
+ entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW)
+ entry->ae_perm &= ~(ACL_WRITE_ACL | ACL_WRITE_OWNER);
+
+ /*
+ * 2.A. If the ACL_ENTRY_NO_PROPAGATE_INHERIT is set, or if the object
+ * being created is not a directory, then clear the
+ * following flags: ACL_ENTRY_NO_PROPAGATE_INHERIT,
+ * ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT,
+ * ACL_ENTRY_INHERIT_ONLY.
+ */
+ if (entry->ae_flags & ACL_ENTRY_NO_PROPAGATE_INHERIT ||
+ !is_directory) {
+ entry->ae_flags &= ~(ACL_ENTRY_NO_PROPAGATE_INHERIT |
+ ACL_ENTRY_FILE_INHERIT | ACL_ENTRY_DIRECTORY_INHERIT |
+ ACL_ENTRY_INHERIT_ONLY);
+
+ /*
+ * Continue on to the next ACE.
+ */
+ continue;
+ }
+
+ /*
+ * 2.B. If the object is a directory and ACL_ENTRY_FILE_INHERIT
+ * is set, but ACL_ENTRY_NO_PROPAGATE_INHERIT is not set, ensure
+ * that ACL_ENTRY_INHERIT_ONLY is set. Continue to the
+ * next ACE. Otherwise...
+ */
+ /*
+ * XXX: Read it again and make sure what does the "otherwise"
+ * apply to.
+ */
+ if (is_directory &&
+ (entry->ae_flags & ACL_ENTRY_FILE_INHERIT) &&
+ ((entry->ae_flags & ACL_ENTRY_DIRECTORY_INHERIT) == 0)) {
+ entry->ae_flags |= ACL_ENTRY_INHERIT_ONLY;
+ continue;
+ }
+
+ /*
+ * 2.C. If the type of the ACE is neither ALLOW nor deny,
+ * then continue.
+ */
+ if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW &&
+ entry->ae_entry_type != ACL_ENTRY_TYPE_DENY)
+ continue;
+
+ /*
+ * 2.D. Copy the original ACE into a second, adjacent ACE.
+ */
+ copy = _acl_duplicate_entry(child_aclp, i);
+
+ /*
+ * 2.E. On the first ACE, ensure that ACL_ENTRY_INHERIT_ONLY
+ * is set.
+ */
+ entry->ae_flags |= ACL_ENTRY_INHERIT_ONLY;
+
+ /*
+ * 2.F. On the second ACE, clear the following flags:
+ * ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_FILE_INHERIT,
+ * ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_INHERIT_ONLY.
+ */
+ copy->ae_flags &= ~(ACL_ENTRY_NO_PROPAGATE_INHERIT |
+ ACL_ENTRY_FILE_INHERIT | ACL_ENTRY_DIRECTORY_INHERIT |
+ ACL_ENTRY_INHERIT_ONLY);
+
+ /*
+ * 2.G. On the second ACE, if the type is ALLOW,
+ * an implementation MAY clear the following
+ * mask bits: ACL_WRITE_ACL, ACL_WRITE_OWNER.
+ */
+ if (copy->ae_entry_type == ACL_ENTRY_TYPE_ALLOW)
+ copy->ae_perm &= ~(ACL_WRITE_ACL | ACL_WRITE_OWNER);
+
+ /*
+ * Increment the counter to skip the copied entry.
+ */
+ i++;
+ }
+
+ /*
+ * 3. To ensure that the mode is honored, apply the algorithm describe
+ * in Section 2.16.6.3, using the mode that is to be used for file
+ * creation.
+ */
+ acl_nfs4_sync_acl_from_mode(child_aclp, mode, file_owner_id);
+}
+
+#ifdef _KERNEL
+static int
+_acls_are_equal(const struct acl *a, const struct acl *b)
+{
+ int i;
+ const struct acl_entry *entrya, *entryb;
+
+ if (a->acl_cnt != b->acl_cnt)
+ return (0);
+
+ for (i = 0; i < b->acl_cnt; i++) {
+ entrya = &(a->acl_entry[i]);
+ entryb = &(b->acl_entry[i]);
+
+ if (entrya->ae_tag != entryb->ae_tag ||
+ entrya->ae_id != entryb->ae_id ||
+ entrya->ae_perm != entryb->ae_perm ||
+ entrya->ae_entry_type != entryb->ae_entry_type ||
+ entrya->ae_flags != entryb->ae_flags)
+ return (0);
+ }
+
+ return (1);
+}
+
+/*
+ * This routine is used to determine whether to remove entry_type attribute
+ * that stores ACL contents.
+ */
+int
+acl_nfs4_is_trivial(const struct acl *aclp, int file_owner_id)
+{
+ int trivial;
+ mode_t tmpmode = 0;
+ struct acl *tmpaclp;
+
+ if (aclp->acl_cnt != 6)
+ return (0);
+
+ /*
+ * Compute the mode from the ACL, then compute new ACL from that mode.
+ * If the ACLs are identical, then the ACL is trivial.
+ *
+ * XXX: I guess there is a faster way to do this. However, even
+ * this slow implementation significantly speeds things up
+ * for files that don't have any entry_type ACL entries - it's
+ * critical for performance to not use EA when they are not
+ * needed.
+ */
+ tmpaclp = acl_alloc(M_WAITOK | M_ZERO);
+ acl_nfs4_sync_mode_from_acl(&tmpmode, aclp);
+ acl_nfs4_sync_acl_from_mode(tmpaclp, tmpmode, file_owner_id);
+ trivial = _acls_are_equal(aclp, tmpaclp);
+ acl_free(tmpaclp);
+
+ return (trivial);
+}
+#endif /* _KERNEL */
+
+int
+acl_nfs4_check(const struct acl *aclp, int is_directory)
+{
+ int i;
+ const struct acl_entry *entry;
+
+ /*
+ * The spec doesn't seem to say anything about ACL validity.
+ * It seems there is not much to do here. There is even no need
+ * to count "owner@" or "everyone@" (ACL_USER_OBJ and ACL_EVERYONE)
+ * entries, as there can be several of them and that's perfectly
+ * valid. There can be none of them too. Really.
+ */
+
+ if (aclp->acl_cnt > ACL_MAX_ENTRIES || aclp->acl_cnt <= 0)
+ return (EINVAL);
+
+ for (i = 0; i < aclp->acl_cnt; i++) {
+ entry = &(aclp->acl_entry[i]);
+
+ switch (entry->ae_tag) {
+ case ACL_USER_OBJ:
+ case ACL_GROUP_OBJ:
+ case ACL_EVERYONE:
+ if (entry->ae_id != ACL_UNDEFINED_ID)
+ return (EINVAL);
+ break;
+
+ case ACL_USER:
+ case ACL_GROUP:
+ if (entry->ae_id == ACL_UNDEFINED_ID)
+ return (EINVAL);
+ break;
+
+ default:
+ return (EINVAL);
+ }
+
+ if ((entry->ae_perm | ACL_NFS4_PERM_BITS) != ACL_NFS4_PERM_BITS)
+ return (EINVAL);
+
+ /*
+ * Disallow ACL_ENTRY_TYPE_AUDIT and ACL_ENTRY_TYPE_ALARM for now.
+ */
+ if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW &&
+ entry->ae_entry_type != ACL_ENTRY_TYPE_DENY)
+ return (EINVAL);
+
+ if ((entry->ae_flags | ACL_FLAGS_BITS) != ACL_FLAGS_BITS)
+ return (EINVAL);
+
+ /* Disallow unimplemented flags. */
+ if (entry->ae_flags & (ACL_ENTRY_SUCCESSFUL_ACCESS |
+ ACL_ENTRY_FAILED_ACCESS))
+ return (EINVAL);
+
+ /* Disallow flags not allowed for ordinary files. */
+ if (!is_directory) {
+ if (entry->ae_flags & (ACL_ENTRY_FILE_INHERIT |
+ ACL_ENTRY_DIRECTORY_INHERIT |
+ ACL_ENTRY_NO_PROPAGATE_INHERIT | ACL_ENTRY_INHERIT_ONLY))
+ return (EINVAL);
+ }
+ }
+
+ return (0);
+}
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index f202631..3f51c5c 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -1017,7 +1017,7 @@ devclass_driver_added(devclass_t dc, driver_t *driver)
* Call BUS_DRIVER_ADDED for any existing busses in this class.
*/
for (i = 0; i < dc->maxunit; i++)
- if (dc->devices[i])
+ if (dc->devices[i] && device_is_attached(dc->devices[i]))
BUS_DRIVER_ADDED(dc->devices[i], driver);
/*
diff --git a/sys/kern/subr_devstat.c b/sys/kern/subr_devstat.c
index bbfed44..e90df59 100644
--- a/sys/kern/subr_devstat.c
+++ b/sys/kern/subr_devstat.c
@@ -469,7 +469,7 @@ static struct devstat *
devstat_alloc(void)
{
struct devstat *dsp;
- struct statspage *spp;
+ struct statspage *spp, *spp2;
u_int u;
static int once;
@@ -479,6 +479,7 @@ devstat_alloc(void)
UID_ROOT, GID_WHEEL, 0400, DEVSTAT_DEVICE_NAME);
once = 1;
}
+ spp2 = NULL;
mtx_lock(&devstat_mutex);
for (;;) {
TAILQ_FOREACH(spp, &pagelist, list) {
@@ -487,24 +488,30 @@ devstat_alloc(void)
}
if (spp != NULL)
break;
- /*
- * We had no free slot in any of our pages, drop the mutex
- * and get another page. In theory we could have more than
- * one process doing this at the same time and consequently
- * we may allocate more pages than we will need. That is
- * Just Too Bad[tm], we can live with that.
- */
mtx_unlock(&devstat_mutex);
- spp = malloc(sizeof *spp, M_DEVSTAT, M_ZERO | M_WAITOK);
- spp->stat = malloc(PAGE_SIZE, M_DEVSTAT, M_ZERO | M_WAITOK);
- spp->nfree = statsperpage;
- mtx_lock(&devstat_mutex);
+ spp2 = malloc(sizeof *spp, M_DEVSTAT, M_ZERO | M_WAITOK);
+ spp2->stat = malloc(PAGE_SIZE, M_DEVSTAT, M_ZERO | M_WAITOK);
+ spp2->nfree = statsperpage;
+
/*
- * It would make more sense to add the new page at the head
- * but the order on the list determine the sequence of the
- * mapping so we can't do that.
+ * If free statspages were added while the lock was released
+ * just reuse them.
*/
- TAILQ_INSERT_TAIL(&pagelist, spp, list);
+ mtx_lock(&devstat_mutex);
+ TAILQ_FOREACH(spp, &pagelist, list)
+ if (spp->nfree > 0)
+ break;
+ if (spp == NULL) {
+ spp = spp2;
+
+ /*
+ * It would make more sense to add the new page at the
+ * head but the order on the list determine the
+ * sequence of the mapping so we can't do that.
+ */
+ TAILQ_INSERT_TAIL(&pagelist, spp, list);
+ } else
+ break;
}
dsp = spp->stat;
for (u = 0; u < statsperpage; u++) {
@@ -515,6 +522,10 @@ devstat_alloc(void)
spp->nfree--;
dsp->allocated = 1;
mtx_unlock(&devstat_mutex);
+ if (spp2 != NULL && spp2 != spp) {
+ free(spp2->stat, M_DEVSTAT);
+ free(spp2, M_DEVSTAT);
+ }
return (dsp);
}
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index d28001f..f226e3a 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -104,12 +104,6 @@ SYSCTL_INT(_kern_smp, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
&forward_signal_enabled, 0,
"Forwarding of a signal to a process on a different CPU");
-/* Enable forwarding of roundrobin to all other cpus */
-static int forward_roundrobin_enabled = 1;
-SYSCTL_INT(_kern_smp, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
- &forward_roundrobin_enabled, 0,
- "Forwarding of roundrobin to all other CPUs");
-
/* Variables needed for SMP rendezvous. */
static volatile int smp_rv_ncpus;
static void (*volatile smp_rv_setup_func)(void *arg);
@@ -189,33 +183,6 @@ forward_signal(struct thread *td)
ipi_selected(1 << id, IPI_AST);
}
-void
-forward_roundrobin(void)
-{
- struct pcpu *pc;
- struct thread *td;
- cpumask_t id, map, me;
-
- CTR0(KTR_SMP, "forward_roundrobin()");
-
- if (!smp_started || cold || panicstr)
- return;
- if (!forward_roundrobin_enabled)
- return;
- map = 0;
- me = PCPU_GET(cpumask);
- SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
- td = pc->pc_curthread;
- id = pc->pc_cpumask;
- if (id != me && (id & stopped_cpus) == 0 &&
- !TD_IS_IDLETHREAD(td)) {
- td->td_flags |= TDF_NEEDRESCHED;
- map |= id;
- }
- }
- ipi_selected(map, IPI_AST);
-}
-
/*
* When called the executing CPU will send an IPI to all other CPUs
* requesting that they halt execution.
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 9717679..34eaf20 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filio.h>
+#include <sys/jail.h>
#include <sys/mount.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
@@ -2316,6 +2317,7 @@ sctp_peeloff(td, uap)
goto done;
td->td_retval[0] = fd;
+ CURVNET_SET(head->so_vnet);
so = sonewconn(head, SS_ISCONNECTED);
if (so == NULL)
goto noconnection;
@@ -2355,6 +2357,7 @@ noconnection:
/*
* Release explicitly held references before returning.
*/
+ CURVNET_RESTORE();
done:
if (nfp != NULL)
fdrop(nfp, td);
@@ -2433,9 +2436,11 @@ sctp_generic_sendmsg (td, uap)
auio.uio_offset = 0; /* XXX */
auio.uio_resid = 0;
len = auio.uio_resid = uap->mlen;
+ CURVNET_SET(so->so_vnet);
error = sctp_lower_sosend(so, to, &auio,
(struct mbuf *)NULL, (struct mbuf *)NULL,
uap->flags, use_rcvinfo, u_sinfo, td);
+ CURVNET_RESTORE();
if (error) {
if (auio.uio_resid != len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
@@ -2543,9 +2548,11 @@ sctp_generic_sendmsg_iov(td, uap)
}
}
len = auio.uio_resid;
+ CURVNET_SET(so->so_vnet);
error = sctp_lower_sosend(so, to, &auio,
(struct mbuf *)NULL, (struct mbuf *)NULL,
uap->flags, use_rcvinfo, u_sinfo, td);
+ CURVNET_RESTORE();
if (error) {
if (auio.uio_resid != len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
@@ -2665,9 +2672,11 @@ sctp_generic_recvmsg(td, uap)
if (KTRPOINT(td, KTR_GENIO))
ktruio = cloneuio(&auio);
#endif /* KTRACE */
+ CURVNET_SET(so->so_vnet);
error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
fromsa, fromlen, &msg_flags,
(struct sctp_sndrcvinfo *)&sinfo, 1);
+ CURVNET_RESTORE();
if (error) {
if (auio.uio_resid != (int)len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h
index 10f348a..b818649 100644
--- a/sys/mips/include/param.h
+++ b/sys/mips/include/param.h
@@ -115,6 +115,8 @@
#define SEGOFSET (NBSEG-1) /* byte offset into segment */
#define SEGSHIFT 22 /* LOG2(NBSEG) */
+#define MAXPAGESIZES 1 /* maximum number of supported page sizes */
+
/* XXXimp: This has moved to vmparam.h */
/* Also, this differs from the mips2 definition, but likely is better */
/* since this means the kernel won't chew up TLBs when it is executing */
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 8f37b61..49d8860 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -298,7 +298,7 @@ SUBDIR= ${_3dfx} \
wlan_xauth \
${_wpi} \
${_wpifw} \
- x86emu \
+ ${_x86bios} \
${_xe} \
xfs \
xl \
@@ -456,6 +456,7 @@ _padlock= padlock
_s3= s3
_twa= twa
_vesa= vesa
+_x86bios= x86bios
.elif ${MACHINE} == "pc98"
_canbepm= canbepm
_canbus= canbus
@@ -528,6 +529,7 @@ _padlock= padlock
.endif
_pccard= pccard
_rdma= rdma
+_s3= s3
_safe= safe
_scsi_low= scsi_low
_smbfs= smbfs
@@ -538,6 +540,7 @@ _sppp= sppp
_tmpfs= tmpfs
_twa= twa
_vesa= vesa
+_x86bios= x86bios
_wi= wi
_wpi= wpi
_wpifw= wpifw
diff --git a/sys/modules/procfs/Makefile b/sys/modules/procfs/Makefile
index 6c840ed..c3b3633 100644
--- a/sys/modules/procfs/Makefile
+++ b/sys/modules/procfs/Makefile
@@ -13,6 +13,7 @@ SRCS+= procfs_ioctl.c
SRCS+= procfs_map.c
SRCS+= procfs_mem.c
SRCS+= procfs_note.c
+SRCS+= procfs_osrel.c
SRCS+= procfs_regs.c
SRCS+= procfs_rlimit.c
SRCS+= procfs_status.c
diff --git a/sys/modules/x86bios/Makefile b/sys/modules/x86bios/Makefile
new file mode 100644
index 0000000..8b5fa30
--- /dev/null
+++ b/sys/modules/x86bios/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+KMOD= x86bios
+SRCS= opt_x86bios.h
+
+.PATH: ${.CURDIR}/../../contrib/x86emu
+.PATH: ${.CURDIR}/../../compat/x86bios
+SRCS+= x86bios.c x86bios_alloc.c x86emu.c x86emu_util.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/x86emu/Makefile b/sys/modules/x86emu/Makefile
deleted file mode 100644
index 3991d6c..0000000
--- a/sys/modules/x86emu/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../contrib/x86emu
-
-KMOD= x86emu
-SRCS= x86emu.c x86emu_util.c
-
-.include <bsd.kmod.mk>
diff --git a/sys/net/if.c b/sys/net/if.c
index c0ff443..55de666 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1432,9 +1432,9 @@ ifa_add_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
if (error == 0 && rt != NULL) {
RT_LOCK(rt);
((struct sockaddr_dl *)rt->rt_gateway)->sdl_type =
- rt->rt_ifp->if_type;
+ ifa->ifa_ifp->if_type;
((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
- rt->rt_ifp->if_index;
+ ifa->ifa_ifp->if_index;
RT_REMREF(rt);
RT_UNLOCK(rt);
} else if (error != 0)
diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
index b66d6e1..4991c81 100644
--- a/sys/net/if_llatbl.c
+++ b/sys/net/if_llatbl.c
@@ -57,11 +57,14 @@ __FBSDID("$FreeBSD$");
MALLOC_DEFINE(M_LLTABLE, "lltable", "link level address tables");
-static SLIST_HEAD(, lltable) lltables = SLIST_HEAD_INITIALIZER(lltables);
+static VNET_DEFINE(SLIST_HEAD(, lltable), lltables);
+#define V_lltables VNET(lltables)
extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *,
u_char *);
+static void vnet_lltable_init(void);
+
struct rwlock lltable_rwlock;
RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
@@ -75,7 +78,7 @@ lltable_sysctl_dumparp(int af, struct sysctl_req *wr)
int error = 0;
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af == af) {
error = llt->llt_dump(llt, wr);
if (error != 0)
@@ -157,7 +160,7 @@ lltable_free(struct lltable *llt)
KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
LLTABLE_WLOCK();
- SLIST_REMOVE(&lltables, llt, lltable, llt_link);
+ SLIST_REMOVE(&V_lltables, llt, lltable, llt_link);
LLTABLE_WUNLOCK();
for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
@@ -180,7 +183,7 @@ lltable_drain(int af)
register int i;
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af != af)
continue;
@@ -202,7 +205,7 @@ lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask)
struct lltable *llt;
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af != af)
continue;
@@ -232,7 +235,7 @@ lltable_init(struct ifnet *ifp, int af)
LIST_INIT(&llt->lle_head[i]);
LLTABLE_WLOCK();
- SLIST_INSERT_HEAD(&lltables, llt, llt_link);
+ SLIST_INSERT_HEAD(&V_lltables, llt, llt_link);
LLTABLE_WUNLOCK();
return (llt);
@@ -302,7 +305,7 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
/* XXX linked list may be too expensive */
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af == dst->sa_family &&
llt->llt_ifp == ifp)
break;
@@ -367,3 +370,13 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
return (error);
}
+
+static void
+vnet_lltable_init()
+{
+
+ SLIST_INIT(&V_lltables);
+}
+VNET_SYSINIT(vnet_lltable_init, SI_SUB_PSEUDO, SI_ORDER_FIRST,
+ vnet_lltable_init, NULL);
+
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index 5ddca24..712c2a8 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -708,7 +708,7 @@ enum {
IEEE80211_ELEMID_VENDOR = 221, /* vendor private */
/*
- * 802.11s IEs based on D3.0 spec and were not assigned by
+ * 802.11s IEs based on D3.03 spec and were not assigned by
* ANA. Beware changing them because some of them are being
* kept compatible with Linux.
*/
@@ -726,10 +726,9 @@ enum {
IEEE80211_ELEMID_MESHPREQ = 68,
IEEE80211_ELEMID_MESHPREP = 69,
IEEE80211_ELEMID_MESHPERR = 70,
- IEEE80211_ELEMID_MESHPU = 53,
- IEEE80211_ELEMID_MESHPUC = 54,
+ IEEE80211_ELEMID_MESHPXU = 53,
+ IEEE80211_ELEMID_MESHPXUC = 54,
IEEE80211_ELEMID_MESHAH = 60, /* Abbreviated Handshake */
- IEEE80211_ELEMID_MESHPEERVER = 80, /* Peering Protocol Version */
};
struct ieee80211_tim_ie {
@@ -925,6 +924,9 @@ enum {
IEEE80211_REASON_MESH_INVALID_GTK = 8, /* 11s */
IEEE80211_REASON_MESH_INCONS_PARAMS = 9, /* 11s */
IEEE80211_REASON_MESH_INVALID_SECURITY = 10, /* 11s */
+ IEEE80211_REASON_MESH_PERR_UNSPEC = 11, /* 11s */
+ IEEE80211_REASON_MESH_PERR_NO_FI = 12, /* 11s */
+ IEEE80211_REASON_MESH_PERR_DEST_UNREACH = 13, /* 11s */
IEEE80211_STATUS_SUCCESS = 0,
IEEE80211_STATUS_UNSPECIFIED = 1,
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index 040941e..2468169 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -188,10 +188,7 @@ SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, rannint, CTLTYPE_INT | CTLFLAG_RW,
#define IEEE80211_HWMP_DEFAULT_MAXHOPS 31
-static ieee80211_recv_action_func hwmp_recv_action_meshpath_preq;
-static ieee80211_recv_action_func hwmp_recv_action_meshpath_prep;
-static ieee80211_recv_action_func hwmp_recv_action_meshpath_perr;
-static ieee80211_recv_action_func hwmp_recv_action_meshpath_rann;
+static ieee80211_recv_action_func hwmp_recv_action_meshpath;
static struct ieee80211_mesh_proto_path mesh_proto_hwmp = {
.mpp_descr = "HWMP",
@@ -217,16 +214,10 @@ ieee80211_hwmp_init(void)
ieee80211_hwmp_rannint = msecs_to_ticks(1*1000);
/*
- * Register action frame handlers.
+ * Register action frame handler.
*/
ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
- IEEE80211_ACTION_MESHPATH_REQ, hwmp_recv_action_meshpath_preq);
- ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
- IEEE80211_ACTION_MESHPATH_REP, hwmp_recv_action_meshpath_prep);
- ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
- IEEE80211_ACTION_MESHPATH_ERR, hwmp_recv_action_meshpath_perr);
- ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
- IEEE80211_ACTION_MESHPATH_RANN, hwmp_recv_action_meshpath_rann);
+ IEEE80211_ACTION_MESHPATH_SEL, hwmp_recv_action_meshpath);
/* NB: default is 5 secs per spec */
mesh_proto_hwmp.mpp_inact = msecs_to_ticks(5*1000);
@@ -285,17 +276,23 @@ hwmp_newstate(struct ieee80211vap *vap, enum ieee80211_state ostate, int arg)
}
static int
-hwmp_recv_action_meshpath_preq(struct ieee80211_node *ni,
+hwmp_recv_action_meshpath(struct ieee80211_node *ni,
const struct ieee80211_frame *wh,
const uint8_t *frm, const uint8_t *efrm)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_meshpreq_ie preq;
+ struct ieee80211_meshprep_ie prep;
+ struct ieee80211_meshperr_ie perr;
+ struct ieee80211_meshrann_ie rann;
const uint8_t *iefrm = frm + 2; /* action + code */
+ int found = 0;
while (efrm - iefrm > 1) {
IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
- if (*iefrm == IEEE80211_ELEMID_MESHPREQ) {
+ switch (*iefrm) {
+ case IEEE80211_ELEMID_MESHPREQ:
+ {
const struct ieee80211_meshpreq_ie *mpreq =
(const struct ieee80211_meshpreq_ie *) iefrm;
/* XXX > 1 target */
@@ -305,7 +302,7 @@ hwmp_recv_action_meshpath_preq(struct ieee80211_node *ni,
IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
wh, NULL, "%s", "PREQ with wrong len");
vap->iv_stats.is_rx_mgtdiscard++;
- return 1;
+ break;
}
memcpy(&preq, mpreq, sizeof(preq));
preq.preq_id = LE_READ_4(&mpreq->preq_id);
@@ -315,28 +312,11 @@ hwmp_recv_action_meshpath_preq(struct ieee80211_node *ni,
preq.preq_targets[0].target_seq =
LE_READ_4(&mpreq->preq_targets[0].target_seq);
hwmp_recv_preq(vap, ni, wh, &preq);
- return 0;
+ found++;
+ break;
}
- iefrm += iefrm[1] + 2;
- }
- IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
- wh, NULL, "%s", "PREQ without IE");
- vap->iv_stats.is_rx_mgtdiscard++;
- return 0;
-}
-
-static int
-hwmp_recv_action_meshpath_prep(struct ieee80211_node *ni,
- const struct ieee80211_frame *wh,
- const uint8_t *frm, const uint8_t *efrm)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211_meshprep_ie prep;
- const uint8_t *iefrm = frm + 2; /* action + code */
-
- while (efrm - iefrm > 1) {
- IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
- if (*iefrm == IEEE80211_ELEMID_MESHPREP) {
+ case IEEE80211_ELEMID_MESHPREP:
+ {
const struct ieee80211_meshprep_ie *mprep =
(const struct ieee80211_meshprep_ie *) iefrm;
if (mprep->prep_len !=
@@ -345,7 +325,7 @@ hwmp_recv_action_meshpath_prep(struct ieee80211_node *ni,
IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
wh, NULL, "%s", "PREP with wrong len");
vap->iv_stats.is_rx_mgtdiscard++;
- return 1;
+ break;
}
memcpy(&prep, mprep, sizeof(prep));
prep.prep_targetseq = LE_READ_4(&mprep->prep_targetseq);
@@ -353,28 +333,11 @@ hwmp_recv_action_meshpath_prep(struct ieee80211_node *ni,
prep.prep_metric = LE_READ_4(&mprep->prep_metric);
prep.prep_origseq = LE_READ_4(&mprep->prep_origseq);
hwmp_recv_prep(vap, ni, wh, &prep);
- return 0;
+ found++;
+ break;
}
- iefrm += iefrm[1] + 2;
- }
- IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
- wh, NULL, "%s", "PREP without IE");
- vap->iv_stats.is_rx_mgtdiscard++;
- return 0;
-}
-
-static int
-hwmp_recv_action_meshpath_perr(struct ieee80211_node *ni,
- const struct ieee80211_frame *wh,
- const uint8_t *frm, const uint8_t *efrm)
-{
- struct ieee80211_meshperr_ie perr;
- struct ieee80211vap *vap = ni->ni_vap;
- const uint8_t *iefrm = frm + 2; /* action + code */
-
- while (efrm - iefrm > 1) {
- IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
- if (*iefrm == IEEE80211_ELEMID_MESHPERR) {
+ case IEEE80211_ELEMID_MESHPERR:
+ {
const struct ieee80211_meshperr_ie *mperr =
(const struct ieee80211_meshperr_ie *) iefrm;
/* XXX > 1 target */
@@ -384,34 +347,17 @@ hwmp_recv_action_meshpath_perr(struct ieee80211_node *ni,
IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
wh, NULL, "%s", "PERR with wrong len");
vap->iv_stats.is_rx_mgtdiscard++;
- return 1;
+ break;
}
memcpy(&perr, mperr, sizeof(perr));
perr.perr_dests[0].dest_seq =
LE_READ_4(&mperr->perr_dests[0].dest_seq);
hwmp_recv_perr(vap, ni, wh, &perr);
- return 0;
+ found++;
+ break;
}
- iefrm += iefrm[1] + 2;
- }
- IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
- wh, NULL, "%s", "PERR without IE");
- vap->iv_stats.is_rx_mgtdiscard++;
- return 0;
-}
-
-static int
-hwmp_recv_action_meshpath_rann(struct ieee80211_node *ni,
- const struct ieee80211_frame *wh,
- const uint8_t *frm, const uint8_t *efrm)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211_meshrann_ie rann;
- const uint8_t *iefrm = frm + 2; /* action + code */
-
- while (efrm - iefrm > 1) {
- IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
- if (*iefrm == IEEE80211_ELEMID_MESHRANN) {
+ case IEEE80211_ELEMID_MESHRANN:
+ {
const struct ieee80211_meshrann_ie *mrann =
(const struct ieee80211_meshrann_ie *) iefrm;
if (mrann->rann_len !=
@@ -426,13 +372,18 @@ hwmp_recv_action_meshpath_rann(struct ieee80211_node *ni,
rann.rann_seq = LE_READ_4(&mrann->rann_seq);
rann.rann_metric = LE_READ_4(&mrann->rann_metric);
hwmp_recv_rann(vap, ni, wh, &rann);
- return 0;
+ found++;
+ break;
+ }
}
iefrm += iefrm[1] + 2;
}
- IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
- wh, NULL, "%s", "RANN without IE");
- vap->iv_stats.is_rx_mgtdiscard++;
+ if (!found) {
+ IEEE80211_DISCARD(vap,
+ IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
+ wh, NULL, "%s", "PATH SEL action without IE");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ }
return 0;
}
@@ -480,24 +431,21 @@ hwmp_send_action(struct ieee80211_node *ni,
return ENOMEM;
}
*frm++ = IEEE80211_ACTION_CAT_MESHPATH;
+ *frm++ = IEEE80211_ACTION_MESHPATH_SEL;
switch (*ie) {
case IEEE80211_ELEMID_MESHPREQ:
- *frm++ = IEEE80211_ACTION_MESHPATH_REQ;
frm = hwmp_add_meshpreq(frm,
(struct ieee80211_meshpreq_ie *)ie);
break;
case IEEE80211_ELEMID_MESHPREP:
- *frm++ = IEEE80211_ACTION_MESHPATH_REP;
frm = hwmp_add_meshprep(frm,
(struct ieee80211_meshprep_ie *)ie);
break;
case IEEE80211_ELEMID_MESHPERR:
- *frm++ = IEEE80211_ACTION_MESHPATH_ERR;
frm = hwmp_add_meshperr(frm,
(struct ieee80211_meshperr_ie *)ie);
break;
case IEEE80211_ELEMID_MESHRANN:
- *frm++ = IEEE80211_ACTION_MESHPATH_RANN;
frm = hwmp_add_meshrann(frm,
(struct ieee80211_meshrann_ie *)ie);
break;
@@ -528,6 +476,11 @@ hwmp_send_action(struct ieee80211_node *ni,
return ic->ic_raw_xmit(ni, m, &params);
}
+#define ADDSHORT(frm, v) do { \
+ frm[0] = (v) & 0xff; \
+ frm[1] = (v) >> 8; \
+ frm += 2; \
+} while (0)
#define ADDWORD(frm, v) do { \
LE_WRITE_4(frm, v); \
frm += 4; \
@@ -592,12 +545,14 @@ hwmp_add_meshperr(uint8_t *frm, const struct ieee80211_meshperr_ie *perr)
*frm++ = IEEE80211_ELEMID_MESHPERR;
*frm++ = sizeof(struct ieee80211_meshperr_ie) - 2 +
(perr->perr_ndests - 1) * sizeof(*perr->perr_dests);
- *frm++ = perr->perr_mode;
+ *frm++ = perr->perr_ttl;
*frm++ = perr->perr_ndests;
for (i = 0; i < perr->perr_ndests; i++) {
+ *frm += perr->perr_dests[i].dest_flags;
IEEE80211_ADDR_COPY(frm, perr->perr_dests[i].dest_addr);
frm += 6;
ADDWORD(frm, perr->perr_dests[i].dest_seq);
+ ADDSHORT(frm, perr->perr_dests[i].dest_rcode);
}
return frm;
}
@@ -1138,12 +1093,15 @@ hwmp_send_prep(struct ieee80211_node *ni,
sizeof(struct ieee80211_meshprep_ie));
}
+#define PERR_DFLAGS(n) perr.perr_dests[n].dest_flags
#define PERR_DADDR(n) perr.perr_dests[n].dest_addr
#define PERR_DSEQ(n) perr.perr_dests[n].dest_seq
+#define PERR_DRCODE(n) perr.perr_dests[n].dest_rcode
static void
hwmp_peerdown(struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211_mesh_state *ms = vap->iv_mesh;
struct ieee80211_meshperr_ie perr;
struct ieee80211_mesh_route *rt;
struct ieee80211_hwmp_route *hr;
@@ -1154,19 +1112,27 @@ hwmp_peerdown(struct ieee80211_node *ni)
hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"%s", "delete route entry");
- perr.perr_mode = 0;
+ perr.perr_ttl = ms->ms_ttl;
perr.perr_ndests = 1;
+ if (hr->hr_seq == 0)
+ PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN;
+ PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC;
IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest);
PERR_DSEQ(0) = hr->hr_seq;
+ PERR_DRCODE(0) = IEEE80211_REASON_MESH_PERR_DEST_UNREACH;
/* NB: flush everything passing through peer */
ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr);
hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr);
}
+#undef PERR_DFLAGS
#undef PERR_DADDR
#undef PERR_DSEQ
+#undef PERR_DRCODE
+#define PERR_DFLAGS(n) perr->perr_dests[n].dest_flags
#define PERR_DADDR(n) perr->perr_dests[n].dest_addr
#define PERR_DSEQ(n) perr->perr_dests[n].dest_seq
+#define PERR_DRCODE(n) perr->perr_dests[n].dest_rcode
static void
hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
const struct ieee80211_frame *wh, const struct ieee80211_meshperr_ie *perr)
@@ -1192,9 +1158,9 @@ hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
rt = ieee80211_mesh_rt_find(vap, PERR_DADDR(i));
if (rt == NULL)
continue;
- hr = IEEE80211_MESH_ROUTE_PRIV(rt,
- struct ieee80211_hwmp_route);
- if (HWMP_SEQ_GEQ(PERR_DSEQ(i), hr->hr_seq)) {
+ hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
+ if (!(PERR_DFLAGS(0) & IEEE80211_MESHPERR_DFLAGS_USN) &&
+ HWMP_SEQ_GEQ(PERR_DSEQ(i), hr->hr_seq)) {
ieee80211_mesh_rt_del(vap, rt->rt_dest);
ieee80211_mesh_rt_flush_peer(vap, rt->rt_dest);
rt = NULL;
@@ -1205,10 +1171,11 @@ hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
* Propagate the PERR if we previously found it on our routing table.
* XXX handle ndest > 1
*/
- if (forward) {
+ if (forward && perr->perr_ttl > 1) {
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"propagate PERR from %s", ether_sprintf(wh->i_addr2));
memcpy(&pperr, perr, sizeof(*perr));
+ pperr.perr_ttl--;
hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr,
&pperr);
}
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 7227495..b0bfe88 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -87,10 +87,10 @@ static void mesh_peer_timeout_backoff(struct ieee80211_node *);
static void mesh_peer_timeout_cb(void *);
static __inline void
mesh_peer_timeout_stop(struct ieee80211_node *);
-static int mesh_verify_meshpeerver(struct ieee80211vap *, const uint8_t *);
static int mesh_verify_meshid(struct ieee80211vap *, const uint8_t *);
static int mesh_verify_meshconf(struct ieee80211vap *, const uint8_t *);
-static int mesh_verify_meshpeer(struct ieee80211vap *, const uint8_t *);
+static int mesh_verify_meshpeer(struct ieee80211vap *, uint8_t,
+ const uint8_t *);
uint32_t mesh_airtime_calc(struct ieee80211_node *);
/*
@@ -1544,19 +1544,16 @@ static const struct ieee80211_meshpeer_ie *
mesh_parse_meshpeering_action(struct ieee80211_node *ni,
const struct ieee80211_frame *wh, /* XXX for VERIFY_LENGTH */
const uint8_t *frm, const uint8_t *efrm,
- struct ieee80211_meshpeer_ie *mp)
+ struct ieee80211_meshpeer_ie *mp, uint8_t subtype)
{
struct ieee80211vap *vap = ni->ni_vap;
const struct ieee80211_meshpeer_ie *mpie;
- const uint8_t *meshid, *meshconf, *meshpeerver, *meshpeer;
+ const uint8_t *meshid, *meshconf, *meshpeer;
- meshid = meshconf = meshpeerver = meshpeer = NULL;
+ meshid = meshconf = meshpeer = NULL;
while (efrm - frm > 1) {
IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return NULL);
switch (*frm) {
- case IEEE80211_ELEMID_MESHPEERVER:
- meshpeerver = frm;
- break;
case IEEE80211_ELEMID_MESHID:
meshid = frm;
break;
@@ -1567,12 +1564,10 @@ mesh_parse_meshpeering_action(struct ieee80211_node *ni,
meshpeer = frm;
mpie = (const struct ieee80211_meshpeer_ie *) frm;
memset(mp, 0, sizeof(*mp));
- mp->peer_subtype = mpie->peer_subtype;
mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid);
/* NB: peer link ID is optional on these frames */
- if (mpie->peer_subtype ==
- IEEE80211_MESH_PEER_LINK_CLOSE &&
- mpie->peer_len == 5) {
+ if (subtype == IEEE80211_MESH_PEER_LINK_CLOSE &&
+ mpie->peer_len == 8) {
mp->peer_linkid = 0;
mp->peer_rcode = LE_READ_2(&mpie->peer_linkid);
} else {
@@ -1589,12 +1584,12 @@ mesh_parse_meshpeering_action(struct ieee80211_node *ni,
* close subtype don't have a Mesh Configuration IE.
* If if fails validation, close the peer link.
*/
- KASSERT(meshpeer != NULL && mp->peer_subtype !=
- IEEE80211_ACTION_MESHPEERING_CLOSE, ("parsing close action"));
+ KASSERT(meshpeer != NULL &&
+ subtype != IEEE80211_ACTION_MESHPEERING_CLOSE,
+ ("parsing close action"));
- if (mesh_verify_meshpeerver(vap, meshpeerver) ||
- mesh_verify_meshid(vap, meshid) ||
- mesh_verify_meshpeer(vap, meshpeer) ||
+ if (mesh_verify_meshid(vap, meshid) ||
+ mesh_verify_meshpeer(vap, subtype, meshpeer) ||
mesh_verify_meshconf(vap, meshconf)) {
uint16_t args[3];
@@ -1638,7 +1633,8 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni,
uint16_t args[3];
/* +2+2 for action + code + capabilites */
- meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2, efrm, &ie);
+ meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2, efrm, &ie,
+ IEEE80211_ACTION_MESHPEERING_OPEN);
if (meshpeer == NULL) {
return 0;
}
@@ -1770,7 +1766,8 @@ mesh_recv_action_meshpeering_confirm(struct ieee80211_node *ni,
uint16_t args[3];
/* +2+2+2+2 for action + code + capabilites + status code + AID */
- meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2+2+2, efrm, &ie);
+ meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2+2+2, efrm, &ie,
+ IEEE80211_ACTION_MESHPEERING_CONFIRM);
if (meshpeer == NULL) {
return 0;
}
@@ -1933,7 +1930,6 @@ mesh_send_action_meshpeering_open(struct ieee80211_node *ni,
ic->ic_headroom + sizeof(struct ieee80211_frame),
sizeof(uint16_t) /* action+category */
+ sizeof(uint16_t) /* capabilites */
- + sizeof(struct ieee80211_meshpeerver_ie)
+ 2 + IEEE80211_RATE_SIZE
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
+ 2 + IEEE80211_MESHID_LEN
@@ -1946,7 +1942,6 @@ mesh_send_action_meshpeering_open(struct ieee80211_node *ni,
* [1] category
* [1] action
* [2] capabilities
- * [tlv] mesh peer protocol version
* [tlv] rates
* [tlv] xrates
* [tlv] mesh id
@@ -1956,7 +1951,6 @@ mesh_send_action_meshpeering_open(struct ieee80211_node *ni,
*frm++ = category;
*frm++ = action;
ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan));
- frm = ieee80211_add_meshpeerver(frm, vap);
rs = ieee80211_get_suprates(ic, ic->ic_curchan);
frm = ieee80211_add_rates(frm, rs);
frm = ieee80211_add_xrates(frm, rs);
@@ -1999,7 +1993,6 @@ mesh_send_action_meshpeering_confirm(struct ieee80211_node *ni,
+ sizeof(uint16_t) /* capabilites */
+ sizeof(uint16_t) /* status code */
+ sizeof(uint16_t) /* AID */
- + sizeof(struct ieee80211_meshpeerver_ie)
+ 2 + IEEE80211_RATE_SIZE
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
+ 2 + IEEE80211_MESHID_LEN
@@ -2014,7 +2007,6 @@ mesh_send_action_meshpeering_confirm(struct ieee80211_node *ni,
* [2] capabilities
* [2] status code
* [2] association id (peer ID)
- * [tlv] mesh peer protocol version
* [tlv] rates
* [tlv] xrates
* [tlv] mesh id
@@ -2026,7 +2018,6 @@ mesh_send_action_meshpeering_confirm(struct ieee80211_node *ni,
ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan));
ADDSHORT(frm, 0); /* status code */
ADDSHORT(frm, args[1]); /* AID */
- frm = ieee80211_add_meshpeerver(frm, vap);
rs = ieee80211_get_suprates(ic, ic->ic_curchan);
frm = ieee80211_add_rates(frm, rs);
frm = ieee80211_add_xrates(frm, rs);
@@ -2067,7 +2058,6 @@ mesh_send_action_meshpeering_close(struct ieee80211_node *ni,
ic->ic_headroom + sizeof(struct ieee80211_frame),
sizeof(uint16_t) /* action+category */
+ sizeof(uint16_t) /* reason code */
- + sizeof(struct ieee80211_meshpeerver_ie)
+ 2 + IEEE80211_MESHID_LEN
+ sizeof(struct ieee80211_meshpeer_ie)
);
@@ -2077,14 +2067,12 @@ mesh_send_action_meshpeering_close(struct ieee80211_node *ni,
* [1] category
* [1] action
* [2] reason code
- * [tlv] mesh peer protocol version
* [tlv] mesh id
* [tlv] mesh peer link mgmt
*/
*frm++ = category;
*frm++ = action;
ADDSHORT(frm, args[2]); /* reason code */
- frm = ieee80211_add_meshpeerver(frm, vap);
frm = ieee80211_add_meshid(frm, vap);
frm = ieee80211_add_meshpeer(frm,
IEEE80211_MESH_PEER_LINK_CLOSE,
@@ -2279,19 +2267,6 @@ mesh_peer_timeout_cb(void *arg)
}
static int
-mesh_verify_meshpeerver(struct ieee80211vap *vap, const uint8_t *ie)
-{
- static const uint8_t peer[4] = IEEE80211_MESHPEERVER_PEER;
- const struct ieee80211_meshpeerver_ie *meshpeerver =
- (const struct ieee80211_meshpeerver_ie *) ie;
-
- if (meshpeerver->peerver_len !=
- sizeof(struct ieee80211_meshpeerver_ie) - 2)
- return 1;
- return memcmp(meshpeerver->peerver_proto, peer, 4);
-}
-
-static int
mesh_verify_meshid(struct ieee80211vap *vap, const uint8_t *ie)
{
struct ieee80211_mesh_state *ms = vap->iv_mesh;
@@ -2364,26 +2339,28 @@ mesh_verify_meshconf(struct ieee80211vap *vap, const uint8_t *ie)
}
static int
-mesh_verify_meshpeer(struct ieee80211vap *vap, const uint8_t *ie)
+mesh_verify_meshpeer(struct ieee80211vap *vap, uint8_t subtype,
+ const uint8_t *ie)
{
const struct ieee80211_meshpeer_ie *meshpeer =
(const struct ieee80211_meshpeer_ie *) ie;
- if (meshpeer == NULL)
+ if (meshpeer == NULL || meshpeer->peer_len < 6 ||
+ meshpeer->peer_len > 10)
return 1;
- switch (meshpeer->peer_subtype) {
+ switch (subtype) {
case IEEE80211_MESH_PEER_LINK_OPEN:
- if (meshpeer->peer_len != 3)
+ if (meshpeer->peer_len != 6)
return 1;
break;
case IEEE80211_MESH_PEER_LINK_CONFIRM:
- if (meshpeer->peer_len != 5)
+ if (meshpeer->peer_len != 8)
return 1;
break;
case IEEE80211_MESH_PEER_LINK_CLOSE:
- if (meshpeer->peer_len < 5)
+ if (meshpeer->peer_len < 8)
return 1;
- if (meshpeer->peer_len == 5 && meshpeer->peer_linkid != 0)
+ if (meshpeer->peer_len == 8 && meshpeer->peer_linkid != 0)
return 1;
if (meshpeer->peer_rcode == 0)
return 1;
@@ -2449,53 +2426,40 @@ ieee80211_add_meshconf(uint8_t *frm, struct ieee80211vap *vap)
}
/*
- * Add a Mesh Peer Protocol IE to a frame.
- * XXX: needs to grow support for Abbreviated Handshake
- */
-uint8_t *
-ieee80211_add_meshpeerver(uint8_t *frm, struct ieee80211vap *vap)
-{
- static struct ieee80211_meshpeerver_ie ie = {
- .peerver_ie = IEEE80211_ELEMID_MESHPEERVER,
- .peerver_len = 4,
- .peerver_proto = IEEE80211_MESHPEERVER_PEER,
- };
-
- KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap"));
-
- memcpy(frm, &ie, sizeof(ie));
- return frm + sizeof(ie);
-}
-
-/*
* Add a Mesh Peer Management IE to a frame.
*/
uint8_t *
ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid,
uint16_t peerid, uint16_t reason)
{
+ /* XXX change for AH */
+ static const uint8_t meshpeerproto[4] = IEEE80211_MESH_PEER_PROTO;
+
KASSERT(localid != 0, ("localid == 0"));
*frm++ = IEEE80211_ELEMID_MESHPEER;
switch (subtype) {
case IEEE80211_MESH_PEER_LINK_OPEN:
- *frm++ = 3; /* length */
- *frm++ = subtype;
+ *frm++ = 6; /* length */
+ memcpy(frm, meshpeerproto, 4);
+ frm += 4;
ADDSHORT(frm, localid); /* local ID */
break;
case IEEE80211_MESH_PEER_LINK_CONFIRM:
KASSERT(peerid != 0, ("sending peer confirm without peer id"));
- *frm++ = 5; /* length */
- *frm++ = subtype;
+ *frm++ = 8; /* length */
+ memcpy(frm, meshpeerproto, 4);
+ frm += 4;
ADDSHORT(frm, localid); /* local ID */
ADDSHORT(frm, peerid); /* peer ID */
break;
case IEEE80211_MESH_PEER_LINK_CLOSE:
if (peerid)
- *frm++ = 7; /* length */
+ *frm++ = 10; /* length */
else
- *frm++ = 5; /* length */
- *frm++ = subtype;
+ *frm++ = 8; /* length */
+ memcpy(frm, meshpeerproto, 4);
+ frm += 4;
ADDSHORT(frm, localid); /* local ID */
if (peerid)
ADDSHORT(frm, peerid); /* peer ID */
diff --git a/sys/net80211/ieee80211_mesh.h b/sys/net80211/ieee80211_mesh.h
index b02c257..e3ce79a 100644
--- a/sys/net80211/ieee80211_mesh.h
+++ b/sys/net80211/ieee80211_mesh.h
@@ -34,7 +34,7 @@
#define IEEE80211_MESH_DEFAULT_TTL 31
/*
- * NB: all structures are__packed so sizeof works on arm, et. al.
+ * NB: all structures are __packed so sizeof works on arm, et. al.
*/
/*
* 802.11s Information Elements.
@@ -116,28 +116,11 @@ struct ieee80211_meshcngst_ie {
AC_BE, AC_VI, AC_VO */
} __packed;
-/* Peer Version */
-struct ieee80211_meshpeerver_ie {
- uint8_t peerver_ie; /* IEEE80211_ELEMID_MESHPEERVER */
- uint8_t peerver_len;
- uint8_t peerver_proto[4];
-} __packed;
-/* Mesh Peering Management Protocol */
-#define IEEE80211_MESHPEERVER_PEER_OUI 0x00, 0x0f, 0xac
-#define IEEE80211_MESHPEERVER_PEER_VALUE 0x2a
-#define IEEE80211_MESHPEERVER_PEER { IEEE80211_MESHPEERVER_PEER_OUI, \
- IEEE80211_MESHPEERVER_PEER_VALUE }
-/* Abbreviated Handshake Protocol */
-#define IEEE80211_MESHPEERVER_AH_OUI 0x00, 0x0f, 0xac
-#define IEEE80211_MESHPEERVER_AH_VALUE 0x2b
-#define IEEE80211_MESHPEERVER_AH { IEEE80211_MESHPEERVER_AH_OUI, \
- IEEE80211_MESHPEERVER_AH_VALUE }
-
/* Peer Link Management */
struct ieee80211_meshpeer_ie {
uint8_t peer_ie; /* IEEE80211_ELEMID_MESHPEER */
uint8_t peer_len;
- uint8_t peer_subtype;
+ uint8_t peer_proto[4]; /* Peer Management Protocol */
uint16_t peer_llinkid; /* Local Link ID */
uint16_t peer_linkid; /* Peer Link ID */
uint16_t peer_rcode;
@@ -150,6 +133,16 @@ enum {
/* values 3-255 are reserved */
};
+/* Mesh Peering Management Protocol */
+#define IEEE80211_MESH_PEER_PROTO_OUI 0x00, 0x0f, 0xac
+#define IEEE80211_MESH_PEER_PROTO_VALUE 0x2a
+#define IEEE80211_MESH_PEER_PROTO { IEEE80211_MESH_PEER_PROTO_OUI, \
+ IEEE80211_MESH_PEER_PROTO_VALUE }
+/* Abbreviated Handshake Protocol */
+#define IEEE80211_MESH_PEER_PROTO_AH_OUI 0x00, 0x0f, 0xac
+#define IEEE80211_MESH_PEER_PROTO_AH_VALUE 0x2b
+#define IEEE80211_MESH_PEER_PROTO_AH { IEEE80211_MESH_PEER_PROTO_AH_OUI, \
+ IEEE80211_MESH_PEER_PROTO_AH_VALUE }
#ifdef notyet
/* Mesh Channel Switch Annoucement */
struct ieee80211_meshcsa_ie {
@@ -256,11 +249,15 @@ struct ieee80211_meshprep_ie {
struct ieee80211_meshperr_ie {
uint8_t perr_ie; /* IEEE80211_ELEMID_MESHPERR */
uint8_t perr_len;
- uint8_t perr_mode; /* NB: reserved */
+ uint8_t perr_ttl;
uint8_t perr_ndests; /* Number of Destinations */
struct {
+ uint8_t dest_flags;
+#define IEEE80211_MESHPERR_DFLAGS_USN 0x01
+#define IEEE80211_MESHPERR_DFLAGS_RC 0x02
uint8_t dest_addr[IEEE80211_ADDR_LEN];
uint32_t dest_seq; /* HWMP Sequence Number */
+ uint16_t dest_rcode;
} __packed perr_dests[1]; /* NB: variable size */
} __packed;
@@ -310,14 +307,11 @@ enum {
};
/*
- * Mesh Path Selection Action codes.
+ * Mesh Path Selection Action code.
*/
enum {
- IEEE80211_ACTION_MESHPATH_REQ = 0,
- IEEE80211_ACTION_MESHPATH_REP = 1,
- IEEE80211_ACTION_MESHPATH_ERR = 2,
- IEEE80211_ACTION_MESHPATH_RANN = 3,
- /* 4-255 reserved */
+ IEEE80211_ACTION_MESHPATH_SEL = 0,
+ /* 1-255 reserved */
};
/*
@@ -479,7 +473,6 @@ int ieee80211_mesh_register_proto_path(const
int ieee80211_mesh_register_proto_metric(const
struct ieee80211_mesh_proto_metric *);
-uint8_t * ieee80211_add_meshpeerver(uint8_t *, struct ieee80211vap *);
uint8_t * ieee80211_add_meshid(uint8_t *, struct ieee80211vap *);
uint8_t * ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);
uint8_t * ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t,
diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
index e855093..2ef6d3a 100644
--- a/sys/netinet/in_mcast.c
+++ b/sys/netinet/in_mcast.c
@@ -2427,8 +2427,10 @@ inp_set_source_filters(struct inpcb *inp, struct sockopt *sopt)
if (error)
return (error);
- if (msfr.msfr_nsrcs > in_mcast_maxsocksrc ||
- (msfr.msfr_fmode != MCAST_EXCLUDE &&
+ if (msfr.msfr_nsrcs > in_mcast_maxsocksrc)
+ return (ENOBUFS);
+
+ if ((msfr.msfr_fmode != MCAST_EXCLUDE &&
msfr.msfr_fmode != MCAST_INCLUDE))
return (EINVAL);
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index f1f5ade..2bc6ca9 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -150,39 +150,42 @@ struct protosw inetsw[] = {
},
#ifdef SCTP
{
- .pr_type = SOCK_DGRAM,
- .pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_SCTP,
- .pr_flags = PR_WANTRCVD,
- .pr_input = sctp_input,
- .pr_ctlinput = sctp_ctlinput,
- .pr_ctloutput = sctp_ctloutput,
- .pr_init = sctp_init,
- .pr_drain = sctp_drain,
- .pr_usrreqs = &sctp_usrreqs
+ .pr_type = SOCK_DGRAM,
+ .pr_domain = &inetdomain,
+ .pr_protocol = IPPROTO_SCTP,
+ .pr_flags = PR_WANTRCVD,
+ .pr_input = sctp_input,
+ .pr_ctlinput = sctp_ctlinput,
+ .pr_ctloutput = sctp_ctloutput,
+ .pr_init = sctp_init,
+#ifdef VIMAGE
+ .pr_destroy = sctp_finish,
+#endif
+ .pr_drain = sctp_drain,
+ .pr_usrreqs = &sctp_usrreqs
},
{
- .pr_type = SOCK_SEQPACKET,
- .pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_SCTP,
- .pr_flags = PR_WANTRCVD,
- .pr_input = sctp_input,
- .pr_ctlinput = sctp_ctlinput,
- .pr_ctloutput = sctp_ctloutput,
- .pr_drain = sctp_drain,
- .pr_usrreqs = &sctp_usrreqs
+ .pr_type = SOCK_SEQPACKET,
+ .pr_domain = &inetdomain,
+ .pr_protocol = IPPROTO_SCTP,
+ .pr_flags = PR_WANTRCVD,
+ .pr_input = sctp_input,
+ .pr_ctlinput = sctp_ctlinput,
+ .pr_ctloutput = sctp_ctloutput,
+ .pr_drain = sctp_drain,
+ .pr_usrreqs = &sctp_usrreqs
},
{
- .pr_type = SOCK_STREAM,
- .pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_SCTP,
- .pr_flags = PR_WANTRCVD,
- .pr_input = sctp_input,
- .pr_ctlinput = sctp_ctlinput,
- .pr_ctloutput = sctp_ctloutput,
- .pr_drain = sctp_drain,
- .pr_usrreqs = &sctp_usrreqs
+ .pr_type = SOCK_STREAM,
+ .pr_domain = &inetdomain,
+ .pr_protocol = IPPROTO_SCTP,
+ .pr_flags = PR_WANTRCVD,
+ .pr_input = sctp_input,
+ .pr_ctlinput = sctp_ctlinput,
+ .pr_ctloutput = sctp_ctloutput,
+ .pr_drain = sctp_drain,
+ .pr_usrreqs = &sctp_usrreqs
},
#endif /* SCTP */
{
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index c38c344..404b5ad 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -881,7 +881,7 @@ send_reply:
/* we probably don't need these operations */
(void)sa6_recoverscope(from6);
sa6_embedscope(from6,
- MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
+ MODULE_GLOBAL(ip6_use_defzone));
break;
}
diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c
index 792a720..6a8dfc9 100644
--- a/sys/netinet/sctp_bsd_addr.c
+++ b/sys/netinet/sctp_bsd_addr.c
@@ -89,6 +89,7 @@ sctp_wakeup_iterator(void)
static void
sctp_iterator_thread(void *v)
{
+ CURVNET_SET((struct vnet *)v);
SCTP_IPI_ITERATOR_WQ_LOCK();
SCTP_BASE_INFO(iterator_running) = 0;
while (1) {
@@ -100,6 +101,7 @@ sctp_iterator_thread(void *v)
}
sctp_iterator_worker();
}
+ CURVNET_RESTORE();
}
void
@@ -108,7 +110,7 @@ sctp_startup_iterator(void)
int ret;
ret = kproc_create(sctp_iterator_thread,
- (void *)NULL,
+ (void *)curvnet,
&SCTP_BASE_INFO(thread_proc),
RFPROC,
SCTP_KTHREAD_PAGES,
@@ -126,7 +128,7 @@ sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
ifa6 = (struct in6_ifaddr *)ifa->ifa;
ifa->flags = ifa6->ia6_flags;
- if (!MODULE_GLOBAL(MOD_INET6, ip6_use_deprecated)) {
+ if (!MODULE_GLOBAL(ip6_use_deprecated)) {
if (ifa->flags &
IN6_IFF_DEPRECATED) {
ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
@@ -206,7 +208,8 @@ sctp_init_ifns_for_vrf(int vrfid)
struct sctp_ifa *sctp_ifa;
uint32_t ifa_flags;
- TAILQ_FOREACH(ifn, &MODULE_GLOBAL(MOD_NET, ifnet), if_list) {
+ IFNET_RLOCK();
+ TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
IF_ADDR_LOCK(ifn);
TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
if (ifa->ifa_addr == NULL) {
@@ -251,6 +254,7 @@ sctp_init_ifns_for_vrf(int vrfid)
}
IF_ADDR_UNLOCK(ifn);
}
+ IFNET_RUNLOCK();
}
void
@@ -336,7 +340,8 @@ void
struct ifnet *ifn;
struct ifaddr *ifa;
- TAILQ_FOREACH(ifn, &MODULE_GLOBAL(MOD_NET, ifnet), if_list) {
+ IFNET_RLOCK();
+ TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
if (!(*pred) (ifn)) {
continue;
}
@@ -344,6 +349,7 @@ void
sctp_addr_change(ifa, add ? RTM_ADD : RTM_DELETE);
}
}
+ IFNET_RUNLOCK();
}
struct mbuf *
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 4a91626..e59e788 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -5873,7 +5873,7 @@ sctp_skip_csum_4:
* idea, so I will leave it in place.
*/
if (inp && ipsec4_in_reject(m, &inp->ip_inp.inp)) {
- MODULE_GLOBAL(MOD_IPSEC, ipsec4stat).in_polvio++;
+ MODULE_GLOBAL(ipsec4stat).in_polvio++;
SCTP_STAT_INCR(sctps_hdrops);
goto bad;
}
diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h
index d018790..f0cca72 100644
--- a/sys/netinet/sctp_os_bsd.h
+++ b/sys/netinet/sctp_os_bsd.h
@@ -78,9 +78,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_icmp.h>
#include <netinet/icmp_var.h>
-#ifdef VIMAGE
-#error "SCTP is not yet compatible with VIMAGE."
-#endif
+#include <net/vnet.h>
#ifdef IPSEC
#include <netipsec/ipsec.h>
@@ -137,25 +135,21 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
#define SCTP_CTR6 CTR6
#endif
-#define SCTP_BASE_INFO(__m) system_base_info.sctppcbinfo.__m
-#define SCTP_BASE_STATS system_base_info.sctpstat
-#define SCTP_BASE_STAT(__m) system_base_info.sctpstat.__m
-#define SCTP_BASE_SYSCTL(__m) system_base_info.sctpsysctl.__m
-#define SCTP_BASE_VAR(__m) system_base_info.__m
-
/*
* Macros to expand out globals defined by various modules
* to either a real global or a virtualized instance of one,
* depending on whether VIMAGE is defined.
*/
-/* first define modules that supply us information */
-#define MOD_NET net
-#define MOD_INET inet
-#define MOD_INET6 inet6
-#define MOD_IPSEC ipsec
-
/* then define the macro(s) that hook into the vimage macros */
-#define MODULE_GLOBAL(__MODULE, __SYMBOL) V_ ## __SYMBOL
+#define MODULE_GLOBAL(__SYMBOL) V_##__SYMBOL
+
+#define V_system_base_info VNET(system_base_info)
+#define SCTP_BASE_INFO(__m) V_system_base_info.sctppcbinfo.__m
+#define SCTP_BASE_STATS V_system_base_info.sctpstat
+#define SCTP_BASE_STATS_SYSCTL VNET_NAME(system_base_info.sctpstat)
+#define SCTP_BASE_STAT(__m) V_system_base_info.sctpstat.__m
+#define SCTP_BASE_SYSCTL(__m) VNET_NAME(system_base_info.sctpsysctl.__m)
+#define SCTP_BASE_VAR(__m) V_system_base_info.__m
/*
*
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 1e768fc..b9750b9 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -3829,7 +3829,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
sin6 = &tmp;
/* KAME hack: embed scopeid */
- if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
+ if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
return (EINVAL);
}
@@ -3883,7 +3883,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
if (net->src_addr_selected == 0) {
sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
/* KAME hack: embed scopeid */
- if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
+ if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
return (EINVAL);
}
@@ -3906,7 +3906,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
} else {
sin6 = (struct sockaddr_in6 *)&ro->ro_dst;
/* KAME hack: embed scopeid */
- if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
+ if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
return (EINVAL);
}
@@ -5143,7 +5143,7 @@ do_a_abort:
*/
(void)sa6_recoverscope(sin6);
stc.scope_id = sin6->sin6_scope_id;
- sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
+ sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
stc.loopback_scope = 1;
stc.local_scope = 0;
stc.site_scope = 1;
@@ -5179,7 +5179,7 @@ do_a_abort:
*/
(void)sa6_recoverscope(sin6);
stc.scope_id = sin6->sin6_scope_id;
- sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
+ sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
} else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
/*
* If the new destination is
@@ -10768,7 +10768,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
/* Fill in the IPv6 header for the ABORT */
ip6_out->ip6_flow = ip6->ip6_flow;
- ip6_out->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim);
+ ip6_out->ip6_hlim = MODULE_GLOBAL(ip6_defhlim);
if (port) {
ip6_out->ip6_nxt = IPPROTO_UDP;
} else {
@@ -11787,7 +11787,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
/* Fill in the IP6 header for the ABORT */
ip6_out->ip6_flow = ip6->ip6_flow;
- ip6_out->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim);
+ ip6_out->ip6_hlim = MODULE_GLOBAL(ip6_defhlim);
if (port) {
ip6_out->ip6_nxt = IPPROTO_UDP;
} else {
@@ -12014,7 +12014,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
/* Fill in the IP6 header for the ABORT */
ip6_out->ip6_flow = ip6->ip6_flow;
- ip6_out->ip6_hlim = MODULE_GLOBAL(MOD_INET6, ip6_defhlim);
+ ip6_out->ip6_hlim = MODULE_GLOBAL(ip6_defhlim);
if (port) {
ip6_out->ip6_nxt = IPPROTO_UDP;
} else {
@@ -12384,8 +12384,8 @@ sctp_lower_sosend(struct socket *so,
t_inp = inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == NULL) {
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EFAULT);
- error = EFAULT;
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+ error = EINVAL;
if (i_pak) {
SCTP_RELEASE_PKT(i_pak);
}
@@ -12432,8 +12432,8 @@ sctp_lower_sosend(struct socket *so,
if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
(inp->sctp_socket->so_qlimit)) {
/* The listener can NOT send */
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EFAULT);
- error = EFAULT;
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
+ error = ENOTCONN;
goto out_unlocked;
}
if ((use_rcvinfo) && srcv) {
@@ -12566,8 +12566,8 @@ sctp_lower_sosend(struct socket *so,
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
/* Should I really unlock ? */
- SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EFAULT);
- error = EFAULT;
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+ error = EINVAL;
goto out_unlocked;
}
@@ -12596,6 +12596,12 @@ sctp_lower_sosend(struct socket *so,
}
}
if (stcb == NULL) {
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
+ (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
+ SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
+ error = ENOTCONN;
+ goto out_unlocked;
+ }
if (addr == NULL) {
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, ENOENT);
error = ENOENT;
@@ -13759,7 +13765,7 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro)
return (0);
/* get prefix entry of address */
- LIST_FOREACH(pfx, &MODULE_GLOBAL(MOD_INET6, nd_prefix), ndpr_entry) {
+ LIST_FOREACH(pfx, &MODULE_GLOBAL(nd_prefix), ndpr_entry) {
if (pfx->ndpr_stateflags & NDPRF_DETACHED)
continue;
if (IN6_ARE_MASKED_ADDR_EQUAL(&pfx->ndpr_prefix.sin6_addr,
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 0d1f1e0..21cd889 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -48,7 +48,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/udp.h>
-struct sctp_base_info system_base_info;
+VNET_DEFINE(struct sctp_base_info, system_base_info);
/* FIX: we don't handle multiple link local scopes */
/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
@@ -59,11 +59,11 @@ SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
struct sockaddr_in6 tmp_a, tmp_b;
memcpy(&tmp_a, a, sizeof(struct sockaddr_in6));
- if (sa6_embedscope(&tmp_a, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
+ if (sa6_embedscope(&tmp_a, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
return 0;
}
memcpy(&tmp_b, b, sizeof(struct sockaddr_in6));
- if (sa6_embedscope(&tmp_b, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
+ if (sa6_embedscope(&tmp_b, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
return 0;
}
return (IN6_ARE_ADDR_EQUAL(&tmp_a.sin6_addr, &tmp_b.sin6_addr));
@@ -2008,7 +2008,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
/* Get the scopes in properly to the sin6 addr's */
/* we probably don't need these operations */
(void)sa6_recoverscope(from6);
- sa6_embedscope(from6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
+ sa6_embedscope(from6, MODULE_GLOBAL(ip6_use_defzone));
break;
}
#endif
@@ -2049,7 +2049,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
/* Get the scopes in properly to the sin6 addr's */
/* we probably don't need these operations */
(void)sa6_recoverscope(to6);
- sa6_embedscope(to6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
+ sa6_embedscope(to6, MODULE_GLOBAL(ip6_use_defzone));
break;
}
#endif
@@ -2316,7 +2316,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
}
#endif /* IPSEC */
SCTP_INCR_EP_COUNT();
- inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl);
+ inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
SCTP_INP_INFO_WUNLOCK();
so->so_pcb = (caddr_t)inp;
@@ -2688,7 +2688,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
bindall = 0;
/* KAME hack: embed scopeid */
- if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
+ if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
return (EINVAL);
}
@@ -2814,8 +2814,8 @@ continue_anyway:
int done;
if (ip_inp->inp_flags & INP_HIGHPORT) {
- first = MODULE_GLOBAL(MOD_INET, ipport_hifirstauto);
- last = MODULE_GLOBAL(MOD_INET, ipport_hilastauto);
+ first = MODULE_GLOBAL(ipport_hifirstauto);
+ last = MODULE_GLOBAL(ipport_hilastauto);
} else if (ip_inp->inp_flags & INP_LOWPORT) {
if (p && (error =
priv_check(p, PRIV_NETINET_RESERVEDPORT)
@@ -2826,11 +2826,11 @@ continue_anyway:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
return (error);
}
- first = MODULE_GLOBAL(MOD_INET, ipport_lowfirstauto);
- last = MODULE_GLOBAL(MOD_INET, ipport_lowlastauto);
+ first = MODULE_GLOBAL(ipport_lowfirstauto);
+ last = MODULE_GLOBAL(ipport_lowlastauto);
} else {
- first = MODULE_GLOBAL(MOD_INET, ipport_firstauto);
- last = MODULE_GLOBAL(MOD_INET, ipport_lastauto);
+ first = MODULE_GLOBAL(ipport_firstauto);
+ last = MODULE_GLOBAL(ipport_lastauto);
}
if (first > last) {
uint16_t temp;
@@ -3756,7 +3756,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
- (void)sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
+ (void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
sin6->sin6_scope_id = 0;
}
#endif
@@ -6422,10 +6422,6 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
/* We look for anything larger than the cum-ack + 1 */
- SCTP_STAT_INCR(sctps_protocol_drain_calls);
- if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
- return;
- }
asoc = &stcb->asoc;
if (asoc->cumulative_tsn == asoc->highest_tsn_inside_map) {
/* none we can reneg on. */
@@ -6588,22 +6584,37 @@ sctp_drain()
* is LOW on MBUF's and needs help. This is where reneging will
* occur. We really hope this does NOT happen!
*/
- struct sctp_inpcb *inp;
- struct sctp_tcb *stcb;
+ VNET_ITERATOR_DECL(vnet_iter);
+ VNET_LIST_RLOCK_NOSLEEP();
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET(vnet_iter);
+ struct sctp_inpcb *inp;
+ struct sctp_tcb *stcb;
- SCTP_INP_INFO_RLOCK();
- LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
- /* For each endpoint */
- SCTP_INP_RLOCK(inp);
- LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
- /* For each association */
- SCTP_TCB_LOCK(stcb);
- sctp_drain_mbufs(inp, stcb);
- SCTP_TCB_UNLOCK(stcb);
+ SCTP_STAT_INCR(sctps_protocol_drain_calls);
+ if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
+#ifdef VIMAGE
+ continue;
+#else
+ return;
+#endif
}
- SCTP_INP_RUNLOCK(inp);
+ SCTP_INP_INFO_RLOCK();
+ LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
+ /* For each endpoint */
+ SCTP_INP_RLOCK(inp);
+ LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
+ /* For each association */
+ SCTP_TCB_LOCK(stcb);
+ sctp_drain_mbufs(inp, stcb);
+ SCTP_TCB_UNLOCK(stcb);
+ }
+ SCTP_INP_RUNLOCK(inp);
+ }
+ SCTP_INP_INFO_RUNLOCK();
+ CURVNET_RESTORE();
}
- SCTP_INP_INFO_RUNLOCK();
+ VNET_LIST_RUNLOCK_NOSLEEP();
}
/*
diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
index 684ed5a..d9e1db6 100644
--- a/sys/netinet/sctp_pcb.h
+++ b/sys/netinet/sctp_pcb.h
@@ -462,7 +462,7 @@ struct sctp_tcb {
* goes with the base info. sctp_pcb.c has
* the real definition.
*/
-extern struct sctp_base_info system_base_info;
+VNET_DECLARE(struct sctp_base_info, system_base_info);
#ifdef INET6
int SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b);
diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h
index 59725f5..595c37c 100644
--- a/sys/netinet/sctp_structs.h
+++ b/sys/netinet/sctp_structs.h
@@ -51,6 +51,7 @@ struct sctp_timer {
void *ep;
void *tcb;
void *net;
+ void *vnet;
/* for sanity checking */
void *self;
diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
index b5c5f6c..ceb4622 100644
--- a/sys/netinet/sctp_sysctl.c
+++ b/sys/netinet/sctp_sysctl.c
@@ -930,7 +930,7 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, output_unlocked, CTLTYPE_INT | CTLFLAG_RW,
#endif
SYSCTL_STRUCT(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_RW,
- &SCTP_BASE_STATS, sctpstat,
+ &SCTP_BASE_STATS_SYSCTL, sctpstat,
"SCTP statistics (struct sctp_stat)");
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_RD,
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index b40ef50..3344018 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -1773,7 +1773,7 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
/* KAME hack: embed scopeid */
- (void)sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
+ (void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
}
#endif
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 4442f11..a8ea998 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -544,7 +544,7 @@ sctp_attach(struct socket *so, int proto, struct thread *p)
inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6; /* I'm not v6! */
ip_inp = &inp->ip_inp.inp;
ip_inp->inp_vflag |= INP_IPV4;
- ip_inp->inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl);
+ ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
#ifdef IPSEC
error = ipsec_init_policy(so, &ip_inp->inp_sp);
#ifdef SCTP_LOG_CLOSING
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index c7bdfb5..94dea3f 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -1446,6 +1446,7 @@ sctp_timeout_handler(void *t)
inp = (struct sctp_inpcb *)tmr->ep;
stcb = (struct sctp_tcb *)tmr->tcb;
net = (struct sctp_nets *)tmr->net;
+ CURVNET_SET((struct vnet *)tmr->vnet);
did_output = 1;
#ifdef SCTP_AUDITING_ENABLED
@@ -1459,6 +1460,7 @@ sctp_timeout_handler(void *t)
* SCTP_PRINTF("Stale SCTP timer fired (%p), ignoring...\n",
* tmr);
*/
+ CURVNET_RESTORE();
return;
}
tmr->stopped_from = 0xa001;
@@ -1467,10 +1469,12 @@ sctp_timeout_handler(void *t)
* SCTP_PRINTF("SCTP timer fired with invalid type: 0x%x\n",
* tmr->type);
*/
+ CURVNET_RESTORE();
return;
}
tmr->stopped_from = 0xa002;
if ((tmr->type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL)) {
+ CURVNET_RESTORE();
return;
}
/* if this is an iterator timeout, get the struct and clear inp */
@@ -1494,6 +1498,7 @@ sctp_timeout_handler(void *t)
(tmr->type != SCTP_TIMER_TYPE_ASOCKILL))
) {
SCTP_INP_DECR_REF(inp);
+ CURVNET_RESTORE();
return;
}
}
@@ -1505,6 +1510,7 @@ sctp_timeout_handler(void *t)
if (inp) {
SCTP_INP_DECR_REF(inp);
}
+ CURVNET_RESTORE();
return;
}
}
@@ -1517,6 +1523,7 @@ sctp_timeout_handler(void *t)
if (stcb) {
atomic_add_int(&stcb->asoc.refcnt, -1);
}
+ CURVNET_RESTORE();
return;
}
tmr->stopped_from = 0xa006;
@@ -1531,6 +1538,7 @@ sctp_timeout_handler(void *t)
if (inp) {
SCTP_INP_DECR_REF(inp);
}
+ CURVNET_RESTORE();
return;
}
}
@@ -1903,6 +1911,7 @@ out_decr:
out_no_decr:
SCTPDBG(SCTP_DEBUG_TIMER1, "Timer now complete (type %d)\n",
type);
+ CURVNET_RESTORE();
}
void
@@ -2263,6 +2272,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
tmr->tcb = (void *)stcb;
tmr->net = (void *)net;
tmr->self = (void *)tmr;
+ tmr->vnet = (void *)curvnet;
tmr->ticks = sctp_get_tick_count();
(void)SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr);
return;
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index 9597528..50f5ef8 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -223,7 +223,7 @@ sctp_skip_csum:
*/
if (in6p_ip && (ipsec6_in_reject(m, in6p_ip))) {
/* XXX */
- MODULE_GLOBAL(MOD_IPSEC, ipsec6stat).in_polvio++;
+ MODULE_GLOBAL(ipsec6stat).in_polvio++;
goto bad;
}
#endif /* IPSEC */
@@ -695,7 +695,7 @@ sctp6_attach(struct socket *so, int proto, struct thread *p)
* socket as well, because the socket may be bound to an IPv6
* wildcard address, which may match an IPv4-mapped IPv6 address.
*/
- inp6->inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl);
+ inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
#endif
/*
* Hmm what about the IPSEC stuff that is missing here but in
@@ -859,7 +859,7 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
}
}
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
- if (!MODULE_GLOBAL(MOD_INET6, ip6_v6only)) {
+ if (!MODULE_GLOBAL(ip6_v6only)) {
struct sockaddr_in sin;
/* convert v4-mapped into v4 addr and send */
@@ -990,7 +990,7 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
}
}
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
- if (!MODULE_GLOBAL(MOD_INET6, ip6_v6only)) {
+ if (!MODULE_GLOBAL(ip6_v6only)) {
/* convert v4-mapped into v4 addr */
in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6);
addr = (struct sockaddr *)&ss;
diff --git a/sys/pci/intpm.c b/sys/pci/intpm.c
index 13404c8..1cbe75d 100644
--- a/sys/pci/intpm.c
+++ b/sys/pci/intpm.c
@@ -167,6 +167,12 @@ intsmb_attach(device_t dev)
sc->poll == 0 ? "enabled" : "disabled");
printf("revision %d\n", pci_read_config(dev, PCI_REVID_SMB, 1));
+ if (!sc->poll && intr == PCI_INTR_SMB_SMI) {
+ device_printf(dev,
+ "using polling mode when configured interrupt is SMI\n");
+ sc->poll = 1;
+ }
+
if (sc->poll)
goto no_intr;
diff --git a/sys/powerpc/include/param.h b/sys/powerpc/include/param.h
index 160cd78..6c3edf9 100644
--- a/sys/powerpc/include/param.h
+++ b/sys/powerpc/include/param.h
@@ -86,6 +86,8 @@
#define PAGE_MASK (PAGE_SIZE - 1)
#define NPTEPG (PAGE_SIZE/(sizeof (pt_entry_t)))
+#define MAXPAGESIZES 1 /* maximum number of supported page sizes */
+
#ifndef KSTACK_PAGES
#define KSTACK_PAGES 4 /* includes pcb */
#endif
diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC
index 95be09a..ecf640c 100644
--- a/sys/sparc64/conf/GENERIC
+++ b/sys/sparc64/conf/GENERIC
@@ -68,6 +68,7 @@ options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options P1003_1B_SEMAPHORES # POSIX-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
options AUDIT # Security event auditing
options MAC # TrustedBSD MAC Framework
diff --git a/sys/sparc64/include/param.h b/sys/sparc64/include/param.h
index 90864b0..af026b2 100644
--- a/sys/sparc64/include/param.h
+++ b/sys/sparc64/include/param.h
@@ -109,6 +109,8 @@
#define PAGE_SIZE_MAX PAGE_SIZE_4M
#define PAGE_MASK_MAX PAGE_MASK_4M
+#define MAXPAGESIZES 1 /* maximum number of supported page sizes */
+
#ifndef KSTACK_PAGES
#define KSTACK_PAGES 4 /* pages of kernel stack (with pcb) */
#endif
diff --git a/sys/sun4v/include/param.h b/sys/sun4v/include/param.h
index 069ab54..2ca699e 100644
--- a/sys/sun4v/include/param.h
+++ b/sys/sun4v/include/param.h
@@ -104,6 +104,8 @@
#define PAGE_SIZE_MAX PAGE_SIZE_4M
#define PAGE_MASK_MAX PAGE_MASK_4M
+#define MAXPAGESIZES 1 /* maximum number of supported page sizes */
+
#ifndef KSTACK_PAGES
#define KSTACK_PAGES 4 /* pages of kernel stack (with pcb) */
#endif
diff --git a/sys/sys/event.h b/sys/sys/event.h
index ec76f35..4365e44 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -191,7 +191,7 @@ struct filterops {
int (*f_attach)(struct knote *kn);
void (*f_detach)(struct knote *kn);
int (*f_event)(struct knote *kn, long hint);
- void (*f_touch)(struct knote *kn, struct kevent *kev, long type);
+ void (*f_touch)(struct knote *kn, struct kevent *kev, u_long type);
};
/*
diff --git a/sys/sys/kbio.h b/sys/sys/kbio.h
index 6f82c6d..22b0285 100644
--- a/sys/sys/kbio.h
+++ b/sys/sys/kbio.h
@@ -106,7 +106,7 @@ typedef struct keyboard_repeat keyboard_repeat_t;
#define _KEYMAP_DECLARED
struct keyent_t {
- u_char map[NUM_STATES];
+ u_int map[NUM_STATES];
u_char spcl;
u_char flgs;
#define FLAG_LOCK_O 0
@@ -220,8 +220,9 @@ typedef struct fkeyarg fkeyarg_t;
#define GIO_SCRNMAP _IOR('k', 2, scrmap_t)
#define PIO_SCRNMAP _IOW('k', 3, scrmap_t)
#endif
-#define GIO_KEYMAP _IOR('k', 6, keymap_t)
-#define PIO_KEYMAP _IOW('k', 7, keymap_t)
+/* XXX: Should have keymap_t as an argument, but that's too big for ioctl()! */
+#define GIO_KEYMAP _IO('k', 6)
+#define PIO_KEYMAP _IO('k', 7)
#define GIO_DEADKEYMAP _IOR('k', 8, accentmap_t)
#define PIO_DEADKEYMAP _IOW('k', 9, accentmap_t)
#define GIO_KEYMAPENT _IOWR('k', 10, keyarg_t)
diff --git a/sys/sys/mman.h b/sys/sys/mman.h
index 6a963c9..9b64e89 100644
--- a/sys/sys/mman.h
+++ b/sys/sys/mman.h
@@ -208,6 +208,7 @@ __BEGIN_DECLS
* posix_typed_mem_open().
*/
#if __BSD_VISIBLE
+int getpagesizes(size_t *, int);
int madvise(void *, size_t, int);
int mincore(const void *, size_t, char *);
int minherit(void *, size_t, int);
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 0fb65b0..7bfab29 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 900001 /* Master, propagated to newvers */
+#define __FreeBSD_version 900002 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>
diff --git a/sys/sys/smp.h b/sys/sys/smp.h
index d80b9e4..782ef74 100644
--- a/sys/sys/smp.h
+++ b/sys/sys/smp.h
@@ -120,7 +120,6 @@ void cpu_mp_setmaxid(void);
void cpu_mp_start(void);
void forward_signal(struct thread *);
-void forward_roundrobin(void);
int restart_cpus(cpumask_t);
int stop_cpus(cpumask_t);
int stop_cpus_hard(cpumask_t);
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 96222da..397976f 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -54,6 +54,7 @@ extern int kstack_pages; /* number of kernel stack pages */
extern int nswap; /* size of swap space */
+extern u_long pagesizes[]; /* supported page sizes */
extern long physmem; /* physical memory */
extern long realmem; /* 'real' memory */
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 2f2d90a..dffbf9a 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -614,6 +614,9 @@ int vn_commname(struct vnode *vn, char *buf, u_int buflen);
int vaccess(enum vtype type, mode_t file_mode, uid_t file_uid,
gid_t file_gid, accmode_t accmode, struct ucred *cred,
int *privused);
+int vaccess_acl_nfs4(enum vtype type, uid_t file_uid, gid_t file_gid,
+ struct acl *aclp, accmode_t accmode, struct ucred *cred,
+ int *privused);
int vaccess_acl_posix1e(enum vtype type, uid_t file_uid,
gid_t file_gid, struct acl *acl, accmode_t accmode,
struct ucred *cred, int *privused);
diff --git a/sys/teken/sequences b/sys/teken/sequences
index 8f7bfb4..957665a 100644
--- a/sys/teken/sequences
+++ b/sys/teken/sequences
@@ -104,6 +104,7 @@ C25ADBG Cons25 set adapter background ^[ [ = G r
C25ADFG Cons25 set adapter foreground ^[ [ = F r
C25BLPD Cons25 set bell pitch duration ^[ [ = B r r
C25CURS Cons25 set cursor type ^[ [ = S r
+C25MODE Cons25 set terminal mode ^[ [ = T r
C25VTSW Cons25 switch virtual terminal ^[ [ z r
# VT52 compatibility
diff --git a/sys/teken/teken.c b/sys/teken/teken.c
index da5c056..c928510 100644
--- a/sys/teken/teken.c
+++ b/sys/teken/teken.c
@@ -48,10 +48,6 @@
static FILE *df;
#endif /* __FreeBSD__ && _KERNEL */
-#include "teken.h"
-#include "teken_wcwidth.h"
-#include "teken_scs.h"
-
/* Private flags for t_stateflags. */
#define TS_FIRSTDIGIT 0x01 /* First numeric digit in escape sequence. */
#define TS_INSERT 0x02 /* Insert mode. */
@@ -64,6 +60,10 @@ static FILE *df;
/* Character that blanks a cell. */
#define BLANK ' '
+#include "teken.h"
+#include "teken_wcwidth.h"
+#include "teken_scs.h"
+
static teken_state_t teken_state_init;
/*
diff --git a/sys/teken/teken.h b/sys/teken/teken.h
index 65ee05e..4e73f7b 100644
--- a/sys/teken/teken.h
+++ b/sys/teken/teken.h
@@ -109,7 +109,7 @@ typedef struct {
tf_respond_t *tf_respond;
} teken_funcs_t;
-typedef teken_char_t teken_scs_t(teken_char_t);
+typedef teken_char_t teken_scs_t(teken_t *, teken_char_t);
/*
* Terminal state.
diff --git a/sys/teken/teken_scs.h b/sys/teken/teken_scs.h
index baeb296..5f42aa4 100644
--- a/sys/teken/teken_scs.h
+++ b/sys/teken/teken_scs.h
@@ -58,39 +58,49 @@ static teken_char_t
teken_scs_process(teken_t *t, teken_char_t c)
{
- return (t->t_scs[t->t_curscs](c));
+ return (t->t_scs[t->t_curscs](t, c));
}
/* Unicode points for VT100 box drawing. */
-static const uint16_t teken_boxdrawing[31] = {
+static const uint16_t teken_boxdrawing_unicode[31] = {
0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7
};
+/* CP437 points for VT100 box drawing. */
+static const uint8_t teken_boxdrawing_8bit[31] = {
+ 0x04, 0xb1, 0x48, 0x46, 0x43, 0x4c, 0xf8, 0xf1,
+ 0x4e, 0x56, 0xd9, 0xbf, 0xda, 0xc0, 0xc5, 0xc4,
+ 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xb4, 0xc1, 0xc2,
+ 0xb3, 0xf3, 0xf2, 0xe3, 0xd8, 0x9c, 0xfa,
+};
+
static teken_char_t
-teken_scs_special_graphics(teken_char_t c)
+teken_scs_special_graphics(teken_t *t, teken_char_t c)
{
/* Box drawing. */
if (c >= '`' && c <= '~')
- return (teken_boxdrawing[c - '`']);
+ return (t->t_stateflags & TS_8BIT ?
+ teken_boxdrawing_8bit[c - '`'] :
+ teken_boxdrawing_unicode[c - '`']);
return (c);
}
static teken_char_t
-teken_scs_uk_national(teken_char_t c)
+teken_scs_uk_national(teken_t *t, teken_char_t c)
{
/* Pound sign. */
if (c == '#')
- return (0xa3);
+ return (t->t_stateflags & TS_8BIT ? 0x9c : 0xa3);
return (c);
}
static teken_char_t
-teken_scs_us_ascii(teken_char_t c)
+teken_scs_us_ascii(teken_t *t __unused, teken_char_t c)
{
/* No processing. */
diff --git a/sys/teken/teken_subr.h b/sys/teken/teken_subr.h
index ab3e759..7d8cd0c 100644
--- a/sys/teken/teken_subr.h
+++ b/sys/teken/teken_subr.h
@@ -397,6 +397,11 @@ teken_subr_delete_line(teken_t *t, unsigned int nrows)
{
teken_rect_t tr;
+ /* Ignore if outside scrolling region. */
+ if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin ||
+ t->t_cursor.tp_row >= t->t_scrollreg.ts_end)
+ return;
+
tr.tr_begin.tp_col = 0;
tr.tr_end.tp_row = t->t_scrollreg.ts_end;
tr.tr_end.tp_col = t->t_winsize.tp_col;
@@ -656,6 +661,11 @@ teken_subr_insert_line(teken_t *t, unsigned int nrows)
{
teken_rect_t tr;
+ /* Ignore if outside scrolling region. */
+ if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin ||
+ t->t_cursor.tp_row >= t->t_scrollreg.ts_end)
+ return;
+
tr.tr_begin.tp_row = t->t_cursor.tp_row;
tr.tr_begin.tp_col = 0;
tr.tr_end.tp_col = t->t_winsize.tp_col;
@@ -802,8 +812,9 @@ teken_subr_regular_character(teken_t *t, teken_char_t c)
int width;
if (t->t_stateflags & TS_8BIT) {
- if (!(t->t_stateflags & TS_CONS25) && c <= 0x1B)
+ if (!(t->t_stateflags & TS_CONS25) && (c <= 0x1b || c == 0x7f))
return;
+ c = teken_scs_process(t, c);
width = 1;
} else {
c = teken_scs_process(t, c);
diff --git a/sys/teken/teken_subr_compat.h b/sys/teken/teken_subr_compat.h
index c642af7..088f378 100644
--- a/sys/teken/teken_subr_compat.h
+++ b/sys/teken/teken_subr_compat.h
@@ -87,6 +87,20 @@ teken_subr_cons25_set_bell_pitch_duration(teken_t *t, unsigned int pitch,
(duration & 0xffff));
}
+static void
+teken_subr_cons25_set_terminal_mode(teken_t *t, unsigned int mode)
+{
+
+ switch (mode) {
+ case 0: /* Switch terminal to xterm. */
+ t->t_stateflags &= ~TS_CONS25;
+ break;
+ case 1: /* Switch terminal to cons25. */
+ t->t_stateflags |= TS_CONS25;
+ break;
+ }
+}
+
#if 0
static void
teken_subr_vt52_decid(teken_t *t)
diff --git a/sys/ufs/ufs/ufs_gjournal.c b/sys/ufs/ufs/ufs_gjournal.c
index da0de65..8e35c08 100644
--- a/sys/ufs/ufs/ufs_gjournal.c
+++ b/sys/ufs/ufs/ufs_gjournal.c
@@ -29,8 +29,6 @@ __FBSDID("$FreeBSD$");
#include "opt_ufs.h"
-#ifdef UFS_GJOURNAL
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -137,5 +135,3 @@ ufs_gjournal_close(struct vnode *vp)
return;
ufs_gjournal_modref(vp, -1);
}
-
-#endif /* UFS_GJOURNAL */
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 2b99e36..c8d25ee 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/conf.h>
#include <sys/stat.h>
+#include <sys/sysent.h>
#include <sys/vmmeter.h>
#include <sys/sysctl.h>
@@ -229,7 +230,8 @@ mmap(td, uap)
fp = NULL;
/* make sure mapping fits into numeric range etc */
- if (uap->len == 0 ||
+ if ((uap->len == 0 && !SV_CURPROC_FLAG(SV_AOUT) &&
+ curproc->p_osrel >= 800104) ||
((flags & MAP_ANON) && uap->fd != -1))
return (EINVAL);
OpenPOWER on IntegriCloud