summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorngie <ngie@FreeBSD.org>2015-12-14 00:12:53 +0000
committerngie <ngie@FreeBSD.org>2015-12-14 00:12:53 +0000
commit17ca717571c27f52897c406a71864f864ca65710 (patch)
treec78986272e2ab4a955534ea9353928c9ce25caa3
parentc85e616e29482200cd0a47fa6c85165a98a4caaf (diff)
parenta3c1f4b0eb9f220318c79476b1fcf38beadf35da (diff)
downloadFreeBSD-src-17ca717571c27f52897c406a71864f864ca65710.zip
FreeBSD-src-17ca717571c27f52897c406a71864f864ca65710.tar.gz
MFhead @ r292177
-rw-r--r--MAINTAINERS83
-rw-r--r--Makefile2
-rw-r--r--Makefile.inc16
-rw-r--r--UPDATING8
-rw-r--r--contrib/elftoolchain/addr2line/addr2line.127
-rw-r--r--contrib/elftoolchain/addr2line/addr2line.c472
-rw-r--r--contrib/elftoolchain/common/elfdefinitions.h2
-rw-r--r--contrib/elftoolchain/elfcopy/binary.c22
-rw-r--r--contrib/elftoolchain/elfcopy/elfcopy.19
-rw-r--r--contrib/elftoolchain/elfcopy/main.c6
-rw-r--r--contrib/elftoolchain/elfcopy/sections.c16
-rw-r--r--contrib/elftoolchain/elfcopy/segments.c4
-rw-r--r--contrib/elftoolchain/libelf/elf_data.c8
-rw-r--r--contrib/elftoolchain/readelf/readelf.c122
-rw-r--r--contrib/top/loadavg.h4
-rwxr-xr-xcontrib/unbound/freebsd-configure.sh3
-rw-r--r--etc/etc.riscv/ttys51
-rw-r--r--lib/csu/riscv/Makefile46
-rw-r--r--lib/csu/riscv/crt1.c89
-rw-r--r--lib/csu/riscv/crti.S58
-rw-r--r--lib/csu/riscv/crtn.S48
-rw-r--r--lib/libc/gen/exec.34
-rw-r--r--lib/libc/net/getaddrinfo.c5
-rw-r--r--lib/libc/regex/grot/Makefile2
-rw-r--r--lib/libc/riscv/Makefile.inc1
-rw-r--r--lib/libthr/arch/riscv/Makefile.inc1
-rw-r--r--lib/msun/riscv/Makefile.inc6
-rw-r--r--lib/msun/riscv/fenv.h228
-rw-r--r--sbin/geom/class/part/gpart.812
-rw-r--r--share/man/man4/mps.439
-rw-r--r--share/mk/bsd.cpu.mk20
-rw-r--r--share/mk/bsd.endian.mk1
-rw-r--r--share/mk/bsd.opts.mk2
-rw-r--r--share/mk/bsd.sys.mk5
-rw-r--r--share/mk/local.dirdeps.mk5
-rw-r--r--share/mk/local.meta.sys.mk3
-rw-r--r--share/mk/src.opts.mk7
-rw-r--r--share/mk/sys.mk11
-rw-r--r--sys/arm64/arm64/gic.c119
-rw-r--r--sys/arm64/arm64/gic.h2
-rw-r--r--sys/arm64/arm64/gic_fdt.c206
-rw-r--r--sys/arm64/arm64/gic_v3_its.c5
-rw-r--r--sys/arm64/arm64/gic_v3_var.h2
-rw-r--r--sys/arm64/arm64/intr_machdep.c27
-rw-r--r--sys/arm64/arm64/pic_if.m8
-rw-r--r--sys/arm64/cavium/thunder_pcie.c11
-rw-r--r--sys/arm64/cavium/thunder_pcie_common.c48
-rw-r--r--sys/arm64/cavium/thunder_pcie_pem.c11
-rw-r--r--sys/arm64/conf/GENERIC7
-rw-r--r--sys/arm64/include/intr.h12
-rw-r--r--sys/boot/common/part.c7
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c94
-rw-r--r--sys/dev/aic/aic_pccard.c1
-rw-r--r--sys/dev/an/if_an_pccard.c1
-rw-r--r--sys/dev/ata/ata-card.c1
-rw-r--r--sys/dev/bwn/if_bwn.c3
-rw-r--r--sys/dev/cmx/cmx_pccard.c2
-rw-r--r--sys/dev/cs/if_cs_pccard.c2
-rw-r--r--sys/dev/ed/if_ed_isa.c3
-rw-r--r--sys/dev/ed/if_ed_pccard.c1
-rw-r--r--sys/dev/ed/if_ed_pci.c3
-rw-r--r--sys/dev/ep/if_ep_pccard.c1
-rw-r--r--sys/dev/ex/if_ex_pccard.c1
-rw-r--r--sys/dev/fdc/fdc_pccard.c1
-rw-r--r--sys/dev/fdt/simplebus.c6
-rw-r--r--sys/dev/fe/if_fe_pccard.c1
-rw-r--r--sys/dev/hwpmc/hwpmc_core.c151
-rw-r--r--sys/dev/md/md.c40
-rw-r--r--sys/dev/ncv/ncr53c500_pccard.c1
-rw-r--r--sys/dev/nsp/nsp_pccard.c1
-rw-r--r--sys/dev/nvd/nvd.c2
-rw-r--r--sys/dev/nvme/nvme.h1
-rw-r--r--sys/dev/nvme/nvme_ns.c18
-rw-r--r--sys/dev/nvme/nvme_sysctl.c16
-rw-r--r--sys/dev/ofw/ofw_bus_subr.c131
-rw-r--r--sys/dev/ofw/ofw_bus_subr.h9
-rw-r--r--sys/dev/ofw/ofw_iicbus.c2
-rw-r--r--sys/dev/otus/if_otus.c2
-rw-r--r--sys/dev/pccard/pccardvar.h10
-rw-r--r--sys/dev/ral/rt2560.c6
-rw-r--r--sys/dev/ral/rt2661.c2
-rw-r--r--sys/dev/ral/rt2860.c2
-rw-r--r--sys/dev/sfxge/common/efx_impl.h9
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.c186
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.h13
-rw-r--r--sys/dev/sfxge/common/hunt_impl.h31
-rw-r--r--sys/dev/sfxge/common/hunt_mcdi.c178
-rw-r--r--sys/dev/sfxge/common/siena_impl.h21
-rw-r--r--sys/dev/sfxge/common/siena_mcdi.c106
-rw-r--r--sys/dev/sfxge/sfxge.c9
-rw-r--r--sys/dev/sn/if_sn_pccard.c1
-rw-r--r--sys/dev/snc/if_snc_pccard.c1
-rw-r--r--sys/dev/sound/usb/uaudio.c1
-rw-r--r--sys/dev/stg/tmc18c30_pccard.c1
-rw-r--r--sys/dev/uart/uart_bus_pccard.c6
-rw-r--r--sys/dev/usb/input/atp.c2
-rw-r--r--sys/dev/usb/input/uep.c1
-rw-r--r--sys/dev/usb/input/uhid.c1
-rw-r--r--sys/dev/usb/input/ukbd.c1
-rw-r--r--sys/dev/usb/input/ums.c1
-rw-r--r--sys/dev/usb/input/wsp.c1
-rw-r--r--sys/dev/usb/misc/udbp.c19
-rw-r--r--sys/dev/usb/misc/ufm.c9
-rw-r--r--sys/dev/usb/misc/ugold.c9
-rw-r--r--sys/dev/usb/misc/uled.c9
-rw-r--r--sys/dev/usb/net/if_aue.c1
-rw-r--r--sys/dev/usb/net/if_axe.c1
-rw-r--r--sys/dev/usb/net/if_axge.c1
-rw-r--r--sys/dev/usb/net/if_cdce.c33
-rw-r--r--sys/dev/usb/net/if_cue.c1
-rw-r--r--sys/dev/usb/net/if_ipheth.c43
-rw-r--r--sys/dev/usb/net/if_kue.c1
-rw-r--r--sys/dev/usb/net/if_mos.c1
-rw-r--r--sys/dev/usb/net/if_rue.c1
-rw-r--r--sys/dev/usb/net/if_smsc.c1
-rw-r--r--sys/dev/usb/net/if_udav.c31
-rw-r--r--sys/dev/usb/net/if_urndis.c31
-rw-r--r--sys/dev/usb/net/if_usie.c1
-rw-r--r--sys/dev/usb/net/uhso.c1
-rw-r--r--sys/dev/usb/serial/u3g.c11
-rw-r--r--sys/dev/usb/serial/uark.c9
-rw-r--r--sys/dev/usb/serial/ubsa.c1
-rw-r--r--sys/dev/usb/serial/uchcom.c1
-rw-r--r--sys/dev/usb/serial/ucycom.c11
-rw-r--r--sys/dev/usb/serial/ufoma.c11
-rw-r--r--sys/dev/usb/serial/uftdi.c11
-rw-r--r--sys/dev/usb/serial/ugensa.c11
-rw-r--r--sys/dev/usb/serial/uipaq.c1
-rw-r--r--sys/dev/usb/serial/ulpt.c1
-rw-r--r--sys/dev/usb/serial/umcs.c1
-rw-r--r--sys/dev/usb/serial/umct.c1
-rw-r--r--sys/dev/usb/serial/umodem.c2
-rw-r--r--sys/dev/usb/serial/umoscom.c9
-rw-r--r--sys/dev/usb/serial/uplcom.c1
-rw-r--r--sys/dev/usb/serial/uslcom.c1
-rw-r--r--sys/dev/usb/serial/uvisor.c11
-rw-r--r--sys/dev/usb/serial/uvscom.c1
-rw-r--r--sys/dev/usb/storage/umass.c11
-rw-r--r--sys/dev/usb/storage/urio.c9
-rw-r--r--sys/dev/usb/usb_hub.c2
-rw-r--r--sys/dev/usb/usbdi.h69
-rw-r--r--sys/dev/usb/wlan/if_rsu.c1
-rw-r--r--sys/dev/usb/wlan/if_rum.c4
-rw-r--r--sys/dev/usb/wlan/if_run.c3
-rw-r--r--sys/dev/usb/wlan/if_uath.c1
-rw-r--r--sys/dev/usb/wlan/if_upgt.c1
-rw-r--r--sys/dev/usb/wlan/if_ural.c3
-rw-r--r--sys/dev/usb/wlan/if_urtw.c9
-rw-r--r--sys/dev/usb/wlan/if_urtwn.c576
-rw-r--r--sys/dev/usb/wlan/if_urtwnreg.h54
-rw-r--r--sys/dev/usb/wlan/if_urtwnvar.h56
-rw-r--r--sys/dev/usb/wlan/if_zyd.c1
-rw-r--r--sys/dev/wi/if_wi_pccard.c1
-rw-r--r--sys/dev/wpi/if_wpi.c1
-rw-r--r--sys/dev/wpi/if_wpi_debug.h1
-rw-r--r--sys/dev/wtap/if_wtap_module.c1
-rw-r--r--sys/dev/wtap/if_wtapvar.h2
-rw-r--r--sys/dev/wtap/plugins/visibility.c1
-rw-r--r--sys/dev/xe/if_xe_pccard.c1
-rw-r--r--sys/geom/part/g_part_gpt.c31
-rw-r--r--sys/kern/kern_linker.c6
-rw-r--r--sys/kern/kern_malloc.c9
-rw-r--r--sys/kern/kern_racct.c8
-rw-r--r--sys/kern/kern_rctl.c2
-rw-r--r--sys/mips/include/cpuregs.h2
-rw-r--r--sys/net/if_llatbl.c41
-rw-r--r--sys/net/if_llatbl.h4
-rw-r--r--sys/net/route.c3
-rw-r--r--sys/net80211/ieee80211_phy.h4
-rw-r--r--sys/netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c12
-rw-r--r--sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c2
-rw-r--r--sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c14
-rw-r--r--sys/netinet/sctp_input.c29
-rw-r--r--sys/netinet/sctp_output.c7
-rw-r--r--sys/netinet/sctp_pcb.h6
-rw-r--r--sys/netinet/tcp_hostcache.c20
-rw-r--r--sys/netinet/tcp_hostcache.h1
-rw-r--r--sys/netinet/tcp_var.h1
-rw-r--r--sys/netinet6/in6.c13
-rw-r--r--sys/netinet6/nd6.c203
-rw-r--r--sys/netinet6/nd6_nbr.c12
-rw-r--r--sys/powerpc/booke/booke_machdep.c19
-rw-r--r--sys/powerpc/booke/trap_subr.S33
-rw-r--r--sys/powerpc/include/trap.h1
-rw-r--r--sys/powerpc/powerpc/trap.c1
-rw-r--r--sys/sys/module.h49
-rw-r--r--sys/vm/uma_core.c5
-rw-r--r--sys/vm/vm_page.c23
-rw-r--r--tools/bsdbox/Makefile.base2
-rwxr-xr-xtools/tools/nanobsd/defaults.sh2
-rw-r--r--tools/tools/nanobsd/embedded/common13
-rw-r--r--tools/tools/nanobsd/embedded/qemu-powerpc64.cfg2
-rw-r--r--usr.bin/mkimg/mbr.c4
-rw-r--r--usr.bin/mkimg/scheme.c1
-rw-r--r--usr.bin/mkimg/scheme.h1
-rw-r--r--usr.bin/unzip/unzip.16
-rw-r--r--usr.bin/unzip/unzip.c122
-rw-r--r--usr.sbin/crunch/crunchide/exec_elf32.c4
-rw-r--r--usr.sbin/kldxref/kldxref.c347
-rw-r--r--usr.sbin/sesutil/Makefile2
-rw-r--r--usr.sbin/sesutil/eltsub.c75
-rw-r--r--usr.sbin/sesutil/eltsub.h5
-rw-r--r--usr.sbin/sesutil/sesutil.c17
203 files changed, 3966 insertions, 1283 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 62ab287..907e376 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26,57 +26,62 @@ sub-system.
subsystem login notes
-----------------------------
-opencrypto jmg Pre-commit review requested. Documentation Required.
-kqueue jmg Pre-commit review requested. Documentation Required.
-share/mk imp, bapt, bdrewery, emaste, sjg Make is hard.
+atf freebsd-testing,jmmv,ngie Pre-commit review requested.
ath(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
-net80211 adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
-iwn(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
-iwm(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
-otus(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
-dev/usb/wlan adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
-openssl benl,jkim Pre-commit review requested.
-release/release.sh gjb,re Pre-commit review and regression tests
- requested.
-sh(1) jilles Pre-commit review requested. This also applies
- to kill(1), printf(1) and test(1) which are
- compiled in as builtins.
-isci(4) jimharris Pre-commit review requested.
-nvme(4) jimharris Pre-commit review requested.
-nvd(4) jimharris Pre-commit review requested.
-nvmecontrol(8) jimharris Pre-commit review requested.
-libfetch des Pre-commit review requested.
-fetch des Pre-commit review requested.
-libpam des Pre-commit review requested.
-openssh des Pre-commit review requested.
-pseudofs des Pre-commit review requested.
-procfs des Pre-commit review requested.
-linprocfs des Pre-commit review requested.
+callout_*(9) rrs Pre-commit review requested -- becareful its tricksy code :o.
contrib/compiler-rt dim Pre-commit review preferred.
contrib/libc++ dim Pre-commit review preferred.
contrib/libcxxrt dim Pre-commit review preferred.
contrib/llvm dim Pre-commit review preferred.
contrib/llvm/tools/lldb emaste Pre-commit review preferred.
-atf freebsd-testing,jmmv,ngie Pre-commit review requested.
contrib/netbsd-tests freebsd-testing,ngie Pre-commit review requested.
contrib/pjdfstest freebsd-testing,ngie,pjd Pre-commit review requested.
+dev/usb/wlan adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
+etc/mail gshapiro Pre-commit review requested. Keep in sync with -STABLE.
+etc/sendmail gshapiro Pre-commit review requested. Keep in sync with -STABLE.
+fetch des Pre-commit review requested.
+isci(4) jimharris Pre-commit review requested.
+iwm(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
+iwn(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
+kqueue jmg Pre-commit review requested. Documentation Required.
+libfetch des Pre-commit review requested.
+libpam des Pre-commit review requested.
+linprocfs des Pre-commit review requested.
+lpr gad Pre-commit review requested, particularly for
+ lpd/recvjob.c and lpd/printjob.c.
+nanobsd imp Pre-commit phabricator review requested.
+net80211 adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
+nis(8), yp(8) araujo Pre-commit review requested.
+nvd(4) jimharris Pre-commit review requested.
+nvme(4) jimharris Pre-commit review requested.
+nvmecontrol(8) jimharris Pre-commit review requested.
+opencrypto jmg Pre-commit review requested. Documentation Required.
+openssh des Pre-commit review requested.
+openssl benl,jkim Pre-commit review requested.
+otus(4) adrian Pre-commit review requested, send to freebsd-wireless@freebsd.org
+pmcstudy(8) rrs Pre-commit review requested.
+procfs des Pre-commit review requested.
+pseudofs des Pre-commit review requested.
+release/release.sh gjb,re Pre-commit review and regression tests
+ requested.
+sctp rrs,tuexen Pre-commit review requested (changes need to be backported to github).
+sendmail gshapiro Pre-commit review requested.
+sh(1) jilles Pre-commit review requested. This also applies
+ to kill(1), printf(1) and test(1) which are
+ compiled in as builtins.
+share/mk imp, bapt, bdrewery, emaste, sjg Make is hard.
share/mk/*.test.mk freebsd-testing,ngie (same list as share/mk too) Pre-commit review requested.
-tests freebsd-testing,ngie Pre-commit review requested.
-sys/dev/usb hselasky If in doubt, ask.
-sys/dev/sound/usb hselasky If in doubt, ask.
sys/compat/linuxkpi hselasky If in doubt, ask.
sys/dev/e1000 erj Pre-commit phabricator review requested.
sys/dev/ixgbe erj Pre-commit phabricator review requested.
sys/dev/ixl erj Pre-commit phabricator review requested.
+sys/dev/sound/usb hselasky If in doubt, ask.
+sys/dev/usb hselasky If in doubt, ask.
sys/netinet/ip_carp.c glebius Pre-commit review recommended.
sys/netpfil/pf kp,glebius Pre-commit review recommended.
-sctp rrs,tuexen Pre-commit review requested (changes need to be backported to github).
-pmcstudy(8) rrs Pre-commit review requested.
-callout_*(9) rrs Pre-commit review requested -- becareful its tricksy code :o.
+tests freebsd-testing,ngie Pre-commit review requested.
usr.sbin/pkg pkg@ Please coordinate behavior or flag changes with pkg team.
-lpr gad Pre-commit review requested, particularly for
- lpd/recvjob.c and lpd/printjob.c.
-nis(8), yp(8) araujo Pre-commit review requested.
+vmm(4) neel,grehan Pre-commit review requested.
---- OLD ----
libc/posix1e rwatson Pre-commit review requested.
POSIX.1e ACLs rwatson Pre-commit review requested.
@@ -102,11 +107,6 @@ cd(4) ken Pre-commit review requested.
pass(4) ken Pre-commit review requested.
ch(4) ken Pre-commit review requested.
em(4) jfv Pre-commit review requested.
-sendmail gshapiro Pre-commit review requested.
-etc/mail gshapiro Pre-commit review requested.
- Keep in sync with -STABLE.
-etc/sendmail gshapiro Pre-commit review requested.
- Keep in sync with -STABLE.
nvi peter Try not to break it.
libz peter Try not to break it.
groff ru Recommends pre-commit review.
@@ -155,5 +155,4 @@ sbin/routed bms Pre-commit review; notify vendor at rhyolite.com
cmx daniel@roe.ch Pre-commit review preferred.
filemon obrien Pre-commit review preferred.
sysdoc trhodes Pre-commit review preferred.
-nanobsd imp Pre-commit review requested for coordination.
-vmm(4) neel,grehan Pre-commit review requested.
+
diff --git a/Makefile b/Makefile
index 7fb9de8..25d8568 100644
--- a/Makefile
+++ b/Makefile
@@ -180,7 +180,7 @@ _MAKE= PATH=${PATH} ${SUB_MAKE} -f Makefile.inc1 TARGET=${_TARGET} TARGET_ARCH=$
_TARGET_ARCH= ${TARGET:S/pc98/i386/:S/arm64/aarch64/}
.elif !defined(TARGET) && defined(TARGET_ARCH) && \
${TARGET_ARCH} != ${MACHINE_ARCH}
-_TARGET= ${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/}
+_TARGET= ${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/riscv64/riscv/}
.endif
.if defined(TARGET) && !defined(_TARGET)
_TARGET=${TARGET}
diff --git a/Makefile.inc1 b/Makefile.inc1
index 645167b..11fc0b9 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -172,7 +172,11 @@ VERSION= FreeBSD ${REVISION}-${BRANCH:C/-p[0-9]+$//} ${TARGET_ARCH} ${SRCRELDATE
.export VERSION
.endif
-KNOWN_ARCHES?= aarch64/arm64 amd64 arm armeb/arm armv6/arm armv6hf/arm i386 i386/pc98 mips mipsel/mips mips64el/mips mips64/mips mipsn32el/mips mipsn32/mips powerpc powerpc64/powerpc sparc64
+KNOWN_ARCHES?= aarch64/arm64 amd64 arm armeb/arm armv6/arm armv6hf/arm \
+ i386 i386/pc98 mips mipsel/mips mips64el/mips mips64/mips \
+ mipsn32el/mips mipsn32/mips powerpc powerpc64/powerpc \
+ riscv64/riscv sparc64
+
.if ${TARGET} == ${TARGET_ARCH}
_t= ${TARGET}
.else
diff --git a/UPDATING b/UPDATING
index 2775c22..b020439 100644
--- a/UPDATING
+++ b/UPDATING
@@ -31,6 +31,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20151211:
+ The code to start recording plug and play data into the modules has
+ been committed. While the old tools will properly build a new kernel,
+ a number of warnings about "unknown metadata record 4" will be produced
+ for an older kldxref. To avoid such warnings, make sure to rebuild
+ the kernel toolchain (or world). Make sure that you have r292078 or
+ later when trying to build 292077 or later before rebuilding.
+
20151207:
Debug data files are now built by default with 'make buildworld' and
installed with 'make installworld'. This facilitates debugging but
diff --git a/contrib/elftoolchain/addr2line/addr2line.1 b/contrib/elftoolchain/addr2line/addr2line.1
index f000c29..15c24ac 100644
--- a/contrib/elftoolchain/addr2line/addr2line.1
+++ b/contrib/elftoolchain/addr2line/addr2line.1
@@ -22,9 +22,9 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $Id: addr2line.1 3195 2015-05-12 17:22:19Z emaste $
+.\" $Id: addr2line.1 3263 2015-11-30 04:25:54Z kaiwang27 $
.\"
-.Dd July 25, 2010
+.Dd November 30, 2015
.Os
.Dt ADDR2LINE 1
.Sh NAME
@@ -32,10 +32,13 @@
.Nd translate program addresses to source file names and line numbers
.Sh SYNOPSIS
.Nm
+.Op Fl a | Fl -addresses
.Op Fl b Ar target | Fl -target Ns = Ns Ar target
.Op Fl e Ar pathname | Fl -exe Ns = Ns Ar pathname
.Op Fl f | Fl -functions
+.Op Fl i | Fl -inlines
.Op Fl j Ar sectionname | Fl -section Ns = Ns Ar sectionname
+.Op Fl p | Fl -pretty-print
.Op Fl s | Fl -basename
.Op Fl C | Fl -demangle
.Op Fl H | Fl -help
@@ -69,6 +72,8 @@ The
.Nm
utility recognizes the following options:
.Bl -tag -width indent
+.It Fl a | Fl -addresses
+Display the address prior to the line number information.
.It Fl b Ar target | Fl -target Ns = Ns Ar target
This option is recognized by
.Nm
@@ -84,11 +89,17 @@ will use the file
.Dq Pa a.out .
.It Fl f | Fl -functions
Display function names in addition to file and line number information.
+.It Fl i | Fl -inlines
+If the address specified belongs to an inlined function, also display the line
+number information for its caller, recursively until the first non-inlined
+caller.
.It Fl j Ar sectionname | Fl -section Ns = Ns Ar sectionname
The values specified by arguments
.Ar hexaddress
are to be treated as offsets into the section named
.Ar sectionname .
+.It Fl p | -pretty-print
+Display the line number information on one line, in human readable manner.
.It Fl s | -basename
Display only the base name for each file name.
.It Fl C | Fl -demangle
@@ -115,6 +126,18 @@ to program address
.Ar hexaddress ,
followed by a line with the file name and line number.
.Pp
+If the
+.Fl p
+option was specified,
+.Nm
+will print line number information and function name on one line in
+human readable manner. If the
+.Fl i
+option was also specified,
+.Nm
+will print the caller function information prefixed with
+.Dq (inlined by) .
+.Pp
The
.Nm
utility prints the file name and line number using the format
diff --git a/contrib/elftoolchain/addr2line/addr2line.c b/contrib/elftoolchain/addr2line/addr2line.c
index 28ae12e..5310576 100644
--- a/contrib/elftoolchain/addr2line/addr2line.c
+++ b/contrib/elftoolchain/addr2line/addr2line.c
@@ -37,33 +37,64 @@
#include <stdlib.h>
#include <string.h>
+#include "uthash.h"
#include "_elftc.h"
-ELFTC_VCSID("$Id: addr2line.c 3249 2015-10-04 08:11:30Z kaiwang27 $");
+ELFTC_VCSID("$Id: addr2line.c 3264 2015-11-30 05:38:14Z kaiwang27 $");
+
+struct Func {
+ char *name;
+ Dwarf_Unsigned lopc;
+ Dwarf_Unsigned hipc;
+ Dwarf_Unsigned call_file;
+ Dwarf_Unsigned call_line;
+ Dwarf_Ranges *ranges;
+ Dwarf_Signed ranges_cnt;
+ struct Func *inlined_caller;
+ STAILQ_ENTRY(Func) next;
+};
+
+struct CU {
+ Dwarf_Off off;
+ Dwarf_Unsigned lopc;
+ Dwarf_Unsigned hipc;
+ char **srcfiles;
+ Dwarf_Signed nsrcfiles;
+ STAILQ_HEAD(, Func) funclist;
+ UT_hash_handle hh;
+};
static struct option longopts[] = {
+ {"addresses", no_argument, NULL, 'a'},
{"target" , required_argument, NULL, 'b'},
{"demangle", no_argument, NULL, 'C'},
{"exe", required_argument, NULL, 'e'},
{"functions", no_argument, NULL, 'f'},
+ {"inlines", no_argument, NULL, 'i'},
{"section", required_argument, NULL, 'j'},
+ {"pretty-print", no_argument, NULL, 'p'},
{"basename", no_argument, NULL, 's'},
{"help", no_argument, NULL, 'H'},
{"version", no_argument, NULL, 'V'},
{NULL, 0, NULL, 0}
};
-static int demangle, func, base;
+static int demangle, func, base, inlines, print_addr, pretty_print;
static char unknown[] = { '?', '?', '\0' };
static Dwarf_Addr section_base;
+static struct CU *culist;
#define USAGE_MESSAGE "\
Usage: %s [options] hexaddress...\n\
Map program addresses to source file names and line numbers.\n\n\
Options:\n\
+ -a | --addresses Display address prior to line number info.\n\
-b TGT | --target=TGT (Accepted but ignored).\n\
-e EXE | --exe=EXE Use program \"EXE\" to translate addresses.\n\
-f | --functions Display function names.\n\
+ -i | --inlines Display caller info for inlined functions.\n\
-j NAME | --section=NAME Values are offsets into section \"NAME\".\n\
+ -p | --pretty-print Display line number info and function name\n\
+ in human readable manner.\n\
-s | --basename Only show the base name for each file name.\n\
-C | --demangle Demangle C++ names.\n\
-H | --help Print a help message.\n\
@@ -122,71 +153,160 @@ handle_high_pc(Dwarf_Die die, Dwarf_Unsigned lopc, Dwarf_Unsigned *hipc)
return (DW_DLV_OK);
}
+static struct Func *
+search_func(struct CU *cu, Dwarf_Unsigned addr)
+{
+ struct Func *f, *f0;
+ Dwarf_Unsigned lopc, hipc, addr_base;
+ int i;
+
+ f0 = NULL;
+
+ STAILQ_FOREACH(f, &cu->funclist, next) {
+ if (f->ranges != NULL) {
+ addr_base = 0;
+ for (i = 0; i < f->ranges_cnt; i++) {
+ if (f->ranges[i].dwr_type == DW_RANGES_END)
+ break;
+ if (f->ranges[i].dwr_type ==
+ DW_RANGES_ADDRESS_SELECTION) {
+ addr_base = f->ranges[i].dwr_addr2;
+ continue;
+ }
+
+ /* DW_RANGES_ENTRY */
+ lopc = f->ranges[i].dwr_addr1 + addr_base;
+ hipc = f->ranges[i].dwr_addr2 + addr_base;
+ if (addr >= lopc && addr < hipc) {
+ if (f0 == NULL ||
+ (lopc >= f0->lopc &&
+ hipc <= f0->hipc)) {
+ f0 = f;
+ f0->lopc = lopc;
+ f0->hipc = hipc;
+ break;
+ }
+ }
+ }
+ } else if (addr >= f->lopc && addr < f->hipc) {
+ if (f0 == NULL ||
+ (f->lopc >= f0->lopc && f->hipc <= f0->hipc))
+ f0 = f;
+ }
+ }
+
+ return (f0);
+}
+
static void
-search_func(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr addr, char **rlt_func)
+collect_func(Dwarf_Debug dbg, Dwarf_Die die, struct Func *parent, struct CU *cu)
{
- Dwarf_Die ret_die, spec_die;
+ Dwarf_Die ret_die, abst_die, spec_die;
Dwarf_Error de;
Dwarf_Half tag;
- Dwarf_Unsigned lopc, hipc;
+ Dwarf_Unsigned lopc, hipc, ranges_off;
+ Dwarf_Signed ranges_cnt;
Dwarf_Off ref;
- Dwarf_Attribute sub_at, spec_at;
- char *func0;
- const char *func1;
- int ret;
+ Dwarf_Attribute abst_at, spec_at;
+ Dwarf_Ranges *ranges;
+ const char *funcname;
+ struct Func *f;
+ int found_ranges, ret;
- if (*rlt_func != NULL)
- goto done;
+ f = NULL;
+ abst_die = spec_die = NULL;
if (dwarf_tag(die, &tag, &de)) {
warnx("dwarf_tag: %s", dwarf_errmsg(de));
goto cont_search;
}
- if (tag == DW_TAG_subprogram) {
+ if (tag == DW_TAG_subprogram || tag == DW_TAG_entry_point ||
+ tag == DW_TAG_inlined_subroutine) {
+ /*
+ * Function address range can be specified by either
+ * a DW_AT_ranges attribute which points to a range list or
+ * by a pair of DW_AT_low_pc and DW_AT_high_pc attributes.
+ */
+ ranges = NULL;
+ ranges_cnt = 0;
+ found_ranges = 0;
+ if (dwarf_attrval_unsigned(die, DW_AT_ranges, &ranges_off,
+ &de) == DW_DLV_OK &&
+ dwarf_get_ranges(dbg, (Dwarf_Off) ranges_off, &ranges,
+ &ranges_cnt, NULL, &de) == DW_DLV_OK) {
+ if (ranges != NULL && ranges_cnt > 0) {
+ found_ranges = 1;
+ goto get_func_name;
+ }
+ }
+
+ /*
+ * Search for DW_AT_low_pc/DW_AT_high_pc if ranges pointer
+ * not found.
+ */
if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) ||
dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, &de))
goto cont_search;
if (handle_high_pc(die, lopc, &hipc) != DW_DLV_OK)
goto cont_search;
- if (addr < lopc || addr >= hipc)
- goto cont_search;
- /* Found it! */
+ get_func_name:
+ /*
+ * Most common case the function name is stored in DW_AT_name
+ * attribute.
+ */
+ if (dwarf_attrval_string(die, DW_AT_name, &funcname, &de) ==
+ DW_DLV_OK)
+ goto add_func;
- if ((*rlt_func = strdup(unknown)) == NULL)
- err(EXIT_FAILURE, "strdup");
- ret = dwarf_attr(die, DW_AT_name, &sub_at, &de);
- if (ret == DW_DLV_ERROR)
- goto done;
- if (ret == DW_DLV_OK) {
- if (dwarf_formstring(sub_at, &func0, &de) ==
- DW_DLV_OK) {
- free(*rlt_func);
- if ((*rlt_func = strdup(func0)) == NULL)
- err(EXIT_FAILURE, "strdup");
- }
- goto done;
- }
+ /*
+ * For inlined function, the actual name is probably in the DIE
+ * referenced by DW_AT_abstract_origin. (if present)
+ */
+ if (dwarf_attr(die, DW_AT_abstract_origin, &abst_at, &de) ==
+ DW_DLV_OK &&
+ dwarf_global_formref(abst_at, &ref, &de) == DW_DLV_OK &&
+ dwarf_offdie(dbg, ref, &abst_die, &de) == DW_DLV_OK &&
+ dwarf_attrval_string(abst_die, DW_AT_name, &funcname,
+ &de) == DW_DLV_OK)
+ goto add_func;
/*
* If DW_AT_name is not present, but DW_AT_specification is
* present, then probably the actual name is in the DIE
* referenced by DW_AT_specification.
*/
- if (dwarf_attr(die, DW_AT_specification, &spec_at, &de))
- goto done;
- if (dwarf_global_formref(spec_at, &ref, &de))
- goto done;
- if (dwarf_offdie(dbg, ref, &spec_die, &de))
- goto done;
- if (dwarf_attrval_string(spec_die, DW_AT_name, &func1, &de) ==
- DW_DLV_OK) {
- free(*rlt_func);
- if ((*rlt_func = strdup(func1)) == NULL)
- err(EXIT_FAILURE, "strdup");
- }
+ if (dwarf_attr(die, DW_AT_specification, &spec_at, &de) ==
+ DW_DLV_OK &&
+ dwarf_global_formref(spec_at, &ref, &de) == DW_DLV_OK &&
+ dwarf_offdie(dbg, ref, &spec_die, &de) == DW_DLV_OK &&
+ dwarf_attrval_string(spec_die, DW_AT_name, &funcname,
+ &de) == DW_DLV_OK)
+ goto add_func;
+
+ /* Skip if no name assoicated with this DIE. */
+ goto cont_search;
- goto done;
+ add_func:
+ if ((f = calloc(1, sizeof(*f))) == NULL)
+ err(EXIT_FAILURE, "calloc");
+ if ((f->name = strdup(funcname)) == NULL)
+ err(EXIT_FAILURE, "strdup");
+ if (found_ranges) {
+ f->ranges = ranges;
+ f->ranges_cnt = ranges_cnt;
+ } else {
+ f->lopc = lopc;
+ f->hipc = hipc;
+ }
+ if (tag == DW_TAG_inlined_subroutine) {
+ f->inlined_caller = parent;
+ dwarf_attrval_unsigned(die, DW_AT_call_file,
+ &f->call_file, &de);
+ dwarf_attrval_unsigned(die, DW_AT_call_line,
+ &f->call_line, &de);
+ }
+ STAILQ_INSERT_TAIL(&cu->funclist, f, next);
}
cont_search:
@@ -194,23 +314,69 @@ cont_search:
/* Search children. */
ret = dwarf_child(die, &ret_die, &de);
if (ret == DW_DLV_ERROR)
- errx(EXIT_FAILURE, "dwarf_child: %s", dwarf_errmsg(de));
- else if (ret == DW_DLV_OK)
- search_func(dbg, ret_die, addr, rlt_func);
+ warnx("dwarf_child: %s", dwarf_errmsg(de));
+ else if (ret == DW_DLV_OK) {
+ if (f != NULL)
+ collect_func(dbg, ret_die, f, cu);
+ else
+ collect_func(dbg, ret_die, parent, cu);
+ }
/* Search sibling. */
ret = dwarf_siblingof(dbg, die, &ret_die, &de);
if (ret == DW_DLV_ERROR)
- errx(EXIT_FAILURE, "dwarf_siblingof: %s", dwarf_errmsg(de));
+ warnx("dwarf_siblingof: %s", dwarf_errmsg(de));
else if (ret == DW_DLV_OK)
- search_func(dbg, ret_die, addr, rlt_func);
+ collect_func(dbg, ret_die, parent, cu);
-done:
+ /* Cleanup */
dwarf_dealloc(dbg, die, DW_DLA_DIE);
+
+ if (abst_die != NULL)
+ dwarf_dealloc(dbg, abst_die, DW_DLA_DIE);
+
+ if (spec_die != NULL)
+ dwarf_dealloc(dbg, spec_die, DW_DLA_DIE);
+}
+
+static void
+print_inlines(struct CU *cu, struct Func *f, Dwarf_Unsigned call_file,
+ Dwarf_Unsigned call_line)
+{
+ char demangled[1024];
+ char *file;
+
+ if (call_file > 0 && (Dwarf_Signed) call_file <= cu->nsrcfiles)
+ file = cu->srcfiles[call_file - 1];
+ else
+ file = unknown;
+
+ if (pretty_print)
+ printf(" (inlined by) ");
+
+ if (func) {
+ if (demangle && !elftc_demangle(f->name, demangled,
+ sizeof(demangled), 0)) {
+ if (pretty_print)
+ printf("%s at ", demangled);
+ else
+ printf("%s\n", demangled);
+ } else {
+ if (pretty_print)
+ printf("%s at ", f->name);
+ else
+ printf("%s\n", f->name);
+ }
+ }
+ (void) printf("%s:%ju\n", base ? basename(file) : file, call_line);
+
+ if (f->inlined_caller != NULL)
+ print_inlines(cu, f->inlined_caller, f->call_file,
+ f->call_line);
}
static void
-translate(Dwarf_Debug dbg, const char* addrstr)
+translate(Dwarf_Debug dbg, Elf *e, const char* addrstr)
{
Dwarf_Die die, ret_die;
Dwarf_Line *lbuf;
@@ -219,18 +385,20 @@ translate(Dwarf_Debug dbg, const char* addrstr)
Dwarf_Unsigned lopc, hipc, addr, lineno, plineno;
Dwarf_Signed lcount;
Dwarf_Addr lineaddr, plineaddr;
- char *funcname;
+ Dwarf_Off off;
+ struct CU *cu;
+ struct Func *f;
+ const char *funcname;
char *file, *file0, *pfile;
char demangled[1024];
- int i, ret;
+ int ec, i, ret;
addr = strtoull(addrstr, NULL, 16);
addr += section_base;
lineno = 0;
file = unknown;
+ cu = NULL;
die = NULL;
- lbuf = NULL;
- lcount = 0;
while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL,
&de)) == DW_DLV_OK) {
@@ -253,59 +421,46 @@ translate(Dwarf_Debug dbg, const char* addrstr)
warnx("could not find DW_TAG_compile_unit die");
goto next_cu;
}
- if (!dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) &&
- !dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, &de)) {
+ if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) ==
+ DW_DLV_OK) {
+ if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc,
+ &de) == DW_DLV_OK) {
+ /*
+ * Check if the address falls into the PC
+ * range of this CU.
+ */
+ if (handle_high_pc(die, lopc, &hipc) !=
+ DW_DLV_OK)
+ goto out;
+ } else {
+ /* Assume ~0ULL if DW_AT_high_pc not present */
+ hipc = ~0ULL;
+ }
+
/*
- * Check if the address falls into the PC range of
- * this CU.
+ * Record the CU in the hash table for faster lookup
+ * later.
*/
- if (handle_high_pc(die, lopc, &hipc) != DW_DLV_OK)
- goto next_cu;
- if (addr < lopc || addr >= hipc)
- goto next_cu;
- }
-
- switch (dwarf_srclines(die, &lbuf, &lcount, &de)) {
- case DW_DLV_OK:
- break;
- case DW_DLV_NO_ENTRY:
- /* If a CU lacks debug info, just skip it. */
- goto next_cu;
- default:
- warnx("dwarf_srclines: %s", dwarf_errmsg(de));
- goto out;
- }
-
- plineaddr = ~0ULL;
- plineno = 0;
- pfile = unknown;
- for (i = 0; i < lcount; i++) {
- if (dwarf_lineaddr(lbuf[i], &lineaddr, &de)) {
- warnx("dwarf_lineaddr: %s",
- dwarf_errmsg(de));
- goto out;
- }
- if (dwarf_lineno(lbuf[i], &lineno, &de)) {
- warnx("dwarf_lineno: %s",
+ if (dwarf_dieoffset(die, &off, &de) != DW_DLV_OK) {
+ warnx("dwarf_dieoffset failed: %s",
dwarf_errmsg(de));
goto out;
}
- if (dwarf_linesrc(lbuf[i], &file0, &de)) {
- warnx("dwarf_linesrc: %s",
- dwarf_errmsg(de));
- } else
- file = file0;
- if (addr == lineaddr)
- goto out;
- else if (addr < lineaddr && addr > plineaddr) {
- lineno = plineno;
- file = pfile;
- goto out;
+ HASH_FIND(hh, culist, &off, sizeof(off), cu);
+ if (cu == NULL) {
+ if ((cu = calloc(1, sizeof(*cu))) == NULL)
+ err(EXIT_FAILURE, "calloc");
+ cu->off = off;
+ cu->lopc = lopc;
+ cu->hipc = hipc;
+ STAILQ_INIT(&cu->funclist);
+ HASH_ADD(hh, culist, off, sizeof(off), cu);
}
- plineaddr = lineaddr;
- plineno = lineno;
- pfile = file;
+
+ if (addr >= lopc && addr < hipc)
+ break;
}
+
next_cu:
if (die != NULL) {
dwarf_dealloc(dbg, die, DW_DLA_DIE);
@@ -313,27 +468,107 @@ translate(Dwarf_Debug dbg, const char* addrstr)
}
}
+ if (ret != DW_DLV_OK || die == NULL)
+ goto out;
+
+ switch (dwarf_srclines(die, &lbuf, &lcount, &de)) {
+ case DW_DLV_OK:
+ break;
+ case DW_DLV_NO_ENTRY:
+ /* If a CU lacks debug info, just skip it. */
+ goto out;
+ default:
+ warnx("dwarf_srclines: %s", dwarf_errmsg(de));
+ goto out;
+ }
+
+ plineaddr = ~0ULL;
+ plineno = 0;
+ pfile = unknown;
+ for (i = 0; i < lcount; i++) {
+ if (dwarf_lineaddr(lbuf[i], &lineaddr, &de)) {
+ warnx("dwarf_lineaddr: %s", dwarf_errmsg(de));
+ goto out;
+ }
+ if (dwarf_lineno(lbuf[i], &lineno, &de)) {
+ warnx("dwarf_lineno: %s", dwarf_errmsg(de));
+ goto out;
+ }
+ if (dwarf_linesrc(lbuf[i], &file0, &de)) {
+ warnx("dwarf_linesrc: %s", dwarf_errmsg(de));
+ } else
+ file = file0;
+ if (addr == lineaddr)
+ goto out;
+ else if (addr < lineaddr && addr > plineaddr) {
+ lineno = plineno;
+ file = pfile;
+ goto out;
+ }
+ plineaddr = lineaddr;
+ plineno = lineno;
+ pfile = file;
+ }
+
out:
+ f = NULL;
funcname = NULL;
- if (ret == DW_DLV_OK && func) {
- search_func(dbg, die, addr, &funcname);
- die = NULL;
+ if (ret == DW_DLV_OK && (func || inlines) && cu != NULL) {
+ if (cu->srcfiles == NULL)
+ if (dwarf_srcfiles(die, &cu->srcfiles, &cu->nsrcfiles,
+ &de))
+ warnx("dwarf_srcfiles: %s", dwarf_errmsg(de));
+ if (STAILQ_EMPTY(&cu->funclist)) {
+ collect_func(dbg, die, NULL, cu);
+ die = NULL;
+ }
+ f = search_func(cu, addr);
+ if (f != NULL)
+ funcname = f->name;
+ }
+
+ if (print_addr) {
+ if ((ec = gelf_getclass(e)) == ELFCLASSNONE) {
+ warnx("gelf_getclass failed: %s", elf_errmsg(-1));
+ ec = ELFCLASS64;
+ }
+ if (ec == ELFCLASS32) {
+ if (pretty_print)
+ printf("0x%08jx: ", (uintmax_t) addr);
+ else
+ printf("0x%08jx\n", (uintmax_t) addr);
+ } else {
+ if (pretty_print)
+ printf("0x%016jx: ", (uintmax_t) addr);
+ else
+ printf("0x%016jx\n", (uintmax_t) addr);
+ }
}
if (func) {
if (funcname == NULL)
- if ((funcname = strdup(unknown)) == NULL)
- err(EXIT_FAILURE, "strdup");
- if (demangle &&
- !elftc_demangle(funcname, demangled, sizeof(demangled), 0))
- printf("%s\n", demangled);
- else
- printf("%s\n", funcname);
- free(funcname);
+ funcname = unknown;
+ if (demangle && !elftc_demangle(funcname, demangled,
+ sizeof(demangled), 0)) {
+ if (pretty_print)
+ printf("%s at ", demangled);
+ else
+ printf("%s\n", demangled);
+ } else {
+ if (pretty_print)
+ printf("%s at ", funcname);
+ else
+ printf("%s\n", funcname);
+ }
}
(void) printf("%s:%ju\n", base ? basename(file) : file, lineno);
+ if (ret == DW_DLV_OK && inlines && cu != NULL &&
+ cu->srcfiles != NULL && f != NULL && f->inlined_caller != NULL)
+ print_inlines(cu, f->inlined_caller, f->call_file,
+ f->call_line);
+
if (die != NULL)
dwarf_dealloc(dbg, die, DW_DLA_DIE);
@@ -421,9 +656,12 @@ main(int argc, char **argv)
exe = NULL;
section = NULL;
- while ((opt = getopt_long(argc, argv, "b:Ce:fj:sHV", longopts, NULL)) !=
- -1) {
+ while ((opt = getopt_long(argc, argv, "ab:Ce:fij:psHV", longopts,
+ NULL)) != -1) {
switch (opt) {
+ case 'a':
+ print_addr = 1;
+ break;
case 'b':
/* ignored */
break;
@@ -436,9 +674,15 @@ main(int argc, char **argv)
case 'f':
func = 1;
break;
+ case 'i':
+ inlines = 1;
+ break;
case 'j':
section = optarg;
break;
+ case 'p':
+ pretty_print = 1;
+ break;
case 's':
base = 1;
break;
@@ -473,10 +717,10 @@ main(int argc, char **argv)
if (argc > 0)
for (i = 0; i < argc; i++)
- translate(dbg, argv[i]);
+ translate(dbg, e, argv[i]);
else
while (fgets(line, sizeof(line), stdin) != NULL) {
- translate(dbg, line);
+ translate(dbg, e, line);
fflush(stdout);
}
diff --git a/contrib/elftoolchain/common/elfdefinitions.h b/contrib/elftoolchain/common/elfdefinitions.h
index 6c9a114..e953c92 100644
--- a/contrib/elftoolchain/common/elfdefinitions.h
+++ b/contrib/elftoolchain/common/elfdefinitions.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: elfdefinitions.h 3247 2015-09-22 16:57:51Z emaste $
+ * $Id: elfdefinitions.h 3253 2015-10-10 18:31:33Z kaiwang27 $
*/
/*
diff --git a/contrib/elftoolchain/elfcopy/binary.c b/contrib/elftoolchain/elfcopy/binary.c
index 6213623..7c834a9 100644
--- a/contrib/elftoolchain/elfcopy/binary.c
+++ b/contrib/elftoolchain/elfcopy/binary.c
@@ -35,17 +35,7 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: binary.c 3174 2015-03-27 17:13:41Z emaste $");
-
-static int
-basename_length(const char *filename)
-{
- char *p;
-
- if ((p = strchr(filename, '.')) != NULL)
- return (p - filename);
- return (strlen(filename));
-}
+ELFTC_VCSID("$Id: binary.c 3270 2015-12-11 18:48:56Z emaste $");
/*
* Convert ELF object to `binary'. Sections with SHF_ALLOC flag set
@@ -150,6 +140,7 @@ create_elf_from_binary(struct elfcopy *ecp, int ifd, const char *ifn)
GElf_Shdr sh;
void *content;
uint64_t off, data_start, data_end, data_size;
+ char *sym_basename, *p;
/* Reset internal section list. */
if (!TAILQ_EMPTY(&ecp->v_sec))
@@ -220,9 +211,13 @@ create_elf_from_binary(struct elfcopy *ecp, int ifd, const char *ifn)
/* Count in .symtab and .strtab section headers. */
shtab->sz += gelf_fsize(ecp->eout, ELF_T_SHDR, 2, EV_CURRENT);
+ if ((sym_basename = strdup(ifn)) == NULL)
+ err(1, "strdup");
+ p = sym_basename;
+ while ((p = strchr(p, '.')) != NULL)
+ *p++ = '_';
#define _GEN_SYMNAME(S) do { \
- snprintf(name, sizeof(name), "%s%.*s%s", "_binary_", \
- basename_length(ifn), ifn, S); \
+ snprintf(name, sizeof(name), "%s%s%s", "_binary_", sym_basename, S); \
} while (0)
/*
@@ -244,6 +239,7 @@ create_elf_from_binary(struct elfcopy *ecp, int ifd, const char *ifn)
finalize_external_symtab(ecp);
create_symtab_data(ecp);
#undef _GEN_SYMNAME
+ free(sym_basename);
/*
* Write the underlying ehdr. Note that it should be called
diff --git a/contrib/elftoolchain/elfcopy/elfcopy.1 b/contrib/elftoolchain/elfcopy/elfcopy.1
index 4889570..83cda5d 100644
--- a/contrib/elftoolchain/elfcopy/elfcopy.1
+++ b/contrib/elftoolchain/elfcopy/elfcopy.1
@@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: elfcopy.1 3195 2015-05-12 17:22:19Z emaste $
+.\" $Id: elfcopy.1 3266 2015-12-07 15:38:26Z emaste $
.\"
-.Dd March 27, 2015
+.Dd December 7, 2015
.Os
.Dt ELFCOPY 1
.Sh NAME
@@ -47,6 +47,7 @@
.Op Fl p | Fl -preserve-dates
.Op Fl w | Fl -wildcard
.Op Fl x | Fl -discard-all
+.Op Fl -add-gnu-debuglink Ns = Ns Ar filename
.Op Fl -add-section Ar sectionname Ns = Ns Ar filename
.Oo
.Fl -adjust-section-vma Ar section Ns {+|-|=} Ns Ar val |
@@ -165,6 +166,10 @@ Mark the end of a character class.
.El
.It Fl x | Fl -discard-all
Do not copy non-global symbols to the output.
+.It Fl -add-gnu-debuglink Ns = Ns Ar filename
+Create a .gnu_debuglink section in the output file that references the
+debug data in
+.Ar filename .
.It Fl -add-section Ar sectionname Ns = Ns Ar filename
Add a new section to the output file with name
.Ar sectionname .
diff --git a/contrib/elftoolchain/elfcopy/main.c b/contrib/elftoolchain/elfcopy/main.c
index cbd48d3..e2685b4 100644
--- a/contrib/elftoolchain/elfcopy/main.c
+++ b/contrib/elftoolchain/elfcopy/main.c
@@ -39,7 +39,7 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: main.c 3216 2015-05-23 21:16:36Z kaiwang27 $");
+ELFTC_VCSID("$Id: main.c 3268 2015-12-07 20:30:55Z emaste $");
enum options
{
@@ -1375,11 +1375,13 @@ Usage: %s [options] infile [outfile]\n\
-w | --wildcard Use shell-style patterns to name symbols.\n\
-x | --discard-all Do not copy non-globals to the output.\n\
-I FORMAT | --input-target=FORMAT\n\
- (Accepted but ignored).\n\
+ Specify object format for the input file.\n\
-K SYM | --keep-symbol=SYM Copy symbol SYM to the output.\n\
-L SYM | --localize-symbol=SYM\n\
Make symbol SYM local to the output file.\n\
-N SYM | --strip-symbol=SYM Do not copy symbol SYM to the output.\n\
+ -O FORMAT | --output-target=FORMAT\n\
+ Specify object format for the output file.\n\
-R NAME | --remove-section=NAME\n\
Remove the named section.\n\
-S | --strip-all Remove all symbol and relocation information\n\
diff --git a/contrib/elftoolchain/elfcopy/sections.c b/contrib/elftoolchain/elfcopy/sections.c
index 02516ef..a17c9ab 100644
--- a/contrib/elftoolchain/elfcopy/sections.c
+++ b/contrib/elftoolchain/elfcopy/sections.c
@@ -34,7 +34,7 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: sections.c 3225 2015-06-06 02:35:23Z kaiwang27 $");
+ELFTC_VCSID("$Id: sections.c 3272 2015-12-11 20:00:54Z kaiwang27 $");
static void add_gnu_debuglink(struct elfcopy *ecp);
static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
@@ -457,11 +457,17 @@ create_scn(struct elfcopy *ecp)
/*
* If strip action is STRIP_NONDEBUG(only keep debug),
- * change sections flags of loadable sections to SHF_NOBITS,
- * and the content of those sections will be ignored.
+ * change sections type of loadable sections and section
+ * groups to SHT_NOBITS, and the content of those sections
+ * will be discarded. However, SHT_NOTE sections should
+ * be kept.
*/
- if (ecp->strip == STRIP_NONDEBUG && (ish.sh_flags & SHF_ALLOC))
- s->type = SHT_NOBITS;
+ if (ecp->strip == STRIP_NONDEBUG) {
+ if (((ish.sh_flags & SHF_ALLOC) ||
+ (ish.sh_flags & SHF_GROUP)) &&
+ ish.sh_type != SHT_NOTE)
+ s->type = SHT_NOBITS;
+ }
check_section_rename(ecp, s);
diff --git a/contrib/elftoolchain/elfcopy/segments.c b/contrib/elftoolchain/elfcopy/segments.c
index 1e271a6..837cea5 100644
--- a/contrib/elftoolchain/elfcopy/segments.c
+++ b/contrib/elftoolchain/elfcopy/segments.c
@@ -34,7 +34,7 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: segments.c 3196 2015-05-12 17:33:48Z emaste $");
+ELFTC_VCSID("$Id: segments.c 3269 2015-12-11 18:38:43Z kaiwang27 $");
static void insert_to_inseg_list(struct segment *seg, struct section *sec);
@@ -77,8 +77,6 @@ add_to_inseg_list(struct elfcopy *ecp, struct section *s)
if (s->off + s->sz > seg->off + seg->fsz &&
s->type != SHT_NOBITS)
continue;
- if (s->off + s->sz > seg->off + seg->msz)
- continue;
if (s->vma + s->sz > seg->addr + seg->msz)
continue;
diff --git a/contrib/elftoolchain/libelf/elf_data.c b/contrib/elftoolchain/libelf/elf_data.c
index ce80e1c..3d8ef6c 100644
--- a/contrib/elftoolchain/libelf/elf_data.c
+++ b/contrib/elftoolchain/libelf/elf_data.c
@@ -32,7 +32,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: elf_data.c 3177 2015-03-30 18:19:41Z emaste $");
+ELFTC_VCSID("$Id: elf_data.c 3258 2015-11-20 18:59:43Z emaste $");
Elf_Data *
elf_getdata(Elf_Scn *s, Elf_Data *ed)
@@ -253,6 +253,12 @@ elf_rawdata(Elf_Scn *s, Elf_Data *ed)
return (NULL);
}
+ if (sh_type != SHT_NOBITS &&
+ sh_offset + sh_size > (uint64_t) e->e_rawsize) {
+ LIBELF_SET_ERROR(SECTION, 0);
+ return (NULL);
+ }
+
if ((d = _libelf_allocate_data(s)) == NULL)
return (NULL);
diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c
index f197403..6902024 100644
--- a/contrib/elftoolchain/readelf/readelf.c
+++ b/contrib/elftoolchain/readelf/readelf.c
@@ -47,7 +47,7 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: readelf.c 3250 2015-10-06 13:56:15Z emaste $");
+ELFTC_VCSID("$Id: readelf.c 3271 2015-12-11 18:53:08Z kaiwang27 $");
/*
* readelf(1) options.
@@ -256,7 +256,7 @@ static const char *dt_type(unsigned int mach, unsigned int dtype);
static void dump_ar(struct readelf *re, int);
static void dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe);
static void dump_attributes(struct readelf *re);
-static uint8_t *dump_compatibility_tag(uint8_t *p);
+static uint8_t *dump_compatibility_tag(uint8_t *p, uint8_t *pe);
static void dump_dwarf(struct readelf *re);
static void dump_dwarf_abbrev(struct readelf *re);
static void dump_dwarf_aranges(struct readelf *re);
@@ -306,7 +306,7 @@ static void dump_ppc_attributes(uint8_t *p, uint8_t *pe);
static void dump_section_groups(struct readelf *re);
static void dump_symtab(struct readelf *re, int i);
static void dump_symtabs(struct readelf *re);
-static uint8_t *dump_unknown_tag(uint64_t tag, uint8_t *p);
+static uint8_t *dump_unknown_tag(uint64_t tag, uint8_t *p, uint8_t *pe);
static void dump_ver(struct readelf *re);
static void dump_verdef(struct readelf *re, int dump);
static void dump_verneed(struct readelf *re, int dump);
@@ -358,8 +358,8 @@ static uint64_t _read_msb(Elf_Data *d, uint64_t *offsetp,
int bytes_to_read);
static uint64_t _decode_lsb(uint8_t **data, int bytes_to_read);
static uint64_t _decode_msb(uint8_t **data, int bytes_to_read);
-static int64_t _decode_sleb128(uint8_t **dp);
-static uint64_t _decode_uleb128(uint8_t **dp);
+static int64_t _decode_sleb128(uint8_t **dp, uint8_t *dpe);
+static uint64_t _decode_uleb128(uint8_t **dp, uint8_t *dpe);
static struct eflags_desc arm_eflags_desc[] = {
{EF_ARM_RELEXEC, "relocatable executable"},
@@ -1171,10 +1171,14 @@ r_type(unsigned int mach, unsigned int type)
case 10: return "R_ARM_THM_PC22";
case 11: return "R_ARM_THM_PC8";
case 12: return "R_ARM_AMP_VCALL9";
- case 13: return "R_ARM_SWI24";
+ case 13: return "R_ARM_TLS_DESC";
+ /* Obsolete R_ARM_SWI24 is also 13 */
case 14: return "R_ARM_THM_SWI8";
case 15: return "R_ARM_XPC25";
case 16: return "R_ARM_THM_XPC22";
+ case 17: return "R_ARM_TLS_DTPMOD32";
+ case 18: return "R_ARM_TLS_DTPOFF32";
+ case 19: return "R_ARM_TLS_TPOFF32";
case 20: return "R_ARM_COPY";
case 21: return "R_ARM_GLOB_DAT";
case 22: return "R_ARM_JUMP_SLOT";
@@ -1183,6 +1187,17 @@ r_type(unsigned int mach, unsigned int type)
case 25: return "R_ARM_GOTPC";
case 26: return "R_ARM_GOT32";
case 27: return "R_ARM_PLT32";
+ case 28: return "R_ARM_CALL";
+ case 29: return "R_ARM_JUMP24";
+ case 30: return "R_ARM_THM_JUMP24";
+ case 31: return "R_ARM_BASE_ABS";
+ case 38: return "R_ARM_TARGET1";
+ case 40: return "R_ARM_V4BX";
+ case 42: return "R_ARM_PREL31";
+ case 43: return "R_ARM_MOVW_ABS_NC";
+ case 44: return "R_ARM_MOVT_ABS";
+ case 45: return "R_ARM_MOVW_PREL_NC";
+ case 46: return "R_ARM_MOVT_PREL";
case 100: return "R_ARM_GNU_VTENTRY";
case 101: return "R_ARM_GNU_VTINHERIT";
case 250: return "R_ARM_RSBREL32";
@@ -2847,9 +2862,9 @@ dump_phdr(struct readelf *re)
printf(" %2.2d ", i);
/* skip NULL section. */
for (j = 1; (size_t)j < re->shnum; j++)
- if (re->sl[j].off >= phdr.p_offset &&
- re->sl[j].off + re->sl[j].sz <=
- phdr.p_offset + phdr.p_memsz)
+ if (re->sl[j].addr >= phdr.p_vaddr &&
+ re->sl[j].addr + re->sl[j].sz <=
+ phdr.p_vaddr + phdr.p_memsz)
printf("%s ", re->sl[j].name);
printf("\n");
}
@@ -4245,7 +4260,7 @@ dump_section_groups(struct readelf *re)
}
static uint8_t *
-dump_unknown_tag(uint64_t tag, uint8_t *p)
+dump_unknown_tag(uint64_t tag, uint8_t *p, uint8_t *pe)
{
uint64_t val;
@@ -4262,7 +4277,7 @@ dump_unknown_tag(uint64_t tag, uint8_t *p)
printf("%s\n", (char *) p);
p += strlen((char *) p) + 1;
} else {
- val = _decode_uleb128(&p);
+ val = _decode_uleb128(&p, pe);
printf("%ju\n", (uintmax_t) val);
}
@@ -4270,11 +4285,11 @@ dump_unknown_tag(uint64_t tag, uint8_t *p)
}
static uint8_t *
-dump_compatibility_tag(uint8_t *p)
+dump_compatibility_tag(uint8_t *p, uint8_t *pe)
{
uint64_t val;
- val = _decode_uleb128(&p);
+ val = _decode_uleb128(&p, pe);
printf("flag = %ju, vendor = %s\n", val, p);
p += strlen((char *) p) + 1;
@@ -4291,7 +4306,7 @@ dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe)
(void) re;
while (p < pe) {
- tag = _decode_uleb128(&p);
+ tag = _decode_uleb128(&p, pe);
found = desc = 0;
for (i = 0; i < sizeof(aeabi_tags) / sizeof(aeabi_tags[0]);
i++) {
@@ -4300,7 +4315,7 @@ dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe)
printf(" %s: ", aeabi_tags[i].s_tag);
if (aeabi_tags[i].get_desc) {
desc = 1;
- val = _decode_uleb128(&p);
+ val = _decode_uleb128(&p, pe);
printf("%s\n",
aeabi_tags[i].get_desc(val));
}
@@ -4310,7 +4325,7 @@ dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe)
break;
}
if (!found) {
- p = dump_unknown_tag(tag, p);
+ p = dump_unknown_tag(tag, p, pe);
continue;
}
if (desc)
@@ -4324,21 +4339,21 @@ dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe)
p += strlen((char *) p) + 1;
break;
case 32: /* Tag_compatibility */
- p = dump_compatibility_tag(p);
+ p = dump_compatibility_tag(p, pe);
break;
case 64: /* Tag_nodefaults */
/* ignored, written as 0. */
- (void) _decode_uleb128(&p);
+ (void) _decode_uleb128(&p, pe);
printf("True\n");
break;
case 65: /* Tag_also_compatible_with */
- val = _decode_uleb128(&p);
+ val = _decode_uleb128(&p, pe);
/* Must be Tag_CPU_arch */
if (val != 6) {
printf("unknown\n");
break;
}
- val = _decode_uleb128(&p);
+ val = _decode_uleb128(&p, pe);
printf("%s\n", aeabi_cpu_arch(val));
/* Skip NUL terminator. */
p++;
@@ -4362,17 +4377,17 @@ dump_mips_attributes(struct readelf *re, uint8_t *p, uint8_t *pe)
(void) re;
while (p < pe) {
- tag = _decode_uleb128(&p);
+ tag = _decode_uleb128(&p, pe);
switch (tag) {
case Tag_GNU_MIPS_ABI_FP:
- val = _decode_uleb128(&p);
+ val = _decode_uleb128(&p, pe);
printf(" Tag_GNU_MIPS_ABI_FP: %s\n", mips_abi_fp(val));
break;
case 32: /* Tag_compatibility */
- p = dump_compatibility_tag(p);
+ p = dump_compatibility_tag(p, pe);
break;
default:
- p = dump_unknown_tag(tag, p);
+ p = dump_unknown_tag(tag, p, pe);
break;
}
}
@@ -4392,22 +4407,22 @@ dump_ppc_attributes(uint8_t *p, uint8_t *pe)
uint64_t tag, val;
while (p < pe) {
- tag = _decode_uleb128(&p);
+ tag = _decode_uleb128(&p, pe);
switch (tag) {
case Tag_GNU_Power_ABI_FP:
- val = _decode_uleb128(&p);
+ val = _decode_uleb128(&p, pe);
printf(" Tag_GNU_Power_ABI_FP: %s\n", ppc_abi_fp(val));
break;
case Tag_GNU_Power_ABI_Vector:
- val = _decode_uleb128(&p);
+ val = _decode_uleb128(&p, pe);
printf(" Tag_GNU_Power_ABI_Vector: %s\n",
ppc_abi_vector(val));
break;
case 32: /* Tag_compatibility */
- p = dump_compatibility_tag(p);
+ p = dump_compatibility_tag(p, pe);
break;
default:
- p = dump_unknown_tag(tag, p);
+ p = dump_unknown_tag(tag, p, pe);
break;
}
}
@@ -4418,7 +4433,7 @@ dump_attributes(struct readelf *re)
{
struct section *s;
Elf_Data *d;
- uint8_t *p, *sp;
+ uint8_t *p, *pe, *sp;
size_t len, seclen, nlen, sublen;
uint64_t val;
int tag, i, elferr;
@@ -4439,6 +4454,7 @@ dump_attributes(struct readelf *re)
if (d->d_size <= 0)
continue;
p = d->d_buf;
+ pe = p + d->d_size;
if (*p != 'A') {
printf("Unknown Attribute Section Format: %c\n",
(char) *p);
@@ -4449,18 +4465,18 @@ dump_attributes(struct readelf *re)
while (len > 0) {
if (len < 4) {
warnx("truncated attribute section length");
- break;
+ return;
}
seclen = re->dw_decode(&p, 4);
if (seclen > len) {
warnx("invalid attribute section length");
- break;
+ return;
}
len -= seclen;
nlen = strlen((char *) p) + 1;
if (nlen + 4 > seclen) {
warnx("invalid attribute section name");
- break;
+ return;
}
printf("Attribute Section: %s\n", (char *) p);
p += nlen;
@@ -4472,14 +4488,14 @@ dump_attributes(struct readelf *re)
if (sublen > seclen) {
warnx("invalid attribute sub-section"
" length");
- break;
+ return;
}
seclen -= sublen;
printf("%s", top_tag(tag));
if (tag == 2 || tag == 3) {
putchar(':');
for (;;) {
- val = _decode_uleb128(&p);
+ val = _decode_uleb128(&p, pe);
if (val == 0)
break;
printf(" %ju", (uintmax_t) val);
@@ -4798,6 +4814,7 @@ dump_dwarf_line(struct readelf *re)
}
endoff = offset + length;
+ pe = (uint8_t *) d->d_buf + endoff;
version = re->dw_read(d, &offset, 2);
hdrlen = re->dw_read(d, &offset, dwarf_size);
minlen = re->dw_read(d, &offset, 1);
@@ -4842,9 +4859,9 @@ dump_dwarf_line(struct readelf *re)
i++;
pn = (char *) p;
p += strlen(pn) + 1;
- dirndx = _decode_uleb128(&p);
- mtime = _decode_uleb128(&p);
- fsize = _decode_uleb128(&p);
+ dirndx = _decode_uleb128(&p, pe);
+ mtime = _decode_uleb128(&p, pe);
+ fsize = _decode_uleb128(&p, pe);
printf(" %d\t%ju\t%ju\t%ju\t%s\n", i,
(uintmax_t) dirndx, (uintmax_t) mtime,
(uintmax_t) fsize, pn);
@@ -4863,7 +4880,6 @@ dump_dwarf_line(struct readelf *re)
#define ADDRESS(x) ((((x) - opbase) / lrange) * minlen)
p++;
- pe = (uint8_t *) d->d_buf + endoff;
printf("\n");
printf(" Line Number Statements:\n");
@@ -4876,7 +4892,7 @@ dump_dwarf_line(struct readelf *re)
* Extended Opcodes.
*/
p++;
- opsize = _decode_uleb128(&p);
+ opsize = _decode_uleb128(&p, pe);
printf(" Extended opcode %u: ", *p);
switch (*p) {
case DW_LNE_end_sequence:
@@ -4895,9 +4911,9 @@ dump_dwarf_line(struct readelf *re)
p++;
pn = (char *) p;
p += strlen(pn) + 1;
- dirndx = _decode_uleb128(&p);
- mtime = _decode_uleb128(&p);
- fsize = _decode_uleb128(&p);
+ dirndx = _decode_uleb128(&p, pe);
+ mtime = _decode_uleb128(&p, pe);
+ fsize = _decode_uleb128(&p, pe);
printf("define new file: %s\n", pn);
break;
default:
@@ -4914,7 +4930,7 @@ dump_dwarf_line(struct readelf *re)
printf(" Copy\n");
break;
case DW_LNS_advance_pc:
- udelta = _decode_uleb128(&p) *
+ udelta = _decode_uleb128(&p, pe) *
minlen;
address += udelta;
printf(" Advance PC by %ju to %#jx\n",
@@ -4922,19 +4938,19 @@ dump_dwarf_line(struct readelf *re)
(uintmax_t) address);
break;
case DW_LNS_advance_line:
- sdelta = _decode_sleb128(&p);
+ sdelta = _decode_sleb128(&p, pe);
line += sdelta;
printf(" Advance Line by %jd to %ju\n",
(intmax_t) sdelta,
(uintmax_t) line);
break;
case DW_LNS_set_file:
- file = _decode_uleb128(&p);
+ file = _decode_uleb128(&p, pe);
printf(" Set File to %ju\n",
(uintmax_t) file);
break;
case DW_LNS_set_column:
- column = _decode_uleb128(&p);
+ column = _decode_uleb128(&p, pe);
printf(" Set Column to %ju\n",
(uintmax_t) column);
break;
@@ -4967,7 +4983,7 @@ dump_dwarf_line(struct readelf *re)
printf(" Set epilogue begin flag\n");
break;
case DW_LNS_set_isa:
- isa = _decode_uleb128(&p);
+ isa = _decode_uleb128(&p, pe);
printf(" Set isa to %ju\n", isa);
break;
default:
@@ -7457,15 +7473,17 @@ _decode_msb(uint8_t **data, int bytes_to_read)
}
static int64_t
-_decode_sleb128(uint8_t **dp)
+_decode_sleb128(uint8_t **dp, uint8_t *dpe)
{
int64_t ret = 0;
- uint8_t b;
+ uint8_t b = 0;
int shift = 0;
uint8_t *src = *dp;
do {
+ if (src >= dpe)
+ break;
b = *src++;
ret |= ((b & 0x7f) << shift);
shift += 7;
@@ -7480,7 +7498,7 @@ _decode_sleb128(uint8_t **dp)
}
static uint64_t
-_decode_uleb128(uint8_t **dp)
+_decode_uleb128(uint8_t **dp, uint8_t *dpe)
{
uint64_t ret = 0;
uint8_t b;
@@ -7489,6 +7507,8 @@ _decode_uleb128(uint8_t **dp)
uint8_t *src = *dp;
do {
+ if (src >= dpe)
+ break;
b = *src++;
ret |= ((b & 0x7f) << shift);
shift += 7;
diff --git a/contrib/top/loadavg.h b/contrib/top/loadavg.h
index e3c156c..2f20231 100644
--- a/contrib/top/loadavg.h
+++ b/contrib/top/loadavg.h
@@ -19,10 +19,10 @@
*
* Defined types: load_avg for load averages, pctcpu for cpu percentages.
*/
-#if defined(mips) && !defined(NetBSD)
+#if defined(mips) && !(defined(NetBSD) || defined(FreeBSD))
# include <sys/fixpoint.h>
# if defined(FBITS) && !defined(FSCALE)
-# define FSCALE (1 << FBITS) /* mips */
+# define FSCALE (1 << FBITS) /* RISC/os on mips */
# endif
#endif
diff --git a/contrib/unbound/freebsd-configure.sh b/contrib/unbound/freebsd-configure.sh
index 4430f3c..5d930a6 100755
--- a/contrib/unbound/freebsd-configure.sh
+++ b/contrib/unbound/freebsd-configure.sh
@@ -24,6 +24,9 @@ ldnsobj=$(realpath $(make -C$ldnsbld -V.OBJDIR))
[ -f $ldnsobj/libprivateldns.a ] || error "can't find LDNS object directory"
export LDFLAGS="-L$ldnsobj"
+export CC=$(echo ".include <bsd.lib.mk>" | make -f /dev/stdin -VCC)
+export CPP=$(echo ".include <bsd.lib.mk>" | make -f /dev/stdin -VCPP)
+
autoconf
autoheader
./configure \
diff --git a/etc/etc.riscv/ttys b/etc/etc.riscv/ttys
new file mode 100644
index 0000000..ede1d79
--- /dev/null
+++ b/etc/etc.riscv/ttys
@@ -0,0 +1,51 @@
+#
+# $FreeBSD$
+# @(#)ttys 5.1 (Berkeley) 4/17/89
+#
+# This file specifies various information about terminals on the system.
+# It is used by several different programs. Common entries for the
+# various columns include:
+#
+# name The name of the terminal device.
+#
+# getty The program to start running on the terminal. Typically a
+# getty program, as the name implies. Other common entries
+# include none, when no getty is needed, and xdm, to start the
+# X Window System.
+#
+# type The initial terminal type for this port. For hardwired
+# terminal lines, this will contain the type of terminal used.
+# For virtual consoles, the correct type is typically xterm.
+# Other common values include dialup for incoming modem ports, and
+# unknown when the terminal type cannot be predetermined.
+#
+# status Must be on or off. If on, init will run the getty program on
+# the specified port. If the word "secure" appears, this tty
+# allows root login.
+#
+# name getty type status comments
+#
+# If console is marked "insecure", then init will ask for the root password
+# when going to single-user mode.
+console none unknown off secure
+#
+ttyv0 "/usr/libexec/getty Pc" xterm onifconsole secure
+# Virtual terminals
+ttyv1 "/usr/libexec/getty Pc" xterm off secure
+ttyv2 "/usr/libexec/getty Pc" xterm off secure
+ttyv3 "/usr/libexec/getty Pc" xterm off secure
+ttyv4 "/usr/libexec/getty Pc" xterm off secure
+ttyv5 "/usr/libexec/getty Pc" xterm off secure
+ttyv6 "/usr/libexec/getty Pc" xterm off secure
+ttyv7 "/usr/libexec/getty Pc" xterm off secure
+#ttyv8 "/usr/local/bin/xdm -nodaemon" xterm off secure
+# Serial terminals
+# The 'dialup' keyword identifies dialin lines to login, fingerd etc.
+ttyu0 "/usr/libexec/getty 3wire" vt100 onifconsole secure
+ttyu1 "/usr/libexec/getty 3wire" vt100 onifconsole secure
+ttyu2 "/usr/libexec/getty 3wire" vt100 onifconsole secure
+ttyu3 "/usr/libexec/getty 3wire" vt100 onifconsole secure
+# Dumb console
+dcons "/usr/libexec/getty std.9600" vt100 off secure
+# RISC-V HTIF console
+rcons "/usr/libexec/getty std.9600" vt100 onifconsole secure
diff --git a/lib/csu/riscv/Makefile b/lib/csu/riscv/Makefile
new file mode 100644
index 0000000..9747619
--- /dev/null
+++ b/lib/csu/riscv/Makefile
@@ -0,0 +1,46 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../common
+
+SRCS= crt1.c crti.S crtn.S
+OBJS= ${SRCS:N*.h:R:S/$/.o/g}
+OBJS+= Scrt1.o gcrt1.o
+CFLAGS+= -I${.CURDIR}/../common \
+ -I${.CURDIR}/../../libc/include
+
+FILES= ${OBJS}
+FILESMODE= ${LIBMODE}
+FILESOWN= ${LIBOWN}
+FILESGRP= ${LIBGRP}
+FILESDIR= ${LIBDIR}
+# These FILES qualify as libraries for the purpose of LIBRARIES_ONLY.
+.undef LIBRARIES_ONLY
+
+CLEANFILES= ${OBJS}
+CLEANFILES+= crt1.s gcrt1.s Scrt1.s
+
+# See the comment in lib/csu/common/crtbrand.c for the reason crt1.c is not
+# directly compiled to .o files.
+
+crt1.s: crt1.c
+ ${CC} ${CFLAGS} -S -o ${.TARGET} ${.CURDIR}/crt1.c
+ sed ${SED_FIX_NOTE} ${.TARGET}
+
+crt1.o: crt1.s
+ ${CC} ${ACFLAGS} -c -o ${.TARGET} crt1.s
+
+gcrt1.s: crt1.c
+ ${CC} ${CFLAGS} -DGCRT -S -o ${.TARGET} ${.CURDIR}/crt1.c
+ sed ${SED_FIX_NOTE} ${.TARGET}
+
+gcrt1.o: gcrt1.s
+ ${CC} ${ACFLAGS} -c -o ${.TARGET} gcrt1.s
+
+Scrt1.s: crt1.c
+ ${CC} ${CFLAGS} -fPIC -DPIC -S -o ${.TARGET} ${.CURDIR}/crt1.c
+ sed ${SED_FIX_NOTE} ${.TARGET}
+
+Scrt1.o: Scrt1.s
+ ${CC} ${ACFLAGS} -c -o ${.TARGET} Scrt1.s
+
+.include <bsd.lib.mk>
diff --git a/lib/csu/riscv/crt1.c b/lib/csu/riscv/crt1.c
new file mode 100644
index 0000000..0c3fbe6
--- /dev/null
+++ b/lib/csu/riscv/crt1.c
@@ -0,0 +1,89 @@
+/* LINTLIBRARY */
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by SRI International and the
+ * University of Cambridge Computer Laboratory under DARPA/AFRL contract
+ * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * Portions of this software were developed by the University of Cambridge
+ * Computer Laboratory as part of the CTSRD Project, with support from the
+ * UK Higher Education Innovation Fund (HEIF).
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+
+#include "libc_private.h"
+#include "crtbrand.c"
+#include "ignore_init.c"
+
+typedef void (*fptr)(void);
+
+#ifdef GCRT
+extern void _mcleanup(void);
+extern void monstartup(void *, void *);
+extern int eprol;
+extern int etext;
+#endif
+
+void __start(int argc, char **argv, char **env, void (*cleanup)(void));
+
+/* The entry function. */
+__asm(" .text \n"
+" .align 0 \n"
+" .globl _start \n"
+" _start: \n"
+" mv a3, a2 \n" /* cleanup */
+" addi a1, a0, 8 \n" /* get argv */
+" ld a0, 0(a0) \n" /* load argc */
+" slli t0, a0, 3 \n" /* mult by arg size */
+" add a2, a1, t0 \n" /* env is after argv */
+" addi a2, a2, 8 \n" /* argv is null terminated */
+" lla gp, _gp \n" /* load global pointer */
+" call __start");
+
+void
+__start(int argc, char **argv, char **env, void (*cleanup)(void))
+{
+
+ handle_argv(argc, argv, env);
+
+ if (&_DYNAMIC != NULL)
+ atexit(cleanup);
+ else
+ _init_tls();
+
+#ifdef GCRT
+ atexit(_mcleanup);
+ monstartup(&eprol, &etext);
+__asm__("eprol:");
+#endif
+
+ handle_static_init(argc, argv, env);
+ exit(main(argc, argv, env));
+}
diff --git a/lib/csu/riscv/crti.S b/lib/csu/riscv/crti.S
new file mode 100644
index 0000000..df6027e
--- /dev/null
+++ b/lib/csu/riscv/crti.S
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by SRI International and the
+ * University of Cambridge Computer Laboratory under DARPA/AFRL contract
+ * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * Portions of this software were developed by the University of Cambridge
+ * Computer Laboratory as part of the CTSRD Project, with support from the
+ * UK Higher Education Innovation Fund (HEIF).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+# this puts _gp into .dynsym, so symlook_obj can now find that (see reloc.c)
+ .weak _gp
+_gp:
+
+ .section .init,"ax",@progbits
+ .align 2
+ .globl _init
+ .type _init,@function
+_init:
+ addi sp, sp, -16
+ sd ra, 0(sp)
+
+ .section .fini,"ax",@progbits
+ .align 2
+ .globl _fini
+ .type _fini,@function
+_fini:
+ addi sp, sp, -16
+ sd ra, 0(sp)
+
+ .section .note.GNU-stack,"",%progbits
diff --git a/lib/csu/riscv/crtn.S b/lib/csu/riscv/crtn.S
new file mode 100644
index 0000000..b582471
--- /dev/null
+++ b/lib/csu/riscv/crtn.S
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by SRI International and the
+ * University of Cambridge Computer Laboratory under DARPA/AFRL contract
+ * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * Portions of this software were developed by the University of Cambridge
+ * Computer Laboratory as part of the CTSRD Project, with support from the
+ * UK Higher Education Innovation Fund (HEIF).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+ .section .init,"ax",@progbits
+ ld ra, 0(sp)
+ addi sp, sp, 16
+ ret
+
+ .section .fini,"ax",@progbits
+ ld ra, 0(sp)
+ addi sp, sp, 16
+ ret
+
+ .section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/gen/exec.3 b/lib/libc/gen/exec.3
index daeccd1..c9d32b4 100644
--- a/lib/libc/gen/exec.3
+++ b/lib/libc/gen/exec.3
@@ -28,7 +28,7 @@
.\" @(#)exec.3 8.3 (Berkeley) 1/24/94
.\" $FreeBSD$
.\"
-.Dd January 24, 1994
+.Dd December 12, 2015
.Dt EXEC 3
.Os
.Sh NAME
@@ -223,7 +223,7 @@ and
.Fn execvp
functions was
.Dq Pa :/bin:/usr/bin .
-This was changed to place the current directory last to enhance system
+This was changed to remove the current directory to enhance system
security.
.Pp
The behavior of
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c
index 95c588b..ab6b65f 100644
--- a/lib/libc/net/getaddrinfo.c
+++ b/lib/libc/net/getaddrinfo.c
@@ -1563,7 +1563,7 @@ addrconfig(struct addrinfo *pai)
if (seen_inet)
continue;
sin = (struct sockaddr_in *)(ifa->ifa_addr);
- if (IN_LOOPBACK(htonl(sin->sin_addr.s_addr)))
+ if (htonl(sin->sin_addr.s_addr) == INADDR_LOOPBACK)
continue;
seen_inet = 1;
break;
@@ -2208,6 +2208,8 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
memset(&sentinel, 0, sizeof(sentinel));
cur = &sentinel;
+ res = __res_state();
+
buf = malloc(sizeof(*buf));
if (!buf) {
RES_SET_H_ERRNO(res, NETDB_INTERNAL);
@@ -2254,7 +2256,6 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
return NS_UNAVAIL;
}
- res = __res_state();
if ((res->options & RES_INIT) == 0 && res_ninit(res) == -1) {
RES_SET_H_ERRNO(res, NETDB_INTERNAL);
free(buf);
diff --git a/lib/libc/regex/grot/Makefile b/lib/libc/regex/grot/Makefile
index e715dd8..056b55e 100644
--- a/lib/libc/regex/grot/Makefile
+++ b/lib/libc/regex/grot/Makefile
@@ -8,7 +8,7 @@
PATHS= ${.CURDIR}/.. ${.CURDIR}/../../locale ${.CURDIR}/../../../../include
.PATH: ${PATHS}
-CFLAGS+= -DPOSIX_MISTAKE -DREDEBUG $(REGCFLAGS)
+CFLAGS+= -static -DPOSIX_MISTAKE -DREDEBUG $(REGCFLAGS)
.for incpath in ${PATHS}
CFLAGS+= -I${incpath}
.endfor
diff --git a/lib/libc/riscv/Makefile.inc b/lib/libc/riscv/Makefile.inc
new file mode 100644
index 0000000..e8c0da7
--- /dev/null
+++ b/lib/libc/riscv/Makefile.inc
@@ -0,0 +1 @@
+# $FreeBSD$
diff --git a/lib/libthr/arch/riscv/Makefile.inc b/lib/libthr/arch/riscv/Makefile.inc
new file mode 100644
index 0000000..e8c0da7
--- /dev/null
+++ b/lib/libthr/arch/riscv/Makefile.inc
@@ -0,0 +1 @@
+# $FreeBSD$
diff --git a/lib/msun/riscv/Makefile.inc b/lib/msun/riscv/Makefile.inc
new file mode 100644
index 0000000..0ce69db
--- /dev/null
+++ b/lib/msun/riscv/Makefile.inc
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+# RISCVTODO: should be 113
+# compilation problems: gcc generates bltuz instruction, which is not exists
+
+LDBL_PREC = 53
diff --git a/lib/msun/riscv/fenv.h b/lib/msun/riscv/fenv.h
new file mode 100644
index 0000000..3eae6c2
--- /dev/null
+++ b/lib/msun/riscv/fenv.h
@@ -0,0 +1,228 @@
+/*-
+ * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
+ * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by SRI International and the
+ * University of Cambridge Computer Laboratory under DARPA/AFRL contract
+ * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * Portions of this software were developed by the University of Cambridge
+ * Computer Laboratory as part of the CTSRD Project, with support from the
+ * UK Higher Education Innovation Fund (HEIF).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _FENV_H_
+#define _FENV_H_
+
+#include <sys/_types.h>
+
+#ifndef __fenv_static
+#define __fenv_static static
+#endif
+
+typedef __uint64_t fenv_t;
+typedef __uint64_t fexcept_t;
+
+/* Exception flags */
+#define FE_INVALID 0x0010
+#define FE_DIVBYZERO 0x0008
+#define FE_OVERFLOW 0x0004
+#define FE_UNDERFLOW 0x0002
+#define FE_INEXACT 0x0001
+#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \
+ FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
+
+/*
+ * RISC-V Rounding modes
+ */
+#define FE_TONEAREST (0x00 << 5)
+#define FE_TOWARDZERO (0x01 << 5)
+#define FE_DOWNWARD (0x02 << 5)
+#define FE_UPWARD (0x03 << 5)
+#define _ROUND_SHIFT 5
+#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
+ FE_UPWARD | FE_TOWARDZERO)
+
+__BEGIN_DECLS
+
+/* Default floating-point environment */
+extern const fenv_t __fe_dfl_env;
+#define FE_DFL_ENV (&__fe_dfl_env)
+
+/* We need to be able to map status flag positions to mask flag positions */
+#define _FPUSW_SHIFT 0
+#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT)
+
+#define __rfs(__fpsr) __asm __volatile("csrr %0, fcsr" : "=r" (*(__fpsr)))
+#define __wfs(__fpsr) __asm __volatile("csrw fcsr, %0" :: "r" (__fpsr))
+
+__fenv_static inline int
+feclearexcept(int __excepts)
+{
+ fexcept_t __fpsr;
+
+ __rfs(&__fpsr);
+ __fpsr &= ~__excepts;
+ __wfs(__fpsr);
+ return (0);
+}
+
+__fenv_static inline int
+fegetexceptflag(fexcept_t *__flagp, int __excepts)
+{
+ fexcept_t __fpsr;
+
+ __rfs(&__fpsr);
+ *__flagp = __fpsr & __excepts;
+ return (0);
+}
+
+__fenv_static inline int
+fesetexceptflag(const fexcept_t *__flagp, int __excepts)
+{
+ fexcept_t __fpsr;
+
+ __rfs(&__fpsr);
+ __fpsr &= ~__excepts;
+ __fpsr |= *__flagp & __excepts;
+ __wfs(__fpsr);
+ return (0);
+}
+
+__fenv_static inline int
+feraiseexcept(int __excepts)
+{
+ fexcept_t __ex = __excepts;
+
+ fesetexceptflag(&__ex, __excepts); /* XXX */
+ return (0);
+}
+
+__fenv_static inline int
+fetestexcept(int __excepts)
+{
+ fexcept_t __fpsr;
+
+ __rfs(&__fpsr);
+ return (__fpsr & __excepts);
+}
+
+__fenv_static inline int
+fegetround(void)
+{
+
+ return (-1);
+}
+
+__fenv_static inline int
+fesetround(int __round)
+{
+
+ return (-1);
+}
+
+__fenv_static inline int
+fegetenv(fenv_t *__envp)
+{
+
+ __rfs(__envp);
+ return (0);
+}
+
+__fenv_static inline int
+feholdexcept(fenv_t *__envp)
+{
+ fenv_t __env;
+
+ __rfs(&__env);
+ *__envp = __env;
+ __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
+ __wfs(__env);
+ return (0);
+}
+
+__fenv_static inline int
+fesetenv(const fenv_t *__envp)
+{
+
+ __wfs(*__envp);
+ return (0);
+}
+
+__fenv_static inline int
+feupdateenv(const fenv_t *__envp)
+{
+ fexcept_t __fpsr;
+
+ __rfs(&__fpsr);
+ __wfs(*__envp);
+ feraiseexcept(__fpsr & FE_ALL_EXCEPT);
+ return (0);
+}
+
+#if __BSD_VISIBLE
+
+/* We currently provide no external definitions of the functions below. */
+
+static inline int
+feenableexcept(int __mask)
+{
+ fenv_t __old_fpsr;
+ fenv_t __new_fpsr;
+
+ __rfs(&__old_fpsr);
+ __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT;
+ __wfs(__new_fpsr);
+ return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+}
+
+static inline int
+fedisableexcept(int __mask)
+{
+ fenv_t __old_fpsr;
+ fenv_t __new_fpsr;
+
+ __rfs(&__old_fpsr);
+ __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
+ __wfs(__new_fpsr);
+ return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+}
+
+static inline int
+fegetexcept(void)
+{
+ fenv_t __fpsr;
+
+ __rfs(&__fpsr);
+ return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT);
+}
+
+#endif /* __BSD_VISIBLE */
+
+__END_DECLS
+
+#endif /* !_FENV_H_ */
diff --git a/sbin/geom/class/part/gpart.8 b/sbin/geom/class/part/gpart.8
index 354d844..452e6b3 100644
--- a/sbin/geom/class/part/gpart.8
+++ b/sbin/geom/class/part/gpart.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 14, 2015
+.Dd December 10, 2015
.Dt GPART 8
.Os
.Sh NAME
@@ -1107,15 +1107,6 @@ and
.Cm recover
are the only operations allowed on corrupt tables.
.Pp
-If the first sector of a provider is corrupt, the kernel can not detect GPT
-even if the partition table itself is not corrupt.
-The protective MBR can be rewritten using the
-.Xr dd 1
-command, to restore the ability to detect the GPT.
-The copy of the protective MBR is usually located in the
-.Pa /boot/pmbr
-file.
-.Pp
If one GPT header appears to be corrupt but the other copy remains intact,
the kernel will log the following:
.Bd -literal -offset indent
@@ -1330,7 +1321,6 @@ and
/sbin/gpart backup ada0 | /sbin/gpart restore -F ada1 ada2
.Ed
.Sh SEE ALSO
-.Xr dd 1 ,
.Xr geom 4 ,
.Xr boot0cfg 8 ,
.Xr geom 8 ,
diff --git a/share/man/man4/mps.4 b/share/man/man4/mps.4
index deeca95..f09ebfd 100644
--- a/share/man/man4/mps.4
+++ b/share/man/man4/mps.4
@@ -34,7 +34,7 @@
.\" $Id: //depot/SpectraBSD/head/share/man/man4/mps.4#6 $
.\" $FreeBSD$
.\"
-.Dd January 3, 2013
+.Dd December 9, 2015
.Dt MPS 4
.Os
.Sh NAME
@@ -129,6 +129,8 @@ driver instance, set the following tunable value in
dev.mps.X.disable_msix=1
.Ed
.Pp
+where X is the adapter number.
+.Pp
To set the maximum number of DMA chains allocated for all adapters,
set the following variable in
.Xr loader.conf 5 :
@@ -166,6 +168,39 @@ The maximum number of active I/O command seen since boot is shown in the
dev.mps.X.io_cmds_highwater
.Xr sysctl 8
variable.
+.Pp
+The adapter can issue the
+.Sy StartStopUnit
+SCSI command to SATA direct-access devices during shutdown, to allow the
+device to quiesce before being powered down.
+To control this feature for all adapters, set the
+.Bd -literal -offset indent
+hw.mps.enable_ssu
+.Ed
+.Pp
+tunable value in
+.Xr loader.conf 5
+to one of the following values:
+.Bl -tag -width 6n -offset indent
+.It 0
+Do not send SSU to either HDDs or SSDs.
+.It 1
+Send SSU to SSDs, but not to HDDs; this is the default value.
+.It 2
+Send SSU to HDDs, but not to SSDs.
+.It 3
+Send SSU to both HDDs and SSDs.
+.El
+.Pp
+To control the feature for a specific adapter, set the following tunable
+value in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+dev.mps.X.enable_ssu
+.Ed
+.Pp
+where X is the adapter number.
+The same set of values are valid as for all adapters.
.Sh DEBUGGING
To enable debugging prints from the
.Nm
@@ -218,7 +253,7 @@ This man page was written by
This driver has a couple of known shortcomings:
.Bl -bullet -compact
.It
-No userland utility available (e.g.
+No userland utility available (e.g.,
.Xr mptutil 8 ) .
.It
The driver probes devices sequentially.
diff --git a/share/mk/bsd.cpu.mk b/share/mk/bsd.cpu.mk
index b9880a3..d54a354 100644
--- a/share/mk/bsd.cpu.mk
+++ b/share/mk/bsd.cpu.mk
@@ -18,6 +18,8 @@ MACHINE_CPU = i486
MACHINE_CPU = mips
. elif ${MACHINE_CPUARCH} == "powerpc"
MACHINE_CPU = aim
+. elif ${MACHINE_CPUARCH} == "riscv"
+MACHINE_CPU = riscv
. elif ${MACHINE_CPUARCH} == "sparc64"
MACHINE_CPU = ultrasparc
. endif
@@ -110,7 +112,12 @@ _CPUCFLAGS = -march=armv5te -D__XSCALE__
_CPUCFLAGS = -march=${CPUTYPE} -DARM_ARCH_6=1
. elif ${CPUTYPE} == "cortexa"
_CPUCFLAGS = -march=armv7 -DARM_ARCH_6=1 -mfpu=vfp
-. else
+. elif ${CPUTYPE:Marmv[4567]*} != ""
+# Handle all the armvX types that FreeBSD runs:
+# armv4, armv4t, armv5, armv5te, armv6, armv6t2, armv7, armv7-a, armv7ve
+# they require -march=. All the others require -mcpu=.
+_CPUCFLAGS = -march=${CPUTYPE}
+. else
# Common values for FreeBSD
# arm:
# arm920t, arm926ej-s, marvell-pj4, fa526, fa626,
@@ -120,7 +127,7 @@ _CPUCFLAGS = -march=armv7 -DARM_ARCH_6=1 -mfpu=vfp
# cortex-a9, cortex-a12, cortex-a15, cortex-a17, cortex-a53, cortex-a57,
# cortex-a72, exynos-m1
_CPUCFLAGS = -mcpu=${CPUTYPE}
-. endif
+. endif
. elif ${MACHINE_ARCH} == "powerpc"
. if ${CPUTYPE} == "e500"
_CPUCFLAGS = -Wa,-me500 -msoft-float
@@ -143,6 +150,8 @@ _CPUCFLAGS = -march=${CPUTYPE}
# sb1, xlp, xlr
_CPUCFLAGS = -march=${CPUTYPE:S/^mips//}
. endif
+. elif ${MACHINE_CPUARCH} == "riscv"
+_CPUCFLAGS = -msoft-float # -march="RV64I" # RISCVTODO
. elif ${MACHINE_ARCH} == "sparc64"
. if ${CPUTYPE} == "v9"
_CPUCFLAGS = -mcpu=v9
@@ -272,6 +281,9 @@ MACHINE_CPU = mips
. if ${CPUTYPE} == "e500"
MACHINE_CPU = booke softfp
. endif
+########## riscv
+. elif ${MACHINE_CPUARCH} == "riscv"
+MACHINE_CPU = riscv
########## sparc64
. elif ${MACHINE_ARCH} == "sparc64"
. if ${CPUTYPE} == "v9"
@@ -308,6 +320,10 @@ CFLAGS += -mfloat-abi=softfp
.endif
.endif
+.if ${MACHINE_CPUARCH} == "riscv"
+CFLAGS += -msoft-float
+.endif
+
# NB: COPTFLAGS is handled in /usr/src/sys/conf/kern.pre.mk
.if !defined(NO_CPU_CFLAGS)
diff --git a/share/mk/bsd.endian.mk b/share/mk/bsd.endian.mk
index 2d1a53e..c7ec42c 100644
--- a/share/mk/bsd.endian.mk
+++ b/share/mk/bsd.endian.mk
@@ -4,6 +4,7 @@
${MACHINE_ARCH} == "amd64" || \
${MACHINE_ARCH} == "i386" || \
(${MACHINE} == "arm" && ${MACHINE_ARCH:Marm*eb*} == "") || \
+ ${MACHINE_CPUARCH} == "riscv" || \
${MACHINE_ARCH:Mmips*el} != ""
TARGET_ENDIANNESS= 1234
.elif ${MACHINE_ARCH} == "powerpc" || \
diff --git a/share/mk/bsd.opts.mk b/share/mk/bsd.opts.mk
index 3c27322..e2c56ac 100644
--- a/share/mk/bsd.opts.mk
+++ b/share/mk/bsd.opts.mk
@@ -104,6 +104,8 @@ MK_${var}:=no
MK_STALE_STAGED= no
.endif
+.include <bsd.cpu.mk>
+
.endif # !_WITHOUT_SRCCONF
.endif
diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk
index 1b0ee8f..8091826 100644
--- a/share/mk/bsd.sys.mk
+++ b/share/mk/bsd.sys.mk
@@ -109,6 +109,11 @@ CWARNFLAGS+= -Werror
CWARNFLAGS+= -Wno-format
.endif # NO_WFORMAT || NO_WFORMAT.${COMPILER_TYPE}
+# GCC 5.2.0
+.if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 50200
+CWARNFLAGS+= -Wno-error=unused-function -Wno-error=enum-compare -Wno-error=logical-not-parentheses -Wno-error=bool-compare -Wno-error=uninitialized -Wno-error=array-bounds -Wno-error=clobbered -Wno-error=cast-align -Wno-error=extra -Wno-error=attributes -Wno-error=inline -Wno-error=unused-but-set-variable -Wno-error=unused-value -Wno-error=strict-aliasing -Wno-error=address
+.endif
+
# How to handle FreeBSD custom printf format specifiers.
.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 30600
FORMAT_EXTENSIONS= -D__printf__=__freebsd_kprintf__
diff --git a/share/mk/local.dirdeps.mk b/share/mk/local.dirdeps.mk
index a24d012..3e08830 100644
--- a/share/mk/local.dirdeps.mk
+++ b/share/mk/local.dirdeps.mk
@@ -97,6 +97,8 @@ _have_depfile=
.endif
.endfor
.if !defined(_have_depfile)
+# KMOD does not use any stdlibs.
+.if !defined(KMOD)
# Has C files. The C_DIRDEPS are shared with C++ files as well.
C_DIRDEPS= \
gnu/lib/csu \
@@ -121,7 +123,8 @@ DIRDEPS+= gnu/lib/libstdc++ gnu/lib/libsupc++
.endif
# XXX: Clang and GCC always adds -lm currently, even when not needed.
DIRDEPS+= lib/msun
-.endif
+.endif # CXX
+.endif # !defined(KMOD)
# Has yacc files.
.if !empty(SRCS:M*.y)
DIRDEPS+= usr.bin/yacc.host
diff --git a/share/mk/local.meta.sys.mk b/share/mk/local.meta.sys.mk
index a97f6f2..1aa749a 100644
--- a/share/mk/local.meta.sys.mk
+++ b/share/mk/local.meta.sys.mk
@@ -48,13 +48,14 @@ TARGET_ARCHES_arm64?= aarch64
TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipsn32el
TARGET_ARCHES_powerpc?= powerpc powerpc64
TARGET_ARCHES_pc98?= i386
+TARGET_ARCHES_riscv?= riscv64
# some corner cases
BOOT_MACHINE_DIR.amd64 = boot/i386
MACHINE_ARCH.host = ${_HOST_ARCH}
# the list of machines we support
-ALL_MACHINE_LIST?= amd64 arm arm64 i386 mips pc98 powerpc sparc64
+ALL_MACHINE_LIST?= amd64 arm arm64 i386 mips pc98 powerpc riscv sparc64
.for m in ${ALL_MACHINE_LIST:O:u}
MACHINE_ARCH_LIST.$m?= ${TARGET_ARCHES_${m}:U$m}
MACHINE_ARCH.$m?= ${MACHINE_ARCH_LIST.$m:[1]}
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
index 094019d..f94e63a 100644
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -229,12 +229,17 @@ __DEFAULT_YES_OPTIONS+=GCC GCC_BOOTSTRAP GNUCXX
__DEFAULT_NO_OPTIONS+=CLANG CLANG_BOOTSTRAP CLANG_FULL CLANG_IS_CC
.endif
# In-tree binutils/gcc are older versions without modern architecture support.
-.if ${__T} == "aarch64"
+.if ${__T} == "aarch64" || ${__T} == "riscv64"
BROKEN_OPTIONS+=BINUTILS BINUTILS_BOOTSTRAP GCC GCC_BOOTSTRAP GDB
__DEFAULT_YES_OPTIONS+=ELFCOPY_AS_OBJCOPY
.else
__DEFAULT_NO_OPTIONS+=ELFCOPY_AS_OBJCOPY
.endif
+.if ${__T} == "riscv64"
+BROKEN_OPTIONS+=PROFILE # "sorry, unimplemented: profiler support for RISC-V"
+BROKEN_OPTIONS+=TESTS # "undefined reference to `_Unwind_Resume'"
+BROKEN_OPTIONS+=CXX # "libcxxrt.so: undefined reference to `_Unwind_Resume_or_Rethrow'"
+.endif
# LLVM lacks support for FreeBSD 64-bit atomic operations for ARMv4/ARMv5
.if ${__T} == "arm" || ${__T} == "armeb"
BROKEN_OPTIONS+=LLDB
diff --git a/share/mk/sys.mk b/share/mk/sys.mk
index 68d2db3..8fe6b68 100644
--- a/share/mk/sys.mk
+++ b/share/mk/sys.mk
@@ -13,7 +13,7 @@ unix ?= We run FreeBSD, not UNIX.
# and/or endian. This is called MACHINE_CPU in NetBSD, but that's used
# for something different in FreeBSD.
#
-MACHINE_CPUARCH=${MACHINE_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc64/powerpc/}
+MACHINE_CPUARCH=${MACHINE_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc64/powerpc/:C/riscv64/riscv/}
.endif
@@ -406,6 +406,15 @@ __MAKE_SHELL?=/bin/sh
path=${__MAKE_SHELL}
.endif
+# Hack for ports compatibility. Historically, ports makefiles have
+# assumed they can examine MACHINE_CPU without including anything
+# because this was automatically included in sys.mk. For /usr/src,
+# this file has moved to being included from bsd.opts.mk. Until all
+# the ports files are modernized, and a reasonable transition
+# period has passed, include it while we're in a ports tree here
+# to preserve historic behavior.
+.if exists(${.CURDIR}/../../Mk/bsd.port.mk)
.include <bsd.cpu.mk>
+.endif
.endif # ! Posix
diff --git a/sys/arm64/arm64/gic.c b/sys/arm64/arm64/gic.c
index 7c0692e..7ac88f3 100644
--- a/sys/arm64/arm64/gic.c
+++ b/sys/arm64/arm64/gic.c
@@ -47,10 +47,14 @@ __FBSDID("$FreeBSD$");
#include <sys/cpuset.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+
#include <machine/bus.h>
#include <machine/intr.h>
#include <machine/smp.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
#include <arm64/arm64/gic.h>
#include "pic_if.h"
@@ -153,7 +157,7 @@ gic_init_secondary(device_t dev)
}
#endif
-static int
+int
arm_gic_attach(device_t dev)
{
struct arm_gic_softc *sc;
@@ -344,3 +348,116 @@ static device_method_t arm_gic_methods[] = {
DEFINE_CLASS_0(gic, arm_gic_driver, arm_gic_methods,
sizeof(struct arm_gic_softc));
+
+#define GICV2M_MSI_TYPER 0x008
+#define MSI_TYPER_SPI_BASE(x) (((x) >> 16) & 0x3ff)
+#define MSI_TYPER_SPI_COUNT(x) (((x) >> 0) & 0x3ff)
+#define GICv2M_MSI_SETSPI_NS 0x040
+#define GICV2M_MSI_IIDR 0xFCC
+
+struct gicv2m_softc {
+ struct resource *sc_mem;
+ struct mtx sc_mutex;
+ u_int sc_spi_start;
+ u_int sc_spi_count;
+ u_int sc_spi_offset;
+};
+
+static int
+gicv2m_probe(device_t dev)
+{
+
+ device_set_desc(dev, "ARM Generic Interrupt Controller MSI/MSIX");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+gicv2m_attach(device_t dev)
+{
+ struct gicv2m_softc *sc;
+ uint32_t typer;
+ int rid;
+
+ sc = device_get_softc(dev);
+
+ rid = 0;
+ sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+ if (sc->sc_mem == NULL) {
+ device_printf(dev, "Unable to allocate resources\n");
+ return (ENXIO);
+ }
+
+ typer = bus_read_4(sc->sc_mem, GICV2M_MSI_TYPER);
+ sc->sc_spi_start = MSI_TYPER_SPI_BASE(typer);
+ sc->sc_spi_count = MSI_TYPER_SPI_COUNT(typer);
+
+ device_printf(dev, "using spi %u to %u\n", sc->sc_spi_start,
+ sc->sc_spi_start + sc->sc_spi_count - 1);
+
+ mtx_init(&sc->sc_mutex, "GICv2m lock", "", MTX_DEF);
+
+ arm_register_msi_pic(dev);
+
+ return (0);
+}
+
+static int
+gicv2m_alloc_msix(device_t dev, device_t pci_dev, int *pirq)
+{
+ struct arm_gic_softc *psc;
+ struct gicv2m_softc *sc;
+ uint32_t reg;
+ int irq;
+
+ psc = device_get_softc(device_get_parent(dev));
+ sc = device_get_softc(dev);
+
+ mtx_lock(&sc->sc_mutex);
+ /* Find an unused interrupt */
+ KASSERT(sc->sc_spi_offset < sc->sc_spi_count, ("No free SPIs"));
+
+ irq = sc->sc_spi_start + sc->sc_spi_offset;
+ sc->sc_spi_offset++;
+
+ /* Interrupts need to be edge triggered, set this */
+ reg = gic_d_read_4(psc, GICD_ICFGR(irq >> 4));
+ reg |= (GICD_ICFGR_TRIG_EDGE | GICD_ICFGR_POL_HIGH) <<
+ ((irq & 0xf) * 2);
+ gic_d_write_4(psc, GICD_ICFGR(irq >> 4), reg);
+
+ *pirq = irq;
+ mtx_unlock(&sc->sc_mutex);
+
+ return (0);
+}
+
+static int
+gicv2m_map_msi(device_t dev, device_t pci_dev, int irq, uint64_t *addr,
+ uint32_t *data)
+{
+ struct gicv2m_softc *sc = device_get_softc(dev);
+
+ *addr = vtophys(rman_get_virtual(sc->sc_mem)) + 0x40;
+ *data = irq;
+
+ return (0);
+}
+
+static device_method_t arm_gicv2m_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, gicv2m_probe),
+ DEVMETHOD(device_attach, gicv2m_attach),
+
+ /* MSI-X */
+ DEVMETHOD(pic_alloc_msix, gicv2m_alloc_msix),
+ DEVMETHOD(pic_map_msi, gicv2m_map_msi),
+
+ { 0, 0 }
+};
+
+static devclass_t arm_gicv2m_devclass;
+
+DEFINE_CLASS_0(gicv2m, arm_gicv2m_driver, arm_gicv2m_methods,
+ sizeof(struct gicv2m_softc));
+EARLY_DRIVER_MODULE(gicv2m, gic, arm_gicv2m_driver, arm_gicv2m_devclass,
+ 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
diff --git a/sys/arm64/arm64/gic.h b/sys/arm64/arm64/gic.h
index 2660884..a8f1c25 100644
--- a/sys/arm64/arm64/gic.h
+++ b/sys/arm64/arm64/gic.h
@@ -51,4 +51,6 @@ struct arm_gic_softc {
uint32_t nirqs;
};
+int arm_gic_attach(device_t);
+
#endif
diff --git a/sys/arm64/arm64/gic_fdt.c b/sys/arm64/arm64/gic_fdt.c
index 6c9338a..a4c4e25 100644
--- a/sys/arm64/arm64/gic_fdt.c
+++ b/sys/arm64/arm64/gic_fdt.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/rman.h>
#include <machine/bus.h>
@@ -56,6 +57,68 @@ static struct ofw_compat_data compat_data[] = {
{NULL, false}
};
+struct gic_range {
+ uint64_t bus;
+ uint64_t host;
+ uint64_t size;
+};
+
+struct arm_gic_fdt_softc {
+ struct arm_gic_softc sc_gic;
+ pcell_t sc_host_cells;
+ pcell_t sc_addr_cells;
+ pcell_t sc_size_cells;
+ struct gic_range *sc_ranges;
+ int sc_nranges;
+};
+
+struct gic_devinfo {
+ struct ofw_bus_devinfo obdinfo;
+ struct resource_list rl;
+};
+
+static int
+gic_fill_ranges(phandle_t node, struct arm_gic_fdt_softc *sc)
+{
+ cell_t *base_ranges;
+ ssize_t nbase_ranges;
+ int i, j, k;
+
+ nbase_ranges = OF_getproplen(node, "ranges");
+ if (nbase_ranges < 0)
+ return (-1);
+ sc->sc_nranges = nbase_ranges / sizeof(cell_t) /
+ (sc->sc_addr_cells + sc->sc_host_cells + sc->sc_size_cells);
+ if (sc->sc_nranges == 0)
+ return (0);
+
+ sc->sc_ranges = malloc(sc->sc_nranges * sizeof(sc->sc_ranges[0]),
+ M_DEVBUF, M_WAITOK);
+ base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
+ OF_getencprop(node, "ranges", base_ranges, nbase_ranges);
+
+ for (i = 0, j = 0; i < sc->sc_nranges; i++) {
+ sc->sc_ranges[i].bus = 0;
+ for (k = 0; k < sc->sc_addr_cells; k++) {
+ sc->sc_ranges[i].bus <<= 32;
+ sc->sc_ranges[i].bus |= base_ranges[j++];
+ }
+ sc->sc_ranges[i].host = 0;
+ for (k = 0; k < sc->sc_host_cells; k++) {
+ sc->sc_ranges[i].host <<= 32;
+ sc->sc_ranges[i].host |= base_ranges[j++];
+ }
+ sc->sc_ranges[i].size = 0;
+ for (k = 0; k < sc->sc_size_cells; k++) {
+ sc->sc_ranges[i].size <<= 32;
+ sc->sc_ranges[i].size |= base_ranges[j++];
+ }
+ }
+
+ free(base_ranges, M_DEVBUF);
+ return (sc->sc_nranges);
+}
+
static int
arm_gic_fdt_probe(device_t dev)
{
@@ -70,15 +133,156 @@ arm_gic_fdt_probe(device_t dev)
return (BUS_PROBE_DEFAULT);
}
+static int
+arm_gic_fdt_attach(device_t dev)
+{
+ struct arm_gic_fdt_softc *sc = device_get_softc(dev);
+ phandle_t root, child;
+ struct gic_devinfo *dinfo;
+ device_t cdev;
+ int err;
+
+ err = arm_gic_attach(dev);
+ if (err != 0)
+ return (err);
+
+ root = ofw_bus_get_node(dev);
+
+ sc->sc_host_cells = 1;
+ OF_getencprop(OF_parent(root), "#address-cells", &sc->sc_host_cells,
+ sizeof(sc->sc_host_cells));
+ sc->sc_addr_cells = 2;
+ OF_getencprop(root, "#address-cells", &sc->sc_addr_cells,
+ sizeof(sc->sc_addr_cells));
+ sc->sc_size_cells = 2;
+ OF_getencprop(root, "#size-cells", &sc->sc_size_cells,
+ sizeof(sc->sc_size_cells));
+
+ if (gic_fill_ranges(root, sc) < 0) {
+ device_printf(dev, "could not get ranges\n");
+ return (ENXIO);
+ }
+
+ for (child = OF_child(root); child != 0; child = OF_peer(child)) {
+ dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO);
+
+ if (ofw_bus_gen_setup_devinfo(&dinfo->obdinfo, child) != 0) {
+ free(dinfo, M_DEVBUF);
+ continue;
+ }
+
+ resource_list_init(&dinfo->rl);
+ ofw_bus_reg_to_rl(dev, child, sc->sc_addr_cells,
+ sc->sc_size_cells, &dinfo->rl);
+
+ cdev = device_add_child(dev, NULL, -1);
+ if (cdev == NULL) {
+ device_printf(dev, "<%s>: device_add_child failed\n",
+ dinfo->obdinfo.obd_name);
+ resource_list_free(&dinfo->rl);
+ ofw_bus_gen_destroy_devinfo(&dinfo->obdinfo);
+ free(dinfo, M_DEVBUF);
+ continue;
+ }
+ device_set_ivars(cdev, dinfo);
+ }
+
+ bus_generic_probe(dev);
+ return (bus_generic_attach(dev));
+}
+
+static struct resource *
+arm_gic_fdt_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct arm_gic_fdt_softc *sc = device_get_softc(bus);
+ struct gic_devinfo *di;
+ struct resource_list_entry *rle;
+ int j;
+
+ KASSERT(type == SYS_RES_MEMORY, ("Invalid resoure type %x", type));
+
+ /*
+ * Request for the default allocation with a given rid: use resource
+ * list stored in the local device info.
+ */
+ if ((start == 0UL) && (end == ~0UL)) {
+ if ((di = device_get_ivars(child)) == NULL)
+ return (NULL);
+
+ if (type == SYS_RES_IOPORT)
+ type = SYS_RES_MEMORY;
+
+ rle = resource_list_find(&di->rl, type, *rid);
+ if (rle == NULL) {
+ if (bootverbose)
+ device_printf(bus, "no default resources for "
+ "rid = %d, type = %d\n", *rid, type);
+ return (NULL);
+ }
+ start = rle->start;
+ end = rle->end;
+ count = rle->count;
+ }
+
+ /* Remap through ranges property */
+ for (j = 0; j < sc->sc_nranges; j++) {
+ if (start >= sc->sc_ranges[j].bus && end <
+ sc->sc_ranges[j].bus + sc->sc_ranges[j].size) {
+ start -= sc->sc_ranges[j].bus;
+ start += sc->sc_ranges[j].host;
+ end -= sc->sc_ranges[j].bus;
+ end += sc->sc_ranges[j].host;
+ break;
+ }
+ }
+ if (j == sc->sc_nranges && sc->sc_nranges != 0) {
+ if (bootverbose)
+ device_printf(bus, "Could not map resource "
+ "%#lx-%#lx\n", start, end);
+
+ return (NULL);
+ }
+
+ return (bus_generic_alloc_resource(bus, child, type, rid, start, end,
+ count, flags));
+}
+
+static const struct ofw_bus_devinfo *
+arm_gic_fdt_ofw_get_devinfo(device_t bus __unused, device_t child)
+{
+ struct gic_devinfo *di;
+
+ di = device_get_ivars(child);
+
+ return (&di->obdinfo);
+}
+
+
static device_method_t arm_gic_fdt_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, arm_gic_fdt_probe),
+ DEVMETHOD(device_attach, arm_gic_fdt_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_add_child, bus_generic_add_child),
+ DEVMETHOD(bus_alloc_resource, arm_gic_fdt_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource,bus_generic_activate_resource),
+
+ /* ofw_bus interface */
+ DEVMETHOD(ofw_bus_get_devinfo, arm_gic_fdt_ofw_get_devinfo),
+ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
+ DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
+ DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
+ DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
+ DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
DEVMETHOD_END
};
DEFINE_CLASS_1(gic, arm_gic_fdt_driver, arm_gic_fdt_methods,
- sizeof(struct arm_gic_softc), arm_gic_driver);
+ sizeof(struct arm_gic_fdt_softc), arm_gic_driver);
static devclass_t arm_gic_fdt_devclass;
diff --git a/sys/arm64/arm64/gic_v3_its.c b/sys/arm64/arm64/gic_v3_its.c
index 4903a51..1200f9c 100644
--- a/sys/arm64/arm64/gic_v3_its.c
+++ b/sys/arm64/arm64/gic_v3_its.c
@@ -74,10 +74,9 @@ static device_method_t gic_v3_its_methods[] = {
*/
/* MSI-X */
DEVMETHOD(pic_alloc_msix, gic_v3_its_alloc_msix),
- DEVMETHOD(pic_map_msix, gic_v3_its_map_msix),
/* MSI */
DEVMETHOD(pic_alloc_msi, gic_v3_its_alloc_msi),
- DEVMETHOD(pic_map_msi, gic_v3_its_map_msix),
+ DEVMETHOD(pic_map_msi, gic_v3_its_map_msi),
/* End */
DEVMETHOD_END
@@ -1658,7 +1657,7 @@ gic_v3_its_alloc_msi(device_t dev, device_t pci_dev, int count, int *irqs)
}
int
-gic_v3_its_map_msix(device_t dev, device_t pci_dev, int irq, uint64_t *addr,
+gic_v3_its_map_msi(device_t dev, device_t pci_dev, int irq, uint64_t *addr,
uint32_t *data)
{
struct gic_v3_its_softc *sc;
diff --git a/sys/arm64/arm64/gic_v3_var.h b/sys/arm64/arm64/gic_v3_var.h
index 7bcd068..8ebd144 100644
--- a/sys/arm64/arm64/gic_v3_var.h
+++ b/sys/arm64/arm64/gic_v3_var.h
@@ -253,7 +253,7 @@ int gic_v3_its_detach(device_t);
int gic_v3_its_alloc_msix(device_t, device_t, int *);
int gic_v3_its_alloc_msi(device_t, device_t, int, int *);
-int gic_v3_its_map_msix(device_t, device_t, int, uint64_t *, uint32_t *);
+int gic_v3_its_map_msi(device_t, device_t, int, uint64_t *, uint32_t *);
int its_init_cpu(struct gic_v3_its_softc *);
diff --git a/sys/arm64/arm64/intr_machdep.c b/sys/arm64/arm64/intr_machdep.c
index 7c383ee..e297ff9 100644
--- a/sys/arm64/arm64/intr_machdep.c
+++ b/sys/arm64/arm64/intr_machdep.c
@@ -217,48 +217,41 @@ arm_register_msi_pic(device_t dev)
}
int
-arm_alloc_msi(device_t pci_dev, int count, int *irqs)
+arm_alloc_msi(device_t pci, device_t child, int count, int maxcount, int *irqs)
{
- return PIC_ALLOC_MSI(msi_pic, pci_dev, count, irqs);
+ return (PIC_ALLOC_MSI(msi_pic, child, count, irqs));
}
int
-arm_release_msi(device_t pci_dev, int count, int *irqs)
+arm_release_msi(device_t pci, device_t child, int count, int *irqs)
{
- return PIC_RELEASE_MSI(msi_pic, pci_dev, count, irqs);
+ return (PIC_RELEASE_MSI(msi_pic, child, count, irqs));
}
int
-arm_map_msi(device_t pci_dev, int irq, uint64_t *addr, uint32_t *data)
+arm_map_msi(device_t pci, device_t child, int irq, uint64_t *addr, uint32_t *data)
{
- return PIC_MAP_MSI(msi_pic, pci_dev, irq, addr, data);
+ return (PIC_MAP_MSI(msi_pic, child, irq, addr, data));
}
int
-arm_alloc_msix(device_t pci_dev, int *irq)
+arm_alloc_msix(device_t pci, device_t child, int *irq)
{
- return PIC_ALLOC_MSIX(msi_pic, pci_dev, irq);
+ return (PIC_ALLOC_MSIX(msi_pic, child, irq));
}
int
-arm_release_msix(device_t pci_dev, int irq)
+arm_release_msix(device_t pci, device_t child, int irq)
{
- return PIC_RELEASE_MSIX(msi_pic, pci_dev, irq);
+ return (PIC_RELEASE_MSIX(msi_pic, child, irq));
}
-int
-arm_map_msix(device_t pci_dev, int irq, uint64_t *addr, uint32_t *data)
-{
-
- return PIC_MAP_MSIX(msi_pic, pci_dev, irq, addr, data);
-}
-
/*
* Finalize interrupts bring-up (should be called from configure_final()).
* Enables all interrupts registered by bus_setup_intr() during boot
diff --git a/sys/arm64/arm64/pic_if.m b/sys/arm64/arm64/pic_if.m
index f05c31b..fe358c6 100644
--- a/sys/arm64/arm64/pic_if.m
+++ b/sys/arm64/arm64/pic_if.m
@@ -158,14 +158,6 @@ METHOD int map_msi {
uint32_t *data;
};
-METHOD int map_msix {
- device_t dev;
- device_t pci_dev;
- int irq;
- uint64_t *addr;
- uint32_t *data;
-};
-
METHOD int release_msi {
device_t dev;
device_t pci_dev;
diff --git a/sys/arm64/cavium/thunder_pcie.c b/sys/arm64/cavium/thunder_pcie.c
index 1108d15..8abdacd 100644
--- a/sys/arm64/cavium/thunder_pcie.c
+++ b/sys/arm64/cavium/thunder_pcie.c
@@ -571,11 +571,12 @@ static device_method_t thunder_pcie_methods[] = {
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
- DEVMETHOD(pcib_map_msi, thunder_common_map_msi),
- DEVMETHOD(pcib_alloc_msix, thunder_common_alloc_msix),
- DEVMETHOD(pcib_release_msix, thunder_common_release_msix),
- DEVMETHOD(pcib_alloc_msi, thunder_common_alloc_msi),
- DEVMETHOD(pcib_release_msi, thunder_common_release_msi),
+
+ DEVMETHOD(pcib_map_msi, arm_map_msi),
+ DEVMETHOD(pcib_alloc_msix, arm_alloc_msix),
+ DEVMETHOD(pcib_release_msix, arm_release_msix),
+ DEVMETHOD(pcib_alloc_msi, arm_alloc_msi),
+ DEVMETHOD(pcib_release_msi, arm_release_msi),
DEVMETHOD_END
};
diff --git a/sys/arm64/cavium/thunder_pcie_common.c b/sys/arm64/cavium/thunder_pcie_common.c
index e3e75f3..59c383f 100644
--- a/sys/arm64/cavium/thunder_pcie_common.c
+++ b/sys/arm64/cavium/thunder_pcie_common.c
@@ -42,54 +42,6 @@ __FBSDID("$FreeBSD$");
#include "thunder_pcie_common.h"
-
-int
-thunder_common_map_msi(device_t pcib, device_t child, int irq,
- uint64_t *addr, uint32_t *data)
-{
- int error;
-
- error = arm_map_msix(child, irq, addr, data);
- return (error);
-}
-
-int
-thunder_common_alloc_msix(device_t pcib, device_t child, int *irq)
-{
- int error;
-
- error = arm_alloc_msix(child, irq);
- return (error);
-}
-
-int
-thunder_common_release_msix(device_t pcib, device_t child, int irq)
-{
- int error;
-
- error = arm_release_msix(child, irq);
- return (error);
-}
-
-int
-thunder_common_alloc_msi(device_t pcib, device_t child, int count, int maxcount,
- int *irqs)
-{
- int error;
-
- error = arm_alloc_msi(child, count, irqs);
- return (error);
-}
-
-int
-thunder_common_release_msi(device_t pcib, device_t child, int count, int *irqs)
-{
- int error;
-
- error = arm_release_msi(child, count, irqs);
- return (error);
-}
-
uint32_t
range_addr_is_pci(struct pcie_range *ranges, uint64_t addr, uint64_t size)
{
diff --git a/sys/arm64/cavium/thunder_pcie_pem.c b/sys/arm64/cavium/thunder_pcie_pem.c
index f36057b..9ea3f77 100644
--- a/sys/arm64/cavium/thunder_pcie_pem.c
+++ b/sys/arm64/cavium/thunder_pcie_pem.c
@@ -165,11 +165,12 @@ static device_method_t thunder_pem_methods[] = {
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
- DEVMETHOD(pcib_map_msi, thunder_common_map_msi),
- DEVMETHOD(pcib_alloc_msix, thunder_common_alloc_msix),
- DEVMETHOD(pcib_release_msix, thunder_common_release_msix),
- DEVMETHOD(pcib_alloc_msi, thunder_common_alloc_msi),
- DEVMETHOD(pcib_release_msi, thunder_common_release_msi),
+
+ DEVMETHOD(pcib_map_msi, arm_map_msi),
+ DEVMETHOD(pcib_alloc_msix, arm_alloc_msix),
+ DEVMETHOD(pcib_release_msix, arm_release_msix),
+ DEVMETHOD(pcib_alloc_msi, arm_alloc_msi),
+ DEVMETHOD(pcib_release_msi, arm_release_msi),
DEVMETHOD_END
};
diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC
index 01ec144..2e7fe8d 100644
--- a/sys/arm64/conf/GENERIC
+++ b/sys/arm64/conf/GENERIC
@@ -99,11 +99,12 @@ device pci
options PCI_IOV # PCI SR-IOV support
# Ethernet NICs
-device vnic # Cavium ThunderX NIC
-device em # Intel PRO/1000 Gigabit Ethernet Family
-device igb # Intel PRO/1000 PCIE Server Gigabit Family
device mii
device miibus # MII bus support
+device em # Intel PRO/1000 Gigabit Ethernet Family
+device igb # Intel PRO/1000 PCIE Server Gigabit Family
+device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet
+device vnic # Cavium ThunderX NIC
# Block devices
device ahci
diff --git a/sys/arm64/include/intr.h b/sys/arm64/include/intr.h
index 1031c64..067c69b 100644
--- a/sys/arm64/include/intr.h
+++ b/sys/arm64/include/intr.h
@@ -36,12 +36,12 @@ int arm_enable_intr(void);
void arm_mask_irq(u_int);
void arm_register_root_pic(device_t, u_int);
void arm_register_msi_pic(device_t);
-int arm_alloc_msi(device_t, int, int *);
-int arm_release_msi(device_t, int, int *);
-int arm_alloc_msix(device_t, int *);
-int arm_release_msix(device_t, int);
-int arm_map_msi(device_t, int, uint64_t *, uint32_t *);
-int arm_map_msix(device_t, int, uint64_t *, uint32_t *);
+int arm_alloc_msi(device_t, device_t, int, int, int *);
+int arm_release_msi(device_t, device_t, int, int *);
+int arm_alloc_msix(device_t, device_t, int *);
+int arm_release_msix(device_t, device_t, int);
+int arm_map_msi(device_t, device_t, int, uint64_t *, uint32_t *);
+int arm_map_msix(device_t, device_t, int, uint64_t *, uint32_t *);
int arm_setup_intr(const char *, driver_filter_t *, driver_intr_t,
void *, u_int, enum intr_type, void **);
int arm_teardown_intr(void *);
diff --git a/sys/boot/common/part.c b/sys/boot/common/part.c
index f978663..8638f02 100644
--- a/sys/boot/common/part.c
+++ b/sys/boot/common/part.c
@@ -301,12 +301,12 @@ ptable_gptread(struct ptable *table, void *dev, diskread_t dread)
}
}
}
- DEBUG("GPT detected");
if (pri == 0 && sec == 0) {
/* Both primary and backup tables are invalid. */
table->type = PTABLE_NONE;
goto out;
}
+ DEBUG("GPT detected");
size = MIN(hdr.hdr_entries * hdr.hdr_entsz,
MAXTBLSZ * table->sectorsize);
for (i = 0; i < size / hdr.hdr_entsz; i++) {
@@ -635,6 +635,11 @@ ptable_open(void *dev, off_t sectors, uint16_t sectorsize,
if (buf[DOSMAGICOFFSET] != 0x55 ||
buf[DOSMAGICOFFSET + 1] != 0xaa) {
DEBUG("magic sequence not found");
+#if defined(LOADER_GPT_SUPPORT)
+ /* There is no PMBR, check that we have backup GPT */
+ table->type = PTABLE_GPT;
+ table = ptable_gptread(table, dev, dread);
+#endif
goto out;
}
/* Check that we have PMBR. Also do some validation. */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
index 848340c..5491442 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
@@ -206,14 +206,12 @@ vdev_geom_detach(void *arg, int flag __unused)
}
}
-static uint64_t
-nvlist_get_guid(nvlist_t *list)
+static void
+nvlist_get_guids(nvlist_t *list, uint64_t *pguid, uint64_t *vguid)
{
- uint64_t value;
- value = 0;
- nvlist_lookup_uint64(list, ZPOOL_CONFIG_GUID, &value);
- return (value);
+ nvlist_lookup_uint64(list, ZPOOL_CONFIG_GUID, vguid);
+ nvlist_lookup_uint64(list, ZPOOL_CONFIG_POOL_GUID, pguid);
}
static int
@@ -268,7 +266,7 @@ vdev_geom_read_config(struct g_consumer *cp, nvlist_t **config)
size_t buflen;
uint64_t psize;
off_t offset, size;
- uint64_t guid, state, txg;
+ uint64_t state, txg;
int error, l, len;
g_topology_assert_not();
@@ -282,7 +280,6 @@ vdev_geom_read_config(struct g_consumer *cp, nvlist_t **config)
size = sizeof(*label) + pp->sectorsize -
((sizeof(*label) - 1) % pp->sectorsize) - 1;
- guid = 0;
label = kmem_alloc(size, KM_SLEEP);
buflen = sizeof(label->vl_vdev_phys.vp_nvlist);
@@ -477,30 +474,29 @@ vdev_geom_read_pool_label(const char *name,
return (*count > 0 ? 0 : ENOENT);
}
-static uint64_t
-vdev_geom_read_guid(struct g_consumer *cp)
+static void
+vdev_geom_read_guids(struct g_consumer *cp, uint64_t *pguid, uint64_t *vguid)
{
nvlist_t *config;
- uint64_t guid;
g_topology_assert_not();
- guid = 0;
+ *pguid = 0;
+ *vguid = 0;
if (vdev_geom_read_config(cp, &config) == 0) {
- guid = nvlist_get_guid(config);
+ nvlist_get_guids(config, pguid, vguid);
nvlist_free(config);
}
- return (guid);
}
static struct g_consumer *
-vdev_geom_attach_by_guid(uint64_t guid)
+vdev_geom_attach_by_guids(uint64_t pool_guid, uint64_t vdev_guid)
{
struct g_class *mp;
struct g_geom *gp, *zgp;
struct g_provider *pp;
struct g_consumer *cp, *zcp;
- uint64_t pguid;
+ uint64_t pguid, vguid;
g_topology_assert();
@@ -520,15 +516,15 @@ vdev_geom_attach_by_guid(uint64_t guid)
if (vdev_geom_attach_taster(zcp, pp) != 0)
continue;
g_topology_unlock();
- pguid = vdev_geom_read_guid(zcp);
+ vdev_geom_read_guids(zcp, &pguid, &vguid);
g_topology_lock();
vdev_geom_detach_taster(zcp);
- if (pguid != guid)
+ if (pguid != pool_guid || vguid != vdev_guid)
continue;
cp = vdev_geom_attach(pp);
if (cp == NULL) {
- printf("ZFS WARNING: Unable to attach to %s.\n",
- pp->name);
+ printf("ZFS WARNING: Unable to "
+ "attach to %s.\n", pp->name);
continue;
}
break;
@@ -546,7 +542,7 @@ end:
}
static struct g_consumer *
-vdev_geom_open_by_guid(vdev_t *vd)
+vdev_geom_open_by_guids(vdev_t *vd)
{
struct g_consumer *cp;
char *buf;
@@ -555,7 +551,7 @@ vdev_geom_open_by_guid(vdev_t *vd)
g_topology_assert();
ZFS_LOG(1, "Searching by guid [%ju].", (uintmax_t)vd->vdev_guid);
- cp = vdev_geom_attach_by_guid(vd->vdev_guid);
+ cp = vdev_geom_attach_by_guids(spa_guid(vd->vdev_spa), vd->vdev_guid);
if (cp != NULL) {
len = strlen(cp->provider->name) + strlen("/dev/") + 1;
buf = kmem_alloc(len, KM_SLEEP);
@@ -564,10 +560,12 @@ vdev_geom_open_by_guid(vdev_t *vd)
spa_strfree(vd->vdev_path);
vd->vdev_path = buf;
- ZFS_LOG(1, "Attach by guid [%ju] succeeded, provider %s.",
+ ZFS_LOG(1, "Attach by guid [%ju:%ju] succeeded, provider %s.",
+ (uintmax_t)spa_guid(vd->vdev_spa),
(uintmax_t)vd->vdev_guid, vd->vdev_path);
} else {
- ZFS_LOG(1, "Search by guid [%ju] failed.",
+ ZFS_LOG(1, "Search by guid [%ju:%ju] failed.",
+ (uintmax_t)spa_guid(vd->vdev_spa),
(uintmax_t)vd->vdev_guid);
}
@@ -579,7 +577,7 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid)
{
struct g_provider *pp;
struct g_consumer *cp;
- uint64_t guid;
+ uint64_t pguid, vguid;
g_topology_assert();
@@ -591,14 +589,17 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid)
if (cp != NULL && check_guid && ISP2(pp->sectorsize) &&
pp->sectorsize <= VDEV_PAD_SIZE) {
g_topology_unlock();
- guid = vdev_geom_read_guid(cp);
+ vdev_geom_read_guids(cp, &pguid, &vguid);
g_topology_lock();
- if (guid != vd->vdev_guid) {
+ if (pguid != spa_guid(vd->vdev_spa) ||
+ vguid != vd->vdev_guid) {
vdev_geom_detach(cp, 0);
cp = NULL;
ZFS_LOG(1, "guid mismatch for provider %s: "
- "%ju != %ju.", vd->vdev_path,
- (uintmax_t)vd->vdev_guid, (uintmax_t)guid);
+ "%ju:%ju != %ju:%ju.", vd->vdev_path,
+ (uintmax_t)spa_guid(vd->vdev_spa),
+ (uintmax_t)vd->vdev_guid,
+ (uintmax_t)pguid, (uintmax_t)vguid);
} else {
ZFS_LOG(1, "guid match for provider %s.",
vd->vdev_path);
@@ -632,23 +633,38 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
g_topology_lock();
error = 0;
- /*
- * If we're creating or splitting a pool, just find the GEOM provider
- * by its name and ignore GUID mismatches.
- */
- if (vd->vdev_spa->spa_load_state == SPA_LOAD_NONE ||
- vd->vdev_spa->spa_splitting_newspa == B_TRUE)
+ if (vd->vdev_spa->spa_splitting_newspa ||
+ (vd->vdev_prevstate == VDEV_STATE_UNKNOWN &&
+ vd->vdev_spa->spa_load_state == SPA_LOAD_NONE)) {
+ /*
+ * We are dealing with a vdev that hasn't been previously
+ * opened (since boot), and we are not loading an
+ * existing pool configuration. This looks like a
+ * vdev add operation to a new or existing pool.
+ * Assume the user knows what he/she is doing and find
+ * GEOM provider by its name, ignoring GUID mismatches.
+ *
+ * XXPOLICY: It would be safer to only allow a device
+ * that is unlabeled or labeled but missing
+ * GUID information to be opened in this fashion,
+ * unless we are doing a split, in which case we
+ * should allow any guid.
+ */
cp = vdev_geom_open_by_path(vd, 0);
- else {
+ } else {
+ /*
+ * Try using the recorded path for this device, but only
+ * accept it if its label data contains the expected GUIDs.
+ */
cp = vdev_geom_open_by_path(vd, 1);
if (cp == NULL) {
/*
* The device at vd->vdev_path doesn't have the
- * expected guid. The disks might have merely
+ * expected GUIDs. The disks might have merely
* moved around so try all other GEOM providers
- * to find one with the right guid.
+ * to find one with the right GUIDs.
*/
- cp = vdev_geom_open_by_guid(vd);
+ cp = vdev_geom_open_by_guids(vd);
}
}
diff --git a/sys/dev/aic/aic_pccard.c b/sys/dev/aic/aic_pccard.c
index 31ba257..ef6dd9e 100644
--- a/sys/dev/aic/aic_pccard.c
+++ b/sys/dev/aic/aic_pccard.c
@@ -196,3 +196,4 @@ extern devclass_t aic_devclass;
MODULE_DEPEND(aic, cam, 1,1,1);
DRIVER_MODULE(aic, pccard, aic_pccard_driver, aic_devclass, 0, 0);
+PCCARD_PNP_INFO(aic_pccard_products);
diff --git a/sys/dev/an/if_an_pccard.c b/sys/dev/an/if_an_pccard.c
index e9485ea..6f26d7a 100644
--- a/sys/dev/an/if_an_pccard.c
+++ b/sys/dev/an/if_an_pccard.c
@@ -108,6 +108,7 @@ static const struct pccard_product an_pccard_products[] = {
PCMCIA_CARD(XIRCOM, CWE1130),
{ NULL }
};
+PCCARD_PNP_INFO(an_pccard_products);
static int
an_pccard_probe(device_t dev)
diff --git a/sys/dev/ata/ata-card.c b/sys/dev/ata/ata-card.c
index 5346b8f..4b0a3d1 100644
--- a/sys/dev/ata/ata-card.c
+++ b/sys/dev/ata/ata-card.c
@@ -183,3 +183,4 @@ static driver_t ata_pccard_driver = {
DRIVER_MODULE(ata, pccard, ata_pccard_driver, ata_devclass, NULL, NULL);
MODULE_DEPEND(ata, ata, 1, 1, 1);
+PCCARD_PNP_INFO(ata_pccard_products);
diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
index 0746a8e..93996e2 100644
--- a/sys/dev/bwn/if_bwn.c
+++ b/sys/dev/bwn/if_bwn.c
@@ -2721,8 +2721,7 @@ bwn_updateslot(struct ieee80211com *ic)
BWN_LOCK(sc);
if (sc->sc_flags & BWN_FLAG_RUNNING) {
mac = (struct bwn_mac *)sc->sc_curmac;
- bwn_set_slot_time(mac,
- (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
+ bwn_set_slot_time(mac, IEEE80211_GET_SLOTTIME(ic));
}
BWN_UNLOCK(sc);
}
diff --git a/sys/dev/cmx/cmx_pccard.c b/sys/dev/cmx/cmx_pccard.c
index 32c4872..ebb57cc 100644
--- a/sys/dev/cmx/cmx_pccard.c
+++ b/sys/dev/cmx/cmx_pccard.c
@@ -112,4 +112,4 @@ static driver_t cmx_pccard_driver = {
};
DRIVER_MODULE(cmx, pccard, cmx_pccard_driver, cmx_devclass, 0, 0);
-
+PCCARD_PNP_INFO(cmx_pccard_products);
diff --git a/sys/dev/cs/if_cs_pccard.c b/sys/dev/cs/if_cs_pccard.c
index 575d7f0..645fbdd 100644
--- a/sys/dev/cs/if_cs_pccard.c
+++ b/sys/dev/cs/if_cs_pccard.c
@@ -56,6 +56,7 @@ static const struct pccard_product cs_pccard_products[] = {
PCMCIA_CARD(IBM, ETHERJET),
{ NULL }
};
+
static int
cs_pccard_probe(device_t dev)
{
@@ -115,3 +116,4 @@ extern devclass_t cs_devclass;
DRIVER_MODULE(cs, pccard, cs_pccard_driver, cs_devclass, 0, 0);
MODULE_DEPEND(cs, ether, 1, 1, 1);
+PCCARD_PNP_INFO(cs_pccard_products);
diff --git a/sys/dev/ed/if_ed_isa.c b/sys/dev/ed/if_ed_isa.c
index afaa377..7b1a6b7 100644
--- a/sys/dev/ed/if_ed_isa.c
+++ b/sys/dev/ed/if_ed_isa.c
@@ -201,3 +201,6 @@ static driver_t ed_isa_driver = {
DRIVER_MODULE(ed, isa, ed_isa_driver, ed_devclass, 0, 0);
MODULE_DEPEND(ed, isa, 1, 1, 1);
MODULE_DEPEND(ed, ether, 1, 1, 1);
+MODULE_PNP_INFO("E:pnpid;", isa, ed, ed_ids, sizeof(ed_ids[0]),
+ sizeof(ed_ids) / sizeof(ed_ids[0]) - 1);
+
diff --git a/sys/dev/ed/if_ed_pccard.c b/sys/dev/ed/if_ed_pccard.c
index 505aff6..07cf892 100644
--- a/sys/dev/ed/if_ed_pccard.c
+++ b/sys/dev/ed/if_ed_pccard.c
@@ -1248,3 +1248,4 @@ DRIVER_MODULE(ed, pccard, ed_pccard_driver, ed_devclass, 0, NULL);
DRIVER_MODULE(miibus, ed, miibus_driver, miibus_devclass, 0, NULL);
MODULE_DEPEND(ed, miibus, 1, 1, 1);
MODULE_DEPEND(ed, ether, 1, 1, 1);
+PCCARD_PNP_INFO(ed_pccard_products);
diff --git a/sys/dev/ed/if_ed_pci.c b/sys/dev/ed/if_ed_pci.c
index 3cf353c..31b9762 100644
--- a/sys/dev/ed/if_ed_pci.c
+++ b/sys/dev/ed/if_ed_pci.c
@@ -143,3 +143,6 @@ static driver_t ed_pci_driver = {
DRIVER_MODULE(ed, pci, ed_pci_driver, ed_devclass, 0, 0);
MODULE_DEPEND(ed, pci, 1, 1, 1);
MODULE_DEPEND(ed, ether, 1, 1, 1);
+MODULE_PNP_INFO("W32:vendor/device;D:human", pci, ed, pci_ids, sizeof(pci_ids[0]),
+ sizeof(pci_ids) / sizeof(pci_ids[0]) - 1);
+
diff --git a/sys/dev/ep/if_ep_pccard.c b/sys/dev/ep/if_ep_pccard.c
index 1b445f9..e0e680c 100644
--- a/sys/dev/ep/if_ep_pccard.c
+++ b/sys/dev/ep/if_ep_pccard.c
@@ -235,3 +235,4 @@ static driver_t ep_pccard_driver = {
extern devclass_t ep_devclass;
DRIVER_MODULE(ep, pccard, ep_pccard_driver, ep_devclass, 0, 0);
+PCCARD_PNP_INFO(ep_pccard_products);
diff --git a/sys/dev/ex/if_ex_pccard.c b/sys/dev/ex/if_ex_pccard.c
index 39fd6f6..6d13a72 100644
--- a/sys/dev/ex/if_ex_pccard.c
+++ b/sys/dev/ex/if_ex_pccard.c
@@ -228,3 +228,4 @@ static driver_t ex_pccard_driver = {
DRIVER_MODULE(ex, pccard, ex_pccard_driver, ex_devclass, 0, 0);
MODULE_DEPEND(ex, pccard, 1, 1, 1);
+PCCARD_PNP_INFO(ex_pccard_products);
diff --git a/sys/dev/fdc/fdc_pccard.c b/sys/dev/fdc/fdc_pccard.c
index d959060..6197dcd 100644
--- a/sys/dev/fdc/fdc_pccard.c
+++ b/sys/dev/fdc/fdc_pccard.c
@@ -139,3 +139,4 @@ static driver_t fdc_pccard_driver = {
};
DRIVER_MODULE(fdc, pccard, fdc_pccard_driver, fdc_devclass, 0, 0);
+PCCARD_PNP_INFO(fdc_pccard_products);
diff --git a/sys/dev/fdt/simplebus.c b/sys/dev/fdt/simplebus.c
index 4cf063e..4e5bdd2 100644
--- a/sys/dev/fdt/simplebus.c
+++ b/sys/dev/fdt/simplebus.c
@@ -304,6 +304,8 @@ simplebus_get_devinfo(device_t bus __unused, device_t child)
struct simplebus_devinfo *ndi;
ndi = device_get_ivars(child);
+ if (ndi == NULL)
+ return (NULL);
return (&ndi->obdinfo);
}
@@ -313,6 +315,8 @@ simplebus_get_resource_list(device_t bus __unused, device_t child)
struct simplebus_devinfo *ndi;
ndi = device_get_ivars(child);
+ if (ndi == NULL)
+ return (NULL);
return (&ndi->rl);
}
@@ -380,6 +384,8 @@ simplebus_print_res(struct simplebus_devinfo *di)
{
int rv;
+ if (di == NULL)
+ return (0);
rv = 0;
rv += resource_list_print_type(&di->rl, "mem", SYS_RES_MEMORY, "%#lx");
rv += resource_list_print_type(&di->rl, "irq", SYS_RES_IRQ, "%ld");
diff --git a/sys/dev/fe/if_fe_pccard.c b/sys/dev/fe/if_fe_pccard.c
index b7c644e..41f7e18 100644
--- a/sys/dev/fe/if_fe_pccard.c
+++ b/sys/dev/fe/if_fe_pccard.c
@@ -145,6 +145,7 @@ static driver_t fe_pccard_driver = {
DRIVER_MODULE(fe, pccard, fe_pccard_driver, fe_devclass, 0, 0);
MODULE_DEPEND(fe, pccard, 1, 1, 1);
+PCCARD_PNP_INFO(fe_pccard_products);
static int fe_probe_mbh(device_t, const struct fe_pccard_product *);
static int fe_probe_tdk(device_t, const struct fe_pccard_product *);
diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c
index 43bcea0..d26c965 100644
--- a/sys/dev/hwpmc/hwpmc_core.c
+++ b/sys/dev/hwpmc/hwpmc_core.c
@@ -634,20 +634,20 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(03H_10H, 0x03, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_SB |
IAP_F_SBX | IAP_F_CAS),
IAPDESCR(03H_20H, 0x03, 0x20, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_CAS),
- IAPDESCR(03H_40H, 0x03, 0x40, IAP_F_CAS),
- IAPDESCR(03H_80H, 0x03, 0x80, IAP_F_CAS),
+ IAPDESCR(03H_40H, 0x03, 0x40, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(03H_80H, 0x03, 0x80, IAP_F_FM | IAP_F_CAS),
IAPDESCR(04H_00H, 0x04, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CAS),
IAPDESCR(04H_01H, 0x04, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O |
IAP_F_CAS),
IAPDESCR(04H_02H, 0x04, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_CAS),
- IAPDESCR(04H_04H, 0x04, 0x04, IAP_F_CAS),
+ IAPDESCR(04H_04H, 0x04, 0x04, IAP_F_FM | IAP_F_CAS),
IAPDESCR(04H_07H, 0x04, 0x07, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(04H_08H, 0x04, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_CAS),
- IAPDESCR(04H_10H, 0x04, 0x10, IAP_F_CAS),
- IAPDESCR(04H_20H, 0x04, 0x20, IAP_F_CAS),
- IAPDESCR(04H_40H, 0x04, 0x40, IAP_F_CAS),
- IAPDESCR(04H_80H, 0x04, 0x80, IAP_F_CAS),
+ IAPDESCR(04H_10H, 0x04, 0x10, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(04H_20H, 0x04, 0x20, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(04H_40H, 0x04, 0x40, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(04H_80H, 0x04, 0x80, IAP_F_FM | IAP_F_CAS),
IAPDESCR(05H_00H, 0x05, 0x00, IAP_F_FM | IAP_F_CC),
IAPDESCR(05H_01H, 0x05, 0x01, IAP_F_FM | IAP_F_I7O | IAP_F_SB | IAP_F_IB |
@@ -690,7 +690,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(08H_08H, 0x08, 0x08, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(08H_09H, 0x08, 0x09, IAP_F_FM | IAP_F_CA),
IAPDESCR(08H_0EH, 0x08, 0x0E, IAP_F_FM | IAP_F_HW | IAP_F_HWX | IAP_F_SL),
- IAPDESCR(08H_10H, 0x08, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB |
+ IAPDESCR(08H_10H, 0x08, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB |
IAP_F_SBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
IAPDESCR(08H_20H, 0x08, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_HW |
IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
@@ -700,7 +700,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(08H_81H, 0x08, 0x81, IAP_F_FM | IAP_F_IB | IAP_F_IBX),
IAPDESCR(08H_82H, 0x08, 0x82, IAP_F_FM | IAP_F_IB | IAP_F_IBX),
IAPDESCR(08H_84H, 0x08, 0x84, IAP_F_FM | IAP_F_IB | IAP_F_IBX),
- IAPDESCR(08H_88H, 0x08, 0x88, IAP_F_IB | IAP_F_IBX),
+ IAPDESCR(08H_88H, 0x08, 0x88, IAP_F_FM | IAP_F_IB | IAP_F_IBX),
IAPDESCR(09H_01H, 0x09, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
IAPDESCR(09H_02H, 0x09, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 | IAP_F_I7O),
@@ -719,7 +719,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(0DH_03H, 0x0D, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_SBX | IAP_F_HW |
IAP_F_IB | IAP_F_IBX | IAP_F_HWX | IAP_F_BW | IAP_F_BWX),
IAPDESCR(0DH_40H, 0x0D, 0x40, IAP_F_FM | IAP_F_SB | IAP_F_SBX),
- IAPDESCR(0DH_80H, 0x0D, 0x00, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(0DH_80H, 0x0D, 0x80, IAP_F_FM | IAP_F_SL),
IAPDESCR(0EH_01H, 0x0E, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB |
IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX |
@@ -830,8 +830,8 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(24H_30H, 0x24, 0x30, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB |
IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX |
IAP_F_BW | IAP_F_BWX),
- IAPDESCR(24H_38H, 0x24, 0x00, IAP_F_FM | IAP_F_SL),
- IAPDESCR(24H_3FH, 0x24, 0x00, IAP_F_FM | IAP_F_HW | IAP_F_HWX | IAP_F_SL),
+ IAPDESCR(24H_38H, 0x24, 0x38, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(24H_3FH, 0x24, 0x3F, IAP_F_FM | IAP_F_HW | IAP_F_HWX | IAP_F_SL),
IAPDESCR(24H_40H, 0x24, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB |
IAP_F_IB | IAP_F_SBX | IAP_F_IBX),
IAPDESCR(24H_41H, 0x24, 0x41, IAP_F_FM | IAP_F_HW | IAP_F_HWX |
@@ -845,7 +845,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(24H_AAH, 0x24, 0xAA, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(24H_C0H, 0x24, 0xC0, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SB |
IAP_F_IB | IAP_F_SBX | IAP_F_IBX),
- IAPDESCR(24H_D8H, 0x24, 0x00, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(24H_D8H, 0x24, 0xD8, IAP_F_FM | IAP_F_SL),
IAPDESCR(24H_E1H, 0x24, 0xE1, IAP_F_FM | IAP_F_HW | IAP_F_HWX |
IAP_F_BW | IAP_F_BWX | IAP_F_SL),
IAPDESCR(24H_E2H, 0x24, 0xE2, IAP_F_FM | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX |
@@ -853,7 +853,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(24H_E4H, 0x24, 0xE4, IAP_F_FM | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX |
IAP_F_SL),
IAPDESCR(24H_E7H, 0x24, 0xE7, IAP_F_FM | IAP_F_HW | IAP_F_HWX | IAP_F_SL),
- IAPDESCR(24H_EFH, 0x24, 0x00, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(24H_EFH, 0x24, 0xEF, IAP_F_FM | IAP_F_SL),
IAPDESCR(24H_F8H, 0x24, 0xF8, IAP_F_FM | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX |
IAP_F_SL),
IAPDESCR(24H_FFH, 0x24, 0xFF, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_HW |
@@ -923,8 +923,8 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(30H, 0x30, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH,
IAP_F_ALLCPUSCORE2),
- IAPDESCR(30H_00H, 0x30, 0x00, IAP_F_CAS),
- IAPDESCR(31H_00H, 0x31, 0x00, IAP_F_CAS),
+ IAPDESCR(30H_00H, 0x30, 0x00, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(31H_00H, 0x31, 0x00, IAP_F_FM | IAP_F_CAS),
IAPDESCR(32H, 0x32, IAP_M_CORE | IAP_M_MESI | IAP_M_PREFETCH, IAP_F_CC),
IAPDESCR(32H, 0x32, IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
@@ -993,7 +993,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(49H_04H, 0x49, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX),
IAPDESCR(49H_0EH, 0x49, 0x0E, IAP_F_FM | IAP_F_HW | IAP_F_HWX | IAP_F_SL),
- IAPDESCR(49H_10H, 0x49, 0x1, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
+ IAPDESCR(49H_10H, 0x49, 0x10, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX |
IAP_F_BW | IAP_F_BWX | IAP_F_SL),
IAPDESCR(49H_20H, 0x49, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_HW | IAP_F_HWX |
@@ -1052,7 +1052,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(58H_08H, 0x58, 0x08, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW |
IAP_F_HWX | IAP_F_BW | IAP_F_BWX),
- IAPDESCR(59H_20H, 0x59, 0x1, IAP_F_SB | IAP_F_SBX),
+ IAPDESCR(59H_20H, 0x59, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_SBX),
IAPDESCR(59H_40H, 0x59, 0x40, IAP_F_FM | IAP_F_SB | IAP_F_SBX),
IAPDESCR(59H_80H, 0x59, 0x80, IAP_F_FM | IAP_F_SB | IAP_F_SBX),
@@ -1069,22 +1069,22 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(5EH_01H, 0x5E, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(5FH_01H, 0x5F, 0x01, IAP_F_FM | IAP_F_IB ), /* IB not in manual */
- IAPDESCR(5FH_04H, 0x5F, 0x04, IAP_F_IBX | IAP_F_IB),
+ IAPDESCR(5FH_01H, 0x5F, 0x01, IAP_F_FM | IAP_F_IB ), /* IB not in manual */
+ IAPDESCR(5FH_04H, 0x5F, 0x04, IAP_F_FM | IAP_F_IBX | IAP_F_IB),
IAPDESCR(60H, 0x60, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
IAPDESCR(60H_01H, 0x60, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O |
IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX |
IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(60H_02H, 0x60, 0x01, IAP_F_FM | IAP_F_WM | IAP_F_I7O | IAP_F_IB |
+ IAPDESCR(60H_02H, 0x60, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7O | IAP_F_IB |
IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(60H_04H, 0x60, 0x01, IAP_F_FM |IAP_F_I7O |
+ IAPDESCR(60H_04H, 0x60, 0x04, IAP_F_FM |IAP_F_I7O |
IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX |
IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(60H_08H, 0x60, 0x01, IAP_F_FM |IAP_F_I7O |
+ IAPDESCR(60H_08H, 0x60, 0x08, IAP_F_FM |IAP_F_I7O |
IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX |
IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(60H_10H, 0x7, 0x00, IAP_F_SL),
+ IAPDESCR(60H_10H, 0x60, 0x10, IAP_F_FM | IAP_F_SL),
IAPDESCR(61H, 0x61, IAP_M_AGENT, IAP_F_CA | IAP_F_CC2),
@@ -1114,7 +1114,6 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(67H, 0x67, IAP_M_AGENT | IAP_M_CORE, IAP_F_CA | IAP_F_CC2),
IAPDESCR(67H, 0x67, IAP_M_AGENT, IAP_F_CC),
-
IAPDESCR(68H, 0x68, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
IAPDESCR(69H, 0x69, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
IAPDESCR(6AH, 0x6A, IAP_M_AGENT | IAP_M_CORE, IAP_F_ALLCPUSCORE2),
@@ -1144,22 +1143,22 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(79H_02H, 0x79, 0x02, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX),
- IAPDESCR(79H_04H, 0x79, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB |
+ IAPDESCR(79H_04H, 0x79, 0x04, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(79H_08H, 0x79, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_IB |
+ IAPDESCR(79H_08H, 0x79, 0x08, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_SL | IAP_F_BW | IAP_F_BWX),
- IAPDESCR(79H_10H, 0x79, 0x1, IAP_F_FM | IAP_F_SB | IAP_F_IB |
+ IAPDESCR(79H_10H, 0x79, 0x10, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(79H_18H, 0x79, 0x01, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX |
+ IAPDESCR(79H_18H, 0x79, 0x18, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX |
IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(79H_20H, 0x79, 0x1, IAP_F_FM | IAP_F_SB | IAP_F_IB |
+ IAPDESCR(79H_20H, 0x79, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(79H_24H, 0x79, 0x01, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX |
+ IAPDESCR(79H_24H, 0x79, 0x24, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW | IAP_F_HWX |
IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(79H_30H, 0x79, 0x1, IAP_F_FM | IAP_F_SB | IAP_F_IB |
+ IAPDESCR(79H_30H, 0x79, 0x30, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
IAPDESCR(79H_3CH, 0x79, 0x3C, IAP_F_FM | IAP_F_IB | IAP_F_IBX | IAP_F_HW |
@@ -1243,7 +1242,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(88H_41H, 0x88, 0x41, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX),
IAPDESCR(88H_7FH, 0x88, 0x7F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(88H_80H, 0x88, 0x0, IAP_F_FM | IAP_F_BW | IAP_F_BWX),
+ IAPDESCR(88H_80H, 0x88, 0x80, IAP_F_FM | IAP_F_BW | IAP_F_BWX),
IAPDESCR(88H_81H, 0x88, 0x81, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX),
IAPDESCR(88H_82H, 0x88, 0x82, IAP_F_FM | IAP_F_SB | IAP_F_IB |
@@ -1272,7 +1271,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(89H_41H, 0x89, 0x41, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX),
IAPDESCR(89H_7FH, 0x89, 0x7F, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(89H_80H, 0x89, 0x0, IAP_F_FM | IAP_F_BW | IAP_F_BWX),
+ IAPDESCR(89H_80H, 0x89, 0x80, IAP_F_FM | IAP_F_BW | IAP_F_BWX),
IAPDESCR(89H_81H, 0x89, 0x81, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX),
IAPDESCR(89H_82H, 0x89, 0x82, IAP_F_FM | IAP_F_SB | IAP_F_IB |
@@ -1358,25 +1357,25 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(A2H_80H, 0xA2, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
IAP_F_SB | IAP_F_SBX),
- IAPDESCR(A3H_01H, 0xA3, 0x02, IAP_F_SBX | IAP_F_IBX | IAP_F_IB | IAP_F_HW |
+ IAPDESCR(A3H_01H, 0xA3, 0x01, IAP_F_FM | IAP_F_SBX | IAP_F_IBX | IAP_F_IB | IAP_F_HW |
IAP_F_HWX | IAP_F_SL),
- IAPDESCR(A3H_02H, 0xA3, 0x02, IAP_F_SBX | IAP_F_IBX | IAP_F_IB | IAP_F_HW |
+ IAPDESCR(A3H_02H, 0xA3, 0x02, IAP_F_FM | IAP_F_SBX | IAP_F_IBX | IAP_F_IB | IAP_F_HW |
IAP_F_HWX | IAP_F_SL),
IAPDESCR(A3H_04H, 0xA3, 0x04, IAP_F_FM | IAP_F_SBX | IAP_F_IBX | IAP_F_IB | IAP_F_SL),
IAPDESCR(A3H_05H, 0xA3, 0x05, IAP_F_FM | IAP_F_HW | IAP_F_HWX | IAP_F_SL),
IAPDESCR(A3H_06H, 0xA3, 0x06, IAP_F_FM | IAP_F_SL),
- IAPDESCR(A3H_08H, 0xA3, 0x08, IAP_F_IBX | IAP_F_HW | IAP_F_IB | IAP_F_HWX |
+ IAPDESCR(A3H_08H, 0xA3, 0x08, IAP_F_FM | IAP_F_IBX | IAP_F_HW | IAP_F_IB | IAP_F_HWX |
IAP_F_SL),
IAPDESCR(A3H_0CH, 0xA3, 0x0C, IAP_F_FM | IAP_F_HW | IAP_F_HW | IAP_F_SL),
IAPDESCR(A3H_10H, 0xA3, 0x10, IAP_F_FM | IAP_F_SL),
IAPDESCR(A3H_14H, 0xA3, 0x14, IAP_F_FM | IAP_F_SL),
IAPDESCR(A6H_01H, 0xA6, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_SL),
- IAPDESCR(A6H_02H, 0xA3, 0x0, IAP_F_FM | IAP_F_SL),
- IAPDESCR(A6H_04H, 0xA3, 0x0, IAP_F_FM | IAP_F_SL),
- IAPDESCR(A6H_08H, 0xA3, 0x0, IAP_F_FM | IAP_F_SL),
- IAPDESCR(A6H_10H, 0xA3, 0x0, IAP_F_FM | IAP_F_SL),
- IAPDESCR(A6H_40H, 0xA3, 0x0, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(A6H_02H, 0xA3, 0x02, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(A6H_04H, 0xA3, 0x04, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(A6H_08H, 0xA3, 0x08, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(A6H_10H, 0xA3, 0x10, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(A6H_40H, 0xA3, 0x40, IAP_F_FM | IAP_F_SL),
IAPDESCR(A7H_01H, 0xA7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM ),
IAPDESCR(A8H_01H, 0xA8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM | IAP_F_IBX |
@@ -1459,7 +1458,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(B4H_04H, 0xB4, 0x04, IAP_F_FM | IAP_F_WM),
IAPDESCR(B6H_01H, 0xB6, 0x01, IAP_F_FM | IAP_F_SB | IAP_F_SBX),
- IAPDESCR(B6H_04H, 0xB6, 0x04, IAP_F_CAS),
+ IAPDESCR(B6H_04H, 0xB6, 0x04, IAP_F_FM | IAP_F_CAS),
IAPDESCR(B7H_01H, 0xB7, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM |
IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_CAS |
@@ -1496,7 +1495,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(C0H_00H, 0xC0, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX | IAP_F_IBX | IAP_F_HW |
IAP_F_CAS | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(C0H_01H, 0xC0, 0x0a, IAP_F_CA | IAP_F_CC2 |
+ IAPDESCR(C0H_01H, 0xC0, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX |
IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
IAPDESCR(C0H_02H, 0xC0, 0x02, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
@@ -1514,9 +1513,9 @@ static struct iap_event_descr iap_events[] = {
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX),
IAPDESCR(C1H_20H, 0xC1, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX),
- IAPDESCR(C1H_3FH, 0xC1, 0x00, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(C1H_3FH, 0xC1, 0x3F, IAP_F_FM | IAP_F_SL),
IAPDESCR(C1H_40H, 0xC1, 0x40, IAP_F_FM | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX),
- IAPDESCR(C1H_80H, 0xC1, 0x80, IAP_F_IB | IAP_F_IBX),
+ IAPDESCR(C1H_80H, 0xC1, 0x80, IAP_F_FM |IAP_F_IB | IAP_F_IBX),
IAPDESCR(C1H_FEH, 0xC1, 0xFE, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
IAPDESCR(C2H_00H, 0xC2, 0x00, IAP_F_FM | IAP_F_CC),
@@ -1542,7 +1541,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(C3H_04H, 0xC3, 0x04, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX |
IAP_F_IBX | IAP_F_HW | IAP_F_CAS | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(C3H_08H, 0xC3, 0x08, IAP_F_CAS),
+ IAPDESCR(C3H_08H, 0xC3, 0x08, IAP_F_FM | IAP_F_CAS),
IAPDESCR(C3H_10H, 0xC3, 0x10, IAP_F_FM | IAP_F_I7O),
IAPDESCR(C3H_20H, 0xC3, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX),
@@ -1570,14 +1569,14 @@ static struct iap_event_descr iap_events[] = {
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
IAPDESCR(C4H_40H, 0xC4, 0x40, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(C4H_7EH, 0xC4, 0x7E, IAP_F_CAS),
- IAPDESCR(C4H_BFH, 0xC4, 0xBF, IAP_F_CAS),
- IAPDESCR(C4H_EBH, 0xC4, 0xEB, IAP_F_CAS),
- IAPDESCR(C4H_F7H, 0xC4, 0xF7, IAP_F_CAS),
- IAPDESCR(C4H_F9H, 0xC4, 0xF9, IAP_F_CAS),
- IAPDESCR(C4H_FBH, 0xC4, 0xFB, IAP_F_CAS),
- IAPDESCR(C4H_FDH, 0xC4, 0xFD, IAP_F_CAS),
- IAPDESCR(C4H_FEH, 0xC4, 0xFE, IAP_F_CAS),
+ IAPDESCR(C4H_7EH, 0xC4, 0x7E, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C4H_BFH, 0xC4, 0xBF, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C4H_EBH, 0xC4, 0xEB, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C4H_F7H, 0xC4, 0xF7, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C4H_F9H, 0xC4, 0xF9, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C4H_FBH, 0xC4, 0xFB, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C4H_FDH, 0xC4, 0xFD, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C4H_FEH, 0xC4, 0xFE, IAP_F_FM | IAP_F_CAS),
IAPDESCR(C5H_00H, 0xC5, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2 |
IAP_F_I7 | IAP_F_WM | IAP_F_SB | IAP_F_IB | IAP_F_SBX |
@@ -1593,14 +1592,14 @@ static struct iap_event_descr iap_events[] = {
IAP_F_SBX | IAP_F_IBX),
IAPDESCR(C5H_20H, 0xC5, 0x20, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_SL),
- IAPDESCR(C5H_7EH, 0xC5, 0x7E, IAP_F_CAS),
- IAPDESCR(C5H_BFH, 0xC5, 0xBF, IAP_F_CAS),
- IAPDESCR(C5H_EBH, 0xC5, 0xEB, IAP_F_CAS),
- IAPDESCR(C5H_F7H, 0xC5, 0xF7, IAP_F_CAS),
- IAPDESCR(C5H_F9H, 0xC5, 0xF9, IAP_F_CAS),
- IAPDESCR(C5H_FBH, 0xC5, 0xFB, IAP_F_CAS),
- IAPDESCR(C5H_FDH, 0xC5, 0xFD, IAP_F_CAS),
- IAPDESCR(C5H_FEH, 0xC5, 0xFE, IAP_F_CAS),
+ IAPDESCR(C5H_7EH, 0xC5, 0x7E, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C5H_BFH, 0xC5, 0xBF, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C5H_EBH, 0xC5, 0xEB, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C5H_F7H, 0xC5, 0xF7, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C5H_F9H, 0xC5, 0xF9, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C5H_FBH, 0xC5, 0xFB, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C5H_FDH, 0xC5, 0xFD, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(C5H_FEH, 0xC5, 0xFE, IAP_F_FM | IAP_F_CAS),
IAPDESCR(C6H_00H, 0xC6, 0x00, IAP_F_FM | IAP_F_CC),
/* For SL C6_01 needs EV_SEL? 0x11, 0x12, 0x13, 0x14, 0x15? */
@@ -1619,7 +1618,7 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(C7H_10H, 0xC7, 0x10, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM | IAP_F_SL),
IAPDESCR(C7H_1FH, 0xC7, 0x1F, IAP_F_FM | IAP_F_CA | IAP_F_CC2),
- IAPDESCR(C7H_20H, 0xC7, 0x0, IAP_F_FM | IAP_F_SL),
+ IAPDESCR(C7H_20H, 0xC7, 0x20, IAP_F_FM | IAP_F_SL),
IAPDESCR(C8H_00H, 0xC8, 0x00, IAP_F_FM | IAP_F_ALLCPUSCORE2),
IAPDESCR(C8H_20H, 0xC8, 0x20, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
@@ -1639,11 +1638,11 @@ static struct iap_event_descr iap_events[] = {
IAP_F_BW | IAP_F_BWX),
IAPDESCR(CAH_10H, 0xCA, 0x10, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX),
- IAPDESCR(CAH_1EH, 0xCA, 0x1, IAP_F_FM | IAP_F_SB | IAP_F_IB |
+ IAPDESCR(CAH_1EH, 0xCA, 0x1E, IAP_F_FM | IAP_F_SB | IAP_F_IB |
IAP_F_SBX | IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX | IAP_F_SL),
- IAPDESCR(CAH_20H, 0xCA, 0x0, IAP_F_FM | IAP_F_CAS | IAP_F_BW | IAP_F_BWX),
- IAPDESCR(CAH_3FH, 0xCA, 0x3F, IAP_F_CAS),
- IAPDESCR(CAH_50H, 0xCA, 0x50, IAP_F_CAS),
+ IAPDESCR(CAH_20H, 0xCA, 0x20, IAP_F_FM | IAP_F_CAS | IAP_F_BW | IAP_F_BWX),
+ IAPDESCR(CAH_3FH, 0xCA, 0x3F, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(CAH_50H, 0xCA, 0x50, IAP_F_FM | IAP_F_CAS),
IAPDESCR(CBH_01H, 0xCB, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM | IAP_F_CAS | IAP_F_SL),
@@ -1655,7 +1654,7 @@ static struct iap_event_descr iap_events[] = {
IAP_F_I7 | IAP_F_WM),
IAPDESCR(CBH_10H, 0xCB, 0x10, IAP_F_FM | IAP_F_CC2 | IAP_F_I7 |
IAP_F_WM),
- IAPDESCR(CBH_1FH, 0xCB, 0x1F, IAP_F_CAS),
+ IAPDESCR(CBH_1FH, 0xCB, 0x1F, IAP_F_FM | IAP_F_CAS),
IAPDESCR(CBH_40H, 0xCB, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(CBH_80H, 0xCB, 0x80, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
@@ -1734,11 +1733,11 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(D3H_01H, 0xD3, 0x01, IAP_F_FM | IAP_F_IB | IAP_F_SBX |
IAP_F_IBX | IAP_F_HW | IAP_F_HWX | IAP_F_BW | IAP_F_BWX),
- IAPDESCR(D3H_03H, 0xD3, 0x03, IAP_F_IBX),
+ IAPDESCR(D3H_03H, 0xD3, 0x03, IAP_F_FM | IAP_F_IBX),
IAPDESCR(D3H_04H, 0xD3, 0x04, IAP_F_FM | IAP_F_SBX | IAP_F_IBX), /* Not defined for IBX */
- IAPDESCR(D3H_0CH, 0xD3, 0x0C, IAP_F_IBX),
- IAPDESCR(D3H_10H, 0xD3, 0x10, IAP_F_IBX ),
- IAPDESCR(D3H_20H, 0xD3, 0x20, IAP_F_IBX ),
+ IAPDESCR(D3H_0CH, 0xD3, 0x0C, IAP_F_FM | IAP_F_IBX),
+ IAPDESCR(D3H_10H, 0xD3, 0x10, IAP_F_FM | IAP_F_IBX ),
+ IAPDESCR(D3H_20H, 0xD3, 0x20, IAP_F_FM | IAP_F_IBX ),
IAPDESCR(D4H_01H, 0xD4, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_CC2 |
IAP_F_I7 | IAP_F_WM),
@@ -1797,12 +1796,12 @@ static struct iap_event_descr iap_events[] = {
IAPDESCR(E6H_01H, 0xE6, 0x01, IAP_F_FM | IAP_F_CA | IAP_F_I7 |
IAP_F_WM | IAP_F_SBX | IAP_F_CAS | IAP_F_SL),
IAPDESCR(E6H_02H, 0xE6, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
- IAPDESCR(E6H_08H, 0xE6, 0x08, IAP_F_CAS),
- IAPDESCR(E6H_10H, 0xE6, 0x10, IAP_F_CAS),
+ IAPDESCR(E6H_08H, 0xE6, 0x08, IAP_F_FM | IAP_F_CAS),
+ IAPDESCR(E6H_10H, 0xE6, 0x10, IAP_F_FM | IAP_F_CAS),
IAPDESCR(E6H_1FH, 0xE6, 0x1F, IAP_F_FM | IAP_F_IB |
IAP_F_IBX | IAP_F_HW | IAP_F_HWX),
- IAPDESCR(E7H_01H, 0xE7, 0x01, IAP_F_CAS),
+ IAPDESCR(E7H_01H, 0xE7, 0x01, IAP_F_FM | IAP_F_CAS),
IAPDESCR(E8H_01H, 0xE8, 0x01, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
IAPDESCR(E8H_02H, 0xE8, 0x02, IAP_F_FM | IAP_F_I7 | IAP_F_WM),
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index a47066e..6405ad5 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -836,8 +836,8 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
struct buf *pb;
bus_dma_segment_t *vlist;
struct thread *td;
- off_t len, zerosize;
- int ma_offs;
+ off_t iolen, len, zerosize;
+ int ma_offs, npages;
switch (bp->bio_cmd) {
case BIO_READ:
@@ -858,6 +858,7 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
pb = NULL;
piov = NULL;
ma_offs = bp->bio_ma_offset;
+ len = bp->bio_length;
/*
* VNODE I/O
@@ -890,7 +891,6 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
auio.uio_iovcnt = howmany(bp->bio_length, zerosize);
piov = malloc(sizeof(*piov) * auio.uio_iovcnt, M_MD, M_WAITOK);
auio.uio_iov = piov;
- len = bp->bio_length;
while (len > 0) {
piov->iov_base = __DECONST(void *, zero_region);
piov->iov_len = len;
@@ -904,7 +904,6 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
piov = malloc(sizeof(*piov) * bp->bio_ma_n, M_MD, M_WAITOK);
auio.uio_iov = piov;
vlist = (bus_dma_segment_t *)bp->bio_data;
- len = bp->bio_length;
while (len > 0) {
piov->iov_base = (void *)(uintptr_t)(vlist->ds_addr +
ma_offs);
@@ -920,11 +919,20 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
piov = auio.uio_iov;
} else if ((bp->bio_flags & BIO_UNMAPPED) != 0) {
pb = getpbuf(&md_vnode_pbuf_freecnt);
- pmap_qenter((vm_offset_t)pb->b_data, bp->bio_ma, bp->bio_ma_n);
- aiov.iov_base = (void *)((vm_offset_t)pb->b_data + ma_offs);
- aiov.iov_len = bp->bio_length;
+ bp->bio_resid = len;
+unmapped_step:
+ npages = atop(min(MAXPHYS, round_page(len + (ma_offs &
+ PAGE_MASK))));
+ iolen = min(ptoa(npages) - (ma_offs & PAGE_MASK), len);
+ KASSERT(iolen > 0, ("zero iolen"));
+ pmap_qenter((vm_offset_t)pb->b_data,
+ &bp->bio_ma[atop(ma_offs)], npages);
+ aiov.iov_base = (void *)((vm_offset_t)pb->b_data +
+ (ma_offs & PAGE_MASK));
+ aiov.iov_len = iolen;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
+ auio.uio_resid = iolen;
} else {
aiov.iov_base = bp->bio_data;
aiov.iov_len = bp->bio_length;
@@ -948,15 +956,21 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
vn_finished_write(mp);
}
- if (pb) {
- pmap_qremove((vm_offset_t)pb->b_data, bp->bio_ma_n);
+ if (pb != NULL) {
+ pmap_qremove((vm_offset_t)pb->b_data, npages);
+ if (error == 0) {
+ len -= iolen;
+ bp->bio_resid -= iolen;
+ ma_offs += iolen;
+ if (len > 0)
+ goto unmapped_step;
+ }
relpbuf(pb, &md_vnode_pbuf_freecnt);
}
- if (piov != NULL)
- free(piov, M_MD);
-
- bp->bio_resid = auio.uio_resid;
+ free(piov, M_MD);
+ if (pb == NULL)
+ bp->bio_resid = auio.uio_resid;
return (error);
}
diff --git a/sys/dev/ncv/ncr53c500_pccard.c b/sys/dev/ncv/ncr53c500_pccard.c
index 23c207a..a7a2b5b 100644
--- a/sys/dev/ncv/ncr53c500_pccard.c
+++ b/sys/dev/ncv/ncr53c500_pccard.c
@@ -293,6 +293,7 @@ static devclass_t ncv_devclass;
MODULE_DEPEND(ncv, scsi_low, 1, 1, 1);
DRIVER_MODULE(ncv, pccard, ncv_pccard_driver, ncv_devclass, 0, 0);
+PCCARD_PNP_INFO(ncv_products);
static void
ncv_card_unload(device_t devi)
diff --git a/sys/dev/nsp/nsp_pccard.c b/sys/dev/nsp/nsp_pccard.c
index a235c22..aed82af 100644
--- a/sys/dev/nsp/nsp_pccard.c
+++ b/sys/dev/nsp/nsp_pccard.c
@@ -233,6 +233,7 @@ static devclass_t nsp_devclass;
MODULE_DEPEND(nsp, scsi_low, 1, 1, 1);
DRIVER_MODULE(nsp, pccard, nsp_pccard_driver, nsp_devclass, 0, 0);
+PCCARD_PNP_INFO(nsp_products);
static void
nsp_card_unload(device_t devi)
diff --git a/sys/dev/nvd/nvd.c b/sys/dev/nvd/nvd.c
index 5d75876..f459e06 100644
--- a/sys/dev/nvd/nvd.c
+++ b/sys/dev/nvd/nvd.c
@@ -279,7 +279,7 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg)
disk->d_sectorsize = nvme_ns_get_sector_size(ns);
disk->d_mediasize = (off_t)nvme_ns_get_size(ns);
disk->d_delmaxsize = (off_t)nvme_ns_get_size(ns);
- disk->d_stripesize = nvme_ns_get_stripesize(ns);
+ disk->d_stripesize = nvme_ns_get_optimal_sector_size(ns);
if (TAILQ_EMPTY(&disk_head))
disk->d_unit = 0;
diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h
index 7e41e77..227a89e 100644
--- a/sys/dev/nvme/nvme.h
+++ b/sys/dev/nvme/nvme.h
@@ -870,6 +870,7 @@ const char * nvme_ns_get_serial_number(struct nvme_namespace *ns);
const char * nvme_ns_get_model_number(struct nvme_namespace *ns);
const struct nvme_namespace_data *
nvme_ns_get_data(struct nvme_namespace *ns);
+uint32_t nvme_ns_get_optimal_sector_size(struct nvme_namespace *ns);
uint32_t nvme_ns_get_stripesize(struct nvme_namespace *ns);
int nvme_ns_bio_process(struct nvme_namespace *ns, struct bio *bp,
diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c
index 754d074..4580e66 100644
--- a/sys/dev/nvme/nvme_ns.c
+++ b/sys/dev/nvme/nvme_ns.c
@@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$");
#include "nvme_private.h"
+extern int nvme_max_optimal_sectorsize;
+
static void nvme_bio_child_inbed(struct bio *parent, int bio_error);
static void nvme_bio_child_done(void *arg,
const struct nvme_completion *cpl);
@@ -217,6 +219,22 @@ nvme_ns_get_stripesize(struct nvme_namespace *ns)
return (ns->stripesize);
}
+uint32_t
+nvme_ns_get_optimal_sector_size(struct nvme_namespace *ns)
+{
+ uint32_t stripesize;
+
+ stripesize = nvme_ns_get_stripesize(ns);
+
+ if (stripesize == 0)
+ return nvme_ns_get_sector_size(ns);
+
+ if (nvme_max_optimal_sectorsize == 0)
+ return (stripesize);
+
+ return (MIN(stripesize, nvme_max_optimal_sectorsize));
+}
+
static void
nvme_ns_bio_done(void *arg, const struct nvme_completion *status)
{
diff --git a/sys/dev/nvme/nvme_sysctl.c b/sys/dev/nvme/nvme_sysctl.c
index 0ebbbf7..8b99111 100644
--- a/sys/dev/nvme/nvme_sysctl.c
+++ b/sys/dev/nvme/nvme_sysctl.c
@@ -33,6 +33,22 @@ __FBSDID("$FreeBSD$");
#include "nvme_private.h"
+SYSCTL_NODE(_kern, OID_AUTO, nvme, CTLFLAG_RD, 0, "NVM Express");
+/*
+ * Intel NVMe controllers have a slow path for I/Os that span a 128KB
+ * stripe boundary but ZFS limits ashift, which is derived from
+ * d_stripesize, to 13 (8KB) so we limit the stripesize reported to
+ * geom(8) to 4KB by default.
+ *
+ * This may result in a small number of additional I/Os to require
+ * splitting in nvme(4), however the NVMe I/O path is very efficient
+ * so these additional I/Os will cause very minimal (if any) difference
+ * in performance or CPU utilisation.
+ */
+int nvme_max_optimal_sectorsize = 1<<12;
+SYSCTL_INT(_kern_nvme, OID_AUTO, max_optimal_sectorsize, CTLFLAG_RWTUN,
+ &nvme_max_optimal_sectorsize, 0, "The maximum optimal sectorsize reported");
+
/*
* CTLTYPE_S64 and sysctl_handle_64 were added in r217616. Define these
* explicitly here for older kernels that don't include the r217616
diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c
index ff1cd81..ba2b20e 100644
--- a/sys/dev/ofw/ofw_bus_subr.c
+++ b/sys/dev/ofw/ofw_bus_subr.c
@@ -607,3 +607,134 @@ ofw_bus_find_child_device_by_phandle(device_t bus, phandle_t node)
return (retval);
}
+
+/*
+ * Parse property that contain list of xrefs and values
+ * (like standard "clocks" and "resets" properties)
+ * Input arguments:
+ * node - consumers device node
+ * list_name - name of parsed list - "clocks"
+ * cells_name - name of size property - "#clock-cells"
+ * Output arguments:
+ * producer - handle of producer
+ * ncells - number of cells in result
+ * cells - array of decoded cells
+ */
+int
+ofw_bus_parse_xref_list_alloc(phandle_t node, const char *list_name,
+ const char *cells_name, int idx, phandle_t *producer, int *ncells,
+ pcell_t **cells)
+{
+ phandle_t pnode;
+ phandle_t *elems;
+ uint32_t pcells;
+ int rv, i, j, nelems, cnt;
+
+ elems = NULL;
+ nelems = OF_getencprop_alloc(node, list_name, sizeof(*elems),
+ (void **)&elems);
+ if (nelems <= 0)
+ return (ENOENT);
+ rv = ENOENT;
+ for (i = 0, cnt = 0; i < nelems; i += pcells, cnt++) {
+ pnode = elems[i++];
+ if (OF_getencprop(OF_node_from_xref(pnode),
+ cells_name, &pcells, sizeof(pcells)) == -1) {
+ printf("Missing %s property\n", cells_name);
+ rv = ENOENT;
+ break;
+ }
+
+ if ((i + pcells) > nelems) {
+ printf("Invalid %s property value <%d>\n", cells_name,
+ pcells);
+ rv = ERANGE;
+ break;
+ }
+ if (cnt == idx) {
+ *cells= malloc(pcells * sizeof(**cells), M_OFWPROP,
+ M_WAITOK);
+ *producer = pnode;
+ *ncells = pcells;
+ for (j = 0; j < pcells; j++)
+ (*cells)[j] = elems[i + j];
+ rv = 0;
+ break;
+ }
+ }
+ if (elems != NULL)
+ free(elems, M_OFWPROP);
+ return (rv);
+}
+
+/*
+ * Find index of string in string list property (case sensitive).
+ */
+int
+ofw_bus_find_string_index(phandle_t node, const char *list_name,
+ const char *name, int *idx)
+{
+ char *elems;
+ int rv, i, cnt, nelems;
+
+ elems = NULL;
+ nelems = OF_getprop_alloc(node, list_name, 1, (void **)&elems);
+ if (nelems <= 0)
+ return (ENOENT);
+
+ rv = ENOENT;
+ for (i = 0, cnt = 0; i < nelems; cnt++) {
+ if (strcmp(elems + i, name) == 0) {
+ *idx = cnt;
+ rv = 0;
+ break;
+ }
+ i += strlen(elems + i) + 1;
+ }
+
+ if (elems != NULL)
+ free(elems, M_OFWPROP);
+ return (rv);
+}
+
+/*
+ * Create zero terminated array of strings from string list property.
+ */
+int
+ofw_bus_string_list_to_array(phandle_t node, const char *list_name,
+ const char ***array)
+{
+ char *elems, *tptr;
+ int i, cnt, nelems, len;
+
+ elems = NULL;
+ nelems = OF_getprop_alloc(node, list_name, 1, (void **)&elems);
+ if (nelems <= 0)
+ return (nelems);
+
+ /* Count number of strings. */
+ for (i = 0, cnt = 0; i < nelems; cnt++)
+ i += strlen(elems + i) + 1;
+
+ /* Allocate space for arrays and all strings. */
+ *array = malloc((cnt + 1) * sizeof(char *) + nelems, M_OFWPROP,
+ M_WAITOK);
+
+ /* Get address of first string. */
+ tptr = (char *)(*array + cnt);
+
+ /* Copy strings. */
+ memcpy(tptr, elems, nelems);
+ free(elems, M_OFWPROP);
+
+ /* Fill string pointers. */
+ for (i = 0, cnt = 0; i < nelems; cnt++) {
+ len = strlen(tptr + i) + 1;
+ *array[cnt] = tptr;
+ i += len;
+ tptr += len;
+ }
+ *array[cnt] = 0;
+
+ return (cnt);
+}
diff --git a/sys/dev/ofw/ofw_bus_subr.h b/sys/dev/ofw/ofw_bus_subr.h
index dffc952..708e984 100644
--- a/sys/dev/ofw/ofw_bus_subr.h
+++ b/sys/dev/ofw/ofw_bus_subr.h
@@ -110,4 +110,13 @@ phandle_t ofw_bus_find_child(phandle_t, const char *);
/* Helper routine to find a device_t child matchig a given phandle_t */
device_t ofw_bus_find_child_device_by_phandle(device_t bus, phandle_t node);
+/* Helper routines for parsing lists */
+int ofw_bus_parse_xref_list_alloc(phandle_t node, const char *list_name,
+ const char *cells_name, int idx, phandle_t *producer, int *ncells,
+ pcell_t **cells);
+int ofw_bus_find_string_index(phandle_t node, const char *list_name,
+ const char *name, int *idx);
+int ofw_bus_string_list_to_array(phandle_t node, const char *list_name,
+ const char ***array);
+
#endif /* !_DEV_OFW_OFW_BUS_SUBR_H_ */
diff --git a/sys/dev/ofw/ofw_iicbus.c b/sys/dev/ofw/ofw_iicbus.c
index e27cc09..c0fa054 100644
--- a/sys/dev/ofw/ofw_iicbus.c
+++ b/sys/dev/ofw/ofw_iicbus.c
@@ -190,6 +190,8 @@ ofw_iicbus_attach(device_t dev)
device_set_ivars(childdev, dinfo);
}
+ /* Register bus */
+ OF_device_register_xref(OF_xref_from_node(node), dev);
return (bus_generic_attach(dev));
}
diff --git a/sys/dev/otus/if_otus.c b/sys/dev/otus/if_otus.c
index 0d59278..160b05e 100644
--- a/sys/dev/otus/if_otus.c
+++ b/sys/dev/otus/if_otus.c
@@ -2423,7 +2423,7 @@ otus_updateslot(struct otus_softc *sc)
OTUS_LOCK_ASSERT(sc);
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
+ slottime = IEEE80211_GET_SLOTTIME(ic);
otus_write(sc, AR_MAC_REG_SLOT_TIME, slottime << 10);
(void)otus_write_barrier(sc);
}
diff --git a/sys/dev/pccard/pccardvar.h b/sys/dev/pccard/pccardvar.h
index bef4a7c..3bc27e3 100644
--- a/sys/dev/pccard/pccardvar.h
+++ b/sys/dev/pccard/pccardvar.h
@@ -85,6 +85,16 @@ struct pccard_product {
const char *pp_cis[4];
};
+/**
+ * Note: There's no cis3 or cis4 reported for NOMATCH / pnpinfo events for pccard
+ * It's unclear if we actually need that for automatic loading or not. These stirngs
+ * are informative, according to the standard, but I have a dim memory of using these
+ * strings to match things, though I can't find the example right now.
+ */
+#define PCCARD_PNP_DESCR "D:human;V32:manufacturer;V32:product;Z:cisvendor;Z:cisproduct;"
+#define PCCARD_PNP_INFO(t) \
+ MODULE_PNP_INFO(PCCARD_PNP_DESCR, pccard, t, t, sizeof(t[0]), sizeof(t) / sizeof(t[0])); \
+
typedef int (*pccard_product_match_fn) (device_t dev,
const struct pccard_product *ent, int vpfmatch);
diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c
index e5d7518..d62c470 100644
--- a/sys/dev/ral/rt2560.c
+++ b/sys/dev/ral/rt2560.c
@@ -2254,7 +2254,7 @@ rt2560_update_slot(struct ieee80211com *ic)
uint32_t tmp;
#ifndef FORCE_SLOTTIME
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
+ slottime = IEEE80211_GET_SLOTTIME(ic);
#else
/*
* Setting slot time according to "short slot time" capability
@@ -2272,13 +2272,13 @@ rt2560_update_slot(struct ieee80211com *ic)
* (-1Mb~-2Mb lower) and the _whole_ BSS would stop using short
* slot time.
*/
- slottime = 20;
+ slottime = IEEE80211_DUR_SLOT;
#endif
/* update the MAC slot boundaries */
tx_sifs = RAL_SIFS - RT2560_TXRX_TURNAROUND;
tx_pifs = tx_sifs + slottime;
- tx_difs = tx_sifs + 2 * slottime;
+ tx_difs = IEEE80211_DUR_DIFS(tx_sifs, slottime);
eifs = (ic->ic_curmode == IEEE80211_MODE_11B) ? 364 : 60;
tmp = RAL_READ(sc, RT2560_CSR11);
diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c
index cff64b1..a2e955c 100644
--- a/sys/dev/ral/rt2661.c
+++ b/sys/dev/ral/rt2661.c
@@ -2090,7 +2090,7 @@ rt2661_update_slot(struct ieee80211com *ic)
uint8_t slottime;
uint32_t tmp;
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
+ slottime = IEEE80211_GET_SLOTTIME(ic);
tmp = RAL_READ(sc, RT2661_MAC_CSR9);
tmp = (tmp & ~0xff) | slottime;
diff --git a/sys/dev/ral/rt2860.c b/sys/dev/ral/rt2860.c
index a572dbf..9447976 100644
--- a/sys/dev/ral/rt2860.c
+++ b/sys/dev/ral/rt2860.c
@@ -3048,7 +3048,7 @@ rt2860_updateslot(struct ieee80211com *ic)
tmp = RAL_READ(sc, RT2860_BKOFF_SLOT_CFG);
tmp &= ~0xff;
- tmp |= (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
+ tmp |= IEEE80211_GET_SLOTTIME(ic);
RAL_WRITE(sc, RT2860_BKOFF_SLOT_CFG, tmp);
}
diff --git a/sys/dev/sfxge/common/efx_impl.h b/sys/dev/sfxge/common/efx_impl.h
index 239d9c8..502fc78 100644
--- a/sys/dev/sfxge/common/efx_impl.h
+++ b/sys/dev/sfxge/common/efx_impl.h
@@ -456,15 +456,12 @@ typedef struct efx_mcdi_ops_s {
efx_rc_t (*emco_init)(efx_nic_t *, const efx_mcdi_transport_t *);
void (*emco_request_copyin)(efx_nic_t *, efx_mcdi_req_t *,
unsigned int, boolean_t, boolean_t);
- boolean_t (*emco_request_poll)(efx_nic_t *);
void (*emco_request_copyout)(efx_nic_t *, efx_mcdi_req_t *);
efx_rc_t (*emco_poll_reboot)(efx_nic_t *);
- void (*emco_fini)(efx_nic_t *);
- efx_rc_t (*emco_fw_update_supported)(efx_nic_t *, boolean_t *);
- efx_rc_t (*emco_macaddr_change_supported)(efx_nic_t *, boolean_t *);
- efx_rc_t (*emco_link_control_supported)(efx_nic_t *, boolean_t *);
- efx_rc_t (*emco_mac_spoofing_supported)(efx_nic_t *, boolean_t *);
+ boolean_t (*emco_poll_response)(efx_nic_t *);
void (*emco_read_response)(efx_nic_t *, void *, size_t, size_t);
+ void (*emco_fini)(efx_nic_t *);
+ efx_rc_t (*emco_feature_supported)(efx_nic_t *, efx_mcdi_feature_id_t, boolean_t *);
} efx_mcdi_ops_t;
typedef struct efx_mcdi_s {
diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c
index e6ca1e8..a5c4d52 100644
--- a/sys/dev/sfxge/common/efx_mcdi.c
+++ b/sys/dev/sfxge/common/efx_mcdi.c
@@ -46,17 +46,12 @@ __FBSDID("$FreeBSD$");
static efx_mcdi_ops_t __efx_mcdi_siena_ops = {
siena_mcdi_init, /* emco_init */
siena_mcdi_request_copyin, /* emco_request_copyin */
- siena_mcdi_request_poll, /* emco_request_poll */
siena_mcdi_request_copyout, /* emco_request_copyout */
siena_mcdi_poll_reboot, /* emco_poll_reboot */
- siena_mcdi_fini, /* emco_fini */
- siena_mcdi_fw_update_supported, /* emco_fw_update_supported */
- siena_mcdi_macaddr_change_supported,
- /* emco_macaddr_change_supported */
- siena_mcdi_link_control_supported,
- /* emco_link_control_supported */
- NULL, /* emco_mac_spoofing_supported */
+ siena_mcdi_poll_response, /* emco_poll_response */
siena_mcdi_read_response, /* emco_read_response */
+ siena_mcdi_fini, /* emco_fini */
+ siena_mcdi_feature_supported, /* emco_feature_supported */
};
#endif /* EFSYS_OPT_SIENA */
@@ -66,18 +61,12 @@ static efx_mcdi_ops_t __efx_mcdi_siena_ops = {
static efx_mcdi_ops_t __efx_mcdi_hunt_ops = {
hunt_mcdi_init, /* emco_init */
hunt_mcdi_request_copyin, /* emco_request_copyin */
- hunt_mcdi_request_poll, /* emco_request_poll */
hunt_mcdi_request_copyout, /* emco_request_copyout */
hunt_mcdi_poll_reboot, /* emco_poll_reboot */
- hunt_mcdi_fini, /* emco_fini */
- hunt_mcdi_fw_update_supported, /* emco_fw_update_supported */
- hunt_mcdi_macaddr_change_supported,
- /* emco_macaddr_change_supported */
- hunt_mcdi_link_control_supported,
- /* emco_link_control_supported */
- hunt_mcdi_mac_spoofing_supported,
- /* emco_mac_spoofing_supported */
+ hunt_mcdi_poll_response, /* emco_poll_response */
hunt_mcdi_read_response, /* emco_read_response */
+ hunt_mcdi_fini, /* emco_fini */
+ hunt_mcdi_feature_supported, /* emco_feature_supported */
};
#endif /* EFSYS_OPT_HUNTINGTON */
@@ -187,6 +176,62 @@ efx_mcdi_new_epoch(
EFSYS_UNLOCK(enp->en_eslp, state);
}
+static void
+efx_mcdi_request_copyin(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __in unsigned int seq,
+ __in boolean_t ev_cpl,
+ __in boolean_t new_epoch)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+
+ emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
+}
+
+static void
+efx_mcdi_request_copyout(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+
+ emcop->emco_request_copyout(enp, emrp);
+}
+
+static efx_rc_t
+efx_mcdi_poll_reboot(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ efx_rc_t rc;
+
+ rc = emcop->emco_poll_reboot(enp);
+ return (rc);
+}
+
+static boolean_t
+efx_mcdi_poll_response(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ boolean_t available;
+
+ available = emcop->emco_poll_response(enp);
+ return (available);
+}
+
+static void
+efx_mcdi_read_response(
+ __in efx_nic_t *enp,
+ __out void *bufferp,
+ __in size_t offset,
+ __in size_t length)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+
+ emcop->emco_read_response(enp, bufferp, offset, length);
+}
void
efx_mcdi_request_start(
@@ -195,7 +240,6 @@ efx_mcdi_request_start(
__in boolean_t ev_cpl)
{
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
- efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
unsigned int seq;
boolean_t new_epoch;
int state;
@@ -204,9 +248,6 @@ efx_mcdi_request_start(
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- if (emcop == NULL || emcop->emco_request_copyin == NULL)
- return;
-
/*
* efx_mcdi_request_start() is naturally serialised against both
* efx_mcdi_request_poll() and efx_mcdi_ev_cpl()/efx_mcdi_ev_death(),
@@ -228,7 +269,7 @@ efx_mcdi_request_start(
new_epoch = emip->emi_new_epoch;
EFSYS_UNLOCK(enp->en_eslp, state);
- emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
+ efx_mcdi_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
}
@@ -241,7 +282,6 @@ efx_mcdi_read_response_header(
const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
#endif /* EFSYS_OPT_MCDI_LOGGING */
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
- efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
efx_dword_t hdr[2];
unsigned int hdr_len;
unsigned int data_len;
@@ -252,7 +292,7 @@ efx_mcdi_read_response_header(
EFSYS_ASSERT(emrp != NULL);
- emcop->emco_read_response(enp, &hdr[0], 0, sizeof (hdr[0]));
+ efx_mcdi_read_response(enp, &hdr[0], 0, sizeof (hdr[0]));
hdr_len = sizeof (hdr[0]);
cmd = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE);
@@ -262,8 +302,7 @@ efx_mcdi_read_response_header(
if (cmd != MC_CMD_V2_EXTN) {
data_len = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN);
} else {
- emcop->emco_read_response(enp, &hdr[1], hdr_len,
- sizeof (hdr[1]));
+ efx_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1]));
hdr_len += sizeof (hdr[1]);
cmd = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD);
@@ -274,7 +313,7 @@ efx_mcdi_read_response_header(
if (error && (data_len == 0)) {
/* The MC has rebooted since the request was sent. */
EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
- emcop->emco_poll_reboot(enp);
+ efx_mcdi_poll_reboot(enp);
rc = EIO;
goto fail1;
}
@@ -291,7 +330,7 @@ efx_mcdi_read_response_header(
int err_arg = 0;
/* Read error code (and arg num for MCDI v2 commands) */
- emcop->emco_read_response(enp, &err, hdr_len, err_len);
+ efx_mcdi_read_response(enp, &err, hdr_len, err_len);
if (err_len >= (MC_CMD_ERR_CODE_OFST + sizeof (efx_dword_t)))
err_code = EFX_DWORD_FIELD(err[0], EFX_DWORD_0);
@@ -361,19 +400,63 @@ fail1:
efx_mcdi_request_poll(
__in efx_nic_t *enp)
{
- efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
- boolean_t completed;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_req_t *emrp;
+ int state;
+ efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- completed = B_FALSE;
+ /* Serialise against post-watchdog efx_mcdi_ev* */
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ EFSYS_ASSERT(emip->emi_pending_req != NULL);
+ EFSYS_ASSERT(!emip->emi_ev_cpl);
+ emrp = emip->emi_pending_req;
+
+ /* Check for reboot atomically w.r.t efx_mcdi_request_start */
+ if (emip->emi_poll_cnt++ == 0) {
+ if ((rc = efx_mcdi_poll_reboot(enp)) != 0) {
+ emip->emi_pending_req = NULL;
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ goto fail1;
+ }
+ }
+
+ /* Check if a response is available */
+ if (efx_mcdi_poll_response(enp) == B_FALSE) {
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (B_FALSE);
+ }
+
+ /* Read the response header */
+ efx_mcdi_read_response_header(enp, emrp);
+
+ /* Request complete */
+ emip->emi_pending_req = NULL;
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ if ((rc = emrp->emr_rc) != 0)
+ goto fail2;
+
+ efx_mcdi_request_copyout(enp, emrp);
+ return (B_TRUE);
+
+fail2:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail2);
+fail1:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
- if (emcop != NULL && emcop->emco_request_poll != NULL)
- completed = emcop->emco_request_poll(enp);
+ /* Reboot/Assertion */
+ if (rc == EIO || rc == EINTR)
+ efx_mcdi_raise_exception(enp, emrp, rc);
- return (completed);
+ return (B_TRUE);
}
__checkReturn boolean_t
@@ -516,16 +599,6 @@ efx_mcdi_raise_exception(
emtp->emt_exception(emtp->emt_context, exception);
}
-static efx_rc_t
-efx_mcdi_poll_reboot(
- __in efx_nic_t *enp)
-{
- efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
-
- return (emcop->emco_poll_reboot(enp));
-}
-
-
void
efx_mcdi_execute(
__in efx_nic_t *enp,
@@ -1316,7 +1389,6 @@ fail1:
return (rc);
}
-
__checkReturn efx_rc_t
efx_mcdi_firmware_update_supported(
__in efx_nic_t *enp,
@@ -1325,9 +1397,9 @@ efx_mcdi_firmware_update_supported(
efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
efx_rc_t rc;
- if (emcop != NULL && emcop->emco_fw_update_supported != NULL) {
- if ((rc = emcop->emco_fw_update_supported(enp, supportedp))
- != 0)
+ if (emcop != NULL) {
+ if ((rc = emcop->emco_feature_supported(enp,
+ EFX_MCDI_FEATURE_FW_UPDATE, supportedp)) != 0)
goto fail1;
} else {
/* Earlier devices always supported updates */
@@ -1350,9 +1422,9 @@ efx_mcdi_macaddr_change_supported(
efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
efx_rc_t rc;
- if (emcop != NULL && emcop->emco_macaddr_change_supported != NULL) {
- if ((rc = emcop->emco_macaddr_change_supported(enp, supportedp))
- != 0)
+ if (emcop != NULL) {
+ if ((rc = emcop->emco_feature_supported(enp,
+ EFX_MCDI_FEATURE_MACADDR_CHANGE, supportedp)) != 0)
goto fail1;
} else {
/* Earlier devices always supported MAC changes */
@@ -1375,9 +1447,9 @@ efx_mcdi_link_control_supported(
efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
efx_rc_t rc;
- if (emcop != NULL && emcop->emco_link_control_supported != NULL) {
- if ((rc = emcop->emco_link_control_supported(enp, supportedp))
- != 0)
+ if (emcop != NULL) {
+ if ((rc = emcop->emco_feature_supported(enp,
+ EFX_MCDI_FEATURE_LINK_CONTROL, supportedp)) != 0)
goto fail1;
} else {
/* Earlier devices always supported link control */
@@ -1400,9 +1472,9 @@ efx_mcdi_mac_spoofing_supported(
efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
efx_rc_t rc;
- if (emcop != NULL && emcop->emco_mac_spoofing_supported != NULL) {
- if ((rc = emcop->emco_mac_spoofing_supported(enp, supportedp))
- != 0)
+ if (emcop != NULL) {
+ if ((rc = emcop->emco_feature_supported(enp,
+ EFX_MCDI_FEATURE_MAC_SPOOFING, supportedp)) != 0)
goto fail1;
} else {
/* Earlier devices always supported MAC spoofing */
diff --git a/sys/dev/sfxge/common/efx_mcdi.h b/sys/dev/sfxge/common/efx_mcdi.h
index f25fb4e..18924a0 100644
--- a/sys/dev/sfxge/common/efx_mcdi.h
+++ b/sys/dev/sfxge/common/efx_mcdi.h
@@ -386,11 +386,18 @@ efx_mcdi_get_loopback_modes(
#define MCDI_CMD_DWORD_FIELD(_edp, _field) \
EFX_DWORD_FIELD(*_edp, MC_CMD_ ## _field)
-#define EFX_MCDI_HAVE_PRIVILEGE(mask, priv) \
- (((mask) & \
- (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) == \
+#define EFX_MCDI_HAVE_PRIVILEGE(mask, priv) \
+ (((mask) & (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) == \
(MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv))
+typedef enum efx_mcdi_feature_id_e {
+ EFX_MCDI_FEATURE_FW_UPDATE = 0,
+ EFX_MCDI_FEATURE_LINK_CONTROL,
+ EFX_MCDI_FEATURE_MACADDR_CHANGE,
+ EFX_MCDI_FEATURE_MAC_SPOOFING,
+ EFX_MCDI_FEATURE_NIDS
+} efx_mcdi_feature_id_t;
+
#ifdef __cplusplus
}
#endif
diff --git a/sys/dev/sfxge/common/hunt_impl.h b/sys/dev/sfxge/common/hunt_impl.h
index 1a57596..49a1244 100644
--- a/sys/dev/sfxge/common/hunt_impl.h
+++ b/sys/dev/sfxge/common/hunt_impl.h
@@ -263,6 +263,10 @@ hunt_mcdi_request_copyin(
__in boolean_t ev_cpl,
__in boolean_t new_epoch);
+extern __checkReturn boolean_t
+hunt_mcdi_poll_response(
+ __in efx_nic_t *enp);
+
extern void
hunt_mcdi_read_response(
__in efx_nic_t *enp,
@@ -270,10 +274,6 @@ hunt_mcdi_read_response(
__in size_t offset,
__in size_t length);
-extern __checkReturn boolean_t
-hunt_mcdi_request_poll(
- __in efx_nic_t *enp);
-
extern void
hunt_mcdi_request_copyout(
__in efx_nic_t *enp,
@@ -284,26 +284,11 @@ hunt_mcdi_poll_reboot(
__in efx_nic_t *enp);
extern __checkReturn efx_rc_t
-hunt_mcdi_fw_update_supported(
- __in efx_nic_t *enp,
- __out boolean_t *supportedp);
-
-extern __checkReturn efx_rc_t
-hunt_mcdi_macaddr_change_supported(
+hunt_mcdi_feature_supported(
__in efx_nic_t *enp,
+ __in efx_mcdi_feature_id_t id,
__out boolean_t *supportedp);
-extern __checkReturn efx_rc_t
-hunt_mcdi_link_control_supported(
- __in efx_nic_t *enp,
- __out boolean_t *supportedp);
-
-extern __checkReturn efx_rc_t
-hunt_mcdi_mac_spoofing_supported(
- __in efx_nic_t *enp,
- __out boolean_t *supportedp);
-
-
#endif /* EFSYS_OPT_MCDI */
/* NVRAM */
@@ -722,7 +707,7 @@ hunt_tx_qstats_update(
#define HUNT_MIN_PIO_ALLOC_SIZE (HUNT_PIOBUF_SIZE / 32)
-#define HUNT_LEGACY_PF_PRIVILEGE_MASK \
+#define HUNT_LEGACY_PF_PRIVILEGE_MASK \
(MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN | \
MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK | \
MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD | \
@@ -735,7 +720,7 @@ hunt_tx_qstats_update(
MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST | \
MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS)
-#define HUNT_LEGACY_VF_PRIVILEGE_MASK 0
+#define HUNT_LEGACY_VF_PRIVILEGE_MASK 0
typedef uint32_t efx_piobuf_handle_t;
diff --git a/sys/dev/sfxge/common/hunt_mcdi.c b/sys/dev/sfxge/common/hunt_mcdi.c
index 11ad231..2e61e74 100644
--- a/sys/dev/sfxge/common/hunt_mcdi.c
+++ b/sys/dev/sfxge/common/hunt_mcdi.c
@@ -268,7 +268,7 @@ hunt_mcdi_request_copyout(
#endif /* EFSYS_OPT_MCDI_LOGGING */
}
-static __checkReturn boolean_t
+ __checkReturn boolean_t
hunt_mcdi_poll_response(
__in efx_nic_t *enp)
{
@@ -299,59 +299,6 @@ hunt_mcdi_read_response(
}
}
- __checkReturn boolean_t
-hunt_mcdi_request_poll(
- __in efx_nic_t *enp)
-{
- efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
- efx_mcdi_req_t *emrp;
- int state;
- efx_rc_t rc;
-
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
-
- /* Serialise against post-watchdog efx_mcdi_ev* */
- EFSYS_LOCK(enp->en_eslp, state);
-
- EFSYS_ASSERT(emip->emi_pending_req != NULL);
- EFSYS_ASSERT(!emip->emi_ev_cpl);
- emrp = emip->emi_pending_req;
-
- /* Check if a response is available */
- if (hunt_mcdi_poll_response(enp) == B_FALSE) {
- EFSYS_UNLOCK(enp->en_eslp, state);
- return (B_FALSE);
- }
-
- /* Read the response header */
- efx_mcdi_read_response_header(enp, emrp);
-
- /* Request complete */
- emip->emi_pending_req = NULL;
-
- /* Ensure stale MCDI requests fail after an MC reboot. */
- emip->emi_new_epoch = B_FALSE;
-
- EFSYS_UNLOCK(enp->en_eslp, state);
-
- if ((rc = emrp->emr_rc) != 0)
- goto fail1;
-
- hunt_mcdi_request_copyout(enp, emrp);
- goto out;
-
-fail1:
- if (!emrp->emr_quiet)
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- /* Reboot/Assertion */
- if (rc == EIO || rc == EINTR)
- efx_mcdi_raise_exception(enp, emrp, rc);
-
-out:
- return (B_TRUE);
-}
-
efx_rc_t
hunt_mcdi_poll_reboot(
__in efx_nic_t *enp)
@@ -399,94 +346,73 @@ fail1:
}
__checkReturn efx_rc_t
-hunt_mcdi_fw_update_supported(
- __in efx_nic_t *enp,
- __out boolean_t *supportedp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
-
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
-
- /*
- * Use privilege mask state at MCDI attach.
- * Admin privilege must be used prior to introduction of
- * specific flag.
- */
- *supportedp =
- EFX_MCDI_HAVE_PRIVILEGE(encp->enc_privilege_mask, ADMIN);
-
- return (0);
-}
-
- __checkReturn efx_rc_t
-hunt_mcdi_macaddr_change_supported(
+hunt_mcdi_feature_supported(
__in efx_nic_t *enp,
+ __in efx_mcdi_feature_id_t id,
__out boolean_t *supportedp)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
uint32_t privilege_mask = encp->enc_privilege_mask;
+ efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
/*
* Use privilege mask state at MCDI attach.
- * Admin privilege must be used prior to introduction of
- * mac spoofing privilege (at v4.6), which is used up to
- * introduction of change mac spoofing privilege (at v4.7)
*/
- *supportedp =
- EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, CHANGE_MAC) ||
- EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, MAC_SPOOFING) ||
- EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, ADMIN);
- return (0);
-}
-
- __checkReturn efx_rc_t
-hunt_mcdi_mac_spoofing_supported(
- __in efx_nic_t *enp,
- __out boolean_t *supportedp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint32_t privilege_mask = encp->enc_privilege_mask;
-
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
-
- /*
- * Use privilege mask state at MCDI attach.
- * Admin privilege must be used prior to introduction of
- * mac spoofing privilege (at v4.6), which is used up to
- * introduction of mac spoofing TX privilege (at v4.7)
- */
- *supportedp =
- EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, MAC_SPOOFING_TX) ||
- EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, MAC_SPOOFING) ||
- EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, ADMIN);
+ switch (id) {
+ case EFX_MCDI_FEATURE_FW_UPDATE:
+ /*
+ * Admin privilege must be used prior to introduction of
+ * specific flag.
+ */
+ *supportedp =
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, ADMIN);
+ break;
+ case EFX_MCDI_FEATURE_LINK_CONTROL:
+ /*
+ * Admin privilege used prior to introduction of
+ * specific flag.
+ */
+ *supportedp =
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, LINK) ||
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, ADMIN);
+ break;
+ case EFX_MCDI_FEATURE_MACADDR_CHANGE:
+ /*
+ * Admin privilege must be used prior to introduction of
+ * mac spoofing privilege (at v4.6), which is used up to
+ * introduction of change mac spoofing privilege (at v4.7)
+ */
+ *supportedp =
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, CHANGE_MAC) ||
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, MAC_SPOOFING) ||
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, ADMIN);
+ break;
+ case EFX_MCDI_FEATURE_MAC_SPOOFING:
+ /*
+ * Admin privilege must be used prior to introduction of
+ * mac spoofing privilege (at v4.6), which is used up to
+ * introduction of mac spoofing TX privilege (at v4.7)
+ */
+ *supportedp =
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, MAC_SPOOFING_TX) ||
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, MAC_SPOOFING) ||
+ EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, ADMIN);
+ break;
+ default:
+ rc = ENOTSUP;
+ goto fail1;
+ break;
+ }
return (0);
-}
-
- __checkReturn efx_rc_t
-hunt_mcdi_link_control_supported(
- __in efx_nic_t *enp,
- __out boolean_t *supportedp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint32_t privilege_mask = encp->enc_privilege_mask;
-
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
-
- /*
- * Use privilege mask state at MCDI attach.
- * Admin privilege used prior to introduction of
- * specific flag.
- */
- *supportedp =
- EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, LINK) ||
- EFX_MCDI_HAVE_PRIVILEGE(privilege_mask, ADMIN);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
- return (0);
+ return (rc);
}
#endif /* EFSYS_OPT_MCDI */
diff --git a/sys/dev/sfxge/common/siena_impl.h b/sys/dev/sfxge/common/siena_impl.h
index 386d53b..0433edb 100644
--- a/sys/dev/sfxge/common/siena_impl.h
+++ b/sys/dev/sfxge/common/siena_impl.h
@@ -121,6 +121,10 @@ siena_mcdi_request_copyin(
__in boolean_t ev_cpl,
__in boolean_t new_epoch);
+extern __checkReturn boolean_t
+siena_mcdi_poll_response(
+ __in efx_nic_t *enp);
+
extern void
siena_mcdi_read_response(
__in efx_nic_t *enp,
@@ -128,10 +132,6 @@ siena_mcdi_read_response(
__in size_t offset,
__in size_t length);
-extern __checkReturn boolean_t
-siena_mcdi_request_poll(
- __in efx_nic_t *enp);
-
extern void
siena_mcdi_request_copyout(
__in efx_nic_t *enp,
@@ -146,18 +146,9 @@ siena_mcdi_fini(
__in efx_nic_t *enp);
extern __checkReturn efx_rc_t
-siena_mcdi_fw_update_supported(
- __in efx_nic_t *enp,
- __out boolean_t *supportedp);
-
-extern __checkReturn efx_rc_t
-siena_mcdi_macaddr_change_supported(
- __in efx_nic_t *enp,
- __out boolean_t *supportedp);
-
-extern __checkReturn efx_rc_t
-siena_mcdi_link_control_supported(
+siena_mcdi_feature_supported(
__in efx_nic_t *enp,
+ __in efx_mcdi_feature_id_t id,
__out boolean_t *supportedp);
#endif /* EFSYS_OPT_MCDI */
diff --git a/sys/dev/sfxge/common/siena_mcdi.c b/sys/dev/sfxge/common/siena_mcdi.c
index 557bd54..a350598 100644
--- a/sys/dev/sfxge/common/siena_mcdi.c
+++ b/sys/dev/sfxge/common/siena_mcdi.c
@@ -180,7 +180,7 @@ siena_mcdi_poll_reboot(
#endif
}
-static __checkReturn boolean_t
+extern __checkReturn boolean_t
siena_mcdi_poll_response(
__in efx_nic_t *enp)
{
@@ -218,69 +218,6 @@ siena_mcdi_read_response(
}
}
- __checkReturn boolean_t
-siena_mcdi_request_poll(
- __in efx_nic_t *enp)
-{
- efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
- efx_mcdi_req_t *emrp;
- int state;
- efx_rc_t rc;
-
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
-
- /* Serialise against post-watchdog efx_mcdi_ev* */
- EFSYS_LOCK(enp->en_eslp, state);
-
- EFSYS_ASSERT(emip->emi_pending_req != NULL);
- EFSYS_ASSERT(!emip->emi_ev_cpl);
- emrp = emip->emi_pending_req;
-
- /* Check for reboot atomically w.r.t efx_mcdi_request_start */
- if (emip->emi_poll_cnt++ == 0) {
- if ((rc = siena_mcdi_poll_reboot(enp)) != 0) {
- emip->emi_pending_req = NULL;
- EFSYS_UNLOCK(enp->en_eslp, state);
-
- goto fail1;
- }
- }
-
- /* Check if a response is available */
- if (siena_mcdi_poll_response(enp) == B_FALSE) {
- EFSYS_UNLOCK(enp->en_eslp, state);
- return (B_FALSE);
- }
-
- /* Read the response header */
- efx_mcdi_read_response_header(enp, emrp);
-
- /* Request complete */
- emip->emi_pending_req = NULL;
-
- EFSYS_UNLOCK(enp->en_eslp, state);
-
- if ((rc = emrp->emr_rc) != 0)
- goto fail2;
-
- siena_mcdi_request_copyout(enp, emrp);
- goto out;
-
-fail2:
- if (!emrp->emr_quiet)
- EFSYS_PROBE(fail2);
-fail1:
- if (!emrp->emr_quiet)
- EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- /* Reboot/Assertion */
- if (rc == EIO || rc == EINTR)
- efx_mcdi_raise_exception(enp, emrp, rc);
-
-out:
- return (B_TRUE);
-}
-
__checkReturn efx_rc_t
siena_mcdi_init(
__in efx_nic_t *enp,
@@ -329,39 +266,34 @@ siena_mcdi_fini(
}
__checkReturn efx_rc_t
-siena_mcdi_fw_update_supported(
+siena_mcdi_feature_supported(
__in efx_nic_t *enp,
+ __in efx_mcdi_feature_id_t id,
__out boolean_t *supportedp)
{
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
-
- *supportedp = B_TRUE;
-
- return (0);
-}
+ efx_rc_t rc;
- __checkReturn efx_rc_t
-siena_mcdi_macaddr_change_supported(
- __in efx_nic_t *enp,
- __out boolean_t *supportedp)
-{
EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
- *supportedp = B_TRUE;
+ switch (id) {
+ case EFX_MCDI_FEATURE_FW_UPDATE:
+ case EFX_MCDI_FEATURE_LINK_CONTROL:
+ case EFX_MCDI_FEATURE_MACADDR_CHANGE:
+ case EFX_MCDI_FEATURE_MAC_SPOOFING:
+ *supportedp = B_TRUE;
+ break;
+ default:
+ rc = ENOTSUP;
+ goto fail1;
+ break;
+ }
return (0);
-}
- __checkReturn efx_rc_t
-siena_mcdi_link_control_supported(
- __in efx_nic_t *enp,
- __out boolean_t *supportedp)
-{
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
-
- *supportedp = B_TRUE;
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
- return (0);
+ return (rc);
}
#endif /* EFSYS_OPT_SIENA && EFSYS_OPT_MCDI */
diff --git a/sys/dev/sfxge/sfxge.c b/sys/dev/sfxge/sfxge.c
index 97588c7..db6225d 100644
--- a/sys/dev/sfxge/sfxge.c
+++ b/sys/dev/sfxge/sfxge.c
@@ -95,6 +95,13 @@ SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_ring, CTLFLAG_RDTUN,
&sfxge_tx_ring_entries, 0,
"Maximum number of descriptors in a transmit ring");
+#define SFXGE_PARAM_RESTART_ATTEMPTS SFXGE_PARAM(restart_attempts)
+static int sfxge_restart_attempts = 3;
+TUNABLE_INT(SFXGE_PARAM_RESTART_ATTEMPTS, &sfxge_restart_attempts);
+SYSCTL_INT(_hw_sfxge, OID_AUTO, restart_attempts, CTLFLAG_RDTUN,
+ &sfxge_restart_attempts, 0,
+ "Maximum number of attempts to bring interface up after reset");
+
#if EFSYS_OPT_MCDI_LOGGING
#define SFXGE_PARAM_MCDI_LOGGING SFXGE_PARAM(mcdi_logging)
static int sfxge_mcdi_logging = 0;
@@ -994,7 +1001,7 @@ sfxge_reset(void *arg, int npending)
sfxge_stop(sc);
efx_nic_reset(sc->enp);
- for (attempt = 0; attempt < 3; ++attempt) {
+ for (attempt = 0; attempt < sfxge_restart_attempts; ++attempt) {
if ((rc = sfxge_start(sc)) == 0)
goto done;
diff --git a/sys/dev/sn/if_sn_pccard.c b/sys/dev/sn/if_sn_pccard.c
index 5c0d4ee..13f4862 100644
--- a/sys/dev/sn/if_sn_pccard.c
+++ b/sys/dev/sn/if_sn_pccard.c
@@ -327,3 +327,4 @@ extern devclass_t sn_devclass;
DRIVER_MODULE(sn, pccard, sn_pccard_driver, sn_devclass, 0, 0);
MODULE_DEPEND(sn, ether, 1, 1, 1);
+PCCARD_PNP_INFO(sn_pccard_products);
diff --git a/sys/dev/snc/if_snc_pccard.c b/sys/dev/snc/if_snc_pccard.c
index 552a11c..7f975be 100644
--- a/sys/dev/snc/if_snc_pccard.c
+++ b/sys/dev/snc/if_snc_pccard.c
@@ -92,6 +92,7 @@ static driver_t snc_pccard_driver = {
DRIVER_MODULE(snc, pccard, snc_pccard_driver, snc_devclass, 0, 0);
MODULE_DEPEND(snc, ether, 1, 1, 1);
+PCCARD_PNP_INFO(snc_pccard_products);
/*
* snc_pccard_detach - detach this instance from the device.
diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index 063d8ce..c3baf7f 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -6118,3 +6118,4 @@ DRIVER_MODULE_ORDERED(uaudio, uhub, uaudio_driver, uaudio_devclass, NULL, 0, SI_
MODULE_DEPEND(uaudio, usb, 1, 1, 1);
MODULE_DEPEND(uaudio, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
MODULE_VERSION(uaudio, 1);
+USB_PNP_HOST_INFO(uaudio_devs);
diff --git a/sys/dev/stg/tmc18c30_pccard.c b/sys/dev/stg/tmc18c30_pccard.c
index a10c001..a172d52 100644
--- a/sys/dev/stg/tmc18c30_pccard.c
+++ b/sys/dev/stg/tmc18c30_pccard.c
@@ -136,3 +136,4 @@ static driver_t stg_pccard_driver = {
DRIVER_MODULE(stg, pccard, stg_pccard_driver, stg_devclass, 0, 0);
MODULE_DEPEND(stg, scsi_low, 1, 1, 1);
+PCCARD_PNP_INFO(stg_products);
diff --git a/sys/dev/uart/uart_bus_pccard.c b/sys/dev/uart/uart_bus_pccard.c
index 0189a5f..edd3f29 100644
--- a/sys/dev/uart/uart_bus_pccard.c
+++ b/sys/dev/uart/uart_bus_pccard.c
@@ -55,6 +55,8 @@ static device_method_t uart_pccard_methods[] = {
{ 0, 0 }
};
+static uint32_t uart_pccard_function = PCCARD_FUNCTION_SERIAL;
+
static driver_t uart_pccard_driver = {
uart_driver_name,
uart_pccard_methods,
@@ -76,7 +78,7 @@ uart_pccard_probe(device_t dev)
* some serial cards are better serviced by other drivers, so
* allow other drivers to claim it, if they want.
*/
- if (fcn == PCCARD_FUNCTION_SERIAL)
+ if (fcn == uart_pccard_function)
return (BUS_PROBE_GENERIC);
return (ENXIO);
@@ -98,3 +100,5 @@ uart_pccard_attach(device_t dev)
}
DRIVER_MODULE(uart, pccard, uart_pccard_driver, uart_devclass, 0, 0);
+MODULE_PNP_INFO("U32:function_type;", pccard, uart, &uart_pccard_function,
+ sizeof(uart_pccard_function), 1);
diff --git a/sys/dev/usb/input/atp.c b/sys/dev/usb/input/atp.c
index 6b9e2ac..2d93d09 100644
--- a/sys/dev/usb/input/atp.c
+++ b/sys/dev/usb/input/atp.c
@@ -2630,3 +2630,5 @@ static driver_t atp_driver = {
DRIVER_MODULE(atp, uhub, atp_driver, atp_devclass, NULL, 0);
MODULE_DEPEND(atp, usb, 1, 1, 1);
MODULE_VERSION(atp, 1);
+USB_PNP_HOST_INFO(fg_devs);
+USB_PNP_HOST_INFO(wsp_devs);
diff --git a/sys/dev/usb/input/uep.c b/sys/dev/usb/input/uep.c
index 260d281..cdcad09 100644
--- a/sys/dev/usb/input/uep.c
+++ b/sys/dev/usb/input/uep.c
@@ -441,3 +441,4 @@ static driver_t uep_driver = {
DRIVER_MODULE(uep, uhub, uep_driver, uep_devclass, NULL, NULL);
MODULE_DEPEND(uep, usb, 1, 1, 1);
MODULE_VERSION(uep, 1);
+USB_PNP_HOST_INFO(uep_devs);
diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c
index b0fe3a0..88c68a7 100644
--- a/sys/dev/usb/input/uhid.c
+++ b/sys/dev/usb/input/uhid.c
@@ -878,3 +878,4 @@ static driver_t uhid_driver = {
DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass, NULL, 0);
MODULE_DEPEND(uhid, usb, 1, 1, 1);
MODULE_VERSION(uhid, 1);
+USB_PNP_HOST_INFO(uhid_devs);
diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c
index 3938952..219d02b 100644
--- a/sys/dev/usb/input/ukbd.c
+++ b/sys/dev/usb/input/ukbd.c
@@ -2178,3 +2178,4 @@ static driver_t ukbd_driver = {
DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0);
MODULE_DEPEND(ukbd, usb, 1, 1, 1);
MODULE_VERSION(ukbd, 1);
+USB_PNP_HOST_INFO(ukbd_devs);
diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c
index 265df4b..43784bf 100644
--- a/sys/dev/usb/input/ums.c
+++ b/sys/dev/usb/input/ums.c
@@ -1052,3 +1052,4 @@ static driver_t ums_driver = {
DRIVER_MODULE(ums, uhub, ums_driver, ums_devclass, NULL, 0);
MODULE_DEPEND(ums, usb, 1, 1, 1);
MODULE_VERSION(ums, 1);
+USB_PNP_HOST_INFO(ums_devs);
diff --git a/sys/dev/usb/input/wsp.c b/sys/dev/usb/input/wsp.c
index 1858c12..86c9352 100644
--- a/sys/dev/usb/input/wsp.c
+++ b/sys/dev/usb/input/wsp.c
@@ -1395,3 +1395,4 @@ static devclass_t wsp_devclass;
DRIVER_MODULE(wsp, uhub, wsp_driver, wsp_devclass, NULL, 0);
MODULE_DEPEND(wsp, usb, 1, 1, 1);
MODULE_VERSION(wsp, 1);
+USB_PNP_HOST_INFO(wsp_devs);
diff --git a/sys/dev/usb/misc/udbp.c b/sys/dev/usb/misc/udbp.c
index 8140170..85924b3 100644
--- a/sys/dev/usb/misc/udbp.c
+++ b/sys/dev/usb/misc/udbp.c
@@ -258,10 +258,20 @@ static driver_t udbp_driver = {
.size = sizeof(struct udbp_softc),
};
+static const STRUCT_USB_HOST_ID udbp_devs[] = {
+ {USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_TURBOCONNECT, 0)},
+ {USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_GADGETZERO, 0)},
+ {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301, 0)},
+ {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302, 0)},
+ {USB_VPI(USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZLINK, 0)},
+ {USB_VPI(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL620USB, 0)},
+};
+
DRIVER_MODULE(udbp, uhub, udbp_driver, udbp_devclass, udbp_modload, 0);
MODULE_DEPEND(udbp, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
MODULE_DEPEND(udbp, usb, 1, 1, 1);
MODULE_VERSION(udbp, 1);
+USB_PNP_HOST_INFO(udbp_devs);
static int
udbp_modload(module_t mod, int event, void *data)
@@ -289,15 +299,6 @@ udbp_modload(module_t mod, int event, void *data)
return (error);
}
-static const STRUCT_USB_HOST_ID udbp_devs[] = {
- {USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_TURBOCONNECT, 0)},
- {USB_VPI(USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_GADGETZERO, 0)},
- {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301, 0)},
- {USB_VPI(USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302, 0)},
- {USB_VPI(USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZLINK, 0)},
- {USB_VPI(USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL620USB, 0)},
-};
-
static int
udbp_probe(device_t dev)
{
diff --git a/sys/dev/usb/misc/ufm.c b/sys/dev/usb/misc/ufm.c
index 0612dd2..e7423b2 100644
--- a/sys/dev/usb/misc/ufm.c
+++ b/sys/dev/usb/misc/ufm.c
@@ -115,14 +115,15 @@ static driver_t ufm_driver = {
.size = sizeof(struct ufm_softc),
};
-DRIVER_MODULE(ufm, uhub, ufm_driver, ufm_devclass, NULL, 0);
-MODULE_DEPEND(ufm, usb, 1, 1, 1);
-MODULE_VERSION(ufm, 1);
-
static const STRUCT_USB_HOST_ID ufm_devs[] = {
{USB_VPI(USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_FMRADIO, 0)},
};
+DRIVER_MODULE(ufm, uhub, ufm_driver, ufm_devclass, NULL, 0);
+MODULE_DEPEND(ufm, usb, 1, 1, 1);
+MODULE_VERSION(ufm, 1);
+USB_PNP_HOST_INFO(ufm_devs);
+
static int
ufm_probe(device_t dev)
{
diff --git a/sys/dev/usb/misc/ugold.c b/sys/dev/usb/misc/ugold.c
index d6f8f77..88190b0 100644
--- a/sys/dev/usb/misc/ugold.c
+++ b/sys/dev/usb/misc/ugold.c
@@ -136,9 +136,14 @@ static driver_t ugold_driver = {
.size = sizeof(struct ugold_softc),
};
+static const STRUCT_USB_HOST_ID ugold_devs[] = {
+ {USB_VPI(USB_VENDOR_CHICONY2, USB_PRODUCT_CHICONY2_TEMPER, 0)},
+};
+
DRIVER_MODULE(ugold, uhub, ugold_driver, ugold_devclass, NULL, NULL);
MODULE_DEPEND(ugold, usb, 1, 1, 1);
MODULE_VERSION(ugold, 1);
+USB_PNP_HOST_INFO(ugold_devs);
static const struct usb_config ugold_config[UGOLD_N_TRANSFER] = {
@@ -153,10 +158,6 @@ static const struct usb_config ugold_config[UGOLD_N_TRANSFER] = {
},
};
-static const STRUCT_USB_HOST_ID ugold_devs[] = {
- {USB_VPI(USB_VENDOR_CHICONY2, USB_PRODUCT_CHICONY2_TEMPER, 0)},
-};
-
static void
ugold_timeout(void *arg)
{
diff --git a/sys/dev/usb/misc/uled.c b/sys/dev/usb/misc/uled.c
index efe6d9c..df117ea 100644
--- a/sys/dev/usb/misc/uled.c
+++ b/sys/dev/usb/misc/uled.c
@@ -107,14 +107,15 @@ static driver_t uled_driver = {
.size = sizeof(struct uled_softc),
};
-DRIVER_MODULE(uled, uhub, uled_driver, uled_devclass, NULL, NULL);
-MODULE_DEPEND(uled, usb, 1, 1, 1);
-MODULE_VERSION(uled, 1);
-
static const STRUCT_USB_HOST_ID uled_devs[] = {
{USB_VPI(USB_VENDOR_DREAMLINK, USB_PRODUCT_DREAMLINK_DL100B, 0)},
};
+DRIVER_MODULE(uled, uhub, uled_driver, uled_devclass, NULL, NULL);
+MODULE_DEPEND(uled, usb, 1, 1, 1);
+MODULE_VERSION(uled, 1);
+USB_PNP_HOST_INFO(uled_devs);
+
static int
uled_probe(device_t dev)
{
diff --git a/sys/dev/usb/net/if_aue.c b/sys/dev/usb/net/if_aue.c
index 81b9cca..a756820 100644
--- a/sys/dev/usb/net/if_aue.c
+++ b/sys/dev/usb/net/if_aue.c
@@ -279,6 +279,7 @@ MODULE_DEPEND(aue, usb, 1, 1, 1);
MODULE_DEPEND(aue, ether, 1, 1, 1);
MODULE_DEPEND(aue, miibus, 1, 1, 1);
MODULE_VERSION(aue, 1);
+USB_PNP_HOST_INFO(aue_devs);
static const struct usb_ether_methods aue_ue_methods = {
.ue_attach_post = aue_attach_post,
diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c
index 1a7987c..1995497 100644
--- a/sys/dev/usb/net/if_axe.c
+++ b/sys/dev/usb/net/if_axe.c
@@ -278,6 +278,7 @@ MODULE_DEPEND(axe, usb, 1, 1, 1);
MODULE_DEPEND(axe, ether, 1, 1, 1);
MODULE_DEPEND(axe, miibus, 1, 1, 1);
MODULE_VERSION(axe, 1);
+USB_PNP_HOST_INFO(axe_devs);
static const struct usb_ether_methods axe_ue_methods = {
.ue_attach_post = axe_attach_post,
diff --git a/sys/dev/usb/net/if_axge.c b/sys/dev/usb/net/if_axge.c
index 2c695cd..eb025c7 100644
--- a/sys/dev/usb/net/if_axge.c
+++ b/sys/dev/usb/net/if_axge.c
@@ -190,6 +190,7 @@ MODULE_DEPEND(axge, usb, 1, 1, 1);
MODULE_DEPEND(axge, ether, 1, 1, 1);
MODULE_DEPEND(axge, miibus, 1, 1, 1);
MODULE_VERSION(axge, 1);
+USB_PNP_HOST_INFO(axge_devs);
static const struct usb_ether_methods axge_ue_methods = {
.ue_attach_post = axge_attach_post,
diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c
index 397c4f6..8b220ae 100644
--- a/sys/dev/usb/net/if_cdce.c
+++ b/sys/dev/usb/net/if_cdce.c
@@ -256,21 +256,6 @@ static eventhandler_tag cdce_etag;
static int cdce_driver_loaded(struct module *, int, void *);
-DRIVER_MODULE(cdce, uhub, cdce_driver, cdce_devclass, cdce_driver_loaded, 0);
-MODULE_VERSION(cdce, 1);
-MODULE_DEPEND(cdce, uether, 1, 1, 1);
-MODULE_DEPEND(cdce, usb, 1, 1, 1);
-MODULE_DEPEND(cdce, ether, 1, 1, 1);
-
-static const struct usb_ether_methods cdce_ue_methods = {
- .ue_attach_post = cdce_attach_post,
- .ue_start = cdce_start,
- .ue_init = cdce_init,
- .ue_stop = cdce_stop,
- .ue_setmulti = cdce_setmulti,
- .ue_setpromisc = cdce_setpromisc,
-};
-
static const STRUCT_USB_HOST_ID cdce_switch_devs[] = {
{USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E3272_INIT, MSC_EJECT_HUAWEI2)},
};
@@ -307,6 +292,24 @@ static const STRUCT_USB_DUAL_ID cdce_dual_devs[] = {
{USB_IF_CSI(UICLASS_CDC, UISUBCLASS_NETWORK_CONTROL_MODEL, 0)},
};
+DRIVER_MODULE(cdce, uhub, cdce_driver, cdce_devclass, cdce_driver_loaded, 0);
+MODULE_VERSION(cdce, 1);
+MODULE_DEPEND(cdce, uether, 1, 1, 1);
+MODULE_DEPEND(cdce, usb, 1, 1, 1);
+MODULE_DEPEND(cdce, ether, 1, 1, 1);
+USB_PNP_DEVICE_INFO(cdce_switch_devs);
+USB_PNP_HOST_INFO(cdce_host_devs);
+USB_PNP_DUAL_INFO(cdce_dual_devs);
+
+static const struct usb_ether_methods cdce_ue_methods = {
+ .ue_attach_post = cdce_attach_post,
+ .ue_start = cdce_start,
+ .ue_init = cdce_init,
+ .ue_stop = cdce_stop,
+ .ue_setmulti = cdce_setmulti,
+ .ue_setpromisc = cdce_setpromisc,
+};
+
#if CDCE_HAVE_NCM
/*------------------------------------------------------------------------*
* cdce_ncm_init
diff --git a/sys/dev/usb/net/if_cue.c b/sys/dev/usb/net/if_cue.c
index 9accde9..39860fe 100644
--- a/sys/dev/usb/net/if_cue.c
+++ b/sys/dev/usb/net/if_cue.c
@@ -177,6 +177,7 @@ MODULE_DEPEND(cue, uether, 1, 1, 1);
MODULE_DEPEND(cue, usb, 1, 1, 1);
MODULE_DEPEND(cue, ether, 1, 1, 1);
MODULE_VERSION(cue, 1);
+USB_PNP_HOST_INFO(cue_devs);
static const struct usb_ether_methods cue_ue_methods = {
.ue_attach_post = cue_attach_post,
diff --git a/sys/dev/usb/net/if_ipheth.c b/sys/dev/usb/net/if_ipheth.c
index 7e121cc..d703588 100644
--- a/sys/dev/usb/net/if_ipheth.c
+++ b/sys/dev/usb/net/if_ipheth.c
@@ -131,27 +131,6 @@ static driver_t ipheth_driver = {
static devclass_t ipheth_devclass;
-DRIVER_MODULE(ipheth, uhub, ipheth_driver, ipheth_devclass, NULL, 0);
-MODULE_VERSION(ipheth, 1);
-MODULE_DEPEND(ipheth, uether, 1, 1, 1);
-MODULE_DEPEND(ipheth, usb, 1, 1, 1);
-MODULE_DEPEND(ipheth, ether, 1, 1, 1);
-
-static const struct usb_ether_methods ipheth_ue_methods = {
- .ue_attach_post = ipheth_attach_post,
- .ue_start = ipheth_start,
- .ue_init = ipheth_init,
- .ue_tick = ipheth_tick,
- .ue_stop = ipheth_stop,
- .ue_setmulti = ipheth_setmulti,
- .ue_setpromisc = ipheth_setpromisc,
-};
-
-#define IPHETH_ID(v,p,c,sc,pt) \
- USB_VENDOR(v), USB_PRODUCT(p), \
- USB_IFACE_CLASS(c), USB_IFACE_SUBCLASS(sc), \
- USB_IFACE_PROTOCOL(pt)
-
static const STRUCT_USB_HOST_ID ipheth_devs[] = {
#if 0
{IPHETH_ID(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE,
@@ -181,6 +160,28 @@ static const STRUCT_USB_HOST_ID ipheth_devs[] = {
#endif
};
+DRIVER_MODULE(ipheth, uhub, ipheth_driver, ipheth_devclass, NULL, 0);
+MODULE_VERSION(ipheth, 1);
+MODULE_DEPEND(ipheth, uether, 1, 1, 1);
+MODULE_DEPEND(ipheth, usb, 1, 1, 1);
+MODULE_DEPEND(ipheth, ether, 1, 1, 1);
+USB_PNP_HOST_INFO(ipheth_devs);
+
+static const struct usb_ether_methods ipheth_ue_methods = {
+ .ue_attach_post = ipheth_attach_post,
+ .ue_start = ipheth_start,
+ .ue_init = ipheth_init,
+ .ue_tick = ipheth_tick,
+ .ue_stop = ipheth_stop,
+ .ue_setmulti = ipheth_setmulti,
+ .ue_setpromisc = ipheth_setpromisc,
+};
+
+#define IPHETH_ID(v,p,c,sc,pt) \
+ USB_VENDOR(v), USB_PRODUCT(p), \
+ USB_IFACE_CLASS(c), USB_IFACE_SUBCLASS(sc), \
+ USB_IFACE_PROTOCOL(pt)
+
static int
ipheth_get_mac_addr(struct ipheth_softc *sc)
{
diff --git a/sys/dev/usb/net/if_kue.c b/sys/dev/usb/net/if_kue.c
index 9d2291e..562ead2 100644
--- a/sys/dev/usb/net/if_kue.c
+++ b/sys/dev/usb/net/if_kue.c
@@ -219,6 +219,7 @@ MODULE_DEPEND(kue, uether, 1, 1, 1);
MODULE_DEPEND(kue, usb, 1, 1, 1);
MODULE_DEPEND(kue, ether, 1, 1, 1);
MODULE_VERSION(kue, 1);
+USB_PNP_HOST_INFO(kue_devs);
static const struct usb_ether_methods kue_ue_methods = {
.ue_attach_post = kue_attach_post,
diff --git a/sys/dev/usb/net/if_mos.c b/sys/dev/usb/net/if_mos.c
index 60b5742..1f92629 100644
--- a/sys/dev/usb/net/if_mos.c
+++ b/sys/dev/usb/net/if_mos.c
@@ -247,6 +247,7 @@ MODULE_DEPEND(mos, uether, 1, 1, 1);
MODULE_DEPEND(mos, usb, 1, 1, 1);
MODULE_DEPEND(mos, ether, 1, 1, 1);
MODULE_DEPEND(mos, miibus, 1, 1, 1);
+USB_PNP_HOST_INFO(mos_devs);
static const struct usb_ether_methods mos_ue_methods = {
.ue_attach_post = mos_attach_post,
diff --git a/sys/dev/usb/net/if_rue.c b/sys/dev/usb/net/if_rue.c
index e9fb622..541d62d 100644
--- a/sys/dev/usb/net/if_rue.c
+++ b/sys/dev/usb/net/if_rue.c
@@ -214,6 +214,7 @@ MODULE_DEPEND(rue, usb, 1, 1, 1);
MODULE_DEPEND(rue, ether, 1, 1, 1);
MODULE_DEPEND(rue, miibus, 1, 1, 1);
MODULE_VERSION(rue, 1);
+USB_PNP_HOST_INFO(rue_devs);
static const struct usb_ether_methods rue_ue_methods = {
.ue_attach_post = rue_attach_post,
diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c
index b642a69..19c4615 100644
--- a/sys/dev/usb/net/if_smsc.c
+++ b/sys/dev/usb/net/if_smsc.c
@@ -1858,3 +1858,4 @@ MODULE_DEPEND(smsc, usb, 1, 1, 1);
MODULE_DEPEND(smsc, ether, 1, 1, 1);
MODULE_DEPEND(smsc, miibus, 1, 1, 1);
MODULE_VERSION(smsc, 1);
+USB_PNP_HOST_INFO(smsc_devs);
diff --git a/sys/dev/usb/net/if_udav.c b/sys/dev/usb/net/if_udav.c
index de908a9..7357425 100644
--- a/sys/dev/usb/net/if_udav.c
+++ b/sys/dev/usb/net/if_udav.c
@@ -165,6 +165,21 @@ static driver_t udav_driver = {
static devclass_t udav_devclass;
+static const STRUCT_USB_HOST_ID udav_devs[] = {
+ /* ShanTou DM9601 USB NIC */
+ {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601, 0)},
+ /* ShanTou ST268 USB NIC */
+ {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268, 0)},
+ /* Corega USB-TXC */
+ {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC, 0)},
+ /* ShanTou AMD8515 USB NIC */
+ {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515, 0)},
+ /* Kontron AG USB Ethernet */
+ {USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_DM9601, 0)},
+ {USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_JP1082,
+ UDAV_FLAG_NO_PHY)},
+};
+
DRIVER_MODULE(udav, uhub, udav_driver, udav_devclass, NULL, 0);
DRIVER_MODULE(miibus, udav, miibus_driver, miibus_devclass, 0, 0);
MODULE_DEPEND(udav, uether, 1, 1, 1);
@@ -172,6 +187,7 @@ MODULE_DEPEND(udav, usb, 1, 1, 1);
MODULE_DEPEND(udav, ether, 1, 1, 1);
MODULE_DEPEND(udav, miibus, 1, 1, 1);
MODULE_VERSION(udav, 1);
+USB_PNP_HOST_INFO(udav_devs);
static const struct usb_ether_methods udav_ue_methods = {
.ue_attach_post = udav_attach_post,
@@ -208,21 +224,6 @@ SYSCTL_INT(_hw_usb_udav, OID_AUTO, debug, CTLFLAG_RWTUN, &udav_debug, 0,
#define UDAV_CLRBIT(sc, reg, x) \
udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
-static const STRUCT_USB_HOST_ID udav_devs[] = {
- /* ShanTou DM9601 USB NIC */
- {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601, 0)},
- /* ShanTou ST268 USB NIC */
- {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268, 0)},
- /* Corega USB-TXC */
- {USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC, 0)},
- /* ShanTou AMD8515 USB NIC */
- {USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515, 0)},
- /* Kontron AG USB Ethernet */
- {USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_DM9601, 0)},
- {USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_JP1082,
- UDAV_FLAG_NO_PHY)},
-};
-
static void
udav_attach_post(struct usb_ether *ue)
{
diff --git a/sys/dev/usb/net/if_urndis.c b/sys/dev/usb/net/if_urndis.c
index 32fa533..749f874 100644
--- a/sys/dev/usb/net/if_urndis.c
+++ b/sys/dev/usb/net/if_urndis.c
@@ -161,21 +161,6 @@ static driver_t urndis_driver = {
static devclass_t urndis_devclass;
-DRIVER_MODULE(urndis, uhub, urndis_driver, urndis_devclass, NULL, NULL);
-MODULE_VERSION(urndis, 1);
-MODULE_DEPEND(urndis, uether, 1, 1, 1);
-MODULE_DEPEND(urndis, usb, 1, 1, 1);
-MODULE_DEPEND(urndis, ether, 1, 1, 1);
-
-static const struct usb_ether_methods urndis_ue_methods = {
- .ue_attach_post = urndis_attach_post,
- .ue_start = urndis_start,
- .ue_init = urndis_init,
- .ue_stop = urndis_stop,
- .ue_setmulti = urndis_setmulti,
- .ue_setpromisc = urndis_setpromisc,
-};
-
static const STRUCT_USB_HOST_ID urndis_host_devs[] = {
/* Generic RNDIS class match */
{USB_IFACE_CLASS(UICLASS_CDC),
@@ -191,6 +176,22 @@ static const STRUCT_USB_HOST_ID urndis_host_devs[] = {
USB_IFACE_PROTOCOL(0xff)},
};
+DRIVER_MODULE(urndis, uhub, urndis_driver, urndis_devclass, NULL, NULL);
+MODULE_VERSION(urndis, 1);
+MODULE_DEPEND(urndis, uether, 1, 1, 1);
+MODULE_DEPEND(urndis, usb, 1, 1, 1);
+MODULE_DEPEND(urndis, ether, 1, 1, 1);
+USB_PNP_HOST_INFO(urndis_host_devs);
+
+static const struct usb_ether_methods urndis_ue_methods = {
+ .ue_attach_post = urndis_attach_post,
+ .ue_start = urndis_start,
+ .ue_init = urndis_init,
+ .ue_stop = urndis_stop,
+ .ue_setmulti = urndis_setmulti,
+ .ue_setpromisc = urndis_setpromisc,
+};
+
static int
urndis_probe(device_t dev)
{
diff --git a/sys/dev/usb/net/if_usie.c b/sys/dev/usb/net/if_usie.c
index 6736cbc..528c1e4 100644
--- a/sys/dev/usb/net/if_usie.c
+++ b/sys/dev/usb/net/if_usie.c
@@ -212,6 +212,7 @@ DRIVER_MODULE(usie, uhub, usie_driver, usie_devclass, usie_driver_loaded, 0);
MODULE_DEPEND(usie, ucom, 1, 1, 1);
MODULE_DEPEND(usie, usb, 1, 1, 1);
MODULE_VERSION(usie, 1);
+USB_PNP_HOST_INFO(usie_devs);
static const struct ucom_callback usie_uc_callback = {
.ucom_cfg_get_status = &usie_uc_cfg_get_status,
diff --git a/sys/dev/usb/net/uhso.c b/sys/dev/usb/net/uhso.c
index 1851320..f2afb0b 100644
--- a/sys/dev/usb/net/uhso.c
+++ b/sys/dev/usb/net/uhso.c
@@ -497,6 +497,7 @@ DRIVER_MODULE(uhso, uhub, uhso_driver, uhso_devclass, uhso_driver_loaded, 0);
MODULE_DEPEND(uhso, ucom, 1, 1, 1);
MODULE_DEPEND(uhso, usb, 1, 1, 1);
MODULE_VERSION(uhso, 1);
+USB_PNP_HOST_INFO(uhso_devs);
static struct ucom_callback uhso_ucom_callback = {
.ucom_cfg_get_status = &uhso_ucom_cfg_get_status,
diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index 065da28..ab6b20a 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -198,11 +198,6 @@ static driver_t u3g_driver = {
.size = sizeof(struct u3g_softc),
};
-DRIVER_MODULE(u3g, uhub, u3g_driver, u3g_devclass, u3g_driver_loaded, 0);
-MODULE_DEPEND(u3g, ucom, 1, 1, 1);
-MODULE_DEPEND(u3g, usb, 1, 1, 1);
-MODULE_VERSION(u3g, 1);
-
static const STRUCT_USB_HOST_ID u3g_devs[] = {
#define U3G_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
U3G_DEV(ACERP, H10, 0),
@@ -587,6 +582,12 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = {
#undef U3G_DEV
};
+DRIVER_MODULE(u3g, uhub, u3g_driver, u3g_devclass, u3g_driver_loaded, 0);
+MODULE_DEPEND(u3g, ucom, 1, 1, 1);
+MODULE_DEPEND(u3g, usb, 1, 1, 1);
+MODULE_VERSION(u3g, 1);
+USB_PNP_HOST_INFO(u3g_devs);
+
static int
u3g_sierra_init(struct usb_device *udev)
{
diff --git a/sys/dev/usb/serial/uark.c b/sys/dev/usb/serial/uark.c
index f0737f2..e0e6d0b 100644
--- a/sys/dev/usb/serial/uark.c
+++ b/sys/dev/usb/serial/uark.c
@@ -168,14 +168,15 @@ static driver_t uark_driver = {
.size = sizeof(struct uark_softc),
};
+static const STRUCT_USB_HOST_ID uark_devs[] = {
+ {USB_VPI(USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116, 0)},
+};
+
DRIVER_MODULE(uark, uhub, uark_driver, uark_devclass, NULL, 0);
MODULE_DEPEND(uark, ucom, 1, 1, 1);
MODULE_DEPEND(uark, usb, 1, 1, 1);
MODULE_VERSION(uark, 1);
-
-static const STRUCT_USB_HOST_ID uark_devs[] = {
- {USB_VPI(USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116, 0)},
-};
+USB_PNP_HOST_INFO(uark_devs);
static int
uark_probe(device_t dev)
diff --git a/sys/dev/usb/serial/ubsa.c b/sys/dev/usb/serial/ubsa.c
index 6a30af2..5fac56a 100644
--- a/sys/dev/usb/serial/ubsa.c
+++ b/sys/dev/usb/serial/ubsa.c
@@ -273,6 +273,7 @@ DRIVER_MODULE(ubsa, uhub, ubsa_driver, ubsa_devclass, NULL, 0);
MODULE_DEPEND(ubsa, ucom, 1, 1, 1);
MODULE_DEPEND(ubsa, usb, 1, 1, 1);
MODULE_VERSION(ubsa, 1);
+USB_PNP_HOST_INFO(ubsa_devs);
static int
ubsa_probe(device_t dev)
diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c
index 41ebe5c..70f1979 100644
--- a/sys/dev/usb/serial/uchcom.c
+++ b/sys/dev/usb/serial/uchcom.c
@@ -874,3 +874,4 @@ DRIVER_MODULE(uchcom, uhub, uchcom_driver, uchcom_devclass, NULL, 0);
MODULE_DEPEND(uchcom, ucom, 1, 1, 1);
MODULE_DEPEND(uchcom, usb, 1, 1, 1);
MODULE_VERSION(uchcom, 1);
+USB_PNP_HOST_INFO(uchcom_devs);
diff --git a/sys/dev/usb/serial/ucycom.c b/sys/dev/usb/serial/ucycom.c
index 7536a02..66aedec 100644
--- a/sys/dev/usb/serial/ucycom.c
+++ b/sys/dev/usb/serial/ucycom.c
@@ -174,11 +174,6 @@ static driver_t ucycom_driver = {
.size = sizeof(struct ucycom_softc),
};
-DRIVER_MODULE(ucycom, uhub, ucycom_driver, ucycom_devclass, NULL, 0);
-MODULE_DEPEND(ucycom, ucom, 1, 1, 1);
-MODULE_DEPEND(ucycom, usb, 1, 1, 1);
-MODULE_VERSION(ucycom, 1);
-
/*
* Supported devices
*/
@@ -186,6 +181,12 @@ static const STRUCT_USB_HOST_ID ucycom_devs[] = {
{USB_VPI(USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE, MODEL_CY7C64013)},
};
+DRIVER_MODULE(ucycom, uhub, ucycom_driver, ucycom_devclass, NULL, 0);
+MODULE_DEPEND(ucycom, ucom, 1, 1, 1);
+MODULE_DEPEND(ucycom, usb, 1, 1, 1);
+MODULE_VERSION(ucycom, 1);
+USB_PNP_HOST_INFO(ucycom_devs);
+
#define UCYCOM_DEFAULT_RATE 4800
#define UCYCOM_DEFAULT_CFG 0x03 /* N-8-1 */
diff --git a/sys/dev/usb/serial/ufoma.c b/sys/dev/usb/serial/ufoma.c
index f3d66df..fb526cd 100644
--- a/sys/dev/usb/serial/ufoma.c
+++ b/sys/dev/usb/serial/ufoma.c
@@ -317,16 +317,17 @@ static driver_t ufoma_driver = {
.size = sizeof(struct ufoma_softc),
};
-DRIVER_MODULE(ufoma, uhub, ufoma_driver, ufoma_devclass, NULL, 0);
-MODULE_DEPEND(ufoma, ucom, 1, 1, 1);
-MODULE_DEPEND(ufoma, usb, 1, 1, 1);
-MODULE_VERSION(ufoma, 1);
-
static const STRUCT_USB_HOST_ID ufoma_devs[] = {
{USB_IFACE_CLASS(UICLASS_CDC),
USB_IFACE_SUBCLASS(UISUBCLASS_MCPC),},
};
+DRIVER_MODULE(ufoma, uhub, ufoma_driver, ufoma_devclass, NULL, 0);
+MODULE_DEPEND(ufoma, ucom, 1, 1, 1);
+MODULE_DEPEND(ufoma, usb, 1, 1, 1);
+MODULE_VERSION(ufoma, 1);
+USB_PNP_HOST_INFO(ufoma_devs);
+
static int
ufoma_probe(device_t dev)
{
diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c
index b33df36..936d7f0 100644
--- a/sys/dev/usb/serial/uftdi.c
+++ b/sys/dev/usb/serial/uftdi.c
@@ -265,11 +265,6 @@ static driver_t uftdi_driver = {
.size = sizeof(struct uftdi_softc),
};
-DRIVER_MODULE(uftdi, uhub, uftdi_driver, uftdi_devclass, NULL, NULL);
-MODULE_DEPEND(uftdi, ucom, 1, 1, 1);
-MODULE_DEPEND(uftdi, usb, 1, 1, 1);
-MODULE_VERSION(uftdi, 1);
-
static const STRUCT_USB_HOST_ID uftdi_devs[] = {
#define UFTDI_DEV(v, p, i) \
{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
@@ -914,6 +909,12 @@ static const STRUCT_USB_HOST_ID uftdi_devs[] = {
#undef UFTDI_DEV
};
+DRIVER_MODULE(uftdi, uhub, uftdi_driver, uftdi_devclass, NULL, NULL);
+MODULE_DEPEND(uftdi, ucom, 1, 1, 1);
+MODULE_DEPEND(uftdi, usb, 1, 1, 1);
+MODULE_VERSION(uftdi, 1);
+USB_PNP_HOST_INFO(uftdi_devs);
+
/*
* Jtag product name strings table. Some products have one or more interfaces
* dedicated to jtag or gpio, but use a product ID that's the same as other
diff --git a/sys/dev/usb/serial/ugensa.c b/sys/dev/usb/serial/ugensa.c
index 5d6785d..d78c326 100644
--- a/sys/dev/usb/serial/ugensa.c
+++ b/sys/dev/usb/serial/ugensa.c
@@ -152,11 +152,6 @@ static driver_t ugensa_driver = {
.size = sizeof(struct ugensa_softc),
};
-DRIVER_MODULE(ugensa, uhub, ugensa_driver, ugensa_devclass, NULL, 0);
-MODULE_DEPEND(ugensa, ucom, 1, 1, 1);
-MODULE_DEPEND(ugensa, usb, 1, 1, 1);
-MODULE_VERSION(ugensa, 1);
-
static const STRUCT_USB_HOST_ID ugensa_devs[] = {
{USB_VPI(USB_VENDOR_AIRPRIME, USB_PRODUCT_AIRPRIME_PC5220, 0)},
{USB_VPI(USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CDMA_MODEM1, 0)},
@@ -165,6 +160,12 @@ static const STRUCT_USB_HOST_ID ugensa_devs[] = {
{USB_VPI(USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_FLEXPACKGPS, 0)},
};
+DRIVER_MODULE(ugensa, uhub, ugensa_driver, ugensa_devclass, NULL, 0);
+MODULE_DEPEND(ugensa, ucom, 1, 1, 1);
+MODULE_DEPEND(ugensa, usb, 1, 1, 1);
+MODULE_VERSION(ugensa, 1);
+USB_PNP_HOST_INFO(ugensa_devs);
+
static int
ugensa_probe(device_t dev)
{
diff --git a/sys/dev/usb/serial/uipaq.c b/sys/dev/usb/serial/uipaq.c
index f9e54f8..d483ce5 100644
--- a/sys/dev/usb/serial/uipaq.c
+++ b/sys/dev/usb/serial/uipaq.c
@@ -1088,6 +1088,7 @@ DRIVER_MODULE(uipaq, uhub, uipaq_driver, uipaq_devclass, NULL, 0);
MODULE_DEPEND(uipaq, ucom, 1, 1, 1);
MODULE_DEPEND(uipaq, usb, 1, 1, 1);
MODULE_VERSION(uipaq, 1);
+USB_PNP_HOST_INFO(uipaq_devs);
static int
uipaq_probe(device_t dev)
diff --git a/sys/dev/usb/serial/ulpt.c b/sys/dev/usb/serial/ulpt.c
index 214310d..52dd494 100644
--- a/sys/dev/usb/serial/ulpt.c
+++ b/sys/dev/usb/serial/ulpt.c
@@ -759,3 +759,4 @@ static driver_t ulpt_driver = {
DRIVER_MODULE(ulpt, uhub, ulpt_driver, ulpt_devclass, NULL, 0);
MODULE_DEPEND(ulpt, usb, 1, 1, 1);
MODULE_VERSION(ulpt, 1);
+USB_PNP_HOST_INFO(ulpt_devs);
diff --git a/sys/dev/usb/serial/umcs.c b/sys/dev/usb/serial/umcs.c
index 01873c6..b48d5e5 100644
--- a/sys/dev/usb/serial/umcs.c
+++ b/sys/dev/usb/serial/umcs.c
@@ -278,6 +278,7 @@ DRIVER_MODULE(umcs7840, uhub, umcs7840_driver, umcs7840_devclass, 0, 0);
MODULE_DEPEND(umcs7840, ucom, 1, 1, 1);
MODULE_DEPEND(umcs7840, usb, 1, 1, 1);
MODULE_VERSION(umcs7840, UMCS7840_MODVER);
+USB_PNP_HOST_INFO(umcs7840_devs);
static int
umcs7840_probe(device_t dev)
diff --git a/sys/dev/usb/serial/umct.c b/sys/dev/usb/serial/umct.c
index d8fad98..32c7897 100644
--- a/sys/dev/usb/serial/umct.c
+++ b/sys/dev/usb/serial/umct.c
@@ -221,6 +221,7 @@ DRIVER_MODULE(umct, uhub, umct_driver, umct_devclass, NULL, 0);
MODULE_DEPEND(umct, ucom, 1, 1, 1);
MODULE_DEPEND(umct, usb, 1, 1, 1);
MODULE_VERSION(umct, 1);
+USB_PNP_HOST_INFO(umct_devs);
static int
umct_probe(device_t dev)
diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c
index c1e8812..5e65c12 100644
--- a/sys/dev/usb/serial/umodem.c
+++ b/sys/dev/usb/serial/umodem.c
@@ -298,6 +298,8 @@ DRIVER_MODULE(umodem, uhub, umodem_driver, umodem_devclass, NULL, 0);
MODULE_DEPEND(umodem, ucom, 1, 1, 1);
MODULE_DEPEND(umodem, usb, 1, 1, 1);
MODULE_VERSION(umodem, UMODEM_MODVER);
+USB_PNP_DUAL_INFO(umodem_dual_devs);
+USB_PNP_HOST_INFO(umodem_host_devs);
static int
umodem_probe(device_t dev)
diff --git a/sys/dev/usb/serial/umoscom.c b/sys/dev/usb/serial/umoscom.c
index f8f460b..8c580da 100644
--- a/sys/dev/usb/serial/umoscom.c
+++ b/sys/dev/usb/serial/umoscom.c
@@ -278,14 +278,15 @@ static driver_t umoscom_driver = {
.size = sizeof(struct umoscom_softc),
};
+static const STRUCT_USB_HOST_ID umoscom_devs[] = {
+ {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7703, 0)}
+};
+
DRIVER_MODULE(umoscom, uhub, umoscom_driver, umoscom_devclass, NULL, 0);
MODULE_DEPEND(umoscom, ucom, 1, 1, 1);
MODULE_DEPEND(umoscom, usb, 1, 1, 1);
MODULE_VERSION(umoscom, 1);
-
-static const STRUCT_USB_HOST_ID umoscom_devs[] = {
- {USB_VPI(USB_VENDOR_MOSCHIP, USB_PRODUCT_MOSCHIP_MCS7703, 0)}
-};
+USB_PNP_HOST_INFO(umoscom_devs);
static int
umoscom_probe(device_t dev)
diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c
index 8f37791..af0166e 100644
--- a/sys/dev/usb/serial/uplcom.c
+++ b/sys/dev/usb/serial/uplcom.c
@@ -326,6 +326,7 @@ DRIVER_MODULE(uplcom, uhub, uplcom_driver, uplcom_devclass, NULL, 0);
MODULE_DEPEND(uplcom, ucom, 1, 1, 1);
MODULE_DEPEND(uplcom, usb, 1, 1, 1);
MODULE_VERSION(uplcom, UPLCOM_MODVER);
+USB_PNP_HOST_INFO(uplcom_devs);
static int
uplcom_probe(device_t dev)
diff --git a/sys/dev/usb/serial/uslcom.c b/sys/dev/usb/serial/uslcom.c
index 9bb03f6..b516bde 100644
--- a/sys/dev/usb/serial/uslcom.c
+++ b/sys/dev/usb/serial/uslcom.c
@@ -382,6 +382,7 @@ DRIVER_MODULE(uslcom, uhub, uslcom_driver, uslcom_devclass, NULL, 0);
MODULE_DEPEND(uslcom, ucom, 1, 1, 1);
MODULE_DEPEND(uslcom, usb, 1, 1, 1);
MODULE_VERSION(uslcom, 1);
+USB_PNP_HOST_INFO(uslcom_devs);
static void
uslcom_watchdog(void *arg)
diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c
index b564c99..bd6bc6b 100644
--- a/sys/dev/usb/serial/uvisor.c
+++ b/sys/dev/usb/serial/uvisor.c
@@ -251,11 +251,6 @@ static driver_t uvisor_driver = {
.size = sizeof(struct uvisor_softc),
};
-DRIVER_MODULE(uvisor, uhub, uvisor_driver, uvisor_devclass, NULL, 0);
-MODULE_DEPEND(uvisor, ucom, 1, 1, 1);
-MODULE_DEPEND(uvisor, usb, 1, 1, 1);
-MODULE_VERSION(uvisor, 1);
-
static const STRUCT_USB_HOST_ID uvisor_devs[] = {
#define UVISOR_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
UVISOR_DEV(ACEECA, MEZ1000, UVISOR_FLAG_PALM4),
@@ -288,6 +283,12 @@ static const STRUCT_USB_HOST_ID uvisor_devs[] = {
#undef UVISOR_DEV
};
+DRIVER_MODULE(uvisor, uhub, uvisor_driver, uvisor_devclass, NULL, 0);
+MODULE_DEPEND(uvisor, ucom, 1, 1, 1);
+MODULE_DEPEND(uvisor, usb, 1, 1, 1);
+MODULE_VERSION(uvisor, 1);
+USB_PNP_HOST_INFO(uvisor_devs);
+
static int
uvisor_probe(device_t dev)
{
diff --git a/sys/dev/usb/serial/uvscom.c b/sys/dev/usb/serial/uvscom.c
index 1ee2745..0a6e714 100644
--- a/sys/dev/usb/serial/uvscom.c
+++ b/sys/dev/usb/serial/uvscom.c
@@ -268,6 +268,7 @@ DRIVER_MODULE(uvscom, uhub, uvscom_driver, uvscom_devclass, NULL, 0);
MODULE_DEPEND(uvscom, ucom, 1, 1, 1);
MODULE_DEPEND(uvscom, usb, 1, 1, 1);
MODULE_VERSION(uvscom, UVSCOM_MODVER);
+USB_PNP_HOST_INFO(uvscom_devs);
static int
uvscom_probe(device_t dev)
diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
index 0b769c4..80b6da3 100644
--- a/sys/dev/usb/storage/umass.c
+++ b/sys/dev/usb/storage/umass.c
@@ -706,20 +706,21 @@ static driver_t umass_driver = {
.size = sizeof(struct umass_softc),
};
+static const STRUCT_USB_HOST_ID __used umass_devs[] = {
+ /* generic mass storage class */
+ {USB_IFACE_CLASS(UICLASS_MASS),},
+};
+
DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, NULL, 0);
MODULE_DEPEND(umass, usb, 1, 1, 1);
MODULE_DEPEND(umass, cam, 1, 1, 1);
MODULE_VERSION(umass, 1);
+USB_PNP_HOST_INFO(umass_devs);
/*
* USB device probe/attach/detach
*/
-static const STRUCT_USB_HOST_ID __used umass_devs[] = {
- /* generic mass storage class */
- {USB_IFACE_CLASS(UICLASS_MASS),},
-};
-
static uint16_t
umass_get_proto(struct usb_interface *iface)
{
diff --git a/sys/dev/usb/storage/urio.c b/sys/dev/usb/storage/urio.c
index 7f11981..7de3132 100644
--- a/sys/dev/usb/storage/urio.c
+++ b/sys/dev/usb/storage/urio.c
@@ -195,16 +195,17 @@ static driver_t urio_driver = {
.size = sizeof(struct urio_softc),
};
-DRIVER_MODULE(urio, uhub, urio_driver, urio_devclass, NULL, 0);
-MODULE_DEPEND(urio, usb, 1, 1, 1);
-MODULE_VERSION(urio, 1);
-
static const STRUCT_USB_HOST_ID urio_devs[] = {
{USB_VPI(USB_VENDOR_DIAMOND, USB_PRODUCT_DIAMOND_RIO500USB, 0)},
{USB_VPI(USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_RIO600USB, 0)},
{USB_VPI(USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_RIO800USB, 0)},
};
+DRIVER_MODULE(urio, uhub, urio_driver, urio_devclass, NULL, 0);
+MODULE_DEPEND(urio, usb, 1, 1, 1);
+MODULE_VERSION(urio, 1);
+USB_PNP_HOST_INFO(urio_devs);
+
static int
urio_probe(device_t dev)
{
diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c
index a54fa2e..280e97a 100644
--- a/sys/dev/usb/usb_hub.c
+++ b/sys/dev/usb/usb_hub.c
@@ -1731,6 +1731,7 @@ uhub_child_pnpinfo_string(device_t parent, device_t child,
if (iface && iface->idesc) {
snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
"devclass=0x%02x devsubclass=0x%02x "
+ "devproto=0x%02x "
"sernum=\"%s\" "
"release=0x%04x "
"mode=%s "
@@ -1740,6 +1741,7 @@ uhub_child_pnpinfo_string(device_t parent, device_t child,
UGETW(res.udev->ddesc.idProduct),
res.udev->ddesc.bDeviceClass,
res.udev->ddesc.bDeviceSubClass,
+ res.udev->ddesc.bDeviceProtocol,
usb_get_serial(res.udev),
UGETW(res.udev->ddesc.bcdDevice),
(res.udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device",
diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h
index ecd5a81..74453ab 100644
--- a/sys/dev/usb/usbdi.h
+++ b/sys/dev/usb/usbdi.h
@@ -266,8 +266,38 @@ struct usb_config {
*/
struct usb_device_id {
- /* Hook for driver specific information */
- unsigned long driver_info;
+ /* Select which fields to match against */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+ uint16_t
+ match_flag_vendor:1,
+ match_flag_product:1,
+ match_flag_dev_lo:1,
+ match_flag_dev_hi:1,
+
+ match_flag_dev_class:1,
+ match_flag_dev_subclass:1,
+ match_flag_dev_protocol:1,
+ match_flag_int_class:1,
+
+ match_flag_int_subclass:1,
+ match_flag_int_protocol:1,
+ match_flag_unused:6;
+#else
+ uint16_t
+ match_flag_unused:6,
+ match_flag_int_protocol:1,
+ match_flag_int_subclass:1,
+
+ match_flag_int_class:1,
+ match_flag_dev_protocol:1,
+ match_flag_dev_subclass:1,
+ match_flag_dev_class:1,
+
+ match_flag_dev_hi:1,
+ match_flag_dev_lo:1,
+ match_flag_product:1,
+ match_flag_vendor:1;
+#endif
/* Used for product specific matches; the BCD range is inclusive */
uint16_t idVendor;
@@ -285,21 +315,13 @@ struct usb_device_id {
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
- /* Select which fields to match against */
- uint8_t match_flag_vendor:1;
- uint8_t match_flag_product:1;
- uint8_t match_flag_dev_lo:1;
- uint8_t match_flag_dev_hi:1;
-
- uint8_t match_flag_dev_class:1;
- uint8_t match_flag_dev_subclass:1;
- uint8_t match_flag_dev_protocol:1;
- uint8_t match_flag_int_class:1;
-
- uint8_t match_flag_int_subclass:1;
- uint8_t match_flag_int_protocol:1;
- uint8_t match_flag_unused:6;
+ /* Hook for driver specific information */
+ unsigned long driver_info;
+/*
+ * XXX can't currently participate in auto driver loading
+ * XXX making it a union with the match_flag_* above messes up init
+ */
#if USB_HAVE_COMPAT_LINUX
/* which fields to match against */
uint16_t match_flags;
@@ -316,6 +338,21 @@ struct usb_device_id {
#endif
} __aligned(32);
+#define USB_STD_PNP_INFO "M16:mask;U16:vendor;U16:product;L16:product;G16:product;" \
+ "U8:devclass;U8:devsubclass;U8:devprotocol;" \
+ "U8:intclass;U8:intsubclass;U8:intprotocol;"
+#define USB_STD_PNP_HOST_INFO USB_STD_PNP_INFO "T:mode=host;"
+#define USB_STD_PNP_DEVICE_INFO USB_STD_PNP_INFO "T:mode=device;"
+#define USB_PNP_HOST_INFO(table) \
+ MODULE_PNP_INFO(USB_STD_PNP_HOST_INFO, usb, table, table, sizeof(table[0]), \
+ sizeof(table) / sizeof(table[0]))
+#define USB_PNP_DEVICE_INFO(table) \
+ MODULE_PNP_INFO(USB_STD_PNP_DEVICE_INFO, usb, table, table, sizeof(table[0]), \
+ sizeof(table) / sizeof(table[0]))
+#define USB_PNP_DUAL_INFO(table) \
+ MODULE_PNP_INFO(USB_STD_PNP_INFO, usb, table, table, sizeof(table[0]), \
+ sizeof(table) / sizeof(table[0]))
+
/* check that the size of the structure above is correct */
extern char usb_device_id_assert[(sizeof(struct usb_device_id) == 32) ? 1 : -1];
diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c
index 6558c93..ea89bff 100644
--- a/sys/dev/usb/wlan/if_rsu.c
+++ b/sys/dev/usb/wlan/if_rsu.c
@@ -249,6 +249,7 @@ MODULE_DEPEND(rsu, wlan, 1, 1, 1);
MODULE_DEPEND(rsu, usb, 1, 1, 1);
MODULE_DEPEND(rsu, firmware, 1, 1, 1);
MODULE_VERSION(rsu, 1);
+USB_PNP_HOST_INFO(rsu_devs);
static uint8_t rsu_wme_ac_xfer_map[4] = {
[WME_AC_BE] = RSU_BULK_TX_BE_BK,
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index 9d2203d..02b82ef 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -4,6 +4,7 @@
* Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
* Copyright (c) 2007-2008 Hans Petter Selasky <hselasky@FreeBSD.org>
+ * Copyright (c) 2015 Andriy Voskoboinyk <avos@FreeBSD.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -2068,7 +2069,7 @@ rum_update_slot_cb(struct rum_softc *sc, union sec_param *data, uint8_t rvp_id)
struct ieee80211com *ic = &sc->sc_ic;
uint8_t slottime;
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
+ slottime = IEEE80211_GET_SLOTTIME(ic);
rum_modbits(sc, RT2573_MAC_CSR9, slottime, 0xff);
@@ -3016,3 +3017,4 @@ DRIVER_MODULE(rum, uhub, rum_driver, rum_devclass, NULL, 0);
MODULE_DEPEND(rum, wlan, 1, 1, 1);
MODULE_DEPEND(rum, usb, 1, 1, 1);
MODULE_VERSION(rum, 1);
+USB_PNP_HOST_INFO(rum_devs);
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index bb52a09..1ad9f60 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -5186,7 +5186,7 @@ run_updateslot_cb(void *arg)
run_read(sc, RT2860_BKOFF_SLOT_CFG, &tmp);
tmp &= ~0xff;
- tmp |= (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
+ tmp |= IEEE80211_GET_SLOTTIME(ic);
run_write(sc, RT2860_BKOFF_SLOT_CFG, tmp);
}
@@ -6236,3 +6236,4 @@ MODULE_DEPEND(run, wlan, 1, 1, 1);
MODULE_DEPEND(run, usb, 1, 1, 1);
MODULE_DEPEND(run, firmware, 1, 1, 1);
MODULE_VERSION(run, 1);
+USB_PNP_HOST_INFO(run_devs);
diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
index ec5b54c..747d49d 100644
--- a/sys/dev/usb/wlan/if_uath.c
+++ b/sys/dev/usb/wlan/if_uath.c
@@ -2794,3 +2794,4 @@ DRIVER_MODULE(uath, uhub, uath_driver, uath_devclass, NULL, 0);
MODULE_DEPEND(uath, wlan, 1, 1, 1);
MODULE_DEPEND(uath, usb, 1, 1, 1);
MODULE_VERSION(uath, 1);
+USB_PNP_HOST_INFO(uath_devs);
diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c
index 2689ae0..8030c6f 100644
--- a/sys/dev/usb/wlan/if_upgt.c
+++ b/sys/dev/usb/wlan/if_upgt.c
@@ -2347,3 +2347,4 @@ MODULE_VERSION(if_upgt, 1);
MODULE_DEPEND(if_upgt, usb, 1, 1, 1);
MODULE_DEPEND(if_upgt, wlan, 1, 1, 1);
MODULE_DEPEND(if_upgt, upgtfw_fw, 1, 1, 1);
+USB_PNP_HOST_INFO(upgt_devs);
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index 3fb03bd..4d84e5a 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -401,6 +401,7 @@ DRIVER_MODULE(ural, uhub, ural_driver, ural_devclass, NULL, 0);
MODULE_DEPEND(ural, usb, 1, 1, 1);
MODULE_DEPEND(ural, wlan, 1, 1, 1);
MODULE_VERSION(ural, 1);
+USB_PNP_HOST_INFO(ural_devs);
static int
ural_match(device_t self)
@@ -1770,7 +1771,7 @@ ural_update_slot(struct ural_softc *sc)
struct ieee80211com *ic = &sc->sc_ic;
uint16_t slottime, sifs, eifs;
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
+ slottime = IEEE80211_GET_SLOTTIME(ic);
/*
* These settings may sound a bit inconsistent but this is what the
diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c
index a9aac3a..105fd9d 100644
--- a/sys/dev/usb/wlan/if_urtw.c
+++ b/sys/dev/usb/wlan/if_urtw.c
@@ -4291,18 +4291,18 @@ urtw_updateslottask(void *arg, int pending)
if (sc->sc_flags & URTW_RTL8187B) {
urtw_write8_m(sc, URTW_SIFS, 0x22);
if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
- urtw_write8_m(sc, URTW_SLOT, 0x9);
+ urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SHSLOT);
else
- urtw_write8_m(sc, URTW_SLOT, 0x14);
+ urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SLOT);
urtw_write8_m(sc, URTW_8187B_EIFS, 0x5b);
urtw_write8_m(sc, URTW_CARRIER_SCOUNT, 0x5b);
} else {
urtw_write8_m(sc, URTW_SIFS, 0x22);
if (sc->sc_state == IEEE80211_S_ASSOC &&
ic->ic_flags & IEEE80211_F_SHSLOT)
- urtw_write8_m(sc, URTW_SLOT, 0x9);
+ urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SHSLOT);
else
- urtw_write8_m(sc, URTW_SLOT, 0x14);
+ urtw_write8_m(sc, URTW_SLOT, IEEE80211_DUR_SLOT);
if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
urtw_write8_m(sc, URTW_DIFS, 0x14);
urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
@@ -4382,3 +4382,4 @@ DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, NULL, 0);
MODULE_DEPEND(urtw, wlan, 1, 1, 1);
MODULE_DEPEND(urtw, usb, 1, 1, 1);
MODULE_VERSION(urtw, 1);
+USB_PNP_HOST_INFO(urtw_devs);
diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c
index 78ead15..4a967ee 100644
--- a/sys/dev/usb/wlan/if_urtwn.c
+++ b/sys/dev/usb/wlan/if_urtwn.c
@@ -3,6 +3,7 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015 Andriy Voskoboinyk <avos@FreeBSD.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -183,8 +184,12 @@ static struct ieee80211vap *urtwn_vap_create(struct ieee80211com *,
static void urtwn_vap_delete(struct ieee80211vap *);
static struct mbuf * urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int,
int *);
-static struct mbuf * urtwn_rxeof(struct usb_xfer *, struct urtwn_data *,
+static struct mbuf * urtwn_report_intr(struct usb_xfer *, struct urtwn_data *,
int *, int8_t *);
+static struct mbuf * urtwn_rxeof(struct urtwn_softc *, uint8_t *, int,
+ int *, int8_t *);
+static void urtwn_r88e_ratectl_tx_complete(struct urtwn_softc *,
+ void *);
static void urtwn_txeof(struct urtwn_softc *, struct urtwn_data *,
int);
static int urtwn_alloc_list(struct urtwn_softc *,
@@ -209,6 +214,9 @@ static uint16_t urtwn_read_2(struct urtwn_softc *, uint16_t);
static uint32_t urtwn_read_4(struct urtwn_softc *, uint16_t);
static int urtwn_fw_cmd(struct urtwn_softc *, uint8_t,
const void *, int);
+static void urtwn_cmdq_cb(void *, int);
+static int urtwn_cmd_sleepable(struct urtwn_softc *, const void *,
+ size_t, CMD_FUNC_PROTO);
static void urtwn_r92c_rf_write(struct urtwn_softc *, int,
uint8_t, uint32_t);
static void urtwn_r88e_rf_write(struct urtwn_softc *, int,
@@ -237,6 +245,17 @@ static int urtwn_setup_beacon(struct urtwn_softc *,
static void urtwn_update_beacon(struct ieee80211vap *, int);
static int urtwn_tx_beacon(struct urtwn_softc *sc,
struct urtwn_vap *);
+static int urtwn_key_alloc(struct ieee80211vap *,
+ struct ieee80211_key *, ieee80211_keyix *,
+ ieee80211_keyix *);
+static void urtwn_key_set_cb(struct urtwn_softc *,
+ union sec_param *);
+static void urtwn_key_del_cb(struct urtwn_softc *,
+ union sec_param *);
+static int urtwn_key_set(struct ieee80211vap *,
+ const struct ieee80211_key *);
+static int urtwn_key_delete(struct ieee80211vap *,
+ const struct ieee80211_key *);
static void urtwn_tsf_task_adhoc(void *, int);
static void urtwn_tsf_sync_enable(struct urtwn_softc *,
struct ieee80211vap *);
@@ -272,6 +291,8 @@ static int urtwn_mac_init(struct urtwn_softc *);
static void urtwn_bb_init(struct urtwn_softc *);
static void urtwn_rf_init(struct urtwn_softc *);
static void urtwn_cam_init(struct urtwn_softc *);
+static int urtwn_cam_write(struct urtwn_softc *, uint32_t,
+ uint32_t);
static void urtwn_pa_bias_init(struct urtwn_softc *);
static void urtwn_rxfilter_init(struct urtwn_softc *);
static void urtwn_edca_init(struct urtwn_softc *);
@@ -295,6 +316,10 @@ static int urtwn_wme_update(struct ieee80211com *);
static void urtwn_set_promisc(struct urtwn_softc *);
static void urtwn_update_promisc(struct ieee80211com *);
static void urtwn_update_mcast(struct ieee80211com *);
+static struct ieee80211_node *urtwn_r88e_node_alloc(struct ieee80211vap *,
+ const uint8_t mac[IEEE80211_ADDR_LEN]);
+static void urtwn_r88e_newassoc(struct ieee80211_node *, int);
+static void urtwn_r88e_node_free(struct ieee80211_node *);
static void urtwn_set_chan(struct urtwn_softc *,
struct ieee80211_channel *,
struct ieee80211_channel *);
@@ -419,6 +444,8 @@ urtwn_attach(device_t self)
mtx_init(&sc->sc_mtx, device_get_nameunit(self),
MTX_NETWORK_LOCK, MTX_DEF);
+ URTWN_CMDQ_LOCK_INIT(sc);
+ URTWN_NT_LOCK_INIT(sc);
callout_init(&sc->sc_watchdog_ch, 0);
mbufq_init(&sc->sc_snd, ifqmaxlen);
@@ -487,6 +514,11 @@ urtwn_attach(device_t self)
| IEEE80211_C_WME /* 802.11e */
;
+ ic->ic_cryptocaps =
+ IEEE80211_CRYPTO_WEP |
+ IEEE80211_CRYPTO_TKIP |
+ IEEE80211_CRYPTO_AES_CCM;
+
bands = 0;
setbit(&bands, IEEE80211_MODE_11B);
setbit(&bands, IEEE80211_MODE_11G);
@@ -504,12 +536,20 @@ urtwn_attach(device_t self)
ic->ic_wme.wme_update = urtwn_wme_update;
ic->ic_update_promisc = urtwn_update_promisc;
ic->ic_update_mcast = urtwn_update_mcast;
+ if (sc->chip & URTWN_CHIP_88E) {
+ ic->ic_node_alloc = urtwn_r88e_node_alloc;
+ ic->ic_newassoc = urtwn_r88e_newassoc;
+ sc->sc_node_free = ic->ic_node_free;
+ ic->ic_node_free = urtwn_r88e_node_free;
+ }
ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr,
sizeof(sc->sc_txtap), URTWN_TX_RADIOTAP_PRESENT,
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
URTWN_RX_RADIOTAP_PRESENT);
+ TASK_INIT(&sc->cmdq_task, 0, urtwn_cmdq_cb, sc);
+
if (bootverbose)
ieee80211_announce(ic);
@@ -559,7 +599,13 @@ urtwn_detach(device_t self)
urtwn_free_rx_list(sc);
URTWN_UNLOCK(sc);
- ieee80211_ifdetach(ic);
+ if (ic->ic_softc == sc) {
+ ieee80211_draintask(ic, &sc->cmdq_task);
+ ieee80211_ifdetach(ic);
+ }
+
+ URTWN_NT_LOCK_DESTROY(sc);
+ URTWN_CMDQ_LOCK_DESTROY(sc);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -632,12 +678,17 @@ urtwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
uvp->newstate = vap->iv_newstate;
vap->iv_newstate = urtwn_newstate;
vap->iv_update_beacon = urtwn_update_beacon;
+ vap->iv_key_alloc = urtwn_key_alloc;
+ vap->iv_key_set = urtwn_key_set;
+ vap->iv_key_delete = urtwn_key_delete;
if (opmode == IEEE80211_M_IBSS) {
uvp->recv_mgmt = vap->iv_recv_mgmt;
vap->iv_recv_mgmt = urtwn_ibss_recv_mgmt;
TASK_INIT(&uvp->tsf_task_adhoc, 0, urtwn_tsf_task_adhoc, vap);
}
+ if (URTWN_CHIP_HAS_RATECTL(sc))
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
ieee80211_media_status, mac);
@@ -649,12 +700,15 @@ static void
urtwn_vap_delete(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
+ struct urtwn_softc *sc = ic->ic_softc;
struct urtwn_vap *uvp = URTWN_VAP(vap);
if (uvp->bcn_mbuf != NULL)
m_freem(uvp->bcn_mbuf);
if (vap->iv_opmode == IEEE80211_M_IBSS)
ieee80211_draintask(ic, &uvp->tsf_task_adhoc);
+ if (URTWN_CHIP_HAS_RATECTL(sc))
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(uvp, M_80211_VAP);
}
@@ -667,7 +721,7 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
struct mbuf *m;
struct r92c_rx_stat *stat;
uint32_t rxdw0, rxdw3;
- uint8_t rate;
+ uint8_t rate, cipher;
int8_t rssi = 0;
int infosz;
@@ -697,6 +751,7 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
}
rate = MS(rxdw3, R92C_RXDW3_RATE);
+ cipher = MS(rxdw0, R92C_RXDW0_CIPHER);
infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
/* Get RSSI from PHY status descriptor if present. */
@@ -716,9 +771,14 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
}
/* Finalize mbuf. */
- wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz);
- memcpy(mtod(m, uint8_t *), wh, pktlen);
- m->m_pkthdr.len = m->m_len = pktlen;
+ memcpy(mtod(m, uint8_t *), (uint8_t *)&stat[1] + infosz, pktlen);
+ m->m_pkthdr.len = m->m_len = pktlen;
+ wh = mtod(m, struct ieee80211_frame *);
+
+ if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
+ cipher != R92C_CAM_ALGO_NONE) {
+ m->m_flags |= M_WEP;
+ }
if (ieee80211_radiotap_active(ic)) {
struct urtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
@@ -733,8 +793,6 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
}
tap->wr_dbm_antsignal = rssi;
tap->wr_dbm_antnoise = URTWN_NOISE_FLOOR;
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
}
*rssi_p = rssi;
@@ -743,16 +801,14 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
}
static struct mbuf *
-urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
+urtwn_report_intr(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
int8_t *nf)
{
struct urtwn_softc *sc = data->sc;
struct ieee80211com *ic = &sc->sc_ic;
struct r92c_rx_stat *stat;
- struct mbuf *m, *m0 = NULL, *prevm = NULL;
- uint32_t rxdw0;
uint8_t *buf;
- int len, totlen, pktlen, infosz, npkts;
+ int len;
usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
@@ -762,6 +818,36 @@ urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
}
buf = data->buf;
+ stat = (struct r92c_rx_stat *)buf;
+
+ if (sc->chip & URTWN_CHIP_88E) {
+ int report_sel = MS(le32toh(stat->rxdw3), R88E_RXDW3_RPT);
+
+ switch (report_sel) {
+ case R88E_RXDW3_RPT_RX:
+ return (urtwn_rxeof(sc, buf, len, rssi, nf));
+ case R88E_RXDW3_RPT_TX1:
+ urtwn_r88e_ratectl_tx_complete(sc, &stat[1]);
+ break;
+ default:
+ DPRINTFN(7, "case %d was not handled\n", report_sel);
+ break;
+ }
+ } else
+ return (urtwn_rxeof(sc, buf, len, rssi, nf));
+
+ return (NULL);
+}
+
+static struct mbuf *
+urtwn_rxeof(struct urtwn_softc *sc, uint8_t *buf, int len, int *rssi,
+ int8_t *nf)
+{
+ struct r92c_rx_stat *stat;
+ struct mbuf *m, *m0 = NULL, *prevm = NULL;
+ uint32_t rxdw0;
+ int totlen, pktlen, infosz, npkts;
+
/* Get the number of encapsulated frames. */
stat = (struct r92c_rx_stat *)buf;
npkts = MS(le32toh(stat->rxdw2), R92C_RXDW2_PKTCNT);
@@ -805,6 +891,35 @@ urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
}
static void
+urtwn_r88e_ratectl_tx_complete(struct urtwn_softc *sc, void *arg)
+{
+ struct r88e_tx_rpt_ccx *rpt = arg;
+ struct ieee80211vap *vap;
+ struct ieee80211_node *ni;
+ uint8_t macid;
+ int ntries;
+
+ macid = MS(rpt->rptb1, R88E_RPTB1_MACID);
+ ntries = MS(rpt->rptb2, R88E_RPTB2_RETRY_CNT);
+
+ URTWN_NT_LOCK(sc);
+ ni = sc->node_list[macid];
+ if (ni != NULL) {
+ vap = ni->ni_vap;
+
+ if (rpt->rptb1 & R88E_RPTB1_PKT_OK) {
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS, &ntries, NULL);
+ } else {
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_FAILURE, &ntries, NULL);
+ }
+ } else
+ DPRINTFN(8, "macid %d, ni is NULL\n", macid);
+ URTWN_NT_UNLOCK(sc);
+}
+
+static void
urtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtwn_softc *sc = usbd_xfer_softc(xfer);
@@ -824,7 +939,7 @@ urtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
if (data == NULL)
goto tr_setup;
STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
- m = urtwn_rxeof(xfer, data, &rssi, &nf);
+ m = urtwn_report_intr(xfer, data, &rssi, &nf);
STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
/* FALLTHROUGH */
case USB_ST_SETUP:
@@ -1183,6 +1298,64 @@ urtwn_fw_cmd(struct urtwn_softc *sc, uint8_t id, const void *buf, int len)
return (0);
}
+static void
+urtwn_cmdq_cb(void *arg, int pending)
+{
+ struct urtwn_softc *sc = arg;
+ struct urtwn_cmdq *item;
+
+ /*
+ * Device must be powered on (via urtwn_power_on())
+ * before any command may be sent.
+ */
+ URTWN_LOCK(sc);
+ if (!(sc->sc_flags & URTWN_RUNNING)) {
+ URTWN_UNLOCK(sc);
+ return;
+ }
+
+ URTWN_CMDQ_LOCK(sc);
+ while (sc->cmdq[sc->cmdq_first].func != NULL) {
+ item = &sc->cmdq[sc->cmdq_first];
+ sc->cmdq_first = (sc->cmdq_first + 1) % URTWN_CMDQ_SIZE;
+ URTWN_CMDQ_UNLOCK(sc);
+
+ item->func(sc, &item->data);
+
+ URTWN_CMDQ_LOCK(sc);
+ memset(item, 0, sizeof (*item));
+ }
+ URTWN_CMDQ_UNLOCK(sc);
+ URTWN_UNLOCK(sc);
+}
+
+static int
+urtwn_cmd_sleepable(struct urtwn_softc *sc, const void *ptr, size_t len,
+ CMD_FUNC_PROTO)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ KASSERT(len <= sizeof(union sec_param), ("buffer overflow"));
+
+ URTWN_CMDQ_LOCK(sc);
+ if (sc->cmdq[sc->cmdq_last].func != NULL) {
+ device_printf(sc->sc_dev, "%s: cmdq overflow\n", __func__);
+ URTWN_CMDQ_UNLOCK(sc);
+
+ return (EAGAIN);
+ }
+
+ if (ptr != NULL)
+ memcpy(&sc->cmdq[sc->cmdq_last].data, ptr, len);
+ sc->cmdq[sc->cmdq_last].func = func;
+ sc->cmdq_last = (sc->cmdq_last + 1) % URTWN_CMDQ_SIZE;
+ URTWN_CMDQ_UNLOCK(sc);
+
+ ieee80211_runtask(ic, &sc->cmdq_task);
+
+ return (0);
+}
+
static __inline void
urtwn_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
{
@@ -1717,6 +1890,153 @@ urtwn_tx_beacon(struct urtwn_softc *sc, struct urtwn_vap *uvp)
return (0);
}
+static int
+urtwn_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
+ ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
+{
+ struct urtwn_softc *sc = vap->iv_ic->ic_softc;
+ uint8_t i;
+
+ if (!(&vap->iv_nw_keys[0] <= k &&
+ k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) {
+ if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT)) {
+ URTWN_LOCK(sc);
+ /*
+ * First 4 slots for group keys,
+ * what is left - for pairwise.
+ * XXX incompatible with IBSS RSN.
+ */
+ for (i = IEEE80211_WEP_NKID;
+ i < R92C_CAM_ENTRY_COUNT; i++) {
+ if ((sc->keys_bmap & (1 << i)) == 0) {
+ sc->keys_bmap |= 1 << i;
+ *keyix = i;
+ break;
+ }
+ }
+ URTWN_UNLOCK(sc);
+ if (i == R92C_CAM_ENTRY_COUNT) {
+ device_printf(sc->sc_dev,
+ "%s: no free space in the key table\n",
+ __func__);
+ return 0;
+ }
+ } else
+ *keyix = 0;
+ } else {
+ *keyix = k - vap->iv_nw_keys;
+ }
+ *rxkeyix = *keyix;
+ return 1;
+}
+
+static void
+urtwn_key_set_cb(struct urtwn_softc *sc, union sec_param *data)
+{
+ struct ieee80211_key *k = &data->key;
+ uint8_t algo, keyid;
+ int i, error;
+
+ if (k->wk_keyix < IEEE80211_WEP_NKID)
+ keyid = k->wk_keyix;
+ else
+ keyid = 0;
+
+ /* Map net80211 cipher to HW crypto algorithm. */
+ switch (k->wk_cipher->ic_cipher) {
+ case IEEE80211_CIPHER_WEP:
+ if (k->wk_keylen < 8)
+ algo = R92C_CAM_ALGO_WEP40;
+ else
+ algo = R92C_CAM_ALGO_WEP104;
+ break;
+ case IEEE80211_CIPHER_TKIP:
+ algo = R92C_CAM_ALGO_TKIP;
+ break;
+ case IEEE80211_CIPHER_AES_CCM:
+ algo = R92C_CAM_ALGO_AES;
+ break;
+ default:
+ device_printf(sc->sc_dev, "%s: undefined cipher %d\n",
+ __func__, k->wk_cipher->ic_cipher);
+ return;
+ }
+
+ DPRINTFN(9, "keyix %d, keyid %d, algo %d/%d, flags %04X, len %d, "
+ "macaddr %s\n", k->wk_keyix, keyid, k->wk_cipher->ic_cipher, algo,
+ k->wk_flags, k->wk_keylen, ether_sprintf(k->wk_macaddr));
+
+ /* Write key. */
+ for (i = 0; i < 4; i++) {
+ error = urtwn_cam_write(sc, R92C_CAM_KEY(k->wk_keyix, i),
+ LE_READ_4(&k->wk_key[i * 4]));
+ if (error != 0)
+ goto fail;
+ }
+
+ /* Write CTL0 last since that will validate the CAM entry. */
+ error = urtwn_cam_write(sc, R92C_CAM_CTL1(k->wk_keyix),
+ LE_READ_4(&k->wk_macaddr[2]));
+ if (error != 0)
+ goto fail;
+ error = urtwn_cam_write(sc, R92C_CAM_CTL0(k->wk_keyix),
+ SM(R92C_CAM_ALGO, algo) |
+ SM(R92C_CAM_KEYID, keyid) |
+ SM(R92C_CAM_MACLO, LE_READ_2(&k->wk_macaddr[0])) |
+ R92C_CAM_VALID);
+ if (error != 0)
+ goto fail;
+
+ return;
+
+fail:
+ device_printf(sc->sc_dev, "%s fails, error %d\n", __func__, error);
+}
+
+static void
+urtwn_key_del_cb(struct urtwn_softc *sc, union sec_param *data)
+{
+ struct ieee80211_key *k = &data->key;
+ int i;
+
+ DPRINTFN(9, "keyix %d, flags %04X, macaddr %s\n",
+ k->wk_keyix, k->wk_flags, ether_sprintf(k->wk_macaddr));
+
+ urtwn_cam_write(sc, R92C_CAM_CTL0(k->wk_keyix), 0);
+ urtwn_cam_write(sc, R92C_CAM_CTL1(k->wk_keyix), 0);
+
+ /* Clear key. */
+ for (i = 0; i < 4; i++)
+ urtwn_cam_write(sc, R92C_CAM_KEY(k->wk_keyix, i), 0);
+ sc->keys_bmap &= ~(1 << k->wk_keyix);
+}
+
+static int
+urtwn_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
+{
+ struct urtwn_softc *sc = vap->iv_ic->ic_softc;
+
+ if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
+ /* Not for us. */
+ return (1);
+ }
+
+ return (!urtwn_cmd_sleepable(sc, k, sizeof(*k), urtwn_key_set_cb));
+}
+
+static int
+urtwn_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
+{
+ struct urtwn_softc *sc = vap->iv_ic->ic_softc;
+
+ if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
+ /* Not for us. */
+ return (1);
+ }
+
+ return (!urtwn_cmd_sleepable(sc, k, sizeof(*k), urtwn_key_del_cb));
+}
+
static void
urtwn_tsf_task_adhoc(void *arg, int pending)
{
@@ -2008,10 +2328,7 @@ urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
urtwn_write_1(sc, R92C_T2T_SIFS + 1, 10);
/* Intialize rate adaptation. */
- if (sc->chip & URTWN_CHIP_88E)
- ni->ni_txrate =
- ni->ni_rates.rs_rates[ni->ni_rates.rs_nrates-1];
- else
+ if (!(sc->chip & URTWN_CHIP_88E))
urtwn_ra_init(sc);
/* Turn link LED on. */
urtwn_set_led(sc, URTWN_LED_LINK, 1);
@@ -2162,16 +2479,38 @@ urtwn_r88e_get_rssi(struct urtwn_softc *sc, int rate, void *physt)
return (rssi);
}
+static __inline uint8_t
+rate2ridx(uint8_t rate)
+{
+ switch (rate) {
+ case 12: return 4;
+ case 18: return 5;
+ case 24: return 6;
+ case 36: return 7;
+ case 48: return 8;
+ case 72: return 9;
+ case 96: return 10;
+ case 108: return 11;
+ case 2: return 0;
+ case 4: return 1;
+ case 11: return 2;
+ case 22: return 3;
+ default: return 0;
+ }
+}
+
static int
urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m, struct urtwn_data *data)
{
- struct ieee80211_frame *wh;
- struct ieee80211_key *k = NULL;
+ const struct ieee80211_txparam *tp;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211_key *k = NULL;
+ struct ieee80211_channel *chan;
+ struct ieee80211_frame *wh;
struct r92c_tx_desc *txd;
- uint8_t macid, raid, ridx, subtype, type, tid, qsel;
+ uint8_t macid, raid, rate, ridx, subtype, type, tid, qsel;
int hasqos, ismcast;
URTWN_ASSERT_LOCKED(sc);
@@ -2192,6 +2531,38 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
} else
tid = 0;
+ chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
+ ni->ni_chan : ic->ic_curchan;
+ tp = &vap->iv_txparms[ieee80211_chan2mode(chan)];
+
+ /* Choose a TX rate index. */
+ if (type == IEEE80211_FC0_TYPE_MGT)
+ rate = tp->mgmtrate;
+ else if (ismcast)
+ rate = tp->mcastrate;
+ else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
+ rate = tp->ucastrate;
+ else if (m->m_flags & M_EAPOL)
+ rate = tp->mgmtrate;
+ else {
+ if (URTWN_CHIP_HAS_RATECTL(sc)) {
+ /* XXX pass pktlen */
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
+ rate = ni->ni_txrate;
+ } else {
+ if (ic->ic_curmode != IEEE80211_MODE_11B)
+ rate = 108;
+ else
+ rate = 22;
+ }
+ }
+
+ ridx = rate2ridx(rate);
+ if (ic->ic_curmode != IEEE80211_MODE_11B)
+ raid = R92C_RAID_11BG;
+ else
+ raid = R92C_RAID_11B;
+
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
k = ieee80211_crypto_encap(ni, m);
if (k == NULL) {
@@ -2214,25 +2585,21 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
if (ismcast)
txd->txdw0 |= htole32(R92C_TXDW0_BMCAST);
- raid = R92C_RAID_11B; /* by default */
- ridx = URTWN_RIDX_CCK1;
if (!ismcast) {
- macid = URTWN_MACID_BSS;
+ if (sc->chip & URTWN_CHIP_88E) {
+ struct urtwn_node *un = URTWN_NODE(ni);
+ macid = un->id;
+ } else
+ macid = URTWN_MACID_BSS;
if (type == IEEE80211_FC0_TYPE_DATA) {
qsel = tid % URTWN_MAX_TID;
- if (!(m->m_flags & M_EAPOL)) {
- if (ic->ic_curmode != IEEE80211_MODE_11B) {
- raid = R92C_RAID_11BG;
- ridx = URTWN_RIDX_OFDM54;
- } else
- ridx = URTWN_RIDX_CCK11;
- }
-
- if (sc->chip & URTWN_CHIP_88E)
- txd->txdw2 |= htole32(R88E_TXDW2_AGGBK);
- else
+ if (sc->chip & URTWN_CHIP_88E) {
+ txd->txdw2 |= htole32(
+ R88E_TXDW2_AGGBK |
+ R88E_TXDW2_CCX_RPT);
+ } else
txd->txdw1 |= htole32(R92C_TXDW1_AGGBK);
if (ic->ic_flags & IEEE80211_F_USEPROT) {
@@ -2272,8 +2639,8 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, ridx));
/* Force this rate if needed. */
- if (ismcast || type != IEEE80211_FC0_TYPE_DATA ||
- (m->m_flags & M_EAPOL))
+ if (URTWN_CHIP_HAS_RATECTL(sc) || ismcast ||
+ (m->m_flags & M_EAPOL) || type != IEEE80211_FC0_TYPE_DATA)
txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
if (!hasqos) {
@@ -2287,12 +2654,30 @@ urtwn_tx_data(struct urtwn_softc *sc, struct ieee80211_node *ni,
txd->txdseq = htole16(M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE);
}
+ if (k != NULL && !(k->wk_flags & IEEE80211_KEY_SWCRYPT)) {
+ uint8_t cipher;
+
+ switch (k->wk_cipher->ic_cipher) {
+ case IEEE80211_CIPHER_WEP:
+ case IEEE80211_CIPHER_TKIP:
+ cipher = R92C_TXDW1_CIPHER_RC4;
+ break;
+ case IEEE80211_CIPHER_AES_CCM:
+ cipher = R92C_TXDW1_CIPHER_AES;
+ break;
+ default:
+ device_printf(sc->sc_dev, "%s: unknown cipher %d\n",
+ __func__, k->wk_cipher->ic_cipher);
+ return (EINVAL);
+ }
+
+ txd->txdw1 |= htole32(SM(R92C_TXDW1_CIPHER, cipher));
+ }
+
if (ieee80211_radiotap_active_vap(vap)) {
struct urtwn_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = 0;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
if (k != NULL)
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
ieee80211_radiotap_tx(vap, m);
@@ -2935,13 +3320,11 @@ urtwn_dma_init(struct urtwn_softc *sc)
else
reg |= R92C_TRXDMA_CTRL_QMAP_LQ;
} else if (nqueues == 2) {
- /* All 2-endpoints configs have a high priority queue. */
- if (!hashq)
- return (EIO);
- if (hasnq)
- reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ;
- else
- reg |= R92C_TRXDMA_CTRL_QMAP_HQ_LQ;
+ /*
+ * All 2-endpoints configs have high and normal
+ * priority queues.
+ */
+ reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ;
} else
reg |= R92C_TRXDMA_CTRL_QMAP_3EP;
usb_err = urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
@@ -3195,6 +3578,23 @@ urtwn_cam_init(struct urtwn_softc *sc)
R92C_CAMCMD_POLLING | R92C_CAMCMD_CLR);
}
+static int
+urtwn_cam_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data)
+{
+ usb_error_t error;
+
+ error = urtwn_write_4(sc, R92C_CAMWRITE, data);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_4(sc, R92C_CAMCMD,
+ R92C_CAMCMD_POLLING | R92C_CAMCMD_WRITE |
+ SM(R92C_CAMCMD_ADDR, addr));
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+
+ return (0);
+}
+
static void
urtwn_pa_bias_init(struct urtwn_softc *sc)
{
@@ -3602,6 +4002,7 @@ static void
urtwn_set_channel(struct ieee80211com *ic)
{
struct urtwn_softc *sc = ic->ic_softc;
+ struct ieee80211_channel *c = ic->ic_curchan;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
URTWN_LOCK(sc);
@@ -3609,7 +4010,11 @@ urtwn_set_channel(struct ieee80211com *ic)
/* Make link LED blink during scan. */
urtwn_set_led(sc, URTWN_LED_LINK, !sc->ledlink);
}
- urtwn_set_chan(sc, ic->ic_curchan, NULL);
+ urtwn_set_chan(sc, c, NULL);
+ sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
+ sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
+ sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
+ sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
URTWN_UNLOCK(sc);
}
@@ -3623,8 +4028,7 @@ urtwn_wme_update(struct ieee80211com *ic)
int ac;
acm = 0;
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ?
- IEEE80211_DUR_SHSLOT : IEEE80211_DUR_SLOT;
+ slottime = IEEE80211_GET_SLOTTIME(ic);
URTWN_LOCK(sc);
for (ac = WME_AC_BE; ac < WME_NUM_AC; ac++) {
@@ -3708,6 +4112,63 @@ urtwn_update_mcast(struct ieee80211com *ic)
/* XXX do nothing? */
}
+static struct ieee80211_node *
+urtwn_r88e_node_alloc(struct ieee80211vap *vap,
+ const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+ struct urtwn_node *un;
+
+ un = malloc(sizeof (struct urtwn_node), M_80211_NODE,
+ M_NOWAIT | M_ZERO);
+
+ if (un == NULL)
+ return NULL;
+
+ un->id = URTWN_MACID_UNDEFINED;
+
+ return &un->ni;
+}
+
+static void
+urtwn_r88e_newassoc(struct ieee80211_node *ni, int isnew)
+{
+ struct urtwn_softc *sc = ni->ni_ic->ic_softc;
+ struct urtwn_node *un = URTWN_NODE(ni);
+ uint8_t id;
+
+ if (!isnew)
+ return;
+
+ URTWN_NT_LOCK(sc);
+ for (id = 0; id <= URTWN_MACID_MAX(sc); id++) {
+ if (id != URTWN_MACID_BC && sc->node_list[id] == NULL) {
+ un->id = id;
+ sc->node_list[id] = ni;
+ break;
+ }
+ }
+ URTWN_NT_UNLOCK(sc);
+
+ if (id > URTWN_MACID_MAX(sc)) {
+ device_printf(sc->sc_dev, "%s: node table is full\n",
+ __func__);
+ }
+}
+
+static void
+urtwn_r88e_node_free(struct ieee80211_node *ni)
+{
+ struct urtwn_softc *sc = ni->ni_ic->ic_softc;
+ struct urtwn_node *un = URTWN_NODE(ni);
+
+ URTWN_NT_LOCK(sc);
+ if (un->id != URTWN_MACID_UNDEFINED)
+ sc->node_list[un->id] = NULL;
+ URTWN_NT_UNLOCK(sc);
+
+ sc->sc_node_free(ni);
+}
+
static void
urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c,
struct ieee80211_channel *extc)
@@ -4022,9 +4483,27 @@ urtwn_init(struct urtwn_softc *sc)
/* Clear per-station keys table. */
urtwn_cam_init(sc);
+ /* Enable decryption / encryption. */
+ urtwn_write_2(sc, R92C_SECCFG,
+ R92C_SECCFG_TXUCKEY_DEF | R92C_SECCFG_RXUCKEY_DEF |
+ R92C_SECCFG_TXENC_ENA | R92C_SECCFG_RXDEC_ENA |
+ R92C_SECCFG_TXBCKEY_DEF | R92C_SECCFG_RXBCKEY_DEF);
+
+ /*
+ * Install static keys (if any).
+ * Must be called after urtwn_cam_init().
+ */
+ ieee80211_runtask(ic, &sc->cmdq_task);
+
/* Enable hardware sequence numbering. */
urtwn_write_1(sc, R92C_HWSEQ_CTRL, 0xff);
+ /* Enable per-packet TX report. */
+ if (sc->chip & URTWN_CHIP_88E) {
+ urtwn_write_1(sc, R88E_TX_RPT_CTRL,
+ urtwn_read_1(sc, R88E_TX_RPT_CTRL) | R88E_TX_RPT1_ENA);
+ }
+
/* Perform LO and IQ calibrations. */
urtwn_iq_calib(sc);
/* Perform LC calibration. */
@@ -4158,3 +4637,4 @@ MODULE_DEPEND(urtwn, usb, 1, 1, 1);
MODULE_DEPEND(urtwn, wlan, 1, 1, 1);
MODULE_DEPEND(urtwn, firmware, 1, 1, 1);
MODULE_VERSION(urtwn, 1);
+USB_PNP_HOST_INFO(urtwn_devs);
diff --git a/sys/dev/usb/wlan/if_urtwnreg.h b/sys/dev/usb/wlan/if_urtwnreg.h
index 993a00b..1a43297 100644
--- a/sys/dev/usb/wlan/if_urtwnreg.h
+++ b/sys/dev/usb/wlan/if_urtwnreg.h
@@ -158,6 +158,9 @@
#define R92C_INIRTS_RATE_SEL 0x480
#define R92C_INIDATA_RATE_SEL(macid) (0x484 + (macid))
#define R92C_MAX_AGGR_NUM 0x4ca
+#define R88E_TX_RPT_CTRL 0x4ec
+#define R88E_TX_RPT_MACID_MAX 0x4ed
+#define R88E_TX_RPT_TIME 0x4f0
/* EDCA Configuration. */
#define R92C_EDCA_VO_PARAM 0x500
#define R92C_EDCA_VI_PARAM 0x504
@@ -479,6 +482,10 @@
#define R92C_RRSR_RSC_UPSUBCHNL 0x00400000
#define R92C_RRSR_SHORT 0x00800000
+/* Bits for R88E_TX_RPT_CTRL. */
+#define R88E_TX_RPT1_ENA 0x01
+#define R88E_TX_RPT2_ENA 0x02
+
/* Bits for R92C_EDCA_XX_PARAM. */
#define R92C_EDCA_PARAM_AIFS_M 0x000000ff
#define R92C_EDCA_PARAM_AIFS_S 0
@@ -550,6 +557,16 @@
#define R92C_CAMCMD_CLR 0x40000000
#define R92C_CAMCMD_POLLING 0x80000000
+/* Bits for R92C_SECCFG. */
+#define R92C_SECCFG_TXUCKEY_DEF 0x0001
+#define R92C_SECCFG_RXUCKEY_DEF 0x0002
+#define R92C_SECCFG_TXENC_ENA 0x0004
+#define R92C_SECCFG_RXDEC_ENA 0x0008
+#define R92C_SECCFG_CMP_A2 0x0010
+#define R92C_SECCFG_TXBCKEY_DEF 0x0040
+#define R92C_SECCFG_RXBCKEY_DEF 0x0080
+#define R88E_SECCFG_CHK_KEYID 0x0100
+
/* Bits for R92C_RXFLTMAP*. */
#define R92C_RXFLTMAP_SUBTYPE(subtype) \
(1 << ((subtype) >> IEEE80211_FC0_SUBTYPE_SHIFT))
@@ -895,6 +912,11 @@ struct r92c_fw_cmd_macid_cfg {
uint8_t macid;
#define URTWN_MACID_BSS 0
#define URTWN_MACID_BC 4 /* Broadcast. */
+#define R92C_MACID_MAX 31
+#define R88E_MACID_MAX 63
+#define URTWN_MACID_MAX(sc) (((sc)->chip & URTWN_CHIP_88E) ? \
+ R88E_MACID_MAX : R92C_MACID_MAX)
+#define URTWN_MACID_UNDEFINED (uint8_t)-1
#define URTWN_MACID_VALID 0x80
} __packed;
@@ -956,6 +978,8 @@ struct r92c_rx_stat {
#define R92C_RXDW0_ICVERR 0x00008000
#define R92C_RXDW0_INFOSZ_M 0x000f0000
#define R92C_RXDW0_INFOSZ_S 16
+#define R92C_RXDW0_CIPHER_M 0x00700000
+#define R92C_RXDW0_CIPHER_S 20
#define R92C_RXDW0_QOS 0x00800000
#define R92C_RXDW0_SHIFT_M 0x03000000
#define R92C_RXDW0_SHIFT_S 24
@@ -972,6 +996,11 @@ struct r92c_rx_stat {
#define R92C_RXDW3_RATE_S 0
#define R92C_RXDW3_HT 0x00000040
#define R92C_RXDW3_HTC 0x00000400
+#define R88E_RXDW3_RPT_M 0x0000c000
+#define R88E_RXDW3_RPT_S 14
+#define R88E_RXDW3_RPT_RX 0
+#define R88E_RXDW3_RPT_TX1 1
+#define R88E_RXDW3_RPT_TX2 2
uint32_t rxdw4;
uint32_t rxdw5;
@@ -1059,6 +1088,7 @@ struct r92c_tx_desc {
uint32_t txdw2;
#define R88E_TXDW2_AGGBK 0x00010000
+#define R88E_TXDW2_CCX_RPT 0x00080000
uint16_t txdw3;
uint16_t txdseq;
@@ -1091,6 +1121,30 @@ struct r92c_tx_desc {
uint16_t pad;
} __packed __attribute__((aligned(4)));
+struct r88e_tx_rpt_ccx {
+ uint8_t rptb0;
+ uint8_t rptb1;
+#define R88E_RPTB1_MACID_M 0x3f
+#define R88E_RPTB1_MACID_S 0
+#define R88E_RPTB1_PKT_OK 0x40
+#define R88E_RPTB1_BMC 0x80
+
+ uint8_t rptb2;
+#define R88E_RPTB2_RETRY_CNT_M 0x3f
+#define R88E_RPTB2_RETRY_CNT_S 0
+#define R88E_RPTB2_LIFE_EXPIRE 0x40
+#define R88E_RPTB2_RETRY_OVER 0x80
+
+ uint8_t rptb3;
+ uint8_t rptb4;
+ uint8_t rptb5;
+ uint8_t rptb6;
+#define R88E_RPTB6_QSEL_M 0xf0
+#define R88E_RPTB6_QSEL_S 4
+
+ uint8_t rptb7;
+} __packed;
+
static const uint8_t ridx2rate[] =
{ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
diff --git a/sys/dev/usb/wlan/if_urtwnvar.h b/sys/dev/usb/wlan/if_urtwnvar.h
index 8901c75..cbb94f9 100644
--- a/sys/dev/usb/wlan/if_urtwnvar.h
+++ b/sys/dev/usb/wlan/if_urtwnvar.h
@@ -71,21 +71,30 @@ struct urtwn_data {
};
typedef STAILQ_HEAD(, urtwn_data) urtwn_datahead;
+union sec_param {
+ struct ieee80211_key key;
+};
+
+#define CMD_FUNC_PROTO void (*func)(struct urtwn_softc *, \
+ union sec_param *)
+
struct urtwn_cmdq {
- void *arg0;
- void *arg1;
- void (*func)(void *);
- struct ieee80211_key *k;
- struct ieee80211_key key;
- uint8_t mac[IEEE80211_ADDR_LEN];
- uint8_t wcid;
+ union sec_param data;
+ CMD_FUNC_PROTO;
};
+#define URTWN_CMDQ_SIZE 16
struct urtwn_fw_info {
const uint8_t *data;
size_t size;
};
+struct urtwn_node {
+ struct ieee80211_node ni; /* must be the first */
+ uint8_t id;
+};
+#define URTWN_NODE(ni) ((struct urtwn_node *)(ni))
+
struct urtwn_vap {
struct ieee80211vap vap;
@@ -152,10 +161,16 @@ struct urtwn_softc {
#define URTWN_CHIP_UMC_A_CUT 0x08
#define URTWN_CHIP_88E 0x10
+#define URTWN_CHIP_HAS_RATECTL(_sc) (!!((_sc)->chip & URTWN_CHIP_88E))
+
+ void (*sc_node_free)(struct ieee80211_node *);
void (*sc_rf_write)(struct urtwn_softc *,
int, uint8_t, uint32_t);
int (*sc_power_on)(struct urtwn_softc *);
+ struct ieee80211_node *node_list[R88E_MACID_MAX];
+ struct mtx nt_mtx;
+
uint8_t board_type;
uint8_t regulatory;
uint8_t pa_setting;
@@ -190,18 +205,13 @@ struct urtwn_softc {
struct callout sc_watchdog_ch;
struct mtx sc_mtx;
+ uint32_t keys_bmap;
-/* need to be power of 2, otherwise URTWN_CMDQ_GET fails */
-#define URTWN_CMDQ_MAX 16
-#define URTWN_CMDQ_MASQ (URTWN_CMDQ_MAX - 1)
- struct urtwn_cmdq cmdq[URTWN_CMDQ_MAX];
+ struct urtwn_cmdq cmdq[URTWN_CMDQ_SIZE];
+ struct mtx cmdq_mtx;
struct task cmdq_task;
- uint32_t cmdq_store;
- uint8_t cmdq_exec;
- uint8_t cmdq_run;
- uint8_t cmdq_key_set;
-#define URTWN_CMDQ_ABORT 0
-#define URTWN_CMDQ_GO 1
+ uint8_t cmdq_first;
+ uint8_t cmdq_last;
uint32_t rf_chnlbw[R92C_MAX_CHAINS];
struct usb_xfer *sc_xfer[URTWN_N_TRANSFER];
@@ -213,3 +223,15 @@ struct urtwn_softc {
#define URTWN_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
#define URTWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
#define URTWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
+
+#define URTWN_CMDQ_LOCK_INIT(sc) \
+ mtx_init(&(sc)->cmdq_mtx, "cmdq lock", NULL, MTX_DEF)
+#define URTWN_CMDQ_LOCK(sc) mtx_lock(&(sc)->cmdq_mtx)
+#define URTWN_CMDQ_UNLOCK(sc) mtx_unlock(&(sc)->cmdq_mtx)
+#define URTWN_CMDQ_LOCK_DESTROY(sc) mtx_destroy(&(sc)->cmdq_mtx)
+
+#define URTWN_NT_LOCK_INIT(sc) \
+ mtx_init(&(sc)->nt_mtx, "node table lock", NULL, MTX_DEF)
+#define URTWN_NT_LOCK(sc) mtx_lock(&(sc)->nt_mtx)
+#define URTWN_NT_UNLOCK(sc) mtx_unlock(&(sc)->nt_mtx)
+#define URTWN_NT_LOCK_DESTROY(sc) mtx_destroy(&(sc)->nt_mtx)
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index dc7a87f..d23f306 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -2893,3 +2893,4 @@ DRIVER_MODULE(zyd, uhub, zyd_driver, zyd_devclass, NULL, 0);
MODULE_DEPEND(zyd, usb, 1, 1, 1);
MODULE_DEPEND(zyd, wlan, 1, 1, 1);
MODULE_VERSION(zyd, 1);
+USB_PNP_HOST_INFO(zyd_devs);
diff --git a/sys/dev/wi/if_wi_pccard.c b/sys/dev/wi/if_wi_pccard.c
index 414dc20d..82c1680 100644
--- a/sys/dev/wi/if_wi_pccard.c
+++ b/sys/dev/wi/if_wi_pccard.c
@@ -153,6 +153,7 @@ static const struct pccard_product wi_pccard_products[] = {
PCMCIA_CARD(TDK, LAK_CD011WL),
{ NULL }
};
+PCCARD_PNP_INFO(wi_pccard_products);
static int
wi_pccard_probe(device_t dev)
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index 3bbc73a..b59d3e6 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -2,6 +2,7 @@
* Copyright (c) 2006,2007
* Damien Bergamini <damien.bergamini@free.fr>
* Benjamin Close <Benjamin.Close@clearchain.com>
+ * Copyright (c) 2015 Andriy Voskoboinyk <avos@FreeBSD.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/sys/dev/wpi/if_wpi_debug.h b/sys/dev/wpi/if_wpi_debug.h
index 6b78ace..da4b71f 100644
--- a/sys/dev/wpi/if_wpi_debug.h
+++ b/sys/dev/wpi/if_wpi_debug.h
@@ -2,6 +2,7 @@
* Copyright (c) 2006,2007
* Damien Bergamini <damien.bergamini@free.fr>
* Benjamin Close <Benjamin.Close@clearchain.com>
+ * Copyright (c) 2015 Andriy Voskoboinyk <avos@FreeBSD.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/sys/dev/wtap/if_wtap_module.c b/sys/dev/wtap/if_wtap_module.c
index 7a87d57..764f8a6 100644
--- a/sys/dev/wtap/if_wtap_module.c
+++ b/sys/dev/wtap/if_wtap_module.c
@@ -41,7 +41,6 @@
#include <sys/ucred.h>
#include <sys/jail.h>
-#include <sys/types.h>
#include <sys/sockio.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
diff --git a/sys/dev/wtap/if_wtapvar.h b/sys/dev/wtap/if_wtapvar.h
index 5ba55cb..a5cfd49 100644
--- a/sys/dev/wtap/if_wtapvar.h
+++ b/sys/dev/wtap/if_wtapvar.h
@@ -32,7 +32,6 @@
#ifndef _DEV_WTAP_WTAPVAR_H
#define _DEV_WTAP_WTAPVAR_H
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/module.h>
@@ -44,7 +43,6 @@
#include <sys/lock.h>
#include <sys/mutex.h>
-#include <sys/types.h>
#include <sys/sockio.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
diff --git a/sys/dev/wtap/plugins/visibility.c b/sys/dev/wtap/plugins/visibility.c
index a73d520..620dfd6 100644
--- a/sys/dev/wtap/plugins/visibility.c
+++ b/sys/dev/wtap/plugins/visibility.c
@@ -41,7 +41,6 @@
#include <sys/ucred.h>
#include <sys/jail.h>
-#include <sys/types.h>
#include <sys/sockio.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
diff --git a/sys/dev/xe/if_xe_pccard.c b/sys/dev/xe/if_xe_pccard.c
index 4db7c8e..bbe6253 100644
--- a/sys/dev/xe/if_xe_pccard.c
+++ b/sys/dev/xe/if_xe_pccard.c
@@ -386,3 +386,4 @@ static driver_t xe_pccard_driver = {
devclass_t xe_devclass;
DRIVER_MODULE(xe, pccard, xe_pccard_driver, xe_devclass, 0, 0);
+PCCARD_PNP_INFO(xe_pccard_products);
diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c
index 922e814..fa9973c 100644
--- a/sys/geom/part/g_part_gpt.c
+++ b/sys/geom/part/g_part_gpt.c
@@ -823,22 +823,23 @@ g_part_gpt_probe(struct g_part_table *table, struct g_consumer *cp)
return (error);
res = le16dec(buf + DOSMAGICOFFSET);
pri = G_PART_PROBE_PRI_LOW;
- for (index = 0; index < NDOSPART; index++) {
- if (buf[DOSPARTOFF + DOSPARTSIZE * index + 4] == 0xee)
- pri = G_PART_PROBE_PRI_HIGH;
- }
- g_free(buf);
- if (res != DOSMAGIC)
- return (ENXIO);
+ if (res == DOSMAGIC) {
+ for (index = 0; index < NDOSPART; index++) {
+ if (buf[DOSPARTOFF + DOSPARTSIZE * index + 4] == 0xee)
+ pri = G_PART_PROBE_PRI_HIGH;
+ }
+ g_free(buf);
- /* Check that there's a primary header. */
- buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error);
- if (buf == NULL)
- return (error);
- res = memcmp(buf, GPT_HDR_SIG, 8);
- g_free(buf);
- if (res == 0)
- return (pri);
+ /* Check that there's a primary header. */
+ buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error);
+ if (buf == NULL)
+ return (error);
+ res = memcmp(buf, GPT_HDR_SIG, 8);
+ g_free(buf);
+ if (res == 0)
+ return (pri);
+ } else
+ g_free(buf);
/* No primary? Check that there's a secondary. */
buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize,
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index 785f066..7454d79 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -1409,7 +1409,7 @@ linker_addmodules(linker_file_t lf, struct mod_metadata **start,
if (mp->md_type != MDT_VERSION)
continue;
modname = mp->md_cval;
- ver = ((struct mod_version *)mp->md_data)->mv_version;
+ ver = ((const struct mod_version *)mp->md_data)->mv_version;
if (modlist_lookup(modname, ver) != NULL) {
printf("module %s already present!\n", modname);
/* XXX what can we do? this is a build error. :-( */
@@ -1530,7 +1530,7 @@ restart:
if (mp->md_type != MDT_VERSION)
continue;
modname = mp->md_cval;
- nver = ((struct mod_version *)
+ nver = ((const struct mod_version *)
mp->md_data)->mv_version;
if (modlist_lookup(modname,
nver) != NULL) {
@@ -2056,7 +2056,7 @@ linker_load_dependencies(linker_file_t lf)
if (mp->md_type != MDT_VERSION)
continue;
modname = mp->md_cval;
- ver = ((struct mod_version *)mp->md_data)->mv_version;
+ ver = ((const struct mod_version *)mp->md_data)->mv_version;
mod = modlist_lookup(modname, ver);
if (mod != NULL) {
printf("interface %s.%d already present in the KLD"
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 01aff78..e7c81d6 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -475,8 +475,7 @@ malloc(unsigned long size, struct malloc_type *mtp, int flags)
if (flags & M_WAITOK)
KASSERT(curthread->td_intr_nesting_level == 0,
("malloc(M_WAITOK) in interrupt context"));
-
- KASSERT(curthread->td_critnest == 0,
+ KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(),
("malloc: called with spinlock or critical section held"));
#ifdef DEBUG_MEMGUARD
@@ -544,8 +543,7 @@ free(void *addr, struct malloc_type *mtp)
u_long size;
KASSERT(mtp->ks_magic == M_MAGIC, ("free: bad malloc type magic"));
-
- KASSERT(curthread->td_critnest == 0,
+ KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(),
("free: called with spinlock or critical section held"));
/* free(NULL, ...) does nothing */
@@ -610,8 +608,7 @@ realloc(void *addr, unsigned long size, struct malloc_type *mtp, int flags)
KASSERT(mtp->ks_magic == M_MAGIC,
("realloc: bad malloc type magic"));
-
- KASSERT(curthread->td_critnest == 0,
+ KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(),
("realloc: called with spinlock or critical section held"));
/* realloc(NULL, ...) is equivalent to malloc(...) */
diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c
index 941da42..a1ad3c9 100644
--- a/sys/kern/kern_racct.c
+++ b/sys/kern/kern_racct.c
@@ -495,13 +495,13 @@ racct_destroy(struct racct **racct)
}
/*
- * Increase consumption of 'resource' by 'amount' for 'racct'
- * and all its parents. Differently from other cases, 'amount' here
+ * Increase consumption of 'resource' by 'amount' for 'racct',
+ * but not its parents. Differently from other cases, 'amount' here
* may be less than zero.
*/
static void
racct_adjust_resource(struct racct *racct, int resource,
- uint64_t amount)
+ int64_t amount)
{
ASSERT_RACCT_ENABLED();
@@ -631,8 +631,8 @@ racct_add_force(struct proc *p, int resource, uint64_t amount)
mtx_lock(&racct_lock);
racct_adjust_resource(p->p_racct, resource, amount);
+ racct_add_cred_locked(p->p_ucred, resource, amount);
mtx_unlock(&racct_lock);
- racct_add_cred(p->p_ucred, resource, amount);
}
static int
diff --git a/sys/kern/kern_rctl.c b/sys/kern/kern_rctl.c
index c04c58b..ee3b385 100644
--- a/sys/kern/kern_rctl.c
+++ b/sys/kern/kern_rctl.c
@@ -282,7 +282,7 @@ rctl_would_exceed(const struct proc *p, const struct rctl_rule *rule,
}
/*
- * Special version of rctl_available() function for the %cpu resource.
+ * Special version of rctl_get_available() for the %CPU resource.
* We slightly cheat here and return less than we normally would.
*/
int64_t
diff --git a/sys/mips/include/cpuregs.h b/sys/mips/include/cpuregs.h
index 54a9234..a39f6a6 100644
--- a/sys/mips/include/cpuregs.h
+++ b/sys/mips/include/cpuregs.h
@@ -524,7 +524,7 @@
#define MIPS_CONFIG0_MT_MASK 0x00000380 /* bits 9..7 MMU Type */
#define MIPS_CONFIG0_MT_SHIFT 7
#define MIPS_CONFIG0_BE 0x00008000 /* data is big-endian */
-#define MIPS_CONFIG0_VI 0x00000004 /* instruction cache is virtual */
+#define MIPS_CONFIG0_VI 0x00000008 /* instruction cache is virtual */
#define MIPS_CONFIG1_TLBSZ_MASK 0x7E000000 /* bits 30..25 # tlb entries minus one */
#define MIPS_CONFIG1_TLBSZ_SHIFT 25
diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c
index c7b1042..f2749e5 100644
--- a/sys/net/if_llatbl.c
+++ b/sys/net/if_llatbl.c
@@ -288,6 +288,47 @@ lltable_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
}
/*
+ * Tries to update @lle link-level address.
+ * Since update requires AFDATA WLOCK, function
+ * drops @lle lock, acquires AFDATA lock and then acquires
+ * @lle lock to maintain lock order.
+ *
+ * Returns 1 on success.
+ */
+int
+lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
+ const char *lladdr)
+{
+
+ /* Perform real LLE update */
+ /* use afdata WLOCK to update fields */
+ LLE_WLOCK_ASSERT(lle);
+ LLE_ADDREF(lle);
+ LLE_WUNLOCK(lle);
+ IF_AFDATA_WLOCK(ifp);
+ LLE_WLOCK(lle);
+
+ /*
+ * Since we droppped LLE lock, other thread might have deleted
+ * this lle. Check and return
+ */
+ if ((lle->la_flags & LLE_DELETED) != 0) {
+ IF_AFDATA_WUNLOCK(ifp);
+ LLE_FREE_LOCKED(lle);
+ return (0);
+ }
+
+ /* Update data */
+ lltable_set_entry_addr(ifp, lle, lladdr);
+
+ IF_AFDATA_WUNLOCK(ifp);
+
+ LLE_REMREF(lle);
+
+ return (1);
+}
+
+/*
*
* Performes generic cleanup routines and frees lle.
*
diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h
index 044959e..8a300c3 100644
--- a/sys/net/if_llatbl.h
+++ b/sys/net/if_llatbl.h
@@ -79,6 +79,8 @@ struct llentry {
int16_t ln_state; /* IPv6 has ND6_LLINFO_NOSTATE == -2 */
uint16_t ln_router;
time_t ln_ntick;
+ time_t lle_remtime; /* Real time remaining */
+ time_t lle_hittime; /* Time when r_skip_req was unset */
int lle_refcnt;
LIST_ENTRY(llentry) lle_chain; /* chain of deleted items */
@@ -222,6 +224,8 @@ struct llentry *llentry_alloc(struct ifnet *, struct lltable *,
size_t lltable_drop_entry_queue(struct llentry *);
void lltable_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
const char *lladdr);
+int lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
+ const char *lladdr);
struct llentry *lltable_alloc_entry(struct lltable *llt, u_int flags,
const struct sockaddr *l4addr);
diff --git a/sys/net/route.c b/sys/net/route.c
index 6b19edd..86f99ee 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1586,7 +1586,10 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
*/
struct sockaddr *info_dst = info->rti_info[RTAX_DST];
info->rti_info[RTAX_DST] = ndst;
+ /* Do not delete existing PINNED(interface) routes */
+ info->rti_flags &= ~RTF_PINNED;
rt_old = rt_unlinkrte(rnh, info, &error);
+ info->rti_flags |= RTF_PINNED;
info->rti_info[RTAX_DST] = info_dst;
if (rt_old != NULL)
rn = rnh->rnh_addaddr(ndst, netmask, rnh,
diff --git a/sys/net80211/ieee80211_phy.h b/sys/net80211/ieee80211_phy.h
index bf39cdd..cb6b358 100644
--- a/sys/net80211/ieee80211_phy.h
+++ b/sys/net80211/ieee80211_phy.h
@@ -53,6 +53,10 @@
#define IEEE80211_DUR_SHSLOT 9 /* ERP short slottime */
#define IEEE80211_DUR_OFDM_SLOT 9 /* OFDM slottime */
+#define IEEE80211_GET_SLOTTIME(ic) \
+ ((ic->ic_flags & IEEE80211_F_SHSLOT) ? \
+ IEEE80211_DUR_SHSLOT : IEEE80211_DUR_SLOT)
+
/*
* DIFS (microseconds).
*/
diff --git a/sys/netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c b/sys/netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c
index d7cff74..634eb54 100644
--- a/sys/netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c
+++ b/sys/netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c
@@ -584,14 +584,14 @@ out:
* PC Card (PCMCIA) probe routine
*/
+static struct pccard_product const bt3c_pccard_products[] = {
+ PCMCIA_CARD(3COM, 3CRWB609),
+ { NULL, }
+};
+
static int
bt3c_pccard_probe(device_t dev)
{
- static struct pccard_product const bt3c_pccard_products[] = {
- PCMCIA_CARD(3COM, 3CRWB609),
- { NULL, }
- };
-
struct pccard_product const *pp = NULL;
pp = pccard_product_lookup(dev, bt3c_pccard_products,
@@ -1222,4 +1222,4 @@ bt3c_modevent(module_t mod, int event, void *data)
DRIVER_MODULE(bt3c, pccard, bt3c_pccard_driver, bt3c_devclass, bt3c_modevent,0);
MODULE_VERSION(ng_bt3c, NG_BLUETOOTH_VERSION);
MODULE_DEPEND(ng_bt3c, netgraph, NG_ABI_VERSION, NG_ABI_VERSION,NG_ABI_VERSION);
-
+PCCARD_PNP_INFO(bt3c_pccard_products);
diff --git a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
index f34c708..4121ebc 100644
--- a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
+++ b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
@@ -1872,4 +1872,4 @@ MODULE_VERSION(ng_ubt, NG_BLUETOOTH_VERSION);
MODULE_DEPEND(ng_ubt, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
MODULE_DEPEND(ng_ubt, ng_hci, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
MODULE_DEPEND(ng_ubt, usb, 1, 1, 1);
-
+USB_PNP_HOST_INFO(ubt_devs);
diff --git a/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c b/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c
index da00e05..d5e55ea 100644
--- a/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c
+++ b/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c
@@ -170,8 +170,15 @@ static driver_t ubtbcmfw_driver =
.size = sizeof(struct ubtbcmfw_softc),
};
+static const STRUCT_USB_HOST_ID ubtbcmfw_devs[] = {
+/* Broadcom BCM2033 devices only */
+ { USB_VPI(USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033, 0) },
+};
+
+
DRIVER_MODULE(ubtbcmfw, uhub, ubtbcmfw_driver, ubtbcmfw_devclass, NULL, 0);
MODULE_DEPEND(ubtbcmfw, usb, 1, 1, 1);
+USB_PNP_HOST_INFO(ubtbcmfw_devs);
/*
* Probe for a USB Bluetooth device
@@ -180,11 +187,6 @@ MODULE_DEPEND(ubtbcmfw, usb, 1, 1, 1);
static int
ubtbcmfw_probe(device_t dev)
{
- static const STRUCT_USB_HOST_ID devs[] = {
- /* Broadcom BCM2033 devices only */
- { USB_VPI(USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033, 0) },
- };
-
struct usb_attach_arg *uaa = device_get_ivars(dev);
if (uaa->usb_mode != USB_MODE_HOST)
@@ -193,7 +195,7 @@ ubtbcmfw_probe(device_t dev)
if (uaa->info.bIfaceIndex != 0)
return (ENXIO);
- return (usbd_lookup_id_by_uaa(devs, sizeof(devs), uaa));
+ return (usbd_lookup_id_by_uaa(ubtbcmfw_devs, sizeof(ubtbcmfw_devs), uaa));
} /* ubtbcmfw_probe */
/*
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index ca15a0d..9edfcf6 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -5641,30 +5641,6 @@ next_chunk:
}
-#ifdef INVARIANTS
-#ifdef __GNUC__
-__attribute__((noinline))
-#endif
- void
- sctp_validate_no_locks(struct sctp_inpcb *inp)
-{
- struct sctp_tcb *lstcb;
-
- LIST_FOREACH(lstcb, &inp->sctp_asoc_list, sctp_tcblist) {
- if (mtx_owned(&lstcb->tcb_mtx)) {
- panic("Own lock on stcb at return from input");
- }
- }
- if (mtx_owned(&inp->inp_create_mtx)) {
- panic("Own create lock on inp");
- }
- if (mtx_owned(&inp->inp_mtx)) {
- panic("Own inp lock on inp");
- }
-}
-
-#endif
-
/*
* common input chunk processing (v4 and v6)
*/
@@ -6048,11 +6024,6 @@ out:
SCTP_INP_DECR_REF(inp_decr);
SCTP_INP_WUNLOCK(inp_decr);
}
-#ifdef INVARIANTS
- if (inp != NULL) {
- sctp_validate_no_locks(inp);
- }
-#endif
return;
}
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 1929b24..c131edf 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -13538,13 +13538,6 @@ out_unlocked:
}
}
#endif
-#ifdef INVARIANTS
- if (inp) {
- sctp_validate_no_locks(inp);
- } else {
- SCTP_PRINTF("Warning - inp is NULL so cant validate locks\n");
- }
-#endif
if (top) {
sctp_m_freem(top);
}
diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
index ff6ccc5..165ef3b 100644
--- a/sys/netinet/sctp_pcb.h
+++ b/sys/netinet/sctp_pcb.h
@@ -654,11 +654,5 @@ void
#endif
-#ifdef INVARIANTS
-void
- sctp_validate_no_locks(struct sctp_inpcb *inp);
-
-#endif
-
#endif /* _KERNEL */
#endif /* !__sctp_pcb_h__ */
diff --git a/sys/netinet/tcp_hostcache.c b/sys/netinet/tcp_hostcache.c
index a492540..5e8342f 100644
--- a/sys/netinet/tcp_hostcache.c
+++ b/sys/netinet/tcp_hostcache.c
@@ -32,8 +32,8 @@
* table to a dedicated structure indexed by the remote IP address. It keeps
* information on the measured TCP parameters of past TCP sessions to allow
* better initial start values to be used with later connections to/from the
- * same source. Depending on the network parameters (delay, bandwidth, max
- * MTU, congestion window) between local and remote sites, this can lead to
+ * same source. Depending on the network parameters (delay, max MTU,
+ * congestion window) between local and remote sites, this can lead to
* significant speed-ups for new TCP connections after the first one.
*
* Due to the tcp_hostcache, all TCP-specific metrics information in the
@@ -440,7 +440,6 @@ tcp_hc_get(struct in_conninfo *inc, struct hc_metrics_lite *hc_metrics_lite)
hc_metrics_lite->rmx_ssthresh = hc_entry->rmx_ssthresh;
hc_metrics_lite->rmx_rtt = hc_entry->rmx_rtt;
hc_metrics_lite->rmx_rttvar = hc_entry->rmx_rttvar;
- hc_metrics_lite->rmx_bandwidth = hc_entry->rmx_bandwidth;
hc_metrics_lite->rmx_cwnd = hc_entry->rmx_cwnd;
hc_metrics_lite->rmx_sendpipe = hc_entry->rmx_sendpipe;
hc_metrics_lite->rmx_recvpipe = hc_entry->rmx_recvpipe;
@@ -555,14 +554,6 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml)
(hc_entry->rmx_ssthresh + hcml->rmx_ssthresh) / 2;
TCPSTAT_INC(tcps_cachedssthresh);
}
- if (hcml->rmx_bandwidth != 0) {
- if (hc_entry->rmx_bandwidth == 0)
- hc_entry->rmx_bandwidth = hcml->rmx_bandwidth;
- else
- hc_entry->rmx_bandwidth =
- (hc_entry->rmx_bandwidth + hcml->rmx_bandwidth) / 2;
- /* TCPSTAT_INC(tcps_cachedbandwidth); */
- }
if (hcml->rmx_cwnd != 0) {
if (hc_entry->rmx_cwnd == 0)
hc_entry->rmx_cwnd = hcml->rmx_cwnd;
@@ -612,7 +603,7 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
SBUF_INCLUDENUL);
sbuf_printf(&sb,
- "\nIP address MTU SSTRESH RTT RTTVAR BANDWIDTH "
+ "\nIP address MTU SSTRESH RTT RTTVAR "
" CWND SENDPIPE RECVPIPE HITS UPD EXP\n");
#define msec(u) (((u) + 500) / 1000)
@@ -621,8 +612,8 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
TAILQ_FOREACH(hc_entry, &V_tcp_hostcache.hashbase[i].hch_bucket,
rmx_q) {
sbuf_printf(&sb,
- "%-15s %5lu %8lu %6lums %6lums %9lu %8lu %8lu %8lu "
- "%4lu %4lu %4i\n",
+ "%-15s %5lu %8lu %6lums %6lums %8lu %8lu %8lu %4lu "
+ "%4lu %4i\n",
hc_entry->ip4.s_addr ? inet_ntoa(hc_entry->ip4) :
#ifdef INET6
ip6_sprintf(ip6buf, &hc_entry->ip6),
@@ -635,7 +626,6 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
(RTM_RTTUNIT / (hz * TCP_RTT_SCALE))),
msec(hc_entry->rmx_rttvar *
(RTM_RTTUNIT / (hz * TCP_RTTVAR_SCALE))),
- hc_entry->rmx_bandwidth * 8,
hc_entry->rmx_cwnd,
hc_entry->rmx_sendpipe,
hc_entry->rmx_recvpipe,
diff --git a/sys/netinet/tcp_hostcache.h b/sys/netinet/tcp_hostcache.h
index 05aea12..44875ff 100644
--- a/sys/netinet/tcp_hostcache.h
+++ b/sys/netinet/tcp_hostcache.h
@@ -57,7 +57,6 @@ struct hc_metrics {
u_long rmx_ssthresh; /* outbound gateway buffer limit */
u_long rmx_rtt; /* estimated round trip time */
u_long rmx_rttvar; /* estimated rtt variance */
- u_long rmx_bandwidth; /* estimated bandwidth */
u_long rmx_cwnd; /* congestion window */
u_long rmx_sendpipe; /* outbound delay-bandwidth product */
u_long rmx_recvpipe; /* inbound delay-bandwidth product */
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index a298edf..bf8347a 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -335,7 +335,6 @@ struct hc_metrics_lite { /* must stay in sync with hc_metrics */
u_long rmx_ssthresh; /* outbound gateway buffer limit */
u_long rmx_rtt; /* estimated round trip time */
u_long rmx_rttvar; /* estimated rtt variance */
- u_long rmx_bandwidth; /* estimated bandwidth */
u_long rmx_cwnd; /* congestion window */
u_long rmx_sendpipe; /* outbound delay-bandwidth product */
u_long rmx_recvpipe; /* inbound delay-bandwidth product */
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index b168a53..5c1563c 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -2064,6 +2064,7 @@ in6_lltable_destroy_lle(struct llentry *lle)
LLE_WUNLOCK(lle);
LLE_LOCK_DESTROY(lle);
+ LLE_REQ_DESTROY(lle);
free(lle, M_LLTABLE);
}
@@ -2080,6 +2081,7 @@ in6_lltable_new(const struct in6_addr *addr6, u_int flags)
lle->base.lle_refcnt = 1;
lle->base.lle_free = in6_lltable_destroy_lle;
LLE_LOCK_INIT(&lle->base);
+ LLE_REQ_INIT(&lle->base);
callout_init(&lle->base.lle_timer, 1);
return (&lle->base);
@@ -2288,6 +2290,13 @@ in6_lltable_lookup(struct lltable *llt, u_int flags,
if (lle == NULL)
return (NULL);
+ KASSERT((flags & (LLE_UNLOCKED|LLE_EXCLUSIVE)) !=
+ (LLE_UNLOCKED|LLE_EXCLUSIVE),("wrong lle request flags: 0x%X",
+ flags));
+
+ if (flags & LLE_UNLOCKED)
+ return (lle);
+
if (flags & LLE_EXCLUSIVE)
LLE_WLOCK(lle);
else
@@ -2350,8 +2359,8 @@ in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
sdl->sdl_index = ifp->if_index;
sdl->sdl_type = ifp->if_type;
bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen);
- ndpc.rtm.rtm_rmx.rmx_expire =
- lle->la_flags & LLE_STATIC ? 0 : lle->la_expire;
+ ndpc.rtm.rtm_rmx.rmx_expire = lle->la_expire +
+ lle->lle_remtime / hz;
ndpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA);
if (lle->la_flags & LLE_STATIC)
ndpc.rtm.rtm_flags |= RTF_STATIC;
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index a925470..a79922b 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -542,6 +542,107 @@ nd6_llinfo_get_holdsrc(struct llentry *ln, struct in6_addr *src)
}
/*
+ * Checks if we need to switch from STALE state.
+ *
+ * RFC 4861 requires switching from STALE to DELAY state
+ * on first packet matching entry, waiting V_nd6_delay and
+ * transition to PROBE state (if upper layer confirmation was
+ * not received).
+ *
+ * This code performs a bit differently:
+ * On packet hit we don't change state (but desired state
+ * can be guessed by control plane). However, after V_nd6_delay
+ * seconds code will transition to PROBE state (so DELAY state
+ * is kinda skipped in most situations).
+ *
+ * Typically, V_nd6_gctimer is bigger than V_nd6_delay, so
+ * we perform the following upon entering STALE state:
+ *
+ * 1) Arm timer to run each V_nd6_delay seconds to make sure that
+ * if packet was transmitted at the start of given interval, we
+ * would be able to switch to PROBE state in V_nd6_delay seconds
+ * as user expects.
+ *
+ * 2) Reschedule timer until original V_nd6_gctimer expires keeping
+ * lle in STALE state (remaining timer value stored in lle_remtime).
+ *
+ * 3) Reschedule timer if packet was transmitted less that V_nd6_delay
+ * seconds ago.
+ *
+ * Returns non-zero value if the entry is still STALE (storing
+ * the next timer interval in @pdelay).
+ *
+ * Returns zero value if original timer expired or we need to switch to
+ * PROBE (store that in @do_switch variable).
+ */
+static int
+nd6_is_stale(struct llentry *lle, long *pdelay, int *do_switch)
+{
+ int nd_delay, nd_gctimer, r_skip_req;
+ time_t lle_hittime;
+ long delay;
+
+ *do_switch = 0;
+ nd_gctimer = V_nd6_gctimer;
+ nd_delay = V_nd6_delay;
+
+ LLE_REQ_LOCK(lle);
+ r_skip_req = lle->r_skip_req;
+ lle_hittime = lle->lle_hittime;
+ LLE_REQ_UNLOCK(lle);
+
+ if (r_skip_req > 0) {
+
+ /*
+ * Nonzero r_skip_req value was set upon entering
+ * STALE state. Since value was not changed, no
+ * packets were passed using this lle. Ask for
+ * timer reschedule and keep STALE state.
+ */
+ delay = (long)(MIN(nd_gctimer, nd_delay));
+ delay *= hz;
+ if (lle->lle_remtime > delay)
+ lle->lle_remtime -= delay;
+ else {
+ delay = lle->lle_remtime;
+ lle->lle_remtime = 0;
+ }
+
+ if (delay == 0) {
+
+ /*
+ * The original ng6_gctime timeout ended,
+ * no more rescheduling.
+ */
+ return (0);
+ }
+
+ *pdelay = delay;
+ return (1);
+ }
+
+ /*
+ * Packet received. Verify timestamp
+ */
+ delay = (long)(time_uptime - lle_hittime);
+ if (delay < nd_delay) {
+
+ /*
+ * V_nd6_delay still not passed since the first
+ * hit in STALE state.
+ * Reshedule timer and return.
+ */
+ *pdelay = (long)(nd_delay - delay) * hz;
+ return (1);
+ }
+
+ /* Request switching to probe */
+ *do_switch = 1;
+ return (0);
+}
+
+
+/*
* Switch @lle state to new state optionally arming timers.
*
* Set noinline to be dtrace-friendly
@@ -550,9 +651,11 @@ __noinline void
nd6_llinfo_setstate(struct llentry *lle, int newstate)
{
struct ifnet *ifp;
- long delay;
+ int nd_gctimer, nd_delay;
+ long delay, remtime;
delay = 0;
+ remtime = 0;
switch (newstate) {
case ND6_LLINFO_INCOMPLETE:
@@ -566,7 +669,19 @@ nd6_llinfo_setstate(struct llentry *lle, int newstate)
}
break;
case ND6_LLINFO_STALE:
- delay = (long)V_nd6_gctimer * hz;
+
+ /*
+ * Notify fast path that we want to know if any packet
+ * is transmitted by setting r_skip_req.
+ */
+ LLE_REQ_LOCK(lle);
+ lle->r_skip_req = 1;
+ LLE_REQ_UNLOCK(lle);
+ nd_delay = V_nd6_delay;
+ nd_gctimer = V_nd6_gctimer;
+
+ delay = (long)(MIN(nd_gctimer, nd_delay)) * hz;
+ remtime = (long)nd_gctimer * hz - delay;
break;
case ND6_LLINFO_DELAY:
lle->la_asked = 0;
@@ -577,6 +692,7 @@ nd6_llinfo_setstate(struct llentry *lle, int newstate)
if (delay > 0)
nd6_llinfo_settimer_locked(lle, delay);
+ lle->lle_remtime = remtime;
lle->ln_state = newstate;
}
@@ -592,7 +708,8 @@ nd6_llinfo_timer(void *arg)
struct in6_addr *dst, *pdst, *psrc, src;
struct ifnet *ifp;
struct nd_ifinfo *ndi = NULL;
- int send_ns;
+ int do_switch, send_ns;
+ long delay;
KASSERT(arg != NULL, ("%s: arg NULL", __func__));
ln = (struct llentry *)arg;
@@ -680,13 +797,35 @@ nd6_llinfo_timer(void *arg)
break;
case ND6_LLINFO_STALE:
- /* Garbage Collection(RFC 2461 5.3) */
- if (!ND6_LLINFO_PERMANENT(ln)) {
- EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_EXPIRED);
- nd6_free(ln, 1);
- ln = NULL;
+ if (nd6_is_stale(ln, &delay, &do_switch) != 0) {
+
+ /*
+ * No packet has used this entry and GC timeout
+ * has not been passed. Reshedule timer and
+ * return.
+ */
+ nd6_llinfo_settimer_locked(ln, delay);
+ break;
}
- break;
+
+ if (do_switch == 0) {
+
+ /*
+ * GC timer has ended and entry hasn't been used.
+ * Run Garbage collector (RFC 4861, 5.3)
+ */
+ if (!ND6_LLINFO_PERMANENT(ln)) {
+ EVENTHANDLER_INVOKE(lle_event, ln,
+ LLENTRY_EXPIRED);
+ nd6_free(ln, 1);
+ ln = NULL;
+ }
+ break;
+ }
+
+ /* Entry has been used AND delay timer has ended. */
+
+ /* FALLTHROUGH */
case ND6_LLINFO_DELAY:
if (ndi && (ndi->flags & ND6_IFF_PERFORMNUD) != 0) {
@@ -1796,7 +1935,11 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
* Record source link-layer address
* XXX is it dependent to ifp->if_type?
*/
- lltable_set_entry_addr(ifp, ln, lladdr);
+ if (lltable_try_set_entry_addr(ifp, ln, lladdr) == 0) {
+ /* Entry was deleted */
+ return;
+ }
+
nd6_llinfo_setstate(ln, ND6_LLINFO_STALE);
EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_RESOLVED);
@@ -1996,31 +2139,25 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
}
IF_AFDATA_RLOCK(ifp);
- ln = nd6_lookup(&dst6->sin6_addr, 0, ifp);
- IF_AFDATA_RUNLOCK(ifp);
-
- /*
- * Perform fast path for the following cases:
- * 1) lle state is REACHABLE
- * 2) lle state is DELAY (NS message sent)
- *
- * Every other case involves lle modification, so we handle
- * them separately.
- */
- if (ln == NULL || (ln->ln_state != ND6_LLINFO_REACHABLE &&
- ln->ln_state != ND6_LLINFO_DELAY)) {
- /* Fall back to slow processing path */
- if (ln != NULL)
- LLE_RUNLOCK(ln);
- return (nd6_resolve_slow(ifp, m, dst6, desten, pflags));
+ ln = nd6_lookup(&dst6->sin6_addr, LLE_UNLOCKED, ifp);
+ if (ln != NULL && (ln->r_flags & RLLE_VALID) != 0) {
+ /* Entry found, let's copy lle info */
+ bcopy(&ln->ll_addr, desten, ifp->if_addrlen);
+ if (pflags != NULL)
+ *pflags = LLE_VALID | (ln->r_flags & RLLE_IFADDR);
+ /* Check if we have feedback request from nd6 timer */
+ if (ln->r_skip_req != 0) {
+ LLE_REQ_LOCK(ln);
+ ln->r_skip_req = 0; /* Notify that entry was used */
+ ln->lle_hittime = time_uptime;
+ LLE_REQ_UNLOCK(ln);
+ }
+ IF_AFDATA_RUNLOCK(ifp);
+ return (0);
}
+ IF_AFDATA_RUNLOCK(ifp);
-
- bcopy(&ln->ll_addr, desten, ifp->if_addrlen);
- if (pflags != NULL)
- *pflags = ln->la_flags;
- LLE_RUNLOCK(ln);
- return (0);
+ return (nd6_resolve_slow(ifp, m, dst6, desten, pflags));
}
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 93d5b58..bf43fb6 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -765,7 +765,10 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
/*
* Record link-layer address, and update the state.
*/
- lltable_set_entry_addr(ifp, ln, lladdr);
+ if (lltable_try_set_entry_addr(ifp, ln, lladdr) == 0) {
+ ln = NULL;
+ goto freeit;
+ }
EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_RESOLVED);
if (is_solicited)
nd6_llinfo_setstate(ln, ND6_LLINFO_REACHABLE);
@@ -831,7 +834,12 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
* Update link-local address, if any.
*/
if (lladdr != NULL) {
- lltable_set_entry_addr(ifp, ln, lladdr);
+ int ret;
+ ret = lltable_try_set_entry_addr(ifp, ln,lladdr);
+ if (ret == 0) {
+ ln = NULL;
+ goto freeit;
+ }
EVENTHANDLER_INVOKE(lle_event, ln,
LLENTRY_RESOLVED);
}
diff --git a/sys/powerpc/booke/booke_machdep.c b/sys/powerpc/booke/booke_machdep.c
index 4b831c4..c98e301 100644
--- a/sys/powerpc/booke/booke_machdep.c
+++ b/sys/powerpc/booke/booke_machdep.c
@@ -142,7 +142,7 @@ __FBSDID("$FreeBSD$");
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
-#ifdef MPC85XX
+#if defined(MPC85XX) || defined(QORIQ_DPAA)
#include <powerpc/mpc85xx/mpc85xx.h>
#endif
@@ -183,6 +183,7 @@ extern void *int_data_storage;
extern void *int_instr_storage;
extern void *int_external_input;
extern void *int_alignment;
+extern void *int_fpu;
extern void *int_program;
extern void *int_syscall;
extern void *int_decrementer;
@@ -191,6 +192,8 @@ extern void *int_watchdog;
extern void *int_data_tlb_error;
extern void *int_inst_tlb_error;
extern void *int_debug;
+extern void *int_vec;
+extern void *int_vecast;
#ifdef HWPMC_HOOKS
extern void *int_performance_counter;
#endif
@@ -234,6 +237,15 @@ ivor_setup(void)
#ifdef HWPMC_HOOKS
SET_TRAP(SPR_IVOR35, int_performance_counter);
#endif
+ switch ((mfpvr() >> 16) & 0xffff) {
+ case FSL_E6500:
+ SET_TRAP(SPR_IVOR32, int_vec);
+ SET_TRAP(SPR_IVOR33, int_vecast);
+ /* FALLTHROUGH */
+ case FSL_E500mc:
+ case FSL_E5500:
+ SET_TRAP(SPR_IVOR7, int_fpu);
+ }
}
static int
@@ -284,7 +296,7 @@ booke_init(uint32_t arg1, uint32_t arg2)
* relatively small number, such as 64K. arg2 is the
* physical address of the argv vector.
* - ePAPR loaders pass an FDT blob in r3 (arg1) and the magic hex
- * string 0x45504150 ('ePAP') in r6 (which has been lost by now).
+ * string 0x45504150 ('EPAP') in r6 (which has been lost by now).
* r4 (arg2) is supposed to be set to zero, but is not always.
*/
@@ -302,9 +314,6 @@ booke_init(uint32_t arg1, uint32_t arg2)
else /* U-Boot */
mdp = NULL;
- /* Reset TLB1 to get rid of temporary mappings */
- tlb1_init();
-
ret = powerpc_init(dtbp, 0, 0, mdp);
/* Enable L1 caches */
diff --git a/sys/powerpc/booke/trap_subr.S b/sys/powerpc/booke/trap_subr.S
index 11ebd30..5f5f1aa 100644
--- a/sys/powerpc/booke/trap_subr.S
+++ b/sys/powerpc/booke/trap_subr.S
@@ -393,12 +393,19 @@
.globl CNAME(interrupt_vector_base)
.align 5
interrupt_vector_base:
+/*****************************************************************************
+ * Catch-all handler to handle uninstalled IVORs
+ ****************************************************************************/
+INTERRUPT(int_unknown)
+ STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
+ FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_RSVD)
+ b trap_common
/*****************************************************************************
* Critical input interrupt
****************************************************************************/
INTERRUPT(int_critical_input)
- STANDARD_PROLOG(SPR_SPRG2, PC_BOOKE_CRITSAVE, SPR_CSRR0, SPR_CSRR1)
+ STANDARD_CRIT_PROLOG(SPR_SPRG2, PC_BOOKE_CRITSAVE, SPR_CSRR0, SPR_CSRR1)
FRAME_SETUP(SPR_SPRG2, PC_BOOKE_CRITSAVE, EXC_CRIT)
addi %r3, %r1, 8
bl CNAME(powerpc_interrupt)
@@ -459,6 +466,12 @@ INTERRUPT(int_program)
b trap_common
+INTERRUPT(int_fpu)
+ STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
+ FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_FPU)
+ b trap_common
+
+
/*****************************************************************************
* System call
****************************************************************************/
@@ -497,6 +510,24 @@ INTERRUPT(int_watchdog)
b trap_common
+/*****************************************************************************
+ * Altivec Unavailable interrupt
+ ****************************************************************************/
+INTERRUPT(int_vec)
+ STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
+ FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_VEC)
+ b trap_common
+
+
+/*****************************************************************************
+ * Watchdog interrupt
+ ****************************************************************************/
+INTERRUPT(int_vecast)
+ STANDARD_PROLOG(SPR_SPRG1, PC_TEMPSAVE, SPR_SRR0, SPR_SRR1)
+ FRAME_SETUP(SPR_SPRG1, PC_TEMPSAVE, EXC_VECAST_E)
+ b trap_common
+
+
#ifdef HWPMC_HOOKS
/*****************************************************************************
* PMC Interrupt
diff --git a/sys/powerpc/include/trap.h b/sys/powerpc/include/trap.h
index 3ca4b13..81c40c9 100644
--- a/sys/powerpc/include/trap.h
+++ b/sys/powerpc/include/trap.h
@@ -86,6 +86,7 @@
#define EXC_ITMISS 0x1200 /* Instruction TLB Miss */
#define EXC_APU 0x1300 /* Auxiliary Processing Unit */
#define EXC_DEBUG 0x2f10 /* Debug trap */
+#define EXC_VECAST_E 0x2f20 /* Altivec Assist (Book-E) */
#define EXC_LAST 0x2f00 /* Last possible exception vector */
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index a18c293..4c9735a 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -252,6 +252,7 @@ trap(struct trapframe *frame)
enable_fpu(td);
break;
+ case EXC_VECAST_E:
case EXC_VECAST_G4:
case EXC_VECAST_G5:
/*
diff --git a/sys/sys/module.h b/sys/sys/module.h
index 4582bf9..f0192d5 100644
--- a/sys/sys/module.h
+++ b/sys/sys/module.h
@@ -89,10 +89,19 @@ struct mod_version {
struct mod_metadata {
int md_version; /* structure version MDTV_* */
int md_type; /* type of entry MDT_* */
- void *md_data; /* specific data */
+ const void *md_data; /* specific data */
const char *md_cval; /* common string label */
};
+struct mod_pnp_match_info
+{
+ const char *descr; /* Description of the table */
+ const char *bus; /* Name of the bus for this table */
+ const void *table; /* Pointer to pnp table */
+ int entry_len; /* Length of each entry in the table (may be */
+ /* longer than descr describes). */
+ int num_entry; /* Number of entries in the table */
+};
#ifdef _KERNEL
#include <sys/linker_set.h>
@@ -155,6 +164,44 @@ struct mod_metadata {
MODULE_METADATA(_##module##_version, MDT_VERSION, \
&_##module##_version, #module)
+/**
+ * Generic macros to create pnp info hints that modules may export
+ * to allow external tools to parse their intenral device tables
+ * to make an informed guess about what driver(s) to load.
+ */
+#define MODULE_PNP_INFO(d, b, unique, t, l, n) \
+ static const struct mod_pnp_match_info _module_pnp_##b##_##unique = { \
+ .descr = d, \
+ .bus = #b, \
+ .table = t, \
+ .entry_len = l, \
+ .num_entry = n \
+ }; \
+ MODULE_METADATA(_md_##b##_pnpinfo_##unique, MDT_PNP_INFO, \
+ &_module_pnp_##b##_##unique, #b);
+/**
+ * descr is a string that describes each entry in the table. The general
+ * form is (TYPE:pnp_name[/pnp_name];)*
+ * where TYPE is one of the following:
+ * U8 uint8_t element
+ * V8 like U8 and 0xff means match any
+ * G16 uint16_t element, any value >= matches
+ * L16 uint16_t element, any value <= matches
+ * M16 uint16_t element, mask of which of the following fields to use.
+ * U16 uint16_t element
+ * V16 like U16 and 0xffff means match any
+ * U32 uint32_t element
+ * V32 like U32 and 0xffffffff means match any
+ * W32 Two 16-bit values with first pnp_name in LSW and second in MSW.
+ * Z pointer to a string to match exactly
+ * D like Z, but is the string passed to device_set_descr()
+ * P A pointer that should be ignored
+ * E EISA PNP Identifier (in binary, but bus publishes string)
+ * K Key for whole table. pnp_name=value. must be last, if present.
+ *
+ * The pnp_name "#" is reserved for other fields that should be ignored.
+ */
+
extern struct sx modules_sx;
#define MOD_XLOCK sx_xlock(&modules_sx)
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 1f57dff..3a0a799 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -2149,8 +2149,7 @@ uma_zalloc_arg(uma_zone_t zone, void *udata, int flags)
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
"uma_zalloc_arg: zone \"%s\"", zone->uz_name);
}
-
- KASSERT(curthread->td_critnest == 0,
+ KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(),
("uma_zalloc_arg: called with spinlock or critical section held"));
#ifdef DEBUG_MEMGUARD
@@ -2690,7 +2689,7 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata)
CTR2(KTR_UMA, "uma_zfree_arg thread %x zone %s", curthread,
zone->uz_name);
- KASSERT(curthread->td_critnest == 0,
+ KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(),
("uma_zfree_arg: called with spinlock or critical section held"));
/* uma_zfree(..., NULL) does nothing, to match free(9). */
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index de67e4e..e5edf77 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -1324,22 +1324,17 @@ vm_page_prev(vm_page_t m)
vm_page_t
vm_page_replace(vm_page_t mnew, vm_object_t object, vm_pindex_t pindex)
{
- vm_page_t mold, mpred;
+ vm_page_t mold;
VM_OBJECT_ASSERT_WLOCKED(object);
+ KASSERT(mnew->object == NULL,
+ ("vm_page_replace: page already in object"));
/*
* This function mostly follows vm_page_insert() and
* vm_page_remove() without the radix, object count and vnode
* dance. Double check such functions for more comments.
*/
- mpred = vm_radix_lookup(&object->rtree, pindex);
- KASSERT(mpred != NULL,
- ("vm_page_replace: replacing page not present with pindex"));
- mpred = TAILQ_PREV(mpred, respgs, listq);
- if (mpred != NULL)
- KASSERT(mpred->pindex < pindex,
- ("vm_page_insert_after: mpred doesn't precede pindex"));
mnew->object = object;
mnew->pindex = pindex;
@@ -1347,17 +1342,17 @@ vm_page_replace(vm_page_t mnew, vm_object_t object, vm_pindex_t pindex)
KASSERT(mold->queue == PQ_NONE,
("vm_page_replace: mold is on a paging queue"));
- /* Detach the old page from the resident tailq. */
+ /* Keep the resident page list in sorted order. */
+ TAILQ_INSERT_AFTER(&object->memq, mold, mnew, listq);
TAILQ_REMOVE(&object->memq, mold, listq);
mold->object = NULL;
vm_page_xunbusy(mold);
- /* Insert the new page in the resident tailq. */
- if (mpred != NULL)
- TAILQ_INSERT_AFTER(&object->memq, mpred, mnew, listq);
- else
- TAILQ_INSERT_HEAD(&object->memq, mnew, listq);
+ /*
+ * The object's resident_page_count does not change because we have
+ * swapped one page for another, but OBJ_MIGHTBEDIRTY.
+ */
if (pmap_page_is_write_mapped(mnew))
vm_object_set_writeable_dirty(object);
return (mold);
diff --git a/tools/bsdbox/Makefile.base b/tools/bsdbox/Makefile.base
index be90098..0274949 100644
--- a/tools/bsdbox/Makefile.base
+++ b/tools/bsdbox/Makefile.base
@@ -14,7 +14,7 @@ CRUNCH_ALIAS_tset= reset
CRUNCH_PROGS_usr.bin+= vmstat
#CRUNCH_PROGS_user.bin+= systat
-CRUNCH_LIBS+= -ldevstat -lncursesw -lncurses -lmemstat -lkvm
+CRUNCH_LIBS+= -ldevstat -lncursesw -lncurses -lmemstat -lkvm -lelf
# CRUNCH_PROGS_usr.bin+= tar
CRUNCH_PROGS_usr.bin+= cpio
diff --git a/tools/tools/nanobsd/defaults.sh b/tools/tools/nanobsd/defaults.sh
index 46608f4..9bc1779 100755
--- a/tools/tools/nanobsd/defaults.sh
+++ b/tools/tools/nanobsd/defaults.sh
@@ -1024,7 +1024,7 @@ export_var ( ) { # Don't wawnt a subshell
set_defaults_and_export ( ) {
: ${NANO_OBJ:=/usr/obj/nanobsd.${NANO_NAME}}
: ${MAKEOBJDIRPREFIX:=${NANO_OBJ}}
- : ${NANO_DISKIMGDIR=:${NANO_OBJ}}
+ : ${NANO_DISKIMGDIR:=${NANO_OBJ}}
NANO_WORLDDIR=${NANO_OBJ}/_.w
NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build
NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install
diff --git a/tools/tools/nanobsd/embedded/common b/tools/tools/nanobsd/embedded/common
index c0bbae9..0a79b6a 100644
--- a/tools/tools/nanobsd/embedded/common
+++ b/tools/tools/nanobsd/embedded/common
@@ -86,7 +86,7 @@ NANO_CFG_BASE=$(pwd)
NANO_CFG_BASE=$(realpath ${NANO_CFG_BASE}/..)
NANO_SRC=$(realpath ${NANO_CFG_BASE}/../../..)
#### XXX share obj
-NANO_OBJ=${NANO_SRC}/../$NANO_NAME/obj
+NANO_OBJ=$(realpath ${NANO_SRC}/../$NANO_NAME/obj)
# Where cust_pkg() finds packages to install
#XXX: Is this the right place?
#NANO_PORTS=$(realpath ${NANO_SRC}/../ports)
@@ -296,7 +296,7 @@ create_diskimage_mbr ( ) (
rm -fr ${NANO_OBJ}/_.${i}*
done
- # Populate the FAT partition
+ # Populate the FAT partition, if needed
if [-n "${NANO_SLICE_FAT}" ]; then
echo Creating MSDOS partition for kernel
newfs_msdos -C ${NANO_SLICE_FAT_SIZE} -F 16 -L ${NANO_NAME} \
@@ -305,6 +305,11 @@ create_diskimage_mbr ( ) (
# makefs -t msdos once that's supported
fi
+ # Populate the Powerpc boot image, if needed
+ if [ "${NANO_LAYOUT}" = powerpc64-ibm ]; then
+ dd if=${NANO_WORLDDIR}/boot/boot1.elf of=${NANO_OBJ}/_.s1 bs=800k count=1 conv=sync
+ fi
+
# Populate the / partition, and place it into a slice with a
# bsd label
[ -z ${NANO_NOPRIV_BUILD} ] || extra="-F ${NANO_METALOG}"
@@ -357,9 +362,9 @@ create_diskimage_mbr ( ) (
# boot image is on a special partition, ala std-embedded, but that
# partition isn't FAT with special files, but a copy of the boot
# loader itself.
- mkimg ${fmtarg} -s mbr -p ppcboot:=${NANO_WORLDDIR}/boot/boot1.elf \
+ mkimg -a 1 ${fmtarg} -s mbr -p prepboot:=${NANO_OBJ}/_.s1 \
-p ${s2}:=${NANO_OBJ}/_.s2 \
- -p ${s3}:=${NANO_OBJ}/_.s3 \
+ -p ${s3}:=${NANO_OBJ}/_.s3a \
-o ${NANO_OBJ}/_.disk.image.${NANO_NAME}${fmt}
;;
esac
diff --git a/tools/tools/nanobsd/embedded/qemu-powerpc64.cfg b/tools/tools/nanobsd/embedded/qemu-powerpc64.cfg
index 00f177a..3789ee8 100644
--- a/tools/tools/nanobsd/embedded/qemu-powerpc64.cfg
+++ b/tools/tools/nanobsd/embedded/qemu-powerpc64.cfg
@@ -31,6 +31,6 @@ NANO_KERNEL=GENERIC64
NANO_DRIVE=ada0
NANO_NAME=qemu-powerpc64
-qemu_env
+NANO_DISKIMAGE_FORMAT=qcow2
. common # Pull in common definitions, keep last
diff --git a/usr.bin/mkimg/mbr.c b/usr.bin/mkimg/mbr.c
index 20d4d91..071bcf5 100644
--- a/usr.bin/mkimg/mbr.c
+++ b/usr.bin/mkimg/mbr.c
@@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
#ifndef DOSPTYP_FAT32
#define DOSPTYP_FAT32 0x0b
#endif
+#ifndef DOSPTYP_PPCBOOT
+#define DOSPTYP_PPCBOOT 0x41
+#endif
#ifndef DOSPTYP_EFI
#define DOSPTYP_EFI 0xef
#endif
@@ -56,6 +59,7 @@ static struct mkimg_alias mbr_aliases[] = {
{ ALIAS_FAT32, ALIAS_INT2TYPE(DOSPTYP_FAT32) },
{ ALIAS_FREEBSD, ALIAS_INT2TYPE(DOSPTYP_386BSD) },
{ ALIAS_NTFS, ALIAS_INT2TYPE(DOSPTYP_NTFS) },
+ { ALIAS_PPCBOOT, ALIAS_INT2TYPE(DOSPTYP_PPCBOOT) },
{ ALIAS_NONE, 0 } /* Keep last! */
};
diff --git a/usr.bin/mkimg/scheme.c b/usr.bin/mkimg/scheme.c
index 1e64855..6cd332f 100644
--- a/usr.bin/mkimg/scheme.c
+++ b/usr.bin/mkimg/scheme.c
@@ -61,6 +61,7 @@ static struct {
{ "freebsd-zfs", ALIAS_FREEBSD_ZFS },
{ "mbr", ALIAS_MBR },
{ "ntfs", ALIAS_NTFS },
+ { "prepboot", ALIAS_PPCBOOT },
{ NULL, ALIAS_NONE } /* Keep last! */
};
diff --git a/usr.bin/mkimg/scheme.h b/usr.bin/mkimg/scheme.h
index 3ba4243..552d031 100644
--- a/usr.bin/mkimg/scheme.h
+++ b/usr.bin/mkimg/scheme.h
@@ -47,6 +47,7 @@ enum alias {
ALIAS_FREEBSD_ZFS,
ALIAS_MBR,
ALIAS_NTFS,
+ ALIAS_PPCBOOT,
/* end */
ALIAS_COUNT /* Keep last! */
};
diff --git a/usr.bin/unzip/unzip.1 b/usr.bin/unzip/unzip.1
index fd9b10f..163fbae 100644
--- a/usr.bin/unzip/unzip.1
+++ b/usr.bin/unzip/unzip.1
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 10, 2012
+.Dd December 12, 2015
.Dt UNZIP 1
.Os
.Sh NAME
@@ -33,7 +33,7 @@
.Nd extract files from a ZIP archive
.Sh SYNOPSIS
.Nm
-.Op Fl aCcfjLlnopqtuv
+.Op Fl aCcfjLlnopqtuvy
.Op Fl d Ar dir
.Ar zipfile
.Sh DESCRIPTION
@@ -102,6 +102,8 @@ content of the archive.
.It Fl x Ar pattern
Exclude files matching the pattern
.Ar pattern .
+.It Fl y
+Print four digit years in listings instead of two.
.It Fl Z Ar mode
Emulate
.Xr zipinfo 1L
diff --git a/usr.bin/unzip/unzip.c b/usr.bin/unzip/unzip.c
index 841c9fb..cb639fb 100644
--- a/usr.bin/unzip/unzip.c
+++ b/usr.bin/unzip/unzip.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Joerg Sonnenberger <joerg@NetBSD.org>
+ * Copyright (c) 2009, 2010 Joerg Sonnenberger <joerg@NetBSD.org>
* Copyright (c) 2007-2008 Dag-Erling Smørgrav
* All rights reserved.
*
@@ -65,6 +65,7 @@ static int q_opt; /* quiet */
static int t_opt; /* test */
static int u_opt; /* update */
static int v_opt; /* verbose/list */
+static const char *y_str = ""; /* 4 digit year */
static int Z1_opt; /* zipinfo mode list files only */
/* debug flag */
@@ -126,7 +127,6 @@ errorx(const char *fmt, ...)
exit(1);
}
-#if 0
/* non-fatal error message + errno */
static void
warning(const char *fmt, ...)
@@ -142,7 +142,6 @@ warning(const char *fmt, ...)
va_end(ap);
fprintf(stderr, ": %s\n", strerror(errno));
}
-#endif
/* non-fatal error message, no errno */
static void
@@ -439,7 +438,7 @@ handle_existing_file(char **path)
(void)unlink(*path);
return 1;
case 'N':
- n_opt = 1;
+ n_opt = 1;
/* FALLTHROUGH */
case 'n':
return -1;
@@ -461,6 +460,34 @@ handle_existing_file(char **path)
}
/*
+ * Detect binary files by a combination of character white list and
+ * black list. NUL bytes and other control codes without use in text files
+ * result directly in switching the file to binary mode. Otherwise, at least
+ * one white-listed byte has to be found.
+ *
+ * Black-listed: 0..6, 14..25, 28..31
+ * White-listed: 9..10, 13, >= 32
+ *
+ * See the proginfo/txtvsbin.txt in the zip sources for a detailed discussion.
+ */
+#define BYTE_IS_BINARY(x) ((x) < 32 && (0xf3ffc07fU & (1U << (x))))
+#define BYTE_IS_TEXT(x) ((x) >= 32 || (0x00002600U & (1U << (x))))
+
+static int
+check_binary(const unsigned char *buf, size_t len)
+{
+ int rv;
+ for (rv = 1; len--; ++buf) {
+ if (BYTE_IS_BINARY(*buf))
+ return 1;
+ if (BYTE_IS_TEXT(*buf))
+ rv = 0;
+ }
+
+ return rv;
+}
+
+/*
* Extract a regular file.
*/
static void
@@ -472,6 +499,7 @@ extract_file(struct archive *a, struct archive_entry *e, char **path)
struct timespec ts[2];
int cr, fd, text, warn, check;
ssize_t len;
+ const char *linkname;
unsigned char *p, *q, *end;
mode = archive_entry_mode(e) & 0777;
@@ -485,7 +513,7 @@ recheck:
if (lstat(*path, &sb) == 0) {
if (u_opt || f_opt) {
/* check if up-to-date */
- if (S_ISREG(sb.st_mode) &&
+ if ((S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode)) &&
(sb.st_mtim.tv_sec > mtime.tv_sec ||
(sb.st_mtim.tv_sec == mtime.tv_sec &&
sb.st_mtim.tv_nsec >= mtime.tv_nsec)))
@@ -509,6 +537,24 @@ recheck:
return;
}
+ ts[0].tv_sec = 0;
+ ts[0].tv_nsec = UTIME_NOW;
+ ts[1] = mtime;
+
+ /* process symlinks */
+ linkname = archive_entry_symlink(e);
+ if (linkname != NULL) {
+ if (symlink(linkname, *path) != 0)
+ error("symlink('%s')", *path);
+ info(" extracting: %s -> %s\n", *path, linkname);
+ if (lchmod(*path, mode) != 0)
+ warning("Cannot set mode for '%s'", *path);
+ /* set access and modification time */
+ if (utimensat(AT_FDCWD, *path, ts, AT_SYMLINK_NOFOLLOW) != 0)
+ warning("utimensat('%s')", *path);
+ return;
+ }
+
if ((fd = open(*path, O_RDWR|O_CREAT|O_TRUNC, mode)) < 0)
error("open('%s')", *path);
@@ -550,12 +596,8 @@ recheck:
* guess wrong, we print a warning message later.
*/
if (a_opt && n == 0) {
- for (p = buffer; p < end; ++p) {
- if (!isascii((unsigned char)*p)) {
- text = 0;
- break;
- }
- }
+ if (check_binary(buffer, len))
+ text = 0;
}
/* simple case */
@@ -568,7 +610,7 @@ recheck:
/* hard case: convert \r\n to \n (sigh...) */
for (p = buffer; p < end; p = q + 1) {
for (q = p; q < end; q++) {
- if (!warn && !isascii(*q)) {
+ if (!warn && BYTE_IS_BINARY(*q)) {
warningx("%s may be corrupted due"
" to weak text file detection"
" heuristic", *path);
@@ -594,9 +636,6 @@ recheck:
info("\n");
/* set access and modification time */
- ts[0].tv_sec = 0;
- ts[0].tv_nsec = UTIME_NOW;
- ts[1] = mtime;
if (futimens(fd, ts) != 0)
error("futimens('%s')", *path);
if (close(fd) != 0)
@@ -639,7 +678,7 @@ extract(struct archive *a, struct archive_entry *e)
}
/* I don't think this can happen in a zipfile.. */
- if (!S_ISDIR(filetype) && !S_ISREG(filetype)) {
+ if (!S_ISDIR(filetype) && !S_ISREG(filetype) && !S_ISLNK(filetype)) {
warningx("skipping non-regular entry '%s'", pathname);
ac(archive_read_data_skip(a));
free(pathname);
@@ -695,7 +734,7 @@ extract_stdout(struct archive *a, struct archive_entry *e)
filetype = archive_entry_filetype(e);
/* I don't think this can happen in a zipfile.. */
- if (!S_ISDIR(filetype) && !S_ISREG(filetype)) {
+ if (!S_ISDIR(filetype) && !S_ISREG(filetype) && !S_ISLNK(filetype)) {
warningx("skipping non-regular entry '%s'", pathname);
ac(archive_read_data_skip(a));
free(pathname);
@@ -753,12 +792,8 @@ extract_stdout(struct archive *a, struct archive_entry *e)
* guess wrong, we print a warning message later.
*/
if (a_opt && n == 0) {
- for (p = buffer; p < end; ++p) {
- if (!isascii((unsigned char)*p)) {
- text = 0;
- break;
- }
- }
+ if (check_binary(buffer, len))
+ text = 0;
}
/* simple case */
@@ -771,7 +806,7 @@ extract_stdout(struct archive *a, struct archive_entry *e)
/* hard case: convert \r\n to \n (sigh...) */
for (p = buffer; p < end; p = q + 1) {
for (q = p; q < end; q++) {
- if (!warn && !isascii(*q)) {
+ if (!warn && BYTE_IS_BINARY(*q)) {
warningx("%s may be corrupted due"
" to weak text file detection"
" heuristic", pathname);
@@ -802,9 +837,14 @@ list(struct archive *a, struct archive_entry *e)
{
char buf[20];
time_t mtime;
+ struct tm *tm;
mtime = archive_entry_mtime(e);
- strftime(buf, sizeof(buf), "%m-%d-%g %R", localtime(&mtime));
+ tm = localtime(&mtime);
+ if (*y_str)
+ strftime(buf, sizeof(buf), "%m-%d-%G %R", tm);
+ else
+ strftime(buf, sizeof(buf), "%m-%d-%g %R", tm);
if (!zipinfo_mode) {
if (v_opt == 1) {
@@ -855,7 +895,6 @@ test(struct archive *a, struct archive_entry *e)
return error_count;
}
-
/*
* Main loop: open the zipfile, iterate over its contents and decide what
* to do with each entry.
@@ -878,11 +917,11 @@ unzip(const char *fn)
if (!p_opt && !q_opt)
printf("Archive: %s\n", fn);
if (v_opt == 1) {
- printf(" Length Date Time Name\n");
- printf(" -------- ---- ---- ----\n");
+ printf(" Length %sDate Time Name\n", y_str);
+ printf(" -------- %s---- ---- ----\n", y_str);
} else if (v_opt == 2) {
- printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
- printf("-------- ------ ------- ----- ---- ---- ------ ----\n");
+ printf(" Length Method Size Ratio %sDate Time CRC-32 Name\n", y_str);
+ printf("-------- ------ ------- ----- %s---- ---- ------ ----\n", y_str);
}
}
@@ -914,13 +953,13 @@ unzip(const char *fn)
if (zipinfo_mode) {
if (v_opt == 1) {
- printf(" -------- -------\n");
- printf(" %8ju %ju file%s\n",
- total_size, file_count, file_count != 1 ? "s" : "");
+ printf(" -------- %s-------\n", y_str);
+ printf(" %8ju %s%ju file%s\n",
+ total_size, y_str, file_count, file_count != 1 ? "s" : "");
} else if (v_opt == 2) {
- printf("-------- ------- --- -------\n");
- printf("%8ju %7ju 0%% %ju file%s\n",
- total_size, total_size, file_count,
+ printf("-------- ------- --- %s-------\n", y_str);
+ printf("%8ju %7ju 0%% %s%ju file%s\n",
+ total_size, total_size, y_str, file_count,
file_count != 1 ? "s" : "");
}
}
@@ -930,7 +969,7 @@ unzip(const char *fn)
if (t_opt) {
if (error_count > 0) {
- errorx("%d checksum error(s) found.", error_count);
+ errorx("%ju checksum error(s) found.", error_count);
}
else {
printf("No errors detected in compressed data of %s.\n",
@@ -943,7 +982,7 @@ static void
usage(void)
{
- fprintf(stderr, "usage: unzip [-aCcfjLlnopqtuvZ1] [-d dir] [-x pattern] zipfile\n");
+ fprintf(stderr, "Usage: unzip [-aCcfjLlnopqtuvyZ1] [-d dir] [-x pattern] zipfile\n");
exit(1);
}
@@ -953,7 +992,7 @@ getopts(int argc, char *argv[])
int opt;
optreset = optind = 1;
- while ((opt = getopt(argc, argv, "aCcd:fjLlnopqtuvx:Z1")) != -1)
+ while ((opt = getopt(argc, argv, "aCcd:fjLlnopqtuvx:yZ1")) != -1)
switch (opt) {
case '1':
Z1_opt = 1;
@@ -1008,6 +1047,9 @@ getopts(int argc, char *argv[])
case 'x':
add_pattern(&exclude, optarg);
break;
+ case 'y':
+ y_str = " ";
+ break;
case 'Z':
zipinfo_mode = 1;
break;
@@ -1040,7 +1082,7 @@ main(int argc, char *argv[])
*/
nopts = getopts(argc, argv);
- /*
+ /*
* When more of the zipinfo mode options are implemented, this
* will need to change.
*/
diff --git a/usr.sbin/crunch/crunchide/exec_elf32.c b/usr.sbin/crunch/crunchide/exec_elf32.c
index fc9a959..6d94429 100644
--- a/usr.sbin/crunch/crunchide/exec_elf32.c
+++ b/usr.sbin/crunch/crunchide/exec_elf32.c
@@ -187,6 +187,10 @@ ELFNAMEEND(check)(int fd, const char *fn)
case /* EM_MIPS_RS3_LE */ EM_MIPS_RS4_BE: break;
case EM_PPC: break;
case EM_PPC64: break;
+#ifndef EM_RISCV
+#define EM_RISCV 243
+#endif
+ case EM_RISCV: break;
case EM_SPARCV9: break;
case EM_X86_64: break;
/* ELFDEFNNAME(MACHDEP_ID_CASES) */
diff --git a/usr.sbin/kldxref/kldxref.c b/usr.sbin/kldxref/kldxref.c
index 1e81801..01b7c65 100644
--- a/usr.sbin/kldxref/kldxref.c
+++ b/usr.sbin/kldxref/kldxref.c
@@ -34,6 +34,7 @@
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/endian.h>
#include <sys/exec.h>
#include <sys/queue.h>
#include <sys/kernel.h>
@@ -53,7 +54,7 @@
#include "ef.h"
-#define MAXRECSIZE 8192
+#define MAXRECSIZE (64 << 10) /* 64k */
#define check(val) if ((error = (val)) != 0) break
static int dflag; /* do not create a hint file, only write on stdout */
@@ -134,14 +135,244 @@ record_string(const char *str)
return record_buf(str, len);
}
+/* From sys/isa/pnp.c */
+static char *
+pnp_eisaformat(uint32_t id)
+{
+ uint8_t *data;
+ static char idbuf[8];
+ const char hextoascii[] = "0123456789abcdef";
+
+ id = htole32(id);
+ data = (uint8_t *)&id;
+ idbuf[0] = '@' + ((data[0] & 0x7c) >> 2);
+ idbuf[1] = '@' + (((data[0] & 0x3) << 3) + ((data[1] & 0xe0) >> 5));
+ idbuf[2] = '@' + (data[1] & 0x1f);
+ idbuf[3] = hextoascii[(data[2] >> 4)];
+ idbuf[4] = hextoascii[(data[2] & 0xf)];
+ idbuf[5] = hextoascii[(data[3] >> 4)];
+ idbuf[6] = hextoascii[(data[3] & 0xf)];
+ idbuf[7] = 0;
+ return(idbuf);
+}
+
+struct pnp_elt
+{
+ int pe_kind; /* What kind of entry */
+#define TYPE_SZ_MASK 0x0f
+#define TYPE_FLAGGED 0x10 /* all f's is a wildcard */
+#define TYPE_INT 0x20 /* Is a number */
+#define TYPE_PAIRED 0x40
+#define TYPE_LE 0x80 /* Matches <= this value */
+#define TYPE_GE 0x100 /* Matches >= this value */
+#define TYPE_MASK 0x200 /* Specifies a mask to follow */
+#define TYPE_U8 (1 | TYPE_INT)
+#define TYPE_V8 (1 | TYPE_INT | TYPE_FLAGGED)
+#define TYPE_G16 (2 | TYPE_INT | TYPE_GE)
+#define TYPE_L16 (2 | TYPE_INT | TYPE_LE)
+#define TYPE_M16 (2 | TYPE_INT | TYPE_MASK)
+#define TYPE_U16 (2 | TYPE_INT)
+#define TYPE_V16 (2 | TYPE_INT | TYPE_FLAGGED)
+#define TYPE_U32 (4 | TYPE_INT)
+#define TYPE_V32 (4 | TYPE_INT | TYPE_FLAGGED)
+#define TYPE_W32 (4 | TYPE_INT | TYPE_PAIRED)
+#define TYPE_D 7
+#define TYPE_Z 8
+#define TYPE_P 9
+#define TYPE_E 10
+#define TYPE_T 11
+ int pe_offset; /* Offset within the element */
+ char * pe_key; /* pnp key name */
+ TAILQ_ENTRY(pnp_elt) next; /* Link */
+};
+typedef TAILQ_HEAD(pnp_head, pnp_elt) pnp_list;
+
+/*
+ * this function finds the data from the pnp table, as described by the
+ * the description and creates a new output (new_desc). This output table
+ * is a form that's easier for the agent that's automatically loading the
+ * modules.
+ *
+ * The format output is the simplified string from this routine in the
+ * same basic format as the pnp string, as documented in sys/module.h.
+ * First a string describing the format is output, the a count of the
+ * number of records, then each record. The format string also describes
+ * the length of each entry (though it isn't a fixed length when strings
+ * are present).
+ *
+ * type Output Meaning
+ * I uint32_t Integer equality comparison
+ * J uint32_t Pair of uint16_t fields converted to native
+ byte order. The two fields both must match.
+ * G uint32_t Greater than or equal to
+ * L uint32_t Less than or equal to
+ * M uint32_t Mask of which fields to test. Fields that
+ take up space increment the count. This
+ field must be first, and resets the count.
+ * D string Description of the device this pnp info is for
+ * Z string pnp string must match this
+ * T nothing T fields set pnp values that must be true for
+ * the entire table.
+ * Values are packed the same way that other values are packed in this file.
+ * Strings and int32_t's start on a 32-bit boundary and are padded with 0
+ * bytes. Objects that are smaller than uint32_t are converted, without
+ * sign extension to uint32_t to simplify parsing downstream.
+ */
+static int
+parse_pnp_list(const char *desc, char **new_desc, pnp_list *list)
+{
+ const char *walker = desc, *ep = desc + strlen(desc);
+ const char *colon, *semi;
+ struct pnp_elt *elt;
+ char *nd;
+ char type[8], key[32];
+ int off;
+
+ off = 0;
+ nd = *new_desc = malloc(strlen(desc) + 1);
+ if (verbose > 1)
+ printf("Converting %s into a list\n", desc);
+ while (walker < ep) {
+ colon = strchr(walker, ':');
+ semi = strchr(walker, ';');
+ if (semi != NULL && semi < colon)
+ goto err;
+ if (colon - walker > sizeof(type))
+ goto err;
+ strncpy(type, walker, colon - walker);
+ type[colon - walker] = '\0';
+ if (semi) {
+ if (semi - colon >= sizeof(key))
+ goto err;
+ strncpy(key, colon + 1, semi - colon - 1);
+ key[semi - colon - 1] = '\0';
+ walker = semi + 1;
+ } else {
+ if (strlen(colon + 1) >= sizeof(key))
+ goto err;
+ strcpy(key, colon + 1);
+ walker = ep;
+ }
+ if (verbose > 1)
+ printf("Found type %s for name %s\n", type, key);
+ /* Skip pointer place holders */
+ if (strcmp(type, "P") == 0) {
+ off += sizeof(void *);
+ continue;
+ }
+
+ /*
+ * Add a node of the appropriate type
+ */
+ elt = malloc(sizeof(struct pnp_elt) + strlen(key) + 1);
+ TAILQ_INSERT_TAIL(list, elt, next);
+ elt->pe_key = (char *)(elt + 1);
+ elt->pe_offset = off;
+ if (strcmp(type, "U8") == 0)
+ elt->pe_kind = TYPE_U8;
+ else if (strcmp(type, "V8") == 0)
+ elt->pe_kind = TYPE_V8;
+ else if (strcmp(type, "G16") == 0)
+ elt->pe_kind = TYPE_G16;
+ else if (strcmp(type, "L16") == 0)
+ elt->pe_kind = TYPE_L16;
+ else if (strcmp(type, "M16") == 0)
+ elt->pe_kind = TYPE_M16;
+ else if (strcmp(type, "U16") == 0)
+ elt->pe_kind = TYPE_U16;
+ else if (strcmp(type, "V16") == 0)
+ elt->pe_kind = TYPE_V16;
+ else if (strcmp(type, "U32") == 0)
+ elt->pe_kind = TYPE_U32;
+ else if (strcmp(type, "V32") == 0)
+ elt->pe_kind = TYPE_V32;
+ else if (strcmp(type, "W32") == 0)
+ elt->pe_kind = TYPE_W32;
+ else if (strcmp(type, "D") == 0) /* description char * */
+ elt->pe_kind = TYPE_D;
+ else if (strcmp(type, "Z") == 0) /* char * to match */
+ elt->pe_kind = TYPE_Z;
+ else if (strcmp(type, "P") == 0) /* Pointer -- ignored */
+ elt->pe_kind = TYPE_P;
+ else if (strcmp(type, "E") == 0) /* EISA PNP ID, as uint32_t */
+ elt->pe_kind = TYPE_E;
+ else if (strcmp(type, "T") == 0)
+ elt->pe_kind = TYPE_T;
+ else
+ goto err;
+ /*
+ * Maybe the rounding here needs to be more nuanced and/or somehow
+ * architecture specific. Fortunately, most tables in the system
+ * have sane ordering of types.
+ */
+ if (elt->pe_kind & TYPE_INT) {
+ elt->pe_offset = roundup2(elt->pe_offset, elt->pe_kind & TYPE_SZ_MASK);
+ off = elt->pe_offset + (elt->pe_kind & TYPE_SZ_MASK);
+ } else if (elt->pe_kind == TYPE_E) {
+ /* Type E stored as Int, displays as string */
+ elt->pe_offset = roundup2(elt->pe_offset, sizeof(uint32_t));
+ off = elt->pe_offset + sizeof(uint32_t);
+ } else if (elt->pe_kind == TYPE_T) {
+ /* doesn't actually consume space in the table */
+ off = elt->pe_offset;
+ } else {
+ elt->pe_offset = roundup2(elt->pe_offset, sizeof(void *));
+ off = elt->pe_offset + sizeof(void *);
+ }
+ if (elt->pe_kind & TYPE_PAIRED) {
+ char *word, *ctx;
+
+ for (word = strtok_r(key, "/", &ctx);
+ word; word = strtok_r(NULL, "/", &ctx)) {
+ sprintf(nd, "%c:%s;", elt->pe_kind & TYPE_FLAGGED ? 'J' : 'I',
+ word);
+ nd += strlen(nd);
+ }
+
+ }
+ else {
+ if (elt->pe_kind & TYPE_FLAGGED)
+ *nd++ = 'J';
+ else if (elt->pe_kind & TYPE_GE)
+ *nd++ = 'G';
+ else if (elt->pe_kind & TYPE_LE)
+ *nd++ = 'L';
+ else if (elt->pe_kind & TYPE_MASK)
+ *nd++ = 'M';
+ else if (elt->pe_kind & TYPE_INT)
+ *nd++ = 'I';
+ else if (elt->pe_kind == TYPE_D)
+ *nd++ = 'D';
+ else if (elt->pe_kind == TYPE_Z || elt->pe_kind == TYPE_E)
+ *nd++ = 'Z';
+ else if (elt->pe_kind == TYPE_T)
+ *nd++ = 'T';
+ else
+ errx(1, "Impossible type %x\n", elt->pe_kind);
+ *nd++ = ':';
+ strcpy(nd, key);
+ nd += strlen(nd);
+ *nd++ = ';';
+ }
+ }
+ *nd++ = '\0';
+ return 0;
+err:
+ errx(1, "Parse error of description string %s", desc);
+}
+
static int
parse_entry(struct mod_metadata *md, const char *cval,
struct elf_file *ef, const char *kldname)
{
struct mod_depend mdp;
struct mod_version mdv;
+ struct mod_pnp_match_info pnp;
+ char descr[1024];
Elf_Off data = (Elf_Off)md->md_data;
- int error = 0;
+ int error = 0, i, len;
+ char *walker;
+ void *table;
record_start();
switch (md->md_type) {
@@ -173,9 +404,119 @@ parse_entry(struct mod_metadata *md, const char *cval,
}
break;
case MDT_PNP_INFO:
+ check(EF_SEG_READ_REL(ef, data, sizeof(pnp), &pnp));
+ check(EF_SEG_READ(ef, (Elf_Off)pnp.descr, sizeof(descr), descr));
+ descr[sizeof(descr) - 1] = '\0';
if (dflag) {
- printf(" pnp info for bus %s\n", cval);
+ printf(" pnp info for bus %s format %s %d entries of %d bytes\n",
+ cval, descr, pnp.num_entry, pnp.entry_len);
+ } else {
+ pnp_list list;
+ struct pnp_elt *elt, *elt_tmp;
+ char *new_descr;
+
+ if (verbose > 1)
+ printf(" pnp info for bus %s format %s %d entries of %d bytes\n",
+ cval, descr, pnp.num_entry, pnp.entry_len);
+ /*
+ * Parse descr to weed out the chaff and to create a list
+ * of offsets to output.
+ */
+ TAILQ_INIT(&list);
+ parse_pnp_list(descr, &new_descr, &list);
+ record_int(MDT_PNP_INFO);
+ record_string(cval);
+ record_string(new_descr);
+ record_int(pnp.num_entry);
+ len = pnp.num_entry * pnp.entry_len;
+ walker = table = malloc(len);
+ check(EF_SEG_READ_REL(ef, (Elf_Off)pnp.table, len, table));
+
+ /*
+ * Walk the list and output things. We've collapsed all the
+ * variant forms of the table down to just ints and strings.
+ */
+ for (i = 0; i < pnp.num_entry; i++) {
+ TAILQ_FOREACH(elt, &list, next) {
+ uint8_t v1;
+ uint16_t v2;
+ uint32_t v4;
+ int value;
+ char buffer[1024];
+
+ if (elt->pe_kind == TYPE_W32) {
+ memcpy(&v4, walker + elt->pe_offset, sizeof(v4));
+ value = v4 & 0xffff;
+ record_int(value);
+ if (verbose > 1)
+ printf("W32:%#x", value);
+ value = (v4 >> 16) & 0xffff;
+ record_int(value);
+ if (verbose > 1)
+ printf(":%#x;", value);
+ } else if (elt->pe_kind & TYPE_INT) {
+ switch (elt->pe_kind & TYPE_SZ_MASK) {
+ case 1:
+ memcpy(&v1, walker + elt->pe_offset, sizeof(v1));
+ if ((elt->pe_kind & TYPE_FLAGGED) && v1 == 0xff)
+ value = -1;
+ else
+ value = v1;
+ break;
+ case 2:
+ memcpy(&v2, walker + elt->pe_offset, sizeof(v2));
+ if ((elt->pe_kind & TYPE_FLAGGED) && v2 == 0xffff)
+ value = -1;
+ else
+ value = v2;
+ break;
+ case 4:
+ memcpy(&v4, walker + elt->pe_offset, sizeof(v4));
+ if ((elt->pe_kind & TYPE_FLAGGED) && v4 == 0xffffffff)
+ value = -1;
+ else
+ value = v4;
+ break;
+ default:
+ errx(1, "Invalid size somehow %#x", elt->pe_kind);
+ }
+ if (verbose > 1)
+ printf("I:%#x;", value);
+ record_int(value);
+ } else if (elt->pe_kind == TYPE_T) {
+ /* Do nothing */
+ } else { /* E, Z or D -- P already filtered */
+ if (elt->pe_kind == TYPE_E) {
+ memcpy(&v4, walker + elt->pe_offset, sizeof(v4));
+ strcpy(buffer, pnp_eisaformat(v4));
+ } else {
+ char *ptr;
+
+ ptr = *(char **)(walker + elt->pe_offset);
+ buffer[0] = '\0';
+ if (ptr != 0) {
+ EF_SEG_READ(ef, (Elf_Off)ptr,
+ sizeof(buffer), buffer);
+ buffer[sizeof(buffer) - 1] = '\0';
+ }
+ }
+ if (verbose > 1)
+ printf("%c:%s;", elt->pe_kind == TYPE_E ? 'E' : (elt->pe_kind == TYPE_Z ? 'Z' : 'D'), buffer);
+ record_string(buffer);
+ }
+ }
+ if (verbose > 1)
+ printf("\n");
+ walker += pnp.entry_len;
+ }
+ /* Now free it */
+ TAILQ_FOREACH_SAFE(elt, &list, next, elt_tmp) {
+ TAILQ_REMOVE(&list, elt, next);
+ free(elt);
+ }
+ free(table);
}
+ break;
default:
warnx("unknown metadata record %d in file %s", md->md_type, kldname);
}
diff --git a/usr.sbin/sesutil/Makefile b/usr.sbin/sesutil/Makefile
index 347223d..bf37192 100644
--- a/usr.sbin/sesutil/Makefile
+++ b/usr.sbin/sesutil/Makefile
@@ -4,4 +4,6 @@ PROG= sesutil
SRCS= sesutil.c eltsub.c
MAN= sesutil.8
+LIBADD= sbuf
+
.include <bsd.prog.mk>
diff --git a/usr.sbin/sesutil/eltsub.c b/usr.sbin/sesutil/eltsub.c
index dae02fe..287530d 100644
--- a/usr.sbin/sesutil/eltsub.c
+++ b/usr.sbin/sesutil/eltsub.c
@@ -32,6 +32,11 @@
* mjacob@feral.com
*/
+#include <sys/endian.h>
+#include <sys/types.h>
+#include <sys/sbuf.h>
+
+#include <err.h>
#include <unistd.h>
#include <stddef.h>
#include <stdint.h>
@@ -43,6 +48,13 @@
#include "eltsub.h"
+/*
+ * offset by +20 degrees.
+ * The range of the value expresses a temperature between -19 and +235 degrees
+ * Celsius. A value of 00h is reserved.
+ */
+#define TEMPERATURE_OFFSET 20
+
char *
geteltnm(int type)
{
@@ -134,7 +146,7 @@ geteltnm(int type)
return (rbuf);
}
-static char *
+char *
scode2ascii(u_char code)
{
static char rbuf[32];
@@ -173,22 +185,51 @@ scode2ascii(u_char code)
return (rbuf);
}
-
-char *
-stat2ascii(int eletype, u_char *cstat)
+struct sbuf *
+stat2sbuf(int eletype, u_char *cstat)
{
- static char ebuf[256], *scode;
+ struct sbuf *buf;
+
+ buf = sbuf_new_auto();
+ if (buf == NULL)
+ err(EXIT_FAILURE, "sbuf_new_auto()");
- scode = scode2ascii(cstat[0]);
- sprintf(ebuf, "%s%s%s%s%s%s (0x%02x 0x%02x 0x%02x 0x%02x)",
- scode,
- (cstat[0] & 0x40) ? ", Prd.Fail" : "",
- (cstat[0] & 0x20) ? ", Disabled" : "",
- (cstat[0] & 0x10) ? ", Swapped" : "",
- (eletype == ELMTYP_DEVICE && (cstat[2] & 0x02)) ?
- ", LED=Locate" : "",
- (eletype == ELMTYP_DEVICE && (cstat[3] & 0x20)) ?
- ", LED=Fault" : "",
- cstat[0], cstat[1], cstat[2], cstat[3]);
- return (ebuf);
+ if (cstat[0] & 0x40)
+ sbuf_printf(buf, "\t\t- Predicted Failure\n");
+ if (cstat[0] & 0x20)
+ sbuf_printf(buf, "\t\t- Disabled\n");
+ if (cstat[0] & 0x10)
+ sbuf_printf(buf, "\t\t- Swapped\n");
+ switch (eletype) {
+ case ELMTYP_DEVICE:
+ if (cstat[2] & 0x02)
+ sbuf_printf(buf, "\t\t- LED=locate\n");
+ if (cstat[2] & 0x20)
+ sbuf_printf(buf, "\t\t- LED=fault\n");
+ break;
+ case ELMTYP_ARRAY_DEV:
+ if (cstat[2] & 0x02)
+ sbuf_printf(buf, "\t\t- LED=locate\n");
+ if (cstat[2] & 0x20)
+ sbuf_printf(buf, "\t\t- LED=fault\n");
+ break;
+ case ELMTYP_FAN:
+ sbuf_printf(buf, "\t\t- Speed: %d rpm\n",
+ (((0x7 & cstat[1]) << 8) + cstat[2]) * 10);
+ break;
+ case ELMTYP_THERM:
+ if (cstat[2]) {
+ sbuf_printf(buf, "\t\t- Temperature: %d C\n",
+ cstat[2] - TEMPERATURE_OFFSET);
+ } else {
+ sbuf_printf(buf, "\t\t- Temperature: -reserved-\n");
+ }
+ break;
+ case ELMTYP_VOM:
+ sbuf_printf(buf, "\t\t- Voltage: %.2f V\n",
+ be16dec(cstat + 2) / 100.0);
+ break;
+ }
+ sbuf_finish(buf);
+ return (buf);
}
diff --git a/usr.sbin/sesutil/eltsub.h b/usr.sbin/sesutil/eltsub.h
index 3d98572..299ada3 100644
--- a/usr.sbin/sesutil/eltsub.h
+++ b/usr.sbin/sesutil/eltsub.h
@@ -32,5 +32,6 @@
* mjacob@feral.com
*/
-char * geteltnm(int);
-char * stat2ascii(int, u_char *);
+char *geteltnm(int);
+char *scode2ascii(u_char);
+struct sbuf *stat2sbuf(int, u_char *);
diff --git a/usr.sbin/sesutil/sesutil.c b/usr.sbin/sesutil/sesutil.c
index 7ce9045..5c96070 100644
--- a/usr.sbin/sesutil/sesutil.c
+++ b/usr.sbin/sesutil/sesutil.c
@@ -31,6 +31,8 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/sbuf.h>
#include <err.h>
#include <errno.h>
@@ -170,7 +172,7 @@ sesled(int argc, char **argv, bool setfault)
sesid = strtoul(disk, &endptr, 10);
if (*endptr == '\0') {
endptr = strrchr(uflag, '*');
- if (*endptr == '*') {
+ if (endptr != NULL && *endptr == '*') {
warnx("Must specifying a SES device (-u) to use a SES "
"id# to identify a disk");
usage(stderr, (setfault ? "fault" : "locate"));
@@ -299,6 +301,7 @@ fault(int argc, char **argv)
static int
objmap(int argc, char **argv __unused)
{
+ struct sbuf *extra;
encioc_elm_devnames_t e_devname;
encioc_elm_status_t e_status;
encioc_elm_desc_t e_desc;
@@ -391,8 +394,10 @@ objmap(int argc, char **argv __unused)
}
printf("\tElement %u, Type: %s\n", e_ptr[j].elm_idx,
geteltnm(e_ptr[j].elm_type));
- printf("\t\tStatus: %s\n",
- stat2ascii(e_ptr[i].elm_type, e_status.cstat));
+ printf("\t\tStatus: %s (0x%02x 0x%02x 0x%02x 0x%02x)\n",
+ scode2ascii(e_status.cstat[0]), e_status.cstat[0],
+ e_status.cstat[1], e_status.cstat[2],
+ e_status.cstat[3]);
if (e_desc.elm_desc_len > 0) {
printf("\t\tDescription: %s\n",
e_desc.elm_desc_str);
@@ -401,6 +406,12 @@ objmap(int argc, char **argv __unused)
printf("\t\tDevice Names: %s\n",
e_devname.elm_devnames);
}
+ extra = stat2sbuf(e_ptr[j].elm_type, e_status.cstat);
+ if (sbuf_len(extra) > 0) {
+ printf("\t\tExtra status:\n%s",
+ sbuf_data(extra));
+ }
+ sbuf_delete(extra);
free(e_devname.elm_devnames);
}
close(fd);
OpenPOWER on IntegriCloud