Merge ^/head r318964 through r319164.
This commit is contained in:
commit
e02c83ea49
@ -150,6 +150,8 @@ OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_
|
||||
OLD_DIRS+=usr/lib/clang/4.0.0/lib/freebsd
|
||||
OLD_DIRS+=usr/lib/clang/4.0.0/lib
|
||||
OLD_DIRS+=usr/lib/clang/4.0.0
|
||||
# 20170529: mount.conf(8) -> mount.conf(5)
|
||||
OLD_FILES+=usr/share/man/man8/mount.conf.8.gz
|
||||
# 20170525: remove misleading template
|
||||
OLD_FILES+=usr/share/misc/man.template
|
||||
# 20170525: disconnect the roff docs from the build
|
||||
@ -222,6 +224,10 @@ OLD_FILES+=usr/share/doc/usd/21.troff/paper.ascii.gz
|
||||
OLD_FILES+=usr/share/doc/usd/22.trofftut/paper.ascii.gz
|
||||
OLD_FILES+=usr/share/doc/usd/Title.ascii.gz
|
||||
OLD_FILES+=usr/share/doc/usd/contents.ascii.gz
|
||||
# 20170523: 64-bit inode support, library version bumps
|
||||
OLD_LIBS+=lib/libzfs.so.2
|
||||
OLD_LIBS+=usr/lib/libarchive.so.6
|
||||
OLD_LIBS+=usr/lib/libmilter.so.5
|
||||
# 20170427: NATM configuration support removed
|
||||
OLD_FILES+=etc/rc.d/atm1
|
||||
OLD_FILES+=etc/rc.d/atm2
|
||||
|
@ -480,7 +480,7 @@ powerpc-*-lynxos*) targ_emul=ppclynx ;;
|
||||
rs6000-*-aix5*) targ_emul=aix5rs6 ;;
|
||||
rs6000-*-aix*) targ_emul=aixrs6
|
||||
;;
|
||||
s390x-*-freebsd*) targ_emul=elf64_s390
|
||||
s390x-*-freebsd*) targ_emul=elf64_s390
|
||||
targ_extra_emuls=elf_s390
|
||||
targ_extra_libpath=$targ_extra_emuls
|
||||
tdir_elf_s390=`echo ${targ_alias} | sed -e 's/s390x/s390/'` ;;
|
||||
@ -490,7 +490,7 @@ s390x-*-linux*) targ_emul=elf64_s390
|
||||
tdir_elf_s390=`echo ${targ_alias} | sed -e 's/s390x/s390/'` ;;
|
||||
s390x-*-tpf*) targ_emul=elf64_s390
|
||||
tdir_elf_s390=`echo ${targ_alias} | sed -e 's/s390x/s390/'` ;;
|
||||
s390-*-freebsd*) targ_emul=elf_s390
|
||||
s390-*-freebsd*) targ_emul=elf_s390
|
||||
targ64_extra_emuls=elf64_s390
|
||||
targ64_extra_libpath=elf64_s390
|
||||
tdir_elf64_s390=`echo ${targ_alias} | sed -e 's/s390/s390x/'`
|
||||
|
@ -47,39 +47,49 @@ struct c4iw_stats c4iw_stats;
|
||||
|
||||
static void copy_wr_to_sq(struct t4_wq *wq, union t4_wr *wqe, u8 len16)
|
||||
{
|
||||
u64 *src, *dst;
|
||||
void *src, *dst;
|
||||
uintptr_t end;
|
||||
int total, len;
|
||||
|
||||
src = (u64 *)wqe;
|
||||
dst = (u64 *)((u8 *)wq->sq.queue + wq->sq.wq_pidx * T4_EQ_ENTRY_SIZE);
|
||||
src = &wqe->flits[0];
|
||||
dst = &wq->sq.queue->flits[wq->sq.wq_pidx *
|
||||
(T4_EQ_ENTRY_SIZE / sizeof(__be64))];
|
||||
if (t4_sq_onchip(wq)) {
|
||||
len16 = align(len16, 4);
|
||||
wc_wmb();
|
||||
}
|
||||
while (len16) {
|
||||
*dst++ = *src++;
|
||||
if (dst == (u64 *)&wq->sq.queue[wq->sq.size])
|
||||
dst = (u64 *)wq->sq.queue;
|
||||
*dst++ = *src++;
|
||||
if (dst == (u64 *)&wq->sq.queue[wq->sq.size])
|
||||
dst = (u64 *)wq->sq.queue;
|
||||
len16--;
|
||||
|
||||
total = len16 * 16;
|
||||
end = (uintptr_t)&wq->sq.queue[wq->sq.size];
|
||||
if (__predict_true((uintptr_t)dst + total <= end)) {
|
||||
/* Won't wrap around. */
|
||||
memcpy(dst, src, total);
|
||||
} else {
|
||||
len = end - (uintptr_t)dst;
|
||||
memcpy(dst, src, len);
|
||||
memcpy(wq->sq.queue, src + len, total - len);
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_wr_to_rq(struct t4_wq *wq, union t4_recv_wr *wqe, u8 len16)
|
||||
{
|
||||
u64 *src, *dst;
|
||||
void *src, *dst;
|
||||
uintptr_t end;
|
||||
int total, len;
|
||||
|
||||
src = (u64 *)wqe;
|
||||
dst = (u64 *)((u8 *)wq->rq.queue + wq->rq.wq_pidx * T4_EQ_ENTRY_SIZE);
|
||||
while (len16) {
|
||||
*dst++ = *src++;
|
||||
if (dst >= (u64 *)&wq->rq.queue[wq->rq.size])
|
||||
dst = (u64 *)wq->rq.queue;
|
||||
*dst++ = *src++;
|
||||
if (dst >= (u64 *)&wq->rq.queue[wq->rq.size])
|
||||
dst = (u64 *)wq->rq.queue;
|
||||
len16--;
|
||||
src = &wqe->flits[0];
|
||||
dst = &wq->rq.queue->flits[wq->rq.wq_pidx *
|
||||
(T4_EQ_ENTRY_SIZE / sizeof(__be64))];
|
||||
|
||||
total = len16 * 16;
|
||||
end = (uintptr_t)&wq->rq.queue[wq->rq.size];
|
||||
if (__predict_true((uintptr_t)dst + total <= end)) {
|
||||
/* Won't wrap around. */
|
||||
memcpy(dst, src, total);
|
||||
} else {
|
||||
len = end - (uintptr_t)dst;
|
||||
memcpy(dst, src, len);
|
||||
memcpy(wq->rq.queue, src + len, total - len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,14 @@ saveseed_cmd="${name}_stop"
|
||||
|
||||
save_dev_random()
|
||||
{
|
||||
oumask=`umask`
|
||||
umask 077
|
||||
for f ; do
|
||||
if :>>"$f" ; then
|
||||
debug "saving entropy to $f"
|
||||
dd if=/dev/random of="$f" bs=4096 count=1 2>/dev/null
|
||||
fi
|
||||
debug "saving entropy to $f"
|
||||
dd if=/dev/random of="$f" bs=4096 count=1 status=none &&
|
||||
chmod 600 "$f"
|
||||
done
|
||||
umask ${oumask}
|
||||
}
|
||||
|
||||
feed_dev_random()
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)getdirentries.2 8.2 (Berkeley) 5/3/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 3, 1995
|
||||
.Dd May 28, 2017
|
||||
.Dt GETDIRENTRIES 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -71,10 +71,11 @@ The data in the buffer is a series of
|
||||
.Vt dirent
|
||||
structures each containing the following entries:
|
||||
.Bd -literal -offset indent
|
||||
uint32_t d_fileno;
|
||||
uint16_t d_reclen;
|
||||
uint8_t d_type;
|
||||
uint8_t d_namlen;
|
||||
ino_t d_fileno;
|
||||
off_t d_off;
|
||||
uint16_t d_reclen;
|
||||
uint8_t d_type;
|
||||
uint16_t d_namlen;
|
||||
char d_name[MAXNAMLEN + 1]; /* see below */
|
||||
.Ed
|
||||
.Pp
|
||||
@ -124,7 +125,10 @@ or
|
||||
A value of zero is returned when
|
||||
the end of the directory has been reached.
|
||||
.Pp
|
||||
The
|
||||
If the
|
||||
.Fa basep
|
||||
pointer value is non-NULL ,
|
||||
the
|
||||
.Fn getdirentries
|
||||
system call writes the position of the block read into the location pointed to by
|
||||
.Fa basep .
|
||||
@ -157,7 +161,7 @@ is not a valid file descriptor open for reading.
|
||||
.It Bq Er EFAULT
|
||||
Either
|
||||
.Fa buf
|
||||
or
|
||||
or non-NULL
|
||||
.Fa basep
|
||||
point outside the allocated address space.
|
||||
.It Bq Er EINVAL
|
||||
|
@ -1,18 +1,13 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR:H}/resolv
|
||||
|
||||
PACKAGE= tests
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/lib/libc/nss
|
||||
|
||||
BINDIR= ${TESTSDIR}
|
||||
|
||||
.PATH: ${.CURDIR:H}/resolv
|
||||
|
||||
${PACKAGE}FILES+= mach
|
||||
|
||||
WARNS?= 1
|
||||
CFLAGS+= -I${SRCTOP}/tests
|
||||
|
||||
ATF_TESTS_C+= getaddrinfo_test
|
||||
ATF_TESTS_C+= getgr_test
|
||||
ATF_TESTS_C+= gethostby_test
|
||||
@ -23,4 +18,10 @@ ATF_TESTS_C+= getrpc_test
|
||||
ATF_TESTS_C+= getserv_test
|
||||
ATF_TESTS_C+= getusershell_test
|
||||
|
||||
${PACKAGE}FILES+= mach
|
||||
|
||||
WARNS?= 3
|
||||
|
||||
CFLAGS+= -I${SRCTOP}/tests
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
@ -125,7 +125,8 @@ compare_addrinfo_(struct addrinfo *ai1, struct addrinfo *ai2)
|
||||
}
|
||||
|
||||
static int
|
||||
compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, void *mdata)
|
||||
compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2,
|
||||
void *mdata __unused)
|
||||
{
|
||||
int rv;
|
||||
|
||||
@ -144,7 +145,7 @@ compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, void *mdata)
|
||||
return (rv);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
free_addrinfo(struct addrinfo *ai)
|
||||
{
|
||||
if (ai == NULL)
|
||||
@ -164,30 +165,30 @@ sdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen)
|
||||
ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol,
|
||||
ai->ai_addrlen);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
written = snprintf(buffer, buflen, "%s ",
|
||||
ai->ai_canonname == NULL ? "(null)" : ai->ai_canonname);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
if (ai->ai_addr == NULL) {
|
||||
written = snprintf(buffer, buflen, "(null)");
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
} else {
|
||||
for (i = 0; i < ai->ai_addrlen; i++) {
|
||||
for (i = 0; i < (int)ai->ai_addrlen; i++) {
|
||||
written = snprintf(buffer, buflen,
|
||||
i + 1 != ai->ai_addrlen ? "%d." : "%d",
|
||||
i + 1 != (int)ai->ai_addrlen ? "%d." : "%d",
|
||||
((unsigned char *)ai->ai_addr)[i]);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
@ -199,7 +200,7 @@ sdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen)
|
||||
if (ai->ai_next != NULL) {
|
||||
written = snprintf(buffer, buflen, ":");
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
@ -309,12 +310,11 @@ addrinfo_read_snapshot_func(struct addrinfo *ai, char *line)
|
||||
{
|
||||
struct addrinfo *ai2;
|
||||
char *s, *ps;
|
||||
int i, rv;
|
||||
int rv;
|
||||
|
||||
printf("1 line read from snapshot:\n%s\n", line);
|
||||
|
||||
rv = 0;
|
||||
i = 0;
|
||||
ps = line;
|
||||
|
||||
s = strsep(&ps, ":");
|
||||
@ -344,7 +344,7 @@ addrinfo_read_snapshot_func(struct addrinfo *ai, char *line)
|
||||
}
|
||||
|
||||
static int
|
||||
addrinfo_test_correctness(struct addrinfo *ai, void *mdata)
|
||||
addrinfo_test_correctness(struct addrinfo *ai, void *mdata __unused)
|
||||
{
|
||||
|
||||
printf("testing correctness with the following data:\n");
|
||||
@ -409,12 +409,20 @@ addrinfo_read_hostlist_func(struct addrinfo *ai, char *line)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
run_tests(char *hostlist_file, char *snapshot_file, int ai_family)
|
||||
static void
|
||||
run_tests(char *hostlist_file, const char *snapshot_file, int ai_family)
|
||||
{
|
||||
struct addrinfo_test_data td, td_snap;
|
||||
char *snapshot_file_copy;
|
||||
int rv;
|
||||
|
||||
if (snapshot_file == NULL)
|
||||
snapshot_file_copy = NULL;
|
||||
else {
|
||||
snapshot_file_copy = strdup(snapshot_file);
|
||||
ATF_REQUIRE(snapshot_file_copy != NULL);
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = ai_family;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
@ -477,24 +485,17 @@ run_tests(char *hostlist_file, char *snapshot_file, int ai_family)
|
||||
TEST_DATA_DESTROY(addrinfo, &td_snap);
|
||||
TEST_DATA_DESTROY(addrinfo, &td);
|
||||
|
||||
free(hostlist_file);
|
||||
free(snapshot_file);
|
||||
free(snapshot_file_copy);
|
||||
}
|
||||
|
||||
#define HOSTLIST_FILE "mach"
|
||||
#define RUN_TESTS(tc, snapshot_file, ai_family) do { \
|
||||
char *_hostlist_file; \
|
||||
char *_snapshot_file; \
|
||||
ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \
|
||||
atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \
|
||||
if (snapshot_file == NULL) \
|
||||
_snapshot_file = NULL; \
|
||||
else { \
|
||||
_snapshot_file = strdup(snapshot_file); \
|
||||
ATF_REQUIRE(_snapshot_file != NULL); \
|
||||
} \
|
||||
run_tests(_hostlist_file, _snapshot_file, ai_family); \
|
||||
} while(0)
|
||||
run_tests(_hostlist_file, snapshot_file, ai_family); \
|
||||
free(_hostlist_file); \
|
||||
} while (0)
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(pf_unspec);
|
||||
ATF_TC_BODY(pf_unspec, tc)
|
||||
|
@ -49,8 +49,6 @@ enum test_methods {
|
||||
TEST_BUILD_SNAPSHOT = 16,
|
||||
};
|
||||
|
||||
static enum test_methods method = TEST_BUILD_SNAPSHOT;
|
||||
|
||||
DECLARE_TEST_DATA(group)
|
||||
DECLARE_TEST_FILE_SNAPSHOT(group)
|
||||
DECLARE_1PASS_TEST(group)
|
||||
@ -104,7 +102,7 @@ clone_group(struct group *dest, struct group const *src)
|
||||
for (cp = src->gr_mem; *cp; ++cp)
|
||||
++members_num;
|
||||
|
||||
dest->gr_mem = calloc(1, (members_num + 1) * sizeof(char *));
|
||||
dest->gr_mem = calloc(members_num + 1, sizeof(char *));
|
||||
ATF_REQUIRE(dest->gr_mem != NULL);
|
||||
|
||||
for (cp = src->gr_mem; *cp; ++cp) {
|
||||
@ -179,7 +177,7 @@ sdump_group(struct group *grp, char *buffer, size_t buflen)
|
||||
written = snprintf(buffer, buflen, "%s:%s:%d:",
|
||||
grp->gr_name, grp->gr_passwd, grp->gr_gid);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
@ -189,7 +187,7 @@ sdump_group(struct group *grp, char *buffer, size_t buflen)
|
||||
written = snprintf(buffer, buflen, "%s%s",
|
||||
cp == grp->gr_mem ? "" : ",", *cp);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
@ -309,7 +307,7 @@ group_fill_test_data(struct group_test_data *td)
|
||||
}
|
||||
|
||||
static int
|
||||
group_test_correctness(struct group *grp, void *mdata)
|
||||
group_test_correctness(struct group *grp, void *mdata __unused)
|
||||
{
|
||||
printf("testing correctness with the following data:\n");
|
||||
dump_group(grp);
|
||||
@ -387,7 +385,7 @@ group_test_getgrgid(struct group *grp_model, void *mdata)
|
||||
}
|
||||
|
||||
static int
|
||||
group_test_getgrent(struct group *grp, void *mdata)
|
||||
group_test_getgrent(struct group *grp, void *mdata __unused)
|
||||
{
|
||||
/* Only correctness can be checked when doing 1-pass test for
|
||||
* getgrent(). */
|
||||
|
@ -87,8 +87,6 @@ static int hostent_test_gethostbyaddr(struct hostent *, void *);
|
||||
static int hostent_test_getaddrinfo_eq(struct hostent *, void *);
|
||||
static int hostent_test_getnameinfo_eq(struct hostent *, void *);
|
||||
|
||||
static void usage(void) __attribute__((__noreturn__));
|
||||
|
||||
IMPLEMENT_TEST_DATA(hostent)
|
||||
IMPLEMENT_TEST_FILE_SNAPSHOT(hostent)
|
||||
IMPLEMENT_1PASS_TEST(hostent)
|
||||
@ -163,8 +161,7 @@ clone_hostent(struct hostent *dest, struct hostent const *src)
|
||||
for (cp = src->h_aliases; *cp; ++cp)
|
||||
++aliases_num;
|
||||
|
||||
dest->h_aliases = calloc(1, (aliases_num + 1) *
|
||||
sizeof(char *));
|
||||
dest->h_aliases = calloc(aliases_num + 1, sizeof(char *));
|
||||
ATF_REQUIRE(dest->h_aliases != NULL);
|
||||
|
||||
for (cp = src->h_aliases; *cp; ++cp) {
|
||||
@ -178,7 +175,7 @@ clone_hostent(struct hostent *dest, struct hostent const *src)
|
||||
for (cp = src->h_addr_list; *cp; ++cp)
|
||||
++addrs_num;
|
||||
|
||||
dest->h_addr_list = calloc(1, (addrs_num + 1) * sizeof(char *));
|
||||
dest->h_addr_list = calloc(addrs_num + 1, sizeof(char *));
|
||||
ATF_REQUIRE(dest->h_addr_list != NULL);
|
||||
|
||||
for (cp = src->h_addr_list; *cp; ++cp) {
|
||||
@ -413,7 +410,7 @@ sdump_hostent(struct hostent *ht, char *buffer, size_t buflen)
|
||||
written = snprintf(buffer, buflen, "%s %d %d",
|
||||
ht->h_name, ht->h_addrtype, ht->h_length);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
@ -422,7 +419,7 @@ sdump_hostent(struct hostent *ht, char *buffer, size_t buflen)
|
||||
for (cp = ht->h_aliases; *cp; ++cp) {
|
||||
written = snprintf(buffer, buflen, " %s",*cp);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
@ -432,59 +429,61 @@ sdump_hostent(struct hostent *ht, char *buffer, size_t buflen)
|
||||
} else {
|
||||
written = snprintf(buffer, buflen, " noaliases");
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
}
|
||||
} else {
|
||||
written = snprintf(buffer, buflen, " (null)");
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
}
|
||||
|
||||
written = snprintf(buffer, buflen, " : ");
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
if (ht->h_addr_list != NULL) {
|
||||
if (*(ht->h_addr_list) != NULL) {
|
||||
for (cp = ht->h_addr_list; *cp; ++cp) {
|
||||
for (i = 0; i < ht->h_length; ++i ) {
|
||||
written = snprintf(buffer, buflen,
|
||||
i + 1 != ht->h_length ? "%d." : "%d",
|
||||
(unsigned char)(*cp)[i]);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
for (i = 0; i < (size_t)ht->h_length; ++i) {
|
||||
written = snprintf(buffer, buflen,
|
||||
i + 1 != (size_t)ht->h_length ?
|
||||
"%d." : "%d",
|
||||
(unsigned char)(*cp)[i]);
|
||||
buffer += written;
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
if (buflen == 0)
|
||||
return;
|
||||
}
|
||||
if (buflen == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (*(cp + 1) ) {
|
||||
written = snprintf(buffer, buflen, " ");
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
}
|
||||
if (*(cp + 1)) {
|
||||
written = snprintf(buffer, buflen,
|
||||
" ");
|
||||
buffer += written;
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
written = snprintf(buffer, buflen, " noaddrs");
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
}
|
||||
} else {
|
||||
written = snprintf(buffer, buflen, " (null)");
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
}
|
||||
@ -676,7 +675,7 @@ dump_hostent(struct hostent *result)
|
||||
}
|
||||
|
||||
static int
|
||||
hostent_test_correctness(struct hostent *ht, void *mdata)
|
||||
hostent_test_correctness(struct hostent *ht, void *mdata __unused)
|
||||
{
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -759,7 +758,7 @@ hostent_test_gethostbyaddr(struct hostent *he, void *mdata)
|
||||
}
|
||||
|
||||
static int
|
||||
hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata)
|
||||
hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata __unused)
|
||||
{
|
||||
struct addrinfo *ai, hints;
|
||||
int rv;
|
||||
@ -777,28 +776,30 @@ hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata)
|
||||
rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
|
||||
if (rv == 0) {
|
||||
printf("not ok - shouldn't have been resolved\n");
|
||||
return (-1);
|
||||
}
|
||||
rv = -1;
|
||||
} else
|
||||
rv = 0;
|
||||
} else {
|
||||
rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
|
||||
if (rv != 0) {
|
||||
printf("not ok - should have been resolved\n");
|
||||
return (-1);
|
||||
rv = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = is_hostent_equal(he, ai);
|
||||
if (rv != 0) {
|
||||
printf("not ok - addrinfo and hostent are not equal\n");
|
||||
return (-1);
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (0);
|
||||
done:
|
||||
if (ai != NULL)
|
||||
freeaddrinfo(ai);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
hostent_test_getnameinfo_eq(struct hostent *he, void *mdata)
|
||||
hostent_test_getnameinfo_eq(struct hostent *he, void *mdata __unused)
|
||||
{
|
||||
char **cp;
|
||||
char buffer[NI_MAXHOST];
|
||||
@ -885,7 +886,7 @@ hostent_test_getnameinfo_eq(struct hostent *he, void *mdata)
|
||||
* An address might reverse resolve to hostname alias or the
|
||||
* official hostname, e.g. moon.vub.ac.be.
|
||||
*/
|
||||
bool found_a_match;
|
||||
bool found_a_match = false;
|
||||
|
||||
if (strcmp(result->h_name, buffer) == 0) {
|
||||
found_a_match = true;
|
||||
@ -921,15 +922,24 @@ hostent_test_getnameinfo_eq(struct hostent *he, void *mdata)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
run_tests(const char *hostlist_file, const char *snapshot_file, int af_type,
|
||||
static int
|
||||
run_tests(const char *hostlist_file, const char *snapshot_file, int _af_type,
|
||||
enum test_methods method, bool use_ipv6_mapping)
|
||||
{
|
||||
char *snapshot_file_copy;
|
||||
struct hostent_test_data td, td_addr, td_snap;
|
||||
res_state statp;
|
||||
int rv = -2;
|
||||
|
||||
switch (af_type) {
|
||||
if (snapshot_file == NULL)
|
||||
snapshot_file_copy = NULL;
|
||||
else {
|
||||
snapshot_file_copy = strdup(snapshot_file);
|
||||
ATF_REQUIRE(snapshot_file_copy != NULL);
|
||||
}
|
||||
snapshot_file = snapshot_file_copy;
|
||||
|
||||
switch (_af_type) {
|
||||
case AF_INET:
|
||||
ATF_REQUIRE_FEATURE("inet");
|
||||
ATF_REQUIRE(!use_ipv6_mapping);
|
||||
@ -938,7 +948,7 @@ run_tests(const char *hostlist_file, const char *snapshot_file, int af_type,
|
||||
ATF_REQUIRE_FEATURE("inet6");
|
||||
break;
|
||||
default:
|
||||
atf_tc_fail("unhandled address family: %d", af_type);
|
||||
atf_tc_fail("unhandled address family: %d", _af_type);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -947,8 +957,8 @@ run_tests(const char *hostlist_file, const char *snapshot_file, int af_type,
|
||||
if (statp == NULL || ((statp->options & RES_INIT) == 0 &&
|
||||
res_ninit(statp) == -1)) {
|
||||
printf("error: can't init res_state\n");
|
||||
|
||||
return (-1);
|
||||
rv = -1;
|
||||
goto fin2;
|
||||
}
|
||||
|
||||
if (use_ipv6_mapping)
|
||||
@ -1052,6 +1062,9 @@ run_tests(const char *hostlist_file, const char *snapshot_file, int af_type,
|
||||
TEST_DATA_DESTROY(hostent, &td_addr);
|
||||
TEST_DATA_DESTROY(hostent, &td);
|
||||
|
||||
fin2:
|
||||
free(snapshot_file_copy);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
@ -1060,30 +1073,24 @@ run_tests(const char *hostlist_file, const char *snapshot_file, int af_type,
|
||||
#define _RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
|
||||
do { \
|
||||
char *_hostlist_file; \
|
||||
char *_snapshot_file; \
|
||||
ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \
|
||||
atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \
|
||||
if (snapshot_file == NULL) \
|
||||
_snapshot_file = NULL; \
|
||||
else { \
|
||||
_snapshot_file = strdup(snapshot_file); \
|
||||
ATF_REQUIRE(_snapshot_file != NULL); \
|
||||
} \
|
||||
ATF_REQUIRE(run_tests(_hostlist_file, _snapshot_file, af_type, \
|
||||
ATF_REQUIRE(run_tests(_hostlist_file, snapshot_file, af_type, \
|
||||
method, use_ipv6_mapping) == 0); \
|
||||
} while(0)
|
||||
free(_hostlist_file); \
|
||||
} while (0)
|
||||
|
||||
#define RUN_HOST_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
|
||||
do { \
|
||||
use_ipnode_functions = false; \
|
||||
_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#define RUN_IPNODE_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
|
||||
do { \
|
||||
use_ipnode_functions = true; \
|
||||
_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4);
|
||||
ATF_TC_BODY(gethostbyaddr_ipv4, tc)
|
||||
|
@ -99,7 +99,7 @@ clone_protoent(struct protoent *dest, struct protoent const *src)
|
||||
for (cp = src->p_aliases; *cp; ++cp)
|
||||
++aliases_num;
|
||||
|
||||
dest->p_aliases = calloc(1, (aliases_num+1) * sizeof(char *));
|
||||
dest->p_aliases = calloc(aliases_num + 1, sizeof(char *));
|
||||
assert(dest->p_aliases != NULL);
|
||||
|
||||
for (cp = src->p_aliases; *cp; ++cp) {
|
||||
@ -172,16 +172,16 @@ sdump_protoent(struct protoent *pe, char *buffer, size_t buflen)
|
||||
written = snprintf(buffer, buflen, "%s %d",
|
||||
pe->p_name, pe->p_proto);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
if (pe->p_aliases != NULL) {
|
||||
if (*(pe->p_aliases) != '\0') {
|
||||
for (cp = pe->p_aliases; *cp; ++cp) {
|
||||
written = snprintf(buffer, buflen, " %s",*cp);
|
||||
written = snprintf(buffer, buflen, " %s", *cp);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
@ -288,7 +288,7 @@ protoent_fill_test_data(struct protoent_test_data *td)
|
||||
}
|
||||
|
||||
static int
|
||||
protoent_test_correctness(struct protoent *pe, void *mdata)
|
||||
protoent_test_correctness(struct protoent *pe, void *mdata __unused)
|
||||
{
|
||||
printf("testing correctness with the following data:\n");
|
||||
dump_protoent(pe);
|
||||
@ -388,14 +388,14 @@ protoent_test_getprotobynumber(struct protoent *pe_model, void *mdata)
|
||||
}
|
||||
|
||||
static int
|
||||
protoent_test_getprotoent(struct protoent *pe, void *mdata)
|
||||
protoent_test_getprotoent(struct protoent *pe, void *mdata __unused)
|
||||
{
|
||||
/* Only correctness can be checked when doing 1-pass test for
|
||||
* getprotoent(). */
|
||||
return (protoent_test_correctness(pe, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
run_tests(const char *snapshot_file, enum test_methods method)
|
||||
{
|
||||
struct protoent_test_data td, td_snap, td_2pass;
|
||||
|
@ -47,8 +47,6 @@ enum test_methods {
|
||||
TEST_BUILD_SNAPSHOT
|
||||
};
|
||||
|
||||
static enum test_methods method = TEST_BUILD_SNAPSHOT;
|
||||
|
||||
DECLARE_TEST_DATA(passwd)
|
||||
DECLARE_TEST_FILE_SNAPSHOT(passwd)
|
||||
DECLARE_1PASS_TEST(passwd)
|
||||
@ -59,7 +57,9 @@ static int compare_passwd(struct passwd *, struct passwd *, void *);
|
||||
static void free_passwd(struct passwd *);
|
||||
|
||||
static void sdump_passwd(struct passwd *, char *, size_t);
|
||||
#ifdef DEBUG
|
||||
static void dump_passwd(struct passwd *);
|
||||
#endif
|
||||
|
||||
static int passwd_read_snapshot_func(struct passwd *, char *);
|
||||
|
||||
@ -97,7 +97,7 @@ clone_passwd(struct passwd *dest, struct passwd const *src)
|
||||
}
|
||||
|
||||
static int
|
||||
compare_passwd(struct passwd *pwd1, struct passwd *pwd2, void *mdata)
|
||||
compare_passwd(struct passwd *pwd1, struct passwd *pwd2, void *mdata __unused)
|
||||
{
|
||||
ATF_REQUIRE(pwd1 != NULL);
|
||||
ATF_REQUIRE(pwd2 != NULL);
|
||||
@ -142,6 +142,7 @@ sdump_passwd(struct passwd *pwd, char *buffer, size_t buflen)
|
||||
pwd->pw_fields);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
dump_passwd(struct passwd *pwd)
|
||||
{
|
||||
@ -152,6 +153,7 @@ dump_passwd(struct passwd *pwd)
|
||||
} else
|
||||
printf("(null)\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
passwd_read_snapshot_func(struct passwd *pwd, char *line)
|
||||
@ -251,7 +253,7 @@ passwd_fill_test_data(struct passwd_test_data *td)
|
||||
}
|
||||
|
||||
static int
|
||||
passwd_test_correctness(struct passwd *pwd, void *mdata)
|
||||
passwd_test_correctness(struct passwd *pwd, void *mdata __unused)
|
||||
{
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -363,7 +365,7 @@ passwd_test_getpwuid(struct passwd *pwd_model, void *mdata)
|
||||
}
|
||||
|
||||
static int
|
||||
passwd_test_getpwent(struct passwd *pwd, void *mdata)
|
||||
passwd_test_getpwent(struct passwd *pwd, void *mdata __unused)
|
||||
{
|
||||
/* Only correctness can be checked when doing 1-pass test for
|
||||
* getpwent(). */
|
||||
|
@ -70,8 +70,6 @@ static int rpcent_test_getrpcbyname(struct rpcent *, void *);
|
||||
static int rpcent_test_getrpcbynumber(struct rpcent *, void *);
|
||||
static int rpcent_test_getrpcent(struct rpcent *, void *);
|
||||
|
||||
static void usage(void) __attribute__((__noreturn__));
|
||||
|
||||
IMPLEMENT_TEST_DATA(rpcent)
|
||||
IMPLEMENT_TEST_FILE_SNAPSHOT(rpcent)
|
||||
IMPLEMENT_1PASS_TEST(rpcent)
|
||||
@ -100,7 +98,7 @@ clone_rpcent(struct rpcent *dest, struct rpcent const *src)
|
||||
for (cp = src->r_aliases; *cp; ++cp)
|
||||
++aliases_num;
|
||||
|
||||
dest->r_aliases = calloc(1, (aliases_num + 1) * sizeof(char *));
|
||||
dest->r_aliases = calloc(aliases_num + 1, sizeof(char *));
|
||||
ATF_REQUIRE(dest->r_aliases != NULL);
|
||||
|
||||
for (cp = src->r_aliases; *cp; ++cp) {
|
||||
@ -173,16 +171,16 @@ sdump_rpcent(struct rpcent *rpc, char *buffer, size_t buflen)
|
||||
written = snprintf(buffer, buflen, "%s %d",
|
||||
rpc->r_name, rpc->r_number);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
if (rpc->r_aliases != NULL) {
|
||||
if (*(rpc->r_aliases) != '\0') {
|
||||
for (cp = rpc->r_aliases; *cp; ++cp) {
|
||||
written = snprintf(buffer, buflen, " %s",*cp);
|
||||
written = snprintf(buffer, buflen, " %s", *cp);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
@ -289,7 +287,7 @@ rpcent_fill_test_data(struct rpcent_test_data *td)
|
||||
}
|
||||
|
||||
static int
|
||||
rpcent_test_correctness(struct rpcent *rpc, void *mdata)
|
||||
rpcent_test_correctness(struct rpcent *rpc, void *mdata __unused)
|
||||
{
|
||||
|
||||
printf("testing correctness with the following data:\n");
|
||||
@ -390,7 +388,7 @@ rpcent_test_getrpcbynumber(struct rpcent *rpc_model, void *mdata)
|
||||
}
|
||||
|
||||
static int
|
||||
rpcent_test_getrpcent(struct rpcent *rpc, void *mdata)
|
||||
rpcent_test_getrpcent(struct rpcent *rpc, void *mdata __unused)
|
||||
{
|
||||
|
||||
/*
|
||||
@ -400,7 +398,7 @@ rpcent_test_getrpcent(struct rpcent *rpc, void *mdata)
|
||||
return (rpcent_test_correctness(rpc, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
run_tests(const char *snapshot_file, enum test_methods method)
|
||||
{
|
||||
struct rpcent_test_data td, td_snap, td_2pass;
|
||||
|
@ -102,7 +102,7 @@ clone_servent(struct servent *dest, struct servent const *src)
|
||||
for (cp = src->s_aliases; *cp; ++cp)
|
||||
++aliases_num;
|
||||
|
||||
dest->s_aliases = calloc(1, (aliases_num + 1) * sizeof(char *));
|
||||
dest->s_aliases = calloc(aliases_num + 1, sizeof(char *));
|
||||
ATF_REQUIRE(dest->s_aliases != NULL);
|
||||
|
||||
for (cp = src->s_aliases; *cp; ++cp) {
|
||||
@ -177,16 +177,16 @@ sdump_servent(struct servent *serv, char *buffer, size_t buflen)
|
||||
written = snprintf(buffer, buflen, "%s %d %s",
|
||||
serv->s_name, ntohs(serv->s_port), serv->s_proto);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
if (serv->s_aliases != NULL) {
|
||||
if (*(serv->s_aliases) != '\0') {
|
||||
for (cp = serv->s_aliases; *cp; ++cp) {
|
||||
written = snprintf(buffer, buflen, " %s",*cp);
|
||||
written = snprintf(buffer, buflen, " %s", *cp);
|
||||
buffer += written;
|
||||
if (written > buflen)
|
||||
if (written > (int)buflen)
|
||||
return;
|
||||
buflen -= written;
|
||||
|
||||
@ -300,7 +300,7 @@ servent_fill_test_data(struct servent_test_data *td)
|
||||
}
|
||||
|
||||
static int
|
||||
servent_test_correctness(struct servent *serv, void *mdata)
|
||||
servent_test_correctness(struct servent *serv, void *mdata __unused)
|
||||
{
|
||||
printf("testing correctness with the following data:\n");
|
||||
dump_servent(serv);
|
||||
@ -403,14 +403,14 @@ servent_test_getservbyport(struct servent *serv_model, void *mdata)
|
||||
}
|
||||
|
||||
static int
|
||||
servent_test_getservent(struct servent *serv, void *mdata)
|
||||
servent_test_getservent(struct servent *serv, void *mdata __unused)
|
||||
{
|
||||
/* Only correctness can be checked when doing 1-pass test for
|
||||
* getservent(). */
|
||||
return (servent_test_correctness(serv, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
run_tests(const char *snapshot_file, enum test_methods method)
|
||||
{
|
||||
struct servent_test_data td, td_snap, td_2pass;
|
||||
|
@ -48,8 +48,6 @@ struct usershell {
|
||||
char *path;
|
||||
};
|
||||
|
||||
static enum test_methods method = TEST_GETUSERSHELL;
|
||||
|
||||
DECLARE_TEST_DATA(usershell)
|
||||
DECLARE_TEST_FILE_SNAPSHOT(usershell)
|
||||
DECLARE_2PASS_TEST(usershell)
|
||||
@ -78,7 +76,8 @@ clone_usershell(struct usershell *dest, struct usershell const *src)
|
||||
}
|
||||
|
||||
static int
|
||||
compare_usershell(struct usershell *us1, struct usershell *us2, void *mdata)
|
||||
compare_usershell(struct usershell *us1, struct usershell *us2,
|
||||
void *mdata __unused)
|
||||
{
|
||||
int rv;
|
||||
|
||||
@ -134,7 +133,7 @@ usershell_read_snapshot_func(struct usershell *us, char *line)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
run_tests(const char *snapshot_file, enum test_methods method)
|
||||
{
|
||||
struct usershell_test_data td, td_snap;
|
||||
|
@ -87,8 +87,6 @@ geom_stats_open(void)
|
||||
if (statsfd < 0)
|
||||
return (errno);
|
||||
pagesize = getpagesize();
|
||||
if (pagesize == -1)
|
||||
return (errno);
|
||||
spp = pagesize / sizeof(struct devstat);
|
||||
p = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, statsfd, 0);
|
||||
if (p == MAP_FAILED) {
|
||||
|
@ -56,6 +56,8 @@ ATF_TC_BODY(kvm_geterr_negative_test_NULL, tc)
|
||||
ATF_REQUIRE(!errbuf_has_error(kvm_geterr(NULL)));
|
||||
}
|
||||
|
||||
/* 1100090 was where kvm_open2(3) was introduced. */
|
||||
#if __FreeBSD_version >= 1100091
|
||||
ATF_TC(kvm_geterr_positive_test_error);
|
||||
ATF_TC_HEAD(kvm_geterr_positive_test_error, tc)
|
||||
{
|
||||
@ -125,13 +127,16 @@ ATF_TC_BODY(kvm_geterr_positive_test_no_error, tc)
|
||||
ATF_REQUIRE_MSG(kvm_close(kd) == 0, "kvm_close failed: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
ATF_TP_ADD_TC(tp, kvm_geterr_negative_test_NULL);
|
||||
#if __FreeBSD_version >= 1100091
|
||||
ATF_TP_ADD_TC(tp, kvm_geterr_positive_test_error);
|
||||
ATF_TP_ADD_TC(tp, kvm_geterr_positive_test_no_error);
|
||||
#endif
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ ATF_TEST_CASE_BODY(dnvlist_get_string__default_value)
|
||||
|
||||
ATF_REQUIRE_EQ(strcmp(dnvlist_get_string(nvl, "hthth", "fd"), "fd"), 0);
|
||||
actual_value = dnvlist_get_string(nvl, "5", "5");
|
||||
ATF_REQUIRE_EQ(strcmp("5", "5"), 0);
|
||||
ATF_REQUIRE_EQ(strcmp(actual_value, "5"), 0);
|
||||
|
||||
nvlist_destroy(nvl);
|
||||
}
|
||||
@ -391,6 +391,7 @@ ATF_TEST_CASE_BODY(dnvlist_take_string__empty)
|
||||
ATF_REQUIRE_EQ(strcmp(actual_val, default_val), 0);
|
||||
|
||||
free(actual_val);
|
||||
free(default_val);
|
||||
nvlist_destroy(nvl);
|
||||
}
|
||||
|
||||
@ -408,6 +409,7 @@ ATF_TEST_CASE_BODY(dnvlist_take_string__default_value)
|
||||
ATF_REQUIRE_EQ(strcmp(actual_val, default_val), 0);
|
||||
|
||||
free(actual_val);
|
||||
free(default_val);
|
||||
nvlist_destroy(nvl);
|
||||
}
|
||||
|
||||
@ -496,6 +498,7 @@ ATF_TEST_CASE_BODY(dnvlist_take_binary__present)
|
||||
|
||||
free(actual_val);
|
||||
free(default_val);
|
||||
free(value);
|
||||
nvlist_destroy(nvl);
|
||||
}
|
||||
|
||||
@ -515,6 +518,7 @@ ATF_TEST_CASE_BODY(dnvlist_take_binary__empty)
|
||||
ATF_REQUIRE_EQ(memcmp(actual_val, default_val, actual_size), 0);
|
||||
|
||||
free(actual_val);
|
||||
free(default_val);
|
||||
nvlist_destroy(nvl);
|
||||
}
|
||||
|
||||
@ -535,6 +539,7 @@ ATF_TEST_CASE_BODY(dnvlist_take_binary__default_value)
|
||||
ATF_REQUIRE_EQ(memcmp(actual_val, default_val, default_size), 0);
|
||||
|
||||
free(actual_val);
|
||||
free(default_val);
|
||||
nvlist_destroy(nvl);
|
||||
}
|
||||
|
||||
|
@ -640,6 +640,7 @@ ATF_TEST_CASE_BODY(nvlist_unpack__duplicate_key)
|
||||
nvlist_add_number(nvl, key2, 10);
|
||||
|
||||
packed = nvlist_pack(nvl, &size);
|
||||
ATF_REQUIRE(packed != NULL);
|
||||
|
||||
/*
|
||||
* Mangle the packed nvlist by replacing key1 with key2, creating a
|
||||
|
@ -6,7 +6,6 @@ FBSD_1.2 {
|
||||
procstat_freefiles;
|
||||
procstat_freeprocs;
|
||||
procstat_get_pipe_info;
|
||||
procstat_get_socket_info;
|
||||
procstat_getfiles;
|
||||
procstat_getprocs;
|
||||
procstat_open_kvm;
|
||||
@ -39,5 +38,6 @@ FBSD_1.5 {
|
||||
procstat_get_pts_info;
|
||||
procstat_get_sem_info;
|
||||
procstat_get_shm_info;
|
||||
procstat_get_socket_info;
|
||||
procstat_get_vnode_info;
|
||||
};
|
||||
|
@ -1497,6 +1497,8 @@ procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst,
|
||||
} else
|
||||
sock->inp_ppcb =
|
||||
(uintptr_t)inpcb.inp_ppcb;
|
||||
sock->sendq = s.so_snd.sb_ccc;
|
||||
sock->recvq = s.so_rcv.sb_ccc;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1510,6 +1512,8 @@ procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst,
|
||||
sock->so_rcv_sb_state = s.so_rcv.sb_state;
|
||||
sock->so_snd_sb_state = s.so_snd.sb_state;
|
||||
sock->unp_conn = (uintptr_t)unpcb.unp_conn;
|
||||
sock->sendq = s.so_snd.sb_ccc;
|
||||
sock->recvq = s.so_rcv.sb_ccc;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1556,17 +1560,22 @@ procstat_get_socket_info_sysctl(struct filestat *fst, struct sockstat *sock,
|
||||
switch(sock->dom_family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
if (sock->proto == IPPROTO_TCP)
|
||||
if (sock->proto == IPPROTO_TCP) {
|
||||
sock->inp_ppcb = kif->kf_un.kf_sock.kf_sock_inpcb;
|
||||
sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq;
|
||||
sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq;
|
||||
}
|
||||
break;
|
||||
case AF_UNIX:
|
||||
if (kif->kf_un.kf_sock.kf_sock_unpconn != 0) {
|
||||
sock->so_rcv_sb_state =
|
||||
kif->kf_un.kf_sock.kf_sock_rcv_sb_state;
|
||||
sock->so_snd_sb_state =
|
||||
kif->kf_un.kf_sock.kf_sock_snd_sb_state;
|
||||
sock->unp_conn =
|
||||
kif->kf_un.kf_sock.kf_sock_unpconn;
|
||||
sock->so_rcv_sb_state =
|
||||
kif->kf_un.kf_sock.kf_sock_rcv_sb_state;
|
||||
sock->so_snd_sb_state =
|
||||
kif->kf_un.kf_sock.kf_sock_snd_sb_state;
|
||||
sock->unp_conn =
|
||||
kif->kf_un.kf_sock.kf_sock_unpconn;
|
||||
sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq;
|
||||
sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -157,6 +157,8 @@ struct sockstat {
|
||||
struct sockaddr_storage sa_peer; /* Peer address. */
|
||||
int type;
|
||||
char dname[32];
|
||||
unsigned int sendq;
|
||||
unsigned int recvq;
|
||||
};
|
||||
|
||||
STAILQ_HEAD(filestat_list, filestat);
|
||||
|
@ -60,12 +60,29 @@ struct freebsd11_shmstat {
|
||||
uint16_t mode;
|
||||
};
|
||||
|
||||
struct freebsd11_sockstat {
|
||||
uint64_t inp_ppcb;
|
||||
uint64_t so_addr;
|
||||
uint64_t so_pcb;
|
||||
uint64_t unp_conn;
|
||||
int dom_family;
|
||||
int proto;
|
||||
int so_rcv_sb_state;
|
||||
int so_snd_sb_state;
|
||||
struct sockaddr_storage sa_local; /* Socket address. */
|
||||
struct sockaddr_storage sa_peer; /* Peer address. */
|
||||
int type;
|
||||
char dname[32];
|
||||
};
|
||||
|
||||
int freebsd11_procstat_get_pts_info(struct procstat *procstat,
|
||||
struct filestat *fst, struct freebsd11_ptsstat *pts, char *errbuf);
|
||||
int freebsd11_procstat_get_sem_info(struct procstat *procstat,
|
||||
struct filestat *fst, struct freebsd11_semstat *sem, char *errbuf);
|
||||
int freebsd11_procstat_get_shm_info(struct procstat *procstat,
|
||||
struct filestat *fst, struct freebsd11_shmstat *shm, char *errbuf);
|
||||
int freebsd11_procstat_get_socket_info(struct procstat *procstat,
|
||||
struct filestat *fst, struct freebsd11_sockstat *sock, char *errbuf);
|
||||
int freebsd11_procstat_get_vnode_info(struct procstat *procstat,
|
||||
struct filestat *fst, struct freebsd11_vnstat *vn, char *errbuf);
|
||||
|
||||
@ -115,6 +132,31 @@ freebsd11_procstat_get_shm_info(struct procstat *procstat,
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd11_procstat_get_socket_info(struct procstat *procstat, struct filestat *fst,
|
||||
struct freebsd11_sockstat *sock_compat, char *errbuf)
|
||||
{
|
||||
struct sockstat sock;
|
||||
int r;
|
||||
|
||||
r = procstat_get_socket_info(procstat, fst, &sock, errbuf);
|
||||
if (r != 0)
|
||||
return (r);
|
||||
sock_compat->inp_ppcb = sock.inp_ppcb;
|
||||
sock_compat->so_addr = sock.so_addr;
|
||||
sock_compat->so_pcb = sock.so_pcb;
|
||||
sock_compat->unp_conn = sock.unp_conn;
|
||||
sock_compat->dom_family = sock.dom_family;
|
||||
sock_compat->proto = sock.proto;
|
||||
sock_compat->so_rcv_sb_state = sock.so_rcv_sb_state;
|
||||
sock_compat->so_snd_sb_state = sock.so_snd_sb_state;
|
||||
sock_compat->sa_local = sock.sa_local;
|
||||
sock_compat->sa_peer = sock.sa_peer;
|
||||
sock_compat->type = sock.type;
|
||||
memcpy(sock_compat->dname, sock.dname, sizeof(sock.dname));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd11_procstat_get_vnode_info(struct procstat *procstat,
|
||||
struct filestat *fst, struct freebsd11_vnstat *vn_compat, char *errbuf)
|
||||
@ -138,6 +180,8 @@ freebsd11_procstat_get_vnode_info(struct procstat *procstat,
|
||||
}
|
||||
|
||||
__sym_compat(procstat_get_pts_info, freebsd11_procstat_get_pts_info, FBSD_1.2);
|
||||
__sym_compat(procstat_get_socket_info, freebsd11_procstat_get_socket_info,
|
||||
FBSD_1.2);
|
||||
__sym_compat(procstat_get_vnode_info, freebsd11_procstat_get_vnode_info,
|
||||
FBSD_1.2);
|
||||
__sym_compat(procstat_get_sem_info, freebsd11_procstat_get_sem_info, FBSD_1.3);
|
||||
|
@ -93,9 +93,38 @@ struct in_addr dhcp_serverip;
|
||||
struct bootp *bootp_response;
|
||||
size_t bootp_response_size;
|
||||
|
||||
static void
|
||||
bootp_fill_request(unsigned char *bp_vend)
|
||||
{
|
||||
/*
|
||||
* We are booting from PXE, we want to send the string
|
||||
* 'PXEClient' to the DHCP server so you have the option of
|
||||
* only responding to PXE aware dhcp requests.
|
||||
*/
|
||||
bp_vend[0] = TAG_CLASSID;
|
||||
bp_vend[1] = 9;
|
||||
bcopy("PXEClient", &bp_vend[2], 9);
|
||||
bp_vend[11] = TAG_USER_CLASS;
|
||||
/* len of each user class + number of user class */
|
||||
bp_vend[12] = 8;
|
||||
/* len of the first user class */
|
||||
bp_vend[13] = 7;
|
||||
bcopy("FreeBSD", &bp_vend[14], 7);
|
||||
bp_vend[21] = TAG_PARAM_REQ;
|
||||
bp_vend[22] = 7;
|
||||
bp_vend[23] = TAG_ROOTPATH;
|
||||
bp_vend[24] = TAG_HOSTNAME;
|
||||
bp_vend[25] = TAG_SWAPSERVER;
|
||||
bp_vend[26] = TAG_GATEWAY;
|
||||
bp_vend[27] = TAG_SUBNET_MASK;
|
||||
bp_vend[28] = TAG_INTF_MTU;
|
||||
bp_vend[29] = TAG_SERVERID;
|
||||
bp_vend[30] = TAG_END;
|
||||
}
|
||||
|
||||
/* Fetch required bootp infomation */
|
||||
void
|
||||
bootp(int sock, int flag)
|
||||
bootp(int sock)
|
||||
{
|
||||
void *pkt;
|
||||
struct iodesc *d;
|
||||
@ -136,28 +165,8 @@ bootp(int sock, int flag)
|
||||
bp->bp_vend[4] = TAG_DHCP_MSGTYPE;
|
||||
bp->bp_vend[5] = 1;
|
||||
bp->bp_vend[6] = DHCPDISCOVER;
|
||||
bootp_fill_request(&bp->bp_vend[7]);
|
||||
|
||||
/*
|
||||
* If we are booting from PXE, we want to send the string
|
||||
* 'PXEClient' to the DHCP server so you have the option of
|
||||
* only responding to PXE aware dhcp requests.
|
||||
*/
|
||||
if (flag & BOOTP_PXE) {
|
||||
bp->bp_vend[7] = TAG_CLASSID;
|
||||
bp->bp_vend[8] = 9;
|
||||
bcopy("PXEClient", &bp->bp_vend[9], 9);
|
||||
bp->bp_vend[18] = TAG_PARAM_REQ;
|
||||
bp->bp_vend[19] = 7;
|
||||
bp->bp_vend[20] = TAG_ROOTPATH;
|
||||
bp->bp_vend[21] = TAG_HOSTNAME;
|
||||
bp->bp_vend[22] = TAG_SWAPSERVER;
|
||||
bp->bp_vend[23] = TAG_GATEWAY;
|
||||
bp->bp_vend[24] = TAG_SUBNET_MASK;
|
||||
bp->bp_vend[25] = TAG_INTF_MTU;
|
||||
bp->bp_vend[26] = TAG_SERVERID;
|
||||
bp->bp_vend[27] = TAG_END;
|
||||
} else
|
||||
bp->bp_vend[7] = TAG_END;
|
||||
#else
|
||||
bp->bp_vend[4] = TAG_END;
|
||||
#endif
|
||||
@ -193,13 +202,7 @@ bootp(int sock, int flag)
|
||||
bp->bp_vend[20] = 4;
|
||||
leasetime = htonl(300);
|
||||
bcopy(&leasetime, &bp->bp_vend[21], 4);
|
||||
if (flag & BOOTP_PXE) {
|
||||
bp->bp_vend[25] = TAG_CLASSID;
|
||||
bp->bp_vend[26] = 9;
|
||||
bcopy("PXEClient", &bp->bp_vend[27], 9);
|
||||
bp->bp_vend[36] = TAG_END;
|
||||
} else
|
||||
bp->bp_vend[25] = TAG_END;
|
||||
bootp_fill_request(&bp->bp_vend[25]);
|
||||
|
||||
expected_dhcpmsgtype = DHCPACK;
|
||||
|
||||
|
@ -108,6 +108,7 @@ struct bootp {
|
||||
#define TAG_T2 ((unsigned char) 59)
|
||||
#define TAG_CLASSID ((unsigned char) 60)
|
||||
#define TAG_CLIENTID ((unsigned char) 61)
|
||||
#define TAG_USER_CLASS ((unsigned char) 77)
|
||||
#endif
|
||||
|
||||
#define TAG_END ((unsigned char) 255)
|
||||
@ -122,12 +123,6 @@ struct bootp {
|
||||
#define DHCPRELEASE 7
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bootp flags
|
||||
*/
|
||||
#define BOOTP_NONE 0x0000 /* No flags */
|
||||
#define BOOTP_PXE 0x0001 /* Booting from PXE. */
|
||||
|
||||
/*
|
||||
* "vendor" data permitted for CMU bootp clients.
|
||||
*/
|
||||
|
@ -119,7 +119,7 @@ ssize_t sendrecv(struct iodesc *,
|
||||
void **, void **);
|
||||
|
||||
/* bootp/DHCP */
|
||||
void bootp(int, int);
|
||||
void bootp(int);
|
||||
|
||||
/* Utilities: */
|
||||
char *ether_sprintf(u_char *);
|
||||
|
@ -73,7 +73,8 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \
|
||||
s_nexttowardf.c s_remquo.c s_remquof.c \
|
||||
s_rint.c s_rintf.c s_round.c s_roundf.c \
|
||||
s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \
|
||||
s_signgam.c s_significand.c s_significandf.c s_sin.c s_sinf.c \
|
||||
s_signgam.c s_significand.c s_significandf.c s_sin.c \
|
||||
s_sincos.c s_sincosf.c s_sinf.c \
|
||||
s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_tgammaf.c s_trunc.c s_truncf.c \
|
||||
w_cabs.c w_cabsf.c w_drem.c w_dremf.c
|
||||
|
||||
@ -104,7 +105,8 @@ COMMON_SRCS+= catrigl.c \
|
||||
s_csqrtl.c s_erfl.c s_exp2l.c s_expl.c s_floorl.c s_fmal.c \
|
||||
s_fmaxl.c s_fminl.c s_frexpl.c s_logbl.c s_logl.c s_nanl.c \
|
||||
s_nextafterl.c s_nexttoward.c s_remquol.c s_rintl.c s_roundl.c \
|
||||
s_scalbnl.c s_sinl.c s_tanhl.c s_tanl.c s_truncl.c w_cabsl.c
|
||||
s_scalbnl.c s_sinl.c s_sincosl.c \
|
||||
s_tanhl.c s_tanl.c s_truncl.c w_cabsl.c
|
||||
.endif
|
||||
|
||||
# C99 complex functions
|
||||
@ -137,7 +139,8 @@ MAN= acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 \
|
||||
fma.3 fmax.3 fmod.3 hypot.3 ieee.3 ieee_test.3 ilogb.3 j0.3 \
|
||||
lgamma.3 log.3 lrint.3 lround.3 math.3 nan.3 \
|
||||
nextafter.3 remainder.3 rint.3 \
|
||||
round.3 scalbn.3 signbit.3 sin.3 sinh.3 sqrt.3 tan.3 tanh.3 trunc.3 \
|
||||
round.3 scalbn.3 signbit.3 sin.3 sincos.3 \
|
||||
sinh.3 sqrt.3 tan.3 tanh.3 trunc.3 \
|
||||
complex.3
|
||||
|
||||
MLINKS+=acos.3 acosf.3 acos.3 acosl.3
|
||||
@ -215,6 +218,7 @@ MLINKS+=round.3 roundf.3 round.3 roundl.3
|
||||
MLINKS+=scalbn.3 scalbln.3 scalbn.3 scalblnf.3 scalbn.3 scalblnl.3
|
||||
MLINKS+=scalbn.3 scalbnf.3 scalbn.3 scalbnl.3
|
||||
MLINKS+=sin.3 sinf.3 sin.3 sinl.3
|
||||
MLINKS+=sincos.3 sincosf.3 sin.3 sincosl.3
|
||||
MLINKS+=sinh.3 sinhf.3 sinh.3 sinhl.3
|
||||
MLINKS+=sqrt.3 cbrt.3 sqrt.3 cbrtf.3 sqrt.3 cbrtl.3 sqrt.3 sqrtf.3 \
|
||||
sqrt.3 sqrtl.3
|
||||
|
@ -294,4 +294,7 @@ FBSD_1.5 {
|
||||
casinl;
|
||||
catanl;
|
||||
catanhl;
|
||||
sincos;
|
||||
sincosf;
|
||||
sincosl;
|
||||
};
|
||||
|
82
lib/msun/man/sincos.3
Normal file
82
lib/msun/man/sincos.3
Normal file
@ -0,0 +1,82 @@
|
||||
.\" Copyright (c) 2011 Steven G. Kargl.
|
||||
.\"
|
||||
.\" 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 REGENTS 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.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 12, 2011
|
||||
.Dt SINCOS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sincos ,
|
||||
.Nm sincosf ,
|
||||
.Nm sincosl
|
||||
.Nd sine and cosine functions
|
||||
.Sh LIBRARY
|
||||
.Lb libm
|
||||
.Sh SYNOPSIS
|
||||
.In math.h
|
||||
.Ft void
|
||||
.Fn sincos "double x" "double *s" "double *c"
|
||||
.Ft void
|
||||
.Fn sincosf "float x" "float *s" "float *c"
|
||||
.Ft void
|
||||
.Fn sincosl "long double x" "long double *s" "long double *c"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn sincos ,
|
||||
.Fn sincosf ,
|
||||
and
|
||||
.Fn sincosl
|
||||
functions compute the sine and cosine of
|
||||
.Fa x .
|
||||
Using these functions allows argument reduction to occur only
|
||||
once instead of twice with individual invocations of
|
||||
.Fn sin
|
||||
and
|
||||
.Fn cos .
|
||||
Like
|
||||
.Fn sin
|
||||
and
|
||||
.Fn cos ,
|
||||
a large magnitude argument may yield a result with little
|
||||
or no significance.
|
||||
.Sh RETURN VALUES
|
||||
Upon returning from
|
||||
.Fn sincos ,
|
||||
.Fn sincosf ,
|
||||
and
|
||||
.Fn sincosl ,
|
||||
the memory pointed to by
|
||||
.Ar "*s"
|
||||
and
|
||||
.Ar "*c"
|
||||
are assigned the values of sine and cosine, respectively.
|
||||
.Sh SEE ALSO
|
||||
.Xr cos 3 ,
|
||||
.Xr sin 3 ,
|
||||
.Sh HISTORY
|
||||
These functions were added to
|
||||
.Fx 9.0
|
||||
to aid in writing various complex function contained in
|
||||
.St -isoC-99 .
|
||||
|
52
lib/msun/src/k_sincos.h
Normal file
52
lib/msun/src/k_sincos.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*-
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*
|
||||
* k_sin.c and k_cos.c merged by Steven G. Kargl.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
static const double
|
||||
S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
|
||||
S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
|
||||
S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
|
||||
S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
|
||||
S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
|
||||
S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
|
||||
|
||||
static const double
|
||||
C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
|
||||
C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
|
||||
C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
|
||||
C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
|
||||
C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
|
||||
C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
|
||||
|
||||
static inline void
|
||||
__kernel_sincos(double x, double y, int iy, double *sn, double *cs)
|
||||
{
|
||||
double hz, r, v, w, z;
|
||||
|
||||
z = x * x;
|
||||
w = z * z;
|
||||
r = S2 + z * (S3 + z * S4) + z * w * (S5 + z * S6);
|
||||
v = z * x;
|
||||
|
||||
if (iy == 0)
|
||||
*sn = x + v * (S1 + z * r);
|
||||
else
|
||||
*sn = x - ((z * (y / 2 - v * r) - y) - v * S1);
|
||||
|
||||
r = z * (C1 + z * (C2 + z * C3)) + w * w * (C4 + z * (C5 + z * C6));
|
||||
hz = z / 2;
|
||||
w = 1 - hz;
|
||||
*cs = w + (((1 - w) - hz) + (z * r - x * y));
|
||||
}
|
43
lib/msun/src/k_sincosf.h
Normal file
43
lib/msun/src/k_sincosf.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*-
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*
|
||||
* k_sinf.c and k_cosf.c merged by Steven G. Kargl.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
|
||||
static const double
|
||||
S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
|
||||
S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */
|
||||
S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
|
||||
S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */
|
||||
|
||||
/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
|
||||
static const double
|
||||
C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */
|
||||
C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */
|
||||
C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
|
||||
C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */
|
||||
|
||||
static inline void
|
||||
__kernel_sincosdf(double x, float *sn, float *cs)
|
||||
{
|
||||
double r, s, w, z;
|
||||
|
||||
z = x * x;
|
||||
w = z * z;
|
||||
r = S3 + z * S4;
|
||||
s = z * x;
|
||||
*sn = (x + s * (S1 + z * S2)) + s * w * r;
|
||||
r = C2 + z * C3;
|
||||
*cs = ((1 + z * C0) + w * C1) + (w * z) * r;
|
||||
}
|
134
lib/msun/src/k_sincosl.h
Normal file
134
lib/msun/src/k_sincosl.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*-
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
|
||||
*
|
||||
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*
|
||||
* k_sinl.c and k_cosl.c merged by Steven G. Kargl
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#if LDBL_MANT_DIG == 64 /* ld80 version of k_sincosl.c. */
|
||||
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
/* Long double constants are slow on these arches, and broken on i386. */
|
||||
static const volatile double
|
||||
C1hi = 0.041666666666666664, /* 0x15555555555555.0p-57 */
|
||||
C1lo = 2.2598839032744733e-18, /* 0x14d80000000000.0p-111 */
|
||||
S1hi = -0.16666666666666666, /* -0x15555555555555.0p-55 */
|
||||
S1lo = -9.2563760475949941e-18; /* -0x15580000000000.0p-109 */
|
||||
#define S1 ((long double)S1hi + S1lo)
|
||||
#define C1 ((long double)C1hi + C1lo)
|
||||
#else
|
||||
static const long double
|
||||
C1 = 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */
|
||||
S1 = -0.166666666666666666671L, /* -0xaaaaaaaaaaaaaaab.0p-66 */
|
||||
#endif
|
||||
|
||||
static const double
|
||||
C2 = -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */
|
||||
C3 = 0.000024801587301571716, /* 0x1a01a01a018e22.0p-68 */
|
||||
C4 = -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */
|
||||
C5 = 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */
|
||||
C6 = -1.1470297442401303e-11, /* -0x19393412bd1529.0p-89 */
|
||||
C7 = 4.7383039476436467e-14, /* 0x1aac9d9af5c43e.0p-97 */
|
||||
S2 = 0.0083333333333333332, /* 0x11111111111111.0p-59 */
|
||||
S3 = -0.00019841269841269427, /* -0x1a01a01a019f81.0p-65 */
|
||||
S4 = 0.0000027557319223597490, /* 0x171de3a55560f7.0p-71 */
|
||||
S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */
|
||||
S6 = 1.6059006598854211e-10, /* 0x161242b90243b5.0p-85 */
|
||||
S7 = -7.6429779983024564e-13, /* -0x1ae42ebd1b2e00.0p-93 */
|
||||
S8 = 2.6174587166648325e-15; /* 0x179372ea0b3f64.0p-101 */
|
||||
|
||||
static inline void
|
||||
__kernel_sincosl(long double x, long double y, int iy, long double *sn,
|
||||
long double *cs)
|
||||
{
|
||||
long double hz, r, v, w, z;
|
||||
|
||||
z = x * x;
|
||||
v = z * x;
|
||||
/*
|
||||
* XXX Replace Horner scheme with an algorithm suitable for CPUs
|
||||
* with more complex pipelines.
|
||||
*/
|
||||
r = S2 + z * (S3 + z * (S4 + z * (S5 + z * (S6 + z * (S7 + z * S8)))));
|
||||
|
||||
if (iy == 0)
|
||||
*sn = x + v * (S1 + z * r);
|
||||
else
|
||||
*sn = x - ((z * (y / 2 - v * r) - y) - v * S1);
|
||||
|
||||
hz = z / 2;
|
||||
w = 1 - hz;
|
||||
r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * (C6 +
|
||||
z * C7))))));
|
||||
*cs = w + (((1 - w) - hz) + (z * r - x * y));
|
||||
}
|
||||
|
||||
#elif LDBL_MANT_DIG == 113 /* ld128 version of k_sincosl.c. */
|
||||
|
||||
static const long double
|
||||
C1 = 0.04166666666666666666666666666666658424671L,
|
||||
C2 = -0.001388888888888888888888888888863490893732L,
|
||||
C3 = 0.00002480158730158730158730158600795304914210L,
|
||||
C4 = -0.2755731922398589065255474947078934284324e-6L,
|
||||
C5 = 0.2087675698786809897659225313136400793948e-8L,
|
||||
C6 = -0.1147074559772972315817149986812031204775e-10L,
|
||||
C7 = 0.4779477332386808976875457937252120293400e-13L,
|
||||
S1 = -0.16666666666666666666666666666666666606732416116558L,
|
||||
S2 = 0.0083333333333333333333333333333331135404851288270047L,
|
||||
S3 = -0.00019841269841269841269841269839935785325638310428717L,
|
||||
S4 = 0.27557319223985890652557316053039946268333231205686e-5L,
|
||||
S5 = -0.25052108385441718775048214826384312253862930064745e-7L,
|
||||
S6 = 0.16059043836821614596571832194524392581082444805729e-9L,
|
||||
S7 = -0.76471637318198151807063387954939213287488216303768e-12L,
|
||||
S8 = 0.28114572543451292625024967174638477283187397621303e-14L;
|
||||
|
||||
static const double
|
||||
C8 = -0.1561920696721507929516718307820958119868e-15,
|
||||
C9 = 0.4110317413744594971475941557607804508039e-18,
|
||||
C10 = -0.8896592467191938803288521958313920156409e-21,
|
||||
C11 = 0.1601061435794535138244346256065192782581e-23,
|
||||
S9 = -0.82206352458348947812512122163446202498005154296863e-17,
|
||||
S10 = 0.19572940011906109418080609928334380560135358385256e-19,
|
||||
S11 = -0.38680813379701966970673724299207480965452616911420e-22,
|
||||
S12 = 0.64038150078671872796678569586315881020659912139412e-25;
|
||||
|
||||
static inline void
|
||||
__kernel_sincosl(long double x, long double y, int iy, long double *sn,
|
||||
long double *cs)
|
||||
{
|
||||
long double hz, r, v, w, z;
|
||||
|
||||
z = x * x;
|
||||
v = z * x;
|
||||
/*
|
||||
* XXX Replace Horner scheme with an algorithm suitable for CPUs
|
||||
* with more complex pipelines.
|
||||
*/
|
||||
r = S2 + z * (S3 + z * (S4 + z * (S5 + z * (S6 + z * (S7 + z * (S8 +
|
||||
z * (S9 + z * (S10 + z * (S11 + z * S12)))))))));
|
||||
|
||||
if (iy == 0)
|
||||
*sn = x + v * (S1 + z * r);
|
||||
else
|
||||
*cs = x - ((z * (y / 2 - v * r) - y) - v * S1);
|
||||
|
||||
hz = z / 2;
|
||||
w = 1 - hz;
|
||||
r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * (C6 +
|
||||
z * (C7 + z * (C8 + z * (C9 + z * (C10 + z * C11))))))))));
|
||||
|
||||
*cs = w + (((1 - w) - hz) + (z * r - x * y));
|
||||
}
|
||||
#else
|
||||
#error "Unsupported long double format"
|
||||
#endif
|
@ -500,6 +500,9 @@ long double truncl(long double);
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
long double lgammal_r(long double, int *);
|
||||
void sincos(double, double *, double *);
|
||||
void sincosf(float, float *, float *);
|
||||
void sincosl(long double, long double *, long double *);
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
@ -306,9 +306,21 @@ do { \
|
||||
fpsetprec(__oprec); \
|
||||
RETURNF(__retval); \
|
||||
} while (0)
|
||||
#define ENTERV() \
|
||||
fp_prec_t __oprec; \
|
||||
\
|
||||
if ((__oprec = fpgetprec()) != FP_PE) \
|
||||
fpsetprec(FP_PE)
|
||||
#define RETURNV() do { \
|
||||
if (__oprec != FP_PE) \
|
||||
fpsetprec(__oprec); \
|
||||
return; \
|
||||
} while (0)
|
||||
#else
|
||||
#define ENTERI(x)
|
||||
#define ENTERI()
|
||||
#define RETURNI(x) RETURNF(x)
|
||||
#define ENTERV()
|
||||
#define RETURNV() return
|
||||
#endif
|
||||
|
||||
/* Default return statement if hack*_t() is not used. */
|
||||
|
80
lib/msun/src/s_sincos.c
Normal file
80
lib/msun/src/s_sincos.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*-
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*
|
||||
* s_sin.c and s_cos.c merged by Steven G. Kargl. Descriptions of the
|
||||
* algorithms are contained in the original files.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include "math.h"
|
||||
#define INLINE_REM_PIO2
|
||||
#include "math_private.h"
|
||||
#include "e_rem_pio2.c"
|
||||
#include "k_sincos.h"
|
||||
|
||||
void
|
||||
sincos(double x, double *sn, double *cs)
|
||||
{
|
||||
double y[2];
|
||||
int32_t n, ix;
|
||||
|
||||
/* High word of x. */
|
||||
GET_HIGH_WORD(ix, x);
|
||||
|
||||
/* |x| ~< pi/4 */
|
||||
ix &= 0x7fffffff;
|
||||
if (ix <= 0x3fe921fb) {
|
||||
if (ix < 0x3e400000) { /* |x| < 2**-27 */
|
||||
if ((int)x == 0) { /* Generate inexact. */
|
||||
*sn = x;
|
||||
*cs = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
__kernel_sincos(x, 0, 0, sn, cs);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If x = Inf or NaN, then sin(x) = NaN and cos(x) = NaN. */
|
||||
if (ix >= 0x7ff00000) {
|
||||
*sn = x - x;
|
||||
*cs = x - x;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Argument reduction. */
|
||||
n = __ieee754_rem_pio2(x, y);
|
||||
|
||||
switch(n & 3) {
|
||||
case 0:
|
||||
__kernel_sincos(y[0], y[1], 1, sn, cs);
|
||||
break;
|
||||
case 1:
|
||||
__kernel_sincos(y[0], y[1], 1, cs, sn);
|
||||
*cs = -*cs;
|
||||
break;
|
||||
case 2:
|
||||
__kernel_sincos(y[0], y[1], 1, sn, cs);
|
||||
*sn = -*sn;
|
||||
*cs = -*cs;
|
||||
break;
|
||||
default:
|
||||
__kernel_sincos(y[0], y[1], 1, cs, sn);
|
||||
*sn = -*sn;
|
||||
}
|
||||
}
|
||||
|
||||
#if (LDBL_MANT_DIG == 53)
|
||||
__weak_reference(sincos, sincosl);
|
||||
#endif
|
126
lib/msun/src/s_sincosf.c
Normal file
126
lib/msun/src/s_sincosf.c
Normal file
@ -0,0 +1,126 @@
|
||||
/*-
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
/* s_sincosf.c -- float version of s_sincos.c.
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
* Optimized by Bruce D. Evans.
|
||||
* Merged s_sinf.c and s_cosf.c by Steven G. Kargl.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include "math.h"
|
||||
#define INLINE_REM_PIO2F
|
||||
#include "math_private.h"
|
||||
#include "e_rem_pio2f.c"
|
||||
#include "k_sincosf.h"
|
||||
|
||||
/* Small multiples of pi/2 rounded to double precision. */
|
||||
static const double
|
||||
p1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
|
||||
p2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
|
||||
p3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
|
||||
p4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
|
||||
|
||||
void
|
||||
sincosf(float x, float *sn, float *cs)
|
||||
{
|
||||
float c, s;
|
||||
double y;
|
||||
int32_t n, hx, ix;
|
||||
|
||||
GET_FLOAT_WORD(hx, x);
|
||||
ix = hx & 0x7fffffff;
|
||||
|
||||
if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
|
||||
if (ix < 0x39800000) { /* |x| < 2**-12 */
|
||||
if ((int)x == 0) {
|
||||
*sn = x; /* x with inexact if x != 0 */
|
||||
*cs = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
__kernel_sincosdf(x, sn, cs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
|
||||
if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */
|
||||
if (hx > 0) {
|
||||
__kernel_sincosdf(x - p1pio2, cs, sn);
|
||||
*cs = -*cs;
|
||||
} else {
|
||||
__kernel_sincosdf(x + p1pio2, cs, sn);
|
||||
*sn = -*sn;
|
||||
}
|
||||
} else {
|
||||
if (hx > 0)
|
||||
__kernel_sincosdf(x - p2pio2, sn, cs);
|
||||
else
|
||||
__kernel_sincosdf(x + p2pio2, sn, cs);
|
||||
*sn = -*sn;
|
||||
*cs = -*cs;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
|
||||
if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */
|
||||
if (hx > 0) {
|
||||
__kernel_sincosdf(x - p3pio2, cs, sn);
|
||||
*sn = -*sn;
|
||||
} else {
|
||||
__kernel_sincosdf(x + p3pio2, cs, sn);
|
||||
*cs = -*cs;
|
||||
}
|
||||
} else {
|
||||
if (hx > 0)
|
||||
__kernel_sincosdf(x - p4pio2, sn, cs);
|
||||
else
|
||||
__kernel_sincosdf(x + p4pio2, sn, cs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* If x = Inf or NaN, then sin(x) = NaN and cos(x) = NaN. */
|
||||
if (ix >= 0x7f800000) {
|
||||
*sn = x - x;
|
||||
*cs = x - x;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Argument reduction. */
|
||||
n = __ieee754_rem_pio2f(x, &y);
|
||||
__kernel_sincosdf(y, &s, &c);
|
||||
|
||||
switch(n & 3) {
|
||||
case 0:
|
||||
*sn = s;
|
||||
*cs = c;
|
||||
break;
|
||||
case 1:
|
||||
*sn = c;
|
||||
*cs = -s;
|
||||
break;
|
||||
case 2:
|
||||
*sn = -s;
|
||||
*cs = -c;
|
||||
break;
|
||||
default:
|
||||
*sn = -c;
|
||||
*cs = s;
|
||||
}
|
||||
}
|
||||
|
||||
|
105
lib/msun/src/s_sincosl.c
Normal file
105
lib/msun/src/s_sincosl.c
Normal file
@ -0,0 +1,105 @@
|
||||
/*-
|
||||
* Copyright (c) 2007, 2010-2013 Steven G. Kargl
|
||||
* 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 unmodified, this list of conditions, and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* s_sinl.c and s_cosl.c merged by Steven G. Kargl.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <float.h>
|
||||
#ifdef __i386__
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
#include "math.h"
|
||||
#include "math_private.h"
|
||||
#include "k_sincosl.h"
|
||||
|
||||
#if LDBL_MANT_DIG == 64
|
||||
#include "../ld80/e_rem_pio2l.h"
|
||||
#elif LDBL_MANT_DIG == 113
|
||||
#include "../ld128/e_rem_pio2l.h"
|
||||
#else
|
||||
#error "Unsupported long double format"
|
||||
#endif
|
||||
|
||||
void
|
||||
sincosl(long double x, long double *sn, long double *cs)
|
||||
{
|
||||
union IEEEl2bits z;
|
||||
int e0, sgn;
|
||||
long double y[2];
|
||||
|
||||
z.e = x;
|
||||
sgn = z.bits.sign;
|
||||
z.bits.sign = 0;
|
||||
|
||||
ENTERV();
|
||||
|
||||
/* Optimize the case where x is already within range. */
|
||||
if (z.e < M_PI_4) {
|
||||
/*
|
||||
* If x = +-0 or x is a subnormal number, then sin(x) = x and
|
||||
* cos(x) = 1.
|
||||
*/
|
||||
if (z.bits.exp == 0) {
|
||||
*sn = x;
|
||||
*cs = 1;
|
||||
} else
|
||||
__kernel_sincosl(x, 0, 0, sn, cs);
|
||||
RETURNV();
|
||||
}
|
||||
|
||||
/* If x = NaN or Inf, then sin(x) and cos(x) are NaN. */
|
||||
if (z.bits.exp == 32767) {
|
||||
*sn = x - x;
|
||||
*cs = x - x;
|
||||
RETURNV();
|
||||
}
|
||||
|
||||
/* Range reduction. */
|
||||
e0 = __ieee754_rem_pio2l(x, y);
|
||||
|
||||
switch (e0 & 3) {
|
||||
case 0:
|
||||
__kernel_sincosl(y[0], y[1], 1, sn, cs);
|
||||
break;
|
||||
case 1:
|
||||
__kernel_sincosl(y[0], y[1], 1, cs, sn);
|
||||
*cs = -*cs;
|
||||
break;
|
||||
case 2:
|
||||
__kernel_sincosl(y[0], y[1], 1, sn, cs);
|
||||
*sn = -*sn;
|
||||
*cs = -*cs;
|
||||
break;
|
||||
default:
|
||||
__kernel_sincosl(y[0], y[1], 1, cs, sn);
|
||||
*sn = -*sn;
|
||||
}
|
||||
|
||||
RETURNV();
|
||||
}
|
@ -498,11 +498,12 @@ main(void)
|
||||
printf("ok %d # SKIP testcase fails assertion on "
|
||||
"amd64\n", j);
|
||||
continue;
|
||||
#endif
|
||||
#else
|
||||
printf("rmode = %d\n", rmodes[i]);
|
||||
fesetround(rmodes[i]);
|
||||
test_infinities();
|
||||
printf("ok %d - fma infinities\n", j);
|
||||
#endif
|
||||
}
|
||||
|
||||
fesetround(FE_TONEAREST);
|
||||
|
@ -137,7 +137,7 @@ run_log2_tests(void)
|
||||
* We should insist that log2() return exactly the correct
|
||||
* result and not raise an inexact exception for powers of 2.
|
||||
*/
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0);
|
||||
for (i = FLT_MIN_EXP - FLT_MANT_DIG; i < FLT_MAX_EXP; i++) {
|
||||
assert(log2f(ldexpf(1.0, i)) == i);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 16, 2017
|
||||
.Dd May 20, 2017
|
||||
.Dt RTLD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -60,10 +60,11 @@ This is useful for C++ libraries that contain static constructors.
|
||||
.Pp
|
||||
When resolving dependencies for the loaded objects,
|
||||
.Nm
|
||||
may be allowed to translate dynamic token strings in rpath and soname
|
||||
by setting
|
||||
translates dynamic token strings in rpath and soname.
|
||||
If the
|
||||
.Fl "z origin"
|
||||
option of the static linker
|
||||
option of the static linker was set when linking the binary,
|
||||
the token expansion is performed at the object load time, see
|
||||
.Xr ld 1 .
|
||||
The following strings are recognized now:
|
||||
.Bl -tag -width ".Pa $PLATFORM"
|
||||
@ -282,6 +283,77 @@ instead of postponing it until required.
|
||||
Normally, the filtees are opened at the time of the first symbol resolution
|
||||
from the filter object.
|
||||
.El
|
||||
.Sh DIRECT EXECUTION MODE
|
||||
.Nm
|
||||
is typically used implicitly, loaded by the kernel as requested by the
|
||||
.Dv PT_INTERP
|
||||
program header of the executed binary.
|
||||
.Fx
|
||||
also supports a direct execution mode for the dynamic linker.
|
||||
In this mode, the user explicitly executes
|
||||
.Nm
|
||||
and provides the path of the program to be linked and executed as
|
||||
an argument.
|
||||
This mode allows use of a non-standard dynamic linker for a program
|
||||
activation without changing the binary or without changing
|
||||
the installed dynamic linker.
|
||||
Execution options may be specified.
|
||||
.Pp
|
||||
The syntax of the direct invocation is
|
||||
.Bd -ragged -offset indent
|
||||
.Pa /libexec/ld-elf.so.1
|
||||
.Op Fl f Ar fd
|
||||
.Op Fl p
|
||||
.Op Fl -
|
||||
.Pa image_path
|
||||
.Op Ar image arguments
|
||||
.Ed
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl f Ar fd
|
||||
File descriptor
|
||||
.Ar fd
|
||||
references the binary to be activated by
|
||||
.Nm .
|
||||
It must already be opened in the process when executing
|
||||
.Nm .
|
||||
If this option is specified,
|
||||
.Ar image_path
|
||||
is only used to provide the
|
||||
.Va argv[0]
|
||||
value to the program.
|
||||
.It Fl p
|
||||
If the
|
||||
.Pa image_path
|
||||
argument specifies a name which does not contain a slash
|
||||
.Dq Li /
|
||||
character,
|
||||
.Nm
|
||||
uses the search path provided by the environment variable
|
||||
.Dv PATH
|
||||
to find the binary to execute.
|
||||
.It Fl -
|
||||
Ends the
|
||||
.Nm
|
||||
options.
|
||||
The argument following
|
||||
.Fl -
|
||||
is interpreted as the path of binary to execute.
|
||||
.El
|
||||
.Pp
|
||||
To conform to user expectation to not break some naively restricted
|
||||
execution environments, in the direct execution mode
|
||||
.Nm
|
||||
emulates verification of the binary execute permission
|
||||
for current user.
|
||||
The verification only uses Unix
|
||||
.Dv DACs ,
|
||||
ignores
|
||||
.Dv ACLs
|
||||
and is racy by its nature.
|
||||
The environments which rely on such restrictions are weak
|
||||
and breakable on its own.
|
||||
.Sh FILES
|
||||
.Bl -tag -width ".Pa /var/run/ld-elf32.so.hints" -compact
|
||||
.It Pa /var/run/ld-elf.so.hints
|
||||
|
@ -4,7 +4,7 @@
|
||||
PACKAGE=runtime
|
||||
PROG= mount
|
||||
SRCS= mount.c mount_fs.c getmntopts.c vfslist.c
|
||||
MAN= mount.8 mount.conf.8
|
||||
MAN= mount.8
|
||||
# We do NOT install the getmntopts.3 man page.
|
||||
|
||||
LIBADD= util
|
||||
|
@ -350,6 +350,7 @@ requirement has not been adhered to.
|
||||
.Xr ddb 4 ,
|
||||
.Xr boot.config 5 ,
|
||||
.Xr make.conf 5 ,
|
||||
.Xr mount.conf 5 ,
|
||||
.Xr ttys 5 ,
|
||||
.Xr boot0cfg 8 ,
|
||||
.Xr btxld 8 ,
|
||||
|
@ -427,6 +427,7 @@ MAN= aac.4 \
|
||||
ral.4 \
|
||||
random.4 \
|
||||
rc.4 \
|
||||
rctl.4 \
|
||||
re.4 \
|
||||
rgephy.4 \
|
||||
rights.4 \
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.Dd March 29, 2017
|
||||
.Dd May 28, 2017
|
||||
.Dt CFISCSI 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -50,9 +50,15 @@ cfiscsi_load="YES"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
subsystem provides iSCSI target device emulation via
|
||||
subsystem provides the kernel component of an iSCSI target.
|
||||
The target is the iSCSI server, providing LUNs backed by local files
|
||||
and volumes to remote initiators.
|
||||
The userspace component is provided by
|
||||
.Xr ctld 8 .
|
||||
.Nm
|
||||
is implemented as a
|
||||
.Xr ctl 4
|
||||
and
|
||||
frontend and uses infrastructure provided by
|
||||
.Xr iscsi 4 .
|
||||
.Sh SYSCTL VARIABLES
|
||||
The following variables are available as both
|
||||
@ -80,7 +86,9 @@ Defaults to 5.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ctl 4 ,
|
||||
.Xr iscsi 4
|
||||
.Xr iscsi 4 ,
|
||||
.Xr ctl.conf 5 ,
|
||||
.Xr ctld 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
@ -23,7 +23,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.Dd July 11, 2015
|
||||
.Dd May 28, 2017
|
||||
.Dt ISCSI 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -46,18 +46,14 @@ iscsi_load="YES"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
subsystem provides the kernel component of an iSCSI initiator.
|
||||
subsystem provides the kernel component of an iSCSI initiator,
|
||||
responsible for implementing the Full Feature Phase of the iSCSI protocol.
|
||||
The initiator is the iSCSI client, which connects to an iSCSI target,
|
||||
providing local access to a remote block device.
|
||||
The userland component is provided by
|
||||
.Xr iscsid 8
|
||||
and both the kernel and userland are configured using
|
||||
.Xr iscsictl 8 .
|
||||
The
|
||||
.Nm
|
||||
subsystem is responsible for implementing the
|
||||
.Qq Full Feature Phase
|
||||
of the iSCSI protocol.
|
||||
.Sh SYSCTL VARIABLES
|
||||
The following variables are available as both
|
||||
.Xr sysctl 8
|
||||
|
74
share/man/man4/rctl.4
Normal file
74
share/man/man4/rctl.4
Normal file
@ -0,0 +1,74 @@
|
||||
.\" Copyright (c) 2017 Edward Tomasz Napierala
|
||||
.\" 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 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 May 28, 2017
|
||||
.Dt RCTL 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rctl
|
||||
.Nd resource limits
|
||||
.Sh SYNOPSIS
|
||||
To compile this driver into the kernel,
|
||||
place the following line in the
|
||||
kernel configuration file:
|
||||
.Bd -ragged -offset indent
|
||||
.Cd "options RACCT"
|
||||
.Cd "options RCTL"
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
subsystem provides a flexible resource limits mechanism,
|
||||
controlled by a set of rules that can be added or removed at runtime
|
||||
using the
|
||||
.Xr rctl 8
|
||||
management utility.
|
||||
.Sh LOADER TUNABLES
|
||||
Tunables can be set at the
|
||||
.Xr loader 8
|
||||
prompt, or
|
||||
.Xr loader.conf 5 .
|
||||
.Bl -tag -width indent
|
||||
.It Va kern.racct.enable: No 1
|
||||
Enable
|
||||
.Nm .
|
||||
This defaults to 1, unless
|
||||
.Cd "options RACCT_DEFAULT_TO_DISABLED"
|
||||
is set in the kernel configuration file.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr rctl.conf 5 ,
|
||||
.Xr rctl 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
subsystem first appeared in
|
||||
.Fx 9.0 .
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
subsystem was developed by
|
||||
.An Edward Tomasz Napierala Aq Mt trasz@FreeBSD.org
|
||||
under sponsorship from the FreeBSD Foundation.
|
@ -40,6 +40,7 @@ MAN= acct.5 \
|
||||
make.conf.5 \
|
||||
moduli.5 \
|
||||
motd.5 \
|
||||
mount.conf.5 \
|
||||
mqueuefs.5 \
|
||||
msdosfs.5 \
|
||||
networks.5 \
|
||||
|
@ -27,7 +27,7 @@
|
||||
.\"
|
||||
.\"
|
||||
.Dd October 17, 2013
|
||||
.Dt MOUNT.CONF 8
|
||||
.Dt MOUNT.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mount.conf
|
||||
@ -52,7 +52,7 @@ The logic for this is in
|
||||
.Fn vfs_mountroot_conf0 .
|
||||
.It
|
||||
The kernel will first mount
|
||||
.Xr devfs 8
|
||||
.Xr devfs 5
|
||||
as the root file system.
|
||||
.It
|
||||
Next, the kernel will parse the in-memory config file created in step 1
|
||||
@ -224,7 +224,7 @@ For each root file system which is mounted, a
|
||||
directory
|
||||
.Em must
|
||||
exist so that the root mount logic can properly re-mount
|
||||
.Xr devfs 8 .
|
||||
.Xr devfs 5 .
|
||||
If this directory does not exist, the system
|
||||
may hang during the bootup process.
|
||||
.Sh SEE ALSO
|
@ -16,6 +16,25 @@ __<bsd.init.mk>__:
|
||||
.include <bsd.own.mk>
|
||||
.MAIN: all
|
||||
|
||||
# Handle INSTALL_AS_USER here to maximize the chance that
|
||||
# it has final authority over fooOWN and fooGRP.
|
||||
.if ${MK_INSTALL_AS_USER} != "no"
|
||||
.if !defined(_uid)
|
||||
_uid!= id -u
|
||||
.export _uid
|
||||
.endif
|
||||
.if ${_uid} != 0
|
||||
.if !defined(_gid)
|
||||
_gid!= id -g
|
||||
.export _gid
|
||||
.endif
|
||||
.for x in BIN CONF DOC DTB INFO KMOD LIB MAN NLS SHARE
|
||||
$xOWN= ${_uid}
|
||||
$xGRP= ${_gid}
|
||||
.endfor
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# Some targets need to know when something may build. This is used to
|
||||
# optimize targets that are only needed when building something, such as
|
||||
# (not) reading in depend files. For DIRDEPS_BUILD, it will only calculate
|
||||
|
@ -135,31 +135,6 @@ CTFCONVERT_CMD=
|
||||
CTFCONVERT_CMD= @:
|
||||
.endif
|
||||
|
||||
.if ${MK_INSTALL_AS_USER} != "no"
|
||||
.if !defined(_uid)
|
||||
_uid!= id -u
|
||||
.export _uid
|
||||
.endif
|
||||
.if ${_uid} != 0
|
||||
.if !defined(USER)
|
||||
# Avoid exporting USER
|
||||
.if !defined(_USER)
|
||||
_USER!= id -un
|
||||
.export _USER
|
||||
.endif
|
||||
USER= ${_USER}
|
||||
.endif
|
||||
.if !defined(_gid)
|
||||
_gid!= id -g
|
||||
.export _gid
|
||||
.endif
|
||||
.for x in BIN CONF DOC DTB INFO KMOD LIB MAN NLS SHARE
|
||||
$xOWN= ${USER}
|
||||
$xGRP= ${_gid}
|
||||
.endfor
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.endif # !_WITHOUT_SRCCONF
|
||||
|
||||
# Binaries
|
||||
|
@ -101,9 +101,6 @@ typedef struct {
|
||||
/*
|
||||
* Miscellaneous
|
||||
*/
|
||||
#define LINUX_NAME_MAX 255
|
||||
#define LINUX_CTL_MAXNAME 10
|
||||
|
||||
#define LINUX_AT_COUNT 19 /* Count of used aux entry types. */
|
||||
|
||||
struct l___sysctl_args
|
||||
@ -117,11 +114,6 @@ struct l___sysctl_args
|
||||
l_ulong __spare[4];
|
||||
};
|
||||
|
||||
/* Scheduling policies */
|
||||
#define LINUX_SCHED_OTHER 0
|
||||
#define LINUX_SCHED_FIFO 1
|
||||
#define LINUX_SCHED_RR 2
|
||||
|
||||
/* Resource limits */
|
||||
#define LINUX_RLIMIT_CPU 0
|
||||
#define LINUX_RLIMIT_FSIZE 1
|
||||
@ -456,20 +448,6 @@ struct l_pollfd {
|
||||
l_short revents;
|
||||
};
|
||||
|
||||
|
||||
#define LINUX_CLONE_VM 0x00000100
|
||||
#define LINUX_CLONE_FS 0x00000200
|
||||
#define LINUX_CLONE_FILES 0x00000400
|
||||
#define LINUX_CLONE_SIGHAND 0x00000800
|
||||
#define LINUX_CLONE_PID 0x00001000 /* No longer exist in Linux */
|
||||
#define LINUX_CLONE_VFORK 0x00004000
|
||||
#define LINUX_CLONE_PARENT 0x00008000
|
||||
#define LINUX_CLONE_THREAD 0x00010000
|
||||
#define LINUX_CLONE_SETTLS 0x00080000
|
||||
#define LINUX_CLONE_PARENT_SETTID 0x00100000
|
||||
#define LINUX_CLONE_CHILD_CLEARTID 0x00200000
|
||||
#define LINUX_CLONE_CHILD_SETTID 0x01000000
|
||||
|
||||
#define LINUX_ARCH_SET_GS 0x1001
|
||||
#define LINUX_ARCH_SET_FS 0x1002
|
||||
#define LINUX_ARCH_GET_FS 0x1003
|
||||
|
@ -76,6 +76,14 @@ device iic
|
||||
device iicbus
|
||||
device twsi
|
||||
|
||||
# Wireless NIC cards
|
||||
device wlan # 802.11 support
|
||||
device ath # Atheros NIC's
|
||||
device ath_pci # Atheros pci/cardbus glue
|
||||
device ath_hal
|
||||
device ath_rate_sample
|
||||
options ATH_ENABLE_11N
|
||||
|
||||
# CESA
|
||||
device cesa
|
||||
device crypto
|
||||
|
@ -97,6 +97,14 @@ struct devsw netdev = {
|
||||
net_cleanup
|
||||
};
|
||||
|
||||
static struct uri_scheme {
|
||||
const char *scheme;
|
||||
int proto;
|
||||
} uri_schemes[] = {
|
||||
{ "tftp:/", NET_TFTP },
|
||||
{ "nfs:/", NET_NFS },
|
||||
};
|
||||
|
||||
static int
|
||||
net_init(void)
|
||||
{
|
||||
@ -248,8 +256,6 @@ net_getparams(int sock)
|
||||
{
|
||||
char buf[MAXHOSTNAMELEN];
|
||||
n_long rootaddr, smask;
|
||||
struct iodesc *d = socktodesc(sock);
|
||||
extern struct in_addr servip;
|
||||
|
||||
#ifdef SUPPORT_BOOTP
|
||||
/*
|
||||
@ -258,26 +264,8 @@ net_getparams(int sock)
|
||||
* be initialized. If any remain uninitialized, we will
|
||||
* use RARP and RPC/bootparam (the Sun way) to get them.
|
||||
*/
|
||||
if (try_bootp) {
|
||||
int rc = -1;
|
||||
if (bootp_response != NULL) {
|
||||
rc = dhcp_try_rfc1048(bootp_response->bp_vend,
|
||||
bootp_response_size -
|
||||
offsetof(struct bootp, bp_vend));
|
||||
|
||||
if (servip.s_addr == 0)
|
||||
servip = bootp_response->bp_siaddr;
|
||||
if (rootip.s_addr == 0)
|
||||
rootip = bootp_response->bp_siaddr;
|
||||
if (gateip.s_addr == 0)
|
||||
gateip = bootp_response->bp_giaddr;
|
||||
if (myip.s_addr == 0)
|
||||
myip = bootp_response->bp_yiaddr;
|
||||
d->myip = myip;
|
||||
}
|
||||
if (rc < 0)
|
||||
bootp(sock, BOOTP_NONE);
|
||||
}
|
||||
if (try_bootp)
|
||||
bootp(sock);
|
||||
if (myip.s_addr != 0)
|
||||
goto exit;
|
||||
#ifdef NETIF_DEBUG
|
||||
@ -334,11 +322,8 @@ net_getparams(int sock)
|
||||
return (EIO);
|
||||
}
|
||||
exit:
|
||||
netproto = NET_TFTP;
|
||||
if ((rootaddr = net_parse_rootpath()) != INADDR_NONE) {
|
||||
netproto = NET_NFS;
|
||||
if ((rootaddr = net_parse_rootpath()) != INADDR_NONE)
|
||||
rootip.s_addr = rootaddr;
|
||||
}
|
||||
|
||||
#ifdef NETIF_DEBUG
|
||||
if (debug) {
|
||||
@ -381,20 +366,69 @@ net_print(int verbose)
|
||||
}
|
||||
|
||||
/*
|
||||
* Strip the server's address off of the rootpath if present and return it in
|
||||
* network byte order, leaving just the pathname part in the global rootpath.
|
||||
* Parses the rootpath if present
|
||||
*
|
||||
* The rootpath format can be in the form
|
||||
* <scheme>://ip/path
|
||||
* <scheme>:/path
|
||||
*
|
||||
* For compatibility with previous behaviour it also accepts as an NFS scheme
|
||||
* ip:/path
|
||||
* /path
|
||||
*
|
||||
* If an ip is set it returns it in network byte order.
|
||||
* The default scheme defined in the global netproto, if not set it defaults to
|
||||
* NFS.
|
||||
* It leaves just the pathname in the global rootpath.
|
||||
*/
|
||||
uint32_t
|
||||
net_parse_rootpath()
|
||||
{
|
||||
n_long addr = INADDR_NONE;
|
||||
char *ptr;
|
||||
n_long addr = htonl(INADDR_NONE);
|
||||
size_t i;
|
||||
char ip[FNAME_SIZE];
|
||||
char *ptr, *val;
|
||||
|
||||
netproto = NET_NONE;
|
||||
|
||||
for (i = 0; i < nitems(uri_schemes); i++) {
|
||||
if (strncmp(rootpath, uri_schemes[i].scheme,
|
||||
strlen(uri_schemes[i].scheme)) != 0)
|
||||
continue;
|
||||
|
||||
netproto = uri_schemes[i].proto;
|
||||
break;
|
||||
}
|
||||
ptr = rootpath;
|
||||
(void)strsep(&ptr, ":");
|
||||
if (ptr != NULL) {
|
||||
addr = inet_addr(rootpath);
|
||||
bcopy(ptr, rootpath, strlen(ptr) + 1);
|
||||
/* Fallback for compatibility mode */
|
||||
if (netproto == NET_NONE) {
|
||||
netproto = NET_NFS;
|
||||
(void)strsep(&ptr, ":");
|
||||
if (ptr != NULL) {
|
||||
addr = inet_addr(rootpath);
|
||||
bcopy(ptr, rootpath, strlen(ptr) + 1);
|
||||
}
|
||||
} else {
|
||||
ptr += strlen(uri_schemes[i].scheme);
|
||||
if (*ptr == '/') {
|
||||
/* we are in the form <scheme>://, we do expect an ip */
|
||||
ptr++;
|
||||
/*
|
||||
* XXX when http will be there we will need to check for
|
||||
* a port, but right now we do not need it yet
|
||||
*/
|
||||
val = strchr(ptr, '/');
|
||||
if (val != NULL) {
|
||||
snprintf(ip, sizeof(ip), "%.*s",
|
||||
(int)((uintptr_t)val - (uintptr_t)ptr),
|
||||
ptr);
|
||||
addr = inet_addr(ip);
|
||||
bcopy(val, rootpath, strlen(val) + 1);
|
||||
}
|
||||
} else {
|
||||
ptr--;
|
||||
bcopy(ptr, rootpath, strlen(ptr) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return (addr);
|
||||
|
@ -10,6 +10,8 @@ INTERNALPROG=
|
||||
NEWVERSWHAT?= "bootstrap loader" x86
|
||||
VERSION_FILE= ${.CURDIR}/../loader/version
|
||||
LOADER_NET_SUPPORT?= yes
|
||||
LOADER_NFS_SUPPORT?= yes
|
||||
LOADER_TFTP_SUPPORT?= yes
|
||||
|
||||
# architecture-specific loader code
|
||||
SRCS= main.c conf.c vers.c
|
||||
@ -30,10 +32,10 @@ LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a
|
||||
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
|
||||
.endif
|
||||
|
||||
# Enable PXE TFTP or NFS support, not both.
|
||||
.if defined(LOADER_TFTP_SUPPORT)
|
||||
CFLAGS+= -DLOADER_TFTP_SUPPORT
|
||||
.else
|
||||
.endif
|
||||
.if defined(LOADER_NFS_SUPPORT)
|
||||
CFLAGS+= -DLOADER_NFS_SUPPORT
|
||||
.endif
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 16, 2017
|
||||
.Dd May 27, 2017
|
||||
.Dt PXEBOOT 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -39,6 +39,11 @@ configured to run under Intel's Preboot Execution Environment (PXE) system.
|
||||
PXE is a form of smart boot ROM, built into Intel EtherExpress Pro/100 and
|
||||
3Com 3c905c Ethernet cards, and Ethernet-equipped Intel motherboards.
|
||||
PXE supports DHCP configuration and provides low-level NIC access services.
|
||||
.Pp
|
||||
The DHCP client will set a DHCP user class named
|
||||
.Va FreeBSD
|
||||
to allow flexible configuration of the DHCP server.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
bootloader retrieves the kernel, modules,
|
||||
@ -69,6 +74,9 @@ max-lease-time 120;
|
||||
subnet 10.0.0.0 netmask 255.255.255.0 {
|
||||
filename "pxeboot";
|
||||
range 10.0.0.10 10.0.0.254;
|
||||
if exists user-class and option user-class = "FreeBSD" {
|
||||
option root-path "tftp://10.0.0.1/FreeBSD";
|
||||
}
|
||||
}
|
||||
|
||||
.Ed
|
||||
@ -85,6 +93,27 @@ expects to fetch
|
||||
.Pa /boot/loader.rc
|
||||
from the specified server before loading any other files.
|
||||
.Pp
|
||||
Valid
|
||||
.Va option root-path
|
||||
Syntax is the following
|
||||
.Bl -tag -width <scheme>://ip/path indent
|
||||
.It /path
|
||||
path to the root filesystem on the NFS server
|
||||
.It ip:/path
|
||||
path to the root filesystem on the NFS server
|
||||
.Ar ip
|
||||
.It nfs:/path
|
||||
path to the root filesystem on the NFS server
|
||||
.It nfs://ip/path
|
||||
path to the root filesystem on the NFS server
|
||||
.Ar ip
|
||||
.It tftp:/path
|
||||
path to the root filesystem on the TFTP server
|
||||
.It tftp://ip/path
|
||||
path to the root filesystem on the TFTP server
|
||||
.Ar ip
|
||||
.El
|
||||
.Pp
|
||||
.Nm
|
||||
defaults to a conservative 1024 byte NFS data packet size.
|
||||
This may be changed by setting the
|
||||
|
@ -682,6 +682,13 @@ static struct da_quirk_entry da_quirk_table[] =
|
||||
{T_DIRECT, SIP_MEDIA_REMOVABLE, "*" , "USB DISK*",
|
||||
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Genesys GL3224
|
||||
*/
|
||||
{T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "STORAGE DEVICE*",
|
||||
"120?"}, /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_4K | DA_Q_NO_RC16
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Genesys 6-in-1 Card Reader
|
||||
|
@ -546,6 +546,14 @@ static struct scsi_quirk_entry scsi_quirk_table[] =
|
||||
{ T_DIRECT, SIP_MEDIA_REMOVABLE, "Garmin", "*", "*" },
|
||||
CAM_QUIRK_NORPTLUNS, /*mintags*/2, /*maxtags*/255
|
||||
},
|
||||
{
|
||||
{ T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic", "STORAGE DEVICE*", "120?" },
|
||||
CAM_QUIRK_NORPTLUNS, /*mintags*/2, /*maxtags*/255
|
||||
},
|
||||
{
|
||||
{ T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic", "MassStorageClass", "1533" },
|
||||
CAM_QUIRK_NORPTLUNS, /*mintags*/2, /*maxtags*/255
|
||||
},
|
||||
{
|
||||
/* Default tagged queuing parameters for all devices */
|
||||
{
|
||||
|
@ -497,7 +497,7 @@ zfsctl_common_getattr(vnode_t *vp, vattr_t *vap)
|
||||
vap->va_blksize = 0;
|
||||
vap->va_nblocks = 0;
|
||||
vap->va_seq = 0;
|
||||
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
|
||||
vn_fsid(vp, vap);
|
||||
vap->va_mode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP |
|
||||
S_IROTH | S_IXOTH;
|
||||
vap->va_type = VDIR;
|
||||
|
@ -1635,7 +1635,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp,
|
||||
cn.cn_nameptr = "snapshot";
|
||||
cn.cn_namelen = strlen(cn.cn_nameptr);
|
||||
cn.cn_nameiop = cnp->cn_nameiop;
|
||||
cn.cn_flags = cnp->cn_flags;
|
||||
cn.cn_flags = cnp->cn_flags & ~ISDOTDOT;
|
||||
cn.cn_lkflags = cnp->cn_lkflags;
|
||||
error = VOP_LOOKUP(zfsctl_vp, vpp, &cn);
|
||||
vput(zfsctl_vp);
|
||||
@ -2708,7 +2708,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
|
||||
#ifdef illumos
|
||||
vap->va_fsid = zp->z_zfsvfs->z_vfs->vfs_dev;
|
||||
#else
|
||||
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
|
||||
vn_fsid(vp, vap);
|
||||
#endif
|
||||
vap->va_nodeid = zp->z_id;
|
||||
if ((vp->v_flag & VROOT) && zfs_show_ctldir(zp))
|
||||
|
@ -31,6 +31,9 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_compat.h"
|
||||
#if defined(KLD_MODULE)
|
||||
#include "opt_global.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/blist.h>
|
||||
@ -2516,6 +2519,7 @@ linux_getrandom(struct thread *td, struct linux_getrandom_args *args)
|
||||
{
|
||||
struct uio uio;
|
||||
struct iovec iov;
|
||||
int error;
|
||||
|
||||
if (args->flags & ~(LINUX_GRND_NONBLOCK|LINUX_GRND_RANDOM))
|
||||
return (EINVAL);
|
||||
@ -2532,7 +2536,10 @@ linux_getrandom(struct thread *td, struct linux_getrandom_args *args)
|
||||
uio.uio_rw = UIO_READ;
|
||||
uio.uio_td = td;
|
||||
|
||||
return (read_random_uio(&uio, args->flags & LINUX_GRND_NONBLOCK));
|
||||
error = read_random_uio(&uio, args->flags & LINUX_GRND_NONBLOCK);
|
||||
if (error == 0)
|
||||
td->td_retval[0] = args->count - uio.uio_resid;
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -8,6 +8,8 @@
|
||||
# the code here when they all produce identical results
|
||||
# (or should)
|
||||
.if !defined(KERNBUILDDIR)
|
||||
opt_global.h:
|
||||
echo "#define DEV_RANDOM 1" >> ${.TARGET}
|
||||
opt_bpf.h:
|
||||
echo "#define DEV_BPF 1" > ${.TARGET}
|
||||
.if ${MK_INET_SUPPORT} != "no"
|
||||
|
@ -3525,6 +3525,7 @@ geom/virstor/binstream.c optional geom_virstor
|
||||
geom/virstor/g_virstor.c optional geom_virstor
|
||||
geom/virstor/g_virstor_md.c optional geom_virstor
|
||||
geom/zero/g_zero.c optional geom_zero
|
||||
fs/ext2fs/ext2_acl.c optional ext2fs
|
||||
fs/ext2fs/ext2_alloc.c optional ext2fs
|
||||
fs/ext2fs/ext2_balloc.c optional ext2fs
|
||||
fs/ext2fs/ext2_bmap.c optional ext2fs
|
||||
|
@ -497,9 +497,7 @@ ipf_nat_soft_init(softc, arg)
|
||||
softn->ipf_nat_pending.ifq_next = NULL;
|
||||
|
||||
for (i = 0, tq = softn->ipf_nat_tcptq; i < IPF_TCP_NSTATES; i++, tq++) {
|
||||
#ifdef LARGE_NAT
|
||||
if (tq->ifq_ttl < softn->ipf_nat_deficmpage)
|
||||
#endif
|
||||
tq->ifq_ttl = softn->ipf_nat_deficmpage;
|
||||
#ifdef LARGE_NAT
|
||||
else if (tq->ifq_ttl > softn->ipf_nat_defage)
|
||||
|
@ -939,7 +939,7 @@ ipf_sync_nat(softc, sp, data)
|
||||
nat_t *n, *nat;
|
||||
synclist_t *sl;
|
||||
u_int hv = 0;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
READ_ENTER(&softs->ipf_syncnat);
|
||||
|
||||
@ -1016,7 +1016,7 @@ ipf_sync_nat(softc, sp, data)
|
||||
}
|
||||
|
||||
RWLOCK_EXIT(&softs->ipf_syncnat);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
@ -302,7 +302,7 @@ ath_hal_rf_name(struct ath_hal *ah)
|
||||
HAL_BOOL
|
||||
ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val)
|
||||
{
|
||||
#define AH_TIMEOUT 1000
|
||||
#define AH_TIMEOUT 5000
|
||||
return ath_hal_waitfor(ah, reg, mask, val, AH_TIMEOUT);
|
||||
#undef AH_TIMEOUT
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_isa.h"
|
||||
#include "opt_psm.h"
|
||||
#include "opt_evdev.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -90,6 +91,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <isa/isavar.h>
|
||||
#endif
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
#include <dev/evdev/evdev.h>
|
||||
#include <dev/evdev/input.h>
|
||||
#endif
|
||||
|
||||
#include <dev/atkbdc/atkbdcreg.h>
|
||||
#include <dev/atkbdc/psm.h>
|
||||
|
||||
@ -325,8 +331,14 @@ typedef struct elantechhw {
|
||||
#define ELANTECH_REG_RDWR 0x00
|
||||
#define ELANTECH_CUSTOM_CMD 0xf8
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
#define ELANTECH_MAX_FINGERS 5
|
||||
#else
|
||||
#define ELANTECH_MAX_FINGERS PSM_FINGERS
|
||||
#endif
|
||||
|
||||
#define ELANTECH_FINGER_MAX_P 255
|
||||
#define ELANTECH_FINGER_MAX_W 15
|
||||
#define ELANTECH_FINGER_SET_XYP(pb) (finger_t) { \
|
||||
.x = (((pb)->ipacket[1] & 0x0f) << 8) | (pb)->ipacket[2], \
|
||||
.y = (((pb)->ipacket[4] & 0x0f) << 8) | (pb)->ipacket[5], \
|
||||
@ -418,6 +430,10 @@ struct psm_softc { /* Driver status information */
|
||||
int cmdcount;
|
||||
struct sigio *async; /* Processes waiting for SIGIO */
|
||||
int extended_buttons;
|
||||
#ifdef EVDEV_SUPPORT
|
||||
struct evdev_dev *evdev_a; /* Absolute reporting device */
|
||||
struct evdev_dev *evdev_r; /* Relative reporting device */
|
||||
#endif
|
||||
};
|
||||
static devclass_t psm_devclass;
|
||||
|
||||
@ -427,6 +443,8 @@ static devclass_t psm_devclass;
|
||||
#define PSM_ASLP 2 /* Waiting for mouse data */
|
||||
#define PSM_SOFTARMED 4 /* Software interrupt armed */
|
||||
#define PSM_NEED_SYNCBITS 8 /* Set syncbits using next data pkt */
|
||||
#define PSM_EV_OPEN_R 0x10 /* Relative evdev device is open */
|
||||
#define PSM_EV_OPEN_A 0x20 /* Absolute evdev device is open */
|
||||
|
||||
/* driver configuration flags (config) */
|
||||
#define PSM_CONFIG_RESOLUTION 0x000f /* resolution */
|
||||
@ -532,13 +550,23 @@ static int psmattach(device_t);
|
||||
static int psmdetach(device_t);
|
||||
static int psmresume(device_t);
|
||||
|
||||
static d_open_t psmopen;
|
||||
static d_close_t psmclose;
|
||||
static d_open_t psm_cdev_open;
|
||||
static d_close_t psm_cdev_close;
|
||||
static d_read_t psmread;
|
||||
static d_write_t psmwrite;
|
||||
static d_ioctl_t psmioctl;
|
||||
static d_poll_t psmpoll;
|
||||
|
||||
static int psmopen(struct psm_softc *);
|
||||
static int psmclose(struct psm_softc *);
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
static evdev_open_t psm_ev_open_r;
|
||||
static evdev_close_t psm_ev_close_r;
|
||||
static evdev_open_t psm_ev_open_a;
|
||||
static evdev_close_t psm_ev_close_a;
|
||||
#endif
|
||||
|
||||
static int enable_aux_dev(KBDC);
|
||||
static int disable_aux_dev(KBDC);
|
||||
static int get_mouse_status(KBDC, int *, int, int);
|
||||
@ -668,8 +696,8 @@ static driver_t psm_driver = {
|
||||
static struct cdevsw psm_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_flags = D_NEEDGIANT,
|
||||
.d_open = psmopen,
|
||||
.d_close = psmclose,
|
||||
.d_open = psm_cdev_open,
|
||||
.d_close = psm_cdev_close,
|
||||
.d_read = psmread,
|
||||
.d_write = psmwrite,
|
||||
.d_ioctl = psmioctl,
|
||||
@ -677,6 +705,17 @@ static struct cdevsw psm_cdevsw = {
|
||||
.d_name = PSM_DRIVER_NAME,
|
||||
};
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
static const struct evdev_methods psm_ev_methods_r = {
|
||||
.ev_open = psm_ev_open_r,
|
||||
.ev_close = psm_ev_close_r,
|
||||
};
|
||||
static const struct evdev_methods psm_ev_methods_a = {
|
||||
.ev_open = psm_ev_open_a,
|
||||
.ev_close = psm_ev_close_a,
|
||||
};
|
||||
#endif
|
||||
|
||||
/* device I/O routines */
|
||||
static int
|
||||
enable_aux_dev(KBDC kbdc)
|
||||
@ -1197,7 +1236,8 @@ reinitialize(struct psm_softc *sc, int doinit)
|
||||
splx(s);
|
||||
|
||||
/* restore the driver state */
|
||||
if ((sc->state & PSM_OPEN) && (err == 0)) {
|
||||
if ((sc->state & (PSM_OPEN | PSM_EV_OPEN_R | PSM_EV_OPEN_A)) &&
|
||||
(err == 0)) {
|
||||
/* enable the aux device and the port again */
|
||||
err = doopen(sc, c);
|
||||
if (err != 0)
|
||||
@ -1578,6 +1618,270 @@ psmprobe(device_t dev)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
/* Values are taken from Linux drivers for userland software compatibility */
|
||||
#define PS2_MOUSE_VENDOR 0x0002
|
||||
#define PS2_MOUSE_GENERIC_PRODUCT 0x0001
|
||||
#define PS2_MOUSE_SYNAPTICS_NAME "SynPS/2 Synaptics TouchPad"
|
||||
#define PS2_MOUSE_SYNAPTICS_PRODUCT 0x0007
|
||||
#define PS2_MOUSE_TRACKPOINT_NAME "TPPS/2 IBM TrackPoint"
|
||||
#define PS2_MOUSE_TRACKPOINT_PRODUCT 0x000A
|
||||
#define PS2_MOUSE_ELANTECH_NAME "ETPS/2 Elantech Touchpad"
|
||||
#define PS2_MOUSE_ELANTECH_ST_NAME "ETPS/2 Elantech TrackPoint"
|
||||
#define PS2_MOUSE_ELANTECH_PRODUCT 0x000E
|
||||
|
||||
#define ABSINFO_END { ABS_CNT, 0, 0, 0 }
|
||||
|
||||
static void
|
||||
psm_support_abs_bulk(struct evdev_dev *evdev, const uint16_t info[][4])
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; info[i][0] != ABS_CNT; i++)
|
||||
evdev_support_abs(evdev, info[i][0], 0, info[i][1], info[i][2],
|
||||
0, 0, info[i][3]);
|
||||
}
|
||||
|
||||
static void
|
||||
psm_push_mt_finger(struct psm_softc *sc, int id, const finger_t *f)
|
||||
{
|
||||
int y = sc->synhw.minimumYCoord + sc->synhw.maximumYCoord - f->y;
|
||||
|
||||
evdev_push_abs(sc->evdev_a, ABS_MT_SLOT, id);
|
||||
evdev_push_abs(sc->evdev_a, ABS_MT_TRACKING_ID, id);
|
||||
evdev_push_abs(sc->evdev_a, ABS_MT_POSITION_X, f->x);
|
||||
evdev_push_abs(sc->evdev_a, ABS_MT_POSITION_Y, y);
|
||||
evdev_push_abs(sc->evdev_a, ABS_MT_PRESSURE, f->p);
|
||||
}
|
||||
|
||||
static void
|
||||
psm_push_st_finger(struct psm_softc *sc, const finger_t *f)
|
||||
{
|
||||
int y = sc->synhw.minimumYCoord + sc->synhw.maximumYCoord - f->y;
|
||||
|
||||
evdev_push_abs(sc->evdev_a, ABS_X, f->x);
|
||||
evdev_push_abs(sc->evdev_a, ABS_Y, y);
|
||||
evdev_push_abs(sc->evdev_a, ABS_PRESSURE, f->p);
|
||||
if (sc->synhw.capPalmDetect)
|
||||
evdev_push_abs(sc->evdev_a, ABS_TOOL_WIDTH, f->w);
|
||||
}
|
||||
|
||||
static void
|
||||
psm_release_mt_slot(struct evdev_dev *evdev, int32_t slot)
|
||||
{
|
||||
|
||||
evdev_push_abs(evdev, ABS_MT_SLOT, slot);
|
||||
evdev_push_abs(evdev, ABS_MT_TRACKING_ID, -1);
|
||||
}
|
||||
|
||||
static int
|
||||
psm_register(device_t dev, int model_code)
|
||||
{
|
||||
struct psm_softc *sc = device_get_softc(dev);
|
||||
struct evdev_dev *evdev_r;
|
||||
int error, i, nbuttons, nwheels, product;
|
||||
bool is_pointing_stick;
|
||||
const char *name;
|
||||
|
||||
name = model_name(model_code);
|
||||
nbuttons = sc->hw.buttons;
|
||||
product = PS2_MOUSE_GENERIC_PRODUCT;
|
||||
nwheels = 0;
|
||||
is_pointing_stick = false;
|
||||
|
||||
switch (model_code) {
|
||||
case MOUSE_MODEL_TRACKPOINT:
|
||||
name = PS2_MOUSE_TRACKPOINT_NAME;
|
||||
product = PS2_MOUSE_TRACKPOINT_PRODUCT;
|
||||
nbuttons = 3;
|
||||
is_pointing_stick = true;
|
||||
break;
|
||||
|
||||
case MOUSE_MODEL_ELANTECH:
|
||||
name = PS2_MOUSE_ELANTECH_ST_NAME;
|
||||
product = PS2_MOUSE_ELANTECH_PRODUCT;
|
||||
nbuttons = 3;
|
||||
is_pointing_stick = true;
|
||||
break;
|
||||
|
||||
case MOUSE_MODEL_MOUSEMANPLUS:
|
||||
case MOUSE_MODEL_4D:
|
||||
nwheels = 2;
|
||||
break;
|
||||
|
||||
case MOUSE_MODEL_EXPLORER:
|
||||
case MOUSE_MODEL_INTELLI:
|
||||
case MOUSE_MODEL_NET:
|
||||
case MOUSE_MODEL_NETSCROLL:
|
||||
case MOUSE_MODEL_4DPLUS:
|
||||
nwheels = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
evdev_r = evdev_alloc();
|
||||
evdev_set_name(evdev_r, name);
|
||||
evdev_set_phys(evdev_r, device_get_nameunit(dev));
|
||||
evdev_set_id(evdev_r, BUS_I8042, PS2_MOUSE_VENDOR, product, 0);
|
||||
evdev_set_methods(evdev_r, sc, &psm_ev_methods_r);
|
||||
|
||||
evdev_support_prop(evdev_r, INPUT_PROP_POINTER);
|
||||
if (is_pointing_stick)
|
||||
evdev_support_prop(evdev_r, INPUT_PROP_POINTING_STICK);
|
||||
evdev_support_event(evdev_r, EV_SYN);
|
||||
evdev_support_event(evdev_r, EV_KEY);
|
||||
evdev_support_event(evdev_r, EV_REL);
|
||||
evdev_support_rel(evdev_r, REL_X);
|
||||
evdev_support_rel(evdev_r, REL_Y);
|
||||
switch (nwheels) {
|
||||
case 2:
|
||||
evdev_support_rel(evdev_r, REL_HWHEEL);
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
evdev_support_rel(evdev_r, REL_WHEEL);
|
||||
}
|
||||
for (i = 0; i < nbuttons; i++)
|
||||
evdev_support_key(evdev_r, BTN_MOUSE + i);
|
||||
|
||||
error = evdev_register_mtx(evdev_r, &Giant);
|
||||
if (error)
|
||||
evdev_free(evdev_r);
|
||||
else
|
||||
sc->evdev_r = evdev_r;
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
psm_register_synaptics(device_t dev)
|
||||
{
|
||||
struct psm_softc *sc = device_get_softc(dev);
|
||||
const uint16_t synaptics_absinfo_st[][4] = {
|
||||
{ ABS_X, sc->synhw.minimumXCoord,
|
||||
sc->synhw.maximumXCoord, sc->synhw.infoXupmm },
|
||||
{ ABS_Y, sc->synhw.minimumYCoord,
|
||||
sc->synhw.maximumYCoord, sc->synhw.infoYupmm },
|
||||
{ ABS_PRESSURE, 0, ELANTECH_FINGER_MAX_P, 0 },
|
||||
ABSINFO_END,
|
||||
};
|
||||
const uint16_t synaptics_absinfo_mt[][4] = {
|
||||
{ ABS_MT_SLOT, 0, PSM_FINGERS-1, 0},
|
||||
{ ABS_MT_TRACKING_ID, -1, PSM_FINGERS-1, 0},
|
||||
{ ABS_MT_POSITION_X, sc->synhw.minimumXCoord,
|
||||
sc->synhw.maximumXCoord, sc->synhw.infoXupmm },
|
||||
{ ABS_MT_POSITION_Y, sc->synhw.minimumYCoord,
|
||||
sc->synhw.maximumYCoord, sc->synhw.infoYupmm },
|
||||
{ ABS_MT_PRESSURE, 0, ELANTECH_FINGER_MAX_P, 0 },
|
||||
ABSINFO_END,
|
||||
};
|
||||
struct evdev_dev *evdev_a;
|
||||
int error, i, guest_model;
|
||||
|
||||
evdev_a = evdev_alloc();
|
||||
evdev_set_name(evdev_a, PS2_MOUSE_SYNAPTICS_NAME);
|
||||
evdev_set_phys(evdev_a, device_get_nameunit(dev));
|
||||
evdev_set_id(evdev_a, BUS_I8042, PS2_MOUSE_VENDOR,
|
||||
PS2_MOUSE_SYNAPTICS_PRODUCT, 0);
|
||||
evdev_set_methods(evdev_a, sc, &psm_ev_methods_a);
|
||||
|
||||
evdev_support_event(evdev_a, EV_SYN);
|
||||
evdev_support_event(evdev_a, EV_KEY);
|
||||
evdev_support_event(evdev_a, EV_ABS);
|
||||
evdev_support_prop(evdev_a, INPUT_PROP_POINTER);
|
||||
if (sc->synhw.capAdvancedGestures)
|
||||
evdev_support_prop(evdev_a, INPUT_PROP_SEMI_MT);
|
||||
if (sc->synhw.capClickPad)
|
||||
evdev_support_prop(evdev_a, INPUT_PROP_BUTTONPAD);
|
||||
evdev_support_key(evdev_a, BTN_TOUCH);
|
||||
evdev_support_nfingers(evdev_a, 3);
|
||||
psm_support_abs_bulk(evdev_a, synaptics_absinfo_st);
|
||||
if (sc->synhw.capAdvancedGestures || sc->synhw.capReportsV)
|
||||
psm_support_abs_bulk(evdev_a, synaptics_absinfo_mt);
|
||||
if (sc->synhw.capPalmDetect)
|
||||
evdev_support_abs(evdev_a, ABS_TOOL_WIDTH, 0, 0, 15, 0, 0, 0);
|
||||
evdev_support_key(evdev_a, BTN_LEFT);
|
||||
if (!sc->synhw.capClickPad) {
|
||||
evdev_support_key(evdev_a, BTN_RIGHT);
|
||||
if (sc->synhw.capExtended && sc->synhw.capMiddle)
|
||||
evdev_support_key(evdev_a, BTN_MIDDLE);
|
||||
}
|
||||
if (sc->synhw.capExtended && sc->synhw.capFourButtons) {
|
||||
evdev_support_key(evdev_a, BTN_BACK);
|
||||
evdev_support_key(evdev_a, BTN_FORWARD);
|
||||
}
|
||||
if (sc->synhw.capExtended && (sc->synhw.nExtendedButtons > 0))
|
||||
for (i = 0; i < sc->synhw.nExtendedButtons; i++)
|
||||
evdev_support_key(evdev_a, BTN_0 + i);
|
||||
|
||||
error = evdev_register_mtx(evdev_a, &Giant);
|
||||
if (!error && sc->synhw.capPassthrough) {
|
||||
guest_model = sc->tpinfo.sysctl_tree != NULL ?
|
||||
MOUSE_MODEL_TRACKPOINT : MOUSE_MODEL_GENERIC;
|
||||
error = psm_register(dev, guest_model);
|
||||
}
|
||||
if (error)
|
||||
evdev_free(evdev_a);
|
||||
else
|
||||
sc->evdev_a = evdev_a;
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
psm_register_elantech(device_t dev)
|
||||
{
|
||||
struct psm_softc *sc = device_get_softc(dev);
|
||||
const uint16_t elantech_absinfo[][4] = {
|
||||
{ ABS_X, 0, sc->elanhw.sizex,
|
||||
sc->elanhw.dpmmx },
|
||||
{ ABS_Y, 0, sc->elanhw.sizey,
|
||||
sc->elanhw.dpmmy },
|
||||
{ ABS_PRESSURE, 0, ELANTECH_FINGER_MAX_P, 0 },
|
||||
{ ABS_TOOL_WIDTH, 0, ELANTECH_FINGER_MAX_W, 0 },
|
||||
{ ABS_MT_SLOT, 0, ELANTECH_MAX_FINGERS - 1, 0 },
|
||||
{ ABS_MT_TRACKING_ID, -1, ELANTECH_MAX_FINGERS - 1, 0 },
|
||||
{ ABS_MT_POSITION_X, 0, sc->elanhw.sizex,
|
||||
sc->elanhw.dpmmx },
|
||||
{ ABS_MT_POSITION_Y, 0, sc->elanhw.sizey,
|
||||
sc->elanhw.dpmmy },
|
||||
{ ABS_MT_PRESSURE, 0, ELANTECH_FINGER_MAX_P, 0 },
|
||||
{ ABS_MT_TOUCH_MAJOR, 0, ELANTECH_FINGER_MAX_W *
|
||||
sc->elanhw.dptracex, 0 },
|
||||
ABSINFO_END,
|
||||
};
|
||||
struct evdev_dev *evdev_a;
|
||||
int error;
|
||||
|
||||
evdev_a = evdev_alloc();
|
||||
evdev_set_name(evdev_a, PS2_MOUSE_ELANTECH_NAME);
|
||||
evdev_set_phys(evdev_a, device_get_nameunit(dev));
|
||||
evdev_set_id(evdev_a, BUS_I8042, PS2_MOUSE_VENDOR,
|
||||
PS2_MOUSE_ELANTECH_PRODUCT, 0);
|
||||
evdev_set_methods(evdev_a, sc, &psm_ev_methods_a);
|
||||
|
||||
evdev_support_event(evdev_a, EV_SYN);
|
||||
evdev_support_event(evdev_a, EV_KEY);
|
||||
evdev_support_event(evdev_a, EV_ABS);
|
||||
evdev_support_prop(evdev_a, INPUT_PROP_POINTER);
|
||||
if (sc->elanhw.issemimt)
|
||||
evdev_support_prop(evdev_a, INPUT_PROP_SEMI_MT);
|
||||
if (sc->elanhw.isclickpad)
|
||||
evdev_support_prop(evdev_a, INPUT_PROP_BUTTONPAD);
|
||||
evdev_support_key(evdev_a, BTN_TOUCH);
|
||||
evdev_support_nfingers(evdev_a, ELANTECH_MAX_FINGERS);
|
||||
evdev_support_key(evdev_a, BTN_LEFT);
|
||||
if (!sc->elanhw.isclickpad)
|
||||
evdev_support_key(evdev_a, BTN_RIGHT);
|
||||
psm_support_abs_bulk(evdev_a, elantech_absinfo);
|
||||
|
||||
error = evdev_register_mtx(evdev_a, &Giant);
|
||||
if (!error && sc->elanhw.hastrackpoint)
|
||||
error = psm_register(dev, MOUSE_MODEL_ELANTECH);
|
||||
if (error)
|
||||
evdev_free(evdev_a);
|
||||
else
|
||||
sc->evdev_a = evdev_a;
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
psmattach(device_t dev)
|
||||
{
|
||||
@ -1609,6 +1913,24 @@ psmattach(device_t dev)
|
||||
sc->bdev = make_dev(&psm_cdevsw, 0, 0, 0, 0666, "bpsm%d", unit);
|
||||
sc->bdev->si_drv1 = sc;
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
switch (sc->hw.model) {
|
||||
case MOUSE_MODEL_SYNAPTICS:
|
||||
error = psm_register_synaptics(dev);
|
||||
break;
|
||||
|
||||
case MOUSE_MODEL_ELANTECH:
|
||||
error = psm_register_elantech(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = psm_register(dev, sc->hw.model);
|
||||
}
|
||||
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
|
||||
/* Some touchpad devices need full reinitialization after suspend. */
|
||||
switch (sc->hw.model) {
|
||||
case MOUSE_MODEL_SYNAPTICS:
|
||||
@ -1657,6 +1979,11 @@ psmdetach(device_t dev)
|
||||
if (sc->state & PSM_OPEN)
|
||||
return (EBUSY);
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
evdev_free(sc->evdev_r);
|
||||
evdev_free(sc->evdev_a);
|
||||
#endif
|
||||
|
||||
rid = KBDC_RID_AUX;
|
||||
bus_teardown_intr(dev, sc->intr, sc->ih);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, rid, sc->intr);
|
||||
@ -1670,13 +1997,83 @@ psmdetach(device_t dev)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
static int
|
||||
psmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
psm_ev_open_r(struct evdev_dev *evdev, void *ev_softc)
|
||||
{
|
||||
struct psm_softc *sc = (struct psm_softc *)ev_softc;
|
||||
int err = 0;
|
||||
|
||||
/* Get device data */
|
||||
if ((sc->state & PSM_VALID) == 0) {
|
||||
/* the device is no longer valid/functioning */
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
if (!(sc->state & (PSM_OPEN | PSM_EV_OPEN_A)))
|
||||
err = psmopen(sc);
|
||||
|
||||
if (err == 0)
|
||||
sc->state |= PSM_EV_OPEN_R;
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
psm_ev_close_r(struct evdev_dev *evdev, void *ev_softc)
|
||||
{
|
||||
struct psm_softc *sc = (struct psm_softc *)ev_softc;
|
||||
|
||||
sc->state &= ~PSM_EV_OPEN_R;
|
||||
|
||||
if (sc->state & (PSM_OPEN | PSM_EV_OPEN_A))
|
||||
return;
|
||||
|
||||
if (sc->state & PSM_VALID)
|
||||
psmclose(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
psm_ev_open_a(struct evdev_dev *evdev, void *ev_softc)
|
||||
{
|
||||
struct psm_softc *sc = (struct psm_softc *)ev_softc;
|
||||
int err = 0;
|
||||
|
||||
/* Get device data */
|
||||
if ((sc->state & PSM_VALID) == 0) {
|
||||
/* the device is no longer valid/functioning */
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
if (!(sc->state & (PSM_OPEN | PSM_EV_OPEN_R)))
|
||||
err = psmopen(sc);
|
||||
|
||||
if (err == 0)
|
||||
sc->state |= PSM_EV_OPEN_A;
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
psm_ev_close_a(struct evdev_dev *evdev, void *ev_softc)
|
||||
{
|
||||
struct psm_softc *sc = (struct psm_softc *)ev_softc;
|
||||
|
||||
sc->state &= ~PSM_EV_OPEN_A;
|
||||
|
||||
if (sc->state & (PSM_OPEN | PSM_EV_OPEN_R))
|
||||
return;
|
||||
|
||||
if (sc->state & PSM_VALID)
|
||||
psmclose(sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
psm_cdev_open(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
{
|
||||
struct psm_softc *sc;
|
||||
int command_byte;
|
||||
int err;
|
||||
int s;
|
||||
int err = 0;
|
||||
|
||||
/* Get device data */
|
||||
sc = dev->si_drv1;
|
||||
@ -1691,6 +2088,59 @@ psmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
|
||||
device_busy(devclass_get_device(psm_devclass, sc->unit));
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
/* Already opened by evdev */
|
||||
if (!(sc->state & (PSM_EV_OPEN_R | PSM_EV_OPEN_A)))
|
||||
#endif
|
||||
err = psmopen(sc);
|
||||
|
||||
if (err == 0)
|
||||
sc->state |= PSM_OPEN;
|
||||
else
|
||||
device_unbusy(devclass_get_device(psm_devclass, sc->unit));
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
psm_cdev_close(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
{
|
||||
struct psm_softc *sc;
|
||||
int err = 0;
|
||||
|
||||
/* Get device data */
|
||||
sc = dev->si_drv1;
|
||||
if ((sc == NULL) || (sc->state & PSM_VALID) == 0) {
|
||||
/* the device is no longer valid/functioning */
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
/* Still opened by evdev */
|
||||
if (!(sc->state & (PSM_EV_OPEN_R | PSM_EV_OPEN_A)))
|
||||
#endif
|
||||
err = psmclose(sc);
|
||||
|
||||
if (err == 0) {
|
||||
sc->state &= ~PSM_OPEN;
|
||||
/* clean up and sigio requests */
|
||||
if (sc->async != NULL) {
|
||||
funsetown(&sc->async);
|
||||
sc->async = NULL;
|
||||
}
|
||||
device_unbusy(devclass_get_device(psm_devclass, sc->unit));
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
psmopen(struct psm_softc *sc)
|
||||
{
|
||||
int command_byte;
|
||||
int err;
|
||||
int s;
|
||||
|
||||
/* Initialize state */
|
||||
sc->mode.level = sc->dflt_mode.level;
|
||||
sc->mode.protocol = sc->dflt_mode.protocol;
|
||||
@ -1750,16 +2200,13 @@ psmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
err = doopen(sc, command_byte);
|
||||
|
||||
/* done */
|
||||
if (err == 0)
|
||||
sc->state |= PSM_OPEN;
|
||||
kbdc_lock(sc->kbdc, FALSE);
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
psmclose(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
psmclose(struct psm_softc *sc)
|
||||
{
|
||||
struct psm_softc *sc = dev->si_drv1;
|
||||
int stat[3];
|
||||
int command_byte;
|
||||
int s;
|
||||
@ -1836,16 +2283,8 @@ psmclose(struct cdev *dev, int flag, int fmt, struct thread *td)
|
||||
/* remove anything left in the output buffer */
|
||||
empty_aux_buffer(sc->kbdc, 10);
|
||||
|
||||
/* clean up and sigio requests */
|
||||
if (sc->async != NULL) {
|
||||
funsetown(&sc->async);
|
||||
sc->async = NULL;
|
||||
}
|
||||
|
||||
/* close is almost always successful */
|
||||
sc->state &= ~PSM_OPEN;
|
||||
kbdc_lock(sc->kbdc, FALSE);
|
||||
device_unbusy(devclass_get_device(psm_devclass, sc->unit));
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -2496,7 +2935,7 @@ psmintr(void *arg)
|
||||
pb = &sc->pqueue[sc->pqueue_end];
|
||||
|
||||
/* discard the byte if the device is not open */
|
||||
if ((sc->state & PSM_OPEN) == 0)
|
||||
if (!(sc->state & (PSM_OPEN | PSM_EV_OPEN_R | PSM_EV_OPEN_A)))
|
||||
continue;
|
||||
|
||||
getmicrouptime(&now);
|
||||
@ -2854,7 +3293,15 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
|
||||
guest_buttons |= MOUSE_BUTTON2DOWN;
|
||||
if (pb->ipacket[1] & 0x02)
|
||||
guest_buttons |= MOUSE_BUTTON3DOWN;
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
|
||||
evdev_push_rel(sc->evdev_r, REL_X, *x);
|
||||
evdev_push_rel(sc->evdev_r, REL_Y, -*y);
|
||||
evdev_push_mouse_btn(sc->evdev_r,
|
||||
guest_buttons);
|
||||
evdev_sync(sc->evdev_r);
|
||||
}
|
||||
#endif
|
||||
ms->button = touchpad_buttons | guest_buttons |
|
||||
sc->extended_buttons;
|
||||
}
|
||||
@ -2965,6 +3412,24 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
|
||||
int mask = 0;
|
||||
maskedbits = (sc->synhw.nExtendedButtons + 1) >> 1;
|
||||
mask = (1 << maskedbits) - 1;
|
||||
#ifdef EVDEV_SUPPORT
|
||||
int i;
|
||||
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
|
||||
if (sc->synhw.capPassthrough) {
|
||||
evdev_push_mouse_btn(sc->evdev_r,
|
||||
extended_buttons);
|
||||
evdev_sync(sc->evdev_r);
|
||||
}
|
||||
for (i = 0; i < maskedbits; i++) {
|
||||
evdev_push_key(sc->evdev_a,
|
||||
BTN_0 + i * 2,
|
||||
pb->ipacket[4] & (1 << i));
|
||||
evdev_push_key(sc->evdev_a,
|
||||
BTN_0 + i * 2 + 1,
|
||||
pb->ipacket[5] & (1 << i));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
pb->ipacket[4] &= ~(mask);
|
||||
pb->ipacket[5] &= ~(mask);
|
||||
} else if (!sc->syninfo.directional_scrolls &&
|
||||
@ -3016,6 +3481,31 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
|
||||
if (id >= nfingers)
|
||||
PSM_FINGER_RESET(f[id]);
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
|
||||
for (id = 0; id < PSM_FINGERS; id++) {
|
||||
if (PSM_FINGER_IS_SET(f[id]))
|
||||
psm_push_mt_finger(sc, id, &f[id]);
|
||||
else
|
||||
psm_release_mt_slot(sc->evdev_a, id);
|
||||
}
|
||||
evdev_push_key(sc->evdev_a, BTN_TOUCH, nfingers > 0);
|
||||
evdev_push_nfingers(sc->evdev_a, nfingers);
|
||||
if (nfingers > 0)
|
||||
psm_push_st_finger(sc, &f[0]);
|
||||
else
|
||||
evdev_push_abs(sc->evdev_a, ABS_PRESSURE, 0);
|
||||
evdev_push_mouse_btn(sc->evdev_a, touchpad_buttons);
|
||||
if (sc->synhw.capExtended && sc->synhw.capFourButtons) {
|
||||
evdev_push_key(sc->evdev_a, BTN_FORWARD,
|
||||
touchpad_buttons & MOUSE_BUTTON4DOWN);
|
||||
evdev_push_key(sc->evdev_a, BTN_BACK,
|
||||
touchpad_buttons & MOUSE_BUTTON5DOWN);
|
||||
}
|
||||
evdev_sync(sc->evdev_a);
|
||||
}
|
||||
#endif
|
||||
|
||||
ms->button = touchpad_buttons;
|
||||
|
||||
psmgestures(sc, &f[0], nfingers, ms);
|
||||
@ -4015,7 +4505,12 @@ proc_elantech(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
|
||||
((pb->ipacket[0] & 0x01) ? MOUSE_BUTTON1DOWN : 0) |
|
||||
((pb->ipacket[0] & 0x02) ? MOUSE_BUTTON3DOWN : 0) |
|
||||
((pb->ipacket[0] & 0x04) ? MOUSE_BUTTON2DOWN : 0);
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
evdev_push_rel(sc->evdev_r, REL_X, *x);
|
||||
evdev_push_rel(sc->evdev_r, REL_Y, -*y);
|
||||
evdev_push_mouse_btn(sc->evdev_r, trackpoint_button);
|
||||
evdev_sync(sc->evdev_r);
|
||||
#endif
|
||||
ms->button = touchpad_button | trackpoint_button;
|
||||
return (0);
|
||||
|
||||
@ -4042,6 +4537,31 @@ proc_elantech(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
|
||||
((pb->ipacket[0] & 0x02) ? MOUSE_BUTTON3DOWN : 0);
|
||||
}
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
|
||||
for (id = 0; id < ELANTECH_MAX_FINGERS; id++) {
|
||||
if (PSM_FINGER_IS_SET(f[id])) {
|
||||
psm_push_mt_finger(sc, id, &f[id]);
|
||||
/* Convert touch width to surface units */
|
||||
evdev_push_abs(sc->evdev_a, ABS_MT_TOUCH_MAJOR,
|
||||
f[id].w * sc->elanhw.dptracex);
|
||||
}
|
||||
if (sc->elanaction.mask & (1 << id) &&
|
||||
!(mask & (1 << id)))
|
||||
psm_release_mt_slot(sc->evdev_a, id);
|
||||
}
|
||||
evdev_push_key(sc->evdev_a, BTN_TOUCH, nfingers > 0);
|
||||
evdev_push_nfingers(sc->evdev_a, nfingers);
|
||||
if (nfingers > 0) {
|
||||
if (PSM_FINGER_IS_SET(f[0]))
|
||||
psm_push_st_finger(sc, &f[0]);
|
||||
} else
|
||||
evdev_push_abs(sc->evdev_a, ABS_PRESSURE, 0);
|
||||
evdev_push_mouse_btn(sc->evdev_a, touchpad_button);
|
||||
evdev_sync(sc->evdev_a);
|
||||
}
|
||||
#endif
|
||||
|
||||
ms->button = touchpad_button | trackpoint_button;
|
||||
|
||||
/* Send finger 1 position to gesture processor */
|
||||
@ -4382,6 +4902,41 @@ psmsoftintr(void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef EVDEV_SUPPORT
|
||||
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE &&
|
||||
sc->hw.model != MOUSE_MODEL_ELANTECH &&
|
||||
sc->hw.model != MOUSE_MODEL_SYNAPTICS) {
|
||||
evdev_push_rel(sc->evdev_r, EV_REL, x);
|
||||
evdev_push_rel(sc->evdev_r, EV_REL, -y);
|
||||
|
||||
switch (sc->hw.model) {
|
||||
case MOUSE_MODEL_EXPLORER:
|
||||
case MOUSE_MODEL_INTELLI:
|
||||
case MOUSE_MODEL_NET:
|
||||
case MOUSE_MODEL_NETSCROLL:
|
||||
case MOUSE_MODEL_4DPLUS:
|
||||
evdev_push_rel(sc->evdev_r, REL_WHEEL, -z);
|
||||
break;
|
||||
case MOUSE_MODEL_MOUSEMANPLUS:
|
||||
case MOUSE_MODEL_4D:
|
||||
switch (z) {
|
||||
case 1:
|
||||
case -1:
|
||||
evdev_push_rel(sc->evdev_r, REL_WHEEL, -z);
|
||||
break;
|
||||
case 2:
|
||||
case -2:
|
||||
evdev_push_rel(sc->evdev_r, REL_HWHEEL, z / 2);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
evdev_push_mouse_btn(sc->evdev_r, ms.button);
|
||||
evdev_sync(sc->evdev_r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* scale values */
|
||||
if (sc->mode.accelfactor >= 1) {
|
||||
if (x != 0) {
|
||||
@ -6494,6 +7049,9 @@ psmresume(device_t dev)
|
||||
}
|
||||
|
||||
DRIVER_MODULE(psm, atkbdc, psm_driver, psm_devclass, 0, 0);
|
||||
#ifdef EVDEV_SUPPORT
|
||||
MODULE_DEPEND(psm, evdev, 1, 1, 1);
|
||||
#endif
|
||||
|
||||
#ifdef DEV_ISA
|
||||
|
||||
|
@ -280,7 +280,7 @@ enum {
|
||||
#define CHIPC_PLL_TYPE1 0x2 /* 48MHz base, 3 dividers */
|
||||
#define CHIPC_PLL_TYPE2 0x4 /* 48MHz, 4 dividers */
|
||||
#define CHIPC_PLL_TYPE3 0x6 /* 25MHz, 2 dividers */
|
||||
#define CHIPC_PLL_TYPE4 0x8 /* 48MHz, 4 dividers */
|
||||
#define CHIPC_PLL_TYPE4 0x1 /* 48MHz, 4 dividers */
|
||||
#define CHIPC_PLL_TYPE5 0x3 /* 25MHz, 4 dividers */
|
||||
#define CHIPC_PLL_TYPE6 0x5 /* 100/200 or 120/240 only */
|
||||
#define CHIPC_PLL_TYPE7 0x7 /* 25MHz, 4 dividers */
|
||||
|
@ -374,7 +374,7 @@ bhnd_pwrctl_slowclk_freq(struct bhnd_pwrctl_softc *sc, bool max_freq)
|
||||
} else if (PWRCTL_QUIRK(sc, SLOWCLK_CTL)) {
|
||||
div = bhnd_bus_read_4(sc->res, CHIPC_PLL_SLOWCLK_CTL);
|
||||
div = CHIPC_GET_BITS(div, CHIPC_SCC_CD);
|
||||
div *= 4;
|
||||
div = 4 * (div + 1);
|
||||
} else if (PWRCTL_QUIRK(sc, INSTACLK_CTL)) {
|
||||
if (max_freq) {
|
||||
div = 1;
|
||||
@ -503,7 +503,10 @@ bhnd_pwrctl_setclk(struct bhnd_pwrctl_softc *sc, bhnd_clock clock)
|
||||
if (bhnd_get_hwrev(sc->chipc_dev) == 10)
|
||||
return (ENODEV);
|
||||
|
||||
scc = bhnd_bus_read_4(sc->res, CHIPC_PLL_SLOWCLK_CTL);
|
||||
if (PWRCTL_QUIRK(sc, SLOWCLK_CTL))
|
||||
scc = bhnd_bus_read_4(sc->res, CHIPC_PLL_SLOWCLK_CTL);
|
||||
else
|
||||
scc = bhnd_bus_read_4(sc->res, CHIPC_SYS_CLK_CTL);
|
||||
|
||||
switch (clock) {
|
||||
case BHND_CLOCK_HT:
|
||||
@ -520,7 +523,10 @@ bhnd_pwrctl_setclk(struct bhnd_pwrctl_softc *sc, bhnd_clock clock)
|
||||
return (ENODEV);
|
||||
}
|
||||
|
||||
bhnd_bus_write_4(sc->res, CHIPC_PLL_SLOWCLK_CTL, scc);
|
||||
if (PWRCTL_QUIRK(sc, SLOWCLK_CTL))
|
||||
bhnd_bus_write_4(sc->res, CHIPC_PLL_SLOWCLK_CTL, scc);
|
||||
else
|
||||
bhnd_bus_write_4(sc->res, CHIPC_SYS_CLK_CTL, scc);
|
||||
DELAY(CHIPC_PLL_DELAY);
|
||||
|
||||
break;
|
||||
|
@ -117,6 +117,13 @@ __FBSDID("$FreeBSD$");
|
||||
#define MAX_RX_PHYS_DSGL_SGE 32
|
||||
#define DSGL_SGE_MAXLEN 65535
|
||||
|
||||
/*
|
||||
* The adapter only supports requests with a total input or output
|
||||
* length of 64k-1 or smaller. Longer requests either result in hung
|
||||
* requests or incorrect results.
|
||||
*/
|
||||
#define MAX_REQUEST_SIZE 65535
|
||||
|
||||
static MALLOC_DEFINE(M_CCR, "ccr", "Chelsio T6 crypto");
|
||||
|
||||
struct ccr_session_hmac {
|
||||
@ -412,6 +419,12 @@ ccr_hmac(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
|
||||
u_int imm_len, iopad_size;
|
||||
int error, sgl_nsegs, sgl_len;
|
||||
|
||||
crd = crp->crp_desc;
|
||||
|
||||
/* Reject requests with too large of an input buffer. */
|
||||
if (crd->crd_len > MAX_REQUEST_SIZE)
|
||||
return (EFBIG);
|
||||
|
||||
axf = s->hmac.auth_hash;
|
||||
|
||||
/* PADs must be 128-bit aligned. */
|
||||
@ -425,7 +438,6 @@ ccr_hmac(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
|
||||
hash_size_in_response = axf->hashsize;
|
||||
transhdr_len = HASH_TRANSHDR_SIZE(kctx_len);
|
||||
|
||||
crd = crp->crp_desc;
|
||||
if (ccr_use_imm_data(transhdr_len, crd->crd_len)) {
|
||||
imm_len = crd->crd_len;
|
||||
sgl_nsegs = 0;
|
||||
@ -538,6 +550,10 @@ ccr_blkcipher(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
|
||||
(crd->crd_len % AES_BLOCK_LEN) != 0)
|
||||
return (EINVAL);
|
||||
|
||||
/* Reject requests with too large of an input buffer. */
|
||||
if (crd->crd_len > MAX_REQUEST_SIZE)
|
||||
return (EFBIG);
|
||||
|
||||
iv_loc = IV_NOP;
|
||||
if (crd->crd_flags & CRD_F_ENCRYPT) {
|
||||
op_type = CHCR_ENCRYPT_OP;
|
||||
@ -785,6 +801,13 @@ ccr_authenc(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
|
||||
* the hash when encrypting. For decryption it only contains
|
||||
* the plain text.
|
||||
*/
|
||||
if (op_type == CHCR_ENCRYPT_OP) {
|
||||
if (crde->crd_len + hash_size_in_response > MAX_REQUEST_SIZE)
|
||||
return (EFBIG);
|
||||
} else {
|
||||
if (crde->crd_len > MAX_REQUEST_SIZE)
|
||||
return (EFBIG);
|
||||
}
|
||||
sglist_reset(sc->sg_dsgl);
|
||||
error = sglist_append_sglist(sc->sg_dsgl, sc->sg_crp, crde->crd_skip,
|
||||
crde->crd_len);
|
||||
@ -824,6 +847,17 @@ ccr_authenc(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
|
||||
} else
|
||||
aad_len = 0;
|
||||
input_len = aad_len + crde->crd_len;
|
||||
|
||||
/*
|
||||
* The firmware hangs if sent a request which is a
|
||||
* bit smaller than MAX_REQUEST_SIZE. In particular, the
|
||||
* firmware appears to require 512 - 16 bytes of spare room
|
||||
* along with the size of the hash even if the hash isn't
|
||||
* included in the input buffer.
|
||||
*/
|
||||
if (input_len + roundup2(axf->hashsize, 16) + (512 - 16) >
|
||||
MAX_REQUEST_SIZE)
|
||||
return (EFBIG);
|
||||
if (op_type == CHCR_DECRYPT_OP)
|
||||
input_len += hash_size_in_response;
|
||||
if (ccr_use_imm_data(transhdr_len, s->blkcipher.iv_len + input_len)) {
|
||||
@ -1105,6 +1139,13 @@ ccr_gcm(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
|
||||
* the tag when encrypting. For decryption it only contains
|
||||
* the plain text.
|
||||
*/
|
||||
if (op_type == CHCR_ENCRYPT_OP) {
|
||||
if (crde->crd_len + hash_size_in_response > MAX_REQUEST_SIZE)
|
||||
return (EFBIG);
|
||||
} else {
|
||||
if (crde->crd_len > MAX_REQUEST_SIZE)
|
||||
return (EFBIG);
|
||||
}
|
||||
sglist_reset(sc->sg_dsgl);
|
||||
error = sglist_append_sglist(sc->sg_dsgl, sc->sg_crp, crde->crd_skip,
|
||||
crde->crd_len);
|
||||
@ -1136,6 +1177,8 @@ ccr_gcm(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
|
||||
input_len = crda->crd_len + crde->crd_len;
|
||||
if (op_type == CHCR_DECRYPT_OP)
|
||||
input_len += hash_size_in_response;
|
||||
if (input_len > MAX_REQUEST_SIZE)
|
||||
return (EFBIG);
|
||||
if (ccr_use_imm_data(transhdr_len, iv_len + input_len)) {
|
||||
imm_len = input_len;
|
||||
sgl_nsegs = 0;
|
||||
|
@ -54,10 +54,12 @@
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
#include <dev/mdio/mdio.h>
|
||||
|
||||
#include <dev/etherswitch/etherswitch.h>
|
||||
#include <dev/etherswitch/rtl8366/rtl8366rbvar.h>
|
||||
|
||||
#include "mdio_if.h"
|
||||
#include "iicbus_if.h"
|
||||
#include "miibus_if.h"
|
||||
#include "etherswitch_if.h"
|
||||
@ -74,7 +76,9 @@ struct rtl8366rb_softc {
|
||||
struct ifnet *ifp[RTL8366_NUM_PHYS];
|
||||
struct callout callout_tick;
|
||||
etherswitch_info_t info;
|
||||
int chip_type; /* 0 = RTL8366RB, 1 = RTL8366SR */
|
||||
int chip_type;
|
||||
int phy4cpu;
|
||||
int numphys;
|
||||
};
|
||||
|
||||
#define RTL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
|
||||
@ -145,7 +149,7 @@ rtl8366rb_probe(device_t dev)
|
||||
bzero(sc, sizeof(*sc));
|
||||
if (smi_probe(dev) != 0)
|
||||
return (ENXIO);
|
||||
if(sc->chip_type == 0)
|
||||
if (sc->chip_type == RTL8366RB)
|
||||
device_set_desc(dev, "RTL8366RB Ethernet Switch Controller");
|
||||
else
|
||||
device_set_desc(dev, "RTL8366SR Ethernet Switch Controller");
|
||||
@ -215,17 +219,23 @@ rtl8366rb_attach(device_t dev)
|
||||
smi_read(dev, RTL8366_CVCR, &rev, RTL_WAITOK);
|
||||
device_printf(dev, "rev. %d\n", rev & 0x000f);
|
||||
|
||||
sc->info.es_nports = RTL8366_NUM_PORTS;
|
||||
sc->phy4cpu = 0;
|
||||
(void) resource_int_value(device_get_name(dev), device_get_unit(dev),
|
||||
"phy4cpu", &sc->phy4cpu);
|
||||
|
||||
sc->numphys = sc->phy4cpu ? RTL8366_NUM_PHYS - 1 : RTL8366_NUM_PHYS;
|
||||
|
||||
sc->info.es_nports = sc->numphys + 1;
|
||||
sc->info.es_nvlangroups = RTL8366_NUM_VLANS;
|
||||
sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
|
||||
if(sc->chip_type == 0)
|
||||
if (sc->chip_type == RTL8366RB)
|
||||
sprintf(sc->info.es_name, "Realtek RTL8366RB");
|
||||
else
|
||||
sprintf(sc->info.es_name, "Realtek RTL8366SR");
|
||||
|
||||
/* attach miibus and phys */
|
||||
/* PHYs need an interface, so we generate a dummy one */
|
||||
for (i = 0; i < RTL8366_NUM_PHYS; i++) {
|
||||
for (i = 0; i < sc->numphys; i++) {
|
||||
sc->ifp[i] = if_alloc(IFT_ETHER);
|
||||
sc->ifp[i]->if_softc = sc;
|
||||
sc->ifp[i]->if_flags |= IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING
|
||||
@ -263,7 +273,7 @@ rtl8366rb_detach(device_t dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
for (i=0; i < RTL8366_NUM_PHYS; i++) {
|
||||
for (i=0; i < sc->numphys; i++) {
|
||||
if (sc->miibus[i])
|
||||
device_delete_child(dev, sc->miibus[i]);
|
||||
if (sc->ifp[i] != NULL)
|
||||
@ -319,7 +329,7 @@ rtl833rb_miipollstat(struct rtl8366rb_softc *sc)
|
||||
uint16_t value;
|
||||
int portstatus;
|
||||
|
||||
for (i = 0; i < RTL8366_NUM_PHYS; i++) {
|
||||
for (i = 0; i < sc->numphys; i++) {
|
||||
mii = device_get_softc(sc->miibus[i]);
|
||||
if ((i % 2) == 0) {
|
||||
if (smi_read(sc->dev, RTL8366_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
|
||||
@ -365,7 +375,7 @@ smi_probe(device_t dev)
|
||||
iicbus = device_get_parent(dev);
|
||||
iicha = device_get_parent(iicbus);
|
||||
|
||||
for(i = 0; i < 2; ++i) {
|
||||
for (i = 0; i < 2; ++i) {
|
||||
iicbus_reset(iicbus, IIC_FASTEST, RTL8366_IIC_ADDR, NULL);
|
||||
for (j=3; j--; ) {
|
||||
IICBUS_STOP(iicha);
|
||||
@ -380,7 +390,7 @@ smi_probe(device_t dev)
|
||||
err = iicbus_start(iicbus, RTL8366_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT);
|
||||
if (err != 0)
|
||||
goto out;
|
||||
if(i == 0) {
|
||||
if (i == 0) {
|
||||
bytes[0] = RTL8366RB_CIR & 0xff;
|
||||
bytes[1] = (RTL8366RB_CIR >> 8) & 0xff;
|
||||
} else {
|
||||
@ -396,22 +406,22 @@ smi_probe(device_t dev)
|
||||
chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
|
||||
if (i == 0 && chipid == RTL8366RB_CIR_ID8366RB) {
|
||||
DPRINTF(dev, "chip id 0x%04x\n", chipid);
|
||||
sc->chip_type = 0;
|
||||
sc->chip_type = RTL8366RB;
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
if (i == 1 && chipid == RTL8366SR_CIR_ID8366SR) {
|
||||
DPRINTF(dev, "chip id 0x%04x\n", chipid);
|
||||
sc->chip_type = 1;
|
||||
sc->chip_type = RTL8366SR;
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
if(i == 0) {
|
||||
if (i == 0) {
|
||||
iicbus_stop(iicbus);
|
||||
iicbus_release_bus(iicbus, dev);
|
||||
}
|
||||
}
|
||||
if(i == 2)
|
||||
if (i == 2)
|
||||
err = ENXIO;
|
||||
out:
|
||||
iicbus_stop(iicbus);
|
||||
@ -472,7 +482,7 @@ smi_select(device_t dev, int op, int sleep)
|
||||
|
||||
RTL_SMI_ACQUIRED_ASSERT((struct rtl8366rb_softc *)device_get_softc(dev));
|
||||
|
||||
if(sc->chip_type == 1) { // RTL8366SR work around
|
||||
if (sc->chip_type == RTL8366SR) { // RTL8366SR work around
|
||||
// this is same work around at probe
|
||||
for (int i=3; i--; )
|
||||
IICBUS_STOP(device_get_parent(device_get_parent(dev)));
|
||||
@ -648,13 +658,18 @@ rtl_getport(device_t dev, etherswitch_port_t *p)
|
||||
|
||||
ifmr = &p->es_ifmr;
|
||||
|
||||
if (p->es_port < 0 || p->es_port >= RTL8366_NUM_PORTS)
|
||||
if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
|
||||
return (ENXIO);
|
||||
vlangroup = RTL8366_PVCR_GET(p->es_port,
|
||||
rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port)));
|
||||
if (sc->phy4cpu && p->es_port == sc->numphys) {
|
||||
vlangroup = RTL8366_PVCR_GET(p->es_port + 1,
|
||||
rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port + 1)));
|
||||
} else {
|
||||
vlangroup = RTL8366_PVCR_GET(p->es_port,
|
||||
rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port)));
|
||||
}
|
||||
p->es_pvid = sc->vid[vlangroup] & ETHERSWITCH_VID_MASK;
|
||||
|
||||
if (p->es_port < RTL8366_NUM_PHYS) {
|
||||
if (p->es_port < sc->numphys) {
|
||||
mii = device_get_softc(sc->miibus[p->es_port]);
|
||||
ifm = &mii->mii_media;
|
||||
err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCGIFMEDIA);
|
||||
@ -687,10 +702,11 @@ rtl_setport(device_t dev, etherswitch_port_t *p)
|
||||
int i, err, vlangroup;
|
||||
struct ifmedia *ifm;
|
||||
struct mii_data *mii;
|
||||
int port;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if (p->es_port < 0 || p->es_port >= RTL8366_NUM_PORTS)
|
||||
if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
|
||||
return (ENXIO);
|
||||
vlangroup = -1;
|
||||
for (i = 0; i < RTL8366_NUM_VLANS; i++) {
|
||||
@ -701,12 +717,18 @@ rtl_setport(device_t dev, etherswitch_port_t *p)
|
||||
}
|
||||
if (vlangroup == -1)
|
||||
return (ENXIO);
|
||||
err = smi_rmw(dev, RTL8366_PVCR_REG(p->es_port),
|
||||
RTL8366_PVCR_VAL(p->es_port, RTL8366_PVCR_PORT_MASK),
|
||||
RTL8366_PVCR_VAL(p->es_port, vlangroup), RTL_WAITOK);
|
||||
if (sc->phy4cpu && p->es_port == sc->numphys) {
|
||||
port = p->es_port + 1;
|
||||
} else {
|
||||
port = p->es_port;
|
||||
}
|
||||
err = smi_rmw(dev, RTL8366_PVCR_REG(port),
|
||||
RTL8366_PVCR_VAL(port, RTL8366_PVCR_PORT_MASK),
|
||||
RTL8366_PVCR_VAL(port, vlangroup), RTL_WAITOK);
|
||||
if (err)
|
||||
return (err);
|
||||
if (p->es_port == RTL8366_CPU_PORT)
|
||||
/* CPU Port */
|
||||
if (p->es_port == sc->numphys)
|
||||
return (0);
|
||||
mii = device_get_softc(sc->miibus[p->es_port]);
|
||||
ifm = &mii->mii_media;
|
||||
@ -720,6 +742,7 @@ rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
|
||||
struct rtl8366rb_softc *sc;
|
||||
uint16_t vmcr[3];
|
||||
int i;
|
||||
int member, untagged;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
@ -727,8 +750,15 @@ rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
|
||||
vmcr[i] = rtl_readreg(dev, RTL8366_VMCR(i, vg->es_vlangroup));
|
||||
|
||||
vg->es_vid = sc->vid[vg->es_vlangroup];
|
||||
vg->es_member_ports = RTL8366_VMCR_MEMBER(vmcr);
|
||||
vg->es_untagged_ports = RTL8366_VMCR_UNTAG(vmcr);
|
||||
member = RTL8366_VMCR_MEMBER(vmcr);
|
||||
untagged = RTL8366_VMCR_UNTAG(vmcr);
|
||||
if (sc->phy4cpu) {
|
||||
vg->es_member_ports = ((member & 0x20) >> 1) | (member & 0x0f);
|
||||
vg->es_untagged_ports = ((untagged & 0x20) >> 1) | (untagged & 0x0f);
|
||||
} else {
|
||||
vg->es_member_ports = member;
|
||||
vg->es_untagged_ports = untagged;
|
||||
}
|
||||
vg->es_fid = RTL8366_VMCR_FID(vmcr);
|
||||
return (0);
|
||||
}
|
||||
@ -738,6 +768,7 @@ rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
|
||||
{
|
||||
struct rtl8366rb_softc *sc;
|
||||
int g;
|
||||
int member, untagged;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
@ -750,16 +781,26 @@ rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
|
||||
sc->vid[g] |= ETHERSWITCH_VID_VALID;
|
||||
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_DOT1Q_REG, g),
|
||||
(vg->es_vid << RTL8366_VMCR_DOT1Q_VID_SHIFT) & RTL8366_VMCR_DOT1Q_VID_MASK);
|
||||
if(sc->chip_type == 0) {
|
||||
if (sc->phy4cpu) {
|
||||
/* add space at phy4 */
|
||||
member = (vg->es_member_ports & 0x0f) |
|
||||
((vg->es_member_ports & 0x10) << 1);
|
||||
untagged = (vg->es_untagged_ports & 0x0f) |
|
||||
((vg->es_untagged_ports & 0x10) << 1);
|
||||
} else {
|
||||
member = vg->es_member_ports;
|
||||
untagged = vg->es_untagged_ports;
|
||||
}
|
||||
if (sc->chip_type == RTL8366RB) {
|
||||
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
|
||||
((vg->es_member_ports << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
|
||||
((vg->es_untagged_ports << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK));
|
||||
((member << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
|
||||
((untagged << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK));
|
||||
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_FID_REG, g),
|
||||
vg->es_fid);
|
||||
} else {
|
||||
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
|
||||
((vg->es_member_ports << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
|
||||
((vg->es_untagged_ports << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK) |
|
||||
((member << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
|
||||
((untagged << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK) |
|
||||
((vg->es_fid << RTL8366_VMCR_FID_FID_SHIFT) & RTL8366_VMCR_FID_FID_MASK));
|
||||
}
|
||||
return (0);
|
||||
@ -886,6 +927,10 @@ static device_method_t rtl8366rb_methods[] = {
|
||||
DEVMETHOD(miibus_readreg, rtl_readphy),
|
||||
DEVMETHOD(miibus_writereg, rtl_writephy),
|
||||
|
||||
/* MDIO interface */
|
||||
DEVMETHOD(mdio_readreg, rtl_readphy),
|
||||
DEVMETHOD(mdio_writereg, rtl_writephy),
|
||||
|
||||
/* etherswitch interface */
|
||||
DEVMETHOD(etherswitch_getconf, rtl_getconf),
|
||||
DEVMETHOD(etherswitch_getinfo, rtl_getinfo),
|
||||
@ -907,6 +952,7 @@ static devclass_t rtl8366rb_devclass;
|
||||
|
||||
DRIVER_MODULE(rtl8366rb, iicbus, rtl8366rb_driver, rtl8366rb_devclass, 0, 0);
|
||||
DRIVER_MODULE(miibus, rtl8366rb, miibus_driver, miibus_devclass, 0, 0);
|
||||
DRIVER_MODULE(mdio, rtl8366rb, mdio_driver, mdio_devclass, 0, 0);
|
||||
DRIVER_MODULE(etherswitch, rtl8366rb, etherswitch_driver, etherswitch_devclass, 0, 0);
|
||||
MODULE_VERSION(rtl8366rb, 1);
|
||||
MODULE_DEPEND(rtl8366rb, iicbus, 1, 1, 1); /* XXX which versions? */
|
||||
|
@ -30,6 +30,9 @@
|
||||
#ifndef _DEV_ETHERSWITCH_RTL8366RBVAR_H_
|
||||
#define _DEV_ETHERSWITCH_RTL8366RBVAR_H_
|
||||
|
||||
#define RTL8366RB 0
|
||||
#define RTL8366SR 1
|
||||
|
||||
#define RTL8366_IIC_ADDR 0xa8
|
||||
#define RTL_IICBUS_TIMEOUT 100 /* us */
|
||||
#define RTL_IICBUS_READ 1
|
||||
@ -173,9 +176,7 @@
|
||||
(0x8000 | (1 << (((phy) & 0x1f) + 9)) | (((page) & (sc->chip_type == 0 ? 0xf : 0x7)) << 5) | ((reg) & 0x1f))
|
||||
|
||||
/* general characteristics of the chip */
|
||||
#define RTL8366_CPU_PORT 5
|
||||
#define RTL8366_NUM_PORTS 6
|
||||
#define RTL8366_NUM_PHYS (RTL8366_NUM_PORTS-1)
|
||||
#define RTL8366_NUM_PHYS 5
|
||||
#define RTL8366_NUM_VLANS 16
|
||||
#define RTL8366_NUM_PHY_REG 32
|
||||
|
||||
|
@ -91,9 +91,9 @@ static struct ieee80211vap *rtwn_vap_create(struct ieee80211com *,
|
||||
static void rtwn_vap_delete(struct ieee80211vap *);
|
||||
static int rtwn_read_chipid(struct rtwn_softc *);
|
||||
static int rtwn_ioctl_reset(struct ieee80211vap *, u_long);
|
||||
#ifndef RTWN_WITHOUT_UCODE
|
||||
static void rtwn_set_media_status(struct rtwn_softc *,
|
||||
union sec_param *);
|
||||
#ifndef RTWN_WITHOUT_UCODE
|
||||
static int rtwn_tx_fwpkt_check(struct rtwn_softc *,
|
||||
struct ieee80211vap *);
|
||||
static int rtwn_construct_nulldata(struct rtwn_softc *,
|
||||
@ -703,13 +703,13 @@ rtwn_ioctl_reset(struct ieee80211vap *vap, u_long cmd)
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef RTWN_WITHOUT_UCODE
|
||||
static void
|
||||
rtwn_set_media_status(struct rtwn_softc *sc, union sec_param *data)
|
||||
{
|
||||
sc->sc_set_media_status(sc, data->macid);
|
||||
}
|
||||
|
||||
#ifndef RTWN_WITHOUT_UCODE
|
||||
static int
|
||||
rtwn_tx_fwpkt_check(struct rtwn_softc *sc, struct ieee80211vap *vap)
|
||||
{
|
||||
@ -1743,11 +1743,9 @@ rtwn_newassoc(struct ieee80211_node *ni, int isnew __unused)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef RTWN_WITHOUT_UCODE
|
||||
/* Notify firmware. */
|
||||
id |= RTWN_MACID_VALID;
|
||||
rtwn_cmd_sleepable(sc, &id, sizeof(id), rtwn_set_media_status);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1759,10 +1757,8 @@ rtwn_node_free(struct ieee80211_node *ni)
|
||||
RTWN_NT_LOCK(sc);
|
||||
if (un->id != RTWN_MACID_UNDEFINED) {
|
||||
sc->node_list[un->id] = NULL;
|
||||
#ifndef RTWN_WITHOUT_UCODE
|
||||
rtwn_cmd_sleepable(sc, &un->id, sizeof(un->id),
|
||||
rtwn_set_media_status);
|
||||
#endif
|
||||
}
|
||||
RTWN_NT_UNLOCK(sc);
|
||||
|
||||
|
@ -141,11 +141,13 @@ r92eu_attach(struct rtwn_usb_softc *uc)
|
||||
sc->sc_vap_preattach = rtwn_nop_softc_vap;
|
||||
sc->sc_postattach = rtwn_nop_softc;
|
||||
sc->sc_detach_private = r92e_detach_private;
|
||||
sc->sc_set_media_status = r92e_set_media_status;
|
||||
#ifndef RTWN_WITHOUT_UCODE
|
||||
sc->sc_set_media_status = r92e_set_media_status;
|
||||
sc->sc_set_rsvd_page = r88e_set_rsvd_page;
|
||||
sc->sc_set_pwrmode = r92e_set_pwrmode;
|
||||
sc->sc_set_rssi = rtwn_nop_softc; /* XXX TODO? */
|
||||
#else
|
||||
sc->sc_set_media_status = rtwn_nop_softc_int;
|
||||
#endif
|
||||
sc->sc_beacon_init = r12a_beacon_init;
|
||||
sc->sc_beacon_enable = r92c_beacon_enable;
|
||||
|
@ -127,6 +127,7 @@ static const struct pci_id pci_ns8250_ids[] = {
|
||||
24 * DEFAULT_RCLK, 2 },
|
||||
{ 0x8086, 0x0f0c, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#2", 0x10,
|
||||
24 * DEFAULT_RCLK, 2 },
|
||||
{ 0x8086, 0x108f, 0xffff, 0, "Intel AMT - SOL", 0x10 },
|
||||
{ 0x8086, 0x1c3d, 0xffff, 0, "Intel AMT - KT Controller", 0x10 },
|
||||
{ 0x8086, 0x1d3d, 0xffff, 0, "Intel C600/X79 Series Chipset KT Controller", 0x10 },
|
||||
{ 0x8086, 0x1e3d, 0xffff, 0, "Intel Panther Point KT Controller", 0x10 },
|
||||
|
521
sys/fs/ext2fs/ext2_acl.c
Normal file
521
sys/fs/ext2fs/ext2_acl.c
Normal file
@ -0,0 +1,521 @@
|
||||
/*-
|
||||
* Copyright (c) 2017, Fedor Uporov
|
||||
* 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 REGENTS 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/extattr.h>
|
||||
|
||||
#include <fs/ext2fs/fs.h>
|
||||
#include <fs/ext2fs/ext2fs.h>
|
||||
#include <fs/ext2fs/inode.h>
|
||||
#include <fs/ext2fs/ext2_acl.h>
|
||||
#include <fs/ext2fs/ext2_extattr.h>
|
||||
#include <fs/ext2fs/ext2_extern.h>
|
||||
#include <fs/ext2fs/ext2_dinode.h>
|
||||
#include <fs/ext2fs/ext2_mount.h>
|
||||
|
||||
void
|
||||
ext2_sync_acl_from_inode(struct inode *ip, struct acl *acl)
|
||||
{
|
||||
struct acl_entry *acl_mask, *acl_group_obj;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Update ACL_USER_OBJ, ACL_OTHER, but simply identify ACL_MASK
|
||||
* and ACL_GROUP_OBJ for use after we know whether ACL_MASK is
|
||||
* present.
|
||||
*/
|
||||
acl_mask = NULL;
|
||||
acl_group_obj = NULL;
|
||||
for (i = 0; i < acl->acl_cnt; i++) {
|
||||
switch (acl->acl_entry[i].ae_tag) {
|
||||
case ACL_USER_OBJ:
|
||||
acl->acl_entry[i].ae_perm = acl_posix1e_mode_to_perm(
|
||||
ACL_USER_OBJ, ip->i_mode);
|
||||
acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID;
|
||||
break;
|
||||
|
||||
case ACL_GROUP_OBJ:
|
||||
acl_group_obj = &acl->acl_entry[i];
|
||||
acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID;
|
||||
break;
|
||||
|
||||
case ACL_OTHER:
|
||||
acl->acl_entry[i].ae_perm = acl_posix1e_mode_to_perm(
|
||||
ACL_OTHER, ip->i_mode);
|
||||
acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID;
|
||||
break;
|
||||
|
||||
case ACL_MASK:
|
||||
acl_mask = &acl->acl_entry[i];
|
||||
acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID;
|
||||
break;
|
||||
|
||||
case ACL_USER:
|
||||
case ACL_GROUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("ext2_sync_acl_from_inode(): bad ae_tag");
|
||||
}
|
||||
}
|
||||
|
||||
if (acl_group_obj == NULL)
|
||||
panic("ext2_sync_acl_from_inode(): no ACL_GROUP_OBJ");
|
||||
|
||||
if (acl_mask == NULL) {
|
||||
/*
|
||||
* There is no ACL_MASK, so update ACL_GROUP_OBJ.
|
||||
*/
|
||||
acl_group_obj->ae_perm = acl_posix1e_mode_to_perm(
|
||||
ACL_GROUP_OBJ, ip->i_mode);
|
||||
} else {
|
||||
/*
|
||||
* Update the ACL_MASK entry instead of ACL_GROUP_OBJ.
|
||||
*/
|
||||
acl_mask->ae_perm = acl_posix1e_mode_to_perm(ACL_GROUP_OBJ,
|
||||
ip->i_mode);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ext2_sync_inode_from_acl(struct acl *acl, struct inode *ip)
|
||||
{
|
||||
|
||||
ip->i_mode &= ACL_PRESERVE_MASK;
|
||||
ip->i_mode |= acl_posix1e_acl_to_mode(acl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert from filesystem to in-memory representation.
|
||||
*/
|
||||
static int
|
||||
ext4_acl_from_disk(char *value, size_t size, struct acl *acl)
|
||||
{
|
||||
const char *end = value + size;
|
||||
int n, count, s;
|
||||
|
||||
if (((struct ext2_acl_header *)value)->a_version != EXT4_ACL_VERSION)
|
||||
return (EINVAL);
|
||||
|
||||
if (!value || size < sizeof(struct ext2_acl_header))
|
||||
return (EINVAL);
|
||||
|
||||
s = size - sizeof(struct ext2_acl_header);
|
||||
s -= 4 * sizeof(struct ext2_acl_entry_short);
|
||||
if (s < 0)
|
||||
if ((size - sizeof(struct ext2_acl_header)) %
|
||||
sizeof(struct ext2_acl_entry_short))
|
||||
count = -1;
|
||||
else
|
||||
count = (size - sizeof(struct ext2_acl_header)) /
|
||||
sizeof(struct ext2_acl_entry_short);
|
||||
else
|
||||
if (s % sizeof(struct ext2_acl_entry))
|
||||
count = -1;
|
||||
else
|
||||
count = s / sizeof(struct ext2_acl_entry) + 4;
|
||||
|
||||
if (count <= 0 || count > acl->acl_maxcnt)
|
||||
return (EINVAL);
|
||||
|
||||
value = value + sizeof(struct ext2_acl_header);
|
||||
|
||||
for (n = 0; n < count; n++) {
|
||||
struct ext2_acl_entry *entry = (struct ext2_acl_entry *)value;
|
||||
if ((char *)value + sizeof(struct ext2_acl_entry_short) > end)
|
||||
return (EINVAL);
|
||||
|
||||
acl->acl_entry[n].ae_tag = entry->ae_tag;
|
||||
acl->acl_entry[n].ae_perm = entry->ae_perm;
|
||||
|
||||
switch (acl->acl_entry[n].ae_tag) {
|
||||
case ACL_USER_OBJ:
|
||||
case ACL_GROUP_OBJ:
|
||||
case ACL_MASK:
|
||||
case ACL_OTHER:
|
||||
value = (char *)value + sizeof(struct ext2_acl_entry_short);
|
||||
break;
|
||||
|
||||
case ACL_USER:
|
||||
value = (char *)value + sizeof(struct ext2_acl_entry);
|
||||
if ((char *)value > end)
|
||||
return (EINVAL);
|
||||
|
||||
acl->acl_entry[n].ae_id = entry->ae_id;
|
||||
break;
|
||||
|
||||
case ACL_GROUP:
|
||||
value = (char *)value + sizeof(struct ext2_acl_entry);
|
||||
if ((char *)value > end)
|
||||
return (EINVAL);
|
||||
|
||||
acl->acl_entry[n].ae_id = entry->ae_id;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (value != end)
|
||||
return (EINVAL);
|
||||
|
||||
acl->acl_cnt = count;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ext2_getacl_posix1e(struct vop_getacl_args *ap)
|
||||
{
|
||||
int attrnamespace;
|
||||
const char *attrname;
|
||||
char *value;
|
||||
int len;
|
||||
int error;
|
||||
|
||||
switch (ap->a_type) {
|
||||
case ACL_TYPE_DEFAULT:
|
||||
attrnamespace = POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE;
|
||||
attrname = POSIX1E_ACL_DEFAULT_EXTATTR_NAME;
|
||||
break;
|
||||
case ACL_TYPE_ACCESS:
|
||||
attrnamespace = POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE;
|
||||
attrname = POSIX1E_ACL_ACCESS_EXTATTR_NAME;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
len = sizeof(*ap->a_aclp) + sizeof(struct ext2_acl_header);
|
||||
value = malloc(len, M_ACL, M_WAITOK);
|
||||
if (!value)
|
||||
return (ENOMEM);
|
||||
|
||||
error = vn_extattr_get(ap->a_vp, IO_NODELOCKED, attrnamespace, attrname,
|
||||
&len, value, ap->a_td);
|
||||
switch (error) {
|
||||
case ENOATTR:
|
||||
switch (ap->a_type) {
|
||||
case ACL_TYPE_ACCESS:
|
||||
ap->a_aclp->acl_cnt = 3;
|
||||
ap->a_aclp->acl_entry[0].ae_tag = ACL_USER_OBJ;
|
||||
ap->a_aclp->acl_entry[0].ae_id = ACL_UNDEFINED_ID;
|
||||
ap->a_aclp->acl_entry[0].ae_perm = ACL_PERM_NONE;
|
||||
ap->a_aclp->acl_entry[1].ae_tag = ACL_GROUP_OBJ;
|
||||
ap->a_aclp->acl_entry[1].ae_id = ACL_UNDEFINED_ID;
|
||||
ap->a_aclp->acl_entry[1].ae_perm = ACL_PERM_NONE;
|
||||
ap->a_aclp->acl_entry[2].ae_tag = ACL_OTHER;
|
||||
ap->a_aclp->acl_entry[2].ae_id = ACL_UNDEFINED_ID;
|
||||
ap->a_aclp->acl_entry[2].ae_perm = ACL_PERM_NONE;
|
||||
break;
|
||||
|
||||
case ACL_TYPE_DEFAULT:
|
||||
ap->a_aclp->acl_cnt = 0;
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
if (!error) {
|
||||
error = ext4_acl_from_disk(value, len, ap->a_aclp);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (error == ENOATTR)
|
||||
error = 0;
|
||||
|
||||
if (ap->a_type == ACL_TYPE_ACCESS)
|
||||
ext2_sync_acl_from_inode(VTOI(ap->a_vp), ap->a_aclp);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
free(value, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
ext2_getacl(struct vop_getacl_args *ap)
|
||||
{
|
||||
|
||||
if (((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) ||
|
||||
((ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) == 1))
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
if (ap->a_type == ACL_TYPE_NFS4)
|
||||
return (ENOTSUP);
|
||||
|
||||
return (ext2_getacl_posix1e(ap));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert from in-memory to filesystem representation.
|
||||
*/
|
||||
static int
|
||||
ext4_acl_to_disk(const struct acl *acl, size_t *size, char *value)
|
||||
{
|
||||
struct ext2_acl_header *ext_acl;
|
||||
int disk_size;
|
||||
char *e;
|
||||
size_t n;
|
||||
|
||||
if (acl->acl_cnt <= 4)
|
||||
disk_size = sizeof(struct ext2_acl_header) +
|
||||
acl->acl_cnt * sizeof(struct ext2_acl_entry_short);
|
||||
else
|
||||
disk_size = sizeof(struct ext2_acl_header) +
|
||||
4 * sizeof(struct ext2_acl_entry_short) +
|
||||
(acl->acl_cnt - 4) * sizeof(struct ext2_acl_entry);
|
||||
|
||||
if (disk_size > *size)
|
||||
return (EINVAL);
|
||||
|
||||
*size = disk_size;
|
||||
ext_acl = (struct ext2_acl_header *)value;
|
||||
|
||||
ext_acl->a_version = EXT4_ACL_VERSION;
|
||||
e = (char *)ext_acl + sizeof(struct ext2_acl_header);
|
||||
for (n = 0; n < acl->acl_cnt; n++) {
|
||||
const struct acl_entry *acl_e = &acl->acl_entry[n];
|
||||
struct ext2_acl_entry *entry = (struct ext2_acl_entry *)e;
|
||||
entry->ae_tag = acl_e->ae_tag;
|
||||
entry->ae_perm = acl_e->ae_perm;
|
||||
switch (acl_e->ae_tag) {
|
||||
case ACL_USER:
|
||||
entry->ae_id = acl_e->ae_id;
|
||||
e += sizeof(struct ext2_acl_entry);
|
||||
break;
|
||||
|
||||
case ACL_GROUP:
|
||||
entry->ae_id = acl_e->ae_id;
|
||||
e += sizeof(struct ext2_acl_entry);
|
||||
break;
|
||||
|
||||
case ACL_USER_OBJ:
|
||||
case ACL_GROUP_OBJ:
|
||||
case ACL_MASK:
|
||||
case ACL_OTHER:
|
||||
e += sizeof(struct ext2_acl_entry_short);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ext2_setacl_posix1e(struct vop_setacl_args *ap)
|
||||
{
|
||||
struct inode *ip = VTOI(ap->a_vp);
|
||||
char *value;
|
||||
size_t len;
|
||||
int error;
|
||||
|
||||
if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* If this is a set operation rather than a delete operation,
|
||||
* invoke VOP_ACLCHECK() on the passed ACL to determine if it is
|
||||
* valid for the target. This will include a check on ap->a_type.
|
||||
*/
|
||||
if (ap->a_aclp != NULL) {
|
||||
/*
|
||||
* Set operation.
|
||||
*/
|
||||
error = VOP_ACLCHECK(ap->a_vp, ap->a_type, ap->a_aclp,
|
||||
ap->a_cred, ap->a_td);
|
||||
if (error)
|
||||
return (error);
|
||||
} else {
|
||||
/*
|
||||
* Delete operation.
|
||||
* POSIX.1e allows only deletion of the default ACL on a
|
||||
* directory (ACL_TYPE_DEFAULT).
|
||||
*/
|
||||
if (ap->a_type != ACL_TYPE_DEFAULT)
|
||||
return (EINVAL);
|
||||
if (ap->a_vp->v_type != VDIR)
|
||||
return (ENOTDIR);
|
||||
}
|
||||
|
||||
if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
|
||||
return (EROFS);
|
||||
|
||||
/*
|
||||
* Authorize the ACL operation.
|
||||
*/
|
||||
if (ip->i_flags & (IMMUTABLE | APPEND))
|
||||
return (EPERM);
|
||||
|
||||
/*
|
||||
* Must hold VADMIN (be file owner) or have appropriate privilege.
|
||||
*/
|
||||
if ((error = VOP_ACCESS(ap->a_vp, VADMIN, ap->a_cred, ap->a_td)))
|
||||
return (error);
|
||||
|
||||
switch (ap->a_type) {
|
||||
case ACL_TYPE_ACCESS:
|
||||
len = sizeof(*ap->a_aclp) + sizeof(struct ext2_acl_header);
|
||||
value = malloc(len, M_ACL, M_WAITOK | M_ZERO);
|
||||
error = ext4_acl_to_disk(ap->a_aclp, &len, value);
|
||||
if (error == 0)
|
||||
error = vn_extattr_set(ap->a_vp, IO_NODELOCKED,
|
||||
POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE,
|
||||
POSIX1E_ACL_ACCESS_EXTATTR_NAME, len,
|
||||
value, ap->a_td);
|
||||
|
||||
free(value, M_ACL);
|
||||
break;
|
||||
|
||||
case ACL_TYPE_DEFAULT:
|
||||
if (ap->a_aclp == NULL) {
|
||||
error = vn_extattr_rm(ap->a_vp, IO_NODELOCKED,
|
||||
POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE,
|
||||
POSIX1E_ACL_DEFAULT_EXTATTR_NAME, ap->a_td);
|
||||
|
||||
/*
|
||||
* Attempting to delete a non-present default ACL
|
||||
* will return success for portability purposes.
|
||||
* (TRIX)
|
||||
*
|
||||
* XXX: Note that since we can't distinguish
|
||||
* "that EA is not supported" from "that EA is not
|
||||
* defined", the success case here overlaps the
|
||||
* the ENOATTR->EOPNOTSUPP case below.
|
||||
*/
|
||||
if (error == ENOATTR)
|
||||
error = 0;
|
||||
} else {
|
||||
len = sizeof(*ap->a_aclp) + sizeof(struct ext2_acl_header);
|
||||
value = malloc(len, M_ACL, M_WAITOK | M_ZERO);
|
||||
error = ext4_acl_to_disk(ap->a_aclp, &len, value);
|
||||
if (error == 0)
|
||||
error = vn_extattr_set(ap->a_vp, IO_NODELOCKED,
|
||||
POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE,
|
||||
POSIX1E_ACL_DEFAULT_EXTATTR_NAME, len,
|
||||
value, ap->a_td);
|
||||
|
||||
free(value, M_ACL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map lack of attribute definition in UFS_EXTATTR into lack of
|
||||
* support for ACLs on the filesystem.
|
||||
*/
|
||||
if (error == ENOATTR)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (ap->a_type == ACL_TYPE_ACCESS) {
|
||||
/*
|
||||
* Now that the EA is successfully updated, update the
|
||||
* inode and mark it as changed.
|
||||
*/
|
||||
ext2_sync_inode_from_acl(ap->a_aclp, ip);
|
||||
ip->i_flag |= IN_CHANGE;
|
||||
error = ext2_update(ip->i_vnode, 1);
|
||||
}
|
||||
|
||||
VN_KNOTE_UNLOCKED(ap->a_vp, NOTE_ATTRIB);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
ext2_setacl(struct vop_setacl_args *ap)
|
||||
{
|
||||
if (((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) ||
|
||||
((ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) == 1))
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
if (ap->a_type == ACL_TYPE_NFS4)
|
||||
return (ENOTSUP);
|
||||
|
||||
return (ext2_setacl_posix1e(ap));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the validity of an ACL for a file.
|
||||
*/
|
||||
int
|
||||
ext2_aclcheck(struct vop_aclcheck_args *ap)
|
||||
{
|
||||
|
||||
if (((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) ||
|
||||
((ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) == 1))
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
if (ap->a_type == ACL_TYPE_NFS4)
|
||||
return (ENOTSUP);
|
||||
|
||||
if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* Verify we understand this type of ACL, and that it applies
|
||||
* to this kind of object.
|
||||
* Rely on the acl_posix1e_check() routine to verify the contents.
|
||||
*/
|
||||
switch (ap->a_type) {
|
||||
case ACL_TYPE_ACCESS:
|
||||
break;
|
||||
|
||||
case ACL_TYPE_DEFAULT:
|
||||
if (ap->a_vp->v_type != VDIR)
|
||||
return (EINVAL);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
return (acl_posix1e_check(ap->a_aclp));
|
||||
}
|
55
sys/fs/ext2fs/ext2_acl.h
Normal file
55
sys/fs/ext2fs/ext2_acl.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*-
|
||||
* Copyright (c) 2017, Fedor Uporov
|
||||
* 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 REGENTS 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _FS_EXT2FS_EXT2_ACL_H_
|
||||
#define _FS_EXT2FS_EXT2_ACL_H_
|
||||
|
||||
#define EXT4_ACL_VERSION 0x0001
|
||||
|
||||
struct ext2_acl_entry {
|
||||
int16_t ae_tag;
|
||||
int16_t ae_perm;
|
||||
int32_t ae_id;
|
||||
};
|
||||
|
||||
struct ext2_acl_entry_short {
|
||||
int16_t ae_tag;
|
||||
int16_t ae_perm;
|
||||
};
|
||||
|
||||
struct ext2_acl_header {
|
||||
int32_t a_version;
|
||||
};
|
||||
|
||||
void ext2_sync_acl_from_inode(struct inode *ip, struct acl *acl);
|
||||
|
||||
int ext2_getacl(struct vop_getacl_args *);
|
||||
int ext2_setacl(struct vop_setacl_args *);
|
||||
int ext2_aclcheck(struct vop_aclcheck_args *);
|
||||
|
||||
#endif /* !_FS_EXT2FS_EXT2_ACL_H_ */
|
@ -46,35 +46,92 @@
|
||||
#include <fs/ext2fs/ext2_extattr.h>
|
||||
#include <fs/ext2fs/ext2_extern.h>
|
||||
|
||||
|
||||
static int
|
||||
ext2_extattr_index_to_bsd(int index)
|
||||
ext2_extattr_attrnamespace_to_bsd(int attrnamespace)
|
||||
{
|
||||
switch (index) {
|
||||
case EXT4_XATTR_INDEX_SYSTEM:
|
||||
return (EXTATTR_NAMESPACE_SYSTEM);
|
||||
|
||||
case EXT4_XATTR_INDEX_USER:
|
||||
return (EXTATTR_NAMESPACE_USER);
|
||||
switch (attrnamespace) {
|
||||
case EXT4_XATTR_INDEX_SYSTEM:
|
||||
return (EXTATTR_NAMESPACE_SYSTEM);
|
||||
|
||||
case EXT4_XATTR_INDEX_USER:
|
||||
return (EXTATTR_NAMESPACE_USER);
|
||||
|
||||
case EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT:
|
||||
return (POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE);
|
||||
|
||||
case EXT4_XATTR_INDEX_POSIX_ACL_ACCESS:
|
||||
return (POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE);
|
||||
}
|
||||
|
||||
return (EXTATTR_NAMESPACE_EMPTY);
|
||||
}
|
||||
|
||||
static int
|
||||
ext2_extattr_index_to_linux(int index)
|
||||
static const char *
|
||||
ext2_extattr_name_to_bsd(int attrnamespace, const char *name, int* name_len)
|
||||
{
|
||||
switch (index) {
|
||||
case EXTATTR_NAMESPACE_SYSTEM:
|
||||
return (EXT4_XATTR_INDEX_SYSTEM);
|
||||
|
||||
case EXTATTR_NAMESPACE_USER:
|
||||
return (EXT4_XATTR_INDEX_USER);
|
||||
if (attrnamespace == EXT4_XATTR_INDEX_SYSTEM)
|
||||
return (name);
|
||||
else if (attrnamespace == EXT4_XATTR_INDEX_USER)
|
||||
return (name);
|
||||
else if (attrnamespace == EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT) {
|
||||
*name_len = strlen(POSIX1E_ACL_DEFAULT_EXTATTR_NAME);
|
||||
return (POSIX1E_ACL_DEFAULT_EXTATTR_NAME);
|
||||
} else if (attrnamespace == EXT4_XATTR_INDEX_POSIX_ACL_ACCESS) {
|
||||
*name_len = strlen(POSIX1E_ACL_ACCESS_EXTATTR_NAME);
|
||||
return (POSIX1E_ACL_ACCESS_EXTATTR_NAME);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: Not all linux namespaces are mapped to bsd for now,
|
||||
* return NULL, which will be converted to ENOTSUP on upper layer.
|
||||
*/
|
||||
#ifdef EXT2FS_DEBUG
|
||||
printf("can not convert ext2fs name to bsd: namespace=%d\n", attrnamespace);
|
||||
#endif /* DEBUG */
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
ext2_extattr_attrnamespace_to_linux(int attrnamespace, const char *name)
|
||||
{
|
||||
|
||||
if (attrnamespace == POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE &&
|
||||
!strcmp(name, POSIX1E_ACL_DEFAULT_EXTATTR_NAME))
|
||||
return (EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT);
|
||||
|
||||
if (attrnamespace == POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE &&
|
||||
!strcmp(name, POSIX1E_ACL_ACCESS_EXTATTR_NAME))
|
||||
return (EXT4_XATTR_INDEX_POSIX_ACL_ACCESS);
|
||||
|
||||
switch (attrnamespace) {
|
||||
case EXTATTR_NAMESPACE_SYSTEM:
|
||||
return (EXT4_XATTR_INDEX_SYSTEM);
|
||||
|
||||
case EXTATTR_NAMESPACE_USER:
|
||||
return (EXT4_XATTR_INDEX_USER);
|
||||
}
|
||||
|
||||
/*
|
||||
* In this case namespace conversion should be unique,
|
||||
* so this point is unreachable.
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static const char *
|
||||
ext2_extattr_name_to_linux(int attrnamespace, const char *name)
|
||||
{
|
||||
|
||||
if (attrnamespace == POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE ||
|
||||
attrnamespace == POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE)
|
||||
return ("");
|
||||
else
|
||||
return (name);
|
||||
}
|
||||
|
||||
int
|
||||
ext2_extattr_valid_attrname(int attrnamespace, const char *attrname)
|
||||
{
|
||||
@ -114,6 +171,8 @@ ext2_extattr_inode_list(struct inode *ip, int attrnamespace,
|
||||
struct buf *bp;
|
||||
struct ext2fs_extattr_dinode_header *header;
|
||||
struct ext2fs_extattr_entry *entry;
|
||||
const char *attr_name;
|
||||
int name_len;
|
||||
int error;
|
||||
|
||||
fs = ip->i_e2fs;
|
||||
@ -147,17 +206,26 @@ ext2_extattr_inode_list(struct inode *ip, int attrnamespace,
|
||||
|
||||
for (entry = EXT2_IFIRST(header); !EXT2_IS_LAST_ENTRY(entry);
|
||||
entry = EXT2_EXTATTR_NEXT(entry)) {
|
||||
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
|
||||
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
|
||||
attrnamespace)
|
||||
continue;
|
||||
|
||||
name_len = entry->e_name_len;
|
||||
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
|
||||
entry->e_name, &name_len);
|
||||
if (!attr_name) {
|
||||
brelse(bp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
if (uio == NULL)
|
||||
*size += entry->e_name_len + 1;
|
||||
*size += name_len + 1;
|
||||
else {
|
||||
char *attr_name = malloc(entry->e_name_len + 1, M_TEMP, M_WAITOK);
|
||||
attr_name[0] = entry->e_name_len;
|
||||
memcpy(&attr_name[1], entry->e_name, entry->e_name_len);
|
||||
error = uiomove(attr_name, entry->e_name_len + 1, uio);
|
||||
free(attr_name, M_TEMP);
|
||||
char *name = malloc(name_len + 1, M_TEMP, M_WAITOK);
|
||||
name[0] = name_len;
|
||||
memcpy(&name[1], attr_name, name_len);
|
||||
error = uiomove(name, name_len + 1, uio);
|
||||
free(name, M_TEMP);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
@ -176,6 +244,8 @@ ext2_extattr_block_list(struct inode *ip, int attrnamespace,
|
||||
struct buf *bp;
|
||||
struct ext2fs_extattr_header *header;
|
||||
struct ext2fs_extattr_entry *entry;
|
||||
const char *attr_name;
|
||||
int name_len;
|
||||
int error;
|
||||
|
||||
fs = ip->i_e2fs;
|
||||
@ -202,17 +272,26 @@ ext2_extattr_block_list(struct inode *ip, int attrnamespace,
|
||||
|
||||
for (entry = EXT2_FIRST_ENTRY(bp); !EXT2_IS_LAST_ENTRY(entry);
|
||||
entry = EXT2_EXTATTR_NEXT(entry)) {
|
||||
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
|
||||
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
|
||||
attrnamespace)
|
||||
continue;
|
||||
|
||||
name_len = entry->e_name_len;
|
||||
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
|
||||
entry->e_name, &name_len);
|
||||
if (!attr_name) {
|
||||
brelse(bp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
if (uio == NULL)
|
||||
*size += entry->e_name_len + 1;
|
||||
*size += name_len + 1;
|
||||
else {
|
||||
char *attr_name = malloc(entry->e_name_len + 1, M_TEMP, M_WAITOK);
|
||||
attr_name[0] = entry->e_name_len;
|
||||
memcpy(&attr_name[1], entry->e_name, entry->e_name_len);
|
||||
error = uiomove(attr_name, entry->e_name_len + 1, uio);
|
||||
free(attr_name, M_TEMP);
|
||||
char *name = malloc(name_len + 1, M_TEMP, M_WAITOK);
|
||||
name[0] = name_len;
|
||||
memcpy(&name[1], attr_name, name_len);
|
||||
error = uiomove(name, name_len + 1, uio);
|
||||
free(name, M_TEMP);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
@ -231,6 +310,8 @@ ext2_extattr_inode_get(struct inode *ip, int attrnamespace,
|
||||
struct buf *bp;
|
||||
struct ext2fs_extattr_dinode_header *header;
|
||||
struct ext2fs_extattr_entry *entry;
|
||||
const char *attr_name;
|
||||
int name_len;
|
||||
int error;
|
||||
|
||||
fs = ip->i_e2fs;
|
||||
@ -264,11 +345,20 @@ ext2_extattr_inode_get(struct inode *ip, int attrnamespace,
|
||||
|
||||
for (entry = EXT2_IFIRST(header); !EXT2_IS_LAST_ENTRY(entry);
|
||||
entry = EXT2_EXTATTR_NEXT(entry)) {
|
||||
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
|
||||
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
|
||||
attrnamespace)
|
||||
continue;
|
||||
|
||||
if (strlen(name) == entry->e_name_len &&
|
||||
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
|
||||
name_len = entry->e_name_len;
|
||||
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
|
||||
entry->e_name, &name_len);
|
||||
if (!attr_name) {
|
||||
brelse(bp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
if (strlen(name) == name_len &&
|
||||
0 == strncmp(attr_name, name, name_len)) {
|
||||
if (uio == NULL)
|
||||
*size += entry->e_value_size;
|
||||
else {
|
||||
@ -294,6 +384,8 @@ ext2_extattr_block_get(struct inode *ip, int attrnamespace,
|
||||
struct buf *bp;
|
||||
struct ext2fs_extattr_header *header;
|
||||
struct ext2fs_extattr_entry *entry;
|
||||
const char *attr_name;
|
||||
int name_len;
|
||||
int error;
|
||||
|
||||
fs = ip->i_e2fs;
|
||||
@ -320,11 +412,20 @@ ext2_extattr_block_get(struct inode *ip, int attrnamespace,
|
||||
|
||||
for (entry = EXT2_FIRST_ENTRY(bp); !EXT2_IS_LAST_ENTRY(entry);
|
||||
entry = EXT2_EXTATTR_NEXT(entry)) {
|
||||
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
|
||||
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
|
||||
attrnamespace)
|
||||
continue;
|
||||
|
||||
if (strlen(name) == entry->e_name_len &&
|
||||
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
|
||||
name_len = entry->e_name_len;
|
||||
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
|
||||
entry->e_name, &name_len);
|
||||
if (!attr_name) {
|
||||
brelse(bp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
if (strlen(name) == name_len &&
|
||||
0 == strncmp(attr_name, name, name_len)) {
|
||||
if (uio == NULL)
|
||||
*size += entry->e_value_size;
|
||||
else {
|
||||
@ -411,6 +512,8 @@ ext2_extattr_inode_delete(struct inode *ip, int attrnamespace, const char *name)
|
||||
struct buf *bp;
|
||||
struct ext2fs_extattr_dinode_header *header;
|
||||
struct ext2fs_extattr_entry *entry;
|
||||
const char *attr_name;
|
||||
int name_len;
|
||||
int error;
|
||||
|
||||
fs = ip->i_e2fs;
|
||||
@ -444,9 +547,20 @@ ext2_extattr_inode_delete(struct inode *ip, int attrnamespace, const char *name)
|
||||
|
||||
/* If I am last entry, just make magic zero */
|
||||
entry = EXT2_IFIRST(header);
|
||||
if (EXT2_IS_LAST_ENTRY(EXT2_EXTATTR_NEXT(entry))) {
|
||||
if (strlen(name) == entry->e_name_len &&
|
||||
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
|
||||
if ((EXT2_IS_LAST_ENTRY(EXT2_EXTATTR_NEXT(entry))) &&
|
||||
(ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) ==
|
||||
attrnamespace)) {
|
||||
|
||||
name_len = entry->e_name_len;
|
||||
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
|
||||
entry->e_name, &name_len);
|
||||
if (!attr_name) {
|
||||
brelse(bp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
if (strlen(name) == name_len &&
|
||||
0 == strncmp(attr_name, name, name_len)) {
|
||||
memset(header, 0, sizeof(struct ext2fs_extattr_dinode_header));
|
||||
|
||||
return (bwrite(bp));
|
||||
@ -455,11 +569,20 @@ ext2_extattr_inode_delete(struct inode *ip, int attrnamespace, const char *name)
|
||||
|
||||
for (entry = EXT2_IFIRST(header); !EXT2_IS_LAST_ENTRY(entry);
|
||||
entry = EXT2_EXTATTR_NEXT(entry)) {
|
||||
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
|
||||
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
|
||||
attrnamespace)
|
||||
continue;
|
||||
|
||||
if (strlen(name) == entry->e_name_len &&
|
||||
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
|
||||
name_len = entry->e_name_len;
|
||||
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
|
||||
entry->e_name, &name_len);
|
||||
if (!attr_name) {
|
||||
brelse(bp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
if (strlen(name) == name_len &&
|
||||
0 == strncmp(attr_name, name, name_len)) {
|
||||
ext2_extattr_delete_entry((char *)EXT2_IFIRST(header),
|
||||
EXT2_IFIRST(header), entry,
|
||||
(char *)dinode + EXT2_INODE_SIZE(fs));
|
||||
@ -521,6 +644,8 @@ ext2_extattr_block_delete(struct inode *ip, int attrnamespace, const char *name)
|
||||
struct buf *bp;
|
||||
struct ext2fs_extattr_header *header;
|
||||
struct ext2fs_extattr_entry *entry;
|
||||
const char *attr_name;
|
||||
int name_len;
|
||||
int error;
|
||||
|
||||
fs = ip->i_e2fs;
|
||||
@ -555,9 +680,20 @@ ext2_extattr_block_delete(struct inode *ip, int attrnamespace, const char *name)
|
||||
|
||||
/* If I am last entry, clean me and free the block */
|
||||
entry = EXT2_FIRST_ENTRY(bp);
|
||||
if (EXT2_IS_LAST_ENTRY(EXT2_EXTATTR_NEXT(entry))) {
|
||||
if (strlen(name) == entry->e_name_len &&
|
||||
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
|
||||
if (EXT2_IS_LAST_ENTRY(EXT2_EXTATTR_NEXT(entry)) &&
|
||||
(ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) ==
|
||||
attrnamespace)) {
|
||||
|
||||
name_len = entry->e_name_len;
|
||||
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
|
||||
entry->e_name, &name_len);
|
||||
if (!attr_name) {
|
||||
brelse(bp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
if (strlen(name) == name_len &&
|
||||
0 == strncmp(attr_name, name, name_len)) {
|
||||
ip->i_blocks -= btodb(fs->e2fs_bsize);
|
||||
ext2_blkfree(ip, ip->i_facl, fs->e2fs_bsize);
|
||||
ip->i_facl = 0;
|
||||
@ -570,11 +706,20 @@ ext2_extattr_block_delete(struct inode *ip, int attrnamespace, const char *name)
|
||||
|
||||
for (entry = EXT2_FIRST_ENTRY(bp); !EXT2_IS_LAST_ENTRY(entry);
|
||||
entry = EXT2_EXTATTR_NEXT(entry)) {
|
||||
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
|
||||
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
|
||||
attrnamespace)
|
||||
continue;
|
||||
|
||||
if (strlen(name) == entry->e_name_len &&
|
||||
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
|
||||
name_len = entry->e_name_len;
|
||||
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
|
||||
entry->e_name, &name_len);
|
||||
if (!attr_name) {
|
||||
brelse(bp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
if (strlen(name) == name_len &&
|
||||
0 == strncmp(attr_name, name, name_len)) {
|
||||
ext2_extattr_delete_entry(bp->b_data,
|
||||
EXT2_FIRST_ENTRY(bp), entry,
|
||||
bp->b_data + bp->b_bufsize);
|
||||
@ -592,15 +737,18 @@ static struct ext2fs_extattr_entry *
|
||||
allocate_entry(const char *name, int attrnamespace, uint16_t offs,
|
||||
uint32_t size, uint32_t hash)
|
||||
{
|
||||
size_t name_len;
|
||||
const char *attr_name;
|
||||
int name_len;
|
||||
struct ext2fs_extattr_entry *entry;
|
||||
|
||||
name_len = strlen(name);
|
||||
attr_name = ext2_extattr_name_to_linux(attrnamespace, name);
|
||||
name_len = strlen(attr_name);
|
||||
|
||||
entry = malloc(sizeof(struct ext2fs_extattr_entry) + name_len,
|
||||
M_TEMP, M_WAITOK);
|
||||
|
||||
entry->e_name_len = name_len;
|
||||
entry->e_name_index = ext2_extattr_index_to_linux(attrnamespace);
|
||||
entry->e_name_index = ext2_extattr_attrnamespace_to_linux(attrnamespace, name);
|
||||
entry->e_value_offs = offs;
|
||||
entry->e_value_block = 0;
|
||||
entry->e_value_size = size;
|
||||
@ -727,6 +875,8 @@ ext2_extattr_inode_set(struct inode *ip, int attrnamespace,
|
||||
struct buf *bp;
|
||||
struct ext2fs_extattr_dinode_header *header;
|
||||
struct ext2fs_extattr_entry *entry;
|
||||
const char *attr_name;
|
||||
int name_len;
|
||||
size_t size = 0, max_size;
|
||||
int error;
|
||||
|
||||
@ -762,11 +912,20 @@ ext2_extattr_inode_set(struct inode *ip, int attrnamespace,
|
||||
/* Find if entry exist */
|
||||
for (entry = EXT2_IFIRST(header); !EXT2_IS_LAST_ENTRY(entry);
|
||||
entry = EXT2_EXTATTR_NEXT(entry)) {
|
||||
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
|
||||
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
|
||||
attrnamespace)
|
||||
continue;
|
||||
|
||||
if (strlen(name) == entry->e_name_len &&
|
||||
0 == strncmp(entry->e_name, name, entry->e_name_len))
|
||||
name_len = entry->e_name_len;
|
||||
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
|
||||
entry->e_name, &name_len);
|
||||
if (!attr_name) {
|
||||
brelse(bp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
if (strlen(name) == name_len &&
|
||||
0 == strncmp(attr_name, name, name_len))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -876,6 +1035,8 @@ ext2_extattr_block_set(struct inode *ip, int attrnamespace,
|
||||
struct buf *bp;
|
||||
struct ext2fs_extattr_header *header;
|
||||
struct ext2fs_extattr_entry *entry;
|
||||
const char *attr_name;
|
||||
int name_len;
|
||||
size_t size;
|
||||
int error;
|
||||
|
||||
@ -916,11 +1077,20 @@ ext2_extattr_block_set(struct inode *ip, int attrnamespace,
|
||||
/* Find if entry exist */
|
||||
for (entry = EXT2_FIRST_ENTRY(bp); !EXT2_IS_LAST_ENTRY(entry);
|
||||
entry = EXT2_EXTATTR_NEXT(entry)) {
|
||||
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
|
||||
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
|
||||
attrnamespace)
|
||||
continue;
|
||||
|
||||
if (strlen(name) == entry->e_name_len &&
|
||||
0 == strncmp(entry->e_name, name, entry->e_name_len))
|
||||
name_len = entry->e_name_len;
|
||||
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
|
||||
entry->e_name, &name_len);
|
||||
if (!attr_name) {
|
||||
brelse(bp);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
if (strlen(name) == name_len &&
|
||||
0 == strncmp(attr_name, name, name_len))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -961,7 +1131,8 @@ ext2_extattr_block_set(struct inode *ip, int attrnamespace,
|
||||
}
|
||||
|
||||
size = ext2_extattr_get_size(NULL, NULL,
|
||||
sizeof(struct ext2fs_extattr_header), strlen(name), uio->uio_resid);
|
||||
sizeof(struct ext2fs_extattr_header),
|
||||
strlen(ext2_extattr_name_to_linux(attrnamespace, name)), uio->uio_resid);
|
||||
if (size > fs->e2fs_bsize)
|
||||
return (ENOSPC);
|
||||
|
||||
|
@ -81,6 +81,7 @@
|
||||
|
||||
#include <fs/ext2fs/fs.h>
|
||||
#include <fs/ext2fs/inode.h>
|
||||
#include <fs/ext2fs/ext2_acl.h>
|
||||
#include <fs/ext2fs/ext2_extern.h>
|
||||
#include <fs/ext2fs/ext2fs.h>
|
||||
#include <fs/ext2fs/ext2_dinode.h>
|
||||
@ -163,6 +164,9 @@ struct vop_vector ext2_vnodeops = {
|
||||
.vop_getextattr = ext2_getextattr,
|
||||
.vop_listextattr = ext2_listextattr,
|
||||
.vop_setextattr = ext2_setextattr,
|
||||
.vop_getacl = ext2_getacl,
|
||||
.vop_setacl = ext2_setacl,
|
||||
.vop_aclcheck = ext2_aclcheck,
|
||||
.vop_vptofh = ext2_vptofh,
|
||||
};
|
||||
|
||||
@ -1083,6 +1087,150 @@ ext2_rename(struct vop_rename_args *ap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ext2_do_posix1e_acl_inheritance_dir(struct vnode *dvp, struct vnode *tvp,
|
||||
mode_t dmode, struct ucred *cred, struct thread *td)
|
||||
{
|
||||
int error;
|
||||
struct inode *ip = VTOI(tvp);
|
||||
struct acl *dacl, *acl;
|
||||
|
||||
acl = acl_alloc(M_WAITOK);
|
||||
dacl = acl_alloc(M_WAITOK);
|
||||
|
||||
/*
|
||||
* Retrieve default ACL from parent, if any.
|
||||
*/
|
||||
error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cred, td);
|
||||
switch (error) {
|
||||
case 0:
|
||||
/*
|
||||
* Retrieved a default ACL, so merge mode and ACL if
|
||||
* necessary. If the ACL is empty, fall through to
|
||||
* the "not defined or available" case.
|
||||
*/
|
||||
if (acl->acl_cnt != 0) {
|
||||
dmode = acl_posix1e_newfilemode(dmode, acl);
|
||||
ip->i_mode = dmode;
|
||||
*dacl = *acl;
|
||||
ext2_sync_acl_from_inode(ip, acl);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case EOPNOTSUPP:
|
||||
/*
|
||||
* Just use the mode as-is.
|
||||
*/
|
||||
ip->i_mode = dmode;
|
||||
error = 0;
|
||||
goto out;
|
||||
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cred, td);
|
||||
if (error == 0)
|
||||
error = VOP_SETACL(tvp, ACL_TYPE_DEFAULT, dacl, cred, td);
|
||||
switch (error) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case EOPNOTSUPP:
|
||||
/*
|
||||
* XXX: This should not happen, as EOPNOTSUPP above
|
||||
* was supposed to free acl.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
printf("ext2_mkdir: VOP_GETACL() but no VOP_SETACL()\n");
|
||||
#endif /* DEBUG */
|
||||
break;
|
||||
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
acl_free(acl);
|
||||
acl_free(dacl);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ext2_do_posix1e_acl_inheritance_file(struct vnode *dvp, struct vnode *tvp,
|
||||
mode_t mode, struct ucred *cred, struct thread *td)
|
||||
{
|
||||
int error;
|
||||
struct inode *ip = VTOI(tvp);
|
||||
struct acl *acl;
|
||||
|
||||
acl = acl_alloc(M_WAITOK);
|
||||
|
||||
/*
|
||||
* Retrieve default ACL for parent, if any.
|
||||
*/
|
||||
error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cred, td);
|
||||
switch (error) {
|
||||
case 0:
|
||||
/*
|
||||
* Retrieved a default ACL, so merge mode and ACL if
|
||||
* necessary.
|
||||
*/
|
||||
if (acl->acl_cnt != 0) {
|
||||
/*
|
||||
* Two possible ways for default ACL to not
|
||||
* be present. First, the EA can be
|
||||
* undefined, or second, the default ACL can
|
||||
* be blank. If it's blank, fall through to
|
||||
* the it's not defined case.
|
||||
*/
|
||||
mode = acl_posix1e_newfilemode(mode, acl);
|
||||
ip->i_mode = mode;
|
||||
ext2_sync_acl_from_inode(ip, acl);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case EOPNOTSUPP:
|
||||
/*
|
||||
* Just use the mode as-is.
|
||||
*/
|
||||
ip->i_mode = mode;
|
||||
error = 0;
|
||||
goto out;
|
||||
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cred, td);
|
||||
switch (error) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case EOPNOTSUPP:
|
||||
/*
|
||||
* XXX: This should not happen, as EOPNOTSUPP above was
|
||||
* supposed to free acl.
|
||||
*/
|
||||
printf("ufs_do_posix1e_acl_inheritance_file: VOP_GETACL() "
|
||||
"but no VOP_SETACL()\n");
|
||||
/* panic("ufs_do_posix1e_acl_inheritance_file: VOP_GETACL() "
|
||||
"but no VOP_SETACL()"); */
|
||||
break;
|
||||
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
acl_free(acl);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mkdir system call
|
||||
*/
|
||||
@ -1192,6 +1340,13 @@ ext2_mkdir(struct vop_mkdir_args *ap)
|
||||
ip->i_flag |= IN_CHANGE;
|
||||
}
|
||||
|
||||
if (dvp->v_mount->mnt_flag & MNT_ACLS) {
|
||||
error = ext2_do_posix1e_acl_inheritance_dir(dvp, tvp, dmode,
|
||||
cnp->cn_cred, cnp->cn_thread);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Directory set up, now install its entry in the parent directory. */
|
||||
error = ext2_direnter(ip, dvp, cnp);
|
||||
if (error) {
|
||||
@ -1446,6 +1601,18 @@ ext2_pathconf(struct vop_pathconf_args *ap)
|
||||
case _PC_NO_TRUNC:
|
||||
*ap->a_retval = 1;
|
||||
break;
|
||||
case _PC_ACL_EXTENDED:
|
||||
if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS)
|
||||
*ap->a_retval = 1;
|
||||
else
|
||||
*ap->a_retval = 0;
|
||||
break;
|
||||
case _PC_ACL_PATH_MAX:
|
||||
if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS)
|
||||
*ap->a_retval = ACL_MAX_ENTRIES;
|
||||
else
|
||||
*ap->a_retval = 3;
|
||||
break;
|
||||
case _PC_MIN_HOLE_SIZE:
|
||||
*ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
|
||||
break;
|
||||
@ -1513,6 +1680,8 @@ ext2_deleteextattr(struct vop_deleteextattr_args *ap)
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = ENOATTR;
|
||||
|
||||
if (EXT2_INODE_SIZE(fs) != E2FS_REV0_INODE_SIZE) {
|
||||
error = ext2_extattr_inode_delete(ip, ap->a_attrnamespace, ap->a_name);
|
||||
if (error != ENOATTR)
|
||||
@ -1552,6 +1721,8 @@ ext2_getextattr(struct vop_getextattr_args *ap)
|
||||
if (ap->a_size != NULL)
|
||||
*ap->a_size = 0;
|
||||
|
||||
error = ENOATTR;
|
||||
|
||||
if (EXT2_INODE_SIZE(fs) != E2FS_REV0_INODE_SIZE) {
|
||||
error = ext2_extattr_inode_get(ip, ap->a_attrnamespace,
|
||||
ap->a_name, ap->a_uio, ap->a_size);
|
||||
@ -1755,6 +1926,14 @@ ext2_makeinode(int mode, struct vnode *dvp, struct vnode **vpp,
|
||||
error = ext2_update(tvp, !DOINGASYNC(tvp));
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
if (dvp->v_mount->mnt_flag & MNT_ACLS) {
|
||||
error = ext2_do_posix1e_acl_inheritance_file(dvp, tvp, mode,
|
||||
cnp->cn_cred, cnp->cn_thread);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
error = ext2_direnter(ip, dvp, cnp);
|
||||
if (error)
|
||||
goto bad;
|
||||
|
@ -490,14 +490,13 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper,
|
||||
* from the value used for the top level server volume
|
||||
* in the mounted subtree.
|
||||
*/
|
||||
if (vp->v_mount->mnt_stat.f_fsid.val[0] !=
|
||||
(uint32_t)np->n_vattr.na_filesid[0])
|
||||
vap->va_fsid = (uint32_t)np->n_vattr.na_filesid[0];
|
||||
else
|
||||
vap->va_fsid = (uint32_t)hash32_buf(
|
||||
vn_fsid(vp, vap);
|
||||
vap->va_fsid = np->n_vattr.na_filesid[0];
|
||||
if (vap->va_fsid == np->n_vattr.na_filesid[0])
|
||||
vap->va_fsid = hash32_buf(
|
||||
np->n_vattr.na_filesid, 2 * sizeof(uint64_t), 0);
|
||||
} else
|
||||
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
|
||||
vn_fsid(vp, vap);
|
||||
np->n_attrstamp = time_second;
|
||||
if (vap->va_size != np->n_size) {
|
||||
if (vap->va_type == VREG) {
|
||||
|
@ -359,6 +359,10 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
inpcb = (struct inpcb *)(so->so_pcb);
|
||||
kif->kf_un.kf_sock.kf_sock_inpcb =
|
||||
(uintptr_t)inpcb->inp_ppcb;
|
||||
kif->kf_un.kf_sock.kf_sock_sendq =
|
||||
sbused(&so->so_snd);
|
||||
kif->kf_un.kf_sock.kf_sock_recvq =
|
||||
sbused(&so->so_rcv);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -372,6 +376,10 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
so->so_rcv.sb_state;
|
||||
kif->kf_un.kf_sock.kf_sock_snd_sb_state =
|
||||
so->so_snd.sb_state;
|
||||
kif->kf_un.kf_sock.kf_sock_sendq =
|
||||
sbused(&so->so_snd);
|
||||
kif->kf_un.kf_sock.kf_sock_recvq =
|
||||
sbused(&so->so_rcv);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2493,3 +2493,14 @@ vn_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size,
|
||||
#endif
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
vn_fsid(struct vnode *vp, struct vattr *va)
|
||||
{
|
||||
fsid_t *f;
|
||||
|
||||
f = &vp->v_mount->mnt_stat.f_fsid;
|
||||
va->va_fsid = (uint32_t)f->val[1];
|
||||
va->va_fsid <<= sizeof(f->val[1]) * NBBY;
|
||||
va->va_fsid += (uint32_t)f->val[0];
|
||||
}
|
||||
|
@ -528,13 +528,14 @@ typedef enum {
|
||||
#define AR71XX_SPI_RDS 0x0C
|
||||
|
||||
#define ATH_READ_REG(reg) \
|
||||
*((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg)))
|
||||
|
||||
*((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg)))
|
||||
/*
|
||||
* Note: Don't put a flush read here; some users (eg the AR724x PCI fixup code)
|
||||
* requires write-only space to certain registers. Doing the read afterwards
|
||||
* causes things to break.
|
||||
*/
|
||||
#define ATH_WRITE_REG(reg, val) \
|
||||
do { \
|
||||
*((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val); \
|
||||
(void) ATH_READ_REG(reg); \
|
||||
} while (0)
|
||||
*((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val)
|
||||
|
||||
static inline void
|
||||
ar71xx_ddr_flush(uint32_t reg)
|
||||
|
@ -208,7 +208,7 @@ bcm_get_uart_rclk(struct bcm_platform *bp)
|
||||
uint64_t
|
||||
bcm_get_alpfreq(struct bcm_platform *bp) {
|
||||
if (!bcm_has_pmu(bp))
|
||||
panic("%s requires PMU\n", __FUNCTION__);
|
||||
return (BHND_PMU_ALP_CLOCK);
|
||||
|
||||
return (bhnd_pmu_alp_clock(bcm_get_pmu(bp)));
|
||||
}
|
||||
@ -217,7 +217,7 @@ bcm_get_alpfreq(struct bcm_platform *bp) {
|
||||
uint64_t
|
||||
bcm_get_ilpfreq(struct bcm_platform *bp) {
|
||||
if (!bcm_has_pmu(bp))
|
||||
panic("%s requires PMU\n", __FUNCTION__);
|
||||
return (BHND_PMU_ILP_CLOCK);
|
||||
|
||||
return (bhnd_pmu_ilp_clock(bcm_get_pmu(bp)));
|
||||
}
|
||||
|
@ -15,12 +15,14 @@ hint.argemdio.0.order=0
|
||||
hint.arge.0.phymask=0x10 # PHY 4
|
||||
# hint.arge.0.miimode=2 # MII
|
||||
hint.arge.0.mdio=mdioproxy1 # Hanging off the arswitch MDIO bus
|
||||
hint.arge.0.eeprommac=0x1fff0000
|
||||
|
||||
# arge1: connected to the LAN switch MAC, at 1000BaseTX / GMII.
|
||||
hint.arge.1.phymask=0x0
|
||||
# hint.arge.1.miimode=1 # GMII
|
||||
hint.arge.1.media=1000 # Force to 1000BaseTX/full
|
||||
hint.arge.1.fduplex=1
|
||||
hint.arge.1.eeprommac=0x1fff0006
|
||||
|
||||
#
|
||||
# AR7240 switch config
|
||||
@ -94,29 +96,15 @@ hint.map.1.readonly=1
|
||||
|
||||
hint.map.2.at="flash/spi0"
|
||||
hint.map.2.start=0x00080000
|
||||
# hint.map.2.end=0x00380000
|
||||
hint.map.2.end=0x00780000
|
||||
# hint.map.2.name="spare-rootfs"
|
||||
hint.map.2.name="rootfs"
|
||||
hint.map.2.readonly=1
|
||||
|
||||
#hint.map.3.at="flash/spi0"
|
||||
#hint.map.3.start=0x00380000
|
||||
#hint.map.3.end=0x00480000
|
||||
#hint.map.3.name="spare-uImage"
|
||||
#hint.map.3.readonly=1
|
||||
|
||||
#hint.map.4.at="flash/spi0"
|
||||
#hint.map.4.start=0x00480000
|
||||
#hint.map.4.end=0x00780000
|
||||
#hint.map.4.name="rootfs"
|
||||
#hint.map.4.readonly=1
|
||||
hint.map.2.end="search:0x00080000:0x10000:.!/bin/sh"
|
||||
hint.map.2.name="kernel"
|
||||
hint.map.2.readonly=0
|
||||
|
||||
hint.map.3.at="flash/spi0"
|
||||
hint.map.3.start=0x00780000
|
||||
hint.map.3.start="search:0x00080000:0x10000:.!/bin/sh"
|
||||
hint.map.3.end=0x00880000
|
||||
hint.map.3.name="uImage"
|
||||
hint.map.3.readonly=1
|
||||
hint.map.3.name="rootfs"
|
||||
hint.map.3.readonly=0
|
||||
|
||||
hint.map.4.at="flash/spi0"
|
||||
hint.map.4.start=0x00880000
|
||||
|
@ -25,13 +25,14 @@ makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
|
||||
|
||||
# Build these as modules so small platform builds will have the
|
||||
# modules already built.
|
||||
makeoptions MODULES_OVERRIDE="gpio ar71xx if_gif if_gre if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath ath_pci hwpmc cam"
|
||||
makeoptions MODULES_OVERRIDE="gpio ar71xx if_gif if_gre if_tap if_tun libalias ipfw ipfw_nat ipfw_nptv6 if_vlan if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath_main ath_pci ath_hal ath_hal_ar5212 ath_hal_ar5416 ath_hal_ar9300 ath_rate ath_dfs hwpmc hwpmc_mips24k cam"
|
||||
|
||||
# For small memory footprints
|
||||
options VM_KMEM_SIZE_SCALE=1
|
||||
|
||||
options DDB
|
||||
options KDB
|
||||
options EARLY_PRINTF
|
||||
|
||||
options SCHED_4BSD #4BSD scheduler
|
||||
options INET #InterNETworking
|
||||
@ -59,11 +60,16 @@ options NO_SYSCTL_DESCR
|
||||
|
||||
options FFS #Berkeley Fast Filesystem
|
||||
options NO_FFS_SNAPSHOT
|
||||
|
||||
options IPFIREWALL_DEFAULT_TO_ACCEPT
|
||||
|
||||
# options SOFTUPDATES #Enable FFS soft updates support
|
||||
# options UFS_ACL #Support for access control lists
|
||||
# options UFS_DIRHASH #Improve performance on big directories
|
||||
# options MSDOSFS # Read MSDOS filesystems; useful for USB/CF
|
||||
|
||||
options UMTX_CHAINS=16
|
||||
|
||||
device pci
|
||||
device ar724x_pci
|
||||
|
||||
@ -129,7 +135,7 @@ device loop
|
||||
device ether
|
||||
device md
|
||||
device bpf
|
||||
#device random
|
||||
device random
|
||||
#device if_bridge
|
||||
#device gif # ip[46] in ip[46] tunneling protocol
|
||||
#device gre # generic encapsulation - only for IPv4 in IPv4 though atm
|
||||
|
@ -3,8 +3,8 @@
|
||||
.PATH: ${SRCTOP}/sys/fs/ext2fs
|
||||
KMOD= ext2fs
|
||||
SRCS= opt_ddb.h opt_directio.h opt_quota.h opt_suiddir.h vnode_if.h \
|
||||
ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_extattr.c ext2_extents.c \
|
||||
ext2_hash.c ext2_htree.c ext2_inode.c ext2_inode_cnv.c ext2_lookup.c \
|
||||
ext2_subr.c ext2_vfsops.c ext2_vnops.c
|
||||
ext2_acl.c ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_extattr.c \
|
||||
ext2_extents.c ext2_hash.c ext2_htree.c ext2_inode.c ext2_inode_cnv.c \
|
||||
ext2_lookup.c ext2_subr.c ext2_vfsops.c ext2_vnops.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -15,7 +15,7 @@ SRCS= linux_fork.c linux${SFX}_dummy.c linux_file.c linux_event.c \
|
||||
linux${SFX}_machdep.c linux_misc.c linux_signal.c \
|
||||
linux_socket.c linux_stats.c linux_sysctl.c linux${SFX}_sysent.c \
|
||||
linux${SFX}_sysvec.c linux_uid16.c linux_time.c \
|
||||
linux_timer.c linux_vdso.c \
|
||||
linux_timer.c linux_vdso.c opt_global.h \
|
||||
opt_inet6.h opt_compat.h opt_posix.h opt_usb.h vnode_if.h \
|
||||
device_if.h bus_if.h assym.s \
|
||||
linux${SFX}_support.s
|
||||
@ -64,10 +64,12 @@ linux${SFX}_support.o: linux${SFX}_assym.h assym.s
|
||||
${VDSO}.so: linux${SFX}_locore.o
|
||||
${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd \
|
||||
--binary-architecture i386 linux${SFX}_locore.o ${.TARGET}
|
||||
strip -N _binary_linux${SFX}_locore_o_size ${.TARGET}
|
||||
.else
|
||||
${VDSO}.so: linux${SFX}_locore.o
|
||||
${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd \
|
||||
--binary-architecture i386 linux${SFX}_locore.o ${.TARGET}
|
||||
strip -N _binary_linux_locore_o_size ${.TARGET}
|
||||
.endif
|
||||
|
||||
linux${SFX}_genassym.o:
|
||||
|
@ -10,7 +10,7 @@ SRCS= linux_fork.c linux_dummy.c linux_file.c linux_event.c \
|
||||
linux_machdep.c linux_misc.c linux_ptrace.c linux_signal.c \
|
||||
linux_socket.c linux_stats.c linux_sysctl.c linux_sysent.c \
|
||||
linux_sysvec.c linux_time.c linux_vdso.c linux_timer.c \
|
||||
opt_inet6.h opt_compat.h opt_posix.h opt_usb.h \
|
||||
opt_inet6.h opt_compat.h opt_global.h opt_posix.h opt_usb.h \
|
||||
vnode_if.h device_if.h bus_if.h assym.s \
|
||||
linux_support.s
|
||||
DPSRCS= linux_genassym.c
|
||||
@ -38,6 +38,7 @@ linux_locore.o: linux_locore.s linux_assym.h
|
||||
${VDSO}.so: linux_locore.o
|
||||
${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd \
|
||||
-S -g --binary-architecture i386:x86-64 linux_locore.o ${.TARGET}
|
||||
strip -N _binary_linux_locore_o_size ${.TARGET}
|
||||
|
||||
linux_support.o: assym.s linux_assym.h
|
||||
${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
|
||||
|
@ -572,24 +572,41 @@ static void
|
||||
lagg_capabilities(struct lagg_softc *sc)
|
||||
{
|
||||
struct lagg_port *lp;
|
||||
int cap = ~0, ena = ~0;
|
||||
u_long hwa = ~0UL;
|
||||
int cap, ena, pena;
|
||||
uint64_t hwa;
|
||||
struct ifnet_hw_tsomax hw_tsomax;
|
||||
|
||||
LAGG_XLOCK_ASSERT(sc);
|
||||
|
||||
memset(&hw_tsomax, 0, sizeof(hw_tsomax));
|
||||
/* Get common enabled capabilities for the lagg ports */
|
||||
ena = ~0;
|
||||
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
|
||||
ena &= lp->lp_ifp->if_capenable;
|
||||
ena = (ena == ~0 ? 0 : ena);
|
||||
|
||||
/* Get capabilities from the lagg ports */
|
||||
/*
|
||||
* Apply common enabled capabilities back to the lagg ports.
|
||||
* May require several iterations if they are dependent.
|
||||
*/
|
||||
do {
|
||||
pena = ena;
|
||||
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
|
||||
lagg_setcaps(lp, ena);
|
||||
ena &= lp->lp_ifp->if_capenable;
|
||||
}
|
||||
} while (pena != ena);
|
||||
|
||||
/* Get other capabilities from the lagg ports */
|
||||
cap = ~0;
|
||||
hwa = ~(uint64_t)0;
|
||||
memset(&hw_tsomax, 0, sizeof(hw_tsomax));
|
||||
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
|
||||
cap &= lp->lp_ifp->if_capabilities;
|
||||
ena &= lp->lp_ifp->if_capenable;
|
||||
hwa &= lp->lp_ifp->if_hwassist;
|
||||
if_hw_tsomax_common(lp->lp_ifp, &hw_tsomax);
|
||||
}
|
||||
cap = (cap == ~0 ? 0 : cap);
|
||||
ena = (ena == ~0 ? 0 : ena);
|
||||
hwa = (hwa == ~0 ? 0 : hwa);
|
||||
hwa = (hwa == ~(uint64_t)0 ? 0 : hwa);
|
||||
|
||||
if (sc->sc_ifp->if_capabilities != cap ||
|
||||
sc->sc_ifp->if_capenable != ena ||
|
||||
@ -604,10 +621,6 @@ lagg_capabilities(struct lagg_softc *sc)
|
||||
if_printf(sc->sc_ifp,
|
||||
"capabilities 0x%08x enabled 0x%08x\n", cap, ena);
|
||||
}
|
||||
|
||||
/* Apply unified capabilities back to the lagg ports. */
|
||||
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
|
||||
lagg_setcaps(lp, ena);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -888,6 +901,7 @@ lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
LAGG_XLOCK(sc);
|
||||
lagg_capabilities(sc);
|
||||
LAGG_XUNLOCK(sc);
|
||||
VLAN_CAPABILITIES(sc->sc_ifp);
|
||||
break;
|
||||
|
||||
case SIOCSIFMTU:
|
||||
@ -1001,6 +1015,7 @@ lagg_port_ifdetach(void *arg __unused, struct ifnet *ifp)
|
||||
lp->lp_detaching = 1;
|
||||
lagg_port_destroy(lp, 1);
|
||||
LAGG_XUNLOCK(sc);
|
||||
VLAN_CAPABILITIES(sc->sc_ifp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1360,6 +1375,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
error = lagg_port_create(sc, tpif);
|
||||
LAGG_XUNLOCK(sc);
|
||||
if_rele(tpif);
|
||||
VLAN_CAPABILITIES(ifp);
|
||||
break;
|
||||
case SIOCSLAGGDELPORT:
|
||||
error = priv_check(td, PRIV_NET_LAGG);
|
||||
@ -1383,6 +1399,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
error = lagg_port_destroy(lp, 1);
|
||||
LAGG_XUNLOCK(sc);
|
||||
if_rele(tpif);
|
||||
VLAN_CAPABILITIES(ifp);
|
||||
break;
|
||||
case SIOCSIFFLAGS:
|
||||
/* Set flags on ports too */
|
||||
@ -1433,6 +1450,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
}
|
||||
lagg_capabilities(sc);
|
||||
LAGG_XUNLOCK(sc);
|
||||
VLAN_CAPABILITIES(ifp);
|
||||
error = 0;
|
||||
break;
|
||||
|
||||
|
@ -299,7 +299,13 @@ VNET_DECLARE(int, natt_cksum_policy);
|
||||
|
||||
#define ipseclog(x) do { if (V_ipsec_debug) log x; } while (0)
|
||||
/* for openbsd compatibility */
|
||||
#ifdef IPSEC_DEBUG
|
||||
#define IPSEC_DEBUG_DECLARE(x) x
|
||||
#define DPRINTF(x) do { if (V_ipsec_debug) printf x; } while (0)
|
||||
#else
|
||||
#define IPSEC_DEBUG_DECLARE(x)
|
||||
#define DPRINTF(x)
|
||||
#endif
|
||||
|
||||
struct inpcb;
|
||||
struct m_tag;
|
||||
|
@ -117,7 +117,7 @@ __FBSDID("$FreeBSD$");
|
||||
static int
|
||||
ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
||||
{
|
||||
char buf[IPSEC_ADDRSTRLEN];
|
||||
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
|
||||
union sockaddr_union dst_address;
|
||||
struct secasvar *sav;
|
||||
uint32_t spi;
|
||||
@ -277,7 +277,7 @@ int
|
||||
ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
|
||||
int protoff)
|
||||
{
|
||||
char buf[IPSEC_ADDRSTRLEN];
|
||||
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
|
||||
struct ipsec_ctx_data ctx;
|
||||
struct xform_history *xh;
|
||||
struct secasindex *saidx;
|
||||
@ -488,7 +488,7 @@ int
|
||||
ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
|
||||
int protoff)
|
||||
{
|
||||
char buf[IPSEC_ADDRSTRLEN];
|
||||
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
|
||||
struct ipsec_ctx_data ctx;
|
||||
struct xform_history *xh;
|
||||
struct secasindex *saidx;
|
||||
|
@ -183,7 +183,6 @@ ipsec4_allocsa(struct mbuf *m, struct secpolicy *sp, u_int *pidx, int *error)
|
||||
static int
|
||||
ipsec4_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx)
|
||||
{
|
||||
char sbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
|
||||
struct ipsec_ctx_data ctx;
|
||||
union sockaddr_union *dst;
|
||||
struct secasvar *sav;
|
||||
@ -230,12 +229,9 @@ ipsec4_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx)
|
||||
ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
|
||||
error = ipsec_encap(&m, &sav->sah->saidx);
|
||||
if (error != 0) {
|
||||
DPRINTF(("%s: encapsulation for SA %s->%s "
|
||||
"SPI 0x%08x failed with error %d\n", __func__,
|
||||
ipsec_address(&sav->sah->saidx.src, sbuf,
|
||||
sizeof(sbuf)),
|
||||
ipsec_address(&sav->sah->saidx.dst, dbuf,
|
||||
sizeof(dbuf)), ntohl(sav->spi), error));
|
||||
DPRINTF(("%s: encapsulation for SPI 0x%08x failed "
|
||||
"with error %d\n", __func__, ntohl(sav->spi),
|
||||
error));
|
||||
/* XXXAE: IPSEC_OSTAT_INC(tunnel); */
|
||||
goto bad;
|
||||
}
|
||||
@ -497,7 +493,6 @@ ipsec6_allocsa(struct mbuf *m, struct secpolicy *sp, u_int *pidx, int *error)
|
||||
static int
|
||||
ipsec6_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx)
|
||||
{
|
||||
char sbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
|
||||
struct ipsec_ctx_data ctx;
|
||||
union sockaddr_union *dst;
|
||||
struct secasvar *sav;
|
||||
@ -539,12 +534,9 @@ ipsec6_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx)
|
||||
}
|
||||
error = ipsec_encap(&m, &sav->sah->saidx);
|
||||
if (error != 0) {
|
||||
DPRINTF(("%s: encapsulation for SA %s->%s "
|
||||
"SPI 0x%08x failed with error %d\n", __func__,
|
||||
ipsec_address(&sav->sah->saidx.src, sbuf,
|
||||
sizeof(sbuf)),
|
||||
ipsec_address(&sav->sah->saidx.dst, dbuf,
|
||||
sizeof(dbuf)), ntohl(sav->spi), error));
|
||||
DPRINTF(("%s: encapsulation for SPI 0x%08x failed "
|
||||
"with error %d\n", __func__, ntohl(sav->spi),
|
||||
error));
|
||||
/* XXXAE: IPSEC_OSTAT_INC(tunnel); */
|
||||
goto bad;
|
||||
}
|
||||
|
@ -53,10 +53,14 @@
|
||||
#define KEYDEBUG_IPSEC_DATA (KEYDEBUG_IPSEC | KEYDEBUG_DATA)
|
||||
#define KEYDEBUG_IPSEC_DUMP (KEYDEBUG_IPSEC | KEYDEBUG_DUMP)
|
||||
|
||||
#ifdef IPSEC_DEBUG
|
||||
#define KEYDBG(lev, arg) \
|
||||
if ((V_key_debug_level & (KEYDEBUG_ ## lev)) == (KEYDEBUG_ ## lev)) { \
|
||||
arg; \
|
||||
}
|
||||
#else
|
||||
#define KEYDBG(lev, arg)
|
||||
#endif /* !IPSEC_DEBUG */
|
||||
|
||||
VNET_DECLARE(uint32_t, key_debug_level);
|
||||
#define V_key_debug_level VNET(key_debug_level)
|
||||
|
@ -544,7 +544,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
||||
static int
|
||||
ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
||||
{
|
||||
char buf[128];
|
||||
IPSEC_DEBUG_DECLARE(char buf[128]);
|
||||
const struct auth_hash *ahx;
|
||||
struct cryptodesc *crda;
|
||||
struct cryptop *crp;
|
||||
@ -681,7 +681,7 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
||||
static int
|
||||
ah_input_cb(struct cryptop *crp)
|
||||
{
|
||||
char buf[IPSEC_ADDRSTRLEN];
|
||||
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
|
||||
unsigned char calc[AH_ALEN_MAX];
|
||||
const struct auth_hash *ahx;
|
||||
struct mbuf *m;
|
||||
@ -831,7 +831,7 @@ static int
|
||||
ah_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
|
||||
u_int idx, int skip, int protoff)
|
||||
{
|
||||
char buf[IPSEC_ADDRSTRLEN];
|
||||
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
|
||||
const struct auth_hash *ahx;
|
||||
struct cryptodesc *crda;
|
||||
struct xform_data *xd;
|
||||
|
@ -263,7 +263,7 @@ esp_zeroize(struct secasvar *sav)
|
||||
static int
|
||||
esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
||||
{
|
||||
char buf[128];
|
||||
IPSEC_DEBUG_DECLARE(char buf[128]);
|
||||
const struct auth_hash *esph;
|
||||
const struct enc_xform *espx;
|
||||
struct xform_data *xd;
|
||||
@ -436,7 +436,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
||||
static int
|
||||
esp_input_cb(struct cryptop *crp)
|
||||
{
|
||||
char buf[128];
|
||||
IPSEC_DEBUG_DECLARE(char buf[128]);
|
||||
u_int8_t lastthree[3], aalg[AH_HMAC_MAXHASHLEN];
|
||||
const struct auth_hash *esph;
|
||||
const struct enc_xform *espx;
|
||||
@ -622,7 +622,7 @@ static int
|
||||
esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
|
||||
u_int idx, int skip, int protoff)
|
||||
{
|
||||
char buf[IPSEC_ADDRSTRLEN];
|
||||
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
|
||||
struct cryptodesc *crde = NULL, *crda = NULL;
|
||||
struct cryptop *crp;
|
||||
const struct auth_hash *esph;
|
||||
|
@ -271,7 +271,7 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
||||
static int
|
||||
ipcomp_input_cb(struct cryptop *crp)
|
||||
{
|
||||
char buf[IPSEC_ADDRSTRLEN];
|
||||
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
|
||||
struct cryptodesc *crd;
|
||||
struct xform_data *xd;
|
||||
struct mbuf *m;
|
||||
@ -387,7 +387,7 @@ static int
|
||||
ipcomp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
|
||||
u_int idx, int skip, int protoff)
|
||||
{
|
||||
char buf[IPSEC_ADDRSTRLEN];
|
||||
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
|
||||
const struct comp_algo *ipcompx;
|
||||
struct cryptodesc *crdc;
|
||||
struct cryptop *crp;
|
||||
@ -521,7 +521,7 @@ ipcomp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
|
||||
static int
|
||||
ipcomp_output_cb(struct cryptop *crp)
|
||||
{
|
||||
char buf[IPSEC_ADDRSTRLEN];
|
||||
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
|
||||
struct xform_data *xd;
|
||||
struct secpolicy *sp;
|
||||
struct secasvar *sav;
|
||||
|
@ -344,7 +344,8 @@ struct kinfo_file {
|
||||
int64_t kf_offset; /* Seek location. */
|
||||
union {
|
||||
struct {
|
||||
uint32_t kf_spareint;
|
||||
/* Sendq size */
|
||||
uint32_t kf_sock_sendq;
|
||||
/* Socket domain. */
|
||||
int kf_sock_domain0;
|
||||
/* Socket type. */
|
||||
@ -365,8 +366,8 @@ struct kinfo_file {
|
||||
uint16_t kf_sock_snd_sb_state;
|
||||
/* Receive buffer state. */
|
||||
uint16_t kf_sock_rcv_sb_state;
|
||||
/* Round to 64 bit alignment. */
|
||||
uint32_t kf_sock_pad0;
|
||||
/* Recvq size. */
|
||||
uint32_t kf_sock_recvq;
|
||||
} kf_sock;
|
||||
struct {
|
||||
/* Vnode type. */
|
||||
|
@ -885,6 +885,8 @@ int vn_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
|
||||
int vn_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
|
||||
struct thread *td);
|
||||
|
||||
void vn_fsid(struct vnode *vp, struct vattr *va);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_SYS_VNODE_H_ */
|
||||
|
@ -381,18 +381,14 @@ struct pagerops swappagerops = {
|
||||
};
|
||||
|
||||
/*
|
||||
* dmmax is in page-sized chunks with the new swap system. It was
|
||||
* dev-bsized chunks in the old. dmmax is always a power of 2.
|
||||
*
|
||||
* swap_*() routines are externally accessible. swp_*() routines are
|
||||
* internal.
|
||||
*/
|
||||
static int dmmax;
|
||||
static int nswap_lowat = 128; /* in pages, swap_pager_almost_full warn */
|
||||
static int nswap_hiwat = 512; /* in pages, swap_pager_almost_full warn */
|
||||
|
||||
SYSCTL_INT(_vm, OID_AUTO, dmmax, CTLFLAG_RD, &dmmax, 0,
|
||||
"Maximum size of a swap block");
|
||||
SYSCTL_INT(_vm, OID_AUTO, dmmax, CTLFLAG_RD, &nsw_cluster_max, 0,
|
||||
"Maximum size of a swap block in pages");
|
||||
|
||||
static void swp_sizecheck(void);
|
||||
static void swp_pager_async_iodone(struct buf *bp);
|
||||
@ -489,11 +485,6 @@ swap_pager_init(void)
|
||||
mtx_init(&sw_dev_mtx, "swapdev", NULL, MTX_DEF);
|
||||
sx_init(&sw_alloc_sx, "swspsx");
|
||||
sx_init(&swdev_syscall_lock, "swsysc");
|
||||
|
||||
/*
|
||||
* Device Stripe, in PAGE_SIZE'd blocks
|
||||
*/
|
||||
dmmax = SWB_NPAGES * 2;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2310,9 +2301,13 @@ swapoff_one(struct swdevt *sp, struct ucred *cred)
|
||||
*/
|
||||
mtx_lock(&sw_dev_mtx);
|
||||
sp->sw_flags |= SW_CLOSING;
|
||||
for (dvbase = 0; dvbase < sp->sw_end; dvbase += dmmax) {
|
||||
for (dvbase = 0; dvbase < nblks; dvbase += BLIST_BMAP_RADIX) {
|
||||
/*
|
||||
* blist_fill() cannot allocate more than BLIST_BMAP_RADIX
|
||||
* blocks per call.
|
||||
*/
|
||||
swap_pager_avail -= blist_fill(sp->sw_blist,
|
||||
dvbase, dmmax);
|
||||
dvbase, ulmin(nblks - dvbase, BLIST_BMAP_RADIX));
|
||||
}
|
||||
swap_total -= (vm_ooffset_t)nblks * PAGE_SIZE;
|
||||
mtx_unlock(&sw_dev_mtx);
|
||||
|
@ -60,14 +60,14 @@ int
|
||||
main(void)
|
||||
{
|
||||
int error, fd, fds[2], i, read_only_fd;
|
||||
char path[PATH_MAX];
|
||||
char path[] = "ftruncate_file";
|
||||
struct stat sb;
|
||||
ssize_t size;
|
||||
off_t len;
|
||||
char ch;
|
||||
|
||||
/*
|
||||
* Tests using a writable temporary file: grow and then shrink a file
|
||||
* Tests using a writable file: grow and then shrink a file
|
||||
* using ftruncate and various lengths. Make sure that a negative
|
||||
* file length is rejected. Make sure that when we grow the file,
|
||||
* bytes now in the range of the file size return 0.
|
||||
@ -75,37 +75,36 @@ main(void)
|
||||
* Save a read-only reference to the file to use later for read-only
|
||||
* descriptor tests.
|
||||
*/
|
||||
snprintf(path, PATH_MAX, "/tmp/ftruncate.XXXXXXXXXXXXX");
|
||||
fd = mkstemp(path);
|
||||
fd = open(path, O_RDWR|O_CREAT, 0600);
|
||||
if (fd < 0)
|
||||
err(-1, "mkstemp");
|
||||
err(1, "open(%s, O_RDWR|O_CREAT, 0600)", path);
|
||||
read_only_fd = open(path, O_RDONLY);
|
||||
if (read_only_fd < 0) {
|
||||
error = errno;
|
||||
(void)unlink(path);
|
||||
errno = error;
|
||||
err(-1, "open(%s, O_RDONLY)", path);
|
||||
err(1, "open(%s, O_RDONLY)", path);
|
||||
}
|
||||
(void)unlink(path);
|
||||
|
||||
if (ftruncate(fd, -1) == 0)
|
||||
errx(-1, "ftruncate(fd, -1) succeeded");
|
||||
errx(1, "ftruncate(fd, -1) succeeded unexpectedly");
|
||||
if (errno != EINVAL)
|
||||
err(-1, "ftruncate(fd, -1) returned wrong error");
|
||||
err(1, "ftruncate(fd, -1) returned wrong error");
|
||||
|
||||
for (i = 0; i < lengths_count; i++) {
|
||||
len = lengths[i];
|
||||
if (ftruncate(fd, len) < 0)
|
||||
err(-1, "ftruncate(%jd) up", (intmax_t)len);
|
||||
err(1, "ftruncate(%jd) up", (intmax_t)len);
|
||||
if (fstat(fd, &sb) < 0)
|
||||
err(-1, "stat");
|
||||
err(1, "stat");
|
||||
if (sb.st_size != len)
|
||||
errx(-1, "fstat with len=%jd returned len %jd up",
|
||||
(intmax_t)len, (intmax_t)sb.st_size);
|
||||
if (len != 0) {
|
||||
size = pread(fd, &ch, sizeof(ch), len - 1);
|
||||
if (size < 0)
|
||||
err(-1, "pread on len %jd up", (intmax_t)len);
|
||||
err(1, "pread on len %jd up", (intmax_t)len);
|
||||
if (size != sizeof(ch))
|
||||
errx(-1, "pread len %jd size %jd up",
|
||||
(intmax_t)len, (intmax_t)size);
|
||||
@ -119,9 +118,9 @@ main(void)
|
||||
for (i = lengths_count - 1; i >= 0; i--) {
|
||||
len = lengths[i];
|
||||
if (ftruncate(fd, len) < 0)
|
||||
err(-1, "ftruncate(%jd) down", (intmax_t)len);
|
||||
err(1, "ftruncate(%jd) down", (intmax_t)len);
|
||||
if (fstat(fd, &sb) < 0)
|
||||
err(-1, "stat");
|
||||
err(1, "stat");
|
||||
if (sb.st_size != len)
|
||||
errx(-1, "fstat(%jd) returned %jd down", (intmax_t)len,
|
||||
sb.st_size);
|
||||
@ -134,7 +133,7 @@ main(void)
|
||||
if (ftruncate(read_only_fd, 0) == 0)
|
||||
errx(-1, "ftruncate(read_only_fd) succeeded");
|
||||
if (errno != EINVAL)
|
||||
err(-1, "ftruncate(read_only_fd) returned wrong error");
|
||||
err(1, "ftruncate(read_only_fd) returned wrong error");
|
||||
close(read_only_fd);
|
||||
|
||||
/*
|
||||
@ -142,22 +141,22 @@ main(void)
|
||||
*/
|
||||
fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
err(-1, "socket(PF_UNIX, SOCK_STREAM, 0)");
|
||||
err(1, "socket(PF_UNIX, SOCK_STREAM, 0)");
|
||||
if (ftruncate(fd, 0) == 0)
|
||||
errx(-1, "ftruncate(socket) succeeded");
|
||||
if (errno != EINVAL)
|
||||
err(-1, "ftruncate(socket) returned wrong error");
|
||||
err(1, "ftruncate(socket) returned wrong error");
|
||||
close(fd);
|
||||
|
||||
/*
|
||||
* Make sure that ftruncate on pipes doesn't work.
|
||||
*/
|
||||
if (pipe(fds) < 0)
|
||||
err(-1, "pipe");
|
||||
err(1, "pipe");
|
||||
if (ftruncate(fds[0], 0) == 0)
|
||||
errx(-1, "ftruncate(pipe) succeeded");
|
||||
if (errno != EINVAL)
|
||||
err(-1, "ftruncate(pipe) returned wrong error");
|
||||
err(1, "ftruncate(pipe) returned wrong error");
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
|
||||
@ -166,11 +165,11 @@ main(void)
|
||||
*/
|
||||
fd = kqueue();
|
||||
if (fd < 0)
|
||||
err(-1, "kqueue");
|
||||
err(1, "kqueue");
|
||||
if (ftruncate(fds[0], 0) == 0)
|
||||
errx(-1, "ftruncate(kqueue) succeeded");
|
||||
if (errno != EINVAL)
|
||||
err(-1, "ftruncate(kqueue) returned wrong error");
|
||||
err(1, "ftruncate(kqueue) returned wrong error");
|
||||
close(fd);
|
||||
|
||||
return (0);
|
||||
|
@ -61,8 +61,9 @@ do_accept(__unused void *arg)
|
||||
|
||||
accept_fd = accept(listen_fd, NULL, NULL);
|
||||
if (accept_fd < 0)
|
||||
err(-1, "accept");
|
||||
err(1, "accept");
|
||||
|
||||
close(accept_fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -73,7 +74,7 @@ do_fork(void)
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0)
|
||||
err(-1, "fork");
|
||||
err(1, "fork");
|
||||
if (pid > 0) {
|
||||
waitpid(pid, NULL, 0);
|
||||
exit(0);
|
||||
@ -84,37 +85,37 @@ do_fork(void)
|
||||
* listen_fd+1, and get back EBADF if it's not a valid descriptor,
|
||||
* and EINVAL if it is. This (currently) works fine in practice.
|
||||
*/
|
||||
if (ftruncate(listen_fd + 1, 0 < 0)) {
|
||||
if (ftruncate(listen_fd + 1, 0) < 0) {
|
||||
if (errno == EBADF)
|
||||
exit(0);
|
||||
else if (errno == EINVAL)
|
||||
errx(-1, "file descriptor still open in child");
|
||||
errx(1, "file descriptor still open in child");
|
||||
else
|
||||
err(-1, "unexpected error");
|
||||
err(1, "unexpected error");
|
||||
} else
|
||||
errx(-1, "ftruncate succeeded");
|
||||
errx(1, "ftruncate succeeded");
|
||||
}
|
||||
|
||||
int
|
||||
main(__unused int argc, __unused char *argv[])
|
||||
main(void)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
pthread_t accept_thread;
|
||||
|
||||
listen_fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (listen_fd < 0)
|
||||
err(-1, "socket");
|
||||
err(1, "socket");
|
||||
bzero(&sin, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_len = sizeof(sin);
|
||||
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
sin.sin_port = htons(PORT);
|
||||
if (bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
|
||||
err(-1, "bind");
|
||||
err(1, "bind");
|
||||
if (listen(listen_fd, -1) <0)
|
||||
err(-1, "listen");
|
||||
err(1, "listen");
|
||||
if (pthread_create(&accept_thread, NULL, do_accept, NULL) != 0)
|
||||
err(-1, "pthread_create");
|
||||
err(1, "pthread_create");
|
||||
sleep(1); /* Easier than using a CV. */
|
||||
do_fork();
|
||||
exit(0);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user