mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-05-13 20:19:19 +08:00
Update to FreeBSD head 2016-12-10
Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
This commit is contained in:
parent
c4e89a9125
commit
75b706fde4
@ -1 +1 @@
|
||||
Subproject commit 9fe7c416e6abb28b1398fd3e5687099846800cfd
|
||||
Subproject commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c
|
@ -96,7 +96,7 @@ rtems_shell_cmd_t rtems_shell_HOSTNAME_Command = {
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch, sflag;
|
||||
int ch, sflag, dflag;
|
||||
char *p, hostname[MAXHOSTNAMELEN];
|
||||
#ifdef __rtems__
|
||||
struct getopt_data getopt_data;
|
||||
@ -107,10 +107,11 @@ main(int argc, char *argv[])
|
||||
#endif /* __rtems__ */
|
||||
|
||||
sflag = 0;
|
||||
dflag = 0;
|
||||
#ifndef __rtems__
|
||||
while ((ch = getopt(argc, argv, "fs")) != -1)
|
||||
while ((ch = getopt(argc, argv, "fsd")) != -1)
|
||||
#else /* __rtems__ */
|
||||
while ((ch = getopt(argc, argv, "fms")) != -1)
|
||||
while ((ch = getopt(argc, argv, "fdms")) != -1)
|
||||
#endif /* __rtems__ */
|
||||
switch (ch) {
|
||||
case 'f':
|
||||
@ -123,6 +124,9 @@ main(int argc, char *argv[])
|
||||
case 's':
|
||||
sflag = 1;
|
||||
break;
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
break;
|
||||
#ifdef __rtems__
|
||||
case 'm':
|
||||
mflag = 1;
|
||||
@ -135,7 +139,7 @@ main(int argc, char *argv[])
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc > 1)
|
||||
if (argc > 1 || (sflag && dflag))
|
||||
usage();
|
||||
|
||||
if (*argv) {
|
||||
@ -164,6 +168,10 @@ main(int argc, char *argv[])
|
||||
p = strchr(hostname, '.');
|
||||
if (p != NULL)
|
||||
*p = '\0';
|
||||
} else if (dflag) {
|
||||
p = strchr(hostname, '.');
|
||||
if (p != NULL)
|
||||
strcpy(hostname, ++p);
|
||||
}
|
||||
(void)printf("%s\n", hostname);
|
||||
}
|
||||
@ -174,6 +182,10 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "usage: hostname [-fms] [name-of-host]\n");
|
||||
#ifndef __rtems__
|
||||
(void)fprintf(stderr, "usage: hostname [-f] [-s | -d] [name-of-host]\n");
|
||||
#else /* __rtems__ */
|
||||
(void)fprintf(stderr, "usage: hostname [-f] [-m | -s | -d] [name-of-host]\n");
|
||||
#endif /* __rtems__ */
|
||||
exit(1);
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ static const char rcsid[] _U_ =
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifdef __rtems__
|
||||
#define HAVE_GETOPT_LONG
|
||||
#define __need_getopt_newlib
|
||||
#include <getopt.h>
|
||||
#define setpriority(a, b, c)
|
||||
@ -84,6 +85,32 @@ extern int SIZE_BUF;
|
||||
#include <smi.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
#include <openssl/crypto.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
#include <getopt.h>
|
||||
#else
|
||||
#include "getopt_long.h"
|
||||
#endif
|
||||
/* Capsicum-specific code requires macros from <net/bpf.h>, which will fail
|
||||
* to compile if <pcap.h> has already been included; including the headers
|
||||
* in the opposite order works fine.
|
||||
*/
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <libgen.h>
|
||||
#endif /* __FreeBSD__ */
|
||||
#ifdef HAVE_CASPER
|
||||
#include <libcasper.h>
|
||||
#include <casper/cap_dns.h>
|
||||
#include <sys/nv.h>
|
||||
#include <sys/ioccom.h>
|
||||
#include <net/bpf.h>
|
||||
#include <fcntl.h>
|
||||
#endif /* HAVE_CASPER */
|
||||
#include <pcap.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
@ -1619,6 +1646,26 @@ main(int argc, char **argv)
|
||||
|
||||
if (pcap_setfilter(pd, &fcode) < 0)
|
||||
error("%s", pcap_geterr(pd));
|
||||
#ifdef HAVE_CASPER
|
||||
if (RFileName == NULL && VFileName == NULL) {
|
||||
static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF };
|
||||
|
||||
/*
|
||||
* The various libpcap devices use a combination of
|
||||
* read (bpf), ioctl (bpf, netmap), poll (netmap).
|
||||
* Grant the relevant access rights, sorted by name.
|
||||
*/
|
||||
cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ);
|
||||
if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
|
||||
errno != ENOSYS) {
|
||||
error("unable to limit pcap descriptor");
|
||||
}
|
||||
if (cap_ioctls_limit(pcap_fileno(pd), cmds,
|
||||
sizeof(cmds) / sizeof(cmds[0])) < 0 && errno != ENOSYS) {
|
||||
error("unable to limit ioctls on pcap descriptor");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (WFileName) {
|
||||
pcap_dumper_t *p;
|
||||
/* Do not exceed the default PATH_MAX for files. */
|
||||
|
@ -136,7 +136,8 @@ __bt_sync(const DB *dbp, u_int flags)
|
||||
return (RET_ERROR);
|
||||
}
|
||||
|
||||
if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED))
|
||||
if (F_ISSET(t, B_INMEM | B_RDONLY) ||
|
||||
!F_ISSET(t, B_MODIFIED | B_METADIRTY))
|
||||
return (RET_SUCCESS);
|
||||
|
||||
if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
|
||||
|
@ -339,6 +339,7 @@ int __sys_openat(int, const char *, int, ...);
|
||||
int __sys_pselect(int, struct fd_set *, struct fd_set *,
|
||||
struct fd_set *, const struct timespec *,
|
||||
const __sigset_t *);
|
||||
int __sys_ptrace(int, __pid_t, char *, int);
|
||||
int __sys_poll(struct pollfd *, unsigned, int);
|
||||
int __sys_ppoll(struct pollfd *, unsigned, const struct timespec *,
|
||||
const __sigset_t *);
|
||||
|
@ -226,6 +226,7 @@ struct ai_order {
|
||||
struct policyqueue *aio_dstpolicy;
|
||||
struct addrinfo *aio_ai;
|
||||
int aio_matchlen;
|
||||
int aio_initial_sequence;
|
||||
};
|
||||
|
||||
static const ns_src default_dns_files[] = {
|
||||
@ -710,6 +711,7 @@ reorder(struct addrinfo *sentinel)
|
||||
aio[i].aio_dstpolicy = match_addrselectpolicy(ai->ai_addr,
|
||||
&policyhead);
|
||||
set_source(&aio[i], &policyhead);
|
||||
aio[i].aio_initial_sequence = i;
|
||||
}
|
||||
|
||||
/* perform sorting. */
|
||||
@ -949,7 +951,7 @@ matchlen(struct sockaddr *src, struct sockaddr *dst)
|
||||
|
||||
while (s < lim)
|
||||
if ((r = (*d++ ^ *s++)) != 0) {
|
||||
while (r < addrlen * 8) {
|
||||
while ((r & 0x80) == 0) {
|
||||
match++;
|
||||
r <<= 1;
|
||||
}
|
||||
@ -1068,6 +1070,23 @@ comp_dst(const void *arg1, const void *arg2)
|
||||
}
|
||||
|
||||
/* Rule 10: Otherwise, leave the order unchanged. */
|
||||
|
||||
/*
|
||||
* Note that qsort is unstable; so, we can't return zero and
|
||||
* expect the order to be unchanged.
|
||||
* That also means we can't depend on the current position of
|
||||
* dst2 being after dst1. We must enforce the initial order
|
||||
* with an explicit compare on the original position.
|
||||
* The qsort specification requires that "When the same objects
|
||||
* (consisting of width bytes, irrespective of their current
|
||||
* positions in the array) are passed more than once to the
|
||||
* comparison function, the results shall be consistent with one
|
||||
* another."
|
||||
* In other words, If A < B, then we must also return B > A.
|
||||
*/
|
||||
if (dst2->aio_initial_sequence < dst1->aio_initial_sequence)
|
||||
return(1);
|
||||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -124,31 +125,46 @@ char *
|
||||
link_ntoa(const struct sockaddr_dl *sdl)
|
||||
{
|
||||
static char obuf[64];
|
||||
char *out = obuf;
|
||||
int i;
|
||||
u_char *in = (u_char *)LLADDR(sdl);
|
||||
u_char *inlim = in + sdl->sdl_alen;
|
||||
int firsttime = 1;
|
||||
_Static_assert(sizeof(obuf) >= IFNAMSIZ + 20, "obuf is too small");
|
||||
char *out;
|
||||
const u_char *in, *inlim;
|
||||
int namelen, i, rem;
|
||||
|
||||
if (sdl->sdl_nlen) {
|
||||
bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
|
||||
out += sdl->sdl_nlen;
|
||||
if (sdl->sdl_alen)
|
||||
namelen = (sdl->sdl_nlen <= IFNAMSIZ) ? sdl->sdl_nlen : IFNAMSIZ;
|
||||
|
||||
out = obuf;
|
||||
rem = sizeof(obuf);
|
||||
if (namelen > 0) {
|
||||
bcopy(sdl->sdl_data, out, namelen);
|
||||
out += namelen;
|
||||
rem -= namelen;
|
||||
if (sdl->sdl_alen > 0) {
|
||||
*out++ = ':';
|
||||
rem--;
|
||||
}
|
||||
}
|
||||
while (in < inlim) {
|
||||
if (firsttime)
|
||||
firsttime = 0;
|
||||
else
|
||||
|
||||
in = (const u_char *)sdl->sdl_data + sdl->sdl_nlen;
|
||||
inlim = in + sdl->sdl_alen;
|
||||
|
||||
while (in < inlim && rem > 1) {
|
||||
if (in != (const u_char *)sdl->sdl_data + sdl->sdl_nlen) {
|
||||
*out++ = '.';
|
||||
rem--;
|
||||
}
|
||||
i = *in++;
|
||||
if (i > 0xf) {
|
||||
out[1] = hexlist[i & 0xf];
|
||||
i >>= 4;
|
||||
out[0] = hexlist[i];
|
||||
out += 2;
|
||||
} else
|
||||
if (rem < 3)
|
||||
break;
|
||||
*out++ = hexlist[i >> 4];
|
||||
*out++ = hexlist[i & 0xf];
|
||||
rem -= 2;
|
||||
} else {
|
||||
if (rem < 2)
|
||||
break;
|
||||
*out++ = hexlist[i];
|
||||
rem--;
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
return (obuf);
|
||||
|
@ -187,6 +187,7 @@ struct hp_order {
|
||||
#define aio_sa aio_un.aiou_sa
|
||||
int aio_matchlen;
|
||||
char *aio_h_addr;
|
||||
int aio_initial_sequence;
|
||||
};
|
||||
|
||||
static struct hostent *_hpcopy(struct hostent *, int *);
|
||||
@ -713,6 +714,7 @@ _hpreorder(struct hostent *hp)
|
||||
aio[i].aio_dstscope = gai_addr2scopetype(sa);
|
||||
aio[i].aio_dstpolicy = match_addrselectpolicy(sa, &policyhead);
|
||||
set_source(&aio[i], &policyhead);
|
||||
aio[i].aio_initial_sequence = i;
|
||||
}
|
||||
|
||||
/* perform sorting. */
|
||||
@ -930,7 +932,7 @@ matchlen(struct sockaddr *src, struct sockaddr *dst)
|
||||
|
||||
while (s < lim)
|
||||
if ((r = (*d++ ^ *s++)) != 0) {
|
||||
while (r < addrlen * 8) {
|
||||
while ((r & 0x80) == 0) {
|
||||
match++;
|
||||
r <<= 1;
|
||||
}
|
||||
@ -1047,6 +1049,23 @@ comp_dst(const void *arg1, const void *arg2)
|
||||
}
|
||||
|
||||
/* Rule 10: Otherwise, leave the order unchanged. */
|
||||
|
||||
/*
|
||||
* Note that qsort is unstable; so, we can't return zero and
|
||||
* expect the order to be unchanged.
|
||||
* That also means we can't depend on the current position of
|
||||
* dst2 being after dst1. We must enforce the initial order
|
||||
* with an explicit compare on the original position.
|
||||
* The qsort specification requires that "When the same objects
|
||||
* (consisting of width bytes, irrespective of their current
|
||||
* positions in the array) are passed more than once to the
|
||||
* comparison function, the results shall be consistent with one
|
||||
* another."
|
||||
* In other words, If A < B, then we must also return B > A.
|
||||
*/
|
||||
if (dst2->aio_initial_sequence < dst1->aio_initial_sequence)
|
||||
return(1);
|
||||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
@ -143,8 +143,11 @@ fgetln(FILE *fp, size_t *lenp)
|
||||
(void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
|
||||
len - off);
|
||||
off = len;
|
||||
if (__srefill(fp))
|
||||
break; /* EOF or error: return partial line */
|
||||
if (__srefill(fp)) {
|
||||
if (__sfeof(fp))
|
||||
break;
|
||||
goto error;
|
||||
}
|
||||
if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL)
|
||||
continue;
|
||||
|
||||
|
@ -1778,6 +1778,7 @@ pfkey_align(msg, mhp)
|
||||
case SADB_EXT_SPIRANGE:
|
||||
case SADB_X_EXT_POLICY:
|
||||
case SADB_X_EXT_SA2:
|
||||
case SADB_X_EXT_SA_REPLAY:
|
||||
mhp[ext->sadb_ext_type] = (caddr_t)ext;
|
||||
break;
|
||||
case SADB_X_EXT_NAT_T_TYPE:
|
||||
|
@ -221,6 +221,7 @@ pfkey_sadump(m)
|
||||
struct sadb_key *m_auth, *m_enc;
|
||||
struct sadb_ident *m_sid, *m_did;
|
||||
struct sadb_sens *m_sens;
|
||||
struct sadb_x_sa_replay *m_sa_replay;
|
||||
|
||||
/* check pfkey message. */
|
||||
if (pfkey_align(m, mhp)) {
|
||||
@ -245,6 +246,7 @@ pfkey_sadump(m)
|
||||
m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC];
|
||||
m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST];
|
||||
m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY];
|
||||
m_sa_replay = (struct sadb_x_sa_replay *)mhp[SADB_X_EXT_SA_REPLAY];
|
||||
|
||||
/* source address */
|
||||
if (m_saddr == NULL) {
|
||||
@ -308,7 +310,8 @@ pfkey_sadump(m)
|
||||
/* replay windoe size & flags */
|
||||
printf("\tseq=0x%08x replay=%u flags=0x%08x ",
|
||||
m_sa2->sadb_x_sa2_sequence,
|
||||
m_sa->sadb_sa_replay,
|
||||
m_sa_replay ? (m_sa_replay->sadb_x_sa_replay_replay >> 3) :
|
||||
m_sa->sadb_sa_replay,
|
||||
m_sa->sadb_sa_flags);
|
||||
|
||||
/* state */
|
||||
|
@ -32,9 +32,6 @@
|
||||
#include <rtems/bsd/sys/cpuset.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_page.h>
|
||||
|
||||
#include <vm/uma.h>
|
||||
#include <vm/uma_int.h>
|
||||
|
||||
|
@ -104,6 +104,8 @@ read_client_conf(void)
|
||||
[top_level_config.requested_option_count++] = DHO_HOST_NAME;
|
||||
top_level_config.requested_options
|
||||
[top_level_config.requested_option_count++] = DHO_DOMAIN_SEARCH;
|
||||
top_level_config.requested_options
|
||||
[top_level_config.requested_option_count++] = DHO_INTERFACE_MTU;
|
||||
|
||||
if ((cfile = fopen(path_dhclient_conf, "r")) != NULL) {
|
||||
do {
|
||||
|
@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "privsep.h"
|
||||
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/endian.h>
|
||||
|
||||
#include <net80211/ieee80211_freebsd.h>
|
||||
|
||||
@ -134,6 +135,9 @@ int fork_privchld(int, int);
|
||||
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
||||
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
|
||||
|
||||
/* Minimum MTU is 68 as per RFC791, p. 24 */
|
||||
#define MIN_MTU 68
|
||||
|
||||
static time_t scripttime;
|
||||
|
||||
int
|
||||
@ -800,9 +804,20 @@ dhcpack(struct packet *packet)
|
||||
void
|
||||
bind_lease(struct interface_info *ip)
|
||||
{
|
||||
struct option_data *opt;
|
||||
|
||||
/* Remember the medium. */
|
||||
ip->client->new->medium = ip->client->medium;
|
||||
|
||||
opt = &ip->client->new->options[DHO_INTERFACE_MTU];
|
||||
if (opt->len == sizeof(u_int16_t)) {
|
||||
u_int16_t mtu = be16dec(opt->data);
|
||||
if (mtu < MIN_MTU)
|
||||
warning("mtu size %u < %d: ignored", (unsigned)mtu, MIN_MTU);
|
||||
else
|
||||
interface_set_mtu_unpriv(privfd, mtu);
|
||||
}
|
||||
|
||||
/* Write out the new lease. */
|
||||
write_client_lease(ip, ip->client->new, 0);
|
||||
|
||||
|
@ -319,6 +319,8 @@ void cancel_timeout(void (*)(void *), void *);
|
||||
void add_protocol(char *, int, void (*)(struct protocol *), void *);
|
||||
void remove_protocol(struct protocol *);
|
||||
int interface_link_status(char *);
|
||||
void interface_set_mtu_unpriv(int, u_int16_t);
|
||||
void interface_set_mtu_priv(char *, u_int16_t);
|
||||
|
||||
/* hash.c */
|
||||
struct hash_table *new_hash(void);
|
||||
|
@ -45,6 +45,7 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "dhcpd.h"
|
||||
#include "privsep.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
@ -107,8 +108,8 @@ discover_interfaces(struct interface_info *iface)
|
||||
if (foo.sin_addr.s_addr == htonl(INADDR_LOOPBACK))
|
||||
continue;
|
||||
if (!iface->ifp) {
|
||||
int len = IFNAMSIZ + ifa->ifa_addr->sa_len;
|
||||
if ((tif = malloc(len)) == NULL)
|
||||
if ((tif = calloc(1, sizeof(struct ifreq)))
|
||||
== NULL)
|
||||
error("no space to remember ifp");
|
||||
strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);
|
||||
memcpy(&tif->ifr_addr, ifa->ifa_addr,
|
||||
@ -503,3 +504,46 @@ interface_link_status(char *ifname)
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
interface_set_mtu_unpriv(int privfd, u_int16_t mtu)
|
||||
{
|
||||
struct imsg_hdr hdr;
|
||||
struct buf *buf;
|
||||
int errs = 0;
|
||||
|
||||
hdr.code = IMSG_SET_INTERFACE_MTU;
|
||||
hdr.len = sizeof(hdr) +
|
||||
sizeof(u_int16_t);
|
||||
|
||||
if ((buf = buf_open(hdr.len)) == NULL)
|
||||
error("buf_open: %m");
|
||||
|
||||
errs += buf_add(buf, &hdr, sizeof(hdr));
|
||||
errs += buf_add(buf, &mtu, sizeof(mtu));
|
||||
if (errs)
|
||||
error("buf_add: %m");
|
||||
|
||||
if (buf_close(privfd, buf) == -1)
|
||||
error("buf_close: %m");
|
||||
}
|
||||
|
||||
void
|
||||
interface_set_mtu_priv(char *ifname, u_int16_t mtu)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int sock;
|
||||
|
||||
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
|
||||
error("Can't create socket");
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
|
||||
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
||||
ifr.ifr_mtu = mtu;
|
||||
|
||||
if (ioctl(sock, SIOCSIFMTU, &ifr) == -1)
|
||||
warning("SIOCSIFMTU failed (%d): %s", mtu,
|
||||
strerror(errno));
|
||||
close(sock);
|
||||
}
|
||||
|
@ -113,6 +113,7 @@ dispatch_imsg(struct interface_info *ifi, int fd)
|
||||
struct client_lease lease;
|
||||
int ret, i, optlen;
|
||||
struct buf *buf;
|
||||
u_int16_t mtu;
|
||||
|
||||
buf_read(fd, &hdr, sizeof(hdr));
|
||||
|
||||
@ -237,6 +238,13 @@ dispatch_imsg(struct interface_info *ifi, int fd)
|
||||
case IMSG_SEND_PACKET:
|
||||
send_packet_priv(ifi, &hdr, fd);
|
||||
break;
|
||||
case IMSG_SET_INTERFACE_MTU:
|
||||
if (hdr.len < sizeof(hdr) + sizeof(u_int16_t))
|
||||
error("corrupted message received");
|
||||
|
||||
buf_read(fd, &mtu, sizeof(u_int16_t));
|
||||
interface_set_mtu_priv(ifi->name, mtu);
|
||||
break;
|
||||
default:
|
||||
error("received unknown message, code %d", hdr.code);
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ enum imsg_code {
|
||||
IMSG_SCRIPT_WRITE_PARAMS,
|
||||
IMSG_SCRIPT_GO,
|
||||
IMSG_SCRIPT_GO_RET,
|
||||
IMSG_SEND_PACKET
|
||||
IMSG_SEND_PACKET,
|
||||
IMSG_SET_INTERFACE_MTU,
|
||||
};
|
||||
|
||||
struct imsg_hdr {
|
||||
|
@ -402,6 +402,7 @@ unsigned char dhcp_option_default_priority_list[] = {
|
||||
DHO_IRC_SERVER,
|
||||
DHO_STREETTALK_SERVER,
|
||||
DHO_STREETTALK_DA_SERVER,
|
||||
DHO_DHCP_USER_CLASS_ID,
|
||||
DHO_DOMAIN_SEARCH,
|
||||
|
||||
/* Presently-undefined options... */
|
||||
|
@ -100,7 +100,7 @@ in_status(int s __unused, const struct ifaddrs *ifa)
|
||||
sin = (struct sockaddr_in *)ifa->ifa_dstaddr;
|
||||
if (sin == NULL)
|
||||
sin = &null_sin;
|
||||
printf(" --> %s ", inet_ntoa(sin->sin_addr));
|
||||
printf(" --> %s", inet_ntoa(sin->sin_addr));
|
||||
}
|
||||
|
||||
sin = (struct sockaddr_in *)ifa->ifa_netmask;
|
||||
|
@ -250,7 +250,7 @@ in6_status(int s __unused, const struct ifaddrs *ifa)
|
||||
if (error != 0)
|
||||
inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf,
|
||||
sizeof(addr_buf));
|
||||
printf(" --> %s ", addr_buf);
|
||||
printf(" --> %s", addr_buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,13 +102,24 @@ link_getaddr(const char *addr, int which)
|
||||
|
||||
if (which != ADDR)
|
||||
errx(1, "can't set link-level netmask or broadcast");
|
||||
if ((temp = malloc(strlen(addr) + 2)) == NULL)
|
||||
errx(1, "malloc failed");
|
||||
temp[0] = ':';
|
||||
strcpy(temp + 1, addr);
|
||||
sdl.sdl_len = sizeof(sdl);
|
||||
link_addr(temp, &sdl);
|
||||
free(temp);
|
||||
if (!strcmp(addr, "random")) {
|
||||
sdl.sdl_len = sizeof(sdl);
|
||||
sdl.sdl_alen = ETHER_ADDR_LEN;
|
||||
sdl.sdl_nlen = 0;
|
||||
sdl.sdl_family = AF_LINK;
|
||||
arc4random_buf(&sdl.sdl_data, ETHER_ADDR_LEN);
|
||||
/* Non-multicast and claim it is locally administered. */
|
||||
sdl.sdl_data[0] &= 0xfc;
|
||||
sdl.sdl_data[0] |= 0x02;
|
||||
} else {
|
||||
if ((temp = malloc(strlen(addr) + 2)) == NULL)
|
||||
errx(1, "malloc failed");
|
||||
temp[0] = ':';
|
||||
strcpy(temp + 1, addr);
|
||||
sdl.sdl_len = sizeof(sdl);
|
||||
link_addr(temp, &sdl);
|
||||
free(temp);
|
||||
}
|
||||
if (sdl.sdl_alen > sizeof(sa->sa_data))
|
||||
errx(1, "malformed link-level address");
|
||||
sa->sa_family = AF_LINK;
|
||||
|
@ -367,6 +367,8 @@ void decide_address_family(struct node_host *, sa_family_t *);
|
||||
void remove_invalid_hosts(struct node_host **, sa_family_t *);
|
||||
int invalid_redirect(struct node_host *, sa_family_t);
|
||||
u_int16_t parseicmpspec(char *, sa_family_t);
|
||||
int kw_casecmp(const void *, const void *);
|
||||
int map_tos(char *string, int *);
|
||||
|
||||
static TAILQ_HEAD(loadanchorshead, loadanchors)
|
||||
loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead);
|
||||
@ -2346,7 +2348,7 @@ pfrule : action dir logquick interface route af proto fromto
|
||||
memcpy(&r.rpool.key, $5.key,
|
||||
sizeof(struct pf_poolhashkey));
|
||||
}
|
||||
if (r.rt && r.rt != PF_FASTROUTE) {
|
||||
if (r.rt) {
|
||||
decide_address_family($5.host, &r.af);
|
||||
remove_invalid_hosts(&$5.host, &r.af);
|
||||
if ($5.host == NULL) {
|
||||
@ -3600,15 +3602,17 @@ icmp6type : STRING {
|
||||
;
|
||||
|
||||
tos : STRING {
|
||||
if (!strcmp($1, "lowdelay"))
|
||||
$$ = IPTOS_LOWDELAY;
|
||||
else if (!strcmp($1, "throughput"))
|
||||
$$ = IPTOS_THROUGHPUT;
|
||||
else if (!strcmp($1, "reliability"))
|
||||
$$ = IPTOS_RELIABILITY;
|
||||
else if ($1[0] == '0' && $1[1] == 'x')
|
||||
$$ = strtoul($1, NULL, 16);
|
||||
else
|
||||
int val;
|
||||
char *end;
|
||||
|
||||
if (map_tos($1, &val))
|
||||
$$ = val;
|
||||
else if ($1[0] == '0' && $1[1] == 'x') {
|
||||
errno = 0;
|
||||
$$ = strtoul($1, &end, 16);
|
||||
if (errno || *end != '\0')
|
||||
$$ = 256;
|
||||
} else
|
||||
$$ = 256; /* flag bad argument */
|
||||
if ($$ < 0 || $$ > 255) {
|
||||
yyerror("illegal tos value %s", $1);
|
||||
@ -4432,8 +4436,9 @@ route : /* empty */ {
|
||||
$$.pool_opts = 0;
|
||||
}
|
||||
| FASTROUTE {
|
||||
/* backwards-compat */
|
||||
$$.host = NULL;
|
||||
$$.rt = PF_FASTROUTE;
|
||||
$$.rt = 0;
|
||||
$$.pool_opts = 0;
|
||||
}
|
||||
| ROUTETO routespec pool_opts {
|
||||
@ -6269,6 +6274,57 @@ pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
kw_casecmp(const void *k, const void *e)
|
||||
{
|
||||
return (strcasecmp(k, ((const struct keywords *)e)->k_name));
|
||||
}
|
||||
|
||||
int
|
||||
map_tos(char *s, int *val)
|
||||
{
|
||||
/* DiffServ Codepoints and other TOS mappings */
|
||||
const struct keywords toswords[] = {
|
||||
{ "af11", IPTOS_DSCP_AF11 },
|
||||
{ "af12", IPTOS_DSCP_AF12 },
|
||||
{ "af13", IPTOS_DSCP_AF13 },
|
||||
{ "af21", IPTOS_DSCP_AF21 },
|
||||
{ "af22", IPTOS_DSCP_AF22 },
|
||||
{ "af23", IPTOS_DSCP_AF23 },
|
||||
{ "af31", IPTOS_DSCP_AF31 },
|
||||
{ "af32", IPTOS_DSCP_AF32 },
|
||||
{ "af33", IPTOS_DSCP_AF33 },
|
||||
{ "af41", IPTOS_DSCP_AF41 },
|
||||
{ "af42", IPTOS_DSCP_AF42 },
|
||||
{ "af43", IPTOS_DSCP_AF43 },
|
||||
{ "critical", IPTOS_PREC_CRITIC_ECP },
|
||||
{ "cs0", IPTOS_DSCP_CS0 },
|
||||
{ "cs1", IPTOS_DSCP_CS1 },
|
||||
{ "cs2", IPTOS_DSCP_CS2 },
|
||||
{ "cs3", IPTOS_DSCP_CS3 },
|
||||
{ "cs4", IPTOS_DSCP_CS4 },
|
||||
{ "cs5", IPTOS_DSCP_CS5 },
|
||||
{ "cs6", IPTOS_DSCP_CS6 },
|
||||
{ "cs7", IPTOS_DSCP_CS7 },
|
||||
{ "ef", IPTOS_DSCP_EF },
|
||||
{ "inetcontrol", IPTOS_PREC_INTERNETCONTROL },
|
||||
{ "lowdelay", IPTOS_LOWDELAY },
|
||||
{ "netcontrol", IPTOS_PREC_NETCONTROL },
|
||||
{ "reliability", IPTOS_RELIABILITY },
|
||||
{ "throughput", IPTOS_THROUGHPUT }
|
||||
};
|
||||
const struct keywords *p;
|
||||
|
||||
p = bsearch(s, toswords, sizeof(toswords)/sizeof(toswords[0]),
|
||||
sizeof(toswords[0]), kw_casecmp);
|
||||
|
||||
if (p) {
|
||||
*val = p->k_val;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rt_tableid_max(void)
|
||||
{
|
||||
|
@ -1364,7 +1364,7 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pf_rule *r, int depth)
|
||||
else
|
||||
snprintf(&path[len], MAXPATHLEN - len,
|
||||
"%s", r->anchor->name);
|
||||
name = path;
|
||||
name = r->anchor->name;
|
||||
} else
|
||||
name = r->anchor->path;
|
||||
} else
|
||||
|
@ -103,7 +103,7 @@ TAILQ_HEAD(superblocks, superblock);
|
||||
* Description of the PF rule structure.
|
||||
*/
|
||||
enum {
|
||||
BARRIER, /* the presence of the field puts the rule in it's own block */
|
||||
BARRIER, /* the presence of the field puts the rule in its own block */
|
||||
BREAK, /* the field may not differ between rules in a superblock */
|
||||
NOMERGE, /* the field may not differ between rules when combined */
|
||||
COMBINED, /* the field may itself be combined with other rules */
|
||||
@ -127,7 +127,7 @@ static struct pf_rule_field pf_rule_desc[] = {
|
||||
|
||||
|
||||
/*
|
||||
* The presence of these fields in a rule put the rule in it's own
|
||||
* The presence of these fields in a rule put the rule in its own
|
||||
* superblock. Thus it will not be optimized. It also prevents the
|
||||
* rule from being re-ordered at all.
|
||||
*/
|
||||
|
@ -790,12 +790,8 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose, int numeric)
|
||||
printf(" reply-to");
|
||||
else if (r->rt == PF_DUPTO)
|
||||
printf(" dup-to");
|
||||
else if (r->rt == PF_FASTROUTE)
|
||||
printf(" fastroute");
|
||||
if (r->rt != PF_FASTROUTE) {
|
||||
printf(" ");
|
||||
print_pool(&r->rpool, 0, 0, r->af, PF_PASS);
|
||||
}
|
||||
printf(" ");
|
||||
print_pool(&r->rpool, 0, 0, r->af, PF_PASS);
|
||||
}
|
||||
if (r->af) {
|
||||
if (r->af == AF_INET)
|
||||
|
@ -677,9 +677,6 @@ S_vmtotal(size_t l2, void *p)
|
||||
}
|
||||
|
||||
#ifdef __amd64__
|
||||
#define efi_next_descriptor(ptr, size) \
|
||||
((struct efi_md *)(((uint8_t *) ptr) + size))
|
||||
|
||||
static int
|
||||
S_efi_map(size_t l2, void *p)
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ breakpoint(void)
|
||||
struct cpu_functions {
|
||||
|
||||
/* CPU functions */
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
void (*cf_cpwait) (void);
|
||||
|
||||
/* MMU functions */
|
||||
@ -140,6 +140,7 @@ struct cpu_functions {
|
||||
void (*cf_idcache_inv_all) (void);
|
||||
void (*cf_idcache_wbinv_all) (void);
|
||||
void (*cf_idcache_wbinv_range) (vm_offset_t, vm_size_t);
|
||||
#endif
|
||||
void (*cf_l2cache_wbinv_all) (void);
|
||||
void (*cf_l2cache_wbinv_range) (vm_offset_t, vm_size_t);
|
||||
void (*cf_l2cache_inv_range) (vm_offset_t, vm_size_t);
|
||||
@ -148,13 +149,17 @@ struct cpu_functions {
|
||||
|
||||
/* Other functions */
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
void (*cf_drain_writebuf) (void);
|
||||
#endif
|
||||
|
||||
void (*cf_sleep) (int mode);
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
/* Soft functions */
|
||||
|
||||
void (*cf_context_switch) (void);
|
||||
#endif
|
||||
|
||||
void (*cf_setup) (void);
|
||||
};
|
||||
@ -164,10 +169,8 @@ extern u_int cputype;
|
||||
|
||||
#if __ARM_ARCH < 6
|
||||
#define cpu_cpwait() cpufuncs.cf_cpwait()
|
||||
#endif
|
||||
|
||||
#define cpu_control(c, e) cpufuncs.cf_control(c, e)
|
||||
#if __ARM_ARCH < 6
|
||||
#define cpu_setttb(t) cpufuncs.cf_setttb(t)
|
||||
|
||||
#define cpu_tlb_flushID() cpufuncs.cf_tlb_flushID()
|
||||
@ -186,6 +189,7 @@ extern u_int cputype;
|
||||
#define cpu_idcache_wbinv_all() cpufuncs.cf_idcache_wbinv_all()
|
||||
#define cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s))
|
||||
#endif
|
||||
|
||||
#define cpu_l2cache_wbinv_all() cpufuncs.cf_l2cache_wbinv_all()
|
||||
#define cpu_l2cache_wb_range(a, s) cpufuncs.cf_l2cache_wb_range((a), (s))
|
||||
#define cpu_l2cache_inv_range(a, s) cpufuncs.cf_l2cache_inv_range((a), (s))
|
||||
@ -274,26 +278,12 @@ void sheeva_l2cache_wbinv_all (void);
|
||||
#if defined(CPU_MV_PJ4B)
|
||||
void armv6_idcache_wbinv_all (void);
|
||||
#endif
|
||||
#if defined(CPU_MV_PJ4B) || defined(CPU_CORTEXA) || defined(CPU_KRAIT)
|
||||
void armv7_setttb (u_int);
|
||||
void armv7_tlb_flushID (void);
|
||||
void armv7_tlb_flushID_SE (u_int);
|
||||
void armv7_icache_sync_range (vm_offset_t, vm_size_t);
|
||||
void armv7_idcache_wbinv_range (vm_offset_t, vm_size_t);
|
||||
void armv7_idcache_inv_all (void);
|
||||
void armv7_dcache_wbinv_all (void);
|
||||
#if defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || \
|
||||
defined(CPU_MV_PJ4B) || defined(CPU_KRAIT)
|
||||
void armv7_idcache_wbinv_all (void);
|
||||
void armv7_dcache_wbinv_range (vm_offset_t, vm_size_t);
|
||||
void armv7_dcache_inv_range (vm_offset_t, vm_size_t);
|
||||
void armv7_dcache_wb_range (vm_offset_t, vm_size_t);
|
||||
void armv7_cpu_sleep (int);
|
||||
void armv7_setup (void);
|
||||
void armv7_context_switch (void);
|
||||
void armv7_drain_writebuf (void);
|
||||
void armv7_sev (void);
|
||||
u_int armv7_auxctrl (u_int, u_int);
|
||||
|
||||
void armadaxp_idcache_wbinv_all (void);
|
||||
|
||||
void cortexa_setup (void);
|
||||
#endif
|
||||
@ -303,26 +293,8 @@ void pj4bv7_setup (void);
|
||||
#endif
|
||||
|
||||
#if defined(CPU_ARM1176)
|
||||
void arm11_tlb_flushID (void);
|
||||
void arm11_tlb_flushID_SE (u_int);
|
||||
void arm11_tlb_flushD (void);
|
||||
void arm11_tlb_flushD_SE (u_int va);
|
||||
|
||||
void arm11_context_switch (void);
|
||||
|
||||
void arm11_drain_writebuf (void);
|
||||
|
||||
void armv6_dcache_wbinv_range (vm_offset_t, vm_size_t);
|
||||
void armv6_dcache_inv_range (vm_offset_t, vm_size_t);
|
||||
void armv6_dcache_wb_range (vm_offset_t, vm_size_t);
|
||||
|
||||
void armv6_idcache_inv_all (void);
|
||||
|
||||
void arm11x6_setttb (u_int);
|
||||
void arm11x6_idcache_wbinv_all (void);
|
||||
void arm11x6_dcache_wbinv_all (void);
|
||||
void arm11x6_icache_sync_range (vm_offset_t, vm_size_t);
|
||||
void arm11x6_idcache_wbinv_range (vm_offset_t, vm_size_t);
|
||||
void arm11x6_setup (void);
|
||||
void arm11x6_sleep (int); /* no ref. for errata */
|
||||
#endif
|
||||
|
@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#ifndef __rtems__
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
#endif /* __rtems__ */
|
||||
@ -639,8 +638,8 @@ zy7_slcr_attach(device_t dev)
|
||||
/* Derive PLL frequencies from PS_CLK. */
|
||||
#ifndef __rtems__
|
||||
node = ofw_bus_get_node(dev);
|
||||
if (OF_getprop(node, "clock-frequency", &cell, sizeof(cell)) > 0)
|
||||
ps_clk_frequency = fdt32_to_cpu(cell);
|
||||
if (OF_getencprop(node, "clock-frequency", &cell, sizeof(cell)) > 0)
|
||||
ps_clk_frequency = cell;
|
||||
else
|
||||
#endif /* __rtems__ */
|
||||
ps_clk_frequency = ZYNQ_DEFAULT_PS_CLK_FREQUENCY;
|
||||
|
@ -294,7 +294,7 @@ typedef enum {
|
||||
/* SIM ready to take more commands */
|
||||
CAM_RELEASE_SIMQ = 0x100,
|
||||
|
||||
/* SIM has this command in it's queue */
|
||||
/* SIM has this command in its queue */
|
||||
CAM_SIM_QUEUED = 0x200,
|
||||
|
||||
/* Quality of service data is valid */
|
||||
|
@ -757,6 +757,9 @@ struct ccb_scsiio {
|
||||
#define CAM_TAG_ACTION_NONE 0x00
|
||||
u_int tag_id; /* tag id from initator (target mode) */
|
||||
u_int init_id; /* initiator id of who selected */
|
||||
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||
struct bio *bio; /* Associated bio */
|
||||
#endif
|
||||
#ifdef __rtems__
|
||||
int readop;
|
||||
rtems_blkdev_sg_buffer *sg_current;
|
||||
@ -1358,6 +1361,9 @@ cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
|
||||
csio->sense_len = sense_len;
|
||||
csio->cdb_len = cdb_len;
|
||||
csio->tag_action = tag_action;
|
||||
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
|
||||
csio->bio = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline void
|
||||
|
@ -166,7 +166,6 @@ void cam_periph_unmapmem(union ccb *ccb,
|
||||
struct cam_periph_map_info *mapinfo);
|
||||
union ccb *cam_periph_getccb(struct cam_periph *periph,
|
||||
u_int32_t priority);
|
||||
void cam_periph_ccbwait(union ccb *ccb);
|
||||
int cam_periph_runccb(union ccb *ccb,
|
||||
int (*error_routine)(union ccb *ccb,
|
||||
cam_flags camflags,
|
||||
|
@ -1063,7 +1063,7 @@ static struct asc_table_entry asc_table[] = {
|
||||
{ SST(0x00, 0x1C, SS_RDEF, /* XXX TBD */
|
||||
"Verify operation in progress") },
|
||||
/* DT B */
|
||||
{ SST(0x00, 0x1D, SS_RDEF, /* XXX TBD */
|
||||
{ SST(0x00, 0x1D, SS_NOP,
|
||||
"ATA pass through information available") },
|
||||
/* DT R MAEBKV */
|
||||
{ SST(0x00, 0x1E, SS_RDEF, /* XXX TBD */
|
||||
@ -1072,7 +1072,7 @@ static struct asc_table_entry asc_table[] = {
|
||||
{ SST(0x00, 0x1F, SS_RDEF, /* XXX TBD */
|
||||
"Logical unit transitioning to another power condition") },
|
||||
/* DT P B */
|
||||
{ SST(0x00, 0x20, SS_RDEF, /* XXX TBD */
|
||||
{ SST(0x00, 0x20, SS_NOP,
|
||||
"Extended copy information available") },
|
||||
/* D */
|
||||
{ SST(0x00, 0x21, SS_RDEF, /* XXX TBD */
|
||||
@ -2338,7 +2338,7 @@ static struct asc_table_entry asc_table[] = {
|
||||
{ SST(0x43, 0x00, SS_RDEF,
|
||||
"Message error") },
|
||||
/* DTLPWROMAEBKVF */
|
||||
{ SST(0x44, 0x00, SS_RDEF,
|
||||
{ SST(0x44, 0x00, SS_FATAL | EIO,
|
||||
"Internal target failure") },
|
||||
/* DT P MAEBKVF */
|
||||
{ SST(0x44, 0x01, SS_RDEF, /* XXX TBD */
|
||||
@ -3199,10 +3199,10 @@ static struct asc_table_entry asc_table[] = {
|
||||
{ SST(0x74, 0x6F, SS_RDEF, /* XXX TBD */
|
||||
"External data encryption control error") },
|
||||
/* DT R M E V */
|
||||
{ SST(0x74, 0x71, SS_RDEF, /* XXX TBD */
|
||||
{ SST(0x74, 0x71, SS_FATAL | EACCES,
|
||||
"Logical unit access not authorized") },
|
||||
/* D */
|
||||
{ SST(0x74, 0x79, SS_RDEF, /* XXX TBD */
|
||||
{ SST(0x74, 0x79, SS_FATAL | EACCES,
|
||||
"Security conflict in translated device") }
|
||||
};
|
||||
|
||||
@ -4661,6 +4661,53 @@ scsi_sense_progress_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
|
||||
scsi_progress_sbuf(sb, progress_val);
|
||||
}
|
||||
|
||||
void
|
||||
scsi_sense_ata_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
|
||||
u_int sense_len, uint8_t *cdb, int cdb_len,
|
||||
struct scsi_inquiry_data *inq_data,
|
||||
struct scsi_sense_desc_header *header)
|
||||
{
|
||||
struct scsi_sense_ata_ret_desc *res;
|
||||
|
||||
res = (struct scsi_sense_ata_ret_desc *)header;
|
||||
|
||||
sbuf_printf(sb, "ATA status: %02x (%s%s%s%s%s%s%s%s), ",
|
||||
res->status,
|
||||
(res->status & 0x80) ? "BSY " : "",
|
||||
(res->status & 0x40) ? "DRDY " : "",
|
||||
(res->status & 0x20) ? "DF " : "",
|
||||
(res->status & 0x10) ? "SERV " : "",
|
||||
(res->status & 0x08) ? "DRQ " : "",
|
||||
(res->status & 0x04) ? "CORR " : "",
|
||||
(res->status & 0x02) ? "IDX " : "",
|
||||
(res->status & 0x01) ? "ERR" : "");
|
||||
if (res->status & 1) {
|
||||
sbuf_printf(sb, "error: %02x (%s%s%s%s%s%s%s%s), ",
|
||||
res->error,
|
||||
(res->error & 0x80) ? "ICRC " : "",
|
||||
(res->error & 0x40) ? "UNC " : "",
|
||||
(res->error & 0x20) ? "MC " : "",
|
||||
(res->error & 0x10) ? "IDNF " : "",
|
||||
(res->error & 0x08) ? "MCR " : "",
|
||||
(res->error & 0x04) ? "ABRT " : "",
|
||||
(res->error & 0x02) ? "NM " : "",
|
||||
(res->error & 0x01) ? "ILI" : "");
|
||||
}
|
||||
|
||||
if (res->flags & SSD_DESC_ATA_FLAG_EXTEND) {
|
||||
sbuf_printf(sb, "count: %02x%02x, ",
|
||||
res->count_15_8, res->count_7_0);
|
||||
sbuf_printf(sb, "LBA: %02x%02x%02x%02x%02x%02x, ",
|
||||
res->lba_47_40, res->lba_39_32, res->lba_31_24,
|
||||
res->lba_23_16, res->lba_15_8, res->lba_7_0);
|
||||
} else {
|
||||
sbuf_printf(sb, "count: %02x, ", res->count_7_0);
|
||||
sbuf_printf(sb, "LBA: %02x%02x%02x, ",
|
||||
res->lba_23_16, res->lba_15_8, res->lba_7_0);
|
||||
}
|
||||
sbuf_printf(sb, "device: %02x, ", res->device);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic sense descriptor printing routine. This is used when we have
|
||||
* not yet implemented a specific printing routine for this descriptor.
|
||||
@ -4707,6 +4754,7 @@ struct scsi_sense_desc_printer {
|
||||
{SSD_DESC_FRU, scsi_sense_fru_sbuf},
|
||||
{SSD_DESC_STREAM, scsi_sense_stream_sbuf},
|
||||
{SSD_DESC_BLOCK, scsi_sense_block_sbuf},
|
||||
{SSD_DESC_ATA, scsi_sense_ata_sbuf},
|
||||
{SSD_DESC_PROGRESS, scsi_sense_progress_sbuf}
|
||||
};
|
||||
|
||||
@ -7913,6 +7961,32 @@ scsi_report_target_group(struct ccb_scsiio *csio, u_int32_t retries,
|
||||
scsi_ulto4b(alloc_len, scsi_cmd->length);
|
||||
}
|
||||
|
||||
void
|
||||
scsi_report_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
|
||||
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
||||
u_int8_t tag_action, u_int8_t pdf,
|
||||
void *buf, u_int32_t alloc_len,
|
||||
u_int8_t sense_len, u_int32_t timeout)
|
||||
{
|
||||
struct scsi_timestamp *scsi_cmd;
|
||||
|
||||
cam_fill_csio(csio,
|
||||
retries,
|
||||
cbfcnp,
|
||||
/*flags*/CAM_DIR_IN,
|
||||
tag_action,
|
||||
/*data_ptr*/(u_int8_t *)buf,
|
||||
/*dxfer_len*/alloc_len,
|
||||
sense_len,
|
||||
sizeof(*scsi_cmd),
|
||||
timeout);
|
||||
scsi_cmd = (struct scsi_timestamp *)&csio->cdb_io.cdb_bytes;
|
||||
bzero(scsi_cmd, sizeof(*scsi_cmd));
|
||||
scsi_cmd->opcode = MAINTENANCE_IN;
|
||||
scsi_cmd->service_action = REPORT_TIMESTAMP | pdf;
|
||||
scsi_ulto4b(alloc_len, scsi_cmd->length);
|
||||
}
|
||||
|
||||
void
|
||||
scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
|
||||
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
||||
@ -7938,6 +8012,45 @@ scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
|
||||
scsi_ulto4b(alloc_len, scsi_cmd->length);
|
||||
}
|
||||
|
||||
void
|
||||
scsi_create_timestamp(uint8_t *timestamp_6b_buf,
|
||||
uint64_t timestamp)
|
||||
{
|
||||
uint8_t buf[8];
|
||||
scsi_u64to8b(timestamp, buf);
|
||||
/*
|
||||
* Using memcopy starting at buf[2] because the set timestamp parameters
|
||||
* only has six bytes for the timestamp to fit into, and we don't have a
|
||||
* scsi_u64to6b function.
|
||||
*/
|
||||
memcpy(timestamp_6b_buf, &buf[2], 6);
|
||||
}
|
||||
|
||||
void
|
||||
scsi_set_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
|
||||
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
||||
u_int8_t tag_action, void *buf, u_int32_t alloc_len,
|
||||
u_int8_t sense_len, u_int32_t timeout)
|
||||
{
|
||||
struct scsi_timestamp *scsi_cmd;
|
||||
|
||||
cam_fill_csio(csio,
|
||||
retries,
|
||||
cbfcnp,
|
||||
/*flags*/CAM_DIR_OUT,
|
||||
tag_action,
|
||||
/*data_ptr*/(u_int8_t *) buf,
|
||||
/*dxfer_len*/alloc_len,
|
||||
sense_len,
|
||||
sizeof(*scsi_cmd),
|
||||
timeout);
|
||||
scsi_cmd = (struct scsi_timestamp *)&csio->cdb_io.cdb_bytes;
|
||||
bzero(scsi_cmd, sizeof(*scsi_cmd));
|
||||
scsi_cmd->opcode = MAINTENANCE_OUT;
|
||||
scsi_cmd->service_action = SET_TIMESTAMP;
|
||||
scsi_ulto4b(alloc_len, scsi_cmd->length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Syncronize the media to the contents of the cache for
|
||||
* the given lba/count pair. Specifying 0/0 means sync
|
||||
|
@ -702,7 +702,9 @@ struct scsi_control_page {
|
||||
|
||||
struct scsi_control_ext_page {
|
||||
uint8_t page_code;
|
||||
#define SCEP_PAGE_CODE 0x0a
|
||||
uint8_t subpage_code;
|
||||
#define SCEP_SUBPAGE_CODE 0x01
|
||||
uint8_t page_length[2];
|
||||
uint8_t flags;
|
||||
#define SCEP_TCMOS 0x04 /* Timestamp Changeable by */
|
||||
@ -2971,6 +2973,31 @@ struct scsi_target_group
|
||||
uint8_t control;
|
||||
};
|
||||
|
||||
struct scsi_timestamp
|
||||
{
|
||||
uint8_t opcode;
|
||||
uint8_t service_action;
|
||||
uint8_t reserved1[4];
|
||||
uint8_t length[4];
|
||||
uint8_t reserved2;
|
||||
uint8_t control;
|
||||
};
|
||||
|
||||
struct scsi_set_timestamp_parameters
|
||||
{
|
||||
uint8_t reserved1[4];
|
||||
uint8_t timestamp[6];
|
||||
uint8_t reserved2[4];
|
||||
};
|
||||
|
||||
struct scsi_report_timestamp_parameter_data
|
||||
{
|
||||
uint8_t length[2];
|
||||
uint8_t reserved1[2];
|
||||
uint8_t timestamp[6];
|
||||
uint8_t reserved2[2];
|
||||
};
|
||||
|
||||
struct scsi_target_port_descriptor {
|
||||
uint8_t reserved[2];
|
||||
uint8_t relative_target_port_identifier[2];
|
||||
@ -3682,6 +3709,10 @@ void scsi_sense_progress_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
|
||||
u_int sense_len, uint8_t *cdb, int cdb_len,
|
||||
struct scsi_inquiry_data *inq_data,
|
||||
struct scsi_sense_desc_header *header);
|
||||
void scsi_sense_ata_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
|
||||
u_int sense_len, uint8_t *cdb, int cdb_len,
|
||||
struct scsi_inquiry_data *inq_data,
|
||||
struct scsi_sense_desc_header *header);
|
||||
void scsi_sense_generic_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
|
||||
u_int sense_len, uint8_t *cdb, int cdb_len,
|
||||
struct scsi_inquiry_data *inq_data,
|
||||
@ -3962,12 +3993,29 @@ void scsi_report_target_group(struct ccb_scsiio *csio, u_int32_t retries,
|
||||
u_int32_t alloc_len, u_int8_t sense_len,
|
||||
u_int32_t timeout);
|
||||
|
||||
void scsi_report_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
|
||||
void (*cbfcnp)(struct cam_periph *,
|
||||
union ccb *), u_int8_t tag_action,
|
||||
u_int8_t pdf,
|
||||
void *buf,
|
||||
u_int32_t alloc_len, u_int8_t sense_len,
|
||||
u_int32_t timeout);
|
||||
|
||||
void scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
|
||||
void (*cbfcnp)(struct cam_periph *,
|
||||
union ccb *), u_int8_t tag_action, void *buf,
|
||||
u_int32_t alloc_len, u_int8_t sense_len,
|
||||
u_int32_t timeout);
|
||||
|
||||
void scsi_create_timestamp(uint8_t *timestamp_6b_buf,
|
||||
uint64_t timestamp);
|
||||
|
||||
void scsi_set_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
|
||||
void (*cbfcnp)(struct cam_periph *,
|
||||
union ccb *), u_int8_t tag_action,
|
||||
void *buf, u_int32_t alloc_len,
|
||||
u_int8_t sense_len, u_int32_t timeout);
|
||||
|
||||
void scsi_synchronize_cache(struct ccb_scsiio *csio,
|
||||
u_int32_t retries,
|
||||
void (*cbfcnp)(struct cam_periph *,
|
||||
|
@ -61,7 +61,7 @@ typedef struct sha1_ctxt SHA1_CTX;
|
||||
extern void sha1_init(struct sha1_ctxt *);
|
||||
extern void sha1_pad(struct sha1_ctxt *);
|
||||
extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
|
||||
extern void sha1_result(struct sha1_ctxt *, char[static SHA1_RESULTLEN]);
|
||||
extern void sha1_result(struct sha1_ctxt *, char[__min_size(SHA1_RESULTLEN)]);
|
||||
|
||||
/* compatibilty with other SHA1 source codes */
|
||||
#define SHA1Init(x) sha1_init((x))
|
||||
|
@ -59,6 +59,12 @@ __BEGIN_DECLS
|
||||
#ifndef SHA256_End
|
||||
#define SHA256_End _libmd_SHA256_End
|
||||
#endif
|
||||
#ifndef SHA256_Fd
|
||||
#define SHA256_Fd _libmd_SHA256_Fd
|
||||
#endif
|
||||
#ifndef SHA256_FdChunk
|
||||
#define SHA256_FdChunk _libmd_SHA256_FdChunk
|
||||
#endif
|
||||
#ifndef SHA256_File
|
||||
#define SHA256_File _libmd_SHA256_File
|
||||
#endif
|
||||
@ -78,10 +84,13 @@ __BEGIN_DECLS
|
||||
|
||||
void SHA256_Init(SHA256_CTX *);
|
||||
void SHA256_Update(SHA256_CTX *, const void *, size_t);
|
||||
void SHA256_Final(unsigned char [static SHA256_DIGEST_LENGTH], SHA256_CTX *);
|
||||
void SHA256_Final(unsigned char [__min_size(SHA256_DIGEST_LENGTH)],
|
||||
SHA256_CTX *);
|
||||
#ifndef _KERNEL
|
||||
char *SHA256_End(SHA256_CTX *, char *);
|
||||
char *SHA256_Data(const void *, unsigned int, char *);
|
||||
char *SHA256_Fd(int, char *);
|
||||
char *SHA256_FdChunk(int, char *, off_t, off_t);
|
||||
char *SHA256_File(const char *, char *);
|
||||
char *SHA256_FileChunk(const char *, char *, off_t, off_t);
|
||||
#endif
|
||||
|
@ -58,6 +58,12 @@ __BEGIN_DECLS
|
||||
#ifndef SHA384_End
|
||||
#define SHA384_End _libmd_SHA384_End
|
||||
#endif
|
||||
#ifndef SHA384_Fd
|
||||
#define SHA384_Fd _libmd_SHA384_Fd
|
||||
#endif
|
||||
#ifndef SHA384_FdChunk
|
||||
#define SHA384_FdChunk _libmd_SHA384_FdChunk
|
||||
#endif
|
||||
#ifndef SHA384_File
|
||||
#define SHA384_File _libmd_SHA384_File
|
||||
#endif
|
||||
@ -74,10 +80,13 @@ __BEGIN_DECLS
|
||||
|
||||
void SHA384_Init(SHA384_CTX *);
|
||||
void SHA384_Update(SHA384_CTX *, const void *, size_t);
|
||||
void SHA384_Final(unsigned char [static SHA384_DIGEST_LENGTH], SHA384_CTX *);
|
||||
void SHA384_Final(unsigned char [__min_size(SHA384_DIGEST_LENGTH)],
|
||||
SHA384_CTX *);
|
||||
#ifndef _KERNEL
|
||||
char *SHA384_End(SHA384_CTX *, char *);
|
||||
char *SHA384_Data(const void *, unsigned int, char *);
|
||||
char *SHA384_Fd(int, char *);
|
||||
char *SHA384_FdChunk(int, char *, off_t, off_t);
|
||||
char *SHA384_File(const char *, char *);
|
||||
char *SHA384_FileChunk(const char *, char *, off_t, off_t);
|
||||
#endif
|
||||
|
@ -58,6 +58,12 @@ __BEGIN_DECLS
|
||||
#ifndef SHA512_End
|
||||
#define SHA512_End _libmd_SHA512_End
|
||||
#endif
|
||||
#ifndef SHA512_Fd
|
||||
#define SHA512_Fd _libmd_SHA512_Fd
|
||||
#endif
|
||||
#ifndef SHA512_FdChunk
|
||||
#define SHA512_FdChunk _libmd_SHA512_FdChunk
|
||||
#endif
|
||||
#ifndef SHA512_File
|
||||
#define SHA512_File _libmd_SHA512_File
|
||||
#endif
|
||||
@ -77,10 +83,13 @@ __BEGIN_DECLS
|
||||
|
||||
void SHA512_Init(SHA512_CTX *);
|
||||
void SHA512_Update(SHA512_CTX *, const void *, size_t);
|
||||
void SHA512_Final(unsigned char [static SHA512_DIGEST_LENGTH], SHA512_CTX *);
|
||||
void SHA512_Final(unsigned char [__min_size(SHA512_DIGEST_LENGTH)],
|
||||
SHA512_CTX *);
|
||||
#ifndef _KERNEL
|
||||
char *SHA512_End(SHA512_CTX *, char *);
|
||||
char *SHA512_Data(const void *, unsigned int, char *);
|
||||
char *SHA512_Fd(int, char *);
|
||||
char *SHA512_FdChunk(int, char *, off_t, off_t);
|
||||
char *SHA512_File(const char *, char *);
|
||||
char *SHA512_FileChunk(const char *, char *, off_t, off_t);
|
||||
#endif
|
||||
|
@ -55,6 +55,12 @@ __BEGIN_DECLS
|
||||
#ifndef SHA512_224_End
|
||||
#define SHA512_224_End _libmd_SHA512_224_End
|
||||
#endif
|
||||
#ifndef SHA512_224_Fd
|
||||
#define SHA512_224_Fd _libmd_SHA512_224_Fd
|
||||
#endif
|
||||
#ifndef SHA512_224_FdChunk
|
||||
#define SHA512_224_FdChunk _libmd_SHA512_224_FdChunk
|
||||
#endif
|
||||
#ifndef SHA512_224_File
|
||||
#define SHA512_224_File _libmd_SHA512_224_File
|
||||
#endif
|
||||
@ -84,6 +90,12 @@ __BEGIN_DECLS
|
||||
#ifndef SHA512_256_End
|
||||
#define SHA512_256_End _libmd_SHA512_256_End
|
||||
#endif
|
||||
#ifndef SHA512_256_Fd
|
||||
#define SHA512_256_Fd _libmd_SHA512_256_Fd
|
||||
#endif
|
||||
#ifndef SHA512_256_FdChunk
|
||||
#define SHA512_256_FdChunk _libmd_SHA512_256_FdChunk
|
||||
#endif
|
||||
#ifndef SHA512_256_File
|
||||
#define SHA512_256_File _libmd_SHA512_256_File
|
||||
#endif
|
||||
@ -103,19 +115,25 @@ __BEGIN_DECLS
|
||||
|
||||
void SHA512_224_Init(SHA512_CTX *);
|
||||
void SHA512_224_Update(SHA512_CTX *, const void *, size_t);
|
||||
void SHA512_224_Final(unsigned char [static SHA512_224_DIGEST_LENGTH], SHA512_CTX *);
|
||||
void SHA512_224_Final(unsigned char [__min_size(SHA512_224_DIGEST_LENGTH)],
|
||||
SHA512_CTX *);
|
||||
#ifndef _KERNEL
|
||||
char *SHA512_224_End(SHA512_CTX *, char *);
|
||||
char *SHA512_224_Data(const void *, unsigned int, char *);
|
||||
char *SHA512_224_Fd(int, char *);
|
||||
char *SHA512_224_FdChunk(int, char *, off_t, off_t);
|
||||
char *SHA512_224_File(const char *, char *);
|
||||
char *SHA512_224_FileChunk(const char *, char *, off_t, off_t);
|
||||
#endif
|
||||
void SHA512_256_Init(SHA512_CTX *);
|
||||
void SHA512_256_Update(SHA512_CTX *, const void *, size_t);
|
||||
void SHA512_256_Final(unsigned char [static SHA512_256_DIGEST_LENGTH], SHA512_CTX *);
|
||||
void SHA512_256_Final(unsigned char [__min_size(SHA512_256_DIGEST_LENGTH)],
|
||||
SHA512_CTX *);
|
||||
#ifndef _KERNEL
|
||||
char *SHA512_256_End(SHA512_CTX *, char *);
|
||||
char *SHA512_256_Data(const void *, unsigned int, char *);
|
||||
char *SHA512_256_Fd(int, char *);
|
||||
char *SHA512_256_FdChunk(int, char *, off_t, off_t);
|
||||
char *SHA512_256_File(const char *, char *);
|
||||
char *SHA512_256_FileChunk(const char *, char *, off_t, off_t);
|
||||
#endif
|
||||
|
@ -68,15 +68,16 @@ typedef struct _SIPHASH_CTX {
|
||||
#define SipHash24_Init(x) SipHash_InitX((x), 2, 4)
|
||||
#define SipHash48_Init(x) SipHash_InitX((x), 4, 8)
|
||||
void SipHash_InitX(SIPHASH_CTX *, int, int);
|
||||
void SipHash_SetKey(SIPHASH_CTX *, const uint8_t[static SIPHASH_KEY_LENGTH]);
|
||||
void SipHash_SetKey(SIPHASH_CTX *,
|
||||
const uint8_t[__min_size(SIPHASH_KEY_LENGTH)]);
|
||||
void SipHash_Update(SIPHASH_CTX *, const void *, size_t);
|
||||
void SipHash_Final(uint8_t[static SIPHASH_DIGEST_LENGTH], SIPHASH_CTX *);
|
||||
void SipHash_Final(uint8_t[__min_size(SIPHASH_DIGEST_LENGTH)], SIPHASH_CTX *);
|
||||
uint64_t SipHash_End(SIPHASH_CTX *);
|
||||
|
||||
#define SipHash24(x, y, z, i) SipHashX((x), 2, 4, (y), (z), (i));
|
||||
#define SipHash48(x, y, z, i) SipHashX((x), 4, 8, (y), (z), (i));
|
||||
uint64_t SipHashX(SIPHASH_CTX *, int, int, const uint8_t[static SIPHASH_KEY_LENGTH], const void *,
|
||||
size_t);
|
||||
uint64_t SipHashX(SIPHASH_CTX *, int, int,
|
||||
const uint8_t[__min_size(SIPHASH_KEY_LENGTH)], const void *, size_t);
|
||||
|
||||
int SipHash24_TestVectors(void);
|
||||
|
||||
|
@ -57,9 +57,12 @@ void SKEIN256_Update(SKEIN256_CTX *ctx, const void *in, size_t len);
|
||||
void SKEIN512_Update(SKEIN512_CTX *ctx, const void *in, size_t len);
|
||||
void SKEIN1024_Update(SKEIN1024_CTX *ctx, const void *in, size_t len);
|
||||
|
||||
void SKEIN256_Final(unsigned char digest[static SKEIN256_DIGEST_LENGTH], SKEIN256_CTX *ctx);
|
||||
void SKEIN512_Final(unsigned char digest[static SKEIN512_DIGEST_LENGTH], SKEIN512_CTX *ctx);
|
||||
void SKEIN1024_Final(unsigned char digest[static SKEIN1024_DIGEST_LENGTH], SKEIN1024_CTX *ctx);
|
||||
void SKEIN256_Final(unsigned char digest[__min_size(SKEIN256_DIGEST_LENGTH)],
|
||||
SKEIN256_CTX *ctx);
|
||||
void SKEIN512_Final(unsigned char digest[__min_size(SKEIN512_DIGEST_LENGTH)],
|
||||
SKEIN512_CTX *ctx);
|
||||
void SKEIN1024_Final(unsigned char digest[__min_size(SKEIN1024_DIGEST_LENGTH)],
|
||||
SKEIN1024_CTX *ctx);
|
||||
|
||||
#ifndef _KERNEL
|
||||
char *SKEIN256_End(SKEIN256_CTX *, char *);
|
||||
@ -68,6 +71,12 @@ char *SKEIN1024_End(SKEIN1024_CTX *, char *);
|
||||
char *SKEIN256_Data(const void *, unsigned int, char *);
|
||||
char *SKEIN512_Data(const void *, unsigned int, char *);
|
||||
char *SKEIN1024_Data(const void *, unsigned int, char *);
|
||||
char *SKEIN256_Fd(int, char *);
|
||||
char *SKEIN512_Fd(int, char *);
|
||||
char *SKEIN1024_Fd(int, char *);
|
||||
char *SKEIN256_FdChunk(int, char *, off_t, off_t);
|
||||
char *SKEIN512_FdChunk(int, char *, off_t, off_t);
|
||||
char *SKEIN1024_FdChunk(int, char *, off_t, off_t);
|
||||
char *SKEIN256_File(const char *, char *);
|
||||
char *SKEIN512_File(const char *, char *);
|
||||
char *SKEIN1024_File(const char *, char *);
|
||||
|
@ -137,6 +137,16 @@ void Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt)
|
||||
#define SKEIN512_End _libmd_SKEIN512_End
|
||||
#define SKEIN1024_End _libmd_SKEIN1024_End
|
||||
#endif
|
||||
#ifndef SKEIN256_Fd
|
||||
#define SKEIN256_Fd _libmd_SKEIN256_Fd
|
||||
#define SKEIN512_Fd _libmd_SKEIN512_Fd
|
||||
#define SKEIN1024_Fd _libmd_SKEIN1024_Fd
|
||||
#endif
|
||||
#ifndef SKEIN256_FdChunk
|
||||
#define SKEIN256_FdChunk _libmd_SKEIN256_FdChunk
|
||||
#define SKEIN512_FdChunk _libmd_SKEIN512_FdChunk
|
||||
#define SKEIN1024_FdChunk _libmd_SKEIN1024_FdChunk
|
||||
#endif
|
||||
#ifndef SKEIN256_File
|
||||
#define SKEIN256_File _libmd_SKEIN256_File
|
||||
#define SKEIN512_File _libmd_SKEIN512_File
|
||||
|
@ -795,6 +795,8 @@ bfe_list_newbuf(struct bfe_softc *sc, int c)
|
||||
int nsegs;
|
||||
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
m->m_len = m->m_pkthdr.len = MCLBYTES;
|
||||
|
||||
if (bus_dmamap_load_mbuf_sg(sc->bfe_rxmbuf_tag, sc->bfe_rx_sparemap,
|
||||
|
@ -367,16 +367,10 @@ MODULE_DEPEND(em, netmap, 1, 1, 1);
|
||||
|
||||
#define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000)
|
||||
#define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024)
|
||||
#define M_TSO_LEN 66
|
||||
|
||||
#define MAX_INTS_PER_SEC 8000
|
||||
#define DEFAULT_ITR (1000000000/(MAX_INTS_PER_SEC * 256))
|
||||
|
||||
/* Allow common code without TSO */
|
||||
#ifndef CSUM_TSO
|
||||
#define CSUM_TSO 0
|
||||
#endif
|
||||
|
||||
#define TSO_WORKAROUND 4
|
||||
|
||||
static SYSCTL_NODE(_hw, OID_AUTO, em, CTLFLAG_RD, 0, "EM driver parameters");
|
||||
@ -1399,15 +1393,9 @@ em_init_locked(struct adapter *adapter)
|
||||
if_clearhwassist(ifp);
|
||||
if (if_getcapenable(ifp) & IFCAP_TXCSUM)
|
||||
if_sethwassistbits(ifp, CSUM_TCP | CSUM_UDP, 0);
|
||||
/*
|
||||
** There have proven to be problems with TSO when not
|
||||
** at full gigabit speed, so disable the assist automatically
|
||||
** when at lower speeds. -jfv
|
||||
*/
|
||||
if (if_getcapenable(ifp) & IFCAP_TSO4) {
|
||||
if (adapter->link_speed == SPEED_1000)
|
||||
if_sethwassistbits(ifp, CSUM_TSO, 0);
|
||||
}
|
||||
|
||||
if (if_getcapenable(ifp) & IFCAP_TSO4)
|
||||
if_sethwassistbits(ifp, CSUM_TSO, 0);
|
||||
|
||||
/* Configure for OS presence */
|
||||
em_init_manageability(adapter);
|
||||
@ -2415,6 +2403,18 @@ em_update_link_status(struct adapter *adapter)
|
||||
if (link_check && (adapter->link_active == 0)) {
|
||||
e1000_get_speed_and_duplex(hw, &adapter->link_speed,
|
||||
&adapter->link_duplex);
|
||||
/*
|
||||
** There have proven to be problems with TSO when not
|
||||
** at full gigabit speed, so disable the assist automatically
|
||||
** when at lower speeds. -jfv
|
||||
*/
|
||||
if (adapter->link_speed != SPEED_1000) {
|
||||
if_sethwassistbits(ifp, 0, CSUM_TSO);
|
||||
if_setcapenablebit(ifp, 0, IFCAP_TSO4);
|
||||
if_setcapabilitiesbit(ifp, 0, IFCAP_TSO4);
|
||||
|
||||
}
|
||||
|
||||
/* Check if we must disable SPEED_MODE bit on PCI-E */
|
||||
if ((adapter->link_speed != SPEED_1000) &&
|
||||
((hw->mac.type == e1000_82571) ||
|
||||
@ -5276,6 +5276,8 @@ em_get_wakeup(device_t dev)
|
||||
case e1000_ich10lan:
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
case e1000_pch_lpt:
|
||||
case e1000_pch_spt:
|
||||
apme_mask = E1000_WUC_APME;
|
||||
adapter->has_amt = TRUE;
|
||||
eeprom_data = E1000_READ_REG(&adapter->hw, E1000_WUC);
|
||||
@ -5324,7 +5326,7 @@ em_enable_wakeup(device_t dev)
|
||||
{
|
||||
struct adapter *adapter = device_get_softc(dev);
|
||||
if_t ifp = adapter->ifp;
|
||||
u32 pmc, ctrl, ctrl_ext, rctl;
|
||||
u32 pmc, ctrl, ctrl_ext, rctl, wuc;
|
||||
u16 status;
|
||||
|
||||
if ((pci_find_cap(dev, PCIY_PMG, &pmc) != 0))
|
||||
@ -5334,7 +5336,9 @@ em_enable_wakeup(device_t dev)
|
||||
ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
|
||||
ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
|
||||
wuc = E1000_READ_REG(&adapter->hw, E1000_WUC);
|
||||
wuc |= E1000_WUC_PME_EN;
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_WUC, wuc);
|
||||
|
||||
if ((adapter->hw.mac.type == e1000_ich8lan) ||
|
||||
(adapter->hw.mac.type == e1000_pchlan) ||
|
||||
@ -5365,8 +5369,10 @@ em_enable_wakeup(device_t dev)
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
|
||||
}
|
||||
|
||||
if ((adapter->hw.mac.type == e1000_pchlan) ||
|
||||
(adapter->hw.mac.type == e1000_pch2lan)) {
|
||||
if ((adapter->hw.mac.type == e1000_pchlan) ||
|
||||
(adapter->hw.mac.type == e1000_pch2lan) ||
|
||||
(adapter->hw.mac.type == e1000_pch_lpt) ||
|
||||
(adapter->hw.mac.type == e1000_pch_spt)) {
|
||||
if (em_enable_phy_wakeup(adapter))
|
||||
return;
|
||||
} else {
|
||||
|
@ -592,11 +592,20 @@ igb_attach(device_t dev)
|
||||
error = EIO;
|
||||
goto err_late;
|
||||
}
|
||||
/* Check its sanity */
|
||||
if (!igb_is_valid_ether_addr(adapter->hw.mac.addr)) {
|
||||
device_printf(dev, "Invalid MAC address\n");
|
||||
error = EIO;
|
||||
goto err_late;
|
||||
|
||||
/* Check its sanity */
|
||||
if (!igb_is_valid_ether_addr(adapter->hw.mac.addr)) {
|
||||
if (adapter->vf_ifp) {
|
||||
u8 addr[ETHER_ADDR_LEN];
|
||||
arc4rand(&addr, sizeof(addr), 0);
|
||||
addr[0] &= 0xFE;
|
||||
addr[0] |= 0x02;
|
||||
bcopy(addr, adapter->hw.mac.addr, sizeof(addr));
|
||||
} else {
|
||||
device_printf(dev, "Invalid MAC address\n");
|
||||
error = EIO;
|
||||
goto err_late;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup OS specific network interface */
|
||||
|
@ -41,7 +41,6 @@
|
||||
*/
|
||||
// #define BATCH_DISPATCH
|
||||
// #define NIC_SEND_COMBINING
|
||||
// #define NIC_PARAVIRT /* enable virtio-like synchronization */
|
||||
|
||||
#include <rtems/bsd/local/opt_inet.h>
|
||||
#include <rtems/bsd/local/opt_inet6.h>
|
||||
@ -488,10 +487,6 @@ lem_attach(device_t dev)
|
||||
lem_add_rx_process_limit(adapter, "batch_enable",
|
||||
"driver rx batch", &adapter->batch_enable, 0);
|
||||
#endif /* BATCH_DISPATCH */
|
||||
#ifdef NIC_PARAVIRT
|
||||
lem_add_rx_process_limit(adapter, "rx_retries",
|
||||
"driver rx retries", &adapter->rx_retries, 0);
|
||||
#endif /* NIC_PARAVIRT */
|
||||
|
||||
/* Sysctl for setting the interface flow control */
|
||||
lem_set_flow_cntrl(adapter, "flow_control",
|
||||
@ -550,51 +545,16 @@ lem_attach(device_t dev)
|
||||
*/
|
||||
adapter->hw.mac.report_tx_early = 1;
|
||||
|
||||
#ifdef NIC_PARAVIRT
|
||||
device_printf(dev, "driver supports paravirt, subdev 0x%x\n",
|
||||
adapter->hw.subsystem_device_id);
|
||||
if (adapter->hw.subsystem_device_id == E1000_PARA_SUBDEV) {
|
||||
uint64_t bus_addr;
|
||||
|
||||
device_printf(dev, "paravirt support on dev %p\n", adapter);
|
||||
tsize = 4096; // XXX one page for the csb
|
||||
if (lem_dma_malloc(adapter, tsize, &adapter->csb_mem, BUS_DMA_NOWAIT)) {
|
||||
device_printf(dev, "Unable to allocate csb memory\n");
|
||||
error = ENOMEM;
|
||||
goto err_csb;
|
||||
}
|
||||
/* Setup the Base of the CSB */
|
||||
adapter->csb = (struct paravirt_csb *)adapter->csb_mem.dma_vaddr;
|
||||
/* force the first kick */
|
||||
adapter->csb->host_need_txkick = 1; /* txring empty */
|
||||
adapter->csb->guest_need_rxkick = 1; /* no rx packets */
|
||||
bus_addr = adapter->csb_mem.dma_paddr;
|
||||
lem_add_rx_process_limit(adapter, "csb_on",
|
||||
"enable paravirt.", &adapter->csb->guest_csb_on, 0);
|
||||
lem_add_rx_process_limit(adapter, "txc_lim",
|
||||
"txc_lim", &adapter->csb->host_txcycles_lim, 1);
|
||||
|
||||
/* some stats */
|
||||
#define PA_SC(name, var, val) \
|
||||
lem_add_rx_process_limit(adapter, name, name, var, val)
|
||||
PA_SC("host_need_txkick",&adapter->csb->host_need_txkick, 1);
|
||||
PA_SC("host_rxkick_at",&adapter->csb->host_rxkick_at, ~0);
|
||||
PA_SC("guest_need_txkick",&adapter->csb->guest_need_txkick, 0);
|
||||
PA_SC("guest_need_rxkick",&adapter->csb->guest_need_rxkick, 1);
|
||||
PA_SC("tdt_reg_count",&adapter->tdt_reg_count, 0);
|
||||
PA_SC("tdt_csb_count",&adapter->tdt_csb_count, 0);
|
||||
PA_SC("tdt_int_count",&adapter->tdt_int_count, 0);
|
||||
PA_SC("guest_need_kick_count",&adapter->guest_need_kick_count, 0);
|
||||
/* tell the host where the block is */
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_CSBAH,
|
||||
(u32)(bus_addr >> 32));
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_CSBAL,
|
||||
(u32)bus_addr);
|
||||
}
|
||||
#endif /* NIC_PARAVIRT */
|
||||
|
||||
tsize = roundup2(adapter->num_tx_desc * sizeof(struct e1000_tx_desc),
|
||||
EM_DBA_ALIGN);
|
||||
/*
|
||||
* It seems that the descriptor DMA engine on some PCI cards
|
||||
* fetches memory past the end of the last descriptor in the
|
||||
* ring. These reads are problematic when VT-d (DMAR) busdma
|
||||
* is used. Allocate the scratch space to avoid getting
|
||||
* faults from DMAR, by requesting scratch memory for one more
|
||||
* descriptor.
|
||||
*/
|
||||
tsize = roundup2((adapter->num_tx_desc + 1) *
|
||||
sizeof(struct e1000_tx_desc), EM_DBA_ALIGN);
|
||||
|
||||
/* Allocate Transmit Descriptor ring */
|
||||
if (lem_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
|
||||
@ -605,8 +565,11 @@ lem_attach(device_t dev)
|
||||
adapter->tx_desc_base =
|
||||
(struct e1000_tx_desc *)adapter->txdma.dma_vaddr;
|
||||
|
||||
rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc),
|
||||
EM_DBA_ALIGN);
|
||||
/*
|
||||
* See comment above txdma allocation for rationale behind +1.
|
||||
*/
|
||||
rsize = roundup2((adapter->num_rx_desc + 1) *
|
||||
sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
|
||||
|
||||
/* Allocate Receive Descriptor ring */
|
||||
if (lem_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
|
||||
@ -751,11 +714,6 @@ err_hw_init:
|
||||
err_rx_desc:
|
||||
lem_dma_free(adapter, &adapter->txdma);
|
||||
err_tx_desc:
|
||||
#ifdef NIC_PARAVIRT
|
||||
lem_dma_free(adapter, &adapter->csb_mem);
|
||||
err_csb:
|
||||
#endif /* NIC_PARAVIRT */
|
||||
|
||||
err_pci:
|
||||
if (adapter->ifp != (void *)NULL)
|
||||
if_free(adapter->ifp);
|
||||
@ -843,12 +801,6 @@ lem_detach(device_t dev)
|
||||
adapter->rx_desc_base = NULL;
|
||||
}
|
||||
|
||||
#ifdef NIC_PARAVIRT
|
||||
if (adapter->csb) {
|
||||
lem_dma_free(adapter, &adapter->csb_mem);
|
||||
adapter->csb = NULL;
|
||||
}
|
||||
#endif /* NIC_PARAVIRT */
|
||||
lem_release_hw_control(adapter);
|
||||
free(adapter->mta, M_DEVBUF);
|
||||
EM_TX_LOCK_DESTROY(adapter);
|
||||
@ -958,16 +910,6 @@ lem_start_locked(if_t ifp)
|
||||
}
|
||||
if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
|
||||
if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0);
|
||||
#ifdef NIC_PARAVIRT
|
||||
if (if_getdrvflags(ifp) & IFF_DRV_OACTIVE && adapter->csb &&
|
||||
adapter->csb->guest_csb_on &&
|
||||
!(adapter->csb->guest_need_txkick & 1)) {
|
||||
adapter->csb->guest_need_txkick = 1;
|
||||
adapter->guest_need_kick_count++;
|
||||
// XXX memory barrier
|
||||
lem_txeof(adapter); // XXX possibly clear IFF_DRV_OACTIVE
|
||||
}
|
||||
#endif /* NIC_PARAVIRT */
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1815,24 +1757,6 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
|
||||
bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
|
||||
#ifdef NIC_PARAVIRT
|
||||
if (adapter->csb) {
|
||||
adapter->csb->guest_tdt = i;
|
||||
/* XXX memory barrier ? */
|
||||
if (adapter->csb->guest_csb_on &&
|
||||
!(adapter->csb->host_need_txkick & 1)) {
|
||||
/* XXX maybe useless
|
||||
* clean the ring. maybe do it before ?
|
||||
* maybe a little bit of histeresys ?
|
||||
*/
|
||||
if (adapter->num_tx_desc_avail <= 64) {// XXX
|
||||
lem_txeof(adapter);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
#endif /* NIC_PARAVIRT */
|
||||
|
||||
#ifdef NIC_SEND_COMBINING
|
||||
if (adapter->sc_enable) {
|
||||
if (adapter->shadow_tdt & MIT_PENDING_INT) {
|
||||
@ -2088,20 +2012,6 @@ lem_local_timer(void *arg)
|
||||
|
||||
lem_smartspeed(adapter);
|
||||
|
||||
#ifdef NIC_PARAVIRT
|
||||
/* recover space if needed */
|
||||
if (adapter->csb && adapter->csb->guest_csb_on &&
|
||||
(adapter->watchdog_check == TRUE) &&
|
||||
(ticks - adapter->watchdog_time > EM_WATCHDOG) &&
|
||||
(adapter->num_tx_desc_avail != adapter->num_tx_desc) ) {
|
||||
lem_txeof(adapter);
|
||||
/*
|
||||
* lem_txeof() normally (except when space in the queue
|
||||
* runs low XXX) cleans watchdog_check so that
|
||||
* we do not hung.
|
||||
*/
|
||||
}
|
||||
#endif /* NIC_PARAVIRT */
|
||||
/*
|
||||
* We check the watchdog: the time since
|
||||
* the last TX descriptor was cleaned.
|
||||
@ -3178,12 +3088,6 @@ lem_txeof(struct adapter *adapter)
|
||||
*/
|
||||
if (adapter->num_tx_desc_avail > EM_TX_CLEANUP_THRESHOLD) {
|
||||
if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
|
||||
#ifdef NIC_PARAVIRT
|
||||
if (adapter->csb) { // XXX also csb_on ?
|
||||
adapter->csb->guest_need_txkick = 2; /* acked */
|
||||
// XXX memory barrier
|
||||
}
|
||||
#endif /* NIC_PARAVIRT */
|
||||
if (adapter->num_tx_desc_avail == adapter->num_tx_desc) {
|
||||
adapter->watchdog_check = FALSE;
|
||||
return;
|
||||
@ -3572,15 +3476,6 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
|
||||
#ifdef BATCH_DISPATCH
|
||||
struct mbuf *mh = NULL, *mt = NULL;
|
||||
#endif /* BATCH_DISPATCH */
|
||||
#ifdef NIC_PARAVIRT
|
||||
int retries = 0;
|
||||
struct paravirt_csb* csb = adapter->csb;
|
||||
int csb_mode = csb && csb->guest_csb_on;
|
||||
|
||||
//ND("clear guest_rxkick at %d", adapter->next_rx_desc_to_check);
|
||||
if (csb_mode && csb->guest_need_rxkick)
|
||||
csb->guest_need_rxkick = 0;
|
||||
#endif /* NIC_PARAVIRT */
|
||||
EM_RX_LOCK(adapter);
|
||||
|
||||
#ifdef BATCH_DISPATCH
|
||||
@ -3598,45 +3493,20 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
|
||||
}
|
||||
#endif /* DEV_NETMAP */
|
||||
|
||||
#if 1 // XXX optimization ?
|
||||
if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
|
||||
if (done != NULL)
|
||||
*done = rx_sent;
|
||||
EM_RX_UNLOCK(adapter);
|
||||
return (FALSE);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
while (count != 0 && if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
|
||||
struct mbuf *m = NULL;
|
||||
|
||||
status = current_desc->status;
|
||||
if ((status & E1000_RXD_STAT_DD) == 0) {
|
||||
#ifdef NIC_PARAVIRT
|
||||
if (csb_mode) {
|
||||
/* buffer not ready yet. Retry a few times before giving up */
|
||||
if (++retries <= adapter->rx_retries) {
|
||||
continue;
|
||||
}
|
||||
if (csb->guest_need_rxkick == 0) {
|
||||
// ND("set guest_rxkick at %d", adapter->next_rx_desc_to_check);
|
||||
csb->guest_need_rxkick = 1;
|
||||
// XXX memory barrier, status volatile ?
|
||||
continue; /* double check */
|
||||
}
|
||||
}
|
||||
/* no buffer ready, give up */
|
||||
#endif /* NIC_PARAVIRT */
|
||||
break;
|
||||
}
|
||||
#ifdef NIC_PARAVIRT
|
||||
if (csb_mode) {
|
||||
if (csb->guest_need_rxkick)
|
||||
// ND("clear again guest_rxkick at %d", adapter->next_rx_desc_to_check);
|
||||
csb->guest_need_rxkick = 0;
|
||||
retries = 0;
|
||||
}
|
||||
#endif /* NIC_PARAVIRT */
|
||||
|
||||
mp = adapter->rx_buffer_area[i].m_head;
|
||||
/*
|
||||
@ -3761,18 +3631,6 @@ discard:
|
||||
bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
|
||||
#ifdef NIC_PARAVIRT
|
||||
if (csb_mode) {
|
||||
/* the buffer at i has been already replaced by lem_get_buf()
|
||||
* so it is safe to set guest_rdt = i and possibly send a kick.
|
||||
* XXX see if we can optimize it later.
|
||||
*/
|
||||
csb->guest_rdt = i;
|
||||
// XXX memory barrier
|
||||
if (i == csb->host_rxkick_at)
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
|
||||
}
|
||||
#endif /* NIC_PARAVIRT */
|
||||
/* Advance our pointers to the next descriptor. */
|
||||
if (++i == adapter->num_rx_desc)
|
||||
i = 0;
|
||||
@ -3819,9 +3677,6 @@ discard:
|
||||
/* Advance the E1000's Receive Queue #0 "Tail Pointer". */
|
||||
if (--i < 0)
|
||||
i = adapter->num_rx_desc - 1;
|
||||
#ifdef NIC_PARAVIRT
|
||||
if (!csb_mode) /* filter out writes */
|
||||
#endif /* NIC_PARAVIRT */
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
|
||||
if (done != NULL)
|
||||
*done = rx_sent;
|
||||
|
@ -123,6 +123,8 @@ rgephy_attach(device_t dev)
|
||||
flags = 0;
|
||||
if (mii_dev_mac_match(dev, "re"))
|
||||
flags |= MIIF_PHYPRIV0;
|
||||
else if (mii_dev_mac_match(dev, "ure"))
|
||||
flags |= MIIF_PHYPRIV1;
|
||||
mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0);
|
||||
|
||||
/* RTL8169S do not report auto-sense; add manually. */
|
||||
@ -295,7 +297,10 @@ rgephy_linkup(struct mii_softc *sc)
|
||||
linkup++;
|
||||
}
|
||||
} else {
|
||||
reg = PHY_READ(sc, RL_GMEDIASTAT);
|
||||
if (sc->mii_flags & MIIF_PHYPRIV1)
|
||||
reg = PHY_READ(sc, URE_GMEDIASTAT);
|
||||
else
|
||||
reg = PHY_READ(sc, RL_GMEDIASTAT);
|
||||
if (reg & RL_GMEDIASTAT_LINK)
|
||||
linkup++;
|
||||
}
|
||||
@ -380,7 +385,10 @@ rgephy_status(struct mii_softc *sc)
|
||||
mii->mii_media_active |= IFM_HDX;
|
||||
}
|
||||
} else {
|
||||
bmsr = PHY_READ(sc, RL_GMEDIASTAT);
|
||||
if (sc->mii_flags & MIIF_PHYPRIV1)
|
||||
bmsr = PHY_READ(sc, URE_GMEDIASTAT);
|
||||
else
|
||||
bmsr = PHY_READ(sc, RL_GMEDIASTAT);
|
||||
if (bmsr & RL_GMEDIASTAT_1000MBPS)
|
||||
mii->mii_media_active |= IFM_1000_T;
|
||||
else if (bmsr & RL_GMEDIASTAT_100MBPS)
|
||||
|
@ -199,4 +199,7 @@
|
||||
#define EEELPAR_1000T 0x0004 /* link partner 1000baseT EEE capable */
|
||||
#define EEELPAR_100TX 0x0002 /* link partner 100baseTX EEE capable */
|
||||
|
||||
/* RTL8153 */
|
||||
#define URE_GMEDIASTAT 0xe908 /* media status register */
|
||||
|
||||
#endif /* _DEV_RGEPHY_MIIREG_H_ */
|
||||
|
@ -663,9 +663,27 @@ enum nvme_log_page {
|
||||
NVME_LOG_ERROR = 0x01,
|
||||
NVME_LOG_HEALTH_INFORMATION = 0x02,
|
||||
NVME_LOG_FIRMWARE_SLOT = 0x03,
|
||||
/* 0x04-0x7F - reserved */
|
||||
NVME_LOG_CHANGED_NAMESPACE = 0x04,
|
||||
NVME_LOG_COMMAND_EFFECT = 0x05,
|
||||
/* 0x06-0x7F - reserved */
|
||||
/* 0x80-0xBF - I/O command set specific */
|
||||
NVME_LOG_RES_NOTIFICATION = 0x80,
|
||||
/* 0xC0-0xFF - vendor specific */
|
||||
|
||||
/*
|
||||
* The following are Intel Specific log pages, but they seem
|
||||
* to be widely implemented.
|
||||
*/
|
||||
INTEL_LOG_READ_LAT_LOG = 0xc1,
|
||||
INTEL_LOG_WRITE_LAT_LOG = 0xc2,
|
||||
INTEL_LOG_TEMP_STATS = 0xc5,
|
||||
INTEL_LOG_ADD_SMART = 0xca,
|
||||
INTEL_LOG_DRIVE_MKT_NAME = 0xdd,
|
||||
|
||||
/*
|
||||
* HGST log page, with lots ofs sub pages.
|
||||
*/
|
||||
HGST_INFO_LOG = 0xc1,
|
||||
};
|
||||
|
||||
struct nvme_error_information_entry {
|
||||
@ -724,8 +742,11 @@ struct nvme_health_information_page {
|
||||
uint64_t unsafe_shutdowns[2];
|
||||
uint64_t media_errors[2];
|
||||
uint64_t num_error_info_log_entries[2];
|
||||
uint32_t warning_temp_time;
|
||||
uint32_t error_temp_time;
|
||||
uint16_t temp_sensor[8];
|
||||
|
||||
uint8_t reserved2[320];
|
||||
uint8_t reserved2[296];
|
||||
} __packed __aligned(4);
|
||||
|
||||
struct nvme_firmware_page {
|
||||
@ -740,6 +761,19 @@ struct nvme_firmware_page {
|
||||
uint8_t reserved2[448];
|
||||
} __packed __aligned(4);
|
||||
|
||||
struct intel_log_temp_stats
|
||||
{
|
||||
uint64_t current;
|
||||
uint64_t overtemp_flag_last;
|
||||
uint64_t overtemp_flag_life;
|
||||
uint64_t max_temp;
|
||||
uint64_t min_temp;
|
||||
uint64_t _rsvd[5];
|
||||
uint64_t max_oper_temp;
|
||||
uint64_t min_oper_temp;
|
||||
uint64_t est_offset;
|
||||
} __packed __aligned(4);
|
||||
|
||||
#define NVME_TEST_MAX_THREADS 128
|
||||
|
||||
struct nvme_io_test {
|
||||
|
@ -3981,7 +3981,7 @@ pci_rescan_method(device_t dev)
|
||||
if (hdrtype & PCIM_MFDEV)
|
||||
pcifunchigh = PCIB_MAXFUNCS(pcib);
|
||||
for (f = 0; f <= pcifunchigh; f++) {
|
||||
if (REG(PCIR_VENDOR, 2) == 0xfff)
|
||||
if (REG(PCIR_VENDOR, 2) == 0xffff)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@ -4081,6 +4081,7 @@ pci_add_child(device_t bus, struct pci_devinfo *dinfo)
|
||||
pci_print_verbose(dinfo);
|
||||
pci_add_resources(bus, dinfo->cfg.dev, 0, 0);
|
||||
pci_child_added(dinfo->cfg.dev);
|
||||
EVENTHANDLER_INVOKE(pci_add_device, dinfo->cfg.dev);
|
||||
}
|
||||
|
||||
void
|
||||
@ -4617,6 +4618,9 @@ static const struct
|
||||
{PCIC_CRYPTO, PCIS_CRYPTO_ENTERTAIN, 1, "entertainment crypto"},
|
||||
{PCIC_DASP, -1, 0, "dasp"},
|
||||
{PCIC_DASP, PCIS_DASP_DPIO, 1, "DPIO module"},
|
||||
{PCIC_DASP, PCIS_DASP_PERFCNTRS, 1, "performance counters"},
|
||||
{PCIC_DASP, PCIS_DASP_COMM_SYNC, 1, "communication synchronizer"},
|
||||
{PCIC_DASP, PCIS_DASP_MGMT_CARD, 1, "signal processing management"},
|
||||
{0, 0, 0, NULL}
|
||||
};
|
||||
|
||||
@ -5009,6 +5013,7 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
|
||||
struct resource_list *rl = &dinfo->resources;
|
||||
struct resource *res;
|
||||
struct pci_map *pm;
|
||||
uint16_t cmd;
|
||||
pci_addr_t map, testval;
|
||||
int mapsize;
|
||||
|
||||
@ -5107,8 +5112,17 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
|
||||
device_printf(child,
|
||||
"Lazy allocation of %#jx bytes rid %#x type %d at %#jx\n",
|
||||
count, *rid, type, rman_get_start(res));
|
||||
|
||||
/* Disable decoding via the CMD register before updating the BAR */
|
||||
cmd = pci_read_config(child, PCIR_COMMAND, 2);
|
||||
pci_write_config(child, PCIR_COMMAND,
|
||||
cmd & ~(PCI_BAR_MEM(map) ? PCIM_CMD_MEMEN : PCIM_CMD_PORTEN), 2);
|
||||
|
||||
map = rman_get_start(res);
|
||||
pci_write_bar(child, pm, map);
|
||||
|
||||
/* Restore the original value of the CMD register */
|
||||
pci_write_config(child, PCIR_COMMAND, cmd, 2);
|
||||
out:
|
||||
return (res);
|
||||
}
|
||||
@ -5331,6 +5345,8 @@ pci_child_deleted(device_t dev, device_t child)
|
||||
dinfo = device_get_ivars(child);
|
||||
rl = &dinfo->resources;
|
||||
|
||||
EVENTHANDLER_INVOKE(pci_delete_device, child);
|
||||
|
||||
/* Turn off access to resources we're about to free */
|
||||
if (bus_child_present(child) != 0) {
|
||||
pci_write_config(child, PCIR_COMMAND, pci_read_config(child,
|
||||
@ -5908,3 +5924,165 @@ pci_find_pcie_root_port(device_t dev)
|
||||
dev = pcib;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for pending transactions to complete on a PCI-express function.
|
||||
*
|
||||
* The maximum delay is specified in milliseconds in max_delay. Note
|
||||
* that this function may sleep.
|
||||
*
|
||||
* Returns true if the function is idle and false if the timeout is
|
||||
* exceeded. If dev is not a PCI-express function, this returns true.
|
||||
*/
|
||||
bool
|
||||
pcie_wait_for_pending_transactions(device_t dev, u_int max_delay)
|
||||
{
|
||||
struct pci_devinfo *dinfo = device_get_ivars(dev);
|
||||
uint16_t sta;
|
||||
int cap;
|
||||
|
||||
cap = dinfo->cfg.pcie.pcie_location;
|
||||
if (cap == 0)
|
||||
return (true);
|
||||
|
||||
sta = pci_read_config(dev, cap + PCIER_DEVICE_STA, 2);
|
||||
while (sta & PCIEM_STA_TRANSACTION_PND) {
|
||||
if (max_delay == 0)
|
||||
return (false);
|
||||
|
||||
/* Poll once every 100 milliseconds up to the timeout. */
|
||||
if (max_delay > 100) {
|
||||
pause_sbt("pcietp", 100 * SBT_1MS, 0, C_HARDCLOCK);
|
||||
max_delay -= 100;
|
||||
} else {
|
||||
pause_sbt("pcietp", max_delay * SBT_1MS, 0,
|
||||
C_HARDCLOCK);
|
||||
max_delay = 0;
|
||||
}
|
||||
sta = pci_read_config(dev, cap + PCIER_DEVICE_STA, 2);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the maximum Completion Timeout in microseconds.
|
||||
*
|
||||
* For non-PCI-express functions this returns 0.
|
||||
*/
|
||||
int
|
||||
pcie_get_max_completion_timeout(device_t dev)
|
||||
{
|
||||
struct pci_devinfo *dinfo = device_get_ivars(dev);
|
||||
int cap;
|
||||
|
||||
cap = dinfo->cfg.pcie.pcie_location;
|
||||
if (cap == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Functions using the 1.x spec use the default timeout range of
|
||||
* 50 microseconds to 50 milliseconds. Functions that do not
|
||||
* support programmable timeouts also use this range.
|
||||
*/
|
||||
if ((dinfo->cfg.pcie.pcie_flags & PCIEM_FLAGS_VERSION) < 2 ||
|
||||
(pci_read_config(dev, cap + PCIER_DEVICE_CAP2, 4) &
|
||||
PCIEM_CAP2_COMP_TIMO_RANGES) == 0)
|
||||
return (50 * 1000);
|
||||
|
||||
switch (pci_read_config(dev, cap + PCIER_DEVICE_CTL2, 2) &
|
||||
PCIEM_CTL2_COMP_TIMO_VAL) {
|
||||
case PCIEM_CTL2_COMP_TIMO_100US:
|
||||
return (100);
|
||||
case PCIEM_CTL2_COMP_TIMO_10MS:
|
||||
return (10 * 1000);
|
||||
case PCIEM_CTL2_COMP_TIMO_55MS:
|
||||
return (55 * 1000);
|
||||
case PCIEM_CTL2_COMP_TIMO_210MS:
|
||||
return (210 * 1000);
|
||||
case PCIEM_CTL2_COMP_TIMO_900MS:
|
||||
return (900 * 1000);
|
||||
case PCIEM_CTL2_COMP_TIMO_3500MS:
|
||||
return (3500 * 1000);
|
||||
case PCIEM_CTL2_COMP_TIMO_13S:
|
||||
return (13 * 1000 * 1000);
|
||||
case PCIEM_CTL2_COMP_TIMO_64S:
|
||||
return (64 * 1000 * 1000);
|
||||
default:
|
||||
return (50 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a Function Level Reset (FLR) on a device.
|
||||
*
|
||||
* This function first waits for any pending transactions to complete
|
||||
* within the timeout specified by max_delay. If transactions are
|
||||
* still pending, the function will return false without attempting a
|
||||
* reset.
|
||||
*
|
||||
* If dev is not a PCI-express function or does not support FLR, this
|
||||
* function returns false.
|
||||
*
|
||||
* Note that no registers are saved or restored. The caller is
|
||||
* responsible for saving and restoring any registers including
|
||||
* PCI-standard registers via pci_save_state() and
|
||||
* pci_restore_state().
|
||||
*/
|
||||
bool
|
||||
pcie_flr(device_t dev, u_int max_delay, bool force)
|
||||
{
|
||||
struct pci_devinfo *dinfo = device_get_ivars(dev);
|
||||
uint16_t cmd, ctl;
|
||||
int compl_delay;
|
||||
int cap;
|
||||
|
||||
cap = dinfo->cfg.pcie.pcie_location;
|
||||
if (cap == 0)
|
||||
return (false);
|
||||
|
||||
if (!(pci_read_config(dev, cap + PCIER_DEVICE_CAP, 4) & PCIEM_CAP_FLR))
|
||||
return (false);
|
||||
|
||||
/*
|
||||
* Disable busmastering to prevent generation of new
|
||||
* transactions while waiting for the device to go idle. If
|
||||
* the idle timeout fails, the command register is restored
|
||||
* which will re-enable busmastering.
|
||||
*/
|
||||
cmd = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||
pci_write_config(dev, PCIR_COMMAND, cmd & ~(PCIM_CMD_BUSMASTEREN), 2);
|
||||
if (!pcie_wait_for_pending_transactions(dev, max_delay)) {
|
||||
if (!force) {
|
||||
pci_write_config(dev, PCIR_COMMAND, cmd, 2);
|
||||
return (false);
|
||||
}
|
||||
pci_printf(&dinfo->cfg,
|
||||
"Resetting with transactions pending after %d ms\n",
|
||||
max_delay);
|
||||
|
||||
/*
|
||||
* Extend the post-FLR delay to cover the maximum
|
||||
* Completion Timeout delay of anything in flight
|
||||
* during the FLR delay. Enforce a minimum delay of
|
||||
* at least 10ms.
|
||||
*/
|
||||
compl_delay = pcie_get_max_completion_timeout(dev) / 1000;
|
||||
if (compl_delay < 10)
|
||||
compl_delay = 10;
|
||||
} else
|
||||
compl_delay = 0;
|
||||
|
||||
/* Initiate the reset. */
|
||||
ctl = pci_read_config(dev, cap + PCIER_DEVICE_CTL, 2);
|
||||
pci_write_config(dev, cap + PCIER_DEVICE_CTL, ctl |
|
||||
PCIEM_CTL_INITIATE_FLR, 2);
|
||||
|
||||
/* Wait for 100ms. */
|
||||
pause_sbt("pcieflr", (100 + compl_delay) * SBT_1MS, 0, C_HARDCLOCK);
|
||||
|
||||
if (pci_read_config(dev, cap + PCIER_DEVICE_STA, 2) &
|
||||
PCIEM_STA_TRANSACTION_PND)
|
||||
pci_printf(&dinfo->cfg, "Transactions pending after FLR!\n");
|
||||
return (true);
|
||||
}
|
||||
|
@ -885,10 +885,25 @@
|
||||
#define PCIEM_ROOT_STA_PME_STATUS 0x00010000
|
||||
#define PCIEM_ROOT_STA_PME_PEND 0x00020000
|
||||
#define PCIER_DEVICE_CAP2 0x24
|
||||
#define PCIEM_CAP2_ARI 0x20
|
||||
#define PCIEM_CAP2_COMP_TIMO_RANGES 0x0000000f
|
||||
#define PCIEM_CAP2_COMP_TIMO_RANGE_A 0x00000001
|
||||
#define PCIEM_CAP2_COMP_TIMO_RANGE_B 0x00000002
|
||||
#define PCIEM_CAP2_COMP_TIMO_RANGE_C 0x00000004
|
||||
#define PCIEM_CAP2_COMP_TIMO_RANGE_D 0x00000008
|
||||
#define PCIEM_CAP2_COMP_TIMO_DISABLE 0x00000010
|
||||
#define PCIEM_CAP2_ARI 0x00000020
|
||||
#define PCIER_DEVICE_CTL2 0x28
|
||||
#define PCIEM_CTL2_COMP_TIMEOUT_VAL 0x000f
|
||||
#define PCIEM_CTL2_COMP_TIMEOUT_DIS 0x0010
|
||||
#define PCIEM_CTL2_COMP_TIMO_VAL 0x000f
|
||||
#define PCIEM_CTL2_COMP_TIMO_50MS 0x0000
|
||||
#define PCIEM_CTL2_COMP_TIMO_100US 0x0001
|
||||
#define PCIEM_CTL2_COMP_TIMO_10MS 0x0002
|
||||
#define PCIEM_CTL2_COMP_TIMO_55MS 0x0005
|
||||
#define PCIEM_CTL2_COMP_TIMO_210MS 0x0006
|
||||
#define PCIEM_CTL2_COMP_TIMO_900MS 0x0009
|
||||
#define PCIEM_CTL2_COMP_TIMO_3500MS 0x000a
|
||||
#define PCIEM_CTL2_COMP_TIMO_13S 0x000d
|
||||
#define PCIEM_CTL2_COMP_TIMO_64S 0x000e
|
||||
#define PCIEM_CTL2_COMP_TIMO_DISABLE 0x0010
|
||||
#define PCIEM_CTL2_ARI 0x0020
|
||||
#define PCIEM_CTL2_ATOMIC_REQ_ENABLE 0x0040
|
||||
#define PCIEM_CTL2_ATOMIC_EGR_BLOCK 0x0080
|
||||
|
@ -31,6 +31,7 @@
|
||||
#define _PCIVAR_H_
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <sys/eventhandler.h>
|
||||
|
||||
/* some PCI bus constants */
|
||||
#define PCI_MAXMAPS_0 6 /* max. no. of memory/port maps */
|
||||
@ -594,7 +595,9 @@ uint32_t pcie_read_config(device_t dev, int reg, int width);
|
||||
void pcie_write_config(device_t dev, int reg, uint32_t value, int width);
|
||||
uint32_t pcie_adjust_config(device_t dev, int reg, uint32_t mask,
|
||||
uint32_t value, int width);
|
||||
|
||||
bool pcie_flr(device_t dev, u_int max_delay, bool force);
|
||||
int pcie_get_max_completion_timeout(device_t dev);
|
||||
bool pcie_wait_for_pending_transactions(device_t dev, u_int max_delay);
|
||||
|
||||
#ifdef BUS_SPACE_MAXADDR
|
||||
#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
|
||||
@ -631,4 +634,12 @@ void * vga_pci_map_bios(device_t dev, size_t *size);
|
||||
void vga_pci_unmap_bios(device_t dev, void *bios);
|
||||
int vga_pci_repost(device_t dev);
|
||||
|
||||
/**
|
||||
* Global eventhandlers invoked when PCI devices are added or removed
|
||||
* from the system.
|
||||
*/
|
||||
typedef void (*pci_event_fn)(void *arg, device_t dev);
|
||||
EVENTHANDLER_DECLARE(pci_add_device, pci_event_fn);
|
||||
EVENTHANDLER_DECLARE(pci_delete_device, pci_event_fn);
|
||||
|
||||
#endif /* _PCIVAR_H_ */
|
||||
|
@ -185,6 +185,8 @@ static const struct rl_type re_devs[] = {
|
||||
"RealTek 810xE PCIe 10/100baseTX" },
|
||||
{ RT_VENDORID, RT_DEVICEID_8168, 0,
|
||||
"RealTek 8168/8111 B/C/CP/D/DP/E/F/G PCIe Gigabit Ethernet" },
|
||||
{ NCUBE_VENDORID, RT_DEVICEID_8168, 0,
|
||||
"TP-Link TG-3468 v2 (RTL8168) Gigabit Ethernet" },
|
||||
{ RT_VENDORID, RT_DEVICEID_8169, 0,
|
||||
"RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" },
|
||||
{ RT_VENDORID, RT_DEVICEID_8169SC, 0,
|
||||
@ -1358,15 +1360,17 @@ re_attach(device_t dev)
|
||||
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
|
||||
}
|
||||
|
||||
/* Disable ASPM L0S/L1. */
|
||||
/* Disable ASPM L0S/L1 and CLKREQ. */
|
||||
if (sc->rl_expcap != 0) {
|
||||
cap = pci_read_config(dev, sc->rl_expcap +
|
||||
PCIER_LINK_CAP, 2);
|
||||
if ((cap & PCIEM_LINK_CAP_ASPM) != 0) {
|
||||
ctl = pci_read_config(dev, sc->rl_expcap +
|
||||
PCIER_LINK_CTL, 2);
|
||||
if ((ctl & PCIEM_LINK_CTL_ASPMC) != 0) {
|
||||
ctl &= ~PCIEM_LINK_CTL_ASPMC;
|
||||
if ((ctl & (PCIEM_LINK_CTL_ECPM |
|
||||
PCIEM_LINK_CTL_ASPMC))!= 0) {
|
||||
ctl &= ~(PCIEM_LINK_CTL_ECPM |
|
||||
PCIEM_LINK_CTL_ASPMC);
|
||||
pci_write_config(dev, sc->rl_expcap +
|
||||
PCIER_LINK_CTL, ctl, 2);
|
||||
device_printf(dev, "ASPM disabled\n");
|
||||
|
@ -1158,3 +1158,8 @@ struct rl_softc {
|
||||
/* US Robotics 997902 device ID */
|
||||
|
||||
#define USR_DEVICEID_997902 0x0116
|
||||
|
||||
/*
|
||||
* NCube vendor ID
|
||||
*/
|
||||
#define NCUBE_VENDORID 0x10FF
|
||||
|
@ -137,6 +137,7 @@ struct tsec_softc {
|
||||
int phyaddr;
|
||||
bus_space_tag_t phy_bst;
|
||||
bus_space_handle_t phy_bsh;
|
||||
int phy_regoff;
|
||||
};
|
||||
|
||||
/* interface to get/put generic objects */
|
||||
@ -260,9 +261,11 @@ extern struct mtx tsec_phy_mtx;
|
||||
#define TSEC_PHY_LOCK(sc) mtx_lock(&tsec_phy_mtx)
|
||||
#define TSEC_PHY_UNLOCK(sc) mtx_unlock(&tsec_phy_mtx)
|
||||
#define TSEC_PHY_READ(sc, reg) \
|
||||
bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, (reg))
|
||||
bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, \
|
||||
(reg) + (sc)->phy_regoff)
|
||||
#define TSEC_PHY_WRITE(sc, reg, val) \
|
||||
bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, (reg), (val))
|
||||
bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, \
|
||||
(reg) + (sc)->phy_regoff, (val))
|
||||
|
||||
/* Lock for transmitter */
|
||||
#define TSEC_TRANSMIT_LOCK(sc) do { \
|
||||
|
@ -100,10 +100,6 @@
|
||||
GINTSTS_WKUPINT | GINTSTS_USBSUSP | GINTMSK_OTGINTMSK | \
|
||||
GINTSTS_SESSREQINT)
|
||||
|
||||
#define DWC_OTG_PHY_ULPI 0
|
||||
#define DWC_OTG_PHY_HSIC 1
|
||||
#define DWC_OTG_PHY_INTERNAL 2
|
||||
|
||||
#ifndef DWC_OTG_PHY_DEFAULT
|
||||
#define DWC_OTG_PHY_DEFAULT DWC_OTG_PHY_ULPI
|
||||
#endif
|
||||
@ -112,10 +108,10 @@ static int dwc_otg_phy_type = DWC_OTG_PHY_DEFAULT;
|
||||
|
||||
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW, 0, "USB DWC OTG");
|
||||
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN,
|
||||
&dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2 - ULPI/HSIC/INTERNAL");
|
||||
&dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2/3 - ULPI/HSIC/INTERNAL/UTMI+");
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
static int dwc_otg_debug;
|
||||
static int dwc_otg_debug = 0;
|
||||
|
||||
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, debug, CTLFLAG_RWTUN,
|
||||
&dwc_otg_debug, 0, "DWC OTG debug level");
|
||||
@ -3891,8 +3887,13 @@ dwc_otg_init(struct dwc_otg_softc *sc)
|
||||
break;
|
||||
}
|
||||
|
||||
/* select HSIC, ULPI or internal PHY mode */
|
||||
switch (dwc_otg_phy_type) {
|
||||
if (sc->sc_phy_type == 0)
|
||||
sc->sc_phy_type = dwc_otg_phy_type + 1;
|
||||
if (sc->sc_phy_bits == 0)
|
||||
sc->sc_phy_bits = 16;
|
||||
|
||||
/* select HSIC, ULPI, UTMI+ or internal PHY mode */
|
||||
switch (sc->sc_phy_type) {
|
||||
case DWC_OTG_PHY_HSIC:
|
||||
DWC_OTG_WRITE_4(sc, DOTG_GUSBCFG,
|
||||
GUSBCFG_PHYIF |
|
||||
@ -3912,6 +3913,16 @@ dwc_otg_init(struct dwc_otg_softc *sc)
|
||||
GUSBCFG_TRD_TIM_SET(5) | temp);
|
||||
DWC_OTG_WRITE_4(sc, DOTG_GOTGCTL, 0);
|
||||
|
||||
temp = DWC_OTG_READ_4(sc, DOTG_GLPMCFG);
|
||||
DWC_OTG_WRITE_4(sc, DOTG_GLPMCFG,
|
||||
temp & ~GLPMCFG_HSIC_CONN);
|
||||
break;
|
||||
case DWC_OTG_PHY_UTMI:
|
||||
DWC_OTG_WRITE_4(sc, DOTG_GUSBCFG,
|
||||
(sc->sc_phy_bits == 16 ? GUSBCFG_PHYIF : 0) |
|
||||
GUSBCFG_TRD_TIM_SET(5) | temp);
|
||||
DWC_OTG_WRITE_4(sc, DOTG_GOTGCTL, 0);
|
||||
|
||||
temp = DWC_OTG_READ_4(sc, DOTG_GLPMCFG);
|
||||
DWC_OTG_WRITE_4(sc, DOTG_GLPMCFG,
|
||||
temp & ~GLPMCFG_HSIC_CONN);
|
||||
|
@ -191,6 +191,13 @@ struct dwc_otg_softc {
|
||||
uint16_t sc_active_rx_ep;
|
||||
uint16_t sc_last_frame_num;
|
||||
|
||||
uint8_t sc_phy_type;
|
||||
uint8_t sc_phy_bits;
|
||||
#define DWC_OTG_PHY_ULPI 1
|
||||
#define DWC_OTG_PHY_HSIC 2
|
||||
#define DWC_OTG_PHY_INTERNAL 3
|
||||
#define DWC_OTG_PHY_UTMI 4
|
||||
|
||||
uint8_t sc_timer_active;
|
||||
uint8_t sc_dev_ep_max;
|
||||
uint8_t sc_dev_in_ep_max;
|
||||
|
@ -661,7 +661,7 @@ usb_test_quirk_by_info(const struct usbd_lookup_info *info, uint16_t quirk)
|
||||
if (quirk == UQ_NONE)
|
||||
goto done;
|
||||
|
||||
mtx_lock(&usb_quirk_mtx);
|
||||
USB_MTX_LOCK(&usb_quirk_mtx);
|
||||
|
||||
for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) {
|
||||
/* see if quirk information does not match */
|
||||
@ -685,13 +685,13 @@ usb_test_quirk_by_info(const struct usbd_lookup_info *info, uint16_t quirk)
|
||||
/* lookup quirk */
|
||||
for (y = 0; y != USB_SUB_QUIRKS_MAX; y++) {
|
||||
if (usb_quirks[x].quirks[y] == quirk) {
|
||||
mtx_unlock(&usb_quirk_mtx);
|
||||
USB_MTX_UNLOCK(&usb_quirk_mtx);
|
||||
DPRINTF("Found quirk '%s'.\n", usb_quirkstr(quirk));
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
mtx_unlock(&usb_quirk_mtx);
|
||||
USB_MTX_UNLOCK(&usb_quirk_mtx);
|
||||
done:
|
||||
return (0); /* no quirk match */
|
||||
}
|
||||
@ -702,7 +702,7 @@ usb_quirk_get_entry(uint16_t vid, uint16_t pid,
|
||||
{
|
||||
uint16_t x;
|
||||
|
||||
mtx_assert(&usb_quirk_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(&usb_quirk_mtx, MA_OWNED);
|
||||
|
||||
if ((vid | pid | lo_rev | hi_rev) == 0) {
|
||||
/* all zero - special case */
|
||||
@ -770,7 +770,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
|
||||
if (y >= USB_DEV_QUIRKS_MAX) {
|
||||
return (EINVAL);
|
||||
}
|
||||
mtx_lock(&usb_quirk_mtx);
|
||||
USB_MTX_LOCK(&usb_quirk_mtx);
|
||||
/* copy out data */
|
||||
pgq->vid = usb_quirks[y].vid;
|
||||
pgq->pid = usb_quirks[y].pid;
|
||||
@ -779,7 +779,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
|
||||
strlcpy(pgq->quirkname,
|
||||
usb_quirkstr(usb_quirks[y].quirks[x]),
|
||||
sizeof(pgq->quirkname));
|
||||
mtx_unlock(&usb_quirk_mtx);
|
||||
USB_MTX_UNLOCK(&usb_quirk_mtx);
|
||||
return (0); /* success */
|
||||
|
||||
case USB_QUIRK_NAME_GET:
|
||||
@ -812,11 +812,11 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
|
||||
if (y == UQ_NONE) {
|
||||
return (EINVAL);
|
||||
}
|
||||
mtx_lock(&usb_quirk_mtx);
|
||||
USB_MTX_LOCK(&usb_quirk_mtx);
|
||||
pqe = usb_quirk_get_entry(pgq->vid, pgq->pid,
|
||||
pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 1);
|
||||
if (pqe == NULL) {
|
||||
mtx_unlock(&usb_quirk_mtx);
|
||||
USB_MTX_UNLOCK(&usb_quirk_mtx);
|
||||
return (EINVAL);
|
||||
}
|
||||
for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
|
||||
@ -825,7 +825,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
|
||||
break;
|
||||
}
|
||||
}
|
||||
mtx_unlock(&usb_quirk_mtx);
|
||||
USB_MTX_UNLOCK(&usb_quirk_mtx);
|
||||
if (x == USB_SUB_QUIRKS_MAX) {
|
||||
return (ENOMEM);
|
||||
}
|
||||
@ -850,11 +850,11 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
|
||||
if (y == UQ_NONE) {
|
||||
return (EINVAL);
|
||||
}
|
||||
mtx_lock(&usb_quirk_mtx);
|
||||
USB_MTX_LOCK(&usb_quirk_mtx);
|
||||
pqe = usb_quirk_get_entry(pgq->vid, pgq->pid,
|
||||
pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 0);
|
||||
if (pqe == NULL) {
|
||||
mtx_unlock(&usb_quirk_mtx);
|
||||
USB_MTX_UNLOCK(&usb_quirk_mtx);
|
||||
return (EINVAL);
|
||||
}
|
||||
for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
|
||||
@ -864,7 +864,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
|
||||
}
|
||||
}
|
||||
if (x == USB_SUB_QUIRKS_MAX) {
|
||||
mtx_unlock(&usb_quirk_mtx);
|
||||
USB_MTX_UNLOCK(&usb_quirk_mtx);
|
||||
return (ENOMEM);
|
||||
}
|
||||
for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
|
||||
@ -876,7 +876,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
|
||||
/* all quirk entries are unused - release */
|
||||
memset(pqe, 0, sizeof(*pqe));
|
||||
}
|
||||
mtx_unlock(&usb_quirk_mtx);
|
||||
USB_MTX_UNLOCK(&usb_quirk_mtx);
|
||||
return (0); /* success */
|
||||
|
||||
default:
|
||||
@ -967,14 +967,14 @@ usb_quirk_add_entry_from_str(const char *name, const char *env)
|
||||
printf("%s: Too many USB quirks, only %d allowed!\n",
|
||||
name, USB_SUB_QUIRKS_MAX);
|
||||
}
|
||||
mtx_lock(&usb_quirk_mtx);
|
||||
USB_MTX_LOCK(&usb_quirk_mtx);
|
||||
new = usb_quirk_get_entry(entry.vid, entry.pid,
|
||||
entry.lo_rev, entry.hi_rev, 1);
|
||||
if (new == NULL)
|
||||
printf("%s: USB quirks table is full!\n", name);
|
||||
else
|
||||
memcpy(new->quirks, entry.quirks, sizeof(entry.quirks));
|
||||
mtx_unlock(&usb_quirk_mtx);
|
||||
USB_MTX_UNLOCK(&usb_quirk_mtx);
|
||||
} else {
|
||||
printf("%s: No USB quirks found!\n", name);
|
||||
}
|
||||
|
@ -1149,7 +1149,7 @@ umass_cancel_ccb(struct umass_softc *sc)
|
||||
{
|
||||
union ccb *ccb;
|
||||
|
||||
mtx_assert(&sc->sc_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(&sc->sc_mtx, MA_OWNED);
|
||||
|
||||
ccb = sc->sc_transfer.ccb;
|
||||
sc->sc_transfer.ccb = NULL;
|
||||
|
@ -510,7 +510,7 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs,
|
||||
done:
|
||||
owned = mtx_owned(uptag->mtx);
|
||||
if (!owned)
|
||||
mtx_lock(uptag->mtx);
|
||||
USB_MTX_LOCK(uptag->mtx);
|
||||
|
||||
uptag->dma_error = (error ? 1 : 0);
|
||||
if (isload) {
|
||||
@ -519,7 +519,7 @@ done:
|
||||
cv_broadcast(uptag->cv);
|
||||
}
|
||||
if (!owned)
|
||||
mtx_unlock(uptag->mtx);
|
||||
USB_MTX_UNLOCK(uptag->mtx);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
@ -594,7 +594,7 @@ usb_pc_alloc_mem(struct usb_page_cache *pc, struct usb_page *pg,
|
||||
pc->tag = utag->tag;
|
||||
pc->ismultiseg = (align == 1);
|
||||
|
||||
mtx_lock(uptag->mtx);
|
||||
USB_MTX_LOCK(uptag->mtx);
|
||||
|
||||
/* load memory into DMA */
|
||||
err = bus_dmamap_load(
|
||||
@ -605,7 +605,7 @@ usb_pc_alloc_mem(struct usb_page_cache *pc, struct usb_page *pg,
|
||||
cv_wait(uptag->cv, uptag->mtx);
|
||||
err = 0;
|
||||
}
|
||||
mtx_unlock(uptag->mtx);
|
||||
USB_MTX_UNLOCK(uptag->mtx);
|
||||
|
||||
if (err || uptag->dma_error) {
|
||||
bus_dmamem_free(utag->tag, ptr, map);
|
||||
@ -661,7 +661,7 @@ usb_pc_load_mem(struct usb_page_cache *pc, usb_size_t size, uint8_t sync)
|
||||
pc->page_offset_end = size;
|
||||
pc->ismultiseg = 1;
|
||||
|
||||
mtx_assert(pc->tag_parent->mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(pc->tag_parent->mtx, MA_OWNED);
|
||||
|
||||
if (size > 0) {
|
||||
if (sync) {
|
||||
@ -919,7 +919,7 @@ usb_bdma_work_loop(struct usb_xfer_queue *pq)
|
||||
xfer = pq->curr;
|
||||
info = xfer->xroot;
|
||||
|
||||
mtx_assert(info->xfer_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(info->xfer_mtx, MA_OWNED);
|
||||
|
||||
if (xfer->error) {
|
||||
/* some error happened */
|
||||
@ -1043,7 +1043,7 @@ usb_bdma_done_event(struct usb_dma_parent_tag *udpt)
|
||||
|
||||
info = USB_DMATAG_TO_XROOT(udpt);
|
||||
|
||||
mtx_assert(info->xfer_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(info->xfer_mtx, MA_OWNED);
|
||||
|
||||
/* copy error */
|
||||
info->dma_error = udpt->dma_error;
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include <sys/callout.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kdb.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
@ -66,4 +68,16 @@ const struct usb_string_lang usb_string_lang_en = {
|
||||
MALLOC_DEFINE(M_USB, "USB", "USB");
|
||||
MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
|
||||
|
||||
int
|
||||
usbd_in_polling_mode(void)
|
||||
{
|
||||
return (USB_IN_POLLING_MODE_VALUE());
|
||||
}
|
||||
|
||||
void
|
||||
usbd_dummy_timeout(void *arg)
|
||||
{
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
MODULE_VERSION(usb, 1);
|
||||
|
@ -39,17 +39,20 @@
|
||||
USB_MODE_DEVICE ? (((xfer)->endpointno & UE_DIR_IN) ? 0 : 1) : \
|
||||
(((xfer)->endpointno & UE_DIR_IN) ? 1 : 0))
|
||||
|
||||
/* macros */
|
||||
/* locking wrappers for BUS lock */
|
||||
#define USB_BUS_LOCK(_b) USB_MTX_LOCK(&(_b)->bus_mtx)
|
||||
#define USB_BUS_UNLOCK(_b) USB_MTX_UNLOCK(&(_b)->bus_mtx)
|
||||
#define USB_BUS_LOCK_ASSERT(_b, _t) USB_MTX_ASSERT(&(_b)->bus_mtx, _t)
|
||||
|
||||
#define USB_BUS_LOCK(_b) mtx_lock(&(_b)->bus_mtx)
|
||||
#define USB_BUS_UNLOCK(_b) mtx_unlock(&(_b)->bus_mtx)
|
||||
#define USB_BUS_LOCK_ASSERT(_b, _t) mtx_assert(&(_b)->bus_mtx, _t)
|
||||
#define USB_BUS_SPIN_LOCK(_b) mtx_lock_spin(&(_b)->bus_spin_lock)
|
||||
#define USB_BUS_SPIN_UNLOCK(_b) mtx_unlock_spin(&(_b)->bus_spin_lock)
|
||||
#define USB_BUS_SPIN_LOCK_ASSERT(_b, _t) mtx_assert(&(_b)->bus_spin_lock, _t)
|
||||
#define USB_XFER_LOCK(_x) mtx_lock((_x)->xroot->xfer_mtx)
|
||||
#define USB_XFER_UNLOCK(_x) mtx_unlock((_x)->xroot->xfer_mtx)
|
||||
#define USB_XFER_LOCK_ASSERT(_x, _t) mtx_assert((_x)->xroot->xfer_mtx, _t)
|
||||
/* locking wrappers for BUS spin lock */
|
||||
#define USB_BUS_SPIN_LOCK(_b) USB_MTX_LOCK_SPIN(&(_b)->bus_spin_lock)
|
||||
#define USB_BUS_SPIN_UNLOCK(_b) USB_MTX_UNLOCK_SPIN(&(_b)->bus_spin_lock)
|
||||
#define USB_BUS_SPIN_LOCK_ASSERT(_b, _t) USB_MTX_ASSERT(&(_b)->bus_spin_lock, _t)
|
||||
|
||||
/* locking wrappers for XFER lock */
|
||||
#define USB_XFER_LOCK(_x) USB_MTX_LOCK((_x)->xroot->xfer_mtx)
|
||||
#define USB_XFER_UNLOCK(_x) USB_MTX_UNLOCK((_x)->xroot->xfer_mtx)
|
||||
#define USB_XFER_LOCK_ASSERT(_x, _t) USB_MTX_ASSERT((_x)->xroot->xfer_mtx, _t)
|
||||
|
||||
/* helper for converting pointers to integers */
|
||||
#define USB_P2U(ptr) \
|
||||
|
@ -1161,7 +1161,7 @@ usb_filter_write(struct knote *kn, long hint)
|
||||
|
||||
f = kn->kn_hook;
|
||||
|
||||
mtx_assert(f->priv_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
|
||||
|
||||
cpd = f->curr_cpd;
|
||||
if (cpd == NULL) {
|
||||
@ -1202,7 +1202,7 @@ usb_filter_read(struct knote *kn, long hint)
|
||||
|
||||
f = kn->kn_hook;
|
||||
|
||||
mtx_assert(f->priv_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
|
||||
|
||||
cpd = f->curr_cpd;
|
||||
if (cpd == NULL) {
|
||||
@ -1732,7 +1732,7 @@ usb_fifo_wait(struct usb_fifo *f)
|
||||
{
|
||||
int err;
|
||||
|
||||
mtx_assert(f->priv_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
|
||||
|
||||
if (f->flag_iserror) {
|
||||
/* we are gone */
|
||||
|
@ -1109,10 +1109,8 @@ usb_detach_device_sub(struct usb_device *udev, device_t *ppdev,
|
||||
device_printf(dev, "Resume failed\n");
|
||||
}
|
||||
}
|
||||
if (device_detach(dev)) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* detach and delete child */
|
||||
if (device_delete_child(udev->parent_dev, dev)) {
|
||||
goto error;
|
||||
}
|
||||
@ -1517,13 +1515,13 @@ usbd_clear_stall_proc(struct usb_proc_msg *_pm)
|
||||
|
||||
/* Change lock */
|
||||
USB_BUS_UNLOCK(udev->bus);
|
||||
mtx_lock(&udev->device_mtx);
|
||||
USB_MTX_LOCK(&udev->device_mtx);
|
||||
|
||||
/* Start clear stall callback */
|
||||
usbd_transfer_start(udev->ctrl_xfer[1]);
|
||||
|
||||
/* Change lock */
|
||||
mtx_unlock(&udev->device_mtx);
|
||||
USB_MTX_UNLOCK(&udev->device_mtx);
|
||||
USB_BUS_LOCK(udev->bus);
|
||||
}
|
||||
|
||||
@ -1591,6 +1589,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
|
||||
/* initialise our SX-lock */
|
||||
sx_init_flags(&udev->enum_sx, "USB config SX lock", SX_DUPOK);
|
||||
sx_init_flags(&udev->sr_sx, "USB suspend and resume SX lock", SX_NOWITNESS);
|
||||
sx_init_flags(&udev->ctrl_sx, "USB control transfer SX lock", SX_DUPOK);
|
||||
|
||||
cv_init(&udev->ctrlreq_cv, "WCTRL");
|
||||
cv_init(&udev->ref_cv, "UGONE");
|
||||
@ -1776,7 +1775,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
|
||||
*/
|
||||
|
||||
/* Protect scratch area */
|
||||
do_unlock = usbd_enum_lock(udev);
|
||||
do_unlock = usbd_ctrl_lock(udev);
|
||||
|
||||
scratch_ptr = udev->scratch.data;
|
||||
|
||||
@ -1827,7 +1826,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
|
||||
}
|
||||
|
||||
if (do_unlock)
|
||||
usbd_enum_unlock(udev);
|
||||
usbd_ctrl_unlock(udev);
|
||||
|
||||
/* assume 100mA bus powered for now. Changed when configured. */
|
||||
udev->power = USB_MIN_POWER;
|
||||
@ -1945,8 +1944,8 @@ config_done:
|
||||
udev->ugen_symlink = usb_alloc_symlink(udev->ugen_name);
|
||||
|
||||
/* Announce device */
|
||||
printf("%s: <%s> at %s\n", udev->ugen_name,
|
||||
usb_get_manufacturer(udev),
|
||||
printf("%s: <%s %s> at %s\n", udev->ugen_name,
|
||||
usb_get_manufacturer(udev), usb_get_product(udev),
|
||||
device_get_nameunit(udev->bus->bdev));
|
||||
#endif
|
||||
|
||||
@ -2155,8 +2154,9 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
|
||||
|
||||
#if USB_HAVE_UGEN
|
||||
if (!rebooting) {
|
||||
printf("%s: <%s> at %s (disconnected)\n", udev->ugen_name,
|
||||
usb_get_manufacturer(udev), device_get_nameunit(bus->bdev));
|
||||
printf("%s: <%s %s> at %s (disconnected)\n", udev->ugen_name,
|
||||
usb_get_manufacturer(udev), usb_get_product(udev),
|
||||
device_get_nameunit(bus->bdev));
|
||||
}
|
||||
|
||||
/* Destroy UGEN symlink, if any */
|
||||
@ -2201,6 +2201,7 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
|
||||
|
||||
sx_destroy(&udev->enum_sx);
|
||||
sx_destroy(&udev->sr_sx);
|
||||
sx_destroy(&udev->ctrl_sx);
|
||||
|
||||
cv_destroy(&udev->ctrlreq_cv);
|
||||
cv_destroy(&udev->ref_cv);
|
||||
@ -2364,7 +2365,7 @@ usbd_set_device_strings(struct usb_device *udev)
|
||||
uint8_t do_unlock;
|
||||
|
||||
/* Protect scratch area */
|
||||
do_unlock = usbd_enum_lock(udev);
|
||||
do_unlock = usbd_ctrl_lock(udev);
|
||||
|
||||
temp_ptr = (char *)udev->scratch.data;
|
||||
temp_size = sizeof(udev->scratch.data);
|
||||
@ -2424,7 +2425,7 @@ usbd_set_device_strings(struct usb_device *udev)
|
||||
}
|
||||
|
||||
if (do_unlock)
|
||||
usbd_enum_unlock(udev);
|
||||
usbd_ctrl_unlock(udev);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2830,6 +2831,40 @@ usbd_enum_is_locked(struct usb_device *udev)
|
||||
return (sx_xlocked(&udev->enum_sx));
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function is used to serialize access to USB control
|
||||
* transfers and the USB scratch area. If the lock is already grabbed
|
||||
* this function returns zero. Else a value of one is returned.
|
||||
*/
|
||||
uint8_t
|
||||
usbd_ctrl_lock(struct usb_device *udev)
|
||||
{
|
||||
if (sx_xlocked(&udev->ctrl_sx))
|
||||
return (0);
|
||||
sx_xlock(&udev->ctrl_sx);
|
||||
|
||||
/*
|
||||
* We need to allow suspend and resume at this point, else the
|
||||
* control transfer will timeout if the device is suspended!
|
||||
*/
|
||||
if (usbd_enum_is_locked(udev))
|
||||
usbd_sr_unlock(udev);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
usbd_ctrl_unlock(struct usb_device *udev)
|
||||
{
|
||||
sx_xunlock(&udev->ctrl_sx);
|
||||
|
||||
/*
|
||||
* Restore the suspend and resume lock after we have unlocked
|
||||
* the USB control transfer lock to avoid LOR:
|
||||
*/
|
||||
if (usbd_enum_is_locked(udev))
|
||||
usbd_sr_lock(udev);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function is used to set the per-interface specific
|
||||
* plug and play information. The string referred to by the pnpinfo
|
||||
|
@ -162,7 +162,7 @@ struct usb_temp_setup {
|
||||
|
||||
/*
|
||||
* The scratch area for USB devices. Access to this structure is
|
||||
* protected by the enumeration SX lock.
|
||||
* protected by the control SX lock.
|
||||
*/
|
||||
union usb_device_scratch {
|
||||
struct usb_hw_ep_scratch hw_ep_scratch[1];
|
||||
@ -183,6 +183,7 @@ struct usb_device {
|
||||
struct usb_udev_msg cs_msg[2];
|
||||
struct sx enum_sx;
|
||||
struct sx sr_sx;
|
||||
struct sx ctrl_sx;
|
||||
struct mtx device_mtx;
|
||||
struct cv ctrlreq_cv;
|
||||
struct cv ref_cv;
|
||||
@ -320,6 +321,8 @@ uint8_t usbd_enum_lock_sig(struct usb_device *);
|
||||
void usbd_enum_unlock(struct usb_device *);
|
||||
void usbd_sr_lock(struct usb_device *);
|
||||
void usbd_sr_unlock(struct usb_device *);
|
||||
uint8_t usbd_ctrl_lock(struct usb_device *);
|
||||
void usbd_ctrl_unlock(struct usb_device *);
|
||||
uint8_t usbd_enum_is_locked(struct usb_device *);
|
||||
|
||||
#if USB_HAVE_TT_SUPPORT
|
||||
|
@ -92,6 +92,9 @@
|
||||
|
||||
#define USB_MAX_AUTO_QUIRK 8 /* maximum number of dynamic quirks */
|
||||
|
||||
#define USB_IN_POLLING_MODE_FUNC() usbd_in_polling_mode()
|
||||
#define USB_IN_POLLING_MODE_VALUE() (SCHEDULER_STOPPED() || kdb_active)
|
||||
|
||||
typedef uint32_t usb_timeout_t; /* milliseconds */
|
||||
typedef uint32_t usb_frlength_t; /* bytes */
|
||||
typedef uint32_t usb_frcount_t; /* units */
|
||||
|
@ -238,7 +238,7 @@ ugen_open_pipe_write(struct usb_fifo *f)
|
||||
struct usb_endpoint *ep = usb_fifo_softc(f);
|
||||
struct usb_endpoint_descriptor *ed = ep->edesc;
|
||||
|
||||
mtx_assert(f->priv_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
|
||||
|
||||
if (f->xfer[0] || f->xfer[1]) {
|
||||
/* transfers are already opened */
|
||||
@ -307,7 +307,7 @@ ugen_open_pipe_read(struct usb_fifo *f)
|
||||
struct usb_endpoint *ep = usb_fifo_softc(f);
|
||||
struct usb_endpoint_descriptor *ed = ep->edesc;
|
||||
|
||||
mtx_assert(f->priv_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
|
||||
|
||||
if (f->xfer[0] || f->xfer[1]) {
|
||||
/* transfers are already opened */
|
||||
@ -716,16 +716,16 @@ ugen_get_cdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called having the enumeration SX locked which
|
||||
* protects the scratch area used.
|
||||
*/
|
||||
static int
|
||||
ugen_get_sdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
|
||||
{
|
||||
void *ptr;
|
||||
uint16_t size;
|
||||
int error;
|
||||
uint8_t do_unlock;
|
||||
|
||||
/* Protect scratch area */
|
||||
do_unlock = usbd_ctrl_lock(f->udev);
|
||||
|
||||
ptr = f->udev->scratch.data;
|
||||
size = sizeof(f->udev->scratch.data);
|
||||
@ -746,6 +746,9 @@ ugen_get_sdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
|
||||
|
||||
error = copyout(ptr, ugd->ugd_data, size);
|
||||
}
|
||||
if (do_unlock)
|
||||
usbd_ctrl_unlock(f->udev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -272,11 +272,11 @@ uhub_reset_tt_proc(struct usb_proc_msg *_pm)
|
||||
|
||||
/* Change lock */
|
||||
USB_BUS_UNLOCK(udev->bus);
|
||||
mtx_lock(&sc->sc_mtx);
|
||||
USB_MTX_LOCK(&sc->sc_mtx);
|
||||
/* Start transfer */
|
||||
usbd_transfer_start(sc->sc_xfer[UHUB_RESET_TT_TRANSFER]);
|
||||
/* Change lock */
|
||||
mtx_unlock(&sc->sc_mtx);
|
||||
USB_MTX_UNLOCK(&sc->sc_mtx);
|
||||
USB_BUS_LOCK(udev->bus);
|
||||
}
|
||||
#endif
|
||||
@ -1521,9 +1521,9 @@ uhub_attach(device_t dev)
|
||||
|
||||
/* Start the interrupt endpoint, if any */
|
||||
|
||||
mtx_lock(&sc->sc_mtx);
|
||||
USB_MTX_LOCK(&sc->sc_mtx);
|
||||
usbd_transfer_start(sc->sc_xfer[UHUB_INTR_TRANSFER]);
|
||||
mtx_unlock(&sc->sc_mtx);
|
||||
USB_MTX_UNLOCK(&sc->sc_mtx);
|
||||
|
||||
/* Enable automatic power save on all USB HUBs */
|
||||
|
||||
|
@ -553,13 +553,13 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
|
||||
memcpy(&sc->cbw->CBWCDB, cmd_ptr, cmd_len);
|
||||
DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw->CBWCDB, ":");
|
||||
|
||||
mtx_lock(&sc->mtx);
|
||||
USB_MTX_LOCK(&sc->mtx);
|
||||
usbd_transfer_start(sc->xfer[sc->state]);
|
||||
|
||||
while (usbd_transfer_pending(sc->xfer[sc->state])) {
|
||||
cv_wait(&sc->cv, &sc->mtx);
|
||||
}
|
||||
mtx_unlock(&sc->mtx);
|
||||
USB_MTX_UNLOCK(&sc->mtx);
|
||||
return (sc->error);
|
||||
}
|
||||
|
||||
@ -584,11 +584,11 @@ bbb_raw_write(struct bbb_transfer *sc, const void *data_ptr, size_t data_len,
|
||||
DPRINTFN(1, "BULK DATA = %*D\n", (int)data_len,
|
||||
(const char *)data_ptr, ":");
|
||||
|
||||
mtx_lock(&sc->mtx);
|
||||
USB_MTX_LOCK(&sc->mtx);
|
||||
usbd_transfer_start(sc->xfer[0]);
|
||||
while (usbd_transfer_pending(sc->xfer[0]))
|
||||
cv_wait(&sc->cv, &sc->mtx);
|
||||
mtx_unlock(&sc->mtx);
|
||||
USB_MTX_UNLOCK(&sc->mtx);
|
||||
return (sc->error);
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ usb_process(void *arg)
|
||||
thread_unlock(td);
|
||||
#endif /* __rtems__ */
|
||||
|
||||
mtx_lock(up->up_mtx);
|
||||
USB_MTX_LOCK(up->up_mtx);
|
||||
|
||||
up->up_curtd = td;
|
||||
|
||||
@ -190,7 +190,7 @@ usb_process(void *arg)
|
||||
|
||||
continue;
|
||||
}
|
||||
/* end if messages - check if anyone is waiting for sync */
|
||||
/* end of messages - check if anyone is waiting for sync */
|
||||
if (up->up_dsleep) {
|
||||
up->up_dsleep = 0;
|
||||
cv_broadcast(&up->up_drain);
|
||||
@ -201,7 +201,7 @@ usb_process(void *arg)
|
||||
|
||||
up->up_ptr = NULL;
|
||||
cv_signal(&up->up_cv);
|
||||
mtx_unlock(up->up_mtx);
|
||||
USB_MTX_UNLOCK(up->up_mtx);
|
||||
#if (__FreeBSD_version >= 800000)
|
||||
/* Clear the proc pointer if this is the last thread. */
|
||||
if (--usb_pcount == 0)
|
||||
@ -297,11 +297,12 @@ usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
|
||||
usb_size_t d;
|
||||
uint8_t t;
|
||||
|
||||
/* check if gone, return dummy value */
|
||||
if (up->up_gone)
|
||||
/* check if gone or in polling mode, return dummy value */
|
||||
if (up->up_gone != 0 ||
|
||||
USB_IN_POLLING_MODE_FUNC() != 0)
|
||||
return (_pm0);
|
||||
|
||||
mtx_assert(up->up_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
|
||||
|
||||
t = 0;
|
||||
|
||||
@ -382,7 +383,7 @@ usb_proc_is_gone(struct usb_process *up)
|
||||
* structure is initialised.
|
||||
*/
|
||||
if (up->up_mtx != NULL)
|
||||
mtx_assert(up->up_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -403,7 +404,7 @@ usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
|
||||
if (up->up_gone)
|
||||
return;
|
||||
|
||||
mtx_assert(up->up_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
|
||||
|
||||
if (up->up_curtd == curthread) {
|
||||
/* Just remove the messages from the queue. */
|
||||
@ -443,9 +444,9 @@ usb_proc_drain(struct usb_process *up)
|
||||
return;
|
||||
/* handle special case with Giant */
|
||||
if (up->up_mtx != &Giant)
|
||||
mtx_assert(up->up_mtx, MA_NOTOWNED);
|
||||
USB_MTX_ASSERT(up->up_mtx, MA_NOTOWNED);
|
||||
|
||||
mtx_lock(up->up_mtx);
|
||||
USB_MTX_LOCK(up->up_mtx);
|
||||
|
||||
/* Set the gone flag */
|
||||
|
||||
@ -482,7 +483,7 @@ usb_proc_drain(struct usb_process *up)
|
||||
DPRINTF("WARNING: Someone is waiting "
|
||||
"for USB process drain!\n");
|
||||
}
|
||||
mtx_unlock(up->up_mtx);
|
||||
USB_MTX_UNLOCK(up->up_mtx);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
@ -503,7 +504,7 @@ usb_proc_rewakeup(struct usb_process *up)
|
||||
if (up->up_gone)
|
||||
return;
|
||||
|
||||
mtx_assert(up->up_mtx, MA_OWNED);
|
||||
USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
|
||||
|
||||
if (up->up_msleep == 0) {
|
||||
/* re-wakeup */
|
||||
|
@ -457,21 +457,14 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
|
||||
return (USB_ERR_INVAL);
|
||||
#endif
|
||||
if ((mtx != NULL) && (mtx != &Giant)) {
|
||||
mtx_unlock(mtx);
|
||||
mtx_assert(mtx, MA_NOTOWNED);
|
||||
USB_MTX_UNLOCK(mtx);
|
||||
USB_MTX_ASSERT(mtx, MA_NOTOWNED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Grab the USB device enumeration SX-lock serialization is
|
||||
* achieved when multiple threads are involved:
|
||||
* Serialize access to this function:
|
||||
*/
|
||||
do_unlock = usbd_enum_lock(udev);
|
||||
|
||||
/*
|
||||
* We need to allow suspend and resume at this point, else the
|
||||
* control transfer will timeout if the device is suspended!
|
||||
*/
|
||||
usbd_sr_unlock(udev);
|
||||
do_unlock = usbd_ctrl_lock(udev);
|
||||
|
||||
hr_func = usbd_get_hr_func(udev);
|
||||
|
||||
@ -715,13 +708,11 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
|
||||
USB_XFER_UNLOCK(xfer);
|
||||
|
||||
done:
|
||||
usbd_sr_lock(udev);
|
||||
|
||||
if (do_unlock)
|
||||
usbd_enum_unlock(udev);
|
||||
usbd_ctrl_unlock(udev);
|
||||
|
||||
if ((mtx != NULL) && (mtx != &Giant))
|
||||
mtx_lock(mtx);
|
||||
USB_MTX_LOCK(mtx);
|
||||
|
||||
switch (err) {
|
||||
case USB_ERR_NORMAL_COMPLETION:
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include <sys/callout.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
@ -341,12 +340,12 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm,
|
||||
pc->buffer = USB_ADD_BYTES(buf, y * size);
|
||||
pc->page_start = pg;
|
||||
|
||||
mtx_lock(pc->tag_parent->mtx);
|
||||
USB_MTX_LOCK(pc->tag_parent->mtx);
|
||||
if (usb_pc_load_mem(pc, size, 1 /* synchronous */ )) {
|
||||
mtx_unlock(pc->tag_parent->mtx);
|
||||
USB_MTX_UNLOCK(pc->tag_parent->mtx);
|
||||
return (1); /* failure */
|
||||
}
|
||||
mtx_unlock(pc->tag_parent->mtx);
|
||||
USB_MTX_UNLOCK(pc->tag_parent->mtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -983,7 +982,7 @@ usbd_transfer_setup(struct usb_device *udev,
|
||||
return (error);
|
||||
|
||||
/* Protect scratch area */
|
||||
do_unlock = usbd_enum_lock(udev);
|
||||
do_unlock = usbd_ctrl_lock(udev);
|
||||
|
||||
refcount = 0;
|
||||
info = NULL;
|
||||
@ -1304,7 +1303,7 @@ done:
|
||||
error = parm->err;
|
||||
|
||||
if (do_unlock)
|
||||
usbd_enum_unlock(udev);
|
||||
usbd_ctrl_unlock(udev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
@ -2292,14 +2291,14 @@ usb_callback_proc(struct usb_proc_msg *_pm)
|
||||
* We exploit the fact that the mutex is the same for all
|
||||
* callbacks that will be called from this thread:
|
||||
*/
|
||||
mtx_lock(info->xfer_mtx);
|
||||
USB_MTX_LOCK(info->xfer_mtx);
|
||||
USB_BUS_LOCK(info->bus);
|
||||
|
||||
/* Continue where we lost track */
|
||||
usb_command_wrapper(&info->done_q,
|
||||
info->done_q.curr);
|
||||
|
||||
mtx_unlock(info->xfer_mtx);
|
||||
USB_MTX_UNLOCK(info->xfer_mtx);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
@ -2352,7 +2351,7 @@ usbd_callback_wrapper(struct usb_xfer_queue *pq)
|
||||
|
||||
USB_BUS_LOCK_ASSERT(info->bus, MA_OWNED);
|
||||
if ((pq->recurse_3 != 0 || mtx_owned(info->xfer_mtx) == 0) &&
|
||||
SCHEDULER_STOPPED() == 0) {
|
||||
USB_IN_POLLING_MODE_FUNC() == 0) {
|
||||
/*
|
||||
* Cases that end up here:
|
||||
*
|
||||
@ -3333,7 +3332,9 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
|
||||
struct usb_xfer_root *xroot;
|
||||
struct usb_device *udev;
|
||||
struct usb_proc_msg *pm;
|
||||
struct usb_bus *bus;
|
||||
uint16_t n;
|
||||
uint16_t drop_bus_spin;
|
||||
uint16_t drop_bus;
|
||||
uint16_t drop_xfer;
|
||||
|
||||
@ -3348,38 +3349,47 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
|
||||
udev = xroot->udev;
|
||||
if (udev == NULL)
|
||||
continue; /* no USB device */
|
||||
if (udev->bus == NULL)
|
||||
bus = udev->bus;
|
||||
if (bus == NULL)
|
||||
continue; /* no BUS structure */
|
||||
if (udev->bus->methods == NULL)
|
||||
if (bus->methods == NULL)
|
||||
continue; /* no BUS methods */
|
||||
if (udev->bus->methods->xfer_poll == NULL)
|
||||
if (bus->methods->xfer_poll == NULL)
|
||||
continue; /* no poll method */
|
||||
|
||||
/* make sure that the BUS mutex is not locked */
|
||||
drop_bus_spin = 0;
|
||||
drop_bus = 0;
|
||||
while (mtx_owned(&xroot->udev->bus->bus_mtx) && !SCHEDULER_STOPPED()) {
|
||||
mtx_unlock(&xroot->udev->bus->bus_mtx);
|
||||
drop_bus++;
|
||||
}
|
||||
|
||||
/* make sure that the transfer mutex is not locked */
|
||||
drop_xfer = 0;
|
||||
while (mtx_owned(xroot->xfer_mtx) && !SCHEDULER_STOPPED()) {
|
||||
mtx_unlock(xroot->xfer_mtx);
|
||||
drop_xfer++;
|
||||
|
||||
if (USB_IN_POLLING_MODE_FUNC() == 0) {
|
||||
/* make sure that the BUS spin mutex is not locked */
|
||||
while (mtx_owned(&bus->bus_spin_lock)) {
|
||||
mtx_unlock_spin(&bus->bus_spin_lock);
|
||||
drop_bus_spin++;
|
||||
}
|
||||
|
||||
/* make sure that the BUS mutex is not locked */
|
||||
while (mtx_owned(&bus->bus_mtx)) {
|
||||
mtx_unlock(&bus->bus_mtx);
|
||||
drop_bus++;
|
||||
}
|
||||
|
||||
/* make sure that the transfer mutex is not locked */
|
||||
while (mtx_owned(xroot->xfer_mtx)) {
|
||||
mtx_unlock(xroot->xfer_mtx);
|
||||
drop_xfer++;
|
||||
}
|
||||
}
|
||||
|
||||
#if USB_HAVE_PER_BUS_PROCESS
|
||||
/* Make sure cv_signal() and cv_broadcast() is not called */
|
||||
USB_BUS_CONTROL_XFER_PROC(udev->bus)->up_msleep = 0;
|
||||
USB_BUS_EXPLORE_PROC(udev->bus)->up_msleep = 0;
|
||||
USB_BUS_GIANT_PROC(udev->bus)->up_msleep = 0;
|
||||
USB_BUS_NON_GIANT_ISOC_PROC(udev->bus)->up_msleep = 0;
|
||||
USB_BUS_NON_GIANT_BULK_PROC(udev->bus)->up_msleep = 0;
|
||||
#endif
|
||||
USB_BUS_CONTROL_XFER_PROC(bus)->up_msleep = 0;
|
||||
USB_BUS_EXPLORE_PROC(bus)->up_msleep = 0;
|
||||
USB_BUS_GIANT_PROC(bus)->up_msleep = 0;
|
||||
USB_BUS_NON_GIANT_ISOC_PROC(bus)->up_msleep = 0;
|
||||
USB_BUS_NON_GIANT_BULK_PROC(bus)->up_msleep = 0;
|
||||
|
||||
/* poll USB hardware */
|
||||
(udev->bus->methods->xfer_poll) (udev->bus);
|
||||
(bus->methods->xfer_poll) (bus);
|
||||
|
||||
USB_BUS_LOCK(xroot->bus);
|
||||
|
||||
@ -3407,7 +3417,11 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
|
||||
|
||||
/* restore BUS mutex */
|
||||
while (drop_bus--)
|
||||
mtx_lock(&xroot->udev->bus->bus_mtx);
|
||||
mtx_lock(&bus->bus_mtx);
|
||||
|
||||
/* restore BUS spin mutex */
|
||||
while (drop_bus_spin--)
|
||||
mtx_lock_spin(&bus->bus_spin_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ device_set_usb_desc(device_t dev)
|
||||
}
|
||||
|
||||
/* Protect scratch area */
|
||||
do_unlock = usbd_enum_lock(udev);
|
||||
do_unlock = usbd_ctrl_lock(udev);
|
||||
|
||||
temp_p = (char *)udev->scratch.data;
|
||||
|
||||
@ -117,7 +117,7 @@ device_set_usb_desc(device_t dev)
|
||||
}
|
||||
|
||||
if (do_unlock)
|
||||
usbd_enum_unlock(udev);
|
||||
usbd_ctrl_unlock(udev);
|
||||
|
||||
device_set_desc_copy(dev, temp_p);
|
||||
device_printf(dev, "<%s> on %s\n", temp_p,
|
||||
|
@ -434,6 +434,39 @@ struct usb_attach_arg {
|
||||
#define UAA_DEV_EJECTING 2
|
||||
};
|
||||
|
||||
/*
|
||||
* General purpose locking wrappers to ease supporting
|
||||
* USB polled mode:
|
||||
*/
|
||||
#ifdef INVARIANTS
|
||||
#define USB_MTX_ASSERT(_m, _t) do { \
|
||||
if (!USB_IN_POLLING_MODE_FUNC()) \
|
||||
mtx_assert(_m, _t); \
|
||||
} while (0)
|
||||
#else
|
||||
#define USB_MTX_ASSERT(_m, _t) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define USB_MTX_LOCK(_m) do { \
|
||||
if (!USB_IN_POLLING_MODE_FUNC()) \
|
||||
mtx_lock(_m); \
|
||||
} while (0)
|
||||
|
||||
#define USB_MTX_UNLOCK(_m) do { \
|
||||
if (!USB_IN_POLLING_MODE_FUNC()) \
|
||||
mtx_unlock(_m); \
|
||||
} while (0)
|
||||
|
||||
#define USB_MTX_LOCK_SPIN(_m) do { \
|
||||
if (!USB_IN_POLLING_MODE_FUNC()) \
|
||||
mtx_lock_spin(_m); \
|
||||
} while (0)
|
||||
|
||||
#define USB_MTX_UNLOCK_SPIN(_m) do { \
|
||||
if (!USB_IN_POLLING_MODE_FUNC()) \
|
||||
mtx_unlock_spin(_m); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* The following is a wrapper for the callout structure to ease
|
||||
* porting the code to other platforms.
|
||||
@ -442,8 +475,26 @@ struct usb_callout {
|
||||
struct callout co;
|
||||
};
|
||||
#define usb_callout_init_mtx(c,m,f) callout_init_mtx(&(c)->co,m,f)
|
||||
#define usb_callout_reset(c,t,f,d) callout_reset(&(c)->co,t,f,d)
|
||||
#define usb_callout_stop(c) callout_stop(&(c)->co)
|
||||
#define usb_callout_reset(c,...) do { \
|
||||
if (!USB_IN_POLLING_MODE_FUNC()) \
|
||||
callout_reset(&(c)->co, __VA_ARGS__); \
|
||||
} while (0)
|
||||
#define usb_callout_reset_sbt(c,...) do { \
|
||||
if (!USB_IN_POLLING_MODE_FUNC()) \
|
||||
callout_reset_sbt(&(c)->co, __VA_ARGS__); \
|
||||
} while (0)
|
||||
#define usb_callout_stop(c) do { \
|
||||
if (!USB_IN_POLLING_MODE_FUNC()) { \
|
||||
callout_stop(&(c)->co); \
|
||||
} else { \
|
||||
/* \
|
||||
* Cannot stop callout when \
|
||||
* polling. Set dummy callback \
|
||||
* function instead: \
|
||||
*/ \
|
||||
(c)->co.c_func = &usbd_dummy_timeout; \
|
||||
} \
|
||||
} while (0)
|
||||
#define usb_callout_drain(c) callout_drain(&(c)->co)
|
||||
#define usb_callout_pending(c) callout_pending(&(c)->co)
|
||||
|
||||
@ -623,6 +674,8 @@ void usbd_frame_zero(struct usb_page_cache *cache, usb_frlength_t offset,
|
||||
void usbd_start_re_enumerate(struct usb_device *udev);
|
||||
usb_error_t
|
||||
usbd_start_set_config(struct usb_device *, uint8_t);
|
||||
int usbd_in_polling_mode(void);
|
||||
void usbd_dummy_timeout(void *);
|
||||
|
||||
int usb_fifo_attach(struct usb_device *udev, void *priv_sc,
|
||||
struct mtx *priv_mtx, struct usb_fifo_methods *pm,
|
||||
|
@ -65,6 +65,7 @@ void i686_pagezero(void *addr);
|
||||
void sse2_pagezero(void *addr);
|
||||
void init_AMD_Elan_sc520(void);
|
||||
vm_paddr_t kvtop(void *addr);
|
||||
void panicifcpuunsupported(void);
|
||||
void ppro_reenable_apic(void);
|
||||
void setidt(int idx, alias_for_inthand_t *func, int typ, int dpl, int selec);
|
||||
union savefpu *get_pcb_user_save_td(struct thread *td);
|
||||
|
@ -215,9 +215,9 @@ void
|
||||
mi_startup(void)
|
||||
{
|
||||
|
||||
register struct sysinit **sipp; /* system initialization*/
|
||||
register struct sysinit **xipp; /* interior loop of sort*/
|
||||
register struct sysinit *save; /* bubble*/
|
||||
struct sysinit **sipp; /* system initialization*/
|
||||
struct sysinit **xipp; /* interior loop of sort*/
|
||||
struct sysinit *save; /* bubble*/
|
||||
#ifdef __rtems__
|
||||
struct sysinit **sysinit = NULL;
|
||||
struct sysinit **sysinit_end = NULL;
|
||||
@ -339,16 +339,7 @@ restart:
|
||||
#endif /* __rtems__ */
|
||||
}
|
||||
|
||||
|
||||
#ifndef __rtems__
|
||||
/*
|
||||
***************************************************************************
|
||||
****
|
||||
**** The following SYSINIT's belong elsewhere, but have not yet
|
||||
**** been moved.
|
||||
****
|
||||
***************************************************************************
|
||||
*/
|
||||
static void
|
||||
print_caddr_t(void *data)
|
||||
{
|
||||
@ -442,17 +433,10 @@ struct sysentvec null_sysvec = {
|
||||
};
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
****
|
||||
**** The two following SYSINIT's are proc0 specific glue code. I am not
|
||||
**** convinced that they can not be safely combined, but their order of
|
||||
**** operation has been maintained as the same as the original init_main.c
|
||||
**** for right now.
|
||||
****
|
||||
**** These probably belong in init_proc.c or kern_proc.c, since they
|
||||
**** deal with proc0 (the fork template process).
|
||||
****
|
||||
***************************************************************************
|
||||
* The two following SYSINIT's are proc0 specific glue code. I am not
|
||||
* convinced that they can not be safely combined, but their order of
|
||||
* operation has been maintained as the same as the original init_main.c
|
||||
* for right now.
|
||||
*/
|
||||
/* ARGSUSED*/
|
||||
static void
|
||||
@ -686,16 +670,6 @@ SYSINIT(random, SI_SUB_RANDOM, SI_ORDER_FIRST, random_init, NULL);
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
****
|
||||
**** The following code probably belongs in another file, like
|
||||
**** kern/init_init.c.
|
||||
****
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* List of paths to try when searching for "init".
|
||||
*/
|
||||
@ -843,7 +817,7 @@ start_init(void *dummy)
|
||||
}
|
||||
|
||||
/*
|
||||
* Like kproc_create(), but runs in it's own address space.
|
||||
* Like kproc_create(), but runs in its own address space.
|
||||
* We do this early to reserve pid 1.
|
||||
*
|
||||
* Note special case - do not make it runnable yet. Other work
|
||||
|
@ -407,6 +407,8 @@ cv_signal(struct cv *cvp)
|
||||
{
|
||||
int wakeup_swapper;
|
||||
|
||||
if (cvp->cv_waiters == 0)
|
||||
return;
|
||||
wakeup_swapper = 0;
|
||||
sleepq_lock(cvp);
|
||||
if (cvp->cv_waiters > 0) {
|
||||
@ -434,6 +436,8 @@ cv_broadcastpri(struct cv *cvp, int pri)
|
||||
{
|
||||
int wakeup_swapper;
|
||||
|
||||
if (cvp->cv_waiters == 0)
|
||||
return;
|
||||
/*
|
||||
* XXX sleepq_broadcast pri argument changed from -1 meaning
|
||||
* no pri to 0 meaning no pri.
|
||||
|
@ -1615,7 +1615,6 @@ restart:
|
||||
if (error)
|
||||
panic("cannot add dependency");
|
||||
}
|
||||
lf->userrefs++; /* so we can (try to) kldunload it */
|
||||
error = linker_file_lookup_set(lf, MDT_SETNAME, &start,
|
||||
&stop, NULL);
|
||||
if (!error) {
|
||||
@ -1653,6 +1652,8 @@ restart:
|
||||
goto fail;
|
||||
}
|
||||
linker_file_register_modules(lf);
|
||||
if (!TAILQ_EMPTY(&lf->modules))
|
||||
lf->flags |= LINKER_FILE_MODULES;
|
||||
if (linker_file_lookup_set(lf, "sysinit_set", &si_start,
|
||||
&si_stop, NULL) == 0)
|
||||
sysinit_add(si_start, si_stop);
|
||||
@ -1669,6 +1670,41 @@ fail:
|
||||
|
||||
SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0);
|
||||
|
||||
/*
|
||||
* Handle preload files that failed to load any modules.
|
||||
*/
|
||||
static void
|
||||
linker_preload_finish(void *arg)
|
||||
{
|
||||
linker_file_t lf, nlf;
|
||||
|
||||
sx_xlock(&kld_sx);
|
||||
TAILQ_FOREACH_SAFE(lf, &linker_files, link, nlf) {
|
||||
/*
|
||||
* If all of the modules in this file failed to load, unload
|
||||
* the file and return an error of ENOEXEC. (Parity with
|
||||
* linker_load_file.)
|
||||
*/
|
||||
if ((lf->flags & LINKER_FILE_MODULES) != 0 &&
|
||||
TAILQ_EMPTY(&lf->modules)) {
|
||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
|
||||
continue;
|
||||
}
|
||||
|
||||
lf->flags &= ~LINKER_FILE_MODULES;
|
||||
lf->userrefs++; /* so we can (try to) kldunload it */
|
||||
}
|
||||
sx_xunlock(&kld_sx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to run after all DECLARE_MODULE SYSINITs. Unfortunately they can be
|
||||
* scheduled at any subsystem and order, so run this as late as possible. init
|
||||
* becomes runnable in SI_SUB_KTHREAD_INIT, so go slightly before that.
|
||||
*/
|
||||
SYSINIT(preload_finish, SI_SUB_KTHREAD_INIT - 100, SI_ORDER_MIDDLE,
|
||||
linker_preload_finish, 0);
|
||||
|
||||
/*
|
||||
* Search for a not-loaded module by name.
|
||||
*
|
||||
|
@ -18,7 +18,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -144,9 +144,12 @@ SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD|CTLFLAG_CAPRD,
|
||||
|
||||
char kernelname[MAXPATHLEN] = "/kernel"; /* XXX bloat */
|
||||
|
||||
SYSCTL_STRING(_kern, KERN_BOOTFILE, bootfile, CTLFLAG_RW,
|
||||
SYSCTL_STRING(_kern, KERN_BOOTFILE, bootfile, CTLFLAG_RW | CTLFLAG_MPSAFE,
|
||||
kernelname, sizeof kernelname, "Name of kernel file booted");
|
||||
|
||||
SYSCTL_INT(_kern, KERN_MAXPHYS, maxphys, CTLFLAG_RD | CTLFLAG_CAPRD,
|
||||
SYSCTL_NULL_INT_PTR, MAXPHYS, "Maximum block I/O access size");
|
||||
|
||||
SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD|CTLFLAG_CAPRD,
|
||||
&mp_ncpus, 0, "Number of active CPUs");
|
||||
|
||||
@ -263,8 +266,9 @@ sysctl_hw_machine_arch(SYSCTL_HANDLER_ARGS)
|
||||
return (error);
|
||||
|
||||
}
|
||||
SYSCTL_PROC(_hw, HW_MACHINE_ARCH, machine_arch, CTLTYPE_STRING | CTLFLAG_RD,
|
||||
NULL, 0, sysctl_hw_machine_arch, "A", "System architecture");
|
||||
SYSCTL_PROC(_hw, HW_MACHINE_ARCH, machine_arch, CTLTYPE_STRING | CTLFLAG_RD |
|
||||
CTLFLAG_MPSAFE, NULL, 0, sysctl_hw_machine_arch, "A",
|
||||
"System architecture");
|
||||
#endif /* __rtems__ */
|
||||
|
||||
SYSCTL_STRING(_kern, OID_AUTO, supported_archs, CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
@ -339,15 +343,15 @@ sysctl_hostname(SYSCTL_HANDLER_ARGS)
|
||||
}
|
||||
|
||||
SYSCTL_PROC(_kern, KERN_HOSTNAME, hostname,
|
||||
CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
|
||||
CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_CAPRD | CTLFLAG_MPSAFE,
|
||||
(void *)(offsetof(struct prison, pr_hostname)), MAXHOSTNAMELEN,
|
||||
sysctl_hostname, "A", "Hostname");
|
||||
SYSCTL_PROC(_kern, KERN_NISDOMAINNAME, domainname,
|
||||
CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
|
||||
CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_CAPRD | CTLFLAG_MPSAFE,
|
||||
(void *)(offsetof(struct prison, pr_domainname)), MAXHOSTNAMELEN,
|
||||
sysctl_hostname, "A", "Name of the current YP/NIS domain");
|
||||
SYSCTL_PROC(_kern, KERN_HOSTUUID, hostuuid,
|
||||
CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_MPSAFE,
|
||||
CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_CAPRD | CTLFLAG_MPSAFE,
|
||||
(void *)(offsetof(struct prison, pr_hostuuid)), HOSTUUIDLEN,
|
||||
sysctl_hostname, "A", "Host UUID");
|
||||
|
||||
@ -407,8 +411,8 @@ SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel,
|
||||
/* Actual kernel configuration options. */
|
||||
extern char kernconfstring[];
|
||||
|
||||
SYSCTL_STRING(_kern, OID_AUTO, conftxt, CTLFLAG_RD, kernconfstring, 0,
|
||||
"Kernel configuration file");
|
||||
SYSCTL_STRING(_kern, OID_AUTO, conftxt, CTLFLAG_RD | CTLFLAG_MPSAFE,
|
||||
kernconfstring, 0, "Kernel configuration file");
|
||||
#endif
|
||||
|
||||
static int
|
||||
|
@ -17,7 +17,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -191,13 +191,7 @@ _sleep(void *ident, struct lock_object *lock, int priority,
|
||||
pri = priority;
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/*
|
||||
* If we are already on a sleep queue, then remove us from that
|
||||
* sleep queue first. We have to do this to handle recursive
|
||||
* sleeps.
|
||||
*/
|
||||
if (TD_ON_SLEEPQ(td))
|
||||
sleepq_remove(td, td->td_wchan);
|
||||
KASSERT(!TD_ON_SLEEPQ(td), ("recursive sleep"));
|
||||
|
||||
if ((uint8_t *)ident >= &pause_wchan[0] &&
|
||||
(uint8_t *)ident <= &pause_wchan[MAXCPU - 1])
|
||||
|
@ -18,7 +18,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
|
@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
|
@ -17,7 +17,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -1059,6 +1059,8 @@ callout_when(sbintime_t sbt, sbintime_t precision, int flags,
|
||||
spinlock_exit();
|
||||
#endif
|
||||
#endif
|
||||
if (cold && to_sbt == 0)
|
||||
to_sbt = sbinuptime();
|
||||
if ((flags & C_HARDCLOCK) == 0)
|
||||
to_sbt += tick_sbt;
|
||||
} else
|
||||
|
@ -30,6 +30,7 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <rtems/bsd/local/opt_bus.h>
|
||||
#include <rtems/bsd/local/opt_ddb.h>
|
||||
|
||||
#include <rtems/bsd/sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
@ -67,6 +68,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/uma.h>
|
||||
#include <vm/vm.h>
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
|
||||
SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
|
||||
SYSCTL_ROOT_NODE(OID_AUTO, dev, CTLFLAG_RW, NULL, NULL);
|
||||
|
||||
@ -147,6 +150,9 @@ static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc");
|
||||
static void devctl2_init(void);
|
||||
#endif /* __rtems__ */
|
||||
|
||||
#define DRIVERNAME(d) ((d)? d->name : "no driver")
|
||||
#define DEVCLANAME(d) ((d)? d->name : "no devclass")
|
||||
|
||||
#ifdef BUS_DEBUG
|
||||
|
||||
static int bus_debug = 1;
|
||||
@ -155,8 +161,6 @@ SYSCTL_INT(_debug, OID_AUTO, bus_debug, CTLFLAG_RWTUN, &bus_debug, 0,
|
||||
|
||||
#define PDEBUG(a) if (bus_debug) {printf("%s:%d: ", __func__, __LINE__), printf a; printf("\n");}
|
||||
#define DEVICENAME(d) ((d)? device_get_name(d): "no device")
|
||||
#define DRIVERNAME(d) ((d)? d->name : "no driver")
|
||||
#define DEVCLANAME(d) ((d)? d->name : "no devclass")
|
||||
|
||||
/**
|
||||
* Produce the indenting, indent*2 spaces plus a '.' ahead of that to
|
||||
@ -180,8 +184,6 @@ void print_devclass_list(void);
|
||||
/* Make the compiler ignore the function calls */
|
||||
#define PDEBUG(a) /* nop */
|
||||
#define DEVICENAME(d) /* nop */
|
||||
#define DRIVERNAME(d) /* nop */
|
||||
#define DEVCLANAME(d) /* nop */
|
||||
|
||||
#define print_device_short(d,i) /* nop */
|
||||
#define print_device(d,i) /* nop */
|
||||
@ -1981,15 +1983,17 @@ device_delete_child(device_t dev, device_t child)
|
||||
|
||||
PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
|
||||
|
||||
/* remove children first */
|
||||
/* detach parent before deleting children, if any */
|
||||
if ((error = device_detach(child)) != 0)
|
||||
return (error);
|
||||
|
||||
/* remove children second */
|
||||
while ((grandchild = TAILQ_FIRST(&child->children)) != NULL) {
|
||||
error = device_delete_child(child, grandchild);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
|
||||
if ((error = device_detach(child)) != 0)
|
||||
return (error);
|
||||
if (child->devclass)
|
||||
devclass_delete_device(child->devclass, child);
|
||||
if (child->parent)
|
||||
@ -2179,6 +2183,12 @@ device_probe_child(device_t dev, device_t child)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset DF_QUIET in case this driver doesn't
|
||||
* end up as the best driver.
|
||||
*/
|
||||
device_verbose(child);
|
||||
|
||||
/*
|
||||
* Probes that return BUS_PROBE_NOWILDCARD or lower
|
||||
* only match on devices whose driver was explicitly
|
||||
@ -3008,6 +3018,7 @@ device_detach(device_t dev)
|
||||
if (!(dev->flags & DF_FIXEDCLASS))
|
||||
devclass_delete_device(dev->devclass, dev);
|
||||
|
||||
device_verbose(dev);
|
||||
dev->state = DS_NOTPRESENT;
|
||||
(void)device_set_driver(dev, NULL);
|
||||
device_sysctl_fini(dev);
|
||||
@ -5396,6 +5407,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
||||
case DEV_SUSPEND:
|
||||
case DEV_RESUME:
|
||||
case DEV_SET_DRIVER:
|
||||
case DEV_CLEAR_DRIVER:
|
||||
case DEV_RESCAN:
|
||||
case DEV_DELETE:
|
||||
error = priv_check(td, PRIV_DRIVER);
|
||||
@ -5561,6 +5573,25 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
||||
error = device_probe_and_attach(dev);
|
||||
break;
|
||||
}
|
||||
case DEV_CLEAR_DRIVER:
|
||||
if (!(dev->flags & DF_FIXEDCLASS)) {
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
if (device_is_attached(dev)) {
|
||||
if (req->dr_flags & DEVF_CLEAR_DRIVER_DETACH)
|
||||
error = device_detach(dev);
|
||||
else
|
||||
error = EBUSY;
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
|
||||
dev->flags &= ~DF_FIXEDCLASS;
|
||||
dev->flags |= DF_WILDCARD;
|
||||
devclass_delete_device(dev->devclass, dev);
|
||||
error = device_probe_and_attach(dev);
|
||||
break;
|
||||
case DEV_RESCAN:
|
||||
if (!device_is_attached(dev)) {
|
||||
error = ENXIO;
|
||||
@ -5604,4 +5635,33 @@ devctl2_init(void)
|
||||
make_dev_credf(MAKEDEV_ETERNAL, &devctl2_cdevsw, 0, NULL,
|
||||
UID_ROOT, GID_WHEEL, 0600, "devctl2");
|
||||
}
|
||||
|
||||
#ifdef DDB
|
||||
DB_SHOW_COMMAND(device, db_show_device)
|
||||
{
|
||||
device_t dev;
|
||||
|
||||
if (!have_addr)
|
||||
return;
|
||||
|
||||
dev = (device_t)addr;
|
||||
|
||||
db_printf("name: %s\n", device_get_nameunit(dev));
|
||||
db_printf(" driver: %s\n", DRIVERNAME(dev->driver));
|
||||
db_printf(" class: %s\n", DEVCLANAME(dev->devclass));
|
||||
db_printf(" addr: %p\n", dev);
|
||||
db_printf(" parent: %p\n", dev->parent);
|
||||
db_printf(" softc: %p\n", dev->softc);
|
||||
db_printf(" ivars: %p\n", dev->ivars);
|
||||
}
|
||||
|
||||
DB_SHOW_ALL_COMMAND(devices, db_show_all_devices)
|
||||
{
|
||||
device_t dev;
|
||||
|
||||
TAILQ_FOREACH(dev, &bus_data_devices, devlink) {
|
||||
db_show_device((db_expr_t)dev, true, count, modif);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* __rtems__ */
|
||||
|
@ -17,7 +17,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
|
@ -16,7 +16,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* 3. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
|
@ -17,7 +17,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -80,7 +80,11 @@ __FBSDID("$FreeBSD$");
|
||||
* Note that stdarg.h and the ANSI style va_start macro is used for both
|
||||
* ANSI and traditional C compilers.
|
||||
*/
|
||||
#ifdef _KERNEL
|
||||
#include <machine/stdarg.h>
|
||||
#else
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
|
@ -434,7 +434,7 @@ sleepq_set_timeout_sbt(void *wchan, sbintime_t sbt, sbintime_t pr,
|
||||
MPASS(TD_ON_SLEEPQ(td));
|
||||
MPASS(td->td_sleepqueue == NULL);
|
||||
MPASS(wchan != NULL);
|
||||
if (cold)
|
||||
if (cold && td == &thread0)
|
||||
panic("timed sleep before timers are working");
|
||||
KASSERT(td->td_sleeptimo == 0, ("td %d %p td_sleeptimo %jx",
|
||||
td->td_tid, td, (uintmax_t)td->td_sleeptimo));
|
||||
@ -1089,9 +1089,9 @@ sleepq_signal(void *wchan, int flags, int pri, int queue)
|
||||
* been sleeping the longest since threads are always added to
|
||||
* the tail of sleep queues.
|
||||
*/
|
||||
besttd = NULL;
|
||||
besttd = TAILQ_FIRST(&sq->sq_blocked[queue]);
|
||||
TAILQ_FOREACH(td, &sq->sq_blocked[queue], td_slpq) {
|
||||
if (besttd == NULL || td->td_priority < besttd->td_priority)
|
||||
if (td->td_priority < besttd->td_priority)
|
||||
besttd = td;
|
||||
}
|
||||
#else /* __rtems__ */
|
||||
|
@ -89,6 +89,7 @@ struct taskqueue {
|
||||
#define TQ_FLAGS_UNLOCKED_ENQUEUE (1 << 2)
|
||||
|
||||
#define DT_CALLOUT_ARMED (1 << 0)
|
||||
#define DT_DRAIN_IN_PROGRESS (1 << 1)
|
||||
|
||||
#ifndef __rtems__
|
||||
#define TQ_LOCK(tq) \
|
||||
@ -334,7 +335,11 @@ taskqueue_enqueue_timeout(struct taskqueue *queue,
|
||||
#endif /* __rtems__ */
|
||||
timeout_task->q = queue;
|
||||
res = timeout_task->t.ta_pending;
|
||||
if (ticks == 0) {
|
||||
if (timeout_task->f & DT_DRAIN_IN_PROGRESS) {
|
||||
/* Do nothing */
|
||||
TQ_UNLOCK(queue);
|
||||
res = -1;
|
||||
} else if (ticks == 0) {
|
||||
taskqueue_enqueue_locked(queue, &timeout_task->t);
|
||||
/* The lock is released inside. */
|
||||
} else {
|
||||
@ -598,8 +603,24 @@ taskqueue_drain_timeout(struct taskqueue *queue,
|
||||
struct timeout_task *timeout_task)
|
||||
{
|
||||
|
||||
/*
|
||||
* Set flag to prevent timer from re-starting during drain:
|
||||
*/
|
||||
TQ_LOCK(queue);
|
||||
KASSERT((timeout_task->f & DT_DRAIN_IN_PROGRESS) == 0,
|
||||
("Drain already in progress"));
|
||||
timeout_task->f |= DT_DRAIN_IN_PROGRESS;
|
||||
TQ_UNLOCK(queue);
|
||||
|
||||
callout_drain(&timeout_task->c);
|
||||
taskqueue_drain(queue, &timeout_task->t);
|
||||
|
||||
/*
|
||||
* Clear flag to allow timer to re-start:
|
||||
*/
|
||||
TQ_LOCK(queue);
|
||||
timeout_task->f &= ~DT_DRAIN_IN_PROGRESS;
|
||||
TQ_UNLOCK(queue);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -666,6 +687,11 @@ _taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
|
||||
} else
|
||||
tq->tq_tcount++;
|
||||
}
|
||||
if (tq->tq_tcount == 0) {
|
||||
free(tq->tq_threads, M_TASKQUEUE);
|
||||
tq->tq_threads = NULL;
|
||||
return (ENOMEM);
|
||||
}
|
||||
#ifndef __rtems__
|
||||
for (i = 0; i < count; i++) {
|
||||
if (tq->tq_threads[i] == NULL)
|
||||
|
@ -22,7 +22,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -556,7 +556,7 @@ fueword32(volatile const void *base, int32_t *val)
|
||||
int
|
||||
fueword64(volatile const void *base, int64_t *val)
|
||||
{
|
||||
int32_t res;
|
||||
int64_t res;
|
||||
|
||||
res = fuword64(base);
|
||||
if (res == -1)
|
||||
|
@ -17,7 +17,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
|
@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
|
@ -252,7 +252,7 @@ do_setopt_accept_filter(struct socket *so, struct sockopt *sopt)
|
||||
newaf = malloc(sizeof(*newaf), M_ACCF, M_WAITOK |
|
||||
M_ZERO);
|
||||
if (afp->accf_create != NULL && afap->af_name[0] != '\0') {
|
||||
int len = strlen(afap->af_name) + 1;
|
||||
size_t len = strlen(afap->af_name) + 1;
|
||||
newaf->so_accept_filter_str = malloc(len, M_ACCF,
|
||||
M_WAITOK);
|
||||
strcpy(newaf->so_accept_filter_str, afap->af_name);
|
||||
|
@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
|
@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -986,7 +986,7 @@ m_devget(char *buf, int totlen, int off, struct ifnet *ifp,
|
||||
len = MHLEN;
|
||||
|
||||
/* Place initial small packet/header at end of mbuf */
|
||||
if (m && totlen + off + max_linkhdr <= MLEN) {
|
||||
if (m && totlen + off + max_linkhdr <= MHLEN) {
|
||||
m->m_data += max_linkhdr;
|
||||
len -= max_linkhdr;
|
||||
}
|
||||
@ -1338,7 +1338,7 @@ nospace:
|
||||
/*
|
||||
* Defragment an mbuf chain, returning at most maxfrags separate
|
||||
* mbufs+clusters. If this is not possible NULL is returned and
|
||||
* the original mbuf chain is left in it's present (potentially
|
||||
* the original mbuf chain is left in its present (potentially
|
||||
* modified) state. We use two techniques: collapsing consecutive
|
||||
* mbufs and replacing consecutive mbufs by a cluster.
|
||||
*
|
||||
|
@ -43,7 +43,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
|
@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -1669,7 +1669,8 @@ dontblock:
|
||||
do {
|
||||
if (flags & MSG_PEEK) {
|
||||
if (controlp != NULL) {
|
||||
*controlp = m_copy(m, 0, m->m_len);
|
||||
*controlp = m_copym(m, 0, m->m_len,
|
||||
M_NOWAIT);
|
||||
controlp = &(*controlp)->m_next;
|
||||
}
|
||||
m = m->m_next;
|
||||
|
@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -94,20 +94,23 @@ static int sockargs(struct mbuf **, char *, socklen_t, int);
|
||||
/*
|
||||
* Convert a user file descriptor to a kernel file entry and check if required
|
||||
* capability rights are present.
|
||||
* If required copy of current set of capability rights is returned.
|
||||
* A reference on the file entry is held upon returning.
|
||||
*/
|
||||
int
|
||||
getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
|
||||
struct file **fpp, u_int *fflagp)
|
||||
struct file **fpp, u_int *fflagp, struct filecaps *havecapsp)
|
||||
{
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
error = fget_unlocked(td->td_proc->p_fd, fd, rightsp, &fp, NULL);
|
||||
error = fget_cap(td, fd, rightsp, &fp, havecapsp);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (fp->f_type != DTYPE_SOCKET) {
|
||||
fdrop(fp, td);
|
||||
if (havecapsp != NULL)
|
||||
filecaps_free(havecapsp);
|
||||
return (ENOTSOCK);
|
||||
}
|
||||
if (fflagp != NULL)
|
||||
@ -148,7 +151,7 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp)
|
||||
return (error);
|
||||
}
|
||||
|
||||
#define getsock_cap(td, fd, rights, fpp, fflagp) rtems_bsd_getsock(fd, fpp, fflagp)
|
||||
#define getsock_cap(td, fd, rights, fpp, fflagp, havecapsp) rtems_bsd_getsock(fd, fpp, fflagp)
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/*
|
||||
@ -162,13 +165,7 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp)
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
sys_socket(td, uap)
|
||||
struct thread *td;
|
||||
struct socket_args /* {
|
||||
int domain;
|
||||
int type;
|
||||
int protocol;
|
||||
} */ *uap;
|
||||
sys_socket(struct thread *td, struct socket_args *uap)
|
||||
{
|
||||
struct socket *so;
|
||||
struct file *fp;
|
||||
@ -239,7 +236,6 @@ socket(int domain, int type, int protocol)
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/* ARGSUSED */
|
||||
#ifdef __rtems__
|
||||
static int kern_bindat(struct thread *td, int dirfd, int fd,
|
||||
struct sockaddr *sa);
|
||||
@ -247,13 +243,7 @@ static int kern_bindat(struct thread *td, int dirfd, int fd,
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
sys_bind(td, uap)
|
||||
struct thread *td;
|
||||
struct bind_args /* {
|
||||
int s;
|
||||
caddr_t name;
|
||||
int namelen;
|
||||
} */ *uap;
|
||||
sys_bind(struct thread *td, struct bind_args *uap)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int error;
|
||||
@ -298,7 +288,7 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
|
||||
AUDIT_ARG_FD(fd);
|
||||
AUDIT_ARG_SOCKADDR(td, dirfd, sa);
|
||||
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_BIND),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
@ -321,18 +311,10 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
#ifndef __rtems__
|
||||
static
|
||||
int
|
||||
sys_bindat(td, uap)
|
||||
struct thread *td;
|
||||
struct bindat_args /* {
|
||||
int fd;
|
||||
int s;
|
||||
caddr_t name;
|
||||
int namelen;
|
||||
} */ *uap;
|
||||
sys_bindat(struct thread *td, struct bindat_args *uap)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int error;
|
||||
@ -346,14 +328,8 @@ sys_bindat(td, uap)
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
sys_listen(td, uap)
|
||||
struct thread *td;
|
||||
struct listen_args /* {
|
||||
int s;
|
||||
int backlog;
|
||||
} */ *uap;
|
||||
sys_listen(struct thread *td, struct listen_args *uap)
|
||||
{
|
||||
struct socket *so;
|
||||
struct file *fp;
|
||||
@ -362,7 +338,7 @@ sys_listen(td, uap)
|
||||
|
||||
AUDIT_ARG_FD(uap->s);
|
||||
error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_LISTEN),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
#ifdef MAC
|
||||
@ -483,6 +459,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
|
||||
struct file *headfp, *nfp = NULL;
|
||||
struct sockaddr *sa = NULL;
|
||||
struct socket *head, *so;
|
||||
struct filecaps fcaps;
|
||||
cap_rights_t rights;
|
||||
u_int fflag;
|
||||
pid_t pgid;
|
||||
@ -493,7 +470,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
|
||||
|
||||
AUDIT_ARG_FD(s);
|
||||
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_ACCEPT),
|
||||
&headfp, &fflag);
|
||||
&headfp, &fflag, &fcaps);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
head = headfp->f_data;
|
||||
@ -506,7 +483,8 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
|
||||
if (error != 0)
|
||||
goto done;
|
||||
#endif
|
||||
error = falloc(td, &nfp, &fd, (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0);
|
||||
error = falloc_caps(td, &nfp, &fd,
|
||||
(flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0, &fcaps);
|
||||
if (error != 0)
|
||||
goto done;
|
||||
ACCEPT_LOCK();
|
||||
@ -615,6 +593,8 @@ noconnection:
|
||||
* a reference on nfp to the caller on success if they request it.
|
||||
*/
|
||||
done:
|
||||
if (nfp == NULL)
|
||||
filecaps_free(&fcaps);
|
||||
if (fp != NULL) {
|
||||
if (error == 0) {
|
||||
*fp = nfp;
|
||||
@ -663,7 +643,6 @@ oaccept(td, uap)
|
||||
#endif /* COMPAT_OLDSOCK */
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/* ARGSUSED */
|
||||
#ifdef __rtems__
|
||||
static int kern_connectat(struct thread *td, int dirfd, int fd,
|
||||
struct sockaddr *sa);
|
||||
@ -671,13 +650,7 @@ static int kern_connectat(struct thread *td, int dirfd, int fd,
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
sys_connect(td, uap)
|
||||
struct thread *td;
|
||||
struct connect_args /* {
|
||||
int s;
|
||||
caddr_t name;
|
||||
int namelen;
|
||||
} */ *uap;
|
||||
sys_connect(struct thread *td, struct connect_args *uap)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int error;
|
||||
@ -722,7 +695,7 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
|
||||
AUDIT_ARG_FD(fd);
|
||||
AUDIT_ARG_SOCKADDR(td, dirfd, sa);
|
||||
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_CONNECT),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
@ -775,16 +748,8 @@ done1:
|
||||
}
|
||||
|
||||
#ifndef __rtems__
|
||||
/* ARGSUSED */
|
||||
int
|
||||
sys_connectat(td, uap)
|
||||
struct thread *td;
|
||||
struct connectat_args /* {
|
||||
int fd;
|
||||
int s;
|
||||
caddr_t name;
|
||||
int namelen;
|
||||
} */ *uap;
|
||||
sys_connectat(struct thread *td, struct connectat_args *uap)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int error;
|
||||
@ -936,11 +901,7 @@ kern_sendit( struct thread *td, int s, struct msghdr *mp, int flags,
|
||||
struct mbuf *control, enum uio_seg segflg);
|
||||
#endif /* __rtems__ */
|
||||
static int
|
||||
sendit(td, s, mp, flags)
|
||||
struct thread *td;
|
||||
int s;
|
||||
struct msghdr *mp;
|
||||
int flags;
|
||||
sendit(struct thread *td, int s, struct msghdr *mp, int flags)
|
||||
{
|
||||
struct mbuf *control;
|
||||
struct sockaddr *to;
|
||||
@ -998,13 +959,8 @@ bad:
|
||||
}
|
||||
|
||||
int
|
||||
kern_sendit(td, s, mp, flags, control, segflg)
|
||||
struct thread *td;
|
||||
int s;
|
||||
struct msghdr *mp;
|
||||
int flags;
|
||||
struct mbuf *control;
|
||||
enum uio_seg segflg;
|
||||
kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
|
||||
struct mbuf *control, enum uio_seg segflg)
|
||||
{
|
||||
struct file *fp;
|
||||
struct uio auio;
|
||||
@ -1026,12 +982,12 @@ kern_sendit(td, s, mp, flags, control, segflg)
|
||||
AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
|
||||
cap_rights_set(&rights, CAP_CONNECT);
|
||||
}
|
||||
error = getsock_cap(td, s, &rights, &fp, NULL);
|
||||
if (error != 0)
|
||||
#endif /* __rtems__ */
|
||||
error = getsock_cap(td->td_proc->p_fd, s, rights, &fp, NULL);
|
||||
if (error)
|
||||
error = getsock_cap(td, s, &rights, &fp, NULL, NULL);
|
||||
if (error != 0) {
|
||||
m_freem(control);
|
||||
return (error);
|
||||
}
|
||||
so = (struct socket *)fp->f_data;
|
||||
|
||||
#ifdef KTRACE
|
||||
@ -1042,12 +998,16 @@ kern_sendit(td, s, mp, flags, control, segflg)
|
||||
if (mp->msg_name != NULL) {
|
||||
error = mac_socket_check_connect(td->td_ucred, so,
|
||||
mp->msg_name);
|
||||
if (error != 0)
|
||||
if (error != 0) {
|
||||
m_freem(control);
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
error = mac_socket_check_send(td->td_ucred, so);
|
||||
if (error != 0)
|
||||
if (error != 0) {
|
||||
m_freem(control);
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
|
||||
auio.uio_iov = mp->msg_iov;
|
||||
@ -1061,6 +1021,7 @@ kern_sendit(td, s, mp, flags, control, segflg)
|
||||
for (i = 0; i < mp->msg_iovlen; i++, iov++) {
|
||||
if ((auio.uio_resid += iov->iov_len) < 0) {
|
||||
error = EINVAL;
|
||||
m_freem(control);
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
@ -1103,16 +1064,7 @@ bad:
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
sys_sendto(td, uap)
|
||||
struct thread *td;
|
||||
struct sendto_args /* {
|
||||
int s;
|
||||
caddr_t buf;
|
||||
size_t len;
|
||||
int flags;
|
||||
caddr_t to;
|
||||
int tolen;
|
||||
} */ *uap;
|
||||
sys_sendto(struct thread *td, struct sendto_args *uap)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec aiov;
|
||||
@ -1167,7 +1119,7 @@ rtems_bsd_sendto(int socket, struct mbuf *m, int flags,
|
||||
struct socket *so;
|
||||
int error;
|
||||
|
||||
error = getsock_cap(td->td_proc->p_fd, socket, CAP_WRITE, &fp, NULL);
|
||||
error = getsock_cap(td->td_proc->p_fd, socket, CAP_WRITE, &fp, NULL, NULL);
|
||||
if (error)
|
||||
return (error);
|
||||
so = (struct socket *)fp->f_data;
|
||||
@ -1186,14 +1138,7 @@ rtems_bsd_sendto(int socket, struct mbuf *m, int flags,
|
||||
#ifndef __rtems__
|
||||
#ifdef COMPAT_OLDSOCK
|
||||
int
|
||||
osend(td, uap)
|
||||
struct thread *td;
|
||||
struct osend_args /* {
|
||||
int s;
|
||||
caddr_t buf;
|
||||
int len;
|
||||
int flags;
|
||||
} */ *uap;
|
||||
osend(struct thread *td, struct osend_args *uap)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec aiov;
|
||||
@ -1210,13 +1155,7 @@ osend(td, uap)
|
||||
}
|
||||
|
||||
int
|
||||
osendmsg(td, uap)
|
||||
struct thread *td;
|
||||
struct osendmsg_args /* {
|
||||
int s;
|
||||
caddr_t msg;
|
||||
int flags;
|
||||
} */ *uap;
|
||||
osendmsg(struct thread *td, struct osendmsg_args *uap)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec *iov;
|
||||
@ -1241,13 +1180,7 @@ osendmsg(td, uap)
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
sys_sendmsg(td, uap)
|
||||
struct thread *td;
|
||||
struct sendmsg_args /* {
|
||||
int s;
|
||||
caddr_t msg;
|
||||
int flags;
|
||||
} */ *uap;
|
||||
sys_sendmsg(struct thread *td, struct sendmsg_args *uap)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec *iov;
|
||||
@ -1297,12 +1230,8 @@ sendmsg(int socket, const struct msghdr *message, int flags)
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
kern_recvit(td, s, mp, fromseg, controlp)
|
||||
struct thread *td;
|
||||
int s;
|
||||
struct msghdr *mp;
|
||||
enum uio_seg fromseg;
|
||||
struct mbuf **controlp;
|
||||
kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg,
|
||||
struct mbuf **controlp)
|
||||
{
|
||||
struct uio auio;
|
||||
struct iovec *iov;
|
||||
@ -1323,7 +1252,7 @@ kern_recvit(td, s, mp, fromseg, controlp)
|
||||
|
||||
AUDIT_ARG_FD(s);
|
||||
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_RECV),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
@ -1459,11 +1388,7 @@ out:
|
||||
}
|
||||
|
||||
static int
|
||||
recvit(td, s, mp, namelenp)
|
||||
struct thread *td;
|
||||
int s;
|
||||
struct msghdr *mp;
|
||||
void *namelenp;
|
||||
recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp)
|
||||
{
|
||||
int error;
|
||||
|
||||
@ -1484,16 +1409,7 @@ recvit(td, s, mp, namelenp)
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
sys_recvfrom(td, uap)
|
||||
struct thread *td;
|
||||
struct recvfrom_args /* {
|
||||
int s;
|
||||
caddr_t buf;
|
||||
size_t len;
|
||||
int flags;
|
||||
struct sockaddr * __restrict from;
|
||||
socklen_t * __restrict fromlenaddr;
|
||||
} */ *uap;
|
||||
sys_recvfrom(struct thread *td, struct recvfrom_args *uap)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec aiov;
|
||||
@ -1551,9 +1467,7 @@ recvfrom(int socket, void *__restrict buffer, size_t length, int flags,
|
||||
#ifndef __rtems__
|
||||
#ifdef COMPAT_OLDSOCK
|
||||
int
|
||||
orecvfrom(td, uap)
|
||||
struct thread *td;
|
||||
struct recvfrom_args *uap;
|
||||
orecvfrom(struct thread *td, struct recvfrom_args *uap)
|
||||
{
|
||||
|
||||
uap->flags |= MSG_COMPAT;
|
||||
@ -1563,14 +1477,7 @@ orecvfrom(td, uap)
|
||||
|
||||
#ifdef COMPAT_OLDSOCK
|
||||
int
|
||||
orecv(td, uap)
|
||||
struct thread *td;
|
||||
struct orecv_args /* {
|
||||
int s;
|
||||
caddr_t buf;
|
||||
int len;
|
||||
int flags;
|
||||
} */ *uap;
|
||||
orecv(struct thread *td, struct orecv_args *uap)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec aiov;
|
||||
@ -1592,13 +1499,7 @@ orecv(td, uap)
|
||||
* rights where the control fields are now.
|
||||
*/
|
||||
int
|
||||
orecvmsg(td, uap)
|
||||
struct thread *td;
|
||||
struct orecvmsg_args /* {
|
||||
int s;
|
||||
struct omsghdr *msg;
|
||||
int flags;
|
||||
} */ *uap;
|
||||
orecvmsg(struct thread *td, struct orecvmsg_args *uap)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec *iov;
|
||||
@ -1626,13 +1527,7 @@ orecvmsg(td, uap)
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
sys_recvmsg(td, uap)
|
||||
struct thread *td;
|
||||
struct recvmsg_args /* {
|
||||
int s;
|
||||
struct msghdr *msg;
|
||||
int flags;
|
||||
} */ *uap;
|
||||
sys_recvmsg(struct thread *td, struct recvmsg_args *uap)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec *uiov, *iov;
|
||||
@ -1684,17 +1579,11 @@ recvmsg(int socket, struct msghdr *message, int flags)
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/* ARGSUSED */
|
||||
#ifdef __rtems__
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
sys_shutdown(td, uap)
|
||||
struct thread *td;
|
||||
struct shutdown_args /* {
|
||||
int s;
|
||||
int how;
|
||||
} */ *uap;
|
||||
sys_shutdown(struct thread *td, struct shutdown_args *uap)
|
||||
{
|
||||
struct socket *so;
|
||||
struct file *fp;
|
||||
@ -1703,7 +1592,7 @@ sys_shutdown(td, uap)
|
||||
|
||||
AUDIT_ARG_FD(uap->s);
|
||||
error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_SHUTDOWN),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
error = soshutdown(so, uap->how);
|
||||
@ -1736,7 +1625,6 @@ shutdown(int socket, int how)
|
||||
}
|
||||
#endif /* __rtems__ */
|
||||
|
||||
/* ARGSUSED */
|
||||
#ifdef __rtems__
|
||||
static int kern_setsockopt( struct thread *td, int s, int level, int name,
|
||||
void *val, enum uio_seg valseg, socklen_t valsize);
|
||||
@ -1744,15 +1632,7 @@ static int kern_setsockopt( struct thread *td, int s, int level, int name,
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
sys_setsockopt(td, uap)
|
||||
struct thread *td;
|
||||
struct setsockopt_args /* {
|
||||
int s;
|
||||
int level;
|
||||
int name;
|
||||
caddr_t val;
|
||||
int valsize;
|
||||
} */ *uap;
|
||||
sys_setsockopt(struct thread *td, struct setsockopt_args *uap)
|
||||
{
|
||||
|
||||
return (kern_setsockopt(td, uap->s, uap->level, uap->name,
|
||||
@ -1784,14 +1664,8 @@ setsockopt(int socket, int level, int option_name, const void *option_value,
|
||||
#endif /* __rtems__ */
|
||||
|
||||
int
|
||||
kern_setsockopt(td, s, level, name, val, valseg, valsize)
|
||||
struct thread *td;
|
||||
int s;
|
||||
int level;
|
||||
int name;
|
||||
void *val;
|
||||
enum uio_seg valseg;
|
||||
socklen_t valsize;
|
||||
kern_setsockopt(struct thread *td, int s, int level, int name, void *val,
|
||||
enum uio_seg valseg, socklen_t valsize)
|
||||
{
|
||||
struct socket *so;
|
||||
struct file *fp;
|
||||
@ -1822,7 +1696,7 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize)
|
||||
|
||||
AUDIT_ARG_FD(s);
|
||||
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SETSOCKOPT),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
error = sosetopt(so, &sopt);
|
||||
@ -1831,7 +1705,6 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize)
|
||||
return(error);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
#ifdef __rtems__
|
||||
static int kern_getsockopt( struct thread *td, int s, int level, int name,
|
||||
void *val, enum uio_seg valseg, socklen_t *valsize);
|
||||
@ -1839,15 +1712,7 @@ static int kern_getsockopt( struct thread *td, int s, int level, int name,
|
||||
static
|
||||
#endif /* __rtems__ */
|
||||
int
|
||||
sys_getsockopt(td, uap)
|
||||
struct thread *td;
|
||||
struct getsockopt_args /* {
|
||||
int s;
|
||||
int level;
|
||||
int name;
|
||||
void * __restrict val;
|
||||
socklen_t * __restrict avalsize;
|
||||
} */ *uap;
|
||||
sys_getsockopt(struct thread *td, struct getsockopt_args *uap)
|
||||
{
|
||||
socklen_t valsize;
|
||||
int error;
|
||||
@ -1895,14 +1760,8 @@ getsockopt(int socket, int level, int option_name, void *__restrict
|
||||
* optval can be a userland or userspace. optlen is always a kernel pointer.
|
||||
*/
|
||||
int
|
||||
kern_getsockopt(td, s, level, name, val, valseg, valsize)
|
||||
struct thread *td;
|
||||
int s;
|
||||
int level;
|
||||
int name;
|
||||
void *val;
|
||||
enum uio_seg valseg;
|
||||
socklen_t *valsize;
|
||||
kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
|
||||
enum uio_seg valseg, socklen_t *valsize)
|
||||
{
|
||||
struct socket *so;
|
||||
struct file *fp;
|
||||
@ -1933,7 +1792,7 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize)
|
||||
|
||||
AUDIT_ARG_FD(s);
|
||||
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_GETSOCKOPT),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error == 0) {
|
||||
so = fp->f_data;
|
||||
error = sogetopt(so, &sopt);
|
||||
@ -1951,16 +1810,8 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
|
||||
/*
|
||||
* getsockname1() - Get socket name.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
getsockname1(td, uap, compat)
|
||||
struct thread *td;
|
||||
struct getsockname_args /* {
|
||||
int fdes;
|
||||
struct sockaddr * __restrict asa;
|
||||
socklen_t * __restrict alen;
|
||||
} */ *uap;
|
||||
int compat;
|
||||
getsockname1(struct thread *td, struct getsockname_args *uap, int compat)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
socklen_t len;
|
||||
@ -2000,7 +1851,7 @@ getsockname(int socket, struct sockaddr *__restrict address,
|
||||
int error;
|
||||
|
||||
if (td != NULL) {
|
||||
error = getsockname1(td, &ua);
|
||||
error = getsockname1(td, &ua, 0);
|
||||
} else {
|
||||
error = ENOMEM;
|
||||
}
|
||||
@ -2021,7 +1872,7 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
|
||||
|
||||
AUDIT_ARG_FD(fd);
|
||||
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETSOCKNAME),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
@ -2051,9 +1902,7 @@ bad:
|
||||
|
||||
#ifndef __rtems__
|
||||
int
|
||||
sys_getsockname(td, uap)
|
||||
struct thread *td;
|
||||
struct getsockname_args *uap;
|
||||
sys_getsockname(struct thread *td, struct getsockname_args *uap)
|
||||
{
|
||||
|
||||
return (getsockname1(td, uap, 0));
|
||||
@ -2061,9 +1910,7 @@ sys_getsockname(td, uap)
|
||||
|
||||
#ifdef COMPAT_OLDSOCK
|
||||
int
|
||||
ogetsockname(td, uap)
|
||||
struct thread *td;
|
||||
struct getsockname_args *uap;
|
||||
ogetsockname(struct thread *td, struct getsockname_args *uap)
|
||||
{
|
||||
|
||||
return (getsockname1(td, uap, 1));
|
||||
@ -2079,16 +1926,8 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
|
||||
/*
|
||||
* getpeername1() - Get name of peer for connected socket.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
getpeername1(td, uap, compat)
|
||||
struct thread *td;
|
||||
struct getpeername_args /* {
|
||||
int fdes;
|
||||
struct sockaddr * __restrict asa;
|
||||
socklen_t * __restrict alen;
|
||||
} */ *uap;
|
||||
int compat;
|
||||
getpeername1(struct thread *td, struct getpeername_args *uap, int compat)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
socklen_t len;
|
||||
@ -2128,7 +1967,7 @@ getpeername(int socket, struct sockaddr *__restrict address,
|
||||
int error;
|
||||
|
||||
if (td != NULL) {
|
||||
error = getpeername1(td, &ua);
|
||||
error = getpeername1(td, &ua, 0);
|
||||
} else {
|
||||
error = ENOMEM;
|
||||
}
|
||||
@ -2149,7 +1988,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
|
||||
|
||||
AUDIT_ARG_FD(fd);
|
||||
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETPEERNAME),
|
||||
&fp, NULL);
|
||||
&fp, NULL, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
@ -2184,9 +2023,7 @@ done:
|
||||
|
||||
#ifndef __rtems__
|
||||
int
|
||||
sys_getpeername(td, uap)
|
||||
struct thread *td;
|
||||
struct getpeername_args *uap;
|
||||
sys_getpeername(struct thread *td, struct getpeername_args *uap)
|
||||
{
|
||||
|
||||
return (getpeername1(td, uap, 0));
|
||||
@ -2194,9 +2031,7 @@ sys_getpeername(td, uap)
|
||||
|
||||
#ifdef COMPAT_OLDSOCK
|
||||
int
|
||||
ogetpeername(td, uap)
|
||||
struct thread *td;
|
||||
struct ogetpeername_args *uap;
|
||||
ogetpeername(struct thread *td, struct ogetpeername_args *uap)
|
||||
{
|
||||
|
||||
/* XXX uap should have type `getpeername_args *' to begin with. */
|
||||
@ -2242,10 +2077,7 @@ sockargs(struct mbuf **mp, char *buf, socklen_t buflen, int type)
|
||||
}
|
||||
|
||||
int
|
||||
getsockaddr(namp, uaddr, len)
|
||||
struct sockaddr **namp;
|
||||
caddr_t uaddr;
|
||||
size_t len;
|
||||
getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int error;
|
||||
|
@ -14,7 +14,7 @@
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
@ -291,8 +291,8 @@ static int unp_connectat(int, struct socket *, struct sockaddr *,
|
||||
static int unp_connect2(struct socket *so, struct socket *so2, int);
|
||||
static void unp_disconnect(struct unpcb *unp, struct unpcb *unp2);
|
||||
#ifndef __rtems__
|
||||
static void unp_dispose(struct mbuf *);
|
||||
static void unp_dispose_so(struct socket *so);
|
||||
static void unp_dispose(struct socket *so);
|
||||
static void unp_dispose_mbuf(struct mbuf *);
|
||||
#endif /* __rtems__ */
|
||||
static void unp_shutdown(struct unpcb *);
|
||||
static void unp_drop(struct unpcb *);
|
||||
@ -355,7 +355,7 @@ static struct domain localdomain = {
|
||||
.dom_init = unp_init,
|
||||
#ifndef __rtems__
|
||||
.dom_externalize = unp_externalize,
|
||||
.dom_dispose = unp_dispose_so,
|
||||
.dom_dispose = unp_dispose,
|
||||
#endif /* __rtems__ */
|
||||
.dom_protosw = localsw,
|
||||
.dom_protoswNPROTOSW = &localsw[nitems(localsw)]
|
||||
@ -1164,7 +1164,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
|
||||
|
||||
if (control != NULL && error != 0)
|
||||
#ifndef __rtems__
|
||||
unp_dispose(control);
|
||||
unp_dispose_mbuf(control);
|
||||
#else /* __rtems__ */
|
||||
BSD_ASSERT(0);
|
||||
#endif /* __rtems__ */
|
||||
@ -2511,7 +2511,7 @@ unp_gc(__unused void *arg, int pending)
|
||||
}
|
||||
|
||||
static void
|
||||
unp_dispose(struct mbuf *m)
|
||||
unp_dispose_mbuf(struct mbuf *m)
|
||||
{
|
||||
|
||||
if (m)
|
||||
@ -2522,7 +2522,7 @@ unp_dispose(struct mbuf *m)
|
||||
* Synchronize against unp_gc, which can trip over data as we are freeing it.
|
||||
*/
|
||||
static void
|
||||
unp_dispose_so(struct socket *so)
|
||||
unp_dispose(struct socket *so)
|
||||
{
|
||||
struct unpcb *unp;
|
||||
|
||||
@ -2530,7 +2530,7 @@ unp_dispose_so(struct socket *so)
|
||||
UNP_LIST_LOCK();
|
||||
unp->unp_gcflag |= UNPGC_IGNORE_RIGHTS;
|
||||
UNP_LIST_UNLOCK();
|
||||
unp_dispose(so->so_rcv.sb_mb);
|
||||
unp_dispose_mbuf(so->so_rcv.sb_mb);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user