Update to FreeBSD head 2016-12-10

Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
This commit is contained in:
Sebastian Huber 2016-12-09 14:19:03 +01:00
parent c4e89a9125
commit 75b706fde4
227 changed files with 3800 additions and 3006 deletions

@ -1 +1 @@
Subproject commit 9fe7c416e6abb28b1398fd3e5687099846800cfd Subproject commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c

View File

@ -96,7 +96,7 @@ rtems_shell_cmd_t rtems_shell_HOSTNAME_Command = {
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int ch, sflag; int ch, sflag, dflag;
char *p, hostname[MAXHOSTNAMELEN]; char *p, hostname[MAXHOSTNAMELEN];
#ifdef __rtems__ #ifdef __rtems__
struct getopt_data getopt_data; struct getopt_data getopt_data;
@ -107,10 +107,11 @@ main(int argc, char *argv[])
#endif /* __rtems__ */ #endif /* __rtems__ */
sflag = 0; sflag = 0;
dflag = 0;
#ifndef __rtems__ #ifndef __rtems__
while ((ch = getopt(argc, argv, "fs")) != -1) while ((ch = getopt(argc, argv, "fsd")) != -1)
#else /* __rtems__ */ #else /* __rtems__ */
while ((ch = getopt(argc, argv, "fms")) != -1) while ((ch = getopt(argc, argv, "fdms")) != -1)
#endif /* __rtems__ */ #endif /* __rtems__ */
switch (ch) { switch (ch) {
case 'f': case 'f':
@ -123,6 +124,9 @@ main(int argc, char *argv[])
case 's': case 's':
sflag = 1; sflag = 1;
break; break;
case 'd':
dflag = 1;
break;
#ifdef __rtems__ #ifdef __rtems__
case 'm': case 'm':
mflag = 1; mflag = 1;
@ -135,7 +139,7 @@ main(int argc, char *argv[])
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (argc > 1) if (argc > 1 || (sflag && dflag))
usage(); usage();
if (*argv) { if (*argv) {
@ -164,6 +168,10 @@ main(int argc, char *argv[])
p = strchr(hostname, '.'); p = strchr(hostname, '.');
if (p != NULL) if (p != NULL)
*p = '\0'; *p = '\0';
} else if (dflag) {
p = strchr(hostname, '.');
if (p != NULL)
strcpy(hostname, ++p);
} }
(void)printf("%s\n", hostname); (void)printf("%s\n", hostname);
} }
@ -174,6 +182,10 @@ static void
usage(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); exit(1);
} }

View File

@ -40,6 +40,7 @@ static const char rcsid[] _U_ =
/* $FreeBSD$ */ /* $FreeBSD$ */
#ifdef __rtems__ #ifdef __rtems__
#define HAVE_GETOPT_LONG
#define __need_getopt_newlib #define __need_getopt_newlib
#include <getopt.h> #include <getopt.h>
#define setpriority(a, b, c) #define setpriority(a, b, c)
@ -84,6 +85,32 @@ extern int SIZE_BUF;
#include <smi.h> #include <smi.h>
#endif #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 <pcap.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
@ -1619,6 +1646,26 @@ main(int argc, char **argv)
if (pcap_setfilter(pd, &fcode) < 0) if (pcap_setfilter(pd, &fcode) < 0)
error("%s", pcap_geterr(pd)); 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) { if (WFileName) {
pcap_dumper_t *p; pcap_dumper_t *p;
/* Do not exceed the default PATH_MAX for files. */ /* Do not exceed the default PATH_MAX for files. */

View File

@ -136,7 +136,8 @@ __bt_sync(const DB *dbp, u_int flags)
return (RET_ERROR); 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); return (RET_SUCCESS);
if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR) if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)

View File

@ -339,6 +339,7 @@ int __sys_openat(int, const char *, int, ...);
int __sys_pselect(int, struct fd_set *, struct fd_set *, int __sys_pselect(int, struct fd_set *, struct fd_set *,
struct fd_set *, const struct timespec *, struct fd_set *, const struct timespec *,
const __sigset_t *); const __sigset_t *);
int __sys_ptrace(int, __pid_t, char *, int);
int __sys_poll(struct pollfd *, unsigned, int); int __sys_poll(struct pollfd *, unsigned, int);
int __sys_ppoll(struct pollfd *, unsigned, const struct timespec *, int __sys_ppoll(struct pollfd *, unsigned, const struct timespec *,
const __sigset_t *); const __sigset_t *);

View File

@ -226,6 +226,7 @@ struct ai_order {
struct policyqueue *aio_dstpolicy; struct policyqueue *aio_dstpolicy;
struct addrinfo *aio_ai; struct addrinfo *aio_ai;
int aio_matchlen; int aio_matchlen;
int aio_initial_sequence;
}; };
static const ns_src default_dns_files[] = { static const ns_src default_dns_files[] = {
@ -710,6 +711,7 @@ reorder(struct addrinfo *sentinel)
aio[i].aio_dstpolicy = match_addrselectpolicy(ai->ai_addr, aio[i].aio_dstpolicy = match_addrselectpolicy(ai->ai_addr,
&policyhead); &policyhead);
set_source(&aio[i], &policyhead); set_source(&aio[i], &policyhead);
aio[i].aio_initial_sequence = i;
} }
/* perform sorting. */ /* perform sorting. */
@ -949,7 +951,7 @@ matchlen(struct sockaddr *src, struct sockaddr *dst)
while (s < lim) while (s < lim)
if ((r = (*d++ ^ *s++)) != 0) { if ((r = (*d++ ^ *s++)) != 0) {
while (r < addrlen * 8) { while ((r & 0x80) == 0) {
match++; match++;
r <<= 1; r <<= 1;
} }
@ -1068,6 +1070,23 @@ comp_dst(const void *arg1, const void *arg2)
} }
/* Rule 10: Otherwise, leave the order unchanged. */ /* 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); return(-1);
} }

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <net/if.h>
#include <net/if_dl.h> #include <net/if_dl.h>
#include <string.h> #include <string.h>
@ -124,31 +125,46 @@ char *
link_ntoa(const struct sockaddr_dl *sdl) link_ntoa(const struct sockaddr_dl *sdl)
{ {
static char obuf[64]; static char obuf[64];
char *out = obuf; _Static_assert(sizeof(obuf) >= IFNAMSIZ + 20, "obuf is too small");
int i; char *out;
u_char *in = (u_char *)LLADDR(sdl); const u_char *in, *inlim;
u_char *inlim = in + sdl->sdl_alen; int namelen, i, rem;
int firsttime = 1;
if (sdl->sdl_nlen) { namelen = (sdl->sdl_nlen <= IFNAMSIZ) ? sdl->sdl_nlen : IFNAMSIZ;
bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
out += sdl->sdl_nlen; out = obuf;
if (sdl->sdl_alen) rem = sizeof(obuf);
if (namelen > 0) {
bcopy(sdl->sdl_data, out, namelen);
out += namelen;
rem -= namelen;
if (sdl->sdl_alen > 0) {
*out++ = ':'; *out++ = ':';
rem--;
}
} }
while (in < inlim) {
if (firsttime) in = (const u_char *)sdl->sdl_data + sdl->sdl_nlen;
firsttime = 0; inlim = in + sdl->sdl_alen;
else
while (in < inlim && rem > 1) {
if (in != (const u_char *)sdl->sdl_data + sdl->sdl_nlen) {
*out++ = '.'; *out++ = '.';
rem--;
}
i = *in++; i = *in++;
if (i > 0xf) { if (i > 0xf) {
out[1] = hexlist[i & 0xf]; if (rem < 3)
i >>= 4; break;
out[0] = hexlist[i]; *out++ = hexlist[i >> 4];
out += 2; *out++ = hexlist[i & 0xf];
} else rem -= 2;
} else {
if (rem < 2)
break;
*out++ = hexlist[i]; *out++ = hexlist[i];
rem--;
}
} }
*out = 0; *out = 0;
return (obuf); return (obuf);

View File

@ -187,6 +187,7 @@ struct hp_order {
#define aio_sa aio_un.aiou_sa #define aio_sa aio_un.aiou_sa
int aio_matchlen; int aio_matchlen;
char *aio_h_addr; char *aio_h_addr;
int aio_initial_sequence;
}; };
static struct hostent *_hpcopy(struct hostent *, int *); 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_dstscope = gai_addr2scopetype(sa);
aio[i].aio_dstpolicy = match_addrselectpolicy(sa, &policyhead); aio[i].aio_dstpolicy = match_addrselectpolicy(sa, &policyhead);
set_source(&aio[i], &policyhead); set_source(&aio[i], &policyhead);
aio[i].aio_initial_sequence = i;
} }
/* perform sorting. */ /* perform sorting. */
@ -930,7 +932,7 @@ matchlen(struct sockaddr *src, struct sockaddr *dst)
while (s < lim) while (s < lim)
if ((r = (*d++ ^ *s++)) != 0) { if ((r = (*d++ ^ *s++)) != 0) {
while (r < addrlen * 8) { while ((r & 0x80) == 0) {
match++; match++;
r <<= 1; r <<= 1;
} }
@ -1047,6 +1049,23 @@ comp_dst(const void *arg1, const void *arg2)
} }
/* Rule 10: Otherwise, leave the order unchanged. */ /* 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); return(-1);
} }

View File

@ -143,8 +143,11 @@ fgetln(FILE *fp, size_t *lenp)
(void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
len - off); len - off);
off = len; off = len;
if (__srefill(fp)) if (__srefill(fp)) {
break; /* EOF or error: return partial line */ if (__sfeof(fp))
break;
goto error;
}
if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL) if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL)
continue; continue;

View File

@ -1778,6 +1778,7 @@ pfkey_align(msg, mhp)
case SADB_EXT_SPIRANGE: case SADB_EXT_SPIRANGE:
case SADB_X_EXT_POLICY: case SADB_X_EXT_POLICY:
case SADB_X_EXT_SA2: case SADB_X_EXT_SA2:
case SADB_X_EXT_SA_REPLAY:
mhp[ext->sadb_ext_type] = (caddr_t)ext; mhp[ext->sadb_ext_type] = (caddr_t)ext;
break; break;
case SADB_X_EXT_NAT_T_TYPE: case SADB_X_EXT_NAT_T_TYPE:

View File

@ -221,6 +221,7 @@ pfkey_sadump(m)
struct sadb_key *m_auth, *m_enc; struct sadb_key *m_auth, *m_enc;
struct sadb_ident *m_sid, *m_did; struct sadb_ident *m_sid, *m_did;
struct sadb_sens *m_sens; struct sadb_sens *m_sens;
struct sadb_x_sa_replay *m_sa_replay;
/* check pfkey message. */ /* check pfkey message. */
if (pfkey_align(m, mhp)) { if (pfkey_align(m, mhp)) {
@ -245,6 +246,7 @@ pfkey_sadump(m)
m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC]; m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC];
m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST]; m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST];
m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY]; 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 */ /* source address */
if (m_saddr == NULL) { if (m_saddr == NULL) {
@ -308,7 +310,8 @@ pfkey_sadump(m)
/* replay windoe size & flags */ /* replay windoe size & flags */
printf("\tseq=0x%08x replay=%u flags=0x%08x ", printf("\tseq=0x%08x replay=%u flags=0x%08x ",
m_sa2->sadb_x_sa2_sequence, 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); m_sa->sadb_sa_flags);
/* state */ /* state */

View File

@ -32,9 +32,6 @@
#include <rtems/bsd/sys/cpuset.h> #include <rtems/bsd/sys/cpuset.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/uma.h> #include <vm/uma.h>
#include <vm/uma_int.h> #include <vm/uma_int.h>

View File

@ -104,6 +104,8 @@ read_client_conf(void)
[top_level_config.requested_option_count++] = DHO_HOST_NAME; [top_level_config.requested_option_count++] = DHO_HOST_NAME;
top_level_config.requested_options top_level_config.requested_options
[top_level_config.requested_option_count++] = DHO_DOMAIN_SEARCH; [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) { if ((cfile = fopen(path_dhclient_conf, "r")) != NULL) {
do { do {

View File

@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include "privsep.h" #include "privsep.h"
#include <sys/capsicum.h> #include <sys/capsicum.h>
#include <sys/endian.h>
#include <net80211/ieee80211_freebsd.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)) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) #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; static time_t scripttime;
int int
@ -800,9 +804,20 @@ dhcpack(struct packet *packet)
void void
bind_lease(struct interface_info *ip) bind_lease(struct interface_info *ip)
{ {
struct option_data *opt;
/* Remember the medium. */ /* Remember the medium. */
ip->client->new->medium = ip->client->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 out the new lease. */
write_client_lease(ip, ip->client->new, 0); write_client_lease(ip, ip->client->new, 0);

View File

@ -319,6 +319,8 @@ void cancel_timeout(void (*)(void *), void *);
void add_protocol(char *, int, void (*)(struct protocol *), void *); void add_protocol(char *, int, void (*)(struct protocol *), void *);
void remove_protocol(struct protocol *); void remove_protocol(struct protocol *);
int interface_link_status(char *); 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 */ /* hash.c */
struct hash_table *new_hash(void); struct hash_table *new_hash(void);

View File

@ -45,6 +45,7 @@
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#include "dhcpd.h" #include "dhcpd.h"
#include "privsep.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -107,8 +108,8 @@ discover_interfaces(struct interface_info *iface)
if (foo.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) if (foo.sin_addr.s_addr == htonl(INADDR_LOOPBACK))
continue; continue;
if (!iface->ifp) { if (!iface->ifp) {
int len = IFNAMSIZ + ifa->ifa_addr->sa_len; if ((tif = calloc(1, sizeof(struct ifreq)))
if ((tif = malloc(len)) == NULL) == NULL)
error("no space to remember ifp"); error("no space to remember ifp");
strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ); strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);
memcpy(&tif->ifr_addr, ifa->ifa_addr, memcpy(&tif->ifr_addr, ifa->ifa_addr,
@ -503,3 +504,46 @@ interface_link_status(char *ifname)
} }
return (1); 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);
}

View File

@ -113,6 +113,7 @@ dispatch_imsg(struct interface_info *ifi, int fd)
struct client_lease lease; struct client_lease lease;
int ret, i, optlen; int ret, i, optlen;
struct buf *buf; struct buf *buf;
u_int16_t mtu;
buf_read(fd, &hdr, sizeof(hdr)); buf_read(fd, &hdr, sizeof(hdr));
@ -237,6 +238,13 @@ dispatch_imsg(struct interface_info *ifi, int fd)
case IMSG_SEND_PACKET: case IMSG_SEND_PACKET:
send_packet_priv(ifi, &hdr, fd); send_packet_priv(ifi, &hdr, fd);
break; 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: default:
error("received unknown message, code %d", hdr.code); error("received unknown message, code %d", hdr.code);
} }

View File

@ -36,7 +36,8 @@ enum imsg_code {
IMSG_SCRIPT_WRITE_PARAMS, IMSG_SCRIPT_WRITE_PARAMS,
IMSG_SCRIPT_GO, IMSG_SCRIPT_GO,
IMSG_SCRIPT_GO_RET, IMSG_SCRIPT_GO_RET,
IMSG_SEND_PACKET IMSG_SEND_PACKET,
IMSG_SET_INTERFACE_MTU,
}; };
struct imsg_hdr { struct imsg_hdr {

View File

@ -402,6 +402,7 @@ unsigned char dhcp_option_default_priority_list[] = {
DHO_IRC_SERVER, DHO_IRC_SERVER,
DHO_STREETTALK_SERVER, DHO_STREETTALK_SERVER,
DHO_STREETTALK_DA_SERVER, DHO_STREETTALK_DA_SERVER,
DHO_DHCP_USER_CLASS_ID,
DHO_DOMAIN_SEARCH, DHO_DOMAIN_SEARCH,
/* Presently-undefined options... */ /* Presently-undefined options... */

View File

@ -100,7 +100,7 @@ in_status(int s __unused, const struct ifaddrs *ifa)
sin = (struct sockaddr_in *)ifa->ifa_dstaddr; sin = (struct sockaddr_in *)ifa->ifa_dstaddr;
if (sin == NULL) if (sin == NULL)
sin = &null_sin; sin = &null_sin;
printf(" --> %s ", inet_ntoa(sin->sin_addr)); printf(" --> %s", inet_ntoa(sin->sin_addr));
} }
sin = (struct sockaddr_in *)ifa->ifa_netmask; sin = (struct sockaddr_in *)ifa->ifa_netmask;

View File

@ -250,7 +250,7 @@ in6_status(int s __unused, const struct ifaddrs *ifa)
if (error != 0) if (error != 0)
inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf, inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf,
sizeof(addr_buf)); sizeof(addr_buf));
printf(" --> %s ", addr_buf); printf(" --> %s", addr_buf);
} }
} }

View File

@ -102,13 +102,24 @@ link_getaddr(const char *addr, int which)
if (which != ADDR) if (which != ADDR)
errx(1, "can't set link-level netmask or broadcast"); errx(1, "can't set link-level netmask or broadcast");
if ((temp = malloc(strlen(addr) + 2)) == NULL) if (!strcmp(addr, "random")) {
errx(1, "malloc failed"); sdl.sdl_len = sizeof(sdl);
temp[0] = ':'; sdl.sdl_alen = ETHER_ADDR_LEN;
strcpy(temp + 1, addr); sdl.sdl_nlen = 0;
sdl.sdl_len = sizeof(sdl); sdl.sdl_family = AF_LINK;
link_addr(temp, &sdl); arc4random_buf(&sdl.sdl_data, ETHER_ADDR_LEN);
free(temp); /* 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)) if (sdl.sdl_alen > sizeof(sa->sa_data))
errx(1, "malformed link-level address"); errx(1, "malformed link-level address");
sa->sa_family = AF_LINK; sa->sa_family = AF_LINK;

View File

@ -367,6 +367,8 @@ void decide_address_family(struct node_host *, sa_family_t *);
void remove_invalid_hosts(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); int invalid_redirect(struct node_host *, sa_family_t);
u_int16_t parseicmpspec(char *, 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) static TAILQ_HEAD(loadanchorshead, loadanchors)
loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead); loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead);
@ -2346,7 +2348,7 @@ pfrule : action dir logquick interface route af proto fromto
memcpy(&r.rpool.key, $5.key, memcpy(&r.rpool.key, $5.key,
sizeof(struct pf_poolhashkey)); sizeof(struct pf_poolhashkey));
} }
if (r.rt && r.rt != PF_FASTROUTE) { if (r.rt) {
decide_address_family($5.host, &r.af); decide_address_family($5.host, &r.af);
remove_invalid_hosts(&$5.host, &r.af); remove_invalid_hosts(&$5.host, &r.af);
if ($5.host == NULL) { if ($5.host == NULL) {
@ -3600,15 +3602,17 @@ icmp6type : STRING {
; ;
tos : STRING { tos : STRING {
if (!strcmp($1, "lowdelay")) int val;
$$ = IPTOS_LOWDELAY; char *end;
else if (!strcmp($1, "throughput"))
$$ = IPTOS_THROUGHPUT; if (map_tos($1, &val))
else if (!strcmp($1, "reliability")) $$ = val;
$$ = IPTOS_RELIABILITY; else if ($1[0] == '0' && $1[1] == 'x') {
else if ($1[0] == '0' && $1[1] == 'x') errno = 0;
$$ = strtoul($1, NULL, 16); $$ = strtoul($1, &end, 16);
else if (errno || *end != '\0')
$$ = 256;
} else
$$ = 256; /* flag bad argument */ $$ = 256; /* flag bad argument */
if ($$ < 0 || $$ > 255) { if ($$ < 0 || $$ > 255) {
yyerror("illegal tos value %s", $1); yyerror("illegal tos value %s", $1);
@ -4432,8 +4436,9 @@ route : /* empty */ {
$$.pool_opts = 0; $$.pool_opts = 0;
} }
| FASTROUTE { | FASTROUTE {
/* backwards-compat */
$$.host = NULL; $$.host = NULL;
$$.rt = PF_FASTROUTE; $$.rt = 0;
$$.pool_opts = 0; $$.pool_opts = 0;
} }
| ROUTETO routespec pool_opts { | ROUTETO routespec pool_opts {
@ -6269,6 +6274,57 @@ pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
return (0); 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 int
rt_tableid_max(void) rt_tableid_max(void)
{ {

View File

@ -1364,7 +1364,7 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pf_rule *r, int depth)
else else
snprintf(&path[len], MAXPATHLEN - len, snprintf(&path[len], MAXPATHLEN - len,
"%s", r->anchor->name); "%s", r->anchor->name);
name = path; name = r->anchor->name;
} else } else
name = r->anchor->path; name = r->anchor->path;
} else } else

View File

@ -103,7 +103,7 @@ TAILQ_HEAD(superblocks, superblock);
* Description of the PF rule structure. * Description of the PF rule structure.
*/ */
enum { 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 */ BREAK, /* the field may not differ between rules in a superblock */
NOMERGE, /* the field may not differ between rules when combined */ NOMERGE, /* the field may not differ between rules when combined */
COMBINED, /* the field may itself be combined with other rules */ 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 * superblock. Thus it will not be optimized. It also prevents the
* rule from being re-ordered at all. * rule from being re-ordered at all.
*/ */

View File

@ -790,12 +790,8 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose, int numeric)
printf(" reply-to"); printf(" reply-to");
else if (r->rt == PF_DUPTO) else if (r->rt == PF_DUPTO)
printf(" dup-to"); printf(" dup-to");
else if (r->rt == PF_FASTROUTE) printf(" ");
printf(" fastroute"); print_pool(&r->rpool, 0, 0, r->af, PF_PASS);
if (r->rt != PF_FASTROUTE) {
printf(" ");
print_pool(&r->rpool, 0, 0, r->af, PF_PASS);
}
} }
if (r->af) { if (r->af) {
if (r->af == AF_INET) if (r->af == AF_INET)

View File

@ -677,9 +677,6 @@ S_vmtotal(size_t l2, void *p)
} }
#ifdef __amd64__ #ifdef __amd64__
#define efi_next_descriptor(ptr, size) \
((struct efi_md *)(((uint8_t *) ptr) + size))
static int static int
S_efi_map(size_t l2, void *p) S_efi_map(size_t l2, void *p)
{ {

View File

@ -60,7 +60,7 @@ breakpoint(void)
struct cpu_functions { struct cpu_functions {
/* CPU functions */ /* CPU functions */
#if __ARM_ARCH < 6
void (*cf_cpwait) (void); void (*cf_cpwait) (void);
/* MMU functions */ /* MMU functions */
@ -140,6 +140,7 @@ struct cpu_functions {
void (*cf_idcache_inv_all) (void); void (*cf_idcache_inv_all) (void);
void (*cf_idcache_wbinv_all) (void); void (*cf_idcache_wbinv_all) (void);
void (*cf_idcache_wbinv_range) (vm_offset_t, vm_size_t); void (*cf_idcache_wbinv_range) (vm_offset_t, vm_size_t);
#endif
void (*cf_l2cache_wbinv_all) (void); void (*cf_l2cache_wbinv_all) (void);
void (*cf_l2cache_wbinv_range) (vm_offset_t, vm_size_t); void (*cf_l2cache_wbinv_range) (vm_offset_t, vm_size_t);
void (*cf_l2cache_inv_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 */ /* Other functions */
#if __ARM_ARCH < 6
void (*cf_drain_writebuf) (void); void (*cf_drain_writebuf) (void);
#endif
void (*cf_sleep) (int mode); void (*cf_sleep) (int mode);
#if __ARM_ARCH < 6
/* Soft functions */ /* Soft functions */
void (*cf_context_switch) (void); void (*cf_context_switch) (void);
#endif
void (*cf_setup) (void); void (*cf_setup) (void);
}; };
@ -164,10 +169,8 @@ extern u_int cputype;
#if __ARM_ARCH < 6 #if __ARM_ARCH < 6
#define cpu_cpwait() cpufuncs.cf_cpwait() #define cpu_cpwait() cpufuncs.cf_cpwait()
#endif
#define cpu_control(c, e) cpufuncs.cf_control(c, e) #define cpu_control(c, e) cpufuncs.cf_control(c, e)
#if __ARM_ARCH < 6
#define cpu_setttb(t) cpufuncs.cf_setttb(t) #define cpu_setttb(t) cpufuncs.cf_setttb(t)
#define cpu_tlb_flushID() cpufuncs.cf_tlb_flushID() #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_all() cpufuncs.cf_idcache_wbinv_all()
#define cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s)) #define cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s))
#endif #endif
#define cpu_l2cache_wbinv_all() cpufuncs.cf_l2cache_wbinv_all() #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_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)) #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) #if defined(CPU_MV_PJ4B)
void armv6_idcache_wbinv_all (void); void armv6_idcache_wbinv_all (void);
#endif #endif
#if defined(CPU_MV_PJ4B) || defined(CPU_CORTEXA) || defined(CPU_KRAIT) #if defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || \
void armv7_setttb (u_int); defined(CPU_MV_PJ4B) || defined(CPU_KRAIT)
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);
void armv7_idcache_wbinv_all (void); 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_cpu_sleep (int);
void armv7_setup (void); void armv7_setup (void);
void armv7_context_switch (void);
void armv7_drain_writebuf (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); void cortexa_setup (void);
#endif #endif
@ -303,26 +293,8 @@ void pj4bv7_setup (void);
#endif #endif
#if defined(CPU_ARM1176) #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 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_setup (void);
void arm11x6_sleep (int); /* no ref. for errata */ void arm11x6_sleep (int); /* no ref. for errata */
#endif #endif

View File

@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
#include <machine/stdarg.h> #include <machine/stdarg.h>
#ifndef __rtems__ #ifndef __rtems__
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
#endif /* __rtems__ */ #endif /* __rtems__ */
@ -639,8 +638,8 @@ zy7_slcr_attach(device_t dev)
/* Derive PLL frequencies from PS_CLK. */ /* Derive PLL frequencies from PS_CLK. */
#ifndef __rtems__ #ifndef __rtems__
node = ofw_bus_get_node(dev); node = ofw_bus_get_node(dev);
if (OF_getprop(node, "clock-frequency", &cell, sizeof(cell)) > 0) if (OF_getencprop(node, "clock-frequency", &cell, sizeof(cell)) > 0)
ps_clk_frequency = fdt32_to_cpu(cell); ps_clk_frequency = cell;
else else
#endif /* __rtems__ */ #endif /* __rtems__ */
ps_clk_frequency = ZYNQ_DEFAULT_PS_CLK_FREQUENCY; ps_clk_frequency = ZYNQ_DEFAULT_PS_CLK_FREQUENCY;

View File

@ -294,7 +294,7 @@ typedef enum {
/* SIM ready to take more commands */ /* SIM ready to take more commands */
CAM_RELEASE_SIMQ = 0x100, CAM_RELEASE_SIMQ = 0x100,
/* SIM has this command in it's queue */ /* SIM has this command in its queue */
CAM_SIM_QUEUED = 0x200, CAM_SIM_QUEUED = 0x200,
/* Quality of service data is valid */ /* Quality of service data is valid */

View File

@ -757,6 +757,9 @@ struct ccb_scsiio {
#define CAM_TAG_ACTION_NONE 0x00 #define CAM_TAG_ACTION_NONE 0x00
u_int tag_id; /* tag id from initator (target mode) */ u_int tag_id; /* tag id from initator (target mode) */
u_int init_id; /* initiator id of who selected */ 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__ #ifdef __rtems__
int readop; int readop;
rtems_blkdev_sg_buffer *sg_current; 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->sense_len = sense_len;
csio->cdb_len = cdb_len; csio->cdb_len = cdb_len;
csio->tag_action = tag_action; csio->tag_action = tag_action;
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
csio->bio = NULL;
#endif
} }
static __inline void static __inline void

View File

@ -166,7 +166,6 @@ void cam_periph_unmapmem(union ccb *ccb,
struct cam_periph_map_info *mapinfo); struct cam_periph_map_info *mapinfo);
union ccb *cam_periph_getccb(struct cam_periph *periph, union ccb *cam_periph_getccb(struct cam_periph *periph,
u_int32_t priority); u_int32_t priority);
void cam_periph_ccbwait(union ccb *ccb);
int cam_periph_runccb(union ccb *ccb, int cam_periph_runccb(union ccb *ccb,
int (*error_routine)(union ccb *ccb, int (*error_routine)(union ccb *ccb,
cam_flags camflags, cam_flags camflags,

View File

@ -1063,7 +1063,7 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x00, 0x1C, SS_RDEF, /* XXX TBD */ { SST(0x00, 0x1C, SS_RDEF, /* XXX TBD */
"Verify operation in progress") }, "Verify operation in progress") },
/* DT B */ /* DT B */
{ SST(0x00, 0x1D, SS_RDEF, /* XXX TBD */ { SST(0x00, 0x1D, SS_NOP,
"ATA pass through information available") }, "ATA pass through information available") },
/* DT R MAEBKV */ /* DT R MAEBKV */
{ SST(0x00, 0x1E, SS_RDEF, /* XXX TBD */ { 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 */ { SST(0x00, 0x1F, SS_RDEF, /* XXX TBD */
"Logical unit transitioning to another power condition") }, "Logical unit transitioning to another power condition") },
/* DT P B */ /* DT P B */
{ SST(0x00, 0x20, SS_RDEF, /* XXX TBD */ { SST(0x00, 0x20, SS_NOP,
"Extended copy information available") }, "Extended copy information available") },
/* D */ /* D */
{ SST(0x00, 0x21, SS_RDEF, /* XXX TBD */ { SST(0x00, 0x21, SS_RDEF, /* XXX TBD */
@ -2338,7 +2338,7 @@ static struct asc_table_entry asc_table[] = {
{ SST(0x43, 0x00, SS_RDEF, { SST(0x43, 0x00, SS_RDEF,
"Message error") }, "Message error") },
/* DTLPWROMAEBKVF */ /* DTLPWROMAEBKVF */
{ SST(0x44, 0x00, SS_RDEF, { SST(0x44, 0x00, SS_FATAL | EIO,
"Internal target failure") }, "Internal target failure") },
/* DT P MAEBKVF */ /* DT P MAEBKVF */
{ SST(0x44, 0x01, SS_RDEF, /* XXX TBD */ { 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 */ { SST(0x74, 0x6F, SS_RDEF, /* XXX TBD */
"External data encryption control error") }, "External data encryption control error") },
/* DT R M E V */ /* DT R M E V */
{ SST(0x74, 0x71, SS_RDEF, /* XXX TBD */ { SST(0x74, 0x71, SS_FATAL | EACCES,
"Logical unit access not authorized") }, "Logical unit access not authorized") },
/* D */ /* D */
{ SST(0x74, 0x79, SS_RDEF, /* XXX TBD */ { SST(0x74, 0x79, SS_FATAL | EACCES,
"Security conflict in translated device") } "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); 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 * Generic sense descriptor printing routine. This is used when we have
* not yet implemented a specific printing routine for this descriptor. * 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_FRU, scsi_sense_fru_sbuf},
{SSD_DESC_STREAM, scsi_sense_stream_sbuf}, {SSD_DESC_STREAM, scsi_sense_stream_sbuf},
{SSD_DESC_BLOCK, scsi_sense_block_sbuf}, {SSD_DESC_BLOCK, scsi_sense_block_sbuf},
{SSD_DESC_ATA, scsi_sense_ata_sbuf},
{SSD_DESC_PROGRESS, scsi_sense_progress_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); 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 void
scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries, scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *), 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); 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 * Syncronize the media to the contents of the cache for
* the given lba/count pair. Specifying 0/0 means sync * the given lba/count pair. Specifying 0/0 means sync

View File

@ -702,7 +702,9 @@ struct scsi_control_page {
struct scsi_control_ext_page { struct scsi_control_ext_page {
uint8_t page_code; uint8_t page_code;
#define SCEP_PAGE_CODE 0x0a
uint8_t subpage_code; uint8_t subpage_code;
#define SCEP_SUBPAGE_CODE 0x01
uint8_t page_length[2]; uint8_t page_length[2];
uint8_t flags; uint8_t flags;
#define SCEP_TCMOS 0x04 /* Timestamp Changeable by */ #define SCEP_TCMOS 0x04 /* Timestamp Changeable by */
@ -2971,6 +2973,31 @@ struct scsi_target_group
uint8_t control; 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 { struct scsi_target_port_descriptor {
uint8_t reserved[2]; uint8_t reserved[2];
uint8_t relative_target_port_identifier[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, u_int sense_len, uint8_t *cdb, int cdb_len,
struct scsi_inquiry_data *inq_data, struct scsi_inquiry_data *inq_data,
struct scsi_sense_desc_header *header); 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, void scsi_sense_generic_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
u_int sense_len, uint8_t *cdb, int cdb_len, u_int sense_len, uint8_t *cdb, int cdb_len,
struct scsi_inquiry_data *inq_data, 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 alloc_len, u_int8_t sense_len,
u_int32_t timeout); 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 scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, void (*cbfcnp)(struct cam_periph *,
union ccb *), u_int8_t tag_action, void *buf, union ccb *), u_int8_t tag_action, void *buf,
u_int32_t alloc_len, u_int8_t sense_len, u_int32_t alloc_len, u_int8_t sense_len,
u_int32_t timeout); 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, void scsi_synchronize_cache(struct ccb_scsiio *csio,
u_int32_t retries, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, void (*cbfcnp)(struct cam_periph *,

View File

@ -61,7 +61,7 @@ typedef struct sha1_ctxt SHA1_CTX;
extern void sha1_init(struct sha1_ctxt *); extern void sha1_init(struct sha1_ctxt *);
extern void sha1_pad(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_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 */ /* compatibilty with other SHA1 source codes */
#define SHA1Init(x) sha1_init((x)) #define SHA1Init(x) sha1_init((x))

View File

@ -59,6 +59,12 @@ __BEGIN_DECLS
#ifndef SHA256_End #ifndef SHA256_End
#define SHA256_End _libmd_SHA256_End #define SHA256_End _libmd_SHA256_End
#endif #endif
#ifndef SHA256_Fd
#define SHA256_Fd _libmd_SHA256_Fd
#endif
#ifndef SHA256_FdChunk
#define SHA256_FdChunk _libmd_SHA256_FdChunk
#endif
#ifndef SHA256_File #ifndef SHA256_File
#define SHA256_File _libmd_SHA256_File #define SHA256_File _libmd_SHA256_File
#endif #endif
@ -78,10 +84,13 @@ __BEGIN_DECLS
void SHA256_Init(SHA256_CTX *); void SHA256_Init(SHA256_CTX *);
void SHA256_Update(SHA256_CTX *, const void *, size_t); 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 #ifndef _KERNEL
char *SHA256_End(SHA256_CTX *, char *); char *SHA256_End(SHA256_CTX *, char *);
char *SHA256_Data(const void *, unsigned int, 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_File(const char *, char *);
char *SHA256_FileChunk(const char *, char *, off_t, off_t); char *SHA256_FileChunk(const char *, char *, off_t, off_t);
#endif #endif

View File

@ -58,6 +58,12 @@ __BEGIN_DECLS
#ifndef SHA384_End #ifndef SHA384_End
#define SHA384_End _libmd_SHA384_End #define SHA384_End _libmd_SHA384_End
#endif #endif
#ifndef SHA384_Fd
#define SHA384_Fd _libmd_SHA384_Fd
#endif
#ifndef SHA384_FdChunk
#define SHA384_FdChunk _libmd_SHA384_FdChunk
#endif
#ifndef SHA384_File #ifndef SHA384_File
#define SHA384_File _libmd_SHA384_File #define SHA384_File _libmd_SHA384_File
#endif #endif
@ -74,10 +80,13 @@ __BEGIN_DECLS
void SHA384_Init(SHA384_CTX *); void SHA384_Init(SHA384_CTX *);
void SHA384_Update(SHA384_CTX *, const void *, size_t); 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 #ifndef _KERNEL
char *SHA384_End(SHA384_CTX *, char *); char *SHA384_End(SHA384_CTX *, char *);
char *SHA384_Data(const void *, unsigned int, 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_File(const char *, char *);
char *SHA384_FileChunk(const char *, char *, off_t, off_t); char *SHA384_FileChunk(const char *, char *, off_t, off_t);
#endif #endif

View File

@ -58,6 +58,12 @@ __BEGIN_DECLS
#ifndef SHA512_End #ifndef SHA512_End
#define SHA512_End _libmd_SHA512_End #define SHA512_End _libmd_SHA512_End
#endif #endif
#ifndef SHA512_Fd
#define SHA512_Fd _libmd_SHA512_Fd
#endif
#ifndef SHA512_FdChunk
#define SHA512_FdChunk _libmd_SHA512_FdChunk
#endif
#ifndef SHA512_File #ifndef SHA512_File
#define SHA512_File _libmd_SHA512_File #define SHA512_File _libmd_SHA512_File
#endif #endif
@ -77,10 +83,13 @@ __BEGIN_DECLS
void SHA512_Init(SHA512_CTX *); void SHA512_Init(SHA512_CTX *);
void SHA512_Update(SHA512_CTX *, const void *, size_t); 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 #ifndef _KERNEL
char *SHA512_End(SHA512_CTX *, char *); char *SHA512_End(SHA512_CTX *, char *);
char *SHA512_Data(const void *, unsigned int, 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_File(const char *, char *);
char *SHA512_FileChunk(const char *, char *, off_t, off_t); char *SHA512_FileChunk(const char *, char *, off_t, off_t);
#endif #endif

View File

@ -55,6 +55,12 @@ __BEGIN_DECLS
#ifndef SHA512_224_End #ifndef SHA512_224_End
#define SHA512_224_End _libmd_SHA512_224_End #define SHA512_224_End _libmd_SHA512_224_End
#endif #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 #ifndef SHA512_224_File
#define SHA512_224_File _libmd_SHA512_224_File #define SHA512_224_File _libmd_SHA512_224_File
#endif #endif
@ -84,6 +90,12 @@ __BEGIN_DECLS
#ifndef SHA512_256_End #ifndef SHA512_256_End
#define SHA512_256_End _libmd_SHA512_256_End #define SHA512_256_End _libmd_SHA512_256_End
#endif #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 #ifndef SHA512_256_File
#define SHA512_256_File _libmd_SHA512_256_File #define SHA512_256_File _libmd_SHA512_256_File
#endif #endif
@ -103,19 +115,25 @@ __BEGIN_DECLS
void SHA512_224_Init(SHA512_CTX *); void SHA512_224_Init(SHA512_CTX *);
void SHA512_224_Update(SHA512_CTX *, const void *, size_t); 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 #ifndef _KERNEL
char *SHA512_224_End(SHA512_CTX *, char *); char *SHA512_224_End(SHA512_CTX *, char *);
char *SHA512_224_Data(const void *, unsigned int, 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_File(const char *, char *);
char *SHA512_224_FileChunk(const char *, char *, off_t, off_t); char *SHA512_224_FileChunk(const char *, char *, off_t, off_t);
#endif #endif
void SHA512_256_Init(SHA512_CTX *); void SHA512_256_Init(SHA512_CTX *);
void SHA512_256_Update(SHA512_CTX *, const void *, size_t); 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 #ifndef _KERNEL
char *SHA512_256_End(SHA512_CTX *, char *); char *SHA512_256_End(SHA512_CTX *, char *);
char *SHA512_256_Data(const void *, unsigned int, 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_File(const char *, char *);
char *SHA512_256_FileChunk(const char *, char *, off_t, off_t); char *SHA512_256_FileChunk(const char *, char *, off_t, off_t);
#endif #endif

View File

@ -68,15 +68,16 @@ typedef struct _SIPHASH_CTX {
#define SipHash24_Init(x) SipHash_InitX((x), 2, 4) #define SipHash24_Init(x) SipHash_InitX((x), 2, 4)
#define SipHash48_Init(x) SipHash_InitX((x), 4, 8) #define SipHash48_Init(x) SipHash_InitX((x), 4, 8)
void SipHash_InitX(SIPHASH_CTX *, int, int); 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_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 *); uint64_t SipHash_End(SIPHASH_CTX *);
#define SipHash24(x, y, z, i) SipHashX((x), 2, 4, (y), (z), (i)); #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)); #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 *, uint64_t SipHashX(SIPHASH_CTX *, int, int,
size_t); const uint8_t[__min_size(SIPHASH_KEY_LENGTH)], const void *, size_t);
int SipHash24_TestVectors(void); int SipHash24_TestVectors(void);

View File

@ -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 SKEIN512_Update(SKEIN512_CTX *ctx, const void *in, size_t len);
void SKEIN1024_Update(SKEIN1024_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 SKEIN256_Final(unsigned char digest[__min_size(SKEIN256_DIGEST_LENGTH)],
void SKEIN512_Final(unsigned char digest[static SKEIN512_DIGEST_LENGTH], SKEIN512_CTX *ctx); SKEIN256_CTX *ctx);
void SKEIN1024_Final(unsigned char digest[static SKEIN1024_DIGEST_LENGTH], SKEIN1024_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 #ifndef _KERNEL
char *SKEIN256_End(SKEIN256_CTX *, char *); 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 *SKEIN256_Data(const void *, unsigned int, char *);
char *SKEIN512_Data(const void *, unsigned int, char *); char *SKEIN512_Data(const void *, unsigned int, char *);
char *SKEIN1024_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 *SKEIN256_File(const char *, char *);
char *SKEIN512_File(const char *, char *); char *SKEIN512_File(const char *, char *);
char *SKEIN1024_File(const char *, char *); char *SKEIN1024_File(const char *, char *);

View File

@ -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 SKEIN512_End _libmd_SKEIN512_End
#define SKEIN1024_End _libmd_SKEIN1024_End #define SKEIN1024_End _libmd_SKEIN1024_End
#endif #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 #ifndef SKEIN256_File
#define SKEIN256_File _libmd_SKEIN256_File #define SKEIN256_File _libmd_SKEIN256_File
#define SKEIN512_File _libmd_SKEIN512_File #define SKEIN512_File _libmd_SKEIN512_File

View File

@ -795,6 +795,8 @@ bfe_list_newbuf(struct bfe_softc *sc, int c)
int nsegs; int nsegs;
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (m == NULL)
return (ENOBUFS);
m->m_len = m->m_pkthdr.len = MCLBYTES; m->m_len = m->m_pkthdr.len = MCLBYTES;
if (bus_dmamap_load_mbuf_sg(sc->bfe_rxmbuf_tag, sc->bfe_rx_sparemap, if (bus_dmamap_load_mbuf_sg(sc->bfe_rxmbuf_tag, sc->bfe_rx_sparemap,

View File

@ -367,16 +367,10 @@ MODULE_DEPEND(em, netmap, 1, 1, 1);
#define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000) #define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000)
#define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024) #define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024)
#define M_TSO_LEN 66
#define MAX_INTS_PER_SEC 8000 #define MAX_INTS_PER_SEC 8000
#define DEFAULT_ITR (1000000000/(MAX_INTS_PER_SEC * 256)) #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 #define TSO_WORKAROUND 4
static SYSCTL_NODE(_hw, OID_AUTO, em, CTLFLAG_RD, 0, "EM driver parameters"); 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_clearhwassist(ifp);
if (if_getcapenable(ifp) & IFCAP_TXCSUM) if (if_getcapenable(ifp) & IFCAP_TXCSUM)
if_sethwassistbits(ifp, CSUM_TCP | CSUM_UDP, 0); if_sethwassistbits(ifp, CSUM_TCP | CSUM_UDP, 0);
/*
** There have proven to be problems with TSO when not if (if_getcapenable(ifp) & IFCAP_TSO4)
** at full gigabit speed, so disable the assist automatically if_sethwassistbits(ifp, CSUM_TSO, 0);
** when at lower speeds. -jfv
*/
if (if_getcapenable(ifp) & IFCAP_TSO4) {
if (adapter->link_speed == SPEED_1000)
if_sethwassistbits(ifp, CSUM_TSO, 0);
}
/* Configure for OS presence */ /* Configure for OS presence */
em_init_manageability(adapter); em_init_manageability(adapter);
@ -2415,6 +2403,18 @@ em_update_link_status(struct adapter *adapter)
if (link_check && (adapter->link_active == 0)) { if (link_check && (adapter->link_active == 0)) {
e1000_get_speed_and_duplex(hw, &adapter->link_speed, e1000_get_speed_and_duplex(hw, &adapter->link_speed,
&adapter->link_duplex); &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 */ /* Check if we must disable SPEED_MODE bit on PCI-E */
if ((adapter->link_speed != SPEED_1000) && if ((adapter->link_speed != SPEED_1000) &&
((hw->mac.type == e1000_82571) || ((hw->mac.type == e1000_82571) ||
@ -5276,6 +5276,8 @@ em_get_wakeup(device_t dev)
case e1000_ich10lan: case e1000_ich10lan:
case e1000_pchlan: case e1000_pchlan:
case e1000_pch2lan: case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
apme_mask = E1000_WUC_APME; apme_mask = E1000_WUC_APME;
adapter->has_amt = TRUE; adapter->has_amt = TRUE;
eeprom_data = E1000_READ_REG(&adapter->hw, E1000_WUC); 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); struct adapter *adapter = device_get_softc(dev);
if_t ifp = adapter->ifp; if_t ifp = adapter->ifp;
u32 pmc, ctrl, ctrl_ext, rctl; u32 pmc, ctrl, ctrl_ext, rctl, wuc;
u16 status; u16 status;
if ((pci_find_cap(dev, PCIY_PMG, &pmc) != 0)) 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_READ_REG(&adapter->hw, E1000_CTRL);
ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3); ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); 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) || if ((adapter->hw.mac.type == e1000_ich8lan) ||
(adapter->hw.mac.type == e1000_pchlan) || (adapter->hw.mac.type == e1000_pchlan) ||
@ -5365,8 +5369,10 @@ em_enable_wakeup(device_t dev)
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl); E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
} }
if ((adapter->hw.mac.type == e1000_pchlan) || if ((adapter->hw.mac.type == e1000_pchlan) ||
(adapter->hw.mac.type == e1000_pch2lan)) { (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)) if (em_enable_phy_wakeup(adapter))
return; return;
} else { } else {

View File

@ -592,11 +592,20 @@ igb_attach(device_t dev)
error = EIO; error = EIO;
goto err_late; goto err_late;
} }
/* Check its sanity */
if (!igb_is_valid_ether_addr(adapter->hw.mac.addr)) { /* Check its sanity */
device_printf(dev, "Invalid MAC address\n"); if (!igb_is_valid_ether_addr(adapter->hw.mac.addr)) {
error = EIO; if (adapter->vf_ifp) {
goto err_late; 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 */ /* Setup OS specific network interface */

View File

@ -41,7 +41,6 @@
*/ */
// #define BATCH_DISPATCH // #define BATCH_DISPATCH
// #define NIC_SEND_COMBINING // #define NIC_SEND_COMBINING
// #define NIC_PARAVIRT /* enable virtio-like synchronization */
#include <rtems/bsd/local/opt_inet.h> #include <rtems/bsd/local/opt_inet.h>
#include <rtems/bsd/local/opt_inet6.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", lem_add_rx_process_limit(adapter, "batch_enable",
"driver rx batch", &adapter->batch_enable, 0); "driver rx batch", &adapter->batch_enable, 0);
#endif /* BATCH_DISPATCH */ #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 */ /* Sysctl for setting the interface flow control */
lem_set_flow_cntrl(adapter, "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; adapter->hw.mac.report_tx_early = 1;
#ifdef NIC_PARAVIRT /*
device_printf(dev, "driver supports paravirt, subdev 0x%x\n", * It seems that the descriptor DMA engine on some PCI cards
adapter->hw.subsystem_device_id); * fetches memory past the end of the last descriptor in the
if (adapter->hw.subsystem_device_id == E1000_PARA_SUBDEV) { * ring. These reads are problematic when VT-d (DMAR) busdma
uint64_t bus_addr; * is used. Allocate the scratch space to avoid getting
* faults from DMAR, by requesting scratch memory for one more
device_printf(dev, "paravirt support on dev %p\n", adapter); * descriptor.
tsize = 4096; // XXX one page for the csb */
if (lem_dma_malloc(adapter, tsize, &adapter->csb_mem, BUS_DMA_NOWAIT)) { tsize = roundup2((adapter->num_tx_desc + 1) *
device_printf(dev, "Unable to allocate csb memory\n"); sizeof(struct e1000_tx_desc), EM_DBA_ALIGN);
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);
/* Allocate Transmit Descriptor ring */ /* Allocate Transmit Descriptor ring */
if (lem_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) { if (lem_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
@ -605,8 +565,11 @@ lem_attach(device_t dev)
adapter->tx_desc_base = adapter->tx_desc_base =
(struct e1000_tx_desc *)adapter->txdma.dma_vaddr; (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 */ /* Allocate Receive Descriptor ring */
if (lem_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) { if (lem_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
@ -751,11 +714,6 @@ err_hw_init:
err_rx_desc: err_rx_desc:
lem_dma_free(adapter, &adapter->txdma); lem_dma_free(adapter, &adapter->txdma);
err_tx_desc: err_tx_desc:
#ifdef NIC_PARAVIRT
lem_dma_free(adapter, &adapter->csb_mem);
err_csb:
#endif /* NIC_PARAVIRT */
err_pci: err_pci:
if (adapter->ifp != (void *)NULL) if (adapter->ifp != (void *)NULL)
if_free(adapter->ifp); if_free(adapter->ifp);
@ -843,12 +801,6 @@ lem_detach(device_t dev)
adapter->rx_desc_base = NULL; 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); lem_release_hw_control(adapter);
free(adapter->mta, M_DEVBUF); free(adapter->mta, M_DEVBUF);
EM_TX_LOCK_DESTROY(adapter); 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 (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0); 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; 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_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 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 #ifdef NIC_SEND_COMBINING
if (adapter->sc_enable) { if (adapter->sc_enable) {
if (adapter->shadow_tdt & MIT_PENDING_INT) { if (adapter->shadow_tdt & MIT_PENDING_INT) {
@ -2088,20 +2012,6 @@ lem_local_timer(void *arg)
lem_smartspeed(adapter); 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 * We check the watchdog: the time since
* the last TX descriptor was cleaned. * 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 (adapter->num_tx_desc_avail > EM_TX_CLEANUP_THRESHOLD) {
if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE); 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) { if (adapter->num_tx_desc_avail == adapter->num_tx_desc) {
adapter->watchdog_check = FALSE; adapter->watchdog_check = FALSE;
return; return;
@ -3572,15 +3476,6 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
#ifdef BATCH_DISPATCH #ifdef BATCH_DISPATCH
struct mbuf *mh = NULL, *mt = NULL; struct mbuf *mh = NULL, *mt = NULL;
#endif /* BATCH_DISPATCH */ #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); EM_RX_LOCK(adapter);
#ifdef BATCH_DISPATCH #ifdef BATCH_DISPATCH
@ -3598,45 +3493,20 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
} }
#endif /* DEV_NETMAP */ #endif /* DEV_NETMAP */
#if 1 // XXX optimization ?
if (!((current_desc->status) & E1000_RXD_STAT_DD)) { if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
if (done != NULL) if (done != NULL)
*done = rx_sent; *done = rx_sent;
EM_RX_UNLOCK(adapter); EM_RX_UNLOCK(adapter);
return (FALSE); return (FALSE);
} }
#endif /* 0 */
while (count != 0 && if_getdrvflags(ifp) & IFF_DRV_RUNNING) { while (count != 0 && if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
struct mbuf *m = NULL; struct mbuf *m = NULL;
status = current_desc->status; status = current_desc->status;
if ((status & E1000_RXD_STAT_DD) == 0) { 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; 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; 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_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 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. */ /* Advance our pointers to the next descriptor. */
if (++i == adapter->num_rx_desc) if (++i == adapter->num_rx_desc)
i = 0; i = 0;
@ -3819,9 +3677,6 @@ discard:
/* Advance the E1000's Receive Queue #0 "Tail Pointer". */ /* Advance the E1000's Receive Queue #0 "Tail Pointer". */
if (--i < 0) if (--i < 0)
i = adapter->num_rx_desc - 1; 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); E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
if (done != NULL) if (done != NULL)
*done = rx_sent; *done = rx_sent;

View File

@ -123,6 +123,8 @@ rgephy_attach(device_t dev)
flags = 0; flags = 0;
if (mii_dev_mac_match(dev, "re")) if (mii_dev_mac_match(dev, "re"))
flags |= MIIF_PHYPRIV0; flags |= MIIF_PHYPRIV0;
else if (mii_dev_mac_match(dev, "ure"))
flags |= MIIF_PHYPRIV1;
mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0); mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0);
/* RTL8169S do not report auto-sense; add manually. */ /* RTL8169S do not report auto-sense; add manually. */
@ -295,7 +297,10 @@ rgephy_linkup(struct mii_softc *sc)
linkup++; linkup++;
} }
} else { } 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) if (reg & RL_GMEDIASTAT_LINK)
linkup++; linkup++;
} }
@ -380,7 +385,10 @@ rgephy_status(struct mii_softc *sc)
mii->mii_media_active |= IFM_HDX; mii->mii_media_active |= IFM_HDX;
} }
} else { } 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) if (bmsr & RL_GMEDIASTAT_1000MBPS)
mii->mii_media_active |= IFM_1000_T; mii->mii_media_active |= IFM_1000_T;
else if (bmsr & RL_GMEDIASTAT_100MBPS) else if (bmsr & RL_GMEDIASTAT_100MBPS)

View File

@ -199,4 +199,7 @@
#define EEELPAR_1000T 0x0004 /* link partner 1000baseT EEE capable */ #define EEELPAR_1000T 0x0004 /* link partner 1000baseT EEE capable */
#define EEELPAR_100TX 0x0002 /* link partner 100baseTX EEE capable */ #define EEELPAR_100TX 0x0002 /* link partner 100baseTX EEE capable */
/* RTL8153 */
#define URE_GMEDIASTAT 0xe908 /* media status register */
#endif /* _DEV_RGEPHY_MIIREG_H_ */ #endif /* _DEV_RGEPHY_MIIREG_H_ */

View File

@ -663,9 +663,27 @@ enum nvme_log_page {
NVME_LOG_ERROR = 0x01, NVME_LOG_ERROR = 0x01,
NVME_LOG_HEALTH_INFORMATION = 0x02, NVME_LOG_HEALTH_INFORMATION = 0x02,
NVME_LOG_FIRMWARE_SLOT = 0x03, 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 */ /* 0x80-0xBF - I/O command set specific */
NVME_LOG_RES_NOTIFICATION = 0x80,
/* 0xC0-0xFF - vendor specific */ /* 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 { struct nvme_error_information_entry {
@ -724,8 +742,11 @@ struct nvme_health_information_page {
uint64_t unsafe_shutdowns[2]; uint64_t unsafe_shutdowns[2];
uint64_t media_errors[2]; uint64_t media_errors[2];
uint64_t num_error_info_log_entries[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); } __packed __aligned(4);
struct nvme_firmware_page { struct nvme_firmware_page {
@ -740,6 +761,19 @@ struct nvme_firmware_page {
uint8_t reserved2[448]; uint8_t reserved2[448];
} __packed __aligned(4); } __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 #define NVME_TEST_MAX_THREADS 128
struct nvme_io_test { struct nvme_io_test {

View File

@ -3981,7 +3981,7 @@ pci_rescan_method(device_t dev)
if (hdrtype & PCIM_MFDEV) if (hdrtype & PCIM_MFDEV)
pcifunchigh = PCIB_MAXFUNCS(pcib); pcifunchigh = PCIB_MAXFUNCS(pcib);
for (f = 0; f <= pcifunchigh; f++) { for (f = 0; f <= pcifunchigh; f++) {
if (REG(PCIR_VENDOR, 2) == 0xfff) if (REG(PCIR_VENDOR, 2) == 0xffff)
continue; continue;
/* /*
@ -4081,6 +4081,7 @@ pci_add_child(device_t bus, struct pci_devinfo *dinfo)
pci_print_verbose(dinfo); pci_print_verbose(dinfo);
pci_add_resources(bus, dinfo->cfg.dev, 0, 0); pci_add_resources(bus, dinfo->cfg.dev, 0, 0);
pci_child_added(dinfo->cfg.dev); pci_child_added(dinfo->cfg.dev);
EVENTHANDLER_INVOKE(pci_add_device, dinfo->cfg.dev);
} }
void void
@ -4617,6 +4618,9 @@ static const struct
{PCIC_CRYPTO, PCIS_CRYPTO_ENTERTAIN, 1, "entertainment crypto"}, {PCIC_CRYPTO, PCIS_CRYPTO_ENTERTAIN, 1, "entertainment crypto"},
{PCIC_DASP, -1, 0, "dasp"}, {PCIC_DASP, -1, 0, "dasp"},
{PCIC_DASP, PCIS_DASP_DPIO, 1, "DPIO module"}, {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} {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_list *rl = &dinfo->resources;
struct resource *res; struct resource *res;
struct pci_map *pm; struct pci_map *pm;
uint16_t cmd;
pci_addr_t map, testval; pci_addr_t map, testval;
int mapsize; int mapsize;
@ -5107,8 +5112,17 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid,
device_printf(child, device_printf(child,
"Lazy allocation of %#jx bytes rid %#x type %d at %#jx\n", "Lazy allocation of %#jx bytes rid %#x type %d at %#jx\n",
count, *rid, type, rman_get_start(res)); 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); map = rman_get_start(res);
pci_write_bar(child, pm, map); pci_write_bar(child, pm, map);
/* Restore the original value of the CMD register */
pci_write_config(child, PCIR_COMMAND, cmd, 2);
out: out:
return (res); return (res);
} }
@ -5331,6 +5345,8 @@ pci_child_deleted(device_t dev, device_t child)
dinfo = device_get_ivars(child); dinfo = device_get_ivars(child);
rl = &dinfo->resources; rl = &dinfo->resources;
EVENTHANDLER_INVOKE(pci_delete_device, child);
/* Turn off access to resources we're about to free */ /* Turn off access to resources we're about to free */
if (bus_child_present(child) != 0) { if (bus_child_present(child) != 0) {
pci_write_config(child, PCIR_COMMAND, pci_read_config(child, pci_write_config(child, PCIR_COMMAND, pci_read_config(child,
@ -5908,3 +5924,165 @@ pci_find_pcie_root_port(device_t dev)
dev = pcib; 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);
}

View File

@ -885,10 +885,25 @@
#define PCIEM_ROOT_STA_PME_STATUS 0x00010000 #define PCIEM_ROOT_STA_PME_STATUS 0x00010000
#define PCIEM_ROOT_STA_PME_PEND 0x00020000 #define PCIEM_ROOT_STA_PME_PEND 0x00020000
#define PCIER_DEVICE_CAP2 0x24 #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 PCIER_DEVICE_CTL2 0x28
#define PCIEM_CTL2_COMP_TIMEOUT_VAL 0x000f #define PCIEM_CTL2_COMP_TIMO_VAL 0x000f
#define PCIEM_CTL2_COMP_TIMEOUT_DIS 0x0010 #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_ARI 0x0020
#define PCIEM_CTL2_ATOMIC_REQ_ENABLE 0x0040 #define PCIEM_CTL2_ATOMIC_REQ_ENABLE 0x0040
#define PCIEM_CTL2_ATOMIC_EGR_BLOCK 0x0080 #define PCIEM_CTL2_ATOMIC_EGR_BLOCK 0x0080

View File

@ -31,6 +31,7 @@
#define _PCIVAR_H_ #define _PCIVAR_H_
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/eventhandler.h>
/* some PCI bus constants */ /* some PCI bus constants */
#define PCI_MAXMAPS_0 6 /* max. no. of memory/port maps */ #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); 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 pcie_adjust_config(device_t dev, int reg, uint32_t mask,
uint32_t value, int width); 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 #ifdef BUS_SPACE_MAXADDR
#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF) #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); void vga_pci_unmap_bios(device_t dev, void *bios);
int vga_pci_repost(device_t dev); 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_ */ #endif /* _PCIVAR_H_ */

View File

@ -185,6 +185,8 @@ static const struct rl_type re_devs[] = {
"RealTek 810xE PCIe 10/100baseTX" }, "RealTek 810xE PCIe 10/100baseTX" },
{ RT_VENDORID, RT_DEVICEID_8168, 0, { RT_VENDORID, RT_DEVICEID_8168, 0,
"RealTek 8168/8111 B/C/CP/D/DP/E/F/G PCIe Gigabit Ethernet" }, "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, { RT_VENDORID, RT_DEVICEID_8169, 0,
"RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" }, "RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" },
{ RT_VENDORID, RT_DEVICEID_8169SC, 0, { RT_VENDORID, RT_DEVICEID_8169SC, 0,
@ -1358,15 +1360,17 @@ re_attach(device_t dev)
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
} }
/* Disable ASPM L0S/L1. */ /* Disable ASPM L0S/L1 and CLKREQ. */
if (sc->rl_expcap != 0) { if (sc->rl_expcap != 0) {
cap = pci_read_config(dev, sc->rl_expcap + cap = pci_read_config(dev, sc->rl_expcap +
PCIER_LINK_CAP, 2); PCIER_LINK_CAP, 2);
if ((cap & PCIEM_LINK_CAP_ASPM) != 0) { if ((cap & PCIEM_LINK_CAP_ASPM) != 0) {
ctl = pci_read_config(dev, sc->rl_expcap + ctl = pci_read_config(dev, sc->rl_expcap +
PCIER_LINK_CTL, 2); PCIER_LINK_CTL, 2);
if ((ctl & PCIEM_LINK_CTL_ASPMC) != 0) { if ((ctl & (PCIEM_LINK_CTL_ECPM |
ctl &= ~PCIEM_LINK_CTL_ASPMC; PCIEM_LINK_CTL_ASPMC))!= 0) {
ctl &= ~(PCIEM_LINK_CTL_ECPM |
PCIEM_LINK_CTL_ASPMC);
pci_write_config(dev, sc->rl_expcap + pci_write_config(dev, sc->rl_expcap +
PCIER_LINK_CTL, ctl, 2); PCIER_LINK_CTL, ctl, 2);
device_printf(dev, "ASPM disabled\n"); device_printf(dev, "ASPM disabled\n");

View File

@ -1158,3 +1158,8 @@ struct rl_softc {
/* US Robotics 997902 device ID */ /* US Robotics 997902 device ID */
#define USR_DEVICEID_997902 0x0116 #define USR_DEVICEID_997902 0x0116
/*
* NCube vendor ID
*/
#define NCUBE_VENDORID 0x10FF

View File

@ -137,6 +137,7 @@ struct tsec_softc {
int phyaddr; int phyaddr;
bus_space_tag_t phy_bst; bus_space_tag_t phy_bst;
bus_space_handle_t phy_bsh; bus_space_handle_t phy_bsh;
int phy_regoff;
}; };
/* interface to get/put generic objects */ /* 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_LOCK(sc) mtx_lock(&tsec_phy_mtx)
#define TSEC_PHY_UNLOCK(sc) mtx_unlock(&tsec_phy_mtx) #define TSEC_PHY_UNLOCK(sc) mtx_unlock(&tsec_phy_mtx)
#define TSEC_PHY_READ(sc, reg) \ #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) \ #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 */ /* Lock for transmitter */
#define TSEC_TRANSMIT_LOCK(sc) do { \ #define TSEC_TRANSMIT_LOCK(sc) do { \

View File

@ -100,10 +100,6 @@
GINTSTS_WKUPINT | GINTSTS_USBSUSP | GINTMSK_OTGINTMSK | \ GINTSTS_WKUPINT | GINTSTS_USBSUSP | GINTMSK_OTGINTMSK | \
GINTSTS_SESSREQINT) 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 #ifndef DWC_OTG_PHY_DEFAULT
#define DWC_OTG_PHY_DEFAULT DWC_OTG_PHY_ULPI #define DWC_OTG_PHY_DEFAULT DWC_OTG_PHY_ULPI
#endif #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"); 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, 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 #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, SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, debug, CTLFLAG_RWTUN,
&dwc_otg_debug, 0, "DWC OTG debug level"); &dwc_otg_debug, 0, "DWC OTG debug level");
@ -3891,8 +3887,13 @@ dwc_otg_init(struct dwc_otg_softc *sc)
break; break;
} }
/* select HSIC, ULPI or internal PHY mode */ if (sc->sc_phy_type == 0)
switch (dwc_otg_phy_type) { 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: case DWC_OTG_PHY_HSIC:
DWC_OTG_WRITE_4(sc, DOTG_GUSBCFG, DWC_OTG_WRITE_4(sc, DOTG_GUSBCFG,
GUSBCFG_PHYIF | GUSBCFG_PHYIF |
@ -3912,6 +3913,16 @@ dwc_otg_init(struct dwc_otg_softc *sc)
GUSBCFG_TRD_TIM_SET(5) | temp); GUSBCFG_TRD_TIM_SET(5) | temp);
DWC_OTG_WRITE_4(sc, DOTG_GOTGCTL, 0); 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); temp = DWC_OTG_READ_4(sc, DOTG_GLPMCFG);
DWC_OTG_WRITE_4(sc, DOTG_GLPMCFG, DWC_OTG_WRITE_4(sc, DOTG_GLPMCFG,
temp & ~GLPMCFG_HSIC_CONN); temp & ~GLPMCFG_HSIC_CONN);

View File

@ -191,6 +191,13 @@ struct dwc_otg_softc {
uint16_t sc_active_rx_ep; uint16_t sc_active_rx_ep;
uint16_t sc_last_frame_num; 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_timer_active;
uint8_t sc_dev_ep_max; uint8_t sc_dev_ep_max;
uint8_t sc_dev_in_ep_max; uint8_t sc_dev_in_ep_max;

View File

@ -661,7 +661,7 @@ usb_test_quirk_by_info(const struct usbd_lookup_info *info, uint16_t quirk)
if (quirk == UQ_NONE) if (quirk == UQ_NONE)
goto done; goto done;
mtx_lock(&usb_quirk_mtx); USB_MTX_LOCK(&usb_quirk_mtx);
for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) { for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) {
/* see if quirk information does not match */ /* 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 */ /* lookup quirk */
for (y = 0; y != USB_SUB_QUIRKS_MAX; y++) { for (y = 0; y != USB_SUB_QUIRKS_MAX; y++) {
if (usb_quirks[x].quirks[y] == quirk) { 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)); DPRINTF("Found quirk '%s'.\n", usb_quirkstr(quirk));
return (1); return (1);
} }
} }
} }
mtx_unlock(&usb_quirk_mtx); USB_MTX_UNLOCK(&usb_quirk_mtx);
done: done:
return (0); /* no quirk match */ return (0); /* no quirk match */
} }
@ -702,7 +702,7 @@ usb_quirk_get_entry(uint16_t vid, uint16_t pid,
{ {
uint16_t x; 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) { if ((vid | pid | lo_rev | hi_rev) == 0) {
/* all zero - special case */ /* all zero - special case */
@ -770,7 +770,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
if (y >= USB_DEV_QUIRKS_MAX) { if (y >= USB_DEV_QUIRKS_MAX) {
return (EINVAL); return (EINVAL);
} }
mtx_lock(&usb_quirk_mtx); USB_MTX_LOCK(&usb_quirk_mtx);
/* copy out data */ /* copy out data */
pgq->vid = usb_quirks[y].vid; pgq->vid = usb_quirks[y].vid;
pgq->pid = usb_quirks[y].pid; pgq->pid = usb_quirks[y].pid;
@ -779,7 +779,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
strlcpy(pgq->quirkname, strlcpy(pgq->quirkname,
usb_quirkstr(usb_quirks[y].quirks[x]), usb_quirkstr(usb_quirks[y].quirks[x]),
sizeof(pgq->quirkname)); sizeof(pgq->quirkname));
mtx_unlock(&usb_quirk_mtx); USB_MTX_UNLOCK(&usb_quirk_mtx);
return (0); /* success */ return (0); /* success */
case USB_QUIRK_NAME_GET: case USB_QUIRK_NAME_GET:
@ -812,11 +812,11 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
if (y == UQ_NONE) { if (y == UQ_NONE) {
return (EINVAL); return (EINVAL);
} }
mtx_lock(&usb_quirk_mtx); USB_MTX_LOCK(&usb_quirk_mtx);
pqe = usb_quirk_get_entry(pgq->vid, pgq->pid, pqe = usb_quirk_get_entry(pgq->vid, pgq->pid,
pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 1); pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 1);
if (pqe == NULL) { if (pqe == NULL) {
mtx_unlock(&usb_quirk_mtx); USB_MTX_UNLOCK(&usb_quirk_mtx);
return (EINVAL); return (EINVAL);
} }
for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) { for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) {
@ -825,7 +825,7 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
break; break;
} }
} }
mtx_unlock(&usb_quirk_mtx); USB_MTX_UNLOCK(&usb_quirk_mtx);
if (x == USB_SUB_QUIRKS_MAX) { if (x == USB_SUB_QUIRKS_MAX) {
return (ENOMEM); return (ENOMEM);
} }
@ -850,11 +850,11 @@ usb_quirk_ioctl(unsigned long cmd, caddr_t data,
if (y == UQ_NONE) { if (y == UQ_NONE) {
return (EINVAL); return (EINVAL);
} }
mtx_lock(&usb_quirk_mtx); USB_MTX_LOCK(&usb_quirk_mtx);
pqe = usb_quirk_get_entry(pgq->vid, pgq->pid, pqe = usb_quirk_get_entry(pgq->vid, pgq->pid,
pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 0); pgq->bcdDeviceLow, pgq->bcdDeviceHigh, 0);
if (pqe == NULL) { if (pqe == NULL) {
mtx_unlock(&usb_quirk_mtx); USB_MTX_UNLOCK(&usb_quirk_mtx);
return (EINVAL); return (EINVAL);
} }
for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) { 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) { if (x == USB_SUB_QUIRKS_MAX) {
mtx_unlock(&usb_quirk_mtx); USB_MTX_UNLOCK(&usb_quirk_mtx);
return (ENOMEM); return (ENOMEM);
} }
for (x = 0; x != USB_SUB_QUIRKS_MAX; x++) { 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 */ /* all quirk entries are unused - release */
memset(pqe, 0, sizeof(*pqe)); memset(pqe, 0, sizeof(*pqe));
} }
mtx_unlock(&usb_quirk_mtx); USB_MTX_UNLOCK(&usb_quirk_mtx);
return (0); /* success */ return (0); /* success */
default: 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", printf("%s: Too many USB quirks, only %d allowed!\n",
name, USB_SUB_QUIRKS_MAX); 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, new = usb_quirk_get_entry(entry.vid, entry.pid,
entry.lo_rev, entry.hi_rev, 1); entry.lo_rev, entry.hi_rev, 1);
if (new == NULL) if (new == NULL)
printf("%s: USB quirks table is full!\n", name); printf("%s: USB quirks table is full!\n", name);
else else
memcpy(new->quirks, entry.quirks, sizeof(entry.quirks)); memcpy(new->quirks, entry.quirks, sizeof(entry.quirks));
mtx_unlock(&usb_quirk_mtx); USB_MTX_UNLOCK(&usb_quirk_mtx);
} else { } else {
printf("%s: No USB quirks found!\n", name); printf("%s: No USB quirks found!\n", name);
} }

View File

@ -1149,7 +1149,7 @@ umass_cancel_ccb(struct umass_softc *sc)
{ {
union ccb *ccb; union ccb *ccb;
mtx_assert(&sc->sc_mtx, MA_OWNED); USB_MTX_ASSERT(&sc->sc_mtx, MA_OWNED);
ccb = sc->sc_transfer.ccb; ccb = sc->sc_transfer.ccb;
sc->sc_transfer.ccb = NULL; sc->sc_transfer.ccb = NULL;

View File

@ -510,7 +510,7 @@ usb_pc_common_mem_cb(void *arg, bus_dma_segment_t *segs,
done: done:
owned = mtx_owned(uptag->mtx); owned = mtx_owned(uptag->mtx);
if (!owned) if (!owned)
mtx_lock(uptag->mtx); USB_MTX_LOCK(uptag->mtx);
uptag->dma_error = (error ? 1 : 0); uptag->dma_error = (error ? 1 : 0);
if (isload) { if (isload) {
@ -519,7 +519,7 @@ done:
cv_broadcast(uptag->cv); cv_broadcast(uptag->cv);
} }
if (!owned) 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->tag = utag->tag;
pc->ismultiseg = (align == 1); pc->ismultiseg = (align == 1);
mtx_lock(uptag->mtx); USB_MTX_LOCK(uptag->mtx);
/* load memory into DMA */ /* load memory into DMA */
err = bus_dmamap_load( 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); cv_wait(uptag->cv, uptag->mtx);
err = 0; err = 0;
} }
mtx_unlock(uptag->mtx); USB_MTX_UNLOCK(uptag->mtx);
if (err || uptag->dma_error) { if (err || uptag->dma_error) {
bus_dmamem_free(utag->tag, ptr, map); 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->page_offset_end = size;
pc->ismultiseg = 1; pc->ismultiseg = 1;
mtx_assert(pc->tag_parent->mtx, MA_OWNED); USB_MTX_ASSERT(pc->tag_parent->mtx, MA_OWNED);
if (size > 0) { if (size > 0) {
if (sync) { if (sync) {
@ -919,7 +919,7 @@ usb_bdma_work_loop(struct usb_xfer_queue *pq)
xfer = pq->curr; xfer = pq->curr;
info = xfer->xroot; info = xfer->xroot;
mtx_assert(info->xfer_mtx, MA_OWNED); USB_MTX_ASSERT(info->xfer_mtx, MA_OWNED);
if (xfer->error) { if (xfer->error) {
/* some error happened */ /* some error happened */
@ -1043,7 +1043,7 @@ usb_bdma_done_event(struct usb_dma_parent_tag *udpt)
info = USB_DMATAG_TO_XROOT(udpt); info = USB_DMATAG_TO_XROOT(udpt);
mtx_assert(info->xfer_mtx, MA_OWNED); USB_MTX_ASSERT(info->xfer_mtx, MA_OWNED);
/* copy error */ /* copy error */
info->dma_error = udpt->dma_error; info->dma_error = udpt->dma_error;

View File

@ -53,6 +53,8 @@
#include <sys/callout.h> #include <sys/callout.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <sys/priv.h> #include <sys/priv.h>
#include <sys/proc.h>
#include <sys/kdb.h>
#include <dev/usb/usb.h> #include <dev/usb/usb.h>
#include <dev/usb/usbdi.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_USB, "USB", "USB");
MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device"); 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); MODULE_VERSION(usb, 1);

View File

@ -39,17 +39,20 @@
USB_MODE_DEVICE ? (((xfer)->endpointno & UE_DIR_IN) ? 0 : 1) : \ USB_MODE_DEVICE ? (((xfer)->endpointno & UE_DIR_IN) ? 0 : 1) : \
(((xfer)->endpointno & UE_DIR_IN) ? 1 : 0)) (((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) /* locking wrappers for BUS spin lock */
#define USB_BUS_UNLOCK(_b) mtx_unlock(&(_b)->bus_mtx) #define USB_BUS_SPIN_LOCK(_b) USB_MTX_LOCK_SPIN(&(_b)->bus_spin_lock)
#define USB_BUS_LOCK_ASSERT(_b, _t) mtx_assert(&(_b)->bus_mtx, _t) #define USB_BUS_SPIN_UNLOCK(_b) USB_MTX_UNLOCK_SPIN(&(_b)->bus_spin_lock)
#define USB_BUS_SPIN_LOCK(_b) mtx_lock_spin(&(_b)->bus_spin_lock) #define USB_BUS_SPIN_LOCK_ASSERT(_b, _t) USB_MTX_ASSERT(&(_b)->bus_spin_lock, _t)
#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) /* locking wrappers for XFER lock */
#define USB_XFER_LOCK(_x) mtx_lock((_x)->xroot->xfer_mtx) #define USB_XFER_LOCK(_x) USB_MTX_LOCK((_x)->xroot->xfer_mtx)
#define USB_XFER_UNLOCK(_x) mtx_unlock((_x)->xroot->xfer_mtx) #define USB_XFER_UNLOCK(_x) USB_MTX_UNLOCK((_x)->xroot->xfer_mtx)
#define USB_XFER_LOCK_ASSERT(_x, _t) mtx_assert((_x)->xroot->xfer_mtx, _t) #define USB_XFER_LOCK_ASSERT(_x, _t) USB_MTX_ASSERT((_x)->xroot->xfer_mtx, _t)
/* helper for converting pointers to integers */ /* helper for converting pointers to integers */
#define USB_P2U(ptr) \ #define USB_P2U(ptr) \

View File

@ -1161,7 +1161,7 @@ usb_filter_write(struct knote *kn, long hint)
f = kn->kn_hook; f = kn->kn_hook;
mtx_assert(f->priv_mtx, MA_OWNED); USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
cpd = f->curr_cpd; cpd = f->curr_cpd;
if (cpd == NULL) { if (cpd == NULL) {
@ -1202,7 +1202,7 @@ usb_filter_read(struct knote *kn, long hint)
f = kn->kn_hook; f = kn->kn_hook;
mtx_assert(f->priv_mtx, MA_OWNED); USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
cpd = f->curr_cpd; cpd = f->curr_cpd;
if (cpd == NULL) { if (cpd == NULL) {
@ -1732,7 +1732,7 @@ usb_fifo_wait(struct usb_fifo *f)
{ {
int err; int err;
mtx_assert(f->priv_mtx, MA_OWNED); USB_MTX_ASSERT(f->priv_mtx, MA_OWNED);
if (f->flag_iserror) { if (f->flag_iserror) {
/* we are gone */ /* we are gone */

View File

@ -1109,10 +1109,8 @@ usb_detach_device_sub(struct usb_device *udev, device_t *ppdev,
device_printf(dev, "Resume failed\n"); device_printf(dev, "Resume failed\n");
} }
} }
if (device_detach(dev)) {
goto error;
}
} }
/* detach and delete child */
if (device_delete_child(udev->parent_dev, dev)) { if (device_delete_child(udev->parent_dev, dev)) {
goto error; goto error;
} }
@ -1517,13 +1515,13 @@ usbd_clear_stall_proc(struct usb_proc_msg *_pm)
/* Change lock */ /* Change lock */
USB_BUS_UNLOCK(udev->bus); USB_BUS_UNLOCK(udev->bus);
mtx_lock(&udev->device_mtx); USB_MTX_LOCK(&udev->device_mtx);
/* Start clear stall callback */ /* Start clear stall callback */
usbd_transfer_start(udev->ctrl_xfer[1]); usbd_transfer_start(udev->ctrl_xfer[1]);
/* Change lock */ /* Change lock */
mtx_unlock(&udev->device_mtx); USB_MTX_UNLOCK(&udev->device_mtx);
USB_BUS_LOCK(udev->bus); USB_BUS_LOCK(udev->bus);
} }
@ -1591,6 +1589,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
/* initialise our SX-lock */ /* initialise our SX-lock */
sx_init_flags(&udev->enum_sx, "USB config SX lock", SX_DUPOK); 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->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->ctrlreq_cv, "WCTRL");
cv_init(&udev->ref_cv, "UGONE"); cv_init(&udev->ref_cv, "UGONE");
@ -1776,7 +1775,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
*/ */
/* Protect scratch area */ /* Protect scratch area */
do_unlock = usbd_enum_lock(udev); do_unlock = usbd_ctrl_lock(udev);
scratch_ptr = udev->scratch.data; scratch_ptr = udev->scratch.data;
@ -1827,7 +1826,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
} }
if (do_unlock) if (do_unlock)
usbd_enum_unlock(udev); usbd_ctrl_unlock(udev);
/* assume 100mA bus powered for now. Changed when configured. */ /* assume 100mA bus powered for now. Changed when configured. */
udev->power = USB_MIN_POWER; udev->power = USB_MIN_POWER;
@ -1945,8 +1944,8 @@ config_done:
udev->ugen_symlink = usb_alloc_symlink(udev->ugen_name); udev->ugen_symlink = usb_alloc_symlink(udev->ugen_name);
/* Announce device */ /* Announce device */
printf("%s: <%s> at %s\n", udev->ugen_name, printf("%s: <%s %s> at %s\n", udev->ugen_name,
usb_get_manufacturer(udev), usb_get_manufacturer(udev), usb_get_product(udev),
device_get_nameunit(udev->bus->bdev)); device_get_nameunit(udev->bus->bdev));
#endif #endif
@ -2155,8 +2154,9 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
#if USB_HAVE_UGEN #if USB_HAVE_UGEN
if (!rebooting) { if (!rebooting) {
printf("%s: <%s> at %s (disconnected)\n", udev->ugen_name, printf("%s: <%s %s> at %s (disconnected)\n", udev->ugen_name,
usb_get_manufacturer(udev), device_get_nameunit(bus->bdev)); usb_get_manufacturer(udev), usb_get_product(udev),
device_get_nameunit(bus->bdev));
} }
/* Destroy UGEN symlink, if any */ /* 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->enum_sx);
sx_destroy(&udev->sr_sx); sx_destroy(&udev->sr_sx);
sx_destroy(&udev->ctrl_sx);
cv_destroy(&udev->ctrlreq_cv); cv_destroy(&udev->ctrlreq_cv);
cv_destroy(&udev->ref_cv); cv_destroy(&udev->ref_cv);
@ -2364,7 +2365,7 @@ usbd_set_device_strings(struct usb_device *udev)
uint8_t do_unlock; uint8_t do_unlock;
/* Protect scratch area */ /* Protect scratch area */
do_unlock = usbd_enum_lock(udev); do_unlock = usbd_ctrl_lock(udev);
temp_ptr = (char *)udev->scratch.data; temp_ptr = (char *)udev->scratch.data;
temp_size = sizeof(udev->scratch.data); temp_size = sizeof(udev->scratch.data);
@ -2424,7 +2425,7 @@ usbd_set_device_strings(struct usb_device *udev)
} }
if (do_unlock) 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)); 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 * The following function is used to set the per-interface specific
* plug and play information. The string referred to by the pnpinfo * plug and play information. The string referred to by the pnpinfo

View File

@ -162,7 +162,7 @@ struct usb_temp_setup {
/* /*
* The scratch area for USB devices. Access to this structure is * 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 { union usb_device_scratch {
struct usb_hw_ep_scratch hw_ep_scratch[1]; struct usb_hw_ep_scratch hw_ep_scratch[1];
@ -183,6 +183,7 @@ struct usb_device {
struct usb_udev_msg cs_msg[2]; struct usb_udev_msg cs_msg[2];
struct sx enum_sx; struct sx enum_sx;
struct sx sr_sx; struct sx sr_sx;
struct sx ctrl_sx;
struct mtx device_mtx; struct mtx device_mtx;
struct cv ctrlreq_cv; struct cv ctrlreq_cv;
struct cv ref_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_enum_unlock(struct usb_device *);
void usbd_sr_lock(struct usb_device *); void usbd_sr_lock(struct usb_device *);
void usbd_sr_unlock(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 *); uint8_t usbd_enum_is_locked(struct usb_device *);
#if USB_HAVE_TT_SUPPORT #if USB_HAVE_TT_SUPPORT

View File

@ -92,6 +92,9 @@
#define USB_MAX_AUTO_QUIRK 8 /* maximum number of dynamic quirks */ #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_timeout_t; /* milliseconds */
typedef uint32_t usb_frlength_t; /* bytes */ typedef uint32_t usb_frlength_t; /* bytes */
typedef uint32_t usb_frcount_t; /* units */ typedef uint32_t usb_frcount_t; /* units */

View File

@ -238,7 +238,7 @@ ugen_open_pipe_write(struct usb_fifo *f)
struct usb_endpoint *ep = usb_fifo_softc(f); struct usb_endpoint *ep = usb_fifo_softc(f);
struct usb_endpoint_descriptor *ed = ep->edesc; 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]) { if (f->xfer[0] || f->xfer[1]) {
/* transfers are already opened */ /* 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 *ep = usb_fifo_softc(f);
struct usb_endpoint_descriptor *ed = ep->edesc; 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]) { if (f->xfer[0] || f->xfer[1]) {
/* transfers are already opened */ /* transfers are already opened */
@ -716,16 +716,16 @@ ugen_get_cdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
return (error); return (error);
} }
/*
* This function is called having the enumeration SX locked which
* protects the scratch area used.
*/
static int static int
ugen_get_sdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd) ugen_get_sdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
{ {
void *ptr; void *ptr;
uint16_t size; uint16_t size;
int error; int error;
uint8_t do_unlock;
/* Protect scratch area */
do_unlock = usbd_ctrl_lock(f->udev);
ptr = f->udev->scratch.data; ptr = f->udev->scratch.data;
size = sizeof(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); error = copyout(ptr, ugd->ugd_data, size);
} }
if (do_unlock)
usbd_ctrl_unlock(f->udev);
return (error); return (error);
} }

View File

@ -272,11 +272,11 @@ uhub_reset_tt_proc(struct usb_proc_msg *_pm)
/* Change lock */ /* Change lock */
USB_BUS_UNLOCK(udev->bus); USB_BUS_UNLOCK(udev->bus);
mtx_lock(&sc->sc_mtx); USB_MTX_LOCK(&sc->sc_mtx);
/* Start transfer */ /* Start transfer */
usbd_transfer_start(sc->sc_xfer[UHUB_RESET_TT_TRANSFER]); usbd_transfer_start(sc->sc_xfer[UHUB_RESET_TT_TRANSFER]);
/* Change lock */ /* Change lock */
mtx_unlock(&sc->sc_mtx); USB_MTX_UNLOCK(&sc->sc_mtx);
USB_BUS_LOCK(udev->bus); USB_BUS_LOCK(udev->bus);
} }
#endif #endif
@ -1521,9 +1521,9 @@ uhub_attach(device_t dev)
/* Start the interrupt endpoint, if any */ /* 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]); 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 */ /* Enable automatic power save on all USB HUBs */

View File

@ -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); memcpy(&sc->cbw->CBWCDB, cmd_ptr, cmd_len);
DPRINTFN(1, "SCSI cmd = %*D\n", (int)cmd_len, (char *)sc->cbw->CBWCDB, ":"); 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]); usbd_transfer_start(sc->xfer[sc->state]);
while (usbd_transfer_pending(sc->xfer[sc->state])) { while (usbd_transfer_pending(sc->xfer[sc->state])) {
cv_wait(&sc->cv, &sc->mtx); cv_wait(&sc->cv, &sc->mtx);
} }
mtx_unlock(&sc->mtx); USB_MTX_UNLOCK(&sc->mtx);
return (sc->error); 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, DPRINTFN(1, "BULK DATA = %*D\n", (int)data_len,
(const char *)data_ptr, ":"); (const char *)data_ptr, ":");
mtx_lock(&sc->mtx); USB_MTX_LOCK(&sc->mtx);
usbd_transfer_start(sc->xfer[0]); usbd_transfer_start(sc->xfer[0]);
while (usbd_transfer_pending(sc->xfer[0])) while (usbd_transfer_pending(sc->xfer[0]))
cv_wait(&sc->cv, &sc->mtx); cv_wait(&sc->cv, &sc->mtx);
mtx_unlock(&sc->mtx); USB_MTX_UNLOCK(&sc->mtx);
return (sc->error); return (sc->error);
} }

View File

@ -121,7 +121,7 @@ usb_process(void *arg)
thread_unlock(td); thread_unlock(td);
#endif /* __rtems__ */ #endif /* __rtems__ */
mtx_lock(up->up_mtx); USB_MTX_LOCK(up->up_mtx);
up->up_curtd = td; up->up_curtd = td;
@ -190,7 +190,7 @@ usb_process(void *arg)
continue; 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) { if (up->up_dsleep) {
up->up_dsleep = 0; up->up_dsleep = 0;
cv_broadcast(&up->up_drain); cv_broadcast(&up->up_drain);
@ -201,7 +201,7 @@ usb_process(void *arg)
up->up_ptr = NULL; up->up_ptr = NULL;
cv_signal(&up->up_cv); cv_signal(&up->up_cv);
mtx_unlock(up->up_mtx); USB_MTX_UNLOCK(up->up_mtx);
#if (__FreeBSD_version >= 800000) #if (__FreeBSD_version >= 800000)
/* Clear the proc pointer if this is the last thread. */ /* Clear the proc pointer if this is the last thread. */
if (--usb_pcount == 0) if (--usb_pcount == 0)
@ -297,11 +297,12 @@ usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
usb_size_t d; usb_size_t d;
uint8_t t; uint8_t t;
/* check if gone, return dummy value */ /* check if gone or in polling mode, return dummy value */
if (up->up_gone) if (up->up_gone != 0 ||
USB_IN_POLLING_MODE_FUNC() != 0)
return (_pm0); return (_pm0);
mtx_assert(up->up_mtx, MA_OWNED); USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
t = 0; t = 0;
@ -382,7 +383,7 @@ usb_proc_is_gone(struct usb_process *up)
* structure is initialised. * structure is initialised.
*/ */
if (up->up_mtx != NULL) if (up->up_mtx != NULL)
mtx_assert(up->up_mtx, MA_OWNED); USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
return (0); return (0);
} }
@ -403,7 +404,7 @@ usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
if (up->up_gone) if (up->up_gone)
return; return;
mtx_assert(up->up_mtx, MA_OWNED); USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
if (up->up_curtd == curthread) { if (up->up_curtd == curthread) {
/* Just remove the messages from the queue. */ /* Just remove the messages from the queue. */
@ -443,9 +444,9 @@ usb_proc_drain(struct usb_process *up)
return; return;
/* handle special case with Giant */ /* handle special case with Giant */
if (up->up_mtx != &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 */ /* Set the gone flag */
@ -482,7 +483,7 @@ usb_proc_drain(struct usb_process *up)
DPRINTF("WARNING: Someone is waiting " DPRINTF("WARNING: Someone is waiting "
"for USB process drain!\n"); "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) if (up->up_gone)
return; return;
mtx_assert(up->up_mtx, MA_OWNED); USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
if (up->up_msleep == 0) { if (up->up_msleep == 0) {
/* re-wakeup */ /* re-wakeup */

View File

@ -457,21 +457,14 @@ usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx,
return (USB_ERR_INVAL); return (USB_ERR_INVAL);
#endif #endif
if ((mtx != NULL) && (mtx != &Giant)) { if ((mtx != NULL) && (mtx != &Giant)) {
mtx_unlock(mtx); USB_MTX_UNLOCK(mtx);
mtx_assert(mtx, MA_NOTOWNED); USB_MTX_ASSERT(mtx, MA_NOTOWNED);
} }
/* /*
* Grab the USB device enumeration SX-lock serialization is * Serialize access to this function:
* achieved when multiple threads are involved:
*/ */
do_unlock = usbd_enum_lock(udev); do_unlock = usbd_ctrl_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);
hr_func = usbd_get_hr_func(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); USB_XFER_UNLOCK(xfer);
done: done:
usbd_sr_lock(udev);
if (do_unlock) if (do_unlock)
usbd_enum_unlock(udev); usbd_ctrl_unlock(udev);
if ((mtx != NULL) && (mtx != &Giant)) if ((mtx != NULL) && (mtx != &Giant))
mtx_lock(mtx); USB_MTX_LOCK(mtx);
switch (err) { switch (err) {
case USB_ERR_NORMAL_COMPLETION: case USB_ERR_NORMAL_COMPLETION:

View File

@ -47,7 +47,6 @@
#include <sys/callout.h> #include <sys/callout.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <sys/priv.h> #include <sys/priv.h>
#include <sys/proc.h>
#include <dev/usb/usb.h> #include <dev/usb/usb.h>
#include <dev/usb/usbdi.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->buffer = USB_ADD_BYTES(buf, y * size);
pc->page_start = pg; 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 */ )) { 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 */ 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); return (error);
/* Protect scratch area */ /* Protect scratch area */
do_unlock = usbd_enum_lock(udev); do_unlock = usbd_ctrl_lock(udev);
refcount = 0; refcount = 0;
info = NULL; info = NULL;
@ -1304,7 +1303,7 @@ done:
error = parm->err; error = parm->err;
if (do_unlock) if (do_unlock)
usbd_enum_unlock(udev); usbd_ctrl_unlock(udev);
return (error); 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 * We exploit the fact that the mutex is the same for all
* callbacks that will be called from this thread: * callbacks that will be called from this thread:
*/ */
mtx_lock(info->xfer_mtx); USB_MTX_LOCK(info->xfer_mtx);
USB_BUS_LOCK(info->bus); USB_BUS_LOCK(info->bus);
/* Continue where we lost track */ /* Continue where we lost track */
usb_command_wrapper(&info->done_q, usb_command_wrapper(&info->done_q,
info->done_q.curr); 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); USB_BUS_LOCK_ASSERT(info->bus, MA_OWNED);
if ((pq->recurse_3 != 0 || mtx_owned(info->xfer_mtx) == 0) && 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: * 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_xfer_root *xroot;
struct usb_device *udev; struct usb_device *udev;
struct usb_proc_msg *pm; struct usb_proc_msg *pm;
struct usb_bus *bus;
uint16_t n; uint16_t n;
uint16_t drop_bus_spin;
uint16_t drop_bus; uint16_t drop_bus;
uint16_t drop_xfer; uint16_t drop_xfer;
@ -3348,38 +3349,47 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
udev = xroot->udev; udev = xroot->udev;
if (udev == NULL) if (udev == NULL)
continue; /* no USB device */ continue; /* no USB device */
if (udev->bus == NULL) bus = udev->bus;
if (bus == NULL)
continue; /* no BUS structure */ continue; /* no BUS structure */
if (udev->bus->methods == NULL) if (bus->methods == NULL)
continue; /* no BUS methods */ continue; /* no BUS methods */
if (udev->bus->methods->xfer_poll == NULL) if (bus->methods->xfer_poll == NULL)
continue; /* no poll method */ continue; /* no poll method */
/* make sure that the BUS mutex is not locked */ drop_bus_spin = 0;
drop_bus = 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; drop_xfer = 0;
while (mtx_owned(xroot->xfer_mtx) && !SCHEDULER_STOPPED()) {
mtx_unlock(xroot->xfer_mtx); if (USB_IN_POLLING_MODE_FUNC() == 0) {
drop_xfer++; /* 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 */ /* Make sure cv_signal() and cv_broadcast() is not called */
USB_BUS_CONTROL_XFER_PROC(udev->bus)->up_msleep = 0; USB_BUS_CONTROL_XFER_PROC(bus)->up_msleep = 0;
USB_BUS_EXPLORE_PROC(udev->bus)->up_msleep = 0; USB_BUS_EXPLORE_PROC(bus)->up_msleep = 0;
USB_BUS_GIANT_PROC(udev->bus)->up_msleep = 0; USB_BUS_GIANT_PROC(bus)->up_msleep = 0;
USB_BUS_NON_GIANT_ISOC_PROC(udev->bus)->up_msleep = 0; USB_BUS_NON_GIANT_ISOC_PROC(bus)->up_msleep = 0;
USB_BUS_NON_GIANT_BULK_PROC(udev->bus)->up_msleep = 0; USB_BUS_NON_GIANT_BULK_PROC(bus)->up_msleep = 0;
#endif
/* poll USB hardware */ /* poll USB hardware */
(udev->bus->methods->xfer_poll) (udev->bus); (bus->methods->xfer_poll) (bus);
USB_BUS_LOCK(xroot->bus); USB_BUS_LOCK(xroot->bus);
@ -3407,7 +3417,11 @@ usbd_transfer_poll(struct usb_xfer **ppxfer, uint16_t max)
/* restore BUS mutex */ /* restore BUS mutex */
while (drop_bus--) 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);
} }
} }

View File

@ -100,7 +100,7 @@ device_set_usb_desc(device_t dev)
} }
/* Protect scratch area */ /* Protect scratch area */
do_unlock = usbd_enum_lock(udev); do_unlock = usbd_ctrl_lock(udev);
temp_p = (char *)udev->scratch.data; temp_p = (char *)udev->scratch.data;
@ -117,7 +117,7 @@ device_set_usb_desc(device_t dev)
} }
if (do_unlock) if (do_unlock)
usbd_enum_unlock(udev); usbd_ctrl_unlock(udev);
device_set_desc_copy(dev, temp_p); device_set_desc_copy(dev, temp_p);
device_printf(dev, "<%s> on %s\n", temp_p, device_printf(dev, "<%s> on %s\n", temp_p,

View File

@ -434,6 +434,39 @@ struct usb_attach_arg {
#define UAA_DEV_EJECTING 2 #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 * The following is a wrapper for the callout structure to ease
* porting the code to other platforms. * porting the code to other platforms.
@ -442,8 +475,26 @@ struct usb_callout {
struct callout co; struct callout co;
}; };
#define usb_callout_init_mtx(c,m,f) callout_init_mtx(&(c)->co,m,f) #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_reset(c,...) do { \
#define usb_callout_stop(c) callout_stop(&(c)->co) 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_drain(c) callout_drain(&(c)->co)
#define usb_callout_pending(c) callout_pending(&(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); void usbd_start_re_enumerate(struct usb_device *udev);
usb_error_t usb_error_t
usbd_start_set_config(struct usb_device *, uint8_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, int usb_fifo_attach(struct usb_device *udev, void *priv_sc,
struct mtx *priv_mtx, struct usb_fifo_methods *pm, struct mtx *priv_mtx, struct usb_fifo_methods *pm,

View File

@ -65,6 +65,7 @@ void i686_pagezero(void *addr);
void sse2_pagezero(void *addr); void sse2_pagezero(void *addr);
void init_AMD_Elan_sc520(void); void init_AMD_Elan_sc520(void);
vm_paddr_t kvtop(void *addr); vm_paddr_t kvtop(void *addr);
void panicifcpuunsupported(void);
void ppro_reenable_apic(void); void ppro_reenable_apic(void);
void setidt(int idx, alias_for_inthand_t *func, int typ, int dpl, int selec); 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); union savefpu *get_pcb_user_save_td(struct thread *td);

View File

@ -215,9 +215,9 @@ void
mi_startup(void) mi_startup(void)
{ {
register struct sysinit **sipp; /* system initialization*/ struct sysinit **sipp; /* system initialization*/
register struct sysinit **xipp; /* interior loop of sort*/ struct sysinit **xipp; /* interior loop of sort*/
register struct sysinit *save; /* bubble*/ struct sysinit *save; /* bubble*/
#ifdef __rtems__ #ifdef __rtems__
struct sysinit **sysinit = NULL; struct sysinit **sysinit = NULL;
struct sysinit **sysinit_end = NULL; struct sysinit **sysinit_end = NULL;
@ -339,16 +339,7 @@ restart:
#endif /* __rtems__ */ #endif /* __rtems__ */
} }
#ifndef __rtems__ #ifndef __rtems__
/*
***************************************************************************
****
**** The following SYSINIT's belong elsewhere, but have not yet
**** been moved.
****
***************************************************************************
*/
static void static void
print_caddr_t(void *data) 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
**** The two following SYSINIT's are proc0 specific glue code. I am not * operation has been maintained as the same as the original init_main.c
**** convinced that they can not be safely combined, but their order of * for right now.
**** 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).
****
***************************************************************************
*/ */
/* ARGSUSED*/ /* ARGSUSED*/
static void 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". * 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. * We do this early to reserve pid 1.
* *
* Note special case - do not make it runnable yet. Other work * Note special case - do not make it runnable yet. Other work

View File

@ -407,6 +407,8 @@ cv_signal(struct cv *cvp)
{ {
int wakeup_swapper; int wakeup_swapper;
if (cvp->cv_waiters == 0)
return;
wakeup_swapper = 0; wakeup_swapper = 0;
sleepq_lock(cvp); sleepq_lock(cvp);
if (cvp->cv_waiters > 0) { if (cvp->cv_waiters > 0) {
@ -434,6 +436,8 @@ cv_broadcastpri(struct cv *cvp, int pri)
{ {
int wakeup_swapper; int wakeup_swapper;
if (cvp->cv_waiters == 0)
return;
/* /*
* XXX sleepq_broadcast pri argument changed from -1 meaning * XXX sleepq_broadcast pri argument changed from -1 meaning
* no pri to 0 meaning no pri. * no pri to 0 meaning no pri.

View File

@ -1615,7 +1615,6 @@ restart:
if (error) if (error)
panic("cannot add dependency"); panic("cannot add dependency");
} }
lf->userrefs++; /* so we can (try to) kldunload it */
error = linker_file_lookup_set(lf, MDT_SETNAME, &start, error = linker_file_lookup_set(lf, MDT_SETNAME, &start,
&stop, NULL); &stop, NULL);
if (!error) { if (!error) {
@ -1653,6 +1652,8 @@ restart:
goto fail; goto fail;
} }
linker_file_register_modules(lf); 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, if (linker_file_lookup_set(lf, "sysinit_set", &si_start,
&si_stop, NULL) == 0) &si_stop, NULL) == 0)
sysinit_add(si_start, si_stop); sysinit_add(si_start, si_stop);
@ -1669,6 +1670,41 @@ fail:
SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0); 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. * Search for a not-loaded module by name.
* *

View File

@ -18,7 +18,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * 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 */ 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"); 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, SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD|CTLFLAG_CAPRD,
&mp_ncpus, 0, "Number of active CPUs"); &mp_ncpus, 0, "Number of active CPUs");
@ -263,8 +266,9 @@ sysctl_hw_machine_arch(SYSCTL_HANDLER_ARGS)
return (error); return (error);
} }
SYSCTL_PROC(_hw, HW_MACHINE_ARCH, machine_arch, CTLTYPE_STRING | CTLFLAG_RD, SYSCTL_PROC(_hw, HW_MACHINE_ARCH, machine_arch, CTLTYPE_STRING | CTLFLAG_RD |
NULL, 0, sysctl_hw_machine_arch, "A", "System architecture"); CTLFLAG_MPSAFE, NULL, 0, sysctl_hw_machine_arch, "A",
"System architecture");
#endif /* __rtems__ */ #endif /* __rtems__ */
SYSCTL_STRING(_kern, OID_AUTO, supported_archs, CTLFLAG_RD | CTLFLAG_MPSAFE, 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, 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, (void *)(offsetof(struct prison, pr_hostname)), MAXHOSTNAMELEN,
sysctl_hostname, "A", "Hostname"); sysctl_hostname, "A", "Hostname");
SYSCTL_PROC(_kern, KERN_NISDOMAINNAME, domainname, 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, (void *)(offsetof(struct prison, pr_domainname)), MAXHOSTNAMELEN,
sysctl_hostname, "A", "Name of the current YP/NIS domain"); sysctl_hostname, "A", "Name of the current YP/NIS domain");
SYSCTL_PROC(_kern, KERN_HOSTUUID, hostuuid, 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, (void *)(offsetof(struct prison, pr_hostuuid)), HOSTUUIDLEN,
sysctl_hostname, "A", "Host UUID"); sysctl_hostname, "A", "Host UUID");
@ -407,8 +411,8 @@ SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel,
/* Actual kernel configuration options. */ /* Actual kernel configuration options. */
extern char kernconfstring[]; extern char kernconfstring[];
SYSCTL_STRING(_kern, OID_AUTO, conftxt, CTLFLAG_RD, kernconfstring, 0, SYSCTL_STRING(_kern, OID_AUTO, conftxt, CTLFLAG_RD | CTLFLAG_MPSAFE,
"Kernel configuration file"); kernconfstring, 0, "Kernel configuration file");
#endif #endif
static int static int

View File

@ -17,7 +17,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -191,13 +191,7 @@ _sleep(void *ident, struct lock_object *lock, int priority,
pri = priority; pri = priority;
#endif /* __rtems__ */ #endif /* __rtems__ */
/* KASSERT(!TD_ON_SLEEPQ(td), ("recursive sleep"));
* 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);
if ((uint8_t *)ident >= &pause_wchan[0] && if ((uint8_t *)ident >= &pause_wchan[0] &&
(uint8_t *)ident <= &pause_wchan[MAXCPU - 1]) (uint8_t *)ident <= &pause_wchan[MAXCPU - 1])

View File

@ -18,7 +18,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

View File

@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

View File

@ -17,7 +17,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -1059,6 +1059,8 @@ callout_when(sbintime_t sbt, sbintime_t precision, int flags,
spinlock_exit(); spinlock_exit();
#endif #endif
#endif #endif
if (cold && to_sbt == 0)
to_sbt = sbinuptime();
if ((flags & C_HARDCLOCK) == 0) if ((flags & C_HARDCLOCK) == 0)
to_sbt += tick_sbt; to_sbt += tick_sbt;
} else } else

View File

@ -30,6 +30,7 @@
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_bus.h> #include <rtems/bsd/local/opt_bus.h>
#include <rtems/bsd/local/opt_ddb.h>
#include <rtems/bsd/sys/param.h> #include <rtems/bsd/sys/param.h>
#include <sys/conf.h> #include <sys/conf.h>
@ -67,6 +68,8 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.h> #include <vm/uma.h>
#include <vm/vm.h> #include <vm/vm.h>
#include <ddb/ddb.h>
SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL); SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
SYSCTL_ROOT_NODE(OID_AUTO, dev, 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); static void devctl2_init(void);
#endif /* __rtems__ */ #endif /* __rtems__ */
#define DRIVERNAME(d) ((d)? d->name : "no driver")
#define DEVCLANAME(d) ((d)? d->name : "no devclass")
#ifdef BUS_DEBUG #ifdef BUS_DEBUG
static int bus_debug = 1; 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 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 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 * 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 */ /* Make the compiler ignore the function calls */
#define PDEBUG(a) /* nop */ #define PDEBUG(a) /* nop */
#define DEVICENAME(d) /* nop */ #define DEVICENAME(d) /* nop */
#define DRIVERNAME(d) /* nop */
#define DEVCLANAME(d) /* nop */
#define print_device_short(d,i) /* nop */ #define print_device_short(d,i) /* nop */
#define print_device(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))); 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) { while ((grandchild = TAILQ_FIRST(&child->children)) != NULL) {
error = device_delete_child(child, grandchild); error = device_delete_child(child, grandchild);
if (error) if (error)
return (error); return (error);
} }
if ((error = device_detach(child)) != 0)
return (error);
if (child->devclass) if (child->devclass)
devclass_delete_device(child->devclass, child); devclass_delete_device(child->devclass, child);
if (child->parent) if (child->parent)
@ -2179,6 +2183,12 @@ device_probe_child(device_t dev, device_t child)
break; 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 * Probes that return BUS_PROBE_NOWILDCARD or lower
* only match on devices whose driver was explicitly * only match on devices whose driver was explicitly
@ -3008,6 +3018,7 @@ device_detach(device_t dev)
if (!(dev->flags & DF_FIXEDCLASS)) if (!(dev->flags & DF_FIXEDCLASS))
devclass_delete_device(dev->devclass, dev); devclass_delete_device(dev->devclass, dev);
device_verbose(dev);
dev->state = DS_NOTPRESENT; dev->state = DS_NOTPRESENT;
(void)device_set_driver(dev, NULL); (void)device_set_driver(dev, NULL);
device_sysctl_fini(dev); 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_SUSPEND:
case DEV_RESUME: case DEV_RESUME:
case DEV_SET_DRIVER: case DEV_SET_DRIVER:
case DEV_CLEAR_DRIVER:
case DEV_RESCAN: case DEV_RESCAN:
case DEV_DELETE: case DEV_DELETE:
error = priv_check(td, PRIV_DRIVER); 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); error = device_probe_and_attach(dev);
break; 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: case DEV_RESCAN:
if (!device_is_attached(dev)) { if (!device_is_attached(dev)) {
error = ENXIO; error = ENXIO;
@ -5604,4 +5635,33 @@ devctl2_init(void)
make_dev_credf(MAKEDEV_ETERNAL, &devctl2_cdevsw, 0, NULL, make_dev_credf(MAKEDEV_ETERNAL, &devctl2_cdevsw, 0, NULL,
UID_ROOT, GID_WHEEL, 0600, "devctl2"); 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__ */ #endif /* __rtems__ */

View File

@ -17,7 +17,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

View File

@ -16,7 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

View File

@ -17,7 +17,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * 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 * Note that stdarg.h and the ANSI style va_start macro is used for both
* ANSI and traditional C compilers. * ANSI and traditional C compilers.
*/ */
#ifdef _KERNEL
#include <machine/stdarg.h> #include <machine/stdarg.h>
#else
#include <stdarg.h>
#endif
#ifdef _KERNEL #ifdef _KERNEL

View File

@ -434,7 +434,7 @@ sleepq_set_timeout_sbt(void *wchan, sbintime_t sbt, sbintime_t pr,
MPASS(TD_ON_SLEEPQ(td)); MPASS(TD_ON_SLEEPQ(td));
MPASS(td->td_sleepqueue == NULL); MPASS(td->td_sleepqueue == NULL);
MPASS(wchan != NULL); MPASS(wchan != NULL);
if (cold) if (cold && td == &thread0)
panic("timed sleep before timers are working"); panic("timed sleep before timers are working");
KASSERT(td->td_sleeptimo == 0, ("td %d %p td_sleeptimo %jx", KASSERT(td->td_sleeptimo == 0, ("td %d %p td_sleeptimo %jx",
td->td_tid, td, (uintmax_t)td->td_sleeptimo)); 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 * been sleeping the longest since threads are always added to
* the tail of sleep queues. * the tail of sleep queues.
*/ */
besttd = NULL; besttd = TAILQ_FIRST(&sq->sq_blocked[queue]);
TAILQ_FOREACH(td, &sq->sq_blocked[queue], td_slpq) { 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; besttd = td;
} }
#else /* __rtems__ */ #else /* __rtems__ */

View File

@ -89,6 +89,7 @@ struct taskqueue {
#define TQ_FLAGS_UNLOCKED_ENQUEUE (1 << 2) #define TQ_FLAGS_UNLOCKED_ENQUEUE (1 << 2)
#define DT_CALLOUT_ARMED (1 << 0) #define DT_CALLOUT_ARMED (1 << 0)
#define DT_DRAIN_IN_PROGRESS (1 << 1)
#ifndef __rtems__ #ifndef __rtems__
#define TQ_LOCK(tq) \ #define TQ_LOCK(tq) \
@ -334,7 +335,11 @@ taskqueue_enqueue_timeout(struct taskqueue *queue,
#endif /* __rtems__ */ #endif /* __rtems__ */
timeout_task->q = queue; timeout_task->q = queue;
res = timeout_task->t.ta_pending; 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); taskqueue_enqueue_locked(queue, &timeout_task->t);
/* The lock is released inside. */ /* The lock is released inside. */
} else { } else {
@ -598,8 +603,24 @@ taskqueue_drain_timeout(struct taskqueue *queue,
struct timeout_task *timeout_task) 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); callout_drain(&timeout_task->c);
taskqueue_drain(queue, &timeout_task->t); 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 static void
@ -666,6 +687,11 @@ _taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
} else } else
tq->tq_tcount++; tq->tq_tcount++;
} }
if (tq->tq_tcount == 0) {
free(tq->tq_threads, M_TASKQUEUE);
tq->tq_threads = NULL;
return (ENOMEM);
}
#ifndef __rtems__ #ifndef __rtems__
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if (tq->tq_threads[i] == NULL) if (tq->tq_threads[i] == NULL)

View File

@ -22,7 +22,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -556,7 +556,7 @@ fueword32(volatile const void *base, int32_t *val)
int int
fueword64(volatile const void *base, int64_t *val) fueword64(volatile const void *base, int64_t *val)
{ {
int32_t res; int64_t res;
res = fuword64(base); res = fuword64(base);
if (res == -1) if (res == -1)

View File

@ -17,7 +17,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

View File

@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

View File

@ -252,7 +252,7 @@ do_setopt_accept_filter(struct socket *so, struct sockopt *sopt)
newaf = malloc(sizeof(*newaf), M_ACCF, M_WAITOK | newaf = malloc(sizeof(*newaf), M_ACCF, M_WAITOK |
M_ZERO); M_ZERO);
if (afp->accf_create != NULL && afap->af_name[0] != '\0') { 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, newaf->so_accept_filter_str = malloc(len, M_ACCF,
M_WAITOK); M_WAITOK);
strcpy(newaf->so_accept_filter_str, afap->af_name); strcpy(newaf->so_accept_filter_str, afap->af_name);

View File

@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

View File

@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -986,7 +986,7 @@ m_devget(char *buf, int totlen, int off, struct ifnet *ifp,
len = MHLEN; len = MHLEN;
/* Place initial small packet/header at end of mbuf */ /* 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; m->m_data += max_linkhdr;
len -= max_linkhdr; len -= max_linkhdr;
} }
@ -1338,7 +1338,7 @@ nospace:
/* /*
* Defragment an mbuf chain, returning at most maxfrags separate * Defragment an mbuf chain, returning at most maxfrags separate
* mbufs+clusters. If this is not possible NULL is returned and * 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 * modified) state. We use two techniques: collapsing consecutive
* mbufs and replacing consecutive mbufs by a cluster. * mbufs and replacing consecutive mbufs by a cluster.
* *

View File

@ -43,7 +43,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

View File

@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

View File

@ -15,7 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -1669,7 +1669,8 @@ dontblock:
do { do {
if (flags & MSG_PEEK) { if (flags & MSG_PEEK) {
if (controlp != NULL) { 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; controlp = &(*controlp)->m_next;
} }
m = m->m_next; m = m->m_next;

View File

@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * 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 * Convert a user file descriptor to a kernel file entry and check if required
* capability rights are present. * 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. * A reference on the file entry is held upon returning.
*/ */
int int
getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp, 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; struct file *fp;
int error; 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) if (error != 0)
return (error); return (error);
if (fp->f_type != DTYPE_SOCKET) { if (fp->f_type != DTYPE_SOCKET) {
fdrop(fp, td); fdrop(fp, td);
if (havecapsp != NULL)
filecaps_free(havecapsp);
return (ENOTSOCK); return (ENOTSOCK);
} }
if (fflagp != NULL) if (fflagp != NULL)
@ -148,7 +151,7 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp)
return (error); 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__ */ #endif /* __rtems__ */
/* /*
@ -162,13 +165,7 @@ rtems_bsd_getsock(int fd, struct file **fpp, u_int *fflagp)
static static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
sys_socket(td, uap) sys_socket(struct thread *td, struct socket_args *uap)
struct thread *td;
struct socket_args /* {
int domain;
int type;
int protocol;
} */ *uap;
{ {
struct socket *so; struct socket *so;
struct file *fp; struct file *fp;
@ -239,7 +236,6 @@ socket(int domain, int type, int protocol)
} }
#endif /* __rtems__ */ #endif /* __rtems__ */
/* ARGSUSED */
#ifdef __rtems__ #ifdef __rtems__
static int kern_bindat(struct thread *td, int dirfd, int fd, static int kern_bindat(struct thread *td, int dirfd, int fd,
struct sockaddr *sa); struct sockaddr *sa);
@ -247,13 +243,7 @@ static int kern_bindat(struct thread *td, int dirfd, int fd,
static static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
sys_bind(td, uap) sys_bind(struct thread *td, struct bind_args *uap)
struct thread *td;
struct bind_args /* {
int s;
caddr_t name;
int namelen;
} */ *uap;
{ {
struct sockaddr *sa; struct sockaddr *sa;
int error; int error;
@ -298,7 +288,7 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
AUDIT_ARG_FD(fd); AUDIT_ARG_FD(fd);
AUDIT_ARG_SOCKADDR(td, dirfd, sa); AUDIT_ARG_SOCKADDR(td, dirfd, sa);
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_BIND), error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_BIND),
&fp, NULL); &fp, NULL, NULL);
if (error != 0) if (error != 0)
return (error); return (error);
so = fp->f_data; so = fp->f_data;
@ -321,18 +311,10 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
return (error); return (error);
} }
/* ARGSUSED */
#ifndef __rtems__ #ifndef __rtems__
static static
int int
sys_bindat(td, uap) sys_bindat(struct thread *td, struct bindat_args *uap)
struct thread *td;
struct bindat_args /* {
int fd;
int s;
caddr_t name;
int namelen;
} */ *uap;
{ {
struct sockaddr *sa; struct sockaddr *sa;
int error; int error;
@ -346,14 +328,8 @@ sys_bindat(td, uap)
} }
#endif /* __rtems__ */ #endif /* __rtems__ */
/* ARGSUSED */
int int
sys_listen(td, uap) sys_listen(struct thread *td, struct listen_args *uap)
struct thread *td;
struct listen_args /* {
int s;
int backlog;
} */ *uap;
{ {
struct socket *so; struct socket *so;
struct file *fp; struct file *fp;
@ -362,7 +338,7 @@ sys_listen(td, uap)
AUDIT_ARG_FD(uap->s); AUDIT_ARG_FD(uap->s);
error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_LISTEN), error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_LISTEN),
&fp, NULL); &fp, NULL, NULL);
if (error == 0) { if (error == 0) {
so = fp->f_data; so = fp->f_data;
#ifdef MAC #ifdef MAC
@ -483,6 +459,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
struct file *headfp, *nfp = NULL; struct file *headfp, *nfp = NULL;
struct sockaddr *sa = NULL; struct sockaddr *sa = NULL;
struct socket *head, *so; struct socket *head, *so;
struct filecaps fcaps;
cap_rights_t rights; cap_rights_t rights;
u_int fflag; u_int fflag;
pid_t pgid; pid_t pgid;
@ -493,7 +470,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
AUDIT_ARG_FD(s); AUDIT_ARG_FD(s);
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_ACCEPT), error = getsock_cap(td, s, cap_rights_init(&rights, CAP_ACCEPT),
&headfp, &fflag); &headfp, &fflag, &fcaps);
if (error != 0) if (error != 0)
return (error); return (error);
head = headfp->f_data; head = headfp->f_data;
@ -506,7 +483,8 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name,
if (error != 0) if (error != 0)
goto done; goto done;
#endif #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) if (error != 0)
goto done; goto done;
ACCEPT_LOCK(); ACCEPT_LOCK();
@ -615,6 +593,8 @@ noconnection:
* a reference on nfp to the caller on success if they request it. * a reference on nfp to the caller on success if they request it.
*/ */
done: done:
if (nfp == NULL)
filecaps_free(&fcaps);
if (fp != NULL) { if (fp != NULL) {
if (error == 0) { if (error == 0) {
*fp = nfp; *fp = nfp;
@ -663,7 +643,6 @@ oaccept(td, uap)
#endif /* COMPAT_OLDSOCK */ #endif /* COMPAT_OLDSOCK */
#endif /* __rtems__ */ #endif /* __rtems__ */
/* ARGSUSED */
#ifdef __rtems__ #ifdef __rtems__
static int kern_connectat(struct thread *td, int dirfd, int fd, static int kern_connectat(struct thread *td, int dirfd, int fd,
struct sockaddr *sa); struct sockaddr *sa);
@ -671,13 +650,7 @@ static int kern_connectat(struct thread *td, int dirfd, int fd,
static static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
sys_connect(td, uap) sys_connect(struct thread *td, struct connect_args *uap)
struct thread *td;
struct connect_args /* {
int s;
caddr_t name;
int namelen;
} */ *uap;
{ {
struct sockaddr *sa; struct sockaddr *sa;
int error; int error;
@ -722,7 +695,7 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
AUDIT_ARG_FD(fd); AUDIT_ARG_FD(fd);
AUDIT_ARG_SOCKADDR(td, dirfd, sa); AUDIT_ARG_SOCKADDR(td, dirfd, sa);
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_CONNECT), error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_CONNECT),
&fp, NULL); &fp, NULL, NULL);
if (error != 0) if (error != 0)
return (error); return (error);
so = fp->f_data; so = fp->f_data;
@ -775,16 +748,8 @@ done1:
} }
#ifndef __rtems__ #ifndef __rtems__
/* ARGSUSED */
int int
sys_connectat(td, uap) sys_connectat(struct thread *td, struct connectat_args *uap)
struct thread *td;
struct connectat_args /* {
int fd;
int s;
caddr_t name;
int namelen;
} */ *uap;
{ {
struct sockaddr *sa; struct sockaddr *sa;
int error; 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); struct mbuf *control, enum uio_seg segflg);
#endif /* __rtems__ */ #endif /* __rtems__ */
static int static int
sendit(td, s, mp, flags) sendit(struct thread *td, int s, struct msghdr *mp, int flags)
struct thread *td;
int s;
struct msghdr *mp;
int flags;
{ {
struct mbuf *control; struct mbuf *control;
struct sockaddr *to; struct sockaddr *to;
@ -998,13 +959,8 @@ bad:
} }
int int
kern_sendit(td, s, mp, flags, control, segflg) kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
struct thread *td; struct mbuf *control, enum uio_seg segflg)
int s;
struct msghdr *mp;
int flags;
struct mbuf *control;
enum uio_seg segflg;
{ {
struct file *fp; struct file *fp;
struct uio auio; struct uio auio;
@ -1026,12 +982,12 @@ kern_sendit(td, s, mp, flags, control, segflg)
AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name); AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
cap_rights_set(&rights, CAP_CONNECT); cap_rights_set(&rights, CAP_CONNECT);
} }
error = getsock_cap(td, s, &rights, &fp, NULL);
if (error != 0)
#endif /* __rtems__ */ #endif /* __rtems__ */
error = getsock_cap(td->td_proc->p_fd, s, rights, &fp, NULL); error = getsock_cap(td, s, &rights, &fp, NULL, NULL);
if (error) if (error != 0) {
m_freem(control);
return (error); return (error);
}
so = (struct socket *)fp->f_data; so = (struct socket *)fp->f_data;
#ifdef KTRACE #ifdef KTRACE
@ -1042,12 +998,16 @@ kern_sendit(td, s, mp, flags, control, segflg)
if (mp->msg_name != NULL) { if (mp->msg_name != NULL) {
error = mac_socket_check_connect(td->td_ucred, so, error = mac_socket_check_connect(td->td_ucred, so,
mp->msg_name); mp->msg_name);
if (error != 0) if (error != 0) {
m_freem(control);
goto bad; goto bad;
}
} }
error = mac_socket_check_send(td->td_ucred, so); error = mac_socket_check_send(td->td_ucred, so);
if (error != 0) if (error != 0) {
m_freem(control);
goto bad; goto bad;
}
#endif #endif
auio.uio_iov = mp->msg_iov; 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++) { for (i = 0; i < mp->msg_iovlen; i++, iov++) {
if ((auio.uio_resid += iov->iov_len) < 0) { if ((auio.uio_resid += iov->iov_len) < 0) {
error = EINVAL; error = EINVAL;
m_freem(control);
goto bad; goto bad;
} }
} }
@ -1103,16 +1064,7 @@ bad:
static static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
sys_sendto(td, uap) sys_sendto(struct thread *td, struct sendto_args *uap)
struct thread *td;
struct sendto_args /* {
int s;
caddr_t buf;
size_t len;
int flags;
caddr_t to;
int tolen;
} */ *uap;
{ {
struct msghdr msg; struct msghdr msg;
struct iovec aiov; struct iovec aiov;
@ -1167,7 +1119,7 @@ rtems_bsd_sendto(int socket, struct mbuf *m, int flags,
struct socket *so; struct socket *so;
int error; 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) if (error)
return (error); return (error);
so = (struct socket *)fp->f_data; so = (struct socket *)fp->f_data;
@ -1186,14 +1138,7 @@ rtems_bsd_sendto(int socket, struct mbuf *m, int flags,
#ifndef __rtems__ #ifndef __rtems__
#ifdef COMPAT_OLDSOCK #ifdef COMPAT_OLDSOCK
int int
osend(td, uap) osend(struct thread *td, struct osend_args *uap)
struct thread *td;
struct osend_args /* {
int s;
caddr_t buf;
int len;
int flags;
} */ *uap;
{ {
struct msghdr msg; struct msghdr msg;
struct iovec aiov; struct iovec aiov;
@ -1210,13 +1155,7 @@ osend(td, uap)
} }
int int
osendmsg(td, uap) osendmsg(struct thread *td, struct osendmsg_args *uap)
struct thread *td;
struct osendmsg_args /* {
int s;
caddr_t msg;
int flags;
} */ *uap;
{ {
struct msghdr msg; struct msghdr msg;
struct iovec *iov; struct iovec *iov;
@ -1241,13 +1180,7 @@ osendmsg(td, uap)
static static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
sys_sendmsg(td, uap) sys_sendmsg(struct thread *td, struct sendmsg_args *uap)
struct thread *td;
struct sendmsg_args /* {
int s;
caddr_t msg;
int flags;
} */ *uap;
{ {
struct msghdr msg; struct msghdr msg;
struct iovec *iov; struct iovec *iov;
@ -1297,12 +1230,8 @@ sendmsg(int socket, const struct msghdr *message, int flags)
static static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
kern_recvit(td, s, mp, fromseg, controlp) kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg,
struct thread *td; struct mbuf **controlp)
int s;
struct msghdr *mp;
enum uio_seg fromseg;
struct mbuf **controlp;
{ {
struct uio auio; struct uio auio;
struct iovec *iov; struct iovec *iov;
@ -1323,7 +1252,7 @@ kern_recvit(td, s, mp, fromseg, controlp)
AUDIT_ARG_FD(s); AUDIT_ARG_FD(s);
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_RECV), error = getsock_cap(td, s, cap_rights_init(&rights, CAP_RECV),
&fp, NULL); &fp, NULL, NULL);
if (error != 0) if (error != 0)
return (error); return (error);
so = fp->f_data; so = fp->f_data;
@ -1459,11 +1388,7 @@ out:
} }
static int static int
recvit(td, s, mp, namelenp) recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp)
struct thread *td;
int s;
struct msghdr *mp;
void *namelenp;
{ {
int error; int error;
@ -1484,16 +1409,7 @@ recvit(td, s, mp, namelenp)
static static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
sys_recvfrom(td, uap) sys_recvfrom(struct thread *td, struct recvfrom_args *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;
{ {
struct msghdr msg; struct msghdr msg;
struct iovec aiov; struct iovec aiov;
@ -1551,9 +1467,7 @@ recvfrom(int socket, void *__restrict buffer, size_t length, int flags,
#ifndef __rtems__ #ifndef __rtems__
#ifdef COMPAT_OLDSOCK #ifdef COMPAT_OLDSOCK
int int
orecvfrom(td, uap) orecvfrom(struct thread *td, struct recvfrom_args *uap)
struct thread *td;
struct recvfrom_args *uap;
{ {
uap->flags |= MSG_COMPAT; uap->flags |= MSG_COMPAT;
@ -1563,14 +1477,7 @@ orecvfrom(td, uap)
#ifdef COMPAT_OLDSOCK #ifdef COMPAT_OLDSOCK
int int
orecv(td, uap) orecv(struct thread *td, struct orecv_args *uap)
struct thread *td;
struct orecv_args /* {
int s;
caddr_t buf;
int len;
int flags;
} */ *uap;
{ {
struct msghdr msg; struct msghdr msg;
struct iovec aiov; struct iovec aiov;
@ -1592,13 +1499,7 @@ orecv(td, uap)
* rights where the control fields are now. * rights where the control fields are now.
*/ */
int int
orecvmsg(td, uap) orecvmsg(struct thread *td, struct orecvmsg_args *uap)
struct thread *td;
struct orecvmsg_args /* {
int s;
struct omsghdr *msg;
int flags;
} */ *uap;
{ {
struct msghdr msg; struct msghdr msg;
struct iovec *iov; struct iovec *iov;
@ -1626,13 +1527,7 @@ orecvmsg(td, uap)
static static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
sys_recvmsg(td, uap) sys_recvmsg(struct thread *td, struct recvmsg_args *uap)
struct thread *td;
struct recvmsg_args /* {
int s;
struct msghdr *msg;
int flags;
} */ *uap;
{ {
struct msghdr msg; struct msghdr msg;
struct iovec *uiov, *iov; struct iovec *uiov, *iov;
@ -1684,17 +1579,11 @@ recvmsg(int socket, struct msghdr *message, int flags)
} }
#endif /* __rtems__ */ #endif /* __rtems__ */
/* ARGSUSED */
#ifdef __rtems__ #ifdef __rtems__
static static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
sys_shutdown(td, uap) sys_shutdown(struct thread *td, struct shutdown_args *uap)
struct thread *td;
struct shutdown_args /* {
int s;
int how;
} */ *uap;
{ {
struct socket *so; struct socket *so;
struct file *fp; struct file *fp;
@ -1703,7 +1592,7 @@ sys_shutdown(td, uap)
AUDIT_ARG_FD(uap->s); AUDIT_ARG_FD(uap->s);
error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_SHUTDOWN), error = getsock_cap(td, uap->s, cap_rights_init(&rights, CAP_SHUTDOWN),
&fp, NULL); &fp, NULL, NULL);
if (error == 0) { if (error == 0) {
so = fp->f_data; so = fp->f_data;
error = soshutdown(so, uap->how); error = soshutdown(so, uap->how);
@ -1736,7 +1625,6 @@ shutdown(int socket, int how)
} }
#endif /* __rtems__ */ #endif /* __rtems__ */
/* ARGSUSED */
#ifdef __rtems__ #ifdef __rtems__
static int kern_setsockopt( struct thread *td, int s, int level, int name, static int kern_setsockopt( struct thread *td, int s, int level, int name,
void *val, enum uio_seg valseg, socklen_t valsize); 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 static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
sys_setsockopt(td, uap) sys_setsockopt(struct thread *td, struct setsockopt_args *uap)
struct thread *td;
struct setsockopt_args /* {
int s;
int level;
int name;
caddr_t val;
int valsize;
} */ *uap;
{ {
return (kern_setsockopt(td, uap->s, uap->level, uap->name, 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__ */ #endif /* __rtems__ */
int int
kern_setsockopt(td, s, level, name, val, valseg, valsize) kern_setsockopt(struct thread *td, int s, int level, int name, void *val,
struct thread *td; enum uio_seg valseg, socklen_t valsize)
int s;
int level;
int name;
void *val;
enum uio_seg valseg;
socklen_t valsize;
{ {
struct socket *so; struct socket *so;
struct file *fp; struct file *fp;
@ -1822,7 +1696,7 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize)
AUDIT_ARG_FD(s); AUDIT_ARG_FD(s);
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SETSOCKOPT), error = getsock_cap(td, s, cap_rights_init(&rights, CAP_SETSOCKOPT),
&fp, NULL); &fp, NULL, NULL);
if (error == 0) { if (error == 0) {
so = fp->f_data; so = fp->f_data;
error = sosetopt(so, &sopt); error = sosetopt(so, &sopt);
@ -1831,7 +1705,6 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize)
return(error); return(error);
} }
/* ARGSUSED */
#ifdef __rtems__ #ifdef __rtems__
static int kern_getsockopt( struct thread *td, int s, int level, int name, static int kern_getsockopt( struct thread *td, int s, int level, int name,
void *val, enum uio_seg valseg, socklen_t *valsize); 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 static
#endif /* __rtems__ */ #endif /* __rtems__ */
int int
sys_getsockopt(td, uap) sys_getsockopt(struct thread *td, struct getsockopt_args *uap)
struct thread *td;
struct getsockopt_args /* {
int s;
int level;
int name;
void * __restrict val;
socklen_t * __restrict avalsize;
} */ *uap;
{ {
socklen_t valsize; socklen_t valsize;
int error; 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. * optval can be a userland or userspace. optlen is always a kernel pointer.
*/ */
int int
kern_getsockopt(td, s, level, name, val, valseg, valsize) kern_getsockopt(struct thread *td, int s, int level, int name, void *val,
struct thread *td; enum uio_seg valseg, socklen_t *valsize)
int s;
int level;
int name;
void *val;
enum uio_seg valseg;
socklen_t *valsize;
{ {
struct socket *so; struct socket *so;
struct file *fp; struct file *fp;
@ -1933,7 +1792,7 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize)
AUDIT_ARG_FD(s); AUDIT_ARG_FD(s);
error = getsock_cap(td, s, cap_rights_init(&rights, CAP_GETSOCKOPT), error = getsock_cap(td, s, cap_rights_init(&rights, CAP_GETSOCKOPT),
&fp, NULL); &fp, NULL, NULL);
if (error == 0) { if (error == 0) {
so = fp->f_data; so = fp->f_data;
error = sogetopt(so, &sopt); error = sogetopt(so, &sopt);
@ -1951,16 +1810,8 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
/* /*
* getsockname1() - Get socket name. * getsockname1() - Get socket name.
*/ */
/* ARGSUSED */
static int static int
getsockname1(td, uap, compat) getsockname1(struct thread *td, struct getsockname_args *uap, int compat)
struct thread *td;
struct getsockname_args /* {
int fdes;
struct sockaddr * __restrict asa;
socklen_t * __restrict alen;
} */ *uap;
int compat;
{ {
struct sockaddr *sa; struct sockaddr *sa;
socklen_t len; socklen_t len;
@ -2000,7 +1851,7 @@ getsockname(int socket, struct sockaddr *__restrict address,
int error; int error;
if (td != NULL) { if (td != NULL) {
error = getsockname1(td, &ua); error = getsockname1(td, &ua, 0);
} else { } else {
error = ENOMEM; error = ENOMEM;
} }
@ -2021,7 +1872,7 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
AUDIT_ARG_FD(fd); AUDIT_ARG_FD(fd);
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETSOCKNAME), error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETSOCKNAME),
&fp, NULL); &fp, NULL, NULL);
if (error != 0) if (error != 0)
return (error); return (error);
so = fp->f_data; so = fp->f_data;
@ -2051,9 +1902,7 @@ bad:
#ifndef __rtems__ #ifndef __rtems__
int int
sys_getsockname(td, uap) sys_getsockname(struct thread *td, struct getsockname_args *uap)
struct thread *td;
struct getsockname_args *uap;
{ {
return (getsockname1(td, uap, 0)); return (getsockname1(td, uap, 0));
@ -2061,9 +1910,7 @@ sys_getsockname(td, uap)
#ifdef COMPAT_OLDSOCK #ifdef COMPAT_OLDSOCK
int int
ogetsockname(td, uap) ogetsockname(struct thread *td, struct getsockname_args *uap)
struct thread *td;
struct getsockname_args *uap;
{ {
return (getsockname1(td, uap, 1)); 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. * getpeername1() - Get name of peer for connected socket.
*/ */
/* ARGSUSED */
static int static int
getpeername1(td, uap, compat) getpeername1(struct thread *td, struct getpeername_args *uap, int compat)
struct thread *td;
struct getpeername_args /* {
int fdes;
struct sockaddr * __restrict asa;
socklen_t * __restrict alen;
} */ *uap;
int compat;
{ {
struct sockaddr *sa; struct sockaddr *sa;
socklen_t len; socklen_t len;
@ -2128,7 +1967,7 @@ getpeername(int socket, struct sockaddr *__restrict address,
int error; int error;
if (td != NULL) { if (td != NULL) {
error = getpeername1(td, &ua); error = getpeername1(td, &ua, 0);
} else { } else {
error = ENOMEM; error = ENOMEM;
} }
@ -2149,7 +1988,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
AUDIT_ARG_FD(fd); AUDIT_ARG_FD(fd);
error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETPEERNAME), error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_GETPEERNAME),
&fp, NULL); &fp, NULL, NULL);
if (error != 0) if (error != 0)
return (error); return (error);
so = fp->f_data; so = fp->f_data;
@ -2184,9 +2023,7 @@ done:
#ifndef __rtems__ #ifndef __rtems__
int int
sys_getpeername(td, uap) sys_getpeername(struct thread *td, struct getpeername_args *uap)
struct thread *td;
struct getpeername_args *uap;
{ {
return (getpeername1(td, uap, 0)); return (getpeername1(td, uap, 0));
@ -2194,9 +2031,7 @@ sys_getpeername(td, uap)
#ifdef COMPAT_OLDSOCK #ifdef COMPAT_OLDSOCK
int int
ogetpeername(td, uap) ogetpeername(struct thread *td, struct ogetpeername_args *uap)
struct thread *td;
struct ogetpeername_args *uap;
{ {
/* XXX uap should have type `getpeername_args *' to begin with. */ /* 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 int
getsockaddr(namp, uaddr, len) getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len)
struct sockaddr **namp;
caddr_t uaddr;
size_t len;
{ {
struct sockaddr *sa; struct sockaddr *sa;
int error; int error;

View File

@ -14,7 +14,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * 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 int unp_connect2(struct socket *so, struct socket *so2, int);
static void unp_disconnect(struct unpcb *unp, struct unpcb *unp2); static void unp_disconnect(struct unpcb *unp, struct unpcb *unp2);
#ifndef __rtems__ #ifndef __rtems__
static void unp_dispose(struct mbuf *); static void unp_dispose(struct socket *so);
static void unp_dispose_so(struct socket *so); static void unp_dispose_mbuf(struct mbuf *);
#endif /* __rtems__ */ #endif /* __rtems__ */
static void unp_shutdown(struct unpcb *); static void unp_shutdown(struct unpcb *);
static void unp_drop(struct unpcb *); static void unp_drop(struct unpcb *);
@ -355,7 +355,7 @@ static struct domain localdomain = {
.dom_init = unp_init, .dom_init = unp_init,
#ifndef __rtems__ #ifndef __rtems__
.dom_externalize = unp_externalize, .dom_externalize = unp_externalize,
.dom_dispose = unp_dispose_so, .dom_dispose = unp_dispose,
#endif /* __rtems__ */ #endif /* __rtems__ */
.dom_protosw = localsw, .dom_protosw = localsw,
.dom_protoswNPROTOSW = &localsw[nitems(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) if (control != NULL && error != 0)
#ifndef __rtems__ #ifndef __rtems__
unp_dispose(control); unp_dispose_mbuf(control);
#else /* __rtems__ */ #else /* __rtems__ */
BSD_ASSERT(0); BSD_ASSERT(0);
#endif /* __rtems__ */ #endif /* __rtems__ */
@ -2511,7 +2511,7 @@ unp_gc(__unused void *arg, int pending)
} }
static void static void
unp_dispose(struct mbuf *m) unp_dispose_mbuf(struct mbuf *m)
{ {
if (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. * Synchronize against unp_gc, which can trip over data as we are freeing it.
*/ */
static void static void
unp_dispose_so(struct socket *so) unp_dispose(struct socket *so)
{ {
struct unpcb *unp; struct unpcb *unp;
@ -2530,7 +2530,7 @@ unp_dispose_so(struct socket *so)
UNP_LIST_LOCK(); UNP_LIST_LOCK();
unp->unp_gcflag |= UNPGC_IGNORE_RIGHTS; unp->unp_gcflag |= UNPGC_IGNORE_RIGHTS;
UNP_LIST_UNLOCK(); UNP_LIST_UNLOCK();
unp_dispose(so->so_rcv.sb_mb); unp_dispose_mbuf(so->so_rcv.sb_mb);
} }
static void static void

Some files were not shown because too many files have changed in this diff Show More