This commit is contained in:
Attilio Rao 2011-05-07 23:34:14 +00:00
commit b9f714be9f
43 changed files with 987 additions and 404 deletions

View File

@ -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 @@ evalvar(char *p, int flag)
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 @@ evalvar(char *p, int flag)
if (subtype == VSLENGTH) {
for (;*val; val++)
varlen++;
if (!localeisutf8 ||
(*val & 0xC0) != 0x80)
varlen++;
}
else {
if (quotes)

View File

@ -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) {

View File

@ -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;

View File

@ -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 **);

View File

@ -14,6 +14,7 @@ SRCS= \
dwarf_errno.c \
dwarf_finish.c \
dwarf_form.c \
dwarf_func.c \
dwarf_init.c \
dwarf_loc.c

View File

@ -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_ */

227
lib/libdwarf/dwarf_func.c Normal file
View File

@ -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);
}
}

View File

@ -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;

View File

@ -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_ */

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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:

View File

@ -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)
.Sh SYNOPSIS
.In ar.h
.Sh DESCRIPTION
An archive managed by the
.Nd archive file format for
.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
.Xr ar 1
archive format, the BSD variant and the SVR4/GNU variant.
Both variants are described by this manual page.
.Pp
The header file
.Sh SYNOPSIS
.In ar.h
defines constants and structures used to describe the layout
of these archives.
.Ss Archive Layout
.Sh DESCRIPTION
.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.
archives are created and managed by the
.Xr ar 1
and
.Xr ranlib 1
utilities.
These archives are typically used during program development to
hold libraries of program objects.
An
.Xr ar 1
archive is contained in a single operating system 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.
This manual page documents two variants of the
.Xr ar 1
archive format: the BSD archive format, and the SVR4/GNU archive
format.
.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
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
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 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.
.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.
.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.
.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
The format of the symbol table depends on the format variant:
.Bl -tag -width "SVR4/GNU" -compact
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
.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 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.
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
.El
.Ss Archive String Table
In the SVR4/GNU variant of the
.Sh STANDARDS COMPLIANCE
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 format is not currently specified by a standard.
.Pp
This manual page documents the
.Xr ar 1
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

View File

@ -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");
/*

View File

@ -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);

View File

@ -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:

View File

@ -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;
/*

View File

@ -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
};

View File

@ -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 */

View File

@ -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)

View File

@ -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) {

View File

@ -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

View File

@ -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
@ -2500,28 +2500,21 @@ ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
}
/*
* 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 {

View File

@ -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_ */

View File

@ -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

View File

@ -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) */

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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))

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 @@ xl_rxeof(struct xl_softc *sc)
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 @@ xl_rxeof(struct xl_softc *sc)
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.

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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 */

View File

@ -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 ]

View File

@ -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 ]

View File

@ -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");