diff options
author | ngie <ngie@FreeBSD.org> | 2015-12-14 00:12:53 +0000 |
---|---|---|
committer | ngie <ngie@FreeBSD.org> | 2015-12-14 00:12:53 +0000 |
commit | 17ca717571c27f52897c406a71864f864ca65710 (patch) | |
tree | c78986272e2ab4a955534ea9353928c9ce25caa3 | |
parent | c85e616e29482200cd0a47fa6c85165a98a4caaf (diff) | |
parent | a3c1f4b0eb9f220318c79476b1fcf38beadf35da (diff) | |
download | FreeBSD-src-17ca717571c27f52897c406a71864f864ca65710.zip FreeBSD-src-17ca717571c27f52897c406a71864f864ca65710.tar.gz |
MFhead @ r292177
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. + @@ -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 @@ -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); |