summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2016-05-09 17:39:43 -0300
committerRenato Botelho <renato@netgate.com>2016-05-09 17:39:43 -0300
commit20ab79d9560e0036f834689a67c3035c18e3eb43 (patch)
treeee1296285669938e8ca9f3215719c5e461aab23b /sys
parent394097451eda898069e18b8dc01759b5ec2d19ff (diff)
parent751248c9f444f5d00818a67a793dc0319749f236 (diff)
downloadFreeBSD-src-20ab79d9560e0036f834689a67c3035c18e3eb43.zip
FreeBSD-src-20ab79d9560e0036f834689a67c3035c18e3eb43.tar.gz
Merge remote-tracking branch 'origin/master' into devel-11
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/acpica/acpi_wakecode.S4
-rw-r--r--sys/amd64/amd64/atomic.c2
-rw-r--r--sys/amd64/amd64/exception.S2
-rw-r--r--sys/amd64/amd64/mpboot.S4
-rw-r--r--sys/amd64/amd64/pmap.c22
-rw-r--r--sys/amd64/conf/GENERIC3
-rw-r--r--sys/amd64/conf/NOTES2
-rw-r--r--sys/amd64/include/vmm.h2
-rw-r--r--sys/amd64/linux/linux_locore.s32
-rw-r--r--sys/amd64/linux/linux_machdep.c2
-rw-r--r--sys/amd64/linux32/linux32_machdep.c2
-rw-r--r--sys/amd64/vmm/amd/vmcb.h2
-rw-r--r--sys/amd64/vmm/intel/vtd.c2
-rw-r--r--sys/amd64/vmm/io/vlapic.c2
-rw-r--r--sys/amd64/vmm/vmm_instruction_emul.c2
-rw-r--r--sys/amd64/vmm/vmm_stat.c2
-rw-r--r--sys/arm/allwinner/a10/a10_intc.c10
-rw-r--r--sys/arm/allwinner/a10_ehci.c1
-rw-r--r--sys/arm/allwinner/a10_gpio.c10
-rw-r--r--sys/arm/allwinner/a83t/a83t_padconf.c162
-rw-r--r--sys/arm/allwinner/a83t/a83t_r_padconf.c62
-rw-r--r--sys/arm/allwinner/a83t/files.a83t4
-rw-r--r--sys/arm/allwinner/a83t/std.a83t15
-rw-r--r--sys/arm/allwinner/allwinner_machdep.c24
-rw-r--r--sys/arm/allwinner/allwinner_machdep.h2
-rw-r--r--sys/arm/allwinner/aw_ccu.c133
-rw-r--r--sys/arm/allwinner/aw_mp.c97
-rw-r--r--sys/arm/allwinner/aw_mp.h1
-rw-r--r--sys/arm/allwinner/aw_nmi.c20
-rw-r--r--sys/arm/allwinner/aw_usbphy.c1
-rw-r--r--sys/arm/allwinner/clk/aw_ahbclk.c78
-rw-r--r--sys/arm/allwinner/clk/aw_apbclk.c56
-rw-r--r--sys/arm/allwinner/clk/aw_cpusclk.c320
-rw-r--r--sys/arm/allwinner/clk/aw_gate.c8
-rw-r--r--sys/arm/allwinner/clk/aw_gmacclk.c49
-rw-r--r--sys/arm/allwinner/clk/aw_pll.c27
-rw-r--r--sys/arm/allwinner/clk/aw_usbclk.c21
-rw-r--r--sys/arm/allwinner/files.allwinner2
-rw-r--r--sys/arm/allwinner/if_awg.c1418
-rw-r--r--sys/arm/allwinner/if_awgreg.h181
-rw-r--r--sys/arm/allwinner/std.allwinner1
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_mmc.c2
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_mmc.h2
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c2
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h2
-rw-r--r--sys/arm/arm/cpufunc_asm_arm11.S2
-rw-r--r--sys/arm/arm/exception.S2
-rw-r--r--sys/arm/arm/genassym.c1
-rw-r--r--sys/arm/arm/generic_timer.c10
-rw-r--r--sys/arm/arm/gic.c12
-rw-r--r--sys/arm/arm/machdep.c2
-rw-r--r--sys/arm/arm/mpcore_timer.c4
-rw-r--r--sys/arm/arm/pmap-v4.c6
-rw-r--r--sys/arm/arm/pmap-v6.c4
-rw-r--r--sys/arm/arm/swtch-v4.S2
-rw-r--r--sys/arm/at91/at91_cfata.c2
-rw-r--r--sys/arm/at91/at91_machdep.c2
-rw-r--r--sys/arm/at91/at91_mci.c4
-rw-r--r--sys/arm/at91/at91_reset.S2
-rw-r--r--sys/arm/at91/at91reg.h4
-rw-r--r--sys/arm/at91/at91sam9260.c2
-rw-r--r--sys/arm/at91/if_ate.c12
-rw-r--r--sys/arm/at91/if_atereg.h4
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_audio.c2
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_dma.c4
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_gpio.c208
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_intr.c11
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2836.c7
-rw-r--r--sys/arm/cavium/cns11xx/if_ece.c2
-rw-r--r--sys/arm/conf/ALLWINNER2
-rw-r--r--sys/arm/freescale/imx/imx6_ipu.c2
-rw-r--r--sys/arm/freescale/imx/imx6_ssi.c4
-rw-r--r--sys/arm/freescale/imx/imx_gpio.c12
-rw-r--r--sys/arm/freescale/vybrid/vf_uart.c2
-rw-r--r--sys/arm/mv/mpic.c12
-rw-r--r--sys/arm/mv/mv_common.c2
-rw-r--r--sys/arm/nvidia/tegra_gpio.c42
-rw-r--r--sys/arm/qemu/virt_machdep.c17
-rw-r--r--sys/arm/samsung/exynos/exynos5_usb_phy.c2
-rw-r--r--sys/arm/ti/aintc.c10
-rw-r--r--sys/arm/ti/omap4/omap4_prcm_clks.c2
-rw-r--r--sys/arm/ti/ti_gpio.c164
-rw-r--r--sys/arm/ti/ti_gpio.h2
-rw-r--r--sys/arm/ti/ti_i2c.c4
-rw-r--r--sys/arm/ti/ti_pinmux.c2
-rw-r--r--sys/arm/ti/ti_prcm.c2
-rw-r--r--sys/arm/ti/ti_scm.c2
-rw-r--r--sys/arm/ti/ti_sdma.c24
-rw-r--r--sys/arm/xilinx/zy7_slcr.c2
-rw-r--r--sys/arm/xscale/i8134x/crb_machdep.c2
-rw-r--r--sys/arm/xscale/i8134x/i81342reg.h2
-rw-r--r--sys/arm/xscale/ixp425/avila_machdep.c2
-rw-r--r--sys/arm/xscale/ixp425/cambria_gpio.c2
-rw-r--r--sys/arm/xscale/ixp425/ixp425_npe.c6
-rw-r--r--sys/arm/xscale/ixp425/ixp425_npereg.h2
-rw-r--r--sys/arm/xscale/ixp425/ixp425_qmgr.c2
-rw-r--r--sys/arm/xscale/pxa/pxa_machdep.c2
-rw-r--r--sys/arm64/arm64/gic_v3.c1
-rw-r--r--sys/arm64/arm64/gic_v3_fdt.c1
-rw-r--r--sys/arm64/arm64/gic_v3_its.c9
-rw-r--r--sys/arm64/arm64/gic_v3_var.h2
-rw-r--r--sys/arm64/conf/GENERIC1
-rw-r--r--sys/boot/efi/libefi/efipart.c11
-rw-r--r--sys/cam/cam_periph.c1
-rw-r--r--sys/cam/scsi/scsi_all.c17
-rw-r--r--sys/cam/scsi/scsi_cd.c2
-rw-r--r--sys/cam/scsi/scsi_xpt.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h12
-rw-r--r--sys/cddl/dev/dtrace/mips/dtrace_asm.S23
-rw-r--r--sys/cddl/dev/dtrace/mips/dtrace_subr.c87
-rw-r--r--sys/cddl/dev/fbt/mips/fbt_isa.c165
-rw-r--r--sys/cddl/dev/fbt/mips/fbt_isa.h30
-rw-r--r--sys/compat/linuxkpi/common/src/linux_compat.c2
-rw-r--r--sys/conf/NOTES1
-rw-r--r--sys/conf/files52
-rw-r--r--sys/conf/files.mips6
-rw-r--r--sys/conf/kmod.mk20
-rw-r--r--sys/conf/options6
-rw-r--r--sys/conf/options.arm1
-rw-r--r--sys/ddb/db_examine.c23
-rw-r--r--sys/dev/acpi_support/atk0110.c2
-rw-r--r--sys/dev/acpica/acpi_pcib_acpi.c7
-rw-r--r--sys/dev/acpica/acpi_thermal.c4
-rw-r--r--sys/dev/ahci/ahci_pci.c9
-rw-r--r--sys/dev/asmc/asmc.c6
-rw-r--r--sys/dev/asmc/asmcvar.h28
-rw-r--r--sys/dev/bhnd/bcma/bcma.c14
-rw-r--r--sys/dev/bhnd/bcma/bcma_bhndb.c7
-rw-r--r--sys/dev/bhnd/bcma/bcma_subr.c2
-rw-r--r--sys/dev/bhnd/bcma/bcmavar.h1
-rw-r--r--sys/dev/bhnd/bcmsrom_fmt.h373
-rw-r--r--sys/dev/bhnd/bcmsrom_tbl.h577
-rw-r--r--sys/dev/bhnd/bhnd.c154
-rw-r--r--sys/dev/bhnd/bhnd.h269
-rw-r--r--sys/dev/bhnd/bhnd_bus_if.m204
-rw-r--r--sys/dev/bhnd/bhnd_ids.h3
-rw-r--r--sys/dev/bhnd/bhnd_subr.c87
-rw-r--r--sys/dev/bhnd/bhndb/bhndb.c157
-rw-r--r--sys/dev/bhnd/bhndb/bhndb.h4
-rw-r--r--sys/dev/bhnd/bhndb/bhndb_if.m17
-rw-r--r--sys/dev/bhnd/bhndb/bhndb_pci.c189
-rw-r--r--sys/dev/bhnd/bhndb/bhndb_pci_hwdata.c56
-rw-r--r--sys/dev/bhnd/bhndb/bhndb_pci_sprom.c210
-rw-r--r--sys/dev/bhnd/bhndb/bhndb_pcireg.h18
-rw-r--r--sys/dev/bhnd/bhndb/bhndb_pcivar.h1
-rw-r--r--sys/dev/bhnd/bhndb/bhndb_subr.c21
-rw-r--r--sys/dev/bhnd/cores/chipc/chipc.c329
-rw-r--r--sys/dev/bhnd/cores/chipc/chipcreg.h38
-rw-r--r--sys/dev/bhnd/cores/chipc/chipcvar.h76
-rw-r--r--sys/dev/bhnd/nvram/bhnd_nvram.h41
-rw-r--r--sys/dev/bhnd/nvram/bhnd_nvram_if.m38
-rw-r--r--sys/dev/bhnd/nvram/bhnd_sprom.c572
-rw-r--r--sys/dev/bhnd/nvram/bhnd_spromreg.h63
-rw-r--r--sys/dev/bhnd/nvram/bhnd_spromvar.h58
-rw-r--r--sys/dev/bhnd/nvram/nvram_map1445
-rw-r--r--sys/dev/bhnd/nvram/nvram_subr.c149
-rw-r--r--sys/dev/bhnd/nvram/nvramvar.h128
-rw-r--r--sys/dev/bhnd/siba/siba.c10
-rw-r--r--sys/dev/bhnd/siba/siba_bhndb.c6
-rw-r--r--sys/dev/bhnd/siba/siba_subr.c7
-rw-r--r--sys/dev/bhnd/siba/sibavar.h1
-rw-r--r--[-rwxr-xr-x]sys/dev/bhnd/tools/bus_macro.sh10
-rwxr-xr-xsys/dev/bhnd/tools/nvram_map_gen.awk1162
-rwxr-xr-xsys/dev/bhnd/tools/nvram_map_gen.sh12
-rw-r--r--sys/dev/buslogic/btreg.h2
-rw-r--r--sys/dev/bwn/bwn_mac.c151
-rw-r--r--sys/dev/bwn/if_bwn.c198
-rw-r--r--sys/dev/bwn/if_bwn_debug.h2
-rw-r--r--sys/dev/bwn/if_bwn_pci.c288
-rw-r--r--sys/dev/bwn/if_bwn_pcivar.h93
-rw-r--r--sys/dev/bwn/if_bwnvar.h7
-rw-r--r--sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt4
-rw-r--r--sys/dev/cxgbe/firmware/t5fw_cfg_fpga.txt4
-rw-r--r--sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt4
-rw-r--r--sys/dev/cxgbe/iw_cxgbe/cm.c1
-rw-r--r--sys/dev/cxgbe/offload.h2
-rw-r--r--sys/dev/cxgbe/t4_main.c9
-rw-r--r--sys/dev/cxgbe/tom/t4_cpl_io.c123
-rw-r--r--sys/dev/cxgbe/tom/t4_ddp.c1730
-rw-r--r--sys/dev/cxgbe/tom/t4_listen.c2
-rw-r--r--sys/dev/cxgbe/tom/t4_tom.c36
-rw-r--r--sys/dev/cxgbe/tom/t4_tom.h63
-rw-r--r--sys/dev/e1000/e1000_82571.c2
-rw-r--r--sys/dev/e1000/e1000_mbx.c4
-rw-r--r--sys/dev/e1000/if_em.c8
-rw-r--r--sys/dev/e1000/if_igb.c7
-rw-r--r--sys/dev/e1000/if_igb.h4
-rw-r--r--sys/dev/e1000/if_lem.c4
-rw-r--r--sys/dev/esp/esp_pci.c2
-rw-r--r--sys/dev/fdc/fdc_acpi.c5
-rw-r--r--sys/dev/fdc/fdcvar.h2
-rw-r--r--sys/dev/hptiop/hptiop.c4
-rw-r--r--sys/dev/ioat/ioat.c169
-rw-r--r--sys/dev/ioat/ioat.h57
-rw-r--r--sys/dev/ioat/ioat_internal.h88
-rw-r--r--sys/dev/iscsi/icl_soft.c4
-rw-r--r--sys/dev/iwn/if_iwn.c22
-rw-r--r--sys/dev/iwn/if_iwnvar.h1
-rw-r--r--sys/dev/ixgbe/if_ixv.c6
-rw-r--r--sys/dev/ixgbe/ixgbe_api.c2
-rw-r--r--sys/dev/ixgbe/ixgbe_common.c2
-rw-r--r--sys/dev/ixgbe/ixgbe_mbx.c4
-rw-r--r--sys/dev/ixgbe/ixgbe_type.h4
-rw-r--r--sys/dev/lmc/if_lmc.h2
-rw-r--r--sys/dev/mpr/mpi/mpi2.h79
-rw-r--r--sys/dev/mpr/mpi/mpi2_cnfg.h181
-rw-r--r--sys/dev/mpr/mpi/mpi2_hbd.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_history.txt153
-rw-r--r--sys/dev/mpr/mpi/mpi2_init.h44
-rw-r--r--sys/dev/mpr/mpi/mpi2_ioc.h158
-rw-r--r--sys/dev/mpr/mpi/mpi2_ra.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_raid.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_sas.h13
-rw-r--r--sys/dev/mpr/mpi/mpi2_targ.h21
-rw-r--r--sys/dev/mpr/mpi/mpi2_tool.h10
-rw-r--r--sys/dev/mpr/mpi/mpi2_type.h8
-rw-r--r--sys/dev/mpr/mpr.c89
-rw-r--r--sys/dev/mpr/mpr_config.c2
-rw-r--r--sys/dev/mpr/mpr_ioctl.h2
-rw-r--r--sys/dev/mpr/mpr_mapping.c2
-rw-r--r--sys/dev/mpr/mpr_mapping.h2
-rw-r--r--sys/dev/mpr/mpr_pci.c12
-rw-r--r--sys/dev/mpr/mpr_sas.c153
-rw-r--r--sys/dev/mpr/mpr_sas.h2
-rw-r--r--sys/dev/mpr/mpr_sas_lsi.c61
-rw-r--r--sys/dev/mpr/mpr_table.c5
-rw-r--r--sys/dev/mpr/mpr_user.c59
-rw-r--r--sys/dev/mpr/mprvar.h26
-rw-r--r--sys/dev/mps/mps_sas.c17
-rw-r--r--sys/dev/nvram2env/nvram2env.c2
-rw-r--r--sys/dev/otus/if_otus.c3
-rw-r--r--sys/dev/pci/pci.c13
-rw-r--r--sys/dev/pci/pci_iov.c34
-rw-r--r--sys/dev/pci/pci_iov_private.h6
-rw-r--r--sys/dev/pci/pci_pci.c530
-rw-r--r--sys/dev/pci/pcib_private.h20
-rw-r--r--sys/dev/pci/pcireg.h8
-rw-r--r--sys/dev/pms/freebsd/driver/common/lxcommon.h4
-rw-r--r--sys/dev/pms/freebsd/driver/common/osenv.h10
-rw-r--r--sys/dev/pms/freebsd/driver/ini/src/agtiapi.c4
-rw-r--r--sys/dev/pms/freebsd/driver/ini/src/osapi.c4
-rw-r--r--sys/dev/sfxge/common/efsys.h18
-rw-r--r--sys/dev/sfxge/common/efx.h14
-rw-r--r--sys/dev/sfxge/common/efx_check.h41
-rw-r--r--sys/dev/sfxge/common/efx_impl.h6
-rw-r--r--sys/dev/sfxge/common/efx_nic.c36
-rw-r--r--sys/dev/sfxge/common/siena_impl.h8
-rw-r--r--sys/dev/sfxge/common/siena_nic.c22
-rw-r--r--sys/dev/siba/siba_core.c53
-rw-r--r--sys/dev/siba/sibareg.h7
-rw-r--r--sys/dev/siba/sibavar.h35
-rw-r--r--sys/dev/sound/pci/hda/hdac.c2
-rw-r--r--sys/dev/sound/pci/hda/hdac.h2
-rw-r--r--sys/dev/usb/controller/xhci_pci.c2
-rw-r--r--sys/dev/usb/usb_device.c4
-rw-r--r--sys/dev/usb/wlan/if_run.c8
-rw-r--r--sys/dev/usb/wlan/if_urtw.c10
-rw-r--r--sys/dev/wi/if_wi.c2
-rw-r--r--sys/dev/xen/blkback/blkback.c12
-rw-r--r--sys/dev/xen/privcmd/privcmd.c96
-rw-r--r--sys/dev/xen/timer/timer.c7
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c4
-rw-r--r--sys/fs/nfsserver/nfs_nfsdkrpc.c6
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsocket.c7
-rw-r--r--sys/geom/uzip/g_uzip.c12
-rw-r--r--sys/i386/conf/GENERIC1
-rw-r--r--sys/isa/isa_common.h2
-rw-r--r--sys/isa/pnp.c2
-rw-r--r--sys/isa/pnpparse.c2
-rw-r--r--sys/kern/kern_descrip.c2
-rw-r--r--sys/kern/subr_bus.c2
-rw-r--r--sys/kern/subr_hash.c22
-rw-r--r--sys/kern/subr_intr.c60
-rw-r--r--sys/kern/subr_rman.c10
-rw-r--r--sys/kern/subr_rtc.c2
-rw-r--r--sys/kern/subr_unit.c79
-rw-r--r--sys/kern/vfs_subr.c39
-rw-r--r--sys/kern/vnode_if.src4
-rw-r--r--sys/kgssapi/krb5/krb5_mech.c2
-rw-r--r--sys/mips/mediatek/mtk_gpio_v1.c33
-rw-r--r--sys/mips/mediatek/mtk_gpio_v2.c41
-rw-r--r--sys/mips/mediatek/mtk_intr_gic.c12
-rw-r--r--sys/mips/mediatek/mtk_intr_v1.c12
-rw-r--r--sys/mips/mediatek/mtk_intr_v2.c12
-rw-r--r--sys/mips/mediatek/mtk_spi_v1.c5
-rw-r--r--sys/mips/mediatek/mtk_spi_v2.c6
-rw-r--r--sys/mips/mips/exception.S7
-rw-r--r--sys/mips/mips/mips_pic.c12
-rw-r--r--sys/mips/mips/trap.c12
-rw-r--r--sys/modules/Makefile3
-rw-r--r--sys/modules/bhnd/Makefile9
-rw-r--r--sys/modules/bhnd/bhndb/Makefile8
-rw-r--r--sys/modules/bhnd/bhndb_pci/Makefile6
-rw-r--r--sys/modules/bhnd/cores/bhnd_chipc/Makefile6
-rw-r--r--sys/modules/bhnd/nvram/Makefile10
-rw-r--r--sys/modules/bwn_pci/Makefile11
-rw-r--r--sys/modules/igb/Makefile2
-rw-r--r--sys/modules/tests/callout_test/Makefile4
-rw-r--r--sys/modules/tests/framework/Makefile4
-rw-r--r--sys/net/altq/altq_cbq.c2
-rw-r--r--sys/net/altq/altq_red.c4
-rw-r--r--sys/net/altq/altq_rio.c2
-rw-r--r--sys/net/altq/altq_rmclass.h2
-rw-r--r--sys/net/bpf.h2
-rw-r--r--sys/net/bridgestp.c2
-rw-r--r--sys/net/flowtable.c9
-rw-r--r--sys/net/if.c2
-rw-r--r--sys/net/if_arcsubr.c2
-rw-r--r--sys/net/if_atm.h2
-rw-r--r--sys/net/if_bridge.c2
-rw-r--r--sys/net/if_clone.c2
-rw-r--r--sys/net/if_epair.c2
-rw-r--r--sys/net/if_ethersubr.c3
-rw-r--r--sys/net/if_lagg.c2
-rw-r--r--sys/net/if_llatbl.c2
-rw-r--r--sys/net/if_sppp.h2
-rw-r--r--sys/net/if_spppsubr.c4
-rw-r--r--sys/net/if_vlan.c4
-rw-r--r--sys/net/rss_config.c2
-rw-r--r--sys/net/rtsock.c2
-rw-r--r--sys/net/sff8472.h2
-rw-r--r--sys/net80211/ieee80211.c2
-rw-r--r--sys/net80211/ieee80211_adhoc.c2
-rw-r--r--sys/net80211/ieee80211_freebsd.c19
-rw-r--r--sys/net80211/ieee80211_hostap.c2
-rw-r--r--sys/net80211/ieee80211_ht.c10
-rw-r--r--sys/net80211/ieee80211_ioctl.c4
-rw-r--r--sys/net80211/ieee80211_mesh.c2
-rw-r--r--sys/net80211/ieee80211_node.c2
-rw-r--r--sys/net80211/ieee80211_output.c6
-rw-r--r--sys/net80211/ieee80211_proto.c6
-rw-r--r--sys/net80211/ieee80211_proto.h6
-rw-r--r--sys/net80211/ieee80211_regdomain.c2
-rw-r--r--sys/net80211/ieee80211_scan_sw.c6
-rw-r--r--sys/net80211/ieee80211_var.h3
-rw-r--r--sys/netinet/cc/cc_cubic.c2
-rw-r--r--sys/netinet/cc/cc_dctcp.c2
-rw-r--r--sys/netinet/cc/cc_htcp.c15
-rw-r--r--sys/netinet/igmp.c4
-rw-r--r--sys/netinet/in_mcast.c2
-rw-r--r--sys/netinet/in_pcb.h2
-rw-r--r--sys/netinet/ip.h2
-rw-r--r--sys/netinet/ip_fastfwd.c2
-rw-r--r--sys/netinet/ip_fw.h6
-rw-r--r--sys/netinet/ip_icmp.c2
-rw-r--r--sys/netinet/ip_options.c2
-rw-r--r--sys/netinet/libalias/alias_irc.c4
-rw-r--r--sys/netinet/libalias/alias_local.h2
-rw-r--r--sys/netinet/libalias/alias_smedia.c2
-rw-r--r--sys/netinet/libalias/libalias.32
-rw-r--r--sys/netinet/sctp_timer.c8
-rw-r--r--sys/netinet/tcp_input.c4
-rw-r--r--sys/netinet/tcp_output.c8
-rw-r--r--sys/netinet/tcp_sack.c4
-rw-r--r--sys/netinet/tcp_stacks/fastpath.c4
-rw-r--r--sys/netinet/tcp_subr.c2
-rw-r--r--sys/netinet/tcp_syncache.c4
-rw-r--r--sys/netinet/tcp_timer.c2
-rw-r--r--sys/netinet6/frag6.c2
-rw-r--r--sys/netinet6/in6.c10
-rw-r--r--sys/netinet6/in6_mcast.c2
-rw-r--r--sys/netinet6/ip6_forward.c2
-rw-r--r--sys/netinet6/ip6_id.c6
-rw-r--r--sys/netinet6/ip6protosw.h2
-rw-r--r--sys/netinet6/mld6.c4
-rw-r--r--sys/netinet6/nd6.c4
-rw-r--r--sys/netinet6/nd6_rtr.c38
-rw-r--r--sys/netipsec/ipsec.c6
-rw-r--r--sys/netipsec/ipsec_output.c2
-rw-r--r--sys/netipsec/key.c12
-rw-r--r--sys/netpfil/ipfw/dn_heap.h4
-rw-r--r--sys/netpfil/ipfw/dummynet.txt12
-rw-r--r--sys/netpfil/ipfw/ip_dn_glue.c2
-rw-r--r--sys/netpfil/ipfw/ip_dummynet.c2
-rw-r--r--sys/netpfil/ipfw/ip_fw2.c4
-rw-r--r--sys/netpfil/ipfw/ip_fw_dynamic.c4
-rw-r--r--sys/netpfil/ipfw/ip_fw_iface.c6
-rw-r--r--sys/netpfil/ipfw/ip_fw_nat.c2
-rw-r--r--sys/netpfil/ipfw/ip_fw_private.h6
-rw-r--r--sys/netpfil/ipfw/ip_fw_sockopt.c33
-rw-r--r--sys/netpfil/ipfw/ip_fw_table.c71
-rw-r--r--sys/netpfil/ipfw/ip_fw_table_algo.c14
-rw-r--r--sys/netpfil/ipfw/ip_fw_table_value.c16
-rw-r--r--sys/netpfil/pf/pf.c2
-rw-r--r--sys/netpfil/pf/pf_ioctl.c2
-rw-r--r--sys/netpfil/pf/pf_norm.c2
-rw-r--r--sys/netsmb/smb_usr.c2
-rw-r--r--sys/ofed/drivers/infiniband/hw/mlx4/main.c2
-rw-r--r--sys/ofed/drivers/infiniband/hw/mlx4/mcg.c2
-rw-r--r--sys/ofed/drivers/infiniband/hw/mlx4/mr.c4
-rw-r--r--sys/ofed/drivers/infiniband/ulp/sdp/sdp.h6
-rw-r--r--sys/ofed/drivers/infiniband/ulp/sdp/sdp_tx.c2
-rw-r--r--sys/ofed/drivers/net/mlx4/en_rx.c2
-rw-r--r--sys/ofed/drivers/net/mlx4/fw.c2
-rw-r--r--sys/ofed/drivers/net/mlx4/main.c4
-rw-r--r--sys/ofed/drivers/net/mlx4/mlx4.h2
-rw-r--r--sys/ofed/drivers/net/mlx4/resource_tracker.c2
-rw-r--r--sys/ofed/include/linux/mlx4/device.h2
-rw-r--r--sys/opencrypto/cast.c2
-rw-r--r--sys/opencrypto/crypto.c2
-rw-r--r--sys/opencrypto/gfmult.c2
-rw-r--r--sys/powerpc/conf/GENERIC1
-rw-r--r--sys/powerpc/conf/GENERIC641
-rw-r--r--sys/rpc/clnt_bck.c2
-rw-r--r--sys/rpc/clnt_dg.c6
-rw-r--r--sys/rpc/clnt_vc.c6
-rw-r--r--sys/rpc/svc.c2
-rw-r--r--sys/rpc/svc.h4
-rw-r--r--sys/rpc/types.h2
-rw-r--r--sys/security/mac/mac_cred.c2
-rw-r--r--sys/security/mac/mac_framework.c2
-rw-r--r--sys/security/mac_biba/mac_biba.h2
-rw-r--r--sys/security/mac_lomac/mac_lomac.c2
-rw-r--r--sys/security/mac_lomac/mac_lomac.h2
-rw-r--r--sys/security/mac_mls/mac_mls.c2
-rw-r--r--sys/security/mac_mls/mac_mls.h2
-rw-r--r--sys/sparc64/sbus/sbus.c2
-rw-r--r--sys/sparc64/sparc64/intr_machdep.c2
-rw-r--r--sys/sys/_bitset.h23
-rw-r--r--sys/sys/_cpuset.h6
-rw-r--r--sys/sys/ata.h4
-rw-r--r--sys/sys/bitset.h21
-rw-r--r--sys/sys/bitstring.h321
-rw-r--r--sys/sys/buf.h2
-rw-r--r--sys/sys/buf_ring.h4
-rw-r--r--sys/sys/cpuset.h6
-rw-r--r--sys/sys/event.h6
-rw-r--r--sys/sys/iconv.h2
-rw-r--r--sys/sys/imgact_binmisc.h2
-rw-r--r--sys/sys/imgact_elf.h2
-rw-r--r--sys/sys/intr.h25
-rw-r--r--sys/sys/ipc.h2
-rw-r--r--sys/sys/ipmi.h2
-rw-r--r--sys/sys/linker.h2
-rw-r--r--sys/sys/memrange.h2
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/pmc.h4
-rw-r--r--sys/sys/priority.h2
-rw-r--r--sys/sys/priv.h2
-rw-r--r--sys/sys/proc.h2
-rw-r--r--sys/sys/procctl.h2
-rw-r--r--sys/sys/shm.h2
-rw-r--r--sys/sys/sockio.h2
-rw-r--r--sys/sys/soundcard.h4
-rw-r--r--sys/sys/sx.h2
-rw-r--r--sys/sys/sysctl.h4
-rw-r--r--sys/sys/timex.h2
-rw-r--r--sys/sys/user.h2
-rw-r--r--sys/sys/vnode.h4
-rw-r--r--sys/x86/acpica/srat.c8
450 files changed, 13615 insertions, 3653 deletions
diff --git a/sys/amd64/acpica/acpi_wakecode.S b/sys/amd64/acpica/acpi_wakecode.S
index a4c559f..6b36d55 100644
--- a/sys/amd64/acpica/acpi_wakecode.S
+++ b/sys/amd64/acpica/acpi_wakecode.S
@@ -179,7 +179,7 @@ wakeup_32:
* Finally, switch to long bit mode by enabling paging. We have
* to be very careful here because all the segmentation disappears
* out from underneath us. The spec says we can depend on the
- * subsequent pipelined branch to execute, but *only if* everthing
+ * subsequent pipelined branch to execute, but *only if* everything
* is still identity mapped. If any mappings change, the pipeline
* will flush.
*/
@@ -188,7 +188,7 @@ wakeup_32:
mov %eax, %cr0
/*
- * At this point paging is enabled, and we are in "compatability" mode.
+ * At this point paging is enabled, and we are in "compatibility" mode.
* We do another far jump to reload %cs with the 64 bit selector.
* %cr3 points to a 4-level page table page.
* We cannot yet jump all the way to the kernel because we can only
diff --git a/sys/amd64/amd64/atomic.c b/sys/amd64/amd64/atomic.c
index 063201f..9dc3e8d 100644
--- a/sys/amd64/amd64/atomic.c
+++ b/sys/amd64/amd64/atomic.c
@@ -27,7 +27,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-/* This file creates publically callable functions to perform various
+/* This file creates publicly callable functions to perform various
* simple arithmetic on memory which is atomic in the presence of
* interrupts and multiple processors.
*/
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index fd8cdac..2c2b99b 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -427,7 +427,7 @@ IDTVEC(fast_syscall)
/*
* Here for CYA insurance, in case a "syscall" instruction gets
- * issued from 32 bit compatability mode. MSR_CSTAR has to point
+ * issued from 32 bit compatibility mode. MSR_CSTAR has to point
* to *something* if EFER_SCE is enabled.
*/
IDTVEC(fast_syscall32)
diff --git a/sys/amd64/amd64/mpboot.S b/sys/amd64/amd64/mpboot.S
index c4b6537..5576aff 100644
--- a/sys/amd64/amd64/mpboot.S
+++ b/sys/amd64/amd64/mpboot.S
@@ -121,7 +121,7 @@ protmode:
* Finally, switch to long bit mode by enabling paging. We have
* to be very careful here because all the segmentation disappears
* out from underneath us. The spec says we can depend on the
- * subsequent pipelined branch to execute, but *only if* everthing
+ * subsequent pipelined branch to execute, but *only if* everything
* is still identity mapped. If any mappings change, the pipeline
* will flush.
*/
@@ -130,7 +130,7 @@ protmode:
mov %eax, %cr0
/*
- * At this point paging is enabled, and we are in "compatability" mode.
+ * At this point paging is enabled, and we are in "compatibility" mode.
* We do another far jump to reload %cs with the 64 bit selector.
* %cr3 points to a 4-level page table page.
* We cannot yet jump all the way to the kernel because we can only
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 22a6c31..a7c879c 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -4407,6 +4407,12 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
lockp)) {
SLIST_INIT(&free);
if (pmap_unwire_ptp(pmap, va, mpde, &free)) {
+ /*
+ * Although "va" is not mapped, paging-
+ * structure caches could nonetheless have
+ * entries that refer to the freed page table
+ * pages. Invalidate those entries.
+ */
pmap_invalidate_page(pmap, va);
pmap_free_zero_pages(&free);
}
@@ -4584,6 +4590,12 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
if (mpte != NULL) {
SLIST_INIT(&free);
if (pmap_unwire_ptp(pmap, va, mpte, &free)) {
+ /*
+ * Although "va" is not mapped, paging-
+ * structure caches could nonetheless have
+ * entries that refer to the freed page table
+ * pages. Invalidate those entries.
+ */
pmap_invalidate_page(pmap, va);
pmap_free_zero_pages(&free);
}
@@ -4967,6 +4979,14 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
SLIST_INIT(&free);
if (pmap_unwire_ptp(dst_pmap, addr,
dstmpte, &free)) {
+ /*
+ * Although "addr" is not
+ * mapped, paging-structure
+ * caches could nonetheless
+ * have entries that refer to
+ * the freed page table pages.
+ * Invalidate those entries.
+ */
pmap_invalidate_page(dst_pmap,
addr);
pmap_free_zero_pages(&free);
@@ -5219,7 +5239,7 @@ pmap_page_is_mapped(vm_page_t m)
* Destroy all managed, non-wired mappings in the given user-space
* pmap. This pmap cannot be active on any processor besides the
* caller.
- *
+ *
* This function cannot be applied to the kernel pmap. Moreover, it
* is not intended for general use. It is only to be used during
* process termination. Consequently, it can be implemented in ways
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 272da43..2859de5 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -102,6 +102,7 @@ device cpufreq
device acpi
options ACPI_DMAR
device pci
+options PCI_HP # PCI-Express native HotPlug
options PCI_IOV # PCI SR-IOV support
# Floppy drives
@@ -349,7 +350,7 @@ device virtio_blk # VirtIO Block device
device virtio_scsi # VirtIO SCSI device
device virtio_balloon # VirtIO Memory Balloon device
-# HyperV drivers and enchancement support
+# HyperV drivers and enhancement support
device hyperv # HyperV drivers
# Xen HVM Guest Optimizations
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index 604a1a3..4107ca6 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -509,7 +509,7 @@ device virtio_balloon # VirtIO Memory Balloon device
device virtio_random # VirtIO Entropy device
device virtio_console # VirtIO Console device
-# Microsoft Hyper-V enchancement support
+# Microsoft Hyper-V enhancement support
device hyperv # HyperV drivers
# Xen HVM Guest Optimizations
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index f2de960..bdfff1f 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -377,7 +377,7 @@ struct vm_copyinfo {
* at 'gla' and 'len' bytes long. The 'prot' should be set to PROT_READ for
* a copyin or PROT_WRITE for a copyout.
*
- * retval is_fault Intepretation
+ * retval is_fault Interpretation
* 0 0 Success
* 0 1 An exception was injected into the guest
* EFAULT N/A Unrecoverable error
diff --git a/sys/amd64/linux/linux_locore.s b/sys/amd64/linux/linux_locore.s
index 5dcc09a..1bcf05b 100644
--- a/sys/amd64/linux/linux_locore.s
+++ b/sys/amd64/linux/linux_locore.s
@@ -29,6 +29,7 @@ NON_GPROF_ENTRY(linux_rt_sigcode)
movq $LINUX_SYS_linux_rt_sigreturn,%rax /* linux_rt_sigreturn() */
syscall /* enter kernel with args */
hlt
+.endrtsigcode:
0: jmp 0b
NON_GPROF_ENTRY(__vdso_clock_gettime)
@@ -74,3 +75,34 @@ NON_GPROF_ENTRY(__vdso_getcpu)
.balign 4
.previous
#endif
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAMEDLSI0:
+ .long .LENDCIEDLSI0-.LSTARTCIEDLSI0
+.LSTARTCIEDLSI0:
+ .long 0 /* CIE ID */
+ .byte 1 /* Version number */
+ .string "zR" /* NULL-terminated
+ * augmentation string
+ */
+ .uleb128 1 /* Code alignment factor */
+ .sleb128 -4 /* Data alignment factor */
+ .byte 8 /* Return address register column */
+ .uleb128 1 /* Augmentation value length */
+ .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
+ .byte 0x0c /* DW_CFA_def_cfa */
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .uleb128 1
+ .align 4
+.LENDCIEDLSI0:
+ .long .LENDFDEDLSI0-.LSTARTFDEDLSI0 /* Length FDE */
+.LSTARTFDEDLSI0:
+ .long .LSTARTFDEDLSI0-.LSTARTFRAMEDLSI0 /* CIE pointer */
+ .long .startrtsigcode-. /* PC-relative start address */
+ .long .endrtsigcode-.startrtsigcode
+ .uleb128 0
+ .align 4
+.LENDFDEDLSI0:
+ .previous
diff --git a/sys/amd64/linux/linux_machdep.c b/sys/amd64/linux/linux_machdep.c
index 376cce7..0459ba7 100644
--- a/sys/amd64/linux/linux_machdep.c
+++ b/sys/amd64/linux/linux_machdep.c
@@ -212,7 +212,7 @@ linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
/*
* The Linux MAP_GROWSDOWN option does not limit auto
* growth of the region. Linux mmap with this option
- * takes as addr the inital BOS, and as len, the initial
+ * takes as addr the initial BOS, and as len, the initial
* region size. It can then grow down from addr without
* limit. However, Linux threads has an implicit internal
* limit to stack size of STACK_SIZE. Its just not
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index 8f4e350..25f023c 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -576,7 +576,7 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot,
/*
* The Linux MAP_GROWSDOWN option does not limit auto
* growth of the region. Linux mmap with this option
- * takes as addr the inital BOS, and as len, the initial
+ * takes as addr the initial BOS, and as len, the initial
* region size. It can then grow down from addr without
* limit. However, Linux threads has an implicit internal
* limit to stack size of STACK_SIZE. Its just not
diff --git a/sys/amd64/vmm/amd/vmcb.h b/sys/amd64/vmm/amd/vmcb.h
index 496f880..9c4f582 100644
--- a/sys/amd64/vmm/amd/vmcb.h
+++ b/sys/amd64/vmm/amd/vmcb.h
@@ -313,7 +313,7 @@ struct vmcb_state {
uint64_t br_to;
uint64_t int_from;
uint64_t int_to;
- uint8_t pad7[0x968]; /* Reserved upto end of VMCB */
+ uint8_t pad7[0x968]; /* Reserved up to end of VMCB */
} __attribute__ ((__packed__));
CTASSERT(sizeof(struct vmcb_state) == 0xC00);
diff --git a/sys/amd64/vmm/intel/vtd.c b/sys/amd64/vmm/intel/vtd.c
index be57aff..f3b7a98 100644
--- a/sys/amd64/vmm/intel/vtd.c
+++ b/sys/amd64/vmm/intel/vtd.c
@@ -463,7 +463,7 @@ vtd_update_mapping(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, uint64_t len,
panic("vtd_create_mapping: unaligned len 0x%0lx", len);
/*
- * Compute the size of the mapping that we can accomodate.
+ * Compute the size of the mapping that we can accommodate.
*
* This is based on three factors:
* - supported super page size
diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c
index 3451e1e..cdf411b 100644
--- a/sys/amd64/vmm/io/vlapic.c
+++ b/sys/amd64/vmm/io/vlapic.c
@@ -841,7 +841,7 @@ vlapic_calcdest(struct vm *vm, cpuset_t *dmask, uint32_t dest, bool phys,
} else {
/*
* In the "Flat Model" the MDA is interpreted as an 8-bit wide
- * bitmask. This model is only avilable in the xAPIC mode.
+ * bitmask. This model is only available in the xAPIC mode.
*/
mda_flat_ldest = dest & 0xff;
diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c
index ae5330f..852f1d7 100644
--- a/sys/amd64/vmm/vmm_instruction_emul.c
+++ b/sys/amd64/vmm/vmm_instruction_emul.c
@@ -1232,7 +1232,7 @@ emulate_stack_op(void *vm, int vcpuid, uint64_t mmio_gpa, struct vie *vie,
size = vie->opsize_override ? 2 : 8;
} else {
/*
- * In protected or compability mode the 'B' flag in the
+ * In protected or compatibility mode the 'B' flag in the
* stack-segment descriptor determines the size of the
* stack pointer.
*/
diff --git a/sys/amd64/vmm/vmm_stat.c b/sys/amd64/vmm/vmm_stat.c
index 7e2f64d..62002d6 100644
--- a/sys/amd64/vmm/vmm_stat.c
+++ b/sys/amd64/vmm/vmm_stat.c
@@ -69,7 +69,7 @@ vmm_stat_register(void *arg)
return;
if (vst_num_elems + vst->nelems >= MAX_VMM_STAT_ELEMS) {
- printf("Cannot accomodate vmm stat type \"%s\"!\n", vst->desc);
+ printf("Cannot accommodate vmm stat type \"%s\"!\n", vst->desc);
return;
}
diff --git a/sys/arm/allwinner/a10/a10_intc.c b/sys/arm/allwinner/a10/a10_intc.c
index 7bd8e80..31e6ef4 100644
--- a/sys/arm/allwinner/a10/a10_intc.c
+++ b/sys/arm/allwinner/a10/a10_intc.c
@@ -298,14 +298,18 @@ static int
a10_intr_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct a10_aintc_softc *sc;
- if (data->type != INTR_MAP_DATA_FDT || data->fdt.ncells != 1 ||
- data->fdt.cells[0] >= A10_INTR_MAX_NIRQS)
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
+ daf = (struct intr_map_data_fdt *)data;
+ if (daf->ncells != 1 || daf->cells[0] >= A10_INTR_MAX_NIRQS)
return (EINVAL);
sc = device_get_softc(dev);
- *isrcp = &sc->isrcs[data->fdt.cells[0]].isrc;
+ *isrcp = &sc->isrcs[daf->cells[0]].isrc;
return (0);
}
diff --git a/sys/arm/allwinner/a10_ehci.c b/sys/arm/allwinner/a10_ehci.c
index c325d60..4a9ee80 100644
--- a/sys/arm/allwinner/a10_ehci.c
+++ b/sys/arm/allwinner/a10_ehci.c
@@ -112,6 +112,7 @@ static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-ehci", (uintptr_t)&a10_ehci_conf },
{ "allwinner,sun6i-a31-ehci", (uintptr_t)&a31_ehci_conf },
{ "allwinner,sun7i-a20-ehci", (uintptr_t)&a10_ehci_conf },
+ { "allwinner,sun8i-a83t-ehci", (uintptr_t)&a31_ehci_conf },
{ NULL, (uintptr_t)NULL }
};
diff --git a/sys/arm/allwinner/a10_gpio.c b/sys/arm/allwinner/a10_gpio.c
index 4e6e612..079e715 100644
--- a/sys/arm/allwinner/a10_gpio.c
+++ b/sys/arm/allwinner/a10_gpio.c
@@ -99,6 +99,12 @@ extern const struct allwinner_padconf a31s_padconf;
extern const struct allwinner_padconf a31_r_padconf;
#endif
+/* Defined in a83t_padconf.c */
+#ifdef SOC_ALLWINNER_A83T
+extern const struct allwinner_padconf a83t_padconf;
+extern const struct allwinner_padconf a83t_r_padconf;
+#endif
+
static struct ofw_compat_data compat_data[] = {
#ifdef SOC_ALLWINNER_A10
{"allwinner,sun4i-a10-pinctrl", (uintptr_t)&a10_padconf},
@@ -115,6 +121,10 @@ static struct ofw_compat_data compat_data[] = {
#if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S)
{"allwinner,sun6i-a31-r-pinctrl", (uintptr_t)&a31_r_padconf},
#endif
+#ifdef SOC_ALLWINNER_A83T
+ {"allwinner,sun8i-a83t-pinctrl", (uintptr_t)&a83t_padconf},
+ {"allwinner,sun8i-a83t-r-pinctrl", (uintptr_t)&a83t_r_padconf},
+#endif
{NULL, 0}
};
diff --git a/sys/arm/allwinner/a83t/a83t_padconf.c b/sys/arm/allwinner/a83t/a83t_padconf.c
new file mode 100644
index 0000000..bbf638e
--- /dev/null
+++ b/sys/arm/allwinner/a83t/a83t_padconf.c
@@ -0,0 +1,162 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/types.h>
+
+#include <arm/allwinner/allwinner_pinctrl.h>
+
+#ifdef SOC_ALLWINNER_A83T
+
+static const struct allwinner_pins a83t_pins[] = {
+ { "PB0", 1, 0, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
+ { "PB1", 1, 1, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
+ { "PB2", 1, 2, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
+ { "PB3", 1, 3, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
+ { "PB4", 1, 4, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
+ { "PB5", 1, 5, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
+ { "PB6", 1, 6, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
+ { "PB7", 1, 7, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
+ { "PB8", 1, 8, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
+ { "PB9", 1, 9, { "gpio_in", "gpio_out", "uart0", NULL, NULL, NULL, "eint" } },
+ { "PB10", 1, 10, { "gpio_in", "gpio_out", "uart0", NULL, NULL, NULL, "eint" } },
+
+ { "PC0", 2, 0, { "gpio_in", "gpio_out", "nand", "spi0" } },
+ { "PC1", 2, 1, { "gpio_in", "gpio_out", "nand", "spi0" } },
+ { "PC2", 2, 2, { "gpio_in", "gpio_out", "nand", "spi0" } },
+ { "PC3", 2, 3, { "gpio_in", "gpio_out", "nand", "spi0" } },
+ { "PC4", 2, 4, { "gpio_in", "gpio_out", "nand" } },
+ { "PC5", 2, 5, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC6", 2, 6, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC7", 2, 7, { "gpio_in", "gpio_out", "nand" } },
+ { "PC8", 2, 8, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC9", 2, 9, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC10", 2, 10, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC11", 2, 11, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC12", 2, 12, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC13", 2, 13, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC14", 2, 14, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC15", 2, 15, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC16", 2, 16, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC17", 2, 17, { "gpio_in", "gpio_out", "nand" } },
+ { "PC18", 2, 18, { "gpio_in", "gpio_out", "nand" } },
+
+ { "PD2", 3, 2, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD3", 3, 3, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD4", 3, 4, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD5", 3, 5, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD6", 3, 6, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD7", 3, 7, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD10", 3, 10, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD11", 3, 11, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD12", 3, 12, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD13", 3, 13, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD14", 3, 14, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD15", 3, 15, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD18", 3, 18, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD19", 3, 19, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD20", 3, 20, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD21", 3, 21, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD22", 3, 22, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD23", 3, 23, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD24", 3, 24, { "gpio_in", "gpio_out", "lcd", "lvds" } },
+ { "PD25", 3, 25, { "gpio_in", "gpio_out", "lcd", "lvds" } },
+ { "PD26", 3, 26, { "gpio_in", "gpio_out", "lcd", "lvds" } },
+ { "PD27", 3, 27, { "gpio_in", "gpio_out", "lcd", "lvds" } },
+ { "PD28", 3, 28, { "gpio_in", "gpio_out", "pwm" } },
+ { "PD29", 3, 29, { "gpio_in", "gpio_out" } },
+
+ { "PE0", 4, 0, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE1", 4, 1, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE2", 4, 2, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE3", 4, 3, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE4", 4, 4, { "gpio_in", "gpio_out", "csi" } },
+ { "PE5", 4, 5, { "gpio_in", "gpio_out", "csi" } },
+ { "PE6", 4, 6, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE7", 4, 7, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE8", 4, 8, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE9", 4, 9, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE10", 4, 10, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
+ { "PE11", 4, 11, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
+ { "PE12", 4, 12, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
+ { "PE13", 4, 13, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
+ { "PE14", 4, 14, { "gpio_in", "gpio_out", "csi", "twi2" } },
+ { "PE15", 4, 15, { "gpio_in", "gpio_out", "csi", "twi2" } },
+ { "PE16", 4, 16, { "gpio_in", "gpio_out" } },
+ { "PE17", 4, 17, { "gpio_in", "gpio_out" } },
+ { "PE18", 4, 18, { "gpio_in", "gpio_out", NULL, "owa" } },
+ { "PE19", 4, 19, { "gpio_in", "gpio_out" } },
+
+ { "PF0", 5, 0, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
+ { "PF1", 5, 1, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
+ { "PF2", 5, 2, { "gpio_in", "gpio_out", "mmc0", "uart0" } },
+ { "PF3", 5, 3, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
+ { "PF4", 5, 4, { "gpio_in", "gpio_out", "mmc0", "uart0" } },
+ { "PF5", 5, 5, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
+ { "PF6", 5, 6, { "gpio_in", "gpio_out" } },
+
+ { "PG0", 6, 0, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG1", 6, 1, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG2", 6, 2, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG3", 6, 3, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG4", 6, 4, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG5", 6, 5, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG6", 6, 6, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
+ { "PG7", 6, 7, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
+ { "PG8", 6, 8, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
+ { "PG9", 6, 9, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
+ { "PG10", 6, 10, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
+ { "PG11", 6, 11, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
+ { "PG12", 6, 12, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
+ { "PG13", 6, 13, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
+
+ { "PH0", 7, 0, { "gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, "eint" } },
+ { "PH1", 7, 1, { "gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, "eint" } },
+ { "PH2", 7, 2, { "gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, "eint" } },
+ { "PH3", 7, 3, { "gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, "eint" } },
+ { "PH4", 7, 4, { "gpio_in", "gpio_out", "i2c2", NULL, NULL, NULL, "eint" } },
+ { "PH5", 7, 5, { "gpio_in", "gpio_out", "i2c2", NULL, NULL, NULL, "eint" } },
+ { "PH6", 7, 6, { "gpio_in", "gpio_out", "hdmiddc", NULL, NULL, NULL, "eint" } },
+ { "PH7", 7, 7, { "gpio_in", "gpio_out", "hdmiddc", NULL, NULL, NULL, "eint" } },
+ { "PH8", 7, 8, { "gpio_in", "gpio_out", "hdmiddc", NULL, NULL, NULL, "eint" } },
+ { "PH9", 7, 9, { "gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "eint" } },
+ { "PH10", 7, 10, { "gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "eint" } },
+ { "PH11", 7, 11, { "gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "eint" } },
+};
+
+const struct allwinner_padconf a83t_padconf = {
+ .npins = nitems(a83t_pins),
+ .pins = a83t_pins,
+};
+
+#endif /* !SOC_ALLWINNER_A83T */
diff --git a/sys/arm/allwinner/a83t/a83t_r_padconf.c b/sys/arm/allwinner/a83t/a83t_r_padconf.c
new file mode 100644
index 0000000..e463745
--- /dev/null
+++ b/sys/arm/allwinner/a83t/a83t_r_padconf.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/types.h>
+
+#include <arm/allwinner/allwinner_pinctrl.h>
+
+#ifdef SOC_ALLWINNER_A83T
+
+static const struct allwinner_pins a83t_r_pins[] = {
+ { "PL0", 0, 0, { "gpio_in", "gpio_out", "s_rsb", "s_i2c", NULL, NULL, "eint" } },
+ { "PL1", 0, 1, { "gpio_in", "gpio_out", "s_rsb", "s_i2c", NULL, NULL, "eint" } },
+ { "PL2", 0, 2, { "gpio_in", "gpio_out", "s_uart", NULL, NULL, NULL, "eint" } },
+ { "PL3", 0, 3, { "gpio_in", "gpio_out", "s_uart", NULL, NULL, NULL, "eint" } },
+ { "PL4", 0, 4, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
+ { "PL5", 0, 5, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
+ { "PL6", 0, 6, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
+ { "PL7", 0, 7, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
+ { "PL8", 0, 8, { "gpio_in", "gpio_out", "s_i2c", NULL, NULL, NULL, "eint" } },
+ { "PL9", 0, 9, { "gpio_in", "gpio_out", "s_i2c", NULL, NULL, NULL, "eint" } },
+ { "PL10", 0, 10, { "gpio_in", "gpio_out", "s_pwm", NULL, NULL, NULL, "eint" } },
+ { "PL11", 0, 11, { "gpio_in", "gpio_out", NULL, NULL, NULL, "eint" } },
+ { "PL12", 0, 12, { "gpio_in", "gpio_out", "s_cir", NULL, NULL, NULL, "eint" } },
+};
+
+const struct allwinner_padconf a83t_r_padconf = {
+ .npins = nitems(a83t_r_pins),
+ .pins = a83t_r_pins,
+};
+
+#endif /* !SOC_ALLWINNER_A83T */
diff --git a/sys/arm/allwinner/a83t/files.a83t b/sys/arm/allwinner/a83t/files.a83t
new file mode 100644
index 0000000..45334a0
--- /dev/null
+++ b/sys/arm/allwinner/a83t/files.a83t
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+arm/allwinner/a83t/a83t_padconf.c standard
+arm/allwinner/a83t/a83t_r_padconf.c standard
diff --git a/sys/arm/allwinner/a83t/std.a83t b/sys/arm/allwinner/a83t/std.a83t
new file mode 100644
index 0000000..06b1ed4
--- /dev/null
+++ b/sys/arm/allwinner/a83t/std.a83t
@@ -0,0 +1,15 @@
+# Allwinner A83T common options
+#$FreeBSD$
+
+cpu CPU_CORTEXA
+machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a"
+
+makeoptions KERNVIRTADDR=0xc0200000
+options KERNVIRTADDR=0xc0200000
+
+options IPI_IRQ_START=0
+options IPI_IRQ_END=15
+
+files "../allwinner/files.allwinner"
+files "../allwinner/a83t/files.a83t"
diff --git a/sys/arm/allwinner/allwinner_machdep.c b/sys/arm/allwinner/allwinner_machdep.c
index e5c8eb8..7916441 100644
--- a/sys/arm/allwinner/allwinner_machdep.c
+++ b/sys/arm/allwinner/allwinner_machdep.c
@@ -94,6 +94,15 @@ a31s_attach(platform_t plat)
return (0);
}
+static int
+a83t_attach(platform_t plat)
+{
+ soc_type = ALLWINNERSOC_A83T;
+ soc_family = ALLWINNERSOC_SUN8I;
+
+ return (0);
+}
+
static vm_offset_t
allwinner_lastaddr(platform_t plat)
{
@@ -196,6 +205,21 @@ static platform_method_t a31s_methods[] = {
FDT_PLATFORM_DEF(a31s, "a31s", 0, "allwinner,sun6i-a31s", 200);
#endif
+#if defined(SOC_ALLWINNER_A83T)
+static platform_method_t a83t_methods[] = {
+ PLATFORMMETHOD(platform_attach, a83t_attach),
+ PLATFORMMETHOD(platform_lastaddr, allwinner_lastaddr),
+ PLATFORMMETHOD(platform_devmap_init, allwinner_devmap_init),
+
+#ifdef SMP
+ PLATFORMMETHOD(platform_mp_start_ap, a83t_mp_start_ap),
+ PLATFORMMETHOD(platform_mp_setmaxid, aw_mp_setmaxid),
+#endif
+ PLATFORMMETHOD_END,
+};
+FDT_PLATFORM_DEF(a83t, "a83t", 0, "allwinner,sun8i-a83t", 200);
+#endif
+
u_int
allwinner_soc_type(void)
{
diff --git a/sys/arm/allwinner/allwinner_machdep.h b/sys/arm/allwinner/allwinner_machdep.h
index c640494..91c97ac 100644
--- a/sys/arm/allwinner/allwinner_machdep.h
+++ b/sys/arm/allwinner/allwinner_machdep.h
@@ -36,11 +36,13 @@
#define ALLWINNERSOC_A20 0x20000000
#define ALLWINNERSOC_A31 0x31000000
#define ALLWINNERSOC_A31S 0x31000001
+#define ALLWINNERSOC_A83T 0x83000000
#define ALLWINNERSOC_SUN4I 0x40000000
#define ALLWINNERSOC_SUN5I 0x50000000
#define ALLWINNERSOC_SUN6I 0x60000000
#define ALLWINNERSOC_SUN7I 0x70000000
+#define ALLWINNERSOC_SUN8I 0x80000000
u_int allwinner_soc_type(void);
u_int allwinner_soc_family(void);
diff --git a/sys/arm/allwinner/aw_ccu.c b/sys/arm/allwinner/aw_ccu.c
index d2ce774..a8342ca 100644
--- a/sys/arm/allwinner/aw_ccu.c
+++ b/sys/arm/allwinner/aw_ccu.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <dev/fdt/simplebus.h>
+#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
@@ -53,40 +54,74 @@ __FBSDID("$FreeBSD$");
#define CCU_BASE 0x01c20000
#define CCU_SIZE 0x400
+#define PRCM_BASE 0x01f01400
+#define PRCM_SIZE 0x200
+
+#define SYSCTRL_BASE 0x01c00000
+#define SYSCTRL_SIZE 0x34
+
struct aw_ccu_softc {
struct simplebus_softc sc;
bus_space_tag_t bst;
- bus_space_handle_t bsh;
+ bus_space_handle_t ccu_bsh;
+ bus_space_handle_t prcm_bsh;
+ bus_space_handle_t sysctrl_bsh;
struct mtx mtx;
+ int flags;
};
+#define CLOCK_CCU (1 << 0)
+#define CLOCK_PRCM (1 << 1)
+#define CLOCK_SYSCTRL (1 << 2)
+
static struct ofw_compat_data compat_data[] = {
- { "allwinner,sun4i-a10", 1 },
- { "allwinner,sun7i-a20", 1 },
- { "allwinner,sun6i-a31", 1 },
- { "allwinner,sun6i-a31s", 1 },
+ { "allwinner,sun4i-a10", CLOCK_CCU },
+ { "allwinner,sun7i-a20", CLOCK_CCU },
+ { "allwinner,sun6i-a31", CLOCK_CCU },
+ { "allwinner,sun6i-a31s", CLOCK_CCU },
+ { "allwinner,sun8i-a83t", CLOCK_CCU|CLOCK_PRCM|CLOCK_SYSCTRL },
{ NULL, 0 }
};
static int
-aw_ccu_check_addr(bus_addr_t addr)
+aw_ccu_check_addr(struct aw_ccu_softc *sc, bus_addr_t addr,
+ bus_space_handle_t *pbsh, bus_size_t *poff)
{
- if (addr < CCU_BASE || addr >= (CCU_BASE + CCU_SIZE))
- return (EINVAL);
- return (0);
+ if (addr >= CCU_BASE && addr < (CCU_BASE + CCU_SIZE) &&
+ (sc->flags & CLOCK_CCU) != 0) {
+ *poff = addr - CCU_BASE;
+ *pbsh = sc->ccu_bsh;
+ return (0);
+ }
+ if (addr >= PRCM_BASE && addr < (PRCM_BASE + PRCM_SIZE) &&
+ (sc->flags & CLOCK_PRCM) != 0) {
+ *poff = addr - PRCM_BASE;
+ *pbsh = sc->prcm_bsh;
+ return (0);
+ }
+ if (addr >= SYSCTRL_BASE && addr < (SYSCTRL_BASE + SYSCTRL_SIZE) &&
+ (sc->flags & CLOCK_SYSCTRL) != 0) {
+ *poff = addr - SYSCTRL_BASE;
+ *pbsh = sc->sysctrl_bsh;
+ return (0);
+ }
+ return (EINVAL);
}
static int
aw_ccu_write_4(device_t dev, bus_addr_t addr, uint32_t val)
{
struct aw_ccu_softc *sc;
+ bus_space_handle_t bsh;
+ bus_size_t reg;
- if (aw_ccu_check_addr(addr) != 0)
+ sc = device_get_softc(dev);
+
+ if (aw_ccu_check_addr(sc, addr, &bsh, &reg) != 0)
return (EINVAL);
- sc = device_get_softc(dev);
mtx_assert(&sc->mtx, MA_OWNED);
- bus_space_write_4(sc->bst, sc->bsh, addr - CCU_BASE, val);
+ bus_space_write_4(sc->bst, bsh, reg, val);
return (0);
}
@@ -95,13 +130,16 @@ static int
aw_ccu_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
{
struct aw_ccu_softc *sc;
+ bus_space_handle_t bsh;
+ bus_size_t reg;
+
+ sc = device_get_softc(dev);
- if (aw_ccu_check_addr(addr) != 0)
+ if (aw_ccu_check_addr(sc, addr, &bsh, &reg) != 0)
return (EINVAL);
- sc = device_get_softc(dev);
mtx_assert(&sc->mtx, MA_OWNED);
- *val = bus_space_read_4(sc->bst, sc->bsh, addr - CCU_BASE);
+ *val = bus_space_read_4(sc->bst, bsh, reg);
return (0);
}
@@ -110,17 +148,20 @@ static int
aw_ccu_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set)
{
struct aw_ccu_softc *sc;
+ bus_space_handle_t bsh;
+ bus_size_t reg;
uint32_t val;
- if (aw_ccu_check_addr(addr) != 0)
+ sc = device_get_softc(dev);
+
+ if (aw_ccu_check_addr(sc, addr, &bsh, &reg) != 0)
return (EINVAL);
- sc = device_get_softc(dev);
mtx_assert(&sc->mtx, MA_OWNED);
- val = bus_space_read_4(sc->bst, sc->bsh, addr - CCU_BASE);
+ val = bus_space_read_4(sc->bst, bsh, reg);
val &= ~clr;
val |= set;
- bus_space_write_4(sc->bst, sc->bsh, addr - CCU_BASE, val);
+ bus_space_write_4(sc->bst, bsh, reg, val);
return (0);
}
@@ -143,20 +184,32 @@ aw_ccu_device_unlock(device_t dev)
mtx_unlock(&sc->mtx);
}
+static const struct ofw_compat_data *
+aw_ccu_search_compatible(void)
+{
+ const struct ofw_compat_data *compat;
+ phandle_t root;
+
+ root = OF_finddevice("/");
+ for (compat = compat_data; compat_data->ocd_str != NULL; compat++)
+ if (fdt_is_compatible(root, compat->ocd_str))
+ break;
+
+ return (compat);
+}
+
static int
aw_ccu_probe(device_t dev)
{
const char *name;
- device_t pdev;
name = ofw_bus_get_name(dev);
if (name == NULL || strcmp(name, "clocks") != 0)
return (ENXIO);
- pdev = device_get_parent(dev);
- if (ofw_bus_search_compatible(pdev, compat_data)->ocd_data == 0)
- return (0);
+ if (aw_ccu_search_compatible()->ocd_data == 0)
+ return (ENXIO);
device_set_desc(dev, "Allwinner Clock Control Unit");
return (BUS_PROBE_SPECIFIC);
@@ -175,15 +228,37 @@ aw_ccu_attach(device_t dev)
simplebus_init(dev, node);
+ sc->flags = aw_ccu_search_compatible()->ocd_data;
+
/*
- * Map CCU registers. The DT doesn't have a "reg" property for the
- * /clocks node and child nodes have conflicting "reg" properties.
+ * Map registers. The DT doesn't have a "reg" property
+ * for the /clocks node and child nodes have conflicting "reg"
+ * properties.
*/
sc->bst = bus_get_bus_tag(dev);
- error = bus_space_map(sc->bst, CCU_BASE, CCU_SIZE, 0, &sc->bsh);
- if (error != 0) {
- device_printf(dev, "couldn't map CCU: %d\n", error);
- return (error);
+ if (sc->flags & CLOCK_CCU) {
+ error = bus_space_map(sc->bst, CCU_BASE, CCU_SIZE, 0,
+ &sc->ccu_bsh);
+ if (error != 0) {
+ device_printf(dev, "couldn't map CCU: %d\n", error);
+ return (error);
+ }
+ }
+ if (sc->flags & CLOCK_PRCM) {
+ error = bus_space_map(sc->bst, PRCM_BASE, PRCM_SIZE, 0,
+ &sc->prcm_bsh);
+ if (error != 0) {
+ device_printf(dev, "couldn't map PRCM: %d\n", error);
+ return (error);
+ }
+ }
+ if (sc->flags & CLOCK_SYSCTRL) {
+ error = bus_space_map(sc->bst, SYSCTRL_BASE, SYSCTRL_SIZE, 0,
+ &sc->sysctrl_bsh);
+ if (error != 0) {
+ device_printf(dev, "couldn't map SYSCTRL: %d\n", error);
+ return (error);
+ }
}
mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
diff --git a/sys/arm/allwinner/aw_mp.c b/sys/arm/allwinner/aw_mp.c
index 9e46f2d..ce0dddd 100644
--- a/sys/arm/allwinner/aw_mp.c
+++ b/sys/arm/allwinner/aw_mp.c
@@ -55,6 +55,9 @@ __FBSDID("$FreeBSD$");
#define CPUCFG_SIZE 0x400
#define PRCM_BASE 0x01f01400
#define PRCM_SIZE 0x800
+/* Register for multi-cluster SoC */
+#define CPUXCFG_BASE 0x01700000
+#define CPUXCFG_SIZE 0x400
#define CPU_OFFSET 0x40
#define CPU_OFFSET_CTL 0x04
@@ -80,6 +83,14 @@ __FBSDID("$FreeBSD$");
#define CPUCFG_DBGCTL0 0x1e0
#define CPUCFG_DBGCTL1 0x1e4
+#define CPUS_CL_RST(cl) (0x30 + (cluster) * 0x4)
+#define CPUX_CL_CTRL0(cl) (0x0 + (cluster) * 0x10)
+#define CPUX_CL_CTRL1(cl) (0x4 + (cluster) * 0x10)
+#define CPUX_CL_CPU_STATUS(cl) (0x30 + (cluster) * 0x4)
+#define CPUX_CL_RST(cl) (0x80 + (cluster) * 0x4)
+#define PRCM_CL_PWROFF(cl) (0x100 + (cluster) * 0x4)
+#define PRCM_CL_PWR_CLAMP(cl, cpu) (0x140 + (cluster) * 0x4 + (cpu) * 0x4)
+
void
aw_mp_setmaxid(platform_t plat)
{
@@ -202,3 +213,89 @@ a31_mp_start_ap(platform_t plat)
bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE);
bus_space_unmap(fdtbus_bs_tag, prcm, PRCM_SIZE);
}
+
+static void
+aw_mc_mp_start_cpu(bus_space_handle_t cpuscfg, bus_space_handle_t cpuxcfg,
+ bus_space_handle_t prcm, int cluster, int cpu)
+{
+ uint32_t val;
+ int i;
+
+ /* Assert core reset */
+ val = bus_space_read_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_RST(cluster));
+ val &= ~(1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_RST(cluster), val);
+
+ /* Assert power-on reset */
+ val = bus_space_read_4(fdtbus_bs_tag, cpuscfg, CPUS_CL_RST(cluster));
+ val &= ~(1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, cpuscfg, CPUS_CL_RST(cluster), val);
+
+ /* Disable automatic L1 cache invalidate at reset */
+ val = bus_space_read_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_CTRL0(cluster));
+ val &= ~(1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_CTRL0(cluster), val);
+
+ /* Release power clamp */
+ for (i = 0; i <= CPU_PWR_CLAMP_STEPS; i++)
+ bus_space_write_4(fdtbus_bs_tag, prcm,
+ PRCM_CL_PWR_CLAMP(cluster, cpu), 0xff >> i);
+ while (bus_space_read_4(fdtbus_bs_tag, prcm,
+ PRCM_CL_PWR_CLAMP(cluster, cpu)) != 0)
+ ;
+
+ /* Clear power-off gating */
+ val = bus_space_read_4(fdtbus_bs_tag, prcm, PRCM_CL_PWROFF(cluster));
+ val &= ~(1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, prcm, PRCM_CL_PWROFF(cluster), val);
+
+ /* De-assert power-on reset */
+ val = bus_space_read_4(fdtbus_bs_tag, cpuscfg, CPUS_CL_RST(cluster));
+ val |= (1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, cpuscfg, CPUS_CL_RST(cluster), val);
+
+ /* De-assert core reset */
+ val = bus_space_read_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_RST(cluster));
+ val |= (1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_RST(cluster), val);
+}
+
+static void
+aw_mc_mp_start_ap(bus_space_handle_t cpuscfg, bus_space_handle_t cpuxcfg,
+ bus_space_handle_t prcm)
+{
+ int cluster, cpu;
+
+ KASSERT(mp_ncpus <= 4, ("multiple clusters not yet supported"));
+
+ dcache_wbinv_poc_all();
+
+ bus_space_write_4(fdtbus_bs_tag, cpuscfg, CPUCFG_P_REG0,
+ pmap_kextract((vm_offset_t)mpentry));
+
+ cluster = 0;
+ for (cpu = 1; cpu < mp_ncpus; cpu++)
+ aw_mc_mp_start_cpu(cpuscfg, cpuxcfg, prcm, cluster, cpu);
+}
+
+void
+a83t_mp_start_ap(platform_t plat)
+{
+ bus_space_handle_t cpuscfg, cpuxcfg, prcm;
+
+ if (bus_space_map(fdtbus_bs_tag, CPUCFG_BASE, CPUCFG_SIZE,
+ 0, &cpuscfg) != 0)
+ panic("Couldn't map the CPUCFG\n");
+ if (bus_space_map(fdtbus_bs_tag, CPUXCFG_BASE, CPUXCFG_SIZE,
+ 0, &cpuxcfg) != 0)
+ panic("Couldn't map the CPUXCFG\n");
+ if (bus_space_map(fdtbus_bs_tag, PRCM_BASE, PRCM_SIZE, 0,
+ &prcm) != 0)
+ panic("Couldn't map the PRCM\n");
+
+ aw_mc_mp_start_ap(cpuscfg, cpuxcfg, prcm);
+ armv7_sev();
+ bus_space_unmap(fdtbus_bs_tag, cpuxcfg, CPUXCFG_SIZE);
+ bus_space_unmap(fdtbus_bs_tag, cpuscfg, CPUCFG_SIZE);
+ bus_space_unmap(fdtbus_bs_tag, prcm, PRCM_SIZE);
+}
diff --git a/sys/arm/allwinner/aw_mp.h b/sys/arm/allwinner/aw_mp.h
index 402147a..591ecea 100644
--- a/sys/arm/allwinner/aw_mp.h
+++ b/sys/arm/allwinner/aw_mp.h
@@ -31,5 +31,6 @@
void aw_mp_setmaxid(platform_t plat);
void a20_mp_start_ap(platform_t plat);
void a31_mp_start_ap(platform_t plat);
+void a83t_mp_start_ap(platform_t plat);
#endif /* _AW_MP_H_ */
diff --git a/sys/arm/allwinner/aw_nmi.c b/sys/arm/allwinner/aw_nmi.c
index 1cdd50e..2b23a4b 100644
--- a/sys/arm/allwinner/aw_nmi.c
+++ b/sys/arm/allwinner/aw_nmi.c
@@ -188,16 +188,18 @@ static int
aw_nmi_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct aw_nmi_softc *sc;
int error;
u_int irq;
- sc = device_get_softc(dev);
if (data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- error = aw_nmi_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
- NULL, NULL);
+ sc = device_get_softc(dev);
+ daf = (struct intr_map_data_fdt *)data;
+
+ error = aw_nmi_map_fdt(dev, daf->ncells, daf->cells, &irq, NULL, NULL);
if (error == 0)
*isrcp = &sc->intr.isrc;
@@ -208,6 +210,7 @@ static int
aw_nmi_setup_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
+ struct intr_map_data_fdt *daf;
struct aw_nmi_softc *sc;
struct aw_nmi_intr *nmi_intr;
int error, icfg;
@@ -215,14 +218,15 @@ aw_nmi_setup_intr(device_t dev, struct intr_irqsrc *isrc,
enum intr_trigger trig;
enum intr_polarity pol;
- sc = device_get_softc(dev);
- nmi_intr = (struct aw_nmi_intr *)isrc;
-
/* Get config for interrupt. */
if (data == NULL || data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- error = aw_nmi_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
- &pol, &trig);
+
+ sc = device_get_softc(dev);
+ nmi_intr = (struct aw_nmi_intr *)isrc;
+ daf = (struct intr_map_data_fdt *)data;
+
+ error = aw_nmi_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol, &trig);
if (error != 0)
return (error);
if (nmi_intr->irq != irq)
diff --git a/sys/arm/allwinner/aw_usbphy.c b/sys/arm/allwinner/aw_usbphy.c
index 25e8da0..31d2313 100644
--- a/sys/arm/allwinner/aw_usbphy.c
+++ b/sys/arm/allwinner/aw_usbphy.c
@@ -55,6 +55,7 @@ static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun5i-a13-usb-phy", 1 },
{ "allwinner,sun6i-a31-usb-phy", 1 },
{ "allwinner,sun7i-a20-usb-phy", 1 },
+ { "allwinner,sun8i-a83t-usb-phy", 1 },
{ NULL, 0 }
};
diff --git a/sys/arm/allwinner/clk/aw_ahbclk.c b/sys/arm/allwinner/clk/aw_ahbclk.c
index 1d3b1a4..00a0afe 100644
--- a/sys/arm/allwinner/clk/aw_ahbclk.c
+++ b/sys/arm/allwinner/clk/aw_ahbclk.c
@@ -63,16 +63,35 @@ __FBSDID("$FreeBSD$");
#define A31_AHB1_CLK_SRC_SEL_MAX 3
#define A31_AHB1_CLK_SRC_SEL_SHIFT 12
+#define A83T_AHB1_CLK_SRC_SEL (0x3 << 12)
+#define A83T_AHB1_CLK_SRC_SEL_ISPLL(x) ((x) & 0x2)
+#define A83T_AHB1_CLK_SRC_SEL_MAX 3
+#define A83T_AHB1_CLK_SRC_SEL_SHIFT 12
+#define A83T_AHB1_PRE_DIV (0x3 << 6)
+#define A83T_AHB1_PRE_DIV_SHIFT 6
+#define A83T_AHB1_CLK_DIV_RATIO (0x3 << 4)
+#define A83T_AHB1_CLK_DIV_RATIO_SHIFT 4
+
+#define H3_AHB2_CLK_CFG (0x3 << 0)
+#define H3_AHB2_CLK_CFG_SHIFT 0
+#define H3_AHB2_CLK_CFG_AHB1 0
+#define H3_AHB2_CLK_CFG_PLL_PERIPH_DIV2 1
+#define H3_AHB2_CLK_CFG_MAX 1
+
enum aw_ahbclk_type {
AW_A10_AHB = 1,
AW_A13_AHB,
AW_A31_AHB1,
+ AW_A83T_AHB1,
+ AW_H3_AHB2,
};
static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-ahb-clk", AW_A10_AHB },
{ "allwinner,sun5i-a13-ahb-clk", AW_A13_AHB },
{ "allwinner,sun6i-a31-ahb1-clk", AW_A31_AHB1 },
+ { "allwinner,sun8i-a83t-ahb1-clk", AW_A83T_AHB1 },
+ { "allwinner,sun8i-h3-ahb2-clk", AW_H3_AHB2 },
{ NULL, 0 }
};
@@ -113,6 +132,19 @@ aw_ahbclk_init(struct clknode *clk, device_t dev)
index = (val & A31_AHB1_CLK_SRC_SEL) >>
A31_AHB1_CLK_SRC_SEL_SHIFT;
break;
+ case AW_A83T_AHB1:
+ DEVICE_LOCK(sc);
+ AHBCLK_READ(sc, &val);
+ DEVICE_UNLOCK(sc);
+ index = (val & A83T_AHB1_CLK_SRC_SEL) >>
+ A83T_AHB1_CLK_SRC_SEL_SHIFT;
+ break;
+ case AW_H3_AHB2:
+ DEVICE_LOCK(sc);
+ AHBCLK_READ(sc, &val);
+ DEVICE_UNLOCK(sc);
+ index = (val & H3_AHB2_CLK_CFG) >> H3_AHB2_CLK_CFG_SHIFT;
+ break;
default:
return (ENXIO);
}
@@ -133,11 +165,10 @@ aw_ahbclk_recalc_freq(struct clknode *clk, uint64_t *freq)
AHBCLK_READ(sc, &val);
DEVICE_UNLOCK(sc);
- div = 1 << ((val & A10_AHB_CLK_DIV_RATIO) >>
- A10_AHB_CLK_DIV_RATIO_SHIFT);
-
switch (sc->type) {
case AW_A31_AHB1:
+ div = 1 << ((val & A10_AHB_CLK_DIV_RATIO) >>
+ A10_AHB_CLK_DIV_RATIO_SHIFT);
src_sel = (val & A31_AHB1_CLK_SRC_SEL) >>
A31_AHB1_CLK_SRC_SEL_SHIFT;
if (src_sel == A31_AHB1_CLK_SRC_SEL_PLL6)
@@ -146,7 +177,28 @@ aw_ahbclk_recalc_freq(struct clknode *clk, uint64_t *freq)
else
pre_div = 1;
break;
+ case AW_A83T_AHB1:
+ div = 1 << ((val & A83T_AHB1_CLK_DIV_RATIO) >>
+ A83T_AHB1_CLK_DIV_RATIO_SHIFT);
+ src_sel = (val & A83T_AHB1_CLK_SRC_SEL) >>
+ A83T_AHB1_CLK_SRC_SEL_SHIFT;
+ if (A83T_AHB1_CLK_SRC_SEL_ISPLL(src_sel))
+ pre_div = ((val & A83T_AHB1_PRE_DIV) >>
+ A83T_AHB1_PRE_DIV_SHIFT) + 1;
+ else
+ pre_div = 1;
+ break;
+ case AW_H3_AHB2:
+ src_sel = (val & H3_AHB2_CLK_CFG) >> H3_AHB2_CLK_CFG_SHIFT;
+ if (src_sel == H3_AHB2_CLK_CFG_PLL_PERIPH_DIV2)
+ div = 2;
+ else
+ div = 1;
+ pre_div = 1;
+ break;
default:
+ div = 1 << ((val & A10_AHB_CLK_DIV_RATIO) >>
+ A10_AHB_CLK_DIV_RATIO_SHIFT);
pre_div = 1;
break;
}
@@ -179,6 +231,26 @@ aw_ahbclk_set_mux(struct clknode *clk, int index)
AHBCLK_WRITE(sc, val);
DEVICE_UNLOCK(sc);
break;
+ case AW_A83T_AHB1:
+ if (index < 0 || index > A83T_AHB1_CLK_SRC_SEL_MAX)
+ return (ERANGE);
+ DEVICE_LOCK(sc);
+ AHBCLK_READ(sc, &val);
+ val &= ~A83T_AHB1_CLK_SRC_SEL;
+ val |= (index << A83T_AHB1_CLK_SRC_SEL_SHIFT);
+ AHBCLK_WRITE(sc, val);
+ DEVICE_UNLOCK(sc);
+ break;
+ case AW_H3_AHB2:
+ if (index < 0 || index > H3_AHB2_CLK_CFG)
+ return (ERANGE);
+ DEVICE_LOCK(sc);
+ AHBCLK_READ(sc, &val);
+ val &= ~H3_AHB2_CLK_CFG;
+ val |= (index << H3_AHB2_CLK_CFG_SHIFT);
+ AHBCLK_WRITE(sc, val);
+ DEVICE_UNLOCK(sc);
+ break;
default:
return (ENXIO);
}
diff --git a/sys/arm/allwinner/clk/aw_apbclk.c b/sys/arm/allwinner/clk/aw_apbclk.c
index a56387b..7620c45 100644
--- a/sys/arm/allwinner/clk/aw_apbclk.c
+++ b/sys/arm/allwinner/clk/aw_apbclk.c
@@ -49,24 +49,32 @@ __FBSDID("$FreeBSD$");
#include "clkdev_if.h"
-#define APB0_CLK_RATIO (0x3 << 8)
-#define APB0_CLK_RATIO_SHIFT 8
-#define APB1_CLK_SRC_SEL (0x3 << 24)
-#define APB1_CLK_SRC_SEL_SHIFT 24
-#define APB1_CLK_SRC_SEL_MAX 0x3
-#define APB1_CLK_RAT_N (0x3 << 16)
-#define APB1_CLK_RAT_N_SHIFT 16
-#define APB1_CLK_RAT_M (0x1f << 0)
-#define APB1_CLK_RAT_M_SHIFT 0
+#define A10_APB0_CLK_RATIO (0x3 << 8)
+#define A10_APB0_CLK_RATIO_SHIFT 8
+#define A10_APB1_CLK_SRC_SEL (0x3 << 24)
+#define A10_APB1_CLK_SRC_SEL_SHIFT 24
+#define A10_APB1_CLK_SRC_SEL_MAX 0x3
+#define A10_APB1_CLK_RAT_N (0x3 << 16)
+#define A10_APB1_CLK_RAT_N_SHIFT 16
+#define A10_APB1_CLK_RAT_M (0x1f << 0)
+#define A10_APB1_CLK_RAT_M_SHIFT 0
+#define A23_APB0_CLK_RATIO (0x3 << 0)
+#define A23_APB0_CLK_RATIO_SHIFT 0
+#define A83T_APB1_CLK_RATIO (0x3 << 8)
+#define A83T_APB1_CLK_RATIO_SHIFT 8
enum aw_apbclk_type {
AW_A10_APB0 = 1,
AW_A10_APB1,
+ AW_A23_APB0,
+ AW_A83T_APB1,
};
static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-apb0-clk", AW_A10_APB0 },
{ "allwinner,sun4i-a10-apb1-clk", AW_A10_APB1 },
+ { "allwinner,sun8i-a23-apb0-clk", AW_A23_APB0 },
+ { "allwinner,sun8i-a83t-apb1-clk", AW_A83T_APB1 },
{ NULL, 0 }
};
@@ -91,13 +99,16 @@ aw_apbclk_init(struct clknode *clk, device_t dev)
switch (sc->type) {
case AW_A10_APB0:
+ case AW_A23_APB0:
+ case AW_A83T_APB1:
index = 0;
break;
case AW_A10_APB1:
DEVICE_LOCK(sc);
APBCLK_READ(sc, &val);
DEVICE_UNLOCK(sc);
- index = (val & APB1_CLK_SRC_SEL) >> APB1_CLK_SRC_SEL_SHIFT;
+ index = (val & A10_APB1_CLK_SRC_SEL) >>
+ A10_APB1_CLK_SRC_SEL_SHIFT;
break;
default:
return (ENXIO);
@@ -121,16 +132,29 @@ aw_apbclk_recalc_freq(struct clknode *clk, uint64_t *freq)
switch (sc->type) {
case AW_A10_APB0:
- div = 1 << ((val & APB0_CLK_RATIO) >> APB0_CLK_RATIO_SHIFT);
+ div = 1 << ((val & A10_APB0_CLK_RATIO) >>
+ A10_APB0_CLK_RATIO_SHIFT);
if (div == 1)
div = 2;
*freq = *freq / div;
break;
case AW_A10_APB1:
- n = 1 << ((val & APB1_CLK_RAT_N) >> APB1_CLK_RAT_N_SHIFT);
- m = ((val & APB1_CLK_RAT_N) >> APB1_CLK_RAT_M_SHIFT) + 1;
+ n = 1 << ((val & A10_APB1_CLK_RAT_N) >>
+ A10_APB1_CLK_RAT_N_SHIFT);
+ m = ((val & A10_APB1_CLK_RAT_N) >>
+ A10_APB1_CLK_RAT_M_SHIFT) + 1;
*freq = *freq / n / m;
break;
+ case AW_A23_APB0:
+ div = 1 << ((val & A23_APB0_CLK_RATIO) >>
+ A23_APB0_CLK_RATIO_SHIFT);
+ *freq = *freq / div;
+ break;
+ case AW_A83T_APB1:
+ div = ((val & A83T_APB1_CLK_RATIO) >>
+ A83T_APB1_CLK_RATIO_SHIFT) + 1;
+ *freq = *freq / div;
+ break;
default:
return (ENXIO);
}
@@ -149,13 +173,13 @@ aw_apbclk_set_mux(struct clknode *clk, int index)
if (sc->type != AW_A10_APB1)
return (ENXIO);
- if (index < 0 || index > APB1_CLK_SRC_SEL_MAX)
+ if (index < 0 || index > A10_APB1_CLK_SRC_SEL_MAX)
return (ERANGE);
DEVICE_LOCK(sc);
APBCLK_READ(sc, &val);
- val &= ~APB1_CLK_SRC_SEL;
- val |= (index << APB1_CLK_SRC_SEL_SHIFT);
+ val &= ~A10_APB1_CLK_SRC_SEL;
+ val |= (index << A10_APB1_CLK_SRC_SEL_SHIFT);
APBCLK_WRITE(sc, val);
DEVICE_UNLOCK(sc);
diff --git a/sys/arm/allwinner/clk/aw_cpusclk.c b/sys/arm/allwinner/clk/aw_cpusclk.c
new file mode 100644
index 0000000..6d18284
--- /dev/null
+++ b/sys/arm/allwinner/clk/aw_cpusclk.c
@@ -0,0 +1,320 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Allwinner CPUS clock
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/ofw_subr.h>
+
+#include <dev/extres/clk/clk.h>
+
+#include "clkdev_if.h"
+
+#define A80_CPUS_CLK_SRC_SEL (0x3 << 16)
+#define A80_CPUS_CLK_SRC_SEL_SHIFT 16
+#define A80_CPUS_CLK_SRC_SEL_X32KI 0
+#define A80_CPUS_CLK_SRC_SEL_OSC24M 1
+#define A80_CPUS_CLK_SRC_SEL_PLL_PERIPH 2
+#define A80_CPUS_CLK_SRC_SEL_PLL_AUDIO 3
+#define A80_CPUS_POST_DIV (0x1f << 8)
+#define A80_CPUS_POST_DIV_SHIFT 8
+#define A80_CPUS_CLK_RATIO (0x3 << 4)
+#define A80_CPUS_CLK_RATIO_SHIFT 4
+
+#define A83T_CPUS_CLK_SRC_SEL (0x3 << 16)
+#define A83T_CPUS_CLK_SRC_SEL_SHIFT 16
+#define A83T_CPUS_CLK_SRC_SEL_X32KI 0
+#define A83T_CPUS_CLK_SRC_SEL_OSC24M 1
+#define A83T_CPUS_CLK_SRC_SEL_PLL_PERIPH 2
+#define A83T_CPUS_CLK_SRC_SEL_INTERNAL_OSC 3
+#define A83T_CPUS_POST_DIV (0x1f << 8)
+#define A83T_CPUS_POST_DIV_SHIFT 8
+#define A83T_CPUS_CLK_RATIO (0x3 << 4)
+#define A83T_CPUS_CLK_RATIO_SHIFT 4
+
+enum aw_cpusclk_type {
+ AW_A80_CPUS = 1,
+ AW_A83T_CPUS,
+};
+
+static struct ofw_compat_data compat_data[] = {
+ { "allwinner,sun9i-a80-cpus-clk", AW_A80_CPUS },
+ { "allwinner,sun8i-a83t-cpus-clk", AW_A83T_CPUS },
+ { NULL, 0 }
+};
+
+struct aw_cpusclk_sc {
+ device_t clkdev;
+ bus_addr_t reg;
+ enum aw_cpusclk_type type;
+};
+
+#define CPUSCLK_READ(sc, val) CLKDEV_READ_4((sc)->clkdev, (sc)->reg, (val))
+#define CPUSCLK_WRITE(sc, val) CLKDEV_WRITE_4((sc)->clkdev, (sc)->reg, (val))
+#define DEVICE_LOCK(sc) CLKDEV_DEVICE_LOCK((sc)->clkdev)
+#define DEVICE_UNLOCK(sc) CLKDEV_DEVICE_UNLOCK((sc)->clkdev)
+
+static int
+aw_cpusclk_init(struct clknode *clk, device_t dev)
+{
+ struct aw_cpusclk_sc *sc;
+ uint32_t val, mask, shift, index;
+
+ sc = clknode_get_softc(clk);
+
+ switch (sc->type) {
+ case AW_A80_CPUS:
+ mask = A80_CPUS_CLK_SRC_SEL;
+ shift = A80_CPUS_CLK_SRC_SEL_SHIFT;
+ break;
+ case AW_A83T_CPUS:
+ mask = A83T_CPUS_CLK_SRC_SEL;
+ shift = A83T_CPUS_CLK_SRC_SEL_SHIFT;
+ break;
+ default:
+ return (ENXIO);
+ }
+
+ DEVICE_LOCK(sc);
+ CPUSCLK_READ(sc, &val);
+ DEVICE_UNLOCK(sc);
+ index = (val & mask) >> shift;
+
+ clknode_init_parent_idx(clk, index);
+ return (0);
+}
+
+static int
+aw_cpusclk_recalc_freq(struct clknode *clk, uint64_t *freq)
+{
+ struct aw_cpusclk_sc *sc;
+ uint32_t val, src_sel, post_div, clk_ratio;
+
+ sc = clknode_get_softc(clk);
+
+ DEVICE_LOCK(sc);
+ CPUSCLK_READ(sc, &val);
+ DEVICE_UNLOCK(sc);
+
+ switch (sc->type) {
+ case AW_A80_CPUS:
+ src_sel = (val & A80_CPUS_CLK_SRC_SEL) >>
+ A80_CPUS_CLK_SRC_SEL_SHIFT;
+ post_div = ((val & A80_CPUS_POST_DIV) >>
+ A80_CPUS_POST_DIV_SHIFT) + 1;
+ clk_ratio = ((val & A80_CPUS_CLK_RATIO) >>
+ A80_CPUS_CLK_RATIO_SHIFT) + 1;
+ if (src_sel == A80_CPUS_CLK_SRC_SEL_PLL_PERIPH)
+ *freq = *freq / post_div / clk_ratio;
+ else
+ *freq = *freq / clk_ratio;
+ break;
+ case AW_A83T_CPUS:
+ src_sel = (val & A83T_CPUS_CLK_SRC_SEL) >>
+ A83T_CPUS_CLK_SRC_SEL_SHIFT;
+ post_div = ((val & A83T_CPUS_POST_DIV) >>
+ A83T_CPUS_POST_DIV_SHIFT) + 1;
+ clk_ratio = 1 << ((val & A83T_CPUS_CLK_RATIO) >>
+ A83T_CPUS_CLK_RATIO_SHIFT);
+ if (src_sel == A83T_CPUS_CLK_SRC_SEL_PLL_PERIPH)
+ *freq = *freq / post_div / clk_ratio;
+ else
+ *freq = *freq / clk_ratio;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
+static int
+aw_cpusclk_set_mux(struct clknode *clk, int index)
+{
+ struct aw_cpusclk_sc *sc;
+ uint32_t mask, shift, val;
+
+ sc = clknode_get_softc(clk);
+
+ switch (sc->type) {
+ case AW_A80_CPUS:
+ mask = A80_CPUS_CLK_SRC_SEL;
+ shift = A80_CPUS_CLK_SRC_SEL_SHIFT;
+ break;
+ case AW_A83T_CPUS:
+ mask = A83T_CPUS_CLK_SRC_SEL;
+ shift = A83T_CPUS_CLK_SRC_SEL_SHIFT;
+ break;
+ default:
+ return (ENXIO);
+ }
+
+ DEVICE_LOCK(sc);
+ CPUSCLK_READ(sc, &val);
+ val &= ~mask;
+ val |= (index << shift);
+ CPUSCLK_WRITE(sc, val);
+ DEVICE_UNLOCK(sc);
+
+ return (0);
+}
+
+static clknode_method_t aw_cpusclk_clknode_methods[] = {
+ /* Device interface */
+ CLKNODEMETHOD(clknode_init, aw_cpusclk_init),
+ CLKNODEMETHOD(clknode_recalc_freq, aw_cpusclk_recalc_freq),
+ CLKNODEMETHOD(clknode_set_mux, aw_cpusclk_set_mux),
+ CLKNODEMETHOD_END
+};
+DEFINE_CLASS_1(aw_cpusclk_clknode, aw_cpusclk_clknode_class,
+ aw_cpusclk_clknode_methods, sizeof(struct aw_cpusclk_sc), clknode_class);
+
+static int
+aw_cpusclk_probe(device_t dev)
+{
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Allwinner CPUS Clock");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+aw_cpusclk_attach(device_t dev)
+{
+ struct clknode_init_def def;
+ struct aw_cpusclk_sc *sc;
+ struct clkdom *clkdom;
+ struct clknode *clk;
+ clk_t clk_parent;
+ bus_addr_t paddr;
+ bus_size_t psize;
+ phandle_t node;
+ int error, ncells, i;
+
+ node = ofw_bus_get_node(dev);
+
+ if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) {
+ device_printf(dev, "cannot parse 'reg' property\n");
+ return (ENXIO);
+ }
+
+ error = ofw_bus_parse_xref_list_get_length(node, "clocks",
+ "#clock-cells", &ncells);
+ if (error != 0) {
+ device_printf(dev, "cannot get clock count\n");
+ return (error);
+ }
+
+ clkdom = clkdom_create(dev);
+
+ memset(&def, 0, sizeof(def));
+ def.id = 1;
+ def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP,
+ M_WAITOK);
+ for (i = 0; i < ncells; i++) {
+ error = clk_get_by_ofw_index(dev, i, &clk_parent);
+ if (error != 0) {
+ device_printf(dev, "cannot get clock %d\n", i);
+ goto fail;
+ }
+ def.parent_names[i] = clk_get_name(clk_parent);
+ clk_release(clk_parent);
+ }
+ def.parent_cnt = ncells;
+
+ error = clk_parse_ofw_clk_name(dev, node, &def.name);
+ if (error != 0) {
+ device_printf(dev, "cannot parse clock name\n");
+ error = ENXIO;
+ goto fail;
+ }
+
+ clk = clknode_create(clkdom, &aw_cpusclk_clknode_class, &def);
+ if (clk == NULL) {
+ device_printf(dev, "cannot create clknode\n");
+ error = ENXIO;
+ goto fail;
+ }
+ sc = clknode_get_softc(clk);
+ sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+ sc->reg = paddr;
+ sc->clkdev = device_get_parent(dev);
+
+ clknode_register(clkdom, clk);
+
+ if (clkdom_finit(clkdom) != 0) {
+ device_printf(dev, "cannot finalize clkdom initialization\n");
+ error = ENXIO;
+ goto fail;
+ }
+
+ if (bootverbose)
+ clkdom_dump(clkdom);
+
+ return (0);
+
+fail:
+ return (error);
+}
+
+static device_method_t aw_cpusclk_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, aw_cpusclk_probe),
+ DEVMETHOD(device_attach, aw_cpusclk_attach),
+
+ DEVMETHOD_END
+};
+
+static driver_t aw_cpusclk_driver = {
+ "aw_cpusclk",
+ aw_cpusclk_methods,
+ 0
+};
+
+static devclass_t aw_cpusclk_devclass;
+
+EARLY_DRIVER_MODULE(aw_cpusclk, simplebus, aw_cpusclk_driver,
+ aw_cpusclk_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
diff --git a/sys/arm/allwinner/clk/aw_gate.c b/sys/arm/allwinner/clk/aw_gate.c
index d43d021..6634c57 100644
--- a/sys/arm/allwinner/clk/aw_gate.c
+++ b/sys/arm/allwinner/clk/aw_gate.c
@@ -76,6 +76,14 @@ static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun6i-a31-apb2-gates-clk",
(uintptr_t)"Allwinner APB2 Clock Gates" },
+ { "allwinner,sun8i-a83t-bus-gates-clk",
+ (uintptr_t)"Allwinner Bus Clock Gates" },
+ { "allwinner,sun8i-a83t-apb0-gates-clk",
+ (uintptr_t)"Allwinner APB0 Clock Gates" },
+
+ { "allwinner,sun9i-a80-apbs-gates-clk",
+ (uintptr_t)"Allwinner APBS Clock Gates" },
+
{ NULL, 0 }
};
diff --git a/sys/arm/allwinner/clk/aw_gmacclk.c b/sys/arm/allwinner/clk/aw_gmacclk.c
index 5e2f618..72495fd 100644
--- a/sys/arm/allwinner/clk/aw_gmacclk.c
+++ b/sys/arm/allwinner/clk/aw_gmacclk.c
@@ -60,18 +60,41 @@ __FBSDID("$FreeBSD$");
#define GMAC_CLK_SRC_EXT_RGMII 1
#define GMAC_CLK_SRC_RGMII 2
+#define EMAC_TXC_DIV_CFG (1 << 15)
+#define EMAC_TXC_DIV_CFG_SHIFT 15
+#define EMAC_TXC_DIV_CFG_125MHZ 0
+#define EMAC_TXC_DIV_CFG_25MHZ 1
+#define EMAC_PHY_SELECT (1 << 16)
+#define EMAC_PHY_SELECT_SHIFT 16
+#define EMAC_PHY_SELECT_INT 0
+#define EMAC_PHY_SELECT_EXT 1
+#define EMAC_ETXDC (0x7 << 10)
+#define EMAC_ETXDC_SHIFT 10
+#define EMAC_ERXDC (0x1f << 5)
+#define EMAC_ERXDC_SHIFT 5
+
#define CLK_IDX_MII 0
#define CLK_IDX_RGMII 1
#define CLK_IDX_COUNT 2
+enum aw_gmacclk_type {
+ GMACCLK_A20 = 1,
+ GMACCLK_A83T,
+};
+
static struct ofw_compat_data compat_data[] = {
- { "allwinner,sun7i-a20-gmac-clk", 1 },
+ { "allwinner,sun7i-a20-gmac-clk", GMACCLK_A20 },
+ { "allwinner,sun8i-a83t-emac-clk", GMACCLK_A83T },
{ NULL, 0 }
};
struct aw_gmacclk_sc {
device_t clkdev;
bus_addr_t reg;
+ enum aw_gmacclk_type type;
+
+ int rx_delay;
+ int tx_delay;
};
#define GMACCLK_READ(sc, val) CLKDEV_READ_4((sc)->clkdev, (sc)->reg, (val))
@@ -110,7 +133,7 @@ static int
aw_gmacclk_set_mux(struct clknode *clk, int index)
{
struct aw_gmacclk_sc *sc;
- uint32_t val, clk_src, pit;
+ uint32_t val, clk_src, pit, txc_div;
int error;
sc = clknode_get_softc(clk);
@@ -120,10 +143,12 @@ aw_gmacclk_set_mux(struct clknode *clk, int index)
case CLK_IDX_MII:
clk_src = GMAC_CLK_SRC_MII;
pit = GMAC_CLK_PIT_MII;
+ txc_div = EMAC_TXC_DIV_CFG_25MHZ;
break;
case CLK_IDX_RGMII:
clk_src = GMAC_CLK_SRC_RGMII;
pit = GMAC_CLK_PIT_RGMII;
+ txc_div = EMAC_TXC_DIV_CFG_125MHZ;
break;
default:
return (ENXIO);
@@ -134,6 +159,20 @@ aw_gmacclk_set_mux(struct clknode *clk, int index)
val &= ~(GMAC_CLK_SRC | GMAC_CLK_PIT);
val |= (clk_src << GMAC_CLK_SRC_SHIFT);
val |= (pit << GMAC_CLK_PIT_SHIFT);
+ if (sc->type == GMACCLK_A83T) {
+ val &= ~EMAC_TXC_DIV_CFG;
+ val |= (txc_div << EMAC_TXC_DIV_CFG_SHIFT);
+ val &= ~EMAC_PHY_SELECT;
+ val |= (EMAC_PHY_SELECT_EXT << EMAC_PHY_SELECT_SHIFT);
+ if (sc->tx_delay >= 0) {
+ val &= ~EMAC_ETXDC;
+ val |= (sc->tx_delay << EMAC_ETXDC_SHIFT);
+ }
+ if (sc->rx_delay >= 0) {
+ val &= ~EMAC_ERXDC;
+ val |= (sc->rx_delay << EMAC_ERXDC_SHIFT);
+ }
+ }
GMACCLK_WRITE(sc, val);
DEVICE_UNLOCK(sc);
@@ -158,7 +197,7 @@ aw_gmacclk_probe(device_t dev)
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
return (ENXIO);
- device_set_desc(dev, "Allwinner Module Clock");
+ device_set_desc(dev, "Allwinner GMAC Clock");
return (BUS_PROBE_DEFAULT);
}
@@ -221,6 +260,10 @@ aw_gmacclk_attach(device_t dev)
sc = clknode_get_softc(clk);
sc->reg = paddr;
sc->clkdev = device_get_parent(dev);
+ sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+ sc->tx_delay = sc->rx_delay = -1;
+ OF_getencprop(node, "tx-delay", &sc->tx_delay, sizeof(sc->tx_delay));
+ OF_getencprop(node, "rx-delay", &sc->rx_delay, sizeof(sc->rx_delay));
clknode_register(clkdom, clk);
diff --git a/sys/arm/allwinner/clk/aw_pll.c b/sys/arm/allwinner/clk/aw_pll.c
index 2e67646..b7c2a7e 100644
--- a/sys/arm/allwinner/clk/aw_pll.c
+++ b/sys/arm/allwinner/clk/aw_pll.c
@@ -124,6 +124,12 @@ __FBSDID("$FreeBSD$");
#define A31_PLL6_DEFAULT_K 0x1
#define A31_PLL6_TIMEOUT 10
+#define A80_PLL4_CLK_OUT_EN (1 << 20)
+#define A80_PLL4_PLL_DIV2 (1 << 18)
+#define A80_PLL4_PLL_DIV1 (1 << 16)
+#define A80_PLL4_FACTOR_N (0xff << 8)
+#define A80_PLL4_FACTOR_N_SHIFT 8
+
#define CLKID_A10_PLL3_1X 0
#define CLKID_A10_PLL3_2X 1
@@ -146,6 +152,7 @@ enum aw_pll_type {
AWPLL_A10_PLL6,
AWPLL_A31_PLL1,
AWPLL_A31_PLL6,
+ AWPLL_A80_PLL4,
};
struct aw_pll_sc {
@@ -524,6 +531,24 @@ a31_pll6_recalc(struct aw_pll_sc *sc, uint64_t *freq)
return (0);
}
+static int
+a80_pll4_recalc(struct aw_pll_sc *sc, uint64_t *freq)
+{
+ uint32_t val, n, div1, div2;
+
+ DEVICE_LOCK(sc);
+ PLL_READ(sc, &val);
+ DEVICE_UNLOCK(sc);
+
+ n = (val & A80_PLL4_FACTOR_N) >> A80_PLL4_FACTOR_N_SHIFT;
+ div1 = (val & A80_PLL4_PLL_DIV1) == 0 ? 1 : 2;
+ div2 = (val & A80_PLL4_PLL_DIV2) == 0 ? 1 : 2;
+
+ *freq = (*freq * n) / div1 / div2;
+
+ return (0);
+}
+
#define PLL(_type, _recalc, _set_freq, _init) \
[(_type)] = { \
.recalc = (_recalc), \
@@ -539,6 +564,7 @@ static struct aw_pll_funcs aw_pll_func[] = {
PLL(AWPLL_A10_PLL6, a10_pll6_recalc, a10_pll6_set_freq, a10_pll6_init),
PLL(AWPLL_A31_PLL1, a31_pll1_recalc, NULL, NULL),
PLL(AWPLL_A31_PLL6, a31_pll6_recalc, NULL, a31_pll6_init),
+ PLL(AWPLL_A80_PLL4, a80_pll4_recalc, NULL, NULL),
};
static struct ofw_compat_data compat_data[] = {
@@ -549,6 +575,7 @@ static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-pll6-clk", AWPLL_A10_PLL6 },
{ "allwinner,sun6i-a31-pll1-clk", AWPLL_A31_PLL1 },
{ "allwinner,sun6i-a31-pll6-clk", AWPLL_A31_PLL6 },
+ { "allwinner,sun9i-a80-pll4-clk", AWPLL_A80_PLL4 },
{ NULL, 0 }
};
diff --git a/sys/arm/allwinner/clk/aw_usbclk.c b/sys/arm/allwinner/clk/aw_usbclk.c
index bac9991..cd935c4 100644
--- a/sys/arm/allwinner/clk/aw_usbclk.c
+++ b/sys/arm/allwinner/clk/aw_usbclk.c
@@ -62,11 +62,13 @@ __FBSDID("$FreeBSD$");
enum aw_usbclk_type {
AW_A10_USBCLK = 1,
AW_A31_USBCLK,
+ AW_A83T_USBCLK,
};
static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-usb-clk", AW_A10_USBCLK },
{ "allwinner,sun6i-a31-usb-clk", AW_A31_USBCLK },
+ { "allwinner,sun8i-a83t-usb-clk", AW_A83T_USBCLK },
{ NULL, 0 }
};
@@ -162,10 +164,11 @@ aw_usbclk_attach(device_t dev)
struct aw_usbclk_softc *sc;
struct clkdom *clkdom;
const char **names;
+ const char *pname;
int index, nout, error;
enum aw_usbclk_type type;
uint32_t *indices;
- clk_t clk_parent;
+ clk_t clk_parent, clk_parent_pll;
bus_size_t psize;
phandle_t node;
@@ -196,11 +199,21 @@ aw_usbclk_attach(device_t dev)
device_printf(dev, "cannot parse clock parent\n");
return (ENXIO);
}
+ if (type == AW_A83T_USBCLK) {
+ error = clk_get_by_ofw_index(dev, 1, &clk_parent_pll);
+ if (error != 0) {
+ device_printf(dev, "cannot parse pll clock parent\n");
+ return (ENXIO);
+ }
+ }
for (index = 0; index < nout; index++) {
- error = aw_usbclk_create(dev, sc->reg, clkdom,
- clk_get_name(clk_parent), names[index],
- indices != NULL ? indices[index] : index);
+ if (strcmp(names[index], "usb_hsic_pll") == 0)
+ pname = clk_get_name(clk_parent_pll);
+ else
+ pname = clk_get_name(clk_parent);
+ error = aw_usbclk_create(dev, sc->reg, clkdom, pname,
+ names[index], indices != NULL ? indices[index] : index);
if (error)
goto fail;
}
diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner
index d02a868..a138989 100644
--- a/sys/arm/allwinner/files.allwinner
+++ b/sys/arm/allwinner/files.allwinner
@@ -18,6 +18,7 @@ arm/allwinner/a20/a20_cpu_cfg.c standard
arm/allwinner/allwinner_machdep.c standard
arm/allwinner/aw_mp.c optional smp
arm/allwinner/axp209.c optional axp209
+arm/allwinner/if_awg.c optional awg
arm/allwinner/if_emac.c optional emac
arm/allwinner/sunxi_dma_if.m standard
dev/iicbus/twsi/a10_twsi.c optional twsi
@@ -35,6 +36,7 @@ arm/allwinner/clk/aw_apbclk.c standard
arm/allwinner/clk/aw_axiclk.c standard
arm/allwinner/clk/aw_codecclk.c standard
arm/allwinner/clk/aw_cpuclk.c standard
+arm/allwinner/clk/aw_cpusclk.c standard
arm/allwinner/clk/aw_debeclk.c standard
arm/allwinner/clk/aw_gate.c standard
arm/allwinner/clk/aw_gmacclk.c standard
diff --git a/sys/arm/allwinner/if_awg.c b/sys/arm/allwinner/if_awg.c
new file mode 100644
index 0000000..87606c3
--- /dev/null
+++ b/sys/arm/allwinner/if_awg.c
@@ -0,0 +1,1418 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Allwinner Gigabit Ethernet MAC (EMAC) controller
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/endian.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/module.h>
+#include <sys/taskqueue.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/allwinner/if_awgreg.h>
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+#include <dev/extres/regulator/regulator.h>
+
+#include "miibus_if.h"
+
+#define RD4(sc, reg) bus_read_4((sc)->res[0], (reg))
+#define WR4(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val))
+
+#define AWG_LOCK(sc) mtx_lock(&(sc)->mtx)
+#define AWG_UNLOCK(sc) mtx_unlock(&(sc)->mtx);
+#define AWG_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED)
+#define AWG_ASSERT_UNLOCKED(sc) mtx_assert(&(sc)->mtx, MA_NOTOWNED)
+
+#define DESC_ALIGN 4
+#define TX_DESC_COUNT 256
+#define TX_DESC_SIZE (sizeof(struct emac_desc) * TX_DESC_COUNT)
+#define RX_DESC_COUNT 256
+#define RX_DESC_SIZE (sizeof(struct emac_desc) * RX_DESC_COUNT)
+
+#define DESC_OFF(n) ((n) * sizeof(struct emac_desc))
+#define TX_NEXT(n) (((n) + 1) & (TX_DESC_COUNT - 1))
+#define TX_SKIP(n, o) (((n) + (o)) & (TX_DESC_COUNT - 1))
+#define RX_NEXT(n) (((n) + 1) & (RX_DESC_COUNT - 1))
+
+#define TX_MAX_SEGS 10
+
+#define SOFT_RST_RETRY 1000
+#define MII_BUSY_RETRY 1000
+#define MDIO_FREQ 2500000
+
+#define BURST_LEN_DEFAULT 8
+#define RX_TX_PRI_DEFAULT 0
+#define PAUSE_TIME_DEFAULT 0x400
+#define TX_INTERVAL_DEFAULT 64
+
+/* Burst length of RX and TX DMA transfers */
+static int awg_burst_len = BURST_LEN_DEFAULT;
+TUNABLE_INT("hw.awg.burst_len", &awg_burst_len);
+
+/* RX / TX DMA priority. If 1, RX DMA has priority over TX DMA. */
+static int awg_rx_tx_pri = RX_TX_PRI_DEFAULT;
+TUNABLE_INT("hw.awg.rx_tx_pri", &awg_rx_tx_pri);
+
+/* Pause time field in the transmitted control frame */
+static int awg_pause_time = PAUSE_TIME_DEFAULT;
+TUNABLE_INT("hw.awg.pause_time", &awg_pause_time);
+
+/* Request a TX interrupt every <n> descriptors */
+static int awg_tx_interval = TX_INTERVAL_DEFAULT;
+TUNABLE_INT("hw.awg.tx_interval", &awg_tx_interval);
+
+static struct ofw_compat_data compat_data[] = {
+ { "allwinner,sun8i-a83t-emac", 1 },
+ { NULL, 0 }
+};
+
+struct awg_bufmap {
+ bus_dmamap_t map;
+ struct mbuf *mbuf;
+};
+
+struct awg_txring {
+ bus_dma_tag_t desc_tag;
+ bus_dmamap_t desc_map;
+ struct emac_desc *desc_ring;
+ bus_addr_t desc_ring_paddr;
+ bus_dma_tag_t buf_tag;
+ struct awg_bufmap buf_map[TX_DESC_COUNT];
+ u_int cur, next, queued;
+};
+
+struct awg_rxring {
+ bus_dma_tag_t desc_tag;
+ bus_dmamap_t desc_map;
+ struct emac_desc *desc_ring;
+ bus_addr_t desc_ring_paddr;
+ bus_dma_tag_t buf_tag;
+ struct awg_bufmap buf_map[RX_DESC_COUNT];
+ u_int cur;
+};
+
+struct awg_softc {
+ struct resource *res[2];
+ struct mtx mtx;
+ if_t ifp;
+ device_t miibus;
+ struct callout stat_ch;
+ struct task link_task;
+ void *ih;
+ u_int mdc_div_ratio_m;
+ int link;
+ int if_flags;
+
+ struct awg_txring tx;
+ struct awg_rxring rx;
+};
+
+static struct resource_spec awg_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static int
+awg_miibus_readreg(device_t dev, int phy, int reg)
+{
+ struct awg_softc *sc;
+ int retry, val;
+
+ sc = device_get_softc(dev);
+ val = 0;
+
+ WR4(sc, EMAC_MII_CMD,
+ (sc->mdc_div_ratio_m << MDC_DIV_RATIO_M_SHIFT) |
+ (phy << PHY_ADDR_SHIFT) |
+ (reg << PHY_REG_ADDR_SHIFT) |
+ MII_BUSY);
+ for (retry = MII_BUSY_RETRY; retry > 0; retry--) {
+ if ((RD4(sc, EMAC_MII_CMD) & MII_BUSY) == 0) {
+ val = RD4(sc, EMAC_MII_DATA);
+ break;
+ }
+ DELAY(10);
+ }
+
+ if (retry == 0)
+ device_printf(dev, "phy read timeout, phy=%d reg=%d\n",
+ phy, reg);
+
+ return (val);
+}
+
+static int
+awg_miibus_writereg(device_t dev, int phy, int reg, int val)
+{
+ struct awg_softc *sc;
+ int retry;
+
+ sc = device_get_softc(dev);
+
+ WR4(sc, EMAC_MII_DATA, val);
+ WR4(sc, EMAC_MII_CMD,
+ (sc->mdc_div_ratio_m << MDC_DIV_RATIO_M_SHIFT) |
+ (phy << PHY_ADDR_SHIFT) |
+ (reg << PHY_REG_ADDR_SHIFT) |
+ MII_WR | MII_BUSY);
+ for (retry = MII_BUSY_RETRY; retry > 0; retry--) {
+ if ((RD4(sc, EMAC_MII_CMD) & MII_BUSY) == 0)
+ break;
+ DELAY(10);
+ }
+
+ if (retry == 0)
+ device_printf(dev, "phy write timeout, phy=%d reg=%d\n",
+ phy, reg);
+
+ return (0);
+}
+
+static void
+awg_update_link_locked(struct awg_softc *sc)
+{
+ struct mii_data *mii;
+ uint32_t val;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ if ((if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) == 0)
+ return;
+ mii = device_get_softc(sc->miibus);
+
+ if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+ (IFM_ACTIVE | IFM_AVALID)) {
+ switch (IFM_SUBTYPE(mii->mii_media_active)) {
+ case IFM_1000_T:
+ case IFM_1000_SX:
+ case IFM_100_TX:
+ case IFM_10_T:
+ sc->link = 1;
+ break;
+ default:
+ sc->link = 0;
+ break;
+ }
+ } else
+ sc->link = 0;
+
+ if (sc->link == 0)
+ return;
+
+ val = RD4(sc, EMAC_BASIC_CTL_0);
+ val &= ~(BASIC_CTL_SPEED | BASIC_CTL_DUPLEX);
+
+ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
+ IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX)
+ val |= BASIC_CTL_SPEED_1000 << BASIC_CTL_SPEED_SHIFT;
+ else if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
+ val |= BASIC_CTL_SPEED_100 << BASIC_CTL_SPEED_SHIFT;
+ else
+ val |= BASIC_CTL_SPEED_10 << BASIC_CTL_SPEED_SHIFT;
+
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
+ val |= BASIC_CTL_DUPLEX;
+
+ WR4(sc, EMAC_BASIC_CTL_0, val);
+
+ val = RD4(sc, EMAC_RX_CTL_0);
+ val &= ~RX_FLOW_CTL_EN;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
+ val |= RX_FLOW_CTL_EN;
+ WR4(sc, EMAC_RX_CTL_0, val);
+
+ val = RD4(sc, EMAC_TX_FLOW_CTL);
+ val &= ~(PAUSE_TIME|TX_FLOW_CTL_EN);
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
+ val |= TX_FLOW_CTL_EN;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
+ val |= awg_pause_time << PAUSE_TIME_SHIFT;
+ WR4(sc, EMAC_TX_FLOW_CTL, val);
+}
+
+static void
+awg_link_task(void *arg, int pending)
+{
+ struct awg_softc *sc;
+
+ sc = arg;
+
+ AWG_LOCK(sc);
+ awg_update_link_locked(sc);
+ AWG_UNLOCK(sc);
+}
+
+static void
+awg_miibus_statchg(device_t dev)
+{
+ struct awg_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ taskqueue_enqueue(taskqueue_swi, &sc->link_task);
+}
+
+static void
+awg_media_status(if_t ifp, struct ifmediareq *ifmr)
+{
+ struct awg_softc *sc;
+ struct mii_data *mii;
+
+ sc = if_getsoftc(ifp);
+ mii = device_get_softc(sc->miibus);
+
+ AWG_LOCK(sc);
+ mii_pollstat(mii);
+ ifmr->ifm_active = mii->mii_media_active;
+ ifmr->ifm_status = mii->mii_media_status;
+ AWG_UNLOCK(sc);
+}
+
+static int
+awg_media_change(if_t ifp)
+{
+ struct awg_softc *sc;
+ struct mii_data *mii;
+ int error;
+
+ sc = if_getsoftc(ifp);
+ mii = device_get_softc(sc->miibus);
+
+ AWG_LOCK(sc);
+ error = mii_mediachg(mii);
+ AWG_UNLOCK(sc);
+
+ return (error);
+}
+
+static void
+awg_setup_txdesc(struct awg_softc *sc, int index, int flags, bus_addr_t paddr,
+ u_int len)
+{
+ uint32_t status, size;
+
+ if (paddr == 0 || len == 0) {
+ status = 0;
+ size = 0;
+ --sc->tx.queued;
+ } else {
+ status = TX_DESC_CTL;
+ size = flags | len;
+ if ((index & (awg_tx_interval - 1)) == 0)
+ size |= htole32(TX_INT_CTL);
+ ++sc->tx.queued;
+ }
+
+ sc->tx.desc_ring[index].addr = htole32((uint32_t)paddr);
+ sc->tx.desc_ring[index].size = htole32(size);
+ sc->tx.desc_ring[index].status = htole32(status);
+}
+
+static int
+awg_setup_txbuf(struct awg_softc *sc, int index, struct mbuf **mp)
+{
+ bus_dma_segment_t segs[TX_MAX_SEGS];
+ int error, nsegs, cur, i, flags;
+ u_int csum_flags;
+ struct mbuf *m;
+
+ m = *mp;
+ error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag,
+ sc->tx.buf_map[index].map, m, segs, &nsegs, BUS_DMA_NOWAIT);
+ if (error == EFBIG) {
+ m = m_collapse(m, M_NOWAIT, TX_MAX_SEGS);
+ if (m == NULL)
+ return (0);
+ *mp = m;
+ error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag,
+ sc->tx.buf_map[index].map, m, segs, &nsegs, BUS_DMA_NOWAIT);
+ }
+ if (error != 0)
+ return (0);
+
+ bus_dmamap_sync(sc->tx.buf_tag, sc->tx.buf_map[index].map,
+ BUS_DMASYNC_PREWRITE);
+
+ flags = TX_FIR_DESC;
+ if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0) {
+ if ((m->m_pkthdr.csum_flags & (CSUM_TCP|CSUM_UDP)) != 0)
+ csum_flags = TX_CHECKSUM_CTL_FULL;
+ else
+ csum_flags = TX_CHECKSUM_CTL_IP;
+ flags |= (csum_flags << TX_CHECKSUM_CTL_SHIFT);
+ }
+
+ for (cur = index, i = 0; i < nsegs; i++) {
+ sc->tx.buf_map[cur].mbuf = (i == 0 ? m : NULL);
+ if (i == nsegs - 1)
+ flags |= TX_LAST_DESC;
+ awg_setup_txdesc(sc, cur, flags, segs[i].ds_addr,
+ segs[i].ds_len);
+ flags &= ~TX_FIR_DESC;
+ cur = TX_NEXT(cur);
+ }
+
+ return (nsegs);
+}
+
+static void
+awg_setup_rxdesc(struct awg_softc *sc, int index, bus_addr_t paddr)
+{
+ uint32_t status, size;
+
+ status = RX_DESC_CTL;
+ size = MCLBYTES - 1;
+
+ sc->rx.desc_ring[index].addr = htole32((uint32_t)paddr);
+ sc->rx.desc_ring[index].size = htole32(size);
+ sc->rx.desc_ring[index].next =
+ htole32(sc->rx.desc_ring_paddr + DESC_OFF(RX_NEXT(index)));
+ sc->rx.desc_ring[index].status = htole32(status);
+}
+
+static int
+awg_setup_rxbuf(struct awg_softc *sc, int index, struct mbuf *m)
+{
+ bus_dma_segment_t seg;
+ int error, nsegs;
+
+ m_adj(m, ETHER_ALIGN);
+
+ error = bus_dmamap_load_mbuf_sg(sc->rx.buf_tag,
+ sc->rx.buf_map[index].map, m, &seg, &nsegs, 0);
+ if (error != 0)
+ return (error);
+
+ bus_dmamap_sync(sc->rx.buf_tag, sc->rx.buf_map[index].map,
+ BUS_DMASYNC_PREREAD);
+
+ sc->rx.buf_map[index].mbuf = m;
+ awg_setup_rxdesc(sc, index, seg.ds_addr);
+
+ return (0);
+}
+
+static struct mbuf *
+awg_alloc_mbufcl(struct awg_softc *sc)
+{
+ struct mbuf *m;
+
+ m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+ if (m != NULL)
+ m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
+
+ return (m);
+}
+
+static void
+awg_start_locked(struct awg_softc *sc)
+{
+ struct mbuf *m;
+ uint32_t val;
+ if_t ifp;
+ int cnt, nsegs;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ if (!sc->link)
+ return;
+
+ ifp = sc->ifp;
+
+ if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
+ return;
+
+ for (cnt = 0; ; cnt++) {
+ if (sc->tx.queued >= TX_DESC_COUNT - TX_MAX_SEGS) {
+ if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0);
+ break;
+ }
+
+ m = if_dequeue(ifp);
+ if (m == NULL)
+ break;
+
+ nsegs = awg_setup_txbuf(sc, sc->tx.cur, &m);
+ if (nsegs == 0) {
+ if_sendq_prepend(ifp, m);
+ break;
+ }
+ if_bpfmtap(ifp, m);
+ sc->tx.cur = TX_SKIP(sc->tx.cur, nsegs);
+ }
+
+ if (cnt != 0) {
+ bus_dmamap_sync(sc->tx.desc_tag, sc->tx.desc_map,
+ BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+
+ /* Start and run TX DMA */
+ val = RD4(sc, EMAC_TX_CTL_1);
+ WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_START);
+ }
+}
+
+static void
+awg_start(if_t ifp)
+{
+ struct awg_softc *sc;
+
+ sc = if_getsoftc(ifp);
+
+ AWG_LOCK(sc);
+ awg_start_locked(sc);
+ AWG_UNLOCK(sc);
+}
+
+static void
+awg_tick(void *softc)
+{
+ struct awg_softc *sc;
+ struct mii_data *mii;
+ if_t ifp;
+ int link;
+
+ sc = softc;
+ ifp = sc->ifp;
+ mii = device_get_softc(sc->miibus);
+
+ AWG_ASSERT_LOCKED(sc);
+
+ if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
+ return;
+
+ link = sc->link;
+ mii_tick(mii);
+ if (sc->link && !link)
+ awg_start_locked(sc);
+
+ callout_reset(&sc->stat_ch, hz, awg_tick, sc);
+}
+
+/* Bit Reversal - http://aggregate.org/MAGIC/#Bit%20Reversal */
+static uint32_t
+bitrev32(uint32_t x)
+{
+ x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+ x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+ x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+ x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+
+ return (x >> 16) | (x << 16);
+}
+
+static void
+awg_setup_rxfilter(struct awg_softc *sc)
+{
+ uint32_t val, crc, hashreg, hashbit, hash[2], machi, maclo;
+ int mc_count, mcnt, i;
+ uint8_t *eaddr, *mta;
+ if_t ifp;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ ifp = sc->ifp;
+ val = 0;
+ hash[0] = hash[1] = 0;
+
+ mc_count = if_multiaddr_count(ifp, -1);
+
+ if (if_getflags(ifp) & IFF_PROMISC)
+ val |= DIS_ADDR_FILTER;
+ else if (if_getflags(ifp) & IFF_ALLMULTI) {
+ val |= RX_ALL_MULTICAST;
+ hash[0] = hash[1] = ~0;
+ } else if (mc_count > 0) {
+ val |= HASH_MULTICAST;
+
+ mta = malloc(sizeof(unsigned char) * ETHER_ADDR_LEN * mc_count,
+ M_DEVBUF, M_NOWAIT);
+ if (mta == NULL) {
+ if_printf(ifp,
+ "failed to allocate temporary multicast list\n");
+ return;
+ }
+
+ if_multiaddr_array(ifp, mta, &mcnt, mc_count);
+ for (i = 0; i < mcnt; i++) {
+ crc = ether_crc32_le(mta + (i * ETHER_ADDR_LEN),
+ ETHER_ADDR_LEN) & 0x7f;
+ crc = bitrev32(~crc) >> 26;
+ hashreg = (crc >> 5);
+ hashbit = (crc & 0x1f);
+ hash[hashreg] |= (1 << hashbit);
+ }
+
+ free(mta, M_DEVBUF);
+ }
+
+ /* Write our unicast address */
+ eaddr = IF_LLADDR(ifp);
+ machi = (eaddr[5] << 8) | eaddr[4];
+ maclo = (eaddr[3] << 24) | (eaddr[2] << 16) | (eaddr[1] << 8) |
+ (eaddr[0] << 0);
+ WR4(sc, EMAC_ADDR_HIGH(0), machi);
+ WR4(sc, EMAC_ADDR_LOW(0), maclo);
+
+ /* Multicast hash filters */
+ WR4(sc, EMAC_RX_HASH_0, hash[1]);
+ WR4(sc, EMAC_RX_HASH_1, hash[0]);
+
+ /* RX frame filter config */
+ WR4(sc, EMAC_RX_FRM_FLT, val);
+}
+
+static void
+awg_init_locked(struct awg_softc *sc)
+{
+ struct mii_data *mii;
+ uint32_t val;
+ if_t ifp;
+
+ mii = device_get_softc(sc->miibus);
+ ifp = sc->ifp;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
+ return;
+
+ awg_setup_rxfilter(sc);
+
+ /* Configure DMA burst length and priorities */
+ val = awg_burst_len << BASIC_CTL_BURST_LEN_SHIFT;
+ if (awg_rx_tx_pri)
+ val |= BASIC_CTL_RX_TX_PRI;
+ WR4(sc, EMAC_BASIC_CTL_1, val);
+
+ /* Enable interrupts */
+ WR4(sc, EMAC_INT_EN, RX_INT_EN | TX_INT_EN | TX_BUF_UA_INT_EN);
+
+ /* Enable transmit DMA */
+ val = RD4(sc, EMAC_TX_CTL_1);
+ WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_EN | TX_MD);
+
+ /* Enable receive DMA */
+ val = RD4(sc, EMAC_RX_CTL_1);
+ WR4(sc, EMAC_RX_CTL_1, val | RX_DMA_EN | RX_MD);
+
+ /* Enable transmitter */
+ val = RD4(sc, EMAC_TX_CTL_0);
+ WR4(sc, EMAC_TX_CTL_0, val | TX_EN);
+
+ /* Enable receiver */
+ val = RD4(sc, EMAC_RX_CTL_0);
+ WR4(sc, EMAC_RX_CTL_0, val | RX_EN | CHECK_CRC);
+
+ if_setdrvflagbits(ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE);
+
+ mii_mediachg(mii);
+ callout_reset(&sc->stat_ch, hz, awg_tick, sc);
+}
+
+static void
+awg_init(void *softc)
+{
+ struct awg_softc *sc;
+
+ sc = softc;
+
+ AWG_LOCK(sc);
+ awg_init_locked(sc);
+ AWG_UNLOCK(sc);
+}
+
+static void
+awg_stop(struct awg_softc *sc)
+{
+ if_t ifp;
+ uint32_t val;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ ifp = sc->ifp;
+
+ callout_stop(&sc->stat_ch);
+
+ /* Stop transmit DMA and flush data in the TX FIFO */
+ val = RD4(sc, EMAC_TX_CTL_1);
+ val &= ~TX_DMA_EN;
+ val |= FLUSH_TX_FIFO;
+ WR4(sc, EMAC_TX_CTL_1, val);
+
+ /* Disable transmitter */
+ val = RD4(sc, EMAC_TX_CTL_0);
+ WR4(sc, EMAC_TX_CTL_0, val & ~TX_EN);
+
+ /* Disable receiver */
+ val = RD4(sc, EMAC_RX_CTL_0);
+ WR4(sc, EMAC_RX_CTL_0, val & ~RX_EN);
+
+ /* Disable interrupts */
+ WR4(sc, EMAC_INT_EN, 0);
+
+ /* Disable transmit DMA */
+ val = RD4(sc, EMAC_TX_CTL_1);
+ WR4(sc, EMAC_TX_CTL_1, val & ~TX_DMA_EN);
+
+ /* Disable receive DMA */
+ val = RD4(sc, EMAC_RX_CTL_1);
+ WR4(sc, EMAC_RX_CTL_1, val & ~RX_DMA_EN);
+
+ sc->link = 0;
+
+ if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+}
+
+static void
+awg_rxintr(struct awg_softc *sc)
+{
+ if_t ifp;
+ struct mbuf *m, *m0;
+ int error, index, len;
+ uint32_t status;
+
+ ifp = sc->ifp;
+
+ bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ for (index = sc->rx.cur; ; index = RX_NEXT(index)) {
+ status = le32toh(sc->rx.desc_ring[index].status);
+ if ((status & RX_DESC_CTL) != 0)
+ break;
+
+ bus_dmamap_sync(sc->rx.buf_tag, sc->rx.buf_map[index].map,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->rx.buf_tag, sc->rx.buf_map[index].map);
+
+ len = (status & RX_FRM_LEN) >> RX_FRM_LEN_SHIFT;
+ if (len != 0) {
+ m = sc->rx.buf_map[index].mbuf;
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = len;
+ m->m_len = len;
+ if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
+
+ if ((if_getcapenable(ifp) & IFCAP_RXCSUM) != 0 &&
+ (status & RX_FRM_TYPE) != 0) {
+ m->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
+ if ((status & RX_HEADER_ERR) == 0)
+ m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+ if ((status & RX_PAYLOAD_ERR) == 0) {
+ m->m_pkthdr.csum_flags |=
+ CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
+ m->m_pkthdr.csum_data = 0xffff;
+ }
+ }
+
+ AWG_UNLOCK(sc);
+ if_input(ifp, m);
+ AWG_LOCK(sc);
+ }
+
+ if ((m0 = awg_alloc_mbufcl(sc)) != NULL) {
+ error = awg_setup_rxbuf(sc, index, m0);
+ if (error != 0) {
+ /* XXX hole in RX ring */
+ }
+ } else
+ if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
+ }
+
+ if (index != sc->rx.cur) {
+ bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map,
+ BUS_DMASYNC_PREWRITE);
+ }
+
+ sc->rx.cur = index;
+}
+
+static void
+awg_txintr(struct awg_softc *sc)
+{
+ struct awg_bufmap *bmap;
+ struct emac_desc *desc;
+ uint32_t status;
+ if_t ifp;
+ int i;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ bus_dmamap_sync(sc->tx.desc_tag, sc->tx.desc_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ ifp = sc->ifp;
+ for (i = sc->tx.next; sc->tx.queued > 0; i = TX_NEXT(i)) {
+ desc = &sc->tx.desc_ring[i];
+ status = le32toh(desc->status);
+ if ((status & TX_DESC_CTL) != 0)
+ break;
+ bmap = &sc->tx.buf_map[i];
+ if (bmap->mbuf != NULL) {
+ bus_dmamap_sync(sc->tx.buf_tag, bmap->map,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->tx.buf_tag, bmap->map);
+ m_freem(bmap->mbuf);
+ bmap->mbuf = NULL;
+ }
+ awg_setup_txdesc(sc, i, 0, 0, 0);
+ if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ }
+
+ sc->tx.next = i;
+
+ bus_dmamap_sync(sc->tx.desc_tag, sc->tx.desc_map,
+ BUS_DMASYNC_PREWRITE);
+}
+
+static void
+awg_intr(void *arg)
+{
+ struct awg_softc *sc;
+ uint32_t val;
+
+ sc = arg;
+
+ AWG_LOCK(sc);
+ val = RD4(sc, EMAC_INT_STA);
+ WR4(sc, EMAC_INT_STA, val);
+
+ if (val & RX_INT)
+ awg_rxintr(sc);
+
+ if (val & (TX_INT|TX_BUF_UA_INT)) {
+ awg_txintr(sc);
+ if (!if_sendq_empty(sc->ifp))
+ awg_start_locked(sc);
+ }
+
+ AWG_UNLOCK(sc);
+}
+
+static int
+awg_ioctl(if_t ifp, u_long cmd, caddr_t data)
+{
+ struct awg_softc *sc;
+ struct mii_data *mii;
+ struct ifreq *ifr;
+ int flags, mask, error;
+
+ sc = if_getsoftc(ifp);
+ mii = device_get_softc(sc->miibus);
+ ifr = (struct ifreq *)data;
+ error = 0;
+
+ switch (cmd) {
+ case SIOCSIFFLAGS:
+ AWG_LOCK(sc);
+ if (if_getflags(ifp) & IFF_UP) {
+ if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+ flags = if_getflags(ifp) ^ sc->if_flags;
+ if ((flags & (IFF_PROMISC|IFF_ALLMULTI)) != 0)
+ awg_setup_rxfilter(sc);
+ } else
+ awg_init_locked(sc);
+ } else {
+ if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
+ awg_stop(sc);
+ }
+ sc->if_flags = if_getflags(ifp);
+ AWG_UNLOCK(sc);
+ break;
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+ AWG_LOCK(sc);
+ awg_setup_rxfilter(sc);
+ AWG_UNLOCK(sc);
+ }
+ break;
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+ break;
+ case SIOCSIFCAP:
+ mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
+ if (mask & IFCAP_VLAN_MTU)
+ if_togglecapenable(ifp, IFCAP_VLAN_MTU);
+ if (mask & IFCAP_RXCSUM)
+ if_togglecapenable(ifp, IFCAP_RXCSUM);
+ if (mask & IFCAP_TXCSUM)
+ if_togglecapenable(ifp, IFCAP_TXCSUM);
+ if ((if_getcapenable(ifp) & (IFCAP_RXCSUM|IFCAP_TXCSUM)) != 0)
+ if_sethwassistbits(ifp, CSUM_IP, 0);
+ else
+ if_sethwassistbits(ifp, 0, CSUM_IP);
+ break;
+ default:
+ error = ether_ioctl(ifp, cmd, data);
+ break;
+ }
+
+ return (error);
+}
+
+static int
+awg_setup_extres(device_t dev)
+{
+ struct awg_softc *sc;
+ hwreset_t rst_ahb;
+ clk_t clk_ahb, clk_tx, clk_tx_parent;
+ regulator_t reg;
+ const char *tx_parent_name;
+ char *phy_type;
+ phandle_t node;
+ uint64_t freq;
+ int error, div;
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+ rst_ahb = NULL;
+ clk_ahb = NULL;
+ clk_tx = NULL;
+ clk_tx_parent = NULL;
+ reg = NULL;
+ phy_type = NULL;
+
+ /* Get AHB clock and reset resources */
+ error = hwreset_get_by_ofw_name(dev, "ahb", &rst_ahb);
+ if (error != 0) {
+ device_printf(dev, "cannot get ahb reset\n");
+ goto fail;
+ }
+ error = clk_get_by_ofw_name(dev, "ahb", &clk_ahb);
+ if (error != 0) {
+ device_printf(dev, "cannot get ahb clock\n");
+ goto fail;
+ }
+
+ /* Configure PHY for MII or RGMII mode */
+ if (OF_getprop_alloc(node, "phy-mode", 1, (void **)&phy_type)) {
+ if (bootverbose)
+ device_printf(dev, "PHY type: %s\n", phy_type);
+
+ if (strcmp(phy_type, "rgmii") == 0)
+ tx_parent_name = "emac_int_tx";
+ else
+ tx_parent_name = "mii_phy_tx";
+ free(phy_type, M_OFWPROP);
+
+ /* Get the TX clock */
+ error = clk_get_by_ofw_name(dev, "tx", &clk_tx);
+ if (error != 0) {
+ device_printf(dev, "cannot get tx clock\n");
+ goto fail;
+ }
+
+ /* Find the desired parent clock based on phy-mode property */
+ error = clk_get_by_name(dev, tx_parent_name, &clk_tx_parent);
+ if (error != 0) {
+ device_printf(dev, "cannot get clock '%s'\n",
+ tx_parent_name);
+ goto fail;
+ }
+
+ /* Set TX clock parent */
+ error = clk_set_parent_by_clk(clk_tx, clk_tx_parent);
+ if (error != 0) {
+ device_printf(dev, "cannot set tx clock parent\n");
+ goto fail;
+ }
+
+ /* Enable TX clock */
+ error = clk_enable(clk_tx);
+ if (error != 0) {
+ device_printf(dev, "cannot enable tx clock\n");
+ goto fail;
+ }
+ }
+
+ /* Enable AHB clock */
+ error = clk_enable(clk_ahb);
+ if (error != 0) {
+ device_printf(dev, "cannot enable ahb clock\n");
+ goto fail;
+ }
+
+ /* De-assert reset */
+ error = hwreset_deassert(rst_ahb);
+ if (error != 0) {
+ device_printf(dev, "cannot de-assert ahb reset\n");
+ goto fail;
+ }
+
+ /* Enable PHY regulator if applicable */
+ if (regulator_get_by_ofw_property(dev, "phy-supply", &reg) == 0) {
+ error = regulator_enable(reg);
+ if (error != 0) {
+ device_printf(dev, "cannot enable PHY regulator\n");
+ goto fail;
+ }
+ }
+
+ /* Determine MDC clock divide ratio based on AHB clock */
+ error = clk_get_freq(clk_ahb, &freq);
+ if (error != 0) {
+ device_printf(dev, "cannot get AHB clock frequency\n");
+ goto fail;
+ }
+ div = freq / MDIO_FREQ;
+ if (div <= 16)
+ sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_16;
+ else if (div <= 32)
+ sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_32;
+ else if (div <= 64)
+ sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_64;
+ else if (div <= 128)
+ sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_128;
+ else {
+ device_printf(dev, "cannot determine MDC clock divide ratio\n");
+ error = ENXIO;
+ goto fail;
+ }
+
+ if (bootverbose)
+ device_printf(dev, "AHB frequency %llu Hz, MDC div: 0x%x\n",
+ freq, sc->mdc_div_ratio_m);
+
+ return (0);
+
+fail:
+ free(phy_type, M_OFWPROP);
+
+ if (reg != NULL)
+ regulator_release(reg);
+ if (clk_tx_parent != NULL)
+ clk_release(clk_tx_parent);
+ if (clk_tx != NULL)
+ clk_release(clk_tx);
+ if (clk_ahb != NULL)
+ clk_release(clk_ahb);
+ if (rst_ahb != NULL)
+ hwreset_release(rst_ahb);
+ return (error);
+}
+
+static void
+awg_get_eaddr(device_t dev, uint8_t *eaddr)
+{
+ struct awg_softc *sc;
+ uint32_t maclo, machi, rnd;
+
+ sc = device_get_softc(dev);
+
+ machi = RD4(sc, EMAC_ADDR_HIGH(0)) & 0xffff;
+ maclo = RD4(sc, EMAC_ADDR_LOW(0));
+
+ if (maclo == 0xffffffff && machi == 0xffff) {
+ /* MAC address in hardware is invalid, create one */
+ rnd = arc4random();
+ maclo = 0x00f2 | (rnd & 0xffff0000);
+ machi = rnd & 0xffff;
+ }
+
+ eaddr[0] = maclo & 0xff;
+ eaddr[1] = (maclo >> 8) & 0xff;
+ eaddr[2] = (maclo >> 16) & 0xff;
+ eaddr[3] = (maclo >> 24) & 0xff;
+ eaddr[4] = machi & 0xff;
+ eaddr[5] = (machi >> 8) & 0xff;
+}
+
+#ifdef AWG_DEBUG
+static void
+awg_dump_regs(device_t dev)
+{
+ static const struct {
+ const char *name;
+ u_int reg;
+ } regs[] = {
+ { "BASIC_CTL_0", EMAC_BASIC_CTL_0 },
+ { "BASIC_CTL_1", EMAC_BASIC_CTL_1 },
+ { "INT_STA", EMAC_INT_STA },
+ { "INT_EN", EMAC_INT_EN },
+ { "TX_CTL_0", EMAC_TX_CTL_0 },
+ { "TX_CTL_1", EMAC_TX_CTL_1 },
+ { "TX_FLOW_CTL", EMAC_TX_FLOW_CTL },
+ { "TX_DMA_LIST", EMAC_TX_DMA_LIST },
+ { "RX_CTL_0", EMAC_RX_CTL_0 },
+ { "RX_CTL_1", EMAC_RX_CTL_1 },
+ { "RX_DMA_LIST", EMAC_RX_DMA_LIST },
+ { "RX_FRM_FLT", EMAC_RX_FRM_FLT },
+ { "RX_HASH_0", EMAC_RX_HASH_0 },
+ { "RX_HASH_1", EMAC_RX_HASH_1 },
+ { "MII_CMD", EMAC_MII_CMD },
+ { "ADDR_HIGH0", EMAC_ADDR_HIGH(0) },
+ { "ADDR_LOW0", EMAC_ADDR_LOW(0) },
+ { "TX_DMA_STA", EMAC_TX_DMA_STA },
+ { "TX_DMA_CUR_DESC", EMAC_TX_DMA_CUR_DESC },
+ { "TX_DMA_CUR_BUF", EMAC_TX_DMA_CUR_BUF },
+ { "RX_DMA_STA", EMAC_RX_DMA_STA },
+ { "RX_DMA_CUR_DESC", EMAC_RX_DMA_CUR_DESC },
+ { "RX_DMA_CUR_BUF", EMAC_RX_DMA_CUR_BUF },
+ { "RGMII_STA", EMAC_RGMII_STA },
+ };
+ struct awg_softc *sc;
+ unsigned int n;
+
+ sc = device_get_softc(dev);
+
+ for (n = 0; n < nitems(regs); n++)
+ device_printf(dev, " %-20s %08x\n", regs[n].name,
+ RD4(sc, regs[n].reg));
+}
+#endif
+
+static int
+awg_reset(device_t dev)
+{
+ struct awg_softc *sc;
+ int retry;
+
+ sc = device_get_softc(dev);
+
+ /* Soft reset all registers and logic */
+ WR4(sc, EMAC_BASIC_CTL_1, BASIC_CTL_SOFT_RST);
+
+ /* Wait for soft reset bit to self-clear */
+ for (retry = SOFT_RST_RETRY; retry > 0; retry--) {
+ if ((RD4(sc, EMAC_BASIC_CTL_1) & BASIC_CTL_SOFT_RST) == 0)
+ break;
+ DELAY(10);
+ }
+ if (retry == 0) {
+ device_printf(dev, "soft reset timed out\n");
+#ifdef AWG_DEBUG
+ awg_dump_regs(dev);
+#endif
+ return (ETIMEDOUT);
+ }
+
+ return (0);
+}
+
+static void
+awg_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ if (error != 0)
+ return;
+ *(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+static int
+awg_setup_dma(device_t dev)
+{
+ struct awg_softc *sc;
+ struct mbuf *m;
+ int error, i;
+
+ sc = device_get_softc(dev);
+
+ /* Setup TX ring */
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* Parent tag */
+ DESC_ALIGN, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ TX_DESC_SIZE, 1, /* maxsize, nsegs */
+ TX_DESC_SIZE, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->tx.desc_tag);
+ if (error != 0) {
+ device_printf(dev, "cannot create TX descriptor ring tag\n");
+ return (error);
+ }
+
+ error = bus_dmamem_alloc(sc->tx.desc_tag, (void **)&sc->tx.desc_ring,
+ BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->tx.desc_map);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate TX descriptor ring\n");
+ return (error);
+ }
+
+ error = bus_dmamap_load(sc->tx.desc_tag, sc->tx.desc_map,
+ sc->tx.desc_ring, TX_DESC_SIZE, awg_dmamap_cb,
+ &sc->tx.desc_ring_paddr, 0);
+ if (error != 0) {
+ device_printf(dev, "cannot load TX descriptor ring\n");
+ return (error);
+ }
+
+ for (i = 0; i < TX_DESC_COUNT; i++)
+ sc->tx.desc_ring[i].next =
+ htole32(sc->tx.desc_ring_paddr + DESC_OFF(TX_NEXT(i)));
+
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* Parent tag */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MCLBYTES, TX_MAX_SEGS, /* maxsize, nsegs */
+ MCLBYTES, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->tx.buf_tag);
+ if (error != 0) {
+ device_printf(dev, "cannot create TX buffer tag\n");
+ return (error);
+ }
+
+ sc->tx.queued = TX_DESC_COUNT;
+ for (i = 0; i < TX_DESC_COUNT; i++) {
+ error = bus_dmamap_create(sc->tx.buf_tag, 0,
+ &sc->tx.buf_map[i].map);
+ if (error != 0) {
+ device_printf(dev, "cannot create TX buffer map\n");
+ return (error);
+ }
+ awg_setup_txdesc(sc, i, 0, 0, 0);
+ }
+
+ /* Setup RX ring */
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* Parent tag */
+ DESC_ALIGN, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ RX_DESC_SIZE, 1, /* maxsize, nsegs */
+ RX_DESC_SIZE, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->rx.desc_tag);
+ if (error != 0) {
+ device_printf(dev, "cannot create RX descriptor ring tag\n");
+ return (error);
+ }
+
+ error = bus_dmamem_alloc(sc->rx.desc_tag, (void **)&sc->rx.desc_ring,
+ BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rx.desc_map);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate RX descriptor ring\n");
+ return (error);
+ }
+
+ error = bus_dmamap_load(sc->rx.desc_tag, sc->rx.desc_map,
+ sc->rx.desc_ring, RX_DESC_SIZE, awg_dmamap_cb,
+ &sc->rx.desc_ring_paddr, 0);
+ if (error != 0) {
+ device_printf(dev, "cannot load RX descriptor ring\n");
+ return (error);
+ }
+
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* Parent tag */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MCLBYTES, 1, /* maxsize, nsegs */
+ MCLBYTES, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->rx.buf_tag);
+ if (error != 0) {
+ device_printf(dev, "cannot create RX buffer tag\n");
+ return (error);
+ }
+
+ for (i = 0; i < RX_DESC_COUNT; i++) {
+ error = bus_dmamap_create(sc->rx.buf_tag, 0,
+ &sc->rx.buf_map[i].map);
+ if (error != 0) {
+ device_printf(dev, "cannot create RX buffer map\n");
+ return (error);
+ }
+ if ((m = awg_alloc_mbufcl(sc)) == NULL) {
+ device_printf(dev, "cannot allocate RX mbuf\n");
+ return (ENOMEM);
+ }
+ error = awg_setup_rxbuf(sc, i, m);
+ if (error != 0) {
+ device_printf(dev, "cannot create RX buffer\n");
+ return (error);
+ }
+ }
+ bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map,
+ BUS_DMASYNC_PREWRITE);
+
+ /* Write transmit and receive descriptor base address registers */
+ WR4(sc, EMAC_TX_DMA_LIST, sc->tx.desc_ring_paddr);
+ WR4(sc, EMAC_RX_DMA_LIST, sc->rx.desc_ring_paddr);
+
+ return (0);
+}
+
+static int
+awg_probe(device_t dev)
+{
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Allwinner Gigabit Ethernet");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+awg_attach(device_t dev)
+{
+ uint8_t eaddr[ETHER_ADDR_LEN];
+ struct awg_softc *sc;
+ phandle_t node;
+ int error;
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+
+ if (bus_alloc_resources(dev, awg_spec, sc->res) != 0) {
+ device_printf(dev, "cannot allocate resources for device\n");
+ return (ENXIO);
+ }
+
+ mtx_init(&sc->mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF);
+ callout_init_mtx(&sc->stat_ch, &sc->mtx, 0);
+ TASK_INIT(&sc->link_task, 0, awg_link_task, sc);
+
+ /* Setup clocks and regulators */
+ error = awg_setup_extres(dev);
+ if (error != 0)
+ return (error);
+
+ /* Read MAC address before resetting the chip */
+ awg_get_eaddr(dev, eaddr);
+
+ /* Soft reset EMAC core */
+ error = awg_reset(dev);
+ if (error != 0)
+ return (error);
+
+ /* Setup DMA descriptors */
+ error = awg_setup_dma(dev);
+ if (error != 0)
+ return (error);
+
+ /* Install interrupt handler */
+ error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, awg_intr, sc, &sc->ih);
+ if (error != 0) {
+ device_printf(dev, "cannot setup interrupt handler\n");
+ return (error);
+ }
+
+ /* Setup ethernet interface */
+ sc->ifp = if_alloc(IFT_ETHER);
+ if_setsoftc(sc->ifp, sc);
+ if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev));
+ if_setflags(sc->ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
+ if_setstartfn(sc->ifp, awg_start);
+ if_setioctlfn(sc->ifp, awg_ioctl);
+ if_setinitfn(sc->ifp, awg_init);
+ if_setsendqlen(sc->ifp, TX_DESC_COUNT - 1);
+ if_setsendqready(sc->ifp);
+ if_sethwassist(sc->ifp, CSUM_IP | CSUM_UDP | CSUM_TCP);
+ if_setcapabilities(sc->ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM);
+ if_setcapenable(sc->ifp, if_getcapabilities(sc->ifp));
+
+ /* Attach MII driver */
+ error = mii_attach(dev, &sc->miibus, sc->ifp, awg_media_change,
+ awg_media_status, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY,
+ MIIF_DOPAUSE);
+ if (error != 0) {
+ device_printf(dev, "cannot attach PHY\n");
+ return (error);
+ }
+
+ /* Attach ethernet interface */
+ ether_ifattach(sc->ifp, eaddr);
+
+ return (0);
+}
+
+static device_method_t awg_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, awg_probe),
+ DEVMETHOD(device_attach, awg_attach),
+
+ /* MII interface */
+ DEVMETHOD(miibus_readreg, awg_miibus_readreg),
+ DEVMETHOD(miibus_writereg, awg_miibus_writereg),
+ DEVMETHOD(miibus_statchg, awg_miibus_statchg),
+
+ DEVMETHOD_END
+};
+
+static driver_t awg_driver = {
+ "awg",
+ awg_methods,
+ sizeof(struct awg_softc),
+};
+
+static devclass_t awg_devclass;
+
+DRIVER_MODULE(awg, simplebus, awg_driver, awg_devclass, 0, 0);
+DRIVER_MODULE(miibus, awg, miibus_driver, miibus_devclass, 0, 0);
+
+MODULE_DEPEND(awg, ether, 1, 1, 1);
+MODULE_DEPEND(awg, miibus, 1, 1, 1);
diff --git a/sys/arm/allwinner/if_awgreg.h b/sys/arm/allwinner/if_awgreg.h
new file mode 100644
index 0000000..53a15c1
--- /dev/null
+++ b/sys/arm/allwinner/if_awgreg.h
@@ -0,0 +1,181 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Allwinner Gigabit Ethernet
+ */
+
+#ifndef __IF_AWGREG_H__
+#define __IF_AWGREG_H__
+
+#define EMAC_BASIC_CTL_0 0x00
+#define BASIC_CTL_SPEED (0x3 << 2)
+#define BASIC_CTL_SPEED_SHIFT 2
+#define BASIC_CTL_SPEED_1000 0
+#define BASIC_CTL_SPEED_10 2
+#define BASIC_CTL_SPEED_100 3
+#define BASIC_CTL_LOOPBACK (1 << 1)
+#define BASIC_CTL_DUPLEX (1 << 0)
+#define EMAC_BASIC_CTL_1 0x04
+#define BASIC_CTL_BURST_LEN (0x3f << 24)
+#define BASIC_CTL_BURST_LEN_SHIFT 24
+#define BASIC_CTL_RX_TX_PRI (1 << 1)
+#define BASIC_CTL_SOFT_RST (1 << 0)
+#define EMAC_INT_STA 0x08
+#define RX_BUF_UA_INT (1 << 10)
+#define RX_INT (1 << 8)
+#define TX_UNDERFLOW_INT (1 << 4)
+#define TX_BUF_UA_INT (1 << 2)
+#define TX_DMA_STOPPED_INT (1 << 1)
+#define TX_INT (1 << 0)
+#define EMAC_INT_EN 0x0c
+#define RX_BUF_UA_INT_EN (1 << 10)
+#define RX_INT_EN (1 << 8)
+#define TX_UNDERFLOW_INT_EN (1 << 4)
+#define TX_BUF_UA_INT_EN (1 << 2)
+#define TX_DMA_STOPPED_INT_EN (1 << 1)
+#define TX_INT_EN (1 << 0)
+#define EMAC_TX_CTL_0 0x10
+#define TX_EN (1 << 31)
+#define EMAC_TX_CTL_1 0x14
+#define TX_DMA_START (1 << 31)
+#define TX_DMA_EN (1 << 30)
+#define TX_MD (1 << 1)
+#define FLUSH_TX_FIFO (1 << 0)
+#define EMAC_TX_FLOW_CTL 0x1c
+#define PAUSE_TIME (0xffff << 4)
+#define PAUSE_TIME_SHIFT 4
+#define TX_FLOW_CTL_EN (1 << 0)
+#define EMAC_TX_DMA_LIST 0x20
+#define EMAC_RX_CTL_0 0x24
+#define RX_EN (1 << 31)
+#define JUMBO_FRM_EN (1 << 29)
+#define STRIP_FCS (1 << 28)
+#define CHECK_CRC (1 << 27)
+#define RX_FLOW_CTL_EN (1 << 16)
+#define EMAC_RX_CTL_1 0x28
+#define RX_DMA_START (1 << 31)
+#define RX_DMA_EN (1 << 30)
+#define RX_MD (1 << 1)
+#define EMAC_RX_DMA_LIST 0x34
+#define EMAC_RX_FRM_FLT 0x38
+#define DIS_ADDR_FILTER (1 << 31)
+#define DIS_BROADCAST (1 << 17)
+#define RX_ALL_MULTICAST (1 << 16)
+#define CTL_FRM_FILTER (0x3 << 12)
+#define CTL_FRM_FILTER_SHIFT 12
+#define HASH_MULTICAST (1 << 9)
+#define HASH_UNICAST (1 << 8)
+#define SA_FILTER_EN (1 << 6)
+#define SA_INV_FILTER (1 << 5)
+#define DA_INV_FILTER (1 << 4)
+#define FLT_MD (1 << 1)
+#define RX_ALL (1 << 0)
+#define EMAC_RX_HASH_0 0x40
+#define EMAC_RX_HASH_1 0x44
+#define EMAC_MII_CMD 0x48
+#define MDC_DIV_RATIO_M (0x7 << 20)
+#define MDC_DIV_RATIO_M_16 0
+#define MDC_DIV_RATIO_M_32 1
+#define MDC_DIV_RATIO_M_64 2
+#define MDC_DIV_RATIO_M_128 3
+#define MDC_DIV_RATIO_M_SHIFT 20
+#define PHY_ADDR (0x1f << 12)
+#define PHY_ADDR_SHIFT 12
+#define PHY_REG_ADDR (0x1f << 4)
+#define PHY_REG_ADDR_SHIFT 4
+#define MII_WR (1 << 1)
+#define MII_BUSY (1 << 0)
+#define EMAC_MII_DATA 0x4c
+#define EMAC_ADDR_HIGH(n) (0x50 + (n) * 8)
+#define EMAC_ADDR_LOW(n) (0x54 + (n) * 8)
+#define EMAC_TX_DMA_STA 0x80
+#define EMAC_TX_DMA_CUR_DESC 0x84
+#define EMAC_TX_DMA_CUR_BUF 0x88
+#define EMAC_RX_DMA_STA 0xc0
+#define EMAC_RX_DMA_CUR_DESC 0xc4
+#define EMAC_RX_DMA_CUR_BUF 0xc8
+#define EMAC_RGMII_STA 0xd0
+
+struct emac_desc {
+ uint32_t status;
+/* Transmit */
+#define TX_DESC_CTL (1 << 31)
+#define TX_HEADER_ERR (1 << 16)
+#define TX_LENGTH_ERR (1 << 14)
+#define TX_PAYLOAD_ERR (1 << 12)
+#define TX_CRS_ERR (1 << 10)
+#define TX_COL_ERR_0 (1 << 9)
+#define TX_COL_ERR_1 (1 << 8)
+#define TX_COL_CNT (0xf << 3)
+#define TX_COL_CNT_SHIFT 3
+#define TX_DEFER_ERR (1 << 2)
+#define TX_UNDERFLOW_ERR (1 << 1)
+#define TX_DEFER (1 << 0)
+/* Receive */
+#define RX_DESC_CTL (1 << 31)
+#define RX_DAF_FAIL (1 << 30)
+#define RX_FRM_LEN (0x3fff << 16)
+#define RX_FRM_LEN_SHIFT 16
+#define RX_NO_ENOUGH_BUF_ERR (1 << 14)
+#define RX_SAF_FAIL (1 << 13)
+#define RX_OVERFLOW_ERR (1 << 11)
+#define RX_FIR_DESC (1 << 9)
+#define RX_LAST_DESC (1 << 8)
+#define RX_HEADER_ERR (1 << 7)
+#define RX_COL_ERR (1 << 6)
+#define RX_FRM_TYPE (1 << 5)
+#define RX_LENGTH_ERR (1 << 4)
+#define RX_PHY_ERR (1 << 3)
+#define RX_CRC_ERR (1 << 1)
+#define RX_PAYLOAD_ERR (1 << 0)
+
+ uint32_t size;
+/* Transmit */
+#define TX_INT_CTL (1 << 31)
+#define TX_LAST_DESC (1 << 30)
+#define TX_FIR_DESC (1 << 29)
+#define TX_CHECKSUM_CTL (0x3 << 27)
+#define TX_CHECKSUM_CTL_IP 1
+#define TX_CHECKSUM_CTL_NO_PSE 2
+#define TX_CHECKSUM_CTL_FULL 3
+#define TX_CHECKSUM_CTL_SHIFT 27
+#define TX_CRC_CTL (1 << 26)
+#define TX_BUF_SIZE (0xfff << 0)
+#define TX_BUF_SIZE_SHIFT 0
+/* Receive */
+#define RX_INT_CTL (1 << 31)
+#define RX_BUF_SIZE (0xfff << 0)
+#define RX_BUF_SIZE_SHIFT 0
+
+ uint32_t addr;
+
+ uint32_t next;
+} __packed;
+
+#endif /* !__IF_AWGREG_H__ */
diff --git a/sys/arm/allwinner/std.allwinner b/sys/arm/allwinner/std.allwinner
index 885d41d..5ac9dd6 100644
--- a/sys/arm/allwinner/std.allwinner
+++ b/sys/arm/allwinner/std.allwinner
@@ -14,3 +14,4 @@ options IPI_IRQ_END=15
files "../allwinner/files.allwinner"
files "../allwinner/a20/files.a20"
files "../allwinner/a31/files.a31"
+files "../allwinner/a83t/files.a83t"
diff --git a/sys/arm/amlogic/aml8726/aml8726_mmc.c b/sys/arm/amlogic/aml8726/aml8726_mmc.c
index 0e24975..5205507 100644
--- a/sys/arm/amlogic/aml8726/aml8726_mmc.c
+++ b/sys/arm/amlogic/aml8726/aml8726_mmc.c
@@ -240,7 +240,7 @@ aml8726_mmc_start_command(struct aml8726_mmc_softc *sc, struct mmc_command *cmd)
* Start and transmission bits are per section 4.7.2 of the:
*
* SD Specifications Part 1
- * Physicaly Layer Simplified Specification
+ * Physical Layer Simplified Specification
* Version 4.10
*/
cmdr = AML_MMC_CMD_START_BIT | AML_MMC_CMD_TRANS_BIT_HOST | cmd->opcode;
diff --git a/sys/arm/amlogic/aml8726/aml8726_mmc.h b/sys/arm/amlogic/aml8726/aml8726_mmc.h
index 64e3bae..a2dde21 100644
--- a/sys/arm/amlogic/aml8726/aml8726_mmc.h
+++ b/sys/arm/amlogic/aml8726/aml8726_mmc.h
@@ -39,7 +39,7 @@
* Read and write are per section 4.6.2 of the:
*
* SD Specifications Part 1
- * Physicaly Layer Simplified Specification
+ * Physical Layer Simplified Specification
* Version 4.10
*/
#define AML_MMC_CMD_TIMEOUT 50
diff --git a/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c b/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c
index 75825fb..a5be5e4 100644
--- a/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c
+++ b/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c
@@ -484,7 +484,7 @@ aml8726_sdxc_finish_command(struct aml8726_sdxc_softc *sc, int mmc_error)
if (stop_cmd != NULL) {
/*
- * If the original command executed successfuly, then
+ * If the original command executed successfully, then
* the hardware will also have automatically executed
* a stop command so don't bother with the one supplied
* with the original request.
diff --git a/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h b/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h
index 013a86e..1d0dc14 100644
--- a/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h
+++ b/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h
@@ -38,7 +38,7 @@
* Read and write are per section 4.6.2 of the:
*
* SD Specifications Part 1
- * Physicaly Layer Simplified Specification
+ * Physical Layer Simplified Specification
* Version 4.10
*/
#define AML_SDXC_CMD_TIMEOUT 50
diff --git a/sys/arm/arm/cpufunc_asm_arm11.S b/sys/arm/arm/cpufunc_asm_arm11.S
index f83f819..d6538c6 100644
--- a/sys/arm/arm/cpufunc_asm_arm11.S
+++ b/sys/arm/arm/cpufunc_asm_arm11.S
@@ -30,7 +30,7 @@
*
* ARM11 assembly functions for CPU / MMU / TLB specific operations
*
- * XXX We make no attempt at present to take advantage of the v6 memroy
+ * XXX We make no attempt at present to take advantage of the v6 memory
* architecture or physically tagged cache.
*/
diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S
index 9f186a5..9466cf6 100644
--- a/sys/arm/arm/exception.S
+++ b/sys/arm/arm/exception.S
@@ -175,7 +175,7 @@ _C_LABEL(dtrace_invop_jump_addr):
ldr r4, [r5, #4]; /* reset it to point at the */ \
cmp r4, #0xffffffff; /* end of memory if necessary; */ \
movne r1, #0xffffffff; /* leave value in r4 for later */ \
- strne r1, [r5, #4]; /* comparision against PC. */ \
+ strne r1, [r5, #4]; /* comparison against PC. */ \
ldr r3, [r5]; /* Retrieve global RAS_START */ \
cmp r3, #0; /* and reset it if non-zero. */ \
movne r1, #0; /* If non-zero RAS_START and */ \
diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c
index f9cb23e..9c67018 100644
--- a/sys/arm/arm/genassym.c
+++ b/sys/arm/arm/genassym.c
@@ -28,6 +28,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/cpuset.h>
#include <sys/systm.h>
#include <sys/assym.h>
#include <sys/proc.h>
diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index 6e6fcea..dcf48bc 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -100,7 +100,7 @@ static struct arm_tmr_softc *arm_tmr_sc = NULL;
static struct resource_spec timer_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE }, /* Secure */
{ SYS_RES_IRQ, 1, RF_ACTIVE }, /* Non-secure */
- { SYS_RES_IRQ, 2, RF_ACTIVE }, /* Virt */
+ { SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL }, /* Virt */
{ SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL }, /* Hyp */
{ -1, 0 }
};
@@ -392,13 +392,17 @@ arm_tmr_attach(device_t dev)
#ifdef __arm__
sc->physical = true;
#else /* __aarch64__ */
- sc->physical = false;
+ /* If we do not have a virtual timer use the physical. */
+ sc->physical = (sc->res[2] == NULL) ? true : false;
#endif
arm_tmr_sc = sc;
/* Setup secure, non-secure and virtual IRQs handler */
for (i = 0; i < 3; i++) {
+ /* If we do not have the interrupt, skip it. */
+ if (sc->res[i] == NULL)
+ continue;
error = bus_setup_intr(dev, sc->res[i], INTR_TYPE_CLK,
arm_tmr_intr, NULL, sc, &sc->ihl[i]);
if (error) {
@@ -417,7 +421,7 @@ arm_tmr_attach(device_t dev)
sc->et.et_quality = 1000;
sc->et.et_frequency = sc->clkfreq;
- sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
+ sc->et.et_min_period = (0x00000010LLU << 32) / sc->et.et_frequency;
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
sc->et.et_start = arm_tmr_start;
sc->et.et_stop = arm_tmr_stop;
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index 08693d9..17e1525 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -1006,18 +1006,22 @@ gic_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp,
enum intr_polarity pol;
enum intr_trigger trig;
struct arm_gic_softc *sc;
+#ifdef FDT
+ struct intr_map_data_fdt *daf;
+#endif
sc = device_get_softc(dev);
switch (data->type) {
#ifdef FDT
case INTR_MAP_DATA_FDT:
- if (gic_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
- &pol, &trig) != 0)
+ daf = (struct intr_map_data_fdt *)data;
+ if (gic_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol,
+ &trig) != 0)
return (EINVAL);
break;
#endif
default:
- return (EINVAL);
+ return (ENOTSUP);
}
if (irq >= sc->nirqs)
@@ -1231,7 +1235,7 @@ arm_gic_next_irq(struct arm_gic_softc *sc, int last_irq)
active_irq = gic_c_read_4(sc, GICC_IAR);
/*
- * Immediatly EOIR the SGIs, because doing so requires the other
+ * Immediately EOIR the SGIs, because doing so requires the other
* bits (ie CPU number), not just the IRQ number, and we do not
* have this information later.
*/
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 453c197..49d5986 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -36,7 +36,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Machine dependant functions for kernel setup
+ * Machine dependent functions for kernel setup
*
* Created : 17/09/94
* Updated : 18/04/01 updated for new wscons
diff --git a/sys/arm/arm/mpcore_timer.c b/sys/arm/arm/mpcore_timer.c
index fb30d38..03f8e4b 100644
--- a/sys/arm/arm/mpcore_timer.c
+++ b/sys/arm/arm/mpcore_timer.c
@@ -367,7 +367,7 @@ attach_et(struct arm_tmr_softc *sc)
* globally and registers both the timecount and eventtimer objects.
*
* RETURNS
- * Zero on sucess or ENXIO if an error occuried.
+ * Zero on success or ENXIO if an error occuried.
*/
static int
arm_tmr_attach(device_t dev)
@@ -457,7 +457,7 @@ EARLY_DRIVER_MODULE(mp_tmr, ofwbus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
/*
* Handle a change in clock frequency. The mpcore timer runs at half the CPU
* frequency. When the CPU frequency changes due to power-saving or thermal
- * managment, the platform-specific code that causes the frequency change calls
+ * management, the platform-specific code that causes the frequency change calls
* this routine to inform the clock driver, and we in turn inform the event
* timer system, which actually updates the value in et->frequency for us and
* reschedules the current event(s) in a way that's atomic with respect to
diff --git a/sys/arm/arm/pmap-v4.c b/sys/arm/arm/pmap-v4.c
index 733ccf2..3bdc9e4 100644
--- a/sys/arm/arm/pmap-v4.c
+++ b/sys/arm/arm/pmap-v4.c
@@ -126,7 +126,7 @@
*
* pmap.c
*
- * Machine dependant vm stuff
+ * Machine dependent vm stuff
*
* Created : 20/09/94
*/
@@ -1386,9 +1386,9 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
*
* Don't turn caching on again if this is a
* modified emulation. This would be
- * inconsitent with the settings created by
+ * inconsistent with the settings created by
* pmap_fix_cache(). Otherwise, it's safe
- * to re-enable cacheing.
+ * to re-enable caching.
*
* There's no need to call pmap_fix_cache()
* here: all pages are losing their write
diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c
index f5a6fa8..703f39d 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -705,7 +705,7 @@ pmap_preboot_get_pages(u_int num)
}
/*
- * The fundamental initalization of PMAP stuff.
+ * The fundamental initialization of PMAP stuff.
*
* Some things already happened in locore.S and some things could happen
* before pmap_bootstrap_prepare() is called, so let's recall what is done:
@@ -1210,7 +1210,7 @@ pmap_bootstrap(vm_offset_t firstaddr)
/*
* Note that in very short time in initarm(), we are going to
- * initialize phys_avail[] array and no futher page allocation
+ * initialize phys_avail[] array and no further page allocation
* can happen after that until vm subsystem will be initialized.
*/
kernel_vm_end_new = kernel_vm_end;
diff --git a/sys/arm/arm/swtch-v4.S b/sys/arm/arm/swtch-v4.S
index 6fdbeed..21924dc 100644
--- a/sys/arm/arm/swtch-v4.S
+++ b/sys/arm/arm/swtch-v4.S
@@ -296,7 +296,7 @@ ENTRY(cpu_switch)
beq .Lcs_context_switched /* yes! */
/*
- * Definately need to flush the cache.
+ * Definitely need to flush the cache.
*/
ldr r1, .Lcpufuncs
diff --git a/sys/arm/at91/at91_cfata.c b/sys/arm/at91/at91_cfata.c
index 37ce434..d4848ff 100644
--- a/sys/arm/at91/at91_cfata.c
+++ b/sys/arm/at91/at91_cfata.c
@@ -26,7 +26,7 @@
* common memory mode. Interrupts are driven by polling. The driver
* implements an ATA bridge and attached ATA channel driver on top
* of it.
- * NOTE WELL: this driver uses polling mode. To achive an acceptable
+ * NOTE WELL: this driver uses polling mode. To achieve an acceptable
* operating speed you will probably want to use HZ=2000 in kernel
* config.
*/
diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c
index b6ff9ca..6be7f72 100644
--- a/sys/arm/at91/at91_machdep.c
+++ b/sys/arm/at91/at91_machdep.c
@@ -36,7 +36,7 @@
*
* machdep.c
*
- * Machine dependant functions for kernel setup
+ * Machine dependent functions for kernel setup
*
* This file needs a lot of work.
*
diff --git a/sys/arm/at91/at91_mci.c b/sys/arm/at91/at91_mci.c
index cf884b9..bb5b7d5 100644
--- a/sys/arm/at91/at91_mci.c
+++ b/sys/arm/at91/at91_mci.c
@@ -92,7 +92,7 @@ __FBSDID("$FreeBSD$");
* speed is 25MHz and the next highest speed is 15MHz or less. This appears
* to work on virtually all SD cards, since it is what this driver has been
* doing prior to the introduction of this option, where the overclocking vs
- * underclocking decision was automaticly "overclock". Modern SD cards can
+ * underclocking decision was automatically "overclock". Modern SD cards can
* run at 45mhz/1-bit in standard mode (high speed mode enable commands not
* sent) without problems.
*
@@ -212,7 +212,7 @@ at91_bswap_buf(struct at91_mci_softc *sc, void * dptr, void * sptr, uint32_t mem
/*
* If the hardware doesn't need byte-swapping, let bcopy() do the
* work. Use bounce buffer even if we don't need byteswap, since
- * buffer may straddle a page boundry, and we don't handle
+ * buffer may straddle a page boundary, and we don't handle
* multi-segment transfers in hardware. Seen from 'bsdlabel -w' which
* uses raw geom access to the volume. Greg Ansley (gja (at)
* ansley.com)
diff --git a/sys/arm/at91/at91_reset.S b/sys/arm/at91/at91_reset.S
index 28703cc..36d72e4 100644
--- a/sys/arm/at91/at91_reset.S
+++ b/sys/arm/at91/at91_reset.S
@@ -14,7 +14,7 @@ __FBSDID("$FreeBSD$");
/*
* From AT91SAM9G20 Datasheet errata 44:3.5:
*
- * When User Reset occurs durring SDRAM read acces, eh SDRAM clock is turned
+ * When User Reset occurs during SDRAM read access, the SDRAM clock is turned
* off while data are ready to be read on the data bus. The SDRAM maintains
* the data until the clock restarts.
*
diff --git a/sys/arm/at91/at91reg.h b/sys/arm/at91/at91reg.h
index e0aaa81..35e14f5 100644
--- a/sys/arm/at91/at91reg.h
+++ b/sys/arm/at91/at91reg.h
@@ -39,9 +39,9 @@
#define AT91_PA_BASE 0xf0000000
/* A few things that we count on being the same
- * throught the whole family of SOCs */
+ * throughout the whole family of SOCs */
-/* SYSC System Controler */
+/* SYSC System Controller */
/* System Registers */
#define AT91_SYS_BASE 0xffff000
#define AT91_SYS_SIZE 0x1000
diff --git a/sys/arm/at91/at91sam9260.c b/sys/arm/at91/at91sam9260.c
index 5b0f537..4514d87 100644
--- a/sys/arm/at91/at91sam9260.c
+++ b/sys/arm/at91/at91sam9260.c
@@ -188,7 +188,7 @@ at91_clock_init(void)
* PMC alogrithm choose the divisor that causes the input clock
* to be near the optimal 2 MHz per datasheet. We know
* we are going to be using this for the USB clock at 96 MHz.
- * Causes no extra frequency deviation for all recomended crystal
+ * Causes no extra frequency deviation for all recommended crystal
* values. See Note 1, table 40-16 SAM9260 doc.
*/
clk = at91_pmc_clock_ref("pllb");
diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c
index 082b24f..fdca46b 100644
--- a/sys/arm/at91/if_ate.c
+++ b/sys/arm/at91/if_ate.c
@@ -651,7 +651,7 @@ ate_activate(device_t dev)
ate_getaddr, &sc->tx_desc_phys, 0) != 0)
goto errout;
- /* Initilize descriptors; mark all empty */
+ /* Initialize descriptors; mark all empty */
for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
sc->tx_descs[i].addr =0;
sc->tx_descs[i].status = ETHB_TX_USED;
@@ -919,7 +919,7 @@ ate_intr(void *xsc)
/*
* Simulate SAM9 FIRST/LAST bits for RM9200.
* RM9200 EMAC has only on Rx buffer per packet.
- * But sometime we are handed a zero lenght packet.
+ * But sometime we are handed a zero length packet.
*/
if ((rxdhead->status & ETH_LEN_MASK) == 0)
rxdhead->status = 0; /* Mark error */
@@ -980,7 +980,7 @@ ate_intr(void *xsc)
do {
/* Last buffer may just be 1-4 bytes of FCS so remain
- * may be zero for last decriptor. */
+ * may be zero for last descriptor. */
if (remain > 0) {
/* Make sure we get the current bytes */
bus_dmamap_sync(sc->rx_tag, sc->rx_map[sc->rxhead],
@@ -989,7 +989,7 @@ ate_intr(void *xsc)
count = MIN(remain, sc->rx_buf_size);
/* XXX Performance robbing copy. Could
- * recieve directly to mbufs if not an
+ * receive directly to mbufs if not an
* RM9200. And even then we could likely
* copy just the protocol headers. XXX */
m_append(mb, count, sc->rx_buf[sc->rxhead]);
@@ -1468,7 +1468,7 @@ ate_miibus_readreg(device_t dev, int phy, int reg)
int val;
/*
- * XXX if we implement agressive power savings, then we need
+ * XXX if we implement aggressive power savings, then we need
* XXX to make sure that the clock to the emac is on here
*/
@@ -1488,7 +1488,7 @@ ate_miibus_writereg(device_t dev, int phy, int reg, int data)
struct ate_softc *sc;
/*
- * XXX if we implement agressive power savings, then we need
+ * XXX if we implement aggressive power savings, then we need
* XXX to make sure that the clock to the emac is on here
*/
diff --git a/sys/arm/at91/if_atereg.h b/sys/arm/at91/if_atereg.h
index fc7e4de..c6cbbcf 100644
--- a/sys/arm/at91/if_atereg.h
+++ b/sys/arm/at91/if_atereg.h
@@ -28,7 +28,7 @@
#ifndef ARM_AT91_IF_ATEREG_H
#define ARM_AT91_IF_ATEREG_H
-/* deines begining ETHB_ are EMACB (newer SAM9 hardware) versions only */
+/* Defines beginning ETHB_ are EMACB (newer SAM9 hardware) versions only. */
#define ETH_CTL 0x00 /* EMAC Control Register */
#define ETH_CFG 0x04 /* EMAC Configuration Register */
@@ -191,7 +191,7 @@ typedef struct {
#define ETH_MAC_LOCAL_3 (1U << 24) /* Packet matched addr 3 */
#define ETH_MAC_LOCAL_2 (1U << 25) /* Packet matched addr 2 */
#define ETH_MAC_LOCAL_1 (1U << 26) /* Packet matched addr 1 */
-#define ETH_MAC_UNK (1U << 27) /* Unkown source address RFU */
+#define ETH_MAC_UNK (1U << 27) /* Unknown source address RFU */
#define ETH_MAC_EXT (1U << 28) /* External Address */
#define ETH_MAC_UCAST (1U << 29) /* Unicast hash match */
#define ETH_MAC_MCAST (1U << 30) /* Multicast hash match */
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_audio.c b/sys/arm/broadcom/bcm2835/bcm2835_audio.c
index bfed287..8658c26 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_audio.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_audio.c
@@ -828,7 +828,7 @@ bcm2835_audio_attach(device_t dev)
/*
* We need interrupts enabled for VCHI to work properly,
- * so delay intialization until it happens
+ * so delay initialization until it happens.
*/
sc->intr_hook.ich_func = bcm2835_audio_delayed_init;
sc->intr_hook.ich_arg = sc;
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_dma.c b/sys/arm/broadcom/bcm2835/bcm2835_dma.c
index 347be2b..f174701 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_dma.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_dma.c
@@ -278,7 +278,7 @@ bcm_dma_init(device_t dev)
/*
* Least alignment for busdma-allocated stuff is cache
- * line size, so just make sure nothing stupid happend
+ * line size, so just make sure nothing stupid happened
* and we got properly aligned address
*/
if ((uintptr_t)cb_virt & 0x1f) {
@@ -539,7 +539,7 @@ bcm_dma_reg_dump(int ch)
* ch - channel number
* src, dst - source and destination address in
* ARM physical memory address space.
- * len - amount of bytes to be transfered
+ * len - amount of bytes to be transferred
*
* Returns 0 on success, -1 otherwise
*/
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
index 7c67a38..9619503 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
@@ -67,8 +67,16 @@ __FBSDID("$FreeBSD$");
#define BCM_GPIO_IRQS 4
#define BCM_GPIO_PINS 54
#define BCM_GPIO_PINS_PER_BANK 32
+
+#ifdef INTRNG
+#define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
+ GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | \
+ GPIO_INTR_LEVEL_HIGH | GPIO_INTR_EDGE_RISING | \
+ GPIO_INTR_EDGE_FALLING | GPIO_INTR_EDGE_BOTH)
+#else
#define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
+#endif
static struct resource_spec bcm_gpio_res_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
@@ -88,7 +96,7 @@ struct bcm_gpio_sysctl {
struct bcm_gpio_irqsrc {
struct intr_irqsrc bgi_isrc;
uint32_t bgi_irq;
- uint32_t bgi_reg;
+ uint32_t bgi_mode;
uint32_t bgi_mask;
};
#endif
@@ -894,6 +902,17 @@ bcm_gpio_detach(device_t dev)
#ifdef INTRNG
static inline void
+bcm_gpio_modify(struct bcm_gpio_softc *sc, uint32_t reg, uint32_t mask,
+ bool set_bits)
+{
+
+ if (set_bits)
+ BCM_GPIO_SET_BITS(sc, reg, mask);
+ else
+ BCM_GPIO_CLEAR_BITS(sc, reg, mask);
+}
+
+static inline void
bcm_gpio_isrc_eoi(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
{
uint32_t bank;
@@ -906,28 +925,64 @@ bcm_gpio_isrc_eoi(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
static inline bool
bcm_gpio_isrc_is_level(struct bcm_gpio_irqsrc *bgi)
{
- uint32_t bank;
- bank = BCM_GPIO_BANK(bgi->bgi_irq);
- return (bgi->bgi_reg == BCM_GPIO_GPHEN(bank) ||
- bgi->bgi_reg == BCM_GPIO_GPLEN(bank));
+ return (bgi->bgi_mode == GPIO_INTR_LEVEL_LOW ||
+ bgi->bgi_mode == GPIO_INTR_LEVEL_HIGH);
}
static inline void
bcm_gpio_isrc_mask(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
{
+ uint32_t bank;
+ bank = BCM_GPIO_BANK(bgi->bgi_irq);
BCM_GPIO_LOCK(sc);
- BCM_GPIO_CLEAR_BITS(sc, bgi->bgi_reg, bgi->bgi_mask);
- BCM_GPIO_UNLOCK(bcm_gpio_sc);
+ switch (bgi->bgi_mode) {
+ case GPIO_INTR_LEVEL_LOW:
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_LEVEL_HIGH:
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_RISING:
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_FALLING:
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_BOTH:
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
+ break;
+ }
+ BCM_GPIO_UNLOCK(sc);
}
static inline void
bcm_gpio_isrc_unmask(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
{
+ uint32_t bank;
+ bank = BCM_GPIO_BANK(bgi->bgi_irq);
BCM_GPIO_LOCK(sc);
- BCM_GPIO_SET_BITS(sc, bgi->bgi_reg, bgi->bgi_mask);
+ switch (bgi->bgi_mode) {
+ case GPIO_INTR_LEVEL_LOW:
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_LEVEL_HIGH:
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_RISING:
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_FALLING:
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_BOTH:
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
+ break;
+ }
BCM_GPIO_UNLOCK(sc);
}
@@ -983,7 +1038,7 @@ bcm_gpio_pic_attach(struct bcm_gpio_softc *sc)
for (irq = 0; irq < BCM_GPIO_PINS; irq++) {
sc->sc_isrcs[irq].bgi_irq = irq;
sc->sc_isrcs[irq].bgi_mask = BCM_GPIO_MASK(irq);
- sc->sc_isrcs[irq].bgi_reg = 0;
+ sc->sc_isrcs[irq].bgi_mode = GPIO_INTR_CONFORM;
error = intr_isrc_register(&sc->sc_isrcs[irq].bgi_isrc,
sc->sc_dev, 0, "%s,%u", name, irq);
@@ -1007,6 +1062,26 @@ bcm_gpio_pic_detach(struct bcm_gpio_softc *sc)
}
static void
+bcm_gpio_pic_config_intr(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi,
+ uint32_t mode)
+{
+ uint32_t bank;
+
+ bank = BCM_GPIO_BANK(bgi->bgi_irq);
+ BCM_GPIO_LOCK(sc);
+ bcm_gpio_modify(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask,
+ mode == GPIO_INTR_EDGE_RISING || mode == GPIO_INTR_EDGE_BOTH);
+ bcm_gpio_modify(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask,
+ mode == GPIO_INTR_EDGE_FALLING || mode == GPIO_INTR_EDGE_BOTH);
+ bcm_gpio_modify(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask,
+ mode == GPIO_INTR_LEVEL_HIGH);
+ bcm_gpio_modify(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask,
+ mode == GPIO_INTR_LEVEL_LOW);
+ bgi->bgi_mode = mode;
+ BCM_GPIO_UNLOCK(sc);
+}
+
+static void
bcm_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
{
struct bcm_gpio_softc *sc = device_get_softc(dev);
@@ -1026,11 +1101,11 @@ bcm_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
}
static int
-bcm_gpio_pic_map_fdt(struct bcm_gpio_softc *sc, u_int ncells, pcell_t *cells,
- u_int *irqp, uint32_t *regp)
+bcm_gpio_pic_map_fdt(struct bcm_gpio_softc *sc, struct intr_map_data_fdt *daf,
+ u_int *irqp, uint32_t *modep)
{
u_int irq;
- uint32_t reg, bank;
+ uint32_t mode, bank;
/*
* The first cell is the interrupt number.
@@ -1041,51 +1116,83 @@ bcm_gpio_pic_map_fdt(struct bcm_gpio_softc *sc, u_int ncells, pcell_t *cells,
* 4 = active high level-sensitive.
* 8 = active low level-sensitive.
*/
- if (ncells != 2)
+ if (daf->ncells != 2)
return (EINVAL);
- irq = cells[0];
+ irq = daf->cells[0];
if (irq >= BCM_GPIO_PINS || bcm_gpio_pin_is_ro(sc, irq))
return (EINVAL);
- /*
- * All interrupt types could be set for an interrupt at one moment.
- * At least, the combination of 'low-to-high' and 'high-to-low' edge
- * triggered interrupt types can make a sense. However, no combo is
- * supported now.
- */
+ /* Only reasonable modes are supported. */
bank = BCM_GPIO_BANK(irq);
- if (cells[1] == 1)
- reg = BCM_GPIO_GPREN(bank);
- else if (cells[1] == 2)
- reg = BCM_GPIO_GPFEN(bank);
- else if (cells[1] == 4)
- reg = BCM_GPIO_GPHEN(bank);
- else if (cells[1] == 8)
- reg = BCM_GPIO_GPLEN(bank);
+ if (daf->cells[1] == 1)
+ mode = GPIO_INTR_EDGE_RISING;
+ else if (daf->cells[1] == 2)
+ mode = GPIO_INTR_EDGE_FALLING;
+ else if (daf->cells[1] == 3)
+ mode = GPIO_INTR_EDGE_BOTH;
+ else if (daf->cells[1] == 4)
+ mode = GPIO_INTR_LEVEL_HIGH;
+ else if (daf->cells[1] == 8)
+ mode = GPIO_INTR_LEVEL_LOW;
else
return (EINVAL);
*irqp = irq;
- if (regp != NULL)
- *regp = reg;
+ if (modep != NULL)
+ *modep = mode;
+ return (0);
+}
+
+static int
+bcm_gpio_pic_map_gpio(struct bcm_gpio_softc *sc, struct intr_map_data_gpio *dag,
+ u_int *irqp, uint32_t *modep)
+{
+ u_int irq;
+ uint32_t mode;
+
+ irq = dag->gpio_pin_num;
+ if (irq >= BCM_GPIO_PINS || bcm_gpio_pin_is_ro(sc, irq))
+ return (EINVAL);
+
+ mode = dag->gpio_intr_mode;
+ if (mode != GPIO_INTR_LEVEL_LOW && mode != GPIO_INTR_LEVEL_HIGH &&
+ mode != GPIO_INTR_EDGE_RISING && mode != GPIO_INTR_EDGE_FALLING &&
+ mode != GPIO_INTR_EDGE_BOTH)
+ return (EINVAL);
+
+ *irqp = irq;
+ if (modep != NULL)
+ *modep = mode;
return (0);
}
static int
+bcm_gpio_pic_map(struct bcm_gpio_softc *sc, struct intr_map_data *data,
+ u_int *irqp, uint32_t *modep)
+{
+
+ switch (data->type) {
+ case INTR_MAP_DATA_FDT:
+ return (bcm_gpio_pic_map_fdt(sc,
+ (struct intr_map_data_fdt *)data, irqp, modep));
+ case INTR_MAP_DATA_GPIO:
+ return (bcm_gpio_pic_map_gpio(sc,
+ (struct intr_map_data_gpio *)data, irqp, modep));
+ default:
+ return (ENOTSUP);
+ }
+}
+
+static int
bcm_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
int error;
u_int irq;
- struct bcm_gpio_softc *sc;
-
- if (data->type != INTR_MAP_DATA_FDT)
- return (ENOTSUP);
+ struct bcm_gpio_softc *sc = device_get_softc(dev);
- sc = device_get_softc(dev);
- error = bcm_gpio_pic_map_fdt(sc, data->fdt.ncells, data->fdt.cells,
- &irq, NULL);
+ error = bcm_gpio_pic_map(sc, data, &irq, NULL);
if (error == 0)
*isrcp = &sc->sc_isrcs[irq].bgi_isrc;
return (error);
@@ -1124,19 +1231,18 @@ bcm_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
u_int irq;
- uint32_t bank, reg;
+ uint32_t mode;
struct bcm_gpio_softc *sc;
struct bcm_gpio_irqsrc *bgi;
- if (data == NULL || data->type != INTR_MAP_DATA_FDT)
+ if (data == NULL)
return (ENOTSUP);
sc = device_get_softc(dev);
bgi = (struct bcm_gpio_irqsrc *)isrc;
/* Get and check config for an interrupt. */
- if (bcm_gpio_pic_map_fdt(sc, data->fdt.ncells, data->fdt.cells, &irq,
- &reg) != 0 || bgi->bgi_irq != irq)
+ if (bcm_gpio_pic_map(sc, data, &irq, &mode) != 0 || bgi->bgi_irq != irq)
return (EINVAL);
/*
@@ -1144,17 +1250,9 @@ bcm_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
* only check that its configuration match.
*/
if (isrc->isrc_handlers != 0)
- return (bgi->bgi_reg == reg ? 0 : EINVAL);
+ return (bgi->bgi_mode == mode ? 0 : EINVAL);
- bank = BCM_GPIO_BANK(irq);
- BCM_GPIO_LOCK(sc);
- BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
- BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
- BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask);
- BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask);
- bgi->bgi_reg = reg;
- BCM_GPIO_SET_BITS(sc, reg, bgi->bgi_mask);
- BCM_GPIO_UNLOCK(sc);
+ bcm_gpio_pic_config_intr(sc, bgi, mode);
return (0);
}
@@ -1165,12 +1263,8 @@ bcm_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
struct bcm_gpio_softc *sc = device_get_softc(dev);
struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
- if (isrc->isrc_handlers == 0) {
- BCM_GPIO_LOCK(sc);
- BCM_GPIO_CLEAR_BITS(sc, bgi->bgi_reg, bgi->bgi_mask);
- bgi->bgi_reg = 0;
- BCM_GPIO_UNLOCK(sc);
- }
+ if (isrc->isrc_handlers == 0)
+ bcm_gpio_pic_config_intr(sc, bgi, GPIO_INTR_CONFORM);
return (0);
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_intr.c b/sys/arm/broadcom/bcm2835/bcm2835_intr.c
index 8124c96..39ad5f7 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_intr.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_intr.c
@@ -268,14 +268,17 @@ bcm_intc_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
u_int irq;
+ struct intr_map_data_fdt *daf;
struct bcm_intc_softc *sc;
if (data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- if (data->fdt.ncells == 1)
- irq = data->fdt.cells[0];
- else if (data->fdt.ncells == 2)
- irq = data->fdt.cells[0] * 32 + data->fdt.cells[1];
+
+ daf = (struct intr_map_data_fdt *)data;
+ if (daf->ncells == 1)
+ irq = daf->cells[0];
+ else if (daf->ncells == 2)
+ irq = daf->cells[0] * 32 + daf->cells[1];
else
return (EINVAL);
diff --git a/sys/arm/broadcom/bcm2835/bcm2836.c b/sys/arm/broadcom/bcm2835/bcm2836.c
index 16c1e4b..3991609 100644
--- a/sys/arm/broadcom/bcm2835/bcm2836.c
+++ b/sys/arm/broadcom/bcm2835/bcm2836.c
@@ -461,15 +461,18 @@ static int
bcm_lintc_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct bcm_lintc_softc *sc;
if (data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- if (data->fdt.ncells != 1 || data->fdt.cells[0] >= BCM_LINTC_NIRQS)
+
+ daf = (struct intr_map_data_fdt *)data;
+ if (daf->ncells != 1 || daf->cells[0] >= BCM_LINTC_NIRQS)
return (EINVAL);
sc = device_get_softc(dev);
- *isrcp = &sc->bls_isrcs[data->fdt.cells[0]].bli_isrc;
+ *isrcp = &sc->bls_isrcs[daf->cells[0]].bli_isrc;
return (0);
}
diff --git a/sys/arm/cavium/cns11xx/if_ece.c b/sys/arm/cavium/cns11xx/if_ece.c
index 2ae3d22..9ed5cbd 100644
--- a/sys/arm/cavium/cns11xx/if_ece.c
+++ b/sys/arm/cavium/cns11xx/if_ece.c
@@ -1685,7 +1685,7 @@ ece_encap(struct ece_softc *sc, struct mbuf *m0)
/*
* After all descriptors are set, we set the flags to start the
- * sending proces.
+ * sending process.
*/
for (seg = 0; seg < nsegs; seg++) {
desc->cown = 0;
diff --git a/sys/arm/conf/ALLWINNER b/sys/arm/conf/ALLWINNER
index 9bb0e0a..3d0acb5 100644
--- a/sys/arm/conf/ALLWINNER
+++ b/sys/arm/conf/ALLWINNER
@@ -28,6 +28,7 @@ options INTRNG
options SOC_ALLWINNER_A20
options SOC_ALLWINNER_A31
options SOC_ALLWINNER_A31S
+options SOC_ALLWINNER_A83T
options HZ=100
options SCHED_ULE # ULE scheduler
@@ -121,6 +122,7 @@ device bpf
#device emac # 10/100 integrated EMAC controller
device dwc # 10/100/1000 integrated GMAC controller
+device awg # 10/100/1000 integrated EMAC controller
# USB ethernet support, requires miibus
device miibus
diff --git a/sys/arm/freescale/imx/imx6_ipu.c b/sys/arm/freescale/imx/imx6_ipu.c
index d1efbff..f561fa7 100644
--- a/sys/arm/freescale/imx/imx6_ipu.c
+++ b/sys/arm/freescale/imx/imx6_ipu.c
@@ -872,7 +872,7 @@ ipu_init_buffer(struct ipu_softc *sc)
stride = sc->sc_mode->hdisplay * MODE_BPP / 8;
- /* init channel paramters */
+ /* init channel parameters */
CH_PARAM_RESET(&param);
/* XXX: interlaced modes are not supported yet */
CH_PARAM_SET_FW(&param, sc->sc_mode->hdisplay - 1);
diff --git a/sys/arm/freescale/imx/imx6_ssi.c b/sys/arm/freescale/imx/imx6_ssi.c
index 9387aa3..9000ae3 100644
--- a/sys/arm/freescale/imx/imx6_ssi.c
+++ b/sys/arm/freescale/imx/imx6_ssi.c
@@ -738,7 +738,7 @@ ssi_attach(device_t dev)
sc->lock = snd_mtxcreate(device_get_nameunit(dev), "ssi softc");
if (sc->lock == NULL) {
- device_printf(dev, "Cant create mtx\n");
+ device_printf(dev, "Can't create mtx\n");
return (ENXIO);
}
@@ -764,7 +764,7 @@ ssi_attach(device_t dev)
/*
* Maximum possible DMA buffer.
- * Will be used partialy to match 24 bit word.
+ * Will be used partially to match 24 bit word.
*/
sc->dma_size = 131072;
diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c
index ba82f5c..c5f7b8c 100644
--- a/sys/arm/freescale/imx/imx_gpio.c
+++ b/sys/arm/freescale/imx/imx_gpio.c
@@ -225,13 +225,15 @@ gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
{
int error;
u_int irq;
+ struct intr_map_data_fdt *daf;
struct imx51_gpio_softc *sc;
if (data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- error = gpio_pic_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
- NULL, NULL);
+ daf = (struct intr_map_data_fdt *)data;
+ error = gpio_pic_map_fdt(dev, daf->ncells, daf->cells, &irq, NULL,
+ NULL);
if (error == 0) {
sc = device_get_softc(dev);
*isrcp = &sc->gpio_pic_irqsrc[irq].gi_isrc;
@@ -265,6 +267,7 @@ static int
gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
+ struct intr_map_data_fdt *daf;
struct imx51_gpio_softc *sc;
struct gpio_irqsrc *gi;
int error, icfg;
@@ -278,8 +281,9 @@ gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
/* Get config for interrupt. */
if (data == NULL || data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- error = gpio_pic_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
- &pol, &trig);
+ daf = (struct intr_map_data_fdt *)data;
+ error = gpio_pic_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol,
+ &trig);
if (error != 0)
return (error);
if (gi->gi_irq != irq)
diff --git a/sys/arm/freescale/vybrid/vf_uart.c b/sys/arm/freescale/vybrid/vf_uart.c
index 312f18c..61a08fb 100644
--- a/sys/arm/freescale/vybrid/vf_uart.c
+++ b/sys/arm/freescale/vybrid/vf_uart.c
@@ -205,7 +205,7 @@ uart_reinit(struct uart_softc *sc, int clkspeed, int baud)
bas = &sc->sc_bas;
if (!bas) {
- printf("Error: cant reconfigure bas\n");
+ printf("Error: can't reconfigure bas\n");
return;
}
diff --git a/sys/arm/mv/mpic.c b/sys/arm/mv/mpic.c
index 4c5856a..7e07d66 100644
--- a/sys/arm/mv/mpic.c
+++ b/sys/arm/mv/mpic.c
@@ -339,15 +339,19 @@ static int
mpic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct mv_mpic_softc *sc;
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
sc = device_get_softc(dev);
+ daf = (struct intr_map_data_fdt *)data;
- if (data->type != INTR_MAP_DATA_FDT || data->fdt.ncells !=1 ||
- data->fdt.cells[0] >= sc->nirqs)
+ if (daf->ncells !=1 || daf->cells[0] >= sc->nirqs)
return (EINVAL);
- *isrcp = &sc->mpic_isrcs[data->fdt.cells[0]].mmi_isrc;
+ *isrcp = &sc->mpic_isrcs[daf->cells[0]].mmi_isrc;
return (0);
}
@@ -564,7 +568,7 @@ mv_msi_data(int irq, uint64_t *addr, uint32_t *data)
node = ofw_bus_get_node(mv_mpic_sc->sc_dev);
- /* Get physical addres of register space */
+ /* Get physical address of register space */
error = fdt_get_range(OF_parent(node), 0, &phys, &size);
if (error) {
printf("%s: Cannot get register physical address, err:%d",
diff --git a/sys/arm/mv/mv_common.c b/sys/arm/mv/mv_common.c
index 2bd13f6..55e3cd1 100644
--- a/sys/arm/mv/mv_common.c
+++ b/sys/arm/mv/mv_common.c
@@ -1398,7 +1398,7 @@ decode_win_pcie_setup(u_long base)
/*
* Upper 16 bits in BAR register is interpreted as BAR size
- * (in 64 kB units) plus 64kB, so substract 0x10000
+ * (in 64 kB units) plus 64kB, so subtract 0x10000
* form value passed to register to get correct value.
*/
size -= 0x10000;
diff --git a/sys/arm/nvidia/tegra_gpio.c b/sys/arm/nvidia/tegra_gpio.c
index 0b2b081..7329ce0 100644
--- a/sys/arm/nvidia/tegra_gpio.c
+++ b/sys/arm/nvidia/tegra_gpio.c
@@ -579,14 +579,19 @@ tegra_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
sc = device_get_softc(dev);
- if (data->type == INTR_MAP_DATA_FDT)
- rv = tegra_gpio_pic_map_fdt(sc, data->fdt.ncells,
- data->fdt.cells, &irq, NULL);
- else if (data->type == INTR_MAP_DATA_GPIO)
- rv = tegra_gpio_pic_map_gpio(sc, data->gpio.gpio_pin_num,
- data->gpio.gpio_pin_flags, data->gpio.gpio_intr_mode,
- &irq, NULL);
- else
+ if (data->type == INTR_MAP_DATA_FDT) {
+ struct intr_map_data_fdt *daf;
+
+ daf = (struct intr_map_data_fdt *)data;
+ rv = tegra_gpio_pic_map_fdt(sc, daf->ncells, daf->cells, &irq,
+ NULL);
+ } else if (data->type == INTR_MAP_DATA_GPIO) {
+ struct intr_map_data_gpio *dag;
+
+ dag = (struct intr_map_data_gpio *)data;
+ rv = tegra_gpio_pic_map_gpio(sc, dag->gpio_pin_num,
+ dag->gpio_pin_flags, dag->gpio_intr_mode, &irq, NULL);
+ } else
return (ENOTSUP);
if (rv == 0)
@@ -648,14 +653,19 @@ tegra_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
return (ENOTSUP);
/* Get and check config for an interrupt. */
- if (data->type == INTR_MAP_DATA_FDT)
- rv = tegra_gpio_pic_map_fdt(sc, data->fdt.ncells,
- data->fdt.cells, &irq, &cfgreg);
- else if (data->type == INTR_MAP_DATA_GPIO)
- rv = tegra_gpio_pic_map_gpio(sc, data->gpio.gpio_pin_num,
- data->gpio.gpio_pin_flags, data->gpio.gpio_intr_mode,
- &irq, &cfgreg);
- else
+ if (data->type == INTR_MAP_DATA_FDT) {
+ struct intr_map_data_fdt *daf;
+
+ daf = (struct intr_map_data_fdt *)data;
+ rv = tegra_gpio_pic_map_fdt(sc, daf->ncells, daf->cells, &irq,
+ &cfgreg);
+ } else if (data->type == INTR_MAP_DATA_GPIO) {
+ struct intr_map_data_gpio *dag;
+
+ dag = (struct intr_map_data_gpio *)data;
+ rv = tegra_gpio_pic_map_gpio(sc, dag->gpio_pin_num,
+ dag->gpio_pin_flags, dag->gpio_intr_mode, &irq, &cfgreg);
+ } else
return (ENOTSUP);
if (rv != 0)
return (EINVAL);
diff --git a/sys/arm/qemu/virt_machdep.c b/sys/arm/qemu/virt_machdep.c
index 95cc225..d15b97c 100644
--- a/sys/arm/qemu/virt_machdep.c
+++ b/sys/arm/qemu/virt_machdep.c
@@ -97,3 +97,20 @@ static platform_method_t virt_methods[] = {
};
FDT_PLATFORM_DEF(virt, "virt", 0, "linux,dummy-virt", 1);
+
+static int
+gem5_devmap_init(platform_t plat)
+{
+
+ devmap_add_entry(0x1c090000, 0x100000); /* Uart */
+ return (0);
+}
+
+static platform_method_t gem5_methods[] = {
+ PLATFORMMETHOD(platform_devmap_init, gem5_devmap_init),
+ PLATFORMMETHOD(platform_lastaddr, virt_lastaddr),
+
+ PLATFORMMETHOD_END,
+};
+
+FDT_PLATFORM_DEF(gem5, "gem5", 0, "arm,vexpress", 1);
diff --git a/sys/arm/samsung/exynos/exynos5_usb_phy.c b/sys/arm/samsung/exynos/exynos5_usb_phy.c
index 2756efb..430c8f8 100644
--- a/sys/arm/samsung/exynos/exynos5_usb_phy.c
+++ b/sys/arm/samsung/exynos/exynos5_usb_phy.c
@@ -161,7 +161,7 @@ vbus_on(struct usb_phy_softc *sc)
gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
if (gpio_dev == NULL) {
- device_printf(sc->dev, "cant find gpio_dev\n");
+ device_printf(sc->dev, "can't find gpio_dev\n");
return (1);
}
diff --git a/sys/arm/ti/aintc.c b/sys/arm/ti/aintc.c
index ebe4864..5fb4695 100644
--- a/sys/arm/ti/aintc.c
+++ b/sys/arm/ti/aintc.c
@@ -178,14 +178,18 @@ static int
ti_aintc_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct ti_aintc_softc *sc;
- if (data->type != INTR_MAP_DATA_FDT || data->fdt.ncells != 1 ||
- data->fdt.cells[0] >= INTC_NIRQS)
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
+ daf = (struct intr_map_data_fdt *)data;
+ if (daf->ncells != 1 || daf->cells[0] >= INTC_NIRQS)
return (EINVAL);
sc = device_get_softc(dev);
- *isrcp = &sc->aintc_isrcs[data->fdt.cells[0]].tai_isrc;
+ *isrcp = &sc->aintc_isrcs[daf->cells[0]].tai_isrc;
return (0);
}
diff --git a/sys/arm/ti/omap4/omap4_prcm_clks.c b/sys/arm/ti/omap4/omap4_prcm_clks.c
index e83e6ee..e17fe3d 100644
--- a/sys/arm/ti/omap4/omap4_prcm_clks.c
+++ b/sys/arm/ti/omap4/omap4_prcm_clks.c
@@ -1329,7 +1329,7 @@ omap4_clk_hsusbhost_accessible(struct ti_clock_dev *clkdev)
* Inherits the locks from the omap_prcm driver, no internal locking.
*
* RETURNS:
- * Returns 0 if sucessful otherwise a negative error code on failure.
+ * Returns 0 if successful otherwise a negative error code on failure.
*/
static int
omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev,
diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c
index 54e5042..a67884e 100644
--- a/sys/arm/ti/ti_gpio.c
+++ b/sys/arm/ti/ti_gpio.c
@@ -290,7 +290,7 @@ ti_gpio_valid_pin(struct ti_gpio_softc *sc, int pin)
}
/**
- * ti_gpio_pin_getcaps - Gets the capabilties of a given pin
+ * ti_gpio_pin_getcaps - Gets the capabilities of a given pin
* @dev: gpio device handle
* @pin: the number of the pin
* @caps: pointer to a value that upon return will contain the capabilities
@@ -300,6 +300,11 @@ ti_gpio_valid_pin(struct ti_gpio_softc *sc, int pin)
* - GPIO_PIN_OUTPUT
* - GPIO_PIN_PULLUP
* - GPIO_PIN_PULLDOWN
+ * - GPIO_INTR_LEVEL_LOW
+ * - GPIO_INTR_LEVEL_HIGH
+ * - GPIO_INTR_EDGE_RISING
+ * - GPIO_INTR_EDGE_FALLING
+ * - GPIO_INTR_EDGE_BOTH
*
* LOCKING:
* No locking required, returns static data.
@@ -316,8 +321,15 @@ ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
if (ti_gpio_valid_pin(sc, pin) != 0)
return (EINVAL);
+#ifdef INTRNG
+ *caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP |
+ GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH |
+ GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING |
+ GPIO_INTR_EDGE_BOTH);
+#else
*caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP |
GPIO_PIN_PULLDOWN);
+#endif
return (0);
}
@@ -800,17 +812,13 @@ ti_gpio_detach(device_t dev)
#ifdef INTRNG
static inline void
-ti_gpio_rwreg_set(struct ti_gpio_softc *sc, uint32_t reg, uint32_t mask)
-{
-
- ti_gpio_write_4(sc, reg, ti_gpio_read_4(sc, reg) | mask);
-}
-
-static inline void
-ti_gpio_rwreg_clr(struct ti_gpio_softc *sc, uint32_t reg, uint32_t mask)
+ti_gpio_rwreg_modify(struct ti_gpio_softc *sc, uint32_t reg, uint32_t mask,
+ bool set_bits)
{
+ uint32_t value;
- ti_gpio_write_4(sc, reg, ti_gpio_read_4(sc, reg) & ~mask);
+ value = ti_gpio_read_4(sc, reg);
+ ti_gpio_write_4(sc, reg, set_bits ? value | mask : value & ~mask);
}
static inline void
@@ -841,8 +849,8 @@ static inline bool
ti_gpio_isrc_is_level(struct ti_gpio_irqsrc *tgi)
{
- return (tgi->tgi_cfgreg == TI_GPIO_LEVELDETECT0 ||
- tgi->tgi_cfgreg == TI_GPIO_LEVELDETECT1);
+ return (tgi->tgi_mode == GPIO_INTR_LEVEL_LOW ||
+ tgi->tgi_mode == GPIO_INTR_LEVEL_HIGH);
}
static int
@@ -889,7 +897,7 @@ ti_gpio_pic_attach(struct ti_gpio_softc *sc)
for (irq = 0; irq < sc->sc_maxpin; irq++) {
sc->sc_isrcs[irq].tgi_irq = irq;
sc->sc_isrcs[irq].tgi_mask = TI_GPIO_MASK(irq);
- sc->sc_isrcs[irq].tgi_cfgreg = 0;
+ sc->sc_isrcs[irq].tgi_mode = GPIO_INTR_CONFORM;
error = intr_isrc_register(&sc->sc_isrcs[irq].tgi_isrc,
sc->sc_dev, 0, "%s,%u", name, irq);
@@ -913,6 +921,24 @@ ti_gpio_pic_detach(struct ti_gpio_softc *sc)
}
static void
+ti_gpio_pic_config_intr(struct ti_gpio_softc *sc, struct ti_gpio_irqsrc *tgi,
+ uint32_t mode)
+{
+
+ TI_GPIO_LOCK(sc);
+ ti_gpio_rwreg_modify(sc, TI_GPIO_RISINGDETECT, tgi->tgi_mask,
+ mode == GPIO_INTR_EDGE_RISING || mode == GPIO_INTR_EDGE_BOTH);
+ ti_gpio_rwreg_modify(sc, TI_GPIO_FALLINGDETECT, tgi->tgi_mask,
+ mode == GPIO_INTR_EDGE_FALLING || mode == GPIO_INTR_EDGE_BOTH);
+ ti_gpio_rwreg_modify(sc, TI_GPIO_LEVELDETECT1, tgi->tgi_mask,
+ mode == GPIO_INTR_LEVEL_HIGH);
+ ti_gpio_rwreg_modify(sc, TI_GPIO_LEVELDETECT0, tgi->tgi_mask,
+ mode == GPIO_INTR_LEVEL_LOW);
+ tgi->tgi_mode = mode;
+ TI_GPIO_UNLOCK(sc);
+}
+
+static void
ti_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
@@ -932,10 +958,10 @@ ti_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
}
static int
-ti_gpio_pic_map_fdt(struct ti_gpio_softc *sc, u_int ncells, pcell_t *cells,
- u_int *irqp, uint32_t *regp)
+ti_gpio_pic_map_fdt(struct ti_gpio_softc *sc, struct intr_map_data_fdt *daf,
+ u_int *irqp, uint32_t *modep)
{
- uint32_t reg;
+ uint32_t mode;
/*
* The first cell is the interrupt number.
@@ -946,46 +972,76 @@ ti_gpio_pic_map_fdt(struct ti_gpio_softc *sc, u_int ncells, pcell_t *cells,
* 4 = active high level-sensitive.
* 8 = active low level-sensitive.
*/
- if (ncells != 2 || cells[0] >= sc->sc_maxpin)
+ if (daf->ncells != 2 || daf->cells[0] >= sc->sc_maxpin)
return (EINVAL);
- /*
- * All interrupt types could be set for an interrupt at one moment.
- * At least, the combination of 'low-to-high' and 'high-to-low' edge
- * triggered interrupt types can make a sense. However, no combo is
- * supported now.
- */
- if (cells[1] == 1)
- reg = TI_GPIO_RISINGDETECT;
- else if (cells[1] == 2)
- reg = TI_GPIO_FALLINGDETECT;
- else if (cells[1] == 4)
- reg = TI_GPIO_LEVELDETECT1;
- else if (cells[1] == 8)
- reg = TI_GPIO_LEVELDETECT0;
+ /* Only reasonable modes are supported. */
+ if (daf->cells[1] == 1)
+ mode = GPIO_INTR_EDGE_RISING;
+ else if (daf->cells[1] == 2)
+ mode = GPIO_INTR_EDGE_FALLING;
+ else if (daf->cells[1] == 3)
+ mode = GPIO_INTR_EDGE_BOTH;
+ else if (daf->cells[1] == 4)
+ mode = GPIO_INTR_LEVEL_HIGH;
+ else if (daf->cells[1] == 8)
+ mode = GPIO_INTR_LEVEL_LOW;
else
return (EINVAL);
- *irqp = cells[0];
- if (regp != NULL)
- *regp = reg;
+ *irqp = daf->cells[0];
+ if (modep != NULL)
+ *modep = mode;
return (0);
}
static int
+ti_gpio_pic_map_gpio(struct ti_gpio_softc *sc, struct intr_map_data_gpio *dag,
+ u_int *irqp, uint32_t *modep)
+{
+ uint32_t mode;
+
+ if (dag->gpio_pin_num >= sc->sc_maxpin)
+ return (EINVAL);
+
+ mode = dag->gpio_intr_mode;
+ if (mode != GPIO_INTR_LEVEL_LOW && mode != GPIO_INTR_LEVEL_HIGH &&
+ mode != GPIO_INTR_EDGE_RISING && mode != GPIO_INTR_EDGE_FALLING &&
+ mode != GPIO_INTR_EDGE_BOTH)
+ return (EINVAL);
+
+ *irqp = dag->gpio_pin_num;
+ if (modep != NULL)
+ *modep = mode;
+ return (0);
+}
+
+static int
+ti_gpio_pic_map(struct ti_gpio_softc *sc, struct intr_map_data *data,
+ u_int *irqp, uint32_t *modep)
+{
+
+ switch (data->type) {
+ case INTR_MAP_DATA_FDT:
+ return (ti_gpio_pic_map_fdt(sc,
+ (struct intr_map_data_fdt *)data, irqp, modep));
+ case INTR_MAP_DATA_GPIO:
+ return (ti_gpio_pic_map_gpio(sc,
+ (struct intr_map_data_gpio *)data, irqp, modep));
+ default:
+ return (ENOTSUP);
+ }
+}
+
+static int
ti_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
int error;
u_int irq;
- struct ti_gpio_softc *sc;
-
- if (data->type != INTR_MAP_DATA_FDT)
- return (ENOTSUP);
+ struct ti_gpio_softc *sc = device_get_softc(dev);
- sc = device_get_softc(dev);
- error = ti_gpio_pic_map_fdt(sc, data->fdt.ncells, data->fdt.cells, &irq,
- NULL);
+ error = ti_gpio_pic_map(sc, data, &irq, NULL);
if (error == 0)
*isrcp = &sc->sc_isrcs[irq].tgi_isrc;
return (error);
@@ -1024,19 +1080,18 @@ ti_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
u_int irq;
- uint32_t cfgreg;
+ uint32_t mode;
struct ti_gpio_softc *sc;
struct ti_gpio_irqsrc *tgi;
- if (data == NULL || data->type != INTR_MAP_DATA_FDT)
+ if (data == NULL)
return (ENOTSUP);
sc = device_get_softc(dev);
tgi = (struct ti_gpio_irqsrc *)isrc;
/* Get and check config for an interrupt. */
- if (ti_gpio_pic_map_fdt(sc, data->fdt.ncells, data->fdt.cells, &irq,
- &cfgreg) != 0 || tgi->tgi_irq != irq)
+ if (ti_gpio_pic_map(sc, data, &irq, &mode) != 0 || tgi->tgi_irq != irq)
return (EINVAL);
/*
@@ -1044,16 +1099,9 @@ ti_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
* only check that its configuration match.
*/
if (isrc->isrc_handlers != 0)
- return (tgi->tgi_cfgreg == cfgreg ? 0 : EINVAL);
+ return (tgi->tgi_mode == mode ? 0 : EINVAL);
- TI_GPIO_LOCK(sc);
- ti_gpio_rwreg_clr(sc, TI_GPIO_RISINGDETECT, tgi->tgi_mask);
- ti_gpio_rwreg_clr(sc, TI_GPIO_FALLINGDETECT, tgi->tgi_mask);
- ti_gpio_rwreg_clr(sc, TI_GPIO_LEVELDETECT1, tgi->tgi_mask);
- ti_gpio_rwreg_clr(sc, TI_GPIO_LEVELDETECT0, tgi->tgi_mask);
- tgi->tgi_cfgreg = cfgreg;
- ti_gpio_rwreg_set(sc, cfgreg, tgi->tgi_mask);
- TI_GPIO_UNLOCK(sc);
+ ti_gpio_pic_config_intr(sc, tgi, mode);
return (0);
}
@@ -1064,12 +1112,8 @@ ti_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
struct ti_gpio_softc *sc = device_get_softc(dev);
struct ti_gpio_irqsrc *tgi = (struct ti_gpio_irqsrc *)isrc;
- if (isrc->isrc_handlers == 0) {
- TI_GPIO_LOCK(sc);
- ti_gpio_rwreg_clr(sc, tgi->tgi_cfgreg, tgi->tgi_mask);
- tgi->tgi_cfgreg = 0;
- TI_GPIO_UNLOCK(sc);
- }
+ if (isrc->isrc_handlers == 0)
+ ti_gpio_pic_config_intr(sc, tgi, GPIO_INTR_CONFORM);
return (0);
}
diff --git a/sys/arm/ti/ti_gpio.h b/sys/arm/ti/ti_gpio.h
index 174dd62..c9785dd 100644
--- a/sys/arm/ti/ti_gpio.h
+++ b/sys/arm/ti/ti_gpio.h
@@ -49,7 +49,7 @@ struct ti_gpio_irqsrc {
struct intr_irqsrc tgi_isrc;
u_int tgi_irq;
uint32_t tgi_mask;
- uint32_t tgi_cfgreg;
+ uint32_t tgi_mode;
};
#endif
diff --git a/sys/arm/ti/ti_i2c.c b/sys/arm/ti/ti_i2c.c
index 92a44a7..55336ff 100644
--- a/sys/arm/ti/ti_i2c.c
+++ b/sys/arm/ti/ti_i2c.c
@@ -236,7 +236,7 @@ ti_i2c_transfer_intr(struct ti_i2c_softc* sc, uint16_t status)
if (status & I2C_STAT_RDR) {
/*
* Receive draining interrupt - last data received.
- * The set FIFO threshold wont be reached to trigger
+ * The set FIFO threshold won't be reached to trigger
* RRDY.
*/
ti_i2c_dbg(sc, "Receive draining interrupt\n");
@@ -272,7 +272,7 @@ ti_i2c_transfer_intr(struct ti_i2c_softc* sc, uint16_t status)
/*
* Transmit draining interrupt - FIFO level is below
* the set threshold and the amount of data still to
- * be transferred wont reach the set FIFO threshold.
+ * be transferred won't reach the set FIFO threshold.
*/
ti_i2c_dbg(sc, "Transmit draining interrupt\n");
diff --git a/sys/arm/ti/ti_pinmux.c b/sys/arm/ti/ti_pinmux.c
index ff4743d..ffeaf75 100644
--- a/sys/arm/ti/ti_pinmux.c
+++ b/sys/arm/ti/ti_pinmux.c
@@ -394,7 +394,7 @@ ti_pinmux_probe(device_t dev)
* @dev: new device
*
* RETURNS
- * Zero on sucess or ENXIO if an error occuried.
+ * Zero on success or ENXIO if an error occuried.
*/
static int
ti_pinmux_attach(device_t dev)
diff --git a/sys/arm/ti/ti_prcm.c b/sys/arm/ti/ti_prcm.c
index c5ab9c7..d742d07 100644
--- a/sys/arm/ti/ti_prcm.c
+++ b/sys/arm/ti/ti_prcm.c
@@ -31,7 +31,7 @@
*/
/**
- * Power, Reset and Clock Managment Module
+ * Power, Reset and Clock Management Module
*
* This is a very simple driver wrapper around the PRCM set of registers in
* the OMAP3 chip. It allows you to turn on and off things like the functional
diff --git a/sys/arm/ti/ti_scm.c b/sys/arm/ti/ti_scm.c
index 14e9200..5608265 100644
--- a/sys/arm/ti/ti_scm.c
+++ b/sys/arm/ti/ti_scm.c
@@ -111,7 +111,7 @@ ti_scm_probe(device_t dev)
* globally and registers both the timecount and eventtimer objects.
*
* RETURNS
- * Zero on sucess or ENXIO if an error occuried.
+ * Zero on success or ENXIO if an error occuried.
*/
static int
ti_scm_attach(device_t dev)
diff --git a/sys/arm/ti/ti_sdma.c b/sys/arm/ti/ti_sdma.c
index a8faba8..7e5e957 100644
--- a/sys/arm/ti/ti_sdma.c
+++ b/sys/arm/ti/ti_sdma.c
@@ -446,7 +446,7 @@ ti_sdma_deactivate_channel(unsigned int ch)
* ti_sdma_disable_channel_irq - disables IRQ's on the given channel
* @ch: the channel to disable IRQ's on
*
- * Disable interupt generation for the given channel.
+ * Disable interrupt generation for the given channel.
*
* LOCKING:
* DMA registers protected by internal mutex
@@ -608,7 +608,7 @@ ti_sdma_get_channel_status(unsigned int ch, uint32_t *status)
/**
* ti_sdma_start_xfer - starts a DMA transfer
- * @ch: the channel number to set the endianess of
+ * @ch: the channel number to set the endianness of
* @src_paddr: the source phsyical address
* @dst_paddr: the destination phsyical address
* @frmcnt: the number of frames per block
@@ -707,7 +707,7 @@ ti_sdma_start_xfer(unsigned int ch, unsigned int src_paddr,
* frmcnt = 1, elmcnt = 512, pktsize = 128
*
* Total transfer bytes = 1 * 512 = 512 elements or 2048 bytes
- * Packets transfered = 128 / 512 = 4
+ * Packets transferred = 128 / 512 = 4
*
*
* LOCKING:
@@ -787,7 +787,7 @@ ti_sdma_start_xfer_packet(unsigned int ch, unsigned int src_paddr,
/**
* ti_sdma_stop_xfer - stops any currently active transfers
- * @ch: the channel number to set the endianess of
+ * @ch: the channel number to set the endianness of
*
* This function call is effectively a NOP if no transaction is in progress.
*
@@ -835,10 +835,10 @@ ti_sdma_stop_xfer(unsigned int ch)
}
/**
- * ti_sdma_set_xfer_endianess - sets the endianess of subsequent transfers
- * @ch: the channel number to set the endianess of
- * @src: the source endianess (either DMA_ENDIAN_LITTLE or DMA_ENDIAN_BIG)
- * @dst: the destination endianess (either DMA_ENDIAN_LITTLE or DMA_ENDIAN_BIG)
+ * ti_sdma_set_xfer_endianess - sets the endianness of subsequent transfers
+ * @ch: the channel number to set the endianness of
+ * @src: the source endianness (either DMA_ENDIAN_LITTLE or DMA_ENDIAN_BIG)
+ * @dst: the destination endianness (either DMA_ENDIAN_LITTLE or DMA_ENDIAN_BIG)
*
*
* LOCKING:
@@ -879,9 +879,9 @@ ti_sdma_set_xfer_endianess(unsigned int ch, unsigned int src, unsigned int dst)
/**
* ti_sdma_set_xfer_burst - sets the source and destination element size
* @ch: the channel number to set the burst settings of
- * @src: the source endianess (either DMA_BURST_NONE, DMA_BURST_16, DMA_BURST_32
+ * @src: the source endianness (either DMA_BURST_NONE, DMA_BURST_16, DMA_BURST_32
* or DMA_BURST_64)
- * @dst: the destination endianess (either DMA_BURST_NONE, DMA_BURST_16,
+ * @dst: the destination endianness (either DMA_BURST_NONE, DMA_BURST_16,
* DMA_BURST_32 or DMA_BURST_64)
*
* This function sets the size of the elements for all subsequent transfers.
@@ -923,7 +923,7 @@ ti_sdma_set_xfer_burst(unsigned int ch, unsigned int src, unsigned int dst)
/**
* ti_sdma_set_xfer_data_type - driver attach function
- * @ch: the channel number to set the endianess of
+ * @ch: the channel number to set the endianness of
* @type: the xfer data type (either DMA_DATA_8BITS_SCALAR, DMA_DATA_16BITS_SCALAR
* or DMA_DATA_32BITS_SCALAR)
*
@@ -1065,7 +1065,7 @@ ti_sdma_sync_params(unsigned int ch, unsigned int trigger, unsigned int mode)
/**
* ti_sdma_set_addr_mode - driver attach function
- * @ch: the channel number to set the endianess of
+ * @ch: the channel number to set the endianness of
* @rd_mode: the xfer source addressing mode (either DMA_ADDR_CONSTANT,
* DMA_ADDR_POST_INCREMENT, DMA_ADDR_SINGLE_INDEX or
* DMA_ADDR_DOUBLE_INDEX)
diff --git a/sys/arm/xilinx/zy7_slcr.c b/sys/arm/xilinx/zy7_slcr.c
index e243ff6..c99d5b0 100644
--- a/sys/arm/xilinx/zy7_slcr.c
+++ b/sys/arm/xilinx/zy7_slcr.c
@@ -177,7 +177,7 @@ zy7_slcr_preload_pl(void)
/* After PL configuration, enable level shifters and deassert top-level
* PL resets. Called from zy7_devcfg.c. Optionally, the level shifters
* can be left disabled but that's rare of an FPGA application. That option
- * is controled by a sysctl in the devcfg driver.
+ * is controlled by a sysctl in the devcfg driver.
*/
void
zy7_slcr_postload_pl(int en_level_shifters)
diff --git a/sys/arm/xscale/i8134x/crb_machdep.c b/sys/arm/xscale/i8134x/crb_machdep.c
index 5268ca9..898bbaa 100644
--- a/sys/arm/xscale/i8134x/crb_machdep.c
+++ b/sys/arm/xscale/i8134x/crb_machdep.c
@@ -38,7 +38,7 @@
*
* machdep.c
*
- * Machine dependant functions for kernel setup
+ * Machine dependent functions for kernel setup
*
* This file needs a lot of work.
*
diff --git a/sys/arm/xscale/i8134x/i81342reg.h b/sys/arm/xscale/i8134x/i81342reg.h
index fd087ce..2402194 100644
--- a/sys/arm/xscale/i8134x/i81342reg.h
+++ b/sys/arm/xscale/i8134x/i81342reg.h
@@ -184,7 +184,7 @@
#define ATU_IATVR2 0x005c /* Inbound ATU Translate Value Register 2 */
#define ATU_IAUTVR2 0x0060 /* Inbound ATU Upper Translate Value Register 2*/
#define ATU_ERLR 0x0064 /* Expansion ROM Limit Register */
-#define ATU_ERTVR 0x0068 /* Expansion ROM Translater Value Register */
+#define ATU_ERTVR 0x0068 /* Expansion ROM Translator Value Register */
#define ATU_ERUTVR 0x006c /* Expansion ROM Upper Translate Value Register*/
#define ATU_CR 0x0070 /* ATU Configuration Register */
#define ATU_CR_OUT_EN (1 << 1)
diff --git a/sys/arm/xscale/ixp425/avila_machdep.c b/sys/arm/xscale/ixp425/avila_machdep.c
index 46e4b10..f26d3ca 100644
--- a/sys/arm/xscale/ixp425/avila_machdep.c
+++ b/sys/arm/xscale/ixp425/avila_machdep.c
@@ -38,7 +38,7 @@
*
* machdep.c
*
- * Machine dependant functions for kernel setup
+ * Machine dependent functions for kernel setup
*
* This file needs a lot of work.
*
diff --git a/sys/arm/xscale/ixp425/cambria_gpio.c b/sys/arm/xscale/ixp425/cambria_gpio.c
index aa3947b..c871418 100644
--- a/sys/arm/xscale/ixp425/cambria_gpio.c
+++ b/sys/arm/xscale/ixp425/cambria_gpio.c
@@ -32,7 +32,7 @@
* The Cambria PLD does not set the i2c ack bit after each write, if we used the
* regular iicbus interface it would abort the xfer after the address byte
* times out and not write our latch. To get around this we grab the iicbus and
- * then do our own bit banging. This is a comprimise to changing all the iicbb
+ * then do our own bit banging. This is a compromise to changing all the iicbb
* device methods to allow a flag to be passed down and is similir to how Linux
* does it.
*
diff --git a/sys/arm/xscale/ixp425/ixp425_npe.c b/sys/arm/xscale/ixp425/ixp425_npe.c
index 6dbce4c..95facb4 100644
--- a/sys/arm/xscale/ixp425/ixp425_npe.c
+++ b/sys/arm/xscale/ixp425/ixp425_npe.c
@@ -507,7 +507,7 @@ ixpnpe_load_firmware(struct ixpnpe_softc *sc, const char *imageName,
/*
* If download was successful, store image Id in list of
- * currently loaded images. If a critical error occured
+ * currently loaded images. If a critical error occurred
* during download, record that the NPE has an invalid image
*/
mtx_lock(&sc->sc_mtx);
@@ -864,7 +864,7 @@ npe_cpu_reset(struct ixpnpe_softc *sc)
while (npe_checkbits(sc,
IX_NPEDL_REG_OFFSET_STAT, IX_NPEDL_MASK_STAT_IFNE)) {
/*
- * Step execution of the NPE intruction to read inFIFO using
+ * Step execution of the NPE instruction to read inFIFO using
* the Debug Executing Context stack.
*/
error = npe_cpu_step(sc, IX_NPEDL_INSTR_RD_FIFO, 0, 0);
@@ -1307,7 +1307,7 @@ npe_logical_reg_write(struct ixpnpe_softc *sc, uint32_t regAddr, uint32_t regVal
((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) <<
IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA);
- /* step execution of NPE intruction using Debug ECS */
+ /* step execution of NPE instruction using Debug ECS */
error = npe_cpu_step(sc, npeInstruction,
ctxtNum, IX_NPEDL_WR_INSTR_LDUR);
}
diff --git a/sys/arm/xscale/ixp425/ixp425_npereg.h b/sys/arm/xscale/ixp425/ixp425_npereg.h
index 069e9d7..94aff85 100644
--- a/sys/arm/xscale/ixp425/ixp425_npereg.h
+++ b/sys/arm/xscale/ixp425/ixp425_npereg.h
@@ -125,7 +125,7 @@
/*
* Reset value for Mailbox (MBST) register
- * NOTE that if used, it should be complemented with an NPE intruction
+ * NOTE that if used, it should be complemented with an NPE instruction
* to clear the Mailbox at the NPE side as well
*/
#define IX_NPEDL_REG_RESET_MBST 0x0000F0F0
diff --git a/sys/arm/xscale/ixp425/ixp425_qmgr.c b/sys/arm/xscale/ixp425/ixp425_qmgr.c
index 822623c..d6db260 100644
--- a/sys/arm/xscale/ixp425/ixp425_qmgr.c
+++ b/sys/arm/xscale/ixp425/ixp425_qmgr.c
@@ -421,7 +421,7 @@ ixpqmgr_qwrite(int qId, uint32_t entry)
return ENOSPC;
}
/*
- * No overflow occured : someone is draining the queue
+ * No overflow occurred : someone is draining the queue
* and the current counter needs to be
* updated from the current number of entries in the queue
*/
diff --git a/sys/arm/xscale/pxa/pxa_machdep.c b/sys/arm/xscale/pxa/pxa_machdep.c
index 32cbcd8..bc3ab6f 100644
--- a/sys/arm/xscale/pxa/pxa_machdep.c
+++ b/sys/arm/xscale/pxa/pxa_machdep.c
@@ -38,7 +38,7 @@
*
* machdep.c
*
- * Machine dependant functions for kernel setup
+ * Machine dependent functions for kernel setup
*
* This file needs a lot of work.
*
diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c
index d8434cf..15a51a3 100644
--- a/sys/arm64/arm64/gic_v3.c
+++ b/sys/arm64/arm64/gic_v3.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bitstring.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
diff --git a/sys/arm64/arm64/gic_v3_fdt.c b/sys/arm64/arm64/gic_v3_fdt.c
index e5d75c3..3f21fee 100644
--- a/sys/arm64/arm64/gic_v3_fdt.c
+++ b/sys/arm64/arm64/gic_v3_fdt.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bitstring.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
diff --git a/sys/arm64/arm64/gic_v3_its.c b/sys/arm64/arm64/gic_v3_its.c
index c830c99..5dd56cf 100644
--- a/sys/arm64/arm64/gic_v3_its.c
+++ b/sys/arm64/arm64/gic_v3_its.c
@@ -852,7 +852,7 @@ lpi_alloc_chunk(struct gic_v3_its_softc *sc, struct lpi_chunk *lpic,
{
u_int *col_ids;
int fclr; /* First cleared bit */
- uint8_t *bitmap;
+ bitstr_t *bitmap;
size_t nb, i;
col_ids = malloc(sizeof(*col_ids) * nvecs, M_GIC_V3_ITS,
@@ -861,7 +861,7 @@ lpi_alloc_chunk(struct gic_v3_its_softc *sc, struct lpi_chunk *lpic,
return (ENOMEM);
mtx_lock_spin(&sc->its_dev_lock);
- bitmap = (uint8_t *)sc->its_lpi_bitmap;
+ bitmap = sc->its_lpi_bitmap;
fclr = 0;
retry:
@@ -901,9 +901,6 @@ static void
lpi_free_chunk(struct gic_v3_its_softc *sc, struct lpi_chunk *lpic)
{
int start, end;
- uint8_t *bitmap;
-
- bitmap = (uint8_t *)sc->its_lpi_bitmap;
KASSERT((lpic->lpi_free == lpic->lpi_num),
("Trying to free LPI chunk that is still in use.\n"));
@@ -915,7 +912,7 @@ lpi_free_chunk(struct gic_v3_its_softc *sc, struct lpi_chunk *lpic)
end = start + lpic->lpi_num - 1;
/* Finally free this chunk */
- bit_nclear(bitmap, start, end);
+ bit_nclear(sc->its_lpi_bitmap, start, end);
mtx_unlock_spin(&sc->its_dev_lock);
free(lpic->lpi_col_ids, M_GIC_V3_ITS);
diff --git a/sys/arm64/arm64/gic_v3_var.h b/sys/arm64/arm64/gic_v3_var.h
index b3c0e52..2e780c3 100644
--- a/sys/arm64/arm64/gic_v3_var.h
+++ b/sys/arm64/arm64/gic_v3_var.h
@@ -236,7 +236,7 @@ struct gic_v3_its_softc {
struct its_dev_list its_dev_list;
- unsigned long * its_lpi_bitmap;
+ bitstr_t * its_lpi_bitmap;
uint32_t its_lpi_maxid;
struct mtx its_dev_lock;
diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC
index 2b52196..9300e77 100644
--- a/sys/arm64/conf/GENERIC
+++ b/sys/arm64/conf/GENERIC
@@ -96,6 +96,7 @@ device vtnet
# Bus drivers
device pci
+options PCI_HP # PCI-Express native HotPlug
options PCI_IOV # PCI SR-IOV support
# Ethernet NICs
diff --git a/sys/boot/efi/libefi/efipart.c b/sys/boot/efi/libefi/efipart.c
index da420bf..410057c 100644
--- a/sys/boot/efi/libefi/efipart.c
+++ b/sys/boot/efi/libefi/efipart.c
@@ -65,14 +65,12 @@ struct devsw efipart_dev = {
/*
* info structure to support bcache
*/
-#define MAXPDDEV 31 /* see MAXDEV in libi386.h */
-
-static struct pdinfo
-{
+struct pdinfo {
int pd_unit; /* unit number */
int pd_open; /* reference counter */
void *pd_bcache; /* buffer cache data */
-} pdinfo [MAXPDDEV];
+};
+static struct pdinfo *pdinfo;
static int npdinfo = 0;
#define PD(dev) (pdinfo[(dev)->d_unit])
@@ -109,6 +107,9 @@ efipart_init(void)
nout = 0;
bzero(aliases, nin * sizeof(EFI_HANDLE));
+ pdinfo = malloc(nin * sizeof(*pdinfo));
+ if (pdinfo == NULL)
+ return (ENOMEM);
for (n = 0; n < nin; n++) {
status = BS->HandleProtocol(hin[n], &devpath_guid,
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index b1686bc..8f780fd 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -1876,6 +1876,7 @@ cam_periph_devctl_notify(union ccb *ccb)
if (cgd->ccb_h.status == CAM_REQ_CMP)
sbuf_bcat(&sb, cgd->serial_num, cgd->serial_num_len);
+ xpt_free_ccb((union ccb *)cgd);
}
sbuf_printf(&sb, "\" ");
sbuf_printf(&sb, "cam_status=\"0x%x\" ", ccb->ccb_h.status);
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c
index 35aecb9..3b23ae0 100644
--- a/sys/cam/scsi/scsi_all.c
+++ b/sys/cam/scsi/scsi_all.c
@@ -957,7 +957,7 @@ static struct scsi_sense_quirk_entry sense_quirk_table[] = {
}
};
-const int sense_quirk_table_size = nitems(sense_quirk_table);
+const u_int sense_quirk_table_size = nitems(sense_quirk_table);
static struct asc_table_entry asc_table[] = {
/*
@@ -3193,7 +3193,7 @@ static struct asc_table_entry asc_table[] = {
"Security conflict in translated device") }
};
-const int asc_table_size = nitems(asc_table);
+const u_int asc_table_size = nitems(asc_table);
struct asc_key
{
@@ -4700,7 +4700,7 @@ scsi_sense_desc_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
struct scsi_inquiry_data *inq_data,
struct scsi_sense_desc_header *header)
{
- int i;
+ u_int i;
for (i = 0; i < nitems(scsi_sense_printers); i++) {
struct scsi_sense_desc_printer *printer;
@@ -5475,8 +5475,8 @@ static struct {
u_int
scsi_calc_syncsrate(u_int period_factor)
{
- int i;
- int num_syncrates;
+ u_int i;
+ u_int num_syncrates;
/*
* It's a bug if period is zero, but if it is anyway, don't
@@ -5511,8 +5511,8 @@ scsi_calc_syncsrate(u_int period_factor)
u_int
scsi_calc_syncparam(u_int period)
{
- int i;
- int num_syncrates;
+ u_int i;
+ u_int num_syncrates;
if (period == 0)
return (~0); /* Async */
@@ -6545,7 +6545,8 @@ scsi_parse_transportid(char *transportid_str,
{
char *tmpstr;
scsi_nv_status status;
- int retval, num_proto_entries, table_entry;
+ u_int num_proto_entries;
+ int retval, table_entry;
retval = 0;
table_entry = 0;
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index f505d2d..42dd491 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -1264,7 +1264,7 @@ cdgetpage(struct cd_mode_params *mode_params)
static int
cdgetpagesize(int page_num)
{
- int i;
+ u_int i;
for (i = 0; i < nitems(cd_page_size_table); i++) {
if (cd_page_size_table[i].page == page_num)
diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c
index 94441a9..30a9104 100644
--- a/sys/cam/scsi/scsi_xpt.c
+++ b/sys/cam/scsi/scsi_xpt.c
@@ -556,8 +556,6 @@ static struct scsi_quirk_entry scsi_quirk_table[] =
},
};
-static const int scsi_quirk_table_size = nitems(scsi_quirk_table);
-
static cam_status proberegister(struct cam_periph *periph,
void *arg);
static void probeschedule(struct cam_periph *probe_periph);
@@ -2365,7 +2363,7 @@ scsi_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
* Take the default quirk entry until we have inquiry
* data and can determine a better quirk to use.
*/
- quirk = &scsi_quirk_table[scsi_quirk_table_size - 1];
+ quirk = &scsi_quirk_table[nitems(scsi_quirk_table) - 1];
device->quirk = (void *)quirk;
device->mintags = quirk->mintags;
device->maxtags = quirk->maxtags;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
index 139a93d..730b423 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
@@ -2483,6 +2483,18 @@ extern void dtrace_helpers_destroy(proc_t *);
#define DTRACE_INVOP_RET 2
#define DTRACE_INVOP_B 3
+#elif defined(__mips__)
+
+#define INSN_SIZE 4
+
+/* Load/Store double RA to/from SP */
+#define LDSD_RA_SP_MASK 0xffff0000
+#define LDSD_DATA_MASK 0x0000ffff
+#define SD_RA_SP 0xffbf0000
+#define LD_RA_SP 0xdfbf0000
+
+#define DTRACE_INVOP_SD 1
+#define DTRACE_INVOP_LD 2
#endif
#ifdef __cplusplus
diff --git a/sys/cddl/dev/dtrace/mips/dtrace_asm.S b/sys/cddl/dev/dtrace/mips/dtrace_asm.S
index 199d16be..a3b24aa 100644
--- a/sys/cddl/dev/dtrace/mips/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/mips/dtrace_asm.S
@@ -28,7 +28,6 @@
#define _ASM
#define _LOCORE
-#define LOCORE
#include <sys/cpuvar_defs.h>
#include <sys/dtrace.h>
@@ -227,28 +226,6 @@ LEAF(dtrace_copystr)
END(dtrace_copystr)
/*
-void dtrace_invop_init(void)
-*/
-LEAF(dtrace_invop_init)
- /* XXX: impement it properly */
- PTR_LA t0, dtrace_invop_jump_addr
- /* dla t1, dtrace_invop_start */
- PTR_S zero, 0(t0)
- j ra
- nop
-END(dtrace_invop_init)
-
-/*
-void dtrace_invop_uninit(void)
-*/
-LEAF(dtrace_invop_uninit)
- PTR_LA t0, dtrace_invop_jump_addr
- PTR_S zero, 0(t0)
- j ra
- nop
-END(dtrace_invop_uninit)
-
-/*
uintptr_t
dtrace_caller(int aframes)
*/
diff --git a/sys/cddl/dev/dtrace/mips/dtrace_subr.c b/sys/cddl/dev/dtrace/mips/dtrace_subr.c
index 9702274..1ed3cd0 100644
--- a/sys/cddl/dev/dtrace/mips/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/mips/dtrace_subr.c
@@ -45,13 +45,14 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#define DELAYBRANCH(x) ((int)(x) < 0)
-
+
+extern int (*dtrace_invop_jump_addr)(struct trapframe *);
extern dtrace_id_t dtrace_probeid_error;
int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t);
typedef struct dtrace_invop_hdlr {
- int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t);
+ int (*dtih_func)(uintptr_t, struct trapframe *, uintptr_t);
struct dtrace_invop_hdlr *dtih_next;
} dtrace_invop_hdlr_t;
@@ -70,6 +71,46 @@ dtrace_invop(uintptr_t addr, struct trapframe *stack, uintptr_t eax)
return (0);
}
+void
+dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t))
+{
+ dtrace_invop_hdlr_t *hdlr;
+
+ hdlr = kmem_alloc(sizeof (dtrace_invop_hdlr_t), KM_SLEEP);
+ hdlr->dtih_func = func;
+ hdlr->dtih_next = dtrace_invop_hdlr;
+ dtrace_invop_hdlr = hdlr;
+}
+
+void
+dtrace_invop_remove(int (*func)(uintptr_t, struct trapframe *, uintptr_t))
+{
+ dtrace_invop_hdlr_t *hdlr, *prev;
+
+ hdlr = dtrace_invop_hdlr;
+ prev = NULL;
+
+ for (;;) {
+ if (hdlr == NULL)
+ panic("attempt to remove non-existent invop handler");
+
+ if (hdlr->dtih_func == func)
+ break;
+
+ prev = hdlr;
+ hdlr = hdlr->dtih_next;
+ }
+
+ if (prev == NULL) {
+ ASSERT(dtrace_invop_hdlr == hdlr);
+ dtrace_invop_hdlr = hdlr->dtih_next;
+ } else {
+ ASSERT(dtrace_invop_hdlr != hdlr);
+ prev->dtih_next = hdlr->dtih_next;
+ }
+
+ kmem_free(hdlr, 0);
+}
/*ARGSUSED*/
void
@@ -199,3 +240,45 @@ dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which,
(uintptr_t)epid,
(uintptr_t)which, (uintptr_t)fault, (uintptr_t)fltoffs);
}
+
+static int
+dtrace_invop_start(struct trapframe *frame)
+{
+ register_t *sp;
+ int16_t offs;
+ int invop;
+
+ invop = dtrace_invop(frame->pc, frame, frame->pc);
+ offs = (invop & LDSD_DATA_MASK);
+ sp = (register_t *)((uint8_t *)frame->sp + offs);
+
+ switch (invop & LDSD_RA_SP_MASK) {
+ case LD_RA_SP:
+ frame->ra = *sp;
+ frame->pc += INSN_SIZE;
+ break;
+ case SD_RA_SP:
+ *(sp) = frame->ra;
+ frame->pc += INSN_SIZE;
+ break;
+ default:
+ printf("%s: 0x%x undefined\n", __func__, invop);
+ return (-1);
+ };
+
+ return (0);
+}
+
+void
+dtrace_invop_init(void)
+{
+
+ dtrace_invop_jump_addr = dtrace_invop_start;
+}
+
+void
+dtrace_invop_uninit(void)
+{
+
+ dtrace_invop_jump_addr = 0;
+}
diff --git a/sys/cddl/dev/fbt/mips/fbt_isa.c b/sys/cddl/dev/fbt/mips/fbt_isa.c
new file mode 100644
index 0000000..a4e9e8b
--- /dev/null
+++ b/sys/cddl/dev/fbt/mips/fbt_isa.c
@@ -0,0 +1,165 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Portions Copyright 2006-2008 John Birrell jb@freebsd.org
+ * Portions Copyright 2013 Justin Hibbits jhibbits@freebsd.org
+ * Portions Copyright 2013 Howard Su howardsu@freebsd.org
+ * Portions Copyright 2015-2016 Ruslan Bukin <br@bsdpad.com>
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/dtrace.h>
+
+#include <machine/cpuregs.h>
+#include <machine/cache.h>
+
+#include "fbt.h"
+
+#define FBT_PATCHVAL (MIPS_BREAK_INSTR)
+#define FBT_ENTRY "entry"
+#define FBT_RETURN "return"
+
+int
+fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval)
+{
+ solaris_cpu_t *cpu;
+ fbt_probe_t *fbt;
+
+ cpu = &solaris_cpu[curcpu];
+ fbt = fbt_probetab[FBT_ADDR2NDX(addr)];
+
+ for (; fbt != NULL; fbt = fbt->fbtp_hashnext) {
+ if ((uintptr_t)fbt->fbtp_patchpoint == addr) {
+ cpu->cpu_dtrace_caller = addr;
+
+ dtrace_probe(fbt->fbtp_id, frame->a0,
+ frame->a1, frame->a2,
+ frame->a3, frame->a4);
+
+ cpu->cpu_dtrace_caller = 0;
+ return (fbt->fbtp_savedval);
+ }
+ }
+
+ return (0);
+}
+
+void
+fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val)
+{
+
+ *fbt->fbtp_patchpoint = val;
+ mips_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 4);
+}
+
+int
+fbt_provide_module_function(linker_file_t lf, int symindx,
+ linker_symval_t *symval, void *opaque)
+{
+ fbt_probe_t *fbt, *retfbt;
+ uint32_t *target, *start;
+ uint32_t *instr, *limit;
+ const char *name;
+ char *modname;
+
+ modname = opaque;
+ name = symval->name;
+
+ /* Check if function is excluded from instrumentation */
+ if (fbt_excluded(name))
+ return (0);
+
+ instr = (uint32_t *)(symval->value);
+ limit = (uint32_t *)(symval->value + symval->size);
+
+ /* Look for store double to ra register */
+ for (; instr < limit; instr++) {
+ if ((*instr & LDSD_RA_SP_MASK) == SD_RA_SP)
+ break;
+ }
+
+ if (instr >= limit)
+ return (0);
+
+ fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
+ fbt->fbtp_name = name;
+ fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
+ name, FBT_ENTRY, 3, fbt);
+ fbt->fbtp_patchpoint = instr;
+ fbt->fbtp_ctl = lf;
+ fbt->fbtp_loadcnt = lf->loadcnt;
+ fbt->fbtp_savedval = *instr;
+ fbt->fbtp_patchval = FBT_PATCHVAL;
+ fbt->fbtp_rval = DTRACE_INVOP_SD;
+ fbt->fbtp_symindx = symindx;
+
+ fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
+ fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
+
+ lf->fbt_nentries++;
+
+ retfbt = NULL;
+again:
+ for (; instr < limit; instr++) {
+ if ((*instr & LDSD_RA_SP_MASK) == LD_RA_SP) {
+ break;
+ }
+ }
+
+ if (instr >= limit)
+ return (0);
+
+ /*
+ * We have a winner!
+ */
+ fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
+ fbt->fbtp_name = name;
+ if (retfbt == NULL) {
+ fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
+ name, FBT_RETURN, 3, fbt);
+ } else {
+ retfbt->fbtp_next = fbt;
+ fbt->fbtp_id = retfbt->fbtp_id;
+ }
+ retfbt = fbt;
+
+ fbt->fbtp_patchpoint = instr;
+ fbt->fbtp_ctl = lf;
+ fbt->fbtp_loadcnt = lf->loadcnt;
+ fbt->fbtp_symindx = symindx;
+ fbt->fbtp_rval = DTRACE_INVOP_LD;
+ fbt->fbtp_savedval = *instr;
+ fbt->fbtp_patchval = FBT_PATCHVAL;
+ fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
+ fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
+
+ lf->fbt_nentries++;
+
+ instr++;
+ goto again;
+}
diff --git a/sys/cddl/dev/fbt/mips/fbt_isa.h b/sys/cddl/dev/fbt/mips/fbt_isa.h
new file mode 100644
index 0000000..5552f31
--- /dev/null
+++ b/sys/cddl/dev/fbt/mips/fbt_isa.h
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * $FreeBSD$
+ *
+ */
+
+#ifndef _FBT_ISA_H_
+#define _FBT_ISA_H_
+
+typedef uint32_t fbt_patchval_t;
+
+#endif
diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c
index d85d4ad..9273a24 100644
--- a/sys/compat/linuxkpi/common/src/linux_compat.c
+++ b/sys/compat/linuxkpi/common/src/linux_compat.c
@@ -671,7 +671,7 @@ linux_file_poll(struct file *file, int events, struct ucred *active_cred,
else
revents = 0;
- return (0);
+ return (revents);
}
static int
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index f1553bf..51e81f1 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1411,6 +1411,7 @@ options MSGBUF_SIZE=40960
# PCI bus & PCI options:
#
device pci
+options PCI_HP # PCI-Express native HotPlug
options PCI_IOV # PCI SR-IOV support
diff --git a/sys/conf/files b/sys/conf/files
index 33de771..98ca4da 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -9,6 +9,16 @@ acpi_quirks.h optional acpi \
compile-with "${AWK} -f $S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \
no-obj no-implicit-rule before-depend \
clean "acpi_quirks.h"
+bhnd_nvram_map.h optional bhndbus | bhnd \
+ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \
+ compile-with "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -h" \
+ no-obj no-implicit-rule before-depend \
+ clean "bhnd_nvram_map.h"
+bhnd_nvram_map_data.h optional bhndbus | bhnd \
+ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \
+ compile-with "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -d" \
+ no-obj no-implicit-rule before-depend \
+ clean "bhnd_nvram_map_data.h"
#
# The 'fdt_dtb_file' target covers an actual DTB file name, which is derived
# from the specified source (DTS) file: <platform>.dts -> <platform>.dtb
@@ -1109,9 +1119,37 @@ dev/ath/ath_rate/sample/sample.c optional ath_rate_sample \
dev/ath/ath_dfs/null/dfs_null.c optional ath \
compile-with "${NORMAL_C} -I$S/dev/ath"
#
-dev/bce/if_bce.c optional bce
-dev/bfe/if_bfe.c optional bfe
-dev/bge/if_bge.c optional bge
+dev/bce/if_bce.c optional bce
+dev/bfe/if_bfe.c optional bfe
+dev/bge/if_bge.c optional bge
+dev/bhnd/bhnd.c optional bhndbus | bhnd
+dev/bhnd/bhnd_subr.c optional bhndbus | bhnd
+dev/bhnd/bhnd_bus_if.m optional bhndbus | bhnd
+dev/bhnd/bhndb/bhndb.c optional bhndbus | bhndb
+dev/bhnd/bhndb/bhndb_bus_if.m optional bhndbus | bhndb
+dev/bhnd/bhndb/bhndb_hwdata.c optional bhndbus | bhndb
+dev/bhnd/bhndb/bhndb_if.m optional bhndbus | bhndb
+dev/bhnd/bhndb/bhndb_pci.c optional bhndbus pci | bhndb pci
+dev/bhnd/bhndb/bhndb_pci_hwdata.c optional bhndbus pci | bhndb pci
+dev/bhnd/bhndb/bhndb_pci_sprom.c optional bhndbus pci | bhndb pci
+dev/bhnd/bhndb/bhndb_subr.c optional bhndbus pci | bhndb
+dev/bhnd/bcma/bcma.c optional bhndbus | bcma
+dev/bhnd/bcma/bcma_bhndb.c optional bhndbus | bcma bhndb
+dev/bhnd/bcma/bcma_erom.c optional bhndbus | bcma
+dev/bhnd/bcma/bcma_subr.c optional bhndbus | bcma
+dev/bhnd/cores/chipc/chipc.c optional bhndbus | bhnd
+dev/bhnd/cores/chipc/bhnd_chipc_if.m optional bhndbus | bhnd
+dev/bhnd/cores/pci/bhnd_pci.c optional bhndbus pci | bhnd pci
+dev/bhnd/cores/pci/bhnd_pci_hostb.c optional bhndbus pci | bhndb pci
+dev/bhnd/cores/pci/bhnd_pcib.c optional bhnd_pcib bhnd pci
+dev/bhnd/nvram/bhnd_nvram_if.m optional bhndbus | bhnd
+dev/bhnd/nvram/bhnd_sprom.c optional bhndbus | bhnd
+dev/bhnd/nvram/nvram_subr.c optional bhndbus | bhnd
+dev/bhnd/siba/siba.c optional bhndbus | siba
+dev/bhnd/siba/siba_bhndb.c optional bhndbus | siba bhndb
+dev/bhnd/siba/siba_nexus.c optional siba_nexus siba
+dev/bhnd/siba/siba_subr.c optional bhndbus | siba
+#
dev/bktr/bktr_audio.c optional bktr pci
dev/bktr/bktr_card.c optional bktr pci
dev/bktr/bktr_core.c optional bktr pci
@@ -1132,10 +1170,12 @@ dev/bwi/if_bwi_pci.c optional bwi pci
# XXX Work around clang warning, until maintainer approves fix.
dev/bwn/if_bwn.c optional bwn siba_bwn \
compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}"
+dev/bwn/if_bwn_pci.c optional bwn pci bhnd | bwn pci bhndbus
dev/bwn/if_bwn_phy_g.c optional bwn siba_bwn \
compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}"
dev/bwn/if_bwn_phy_lp.c optional bwn siba_bwn \
compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}"
+dev/bwn/bwn_mac.c optional bwn bhnd | bwn bhndbus
dev/cardbus/cardbus.c optional cardbus
dev/cardbus/cardbus_cis.c optional cardbus
dev/cardbus/cardbus_device.c optional cardbus
@@ -2400,11 +2440,11 @@ dev/si/si3_t225.c optional si
dev/si/si_eisa.c optional si eisa
dev/si/si_isa.c optional si isa
dev/si/si_pci.c optional si pci
-dev/siba/siba.c optional siba
+dev/siba/siba.c optional siba !bhnd !bhndbus
dev/siba/siba_bwn.c optional siba_bwn pci
-dev/siba/siba_cc.c optional siba
+dev/siba/siba_cc.c optional siba !bhnd !bhndbus
dev/siba/siba_core.c optional siba | siba_bwn pci
-dev/siba/siba_pcib.c optional siba pci
+dev/siba/siba_pcib.c optional siba pci !bhnd !bhndbus
dev/siis/siis.c optional siis pci
dev/sis/if_sis.c optional sis pci
dev/sk/if_sk.c optional sk pci
diff --git a/sys/conf/files.mips b/sys/conf/files.mips
index 4cacac4..0fe0795 100644
--- a/sys/conf/files.mips
+++ b/sys/conf/files.mips
@@ -95,3 +95,9 @@ dev/hwpmc/hwpmc_mips74k.c optional hwpmc_mips74k
# ofw support
dev/ofw/ofwpci.c optional fdt pci
+
+# DTrace
+cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs | dtrace compile-with "${CDDL_C}"
+cddl/dev/dtrace/mips/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}"
+cddl/dev/dtrace/mips/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}"
+cddl/dev/fbt/mips/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk
index 9e6b06c..2264ece 100644
--- a/sys/conf/kmod.mk
+++ b/sys/conf/kmod.mk
@@ -411,6 +411,26 @@ ${_i}devs.h: ${SYSDIR}/tools/${_i}devs2h.awk ${SYSDIR}/dev/${_i}/${_i}devs
.endif
.endfor # _i
+.if !empty(SRCS:Mbhnd_nvram_map.h)
+CLEANFILES+= bhnd_nvram_map.h
+bhnd_nvram_map.h: ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.awk \
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map
+bhnd_nvram_map.h:
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map -h
+.endif
+
+.if !empty(SRCS:Mbhnd_nvram_map_data.h)
+CLEANFILES+= bhnd_nvram_map_data.h
+bhnd_nvram_map_data.h: ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.awk \
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map
+bhnd_nvram_map_data.h:
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map -d
+.endif
+
.if !empty(SRCS:Musbdevs.h)
CLEANFILES+= usbdevs.h
usbdevs.h: ${SYSDIR}/tools/usbdevs2h.awk ${SYSDIR}/dev/usb/usbdevs
diff --git a/sys/conf/options b/sys/conf/options
index 11e778f..6dd51d7 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -177,6 +177,7 @@ NO_SYSCTL_DESCR opt_global.h
NSWBUF_MIN opt_swap.h
MBUF_PACKET_ZONE_DISABLE opt_global.h
PANIC_REBOOT_WAIT_TIME opt_panic.h
+PCI_HP opt_pci.h
PCI_IOV opt_global.h
PPC_DEBUG opt_ppc.h
PPC_PROBE_CHIPSET opt_ppc.h
@@ -822,7 +823,7 @@ ATH_KTR_INTR_DEBUG opt_ath.h
# options for the Atheros hal
AH_SUPPORT_AR5416 opt_ah.h
# XXX For now, this breaks non-AR9130 chipsets, so only use it
-# XXX when actually targetting AR9130.
+# XXX when actually targeting AR9130.
AH_SUPPORT_AR9130 opt_ah.h
# This is required for AR933x SoC support
@@ -852,6 +853,9 @@ AH_AR5416_INTERRUPT_MITIGATION opt_ah.h
BWI_DEBUG opt_bwi.h
BWI_DEBUG_VERBOSE opt_bwi.h
+# options for the Brodacom BCM43xx driver (bwn)
+BWN_DEBUG opt_bwn.h
+
# options for the Marvell 8335 wireless driver
MALO_DEBUG opt_malo.h
MALO_TXBUF opt_malo.h
diff --git a/sys/conf/options.arm b/sys/conf/options.arm
index 8a14da1..0d42ddb 100644
--- a/sys/conf/options.arm
+++ b/sys/conf/options.arm
@@ -44,6 +44,7 @@ SOC_ALLWINNER_A10 opt_global.h
SOC_ALLWINNER_A20 opt_global.h
SOC_ALLWINNER_A31 opt_global.h
SOC_ALLWINNER_A31S opt_global.h
+SOC_ALLWINNER_A83T opt_global.h
SOC_BCM2835 opt_global.h
SOC_BCM2836 opt_global.h
SOC_IMX51 opt_global.h
diff --git a/sys/ddb/db_examine.c b/sys/ddb/db_examine.c
index 3eff396..a41fcb5 100644
--- a/sys/ddb/db_examine.c
+++ b/sys/ddb/db_examine.c
@@ -89,6 +89,15 @@ db_examine(db_addr_t addr, char *fmt, int count)
case 'g':
size = 8;
break;
+ case 'a': /* address */
+ size = sizeof(void *);
+ /* always forces a new line */
+ if (db_print_position() != 0)
+ db_printf("\n");
+ db_prev = addr;
+ db_printsym(addr, DB_STGY_ANY);
+ db_printf(":\t");
+ break;
default:
if (db_print_position() == 0) {
/* Print the address. */
@@ -99,18 +108,6 @@ db_examine(db_addr_t addr, char *fmt, int count)
width = size * 4;
switch (c) {
- case 'a': /* address */
- size = sizeof(void *);
- value = db_get_value(addr, size, TRUE);
- addr += size;
- db_printsym(value, DB_STGY_ANY);
- break;
- case 'p':
- size = sizeof(void *);
- value = db_get_value(addr, size, TRUE);
- addr += size;
- db_printf("%p", (void *)value);
- break;
case 'r': /* signed, current radix */
value = db_get_value(addr, size, true);
addr += size;
@@ -176,7 +173,7 @@ db_examine(db_addr_t addr, char *fmt, int count)
default:
break;
}
- if (db_print_position() != 0 || c == 'a' || c == 'p')
+ if (db_print_position() != 0)
db_end_line(1);
break;
}
diff --git a/sys/dev/acpi_support/atk0110.c b/sys/dev/acpi_support/atk0110.c
index 7d30d5f..3a49988 100644
--- a/sys/dev/acpi_support/atk0110.c
+++ b/sys/dev/acpi_support/atk0110.c
@@ -66,7 +66,7 @@ struct aibs_sensor {
};
struct aibs_softc {
- struct device *sc_dev;
+ device_t sc_dev;
ACPI_HANDLE sc_ah;
struct aibs_sensor *sc_asens_volt;
diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c
index e9bcbd1..506e267 100644
--- a/sys/dev/acpica/acpi_pcib_acpi.c
+++ b/sys/dev/acpica/acpi_pcib_acpi.c
@@ -29,6 +29,8 @@
__FBSDID("$FreeBSD$");
#include "opt_acpi.h"
+#include "opt_pci.h"
+
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
@@ -312,6 +314,11 @@ acpi_pcib_osc(struct acpi_hpcib_softc *sc)
/* Control Field */
cap_set[2] = 0;
+#ifdef PCI_HP
+ /* Control Field: PCI Express Native Hot Plug */
+ cap_set[2] |= 0x1;
+#endif
+
status = acpi_EvaluateOSC(sc->ap_handle, pci_host_bridge_uuid, 1,
nitems(cap_set), cap_set, cap_set, false);
if (ACPI_FAILURE(status)) {
diff --git a/sys/dev/acpica/acpi_thermal.c b/sys/dev/acpica/acpi_thermal.c
index 4acf3c4..dab1ac9 100644
--- a/sys/dev/acpica/acpi_thermal.c
+++ b/sys/dev/acpica/acpi_thermal.c
@@ -785,7 +785,7 @@ acpi_tz_temp_sysctl(SYSCTL_HANDLER_ARGS)
int error;
sc = oidp->oid_arg1;
- temp_ptr = (int *)((uintptr_t)sc + oidp->oid_arg2);
+ temp_ptr = (int *)(void *)(uintptr_t)((uintptr_t)sc + oidp->oid_arg2);
temp = *temp_ptr;
error = sysctl_handle_int(oidp, &temp, 0, req);
@@ -814,7 +814,7 @@ acpi_tz_passive_sysctl(SYSCTL_HANDLER_ARGS)
int error;
sc = oidp->oid_arg1;
- val_ptr = (int *)((uintptr_t)sc + oidp->oid_arg2);
+ val_ptr = (int *)(void *)(uintptr_t)((uintptr_t)sc + oidp->oid_arg2);
val = *val_ptr;
error = sysctl_handle_int(oidp, &val, 0, req);
diff --git a/sys/dev/ahci/ahci_pci.c b/sys/dev/ahci/ahci_pci.c
index 11e89c5..6b6a1a6 100644
--- a/sys/dev/ahci/ahci_pci.c
+++ b/sys/dev/ahci/ahci_pci.c
@@ -176,6 +176,15 @@ static const struct {
{0x9c078086, 0x00, "Intel Lynx Point-LP (RAID)", 0},
{0x9c0e8086, 0x00, "Intel Lynx Point-LP (RAID)", 0},
{0x9c0f8086, 0x00, "Intel Lynx Point-LP (RAID)", 0},
+ {0x9d038086, 0x00, "Intel Sunrise Point-LP", 0},
+ {0x9d058086, 0x00, "Intel Sunrise Point-LP (RAID)", 0},
+ {0x9d078086, 0x00, "Intel Sunrise Point-LP (RAID)", 0},
+ {0xa1028086, 0x00, "Intel Sunrise Point", 0},
+ {0xa1038086, 0x00, "Intel Sunrise Point", 0},
+ {0xa1058086, 0x00, "Intel Sunrise Point (RAID)", 0},
+ {0xa1068086, 0x00, "Intel Sunrise Point (RAID)", 0},
+ {0xa1078086, 0x00, "Intel Sunrise Point (RAID)", 0},
+ {0xa10f8086, 0x00, "Intel Sunrise Point (RAID)", 0},
{0x23238086, 0x00, "Intel DH89xxCC", 0},
{0x2360197b, 0x00, "JMicron JMB360", 0},
{0x2361197b, 0x00, "JMicron JMB361", AHCI_Q_NOFORCE},
diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c
index bbe8bfd..384e733 100644
--- a/sys/dev/asmc/asmc.c
+++ b/sys/dev/asmc/asmc.c
@@ -216,6 +216,12 @@ struct asmc_model asmc_models[] = {
},
{
+ "MacBookPro5,1", "Apple SMC MacBook Pro Core 2 Duo (2008/2009)",
+ ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS,
+ ASMC_MBP5_TEMPS, ASMC_MBP5_TEMPNAMES, ASMC_MBP5_TEMPDESCS
+ },
+
+ {
"MacBookPro8,2", "Apple SMC MacBook Pro (early 2011)",
ASMC_SMS_FUNCS, ASMC_FAN_FUNCS, ASMC_LIGHT_FUNCS,
ASMC_MBP8_TEMPS, ASMC_MBP8_TEMPNAMES, ASMC_MBP8_TEMPDESCS
diff --git a/sys/dev/asmc/asmcvar.h b/sys/dev/asmc/asmcvar.h
index f67ee16..26c6203 100644
--- a/sys/dev/asmc/asmcvar.h
+++ b/sys/dev/asmc/asmcvar.h
@@ -188,6 +188,34 @@ struct asmc_softc {
"Unknown", "Unknown", \
"Wireless Module", }
+#define ASMC_MBP5_TEMPS { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", \
+ "TC0F", "TC0P", "TG0D", "TG0F", "TG0H", \
+ "TG0P", "TG0T", "TG1H", "TN0D", "TN0P", \
+ "TTF0", "Th2H", "Tm0P", "Ts0P", "Ts0S", \
+ NULL }
+
+#define ASMC_MBP5_TEMPNAMES { "enclosure_bottom_0", "enclosure_bottom_1", \
+ "enclosure_bottom_2", "enclosure_bottom_3", \
+ "cpu_diode", "cpu", \
+ "cpu_pin", "gpu_diode", \
+ "gpu", "gpu_heatsink", \
+ "gpu_pin", "gpu_transistor", \
+ "gpu_2_heatsink", "northbridge_diode", \
+ "northbridge_pin", "unknown", \
+ "heatsink_2", "memory_controller", \
+ "pci_express_slot_pin", "pci_express_slot_unk" }
+
+#define ASMC_MBP5_TEMPDESCS { "Enclosure Bottom 0", "Enclosure Bottom 1", \
+ "Enclosure Bottom 2", "Enclosure Bottom 3", \
+ "CPU Diode", "CPU ???", \
+ "CPU Pin", "GPU Diode", \
+ "GPU ???", "GPU Heatsink", \
+ "GPU Pin", "GPU Transistor", \
+ "GPU 2 Heatsink", "Northbridge Diode", \
+ "Northbridge Pin", "Unknown", \
+ "Heatsink 2", "Memory Controller", \
+ "PCI Express Slot Pin", "PCI Express Slot (unk)" }
+
#define ASMC_MBP8_TEMPS { "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", \
"TC0E", "TC0F", "TC0P", "TC1C", "TC2C", \
"TC3C", "TC4C", "TCFC", "TCGC", "TCSA", \
diff --git a/sys/dev/bhnd/bcma/bcma.c b/sys/dev/bhnd/bcma/bcma.c
index f1387e7..b9a7c33 100644
--- a/sys/dev/bhnd/bcma/bcma.c
+++ b/sys/dev/bhnd/bcma/bcma.c
@@ -194,6 +194,14 @@ bcma_get_resource_list(device_t dev, device_t child)
return (&dinfo->resources);
}
+static device_t
+bcma_find_hostb_device(device_t dev)
+{
+ struct bcma_softc *sc = device_get_softc(dev);
+
+ /* This is set (or not) by the concrete bcma driver subclass. */
+ return (sc->hostb_dev);
+}
static int
bcma_reset_core(device_t dev, device_t child, uint16_t flags)
@@ -251,6 +259,11 @@ bcma_get_port_count(device_t dev, device_t child, bhnd_port_type type)
return (dinfo->corecfg->num_bridge_ports);
case BHND_PORT_AGENT:
return (dinfo->corecfg->num_wrapper_ports);
+ default:
+ device_printf(dev, "%s: unknown type (%d)\n",
+ __func__,
+ type);
+ return (0);
}
}
@@ -466,6 +479,7 @@ static device_method_t bcma_methods[] = {
DEVMETHOD(bus_get_resource_list, bcma_get_resource_list),
/* BHND interface */
+ DEVMETHOD(bhnd_bus_find_hostb_device, bcma_find_hostb_device),
DEVMETHOD(bhnd_bus_reset_core, bcma_reset_core),
DEVMETHOD(bhnd_bus_suspend_core, bcma_suspend_core),
DEVMETHOD(bhnd_bus_get_port_count, bcma_get_port_count),
diff --git a/sys/dev/bhnd/bcma/bcma_bhndb.c b/sys/dev/bhnd/bcma/bcma_bhndb.c
index ec8b647..88a5a28 100644
--- a/sys/dev/bhnd/bcma/bcma_bhndb.c
+++ b/sys/dev/bhnd/bcma/bcma_bhndb.c
@@ -65,14 +65,16 @@ bcma_bhndb_probe(device_t dev)
static int
bcma_bhndb_attach(device_t dev)
{
+ struct bcma_softc *sc;
const struct bhnd_chipid *cid;
struct resource *erom_res;
int error;
int rid;
- cid = BHNDB_GET_CHIPID(device_get_parent(dev), dev);
+ sc = device_get_softc(dev);
/* Map the EROM resource and enumerate our children. */
+ cid = BHNDB_GET_CHIPID(device_get_parent(dev), dev);
rid = 0;
erom_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, cid->enum_addr,
cid->enum_addr + BCMA_EROM_TABLE_SIZE, BCMA_EROM_TABLE_SIZE,
@@ -95,6 +97,9 @@ bcma_bhndb_attach(device_t dev)
if (error)
return (error);
+ /* Ask our parent bridge to find the corresponding bridge core */
+ sc->hostb_dev = BHNDB_FIND_HOSTB_DEVICE(device_get_parent(dev), dev);
+
/* Call our superclass' implementation */
return (bcma_attach(dev));
}
diff --git a/sys/dev/bhnd/bcma/bcma_subr.c b/sys/dev/bhnd/bcma/bcma_subr.c
index 53d7564..c493f9c 100644
--- a/sys/dev/bhnd/bcma/bcma_subr.c
+++ b/sys/dev/bhnd/bcma/bcma_subr.c
@@ -134,6 +134,8 @@ bcma_corecfg_get_port_list(struct bcma_corecfg *cfg, bhnd_port_type type)
case BHND_PORT_AGENT:
return (&cfg->wrapper_ports);
break;
+ default:
+ return (NULL);
}
}
diff --git a/sys/dev/bhnd/bcma/bcmavar.h b/sys/dev/bhnd/bcma/bcmavar.h
index 48a5307..359a2d1 100644
--- a/sys/dev/bhnd/bcma/bcmavar.h
+++ b/sys/dev/bhnd/bcma/bcmavar.h
@@ -144,6 +144,7 @@ struct bcma_devinfo {
/** BMCA per-instance state */
struct bcma_softc {
struct bhnd_softc bhnd_sc; /**< bhnd state */
+ device_t hostb_dev; /**< host bridge core, or NULL */
};
#endif /* _BCMA_BCMAVAR_H_ */ \ No newline at end of file
diff --git a/sys/dev/bhnd/bcmsrom_fmt.h b/sys/dev/bhnd/bcmsrom_fmt.h
deleted file mode 100644
index 66c2b9d..0000000
--- a/sys/dev/bhnd/bcmsrom_fmt.h
+++ /dev/null
@@ -1,373 +0,0 @@
-/*-
- * Copyright (c) 2010 Broadcom Corporation
- *
- * This file is derived from the bcmsrom.h header distributed with Broadcom's
- * brcm80211 Linux driver release, as contributed to the Linux staging
- * repository.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _BHND_BCMSROM_FMT_H_
-#define _BHND_BCMSROM_FMT_H_
-
-/* Maximum srom: 6 Kilobits == 768 bytes */
-#define SROM_MAX 768
-#define SROM_MAXW 384
-#define VARS_MAX 4096
-
-/* PCI fields */
-#define PCI_F0DEVID 48
-
-#define SROM_WORDS 64
-
-#define SROM3_SWRGN_OFF 28 /* s/w region offset in words */
-
-#define SROM_SSID 2
-
-#define SROM_WL1LHMAXP 29
-
-#define SROM_WL1LPAB0 30
-#define SROM_WL1LPAB1 31
-#define SROM_WL1LPAB2 32
-
-#define SROM_WL1HPAB0 33
-#define SROM_WL1HPAB1 34
-#define SROM_WL1HPAB2 35
-
-#define SROM_MACHI_IL0 36
-#define SROM_MACMID_IL0 37
-#define SROM_MACLO_IL0 38
-#define SROM_MACHI_ET0 39
-#define SROM_MACMID_ET0 40
-#define SROM_MACLO_ET0 41
-#define SROM_MACHI_ET1 42
-#define SROM_MACMID_ET1 43
-#define SROM_MACLO_ET1 44
-#define SROM3_MACHI 37
-#define SROM3_MACMID 38
-#define SROM3_MACLO 39
-
-#define SROM_BXARSSI2G 40
-#define SROM_BXARSSI5G 41
-
-#define SROM_TRI52G 42
-#define SROM_TRI5GHL 43
-
-#define SROM_RXPO52G 45
-
-#define SROM2_ENETPHY 45
-
-#define SROM_AABREV 46
-/* Fields in AABREV */
-#define SROM_BR_MASK 0x00ff
-#define SROM_CC_MASK 0x0f00
-#define SROM_CC_SHIFT 8
-#define SROM_AA0_MASK 0x3000
-#define SROM_AA0_SHIFT 12
-#define SROM_AA1_MASK 0xc000
-#define SROM_AA1_SHIFT 14
-
-#define SROM_WL0PAB0 47
-#define SROM_WL0PAB1 48
-#define SROM_WL0PAB2 49
-
-#define SROM_LEDBH10 50
-#define SROM_LEDBH32 51
-
-#define SROM_WL10MAXP 52
-
-#define SROM_WL1PAB0 53
-#define SROM_WL1PAB1 54
-#define SROM_WL1PAB2 55
-
-#define SROM_ITT 56
-
-#define SROM_BFL 57
-#define SROM_BFL2 28
-#define SROM3_BFL2 61
-
-#define SROM_AG10 58
-
-#define SROM_CCODE 59
-
-#define SROM_OPO 60
-
-#define SROM3_LEDDC 62
-
-#define SROM_CRCREV 63
-
-/* SROM Rev 4: Reallocate the software part of the srom to accommodate
- * MIMO features. It assumes up to two PCIE functions and 440 bytes
- * of useable srom i.e. the useable storage in chips with OTP that
- * implements hardware redundancy.
- */
-
-#define SROM4_WORDS 220
-
-#define SROM4_SIGN 32
-#define SROM4_SIGNATURE 0x5372
-
-#define SROM4_BREV 33
-
-#define SROM4_BFL0 34
-#define SROM4_BFL1 35
-#define SROM4_BFL2 36
-#define SROM4_BFL3 37
-#define SROM5_BFL0 37
-#define SROM5_BFL1 38
-#define SROM5_BFL2 39
-#define SROM5_BFL3 40
-
-#define SROM4_MACHI 38
-#define SROM4_MACMID 39
-#define SROM4_MACLO 40
-#define SROM5_MACHI 41
-#define SROM5_MACMID 42
-#define SROM5_MACLO 43
-
-#define SROM4_CCODE 41
-#define SROM4_REGREV 42
-#define SROM5_CCODE 34
-#define SROM5_REGREV 35
-
-#define SROM4_LEDBH10 43
-#define SROM4_LEDBH32 44
-#define SROM5_LEDBH10 59
-#define SROM5_LEDBH32 60
-
-#define SROM4_LEDDC 45
-#define SROM5_LEDDC 45
-
-#define SROM4_AA 46
-#define SROM4_AA2G_MASK 0x00ff
-#define SROM4_AA2G_SHIFT 0
-#define SROM4_AA5G_MASK 0xff00
-#define SROM4_AA5G_SHIFT 8
-
-#define SROM4_AG10 47
-#define SROM4_AG32 48
-
-#define SROM4_TXPID2G 49
-#define SROM4_TXPID5G 51
-#define SROM4_TXPID5GL 53
-#define SROM4_TXPID5GH 55
-
-#define SROM4_TXRXC 61
-#define SROM4_TXCHAIN_MASK 0x000f
-#define SROM4_TXCHAIN_SHIFT 0
-#define SROM4_RXCHAIN_MASK 0x00f0
-#define SROM4_RXCHAIN_SHIFT 4
-#define SROM4_SWITCH_MASK 0xff00
-#define SROM4_SWITCH_SHIFT 8
-
-/* Per-path fields */
-#define MAX_PATH_SROM 4
-#define SROM4_PATH0 64
-#define SROM4_PATH1 87
-#define SROM4_PATH2 110
-#define SROM4_PATH3 133
-
-#define SROM4_2G_ITT_MAXP 0
-#define SROM4_2G_PA 1
-#define SROM4_5G_ITT_MAXP 5
-#define SROM4_5GLH_MAXP 6
-#define SROM4_5G_PA 7
-#define SROM4_5GL_PA 11
-#define SROM4_5GH_PA 15
-
-/* Fields in the ITT_MAXP and 5GLH_MAXP words */
-#define B2G_MAXP_MASK 0xff
-#define B2G_ITT_SHIFT 8
-#define B5G_MAXP_MASK 0xff
-#define B5G_ITT_SHIFT 8
-#define B5GH_MAXP_MASK 0xff
-#define B5GL_MAXP_SHIFT 8
-
-/* All the miriad power offsets */
-#define SROM4_2G_CCKPO 156
-#define SROM4_2G_OFDMPO 157
-#define SROM4_5G_OFDMPO 159
-#define SROM4_5GL_OFDMPO 161
-#define SROM4_5GH_OFDMPO 163
-#define SROM4_2G_MCSPO 165
-#define SROM4_5G_MCSPO 173
-#define SROM4_5GL_MCSPO 181
-#define SROM4_5GH_MCSPO 189
-#define SROM4_CDDPO 197
-#define SROM4_STBCPO 198
-#define SROM4_BW40PO 199
-#define SROM4_BWDUPPO 200
-
-#define SROM4_CRCREV 219
-
-/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
- * This is acombined srom for both MIMO and SISO boards, usable in
- * the .130 4Kilobit OTP with hardware redundancy.
- */
-
-#define SROM8_SIGN 64
-
-#define SROM8_BREV 65
-
-#define SROM8_BFL0 66
-#define SROM8_BFL1 67
-#define SROM8_BFL2 68
-#define SROM8_BFL3 69
-
-#define SROM8_MACHI 70
-#define SROM8_MACMID 71
-#define SROM8_MACLO 72
-
-#define SROM8_CCODE 73
-#define SROM8_REGREV 74
-
-#define SROM8_LEDBH10 75
-#define SROM8_LEDBH32 76
-
-#define SROM8_LEDDC 77
-
-#define SROM8_AA 78
-
-#define SROM8_AG10 79
-#define SROM8_AG32 80
-
-#define SROM8_TXRXC 81
-
-#define SROM8_BXARSSI2G 82
-#define SROM8_BXARSSI5G 83
-#define SROM8_TRI52G 84
-#define SROM8_TRI5GHL 85
-#define SROM8_RXPO52G 86
-
-#define SROM8_FEM2G 87
-#define SROM8_FEM5G 88
-#define SROM8_FEM_ANTSWLUT_MASK 0xf800
-#define SROM8_FEM_ANTSWLUT_SHIFT 11
-#define SROM8_FEM_TR_ISO_MASK 0x0700
-#define SROM8_FEM_TR_ISO_SHIFT 8
-#define SROM8_FEM_PDET_RANGE_MASK 0x00f8
-#define SROM8_FEM_PDET_RANGE_SHIFT 3
-#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006
-#define SROM8_FEM_EXTPA_GAIN_SHIFT 1
-#define SROM8_FEM_TSSIPOS_MASK 0x0001
-#define SROM8_FEM_TSSIPOS_SHIFT 0
-
-#define SROM8_THERMAL 89
-
-/* Temp sense related entries */
-#define SROM8_MPWR_RAWTS 90
-#define SROM8_TS_SLP_OPT_CORRX 91
-/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */
-#define SROM8_FOC_HWIQ_IQSWP 92
-
-/* Temperature delta for PHY calibration */
-#define SROM8_PHYCAL_TEMPDELTA 93
-
-/* Per-path offsets & fields */
-#define SROM8_PATH0 96
-#define SROM8_PATH1 112
-#define SROM8_PATH2 128
-#define SROM8_PATH3 144
-
-#define SROM8_2G_ITT_MAXP 0
-#define SROM8_2G_PA 1
-#define SROM8_5G_ITT_MAXP 4
-#define SROM8_5GLH_MAXP 5
-#define SROM8_5G_PA 6
-#define SROM8_5GL_PA 9
-#define SROM8_5GH_PA 12
-
-/* All the miriad power offsets */
-#define SROM8_2G_CCKPO 160
-
-#define SROM8_2G_OFDMPO 161
-#define SROM8_5G_OFDMPO 163
-#define SROM8_5GL_OFDMPO 165
-#define SROM8_5GH_OFDMPO 167
-
-#define SROM8_2G_MCSPO 169
-#define SROM8_5G_MCSPO 177
-#define SROM8_5GL_MCSPO 185
-#define SROM8_5GH_MCSPO 193
-
-#define SROM8_CDDPO 201
-#define SROM8_STBCPO 202
-#define SROM8_BW40PO 203
-#define SROM8_BWDUPPO 204
-
-/* SISO PA parameters are in the path0 spaces */
-#define SROM8_SISO 96
-
-/* Legacy names for SISO PA parameters */
-#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP)
-#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA)
-#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1)
-#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2)
-#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP)
-#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP)
-#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA)
-#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1)
-#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2)
-#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA)
-#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1)
-#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2)
-#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA)
-#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1)
-#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2)
-
-#define SROM8_CRCREV 219
-
-/* SROM REV 9 */
-#define SROM9_2GPO_CCKBW20 160
-#define SROM9_2GPO_CCKBW20UL 161
-#define SROM9_2GPO_LOFDMBW20 162
-#define SROM9_2GPO_LOFDMBW20UL 164
-
-#define SROM9_5GLPO_LOFDMBW20 166
-#define SROM9_5GLPO_LOFDMBW20UL 168
-#define SROM9_5GMPO_LOFDMBW20 170
-#define SROM9_5GMPO_LOFDMBW20UL 172
-#define SROM9_5GHPO_LOFDMBW20 174
-#define SROM9_5GHPO_LOFDMBW20UL 176
-
-#define SROM9_2GPO_MCSBW20 178
-#define SROM9_2GPO_MCSBW20UL 180
-#define SROM9_2GPO_MCSBW40 182
-
-#define SROM9_5GLPO_MCSBW20 184
-#define SROM9_5GLPO_MCSBW20UL 186
-#define SROM9_5GLPO_MCSBW40 188
-#define SROM9_5GMPO_MCSBW20 190
-#define SROM9_5GMPO_MCSBW20UL 192
-#define SROM9_5GMPO_MCSBW40 194
-#define SROM9_5GHPO_MCSBW20 196
-#define SROM9_5GHPO_MCSBW20UL 198
-#define SROM9_5GHPO_MCSBW40 200
-
-#define SROM9_PO_MCS32 202
-#define SROM9_PO_LOFDM40DUP 203
-
-#define SROM9_REV_CRC 219
-
-typedef struct {
- u8 tssipos; /* TSSI positive slope, 1: positive, 0: negative */
- u8 extpagain; /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
- u8 pdetrange; /* support 32 combinations of different Pdet dynamic ranges */
- u8 triso; /* TR switch isolation */
- u8 antswctrllut; /* antswctrl lookup table configuration: 32 possible choices */
-} srom_fem_t;
-
-#endif /* _BHND_BCMSROM_TBL_H_ */
diff --git a/sys/dev/bhnd/bcmsrom_tbl.h b/sys/dev/bhnd/bcmsrom_tbl.h
deleted file mode 100644
index 1373f3f..0000000
--- a/sys/dev/bhnd/bcmsrom_tbl.h
+++ /dev/null
@@ -1,577 +0,0 @@
-/*-
- * Copyright (c) 2010 Broadcom Corporation
- *
- * This file is derived from the bcmsrom.h header distributed with Broadcom's
- * brcm80211 Linux driver release, as contributed to the Linux staging
- * repository.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _BHND_BCMSROM_TBL_H_
-#define _BHND_BCMSROM_TBL_H_
-
-#include "bcmsrom_fmt.h"
-
-typedef struct {
- const char *name;
- u32 revmask;
- u32 flags;
- u16 off;
- u16 mask;
-} sromvar_t;
-
-#define SRFL_MORE 1 /* value continues as described by the next entry */
-#define SRFL_NOFFS 2 /* value bits can't be all one's */
-#define SRFL_PRHEX 4 /* value is in hexdecimal format */
-#define SRFL_PRSIGN 8 /* value is in signed decimal format */
-#define SRFL_CCODE 0x10 /* value is in country code format */
-#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */
-#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */
-#define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */
-
-/* Assumptions:
- * - Ethernet address spans across 3 consective words
- *
- * Table rules:
- * - Add multiple entries next to each other if a value spans across multiple words
- * (even multiple fields in the same word) with each entry except the last having
- * it's SRFL_MORE bit set.
- * - Ethernet address entry does not follow above rule and must not have SRFL_MORE
- * bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
- * - The last entry's name field must be NULL to indicate the end of the table. Other
- * entries must have non-NULL name.
- */
-
-static const sromvar_t pci_sromvars[] = {
- {"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff},
- {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK},
- {"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
- {"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
- {"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
- {"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
- {"", 0, 0, SROM_BFL2, 0xffff},
- {"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
- {"", 0, 0, SROM3_BFL2, 0xffff},
- {"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff},
- {"", 0, 0, SROM4_BFL1, 0xffff},
- {"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff},
- {"", 0, 0, SROM5_BFL1, 0xffff},
- {"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff},
- {"", 0, 0, SROM8_BFL1, 0xffff},
- {"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff},
- {"", 0, 0, SROM4_BFL3, 0xffff},
- {"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff},
- {"", 0, 0, SROM5_BFL3, 0xffff},
- {"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff},
- {"", 0, 0, SROM8_BFL3, 0xffff},
- {"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
- {"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
- {"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff},
- {"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff},
- {"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff},
- {"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff},
- {"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
- {"regrev", 0x00000008, 0, SROM_OPO, 0xff00},
- {"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff},
- {"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff},
- {"regrev", 0xffffff00, 0, SROM8_REGREV, 0x00ff},
- {"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff},
- {"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
- {"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff},
- {"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
- {"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff},
- {"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
- {"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff},
- {"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
- {"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff},
- {"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
- {"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff},
- {"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
- {"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
- {"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
- {"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
- {"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
- {"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
- {"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
- {"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
- {"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff},
- {"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff},
- {"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
- {"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
- {"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
- {"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
- {"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
- {"opo", 0x0000000c, 0, SROM_OPO, 0x00ff},
- {"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
- {"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
- {"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff},
- {"aa2g", 0xffffff00, 0, SROM8_AA, 0x00ff},
- {"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
- {"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00},
- {"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00},
- {"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff},
- {"ag1", 0x0000000e, 0, SROM_AG10, 0xff00},
- {"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff},
- {"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00},
- {"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff},
- {"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00},
- {"ag0", 0xffffff00, 0, SROM8_AG10, 0x00ff},
- {"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00},
- {"ag2", 0xffffff00, 0, SROM8_AG32, 0x00ff},
- {"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00},
- {"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
- {"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
- {"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
- {"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
- {"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
- {"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
- {"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
- {"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
- {"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
- {"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00},
- {"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
- {"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
- {"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff},
- {"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
- {"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
- {"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
- {"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
- {"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
- {"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
- {"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
- {"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
- {"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
- {"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
- {"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
- {"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
- {"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
- {"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
- {"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
- {"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
- {"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
- {"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
- {"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
- {"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
- {"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
- {"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
- {"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
- {"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
- {"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
- {"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
- {"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
- {"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
- {"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
- {"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff},
- {"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00},
- {"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff},
- {"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00},
- {"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
- {"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00},
- {"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
- {"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
- {"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff},
- {"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
- {"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
- {"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
- {"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK},
- {"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK},
- {"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK},
- {"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK},
- {"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK},
- {"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK},
- {"tssipos2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK},
- {"extpagain2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK},
- {"pdetrange2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK},
- {"triso2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
- {"antswctl2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK},
- {"tssipos5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK},
- {"extpagain5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK},
- {"pdetrange5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK},
- {"triso5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
- {"antswctl5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK},
- {"tempthresh", 0xffffff00, 0, SROM8_THERMAL, 0xff00},
- {"tempoffset", 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
- {"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff},
- {"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
- {"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G+1, 0x00ff},
- {"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G+1, 0xff00},
- {"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff},
- {"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
- {"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G+1, 0x00ff},
- {"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G+1, 0xff00},
- {"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff},
- {"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
- {"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL+1, 0x00ff},
- {"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL+1, 0xff00},
- {"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff},
- {"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
- {"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH+1, 0x00ff},
- {"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH+1, 0xff00},
-
- {"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
- {"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
- {"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
- {"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
- {"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
- {"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
- {"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
- {"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
- {"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff},
- {"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff},
- {"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff},
- {"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff},
- {"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff},
- {"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff},
- {"rawtempsense",0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff},
- {"measpower", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00},
- {"tempsense_slope",0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0x00ff},
- {"tempcorrx", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00},
- {"tempsense_option",0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0x0300},
- {"freqoffset_corr",0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x000f},
- {"iqcal_swp_dis",0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010},
- {"hw_iqcal_en", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020},
- {"phycal_tempdelta",0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff},
-
- {"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
- {"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
- {"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
- {"", 0, 0, SROM4_2G_OFDMPO+1, 0xffff},
- {"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
- {"", 0, 0, SROM4_5G_OFDMPO+1, 0xffff},
- {"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
- {"", 0, 0, SROM4_5GL_OFDMPO+1, 0xffff},
- {"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
- {"", 0, 0, SROM4_5GH_OFDMPO+1, 0xffff},
- {"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
- {"", 0, 0, SROM8_2G_OFDMPO+1, 0xffff},
- {"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
- {"", 0, 0, SROM8_5G_OFDMPO+1, 0xffff},
- {"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
- {"", 0, 0, SROM8_5GL_OFDMPO+1, 0xffff},
- {"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
- {"", 0, 0, SROM8_5GH_OFDMPO+1, 0xffff},
-
- {"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
- {"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO+1, 0xffff},
- {"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO+2, 0xffff},
- {"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO+3, 0xffff},
- {"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO+4, 0xffff},
- {"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO+5, 0xffff},
- {"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO+6, 0xffff},
- {"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO+7, 0xffff},
-
- {"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
- {"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO+1, 0xffff},
- {"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO+2, 0xffff},
- {"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO+3, 0xffff},
- {"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO+4, 0xffff},
- {"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO+5, 0xffff},
- {"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO+6, 0xffff},
- {"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO+7, 0xffff},
-
- {"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
- {"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO+1, 0xffff},
- {"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO+2, 0xffff},
- {"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO+3, 0xffff},
- {"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO+4, 0xffff},
- {"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO+5, 0xffff},
- {"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO+6, 0xffff},
- {"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO+7, 0xffff},
-
- {"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
- {"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO+1, 0xffff},
- {"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO+2, 0xffff},
- {"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO+3, 0xffff},
- {"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO+4, 0xffff},
- {"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO+5, 0xffff},
- {"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO+6, 0xffff},
- {"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO+7, 0xffff},
-
- {"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
- {"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO+1, 0xffff},
- {"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO+2, 0xffff},
- {"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO+3, 0xffff},
- {"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO+4, 0xffff},
- {"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO+5, 0xffff},
- {"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO+6, 0xffff},
- {"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO+7, 0xffff},
-
- {"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
- {"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO+1, 0xffff},
- {"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO+2, 0xffff},
- {"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO+3, 0xffff},
- {"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO+4, 0xffff},
- {"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO+5, 0xffff},
- {"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO+6, 0xffff},
- {"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO+7, 0xffff},
-
- {"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
- {"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO+1, 0xffff},
- {"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO+2, 0xffff},
- {"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO+3, 0xffff},
- {"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO+4, 0xffff},
- {"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO+5, 0xffff},
- {"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO+6, 0xffff},
- {"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO+7, 0xffff},
- {"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
- {"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO+1, 0xffff},
- {"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO+2, 0xffff},
- {"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO+3, 0xffff},
- {"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO+4, 0xffff},
- {"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO+5, 0xffff},
- {"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO+6, 0xffff},
- {"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO+7, 0xffff},
- {"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff},
- {"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff},
- {"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff},
- {"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
- {"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff},
- {"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff},
- {"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff},
- {"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
-
- /* power per rate from sromrev 9 */
- {"cckbw202gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
- {"cckbw20ul2gpo",0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
- {"legofdmbw202gpo",0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20, 0xffff},
- {"", 0, 0, SROM9_2GPO_LOFDMBW20+1, 0xffff},
- {"legofdmbw20ul2gpo",0xfffffe00,SRFL_MORE, SROM9_2GPO_LOFDMBW20UL, 0xffff},
- {"", 0, 0, SROM9_2GPO_LOFDMBW20UL+1,0xffff},
- {"legofdmbw205glpo",0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20, 0xffff},
- {"", 0, 0, SROM9_5GLPO_LOFDMBW20+1,0xffff},
- {"legofdmbw20ul5glpo",0xfffffe00,SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL,0xffff},
- {"", 0, 0, SROM9_5GLPO_LOFDMBW20UL+1,0xffff},
- {"legofdmbw205gmpo",0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20, 0xffff},
- {"", 0, 0, SROM9_5GMPO_LOFDMBW20+1,0xffff},
- {"legofdmbw20ul5gmpo",0xfffffe00,SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL,0xffff},
- {"", 0, 0, SROM9_5GMPO_LOFDMBW20UL+1,0xffff},
- {"legofdmbw205ghpo",0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20, 0xffff},
- {"", 0, 0, SROM9_5GHPO_LOFDMBW20+1,0xffff},
- {"legofdmbw20ul5ghpo",0xfffffe00,SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL,0xffff},
- {"", 0, 0, SROM9_5GHPO_LOFDMBW20UL+1,0xffff},
- {"mcsbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff},
- {"", 0, 0, SROM9_2GPO_MCSBW20+1, 0xffff},
- {"mcsbw20ul2gpo",0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff},
- {"", 0, 0, SROM9_2GPO_MCSBW20UL+1, 0xffff},
- {"mcsbw402gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff},
- {"", 0, 0, SROM9_2GPO_MCSBW40+1, 0xffff},
- {"mcsbw205glpo",0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff},
- {"", 0, 0, SROM9_5GLPO_MCSBW20+1, 0xffff},
- {"mcsbw20ul5glpo",0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20UL, 0xffff},
- {"", 0, 0, SROM9_5GLPO_MCSBW20UL+1,0xffff},
- {"mcsbw405glpo",0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff},
- {"", 0, 0, SROM9_5GLPO_MCSBW40+1, 0xffff},
- {"mcsbw205gmpo",0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff},
- {"", 0, 0, SROM9_5GMPO_MCSBW20+1, 0xffff},
- {"mcsbw20ul5gmpo",0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20UL, 0xffff},
- {"", 0, 0, SROM9_5GMPO_MCSBW20UL+1,0xffff},
- {"mcsbw405gmpo",0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff},
- {"", 0, 0, SROM9_5GMPO_MCSBW40+1, 0xffff},
- {"mcsbw205ghpo",0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff},
- {"", 0, 0, SROM9_5GHPO_MCSBW20+1, 0xffff},
- {"mcsbw20ul5ghpo",0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20UL, 0xffff},
- {"", 0, 0, SROM9_5GHPO_MCSBW20UL+1,0xffff},
- {"mcsbw405ghpo",0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff},
- {"", 0, 0, SROM9_5GHPO_MCSBW40+1, 0xffff},
- {"mcs32po", 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
- {"legofdm40duppo",0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
-
- {NULL, 0, 0, 0, 0}
-};
-
-static const sromvar_t perpath_pci_sromvars[] = {
- {"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff},
- {"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
- {"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
- {"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
- {"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA+1, 0xffff},
- {"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA+2, 0xffff},
- {"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA+3, 0xffff},
- {"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff},
- {"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff},
- {"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
- {"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
- {"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA+1, 0xffff},
- {"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA+2, 0xffff},
- {"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA+3, 0xffff},
- {"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
- {"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA+1, 0xffff},
- {"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA+2, 0xffff},
- {"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA+3, 0xffff},
- {"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
- {"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA+1, 0xffff},
- {"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA+2, 0xffff},
- {"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA+3, 0xffff},
- {"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
- {"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
- {"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
- {"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
- {"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA+1, 0xffff},
- {"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA+2, 0xffff},
- {"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
- {"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
- {"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
- {"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
- {"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA+1, 0xffff},
- {"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA+2, 0xffff},
- {"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
- {"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA+1, 0xffff},
- {"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA+2, 0xffff},
- {"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
- {"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA+1, 0xffff},
- {"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA+2, 0xffff},
- {NULL, 0, 0, 0, 0}
-};
-
-#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP))
-#define PHY_TYPE_N 4 /* N-Phy value */
-#define PHY_TYPE_LP 5 /* LP-Phy value */
-#endif /* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */
-#if !defined(PHY_TYPE_NULL)
-#define PHY_TYPE_NULL 0xf /* Invalid Phy value */
-#endif /* !defined(PHY_TYPE_NULL) */
-
-typedef struct {
- u16 phy_type;
- u16 bandrange;
- u16 chain;
- const char *vars;
-} pavars_t;
-
-static const pavars_t pavars[] = {
- /* NPHY */
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0, "pa5glw0a0 pa5glw1a0 pa5glw2a0"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1, "pa5glw0a1 pa5glw1a1 pa5glw2a1"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0, "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1, "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"},
- /* LPPHY */
- {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"},
- {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"},
- {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"},
- {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"},
- {PHY_TYPE_NULL, 0, 0, ""}
-};
-
-typedef struct {
- u16 phy_type;
- u16 bandrange;
- const char *vars;
-} povars_t;
-
-static const povars_t povars[] = {
- /* NPHY */
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G,
- "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 "
- "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL,
- "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 "
- "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM,
- "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 "
- "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH,
- "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 "
- "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"},
- {PHY_TYPE_NULL, 0, ""}
-};
-
-typedef struct {
- u8 tag; /* Broadcom subtag name */
- u8 len; /* Length field of the tuple, note that it includes the
- * subtag name (1 byte): 1 + tuple content length
- */
- const char *params;
-} cis_tuple_t;
-
-#define OTP_RAW (0xff - 1) /* Reserved tuple number for wrvar Raw input */
-#define OTP_VERS_1 (0xff - 2) /* CISTPL_VERS_1 */
-#define OTP_MANFID (0xff - 3) /* CISTPL_MANFID */
-#define OTP_RAW1 (0xff - 4) /* Like RAW, but comes first */
-
-static const cis_tuple_t cis_hnbuvars[] = {
- {OTP_RAW1, 0, ""}, /* special case */
- {OTP_VERS_1, 0, "smanf sproductname"}, /* special case (non BRCM tuple) */
- {OTP_MANFID, 4, "2manfid 2prodid"}, /* special case (non BRCM tuple) */
- {HNBU_SROMREV, 2, "1sromrev"},
- /* NOTE: subdevid is also written to boardtype.
- * Need to write HNBU_BOARDTYPE to change it if it is different.
- */
- {HNBU_CHIPID, 11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"},
- {HNBU_BOARDREV, 3, "2boardrev"},
- {HNBU_PAPARMS, 10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"},
- {HNBU_AA, 3, "1aa2g 1aa5g"},
- {HNBU_AA, 3, "1aa0 1aa1"}, /* backward compatibility */
- {HNBU_AG, 5, "1ag0 1ag1 1ag2 1ag3"},
- {HNBU_BOARDFLAGS, 9, "4boardflags 4boardflags2"},
- {HNBU_LEDS, 5, "1ledbh0 1ledbh1 1ledbh2 1ledbh3"},
- {HNBU_CCODE, 4, "2ccode 1cctl"},
- {HNBU_CCKPO, 3, "2cckpo"},
- {HNBU_OFDMPO, 5, "4ofdmpo"},
- {HNBU_RDLID, 3, "2rdlid"},
- {HNBU_RSSISMBXA2G, 3, "0rssismf2g 0rssismc2g 0rssisav2g 0bxa2g"}, /* special case */
- {HNBU_RSSISMBXA5G, 3, "0rssismf5g 0rssismc5g 0rssisav5g 0bxa5g"}, /* special case */
- {HNBU_XTALFREQ, 5, "4xtalfreq"},
- {HNBU_TRI2G, 2, "1tri2g"},
- {HNBU_TRI5G, 4, "1tri5gl 1tri5g 1tri5gh"},
- {HNBU_RXPO2G, 2, "1rxpo2g"},
- {HNBU_RXPO5G, 2, "1rxpo5g"},
- {HNBU_BOARDNUM, 3, "2boardnum"},
- {HNBU_MACADDR, 7, "6macaddr"}, /* special case */
- {HNBU_RDLSN, 3, "2rdlsn"},
- {HNBU_BOARDTYPE, 3, "2boardtype"},
- {HNBU_LEDDC, 3, "2leddc"},
- {HNBU_RDLRNDIS, 2, "1rdlndis"},
- {HNBU_CHAINSWITCH, 5, "1txchain 1rxchain 2antswitch"},
- {HNBU_REGREV, 2, "1regrev"},
- {HNBU_FEM, 5, "0antswctl2g, 0triso2g, 0pdetrange2g, 0extpagain2g, 0tssipos2g" "0antswctl5g, 0triso5g, 0pdetrange5g, 0extpagain5g, 0tssipos5g"}, /* special case */
- {HNBU_PAPARMS_C0, 31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 "
- "2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 "
- "2pa5gw1a0 2pa5gw2a0 2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 "
- "2pa5ghw1a0 2pa5ghw2a0"},
- {HNBU_PAPARMS_C1, 31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 "
- "2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 "
- "2pa5gw1a1 2pa5gw2a1 2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 "
- "2pa5ghw1a1 2pa5ghw2a1"},
- {HNBU_PO_CCKOFDM, 19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo "
- "4ofdm5ghpo"},
- {HNBU_PO_MCS2G, 17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 "
- "2mcs2gpo4 2mcs2gpo5 2mcs2gpo6 2mcs2gpo7"},
- {HNBU_PO_MCS5GM, 17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 "
- "2mcs5gpo4 2mcs5gpo5 2mcs5gpo6 2mcs5gpo7"},
- {HNBU_PO_MCS5GLH, 33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 "
- "2mcs5glpo4 2mcs5glpo5 2mcs5glpo6 2mcs5glpo7 "
- "2mcs5ghpo0 2mcs5ghpo1 2mcs5ghpo2 2mcs5ghpo3 "
- "2mcs5ghpo4 2mcs5ghpo5 2mcs5ghpo6 2mcs5ghpo7"},
- {HNBU_CCKFILTTYPE, 2, "1cckdigfilttype"},
- {HNBU_PO_CDD, 3, "2cddpo"},
- {HNBU_PO_STBC, 3, "2stbcpo"},
- {HNBU_PO_40M, 3, "2bw40po"},
- {HNBU_PO_40MDUP, 3, "2bwduppo"},
- {HNBU_RDLRWU, 2, "1rdlrwu"},
- {HNBU_WPS, 3, "1wpsgpio 1wpsled"},
- {HNBU_USBFS, 2, "1usbfs"},
- {HNBU_CUSTOM1, 5, "4customvar1"},
- {OTP_RAW, 0, ""}, /* special case */
- {HNBU_OFDMPO5G, 13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"},
- {HNBU_USBEPNUM, 3, "2usbepnum"},
- {0xFF, 0, ""}
-};
-
-#endif /* _BHND_BCMSROM_TBL_H_ */
diff --git a/sys/dev/bhnd/bhnd.c b/sys/dev/bhnd/bhnd.c
index 01911f63..3be15b2 100644
--- a/sys/dev/bhnd/bhnd.c
+++ b/sys/dev/bhnd/bhnd.c
@@ -58,11 +58,14 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <machine/resource.h>
-#include "bhnd.h"
-#include "bhndvar.h"
+#include "nvram/bhnd_nvram.h"
+#include "bhnd_chipc_if.h"
#include "bhnd_nvram_if.h"
+#include "bhnd.h"
+#include "bhndvar.h"
+
MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures");
/**
@@ -347,10 +350,12 @@ bhnd_generic_get_probe_order(device_t dev, device_t child)
case BHND_DEVCLASS_EROM:
case BHND_DEVCLASS_OTHER:
case BHND_DEVCLASS_INVALID:
- if (bhnd_is_hostb_device(child))
+ if (bhnd_find_hostb_device(dev) == child)
return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY);
return (BHND_PROBE_DEFAULT);
+ default:
+ return (BHND_PROBE_DEFAULT);
}
}
@@ -384,23 +389,27 @@ bhnd_generic_is_region_valid(device_t dev, device_t child,
static device_t
find_nvram_child(device_t dev)
{
- device_t chipc, nvram;
+ device_t chipc, nvram;
/* Look for a directly-attached NVRAM child */
- nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass),
- -1);
- if (nvram == NULL)
- return (NULL);
+ nvram = device_find_child(dev, "bhnd_nvram", 0);
+ if (nvram != NULL)
+ return (nvram);
- /* Further checks require a bhnd(4) bus */
+ /* Remaining checks are only applicable when searching a bhnd(4)
+ * bus. */
if (device_get_devclass(dev) != bhnd_devclass)
return (NULL);
- /* Look for a ChipCommon-attached OTP device */
+ /* Look for a ChipCommon device */
if ((chipc = bhnd_find_child(dev, BHND_DEVCLASS_CC, -1)) != NULL) {
- /* Recursively search the ChipCommon device */
- if ((nvram = find_nvram_child(chipc)) != NULL)
- return (nvram);
+ bhnd_nvram_src_t src;
+
+ /* Query the NVRAM source and determine whether it's
+ * accessible via the ChipCommon device */
+ src = BHND_CHIPC_NVRAM_SRC(chipc);
+ if (BHND_NVRAM_SRC_CC(src))
+ return (chipc);
}
/* Not found */
@@ -408,22 +417,26 @@ find_nvram_child(device_t dev)
}
/**
- * Default bhnd(4) bus driver implementation of BHND_BUS_READ_NVRAM_VAR().
+ * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR().
+ *
+ * This implementation searches @p dev for a usable NVRAM child device:
+ * - The first child device implementing the bhnd_nvram devclass is
+ * returned, otherwise
+ * - If @p dev is a bhnd(4) bus, a ChipCommon core that advertises an
+ * attached NVRAM source.
*
- * This implementation searches @p dev for a valid NVRAM device. If no NVRAM
- * child device is found on @p dev, the request is delegated to the
- * BHND_BUS_READ_NVRAM_VAR() method on the parent
- * of @p dev.
+ * If no usable child device is found on @p dev, the request is delegated to
+ * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev.
*/
static int
-bhnd_generic_read_nvram_var(device_t dev, device_t child, const char *name,
+bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name,
void *buf, size_t *size)
{
device_t nvram;
/* Try to find an NVRAM device applicable to @p child */
if ((nvram = find_nvram_child(dev)) == NULL)
- return (BHND_BUS_READ_NVRAM_VAR(device_get_parent(dev), child,
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
name, buf, size));
return BHND_NVRAM_GETVAR(nvram, name, buf, size);
@@ -585,48 +598,53 @@ bhnd_generic_resume_child(device_t dev, device_t child)
* non-bridged bus implementations, resources will never be marked as
* indirect, and these methods should never be called.
*/
-
-static uint8_t
-bhnd_read_1(device_t dev, device_t child, struct bhnd_resource *r,
- bus_size_t offset)
-{
- return (BHND_BUS_READ_1(device_get_parent(dev), child, r, offset));
-}
-
-static uint16_t
-bhnd_read_2(device_t dev, device_t child, struct bhnd_resource *r,
- bus_size_t offset)
-{
- return (BHND_BUS_READ_2(device_get_parent(dev), child, r, offset));
-}
-
-static uint32_t
-bhnd_read_4(device_t dev, device_t child, struct bhnd_resource *r,
- bus_size_t offset)
-{
- return (BHND_BUS_READ_4(device_get_parent(dev), child, r, offset));
+#define BHND_IO_READ(_type, _name, _method) \
+static _type \
+bhnd_read_ ## _name (device_t dev, device_t child, \
+ struct bhnd_resource *r, bus_size_t offset) \
+{ \
+ return (BHND_BUS_READ_ ## _method( \
+ device_get_parent(dev), child, r, offset)); \
}
-static void
-bhnd_write_1(device_t dev, device_t child, struct bhnd_resource *r,
- bus_size_t offset, uint8_t value)
-{
- BHND_BUS_WRITE_1(device_get_parent(dev), child, r, offset, value);
+#define BHND_IO_WRITE(_type, _name, _method) \
+static void \
+bhnd_write_ ## _name (device_t dev, device_t child, \
+ struct bhnd_resource *r, bus_size_t offset, _type value) \
+{ \
+ return (BHND_BUS_WRITE_ ## _method( \
+ device_get_parent(dev), child, r, offset, \
+ value)); \
}
-static void
-bhnd_write_2(device_t dev, device_t child, struct bhnd_resource *r,
- bus_size_t offset, uint16_t value)
-{
- BHND_BUS_WRITE_2(device_get_parent(dev), child, r, offset, value);
+#define BHND_IO_MULTI(_type, _rw, _name, _method) \
+static void \
+bhnd_ ## _rw ## _multi_ ## _name (device_t dev, device_t child, \
+ struct bhnd_resource *r, bus_size_t offset, _type *datap, \
+ bus_size_t count) \
+{ \
+ BHND_BUS_ ## _method(device_get_parent(dev), child, r, \
+ offset, datap, count); \
}
-static void
-bhnd_write_4(device_t dev, device_t child, struct bhnd_resource *r,
- bus_size_t offset, uint32_t value)
-{
- BHND_BUS_WRITE_4(device_get_parent(dev), child, r, offset, value);
-}
+#define BHND_IO_METHODS(_type, _size) \
+ BHND_IO_READ(_type, _size, _size) \
+ BHND_IO_WRITE(_type, _size, _size) \
+ \
+ BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \
+ BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \
+ \
+ BHND_IO_MULTI(_type, read, _size, READ_MULTI_ ## _size) \
+ BHND_IO_MULTI(_type, write, _size, WRITE_MULTI_ ## _size) \
+ \
+ BHND_IO_MULTI(_type, read, stream_ ## _size, \
+ READ_MULTI_STREAM_ ## _size) \
+ BHND_IO_MULTI(_type, write, stream_ ## _size, \
+ WRITE_MULTI_STREAM_ ## _size) \
+
+BHND_IO_METHODS(uint8_t, 1);
+BHND_IO_METHODS(uint16_t, 2);
+BHND_IO_METHODS(uint32_t, 4);
static void
bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r,
@@ -674,15 +692,35 @@ static device_method_t bhnd_methods[] = {
DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid),
DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order),
DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid),
- DEVMETHOD(bhnd_bus_is_hostb_device, bhnd_bus_generic_is_hostb_device),
DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled),
- DEVMETHOD(bhnd_bus_read_nvram_var, bhnd_generic_read_nvram_var),
+ DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var),
DEVMETHOD(bhnd_bus_read_1, bhnd_read_1),
DEVMETHOD(bhnd_bus_read_2, bhnd_read_2),
DEVMETHOD(bhnd_bus_read_4, bhnd_read_4),
DEVMETHOD(bhnd_bus_write_1, bhnd_write_1),
DEVMETHOD(bhnd_bus_write_2, bhnd_write_2),
DEVMETHOD(bhnd_bus_write_4, bhnd_write_4),
+ DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1),
+ DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2),
+ DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4),
+ DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1),
+ DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2),
+ DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4),
+
+ DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1),
+ DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2),
+ DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4),
+ DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1),
+ DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2),
+ DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4),
+
+ DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1),
+ DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2),
+ DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4),
+ DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1),
+ DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2),
+ DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4),
+
DEVMETHOD(bhnd_bus_barrier, bhnd_barrier),
DEVMETHOD_END
diff --git a/sys/dev/bhnd/bhnd.h b/sys/dev/bhnd/bhnd.h
index 7589556..dca9867 100644
--- a/sys/dev/bhnd/bhnd.h
+++ b/sys/dev/bhnd/bhnd.h
@@ -232,6 +232,65 @@ struct bhnd_core_match {
.unit = -1 \
}
+/** A chipset match descriptor. */
+struct bhnd_chip_match {
+ /** Select fields to be matched */
+ uint8_t
+ match_id:1,
+ match_rev:1,
+ match_pkg:1,
+ match_flags_unused:5;
+
+ uint16_t chip_id; /**< required chip id */
+ struct bhnd_hwrev_match chip_rev; /**< matching chip revisions */
+ uint8_t chip_pkg; /**< required package */
+};
+
+#define BHND_CHIP_MATCH_ANY \
+ { .match_id = 0, .match_rev = 0, .match_pkg = 0 }
+
+#define BHND_CHIP_MATCH_IS_ANY(_m) \
+ ((_m)->match_id == 0 && (_m)->match_rev == 0 && (_m)->match_pkg == 0)
+
+/** Set the required chip ID within a bhnd_chip_match instance */
+#define BHND_CHIP_ID(_cid) \
+ .match_id = 1, .chip_id = BHND_CHIPID_BCM ## _cid
+
+/** Set the required revision range within a bhnd_chip_match instance */
+#define BHND_CHIP_REV(_rev) \
+ .match_rev = 1, .chip_rev = BHND_ ## _rev
+
+/** Set the required package ID within a bhnd_chip_match instance */
+#define BHND_CHIP_PKG(_pkg) \
+ .match_pkg = 1, .chip_pkg = BHND_PKGID_BCM ## _pkg
+
+/** Set the required chip and package ID within a bhnd_chip_match instance */
+#define BHND_CHIP_IP(_cid, _pkg) \
+ BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg)
+
+/** Set the required chip ID, package ID, and revision within a bhnd_chip_match
+ * instance */
+#define BHND_CHIP_IPR(_cid, _pkg, _rev) \
+ BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg), BHND_CHIP_REV(_rev)
+
+/** Set the required chip ID and revision within a bhnd_chip_match
+ * instance */
+#define BHND_CHIP_IR(_cid, _rev) \
+ BHND_CHIP_ID(_cid), BHND_CHIP_REV(_rev)
+
+/**
+ * Chipset quirk table descriptor.
+ */
+struct bhnd_chip_quirk {
+ const struct bhnd_chip_match chip; /**< chip match descriptor */
+ uint32_t quirks; /**< quirk flags */
+};
+
+#define BHND_CHIP_QUIRK_END { BHND_CHIP_MATCH_ANY, 0 }
+
+#define BHND_CHIP_QUIRK_IS_END(_q) \
+ (BHND_CHIP_MATCH_IS_ANY(&(_q)->chip) && (_q)->quirks == 0)
+
/**
* Device quirk table descriptor.
*/
@@ -297,9 +356,16 @@ bool bhnd_core_matches(
const struct bhnd_core_info *core,
const struct bhnd_core_match *desc);
+bool bhnd_chip_matches(
+ const struct bhnd_chipid *chipid,
+ const struct bhnd_chip_match *desc);
+
bool bhnd_hwrev_matches(uint16_t hwrev,
const struct bhnd_hwrev_match *desc);
+uint32_t bhnd_chip_quirks(device_t dev,
+ const struct bhnd_chip_quirk *table);
+
bool bhnd_device_matches(device_t dev,
const struct bhnd_core_match *desc);
@@ -335,8 +401,6 @@ void bhnd_set_custom_core_desc(device_t dev,
void bhnd_set_default_core_desc(device_t dev);
-bool bhnd_bus_generic_is_hostb_device(device_t dev,
- device_t child);
bool bhnd_bus_generic_is_hw_disabled(device_t dev,
device_t child);
bool bhnd_bus_generic_is_region_valid(device_t dev,
@@ -364,14 +428,14 @@ int bhnd_bus_generic_deactivate_resource (device_t dev,
/**
- * Return true if @p dev is serving as a host bridge for its parent bhnd
- * bus.
+ * Return the active host bridge core for the bhnd bus, if any, or NULL if
+ * not found.
*
- * @param dev A bhnd bus child device.
+ * @param dev A bhnd bus device.
*/
-static inline bool
-bhnd_is_hostb_device(device_t dev) {
- return (BHND_BUS_IS_HOSTB_DEVICE(device_get_parent(dev), dev));
+static inline device_t
+bhnd_find_hostb_device(device_t dev) {
+ return (BHND_BUS_FIND_HOSTB_DEVICE(dev));
}
/**
@@ -391,6 +455,66 @@ bhnd_is_hw_disabled(device_t dev) {
}
/**
+ * Return the BHND chip identification info for the bhnd bus.
+ *
+ * @param dev A bhnd bus child device.
+ */
+static inline const struct bhnd_chipid *
+bhnd_get_chipid(device_t dev) {
+ return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev));
+};
+
+/**
+ * Determine an NVRAM variable's expected size.
+ *
+ * @param dev A bhnd bus child device.
+ * @param name The variable name.
+ * @param[out] len On success, the variable's size, in bytes.
+ *
+ * @retval 0 success
+ * @retval ENOENT The requested variable was not found.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+static inline int
+bhnd_nvram_getvarlen(device_t dev, const char *name, size_t *len)
+{
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, NULL,
+ len));
+}
+
+/**
+ * Read an NVRAM variable.
+ *
+ * @param dev A bhnd bus child device.
+ * @param name The NVRAM variable name.
+ * @param buf A buffer large enough to hold @p len bytes. On success,
+ * the requested value will be written to this buffer.
+ * @param len The required variable length.
+ *
+ * @retval 0 success
+ * @retval ENOENT The requested variable was not found.
+ * @retval EINVAL If @p len does not match the actual variable size.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+static inline int
+bhnd_nvram_getvar(device_t dev, const char *name, void *buf, size_t len)
+{
+ size_t var_len;
+ int error;
+
+ if ((error = bhnd_nvram_getvarlen(dev, name, &var_len)))
+ return (error);
+
+ if (len != var_len)
+ return (EINVAL);
+
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, buf,
+ &len));
+}
+
+/**
* Allocate a resource from a device's parent bhnd(4) bus.
*
* @param dev The device requesting resource ownership.
@@ -610,37 +734,152 @@ bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port,
#define bhnd_bus_barrier(r, o, l, f) \
((r)->direct) ? \
bus_barrier((r)->res, (o), (l), (f)) : \
- BHND_BUS_BARRIER(device_get_parent(rman_get_device((r)->res)), \
+ BHND_BUS_BARRIER( \
+ device_get_parent(rman_get_device((r)->res)), \
rman_get_device((r)->res), (r), (o), (l), (f))
#define bhnd_bus_read_1(r, o) \
((r)->direct) ? \
bus_read_1((r)->res, (o)) : \
- BHND_BUS_READ_1(device_get_parent(rman_get_device((r)->res)), \
+ BHND_BUS_READ_1( \
+ device_get_parent(rman_get_device((r)->res)), \
rman_get_device((r)->res), (r), (o))
+#define bhnd_bus_read_multi_1(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_read_multi_1((r)->res, (o), (d), (c)) : \
+ BHND_BUS_READ_MULTI_1( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
#define bhnd_bus_write_1(r, o, v) \
((r)->direct) ? \
bus_write_1((r)->res, (o), (v)) : \
- BHND_BUS_WRITE_1(device_get_parent(rman_get_device((r)->res)), \
+ BHND_BUS_WRITE_1( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (v))
+#define bhnd_bus_write_multi_1(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_write_multi_1((r)->res, (o), (d), (c)) : \
+ BHND_BUS_WRITE_MULTI_1( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
+#define bhnd_bus_read_stream_1(r, o) \
+ ((r)->direct) ? \
+ bus_read_stream_1((r)->res, (o)) : \
+ BHND_BUS_READ_STREAM_1( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o))
+#define bhnd_bus_read_multi_stream_1(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_read_multi_stream_1((r)->res, (o), (d), (c)) : \
+ BHND_BUS_READ_MULTI_STREAM_1( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
+#define bhnd_bus_write_stream_1(r, o, v) \
+ ((r)->direct) ? \
+ bus_write_stream_1((r)->res, (o), (v)) : \
+ BHND_BUS_WRITE_STREAM_1( \
+ device_get_parent(rman_get_device((r)->res)), \
rman_get_device((r)->res), (r), (o), (v))
+#define bhnd_bus_write_multi_stream_1(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_write_multi_stream_1((r)->res, (o), (d), (c)) : \
+ BHND_BUS_WRITE_MULTI_STREAM_1( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
#define bhnd_bus_read_2(r, o) \
((r)->direct) ? \
bus_read_2((r)->res, (o)) : \
- BHND_BUS_READ_2(device_get_parent(rman_get_device((r)->res)), \
+ BHND_BUS_READ_2( \
+ device_get_parent(rman_get_device((r)->res)), \
rman_get_device((r)->res), (r), (o))
+#define bhnd_bus_read_multi_2(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_read_multi_2((r)->res, (o), (d), (c)) : \
+ BHND_BUS_READ_MULTI_2( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
#define bhnd_bus_write_2(r, o, v) \
((r)->direct) ? \
bus_write_2((r)->res, (o), (v)) : \
- BHND_BUS_WRITE_2(device_get_parent(rman_get_device((r)->res)), \
+ BHND_BUS_WRITE_2( \
+ device_get_parent(rman_get_device((r)->res)), \
rman_get_device((r)->res), (r), (o), (v))
+#define bhnd_bus_write_multi_2(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_write_multi_2((r)->res, (o), (d), (c)) : \
+ BHND_BUS_WRITE_MULTI_2( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
+#define bhnd_bus_read_stream_2(r, o) \
+ ((r)->direct) ? \
+ bus_read_stream_2((r)->res, (o)) : \
+ BHND_BUS_READ_STREAM_2( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o))
+#define bhnd_bus_read_multi_stream_2(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_read_multi_stream_2((r)->res, (o), (d), (c)) : \
+ BHND_BUS_READ_MULTI_STREAM_2( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
+#define bhnd_bus_write_stream_2(r, o, v) \
+ ((r)->direct) ? \
+ bus_write_stream_2((r)->res, (o), (v)) : \
+ BHND_BUS_WRITE_STREAM_2( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (v))
+#define bhnd_bus_write_multi_stream_2(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_write_multi_stream_2((r)->res, (o), (d), (c)) : \
+ BHND_BUS_WRITE_MULTI_STREAM_2( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
#define bhnd_bus_read_4(r, o) \
((r)->direct) ? \
bus_read_4((r)->res, (o)) : \
- BHND_BUS_READ_4(device_get_parent(rman_get_device((r)->res)), \
+ BHND_BUS_READ_4( \
+ device_get_parent(rman_get_device((r)->res)), \
rman_get_device((r)->res), (r), (o))
+#define bhnd_bus_read_multi_4(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_read_multi_4((r)->res, (o), (d), (c)) : \
+ BHND_BUS_READ_MULTI_4( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
#define bhnd_bus_write_4(r, o, v) \
((r)->direct) ? \
bus_write_4((r)->res, (o), (v)) : \
- BHND_BUS_WRITE_4(device_get_parent(rman_get_device((r)->res)), \
+ BHND_BUS_WRITE_4( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (v))
+#define bhnd_bus_write_multi_4(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_write_multi_4((r)->res, (o), (d), (c)) : \
+ BHND_BUS_WRITE_MULTI_4( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
+#define bhnd_bus_read_stream_4(r, o) \
+ ((r)->direct) ? \
+ bus_read_stream_4((r)->res, (o)) : \
+ BHND_BUS_READ_STREAM_4( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o))
+#define bhnd_bus_read_multi_stream_4(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_read_multi_stream_4((r)->res, (o), (d), (c)) : \
+ BHND_BUS_READ_MULTI_STREAM_4( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
+#define bhnd_bus_write_stream_4(r, o, v) \
+ ((r)->direct) ? \
+ bus_write_stream_4((r)->res, (o), (v)) : \
+ BHND_BUS_WRITE_STREAM_4( \
+ device_get_parent(rman_get_device((r)->res)), \
rman_get_device((r)->res), (r), (o), (v))
+#define bhnd_bus_write_multi_stream_4(r, o, d, c) \
+ ((r)->direct) ? \
+ bus_write_multi_stream_4((r)->res, (o), (d), (c)) : \
+ BHND_BUS_WRITE_MULTI_STREAM_4( \
+ device_get_parent(rman_get_device((r)->res)), \
+ rman_get_device((r)->res), (r), (o), (d), (c))
#endif /* _BHND_BHND_H_ */
diff --git a/sys/dev/bhnd/bhnd_bus_if.m b/sys/dev/bhnd/bhnd_bus_if.m
index 779dd89..9762288 100644
--- a/sys/dev/bhnd/bhnd_bus_if.m
+++ b/sys/dev/bhnd/bhnd_bus_if.m
@@ -55,10 +55,10 @@ CODE {
panic("bhnd_bus_get_chipid unimplemented");
}
- static bool
- bhnd_bus_null_is_hostb_device(device_t dev, device_t child)
+ static device_t
+ bhnd_bus_null_find_hostb_device(device_t dev)
{
- panic("bhnd_bus_is_hostb_device unimplemented");
+ panic("bhnd_bus_find_hostb_device unimplemented");
}
static bool
@@ -96,7 +96,7 @@ CODE {
}
static int
- bhnd_bus_null_read_nvram_var(device_t dev, device_t child,
+ bhnd_bus_null_get_nvram_var(device_t dev, device_t child,
const char *name, void *buf, size_t *size)
{
return (ENOENT);
@@ -105,19 +105,16 @@ CODE {
}
/**
- * Returns true if @p child is serving as a host bridge for the bhnd
- * bus.
+ * Return the active host bridge core for the bhnd bus, if any.
*
- * The default implementation will walk the parent device tree until
- * the root node is hit, returning false.
+ * @param dev The bhnd bus device.
*
- * @param dev The device whose child is being examined.
- * @param child The child device.
+ * @retval device_t if a hostb device exists
+ * @retval NULL if no hostb device is found.
*/
-METHOD bool is_hostb_device {
+METHOD device_t find_hostb_device {
device_t dev;
- device_t child;
-} DEFAULT bhnd_bus_null_is_hostb_device;
+} DEFAULT bhnd_bus_null_find_hostb_device;
/**
* Return true if the hardware components required by @p child are unpopulated
@@ -406,13 +403,13 @@ METHOD int get_region_addr {
* @retval non-zero If reading @p name otherwise fails, a regular unix
* error code will be returned.
*/
-METHOD int read_nvram_var {
+METHOD int get_nvram_var {
device_t dev;
device_t child;
const char *name;
void *buf;
size_t *size;
-} DEFAULT bhnd_bus_null_read_nvram_var;
+} DEFAULT bhnd_bus_null_get_nvram_var;
/** An implementation of bus_read_1() compatible with bhnd_resource */
@@ -466,6 +463,183 @@ METHOD void write_4 {
uint32_t value;
}
+/** An implementation of bus_read_stream_1() compatible with bhnd_resource */
+METHOD uint8_t read_stream_1 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+}
+
+/** An implementation of bus_read_stream_2() compatible with bhnd_resource */
+METHOD uint16_t read_stream_2 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+}
+
+/** An implementation of bus_read_stream_4() compatible with bhnd_resource */
+METHOD uint32_t read_stream_4 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+}
+
+/** An implementation of bus_write_stream_1() compatible with bhnd_resource */
+METHOD void write_stream_1 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint8_t value;
+}
+
+/** An implementation of bus_write_stream_2() compatible with bhnd_resource */
+METHOD void write_stream_2 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint16_t value;
+}
+
+/** An implementation of bus_write_stream_4() compatible with bhnd_resource */
+METHOD void write_stream_4 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint32_t value;
+}
+
+/** An implementation of bus_read_multi_1() compatible with bhnd_resource */
+METHOD void read_multi_1 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint8_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_read_multi_2() compatible with bhnd_resource */
+METHOD void read_multi_2 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint16_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_read_multi_4() compatible with bhnd_resource */
+METHOD void read_multi_4 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint32_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_write_multi_1() compatible with bhnd_resource */
+METHOD void write_multi_1 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint8_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_write_multi_2() compatible with bhnd_resource */
+METHOD void write_multi_2 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint16_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_write_multi_4() compatible with bhnd_resource */
+METHOD void write_multi_4 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint32_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_read_multi_stream_1() compatible
+ * bhnd_resource */
+METHOD void read_multi_stream_1 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint8_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_read_multi_stream_2() compatible
+ * bhnd_resource */
+METHOD void read_multi_stream_2 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint16_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_read_multi_stream_4() compatible
+ * bhnd_resource */
+METHOD void read_multi_stream_4 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint32_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_write_multi_stream_1() compatible
+ * bhnd_resource */
+METHOD void write_multi_stream_1 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint8_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_write_multi_stream_2() compatible with
+ * bhnd_resource */
+METHOD void write_multi_stream_2 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint16_t *datap;
+ bus_size_t count;
+}
+
+/** An implementation of bus_write_multi_stream_4() compatible with
+ * bhnd_resource */
+METHOD void write_multi_stream_4 {
+ device_t dev;
+ device_t child;
+ struct bhnd_resource *r;
+ bus_size_t offset;
+ uint32_t *datap;
+ bus_size_t count;
+}
+
/** An implementation of bus_barrier() compatible with bhnd_resource */
METHOD void barrier {
device_t dev;
diff --git a/sys/dev/bhnd/bhnd_ids.h b/sys/dev/bhnd/bhnd_ids.h
index e28e53b..5000cf7 100644
--- a/sys/dev/bhnd/bhnd_ids.h
+++ b/sys/dev/bhnd/bhnd_ids.h
@@ -328,6 +328,7 @@
#define BHND_CHIPID_BCM43428 43428 /* 43228 chipcommon chipid (OTP, RBBU) */
#define BHND_CHIPID_BCM43431 43431 /* 4331 chipcommon chipid (OTP, RBBU) */
#define BHND_CHIPID_BCM43460 43460 /* 4360 chipcommon chipid (OTP, RBBU) */
+#define BHND_CHIPID_BCM43462 0xA9C6 /* 43462 chipcommon chipid */
#define BHND_CHIPID_BCM4325 0x4325 /* 4325 chip id */
#define BHND_CHIPID_BCM4328 0x4328 /* 4328 chip id */
#define BHND_CHIPID_BCM4329 0x4329 /* 4329 chipcommon chipid */
@@ -345,6 +346,7 @@
#define BHND_CHIPID_BCM4334 0x4334 /* 4334 chipcommon chipid */
#define BHND_CHIPID_BCM4335 0x4335 /* 4335 chipcommon chipid */
#define BHND_CHIPID_BCM4360 0x4360 /* 4360 chipcommon chipid */
+#define BHND_CHIPID_BCM43602 0xaa52 /* 43602 chipcommon chipid */
#define BHND_CHIPID_BCM4352 0x4352 /* 4352 chipcommon chipid */
#define BHND_CHIPID_BCM43526 0xAA06
#define BHND_CHIPID_BCM43341 43341 /* 43341 chipcommon chipid */
@@ -433,7 +435,6 @@
#define BHND_PKGID_BCM4335_FCBGAD (0x3) /* FCBGA Debug Debug/Dev All if's. */
#define BHND_PKGID_PKG_MASK_BCM4335 (0x3)
-
/* Broadcom Core IDs */
#define BHND_COREID_INVALID 0x700 /* Invalid coreid */
#define BHND_COREID_CC 0x800 /* chipcommon core */
diff --git a/sys/dev/bhnd/bhnd_subr.c b/sys/dev/bhnd/bhnd_subr.c
index 1d5557b..ac8fb0d 100644
--- a/sys/dev/bhnd/bhnd_subr.c
+++ b/sys/dev/bhnd/bhnd_subr.c
@@ -184,6 +184,8 @@ bhnd_port_type_name(bhnd_port_type port_type)
return ("bridge");
case BHND_PORT_AGENT:
return ("agent");
+ default:
+ return "unknown";
}
}
@@ -413,10 +415,6 @@ bhnd_core_matches(const struct bhnd_core_info *core,
if (!bhnd_hwrev_matches(core->hwrev, &desc->hwrev))
return (false);
-
- if (desc->hwrev.end != BHND_HWREV_INVALID &&
- desc->hwrev.end < core->hwrev)
- return (false);
if (desc->class != BHND_DEVCLASS_INVALID &&
desc->class != bhnd_core_class(core))
@@ -426,6 +424,32 @@ bhnd_core_matches(const struct bhnd_core_info *core,
}
/**
+ * Return true if the @p chip matches @p desc.
+ *
+ * @param chip A bhnd chip identifier.
+ * @param desc A match descriptor to compare against @p chip.
+ *
+ * @retval true if @p chip matches @p match
+ * @retval false if @p chip does not match @p match.
+ */
+bool
+bhnd_chip_matches(const struct bhnd_chipid *chip,
+ const struct bhnd_chip_match *desc)
+{
+ if (desc->match_id && chip->chip_id != desc->chip_id)
+ return (false);
+
+ if (desc->match_pkg && chip->chip_pkg != desc->chip_pkg)
+ return (false);
+
+ if (desc->match_rev &&
+ !bhnd_hwrev_matches(chip->chip_rev, &desc->chip_rev))
+ return (false);
+
+ return (true);
+}
+
+/**
* Return true if the @p hwrev matches @p desc.
*
* @param hwrev A bhnd hardware revision.
@@ -484,7 +508,11 @@ const struct bhnd_device *
bhnd_device_lookup(device_t dev, const struct bhnd_device *table,
size_t entry_size)
{
- const struct bhnd_device *entry;
+ const struct bhnd_device *entry;
+ device_t hostb, parent;
+
+ parent = device_get_parent(dev);
+ hostb = bhnd_find_hostb_device(parent);
for (entry = table; entry->desc != NULL; entry =
(const struct bhnd_device *) ((const char *) entry + entry_size))
@@ -494,8 +522,8 @@ bhnd_device_lookup(device_t dev, const struct bhnd_device *table,
continue;
/* match device flags */
- if (entry->device_flags & BHND_DF_HOSTB) {
- if (!bhnd_is_hostb_device(dev))
+ if (entry->device_flags & BHND_DF_HOSTB) {
+ if (dev != hostb)
continue;
}
@@ -508,6 +536,33 @@ bhnd_device_lookup(device_t dev, const struct bhnd_device *table,
}
/**
+ * Scan @p table for all quirk flags applicable to @p dev's chip identifier
+ * (as returned by bhnd_get_chipid).
+ *
+ * @param dev A bhnd device.
+ * @param table The chip quirk table to search.
+ *
+ * @return returns all matching quirk flags.
+ */
+uint32_t
+bhnd_chip_quirks(device_t dev, const struct bhnd_chip_quirk *table)
+{
+ const struct bhnd_chipid *cid;
+ const struct bhnd_chip_quirk *qent;
+ uint32_t quirks;
+
+ cid = bhnd_get_chipid(dev);
+ quirks = 0;
+
+ for (qent = table; !BHND_CHIP_QUIRK_IS_END(qent); qent++) {
+ if (bhnd_chip_matches(cid, &qent->chip))
+ quirks |= qent->quirks;
+ }
+
+ return (quirks);
+}
+
+/**
* Scan @p table for all quirk flags applicable to @p dev.
*
* @param dev A bhnd device to match against @p table.
@@ -736,24 +791,6 @@ bhnd_set_default_core_desc(device_t dev)
}
/**
- * Helper function for implementing BHND_BUS_IS_HOSTB_DEVICE().
- *
- * If a parent device is available, this implementation delegates the
- * request to the BHND_BUS_IS_HOSTB_DEVICE() method on the parent of @p dev.
- *
- * If no parent device is available (i.e. on a the bus root), false
- * is returned.
- */
-bool
-bhnd_bus_generic_is_hostb_device(device_t dev, device_t child) {
- if (device_get_parent(dev) != NULL)
- return (BHND_BUS_IS_HOSTB_DEVICE(device_get_parent(dev),
- child));
-
- return (false);
-}
-
-/**
* Helper function for implementing BHND_BUS_IS_HW_DISABLED().
*
* If a parent device is available, this implementation delegates the
diff --git a/sys/dev/bhnd/bhndb/bhndb.c b/sys/dev/bhnd/bhndb/bhndb.c
index 3deae00..b75c04a 100644
--- a/sys/dev/bhnd/bhndb/bhndb.c
+++ b/sys/dev/bhnd/bhndb/bhndb.c
@@ -51,6 +51,10 @@ __FBSDID("$FreeBSD$");
#include <dev/bhnd/bhndreg.h>
#include <dev/bhnd/cores/chipc/chipcreg.h>
+#include <dev/bhnd/nvram/bhnd_nvram.h>
+
+#include "bhnd_chipc_if.h"
+#include "bhnd_nvram_if.h"
#include "bhndbvar.h"
#include "bhndb_bus_if.h"
@@ -259,9 +263,9 @@ bhndb_initialize_region_cfg(struct bhndb_softc *sc, device_t *devs, int ndevs,
continue;
/* Fetch the base address of the mapped port. */
- error = bhnd_get_region_addr(child,
- regw->core.port_type, regw->core.port,
- regw->core.region, &addr, &size);
+ error = bhnd_get_region_addr(child,
+ regw->d.core.port_type, regw->d.core.port,
+ regw->d.core.region, &addr, &size);
if (error)
return (error);
@@ -536,8 +540,7 @@ bhndb_attach(device_t dev, bhnd_devclass_t bridge_devclass)
}
/* Attach our bridged bus device */
- sc->bus_dev = BUS_ADD_CHILD(dev, 0, devclass_get_name(bhnd_devclass),
- -1);
+ sc->bus_dev = BUS_ADD_CHILD(dev, 0, "bhnd", -1);
if (sc->bus_dev == NULL) {
error = ENXIO;
goto failed;
@@ -590,18 +593,12 @@ bhndb_generic_init_full_config(device_t dev, device_t child,
sc = device_get_softc(dev);
hostb = NULL;
- /* Fetch the full set of attached devices */
+ /* Fetch the full set of bhnd-attached cores */
if ((error = device_get_children(sc->bus_dev, &devs, &ndevs)))
return (error);
/* Find our host bridge device */
- for (int i = 0; i < ndevs; i++) {
- if (bhnd_is_hostb_device(devs[i])) {
- hostb = devs[i];
- break;
- }
- }
-
+ hostb = BHNDB_FIND_HOSTB_DEVICE(dev, child);
if (hostb == NULL) {
device_printf(sc->dev, "no host bridge core found\n");
error = ENODEV;
@@ -616,7 +613,7 @@ bhndb_generic_init_full_config(device_t dev, device_t child,
goto cleanup;
}
- if (bootverbose)
+ if (bootverbose || BHNDB_DEBUG(PRIO))
device_printf(sc->dev, "%s resource configuration\n", hw->name);
/* Release existing resource state */
@@ -868,6 +865,9 @@ bhndb_get_rman(struct bhndb_softc *sc, device_t child, int type)
return (NULL);
};
}
+
+ /* Quieten gcc */
+ return (NULL);
}
/**
@@ -948,13 +948,13 @@ bhndb_is_hw_disabled(device_t dev, device_t child) {
/* Otherwise, we treat bridge-capable cores as unpopulated if they're
* not the configured host bridge */
if (BHND_DEVCLASS_SUPPORTS_HOSTB(bhnd_core_class(&core)))
- return (!BHND_BUS_IS_HOSTB_DEVICE(dev, child));
+ return (BHNDB_FIND_HOSTB_DEVICE(dev, sc->bus_dev) != child);
/* Otherwise, assume the core is populated */
return (false);
}
-/* ascending core index comparison used by bhndb_is_hostb_device() */
+/* ascending core index comparison used by bhndb_find_hostb_device() */
static int
compare_core_index(const void *lhs, const void *rhs)
{
@@ -970,7 +970,7 @@ compare_core_index(const void *lhs, const void *rhs)
}
/**
- * Default bhndb(4) implementation of BHND_BUS_IS_HOSTB_DEVICE().
+ * Default bhndb(4) implementation of BHND_BUS_FIND_HOSTB_DEVICE().
*
* This function uses a heuristic valid on all known PCI/PCIe/PCMCIA-bridged
* bhnd(4) devices to determine the hostb core:
@@ -980,27 +980,19 @@ compare_core_index(const void *lhs, const void *rhs)
* - The core must be the first device on the bus with the bridged device
* class.
*
- * @param sc The bridge device state.
- * @param cores The table of bridge-enumerated cores.
- * @param num_cores The length of @p cores.
- * @param core The core to check.
+ * @param dev The bhndb device
+ * @param child The requesting bhnd bus.
*/
-static bool
-bhndb_is_hostb_device(device_t dev, device_t child)
+static device_t
+bhndb_find_hostb_device(device_t dev, device_t child)
{
struct bhndb_softc *sc;
struct bhnd_core_match md;
device_t hostb_dev, *devlist;
int devcnt, error;
-
sc = device_get_softc(dev);
- /* Requestor must be attached to the bhnd bus */
- if (device_get_parent(child) != sc->bus_dev)
- return (BHND_BUS_IS_HOSTB_DEVICE(device_get_parent(dev),
- child));
-
/* Determine required device class and set up a match descriptor. */
md = (struct bhnd_core_match) {
.vendor = BHND_MFGID_BCM,
@@ -1009,19 +1001,15 @@ bhndb_is_hostb_device(device_t dev, device_t child)
.class = sc->bridge_class,
.unit = 0
};
-
- /* Pre-screen the device before searching over the full device list. */
- if (!bhnd_device_matches(child, &md))
- return (false);
/* Must be the absolute first matching device on the bus. */
- if ((error = device_get_children(sc->bus_dev, &devlist, &devcnt)))
+ if ((error = device_get_children(child, &devlist, &devcnt)))
return (false);
/* Sort by core index value, ascending */
qsort(devlist, devcnt, sizeof(*devlist), compare_core_index);
- /* Find the actual hostb device */
+ /* Find the hostb device */
hostb_dev = NULL;
for (int i = 0; i < devcnt; i++) {
if (bhnd_device_matches(devlist[i], &md)) {
@@ -1033,7 +1021,7 @@ bhndb_is_hostb_device(device_t dev, device_t child)
/* Clean up */
free(devlist, M_TEMP);
- return (child == hostb_dev);
+ return (hostb_dev);
}
/**
@@ -1314,9 +1302,10 @@ bhndb_retain_dynamic_window(struct bhndb_softc *sc, struct resource *r)
rman_get_size(r));
if (error) {
device_printf(sc->dev, "dynamic window initialization "
- "for 0x%llx-0x%llx failed\n",
+ "for 0x%llx-0x%llx failed: %d\n",
(unsigned long long) r_start,
- (unsigned long long) r_start + r_size - 1);
+ (unsigned long long) r_start + r_size - 1,
+ error);
return (NULL);
}
@@ -1725,6 +1714,26 @@ bhndb_io_resource(struct bhndb_softc *sc, bus_addr_t addr, bus_size_t size,
return (dwa);
}
+/**
+ * Default bhndb(4) implementation of BHND_BUS_GET_NVRAM_VAR().
+ */
+static int
+bhndb_get_nvram_var(device_t dev, device_t child, const char *name,
+ void *buf, size_t *size)
+{
+ device_t nvram;
+
+ /* Look for a directly-attached NVRAM child */
+ nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass),
+ 0);
+ if (nvram != NULL)
+ return (BHND_NVRAM_GETVAR(nvram, name, buf, size));
+
+ /* Otherwise, delegate to our parent */
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
+ name, buf, size));
+}
+
/*
* BHND_BUS_(READ|WRITE_* implementations
*/
@@ -1753,37 +1762,60 @@ bhndb_io_resource(struct bhndb_softc *sc, bus_addr_t addr, bus_size_t size,
BHNDB_UNLOCK(sc);
/* Defines a bhndb_bus_read_* method implementation */
-#define BHNDB_IO_READ(_type, _size) \
+#define BHNDB_IO_READ(_type, _name) \
static _type \
-bhndb_bus_read_ ## _size (device_t dev, device_t child, \
+bhndb_bus_read_ ## _name (device_t dev, device_t child, \
struct bhnd_resource *r, bus_size_t offset) \
{ \
_type v; \
BHNDB_IO_COMMON_SETUP(sizeof(_type)); \
- v = bus_read_ ## _size (io_res, io_offset); \
+ v = bus_read_ ## _name (io_res, io_offset); \
BHNDB_IO_COMMON_TEARDOWN(); \
\
return (v); \
}
/* Defines a bhndb_bus_write_* method implementation */
-#define BHNDB_IO_WRITE(_type, _size) \
+#define BHNDB_IO_WRITE(_type, _name) \
static void \
-bhndb_bus_write_ ## _size (device_t dev, device_t child, \
+bhndb_bus_write_ ## _name (device_t dev, device_t child, \
struct bhnd_resource *r, bus_size_t offset, _type value) \
{ \
BHNDB_IO_COMMON_SETUP(sizeof(_type)); \
- bus_write_ ## _size (io_res, io_offset, value); \
+ bus_write_ ## _name (io_res, io_offset, value); \
BHNDB_IO_COMMON_TEARDOWN(); \
}
-BHNDB_IO_READ(uint8_t, 1);
-BHNDB_IO_READ(uint16_t, 2);
-BHNDB_IO_READ(uint32_t, 4);
+/* Defines a bhndb_bus_(read|write)_multi_* method implementation */
+#define BHNDB_IO_MULTI(_type, _rw, _name) \
+static void \
+bhndb_bus_ ## _rw ## _multi_ ## _name (device_t dev, \
+ device_t child, struct bhnd_resource *r, bus_size_t offset, \
+ _type *datap, bus_size_t count) \
+{ \
+ BHNDB_IO_COMMON_SETUP(sizeof(_type) * count); \
+ bus_ ## _rw ## _multi_ ## _name (io_res, io_offset, \
+ datap, count); \
+ BHNDB_IO_COMMON_TEARDOWN(); \
+}
+
+/* Defines a complete set of read/write methods */
+#define BHNDB_IO_METHODS(_type, _size) \
+ BHNDB_IO_READ(_type, _size) \
+ BHNDB_IO_WRITE(_type, _size) \
+ \
+ BHNDB_IO_READ(_type, stream_ ## _size) \
+ BHNDB_IO_WRITE(_type, stream_ ## _size) \
+ \
+ BHNDB_IO_MULTI(_type, read, _size) \
+ BHNDB_IO_MULTI(_type, write, _size) \
+ \
+ BHNDB_IO_MULTI(_type, read, stream_ ## _size) \
+ BHNDB_IO_MULTI(_type, write, stream_ ## _size)
-BHNDB_IO_WRITE(uint8_t, 1);
-BHNDB_IO_WRITE(uint16_t, 2);
-BHNDB_IO_WRITE(uint32_t, 4);
+BHNDB_IO_METHODS(uint8_t, 1);
+BHNDB_IO_METHODS(uint16_t, 2);
+BHNDB_IO_METHODS(uint32_t, 4);
/**
* Default bhndb(4) implementation of BHND_BUS_BARRIER().
@@ -1920,21 +1952,44 @@ static device_method_t bhndb_methods[] = {
/* BHNDB interface */
DEVMETHOD(bhndb_get_chipid, bhndb_get_chipid),
DEVMETHOD(bhndb_init_full_config, bhndb_generic_init_full_config),
+ DEVMETHOD(bhndb_find_hostb_device, bhndb_find_hostb_device),
DEVMETHOD(bhndb_suspend_resource, bhndb_suspend_resource),
DEVMETHOD(bhndb_resume_resource, bhndb_resume_resource),
/* BHND interface */
DEVMETHOD(bhnd_bus_is_hw_disabled, bhndb_is_hw_disabled),
- DEVMETHOD(bhnd_bus_is_hostb_device, bhndb_is_hostb_device),
DEVMETHOD(bhnd_bus_get_chipid, bhndb_get_chipid),
DEVMETHOD(bhnd_bus_activate_resource, bhndb_activate_bhnd_resource),
DEVMETHOD(bhnd_bus_deactivate_resource, bhndb_deactivate_bhnd_resource),
+ DEVMETHOD(bhnd_bus_get_nvram_var, bhndb_get_nvram_var),
DEVMETHOD(bhnd_bus_read_1, bhndb_bus_read_1),
DEVMETHOD(bhnd_bus_read_2, bhndb_bus_read_2),
DEVMETHOD(bhnd_bus_read_4, bhndb_bus_read_4),
DEVMETHOD(bhnd_bus_write_1, bhndb_bus_write_1),
DEVMETHOD(bhnd_bus_write_2, bhndb_bus_write_2),
DEVMETHOD(bhnd_bus_write_4, bhndb_bus_write_4),
+
+ DEVMETHOD(bhnd_bus_read_stream_1, bhndb_bus_read_stream_1),
+ DEVMETHOD(bhnd_bus_read_stream_2, bhndb_bus_read_stream_2),
+ DEVMETHOD(bhnd_bus_read_stream_4, bhndb_bus_read_stream_4),
+ DEVMETHOD(bhnd_bus_write_stream_1, bhndb_bus_write_stream_1),
+ DEVMETHOD(bhnd_bus_write_stream_2, bhndb_bus_write_stream_2),
+ DEVMETHOD(bhnd_bus_write_stream_4, bhndb_bus_write_stream_4),
+
+ DEVMETHOD(bhnd_bus_read_multi_1, bhndb_bus_read_multi_1),
+ DEVMETHOD(bhnd_bus_read_multi_2, bhndb_bus_read_multi_2),
+ DEVMETHOD(bhnd_bus_read_multi_4, bhndb_bus_read_multi_4),
+ DEVMETHOD(bhnd_bus_write_multi_1, bhndb_bus_write_multi_1),
+ DEVMETHOD(bhnd_bus_write_multi_2, bhndb_bus_write_multi_2),
+ DEVMETHOD(bhnd_bus_write_multi_4, bhndb_bus_write_multi_4),
+
+ DEVMETHOD(bhnd_bus_read_multi_stream_1, bhndb_bus_read_multi_stream_1),
+ DEVMETHOD(bhnd_bus_read_multi_stream_2, bhndb_bus_read_multi_stream_2),
+ DEVMETHOD(bhnd_bus_read_multi_stream_4, bhndb_bus_read_multi_stream_4),
+ DEVMETHOD(bhnd_bus_write_multi_stream_1,bhndb_bus_write_multi_stream_1),
+ DEVMETHOD(bhnd_bus_write_multi_stream_2,bhndb_bus_write_multi_stream_2),
+ DEVMETHOD(bhnd_bus_write_multi_stream_4,bhndb_bus_write_multi_stream_4),
+
DEVMETHOD(bhnd_bus_barrier, bhndb_bus_barrier),
DEVMETHOD_END
diff --git a/sys/dev/bhnd/bhndb/bhndb.h b/sys/dev/bhnd/bhndb/bhndb.h
index 7ece8ae..366f119 100644
--- a/sys/dev/bhnd/bhndb/bhndb.h
+++ b/sys/dev/bhnd/bhndb/bhndb.h
@@ -98,7 +98,7 @@ struct bhndb_regwin {
struct {
bus_size_t cfg_offset; /**< window address config offset. */
} dyn;
- };
+ } d;
};
#define BHNDB_REGWIN_TABLE_END { BHNDB_REGWIN_T_INVALID, 0, 0, { 0, 0 } }
@@ -170,4 +170,4 @@ struct bhndb_hw_priority {
#define BHNDB_HW_PRIORITY_TABLE_END { {}, BHNDB_PRIORITY_NONE, NULL, 0 }
-#endif /* _BHND_BHNDB_H_ */ \ No newline at end of file
+#endif /* _BHND_BHNDB_H_ */
diff --git a/sys/dev/bhnd/bhndb/bhndb_if.m b/sys/dev/bhnd/bhndb/bhndb_if.m
index 110925b..ce13a9e 100644
--- a/sys/dev/bhnd/bhndb/bhndb_if.m
+++ b/sys/dev/bhnd/bhndb/bhndb_if.m
@@ -62,6 +62,12 @@ CODE {
panic("bhndb_init_full_config unimplemented");
}
+ static device_t
+ bhndb_null_find_hostb_device(device_t dev, device_t child)
+ {
+ panic("bhndb_find_hostb_device unimplemented");
+ }
+
static void
bhndb_null_suspend_resource(device_t dev, device_t child, int type,
struct resource *r)
@@ -120,6 +126,17 @@ METHOD int init_full_config {
} DEFAULT bhndb_null_init_full_config;
/**
+ * Locate the active host bridge core for the attached bhnd bus.
+ *
+ * @param dev The bridge device.
+ * @param child The bhnd bus device attached to @p dev.
+ */
+METHOD device_t find_hostb_device {
+ device_t dev;
+ device_t child;
+} DEFAULT bhndb_null_find_hostb_device;
+
+/**
* Mark a resource as 'suspended', gauranteeing to the bridge that no
* further use of the resource will be made until BHNDB_RESUME_RESOURCE()
* is called.
diff --git a/sys/dev/bhnd/bhndb/bhndb_pci.c b/sys/dev/bhnd/bhndb/bhndb_pci.c
index d8fc379..baf28473 100644
--- a/sys/dev/bhnd/bhndb/bhndb_pci.c
+++ b/sys/dev/bhnd/bhndb/bhndb_pci.c
@@ -61,15 +61,19 @@ __FBSDID("$FreeBSD$");
#include "bhndb_pcivar.h"
#include "bhndb_private.h"
-static int bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc);
-static int bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc);
+static int bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc);
+static int bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc);
-static int bhndb_pci_compat_setregwin(struct bhndb_pci_softc *,
- const struct bhndb_regwin *, bhnd_addr_t);
-static int bhndb_pci_fast_setregwin(struct bhndb_pci_softc *,
- const struct bhndb_regwin *, bhnd_addr_t);
+static int bhndb_pci_compat_setregwin(struct bhndb_pci_softc *,
+ const struct bhndb_regwin *, bhnd_addr_t);
+static int bhndb_pci_fast_setregwin(struct bhndb_pci_softc *,
+ const struct bhndb_regwin *, bhnd_addr_t);
-static void bhndb_init_sromless_pci_config(struct bhndb_pci_softc *sc);
+static void bhndb_init_sromless_pci_config(
+ struct bhndb_pci_softc *sc);
+
+static bus_addr_t bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc);
+static bus_size_t bhndb_pci_sprom_size(struct bhndb_pci_softc *sc);
/**
* Default bhndb_pci implementation of device_probe().
@@ -104,13 +108,14 @@ bhndb_pci_attach(device_t dev)
sc = device_get_softc(dev);
sc->dev = dev;
+ sc->parent = device_get_parent(dev);
/* Enable PCI bus mastering */
- pci_enable_busmaster(device_get_parent(dev));
+ pci_enable_busmaster(sc->parent);
/* Determine our bridge device class */
sc->pci_devclass = BHND_DEVCLASS_PCI;
- if (pci_find_cap(device_get_parent(dev), PCIY_EXPRESS, &reg) == 0)
+ if (pci_find_cap(sc->parent, PCIY_EXPRESS, &reg) == 0)
sc->pci_devclass = BHND_DEVCLASS_PCIE;
/* Enable clocks (if supported by this hardware) */
@@ -142,6 +147,8 @@ bhndb_pci_init_full_config(device_t dev, device_t child,
const struct bhndb_hw_priority *hw_prio_table)
{
struct bhndb_pci_softc *sc;
+ device_t nv_dev;
+ bus_size_t nv_sz;
int error;
sc = device_get_softc(dev);
@@ -153,9 +160,127 @@ bhndb_pci_init_full_config(device_t dev, device_t child,
/* Fix-up power on defaults for SROM-less devices. */
bhndb_init_sromless_pci_config(sc);
+ /* If SPROM is mapped directly into BAR0, add NVRAM device. */
+ nv_sz = bhndb_pci_sprom_size(sc);
+ if (nv_sz > 0) {
+ struct bhndb_devinfo *dinfo;
+ const char *dname;
+
+ if (bootverbose) {
+ device_printf(dev, "found SPROM (%u bytes)\n",
+ (unsigned int) nv_sz);
+ }
+
+ /* Add sprom device */
+ dname = "bhnd_nvram";
+ if ((nv_dev = BUS_ADD_CHILD(dev, 0, dname, -1)) == NULL) {
+ device_printf(dev, "failed to add sprom device\n");
+ return (ENXIO);
+ }
+
+ /* Initialize device address space and resource covering the
+ * BAR0 SPROM shadow. */
+ dinfo = device_get_ivars(nv_dev);
+ dinfo->addrspace = BHNDB_ADDRSPACE_NATIVE;
+ error = bus_set_resource(nv_dev, SYS_RES_MEMORY, 0,
+ bhndb_pci_sprom_addr(sc), nv_sz);
+
+ if (error) {
+ device_printf(dev,
+ "failed to register sprom resources\n");
+ return (error);
+ }
+
+ /* Attach the device */
+ if ((error = device_probe_and_attach(nv_dev))) {
+ device_printf(dev, "sprom attach failed\n");
+ return (error);
+ }
+ }
+
return (0);
}
+static const struct bhndb_regwin *
+bhndb_pci_sprom_regwin(struct bhndb_pci_softc *sc)
+{
+ struct bhndb_resources *bres;
+ const struct bhndb_hwcfg *cfg;
+ const struct bhndb_regwin *sprom_win;
+
+ bres = sc->bhndb.bus_res;
+ cfg = bres->cfg;
+
+ sprom_win = bhndb_regwin_find_type(cfg->register_windows,
+ BHNDB_REGWIN_T_SPROM, BHNDB_PCI_V0_BAR0_SPROM_SIZE);
+
+ return (sprom_win);
+}
+
+static bus_addr_t
+bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc)
+{
+ const struct bhndb_regwin *sprom_win;
+ struct resource *r;
+
+ /* Fetch the SPROM register window */
+ sprom_win = bhndb_pci_sprom_regwin(sc);
+ KASSERT(sprom_win != NULL, ("requested sprom address on PCI_V2+"));
+
+ /* Fetch the associated resource */
+ r = bhndb_find_regwin_resource(sc->bhndb.bus_res, sprom_win);
+ KASSERT(r != NULL, ("missing resource for sprom window\n"));
+
+ return (rman_get_start(r) + sprom_win->win_offset);
+}
+
+static bus_size_t
+bhndb_pci_sprom_size(struct bhndb_pci_softc *sc)
+{
+ const struct bhndb_regwin *sprom_win;
+ uint32_t sctl;
+ bus_size_t sprom_sz;
+
+ sprom_win = bhndb_pci_sprom_regwin(sc);
+
+ /* PCI_V2 and later devices map SPROM/OTP via ChipCommon */
+ if (sprom_win == NULL)
+ return (0);
+
+ /* Determine SPROM size */
+ sctl = pci_read_config(sc->parent, BHNDB_PCI_SPROM_CONTROL, 4);
+ if (sctl & BHNDB_PCI_SPROM_BLANK)
+ return (0);
+
+ switch (sctl & BHNDB_PCI_SPROM_SZ_MASK) {
+ case BHNDB_PCI_SPROM_SZ_1KB:
+ sprom_sz = (1 * 1024);
+ break;
+
+ case BHNDB_PCI_SPROM_SZ_4KB:
+ sprom_sz = (4 * 1024);
+ break;
+
+ case BHNDB_PCI_SPROM_SZ_16KB:
+ sprom_sz = (16 * 1024);
+ break;
+
+ case BHNDB_PCI_SPROM_SZ_RESERVED:
+ default:
+ device_printf(sc->dev, "invalid PCI sprom size 0x%x\n", sctl);
+ return (0);
+ }
+
+ if (sprom_sz > sprom_win->win_size) {
+ device_printf(sc->dev,
+ "PCI sprom size (0x%x) overruns defined register window\n",
+ sctl);
+ return (0);
+ }
+
+ return (sprom_sz);
+}
+
/*
* On devices without a SROM, the PCI(e) cores will be initialized with
* their Power-on-Reset defaults; this can leave two of the BAR0 PCI windows
@@ -274,7 +399,7 @@ bhndb_pci_detach(device_t dev)
return (error);
/* Disable PCI bus mastering */
- pci_disable_busmaster(device_get_parent(dev));
+ pci_disable_busmaster(sc->parent);
return (0);
}
@@ -301,19 +426,18 @@ static int
bhndb_pci_compat_setregwin(struct bhndb_pci_softc *sc,
const struct bhndb_regwin *rw, bhnd_addr_t addr)
{
- device_t parent;
int error;
-
- parent = sc->bhndb.parent_dev;
+ int reg;
if (rw->win_type != BHNDB_REGWIN_T_DYN)
return (ENODEV);
+ reg = rw->d.dyn.cfg_offset;
for (u_int i = 0; i < BHNDB_PCI_BARCTRL_WRITE_RETRY; i++) {
if ((error = bhndb_pci_fast_setregwin(sc, rw, addr)))
return (error);
- if (pci_read_config(parent, rw->dyn.cfg_offset, 4) == addr)
+ if (pci_read_config(sc->parent, reg, 4) == addr)
return (0);
DELAY(10);
@@ -330,8 +454,6 @@ static int
bhndb_pci_fast_setregwin(struct bhndb_pci_softc *sc,
const struct bhndb_regwin *rw, bhnd_addr_t addr)
{
- device_t parent = sc->bhndb.parent_dev;
-
/* The PCI bridge core only supports 32-bit addressing, regardless
* of the bus' support for 64-bit addressing */
if (addr > UINT32_MAX)
@@ -343,7 +465,7 @@ bhndb_pci_fast_setregwin(struct bhndb_pci_softc *sc,
if (addr % rw->win_size != 0)
return (EINVAL);
- pci_write_config(parent, rw->dyn.cfg_offset, addr, 4);
+ pci_write_config(sc->parent, rw->d.dyn.cfg_offset, addr, 4);
break;
default:
return (ENODEV);
@@ -366,7 +488,6 @@ bhndb_pci_fast_setregwin(struct bhndb_pci_softc *sc,
static int
bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc)
{
- device_t pci_parent;
uint32_t gpio_in, gpio_out, gpio_en;
uint32_t gpio_flags;
uint16_t pci_status;
@@ -375,35 +496,33 @@ bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc)
if (sc->pci_devclass != BHND_DEVCLASS_PCI)
return (0);
- pci_parent = device_get_parent(sc->dev);
-
/* Read state of XTAL pin */
- gpio_in = pci_read_config(pci_parent, BHNDB_PCI_GPIO_IN, 4);
+ gpio_in = pci_read_config(sc->parent, BHNDB_PCI_GPIO_IN, 4);
if (gpio_in & BHNDB_PCI_GPIO_XTAL_ON)
return (0); /* already enabled */
/* Fetch current config */
- gpio_out = pci_read_config(pci_parent, BHNDB_PCI_GPIO_OUT, 4);
- gpio_en = pci_read_config(pci_parent, BHNDB_PCI_GPIO_OUTEN, 4);
+ gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4);
+ gpio_en = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, 4);
/* Set PLL_OFF/XTAL_ON pins to HIGH and enable both pins */
gpio_flags = (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
gpio_out |= gpio_flags;
gpio_en |= gpio_flags;
- pci_write_config(pci_parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
- pci_write_config(pci_parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
DELAY(1000);
/* Reset PLL_OFF */
gpio_out &= ~BHNDB_PCI_GPIO_PLL_OFF;
- pci_write_config(pci_parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
DELAY(5000);
/* Clear any PCI 'sent target-abort' flag. */
- pci_status = pci_read_config(pci_parent, PCIR_STATUS, 2);
+ pci_status = pci_read_config(sc->parent, PCIR_STATUS, 2);
pci_status &= ~PCIM_STATUS_STABORT;
- pci_write_config(pci_parent, PCIR_STATUS, pci_status, 2);
+ pci_write_config(sc->parent, PCIR_STATUS, pci_status, 2);
return (0);
}
@@ -416,31 +535,28 @@ bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc)
static int
bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc)
{
- device_t parent_dev;
uint32_t gpio_out, gpio_en;
/* Only supported and required on PCI devices */
if (sc->pci_devclass != BHND_DEVCLASS_PCI)
return (0);
- parent_dev = device_get_parent(sc->dev);
-
// TODO: Check board flags for BFL2_XTALBUFOUTEN?
// TODO: Check PCI core revision?
// TODO: Switch to 'slow' clock?
/* Fetch current config */
- gpio_out = pci_read_config(parent_dev, BHNDB_PCI_GPIO_OUT, 4);
- gpio_en = pci_read_config(parent_dev, BHNDB_PCI_GPIO_OUTEN, 4);
+ gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4);
+ gpio_en = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, 4);
/* Set PLL_OFF to HIGH, XTAL_ON to LOW. */
gpio_out &= ~BHNDB_PCI_GPIO_XTAL_ON;
gpio_out |= BHNDB_PCI_GPIO_PLL_OFF;
- pci_write_config(parent_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
/* Enable both output pins */
gpio_en |= (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
- pci_write_config(parent_dev, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
return (0);
}
@@ -464,6 +580,7 @@ DEFINE_CLASS_1(bhndb, bhndb_pci_driver, bhndb_pci_methods,
sizeof(struct bhndb_pci_softc), bhndb_driver);
MODULE_VERSION(bhndb_pci, 1);
-MODULE_DEPEND(bhndb_pci, bhnd_pci, 1, 1, 1);
+MODULE_DEPEND(bhndb_pci, bhnd_pci_hostb, 1, 1, 1);
MODULE_DEPEND(bhndb_pci, pci, 1, 1, 1);
MODULE_DEPEND(bhndb_pci, bhndb, 1, 1, 1);
+MODULE_DEPEND(bhndb_pci, bhnd, 1, 1, 1);
diff --git a/sys/dev/bhnd/bhndb/bhndb_pci_hwdata.c b/sys/dev/bhnd/bhndb/bhndb_pci_hwdata.c
index 0ebb2cb..b2cc58e 100644
--- a/sys/dev/bhnd/bhndb/bhndb_pci_hwdata.c
+++ b/sys/dev/bhnd/bhndb/bhndb_pci_hwdata.c
@@ -93,7 +93,9 @@ const struct bhndb_hwcfg bhndb_pci_siba_generic_hwcfg = {
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V1_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
+ .d.dyn = {
+ .cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL
+ },
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
BHNDB_REGWIN_TABLE_END
@@ -122,7 +124,9 @@ const struct bhndb_hwcfg bhndb_pci_bcma_generic_hwcfg = {
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V1_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
+ .d.dyn = {
+ .cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
+ },
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -131,7 +135,7 @@ const struct bhndb_hwcfg bhndb_pci_bcma_generic_hwcfg = {
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V1_BAR0_CCREGS_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_CCREGS_SIZE,
- .core = {
+ .d.core = {
.class = BHND_DEVCLASS_CC,
.unit = 0,
.port = 0,
@@ -327,7 +331,9 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v0 = {
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V0_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V0_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V0_BAR0_WIN0_CONTROL,
+ .d.dyn = {
+ .cfg_offset = BHNDB_PCI_V0_BAR0_WIN0_CONTROL
+ },
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -344,7 +350,7 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v0 = {
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V0_BAR0_PCIREG_OFFSET,
.win_size = BHNDB_PCI_V0_BAR0_PCIREG_SIZE,
- .core = {
+ .d.core = {
.class = BHND_DEVCLASS_PCI,
.unit = 0,
.port = 0,
@@ -375,7 +381,9 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v1_pci = {
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V1_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
+ .d.dyn = {
+ .cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL
+ },
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -392,7 +400,7 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v1_pci = {
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V1_BAR0_PCIREG_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_PCIREG_SIZE,
- .core = {
+ .d.core = {
.class = BHND_DEVCLASS_PCI,
.unit = 0,
.port = 0,
@@ -407,7 +415,7 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v1_pci = {
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V1_BAR0_CCREGS_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_CCREGS_SIZE,
- .core = {
+ .d.core = {
.class = BHND_DEVCLASS_CC,
.unit = 0,
.port = 0,
@@ -439,7 +447,9 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v1_pcie = {
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V1_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL,
+ .d.dyn = {
+ .cfg_offset = BHNDB_PCI_V1_BAR0_WIN0_CONTROL
+ },
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -456,7 +466,7 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v1_pcie = {
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V1_BAR0_PCIREG_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_PCIREG_SIZE,
- .core = {
+ .d.core = {
.class = BHND_DEVCLASS_PCIE,
.unit = 0,
.port = 0,
@@ -471,7 +481,7 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v1_pcie = {
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V1_BAR0_CCREGS_OFFSET,
.win_size = BHNDB_PCI_V1_BAR0_CCREGS_SIZE,
- .core = {
+ .d.core = {
.class = BHND_DEVCLASS_CC,
.unit = 0,
.port = 0,
@@ -503,7 +513,9 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v2 = {
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V2_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V2_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V2_BAR0_WIN0_CONTROL,
+ .d.dyn = {
+ .cfg_offset = BHNDB_PCI_V2_BAR0_WIN0_CONTROL,
+ },
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -512,7 +524,9 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v2 = {
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V2_BAR0_WIN1_OFFSET,
.win_size = BHNDB_PCI_V2_BAR0_WIN1_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V2_BAR0_WIN1_CONTROL,
+ .d.dyn = {
+ .cfg_offset = BHNDB_PCI_V2_BAR0_WIN1_CONTROL,
+ },
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -521,7 +535,7 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v2 = {
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V2_BAR0_PCIREG_OFFSET,
.win_size = BHNDB_PCI_V2_BAR0_PCIREG_SIZE,
- .core = {
+ .d.core = {
.class = BHND_DEVCLASS_PCIE,
.unit = 0,
.port = 0,
@@ -536,7 +550,7 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v2 = {
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V2_BAR0_CCREGS_OFFSET,
.win_size = BHNDB_PCI_V2_BAR0_CCREGS_SIZE,
- .core = {
+ .d.core = {
.class = BHND_DEVCLASS_CC,
.unit = 0,
.port = 0,
@@ -568,7 +582,9 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v3 = {
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V3_BAR0_WIN0_OFFSET,
.win_size = BHNDB_PCI_V3_BAR0_WIN0_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V3_BAR0_WIN0_CONTROL,
+ .d.dyn = {
+ .cfg_offset = BHNDB_PCI_V3_BAR0_WIN0_CONTROL,
+ },
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -577,7 +593,9 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v3 = {
.win_type = BHNDB_REGWIN_T_DYN,
.win_offset = BHNDB_PCI_V3_BAR0_WIN1_OFFSET,
.win_size = BHNDB_PCI_V3_BAR0_WIN1_SIZE,
- .dyn.cfg_offset = BHNDB_PCI_V3_BAR0_WIN1_CONTROL,
+ .d.dyn = {
+ .cfg_offset = BHNDB_PCI_V3_BAR0_WIN1_CONTROL,
+ },
.res = { SYS_RES_MEMORY, PCIR_BAR(0) }
},
@@ -586,7 +604,7 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v3 = {
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V3_BAR0_PCIREG_OFFSET,
.win_size = BHNDB_PCI_V3_BAR0_PCIREG_SIZE,
- .core = {
+ .d.core = {
.class = BHND_DEVCLASS_PCIE,
.unit = 0,
.port = 0,
@@ -601,7 +619,7 @@ static const struct bhndb_hwcfg bhndb_pci_hwcfg_v3 = {
.win_type = BHNDB_REGWIN_T_CORE,
.win_offset = BHNDB_PCI_V3_BAR0_CCREGS_OFFSET,
.win_size = BHNDB_PCI_V3_BAR0_CCREGS_SIZE,
- .core = {
+ .d.core = {
.class = BHND_DEVCLASS_CC,
.unit = 0,
.port = 0,
diff --git a/sys/dev/bhnd/bhndb/bhndb_pci_sprom.c b/sys/dev/bhnd/bhndb/bhndb_pci_sprom.c
new file mode 100644
index 0000000..8f0ea56
--- /dev/null
+++ b/sys/dev/bhnd/bhndb/bhndb_pci_sprom.c
@@ -0,0 +1,210 @@
+/*-
+ * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * BHNDB PCI SPROM driver.
+ *
+ * Provides support for early PCI bridge cores that vend SPROM CSRs
+ * via PCI configuration space.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/limits.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/bhnd/bhnd.h>
+#include <dev/bhnd/cores/pci/bhnd_pci_hostbvar.h>
+#include <dev/bhnd/nvram/bhnd_spromvar.h>
+
+#include "bhnd_nvram_if.h"
+#include "bhndb_pcireg.h"
+#include "bhndb_pcivar.h"
+
+struct bhndb_pci_sprom_softc {
+ device_t dev;
+ struct bhnd_resource *sprom_res; /**< SPROM resource */
+ int sprom_rid; /**< SPROM RID */
+ struct bhnd_sprom shadow; /**< SPROM shadow */
+ struct mtx mtx; /**< SPROM shadow mutex */
+};
+
+#define SPROM_LOCK_INIT(sc) \
+ mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
+ "BHND PCI SPROM lock", MTX_DEF)
+#define SPROM_LOCK(sc) mtx_lock(&(sc)->mtx)
+#define SPROM_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
+#define SPROM_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->mtx, what)
+#define SPROM_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx)
+
+static int
+bhndb_pci_sprom_probe(device_t dev)
+{
+ device_t bridge, bus;
+
+ /* Our parent must be a PCI-BHND bridge with an attached bhnd bus */
+ bridge = device_get_parent(dev);
+ if (device_get_driver(bridge) != &bhndb_pci_driver)
+ return (ENXIO);
+
+ bus = device_find_child(bridge, devclass_get_name(bhnd_devclass), 0);
+ if (bus == NULL)
+ return (ENXIO);
+
+ /* Found */
+ device_set_desc(dev, "PCI-BHNDB SPROM/OTP");
+ if (!bootverbose)
+ device_quiet(dev);
+
+ /* Refuse wildcard attachments */
+ return (BUS_PROBE_NOWILDCARD);
+}
+
+static int
+bhndb_pci_sprom_attach(device_t dev)
+{
+ struct bhndb_pci_sprom_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ /* Allocate SPROM resource */
+ sc->sprom_rid = 0;
+ sc->sprom_res = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &sc->sprom_rid, RF_ACTIVE);
+ if (sc->sprom_res == NULL) {
+ device_printf(dev, "failed to allocate resources\n");
+ return (ENXIO);
+ }
+
+ /* Initialize SPROM shadow */
+ if ((error = bhnd_sprom_init(&sc->shadow, sc->sprom_res, 0))) {
+ device_printf(dev, "unrecognized SPROM format\n");
+ goto failed;
+ }
+
+ /* Initialize mutex */
+ SPROM_LOCK_INIT(sc);
+
+ return (0);
+
+failed:
+ bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sprom_rid,
+ sc->sprom_res);
+ return (error);
+}
+
+static int
+bhndb_pci_sprom_resume(device_t dev)
+{
+ return (0);
+}
+
+static int
+bhndb_pci_sprom_suspend(device_t dev)
+{
+ return (0);
+}
+
+static int
+bhndb_pci_sprom_detach(device_t dev)
+{
+ struct bhndb_pci_sprom_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sprom_rid,
+ sc->sprom_res);
+ bhnd_sprom_fini(&sc->shadow);
+ SPROM_LOCK_DESTROY(sc);
+
+ return (0);
+}
+
+static int
+bhndb_pci_sprom_getvar(device_t dev, const char *name, void *buf, size_t *len)
+{
+ struct bhndb_pci_sprom_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ SPROM_LOCK(sc);
+ error = bhnd_sprom_getvar(&sc->shadow, name, buf, len);
+ SPROM_UNLOCK(sc);
+
+ return (error);
+}
+
+static int
+bhndb_pci_sprom_setvar(device_t dev, const char *name, const void *buf,
+ size_t len)
+{
+ struct bhndb_pci_sprom_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ SPROM_LOCK(sc);
+ error = bhnd_sprom_setvar(&sc->shadow, name, buf, len);
+ SPROM_UNLOCK(sc);
+
+ return (error);
+}
+
+static device_method_t bhndb_pci_sprom_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, bhndb_pci_sprom_probe),
+ DEVMETHOD(device_attach, bhndb_pci_sprom_attach),
+ DEVMETHOD(device_resume, bhndb_pci_sprom_resume),
+ DEVMETHOD(device_suspend, bhndb_pci_sprom_suspend),
+ DEVMETHOD(device_detach, bhndb_pci_sprom_detach),
+
+ /* NVRAM interface */
+ DEVMETHOD(bhnd_nvram_getvar, bhndb_pci_sprom_getvar),
+ DEVMETHOD(bhnd_nvram_setvar, bhndb_pci_sprom_setvar),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(bhnd_nvram, bhndb_pci_sprom_driver, bhndb_pci_sprom_methods, sizeof(struct bhndb_pci_sprom_softc));
+
+DRIVER_MODULE(bhndb_pci_sprom, bhndb, bhndb_pci_sprom_driver, bhnd_nvram_devclass, NULL, NULL);
+MODULE_DEPEND(bhndb_pci_sprom, bhnd, 1, 1, 1);
+MODULE_VERSION(bhndb_pci_sprom, 1);
diff --git a/sys/dev/bhnd/bhndb/bhndb_pcireg.h b/sys/dev/bhnd/bhndb/bhndb_pcireg.h
index 6f431ac..eb2dc66 100644
--- a/sys/dev/bhnd/bhndb/bhndb_pcireg.h
+++ b/sys/dev/bhnd/bhndb/bhndb_pcireg.h
@@ -205,13 +205,17 @@
#define BHNDB_PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */
/* BHNDB_PCI_SPROM_CONTROL */
-#define BHNDB_PCI_SPROM_SZ_MSK 0x02 /* SPROM Size Mask */
-#define BHNDB_PCI_SPROM_LOCKED 0x08 /* SPROM Locked */
-#define BHNDB_PCI_SPROM_BLANK 0x04 /* indicating a blank SPROM */
-#define BHNDB_PCI_SPROM_WRITEEN 0x10 /* SPROM write enable */
-#define BHNDB_PCI_SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */
-#define BHNDB_PCI_SPROM_BACKPLANE_EN 0x40 /* Enable indirect backplane access */
-#define BHNDB_PCI_SPROM_OTPIN_USE 0x80 /* device OTP In use */
+#define BHNDB_PCI_SPROM_SZ_MASK 0x03 /**< sprom size mask */
+#define BHNDB_PCI_SPROM_SZ_1KB 0x00 /**< 1KB sprom size */
+#define BHNDB_PCI_SPROM_SZ_4KB 0x01 /**< 4KB sprom size */
+#define BHNDB_PCI_SPROM_SZ_16KB 0x02 /**< 16KB sprom size */
+#define BHNDB_PCI_SPROM_SZ_RESERVED 0x03 /**< unsupported sprom size */
+#define BHNDB_PCI_SPROM_LOCKED 0x08 /**< sprom locked */
+#define BHNDB_PCI_SPROM_BLANK 0x04 /**< sprom blank */
+#define BHNDB_PCI_SPROM_WRITEEN 0x10 /**< sprom write enable */
+#define BHNDB_PCI_SPROM_BOOTROM_WE 0x20 /**< external bootrom write enable */
+#define BHNDB_PCI_SPROM_BACKPLANE_EN 0x40 /**< enable indirect backplane access (BHNDB_PCI_BACKPLANE_*) */
+#define BHNDB_PCI_SPROM_OTPIN_USE 0x80 /**< device OTP in use */
/* PCI (non-PCIe) BHNDB_PCI_GPIO_OUTEN */
diff --git a/sys/dev/bhnd/bhndb/bhndb_pcivar.h b/sys/dev/bhnd/bhndb/bhndb_pcivar.h
index 021b393..7d7fcad 100644
--- a/sys/dev/bhnd/bhndb/bhndb_pcivar.h
+++ b/sys/dev/bhnd/bhndb/bhndb_pcivar.h
@@ -51,6 +51,7 @@ typedef int (*bhndb_pci_set_regwin_t)(struct bhndb_pci_softc *sc,
struct bhndb_pci_softc {
struct bhndb_softc bhndb; /**< parent softc */
device_t dev; /**< bridge device */
+ device_t parent; /**< parent PCI device */
bhnd_devclass_t pci_devclass; /**< PCI core's devclass */
bhndb_pci_set_regwin_t set_regwin; /**< regwin handler */
};
diff --git a/sys/dev/bhnd/bhndb/bhndb_subr.c b/sys/dev/bhnd/bhndb/bhndb_subr.c
index f6b003a..c9dd99c 100644
--- a/sys/dev/bhnd/bhndb/bhndb_subr.c
+++ b/sys/dev/bhnd/bhndb/bhndb_subr.c
@@ -52,8 +52,7 @@ bhndb_attach_bridge(device_t parent, device_t *bhndb, int unit)
{
int error;
- *bhndb = device_add_child(parent, devclass_get_name(bhndb_devclass),
- unit);
+ *bhndb = device_add_child(parent, "bhndb", unit);
if (*bhndb == NULL)
return (ENXIO);
@@ -874,19 +873,19 @@ bhndb_regwin_find_core(const struct bhndb_regwin *table, bhnd_devclass_t class,
if (rw->win_type != BHNDB_REGWIN_T_CORE)
continue;
- if (rw->core.class != class)
+ if (rw->d.core.class != class)
continue;
- if (unit != -1 && rw->core.unit != unit)
+ if (unit != -1 && rw->d.core.unit != unit)
continue;
- if (rw->core.port_type != port_type)
+ if (rw->d.core.port_type != port_type)
continue;
- if (rw->core.port != port)
+ if (rw->d.core.port != port)
continue;
- if (rw->core.region != region)
+ if (rw->d.core.region != region)
continue;
return (rw);
@@ -945,16 +944,16 @@ bhndb_regwin_matches_device(const struct bhndb_regwin *regw, device_t dev)
return (false);
/* Device class must match */
- if (bhnd_get_class(dev) != regw->core.class)
+ if (bhnd_get_class(dev) != regw->d.core.class)
return (false);
/* Device unit must match */
- if (bhnd_get_core_unit(dev) != regw->core.unit)
+ if (bhnd_get_core_unit(dev) != regw->d.core.unit)
return (false);
/* The regwin port/region must be defined. */
- if (!bhnd_is_region_valid(dev, regw->core.port_type, regw->core.port,
- regw->core.region))
+ if (!bhnd_is_region_valid(dev, regw->d.core.port_type, regw->d.core.port,
+ regw->d.core.region))
{
return (false);
}
diff --git a/sys/dev/bhnd/cores/chipc/chipc.c b/sys/dev/bhnd/cores/chipc/chipc.c
index eac1dcb..2f698ce 100644
--- a/sys/dev/bhnd/cores/chipc/chipc.c
+++ b/sys/dev/bhnd/cores/chipc/chipc.c
@@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$");
#include <dev/bhnd/bhnd.h>
+#include "bhnd_nvram_if.h"
+
#include "chipcreg.h"
#include "chipcvar.h"
@@ -73,13 +75,44 @@ static const struct bhnd_device chipc_devices[] = {
/* Device quirks table */
static struct bhnd_device_quirk chipc_quirks[] = {
- { BHND_HWREV_RANGE (0, 21), CHIPC_QUIRK_ALWAYS_HAS_SPROM },
- { BHND_HWREV_EQ (22), CHIPC_QUIRK_SPROM_CHECK_CST_R22 },
- { BHND_HWREV_RANGE (23, 31), CHIPC_QUIRK_SPROM_CHECK_CST_R23 },
- { BHND_HWREV_GTE (35), CHIPC_QUIRK_SUPPORTS_NFLASH },
+ { BHND_HWREV_GTE (32), CHIPC_QUIRK_SUPPORTS_SPROM },
+ { BHND_HWREV_GTE (35), CHIPC_QUIRK_SUPPORTS_NFLASH },
BHND_DEVICE_QUIRK_END
};
+/* Chip-specific quirks table */
+static struct bhnd_chip_quirk chipc_chip_quirks[] = {
+ /* 4331 12x9 packages */
+ {{ BHND_CHIP_IP(4331, 4331TN) },
+ CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM
+ },
+ {{ BHND_CHIP_IP(4331, 4331TNA0) },
+ CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM
+ },
+
+ /* 4331 12x12 packages */
+ {{ BHND_CHIP_IPR(4331, 4331TT, HWREV_GTE(1)) },
+ CHIPC_QUIRK_4331_EXTPA2_MUX_SPROM
+ },
+
+ /* 4331 (all packages/revisions) */
+ {{ BHND_CHIP_ID(4331) },
+ CHIPC_QUIRK_4331_EXTPA_MUX_SPROM
+ },
+
+ /* 4360 family (all revs <= 2) */
+ {{ BHND_CHIP_IR(4352, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+ {{ BHND_CHIP_IR(43460, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+ {{ BHND_CHIP_IR(43462, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+ {{ BHND_CHIP_IR(43602, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+
+ BHND_CHIP_QUIRK_END
+};
+
/* quirk and capability flag convenience macros */
#define CHIPC_QUIRK(_sc, _name) \
((_sc)->quirks & CHIPC_QUIRK_ ## _name)
@@ -91,7 +124,13 @@ static struct bhnd_device_quirk chipc_quirks[] = {
KASSERT(CHIPC_QUIRK((_sc), name), ("quirk " __STRING(_name) " not set"))
#define CHIPC_ASSERT_CAP(_sc, name) \
- KASSERT(CHIPC_CAP((_sc), name), ("capability " __STRING(_name) " not set"))
+ KASSERT(CHIPC_CAP((_sc), name), ("capability " __STRING(_name) " not set"))
+
+static bhnd_nvram_src_t chipc_nvram_identify(struct chipc_softc *sc);
+static int chipc_sprom_init(struct chipc_softc *);
+static int chipc_enable_sprom_pins(struct chipc_softc *);
+static int chipc_disable_sprom_pins(struct chipc_softc *);
+
static int
chipc_probe(device_t dev)
@@ -119,6 +158,9 @@ chipc_attach(device_t dev)
sc->dev = dev;
sc->quirks = bhnd_device_quirks(dev, chipc_devices,
sizeof(chipc_devices[0]));
+ sc->quirks |= bhnd_chip_quirks(dev, chipc_chip_quirks);
+
+ CHIPC_LOCK_INIT(sc);
/* Allocate bus resources */
memcpy(sc->rspec, chipc_rspec, sizeof(sc->rspec));
@@ -152,22 +194,28 @@ chipc_attach(device_t dev)
sc->caps = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES);
sc->cst = bhnd_bus_read_4(sc->core, CHIPC_CHIPST);
- // TODO
- switch (bhnd_chipc_nvram_src(dev)) {
- case BHND_NVRAM_SRC_CIS:
- device_printf(dev, "NVRAM source: CIS\n");
- break;
- case BHND_NVRAM_SRC_SPROM:
- device_printf(dev, "NVRAM source: SPROM\n");
- break;
+ /* Identify NVRAM source */
+ sc->nvram_src = chipc_nvram_identify(sc);
+
+ /* Read NVRAM data */
+ switch (sc->nvram_src) {
case BHND_NVRAM_SRC_OTP:
- device_printf(dev, "NVRAM source: OTP\n");
+ // TODO (requires access to OTP hardware)
+ device_printf(sc->dev, "NVRAM-OTP unsupported\n");
break;
+
case BHND_NVRAM_SRC_NFLASH:
- device_printf(dev, "NVRAM source: NFLASH\n");
+ // TODO (requires access to NFLASH hardware)
+ device_printf(sc->dev, "NVRAM-NFLASH unsupported\n");
+ break;
+
+ case BHND_NVRAM_SRC_SPROM:
+ if ((error = chipc_sprom_init(sc)))
+ goto cleanup;
break;
- case BHND_NVRAM_SRC_NONE:
- device_printf(dev, "NVRAM source: NONE\n");
+
+ case BHND_NVRAM_SRC_UNKNOWN:
+ /* Handled externally */
break;
}
@@ -175,6 +223,7 @@ chipc_attach(device_t dev)
cleanup:
bhnd_release_resources(dev, sc->rspec, sc->res);
+ CHIPC_LOCK_DESTROY(sc);
return (error);
}
@@ -185,6 +234,9 @@ chipc_detach(device_t dev)
sc = device_get_softc(dev);
bhnd_release_resources(dev, sc->rspec, sc->res);
+ bhnd_sprom_fini(&sc->sprom);
+
+ CHIPC_LOCK_DESTROY(sc);
return (0);
}
@@ -202,68 +254,64 @@ chipc_resume(device_t dev)
}
/**
- * Use device-specific ChipStatus flags to determine the preferred NVRAM
- * data source.
+ * Initialize local SPROM shadow, if required.
+ *
+ * @param sc chipc driver state.
*/
-static bhnd_nvram_src_t
-chipc_nvram_src_chipst(struct chipc_softc *sc)
+static int
+chipc_sprom_init(struct chipc_softc *sc)
{
- uint8_t nvram_sel;
-
- CHIPC_ASSERT_QUIRK(sc, SPROM_CHECK_CHIPST);
-
- if (CHIPC_QUIRK(sc, SPROM_CHECK_CST_R22)) {
- // TODO: On these devices, the official driver code always
- // assumes SPROM availability if CHIPC_CST_OTP_SEL is not
- // set; we must review against the actual behavior of our
- // BCM4312 hardware
- nvram_sel = CHIPC_GET_ATTR(sc->cst, CST_SPROM_OTP_SEL_R22);
- } else if (CHIPC_QUIRK(sc, SPROM_CHECK_CST_R23)) {
- nvram_sel = CHIPC_GET_ATTR(sc->cst, CST_SPROM_OTP_SEL_R23);
- } else {
- panic("invalid CST OTP/SPROM chipc quirk flags");
- }
- device_printf(sc->dev, "querying chipst for 0x%x, 0x%x\n", sc->ccid.chip_id, sc->cst);
+ int error;
- switch (nvram_sel) {
- case CHIPC_CST_DEFCIS_SEL:
- return (BHND_NVRAM_SRC_CIS);
+ KASSERT(sc->nvram_src == BHND_NVRAM_SRC_SPROM,
+ ("non-SPROM source (%u)\n", sc->nvram_src));
- case CHIPC_CST_SPROM_SEL:
- case CHIPC_CST_OTP_PWRDN:
- return (BHND_NVRAM_SRC_SPROM);
+ /* Enable access to the SPROM */
+ CHIPC_LOCK(sc);
+ if ((error = chipc_enable_sprom_pins(sc)))
+ goto failed;
- case CHIPC_CST_OTP_SEL:
- return (BHND_NVRAM_SRC_OTP);
+ /* Initialize SPROM parser */
+ error = bhnd_sprom_init(&sc->sprom, sc->core, CHIPC_SPROM_OTP);
+ if (error) {
+ device_printf(sc->dev, "SPROM identification failed: %d\n",
+ error);
- default:
- device_printf(sc->dev, "unrecognized OTP/SPROM type 0x%hhx",
- nvram_sel);
- return (BHND_NVRAM_SRC_NONE);
+ chipc_disable_sprom_pins(sc);
+ goto failed;
+ }
+
+ /* Drop access to the SPROM lines */
+ if ((error = chipc_disable_sprom_pins(sc))) {
+ bhnd_sprom_fini(&sc->sprom);
+ goto failed;
}
+ CHIPC_UNLOCK(sc);
+
+ return (0);
+
+failed:
+ CHIPC_UNLOCK(sc);
+ return (error);
}
/**
- * Determine the preferred NVRAM data source.
+ * Determine the NVRAM data source for this device.
+ *
+ * @param sc chipc driver state.
*/
static bhnd_nvram_src_t
-chipc_nvram_src(device_t dev)
+chipc_nvram_identify(struct chipc_softc *sc)
{
- struct chipc_softc *sc;
uint32_t srom_ctrl;
- sc = device_get_softc(dev);
-
- /* Very early devices always included a SPROM */
- if (CHIPC_QUIRK(sc, ALWAYS_HAS_SPROM))
- return (BHND_NVRAM_SRC_SPROM);
-
- /* Most other early devices require checking ChipStatus flags */
- if (CHIPC_QUIRK(sc, SPROM_CHECK_CHIPST))
- return (chipc_nvram_src_chipst(sc));
+ /* Very early devices vend SPROM/OTP/CIS (if at all) via the
+ * host bridge interface instead of ChipCommon. */
+ if (!CHIPC_QUIRK(sc, SUPPORTS_SPROM))
+ return (BHND_NVRAM_SRC_UNKNOWN);
/*
- * Later chipset revisions standardized the NVRAM capability flags and
+ * Later chipset revisions standardized the SPROM capability flags and
* register interfaces.
*
* We check for hardware presence in order of precedence. For example,
@@ -287,7 +335,158 @@ chipc_nvram_src(device_t dev)
return (BHND_NVRAM_SRC_NFLASH);
/* No NVRAM hardware capability declared */
- return (BHND_NVRAM_SRC_NONE);
+ return (BHND_NVRAM_SRC_UNKNOWN);
+}
+
+
+/**
+ * If required by this device, enable access to the SPROM.
+ *
+ * @param sc chipc driver state.
+ */
+static int
+chipc_enable_sprom_pins(struct chipc_softc *sc)
+{
+ uint32_t cctrl;
+
+ CHIPC_LOCK_ASSERT(sc, MA_OWNED);
+
+ /* Nothing to do? */
+ if (!CHIPC_QUIRK(sc, MUX_SPROM))
+ return (0);
+
+ cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
+
+ /* 4331 devices */
+ if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) {
+ cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN;
+
+ if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM))
+ cctrl &= ~CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5;
+
+ if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM))
+ cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN2;
+
+ bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
+ return (0);
+ }
+
+ /* 4360 devices */
+ if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) {
+ /* Unimplemented */
+ }
+
+ /* Refuse to proceed on unsupported devices with muxed SPROM pins */
+ device_printf(sc->dev, "muxed sprom lines on unrecognized device\n");
+ return (ENXIO);
+}
+
+/**
+ * If required by this device, revert any GPIO/pin configuration applied
+ * to allow SPROM access.
+ *
+ * @param sc chipc driver state.
+ */
+static int
+chipc_disable_sprom_pins(struct chipc_softc *sc)
+{
+ uint32_t cctrl;
+
+ CHIPC_LOCK_ASSERT(sc, MA_OWNED);
+
+ /* Nothing to do? */
+ if (!CHIPC_QUIRK(sc, MUX_SPROM))
+ return (0);
+
+ cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
+
+ /* 4331 devices */
+ if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) {
+ cctrl |= CHIPC_CCTRL4331_EXTPA_EN;
+
+ if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM))
+ cctrl |= CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5;
+
+ if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM))
+ cctrl |= CHIPC_CCTRL4331_EXTPA_EN2;
+
+ bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
+ return (0);
+ }
+
+ /* 4360 devices */
+ if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) {
+ /* Unimplemented */
+ }
+
+ /* Refuse to proceed on unsupported devices with muxed SPROM pins */
+ device_printf(sc->dev, "muxed sprom lines on unrecognized device\n");
+ return (ENXIO);
+}
+
+static bhnd_nvram_src_t
+chipc_nvram_src(device_t dev)
+{
+ struct chipc_softc *sc = device_get_softc(dev);
+ return (sc->nvram_src);
+}
+
+static int
+chipc_nvram_getvar(device_t dev, const char *name, void *buf, size_t *len)
+{
+ struct chipc_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ switch (sc->nvram_src) {
+ case BHND_NVRAM_SRC_SPROM:
+ CHIPC_LOCK(sc);
+ error = bhnd_sprom_getvar(&sc->sprom, name, buf, len);
+ CHIPC_UNLOCK(sc);
+ return (error);
+
+ case BHND_NVRAM_SRC_OTP:
+ case BHND_NVRAM_SRC_NFLASH:
+ /* Currently unsupported */
+ return (ENXIO);
+
+ case BHND_NVRAM_SRC_UNKNOWN:
+ return (ENODEV);
+ }
+
+ /* Unknown NVRAM source */
+ return (ENODEV);
+}
+
+static int
+chipc_nvram_setvar(device_t dev, const char *name, const void *buf,
+ size_t len)
+{
+ struct chipc_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ switch (sc->nvram_src) {
+ case BHND_NVRAM_SRC_SPROM:
+ CHIPC_LOCK(sc);
+ error = bhnd_sprom_setvar(&sc->sprom, name, buf, len);
+ CHIPC_UNLOCK(sc);
+ return (error);
+
+ case BHND_NVRAM_SRC_OTP:
+ case BHND_NVRAM_SRC_NFLASH:
+ /* Currently unsupported */
+ return (ENXIO);
+
+ case BHND_NVRAM_SRC_UNKNOWN:
+ default:
+ return (ENODEV);
+ }
+
+ /* Unknown NVRAM source */
+ return (ENODEV);
}
static device_method_t chipc_methods[] = {
@@ -301,6 +500,10 @@ static device_method_t chipc_methods[] = {
/* ChipCommon interface */
DEVMETHOD(bhnd_chipc_nvram_src, chipc_nvram_src),
+ /* NVRAM interface */
+ DEVMETHOD(bhnd_nvram_getvar, chipc_nvram_getvar),
+ DEVMETHOD(bhnd_nvram_setvar, chipc_nvram_setvar),
+
DEVMETHOD_END
};
diff --git a/sys/dev/bhnd/cores/chipc/chipcreg.h b/sys/dev/bhnd/cores/chipc/chipcreg.h
index 5024684..b67eb34 100644
--- a/sys/dev/bhnd/cores/chipc/chipcreg.h
+++ b/sys/dev/bhnd/cores/chipc/chipcreg.h
@@ -36,26 +36,12 @@
#define CHIPC_GET_ATTR(_entry, _attr) \
((_entry & CHIPC_ ## _attr ## _MASK) >> CHIPC_ ## _attr ## _SHIFT)
-#define CHIPC_ID 0x0
-#define CHIPC_CAPABILITIES 0x04
-#define CHIPC_CHIPST 0x2c
-#define CHIPC_EROMPTR 0xfc /**< 32-bit EROM base address
- * on BCMA devices */
-
-/** chipid */
-#define CHIPC_ID 0x0 /**< identification register */
-#define CHIPC_ID_CHIP_MASK 0x0000FFFF /**< chip id */
-#define CHIPC_ID_CHIP_SHIFT 0
-#define CHIPC_ID_REV_MASK 0x000F0000 /**< chip revision */
-#define CHIPC_ID_REV_SHIFT 16
-#define CHIPC_ID_PKG_MASK 0x00F00000 /**< physical package ID */
-#define CHIPC_ID_PKG_SHIFT 20
-#define CHIPC_ID_NUMCORE_MASK 0x0F000000 /**< number of cores on chip (rev >= 4) */
-#define CHIPC_ID_NUMCORE_SHIFT 24
-#define CHIPC_ID_BUS_MASK 0xF0000000 /**< chip/interconnect type (BHND_CHIPTYPE_*) */
-#define CHIPC_ID_BUS_SHIFT 28
+#define CHIPC_ID 0x0
+#define CHIPC_CAPABILITIES 0x04
#define CHIPC_OTPST 0x10
+#define CHIPC_CHIPCTRL 0x28 /**< chip control */
+#define CHIPC_CHIPST 0x2c /**< chip status */
#define CHIPC_JTAGCMD 0x30
#define CHIPC_JTAGIR 0x34
#define CHIPC_JTAGDR 0x38
@@ -76,6 +62,8 @@
#define CHIPC_CLKC_M3 0xa0
#define CHIPC_CLKDIV 0xa4
#define CHIPC_SYS_CLK_CTL 0xc0
+#define CHIPC_EROMPTR 0xfc /**< 32-bit EROM base address
+ * on BCMA devices */
#define CHIPC_SPROM_CTRL 0x190 /**< SPROM interface (rev >= 32) */
#define CHIPC_SPROM_ADDR 0x194
#define CHIPC_SPROM_DATA 0x198
@@ -95,6 +83,19 @@
#define CHIPC_PMU_PLL_CONTROL_DATA 0x664
#define CHIPC_SPROM_OTP 0x800 /* SPROM/OTP address space */
+/** chipid */
+#define CHIPC_ID 0x0 /**< identification register */
+#define CHIPC_ID_CHIP_MASK 0x0000FFFF /**< chip id */
+#define CHIPC_ID_CHIP_SHIFT 0
+#define CHIPC_ID_REV_MASK 0x000F0000 /**< chip revision */
+#define CHIPC_ID_REV_SHIFT 16
+#define CHIPC_ID_PKG_MASK 0x00F00000 /**< physical package ID */
+#define CHIPC_ID_PKG_SHIFT 20
+#define CHIPC_ID_NUMCORE_MASK 0x0F000000 /**< number of cores on chip (rev >= 4) */
+#define CHIPC_ID_NUMCORE_SHIFT 24
+#define CHIPC_ID_BUS_MASK 0xF0000000 /**< chip/interconnect type (BHND_CHIPTYPE_*) */
+#define CHIPC_ID_BUS_SHIFT 28
+
/* capabilities */
#define CHIPC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */
#define CHIPC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
@@ -1124,6 +1125,7 @@ enum {
#define CHIPC_CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */
#define CHIPC_CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */
#define CHIPC_CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */
+#define CHIPC_CCTRL4331_EXTPA_EN2 (1<<12) /* 0 ext pa2 disable, 1 ext pa2 enabled */
#define CHIPC_CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */
#define CHIPC_CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */
diff --git a/sys/dev/bhnd/cores/chipc/chipcvar.h b/sys/dev/bhnd/cores/chipc/chipcvar.h
index 988224b..fe8dd0a 100644
--- a/sys/dev/bhnd/cores/chipc/chipcvar.h
+++ b/sys/dev/bhnd/cores/chipc/chipcvar.h
@@ -32,6 +32,8 @@
#ifndef _BHND_CORES_CHIPC_CHIPCVAR_H_
#define _BHND_CORES_CHIPC_CHIPCVAR_H_
+#include <dev/bhnd/nvram/bhnd_spromvar.h>
+
#include "chipc.h"
DECLARE_CLASS(bhnd_chipc);
@@ -45,37 +47,64 @@ extern devclass_t bhnd_chipc_devclass;
*/
enum {
/** No quirks */
- CHIPC_QUIRK_NONE = 0,
+ CHIPC_QUIRK_NONE = 0,
/**
- * The device always provides an external SROM.
+ * ChipCommon-controlled SPROM/OTP is supported, along with the
+ * CHIPC_CAP_SPROM capability flag.
*/
- CHIPC_QUIRK_ALWAYS_HAS_SPROM = (1<<1),
-
-
+ CHIPC_QUIRK_SUPPORTS_SPROM = (1<<1),
+
/**
- * SROM availability must be determined through chip-specific
- * ChipStatus flags.
+ * External NAND NVRAM is supported, along with the CHIPC_CAP_NFLASH
+ * capability flag.
*/
- CHIPC_QUIRK_SPROM_CHECK_CHIPST = (1<<3),
+ CHIPC_QUIRK_SUPPORTS_NFLASH = (1<<2),
/**
- * Use the rev22 chipstatus register format when determining SPROM
- * availability.
+ * The SPROM is attached via muxed pins. The pins must be switched
+ * to allow reading/writing.
*/
- CHIPC_QUIRK_SPROM_CHECK_CST_R22 = (1<<4)|CHIPC_QUIRK_SPROM_CHECK_CHIPST,
+ CHIPC_QUIRK_MUX_SPROM = (1<<3),
/**
- * Use the rev23 chipstatus register format when determining SPROM
- * availability.
+ * Access to the SPROM uses pins shared with the 802.11a external PA.
+ *
+ * On modules using these 4331 packages, the CCTRL4331_EXTPA_EN flag
+ * must be cleared to allow SPROM access.
*/
- CHIPC_QUIRK_SPROM_CHECK_CST_R23 = (1<<5)|CHIPC_QUIRK_SPROM_CHECK_CHIPST,
+ CHIPC_QUIRK_4331_EXTPA_MUX_SPROM = (1<<4) |
+ CHIPC_QUIRK_MUX_SPROM,
/**
- * External NAND NVRAM is supported, along with the CHIPC_CAP_NFLASH
- * capability flag.
+ * Access to the SPROM uses pins shared with the 802.11a external PA.
+ *
+ * On modules using these 4331 chip packages, the external PA is
+ * attached via GPIO 2, 5, and sprom_dout pins.
+ *
+ * When enabling and disabling EXTPA to allow SPROM access, the
+ * CCTRL4331_EXTPA_ON_GPIO2_5 flag must also be set or cleared,
+ * respectively.
+ */
+ CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM = (1<<5) |
+ CHIPC_QUIRK_4331_EXTPA_MUX_SPROM,
+
+ /**
+ * Access to the SPROM uses pins shared with two 802.11a external PAs.
+ *
+ * When enabling and disabling EXTPA, the CCTRL4331_EXTPA_EN2 must also
+ * be cleared to allow SPROM access.
*/
- CHIPC_QUIRK_SUPPORTS_NFLASH = (1<<6),
+ CHIPC_QUIRK_4331_EXTPA2_MUX_SPROM = (1<<6) |
+ CHIPC_QUIRK_4331_EXTPA_MUX_SPROM,
+
+
+ /**
+ * SPROM pins are muxed with the FEM control lines on this 4360-family
+ * device. The muxed pins must be switched to allow reading/writing
+ * the SPROM.
+ */
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM = (1<<5) | CHIPC_QUIRK_MUX_SPROM
};
struct chipc_softc {
@@ -89,6 +118,19 @@ struct chipc_softc {
uint32_t quirks; /**< CHIPC_QUIRK_* quirk flags */
uint32_t caps; /**< CHIPC_CAP_* capability register flags */
uint32_t cst; /**< CHIPC_CST* status register flags */
+ bhnd_nvram_src_t nvram_src; /**< NVRAM source */
+
+ struct mtx mtx; /**< state mutex. */
+
+ struct bhnd_sprom sprom; /**< OTP/SPROM shadow, if any */
};
+#define CHIPC_LOCK_INIT(sc) \
+ mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
+ "BHND chipc driver lock", MTX_DEF)
+#define CHIPC_LOCK(sc) mtx_lock(&(sc)->mtx)
+#define CHIPC_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
+#define CHIPC_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->mtx, what)
+#define CHIPC_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx)
+
#endif /* _BHND_CORES_CHIPC_CHIPCVAR_H_ */ \ No newline at end of file
diff --git a/sys/dev/bhnd/nvram/bhnd_nvram.h b/sys/dev/bhnd/nvram/bhnd_nvram.h
index e2b6b0b..2c0c36b 100644
--- a/sys/dev/bhnd/nvram/bhnd_nvram.h
+++ b/sys/dev/bhnd/nvram/bhnd_nvram.h
@@ -36,10 +36,6 @@
* NVRAM data sources supported by bhnd(4) devices.
*/
typedef enum {
- BHND_NVRAM_SRC_CIS, /**< Default CIS source; this may
- * apply, for example, to PCMCIA cards
- * vending Broadcom NVRAM data via
- * their standard CIS table. */
BHND_NVRAM_SRC_OTP, /**< On-chip one-time-programmable
* memory. */
@@ -51,15 +47,36 @@ typedef enum {
* NVRAM. */
BHND_NVRAM_SRC_SPROM, /**< External serial EEPROM. */
- BHND_NVRAM_SRC_NONE /**< No NVRAM source is directly
- * attached. This is used on devices
- * attached via PCI(e) to BHND SoCs,
- * where to avoid unnecessary flash
- * hardware, NVRAM configuration for
- * individual devices is provided by
- * hardware attached to the SoC
- * itself.
+ BHND_NVRAM_SRC_UNKNOWN /**< No NVRAM source is directly
+ * attached.
+ *
+ * This will be returned by ChipCommon
+ * revisions (rev <= 31) used in early
+ * chipsets that vend SPROM/OTP via the
+ * native host bridge interface.
+ *
+ * For example, PCMCIA cards may vend
+ * Broadcom NVRAM data via their standard CIS
+ * table, and earlier PCI(e) devices map
+ * SPROM statically into PCI BARs, and the
+ * control registers into PCI config space.
+
+ * This will also be returned on later
+ * devices that are attached via PCI(e) to
+ * BHND SoCs, but do not include an attached
+ * SPROM, or programmed OTP. On such SoCs,
+ * NVRAM configuration for individual devices
+ * is provided by a common platform NVRAM
+ * device.
*/
} bhnd_nvram_src_t;
+/**
+ * Evaluates to true if the given NVRAM data source is accessible via
+ * ChipCommon.
+ */
+#define BHND_NVRAM_SRC_CC(_src) \
+ ((_src) == BHND_NVRAM_SRC_OTP || (_src) == BHND_NVRAM_SRC_SPROM)
+
+
#endif /* _BHND_NVRAM_BHND_NVRAM_H_ */ \ No newline at end of file
diff --git a/sys/dev/bhnd/nvram/bhnd_nvram_if.m b/sys/dev/bhnd/nvram/bhnd_nvram_if.m
index c4baaec..2bb307b 100644
--- a/sys/dev/bhnd/nvram/bhnd_nvram_if.m
+++ b/sys/dev/bhnd/nvram/bhnd_nvram_if.m
@@ -46,13 +46,16 @@ INTERFACE bhnd_nvram;
* @param[out] buf On success, the requested value will be written
* to this buffer. This argment may be NULL if
* the value is not desired.
- * @param[in,out] size The capacity of @p buf. On success, will be set
- * to the actual size of the requested value.
+ * @param[in,out] len The maximum capacity of @p buf. On success,
+ * will be set to the actual size of the requested
+ * value.
*
* @retval 0 success
* @retval ENOENT The requested variable was not found.
- * @retval ENOMEM If @p buf is non-NULL and a buffer of @p size is too
+ * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too
* small to hold the requested value.
+ * @retval ENODEV If no supported NVRAM hardware is accessible via this
+ * device.
* @retval non-zero If reading @p name otherwise fails, a regular unix
* error code will be returned.
*/
@@ -60,5 +63,30 @@ METHOD int getvar {
device_t dev;
const char *name;
void *buf;
- size_t *size;
-}; \ No newline at end of file
+ size_t *len;
+};
+
+/**
+ * Set an NVRAM variable's local value.
+ *
+ * No changes should be written to non-volatile storage.
+ *
+ * @param dev The NVRAM device.
+ * @param name The NVRAM variable name.
+ * @param buf The new value.
+ * @param len The size of @p buf.
+ *
+ * @retval 0 success
+ * @retval ENOENT The specified variable name is not recognized.
+ * @retval EINVAL If @p len does not match the expected variable size.
+ * @retval ENODEV If no supported NVRAM hardware is accessible via this
+ * device.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+METHOD int setvar {
+ device_t dev;
+ const char *name;
+ const void *buf;
+ size_t len;
+};
diff --git a/sys/dev/bhnd/nvram/bhnd_sprom.c b/sys/dev/bhnd/nvram/bhnd_sprom.c
new file mode 100644
index 0000000..54c1faa
--- /dev/null
+++ b/sys/dev/bhnd/nvram/bhnd_sprom.c
@@ -0,0 +1,572 @@
+/*-
+ * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/rman.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/bhnd/bhndvar.h>
+
+#include "nvramvar.h"
+
+#include "bhnd_spromreg.h"
+#include "bhnd_spromvar.h"
+
+/*
+ * BHND SPROM Parsing
+ *
+ * Provides identification and parsing of BHND SPROM data.
+ */
+
+static int sprom_direct_read(struct bhnd_sprom *sc, size_t offset,
+ void *buf, size_t nbytes, uint8_t *crc);
+static int sprom_extend_shadow(struct bhnd_sprom *sc, size_t image_size,
+ uint8_t *crc);
+static int sprom_populate_shadow(struct bhnd_sprom *sc);
+
+static int sprom_var_defn(struct bhnd_sprom *sc, const char *name,
+ const struct bhnd_nvram_var **var,
+ const struct bhnd_sprom_var **sprom, size_t *size);
+
+/* SPROM revision is always located at the second-to-last byte */
+#define SPROM_REV(_sc) SPROM_READ_1((_sc), (_sc)->sp_size - 2)
+
+/* SPROM CRC is always located at the last byte */
+#define SPROM_CRC_OFF(_sc) SPROM_CRC_LEN(_sc)
+
+/* SPROM CRC covers all but the final CRC byte */
+#define SPROM_CRC_LEN(_sc) ((_sc)->sp_size - 1)
+
+/* SPROM shadow I/O (with byte-order translation) */
+#define SPROM_READ_1(_sc, _off) SPROM_READ_ENC_1(_sc, _off)
+#define SPROM_READ_2(_sc, _off) le16toh(SPROM_READ_ENC_2(_sc, _off))
+#define SPROM_READ_4(_sc, _off) le32toh(SPROM_READ_ENC_4(_sc, _off))
+
+#define SPROM_WRITE_1(_sc, _off, _v) SPROM_WRITE_ENC_1(_sc, _off, (_v))
+#define SPROM_WRITE_2(_sc, _off, _v) SPROM_WRITE_ENC_2(_sc, _off, \
+ htole16(_v))
+#define SPROM_WRITE_4(_sc, _off, _v) SPROM_WRITE_ENC_4(_sc, _off, \
+ htole32(_v))
+
+/* SPROM shadow I/O (without byte-order translation) */
+#define SPROM_READ_ENC_1(_sc, _off) (*(uint8_t *)((_sc)->sp_shadow + _off))
+#define SPROM_READ_ENC_2(_sc, _off) (*(uint16_t *)((_sc)->sp_shadow + _off))
+#define SPROM_READ_ENC_4(_sc, _off) (*(uint32_t *)((_sc)->sp_shadow + _off))
+
+#define SPROM_WRITE_ENC_1(_sc, _off, _v) \
+ *((uint8_t *)((_sc)->sp_shadow + _off)) = (_v)
+#define SPROM_WRITE_ENC_2(_sc, _off, _v) \
+ *((uint16_t *)((_sc)->sp_shadow + _off)) = (_v)
+#define SPROM_WRITE_ENC_4(_sc, _off, _v) \
+ *((uint32_t *)((_sc)->sp_shadow + _off)) = (_v)
+
+/* Call @p _next macro with the C type, widened (signed or unsigned) C
+ * type, and width associated with @p _dtype */
+#define SPROM_SWITCH_TYPE(_dtype, _next, ...) \
+do { \
+ switch (_dtype) { \
+ case BHND_NVRAM_DT_UINT8: \
+ _next (uint8_t, uint32_t, 1, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_UINT16: \
+ _next (uint16_t, uint32_t, 2, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_UINT32: \
+ _next (uint32_t, uint32_t, 4, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_INT8: \
+ _next (int8_t, int32_t, 1, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_INT16: \
+ _next (int16_t, int32_t, 2, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_INT32: \
+ _next (int32_t, int32_t, 4, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_CHAR: \
+ _next (uint8_t, uint32_t, 1, \
+ ## __VA_ARGS__); \
+ break; \
+ } \
+} while (0)
+
+/*
+ * Table of supported SPROM image formats, sorted by image size, ascending.
+ */
+#define SPROM_FMT(_sz, _revmin, _revmax, _sig) \
+ { SPROM_SZ_ ## _sz, _revmin, _revmax, \
+ SPROM_SIG_ ## _sig ## _OFF, \
+ SPROM_SIG_ ## _sig }
+
+static const struct sprom_fmt {
+ size_t size;
+ uint8_t rev_min;
+ uint8_t rev_max;
+ size_t sig_offset;
+ uint16_t sig_req;
+} sprom_fmts[] = {
+ SPROM_FMT(R1_3, 1, 3, NONE),
+ SPROM_FMT(R4_8_9, 4, 4, R4),
+ SPROM_FMT(R4_8_9, 8, 9, R8_9),
+ SPROM_FMT(R10, 10, 10, R10),
+ SPROM_FMT(R11, 11, 11, R11)
+};
+
+/**
+ * Identify the SPROM format at @p offset within @p r, verify the CRC,
+ * and allocate a local shadow copy of the SPROM data.
+ *
+ * After successful initialization, @p r will not be accessed; any pin
+ * configuration required for SPROM access may be reset.
+ *
+ * @param[out] sprom On success, will be initialized with shadow of the SPROM
+ * data.
+ * @param r An active resource mapping the SPROM data.
+ * @param offset Offset of the SPROM data within @p resource.
+ */
+int
+bhnd_sprom_init(struct bhnd_sprom *sprom, struct bhnd_resource *r,
+ bus_size_t offset)
+{
+ bus_size_t res_size;
+ int error;
+
+ sprom->dev = rman_get_device(r->res);
+ sprom->sp_res = r;
+ sprom->sp_res_off = offset;
+
+ /* Determine maximum possible SPROM image size */
+ res_size = rman_get_size(r->res);
+ if (offset >= res_size)
+ return (EINVAL);
+
+ sprom->sp_size_max = MIN(res_size - offset, SPROM_SZ_MAX);
+
+ /* Allocate and populate SPROM shadow */
+ sprom->sp_size = 0;
+ sprom->sp_capacity = sprom->sp_size_max;
+ sprom->sp_shadow = malloc(sprom->sp_capacity, M_BHND, M_NOWAIT);
+ if (sprom->sp_shadow == NULL)
+ return (ENOMEM);
+
+ /* Read and identify SPROM image */
+ if ((error = sprom_populate_shadow(sprom)))
+ return (error);
+
+ return (0);
+}
+
+/**
+ * Release all resources held by @p sprom.
+ *
+ * @param sprom A SPROM instance previously initialized via bhnd_sprom_init().
+ */
+void
+bhnd_sprom_fini(struct bhnd_sprom *sprom)
+{
+ free(sprom->sp_shadow, M_BHND);
+}
+
+/* Perform a read using a SPROM offset descriptor, safely widening the
+ * result to its 32-bit representation before assigning it to @p _dest. */
+#define SPROM_GETVAR_READ(_type, _widen, _width, _sc, _off, _dest) \
+do { \
+ _type _v = (_type)SPROM_READ_ ## _width(_sc, _off->offset); \
+ if (_off->shift > 0) { \
+ _v >>= _off->shift; \
+ } else if (off->shift < 0) { \
+ _v <<= -_off->shift; \
+ } \
+ _dest = ((uint32_t) (_widen) _v) & _off->mask; \
+} while(0)
+
+/* Emit a value read using a SPROM offset descriptor, narrowing the
+ * result output representation and, if necessary, OR'ing it with the
+ * previously read value from @p _buf. */
+#define SPROM_GETVAR_WRITE(_type, _widen, _width, _off, _src, _buf) \
+do { \
+ _type _v = (_type) (_widen) _src; \
+ if (_off->cont) \
+ _v |= *((_type *)_buf); \
+ *((_type *)_buf) = _v; \
+} while(0)
+
+/**
+ * Read a SPROM variable, performing conversion to host byte order.
+ *
+ * @param sc The SPROM parser state.
+ * @param name The SPROM variable name.
+ * @param[out] buf On success, the requested value will be written
+ * to this buffer. This argment may be NULL if
+ * the value is not desired.
+ * @param[in,out] len The capacity of @p buf. On success, will be set
+ * to the actual size of the requested value.
+ *
+ * @retval 0 success
+ * @retval ENOENT The requested variable was not found.
+ * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too
+ * small to hold the requested value.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+int
+bhnd_sprom_getvar(struct bhnd_sprom *sc, const char *name, void *buf,
+ size_t *len)
+{
+ const struct bhnd_nvram_var *nv;
+ const struct bhnd_sprom_var *sv;
+ size_t all1_offs;
+ size_t req_size;
+ int error;
+
+ if ((error = sprom_var_defn(sc, name, &nv, &sv, &req_size)))
+ return (error);
+
+ /* Provide required size */
+ if (buf == NULL) {
+ *len = req_size;
+ return (0);
+ }
+
+ /* Check (and update) target buffer len */
+ if (*len < req_size)
+ return (ENOMEM);
+ else
+ *len = req_size;
+
+ /* Read data */
+ all1_offs = 0;
+ for (size_t i = 0; i < sv->num_offsets; i++) {
+ const struct bhnd_sprom_offset *off;
+ uint32_t val;
+
+ off = &sv->offsets[i];
+ KASSERT(!off->cont || i > 0, ("cont marked on first offset"));
+
+ /* If not a continuation, advance the output buffer */
+ if (i > 0 && !off->cont) {
+ buf = ((uint8_t *)buf) +
+ bhnd_nvram_type_width(sv->offsets[i-1].type);
+ }
+
+ /* Read the value, widening to a common uint32
+ * representation */
+ SPROM_SWITCH_TYPE(off->type, SPROM_GETVAR_READ, sc, off, val);
+
+ /* If IGNALL1, record whether value has all bits set. */
+ if (nv->flags & BHND_NVRAM_VF_IGNALL1) {
+ uint32_t all1;
+
+ all1 = off->mask;
+ if (off->shift > 0)
+ all1 >>= off->shift;
+ else if (off->shift < 0)
+ all1 <<= -off->shift;
+
+ if ((val & all1) == all1)
+ all1_offs++;
+ }
+
+ /* Write the value, narrowing to the appropriate output
+ * width. */
+ SPROM_SWITCH_TYPE(nv->type, SPROM_GETVAR_WRITE, off, val, buf);
+ }
+
+ /* Should value should be treated as uninitialized? */
+ if (nv->flags & BHND_NVRAM_VF_IGNALL1 && all1_offs == sv->num_offsets)
+ return (ENOENT);
+
+ return (0);
+}
+
+/* Perform a read of a variable offset from _src, safely widening the result
+ * to its 32-bit representation before assigning it to @p
+ * _dest. */
+#define SPROM_SETVAR_READ(_type, _widen, _width, _off, _src, _dest) \
+do { \
+ _type _v = *(const _type *)_src; \
+ if (_off->shift > 0) { \
+ _v <<= _off->shift; \
+ } else if (off->shift < 0) { \
+ _v >>= -_off->shift; \
+ } \
+ _dest = ((uint32_t) (_widen) _v) & _off->mask; \
+} while(0)
+
+
+/* Emit a value read using a SPROM offset descriptor, narrowing the
+ * result output representation and, if necessary, OR'ing it with the
+ * previously read value from @p _buf. */
+#define SPROM_SETVAR_WRITE(_type, _widen, _width, _sc, _off, _src) \
+do { \
+ _type _v = (_type) (_widen) _src; \
+ if (_off->cont) \
+ _v |= SPROM_READ_ ## _width(_sc, _off->offset); \
+ SPROM_WRITE_ ## _width(_sc, _off->offset, _v); \
+} while(0)
+
+/**
+ * Set a local value for a SPROM variable, performing conversion to SPROM byte
+ * order.
+ *
+ * The new value will be written to the backing SPROM shadow.
+ *
+ * @param sc The SPROM parser state.
+ * @param name The SPROM variable name.
+ * @param[out] buf The new value.
+ * @param[in,out] len The size of @p buf.
+ *
+ * @retval 0 success
+ * @retval ENOENT The requested variable was not found.
+ * @retval EINVAL If @p len does not match the expected variable size.
+ */
+int
+bhnd_sprom_setvar(struct bhnd_sprom *sc, const char *name, const void *buf,
+ size_t len)
+{
+ const struct bhnd_nvram_var *nv;
+ const struct bhnd_sprom_var *sv;
+ size_t req_size;
+ int error;
+ uint8_t crc;
+
+ if ((error = sprom_var_defn(sc, name, &nv, &sv, &req_size)))
+ return (error);
+
+ /* Provide required size */
+ if (len != req_size)
+ return (EINVAL);
+
+ /* Write data */
+ for (size_t i = 0; i < sv->num_offsets; i++) {
+ const struct bhnd_sprom_offset *off;
+ uint32_t val;
+
+ off = &sv->offsets[i];
+ KASSERT(!off->cont || i > 0, ("cont marked on first offset"));
+
+ /* If not a continuation, advance the input pointer */
+ if (i > 0 && !off->cont) {
+ buf = ((const uint8_t *)buf) +
+ bhnd_nvram_type_width(sv->offsets[i-1].type);
+ }
+
+ /* Read the value, widening to a common uint32
+ * representation */
+ SPROM_SWITCH_TYPE(nv->type, SPROM_SETVAR_READ, off, buf, val);
+
+ /* Write the value, narrowing to the appropriate output
+ * width. */
+ SPROM_SWITCH_TYPE(off->type, SPROM_SETVAR_WRITE, sc, off, val);
+ }
+
+ /* Update CRC */
+ crc = ~bhnd_nvram_crc8(sc->sp_shadow, SPROM_CRC_LEN(sc),
+ BHND_NVRAM_CRC8_INITIAL);
+ SPROM_WRITE_1(sc, SPROM_CRC_OFF(sc), crc);
+
+ return (0);
+}
+
+/* Read and identify the SPROM image by incrementally performing
+ * read + CRC of all supported image formats */
+static int
+sprom_populate_shadow(struct bhnd_sprom *sc)
+{
+ const struct sprom_fmt *fmt;
+ int error;
+ uint16_t sig;
+ uint8_t srom_rev;
+ uint8_t crc;
+
+ crc = BHND_NVRAM_CRC8_INITIAL;
+
+ /* Identify the SPROM revision (and populate the SPROM shadow) */
+ for (size_t i = 0; i < nitems(sprom_fmts); i++) {
+ fmt = &sprom_fmts[i];
+
+ /* Read image data and check CRC */
+ if ((error = sprom_extend_shadow(sc, fmt->size, &crc)))
+ return (error);
+
+ /* Skip on invalid CRC */
+ if (crc != BHND_NVRAM_CRC8_VALID)
+ continue;
+
+ /* Fetch SROM revision */
+ srom_rev = SPROM_REV(sc);
+
+ /* Early sromrev 1 devices (specifically some BCM440x enet
+ * cards) are reported to have been incorrectly programmed
+ * with a revision of 0x10. */
+ if (fmt->size == SPROM_SZ_R1_3 && srom_rev == 0x10)
+ srom_rev = 0x1;
+
+ /* Verify revision range */
+ if (srom_rev < fmt->rev_min || srom_rev > fmt->rev_max)
+ continue;
+
+ /* Verify signature (if any) */
+ sig = SPROM_SIG_NONE;
+ if (fmt->sig_offset != SPROM_SIG_NONE_OFF)
+ sig = SPROM_READ_2(sc, fmt->sig_offset);
+
+ if (sig != fmt->sig_req) {
+ device_printf(sc->dev,
+ "invalid sprom %hhu signature: 0x%hx "
+ "(expected 0x%hx)\n",
+ srom_rev, sig, fmt->sig_req);
+ return (EINVAL);
+ }
+
+ /* Identified */
+ sc->sp_rev = srom_rev;
+ return (0);
+ }
+
+ /* identification failed */
+ device_printf(sc->dev, "unrecognized sprom format\n");
+ return (EINVAL);
+}
+
+/*
+ * Extend the shadowed SPROM buffer to image_size, reading any required
+ * data from the backing SPROM resource and updating the CRC.
+ */
+static int
+sprom_extend_shadow(struct bhnd_sprom *sc, size_t image_size,
+ uint8_t *crc)
+{
+ int error;
+
+ KASSERT(image_size >= sc->sp_size, (("shadow truncation unsupported")));
+
+ /* Verify the request fits within our shadow buffer */
+ if (image_size > sc->sp_capacity)
+ return (ENOSPC);
+
+ /* Skip no-op requests */
+ if (sc->sp_size == image_size)
+ return (0);
+
+ /* Populate the extended range */
+ error = sprom_direct_read(sc, sc->sp_size, sc->sp_shadow + sc->sp_size,
+ image_size - sc->sp_size, crc);
+ if (error)
+ return (error);
+
+ sc->sp_size = image_size;
+ return (0);
+}
+
+/**
+ * Read nbytes at the given offset from the backing SPROM resource, and
+ * update the CRC.
+ */
+static int
+sprom_direct_read(struct bhnd_sprom *sc, size_t offset, void *buf,
+ size_t nbytes, uint8_t *crc)
+{
+ bus_size_t res_offset;
+ size_t nread;
+ uint16_t *p;
+
+ KASSERT(nbytes % sizeof(uint16_t) == 0, ("unaligned sprom size"));
+ KASSERT(offset % sizeof(uint16_t) == 0, ("unaligned sprom offset"));
+
+ /* Check for read overrun */
+ if (offset >= sc->sp_size_max || sc->sp_size_max - offset < nbytes) {
+ device_printf(sc->dev, "requested SPROM read would overrun\n");
+ return (EINVAL);
+ }
+
+ p = (uint16_t *)buf;
+ res_offset = sc->sp_res_off + offset;
+
+ /* Perform read */
+ for (nread = 0; nread < nbytes; nread += 2) {
+ *p = bhnd_bus_read_stream_2(sc->sp_res, res_offset+nread);
+ *crc = bhnd_nvram_crc8(p, sizeof(*p), *crc);
+ p++;
+ };
+
+ return (0);
+}
+
+
+/**
+ * Locate the variable and SPROM revision-specific definitions
+ * for variable with @p name.
+ */
+static int
+sprom_var_defn(struct bhnd_sprom *sc, const char *name,
+ const struct bhnd_nvram_var **var,
+ const struct bhnd_sprom_var **sprom,
+ size_t *size)
+{
+ /* Find variable definition */
+ *var = bhnd_nvram_var_defn(name);
+ if (*var == NULL)
+ return (ENOENT);
+
+ /* Find revision-specific SPROM definition */
+ for (size_t i = 0; i < (*var)->num_sp_descs; i++) {
+ const struct bhnd_sprom_var *sp = &(*var)->sprom_descs[i];
+
+ if (sc->sp_rev < sp->compat.first)
+ continue;
+
+ if (sc->sp_rev > sp->compat.last)
+ continue;
+
+ /* Found */
+ *sprom = sp;
+
+ /* Calculate size in bytes */
+ *size = bhnd_nvram_type_width((*var)->type) * sp->num_offsets;
+ return (0);
+ }
+
+ /* Not supported by this SPROM revision */
+ return (ENOENT);
+} \ No newline at end of file
diff --git a/sys/dev/bhnd/nvram/bhnd_spromreg.h b/sys/dev/bhnd/nvram/bhnd_spromreg.h
new file mode 100644
index 0000000..2d5c237
--- /dev/null
+++ b/sys/dev/bhnd/nvram/bhnd_spromreg.h
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BHND_NVRAM_SPROMREG_H_
+#define _BHND_NVRAM_SPROMREG_H_
+
+#define SPROM_SZ_R1_3 128 /**< SPROM image size (rev 1-3) */
+#define SPROM_SZ_R4_8_9 440 /**< SPROM image size (rev 4, 8-9) */
+#define SPROM_SZ_R10 460 /**< SPROM image size (rev 10) */
+#define SPROM_SZ_R11 468 /**< SPROM image size (rev 11) */
+
+/** Maximum supported SPROM image size */
+#define SPROM_SZ_MAX SPROM_SZ_R11
+
+#define SPROM_SIG_NONE 0x0
+#define SPROM_SIG_NONE_OFF 0x0
+
+/** SPROM signature (rev 4) */
+#define SPROM_SIG_R4 0x5372
+#define SPROM_SIG_R4_OFF 64 /**< SPROM signature offset (rev 4) */
+
+/** SPROM signature (rev 8, 9) */
+#define SPROM_SIG_R8_9 SPROM_SIG_R4
+#define SPROM_SIG_R8_9_OFF 128 /**< SPROM signature offset (rev 8-9) */
+
+/** SPROM signature (rev 10) */
+#define SPROM_SIG_R10 SPROM_SIG_R4
+#define SPROM_SIG_R10_OFF 438 /**< SPROM signature offset (rev 10) */
+
+/** SPROM signature (rev 11) */
+#define SPROM_SIG_R11 0x0634
+#define SPROM_SIG_R11_OFF 128 /**< SPROM signature offset (rev 11) */
+
+
+#endif /* _BHND_NVRAM_SPROMREG_H_ */
diff --git a/sys/dev/bhnd/nvram/bhnd_spromvar.h b/sys/dev/bhnd/nvram/bhnd_spromvar.h
new file mode 100644
index 0000000..15cfa79
--- /dev/null
+++ b/sys/dev/bhnd/nvram/bhnd_spromvar.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BHND_NVRAM_BHND_SPROM_H_
+#define _BHND_NVRAM_BHND_SPROM_H_
+
+struct bhnd_sprom {
+ device_t dev; /**< sprom parent device */
+
+ uint8_t sp_rev; /**< sprom revision */
+
+ struct bhnd_resource *sp_res; /**< sprom resource. */
+ bus_size_t sp_res_off; /**< offset to sprom image */
+
+ uint8_t *sp_shadow; /**< sprom shadow */
+ bus_size_t sp_size_max; /**< maximum possible sprom length */
+ size_t sp_size; /**< shadow size */
+ size_t sp_capacity; /**< shadow buffer capacity */
+};
+
+int bhnd_sprom_init(struct bhnd_sprom *sprom, struct bhnd_resource *r,
+ bus_size_t offset);
+void bhnd_sprom_fini(struct bhnd_sprom *sprom);
+
+int bhnd_sprom_getvar(struct bhnd_sprom *sc, const char *name, void *buf,
+ size_t *len);
+int bhnd_sprom_setvar(struct bhnd_sprom *sc, const char *name,
+ const void *buf, size_t len);
+
+#endif /* _BHND_NVRAM_BHND_SPROM_H_ */
diff --git a/sys/dev/bhnd/nvram/nvram_map b/sys/dev/bhnd/nvram/nvram_map
new file mode 100644
index 0000000..a716280
--- /dev/null
+++ b/sys/dev/bhnd/nvram/nvram_map
@@ -0,0 +1,1445 @@
+#-
+# Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+# Copyright (C) 2008-2015, Broadcom Corporation.
+# All Rights Reserved.
+#
+# The contents of this file (variable names, descriptions, and offsets) were
+# extracted or derived from Broadcom's ISC-licensed sources.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# SPECIAL, DIRECT, 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.
+#
+# $FreeBSD$
+
+#
+# NVRAM variable definitions and revision-specific SPROM offsets.
+#
+# Processed by nvram_map_gen.awk to produce bhnd_nvram_map.h
+#
+# NOTE: file was originally generated automatically by using libclang
+# to analyze and extract format information and descriptions from Broadcom's
+# available ISC-licensed CIS and SROM code and associated headers.
+#
+
+# Antennas available
+u8 aa2g {
+ srom 1-3 0x5C (&0x30, >>4)
+ srom 4-7 0x5D
+ srom 8-10 0x9D
+ srom >= 11 0xA1
+}
+u8 aa5g {
+ srom 1-3 0x5C (&0xC0, >>6)
+ srom 4-7 0x5C
+ srom 8-10 0x9C
+ srom >= 11 0xA0
+}
+
+# ACPHY PA trimming parameters: 40
+u16[12] pa5gbw40a0 {
+ srom >= 11 0x110
+}
+
+# ACPHY PA trimming parameters: 80
+u16[12] pa5gbw80a0 {
+ srom >= 11 0x138
+}
+
+# ACPHY PA trimming parameters: 40/80
+u16[12] pa5gbw4080a0 {
+ srom >= 11 0x138
+}
+u16[12] pa5gbw4080a1 {
+ srom >= 11 u16 0xB6, u16 0xBC, u16 0xCE, u16 0xD4, u16[8] 0x128
+}
+
+# ACPHY PA trimming parameters: CCK
+u16[3] pa2gccka0 {
+ srom >= 11 0x102
+}
+
+# ACPHY Power-per-rate 2gpo
+u16 dot11agofdmhrbw202gpo {
+ srom >= 11 0x15C
+}
+u16 ofdmlrbw202gpo {
+ srom >= 11 0x15E
+}
+
+# ACPHY Power-per-rate 5gpo
+u32 mcsbw805glpo {
+ srom >= 11 0x168
+}
+u32 mcsbw805gmpo {
+ srom >= 11 0x178
+}
+u32 mcsbw805ghpo {
+ srom >= 11 0x188
+}
+u16 mcslr5glpo {
+ srom >= 11 0x190 (&0xFFF)
+}
+u16 mcslr5gmpo {
+ srom >= 11 0x192
+}
+u16 mcslr5ghpo {
+ srom >= 11 0x194
+}
+
+# ACPHY Power-per-rate sbpo
+u16 sb20in40hrpo {
+ srom >= 11 0x196
+}
+u16 sb20in80and160hr5glpo {
+ srom >= 11 0x198
+}
+u16 sb40and80hr5glpo {
+ srom >= 11 0x19A
+}
+u16 sb20in80and160hr5gmpo {
+ srom >= 11 0x19C
+}
+u16 sb40and80hr5gmpo {
+ srom >= 11 0x19E
+}
+u16 sb20in80and160hr5ghpo {
+ srom >= 11 0x1A0
+}
+u16 sb40and80hr5ghpo {
+ srom >= 11 0x1A2
+}
+u16 sb20in40lrpo {
+ srom >= 11 0x1A4
+}
+u16 sb20in80and160lr5glpo {
+ srom >= 11 0x1A6
+}
+u16 sb40and80lr5glpo {
+ srom >= 11 0x1A8
+}
+u16 sb20in80and160lr5gmpo {
+ srom >= 11 0x1AA
+}
+u16 sb40and80lr5gmpo {
+ srom >= 11 0x1AC
+}
+u16 sb20in80and160lr5ghpo {
+ srom >= 11 0x1AE
+}
+u16 sb40and80lr5ghpo {
+ srom >= 11 0x1B0
+}
+u16 dot11agduphrpo {
+ srom >= 11 0x1B2
+}
+u16 dot11agduplrpo {
+ srom >= 11 0x1B4
+}
+
+# Antenna gain
+u8 ag0 {
+ srom 1-3 0x75
+ srom 4-7 0x5F
+ srom 8-10 0x9F
+}
+u8 ag1 {
+ srom 1-3 0x74
+ srom 4-7 0x5E
+ srom 8-10 0x9E
+}
+u8 ag2 {
+ srom 4-7 0x61
+ srom 8-10 0xA1
+}
+u8 ag3 {
+ srom 4-7 0x60
+ srom 8-10 0xA0
+}
+
+u8 agbg0 {
+ srom >= 11 0xA2
+}
+u8 agbg1 {
+ srom >= 11 0xA3
+}
+u8 agbg2 {
+ srom >= 11 0xA4
+}
+u8 aga0 {
+ srom >= 11 0xA5
+}
+u8 aga1 {
+ srom >= 11 0xA6
+}
+u8 aga2 {
+ srom >= 11 0xA7
+}
+
+# board flags
+u32 boardflags {
+ srom 1 u16 0x72
+ srom 2 u16 0x72 | u16 0x38 (<<16)
+ srom 3 u16 0x72 | u16 0x7A (<<16)
+ srom 4 0x44
+ srom 5-7 0x4A
+ srom >= 8 0x84
+}
+u32 boardflags2 {
+ srom 4 0x48
+ srom 5-7 0x4E
+ srom >= 8 0x88
+}
+u32 boardflags3 {
+ srom >= 11 0x8C
+}
+
+# board serial number, independent of mac addr
+u16 boardnum {
+ srom 1-2 0x4C
+ srom 3 0x4E
+ srom 4 0x50
+ srom 5-7 0x56
+ srom 8-10 0x90
+ srom >= 11 0x94
+}
+
+# One byte board revision
+u16 boardrev {
+ srom 1-3 u8 0x5D
+ srom 4-7 0x42
+ srom >= 8 0x82
+}
+
+# 2 bytes; boardtype
+u16 boardtype {
+ srom >= 2 0x4
+}
+
+# Default country code (sromrev == 1)
+u8 cc {
+ srom 1 0x5C (&0xF)
+}
+
+# 2 bytes each
+# CCK Power offsets for 20 MHz rates (11, 5.5, 2, 1Mbps)
+# cckbw202gpo cckbw20ul2gpo
+#
+u16 cckbw202gpo {
+ srom 9-10 0x140
+ srom >= 11 0x150
+}
+u16 cckbw20ul2gpo {
+ srom 9-10 0x142
+ srom >= 11 0x152
+}
+
+# Country code (2 bytes ascii + 1 byte cctl)
+# in rev 2
+#
+char[2] ccode {
+ sfmt ccode
+ srom 0-3 0x76
+ srom 4 0x52
+ srom 5-7 0x44
+ srom 8-10 0x92
+ srom >= 11 0x96
+}
+
+# 2 byte; txchain, rxchain
+u8 txchain {
+ all1 ignore
+ srom 4-7 0x7B (&0xF)
+ srom 8-10 0xA3 (&0xF)
+ srom >= 11 0xA9 (&0xF)
+}
+u8 rxchain {
+ all1 ignore
+ srom 4-7 0x7B (&0xF0, >>4)
+ srom 8-10 0xA3 (&0xF0, >>4)
+ srom >= 11 0xA9 (&0xF0, >>4)
+}
+u16 antswitch {
+ all1 ignore
+ srom 4-7 u8 0x7A
+ srom 8-10 u8 0xA2
+ srom >= 11 u8 0xA8
+}
+
+# PCI device id
+private u16 devid {
+ srom >= 8 u16 0x60
+}
+
+u8 elna2g {
+ srom 8-10 0xBB
+}
+
+u8 elna5g {
+ srom 8-10 0xBA
+}
+
+# 11n front-end specification
+u8 antswctl2g {
+ srom 8-10 0xAE (&0xF8, >>3)
+}
+u8 triso2g {
+ srom 8-10 0xAE (&0x7)
+}
+u8 pdetrange2g {
+ srom 8-10 0xAF (&0xF8, >>3)
+}
+u8 extpagain2g {
+ srom 8-10 0xAF (&0x6, >>1)
+}
+u8 tssipos2g {
+ srom 8-10 0xAF (&0x1)
+}
+u8 antswctl5g {
+ srom 8-10 0xB0 (&0xF8, >>3)
+}
+u8 triso5g {
+ srom 8-10 0xB0 (&0x7)
+}
+u8 pdetrange5g {
+ srom 8-10 0xB1 (&0xF8, >>3)
+}
+u8 extpagain5g {
+ srom 8-10 0xB1 (&0x6, >>1)
+}
+u8 tssipos5g {
+ srom 8-10 0xB1 (&0x1)
+}
+
+# FEM config
+u8 femctrl {
+ sfmt decimal
+ srom >= 11 0xAA (&0xF8, >>3)
+}
+u8 papdcap2g {
+ sfmt decimal
+ srom >= 11 0xAA (&0x4, >>2)
+}
+u8 tworangetssi2g {
+ sfmt decimal
+ srom >= 11 0xAA (&0x2, >>1)
+}
+u8 pdgain2g {
+ sfmt decimal
+ srom >= 11 u16 0xAA (&0x1F0, >>4)
+}
+u8 epagain2g {
+ sfmt decimal
+ srom >= 11 0xAB (&0xE, >>1)
+}
+u8 tssiposslope2g {
+ sfmt decimal
+ srom >= 11 0xAB (&0x1)
+}
+u8 gainctrlsph {
+ sfmt decimal
+ srom >= 11 0xAC (&0xF8, >>3)
+}
+u8 papdcap5g {
+ sfmt decimal
+ srom >= 11 0xAC (&0x4, >>2)
+}
+u8 tworangetssi5g {
+ sfmt decimal
+ srom >= 11 0xAC (&0x2, >>1)
+}
+u8 pdgain5g {
+ sfmt decimal
+ srom >= 11 u16 0xAC (&0x1F0, >>4)
+}
+u8 epagain5g {
+ sfmt decimal
+ srom >= 11 0xAD (&0xE, >>1)
+}
+u8 tssiposslope5g {
+ sfmt decimal
+ srom >= 11 0xAD (&0x1)
+}
+
+# LED duty cycle
+u8[2] leddc {
+ sfmt led_dc
+ all1 ignore
+ srom 3 0x7C
+ srom 4 0x5A
+ srom 5-7 0x5A
+ srom 8-10 0x9A
+ srom >= 11 0x9E
+}
+
+# LED set
+u8 ledbh0 {
+ all1 ignore
+ srom 1-3 0x65
+ srom 4 0x57
+ srom 5-7 0x77
+ srom 8-10 0x97
+ srom >= 11 0x9B
+}
+u8 ledbh1 {
+ all1 ignore
+ srom 1-3 0x64
+ srom 4 0x56
+ srom 5-7 0x76
+ srom 8-10 0x96
+ srom >= 11 0x9A
+}
+u8 ledbh2 {
+ all1 ignore
+ srom 1-3 0x67
+ srom 4 0x59
+ srom 5-7 0x79
+ srom 8-10 0x99
+ srom >= 11 0x9D
+}
+u8 ledbh3 {
+ all1 ignore
+ srom 1-3 0x66
+ srom 4 0x58
+ srom 5-7 0x78
+ srom 8-10 0x98
+ srom >= 11 0x9C
+}
+
+# 2 bytes total
+# Additional power offset for Legacy Dup40 transmissions.
+# Applied in addition to legofdmbw20ulXpo, X=2g, 5gl, 5gm, or 5gh.
+# LSB nibble: 2G band, MSB nibble: 5G band high subband.
+# leg40dup5ghpo, leg40dup5gmpo, leg40dup5glpo, leg40dup2gpo
+#
+u16 legofdm40duppo {
+ srom 9-10 0x196
+}
+
+# 4 bytes each
+# OFDM power offsets for 20 MHz Legacy rates
+# (54, 48, 36, 24, 18, 12, 9, 6 Mbps)
+# legofdmbw202gpo legofdmbw20ul2gpo
+#
+u32 legofdmbw202gpo {
+ srom 9-10 0x144
+}
+u32 legofdmbw20ul2gpo {
+ srom 9-10 0x148
+}
+
+# 4 bytes each
+# 5G band: OFDM power offsets for 20 MHz Legacy rates
+# (54, 48, 36, 24, 18, 12, 9, 6 Mbps)
+# low subband : legofdmbw205glpo legofdmbw20ul2glpo
+# mid subband :legofdmbw205gmpo legofdmbw20ul2gmpo
+# high subband :legofdmbw205ghpo legofdmbw20ul2ghpo
+#
+u32 legofdmbw205glpo {
+ srom 9-10 0x14C
+}
+u32 legofdmbw20ul5glpo {
+ srom 9-10 0x150
+}
+u32 legofdmbw205gmpo {
+ srom 9-10 0x154
+}
+u32 legofdmbw20ul5gmpo {
+ srom 9-10 0x158
+}
+u32 legofdmbw205ghpo {
+ srom 9-10 0x15C
+}
+u32 legofdmbw20ul5ghpo {
+ srom 9-10 0x160
+}
+
+# mac addr override for the standard CIS LAN_NID
+u8[6] macaddr {
+ sfmt macaddr
+ srom 3 u8 0x4B, u8 0x4A, u8 0x4D, u8 0x4C, u8 0x4F, u8 0x4E
+ srom 4 u8 0x4D, u8 0x4C, u8 0x4F, u8 0x4E, u8 0x51, u8 0x50
+ srom 5-7 u8 0x53, u8 0x52, u8 0x55, u8 0x54, u8 0x57, u8 0x56
+ srom 8-10 u8 0x8D, u8 0x8C, u8 0x8F, u8 0x8E, u8 0x91, u8 0x90
+ srom >= 11 u8 0x91, u8 0x90, u8 0x93, u8 0x92, u8 0x95, u8 0x94
+}
+
+# 4 bytes each
+# mcs 0-7 power-offset. LSB nibble: m0, MSB nibble: m7
+# mcsbw202gpo mcsbw20ul2gpo mcsbw402gpo
+#
+u32 mcsbw202gpo {
+ srom 9-10 0x164
+ srom >= 11 0x154
+}
+u32 mcsbw20ul2gpo {
+ srom 9-10 0x168
+}
+u32 mcsbw402gpo {
+ srom 9-10 0x16C
+ srom >= 11 0x158
+}
+
+# 4 bytes each
+# 5G high subband mcs 0-7 power-offset.
+# LSB nibble: m0, MSB nibble: m7
+# mcsbw205ghpo mcsbw20ul5ghpo mcsbw405ghpo
+#
+u32 mcsbw205ghpo {
+ srom 9-10 0x188
+ srom >= 11 0x180
+}
+u32 mcsbw20ul5ghpo {
+ srom 9-10 0x18C
+}
+u32 mcsbw405ghpo {
+ srom 9-10 0x190
+ srom >= 11 0x184
+}
+
+# 4 bytes each
+# 5G low subband mcs 0-7 power-offset.
+# LSB nibble: m0, MSB nibble: m7
+# mcsbw205glpo mcsbw20ul5glpo mcsbw405glpo
+#
+u32 mcsbw205glpo {
+ srom 9-10 0x170
+ srom >= 11 0x160
+}
+u32 mcsbw20ul5glpo {
+ srom 9-10 0x174
+}
+u32 mcsbw405glpo {
+ srom 9-10 0x178
+ srom >= 11 0x164
+}
+
+# 4 bytes each
+# 5G mid subband mcs 0-7 power-offset.
+# LSB nibble: m0, MSB nibble: m7
+# mcsbw205gmpo mcsbw20ul5gmpo mcsbw405gmpo
+#
+u32 mcsbw205gmpo {
+ srom 9-10 0x17C
+ srom >= 11 0x170
+}
+u32 mcsbw20ul5gmpo {
+ srom 9-10 0x180
+}
+u32 mcsbw405gmpo {
+ srom 9-10 0x184
+ srom >= 11 0x174
+}
+
+# 2 bytes total
+# mcs-32 power offset for each band/subband.
+# LSB nibble: 2G band, MSB nibble:
+# mcs322ghpo, mcs325gmpo, mcs325glpo, mcs322gpo
+#
+u16 mcs32po {
+ srom 9-10 0x194
+}
+
+u8 measpower {
+ srom 8-10 0xB4 (&0xFE, >>1)
+ srom >= 11 0xB0 (&0xFE, >>1)
+}
+u8 measpower1 {
+ srom 8-10 0xBF (&0x7F)
+ srom >= 11 0xBB (&0x7F)
+}
+u8 measpower2 {
+ srom 8-10 u16 0xBE (&0x3F80, >>7)
+ srom >= 11 u16 0xBA (&0x3F80, >>7)
+}
+u16 rawtempsense {
+ srom 8-10 0xB4 (&0x1FF)
+ srom >= 11 0xB0 (&0x1FF)
+}
+
+u8 noiselvl2ga0 {
+ sfmt decimal
+ srom 8-10 0x1AB (&0x1F)
+ srom >= 11 0x1BD (&0x1F)
+}
+u8 noiselvl2ga1 {
+ sfmt decimal
+ srom 8-10 u16 0x1AA (&0x3E0, >>5)
+ srom >= 11 u16 0x1BC (&0x3E0, >>5)
+}
+u8 noiselvl2ga2 {
+ sfmt decimal
+ srom 8-10 0x1AA (&0x7C, >>2)
+ srom >= 11 0x1BC (&0x7C, >>2)
+}
+u8[4] noiselvl5ga0 {
+ sfmt decimal
+ srom >= 11 u8 0x1BF (&0x1F), u8 0x1C1 (&0x1F), u8 0x1C3 (&0x1F), u8 0x1C5 (&0x1F)
+}
+u8[4] noiselvl5ga1 {
+ sfmt decimal
+ srom >= 11 u16[4] 0x1BE (&0x3E0, >>5)
+}
+u8[4] noiselvl5ga2 {
+ sfmt decimal
+ srom >= 11 u8 0x1BE (&0x7C, >>2), u8 0x1C0 (&0x7C, >>2), u8 0x1C2 (&0x7C, >>2), u8 0x1C4 (&0x7C, >>2)
+}
+
+# paparambwver
+u8 paparambwver {
+ sfmt decimal
+ srom >= 11 0x190 (&0xF0, >>4)
+}
+
+# PA parameters: 8 (sromrev == 1)
+# or 9 (sromrev > 1) bytes
+#
+u16 pa0b0 {
+ sfmt decimal
+ srom 1-3 0x5E
+ srom 8-10 0xC2
+}
+u16 pa0b1 {
+ sfmt decimal
+ srom 1-3 0x60
+ srom 8-10 0xC4
+}
+u16 pa0b2 {
+ sfmt decimal
+ srom 1-3 0x62
+ srom 8-10 0xC6
+}
+u8 pa0itssit {
+ sfmt decimal
+ srom 1-3 0x71
+ srom 8-10 0xC0
+}
+u8 pa0maxpwr {
+ sfmt decimal
+ srom 1-3 0x69
+ srom 8-10 0xC1
+}
+u8 opo {
+ srom 2-3 0x79
+ srom 8-10 0x143
+}
+
+# 5G PA params
+u16 pa1b0 {
+ sfmt decimal
+ srom 1-3 0x6A
+ srom 8-10 0xCC
+}
+u16 pa1b1 {
+ sfmt decimal
+ srom 1-3 0x6C
+ srom 8-10 0xCE
+}
+u16 pa1b2 {
+ sfmt decimal
+ srom 1-3 0x6E
+ srom 8-10 0xD0
+}
+u16 pa1lob0 {
+ sfmt decimal
+ srom 2-3 0x3C
+ srom 8-10 0xD2
+}
+u16 pa1lob1 {
+ sfmt decimal
+ srom 2-3 0x3E
+ srom 8-10 0xD4
+}
+u16 pa1lob2 {
+ sfmt decimal
+ srom 2-3 0x40
+ srom 8-10 0xD6
+}
+u16 pa1hib0 {
+ sfmt decimal
+ srom 2-3 0x42
+ srom 8-10 0xD8
+}
+u16 pa1hib1 {
+ sfmt decimal
+ srom 2-3 0x44
+ srom 8-10 0xDA
+}
+u16 pa1hib2 {
+ sfmt decimal
+ srom 2-3 0x46
+ srom 8-10 0xDC
+}
+u8 pa1itssit {
+ sfmt decimal
+ srom 1-3 0x70
+ srom 8-10 0xC8
+}
+u8 pa1maxpwr {
+ sfmt decimal
+ srom 1-3 0x68
+ srom 8-10 0xC9
+}
+u8 pa1lomaxpwr {
+ sfmt decimal
+ srom 2-3 0x3A
+ srom 8-10 0xCA
+}
+u8 pa1himaxpwr {
+ sfmt decimal
+ srom 2-3 0x3B
+ srom 8-10 0xCB
+}
+
+u16 pdoffset40ma0 {
+ srom >= 11 0xCA
+}
+u16 pdoffset40ma1 {
+ srom >= 11 0xCC
+}
+u16 pdoffset40ma2 {
+ srom >= 11 0xCE
+}
+u16 pdoffset80ma0 {
+ srom >= 11 0xD0
+}
+u16 pdoffset80ma1 {
+ srom >= 11 0xD2
+}
+u16 pdoffset80ma2 {
+ srom >= 11 0xD4
+}
+
+u8 pdoffset2g40ma0 {
+ srom >= 11 0xC9 (&0xF)
+}
+u8 pdoffset2g40ma1 {
+ srom >= 11 0xC9 (&0xF0, >>4)
+}
+u8 pdoffset2g40ma2 {
+ srom >= 11 0xC8 (&0xF)
+}
+u8 pdoffset2g40mvalid {
+ srom >= 11 0xC8 (&0x80, >>7)
+}
+
+# 40Mhz channel 2g/5g power offset
+u16 bw40po {
+ srom 4-7 0x18E
+ srom 8 0x196
+}
+
+# 40Mhz channel dup 2g/5g power offset
+u16 bwduppo {
+ srom 4-7 0x190
+ srom 8 0x198
+}
+
+# cck2g/ofdm2g/ofdm5g power offset
+u16 cck2gpo {
+ srom 4-7 0x138
+ srom 8 0x140
+}
+u32 ofdm2gpo {
+ srom 4-7 0x13A
+ srom 8 0x142
+}
+u32 ofdm5gpo {
+ srom 4-7 0x13E
+ srom 8 0x146
+}
+u32 ofdm5glpo {
+ srom 4-7 0x142
+ srom 8 0x14A
+}
+u32 ofdm5ghpo {
+ srom 4-7 0x146
+ srom 8 0x14E
+}
+
+# cdd2g/5g power offset
+u16 cddpo {
+ srom 4-7 0x18A
+ srom 8 0x192
+}
+
+# mcs2g power offset
+u16 mcs2gpo0 {
+ srom 4-7 0x14A
+ srom 8 0x152
+}
+u16 mcs2gpo1 {
+ srom 4-7 0x14C
+ srom 8 0x154
+}
+u16 mcs2gpo2 {
+ srom 4-7 0x14E
+ srom 8 0x156
+}
+u16 mcs2gpo3 {
+ srom 4-7 0x150
+ srom 8 0x158
+}
+u16 mcs2gpo4 {
+ srom 4-7 0x152
+ srom 8 0x15A
+}
+u16 mcs2gpo5 {
+ srom 4-7 0x154
+ srom 8 0x15C
+}
+u16 mcs2gpo6 {
+ srom 4-7 0x156
+ srom 8 0x15E
+}
+u16 mcs2gpo7 {
+ srom 4-7 0x158
+ srom 8 0x160
+}
+
+# mcs5g low-high band power offset
+u16 mcs5glpo0 {
+ srom 4-7 0x16A
+ srom 8 0x172
+}
+u16 mcs5glpo1 {
+ srom 4-7 0x16C
+ srom 8 0x174
+}
+u16 mcs5glpo2 {
+ srom 4-7 0x16E
+ srom 8 0x176
+}
+u16 mcs5glpo3 {
+ srom 4-7 0x170
+ srom 8 0x178
+}
+u16 mcs5glpo4 {
+ srom 4-7 0x172
+ srom 8 0x17A
+}
+u16 mcs5glpo5 {
+ srom 4-7 0x174
+ srom 8 0x17C
+}
+u16 mcs5glpo6 {
+ srom 4-7 0x176
+ srom 8 0x17E
+}
+u16 mcs5glpo7 {
+ srom 4-7 0x178
+ srom 8 0x180
+}
+u16 mcs5ghpo0 {
+ srom 4-7 0x17A
+ srom 8 0x182
+}
+u16 mcs5ghpo1 {
+ srom 4-7 0x17C
+ srom 8 0x184
+}
+u16 mcs5ghpo2 {
+ srom 4-7 0x17E
+ srom 8 0x186
+}
+u16 mcs5ghpo3 {
+ srom 4-7 0x180
+ srom 8 0x188
+}
+u16 mcs5ghpo4 {
+ srom 4-7 0x182
+ srom 8 0x18A
+}
+u16 mcs5ghpo5 {
+ srom 4-7 0x184
+ srom 8 0x18C
+}
+u16 mcs5ghpo6 {
+ srom 4-7 0x186
+ srom 8 0x18E
+}
+u16 mcs5ghpo7 {
+ srom 4-7 0x188
+ srom 8 0x190
+}
+
+# mcs5g mid band power offset
+u16 mcs5gpo0 {
+ srom 4-7 0x15A
+ srom 8 0x162
+}
+u16 mcs5gpo1 {
+ srom 4-7 0x15C
+ srom 8 0x164
+}
+u16 mcs5gpo2 {
+ srom 4-7 0x15E
+ srom 8 0x166
+}
+u16 mcs5gpo3 {
+ srom 4-7 0x160
+ srom 8 0x168
+}
+u16 mcs5gpo4 {
+ srom 4-7 0x162
+ srom 8 0x16A
+}
+u16 mcs5gpo5 {
+ srom 4-7 0x164
+ srom 8 0x16C
+}
+u16 mcs5gpo6 {
+ srom 4-7 0x166
+ srom 8 0x16E
+}
+u16 mcs5gpo7 {
+ srom 4-7 0x168
+ srom 8 0x170
+}
+
+# stbc2g/5g power offset
+u16 stbcpo {
+ srom 4-7 0x18C
+ srom 8 0x194
+}
+
+u8 regrev {
+ srom 3 0x78
+ srom 4 0x55
+ srom 5-7 0x47
+ srom 8-10 0x95
+ srom >= 11 0x99
+}
+
+# 4328 2G RSSI mid pt sel & board switch arch,
+# 2 bytes, rev 3.
+#
+u8 rssismf2g {
+ srom 3 0x51 (&0xF)
+ srom 8-10 0xA5 (&0xF)
+}
+u8 rssismc2g {
+ srom 3 0x51 (&0xF0, >>4)
+ srom 8-10 0xA5 (&0xF0, >>4)
+}
+u8 rssisav2g {
+ srom 3 0x50 (&0x7)
+ srom 8-10 0xA4 (&0x7)
+}
+u8 bxa2g {
+ srom 3 0x50 (&0x18, >>3)
+ srom 8-10 0xA4 (&0x18, >>3)
+}
+
+# 4328 5G RSSI mid pt sel & board switch arch,
+# 2 bytes, rev 3.
+#
+u8 rssismf5g {
+ srom 3 0x53 (&0xF)
+ srom 8-10 0xA7 (&0xF)
+}
+u8 rssismc5g {
+ srom 3 0x53 (&0xF0, >>4)
+ srom 8-10 0xA7 (&0xF0, >>4)
+}
+u8 rssisav5g {
+ srom 3 0x52 (&0x7)
+ srom 8-10 0xA6 (&0x7)
+}
+u8 bxa5g {
+ srom 3 0x52 (&0x18, >>3)
+ srom 8-10 0xA6 (&0x18, >>3)
+}
+
+u8 rxgainerr2ga0 {
+ srom 8-10 0x19B (&0x3F)
+ srom >= 11 0x1C7 (&0x3F)
+}
+u8 rxgainerr2ga1 {
+ srom 8-10 u16 0x19A (&0x7C0, >>6)
+ srom >= 11 u16 0x1C6 (&0x7C0, >>6)
+}
+u8 rxgainerr2ga2 {
+ srom 8-10 0x19A (&0xF8, >>3)
+ srom >= 11 0x1C6 (&0xF8, >>3)
+}
+u8[4] rxgainerr5ga0 {
+ srom >= 11 u8 0x1C9 (&0x3F), u8 0x1CB (&0x3F), u8 0x1CD (&0x3F), u8 0x1CF (&0x3F)
+}
+u8[4] rxgainerr5ga1 {
+ srom >= 11 u16[4] 0x1C8 (&0x7C0, >>6)
+}
+u8[4] rxgainerr5ga2 {
+ srom >= 11 u8 0x1C8 (&0xF8, >>3), u8 0x1CA (&0xF8, >>3), u8 0x1CC (&0xF8, >>3), u8 0x1CE (&0xF8, >>3)
+}
+u8 rxgainerr5gha0 {
+ srom 8-10 0x1A1 (&0x3F)
+}
+u8 rxgainerr5gha1 {
+ srom 8-10 u16 0x1A0 (&0x7C0, >>6)
+}
+u8 rxgainerr5gha2 {
+ srom 8-10 0x1A0 (&0xF8, >>3)
+}
+u8 rxgainerr5gla0 {
+ srom 8-10 0x19D (&0x3F)
+}
+u8 rxgainerr5gla1 {
+ srom 8-10 u16 0x19C (&0x7C0, >>6)
+}
+u8 rxgainerr5gla2 {
+ srom 8-10 0x19C (&0xF8, >>3)
+}
+u8 rxgainerr5gma0 {
+ srom 8-10 0x19F (&0x3F)
+}
+u8 rxgainerr5gma1 {
+ srom 8-10 u16 0x19E (&0x7C0, >>6)
+}
+u8 rxgainerr5gma2 {
+ srom 8-10 0x19E (&0xF8, >>3)
+}
+u8 rxgainerr5gua0 {
+ srom 8-10 0x1A3 (&0x3F)
+}
+u8 rxgainerr5gua1 {
+ srom 8-10 u16 0x1A2 (&0x7C0, >>6)
+}
+u8 rxgainerr5gua2 {
+ srom 8-10 0x1A2 (&0xF8, >>3)
+}
+
+# 4328 2G RX power offset
+i8 rxpo2g {
+ sfmt decimal
+ srom 3 0x5B
+ srom 8-10 0xAD
+}
+
+# 4328 5G RX power offset
+i8 rxpo5g {
+ sfmt decimal
+ srom 3 0x5A
+ srom 8-10 0xAC
+}
+
+u16 subband5gver {
+ srom 8-10 u8 0x1A5 (&0x7)
+ srom >= 11 0xD6
+}
+
+# 2 bytes
+# byte1 tempthresh
+# byte2 period(msb 4 bits) | hysterisis(lsb 4 bits)
+#
+u8 tempthresh {
+ srom 8-10 0xB2
+ srom >= 11 0xAE
+}
+u8 temps_period {
+ sfmt decimal
+ srom 8-10 0xBC (&0xF)
+ srom >= 11 0xB8 (&0xF)
+}
+u8 temps_hysteresis {
+ sfmt decimal
+ srom 8-10 0xBC (&0xF0, >>4)
+ srom >= 11 0xB8 (&0xF0, >>4)
+}
+u8 tempoffset {
+ sfmt decimal
+ srom 8-10 0xB3
+ srom >= 11 0xAF
+}
+u8 tempsense_slope {
+ srom 8-10 0xB7
+ srom >= 11 0xB3
+}
+u8 tempcorrx {
+ srom 8-10 0xB6 (&0xFC, >>2)
+ srom >= 11 0xB2 (&0xFC, >>2)
+}
+u8 tempsense_option {
+ srom 8-10 0xB6 (&0x3)
+ srom >= 11 0xB2 (&0x3)
+}
+u8 phycal_tempdelta {
+ sfmt decimal
+ srom 8-10 0xBD
+ srom >= 11 0xB9
+}
+
+# 4328 2G TR isolation, 1 byte
+u8 tri2g {
+ srom 3 0x55
+ srom 8-10 0xA9
+}
+
+# 4328 5G TR isolation, 3 bytes
+u8 tri5gl {
+ srom 3 0x57
+ srom 8-10 0xAB
+}
+u8 tri5g {
+ srom 3 0x54
+ srom 8-10 0xA8
+}
+u8 tri5gh {
+ srom 3 0x56
+ srom 8-10 0xAA
+}
+
+# phy txbf rpcalvars
+u16 rpcal2g {
+ srom >= 11 0x16C
+}
+u16 rpcal5gb0 {
+ srom >= 11 0x16E
+}
+u16 rpcal5gb1 {
+ srom >= 11 0x17C
+}
+u16 rpcal5gb2 {
+ srom >= 11 0x17E
+}
+u16 rpcal5gb3 {
+ srom >= 11 0x18C
+}
+
+# Crystal frequency in kilohertz
+u32 xtalfreq {
+ sfmt decimal
+ srom >= 11 u16 0xB4
+}
+
+# N-PHY tx power workaround
+u8 txpid2ga0 {
+ srom 4-7 0x63
+}
+u8 txpid2ga1 {
+ srom 4-7 0x62
+}
+u8 txpid2ga2 {
+ srom 4-7 0x65
+}
+u8 txpid2ga3 {
+ srom 4-7 0x64
+}
+u8 txpid5ga0 {
+ srom 4-7 0x67
+}
+u8 txpid5ga1 {
+ srom 4-7 0x66
+}
+u8 txpid5ga2 {
+ srom 4-7 0x69
+}
+u8 txpid5ga3 {
+ srom 4-7 0x68
+}
+u8 txpid5gha0 {
+ srom 4-7 0x6F
+}
+u8 txpid5gha1 {
+ srom 4-7 0x6E
+}
+u8 txpid5gha2 {
+ srom 4-7 0x71
+}
+u8 txpid5gha3 {
+ srom 4-7 0x70
+}
+u8 txpid5gla0 {
+ srom 4-7 0x6B
+}
+u8 txpid5gla1 {
+ srom 4-7 0x6A
+}
+u8 txpid5gla2 {
+ srom 4-7 0x6D
+}
+u8 txpid5gla3 {
+ srom 4-7 0x6C
+}
+
+u16 cckPwrOffset {
+ srom 10 0x1B4
+}
+u8[6] et1macaddr {
+ sfmt macaddr
+ srom 0-2 u8 0x55, u8 0x54, u8 0x57, u8 0x56, u8 0x59, u8 0x58
+}
+u8 eu_edthresh2g {
+ srom 8 0x1A9
+ srom 9 0x199
+ srom 10 0x199
+ srom 11 0x1D1
+}
+u8 eu_edthresh5g {
+ srom 8 0x1A8
+ srom 9 0x198
+ srom 10 0x198
+ srom 11 0x1D0
+}
+u8 freqoffset_corr {
+ srom 8-10 0xB9 (&0xF)
+}
+u8 hw_iqcal_en {
+ srom 8-10 0xB9 (&0x20, >>5)
+}
+u8[6] il0macaddr {
+ sfmt macaddr
+ srom 0-2 u8 0x49, u8 0x48, u8 0x51, u8 0x50, u8 0x53, u8 0x52
+}
+u8 iqcal_swp_dis {
+ srom 8-10 0xB9 (&0x10, >>4)
+}
+
+u8 noisecaloffset {
+ srom 8-9 0x1B5
+}
+u8 noisecaloffset5g {
+ srom 8-9 0x1B4
+}
+u8 noiselvl5gha0 {
+ srom 8-10 0x1B1 (&0x1F)
+}
+u8 noiselvl5gha1 {
+ srom 8-10 u16 0x1B0 (&0x3E0, >>5)
+}
+u8 noiselvl5gha2 {
+ srom 8-10 0x1B0 (&0x7C, >>2)
+}
+u8 noiselvl5gla0 {
+ srom 8-10 0x1AD (&0x1F)
+}
+u8 noiselvl5gla1 {
+ srom 8-10 u16 0x1AC (&0x3E0, >>5)
+}
+u8 noiselvl5gla2 {
+ srom 8-10 0x1AC (&0x7C, >>2)
+}
+u8 noiselvl5gma0 {
+ srom 8-10 0x1AF (&0x1F)
+}
+u8 noiselvl5gma1 {
+ srom 8-10 u16 0x1AE (&0x3E0, >>5)
+}
+u8 noiselvl5gma2 {
+ srom 8-10 0x1AE (&0x7C, >>2)
+}
+u8 noiselvl5gua0 {
+ srom 8-10 0x1B3 (&0x1F)
+}
+u8 noiselvl5gua1 {
+ srom 8-10 u16 0x1B2 (&0x3E0, >>5)
+}
+u8 noiselvl5gua2 {
+ srom 8-10 0x1B2 (&0x7C, >>2)
+}
+
+u8 pcieingress_war {
+ srom 8-10 0x1A7 (&0xF)
+}
+
+u8 pdoffsetcckma0 {
+ srom >= 11 0x18F (&0xF)
+}
+u8 pdoffsetcckma1 {
+ srom >= 11 0x18F (&0xF0, >>4)
+}
+u8 pdoffsetcckma2 {
+ srom >= 11 0x18E (&0xF)
+}
+
+u8 sar2g {
+ srom 9-10 0x1A9
+ srom >= 11 0x1BB
+}
+u8 sar5g {
+ srom 9-10 0x1A8
+ srom >= 11 0x1BA
+}
+
+u16 subvid {
+ srom >= 2 0x6
+}
+
+u32[5] swctrlmap_2g {
+ srom 10 u32[4] 0x1B8, u16 0x1C8
+}
+
+u16 tssifloor2g {
+ srom >= 11 0xBE (&0x3FF)
+}
+u16[4] tssifloor5g {
+ srom >= 11 0xC0 (&0x3FF)
+}
+
+u8 txidxcap2g {
+ srom >= 11 u16 0x1A8 (&0xFF0, >>4)
+}
+u8 txidxcap5g {
+ srom >= 11 u16 0x1AC (&0xFF0, >>4)
+}
+
+#
+# Any variables defined within a `struct` block will be interpreted relative to
+# the provided array of SPROM base addresses; this is used to define
+# a common layout defined at the given base addresses.
+#
+# To produce SPROM variable names matching those used in the Broadcom HND
+# ASCII 'key=value\0' NVRAM, the index number of the variable's
+# struct instance will be appended (e.g., given a variable of noiselvl5ga, the
+# generated variable instances will be named noiselvl5ga0, noiselvl5ga1,
+# noiselvl5ga2, noiselvl5ga3 ...)
+#
+
+# PHY chain[0-4] parameters
+struct phy_chains[] {
+ srom 4-7 [0x080, 0x0AE, 0x0DC, 0x10A]
+ srom 8-10 [0x0C0, 0x0E0, 0x100, 0x120]
+ srom >= 11 [0x0D8, 0x100, 0x128]
+
+ # AC-PHY PA parameters
+ u8[4] maxp5ga {
+ srom 4-7 u8 0xB
+ srom 8-10 u8 0x9
+ srom >= 11 u8 0xD, u8 0xC, u8 0xF, u8 0xE
+ }
+ u16[3] pa2ga {
+ srom >= 11 0x2
+ }
+ u8 maxp2ga {
+ srom 4-7 0x1
+ srom 8-10 0x1
+ srom >= 11 0x1
+ }
+ u16[12] pa5ga {
+ srom >= 11 0x10
+ }
+
+ # AC-PHY rxgains
+ u8 rxgains5ghtrelnabypa {
+ srom >= 11 0x8 (&0x80, >>7)
+ }
+ u8 rxgains5ghelnagaina {
+ srom >= 11 0x8 (&0x7)
+ }
+ u8 rxgains5gelnagaina {
+ srom >= 11 0xA (&0x7)
+ }
+ u8 rxgains5gmtrelnabypa {
+ srom >= 11 0x9 (&0x80, >>7)
+ }
+ u8 rxgains2gtrelnabypa {
+ srom >= 11 0xB (&0x80, >>7)
+ }
+ u8 rxgains5gmtrisoa {
+ srom >= 11 0x9 (&0x78, >>3)
+ }
+ u8 rxgains5gmelnagaina {
+ srom >= 11 0x9 (&0x7)
+ }
+ u8 rxgains2gelnagaina {
+ srom >= 11 0xB (&0x7)
+ }
+ u8 rxgains5gtrisoa {
+ srom >= 11 0xA (&0x78, >>3)
+ }
+ u8 rxgains5gtrelnabypa {
+ srom >= 11 0xA (&0x80, >>7)
+ }
+ u8 rxgains2gtrisoa {
+ srom >= 11 0xB (&0x78, >>3)
+ }
+ u8 rxgains5ghtrisoa {
+ srom >= 11 0x8 (&0x78, >>3)
+ }
+
+ # 11n PA parameters
+ u16 pa5gw2a {
+ srom 4-7 0x12
+ srom 8-10 0x10
+ }
+ u16 pa5ghw1a {
+ srom 4-7 0x20
+ srom 8-10 0x1A
+ }
+ u16 pa5glw3a {
+ srom 4-7 0x1C
+ }
+ u16 pa5glw1a {
+ srom 4-7 0x18
+ srom 8-10 0x14
+ }
+ u16 pa5gw1a {
+ srom 4-7 0x10
+ srom 8-10 0xE
+ }
+ u16 pa5glw0a {
+ srom 4-7 0x16
+ srom 8-10 0x12
+ }
+ u16 pa5gw3a {
+ srom 4-7 0x14
+ }
+ u16 pa5glw2a {
+ srom 4-7 0x1A
+ srom 8-10 0x16
+ }
+ u16 pa5ghw3a {
+ srom 4-7 0x24
+ }
+ u16 pa5gw0a {
+ srom 4-7 0xE
+ srom 8-10 0xC
+ }
+ u8 maxp5gha {
+ srom 4-7 0xD
+ srom 8-10 0xB
+ }
+ u16 pa5ghw2a {
+ srom 4-7 0x22
+ srom 8-10 0x1C
+ }
+ u16 pa5ghw0a {
+ srom 4-7 0x1E
+ srom 8-10 0x18
+ }
+ u16 pa2gw3a {
+ srom 4-7 0x8
+ }
+ u16 pa2gw2a {
+ srom 4-7 0x6
+ srom 8-10 0x6
+ }
+ u16 pa2gw1a {
+ srom 4-7 0x4
+ srom 8-10 0x4
+ }
+ u16 pa2gw0a {
+ srom 4-7 0x2
+ srom 8-10 0x2
+ }
+ u8 maxp5gla {
+ srom 4-7 0xC
+ srom 8-10 0xA
+ }
+ u8 itt5ga {
+ srom 4-7 0xA
+ srom 8-10 0x8
+ }
+ u8 itt2ga {
+ srom 4-7 0x0
+ srom 8-10 0x0
+ }
+}
diff --git a/sys/dev/bhnd/nvram/nvram_subr.c b/sys/dev/bhnd/nvram/nvram_subr.c
new file mode 100644
index 0000000..8465af8
--- /dev/null
+++ b/sys/dev/bhnd/nvram/nvram_subr.c
@@ -0,0 +1,149 @@
+/*-
+ * Copyright (c) 2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include "bhnd_nvram_map_data.h"
+
+/*
+ * CRC-8 lookup table used to checksum SPROM and NVRAM data via
+ * bhnd_nvram_crc8().
+ *
+ * Generated with following parameters:
+ * polynomial: CRC-8 (x^8 + x^7 + x^6 + x^4 + x^2 + 1)
+ * reflected bits: false
+ * reversed: true
+ */
+const uint8_t bhnd_nvram_crc8_tab[] = {
+ 0x00, 0xf7, 0xb9, 0x4e, 0x25, 0xd2, 0x9c, 0x6b, 0x4a, 0xbd, 0xf3,
+ 0x04, 0x6f, 0x98, 0xd6, 0x21, 0x94, 0x63, 0x2d, 0xda, 0xb1, 0x46,
+ 0x08, 0xff, 0xde, 0x29, 0x67, 0x90, 0xfb, 0x0c, 0x42, 0xb5, 0x7f,
+ 0x88, 0xc6, 0x31, 0x5a, 0xad, 0xe3, 0x14, 0x35, 0xc2, 0x8c, 0x7b,
+ 0x10, 0xe7, 0xa9, 0x5e, 0xeb, 0x1c, 0x52, 0xa5, 0xce, 0x39, 0x77,
+ 0x80, 0xa1, 0x56, 0x18, 0xef, 0x84, 0x73, 0x3d, 0xca, 0xfe, 0x09,
+ 0x47, 0xb0, 0xdb, 0x2c, 0x62, 0x95, 0xb4, 0x43, 0x0d, 0xfa, 0x91,
+ 0x66, 0x28, 0xdf, 0x6a, 0x9d, 0xd3, 0x24, 0x4f, 0xb8, 0xf6, 0x01,
+ 0x20, 0xd7, 0x99, 0x6e, 0x05, 0xf2, 0xbc, 0x4b, 0x81, 0x76, 0x38,
+ 0xcf, 0xa4, 0x53, 0x1d, 0xea, 0xcb, 0x3c, 0x72, 0x85, 0xee, 0x19,
+ 0x57, 0xa0, 0x15, 0xe2, 0xac, 0x5b, 0x30, 0xc7, 0x89, 0x7e, 0x5f,
+ 0xa8, 0xe6, 0x11, 0x7a, 0x8d, 0xc3, 0x34, 0xab, 0x5c, 0x12, 0xe5,
+ 0x8e, 0x79, 0x37, 0xc0, 0xe1, 0x16, 0x58, 0xaf, 0xc4, 0x33, 0x7d,
+ 0x8a, 0x3f, 0xc8, 0x86, 0x71, 0x1a, 0xed, 0xa3, 0x54, 0x75, 0x82,
+ 0xcc, 0x3b, 0x50, 0xa7, 0xe9, 0x1e, 0xd4, 0x23, 0x6d, 0x9a, 0xf1,
+ 0x06, 0x48, 0xbf, 0x9e, 0x69, 0x27, 0xd0, 0xbb, 0x4c, 0x02, 0xf5,
+ 0x40, 0xb7, 0xf9, 0x0e, 0x65, 0x92, 0xdc, 0x2b, 0x0a, 0xfd, 0xb3,
+ 0x44, 0x2f, 0xd8, 0x96, 0x61, 0x55, 0xa2, 0xec, 0x1b, 0x70, 0x87,
+ 0xc9, 0x3e, 0x1f, 0xe8, 0xa6, 0x51, 0x3a, 0xcd, 0x83, 0x74, 0xc1,
+ 0x36, 0x78, 0x8f, 0xe4, 0x13, 0x5d, 0xaa, 0x8b, 0x7c, 0x32, 0xc5,
+ 0xae, 0x59, 0x17, 0xe0, 0x2a, 0xdd, 0x93, 0x64, 0x0f, 0xf8, 0xb6,
+ 0x41, 0x60, 0x97, 0xd9, 0x2e, 0x45, 0xb2, 0xfc, 0x0b, 0xbe, 0x49,
+ 0x07, 0xf0, 0x9b, 0x6c, 0x22, 0xd5, 0xf4, 0x03, 0x4d, 0xba, 0xd1,
+ 0x26, 0x68, 0x9f
+};
+
+
+/**
+ * Return the size of type @p dt.
+ *
+ * @param dt NVRAM data type.
+ * @result the byte width of @p dt.
+ */
+size_t
+bhnd_nvram_type_width(bhnd_nvram_dt dt)
+{
+ switch (dt) {
+ case BHND_NVRAM_DT_INT8:
+ case BHND_NVRAM_DT_UINT8:
+ case BHND_NVRAM_DT_CHAR:
+ return (sizeof(uint8_t));
+
+ case BHND_NVRAM_DT_INT16:
+ case BHND_NVRAM_DT_UINT16:
+ return (sizeof(uint16_t));
+
+ case BHND_NVRAM_DT_INT32:
+ case BHND_NVRAM_DT_UINT32:
+ return (sizeof(uint32_t));
+ }
+
+ /* Quiesce gcc4.2 */
+ panic("bhnd nvram data type %u unknown", dt);
+}
+
+
+/**
+ * Return the variable definition for @p varname, if any.
+ *
+ * @param varname variable name
+ *
+ * @retval bhnd_nvram_var If a valid definition for @p varname is found.
+ * @retval NULL If no definition for @p varname is found.
+ */
+const struct bhnd_nvram_var *
+bhnd_nvram_var_defn(const char *varname)
+{
+ size_t min, mid, max;
+ int order;
+
+ /*
+ * Locate the requested variable using a binary search.
+ *
+ * The variable table is guaranteed to be sorted in lexicographical
+ * order (using the 'C' locale for collation rules)
+ */
+ min = 0;
+ mid = 0;
+ max = nitems(bhnd_nvram_vars) - 1;
+
+ while (max >= min) {
+ /* Select midpoint */
+ mid = (min + max) / 2;
+
+ /* Determine which side of the partition to search */
+ order = strcmp(bhnd_nvram_vars[mid].name, varname);
+ if (order < 0) {
+ /* Search upper partition */
+ min = mid + 1;
+ } else if (order > 0) {
+ /* Search lower partition */
+ max = mid - 1;
+ } else if (order == 0) {
+ /* Match found */
+ return (&bhnd_nvram_vars[mid]);
+ }
+ }
+
+ /* Not found */
+ return (NULL);
+}
diff --git a/sys/dev/bhnd/nvram/nvramvar.h b/sys/dev/bhnd/nvram/nvramvar.h
new file mode 100644
index 0000000..969cb50
--- /dev/null
+++ b/sys/dev/bhnd/nvram/nvramvar.h
@@ -0,0 +1,128 @@
+/*-
+ * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BHND_NVRAM_BHND_NVRAMVAR_H_
+#define _BHND_NVRAM_BHND_NVRAMVAR_H_
+
+/** NVRAM Primitive data types */
+typedef enum {
+ BHND_NVRAM_DT_UINT8 = 0, /**< unsigned 8-bit integer */
+ BHND_NVRAM_DT_UINT16 = 1, /**< unsigned 16-bit integer */
+ BHND_NVRAM_DT_UINT32 = 2, /**< unsigned 32-bit integer */
+ BHND_NVRAM_DT_INT8 = 3, /**< signed 8-bit integer */
+ BHND_NVRAM_DT_INT16 = 4, /**< signed 16-bit integer */
+ BHND_NVRAM_DT_INT32 = 5, /**< signed 32-bit integer */
+ BHND_NVRAM_DT_CHAR = 6, /**< ASCII char */
+} bhnd_nvram_dt;
+
+/** NVRAM data type string representations */
+typedef enum {
+ BHND_NVRAM_VFMT_HEX = 1, /**< hex format */
+ BHND_NVRAM_VFMT_DEC = 2, /**< decimal format */
+ BHND_NVRAM_VFMT_MACADDR = 3, /**< mac address (canonical form, hex octets,
+ separated with ':') */
+ BHND_NVRAM_VFMT_LEDDC = 4, /**< LED PWM duty-cycle (2 bytes -- on/off) */
+ BHND_NVRAM_VFMT_CCODE = 5 /**< count code format (2-3 ASCII chars, or hex string) */
+} bhnd_nvram_fmt;
+
+/** NVRAM variable flags */
+enum {
+ BHND_NVRAM_VF_ARRAY = (1<<0), /**< variable is an array */
+ BHND_NVRAM_VF_MFGINT = (1<<1), /**< mfg-internal variable; should not be externally visible */
+ BHND_NVRAM_VF_IGNALL1 = (1<<2) /**< hide variable if its value has all bits set. */
+};
+
+#define BHND_SPROMREV_MAX UINT8_MAX /**< maximum supported SPROM revision */
+
+/** SPROM revision compatibility declaration */
+struct bhnd_sprom_compat {
+ uint8_t first; /**< first compatible SPROM revision */
+ uint8_t last; /**< last compatible SPROM revision, or BHND_SPROMREV_MAX */
+};
+
+/** SPROM value descriptor */
+struct bhnd_sprom_offset {
+ uint16_t offset; /**< byte offset within SPROM */
+ bool cont:1; /**< value should be bitwise OR'd with the
+ * previous offset descriptor */
+ bhnd_nvram_dt type:7; /**< data type */
+ int8_t shift; /**< shift to be applied to the value */
+ uint32_t mask; /**< mask to be applied to the value(s) */
+};
+
+/** SPROM-specific variable definition */
+struct bhnd_sprom_var {
+ struct bhnd_sprom_compat compat; /**< sprom compatibility declaration */
+ const struct bhnd_sprom_offset *offsets; /**< offset descriptors */
+ size_t num_offsets; /**< number of offset descriptors */
+};
+
+/** NVRAM variable definition */
+struct bhnd_nvram_var {
+ const char *name; /**< variable name */
+ bhnd_nvram_dt type; /**< base data type */
+ bhnd_nvram_fmt fmt; /**< string format */
+ uint32_t flags; /**< BHND_NVRAM_VF_* flags */
+
+ const struct bhnd_sprom_var *sprom_descs; /**< SPROM-specific variable descriptors */
+ size_t num_sp_descs; /**< number of sprom descriptors */
+};
+
+size_t bhnd_nvram_type_width(bhnd_nvram_dt dt);
+const struct bhnd_nvram_var *bhnd_nvram_var_defn(const char *varname);
+
+/** Initial bhnd_nvram_crc8 value */
+#define BHND_NVRAM_CRC8_INITIAL 0xFF
+
+/** Valid CRC-8 checksum */
+#define BHND_NVRAM_CRC8_VALID 0x9F
+
+extern const uint8_t bhnd_nvram_crc8_tab[];
+
+/**
+ * Calculate CRC-8 over @p buf.
+ *
+ * @param buf input buffer
+ * @param size buffer size
+ * @param crc last computed crc, or BHND_NVRAM_CRC8_INITIAL
+ */
+static inline uint8_t
+bhnd_nvram_crc8(const void *buf, size_t size, uint8_t crc)
+{
+ const uint8_t *p = (const uint8_t *)buf;
+ while (size--)
+ crc = bhnd_nvram_crc8_tab[(crc ^ *p++)];
+
+ return (crc);
+}
+
+
+#endif /* _BHND_NVRAM_BHND_NVRAMVAR_H_ */ \ No newline at end of file
diff --git a/sys/dev/bhnd/siba/siba.c b/sys/dev/bhnd/siba/siba.c
index 4e0c34a..9fc87ff 100644
--- a/sys/dev/bhnd/siba/siba.c
+++ b/sys/dev/bhnd/siba/siba.c
@@ -216,6 +216,15 @@ siba_get_resource_list(device_t dev, device_t child)
return (&dinfo->resources);
}
+static device_t
+siba_find_hostb_device(device_t dev)
+{
+ struct siba_softc *sc = device_get_softc(dev);
+
+ /* This is set (or not) by the concrete siba driver subclass. */
+ return (sc->hostb_dev);
+}
+
static int
siba_reset_core(device_t dev, device_t child, uint16_t flags)
{
@@ -662,6 +671,7 @@ static device_method_t siba_methods[] = {
DEVMETHOD(bus_get_resource_list, siba_get_resource_list),
/* BHND interface */
+ DEVMETHOD(bhnd_bus_find_hostb_device, siba_find_hostb_device),
DEVMETHOD(bhnd_bus_reset_core, siba_reset_core),
DEVMETHOD(bhnd_bus_suspend_core, siba_suspend_core),
DEVMETHOD(bhnd_bus_get_port_count, siba_get_port_count),
diff --git a/sys/dev/bhnd/siba/siba_bhndb.c b/sys/dev/bhnd/siba/siba_bhndb.c
index 0e348b6..8a0e149 100644
--- a/sys/dev/bhnd/siba/siba_bhndb.c
+++ b/sys/dev/bhnd/siba/siba_bhndb.c
@@ -73,9 +73,12 @@ siba_bhndb_probe(device_t dev)
static int
siba_bhndb_attach(device_t dev)
{
+ struct siba_softc *sc;
const struct bhnd_chipid *chipid;
int error;
+ sc = device_get_softc(dev);
+
/* Enumerate our children. */
chipid = BHNDB_GET_CHIPID(device_get_parent(dev), dev);
if ((error = siba_add_children(dev, chipid)))
@@ -87,6 +90,9 @@ siba_bhndb_attach(device_t dev)
if (error)
return (error);
+ /* Ask our parent bridge to find the corresponding bridge core */
+ sc->hostb_dev = BHNDB_FIND_HOSTB_DEVICE(device_get_parent(dev), dev);
+
/* Call our superclass' implementation */
return (siba_attach(dev));
}
diff --git a/sys/dev/bhnd/siba/siba_subr.c b/sys/dev/bhnd/siba/siba_subr.c
index 555c603..e688006 100644
--- a/sys/dev/bhnd/siba/siba_subr.c
+++ b/sys/dev/bhnd/siba/siba_subr.c
@@ -187,6 +187,11 @@ siba_dinfo_get_port(struct siba_devinfo *dinfo, bhnd_port_type port_type,
return (NULL);
case BHND_PORT_AGENT:
return (NULL);
+ default:
+ printf("%s: unknown port_type (%d)\n",
+ __func__,
+ port_type);
+ return (NULL);
}
}
@@ -369,4 +374,4 @@ siba_parse_admatch(uint32_t am, uint32_t *addr, uint32_t *size)
}
return (0);
-} \ No newline at end of file
+}
diff --git a/sys/dev/bhnd/siba/sibavar.h b/sys/dev/bhnd/siba/sibavar.h
index 764ce23..f2b648a 100644
--- a/sys/dev/bhnd/siba/sibavar.h
+++ b/sys/dev/bhnd/siba/sibavar.h
@@ -145,6 +145,7 @@ struct siba_devinfo {
/** siba(4) per-instance state */
struct siba_softc {
struct bhnd_softc bhnd_sc; /**< bhnd state */
+ device_t hostb_dev; /**< host bridge core, or NULL */
};
#endif /* _SIBA_SIBAVAR_H_ */
diff --git a/sys/dev/bhnd/tools/bus_macro.sh b/sys/dev/bhnd/tools/bus_macro.sh
index de9e798..a11ed0c 100755..100644
--- a/sys/dev/bhnd/tools/bus_macro.sh
+++ b/sys/dev/bhnd/tools/bus_macro.sh
@@ -50,8 +50,8 @@ macro () {
echo -n ", (${i})"
done
echo ") : \\"
- echo -n " BHND_BUS_${bus_n}("
- echo "device_get_parent(rman_get_device((r)->res)), \\"
+ echo " BHND_BUS_${bus_n}( \\"
+ echo " device_get_parent(rman_get_device((r)->res)), \\"
echo -n " rman_get_device((r)->res), (r)"
for i
do
@@ -70,15 +70,15 @@ do
# macro copy_region_$w so dh do c
# macro copy_region_stream_$w ?
# macro peek_$w
- for s in "" #stream_
+ for s in "" stream_
do
macro read_$s$w o
-# macro read_multi_$s$w o d c
+ macro read_multi_$s$w o d c
# macro read_region_$s$w o d c
# macro set_multi_$s$w o v c
# macro set_region_$s$w o v c
macro write_$s$w o v
-# macro write_multi_$s$w o d c
+ macro write_multi_$s$w o d c
# macro write_region_$s$w o d c
done
done
diff --git a/sys/dev/bhnd/tools/nvram_map_gen.awk b/sys/dev/bhnd/tools/nvram_map_gen.awk
new file mode 100755
index 0000000..52e3a4d
--- /dev/null
+++ b/sys/dev/bhnd/tools/nvram_map_gen.awk
@@ -0,0 +1,1162 @@
+#!/usr/bin/awk -f
+
+#-
+# Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer,
+# without modification.
+# 2. Redistributions in binary form must reproduce at minimum a disclaimer
+# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+# redistribution must be conditioned upon including a substantially
+# similar Disclaimer requirement for further binary redistribution.
+#
+# NO WARRANTY
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGES.
+#
+# $FreeBSD$
+
+BEGIN {
+ RS="\n"
+
+ depth = 0
+ symbols[depth,"_file"] = FILENAME
+ num_output_vars = 0
+ OUTPUT_FILE = null
+
+ # Seed rand()
+ srand()
+
+ # Output type
+ OUT_T = null
+ OUT_T_HEADER = "HEADER"
+ OUT_T_DATA = "DATA"
+
+ # Enable debug output
+ DEBUG = 0
+
+ # Maximum revision
+ REV_MAX = 255
+
+ # Parse arguments
+ if (ARGC < 2)
+ usage()
+
+ for (i = 1; i < ARGC; i++) {
+ if (ARGV[i] == "--debug") {
+ DEBUG = 1
+ } else if (ARGV[i] == "-d" && OUT_T == null) {
+ OUT_T = OUT_T_DATA
+ } else if (ARGV[i] == "-h" && OUT_T == null) {
+ OUT_T = OUT_T_HEADER
+ } else if (ARGV[i] == "-o") {
+ i++
+ if (i >= ARGC)
+ usage()
+
+ OUTPUT_FILE = ARGV[i]
+ } else if (ARGV[i] == "--") {
+ i++
+ break
+ } else if (ARGV[i] !~ /^-/) {
+ FILENAME = ARGV[i]
+ } else {
+ print "unknown option " ARGV[i]
+ usage()
+ }
+ }
+
+ ARGC=2
+
+ if (OUT_T == null) {
+ print("error: one of -d or -h required")
+ usage()
+ }
+
+ if (FILENAME == null) {
+ print("error: no input file specified")
+ usage()
+ }
+
+ if (OUTPUT_FILE == "-") {
+ OUTPUT_FILE = "/dev/stdout"
+ } else if (OUTPUT_FILE == null) {
+ _bi = split(FILENAME, _paths, "/")
+ OUTPUT_FILE = _paths[_bi]
+
+ if (OUTPUT_FILE !~ /^bhnd_/)
+ OUTPUT_FILE = "bhnd_" OUTPUT_FILE
+
+ if (OUT_T == OUT_T_HEADER)
+ OUTPUT_FILE = OUTPUT_FILE ".h"
+ else
+ OUTPUT_FILE = OUTPUT_FILE "_data.h"
+ }
+
+ # Format Constants
+ FMT["hex"] = "BHND_NVRAM_VFMT_HEX"
+ FMT["decimal"] = "BHND_NVRAM_VFMT_DEC"
+ FMT["ccode"] = "BHND_NVRAM_VFMT_CCODE"
+ FMT["macaddr"] = "BHND_NVRAM_VFMT_MACADDR"
+ FMT["led_dc"] = "BHND_NVRAM_VFMT_LEDDC"
+
+ # Data Type Constants
+ DTYPE["u8"] = "BHND_NVRAM_DT_UINT8"
+ DTYPE["u16"] = "BHND_NVRAM_DT_UINT16"
+ DTYPE["u32"] = "BHND_NVRAM_DT_UINT32"
+ DTYPE["i8"] = "BHND_NVRAM_DT_INT8"
+ DTYPE["i16"] = "BHND_NVRAM_DT_INT16"
+ DTYPE["i32"] = "BHND_NVRAM_DT_INT32"
+ DTYPE["char"] = "BHND_NVRAM_DT_CHAR"
+
+ # Default masking for standard types
+ TMASK["u8"] = "0x000000FF"
+ TMASK["u16"] = "0x0000FFFF"
+ TMASK["u32"] = "0xFFFFFFFF"
+ TMASK["i8"] = TMASK["u8"]
+ TMASK["i16"] = TMASK["u16"]
+ TMASK["i32"] = TMASK["u32"]
+ TMASK["char"] = TMASK["u8"]
+
+ # Byte sizes for standard types
+ TSIZE["u8"] = "1"
+ TSIZE["u16"] = "2"
+ TSIZE["u32"] = "4"
+ TSIZE["i8"] = TSIZE["u8"]
+ TSIZE["i16"] = TSIZE["u8"]
+ TSIZE["i32"] = TSIZE["u8"]
+ TSIZE["char"] = "1"
+
+ # Common Regexs
+ INT_REGEX = "^(0|[1-9][0-9]*),?$"
+ HEX_REGEX = "^0x[A-Fa-f0-9]+,?$"
+
+ ARRAY_REGEX = "\\[(0|[1-9][0-9]*)\\]"
+ TYPES_REGEX = "^(((u|i)(8|16|32))|char)("ARRAY_REGEX")?,?$"
+
+ IDENT_REGEX = "^[A-Za-z_][A-Za-z0-9_]*,?$"
+ SROM_OFF_REGEX = "("TYPES_REGEX"|"HEX_REGEX")"
+
+ # Parser states types
+ ST_STRUCT_BLOCK = "struct" # struct block
+ ST_VAR_BLOCK = "var" # variable block
+ ST_SROM_DEFN = "srom" # srom offset defn
+ ST_NONE = "NONE" # default state
+
+ # Property types
+ PROP_T_SFMT = "sfmt"
+ PROP_T_ALL1 = "all1"
+
+ # Internal variables used for parser state
+ # tracking
+ STATE_TYPE = "_state_type"
+ STATE_IDENT = "_state_block_name"
+ STATE_LINENO = "_state_first_line"
+ STATE_ISBLOCK = "_state_is_block"
+
+ # Common array keys
+ DEF_LINE = "def_line"
+ NUM_REVS = "num_revs"
+ REV = "rev"
+
+ # Revision array keys
+ REV_START = "rev_start"
+ REV_END = "rev_end"
+ REV_DESC = "rev_decl"
+ REV_NUM_OFFS = "num_offs"
+
+ # Offset array keys
+ OFF = "off"
+ OFF_NUM_SEGS = "off_num_segs"
+ OFF_SEG = "off_seg"
+
+ # Segment array keys
+ SEG_ADDR = "seg_addr"
+ SEG_COUNT = "seg_count"
+ SEG_TYPE = "seg_type"
+ SEG_MASK = "seg_mask"
+ SEG_SHIFT = "seg_shift"
+
+ # Variable array keys
+ VAR_NAME = "v_name"
+ VAR_TYPE = "v_type"
+ VAR_BASE_TYPE = "v_base_type"
+ VAR_FMT = "v_fmt"
+ VAR_STRUCT = "v_parent_struct"
+ VAR_PRIVATE = "v_private"
+ VAR_ARRAY = "v_array"
+ VAR_IGNALL1 = "v_ignall1"
+}
+
+# return the flag definition for variable `v`
+function gen_var_flags (v)
+{
+ _num_flags = 0;
+ if (vars[v,VAR_ARRAY])
+ _flags[_num_flags++] = "BHND_NVRAM_VF_ARRAY"
+
+ if (vars[v,VAR_PRIVATE])
+ _flags[_num_flags++] = "BHND_NVRAM_VF_MFGINT"
+
+ if (vars[v,VAR_IGNALL1])
+ _flags[_num_flags++] = "BHND_NVRAM_VF_IGNALL1"
+
+ if (_num_flags == 0)
+ _flags[_num_flags++] = "0"
+
+ return (join(_flags, "|", _num_flags))
+}
+
+# emit the bhnd_sprom_offsets for a given variable revision key
+function emit_var_sprom_offsets (v, revk)
+{
+ emit(sprintf("{{%u, %u}, (struct bhnd_sprom_offset[]) {\n",
+ vars[revk,REV_START],
+ vars[revk,REV_END]))
+ output_depth++
+
+ num_offs = vars[revk,REV_NUM_OFFS]
+ num_offs_written = 0
+ elem_count = 0
+ for (offset = 0; offset < num_offs; offset++) {
+ offk = subkey(revk, OFF, offset"")
+ num_segs = vars[offk,OFF_NUM_SEGS]
+
+ for (seg = 0; seg < num_segs; seg++) {
+ segk = subkey(offk, OFF_SEG, seg"")
+
+ for (seg_n = 0; seg_n < vars[segk,SEG_COUNT]; seg_n++) {
+ seg_addr = vars[segk,SEG_ADDR]
+ seg_addr += TSIZE[vars[segk,SEG_TYPE]] * seg_n
+
+ emit(sprintf("{%s, %s, %s, %s, %s},\n",
+ seg_addr,
+ (seg > 0) ? "true" : "false",
+ DTYPE[vars[segk,SEG_TYPE]],
+ vars[segk,SEG_SHIFT],
+ vars[segk,SEG_MASK]))
+
+ num_offs_written++
+ }
+ }
+ }
+
+ output_depth--
+ emit("}, " num_offs_written "},\n")
+}
+
+# emit the bhnd_nvram_var definition for variable name `v`
+function emit_var_defn (v)
+{
+ emit(sprintf("{\"%s\", %s, %s, %s, (struct bhnd_sprom_var[]) {\n",
+ v suffix,
+ DTYPE[vars[v,VAR_BASE_TYPE]],
+ FMT[vars[v,VAR_FMT]],
+ gen_var_flags(v)))
+ output_depth++
+
+ for (rev = 0; rev < vars[v,NUM_REVS]; rev++) {
+ revk = subkey(v, REV, rev"")
+ emit_var_sprom_offsets(v, revk)
+ }
+
+ output_depth--
+ emit("}, " vars[v,NUM_REVS] "},\n")
+}
+
+# emit a header name #define for variable `v`
+function emit_var_namedef (v)
+{
+ emit("#define\tBHND_NVAR_" toupper(v) "\t\"" v "\"\n")
+}
+
+# generate a set of var offset definitions for struct variable `st_vid`
+function gen_struct_var_offsets (vid, revk, st_vid, st_revk, base_addr)
+{
+ # Copy all offsets to the new variable
+ for (offset = 0; offset < vars[v,REV_NUM_OFFS]; offset++) {
+ st_offk = subkey(st_revk, OFF, offset"")
+ offk = subkey(revk, OFF, offset"")
+
+ # Copy all segments to the new variable, applying base
+ # address adjustment
+ num_segs = vars[st_offk,OFF_NUM_SEGS]
+ vars[offk,OFF_NUM_SEGS] = num_segs
+
+ for (seg = 0; seg < num_segs; seg++) {
+ st_segk = subkey(st_offk, OFF_SEG, seg"")
+ segk = subkey(offk, OFF_SEG, seg"")
+
+ vars[segk,SEG_ADDR] = vars[st_segk,SEG_ADDR] + \
+ base_addr""
+ vars[segk,SEG_COUNT] = vars[st_segk,SEG_COUNT]
+ vars[segk,SEG_TYPE] = vars[st_segk,SEG_TYPE]
+ vars[segk,SEG_MASK] = vars[st_segk,SEG_MASK]
+ vars[segk,SEG_SHIFT] = vars[st_segk,SEG_SHIFT]
+ }
+ }
+}
+
+# generate a complete set of variable definitions for struct variable `st_vid`.
+function gen_struct_vars (st_vid)
+{
+ st = vars[st_vid,VAR_STRUCT]
+ st_max_off = 0
+
+ # determine the total number of variables to generate
+ for (st_rev = 0; st_rev < structs[st,NUM_REVS]; st_rev++) {
+ srevk = subkey(st, REV, st_rev"")
+ for (off = 0; off < structs[srevk,REV_NUM_OFFS]; off++) {
+ if (off > st_max_off)
+ st_max_off = off
+ }
+ }
+
+ # generate variable records for each defined struct offset
+ for (off = 0; off < st_max_off; off++) {
+ # Construct basic variable definition
+ v = st_vid off""
+ vars[v,VAR_TYPE] = vars[st_vid,VAR_TYPE]
+ vars[v,VAR_BASE_TYPE] = vars[st_vid,VAR_BASE_TYPE]
+ vars[v,VAR_FMT] = vars[st_vid,VAR_FMT]
+ vars[v,VAR_PRIVATE] = vars[st_vid,VAR_PRIVATE]
+ vars[v,VAR_ARRAY] = vars[st_vid,VAR_ARRAY]
+ vars[v,VAR_IGNALL1] = vars[st_vid,VAR_IGNALL1]
+ vars[v,NUM_REVS] = 0
+
+ # Add to output variable list
+ output_vars[num_output_vars++] = v
+
+ # Construct revision / offset entries
+ for (srev = 0; srev < structs[st,NUM_REVS]; srev++) {
+ # Struct revision key
+ st_revk = subkey(st, REV, srev"")
+
+ # Skip offsets not defined for this revision
+ if (off > structs[st_revk,REV_NUM_OFFS])
+ continue
+
+ # Strut offset key and associated base address */
+ offk = subkey(st_revk, OFF, off"")
+ base_addr = structs[offk,SEG_ADDR]
+
+ for (vrev = 0; vrev < vars[st_vid,NUM_REVS]; vrev++) {
+ st_var_revk = subkey(st_vid, REV, vrev"")
+ v_start = vars[st_var_revk,REV_START]
+ v_end = vars[st_var_revk,REV_END]
+ s_start = structs[st_revk,REV_START]
+ s_end = structs[st_revk,REV_END]
+
+ # We don't support computing the union
+ # of partially overlapping ranges
+ if ((v_start < s_start && v_end >= s_start) ||
+ (v_start <= s_end && v_end > s_end))
+ {
+ errorx("partially overlapping " \
+ "revision ranges are not supported")
+ }
+
+ # skip variables revs that are not within
+ # the struct offset's compatibility range
+ if (v_start < s_start || v_start > s_end ||
+ v_end < s_start || v_end > s_end)
+ continue
+
+ # Generate the new revision record
+ rev = vars[v,NUM_REVS] ""
+ revk = subkey(v, REV, rev)
+ vars[v,NUM_REVS]++
+
+ vars[revk,DEF_LINE] = vars[st_revk,DEF_LINE]
+ vars[revk,REV_START] = v_start
+ vars[revk,REV_END] = v_end
+ vars[revk,REV_NUM_OFFS] = \
+ vars[st_var_revk,REV_NUM_OFFS]
+
+ gen_struct_var_offsets(v, revk, st_vid, st_revk,
+ base_addr)
+ }
+ }
+ }
+}
+
+
+END {
+ # Skip completion handling if exiting from an error
+ if (_EARLY_EXIT)
+ exit 1
+
+ # Check for complete block closure
+ if (depth > 0) {
+ block_start = g(STATE_LINENO)
+ errorx("missing '}' for block opened on line " block_start "")
+ }
+
+ # Generate concrete variable definitions for all struct variables
+ for (v in var_names) {
+ if (vars[v,VAR_STRUCT] != null) {
+ gen_struct_vars(v)
+ } else {
+ output_vars[num_output_vars++] = v
+ }
+ }
+
+ # Apply lexicographical sorting. To support more effecient table
+ # searching, we guarantee a stable sort order (using C collation).
+ sort(output_vars)
+
+ # Truncate output file and write common header
+ printf("") > OUTPUT_FILE
+ emit("/*\n")
+ emit(" * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.\n")
+ emit(" *\n")
+ emit(" * generated from nvram map: " FILENAME "\n")
+ emit(" */\n")
+ emit("\n")
+
+ # Emit all variable definitions
+ if (OUT_T == OUT_T_DATA) {
+ emit("#include <dev/bhnd/nvram/nvramvar.h>\n")
+ emit("static const struct bhnd_nvram_var bhnd_nvram_vars[] = "\
+ "{\n")
+ output_depth++
+ for (i = 0; i < num_output_vars; i++)
+ emit_var_defn(output_vars[i])
+ output_depth--
+ emit("};\n")
+ } else if (OUT_T == OUT_T_HEADER) {
+ for (i = 0; i < num_output_vars; i++)
+ emit_var_namedef(output_vars[i])
+ }
+
+ printf("%u variable records written to %s\n", num_output_vars,
+ OUTPUT_FILE) >> "/dev/stderr"
+}
+
+
+#
+# Print usage
+#
+function usage ()
+{
+ print "usage: bhnd_nvram_map.awk <input map> [-hd] [-o output file]"
+ _EARLY_EXIT = 1
+ exit 1
+}
+
+#
+# Join all array elements with the given separator
+#
+function join (array, sep, count)
+{
+ if (count == 0)
+ return ("")
+
+ _result = array[0]
+ for (_ji = 1; _ji < count; _ji++)
+ _result = _result sep array[_ji]
+
+ return (_result)
+}
+
+#
+# Sort a contiguous integer-indexed array, using standard awk comparison
+# operators over its values.
+#
+function sort (array) {
+ # determine array size
+ _sort_alen = 0
+
+ for (_ssort_key in array)
+ _sort_alen++
+
+ if (_sort_alen <= 1)
+ return
+
+ # perform sort
+ _qsort(array, 0, _sort_alen-1)
+}
+
+function _qsort (array, first, last)
+{
+ if (first >= last)
+ return
+
+ # select pivot element
+ _qpivot = int(first + int((last-first+1) * rand()))
+ _qleft = first
+ _qright = last
+
+ _qpivot_val = array[_qpivot]
+
+ # partition
+ while (_qleft <= _qright) {
+ while (array[_qleft] < _qpivot_val)
+ _qleft++
+
+ while (array[_qright] > _qpivot_val)
+ _qright--
+
+ # swap
+ if (_qleft <= _qright) {
+ _qleft_val = array[_qleft]
+ _qright_val = array[_qright]
+
+ array[_qleft] = _qright_val
+ array[_qright] = _qleft_val
+
+ _qleft++
+ _qright--
+ }
+ }
+
+ # sort the partitions
+ _qsort(array, first, _qright)
+ _qsort(array, _qleft, last)
+}
+
+#
+# Print msg to output file, without indentation
+#
+function emit_ni (msg)
+{
+ printf("%s", msg) >> OUTPUT_FILE
+}
+
+#
+# Print msg to output file, indented for the current `output_depth`
+#
+function emit (msg)
+{
+ for (_ind = 0; _ind < output_depth; _ind++)
+ emit_ni("\t")
+
+ emit_ni(msg)
+}
+
+#
+# Print a warning to stderr
+#
+function warn (msg)
+{
+ print "warning:", msg, "at", FILENAME, "line", NR > "/dev/stderr"
+}
+
+#
+# Print a compiler error to stderr
+#
+function error (msg)
+{
+ errorx(msg " at " FILENAME " line " NR ":\n\t" $0)
+}
+
+#
+# Print an error message without including the source line information
+#
+function errorx (msg)
+{
+ print "error:", msg > "/dev/stderr"
+ _EARLY_EXIT=1
+ exit 1
+}
+
+#
+# Print a debug output message
+#
+function debug (msg)
+{
+ if (!DEBUG)
+ return
+ for (_di = 0; _di < depth; _di++)
+ printf("\t") > "/dev/stderr"
+ print msg > "/dev/stderr"
+}
+
+#
+# Return an array key composed of the given (parent, selector, child)
+# tuple.
+# The child argument is optional and may be omitted.
+#
+function subkey (parent, selector, child)
+{
+ if (child != null)
+ return (parent SUBSEP selector SUBSEP child)
+ else
+ return (parent SUBSEP selector)
+}
+
+#
+# Advance to the next non-comment input record
+#
+function next_line ()
+{
+ do {
+ _result = getline
+ } while (_result > 0 && $0 ~ /^[ \t]*#.*/) # skip comment lines
+ return (_result)
+}
+
+#
+# Advance to the next input record and verify that it matches @p regex
+#
+function getline_matching (regex)
+{
+ _result = next_line()
+ if (_result <= 0)
+ return (_result)
+
+ if ($0 ~ regex)
+ return (1)
+
+ return (-1)
+}
+
+#
+# Shift the current fields left by `n`.
+#
+# If all fields are consumed and the optional do_getline argument is true,
+# read the next line.
+#
+function shiftf (n, do_getline)
+{
+ if (n > NF) error("shift past end of line")
+ for (_si = 1; _si <= NF-n; _si++) {
+ $(_si) = $(_si+n)
+ }
+ NF = NF - n
+
+ if (NF == 0 && do_getline)
+ next_line()
+}
+
+#
+# Parse a revision descriptor from the current line.
+#
+function parse_revdesc (result)
+{
+ _rstart = 0
+ _rend = 0
+
+ if ($2 ~ "[0-9]*-[0-9*]") {
+ split($2, _revrange, "[ \t]*-[ \t]*")
+ _rstart = _revrange[1]
+ _rend = _revrange[2]
+ } else if ($2 ~ "(>|>=|<|<=)" && $3 ~ "[1-9][0-9]*") {
+ if ($2 == ">") {
+ _rstart = int($3)+1
+ _rend = REV_MAX
+ } else if ($2 == ">=") {
+ _rstart = int($3)
+ _rend = REV_MAX
+ } else if ($2 == "<" && int($3) > 0) {
+ _rstart = 0
+ _rend = int($3)-1
+ } else if ($2 == "<=") {
+ _rstart = 0
+ _rend = int($3)-1
+ } else {
+ error("invalid revision descriptor")
+ }
+ } else if ($2 ~ "[1-9][0-9]*") {
+ _rstart = int($2)
+ _rend = int($2)
+ } else {
+ error("invalid revision descriptor")
+ }
+
+ result[REV_START] = _rstart
+ result[REV_END] = _rend
+}
+
+#
+# Push a new parser state.
+#
+# The name may be null, in which case the STATE_IDENT variable will not be
+# defined in this scope
+#
+function push_state (type, name, block) {
+ depth++
+ push(STATE_LINENO, NR)
+ if (name != null)
+ push(STATE_IDENT, name)
+ push(STATE_TYPE, type)
+ push(STATE_ISBLOCK, block)
+}
+
+#
+# Pop the top of the parser state stack.
+#
+function pop_state () {
+ # drop all symbols defined at this depth
+ for (s in symbols) {
+ if (s ~ "^"depth"[^0-9]")
+ delete symbols[s]
+ }
+ depth--
+}
+
+#
+# Find opening brace and push a new parser state for a brace-delimited block.
+#
+# The name may be null, in which case the STATE_IDENT variable will not be
+# defined in this scope
+#
+function open_block (type, name)
+{
+ if ($0 ~ "{" || getline_matching("^[ \t]*{") > 0) {
+ push_state(type, name, 1)
+ sub("^[^{]+{", "", $0)
+ return
+ }
+
+ error("found '"$1 "' instead of expected '{' for '" name "'")
+}
+
+#
+# Find closing brace and pop parser states until the first
+# brace-delimited block is discarded.
+#
+function close_block ()
+{
+ if ($0 !~ "}")
+ error("internal error - no closing brace")
+
+ # pop states until we exit the first enclosing block
+ do {
+ _closed_block = g(STATE_ISBLOCK)
+ pop_state()
+ } while (!_closed_block)
+
+ # strip everything prior to the block closure
+ sub("^[^}]*}", "", $0)
+}
+
+# Internal symbol table lookup function. Returns the symbol depth if
+# name is found at or above scope; if scope is null, it defauls to 0
+function _find_sym (name, scope)
+{
+ if (scope == null)
+ scope = 0;
+
+ for (i = scope; i < depth; i++) {
+ if ((depth-i,name) in symbols)
+ return (depth-i)
+ }
+
+ return (-1)
+}
+
+#
+# Look up a variable in the symbol table with `name` and return its value.
+#
+# If `scope` is not null, the variable search will start at the provided
+# scope level -- 0 is the current scope, 1 is the parent's scope, etc.
+#
+function g (name, scope)
+{
+ _g_depth = _find_sym(name, scope)
+ if (_g_depth < 0)
+ error("'" name "' is undefined")
+
+ return (symbols[_g_depth,name])
+}
+
+function is_defined (name, scope)
+{
+ return (_find_sym(name, scope) >= 0)
+}
+
+# Define a new variable in the symbol table's current scope,
+# with the given value
+function push (name, value)
+{
+ symbols[depth,name] = value
+}
+
+# Set an existing variable's value in the symbol table; if not yet defined,
+# will trigger an error
+function set (name, value, scope)
+{
+ for (i = 0; i < depth; i++) {
+ if ((depth-i,name) in symbols) {
+ symbols[depth-i,name] = value
+ return
+ }
+ }
+ # No existing value, cannot define
+ error("'" name "' is undefined")
+}
+
+# Evaluates to true if immediately within a block scope of the given type
+function in_state (type)
+{
+ if (!is_defined(STATE_TYPE))
+ return (type == ST_NONE)
+
+ return (type == g(STATE_TYPE))
+}
+
+# Evaluates to true if within an immediate or non-immediate block scope of the
+# given type
+function in_nested_state (type)
+{
+ for (i = 0; i < depth; i++) {
+ if ((depth-i,STATE_TYPE) in symbols) {
+ if (symbols[depth-i,STATE_TYPE] == type)
+ return (1)
+ }
+ }
+ return (0)
+}
+
+# Evaluates to true if definitions of the given type are permitted within
+# the current scope
+function allow_def (type)
+{
+ if (type == ST_VAR_BLOCK) {
+ return (in_state(ST_NONE) || in_state(ST_STRUCT_BLOCK))
+ } else if (type == ST_STRUCT_BLOCK) {
+ return (in_state(ST_NONE))
+ } else if (type == ST_SROM_DEFN) {
+ return (in_state(ST_VAR_BLOCK) || in_state(ST_STRUCT_BLOCK))
+ }
+
+ error("unknown type '" type "'")
+}
+
+# struct definition
+$1 == ST_STRUCT_BLOCK && allow_def($1) {
+ name = $2
+
+ # Remove array[] specifier
+ if (sub(/\[\]$/, "", name) == 0)
+ error("expected '" name "[]', not '" name "'")
+
+ if (name !~ IDENT_REGEX || name ~ TYPES_REGEX)
+ error("invalid identifier '" name "'")
+
+ # Add top-level struct entry
+ if ((name,DEF_LINE) in structs)
+ error("struct identifier '" name "' previously defined on " \
+ "line " structs[name,DEF_LINE])
+ structs[name,DEF_LINE] = NR
+ structs[name,NUM_REVS] = 0
+
+ # Open the block
+ debug("struct " name " {")
+ open_block(ST_STRUCT_BLOCK, name)
+}
+
+# struct srom descriptor
+$1 == ST_SROM_DEFN && allow_def(ST_SROM_DEFN) && in_state(ST_STRUCT_BLOCK) {
+ sid = g(STATE_IDENT)
+
+ # parse revision descriptor
+ rev_desc[REV_START] = 0
+ parse_revdesc(rev_desc)
+
+ # assign revision id
+ rev = structs[sid,NUM_REVS] ""
+ revk = subkey(sid, REV, rev)
+ structs[sid,NUM_REVS]++
+
+ # init basic revision state
+ structs[revk,REV_START] = rev_desc[REV_START]
+ structs[revk,REV_END] = rev_desc[REV_END]
+
+ if (match($0, "\\[[^]]*\\]") <= 0)
+ error("expected base address array")
+
+ addrs_str = substr($0, RSTART+1, RLENGTH-2)
+ num_offs = split(addrs_str, addrs, ",[ \t]*")
+ structs[revk, REV_NUM_OFFS] = num_offs
+ for (i = 1; i <= num_offs; i++) {
+ offk = subkey(revk, OFF, (i-1) "")
+
+ if (addrs[i] !~ HEX_REGEX)
+ error("invalid base address '" addrs[i] "'")
+
+ structs[offk,SEG_ADDR] = addrs[i]
+ }
+
+ debug("struct_srom " structs[revk,REV_START] "... [" addrs_str "]")
+ next
+}
+
+# close any previous srom revision descriptor
+$1 == ST_SROM_DEFN && in_state(ST_SROM_DEFN) {
+ pop_state()
+}
+
+# open a new srom revision descriptor
+$1 == ST_SROM_DEFN && allow_def(ST_SROM_DEFN) {
+ # parse revision descriptor
+ parse_revdesc(rev_desc)
+
+ # assign revision id
+ vid = g(STATE_IDENT)
+ rev = vars[vid,NUM_REVS] ""
+ revk = subkey(vid, REV, rev)
+ vars[vid,NUM_REVS]++
+
+ # vend scoped rev/revk variables for use in the
+ # revision offset block
+ push("rev_id", rev)
+ push("rev_key", revk)
+
+ # init basic revision state
+ vars[revk,DEF_LINE] = NR
+ vars[revk,REV_START] = rev_desc[REV_START]
+ vars[revk,REV_END] = rev_desc[REV_END]
+ vars[revk,REV_NUM_OFFS] = 0
+
+ debug("srom " rev_desc[REV_START] "-" rev_desc[REV_END] " {")
+ push_state(ST_SROM_DEFN, null, 0)
+
+ # seek to the first offset definition
+ do {
+ shiftf(1)
+ } while ($1 !~ SROM_OFF_REGEX && NF > 0)
+}
+
+#
+# Extract and return the array length from the given type string.
+# Returns -1 if the type is not an array.
+#
+function type_array_len (type)
+{
+ # extract byte count[] and width
+ if (match(type, ARRAY_REGEX"$") > 0) {
+ return (substr(type, RSTART+1, RLENGTH-2))
+ } else {
+ return (-1)
+ }
+}
+
+#
+# Parse an offset declaration from the current line.
+#
+function parse_offset_segment (revk, offk)
+{
+ vid = g(STATE_IDENT)
+
+ # use explicit type if specified, otherwise use the variable's
+ # common type
+ if ($1 !~ HEX_REGEX) {
+ type = $1
+ if (type !~ TYPES_REGEX)
+ error("unknown field type '" type "'")
+
+ shiftf(1)
+ } else {
+ type = vars[vid,VAR_TYPE]
+ }
+
+ # read offset value
+ offset = $1
+ if (offset !~ HEX_REGEX)
+ error("invalid offset value '" offset "'")
+
+ # extract byte count[], base type, and width
+ if (match(type, ARRAY_REGEX"$") > 0) {
+ count = int(substr(type, RSTART+1, RLENGTH-2))
+ type = substr(type, 1, RSTART-1)
+ } else {
+ count = 1
+ }
+ width = TSIZE[type]
+
+ # seek to attributes or end of the offset expr
+ sub("^[^,(|){}]+", "", $0)
+
+ # parse attributes
+ mask=TMASK[type]
+ shift=0
+
+ if ($1 ~ "^\\(") {
+ # extract attribute list
+ if (match($0, "\\([^|\(\)]*\\)") <= 0)
+ error("expected attribute list")
+ attr_str = substr($0, RSTART+1, RLENGTH-2)
+
+ # drop from input line
+ $0 = substr($0, RSTART+RLENGTH, length($0) - RSTART+RLENGTH)
+
+ # parse attributes
+ num_attr = split(attr_str, attrs, ",[ \t]*")
+ for (i = 1; i <= num_attr; i++) {
+ attr = attrs[i]
+ if (sub("^&[ \t]*", "", attr) > 0) {
+ mask = attr
+ } else if (sub("^<<[ \t]*", "", attr) > 0) {
+ shift = "-"attr
+ } else if (sub("^>>[ \t]*", "", attr) > 0) {
+ shift = attr
+ } else {
+ error("unknown attribute '" attr "'")
+ }
+ }
+ }
+
+ # assign segment id
+ seg = vars[offk,OFF_NUM_SEGS] ""
+ segk = subkey(offk, OFF_SEG, seg)
+ vars[offk,OFF_NUM_SEGS]++
+
+ vars[segk,SEG_ADDR] = offset + (width * _oi)
+ vars[segk,SEG_COUNT] = count
+ vars[segk,SEG_TYPE] = type
+ vars[segk,SEG_MASK] = mask
+ vars[segk,SEG_SHIFT] = shift
+
+ debug("{"vars[segk,SEG_ADDR]", "type", "mask", "shift"}" \
+ _comma)
+}
+
+# revision offset definition
+$1 ~ SROM_OFF_REGEX && in_state(ST_SROM_DEFN) {
+ vid = g(STATE_IDENT)
+
+ # fetch rev id/key defined by our parent block
+ rev = g("rev_id")
+ revk = g("rev_key")
+
+ # parse all offsets
+ do {
+ # assign offset id
+ off = vars[revk,REV_NUM_OFFS] ""
+ offk = subkey(revk, OFF, off)
+ vars[revk,REV_NUM_OFFS]++
+
+ # initialize segment count
+ vars[offk,DEF_LINE] = NR
+ vars[offk,OFF_NUM_SEGS] = 0
+
+ debug("[")
+ # parse all segments
+ do {
+ parse_offset_segment(revk, offk)
+ _more_seg = ($1 == "|")
+ if (_more_seg)
+ shiftf(1, 1)
+ } while (_more_seg)
+ debug("],")
+ _more_vals = ($1 == ",")
+ if (_more_vals)
+ shiftf(1, 1)
+ } while (_more_vals)
+}
+
+# variable definition
+(($1 == "private" && $2 ~ TYPES_REGEX) || $1 ~ TYPES_REGEX) &&
+ allow_def(ST_VAR_BLOCK) \
+{
+ # check for 'private' flag
+ if ($1 == "private") {
+ private = 1
+ shiftf(1)
+ } else {
+ private = 0
+ }
+
+ type = $1
+ name = $2
+ array = 0
+ debug(type " " name " {")
+
+ # Check for and remove any array[] specifier
+ base_type = type
+ if (sub(ARRAY_REGEX"$", "", base_type) > 0)
+ array = 1
+
+ # verify type
+ if (!base_type in DTYPE)
+ error("unknown type '" $1 "'")
+
+ # Add top-level variable entry
+ if (name in var_names)
+ error("variable identifier '" name "' previously defined on " \
+ "line " vars[name,DEF_LINE])
+
+ var_names[name] = 0
+ vars[name,VAR_NAME] = name
+ vars[name,DEF_LINE] = NR
+ vars[name,VAR_TYPE] = type
+ vars[name,VAR_BASE_TYPE] = base_type
+ vars[name,NUM_REVS] = 0
+ vars[name,VAR_PRIVATE] = private
+ vars[name,VAR_ARRAY] = array
+ vars[name,VAR_FMT] = "hex" # default if not specified
+
+ open_block(ST_VAR_BLOCK, name)
+
+ debug("type=" DTYPE[base_type])
+
+ if (in_nested_state(ST_STRUCT_BLOCK)) {
+ # Fetch the enclosing struct's name
+ sid = g(STATE_IDENT, 1)
+
+ # Mark as a struct-based variable
+ vars[name,VAR_STRUCT] = sid
+ }
+}
+
+# variable parameters
+$1 ~ IDENT_REGEX && $2 ~ IDENT_REGEX && in_state(ST_VAR_BLOCK) {
+ vid = g(STATE_IDENT)
+ if ($1 == PROP_T_SFMT) {
+ if (!$2 in FMT)
+ error("invalid fmt '" $2 "'")
+
+ vars[vid,VAR_FMT] = $2
+ debug($1 "=" FMT[$2])
+ } else if ($1 == PROP_T_ALL1 && $2 == "ignore") {
+ vars[vid,VAR_IGNALL1] = 1
+ } else {
+ error("unknown parameter " $1)
+ }
+ next
+}
+
+# Skip comments and blank lines
+/^[ \t]*#/ || /^$/ {
+ next
+}
+
+# Close blocks
+/}/ && !in_state(ST_NONE) {
+ while (!in_state(ST_NONE) && $0 ~ "}") {
+ close_block();
+ debug("}")
+ }
+ next
+}
+
+# Report unbalanced '}'
+/}/ && in_state(ST_NONE) {
+ error("extra '}'")
+}
+
+# Invalid variable type
+$1 && allow_def(ST_VAR_BLOCK) {
+ error("unknown type '" $1 "'")
+}
+
+# Generic parse failure
+{
+ error("unrecognized statement")
+}
diff --git a/sys/dev/bhnd/tools/nvram_map_gen.sh b/sys/dev/bhnd/tools/nvram_map_gen.sh
new file mode 100755
index 0000000..d2b981a
--- /dev/null
+++ b/sys/dev/bhnd/tools/nvram_map_gen.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Use C locale to ensure AWK string comparisons always produce
+# a stable sort order.
+
+# $FreeBSD$
+
+BHND_TOOLDIR="$(dirname $0)/"
+
+LC_ALL=C; export LC_ALL
+
+"$BHND_TOOLDIR/nvram_map_gen.awk" $@
diff --git a/sys/dev/buslogic/btreg.h b/sys/dev/buslogic/btreg.h
index 1475fd5..a22c5aa 100644
--- a/sys/dev/buslogic/btreg.h
+++ b/sys/dev/buslogic/btreg.h
@@ -595,7 +595,7 @@ struct sg_map_node {
};
struct bt_softc {
- struct device *dev;
+ device_t dev;
struct resource *port;
struct resource *irq;
struct resource *drq;
diff --git a/sys/dev/bwn/bwn_mac.c b/sys/dev/bwn/bwn_mac.c
new file mode 100644
index 0000000..8b2e962
--- /dev/null
+++ b/sys/dev/bwn/bwn_mac.c
@@ -0,0 +1,151 @@
+/*-
+ * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/bhnd/bhnd.h>
+#include <dev/bhnd/bhnd_ids.h>
+
+#include "bhnd_nvram_map.h"
+
+static const struct resource_spec bwn_rspec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, -1, 0 }
+};
+
+#define RSPEC_LEN (sizeof(bwn_rspec)/sizeof(bwn_rspec[0]))
+
+struct bwn_softc {
+ struct resource_spec rspec[RSPEC_LEN];
+ struct bhnd_resource *res[RSPEC_LEN-1];
+};
+
+static const struct bwn_device {
+ uint16_t vendor;
+ uint16_t device;
+} bwn_devices[] = {
+ { BHND_MFGID_BCM, BHND_COREID_D11 },
+ { BHND_MFGID_INVALID, BHND_COREID_INVALID }
+};
+
+static int
+bwn_probe(device_t dev)
+{
+ const struct bwn_device *id;
+
+ for (id = bwn_devices; id->device != BHND_COREID_INVALID; id++)
+ {
+ if (bhnd_get_vendor(dev) == id->vendor &&
+ bhnd_get_device(dev) == id->device)
+ {
+ device_set_desc(dev, bhnd_get_device_name(dev));
+ return (BUS_PROBE_DEFAULT);
+ }
+ }
+
+ return (ENXIO);
+}
+
+static int
+bwn_attach(device_t dev)
+{
+ struct bwn_softc *sc;
+ struct bhnd_resource *r;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ memcpy(sc->rspec, bwn_rspec, sizeof(bwn_rspec));
+ if ((error = bhnd_alloc_resources(dev, sc->rspec, sc->res)))
+ return (error);
+
+ // XXX TODO
+ r = sc->res[0];
+ device_printf(dev, "got rid=%d res=%p\n", sc->rspec[0].rid, r);
+
+ uint8_t macaddr[6];
+ error = bhnd_nvram_getvar(dev, BHND_NVAR_MACADDR, macaddr,
+ sizeof(macaddr));
+ if (error)
+ return (error);
+
+ device_printf(dev, "got macaddr %6D\n", macaddr, ":");
+
+ return (0);
+}
+
+static int
+bwn_detach(device_t dev)
+{
+ struct bwn_softc *sc;
+
+ sc = device_get_softc(dev);
+ bhnd_release_resources(dev, sc->rspec, sc->res);
+
+ return (0);
+}
+
+static int
+bwn_suspend(device_t dev)
+{
+ return (0);
+}
+
+static int
+bwn_resume(device_t dev)
+{
+ return (0);
+}
+
+static device_method_t bwn_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, bwn_probe),
+ DEVMETHOD(device_attach, bwn_attach),
+ DEVMETHOD(device_detach, bwn_detach),
+ DEVMETHOD(device_suspend, bwn_suspend),
+ DEVMETHOD(device_resume, bwn_resume),
+ DEVMETHOD_END
+};
+
+static devclass_t bwn_devclass;
+
+DEFINE_CLASS_0(bwn, bwn_driver, bwn_methods, sizeof(struct bwn_softc));
+DRIVER_MODULE(bwn_mac, bhnd, bwn_driver, bwn_devclass, 0, 0);
+MODULE_DEPEND(bwn_mac, bhnd, 1, 1, 1);
+MODULE_VERSION(bwn_mac, 1);
diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
index de1bf71..4cddf8d 100644
--- a/sys/dev/bwn/if_bwn.c
+++ b/sys/dev/bwn/if_bwn.c
@@ -3987,6 +3987,33 @@ bwn_fw_loaducode(struct bwn_mac *mac)
error = EOPNOTSUPP;
goto error;
}
+
+ /*
+ * Determine firmware header version; needed for TX/RX packet
+ * handling.
+ */
+ if (mac->mac_fw.rev >= 598)
+ mac->mac_fw.fw_hdr_format = BWN_FW_HDR_598;
+ else if (mac->mac_fw.rev >= 410)
+ mac->mac_fw.fw_hdr_format = BWN_FW_HDR_410;
+ else
+ mac->mac_fw.fw_hdr_format = BWN_FW_HDR_351;
+
+ /*
+ * We don't support rev 598 or later; that requires
+ * another round of changes to the TX/RX descriptor
+ * and status layout.
+ *
+ * So, complain this is the case and exit out, rather
+ * than attaching and then failing.
+ */
+ if (mac->mac_fw.fw_hdr_format == BWN_FW_HDR_598) {
+ device_printf(sc->sc_dev,
+ "firmware is too new (>=598); not supported\n");
+ error = EOPNOTSUPP;
+ goto error;
+ }
+
mac->mac_fw.patch = bwn_shm_read_2(mac, BWN_SHARED,
BWN_SHARED_UCODE_PATCH);
date = bwn_shm_read_2(mac, BWN_SHARED, BWN_SHARED_UCODE_DATE);
@@ -4942,6 +4969,12 @@ bwn_intr_txeof(struct bwn_mac *mac)
break;
stat1 = BWN_READ_4(mac, BWN_XMITSTAT_1);
+ DPRINTF(mac->mac_sc, BWN_DEBUG_XMIT,
+ "%s: stat0=0x%08x, stat1=0x%08x\n",
+ __func__,
+ stat0,
+ stat1);
+
stat.cookie = (stat0 >> 16);
stat.seq = (stat1 & 0x0000ffff);
stat.phy_stat = ((stat1 & 0x00ff0000) >> 16);
@@ -5132,16 +5165,8 @@ bwn_dma_rxeof(struct bwn_dma_ring *dr, int *slot)
static void
bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
{
- struct bwn_dma_ring *dr;
- struct bwn_dmadesc_generic *desc;
- struct bwn_dmadesc_meta *meta;
- struct bwn_pio_txqueue *tq;
- struct bwn_pio_txpkt *tp = NULL;
struct bwn_softc *sc = mac->mac_sc;
struct bwn_stats *stats = &mac->mac_stats;
- struct ieee80211_node *ni;
- struct ieee80211vap *vap;
- int retrycnt = 0, slot;
BWN_ASSERT_LOCKED(mac->mac_sc);
@@ -5157,46 +5182,8 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
}
if (mac->mac_flags & BWN_MAC_FLAG_DMA) {
- if (status->ack) {
- dr = bwn_dma_parse_cookie(mac, status,
- status->cookie, &slot);
- if (dr == NULL) {
- device_printf(sc->sc_dev,
- "failed to parse cookie\n");
- return;
- }
- while (1) {
- dr->getdesc(dr, slot, &desc, &meta);
- if (meta->mt_islast) {
- ni = meta->mt_ni;
- vap = ni->ni_vap;
- ieee80211_ratectl_tx_complete(vap, ni,
- status->ack ?
- IEEE80211_RATECTL_TX_SUCCESS :
- IEEE80211_RATECTL_TX_FAILURE,
- &retrycnt, 0);
- break;
- }
- slot = bwn_dma_nextslot(dr, slot);
- }
- }
bwn_dma_handle_txeof(mac, status);
} else {
- if (status->ack) {
- tq = bwn_pio_parse_cookie(mac, status->cookie, &tp);
- if (tq == NULL) {
- device_printf(sc->sc_dev,
- "failed to parse cookie\n");
- return;
- }
- ni = tp->tp_ni;
- vap = ni->ni_vap;
- ieee80211_ratectl_tx_complete(vap, ni,
- status->ack ?
- IEEE80211_RATECTL_TX_SUCCESS :
- IEEE80211_RATECTL_TX_FAILURE,
- &retrycnt, 0);
- }
bwn_pio_handle_txeof(mac, status);
}
@@ -5441,6 +5428,63 @@ bwn_hwrate2ieeerate(int rate)
}
}
+/*
+ * Post process the RX provided RSSI.
+ *
+ * Valid for A, B, G, LP PHYs.
+ */
+static int8_t
+bwn_rx_rssi_calc(struct bwn_mac *mac, uint8_t in_rssi,
+ int ofdm, int adjust_2053, int adjust_2050)
+{
+ struct bwn_phy *phy = &mac->mac_phy;
+ struct bwn_phy_g *gphy = &phy->phy_g;
+ int tmp;
+
+ switch (phy->rf_ver) {
+ case 0x2050:
+ if (ofdm) {
+ tmp = in_rssi;
+ if (tmp > 127)
+ tmp -= 256;
+ tmp = tmp * 73 / 64;
+ if (adjust_2050)
+ tmp += 25;
+ else
+ tmp -= 3;
+ } else {
+ if (siba_sprom_get_bf_lo(mac->mac_sc->sc_dev)
+ & BWN_BFL_RSSI) {
+ if (in_rssi > 63)
+ in_rssi = 63;
+ tmp = gphy->pg_nrssi_lt[in_rssi];
+ tmp = (31 - tmp) * -131 / 128 - 57;
+ } else {
+ tmp = in_rssi;
+ tmp = (31 - tmp) * -149 / 128 - 68;
+ }
+ if (phy->type == BWN_PHYTYPE_G && adjust_2050)
+ tmp += 25;
+ }
+ break;
+ case 0x2060:
+ if (in_rssi > 127)
+ tmp = in_rssi - 256;
+ else
+ tmp = in_rssi;
+ break;
+ default:
+ tmp = in_rssi;
+ tmp = (tmp - 11) * 103 / 64;
+ if (adjust_2053)
+ tmp -= 109;
+ else
+ tmp -= 83;
+ }
+
+ return (tmp);
+}
+
static void
bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
{
@@ -5460,8 +5504,11 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
phystat0 = le16toh(rxhdr->phy_status0);
phystat3 = le16toh(rxhdr->phy_status3);
+
+ /* XXX Note: mactime, macstat, chanstat need fixing for fw 598 */
macstat = le32toh(rxhdr->mac_status);
chanstat = le16toh(rxhdr->channel);
+
phytype = chanstat & BWN_RX_CHAN_PHYTYPE;
if (macstat & BWN_RX_MAC_FCSERR)
@@ -5492,8 +5539,6 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
BWN_ISOLDFMT(mac),
(macstat & BWN_RX_MAC_KEYIDX) >> BWN_RX_MAC_KEYIDX_SHIFT);
- /* XXX calculating RSSI & noise & antenna */
-
if (phystat0 & BWN_RX_PHYST0_OFDM)
rate = bwn_plcp_get_ofdmrate(mac, plcp,
phytype == BWN_PHYTYPE_A);
@@ -5505,14 +5550,29 @@ bwn_rxeof(struct bwn_mac *mac, struct mbuf *m, const void *_rxhdr)
}
sc->sc_rx_rate = bwn_hwrate2ieeerate(rate);
+ /* rssi/noise */
+ switch (phytype) {
+ case BWN_PHYTYPE_A:
+ case BWN_PHYTYPE_B:
+ case BWN_PHYTYPE_G:
+ case BWN_PHYTYPE_LP:
+ rssi = bwn_rx_rssi_calc(mac, rxhdr->phy.abg.rssi,
+ !! (phystat0 & BWN_RX_PHYST0_OFDM),
+ !! (phystat0 & BWN_RX_PHYST0_GAINCTL),
+ !! (phystat3 & BWN_RX_PHYST3_TRSTATE));
+ break;
+ default:
+ /* XXX TODO: implement rssi for other PHYs */
+ break;
+ }
+
+ noise = mac->mac_stats.link_noise;
+
/* RX radio tap */
if (ieee80211_radiotap_active(ic))
bwn_rx_radiotap(mac, m, rxhdr, plcp, rate, rssi, noise);
m_adj(m, -IEEE80211_CRC_LEN);
- rssi = rxhdr->phy.abg.rssi; /* XXX incorrect RSSI calculation? */
- noise = mac->mac_stats.link_noise;
-
BWN_UNLOCK(sc);
ni = ieee80211_find_rxnode(ic, wh);
@@ -5538,6 +5598,7 @@ bwn_dma_handle_txeof(struct bwn_mac *mac,
struct bwn_dmadesc_meta *meta;
struct bwn_softc *sc = mac->mac_sc;
int slot;
+ int retrycnt = 0;
BWN_ASSERT_LOCKED(sc);
@@ -5562,6 +5623,13 @@ bwn_dma_handle_txeof(struct bwn_mac *mac,
KASSERT(meta->mt_m != NULL,
("%s:%d: fail", __func__, __LINE__));
+ /* Just count full frame retries for now */
+ retrycnt = status->framecnt - 1;
+ ieee80211_ratectl_tx_complete(meta->mt_ni->ni_vap, meta->mt_ni,
+ status->ack ?
+ IEEE80211_RATECTL_TX_SUCCESS :
+ IEEE80211_RATECTL_TX_FAILURE,
+ &retrycnt, 0);
ieee80211_tx_complete(meta->mt_ni, meta->mt_m, 0);
meta->mt_ni = NULL;
meta->mt_m = NULL;
@@ -5589,6 +5657,7 @@ bwn_pio_handle_txeof(struct bwn_mac *mac,
struct bwn_pio_txqueue *tq;
struct bwn_pio_txpkt *tp = NULL;
struct bwn_softc *sc = mac->mac_sc;
+ int retrycnt = 0;
BWN_ASSERT_LOCKED(sc);
@@ -5604,6 +5673,15 @@ bwn_pio_handle_txeof(struct bwn_mac *mac,
* Do any tx complete callback. Note this must
* be done before releasing the node reference.
*/
+
+ /* Just count full frame retries for now */
+ retrycnt = status->framecnt - 1;
+ ieee80211_ratectl_tx_complete(tp->tp_ni->ni_vap, tp->tp_ni,
+ status->ack ?
+ IEEE80211_RATECTL_TX_SUCCESS :
+ IEEE80211_RATECTL_TX_FAILURE,
+ &retrycnt, 0);
+
if (tp->tp_m->m_flags & M_TXCB)
ieee80211_process_callback(tp->tp_ni, tp->tp_m, 0);
ieee80211_free_node(tp->tp_ni);
@@ -5751,6 +5829,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = rate_fb = tp->ucastrate;
else {
+ /* XXX TODO: don't fall back to CCK rates for OFDM */
rix = ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
@@ -5763,6 +5842,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
sc->sc_tx_rate = rate;
+ /* Note: this maps the select ieee80211 rate to hardware rate */
rate = bwn_ieeerate2hwrate(sc, rate);
rate_fb = bwn_ieeerate2hwrate(sc, rate_fb);
@@ -5771,6 +5851,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
bcopy(wh->i_fc, txhdr->macfc, sizeof(txhdr->macfc));
bcopy(wh->i_addr1, txhdr->addr1, IEEE80211_ADDR_LEN);
+ /* XXX rate/rate_fb is the hardware rate */
if ((rate_fb == rate) ||
(*(u_int16_t *)wh->i_dur & htole16(0x8000)) ||
(*(u_int16_t *)wh->i_dur == htole16(0)))
@@ -5792,6 +5873,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
txhdr->chan = phy->chan;
phyctl |= (BWN_ISOFDMRATE(rate)) ? BWN_TX_PHY_ENC_OFDM :
BWN_TX_PHY_ENC_CCK;
+ /* XXX preamble? obey net80211 */
if (isshort && (rate == BWN_CCK_RATE_2MB || rate == BWN_CCK_RATE_5MB ||
rate == BWN_CCK_RATE_11MB))
phyctl |= BWN_TX_PHY_SHORTPRMBL;
@@ -5828,9 +5910,11 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
if (ic->ic_flags & IEEE80211_F_USEPROT) {
/* XXX RTS rate is always 1MB??? */
+ /* XXX TODO: don't fall back to CCK rates for OFDM */
rts_rate = BWN_CCK_RATE_1MB;
rts_rate_fb = bwn_get_fbrate(rts_rate);
+ /* XXX 'rate' here is hardware rate now, not the net80211 rate */
protdur = ieee80211_compute_duration(ic->ic_rt,
m->m_pkthdr.len, rate, isshort) +
+ ieee80211_ack_duration(ic->ic_rt, rate, isshort);
@@ -5851,6 +5935,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
rts = (struct ieee80211_frame_rts *)(BWN_ISOLDFMT(mac) ?
(txhdr->body.old.rts_frame) :
(txhdr->body.new.rts_frame));
+ /* XXX rate/rate_fb is the hardware rate */
protdur += ieee80211_ack_duration(ic->ic_rt, rate,
isshort);
mprot = ieee80211_alloc_rts(ic, wh->i_addr1,
@@ -5958,10 +6043,16 @@ bwn_antenna_sanitize(struct bwn_mac *mac, uint8_t n)
return (n);
}
+/*
+ * Return a fallback rate for the given rate.
+ *
+ * Note: Don't fall back from OFDM to CCK.
+ */
static uint8_t
bwn_get_fbrate(uint8_t bitrate)
{
switch (bitrate) {
+ /* CCK */
case BWN_CCK_RATE_1MB:
return (BWN_CCK_RATE_1MB);
case BWN_CCK_RATE_2MB:
@@ -5970,8 +6061,10 @@ bwn_get_fbrate(uint8_t bitrate)
return (BWN_CCK_RATE_2MB);
case BWN_CCK_RATE_11MB:
return (BWN_CCK_RATE_5MB);
+
+ /* OFDM */
case BWN_OFDM_RATE_6MB:
- return (BWN_CCK_RATE_5MB);
+ return (BWN_OFDM_RATE_6MB);
case BWN_OFDM_RATE_9MB:
return (BWN_OFDM_RATE_6MB);
case BWN_OFDM_RATE_12MB:
@@ -6886,3 +6979,4 @@ MODULE_DEPEND(bwn, siba_bwn, 1, 1, 1);
MODULE_DEPEND(bwn, wlan, 1, 1, 1); /* 802.11 media layer */
MODULE_DEPEND(bwn, firmware, 1, 1, 1); /* firmware support */
MODULE_DEPEND(bwn, wlan_amrr, 1, 1, 1);
+MODULE_VERSION(bwn, 1);
diff --git a/sys/dev/bwn/if_bwn_debug.h b/sys/dev/bwn/if_bwn_debug.h
index c38b08f..761fc5d 100644
--- a/sys/dev/bwn/if_bwn_debug.h
+++ b/sys/dev/bwn/if_bwn_debug.h
@@ -32,6 +32,8 @@
#ifndef __IF_BWN_DEBUG_H__
#define __IF_BWN_DEBUG_H__
+#define BWN_DEBUG
+
enum {
BWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
BWN_DEBUG_RECV = 0x00000002, /* basic recv operation */
diff --git a/sys/dev/bwn/if_bwn_pci.c b/sys/dev/bwn/if_bwn_pci.c
new file mode 100644
index 0000000..7e145c5
--- /dev/null
+++ b/sys/dev/bwn/if_bwn_pci.c
@@ -0,0 +1,288 @@
+/*-
+ * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/bhnd/bhndb/bhndb_pcivar.h>
+#include <dev/bhnd/bhndb/bhndb_pci_hwdata.h>
+
+#include <dev/bhnd/bhnd_ids.h>
+
+#include "bhndb_bus_if.h"
+
+#include "if_bwn_pcivar.h"
+
+/* If non-zero, enable attachment of BWN_QUIRK_UNTESTED devices */
+static int attach_untested = 0;
+TUNABLE_INT("hw.bwn_pci.attach_untested", &attach_untested);
+
+/* If non-zero, probe at a higher priority than the stable if_bwn driver. */
+static int prefer_new_driver = 0;
+TUNABLE_INT("hw.bwn_pci.preferred", &prefer_new_driver);
+
+/* SIBA Devices */
+static const struct bwn_pci_device siba_devices[] = {
+ BWN_BCM_DEV(BCM4301, "BCM4301 802.11b",
+ BWN_QUIRK_ENET_HW_UNPOPULATED),
+
+ BWN_BCM_DEV(BCM4306, "BCM4306 802.11b/g", 0),
+ BWN_BCM_DEV(BCM4306_D11G, "BCM4306 802.11g", 0),
+ BWN_BCM_DEV(BCM4306_D11A, "BCM4306 802.11a",
+ BWN_QUIRK_WLAN_DUALCORE),
+ BWN_BCM_DEV(BCM4306_D11DUAL, "BCM4306 802.11a/b",
+ BWN_QUIRK_WLAN_DUALCORE),
+ BWN_BCM_DEV(BCM4306_D11G_ID2, "BCM4306 802.11g", 0),
+
+ BWN_BCM_DEV(BCM4307, "BCM4307 802.11b", 0),
+
+ BWN_BCM_DEV(BCM4311_D11G, "BCM4311 802.11b/g", 0),
+ BWN_BCM_DEV(BCM4311_D11DUAL, "BCM4311 802.11a/b/g", 0),
+ BWN_BCM_DEV(BCM4311_D11A, "BCM4311 802.11a",
+ BWN_QUIRK_UNTESTED|BWN_QUIRK_WLAN_DUALCORE),
+
+ BWN_BCM_DEV(BCM4318_D11G, "BCM4318 802.11b/g", 0),
+ BWN_BCM_DEV(BCM4318_D11DUAL, "BCM4318 802.11a/b/g", 0),
+ BWN_BCM_DEV(BCM4318_D11A, "BCM4318 802.11a",
+ BWN_QUIRK_UNTESTED|BWN_QUIRK_WLAN_DUALCORE),
+
+ BWN_BCM_DEV(BCM4321_D11N, "BCM4321 802.11n Dual-Band", 0),
+ BWN_BCM_DEV(BCM4321_D11N2G, "BCM4321 802.11n 2GHz", 0),
+ BWN_BCM_DEV(BCM4321_D11N2G, "BCM4321 802.11n 5GHz",
+ BWN_QUIRK_UNTESTED),
+
+ BWN_BCM_DEV(BCM4322_D11N, "BCM4322 802.11n Dual-Band", 0),
+ BWN_BCM_DEV(BCM4322_D11N2G, "BCM4322 802.11n 2GHz",
+ BWN_QUIRK_UNTESTED),
+ BWN_BCM_DEV(BCM4322_D11N5G, "BCM4322 802.11n 5GHz",
+ BWN_QUIRK_UNTESTED),
+
+ BWN_BCM_DEV(BCM4328_D11G, "BCM4328/4312 802.11g", 0),
+
+ { 0, 0, NULL, 0 }
+};
+
+/** BCMA Devices */
+static const struct bwn_pci_device bcma_devices[] = {
+ BWN_BCM_DEV(BCM4331_D11N, "BCM4331 802.11n Dual-Band", 0),
+ BWN_BCM_DEV(BCM4331_D11N2G, "BCM4331 802.11n 2GHz", 0),
+ BWN_BCM_DEV(BCM4331_D11N5G, "BCM4331 802.11n 5GHz", 0),
+
+ { 0, 0, NULL, 0}
+};
+
+/** Device configuration table */
+static const struct bwn_pci_devcfg bwn_pci_devcfgs[] = {
+ /* SIBA devices */
+ {
+ .bridge_hwcfg = &bhndb_pci_siba_generic_hwcfg,
+ .bridge_hwtable = bhndb_pci_generic_hw_table,
+ .devices = siba_devices
+ },
+ /* BCMA devices */
+ {
+ .bridge_hwcfg = &bhndb_pci_bcma_generic_hwcfg,
+ .bridge_hwtable = bhndb_pci_generic_hw_table,
+ .devices = bcma_devices
+ },
+ { NULL, NULL, NULL }
+};
+
+/** Search the device configuration table for an entry matching @p dev. */
+static int
+bwn_pci_find_devcfg(device_t dev, const struct bwn_pci_devcfg **cfg,
+ const struct bwn_pci_device **device)
+{
+ const struct bwn_pci_devcfg *dvc;
+ const struct bwn_pci_device *dv;
+
+ for (dvc = bwn_pci_devcfgs; dvc->devices != NULL; dvc++) {
+ for (dv = dvc->devices; dv->device != 0; dv++) {
+ if (pci_get_vendor(dev) == dv->vendor &&
+ pci_get_device(dev) == dv->device)
+ {
+ if (cfg != NULL)
+ *cfg = dvc;
+
+ if (device != NULL)
+ *device = dv;
+
+ return (0);
+ }
+ }
+ }
+
+ return (ENOENT);
+}
+
+static int
+bwn_pci_probe(device_t dev)
+{
+ const struct bwn_pci_device *ident;
+
+ if (bwn_pci_find_devcfg(dev, NULL, &ident))
+ return (ENXIO);
+
+ /* Skip untested devices */
+ if (ident->quirks & BWN_QUIRK_UNTESTED && !attach_untested)
+ return (ENXIO);
+
+ device_set_desc(dev, ident->desc);
+
+ /* Until this driver is complete, require explicit opt-in before
+ * superceding if_bwn/siba_bwn. */
+ if (prefer_new_driver)
+ return (BUS_PROBE_DEFAULT+1);
+ else
+ return (BUS_PROBE_LOW_PRIORITY);
+
+ // return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bwn_pci_attach(device_t dev)
+{
+ struct bwn_pci_softc *sc;
+ const struct bwn_pci_device *ident;
+ int error;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ /* Find our hardware config */
+ if (bwn_pci_find_devcfg(dev, &sc->devcfg, &ident))
+ return (ENXIO);
+
+ /* Save quirk flags */
+ sc->quirks = ident->quirks;
+
+ /* Attach bridge device */
+ if ((error = bhndb_attach_bridge(dev, &sc->bhndb_dev, -1)))
+ return (ENXIO);
+
+ /* Success */
+ return (0);
+}
+
+static int
+bwn_pci_detach(device_t dev)
+{
+ return (bus_generic_detach(dev));
+}
+
+static void
+bwn_pci_probe_nomatch(device_t dev, device_t child)
+{
+ const char *name;
+
+ name = device_get_name(child);
+ if (name == NULL)
+ name = "unknown device";
+
+ device_printf(dev, "<%s> (no driver attached)\n", name);
+}
+
+static const struct bhndb_hwcfg *
+bwn_pci_get_generic_hwcfg(device_t dev, device_t child)
+{
+ struct bwn_pci_softc *sc = device_get_softc(dev);
+ return (sc->devcfg->bridge_hwcfg);
+}
+
+static const struct bhndb_hw *
+bwn_pci_get_bhndb_hwtable(device_t dev, device_t child)
+{
+ struct bwn_pci_softc *sc = device_get_softc(dev);
+ return (sc->devcfg->bridge_hwtable);
+}
+
+static bool
+bwn_pci_is_core_disabled(device_t dev, device_t child,
+ struct bhnd_core_info *core)
+{
+ struct bwn_pci_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ switch (bhnd_core_class(core)) {
+ case BHND_DEVCLASS_WLAN:
+ if (core->unit > 0 && !(sc->quirks & BWN_QUIRK_WLAN_DUALCORE))
+ return (true);
+
+ return (false);
+
+ case BHND_DEVCLASS_ENET:
+ case BHND_DEVCLASS_ENET_MAC:
+ case BHND_DEVCLASS_ENET_PHY:
+ return ((sc->quirks & BWN_QUIRK_ENET_HW_UNPOPULATED) != 0);
+
+ default:
+ return (false);
+ }
+}
+
+static device_method_t bwn_pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, bwn_pci_probe),
+ DEVMETHOD(device_attach, bwn_pci_attach),
+ DEVMETHOD(device_detach, bwn_pci_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+
+ /* Bus interface */
+ DEVMETHOD(bus_probe_nomatch, bwn_pci_probe_nomatch),
+
+ /* BHNDB_BUS Interface */
+ DEVMETHOD(bhndb_bus_get_generic_hwcfg, bwn_pci_get_generic_hwcfg),
+ DEVMETHOD(bhndb_bus_get_hardware_table, bwn_pci_get_bhndb_hwtable),
+ DEVMETHOD(bhndb_bus_is_core_disabled, bwn_pci_is_core_disabled),
+
+ DEVMETHOD_END
+};
+
+static devclass_t bwn_pci_devclass;
+
+DEFINE_CLASS_0(bwn_pci, bwn_pci_driver, bwn_pci_methods, sizeof(struct bwn_pci_softc));
+DRIVER_MODULE(bwn_pci, pci, bwn_pci_driver, bwn_pci_devclass, NULL, NULL);
+DRIVER_MODULE(bhndb, bwn_pci, bhndb_pci_driver, bhndb_devclass, NULL, NULL);
+
+MODULE_DEPEND(bwn_pci, bwn, 1, 1, 1);
+MODULE_DEPEND(bwn_pci, bhndb, 1, 1, 1);
+MODULE_DEPEND(bwn_pci, bhndb_pci, 1, 1, 1);
+MODULE_DEPEND(bwn_pci, bcma_bhndb, 1, 1, 1);
+MODULE_DEPEND(bwn_pci, siba_bhndb, 1, 1, 1);
diff --git a/sys/dev/bwn/if_bwn_pcivar.h b/sys/dev/bwn/if_bwn_pcivar.h
new file mode 100644
index 0000000..aabb3e8
--- /dev/null
+++ b/sys/dev/bwn/if_bwn_pcivar.h
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _IF_BWN_PCIVAR_H_
+#define _IF_BWN_PCIVAR_H_
+
+struct bwn_pci_devcfg;
+
+/** bwn_pci per-instance state. */
+struct bwn_pci_softc {
+ device_t dev; /**< device */
+ device_t bhndb_dev; /**< bhnd bridge device */
+ const struct bwn_pci_devcfg *devcfg; /**< bwn device config */
+ uint32_t quirks; /**< quirk flags */
+};
+
+/* bwn device quirks */
+enum {
+ /** No quirks */
+ BWN_QUIRK_NONE = 0,
+
+ /**
+ * This model/revision has not been tested and may not work.
+ */
+ BWN_QUIRK_UNTESTED = 1<<0,
+
+ /**
+ * Early dual-band devices did not support accessing multiple PHYs
+ * from a single WLAN core, and instead used separate 2GHz and 5GHz
+ * WLAN cores.
+ *
+ * However, not all cards with two WLAN cores are fully populated;
+ * we must whitelist the boards on which a second WLAN core is actually
+ * usable.
+ */
+ BWN_QUIRK_WLAN_DUALCORE = 1<<1,
+
+ /**
+ * Some early devices shipped with unconnected ethernet cores; set
+ * this quirk to treat these cores as unpopulated.
+ */
+ BWN_QUIRK_ENET_HW_UNPOPULATED = 1<<2,
+};
+
+/* PCI device descriptor */
+struct bwn_pci_device {
+ uint16_t vendor;
+ uint16_t device;
+ const char *desc;
+ uint32_t quirks;
+};
+
+
+#define BWN_BCM_DEV(_devid, _desc, _quirks) \
+ { PCI_VENDOR_BROADCOM, PCI_DEVID_ ## _devid, \
+ "Broadcom " _desc " Wireless", _quirks }
+
+/* Supported device table */
+struct bwn_pci_devcfg {
+ const struct bhndb_hwcfg *bridge_hwcfg;
+ const struct bhndb_hw *bridge_hwtable;
+ const struct bwn_pci_device *devices;
+};
+
+#endif /* _IF_BWN_PCIVAR_H_ */ \ No newline at end of file
diff --git a/sys/dev/bwn/if_bwnvar.h b/sys/dev/bwn/if_bwnvar.h
index b8295ec..e3e5815 100644
--- a/sys/dev/bwn/if_bwnvar.h
+++ b/sys/dev/bwn/if_bwnvar.h
@@ -751,6 +751,12 @@ struct bwn_fwinitvals {
} __packed data;
} __packed;
+enum bwn_fw_hdr_format {
+ BWN_FW_HDR_598,
+ BWN_FW_HDR_410,
+ BWN_FW_HDR_351,
+};
+
enum bwn_fwtype {
BWN_FWTYPE_DEFAULT,
BWN_FWTYPE_OPENSOURCE,
@@ -773,6 +779,7 @@ struct bwn_fw {
struct bwn_fwfile pcm;
struct bwn_fwfile initvals;
struct bwn_fwfile initvals_band;
+ enum bwn_fw_hdr_format fw_hdr_format;
uint16_t rev;
uint16_t patch;
diff --git a/sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt b/sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt
index 43dc76e..cc8ad8b 100644
--- a/sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt
+++ b/sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt
@@ -17,7 +17,7 @@
# finite. This requires balancing the configuration/operation needs of
# device drivers across OSes and a large number of customer application.
#
-# Some of the more important resources to allocate and their constraints are:
+# Some of the more important resources to allocate and their constaints are:
# 1. Virtual Interfaces: 128.
# 2. Ingress Queues with Free Lists: 1024. PCI-E SR-IOV Virtual Functions
# must use a power of 2 Ingress Queues.
@@ -275,7 +275,7 @@
# to directly select the type of Physical Function to which they wish to be
# attached.
#
-# Note that the actual values used for the PCI-E Intellectual Property will be
+# Note that the actual values used for the PCI-E Intelectual Property will be
# 1 less than those below since that's the way it "counts" things. For
# readability, we use the number we actually mean ...
#
diff --git a/sys/dev/cxgbe/firmware/t5fw_cfg_fpga.txt b/sys/dev/cxgbe/firmware/t5fw_cfg_fpga.txt
index 4c74fa1..e1c8b00 100644
--- a/sys/dev/cxgbe/firmware/t5fw_cfg_fpga.txt
+++ b/sys/dev/cxgbe/firmware/t5fw_cfg_fpga.txt
@@ -17,7 +17,7 @@
# finite. This requires balancing the configuration/operation needs of
# device drivers across OSes and a large number of customer application.
#
-# Some of the more important resources to allocate and their constraints are:
+# Some of the more important resources to allocate and their constaints are:
# 1. Virtual Interfaces: 128.
# 2. Ingress Queues with Free Lists: 1024. PCI-E SR-IOV Virtual Functions
# must use a power of 2 Ingress Queues.
@@ -292,7 +292,7 @@
# to directly select the type of Physical Function to which they wish to be
# attached.
#
-# Note that the actual values used for the PCI-E Intellectual Property will be
+# Note that the actual values used for the PCI-E Intelectual Property will be
# 1 less than those below since that's the way it "counts" things. For
# readability, we use the number we actually mean ...
#
diff --git a/sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt b/sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt
index d6caf2c..6fcc934 100644
--- a/sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt
+++ b/sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt
@@ -18,7 +18,7 @@
# are finite. This requires balancing the configuration/operation needs of
# device drivers across OSes and a large number of customer application.
#
-# Some of the more important resources to allocate and their constraints are:
+# Some of the more important resources to allocate and their constaints are:
# 1. Virtual Interfaces: 256.
# 2. Ingress Queues with Free Lists: 1024.
# 3. Egress Queues: 128K.
@@ -309,7 +309,7 @@
# to directly select the type of Physical Function to which they wish to be
# attached.
#
-# Note that the actual values used for the PCI-E Intellectual Property will be
+# Note that the actual values used for the PCI-E Intelectual Property will be
# 1 less than those below since that's the way it "counts" things. For
# readability, we use the number we actually mean ...
#
diff --git a/sys/dev/cxgbe/iw_cxgbe/cm.c b/sys/dev/cxgbe/iw_cxgbe/cm.c
index c2b72fa..3759140 100644
--- a/sys/dev/cxgbe/iw_cxgbe/cm.c
+++ b/sys/dev/cxgbe/iw_cxgbe/cm.c
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
struct sge_iq;
struct rss_header;
+struct cpl_set_tcb_rpl;
#include <linux/types.h>
#include "offload.h"
#include "tom/t4_tom.h"
diff --git a/sys/dev/cxgbe/offload.h b/sys/dev/cxgbe/offload.h
index d1363c4..22612d5 100644
--- a/sys/dev/cxgbe/offload.h
+++ b/sys/dev/cxgbe/offload.h
@@ -145,8 +145,6 @@ struct uld_info {
struct tom_tunables {
int sndbuf;
int ddp;
- int indsz;
- int ddp_thres;
int rx_coalesce;
int tx_align;
};
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 1e86aa9..132d69e 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -4901,15 +4901,6 @@ t4_sysctls(struct adapter *sc)
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "ddp", CTLFLAG_RW,
&sc->tt.ddp, 0, "DDP allowed");
- sc->tt.indsz = G_INDICATESIZE(t4_read_reg(sc, A_TP_PARA_REG5));
- SYSCTL_ADD_INT(ctx, children, OID_AUTO, "indsz", CTLFLAG_RW,
- &sc->tt.indsz, 0, "DDP max indicate size allowed");
-
- sc->tt.ddp_thres =
- G_RXCOALESCESIZE(t4_read_reg(sc, A_TP_PARA_REG2));
- SYSCTL_ADD_INT(ctx, children, OID_AUTO, "ddp_thres", CTLFLAG_RW,
- &sc->tt.ddp_thres, 0, "DDP threshold");
-
sc->tt.rx_coalesce = 1;
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "rx_coalesce",
CTLFLAG_RW, &sc->tt.rx_coalesce, 0, "receive coalescing");
diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c
index 43e4d611..4710977 100644
--- a/sys/dev/cxgbe/tom/t4_cpl_io.c
+++ b/sys/dev/cxgbe/tom/t4_cpl_io.c
@@ -267,6 +267,7 @@ make_established(struct toepcb *toep, uint32_t snd_isn, uint32_t rcv_isn,
uint16_t tcpopt = be16toh(opt);
struct flowc_tx_params ftxp;
+ CURVNET_SET(so->so_vnet);
INP_WLOCK_ASSERT(inp);
KASSERT(tp->t_state == TCPS_SYN_SENT ||
tp->t_state == TCPS_SYN_RECEIVED,
@@ -317,6 +318,7 @@ make_established(struct toepcb *toep, uint32_t snd_isn, uint32_t rcv_isn,
send_flowc_wr(toep, &ftxp);
soisconnected(so);
+ CURVNET_RESTORE();
}
static int
@@ -341,7 +343,7 @@ send_rx_credits(struct adapter *sc, struct toepcb *toep, int credits)
}
void
-t4_rcvd(struct toedev *tod, struct tcpcb *tp)
+t4_rcvd_locked(struct toedev *tod, struct tcpcb *tp)
{
struct adapter *sc = tod->tod_softc;
struct inpcb *inp = tp->t_inpcb;
@@ -352,7 +354,7 @@ t4_rcvd(struct toedev *tod, struct tcpcb *tp)
INP_WLOCK_ASSERT(inp);
- SOCKBUF_LOCK(sb);
+ SOCKBUF_LOCK_ASSERT(sb);
KASSERT(toep->sb_cc >= sbused(sb),
("%s: sb %p has more data (%d) than last time (%d).",
__func__, sb, sbused(sb), toep->sb_cc));
@@ -370,6 +372,17 @@ t4_rcvd(struct toedev *tod, struct tcpcb *tp)
tp->rcv_wnd += credits;
tp->rcv_adv += credits;
}
+}
+
+void
+t4_rcvd(struct toedev *tod, struct tcpcb *tp)
+{
+ struct inpcb *inp = tp->t_inpcb;
+ struct socket *so = inp->inp_socket;
+ struct sockbuf *sb = &so->so_rcv;
+
+ SOCKBUF_LOCK(sb);
+ t4_rcvd_locked(tod, tp);
SOCKBUF_UNLOCK(sb);
}
@@ -1040,7 +1053,6 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
struct inpcb *inp = toep->inp;
struct tcpcb *tp = NULL;
struct socket *so;
- struct sockbuf *sb;
#ifdef INVARIANTS
unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
#endif
@@ -1086,12 +1098,14 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
tp->rcv_nxt++; /* FIN */
so = inp->inp_socket;
- sb = &so->so_rcv;
- SOCKBUF_LOCK(sb);
- if (__predict_false(toep->ddp_flags & (DDP_BUF0_ACTIVE | DDP_BUF1_ACTIVE))) {
- handle_ddp_close(toep, tp, sb, cpl->rcv_nxt);
+ if (toep->ulp_mode == ULP_MODE_TCPDDP) {
+ DDP_LOCK(toep);
+ if (__predict_false(toep->ddp_flags &
+ (DDP_BUF0_ACTIVE | DDP_BUF1_ACTIVE)))
+ handle_ddp_close(toep, tp, cpl->rcv_nxt);
+ DDP_UNLOCK(toep);
}
- socantrcvmore_locked(so); /* unlocks the sockbuf */
+ socantrcvmore(so);
if (toep->ulp_mode != ULP_MODE_RDMA) {
KASSERT(tp->rcv_nxt == be32toh(cpl->rcv_nxt),
@@ -1407,6 +1421,8 @@ do_rx_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
tp->rcv_wnd -= len;
tp->t_rcvtime = ticks;
+ if (toep->ulp_mode == ULP_MODE_TCPDDP)
+ DDP_LOCK(toep);
so = inp_inpcbtosocket(inp);
sb = &so->so_rcv;
SOCKBUF_LOCK(sb);
@@ -1416,6 +1432,8 @@ do_rx_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
__func__, tid, len);
m_freem(m);
SOCKBUF_UNLOCK(sb);
+ if (toep->ulp_mode == ULP_MODE_TCPDDP)
+ DDP_UNLOCK(toep);
INP_WUNLOCK(inp);
INP_INFO_RLOCK(&V_tcbinfo);
@@ -1429,6 +1447,7 @@ do_rx_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
}
/* receive buffer autosize */
+ CURVNET_SET(so->so_vnet);
if (sb->sb_flags & SB_AUTOSIZE &&
V_tcp_do_autorcvbuf &&
sb->sb_hiwat < V_tcp_autorcvbuf_max &&
@@ -1443,6 +1462,10 @@ do_rx_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
toep->rx_credits += newsize - hiwat;
}
+ if (toep->ddp_waiting_count != 0 || toep->ddp_active_count != 0)
+ CTR3(KTR_CXGBE, "%s: tid %u, non-ddp rx (%d bytes)", __func__,
+ tid, len);
+
if (toep->ulp_mode == ULP_MODE_TCPDDP) {
int changed = !(toep->ddp_flags & DDP_ON) ^ cpl->ddp_off;
@@ -1455,47 +1478,22 @@ do_rx_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
__func__));
/* Fell out of DDP mode */
- toep->ddp_flags &= ~(DDP_ON | DDP_BUF0_ACTIVE |
- DDP_BUF1_ACTIVE);
+ toep->ddp_flags &= ~DDP_ON;
+ CTR1(KTR_CXGBE, "%s: fell out of DDP mode",
+ __func__);
- if (ddp_placed)
- insert_ddp_data(toep, ddp_placed);
+ insert_ddp_data(toep, ddp_placed);
}
}
- if ((toep->ddp_flags & DDP_OK) == 0 &&
- time_uptime >= toep->ddp_disabled + DDP_RETRY_WAIT) {
- toep->ddp_score = DDP_LOW_SCORE;
- toep->ddp_flags |= DDP_OK;
- CTR3(KTR_CXGBE, "%s: tid %u DDP_OK @ %u",
- __func__, tid, time_uptime);
- }
-
if (toep->ddp_flags & DDP_ON) {
-
/*
- * CPL_RX_DATA with DDP on can only be an indicate. Ask
- * soreceive to post a buffer or disable DDP. The
- * payload that arrived in this indicate is appended to
- * the socket buffer as usual.
+ * CPL_RX_DATA with DDP on can only be an indicate.
+ * Start posting queued AIO requests via DDP. The
+ * payload that arrived in this indicate is appended
+ * to the socket buffer as usual.
*/
-
-#if 0
- CTR5(KTR_CXGBE,
- "%s: tid %u (0x%x) DDP indicate (seq 0x%x, len %d)",
- __func__, tid, toep->flags, be32toh(cpl->seq), len);
-#endif
- sb->sb_flags |= SB_DDP_INDICATE;
- } else if ((toep->ddp_flags & (DDP_OK|DDP_SC_REQ)) == DDP_OK &&
- tp->rcv_wnd > DDP_RSVD_WIN && len >= sc->tt.ddp_thres) {
-
- /*
- * DDP allowed but isn't on (and a request to switch it
- * on isn't pending either), and conditions are ripe for
- * it to work. Switch it on.
- */
-
- enable_ddp(sc, toep);
+ handle_ddp_indicate(toep);
}
}
@@ -1513,10 +1511,19 @@ do_rx_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
tp->rcv_wnd += credits;
tp->rcv_adv += credits;
}
+
+ if (toep->ddp_waiting_count > 0 && sbavail(sb) != 0) {
+ CTR2(KTR_CXGBE, "%s: tid %u queueing AIO task", __func__,
+ tid);
+ ddp_queue_toep(toep);
+ }
sorwakeup_locked(so);
SOCKBUF_UNLOCK_ASSERT(sb);
+ if (toep->ulp_mode == ULP_MODE_TCPDDP)
+ DDP_UNLOCK(toep);
INP_WUNLOCK(inp);
+ CURVNET_RESTORE();
return (0);
}
@@ -1676,6 +1683,7 @@ do_set_tcb_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
struct adapter *sc = iq->adapter;
const struct cpl_set_tcb_rpl *cpl = (const void *)(rss + 1);
unsigned int tid = GET_TID(cpl);
+ struct toepcb *toep;
#ifdef INVARIANTS
unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
#endif
@@ -1687,6 +1695,12 @@ do_set_tcb_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
if (is_ftid(sc, tid))
return (t4_filter_rpl(iq, rss, m)); /* TCB is a filter */
+ toep = lookup_tid(sc, tid);
+ if (toep->ulp_mode == ULP_MODE_TCPDDP) {
+ handle_ddp_tcb_rpl(toep, cpl);
+ return (0);
+ }
+
/*
* TOM and/or other ULPs don't request replies for CPL_SET_TCB or
* CPL_SET_TCB_FIELD requests. This can easily change and when it does
@@ -1728,6 +1742,31 @@ t4_set_tcb_field(struct adapter *sc, struct toepcb *toep, int ctrl,
}
void
+t4_set_tcb_field_rpl(struct adapter *sc, struct toepcb *toep, int ctrl,
+ uint16_t word, uint64_t mask, uint64_t val, uint8_t cookie)
+{
+ struct wrqe *wr;
+ struct cpl_set_tcb_field *req;
+
+ KASSERT((cookie & ~M_COOKIE) == 0, ("%s: invalid cookie %#x", __func__,
+ cookie));
+ wr = alloc_wrqe(sizeof(*req), ctrl ? toep->ctrlq : toep->ofld_txq);
+ if (wr == NULL) {
+ /* XXX */
+ panic("%s: allocation failure.", __func__);
+ }
+ req = wrtod(wr);
+
+ INIT_TP_WR_MIT_CPL(req, CPL_SET_TCB_FIELD, toep->tid);
+ req->reply_ctrl = htobe16(V_QUEUENO(toep->ofld_rxq->iq.abs_id));
+ req->word_cookie = htobe16(V_WORD(word) | V_COOKIE(cookie));
+ req->mask = htobe64(mask);
+ req->val = htobe64(val);
+
+ t4_wrq_tx(sc, wr);
+}
+
+void
t4_init_cpl_io_handlers(struct adapter *sc)
{
diff --git a/sys/dev/cxgbe/tom/t4_ddp.c b/sys/dev/cxgbe/tom/t4_ddp.c
index 2aa774d..8cba8ca 100644
--- a/sys/dev/cxgbe/tom/t4_ddp.c
+++ b/sys/dev/cxgbe/tom/t4_ddp.c
@@ -31,7 +31,8 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include <sys/param.h>
-#include <sys/types.h>
+#include <sys/aio.h>
+#include <sys/file.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
@@ -41,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
+#include <sys/taskqueue.h>
#include <sys/uio.h>
#include <netinet/in.h>
#include <netinet/in_pcb.h>
@@ -72,7 +74,10 @@ VNET_DECLARE(int, tcp_autorcvbuf_inc);
VNET_DECLARE(int, tcp_autorcvbuf_max);
#define V_tcp_autorcvbuf_max VNET(tcp_autorcvbuf_max)
-static struct mbuf *get_ddp_mbuf(int len);
+static void aio_ddp_requeue_task(void *context, int pending);
+static void ddp_complete_all(struct toepcb *toep, int error);
+static void t4_aio_cancel_active(struct kaiocb *job);
+static void t4_aio_cancel_queued(struct kaiocb *job);
#define PPOD_SZ(n) ((n) * sizeof(struct pagepod))
#define PPOD_SIZE (PPOD_SZ(1))
@@ -80,6 +85,10 @@ static struct mbuf *get_ddp_mbuf(int len);
/* XXX: must match A_ULP_RX_TDDP_PSZ */
static int t4_ddp_pgsz[] = {4096, 4096 << 2, 4096 << 4, 4096 << 6};
+static TAILQ_HEAD(, pageset) ddp_orphan_pagesets;
+static struct mtx ddp_orphan_pagesets_lock;
+static struct task ddp_orphan_task;
+
#define MAX_DDP_BUFFER_SIZE (M_TCB_RX_DDP_BUF0_LEN)
static int
alloc_ppods(struct tom_data *td, int n, u_int *ppod_addr)
@@ -112,33 +121,199 @@ pages_to_nppods(int npages, int ddp_pgsz)
return (howmany(nsegs, PPOD_PAGES));
}
+/*
+ * A page set holds information about a buffer used for DDP. The page
+ * set holds resources such as the VM pages backing the buffer (either
+ * held or wired) and the page pods associated with the buffer.
+ * Recently used page sets are cached to allow for efficient reuse of
+ * buffers (avoiding the need to re-fault in pages, hold them, etc.).
+ * Note that cached page sets keep the backing pages wired. The
+ * number of wired pages is capped by only allowing for two wired
+ * pagesets per connection. This is not a perfect cap, but is a
+ * trade-off for performance.
+ *
+ * If an application ping-pongs two buffers for a connection via
+ * aio_read(2) then those buffers should remain wired and expensive VM
+ * fault lookups should be avoided after each buffer has been used
+ * once. If an application uses more than two buffers then this will
+ * fall back to doing expensive VM fault lookups for each operation.
+ */
+static void
+free_pageset(struct tom_data *td, struct pageset *ps)
+{
+ vm_page_t p;
+ int i;
+
+ if (ps->nppods > 0)
+ free_ppods(td, ps->ppod_addr, ps->nppods);
+
+ if (ps->flags & PS_WIRED) {
+ for (i = 0; i < ps->npages; i++) {
+ p = ps->pages[i];
+ vm_page_lock(p);
+ vm_page_unwire(p, PQ_INACTIVE);
+ vm_page_unlock(p);
+ }
+ } else
+ vm_page_unhold_pages(ps->pages, ps->npages);
+ mtx_lock(&ddp_orphan_pagesets_lock);
+ TAILQ_INSERT_TAIL(&ddp_orphan_pagesets, ps, link);
+ taskqueue_enqueue(taskqueue_thread, &ddp_orphan_task);
+ mtx_unlock(&ddp_orphan_pagesets_lock);
+}
+
+static void
+ddp_free_orphan_pagesets(void *context, int pending)
+{
+ struct pageset *ps;
+
+ mtx_lock(&ddp_orphan_pagesets_lock);
+ while (!TAILQ_EMPTY(&ddp_orphan_pagesets)) {
+ ps = TAILQ_FIRST(&ddp_orphan_pagesets);
+ TAILQ_REMOVE(&ddp_orphan_pagesets, ps, link);
+ mtx_unlock(&ddp_orphan_pagesets_lock);
+ if (ps->vm)
+ vmspace_free(ps->vm);
+ free(ps, M_CXGBE);
+ mtx_lock(&ddp_orphan_pagesets_lock);
+ }
+ mtx_unlock(&ddp_orphan_pagesets_lock);
+}
+
+static void
+recycle_pageset(struct toepcb *toep, struct pageset *ps)
+{
+
+ DDP_ASSERT_LOCKED(toep);
+ if (!(toep->ddp_flags & DDP_DEAD) && ps->flags & PS_WIRED) {
+ KASSERT(toep->ddp_cached_count + toep->ddp_active_count <
+ nitems(toep->db), ("too many wired pagesets"));
+ TAILQ_INSERT_HEAD(&toep->ddp_cached_pagesets, ps, link);
+ toep->ddp_cached_count++;
+ } else
+ free_pageset(toep->td, ps);
+}
+
+static void
+ddp_complete_one(struct kaiocb *job, int error)
+{
+ long copied;
+
+ /*
+ * If this job had copied data out of the socket buffer before
+ * it was cancelled, report it as a short read rather than an
+ * error.
+ */
+ copied = job->uaiocb._aiocb_private.status;
+ if (copied != 0 || error == 0)
+ aio_complete(job, copied, 0);
+ else
+ aio_complete(job, -1, error);
+}
+
static void
free_ddp_buffer(struct tom_data *td, struct ddp_buffer *db)
{
- if (db == NULL)
- return;
+ if (db->job) {
+ /*
+ * XXX: If we are un-offloading the socket then we
+ * should requeue these on the socket somehow. If we
+ * got a FIN from the remote end, then this completes
+ * any remaining requests with an EOF read.
+ */
+ if (!aio_clear_cancel_function(db->job))
+ ddp_complete_one(db->job, 0);
+ }
+
+ if (db->ps)
+ free_pageset(td, db->ps);
+}
- if (db->pages)
- free(db->pages, M_CXGBE);
+void
+ddp_init_toep(struct toepcb *toep)
+{
+
+ TAILQ_INIT(&toep->ddp_aiojobq);
+ TASK_INIT(&toep->ddp_requeue_task, 0, aio_ddp_requeue_task, toep);
+ toep->ddp_active_id = -1;
+ mtx_init(&toep->ddp_lock, "t4 ddp", NULL, MTX_DEF);
+}
- if (db->nppods > 0)
- free_ppods(td, db->ppod_addr, db->nppods);
+void
+ddp_uninit_toep(struct toepcb *toep)
+{
- free(db, M_CXGBE);
+ mtx_destroy(&toep->ddp_lock);
}
void
release_ddp_resources(struct toepcb *toep)
{
+ struct pageset *ps;
int i;
+ DDP_LOCK(toep);
+ toep->flags |= DDP_DEAD;
for (i = 0; i < nitems(toep->db); i++) {
- if (toep->db[i] != NULL) {
- free_ddp_buffer(toep->td, toep->db[i]);
- toep->db[i] = NULL;
- }
+ free_ddp_buffer(toep->td, &toep->db[i]);
+ }
+ while ((ps = TAILQ_FIRST(&toep->ddp_cached_pagesets)) != NULL) {
+ TAILQ_REMOVE(&toep->ddp_cached_pagesets, ps, link);
+ free_pageset(toep->td, ps);
+ }
+ ddp_complete_all(toep, 0);
+ DDP_UNLOCK(toep);
+}
+
+#ifdef INVARIANTS
+void
+ddp_assert_empty(struct toepcb *toep)
+{
+ int i;
+
+ MPASS(!(toep->ddp_flags & DDP_TASK_ACTIVE));
+ for (i = 0; i < nitems(toep->db); i++) {
+ MPASS(toep->db[i].job == NULL);
+ MPASS(toep->db[i].ps == NULL);
}
+ MPASS(TAILQ_EMPTY(&toep->ddp_cached_pagesets));
+ MPASS(TAILQ_EMPTY(&toep->ddp_aiojobq));
+}
+#endif
+
+static void
+complete_ddp_buffer(struct toepcb *toep, struct ddp_buffer *db,
+ unsigned int db_idx)
+{
+ unsigned int db_flag;
+
+ toep->ddp_active_count--;
+ if (toep->ddp_active_id == db_idx) {
+ if (toep->ddp_active_count == 0) {
+ KASSERT(toep->db[db_idx ^ 1].job == NULL,
+ ("%s: active_count mismatch", __func__));
+ toep->ddp_active_id = -1;
+ } else
+ toep->ddp_active_id ^= 1;
+ CTR2(KTR_CXGBE, "%s: ddp_active_id = %d", __func__,
+ toep->ddp_active_id);
+ } else {
+ KASSERT(toep->ddp_active_count != 0 &&
+ toep->ddp_active_id != -1,
+ ("%s: active count mismatch", __func__));
+ }
+
+ db->cancel_pending = 0;
+ db->job = NULL;
+ recycle_pageset(toep, db->ps);
+ db->ps = NULL;
+
+ db_flag = db_idx == 1 ? DDP_BUF1_ACTIVE : DDP_BUF0_ACTIVE;
+ KASSERT(toep->ddp_flags & db_flag,
+ ("%s: DDP buffer not active. toep %p, ddp_flags 0x%x",
+ __func__, toep, toep->ddp_flags));
+ toep->ddp_flags &= ~db_flag;
}
/* XXX: handle_ddp_data code duplication */
@@ -147,28 +322,59 @@ insert_ddp_data(struct toepcb *toep, uint32_t n)
{
struct inpcb *inp = toep->inp;
struct tcpcb *tp = intotcpcb(inp);
- struct sockbuf *sb = &inp->inp_socket->so_rcv;
- struct mbuf *m;
+ struct ddp_buffer *db;
+ struct kaiocb *job;
+ size_t placed;
+ long copied;
+ unsigned int db_flag, db_idx;
INP_WLOCK_ASSERT(inp);
- SOCKBUF_LOCK_ASSERT(sb);
+ DDP_ASSERT_LOCKED(toep);
- m = get_ddp_mbuf(n);
tp->rcv_nxt += n;
#ifndef USE_DDP_RX_FLOW_CONTROL
KASSERT(tp->rcv_wnd >= n, ("%s: negative window size", __func__));
tp->rcv_wnd -= n;
#endif
-
- KASSERT(toep->sb_cc >= sbused(sb),
- ("%s: sb %p has more data (%d) than last time (%d).",
- __func__, sb, sbused(sb), toep->sb_cc));
- toep->rx_credits += toep->sb_cc - sbused(sb);
-#ifdef USE_DDP_RX_FLOW_CONTROL
- toep->rx_credits -= n; /* adjust for F_RX_FC_DDP */
+#ifndef USE_DDP_RX_FLOW_CONTROL
+ toep->rx_credits += n;
#endif
- sbappendstream_locked(sb, m, 0);
- toep->sb_cc = sbused(sb);
+ CTR2(KTR_CXGBE, "%s: placed %u bytes before falling out of DDP",
+ __func__, n);
+ while (toep->ddp_active_count > 0) {
+ MPASS(toep->ddp_active_id != -1);
+ db_idx = toep->ddp_active_id;
+ db_flag = db_idx == 1 ? DDP_BUF1_ACTIVE : DDP_BUF0_ACTIVE;
+ MPASS((toep->ddp_flags & db_flag) != 0);
+ db = &toep->db[db_idx];
+ job = db->job;
+ copied = job->uaiocb._aiocb_private.status;
+ placed = n;
+ if (placed > job->uaiocb.aio_nbytes - copied)
+ placed = job->uaiocb.aio_nbytes - copied;
+ if (!aio_clear_cancel_function(job)) {
+ /*
+ * Update the copied length for when
+ * t4_aio_cancel_active() completes this
+ * request.
+ */
+ job->uaiocb._aiocb_private.status += placed;
+ } else if (copied + placed != 0) {
+ CTR4(KTR_CXGBE,
+ "%s: completing %p (copied %ld, placed %lu)",
+ __func__, job, copied, placed);
+ /* XXX: This always completes if there is some data. */
+ aio_complete(job, copied + placed, 0);
+ } else if (aio_set_cancel_function(job, t4_aio_cancel_queued)) {
+ TAILQ_INSERT_HEAD(&toep->ddp_aiojobq, job, list);
+ toep->ddp_waiting_count++;
+ } else
+ aio_cancel(job);
+ n -= placed;
+ complete_ddp_buffer(toep, db, db_idx);
+ }
+
+ MPASS(n == 0);
}
/* SET_TCB_FIELD sent as a ULP command looks like this */
@@ -236,42 +442,10 @@ mk_rx_data_ack_ulp(struct ulp_txpkt *ulpmc, struct toepcb *toep)
return (ulpsc);
}
-static inline uint64_t
-select_ddp_flags(struct socket *so, int flags, int db_idx)
-{
- uint64_t ddp_flags = V_TF_DDP_INDICATE_OUT(0);
- int waitall = flags & MSG_WAITALL;
- int nb = so->so_state & SS_NBIO || flags & (MSG_DONTWAIT | MSG_NBIO);
-
- KASSERT(db_idx == 0 || db_idx == 1,
- ("%s: bad DDP buffer index %d", __func__, db_idx));
-
- if (db_idx == 0) {
- ddp_flags |= V_TF_DDP_BUF0_VALID(1) | V_TF_DDP_ACTIVE_BUF(0);
- if (waitall)
- ddp_flags |= V_TF_DDP_PUSH_DISABLE_0(1);
- else if (nb)
- ddp_flags |= V_TF_DDP_BUF0_FLUSH(1);
- else
- ddp_flags |= V_TF_DDP_BUF0_FLUSH(0);
- } else {
- ddp_flags |= V_TF_DDP_BUF1_VALID(1) | V_TF_DDP_ACTIVE_BUF(1);
- if (waitall)
- ddp_flags |= V_TF_DDP_PUSH_DISABLE_1(1);
- else if (nb)
- ddp_flags |= V_TF_DDP_BUF1_FLUSH(1);
- else
- ddp_flags |= V_TF_DDP_BUF1_FLUSH(0);
- }
-
- return (ddp_flags);
-}
-
static struct wrqe *
mk_update_tcb_for_ddp(struct adapter *sc, struct toepcb *toep, int db_idx,
- int offset, uint64_t ddp_flags)
+ struct pageset *ps, int offset, uint64_t ddp_flags, uint64_t ddp_flags_mask)
{
- struct ddp_buffer *db = toep->db[db_idx];
struct wrqe *wr;
struct work_request_hdr *wrh;
struct ulp_txpkt *ulpmc;
@@ -302,7 +476,7 @@ mk_update_tcb_for_ddp(struct adapter *sc, struct toepcb *toep, int db_idx,
ulpmc = mk_set_tcb_field_ulp(ulpmc, toep,
W_TCB_RX_DDP_BUF0_TAG + db_idx,
V_TCB_RX_DDP_BUF0_TAG(M_TCB_RX_DDP_BUF0_TAG),
- V_TCB_RX_DDP_BUF0_TAG(db->tag));
+ V_TCB_RX_DDP_BUF0_TAG(ps->tag));
/* Update the current offset in the DDP buffer and its total length */
if (db_idx == 0)
@@ -311,21 +485,18 @@ mk_update_tcb_for_ddp(struct adapter *sc, struct toepcb *toep, int db_idx,
V_TCB_RX_DDP_BUF0_OFFSET(M_TCB_RX_DDP_BUF0_OFFSET) |
V_TCB_RX_DDP_BUF0_LEN(M_TCB_RX_DDP_BUF0_LEN),
V_TCB_RX_DDP_BUF0_OFFSET(offset) |
- V_TCB_RX_DDP_BUF0_LEN(db->len));
+ V_TCB_RX_DDP_BUF0_LEN(ps->len));
else
ulpmc = mk_set_tcb_field_ulp(ulpmc, toep,
W_TCB_RX_DDP_BUF1_OFFSET,
V_TCB_RX_DDP_BUF1_OFFSET(M_TCB_RX_DDP_BUF1_OFFSET) |
V_TCB_RX_DDP_BUF1_LEN((u64)M_TCB_RX_DDP_BUF1_LEN << 32),
V_TCB_RX_DDP_BUF1_OFFSET(offset) |
- V_TCB_RX_DDP_BUF1_LEN((u64)db->len << 32));
+ V_TCB_RX_DDP_BUF1_LEN((u64)ps->len << 32));
/* Update DDP flags */
ulpmc = mk_set_tcb_field_ulp(ulpmc, toep, W_TCB_RX_DDP_FLAGS,
- V_TF_DDP_BUF0_FLUSH(1) | V_TF_DDP_BUF1_FLUSH(1) |
- V_TF_DDP_PUSH_DISABLE_0(1) | V_TF_DDP_PUSH_DISABLE_1(1) |
- V_TF_DDP_BUF0_VALID(1) | V_TF_DDP_BUF1_VALID(1) |
- V_TF_DDP_ACTIVE_BUF(1) | V_TF_DDP_INDICATE_OUT(1), ddp_flags);
+ ddp_flags_mask, ddp_flags);
/* Gratuitous RX_DATA_ACK with RX_MODULATE set to speed up delivery. */
ulpmc = mk_rx_data_ack_ulp(ulpmc, toep);
@@ -333,30 +504,20 @@ mk_update_tcb_for_ddp(struct adapter *sc, struct toepcb *toep, int db_idx,
return (wr);
}
-static void
-discourage_ddp(struct toepcb *toep)
-{
-
- if (toep->ddp_score && --toep->ddp_score == 0) {
- toep->ddp_flags &= ~DDP_OK;
- toep->ddp_disabled = time_uptime;
- CTR3(KTR_CXGBE, "%s: tid %u !DDP_OK @ %u",
- __func__, toep->tid, time_uptime);
- }
-}
-
static int
handle_ddp_data(struct toepcb *toep, __be32 ddp_report, __be32 rcv_nxt, int len)
{
uint32_t report = be32toh(ddp_report);
- unsigned int db_flag;
+ unsigned int db_idx;
struct inpcb *inp = toep->inp;
+ struct ddp_buffer *db;
struct tcpcb *tp;
struct socket *so;
struct sockbuf *sb;
- struct mbuf *m;
+ struct kaiocb *job;
+ long copied;
- db_flag = report & F_DDP_BUF_IDX ? DDP_BUF1_ACTIVE : DDP_BUF0_ACTIVE;
+ db_idx = report & F_DDP_BUF_IDX ? 1 : 0;
if (__predict_false(!(report & F_DDP_INV)))
CXGBE_UNIMPLEMENTED("DDP buffer still valid");
@@ -364,19 +525,24 @@ handle_ddp_data(struct toepcb *toep, __be32 ddp_report, __be32 rcv_nxt, int len)
INP_WLOCK(inp);
so = inp_inpcbtosocket(inp);
sb = &so->so_rcv;
- if (__predict_false(inp->inp_flags & (INP_DROPPED | INP_TIMEWAIT))) {
+ DDP_LOCK(toep);
+
+ KASSERT(toep->ddp_active_id == db_idx,
+ ("completed DDP buffer (%d) != active_id (%d) for tid %d", db_idx,
+ toep->ddp_active_id, toep->tid));
+ db = &toep->db[db_idx];
+ job = db->job;
+ if (__predict_false(inp->inp_flags & (INP_DROPPED | INP_TIMEWAIT))) {
/*
- * XXX: think a bit more.
- * tcpcb probably gone, but socket should still be around
- * because we always wait for DDP completion in soreceive no
- * matter what. Just wake it up and let it clean up.
+ * This can happen due to an administrative tcpdrop(8).
+ * Just fail the request with ECONNRESET.
*/
-
CTR5(KTR_CXGBE, "%s: tid %u, seq 0x%x, len %d, inp_flags 0x%x",
__func__, toep->tid, be32toh(rcv_nxt), len, inp->inp_flags);
- SOCKBUF_LOCK(sb);
- goto wakeup;
+ if (aio_clear_cancel_function(job))
+ ddp_complete_one(job, ECONNRESET);
+ goto completed;
}
tp = intotcpcb(inp);
@@ -386,7 +552,7 @@ handle_ddp_data(struct toepcb *toep, __be32 ddp_report, __be32 rcv_nxt, int len)
* sequence number of the next byte to receive. The length of
* the data received for this message must be computed by
* comparing the new and old values of rcv_nxt.
- *
+ *
* For RX_DATA_DDP, len might be non-zero, but it is only the
* length of the most recent DMA. It does not include the
* total length of the data received since the previous update
@@ -400,15 +566,14 @@ handle_ddp_data(struct toepcb *toep, __be32 ddp_report, __be32 rcv_nxt, int len)
KASSERT(tp->rcv_wnd >= len, ("%s: negative window size", __func__));
tp->rcv_wnd -= len;
#endif
- m = get_ddp_mbuf(len);
-
- SOCKBUF_LOCK(sb);
- if (report & F_DDP_BUF_COMPLETE)
- toep->ddp_score = DDP_HIGH_SCORE;
- else
- discourage_ddp(toep);
+#ifdef VERBOSE_TRACES
+ CTR4(KTR_CXGBE, "%s: DDP[%d] placed %d bytes (%#x)", __func__, db_idx,
+ len, report);
+#endif
/* receive buffer autosize */
+ CURVNET_SET(so->so_vnet);
+ SOCKBUF_LOCK(sb);
if (sb->sb_flags & SB_AUTOSIZE &&
V_tcp_do_autorcvbuf &&
sb->sb_hiwat < V_tcp_autorcvbuf_max &&
@@ -422,57 +587,185 @@ handle_ddp_data(struct toepcb *toep, __be32 ddp_report, __be32 rcv_nxt, int len)
else
toep->rx_credits += newsize - hiwat;
}
+ SOCKBUF_UNLOCK(sb);
+ CURVNET_RESTORE();
- KASSERT(toep->sb_cc >= sbused(sb),
- ("%s: sb %p has more data (%d) than last time (%d).",
- __func__, sb, sbused(sb), toep->sb_cc));
- toep->rx_credits += toep->sb_cc - sbused(sb);
-#ifdef USE_DDP_RX_FLOW_CONTROL
- toep->rx_credits -= len; /* adjust for F_RX_FC_DDP */
+#ifndef USE_DDP_RX_FLOW_CONTROL
+ toep->rx_credits += len;
#endif
- sbappendstream_locked(sb, m, 0);
- toep->sb_cc = sbused(sb);
-wakeup:
- KASSERT(toep->ddp_flags & db_flag,
- ("%s: DDP buffer not active. toep %p, ddp_flags 0x%x, report 0x%x",
- __func__, toep, toep->ddp_flags, report));
- toep->ddp_flags &= ~db_flag;
- sorwakeup_locked(so);
- SOCKBUF_UNLOCK_ASSERT(sb);
+ if (db->cancel_pending) {
+ /*
+ * Update the job's length but defer completion to the
+ * TCB_RPL callback.
+ */
+ job->uaiocb._aiocb_private.status += len;
+ goto out;
+ } else if (!aio_clear_cancel_function(job)) {
+ /*
+ * Update the copied length for when
+ * t4_aio_cancel_active() completes this request.
+ */
+ job->uaiocb._aiocb_private.status += len;
+ } else {
+ copied = job->uaiocb._aiocb_private.status;
+#ifdef VERBOSE_TRACES
+ CTR4(KTR_CXGBE, "%s: completing %p (copied %ld, placed %d)",
+ __func__, job, copied, len);
+#endif
+ aio_complete(job, copied + len, 0);
+ t4_rcvd(&toep->td->tod, tp);
+ }
+
+completed:
+ complete_ddp_buffer(toep, db, db_idx);
+ if (toep->ddp_waiting_count > 0)
+ ddp_queue_toep(toep);
+out:
+ DDP_UNLOCK(toep);
INP_WUNLOCK(inp);
+
return (0);
}
void
-handle_ddp_close(struct toepcb *toep, struct tcpcb *tp, struct sockbuf *sb,
- __be32 rcv_nxt)
+handle_ddp_indicate(struct toepcb *toep)
{
- struct mbuf *m;
- int len;
- SOCKBUF_LOCK_ASSERT(sb);
+ DDP_ASSERT_LOCKED(toep);
+ MPASS(toep->ddp_active_count == 0);
+ MPASS((toep->ddp_flags & (DDP_BUF0_ACTIVE | DDP_BUF1_ACTIVE)) == 0);
+ if (toep->ddp_waiting_count == 0) {
+ /*
+ * The pending requests that triggered the request for an
+ * an indicate were cancelled. Those cancels should have
+ * already disabled DDP. Just ignore this as the data is
+ * going into the socket buffer anyway.
+ */
+ return;
+ }
+ CTR3(KTR_CXGBE, "%s: tid %d indicated (%d waiting)", __func__,
+ toep->tid, toep->ddp_waiting_count);
+ ddp_queue_toep(toep);
+}
+
+enum {
+ DDP_BUF0_INVALIDATED = 0x2,
+ DDP_BUF1_INVALIDATED
+};
+
+void
+handle_ddp_tcb_rpl(struct toepcb *toep, const struct cpl_set_tcb_rpl *cpl)
+{
+ unsigned int db_idx;
+ struct inpcb *inp = toep->inp;
+ struct ddp_buffer *db;
+ struct kaiocb *job;
+ long copied;
+
+ if (cpl->status != CPL_ERR_NONE)
+ panic("XXX: tcp_rpl failed: %d", cpl->status);
+
+ switch (cpl->cookie) {
+ case V_WORD(W_TCB_RX_DDP_FLAGS) | V_COOKIE(DDP_BUF0_INVALIDATED):
+ case V_WORD(W_TCB_RX_DDP_FLAGS) | V_COOKIE(DDP_BUF1_INVALIDATED):
+ /*
+ * XXX: This duplicates a lot of code with handle_ddp_data().
+ */
+ db_idx = G_COOKIE(cpl->cookie) - DDP_BUF0_INVALIDATED;
+ INP_WLOCK(inp);
+ DDP_LOCK(toep);
+ db = &toep->db[db_idx];
+
+ /*
+ * handle_ddp_data() should leave the job around until
+ * this callback runs once a cancel is pending.
+ */
+ MPASS(db != NULL);
+ MPASS(db->job != NULL);
+ MPASS(db->cancel_pending);
+
+ /*
+ * XXX: It's not clear what happens if there is data
+ * placed when the buffer is invalidated. I suspect we
+ * need to read the TCB to see how much data was placed.
+ *
+ * For now this just pretends like nothing was placed.
+ *
+ * XXX: Note that if we did check the PCB we would need to
+ * also take care of updating the tp, etc.
+ */
+ job = db->job;
+ copied = job->uaiocb._aiocb_private.status;
+ if (copied == 0) {
+ CTR2(KTR_CXGBE, "%s: cancelling %p", __func__, job);
+ aio_cancel(job);
+ } else {
+ CTR3(KTR_CXGBE, "%s: completing %p (copied %ld)",
+ __func__, job, copied);
+ aio_complete(job, copied, 0);
+ t4_rcvd(&toep->td->tod, intotcpcb(inp));
+ }
+
+ complete_ddp_buffer(toep, db, db_idx);
+ if (toep->ddp_waiting_count > 0)
+ ddp_queue_toep(toep);
+ DDP_UNLOCK(toep);
+ INP_WUNLOCK(inp);
+ break;
+ default:
+ panic("XXX: unknown tcb_rpl offset %#x, cookie %#x",
+ G_WORD(cpl->cookie), G_COOKIE(cpl->cookie));
+ }
+}
+
+void
+handle_ddp_close(struct toepcb *toep, struct tcpcb *tp, __be32 rcv_nxt)
+{
+ struct ddp_buffer *db;
+ struct kaiocb *job;
+ long copied;
+ unsigned int db_flag, db_idx;
+ int len, placed;
+
INP_WLOCK_ASSERT(toep->inp);
+ DDP_ASSERT_LOCKED(toep);
len = be32toh(rcv_nxt) - tp->rcv_nxt;
- /* Signal handle_ddp() to break out of its sleep loop. */
- toep->ddp_flags &= ~(DDP_BUF0_ACTIVE | DDP_BUF1_ACTIVE);
- if (len == 0)
- return;
-
tp->rcv_nxt += len;
- KASSERT(toep->sb_cc >= sbused(sb),
- ("%s: sb %p has more data (%d) than last time (%d).",
- __func__, sb, sbused(sb), toep->sb_cc));
- toep->rx_credits += toep->sb_cc - sbused(sb);
-#ifdef USE_DDP_RX_FLOW_CONTROL
- toep->rx_credits -= len; /* adjust for F_RX_FC_DDP */
+#ifndef USE_DDP_RX_FLOW_CONTROL
+ toep->rx_credits += len;
#endif
- m = get_ddp_mbuf(len);
+ while (toep->ddp_active_count > 0) {
+ MPASS(toep->ddp_active_id != -1);
+ db_idx = toep->ddp_active_id;
+ db_flag = db_idx == 1 ? DDP_BUF1_ACTIVE : DDP_BUF0_ACTIVE;
+ MPASS((toep->ddp_flags & db_flag) != 0);
+ db = &toep->db[db_idx];
+ job = db->job;
+ copied = job->uaiocb._aiocb_private.status;
+ placed = len;
+ if (placed > job->uaiocb.aio_nbytes - copied)
+ placed = job->uaiocb.aio_nbytes - copied;
+ if (!aio_clear_cancel_function(job)) {
+ /*
+ * Update the copied length for when
+ * t4_aio_cancel_active() completes this
+ * request.
+ */
+ job->uaiocb._aiocb_private.status += placed;
+ } else {
+ CTR4(KTR_CXGBE, "%s: tid %d completed buf %d len %d",
+ __func__, toep->tid, db_idx, placed);
+ aio_complete(job, copied + placed, 0);
+ }
+ len -= placed;
+ complete_ddp_buffer(toep, db, db_idx);
+ }
- sbappendstream_locked(sb, m, 0);
- toep->sb_cc = sbused(sb);
+ MPASS(len == 0);
+ ddp_complete_all(toep, 0);
}
#define DDP_ERR (F_DDP_PPOD_MISMATCH | F_DDP_LLIMIT_ERR | F_DDP_ULIMIT_ERR |\
@@ -529,7 +822,7 @@ do_rx_ddp_complete(struct sge_iq *iq, const struct rss_header *rss,
return (0);
}
-void
+static void
enable_ddp(struct adapter *sc, struct toepcb *toep)
{
@@ -540,6 +833,7 @@ enable_ddp(struct adapter *sc, struct toepcb *toep)
CTR3(KTR_CXGBE, "%s: tid %u (time %u)",
__func__, toep->tid, time_uptime);
+ DDP_ASSERT_LOCKED(toep);
toep->ddp_flags |= DDP_SC_REQ;
t4_set_tcb_field(sc, toep, 1, W_TCB_RX_DDP_FLAGS,
V_TF_DDP_OFF(1) | V_TF_DDP_INDICATE_OUT(1) |
@@ -550,81 +844,6 @@ enable_ddp(struct adapter *sc, struct toepcb *toep)
V_TF_RCV_COALESCE_ENABLE(1), 0);
}
-static inline void
-disable_ddp(struct adapter *sc, struct toepcb *toep)
-{
-
- KASSERT((toep->ddp_flags & (DDP_ON | DDP_SC_REQ)) == DDP_ON,
- ("%s: toep %p has bad ddp_flags 0x%x",
- __func__, toep, toep->ddp_flags));
-
- CTR3(KTR_CXGBE, "%s: tid %u (time %u)",
- __func__, toep->tid, time_uptime);
-
- toep->ddp_flags |= DDP_SC_REQ;
- t4_set_tcb_field(sc, toep, 1, W_TCB_T_FLAGS,
- V_TF_RCV_COALESCE_ENABLE(1), V_TF_RCV_COALESCE_ENABLE(1));
- t4_set_tcb_field(sc, toep, 1, W_TCB_RX_DDP_FLAGS, V_TF_DDP_OFF(1),
- V_TF_DDP_OFF(1));
-}
-
-static int
-hold_uio(struct uio *uio, vm_page_t **ppages, int *pnpages)
-{
- struct vm_map *map;
- struct iovec *iov;
- vm_offset_t start, end;
- vm_page_t *pp;
- int n;
-
- KASSERT(uio->uio_iovcnt == 1,
- ("%s: uio_iovcnt %d", __func__, uio->uio_iovcnt));
- KASSERT(uio->uio_td->td_proc == curproc,
- ("%s: uio proc (%p) is not curproc (%p)",
- __func__, uio->uio_td->td_proc, curproc));
-
- map = &curproc->p_vmspace->vm_map;
- iov = &uio->uio_iov[0];
- start = trunc_page((uintptr_t)iov->iov_base);
- end = round_page((vm_offset_t)iov->iov_base + iov->iov_len);
- n = howmany(end - start, PAGE_SIZE);
-
- if (end - start > MAX_DDP_BUFFER_SIZE)
- return (E2BIG);
-
- pp = malloc(n * sizeof(vm_page_t), M_CXGBE, M_NOWAIT);
- if (pp == NULL)
- return (ENOMEM);
-
- if (vm_fault_quick_hold_pages(map, (vm_offset_t)iov->iov_base,
- iov->iov_len, VM_PROT_WRITE, pp, n) < 0) {
- free(pp, M_CXGBE);
- return (EFAULT);
- }
-
- *ppages = pp;
- *pnpages = n;
-
- return (0);
-}
-
-static int
-bufcmp(struct ddp_buffer *db, vm_page_t *pages, int npages, int offset, int len)
-{
- int i;
-
- if (db == NULL || db->npages != npages || db->offset != offset ||
- db->len != len)
- return (1);
-
- for (i = 0; i < npages; i++) {
- if (pages[i]->phys_addr != db->pages[i]->phys_addr)
- return (1);
- }
-
- return (0);
-}
-
static int
calculate_hcf(int n1, int n2)
{
@@ -647,12 +866,13 @@ calculate_hcf(int n1, int n2)
return (b);
}
-static struct ddp_buffer *
-alloc_ddp_buffer(struct tom_data *td, vm_page_t *pages, int npages, int offset,
- int len)
+static int
+alloc_page_pods(struct tom_data *td, struct pageset *ps)
{
int i, hcf, seglen, idx, ppod, nppods;
- struct ddp_buffer *db;
+ u_int ppod_addr;
+
+ KASSERT(ps->nppods == 0, ("%s: page pods already allocated", __func__));
/*
* The DDP page size is unrelated to the VM page size. We combine
@@ -662,10 +882,11 @@ alloc_ddp_buffer(struct tom_data *td, vm_page_t *pages, int npages, int offset,
* the page list.
*/
hcf = 0;
- for (i = 0; i < npages; i++) {
+ for (i = 0; i < ps->npages; i++) {
seglen = PAGE_SIZE;
- while (i < npages - 1 &&
- pages[i]->phys_addr + PAGE_SIZE == pages[i + 1]->phys_addr) {
+ while (i < ps->npages - 1 &&
+ ps->pages[i]->phys_addr + PAGE_SIZE ==
+ ps->pages[i + 1]->phys_addr) {
seglen += PAGE_SIZE;
i++;
}
@@ -683,7 +904,7 @@ alloc_ddp_buffer(struct tom_data *td, vm_page_t *pages, int npages, int offset,
("%s: PAGE_SIZE %d, hcf %d", __func__, PAGE_SIZE, hcf));
CTR3(KTR_CXGBE, "%s: PAGE_SIZE %d, hcf %d",
__func__, PAGE_SIZE, hcf);
- return (NULL);
+ return (0);
}
for (idx = nitems(t4_ddp_pgsz) - 1; idx > 0; idx--) {
@@ -693,40 +914,29 @@ alloc_ddp_buffer(struct tom_data *td, vm_page_t *pages, int npages, int offset,
have_pgsz:
MPASS(idx <= M_PPOD_PGSZ);
- db = malloc(sizeof(*db), M_CXGBE, M_NOWAIT);
- if (db == NULL) {
- CTR1(KTR_CXGBE, "%s: malloc failed.", __func__);
- return (NULL);
- }
-
- nppods = pages_to_nppods(npages, t4_ddp_pgsz[idx]);
- if (alloc_ppods(td, nppods, &db->ppod_addr) != 0) {
- free(db, M_CXGBE);
- CTR4(KTR_CXGBE, "%s: no pods, nppods %d, resid %d, pgsz %d",
- __func__, nppods, len, t4_ddp_pgsz[idx]);
- return (NULL);
+ nppods = pages_to_nppods(ps->npages, t4_ddp_pgsz[idx]);
+ if (alloc_ppods(td, nppods, &ppod_addr) != 0) {
+ CTR4(KTR_CXGBE, "%s: no pods, nppods %d, npages %d, pgsz %d",
+ __func__, nppods, ps->npages, t4_ddp_pgsz[idx]);
+ return (0);
}
- ppod = (db->ppod_addr - td->ppod_start) / PPOD_SIZE;
- db->tag = V_PPOD_PGSZ(idx) | V_PPOD_TAG(ppod);
- db->nppods = nppods;
- db->npages = npages;
- db->pages = pages;
- db->offset = offset;
- db->len = len;
+ ppod = (ppod_addr - td->ppod_start) / PPOD_SIZE;
+ ps->tag = V_PPOD_PGSZ(idx) | V_PPOD_TAG(ppod);
+ ps->ppod_addr = ppod_addr;
+ ps->nppods = nppods;
- CTR6(KTR_CXGBE, "New DDP buffer. "
- "ddp_pgsz %d, ppod 0x%x, npages %d, nppods %d, offset %d, len %d",
- t4_ddp_pgsz[idx], ppod, db->npages, db->nppods, db->offset,
- db->len);
+ CTR5(KTR_CXGBE, "New page pods. "
+ "ps %p, ddp_pgsz %d, ppod 0x%x, npages %d, nppods %d",
+ ps, t4_ddp_pgsz[idx], ppod, ps->npages, ps->nppods);
- return (db);
+ return (1);
}
#define NUM_ULP_TX_SC_IMM_PPODS (256 / PPOD_SIZE)
static int
-write_page_pods(struct adapter *sc, struct toepcb *toep, struct ddp_buffer *db)
+write_page_pods(struct adapter *sc, struct toepcb *toep, struct pageset *ps)
{
struct wrqe *wr;
struct ulp_mem_io *ulpmc;
@@ -736,17 +946,20 @@ write_page_pods(struct adapter *sc, struct toepcb *toep, struct ddp_buffer *db)
u_int ppod_addr;
uint32_t cmd;
+ KASSERT(!(ps->flags & PS_PPODS_WRITTEN),
+ ("%s: page pods already written", __func__));
+
cmd = htobe32(V_ULPTX_CMD(ULP_TX_MEM_WRITE));
if (is_t4(sc))
cmd |= htobe32(F_ULP_MEMIO_ORDER);
else
cmd |= htobe32(F_T5_ULP_MEMIO_IMM);
- ddp_pgsz = t4_ddp_pgsz[G_PPOD_PGSZ(db->tag)];
- ppod_addr = db->ppod_addr;
- for (i = 0; i < db->nppods; ppod_addr += chunk) {
+ ddp_pgsz = t4_ddp_pgsz[G_PPOD_PGSZ(ps->tag)];
+ ppod_addr = ps->ppod_addr;
+ for (i = 0; i < ps->nppods; ppod_addr += chunk) {
/* How many page pods are we writing in this cycle */
- n = min(db->nppods - i, NUM_ULP_TX_SC_IMM_PPODS);
+ n = min(ps->nppods - i, NUM_ULP_TX_SC_IMM_PPODS);
chunk = PPOD_SZ(n);
len = roundup2(sizeof(*ulpmc) + sizeof(*ulpsc) + chunk, 16);
@@ -768,15 +981,15 @@ write_page_pods(struct adapter *sc, struct toepcb *toep, struct ddp_buffer *db)
ppod = (struct pagepod *)(ulpsc + 1);
for (j = 0; j < n; i++, j++, ppod++) {
ppod->vld_tid_pgsz_tag_color = htobe64(F_PPOD_VALID |
- V_PPOD_TID(toep->tid) | db->tag);
- ppod->len_offset = htobe64(V_PPOD_LEN(db->len) |
- V_PPOD_OFST(db->offset));
+ V_PPOD_TID(toep->tid) | ps->tag);
+ ppod->len_offset = htobe64(V_PPOD_LEN(ps->len) |
+ V_PPOD_OFST(ps->offset));
ppod->rsvd = 0;
idx = i * PPOD_PAGES * (ddp_pgsz / PAGE_SIZE);
for (k = 0; k < nitems(ppod->addr); k++) {
- if (idx < db->npages) {
+ if (idx < ps->npages) {
ppod->addr[k] =
- htobe64(db->pages[idx]->phys_addr);
+ htobe64(ps->pages[idx]->phys_addr);
idx += ddp_pgsz / PAGE_SIZE;
} else
ppod->addr[k] = 0;
@@ -792,184 +1005,49 @@ write_page_pods(struct adapter *sc, struct toepcb *toep, struct ddp_buffer *db)
t4_wrq_tx(sc, wr);
}
+ ps->flags |= PS_PPODS_WRITTEN;
return (0);
}
-/*
- * Reuse, or allocate (and program the page pods for) a new DDP buffer. The
- * "pages" array is handed over to this function and should not be used in any
- * way by the caller after that.
- */
-static int
-select_ddp_buffer(struct adapter *sc, struct toepcb *toep, vm_page_t *pages,
- int npages, int db_off, int db_len)
-{
- struct ddp_buffer *db;
- struct tom_data *td = sc->tom_softc;
- int i, empty_slot = -1;
-
- /* Try to reuse */
- for (i = 0; i < nitems(toep->db); i++) {
- if (bufcmp(toep->db[i], pages, npages, db_off, db_len) == 0) {
- free(pages, M_CXGBE);
- return (i); /* pages still held */
- } else if (toep->db[i] == NULL && empty_slot < 0)
- empty_slot = i;
- }
-
- /* Allocate new buffer, write its page pods. */
- db = alloc_ddp_buffer(td, pages, npages, db_off, db_len);
- if (db == NULL) {
- vm_page_unhold_pages(pages, npages);
- free(pages, M_CXGBE);
- return (-1);
- }
- if (write_page_pods(sc, toep, db) != 0) {
- vm_page_unhold_pages(pages, npages);
- free_ddp_buffer(td, db);
- return (-1);
- }
-
- i = empty_slot;
- if (i < 0) {
- i = arc4random() % nitems(toep->db);
- free_ddp_buffer(td, toep->db[i]);
- }
- toep->db[i] = db;
-
- CTR5(KTR_CXGBE, "%s: tid %d, DDP buffer[%d] = %p (tag 0x%x)",
- __func__, toep->tid, i, db, db->tag);
-
- return (i);
-}
-
static void
-wire_ddp_buffer(struct ddp_buffer *db)
+wire_pageset(struct pageset *ps)
{
- int i;
vm_page_t p;
+ int i;
+
+ KASSERT(!(ps->flags & PS_WIRED), ("pageset already wired"));
- for (i = 0; i < db->npages; i++) {
- p = db->pages[i];
+ for (i = 0; i < ps->npages; i++) {
+ p = ps->pages[i];
vm_page_lock(p);
vm_page_wire(p);
vm_page_unhold(p);
vm_page_unlock(p);
}
+ ps->flags |= PS_WIRED;
}
-static void
-unwire_ddp_buffer(struct ddp_buffer *db)
-{
- int i;
- vm_page_t p;
-
- for (i = 0; i < db->npages; i++) {
- p = db->pages[i];
- vm_page_lock(p);
- vm_page_unwire(p, PQ_INACTIVE);
- vm_page_unlock(p);
- }
-}
-
+/*
+ * Prepare a pageset for DDP. This wires the pageset and sets up page
+ * pods.
+ */
static int
-handle_ddp(struct socket *so, struct uio *uio, int flags, int error)
+prep_pageset(struct adapter *sc, struct toepcb *toep, struct pageset *ps)
{
- struct sockbuf *sb = &so->so_rcv;
- struct tcpcb *tp = so_sototcpcb(so);
- struct toepcb *toep = tp->t_toe;
- struct adapter *sc = td_adapter(toep->td);
- vm_page_t *pages;
- int npages, db_idx, rc, buf_flag;
- struct ddp_buffer *db;
- struct wrqe *wr;
- uint64_t ddp_flags;
-
- SOCKBUF_LOCK_ASSERT(sb);
-
-#if 0
- if (sbused(sb) + sc->tt.ddp_thres > uio->uio_resid) {
- CTR4(KTR_CXGBE, "%s: sb_cc %d, threshold %d, resid %d",
- __func__, sbused(sb), sc->tt.ddp_thres, uio->uio_resid);
- }
-#endif
-
- /* XXX: too eager to disable DDP, could handle NBIO better than this. */
- if (sbused(sb) >= uio->uio_resid || uio->uio_resid < sc->tt.ddp_thres ||
- uio->uio_resid > MAX_DDP_BUFFER_SIZE || uio->uio_iovcnt > 1 ||
- so->so_state & SS_NBIO || flags & (MSG_DONTWAIT | MSG_NBIO) ||
- error || so->so_error || sb->sb_state & SBS_CANTRCVMORE)
- goto no_ddp;
+ struct tom_data *td = sc->tom_softc;
- /*
- * Fault in and then hold the pages of the uio buffers. We'll wire them
- * a bit later if everything else works out.
- */
- SOCKBUF_UNLOCK(sb);
- if (hold_uio(uio, &pages, &npages) != 0) {
- SOCKBUF_LOCK(sb);
- goto no_ddp;
- }
- SOCKBUF_LOCK(sb);
- if (__predict_false(so->so_error || sb->sb_state & SBS_CANTRCVMORE)) {
- vm_page_unhold_pages(pages, npages);
- free(pages, M_CXGBE);
- goto no_ddp;
+ if (!(ps->flags & PS_WIRED))
+ wire_pageset(ps);
+ if (ps->nppods == 0 && !alloc_page_pods(td, ps)) {
+ return (0);
}
-
- /*
- * Figure out which one of the two DDP buffers to use this time.
- */
- db_idx = select_ddp_buffer(sc, toep, pages, npages,
- (uintptr_t)uio->uio_iov->iov_base & PAGE_MASK, uio->uio_resid);
- pages = NULL; /* handed off to select_ddp_buffer */
- if (db_idx < 0)
- goto no_ddp;
- db = toep->db[db_idx];
- buf_flag = db_idx == 0 ? DDP_BUF0_ACTIVE : DDP_BUF1_ACTIVE;
-
- /*
- * Build the compound work request that tells the chip where to DMA the
- * payload.
- */
- ddp_flags = select_ddp_flags(so, flags, db_idx);
- wr = mk_update_tcb_for_ddp(sc, toep, db_idx, sbused(sb), ddp_flags);
- if (wr == NULL) {
- /*
- * Just unhold the pages. The DDP buffer's software state is
- * left as-is in the toep. The page pods were written
- * successfully and we may have an opportunity to use it in the
- * future.
- */
- vm_page_unhold_pages(db->pages, db->npages);
- goto no_ddp;
+ if (!(ps->flags & PS_PPODS_WRITTEN) &&
+ write_page_pods(sc, toep, ps) != 0) {
+ return (0);
}
- /* Wire (and then unhold) the pages, and give the chip the go-ahead. */
- wire_ddp_buffer(db);
- t4_wrq_tx(sc, wr);
- sb->sb_flags &= ~SB_DDP_INDICATE;
- toep->ddp_flags |= buf_flag;
-
- /*
- * Wait for the DDP operation to complete and then unwire the pages.
- * The return code from the sbwait will be the final return code of this
- * function. But we do need to wait for DDP no matter what.
- */
- rc = sbwait(sb);
- while (toep->ddp_flags & buf_flag) {
- /* XXXGL: shouldn't here be sbwait() call? */
- sb->sb_flags |= SB_WAIT;
- msleep(&sb->sb_acc, &sb->sb_mtx, PSOCK , "sbwait", 0);
- }
- unwire_ddp_buffer(db);
- return (rc);
-no_ddp:
- disable_ddp(sc, toep);
- discourage_ddp(toep);
- sb->sb_flags &= ~SB_DDP_INDICATE;
- return (0);
+ return (1);
}
void
@@ -994,287 +1072,689 @@ t4_uninit_ddp(struct adapter *sc __unused, struct tom_data *td)
}
}
-#define VNET_SO_ASSERT(so) \
- VNET_ASSERT(curvnet != NULL, \
- ("%s:%d curvnet is NULL, so=%p", __func__, __LINE__, (so)));
-#define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? 0 : SBL_WAIT)
static int
-soreceive_rcvoob(struct socket *so, struct uio *uio, int flags)
+pscmp(struct pageset *ps, struct vmspace *vm, vm_offset_t start, int npages,
+ int pgoff, int len)
{
- CXGBE_UNIMPLEMENTED(__func__);
-}
+ if (ps->npages != npages || ps->offset != pgoff || ps->len != len)
+ return (1);
-static char ddp_magic_str[] = "nothing to see here";
+ return (ps->vm != vm || ps->vm_timestamp != vm->vm_map.timestamp);
+}
-static struct mbuf *
-get_ddp_mbuf(int len)
+static int
+hold_aio(struct toepcb *toep, struct kaiocb *job, struct pageset **pps)
{
- struct mbuf *m;
-
- m = m_get(M_NOWAIT, MT_DATA);
- if (m == NULL)
- CXGBE_UNIMPLEMENTED("mbuf alloc failure");
- m->m_len = len;
- m->m_data = &ddp_magic_str[0];
+ struct vmspace *vm;
+ vm_map_t map;
+ vm_offset_t start, end, pgoff;
+ struct pageset *ps;
+ int n;
- return (m);
-}
+ DDP_ASSERT_LOCKED(toep);
-static inline int
-is_ddp_mbuf(struct mbuf *m)
-{
+ /*
+ * The AIO subsystem will cancel and drain all requests before
+ * permitting a process to exit or exec, so p_vmspace should
+ * be stable here.
+ */
+ vm = job->userproc->p_vmspace;
+ map = &vm->vm_map;
+ start = (uintptr_t)job->uaiocb.aio_buf;
+ pgoff = start & PAGE_MASK;
+ end = round_page(start + job->uaiocb.aio_nbytes);
+ start = trunc_page(start);
+
+ if (end - start > MAX_DDP_BUFFER_SIZE) {
+ /*
+ * Truncate the request to a short read.
+ * Alternatively, we could DDP in chunks to the larger
+ * buffer, but that would be quite a bit more work.
+ *
+ * When truncating, round the request down to avoid
+ * crossing a cache line on the final transaction.
+ */
+ end = rounddown2(start + MAX_DDP_BUFFER_SIZE, CACHE_LINE_SIZE);
+#ifdef VERBOSE_TRACES
+ CTR4(KTR_CXGBE, "%s: tid %d, truncating size from %lu to %lu",
+ __func__, toep->tid, (unsigned long)job->uaiocb.aio_nbytes,
+ (unsigned long)(end - (start + pgoff)));
+ job->uaiocb.aio_nbytes = end - (start + pgoff);
+#endif
+ end = round_page(end);
+ }
- return (m->m_data == &ddp_magic_str[0]);
-}
+ n = atop(end - start);
-/*
- * Copy an mbuf chain into a uio limited by len if set.
- */
-static int
-m_mbuftouio_ddp(struct uio *uio, struct mbuf *m, int len)
-{
- int error, length, total;
- int progress = 0;
+ /*
+ * Try to reuse a cached pageset.
+ */
+ TAILQ_FOREACH(ps, &toep->ddp_cached_pagesets, link) {
+ if (pscmp(ps, vm, start, n, pgoff,
+ job->uaiocb.aio_nbytes) == 0) {
+ TAILQ_REMOVE(&toep->ddp_cached_pagesets, ps, link);
+ toep->ddp_cached_count--;
+ *pps = ps;
+ return (0);
+ }
+ }
- if (len > 0)
- total = min(uio->uio_resid, len);
- else
- total = uio->uio_resid;
+ /*
+ * If there are too many cached pagesets to create a new one,
+ * free a pageset before creating a new one.
+ */
+ KASSERT(toep->ddp_active_count + toep->ddp_cached_count <=
+ nitems(toep->db), ("%s: too many wired pagesets", __func__));
+ if (toep->ddp_active_count + toep->ddp_cached_count ==
+ nitems(toep->db)) {
+ KASSERT(toep->ddp_cached_count > 0,
+ ("no cached pageset to free"));
+ ps = TAILQ_LAST(&toep->ddp_cached_pagesets, pagesetq);
+ TAILQ_REMOVE(&toep->ddp_cached_pagesets, ps, link);
+ toep->ddp_cached_count--;
+ free_pageset(toep->td, ps);
+ }
+ DDP_UNLOCK(toep);
+
+ /* Create a new pageset. */
+ ps = malloc(sizeof(*ps) + n * sizeof(vm_page_t), M_CXGBE, M_WAITOK |
+ M_ZERO);
+ ps->pages = (vm_page_t *)(ps + 1);
+ ps->vm_timestamp = map->timestamp;
+ ps->npages = vm_fault_quick_hold_pages(map, start, end - start,
+ VM_PROT_WRITE, ps->pages, n);
+
+ DDP_LOCK(toep);
+ if (ps->npages < 0) {
+ free(ps, M_CXGBE);
+ return (EFAULT);
+ }
- /* Fill the uio with data from the mbufs. */
- for (; m != NULL; m = m->m_next) {
- length = min(m->m_len, total - progress);
+ KASSERT(ps->npages == n, ("hold_aio: page count mismatch: %d vs %d",
+ ps->npages, n));
- if (is_ddp_mbuf(m)) {
- enum uio_seg segflag = uio->uio_segflg;
+ ps->offset = pgoff;
+ ps->len = job->uaiocb.aio_nbytes;
+ atomic_add_int(&vm->vm_refcnt, 1);
+ ps->vm = vm;
- uio->uio_segflg = UIO_NOCOPY;
- error = uiomove(mtod(m, void *), length, uio);
- uio->uio_segflg = segflag;
- } else
- error = uiomove(mtod(m, void *), length, uio);
- if (error)
- return (error);
+ CTR5(KTR_CXGBE, "%s: tid %d, new pageset %p for job %p, npages %d",
+ __func__, toep->tid, ps, job, ps->npages);
+ *pps = ps;
+ return (0);
+}
- progress += length;
+static void
+ddp_complete_all(struct toepcb *toep, int error)
+{
+ struct kaiocb *job;
+
+ DDP_ASSERT_LOCKED(toep);
+ while (!TAILQ_EMPTY(&toep->ddp_aiojobq)) {
+ job = TAILQ_FIRST(&toep->ddp_aiojobq);
+ TAILQ_REMOVE(&toep->ddp_aiojobq, job, list);
+ toep->ddp_waiting_count--;
+ if (aio_clear_cancel_function(job))
+ ddp_complete_one(job, error);
}
+}
- return (0);
+static void
+aio_ddp_cancel_one(struct kaiocb *job)
+{
+ long copied;
+
+ /*
+ * If this job had copied data out of the socket buffer before
+ * it was cancelled, report it as a short read rather than an
+ * error.
+ */
+ copied = job->uaiocb._aiocb_private.status;
+ if (copied != 0)
+ aio_complete(job, copied, 0);
+ else
+ aio_cancel(job);
}
/*
- * Based on soreceive_stream() in uipc_socket.c
+ * Called when the main loop wants to requeue a job to retry it later.
+ * Deals with the race of the job being cancelled while it was being
+ * examined.
*/
-int
-t4_soreceive_ddp(struct socket *so, struct sockaddr **psa, struct uio *uio,
- struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
+static void
+aio_ddp_requeue_one(struct toepcb *toep, struct kaiocb *job)
+{
+
+ DDP_ASSERT_LOCKED(toep);
+ if (!(toep->ddp_flags & DDP_DEAD) &&
+ aio_set_cancel_function(job, t4_aio_cancel_queued)) {
+ TAILQ_INSERT_HEAD(&toep->ddp_aiojobq, job, list);
+ toep->ddp_waiting_count++;
+ } else
+ aio_ddp_cancel_one(job);
+}
+
+static void
+aio_ddp_requeue(struct toepcb *toep)
{
- int len = 0, error = 0, flags, oresid, ddp_handled = 0;
+ struct adapter *sc = td_adapter(toep->td);
+ struct socket *so;
struct sockbuf *sb;
- struct mbuf *m, *n = NULL;
-
- /* We only do stream sockets. */
- if (so->so_type != SOCK_STREAM)
- return (EINVAL);
- if (psa != NULL)
- *psa = NULL;
- if (controlp != NULL)
- return (EINVAL);
- if (flagsp != NULL)
- flags = *flagsp &~ MSG_EOR;
- else
- flags = 0;
- if (flags & MSG_OOB)
- return (soreceive_rcvoob(so, uio, flags));
- if (mp0 != NULL)
- *mp0 = NULL;
+ struct inpcb *inp;
+ struct kaiocb *job;
+ struct ddp_buffer *db;
+ size_t copied, offset, resid;
+ struct pageset *ps;
+ struct mbuf *m;
+ uint64_t ddp_flags, ddp_flags_mask;
+ struct wrqe *wr;
+ int buf_flag, db_idx, error;
- sb = &so->so_rcv;
+ DDP_ASSERT_LOCKED(toep);
- /* Prevent other readers from entering the socket. */
- error = sblock(sb, SBLOCKWAIT(flags));
- SOCKBUF_LOCK(sb);
- if (error)
- goto out;
+restart:
+ if (toep->ddp_flags & DDP_DEAD) {
+ MPASS(toep->ddp_waiting_count == 0);
+ MPASS(toep->ddp_active_count == 0);
+ return;
+ }
- /* Easy one, no space to copyout anything. */
- if (uio->uio_resid == 0) {
- error = EINVAL;
- goto out;
+ if (toep->ddp_waiting_count == 0 ||
+ toep->ddp_active_count == nitems(toep->db)) {
+ return;
}
- oresid = uio->uio_resid;
- /* We will never ever get anything unless we are or were connected. */
+ job = TAILQ_FIRST(&toep->ddp_aiojobq);
+ so = job->fd_file->f_data;
+ sb = &so->so_rcv;
+ SOCKBUF_LOCK(sb);
+
+ /* We will never get anything unless we are or were connected. */
if (!(so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED))) {
- error = ENOTCONN;
- goto out;
+ SOCKBUF_UNLOCK(sb);
+ ddp_complete_all(toep, ENOTCONN);
+ return;
}
-restart:
- SOCKBUF_LOCK_ASSERT(&so->so_rcv);
+ KASSERT(toep->ddp_active_count == 0 || sbavail(sb) == 0,
+ ("%s: pending sockbuf data and DDP is active", __func__));
- if (sb->sb_flags & SB_DDP_INDICATE && !ddp_handled) {
+ /* Abort if socket has reported problems. */
+ /* XXX: Wait for any queued DDP's to finish and/or flush them? */
+ if (so->so_error && sbavail(sb) == 0) {
+ toep->ddp_waiting_count--;
+ TAILQ_REMOVE(&toep->ddp_aiojobq, job, list);
+ if (!aio_clear_cancel_function(job)) {
+ SOCKBUF_UNLOCK(sb);
+ goto restart;
+ }
- /* uio should be just as it was at entry */
- KASSERT(oresid == uio->uio_resid,
- ("%s: oresid = %d, uio_resid = %zd, sbavail = %d",
- __func__, oresid, uio->uio_resid, sbavail(sb)));
+ /*
+ * If this job has previously copied some data, report
+ * a short read and leave the error to be reported by
+ * a future request.
+ */
+ copied = job->uaiocb._aiocb_private.status;
+ if (copied != 0) {
+ SOCKBUF_UNLOCK(sb);
+ aio_complete(job, copied, 0);
+ goto restart;
+ }
+ error = so->so_error;
+ so->so_error = 0;
+ SOCKBUF_UNLOCK(sb);
+ aio_complete(job, -1, error);
+ goto restart;
+ }
- error = handle_ddp(so, uio, flags, 0);
- ddp_handled = 1;
- if (error)
- goto out;
+ /*
+ * Door is closed. If there is pending data in the socket buffer,
+ * deliver it. If there are pending DDP requests, wait for those
+ * to complete. Once they have completed, return EOF reads.
+ */
+ if (sb->sb_state & SBS_CANTRCVMORE && sbavail(sb) == 0) {
+ SOCKBUF_UNLOCK(sb);
+ if (toep->ddp_active_count != 0)
+ return;
+ ddp_complete_all(toep, 0);
+ return;
}
- /* Abort if socket has reported problems. */
- if (so->so_error) {
- if (sbavail(sb))
- goto deliver;
- if (oresid > uio->uio_resid)
- goto out;
- error = so->so_error;
- if (!(flags & MSG_PEEK))
- so->so_error = 0;
- goto out;
+ /*
+ * If DDP is not enabled and there is no pending socket buffer
+ * data, try to enable DDP.
+ */
+ if (sbavail(sb) == 0 && (toep->ddp_flags & DDP_ON) == 0) {
+ SOCKBUF_UNLOCK(sb);
+
+ /*
+ * Wait for the card to ACK that DDP is enabled before
+ * queueing any buffers. Currently this waits for an
+ * indicate to arrive. This could use a TCB_SET_FIELD_RPL
+ * message to know that DDP was enabled instead of waiting
+ * for the indicate which would avoid copying the indicate
+ * if no data is pending.
+ *
+ * XXX: Might want to limit the indicate size to the size
+ * of the first queued request.
+ */
+ if ((toep->ddp_flags & DDP_SC_REQ) == 0)
+ enable_ddp(sc, toep);
+ return;
}
+ SOCKBUF_UNLOCK(sb);
- /* Door is closed. Deliver what is left, if any. */
- if (sb->sb_state & SBS_CANTRCVMORE) {
- if (sbavail(sb))
- goto deliver;
- else
- goto out;
+ /*
+ * If another thread is queueing a buffer for DDP, let it
+ * drain any work and return.
+ */
+ if (toep->ddp_queueing != NULL)
+ return;
+
+ /* Take the next job to prep it for DDP. */
+ toep->ddp_waiting_count--;
+ TAILQ_REMOVE(&toep->ddp_aiojobq, job, list);
+ if (!aio_clear_cancel_function(job))
+ goto restart;
+ toep->ddp_queueing = job;
+
+ /* NB: This drops DDP_LOCK while it holds the backing VM pages. */
+ error = hold_aio(toep, job, &ps);
+ if (error != 0) {
+ ddp_complete_one(job, error);
+ toep->ddp_queueing = NULL;
+ goto restart;
}
- /* Socket buffer is empty and we shall not block. */
- if (sbavail(sb) == 0 &&
- ((so->so_state & SS_NBIO) || (flags & (MSG_DONTWAIT|MSG_NBIO)))) {
- error = EAGAIN;
- goto out;
+ SOCKBUF_LOCK(sb);
+ if (so->so_error && sbavail(sb) == 0) {
+ copied = job->uaiocb._aiocb_private.status;
+ if (copied != 0) {
+ SOCKBUF_UNLOCK(sb);
+ recycle_pageset(toep, ps);
+ aio_complete(job, copied, 0);
+ toep->ddp_queueing = NULL;
+ goto restart;
+ }
+
+ error = so->so_error;
+ so->so_error = 0;
+ SOCKBUF_UNLOCK(sb);
+ recycle_pageset(toep, ps);
+ aio_complete(job, -1, error);
+ toep->ddp_queueing = NULL;
+ goto restart;
}
- /* Socket buffer got some data that we shall deliver now. */
- if (sbavail(sb) > 0 && !(flags & MSG_WAITALL) &&
- ((so->so_state & SS_NBIO) ||
- (flags & (MSG_DONTWAIT|MSG_NBIO)) ||
- sbavail(sb) >= sb->sb_lowat ||
- sbavail(sb) >= uio->uio_resid ||
- sbavail(sb) >= sb->sb_hiwat) ) {
- goto deliver;
+ if (sb->sb_state & SBS_CANTRCVMORE && sbavail(sb) == 0) {
+ SOCKBUF_UNLOCK(sb);
+ recycle_pageset(toep, ps);
+ if (toep->ddp_active_count != 0) {
+ /*
+ * The door is closed, but there are still pending
+ * DDP buffers. Requeue. These jobs will all be
+ * completed once those buffers drain.
+ */
+ aio_ddp_requeue_one(toep, job);
+ toep->ddp_queueing = NULL;
+ return;
+ }
+ ddp_complete_one(job, 0);
+ ddp_complete_all(toep, 0);
+ toep->ddp_queueing = NULL;
+ return;
}
- /* On MSG_WAITALL we must wait until all data or error arrives. */
- if ((flags & MSG_WAITALL) &&
- (sbavail(sb) >= uio->uio_resid || sbavail(sb) >= sb->sb_lowat))
- goto deliver;
+sbcopy:
+ /*
+ * If the toep is dead, there shouldn't be any data in the socket
+ * buffer, so the above case should have handled this.
+ */
+ MPASS(!(toep->ddp_flags & DDP_DEAD));
/*
- * Wait and block until (more) data comes in.
- * NB: Drops the sockbuf lock during wait.
+ * If there is pending data in the socket buffer (either
+ * from before the requests were queued or a DDP indicate),
+ * copy those mbufs out directly.
*/
- error = sbwait(sb);
- if (error) {
- if (sb->sb_flags & SB_DDP_INDICATE && !ddp_handled) {
- (void) handle_ddp(so, uio, flags, 1);
- ddp_handled = 1;
+ copied = 0;
+ offset = ps->offset + job->uaiocb._aiocb_private.status;
+ MPASS(job->uaiocb._aiocb_private.status <= job->uaiocb.aio_nbytes);
+ resid = job->uaiocb.aio_nbytes - job->uaiocb._aiocb_private.status;
+ m = sb->sb_mb;
+ KASSERT(m == NULL || toep->ddp_active_count == 0,
+ ("%s: sockbuf data with active DDP", __func__));
+ while (m != NULL && resid > 0) {
+ struct iovec iov[1];
+ struct uio uio;
+ int error;
+
+ iov[0].iov_base = mtod(m, void *);
+ iov[0].iov_len = m->m_len;
+ if (iov[0].iov_len > resid)
+ iov[0].iov_len = resid;
+ uio.uio_iov = iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = 0;
+ uio.uio_resid = iov[0].iov_len;
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_rw = UIO_WRITE;
+ error = uiomove_fromphys(ps->pages, offset + copied,
+ uio.uio_resid, &uio);
+ MPASS(error == 0 && uio.uio_resid == 0);
+ copied += uio.uio_offset;
+ resid -= uio.uio_offset;
+ m = m->m_next;
+ }
+ if (copied != 0) {
+ sbdrop_locked(sb, copied);
+ job->uaiocb._aiocb_private.status += copied;
+ copied = job->uaiocb._aiocb_private.status;
+ inp = sotoinpcb(so);
+ if (!INP_TRY_WLOCK(inp)) {
+ /*
+ * The reference on the socket file descriptor in
+ * the AIO job should keep 'sb' and 'inp' stable.
+ * Our caller has a reference on the 'toep' that
+ * keeps it stable.
+ */
+ SOCKBUF_UNLOCK(sb);
+ DDP_UNLOCK(toep);
+ INP_WLOCK(inp);
+ DDP_LOCK(toep);
+ SOCKBUF_LOCK(sb);
+
+ /*
+ * If the socket has been closed, we should detect
+ * that and complete this request if needed on
+ * the next trip around the loop.
+ */
}
- goto out;
+ t4_rcvd_locked(&toep->td->tod, intotcpcb(inp));
+ INP_WUNLOCK(inp);
+ if (resid == 0 || toep->ddp_flags & DDP_DEAD) {
+ /*
+ * We filled the entire buffer with socket
+ * data, DDP is not being used, or the socket
+ * is being shut down, so complete the
+ * request.
+ */
+ SOCKBUF_UNLOCK(sb);
+ recycle_pageset(toep, ps);
+ aio_complete(job, copied, 0);
+ toep->ddp_queueing = NULL;
+ goto restart;
+ }
+
+ /*
+ * If DDP is not enabled, requeue this request and restart.
+ * This will either enable DDP or wait for more data to
+ * arrive on the socket buffer.
+ */
+ if ((toep->ddp_flags & (DDP_ON | DDP_SC_REQ)) != DDP_ON) {
+ SOCKBUF_UNLOCK(sb);
+ recycle_pageset(toep, ps);
+ aio_ddp_requeue_one(toep, job);
+ toep->ddp_queueing = NULL;
+ goto restart;
+ }
+
+ /*
+ * An indicate might have arrived and been added to
+ * the socket buffer while it was unlocked after the
+ * copy to lock the INP. If so, restart the copy.
+ */
+ if (sbavail(sb) != 0)
+ goto sbcopy;
}
- goto restart;
+ SOCKBUF_UNLOCK(sb);
-deliver:
- SOCKBUF_LOCK_ASSERT(&so->so_rcv);
- KASSERT(sbavail(sb) > 0, ("%s: sockbuf empty", __func__));
- KASSERT(sb->sb_mb != NULL, ("%s: sb_mb == NULL", __func__));
+ if (prep_pageset(sc, toep, ps) == 0) {
+ recycle_pageset(toep, ps);
+ aio_ddp_requeue_one(toep, job);
+ toep->ddp_queueing = NULL;
- if (sb->sb_flags & SB_DDP_INDICATE && !ddp_handled)
- goto restart;
+ /*
+ * XXX: Need to retry this later. Mostly need a trigger
+ * when page pods are freed up.
+ */
+ printf("%s: prep_pageset failed\n", __func__);
+ return;
+ }
- /* Statistics. */
- if (uio->uio_td)
- uio->uio_td->td_ru.ru_msgrcv++;
-
- /* Fill uio until full or current end of socket buffer is reached. */
- len = min(uio->uio_resid, sbavail(sb));
- if (mp0 != NULL) {
- /* Dequeue as many mbufs as possible. */
- if (!(flags & MSG_PEEK) && len >= sb->sb_mb->m_len) {
- for (*mp0 = m = sb->sb_mb;
- m != NULL && m->m_len <= len;
- m = m->m_next) {
- len -= m->m_len;
- uio->uio_resid -= m->m_len;
- sbfree(sb, m);
- n = m;
- }
- sb->sb_mb = m;
- if (sb->sb_mb == NULL)
- SB_EMPTY_FIXUP(sb);
- n->m_next = NULL;
- }
- /* Copy the remainder. */
- if (len > 0) {
- KASSERT(sb->sb_mb != NULL,
- ("%s: len > 0 && sb->sb_mb empty", __func__));
-
- m = m_copym(sb->sb_mb, 0, len, M_NOWAIT);
- if (m == NULL)
- len = 0; /* Don't flush data from sockbuf. */
- else
- uio->uio_resid -= m->m_len;
- if (*mp0 != NULL)
- n->m_next = m;
- else
- *mp0 = m;
- if (*mp0 == NULL) {
- error = ENOBUFS;
- goto out;
- }
- }
+ /* Determine which DDP buffer to use. */
+ if (toep->db[0].job == NULL) {
+ db_idx = 0;
} else {
- /* NB: Must unlock socket buffer as uiomove may sleep. */
- SOCKBUF_UNLOCK(sb);
- error = m_mbuftouio_ddp(uio, sb->sb_mb, len);
- SOCKBUF_LOCK(sb);
- if (error)
- goto out;
+ MPASS(toep->db[1].job == NULL);
+ db_idx = 1;
+ }
+
+ ddp_flags = 0;
+ ddp_flags_mask = 0;
+ if (db_idx == 0) {
+ ddp_flags |= V_TF_DDP_BUF0_VALID(1);
+ if (so->so_state & SS_NBIO)
+ ddp_flags |= V_TF_DDP_BUF0_FLUSH(1);
+ ddp_flags_mask |= V_TF_DDP_PSH_NO_INVALIDATE0(1) |
+ V_TF_DDP_PUSH_DISABLE_0(1) | V_TF_DDP_PSHF_ENABLE_0(1) |
+ V_TF_DDP_BUF0_FLUSH(1) | V_TF_DDP_BUF0_VALID(1);
+ buf_flag = DDP_BUF0_ACTIVE;
+ } else {
+ ddp_flags |= V_TF_DDP_BUF1_VALID(1);
+ if (so->so_state & SS_NBIO)
+ ddp_flags |= V_TF_DDP_BUF1_FLUSH(1);
+ ddp_flags_mask |= V_TF_DDP_PSH_NO_INVALIDATE1(1) |
+ V_TF_DDP_PUSH_DISABLE_1(1) | V_TF_DDP_PSHF_ENABLE_1(1) |
+ V_TF_DDP_BUF1_FLUSH(1) | V_TF_DDP_BUF1_VALID(1);
+ buf_flag = DDP_BUF1_ACTIVE;
+ }
+ MPASS((toep->ddp_flags & buf_flag) == 0);
+ if ((toep->ddp_flags & (DDP_BUF0_ACTIVE | DDP_BUF1_ACTIVE)) == 0) {
+ MPASS(db_idx == 0);
+ MPASS(toep->ddp_active_id == -1);
+ MPASS(toep->ddp_active_count == 0);
+ ddp_flags_mask |= V_TF_DDP_ACTIVE_BUF(1);
}
- SBLASTRECORDCHK(sb);
- SBLASTMBUFCHK(sb);
/*
- * Remove the delivered data from the socket buffer unless we
- * were only peeking.
+ * The TID for this connection should still be valid. If DDP_DEAD
+ * is set, SBS_CANTRCVMORE should be set, so we shouldn't be
+ * this far anyway. Even if the socket is closing on the other
+ * end, the AIO job holds a reference on this end of the socket
+ * which will keep it open and keep the TCP PCB attached until
+ * after the job is completed.
*/
- if (!(flags & MSG_PEEK)) {
- if (len > 0)
- sbdrop_locked(sb, len);
-
- /* Notify protocol that we drained some data. */
- if ((so->so_proto->pr_flags & PR_WANTRCVD) &&
- (((flags & MSG_WAITALL) && uio->uio_resid > 0) ||
- !(flags & MSG_SOCALLBCK))) {
- SOCKBUF_UNLOCK(sb);
- VNET_SO_ASSERT(so);
- (*so->so_proto->pr_usrreqs->pru_rcvd)(so, flags);
- SOCKBUF_LOCK(sb);
+ wr = mk_update_tcb_for_ddp(sc, toep, db_idx, ps,
+ job->uaiocb._aiocb_private.status, ddp_flags, ddp_flags_mask);
+ if (wr == NULL) {
+ recycle_pageset(toep, ps);
+ aio_ddp_requeue_one(toep, job);
+ toep->ddp_queueing = NULL;
+
+ /*
+ * XXX: Need a way to kick a retry here.
+ *
+ * XXX: We know the fixed size needed and could
+ * preallocate this using a blocking request at the
+ * start of the task to avoid having to handle this
+ * edge case.
+ */
+ printf("%s: mk_update_tcb_for_ddp failed\n", __func__);
+ return;
+ }
+
+ if (!aio_set_cancel_function(job, t4_aio_cancel_active)) {
+ free_wrqe(wr);
+ recycle_pageset(toep, ps);
+ aio_ddp_cancel_one(job);
+ toep->ddp_queueing = NULL;
+ goto restart;
+ }
+
+#ifdef VERBOSE_TRACES
+ CTR5(KTR_CXGBE, "%s: scheduling %p for DDP[%d] (flags %#lx/%#lx)",
+ __func__, job, db_idx, ddp_flags, ddp_flags_mask);
+#endif
+ /* Give the chip the go-ahead. */
+ t4_wrq_tx(sc, wr);
+ db = &toep->db[db_idx];
+ db->cancel_pending = 0;
+ db->job = job;
+ db->ps = ps;
+ toep->ddp_queueing = NULL;
+ toep->ddp_flags |= buf_flag;
+ toep->ddp_active_count++;
+ if (toep->ddp_active_count == 1) {
+ MPASS(toep->ddp_active_id == -1);
+ toep->ddp_active_id = db_idx;
+ CTR2(KTR_CXGBE, "%s: ddp_active_id = %d", __func__,
+ toep->ddp_active_id);
+ }
+ goto restart;
+}
+
+void
+ddp_queue_toep(struct toepcb *toep)
+{
+
+ DDP_ASSERT_LOCKED(toep);
+ if (toep->ddp_flags & DDP_TASK_ACTIVE)
+ return;
+ toep->ddp_flags |= DDP_TASK_ACTIVE;
+ hold_toepcb(toep);
+ soaio_enqueue(&toep->ddp_requeue_task);
+}
+
+static void
+aio_ddp_requeue_task(void *context, int pending)
+{
+ struct toepcb *toep = context;
+
+ DDP_LOCK(toep);
+ aio_ddp_requeue(toep);
+ toep->ddp_flags &= ~DDP_TASK_ACTIVE;
+ DDP_UNLOCK(toep);
+
+ free_toepcb(toep);
+}
+
+static void
+t4_aio_cancel_active(struct kaiocb *job)
+{
+ struct socket *so = job->fd_file->f_data;
+ struct tcpcb *tp = so_sototcpcb(so);
+ struct toepcb *toep = tp->t_toe;
+ struct adapter *sc = td_adapter(toep->td);
+ uint64_t valid_flag;
+ int i;
+
+ DDP_LOCK(toep);
+ if (aio_cancel_cleared(job)) {
+ DDP_UNLOCK(toep);
+ aio_ddp_cancel_one(job);
+ return;
+ }
+
+ for (i = 0; i < nitems(toep->db); i++) {
+ if (toep->db[i].job == job) {
+ /* Should only ever get one cancel request for a job. */
+ MPASS(toep->db[i].cancel_pending == 0);
+
+ /*
+ * Invalidate this buffer. It will be
+ * cancelled or partially completed once the
+ * card ACKs the invalidate.
+ */
+ valid_flag = i == 0 ? V_TF_DDP_BUF0_VALID(1) :
+ V_TF_DDP_BUF1_VALID(1);
+ t4_set_tcb_field_rpl(sc, toep, 1, W_TCB_RX_DDP_FLAGS,
+ valid_flag, 0, i + DDP_BUF0_INVALIDATED);
+ toep->db[i].cancel_pending = 1;
+ CTR2(KTR_CXGBE, "%s: request %p marked pending",
+ __func__, job);
+ break;
}
}
+ DDP_UNLOCK(toep);
+}
+
+static void
+t4_aio_cancel_queued(struct kaiocb *job)
+{
+ struct socket *so = job->fd_file->f_data;
+ struct tcpcb *tp = so_sototcpcb(so);
+ struct toepcb *toep = tp->t_toe;
+
+ DDP_LOCK(toep);
+ if (!aio_cancel_cleared(job)) {
+ TAILQ_REMOVE(&toep->ddp_aiojobq, job, list);
+ toep->ddp_waiting_count--;
+ if (toep->ddp_waiting_count == 0)
+ ddp_queue_toep(toep);
+ }
+ CTR2(KTR_CXGBE, "%s: request %p cancelled", __func__, job);
+ DDP_UNLOCK(toep);
+
+ aio_ddp_cancel_one(job);
+}
+
+int
+t4_aio_queue_ddp(struct socket *so, struct kaiocb *job)
+{
+ struct tcpcb *tp = so_sototcpcb(so);
+ struct toepcb *toep = tp->t_toe;
+
+
+ /* Ignore writes. */
+ if (job->uaiocb.aio_lio_opcode != LIO_READ)
+ return (EOPNOTSUPP);
+
+ DDP_LOCK(toep);
/*
- * For MSG_WAITALL we may have to loop again and wait for
- * more data to come in.
+ * XXX: Think about possibly returning errors for ENOTCONN,
+ * etc. Perhaps the caller would only queue the request
+ * if it failed with EOPNOTSUPP?
*/
- if ((flags & MSG_WAITALL) && uio->uio_resid > 0)
- goto restart;
-out:
- SOCKBUF_LOCK_ASSERT(sb);
- SBLASTRECORDCHK(sb);
- SBLASTMBUFCHK(sb);
- SOCKBUF_UNLOCK(sb);
- sbunlock(sb);
- return (error);
+
+#ifdef VERBOSE_TRACES
+ CTR2(KTR_CXGBE, "%s: queueing %p", __func__, job);
+#endif
+ if (!aio_set_cancel_function(job, t4_aio_cancel_queued))
+ panic("new job was cancelled");
+ TAILQ_INSERT_TAIL(&toep->ddp_aiojobq, job, list);
+ job->uaiocb._aiocb_private.status = 0;
+ toep->ddp_waiting_count++;
+ toep->ddp_flags |= DDP_OK;
+
+ /*
+ * Try to handle this request synchronously. If this has
+ * to block because the task is running, it will just bail
+ * and let the task handle it instead.
+ */
+ aio_ddp_requeue(toep);
+ DDP_UNLOCK(toep);
+ return (0);
+}
+
+int
+t4_ddp_mod_load(void)
+{
+
+ TAILQ_INIT(&ddp_orphan_pagesets);
+ mtx_init(&ddp_orphan_pagesets_lock, "ddp orphans", NULL, MTX_DEF);
+ TASK_INIT(&ddp_orphan_task, 0, ddp_free_orphan_pagesets, NULL);
+ return (0);
}
+void
+t4_ddp_mod_unload(void)
+{
+
+ taskqueue_drain(taskqueue_thread, &ddp_orphan_task);
+ MPASS(TAILQ_EMPTY(&ddp_orphan_pagesets));
+ mtx_destroy(&ddp_orphan_pagesets_lock);
+}
#endif
diff --git a/sys/dev/cxgbe/tom/t4_listen.c b/sys/dev/cxgbe/tom/t4_listen.c
index 36b53d3..9865cc4 100644
--- a/sys/dev/cxgbe/tom/t4_listen.c
+++ b/sys/dev/cxgbe/tom/t4_listen.c
@@ -1305,6 +1305,7 @@ found:
REJECT_PASS_ACCEPT();
}
so = inp->inp_socket;
+ CURVNET_SET(so->so_vnet);
mtu_idx = find_best_mtu_idx(sc, &inc, be16toh(cpl->tcpopt.mss));
rscale = cpl->tcpopt.wsf && V_tcp_do_rfc1323 ? select_rcv_wscale() : 0;
@@ -1351,6 +1352,7 @@ found:
*/
toe_syncache_add(&inc, &to, &th, inp, tod, synqe);
INP_UNLOCK_ASSERT(inp); /* ok to assert, we have a ref on the inp */
+ CURVNET_RESTORE();
/*
* If we replied during syncache_add (synqe->wr has been consumed),
diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c
index fe7ec76..452c47e 100644
--- a/sys/dev/cxgbe/tom/t4_tom.c
+++ b/sys/dev/cxgbe/tom/t4_tom.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/protosw.h>
#include <sys/domain.h>
+#include <sys/refcount.h>
#include <sys/rmlock.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -152,6 +153,7 @@ alloc_toepcb(struct vi_info *vi, int txqid, int rxqid, int flags)
if (toep == NULL)
return (NULL);
+ refcount_init(&toep->refcount, 1);
toep->td = sc->tom_softc;
toep->vi = vi;
toep->tx_total = tx_credits;
@@ -165,19 +167,32 @@ alloc_toepcb(struct vi_info *vi, int txqid, int rxqid, int flags)
toep->txsd_avail = txsd_total;
toep->txsd_pidx = 0;
toep->txsd_cidx = 0;
+ ddp_init_toep(toep);
return (toep);
}
+struct toepcb *
+hold_toepcb(struct toepcb *toep)
+{
+
+ refcount_acquire(&toep->refcount);
+ return (toep);
+}
+
void
free_toepcb(struct toepcb *toep)
{
+ if (refcount_release(&toep->refcount) == 0)
+ return;
+
KASSERT(!(toep->flags & TPF_ATTACHED),
("%s: attached to an inpcb", __func__));
KASSERT(!(toep->flags & TPF_CPL_PENDING),
("%s: CPL pending", __func__));
+ ddp_uninit_toep(toep);
free(toep, M_CXGBE);
}
@@ -259,6 +274,8 @@ undo_offload_socket(struct socket *so)
mtx_lock(&td->toep_list_lock);
TAILQ_REMOVE(&td->toep_list, toep, link);
mtx_unlock(&td->toep_list_lock);
+
+ free_toepcb(toep);
}
static void
@@ -283,9 +300,9 @@ release_offload_resources(struct toepcb *toep)
*/
MPASS(mbufq_len(&toep->ulp_pduq) == 0);
MPASS(mbufq_len(&toep->ulp_pdu_reclaimq) == 0);
-
- if (toep->ulp_mode == ULP_MODE_TCPDDP)
- release_ddp_resources(toep);
+#ifdef INVARIANTS
+ ddp_assert_empty(toep);
+#endif
if (toep->l2te)
t4_l2t_release(toep->l2te);
@@ -389,6 +406,8 @@ final_cpl_received(struct toepcb *toep)
CTR6(KTR_CXGBE, "%s: tid %d, toep %p (0x%x), inp %p (0x%x)",
__func__, toep->tid, toep, toep->flags, inp, inp->inp_flags);
+ if (toep->ulp_mode == ULP_MODE_TCPDDP)
+ release_ddp_resources(toep);
toep->inp = NULL;
toep->flags &= ~TPF_CPL_PENDING;
mbufq_drain(&toep->ulp_pdu_reclaimq);
@@ -599,7 +618,6 @@ set_tcpddp_ulp_mode(struct toepcb *toep)
toep->ulp_mode = ULP_MODE_TCPDDP;
toep->ddp_flags = DDP_OK;
- toep->ddp_score = DDP_LOW_SCORE;
}
int
@@ -1109,12 +1127,16 @@ t4_tom_mod_load(void)
int rc;
struct protosw *tcp_protosw, *tcp6_protosw;
+ rc = t4_ddp_mod_load();
+ if (rc != 0)
+ return (rc);
+
tcp_protosw = pffindproto(PF_INET, IPPROTO_TCP, SOCK_STREAM);
if (tcp_protosw == NULL)
return (ENOPROTOOPT);
bcopy(tcp_protosw, &ddp_protosw, sizeof(ddp_protosw));
bcopy(tcp_protosw->pr_usrreqs, &ddp_usrreqs, sizeof(ddp_usrreqs));
- ddp_usrreqs.pru_soreceive = t4_soreceive_ddp;
+ ddp_usrreqs.pru_aio_queue = t4_aio_queue_ddp;
ddp_protosw.pr_usrreqs = &ddp_usrreqs;
tcp6_protosw = pffindproto(PF_INET6, IPPROTO_TCP, SOCK_STREAM);
@@ -1122,7 +1144,7 @@ t4_tom_mod_load(void)
return (ENOPROTOOPT);
bcopy(tcp6_protosw, &ddp6_protosw, sizeof(ddp6_protosw));
bcopy(tcp6_protosw->pr_usrreqs, &ddp6_usrreqs, sizeof(ddp6_usrreqs));
- ddp6_usrreqs.pru_soreceive = t4_soreceive_ddp;
+ ddp6_usrreqs.pru_aio_queue = t4_aio_queue_ddp;
ddp6_protosw.pr_usrreqs = &ddp6_usrreqs;
TIMEOUT_TASK_INIT(taskqueue_thread, &clip_task, 0, t4_clip_task, NULL);
@@ -1162,6 +1184,8 @@ t4_tom_mod_unload(void)
taskqueue_cancel_timeout(taskqueue_thread, &clip_task, NULL);
}
+ t4_ddp_mod_unload();
+
return (0);
}
#endif /* TCP_OFFLOAD */
diff --git a/sys/dev/cxgbe/tom/t4_tom.h b/sys/dev/cxgbe/tom/t4_tom.h
index f61888d..09238a4 100644
--- a/sys/dev/cxgbe/tom/t4_tom.h
+++ b/sys/dev/cxgbe/tom/t4_tom.h
@@ -74,6 +74,8 @@ enum {
DDP_ON = (1 << 2), /* DDP is turned on */
DDP_BUF0_ACTIVE = (1 << 3), /* buffer 0 in use (not invalidated) */
DDP_BUF1_ACTIVE = (1 << 4), /* buffer 1 in use (not invalidated) */
+ DDP_TASK_ACTIVE = (1 << 5), /* requeue task is queued / running */
+ DDP_DEAD = (1 << 6), /* toepcb is shutting down */
};
struct ofld_tx_sdesc {
@@ -81,19 +83,36 @@ struct ofld_tx_sdesc {
uint8_t tx_credits; /* firmware tx credits (unit is 16B) */
};
-struct ddp_buffer {
- uint32_t tag; /* includes color, page pod addr, and DDP page size */
+struct pageset {
+ TAILQ_ENTRY(pageset) link;
+ vm_page_t *pages;
+ int npages;
+ int flags;
u_int ppod_addr;
int nppods;
- int offset;
+ uint32_t tag; /* includes color, page pod addr, and DDP page size */
+ int offset; /* offset in first page */
int len;
- int npages;
- vm_page_t *pages;
+ struct vmspace *vm;
+ u_int vm_timestamp;
+};
+
+TAILQ_HEAD(pagesetq, pageset);
+
+#define PS_WIRED 0x0001 /* Pages wired rather than held. */
+#define PS_PPODS_WRITTEN 0x0002 /* Page pods written to the card. */
+
+struct ddp_buffer {
+ struct pageset *ps;
+
+ struct kaiocb *job;
+ int cancel_pending;
};
struct toepcb {
TAILQ_ENTRY(toepcb) link; /* toep_list */
u_int flags; /* miscellaneous flags */
+ int refcount;
struct tom_data *td;
struct inpcb *inp; /* backpointer to host stack's PCB */
struct vi_info *vi; /* virtual interface */
@@ -121,9 +140,16 @@ struct toepcb {
struct mbufq ulp_pdu_reclaimq;
u_int ddp_flags;
- struct ddp_buffer *db[2];
- time_t ddp_disabled;
- uint8_t ddp_score;
+ struct ddp_buffer db[2];
+ TAILQ_HEAD(, pageset) ddp_cached_pagesets;
+ TAILQ_HEAD(, kaiocb) ddp_aiojobq;
+ u_int ddp_waiting_count;
+ u_int ddp_active_count;
+ u_int ddp_cached_count;
+ int ddp_active_id; /* the currently active DDP buffer */
+ struct task ddp_requeue_task;
+ struct kaiocb *ddp_queueing;
+ struct mtx ddp_lock;
/* Tx software descriptor */
uint8_t txsd_total;
@@ -133,6 +159,10 @@ struct toepcb {
struct ofld_tx_sdesc txsd[];
};
+#define DDP_LOCK(toep) mtx_lock(&(toep)->ddp_lock)
+#define DDP_UNLOCK(toep) mtx_unlock(&(toep)->ddp_lock)
+#define DDP_ASSERT_LOCKED(toep) mtx_assert(&(toep)->ddp_lock, MA_OWNED)
+
struct flowc_tx_params {
uint32_t snd_nxt;
uint32_t rcv_nxt;
@@ -242,6 +272,7 @@ mbuf_ulp_submode(struct mbuf *m)
/* t4_tom.c */
struct toepcb *alloc_toepcb(struct vi_info *, int, int, int);
+struct toepcb *hold_toepcb(struct toepcb *);
void free_toepcb(struct toepcb *);
void offload_socket(struct socket *, struct toepcb *);
void undo_offload_socket(struct socket *);
@@ -289,11 +320,14 @@ void send_flowc_wr(struct toepcb *, struct flowc_tx_params *);
void send_reset(struct adapter *, struct toepcb *, uint32_t);
void make_established(struct toepcb *, uint32_t, uint32_t, uint16_t);
void t4_rcvd(struct toedev *, struct tcpcb *);
+void t4_rcvd_locked(struct toedev *, struct tcpcb *);
int t4_tod_output(struct toedev *, struct tcpcb *);
int t4_send_fin(struct toedev *, struct tcpcb *);
int t4_send_rst(struct toedev *, struct tcpcb *);
void t4_set_tcb_field(struct adapter *, struct toepcb *, int, uint16_t,
uint64_t, uint64_t);
+void t4_set_tcb_field_rpl(struct adapter *, struct toepcb *, int, uint16_t,
+ uint64_t, uint64_t, uint8_t);
void t4_push_frames(struct adapter *sc, struct toepcb *toep, int drop);
void t4_push_pdus(struct adapter *sc, struct toepcb *toep, int drop);
@@ -302,10 +336,17 @@ void t4_init_ddp(struct adapter *, struct tom_data *);
void t4_uninit_ddp(struct adapter *, struct tom_data *);
int t4_soreceive_ddp(struct socket *, struct sockaddr **, struct uio *,
struct mbuf **, struct mbuf **, int *);
-void enable_ddp(struct adapter *, struct toepcb *toep);
+int t4_aio_queue_ddp(struct socket *, struct kaiocb *);
+int t4_ddp_mod_load(void);
+void t4_ddp_mod_unload(void);
+void ddp_assert_empty(struct toepcb *);
+void ddp_init_toep(struct toepcb *);
+void ddp_uninit_toep(struct toepcb *);
+void ddp_queue_toep(struct toepcb *);
void release_ddp_resources(struct toepcb *toep);
-void handle_ddp_close(struct toepcb *, struct tcpcb *, struct sockbuf *,
- uint32_t);
+void handle_ddp_close(struct toepcb *, struct tcpcb *, uint32_t);
+void handle_ddp_indicate(struct toepcb *);
+void handle_ddp_tcb_rpl(struct toepcb *, const struct cpl_set_tcb_rpl *);
void insert_ddp_data(struct toepcb *, uint32_t);
#endif
diff --git a/sys/dev/e1000/e1000_82571.c b/sys/dev/e1000/e1000_82571.c
index a64ef56..5ff17f0 100644
--- a/sys/dev/e1000/e1000_82571.c
+++ b/sys/dev/e1000/e1000_82571.c
@@ -396,7 +396,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
}
/* Ensure that the inter-port SWSM.SMBI lock bit is clear before
- * first NVM or PHY acess. This should be done for single-port
+ * first NVM or PHY access. This should be done for single-port
* devices, and for one port only on dual-port devices so that
* for those devices we can still use the SMBI lock to synchronize
* inter-port accesses to the PHY & NVM.
diff --git a/sys/dev/e1000/e1000_mbx.c b/sys/dev/e1000/e1000_mbx.c
index 1de19a4..34649bf 100644
--- a/sys/dev/e1000/e1000_mbx.c
+++ b/sys/dev/e1000/e1000_mbx.c
@@ -67,7 +67,7 @@ static s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw,
* @size: Length of buffer
* @mbx_id: id of mailbox to read
*
- * returns SUCCESS if it successfuly read message from buffer
+ * returns SUCCESS if it successfully read message from buffer
**/
s32 e1000_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
{
@@ -493,7 +493,7 @@ out_no_write:
* @size: Length of buffer
* @mbx_id: id of mailbox to read
*
- * returns SUCCESS if it successfuly read message from buffer
+ * returns SUCCESS if it successfully read message from buffer
**/
static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size,
u16 E1000_UNUSEDARG mbx_id)
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index a989cae..14f5463 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -582,7 +582,7 @@ em_attach(device_t dev)
}
/*
** In the new SPT device flash is not a
- ** seperate BAR, rather it is also in BAR0,
+ ** separate BAR, rather it is also in BAR0,
** so use the same tag and an offset handle for the
** FLASH read/write macros in the shared code.
*/
@@ -1929,7 +1929,7 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp)
* so we firstly get a writable mbuf chain then coalesce ethernet/
* IP/TCP header into a single buffer to meet the requirement of
* controller. This also simplifies IP/TCP/UDP checksum offloading
- * which also has similiar restrictions.
+ * which also has similar restrictions.
*/
if (do_tso || m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) {
if (do_tso || (m_head->m_next != NULL &&
@@ -2595,7 +2595,7 @@ em_allocate_legacy(struct adapter *adapter)
*
* Setup the MSIX Interrupt handlers
* This is not really Multiqueue, rather
- * its just seperate interrupt vectors
+ * its just separate interrupt vectors
* for TX, RX, and Link.
*
**********************************************************************/
@@ -3083,7 +3083,7 @@ em_reset(struct adapter *adapter)
* received after sending an XOFF.
* - Low water mark works best when it is very near the high water mark.
* This allows the receiver to restart by sending XON when it has
- * drained a bit. Here we use an arbitary value of 1500 which will
+ * drained a bit. Here we use an arbitrary value of 1500 which will
* restart after one full frame is pulled from the buffer. There
* could be several smaller frames in the buffer and if so they will
* not trigger the XON until their total number reduces the buffer
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index 965370d..120111d 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -304,7 +304,7 @@ SYSCTL_INT(_hw_igb, OID_AUTO, buf_ring_size, CTLFLAG_RDTUN,
/*
** Header split causes the packet header to
-** be dma'd to a seperate mbuf from the payload.
+** be dma'd to a separate mbuf from the payload.
** this can have memory alignment benefits. But
** another plus is that small packets often fit
** into the header and thus use no cluster. Its
@@ -659,7 +659,8 @@ igb_attach(device_t dev)
return (0);
err_late:
- igb_detach(dev);
+ if (igb_detach(dev) == 0) /* igb_detach() already did the cleanup */
+ return(error);
igb_free_transmit_structures(adapter);
igb_free_receive_structures(adapter);
igb_release_hw_control(adapter);
@@ -4482,7 +4483,7 @@ skip_head:
** Now set up the LRO interface, we
** also only do head split when LRO
** is enabled, since so often they
- ** are undesireable in similar setups.
+ ** are undesirable in similar setups.
*/
if (ifp->if_capenable & IFCAP_LRO) {
error = tcp_lro_init(lro);
diff --git a/sys/dev/e1000/if_igb.h b/sys/dev/e1000/if_igb.h
index a0c35be..a30fc99 100644
--- a/sys/dev/e1000/if_igb.h
+++ b/sys/dev/e1000/if_igb.h
@@ -35,6 +35,10 @@
#ifndef _IF_IGB_H_
#define _IF_IGB_H_
+#ifdef ALTQ
+#define IGB_LEGACY_TX
+#endif
+
#include <sys/param.h>
#include <sys/systm.h>
#ifndef IGB_LEGACY_TX
diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c
index 864ed6b..50b2cb0 100644
--- a/sys/dev/e1000/if_lem.c
+++ b/sys/dev/e1000/if_lem.c
@@ -2412,7 +2412,7 @@ lem_hardware_init(struct adapter *adapter)
* received after sending an XOFF.
* - Low water mark works best when it is very near the high water mark.
* This allows the receiver to restart by sending XON when it has
- * drained a bit. Here we use an arbitary value of 1500 which will
+ * drained a bit. Here we use an arbitrary value of 1500 which will
* restart after one full frame is pulled from the buffer. There
* could be several smaller frames in the buffer and if so they will
* not trigger the XON until their total number reduces the buffer
@@ -3838,7 +3838,7 @@ discard:
* copy ethernet header to the new mbuf. The new mbuf is prepended into the
* existing mbuf chain.
*
- * Be aware, best performance of the 8254x is achived only when jumbo frame is
+ * Be aware, best performance of the 8254x is achieved only when jumbo frame is
* not used at all on architectures with strict alignment.
*/
static int
diff --git a/sys/dev/esp/esp_pci.c b/sys/dev/esp/esp_pci.c
index bd85d8e..fc3af2b 100644
--- a/sys/dev/esp/esp_pci.c
+++ b/sys/dev/esp/esp_pci.c
@@ -97,7 +97,7 @@ __FBSDID("$FreeBSD$");
struct esp_pci_softc {
struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
- struct device *sc_dev;
+ device_t sc_dev;
struct resource *sc_res[2];
#define ESP_PCI_RES_INTR 0
diff --git a/sys/dev/fdc/fdc_acpi.c b/sys/dev/fdc/fdc_acpi.c
index 9c6eb35..afef409 100644
--- a/sys/dev/fdc/fdc_acpi.c
+++ b/sys/dev/fdc/fdc_acpi.c
@@ -135,14 +135,13 @@ fdc_acpi_attach(device_t dev)
obj = buf.Pointer;
error = fdc_acpi_probe_children(bus, dev, obj->Buffer.Pointer);
- if (error == 0)
- fdc_start_worker(dev);
-
out:
if (buf.Pointer)
free(buf.Pointer, M_TEMP);
if (error != 0)
fdc_release_resources(sc);
+ else
+ fdc_start_worker(dev);
return (error);
}
diff --git a/sys/dev/fdc/fdcvar.h b/sys/dev/fdc/fdcvar.h
index be4b638..edaef79 100644
--- a/sys/dev/fdc/fdcvar.h
+++ b/sys/dev/fdc/fdcvar.h
@@ -66,7 +66,7 @@ struct fdc_data {
bus_space_handle_t ioh[FDC_MAXREG];
int ioff[FDC_MAXREG];
void *fdc_intr;
- struct device *fdc_dev;
+ device_t fdc_dev;
struct mtx fdc_mtx;
struct proc *fdc_thread;
};
diff --git a/sys/dev/hptiop/hptiop.c b/sys/dev/hptiop/hptiop.c
index b9c7211..ea05f4b 100644
--- a/sys/dev/hptiop/hptiop.c
+++ b/sys/dev/hptiop/hptiop.c
@@ -1241,7 +1241,7 @@ static int hptiop_post_ioctl_command_mv(struct hpt_iop_hba *hba,
req->header.result = IOP_RESULT_PENDING;
req->header.flags = IOP_REQUEST_FLAG_OUTPUT_CONTEXT;
size = req->header.size >> 8;
- size = size > 3 ? 3 : size;
+ size = imin(3, size);
req_phy = hba->ctlcfgcmd_phy | MVIOP_MU_QUEUE_ADDR_HOST_BIT | size;
hptiop_mv_inbound_write(req_phy, hba);
@@ -2561,7 +2561,7 @@ static void hptiop_post_req_mv(struct hpt_iop_hba *hba,
size = req->header.size >> 8;
hptiop_mv_inbound_write(req_phy
| MVIOP_MU_QUEUE_ADDR_HOST_BIT
- | (size > 3 ? 3 : size), hba);
+ | imin(3, size), hba);
}
static void hptiop_post_req_mvfrey(struct hpt_iop_hba *hba,
diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c
index 85ceacb..2a68e6e 100644
--- a/sys/dev/ioat/ioat.c
+++ b/sys/dev/ioat/ioat.c
@@ -52,6 +52,9 @@ __FBSDID("$FreeBSD$");
#include "ioat_hw.h"
#include "ioat_internal.h"
+#ifndef BUS_SPACE_MAXADDR_40BIT
+#define BUS_SPACE_MAXADDR_40BIT 0xFFFFFFFFFFULL
+#endif
#define IOAT_INTR_TIMO (hz / 10)
#define IOAT_REFLK (&ioat->submit_lock)
@@ -132,7 +135,7 @@ static device_method_t ioat_pci_methods[] = {
DEVMETHOD(device_probe, ioat_probe),
DEVMETHOD(device_attach, ioat_attach),
DEVMETHOD(device_detach, ioat_detach),
- { 0, 0 }
+ DEVMETHOD_END
};
static driver_t ioat_pci_driver = {
@@ -454,7 +457,7 @@ ioat3_attach(device_t device)
num_descriptors = 1 << ioat->ring_size_order;
bus_dma_tag_create(bus_get_dma_tag(ioat->device), 0x40, 0x0,
- BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+ BUS_SPACE_MAXADDR_40BIT, BUS_SPACE_MAXADDR, NULL, NULL,
sizeof(struct ioat_dma_hw_descriptor), 1,
sizeof(struct ioat_dma_hw_descriptor), 0, NULL, NULL,
&ioat->hw_desc_tag);
@@ -879,8 +882,8 @@ ioat_op_generic(struct ioat_softc *ioat, uint8_t op,
mtx_assert(&ioat->submit_lock, MA_OWNED);
- KASSERT((flags & ~DMA_ALL_FLAGS) == 0, ("Unrecognized flag(s): %#x",
- flags & ~DMA_ALL_FLAGS));
+ KASSERT((flags & ~_DMA_GENERIC_FLAGS) == 0,
+ ("Unrecognized flag(s): %#x", flags & ~_DMA_GENERIC_FLAGS));
if ((flags & DMA_NO_WAIT) != 0)
mflags = M_NOWAIT;
else
@@ -1015,6 +1018,164 @@ ioat_copy_8k_aligned(bus_dmaengine_t dmaengine, bus_addr_t dst1,
}
struct bus_dmadesc *
+ioat_copy_crc(bus_dmaengine_t dmaengine, bus_addr_t dst, bus_addr_t src,
+ bus_size_t len, uint32_t *initialseed, bus_addr_t crcptr,
+ bus_dmaengine_callback_t callback_fn, void *callback_arg, uint32_t flags)
+{
+ struct ioat_crc32_hw_descriptor *hw_desc;
+ struct ioat_descriptor *desc;
+ struct ioat_softc *ioat;
+ uint32_t teststore;
+ uint8_t op;
+
+ CTR0(KTR_IOAT, __func__);
+ ioat = to_ioat_softc(dmaengine);
+
+ if ((ioat->capabilities & IOAT_DMACAP_MOVECRC) == 0) {
+ ioat_log_message(0, "%s: Device lacks MOVECRC capability\n",
+ __func__);
+ return (NULL);
+ }
+ if (((src | dst) & (0xffffffull << 40)) != 0) {
+ ioat_log_message(0, "%s: High 24 bits of src/dst invalid\n",
+ __func__);
+ return (NULL);
+ }
+ teststore = (flags & _DMA_CRC_TESTSTORE);
+ if (teststore == _DMA_CRC_TESTSTORE) {
+ ioat_log_message(0, "%s: TEST and STORE invalid\n", __func__);
+ return (NULL);
+ }
+ if (teststore == 0 && (flags & DMA_CRC_INLINE) != 0) {
+ ioat_log_message(0, "%s: INLINE invalid without TEST or STORE\n",
+ __func__);
+ return (NULL);
+ }
+
+ switch (teststore) {
+ case DMA_CRC_STORE:
+ op = IOAT_OP_MOVECRC_STORE;
+ break;
+ case DMA_CRC_TEST:
+ op = IOAT_OP_MOVECRC_TEST;
+ break;
+ default:
+ KASSERT(teststore == 0, ("bogus"));
+ op = IOAT_OP_MOVECRC;
+ break;
+ }
+
+ if ((flags & DMA_CRC_INLINE) == 0 &&
+ (crcptr & (0xffffffull << 40)) != 0) {
+ ioat_log_message(0,
+ "%s: High 24 bits of crcptr invalid\n", __func__);
+ return (NULL);
+ }
+
+ desc = ioat_op_generic(ioat, op, len, src, dst, callback_fn,
+ callback_arg, flags & ~_DMA_CRC_FLAGS);
+ if (desc == NULL)
+ return (NULL);
+
+ hw_desc = desc->u.crc32;
+
+ if ((flags & DMA_CRC_INLINE) == 0)
+ hw_desc->crc_address = crcptr;
+ else
+ hw_desc->u.control.crc_location = 1;
+
+ if (initialseed != NULL) {
+ hw_desc->u.control.use_seed = 1;
+ hw_desc->seed = *initialseed;
+ }
+
+ if (g_ioat_debug_level >= 3)
+ dump_descriptor(hw_desc);
+
+ ioat_submit_single(ioat);
+ return (&desc->bus_dmadesc);
+}
+
+struct bus_dmadesc *
+ioat_crc(bus_dmaengine_t dmaengine, bus_addr_t src, bus_size_t len,
+ uint32_t *initialseed, bus_addr_t crcptr,
+ bus_dmaengine_callback_t callback_fn, void *callback_arg, uint32_t flags)
+{
+ struct ioat_crc32_hw_descriptor *hw_desc;
+ struct ioat_descriptor *desc;
+ struct ioat_softc *ioat;
+ uint32_t teststore;
+ uint8_t op;
+
+ CTR0(KTR_IOAT, __func__);
+ ioat = to_ioat_softc(dmaengine);
+
+ if ((ioat->capabilities & IOAT_DMACAP_CRC) == 0) {
+ ioat_log_message(0, "%s: Device lacks CRC capability\n",
+ __func__);
+ return (NULL);
+ }
+ if ((src & (0xffffffull << 40)) != 0) {
+ ioat_log_message(0, "%s: High 24 bits of src invalid\n",
+ __func__);
+ return (NULL);
+ }
+ teststore = (flags & _DMA_CRC_TESTSTORE);
+ if (teststore == _DMA_CRC_TESTSTORE) {
+ ioat_log_message(0, "%s: TEST and STORE invalid\n", __func__);
+ return (NULL);
+ }
+ if (teststore == 0 && (flags & DMA_CRC_INLINE) != 0) {
+ ioat_log_message(0, "%s: INLINE invalid without TEST or STORE\n",
+ __func__);
+ return (NULL);
+ }
+
+ switch (teststore) {
+ case DMA_CRC_STORE:
+ op = IOAT_OP_CRC_STORE;
+ break;
+ case DMA_CRC_TEST:
+ op = IOAT_OP_CRC_TEST;
+ break;
+ default:
+ KASSERT(teststore == 0, ("bogus"));
+ op = IOAT_OP_CRC;
+ break;
+ }
+
+ if ((flags & DMA_CRC_INLINE) == 0 &&
+ (crcptr & (0xffffffull << 40)) != 0) {
+ ioat_log_message(0,
+ "%s: High 24 bits of crcptr invalid\n", __func__);
+ return (NULL);
+ }
+
+ desc = ioat_op_generic(ioat, op, len, src, 0, callback_fn,
+ callback_arg, flags & ~_DMA_CRC_FLAGS);
+ if (desc == NULL)
+ return (NULL);
+
+ hw_desc = desc->u.crc32;
+
+ if ((flags & DMA_CRC_INLINE) == 0)
+ hw_desc->crc_address = crcptr;
+ else
+ hw_desc->u.control.crc_location = 1;
+
+ if (initialseed != NULL) {
+ hw_desc->u.control.use_seed = 1;
+ hw_desc->seed = *initialseed;
+ }
+
+ if (g_ioat_debug_level >= 3)
+ dump_descriptor(hw_desc);
+
+ ioat_submit_single(ioat);
+ return (&desc->bus_dmadesc);
+}
+
+struct bus_dmadesc *
ioat_blockfill(bus_dmaengine_t dmaengine, bus_addr_t dst, uint64_t fillpattern,
bus_size_t len, bus_dmaengine_callback_t callback_fn, void *callback_arg,
uint32_t flags)
diff --git a/sys/dev/ioat/ioat.h b/sys/dev/ioat/ioat.h
index ff05602..2e10124 100644
--- a/sys/dev/ioat/ioat.h
+++ b/sys/dev/ioat/ioat.h
@@ -52,7 +52,26 @@ __FBSDID("$FreeBSD$");
* may be prefetched before operation 1 completes.
*/
#define DMA_FENCE 0x4
-#define DMA_ALL_FLAGS (DMA_INT_EN | DMA_NO_WAIT | DMA_FENCE)
+#define _DMA_GENERIC_FLAGS (DMA_INT_EN | DMA_NO_WAIT | DMA_FENCE)
+
+/*
+ * Emit a CRC32C as the result of a ioat_copy_crc() or ioat_crc().
+ */
+#define DMA_CRC_STORE 0x8
+
+/*
+ * Compare the CRC32C of a ioat_copy_crc() or ioat_crc() against an expeceted
+ * value. It is invalid to specify both TEST and STORE.
+ */
+#define DMA_CRC_TEST 0x10
+#define _DMA_CRC_TESTSTORE (DMA_CRC_STORE | DMA_CRC_TEST)
+
+/*
+ * Use an inline comparison CRC32C or emit an inline CRC32C result. Invalid
+ * without one of STORE or TEST.
+ */
+#define DMA_CRC_INLINE 0x20
+#define _DMA_CRC_FLAGS (DMA_CRC_STORE | DMA_CRC_TEST | DMA_CRC_INLINE)
/*
* Hardware revision number. Different hardware revisions support different
@@ -152,6 +171,42 @@ struct bus_dmadesc *ioat_copy_8k_aligned(bus_dmaengine_t dmaengine,
bus_dmaengine_callback_t callback_fn, void *callback_arg, uint32_t flags);
/*
+ * Copy len bytes from dst to src, like ioat_copy().
+ *
+ * Additionally, accumulate a CRC32C of the data.
+ *
+ * If initialseed is not NULL, the value it points to is used to seed the
+ * initial value of the CRC32C.
+ *
+ * If flags include DMA_CRC_STORE and not DMA_CRC_INLINE, crcptr is written
+ * with the 32-bit CRC32C result (in wire format).
+ *
+ * If flags include DMA_CRC_TEST and not DMA_CRC_INLINE, the computed CRC32C is
+ * compared with the 32-bit CRC32C pointed to by crcptr. If they do not match,
+ * a channel error is raised.
+ *
+ * If the DMA_CRC_INLINE flag is set, crcptr is ignored and the DMA engine uses
+ * the 4 bytes trailing the source data (TEST) or the destination data (STORE).
+ */
+struct bus_dmadesc *ioat_copy_crc(bus_dmaengine_t dmaengine, bus_addr_t dst,
+ bus_addr_t src, bus_size_t len, uint32_t *initialseed, bus_addr_t crcptr,
+ bus_dmaengine_callback_t callback_fn, void *callback_arg, uint32_t flags);
+
+/*
+ * ioat_crc() is nearly identical to ioat_copy_crc(), but does not actually
+ * move data around.
+ *
+ * Like ioat_copy_crc, ioat_crc computes a CRC32C over len bytes pointed to by
+ * src. The flags affect its operation in the same way, with one exception:
+ *
+ * If flags includes both DMA_CRC_STORE and DMA_CRC_INLINE, the computed CRC32C
+ * is written to the 4 bytes trailing the *source* data.
+ */
+struct bus_dmadesc *ioat_crc(bus_dmaengine_t dmaengine, bus_addr_t src,
+ bus_size_t len, uint32_t *initialseed, bus_addr_t crcptr,
+ bus_dmaengine_callback_t callback_fn, void *callback_arg, uint32_t flags);
+
+/*
* Issues a null operation. This issues the operation to the hardware, but the
* hardware doesn't do anything with it.
*/
diff --git a/sys/dev/ioat/ioat_internal.h b/sys/dev/ioat/ioat_internal.h
index 85b7316..322671c 100644
--- a/sys/dev/ioat/ioat_internal.h
+++ b/sys/dev/ioat/ioat_internal.h
@@ -211,6 +211,85 @@ struct ioat_fill_hw_descriptor {
uint64_t user2;
};
+struct ioat_crc32_hw_descriptor {
+ uint32_t size;
+ union {
+ uint32_t control_raw;
+ struct generic_dma_control control_generic;
+ struct {
+ uint32_t int_enable:1;
+ uint32_t src_snoop_disable:1;
+ uint32_t dest_snoop_disable:1;
+ uint32_t completion_update:1;
+ uint32_t fence:1;
+ uint32_t reserved1:3;
+ uint32_t bundle:1;
+ uint32_t dest_dca:1;
+ uint32_t hint:1;
+ uint32_t use_seed:1;
+ /*
+ * crc_location:
+ * For IOAT_OP_MOVECRC_TEST and IOAT_OP_CRC_TEST:
+ * 0: comparison value is pointed to by CRC Address
+ * field.
+ * 1: comparison value follows data in wire format
+ * ("inverted reflected bit order") in the 4 bytes
+ * following the source data.
+ *
+ * For IOAT_OP_CRC_STORE:
+ * 0: Result will be stored at location pointed to by
+ * CRC Address field (in wire format).
+ * 1: Result will be stored directly following the
+ * source data.
+ *
+ * For IOAT_OP_MOVECRC_STORE:
+ * 0: Result will be stored at location pointed to by
+ * CRC Address field (in wire format).
+ * 1: Result will be stored directly following the
+ * *destination* data.
+ */
+ uint32_t crc_location:1;
+ uint32_t reserved2:11;
+ /*
+ * MOVECRC - Move data in the same way as standard copy
+ * operation, but also compute CRC32.
+ *
+ * CRC - Only compute CRC on source data.
+ *
+ * There is a CRC accumulator register in the hardware.
+ * If 'initial' is set, it is initialized to the value
+ * in 'seed.'
+ *
+ * In all modes, these operators accumulate size bytes
+ * at src_addr into the running CRC32C.
+ *
+ * Store mode emits the accumulated CRC, in wire
+ * format, as specified by the crc_location bit above.
+ *
+ * Test mode compares the accumulated CRC against the
+ * reference CRC, as described in crc_location above.
+ * On failure, halts the DMA engine with a CRC error
+ * status.
+ */
+ #define IOAT_OP_MOVECRC 0x41
+ #define IOAT_OP_MOVECRC_TEST 0x42
+ #define IOAT_OP_MOVECRC_STORE 0x43
+ #define IOAT_OP_CRC 0x81
+ #define IOAT_OP_CRC_TEST 0x82
+ #define IOAT_OP_CRC_STORE 0x83
+ uint32_t op:8;
+ } control;
+ } u;
+ uint64_t src_addr;
+ uint64_t dest_addr;
+ uint64_t next;
+ uint64_t next_src_addr;
+ uint64_t next_dest_addr;
+ uint32_t seed;
+ uint32_t reserved;
+ uint64_t crc_address;
+};
+
struct ioat_xor_hw_descriptor {
uint32_t size;
union {
@@ -338,6 +417,7 @@ struct ioat_descriptor {
struct ioat_generic_hw_descriptor *generic;
struct ioat_dma_hw_descriptor *dma;
struct ioat_fill_hw_descriptor *fill;
+ struct ioat_crc32_hw_descriptor *crc32;
struct ioat_xor_hw_descriptor *xor;
struct ioat_xor_ext_hw_descriptor *xor_ext;
struct ioat_pq_hw_descriptor *pq;
@@ -348,13 +428,7 @@ struct ioat_descriptor {
bus_addr_t hw_desc_bus_addr;
};
-/* Unsupported by this driver at this time. */
-#define IOAT_OP_MOVECRC 0x41
-#define IOAT_OP_MOVECRC_TEST 0x42
-#define IOAT_OP_MOVECRC_STORE 0x43
-#define IOAT_OP_CRC 0x81
-#define IOAT_OP_CRC_TEST 0x82
-#define IOAT_OP_CRC_STORE 0x83
+/* Unused by this driver at this time. */
#define IOAT_OP_MARKER 0x84
/*
diff --git a/sys/dev/iscsi/icl_soft.c b/sys/dev/iscsi/icl_soft.c
index c006c05..bf8bec7 100644
--- a/sys/dev/iscsi/icl_soft.c
+++ b/sys/dev/iscsi/icl_soft.c
@@ -782,7 +782,7 @@ icl_receive_thread(void *arg)
/*
* Set the low watermark, to be checked by
* soreadable() in icl_soupcall_receive()
- * to avoid unneccessary wakeups until there
+ * to avoid unnecessary wakeups until there
* is enough data received to read the PDU.
*/
SOCKBUF_LOCK(&so->so_rcv);
@@ -908,7 +908,7 @@ icl_conn_send_pdus(struct icl_conn *ic, struct icl_pdu_stailq *queue)
/*
* Set the low watermark, to be checked by
* sowriteable() in icl_soupcall_send()
- * to avoid unneccessary wakeups until there
+ * to avoid unnecessary wakeups until there
* is enough space for the PDU to fit.
*/
SOCKBUF_LOCK(&so->so_snd);
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index 6a740d3..9545fe3 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -344,7 +344,6 @@ static void iwn_scan_end(struct ieee80211com *);
static void iwn_set_channel(struct ieee80211com *);
static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
static void iwn_scan_mindwell(struct ieee80211_scan_state *);
-static void iwn_hw_reset(void *, int);
#ifdef IWN_DEBUG
static char *iwn_get_csr_string(int);
static void iwn_debug_register(struct iwn_softc *);
@@ -677,7 +676,6 @@ iwn_attach(device_t dev)
callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0);
callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
- TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc);
TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc);
TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc);
TASK_INIT(&sc->sc_panic_task, 0, iwn_panicked, sc);
@@ -1400,7 +1398,6 @@ iwn_detach(device_t dev)
iwn_xmit_queue_drain(sc);
IWN_UNLOCK(sc);
- ieee80211_draintask(&sc->sc_ic, &sc->sc_reinit_task);
ieee80211_draintask(&sc->sc_ic, &sc->sc_radioon_task);
ieee80211_draintask(&sc->sc_ic, &sc->sc_radiooff_task);
iwn_stop(sc);
@@ -2215,7 +2212,7 @@ iwn4965_read_eeprom(struct iwn_softc *sc)
/* Read regulatory domain (4 ASCII characters). */
iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4);
- /* Read the list of authorized channels (20MHz ones only). */
+ /* Read the list of authorized channels (20MHz & 40MHz). */
for (i = 0; i < IWN_NBANDS - 1; i++) {
addr = iwn4965_regulatory_bands[i];
iwn_read_eeprom_channels(sc, i, addr);
@@ -2306,7 +2303,7 @@ iwn5000_read_eeprom(struct iwn_softc *sc)
iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN,
sc->eeprom_domain, 4);
- /* Read the list of authorized channels (20MHz ones only). */
+ /* Read the list of authorized channels (20MHz & 40MHz). */
for (i = 0; i < IWN_NBANDS - 1; i++) {
addr = base + sc->base_params->regulatory_bands[i];
iwn_read_eeprom_channels(sc, i, addr);
@@ -4972,7 +4969,7 @@ iwn_watchdog(void *arg)
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
ic_printf(ic, "device timeout\n");
- ieee80211_runtask(ic, &sc->sc_reinit_task);
+ ieee80211_restart_all(ic);
return;
}
}
@@ -8907,19 +8904,6 @@ iwn_scan_mindwell(struct ieee80211_scan_state *ss)
{
/* NB: don't try to abort scan; wait for firmware to finish */
}
-
-static void
-iwn_hw_reset(void *arg0, int pending)
-{
- struct iwn_softc *sc = arg0;
- struct ieee80211com *ic = &sc->sc_ic;
-
- DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
-
- iwn_stop(sc);
- iwn_init(sc);
- ieee80211_notify_radio(ic, 1);
-}
#ifdef IWN_DEBUG
#define IWN_DESC(x) case x: return #x
diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
index a271304..ad9b948 100644
--- a/sys/dev/iwn/if_iwnvar.h
+++ b/sys/dev/iwn/if_iwnvar.h
@@ -304,7 +304,6 @@ struct iwn_softc {
int sc_cap_off; /* PCIe Capabilities. */
/* Tasks used by the driver */
- struct task sc_reinit_task;
struct task sc_radioon_task;
struct task sc_radiooff_task;
struct task sc_panic_task;
diff --git a/sys/dev/ixgbe/if_ixv.c b/sys/dev/ixgbe/if_ixv.c
index 7b6e3d1..13c2bef 100644
--- a/sys/dev/ixgbe/if_ixv.c
+++ b/sys/dev/ixgbe/if_ixv.c
@@ -195,7 +195,7 @@ TUNABLE_INT("hw.ixv.flow_control", &ixv_flow_control);
/*
* Header split: this causes the hardware to DMA
- * the header into a seperate mbuf from the payload,
+ * the header into a separate mbuf from the payload,
* it can be a performance win in some workloads, but
* in others it actually hurts, its off by default.
*/
@@ -1141,7 +1141,7 @@ ixv_local_timer(void *arg)
}
- /* Only truely watchdog if all queues show hung */
+ /* Only truly watchdog if all queues show hung */
if (hung == adapter->num_queues)
goto watchdog;
else if (queues != 0) { /* Force an IRQ on queues with work */
@@ -1958,7 +1958,7 @@ ixv_handle_mbx(void *context, int pending)
}
/*
-** The VF stats registers never have a truely virgin
+** The VF stats registers never have a truly virgin
** starting point, so this routine tries to make an
** artificial one, marking ground zero on attach as
** it were.
diff --git a/sys/dev/ixgbe/ixgbe_api.c b/sys/dev/ixgbe/ixgbe_api.c
index 0f4d973..894d0b2 100644
--- a/sys/dev/ixgbe/ixgbe_api.c
+++ b/sys/dev/ixgbe/ixgbe_api.c
@@ -879,7 +879,7 @@ s32 ixgbe_update_eeprom_checksum(struct ixgbe_hw *hw)
* @vmdq: VMDq pool to assign
*
* Puts an ethernet address into a receive address register, or
- * finds the rar that it is aleady in; adds to the pool list
+ * finds the rar that it is already in; adds to the pool list
**/
s32 ixgbe_insert_mac_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
{
diff --git a/sys/dev/ixgbe/ixgbe_common.c b/sys/dev/ixgbe/ixgbe_common.c
index c302071..cad2a85 100644
--- a/sys/dev/ixgbe/ixgbe_common.c
+++ b/sys/dev/ixgbe/ixgbe_common.c
@@ -3610,7 +3610,7 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
* @vmdq: VMDq pool to assign
*
* Puts an ethernet address into a receive address register, or
- * finds the rar that it is aleady in; adds to the pool list
+ * finds the rar that it is already in; adds to the pool list
**/
s32 ixgbe_insert_mac_addr_generic(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
{
diff --git a/sys/dev/ixgbe/ixgbe_mbx.c b/sys/dev/ixgbe/ixgbe_mbx.c
index d8ba55a..3e9b78a 100644
--- a/sys/dev/ixgbe/ixgbe_mbx.c
+++ b/sys/dev/ixgbe/ixgbe_mbx.c
@@ -42,7 +42,7 @@
* @size: Length of buffer
* @mbx_id: id of mailbox to read
*
- * returns SUCCESS if it successfuly read message from buffer
+ * returns SUCCESS if it successfully read message from buffer
**/
s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
{
@@ -462,7 +462,7 @@ out_no_write:
* @size: Length of buffer
* @mbx_id: id of mailbox to read
*
- * returns SUCCESS if it successfuly read message from buffer
+ * returns SUCCESS if it successfully read message from buffer
**/
static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
u16 mbx_id)
diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h
index da03f79..123c9d5 100644
--- a/sys/dev/ixgbe/ixgbe_type.h
+++ b/sys/dev/ixgbe/ixgbe_type.h
@@ -47,7 +47,7 @@
*
* - IXGBE_ERROR_POLLING
* This category is for errors related to polling/timeout issues and should be
- * used in any case where the timeout occured, or a failure to obtain a lock, or
+ * used in any case where the timeout occurred, or a failure to obtain a lock, or
* failure to receive data within the time limit.
*
* - IXGBE_ERROR_CAUTION
@@ -2078,7 +2078,7 @@ enum {
#define IXGBE_MACC_FS 0x00040000
#define IXGBE_MAC_RX2TX_LPBK 0x00000002
-/* Veto Bit definiton */
+/* Veto Bit definition */
#define IXGBE_MMNGC_MNG_VETO 0x00000001
/* LINKS Bit Masks */
diff --git a/sys/dev/lmc/if_lmc.h b/sys/dev/lmc/if_lmc.h
index 0121375..357fd88 100644
--- a/sys/dev/lmc/if_lmc.h
+++ b/sys/dev/lmc/if_lmc.h
@@ -1092,7 +1092,7 @@ struct softc
#endif
struct callout callout; /* watchdog needs this */
- struct device *dev; /* base device pointer */
+ device_t dev; /* base device pointer */
bus_space_tag_t csr_tag; /* bus_space needs this */
bus_space_handle_t csr_handle;/* bus_space_needs this */
void *irq_cookie; /* bus_teardown_intr needs this */
diff --git a/sys/dev/mpr/mpi/mpi2.h b/sys/dev/mpr/mpi/mpi2.h
index 42fdec2..7084a85 100644
--- a/sys/dev/mpr/mpi/mpi2.h
+++ b/sys/dev/mpr/mpi/mpi2.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,8 @@
/*
* Copyright (c) 2000-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2.h
@@ -43,7 +44,7 @@
* scatter/gather formats.
* Creation Date: June 21, 2006
*
- * mpi2.h Version: 02.00.33
+ * mpi2.h Version: 02.00.42
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@@ -125,6 +126,22 @@
* 04-17-13 02.00.31 Bumped MPI2_HEADER_VERSION_UNIT.
* 08-19-13 02.00.32 Bumped MPI2_HEADER_VERSION_UNIT.
* 12-05-13 02.00.33 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 01-08-14 02.00.34 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 06-13-14 02.00.35 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-18-14 02.00.36 Updated copyright information.
+ * Bumped MPI2_HEADER_VERSION_UNIT.
+ * 03-16-15 02.00.37 Updated for MPI v2.6.
+ * Bumped MPI2_HEADER_VERSION_UNIT.
+ * Added Scratchpad registers to
+ * MPI2_SYSTEM_INTERFACE_REGS.
+ * Added MPI2_DIAG_SBR_RELOAD.
+ * Added MPI2_IOCSTATUS_INSUFFICIENT_POWER.
+ * 03-19-15 02.00.38 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 05-25-15 02.00.39 Bumped MPI2_HEADER_VERSION_UNIT
+ * 08-25-15 02.00.40 Bumped MPI2_HEADER_VERSION_UNIT.
+ * Added V7 HostDiagnostic register defines
+ * 12-15-15 02.00.41 Bumped MPI_HEADER_VERSION_UNIT
+ * 01-01-16 02.00.42 Bumped MPI_HEADER_VERSION_UNIT
* --------------------------------------------------------------------------
*/
@@ -160,8 +177,15 @@
#define MPI2_VERSION_02_05 (0x0205)
+/* minor version for MPI v2.6 compatible products */
+#define MPI26_VERSION_MINOR (0x06)
+#define MPI26_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \
+ MPI26_VERSION_MINOR)
+#define MPI2_VERSION_02_06 (0x0206)
+
+
/* Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT (0x21)
+#define MPI2_HEADER_VERSION_UNIT (0x2A)
#define MPI2_HEADER_VERSION_DEV (0x00)
#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
@@ -217,7 +241,8 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
U32 HCBSize; /* 0x74 */
U32 HCBAddressLow; /* 0x78 */
U32 HCBAddressHigh; /* 0x7C */
- U32 Reserved6[16]; /* 0x80 */
+ U32 Reserved6[12]; /* 0x80 */
+ U32 Scratchpad[4]; /* 0xB0 */
U32 RequestDescriptorPostLow; /* 0xC0 */
U32 RequestDescriptorPostHigh; /* 0xC4 */
U32 Reserved7[14]; /* 0xC8 */
@@ -261,10 +286,17 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
*/
#define MPI2_HOST_DIAGNOSTIC_OFFSET (0x00000008)
+#define MPI2_DIAG_SBR_RELOAD (0x00002000)
+
#define MPI2_DIAG_BOOT_DEVICE_SELECT_MASK (0x00001800)
#define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT (0x00000000)
#define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW (0x00000800)
+/* Defines for V7A/V7R HostDiagnostic Register */
+#define MPI26_DIAG_BOOT_DEVICE_SELECT_FLASH64 (0x00000000)
+#define MPI26_DIAG_BOOT_DEVICE_SELECT_HCDW64 (0x00000800)
+#define MPI26_DIAG_BOOT_DEVICE_SELECT_FLASH32 (0x00001000)
+#define MPI26_DIAG_BOOT_DEVICE_SELECT_HCDW32 (0x00001800)
#define MPI2_DIAG_CLEAR_FLASH_BAD_SIG (0x00000400)
#define MPI2_DIAG_FORCE_HCB_ON_RESET (0x00000200)
#define MPI2_DIAG_HCB_MODE (0x00000100)
@@ -335,7 +367,15 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
#define MPI2_HCB_ADDRESS_HIGH_OFFSET (0x0000007C)
/*
- * Offsets for the Request Queue
+ * Offsets for the Scratchpad registers
+ */
+#define MPI26_SCRATCHPAD0_OFFSET (0x000000B0)
+#define MPI26_SCRATCHPAD1_OFFSET (0x000000B4)
+#define MPI26_SCRATCHPAD2_OFFSET (0x000000B8)
+#define MPI26_SCRATCHPAD3_OFFSET (0x000000BC)
+
+/*
+ * Offsets for the Request Descriptor Post Queue
*/
#define MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET (0x000000C0)
#define MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET (0x000000C4)
@@ -367,7 +407,8 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR
Mpi2DefaultRequestDescriptor_t, MPI2_POINTER pMpi2DefaultRequestDescriptor_t;
/* defines for the RequestFlags field */
-#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK (0x0E)
+#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK (0x1E)
+#define MPI2_REQ_DESCRIPT_FLAGS_TYPE_RSHIFT (1) /* use carefully; values below are pre-shifted left */
#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO (0x00)
#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET (0x02)
#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x06)
@@ -455,6 +496,10 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION
Mpi2RequestDescriptorUnion_t, MPI2_POINTER pMpi2RequestDescriptorUnion_t;
+
+/* for the RequestFlags field, use the same defines as MPI2_DEFAULT_REQUEST_DESCRIPTOR */
+
+
/* Reply Descriptors */
/* Default Reply Descriptor */
@@ -603,7 +648,8 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION
#define MPI2_FUNCTION_TOOLBOX (0x17) /* Toolbox */
#define MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR (0x18) /* SCSI Enclosure Processor */
#define MPI2_FUNCTION_SMP_PASSTHROUGH (0x1A) /* SMP Passthrough */
-#define MPI2_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B) /* SAS IO Unit Control */
+#define MPI2_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B) /* SAS IO Unit Control */ /* for MPI v2.5 and earlier */
+#define MPI2_FUNCTION_IO_UNIT_CONTROL (0x1B) /* IO Unit Control */ /* for MPI v2.6 and later */
#define MPI2_FUNCTION_SATA_PASSTHROUGH (0x1C) /* SATA Passthrough */
#define MPI2_FUNCTION_DIAG_BUFFER_POST (0x1D) /* Diagnostic Buffer Post */
#define MPI2_FUNCTION_DIAG_RELEASE (0x1E) /* Diagnostic Release */
@@ -646,6 +692,7 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION
#define MPI2_IOCSTATUS_INVALID_FIELD (0x0007)
#define MPI2_IOCSTATUS_INVALID_STATE (0x0008)
#define MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED (0x0009)
+#define MPI2_IOCSTATUS_INSUFFICIENT_POWER (0x000A) /* MPI v2.6 and later */
/****************************************************************************
* Config IOCStatus values
@@ -1123,7 +1170,7 @@ typedef union _MPI2_IEEE_SGE_CHAIN_UNION
} MPI2_IEEE_SGE_CHAIN_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_CHAIN_UNION,
Mpi2IeeeSgeChainUnion_t, MPI2_POINTER pMpi2IeeeSgeChainUnion_t;
-/* MPI25_IEEE_SGE_CHAIN64 is for MPI v2.5 products only */
+/* MPI25_IEEE_SGE_CHAIN64 is for MPI v2.5 and later */
typedef struct _MPI25_IEEE_SGE_CHAIN64
{
U64 Address;
@@ -1181,16 +1228,23 @@ typedef union _MPI25_SGE_IO_UNION
#define MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT (0x00)
#define MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT (0x80)
+/* Next Segment Format */
+
+#define MPI26_IEEE_SGE_FLAGS_NSF_MASK (0x1C)
+#define MPI26_IEEE_SGE_FLAGS_NSF_MPI_IEEE (0x00)
+
/* Data Location Address Space */
#define MPI2_IEEE_SGE_FLAGS_ADDR_MASK (0x03)
-#define MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR (0x00) /* for MPI v2.0, use in IEEE Simple Element only; for MPI v2.5, use in IEEE Simple or Chain element */
+#define MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR (0x00) /* for MPI v2.0, use in IEEE Simple Element only; for MPI v2.5 and later, use in IEEE Simple or Chain element */
#define MPI2_IEEE_SGE_FLAGS_IOCDDR_ADDR (0x01) /* use in IEEE Simple Element only */
#define MPI2_IEEE_SGE_FLAGS_IOCPLB_ADDR (0x02)
#define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03) /* for MPI v2.0, use in IEEE Simple Element only; for MPI v2.5, use in IEEE Simple or Chain element */
#define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR (0x03) /* use in MPI v2.0 IEEE Chain Element only */
#define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR (MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR) /* typo in name */
+#define MPI26_IEEE_SGE_FLAGS_IOCCTL_ADDR (0x02) /* for MPI v2.6 only */
+
/****************************************************************************
* IEEE SGE operation Macros
****************************************************************************/
@@ -1246,8 +1300,9 @@ typedef union _MPI2_SGE_IO_UNION
#define MPI2_SGLFLAGS_ADDRESS_SPACE_MASK (0x0C)
#define MPI2_SGLFLAGS_SYSTEM_ADDRESS_SPACE (0x00)
#define MPI2_SGLFLAGS_IOCDDR_ADDRESS_SPACE (0x04)
-#define MPI2_SGLFLAGS_IOCPLB_ADDRESS_SPACE (0x08)
-#define MPI2_SGLFLAGS_IOCPLBNTA_ADDRESS_SPACE (0x0C)
+#define MPI2_SGLFLAGS_IOCPLB_ADDRESS_SPACE (0x08) /* only for MPI v2.5 and earlier */
+#define MPI26_SGLFLAGS_IOCPLB_ADDRESS_SPACE (0x08) /* only for MPI v2.6 */
+#define MPI2_SGLFLAGS_IOCPLBNTA_ADDRESS_SPACE (0x0C) /* only for MPI v2.5 and earlier */
/* values for SGL Type subfield */
#define MPI2_SGLFLAGS_SGL_TYPE_MASK (0x03)
#define MPI2_SGLFLAGS_SGL_TYPE_MPI (0x00)
diff --git a/sys/dev/mpr/mpi/mpi2_cnfg.h b/sys/dev/mpr/mpi/mpi2_cnfg.h
index 3b0eb63..fb968b6 100644
--- a/sys/dev/mpr/mpi/mpi2_cnfg.h
+++ b/sys/dev/mpr/mpi/mpi2_cnfg.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,14 +34,15 @@
/*
* Copyright (c) 2000-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2_cnfg.h
* Title: MPI Configuration messages and pages
* Creation Date: November 10, 2006
*
- * mpi2_cnfg.h Version: 02.00.27
+ * mpi2_cnfg.h Version: 02.00.35
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@@ -210,6 +211,21 @@
* MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0.
* Added MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID for
* MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0.
+ * 01-08-14 02.00.28 Added more defines for the BiosOptions field of
+ * MPI2_CONFIG_PAGE_BIOS_1.
+ * 06-13-14 02.00.29 Added SSUTimeout field to MPI2_CONFIG_PAGE_BIOS_1, and
+ * more defines for the BiosOptions field.
+ * 11-18-14 02.00.30 Updated copyright information.
+ * Added MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG.
+ * Added AdapterOrderAux fields to BIOS Page 3.
+ * 03-16-15 02.00.31 Updated for MPI v2.6.
+ * Added BoardPowerRequirement, PCISlotPowerAllocation, and
+ * Flags field to IO Unit Page 7.
+ * Added IO Unit Page 11.
+ * Added new SAS Phy Event codes
+ * 05-25-15 02.00.33 Added more defines for the BiosOptions field of
+ * MPI2_CONFIG_PAGE_BIOS_1.
+ * 12-18-15 02.00.35 Added SATADeviceWaitTime to SAS IO Unit Page 4.
* --------------------------------------------------------------------------
*/
@@ -387,7 +403,6 @@ typedef union _MPI2_CONFIG_EXT_PAGE_HEADER_UNION
#define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK (0x000000FF)
-
/****************************************************************************
* Configuration messages
****************************************************************************/
@@ -491,8 +506,17 @@ typedef struct _MPI2_CONFIG_REPLY
#define MPI25_MFGPAGE_DEVID_SAS3108_5 (0x0094)
#define MPI25_MFGPAGE_DEVID_SAS3108_6 (0x0095)
-
-
+/* MPI v2.6 SAS Products */
+#define MPI26_MFGPAGE_DEVID_SAS3216 (0x00C9)
+#define MPI26_MFGPAGE_DEVID_SAS3224 (0x00C4)
+#define MPI26_MFGPAGE_DEVID_SAS3316_1 (0x00C5)
+#define MPI26_MFGPAGE_DEVID_SAS3316_2 (0x00C6)
+#define MPI26_MFGPAGE_DEVID_SAS3316_3 (0x00C7)
+#define MPI26_MFGPAGE_DEVID_SAS3316_4 (0x00C8)
+#define MPI26_MFGPAGE_DEVID_SAS3324_1 (0x00C0)
+#define MPI26_MFGPAGE_DEVID_SAS3324_2 (0x00C1)
+#define MPI26_MFGPAGE_DEVID_SAS3324_3 (0x00C2)
+#define MPI26_MFGPAGE_DEVID_SAS3324_4 (0x00C3)
/* Manufacturing Page 0 */
@@ -962,14 +986,16 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7
U16 BoardTemperature; /* 0x14 */
U8 BoardTemperatureUnits; /* 0x16 */
U8 Reserved3; /* 0x17 */
- U32 Reserved4; /* 0x18 */
- U32 Reserved5; /* 0x1C */
- U32 Reserved6; /* 0x20 */
- U32 Reserved7; /* 0x24 */
+ U32 BoardPowerRequirement; /* 0x18 */ /* reserved prior to MPI v2.6 */
+ U32 PCISlotPowerAllocation; /* 0x1C */ /* reserved prior to MPI v2.6 */
+ U8 Flags; /* 0x20 */ /* reserved prior to MPI v2.6 */
+ U8 Reserved6; /* 0x21 */
+ U16 Reserved7; /* 0x22 */
+ U32 Reserved8; /* 0x24 */
} MPI2_CONFIG_PAGE_IO_UNIT_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_7,
Mpi2IOUnitPage7_t, MPI2_POINTER pMpi2IOUnitPage7_t;
-#define MPI2_IOUNITPAGE7_PAGEVERSION (0x04)
+#define MPI2_IOUNITPAGE7_PAGEVERSION (0x05)
/* defines for IO Unit Page 7 CurrentPowerMode and PreviousPowerMode fields */
#define MPI25_IOUNITPAGE7_PM_INIT_MASK (0xC0)
@@ -1050,6 +1076,8 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7
#define MPI2_IOUNITPAGE7_BOARD_TEMP_FAHRENHEIT (0x01)
#define MPI2_IOUNITPAGE7_BOARD_TEMP_CELSIUS (0x02)
+/* defines for IO Unit Page 7 Flags field */
+#define MPI2_IOUNITPAGE7_FLAG_CABLE_POWER_EXC (0x01)
/* IO Unit Page 8 */
@@ -1168,6 +1196,61 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_10
#define MPI2_IOUNITPAGE10_PAGEVERSION (0x01)
+/* IO Unit Page 11 (for MPI v2.6 and later) */
+
+typedef struct _MPI26_IOUNIT11_SPINUP_GROUP
+{
+ U8 MaxTargetSpinup; /* 0x00 */
+ U8 SpinupDelay; /* 0x01 */
+ U8 SpinupFlags; /* 0x02 */
+ U8 Reserved1; /* 0x03 */
+} MPI26_IOUNIT11_SPINUP_GROUP, MPI2_POINTER PTR_MPI26_IOUNIT11_SPINUP_GROUP,
+ Mpi26IOUnit11SpinupGroup_t, MPI2_POINTER pMpi26IOUnit11SpinupGroup_t;
+
+/* defines for IO Unit Page 11 SpinupFlags */
+#define MPI26_IOUNITPAGE11_SPINUP_DISABLE_FLAG (0x01)
+
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * four and check the value returned for NumPhys at runtime.
+ */
+#ifndef MPI26_IOUNITPAGE11_PHY_MAX
+#define MPI26_IOUNITPAGE11_PHY_MAX (4)
+#endif
+
+typedef struct _MPI26_CONFIG_PAGE_IO_UNIT_11
+{
+ MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
+ U32 Reserved1; /* 0x04 */
+ MPI26_IOUNIT11_SPINUP_GROUP SpinupGroupParameters[4]; /* 0x08 */
+ U32 Reserved2; /* 0x18 */
+ U32 Reserved3; /* 0x1C */
+ U32 Reserved4; /* 0x20 */
+ U8 BootDeviceWaitTime; /* 0x24 */
+ U8 Reserved5; /* 0x25 */
+ U16 Reserved6; /* 0x26 */
+ U8 NumPhys; /* 0x28 */
+ U8 PEInitialSpinupDelay; /* 0x29 */
+ U8 PEReplyDelay; /* 0x2A */
+ U8 Flags; /* 0x2B */
+ U8 PHY[MPI26_IOUNITPAGE11_PHY_MAX];/* 0x2C */
+} MPI26_CONFIG_PAGE_IO_UNIT_11,
+ MPI2_POINTER PTR_MPI26_CONFIG_PAGE_IO_UNIT_11,
+ Mpi26IOUnitPage11_t, MPI2_POINTER pMpi26IOUnitPage11_t;
+
+#define MPI26_IOUNITPAGE11_PAGEVERSION (0x00)
+
+/* defines for Flags field */
+#define MPI26_IOUNITPAGE11_FLAGS_AUTO_PORTENABLE (0x01)
+
+/* defines for PHY field */
+#define MPI26_IOUNITPAGE11_PHY_SPINUP_GROUP_MASK (0x03)
+
+
+
+
+
/****************************************************************************
* IOC Config Pages
@@ -1331,7 +1414,9 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_1
MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
U32 BiosOptions; /* 0x04 */
U32 IOCSettings; /* 0x08 */
- U32 Reserved1; /* 0x0C */
+ U8 SSUTimeout; /* 0x0C */
+ U8 Reserved1; /* 0x0D */
+ U16 Reserved2; /* 0x0E */
U32 DeviceSettings; /* 0x10 */
U16 NumberOfDevices; /* 0x14 */
U16 UEFIVersion; /* 0x16 */
@@ -1342,18 +1427,36 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_1
} MPI2_CONFIG_PAGE_BIOS_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_1,
Mpi2BiosPage1_t, MPI2_POINTER pMpi2BiosPage1_t;
-#define MPI2_BIOSPAGE1_PAGEVERSION (0x05)
+#define MPI2_BIOSPAGE1_PAGEVERSION (0x07)
/* values for BIOS Page 1 BiosOptions field */
-#define MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID (0x000000F0)
-#define MPI2_BIOSPAGE1_OPTIONS_LSI_OEM_ID (0x00000000)
+#define MPI2_BIOSPAGE1_OPTIONS_BOOT_LIST_ADD_ALT_BOOT_DEVICE (0x00008000)
+#define MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG (0x00004000)
+
+#define MPI2_BIOSPAGE1_OPTIONS_PNS_MASK (0x00003800)
+#define MPI2_BIOSPAGE1_OPTIONS_PNS_PBDHL (0x00000000)
+#define MPI2_BIOSPAGE1_OPTIONS_PNS_ENCSLOSURE (0x00000800)
+#define MPI2_BIOSPAGE1_OPTIONS_PNS_LWWID (0x00001000)
+#define MPI2_BIOSPAGE1_OPTIONS_PNS_PSENS (0x00001800)
+#define MPI2_BIOSPAGE1_OPTIONS_PNS_ESPHY (0x00002000)
-#define MPI2_BIOSPAGE1_OPTIONS_MASK_UEFI_HII_REGISTRATION (0x00000006)
-#define MPI2_BIOSPAGE1_OPTIONS_ENABLE_UEFI_HII (0x00000000)
-#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_UEFI_HII (0x00000002)
-#define MPI2_BIOSPAGE1_OPTIONS_VERSION_CHECK_UEFI_HII (0x00000004)
+#define MPI2_BIOSPAGE1_OPTIONS_X86_DISABLE_BIOS (0x00000400)
-#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001)
+#define MPI2_BIOSPAGE1_OPTIONS_MASK_REGISTRATION_UEFI_BSD (0x00000300)
+#define MPI2_BIOSPAGE1_OPTIONS_USE_BIT0_REGISTRATION_UEFI_BSD (0x00000000)
+#define MPI2_BIOSPAGE1_OPTIONS_FULL_REGISTRATION_UEFI_BSD (0x00000100)
+#define MPI2_BIOSPAGE1_OPTIONS_ADAPTER_REGISTRATION_UEFI_BSD (0x00000200)
+#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_REGISTRATION_UEFI_BSD (0x00000300)
+
+#define MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID (0x000000F0)
+#define MPI2_BIOSPAGE1_OPTIONS_LSI_OEM_ID (0x00000000)
+
+#define MPI2_BIOSPAGE1_OPTIONS_MASK_UEFI_HII_REGISTRATION (0x00000006)
+#define MPI2_BIOSPAGE1_OPTIONS_ENABLE_UEFI_HII (0x00000000)
+#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_UEFI_HII (0x00000002)
+#define MPI2_BIOSPAGE1_OPTIONS_VERSION_CHECK_UEFI_HII (0x00000004)
+
+#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001)
/* values for BIOS Page 1 IOCSettings field */
#define MPI2_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000)
@@ -1477,6 +1580,8 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_2
/* BIOS Page 3 */
+#define MPI2_BIOSPAGE3_NUM_ADAPTER (4)
+
typedef struct _MPI2_ADAPTER_INFO
{
U8 PciBusNumber; /* 0x00 */
@@ -1488,17 +1593,26 @@ typedef struct _MPI2_ADAPTER_INFO
#define MPI2_ADAPTER_INFO_FLAGS_EMBEDDED (0x0001)
#define MPI2_ADAPTER_INFO_FLAGS_INIT_STATUS (0x0002)
+typedef struct _MPI2_ADAPTER_ORDER_AUX
+{
+ U64 WWID; /* 0x00 */
+ U32 Reserved1; /* 0x08 */
+ U32 Reserved2; /* 0x0C */
+} MPI2_ADAPTER_ORDER_AUX, MPI2_POINTER PTR_MPI2_ADAPTER_ORDER_AUX,
+ Mpi2AdapterOrderAux_t, MPI2_POINTER pMpi2AdapterOrderAux_t;
+
typedef struct _MPI2_CONFIG_PAGE_BIOS_3
{
MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
U32 GlobalFlags; /* 0x04 */
U32 BiosVersion; /* 0x08 */
- MPI2_ADAPTER_INFO AdapterOrder[4]; /* 0x0C */
+ MPI2_ADAPTER_INFO AdapterOrder[MPI2_BIOSPAGE3_NUM_ADAPTER]; /* 0x0C */
U32 Reserved1; /* 0x1C */
+ MPI2_ADAPTER_ORDER_AUX AdapterOrderAux[MPI2_BIOSPAGE3_NUM_ADAPTER]; /* 0x20 */ /* MPI v2.5 and newer */
} MPI2_CONFIG_PAGE_BIOS_3, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_BIOS_3,
Mpi2BiosPage3_t, MPI2_POINTER pMpi2BiosPage3_t;
-#define MPI2_BIOSPAGE3_PAGEVERSION (0x00)
+#define MPI2_BIOSPAGE3_PAGEVERSION (0x01)
/* values for BIOS Page 3 GlobalFlags */
#define MPI2_BIOSPAGE3_FLAGS_PAUSE_ON_ERROR (0x00000002)
@@ -1990,6 +2104,8 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_0
#define MPI2_SASIOUNIT0_PORTFLAGS_AUTO_PORT_CONFIG (0x01)
/* values for SAS IO Unit Page 0 PhyFlags */
+#define MPI2_SASIOUNIT0_PHYFLAGS_INIT_PERSIST_CONNECT (0x40)
+#define MPI2_SASIOUNIT0_PHYFLAGS_TARG_PERSIST_CONNECT (0x20)
#define MPI2_SASIOUNIT0_PHYFLAGS_ZONING_ENABLED (0x10)
#define MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED (0x08)
@@ -2082,6 +2198,7 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1
#define MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) /* MPI v2.0 only. Obsolete in MPI v2.5 and later. */
/* values for SAS IO Unit Page 1 AdditionalControlFlags */
+#define MPI2_SASIOUNIT1_ACONTROL_DA_PERSIST_CONNECT (0x0100)
#define MPI2_SASIOUNIT1_ACONTROL_MULTI_PORT_DOMAIN_ILLEGAL (0x0080)
#define MPI2_SASIOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION (0x0040)
#define MPI2_SASIOUNIT1_ACONTROL_INVALID_TOPOLOGY_CORRECTION (0x0020)
@@ -2099,6 +2216,8 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1
#define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01)
/* values for SAS IO Unit Page 1 PhyFlags */
+#define MPI2_SASIOUNIT1_PHYFLAGS_INIT_PERSIST_CONNECT (0x40)
+#define MPI2_SASIOUNIT1_PHYFLAGS_TARG_PERSIST_CONNECT (0x20)
#define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE (0x10)
#define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE (0x08)
@@ -2117,7 +2236,7 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_1
/* see mpi2_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
-/* SAS IO Unit Page 4 */
+/* SAS IO Unit Page 4 (for MPI v2.5 and earlier) */
typedef struct _MPI2_SAS_IOUNIT4_SPINUP_GROUP
{
@@ -2148,7 +2267,7 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_4
U32 Reserved2; /* 0x1C */
U32 Reserved3; /* 0x20 */
U8 BootDeviceWaitTime; /* 0x24 */
- U8 Reserved4; /* 0x25 */
+ U8 SATADeviceWaitTime; /* 0x25 */
U16 Reserved5; /* 0x26 */
U8 NumPhys; /* 0x28 */
U8 PEInitialSpinupDelay; /* 0x29 */
@@ -2595,6 +2714,7 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0
#define MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020)
#define MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010)
#define MPI2_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008)
+#define MPI2_SAS_DEVICE0_FLAGS_PERSIST_CAPABLE (0x0004)
#define MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID (0x0002)
#define MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001)
@@ -2766,6 +2886,19 @@ typedef struct _MPI2_SASPHY3_PHY_EVENT_CONFIG
#define MPI2_SASPHY3_EVENT_CODE_MISALIGNED_MUX_PRIMITIVE (0xD1)
#define MPI2_SASPHY3_EVENT_CODE_RX_AIP (0xD2)
+/* Following codes are product specific and in MPI v2.6 and later */
+#define MPI2_SASPHY3_EVENT_CODE_LCARB_WAIT_TIME (0xD3)
+#define MPI2_SASPHY3_EVENT_CODE_RCVD_CONN_RESP_WAIT_TIME (0xD4)
+#define MPI2_SASPHY3_EVENT_CODE_LCCONN_TIME (0xD5)
+#define MPI2_SASPHY3_EVENT_CODE_SSP_TX_START_TRANSMIT (0xD6)
+#define MPI2_SASPHY3_EVENT_CODE_SATA_TX_START (0xD7)
+#define MPI2_SASPHY3_EVENT_CODE_SMP_TX_START_TRANSMT (0xD8)
+#define MPI2_SASPHY3_EVENT_CODE_TX_SMP_BREAK_CONN (0xD9)
+#define MPI2_SASPHY3_EVENT_CODE_SSP_RX_START_RECEIVE (0xDA)
+#define MPI2_SASPHY3_EVENT_CODE_SATA_RX_START_RECEIVE (0xDB)
+#define MPI2_SASPHY3_EVENT_CODE_SMP_RX_START_RECEIVE (0xDC)
+
+
/* values for the CounterType field */
#define MPI2_SASPHY3_COUNTER_TYPE_WRAPPING (0x00)
#define MPI2_SASPHY3_COUNTER_TYPE_SATURATING (0x01)
diff --git a/sys/dev/mpr/mpi/mpi2_hbd.h b/sys/dev/mpr/mpi/mpi2_hbd.h
index 520407b..4870071 100644
--- a/sys/dev/mpr/mpi/mpi2_hbd.h
+++ b/sys/dev/mpr/mpi/mpi2_hbd.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,14 +34,15 @@
/*
* Copyright (c) 2009-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2_hbd.h
* Title: MPI Host Based Discovery messages and structures
* Creation Date: October 21, 2009
*
- * mpi2_hbd.h Version: 02.00.02
+ * mpi2_hbd.h Version: 02.00.03
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@@ -57,6 +58,7 @@
* 08-11-10 02.00.01 Removed PortGroups, DmaGroup, and ControlGroup from
* HBD Action request, replaced by AdditionalInfo field.
* 11-18-11 02.00.02 Incorporating additions for MPI v2.5.
+ * 11-18-14 02.00.03 Updated copyright information.
* --------------------------------------------------------------------------
*/
diff --git a/sys/dev/mpr/mpi/mpi2_history.txt b/sys/dev/mpr/mpi/mpi2_history.txt
index e843237..64498a2 100644
--- a/sys/dev/mpr/mpi/mpi2_history.txt
+++ b/sys/dev/mpr/mpi/mpi2_history.txt
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,27 +37,28 @@
==============================
Copyright (c) 2000-2015 LSI Corporation.
- Copyright (c) 2013-2015 Avago Technologies
+ Copyright (c) 2013-2016 Avago Technologies
+ All rights reserved.
---------------------------------------
- Header Set Release Version: 02.00.33
- Header Set Release Date: 12-05-13
+ Header Set Release Version: 02.00.42
+ Header Set Release Date: 01-04-16
---------------------------------------
Filename Current version Prior version
---------- --------------- -------------
- mpi2.h 02.00.33 02.00.32
- mpi2_cnfg.h 02.00.27 02.00.26
- mpi2_init.h 02.00.15 02.00.15
- mpi2_ioc.h 02.00.24 02.00.23
- mpi2_raid.h 02.00.10 02.00.10
- mpi2_sas.h 02.00.08 02.00.08
- mpi2_targ.h 02.00.06 02.00.06
- mpi2_tool.h 02.00.11 02.00.11
- mpi2_type.h 02.00.00 02.00.00
- mpi2_ra.h 02.00.00 02.00.00
- mpi2_hbd.h 02.00.02 02.00.02
- mpi2_history.txt 02.00.33 02.00.32
+ mpi2.h 02.00.42 02.00.41
+ mpi2_cnfg.h 02.00.35 02.00.34
+ mpi2_init.h 02.00.20 02.00.19
+ mpi2_ioc.h 02.00.27 02.00.27
+ mpi2_raid.h 02.00.11 02.00.11
+ mpi2_sas.h 02.00.10 02.00.10
+ mpi2_targ.h 02.00.09 02.00.09
+ mpi2_tool.h 02.00.13 02.00.13
+ mpi2_type.h 02.00.01 02.00.01
+ mpi2_ra.h 02.00.01 02.00.01
+ mpi2_hbd.h 02.00.03 02.00.03
+ mpi2_history.txt 02.00.41 02.00.40
* Date Version Description
@@ -134,6 +135,22 @@ mpi2.h
* 04-17-13 02.00.31 Bumped MPI2_HEADER_VERSION_UNIT.
* 08-19-13 02.00.32 Bumped MPI2_HEADER_VERSION_UNIT.
* 12-05-13 02.00.33 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 01-08-14 02.00.34 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 06-13-14 02.00.35 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-18-14 02.00.36 Updated copyright information.
+ * Bumped MPI2_HEADER_VERSION_UNIT.
+ * 03-16-15 02.00.37 Updated for MPI v2.6.
+ * Bumped MPI2_HEADER_VERSION_UNIT.
+ * Added Scratchpad registers to
+ * MPI2_SYSTEM_INTERFACE_REGS.
+ * Added MPI2_DIAG_SBR_RELOAD.
+ * Added MPI2_IOCSTATUS_INSUFFICIENT_POWER.
+ * 03-19-15 02.00.38 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 05-25-15 02.00.39 Bumped MPI2_HEADER_VERSION_UNIT.
+ * 08-25-15 02.00.40 Bumped MPI2_HEADER_VERSION_UNIT.
+ * Added V7 HostDiagnostic register defines
+ * 12-15-15 02.00.41 Bumped MPI_HEADER_VERSION_UNIT
+ * 01-04-16 02.00.42 Bumped MPI_HEADER_VERSION_UNIT
* --------------------------------------------------------------------------
mpi2_cnfg.h
@@ -294,6 +311,21 @@ mpi2_cnfg.h
* MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0.
* Added MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID for
* MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0.
+ * 01-08-14 02.00.28 Added more defines for the BiosOptions field of
+ * MPI2_CONFIG_PAGE_BIOS_1.
+ * 06-13-14 02.00.29 Added SSUTimeout field to MPI2_CONFIG_PAGE_BIOS_1, and
+ * more defines for the BiosOptions field..
+ * 11-18-14 02.00.30 Updated copyright information.
+ * Added MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG.
+ * Added AdapterOrderAux fields to BIOS Page 3.
+ * 03-16-15 02.00.31 Updated for MPI v2.6.
+ * Added BoardPowerRequirement, PCISlotPowerAllocation, and
+ * Flags field to IO Unit Page 7.
+ * Added IO Unit Page 11.
+ * Added new SAS Phy Event codes
+ * 05-25-15 02.00.33 Added more defines for the BiosOptions field of
+ * MPI2_CONFIG_PAGE_BIOS_1.
+ * 12-18-15 02.00.35 Added SATADeviceWaitTime to SAS IO Unit Page 4.
* --------------------------------------------------------------------------
mpi2_init.h
@@ -305,7 +337,7 @@ mpi2_init.h
* 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t.
* 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO
* Control field Task Attribute flags.
- * Moved LUN field defines to mpi2.h because they are
+ * Moved LUN field defines to mpi2.h becasue they are
* common to many structures.
* 05-06-09 02.00.07 Changed task management type of Query Unit Attention to
* Query Asynchronous Event.
@@ -323,6 +355,16 @@ mpi2_init.h
* Priority to match SAM-4.
* Added EEDPErrorOffset to MPI2_SCSI_IO_REPLY.
* 07-10-12 02.00.14 Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION.
+ * 04-09-13 02.00.15 Added SCSIStatusQualifier field to MPI2_SCSI_IO_REPLY,
+ * replacing the Reserved4 field.
+ * 11-18-14 02.00.16 Updated copyright information.
+ * 03-16-15 02.00.17 Updated for MPI v2.6.
+ * Added MPI26_SCSIIO_IOFLAGS_ESCAPE_PASSTHROUGH.
+ * Added MPI2_SEP_REQ_SLOTSTATUS_DEV_OFF and
+ * MPI2_SEP_REPLY_SLOTSTATUS_DEV_OFF.
+ * 08-26-15 02.00.18 Added SCSITASKMGMT_MSGFLAGS for Target Reset.
+ * 12-18-15 02.00.19 Added EEDPObservedValue added to SCSI IO Reply message.
+ * 01-04-16 02.00.20 Modified EEDP reported values in SCSI IO Reply message.
* --------------------------------------------------------------------------
mpi2_ioc.h
@@ -441,6 +483,16 @@ mpi2_ioc.h
* Added MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY.
* Added Encrypted Hash Extended Image.
* 12-05-13 02.00.24 Added MPI25_HASH_IMAGE_TYPE_BIOS.
+ * 11-18-14 02.00.25 Updated copyright information.
+ * 03-16-15 02.00.26 Updated for MPI v2.6.
+ * Added MPI2_EVENT_ACTIVE_CABLE_EXCEPTION and
+ * MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT.
+ * Added MPI2_EVENT_PCIE_LINK_COUNTER and
+ * MPI26_EVENT_DATA_PCIE_LINK_COUNTER.
+ * Added MPI26_CTRL_OP_SHUTDOWN.
+ * Added MPI26_CTRL_OP_LINK_CLEAR_ERROR_LOG
+ * Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS
+ * 08-25-15 02.00.27 Added IC ARCH Class based signature defines.
* --------------------------------------------------------------------------
mpi2_raid.h
@@ -479,6 +531,9 @@ mpi2_sas.h
* Passthrough Request message.
* 08-19-13 02.00.08 Made MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL obsolete
* for anything newer than MPI v2.0.
+ * 11-18-14 02.00.09 Updated copyright information.
+ * 03-16-15 02.00.10 Updated for MPI v2.6.
+ * Added MPI2_SATA_PT_REQ_PT_FLAGS_FPDMA.
* --------------------------------------------------------------------------
mpi2_targ.h
@@ -496,6 +551,11 @@ mpi2_targ.h
* request message structure.
* Added AbortType MPI2_TARGET_MODE_ABORT_DEVHANDLE and
* MPI2_TARGET_MODE_ABORT_ALL_COMMANDS.
+ * 06-13-14 02.00.07 Added MinMSIxIndex and MaxMSIxIndex fields to
+ * MPI2_TARGET_CMD_BUF_POST_BASE_REQUEST.
+ * 11-18-14 02.00.08 Updated copyright information.
+ * 03-16-15 02.00.09 Updated for MPI v2.6.
+ * Added MPI26_TARGET_ASSIST_IOFLAGS_ESCAPE_PASSTHROUGH.
* --------------------------------------------------------------------------
mpi2_tool.h
@@ -519,14 +579,18 @@ mpi2_tool.h
* 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that
* it uses MPI Chain SGE as well as MPI Simple SGE.
* 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info.
+ * 01-08-14 02.00.12 Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC.
+ * 11-18-14 02.00.13 Updated copyright information.
* --------------------------------------------------------------------------
mpi2_type.h
* 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
+ * 11-18-14 02.00.01 Updated copyright information.
* --------------------------------------------------------------------------
mpi2_ra.h
* 05-06-09 02.00.00 Initial version.
+ * 11-18-14 02.00.01 Updated copyright information.
* --------------------------------------------------------------------------
mpi2_hbd.h
@@ -534,24 +598,53 @@ mpi2_hbd.h
* 08-11-10 02.00.01 Removed PortGroups, DmaGroup, and ControlGroup from
* HBD Action request, replaced by AdditionalInfo field.
* 11-18-11 02.00.02 Incorporating additions for MPI v2.5.
+ * 11-18-14 02.00.03 Updated copyright information.
* --------------------------------------------------------------------------
mpi2_history.txt Parts list history
-Filename 02.00.33 02.00.32 02.00.31 02.00.30
----------- -------- -------- -------- --------
-mpi2.h 02.00.33 02.00.32 02.00.31 02.00.30
-mpi2_cnfg.h 02.00.27 02.00.26 02.00.25 02.00.25
-mpi2_init.h 02.00.15 02.00.15 02.00.15 02.00.15
-mpi2_ioc.h 02.00.24 02.00.23 02.00.22 02.00.22
-mpi2_raid.h 02.00.10 02.00.10 02.00.10 02.00.09
-mpi2_sas.h 02.00.08 02.00.08 02.00.07 02.00.07
-mpi2_targ.h 02.00.06 02.00.06 02.00.06 02.00.06
-mpi2_tool.h 02.00.11 02.00.11 02.00.10 02.00.10
-mpi2_type.h 02.00.00 02.00.00 02.00.00 02.00.00
-mpi2_ra.h 02.00.00 02.00.00 02.00.00 02.00.00
-mpi2_hbd.h 02.00.02 02.00.02 02.00.02 02.00.02
+Filename 02.00.42
+---------- --------
+mpi2.h 02.00.42
+mpi2_cnfg.h 02.00.35
+mpi2_init.h 02.00.20
+mpi2_ioc.h 02.00.27
+mpi2_raid.h 02.00.11
+mpi2_sas.h 02.00.10
+mpi2_targ.h 02.00.09
+mpi2_tool.h 02.00.13
+mpi2_type.h 02.00.01
+mpi2_ra.h 02.00.01
+mpi2_hbd.h 02.00.03
+
+Filename 02.00.41 02.00.40 02.00.39 02.00.38 02.00.37 02.00.36
+---------- -------- -------- -------- -------- -------- --------
+mpi2.h 02.00.41 02.00.40 02.00.39 02.00.38 02.00.37 02.00.36
+mpi2_cnfg.h 02.00.35 02.00.34 02.00.33 02.00.32 02.00.31 02.00.30
+mpi2_init.h 02.00.19 02.00.18 02.00.17 02.00.17 02.00.17 02.00.16
+mpi2_ioc.h 02.00.27 02.00.27 02.00.26 02.00.26 02.00.26 02.00.25
+mpi2_raid.h 02.00.11 02.00.11 02.00.11 02.00.11 02.00.11 02.00.11
+mpi2_sas.h 02.00.10 02.00.10 02.00.10 02.00.10 02.00.10 02.00.09
+mpi2_targ.h 02.00.09 02.00.09 02.00.09 02.00.09 02.00.09 02.00.08
+mpi2_tool.h 02.00.13 02.00.13 02.00.13 02.00.13 02.00.13 02.00.13
+mpi2_type.h 02.00.01 02.00.01 02.00.01 02.00.01 02.00.01 02.00.01
+mpi2_ra.h 02.00.01 02.00.01 02.00.01 02.00.01 02.00.01 02.00.01
+mpi2_hbd.h 02.00.03 02.00.03 02.00.03 02.00.03 02.00.03 02.00.03
+
+Filename 02.00.35 02.00.34 02.00.33 02.00.32 02.00.31 02.00.30
+---------- -------- -------- -------- -------- -------- --------
+mpi2.h 02.00.35 02.00.34 02.00.33 02.00.32 02.00.31 02.00.30
+mpi2_cnfg.h 02.00.29 02.00.28 02.00.27 02.00.26 02.00.25 02.00.25
+mpi2_init.h 02.00.15 02.00.15 02.00.15 02.00.15 02.00.15 02.00.15
+mpi2_ioc.h 02.00.24 02.00.24 02.00.24 02.00.23 02.00.22 02.00.22
+mpi2_raid.h 02.00.10 02.00.10 02.00.10 02.00.10 02.00.10 02.00.09
+mpi2_sas.h 02.00.08 02.00.08 02.00.08 02.00.08 02.00.07 02.00.07
+mpi2_targ.h 02.00.07 02.00.06 02.00.06 02.00.06 02.00.06 02.00.06
+mpi2_tool.h 02.00.12 02.00.12 02.00.11 02.00.11 02.00.10 02.00.10
+mpi2_type.h 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00
+mpi2_ra.h 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00
+mpi2_hbd.h 02.00.02 02.00.02 02.00.02 02.00.02 02.00.02 02.00.02
Filename 02.00.29 02.00.28 02.00.27 02.00.26 02.00.25 02.00.24
---------- -------- -------- -------- -------- -------- --------
diff --git a/sys/dev/mpr/mpi/mpi2_init.h b/sys/dev/mpr/mpi/mpi2_init.h
index 5b73643..12b2689 100644
--- a/sys/dev/mpr/mpi/mpi2_init.h
+++ b/sys/dev/mpr/mpi/mpi2_init.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,14 +34,15 @@
/*
* Copyright (c) 2000-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2_init.h
* Title: MPI SCSI initiator mode messages and structures
* Creation Date: June 23, 2006
*
- * mpi2_init.h Version: 02.00.15
+ * mpi2_init.h Version: 02.00.20
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@@ -61,7 +62,7 @@
* 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t.
* 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO
* Control field Task Attribute flags.
- * Moved LUN field defines to mpi2.h because they are
+ * Moved LUN field defines to mpi2.h becasue they are
* common to many structures.
* 05-06-09 02.00.07 Changed task management type of Query Unit Attention to
* Query Asynchronous Event.
@@ -81,6 +82,14 @@
* 07-10-12 02.00.14 Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION.
* 04-09-13 02.00.15 Added SCSIStatusQualifier field to MPI2_SCSI_IO_REPLY,
* replacing the Reserved4 field.
+ * 11-18-14 02.00.16 Updated copyright information.
+ * 03-16-15 02.00.17 Updated for MPI v2.6.
+ * Added MPI26_SCSIIO_IOFLAGS_ESCAPE_PASSTHROUGH.
+ * Added MPI2_SEP_REQ_SLOTSTATUS_DEV_OFF and
+ * MPI2_SEP_REPLY_SLOTSTATUS_DEV_OFF.
+ * 08-26-15 02.00.18 Added SCSITASKMGMT_MSGFLAGS for Target Reset.
+ * 12-18-15 02.00.19 Added EEDPObservedValue added to SCSI IO Reply message.
+ * 01-04-16 02.00.20 Modified EEDP reported values in SCSI IO Reply message.
* --------------------------------------------------------------------------
*/
@@ -164,8 +173,9 @@ typedef struct _MPI2_SCSI_IO_REQUEST
#define MPI2_SCSIIO_MSGFLAGS_MASK_SENSE_ADDR (0x0C)
#define MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR (0x00)
#define MPI2_SCSIIO_MSGFLAGS_IOCDDR_SENSE_ADDR (0x04)
-#define MPI2_SCSIIO_MSGFLAGS_IOCPLB_SENSE_ADDR (0x08)
-#define MPI2_SCSIIO_MSGFLAGS_IOCPLBNTA_SENSE_ADDR (0x0C)
+#define MPI2_SCSIIO_MSGFLAGS_IOCPLB_SENSE_ADDR (0x08) /* for MPI v2.5 and earlier only */
+#define MPI2_SCSIIO_MSGFLAGS_IOCPLBNTA_SENSE_ADDR (0x0C) /* for MPI v2.5 and earlier only */
+#define MPI26_SCSIIO_MSGFLAGS_IOCCTL_SENSE_ADDR (0x08) /* for MPI v2.6 only */
/* SCSI IO SGLFlags bits */
@@ -268,7 +278,7 @@ typedef union _MPI25_SCSI_IO_CDB_UNION
} MPI25_SCSI_IO_CDB_UNION, MPI2_POINTER PTR_MPI25_SCSI_IO_CDB_UNION,
Mpi25ScsiIoCdb_t, MPI2_POINTER pMpi25ScsiIoCdb_t;
-/* MPI v2.5 SCSI IO Request Message */
+/* MPI v2.5/2.6 SCSI IO Request Message */
typedef struct _MPI25_SCSI_IO_REQUEST
{
U16 DevHandle; /* 0x00 */
@@ -347,8 +357,10 @@ typedef struct _MPI25_SCSI_IO_REQUEST
#define MPI25_SCSIIO_IOFLAGS_NORMAL_PATH (0x0000)
#define MPI25_SCSIIO_IOFLAGS_FAST_PATH (0x4000)
+#define MPI26_SCSIIO_IOFLAGS_ESCAPE_PASSTHROUGH (0x2000) /* MPI v2.6 and later */
#define MPI25_SCSIIO_IOFLAGS_LARGE_CDB (0x1000)
#define MPI25_SCSIIO_IOFLAGS_BIDIRECTIONAL (0x0800)
+#define MPI26_SCSIIO_IOFLAGS_PORT_REQUEST (0x0400) /* MPI v2.6 and later; IOC use only */
#define MPI25_SCSIIO_IOFLAGS_CDBLENGTH_MASK (0x01FF)
/* MPI v2.5 defines for the EEDPFlags bits */
@@ -394,11 +406,19 @@ typedef struct _MPI2_SCSI_IO_REPLY
U16 TaskTag; /* 0x20 */
U16 SCSIStatusQualifier; /* 0x22 */
U32 BidirectionalTransferCount; /* 0x24 */
- U32 EEDPErrorOffset; /* 0x28 */ /* MPI 2.5 only; Reserved in MPI 2.0 */
- U32 Reserved6; /* 0x2C */
+ U32 EEDPErrorOffset; /* 0x28 */ /* MPI 2.5+ only; Reserved in MPI 2.0 */
+ U16 EEDPObservedAppTag; /* 0x2C */ /* MPI 2.5+ only; Reserved in MPI 2.0 */
+ U16 EEDPObservedGuard; /* 0x2E */ /* MPI 2.5+ only; Reserved in MPI 2.0 */
+ U32 EEDPObservedRefTag; /* 0x30 */ /* MPI 2.5+ only; Reserved in MPI 2.0 */
} MPI2_SCSI_IO_REPLY, MPI2_POINTER PTR_MPI2_SCSI_IO_REPLY,
Mpi2SCSIIOReply_t, MPI2_POINTER pMpi2SCSIIOReply_t;
+/* SCSI IO Reply MsgFlags bits */
+#define MPI26_SCSIIO_REPLY_MSGFLAGS_REFTAG_OBSERVED_VALID (0x01)
+#define MPI26_SCSIIO_REPLY_MSGFLAGS_GUARD_OBSERVED_VALID (0x02)
+#define MPI26_SCSIIO_REPLY_MSGFLAGS_APPTAG_OBSERVED_VALID (0x04)
+
+
/* SCSI IO Reply SCSIStatus values (SAM-4 status codes) */
#define MPI2_SCSI_STATUS_GOOD (0x00)
@@ -474,12 +494,10 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST
#define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET (0x18)
#define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET (0x00)
+#define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x01)
#define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST (0x08)
#define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET (0x10)
-#define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x01)
-
-
/* SCSI Task Management Reply Message */
typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY
@@ -561,6 +579,7 @@ typedef struct _MPI2_SEP_REQUEST
#define MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS (0x01)
/* SlotStatus defines */
+#define MPI2_SEP_REQ_SLOTSTATUS_DEV_OFF (0x00080000) /* MPI v2.6 and newer */
#define MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000)
#define MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
#define MPI2_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
@@ -598,6 +617,7 @@ typedef struct _MPI2_SEP_REPLY
Mpi2SepReply_t, MPI2_POINTER pMpi2SepReply_t;
/* SlotStatus defines */
+#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_OFF (0x00080000) /* MPI v2.6 and newer */
#define MPI2_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000)
#define MPI2_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
#define MPI2_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
diff --git a/sys/dev/mpr/mpi/mpi2_ioc.h b/sys/dev/mpr/mpi/mpi2_ioc.h
index 54f39a5..37f01c6 100644
--- a/sys/dev/mpr/mpi/mpi2_ioc.h
+++ b/sys/dev/mpr/mpi/mpi2_ioc.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,14 +34,15 @@
/*
* Copyright (c) 2000-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2_ioc.h
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: October 11, 2006
*
- * mpi2_ioc.h Version: 02.00.24
+ * mpi2_ioc.h Version: 02.00.27
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@@ -168,6 +169,17 @@
* Added MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY.
* Added Encrypted Hash Extended Image.
* 12-05-13 02.00.24 Added MPI25_HASH_IMAGE_TYPE_BIOS.
+ * 11-18-14 02.00.25 Updated copyright information.
+ * 03-16-15 02.00.26 Updated for MPI v2.6.
+ * Added MPI2_EVENT_ACTIVE_CABLE_EXCEPTION and
+ * MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT.
+ * Added MPI2_EVENT_PCIE_LINK_COUNTER and
+ * MPI26_EVENT_DATA_PCIE_LINK_COUNTER.
+ * Added MPI26_CTRL_OP_SHUTDOWN.
+ * Added MPI26_CTRL_OP_LINK_CLEAR_ERROR_LOG
+ * Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS
+ * 08-25-15 02.00.27 Added IC ARCH Class based signature defines
+ *
* --------------------------------------------------------------------------
*/
@@ -200,8 +212,8 @@ typedef struct _MPI2_IOC_INIT_REQUEST
U16 MsgVersion; /* 0x0C */
U16 HeaderVersion; /* 0x0E */
U32 Reserved5; /* 0x10 */
- U16 Reserved6; /* 0x14 */
- U8 Reserved7; /* 0x16 */
+ U16 ConfigurationFlags; /* 0x14 */
+ U8 HostPageSize; /* 0x16 */
U8 HostMSIxVectors; /* 0x17 */
U16 Reserved8; /* 0x18 */
U16 SystemRequestFrameSize; /* 0x1A */
@@ -329,7 +341,12 @@ typedef struct _MPI2_IOC_FACTS_REPLY
U16 MaxDevHandle; /* 0x38 */
U16 MaxPersistentEntries; /* 0x3A */
U16 MinDevHandle; /* 0x3C */
- U16 Reserved4; /* 0x3E */
+ U8 CurrentHostPageSize; /* 0x3E */
+ U8 Reserved4; /* 0x3F */
+ U8 SGEModifierMask; /* 0x40 */
+ U8 SGEModifierValue; /* 0x41 */
+ U8 SGEModifierShift; /* 0x42 */
+ U8 Reserved5; /* 0x43 */
} MPI2_IOC_FACTS_REPLY, MPI2_POINTER PTR_MPI2_IOC_FACTS_REPLY,
Mpi2IOCFactsReply_t, MPI2_POINTER pMpi2IOCFactsReply_t;
@@ -383,8 +400,8 @@ typedef struct _MPI2_IOC_FACTS_REPLY
#define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004)
/* ProtocolFlags */
-#define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET (0x0001)
#define MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR (0x0002)
+#define MPI2_IOCFACTS_PROTOCOL_SCSI_TARGET (0x0001)
/****************************************************************************
@@ -559,6 +576,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
#define MPI2_EVENT_TEMP_THRESHOLD (0x0027)
#define MPI2_EVENT_HOST_MESSAGE (0x0028)
#define MPI2_EVENT_POWER_PERFORMANCE_CHANGE (0x0029)
+#define MPI2_EVENT_ACTIVE_CABLE_EXCEPTION (0x0034) /* MPI v2.6 and later */
#define MPI2_EVENT_MIN_PRODUCT_SPECIFIC (0x006E)
#define MPI2_EVENT_MAX_PRODUCT_SPECIFIC (0x007F)
@@ -630,7 +648,7 @@ typedef struct _MPI2_EVENT_DATA_HOST_MESSAGE
Mpi2EventDataHostMessage_t, MPI2_POINTER pMpi2EventDataHostMessage_t;
-/* Power Performance Change Event */
+/* Power Performance Change Event data */
typedef struct _MPI2_EVENT_DATA_POWER_PERF_CHANGE
{
@@ -656,6 +674,23 @@ typedef struct _MPI2_EVENT_DATA_POWER_PERF_CHANGE
#define MPI2_EVENT_PM_MODE_STANDBY (0x06)
+/* Active Cable Exception Event data */
+
+typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT
+{
+ U32 ActiveCablePowerRequirement; /* 0x00 */
+ U8 ReasonCode; /* 0x04 */
+ U8 ReceptacleID; /* 0x05 */
+ U16 Reserved1; /* 0x06 */
+} MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
+ MPI2_POINTER PTR_MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
+ Mpi26EventDataActiveCableExcept_t,
+ MPI2_POINTER pMpi26EventDataActiveCableExcept_t;
+
+/* defines for ReasonCode field */
+#define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER (0x00)
+
+
/* Hard Reset Received Event data */
typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
@@ -1130,7 +1165,6 @@ typedef struct _MPI2_EVENT_DATA_HBD_PHY
#define MPI2_EVENT_HBD_DT_SAS (0x01)
-
/****************************************************************************
* EventAck message
****************************************************************************/
@@ -1348,6 +1382,7 @@ typedef struct _MPI2_FW_UPLOAD_REQUEST
#define MPI2_FW_UPLOAD_ITYPE_MEGARAID (0x09)
#define MPI2_FW_UPLOAD_ITYPE_COMPLETE (0x0A)
#define MPI2_FW_UPLOAD_ITYPE_COMMON_BOOT_BLOCK (0x0B)
+#define MPI2_FW_UPLOAD_ITYPE_CBB_BACKUP (0x0D)
/* MPI v2.0 FWUpload TransactionContext Element */
typedef struct _MPI2_FW_UPLOAD_TCSGE
@@ -1436,7 +1471,7 @@ typedef struct _MPI2_FW_IMAGE_HEADER
U32 Reserved54; /* 0x54 */
U32 Reserved58; /* 0x58 */
U32 Reserved5C; /* 0x5C */
- U32 Reserved60; /* 0x60 */
+ U32 BootFlags; /* 0x60 */ /* reserved in MPI v2.5 and earlier */
U32 FirmwareVersionNameWhat; /* 0x64 */
U8 FirmwareVersionName[32]; /* 0x68 */
U32 VendorNameWhat; /* 0x88 */
@@ -1462,18 +1497,27 @@ typedef struct _MPI2_FW_IMAGE_HEADER
#define MPI2_FW_HEADER_SIGNATURE_OFFSET (0x00)
#define MPI2_FW_HEADER_SIGNATURE_MASK (0xFF000000)
#define MPI2_FW_HEADER_SIGNATURE (0xEA000000)
+#define MPI26_FW_HEADER_SIGNATURE (0xEB000000)
/* Signature0 field */
#define MPI2_FW_HEADER_SIGNATURE0_OFFSET (0x04)
#define MPI2_FW_HEADER_SIGNATURE0 (0x5AFAA55A)
+#define MPI26_FW_HEADER_SIGNATURE0_BASE (0x5AEAA500) /* Last byte is defined by architecture */
+#define MPI26_FW_HEADER_SIGNATURE0_ARC_0 (0x5A)
+#define MPI26_FW_HEADER_SIGNATURE0_ARC_1 (0x00)
+#define MPI26_FW_HEADER_SIGNATURE0_ARC_2 (0x01)
+#define MPI26_FW_HEADER_SIGNATURE0 (MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_0) // legacy (0x5AEAA55A)
+#define MPI26_FW_HEADER_SIGNATURE0_3516 (MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_1)
/* Signature1 field */
#define MPI2_FW_HEADER_SIGNATURE1_OFFSET (0x08)
#define MPI2_FW_HEADER_SIGNATURE1 (0xA55AFAA5)
+#define MPI26_FW_HEADER_SIGNATURE1 (0xA55AEAA5)
/* Signature2 field */
#define MPI2_FW_HEADER_SIGNATURE2_OFFSET (0x0C)
#define MPI2_FW_HEADER_SIGNATURE2 (0x5AA55AFA)
+#define MPI26_FW_HEADER_SIGNATURE2 (0x5AA55AEA)
/* defines for using the ProductID field */
@@ -1491,6 +1535,8 @@ typedef struct _MPI2_FW_IMAGE_HEADER
#define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0013)
#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS (0x0014)
#define MPI25_FW_HEADER_PID_FAMILY_3108_SAS (0x0021)
+#define MPI26_FW_HEADER_PID_FAMILY_3324_SAS (0x0028)
+#define MPI26_FW_HEADER_PID_FAMILY_3516_SAS (0x0031)
/* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */
@@ -1499,6 +1545,7 @@ typedef struct _MPI2_FW_IMAGE_HEADER
#define MPI2_FW_HEADER_IMAGESIZE_OFFSET (0x2C)
#define MPI2_FW_HEADER_NEXTIMAGE_OFFSET (0x30)
+#define MPI26_FW_HEADER_BOOTFLAGS_OFFSET (0x60)
#define MPI2_FW_HEADER_VERNMHWAT_OFFSET (0x64)
#define MPI2_FW_HEADER_WHAT_SIGNATURE (0x29232840)
@@ -1612,7 +1659,10 @@ typedef struct _MPI2_FLASH_LAYOUT_DATA
#define MPI2_FLASH_REGION_CONFIG_1 (0x07)
#define MPI2_FLASH_REGION_CONFIG_2 (0x08)
#define MPI2_FLASH_REGION_MEGARAID (0x09)
-#define MPI2_FLASH_REGION_INIT (0x0A)
+#define MPI2_FLASH_REGION_COMMON_BOOT_BLOCK (0x0A)
+#define MPI2_FLASH_REGION_INIT (MPI2_FLASH_REGION_COMMON_BOOT_BLOCK) /* older name */
+#define MPI2_FLASH_REGION_CBB_BACKUP (0x0D)
+
/* ImageRevision */
#define MPI2_FLASH_LAYOUT_IMAGE_REVISION (0x00)
@@ -1854,5 +1904,91 @@ typedef struct _MPI2_PWR_MGMT_CONTROL_REPLY
Mpi2PwrMgmtControlReply_t, MPI2_POINTER pMpi2PwrMgmtControlReply_t;
+/****************************************************************************
+* IO Unit Control messages (MPI v2.6 and later only.)
+****************************************************************************/
+
+/* IO Unit Control Request Message */
+typedef struct _MPI26_IOUNIT_CONTROL_REQUEST
+{
+ U8 Operation; /* 0x00 */
+ U8 Reserved1; /* 0x01 */
+ U8 ChainOffset; /* 0x02 */
+ U8 Function; /* 0x03 */
+ U16 DevHandle; /* 0x04 */
+ U8 IOCParameter; /* 0x06 */
+ U8 MsgFlags; /* 0x07 */
+ U8 VP_ID; /* 0x08 */
+ U8 VF_ID; /* 0x09 */
+ U16 Reserved3; /* 0x0A */
+ U16 Reserved4; /* 0x0C */
+ U8 PhyNum; /* 0x0E */
+ U8 PrimFlags; /* 0x0F */
+ U32 Primitive; /* 0x10 */
+ U8 LookupMethod; /* 0x14 */
+ U8 Reserved5; /* 0x15 */
+ U16 SlotNumber; /* 0x16 */
+ U64 LookupAddress; /* 0x18 */
+ U32 IOCParameterValue; /* 0x20 */
+ U32 Reserved7; /* 0x24 */
+ U32 Reserved8; /* 0x28 */
+} MPI26_IOUNIT_CONTROL_REQUEST,
+ MPI2_POINTER PTR_MPI26_IOUNIT_CONTROL_REQUEST,
+ Mpi26IoUnitControlRequest_t, MPI2_POINTER pMpi26IoUnitControlRequest_t;
+
+/* values for the Operation field */
+#define MPI26_CTRL_OP_CLEAR_ALL_PERSISTENT (0x02)
+#define MPI26_CTRL_OP_SAS_PHY_LINK_RESET (0x06)
+#define MPI26_CTRL_OP_SAS_PHY_HARD_RESET (0x07)
+#define MPI26_CTRL_OP_PHY_CLEAR_ERROR_LOG (0x08)
+#define MPI26_CTRL_OP_LINK_CLEAR_ERROR_LOG (0x09)
+#define MPI26_CTRL_OP_SAS_SEND_PRIMITIVE (0x0A)
+#define MPI26_CTRL_OP_FORCE_FULL_DISCOVERY (0x0B)
+#define MPI26_CTRL_OP_REMOVE_DEVICE (0x0D)
+#define MPI26_CTRL_OP_LOOKUP_MAPPING (0x0E)
+#define MPI26_CTRL_OP_SET_IOC_PARAMETER (0x0F)
+#define MPI26_CTRL_OP_ENABLE_FP_DEVICE (0x10)
+#define MPI26_CTRL_OP_DISABLE_FP_DEVICE (0x11)
+#define MPI26_CTRL_OP_ENABLE_FP_ALL (0x12)
+#define MPI26_CTRL_OP_DISABLE_FP_ALL (0x13)
+#define MPI26_CTRL_OP_DEV_ENABLE_NCQ (0x14)
+#define MPI26_CTRL_OP_DEV_DISABLE_NCQ (0x15)
+#define MPI26_CTRL_OP_SHUTDOWN (0x16)
+#define MPI26_CTRL_OP_DEV_ENABLE_PERSIST_CONNECTION (0x17)
+#define MPI26_CTRL_OP_DEV_DISABLE_PERSIST_CONNECTION (0x18)
+#define MPI26_CTRL_OP_DEV_CLOSE_PERSIST_CONNECTION (0x19)
+#define MPI26_CTRL_OP_PRODUCT_SPECIFIC_MIN (0x80)
+
+/* values for the PrimFlags field */
+#define MPI26_CTRL_PRIMFLAGS_SINGLE (0x08)
+#define MPI26_CTRL_PRIMFLAGS_TRIPLE (0x02)
+#define MPI26_CTRL_PRIMFLAGS_REDUNDANT (0x01)
+
+/* values for the LookupMethod field */
+#define MPI26_CTRL_LOOKUP_METHOD_WWID_ADDRESS (0x01)
+#define MPI26_CTRL_LOOKUP_METHOD_ENCLOSURE_SLOT (0x02)
+#define MPI26_CTRL_LOOKUP_METHOD_SAS_DEVICE_NAME (0x03)
+
+
+/* IO Unit Control Reply Message */
+typedef struct _MPI26_IOUNIT_CONTROL_REPLY
+{
+ U8 Operation; /* 0x00 */
+ U8 Reserved1; /* 0x01 */
+ U8 MsgLength; /* 0x02 */
+ U8 Function; /* 0x03 */
+ U16 DevHandle; /* 0x04 */
+ U8 IOCParameter; /* 0x06 */
+ U8 MsgFlags; /* 0x07 */
+ U8 VP_ID; /* 0x08 */
+ U8 VF_ID; /* 0x09 */
+ U16 Reserved3; /* 0x0A */
+ U16 Reserved4; /* 0x0C */
+ U16 IOCStatus; /* 0x0E */
+ U32 IOCLogInfo; /* 0x10 */
+} MPI26_IOUNIT_CONTROL_REPLY, MPI2_POINTER PTR_MPI26_IOUNIT_CONTROL_REPLY,
+ Mpi26IoUnitControlReply_t, MPI2_POINTER pMpi26IoUnitControlReply_t;
+
+
#endif
diff --git a/sys/dev/mpr/mpi/mpi2_ra.h b/sys/dev/mpr/mpi/mpi2_ra.h
index 02304aa..013f598 100644
--- a/sys/dev/mpr/mpi/mpi2_ra.h
+++ b/sys/dev/mpr/mpi/mpi2_ra.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,14 +34,15 @@
/*
* Copyright (c) 2012-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2_ra.h
* Title: MPI RAID Accelerator messages and structures
* Creation Date: April 13, 2009
*
- * mpi2_ra.h Version: 02.00.00
+ * mpi2_ra.h Version: 02.00.01
*
* Version History
* ---------------
@@ -49,6 +50,7 @@
* Date Version Description
* -------- -------- ------------------------------------------------------
* 05-06-09 02.00.00 Initial version.
+ * 11-18-14 02.00.01 Updated copyright information.
* --------------------------------------------------------------------------
*/
diff --git a/sys/dev/mpr/mpi/mpi2_raid.h b/sys/dev/mpr/mpi/mpi2_raid.h
index 52ebf07..81be995 100644
--- a/sys/dev/mpr/mpi/mpi2_raid.h
+++ b/sys/dev/mpr/mpi/mpi2_raid.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,14 +34,15 @@
/*
* Copyright (c) 2000-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2_raid.h
* Title: MPI Integrated RAID messages and structures
* Creation Date: April 26, 2007
*
- * mpi2_raid.h Version: 02.00.10
+ * mpi2_raid.h Version: 02.00.11
*
* Version History
* ---------------
@@ -66,6 +67,7 @@
* 07-26-12 02.00.09 Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR.
* Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define.
* 04-17-13 02.00.10 Added MPI25_RAID_ACTION_ADATA_ALLOW_PI.
+ * 11-18-14 02.00.11 Updated copyright information.
* --------------------------------------------------------------------------
*/
diff --git a/sys/dev/mpr/mpi/mpi2_sas.h b/sys/dev/mpr/mpi/mpi2_sas.h
index 7cae2c3..8f90b2b 100644
--- a/sys/dev/mpr/mpi/mpi2_sas.h
+++ b/sys/dev/mpr/mpi/mpi2_sas.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,14 +34,15 @@
/*
* Copyright (c) 2000-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2_sas.h
* Title: MPI Serial Attached SCSI structures and definitions
* Creation Date: February 9, 2007
*
- * mpi2_sas.h Version: 02.00.08
+ * mpi2_sas.h Version: 02.00.10
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@@ -67,6 +68,9 @@
* Passthrough Request message.
* 08-19-13 02.00.08 Made MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL obsolete
* for anything newer than MPI v2.0.
+ * 11-18-14 02.00.09 Updated copyright information.
+ * 03-16-15 02.00.10 Updated for MPI v2.6.
+ * Added MPI2_SATA_PT_REQ_PT_FLAGS_FPDMA.
* --------------------------------------------------------------------------
*/
@@ -226,6 +230,7 @@ typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST
/* values for PassthroughFlags field */
#define MPI2_SATA_PT_REQ_PT_FLAGS_EXECUTE_DIAG (0x0100)
+#define MPI2_SATA_PT_REQ_PT_FLAGS_FPDMA (0x0040) /* MPI v2.6 and newer */
#define MPI2_SATA_PT_REQ_PT_FLAGS_DMA (0x0020)
#define MPI2_SATA_PT_REQ_PT_FLAGS_PIO (0x0010)
#define MPI2_SATA_PT_REQ_PT_FLAGS_UNSPECIFIED_VU (0x0004)
@@ -262,6 +267,8 @@ typedef struct _MPI2_SATA_PASSTHROUGH_REPLY
/****************************************************************************
* SAS IO Unit Control messages
+* (MPI v2.5 and earlier only.
+* Replaced by IO Unit Control messages in MPI v2.6 and later.)
****************************************************************************/
/* SAS IO Unit Control Request Message */
diff --git a/sys/dev/mpr/mpi/mpi2_targ.h b/sys/dev/mpr/mpi/mpi2_targ.h
index 85b5ac5..0216cfe 100644
--- a/sys/dev/mpr/mpi/mpi2_targ.h
+++ b/sys/dev/mpr/mpi/mpi2_targ.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,14 +34,15 @@
/*
* Copyright (c) 2000-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2_targ.h
* Title: MPI Target mode messages and structures
* Creation Date: September 8, 2006
*
- * mpi2_targ.h Version: 02.00.06
+ * mpi2_targ.h Version: 02.00.09
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@@ -67,6 +68,11 @@
* request message structure.
* Added AbortType MPI2_TARGET_MODE_ABORT_DEVHANDLE and
* MPI2_TARGET_MODE_ABORT_ALL_COMMANDS.
+ * 06-13-14 02.00.07 Added MinMSIxIndex and MaxMSIxIndex fields to
+ * MPI2_TARGET_CMD_BUF_POST_BASE_REQUEST.
+ * 11-18-14 02.00.08 Updated copyright information.
+ * 03-16-15 02.00.09 Updated for MPI v2.6.
+ * Added MPI26_TARGET_ASSIST_IOFLAGS_ESCAPE_PASSTHROUGH.
* --------------------------------------------------------------------------
*/
@@ -98,7 +104,8 @@ typedef struct _MPI2_TARGET_CMD_BUF_POST_BASE_REQUEST
U16 Reserved2; /* 0x0A */
U32 Reserved3; /* 0x0C */
U16 CmdBufferLength; /* 0x10 */
- U16 Reserved4; /* 0x12 */
+ U8 MinMSIxIndex; /* 0x12 */ /* MPI 2.5 and newer only; Reserved in MPI 2.0 */
+ U8 MaxMSIxIndex; /* 0x13 */ /* MPI 2.5 and newer only; Reserved in MPI 2.0 */
U32 BaseAddressLow; /* 0x14 */
U32 BaseAddressHigh; /* 0x18 */
} MPI2_TARGET_CMD_BUF_POST_BASE_REQUEST,
@@ -110,8 +117,9 @@ typedef struct _MPI2_TARGET_CMD_BUF_POST_BASE_REQUEST
#define MPI2_CMD_BUF_POST_BASE_ADDRESS_SPACE_MASK (0x0C)
#define MPI2_CMD_BUF_POST_BASE_SYSTEM_ADDRESS_SPACE (0x00)
#define MPI2_CMD_BUF_POST_BASE_IOCDDR_ADDRESS_SPACE (0x04)
-#define MPI2_CMD_BUF_POST_BASE_IOCPLB_ADDRESS_SPACE (0x08)
-#define MPI2_CMD_BUF_POST_BASE_IOCPLBNTA_ADDRESS_SPACE (0x0C)
+#define MPI2_CMD_BUF_POST_BASE_IOCPLB_ADDRESS_SPACE (0x08) /* only for MPI v2.5 and earlier */
+#define MPI26_CMD_BUF_POST_BASE_IOCCTL_ADDRESS_SPACE (0x08) /* for MPI v2.6 only */
+#define MPI2_CMD_BUF_POST_BASE_IOCPLBNTA_ADDRESS_SPACE (0x0C) /* only for MPI v2.5 and earlier */
#define MPI2_CMD_BUF_POST_BASE_FLAGS_AUTO_POST_ALL (0x01)
@@ -406,6 +414,7 @@ typedef struct _MPI25_TARGET_ASSIST_REQUEST
#define MPI25_TA_DMAFLAGS_OP_D_H_I_I (0x0F)
/* defines for the IoFlags field */
+#define MPI26_TARGET_ASSIST_IOFLAGS_ESCAPE_PASSTHROUGH (0x2000) /* MPI v2.6 and later */
#define MPI25_TARGET_ASSIST_IOFLAGS_BIDIRECTIONAL (0x0800)
#define MPI25_TARGET_ASSIST_IOFLAGS_RECEIVE_FIRST (0x0200)
diff --git a/sys/dev/mpr/mpi/mpi2_tool.h b/sys/dev/mpr/mpi/mpi2_tool.h
index 59917c0..fce98ae 100644
--- a/sys/dev/mpr/mpi/mpi2_tool.h
+++ b/sys/dev/mpr/mpi/mpi2_tool.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,14 +34,15 @@
/*
* Copyright (c) 2000-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2_tool.h
* Title: MPI diagnostic tool structures and definitions
* Creation Date: March 26, 2007
*
- * mpi2_tool.h Version: 02.00.11
+ * mpi2_tool.h Version: 02.00.13
*
* Version History
* ---------------
@@ -68,6 +69,8 @@
* 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that
* it uses MPI Chain SGE as well as MPI Simple SGE.
* 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info.
+ * 01-08-14 02.00.12 Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC.
+ * 11-18-14 02.00.13 Updated copyright information.
* --------------------------------------------------------------------------
*/
@@ -139,6 +142,7 @@ typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST
#define MPI2_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000)
#define MPI2_TOOLBOX_CLEAN_FW_CURRENT (0x10000000)
#define MPI2_TOOLBOX_CLEAN_FW_BACKUP (0x08000000)
+#define MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC (0x04000000)
#define MPI2_TOOLBOX_CLEAN_MEGARAID (0x02000000)
#define MPI2_TOOLBOX_CLEAN_INITIALIZATION (0x01000000)
#define MPI2_TOOLBOX_CLEAN_FLASH (0x00000004)
diff --git a/sys/dev/mpr/mpi/mpi2_type.h b/sys/dev/mpr/mpi/mpi2_type.h
index b063683..8e64484 100644
--- a/sys/dev/mpr/mpi/mpi2_type.h
+++ b/sys/dev/mpr/mpi/mpi2_type.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,14 +34,15 @@
/*
* Copyright (c) 2000-2015 LSI Corporation.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
+ * All rights reserved.
*
*
* Name: mpi2_type.h
* Title: MPI basic type definitions
* Creation Date: August 16, 2006
*
- * mpi2_type.h Version: 02.00.00
+ * mpi2_type.h Version: 02.00.01
*
* Version History
* ---------------
@@ -49,6 +50,7 @@
* Date Version Description
* -------- -------- ------------------------------------------------------
* 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
+ * 11-18-14 02.00.01 Updated copyright information.
* --------------------------------------------------------------------------
*/
diff --git a/sys/dev/mpr/mpr.c b/sys/dev/mpr/mpr.c
index 5580157..5ae9f4c 100644
--- a/sys/dev/mpr/mpr.c
+++ b/sys/dev/mpr/mpr.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2009 Yahoo! Inc.
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -92,14 +92,11 @@ static __inline void mpr_complete_command(struct mpr_softc *sc,
struct mpr_command *cm);
static void mpr_dispatch_event(struct mpr_softc *sc, uintptr_t data,
MPI2_EVENT_NOTIFICATION_REPLY *reply);
-static void mpr_config_complete(struct mpr_softc *sc,
- struct mpr_command *cm);
+static void mpr_config_complete(struct mpr_softc *sc, struct mpr_command *cm);
static void mpr_periodic(void *);
static int mpr_reregister_events(struct mpr_softc *sc);
-static void mpr_enqueue_request(struct mpr_softc *sc,
- struct mpr_command *cm);
-static int mpr_get_iocfacts(struct mpr_softc *sc,
- MPI2_IOC_FACTS_REPLY *facts);
+static void mpr_enqueue_request(struct mpr_softc *sc, struct mpr_command *cm);
+static int mpr_get_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts);
static int mpr_wait_db_ack(struct mpr_softc *sc, int timeout, int sleep_flag);
SYSCTL_NODE(_hw, OID_AUTO, mpr, CTLFLAG_RD, 0, "MPR Driver Parameters");
@@ -444,6 +441,8 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
(saved_facts.IOCCapabilities != sc->facts->IOCCapabilities) ||
(saved_facts.IOCRequestFrameSize !=
sc->facts->IOCRequestFrameSize) ||
+ (saved_facts.IOCMaxChainSegmentSize !=
+ sc->facts->IOCMaxChainSegmentSize) ||
(saved_facts.MaxTargets != sc->facts->MaxTargets) ||
(saved_facts.MaxSasExpanders != sc->facts->MaxSasExpanders) ||
(saved_facts.MaxEnclosures != sc->facts->MaxEnclosures) ||
@@ -550,8 +549,8 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
error = mpr_transition_operational(sc);
if (error != 0) {
if (attaching) {
- mpr_printf(sc, "%s failed to transition to "
- "operational with error %d\n", __func__, error);
+ mpr_printf(sc, "%s failed to transition to operational "
+ "with error %d\n", __func__, error);
mpr_free(sc);
return (error);
} else {
@@ -685,7 +684,7 @@ mpr_reinit(struct mpr_softc *sc)
if (sc->mpr_flags & MPR_FLAGS_DIAGRESET) {
mpr_dprint(sc, MPR_INIT, "%s reset already in progress\n",
- __func__);
+ __func__);
return 0;
}
@@ -1191,7 +1190,28 @@ mpr_alloc_requests(struct mpr_softc *sc)
bus_dmamap_load(sc->req_dmat, sc->req_map, sc->req_frames, rsize,
mpr_memaddr_cb, &sc->req_busaddr, 0);
- rsize = sc->facts->IOCRequestFrameSize * sc->max_chains * 4;
+ /*
+ * Gen3 and beyond uses the IOCMaxChainSegmentSize from IOC Facts to
+ * get the size of a Chain Frame. Previous versions use the size as a
+ * Request Frame for the Chain Frame size. If IOCMaxChainSegmentSize
+ * is 0, use the default value. The IOCMaxChainSegmentSize is the
+ * number of 16-byte elelements that can fit in a Chain Frame, which is
+ * the size of an IEEE Simple SGE.
+ */
+ if (sc->facts->MsgVersion >= MPI2_VERSION_02_05) {
+ sc->chain_seg_size =
+ htole16(sc->facts->IOCMaxChainSegmentSize);
+ if (sc->chain_seg_size == 0) {
+ sc->chain_frame_size = MPR_DEFAULT_CHAIN_SEG_SIZE *
+ MPR_MAX_CHAIN_ELEMENT_SIZE;
+ } else {
+ sc->chain_frame_size = sc->chain_seg_size *
+ MPR_MAX_CHAIN_ELEMENT_SIZE;
+ }
+ } else {
+ sc->chain_frame_size = sc->facts->IOCRequestFrameSize * 4;
+ }
+ rsize = sc->chain_frame_size * sc->max_chains;
if (bus_dma_tag_create( sc->mpr_parent_dmat, /* parent */
16, 0, /* algnmnt, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
@@ -1249,9 +1269,9 @@ mpr_alloc_requests(struct mpr_softc *sc)
for (i = 0; i < sc->max_chains; i++) {
chain = &sc->chains[i];
chain->chain = (MPI2_SGE_IO_UNION *)(sc->chain_frames +
- i * sc->facts->IOCRequestFrameSize * 4);
+ i * sc->chain_frame_size);
chain->chain_busaddr = sc->chain_busaddr +
- i * sc->facts->IOCRequestFrameSize * 4;
+ i * sc->chain_frame_size;
mpr_free_chain(sc, chain);
sc->chain_free_lowwater++;
}
@@ -1712,9 +1732,9 @@ mpr_complete_command(struct mpr_softc *sc, struct mpr_command *cm)
if (cm->cm_complete != NULL) {
mpr_dprint(sc, MPR_TRACE,
- "%s cm %p calling cm_complete %p data %p reply %p\n",
- __func__, cm, cm->cm_complete, cm->cm_complete_data,
- cm->cm_reply);
+ "%s cm %p calling cm_complete %p data %p reply %p\n",
+ __func__, cm, cm->cm_complete, cm->cm_complete_data,
+ cm->cm_reply);
cm->cm_complete(sc, cm);
}
@@ -1771,10 +1791,9 @@ mpr_sas_log_info(struct mpr_softc *sc , u32 log_info)
break;
}
- mpr_dprint(sc, MPR_INFO, "log_info(0x%08x): originator(%s), "
- "code(0x%02x), sub_code(0x%04x)\n", log_info,
- originator_str, sas_loginfo.dw.code,
- sas_loginfo.dw.subcode);
+ mpr_dprint(sc, MPR_LOG, "log_info(0x%08x): originator(%s), "
+ "code(0x%02x), sub_code(0x%04x)\n", log_info, originator_str,
+ sas_loginfo.dw.code, sas_loginfo.dw.subcode);
}
static void
@@ -1923,9 +1942,10 @@ mpr_intr_locked(void *data)
*/
rel_rep =
(MPI2_DIAG_RELEASE_REPLY *)reply;
- if (le16toh(rel_rep->IOCStatus) ==
+ if ((le16toh(rel_rep->IOCStatus) &
+ MPI2_IOCSTATUS_MASK) ==
MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED)
- {
+ {
pBuffer =
&sc->fw_diag_buffer_list[
rel_rep->BufferType];
@@ -2173,7 +2193,7 @@ mpr_add_chain(struct mpr_command *cm, int segsleft)
MPI2_REQUEST_HEADER *req;
MPI25_IEEE_SGE_CHAIN64 *ieee_sgc;
struct mpr_chain *chain;
- int space, sgc_size, current_segs, rem_segs, segs_per_frame;
+ int sgc_size, current_segs, rem_segs, segs_per_frame;
uint8_t next_chain_offset = 0;
/*
@@ -2195,8 +2215,6 @@ mpr_add_chain(struct mpr_command *cm, int segsleft)
if (chain == NULL)
return (ENOBUFS);
- space = (int)cm->cm_sc->facts->IOCRequestFrameSize * 4;
-
/*
* Note: a double-linked list is used to make it easier to walk for
* debugging.
@@ -2222,13 +2240,14 @@ mpr_add_chain(struct mpr_command *cm, int segsleft)
*/
current_segs = (cm->cm_sglsize / sgc_size) - 1;
rem_segs = segsleft - current_segs;
- segs_per_frame = space / sgc_size;
+ segs_per_frame = sc->chain_frame_size / sgc_size;
if (rem_segs > segs_per_frame) {
next_chain_offset = segs_per_frame - 1;
}
}
ieee_sgc = &((MPI25_SGE_IO_UNION *)cm->cm_sge)->IeeeChain;
- ieee_sgc->Length = next_chain_offset ? htole32((uint32_t)space) :
+ ieee_sgc->Length = next_chain_offset ?
+ htole32((uint32_t)sc->chain_frame_size) :
htole32((uint32_t)rem_segs * (uint32_t)sgc_size);
ieee_sgc->NextChainOffset = next_chain_offset;
ieee_sgc->Flags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
@@ -2237,10 +2256,9 @@ mpr_add_chain(struct mpr_command *cm, int segsleft)
ieee_sgc->Address.High = htole32(chain->chain_busaddr >> 32);
cm->cm_sge = &((MPI25_SGE_IO_UNION *)chain->chain)->IeeeSimple;
req = (MPI2_REQUEST_HEADER *)cm->cm_req;
- req->ChainOffset = ((sc->facts->IOCRequestFrameSize * 4) -
- sgc_size) >> 4;
+ req->ChainOffset = (sc->chain_frame_size - sgc_size) >> 4;
- cm->cm_sglsize = space;
+ cm->cm_sglsize = sc->chain_frame_size;
return (0);
}
@@ -2463,10 +2481,9 @@ mpr_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
* user they did the wrong thing.
*/
if ((cm->cm_max_segs != 0) && (nsegs > cm->cm_max_segs)) {
- mpr_dprint(sc, MPR_ERROR,
- "%s: warning: busdma returned %d segments, "
- "more than the %d allowed\n", __func__, nsegs,
- cm->cm_max_segs);
+ mpr_dprint(sc, MPR_ERROR, "%s: warning: busdma returned %d "
+ "segments, more than the %d allowed\n", __func__, nsegs,
+ cm->cm_max_segs);
}
/*
@@ -2663,8 +2680,8 @@ mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm)
if (error) {
mpr_dprint(sc, MPR_FAULT, "Calling Reinit from %s\n", __func__);
rc = mpr_reinit(sc);
- mpr_dprint(sc, MPR_FAULT, "Reinit %s\n", (rc == 0) ?
- "success" : "failed");
+ mpr_dprint(sc, MPR_FAULT, "Reinit %s\n", (rc == 0) ? "success" :
+ "failed");
}
return (error);
}
diff --git a/sys/dev/mpr/mpr_config.c b/sys/dev/mpr/mpr_config.c
index c0ea3d5..0ba44ea 100644
--- a/sys/dev/mpr/mpr_config.c
+++ b/sys/dev/mpr/mpr_config.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/mpr/mpr_ioctl.h b/sys/dev/mpr/mpr_ioctl.h
index aa1a4cb..df41f56 100644
--- a/sys/dev/mpr/mpr_ioctl.h
+++ b/sys/dev/mpr/mpr_ioctl.h
@@ -33,7 +33,7 @@
*/
/*-
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/mpr/mpr_mapping.c b/sys/dev/mpr/mpr_mapping.c
index 110e6a3..0feb555 100644
--- a/sys/dev/mpr/mpr_mapping.c
+++ b/sys/dev/mpr/mpr_mapping.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/mpr/mpr_mapping.h b/sys/dev/mpr/mpr_mapping.h
index fafaf9b..05571f2e 100644
--- a/sys/dev/mpr/mpr_mapping.h
+++ b/sys/dev/mpr/mpr_mapping.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/mpr/mpr_pci.c b/sys/dev/mpr/mpr_pci.c
index 7430eac..17f3f3e 100644
--- a/sys/dev/mpr/mpr_pci.c
+++ b/sys/dev/mpr/mpr_pci.c
@@ -110,6 +110,18 @@ struct mpr_ident {
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_5" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_6" },
+ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_1,
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3316_1" },
+ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_2,
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3316_2" },
+ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_1,
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3324_1" },
+ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_2,
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3324_2" },
+ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3216,
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3216" },
+ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3224,
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3224" },
{ 0, 0, 0, 0, 0, NULL }
};
diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c
index eac3360..45c0bbd 100644
--- a/sys/dev/mpr/mpr_sas.c
+++ b/sys/dev/mpr/mpr_sas.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2009 Yahoo! Inc.
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -119,13 +119,11 @@ static void mprsas_remove_complete(struct mpr_softc *, struct mpr_command *);
static void mprsas_action(struct cam_sim *sim, union ccb *ccb);
static void mprsas_poll(struct cam_sim *sim);
static void mprsas_scsiio_timeout(void *data);
-static void mprsas_abort_complete(struct mpr_softc *sc,
- struct mpr_command *cm);
+static void mprsas_abort_complete(struct mpr_softc *sc, struct mpr_command *cm);
static void mprsas_action_scsiio(struct mprsas_softc *, union ccb *);
static void mprsas_scsiio_complete(struct mpr_softc *, struct mpr_command *);
static void mprsas_action_resetdev(struct mprsas_softc *, union ccb *);
-static void mprsas_resetdev_complete(struct mpr_softc *,
- struct mpr_command *);
+static void mprsas_resetdev_complete(struct mpr_softc *, struct mpr_command *);
static int mprsas_send_abort(struct mpr_softc *sc, struct mpr_command *tm,
struct mpr_command *cm);
static void mprsas_async(void *callback_arg, uint32_t code,
@@ -142,10 +140,9 @@ static void mprsas_portenable_complete(struct mpr_softc *sc,
struct mpr_command *cm);
#if __FreeBSD_version >= 900026
-static void mprsas_smpio_complete(struct mpr_softc *sc,
- struct mpr_command *cm);
-static void mprsas_send_smpcmd(struct mprsas_softc *sassc,
- union ccb *ccb, uint64_t sasaddr);
+static void mprsas_smpio_complete(struct mpr_softc *sc, struct mpr_command *cm);
+static void mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
+ uint64_t sasaddr);
static void mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb);
#endif //FreeBSD_version >= 900026
@@ -246,6 +243,8 @@ mprsas_alloc_tm(struct mpr_softc *sc)
void
mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm)
{
+ int target_id = 0xFFFFFFFF;
+
MPR_FUNCTRACE(sc);
if (tm == NULL)
return;
@@ -257,10 +256,11 @@ mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm)
*/
if (tm->cm_targ != NULL) {
tm->cm_targ->flags &= ~MPRSAS_TARGET_INRESET;
+ target_id = tm->cm_targ->tid;
}
if (tm->cm_ccb) {
mpr_dprint(sc, MPR_INFO, "Unfreezing devq for target ID %d\n",
- tm->cm_targ->tid);
+ target_id);
xpt_release_devq(tm->cm_ccb->ccb_h.path, 1, TRUE);
xpt_free_path(tm->cm_ccb->ccb_h.path);
xpt_free_ccb(tm->cm_ccb);
@@ -375,15 +375,14 @@ mprsas_remove_volume(struct mpr_softc *sc, struct mpr_command *tm)
return;
}
- if (reply->IOCStatus != MPI2_IOCSTATUS_SUCCESS) {
- mpr_dprint(sc, MPR_FAULT, "IOCStatus = 0x%x while resetting "
- "device 0x%x\n", reply->IOCStatus, handle);
- mprsas_free_tm(sc, tm);
- return;
+ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) !=
+ MPI2_IOCSTATUS_SUCCESS) {
+ mpr_dprint(sc, MPR_ERROR, "IOCStatus = 0x%x while resetting "
+ "device 0x%x\n", le16toh(reply->IOCStatus), handle);
}
mpr_dprint(sc, MPR_XINFO, "Reset aborted %u commands\n",
- reply->TerminationCount);
+ le32toh(reply->TerminationCount));
mpr_free_reply(sc, tm->cm_reply_data);
tm->cm_reply = NULL; /* Ensures the reply won't get re-freed */
@@ -396,7 +395,8 @@ mprsas_remove_volume(struct mpr_softc *sc, struct mpr_command *tm)
* this target id if possible, and so we can assign the same target id
* to this device if it comes back in the future.
*/
- if (reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) {
+ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) ==
+ MPI2_IOCSTATUS_SUCCESS) {
targ = tm->cm_targ;
targ->handle = 0x0;
targ->encl_handle = 0x0;
@@ -564,8 +564,6 @@ mprsas_remove_device(struct mpr_softc *sc, struct mpr_command *tm)
mpr_dprint(sc, MPR_ERROR, "%s: cm_flags = %#x for remove of "
"handle %#04x! This should not happen!\n", __func__,
tm->cm_flags, handle);
- mprsas_free_tm(sc, tm);
- return;
}
if (reply == NULL) {
@@ -576,11 +574,10 @@ mprsas_remove_device(struct mpr_softc *sc, struct mpr_command *tm)
return;
}
- if (le16toh(reply->IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
- mpr_dprint(sc, MPR_FAULT, "IOCStatus = 0x%x while resetting "
+ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) !=
+ MPI2_IOCSTATUS_SUCCESS) {
+ mpr_dprint(sc, MPR_ERROR, "IOCStatus = 0x%x while resetting "
"device 0x%x\n", le16toh(reply->IOCStatus), handle);
- mprsas_free_tm(sc, tm);
- return;
}
mpr_dprint(sc, MPR_XINFO, "Reset aborted %u commands\n",
@@ -661,7 +658,8 @@ mprsas_remove_complete(struct mpr_softc *sc, struct mpr_command *tm)
* this target id if possible, and so we can assign the same target id
* to this device if it comes back in the future.
*/
- if (le16toh(reply->IOCStatus) == MPI2_IOCSTATUS_SUCCESS) {
+ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) ==
+ MPI2_IOCSTATUS_SUCCESS) {
targ = tm->cm_targ;
targ->handle = 0x0;
targ->encl_handle = 0x0;
@@ -707,6 +705,7 @@ mprsas_register_events(struct mpr_softc *sc)
setbit(events, MPI2_EVENT_IR_PHYSICAL_DISK);
setbit(events, MPI2_EVENT_IR_OPERATION_STATUS);
setbit(events, MPI2_EVENT_TEMP_THRESHOLD);
+ setbit(events, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
mpr_register_events(sc, events, mprsas_evt_handler, NULL,
&sc->sassc->mprsas_eh);
@@ -926,7 +925,6 @@ mpr_detach_sas(struct mpr_softc *sc)
cam_sim_free(sassc->sim, FALSE);
}
- sassc->flags |= MPRSAS_SHUTDOWN;
mpr_unlock(sc);
if (sassc->devq != NULL)
@@ -1065,15 +1063,15 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb)
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
break;
case XPT_RESET_DEV:
- mpr_dprint(sassc->sc, MPR_XINFO,
- "mprsas_action XPT_RESET_DEV\n");
+ mpr_dprint(sassc->sc, MPR_XINFO, "mprsas_action "
+ "XPT_RESET_DEV\n");
mprsas_action_resetdev(sassc, ccb);
return;
case XPT_RESET_BUS:
case XPT_ABORT:
case XPT_TERM_IO:
- mpr_dprint(sassc->sc, MPR_XINFO,
- "mprsas_action faking success for abort or reset\n");
+ mpr_dprint(sassc->sc, MPR_XINFO, "mprsas_action faking success "
+ "for abort or reset\n");
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
break;
case XPT_SCSI_IO:
@@ -1134,8 +1132,8 @@ mprsas_complete_all_commands(struct mpr_softc *sc)
if (cm->cm_complete != NULL) {
mprsas_log_command(cm, MPR_RECOVERY,
- "completing cm %p state %x ccb %p for diag "
- "reset\n", cm, cm->cm_state, cm->cm_ccb);
+ "completing cm %p state %x ccb %p for diag reset\n",
+ cm, cm->cm_state, cm->cm_ccb);
cm->cm_complete(sc, cm);
completed = 1;
}
@@ -1216,14 +1214,13 @@ mprsas_tm_timeout(void *data)
mtx_assert(&sc->mpr_mtx, MA_OWNED);
- mprsas_log_command(tm, MPR_INFO|MPR_RECOVERY,
- "task mgmt %p timed out\n", tm);
+ mprsas_log_command(tm, MPR_INFO|MPR_RECOVERY, "task mgmt %p timed "
+ "out\n", tm);
mpr_reinit(sc);
}
static void
-mprsas_logical_unit_reset_complete(struct mpr_softc *sc,
- struct mpr_command *tm)
+mprsas_logical_unit_reset_complete(struct mpr_softc *sc, struct mpr_command *tm)
{
MPI2_SCSI_TASK_MANAGE_REPLY *reply;
MPI2_SCSI_TASK_MANAGE_REQUEST *req;
@@ -1250,8 +1247,8 @@ mprsas_logical_unit_reset_complete(struct mpr_softc *sc,
}
if (reply == NULL) {
- mprsas_log_command(tm, MPR_RECOVERY,
- "NULL reset reply for tm %p\n", tm);
+ mprsas_log_command(tm, MPR_RECOVERY, "NULL reset reply for tm "
+ "%p\n", tm);
if ((sc->mpr_flags & MPR_FLAGS_DIAGRESET) != 0) {
/* this completion was due to a reset, just cleanup */
targ->tm = NULL;
@@ -1338,8 +1335,8 @@ mprsas_target_reset_complete(struct mpr_softc *sc, struct mpr_command *tm)
}
if (reply == NULL) {
- mprsas_log_command(tm, MPR_RECOVERY,
- "NULL reset reply for tm %p\n", tm);
+ mprsas_log_command(tm, MPR_RECOVERY, "NULL reset reply for tm "
+ "%p\n", tm);
if ((sc->mpr_flags & MPR_FLAGS_DIAGRESET) != 0) {
/* this completion was due to a reset, just cleanup */
targ->tm = NULL;
@@ -1626,9 +1623,8 @@ mprsas_scsiio_timeout(void *data)
targ = cm->cm_targ;
targ->timeouts++;
- mprsas_log_command(cm, MPR_ERROR, "command timeout cm %p ccb %p "
- "target %u, handle(0x%04x)\n", cm, cm->cm_ccb, targ->tid,
- targ->handle);
+ mprsas_log_command(cm, MPR_ERROR, "command timeout cm %p ccb %p target "
+ "%u, handle(0x%04x)\n", cm, cm->cm_ccb, targ->tid, targ->handle);
if (targ->encl_level_valid) {
mpr_dprint(sc, MPR_ERROR, "At enclosure level %d, slot %d, "
"connector name (%4s)\n", targ->encl_level, targ->encl_slot,
@@ -1666,8 +1662,8 @@ mprsas_scsiio_timeout(void *data)
* more credits than disks in an enclosure, and limit
* ourselves to one TM per target for recovery.
*/
- mpr_dprint(sc, MPR_RECOVERY,
- "timedout cm %p failed to allocate a tm\n", cm);
+ mpr_dprint(sc, MPR_RECOVERY, "timedout cm %p failed to "
+ "allocate a tm\n", cm);
}
}
@@ -1927,8 +1923,13 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
cm->cm_desc.SCSIIO.DevHandle = htole16(targ->handle);
}
+#if __FreeBSD_version >= 1000029
callout_reset_sbt(&cm->cm_callout, SBT_1MS * ccb->ccb_h.timeout, 0,
mprsas_scsiio_timeout, cm, 0);
+#else //__FreeBSD_version < 1000029
+ callout_reset(&cm->cm_callout, (ccb->ccb_h.timeout * hz) / 1000,
+ mprsas_scsiio_timeout, cm);
+#endif //__FreeBSD_version >= 1000029
targ->issued++;
targ->outstanding++;
@@ -2053,6 +2054,9 @@ mpr_sc_failed_io_info(struct mpr_softc *sc, struct ccb_scsiio *csio,
case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
desc_ioc_state = "eedp app tag error";
break;
+ case MPI2_IOCSTATUS_INSUFFICIENT_POWER:
+ desc_ioc_state = "insufficient power";
+ break;
default:
desc_ioc_state = "unknown";
break;
@@ -2465,11 +2469,20 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
/*
- * Since these are generally external (i.e. hopefully
- * transient transport-related) errors, retry these without
- * decrementing the retry count.
+ * These can sometimes be transient transport-related
+ * errors, and sometimes persistent drive-related errors.
+ * We used to retry these without decrementing the retry
+ * count by returning CAM_REQUEUE_REQ. Unfortunately, if
+ * we hit a persistent drive problem that returns one of
+ * these error codes, we would retry indefinitely. So,
+ * return CAM_REQ_CMP_ERROR so that we decrement the retry
+ * count and avoid infinite retries. We're taking the
+ * potential risk of flagging false failures in the event
+ * of a topology-related error (e.g. a SAS expander problem
+ * causes a command addressed to a drive to fail), but
+ * avoiding getting into an infinite retry loop.
*/
- mprsas_set_ccbstatus(ccb, CAM_REQUEUE_REQ);
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
mprsas_log_command(cm, MPR_INFO,
"terminated ioc %x scsi %x state %x xfer %u\n",
le16toh(rep->IOCStatus), rep->SCSIStatus, rep->SCSIState,
@@ -2578,8 +2591,7 @@ bailout:
}
static void
-mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
- uint64_t sasaddr)
+mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb, uint64_t sasaddr)
{
struct mpr_command *cm;
uint8_t *request, *response;
@@ -2612,9 +2624,9 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
*/
if ((ccb->smpio.smp_request_sglist_cnt > 1)
|| (ccb->smpio.smp_response_sglist_cnt > 1)) {
- mpr_dprint(sc, MPR_ERROR,
- "%s: multiple request or response buffer segments "
- "not supported for SMP\n", __func__);
+ mpr_dprint(sc, MPR_ERROR, "%s: multiple request or "
+ "response buffer segments not supported for SMP\n",
+ __func__);
mprsas_set_ccbstatus(ccb, CAM_REQ_INVALID);
xpt_done(ccb);
return;
@@ -2715,8 +2727,8 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
cm = mpr_alloc_command(sc);
if (cm == NULL) {
- mpr_dprint(sc, MPR_ERROR,
- "%s: cannot allocate command\n", __func__);
+ mpr_dprint(sc, MPR_ERROR, "%s: cannot allocate command\n",
+ __func__);
mprsas_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL);
xpt_done(ccb);
return;
@@ -2949,14 +2961,13 @@ mprsas_action_resetdev(struct mprsas_softc *sassc, union ccb *ccb)
MPR_FUNCTRACE(sassc->sc);
mtx_assert(&sassc->sc->mpr_mtx, MA_OWNED);
- KASSERT(ccb->ccb_h.target_id < sassc->maxtargets,
- ("Target %d out of bounds in XPT_RESET_DEV\n",
- ccb->ccb_h.target_id));
+ KASSERT(ccb->ccb_h.target_id < sassc->maxtargets, ("Target %d out of "
+ "bounds in XPT_RESET_DEV\n", ccb->ccb_h.target_id));
sc = sassc->sc;
tm = mpr_alloc_command(sc);
if (tm == NULL) {
- mpr_dprint(sc, MPR_ERROR,
- "command alloc failure in mprsas_action_resetdev\n");
+ mpr_dprint(sc, MPR_ERROR, "command alloc failure in "
+ "mprsas_action_resetdev\n");
mprsas_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL);
xpt_done(ccb);
return;
@@ -3014,9 +3025,8 @@ mprsas_resetdev_complete(struct mpr_softc *sc, struct mpr_command *tm)
goto bailout;
}
- mpr_dprint(sc, MPR_XINFO,
- "%s: IOCStatus = 0x%x ResponseCode = 0x%x\n", __func__,
- le16toh(resp->IOCStatus), le32toh(resp->ResponseCode));
+ mpr_dprint(sc, MPR_XINFO, "%s: IOCStatus = 0x%x ResponseCode = 0x%x\n",
+ __func__, le16toh(resp->IOCStatus), le32toh(resp->ResponseCode));
if (le32toh(resp->ResponseCode) == MPI2_SCSITASKMGMT_RSP_TM_COMPLETE) {
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
@@ -3205,8 +3215,8 @@ mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path,
targetid = xpt_path_target_id(path);
lunid = xpt_path_lun_id(path);
- KASSERT(targetid < sassc->maxtargets,
- ("Target %d out of bounds in mprsas_check_eedp\n", targetid));
+ KASSERT(targetid < sassc->maxtargets, ("Target %d out of bounds in "
+ "mprsas_check_eedp\n", targetid));
target = &sassc->targets[targetid];
if (target->handle == 0x0)
return;
@@ -3216,7 +3226,7 @@ mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path,
*
* If this flag is set in the inquiry data, the device supports
* protection information, and must support the 16 byte read capacity
- * command, otherwise continue without sending read cap 16
+ * command, otherwise continue without sending read cap 16.
*/
if ((cgd->inq_data.spc3_flags & SPC3_SID_PROTECT) == 0)
return;
@@ -3232,10 +3242,10 @@ mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path,
return;
}
- if (xpt_create_path(&local_path, xpt_periph, pathid, targetid, lunid)
- != CAM_REQ_CMP) {
+ if (xpt_create_path(&local_path, xpt_periph, pathid, targetid, lunid) !=
+ CAM_REQ_CMP) {
mpr_dprint(sc, MPR_ERROR, "Unable to create path for EEDP "
- "support\n");
+ "support.\n");
xpt_free_ccb(ccb);
return;
}
@@ -3337,9 +3347,8 @@ mprsas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb)
* target.
*/
sassc = (struct mprsas_softc *)done_ccb->ccb_h.ppriv_ptr1;
- KASSERT(done_ccb->ccb_h.target_id < sassc->maxtargets,
- ("Target %d out of bounds in mprsas_read_cap_done\n",
- done_ccb->ccb_h.target_id));
+ KASSERT(done_ccb->ccb_h.target_id < sassc->maxtargets, ("Target %d out "
+ "of bounds in mprsas_read_cap_done\n", done_ccb->ccb_h.target_id));
target = &sassc->targets[done_ccb->ccb_h.target_id];
SLIST_FOREACH(lun, &target->luns, lun_link) {
if (lun->lun_id != done_ccb->ccb_h.target_lun)
diff --git a/sys/dev/mpr/mpr_sas.h b/sys/dev/mpr/mpr_sas.h
index ebeed30..614b5fe 100644
--- a/sys/dev/mpr/mpr_sas.h
+++ b/sys/dev/mpr/mpr_sas.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/mpr/mpr_sas_lsi.c b/sys/dev/mpr/mpr_sas_lsi.c
index f162d1f..640338a 100644
--- a/sys/dev/mpr/mpr_sas_lsi.c
+++ b/sys/dev/mpr/mpr_sas_lsi.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-/* Communications core for LSI MPT3 */
+/* Communications core for Avago Technologies (LSI) MPT3 */
/* TODO Move headers to mprvar */
#include <sys/types.h>
@@ -252,8 +252,7 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
data = (MPI2_EVENT_DATA_SAS_DISCOVERY *)fw_event->event_data;
if (data->ReasonCode & MPI2_EVENT_SAS_DISC_RC_STARTED)
- mpr_dprint(sc, MPR_TRACE,"SAS discovery start "
- "event\n");
+ mpr_dprint(sc, MPR_TRACE,"SAS discovery start event\n");
if (data->ReasonCode & MPI2_EVENT_SAS_DISC_RC_COMPLETED) {
mpr_dprint(sc, MPR_TRACE,"SAS discovery stop event\n");
sassc->flags &= ~MPRSAS_IN_DISCOVERY;
@@ -646,6 +645,23 @@ skip_fp_send:
}
break;
}
+ case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
+ {
+ pMpi26EventDataActiveCableExcept_t ace_event_data;
+ ace_event_data =
+ (pMpi26EventDataActiveCableExcept_t)fw_event->event_data;
+
+ if (ace_event_data->ReasonCode ==
+ MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) {
+ mpr_printf(sc, "Currently an active cable with "
+ "ReceptacleID %d cannot be powered and device "
+ "connected to this active cable will not be seen. "
+ "This active cable requires %d mW of power.\n",
+ ace_event_data->ReceptacleID,
+ ace_event_data->ActiveCablePowerRequirement);
+ }
+ break;
+ }
case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
default:
@@ -839,8 +855,8 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
} else {
mpr_dprint(sc, MPR_ERROR, "Failed to allocate "
- "tm for Target Reset after SATA ID "
- "command timed out (cm %p)\n", cm);
+ "tm for Target Reset after SATA ID command "
+ "timed out (cm %p)\n", cm);
}
/*
* No need to check for more since the target is
@@ -901,9 +917,8 @@ mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc,
}
}
} while (((rc && (rc != EWOULDBLOCK)) ||
- (ioc_status &&
- (ioc_status != MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR))
- || sas_status) && (try_count < 5));
+ (ioc_status && (ioc_status != MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR))
+ || sas_status) && (try_count < 5));
if (rc == 0 && !ioc_status && !sas_status) {
mpr_dprint(sc, MPR_MAPPING, "%s: got SATA identify "
@@ -1059,8 +1074,8 @@ mprsas_ata_id_timeout(void *data)
__func__, cm, sc);
if ((callout_pending(&cm->cm_callout)) ||
(!callout_active(&cm->cm_callout))) {
- mpr_dprint(sc, MPR_INFO, "%s ATA ID command almost timed "
- "out\n", __func__);
+ mpr_dprint(sc, MPR_INFO, "%s ATA ID command almost timed out\n",
+ __func__);
return;
}
callout_deactivate(&cm->cm_callout);
@@ -1072,21 +1087,21 @@ mprsas_ata_id_timeout(void *data)
*/
mpr_intr_locked(sc);
if (cm->cm_state == MPR_CM_STATE_FREE) {
- mpr_dprint(sc, MPR_INFO, "%s ATA ID command almost timed "
- "out\n", __func__);
+ mpr_dprint(sc, MPR_INFO, "%s ATA ID command almost timed out\n",
+ __func__);
return;
}
mpr_dprint(sc, MPR_INFO, "ATA ID command timeout cm %p\n", cm);
/*
- * Send wakeup() to the sleeping thread that issued this ATA ID
- * command. wakeup() will cause msleep to return a 0 (not EWOULDBLOCK),
- * and this will keep reinit() from being called. This way, an Abort
- * Task TM can be issued so that the timed out command can be cleared.
- * The Abort Task cannot be sent from here because the driver has not
- * completed setting up targets. Instead, the command is flagged so
- * that special handling will be used to send the abort.
+ * Send wakeup() to the sleeping thread that issued this ATA ID command.
+ * wakeup() will cause msleep to return a 0 (not EWOULDBLOCK), and this
+ * will keep reinit() from being called. This way, an Abort Task TM can
+ * be issued so that the timed out command can be cleared. The Abort
+ * Task cannot be sent from here because the driver has not completed
+ * setting up targets. Instead, the command is flagged so that special
+ * handling will be used to send the abort.
*/
cm->cm_flags |= MPR_CM_FLAGS_SATA_ID_TIMEOUT;
wakeup(cm);
@@ -1257,15 +1272,15 @@ mprsas_stop_unit_done(struct cam_periph *periph, union ccb *done_ccb)
struct mprsas_softc *sassc;
char path_str[64];
+ if (done_ccb == NULL)
+ return;
+
sassc = (struct mprsas_softc *)done_ccb->ccb_h.ppriv_ptr1;
xpt_path_string(done_ccb->ccb_h.path, path_str, sizeof(path_str));
mpr_dprint(sassc->sc, MPR_INFO, "Completing stop unit for %s\n",
path_str);
- if (done_ccb == NULL)
- return;
-
/*
* Nothing more to do except free the CCB and path. If the command
* timed out, an abort reset, then target reset will be issued during
diff --git a/sys/dev/mpr/mpr_table.c b/sys/dev/mpr/mpr_table.c
index 6e7797e..6ec6492 100644
--- a/sys/dev/mpr/mpr_table.c
+++ b/sys/dev/mpr/mpr_table.c
@@ -342,9 +342,8 @@ mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
"PHY[%d].LinkRate: %s (0x%x)\n", phynum,
mpr_describe_table(mpr_linkrate_names,
(phy->LinkRate >> 4) & 0xf), phy->LinkRate);
- mpr_dprint_field(sc,MPR_EVENT,"PHY[%d].PhyStatus: "
- "%s\n", phynum,
- mpr_describe_table(mpr_phystatus_names,
+ mpr_dprint_field(sc,MPR_EVENT,"PHY[%d].PhyStatus: %s\n",
+ phynum, mpr_describe_table(mpr_phystatus_names,
phy->PhyStatus));
}
break;
diff --git a/sys/dev/mpr/mpr_user.c b/sys/dev/mpr/mpr_user.c
index 37d9467..db8de93 100644
--- a/sys/dev/mpr/mpr_user.c
+++ b/sys/dev/mpr/mpr_user.c
@@ -31,7 +31,7 @@
*/
/*-
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -130,24 +130,23 @@ static mpr_user_f mpi_pre_config;
static mpr_user_f mpi_pre_sas_io_unit_control;
static int mpr_user_read_cfg_header(struct mpr_softc *,
- struct mpr_cfg_page_req *);
+ struct mpr_cfg_page_req *);
static int mpr_user_read_cfg_page(struct mpr_softc *,
- struct mpr_cfg_page_req *, void *);
+ struct mpr_cfg_page_req *, void *);
static int mpr_user_read_extcfg_header(struct mpr_softc *,
- struct mpr_ext_cfg_page_req *);
+ struct mpr_ext_cfg_page_req *);
static int mpr_user_read_extcfg_page(struct mpr_softc *,
- struct mpr_ext_cfg_page_req *, void *);
+ struct mpr_ext_cfg_page_req *, void *);
static int mpr_user_write_cfg_page(struct mpr_softc *,
- struct mpr_cfg_page_req *, void *);
+ struct mpr_cfg_page_req *, void *);
static int mpr_user_setup_request(struct mpr_command *,
- struct mpr_usr_command *);
+ struct mpr_usr_command *);
static int mpr_user_command(struct mpr_softc *, struct mpr_usr_command *);
static int mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data);
static void mpr_user_get_adapter_data(struct mpr_softc *sc,
mpr_adapter_data_t *data);
-static void mpr_user_read_pci_info(struct mpr_softc *sc,
- mpr_pci_info_t *data);
+static void mpr_user_read_pci_info(struct mpr_softc *sc, mpr_pci_info_t *data);
static uint8_t mpr_get_fw_diag_buffer_number(struct mpr_softc *sc,
uint32_t unique_id);
static int mpr_post_fw_diag_buffer(struct mpr_softc *sc,
@@ -159,8 +158,8 @@ static int mpr_diag_register(struct mpr_softc *sc,
mpr_fw_diag_register_t *diag_register, uint32_t *return_code);
static int mpr_diag_unregister(struct mpr_softc *sc,
mpr_fw_diag_unregister_t *diag_unregister, uint32_t *return_code);
-static int mpr_diag_query(struct mpr_softc *sc,
- mpr_fw_diag_query_t *diag_query, uint32_t *return_code);
+static int mpr_diag_query(struct mpr_softc *sc, mpr_fw_diag_query_t *diag_query,
+ uint32_t *return_code);
static int mpr_diag_read_buffer(struct mpr_softc *sc,
mpr_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
uint32_t *return_code);
@@ -168,10 +167,8 @@ static int mpr_diag_release(struct mpr_softc *sc,
mpr_fw_diag_release_t *diag_release, uint32_t *return_code);
static int mpr_do_diag_action(struct mpr_softc *sc, uint32_t action,
uint8_t *diag_action, uint32_t length, uint32_t *return_code);
-static int mpr_user_diag_action(struct mpr_softc *sc,
- mpr_diag_action_t *data);
-static void mpr_user_event_query(struct mpr_softc *sc,
- mpr_event_query_t *data);
+static int mpr_user_diag_action(struct mpr_softc *sc, mpr_diag_action_t *data);
+static void mpr_user_event_query(struct mpr_softc *sc, mpr_event_query_t *data);
static void mpr_user_event_enable(struct mpr_softc *sc,
mpr_event_enable_t *data);
static int mpr_user_event_report(struct mpr_softc *sc,
@@ -212,11 +209,12 @@ mpr_attach_user(struct mpr_softc *sc)
int unit;
unit = device_get_unit(sc->mpr_dev);
- sc->mpr_cdev = make_dev(&mpr_cdevsw, unit, UID_ROOT, GID_OPERATOR,
- 0640, "mpr%d", unit);
- if (sc->mpr_cdev == NULL) {
+ sc->mpr_cdev = make_dev(&mpr_cdevsw, unit, UID_ROOT, GID_OPERATOR, 0640,
+ "mpr%d", unit);
+
+ if (sc->mpr_cdev == NULL)
return (ENOMEM);
- }
+
sc->mpr_cdev->si_drv1 = sc;
return (0);
}
@@ -284,8 +282,8 @@ mpr_user_read_cfg_header(struct mpr_softc *sc,
}
static int
-mpr_user_read_cfg_page(struct mpr_softc *sc,
- struct mpr_cfg_page_req *page_req, void *buf)
+mpr_user_read_cfg_page(struct mpr_softc *sc, struct mpr_cfg_page_req *page_req,
+ void *buf)
{
MPI2_CONFIG_PAGE_HEADER *reqhdr, *hdr;
struct mpr_config_params params;
@@ -1257,12 +1255,14 @@ mpr_post_fw_diag_buffer(struct mpr_softc *sc,
* Process POST reply.
*/
reply = (MPI2_DIAG_BUFFER_POST_REPLY *)cm->cm_reply;
- if (reply->IOCStatus != MPI2_IOCSTATUS_SUCCESS) {
+ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) !=
+ MPI2_IOCSTATUS_SUCCESS) {
status = MPR_DIAG_FAILURE;
mpr_dprint(sc, MPR_FAULT, "%s: post of FW Diag Buffer failed "
"with IOCStatus = 0x%x, IOCLogInfo = 0x%x and "
- "TransferLength = 0x%x\n", __func__, reply->IOCStatus,
- reply->IOCLogInfo, reply->TransferLength);
+ "TransferLength = 0x%x\n", __func__,
+ le16toh(reply->IOCStatus), le32toh(reply->IOCLogInfo),
+ le32toh(reply->TransferLength));
goto done;
}
@@ -1341,12 +1341,13 @@ mpr_release_fw_diag_buffer(struct mpr_softc *sc,
* Process RELEASE reply.
*/
reply = (MPI2_DIAG_RELEASE_REPLY *)cm->cm_reply;
- if ((reply->IOCStatus != MPI2_IOCSTATUS_SUCCESS) ||
- pBuffer->owned_by_firmware) {
+ if (((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) !=
+ MPI2_IOCSTATUS_SUCCESS) || pBuffer->owned_by_firmware) {
status = MPR_DIAG_FAILURE;
mpr_dprint(sc, MPR_FAULT, "%s: release of FW Diag Buffer "
"failed with IOCStatus = 0x%x and IOCLogInfo = 0x%x\n",
- __func__, reply->IOCStatus, reply->IOCLogInfo);
+ __func__, le16toh(reply->IOCStatus),
+ le32toh(reply->IOCLogInfo));
goto done;
}
@@ -1718,8 +1719,8 @@ mpr_diag_release(struct mpr_softc *sc, mpr_fw_diag_release_t *diag_release,
}
static int
-mpr_do_diag_action(struct mpr_softc *sc, uint32_t action,
- uint8_t *diag_action, uint32_t length, uint32_t *return_code)
+mpr_do_diag_action(struct mpr_softc *sc, uint32_t action, uint8_t *diag_action,
+ uint32_t length, uint32_t *return_code)
{
mpr_fw_diag_register_t diag_register;
mpr_fw_diag_unregister_t diag_unregister;
diff --git a/sys/dev/mpr/mprvar.h b/sys/dev/mpr/mprvar.h
index 306324b..dd4b40f 100644
--- a/sys/dev/mpr/mprvar.h
+++ b/sys/dev/mpr/mprvar.h
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2009 Yahoo! Inc.
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
#ifndef _MPRVAR_H
#define _MPRVAR_H
-#define MPR_DRIVER_VERSION "09.255.01.00-fbsd"
+#define MPR_DRIVER_VERSION "13.00.00.00-fbsd"
#define MPR_DB_MAX_WAIT 2500
@@ -46,6 +46,8 @@
#define MPR_SGE64_SIZE 12
#define MPR_SGE32_SIZE 8
#define MPR_SGC_SIZE 8
+#define MPR_DEFAULT_CHAIN_SEG_SIZE 8
+#define MPR_MAX_CHAIN_ELEMENT_SIZE 16
#define MPR_FUNCTRACE(sc) \
mpr_dprint((sc), MPR_TRACE, "%s\n", __func__)
@@ -263,6 +265,8 @@ struct mpr_softc {
int chain_free;
int max_chains;
int chain_free_lowwater;
+ uint32_t chain_frame_size;
+ uint16_t chain_seg_size;
u_int enable_ssu;
int spinup_wait_time;
uint64_t chain_alloc_fail;
@@ -585,13 +589,13 @@ do { \
#define mpr_dprint(sc, level, msg, args...) \
do { \
- if ((sc)->mpr_debug & level) \
+ if ((sc)->mpr_debug & (level)) \
device_printf((sc)->mpr_dev, msg, ##args); \
} while (0)
#define mpr_dprint_field(sc, level, msg, args...) \
do { \
- if ((sc)->mpr_debug & level) \
+ if ((sc)->mpr_debug & (level)) \
printf("\t" msg, ##args); \
} while (0)
@@ -653,8 +657,7 @@ void mpr_intr_locked(void *);
int mpr_register_events(struct mpr_softc *, uint8_t *, mpr_evt_callback_t *,
void *, struct mpr_event_handle **);
int mpr_restart(struct mpr_softc *);
-int mpr_update_events(struct mpr_softc *, struct mpr_event_handle *,
- uint8_t *);
+int mpr_update_events(struct mpr_softc *, struct mpr_event_handle *, uint8_t *);
int mpr_deregister_events(struct mpr_softc *, struct mpr_event_handle *);
int mpr_push_sge(struct mpr_command *, MPI2_SGE_SIMPLE64 *, size_t, int);
int mpr_push_ieee_sge(struct mpr_command *, void *, int);
@@ -671,8 +674,8 @@ void mprsas_record_event(struct mpr_softc *sc,
MPI2_EVENT_NOTIFICATION_REPLY *event_reply);
int mpr_map_command(struct mpr_softc *sc, struct mpr_command *cm);
-int mpr_wait_command(struct mpr_softc *sc, struct mpr_command *cm,
- int timeout, int sleep_flag);
+int mpr_wait_command(struct mpr_softc *sc, struct mpr_command *cm, int timeout,
+ int sleep_flag);
int mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm);
int mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t
@@ -727,11 +730,10 @@ void mpr_mapping_ir_config_change_event(struct mpr_softc *sc,
void mprsas_evt_handler(struct mpr_softc *sc, uintptr_t data,
MPI2_EVENT_NOTIFICATION_REPLY *event);
void mprsas_prepare_remove(struct mprsas_softc *sassc, uint16_t handle);
-void mprsas_prepare_volume_remove(struct mprsas_softc *sassc,
- uint16_t handle);
+void mprsas_prepare_volume_remove(struct mprsas_softc *sassc, uint16_t handle);
int mprsas_startup(struct mpr_softc *sc);
-struct mprsas_target * mprsas_find_target_by_handle(struct mprsas_softc *,
- int, uint16_t);
+struct mprsas_target * mprsas_find_target_by_handle(struct mprsas_softc *, int,
+ uint16_t);
void mprsas_realloc_targets(struct mpr_softc *sc, int maxtargets);
struct mpr_command * mprsas_alloc_tm(struct mpr_softc *sc);
void mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm);
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index a4dd3e1..3790e8f 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -2408,11 +2408,20 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
/*
- * Since these are generally external (i.e. hopefully
- * transient transport-related) errors, retry these without
- * decrementing the retry count.
+ * These can sometimes be transient transport-related
+ * errors, and sometimes persistent drive-related errors.
+ * We used to retry these without decrementing the retry
+ * count by returning CAM_REQUEUE_REQ. Unfortunately, if
+ * we hit a persistent drive problem that returns one of
+ * these error codes, we would retry indefinitely. So,
+ * return CAM_REQ_CMP_ERROR so that we decrement the retry
+ * count and avoid infinite retries. We're taking the
+ * potential risk of flagging false failures in the event
+ * of a topology-related error (e.g. a SAS expander problem
+ * causes a command addressed to a drive to fail), but
+ * avoiding getting into an infinite retry loop.
*/
- mpssas_set_ccbstatus(ccb, CAM_REQUEUE_REQ);
+ mpssas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
mpssas_log_command(cm, MPS_INFO,
"terminated ioc %x scsi %x state %x xfer %u\n",
le16toh(rep->IOCStatus), rep->SCSIStatus, rep->SCSIState,
diff --git a/sys/dev/nvram2env/nvram2env.c b/sys/dev/nvram2env/nvram2env.c
index 608fac6..4c0ce1e 100644
--- a/sys/dev/nvram2env/nvram2env.c
+++ b/sys/dev/nvram2env/nvram2env.c
@@ -127,7 +127,7 @@ nvram2env_probe(device_t dev)
ivar == 0)
continue;
- sc->addr = MIPS_PHYS_TO_KSEG1(ivar);
+ sc->addr = ivar;
if (bootverbose)
device_printf(dev, "base=0x%08x sig=0x%08x "
diff --git a/sys/dev/otus/if_otus.c b/sys/dev/otus/if_otus.c
index 7b069a6..f08332c 100644
--- a/sys/dev/otus/if_otus.c
+++ b/sys/dev/otus/if_otus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_otus.c,v 1.46 2015/03/14 03:38:49 jsg Exp $ */
+/* $OpenBSD: if_otus.c,v 1.49 2015/11/24 13:33:18 mpi Exp $ */
/*-
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <net/if_arp.h>
#include <net/if_dl.h>
#include <net/if_media.h>
-#include <net/if_types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 630aaa9..3c998b4 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -5427,7 +5427,8 @@ pci_child_location_str_method(device_t dev, device_t child, char *buf,
size_t buflen)
{
- snprintf(buf, buflen, "pci%d:%d:%d:%d", pci_get_domain(child),
+ snprintf(buf, buflen, "slot=%d function=%d dbsf=pci%d:%d:%d:%d",
+ pci_get_slot(child), pci_get_function(child), pci_get_domain(child),
pci_get_bus(child), pci_get_slot(child), pci_get_function(child));
return (0);
}
@@ -5643,6 +5644,11 @@ pci_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
pci_resume_msi(dev);
if (dinfo->cfg.msix.msix_location != 0)
pci_resume_msix(dev);
+
+#ifdef PCI_IOV
+ if (dinfo->cfg.iov != NULL)
+ pci_iov_cfg_restore(dev, dinfo);
+#endif
}
static void
@@ -5755,6 +5761,11 @@ pci_cfg_save(device_t dev, struct pci_devinfo *dinfo, int setstate)
if (dinfo->cfg.pcix.pcix_location != 0)
pci_cfg_save_pcix(dev, dinfo);
+#ifdef PCI_IOV
+ if (dinfo->cfg.iov != NULL)
+ pci_iov_cfg_save(dev, dinfo);
+#endif
+
/*
* don't set the state for display devices, base peripherals and
* memory devices since bad things happen when they are powered down.
diff --git a/sys/dev/pci/pci_iov.c b/sys/dev/pci/pci_iov.c
index 287f5a2..bba99f6 100644
--- a/sys/dev/pci/pci_iov.c
+++ b/sys/dev/pci/pci_iov.c
@@ -442,6 +442,7 @@ pci_iov_set_ari(device_t bus)
}
}
}
+ free(devlist, M_TEMP);
/*
* If we called this function some device must have the SR-IOV
@@ -451,10 +452,14 @@ pci_iov_set_ari(device_t bus)
("Could not find child of %s with SR-IOV capability",
device_get_nameunit(bus)));
- iov_ctl = pci_read_config(lowest, iov_pos + PCIR_SRIOV_CTL, 2);
+ iov_ctl = pci_read_config(lowest, lowest_pos + PCIR_SRIOV_CTL, 2);
iov_ctl |= PCIM_SRIOV_ARI_EN;
- pci_write_config(lowest, iov_pos + PCIR_SRIOV_CTL, iov_ctl, 2);
- free(devlist, M_TEMP);
+ pci_write_config(lowest, lowest_pos + PCIR_SRIOV_CTL, iov_ctl, 2);
+ if ((pci_read_config(lowest, lowest_pos + PCIR_SRIOV_CTL, 2) &
+ PCIM_SRIOV_ARI_EN) == 0) {
+ device_printf(lowest, "failed to enable ARI\n");
+ return (ENXIO);
+ }
return (0);
}
@@ -765,6 +770,29 @@ out:
return (error);
}
+void
+pci_iov_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
+{
+ struct pcicfg_iov *iov;
+
+ iov = dinfo->cfg.iov;
+
+ IOV_WRITE(dinfo, PCIR_SRIOV_PAGE_SIZE, iov->iov_page_size, 4);
+ IOV_WRITE(dinfo, PCIR_SRIOV_NUM_VFS, iov->iov_num_vfs, 2);
+ IOV_WRITE(dinfo, PCIR_SRIOV_CTL, iov->iov_ctl, 2);
+}
+
+void
+pci_iov_cfg_save(device_t dev, struct pci_devinfo *dinfo)
+{
+ struct pcicfg_iov *iov;
+
+ iov = dinfo->cfg.iov;
+
+ iov->iov_page_size = IOV_READ(dinfo, PCIR_SRIOV_PAGE_SIZE, 4);
+ iov->iov_ctl = IOV_READ(dinfo, PCIR_SRIOV_CTL, 2);
+}
+
/* Return true if child is a VF of the given PF. */
static int
pci_iov_is_child_vf(struct pcicfg_iov *pf, device_t child)
diff --git a/sys/dev/pci/pci_iov_private.h b/sys/dev/pci/pci_iov_private.h
index 6938e2e..2d15353 100644
--- a/sys/dev/pci/pci_iov_private.h
+++ b/sys/dev/pci/pci_iov_private.h
@@ -47,10 +47,16 @@ struct pcicfg_iov {
int iov_pos;
int iov_num_vfs;
uint32_t iov_flags;
+
+ uint16_t iov_ctl;
+ uint32_t iov_page_size;
};
#define IOV_RMAN_INITED 0x0001
#define IOV_BUSY 0x0002
+void pci_iov_cfg_restore(device_t dev, struct pci_devinfo *dinfo);
+void pci_iov_cfg_save(device_t dev, struct pci_devinfo *dinfo);
+
#endif
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index 76643bc..e3539f5 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$");
* PCI:PCI bridge support.
*/
+#include "opt_pci.h"
+
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
@@ -43,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
+#include <sys/taskqueue.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
@@ -67,6 +70,11 @@ static int pcib_try_enable_ari(device_t pcib, device_t dev);
static int pcib_ari_enabled(device_t pcib);
static void pcib_ari_decode_rid(device_t pcib, uint16_t rid,
int *bus, int *slot, int *func);
+#ifdef PCI_HP
+static void pcib_pcie_ab_timeout(void *arg);
+static void pcib_pcie_cc_timeout(void *arg);
+static void pcib_pcie_dll_timeout(void *arg);
+#endif
static device_method_t pcib_methods[] = {
/* Device interface */
@@ -78,6 +86,7 @@ static device_method_t pcib_methods[] = {
DEVMETHOD(device_resume, pcib_resume),
/* Bus interface */
+ DEVMETHOD(bus_child_present, pcib_child_present),
DEVMETHOD(bus_read_ivar, pcib_read_ivar),
DEVMETHOD(bus_write_ivar, pcib_write_ivar),
DEVMETHOD(bus_alloc_resource, pcib_alloc_resource),
@@ -839,6 +848,466 @@ pcib_set_mem_decode(struct pcib_softc *sc)
}
#endif
+#ifdef PCI_HP
+/*
+ * PCI-express HotPlug support.
+ */
+static void
+pcib_probe_hotplug(struct pcib_softc *sc)
+{
+ device_t dev;
+
+ dev = sc->dev;
+ if (pci_find_cap(dev, PCIY_EXPRESS, NULL) != 0)
+ return;
+
+ if (!(pcie_read_config(dev, PCIER_FLAGS, 2) & PCIEM_FLAGS_SLOT))
+ return;
+
+ sc->pcie_link_cap = pcie_read_config(dev, PCIER_LINK_CAP, 4);
+ sc->pcie_slot_cap = pcie_read_config(dev, PCIER_SLOT_CAP, 4);
+
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_HPC)
+ sc->flags |= PCIB_HOTPLUG;
+}
+
+/*
+ * Send a HotPlug command to the slot control register. If this slot
+ * uses command completion interrupts, these updates will be buffered
+ * while a previous command is completing.
+ */
+static void
+pcib_pcie_hotplug_command(struct pcib_softc *sc, uint16_t val, uint16_t mask)
+{
+ device_t dev;
+ uint16_t ctl, new;
+
+ dev = sc->dev;
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_NCCS) {
+ ctl = pcie_read_config(dev, PCIER_SLOT_CTL, 2);
+ new = (ctl & ~mask) | val;
+ if (new != ctl)
+ pcie_write_config(dev, PCIER_SLOT_CTL, new, 2);
+ return;
+ }
+
+ if (sc->flags & PCIB_HOTPLUG_CMD_PENDING) {
+ sc->pcie_pending_link_ctl_val &= ~mask;
+ sc->pcie_pending_link_ctl_val |= val;
+ sc->pcie_pending_link_ctl_mask |= mask;
+ } else {
+ ctl = pcie_read_config(dev, PCIER_SLOT_CTL, 2);
+ new = (ctl & ~mask) | val;
+ if (new != ctl) {
+ pcie_write_config(dev, PCIER_SLOT_CTL, ctl, 2);
+ sc->flags |= PCIB_HOTPLUG_CMD_PENDING;
+ if (!cold)
+ callout_reset(&sc->pcie_cc_timer, hz,
+ pcib_pcie_cc_timeout, sc);
+ }
+ }
+}
+
+static void
+pcib_pcie_hotplug_command_completed(struct pcib_softc *sc)
+{
+ device_t dev;
+ uint16_t ctl, new;
+
+ dev = sc->dev;
+
+ if (bootverbose)
+ device_printf(dev, "Command Completed\n");
+ if (!(sc->flags & PCIB_HOTPLUG_CMD_PENDING))
+ return;
+ if (sc->pcie_pending_link_ctl_mask != 0) {
+ ctl = pcie_read_config(dev, PCIER_SLOT_CTL, 2);
+ new = ctl & ~sc->pcie_pending_link_ctl_mask;
+ new |= sc->pcie_pending_link_ctl_val;
+ if (new != ctl) {
+ pcie_write_config(dev, PCIER_SLOT_CTL, ctl, 2);
+ if (!cold)
+ callout_reset(&sc->pcie_cc_timer, hz,
+ pcib_pcie_cc_timeout, sc);
+ } else
+ sc->flags &= ~PCIB_HOTPLUG_CMD_PENDING;
+ sc->pcie_pending_link_ctl_mask = 0;
+ sc->pcie_pending_link_ctl_val = 0;
+ } else {
+ callout_stop(&sc->pcie_cc_timer);
+ sc->flags &= ~PCIB_HOTPLUG_CMD_PENDING;
+ }
+}
+
+/*
+ * Returns true if a card is fully inserted from the user's
+ * perspective. It may not yet be ready for access, but the driver
+ * can now start enabling access if necessary.
+ */
+static bool
+pcib_hotplug_inserted(struct pcib_softc *sc)
+{
+
+ /* Pretend the card isn't present if a detach is forced. */
+ if (sc->flags & PCIB_DETACHING)
+ return (false);
+
+ /* Card must be present in the slot. */
+ if ((sc->pcie_slot_sta & PCIEM_SLOT_STA_PDS) == 0)
+ return (false);
+
+ /* A power fault implicitly turns off power to the slot. */
+ if (sc->pcie_slot_sta & PCIEM_SLOT_STA_PFD)
+ return (false);
+
+ /* If the MRL is disengaged, the slot is powered off. */
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_MRLSP &&
+ (sc->pcie_slot_sta & PCIEM_SLOT_STA_MRLSS) != 0)
+ return (false);
+
+ return (true);
+}
+
+/*
+ * Returns -1 if the card is fully inserted, powered, and ready for
+ * access. Otherwise, returns 0.
+ */
+static int
+pcib_hotplug_present(struct pcib_softc *sc)
+{
+ device_t dev;
+
+ dev = sc->dev;
+
+ /* Card must be inserted. */
+ if (!pcib_hotplug_inserted(sc))
+ return (0);
+
+ /*
+ * Require the Electromechanical Interlock to be engaged if
+ * present.
+ */
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_EIP &&
+ (sc->pcie_slot_sta & PCIEM_SLOT_STA_EIS) == 0)
+ return (0);
+
+ /* Require the Data Link Layer to be active. */
+ if (sc->pcie_link_cap & PCIEM_LINK_CAP_DL_ACTIVE) {
+ if (!(sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE))
+ return (0);
+ }
+
+ return (-1);
+}
+
+static void
+pcib_pcie_hotplug_update(struct pcib_softc *sc, uint16_t val, uint16_t mask,
+ bool schedule_task)
+{
+ bool card_inserted;
+
+ /* Clear DETACHING if Present Detect has cleared. */
+ if ((sc->pcie_slot_sta & (PCIEM_SLOT_STA_PDC | PCIEM_SLOT_STA_PDS)) ==
+ PCIEM_SLOT_STA_PDC)
+ sc->flags &= ~PCIB_DETACHING;
+
+ card_inserted = pcib_hotplug_inserted(sc);
+
+ /* Turn the power indicator on if a card is inserted. */
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_PIP) {
+ mask |= PCIEM_SLOT_CTL_PIC;
+ if (card_inserted)
+ val |= PCIEM_SLOT_CTL_PI_ON;
+ else if (sc->flags & PCIB_DETACH_PENDING)
+ val |= PCIEM_SLOT_CTL_PI_BLINK;
+ else
+ val |= PCIEM_SLOT_CTL_PI_OFF;
+ }
+
+ /* Turn the power on via the Power Controller if a card is inserted. */
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_PCP) {
+ mask |= PCIEM_SLOT_CTL_PCC;
+ if (card_inserted)
+ val |= PCIEM_SLOT_CTL_PC_ON;
+ else
+ val |= PCIEM_SLOT_CTL_PC_OFF;
+ }
+
+ /*
+ * If a card is inserted, enable the Electromechanical
+ * Interlock. If a card is not inserted (or we are in the
+ * process of detaching), disable the Electromechanical
+ * Interlock.
+ */
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_EIP) {
+ if (card_inserted !=
+ !(sc->pcie_slot_sta & PCIEM_SLOT_STA_EIS)) {
+ mask |= PCIEM_SLOT_CTL_EIC;
+ val |= PCIEM_SLOT_CTL_EIC;
+ }
+ }
+
+ /*
+ * Start a timer to see if the Data Link Layer times out.
+ * Note that we only start the timer if Presence Detect
+ * changed on this interrupt. Stop any scheduled timer if
+ * the Data Link Layer is active.
+ */
+ if (sc->pcie_link_cap & PCIEM_LINK_CAP_DL_ACTIVE) {
+ if (card_inserted &&
+ !(sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE) &&
+ sc->pcie_slot_sta & PCIEM_SLOT_STA_PDC) {
+ if (cold)
+ device_printf(sc->dev,
+ "Data Link Layer inactive\n");
+ else
+ callout_reset(&sc->pcie_dll_timer, hz,
+ pcib_pcie_dll_timeout, sc);
+ } else if (sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE)
+ callout_stop(&sc->pcie_dll_timer);
+ }
+
+ pcib_pcie_hotplug_command(sc, val, mask);
+
+ /*
+ * During attach the child "pci" device is added sychronously;
+ * otherwise, the task is scheduled to manage the child
+ * device.
+ */
+ if (schedule_task &&
+ (pcib_hotplug_present(sc) != 0) != (sc->child != NULL))
+ taskqueue_enqueue(taskqueue_thread, &sc->pcie_hp_task);
+}
+
+static void
+pcib_pcie_intr(void *arg)
+{
+ struct pcib_softc *sc;
+ device_t dev;
+
+ sc = arg;
+ dev = sc->dev;
+ sc->pcie_slot_sta = pcie_read_config(dev, PCIER_SLOT_STA, 2);
+
+ /* Clear the events just reported. */
+ pcie_write_config(dev, PCIER_SLOT_STA, sc->pcie_slot_sta, 2);
+
+ if (sc->pcie_slot_sta & PCIEM_SLOT_STA_ABP) {
+ if (sc->flags & PCIB_DETACH_PENDING) {
+ device_printf(dev,
+ "Attention Button Pressed: Detach Cancelled\n");
+ sc->flags &= ~PCIB_DETACH_PENDING;
+ callout_stop(&sc->pcie_ab_timer);
+ } else {
+ device_printf(dev,
+ "Attention Button Pressed: Detaching in 5 seconds\n");
+ sc->flags |= PCIB_DETACH_PENDING;
+ callout_reset(&sc->pcie_ab_timer, 5 * hz,
+ pcib_pcie_ab_timeout, sc);
+ }
+ }
+ if (sc->pcie_slot_sta & PCIEM_SLOT_STA_PFD)
+ device_printf(dev, "Power Fault Detected\n");
+ if (sc->pcie_slot_sta & PCIEM_SLOT_STA_MRLSC)
+ device_printf(dev, "MRL Sensor Changed to %s\n",
+ sc->pcie_slot_sta & PCIEM_SLOT_STA_MRLSS ? "open" :
+ "closed");
+ if (bootverbose && sc->pcie_slot_sta & PCIEM_SLOT_STA_PDC)
+ device_printf(dev, "Present Detect Changed to %s\n",
+ sc->pcie_slot_sta & PCIEM_SLOT_STA_PDS ? "card present" :
+ "empty");
+ if (sc->pcie_slot_sta & PCIEM_SLOT_STA_CC)
+ pcib_pcie_hotplug_command_completed(sc);
+ if (sc->pcie_slot_sta & PCIEM_SLOT_STA_DLLSC) {
+ sc->pcie_link_sta = pcie_read_config(dev, PCIER_LINK_STA, 2);
+ if (bootverbose)
+ device_printf(dev,
+ "Data Link Layer State Changed to %s\n",
+ sc->pcie_link_sta & PCIEM_LINK_STA_DL_ACTIVE ?
+ "active" : "inactive");
+ }
+
+ pcib_pcie_hotplug_update(sc, 0, 0, true);
+}
+
+static void
+pcib_pcie_hotplug_task(void *context, int pending)
+{
+ struct pcib_softc *sc;
+ device_t dev;
+
+ sc = context;
+ mtx_lock(&Giant);
+ dev = sc->dev;
+ if (pcib_hotplug_present(sc) != 0) {
+ if (sc->child == NULL) {
+ sc->child = device_add_child(dev, "pci", -1);
+ bus_generic_attach(dev);
+ }
+ } else {
+ if (sc->child != NULL) {
+ if (device_delete_child(dev, sc->child) == 0)
+ sc->child = NULL;
+ }
+ }
+ mtx_unlock(&Giant);
+}
+
+static void
+pcib_pcie_ab_timeout(void *arg)
+{
+ struct pcib_softc *sc;
+ device_t dev;
+
+ sc = arg;
+ dev = sc->dev;
+ mtx_assert(&Giant, MA_OWNED);
+ if (sc->flags & PCIB_DETACH_PENDING) {
+ sc->flags |= PCIB_DETACHING;
+ sc->flags &= ~PCIB_DETACH_PENDING;
+ pcib_pcie_hotplug_update(sc, 0, 0, true);
+ }
+}
+
+static void
+pcib_pcie_cc_timeout(void *arg)
+{
+ struct pcib_softc *sc;
+ device_t dev;
+
+ sc = arg;
+ dev = sc->dev;
+ mtx_assert(&Giant, MA_OWNED);
+ if (sc->flags & PCIB_HOTPLUG_CMD_PENDING) {
+ device_printf(dev,
+ "Hotplug Command Timed Out - forcing detach\n");
+ sc->flags &= ~(PCIB_HOTPLUG_CMD_PENDING | PCIB_DETACH_PENDING);
+ sc->flags |= PCIB_DETACHING;
+ pcib_pcie_hotplug_update(sc, 0, 0, true);
+ }
+}
+
+static void
+pcib_pcie_dll_timeout(void *arg)
+{
+ struct pcib_softc *sc;
+ device_t dev;
+ uint16_t sta;
+
+ sc = arg;
+ dev = sc->dev;
+ mtx_assert(&Giant, MA_OWNED);
+ sta = pcie_read_config(dev, PCIER_LINK_STA, 2);
+ if (!(sta & PCIEM_LINK_STA_DL_ACTIVE)) {
+ device_printf(dev,
+ "Timed out waiting for Data Link Layer Active\n");
+ sc->flags |= PCIB_DETACHING;
+ pcib_pcie_hotplug_update(sc, 0, 0, true);
+ } else if (sta != sc->pcie_link_sta) {
+ device_printf(dev,
+ "Missed HotPlug interrupt waiting for DLL Active\n");
+ pcib_pcie_intr(sc);
+ }
+}
+
+static int
+pcib_alloc_pcie_irq(struct pcib_softc *sc)
+{
+ device_t dev;
+ int count, error, rid;
+
+ rid = -1;
+ dev = sc->dev;
+
+ /*
+ * For simplicity, only use MSI-X if there is a single message.
+ * To support a device with multiple messages we would have to
+ * use remap intr if the MSI number is not 0.
+ */
+ count = pci_msix_count(dev);
+ if (count == 1) {
+ error = pci_alloc_msix(dev, &count);
+ if (error == 0)
+ rid = 1;
+ }
+
+ if (rid < 0 && pci_msi_count(dev) > 0) {
+ count = 1;
+ error = pci_alloc_msi(dev, &count);
+ if (error == 0)
+ rid = 1;
+ }
+
+ if (rid < 0)
+ rid = 0;
+
+ sc->pcie_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_ACTIVE);
+ if (sc->pcie_irq == NULL) {
+ device_printf(dev,
+ "Failed to allocate interrupt for PCI-e events\n");
+ if (rid > 0)
+ pci_release_msi(dev);
+ return (ENXIO);
+ }
+
+ error = bus_setup_intr(dev, sc->pcie_irq, INTR_TYPE_MISC,
+ NULL, pcib_pcie_intr, sc, &sc->pcie_ihand);
+ if (error) {
+ device_printf(dev, "Failed to setup PCI-e interrupt handler\n");
+ bus_release_resource(dev, SYS_RES_IRQ, rid, sc->pcie_irq);
+ if (rid > 0)
+ pci_release_msi(dev);
+ return (error);
+ }
+ return (0);
+}
+
+static void
+pcib_setup_hotplug(struct pcib_softc *sc)
+{
+ device_t dev;
+ uint16_t mask, val;
+
+ dev = sc->dev;
+ callout_init(&sc->pcie_ab_timer, 0);
+ callout_init(&sc->pcie_cc_timer, 0);
+ callout_init(&sc->pcie_dll_timer, 0);
+ TASK_INIT(&sc->pcie_hp_task, 0, pcib_pcie_hotplug_task, sc);
+
+ /* Allocate IRQ. */
+ if (pcib_alloc_pcie_irq(sc) != 0)
+ return;
+
+ sc->pcie_link_sta = pcie_read_config(dev, PCIER_LINK_STA, 2);
+ sc->pcie_slot_sta = pcie_read_config(dev, PCIER_SLOT_STA, 2);
+
+ /* Enable HotPlug events. */
+ mask = PCIEM_SLOT_CTL_DLLSCE | PCIEM_SLOT_CTL_HPIE |
+ PCIEM_SLOT_CTL_CCIE | PCIEM_SLOT_CTL_PDCE | PCIEM_SLOT_CTL_MRLSCE |
+ PCIEM_SLOT_CTL_PFDE | PCIEM_SLOT_CTL_ABPE;
+ val = PCIEM_SLOT_CTL_PDCE | PCIEM_SLOT_CTL_HPIE;
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_APB)
+ val |= PCIEM_SLOT_CTL_ABPE;
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_PCP)
+ val |= PCIEM_SLOT_CTL_PFDE;
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_MRLSP)
+ val |= PCIEM_SLOT_CTL_MRLSCE;
+ if (!(sc->pcie_slot_cap & PCIEM_SLOT_CAP_NCCS))
+ val |= PCIEM_SLOT_CTL_CCIE;
+ if (sc->pcie_link_cap & PCIEM_LINK_CAP_DL_ACTIVE)
+ val |= PCIEM_SLOT_CTL_DLLSCE;
+
+ /* Turn the attention indicator off. */
+ if (sc->pcie_slot_cap & PCIEM_SLOT_CAP_AIP) {
+ mask |= PCIEM_SLOT_CTL_AIC;
+ val |= PCIEM_SLOT_CTL_AI_OFF;
+ }
+
+ pcib_pcie_hotplug_update(sc, val, mask, false);
+}
+#endif
+
/*
* Get current bridge configuration.
*/
@@ -1017,12 +1486,19 @@ pcib_attach_common(device_t dev)
pci_read_config(dev, PCIR_PROGIF, 1) == PCIP_BRIDGE_PCI_SUBTRACTIVE)
sc->flags |= PCIB_SUBTRACTIVE;
+#ifdef PCI_HP
+ pcib_probe_hotplug(sc);
+#endif
#ifdef NEW_PCIB
#ifdef PCI_RES_BUS
pcib_setup_secbus(dev, &sc->bus, 1);
#endif
pcib_probe_windows(sc);
#endif
+#ifdef PCI_HP
+ if (sc->flags & PCIB_HOTPLUG)
+ pcib_setup_hotplug(sc);
+#endif
if (bootverbose) {
device_printf(dev, " domain %d\n", sc->domain);
device_printf(dev, " secondary bus %d\n", sc->bus.sec);
@@ -1074,6 +1550,17 @@ pcib_attach_common(device_t dev)
pci_enable_busmaster(dev);
}
+#ifdef PCI_HP
+static int
+pcib_present(struct pcib_softc *sc)
+{
+
+ if (sc->flags & PCIB_HOTPLUG)
+ return (pcib_hotplug_present(sc) != 0);
+ return (1);
+}
+#endif
+
int
pcib_attach_child(device_t dev)
{
@@ -1085,6 +1572,13 @@ pcib_attach_child(device_t dev)
return(0);
}
+#ifdef PCI_HP
+ if (!pcib_present(sc)) {
+ /* An empty HotPlug slot, so don't add a PCI bus yet. */
+ return (0);
+ }
+#endif
+
sc->child = device_add_child(dev, "pci", -1);
return (bus_generic_attach(dev));
}
@@ -1129,6 +1623,22 @@ pcib_bridge_init(device_t dev)
}
int
+pcib_child_present(device_t dev, device_t child)
+{
+#ifdef PCI_HP
+ struct pcib_softc *sc = device_get_softc(dev);
+ int retval;
+
+ retval = bus_child_present(dev);
+ if (retval != 0 && sc->flags & PCIB_HOTPLUG)
+ retval = pcib_hotplug_present(sc);
+ return (retval);
+#else
+ return (bus_child_present(dev));
+#endif
+}
+
+int
pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pcib_softc *sc = device_get_softc(dev);
@@ -1909,7 +2419,21 @@ pcib_ari_decode_rid(device_t pcib, uint16_t rid, int *bus, int *slot,
static uint32_t
pcib_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width)
{
+#ifdef PCI_HP
+ struct pcib_softc *sc;
+ sc = device_get_softc(dev);
+ if (!pcib_present(sc)) {
+ switch (width) {
+ case 2:
+ return (0xffff);
+ case 1:
+ return (0xff);
+ default:
+ return (0xffffffff);
+ }
+ }
+#endif
pcib_xlate_ari(dev, b, &s, &f);
return(PCIB_READ_CONFIG(device_get_parent(device_get_parent(dev)), b, s,
f, reg, width));
@@ -1918,7 +2442,13 @@ pcib_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width)
static void
pcib_write_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, uint32_t val, int width)
{
+#ifdef PCI_HP
+ struct pcib_softc *sc;
+ sc = device_get_softc(dev);
+ if (!pcib_present(sc))
+ return;
+#endif
pcib_xlate_ari(dev, b, &s, &f);
PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(dev)), b, s, f,
reg, val, width);
diff --git a/sys/dev/pci/pcib_private.h b/sys/dev/pci/pcib_private.h
index 93d9a71..c209162 100644
--- a/sys/dev/pci/pcib_private.h
+++ b/sys/dev/pci/pcib_private.h
@@ -33,6 +33,9 @@
#ifndef __PCIB_PRIVATE_H__
#define __PCIB_PRIVATE_H__
+#include <sys/_callout.h>
+#include <sys/_task.h>
+
#ifdef NEW_PCIB
/*
* Data structure and routines that Host to PCI bridge drivers can use
@@ -107,6 +110,10 @@ struct pcib_softc
#define PCIB_DISABLE_MSI 0x2
#define PCIB_DISABLE_MSIX 0x4
#define PCIB_ENABLE_ARI 0x8
+#define PCIB_HOTPLUG 0x10
+#define PCIB_HOTPLUG_CMD_PENDING 0x20
+#define PCIB_DETACH_PENDING 0x40
+#define PCIB_DETACHING 0x80
u_int domain; /* domain number */
u_int pribus; /* primary bus number */
struct pcib_secbus bus; /* secondary bus numbers */
@@ -123,6 +130,18 @@ struct pcib_softc
uint32_t iolimit; /* topmost address of port window */
#endif
uint16_t bridgectl; /* bridge control register */
+ uint16_t pcie_link_sta;
+ uint16_t pcie_slot_sta;
+ uint32_t pcie_link_cap;
+ uint32_t pcie_slot_cap;
+ uint16_t pcie_pending_link_ctl_mask;
+ uint16_t pcie_pending_link_ctl_val;
+ struct resource *pcie_irq;
+ void *pcie_ihand;
+ struct task pcie_hp_task;
+ struct callout pcie_ab_timer;
+ struct callout pcie_cc_timer;
+ struct callout pcie_dll_timer;
};
#define PCIB_SUPPORTED_ARI_VER 1
@@ -151,6 +170,7 @@ void pcib_bridge_init(device_t dev);
#ifdef NEW_PCIB
const char *pcib_child_name(device_t child);
#endif
+int pcib_child_present(device_t dev, device_t child);
int pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result);
int pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value);
struct resource *pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index 68b5378..d463b7a 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -850,8 +850,16 @@
#define PCIEM_SLOT_CTL_CCIE 0x0010
#define PCIEM_SLOT_CTL_HPIE 0x0020
#define PCIEM_SLOT_CTL_AIC 0x00c0
+#define PCIEM_SLOT_CTL_AI_ON 0x0040
+#define PCIEM_SLOT_CTL_AI_BLINK 0x0080
+#define PCIEM_SLOT_CTL_AI_OFF 0x00c0
#define PCIEM_SLOT_CTL_PIC 0x0300
+#define PCIEM_SLOT_CTL_PI_ON 0x0100
+#define PCIEM_SLOT_CTL_PI_BLINK 0x0200
+#define PCIEM_SLOT_CTL_PI_OFF 0x0300
#define PCIEM_SLOT_CTL_PCC 0x0400
+#define PCIEM_SLOT_CTL_PC_ON 0x0000
+#define PCIEM_SLOT_CTL_PC_OFF 0x0400
#define PCIEM_SLOT_CTL_EIC 0x0800
#define PCIEM_SLOT_CTL_DLLSCE 0x1000
#define PCIER_SLOT_STA 0x1a
diff --git a/sys/dev/pms/freebsd/driver/common/lxcommon.h b/sys/dev/pms/freebsd/driver/common/lxcommon.h
index 0df2702..71ce230 100644
--- a/sys/dev/pms/freebsd/driver/common/lxcommon.h
+++ b/sys/dev/pms/freebsd/driver/common/lxcommon.h
@@ -452,7 +452,7 @@ typedef struct _ag_card_info {
/*
** Optional Adjustable Parameters Structures.
-** Not using pointer stucture for easy read and access tree structure.
+** Not using pointer structure for easy read and access tree structure.
** In the future if more layer of key tree involved, it might be a good
** idea to change the structure and program.
*/
@@ -637,7 +637,7 @@ typedef struct _LINK_LIST
{
PLINK_NODE pHead;
bit32 Count;
- LINK_NODE Head __cacheline_aligned; // allways one link to speed up insert&rm
+ LINK_NODE Head __cacheline_aligned; // always one link to speed up insert&rm
} LINK_LIST, * PLINK_LIST __cacheline_aligned;
diff --git a/sys/dev/pms/freebsd/driver/common/osenv.h b/sys/dev/pms/freebsd/driver/common/osenv.h
index 16b8aa9..491c29e 100644
--- a/sys/dev/pms/freebsd/driver/common/osenv.h
+++ b/sys/dev/pms/freebsd/driver/common/osenv.h
@@ -28,7 +28,7 @@ Version Control Information:
$RCSfile: osenv.h,v $
$Revision: 114125 $
-Note: This file defines the working enviornment of the system. All
+Note: This file defines the working environment of the system. All
defines listed in this file could also be compiler flags.
I am listing all the defines (even if used as a compiler flag)
so that they can be seen and documented.
@@ -41,7 +41,7 @@ Note: This file defines the working enviornment of the system. All
/*
** Define the protocols to compile with. Currently, these defines are
** only for this header file and are used further down to define the protocol
-** specific enviornment:
+** specific environment:
**
** #define AG_PROTOCOL_ISCSI
** #define AG_PROTOCOL_FC
@@ -87,12 +87,12 @@ Note: This file defines the working enviornment of the system. All
#endif
/***************************************************************************
-iSCSI enviornment - The following is used for compiling the iSCSI
+iSCSI environment - The following is used for compiling the iSCSI
protocol.
**************************************************************************/
/*
-** Define the existance of an external bus swapper using on of the
+** Define the existence of an external bus swapper using on of the
** following:
**
** #define AG_SWAPPING_BUS
@@ -109,7 +109,7 @@ iSCSI enviornment - The following is used for compiling the iSCSI
/* #define AG_CACHED_MSG_SYSTEM */
/***************************************************************************
-FC enviornment - The following is used for compiling the FC protocol.
+FC environment - The following is used for compiling the FC protocol.
**************************************************************************/
/*
diff --git a/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c b/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c
index 640d341..f0646dd 100644
--- a/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c
+++ b/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c
@@ -3749,7 +3749,7 @@ static void agtiapi_PrepareSMPSGListCB( void *arg,
return;
}
/* TODO: add indirect handling */
- /* set the flag correctly based on Indiret SMP request and responce */
+ /* set the flag correctly based on Indiret SMP request and response */
AGTIAPI_PRINTK( "agtiapi_PrepareSMPSGListCB: send ccb pccb->devHandle %p, "
"pccb->targetId %d TID %d pmcsc->devDiscover %d card %p\n",
@@ -5811,7 +5811,7 @@ agtiapi_ReleaseCCBs()
Purpose:
Free all allocated CCB memories for the Host Adapter.
Parameters:
- struct agtiapi_softc *pCard (IN) Pointer to HBA data stucture
+ struct agtiapi_softc *pCard (IN) Pointer to HBA data structure
Return:
Note:
******************************************************************************/
diff --git a/sys/dev/pms/freebsd/driver/ini/src/osapi.c b/sys/dev/pms/freebsd/driver/ini/src/osapi.c
index f461923..2faaff8 100644
--- a/sys/dev/pms/freebsd/driver/ini/src/osapi.c
+++ b/sys/dev/pms/freebsd/driver/ini/src/osapi.c
@@ -172,7 +172,7 @@ void ostiInitiatorEvent( tiRoot_t *ptiRoot,
ccbIO = pccb->pccbIO;
if (ccbIO->startTime == 0) /* IO has been completed. */
{
- AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM failed becasue IO has been completed! pTMccb %p flag %x \n",
+ AGTIAPI_PRINTK("tiIntrEventTypeTaskManagement: TM failed because IO has been completed! pTMccb %p flag %x \n",
pccb, pccb->flags);
}
else
@@ -443,7 +443,7 @@ ostiInitiatorSMPCompleted(tiRoot_t *ptiRoot,
struct ccb_smpio *csmpio = &ccb->smpio;
memcpy(csmpio->smp_response, tiFrameHandle, tiSMPInfoLen);
csmpio->smp_response_len = tiSMPInfoLen;
- agtiapi_hexdump("ostiInitiatorSMPCompleted: Responce Payload in CAM", (bit8 *)csmpio->smp_response, csmpio->smp_response_len);
+ agtiapi_hexdump("ostiInitiatorSMPCompleted: Response Payload in CAM", (bit8 *)csmpio->smp_response, csmpio->smp_response_len);
}
pccb->flags |= REQ_DONE;
agtiapi_QueueCCB(pCard, &pCard->smpDoneHead, &pCard->smpDoneTail
diff --git a/sys/dev/sfxge/common/efsys.h b/sys/dev/sfxge/common/efsys.h
index b44daca..f019139 100644
--- a/sys/dev/sfxge/common/efsys.h
+++ b/sys/dev/sfxge/common/efsys.h
@@ -236,8 +236,6 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_NAMES 1
-#define EFSYS_OPT_FALCON 0
-#define EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE 0
#define EFSYS_OPT_SIENA 1
#define EFSYS_OPT_HUNTINGTON 1
#define EFSYS_OPT_MEDFORD 0
@@ -251,39 +249,23 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_MCDI_LOGGING 0
#define EFSYS_OPT_MCDI_PROXY_AUTH 0
-#define EFSYS_OPT_MAC_FALCON_GMAC 0
-#define EFSYS_OPT_MAC_FALCON_XMAC 0
#define EFSYS_OPT_MAC_STATS 1
#define EFSYS_OPT_LOOPBACK 0
-#define EFSYS_OPT_MON_NULL 0
-#define EFSYS_OPT_MON_LM87 0
-#define EFSYS_OPT_MON_MAX6647 0
#define EFSYS_OPT_MON_MCDI 0
#define EFSYS_OPT_MON_STATS 0
-#define EFSYS_OPT_PHY_NULL 0
-#define EFSYS_OPT_PHY_QT2022C2 0
-#define EFSYS_OPT_PHY_SFX7101 0
-#define EFSYS_OPT_PHY_TXC43128 0
-#define EFSYS_OPT_PHY_SFT9001 0
-#define EFSYS_OPT_PHY_QT2025C 0
#define EFSYS_OPT_PHY_STATS 1
#define EFSYS_OPT_PHY_PROPS 0
-#define EFSYS_OPT_PHY_BIST 0
#define EFSYS_OPT_BIST 1
#define EFSYS_OPT_PHY_LED_CONTROL 1
#define EFSYS_OPT_PHY_FLAGS 0
#define EFSYS_OPT_VPD 1
#define EFSYS_OPT_NVRAM 1
-#define EFSYS_OPT_NVRAM_FALCON_BOOTROM 0
-#define EFSYS_OPT_NVRAM_SFT9001 0
-#define EFSYS_OPT_NVRAM_SFX7101 0
#define EFSYS_OPT_BOOTCFG 0
-#define EFSYS_OPT_PCIE_TUNE 0
#define EFSYS_OPT_DIAG 0
#define EFSYS_OPT_WOL 1
#define EFSYS_OPT_RX_SCALE 1
diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h
index 14374cf..3b67471 100644
--- a/sys/dev/sfxge/common/efx.h
+++ b/sys/dev/sfxge/common/efx.h
@@ -34,6 +34,7 @@
#define _SYS_EFX_H
#include "efsys.h"
+#include "efx_check.h"
#include "efx_phy_ids.h"
#ifdef __cplusplus
@@ -148,19 +149,6 @@ extern __checkReturn efx_rc_t
efx_nic_probe(
__in efx_nic_t *enp);
-#if EFSYS_OPT_PCIE_TUNE
-
-extern __checkReturn efx_rc_t
-efx_nic_pcie_tune(
- __in efx_nic_t *enp,
- unsigned int nlanes);
-
-extern __checkReturn efx_rc_t
-efx_nic_pcie_extended_sync(
- __in efx_nic_t *enp);
-
-#endif /* EFSYS_OPT_PCIE_TUNE */
-
extern __checkReturn efx_rc_t
efx_nic_init(
__in efx_nic_t *enp);
diff --git a/sys/dev/sfxge/common/efx_check.h b/sys/dev/sfxge/common/efx_check.h
index d6b7cf4..1abed3e 100644
--- a/sys/dev/sfxge/common/efx_check.h
+++ b/sys/dev/sfxge/common/efx_check.h
@@ -43,6 +43,32 @@
* from client code (and do not reappear in merges from other branches).
*/
+#ifdef EFSYS_OPT_FALCON
+# error "FALCON is obsolete and is not supported."
+#else
+/* FIXME: remove this after Falcon support has been removed */
+#define EFSYS_OPT_FALCON (0)
+#define EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE (0)
+
+#define EFSYS_OPT_MAC_FALCON_GMAC (0)
+#define EFSYS_OPT_MAC_FALCON_XMAC (0)
+
+#define EFSYS_OPT_MON_LM87 (0)
+#define EFSYS_OPT_MON_MAX6647 (0)
+#define EFSYS_OPT_MON_NULL (0)
+
+#define EFSYS_OPT_NVRAM_FALCON_BOOTROM (0)
+#define EFSYS_OPT_NVRAM_SFT9001 (0)
+#define EFSYS_OPT_NVRAM_SFX7101 (0)
+
+#define EFSYS_OPT_PHY_NULL (0)
+#define EFSYS_OPT_PHY_QT2022C2 (0)
+#define EFSYS_OPT_PHY_QT2025C (0)
+#define EFSYS_OPT_PHY_SFT9001 (0)
+#define EFSYS_OPT_PHY_SFX7101 (0)
+#define EFSYS_OPT_PHY_TXC43128 (0)
+#endif
+
/* Support NVRAM based boot config */
#if EFSYS_OPT_BOOTCFG
# if !EFSYS_OPT_NVRAM
@@ -252,17 +278,14 @@
# endif
#endif /* EFSYS_OPT_NVRAM_SFX7101 */
-/* Support PCIe interface tuning */
-#if EFSYS_OPT_PCIE_TUNE
-# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
-# error "PCIE_TUNE requires FALCON or SIENA"
-# endif
-#endif /* EFSYS_OPT_PCIE_TUNE */
+#ifdef EFSYS_OPT_PCIE_TUNE
+# error "PCIE_TUNE is obsolete and is not supported."
+#endif
/* Obsolete option */
-#if EFSYS_OPT_PHY_BIST
-# error "PHY_BIST is obsolete (replaced by BIST)."
-#endif /* EFSYS_OPT_PHY_BIST */
+#ifdef EFSYS_OPT_PHY_BIST
+# error "PHY_BIST is obsolete (replaced by BIST)."
+#endif
/* Support PHY flags */
#if EFSYS_OPT_PHY_FLAGS
diff --git a/sys/dev/sfxge/common/efx_impl.h b/sys/dev/sfxge/common/efx_impl.h
index 5495b15..f917ba1 100644
--- a/sys/dev/sfxge/common/efx_impl.h
+++ b/sys/dev/sfxge/common/efx_impl.h
@@ -34,6 +34,7 @@
#define _SYS_EFX_IMPL_H
#include "efsys.h"
+#include "efx_check.h"
#include "efx.h"
#include "efx_regs.h"
#include "efx_regs_ef10.h"
@@ -43,8 +44,6 @@
#define ESE_DZ_EV_CODE_DRV_GEN_EV FSE_AZ_EV_CODE_DRV_GEN_EV
#endif
-#include "efx_check.h"
-
#if EFSYS_OPT_FALCON
#include "falcon_impl.h"
@@ -668,9 +667,6 @@ struct efx_nic_s {
const uint8_t *enu_forced_cfg;
#endif /* EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE */
uint8_t enu_mon_devid;
-#if EFSYS_OPT_PCIE_TUNE
- unsigned int enu_nlanes;
-#endif /* EFSYS_OPT_PCIE_TUNE */
uint16_t enu_board_rev;
boolean_t enu_internal_sram;
uint8_t enu_sram_num_bank;
diff --git a/sys/dev/sfxge/common/efx_nic.c b/sys/dev/sfxge/common/efx_nic.c
index 149cd23..35cd8eb 100644
--- a/sys/dev/sfxge/common/efx_nic.c
+++ b/sys/dev/sfxge/common/efx_nic.c
@@ -467,42 +467,6 @@ fail1:
return (rc);
}
-#if EFSYS_OPT_PCIE_TUNE
-
- __checkReturn efx_rc_t
-efx_nic_pcie_tune(
- __in efx_nic_t *enp,
- unsigned int nlanes)
-{
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
- EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
-
-#if EFSYS_OPT_FALCON
- if (enp->en_family == EFX_FAMILY_FALCON)
- return (falcon_nic_pcie_tune(enp, nlanes));
-#endif
- return (ENOTSUP);
-}
-
- __checkReturn efx_rc_t
-efx_nic_pcie_extended_sync(
- __in efx_nic_t *enp)
-{
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
- EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
-
-#if EFSYS_OPT_SIENA
- if (enp->en_family == EFX_FAMILY_SIENA)
- return (siena_nic_pcie_extended_sync(enp));
-#endif
-
- return (ENOTSUP);
-}
-
-#endif /* EFSYS_OPT_PCIE_TUNE */
-
__checkReturn efx_rc_t
efx_nic_set_drv_limits(
__inout efx_nic_t *enp,
diff --git a/sys/dev/sfxge/common/siena_impl.h b/sys/dev/sfxge/common/siena_impl.h
index 4c80cd6..f9efe58 100644
--- a/sys/dev/sfxge/common/siena_impl.h
+++ b/sys/dev/sfxge/common/siena_impl.h
@@ -59,14 +59,6 @@ extern __checkReturn efx_rc_t
siena_nic_probe(
__in efx_nic_t *enp);
-#if EFSYS_OPT_PCIE_TUNE
-
-extern __checkReturn efx_rc_t
-siena_nic_pcie_extended_sync(
- __in efx_nic_t *enp);
-
-#endif
-
extern __checkReturn efx_rc_t
siena_nic_reset(
__in efx_nic_t *enp);
diff --git a/sys/dev/sfxge/common/siena_nic.c b/sys/dev/sfxge/common/siena_nic.c
index 59e1283..f49914b 100644
--- a/sys/dev/sfxge/common/siena_nic.c
+++ b/sys/dev/sfxge/common/siena_nic.c
@@ -78,28 +78,6 @@ fail1:
return (rc);
}
-#if EFSYS_OPT_PCIE_TUNE
-
- __checkReturn efx_rc_t
-siena_nic_pcie_extended_sync(
- __in efx_nic_t *enp)
-{
- efx_rc_t rc;
-
- if ((rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG17230,
- B_TRUE, NULL) != 0))
- goto fail1;
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- return (rc);
-}
-
-#endif /* EFSYS_OPT_PCIE_TUNE */
-
static __checkReturn efx_rc_t
siena_board_cfg(
__in efx_nic_t *enp)
diff --git a/sys/dev/siba/siba_core.c b/sys/dev/siba/siba_core.c
index 92c54d2..623bfc1 100644
--- a/sys/dev/siba/siba_core.c
+++ b/sys/dev/siba/siba_core.c
@@ -1689,6 +1689,29 @@ siba_sprom_r8(struct siba_sprom *out, const uint16_t *in)
SIBA_SHIFTOUT(again.ghz24.a2, SIBA_SPROM8_AGAIN23, SIBA_SPROM8_AGAIN2);
SIBA_SHIFTOUT(again.ghz24.a3, SIBA_SPROM8_AGAIN23, SIBA_SPROM8_AGAIN3);
bcopy(&out->again.ghz24, &out->again.ghz5, sizeof(out->again.ghz5));
+
+ /* FEM */
+ SIBA_SHIFTOUT(fem.ghz2.tssipos, SIBA_SPROM8_FEM2G,
+ SSB_SROM8_FEM_TSSIPOS);
+ SIBA_SHIFTOUT(fem.ghz2.extpa_gain, SIBA_SPROM8_FEM2G,
+ SSB_SROM8_FEM_EXTPA_GAIN);
+ SIBA_SHIFTOUT(fem.ghz2.pdet_range, SIBA_SPROM8_FEM2G,
+ SSB_SROM8_FEM_PDET_RANGE);
+ SIBA_SHIFTOUT(fem.ghz2.tr_iso, SIBA_SPROM8_FEM2G,
+ SSB_SROM8_FEM_TR_ISO);
+ SIBA_SHIFTOUT(fem.ghz2.antswlut, SIBA_SPROM8_FEM2G,
+ SSB_SROM8_FEM_ANTSWLUT);
+
+ SIBA_SHIFTOUT(fem.ghz5.tssipos, SIBA_SPROM8_FEM5G,
+ SSB_SROM8_FEM_TSSIPOS);
+ SIBA_SHIFTOUT(fem.ghz5.extpa_gain, SIBA_SPROM8_FEM5G,
+ SSB_SROM8_FEM_EXTPA_GAIN);
+ SIBA_SHIFTOUT(fem.ghz5.pdet_range, SIBA_SPROM8_FEM5G,
+ SSB_SROM8_FEM_PDET_RANGE);
+ SIBA_SHIFTOUT(fem.ghz5.tr_iso, SIBA_SPROM8_FEM5G,
+ SSB_SROM8_FEM_TR_ISO);
+ SIBA_SHIFTOUT(fem.ghz5.antswlut, SIBA_SPROM8_FEM5G,
+ SSB_SROM8_FEM_ANTSWLUT);
}
static int8_t
@@ -2338,6 +2361,36 @@ siba_read_sprom(device_t dev, device_t child, int which, uintptr_t *result)
case SIBA_SPROMVAR_BF2_HI:
*result = siba->siba_sprom.bf2_hi;
break;
+ case SIBA_SPROMVAR_FEM_2GHZ_TSSIPOS:
+ *result = siba->siba_sprom.fem.ghz2.tssipos;
+ break;
+ case SIBA_SPROMVAR_FEM_2GHZ_EXTPAGAIN:
+ *result = siba->siba_sprom.fem.ghz2.extpa_gain;
+ break;
+ case SIBA_SPROMVAR_FEM_2GHZ_PDET_RANGE:
+ *result = siba->siba_sprom.fem.ghz2.pdet_range;
+ break;
+ case SIBA_SPROMVAR_FEM_2GHZ_TR_ISO:
+ *result = siba->siba_sprom.fem.ghz2.tr_iso;
+ break;
+ case SIBA_SPROMVAR_FEM_2GHZ_ANTSWLUT:
+ *result = siba->siba_sprom.fem.ghz2.antswlut;
+ break;
+ case SIBA_SPROMVAR_FEM_5GHZ_TSSIPOS:
+ *result = siba->siba_sprom.fem.ghz5.tssipos;
+ break;
+ case SIBA_SPROMVAR_FEM_5GHZ_EXTPAGAIN:
+ *result = siba->siba_sprom.fem.ghz5.extpa_gain;
+ break;
+ case SIBA_SPROMVAR_FEM_5GHZ_PDET_RANGE:
+ *result = siba->siba_sprom.fem.ghz5.pdet_range;
+ break;
+ case SIBA_SPROMVAR_FEM_5GHZ_TR_ISO:
+ *result = siba->siba_sprom.fem.ghz5.tr_iso;
+ break;
+ case SIBA_SPROMVAR_FEM_5GHZ_ANTSWLUT:
+ *result = siba->siba_sprom.fem.ghz5.antswlut;
+ break;
default:
return (ENOENT);
}
diff --git a/sys/dev/siba/sibareg.h b/sys/dev/siba/sibareg.h
index c2a4fdb..7869850 100644
--- a/sys/dev/siba/sibareg.h
+++ b/sys/dev/siba/sibareg.h
@@ -414,6 +414,13 @@
#define SIBA_SPROM8_RXPO 0x10ac
#define SIBA_SPROM8_RXPO2G 0x00ff
#define SIBA_SPROM8_RXPO5G 0xff00
+#define SIBA_SPROM8_FEM2G 0x00AE
+#define SIBA_SPROM8_FEM5G 0x00B0
+#define SSB_SROM8_FEM_TSSIPOS 0x0001
+#define SSB_SROM8_FEM_EXTPA_GAIN 0x0006
+#define SSB_SROM8_FEM_PDET_RANGE 0x00F8
+#define SSB_SROM8_FEM_TR_ISO 0x0700
+#define SSB_SROM8_FEM_ANTSWLUT 0xF800
#define SIBA_SPROM8_MAXP_BG 0x10c0
#define SIBA_SPROM8_MAXP_BG_MASK 0x00ff
#define SIBA_SPROM8_TSSI_BG 0xff00
diff --git a/sys/dev/siba/sibavar.h b/sys/dev/siba/sibavar.h
index 9b82310..14e0b14 100644
--- a/sys/dev/siba/sibavar.h
+++ b/sys/dev/siba/sibavar.h
@@ -278,7 +278,17 @@ enum siba_sprom_vars {
SIBA_SPROMVAR_BF_LO,
SIBA_SPROMVAR_BF_HI,
SIBA_SPROMVAR_BF2_LO,
- SIBA_SPROMVAR_BF2_HI
+ SIBA_SPROMVAR_BF2_HI,
+ SIBA_SPROMVAR_FEM_2GHZ_TSSIPOS,
+ SIBA_SPROMVAR_FEM_2GHZ_EXTPAGAIN,
+ SIBA_SPROMVAR_FEM_2GHZ_PDET_RANGE,
+ SIBA_SPROMVAR_FEM_2GHZ_TR_ISO,
+ SIBA_SPROMVAR_FEM_2GHZ_ANTSWLUT,
+ SIBA_SPROMVAR_FEM_5GHZ_TSSIPOS,
+ SIBA_SPROMVAR_FEM_5GHZ_EXTPAGAIN,
+ SIBA_SPROMVAR_FEM_5GHZ_PDET_RANGE,
+ SIBA_SPROMVAR_FEM_5GHZ_TR_ISO,
+ SIBA_SPROMVAR_FEM_5GHZ_ANTSWLUT,
};
int siba_read_sprom(device_t, device_t, int, uintptr_t *);
@@ -364,6 +374,18 @@ SIBA_SPROM_ACCESSOR(bf_lo, BF_LO, uint16_t);
SIBA_SPROM_ACCESSOR(bf_hi, BF_HI, uint16_t);
SIBA_SPROM_ACCESSOR(bf2_lo, BF2_LO, uint16_t);
SIBA_SPROM_ACCESSOR(bf2_hi, BF2_HI, uint16_t);
+/* 2GHz FEM */
+SIBA_SPROM_ACCESSOR(fem_2ghz_tssipos, FEM_2GHZ_TSSIPOS, uint8_t);
+SIBA_SPROM_ACCESSOR(fem_2ghz_extpa_gain, FEM_2GHZ_EXTPAGAIN, uint8_t);
+SIBA_SPROM_ACCESSOR(fem_2ghz_pdet_range, FEM_2GHZ_PDET_RANGE, uint8_t);
+SIBA_SPROM_ACCESSOR(fem_2ghz_tr_iso, FEM_2GHZ_TR_ISO, uint8_t);
+SIBA_SPROM_ACCESSOR(fem_2ghz_antswlut, FEM_2GHZ_ANTSWLUT, uint8_t);
+/* 5GHz FEM */
+SIBA_SPROM_ACCESSOR(fem_5ghz_tssipos, FEM_5GHZ_TSSIPOS, uint8_t);
+SIBA_SPROM_ACCESSOR(fem_5ghz_extpa_gain, FEM_5GHZ_EXTPAGAIN, uint8_t);
+SIBA_SPROM_ACCESSOR(fem_5ghz_pdet_range, FEM_5GHZ_PDET_RANGE, uint8_t);
+SIBA_SPROM_ACCESSOR(fem_5ghz_tr_iso, FEM_5GHZ_TR_ISO, uint8_t);
+SIBA_SPROM_ACCESSOR(fem_5ghz_antswlut, FEM_5GHZ_ANTSWLUT, uint8_t);
#undef SIBA_SPROM_ACCESSOR
@@ -434,6 +456,17 @@ struct siba_sprom {
int8_t a0, a1, a2, a3;
} ghz5;
} again; /* antenna gain */
+
+ struct {
+ struct {
+ uint8_t tssipos, extpa_gain, pdet_range, tr_iso;
+ uint8_t antswlut;
+ } ghz2;
+ struct {
+ uint8_t tssipos, extpa_gain, pdet_range, tr_iso;
+ uint8_t antswlut;
+ } ghz5;
+ } fem;
};
#define SIBA_LDO_PAREF 0
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index c761acb..a63c730 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -93,6 +93,8 @@ static const struct {
{ HDA_INTEL_WELLS2, "Intel Wellsburg", 0, 0 },
{ HDA_INTEL_LPTLP1, "Intel Lynx Point-LP", 0, 0 },
{ HDA_INTEL_LPTLP2, "Intel Lynx Point-LP", 0, 0 },
+ { HDA_INTEL_SRPTLP, "Intel Sunrise Point-LP", 0, 0 },
+ { HDA_INTEL_SRPT, "Intel Sunrise Point", 0, 0 },
{ HDA_INTEL_82801F, "Intel 82801F", 0, 0 },
{ HDA_INTEL_63XXESB, "Intel 631x/632xESB", 0, 0 },
{ HDA_INTEL_82801G, "Intel 82801G", 0, 0 },
diff --git a/sys/dev/sound/pci/hda/hdac.h b/sys/dev/sound/pci/hda/hdac.h
index 1fc265a..71c9e08 100644
--- a/sys/dev/sound/pci/hda/hdac.h
+++ b/sys/dev/sound/pci/hda/hdac.h
@@ -69,6 +69,8 @@
#define HDA_INTEL_LPTLP1 HDA_MODEL_CONSTRUCT(INTEL, 0x9c20)
#define HDA_INTEL_LPTLP2 HDA_MODEL_CONSTRUCT(INTEL, 0x9c21)
#define HDA_INTEL_BDW2 HDA_MODEL_CONSTRUCT(INTEL, 0x9ca0)
+#define HDA_INTEL_SRPTLP HDA_MODEL_CONSTRUCT(INTEL, 0x9d70)
+#define HDA_INTEL_SRPT HDA_MODEL_CONSTRUCT(INTEL, 0xa170)
#define HDA_INTEL_ALL HDA_MODEL_CONSTRUCT(INTEL, 0xffff)
/* Nvidia */
diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c
index d4355e9..09fab21 100644
--- a/sys/dev/usb/controller/xhci_pci.c
+++ b/sys/dev/usb/controller/xhci_pci.c
@@ -122,6 +122,8 @@ xhci_pci_match(device_t self)
return ("Intel Wellsburg USB 3.0 controller");
case 0x9cb18086:
return ("Broadwell Integrated PCH-LP chipset USB 3.0 controller");
+ case 0xa12f8086:
+ return ("Intel Sunrise Point USB 3.0 controller");
case 0xa01b177d:
return ("Cavium ThunderX USB 3.0 controller");
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index df9fea6..30336a1 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -1774,7 +1774,9 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
scratch_ptr = udev->scratch.data;
- if (udev->ddesc.iManufacturer ||
+ if (udev->flags.no_strings) {
+ err = USB_ERR_INVAL;
+ } else if (udev->ddesc.iManufacturer ||
udev->ddesc.iProduct ||
udev->ddesc.iSerialNumber) {
/* read out the language ID string */
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index 1a96776..c7d7712 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -5222,7 +5222,7 @@ run_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain)
static void
run_rt5390_bbp_init(struct run_softc *sc)
{
- int i;
+ u_int i;
uint8_t bbp;
/* Apply maximum likelihood detection for 2 stream case. */
@@ -5332,7 +5332,7 @@ run_rt3070_rf_init(struct run_softc *sc)
{
uint32_t tmp;
uint8_t bbp4, mingain, rf, target;
- int i;
+ u_int i;
run_rt3070_rf_read(sc, 30, &rf);
/* toggle RF R30 bit 7 */
@@ -5476,7 +5476,7 @@ run_rt3593_rf_init(struct run_softc *sc)
{
uint32_t tmp;
uint8_t rf;
- int i;
+ u_int i;
/* Disable the GPIO bits 4 and 7 for LNA PE control. */
run_read(sc, RT3070_GPIO_SWITCH, &tmp);
@@ -5525,7 +5525,7 @@ run_rt5390_rf_init(struct run_softc *sc)
{
uint32_t tmp;
uint8_t rf;
- int i;
+ u_int i;
/* Toggle RF R2 to initiate calibration. */
if (sc->mac_ver == 0x5390) {
diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c
index 8895705..4c6bc76 100644
--- a/sys/dev/usb/wlan/if_urtw.c
+++ b/sys/dev/usb/wlan/if_urtw.c
@@ -1910,7 +1910,7 @@ fail:
static uint16_t
urtw_rate2rtl(uint32_t rate)
{
- int i;
+ unsigned int i;
for (i = 0; i < nitems(urtw_ratetable); i++) {
if (rate == urtw_ratetable[i].reg)
@@ -1923,7 +1923,7 @@ urtw_rate2rtl(uint32_t rate)
static uint16_t
urtw_rtl2rate(uint32_t rate)
{
- int i;
+ unsigned int i;
for (i = 0; i < nitems(urtw_ratetable); i++) {
if (rate == urtw_ratetable[i].val)
@@ -2450,7 +2450,7 @@ fail:
static usb_error_t
urtw_8225_rf_init(struct urtw_softc *sc)
{
- int i;
+ unsigned int i;
uint16_t data;
usb_error_t error;
@@ -2831,7 +2831,7 @@ fail:
static usb_error_t
urtw_8225v2_rf_init(struct urtw_softc *sc)
{
- int i;
+ unsigned int i;
uint16_t data;
uint32_t data32;
usb_error_t error;
@@ -3164,7 +3164,7 @@ static usb_error_t
urtw_8225v2b_rf_init(struct urtw_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
- int i;
+ unsigned int i;
uint8_t data8;
usb_error_t error;
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index 19876e1..e2ea3c9 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -337,7 +337,7 @@ wi_attach(device_t dev)
*/
buflen = sizeof(val);
if (wi_read_rid(sc, WI_RID_CHANNEL_LIST, &val, &buflen) != 0)
- val = htole16(0x1fff); /* assume 1-11 */
+ val = htole16(0x1fff); /* assume 1-13 */
KASSERT(val != 0, ("wi_attach: no available channels listed!"));
val <<= 1; /* shift for base 1 indices */
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c
index 97068a1..8729b45 100644
--- a/sys/dev/xen/blkback/blkback.c
+++ b/sys/dev/xen/blkback/blkback.c
@@ -977,8 +977,8 @@ xbb_get_gntaddr(struct xbb_xen_reqlist *reqlist, int pagenr, int sector)
static uint8_t *
xbb_get_kva(struct xbb_softc *xbb, int nr_pages)
{
- intptr_t first_clear;
- intptr_t num_clear;
+ int first_clear;
+ int num_clear;
uint8_t *free_kva;
int i;
@@ -1027,7 +1027,7 @@ xbb_get_kva(struct xbb_softc *xbb, int nr_pages)
first_clear + nr_pages - 1);
free_kva = xbb->kva +
- (uint8_t *)(first_clear * PAGE_SIZE);
+ (uint8_t *)((intptr_t)first_clear * PAGE_SIZE);
KASSERT(free_kva >= (uint8_t *)xbb->kva &&
free_kva + (nr_pages * PAGE_SIZE) <=
@@ -2967,10 +2967,6 @@ xbb_connect_ring(struct xbb_softc *xbb)
return 0;
}
-/* Needed to make bit_alloc() macro work */
-#define calloc(count, size) malloc((count)*(size), M_XENBLOCKBACK, \
- M_NOWAIT|M_ZERO);
-
/**
* Size KVA and pseudo-physical address allocations based on negotiated
* values for the size and number of I/O requests, and the size of our
@@ -2989,7 +2985,7 @@ xbb_alloc_communication_mem(struct xbb_softc *xbb)
xbb->kva_size = xbb->reqlist_kva_size +
(xbb->ring_config.ring_pages * PAGE_SIZE);
- xbb->kva_free = bit_alloc(xbb->reqlist_kva_pages);
+ xbb->kva_free = bit_alloc(xbb->reqlist_kva_pages, M_XENBLOCKBACK, M_NOWAIT);
if (xbb->kva_free == NULL)
return (ENOMEM);
diff --git a/sys/dev/xen/privcmd/privcmd.c b/sys/dev/xen/privcmd/privcmd.c
index 0bf9585..37a3dbf 100644
--- a/sys/dev/xen/privcmd/privcmd.c
+++ b/sys/dev/xen/privcmd/privcmd.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/tree.h>
#include <sys/module.h>
#include <sys/proc.h>
+#include <sys/bitset.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -72,7 +73,7 @@ struct privcmd_map {
int pseudo_phys_res_id;
vm_paddr_t phys_base_addr;
boolean_t mapped;
- int *errs;
+ BITSET_DEFINE_VAR() *err;
};
static d_ioctl_t privcmd_ioctl;
@@ -138,7 +139,7 @@ retry:
rm.gpfn = atop(map->phys_base_addr) + i;
HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &rm);
}
- free(map->errs, M_PRIVCMD);
+ free(map->err, M_PRIVCMD);
}
error = xenmem_free(privcmd_dev, map->pseudo_phys_res_id,
@@ -160,7 +161,7 @@ privcmd_pg_fault(vm_object_t object, vm_ooffset_t offset,
return (VM_PAGER_FAIL);
pidx = OFF_TO_IDX(offset);
- if (pidx >= map->size || map->errs[pidx] != 0)
+ if (pidx >= map->size || BIT_ISSET(map->size, pidx, map->err))
return (VM_PAGER_FAIL);
page = PHYS_TO_VM_PAGE(map->phys_base_addr + offset);
@@ -249,14 +250,15 @@ privcmd_ioctl(struct cdev *dev, unsigned long cmd, caddr_t arg,
vm_map_t map;
vm_map_entry_t entry;
vm_object_t mem;
- vm_pindex_t index;
+ vm_pindex_t pindex;
vm_prot_t prot;
boolean_t wired;
struct xen_add_to_physmap_range add;
xen_ulong_t *idxs;
xen_pfn_t *gpfns;
- int *errs;
+ int *errs, index;
struct privcmd_map *umap;
+ uint16_t num;
mmap = (struct ioctl_privcmd_mmapbatch *)arg;
@@ -268,7 +270,7 @@ privcmd_ioctl(struct cdev *dev, unsigned long cmd, caddr_t arg,
map = &td->td_proc->p_vmspace->vm_map;
error = vm_map_lookup(&map, mmap->addr, VM_PROT_NONE, &entry,
- &mem, &index, &prot, &wired);
+ &mem, &pindex, &prot, &wired);
if (error != KERN_SUCCESS) {
error = EINVAL;
break;
@@ -289,54 +291,72 @@ privcmd_ioctl(struct cdev *dev, unsigned long cmd, caddr_t arg,
add.domid = DOMID_SELF;
add.space = XENMAPSPACE_gmfn_foreign;
- add.size = mmap->num;
add.foreign_domid = mmap->dom;
- idxs = malloc(sizeof(*idxs) * mmap->num, M_PRIVCMD,
- M_WAITOK | M_ZERO);
- gpfns = malloc(sizeof(*gpfns) * mmap->num, M_PRIVCMD,
- M_WAITOK | M_ZERO);
- errs = malloc(sizeof(*errs) * mmap->num, M_PRIVCMD,
- M_WAITOK | M_ZERO);
+ /*
+ * The 'size' field in the xen_add_to_physmap_range only
+ * allows for UINT16_MAX mappings in a single hypercall.
+ */
+ num = MIN(mmap->num, UINT16_MAX);
+
+ idxs = malloc(sizeof(*idxs) * num, M_PRIVCMD, M_WAITOK);
+ gpfns = malloc(sizeof(*gpfns) * num, M_PRIVCMD, M_WAITOK);
+ errs = malloc(sizeof(*errs) * num, M_PRIVCMD, M_WAITOK);
set_xen_guest_handle(add.idxs, idxs);
set_xen_guest_handle(add.gpfns, gpfns);
set_xen_guest_handle(add.errs, errs);
- error = copyin(&mmap->arr[0], idxs,
- sizeof(idxs[0]) * mmap->num);
- if (error != 0)
- goto mmap_out;
-
- for (i = 0; i < mmap->num; i++)
- gpfns[i] = atop(umap->phys_base_addr + i * PAGE_SIZE);
-
- error = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &add);
- if (error) {
- error = xen_translate_error(error);
- goto mmap_out;
- }
+ /* Allocate a bitset to store broken page mappings. */
+ umap->err = BITSET_ALLOC(mmap->num, M_PRIVCMD,
+ M_WAITOK | M_ZERO);
- for (i = 0; i < mmap->num; i++) {
- if (errs[i] != 0)
- errs[i] = xen_translate_error(errs[i]);
+ for (index = 0; index < mmap->num; index += num) {
+ num = MIN(mmap->num - index, UINT16_MAX);
+ add.size = num;
+
+ error = copyin(&mmap->arr[index], idxs,
+ sizeof(idxs[0]) * num);
+ if (error != 0)
+ goto mmap_out;
+
+ for (i = 0; i < num; i++)
+ gpfns[i] = atop(umap->phys_base_addr +
+ (i + index) * PAGE_SIZE);
+
+ bzero(errs, sizeof(*errs) * num);
+
+ error = HYPERVISOR_memory_op(
+ XENMEM_add_to_physmap_range, &add);
+ if (error != 0) {
+ error = xen_translate_error(error);
+ goto mmap_out;
+ }
+
+ for (i = 0; i < num; i++) {
+ if (errs[i] != 0) {
+ errs[i] = xen_translate_error(errs[i]);
+
+ /* Mark the page as invalid. */
+ BIT_SET(mmap->num, index + i,
+ umap->err);
+ }
+ }
+
+ error = copyout(errs, &mmap->err[index],
+ sizeof(errs[0]) * num);
+ if (error != 0)
+ goto mmap_out;
}
- /*
- * Save errs, so we know which pages have been
- * successfully mapped.
- */
- umap->errs = errs;
umap->mapped = true;
- error = copyout(errs, &mmap->err[0],
- sizeof(errs[0]) * mmap->num);
-
mmap_out:
free(idxs, M_PRIVCMD);
free(gpfns, M_PRIVCMD);
+ free(errs, M_PRIVCMD);
if (!umap->mapped)
- free(errs, M_PRIVCMD);
+ free(umap->err, M_PRIVCMD);
break;
}
diff --git a/sys/dev/xen/timer/timer.c b/sys/dev/xen/timer/timer.c
index 083898c..996399b 100644
--- a/sys/dev/xen/timer/timer.c
+++ b/sys/dev/xen/timer/timer.c
@@ -77,7 +77,12 @@ static devclass_t xentimer_devclass;
/* Xen timers may fire up to 100us off */
#define XENTIMER_MIN_PERIOD_IN_NSEC 100*NSEC_IN_USEC
-#define XENCLOCK_RESOLUTION 1000001 /* ATRTC resolution + 1 */
+
+/*
+ * The real resolution of the PV clock is 1ns, but the highest
+ * resolution that FreeBSD supports is 1us, so just use that.
+ */
+#define XENCLOCK_RESOLUTION 1
#define XENTIMER_QUALITY 950
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index 0d46d95..02b85e7 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -3174,6 +3174,10 @@ nfssvc_idname(struct nfsd_idargs *nidp)
static int onethread = 0;
static time_t lasttime = 0;
+ if (nidp->nid_namelen <= 0 || nidp->nid_namelen > MAXHOSTNAMELEN) {
+ error = EINVAL;
+ goto out;
+ }
if (nidp->nid_flag & NFSID_INITIALIZE) {
cp = malloc(nidp->nid_namelen + 1, M_NFSSTRING, M_WAITOK);
error = copyin(CAST_USER_ADDR_T(nidp->nid_name), cp,
diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c
index 6dd0c32..e5ad4ab 100644
--- a/sys/fs/nfsserver/nfs_nfsdkrpc.c
+++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c
@@ -231,10 +231,16 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
* Get a refcnt (shared lock) on nfsd_suspend_lock.
* NFSSVC_SUSPENDNFSD will take an exclusive lock on
* nfsd_suspend_lock to suspend these threads.
+ * The call to nfsv4_lock() that precedes nfsv4_getref()
+ * ensures that the acquisition of the exclusive lock
+ * takes priority over acquisition of the shared lock by
+ * waiting for any exclusive lock request to complete.
* This must be done here, before the check of
* nfsv4root exports by nfsvno_v4rootexport().
*/
NFSLOCKV4ROOTMUTEX();
+ nfsv4_lock(&nfsd_suspend_lock, 0, NULL, NFSV4ROOTLOCKMUTEXPTR,
+ NULL);
nfsv4_getref(&nfsd_suspend_lock, NULL, NFSV4ROOTLOCKMUTEXPTR,
NULL);
NFSUNLOCKV4ROOTMUTEX();
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c
index 4e995c1..e09116c 100644
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -771,7 +771,12 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
}
if (nfsv4_opflag[op].savereply)
nd->nd_flag |= ND_SAVEREPLY;
- NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]);
+ /*
+ * For now, newnfsstats.srvrpccnt[] doesn't have entries
+ * for the NFSv4.1 operations.
+ */
+ if (nd->nd_procnum < NFSV4OP_NOPS)
+ NFSINCRGLOBAL(newnfsstats.srvrpccnt[nd->nd_procnum]);
switch (op) {
case NFSV4OP_PUTFH:
error = nfsrv_mtofh(nd, &fh);
diff --git a/sys/geom/uzip/g_uzip.c b/sys/geom/uzip/g_uzip.c
index bbb31e4..bdbf723 100644
--- a/sys/geom/uzip/g_uzip.c
+++ b/sys/geom/uzip/g_uzip.c
@@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$");
#include <geom/uzip/g_uzip_lzma.h>
#include <geom/uzip/g_uzip_wrkthr.h>
+#include "opt_geom.h"
+
MALLOC_DEFINE(M_GEOM_UZIP, "geom_uzip", "GEOM UZIP data structures");
FEATURE(geom_uzip, "GEOM read-only compressed disks support");
@@ -576,8 +578,8 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
struct g_provider *pp2;
struct g_uzip_softc *sc;
enum {
- GEOM_UZIP = 1,
- GEOM_ULZMA
+ G_UZIP = 1,
+ G_ULZMA
} type;
g_trace(G_T_TOPOLOGY, "%s(%s,%s)", __func__, mp->name, pp->name);
@@ -621,7 +623,7 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
switch (header->magic[CLOOP_OFS_COMPR]) {
case CLOOP_COMP_LZMA:
case CLOOP_COMP_LZMA_DDP:
- type = GEOM_ULZMA;
+ type = G_ULZMA;
if (header->magic[CLOOP_OFS_VERSN] < CLOOP_MINVER_LZMA) {
DPRINTF(GUZ_DBG_ERR, ("%s: image version too old\n",
gp->name));
@@ -632,7 +634,7 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
break;
case CLOOP_COMP_LIBZ:
case CLOOP_COMP_LIBZ_DDP:
- type = GEOM_UZIP;
+ type = G_UZIP;
if (header->magic[CLOOP_OFS_VERSN] < CLOOP_MINVER_ZLIB) {
DPRINTF(GUZ_DBG_ERR, ("%s: image version too old\n",
gp->name));
@@ -728,7 +730,7 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags)
sc->req_total = 0;
sc->req_cached = 0;
- if (type == GEOM_UZIP) {
+ if (type == G_UZIP) {
sc->dcp = g_uzip_zlib_ctor(sc->blksz);
} else {
sc->dcp = g_uzip_lzma_ctor(sc->blksz);
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index ee2df93..aefc507 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -101,6 +101,7 @@ device cpufreq
# Bus support.
device acpi
device pci
+options PCI_HP # PCI-Express native HotPlug
options PCI_IOV # PCI SR-IOV support
# Floppy drives
diff --git a/sys/isa/isa_common.h b/sys/isa/isa_common.h
index 977e222..18975cb 100644
--- a/sys/isa/isa_common.h
+++ b/sys/isa/isa_common.h
@@ -65,7 +65,7 @@ struct isa_device {
#define DEVTOISA(dev) ((struct isa_device *) device_get_ivars(dev))
/*
- * These functions are architecture dependant.
+ * These functions are architecture dependent.
*/
extern void isa_init(device_t dev);
extern struct resource *isa_alloc_resource(device_t bus, device_t child,
diff --git a/sys/isa/pnp.c b/sys/isa/pnp.c
index 599af84..db37fa6 100644
--- a/sys/isa/pnp.c
+++ b/sys/isa/pnp.c
@@ -450,7 +450,7 @@ pnp_create_devices(device_t parent, pnp_id *p, int csn,
if (dev) {
/*
* This is an optional device
- * indentifier string. Skipt it
+ * identifier string. Skip it
* for now.
*/
continue;
diff --git a/sys/isa/pnpparse.c b/sys/isa/pnpparse.c
index 7f051d6..2f0a1fe 100644
--- a/sys/isa/pnpparse.c
+++ b/sys/isa/pnpparse.c
@@ -499,7 +499,7 @@ pnp_parse_resources(device_t dev, u_char *resources, int len, int ldn)
/*
* Back to the common part; clear it
* as its contents has already been copied
- * to each dependant.
+ * to each dependent.
*/
config = &configs[0];
bzero(config, sizeof(*config));
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index bd8a934..a0b07d1 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -2307,7 +2307,7 @@ fdcloseexec(struct thread *td)
FILEDESC_XLOCK(fdp);
fdfree(fdp, i);
(void) closefp(fdp, i, fp, td, 0);
- /* closefp() drops the FILEDESC lock. */
+ FILEDESC_UNLOCK_ASSERT(fdp);
}
}
}
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 1202903..a891949 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -5186,7 +5186,7 @@ find_device(struct devreq *req, device_t *devp)
}
static bool
-driver_exists(struct device *bus, const char *driver)
+driver_exists(device_t bus, const char *driver)
{
devclass_t dc;
diff --git a/sys/kern/subr_hash.c b/sys/kern/subr_hash.c
index 4d9249f..2aae043 100644
--- a/sys/kern/subr_hash.c
+++ b/sys/kern/subr_hash.c
@@ -41,6 +41,13 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/malloc.h>
+static __inline int
+hash_mflags(int flags)
+{
+
+ return ((flags & HASH_NOWAIT) ? M_NOWAIT : M_WAITOK);
+}
+
/*
* General routine to allocate a hash table with control of memory flags.
*/
@@ -61,13 +68,8 @@ hashinit_flags(int elements, struct malloc_type *type, u_long *hashmask,
continue;
hashsize >>= 1;
- if (flags & HASH_NOWAIT)
- hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl),
- type, M_NOWAIT);
- else
- hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl),
- type, M_WAITOK);
-
+ hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type,
+ hash_mflags(flags));
if (hashtbl != NULL) {
for (i = 0; i < hashsize; i++)
LIST_INIT(&hashtbl[i]);
@@ -112,7 +114,7 @@ phashinit_flags(int elements, struct malloc_type *type, u_long *nentries, int fl
{
long hashsize;
LIST_HEAD(generic, generic) *hashtbl;
- int i, m_flags;
+ int i;
KASSERT(elements > 0, ("%s: bad elements", __func__));
/* Exactly one of HASH_WAITOK and HASH_NOWAIT must be set. */
@@ -127,8 +129,8 @@ phashinit_flags(int elements, struct malloc_type *type, u_long *nentries, int fl
}
hashsize = primes[i - 1];
- m_flags = (flags & HASH_NOWAIT) ? M_NOWAIT : M_WAITOK;
- hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, m_flags);
+ hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type,
+ hash_mflags(flags));
if (hashtbl == NULL)
return (NULL);
diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c
index c5febf5..9b92e73 100644
--- a/sys/kern/subr_intr.c
+++ b/sys/kern/subr_intr.c
@@ -128,7 +128,7 @@ struct intr_dev_data {
device_t idd_dev;
intptr_t idd_xref;
u_int idd_irq;
- struct intr_map_data idd_data;
+ struct intr_map_data * idd_data;
struct intr_irqsrc * idd_isrc;
};
@@ -495,8 +495,10 @@ static struct intr_dev_data *
intr_ddata_alloc(u_int extsize)
{
struct intr_dev_data *ddata;
+ size_t size;
- ddata = malloc(sizeof(*ddata) + extsize, M_INTRNG, M_WAITOK | M_ZERO);
+ size = sizeof(*ddata);
+ ddata = malloc(size + extsize, M_INTRNG, M_WAITOK | M_ZERO);
mtx_lock(&isrc_table_lock);
if (intr_ddata_first_unused >= nitems(intr_ddata_tab)) {
@@ -507,6 +509,9 @@ intr_ddata_alloc(u_int extsize)
intr_ddata_tab[intr_ddata_first_unused] = ddata;
ddata->idd_irq = IRQ_DDATA_BASE + intr_ddata_first_unused++;
mtx_unlock(&isrc_table_lock);
+
+ ddata->idd_data = (struct intr_map_data *)((uintptr_t)ddata + size);
+ ddata->idd_data->size = extsize;
return (ddata);
}
@@ -534,13 +539,13 @@ intr_ddata_lookup(u_int irq, struct intr_map_data **datap)
ddata = intr_ddata_tab[irq];
if (ddata->idd_isrc == NULL) {
error = intr_map_irq(ddata->idd_dev, ddata->idd_xref,
- &ddata->idd_data, &irq);
+ ddata->idd_data, &irq);
if (error != 0)
return (NULL);
ddata->idd_isrc = isrc_lookup(irq);
}
if (datap != NULL)
- *datap = &ddata->idd_data;
+ *datap = ddata->idd_data;
return (ddata->idd_isrc);
}
@@ -554,17 +559,21 @@ u_int
intr_acpi_map_irq(device_t dev, u_int irq, enum intr_polarity pol,
enum intr_trigger trig)
{
+ struct intr_map_data_acpi *daa;
struct intr_dev_data *ddata;
- ddata = intr_ddata_alloc(0);
+ ddata = intr_ddata_alloc(sizeof(struct intr_map_data_acpi));
if (ddata == NULL)
return (INTR_IRQ_INVALID); /* no space left */
ddata->idd_dev = dev;
- ddata->idd_data.type = INTR_MAP_DATA_ACPI;
- ddata->idd_data.acpi.irq = irq;
- ddata->idd_data.acpi.pol = pol;
- ddata->idd_data.acpi.trig = trig;
+ ddata->idd_data->type = INTR_MAP_DATA_ACPI;
+
+ daa = (struct intr_map_data_acpi *)ddata->idd_data;
+ daa->irq = irq;
+ daa->pol = pol;
+ daa->trig = trig;
+
return (ddata->idd_irq);
}
#endif
@@ -577,19 +586,21 @@ intr_acpi_map_irq(device_t dev, u_int irq, enum intr_polarity pol,
u_int
intr_fdt_map_irq(phandle_t node, pcell_t *cells, u_int ncells)
{
+ size_t cellsize;
struct intr_dev_data *ddata;
- u_int cellsize;
+ struct intr_map_data_fdt *daf;
cellsize = ncells * sizeof(*cells);
- ddata = intr_ddata_alloc(cellsize);
+ ddata = intr_ddata_alloc(sizeof(struct intr_map_data_fdt) + cellsize);
if (ddata == NULL)
return (INTR_IRQ_INVALID); /* no space left */
ddata->idd_xref = (intptr_t)node;
- ddata->idd_data.type = INTR_MAP_DATA_FDT;
- ddata->idd_data.fdt.ncells = ncells;
- ddata->idd_data.fdt.cells = (pcell_t *)(ddata + 1);
- memcpy(ddata->idd_data.fdt.cells, cells, cellsize);
+ ddata->idd_data->type = INTR_MAP_DATA_FDT;
+
+ daf = (struct intr_map_data_fdt *)ddata->idd_data;
+ daf->ncells = ncells;
+ memcpy(daf->cells, cells, cellsize);
return (ddata->idd_irq);
}
#endif
@@ -602,16 +613,19 @@ u_int
intr_gpio_map_irq(device_t dev, u_int pin_num, u_int pin_flags, u_int intr_mode)
{
struct intr_dev_data *ddata;
+ struct intr_map_data_gpio *dag;
- ddata = intr_ddata_alloc(0);
+ ddata = intr_ddata_alloc(sizeof(struct intr_map_data_gpio));
if (ddata == NULL)
return (INTR_IRQ_INVALID); /* no space left */
ddata->idd_dev = dev;
- ddata->idd_data.type = INTR_MAP_DATA_GPIO;
- ddata->idd_data.gpio.gpio_pin_num = pin_num;
- ddata->idd_data.gpio.gpio_pin_flags = pin_flags;
- ddata->idd_data.gpio.gpio_intr_mode = intr_mode;
+ ddata->idd_data->type = INTR_MAP_DATA_GPIO;
+
+ dag = (struct intr_map_data_gpio *)ddata->idd_data;
+ dag->gpio_pin_num = pin_num;
+ dag->gpio_pin_flags = pin_flags;
+ dag->gpio_intr_mode = intr_mode;
return (ddata->idd_irq);
}
@@ -857,6 +871,10 @@ pic_create(device_t dev, intptr_t xref)
return (pic);
}
pic = malloc(sizeof(*pic), M_INTRNG, M_NOWAIT | M_ZERO);
+ if (pic == NULL) {
+ mtx_unlock(&pic_list_lock);
+ return (NULL);
+ }
pic->pic_xref = xref;
pic->pic_dev = dev;
SLIST_INSERT_HEAD(&pic_list, pic, pic_next);
@@ -971,7 +989,7 @@ intr_map_irq(device_t dev, intptr_t xref, struct intr_map_data *data,
return (EINVAL);
pic = pic_lookup(dev, xref);
- if (pic == NULL || pic->pic_dev == NULL)
+ if (pic == NULL)
return (ESRCH);
error = PIC_MAP_INTR(pic->pic_dev, data, &isrc);
diff --git a/sys/kern/subr_rman.c b/sys/kern/subr_rman.c
index 9bbec64..d1c68b45 100644
--- a/sys/kern/subr_rman.c
+++ b/sys/kern/subr_rman.c
@@ -94,7 +94,7 @@ struct resource_i {
rman_res_t r_end; /* index of the last entry (inclusive) */
u_int r_flags;
void *r_virtual; /* virtual address of this resource */
- struct device *r_dev; /* device which has allocated this resource */
+ device_t r_dev; /* device which has allocated this resource */
struct rman *r_rm; /* resource manager from whence this came */
int r_rid; /* optional rid for this resource. */
};
@@ -436,7 +436,7 @@ rman_adjust_resource(struct resource *rr, rman_res_t start, rman_res_t end)
struct resource *
rman_reserve_resource_bound(struct rman *rm, rman_res_t start, rman_res_t end,
rman_res_t count, rman_res_t bound, u_int flags,
- struct device *dev)
+ device_t dev)
{
u_int new_rflags;
struct resource_i *r, *s, *rv;
@@ -652,7 +652,7 @@ out:
struct resource *
rman_reserve_resource(struct rman *rm, rman_res_t start, rman_res_t end,
- rman_res_t count, u_int flags, struct device *dev)
+ rman_res_t count, u_int flags, device_t dev)
{
return (rman_reserve_resource_bound(rm, start, end, count, 0, flags,
@@ -911,13 +911,13 @@ rman_get_rid(struct resource *r)
}
void
-rman_set_device(struct resource *r, struct device *dev)
+rman_set_device(struct resource *r, device_t dev)
{
r->__r_i->r_dev = dev;
}
-struct device *
+device_t
rman_get_device(struct resource *r)
{
diff --git a/sys/kern/subr_rtc.c b/sys/kern/subr_rtc.c
index ed2befc..5d4167d 100644
--- a/sys/kern/subr_rtc.c
+++ b/sys/kern/subr_rtc.c
@@ -84,7 +84,7 @@ clock_register(device_t dev, long res) /* res has units of microseconds */
{
if (clock_dev != NULL) {
- if (clock_res > res) {
+ if (clock_res <= res) {
if (bootverbose)
device_printf(dev, "not installed as "
"time-of-day clock: clock %s has higher "
diff --git a/sys/kern/subr_unit.c b/sys/kern/subr_unit.c
index 8283550..9da9160 100644
--- a/sys/kern/subr_unit.c
+++ b/sys/kern/subr_unit.c
@@ -67,13 +67,13 @@
* N is the number of the highest unit allocated.
*/
+#include <sys/param.h>
#include <sys/types.h>
#include <sys/_unrhdr.h>
#ifdef _KERNEL
#include <sys/bitstring.h>
-#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -169,7 +169,7 @@ mtx_assert(struct mtx *mp, int flag)
* element:
* If ptr is NULL, it represents a run of free items.
* If ptr points to the unrhdr it represents a run of allocated items.
- * Otherwise it points to an bitstring of allocated items.
+ * Otherwise it points to a bitstring of allocated items.
*
* For runs the len field is the length of the run.
* For bitmaps the len field represents the number of allocated items.
@@ -183,14 +183,33 @@ struct unr {
};
struct unrb {
- u_char busy;
- bitstr_t map[sizeof(struct unr) - 1];
+ bitstr_t map[sizeof(struct unr) / sizeof(bitstr_t)];
};
-CTASSERT(sizeof(struct unr) == sizeof(struct unrb));
+CTASSERT((sizeof(struct unr) % sizeof(bitstr_t)) == 0);
+
+/* Number of bits we can store in the bitmap */
+#define NBITS (8 * sizeof(((struct unrb*)NULL)->map))
+
+/* Is the unrb empty in at least the first len bits? */
+static inline bool
+ub_empty(struct unrb *ub, int len) {
+ int first_set;
+
+ bit_ffs(ub->map, len, &first_set);
+ return (first_set == -1);
+}
+
+/* Is the unrb full? That is, is the number of set elements equal to len? */
+static inline bool
+ub_full(struct unrb *ub, int len)
+{
+ int first_clear;
+
+ bit_ffc(ub->map, len, &first_clear);
+ return (first_clear == -1);
+}
-/* Number of bits in the bitmap */
-#define NBITS ((int)sizeof(((struct unrb *)NULL)->map) * 8)
#if defined(DIAGNOSTIC) || !defined(_KERNEL)
/*
@@ -214,16 +233,13 @@ check_unrhdr(struct unrhdr *uh, int line)
if (up->ptr != uh && up->ptr != NULL) {
ub = up->ptr;
KASSERT (up->len <= NBITS,
- ("UNR inconsistency: len %u max %d (line %d)\n",
+ ("UNR inconsistency: len %u max %zd (line %d)\n",
up->len, NBITS, line));
z++;
w = 0;
for (x = 0; x < up->len; x++)
if (bit_test(ub->map, x))
w++;
- KASSERT (w == ub->busy,
- ("UNR inconsistency: busy %u found %u (line %d)\n",
- ub->busy, w, line));
y += w;
} else if (up->ptr != NULL)
y += up->len;
@@ -239,7 +255,7 @@ check_unrhdr(struct unrhdr *uh, int line)
#else
static __inline void
-check_unrhdr(struct unrhdr *uh, int line)
+check_unrhdr(struct unrhdr *uh __unused, int line __unused)
{
}
@@ -417,32 +433,24 @@ optimize_unr(struct unrhdr *uh)
a = us->len;
l = us->ptr == uh ? 1 : 0;
ub = (void *)us;
- ub->busy = 0;
- if (l) {
+ bit_nclear(ub->map, 0, NBITS - 1);
+ if (l)
bit_nset(ub->map, 0, a);
- ub->busy += a;
- } else {
- bit_nclear(ub->map, 0, a);
- }
if (!is_bitmap(uh, uf)) {
- if (uf->ptr == NULL) {
+ if (uf->ptr == NULL)
bit_nclear(ub->map, a, a + uf->len - 1);
- } else {
+ else
bit_nset(ub->map, a, a + uf->len - 1);
- ub->busy += uf->len;
- }
uf->ptr = ub;
uf->len += a;
us = uf;
} else {
ubf = uf->ptr;
for (l = 0; l < uf->len; l++, a++) {
- if (bit_test(ubf->map, l)) {
+ if (bit_test(ubf->map, l))
bit_set(ub->map, a);
- ub->busy++;
- } else {
+ else
bit_clear(ub->map, a);
- }
}
uf->len = a;
delete_unr(uh, uf->ptr);
@@ -464,19 +472,16 @@ optimize_unr(struct unrhdr *uh)
delete_unr(uh, uf);
} else if (uf->ptr == uh) {
bit_nset(ub->map, us->len, us->len + uf->len - 1);
- ub->busy += uf->len;
us->len += uf->len;
TAILQ_REMOVE(&uh->head, uf, list);
delete_unr(uh, uf);
} else {
ubf = uf->ptr;
for (l = 0; l < uf->len; l++, us->len++) {
- if (bit_test(ubf->map, l)) {
+ if (bit_test(ubf->map, l))
bit_set(ub->map, us->len);
- ub->busy++;
- } else {
+ else
bit_clear(ub->map, us->len);
- }
}
TAILQ_REMOVE(&uh->head, uf, list);
delete_unr(uh, ubf);
@@ -499,10 +504,10 @@ collapse_unr(struct unrhdr *uh, struct unr *up)
/* If bitmap is all set or clear, change it to runlength */
if (is_bitmap(uh, up)) {
ub = up->ptr;
- if (ub->busy == up->len) {
+ if (ub_full(ub, up->len)) {
delete_unr(uh, up->ptr);
up->ptr = uh;
- } else if (ub->busy == 0) {
+ } else if (ub_empty(ub, up->len)) {
delete_unr(uh, up->ptr);
up->ptr = NULL;
}
@@ -600,11 +605,9 @@ alloc_unrl(struct unrhdr *uh)
up->len--;
} else { /* bitmap */
ub = up->ptr;
- KASSERT(ub->busy < up->len, ("UNR bitmap confusion"));
bit_ffc(ub->map, up->len, &y);
KASSERT(y != -1, ("UNR corruption: No clear bit in bitmap."));
bit_set(ub->map, y);
- ub->busy++;
x += y;
}
uh->busy++;
@@ -688,7 +691,6 @@ alloc_unr_specificl(struct unrhdr *uh, u_int item, void **p1, void **p2)
ub = up->ptr;
if (bit_test(ub->map, i) == 0) {
bit_set(ub->map, i);
- ub->busy++;
goto done;
} else
return (-1);
@@ -807,7 +809,6 @@ free_unrl(struct unrhdr *uh, u_int item, void **p1, void **p2)
("UNR: Freeing free item %d (bitmap)\n", item));
bit_clear(ub->map, item);
uh->busy--;
- ub->busy--;
collapse_unr(uh, up);
return;
}
@@ -905,7 +906,7 @@ print_unr(struct unrhdr *uh, struct unr *up)
printf("alloc\n");
else {
ub = up->ptr;
- printf("bitmap(%d) [", ub->busy);
+ printf("bitmap [");
for (x = 0; x < up->len; x++) {
if (bit_test(ub->map, x))
printf("#");
@@ -1025,7 +1026,7 @@ main(int argc, char **argv)
printf("sizeof(struct unr) %zu\n", sizeof(struct unr));
printf("sizeof(struct unrb) %zu\n", sizeof(struct unrb));
printf("sizeof(struct unrhdr) %zu\n", sizeof(struct unrhdr));
- printf("NBITS %d\n", NBITS);
+ printf("NBITS %lu\n", (unsigned long)NBITS);
x = 1;
for (m = 0; m < count * reps; m++) {
j = random();
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 795eac5..97ab886 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -4722,6 +4722,45 @@ vop_symlink_post(void *ap, int rc)
VFS_KNOTE_LOCKED(a->a_dvp, NOTE_WRITE);
}
+void
+vop_open_post(void *ap, int rc)
+{
+ struct vop_open_args *a = ap;
+
+ if (!rc)
+ VFS_KNOTE_LOCKED(a->a_vp, NOTE_OPEN);
+}
+
+void
+vop_close_post(void *ap, int rc)
+{
+ struct vop_close_args *a = ap;
+
+ if (!rc && (a->a_cred != NOCRED || /* filter out revokes */
+ (a->a_vp->v_iflag & VI_DOOMED) == 0)) {
+ VFS_KNOTE_LOCKED(a->a_vp, (a->a_fflag & FWRITE) != 0 ?
+ NOTE_CLOSE_WRITE : NOTE_CLOSE);
+ }
+}
+
+void
+vop_read_post(void *ap, int rc)
+{
+ struct vop_read_args *a = ap;
+
+ if (!rc)
+ VFS_KNOTE_LOCKED(a->a_vp, NOTE_READ);
+}
+
+void
+vop_readdir_post(void *ap, int rc)
+{
+ struct vop_readdir_args *a = ap;
+
+ if (!rc)
+ VFS_KNOTE_LOCKED(a->a_vp, NOTE_READ);
+}
+
static struct knlist fs_knlist;
static void
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index 1b07a36..0350e0e 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -121,6 +121,7 @@ vop_mknod {
%% open vp L L L
+%! open post vop_open_post
vop_open {
IN struct vnode *vp;
@@ -132,6 +133,7 @@ vop_open {
%% close vp L L L
+%! close post vop_close_post
vop_close {
IN struct vnode *vp;
@@ -186,6 +188,7 @@ vop_markatime {
};
%% read vp L L L
+%! read post vop_read_post
vop_read {
IN struct vnode *vp;
@@ -326,6 +329,7 @@ vop_symlink {
%% readdir vp L L L
+%! readdir post vop_readdir_post
vop_readdir {
IN struct vnode *vp;
diff --git a/sys/kgssapi/krb5/krb5_mech.c b/sys/kgssapi/krb5/krb5_mech.c
index 4cfea58..38db0d2 100644
--- a/sys/kgssapi/krb5/krb5_mech.c
+++ b/sys/kgssapi/krb5/krb5_mech.c
@@ -1339,7 +1339,7 @@ krb5_wrap_old(struct krb5_context *kc, int conf_req_flag,
* SND_SEQ:
*
* Take the four bytes of the sequence number least
- * significant first (most signficant first for ARCFOUR)
+ * significant first (most significant first for ARCFOUR)
* followed by four bytes of direction marker (zero for
* initiator and 0xff for acceptor). Encrypt that data using
* the SGN_CKSUM as IV.
diff --git a/sys/mips/mediatek/mtk_gpio_v1.c b/sys/mips/mediatek/mtk_gpio_v1.c
index 5499263..7ca3a12 100644
--- a/sys/mips/mediatek/mtk_gpio_v1.c
+++ b/sys/mips/mediatek/mtk_gpio_v1.c
@@ -290,7 +290,7 @@ mtk_gpio_attach(device_t dev)
else
sc->num_pins = MTK_GPIO_PINS;
- for (i = 0; i < num_pins; i++) {
+ for (i = 0; i < sc->num_pins; i++) {
sc->pins[i].pin_caps |= GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
GPIO_PIN_INVIN | GPIO_PIN_INVOUT;
sc->pins[i].intr_polarity = INTR_POLARITY_HIGH;
@@ -444,18 +444,12 @@ mtk_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
return (EINVAL);
MTK_GPIO_LOCK(sc);
- if(!(sc->pins[pin].pin_flags & GPIO_PIN_OUTPUT)) {
- ret = EINVAL;
- goto out;
- }
-
if (value)
MTK_WRITE_4(sc, GPIO_PIOSET, (1u << pin));
else
MTK_WRITE_4(sc, GPIO_PIORESET, (1u << pin));
-
-out:
MTK_GPIO_UNLOCK(sc);
+
return (ret);
}
@@ -473,15 +467,10 @@ mtk_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
return (EINVAL);
MTK_GPIO_LOCK(sc);
- if(!(sc->pins[pin].pin_flags & GPIO_PIN_INPUT)) {
- ret = EINVAL;
- goto out;
- }
data = MTK_READ_4(sc, GPIO_PIODATA);
*val = (data & (1u << pin)) ? 1 : 0;
-
-out:
MTK_GPIO_UNLOCK(sc);
+
return (ret);
}
@@ -491,12 +480,12 @@ mtk_gpio_pin_toggle(device_t dev, uint32_t pin)
struct mtk_gpio_softc *sc;
int ret;
- if (pin >= sc->num_pins)
- return (EINVAL);
-
sc = device_get_softc(dev);
ret = 0;
+ if (pin >= sc->num_pins)
+ return (EINVAL);
+
MTK_GPIO_LOCK(sc);
if (!(sc->pins[pin].pin_flags & GPIO_PIN_OUTPUT)) {
ret = EINVAL;
@@ -514,15 +503,19 @@ static int
mtk_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct mtk_gpio_softc *sc;
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
sc = device_get_softc(dev);
+ daf = (struct intr_map_data_fdt *)data;
- if (data == NULL || data->type != INTR_MAP_DATA_FDT ||
- data->fdt.ncells != 1 || data->fdt.cells[0] >= sc->num_pins)
+ if (daf->ncells != 1 || daf->cells[0] >= sc->num_pins)
return (EINVAL);
- *isrcp = PIC_INTR_ISRC(sc, data->fdt.cells[0]);
+ *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]);
return (0);
}
diff --git a/sys/mips/mediatek/mtk_gpio_v2.c b/sys/mips/mediatek/mtk_gpio_v2.c
index c7c0326..75c7263 100644
--- a/sys/mips/mediatek/mtk_gpio_v2.c
+++ b/sys/mips/mediatek/mtk_gpio_v2.c
@@ -428,23 +428,17 @@ mtk_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
struct mtk_gpio_softc *sc;
int ret;
- if (pin >= sc->num_pins)
- return (EINVAL);
-
sc = device_get_softc(dev);
ret = 0;
+ if (pin >= sc->num_pins)
+ return (EINVAL);
+
MTK_GPIO_LOCK(sc);
- if (!(sc->pins[pin].pin_flags & GPIO_PIN_OUTPUT)) {
- ret = EINVAL;
- goto out;
- }
if (value)
MTK_WRITE_4(sc, GPIO_PIOSET(sc), (1u << pin));
else
MTK_WRITE_4(sc, GPIO_PIORESET(sc), (1u << pin));
-
-out:
MTK_GPIO_UNLOCK(sc);
return (ret);
@@ -457,22 +451,17 @@ mtk_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
uint32_t data;
int ret;
- if (pin >= sc->num_pins)
- return (EINVAL);
-
sc = device_get_softc(dev);
ret = 0;
+ if (pin >= sc->num_pins)
+ return (EINVAL);
+
MTK_GPIO_LOCK(sc);
- if (!(sc->pins[pin].pin_flags & GPIO_PIN_INPUT)) {
- ret = EINVAL;
- goto out;
- }
data = MTK_READ_4(sc, GPIO_PIODATA(sc));
*val = (data & (1u << pin)) ? 1 : 0;
-
-out:
MTK_GPIO_UNLOCK(sc);
+
return (ret);
}
@@ -483,12 +472,12 @@ mtk_gpio_pin_toggle(device_t dev, uint32_t pin)
uint32_t val;
int ret;
- if (pin >= sc->num_pins)
- return (EINVAL);
-
sc = device_get_softc(dev);
ret = 0;
+ if (pin >= sc->num_pins)
+ return (EINVAL);
+
MTK_GPIO_LOCK(sc);
if(!(sc->pins[pin].pin_flags & GPIO_PIN_OUTPUT)) {
ret = EINVAL;
@@ -511,15 +500,19 @@ static int
mtk_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct mtk_gpio_softc *sc;
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
sc = device_get_softc(dev);
+ daf = (struct intr_map_data_fdt *)data;
- if (data == NULL || data->type != INTR_MAP_DATA_FDT ||
- data->fdt.ncells != 1 || data->fdt.cells[0] >= sc->num_pins)
+ if (daf->ncells != 1 || daf->cells[0] >= sc->num_pins)
return (EINVAL);
- *isrcp = PIC_INTR_ISRC(sc, data->fdt.cells[0]);
+ *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]);
return (0);
}
diff --git a/sys/mips/mediatek/mtk_intr_gic.c b/sys/mips/mediatek/mtk_intr_gic.c
index 5c25045..ea8c887 100644
--- a/sys/mips/mediatek/mtk_intr_gic.c
+++ b/sys/mips/mediatek/mtk_intr_gic.c
@@ -265,18 +265,22 @@ mtk_gic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
#ifdef FDT
+ struct intr_map_data_fdt *daf;
struct mtk_gic_softc *sc;
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
sc = device_get_softc(dev);
+ daf = (struct intr_map_data_fdt *)data;
- if (data == NULL || data->type != INTR_MAP_DATA_FDT ||
- data->fdt.ncells != 3 || data->fdt.cells[1] >= sc->nirqs)
+ if (daf->ncells != 3 || daf->cells[1] >= sc->nirqs)
return (EINVAL);
- *isrcp = GIC_INTR_ISRC(sc, data->fdt.cells[1]);
+ *isrcp = GIC_INTR_ISRC(sc, daf->cells[1]);
return (0);
#else
- return (EINVAL);
+ return (ENOTSUP);
#endif
}
diff --git a/sys/mips/mediatek/mtk_intr_v1.c b/sys/mips/mediatek/mtk_intr_v1.c
index f1ae3a2..58b610d 100644
--- a/sys/mips/mediatek/mtk_intr_v1.c
+++ b/sys/mips/mediatek/mtk_intr_v1.c
@@ -275,18 +275,22 @@ mtk_pic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
#ifdef FDT
+ struct intr_map_data_fdt *daf;
struct mtk_pic_softc *sc;
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
sc = device_get_softc(dev);
+ daf = (struct intr_map_data_fdt *)data;
- if (data == NULL || data->type != INTR_MAP_DATA_FDT ||
- data->fdt.ncells != 1 || data->fdt.cells[0] >= sc->nirqs)
+ if (daf->ncells != 1 || daf->cells[0] >= sc->nirqs)
return (EINVAL);
- *isrcp = PIC_INTR_ISRC(sc, data->fdt.cells[0]);
+ *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]);
return (0);
#else
- return (EINVAL);
+ return (ENOTSUP);
#endif
}
diff --git a/sys/mips/mediatek/mtk_intr_v2.c b/sys/mips/mediatek/mtk_intr_v2.c
index 5a9646e..556738f 100644
--- a/sys/mips/mediatek/mtk_intr_v2.c
+++ b/sys/mips/mediatek/mtk_intr_v2.c
@@ -270,18 +270,22 @@ mtk_pic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
#ifdef FDT
+ struct intr_map_data_fdt *daf;
struct mtk_pic_softc *sc;
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
sc = device_get_softc(dev);
+ daf = (struct intr_map_data_fdt *)data;
- if (data == NULL || data->type != INTR_MAP_DATA_FDT ||
- data->fdt.ncells != 1 || data->fdt.cells[0] >= sc->nirqs)
+ if (daf->ncells != 1 || daf->cells[0] >= sc->nirqs)
return (EINVAL);
- *isrcp = PIC_INTR_ISRC(sc, data->fdt.cells[0]);
+ *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]);
return (0);
#else
- return (EINVAL);
+ return (ENOTSUP);
#endif
}
diff --git a/sys/mips/mediatek/mtk_spi_v1.c b/sys/mips/mediatek/mtk_spi_v1.c
index 1835b8e..9cf8faa 100644
--- a/sys/mips/mediatek/mtk_spi_v1.c
+++ b/sys/mips/mediatek/mtk_spi_v1.c
@@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/cpu.h>
-//#include <machine/pmap.h>
#include <dev/spibus/spi.h>
#include <dev/spibus/spibusvar.h>
@@ -166,7 +165,6 @@ mtk_spi_detach(device_t dev)
static void
mtk_spi_chip_activate(struct mtk_spi_softc *sc)
{
-// printf("%s\n", __func__);
mtk_spi_wait(sc);
/*
* Put all CSx to low
@@ -177,7 +175,6 @@ mtk_spi_chip_activate(struct mtk_spi_softc *sc)
static void
mtk_spi_chip_deactivate(struct mtk_spi_softc *sc)
{
-// printf("%s\n", __func__);
mtk_spi_wait(sc);
/*
* Put all CSx to high
@@ -212,14 +209,12 @@ mtk_spi_txrx(struct mtk_spi_softc *sc, uint8_t *data, int write)
if (write == MTK_SPI_WRITE) {
SPI_WRITE(sc, MTK_SPIDATA, *data);
SPI_SET_BITS(sc, MTK_SPICTL, START_WRITE);
- //printf("%s(W:%d)\n", __func__, *data);
} else {/* MTK_SPI_READ */
SPI_SET_BITS(sc, MTK_SPICTL, START_READ);
if (mtk_spi_wait(sc))
return (EBUSY);
*data = SPI_READ(sc, MTK_SPIDATA) & 0xff;
- //printf("%s(R:%d)\n", __func__, *data);
}
return (0);
}
diff --git a/sys/mips/mediatek/mtk_spi_v2.c b/sys/mips/mediatek/mtk_spi_v2.c
index 0ffd976..1f85ca3 100644
--- a/sys/mips/mediatek/mtk_spi_v2.c
+++ b/sys/mips/mediatek/mtk_spi_v2.c
@@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/cpu.h>
-//#include <machine/pmap.h>
#include <dev/spibus/spi.h>
#include <dev/spibus/spibusvar.h>
@@ -157,8 +156,6 @@ mtk_spi_detach(device_t dev)
{
struct mtk_spi_softc *sc = device_get_softc(dev);
- //SPI_SET_BITS(sc, MTK_SPICTL, HIZSMOSI | CS_HIGH);
-
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
@@ -168,7 +165,6 @@ mtk_spi_detach(device_t dev)
static void
mtk_spi_chip_activate(struct mtk_spi_softc *sc)
{
-// printf("%s\n", __func__);
mtk_spi_wait(sc);
/*
* Put all CSx to low
@@ -179,7 +175,6 @@ mtk_spi_chip_activate(struct mtk_spi_softc *sc)
static void
mtk_spi_chip_deactivate(struct mtk_spi_softc *sc)
{
-// printf("%s\n", __func__);
mtk_spi_wait(sc);
/*
* Put all CSx to high
@@ -197,7 +192,6 @@ mtk_spi_wait(struct mtk_spi_softc *sc)
break;
}
if (i == 0) {
- //printf("busy\n");
return (1);
}
diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S
index ed02e5a..725ae65 100644
--- a/sys/mips/mips/exception.S
+++ b/sys/mips/mips/exception.S
@@ -69,13 +69,6 @@
#ifdef KDTRACE_HOOKS
.data
- .globl dtrace_invop_jump_addr
- .align 4
- .type dtrace_invop_jump_addr, @object
- .size dtrace_invop_jump_addr, 8
-dtrace_invop_jump_addr:
- .word 0
- .word 0
.globl dtrace_invop_calltrap_addr
.align 4
.type dtrace_invop_calltrap_addr, @object
diff --git a/sys/mips/mips/mips_pic.c b/sys/mips/mips/mips_pic.c
index a24647d..9b7eeb0 100644
--- a/sys/mips/mips/mips_pic.c
+++ b/sys/mips/mips/mips_pic.c
@@ -305,18 +305,22 @@ mips_pic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
#ifdef FDT
+ struct intr_map_data_fdt *daf;
struct mips_pic_softc *sc;
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
sc = device_get_softc(dev);
+ daf = (struct intr_map_data_fdt *)data;
- if (data == NULL || data->type != INTR_MAP_DATA_FDT ||
- data->fdt.ncells != 1 || data->fdt.cells[0] >= sc->nirqs)
+ if (daf->ncells != 1 || daf->cells[0] >= sc->nirqs)
return (EINVAL);
- *isrcp = PIC_INTR_ISRC(sc, data->fdt.cells[0]);
+ *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]);
return (0);
#else
- return (EINVAL);
+ return (ENOTSUP);
#endif
}
diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c
index f3ef629..f98fc97 100644
--- a/sys/mips/mips/trap.c
+++ b/sys/mips/mips/trap.c
@@ -160,6 +160,8 @@ static void log_bad_page_fault(char *, struct trapframe *, int);
static void log_frame_dump(struct trapframe *frame);
static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
+int (*dtrace_invop_jump_addr)(struct trapframe *);
+
#ifdef TRAP_DEBUG
static void trap_frame_dump(struct trapframe *frame);
#endif
@@ -808,11 +810,19 @@ dofault:
return (trapframe->pc);
}
-#ifdef DDB
+#if defined(KDTRACE_HOOKS) || defined(DDB)
case T_BREAK:
+#ifdef KDTRACE_HOOKS
+ if (!usermode && dtrace_invop_jump_addr != 0) {
+ dtrace_invop_jump_addr(trapframe);
+ return (trapframe->pc);
+ }
+#endif
+#ifdef DDB
kdb_trap(type, 0, trapframe);
return (trapframe->pc);
#endif
+#endif
case T_BREAK + T_USER:
{
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index e2c2205..57e27b0 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -50,7 +50,9 @@ SUBDIR= \
${_auxio} \
${_bce} \
bfe \
+ bhnd \
bge \
+ bhnd \
${_bxe} \
${_bios} \
${_bktr} \
@@ -58,6 +60,7 @@ SUBDIR= \
bridgestp \
bwi \
bwn \
+ bwn_pci \
cam \
${_canbepm} \
${_canbus} \
diff --git a/sys/modules/bhnd/Makefile b/sys/modules/bhnd/Makefile
index 862b56d..9ef9d13 100644
--- a/sys/modules/bhnd/Makefile
+++ b/sys/modules/bhnd/Makefile
@@ -1,10 +1,16 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../dev/bhnd
+.PATH: ${.CURDIR}/../../dev/bhnd/nvram
KMOD= bhnd
SRCS= bhnd.c bhnd_subr.c \
- bhnd_bus_if.c bhnd_bus_if.h bhnd_nvram_if.h
+ bhnd_sprom.c nvram_subr.c \
+ bhnd_nvram_map.h bhnd_nvram_map_data.h
+
+SRCS+= bhnd_bus_if.c bhnd_bus_if.h \
+ bhnd_chipc_if.c bhnd_chipc_if.h \
+ bhnd_nvram_if.c bhnd_nvram_if.h
SRCS+= device_if.h bus_if.h
@@ -13,7 +19,6 @@ SUBDIR= bcma \
bhndb \
bhndb_pci \
cores \
- nvram \
siba \
siba_bhndb
diff --git a/sys/modules/bhnd/bhndb/Makefile b/sys/modules/bhnd/bhndb/Makefile
index 06822de..7188009 100644
--- a/sys/modules/bhnd/bhndb/Makefile
+++ b/sys/modules/bhnd/bhndb/Makefile
@@ -5,9 +5,11 @@
KMOD= bhndb
SRCS= bhndb.c bhndb_subr.c bhndb_hwdata.c \
bhndb_bus_if.c bhndb_bus_if.h \
- bhndb_if.c bhndb_if.h \
- bhnd_bus_if.h
+ bhndb_if.c bhndb_if.h
+SRCS+= bhnd_bus_if.h \
+ bhnd_chipc_if.h \
+ bhnd_nvram_if.h
-SRCS+= device_if.h bus_if.h
+SRCS+= device_if.h bus_if.h pci_if.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/bhnd/bhndb_pci/Makefile b/sys/modules/bhnd/bhndb_pci/Makefile
index a327aa5..f10845a 100644
--- a/sys/modules/bhnd/bhndb_pci/Makefile
+++ b/sys/modules/bhnd/bhndb_pci/Makefile
@@ -3,9 +3,11 @@
.PATH: ${.CURDIR}/../../../dev/bhnd/bhndb
KMOD= bhndb_pci
-SRCS= bhndb_pci.c bhndb_pci_hwdata.c
+SRCS= bhndb_pci.c bhndb_pci_hwdata.c \
+ bhndb_pci_sprom.c
SRCS+= bhnd_bus_if.h bhndb_bus_if.h bhndb_if.h
+SRCS+= bhnd_nvram_if.h
-SRCS+= device_if.h bus_if.h
+SRCS+= device_if.h bus_if.h pci_if.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/bhnd/cores/bhnd_chipc/Makefile b/sys/modules/bhnd/cores/bhnd_chipc/Makefile
index d35409d..bb75aad 100644
--- a/sys/modules/bhnd/cores/bhnd_chipc/Makefile
+++ b/sys/modules/bhnd/cores/bhnd_chipc/Makefile
@@ -3,8 +3,8 @@
.PATH: ${.CURDIR}/../../../../dev/bhnd/cores/chipc
KMOD= bhnd_chipc
-SRCS= chipc.c \
- bhnd_chipc_if.c bhnd_chipc_if.h
-SRCS+= device_if.h bus_if.h bhnd_bus_if.h
+SRCS= chipc.c
+SRCS+= device_if.h bus_if.h bhnd_bus_if.h \
+ bhnd_chipc_if.h bhnd_nvram_if.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/bhnd/nvram/Makefile b/sys/modules/bhnd/nvram/Makefile
deleted file mode 100644
index 6c6d203..0000000
--- a/sys/modules/bhnd/nvram/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../../dev/bhnd/nvram
-
-KMOD= bhnd_nvram
-SRCS= bhnd_nvram_if.c bhnd_nvram_if.h bhnd_bus_if.h
-
-SRCS+= device_if.h bus_if.h
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/bwn_pci/Makefile b/sys/modules/bwn_pci/Makefile
new file mode 100644
index 0000000..355bc2a
--- /dev/null
+++ b/sys/modules/bwn_pci/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../dev/bwn
+
+KMOD= if_bwn_pci
+SRCS= if_bwn_pci.c bwn_mac.c
+SRCS+= bhnd_bus_if.h bhndb_bus_if.h \
+ bhndb_if.h bhnd_nvram_map.h
+SRCS+= device_if.h bus_if.h pci_if.h \
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/igb/Makefile b/sys/modules/igb/Makefile
index 57a74fa..4db9608 100644
--- a/sys/modules/igb/Makefile
+++ b/sys/modules/igb/Makefile
@@ -17,7 +17,7 @@ CFLAGS += -I${.CURDIR}/../../dev/e1000 -DSMP
# IGB_LEGACY_TX will override the stack if_transmit path and
# instead use the older if_start non-multiqueue capable interface.
-# This might be desireable for testing, or to enable the use of
+# This might be desirable for testing, or to enable the use of
# ALTQ.
#CFLAGS += -DIGB_LEGACY_TX
diff --git a/sys/modules/tests/callout_test/Makefile b/sys/modules/tests/callout_test/Makefile
index eadcadc..4781488 100644
--- a/sys/modules/tests/callout_test/Makefile
+++ b/sys/modules/tests/callout_test/Makefile
@@ -2,10 +2,6 @@
# $FreeBSD$
#
-PACKAGE= tests
-FILESGROUPS= TESTS
-TESTSPACKAGE= ${PACKAGE}
-
.PATH: ${.CURDIR}/../../../tests/callout_test
KMOD= callout_test
diff --git a/sys/modules/tests/framework/Makefile b/sys/modules/tests/framework/Makefile
index c56838d..f5f608f 100644
--- a/sys/modules/tests/framework/Makefile
+++ b/sys/modules/tests/framework/Makefile
@@ -2,10 +2,6 @@
# $FreeBSD$
#
-PACKAGE= tests
-FILESGROUPS= TESTS
-TESTSPACKAGE= ${PACKAGE}
-
.PATH: ${.CURDIR}/../../../tests/framework
KMOD= kern_testfrwk
diff --git a/sys/net/altq/altq_cbq.c b/sys/net/altq/altq_cbq.c
index a51a21f..56c14d3 100644
--- a/sys/net/altq/altq_cbq.c
+++ b/sys/net/altq/altq_cbq.c
@@ -701,7 +701,7 @@ cbq_modify_class(acp)
* struct rm_class *parent, struct rm_class *borrow)
*
* This function create a new traffic class in the CBQ class hierarchy of
- * given paramters. The class that created is either the root, default,
+ * given parameters. The class that created is either the root, default,
* or a new dynamic class. If CBQ is not initilaized, the the root class
* will be created.
*/
diff --git a/sys/net/altq/altq_red.c b/sys/net/altq/altq_red.c
index 1347851..9d75460 100644
--- a/sys/net/altq/altq_red.c
+++ b/sys/net/altq/altq_red.c
@@ -158,7 +158,7 @@
#define TH_MIN 5 /* min threshold */
#define TH_MAX 15 /* max threshold */
-#define RED_LIMIT 60 /* default max queue lenght */
+#define RED_LIMIT 60 /* default max queue length */
#define RED_STATS /* collect statistics */
/*
@@ -171,7 +171,7 @@
#ifdef ALTQ3_COMPAT
#ifdef ALTQ_FLOWVALVE
/*
- * flow-valve is an extention to protect red from unresponsive flows
+ * flow-valve is an extension to protect red from unresponsive flows
* and to promote end-to-end congestion control.
* flow-valve observes the average drop rates of the flows that have
* experienced packet drops in the recent past.
diff --git a/sys/net/altq/altq_rio.c b/sys/net/altq/altq_rio.c
index 0f19735e..7687701 100644
--- a/sys/net/altq/altq_rio.c
+++ b/sys/net/altq/altq_rio.c
@@ -146,7 +146,7 @@
#define TH_MIN 5 /* min threshold */
#define TH_MAX 15 /* max threshold */
-#define RIO_LIMIT 60 /* default max queue lenght */
+#define RIO_LIMIT 60 /* default max queue length */
#define RIO_STATS /* collect statistics */
#define TV_DELTA(a, b, delta) { \
diff --git a/sys/net/altq/altq_rmclass.h b/sys/net/altq/altq_rmclass.h
index d511714..6130c4f 100644
--- a/sys/net/altq/altq_rmclass.h
+++ b/sys/net/altq/altq_rmclass.h
@@ -188,7 +188,7 @@ struct rm_class {
*/
struct rm_ifdat {
int queued_; /* # pkts queued downstream */
- int efficient_; /* Link Efficency bit */
+ int efficient_; /* Link Efficiency bit */
int wrr_; /* Enable Weighted Round-Robin */
u_long ns_per_byte_; /* Link byte speed. */
int maxqueued_; /* Max packets to queue */
diff --git a/sys/net/bpf.h b/sys/net/bpf.h
index 0ffc15ac..058f3c0 100644
--- a/sys/net/bpf.h
+++ b/sys/net/bpf.h
@@ -579,7 +579,7 @@ struct bpf_zbuf_header {
* input packets such as port scans, packets from old lost connections,
* etc. to force the connection to stay up).
*
- * The first byte of the PPP header (0xff03) is modified to accomodate
+ * The first byte of the PPP header (0xff03) is modified to accommodate
* the direction - 0x00 = IN, 0x01 = OUT.
*/
#define DLT_PPP_PPPD 166
diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c
index d6e118c..c308542 100644
--- a/sys/net/bridgestp.c
+++ b/sys/net/bridgestp.c
@@ -789,7 +789,7 @@ bstp_assign_roles(struct bstp_state *bs)
bs->bs_root_htime = bs->bs_bridge_htime;
bs->bs_root_port = NULL;
- /* check if any recieved info supersedes us */
+ /* check if any received info supersedes us */
LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
if (bp->bp_infois != BSTP_INFO_RECEIVED)
continue;
diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c
index f45a687..895b233 100644
--- a/sys/net/flowtable.c
+++ b/sys/net/flowtable.c
@@ -741,10 +741,6 @@ flowtable_lookup_common(struct flowtable *ft, uint32_t *key, int keylen,
return (flowtable_insert(ft, hash, key, keylen, fibnum));
}
-/*
- * used by the bit_alloc macro
- */
-#define calloc(count, size) malloc((count)*(size), M_FTABLE, M_WAITOK | M_ZERO)
static void
flowtable_alloc(struct flowtable *ft)
{
@@ -759,11 +755,10 @@ flowtable_alloc(struct flowtable *ft)
bitstr_t **b;
b = zpcpu_get_cpu(ft->ft_masks, i);
- *b = bit_alloc(ft->ft_size);
+ *b = bit_alloc(ft->ft_size, M_FTABLE, M_WAITOK);
}
- ft->ft_tmpmask = bit_alloc(ft->ft_size);
+ ft->ft_tmpmask = bit_alloc(ft->ft_size, M_FTABLE, M_WAITOK);
}
-#undef calloc
static void
flowtable_free_stale(struct flowtable *ft, struct rtentry *rt, int maxidle)
diff --git a/sys/net/if.c b/sys/net/if.c
index 1a11093..7a0bcec 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -558,7 +558,7 @@ ifq_delete(struct ifaltq *ifq)
}
/*
- * Perform generic interface initalization tasks and attach the interface
+ * Perform generic interface initialization tasks and attach the interface
* to the list of "active" interfaces. If vmove flag is set on entry
* to if_attach_internal(), perform only a limited subset of initialization
* tasks, given that we are moving from one vnet to another an ifnet which
diff --git a/sys/net/if_arcsubr.c b/sys/net/if_arcsubr.c
index 271e652..ff38b68 100644
--- a/sys/net/if_arcsubr.c
+++ b/sys/net/if_arcsubr.c
@@ -345,7 +345,7 @@ arc_frag_next(struct ifnet *ifp)
/*
* Defragmenter. Returns mbuf if last packet found, else
- * NULL. frees imcoming mbuf as necessary.
+ * NULL. frees incoming mbuf as necessary.
*/
static __inline struct mbuf *
diff --git a/sys/net/if_atm.h b/sys/net/if_atm.h
index c669c3d..a0900ee 100644
--- a/sys/net/if_atm.h
+++ b/sys/net/if_atm.h
@@ -96,7 +96,7 @@ struct ifatm_mib {
/*
* Traffic parameters for ATM connections. This contains all parameters
- * to accomodate UBR, UBR+MCR, CBR, VBR and ABR connections.
+ * to accommodate UBR, UBR+MCR, CBR, VBR and ABR connections.
*
* Keep in sync with ng_atm.h
*/
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 00621c7..d1df805 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -71,7 +71,7 @@
* - Currently only supports Ethernet-like interfaces (Ethernet,
* 802.11, VLANs on Ethernet, etc.) Figure out a nice way
* to bridge other types of interfaces (FDDI-FDDI, and maybe
- * consider heterogenous bridges).
+ * consider heterogeneous bridges).
*/
#include <sys/cdefs.h>
diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c
index dc71bfc..41516b6 100644
--- a/sys/net/if_clone.c
+++ b/sys/net/if_clone.c
@@ -484,7 +484,7 @@ if_clone_list(struct if_clonereq *ifcr)
* below, but that's not a major problem. Not caping our
* allocation to the number of cloners actually in the system
* could be because that would let arbitrary users cause us to
- * allocate abritrary amounts of kernel memory.
+ * allocate arbitrary amounts of kernel memory.
*/
buf_count = (V_if_cloners_count < ifcr->ifcr_count) ?
V_if_cloners_count : ifcr->ifcr_count;
diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c
index 6c14037..943776c 100644
--- a/sys/net/if_epair.c
+++ b/sys/net/if_epair.c
@@ -514,7 +514,7 @@ epair_transmit_locked(struct ifnet *ifp, struct mbuf *m)
DPRINTF("packet %s -> %s\n", ifp->if_xname, oifp->if_xname);
#ifdef ALTQ
- /* Support ALTQ via the clasic if_start() path. */
+ /* Support ALTQ via the classic if_start() path. */
IF_LOCK(&ifp->if_snd);
if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
ALTQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index a73302e..e4b5ed9 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -428,9 +428,6 @@ ether_output_frame(struct ifnet *ifp, struct mbuf *m)
return ((ifp->if_transmit)(ifp, m));
}
-#if defined(INET) || defined(INET6)
-#endif
-
/*
* Process a received Ethernet packet; the packet is in the
* mbuf chain m with the ethernet header at the front.
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index 0477122..8b81abf 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -2031,7 +2031,7 @@ lagg_fail_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m)
if (!LAGG_PORTACTIVE(sc->sc_primary)) {
tmp_tp = lagg_link_active(sc, sc->sc_primary);
/*
- * If tmp_tp is null, we've recieved a packet when all
+ * If tmp_tp is null, we've received a packet when all
* our links are down. Weird, but process it anyways.
*/
if ((tmp_tp == NULL || tmp_tp == lp)) {
diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
index beef6b4..7183cff 100644
--- a/sys/net/if_llatbl.c
+++ b/sys/net/if_llatbl.c
@@ -409,7 +409,7 @@ lltable_update_ifaddr(struct lltable *llt)
/*
*
- * Performes generic cleanup routines and frees lle.
+ * Performs generic cleanup routines and frees lle.
*
* Called for non-linked entries, with callouts and
* other AF-specific cleanups performed.
diff --git a/sys/net/if_sppp.h b/sys/net/if_sppp.h
index 97f94b3..23a08e7 100644
--- a/sys/net/if_sppp.h
+++ b/sys/net/if_sppp.h
@@ -78,7 +78,7 @@ struct sauth {
/*
* Don't change the order of this. Ordering the phases this way allows
- * for a comparision of ``pp_phase >= PHASE_AUTHENTICATE'' in order to
+ * for a comparison of ``pp_phase >= PHASE_AUTHENTICATE'' in order to
* know whether LCP is up.
*/
enum ppp_phase {
diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c
index 092106e..c448061 100644
--- a/sys/net/if_spppsubr.c
+++ b/sys/net/if_spppsubr.c
@@ -2962,7 +2962,7 @@ sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
* since our algorithm always uses the
* original option to NAK it with new values,
* things would become more complicated. In
- * pratice, the only commonly implemented IP
+ * practice, the only commonly implemented IP
* compression option is VJ anyway, so the
* difference is negligible.
*/
@@ -4295,7 +4295,7 @@ sppp_chap_tlu(struct sppp *sp)
if ((sp->hisauth.flags & AUTHFLAG_NORECHALLENGE) == 0)
log(-1, "next re-challenge in %d seconds\n", i);
else
- log(-1, "re-challenging supressed\n");
+ log(-1, "re-challenging suppressed\n");
}
SPPP_LOCK(sp);
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 45790b6..0838287 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -728,7 +728,7 @@ vlan_tag_recalculate(struct ifvlan *ifv)
* VLAN support can be loaded as a module. The only place in the
* system that's intimately aware of this is ether_input. We hook
* into this code through vlan_input_p which is defined there and
- * set here. Noone else in the system should be aware of this so
+ * set here. No one else in the system should be aware of this so
* we use an explicit reference here.
*/
extern void (*vlan_input_p)(struct ifnet *, struct mbuf *);
@@ -901,7 +901,7 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
* o specify no parameters and get an unattached device that
* must be configured separately.
* The first technique is preferred; the latter two are
- * supported for backwards compatibilty.
+ * supported for backwards compatibility.
*
* XXXRW: Note historic use of the word "tag" here. New ioctls may be
* called for.
diff --git a/sys/net/rss_config.c b/sys/net/rss_config.c
index e7e8eb4..9597614 100644
--- a/sys/net/rss_config.c
+++ b/sys/net/rss_config.c
@@ -168,7 +168,7 @@ static uint8_t rss_key[RSS_KEYSIZE] = {
/*
* RSS hash->CPU table, which maps hashed packet headers to particular CPUs.
- * Drivers may supplement this table with a seperate CPU<->queue table when
+ * Drivers may supplement this table with a separate CPU<->queue table when
* programming devices.
*/
struct rss_table_entry {
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 4a22913..c074603 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1199,7 +1199,7 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int *
/*
* This routine is called to generate a message from the routing
- * socket indicating that a redirect has occured, a routing lookup
+ * socket indicating that a redirect has occurred, a routing lookup
* has failed, or that a protocol has detected timeouts to a particular
* destination.
*/
diff --git a/sys/net/sff8472.h b/sys/net/sff8472.h
index fdeb2e9..5c50ea4 100644
--- a/sys/net/sff8472.h
+++ b/sys/net/sff8472.h
@@ -431,7 +431,7 @@ static const char *sff_8024_id[SFF_8024_ID_LAST + 1] = {"Unknown",
"SMM8",
"CDFP3"};
-/* Keep compability with old definitions */
+/* Keep compatibility with old definitions */
#define SFF_8472_ID_UNKNOWN SFF_8024_ID_UNKNOWN
#define SFF_8472_ID_GBIC SFF_8024_ID_GBIC
#define SFF_8472_ID_SFF SFF_8024_ID_SFF
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index 86f4d81..d2b254a 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -1833,7 +1833,7 @@ ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode m
{ 6 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM3 },
{ 9 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM4 },
{ 54 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM27 },
- /* NB: OFDM72 doesn't realy exist so we don't handle it */
+ /* NB: OFDM72 doesn't really exist so we don't handle it */
};
static const struct ratemedia htrates[] = {
{ 0, IFM_IEEE80211_MCS },
diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
index deb329f..b7f4bbd 100644
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -775,7 +775,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
*
* Since there's no (current) way to inform
* the driver that a channel width change has
- * occured for a single node, just stub this
+ * occurred for a single node, just stub this
* out.
*/
#if 0
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 690e123..373b053 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -851,6 +851,7 @@ ieee80211_load_module(const char *modname)
}
static eventhandler_tag wlan_bpfevent;
+static eventhandler_tag wlan_ifllevent;
static void
bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
@@ -879,6 +880,21 @@ bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
}
/*
+ * Change MAC address on the vap (if was not started).
+ */
+static void
+wlan_iflladdr(void *arg __unused, struct ifnet *ifp)
+{
+ /* NB: identify vap's by if_init */
+ if (ifp->if_init == ieee80211_init &&
+ (ifp->if_flags & IFF_UP) == 0) {
+ struct ieee80211vap *vap = ifp->if_softc;
+
+ IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
+ }
+}
+
+/*
* Module glue.
*
* NB: the module name is "wlan" for compatibility with NetBSD.
@@ -892,12 +908,15 @@ wlan_modevent(module_t mod, int type, void *unused)
printf("wlan: <802.11 Link Layer>\n");
wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track,
bpf_track, 0, EVENTHANDLER_PRI_ANY);
+ wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
+ wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
wlan_cloner = if_clone_simple(wlanname, wlan_clone_create,
wlan_clone_destroy, 0);
return 0;
case MOD_UNLOAD:
if_clone_detach(wlan_cloner);
EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
+ EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
return 0;
}
return EINVAL;
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index 3b2670c..1f32c7e 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -1452,7 +1452,7 @@ ieee80211_parse_rsn(struct ieee80211vap *vap, const uint8_t *frm,
}
/*
- * WPA/802.11i assocation request processing.
+ * WPA/802.11i association request processing.
*/
static int
wpa_assocreq(struct ieee80211_node *ni, struct ieee80211_rsnparms *rsnparms,
diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c
index d33b5c4..0320c2d 100644
--- a/sys/net80211/ieee80211_ht.c
+++ b/sys/net80211/ieee80211_ht.c
@@ -2298,7 +2298,7 @@ bar_timeout(void *arg)
* to make sure we notify the driver that a BAR
* TX did occur and fail. This gives the driver
* a chance to undo any queue pause that may
- * have occured.
+ * have occurred.
*/
ic->ic_bar_response(ni, tap, 1);
ieee80211_ampdu_stop(ni, tap, IEEE80211_REASON_TIMEOUT);
@@ -2742,6 +2742,14 @@ ieee80211_add_htcap_body(uint8_t *frm, struct ieee80211_node *ni)
rxmax = MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
density = MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_11N,
+ "%s: advertised rxmax=%d, density=%d, vap rxmax=%d, density=%d\n",
+ __func__,
+ rxmax,
+ density,
+ vap->iv_ampdu_rxmax,
+ vap->iv_ampdu_density);
+
/* Cap at VAP rxmax */
if (rxmax > vap->iv_ampdu_rxmax)
rxmax = vap->iv_ampdu_rxmax;
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 823906b..3d93278 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -3428,10 +3428,10 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCSIFADDR:
/*
- * XXX Handle this directly so we can supress if_init calls.
+ * XXX Handle this directly so we can suppress if_init calls.
* XXX This should be done in ether_ioctl but for the moment
* XXX there are too many other parts of the system that
- * XXX set IFF_UP and so supress if_init being called when
+ * XXX set IFF_UP and so suppress if_init being called when
* XXX it should be.
*/
ifa = (struct ifaddr *) data;
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 58ec8c1..17adda0 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -1155,7 +1155,7 @@ mesh_forward(struct ieee80211vap *vap, struct mbuf *m,
IEEE80211_TX_UNLOCK_ASSERT(ic);
/*
- * mesh ttl of 1 means we are the last one receving it,
+ * mesh ttl of 1 means we are the last one receiving it,
* according to amendment we decrement and then check if
* 0, if so we dont forward.
*/
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index 0986145..c1135af 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -2217,7 +2217,7 @@ ieee80211_node_timeout(void *arg)
* Defer timeout processing if a channel switch is pending.
* We typically need to be mute so not doing things that
* might generate frames is good to handle in one place.
- * Supressing the station timeout processing may extend the
+ * Suppressing the station timeout processing may extend the
* lifetime of inactive stations (by not decrementing their
* idle counters) but this should be ok unless the CSA is
* active for an unusually long time.
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 857b042..68e46eb 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -2894,7 +2894,7 @@ ieee80211_tx_mgt_cb(struct ieee80211_node *ni, void *arg, int status)
/*
* Frame transmit completed; arrange timer callback. If
- * transmit was successfuly we wait for response. Otherwise
+ * transmit was successfully we wait for response. Otherwise
* we arrange an immediate callback instead of doing the
* callback directly since we don't know what state the driver
* is in (e.g. what locks it is holding). This work should
@@ -3231,10 +3231,10 @@ ieee80211_beacon_update(struct ieee80211_node *ni, struct mbuf *m, int mcast)
struct ieee80211_wme_state *wme = &ic->ic_wme;
/*
- * Check for agressive mode change. When there is
+ * Check for aggressive mode change. When there is
* significant high priority traffic in the BSS
* throttle back BE traffic by using conservative
- * parameters. Otherwise BE uses agressive params
+ * parameters. Otherwise BE uses aggressive params
* to optimize performance of legacy/non-QoS traffic.
*/
if (wme->wme_flags & WME_F_AGGRMODE) {
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 6704fea..c85aebf 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -1082,7 +1082,7 @@ ieee80211_wme_initparams_locked(struct ieee80211vap *vap)
/* NB: check ic_bss to avoid NULL deref on initial attach */
if (vap->iv_bss != NULL) {
/*
- * Calculate agressive mode switching threshold based
+ * Calculate aggressive mode switching threshold based
* on beacon interval. This doesn't need locking since
* we're only called before entering the RUN state at
* which point we start sending beacon frames.
@@ -1164,11 +1164,11 @@ ieee80211_wme_updateparams_locked(struct ieee80211vap *vap)
mode = IEEE80211_MODE_AUTO;
/*
- * This implements agressive mode as found in certain
+ * This implements aggressive mode as found in certain
* vendors' AP's. When there is significant high
* priority (VI/VO) traffic in the BSS throttle back BE
* traffic by using conservative parameters. Otherwise
- * BE uses agressive params to optimize performance of
+ * BE uses aggressive params to optimize performance of
* legacy/non-QoS traffic.
*/
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 74f8ebcd..f2b231c 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -276,10 +276,10 @@ struct chanAccParams {
struct ieee80211_wme_state {
u_int wme_flags;
-#define WME_F_AGGRMODE 0x00000001 /* STATUS: WME agressive mode */
+#define WME_F_AGGRMODE 0x00000001 /* STATUS: WME aggressive mode */
u_int wme_hipri_traffic; /* VI/VO frames in beacon interval */
- u_int wme_hipri_switch_thresh;/* agressive mode switch thresh */
- u_int wme_hipri_switch_hysteresis;/* agressive mode switch hysteresis */
+ u_int wme_hipri_switch_thresh;/* aggressive mode switch thresh */
+ u_int wme_hipri_switch_hysteresis;/* aggressive mode switch hysteresis */
struct wmeParams wme_params[4]; /* from assoc resp for each AC*/
struct chanAccParams wme_wmeChanParams; /* WME params applied to self */
diff --git a/sys/net80211/ieee80211_regdomain.c b/sys/net80211/ieee80211_regdomain.c
index 4db08fd..f565a65 100644
--- a/sys/net80211/ieee80211_regdomain.c
+++ b/sys/net80211/ieee80211_regdomain.c
@@ -266,7 +266,7 @@ ieee80211_alloc_countryie(struct ieee80211com *ic)
* Indoor/Outdoor portion of country string:
* 'I' indoor only
* 'O' outdoor only
- * ' ' all enviroments
+ * ' ' all environments
*/
ie->cc[2] = (rd->location == 'I' ? 'I' :
rd->location == 'O' ? 'O' : ' ');
diff --git a/sys/net80211/ieee80211_scan_sw.c b/sys/net80211/ieee80211_scan_sw.c
index 323bf93..9899200 100644
--- a/sys/net80211/ieee80211_scan_sw.c
+++ b/sys/net80211/ieee80211_scan_sw.c
@@ -771,7 +771,7 @@ scan_end(struct ieee80211_scan_state *ss, int scandone)
/* XXX scan state can change! Re-validate scan state! */
/*
- * Since a cancellation may have occured during one of the
+ * Since a cancellation may have occurred during one of the
* driver calls (whilst unlocked), update scandone.
*/
if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) {
@@ -818,7 +818,7 @@ scan_end(struct ieee80211_scan_state *ss, int scandone)
"[ticks %u, dwell min %lu scanend %lu]\n",
__func__,
ticks, ss->ss_mindwell, ss_priv->ss_scanend);
- ss->ss_next = 0; /* reset to begining */
+ ss->ss_next = 0; /* reset to beginning */
if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
vap->iv_stats.is_scan_active++;
else
@@ -840,7 +840,7 @@ scan_end(struct ieee80211_scan_state *ss, int scandone)
ticks, ss->ss_mindwell, ss_priv->ss_scanend);
/*
- * Since a cancellation may have occured during one of the
+ * Since a cancellation may have occurred during one of the
* driver calls (whilst unlocked), update scandone.
*/
if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) {
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 8c0f6fb..f94a15a 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -148,7 +148,8 @@ struct ieee80211com {
uint32_t ic_htcaps; /* HT capabilities */
uint32_t ic_htextcaps; /* HT extended capabilities */
uint32_t ic_cryptocaps; /* crypto capabilities */
- uint8_t ic_modecaps[2]; /* set of mode capabilities */
+ /* set of mode capabilities */
+ uint8_t ic_modecaps[IEEE80211_MODE_BYTES];
uint8_t ic_promisc; /* vap's needing promisc mode */
uint8_t ic_allmulti; /* vap's needing all multicast*/
uint8_t ic_nrunning; /* vap's marked running */
diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c
index 9fdb99e..a447345 100644
--- a/sys/netinet/cc/cc_cubic.c
+++ b/sys/netinet/cc/cc_cubic.c
@@ -143,7 +143,7 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type)
* the I-D. Using min_rtt in the tf_cwnd calculation
* causes w_tf to grow much faster than it should if the
* RTT is dominated by network buffering rather than
- * propogation delay.
+ * propagation delay.
*/
w_tf = tf_cwnd(ticks_since_cong,
cubic_data->mean_rtt_ticks, cubic_data->max_cwnd,
diff --git a/sys/netinet/cc/cc_dctcp.c b/sys/netinet/cc/cc_dctcp.c
index fd36d1c..ce75750 100644
--- a/sys/netinet/cc/cc_dctcp.c
+++ b/sys/netinet/cc/cc_dctcp.c
@@ -202,7 +202,7 @@ dctcp_cb_init(struct cc_var *ccv)
dctcp_data->bytes_ecn = 0;
dctcp_data->bytes_total = 0;
/*
- * When alpha is set to 0 in the beggining, DCTCP sender transfers as
+ * When alpha is set to 0 in the beginning, DCTCP sender transfers as
* much data as possible until the value converges which may expand the
* queueing delay at the switch. When alpha is set to 1, queueing delay
* is kept small.
diff --git a/sys/netinet/cc/cc_htcp.c b/sys/netinet/cc/cc_htcp.c
index 97012f5..ada0a43 100644
--- a/sys/netinet/cc/cc_htcp.c
+++ b/sys/netinet/cc/cc_htcp.c
@@ -346,8 +346,10 @@ htcp_mod_init(void)
static void
htcp_post_recovery(struct cc_var *ccv)
{
+ int pipe;
struct htcp *htcp_data;
+ pipe = 0;
htcp_data = ccv->cc_data;
if (IN_FASTRECOVERY(CCV(ccv, t_flags))) {
@@ -358,10 +360,13 @@ htcp_post_recovery(struct cc_var *ccv)
*
* XXXLAS: Find a way to do this without needing curack
*/
- if (SEQ_GT(ccv->curack + CCV(ccv, snd_ssthresh),
- CCV(ccv, snd_max)))
- CCV(ccv, snd_cwnd) = CCV(ccv, snd_max) - ccv->curack +
- CCV(ccv, t_maxseg);
+ if (V_tcp_do_rfc6675_pipe)
+ pipe = tcp_compute_pipe(ccv->ccvc.tcp);
+ else
+ pipe = CCV(ccv, snd_max) - ccv->curack;
+
+ if (pipe < CCV(ccv, snd_ssthresh))
+ CCV(ccv, snd_cwnd) = pipe + CCV(ccv, t_maxseg);
else
CCV(ccv, snd_cwnd) = max(1, ((htcp_data->beta *
htcp_data->prev_cwnd / CCV(ccv, t_maxseg))
@@ -440,7 +445,7 @@ htcp_recalc_beta(struct cc_var *ccv)
/*
* TCPTV_SRTTBASE is the initialised value of each connection's SRTT, so
* we only calc beta if the connection's SRTT has been changed from its
- * inital value. beta is bounded to ensure it is always between
+ * initial value. beta is bounded to ensure it is always between
* HTCP_MINBETA and HTCP_MAXBETA.
*/
if (V_htcp_adaptive_backoff && htcp_data->minrtt != TCPTV_SRTTBASE &&
diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c
index dcadec5..90c00c62 100644
--- a/sys/netinet/igmp.c
+++ b/sys/netinet/igmp.c
@@ -1103,9 +1103,9 @@ out_locked:
}
/*
- * Process a recieved IGMPv3 group-specific or group-and-source-specific
+ * Process a received IGMPv3 group-specific or group-and-source-specific
* query.
- * Return <0 if any error occured. Currently this is ignored.
+ * Return <0 if any error occurred. Currently this is ignored.
*/
static int
igmp_input_v3_group_query(struct in_multi *inm, struct igmp_ifsoftc *igi,
diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
index 4037dbf..07b5bba 100644
--- a/sys/netinet/in_mcast.c
+++ b/sys/netinet/in_mcast.c
@@ -619,7 +619,7 @@ inm_clear_recorded(struct in_multi *inm)
*
* Return 0 if the source didn't exist or was already marked as recorded.
* Return 1 if the source was marked as recorded by this function.
- * Return <0 if any error occured (negated errno code).
+ * Return <0 if any error occurred (negated errno code).
*/
int
inm_record_source(struct in_multi *inm, const in_addr_t naddr)
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 9c77a51..17f7c3d 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -121,7 +121,7 @@ struct in_conninfo {
*/
#define INC_ISIPV6 0x01
-#define inc_isipv6 inc_flags /* temp compatability */
+#define inc_isipv6 inc_flags /* temp compatibility */
#define inc_fport inc_ie.ie_fport
#define inc_lport inc_ie.ie_lport
#define inc_faddr inc_ie.ie_faddr
diff --git a/sys/netinet/ip.h b/sys/netinet/ip.h
index 9269396..98bd1e9 100644
--- a/sys/netinet/ip.h
+++ b/sys/netinet/ip.h
@@ -147,7 +147,7 @@ struct ip {
#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
#define IPOPT_LSRR 131 /* loose source route */
#define IPOPT_ESO 133 /* extended security */
-#define IPOPT_CIPSO 134 /* commerical security */
+#define IPOPT_CIPSO 134 /* commercial security */
#define IPOPT_SATID 136 /* satnet id */
#define IPOPT_SSRR 137 /* strict source route */
#define IPOPT_RA 148 /* router alert */
diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c
index 22eb727..3fc7c74 100644
--- a/sys/netinet/ip_fastfwd.c
+++ b/sys/netinet/ip_fastfwd.c
@@ -205,7 +205,7 @@ ip_tryforward(struct mbuf *m)
*
* XXX: Probably some of these checks could be direct drop
* conditions. However it is not clear whether there are some
- * hacks or obscure behaviours which make it neccessary to
+ * hacks or obscure behaviours which make it necessary to
* let ip_input handle it. We play safe here and let ip_input
* deal with it until it is proven that we can directly drop it.
*/
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 7250527..e46abf8 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -861,9 +861,9 @@ typedef struct _ipfw_obj_tentry {
#define IPFW_CTF_ATOMIC 0x01 /* Perform atomic operation */
/* Operation results */
#define IPFW_TR_IGNORED 0 /* Entry was ignored (rollback) */
-#define IPFW_TR_ADDED 1 /* Entry was succesfully added */
-#define IPFW_TR_UPDATED 2 /* Entry was succesfully updated*/
-#define IPFW_TR_DELETED 3 /* Entry was succesfully deleted*/
+#define IPFW_TR_ADDED 1 /* Entry was successfully added */
+#define IPFW_TR_UPDATED 2 /* Entry was successfully updated*/
+#define IPFW_TR_DELETED 3 /* Entry was successfully deleted*/
#define IPFW_TR_LIMIT 4 /* Entry was ignored (limit) */
#define IPFW_TR_NOTFOUND 5 /* Entry was not found */
#define IPFW_TR_EXISTS 6 /* Entry already exists */
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index fee980f..a87daf7 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -223,7 +223,7 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
/*
* Calculate length to quote from original packet and
* prevent the ICMP mbuf from overflowing.
- * Unfortunatly this is non-trivial since ip_forward()
+ * Unfortunately this is non-trivial since ip_forward()
* sends us truncated packets.
*/
nlen = m_length(n, NULL);
diff --git a/sys/netinet/ip_options.c b/sys/netinet/ip_options.c
index b050423..3e44ffb 100644
--- a/sys/netinet/ip_options.c
+++ b/sys/netinet/ip_options.c
@@ -706,7 +706,7 @@ bad:
* may change in future.
* Router alert options SHOULD be passed if running in IPSTEALTH mode and
* we are not the endpoint.
- * Length checks on individual options should already have been peformed
+ * Length checks on individual options should already have been performed
* by ip_dooptions() therefore they are folded under INVARIANTS here.
*
* Return zero if not present or options are invalid, non-zero if present.
diff --git a/sys/netinet/libalias/alias_irc.c b/sys/netinet/libalias/alias_irc.c
index 552fab8..cb2d67d 100644
--- a/sys/netinet/libalias/alias_irc.c
+++ b/sys/netinet/libalias/alias_irc.c
@@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
Version 2.1: May, 1997 (cjm)
Very minor changes to conform with
local/global/function naming conventions
- withing the packet alising module.
+ within the packet alising module.
*/
/* Includes */
@@ -482,7 +482,7 @@ lPACKET_DONE:
which will generate a type-error on all but 32-bit machines.
[Note 2] This routine really ought to be replaced with one that
- creates a transparent proxy on the aliasing host, to allow arbitary
+ creates a transparent proxy on the aliasing host, to allow arbitrary
changes in the TCP stream. This should not be too difficult given
this base; I (ee) will try to do this some time later.
*/
diff --git a/sys/netinet/libalias/alias_local.h b/sys/netinet/libalias/alias_local.h
index c291a37..506193c 100644
--- a/sys/netinet/libalias/alias_local.h
+++ b/sys/netinet/libalias/alias_local.h
@@ -357,7 +357,7 @@ void PunchFWHole(struct alias_link *_lnk);
/* Housekeeping function */
void HouseKeeping(struct libalias *);
-/* Tcp specfic routines */
+/* Tcp specific routines */
/* lint -save -library Suppress flexelint warnings */
/* Transparent proxy routines */
diff --git a/sys/netinet/libalias/alias_smedia.c b/sys/netinet/libalias/alias_smedia.c
index 0e44207..6ab490b 100644
--- a/sys/netinet/libalias/alias_smedia.c
+++ b/sys/netinet/libalias/alias_smedia.c
@@ -518,7 +518,7 @@ AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *lnk,
/*
* When aliasing a server, check for the 200 reply
- * Accomodate varying number of blanks between 200 & OK
+ * Accommodate varying number of blanks between 200 & OK
*/
if (dlen >= (int)strlen(str200)) {
diff --git a/sys/netinet/libalias/libalias.3 b/sys/netinet/libalias/libalias.3
index 543420b..e496168 100644
--- a/sys/netinet/libalias/libalias.3
+++ b/sys/netinet/libalias/libalias.3
@@ -1067,7 +1067,7 @@ In case the application provides a
.Dv SIGHUP
signal handler, add a call to
.Fn LibAliasRefreshModules
-inside the handler, and everytime you want to refresh the loaded modules,
+inside the handler, and every time you want to refresh the loaded modules,
send it the
.Dv SIGHUP
signal:
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index 2d29fcb..ae6ec49 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -1076,8 +1076,8 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
return (1);
}
/*
- * cleared threshold management now lets backoff the address & select
- * an alternate
+ * Cleared threshold management, now lets backoff the address and
+ * select an alternate
*/
stcb->asoc.dropped_special_cnt = 0;
sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0, 0);
@@ -1122,8 +1122,8 @@ sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
return (1);
}
/*
- * cleared threshold management now lets backoff the address & select
- * an alternate
+ * Cleared threshold management, now lets backoff the address and
+ * select an alternate
*/
sctp_backoff_on_timeout(stcb, strrst->whoTo, 1, 0, 0);
alt = sctp_find_alternate_net(stcb, strrst->whoTo, 0);
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 324b0da..cd400f5 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -365,7 +365,7 @@ cc_conn_init(struct tcpcb *tp)
/*
* There's some sort of gateway or interface
* buffer limit on the path. Use this to set
- * the slow start threshhold, but set the
+ * the slow start threshold, but set the
* threshold to no less than 2*mss.
*/
tp->snd_ssthresh = max(2 * maxseg, metrics.rmx_ssthresh);
@@ -2533,7 +2533,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
* change and FIN isn't set),
* the ack is the biggest we've
* seen and we've seen exactly our rexmt
- * threshhold of them, assume a packet
+ * threshold of them, assume a packet
* has been dropped and retransmit it.
* Kludge snd_nxt & the congestion
* window so we send only this one
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index 2043fc9..e2490ac 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -215,7 +215,7 @@ tcp_output(struct tcpcb *tp)
*/
if ((tp->t_flags & TF_FASTOPEN) &&
(tp->t_state == TCPS_SYN_RECEIVED) &&
- SEQ_GT(tp->snd_max, tp->snd_una) && /* inital SYN|ACK sent */
+ SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN|ACK sent */
(tp->snd_nxt != tp->snd_una)) /* not a retransmit */
return (0);
#endif
@@ -495,9 +495,9 @@ after_sack_rexmit:
* and does at most one step per received ACK. This fast
* scaling has the drawback of growing the send buffer beyond
* what is strictly necessary to make full use of a given
- * delay*bandwith product. However testing has shown this not
+ * delay*bandwidth product. However testing has shown this not
* to be much of an problem. At worst we are trading wasting
- * of available bandwith (the non-use of it) for wasting some
+ * of available bandwidth (the non-use of it) for wasting some
* socket buffer memory.
*
* TODO: Shrink send buffer during idle periods together
@@ -1619,7 +1619,7 @@ tcp_setpersist(struct tcpcb *tp)
if (tcp_timer_active(tp, TT_REXMT))
panic("tcp_setpersist: retransmit pending");
/*
- * Start/restart persistance timer.
+ * Start/restart persistence timer.
*/
TCPT_RANGESET(tt, t * tcp_backoff[tp->t_rxtshift],
tcp_persmin, tcp_persmax);
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c
index 1e31871..a153f6c 100644
--- a/sys/netinet/tcp_sack.c
+++ b/sys/netinet/tcp_sack.c
@@ -401,8 +401,8 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack)
/*
* Sort the SACK blocks so we can update the scoreboard with just one
- * pass. The overhead of sorting upto 4+1 elements is less than
- * making upto 4+1 passes over the scoreboard.
+ * pass. The overhead of sorting up to 4+1 elements is less than
+ * making up to 4+1 passes over the scoreboard.
*/
for (i = 0; i < num_sack_blks; i++) {
for (j = i + 1; j < num_sack_blks; j++) {
diff --git a/sys/netinet/tcp_stacks/fastpath.c b/sys/netinet/tcp_stacks/fastpath.c
index 5529fd8..83547eb 100644
--- a/sys/netinet/tcp_stacks/fastpath.c
+++ b/sys/netinet/tcp_stacks/fastpath.c
@@ -185,7 +185,7 @@ tcp_do_fastack(struct mbuf *m, struct tcphdr *th, struct socket *so,
short ostate = 0;
#endif
/*
- * The following if statment will be true if
+ * The following if statement will be true if
* we are doing the win_up_in_fp <and>
* - We have more new data (SEQ_LT(tp->snd_wl1, th->th_seq)) <or>
* - No more new data, but we have an ack for new data
@@ -1061,7 +1061,7 @@ tcp_do_slowpath(struct mbuf *m, struct tcphdr *th, struct socket *so,
* change and FIN isn't set),
* the ack is the biggest we've
* seen and we've seen exactly our rexmt
- * threshhold of them, assume a packet
+ * threshold of them, assume a packet
* has been dropped and retransmit it.
* Kludge snd_nxt & the congestion
* window so we send only this one
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 178ea77..64d7124 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1376,7 +1376,7 @@ tcp_discardcb(struct tcpcb *tp)
* Update the ssthresh always when the conditions below
* are satisfied. This gives us better new start value
* for the congestion avoidance for new connections.
- * ssthresh is only set if packet loss occured on a session.
+ * ssthresh is only set if packet loss occurred on a session.
*
* XXXRW: 'so' may be NULL here, and/or socket buffer may be
* being torn down. Ideally this code would not use 'so'.
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 2c568da..adb4cab 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -1419,7 +1419,7 @@ skip_alloc:
* With the default maxsockbuf of 256K, a scale factor
* of 3 will be chosen by this algorithm. Those who
* choose a larger maxsockbuf should watch out
- * for the compatiblity problems mentioned above.
+ * for the compatibility problems mentioned above.
*
* RFC1323: The Window field in a SYN (i.e., a <SYN>
* or <SYN,ACK>) segment itself is never scaled.
@@ -1746,7 +1746,7 @@ syncache_respond(struct syncache *sc, struct syncache_head *sch, int locked,
* with the latter taking over when the former is exhausted. When matching
* syncache entry is found the syncookie is ignored.
*
- * The only reliable information persisting the 3WHS is our inital sequence
+ * The only reliable information persisting the 3WHS is our initial sequence
* number ISS of 32 bits. Syncookies embed a cryptographically sufficient
* strong hash (MAC) value and a few bits of TCP SYN options in the ISS
* of our SYN|ACK. The MAC can be recomputed when the ACK to our SYN|ACK
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 5d6865c..5925f42 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -522,7 +522,7 @@ tcp_timer_persist(void *xtp)
KASSERT((tp->t_timers->tt_flags & TT_PERSIST) != 0,
("%s: tp %p persist callout should be running", __func__, tp));
/*
- * Persistance timer into zero window.
+ * Persistence timer into zero window.
* Force a byte to be output, if possible.
*/
TCPSTAT_INC(tcps_persisttimeo);
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index a2f6635..b0aa5fe 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -135,7 +135,7 @@ frag6_init(void)
* fragment's Fragment header.
* -> should grab it from the first fragment only
*
- * The following note also contradicts with fragment rule - noone is going to
+ * The following note also contradicts with fragment rule - no one is going to
* send different fragment with different next header field.
*
* additional note (p22):
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 0dfaf04..902438e 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -669,14 +669,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
(*carp_detach_p)(&ia->ia_ifa);
goto out;
}
- if (pr == NULL) {
- if (carp_attached)
- (*carp_detach_p)(&ia->ia_ifa);
- log(LOG_ERR, "nd6_prelist_add succeeded but "
- "no prefix\n");
- error = EINVAL;
- goto out;
- }
}
/* relate the address to the prefix */
@@ -1955,7 +1947,7 @@ in6if_do_dad(struct ifnet *ifp)
/*
* Our DAD routine requires the interface up and running.
* However, some interfaces can be up before the RUNNING
- * status. Additionaly, users may try to assign addresses
+ * status. Additionally, users may try to assign addresses
* before the interface becomes up (or running).
* This function returns EAGAIN in that case.
* The caller should mark "tentative" on the address instead of
diff --git a/sys/netinet6/in6_mcast.c b/sys/netinet6/in6_mcast.c
index 9d96cf5..4effb57 100644
--- a/sys/netinet6/in6_mcast.c
+++ b/sys/netinet6/in6_mcast.c
@@ -574,7 +574,7 @@ in6m_clear_recorded(struct in6_multi *inm)
*
* Return 0 if the source didn't exist or was already marked as recorded.
* Return 1 if the source was marked as recorded by this function.
- * Return <0 if any error occured (negated errno code).
+ * Return <0 if any error occurred (negated errno code).
*/
int
in6m_record_source(struct in6_multi *inm, const struct in6_addr *addr)
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index e8810d6..3b3058b 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -282,7 +282,7 @@ ip6_forward(struct mbuf *m, int srcrt)
* ipsec6_proces_packet will send the packet using ip6_output
*/
error = ipsec6_process_packet(m, sp->req);
- /* Release SP if an error occured */
+ /* Release SP if an error occurred */
if (error != 0)
KEY_FREESP(&sp);
if (error == EJUSTRETURN) {
diff --git a/sys/netinet6/ip6_id.c b/sys/netinet6/ip6_id.c
index 3f40fa5..9a8086f 100644
--- a/sys/netinet6/ip6_id.c
+++ b/sys/netinet6/ip6_id.c
@@ -108,7 +108,7 @@ __FBSDID("$FreeBSD$");
struct randomtab {
const int ru_bits; /* resulting bits */
- const long ru_out; /* Time after wich will be reseeded */
+ const long ru_out; /* Time after which will be reseeded */
const u_int32_t ru_max; /* Uniq cycle, avoid blackjack prediction */
const u_int32_t ru_gen; /* Starting generator */
const u_int32_t ru_n; /* ru_n: prime, ru_n - 1: product of pfacts[] */
@@ -128,7 +128,7 @@ struct randomtab {
static struct randomtab randomtab_32 = {
32, /* resulting bits */
- 180, /* Time after wich will be reseeded */
+ 180, /* Time after which will be reseeded */
1000000000, /* Uniq cycle, avoid blackjack prediction */
2, /* Starting generator */
2147483629, /* RU_N-1 = 2^2*3^2*59652323 */
@@ -139,7 +139,7 @@ static struct randomtab randomtab_32 = {
static struct randomtab randomtab_20 = {
20, /* resulting bits */
- 180, /* Time after wich will be reseeded */
+ 180, /* Time after which will be reseeded */
200000, /* Uniq cycle, avoid blackjack prediction */
2, /* Starting generator */
524269, /* RU_N-1 = 2^2*3^2*14563 */
diff --git a/sys/netinet6/ip6protosw.h b/sys/netinet6/ip6protosw.h
index e8d4bad..9e80a69 100644
--- a/sys/netinet6/ip6protosw.h
+++ b/sys/netinet6/ip6protosw.h
@@ -92,7 +92,7 @@ struct pr_usrreqs;
*
* ip6c_finaldst usually points to ip6c_ip6->ip6_dst. if the original
* (internal) packet carries a routing header, it may point the final
- * dstination address in the routing header.
+ * destination address in the routing header.
*
* ip6c_src: ip6c_ip6->ip6_src + scope info + flowlabel in ip6c_ip6
* (beware of flowlabel, if you try to compare it against others)
diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
index 3c4cc99..a2f2d7e 100644
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -971,9 +971,9 @@ out_locked:
}
/*
- * Process a recieved MLDv2 group-specific or group-and-source-specific
+ * Process a received MLDv2 group-specific or group-and-source-specific
* query.
- * Return <0 if any error occured. Currently this is ignored.
+ * Return <0 if any error occurred. Currently this is ignored.
*/
static int
mld_v2_process_group_query(struct in6_multi *inm, struct mld_ifsoftc *mli,
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 3921e32..2aaa10d 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -479,7 +479,7 @@ nd6_options(union nd_opts *ndopts)
default:
/*
* Unknown options must be silently ignored,
- * to accomodate future extension to the protocol.
+ * to accommodate future extension to the protocol.
*/
nd6log((LOG_DEBUG,
"nd6_options: unsupported option %d - "
@@ -1604,7 +1604,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
case SIOCSIFINFO_IN6:
/*
* used to change host variables from userland.
- * intented for a use on router to reflect RA configurations.
+ * intended for a use on router to reflect RA configurations.
*/
/* 0 means 'unspecified' */
if (ND.linkmtu != 0) {
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index aa7baad..988bf2b 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -482,7 +482,7 @@ nd6_rtmsg(int cmd, struct rtentry *rt)
}
/*
- * default router list proccessing sub routines
+ * default router list processing sub routines
*/
static void
@@ -993,11 +993,9 @@ nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr,
new->ndpr_flags = pr->ndpr_flags;
if ((error = in6_init_prefix_ltimes(new)) != 0) {
free(new, M_IP6NDP);
- return(error);
+ return (error);
}
new->ndpr_lastupdate = time_uptime;
- if (newp != NULL)
- *newp = new;
/* initialization */
LIST_INIT(&new->ndpr_advrtrs);
@@ -1021,10 +1019,11 @@ nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr,
}
}
- if (dr)
+ if (dr != NULL)
pfxrtr_add(new, dr);
-
- return 0;
+ if (newp != NULL)
+ *newp = new;
+ return (0);
}
void
@@ -1081,7 +1080,6 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
struct ifnet *ifp = new->ndpr_ifp;
struct nd_prefix *pr;
int error = 0;
- int newprefix = 0;
int auth;
struct in6_addrlifetime lt6_tmp;
char ip6buf[INET6_ADDRSTRLEN];
@@ -1139,23 +1137,17 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
if (dr && pfxrtr_lookup(pr, dr) == NULL)
pfxrtr_add(pr, dr);
} else {
- struct nd_prefix *newpr = NULL;
-
- newprefix = 1;
-
if (new->ndpr_vltime == 0)
goto end;
if (new->ndpr_raf_onlink == 0 && new->ndpr_raf_auto == 0)
goto end;
- error = nd6_prelist_add(new, dr, &newpr);
- if (error != 0 || newpr == NULL) {
+ error = nd6_prelist_add(new, dr, &pr);
+ if (error != 0) {
nd6log((LOG_NOTICE, "prelist_update: "
- "nd6_prelist_add failed for %s/%d on %s "
- "errno=%d, returnpr=%p\n",
+ "nd6_prelist_add failed for %s/%d on %s errno=%d\n",
ip6_sprintf(ip6buf, &new->ndpr_prefix.sin6_addr),
- new->ndpr_plen, if_name(new->ndpr_ifp),
- error, newpr));
+ new->ndpr_plen, if_name(new->ndpr_ifp), error));
goto end; /* we should just give up in this case. */
}
@@ -1166,13 +1158,11 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
* addresses. Thus, we explicitly make sure that the prefix
* itself expires now.
*/
- if (newpr->ndpr_raf_onlink == 0) {
- newpr->ndpr_vltime = 0;
- newpr->ndpr_pltime = 0;
- in6_init_prefix_ltimes(newpr);
+ if (pr->ndpr_raf_onlink == 0) {
+ pr->ndpr_vltime = 0;
+ pr->ndpr_pltime = 0;
+ in6_init_prefix_ltimes(pr);
}
-
- pr = newpr;
}
/*
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c
index e03fc02..fbe4b1a 100644
--- a/sys/netipsec/ipsec.c
+++ b/sys/netipsec/ipsec.c
@@ -290,7 +290,7 @@ key_allocsp_default(const char* where, int tag)
* 0 : bypass
* EACCES : discard packet.
* ENOENT : ipsec_acquire() in progress, maybe.
- * others : error occured.
+ * others : error occurred.
* others: a pointer to SP
*
* NOTE: IPv6 mapped adddress concern is implemented here.
@@ -318,7 +318,7 @@ ipsec_getpolicy(struct tdb_ident *tdbi, u_int dir)
* 0 : bypass
* EACCES : discard packet.
* ENOENT : ipsec_acquire() in progress, maybe.
- * others : error occured.
+ * others : error occurred.
* others: a pointer to SP
*
* NOTE: IPv6 mapped adddress concern is implemented here.
@@ -425,7 +425,7 @@ ipsec_getpolicybysock(const struct mbuf *m, u_int dir, struct inpcb *inp,
* 0 : bypass
* EACCES : discard packet.
* ENOENT : ipsec_acquire() in progress, maybe.
- * others : error occured.
+ * others : error occurred.
*/
struct secpolicy *
ipsec_getpolicybyaddr(const struct mbuf *m, u_int dir, int *error)
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
index e0523d4..24d8f4e 100644
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -589,7 +589,7 @@ ipsec4_process_packet(struct mbuf *m, struct ipsecrequest *isr)
* packet will be returned for transmission after crypto
* processing, etc. are completed.
*
- * NB: m & sav are ``passed to caller'' who's reponsible for
+ * NB: m & sav are ``passed to caller'' who's responsible for
* for reclaiming their resources.
*/
switch(dst->sa.sa_family) {
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index 7d58d84..db7defd 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -933,7 +933,7 @@ key_do_allocsa_policy(struct secashead *sah, u_int state)
{
struct secasvar *sav, *nextsav, *candidate, *d;
- /* initilize */
+ /* initialize */
candidate = NULL;
SAHTREE_LOCK();
@@ -1058,7 +1058,7 @@ key_do_allocsa_policy(struct secashead *sah, u_int state)
* allocating a usable SA entry for a *INBOUND* packet.
* Must call key_freesav() later.
* OUT: positive: pointer to a usable sav (i.e. MATURE or DYING state).
- * NULL: not found, or error occured.
+ * NULL: not found, or error occurred.
*
* In the comparison, no source address is used--for RFC2401 conformance.
* To quote, from section 4.1:
@@ -2335,7 +2335,7 @@ key_spdget(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
* send
* <base, policy(*)>
* to KMD, and expect to receive
- * <base> with SADB_X_SPDACQUIRE if error occured,
+ * <base> with SADB_X_SPDACQUIRE if error occurred,
* or
* <base, policy>
* with SADB_X_SPDUPDATE from KMD by PF_KEY.
@@ -6153,7 +6153,7 @@ key_getprop(const struct secasindex *saidx)
* <base, SA, address(SD), (address(P)), x_policy,
* (identity(SD),) (sensitivity,) proposal>
* to KMD, and expect to receive
- * <base> with SADB_ACQUIRE if error occured,
+ * <base> with SADB_ACQUIRE if error occurred,
* or
* <base, src address, dst address, (SPI range)> with SADB_GETSPI
* from KMD by PF_KEY.
@@ -6517,9 +6517,9 @@ key_acquire2(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
/*
* Error message from KMd.
- * We assume that if error was occured in IKEd, the length of PFKEY
+ * We assume that if error was occurred in IKEd, the length of PFKEY
* message is equal to the size of sadb_msg structure.
- * We do not raise error even if error occured in this function.
+ * We do not raise error even if error occurred in this function.
*/
if (mhp->msg->sadb_msg_len == PFKEY_UNIT64(sizeof(struct sadb_msg))) {
struct secacq *acq;
diff --git a/sys/netpfil/ipfw/dn_heap.h b/sys/netpfil/ipfw/dn_heap.h
index c95473a..cb6e03e 100644
--- a/sys/netpfil/ipfw/dn_heap.h
+++ b/sys/netpfil/ipfw/dn_heap.h
@@ -83,7 +83,7 @@ enum {
* heap_insert() adds a key-pointer pair to the heap
*
* HEAP_TOP() returns a pointer to the top element of the heap,
- * but makes no checks on its existance (XXX should we change ?)
+ * but makes no checks on its existence (XXX should we change ?)
*
* heap_extract() removes the entry at the top, returing the pointer.
* (the key should have been read before).
@@ -146,7 +146,7 @@ int heap_scan(struct dn_heap *, int (*)(void *, uintptr_t), uintptr_t);
* of the dn_ht_find(), and of the callbacks:
*
* DNHT_KEY_IS_OBJ means the key is the object pointer.
- * It is usally of interest for the hash and match functions.
+ * It is usually of interest for the hash and match functions.
*
* DNHT_MATCH_PTR during a lookup, match pointers instead
* of calling match(). Normally used when removing specific
diff --git a/sys/netpfil/ipfw/dummynet.txt b/sys/netpfil/ipfw/dummynet.txt
index b3b2ee9..68cce1a 100644
--- a/sys/netpfil/ipfw/dummynet.txt
+++ b/sys/netpfil/ipfw/dummynet.txt
@@ -86,7 +86,7 @@ USERLAND-KERNEL API (ip_dummynet.h)
struct dn_link:
contains data about the physical link such as
- bandwith, delay, burst size;
+ bandwidth, delay, burst size;
struct dn_fs:
describes a flowset, i.e. a template for queues.
@@ -444,7 +444,7 @@ of the object to remove
Delete of pipe x
----------------
-A pipe can be deleted by the user throught the command 'ipfw pipe x delete'.
+A pipe can be deleted by the user through the command 'ipfw pipe x delete'.
To delete a pipe, the pipe is removed from the pipe list, and then deleted.
Also the scheduler associated with this pipe should be deleted.
For compatibility with old dummynet syntax, the associated FIFO scheduler and
@@ -452,7 +452,7 @@ FIFO flowset must be deleted.
Delete of flowset x
-------------------
-To remove a flowset, we must be sure that is no loger referenced by any object.
+To remove a flowset, we must be sure that is no longer referenced by any object.
If the flowset to remove is in the unlinked flowset list, there is not any
issue, the flowset can be safely removed calling a free() (the flowset
extension is not yet created if the flowset is in this list).
@@ -492,7 +492,7 @@ If the counter was not 0, we wait for it. Every time the dummynet_task()
function extract a scheduler from the system_heap, the counter is decremented.
If the scheduler has the delete flag enabled the dequeue() is not called and
delete_scheduler_instance() is called to delete the instance.
-Obviously this scheduler instance is no loger inserted in the system_heap.
+Obviously this scheduler instance is no longer inserted in the system_heap.
If the counter reaches 0, the delete_scheduler_template() function is called
all memory is released.
NOTE: Flowsets that belong to this scheduler are not deleted, so if a new
@@ -559,7 +559,7 @@ There are four request for old dummynet:
depending of its version. There are two function that build the
corrected buffer, ip_dummynet_get7() and ip_dummynet_get8(). These
functions reproduce the buffer exactly as 'ipfw' expect. The only difference
- is that the weight parameter for a queue is no loger sent by dummynet and so
+ is that the weight parameter for a queue is no longer sent by dummynet and so
it is set to 0.
Moreover, because of the internal structure has changed, the bucket size
of a queue could not be correct, because now all flowset share the hash
@@ -581,7 +581,7 @@ I have to modify the ip_fw2.c file to manage these two case, and added a
variable (is7) to store the ipfw version used, using an approach like the
previous file:
- when a new rule is added (option IP_FW_ADD) the is7 variable is set if the
- size of the rule received corrispond to FreeBSD 7.2 ipfw version. If so, the
+ size of the rule received correspond to FreeBSD 7.2 ipfw version. If so, the
rule is converted to version 8 calling the function convert_rule_to_8().
Moreover, after the insertion of the rule, the rule is now reconverted to
version 7 because the ipfw binary will print it.
diff --git a/sys/netpfil/ipfw/ip_dn_glue.c b/sys/netpfil/ipfw/ip_dn_glue.c
index 7d7e695..02fbf3e 100644
--- a/sys/netpfil/ipfw/ip_dn_glue.c
+++ b/sys/netpfil/ipfw/ip_dn_glue.c
@@ -778,7 +778,7 @@ ip_dummynet_compat(struct sockopt *sopt)
void *v = NULL;
struct dn_id oid;
- /* Lenght of data, used to found ipfw version... */
+ /* Length of data, used to found ipfw version... */
int len = sopt->sopt_valsize;
/* len can be 0 if command was dummynet_flush */
diff --git a/sys/netpfil/ipfw/ip_dummynet.c b/sys/netpfil/ipfw/ip_dummynet.c
index 9061ffa..a0c636e 100644
--- a/sys/netpfil/ipfw/ip_dummynet.c
+++ b/sys/netpfil/ipfw/ip_dummynet.c
@@ -1629,7 +1629,7 @@ dummynet_flush(void)
* with an oid which is at least a dn_id.
* - the first object is the command (config, delete, flush, ...)
* - config_link must be issued after the corresponding config_sched
- * - parameters (DN_TXT) for an object must preceed the object
+ * - parameters (DN_TXT) for an object must precede the object
* processed on a config_sched.
*/
int
diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c
index b0a7474..45da69d 100644
--- a/sys/netpfil/ipfw/ip_fw2.c
+++ b/sys/netpfil/ipfw/ip_fw2.c
@@ -936,7 +936,7 @@ ipfw_chk(struct ip_fw_args *args)
* offset == 0 means that (if this is an IPv4 packet)
* this is the first or only fragment.
* For IPv6 offset|ip6f_mf == 0 means there is no Fragment Header
- * or there is a single packet fragement (fragement header added
+ * or there is a single packet fragment (fragment header added
* without needed). We will treat a single packet fragment as if
* there was no fragment header (or log/block depending on the
* V_fw_permit_single_frag6 sysctl setting).
@@ -1999,7 +1999,7 @@ do { \
* certainly be inp_user_cookie?
*/
- /* For incomming packet, lookup up the
+ /* For incoming packet, lookup up the
inpcb using the src/dest ip/port tuple */
if (inp == NULL) {
inp = in_pcblookup(pi,
diff --git a/sys/netpfil/ipfw/ip_fw_dynamic.c b/sys/netpfil/ipfw/ip_fw_dynamic.c
index 96f38e4..991de22 100644
--- a/sys/netpfil/ipfw/ip_fw_dynamic.c
+++ b/sys/netpfil/ipfw/ip_fw_dynamic.c
@@ -989,7 +989,7 @@ ipfw_dyn_send_ka(struct mbuf **mtailp, ipfw_dyn_rule *q)
}
/*
- * This procedure is used to perform various maintance
+ * This procedure is used to perform various maintenance
* on dynamic hash list. Currently it is called every second.
*/
static void
@@ -1021,7 +1021,7 @@ ipfw_dyn_tick(void * vnetx)
/*
- * Walk thru all dynamic states doing generic maintance:
+ * Walk through all dynamic states doing generic maintenance:
* 1) free expired states
* 2) free all states based on deleted rule / set
* 3) send keepalives for states if needed
diff --git a/sys/netpfil/ipfw/ip_fw_iface.c b/sys/netpfil/ipfw/ip_fw_iface.c
index 07d24de..b2aa7d3 100644
--- a/sys/netpfil/ipfw/ip_fw_iface.c
+++ b/sys/netpfil/ipfw/ip_fw_iface.c
@@ -249,13 +249,14 @@ vnet_ipfw_iface_init(struct ip_fw_chain *ch)
}
}
-static void
+static int
destroy_iface(struct namedobj_instance *ii, struct named_object *no,
void *arg)
{
/* Assume all consumers have been already detached */
free(no, M_IPFW);
+ return (0);
}
/*
@@ -460,7 +461,7 @@ struct dump_iface_args {
struct sockopt_data *sd;
};
-static void
+static int
export_iface_internal(struct namedobj_instance *ii, struct named_object *no,
void *arg)
{
@@ -481,6 +482,7 @@ export_iface_internal(struct namedobj_instance *ii, struct named_object *no,
i->ifindex = iif->ifindex;
i->refcnt = iif->no.refcnt;
i->gencnt = iif->gencnt;
+ return (0);
}
/*
diff --git a/sys/netpfil/ipfw/ip_fw_nat.c b/sys/netpfil/ipfw/ip_fw_nat.c
index df40398..a32d32f 100644
--- a/sys/netpfil/ipfw/ip_fw_nat.c
+++ b/sys/netpfil/ipfw/ip_fw_nat.c
@@ -932,7 +932,7 @@ ipfw_nat_cfg(struct sockopt *sopt)
/*
* Allocate 2x buffer to store converted structures.
- * new redir_cfg has shrinked, so we're sure that
+ * new redir_cfg has shrunk, so we're sure that
* new buffer size is enough.
*/
buf = malloc(roundup2(len, 8) + len2, M_TEMP, M_WAITOK | M_ZERO);
diff --git a/sys/netpfil/ipfw/ip_fw_private.h b/sys/netpfil/ipfw/ip_fw_private.h
index 62e1a9a..52e8a76 100644
--- a/sys/netpfil/ipfw/ip_fw_private.h
+++ b/sys/netpfil/ipfw/ip_fw_private.h
@@ -649,7 +649,7 @@ caddr_t ipfw_get_sopt_header(struct sockopt_data *sd, size_t needed);
} while(0)
struct namedobj_instance;
-typedef void (objhash_cb_t)(struct namedobj_instance *ni, struct named_object *,
+typedef int (objhash_cb_t)(struct namedobj_instance *ni, struct named_object *,
void *arg);
typedef uint32_t (objhash_hash_f)(struct namedobj_instance *ni, const void *key,
uint32_t kopt);
@@ -675,7 +675,7 @@ int ipfw_objhash_same_name(struct namedobj_instance *ni, struct named_object *a,
void ipfw_objhash_add(struct namedobj_instance *ni, struct named_object *no);
void ipfw_objhash_del(struct namedobj_instance *ni, struct named_object *no);
uint32_t ipfw_objhash_count(struct namedobj_instance *ni);
-void ipfw_objhash_foreach(struct namedobj_instance *ni, objhash_cb_t *f,
+int ipfw_objhash_foreach(struct namedobj_instance *ni, objhash_cb_t *f,
void *arg);
int ipfw_objhash_free_idx(struct namedobj_instance *ni, uint16_t idx);
int ipfw_objhash_alloc_idx(void *n, uint16_t *pidx);
@@ -684,6 +684,8 @@ void ipfw_objhash_set_funcs(struct namedobj_instance *ni,
int ipfw_objhash_find_type(struct namedobj_instance *ni, struct tid_info *ti,
uint32_t etlv, struct named_object **pno);
void ipfw_export_obj_ntlv(struct named_object *no, ipfw_obj_ntlv *ntlv);
+ipfw_obj_ntlv *ipfw_find_name_tlv_type(void *tlvs, int len, uint16_t uidx,
+ uint32_t etlv);
void ipfw_init_obj_rewriter(void);
void ipfw_destroy_obj_rewriter(void);
void ipfw_add_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count);
diff --git a/sys/netpfil/ipfw/ip_fw_sockopt.c b/sys/netpfil/ipfw/ip_fw_sockopt.c
index 5eecf97..2f41d23 100644
--- a/sys/netpfil/ipfw/ip_fw_sockopt.c
+++ b/sys/netpfil/ipfw/ip_fw_sockopt.c
@@ -2467,7 +2467,7 @@ ref_rule_objects(struct ip_fw_chain *ch, struct ip_fw *rule,
if (error != 0)
break;
/*
- * Compability stuff for old clients:
+ * Compatibility stuff for old clients:
* prepare to automaitcally create non-existing objects.
*/
if (unresolved != 0) {
@@ -2579,7 +2579,7 @@ free:
* Rules in reply are modified to store their actual ruleset number.
*
* (*1) TLVs inside IPFW_TLV_TBL_LIST needs to be sorted ascending
- * accoring to their idx field and there has to be no duplicates.
+ * according to their idx field and there has to be no duplicates.
* (*2) Numbered rules inside IPFW_TLV_RULE_LIST needs to be sorted ascending.
* (*3) Each ip_fw structure needs to be aligned to u64 boundary.
*
@@ -3009,7 +3009,7 @@ ipfw_del_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count)
return (0);
}
-static void
+static int
export_objhash_ntlv_internal(struct namedobj_instance *ni,
struct named_object *no, void *arg)
{
@@ -3019,8 +3019,9 @@ export_objhash_ntlv_internal(struct namedobj_instance *ni,
sd = (struct sockopt_data *)arg;
ntlv = (ipfw_obj_ntlv *)ipfw_get_sopt_space(sd, sizeof(*ntlv));
if (ntlv == NULL)
- return;
+ return (ENOMEM);
ipfw_export_obj_ntlv(no, ntlv);
+ return (0);
}
/*
@@ -3279,7 +3280,7 @@ ipfw_flush_sopt_data(struct sockopt_data *sd)
}
/*
- * Ensures that @sd buffer has contigious @neeeded number of
+ * Ensures that @sd buffer has contiguous @neeeded number of
* bytes.
*
* Returns pointer to requested space or NULL.
@@ -3307,7 +3308,7 @@ ipfw_get_sopt_space(struct sockopt_data *sd, size_t needed)
}
/*
- * Requests @needed contigious bytes from @sd buffer.
+ * Requests @needed contiguous bytes from @sd buffer.
* Function is used to notify subsystem that we are
* interesed in first @needed bytes (request header)
* and the rest buffer can be safely zeroed.
@@ -3396,7 +3397,7 @@ ipfw_ctl3(struct sockopt *sopt)
/*
* Determine opcode type/buffer size:
* allocate sliding-window buf for data export or
- * contigious buffer for special ops.
+ * contiguous buffer for special ops.
*/
if ((h.dir & HDIR_SET) != 0) {
/* Set request. Allocate contigous buffer. */
@@ -4089,8 +4090,8 @@ ipfw_objhash_lookup_name(struct namedobj_instance *ni, uint32_t set, char *name)
*
* Returns pointer to found TLV or NULL.
*/
-static ipfw_obj_ntlv *
-find_name_tlv_type(void *tlvs, int len, uint16_t uidx, uint32_t etlv)
+ipfw_obj_ntlv *
+ipfw_find_name_tlv_type(void *tlvs, int len, uint16_t uidx, uint32_t etlv)
{
ipfw_obj_ntlv *ntlv;
uintptr_t pa, pe;
@@ -4145,7 +4146,7 @@ ipfw_objhash_find_type(struct namedobj_instance *ni, struct tid_info *ti,
if (ti->tlvs == NULL)
return (EINVAL);
- ntlv = find_name_tlv_type(ti->tlvs, ti->tlen, ti->uidx, etlv);
+ ntlv = ipfw_find_name_tlv_type(ti->tlvs, ti->tlen, ti->uidx, etlv);
if (ntlv == NULL)
return (EINVAL);
name = ntlv->name;
@@ -4249,16 +4250,20 @@ ipfw_objhash_count(struct namedobj_instance *ni)
* Runs @func for each found named object.
* It is safe to delete objects from callback
*/
-void
+int
ipfw_objhash_foreach(struct namedobj_instance *ni, objhash_cb_t *f, void *arg)
{
struct named_object *no, *no_tmp;
- int i;
+ int i, ret;
for (i = 0; i < ni->nn_size; i++) {
- TAILQ_FOREACH_SAFE(no, &ni->names[i], nn_next, no_tmp)
- f(ni, no, arg);
+ TAILQ_FOREACH_SAFE(no, &ni->names[i], nn_next, no_tmp) {
+ ret = f(ni, no, arg);
+ if (ret != 0)
+ return (ret);
+ }
}
+ return (0);
}
/*
diff --git a/sys/netpfil/ipfw/ip_fw_table.c b/sys/netpfil/ipfw/ip_fw_table.c
index 175202a..194be08 100644
--- a/sys/netpfil/ipfw/ip_fw_table.c
+++ b/sys/netpfil/ipfw/ip_fw_table.c
@@ -319,7 +319,7 @@ find_ref_table(struct ip_fw_chain *ch, struct tid_info *ti,
if (op == OP_DEL)
return (ESRCH);
- /* Compability mode: create new table for old clients */
+ /* Compatibility mode: create new table for old clients */
if ((tei->flags & TEI_FLAGS_COMPAT) == 0)
return (ESRCH);
@@ -927,7 +927,7 @@ manage_table_ent_v0(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
tei.masklen = xent->masklen;
ipfw_import_table_value_legacy(xent->value, &v);
tei.pvalue = &v;
- /* Old requests compability */
+ /* Old requests compatibility */
tei.flags = TEI_FLAGS_COMPAT;
if (xent->type == IPFW_TABLE_ADDR) {
if (xent->len - hdrlen == sizeof(in_addr_t))
@@ -1207,7 +1207,7 @@ flush_table(struct ip_fw_chain *ch, struct tid_info *ti)
uint8_t tflags;
/*
- * Stage 1: save table algoritm.
+ * Stage 1: save table algorithm.
* Reference found table to ensure it won't disappear.
*/
IPFW_UH_WLOCK(ch);
@@ -1879,7 +1879,6 @@ create_table(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
/*
* Creates new table based on @ti and @aname.
*
- * Relies on table name checking inside find_name_tlv()
* Assume @aname to be checked and valid.
* Stores allocated table kidx inside @pkidx (if non-NULL).
* Reference created table if @compat is non-zero.
@@ -2120,7 +2119,7 @@ struct dump_table_args {
struct sockopt_data *sd;
};
-static void
+static int
export_table_internal(struct namedobj_instance *ni, struct named_object *no,
void *arg)
{
@@ -2133,6 +2132,7 @@ export_table_internal(struct namedobj_instance *ni, struct named_object *no,
KASSERT(i != NULL, ("previously checked buffer is not enough"));
export_table_info(dta->ch, (struct table_config *)no, i);
+ return (0);
}
/*
@@ -2582,7 +2582,7 @@ ipfw_foreach_table_tentry(struct ip_fw_chain *ch, uint16_t kidx,
*/
/*
- * Finds algoritm by index, table type or supplied name.
+ * Finds algorithm by index, table type or supplied name.
*
* Returns pointer to algo or NULL.
*/
@@ -2927,44 +2927,6 @@ check_table_name(const char *name)
}
/*
- * Find tablename TLV by @uid.
- * Check @tlvs for valid data inside.
- *
- * Returns pointer to found TLV or NULL.
- */
-static ipfw_obj_ntlv *
-find_name_tlv(void *tlvs, int len, uint16_t uidx)
-{
- ipfw_obj_ntlv *ntlv;
- uintptr_t pa, pe;
- int l;
-
- pa = (uintptr_t)tlvs;
- pe = pa + len;
- l = 0;
- for (; pa < pe; pa += l) {
- ntlv = (ipfw_obj_ntlv *)pa;
- l = ntlv->head.length;
-
- if (l != sizeof(*ntlv))
- return (NULL);
-
- if (ntlv->head.type != IPFW_TLV_TBL_NAME)
- continue;
-
- if (ntlv->idx != uidx)
- continue;
-
- if (check_table_name(ntlv->name) != 0)
- return (NULL);
-
- return (ntlv);
- }
-
- return (NULL);
-}
-
-/*
* Finds table config based on either legacy index
* or name in ntlv.
* Note @ti structure contains unchecked data from userland.
@@ -2981,7 +2943,8 @@ find_table_err(struct namedobj_instance *ni, struct tid_info *ti,
uint32_t set;
if (ti->tlvs != NULL) {
- ntlv = find_name_tlv(ti->tlvs, ti->tlen, ti->uidx);
+ ntlv = ipfw_find_name_tlv_type(ti->tlvs, ti->tlen, ti->uidx,
+ IPFW_TLV_TBL_NAME);
if (ntlv == NULL)
return (EINVAL);
name = ntlv->name;
@@ -3039,7 +3002,8 @@ alloc_table_config(struct ip_fw_chain *ch, struct tid_info *ti,
uint32_t set;
if (ti->tlvs != NULL) {
- ntlv = find_name_tlv(ti->tlvs, ti->tlen, ti->uidx);
+ ntlv = ipfw_find_name_tlv_type(ti->tlvs, ti->tlen, ti->uidx,
+ IPFW_TLV_TBL_NAME);
if (ntlv == NULL)
return (NULL);
name = ntlv->name;
@@ -3160,7 +3124,7 @@ struct swap_table_args {
* Ensure we dispatch each table once by setting/checking ochange
* fields.
*/
-static void
+static int
swap_table_set(struct namedobj_instance *ni, struct named_object *no,
void *arg)
{
@@ -3171,10 +3135,10 @@ swap_table_set(struct namedobj_instance *ni, struct named_object *no,
sta = (struct swap_table_args *)arg;
if (no->set != sta->set && (no->set != sta->new_set || sta->mv != 0))
- return;
+ return (0);
if (tc->ochanged != 0)
- return;
+ return (0);
tc->ochanged = 1;
ipfw_objhash_del(ni, no);
@@ -3183,12 +3147,13 @@ swap_table_set(struct namedobj_instance *ni, struct named_object *no,
else
no->set = sta->set;
ipfw_objhash_add(ni, no);
+ return (0);
}
/*
* Cleans up ochange field for all tables.
*/
-static void
+static int
clean_table_set_data(struct namedobj_instance *ni, struct named_object *no,
void *arg)
{
@@ -3199,6 +3164,7 @@ clean_table_set_data(struct namedobj_instance *ni, struct named_object *no,
sta = (struct swap_table_args *)arg;
tc->ochanged = 0;
+ return (0);
}
/*
@@ -3224,7 +3190,7 @@ ipfw_swap_tables_sets(struct ip_fw_chain *ch, uint32_t set,
* Move all tables which are reference by rules in @rr to set @new_set.
* Makes sure that all relevant tables are referenced ONLLY by given rules.
*
- * Retuns 0 on success,
+ * Returns 0 on success,
*/
int
ipfw_move_tables_sets(struct ip_fw_chain *ch, ipfw_range_tlv *rt,
@@ -3355,7 +3321,7 @@ static struct ipfw_sopt_handler scodes[] = {
{ IP_FW_TABLE_XGETSIZE, 0, HDIR_GET, get_table_size },
};
-static void
+static int
destroy_table_locked(struct namedobj_instance *ni, struct named_object *no,
void *arg)
{
@@ -3365,6 +3331,7 @@ destroy_table_locked(struct namedobj_instance *ni, struct named_object *no,
printf("Error unlinking kidx %d from table %s\n",
no->kidx, no->name);
free_table_config(ni, (struct table_config *)no);
+ return (0);
}
/*
diff --git a/sys/netpfil/ipfw/ip_fw_table_algo.c b/sys/netpfil/ipfw/ip_fw_table_algo.c
index c04ee86..bd6a54d 100644
--- a/sys/netpfil/ipfw/ip_fw_table_algo.c
+++ b/sys/netpfil/ipfw/ip_fw_table_algo.c
@@ -181,7 +181,7 @@ __FBSDID("$FreeBSD$");
* OPTIONAL, locked (UH). (M_NOWAIT). Returns 0 on success.
*
* Finds entry specified by given key.
- * * Caller is requred to do the following:
+ * * Caller is required to do the following:
* entry found: returns 0, export entry to @tent
* entry not found: returns ENOENT
*
@@ -263,7 +263,7 @@ __FBSDID("$FreeBSD$");
* Dumps entry @e to @tent.
*
*
- * -print_config: prints custom algoritm options into buffer.
+ * -print_config: prints custom algorithm options into buffer.
* typedef void (ta_print_config)(void *ta_state, struct table_info *ti,
* char *buf, size_t bufsize);
* OPTIONAL. locked(UH). (M_NOWAIT).
@@ -1941,7 +1941,7 @@ static int ta_lookup_ifidx(struct table_info *ti, void *key, uint32_t keylen,
static int ta_init_ifidx(struct ip_fw_chain *ch, void **ta_state,
struct table_info *ti, char *data, uint8_t tflags);
static void ta_change_ti_ifidx(void *ta_state, struct table_info *ti);
-static void destroy_ifidx_locked(struct namedobj_instance *ii,
+static int destroy_ifidx_locked(struct namedobj_instance *ii,
struct named_object *no, void *arg);
static void ta_destroy_ifidx(void *ta_state, struct table_info *ti);
static void ta_dump_ifidx_tinfo(void *ta_state, struct table_info *ti,
@@ -1969,7 +1969,7 @@ static int ta_dump_ifidx_tentry(void *ta_state, struct table_info *ti, void *e,
ipfw_obj_tentry *tent);
static int ta_find_ifidx_tentry(void *ta_state, struct table_info *ti,
ipfw_obj_tentry *tent);
-static void foreach_ifidx(struct namedobj_instance *ii, struct named_object *no,
+static int foreach_ifidx(struct namedobj_instance *ii, struct named_object *no,
void *arg);
static void ta_foreach_ifidx(void *ta_state, struct table_info *ti,
ta_foreach_f *f, void *arg);
@@ -2126,7 +2126,7 @@ ta_change_ti_ifidx(void *ta_state, struct table_info *ti)
icfg->ti = ti;
}
-static void
+static int
destroy_ifidx_locked(struct namedobj_instance *ii, struct named_object *no,
void *arg)
{
@@ -2139,6 +2139,7 @@ destroy_ifidx_locked(struct namedobj_instance *ii, struct named_object *no,
ipfw_iface_del_notify(ch, &ife->ic);
ipfw_iface_unref(ch, &ife->ic);
free(ife, M_IPFW_TBL);
+ return (0);
}
@@ -2560,7 +2561,7 @@ struct wa_ifidx {
void *arg;
};
-static void
+static int
foreach_ifidx(struct namedobj_instance *ii, struct named_object *no,
void *arg)
{
@@ -2571,6 +2572,7 @@ foreach_ifidx(struct namedobj_instance *ii, struct named_object *no,
wa = (struct wa_ifidx *)arg;
wa->f(ife, wa->arg);
+ return (0);
}
static void
diff --git a/sys/netpfil/ipfw/ip_fw_table_value.c b/sys/netpfil/ipfw/ip_fw_table_value.c
index 7e2f5cb..e92a5a9 100644
--- a/sys/netpfil/ipfw/ip_fw_table_value.c
+++ b/sys/netpfil/ipfw/ip_fw_table_value.c
@@ -147,7 +147,7 @@ get_value_ptrs(struct ip_fw_chain *ch, struct table_config *tc, int vshared,
/*
* Update pointers to real vaues after @pval change.
*/
-static void
+static int
update_tvalue(struct namedobj_instance *ni, struct named_object *no, void *arg)
{
struct vdump_args *da;
@@ -160,7 +160,7 @@ update_tvalue(struct namedobj_instance *ni, struct named_object *no, void *arg)
pval = da->pval;
ptv->pval = &pval[ptv->no.kidx];
ptv->no.name = (char *)&pval[ptv->no.kidx];
-
+ return (0);
}
/*
@@ -500,7 +500,7 @@ ipfw_link_table_values(struct ip_fw_chain *ch, struct tableop_state *ts)
count = ts->count;
for (i = 0; i < count; i++) {
ptei = &tei[i];
- ptei->value = 0; /* Ensure value is always 0 in the beginnig */
+ ptei->value = 0; /* Ensure value is always 0 in the beginning */
mask_table_value(ptei->pvalue, &tval, ts->vmask);
ptv = (struct table_val_link *)ipfw_objhash_lookup_name(vi, 0,
(char *)&tval);
@@ -603,7 +603,7 @@ ipfw_link_table_values(struct ip_fw_chain *ch, struct tableop_state *ts)
}
/*
- * Compability function used to import data from old
+ * Compatibility function used to import data from old
* IP_FW_TABLE_ADD / IP_FW_TABLE_XADD opcodes.
*/
void
@@ -693,7 +693,7 @@ ipfw_export_table_value_v1(struct table_value *v, ipfw_table_value *piv)
* Exports real value data into ipfw_table_value structure.
* Utilizes "spare1" field to store kernel index.
*/
-static void
+static int
dump_tvalue(struct namedobj_instance *ni, struct named_object *no, void *arg)
{
struct vdump_args *da;
@@ -707,11 +707,12 @@ dump_tvalue(struct namedobj_instance *ni, struct named_object *no, void *arg)
/* Out of memory, returning */
if (v == NULL) {
da->error = ENOMEM;
- return;
+ return (ENOMEM);
}
memcpy(v, ptv->pval, sizeof(*v));
v->spare1 = ptv->no.kidx;
+ return (0);
}
/*
@@ -785,12 +786,13 @@ ipfw_table_value_init(struct ip_fw_chain *ch, int first)
IPFW_ADD_SOPT_HANDLER(first, scodes);
}
-static void
+static int
destroy_value(struct namedobj_instance *ni, struct named_object *no,
void *arg)
{
free(no, M_IPFW);
+ return (0);
}
void
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 1496ea4..a6ab515 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -4256,7 +4256,7 @@ pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst,
* (Selective ACK). We could optionally validate the SACK values
* against the current ACK window, either forwards or backwards, but
* I'm not confident that SACK has been implemented properly
- * everywhere. It wouldn't surprise me if several stacks accidently
+ * everywhere. It wouldn't surprise me if several stacks accidentally
* SACK too far backwards of previously ACKed data. There really aren't
* any security implications of bad SACKing unless the target stack
* doesn't validate the option length correctly. Someone trying to
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 8b3f02f..96c2288 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -3587,7 +3587,7 @@ shutdown_pf(void)
pf_clear_srcnodes(NULL);
/* status does not use malloced mem so no need to cleanup */
- /* fingerprints and interfaces have thier own cleanup code */
+ /* fingerprints and interfaces have their own cleanup code */
} while(0);
return (error);
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
index 99cca63..a2841a2 100644
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -62,7 +62,7 @@ __FBSDID("$FreeBSD$");
struct pf_frent {
TAILQ_ENTRY(pf_frent) fr_next;
struct mbuf *fe_m;
- uint16_t fe_hdrlen; /* ipv4 header lenght with ip options
+ uint16_t fe_hdrlen; /* ipv4 header length with ip options
ipv6, extension, fragment header */
uint16_t fe_extoff; /* last extension header offset or 0 */
uint16_t fe_len; /* fragment length */
diff --git a/sys/netsmb/smb_usr.c b/sys/netsmb/smb_usr.c
index 6c3e6b1..1b1d1f8 100644
--- a/sys/netsmb/smb_usr.c
+++ b/sys/netsmb/smb_usr.c
@@ -158,7 +158,7 @@ out:
/*
* Connect to the resource specified by smbioc_ossn structure.
* It may either find an existing connection or try to establish a new one.
- * If no errors occured smb_vc returned locked and referenced.
+ * If no errors occurred smb_vc returned locked and referenced.
*/
int
smb_usr_opensession(struct smbioc_ossn *dp, struct smb_cred *scred,
diff --git a/sys/ofed/drivers/infiniband/hw/mlx4/main.c b/sys/ofed/drivers/infiniband/hw/mlx4/main.c
index 41705ad..cff90cc 100644
--- a/sys/ofed/drivers/infiniband/hw/mlx4/main.c
+++ b/sys/ofed/drivers/infiniband/hw/mlx4/main.c
@@ -799,7 +799,7 @@ static int mlx4_ib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
unsigned long command = vma->vm_pgoff & MLX4_IB_MMAP_CMD_MASK;
if (command < MLX4_IB_MMAP_GET_CONTIGUOUS_PAGES) {
- /* compatability handling for commands 0 & 1*/
+ /* compatibility handling for commands 0 & 1*/
if (vma->vm_end - vma->vm_start != PAGE_SIZE)
return -EINVAL;
}
diff --git a/sys/ofed/drivers/infiniband/hw/mlx4/mcg.c b/sys/ofed/drivers/infiniband/hw/mlx4/mcg.c
index f2a8411..85199e7 100644
--- a/sys/ofed/drivers/infiniband/hw/mlx4/mcg.c
+++ b/sys/ofed/drivers/infiniband/hw/mlx4/mcg.c
@@ -689,7 +689,7 @@ static void mlx4_ib_mcg_work_handler(struct work_struct *work)
cur_join_state = group->rec.scope_join_state & 7;
if (method == IB_MGMT_METHOD_GET_RESP) {
- /* successfull join */
+ /* successful join */
if (!cur_join_state && resp_join_state)
--rc;
} else if (!resp_join_state)
diff --git a/sys/ofed/drivers/infiniband/hw/mlx4/mr.c b/sys/ofed/drivers/infiniband/hw/mlx4/mr.c
index a13bee7..f531a03 100644
--- a/sys/ofed/drivers/infiniband/hw/mlx4/mr.c
+++ b/sys/ofed/drivers/infiniband/hw/mlx4/mr.c
@@ -341,8 +341,8 @@ int mlx4_ib_umem_calc_optimal_mtt_size(struct ib_umem *umem,
address for the start of the MR.
*/
/* umem_get aligned the start_va to a page
- boundry. Therefore, we need to align the
- start va to the same boundry */
+ boundary. Therefore, we need to align the
+ start va to the same boundary */
/* misalignment_bits is needed to handle the
case of a single memory region. In this
case, the rest of the logic will not reduce
diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp.h b/sys/ofed/drivers/infiniband/ulp/sdp/sdp.h
index 5c573d2..bd07d49 100644
--- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp.h
+++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp.h
@@ -66,7 +66,7 @@ struct name { \
struct type *lh_first; /* first element */ \
}
-/* Interval between sucessive polls in the Tx routine when polling is used
+/* Interval between successive polls in the Tx routine when polling is used
instead of interrupts (in per-core Tx rings) - should be power of 2 */
#define SDP_TX_POLL_MODER 16
#define SDP_TX_POLL_TIMEOUT (HZ / 20)
@@ -424,8 +424,8 @@ struct sdp_sock {
/* SDP slow start */
int recv_request_head; /* mark the rx_head when the resize request
- was recieved */
- int recv_request; /* XXX flag if request to resize was recieved */
+ was received */
+ int recv_request; /* XXX flag if request to resize was received */
unsigned long tx_packets;
unsigned long rx_packets;
diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_tx.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_tx.c
index 6f54331..8f2a2f0 100644
--- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_tx.c
+++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_tx.c
@@ -328,7 +328,7 @@ sdp_poll_tx(struct sdp_sock *ssk)
SDPSTATS_COUNTER_INC(tx_poll_hit);
inflight = (u32) tx_ring_posted(ssk);
- sdp_prf1(ssk->socket, NULL, "finished tx proccessing. inflight = %d",
+ sdp_prf1(ssk->socket, NULL, "finished tx processing. inflight = %d",
inflight);
/* If there are still packets in flight and the timer has not already
diff --git a/sys/ofed/drivers/net/mlx4/en_rx.c b/sys/ofed/drivers/net/mlx4/en_rx.c
index 235a9ab..f4425af 100644
--- a/sys/ofed/drivers/net/mlx4/en_rx.c
+++ b/sys/ofed/drivers/net/mlx4/en_rx.c
@@ -552,7 +552,7 @@ mlx4_en_rx_mb(struct mlx4_en_priv *priv, struct mlx4_en_rx_ring *ring,
/* For cpu arch with cache line of 64B the performance is better when cqe size==64B
* To enlarge cqe size from 32B to 64B --> 32B of garbage (i.e. 0xccccccc)
* was added in the beginning of each cqe (the real data is in the corresponding 32B).
- * The following calc ensures that when factor==1, it means we are alligned to 64B
+ * The following calc ensures that when factor==1, it means we are aligned to 64B
* and we get the real cqe data*/
#define CQE_FACTOR_INDEX(index, factor) ((index << factor) + factor)
int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget)
diff --git a/sys/ofed/drivers/net/mlx4/fw.c b/sys/ofed/drivers/net/mlx4/fw.c
index 93f7f71..a16ede6 100644
--- a/sys/ofed/drivers/net/mlx4/fw.c
+++ b/sys/ofed/drivers/net/mlx4/fw.c
@@ -1901,7 +1901,7 @@ void mlx4_opreq_action(struct work_struct *work)
MLX4_CMD_GET_OP_REQ, MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_NATIVE);
if (err) {
- mlx4_err(dev, "Failed to retreive required operation: %d\n", err);
+ mlx4_err(dev, "Failed to retrieve required operation: %d\n", err);
return;
}
MLX4_GET(modifier, outbox, GET_OP_REQ_MODIFIER_OFFSET);
diff --git a/sys/ofed/drivers/net/mlx4/main.c b/sys/ofed/drivers/net/mlx4/main.c
index 462e7c8..314a4ba 100644
--- a/sys/ofed/drivers/net/mlx4/main.c
+++ b/sys/ofed/drivers/net/mlx4/main.c
@@ -159,7 +159,7 @@ MODULE_PARM_DESC(high_rate_steer, "Enable steering mode for higher packet rate"
static int fast_drop;
module_param_named(fast_drop, fast_drop, int, 0444);
MODULE_PARM_DESC(fast_drop,
- "Enable fast packet drop when no recieve WQEs are posted");
+ "Enable fast packet drop when no receive WQEs are posted");
int mlx4_enable_64b_cqe_eqe = 1;
module_param_named(enable_64b_cqe_eqe, mlx4_enable_64b_cqe_eqe, int, 0644);
@@ -2452,7 +2452,7 @@ EXPORT_SYMBOL_GPL(mlx4_counter_alloc);
void __mlx4_counter_free(struct mlx4_dev *dev, int slave, int port, u32 idx)
{
- /* check if native or slave and deletes acordingly */
+ /* check if native or slave and deletes accordingly */
struct mlx4_priv *priv = mlx4_priv(dev);
struct counter_index *pf, *tmp_pf;
struct counter_index *vf, *tmp_vf;
diff --git a/sys/ofed/drivers/net/mlx4/mlx4.h b/sys/ofed/drivers/net/mlx4/mlx4.h
index bef2e00..e23e461 100644
--- a/sys/ofed/drivers/net/mlx4/mlx4.h
+++ b/sys/ofed/drivers/net/mlx4/mlx4.h
@@ -164,7 +164,7 @@ enum mlx4_res_tracker_free_type {
/*
*Virtual HCR structures.
- * mlx4_vhcr is the sw representation, in machine endianess
+ * mlx4_vhcr is the sw representation, in machine endianness
*
* mlx4_vhcr_cmd is the formalized structure, the one that is passed
* to FW to go through communication channel.
diff --git a/sys/ofed/drivers/net/mlx4/resource_tracker.c b/sys/ofed/drivers/net/mlx4/resource_tracker.c
index 743c887..1bdab67 100644
--- a/sys/ofed/drivers/net/mlx4/resource_tracker.c
+++ b/sys/ofed/drivers/net/mlx4/resource_tracker.c
@@ -2916,7 +2916,7 @@ int mlx4_WRITE_MTT_wrapper(struct mlx4_dev *dev, int slave,
/* Call the SW implementation of write_mtt:
* - Prepare a dummy mtt struct
- * - Translate inbox contents to simple addresses in host endianess */
+ * - Translate inbox contents to simple addresses in host endianness */
mtt.offset = 0; /* TBD this is broken but I don't handle it since
we don't really use it */
mtt.order = 0;
diff --git a/sys/ofed/include/linux/mlx4/device.h b/sys/ofed/include/linux/mlx4/device.h
index aca4aef..7f545b1 100644
--- a/sys/ofed/include/linux/mlx4/device.h
+++ b/sys/ofed/include/linux/mlx4/device.h
@@ -106,7 +106,7 @@ enum {
MLX4_MFUNC_EQE_MASK = (MLX4_MFUNC_MAX_EQES - 1)
};
-/* Driver supports 3 diffrent device methods to manage traffic steering:
+/* Driver supports 3 different device methods to manage traffic steering:
* -device managed - High level API for ib and eth flow steering. FW is
* managing flow steering tables.
* - B0 steering mode - Common low level API for ib and (if supported) eth.
diff --git a/sys/opencrypto/cast.c b/sys/opencrypto/cast.c
index 7474b36..53fec76 100644
--- a/sys/opencrypto/cast.c
+++ b/sys/opencrypto/cast.c
@@ -127,7 +127,7 @@ u_int32_t t, l, r;
}
-/***** Key Schedual *****/
+/***** Key Schedule *****/
void cast_setkey(cast_key* key, u_int8_t* rawkey, int keybytes)
{
diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c
index d084b77..44fbdf8 100644
--- a/sys/opencrypto/crypto.c
+++ b/sys/opencrypto/crypto.c
@@ -911,7 +911,7 @@ again:
}
/*
- * Dispatch an assymetric crypto request.
+ * Dispatch an asymmetric crypto request.
*/
static int
crypto_kinvoke(struct cryptkop *krp, int crid)
diff --git a/sys/opencrypto/gfmult.c b/sys/opencrypto/gfmult.c
index 990a7ff..b34af26 100644
--- a/sys/opencrypto/gfmult.c
+++ b/sys/opencrypto/gfmult.c
@@ -40,7 +40,7 @@ static const uint8_t nib_rev[] = {
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf,
};
-/* calulate v * 2 */
+/* calculate v * 2 */
static inline struct gf128
gf128_mulalpha(struct gf128 v)
{
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index f67e5e5..d464ac7 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -102,6 +102,7 @@ device cpufreq
# Standard busses
device pci
+options PCI_HP # PCI-Express native HotPlug
device agp
# ATA controllers
diff --git a/sys/powerpc/conf/GENERIC64 b/sys/powerpc/conf/GENERIC64
index 847101f..88d4811 100644
--- a/sys/powerpc/conf/GENERIC64
+++ b/sys/powerpc/conf/GENERIC64
@@ -99,6 +99,7 @@ device cpufreq
# Standard busses
device pci
+options PCI_HP # PCI-Express native HotPlug
device agp
# ATA controllers
diff --git a/sys/rpc/clnt_bck.c b/sys/rpc/clnt_bck.c
index 477b276..f1c8dde 100644
--- a/sys/rpc/clnt_bck.c
+++ b/sys/rpc/clnt_bck.c
@@ -431,7 +431,7 @@ got_reply:
}
} /* end successful completion */
/*
- * If unsuccesful AND error is an authentication error
+ * If unsuccessful AND error is an authentication error
* then refresh credentials and try again, else break
*/
else if (stat == RPC_AUTHERROR)
diff --git a/sys/rpc/clnt_dg.c b/sys/rpc/clnt_dg.c
index d9d5e41..1f181fd 100644
--- a/sys/rpc/clnt_dg.c
+++ b/sys/rpc/clnt_dg.c
@@ -742,7 +742,7 @@ got_reply:
}
} /* end successful completion */
/*
- * If unsuccesful AND error is an authentication error
+ * If unsuccessful AND error is an authentication error
* then refresh credentials and try again, else break
*/
else if (stat == RPC_AUTHERROR)
@@ -882,7 +882,7 @@ clnt_dg_control(CLIENT *cl, u_int request, void *info)
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
- * begining of the RPC header. MUST be changed if the
+ * beginning of the RPC header. MUST be changed if the
* call_struct is changed
*/
*(uint32_t *)info =
@@ -899,7 +899,7 @@ clnt_dg_control(CLIENT *cl, u_int request, void *info)
/*
* This RELIES on the information that, in the call body,
* the program number field is the fourth field from the
- * begining of the RPC header. MUST be changed if the
+ * beginning of the RPC header. MUST be changed if the
* call_struct is changed
*/
*(uint32_t *)info =
diff --git a/sys/rpc/clnt_vc.c b/sys/rpc/clnt_vc.c
index 3899511..1bd6e1c 100644
--- a/sys/rpc/clnt_vc.c
+++ b/sys/rpc/clnt_vc.c
@@ -520,7 +520,7 @@ got_reply:
}
} /* end successful completion */
/*
- * If unsuccesful AND error is an authentication error
+ * If unsuccessful AND error is an authentication error
* then refresh credentials and try again, else break
*/
else if (stat == RPC_AUTHERROR)
@@ -653,7 +653,7 @@ clnt_vc_control(CLIENT *cl, u_int request, void *info)
/*
* This RELIES on the information that, in the call body,
* the version number field is the fifth field from the
- * begining of the RPC header. MUST be changed if the
+ * beginning of the RPC header. MUST be changed if the
* call_struct is changed
*/
*(uint32_t *)info =
@@ -671,7 +671,7 @@ clnt_vc_control(CLIENT *cl, u_int request, void *info)
/*
* This RELIES on the information that, in the call body,
* the program number field is the fourth field from the
- * begining of the RPC header. MUST be changed if the
+ * beginning of the RPC header. MUST be changed if the
* call_struct is changed
*/
*(uint32_t *)info =
diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c
index b436c18..50ab93a 100644
--- a/sys/rpc/svc.c
+++ b/sys/rpc/svc.c
@@ -440,7 +440,7 @@ xprt_inactive(SVCXPRT *xprt)
/*
* Variant of xprt_inactive() for use only when sure that port is
- * assigned to thread. For example, withing receive handlers.
+ * assigned to thread. For example, within receive handlers.
*/
void
xprt_inactive_self(SVCXPRT *xprt)
diff --git a/sys/rpc/svc.h b/sys/rpc/svc.h
index 80285ec..22322ba 100644
--- a/sys/rpc/svc.h
+++ b/sys/rpc/svc.h
@@ -226,7 +226,7 @@ typedef struct __rpc_svcxprt_ext {
* The services list
* Each entry represents a set of procedures (an rpc program).
* The dispatch routine takes request structs and runs the
- * apropriate procedure.
+ * appropriate procedure.
*/
struct svc_callout {
TAILQ_ENTRY(svc_callout) sc_link;
@@ -240,7 +240,7 @@ TAILQ_HEAD(svc_callout_list, svc_callout);
/*
* The services connection loss list
* The dispatch routine takes request structs and runs the
- * apropriate procedure.
+ * appropriate procedure.
*/
struct svc_loss_callout {
TAILQ_ENTRY(svc_loss_callout) slc_link;
diff --git a/sys/rpc/types.h b/sys/rpc/types.h
index dd51a8a..62b5aca 100644
--- a/sys/rpc/types.h
+++ b/sys/rpc/types.h
@@ -94,7 +94,7 @@ struct netbuf {
};
/*
- * The format of the addres and options arguments of the XTI t_bind call.
+ * The format of the address and options arguments of the XTI t_bind call.
* Only provided for compatibility, it should not be used.
*/
diff --git a/sys/security/mac/mac_cred.c b/sys/security/mac/mac_cred.c
index 372679b..48bd480 100644
--- a/sys/security/mac/mac_cred.c
+++ b/sys/security/mac/mac_cred.c
@@ -174,7 +174,7 @@ mac_cred_internalize_label(struct label *label, char *string)
/*
* When a new process is created, its label must be initialized. Generally,
- * this involves inheritence from the parent process, modulo possible deltas.
+ * this involves inheritance from the parent process, modulo possible deltas.
* This function allows that processing to take place.
*/
void
diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c
index d76b280..f56627c 100644
--- a/sys/security/mac/mac_framework.c
+++ b/sys/security/mac/mac_framework.c
@@ -437,7 +437,7 @@ mac_policy_register(struct mac_policy_conf *mpc)
* Per-policy initialization. Currently, this takes place under the
* exclusive lock, so policies must not sleep in their init method.
* In the future, we may want to separate "init" from "start", with
- * "init" occuring without the lock held. Likewise, on tear-down,
+ * "init" occurring without the lock held. Likewise, on tear-down,
* breaking out "stop" from "destroy".
*/
if (mpc->mpc_ops->mpo_init != NULL)
diff --git a/sys/security/mac_biba/mac_biba.h b/sys/security/mac_biba/mac_biba.h
index 05eefab..a97f29b 100644
--- a/sys/security/mac_biba/mac_biba.h
+++ b/sys/security/mac_biba/mac_biba.h
@@ -54,7 +54,7 @@
* MAC_BIBA_TYPE_LABEL. */
#define MAC_BIBA_TYPE_HIGH 3 /* Dominates any
* MAC_BIBA_TYPE_LABEL. */
-#define MAC_BIBA_TYPE_EQUAL 4 /* Equivilent to any
+#define MAC_BIBA_TYPE_EQUAL 4 /* Equivalent to any
* MAC_BIBA_TYPE_LABEL. */
/*
diff --git a/sys/security/mac_lomac/mac_lomac.c b/sys/security/mac_lomac/mac_lomac.c
index 5607940..b7c6289 100644
--- a/sys/security/mac_lomac/mac_lomac.c
+++ b/sys/security/mac_lomac/mac_lomac.c
@@ -1472,7 +1472,7 @@ lomac_netinet_firewall_send(struct mbuf *m, struct label *mlabel)
dest = SLOT(mlabel);
- /* XXX: where is the label for the firewall really comming from? */
+ /* XXX: where is the label for the firewall really coming from? */
lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
}
diff --git a/sys/security/mac_lomac/mac_lomac.h b/sys/security/mac_lomac/mac_lomac.h
index 9edba98..9e69f95 100644
--- a/sys/security/mac_lomac/mac_lomac.h
+++ b/sys/security/mac_lomac/mac_lomac.h
@@ -56,7 +56,7 @@
* MAC_LOMAC_TYPE_LABEL. */
#define MAC_LOMAC_TYPE_HIGH 3 /* Dominates any
* MAC_LOMAC_TYPE_LABEL. */
-#define MAC_LOMAC_TYPE_EQUAL 4 /* Equivilent to any
+#define MAC_LOMAC_TYPE_EQUAL 4 /* Equivalent to any
* MAC_LOMAC_TYPE_LABEL. */
/*
diff --git a/sys/security/mac_mls/mac_mls.c b/sys/security/mac_mls/mac_mls.c
index 6a074d0..935c159 100644
--- a/sys/security/mac_mls/mac_mls.c
+++ b/sys/security/mac_mls/mac_mls.c
@@ -1276,7 +1276,7 @@ mls_netinet_firewall_send(struct mbuf *m, struct label *mlabel)
dest = SLOT(mlabel);
- /* XXX: where is the label for the firewall really comming from? */
+ /* XXX: where is the label for the firewall really coming from? */
mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
}
diff --git a/sys/security/mac_mls/mac_mls.h b/sys/security/mac_mls/mac_mls.h
index 7bed921..b1ba469 100644
--- a/sys/security/mac_mls/mac_mls.h
+++ b/sys/security/mac_mls/mac_mls.h
@@ -54,7 +54,7 @@
* MAC_MLS_TYPE_LABEL. */
#define MAC_MLS_TYPE_HIGH 3 /* Dominates any
* MAC_MLS_TYPE_LABEL. */
-#define MAC_MLS_TYPE_EQUAL 4 /* Equivilent to any
+#define MAC_MLS_TYPE_EQUAL 4 /* Equivalent to any
* MAC_MLS_TYPE_LABEL. */
/*
diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c
index 65e44ff..6d448f9 100644
--- a/sys/sparc64/sbus/sbus.c
+++ b/sys/sparc64/sbus/sbus.c
@@ -341,7 +341,7 @@ sbus_attach(device_t dev)
sc->sc_burst =
(SBUS_BURST64_DEF << SBUS_BURST64_SHIFT) | SBUS_BURST_DEF;
- /* initalise the IOMMU */
+ /* initialise the IOMMU */
/* punch in our copies */
sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(SBUS_IOMMU_BITS);
diff --git a/sys/sparc64/sparc64/intr_machdep.c b/sys/sparc64/sparc64/intr_machdep.c
index fe467f0..2c0c538 100644
--- a/sys/sparc64/sparc64/intr_machdep.c
+++ b/sys/sparc64/sparc64/intr_machdep.c
@@ -367,7 +367,7 @@ inthand_add(const char *name, int vec, driver_filter_t *filt,
/*
* Check if we need to upgrade from PIL_ITHREAD to PIL_FILTER.
* Given that apart from the on-board SCCs and UARTs shared
- * interrupts are rather uncommon on sparc64 this sould be
+ * interrupts are rather uncommon on sparc64 this should be
* pretty rare in practice.
*/
filter = 0;
diff --git a/sys/sys/_bitset.h b/sys/sys/_bitset.h
index 26a8848..2f5301d 100644
--- a/sys/sys/_bitset.h
+++ b/sys/sys/_bitset.h
@@ -36,26 +36,23 @@
* Macros addressing word and bit within it, tuned to make compiler
* optimize cases when SETSIZE fits into single machine word.
*/
-#define _BITSET_BITS (sizeof(long) * NBBY)
+#define _BITSET_BITS (sizeof(long) * 8)
-#define __bitset_words(_s) (howmany(_s, _BITSET_BITS))
+#define __howmany(x, y) (((x) + ((y) - 1)) / (y))
-#define __bitset_mask(_s, n) \
- (1L << ((__bitset_words((_s)) == 1) ? \
- (__size_t)(n) : ((n) % _BITSET_BITS)))
-
-#define __bitset_word(_s, n) \
- ((__bitset_words((_s)) == 1) ? 0 : ((n) / _BITSET_BITS))
+#define __bitset_words(_s) (__howmany(_s, _BITSET_BITS))
#define BITSET_DEFINE(t, _s) \
struct t { \
long __bits[__bitset_words((_s))]; \
}
-#define BITSET_T_INITIALIZER(x) \
- { .__bits = { x } }
-
-#define BITSET_FSET(n) \
- [ 0 ... ((n) - 1) ] = (-1L)
+/*
+ * Helper to declare a bitset without it's size being a constant.
+ *
+ * Sadly we cannot declare a bitset struct with '__bits[]', because it's
+ * the only member of the struct and the compiler complains.
+ */
+#define BITSET_DEFINE_VAR(t) BITSET_DEFINE(t, 1)
#endif /* !_SYS__BITSET_H_ */
diff --git a/sys/sys/_cpuset.h b/sys/sys/_cpuset.h
index cd384848..1ddafac 100644
--- a/sys/sys/_cpuset.h
+++ b/sys/sys/_cpuset.h
@@ -44,13 +44,7 @@
#define CPU_SETSIZE CPU_MAXSIZE
#endif
-#define _NCPUBITS _BITSET_BITS
-#define _NCPUWORDS __bitset_words(CPU_SETSIZE)
-
BITSET_DEFINE(_cpuset, CPU_SETSIZE);
typedef struct _cpuset cpuset_t;
-#define CPUSET_FSET BITSET_FSET(_NCPUWORDS)
-#define CPUSET_T_INITIALIZER BITSET_T_INITIALIZER
-
#endif /* !_SYS__CPUSET_H_ */
diff --git a/sys/sys/ata.h b/sys/sys/ata.h
index 5df610e..672ee41 100644
--- a/sys/sys/ata.h
+++ b/sys/sys/ata.h
@@ -377,10 +377,10 @@ struct ata_params {
#define ATA_NCQ_NON_DATA 0x63 /* NCQ non-data command */
#define ATA_SEND_FPDMA_QUEUED 0x64 /* send DMA NCQ */
#define ATA_SFPDMA_DSM 0x00 /* Data set management */
-#define ATA_SFPDMA_DSM_TRIM 0x01 /* Set trim bit in auxilary */
+#define ATA_SFPDMA_DSM_TRIM 0x01 /* Set trim bit in auxiliary */
#define ATA_SFPDMA_HYBRID_EVICT 0x01 /* Hybrid Evict */
#define ATA_SFPDMA_WLDMA 0x02 /* Write Log DMA EXT */
-#define ATA_RECV_FPDMA_QUEUED 0x65 /* recieve DMA NCQ */
+#define ATA_RECV_FPDMA_QUEUED 0x65 /* receive DMA NCQ */
#define ATA_SEP_ATTN 0x67 /* SEP request */
#define ATA_SEEK 0x70 /* seek */
#define ATA_PACKET_CMD 0xa0 /* packet command */
diff --git a/sys/sys/bitset.h b/sys/sys/bitset.h
index d130522..723c39b 100644
--- a/sys/sys/bitset.h
+++ b/sys/sys/bitset.h
@@ -32,6 +32,13 @@
#ifndef _SYS_BITSET_H_
#define _SYS_BITSET_H_
+#define __bitset_mask(_s, n) \
+ (1L << ((__bitset_words((_s)) == 1) ? \
+ (__size_t)(n) : ((n) % _BITSET_BITS)))
+
+#define __bitset_word(_s, n) \
+ ((__bitset_words((_s)) == 1) ? 0 : ((n) / _BITSET_BITS))
+
#define BIT_CLR(_s, n, p) \
((p)->__bits[__bitset_word(_s, n)] &= ~__bitset_mask((_s), (n)))
@@ -185,5 +192,17 @@
__count += __bitcountl((p)->__bits[__i]); \
__count; \
})
-
+
+#define BITSET_T_INITIALIZER(x) \
+ { .__bits = { x } }
+
+#define BITSET_FSET(n) \
+ [ 0 ... ((n) - 1) ] = (-1L)
+
+/*
+ * Dynamically allocate a bitset.
+ */
+#define BITSET_ALLOC(_s, mt, mf) \
+ malloc(__bitset_words(_s) * sizeof(long), mt, (mf))
+
#endif /* !_SYS_BITSET_H_ */
diff --git a/sys/sys/bitstring.h b/sys/sys/bitstring.h
index 125ef51..a8d5652 100644
--- a/sys/sys/bitstring.h
+++ b/sys/sys/bitstring.h
@@ -29,118 +29,231 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * Copyright (c) 2014 Spectra Logic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
* $FreeBSD$
*/
-
#ifndef _SYS_BITSTRING_H_
#define _SYS_BITSTRING_H_
-typedef unsigned char bitstr_t;
+#ifdef _KERNEL
+#include <sys/libkern.h>
+#include <sys/malloc.h>
+#endif
+
+typedef unsigned long bitstr_t;
+
+/*---------------------- Private Implementation Details ----------------------*/
+#define _BITSTR_MASK (~0UL)
+#define _BITSTR_BITS (sizeof(bitstr_t) * 8)
-/* internal macros */
- /* byte of the bitstring bit is in */
-#define _bit_byte(bit) \
- ((bit) >> 3)
+/* bitstr_t in bit string containing the bit. */
+static inline int
+_bit_idx(int _bit)
+{
+ return (_bit / _BITSTR_BITS);
+}
- /* mask for the bit within its byte */
-#define _bit_mask(bit) \
- (1 << ((bit)&0x7))
+/* bit number within bitstr_t at _bit_idx(_bit). */
+static inline int
+_bit_offset(int _bit)
+{
+ return (_bit % _BITSTR_BITS);
+}
-/* external macros */
- /* bytes in a bitstring of nbits bits */
-#define bitstr_size(nbits) \
- (((nbits) + 7) >> 3)
+/* Mask for the bit within its long. */
+static inline bitstr_t
+_bit_mask(int _bit)
+{
+ return (1UL << _bit_offset(_bit));
+}
- /* allocate a bitstring */
-#define bit_alloc(nbits) \
- (bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t))
+static inline bitstr_t
+_bit_make_mask(int _start, int _stop)
+{
+ return ((_BITSTR_MASK << _bit_offset(_start)) &
+ (_BITSTR_MASK >> (_BITSTR_BITS - _bit_offset(_stop) - 1)));
+}
- /* allocate a bitstring on the stack */
+/*----------------------------- Public Interface -----------------------------*/
+/* Number of bytes consumed by a bit string of nbits bits */
+#define bitstr_size(_nbits) \
+ (((_nbits) + _BITSTR_BITS - 1) / 8)
+
+/* Allocate a bit string initialized with no bits set. */
+#ifdef _KERNEL
+static inline bitstr_t *
+bit_alloc(int _nbits, struct malloc_type *type, int flags)
+{
+ return ((bitstr_t *)malloc(bitstr_size(_nbits), type, flags | M_ZERO));
+}
+#else
+static inline bitstr_t *
+bit_alloc(int _nbits)
+{
+ return ((bitstr_t *)calloc(bitstr_size(_nbits), 1));
+}
+#endif
+
+/* Allocate a bit string on the stack with no bits set. */
#define bit_decl(name, nbits) \
- ((name)[bitstr_size(nbits)])
-
- /* is bit N of bitstring name set? */
-#define bit_test(name, bit) \
- ((name)[_bit_byte(bit)] & _bit_mask(bit))
-
- /* set bit N of bitstring name */
-#define bit_set(name, bit) \
- ((name)[_bit_byte(bit)] |= _bit_mask(bit))
-
- /* clear bit N of bitstring name */
-#define bit_clear(name, bit) \
- ((name)[_bit_byte(bit)] &= ~_bit_mask(bit))
-
- /* clear bits start ... stop in bitstring */
-#define bit_nclear(name, start, stop) do { \
- register bitstr_t *_name = (name); \
- register int _start = (start), _stop = (stop); \
- register int _startbyte = _bit_byte(_start); \
- register int _stopbyte = _bit_byte(_stop); \
- if (_startbyte == _stopbyte) { \
- _name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \
- (0xff << ((_stop&0x7) + 1))); \
- } else { \
- _name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \
- while (++_startbyte < _stopbyte) \
- _name[_startbyte] = 0; \
- _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \
- } \
-} while (0)
-
- /* set bits start ... stop in bitstring */
-#define bit_nset(name, start, stop) do { \
- register bitstr_t *_name = (name); \
- register int _start = (start), _stop = (stop); \
- register int _startbyte = _bit_byte(_start); \
- register int _stopbyte = _bit_byte(_stop); \
- if (_startbyte == _stopbyte) { \
- _name[_startbyte] |= ((0xff << (_start&0x7)) & \
- (0xff >> (7 - (_stop&0x7)))); \
- } else { \
- _name[_startbyte] |= 0xff << ((_start)&0x7); \
- while (++_startbyte < _stopbyte) \
- _name[_startbyte] = 0xff; \
- _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \
- } \
-} while (0)
-
- /* find first bit clear in name */
-#define bit_ffc(name, nbits, value) do { \
- register bitstr_t *_name = (name); \
- register int _byte, _nbits = (nbits); \
- register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \
- if (_nbits > 0) \
- for (_byte = 0; _byte <= _stopbyte; ++_byte) \
- if (_name[_byte] != 0xff) { \
- bitstr_t _lb; \
- _value = _byte << 3; \
- for (_lb = _name[_byte]; (_lb&0x1); \
- ++_value, _lb >>= 1); \
- break; \
- } \
- if (_value >= nbits) \
- _value = -1; \
- *(value) = _value; \
-} while (0)
-
- /* find first bit set in name */
-#define bit_ffs(name, nbits, value) do { \
- register bitstr_t *_name = (name); \
- register int _byte, _nbits = (nbits); \
- register int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \
- if (_nbits > 0) \
- for (_byte = 0; _byte <= _stopbyte; ++_byte) \
- if (_name[_byte]) { \
- bitstr_t _lb; \
- _value = _byte << 3; \
- for (_lb = _name[_byte]; !(_lb&0x1); \
- ++_value, _lb >>= 1); \
- break; \
- } \
- if (_value >= nbits) \
- _value = -1; \
- *(value) = _value; \
-} while (0)
-
-#endif /* !_SYS_BITSTRING_H_ */
+ ((name)[bitstr_size(nbits) / sizeof(bitstr_t)])
+
+/* Is bit N of bit string set? */
+static inline int
+bit_test(const bitstr_t *_bitstr, int _bit)
+{
+ return ((_bitstr[_bit_idx(_bit)] & _bit_mask(_bit)) != 0);
+}
+
+/* Set bit N of bit string. */
+static inline void
+bit_set(bitstr_t *_bitstr, int _bit)
+{
+ _bitstr[_bit_idx(_bit)] |= _bit_mask(_bit);
+}
+
+/* clear bit N of bit string name */
+static inline void
+bit_clear(bitstr_t *_bitstr, int _bit)
+{
+ _bitstr[_bit_idx(_bit)] &= ~_bit_mask(_bit);
+}
+
+/* Set bits start ... stop inclusive in bit string. */
+static inline void
+bit_nset(bitstr_t *_bitstr, int _start, int _stop)
+{
+ bitstr_t *_stopbitstr;
+
+ _stopbitstr = _bitstr + _bit_idx(_stop);
+ _bitstr += _bit_idx(_start);
+
+ if (_bitstr == _stopbitstr) {
+ *_bitstr |= _bit_make_mask(_start, _stop);
+ } else {
+ *_bitstr |= _bit_make_mask(_start, _BITSTR_BITS - 1);
+ while (++_bitstr < _stopbitstr)
+ *_bitstr = _BITSTR_MASK;
+ *_stopbitstr |= _bit_make_mask(0, _stop);
+ }
+}
+
+/* Clear bits start ... stop inclusive in bit string. */
+static inline void
+bit_nclear(bitstr_t *_bitstr, int _start, int _stop)
+{
+ bitstr_t *_stopbitstr;
+
+ _stopbitstr = _bitstr + _bit_idx(_stop);
+ _bitstr += _bit_idx(_start);
+
+ if (_bitstr == _stopbitstr) {
+ *_bitstr &= ~_bit_make_mask(_start, _stop);
+ } else {
+ *_bitstr &= ~_bit_make_mask(_start, _BITSTR_BITS - 1);
+ while (++_bitstr < _stopbitstr)
+ *_bitstr = 0;
+ *_stopbitstr &= ~_bit_make_mask(0, _stop);
+ }
+}
+
+/* Find the first bit set in bit string at or after bit start. */
+static inline void
+bit_ffs_at(bitstr_t *_bitstr, int _start, int _nbits, int *_result)
+{
+ bitstr_t *_curbitstr;
+ bitstr_t *_stopbitstr;
+ bitstr_t _test;
+ int _value, _offset;
+
+ if (_nbits > 0) {
+ _curbitstr = _bitstr + _bit_idx(_start);
+ _stopbitstr = _bitstr + _bit_idx(_nbits - 1);
+
+ _test = *_curbitstr;
+ if (_bit_offset(_start) != 0)
+ _test &= _bit_make_mask(_start, _BITSTR_BITS - 1);
+ while (_test == 0 && _curbitstr < _stopbitstr)
+ _test = *(++_curbitstr);
+
+ _offset = ffsl(_test);
+ _value = ((_curbitstr - _bitstr) * _BITSTR_BITS) + _offset - 1;
+ if (_offset == 0 || _value >= _nbits)
+ _value = -1;
+ } else {
+ _value = -1;
+ }
+ *_result = _value;
+}
+
+/* Find the first bit clear in bit string at or after bit start. */
+static inline void
+bit_ffc_at(bitstr_t *_bitstr, int _start, int _nbits, int *_result)
+{
+ bitstr_t *_curbitstr;
+ bitstr_t *_stopbitstr;
+ bitstr_t _test;
+ int _value, _offset;
+
+ if (_nbits > 0) {
+ _curbitstr = _bitstr + _bit_idx(_start);
+ _stopbitstr = _bitstr + _bit_idx(_nbits - 1);
+
+ _test = *_curbitstr;
+ if (_bit_offset(_start) != 0)
+ _test |= _bit_make_mask(0, _start - 1);
+ while (_test == _BITSTR_MASK && _curbitstr < _stopbitstr)
+ _test = *(++_curbitstr);
+
+ _offset = ffsl(~_test);
+ _value = ((_curbitstr - _bitstr) * _BITSTR_BITS) + _offset - 1;
+ if (_offset == 0 || _value >= _nbits)
+ _value = -1;
+ } else {
+ _value = -1;
+ }
+ *_result = _value;
+}
+
+/* Find the first bit set in bit string. */
+static inline void
+bit_ffs(bitstr_t *_bitstr, int _nbits, int *_result)
+{
+ bit_ffs_at(_bitstr, /*start*/0, _nbits, _result);
+}
+
+/* Find the first bit clear in bit string. */
+static inline void
+bit_ffc(bitstr_t *_bitstr, int _nbits, int *_result)
+{
+ bit_ffc_at(_bitstr, /*start*/0, _nbits, _result);
+}
+
+#endif /* _SYS_BITSTRING_H_ */
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
index 77343e7..cec28f4 100644
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -206,7 +206,7 @@ struct buf {
#define B_NOREUSE 0x00000800 /* Contents not reused once released. */
#define B_00001000 0x00001000 /* Available flag. */
#define B_INVAL 0x00002000 /* Does not contain valid info. */
-#define B_BARRIER 0x00004000 /* Write this and all preceeding first. */
+#define B_BARRIER 0x00004000 /* Write this and all preceding first. */
#define B_NOCACHE 0x00008000 /* Do not cache block after use. */
#define B_MALLOC 0x00010000 /* malloced b_data */
#define B_CLUSTEROK 0x00020000 /* Pagein op, so swap() can count it. */
diff --git a/sys/sys/buf_ring.h b/sys/sys/buf_ring.h
index 6a6bfc4..c771fe0 100644
--- a/sys/sys/buf_ring.h
+++ b/sys/sys/buf_ring.h
@@ -98,7 +98,7 @@ buf_ring_enqueue(struct buf_ring *br, void *buf)
/*
* If there are other enqueues in progress
- * that preceeded us, we need to wait for them
+ * that preceded us, we need to wait for them
* to complete
*/
while (br->br_prod_tail != prod_head)
@@ -135,7 +135,7 @@ buf_ring_dequeue_mc(struct buf_ring *br)
#endif
/*
* If there are other dequeues in progress
- * that preceeded us, we need to wait for them
+ * that preceded us, we need to wait for them
* to complete
*/
while (br->br_cons_tail != cons_head)
diff --git a/sys/sys/cpuset.h b/sys/sys/cpuset.h
index 4fa55a9..e017883 100644
--- a/sys/sys/cpuset.h
+++ b/sys/sys/cpuset.h
@@ -35,6 +35,10 @@
#include <sys/_cpuset.h>
#include <sys/bitset.h>
+#include <sys/queue.h>
+
+#define _NCPUBITS _BITSET_BITS
+#define _NCPUWORDS __bitset_words(CPU_SETSIZE)
#define CPUSETBUFSIZ ((2 + sizeof(long) * 2) * _NCPUWORDS)
@@ -61,6 +65,8 @@
#define CPU_COPY_STORE_REL(f, t) BIT_COPY_STORE_REL(CPU_SETSIZE, f, t)
#define CPU_FFS(p) BIT_FFS(CPU_SETSIZE, p)
#define CPU_COUNT(p) BIT_COUNT(CPU_SETSIZE, p)
+#define CPUSET_FSET BITSET_FSET(_NCPUWORDS)
+#define CPUSET_T_INITIALIZER BITSET_T_INITIALIZER
/*
* Valid cpulevel_t values.
diff --git a/sys/sys/event.h b/sys/sys/event.h
index 7897c81..5b54150 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -121,6 +121,12 @@ struct kevent {
#define NOTE_LINK 0x0010 /* link count changed */
#define NOTE_RENAME 0x0020 /* vnode was renamed */
#define NOTE_REVOKE 0x0040 /* vnode access was revoked */
+#define NOTE_OPEN 0x0080 /* vnode was opened */
+#define NOTE_CLOSE 0x0100 /* file closed, fd did not
+ allowed write */
+#define NOTE_CLOSE_WRITE 0x0200 /* file closed, fd did allowed
+ write */
+#define NOTE_READ 0x0400 /* file was read */
/*
* data/hint flags for EVFILT_PROC and EVFILT_PROCDESC, shared with userspace
diff --git a/sys/sys/iconv.h b/sys/sys/iconv.h
index 5e59795..44a03e961 100644
--- a/sys/sys/iconv.h
+++ b/sys/sys/iconv.h
@@ -65,7 +65,7 @@ struct iconv_cspair_info {
};
/*
- * Paramters for 'add' sysctl
+ * Parameters for 'add' sysctl
*/
#define ICONV_ADD_VER 1
diff --git a/sys/sys/imgact_binmisc.h b/sys/sys/imgact_binmisc.h
index f1ed1d8..7d58fa0 100644
--- a/sys/sys/imgact_binmisc.h
+++ b/sys/sys/imgact_binmisc.h
@@ -41,7 +41,7 @@
#define IBE_NAME_MAX 32 /* Max size for entry name. */
#define IBE_MAGIC_MAX 256 /* Max size for header magic and mask. */
#define IBE_ARG_LEN_MAX 256 /* Max space for optional interpreter command-
- line argruments seperated by white space */
+ line arguments separated by white space */
#define IBE_INTERP_LEN_MAX (MAXPATHLEN + IBE_ARG_LEN_MAX)
#define IBE_MAX_ENTRIES 64 /* Max number of interpreter entries. */
diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h
index 9b47042..beb5f96 100644
--- a/sys/sys/imgact_elf.h
+++ b/sys/sys/imgact_elf.h
@@ -41,7 +41,7 @@ struct image_params;
struct thread;
/*
- * Structure used to pass infomation from the loader to the
+ * Structure used to pass information from the loader to the
* stack fixup routine.
*/
typedef struct {
diff --git a/sys/sys/intr.h b/sys/sys/intr.h
index 7d309f5..e1e2a22 100644
--- a/sys/sys/intr.h
+++ b/sys/sys/intr.h
@@ -40,8 +40,14 @@ enum intr_map_data_type {
INTR_MAP_DATA_GPIO,
};
+struct intr_map_data {
+ enum intr_map_data_type type;
+ size_t size;
+};
+
#ifdef DEV_ACPI
struct intr_map_data_acpi {
+ struct intr_map_data hdr;
u_int irq;
enum intr_polarity pol;
enum intr_trigger trig;
@@ -49,30 +55,19 @@ struct intr_map_data_acpi {
#endif
#ifdef FDT
struct intr_map_data_fdt {
- u_int ncells;
- pcell_t *cells;
+ struct intr_map_data hdr;
+ u_int ncells;
+ pcell_t cells[0];
};
#endif
struct intr_map_data_gpio {
+ struct intr_map_data hdr;
u_int gpio_pin_num;
u_int gpio_pin_flags;
u_int gpio_intr_mode;
};
-struct intr_map_data {
- enum intr_map_data_type type;
- union {
-#ifdef DEV_ACPI
- struct intr_map_data_acpi acpi;
-#endif
-#ifdef FDT
- struct intr_map_data_fdt fdt;
-#endif
- struct intr_map_data_gpio gpio;
- };
-};
-
#ifdef notyet
#define INTR_SOLO INTR_MD1
typedef int intr_irq_filter_t(void *arg, struct trapframe *tf);
diff --git a/sys/sys/ipc.h b/sys/sys/ipc.h
index e643d48..19f1d39 100644
--- a/sys/sys/ipc.h
+++ b/sys/sys/ipc.h
@@ -112,7 +112,7 @@ struct ipc_perm {
#define IPC_STAT 2 /* get options */
#if __BSD_VISIBLE
/*
- * For Linux compatability.
+ * For Linux compatibility.
*/
#define IPC_INFO 3 /* get info */
#endif
diff --git a/sys/sys/ipmi.h b/sys/sys/ipmi.h
index 578d78c..b8e318a 100644
--- a/sys/sys/ipmi.h
+++ b/sys/sys/ipmi.h
@@ -122,7 +122,7 @@ struct ipmi_ipmb_addr {
};
#if defined(__amd64__)
-/* Compatiblity with 32-bit binaries. */
+/* Compatibility with 32-bit binaries. */
#define IPMICTL_RECEIVE_MSG_TRUNC_32 _IOWR(IPMI_IOC_MAGIC, 11, struct ipmi_recv32)
#define IPMICTL_RECEIVE_MSG_32 _IOWR(IPMI_IOC_MAGIC, 12, struct ipmi_recv32)
diff --git a/sys/sys/linker.h b/sys/sys/linker.h
index 5248bfb..42253a7 100644
--- a/sys/sys/linker.h
+++ b/sys/sys/linker.h
@@ -160,7 +160,7 @@ int linker_file_function_listall(linker_file_t,
linker_function_nameval_callback_t, void *);
/*
- * Functions soley for use by the linker class handlers.
+ * Functions solely for use by the linker class handlers.
*/
int linker_add_class(linker_class_t _cls);
int linker_file_unload(linker_file_t _file, int flags);
diff --git a/sys/sys/memrange.h b/sys/sys/memrange.h
index 32ae238..6d6ff0e 100644
--- a/sys/sys/memrange.h
+++ b/sys/sys/memrange.h
@@ -1,5 +1,5 @@
/*
- * Memory range attribute operations, peformed on /dev/mem
+ * Memory range attribute operations, performed on /dev/mem
*
* $FreeBSD$
*/
diff --git a/sys/sys/param.h b/sys/sys/param.h
index a0eede9..6c64074 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 1100106 /* Master, propagated to newvers */
+#define __FreeBSD_version 1100107 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index e559b76..a03e507 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -283,7 +283,7 @@ enum pmc_disp {
__PMC_CAP(THRESHOLD, 4, "ignore events below a threshold") \
__PMC_CAP(READ, 5, "read PMC counter") \
__PMC_CAP(WRITE, 6, "reprogram PMC counter") \
- __PMC_CAP(INVERT, 7, "invert comparision sense") \
+ __PMC_CAP(INVERT, 7, "invert comparison sense") \
__PMC_CAP(QUALIFIER, 8, "further qualify monitored events") \
__PMC_CAP(PRECISE, 9, "perform precise sampling") \
__PMC_CAP(TAGGING, 10, "tag upstream events") \
@@ -587,7 +587,7 @@ struct pmc_op_writelog {
/*
* OP GETMSR
*
- * Retrieve the machine specific address assoicated with the allocated
+ * Retrieve the machine specific address associated with the allocated
* PMC. This number can be used subsequently with a read-performance-counter
* instruction.
*/
diff --git a/sys/sys/priority.h b/sys/sys/priority.h
index 6548a35..a2cd3b7 100644
--- a/sys/sys/priority.h
+++ b/sys/sys/priority.h
@@ -126,7 +126,7 @@
struct priority {
u_char pri_class; /* Scheduling class. */
u_char pri_level; /* Normal priority level. */
- u_char pri_native; /* Priority before propogation. */
+ u_char pri_native; /* Priority before propagation. */
u_char pri_user; /* User priority based on p_cpu and p_nice. */
};
diff --git a/sys/sys/priv.h b/sys/sys/priv.h
index 8f94a3c..86ea05e 100644
--- a/sys/sys/priv.h
+++ b/sys/sys/priv.h
@@ -134,7 +134,7 @@
#define PRIV_JAIL_REMOVE 112 /* Remove a jail. */
/*
- * Kernel environment priveleges.
+ * Kernel environment privileges.
*/
#define PRIV_KENV_SET 120 /* Set kernel env. variables. */
#define PRIV_KENV_UNSET 121 /* Unset kernel env. variables. */
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 16c739e..35303fc 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -426,7 +426,7 @@ do { \
#define TDP_BUFNEED 0x00000008 /* Do not recurse into the buf flush */
#define TDP_COWINPROGRESS 0x00000010 /* Snapshot copy-on-write in progress. */
#define TDP_ALTSTACK 0x00000020 /* Have alternate signal stack. */
-#define TDP_DEADLKTREAT 0x00000040 /* Lock aquisition - deadlock treatment. */
+#define TDP_DEADLKTREAT 0x00000040 /* Lock acquisition - deadlock treatment. */
#define TDP_NOFAULTING 0x00000080 /* Do not handle page faults. */
#define TDP_UNUSED9 0x00000100 /* --available-- */
#define TDP_OWEUPC 0x00000200 /* Call addupc() at next AST. */
diff --git a/sys/sys/procctl.h b/sys/sys/procctl.h
index 75dbf53..c6f1e94 100644
--- a/sys/sys/procctl.h
+++ b/sys/sys/procctl.h
@@ -88,7 +88,7 @@ struct procctl_reaper_kill {
int rk_sig; /* in - signal to send */
u_int rk_flags; /* in - REAPER_KILL flags */
pid_t rk_subtree; /* in - subtree, if REAPER_KILL_SUBTREE */
- u_int rk_killed; /* out - count of processes sucessfully
+ u_int rk_killed; /* out - count of processes successfully
killed */
pid_t rk_fpid; /* out - first failed pid for which error
is returned */
diff --git a/sys/sys/shm.h b/sys/sys/shm.h
index f685df3..455e858 100644
--- a/sys/sys/shm.h
+++ b/sys/sys/shm.h
@@ -56,7 +56,7 @@
#define SHM_LOCK 11
#define SHM_UNLOCK 12
-/* ipcs shmctl commands for Linux compatability */
+/* ipcs shmctl commands for Linux compatibility */
#define SHM_STAT 13
#define SHM_INFO 14
diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
index 73ebf5f..abdf1c3 100644
--- a/sys/sys/sockio.h
+++ b/sys/sys/sockio.h
@@ -98,7 +98,7 @@
#define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set linklevel addr */
#define SIOCGI2C _IOWR('i', 61, struct ifreq) /* get I2C data */
-#define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif addres */
+#define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif address */
#define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr */
#define SIOCGIFPDSTADDR _IOWR('i', 72, struct ifreq) /* get gif pdst addr */
#define SIOCDIFPHYADDR _IOW('i', 73, struct ifreq) /* delete gif addrs */
diff --git a/sys/sys/soundcard.h b/sys/sys/soundcard.h
index 2916287..4867f6c 100644
--- a/sys/sys/soundcard.h
+++ b/sys/sys/soundcard.h
@@ -185,7 +185,7 @@ struct snd_size {
#define AFMT_U24_LE 0x00040000 /* Little endian unsigned 24-bit */
#define AFMT_U24_BE 0x00080000 /* Big endian unsigned 24-bit */
-/* Machine dependant AFMT_* definitions. */
+/* Machine dependent AFMT_* definitions. */
#if BYTE_ORDER == LITTLE_ENDIAN
#define AFMT_S16_NE AFMT_S16_LE
#define AFMT_S24_NE AFMT_S24_LE
@@ -1447,7 +1447,7 @@ void seqbuf_dump(void); /* This function must be provided by programs */
SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2)
/*
- * Timing and syncronization macros
+ * Timing and synchronization macros
*/
#define _TIMER_EVENT(ev, parm) { \
diff --git a/sys/sys/sx.h b/sys/sys/sx.h
index 96a664f..03b51d3 100644
--- a/sys/sys/sx.h
+++ b/sys/sys/sx.h
@@ -308,7 +308,7 @@ __sx_sunlock(struct sx *sx, const char *file, int line)
#define SA_RECURSED LA_RECURSED
#define SA_NOTRECURSED LA_NOTRECURSED
-/* Backwards compatability. */
+/* Backwards compatibility. */
#define SX_LOCKED LA_LOCKED
#define SX_SLOCKED LA_SLOCKED
#define SX_XLOCKED LA_XLOCKED
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index eb5eef0..4590ef9 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -608,7 +608,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
__ptr, 0, sysctl_handle_64, "QU", __DESCR(descr)); \
})
-/* Oid for a CPU dependant variable */
+/* Oid for a CPU dependent variable */
#define SYSCTL_ADD_UAUTO(ctx, parent, nbr, name, access, ptr, descr) \
({ \
struct sysctl_oid *__ret; \
@@ -753,7 +753,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
})
/*
- * A macro to generate a read-only sysctl to indicate the presense of optional
+ * A macro to generate a read-only sysctl to indicate the presence of optional
* kernel features.
*/
#define FEATURE(name, desc) \
diff --git a/sys/sys/timex.h b/sys/sys/timex.h
index 4b75fcc..4fa5735 100644
--- a/sys/sys/timex.h
+++ b/sys/sys/timex.h
@@ -105,7 +105,7 @@
#define TIME_INS 1 /* insert leap second warning */
#define TIME_DEL 2 /* delete leap second warning */
#define TIME_OOP 3 /* leap second in progress */
-#define TIME_WAIT 4 /* leap second has occured */
+#define TIME_WAIT 4 /* leap second has occurred */
#define TIME_ERROR 5 /* error (see status word) */
/*
diff --git a/sys/sys/user.h b/sys/sys/user.h
index fd362c2..6049e80 100644
--- a/sys/sys/user.h
+++ b/sys/sys/user.h
@@ -296,7 +296,7 @@ struct user {
/*
* Old format. Has variable hidden padding due to alignment.
- * This is a compatability hack for pre-build 7.1 packages.
+ * This is a compatibility hack for pre-build 7.1 packages.
*/
#if defined(__amd64__)
#define KINFO_OFILE_SIZE 1328
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index f3ae773..df43134 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -774,6 +774,7 @@ int dead_read(struct vop_read_args *ap);
int dead_write(struct vop_write_args *ap);
/* These are called from within the actual VOPS. */
+void vop_close_post(void *a, int rc);
void vop_create_post(void *a, int rc);
void vop_deleteextattr_post(void *a, int rc);
void vop_link_post(void *a, int rc);
@@ -783,6 +784,9 @@ void vop_lookup_post(void *a, int rc);
void vop_lookup_pre(void *a);
void vop_mkdir_post(void *a, int rc);
void vop_mknod_post(void *a, int rc);
+void vop_open_post(void *a, int rc);
+void vop_read_post(void *a, int rc);
+void vop_readdir_post(void *a, int rc);
void vop_reclaim_post(void *a, int rc);
void vop_remove_post(void *a, int rc);
void vop_rename_post(void *a, int rc);
diff --git a/sys/x86/acpica/srat.c b/sys/x86/acpica/srat.c
index 85f1922..1d0f73d 100644
--- a/sys/x86/acpica/srat.c
+++ b/sys/x86/acpica/srat.c
@@ -201,8 +201,12 @@ srat_parse_entry(ACPI_SUBTABLE_HEADER *entry, void *arg)
"enabled" : "disabled");
if (!(cpu->Flags & ACPI_SRAT_CPU_ENABLED))
break;
- KASSERT(!cpus[cpu->ApicId].enabled,
- ("Duplicate local APIC ID %u", cpu->ApicId));
+ if (cpus[cpu->ApicId].enabled) {
+ printf("SRAT: Duplicate local APIC ID %u\n",
+ cpu->ApicId);
+ *(int *)arg = ENXIO;
+ break;
+ }
cpus[cpu->ApicId].domain = domain;
cpus[cpu->ApicId].enabled = 1;
break;
OpenPOWER on IntegriCloud