diff options
43 files changed, 985 insertions, 402 deletions
diff --git a/bin/sh/expand.c b/bin/sh/expand.c index c343977..dcef74e 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -665,6 +665,7 @@ evalvar(char *p, int flag) int special; int startloc; int varlen; + int varlenb; int easy; int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); @@ -712,8 +713,15 @@ again: /* jump here after setting a variable with ${var=text} */ if (special) { varvalue(var, varflags & VSQUOTE, subtype, flag); if (subtype == VSLENGTH) { - varlen = expdest - stackblock() - startloc; - STADJUST(-varlen, expdest); + varlenb = expdest - stackblock() - startloc; + varlen = varlenb; + if (localeisutf8) { + val = stackblock() + startloc; + for (;val != expdest; val++) + if ((*val & 0xC0) == 0x80) + varlen--; + } + STADJUST(-varlenb, expdest); } } else { char const *syntax = (varflags & VSQUOTE) ? DQSYNTAX @@ -721,7 +729,9 @@ again: /* jump here after setting a variable with ${var=text} */ if (subtype == VSLENGTH) { for (;*val; val++) - varlen++; + if (!localeisutf8 || + (*val & 0xC0) != 0x80) + varlen++; } else { if (quotes) diff --git a/bin/sh/main.c b/bin/sh/main.c index 12a7ff2..d3250eb 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$"); int rootpid; int rootshell; struct jmploc main_handler; +int localeisutf8; static void read_profile(const char *); static char *find_dot_file(char *); @@ -96,6 +97,7 @@ main(int argc, char *argv[]) char *shinit; (void) setlocale(LC_ALL, ""); + updatecharset(); state = 0; if (setjmp(main_handler.loc)) { switch (exception) { diff --git a/bin/sh/var.c b/bin/sh/var.c index e14027f..5c87a1f 100644 --- a/bin/sh/var.c +++ b/bin/sh/var.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); */ #include <locale.h> +#include <langinfo.h> #include "shell.h" #include "output.h" @@ -361,6 +362,7 @@ setvareq(char *s, int flags) if ((vp->flags & VEXPORT) && localevar(s)) { change_env(s, 1); (void) setlocale(LC_ALL, ""); + updatecharset(); } INTON; return; @@ -379,6 +381,7 @@ setvareq(char *s, int flags) if ((vp->flags & VEXPORT) && localevar(s)) { change_env(s, 1); (void) setlocale(LC_ALL, ""); + updatecharset(); } INTON; } @@ -480,6 +483,7 @@ bltinsetlocale(void) if (loc != NULL) { setlocale(LC_ALL, loc); INTON; + updatecharset(); return; } locdef = bltinlookup("LANG", 0); @@ -491,6 +495,7 @@ bltinsetlocale(void) setlocale(locale_categories[i], loc); } INTON; + updatecharset(); } /* @@ -505,12 +510,24 @@ bltinunsetlocale(void) for (lp = cmdenviron ; lp ; lp = lp->next) { if (localevar(lp->text)) { setlocale(LC_ALL, ""); + updatecharset(); return; } } INTON; } +/* + * Update the localeisutf8 flag. + */ +void +updatecharset(void) +{ + char *charset; + + charset = nl_langinfo(CODESET); + localeisutf8 = !strcmp(charset, "UTF-8"); +} /* * Generate a list of exported variables. This routine is used to construct @@ -656,6 +673,7 @@ exportcmd(int argc, char **argv) if ((vp->flags & VEXPORT) && localevar(vp->text)) { change_env(vp->text, 1); (void) setlocale(LC_ALL, ""); + updatecharset(); } goto found; } @@ -850,6 +868,7 @@ unsetvar(const char *s) if ((vp->flags & VEXPORT) && localevar(vp->text)) { change_env(s, 0); setlocale(LC_ALL, ""); + updatecharset(); } vp->flags &= ~VEXPORT; vp->flags |= VUNSET; diff --git a/bin/sh/var.h b/bin/sh/var.h index 775db41..4336562 100644 --- a/bin/sh/var.h +++ b/bin/sh/var.h @@ -81,6 +81,8 @@ extern struct var vhistsize; extern struct var vterm; #endif +extern int localeisutf8; + /* * The following macros access the values of the above variables. * They have to skip over the name. They return the null string @@ -112,6 +114,7 @@ char *lookupvar(const char *); char *bltinlookup(const char *, int); void bltinsetlocale(void); void bltinunsetlocale(void); +void updatecharset(void); char **environment(void); int showvarscmd(int, char **); int exportcmd(int, char **); diff --git a/lib/libdwarf/Makefile b/lib/libdwarf/Makefile index 1375a92..aa182e7 100644 --- a/lib/libdwarf/Makefile +++ b/lib/libdwarf/Makefile @@ -14,6 +14,7 @@ SRCS= \ dwarf_errno.c \ dwarf_finish.c \ dwarf_form.c \ + dwarf_func.c \ dwarf_init.c \ dwarf_loc.c diff --git a/lib/libdwarf/_libdwarf.h b/lib/libdwarf/_libdwarf.h index 697b034..828250e 100644 --- a/lib/libdwarf/_libdwarf.h +++ b/lib/libdwarf/_libdwarf.h @@ -163,6 +163,37 @@ struct _Dwarf_Debug { dbg_cu; /* List of compilation units. */ Dwarf_CU dbg_cu_current; /* Ptr to the current compilation unit. */ + + STAILQ_HEAD(, _Dwarf_Func) dbg_func; /* List of functions */ +}; + +struct _Dwarf_Func { + Dwarf_Die func_die; + const char *func_name; + Dwarf_Addr func_low_pc; + Dwarf_Addr func_high_pc; + int func_is_inlined; + /* inlined instance */ + STAILQ_HEAD(, _Dwarf_Inlined_Func) func_inlined_instances; + STAILQ_ENTRY(_Dwarf_Func) func_next; }; +struct _Dwarf_Inlined_Func { + struct _Dwarf_Func *ifunc_origin; + Dwarf_Die ifunc_abstract; + Dwarf_Die ifunc_concrete; + Dwarf_Addr ifunc_low_pc; + Dwarf_Addr ifunc_high_pc; + STAILQ_ENTRY(_Dwarf_Inlined_Func) ifunc_next; +}; + +void dwarf_build_function_table(Dwarf_Debug dbg); + +#ifdef DWARF_DEBUG +#include <assert.h> +#define DWARF_ASSERT(x) assert(x) +#else +#define DWARF_ASSERT(x) +#endif + #endif /* !__LIBDWARF_H_ */ diff --git a/lib/libdwarf/dwarf_func.c b/lib/libdwarf/dwarf_func.c new file mode 100644 index 0000000..b00d858 --- /dev/null +++ b/lib/libdwarf/dwarf_func.c @@ -0,0 +1,227 @@ +/*- + * Copyright (c) 2008-2009, 2011, Juniper Networks, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * JNPR: dwarf_func.c 336441 2009-10-17 09:19:54Z deo + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdlib.h> +#include <string.h> +#include <libdwarf.h> +#include <_libdwarf.h> + +static void +dwarf_add_function(Dwarf_Debug dbg, Dwarf_Func func) +{ + + STAILQ_INSERT_TAIL(&dbg->dbg_func, func, func_next); +} + +int +dwarf_function_get_addr_range(Dwarf_Func f, Dwarf_Addr *low_pc, + Dwarf_Addr *high_pc) +{ + + *low_pc = f->func_low_pc; + *high_pc = f->func_high_pc; + return 0; +} + +int +dwarf_inlined_function_get_addr_range(Dwarf_Inlined_Func f, Dwarf_Addr *low_pc, + Dwarf_Addr *high_pc) +{ + + *low_pc = f->ifunc_low_pc; + *high_pc = f->ifunc_high_pc; + return 0; +} + +int +dwarf_function_is_inlined(Dwarf_Func f) +{ + + if (f->func_is_inlined == DW_INL_inlined || + f->func_is_inlined == DW_INL_declared_inlined) + return 1; + else + return 0; +} + +Dwarf_Func +dwarf_find_function_by_name(Dwarf_Debug dbg, const char *name) +{ + /* XXX: replace with a fast version */ + + Dwarf_Func func; + STAILQ_FOREACH(func, &dbg->dbg_func, func_next) { + if (strcmp(name, func->func_name) == 0) + return func; + } + return NULL; +} + +Dwarf_Func +dwarf_find_function_by_offset(Dwarf_Debug dbg, Dwarf_Off off) +{ + + Dwarf_Func func; + Dwarf_Die die; + /* printf("look for %llx\n", off); */ + STAILQ_FOREACH(func, &dbg->dbg_func, func_next) { + die = func->func_die; + if ((off_t)die->die_offset == off) { + return func; + } + } + return NULL; +} + +void +dwarf_build_function_table(Dwarf_Debug dbg) +{ + Dwarf_CU cu; + Dwarf_AttrValue av; + Dwarf_Die die, origin_die; + Dwarf_Func func, origin_func; + Dwarf_Inlined_Func ifunc; + unsigned long long offset; + const char *name; + Dwarf_Error error; + + /* + * find out all the functions + */ + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + STAILQ_FOREACH(die, &cu->cu_die, die_next) { + if (die->die_a->a_tag == DW_TAG_subprogram) { + /* + * Some function has multiple entries, i.e. + * if a function is inlined, it has many + * abstract/concrete instances, the abstract + * instances are with DW_TAG_subprogram. + */ + dwarf_attrval_string(die, DW_AT_name, &name, + &error); + func = dwarf_find_function_by_name(dbg, name); + if (func == NULL) { + func = malloc( + sizeof(struct _Dwarf_Func)); + DWARF_ASSERT(func); + + func->func_die = die; + func->func_name = name; + STAILQ_INIT( + &func->func_inlined_instances); + + dwarf_add_function(dbg, func); + STAILQ_FOREACH(av, &die->die_attrval, + av_next) { + switch (av->av_attrib) { + case DW_AT_low_pc: + func->func_low_pc = + av->u[0].u64; + break; + case DW_AT_high_pc: + func->func_high_pc = + av->u[0].u64; + break; + case DW_AT_inline: + func->func_is_inlined = + av->u[0].u64; + break; + } + } + } + } + } + } + + /* + * Now check the concrete inlined instances. + */ + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + STAILQ_FOREACH(die, &cu->cu_die, die_next) { + if (die->die_a->a_tag == DW_TAG_inlined_subroutine) { + ifunc = malloc( + sizeof(struct _Dwarf_Inlined_Func)); + DWARF_ASSERT(ifunc); + STAILQ_FOREACH(av, &die->die_attrval, av_next) { + switch (av->av_attrib) { + case DW_AT_abstract_origin: + offset = av->u[0].u64 + + die->die_cu->cu_offset; + origin_die = dwarf_die_find( + die, offset); + DWARF_ASSERT(origin_die != 0); + + /* + * the abstract origin must + * have been merged with + * another die + */ + dwarf_attrval_string( + origin_die, DW_AT_name, + &name, &error); + origin_func = + dwarf_find_function_by_name + (dbg, name); + DWARF_ASSERT(origin_func != 0); + + STAILQ_INSERT_TAIL( + &origin_func-> + func_inlined_instances, + ifunc, ifunc_next); + + break; + case DW_AT_low_pc: + ifunc->ifunc_low_pc = + av->u[0].u64; + break; + case DW_AT_high_pc: + ifunc->ifunc_high_pc = + av->u[0].u64; + break; + } + } + } + } + } +} + +void +dwarf_function_iterate_inlined_instance(Dwarf_Func func, + Dwarf_Inlined_Callback f, void *data) +{ + Dwarf_Inlined_Func ifunc; + + if (!dwarf_function_is_inlined(func)) + return; + STAILQ_FOREACH(ifunc, &func->func_inlined_instances, ifunc_next) { + f(ifunc, data); + } +} diff --git a/lib/libdwarf/dwarf_init.c b/lib/libdwarf/dwarf_init.c index 30b7b0f..95642a0 100644 --- a/lib/libdwarf/dwarf_init.c +++ b/lib/libdwarf/dwarf_init.c @@ -578,6 +578,9 @@ dwarf_init_info(Dwarf_Debug dbg, Dwarf_Error *error) offset = next_offset; } + /* Build the function table. */ + dwarf_build_function_table(dbg); + return ret; } @@ -686,6 +689,7 @@ dwarf_elf_init(Elf *elf, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error) dbg->dbg_mode = mode; STAILQ_INIT(&dbg->dbg_cu); + STAILQ_INIT(&dbg->dbg_func); *ret_dbg = dbg; diff --git a/lib/libdwarf/libdwarf.h b/lib/libdwarf/libdwarf.h index 6d4930d..04192b7 100644 --- a/lib/libdwarf/libdwarf.h +++ b/lib/libdwarf/libdwarf.h @@ -51,6 +51,7 @@ typedef struct _Dwarf_Debug *Dwarf_Debug; typedef struct _Dwarf_Die *Dwarf_Die; typedef struct _Dwarf_Fde *Dwarf_Fde; typedef struct _Dwarf_Func *Dwarf_Func; +typedef struct _Dwarf_Inlined_Func *Dwarf_Inlined_Func; typedef struct _Dwarf_Global *Dwarf_Global; typedef struct _Dwarf_Line *Dwarf_Line; typedef struct _Dwarf_Type *Dwarf_Type; @@ -71,6 +72,9 @@ typedef struct { Dwarf_Loc *ld_s; } Dwarf_Locdesc; +/* receiver function for dwarf_function_iterate_inlined_instance() API */ +typedef void (*Dwarf_Inlined_Callback)(Dwarf_Inlined_Func, void *); + /* * Error numbers which are specific to this implementation. */ @@ -157,6 +161,16 @@ void dwarf_dump_strtab(Dwarf_Debug); void dwarf_dump_symtab(Dwarf_Debug); void dwarf_dump_raw(Dwarf_Debug); void dwarf_dump_tree(Dwarf_Debug); +Dwarf_Func dwarf_find_function_by_offset(Dwarf_Debug dbg, Dwarf_Off off); +Dwarf_Func dwarf_find_function_by_name(Dwarf_Debug dbg, const char *name); +int dwarf_function_get_addr_range(Dwarf_Func f, + Dwarf_Addr *low_pc, Dwarf_Addr *high_pc); +int dwarf_function_is_inlined(Dwarf_Func f); +void dwarf_function_iterate_inlined_instance(Dwarf_Func func, + Dwarf_Inlined_Callback f, void *data); +int dwarf_inlined_function_get_addr_range(Dwarf_Inlined_Func f, + Dwarf_Addr *low_pc, Dwarf_Addr *high_pc); + __END_DECLS #endif /* !_LIBDWARF_H_ */ diff --git a/lib/libelf/Makefile b/lib/libelf/Makefile index fc70d9d..fe921cb 100644 --- a/lib/libelf/Makefile +++ b/lib/libelf/Makefile @@ -57,7 +57,7 @@ INCS= libelf.h gelf.h GENSRCS= libelf_fsize.c libelf_msize.c libelf_convert.c CLEANFILES= ${GENSRCS} -CFLAGS+= -I. -I${.CURDIR} +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../../sys SHLIB_MAJOR= 1 diff --git a/lib/libelf/elf_data.c b/lib/libelf/elf_data.c index b8c10de..c34c4ad 100644 --- a/lib/libelf/elf_data.c +++ b/lib/libelf/elf_data.c @@ -225,7 +225,8 @@ elf_rawdata(Elf_Scn *s, Elf_Data *d) if ((d = _libelf_allocate_data(s)) == NULL) return (NULL); - d->d_buf = sh_type == SHT_NOBITS ? NULL : e->e_rawfile + sh_offset; + d->d_buf = (sh_type == SHT_NOBITS || sh_size == 0) ? NULL : + e->e_rawfile + sh_offset; d->d_off = 0; d->d_align = sh_align; d->d_size = sh_size; diff --git a/lib/libelf/elf_getdata.3 b/lib/libelf/elf_getdata.3 index 6a5ef39..59e0ef6 100644 --- a/lib/libelf/elf_getdata.3 +++ b/lib/libelf/elf_getdata.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2006,2008,2010 Joseph Koshy. All rights reserved. +.\" Copyright (c) 2006,2008,2010-2011 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 30, 2010 +.Dd January 26, 2011 .Dt ELF_GETDATA 3 .Os .Sh NAME @@ -142,9 +142,10 @@ always returns .Vt Elf_Data structures of type .Dv ELF_T_BYTE . -.Ss Special handling of SHT_NOBITS sections +.Ss Special handling of zero-sized and SHT_NOBITS sections For sections of type -.Dv SHT_NOBITS , +.Dv SHT_NOBITS, +and for zero-sized sections, the functions .Fn elf_getdata and diff --git a/lib/libelf/libelf_data.c b/lib/libelf/libelf_data.c index 67388b6..ee2d57a 100644 --- a/lib/libelf/libelf_data.c +++ b/lib/libelf/libelf_data.c @@ -84,6 +84,8 @@ _libelf_xlate_shtype(uint32_t sht) case SHT_SUNW_dof: return (ELF_T_BYTE); #endif + case SHT_MIPS_DWARF: + /* FALLTHROUGH */ case SHT_AMD64_UNWIND: /* == SHT_IA_64_UNWIND */ return (ELF_T_BYTE); default: diff --git a/share/man/man5/ar.5 b/share/man/man5/ar.5 index dc802ce..81bc7e6 100644 --- a/share/man/man5/ar.5 +++ b/share/man/man5/ar.5 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2007 Joseph Koshy. All rights reserved. +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -9,226 +9,319 @@ .\" 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" 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$ .\" -.Dd September 7, 2007 -.Dt AR 5 +.Dd November 28, 2010 .Os +.Dt AR 5 .Sh NAME .Nm ar -.Nd format of archives managed by ar(1) and ranlib(1) +.Nd archive file format for +.Xr ar 1 +and +.Xr ranlib 1 .Sh SYNOPSIS .In ar.h .Sh DESCRIPTION -An archive managed by the +.Xr ar 1 +archives are created and managed by the .Xr ar 1 and .Xr ranlib 1 -utilities is a single file that stores the individual members of the -archive along with metadata for each member. -There are two major variants of the +utilities. +These archives are typically used during program development to +hold libraries of program objects. +An .Xr ar 1 -archive format, the BSD variant and the SVR4/GNU variant. -Both variants are described by this manual page. +archive is contained in a single operating system file. .Pp -The header file -.In ar.h -defines constants and structures used to describe the layout -of these archives. -.Ss Archive Layout +This manual page documents two variants of the .Xr ar 1 -archives start with a string of magic bytes -.Qq !<arch>\en -(constant -.Dv ARMAG -in header -.In ar.h ) . -The content of the archive follows the magic bytes. -Each member stored in the archive is preceded by a fixed size -archive header that stores file permissions, last modification -time, the owner, and the group of the archived file. -.Pp -Archive headers start at an even byte offset in the archive -file. -If the length of the preceding archive member was odd, then an extra -newline character -.Dq "\en" -is used as padding. -.Pp -The archive header comprises six fixed-size ASCII strings followed -by a two character trailer (see -.Vt "struct ar_hdr" -in header file -.In ar.h Ns ): -.Bd -literal -struct ar_hdr { - char ar_name[16]; /* name */ - char ar_date[12]; /* modification time */ - char ar_uid[6]; /* user id */ - char ar_gid[6]; /* group id */ - char ar_mode[8]; /* octal file permissions */ - char ar_size[10]; /* size in bytes */ - char ar_fmag[2]; /* consistency check */ -}; -.Ed -.Pp -Unused characters in the header are filled with space (ASCII 20H) -characters. -Each field of the header abuts the next without additional padding. -.Pp -The members of the archive header are as follows: -.Bl -tag -width "Va ar_name" -compact -.It Va ar_date -This field holds the decimal representation of the -modification time, in seconds since the epoch, of the archive -member. -.It Va ar_fmag -This trailer field holds the two characters -.Qq `\en -(constant -.Dv ARFMAG -defined in header file -.In ar.h Ns ), -and is used for consistency checks. -.It Va ar_gid -This field holds the decimal representation of the numeric -user id of the creator of the member. -.It Va ar_mode -This field holds octal representation of the file permissions -for the member. -.It Va ar_name -This field holds the name of an archive member. -The usage of this field depends on the format variant: -.Bl -tag -width "SVR4/GNU" -compact -.It BSD -In the BSD variant, names that are shorter than 16 characters and -without embedded spaces are stored directly in this field. -If a name has an embedded space, or if it is longer than 16 -characters, then the string -.Qq "#1/" -followed by the decimal representation of the length of the file name -is placed in this field. -The actual file name is stored immediately after the archive header. -The content of the archive member follows the file name. +archive format: the BSD archive format, and the SVR4/GNU archive +format. +.Pp +In both variants the archive file starts with an identifying byte +sequence of the seven ASCII characters +.Sq Li "!<arch>" +followed by a ASCII linefeed character +.Po +see the constant +.Dq ARMAG +in the header file +.In ar.h +.Pc . +.Pp +Archive members follow the initial identifying byte sequence. +Each archive member is prefixed by a fixed size header describing the +file attributes associated with the member. +.Ss "Archive Headers" +An archive header describes the file attributes for the archive member that +follows it. The -.Va ar_size -field of the header (see below) will then hold the sum of the size of -the file name and the size of the member. -.It SVR4/GNU -In the SVR4/GNU variant, names up to 15 characters in length are -stored directly in this field, and are terminated by a -.Qq / -(ASCII 2FH) character. -Names larger than 15 characters in length are stored in a special -archive string table member (see -.Sx "Archive String Table" -below), and the -.Va ar_name -field holds the string -.Qq "/" -followed by the decimal representation of the offset in the archive -string table of the actual name. +.Xr ar 5 +format only supports a limited number of attributes: the file name, +the file creation time stamp, the uid and gid of the creator, the file +mode and the file size. +.Pp +Archive headers are placed at an even byte offset in the archive file. +If the data for an archive member ends at an odd byte offset, then a +padding byte with value 0x0A is used to position the next archive +header on an even byte offset. +.Pp +An archive header comprises the following fixed sized fields: +.Bl -tag -width "Li ar_name" +.It Ar ar_name +(16 bytes) The file name of the archive member. +The format of this field varies between the BSD and SVR4/GNU formats and +is described in more detail in the section +.Sx "Representing File Names" +below. +.It Ar ar_date +(12 bytes) The file modification time for the member in seconds since the +epoch, encoded as a decimal number. +.It Ar ar_uid +(6 bytes) The uid associated with the archive member, encoded as a +decimal number. +.It Ar ar_gid +(6 bytes) The gid associated with the archive member, encoded as a +decimal number. +.It Ar ar_mode +(8 bytes) The file mode for the archive member, encoded as an octal +number. +.It Ar ar_size +(10 bytes) In the SVR4/GNU archive format this field holds the size in +bytes of the archive member, encoded as a decimal number. +In the BSD archive format, for short file names, this field +holds the size in bytes of the archive member, encoded as a decimal +number. +For long file names +.Po +see +.Sx "Representing File Names" +below +.Pc , +the field contains the combined size of the +archive member and its file name, encoded as a decimal number. +.It Ar ar_fmag +(2 bytes) This field holds 2 bytes with values 0x96 and 0x0A +respectively, marking the end of the header. +.El +.Pp +Unused bytes in the fields of an archive header are set to the value +0x20. +.Ss "Representing File Names" +The BSD and SVR4/GNU variants use different schemes for encoding file +names for members. +.Bl -tag -width "SVR4/GNU" +.It "BSD" +File names that are upto 16 bytes long and which do not contain +embedded spaces are stored directly in the +.Ar ar_name +field of the archive header. +File names that are either longer than 16 bytes or which contain +embedded spaces are stored immediately after the archive header +and the +.Ar ar_name +field of the archive header is set to the string +.Dq "#1/" +followed by a decimal representation of the number of bytes needed for +the file name. +In addition, the +.Ar ar_size +field of the archive header is set to the decimal representation of +the combined sizes of the archive member and the file name. +The file contents of the member follows the file name without further +padding. +.Pp +As an example, if the file name for a member was +.Dq "A B" +and its contents was the string +.Dq "C D" , +then the +.Ar ar_name +field of the header would contain +.Dq Li "#1/3" , +the +.Ar ar_size +field of the header would contain +.Dq Li 6 , +and the bytes immediately following the header would be 0x41, 0x20, +0x42, 0x43, 0x20 and 0x44 +.Po +ASCII +.Dq "A BC D" +.Pc . +.It "SVR4/GNU" +File names that are upto 15 characters long are stored directly in the +.Ar ar_name +field of the header, terminated by a +.Dq Li / +character. +.Pp +If the file name is larger than would fit in space for the +.Ar ar_name +field, then the actual file name is kept in the archive +string table +.Po +see +.Sx "Archive String Tables" +below +.Pc , +and the decimal offset of the file name in the string table is stored +in the +.Ar ar_name +field, prefixed by a +.Dq Li / +character. +.Pp +As an example, if the real file name has been stored at offset 768 in +the archive string table, the +.Ar ar_name +field of the header will contain the string +.Dq /768 . .El -.It Va ar_size -In the SVR4/GNU variant, this field holds the decimal representation -of actual size in bytes of the archived file. -In the BSD variant, for member names that use the -.Va ar_name -field directly, this field holds the decimal representation of the -actual size in bytes of the archived member. -For member names that use the extension mechanism described above, the -field will hold the sum of the sizes, in bytes, of the filename and the -archive member. -.It Va ar_uid -This field holds the decimal representation of the numeric -group id of the creator of the member. +.Ss "Special Archive Members" +The following archive members are special. +.Bl -tag -width indent +.It Dq Li / +In the SVR4/GNU variant of the archive format, the archive member with +name +.Dq Li / +denotes an archive symbol table. +If present, this member will be the very first member in the +archive. +.It Dq Li // +In the SVR4/GNU variant of the archive format, the archive member with +name +.Dq Li // +denotes the archive string table. +This special member is used to hold filenames that do not fit in the +file name field of the header +.Po +see +.Sx "Representing File Names" +above +.Pc . +If present, this member immediately follows the archive symbol table +if an archive symbol table is present, or is the first member otherwise. +.It Dq Li "__.SYMDEF" +This special member contains the archive symbol table in the BSD +variant of the archive format. +If present, this member will be the very first member in the +archive. .El -.Ss Archive Symbol Table -An archive may additionally contain an archive symbol table -used by the link editor, -.Xr ld 1 . -This symbol table has the member name -.Qq __.SYMDEF -in the BSD variant of the archive format, and the name -.Qq / -in the SVR4/GNU variant. -.Pp -The format of the symbol table depends on the format variant: -.Bl -tag -width "SVR4/GNU" -compact +.Ss "Archive String Tables" +An archive string table is used in the SVR4/GNU archive format to hold +file names that are too large to fit into the constraints of the +.Ar ar_name +field of the archive header. +An archive string table contains a sequence of file names. +Each file name in the archive string table is terminated by the +byte sequence 0x2F, 0x0A +.Po +the ASCII string +.Dq "/\en" +.Pc . +No padding is used to separate adjacent file names. +.Ss "Archive Symbol Tables" +Archive symbol tables are used to speed up link editing by providing a +mapping between the program symbols defined in the archive +and the corresponding archive members. +Archive symbol tables are managed by the +.Xr ranlib 1 +utility. +.Pp +The format of archive symbol tables is as follows: +.Bl -tag -width "SVR4/GNU" .It BSD -In the BSD variant, the symbol table has 4 parts encoded in -a machine dependent manner: -.Bl -enum -compact -.It -The first part is a binary value containing size in bytes of the -second part encoded as a C -.Dq long . -.It -The second part is a list of -.Vt struct ranlib -structures (see -.In ranlib.h Ns ). -Each ranlib structure describes one symbol and comprises of -two C -.Dq long -values. -The first -.Dq long -is a zero-based offset into the string table in the fourth part -for the symbol's name. -The second -.Dq long -is an offset from the beginning of the archive to the start -of the archive header for the member that defines the symbol. -.It -The third part is a binary value denoting the length of the -string table contained in the fourth part. -.It -The fourth part is a string table containing NUL-terminated -strings. +In the BSD archive format, the archive symbol table comprises +of two parts: a part containing an array of +.Vt "struct ranlib" +descriptors, followed by a part containing a symbol string table. +The sizes and layout of the structures that make up a BSD format +archive symbol table are machine dependent. +.Pp +The part containing +.Vt "struct ranlib" +descriptors begins with a field containing the size in bytes of the +array of +.Vt "struct ranlib" +descriptors encoded as a C +.Vt long +value. +.Pp +The array of +.Vt "struct ranlib" +descriptors follows the size field. +Each +.Vt "struct ranlib" +descriptor describes one symbol. +.Pp +A +.Vt "struct ranlib" +descriptor comprises two fields: +.Bl -tag -width "Ar ran_strx" -compact +.It Ar ran_strx +.Pq C Vt long +This field contains the zero-based offset of the symbol name in the +symbol string table. +.It Ar ran_off +.Pq C Vt long +This field is the file offset to the archive header for the archive +member defining the symbol. .El +.Pp +The part containing the symbol string table begins with a field +containing the size in bytes of the string table, encoded as a C +.Vt long +value. +This string table follows the size field, and contains +NUL-terminated strings for the symbols in the symbol table. .It SVR4/GNU -In the SVR4/GNU variant, the symbol table comprises of three parts -which follow each other without padding: -.Bl -enum -compact -.It -The first part comprises of a count of entries in the symbol table, -stored a 4 byte binary value in MSB first order. -.It -The next part is an array of 4 byte file offsets within the archive -to archive header for members that define the symbol in question. -Each offset in stored in MSB first order. -.It -The third part is a string table, that contains NUL-terminated -strings for the symbols in the symbol table. -.El +In the SVR4/GNU archive format, the archive symbol table starts with a +4-byte binary value containing the number of entries contained in the +archive symbol table. +This count of entries is stored most significant byte first. +.Pp +Next, there are +.Ar count +4-byte numbers, each stored most significant byte first. +Each number is a binary offset to the archive header for the member in +the archive file for the corresponding symbol table entry. +.Pp +After the binary offset values, there are +.Ar count +NUL-terminated strings in sequence, holding the symbol names for +the corresponding symbol table entries. .El -.Ss Archive String Table -In the SVR4/GNU variant of the +.Sh STANDARDS COMPLIANCE +The +.Xr ar 1 +archive format is not currently specified by a standard. +.Pp +This manual page documents the .Xr ar 1 -archive format, long file names are stored in a separate -archive string table and referenced from the archive header -for each member. -Each file name is terminated by the string -.Qq /\en . -The string table itself has a name of -.Qq // . +archive formats used by the +.Bx 4.4 +and +.Ux SVR4 +operating system releases. .Sh SEE ALSO .Xr ar 1 , +.Xr ld 1 , .Xr ranlib 1 , -.Xr archive 3 , .Xr elf 3 , -.Xr gelf 3 , -.Xr elf 5 +.Xr elf_getarsym 3 , +.Xr elf_rand 3 diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c index a9370d9..de4bd9a 100644 --- a/sys/boot/common/interp.c +++ b/sys/boot/common/interp.c @@ -105,7 +105,7 @@ interact(void) /* * Read our default configuration */ - if(include("/boot/loader.rc")!=CMD_OK) + if (include("/boot/loader.rc") != CMD_OK) include("/boot/boot.conf"); printf("\n"); /* diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index 3d81800..c1951ff 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -2138,7 +2138,7 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td) ("trying to do CDIOREADTOCHEADER\n")); error = cdreadtoc(periph, 0, 0, (u_int8_t *)th, - sizeof (*th), /*sense_flags*/0); + sizeof (*th), /*sense_flags*/SF_NO_PRINT); if (error) { free(th, M_SCSICD); cam_periph_unlock(periph); diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c index 11d0ee8..2cc1e08 100644 --- a/sys/dev/ath/ath_hal/ah.c +++ b/sys/dev/ath/ath_hal/ah.c @@ -585,19 +585,49 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, return HAL_ENOTSUPP; case HAL_CAP_11D: return HAL_OK; - case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ - return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_HT: return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_GTXTO: + return pCap->halGTTSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_FAST_CC: + return pCap->halFastCCSupport ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_TX_CHAINMASK: /* mask of TX chains supported */ *result = pCap->halTxChainMask; return HAL_OK; case HAL_CAP_RX_CHAINMASK: /* mask of RX chains supported */ *result = pCap->halRxChainMask; return HAL_OK; + case HAL_CAP_NUM_GPIO_PINS: + *result = pCap->halNumGpioPins; + return HAL_OK; + case HAL_CAP_CST: + return pCap->halCSTSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_RTS_AGGR_LIMIT: + *result = pCap->halRtsAggrLimit; + return HAL_OK; + case HAL_CAP_4ADDR_AGGR: + return pCap->hal4AddrAggrSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_AUTO_SLEEP: + return pCap->halAutoSleepSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_MBSSID_AGGR_SUPPORT: + return pCap->halMbssidAggrSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_SPLIT_4KB_TRANS: /* hardware handles descriptors straddling 4k page boundary */ + return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_REG_FLAG: + *result = AH_PRIVATE(ah)->ah_currentRDext; + return HAL_OK; + case HAL_CAP_BT_COEX: + return pCap->halBtCoexSupport ? HAL_OK : HAL_ENOTSUPP; + case HAL_CAP_HT20_SGI: + return pCap->halHTSGI20Support ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_RXTSTAMP_PREC: /* rx desc tstamp precision (bits) */ *result = pCap->halTstampPrecision; return HAL_OK; + + /* FreeBSD-specific entries for now */ + case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ + return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_INTRMASK: /* mask of supported interrupts */ *result = pCap->halIntrMask; return HAL_OK; @@ -614,10 +644,6 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, default: return HAL_ENOTSUPP; } - case HAL_CAP_SPLIT_4KB_TRANS: /* hardware handles descriptors straddling 4k page boundary */ - return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP; - case HAL_CAP_HAS_PSPOLL: /* hardware has ps-poll support */ - return pCap->halHasPsPollSupport ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_RXDESC_SELFLINK: /* hardware supports self-linked final RX descriptors correctly */ return pCap->halHasRxSelfLinkedTail ? HAL_OK : HAL_ENOTSUPP; default: diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index e234efa..85790e1 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -109,21 +109,41 @@ typedef enum { HAL_CAP_TPC_ACK = 26, /* ack txpower with per-packet tpc */ HAL_CAP_TPC_CTS = 27, /* cts txpower with per-packet tpc */ HAL_CAP_11D = 28, /* 11d beacon support for changing cc */ - HAL_CAP_INTMIT = 29, /* interference mitigation */ - HAL_CAP_RXORN_FATAL = 30, /* HAL_INT_RXORN treated as fatal */ - HAL_CAP_HT = 31, /* hardware can support HT */ - HAL_CAP_TX_CHAINMASK = 32, /* mask of TX chains supported */ - HAL_CAP_RX_CHAINMASK = 33, /* mask of RX chains supported */ - HAL_CAP_RXTSTAMP_PREC = 34, /* rx desc tstamp precision (bits) */ - HAL_CAP_BB_HANG = 35, /* can baseband hang */ - HAL_CAP_MAC_HANG = 36, /* can MAC hang */ - HAL_CAP_INTRMASK = 37, /* bitmask of supported interrupts */ - HAL_CAP_BSSIDMATCH = 38, /* hardware has disable bssid match */ - HAL_CAP_STREAMS = 39, /* how many 802.11n spatial streams are available */ - HAL_CAP_SPLIT_4KB_TRANS = 40, /* hardware supports descriptors straddling a 4k page boundary */ - HAL_CAP_HAS_PSPOLL = 41, /* hardware has ps-poll support */ - HAL_CAP_RXDESC_SELFLINK = 42, /* support a self-linked tail RX descriptor */ - HAL_CAP_GTXTO = 43, /* hardware supports global tx timeout */ + + HAL_CAP_HT = 30, /* hardware can support HT */ + HAL_CAP_GTXTO = 31, /* hardware supports global tx timeout */ + HAL_CAP_FAST_CC = 32, /* hardware supports fast channel change */ + HAL_CAP_TX_CHAINMASK = 33, /* mask of TX chains supported */ + HAL_CAP_RX_CHAINMASK = 34, /* mask of RX chains supported */ + HAL_CAP_NUM_GPIO_PINS = 36, /* number of GPIO pins */ + + HAL_CAP_CST = 38, /* hardware supports carrier sense timeout */ + + HAL_CAP_RTS_AGGR_LIMIT = 42, /* aggregation limit with RTS */ + HAL_CAP_4ADDR_AGGR = 43, /* hardware is capable of 4addr aggregation */ + + HAL_CAP_AUTO_SLEEP = 48, /* hardware can go to network sleep + automatically after waking up to receive TIM */ + HAL_CAP_MBSSID_AGGR_SUPPORT = 49, /* Support for mBSSID Aggregation */ + HAL_CAP_SPLIT_4KB_TRANS = 50, /* hardware supports descriptors straddling a 4k page boundary */ + HAL_CAP_REG_FLAG = 51, /* Regulatory domain flags */ + + HAL_CAP_BT_COEX = 60, /* hardware is capable of bluetooth coexistence */ + + HAL_CAP_HT20_SGI = 96, /* hardware supports HT20 short GI */ + + HAL_CAP_RXTSTAMP_PREC = 100, /* rx desc tstamp precision (bits) */ + + /* The following are private to the FreeBSD HAL (224 onward) */ + + HAL_CAP_INTMIT = 229, /* interference mitigation */ + HAL_CAP_RXORN_FATAL = 230, /* HAL_INT_RXORN treated as fatal */ + HAL_CAP_BB_HANG = 235, /* can baseband hang */ + HAL_CAP_MAC_HANG = 236, /* can MAC hang */ + HAL_CAP_INTRMASK = 237, /* bitmask of supported interrupts */ + HAL_CAP_BSSIDMATCH = 238, /* hardware has disable bssid match */ + HAL_CAP_STREAMS = 239, /* how many 802.11n spatial streams are available */ + HAL_CAP_RXDESC_SELFLINK = 242, /* support a self-linked tail RX descriptor */ } HAL_CAPABILITY_TYPE; /* diff --git a/sys/dev/ath/ath_hal/ah_debug.h b/sys/dev/ath/ath_hal/ah_debug.h index f31eec0..14dfe38 100644 --- a/sys/dev/ath/ath_hal/ah_debug.h +++ b/sys/dev/ath/ath_hal/ah_debug.h @@ -45,6 +45,8 @@ enum { HAL_DEBUG_GPIO = 0x00040000, /* GPIO debugging */ HAL_DEBUG_INTERRUPT = 0x00080000, /* interrupt handling */ HAL_DEBUG_DIVERSITY = 0x00100000, /* diversity debugging */ + HAL_DEBUG_DFS = 0x00200000, /* DFS debugging */ + HAL_DEBUG_HANG = 0x00400000, /* BB/MAC hang debugging */ HAL_DEBUG_ANY = 0xffffffff }; diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index cefe28a..c4ffe74 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -184,6 +184,7 @@ typedef struct { halChanHalfRate : 1, halChanQuarterRate : 1, halHTSupport : 1, + halHTSGI20Support : 1, halRfSilentSupport : 1, halHwPhyCounterSupport : 1, halWowSupport : 1, @@ -197,13 +198,13 @@ typedef struct { halCSTSupport : 1, halRifsRxSupport : 1, halRifsTxSupport : 1, + hal4AddrAggrSupport : 1, halExtChanDfsSupport : 1, halForcePpmSupport : 1, halEnhancedPmSupport : 1, halMbssidAggrSupport : 1, halBssidMatchSupport : 1, hal4kbSplitTransSupport : 1, - halHasPsPollSupport : 1, halHasRxSelfLinkedTail : 1; uint32_t halWirelessModes; uint16_t halTotalQueues; @@ -298,6 +299,7 @@ struct ath_hal_private { * State for regulatory domain handling. */ HAL_REG_DOMAIN ah_currentRD; /* EEPROM regulatory domain */ + HAL_REG_DOMAIN ah_currentRDext; /* EEPROM extended regdomain flags */ HAL_CHANNEL_INTERNAL ah_channels[AH_MAXCHAN]; /* private chan state */ u_int ah_nchan; /* valid items in ah_channels */ const struct regDomain *ah_rd2GHz; /* reg state for 2G band */ diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c index 0ea3034..3a8f785 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_ani.c @@ -296,6 +296,12 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param) } OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]); + + /* Only set the ext channel cycpwr_thr1 field for ht/40 */ + if (IEEE80211_IS_CHAN_HT40(AH_PRIVATE(ah)->ah_curchan)) + OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, + AR_PHY_EXT_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]); + if (level > aniState->spurImmunityLevel) ahp->ah_stats.ast_ani_spurup++; else if (level < aniState->spurImmunityLevel) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c index 0e91e9f..9ef0984 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c @@ -371,6 +371,8 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc, /* Read Reg Domain */ AH_PRIVATE(ah)->ah_currentRD = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + AH_PRIVATE(ah)->ah_currentRDext = + ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL); /* * ah_miscMode is populated by ar5416FillCapabilityInfo() @@ -810,6 +812,7 @@ ar5416FillCapabilityInfo(struct ath_hal *ah) pCap->halBssIdMaskSupport = AH_TRUE; pCap->halMcastKeySrchSupport = AH_FALSE; pCap->halTsfAddSupport = AH_TRUE; + pCap->hal4AddrAggrSupport = AH_FALSE; /* Broken in Owl */ if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK) pCap->halTotalQueues = val; @@ -860,10 +863,12 @@ ar5416FillCapabilityInfo(struct ath_hal *ah) pCap->halTxStreams = 2; pCap->halRxStreams = 2; pCap->halRtsAggrLimit = 8*1024; /* Owl 2.0 limit */ - pCap->halMbssidAggrSupport = AH_TRUE; + pCap->halMbssidAggrSupport = AH_FALSE; /* Broken on Owl */ pCap->halForcePpmSupport = AH_TRUE; pCap->halEnhancedPmSupport = AH_TRUE; pCap->halBssidMatchSupport = AH_TRUE; + pCap->halGTTSupport = AH_TRUE; + pCap->halCSTSupport = AH_TRUE; if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) && ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) { diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c index 087bf92..3ed44c7 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c @@ -278,14 +278,12 @@ ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, uint32_t capability, uint32_t *result) { switch (type) { - case HAL_CAP_GTXTO: - return HAL_OK; /* All AR5416+ supports Global TX Timeout */ case HAL_CAP_BB_HANG: switch (capability) { case HAL_BB_HANG_RIFS: - return AR_SREV_SOWL(ah) ? HAL_OK : HAL_ENOTSUPP; + return (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP; case HAL_BB_HANG_DFS: - return AR_SREV_SOWL(ah) ? HAL_OK : HAL_ENOTSUPP; + return (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP; case HAL_BB_HANG_RX_CLEAR: return AR_SREV_MERLIN(ah) ? HAL_OK : HAL_ENOTSUPP; } @@ -293,7 +291,7 @@ ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, case HAL_CAP_MAC_HANG: return ((ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCI) || (ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCIE) || - AR_SREV_SOWL(ah)) ? + AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_DIVERSITY: /* disable classic fast diversity */ return HAL_ENXIO; @@ -466,12 +464,12 @@ ar5416DetectMacHang(struct ath_hal *ah) if (ar5416CompareDbgHang(ah, &mac_dbg, &hang_sig2)) return HAL_MAC_HANG_SIG2; - HALDEBUG(ah, HAL_DEBUG_ANY, "%s Found an unknown MAC hang signature " + HALDEBUG(ah, HAL_DEBUG_HANG, "%s Found an unknown MAC hang signature " "DMADBG_3=0x%x DMADBG_4=0x%x DMADBG_5=0x%x DMADBG_6=0x%x\n", __func__, mac_dbg.dma_dbg_3, mac_dbg.dma_dbg_4, mac_dbg.dma_dbg_5, mac_dbg.dma_dbg_6); - return HAL_MAC_HANG_UNKNOWN; + return 0; } /* @@ -515,16 +513,16 @@ ar5416DetectBBHang(struct ath_hal *ah) } for (i = 0; i < N(hang_list); i++) if ((hang_sig & hang_list[i].mask) == hang_list[i].val) { - HALDEBUG(ah, HAL_DEBUG_ANY, + HALDEBUG(ah, HAL_DEBUG_HANG, "%s BB hang, signature 0x%x, code 0x%x\n", __func__, hang_sig, hang_list[i].code); return hang_list[i].code; } - HALDEBUG(ah, HAL_DEBUG_ANY, "%s Found an unknown BB hang signature! " + HALDEBUG(ah, HAL_DEBUG_HANG, "%s Found an unknown BB hang signature! " "<0x806c>=0x%x\n", __func__, hang_sig); - return HAL_BB_HANG_UNKNOWN; + return 0; #undef N } #undef NUM_STATUS_READS diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c index 12f30f1..c4fae17 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c @@ -1465,7 +1465,7 @@ ar5416GetRegChainOffset(struct ath_hal *ah, int i) { int regChainOffset; - if (AR_SREV_OWL_20_OR_LATER(ah) && + if (AR_SREV_5416_V20_OR_LATER(ah) && (AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) { /* Regs are swapped from chain 2 to 1 for 5416 2_0 with @@ -1518,7 +1518,7 @@ ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan) * XXX update */ - if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) + if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) ar5416SetDefGainValues(ah, pModal, eep, txRxAttenLocal, regChainOffset, i); } @@ -2217,7 +2217,7 @@ ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); - if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { + if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { ar5416SetGainBoundariesClosedLoop(ah, i, pdGainOverlap_t2, gainBoundaries); } @@ -2329,7 +2329,7 @@ ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); /* NB: only applies to owl 1.0 */ - if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) { + if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah) ) { /* * fix the gain delta, but get a delta that can be applied to min to * keep the upper power values accurate, don't think max needs to @@ -2501,27 +2501,20 @@ ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan) } /* - * The AR5416 initvals have this already set to 0x11; AR9160 has - * the register set to 0x0. Figure out whether AR9130/AR9160 needs - * this before moving forward with it. - */ -#if 0 - /* Disable BB clock gating for AR5416v2, AR9130, AR9160 */ - if (AR_SREV_OWL_20_OR_LATER(ah) || AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) { - /* - * Disable BB clock gating - * Necessary to avoid issues on AR5416 2.0 - */ - OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); - } -#endif - - /* * Disable RIFS search on some chips to avoid baseband * hang issues. */ if (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) (void) ar5416SetRifsDelay(ah, AH_FALSE); + + if (!AR_SREV_5416_V20_OR_LATER(ah) || AR_SREV_MERLIN(ah)) + return; + + /* + * Disable BB clock gating + * Necessary to avoid issues on AR5416 2.0 + */ + OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); } struct ini { diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h index e52ded6..76f5080 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416desc.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416desc.h @@ -387,11 +387,11 @@ struct ar5416_desc { #define RXSTATUS_OFFSET(ah) 4 #define RXSTATUS_NUMWORDS(ah) 9 #define RXSTATUS_RATE(ah, ads) \ - (AR_SREV_OWL_20_OR_LATER(ah) ? \ + (AR_SREV_5416_V20_OR_LATER(ah) ? \ MS((ads)->ds_rxstatus0, AR_RxRate) : \ ((ads)->ds_rxstatus3 >> 2) & 0xFF) #define RXSTATUS_DUPLICATE(ah, ads) \ - (AR_SREV_OWL_20_OR_LATER(ah) ? \ + (AR_SREV_5416_V20_OR_LATER(ah) ? \ MS((ads)->ds_rxstatus3, AR_Parallel40) : \ ((ads)->ds_rxstatus3 >> 10) & 0x1) #endif /* _ATH_AR5416_DESC_H_ */ diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h index efe509f..fc02886 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416phy.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416phy.h @@ -100,6 +100,13 @@ #define AR_PHY_EXT_MINCCA_PWR_S 23 #define AR_PHY_EXT_CCA_THRESH62 0x007F0000 #define AR_PHY_EXT_CCA_THRESH62_S 16 +/* + * This duplicates AR_PHY_EXT_CCA_CYCPWR_THR1; it reads more like + * an ANI register this way. + */ +#define AR_PHY_EXT_TIMING5_CYCPWR_THR1 0x0000FE00 +#define AR_PHY_EXT_TIMING5_CYCPWR_THR1_S 9 + #define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000 #define AR9280_PHY_EXT_MINCCA_PWR_S 16 diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h index 96903e4..983a956 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416reg.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416reg.h @@ -580,6 +580,17 @@ #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 +/* + * AR5212 defines the MAC revision mask as 0xF, but both ath9k and + * the Atheros HAL define it as 0x7. + * + * What this means however is AR5416 silicon revisions have + * changed. The below macros are for what is contained in the + * lower four bits; if the lower three bits are taken into account + * the revisions become 1.0 => 0x0, 2.0 => 0x1, 2.2 => 0x2. + */ + +/* These are the legacy revisions, with a four bit AR_SREV_REVISION mask */ #define AR_SREV_REVISION_OWL_10 0x08 #define AR_SREV_REVISION_OWL_20 0x09 #define AR_SREV_REVISION_OWL_22 0x0a @@ -590,9 +601,13 @@ #define AR_RAD2122_SREV_MAJOR 0xf0 /* Fowl: 2+5G/2x2 */ /* Test macro for owl 1.0 */ -#define IS_5416V1(_ah) ((_ah)->ah_macRev == AR_SREV_REVISION_OWL_10) -#define IS_5416V2(_ah) ((_ah)->ah_macRev >= AR_SREV_REVISION_OWL_20) -#define IS_5416V2_2(_ah) ((_ah)->ah_macRev == AR_SREV_REVISION_OWL_22) +#define IS_5416V1(_ah) (AR_SREV_OWL((_ah)) && AH_PRIVATE((_ah))->ah_macRev == AR_SREV_REVISION_OWL_10) +#define IS_5416V2(_ah) (AR_SREV_OWL((_ah)) && AH_PRIVATE((_ah))->ah_macRev >= AR_SREV_REVISION_OWL_20) +#define IS_5416V2_2(_ah) (AR_SREV_OWL((_ah)) && AH_PRIVATE((_ah))->ah_macRev == AR_SREV_REVISION_OWL_22) + +/* Misc; compatibility with Atheros HAL */ +#define AR_SREV_5416_V20_OR_LATER(_ah) (AR_SREV_HOWL((_ah)) || AR_SREV_OWL_20_OR_LATER(_ah)) +#define AR_SREV_5416_V22_OR_LATER(_ah) (AR_SREV_HOWL((_ah)) || AR_SREV_OWL_22_OR_LATER(_ah)) /* Expanded Mac Silicon Rev (16 bits starting with Sowl) */ #define AR_XSREV_ID 0xFFFFFFFF /* Chip ID */ @@ -609,9 +624,20 @@ #define AR_XSREV_VERSION_OWL_PCI 0x0D #define AR_XSREV_VERSION_OWL_PCIE 0x0C + + +/* + * These are from ath9k/Atheros and assume an AR_SREV version mask + * of 0x07, rather than 0x0F which is being used in the FreeBSD HAL. + * Thus, don't use these values as they're incorrect here; use + * AR_SREV_REVISION_OWL_{10,20,22}. + */ +#if 0 #define AR_XSREV_REVISION_OWL_10 0 /* Owl 1.0 */ #define AR_XSREV_REVISION_OWL_20 1 /* Owl 2.0/2.1 */ #define AR_XSREV_REVISION_OWL_22 2 /* Owl 2.2 */ +#endif + #define AR_XSREV_VERSION_HOWL 0x14 /* Howl (AR9130) */ #define AR_XSREV_VERSION_SOWL 0x40 /* Sowl (AR9160) */ #define AR_XSREV_REVISION_SOWL_10 0 /* Sowl 1.0 */ @@ -632,12 +658,12 @@ #define AR_SREV_OWL_20_OR_LATER(_ah) \ ((AR_SREV_OWL(_ah) && \ - AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_OWL_20) || \ + AH_PRIVATE((_ah))->ah_macRev >= AR_SREV_REVISION_OWL_20) || \ AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_HOWL) #define AR_SREV_OWL_22_OR_LATER(_ah) \ ((AR_SREV_OWL(_ah) && \ - AH_PRIVATE((_ah))->ah_macRev >= AR_XSREV_REVISION_OWL_22) || \ + AH_PRIVATE((_ah))->ah_macRev >= AR_SREV_REVISION_OWL_22) || \ AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_HOWL) /* Howl (AR9130) */ diff --git a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c index 11c988f..49a5f5e 100644 --- a/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c +++ b/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c @@ -236,6 +236,9 @@ ar9130Attach(uint16_t devid, HAL_SOFTC sc, /* Read Reg Domain */ AH_PRIVATE(ah)->ah_currentRD = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + AH_PRIVATE(ah)->ah_currentRDext = + ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL); + /* * ah_miscMode is populated by ar5416FillCapabilityInfo() @@ -287,6 +290,14 @@ ar9130FillCapabilityInfo(struct ath_hal *ah) pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */ pCap->halExtChanDfsSupport = AH_TRUE; pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */ + /* + * MBSSID aggregation is broken in Howl v1.1, v1.2, v1.3 + * and works fine in v1.4. + * XXX todo, enable it for v1.4. + */ + pCap->halMbssidAggrSupport = AH_FALSE; + pCap->hal4AddrAggrSupport = AH_TRUE; + return AH_TRUE; } diff --git a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c index 689ef7f..0b6472b 100644 --- a/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c +++ b/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c @@ -241,6 +241,8 @@ ar9160Attach(uint16_t devid, HAL_SOFTC sc, /* Read Reg Domain */ AH_PRIVATE(ah)->ah_currentRD = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + AH_PRIVATE(ah)->ah_currentRDext = + ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL); /* * ah_miscMode is populated by ar5416FillCapabilityInfo() @@ -292,6 +294,9 @@ ar9160FillCapabilityInfo(struct ath_hal *ah) pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */ pCap->halExtChanDfsSupport = AH_TRUE; pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */ + pCap->halMbssidAggrSupport = AH_TRUE; + pCap->hal4AddrAggrSupport = AH_TRUE; + /* AR9160 is a 2x2 stream device */ pCap->halTxStreams = 2; pCap->halRxStreams = 2; diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c index 2ea0c3d..5e44cc5 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c @@ -325,6 +325,8 @@ ar9280Attach(uint16_t devid, HAL_SOFTC sc, /* Read Reg Domain */ AH_PRIVATE(ah)->ah_currentRD = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + AH_PRIVATE(ah)->ah_currentRDext = + ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL); /* * ah_miscMode is populated by ar5416FillCapabilityInfo() @@ -782,8 +784,11 @@ ar9280FillCapabilityInfo(struct ath_hal *ah) pCap->hal4kbSplitTransSupport = AH_FALSE; /* Disable this so Block-ACK works correctly */ pCap->halHasRxSelfLinkedTail = AH_FALSE; + pCap->halMbssidAggrSupport = AH_TRUE; + pCap->hal4AddrAggrSupport = AH_TRUE; + if (AR_SREV_MERLIN_20_OR_LATER(ah)) - pCap->halHasPsPollSupport = AH_TRUE; + pCap->halPSPollBroken = AH_FALSE; pCap->halRxStbcSupport = 1; pCap->halTxStbcSupport = 1; diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c b/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c index 8f9cf1d..da5e4ed 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c @@ -368,7 +368,7 @@ ar9280SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, gainBoundaries, numXpdGain, pdGainOverlap_t2, pwr_table_offset, &diff); - if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { + if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { /* Set gain boundaries for either open- or closed-loop TPC */ if (AR_SREV_MERLIN_20_OR_LATER(ah) && ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c index 93406f2..7aebc96 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c @@ -284,6 +284,11 @@ ar9285Attach(uint16_t devid, HAL_SOFTC sc, /* Read Reg Domain */ AH_PRIVATE(ah)->ah_currentRD = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); + /* + * For Kite and later chipsets, the following bits are not + * programmed in EEPROM and so are set as enabled always. + */ + AH_PRIVATE(ah)->ah_currentRDext = AR9285_RDEXT_DEFAULT; /* * ah_miscMode is populated by ar5416FillCapabilityInfo() @@ -390,8 +395,11 @@ ar9285FillCapabilityInfo(struct ath_hal *ah) pCap->hal4kbSplitTransSupport = AH_FALSE; /* Disable this so Block-ACK works correctly */ pCap->halHasRxSelfLinkedTail = AH_FALSE; + pCap->halMbssidAggrSupport = AH_TRUE; + pCap->hal4AddrAggrSupport = AH_TRUE; + if (AR_SREV_KITE_12_OR_LATER(ah)) - pCap->halHasPsPollSupport = AH_TRUE; + pCap->halPSPollBroken = AH_FALSE; pCap->halRxStbcSupport = 1; pCap->halTxStbcSupport = 1; diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c index 4a7c83e..68c8cea 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c @@ -648,7 +648,7 @@ ar9285SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom_4k *pEepData, &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); - if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) { + if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { /* * Note the pdadc table may not start at 0 dBm power, could be * negative or greater than 0. Need to offset the power @@ -762,7 +762,7 @@ ar9285GetGainBoundariesAndPdadcs(struct ath_hal *ah, pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); /* NB: only applies to owl 1.0 */ - if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) { + if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah) ) { /* * fix the gain delta, but get a delta that can be applied to min to * keep the upper power values accurate, don't think max needs to diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 4ff8967..60d791c 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1565,6 +1565,7 @@ product FALCOM TWIST 0x0001 USB GSM/GPRS Modem /* FEIYA products */ product FEIYA 5IN1 0x1132 5-in-1 Card Reader +product FEIYA AC110 0x6300 AC-110 Card Reader /* Fiberline */ product FIBERLINE WL430U 0x6003 WL-430U diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 004b511..f1c1d02 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -225,8 +225,8 @@ static int xl_attach(device_t); static int xl_detach(device_t); static int xl_newbuf(struct xl_softc *, struct xl_chain_onefrag *); -static void xl_stats_update(void *); -static void xl_stats_update_locked(struct xl_softc *); +static void xl_tick(void *); +static void xl_stats_update(struct xl_softc *); static int xl_encap(struct xl_softc *, struct xl_chain *, struct mbuf **); static int xl_rxeof(struct xl_softc *); static void xl_rxeof_task(void *, int); @@ -1330,7 +1330,7 @@ xl_attach(device_t dev) goto fail; } - callout_init_mtx(&sc->xl_stat_callout, &sc->xl_mtx, 0); + callout_init_mtx(&sc->xl_tick_callout, &sc->xl_mtx, 0); TASK_INIT(&sc->xl_task, 0, xl_rxeof_task, sc); /* @@ -1695,7 +1695,7 @@ xl_detach(device_t dev) xl_stop(sc); XL_UNLOCK(sc); taskqueue_drain(taskqueue_swi, &sc->xl_task); - callout_drain(&sc->xl_stat_callout); + callout_drain(&sc->xl_tick_callout); ether_ifdetach(ifp); } if (sc->xl_miibus) @@ -1904,8 +1904,8 @@ xl_newbuf(struct xl_softc *sc, struct xl_chain_onefrag *c) sc->xl_tmpmap = map; c->xl_mbuf = m_new; c->xl_ptr->xl_frag.xl_len = htole32(m_new->m_len | XL_LAST_FRAG); - c->xl_ptr->xl_status = 0; c->xl_ptr->xl_frag.xl_addr = htole32(segs->ds_addr); + c->xl_ptr->xl_status = 0; bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREREAD); return (0); } @@ -1944,7 +1944,7 @@ xl_rxeof(struct xl_softc *sc) struct mbuf *m; struct ifnet *ifp = sc->xl_ifp; struct xl_chain_onefrag *cur_rx; - int total_len = 0; + int total_len; int rx_npkts = 0; u_int32_t rxstat; @@ -1963,6 +1963,7 @@ again: cur_rx = sc->xl_cdata.xl_rx_head; sc->xl_cdata.xl_rx_head = cur_rx->xl_next; total_len = rxstat & XL_RXSTAT_LENMASK; + rx_npkts++; /* * Since we have told the chip to allow large frames, @@ -2047,7 +2048,6 @@ again: XL_UNLOCK(sc); (*ifp->if_input)(ifp, m); XL_LOCK(sc); - rx_npkts++; /* * If we are running from the taskqueue, the interface @@ -2207,7 +2207,7 @@ xl_txeoc(struct xl_softc *sc) txstat & XL_TXSTATUS_JABBER || txstat & XL_TXSTATUS_RECLAIM) { device_printf(sc->xl_dev, - "transmission error: %x\n", txstat); + "transmission error: 0x%02x\n", txstat); CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET); xl_wait(sc); if (sc->xl_type == XL_TYPE_905B) { @@ -2220,11 +2220,14 @@ xl_txeoc(struct xl_softc *sc) CSR_WRITE_4(sc, XL_DOWNLIST_PTR, c->xl_phys); CSR_WRITE_1(sc, XL_DOWN_POLL, 64); + sc->xl_wdog_timer = 5; } } else { - if (sc->xl_cdata.xl_tx_head != NULL) + if (sc->xl_cdata.xl_tx_head != NULL) { CSR_WRITE_4(sc, XL_DOWNLIST_PTR, sc->xl_cdata.xl_tx_head->xl_phys); + sc->xl_wdog_timer = 5; + } } /* * Remember to set this for the @@ -2273,17 +2276,17 @@ xl_intr(void *arg) } #endif - while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS && - status != 0xFFFF) { + for (;;) { + status = CSR_READ_2(sc, XL_STATUS); + if ((status & XL_INTRS) == 0 || status == 0xFFFF) + break; CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|(status & XL_INTRS)); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; if (status & XL_STAT_UP_COMPLETE) { - int curpkts; - - curpkts = ifp->if_ipackets; - xl_rxeof(sc); - if (curpkts == ifp->if_ipackets) { + if (xl_rxeof(sc) == 0) { while (xl_rx_resync(sc)) xl_rxeof(sc); } @@ -2304,16 +2307,15 @@ xl_intr(void *arg) if (status & XL_STAT_ADFAIL) { ifp->if_drv_flags &= ~IFF_DRV_RUNNING; xl_init_locked(sc); + break; } - if (status & XL_STAT_STATSOFLOW) { - sc->xl_stats_no_timeout = 1; - xl_stats_update_locked(sc); - sc->xl_stats_no_timeout = 0; - } + if (status & XL_STAT_STATSOFLOW) + xl_stats_update(sc); } - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd) && + ifp->if_drv_flags & IFF_DRV_RUNNING) { if (sc->xl_type == XL_TYPE_905B) xl_start_90xB_locked(ifp); else @@ -2377,49 +2379,46 @@ xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) xl_init_locked(sc); } - if (status & XL_STAT_STATSOFLOW) { - sc->xl_stats_no_timeout = 1; - xl_stats_update_locked(sc); - sc->xl_stats_no_timeout = 0; - } + if (status & XL_STAT_STATSOFLOW) + xl_stats_update(sc); } } return (rx_npkts); } #endif /* DEVICE_POLLING */ -/* - * XXX: This is an entry point for callout which needs to take the lock. - */ static void -xl_stats_update(void *xsc) +xl_tick(void *xsc) { struct xl_softc *sc = xsc; + struct mii_data *mii; XL_LOCK_ASSERT(sc); + if (sc->xl_miibus != NULL) { + mii = device_get_softc(sc->xl_miibus); + mii_tick(mii); + } + + xl_stats_update(sc); if (xl_watchdog(sc) == EJUSTRETURN) return; - xl_stats_update_locked(sc); + callout_reset(&sc->xl_tick_callout, hz, xl_tick, sc); } static void -xl_stats_update_locked(struct xl_softc *sc) +xl_stats_update(struct xl_softc *sc) { struct ifnet *ifp = sc->xl_ifp; struct xl_stats xl_stats; u_int8_t *p; int i; - struct mii_data *mii = NULL; XL_LOCK_ASSERT(sc); bzero((char *)&xl_stats, sizeof(struct xl_stats)); - if (sc->xl_miibus != NULL) - mii = device_get_softc(sc->xl_miibus); - p = (u_int8_t *)&xl_stats; /* Read all the stats registers. */ @@ -2441,14 +2440,7 @@ xl_stats_update_locked(struct xl_softc *sc) */ XL_SEL_WIN(4); CSR_READ_1(sc, XL_W4_BADSSD); - - if ((mii != NULL) && (!sc->xl_stats_no_timeout)) - mii_tick(mii); - XL_SEL_WIN(7); - - if (!sc->xl_stats_no_timeout) - callout_reset(&sc->xl_stat_callout, hz, xl_stats_update, sc); } /* @@ -2507,6 +2499,7 @@ xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf **m_head) *m_head = NULL; return (EIO); } + bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREWRITE); total_len = 0; for (i = 0; i < nseg; i++) { @@ -2519,8 +2512,6 @@ xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf **m_head) total_len += sc->xl_cdata.xl_tx_segs[i].ds_len; } c->xl_ptr->xl_frag[nseg - 1].xl_len |= htole32(XL_LAST_FRAG); - c->xl_ptr->xl_status = htole32(total_len); - c->xl_ptr->xl_next = 0; if (sc->xl_type == XL_TYPE_905B) { status = XL_TXSTAT_RND_DEFEAT; @@ -2535,11 +2526,12 @@ xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf **m_head) status |= XL_TXSTAT_UDPCKSUM; } #endif - c->xl_ptr->xl_status = htole32(status); - } + } else + status = total_len; + c->xl_ptr->xl_status = htole32(status); + c->xl_ptr->xl_next = 0; c->xl_mbuf = *m_head; - bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREWRITE); return (0); } @@ -2569,9 +2561,9 @@ static void xl_start_locked(struct ifnet *ifp) { struct xl_softc *sc = ifp->if_softc; - struct mbuf *m_head = NULL; + struct mbuf *m_head; struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx; - u_int32_t status; + struct xl_chain *prev_tx; int error; XL_LOCK_ASSERT(sc); @@ -2601,11 +2593,13 @@ xl_start_locked(struct ifnet *ifp) break; /* Pick a descriptor off the free list. */ + prev_tx = cur_tx; cur_tx = sc->xl_cdata.xl_tx_free; /* Pack the data into the descriptor. */ error = xl_encap(sc, cur_tx, &m_head); if (error) { + cur_tx = prev_tx; if (m_head == NULL) break; ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -2644,8 +2638,6 @@ xl_start_locked(struct ifnet *ifp) * once for each packet. */ cur_tx->xl_ptr->xl_status |= htole32(XL_TXSTAT_DL_INTR); - bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap, - BUS_DMASYNC_PREWRITE); /* * Queue the packets. If the TX channel is clear, update @@ -2658,7 +2650,6 @@ xl_start_locked(struct ifnet *ifp) sc->xl_cdata.xl_tx_tail->xl_next = start_tx; sc->xl_cdata.xl_tx_tail->xl_ptr->xl_next = htole32(start_tx->xl_phys); - status = sc->xl_cdata.xl_tx_tail->xl_ptr->xl_status; sc->xl_cdata.xl_tx_tail->xl_ptr->xl_status &= htole32(~XL_TXSTAT_DL_INTR); sc->xl_cdata.xl_tx_tail = cur_tx; @@ -2666,6 +2657,8 @@ xl_start_locked(struct ifnet *ifp) sc->xl_cdata.xl_tx_head = start_tx; sc->xl_cdata.xl_tx_tail = cur_tx; } + bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap, + BUS_DMASYNC_PREWRITE); if (!CSR_READ_4(sc, XL_DOWNLIST_PTR)) CSR_WRITE_4(sc, XL_DOWNLIST_PTR, start_tx->xl_phys); @@ -2700,8 +2693,9 @@ static void xl_start_90xB_locked(struct ifnet *ifp) { struct xl_softc *sc = ifp->if_softc; - struct mbuf *m_head = NULL; + struct mbuf *m_head; struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx; + struct xl_chain *prev_tx; int error, idx; XL_LOCK_ASSERT(sc); @@ -2724,11 +2718,13 @@ xl_start_90xB_locked(struct ifnet *ifp) if (m_head == NULL) break; + prev_tx = cur_tx; cur_tx = &sc->xl_cdata.xl_tx_chain[idx]; /* Pack the data into the descriptor. */ error = xl_encap(sc, cur_tx, &m_head); if (error) { + cur_tx = prev_tx; if (m_head == NULL) break; ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -2765,12 +2761,12 @@ xl_start_90xB_locked(struct ifnet *ifp) * once for each packet. */ cur_tx->xl_ptr->xl_status |= htole32(XL_TXSTAT_DL_INTR); - bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap, - BUS_DMASYNC_PREWRITE); /* Start transmission */ sc->xl_cdata.xl_tx_prod = idx; start_tx->xl_prev->xl_ptr->xl_next = htole32(start_tx->xl_phys); + bus_dmamap_sync(sc->xl_ldata.xl_tx_tag, sc->xl_ldata.xl_tx_dmamap, + BUS_DMASYNC_PREWRITE); /* * Set a timeout in case the chip goes out to lunch. @@ -2949,9 +2945,7 @@ xl_init_locked(struct xl_softc *sc) /* Clear out the stats counters. */ CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE); - sc->xl_stats_no_timeout = 1; - xl_stats_update_locked(sc); - sc->xl_stats_no_timeout = 0; + xl_stats_update(sc); XL_SEL_WIN(4); CSR_WRITE_2(sc, XL_W4_NET_DIAG, XL_NETDIAG_UPPER_BYTES_ENABLE); CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_ENABLE); @@ -2973,7 +2967,7 @@ xl_init_locked(struct xl_softc *sc) /* Set the RX early threshold */ CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_THRESH|(XL_PACKET_SIZE >>2)); - CSR_WRITE_2(sc, XL_DMACTL, XL_DMACTL_UP_RX_EARLY); + CSR_WRITE_4(sc, XL_DMACTL, XL_DMACTL_UP_RX_EARLY); /* Enable receiver and transmitter. */ CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE); @@ -2992,7 +2986,7 @@ xl_init_locked(struct xl_softc *sc) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->xl_wdog_timer = 0; - callout_reset(&sc->xl_stat_callout, hz, xl_stats_update, sc); + callout_reset(&sc->xl_tick_callout, hz, xl_tick, sc); } /* @@ -3301,7 +3295,7 @@ xl_stop(struct xl_softc *sc) bus_space_write_4(sc->xl_ftag, sc->xl_fhandle, 4, 0x8000); /* Stop the stats updater. */ - callout_stop(&sc->xl_stat_callout); + callout_stop(&sc->xl_tick_callout); /* * Free data in the RX lists. diff --git a/sys/dev/xl/if_xlreg.h b/sys/dev/xl/if_xlreg.h index 2685c44..f5494f5 100644 --- a/sys/dev/xl/if_xlreg.h +++ b/sys/dev/xl/if_xlreg.h @@ -124,6 +124,11 @@ #define XL_DMACTL_DOWN_INPROG 0x00000080 #define XL_DMACTL_COUNTER_SPEED 0x00000100 #define XL_DMACTL_DOWNDOWN_MODE 0x00000200 +#define XL_DMACTL_UP_ALTSEQ_DIS 0x00010000 /* 3c90xB/3c90xC */ +#define XL_DMACTL_DOWN_ALTSEQ_DIS 0x00020000 /* 3c90xC only */ +#define XL_DMACTL_DEFEAT_MWI 0x00100000 /* 3c90xB/3c90xC */ +#define XL_DMACTL_DEFEAT_MRL 0x00100000 /* 3c90xB/3c90xC */ +#define XL_DMACTL_UP_OVERRUN_DISC_DIS 0x00200000 /* 3c90xB/3c90xC */ #define XL_DMACTL_TARGET_ABORT 0x40000000 #define XL_DMACTL_MASTER_ABORT 0x80000000 @@ -468,8 +473,8 @@ struct xl_list { struct xl_list_onefrag { u_int32_t xl_next; /* final entry has 0 nextptr */ - u_int32_t xl_status; - struct xl_frag xl_frag; + volatile u_int32_t xl_status; + volatile struct xl_frag xl_frag; }; struct xl_list_data { @@ -614,13 +619,12 @@ struct xl_softc { u_int32_t xl_xcvr; u_int16_t xl_media; u_int16_t xl_caps; - u_int8_t xl_stats_no_timeout; u_int16_t xl_tx_thresh; int xl_pmcap; int xl_if_flags; struct xl_list_data xl_ldata; struct xl_chain_data xl_cdata; - struct callout xl_stat_callout; + struct callout xl_tick_callout; int xl_wdog_timer; int xl_flags; struct resource *xl_fres; diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index bfb96e9..265a5c4 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -1359,6 +1359,7 @@ cpu_idle(int busy) if (mp_grab_cpu_hlt()) return; #endif +#ifndef XEN /* If we are busy - try to use fast methods. */ if (busy) { if ((cpu_feature2 & CPUID2_MON) && idle_mwait) { @@ -1367,7 +1368,6 @@ cpu_idle(int busy) } } -#ifndef XEN /* If we have time - switch timers into idle mode. */ if (!busy) { critical_enter(); @@ -1395,8 +1395,8 @@ cpu_idle(int busy) cpu_activeclock(); critical_exit(); } -#endif out: +#endif CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done", busy, curcpu); } diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index a160642..5f10ad6 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_pageout.h> #include <vm/uma.h> +#include <machine/bootinfo.h> #include <machine/md_var.h> #include <machine/pal.h> @@ -1206,6 +1207,8 @@ vm_paddr_t pmap_kextract(vm_offset_t va) { struct ia64_lpte *pte; + uint64_t *pbvm_pgtbl; + u_int idx; KASSERT(va >= VM_MAXUSER_ADDRESS, ("Must be kernel VA")); @@ -1222,6 +1225,25 @@ pmap_kextract(vm_offset_t va) return (pmap_present(pte) ? pmap_ppn(pte)|(va&PAGE_MASK) : 0); } + /* PBVM page table. */ + if (va >= IA64_PBVM_PGTBL + bootinfo->bi_pbvm_pgtblsz); + return (0); + if (va >= IA64_PBVM_PGTBL) + return (va - IA64_PBVM_PGTBL) + bootinfo->bi_pbvm_pgtbl; + + /* PBVM. */ + if (va >= IA64_PBVM_BASE) { + pbvm_pgtbl = (void *)IA64_PBVM_PGTBL; + idx = (va - IA64_PBVM_BASE) >> IA64_PBVM_PAGE_SHIFT; + if (idx >= (bootinfo->bi_pbvm_pgtblsz >> 3)) + return (0); + if ((pbvm_pgtbl[idx] & PTE_PRESENT) == 0) + return (0); + return ((pbvm_pgtbl[idx] & PTE_PPN_MASK) + + (va & IA64_PBVM_PAGE_MASK)); + } + + printf("XXX: %s: va=%#lx\n", __func__, va); return (0); } diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c index 73551f4..41a9fa8 100644 --- a/sys/kern/kern_environment.c +++ b/sys/kern/kern_environment.c @@ -321,6 +321,8 @@ getenv(const char *name) } else { mtx_unlock(&kenv_lock); ret = NULL; + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, + "getenv"); } } else ret = _getenv_static(name); diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h index 568d15f..42165ce 100644 --- a/sys/sys/elf_common.h +++ b/sys/sys/elf_common.h @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien * Copyright (c) 1998 John D. Polstra. * All rights reserved. * @@ -295,6 +296,7 @@ typedef struct { #define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ #define SHT_LOPROC 0x70000000 /* reserved range for processor */ #define SHT_AMD64_UNWIND 0x70000001 /* unwind information */ +#define SHT_MIPS_DWARF 0x7000001e /* MIPS gcc uses MIPS_DWARF */ #define SHT_HIPROC 0x7fffffff /* specific section header types */ #define SHT_LOUSER 0x80000000 /* reserved range for application */ #define SHT_HIUSER 0xffffffff /* specific indexes */ diff --git a/tools/regression/bin/sh/expansion/length7.0 b/tools/regression/bin/sh/expansion/length7.0 new file mode 100644 index 0000000..b79b116 --- /dev/null +++ b/tools/regression/bin/sh/expansion/length7.0 @@ -0,0 +1,14 @@ +# $FreeBSD$ + +unset LC_ALL +LC_CTYPE=en_US.UTF-8 +export LC_CTYPE + +# a umlaut +s=$(printf '\303\244') +# euro sign +s=$s$(printf '\342\202\254') +# some sort of 't' outside BMP +s=$s$(printf '\360\235\225\245') +set -- "$s" +[ ${#s} = 3 ] && [ ${#1} = 3 ] diff --git a/tools/regression/bin/sh/expansion/length8.0 b/tools/regression/bin/sh/expansion/length8.0 new file mode 100644 index 0000000..3cc6c15 --- /dev/null +++ b/tools/regression/bin/sh/expansion/length8.0 @@ -0,0 +1,14 @@ +# $FreeBSD$ + +unset LC_ALL +LC_CTYPE=en_US.ISO8859-1 +export LC_CTYPE + +# a umlaut +s=$(printf '\303\244') +# euro sign +s=$s$(printf '\342\202\254') +# some sort of 't' outside BMP +s=$s$(printf '\360\235\225\245') +set -- "$s" +[ ${#s} = 9 ] && [ ${#1} = 9 ] diff --git a/usr.sbin/usbdump/usbdump.c b/usr.sbin/usbdump/usbdump.c index 4eb709b..f32104a 100644 --- a/usr.sbin/usbdump/usbdump.c +++ b/usr.sbin/usbdump/usbdump.c @@ -40,7 +40,6 @@ #include <dev/usb/usb.h> #include <dev/usb/usb_pf.h> #include <dev/usb/usbdi.h> -#include <assert.h> #include <errno.h> #include <fcntl.h> #include <limits.h> @@ -49,6 +48,8 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <sysexits.h> +#include <err.h> struct usbcap { int fd; /* fd for /dev/usbpf */ @@ -408,9 +409,15 @@ write_packets(struct usbcap *p, const uint8_t *data, const int datalen) int ret; ret = write(p->wfd, &len, sizeof(int)); - assert(ret == sizeof(int)); + if (ret != sizeof(int)) { + err(EXIT_FAILURE, "Could not write length " + "field of USB data payload"); + } ret = write(p->wfd, data, datalen); - assert(ret == datalen); + if (ret != datalen) { + err(EXIT_FAILURE, "Could not write " + "complete USB data payload"); + } } static void @@ -423,14 +430,16 @@ read_file(struct usbcap *p) while ((ret = read(p->rfd, &datalen, sizeof(int))) == sizeof(int)) { datalen = le32toh(datalen); data = malloc(datalen); - assert(data != NULL); + if (data == NULL) + errx(EX_SOFTWARE, "Out of memory."); ret = read(p->rfd, data, datalen); - assert(ret == datalen); + if (ret != datalen) { + err(EXIT_FAILURE, "Could not read complete " + "USB data payload"); + } print_packets(data, datalen); free(data); } - if (ret == -1) - fprintf(stderr, "read: %s\n", strerror(errno)); } static void @@ -466,14 +475,27 @@ init_rfile(struct usbcap *p) p->rfd = open(r_arg, O_RDONLY); if (p->rfd < 0) { - fprintf(stderr, "open: %s (%s)\n", r_arg, strerror(errno)); - exit(EXIT_FAILURE); + err(EXIT_FAILURE, "Could not open " + "'%s' for read", r_arg); } ret = read(p->rfd, &uf, sizeof(uf)); - assert(ret == sizeof(uf)); - assert(le32toh(uf.magic) == USBCAP_FILEHDR_MAGIC); - assert(uf.major == 0); - assert(uf.minor == 2); + if (ret != sizeof(uf)) { + err(EXIT_FAILURE, "Could not read USB capture " + "file header"); + } + if (le32toh(uf.magic) != USBCAP_FILEHDR_MAGIC) { + errx(EX_SOFTWARE, "Invalid magic field(0x%08x) " + "in USB capture file header.", + (unsigned int)le32toh(uf.magic)); + } + if (uf.major != 0) { + errx(EX_SOFTWARE, "Invalid major version(%d) " + "field in USB capture file header.", (int)uf.major); + } + if (uf.minor != 2) { + errx(EX_SOFTWARE, "Invalid minor version(%d) " + "field in USB capture file header.", (int)uf.minor); + } } static void @@ -484,15 +506,18 @@ init_wfile(struct usbcap *p) p->wfd = open(w_arg, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); if (p->wfd < 0) { - fprintf(stderr, "open: %s (%s)\n", w_arg, strerror(errno)); - exit(EXIT_FAILURE); + err(EXIT_FAILURE, "Could not open " + "'%s' for write", r_arg); } - bzero(&uf, sizeof(uf)); + memset(&uf, 0, sizeof(uf)); uf.magic = htole32(USBCAP_FILEHDR_MAGIC); uf.major = 0; uf.minor = 2; ret = write(p->wfd, (const void *)&uf, sizeof(uf)); - assert(ret == sizeof(uf)); + if (ret != sizeof(uf)) { + err(EXIT_FAILURE, "Could not write " + "USB capture header"); + } } static void @@ -501,13 +526,13 @@ usage(void) #define FMT " %-14s %s\n" fprintf(stderr, "usage: usbdump [options]\n"); - fprintf(stderr, FMT, "-i ifname", "Listen on USB bus interface"); - fprintf(stderr, FMT, "-r file", "Read the raw packets from file"); - fprintf(stderr, FMT, "-s snaplen", "Snapshot bytes from each packet"); - fprintf(stderr, FMT, "-v", "Increases the verbose level"); - fprintf(stderr, FMT, "-w file", "Write the raw packets to file"); + fprintf(stderr, FMT, "-i <usbusX>", "Listen on USB bus interface"); + fprintf(stderr, FMT, "-r <file>", "Read the raw packets from file"); + fprintf(stderr, FMT, "-s <snaplen>", "Snapshot bytes from each packet"); + fprintf(stderr, FMT, "-v", "Increase the verbose level"); + fprintf(stderr, FMT, "-w <file>", "Write the raw packets to file"); #undef FMT - exit(1); + exit(EX_USAGE); } int @@ -525,7 +550,7 @@ main(int argc, char *argv[]) int fd, o; const char *optstring; - bzero(&uc, sizeof(struct usbcap)); + memset(&uc, 0, sizeof(struct usbcap)); optstring = "i:r:s:vw:"; while ((o = getopt(argc, argv, optstring)) != -1) { @@ -565,20 +590,15 @@ main(int argc, char *argv[]) } p->fd = fd = open("/dev/bpf", O_RDONLY); - if (p->fd < 0) { - fprintf(stderr, "(no devices found)\n"); - return (EXIT_FAILURE); - } + if (p->fd < 0) + err(EXIT_FAILURE, "Could not open BPF device"); + + if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) + err(EXIT_FAILURE, "BIOCVERSION ioctl failed"); - if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) { - fprintf(stderr, "BIOCVERSION: %s\n", strerror(errno)); - return (EXIT_FAILURE); - } if (bv.bv_major != BPF_MAJOR_VERSION || - bv.bv_minor < BPF_MINOR_VERSION) { - fprintf(stderr, "kernel bpf filter out of date"); - return (EXIT_FAILURE); - } + bv.bv_minor < BPF_MINOR_VERSION) + errx(EXIT_FAILURE, "Kernel BPF filter out of date"); /* USB transfers can be greater than 64KByte */ v = 1U << 16; @@ -592,22 +612,16 @@ main(int argc, char *argv[]) if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) break; } - if (v == 0) { - fprintf(stderr, "BIOCSBLEN: %s: No buffer size worked", i_arg); - return (EXIT_FAILURE); - } + if (v == 0) + errx(EXIT_FAILURE, "No buffer size worked."); - if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) { - fprintf(stderr, "BIOCGBLEN: %s", strerror(errno)); - return (EXIT_FAILURE); - } + if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) + err(EXIT_FAILURE, "BIOCGBLEN ioctl failed"); p->bufsize = v; p->buffer = (uint8_t *)malloc(p->bufsize); - if (p->buffer == NULL) { - fprintf(stderr, "malloc: %s", strerror(errno)); - return (EXIT_FAILURE); - } + if (p->buffer == NULL) + errx(EX_SOFTWARE, "Out of memory."); /* XXX no read filter rules yet so at this moment accept everything */ total_insn.code = (u_short)(BPF_RET | BPF_K); @@ -617,27 +631,21 @@ main(int argc, char *argv[]) total_prog.bf_len = 1; total_prog.bf_insns = &total_insn; - if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) { - fprintf(stderr, "BIOCSETF: %s", strerror(errno)); - return (EXIT_FAILURE); - } + if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) + err(EXIT_FAILURE, "BIOCSETF ioctl failed"); /* 1 second read timeout */ tv.tv_sec = 1; tv.tv_usec = 0; - if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&tv) < 0) { - fprintf(stderr, "BIOCSRTIMEOUT: %s", strerror(errno)); - return (EXIT_FAILURE); - } + if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&tv) < 0) + err(EXIT_FAILURE, "BIOCSRTIMEOUT ioctl failed"); (void)signal(SIGINT, handle_sigint); do_loop(p); - if (ioctl(fd, BIOCGSTATS, (caddr_t)&us) < 0) { - fprintf(stderr, "BIOCGSTATS: %s", strerror(errno)); - return (EXIT_FAILURE); - } + if (ioctl(fd, BIOCGSTATS, (caddr_t)&us) < 0) + err(EXIT_FAILURE, "BIOCGSTATS ioctl failed"); /* XXX what's difference between pkt_captured and us.us_recv? */ printf("\n"); |