MFC
This commit is contained in:
commit
b9f714be9f
@ -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)
|
||||
|
@ -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) {
|
||||
|
19
bin/sh/var.c
19
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;
|
||||
|
@ -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 **);
|
||||
|
@ -14,6 +14,7 @@ SRCS= \
|
||||
dwarf_errno.c \
|
||||
dwarf_finish.c \
|
||||
dwarf_form.c \
|
||||
dwarf_func.c \
|
||||
dwarf_init.c \
|
||||
dwarf_loc.c
|
||||
|
||||
|
@ -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
227
lib/libdwarf/dwarf_func.c
Normal 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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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) */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
14
tools/regression/bin/sh/expansion/length7.0
Normal file
14
tools/regression/bin/sh/expansion/length7.0
Normal 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 ]
|
14
tools/regression/bin/sh/expansion/length8.0
Normal file
14
tools/regression/bin/sh/expansion/length8.0
Normal 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 ]
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user