Index: bin/sh/arith.h =================================================================== --- bin/sh/arith.h +++ bin/sh/arith.h @@ -35,4 +35,3 @@ #define DIGITS(var) (3 + (2 + CHAR_BIT * sizeof((var))) / 3) arith_t arith(const char *); -void arith_lex_reset(void); Index: bin/sh/expand.c =================================================================== --- bin/sh/expand.c +++ bin/sh/expand.c @@ -97,7 +97,7 @@ struct worddest *); static void expbackq(union node *, int, int, struct worddest *); static void subevalvar_trim(const char *, struct nodelist *, int, int, int); -static int subevalvar_misc(const char *, struct nodelist *, const char *, int, +static void subevalvar_misc(const char *, struct nodelist *, const char *, int, int, int); static const char *evalvar(const char *, struct nodelist **restrict, int, struct worddest *); @@ -617,7 +617,7 @@ } -static int +static void subevalvar_misc(const char *p, struct nodelist *argbackq, const char *var, int subtype, int startloc, int varflags) { @@ -634,7 +634,7 @@ setvar(var, startp, 0); amount = startp - expdest; STADJUST(amount, expdest); - return 1; + return; case VSQUESTION: if (*p != CTLENDVAR) { @@ -643,7 +643,6 @@ } error("%.*s: parameter %snot set", (int)(p - var - 1), var, (varflags & VSNUL) ? "null or " : ""); - return 0; default: abort(); @@ -792,12 +791,11 @@ case VSASSIGN: case VSQUESTION: if (!set) { - if (subevalvar_misc(p, *argbackq, var, subtype, - startloc, varflags)) { - varflags &= ~VSNUL; - goto again; - } - break; + subevalvar_misc(p, *argbackq, var, subtype, + startloc, varflags); + /* assert(subtype == VSASSIGN); */ + varflags &= ~VSNUL; + goto again; } break; Index: contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c =================================================================== --- contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c +++ contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c @@ -46,7 +46,11 @@ rqtp.tv_sec = 0; rqtp.tv_nsec = 0; rmtp.tv_sec = -1; rmtp.tv_nsec = -1; ATF_REQUIRE(clock_nanosleep(CLOCK_REALTIME, 0, &rqtp, &rmtp) == 0); +#ifdef __FreeBSD__ + ATF_CHECK(rmtp.tv_sec == -1 && rmtp.tv_nsec == -1); +#else ATF_CHECK(rmtp.tv_sec == 0 && rmtp.tv_nsec == 0); +#endif ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &rqtp) == 0); rmtp.tv_sec = -1; rmtp.tv_nsec = -1; Index: include/time.h =================================================================== --- include/time.h +++ include/time.h @@ -169,12 +169,12 @@ int clock_getres(clockid_t, struct timespec *); int clock_gettime(clockid_t, struct timespec *); int clock_settime(clockid_t, const struct timespec *); -/* XXX missing: clock_nanosleep() */ int nanosleep(const struct timespec *, struct timespec *); #endif /* __POSIX_VISIBLE >= 199309 */ #if __POSIX_VISIBLE >= 200112 int clock_getcpuclockid(pid_t, clockid_t *); +int clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *); #endif #if __POSIX_VISIBLE >= 199506 Index: lib/libc/include/libc_private.h =================================================================== --- lib/libc/include/libc_private.h +++ lib/libc/include/libc_private.h @@ -229,6 +229,7 @@ INTERPOS_ppoll, INTERPOS_map_stacks_exec, INTERPOS_fdatasync, + INTERPOS_clock_nanosleep, INTERPOS_MAX }; @@ -318,6 +319,8 @@ int __sys_accept(int, struct sockaddr *, __socklen_t *); int __sys_accept4(int, struct sockaddr *, __socklen_t *, int); int __sys_clock_gettime(__clockid_t, struct timespec *ts); +int __sys_clock_nanosleep(__clockid_t, int, + const struct timespec *, struct timespec *); int __sys_close(int); int __sys_connect(int, const struct sockaddr *, __socklen_t); int __sys_fcntl(int, int, ...); Index: lib/libc/include/namespace.h =================================================================== --- lib/libc/include/namespace.h +++ lib/libc/include/namespace.h @@ -56,6 +56,7 @@ #define bind _bind #define __cap_get_fd ___cap_get_fd #define __cap_set_fd ___cap_set_fd +#define clock_nanosleep _clock_nanosleep #define close _close #define connect _connect #define dup _dup Index: lib/libc/include/un-namespace.h =================================================================== --- lib/libc/include/un-namespace.h +++ lib/libc/include/un-namespace.h @@ -37,6 +37,7 @@ #undef bind #undef __cap_get_fd #undef __cap_set_fd +#undef clock_nanosleep #undef close #undef connect #undef dup Index: lib/libc/string/memmem.3 =================================================================== --- lib/libc/string/memmem.3 +++ lib/libc/string/memmem.3 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 26, 2015 +.Dd March 17, 2017 .Dt MEMMEM 3 .Os .Sh NAME @@ -77,8 +77,11 @@ .Fn memmem function first appeared in .Fx 6.0 . -.Sh AUTHORS +It was replaced with an optimized O(n) implementation from the musl libc +project in +.Fx 12.0 . .An Pascal Gloor Aq Mt pascal.gloor@spale.com +provided this man page along with the previous implementation. .Sh BUGS This function was broken in Linux libc up to and including version 5.0.9 and in GNU libc prior to version 2.1. Index: lib/libc/string/memmem.c =================================================================== --- lib/libc/string/memmem.c +++ lib/libc/string/memmem.c @@ -1,65 +1,181 @@ /*- - * Copyright (c) 2005 Pascal Gloor + * Copyright (c) 2005-2014 Rich Felker, et al. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #include __FBSDID("$FreeBSD$"); #include +#include + +static char *twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) +{ + uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1]; + for (h++, k--; k; k--, hw = hw<<8 | *++h) + if (hw == nw) return (char *)h-1; + return 0; +} + +static char *threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) +{ + uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8; + uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8; + for (h+=2, k-=2; k; k--, hw = (hw|*++h)<<8) + if (hw == nw) return (char *)h-2; + return 0; +} + +static char *fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) +{ + uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3]; + uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3]; + for (h+=3, k-=3; k; k--, hw = hw<<8 | *++h) + if (hw == nw) return (char *)h-3; + return 0; +} + +#define MAX(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) + +#define BITOP(a,b,op) \ + ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) /* - * Find the first occurrence of the byte string s in byte string l. + * Two Way string search algorithm, with a bad shift table applied to the last + * byte of the window. A bit array marks which entries in the shift table are + * initialized to avoid fully initializing a 1kb/2kb table. + * + * Reference: CROCHEMORE M., PERRIN D., 1991, Two-way string-matching, + * Journal of the ACM 38(3):651-675 */ - -void * -memmem(const void *l, size_t l_len, const void *s, size_t s_len) +static char *twoway_memmem(const unsigned char *h, const unsigned char *z, const unsigned char *n, size_t l) { - register char *cur, *last; - const char *cl = (const char *)l; - const char *cs = (const char *)s; + size_t i, ip, jp, k, p, ms, p0, mem, mem0; + size_t byteset[32 / sizeof(size_t)] = { 0 }; + size_t shift[256]; + + /* Computing length of needle and fill shift table */ + for (i=0; i n[jp+k]) { + jp += k; + k = 1; + p = jp - ip; + } else { + ip = jp++; + k = p = 1; + } + } + ms = ip; + p0 = p; + + /* And with the opposite comparison */ + ip = -1; jp = 0; k = p = 1; + while (jp+k ms+1) ms = ip; + else p = p0; - /* empty "s" matches the beginning of "l" */ - if (s_len == 0) - return (void *)cl; + /* Periodic needle? */ + if (memcmp(n, n+p, ms+1)) { + mem0 = 0; + p = MAX(ms, l-ms-1) + 1; + } else mem0 = l-p; + mem = 0; - /* "s" must be smaller or equal to "l" */ - if (l_len < s_len) - return NULL; + /* Search loop */ + for (;;) { + /* If remainder of haystack is shorter than needle, done */ + if (z-h < l) return 0; + + /* Check last byte first; advance by shift on mismatch */ + if (BITOP(byteset, h[l-1], &)) { + k = l-shift[h[l-1]]; + if (k) { + if (mem0 && mem && k < p) k = l-p; + h += k; + mem = 0; + continue; + } + } else { + h += l; + mem = 0; + continue; + } + + /* Compare right half */ + for (k=MAX(ms+1,mem); kmem && n[k-1] == h[k-1]; k--); + if (k <= mem) return (char *)h; + h += p; + mem = mem0; + } +} + +void *memmem(const void *h0, size_t k, const void *n0, size_t l) +{ + const unsigned char *h = h0, *n = n0; - /* special case where s_len == 1 */ - if (s_len == 1) - return memchr(l, (int)*cs, l_len); + /* Return immediately on empty needle */ + if (!l) return (void *)h; - /* the last position where its possible to find "s" in "l" */ - last = (char *)cl + l_len - s_len; + /* Return immediately when needle is longer than haystack */ + if (k __FBSDID("$FreeBSD$"); #include +#include + +static char *twobyte_strstr(const unsigned char *h, const unsigned char *n) +{ + uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1]; + for (h++; *h && hw != nw; hw = hw<<8 | *++h); + return *h ? (char *)h-1 : 0; +} + +static char *threebyte_strstr(const unsigned char *h, const unsigned char *n) +{ + uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8; + uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8; + for (h+=2; *h && hw != nw; hw = (hw|*++h)<<8); + return *h ? (char *)h-2 : 0; +} + +static char *fourbyte_strstr(const unsigned char *h, const unsigned char *n) +{ + uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3]; + uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3]; + for (h+=3; *h && hw != nw; hw = hw<<8 | *++h); + return *h ? (char *)h-3 : 0; +} + +#define MAX(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) + +#define BITOP(a,b,op) \ + ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a)))) /* - * Find the first occurrence of find in s. + * Two Way string search algorithm, with a bad shift table applied to the last + * byte of the window. A bit array marks which entries in the shift table are + * initialized to avoid fully initializing a 1kb/2kb table. + * + * Reference: CROCHEMORE M., PERRIN D., 1991, Two-way string-matching, + * Journal of the ACM 38(3):651-675 */ -char * -strstr(const char *s, const char *find) +static char *twoway_strstr(const unsigned char *h, const unsigned char *n) { - char c, sc; - size_t len; - - if ((c = *find++) != '\0') { - len = strlen(find); - do { - do { - if ((sc = *s++) == '\0') - return (NULL); - } while (sc != c); - } while (strncmp(s, find, len) != 0); - s--; + const unsigned char *z; + size_t l, ip, jp, k, p, ms, p0, mem, mem0; + size_t byteset[32 / sizeof(size_t)] = { 0 }; + size_t shift[256]; + + /* Computing length of needle and fill shift table */ + for (l=0; n[l] && h[l]; l++) + BITOP(byteset, n[l], |=), shift[n[l]] = l+1; + if (n[l]) return 0; /* hit the end of h */ + + /* Compute maximal suffix */ + ip = -1; jp = 0; k = p = 1; + while (jp+k n[jp+k]) { + jp += k; + k = 1; + p = jp - ip; + } else { + ip = jp++; + k = p = 1; + } + } + ms = ip; + p0 = p; + + /* And with the opposite comparison */ + ip = -1; jp = 0; k = p = 1; + while (jp+k ms+1) ms = ip; + else p = p0; + + /* Periodic needle? */ + if (memcmp(n, n+p, ms+1)) { + mem0 = 0; + p = MAX(ms, l-ms-1) + 1; + } else mem0 = l-p; + mem = 0; + + /* Initialize incremental end-of-haystack pointer */ + z = h; + + /* Search loop */ + for (;;) { + /* Update incremental end-of-haystack pointer */ + if (z-h < l) { + /* Fast estimate for MIN(l,63) */ + size_t grow = l | 63; + const unsigned char *z2 = memchr(z, 0, grow); + if (z2) { + z = z2; + if (z-h < l) return 0; + } else z += grow; + } + + /* Check last byte first; advance by shift on mismatch */ + if (BITOP(byteset, h[l-1], &)) { + k = l-shift[h[l-1]]; + //printf("adv by %zu (on %c) at [%s] (%zu;l=%zu)\n", k, h[l-1], h, shift[h[l-1]], l); + if (k) { + if (mem0 && mem && k < p) k = l-p; + h += k; + mem = 0; + continue; + } + } else { + h += l; + mem = 0; + continue; + } + + /* Compare right half */ + for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++); + if (n[k]) { + h += k-ms; + mem = 0; + continue; + } + /* Compare left half */ + for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--); + if (k <= mem) return (char *)h; + h += p; + mem = mem0; } - return ((char *)s); +} + +char *strstr(const char *h, const char *n) +{ + /* Return immediately on empty needle */ + if (!n[0]) return (char *)h; + + /* Use faster algorithms for short needles */ + h = strchr(h, *n); + if (!h || !n[1]) return (char *)h; + if (!h[1]) return 0; + if (!n[2]) return twobyte_strstr((void *)h, (void *)n); + if (!h[2]) return 0; + if (!n[3]) return threebyte_strstr((void *)h, (void *)n); + if (!h[3]) return 0; + if (!n[4]) return fourbyte_strstr((void *)h, (void *)n); + + return twoway_strstr((void *)h, (void *)n); } Index: lib/libc/sys/Makefile.inc =================================================================== --- lib/libc/sys/Makefile.inc +++ lib/libc/sys/Makefile.inc @@ -45,6 +45,7 @@ accept \ accept4 \ aio_suspend \ + clock_nanosleep \ close \ connect \ fcntl \ @@ -360,6 +361,7 @@ chown.2 lchown.2 MLINKS+=clock_gettime.2 clock_getres.2 \ clock_gettime.2 clock_settime.2 +MLINKS+=nanosleep.2 clock_nanosleep.2 MLINKS+=cpuset.2 cpuset_getid.2 \ cpuset.2 cpuset_setid.2 MLINKS+=cpuset_getaffinity.2 cpuset_setaffinity.2 Index: lib/libc/sys/Symbol.map =================================================================== --- lib/libc/sys/Symbol.map +++ lib/libc/sys/Symbol.map @@ -399,6 +399,7 @@ }; FBSD_1.5 { + clock_nanosleep; fdatasync; }; @@ -511,6 +512,7 @@ __sys_clock_getres; _clock_gettime; __sys_clock_gettime; + __sys_clock_nanosleep; _clock_settime; __sys_clock_settime; _close; Index: lib/libc/sys/clock_nanosleep.c =================================================================== --- lib/libc/sys/clock_nanosleep.c +++ lib/libc/sys/clock_nanosleep.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2017 Eric van Gyzen * Copyright (c) 2014 The FreeBSD Foundation. * All rights reserved. * @@ -34,58 +35,19 @@ __FBSDID("$FreeBSD$"); #include +#include #include "libc_private.h" -#define SLOT(a, b) \ - [INTERPOS_##a] = (interpos_func_t)b -interpos_func_t __libc_interposing[INTERPOS_MAX] = { - SLOT(accept, __sys_accept), - SLOT(accept4, __sys_accept4), - SLOT(aio_suspend, __sys_aio_suspend), - SLOT(close, __sys_close), - SLOT(connect, __sys_connect), - SLOT(fcntl, __sys_fcntl), - SLOT(fsync, __sys_fsync), - SLOT(fork, __sys_fork), - SLOT(msync, __sys_msync), - SLOT(nanosleep, __sys_nanosleep), - SLOT(openat, __sys_openat), - SLOT(poll, __sys_poll), - SLOT(pselect, __sys_pselect), - SLOT(read, __sys_read), - SLOT(readv, __sys_readv), - SLOT(recvfrom, __sys_recvfrom), - SLOT(recvmsg, __sys_recvmsg), - SLOT(select, __sys_select), - SLOT(sendmsg, __sys_sendmsg), - SLOT(sendto, __sys_sendto), - SLOT(setcontext, __sys_setcontext), - SLOT(sigaction, __sys_sigaction), - SLOT(sigprocmask, __sys_sigprocmask), - SLOT(sigsuspend, __sys_sigsuspend), - SLOT(sigwait, __libc_sigwait), - SLOT(sigtimedwait, __sys_sigtimedwait), - SLOT(sigwaitinfo, __sys_sigwaitinfo), - SLOT(swapcontext, __sys_swapcontext), - SLOT(system, __libc_system), - SLOT(tcdrain, __libc_tcdrain), - SLOT(wait4, __sys_wait4), - SLOT(write, __sys_write), - SLOT(writev, __sys_writev), - SLOT(_pthread_mutex_init_calloc_cb, _pthread_mutex_init_calloc_cb_stub), - SLOT(spinlock, __libc_spinlock_stub), - SLOT(spinunlock, __libc_spinunlock_stub), - SLOT(kevent, __sys_kevent), - SLOT(wait6, __sys_wait6), - SLOT(ppoll, __sys_ppoll), - SLOT(map_stacks_exec, __libc_map_stacks_exec), - SLOT(fdatasync, __sys_fdatasync), -}; -#undef SLOT +__weak_reference(__sys_clock_nanosleep, __clock_nanosleep); -interpos_func_t * -__libc_interposing_slot(int interposno) +#pragma weak clock_nanosleep +int +clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, + struct timespec *rmtp) { - return (&__libc_interposing[interposno]); + return (((int (*)(clockid_t, int, const struct timespec *, + struct timespec *)) + __libc_interposing[INTERPOS_clock_nanosleep])(clock_id, flags, + rqtp, rmtp)); } Index: lib/libc/sys/interposing_table.c =================================================================== --- lib/libc/sys/interposing_table.c +++ lib/libc/sys/interposing_table.c @@ -80,6 +80,7 @@ SLOT(ppoll, __sys_ppoll), SLOT(map_stacks_exec, __libc_map_stacks_exec), SLOT(fdatasync, __sys_fdatasync), + SLOT(clock_nanosleep, __sys_clock_nanosleep), }; #undef SLOT Index: lib/libc/sys/nanosleep.2 =================================================================== --- lib/libc/sys/nanosleep.2 +++ lib/libc/sys/nanosleep.2 @@ -1,5 +1,4 @@ -.\" $OpenBSD: nanosleep.2,v 1.1 1997/04/20 20:56:20 tholo Exp $ -.\" $NetBSD: nanosleep.2,v 1.1 1997/04/17 18:12:02 jtc Exp $ +.\" $NetBSD: nanosleep.2,v 1.23 2016/11/14 10:40:59 wiz Exp $ .\" .\" Copyright (c) 1986, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,51 +30,136 @@ .\" @(#)sleep.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd April 17, 1997 +.Dd March 17, 2017 .Dt NANOSLEEP 2 .Os .Sh NAME .Nm nanosleep -.Nd suspend process execution for an interval measured in nanoseconds +.Nd high resolution sleep .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In time.h .Ft int -.Fn nanosleep "const struct timespec *rqtp" "struct timespec *rmtp" +.Fo clock_nanosleep +.Fa "clockid_t clock_id" +.Fa "int flags" +.Fa "const struct timespec *rqtp" +.Fa "struct timespec *rmtp" +.Fc +.Ft int +.Fo nanosleep +.Fa "const struct timespec *rqtp" +.Fa "struct timespec *rmtp" +.Fc .Sh DESCRIPTION -The -.Fn nanosleep -system call -causes the calling thread to sleep until the time interval specified by +If the +.Dv TIMER_ABSTIME +flag is not set in the +.Fa flags +argument, then +.Fn clock_nanosleep +suspends execution of the calling thread until either the +time interval specified by the +.Fa rqtp +argument has elapsed, +or a signal is delivered to the calling process and its +action is to invoke a signal-catching function or to terminate the +process. +The clock used to measure the time is specified by the +.Fa clock_id +argument. +.Pp +If the +.Dv TIMER_ABSTIME +flag is set in the +.Fa flags +argument, then +.Fn clock_nanosleep +suspends execution of the calling thread until either the value +of the clock specified by the +.Fa clock_id +argument reaches the absolute time specified by the +.Fa rqtp +argument, +or a signal is delivered to the calling process and its +action is to invoke a signal-catching function or to terminate the +process. +If, at the time of the call, the time value specified by .Fa rqtp -has elapsed. -An unmasked signal will -cause it to terminate the sleep early, regardless of the +is less than or equal to the time value of the specified clock, then +.Fn clock_nanosleep +returns immediately and the calling thread is not suspended. +.Pp +The suspension time may be longer than requested due to the +scheduling of other activity by the system. +An unmasked signal will terminate the sleep early, regardless of the .Dv SA_RESTART value on the interrupting signal. -.Sh RETURN VALUES -If the +The +.Fa rqtp +and +.Fa rmtp +arguments can point to the same object. +.Pp +The following +.Fa clock_id +values are supported: +.Pp +.Bl -item -compact -offset indent +.It +CLOCK_MONOTONIC +.It +CLOCK_MONOTONIC_FAST +.It +CLOCK_MONOTONIC_PRECISE +.It +CLOCK_REALTIME +.It +CLOCK_REALTIME_FAST +.It +CLOCK_REALTIME_PRECISE +.It +CLOCK_SECOND +.It +CLOCK_UPTIME +.It +CLOCK_UPTIME_FAST +.It +CLOCK_UPTIME_PRECISE +.El +.Pp +The .Fn nanosleep -system call returns because the requested time has elapsed, the value -returned will be zero. +function behaves like +.Fn clock_nanosleep +with a +.Fa clock_id +argument of +.Dv CLOCK_REALTIME +and without the +.Dv TIMER_ABSTIME +flag in the +.Fa flags +argument. +.Sh RETURN VALUES +These functions return zero when the requested time has elapsed. .Pp -If the +If these functions return for any other reason, then +.Fn clock_nanosleep +will directly return the error number, and .Fn nanosleep -system call returns due to the delivery of a signal, the value returned -will be -1, and the global variable +will return \-1 with the global variable .Va errno -will be set to indicate the interruption. -If +set to indicate the error. +If a relative sleep is interrupted by a signal and .Fa rmtp is -.No non- Ns Dv NULL , +.Pf non- Dv NULL , the timespec structure it references is updated to contain the unslept amount (the request time minus the time actually slept). .Sh ERRORS -The -.Fn nanosleep -system call fails if: +These functions can fail with the following errors. .Bl -tag -width Er .It Bq Er EFAULT Either @@ -85,27 +169,32 @@ points to memory that is not a valid part of the process address space. .It Bq Er EINTR -The -.Fn nanosleep -system call -was interrupted by the delivery of a signal. +The function was interrupted by the delivery of a signal. .It Bq Er EINVAL The .Fa rqtp -argument -specified a nanosecond value less than zero +argument specified a nanosecond value less than zero or greater than or equal to 1000 million. -.It Bq Er ENOSYS +.It Bq Er EINVAL The -.Fn nanosleep -system call -is not supported by this implementation. +.Fa flags +argument contained an invalid flag. +.It Bq Er EINVAL +The +.Fa clock_id +argument was +.Dv CLOCK_THREAD_CPUTIME_ID +or an unrecognized value. +.It Bq Er ENOTSUP +The +.Fa clock_id +argument was valid but not supported by this implementation of +.Fn clock_nanosleep . .El .Sh SEE ALSO -.Xr sigsuspend 2 , +.Xr clock_gettime 2 , +.Xr sigaction 2 , .Xr sleep 3 .Sh STANDARDS -The -.Fn nanosleep -system call conforms to -.St -p1003.1b-93 . +These functions conform to +.St -p1003.1-2008 . Index: lib/libc/tests/sys/Makefile =================================================================== --- lib/libc/tests/sys/Makefile +++ lib/libc/tests/sys/Makefile @@ -12,6 +12,7 @@ NETBSD_ATF_TESTS_C+= bind_test NETBSD_ATF_TESTS_C+= chroot_test NETBSD_ATF_TESTS_C+= clock_gettime_test +NETBSD_ATF_TESTS_C+= clock_nanosleep_test NETBSD_ATF_TESTS_C+= connect_test NETBSD_ATF_TESTS_C+= dup_test NETBSD_ATF_TESTS_C+= fsync_test Index: lib/libthr/thread/thr_private.h =================================================================== --- lib/libthr/thread/thr_private.h +++ lib/libthr/thread/thr_private.h @@ -865,6 +865,8 @@ /* #include */ #ifdef _TIME_H_ +int __sys_clock_nanosleep(clockid_t, int, const struct timespec *, + struct timespec *); int __sys_nanosleep(const struct timespec *, struct timespec *); #endif Index: lib/libthr/thread/thr_syscalls.c =================================================================== --- lib/libthr/thread/thr_syscalls.c +++ lib/libthr/thread/thr_syscalls.c @@ -260,6 +260,22 @@ } static int +__thr_clock_nanosleep(clockid_t clock_id, int flags, + const struct timespec *time_to_sleep, struct timespec *time_remaining) +{ + struct pthread *curthread; + int ret; + + curthread = _get_curthread(); + _thr_cancel_enter(curthread); + ret = __sys_clock_nanosleep(clock_id, flags, time_to_sleep, + time_remaining); + _thr_cancel_leave(curthread, 1); + + return (ret); +} + +static int __thr_nanosleep(const struct timespec *time_to_sleep, struct timespec *time_remaining) { @@ -668,6 +684,7 @@ SLOT(ppoll); SLOT(map_stacks_exec); SLOT(fdatasync); + SLOT(clock_nanosleep); #undef SLOT *(__libc_interposing_slot( INTERPOS__pthread_mutex_init_calloc_cb)) = Index: share/man/man3/pthread_testcancel.3 =================================================================== --- share/man/man3/pthread_testcancel.3 +++ share/man/man3/pthread_testcancel.3 @@ -1,5 +1,5 @@ .\" $FreeBSD$ -.Dd February 17, 2017 +.Dd March 18, 2017 .Dt PTHREAD_TESTCANCEL 3 .Os .Sh NAME @@ -105,6 +105,7 @@ .It Fn accept4 .It Fn aio_suspend .It Fn connect +.It Fn clock_nanosleep .It Fn close .It Fn creat .It Fn fcntl Index: sys/amd64/linux/linux.h =================================================================== --- sys/amd64/linux/linux.h +++ sys/amd64/linux/linux.h @@ -383,50 +383,6 @@ l_uintptr_t __pad; }; -/* - * Socket defines - */ - -#define LINUX_SOL_SOCKET 1 -#define LINUX_SOL_IP 0 -#define LINUX_SOL_IPX 256 -#define LINUX_SOL_AX25 257 -#define LINUX_SOL_TCP 6 -#define LINUX_SOL_UDP 17 - -#define LINUX_SO_DEBUG 1 -#define LINUX_SO_REUSEADDR 2 -#define LINUX_SO_TYPE 3 -#define LINUX_SO_ERROR 4 -#define LINUX_SO_DONTROUTE 5 -#define LINUX_SO_BROADCAST 6 -#define LINUX_SO_SNDBUF 7 -#define LINUX_SO_RCVBUF 8 -#define LINUX_SO_KEEPALIVE 9 -#define LINUX_SO_OOBINLINE 10 -#define LINUX_SO_NO_CHECK 11 -#define LINUX_SO_PRIORITY 12 -#define LINUX_SO_LINGER 13 -#define LINUX_SO_PASSCRED 16 -#define LINUX_SO_PEERCRED 17 -#define LINUX_SO_RCVLOWAT 18 -#define LINUX_SO_SNDLOWAT 19 -#define LINUX_SO_RCVTIMEO 20 -#define LINUX_SO_SNDTIMEO 21 -#define LINUX_SO_TIMESTAMP 29 -#define LINUX_SO_ACCEPTCONN 30 - -#define LINUX_IP_TOS 1 -#define LINUX_IP_TTL 2 -#define LINUX_IP_HDRINCL 3 -#define LINUX_IP_OPTIONS 4 - -#define LINUX_IP_MULTICAST_IF 32 -#define LINUX_IP_MULTICAST_TTL 33 -#define LINUX_IP_MULTICAST_LOOP 34 -#define LINUX_IP_ADD_MEMBERSHIP 35 -#define LINUX_IP_DROP_MEMBERSHIP 36 - struct l_sockaddr { l_ushort sa_family; char sa_data[14]; Index: sys/amd64/linux/linux_dummy.c =================================================================== --- sys/amd64/linux/linux_dummy.c +++ sys/amd64/linux/linux_dummy.c @@ -135,7 +135,6 @@ DUMMY(renameat2); /* linux 3.15: */ DUMMY(seccomp); -DUMMY(getrandom); DUMMY(memfd_create); DUMMY(kexec_file_load); /* linux 3.18: */ Index: sys/amd64/linux32/linux.h =================================================================== --- sys/amd64/linux32/linux.h +++ sys/amd64/linux32/linux.h @@ -474,37 +474,6 @@ l_uintptr_t __pad; } __packed; -/* - * Socket defines - */ -#define LINUX_SOL_SOCKET 1 -#define LINUX_SOL_IP 0 -#define LINUX_SOL_IPX 256 -#define LINUX_SOL_AX25 257 -#define LINUX_SOL_TCP 6 -#define LINUX_SOL_UDP 17 - -#define LINUX_SO_DEBUG 1 -#define LINUX_SO_REUSEADDR 2 -#define LINUX_SO_TYPE 3 -#define LINUX_SO_ERROR 4 -#define LINUX_SO_DONTROUTE 5 -#define LINUX_SO_BROADCAST 6 -#define LINUX_SO_SNDBUF 7 -#define LINUX_SO_RCVBUF 8 -#define LINUX_SO_KEEPALIVE 9 -#define LINUX_SO_OOBINLINE 10 -#define LINUX_SO_NO_CHECK 11 -#define LINUX_SO_PRIORITY 12 -#define LINUX_SO_LINGER 13 -#define LINUX_SO_PEERCRED 17 -#define LINUX_SO_RCVLOWAT 18 -#define LINUX_SO_SNDLOWAT 19 -#define LINUX_SO_RCVTIMEO 20 -#define LINUX_SO_SNDTIMEO 21 -#define LINUX_SO_TIMESTAMP 29 -#define LINUX_SO_ACCEPTCONN 30 - struct l_sockaddr { l_ushort sa_family; char sa_data[14]; Index: sys/amd64/linux32/linux32_dummy.c =================================================================== --- sys/amd64/linux32/linux32_dummy.c +++ sys/amd64/linux32/linux32_dummy.c @@ -144,7 +144,6 @@ DUMMY(renameat2); /* linux 3.15: */ DUMMY(seccomp); -DUMMY(getrandom); DUMMY(memfd_create); /* linux 3.18: */ DUMMY(bpf); Index: sys/arm/freescale/imx/imx51_ccm.c =================================================================== --- sys/arm/freescale/imx/imx51_ccm.c +++ sys/arm/freescale/imx/imx51_ccm.c @@ -77,6 +77,7 @@ #include #include +#include #include #include @@ -95,10 +96,34 @@ #define IMX51_CKIL_FREQ 32768 #endif +/* + * The fdt data does not provide reg properties describing the DPLL register + * blocks we need to access, presumably because the needed addresses are + * hard-coded within the linux driver. That leaves us with no choice but to do + * the same thing, if we want to run with vendor-supplied fdt data. So here we + * have tables of the physical addresses we need for each soc, and we'll use + * bus_space_map() at attach() time to get access to them. + */ +static uint32_t imx51_dpll_addrs[IMX51_N_DPLLS] = { + 0x83f80000, /* DPLL1 */ + 0x83f84000, /* DPLL2 */ + 0x83f88000, /* DPLL3 */ +}; + +static uint32_t imx53_dpll_addrs[IMX51_N_DPLLS] = { + 0x63f80000, /* DPLL1 */ + 0x63f84000, /* DPLL2 */ + 0x63f88000, /* DPLL3 */ +}; + +#define DPLL_REGS_SZ (16 * 1024) + struct imxccm_softc { device_t sc_dev; - struct resource *res[7]; + struct resource *ccmregs; u_int64_t pll_freq[IMX51_N_DPLLS]; + bus_space_tag_t pllbst; + bus_space_handle_t pllbsh[IMX51_N_DPLLS]; }; struct imxccm_softc *ccm_softc = NULL; @@ -126,15 +151,26 @@ EARLY_DRIVER_MODULE(imxccm, simplebus, imxccm_driver, imxccm_devclass, 0, 0, BUS_PASS_CPU); -static struct resource_spec imxccm_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Global registers */ - { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* DPLLIP1 */ - { SYS_RES_MEMORY, 2, RF_ACTIVE }, /* DPLLIP2 */ - { SYS_RES_MEMORY, 3, RF_ACTIVE }, /* DPLLIP3 */ - { SYS_RES_IRQ, 0, RF_ACTIVE }, /* 71 */ - { SYS_RES_IRQ, 1, RF_ACTIVE }, /* 72 */ - { -1, 0 } -}; +static inline uint32_t +pll_read_4(struct imxccm_softc *sc, int pll, int reg) +{ + + return (bus_space_read_4(sc->pllbst, sc->pllbsh[pll - 1], reg)); +} + +static inline uint32_t +ccm_read_4(struct imxccm_softc *sc, int reg) +{ + + return (bus_read_4(sc->ccmregs, reg)); +} + +static inline void +ccm_write_4(struct imxccm_softc *sc, int reg, uint32_t val) +{ + + bus_write_4(sc->ccmregs, reg, val); +} static int imxccm_match(device_t dev) @@ -155,13 +191,40 @@ imxccm_attach(device_t dev) { struct imxccm_softc *sc; + int idx; + u_int soc; + uint32_t *pll_addrs; sc = device_get_softc(dev); sc->sc_dev = dev; - if (bus_alloc_resources(dev, imxccm_spec, sc->res)) { + switch ((soc = imx_soc_type())) { + case IMXSOC_51: + pll_addrs = imx51_dpll_addrs; + break; + case IMXSOC_53: + pll_addrs = imx53_dpll_addrs; + break; + default: + device_printf(dev, "No support for SoC type 0x%08x\n", soc); + goto noclocks; + } + + idx = 0; + sc->ccmregs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &idx, + RF_ACTIVE); + if (sc->ccmregs == NULL) { device_printf(dev, "could not allocate resources\n"); - return (ENXIO); + goto noclocks; + } + + sc->pllbst = fdtbus_bs_tag; + for (idx = 0; idx < IMX51_N_DPLLS; ++idx) { + if (bus_space_map(sc->pllbst, pll_addrs[idx], DPLL_REGS_SZ, 0, + &sc->pllbsh[idx]) != 0) { + device_printf(dev, "Cannot map DPLL registers\n"); + goto noclocks; + } } ccm_softc = sc; @@ -186,6 +249,10 @@ return (0); + +noclocks: + + panic("Cannot continue without clock support"); } u_int @@ -210,13 +277,13 @@ case IMX51CLK_PLL3: return ccm_softc->pll_freq[clk-IMX51CLK_PLL1]; case IMX51CLK_PLL1SW: - ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR); + ccsr = ccm_read_4(ccm_softc, CCMC_CCSR); if ((ccsr & CCSR_PLL1_SW_CLK_SEL) == 0) return ccm_softc->pll_freq[1-1]; /* step clock */ /* FALLTHROUGH */ case IMX51CLK_PLL1STEP: - ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR); + ccsr = ccm_read_4(ccm_softc, CCMC_CCSR); switch ((ccsr & CCSR_STEP_SEL_MASK) >> CCSR_STEP_SEL_SHIFT) { case 0: return imx51_get_clock(IMX51CLK_LP_APM); @@ -233,34 +300,34 @@ } /*NOTREACHED*/ case IMX51CLK_PLL2SW: - ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR); + ccsr = ccm_read_4(ccm_softc, CCMC_CCSR); if ((ccsr & CCSR_PLL2_SW_CLK_SEL) == 0) return imx51_get_clock(IMX51CLK_PLL2); return 0; /* XXX PLL2 bypass clk */ case IMX51CLK_PLL3SW: - ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR); + ccsr = ccm_read_4(ccm_softc, CCMC_CCSR); if ((ccsr & CCSR_PLL3_SW_CLK_SEL) == 0) return imx51_get_clock(IMX51CLK_PLL3); return 0; /* XXX PLL3 bypass clk */ case IMX51CLK_LP_APM: - ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR); + ccsr = ccm_read_4(ccm_softc, CCMC_CCSR); return (ccsr & CCSR_LP_APM) ? imx51_get_clock(IMX51CLK_FPM) : IMX51_OSC_FREQ; case IMX51CLK_ARM_ROOT: freq = imx51_get_clock(IMX51CLK_PLL1SW); - cacrr = bus_read_4(ccm_softc->res[0], CCMC_CACRR); + cacrr = ccm_read_4(ccm_softc, CCMC_CACRR); return freq / (cacrr + 1); /* ... */ case IMX51CLK_MAIN_BUS_CLK_SRC: - cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR); + cbcdr = ccm_read_4(ccm_softc, CCMC_CBCDR); if ((cbcdr & CBCDR_PERIPH_CLK_SEL) == 0) freq = imx51_get_clock(IMX51CLK_PLL2SW); else { freq = 0; - cbcmr = bus_read_4(ccm_softc->res[0], CCMC_CBCMR); + cbcmr = ccm_read_4(ccm_softc, CCMC_CBCMR); switch ((cbcmr & CBCMR_PERIPH_APM_SEL_MASK) >> CBCMR_PERIPH_APM_SEL_SHIFT) { case 0: @@ -280,29 +347,29 @@ return freq; case IMX51CLK_MAIN_BUS_CLK: freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK_SRC); - cdcr = bus_read_4(ccm_softc->res[0], CCMC_CDCR); + cdcr = ccm_read_4(ccm_softc, CCMC_CDCR); return freq / (1 + ((cdcr & CDCR_PERIPH_CLK_DVFS_PODF_MASK) >> CDCR_PERIPH_CLK_DVFS_PODF_SHIFT)); case IMX51CLK_AHB_CLK_ROOT: freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK); - cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR); + cbcdr = ccm_read_4(ccm_softc, CCMC_CBCDR); return freq / (1 + ((cbcdr & CBCDR_AHB_PODF_MASK) >> CBCDR_AHB_PODF_SHIFT)); case IMX51CLK_IPG_CLK_ROOT: freq = imx51_get_clock(IMX51CLK_AHB_CLK_ROOT); - cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR); + cbcdr = ccm_read_4(ccm_softc, CCMC_CBCDR); return freq / (1 + ((cbcdr & CBCDR_IPG_PODF_MASK) >> CBCDR_IPG_PODF_SHIFT)); case IMX51CLK_PERCLK_ROOT: - cbcmr = bus_read_4(ccm_softc->res[0], CCMC_CBCMR); + cbcmr = ccm_read_4(ccm_softc, CCMC_CBCMR); if (cbcmr & CBCMR_PERCLK_IPG_SEL) return imx51_get_clock(IMX51CLK_IPG_CLK_ROOT); if (cbcmr & CBCMR_PERCLK_LP_APM_SEL) freq = imx51_get_clock(IMX51CLK_LP_APM); else freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK_SRC); - cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR); + cbcdr = ccm_read_4(ccm_softc, CCMC_CBCDR); #ifdef IMXCCMDEBUG printf("cbcmr=%x cbcdr=%x\n", cbcmr, cbcdr); @@ -316,8 +383,8 @@ CBCDR_PERCLK_PODF_SHIFT); return freq; case IMX51CLK_UART_CLK_ROOT: - cscdr1 = bus_read_4(ccm_softc->res[0], CCMC_CSCDR1); - cscmr1 = bus_read_4(ccm_softc->res[0], CCMC_CSCMR1); + cscdr1 = ccm_read_4(ccm_softc, CCMC_CSCDR1); + cscmr1 = ccm_read_4(ccm_softc, CCMC_CSCMR1); #ifdef IMXCCMDEBUG printf("cscdr1=%x cscmr1=%x\n", cscdr1, cscmr1); @@ -344,7 +411,7 @@ CSCDR1_UART_CLK_PODF_SHIFT)); case IMX51CLK_IPU_HSP_CLK_ROOT: freq = 0; - cbcmr = bus_read_4(ccm_softc->res[0], CCMC_CBCMR); + cbcmr = ccm_read_4(ccm_softc, CCMC_CBCMR); switch ((cbcmr & CBCMR_IPU_HSP_CLK_SEL_MASK) >> CBCMR_IPU_HSP_CLK_SEL_SHIFT) { case 0: @@ -387,16 +454,16 @@ KASSERT(1 <= pll_no && pll_no <= IMX51_N_DPLLS, ("Wrong PLL id")); - dp_ctrl = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_CTL); + dp_ctrl = pll_read_4(ccm_softc, pll_no, DPLL_DP_CTL); if (dp_ctrl & DP_CTL_HFSM) { - dp_op = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_OP); - dp_mfd = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_MFD); - dp_mfn = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_MFN); + dp_op = pll_read_4(ccm_softc, pll_no, DPLL_DP_HFS_OP); + dp_mfd = pll_read_4(ccm_softc, pll_no, DPLL_DP_HFS_MFD); + dp_mfn = pll_read_4(ccm_softc, pll_no, DPLL_DP_HFS_MFN); } else { - dp_op = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_OP); - dp_mfd = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_MFD); - dp_mfn = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_MFN); + dp_op = pll_read_4(ccm_softc, pll_no, DPLL_DP_OP); + dp_mfd = pll_read_4(ccm_softc, pll_no, DPLL_DP_MFD); + dp_mfn = pll_read_4(ccm_softc, pll_no, DPLL_DP_MFN); } pdf = dp_op & DP_OP_PDF_MASK; @@ -415,7 +482,7 @@ ref = 24000000; /* IMX51_OSC_FREQ */ break; case DP_CTL_REF_CLK_SEL_FPM: - ccr = bus_read_4(ccm_softc->res[0], CCMC_CCR); + ccr = ccm_read_4(ccm_softc, CCMC_CCR); if (ccr & CCR_FPM_MULT) /* TODO: get from FDT "fsl,imx-ckil" */ ref = 32768 * 1024; @@ -460,10 +527,10 @@ group = CCMR_CCGR_MODULE(clk_src); field = clk_src % CCMR_CCGR_NSOURCE; - reg = bus_read_4(ccm_softc->res[0], CCMC_CCGR(group)); + reg = ccm_read_4(ccm_softc, CCMC_CCGR(group)); reg &= ~(0x03 << field * 2); reg |= (mode << field * 2); - bus_write_4(ccm_softc->res[0], CCMC_CCGR(group), reg); + ccm_write_4(ccm_softc, CCMC_CCGR(group), reg); } int @@ -471,7 +538,7 @@ { uint32_t reg; - reg = bus_read_4(ccm_softc->res[0], + reg = ccm_read_4(ccm_softc, CCMC_CCGR(CCMR_CCGR_MODULE(clk_src))); return ((reg >> (clk_src % CCMR_CCGR_NSOURCE) * 2) & 0x03); } @@ -489,20 +556,20 @@ * Select PLL2 as the source for the USB clock. * The default is PLL3, but U-boot changes it to PLL2. */ - regval = bus_read_4(ccm_softc->res[0], CCMC_CSCMR1); + regval = ccm_read_4(ccm_softc, CCMC_CSCMR1); regval &= ~CSCMR1_USBOH3_CLK_SEL_MASK; regval |= 1 << CSCMR1_USBOH3_CLK_SEL_SHIFT; - bus_write_4(ccm_softc->res[0], CCMC_CSCMR1, regval); + ccm_write_4(ccm_softc, CCMC_CSCMR1, regval); /* * Set the USB clock pre-divider to div-by-5, post-divider to div-by-2. */ - regval = bus_read_4(ccm_softc->res[0], CCMC_CSCDR1); + regval = ccm_read_4(ccm_softc, CCMC_CSCDR1); regval &= ~CSCDR1_USBOH3_CLK_PODF_MASK; regval &= ~CSCDR1_USBOH3_CLK_PRED_MASK; regval |= 4 << CSCDR1_USBOH3_CLK_PRED_SHIFT; regval |= 1 << CSCDR1_USBOH3_CLK_PODF_SHIFT; - bus_write_4(ccm_softc->res[0], CCMC_CSCDR1, regval); + ccm_write_4(ccm_softc, CCMC_CSCDR1, regval); /* * The same two clocks gates are used on imx51 and imx53. @@ -522,9 +589,9 @@ * strange, but we'll go with it until more is known. */ if (imx_soc_type() == IMXSOC_53) { - regval = bus_read_4(ccm_softc->res[0], CCMC_CSCMR1); + regval = ccm_read_4(ccm_softc, CCMC_CSCMR1); regval |= 1 << CSCMR1_USBPHY_CLK_SEL_SHIFT; - bus_write_4(ccm_softc->res[0], CCMC_CSCMR1, regval); + ccm_write_4(ccm_softc, CCMC_CSCMR1, regval); } /* Index: sys/arm/freescale/imx/imx53_machdep.c =================================================================== --- sys/arm/freescale/imx/imx53_machdep.c +++ sys/arm/freescale/imx/imx53_machdep.c @@ -53,10 +53,6 @@ imx53_attach(platform_t plat) { - /* XXX - Get rid of this stuff soon. */ - boothowto |= RB_VERBOSE|RB_MULTIPLE; - bootverbose = 1; - return (0); } Index: sys/compat/freebsd32/freebsd32_misc.c =================================================================== --- sys/compat/freebsd32/freebsd32_misc.c +++ sys/compat/freebsd32/freebsd32_misc.c @@ -129,6 +129,8 @@ static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); +static int freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id, + int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp); void freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32) @@ -2226,28 +2228,48 @@ int freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) { + + return (freebsd32_user_clock_nanosleep(td, CLOCK_REALTIME, + TIMER_RELTIME, uap->rqtp, uap->rmtp)); +} + +int +freebsd32_clock_nanosleep(struct thread *td, + struct freebsd32_clock_nanosleep_args *uap) +{ + int error; + + error = freebsd32_user_clock_nanosleep(td, uap->clock_id, uap->flags, + uap->rqtp, uap->rmtp); + return (kern_posix_error(td, error)); +} + +static int +freebsd32_user_clock_nanosleep(struct thread *td, clockid_t clock_id, + int flags, const struct timespec32 *ua_rqtp, struct timespec32 *ua_rmtp) +{ struct timespec32 rmt32, rqt32; struct timespec rmt, rqt; int error; - error = copyin(uap->rqtp, &rqt32, sizeof(rqt32)); + error = copyin(ua_rqtp, &rqt32, sizeof(rqt32)); if (error) return (error); CP(rqt32, rqt, tv_sec); CP(rqt32, rqt, tv_nsec); - if (uap->rmtp && - !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) + if (ua_rmtp != NULL && (flags & TIMER_ABSTIME) == 0 && + !useracc(ua_rmtp, sizeof(rmt32), VM_PROT_WRITE)) return (EFAULT); - error = kern_nanosleep(td, &rqt, &rmt); - if (error && uap->rmtp) { + error = kern_clock_nanosleep(td, clock_id, flags, &rqt, &rmt); + if (error == EINTR && ua_rmtp != NULL && (flags & TIMER_ABSTIME) == 0) { int error2; CP(rmt, rmt32, tv_sec); CP(rmt, rmt32, tv_nsec); - error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32)); + error2 = copyout(&rmt32, ua_rmtp, sizeof(rmt32)); if (error2) error = error2; } Index: sys/compat/freebsd32/syscalls.master =================================================================== --- sys/compat/freebsd32/syscalls.master +++ sys/compat/freebsd32/syscalls.master @@ -462,7 +462,10 @@ struct ffclock_estimate *cest); } 243 AUE_NULL NOPROTO { int ffclock_getestimate( \ struct ffclock_estimate *cest); } -244 AUE_NULL UNIMPL nosys +244 AUE_NULL STD { int freebsd32_clock_nanosleep( \ + clockid_t clock_id, int flags, \ + const struct timespec32 *rqtp, \ + struct timespec32 *rmtp); } 245 AUE_NULL UNIMPL nosys 246 AUE_NULL UNIMPL nosys 247 AUE_NULL STD { int freebsd32_clock_getcpuclockid2(\ Index: sys/compat/linsysfs/linsysfs.c =================================================================== --- sys/compat/linsysfs/linsysfs.c +++ sys/compat/linsysfs/linsysfs.c @@ -221,13 +221,62 @@ } /* + * Filler function for sys/devices/system/cpu/online + */ +static int +linsysfs_cpuonline(PFS_FILL_ARGS) +{ + + sbuf_printf(sb, "%d-%d\n", CPU_FIRST(), mp_maxid); + return (0); +} + +/* + * Filler function for sys/devices/system/cpu/cpuX/online + */ +static int +linsysfs_cpuxonline(PFS_FILL_ARGS) +{ + + sbuf_printf(sb, "1\n"); + return (0); +} + +static void +linsysfs_listcpus(struct pfs_node *dir) +{ + struct pfs_node *cpu; + char *name; + int i, count, len; + + len = 1; + count = mp_maxcpus; + while (count > 10) { + count /= 10; + len++; + } + len += sizeof("cpu"); + name = malloc(len, M_TEMP, M_WAITOK); + + for (i = 0; i < mp_ncpus; ++i) { + /* /sys/devices/system/cpu/cpuX */ + sprintf(name, "cpu%d", i); + cpu = pfs_create_dir(dir, name, NULL, NULL, NULL, 0); + + pfs_create_file(cpu, "online", &linsysfs_cpuxonline, + NULL, NULL, NULL, PFS_RD); + } + free(name, M_TEMP); +} + +/* * Constructor */ static int linsysfs_init(PFS_INIT_ARGS) { struct pfs_node *root; - struct pfs_node *dir; + struct pfs_node *dir, *sys, *cpu; struct pfs_node *pci; struct pfs_node *scsi; devclass_t devclass; @@ -241,10 +290,10 @@ scsi = pfs_create_dir(root, "class", NULL, NULL, NULL, 0); scsi = pfs_create_dir(scsi, "scsi_host", NULL, NULL, NULL, 0); - /* /sys/device */ + /* /sys/devices */ dir = pfs_create_dir(root, "devices", NULL, NULL, NULL, 0); - /* /sys/device/pci0000:00 */ + /* /sys/devices/pci0000:00 */ pci = pfs_create_dir(dir, "pci0000:00", NULL, NULL, NULL, 0); devclass = devclass_find("root"); @@ -254,6 +303,18 @@ dev = devclass_get_device(devclass, 0); linsysfs_run_bus(dev, pci, scsi, "/pci0000:00", "0000"); + + /* /sys/devices/system */ + sys = pfs_create_dir(dir, "system", NULL, NULL, NULL, 0); + + /* /sys/devices/system/cpu */ + cpu = pfs_create_dir(sys, "cpu", NULL, NULL, NULL, 0); + + pfs_create_file(cpu, "online", &linsysfs_cpuonline, + NULL, NULL, NULL, PFS_RD); + + linsysfs_listcpus(cpu); + return (0); } Index: sys/compat/linux/linux_misc.h =================================================================== --- sys/compat/linux/linux_misc.h +++ sys/compat/linux/linux_misc.h @@ -145,6 +145,10 @@ #define LINUX_RLIM_INFINITY (~0UL) +/* Linux getrandom flags */ +#define LINUX_GRND_NONBLOCK 0x0001 +#define LINUX_GRND_RANDOM 0x0002 + int linux_common_wait(struct thread *td, int pid, int *status, int options, struct rusage *ru); void linux_to_bsd_waitopts(int options, int *bsdopts); Index: sys/compat/linux/linux_misc.c =================================================================== --- sys/compat/linux/linux_misc.c +++ sys/compat/linux/linux_misc.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,7 @@ #include #include #include +#include #include @@ -2508,3 +2510,27 @@ if (options & __WCLONE) *bsdopts |= WLINUXCLONE; } + +int +linux_getrandom(struct thread *td, struct linux_getrandom_args *args) +{ + struct uio uio; + struct iovec iov; + + if (args->flags & ~(LINUX_GRND_NONBLOCK|LINUX_GRND_RANDOM)) + return (EINVAL); + if (args->count > INT_MAX) + args->count = INT_MAX; + + iov.iov_base = args->buf; + iov.iov_len = args->count; + + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_resid = iov.iov_len; + uio.uio_segflg = UIO_USERSPACE; + uio.uio_rw = UIO_READ; + uio.uio_td = td; + + return (read_random_uio(&uio, args->flags & LINUX_GRND_NONBLOCK)); +} Index: sys/compat/linux/linux_socket.h =================================================================== --- sys/compat/linux/linux_socket.h +++ sys/compat/linux/linux_socket.h @@ -172,6 +172,39 @@ #define LINUX_SENDMMSG 20 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ +/* Socket defines */ +#define LINUX_SOL_SOCKET 1 +#define LINUX_SOL_IP 0 +#define LINUX_SOL_TCP 6 +#define LINUX_SOL_UDP 17 +#define LINUX_SOL_IPV6 41 +#define LINUX_SOL_IPX 256 +#define LINUX_SOL_AX25 257 + +#define LINUX_SO_DEBUG 1 +#define LINUX_SO_REUSEADDR 2 +#define LINUX_SO_TYPE 3 +#define LINUX_SO_ERROR 4 +#define LINUX_SO_DONTROUTE 5 +#define LINUX_SO_BROADCAST 6 +#define LINUX_SO_SNDBUF 7 +#define LINUX_SO_RCVBUF 8 +#define LINUX_SO_KEEPALIVE 9 +#define LINUX_SO_OOBINLINE 10 +#define LINUX_SO_NO_CHECK 11 +#define LINUX_SO_PRIORITY 12 +#define LINUX_SO_LINGER 13 +#ifndef LINUX_SO_PASSCRED /* powerpc differs */ +#define LINUX_SO_PASSCRED 16 +#define LINUX_SO_PEERCRED 17 +#define LINUX_SO_RCVLOWAT 18 +#define LINUX_SO_SNDLOWAT 19 +#define LINUX_SO_RCVTIMEO 20 +#define LINUX_SO_SNDTIMEO 21 +#endif +#define LINUX_SO_TIMESTAMP 29 +#define LINUX_SO_ACCEPTCONN 30 + /* Socket options */ #define LINUX_IP_TOS 1 #define LINUX_IP_TTL 2 Index: sys/compat/linux/linux_socket.c =================================================================== --- sys/compat/linux/linux_socket.c +++ sys/compat/linux/linux_socket.c @@ -1547,7 +1547,6 @@ return (kern_setsockopt(td, args->s, bsd_args.level, name, &tv, UIO_SYSSPACE, sizeof(tv))); /* NOTREACHED */ - break; default: break; } @@ -1619,9 +1618,8 @@ return (copyout(&linux_tv, PTRIN(args->optval), sizeof(linux_tv))); /* NOTREACHED */ - break; case LOCAL_PEERCRED: - if (args->optlen != sizeof(lxu)) + if (args->optlen < sizeof(lxu)) return (EINVAL); xulen = sizeof(xu); error = kern_getsockopt(td, args->s, bsd_args.level, @@ -1636,7 +1634,6 @@ lxu.gid = xu.cr_gid; return (copyout(&lxu, PTRIN(args->optval), sizeof(lxu))); /* NOTREACHED */ - break; case SO_ERROR: len = sizeof(newval); error = kern_getsockopt(td, args->s, bsd_args.level, Index: sys/compat/linux/linux_time.c =================================================================== --- sys/compat/linux/linux_time.c +++ sys/compat/linux/linux_time.c @@ -142,7 +142,7 @@ LIN_SDT_PROBE2(time, linux_to_native_timespec, entry, ntp, ltp); - if (ltp->tv_sec < 0 || ltp->tv_nsec > (l_long)999999999L) { + if (ltp->tv_sec < 0 || (l_ulong)ltp->tv_nsec > 999999999L) { LIN_SDT_PROBE1(time, linux_to_native_timespec, return, EINVAL); return (EINVAL); } @@ -519,7 +519,7 @@ return (error); } error = kern_nanosleep(td, &rqts, rmtp); - if (args->rmtp != NULL) { + if (error == EINTR && args->rmtp != NULL) { error2 = native_to_linux_timespec(&lrmts, rmtp); if (error2 != 0) return (error2); @@ -583,7 +583,7 @@ return (error); } error = kern_nanosleep(td, &rqts, rmtp); - if (args->rmtp != NULL) { + if (error == EINTR && args->rmtp != NULL) { /* XXX. Not for TIMER_ABSTIME */ error2 = native_to_linux_timespec(&lrmts, rmtp); if (error2 != 0) Index: sys/ddb/db_expr.c =================================================================== --- sys/ddb/db_expr.c +++ sys/ddb/db_expr.c @@ -261,7 +261,7 @@ lhs <<= rhs; else { /* Shift right is unsigned */ - lhs = (unsigned) lhs >> rhs; + lhs = (db_addr_t)lhs >> rhs; } t = db_read_token(); } Index: sys/dev/isp/isp.c =================================================================== --- sys/dev/isp/isp.c +++ sys/dev/isp/isp.c @@ -5989,8 +5989,6 @@ return (1); case RQSTYPE_ATIO: case RQSTYPE_CTIO: - case RQSTYPE_ENABLE_LUN: - case RQSTYPE_MODIFY_LUN: case RQSTYPE_NOTIFY: case RQSTYPE_NOTIFY_ACK: case RQSTYPE_CTIO1: Index: sys/dev/isp/isp_freebsd.c =================================================================== --- sys/dev/isp/isp_freebsd.c +++ sys/dev/isp/isp_freebsd.c @@ -788,7 +788,6 @@ static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *); static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *); static void isp_handle_platform_ctio(ispsoftc_t *, void *); -static void isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *); static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *); static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *, uint32_t rsp); static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *); @@ -1632,23 +1631,10 @@ static void isp_target_putback_atio(union ccb *ccb) { - ispsoftc_t *isp; - struct ccb_scsiio *cso; - void *qe; + ispsoftc_t *isp = XS_ISP(ccb); + struct ccb_scsiio *cso = &ccb->csio; at2_entry_t local, *at = &local; - isp = XS_ISP(ccb); - - qe = isp_getrqentry(isp); - if (qe == NULL) { - xpt_print(ccb->ccb_h.path, - "%s: Request Queue Overflow\n", __func__); - callout_reset(&PISP_PCMD(ccb)->wdog, 10, - isp_refire_putback_atio, ccb); - return; - } - memset(qe, 0, QENTRY_LEN); - cso = &ccb->csio; ISP_MEMZERO(at, sizeof (at2_entry_t)); at->at_header.rqs_entry_type = RQSTYPE_ATIO2; at->at_header.rqs_entry_count = 1; @@ -1660,10 +1646,11 @@ at->at_status = CT_OK; at->at_rxid = cso->tag_id; at->at_iid = cso->ccb_h.target_id; - isp_put_atio2(isp, at, qe); - ISP_TDQE(isp, "isp_target_putback_atio", isp->isp_reqidx, qe); - ISP_SYNC_REQUEST(isp); - isp_complete_ctio(ccb); + if (isp_target_put_entry(isp, at)) { + callout_reset(&PISP_PCMD(ccb)->wdog, 10, + isp_refire_putback_atio, ccb); + } else + isp_complete_ctio(ccb); } static void @@ -2295,79 +2282,6 @@ } static void -isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp) -{ - int needack = 1; - switch (inp->in_status) { - case IN_PORT_LOGOUT: - /* - * XXX: Need to delete this initiator's WWN from the database - * XXX: Need to send this LOGOUT upstream - */ - isp_prt(isp, ISP_LOGWARN, "port logout of S_ID 0x%x", inp->in_iid); - break; - case IN_PORT_CHANGED: - isp_prt(isp, ISP_LOGWARN, "port changed for S_ID 0x%x", inp->in_iid); - break; - case IN_GLOBAL_LOGO: - isp_del_all_wwn_entries(isp, 0); - isp_prt(isp, ISP_LOGINFO, "all ports logged out"); - break; - case IN_ABORT_TASK: - { - uint16_t nphdl, lun; - uint32_t sid; - uint64_t wwn; - fcportdb_t *lp; - isp_notify_t tmp, *nt = &tmp; - - if (ISP_CAP_SCCFW(isp)) { - lun = inp->in_scclun; - } else { - lun = inp->in_lun; - } - if (ISP_CAP_2KLOGIN(isp)) { - nphdl = ((in_fcentry_e_t *)inp)->in_iid; - } else { - nphdl = inp->in_iid; - } - if (isp_find_pdb_by_handle(isp, 0, nphdl, &lp)) { - wwn = lp->port_wwn; - sid = lp->portid; - } else { - wwn = INI_ANY; - sid = PORT_ANY; - } - isp_prt(isp, ISP_LOGTDEBUG0, "ABORT TASK RX_ID %x WWN 0x%016llx", - inp->in_seqid, (unsigned long long) wwn); - - ISP_MEMZERO(nt, sizeof (isp_notify_t)); - nt->nt_hba = isp; - nt->nt_tgt = FCPARAM(isp, 0)->isp_wwpn; - nt->nt_wwn = wwn; - nt->nt_nphdl = nphdl; - nt->nt_sid = sid; - nt->nt_did = PORT_ANY; - nt->nt_lun = lun; - nt->nt_tagval = inp->in_seqid; - nt->nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); - nt->nt_need_ack = 1; - nt->nt_channel = 0; - nt->nt_ncode = NT_ABORT_TASK; - nt->nt_lreserved = inp; - isp_handle_platform_target_tmf(isp, nt); - needack = 0; - break; - } - default: - break; - } - if (needack) { - isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp); - } -} - -static void isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) { uint16_t nphdl; @@ -2612,18 +2526,19 @@ fcportdb_t *lp; struct ccb_immediate_notify *inot; inot_private_data_t *ntp = NULL; + atio_private_data_t *atp; lun_id_t lun; - isp_prt(isp, ISP_LOGTDEBUG0, "%s: code 0x%x sid 0x%x tagval 0x%016llx chan %d lun 0x%x", __func__, notify->nt_ncode, + isp_prt(isp, ISP_LOGTDEBUG0, "%s: code 0x%x sid 0x%x tagval 0x%016llx chan %d lun %jx", __func__, notify->nt_ncode, notify->nt_sid, (unsigned long long) notify->nt_tagval, notify->nt_channel, notify->nt_lun); - /* - * NB: This assignment is necessary because of tricky type conversion. - * XXX: This is tricky and I need to check this. If the lun isn't known - * XXX: for the task management function, it does not of necessity follow - * XXX: that it should go up stream to the wildcard listener. - */ if (notify->nt_lun == LUN_ANY) { - lun = CAM_LUN_WILDCARD; + if (notify->nt_tagval == TAG_ANY) { + lun = CAM_LUN_WILDCARD; + } else { + atp = isp_find_atpd(isp, notify->nt_channel, + notify->nt_tagval & 0xffffffff); + lun = atp ? atp->lun : CAM_LUN_WILDCARD; + } } else { lun = notify->nt_lun; } @@ -2701,7 +2616,7 @@ xpt_done((union ccb *)inot); return; bad: - if (notify->nt_need_ack && notify->nt_lreserved) { + if (notify->nt_need_ack) { if (((isphdr_t *)notify->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) { if (isp_acknak_abts(isp, notify->nt_lreserved, ENOMEM)) { isp_prt(isp, ISP_LOGWARN, "you lose- unable to send an ACKNAK"); @@ -3215,7 +3130,10 @@ /* Search for the INOT among running. */ ntp = isp_find_ntpd(isp, XS_CHANNEL(accb), accb->cin1.tag_id, accb->cin1.seq_id); if (ntp != NULL) { - isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, ntp->data); + if (ntp->nt.nt_need_ack) { + isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, + ntp->nt.nt_lreserved); + } isp_put_ntpd(isp, XS_CHANNEL(accb), ntp); ccb->ccb_h.status = CAM_REQ_CMP; } else { @@ -4143,12 +4061,8 @@ isp_tna_t *tp = malloc(sizeof (*tp), M_DEVBUF, M_NOWAIT); if (tp) { tp->isp = isp; - if (inot) { - memcpy(tp->data, inot, sizeof (tp->data)); - tp->not = tp->data; - } else { - tp->not = NULL; - } + memcpy(tp->data, inot, sizeof (tp->data)); + tp->not = tp->data; callout_init_mtx(&tp->timer, &isp->isp_lock, 0); callout_reset(&tp->timer, 5, isp_refire_notify_ack, tp); @@ -4170,11 +4084,7 @@ isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x", __func__, hp->rqs_entry_type); break; case RQSTYPE_NOTIFY: - if (IS_24XX(isp)) { - isp_handle_platform_notify_24xx(isp, (in_fcentry_24xx_t *) hp); - } else { - isp_handle_platform_notify_fc(isp, (in_fcentry_t *) hp); - } + isp_handle_platform_notify_24xx(isp, (in_fcentry_24xx_t *) hp); break; case RQSTYPE_ATIO: isp_handle_platform_atio7(isp, (at7_entry_t *) hp); @@ -4188,55 +4098,6 @@ case RQSTYPE_CTIO: isp_handle_platform_ctio(isp, hp); break; - case RQSTYPE_ABTS_RCVD: - { - abts_t *abts = (abts_t *)hp; - isp_notify_t notify, *nt = ¬ify; - atio_private_data_t *atp; - fcportdb_t *lp; - uint16_t chan; - uint32_t sid, did; - - did = (abts->abts_did_hi << 16) | abts->abts_did_lo; - sid = (abts->abts_sid_hi << 16) | abts->abts_sid_lo; - ISP_MEMZERO(nt, sizeof (isp_notify_t)); - - nt->nt_hba = isp; - nt->nt_did = did; - nt->nt_nphdl = abts->abts_nphdl; - nt->nt_sid = sid; - isp_find_chan_by_did(isp, did, &chan); - if (chan == ISP_NOCHAN) { - nt->nt_tgt = TGT_ANY; - } else { - nt->nt_tgt = FCPARAM(isp, chan)->isp_wwpn; - if (isp_find_pdb_by_handle(isp, chan, abts->abts_nphdl, &lp)) { - nt->nt_wwn = lp->port_wwn; - } else { - nt->nt_wwn = INI_ANY; - } - } - /* - * Try hard to find the lun for this command. - */ - atp = isp_find_atpd(isp, chan, abts->abts_rxid_task); - nt->nt_lun = atp ? atp->lun : LUN_ANY; - nt->nt_need_ack = 1; - nt->nt_tagval = abts->abts_rxid_task; - nt->nt_tagval |= (((uint64_t) abts->abts_rxid_abts) << 32); - if (abts->abts_rxid_task == ISP24XX_NO_TASK) { - isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS from N-Port handle 0x%x Port 0x%06x has no task id (rx_id 0x%04x ox_id 0x%04x)", - abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rx_id, abts->abts_ox_id); - } else { - isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS from N-Port handle 0x%x Port 0x%06x for task 0x%x (rx_id 0x%04x ox_id 0x%04x)", - abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rxid_task, abts->abts_rx_id, abts->abts_ox_id); - } - nt->nt_channel = chan; - nt->nt_ncode = NT_ABORT_TASK; - nt->nt_lreserved = hp; - isp_handle_platform_target_tmf(isp, nt); - break; - } } break; } Index: sys/dev/isp/isp_library.h =================================================================== --- sys/dev/isp/isp_library.h +++ sys/dev/isp/isp_library.h @@ -181,8 +181,6 @@ void isp_get_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *); void isp_get_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *); void isp_get_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *); -void isp_put_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *); -void isp_get_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *); void isp_put_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *); void isp_put_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *); void isp_put_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *); Index: sys/dev/isp/isp_library.c =================================================================== --- sys/dev/isp/isp_library.c +++ sys/dev/isp/isp_library.c @@ -3055,78 +3055,6 @@ } void -isp_put_enable_lun(ispsoftc_t *isp, lun_entry_t *lesrc, lun_entry_t *ledst) -{ - int i; - isp_put_hdr(isp, &lesrc->le_header, &ledst->le_header); - ISP_IOXPUT_32(isp, lesrc->le_reserved, &ledst->le_reserved); - if (ISP_IS_SBUS(isp)) { - ISP_IOXPUT_8(isp, lesrc->le_lun, &ledst->le_rsvd); - ISP_IOXPUT_8(isp, lesrc->le_rsvd, &ledst->le_lun); - ISP_IOXPUT_8(isp, lesrc->le_ops, &ledst->le_tgt); - ISP_IOXPUT_8(isp, lesrc->le_tgt, &ledst->le_ops); - ISP_IOXPUT_8(isp, lesrc->le_status, &ledst->le_reserved2); - ISP_IOXPUT_8(isp, lesrc->le_reserved2, &ledst->le_status); - ISP_IOXPUT_8(isp, lesrc->le_cmd_count, &ledst->le_in_count); - ISP_IOXPUT_8(isp, lesrc->le_in_count, &ledst->le_cmd_count); - ISP_IOXPUT_8(isp, lesrc->le_cdb6len, &ledst->le_cdb7len); - ISP_IOXPUT_8(isp, lesrc->le_cdb7len, &ledst->le_cdb6len); - } else { - ISP_IOXPUT_8(isp, lesrc->le_lun, &ledst->le_lun); - ISP_IOXPUT_8(isp, lesrc->le_rsvd, &ledst->le_rsvd); - ISP_IOXPUT_8(isp, lesrc->le_ops, &ledst->le_ops); - ISP_IOXPUT_8(isp, lesrc->le_tgt, &ledst->le_tgt); - ISP_IOXPUT_8(isp, lesrc->le_status, &ledst->le_status); - ISP_IOXPUT_8(isp, lesrc->le_reserved2, &ledst->le_reserved2); - ISP_IOXPUT_8(isp, lesrc->le_cmd_count, &ledst->le_cmd_count); - ISP_IOXPUT_8(isp, lesrc->le_in_count, &ledst->le_in_count); - ISP_IOXPUT_8(isp, lesrc->le_cdb6len, &ledst->le_cdb6len); - ISP_IOXPUT_8(isp, lesrc->le_cdb7len, &ledst->le_cdb7len); - } - ISP_IOXPUT_32(isp, lesrc->le_flags, &ledst->le_flags); - ISP_IOXPUT_16(isp, lesrc->le_timeout, &ledst->le_timeout); - for (i = 0; i < 20; i++) { - ISP_IOXPUT_8(isp, lesrc->le_reserved3[i], &ledst->le_reserved3[i]); - } -} - -void -isp_get_enable_lun(ispsoftc_t *isp, lun_entry_t *lesrc, lun_entry_t *ledst) -{ - int i; - isp_get_hdr(isp, &lesrc->le_header, &ledst->le_header); - ISP_IOXGET_32(isp, &lesrc->le_reserved, ledst->le_reserved); - if (ISP_IS_SBUS(isp)) { - ISP_IOXGET_8(isp, &lesrc->le_lun, ledst->le_rsvd); - ISP_IOXGET_8(isp, &lesrc->le_rsvd, ledst->le_lun); - ISP_IOXGET_8(isp, &lesrc->le_ops, ledst->le_tgt); - ISP_IOXGET_8(isp, &lesrc->le_tgt, ledst->le_ops); - ISP_IOXGET_8(isp, &lesrc->le_status, ledst->le_reserved2); - ISP_IOXGET_8(isp, &lesrc->le_reserved2, ledst->le_status); - ISP_IOXGET_8(isp, &lesrc->le_cmd_count, ledst->le_in_count); - ISP_IOXGET_8(isp, &lesrc->le_in_count, ledst->le_cmd_count); - ISP_IOXGET_8(isp, &lesrc->le_cdb6len, ledst->le_cdb7len); - ISP_IOXGET_8(isp, &lesrc->le_cdb7len, ledst->le_cdb6len); - } else { - ISP_IOXGET_8(isp, &lesrc->le_lun, ledst->le_lun); - ISP_IOXGET_8(isp, &lesrc->le_rsvd, ledst->le_rsvd); - ISP_IOXGET_8(isp, &lesrc->le_ops, ledst->le_ops); - ISP_IOXGET_8(isp, &lesrc->le_tgt, ledst->le_tgt); - ISP_IOXGET_8(isp, &lesrc->le_status, ledst->le_status); - ISP_IOXGET_8(isp, &lesrc->le_reserved2, ledst->le_reserved2); - ISP_IOXGET_8(isp, &lesrc->le_cmd_count, ledst->le_cmd_count); - ISP_IOXGET_8(isp, &lesrc->le_in_count, ledst->le_in_count); - ISP_IOXGET_8(isp, &lesrc->le_cdb6len, ledst->le_cdb6len); - ISP_IOXGET_8(isp, &lesrc->le_cdb7len, ledst->le_cdb7len); - } - ISP_IOXGET_32(isp, &lesrc->le_flags, ledst->le_flags); - ISP_IOXGET_16(isp, &lesrc->le_timeout, ledst->le_timeout); - for (i = 0; i < 20; i++) { - ISP_IOXGET_8(isp, &lesrc->le_reserved3[i], ledst->le_reserved3[i]); - } -} - -void isp_put_notify_fc(ispsoftc_t *isp, in_fcentry_t *src, in_fcentry_t *dst) { isp_put_hdr(isp, &src->in_header, &dst->in_header); Index: sys/dev/isp/isp_target.h =================================================================== --- sys/dev/isp/isp_target.h +++ sys/dev/isp/isp_target.h @@ -64,16 +64,15 @@ uint64_t nt_wwn; /* source (wwn) */ uint64_t nt_tgt; /* destination (wwn) */ uint64_t nt_tagval; /* tag value */ + lun_id_t nt_lun; /* logical unit */ uint32_t nt_sid : 24; /* source port id */ uint32_t nt_failed : 1, /* notify operation failed */ nt_need_ack : 1, /* this notify needs an ACK */ nt_did : 24; /* destination port id */ - uint32_t - nt_lun : 16, /* logical unit */ - nt_nphdl : 16; /* n-port handle */ - uint8_t nt_channel; /* channel id */ + uint16_t nt_nphdl; /* n-port handle */ + uint8_t nt_channel; /* channel id */ isp_ncode_t nt_ncode; /* action */ } isp_notify_t; #define MATCH_TMD(tmd, iid, lun, tag) \ Index: sys/dev/isp/isp_target.c =================================================================== --- sys/dev/isp/isp_target.c +++ sys/dev/isp/isp_target.c @@ -58,10 +58,12 @@ static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *); static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *); +static void isp_handle_abts(ispsoftc_t *, abts_t *); static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *); static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *); static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *); -static void isp_handle_24xx_inotify(ispsoftc_t *, in_fcentry_24xx_t *); +static void isp_handle_notify(ispsoftc_t *, in_fcentry_t *); +static void isp_handle_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *); /* * The Qlogic driver gets an interrupt to look at response queue entries. @@ -112,8 +114,6 @@ int isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) { - uint16_t status; - uint32_t seqid; union { at2_entry_t *at2iop; at2e_entry_t *at2eiop; @@ -152,9 +152,7 @@ #define hdrp unp.hp } unp; uint8_t local[QENTRY_LEN]; - uint16_t iid; int bus, type, len, level, rval = 1; - isp_notify_t notify; type = isp_get_response_type(isp, (isphdr_t *)vptr); unp.vp = vptr; @@ -215,124 +213,19 @@ isp_handle_ctio7(isp, (ct7_entry_t *) local); break; - case RQSTYPE_ENABLE_LUN: - case RQSTYPE_MODIFY_LUN: - isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local); - isp_async(isp, ISPASYNC_TARGET_ACTION, local); - break; - case RQSTYPE_NOTIFY: bus = 0; if (IS_24XX(isp)) { isp_get_notify_24xx(isp, inot_24xx, (in_fcentry_24xx_t *)local); inot_24xx = (in_fcentry_24xx_t *) local; - isp_handle_24xx_inotify(isp, inot_24xx); - break; - } else { - if (ISP_CAP_2KLOGIN(isp)) { - in_fcentry_e_t *ecp = (in_fcentry_e_t *)local; - isp_get_notify_fc_e(isp, inote_fcp, ecp); - iid = ecp->in_iid; - status = ecp->in_status; - seqid = ecp->in_seqid; - } else { - in_fcentry_t *fcp = (in_fcentry_t *)local; - isp_get_notify_fc(isp, inot_fcp, fcp); - iid = fcp->in_iid; - status = fcp->in_status; - seqid = fcp->in_seqid; - } - } - - isp_prt(isp, ISP_LOGTDEBUG0, "Immediate Notify On Bus %d, status=0x%x seqid=0x%x", bus, status, seqid); - - switch (status) { - case IN_MSG_RECEIVED: - case IN_IDE_RECEIVED: - isp_got_msg_fc(isp, (in_fcentry_t *)local); - break; - case IN_RSRC_UNAVAIL: - isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs"); - isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, local); - break; - - case IN_RESET: - ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); - notify.nt_hba = isp; - notify.nt_wwn = INI_ANY; - notify.nt_tgt = TGT_ANY; - notify.nt_nphdl = iid; - notify.nt_sid = PORT_ANY; - notify.nt_did = PORT_ANY; - notify.nt_lun = LUN_ANY; - notify.nt_tagval = TAG_ANY; - notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); - notify.nt_ncode = NT_BUS_RESET; - notify.nt_need_ack = 1; - notify.nt_lreserved = local; - isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); - break; - - case IN_PORT_LOGOUT: - ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); - notify.nt_hba = isp; - notify.nt_wwn = INI_ANY; - notify.nt_nphdl = iid; - notify.nt_sid = PORT_ANY; - notify.nt_did = PORT_ANY; - notify.nt_ncode = NT_LOGOUT; - notify.nt_need_ack = 1; - notify.nt_lreserved = local; - isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); - break; - - case IN_ABORT_TASK: - ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); - notify.nt_hba = isp; - notify.nt_wwn = INI_ANY; - notify.nt_nphdl = iid; - notify.nt_sid = PORT_ANY; - notify.nt_did = PORT_ANY; - notify.nt_ncode = NT_ABORT_TASK; - notify.nt_need_ack = 1; - notify.nt_lreserved = local; - isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); - break; - - case IN_GLOBAL_LOGO: - isp_prt(isp, ISP_LOGTINFO, "%s: all ports logged out", __func__); - ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); - notify.nt_hba = isp; - notify.nt_wwn = INI_ANY; - notify.nt_nphdl = NIL_HANDLE; - notify.nt_sid = PORT_ANY; - notify.nt_did = PORT_ANY; - notify.nt_ncode = NT_GLOBAL_LOGOUT; - notify.nt_need_ack = 1; - notify.nt_lreserved = local; - isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); - break; - - case IN_PORT_CHANGED: - isp_prt(isp, ISP_LOGTINFO, "%s: port changed", __func__); - ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); - notify.nt_hba = isp; - notify.nt_wwn = INI_ANY; - notify.nt_nphdl = NIL_HANDLE; - notify.nt_sid = PORT_ANY; - notify.nt_did = PORT_ANY; - notify.nt_ncode = NT_CHANGED; - notify.nt_need_ack = 1; - notify.nt_lreserved = local; - isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); - break; - - default: - ISP_SNPRINTF(local, sizeof local, "%s: unknown status to RQSTYPE_NOTIFY (0x%x)", __func__, status); - isp_print_bytes(isp, local, QENTRY_LEN, vptr); - isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, local); + isp_handle_notify_24xx(isp, inot_24xx); break; } + if (ISP_CAP_2KLOGIN(isp)) + isp_get_notify_fc_e(isp, inote_fcp, (in_fcentry_e_t *)local); + else + isp_get_notify_fc(isp, inot_fcp, (in_fcentry_t *)local); + isp_handle_notify(isp, (in_fcentry_t *)local); break; case RQSTYPE_NOTIFY_ACK: @@ -367,7 +260,7 @@ case RQSTYPE_ABTS_RCVD: isp_get_abts(isp, abts, (abts_t *)local); - isp_async(isp, ISPASYNC_TARGET_ACTION, &local); + isp_handle_abts(isp, (abts_t *)local); break; case RQSTYPE_ABTS_RSP: isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local); @@ -421,22 +314,37 @@ return (-1); } switch (etype) { + case RQSTYPE_NOTIFY_ACK: + if (IS_24XX(isp)) + isp_put_notify_24xx_ack(isp, (na_fcentry_24xx_t *)ap, + (na_fcentry_24xx_t *)outp); + else if (ISP_CAP_2KLOGIN(isp)) + isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *)ap, + (na_fcentry_e_t *)outp); + else + isp_put_notify_ack_fc(isp, ap, (na_fcentry_t *)outp); + break; case RQSTYPE_ATIO2: - if (ISP_CAP_2KLOGIN(isp)) { - isp_put_atio2e(isp, (at2e_entry_t *) ap, (at2e_entry_t *) outp); - } else { - isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp); - } + if (ISP_CAP_2KLOGIN(isp)) + isp_put_atio2e(isp, (at2e_entry_t *)ap, + (at2e_entry_t *)outp); + else + isp_put_atio2(isp, (at2_entry_t *)ap, + (at2_entry_t *)outp); break; case RQSTYPE_CTIO2: - if (ISP_CAP_2KLOGIN(isp)) { - isp_put_ctio2e(isp, (ct2e_entry_t *) ap, (ct2e_entry_t *) outp); - } else { - isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp); - } + if (ISP_CAP_2KLOGIN(isp)) + isp_put_ctio2e(isp, (ct2e_entry_t *)ap, + (ct2e_entry_t *)outp); + else + isp_put_ctio2(isp, (ct2_entry_t *)ap, + (ct2_entry_t *)outp); break; case RQSTYPE_CTIO7: - isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp); + isp_put_ctio7(isp, (ct7_entry_t *)ap, (ct7_entry_t *)outp); + break; + case RQSTYPE_ABTS_RSP: + isp_put_abts_rsp(isp, (abts_rsp_t *)ap, (abts_rsp_t *)outp); break; default: isp_prt(isp, ISP_LOGERR, "%s: Unknown type 0x%x", __func__, etype); @@ -689,9 +597,6 @@ } default: isp_prt(isp, ISP_LOGERR, "%s: unknown event 0x%x", __func__, event); - if (isp->isp_state == ISP_RUNSTATE) { - isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, NULL); - } break; } } @@ -703,8 +608,8 @@ isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp) { isp_notify_t notify; - static const char f1[] = "%s from N-port handle 0x%x lun %x seq 0x%x"; - static const char f2[] = "unknown %s 0x%x lun %x N-Port handle 0x%x task flags 0x%x seq 0x%x\n"; + static const char f1[] = "%s from N-port handle 0x%x lun %jx seq 0x%x"; + static const char f2[] = "unknown %s 0x%x lun %jx N-Port handle 0x%x task flags 0x%x seq 0x%x\n"; uint16_t seqid, nphdl; ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); @@ -766,8 +671,8 @@ isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep) { isp_notify_t notify; - static const char f1[] = "%s from PortID 0x%06x lun %x seq 0x%08x"; - static const char f2[] = "unknown Task Flag 0x%x lun %x PortID 0x%x tag 0x%08x"; + static const char f1[] = "%s from PortID 0x%06x lun %jx seq 0x%08x"; + static const char f2[] = "unknown Task Flag 0x%x lun %jx PortID 0x%x tag 0x%08x"; fcportdb_t *lp; uint16_t chan; uint32_t sid, did; @@ -775,7 +680,7 @@ ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); notify.nt_hba = isp; notify.nt_wwn = INI_ANY; - notify.nt_lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | (aep->at_cmnd.fcp_cmnd_lun[1]); + notify.nt_lun = CAM_EXTLUN_BYTE_SWIZZLE(be64dec(aep->at_cmnd.fcp_cmnd_lun)); notify.nt_tagval = aep->at_rxid; notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); notify.nt_lreserved = aep; @@ -833,98 +738,79 @@ isp_notify_ack(ispsoftc_t *isp, void *arg) { char storage[QENTRY_LEN]; - void *outp; /* * This is in case a Task Management Function ends up here. */ - if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) { + if (IS_24XX(isp) && ((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO) { at7_entry_t *aep = arg; return (isp_endcmd(isp, aep, NIL_HANDLE, 0, 0, 0)); } - outp = isp_getrqentry(isp); - if (outp == NULL) { - isp_prt(isp, ISP_LOGWARN, rqo, __func__); - return (1); - } - ISP_MEMZERO(storage, QENTRY_LEN); - if (IS_24XX(isp)) { + in_fcentry_24xx_t *in = arg; na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage; + na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; na->na_header.rqs_entry_count = 1; - if (arg) { - in_fcentry_24xx_t *in = arg; - na->na_nphdl = in->in_nphdl; - na->na_flags = in->in_flags; - na->na_status = in->in_status; - na->na_status_subcode = in->in_status_subcode; - na->na_fwhandle = in->in_fwhandle; - na->na_rxid = in->in_rxid; - na->na_oxid = in->in_oxid; - na->na_vpidx = in->in_vpidx; - if (in->in_status == IN24XX_SRR_RCVD) { - na->na_srr_rxid = in->in_srr_rxid; - na->na_srr_reloff_hi = in->in_srr_reloff_hi; - na->na_srr_reloff_lo = in->in_srr_reloff_lo; - na->na_srr_iu = in->in_srr_iu; - /* - * Whether we're accepting the SRR or rejecting - * it is determined by looking at the in_reserved - * field in the original notify structure. - */ - if (in->in_reserved) { - na->na_srr_flags = 1; - na->na_srr_reject_vunique = 0; - na->na_srr_reject_code = 9; /* unable to perform this command at this time */ - na->na_srr_reject_explanation = 0x2a; /* unable to supply the requested data */ - } + na->na_nphdl = in->in_nphdl; + na->na_flags = in->in_flags; + na->na_status = in->in_status; + na->na_status_subcode = in->in_status_subcode; + na->na_fwhandle = in->in_fwhandle; + na->na_rxid = in->in_rxid; + na->na_oxid = in->in_oxid; + na->na_vpidx = in->in_vpidx; + if (in->in_status == IN24XX_SRR_RCVD) { + na->na_srr_rxid = in->in_srr_rxid; + na->na_srr_reloff_hi = in->in_srr_reloff_hi; + na->na_srr_reloff_lo = in->in_srr_reloff_lo; + na->na_srr_iu = in->in_srr_iu; + /* + * Whether we're accepting the SRR or rejecting + * it is determined by looking at the in_reserved + * field in the original notify structure. + */ + if (in->in_reserved) { + na->na_srr_flags = 1; + na->na_srr_reject_vunique = 0; + /* Unable to perform this command at this time. */ + na->na_srr_reject_code = 9; + /* Unable to supply the requested data. */ + na->na_srr_reject_explanation = 0x2a; } } - isp_put_notify_24xx_ack(isp, na, (na_fcentry_24xx_t *)outp); } else { + in_fcentry_t *in = arg; na_fcentry_t *na = (na_fcentry_t *) storage; - int iid = 0; + int iid; - if (arg) { - in_fcentry_t *inp = arg; - ISP_MEMCPY(storage, arg, sizeof (isphdr_t)); - if (ISP_CAP_2KLOGIN(isp)) { - ((na_fcentry_e_t *)na)->na_iid = ((in_fcentry_e_t *)inp)->in_iid; - iid = ((na_fcentry_e_t *)na)->na_iid; - } else { - na->na_iid = inp->in_iid; - iid = na->na_iid; - } - na->na_task_flags = inp->in_task_flags & TASK_FLAGS_RESERVED_MASK; - na->na_seqid = inp->in_seqid; - na->na_status = inp->in_status; - na->na_flags = NAFC_RCOUNT; - if (inp->in_status == IN_RESET) { - na->na_flags = NAFC_RST_CLRD; /* We do not modify resource counts for LIP resets */ - } - if (inp->in_status == IN_MSG_RECEIVED) { - na->na_flags |= NAFC_TVALID; - na->na_response = 0; /* XXX SUCCEEDED XXX */ - } + ISP_MEMCPY(storage, arg, sizeof (isphdr_t)); + if (ISP_CAP_2KLOGIN(isp)) { + iid = ((in_fcentry_e_t *)in)->in_iid; + ((na_fcentry_e_t *)na)->na_iid = iid; } else { + iid = in->in_iid; + na->na_iid = iid; + } + na->na_task_flags = in->in_task_flags & TASK_FLAGS_RESERVED_MASK; + na->na_seqid = in->in_seqid; + na->na_status = in->in_status; + na->na_flags = NAFC_RCOUNT; + /* We do not modify resource counts for LIP resets */ + if (in->in_status == IN_RESET) na->na_flags = NAFC_RST_CLRD; + if (in->in_status == IN_MSG_RECEIVED) { + na->na_flags |= NAFC_TVALID; + na->na_response = 0; /* XXX SUCCEEDED XXX */ } na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; na->na_header.rqs_entry_count = 1; - if (ISP_CAP_2KLOGIN(isp)) { - isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na, (na_fcentry_e_t *)outp); - } else { - isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp); - } isp_prt(isp, ISP_LOGTDEBUG0, "notify ack handle %x seqid %x flags %x tflags %x response %x", iid, na->na_seqid, na->na_flags, na->na_task_flags, na->na_response); } - ISP_TDQE(isp, "isp_notify_ack", isp->isp_reqidx, storage); - ISP_SYNC_REQUEST(isp); - return (0); + return (isp_target_put_entry(isp, &storage)); } int @@ -935,7 +821,6 @@ uint8_t tmpb; abts_t *abts = arg; abts_rsp_t *rsp = (abts_rsp_t *) storage; - void *outp; if (!IS_24XX(isp)) { isp_prt(isp, ISP_LOGERR, "%s: called for non-24XX card", __func__); @@ -947,12 +832,6 @@ return (0); } - outp = isp_getrqentry(isp); - if (outp == NULL) { - isp_prt(isp, ISP_LOGWARN, rqo, __func__); - return (1); - } - ISP_MEMCPY(rsp, abts, QENTRY_LEN); rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP; @@ -995,15 +874,48 @@ break; } } + return (isp_target_put_entry(isp, rsp)); +} - /* - * The caller will have set response values as appropriate - * in the ABTS structure just before calling us. - */ - isp_put_abts_rsp(isp, rsp, (abts_rsp_t *)outp); - ISP_TDQE(isp, "isp_acknak_abts", isp->isp_reqidx, storage); - ISP_SYNC_REQUEST(isp); - return (0); +static void +isp_handle_abts(ispsoftc_t *isp, abts_t *abts) +{ + isp_notify_t notify, *nt = ¬ify; + fcportdb_t *lp; + uint16_t chan; + uint32_t sid, did; + + did = (abts->abts_did_hi << 16) | abts->abts_did_lo; + sid = (abts->abts_sid_hi << 16) | abts->abts_sid_lo; + ISP_MEMZERO(nt, sizeof (isp_notify_t)); + + nt->nt_hba = isp; + nt->nt_did = did; + nt->nt_nphdl = abts->abts_nphdl; + nt->nt_sid = sid; + isp_find_chan_by_did(isp, did, &chan); + if (chan == ISP_NOCHAN) { + nt->nt_tgt = TGT_ANY; + } else { + nt->nt_tgt = FCPARAM(isp, chan)->isp_wwpn; + if (isp_find_pdb_by_handle(isp, chan, abts->abts_nphdl, &lp)) { + nt->nt_wwn = lp->port_wwn; + } else { + nt->nt_wwn = INI_ANY; + } + } + nt->nt_lun = LUN_ANY; + nt->nt_need_ack = 1; + nt->nt_tagval = abts->abts_rxid_task; + nt->nt_tagval |= (((uint64_t) abts->abts_rxid_abts) << 32); + isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS from N-Port handle 0x%x" + " Port 0x%06x for task 0x%x (rx_id 0x%04x ox_id 0x%04x)", + abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rxid_task, + abts->abts_rx_id, abts->abts_ox_id); + nt->nt_channel = chan; + nt->nt_ncode = NT_ABORT_TASK; + nt->nt_lreserved = abts; + isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); } static void @@ -1391,7 +1303,84 @@ } static void -isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx) +isp_handle_notify(ispsoftc_t *isp, in_fcentry_t *inp) +{ + fcportdb_t *lp; + uint64_t wwn; + uint32_t sid; + uint16_t nphdl, status; + isp_notify_t notify; + + status = inp->in_status; + isp_prt(isp, ISP_LOGTDEBUG0, "Immediate Notify, status=0x%x seqid=0x%x", + status, inp->in_seqid); + switch (status) { + case IN_MSG_RECEIVED: + case IN_IDE_RECEIVED: + isp_got_msg_fc(isp, inp); + return; + case IN_RSRC_UNAVAIL: + isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs"); + isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp); + return; + } + + if (ISP_CAP_2KLOGIN(isp)) + nphdl = ((in_fcentry_e_t *)inp)->in_iid; + else + nphdl = inp->in_iid; + if (isp_find_pdb_by_handle(isp, 0, nphdl, &lp)) { + wwn = lp->port_wwn; + sid = lp->portid; + } else { + wwn = INI_ANY; + sid = PORT_ANY; + } + + ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); + notify.nt_hba = isp; + notify.nt_wwn = wwn; + notify.nt_tgt = FCPARAM(isp, 0)->isp_wwpn; + notify.nt_nphdl = nphdl; + notify.nt_sid = sid; + notify.nt_did = PORT_ANY; + if (ISP_CAP_SCCFW(isp)) + notify.nt_lun = inp->in_scclun; + else + notify.nt_lun = inp->in_lun; + notify.nt_tagval = inp->in_seqid; + notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); + notify.nt_need_ack = 1; + notify.nt_channel = 0; + notify.nt_lreserved = inp; + + switch (status) { + case IN_RESET: + notify.nt_ncode = NT_BUS_RESET; + break; + case IN_PORT_LOGOUT: + notify.nt_ncode = NT_LOGOUT; + break; + case IN_ABORT_TASK: + notify.nt_ncode = NT_ABORT_TASK; + break; + case IN_GLOBAL_LOGO: + notify.nt_ncode = NT_GLOBAL_LOGOUT; + break; + case IN_PORT_CHANGED: + notify.nt_ncode = NT_CHANGED; + break; + default: + isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x)", + __func__, status); + isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp); + return; + } + isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); +} + +static void +isp_handle_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx) { uint8_t ochan, chan, lochan, hichan; @@ -1415,27 +1404,28 @@ hichan = chan + 1; } isp_prt(isp, ISP_LOGTDEBUG1, "%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x", __func__, lochan, hichan-1, inot_24xx->in_status, inot_24xx->in_rxid); - for (chan = lochan; chan < hichan; chan++) { - if (FCPARAM(isp, chan)->role == ISP_ROLE_NONE) - continue; - switch (inot_24xx->in_status) { - case IN24XX_LIP_RESET: - case IN24XX_LINK_RESET: - case IN24XX_PORT_LOGOUT: - case IN24XX_PORT_CHANGED: - case IN24XX_LINK_FAILED: - case IN24XX_SRR_RCVD: - case IN24XX_ELS_RCVD: - inot_24xx->in_reserved = 0; /* clear this for later usage */ + switch (inot_24xx->in_status) { + case IN24XX_LIP_RESET: + case IN24XX_LINK_RESET: + case IN24XX_PORT_LOGOUT: + case IN24XX_PORT_CHANGED: + case IN24XX_LINK_FAILED: + case IN24XX_SRR_RCVD: + case IN24XX_ELS_RCVD: + for (chan = lochan; chan < hichan; chan++) { + if (FCPARAM(isp, chan)->role == ISP_ROLE_NONE) + continue; + inot_24xx->in_reserved = 0; /* clear this for later usage */ inot_24xx->in_vpidx = chan; isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx); - break; - default: - isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x) for chan %d", __func__, inot_24xx->in_status, chan); - isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_24xx); - break; } + inot_24xx->in_vpidx = ochan; + break; + default: + isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x) for chan %d", + __func__, inot_24xx->in_status, chan); + isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_24xx); + break; } - inot_24xx->in_vpidx = ochan; } #endif Index: sys/dev/syscons/scterm-teken.c =================================================================== --- sys/dev/syscons/scterm-teken.c +++ sys/dev/syscons/scterm-teken.c @@ -315,88 +315,57 @@ * libteken routines. */ -static const unsigned char fgcolors_normal[TC_NCOLORS] = { - FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, - FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY, +static const teken_color_t sc_to_te_color[] = { + TC_BLACK, TC_BLUE, TC_GREEN, TC_CYAN, + TC_RED, TC_MAGENTA, TC_BROWN, TC_WHITE, }; -static const unsigned char fgcolors_bold[TC_NCOLORS] = { - FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW, - FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE, -}; - -static const unsigned char bgcolors[TC_NCOLORS] = { - BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, - BG_BLUE, BG_MAGENTA, BG_CYAN, BG_LIGHTGREY, +static const unsigned char te_to_sc_color[] = { + FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, + FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY, }; static void scteken_sc_to_te_attr(unsigned char color, teken_attr_t *a) { - teken_color_t fg, bg; /* - * XXX: Reverse conversion of syscons to teken attributes. Not - * realiable. Maybe we should turn it into a 1:1 mapping one of - * these days? + * Conversions of attrs are not reversible. Since sc attrs are + * pure colors in the simplest mode (16-color graphics) and the + * API is too deficient to tell us the mode, always convert to + * pure colors. The conversion is essentially the identity except + * for reordering the non-brightness bits in the 2 color numbers. */ - a->ta_format = 0; - a->ta_fgcolor = TC_WHITE; - a->ta_bgcolor = TC_BLACK; - -#ifdef FG_BLINK - if (color & FG_BLINK) { - a->ta_format |= TF_BLINK; - color &= ~FG_BLINK; - } -#endif /* FG_BLINK */ - - for (fg = 0; fg < TC_NCOLORS; fg++) { - for (bg = 0; bg < TC_NCOLORS; bg++) { - if ((fgcolors_normal[fg] | bgcolors[bg]) == color) { - a->ta_fgcolor = fg; - a->ta_bgcolor = bg; - return; - } - - if ((fgcolors_bold[fg] | bgcolors[bg]) == color) { - a->ta_fgcolor = fg; - a->ta_bgcolor = bg; - a->ta_format |= TF_BOLD; - return; - } - } - } + a->ta_fgcolor = sc_to_te_color[color & 7] | (color & 8); + a->ta_bgcolor = sc_to_te_color[(color >> 4) & 7] | ((color >> 4) & 8); } static int scteken_te_to_sc_attr(const teken_attr_t *a) { - int attr = 0; + int attr; teken_color_t fg, bg; if (a->ta_format & TF_REVERSE) { - fg = teken_256to8(a->ta_bgcolor); - bg = teken_256to8(a->ta_fgcolor); + fg = a->ta_bgcolor; + bg = a->ta_fgcolor; } else { - fg = teken_256to8(a->ta_fgcolor); - bg = teken_256to8(a->ta_bgcolor); + fg = a->ta_fgcolor; + bg = a->ta_bgcolor; } - if (a->ta_format & TF_BOLD) - attr |= fgcolors_bold[fg]; - else - attr |= fgcolors_normal[fg]; - attr |= bgcolors[bg]; - -#ifdef FG_UNDERLINE - if (a->ta_format & TF_UNDERLINE) - attr |= FG_UNDERLINE; -#endif /* FG_UNDERLINE */ -#ifdef FG_BLINK + if (fg >= 16) + fg = teken_256to16(fg); + if (bg >= 16) + bg = teken_256to16(bg); + attr = te_to_sc_color[fg & 7] | (fg & 8) | + ((te_to_sc_color[bg & 7] | (bg & 8)) << 4); + + /* XXX: underline mapping for Hercules adapter can be better. */ + if (a->ta_format & (TF_BOLD | TF_UNDERLINE)) + attr ^= 8; if (a->ta_format & TF_BLINK) - attr |= FG_BLINK; -#endif /* FG_BLINK */ + attr ^= 0x80; return (attr); } Index: sys/dev/vt/vt_core.c =================================================================== --- sys/dev/vt/vt_core.c +++ sys/dev/vt/vt_core.c @@ -1075,6 +1075,8 @@ if (TCHAR_FORMAT(c) & TF_BOLD) *fg = TCOLOR_LIGHT(*fg); *bg = TCHAR_BGCOLOR(c); + if (TCHAR_FORMAT(c) & TF_BLINK) + *bg = TCOLOR_LIGHT(*bg); if (TCHAR_FORMAT(c) & TF_REVERSE) invert ^= 1; Index: sys/i386/linux/linux.h =================================================================== --- sys/i386/linux/linux.h +++ sys/i386/linux/linux.h @@ -453,37 +453,6 @@ void *__pad; }; -/* - * Socket defines - */ -#define LINUX_SOL_SOCKET 1 -#define LINUX_SOL_IP 0 -#define LINUX_SOL_IPX 256 -#define LINUX_SOL_AX25 257 -#define LINUX_SOL_TCP 6 -#define LINUX_SOL_UDP 17 - -#define LINUX_SO_DEBUG 1 -#define LINUX_SO_REUSEADDR 2 -#define LINUX_SO_TYPE 3 -#define LINUX_SO_ERROR 4 -#define LINUX_SO_DONTROUTE 5 -#define LINUX_SO_BROADCAST 6 -#define LINUX_SO_SNDBUF 7 -#define LINUX_SO_RCVBUF 8 -#define LINUX_SO_KEEPALIVE 9 -#define LINUX_SO_OOBINLINE 10 -#define LINUX_SO_NO_CHECK 11 -#define LINUX_SO_PRIORITY 12 -#define LINUX_SO_LINGER 13 -#define LINUX_SO_PEERCRED 17 -#define LINUX_SO_RCVLOWAT 18 -#define LINUX_SO_SNDLOWAT 19 -#define LINUX_SO_RCVTIMEO 20 -#define LINUX_SO_SNDTIMEO 21 -#define LINUX_SO_TIMESTAMP 29 -#define LINUX_SO_ACCEPTCONN 30 - struct l_sockaddr { l_ushort sa_family; char sa_data[14]; Index: sys/i386/linux/linux_dummy.c =================================================================== --- sys/i386/linux/linux_dummy.c +++ sys/i386/linux/linux_dummy.c @@ -140,7 +140,6 @@ DUMMY(renameat2); /* linux 3.15: */ DUMMY(seccomp); -DUMMY(getrandom); DUMMY(memfd_create); /* linux 3.18: */ DUMMY(bpf); Index: sys/kern/imgact_elf.c =================================================================== --- sys/kern/imgact_elf.c +++ sys/kern/imgact_elf.c @@ -582,7 +582,7 @@ /* This had damn well better be true! */ if (map_len != 0) { rv = __elfN(map_insert)(imgp, map, NULL, 0, map_addr, - map_addr + map_len, VM_PROT_ALL, 0); + map_addr + map_len, prot, 0); if (rv != KERN_SUCCESS) return (EINVAL); } @@ -603,10 +603,12 @@ } /* - * set it to the specified protection. + * Remove write access to the page if it was only granted by map_insert + * to allow copyout. */ - vm_map_protect(map, trunc_page(map_addr), round_page(map_addr + - map_len), prot, FALSE); + if ((prot & VM_PROT_WRITE) == 0) + vm_map_protect(map, trunc_page(map_addr), round_page(map_addr + + map_len), prot, FALSE); return (0); } Index: sys/kern/kern_time.c =================================================================== --- sys/kern/kern_time.c +++ sys/kern/kern_time.c @@ -86,6 +86,9 @@ static int settime(struct thread *, struct timeval *); static void timevalfix(struct timeval *); +static int user_clock_nanosleep(struct thread *td, clockid_t clock_id, + int flags, const struct timespec *ua_rqtp, + struct timespec *ua_rmtp); static void itimer_start(void); static int itimer_init(void *, int, int); @@ -481,47 +484,95 @@ return (0); } +int +kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt) +{ + + return (kern_clock_nanosleep(td, CLOCK_REALTIME, TIMER_RELTIME, rqt, + rmt)); +} + static uint8_t nanowait[MAXCPU]; int -kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt) +kern_clock_nanosleep(struct thread *td, clockid_t clock_id, int flags, + const struct timespec *rqt, struct timespec *rmt) { - struct timespec ts; + struct timespec ts, now; sbintime_t sbt, sbtt, prec, tmp; time_t over; int error; + bool is_abs_real; if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000) return (EINVAL); - if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0)) - return (0); - ts = *rqt; - if (ts.tv_sec > INT32_MAX / 2) { - over = ts.tv_sec - INT32_MAX / 2; - ts.tv_sec -= over; - } else - over = 0; - tmp = tstosbt(ts); - prec = tmp; - prec >>= tc_precexp; - if (TIMESEL(&sbt, tmp)) - sbt += tc_tick_sbt; - sbt += tmp; - error = tsleep_sbt(&nanowait[curcpu], PWAIT | PCATCH, "nanslp", - sbt, prec, C_ABSOLUTE); + if ((flags & ~TIMER_ABSTIME) != 0) + return (EINVAL); + switch (clock_id) { + case CLOCK_REALTIME: + case CLOCK_REALTIME_PRECISE: + case CLOCK_REALTIME_FAST: + case CLOCK_SECOND: + is_abs_real = (flags & TIMER_ABSTIME) != 0; + break; + case CLOCK_MONOTONIC: + case CLOCK_MONOTONIC_PRECISE: + case CLOCK_MONOTONIC_FAST: + case CLOCK_UPTIME: + case CLOCK_UPTIME_PRECISE: + case CLOCK_UPTIME_FAST: + is_abs_real = false; + break; + case CLOCK_VIRTUAL: + case CLOCK_PROF: + case CLOCK_PROCESS_CPUTIME_ID: + return (ENOTSUP); + case CLOCK_THREAD_CPUTIME_ID: + default: + return (EINVAL); + } + do { + ts = *rqt; + if ((flags & TIMER_ABSTIME) != 0) { + if (is_abs_real) + td->td_rtcgen = + atomic_load_acq_int(&rtc_generation); + error = kern_clock_gettime(td, clock_id, &now); + KASSERT(error == 0, ("kern_clock_gettime: %d", error)); + timespecsub(&ts, &now); + } + if (ts.tv_sec < 0 || (ts.tv_sec == 0 && ts.tv_nsec == 0)) { + error = EWOULDBLOCK; + break; + } + if (ts.tv_sec > INT32_MAX / 2) { + over = ts.tv_sec - INT32_MAX / 2; + ts.tv_sec -= over; + } else + over = 0; + tmp = tstosbt(ts); + prec = tmp; + prec >>= tc_precexp; + if (TIMESEL(&sbt, tmp)) + sbt += tc_tick_sbt; + sbt += tmp; + error = tsleep_sbt(&nanowait[curcpu], PWAIT | PCATCH, "nanslp", + sbt, prec, C_ABSOLUTE); + } while (error == 0 && is_abs_real && td->td_rtcgen == 0); + td->td_rtcgen = 0; if (error != EWOULDBLOCK) { + TIMESEL(&sbtt, tmp); + if (sbtt >= sbt) + return (0); if (error == ERESTART) error = EINTR; - TIMESEL(&sbtt, tmp); - if (rmt != NULL) { + if ((flags & TIMER_ABSTIME) == 0 && rmt != NULL) { ts = sbttots(sbt - sbtt); ts.tv_sec += over; if (ts.tv_sec < 0) timespecclear(&ts); *rmt = ts; } - if (sbtt >= sbt) - return (0); return (error); } return (0); @@ -537,21 +588,48 @@ int sys_nanosleep(struct thread *td, struct nanosleep_args *uap) { + + return (user_clock_nanosleep(td, CLOCK_REALTIME, TIMER_RELTIME, + uap->rqtp, uap->rmtp)); +} + +#ifndef _SYS_SYSPROTO_H_ +struct clock_nanosleep_args { + clockid_t clock_id; + int flags; + struct timespec *rqtp; + struct timespec *rmtp; +}; +#endif +/* ARGSUSED */ +int +sys_clock_nanosleep(struct thread *td, struct clock_nanosleep_args *uap) +{ + int error; + + error = user_clock_nanosleep(td, uap->clock_id, uap->flags, uap->rqtp, + uap->rmtp); + return (kern_posix_error(td, error)); +} + +static int +user_clock_nanosleep(struct thread *td, clockid_t clock_id, int flags, + const struct timespec *ua_rqtp, struct timespec *ua_rmtp) +{ struct timespec rmt, rqt; int error; - error = copyin(uap->rqtp, &rqt, sizeof(rqt)); + error = copyin(ua_rqtp, &rqt, sizeof(rqt)); if (error) return (error); - - if (uap->rmtp && - !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) - return (EFAULT); - error = kern_nanosleep(td, &rqt, &rmt); - if (error && uap->rmtp) { + if (ua_rmtp != NULL && (flags & TIMER_ABSTIME) == 0 && + !useracc(ua_rmtp, sizeof(rmt), VM_PROT_WRITE)) + return (EFAULT); + error = kern_clock_nanosleep(td, clock_id, flags, &rqt, &rmt); + if (error == EINTR && ua_rmtp != NULL && (flags & TIMER_ABSTIME) == 0) { int error2; - error2 = copyout(&rmt, uap->rmtp, sizeof(rmt)); + error2 = copyout(&rmt, ua_rmtp, sizeof(rmt)); if (error2) error = error2; } Index: sys/kern/subr_terminal.c =================================================================== --- sys/kern/subr_terminal.c +++ sys/kern/subr_terminal.c @@ -130,9 +130,25 @@ .ta_format = TCHAR_FORMAT(TERMINAL_NORM_ATTR) }; +/* Fudge fg brightness as TF_BOLD (shifted). */ +#define TCOLOR_FG_FUDGED(color) __extension__ ({ \ + teken_color_t _c; \ + \ + _c = (color); \ + TCOLOR_FG(_c & 7) | ((_c & 8) << 18); \ +}) + +/* Fudge bg brightness as TF_BLINK (shifted). */ +#define TCOLOR_BG_FUDGED(color) __extension__ ({ \ + teken_color_t _c; \ + \ + _c = (color); \ + TCOLOR_BG(_c & 7) | ((_c & 8) << 20); \ +}) + #define TCHAR_CREATE(c, a) ((c) | TFORMAT((a)->ta_format) | \ - TCOLOR_FG(teken_256to8((a)->ta_fgcolor)) | \ - TCOLOR_BG(teken_256to8((a)->ta_bgcolor))) + TCOLOR_FG_FUDGED(teken_256to16((a)->ta_fgcolor)) | \ + TCOLOR_BG_FUDGED(teken_256to16((a)->ta_bgcolor))) static void terminal_init(struct terminal *tm) Index: sys/kern/syscalls.master =================================================================== --- sys/kern/syscalls.master +++ sys/kern/syscalls.master @@ -461,7 +461,9 @@ struct ffclock_estimate *cest); } 243 AUE_NULL STD { int ffclock_getestimate( \ struct ffclock_estimate *cest); } -244 AUE_NULL UNIMPL nosys +244 AUE_NULL STD { int clock_nanosleep(clockid_t clock_id, \ + int flags, const struct timespec *rqtp, \ + struct timespec *rmtp); } 245 AUE_NULL UNIMPL nosys 246 AUE_NULL UNIMPL nosys 247 AUE_NULL STD { int clock_getcpuclockid2(id_t id,\ Index: sys/netpfil/ipfw/dn_aqm_pie.h =================================================================== --- sys/netpfil/ipfw/dn_aqm_pie.h +++ sys/netpfil/ipfw/dn_aqm_pie.h @@ -37,16 +37,16 @@ #define DN_AQM_PIE 2 #define PIE_DQ_THRESHOLD_BITS 14 /* 2^14 =16KB */ -#define PIE_DQ_THRESHOLD (1UL << PIE_DQ_THRESHOLD_BITS) +#define PIE_DQ_THRESHOLD (1L << PIE_DQ_THRESHOLD_BITS) #define MEAN_PKTSIZE 800 /* 31-bits because random() generates range from 0->(2**31)-1 */ #define PIE_PROB_BITS 31 -#define PIE_MAX_PROB ((1ULL<t_defattr.ta_bgcolor = cons25_colors[c % 8]; - t->t_curattr.ta_bgcolor = cons25_colors[c % 8]; + t->t_defattr.ta_bgcolor = cons25_colors[c % 8] | (c & 8); + t->t_curattr.ta_bgcolor = cons25_colors[c % 8] | (c & 8); } static void teken_subr_cons25_set_adapter_foreground(teken_t *t, unsigned int c) { - t->t_defattr.ta_fgcolor = cons25_colors[c % 8]; - t->t_curattr.ta_fgcolor = cons25_colors[c % 8]; - if (c >= 8) { - t->t_defattr.ta_format |= TF_BOLD; - t->t_curattr.ta_format |= TF_BOLD; - } else { - t->t_defattr.ta_format &= ~TF_BOLD; - t->t_curattr.ta_format &= ~TF_BOLD; - } + t->t_defattr.ta_fgcolor = cons25_colors[c % 8] | (c & 8); + t->t_curattr.ta_fgcolor = cons25_colors[c % 8] | (c & 8); } static const teken_color_t cons25_revcolors[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; Index: tests/sys/kern/ptrace_test.c =================================================================== --- tests/sys/kern/ptrace_test.c +++ tests/sys/kern/ptrace_test.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include #include @@ -40,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -1872,15 +1875,11 @@ cpuset_t setmask; pthread_t t; pthread_barrier_t barrier; + struct sched_param sched_param; ATF_REQUIRE((fpid = fork()) != -1); if (fpid == 0) { - /* - * Bind to one CPU so only one thread at a time will run. This - * test expects that the first thread created (the main thread) - * will be unsuspended first and will block the second thread - * from running. - */ + /* Bind to one CPU so only one thread at a time will run. */ CPU_ZERO(&setmask); CPU_SET(0, &setmask); cpusetid_t setid; @@ -1893,6 +1892,20 @@ CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, (void*)&barrier) == 0); + /* + * Give the main thread higher priority. The test always + * assumes that, if both threads are able to run, the main + * thread runs first. + */ + sched_param.sched_priority = + (sched_get_priority_max(SCHED_FIFO) + + sched_get_priority_min(SCHED_FIFO)) / 2; + CHILD_REQUIRE(pthread_setschedparam(pthread_self(), + SCHED_FIFO, &sched_param) == 0); + sched_param.sched_priority -= RQ_PPQ; + CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, + &sched_param) == 0); + sigset_t sigmask; sigemptyset(&sigmask); sigaddset(&sigmask, SIGUSR2); @@ -1952,23 +1965,19 @@ ATF_TC_BODY(ptrace__PT_KILL_competing_stop, tc) { pid_t fpid, wpid; - int status, i; + int status; cpuset_t setmask; pthread_t t; pthread_barrier_t barrier; lwpid_t main_lwp; struct ptrace_lwpinfo pl; + struct sched_param sched_param; ATF_REQUIRE((fpid = fork()) != -1); if (fpid == 0) { trace_me(); - /* - * Bind to one CPU so only one thread at a time will run. This - * test expects that the first thread created (the main thread) - * will be unsuspended first and will block the second thread - * from running. - */ + /* Bind to one CPU so only one thread at a time will run. */ CPU_ZERO(&setmask); CPU_SET(0, &setmask); cpusetid_t setid; @@ -1981,6 +1990,20 @@ CHILD_REQUIRE(pthread_create(&t, NULL, mask_usr1_thread, (void*)&barrier) == 0); + /* + * Give the main thread higher priority. The test always + * assumes that, if both threads are able to run, the main + * thread runs first. + */ + sched_param.sched_priority = + (sched_get_priority_max(SCHED_FIFO) + + sched_get_priority_min(SCHED_FIFO)) / 2; + CHILD_REQUIRE(pthread_setschedparam(pthread_self(), + SCHED_FIFO, &sched_param) == 0); + sched_param.sched_priority -= RQ_PPQ; + CHILD_REQUIRE(pthread_setschedparam(t, SCHED_FIFO, + &sched_param) == 0); + sigset_t sigmask; sigemptyset(&sigmask); sigaddset(&sigmask, SIGUSR2); @@ -2027,34 +2050,43 @@ ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); } - /* Let both threads hit their syscall entries. */ - for (i = 0; i < 2; ++i) { - ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); + /* Proceed, allowing main thread to hit syscall entry for getpid(). */ + ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); - wpid = waitpid(fpid, &status, 0); - ATF_REQUIRE(wpid == fpid); - ATF_REQUIRE(WIFSTOPPED(status)); - ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); - ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, - sizeof(pl)) != -1); - ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, + sizeof(pl)) != -1); + ATF_REQUIRE(pl.pl_lwpid == main_lwp); + ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE); + /* Prevent the main thread from hitting its syscall exit for now. */ + ATF_REQUIRE(ptrace(PT_SUSPEND, main_lwp, 0, 0) == 0); - /* - * Prevent the main thread from hitting its syscall exit for - * now. - */ - if (pl.pl_lwpid == main_lwp) - ATF_REQUIRE(ptrace(PT_SUSPEND, main_lwp, 0, 0) == 0); + /* + * Proceed, allowing second thread to hit syscall exit for + * pthread_barrier_wait(). + */ + ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); - } + wpid = waitpid(fpid, &status, 0); + ATF_REQUIRE(wpid == fpid); + ATF_REQUIRE(WIFSTOPPED(status)); + ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); + + ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, + sizeof(pl)) != -1); + ATF_REQUIRE(pl.pl_lwpid != main_lwp); + ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX); /* Send a signal that only the second thread can handle. */ ATF_REQUIRE(kill(fpid, SIGUSR2) == 0); ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0); - /* The second wait() should report the SIGUSR2. */ + /* The next wait() should report the SIGUSR2. */ wpid = waitpid(fpid, &status, 0); ATF_REQUIRE(wpid == fpid); ATF_REQUIRE(WIFSTOPPED(status)); @@ -2065,10 +2097,11 @@ /* * At this point, the main thread is in the middle of a system call and - * has been resumed. The second thread has taken a signal which will be - * replaced with a SIGKILL. We expect the main thread will get to run - * first. It should notice the kill request and exit accordingly and - * not stop for the system call exit event. + * has been resumed. The second thread has taken a SIGUSR2 which will + * be replaced with a SIGKILL below. The main thread will get to run + * first. It should notice the kill request (even though the signal + * replacement occurred in the other thread) and exit accordingly. It + * should not stop for the system call exit event. */ /* Replace the SIGUSR2 with a kill. */ Index: usr.bin/truss/syscall.h =================================================================== --- usr.bin/truss/syscall.h +++ usr.bin/truss/syscall.h @@ -45,6 +45,8 @@ Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl, LinuxSockArgs, Umtxop, Atfd, Atflags, Timespec2, Accessmode, Long, Sysarch, ExecArgs, ExecEnv, PipeFds, QuadHex, Utrace, IntArray, Pipe2, + CapFcntlRights, Fadvice, FileFlags, Flockop, Getfsstatmode, Kldsymcmd, + Kldunloadflags, CloudABIAdvice, CloudABIClockID, ClouduABIFDSFlags, CloudABIFDStat, CloudABIFileStat, CloudABIFileType, Index: usr.bin/truss/syscalls.c =================================================================== --- usr.bin/truss/syscalls.c +++ usr.bin/truss/syscalls.c @@ -92,10 +92,17 @@ { Int, 3 } } }, { .name = "break", .ret_type = 1, .nargs = 1, .args = { { Ptr, 0 } } }, + { .name = "cap_fcntls_get", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { CapFcntlRights | OUT, 1 } } }, + { .name = "cap_fcntls_limit", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { CapFcntlRights, 1 } } }, { .name = "chdir", .ret_type = 1, .nargs = 1, .args = { { Name, 0 } } }, { .name = "chflags", .ret_type = 1, .nargs = 2, - .args = { { Name | IN, 0 }, { Hex, 1 } } }, + .args = { { Name | IN, 0 }, { FileFlags, 1 } } }, + { .name = "chflagsat", .ret_type = 1, .nargs = 4, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { FileFlags, 2 }, + { Atflags, 3 } } }, { .name = "chmod", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, { .name = "chown", .ret_type = 1, .nargs = 3, @@ -121,6 +128,8 @@ { .name = "faccessat", .ret_type = 1, .nargs = 4, .args = { { Atfd, 0 }, { Name | IN, 1 }, { Accessmode, 2 }, { Atflags, 3 } } }, + { .name = "fchflags", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { FileFlags, 1 } } }, { .name = "fchmod", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Octal, 1 } } }, { .name = "fchmodat", .ret_type = 1, .nargs = 4, @@ -132,6 +141,8 @@ { Atflags, 4 } } }, { .name = "fcntl", .ret_type = 1, .nargs = 3, .args = { { Int, 0 }, { Fcntl, 1 }, { Fcntlflag, 2 } } }, + { .name = "flock", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Flockop, 1 } } }, { .name = "fstat", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Stat | OUT, 1 } } }, { .name = "fstatat", .ret_type = 1, .nargs = 4, @@ -147,6 +158,8 @@ .args = { { Int, 0 }, { Timeval2 | IN, 1 } } }, { .name = "futimesat", .ret_type = 1, .nargs = 3, .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timeval2 | IN, 2 } } }, + { .name = "getfsstat", .ret_type = 1, .nargs = 3, + .args = { { Ptr, 0 }, { Long, 1 }, { Getfsstatmode, 2 } } }, { .name = "getitimer", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Itimerval | OUT, 2 } } }, { .name = "getpeername", .ret_type = 1, .nargs = 3, @@ -180,12 +193,16 @@ .args = { { Int, 0 } } }, { .name = "kldstat", .ret_type = 1, .nargs = 2, .args = { { Int, 0 }, { Ptr, 1 } } }, + { .name = "kldsym", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { Kldsymcmd, 1 }, { Ptr, 2 } } }, { .name = "kldunload", .ret_type = 1, .nargs = 1, .args = { { Int, 0 } } }, + { .name = "kldunloadf", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Kldunloadflags, 1 } } }, { .name = "kse_release", .ret_type = 0, .nargs = 1, .args = { { Timespec, 0 } } }, { .name = "lchflags", .ret_type = 1, .nargs = 2, - .args = { { Name | IN, 0 }, { Hex, 1 } } }, + .args = { { Name | IN, 0 }, { FileFlags, 1 } } }, { .name = "lchmod", .ret_type = 1, .nargs = 2, .args = { { Name, 0 }, { Octal, 1 } } }, { .name = "lchown", .ret_type = 1, .nargs = 3, @@ -239,6 +256,9 @@ .args = { { Ptr, 0 }, { Pipe2, 1 } } }, { .name = "poll", .ret_type = 1, .nargs = 3, .args = { { Pollfd, 0 }, { Int, 1 }, { Int, 2 } } }, + { .name = "posix_fadvise", .ret_type = 1, .nargs = 4, + .args = { { Int, 0 }, { QuadHex, 1 }, { QuadHex, 2 }, + { Fadvice, 3 } } }, { .name = "posix_openpt", .ret_type = 1, .nargs = 1, .args = { { Open, 0 } } }, { .name = "procctl", .ret_type = 1, .nargs = 4, @@ -791,6 +811,18 @@ fprintf(fp, "|0x%x", rem); } +static void +print_mask_arg32(bool (*decoder)(FILE *, uint32_t, uint32_t *), FILE *fp, + uint32_t value) +{ + uint32_t rem; + + if (!decoder(fp, value, &rem)) + fprintf(fp, "0x%x", rem); + else if (rem != 0) + fprintf(fp, "|0x%x", rem); +} + #ifndef __LP64__ /* * Add argument padding to subsequent system calls afater a Quad @@ -1832,6 +1864,46 @@ case Pipe2: print_mask_arg(sysdecode_pipe2_flags, fp, args[sc->offset]); break; + case CapFcntlRights: { + uint32_t rights; + + if (sc->type & OUT) { + if (get_struct(pid, (void *)args[sc->offset], &rights, + sizeof(rights)) == -1) { + fprintf(fp, "0x%lx", args[sc->offset]); + break; + } + } else + rights = args[sc->offset]; + print_mask_arg32(sysdecode_cap_fcntlrights, fp, rights); + break; + } + case Fadvice: + print_integer_arg(sysdecode_fadvice, fp, args[sc->offset]); + break; + case FileFlags: { + fflags_t rem; + + if (!sysdecode_fileflags(fp, args[sc->offset], &rem)) + fprintf(fp, "0x%x", rem); + else if (rem != 0) + fprintf(fp, "|0x%x", rem); + break; + } + case Flockop: + print_mask_arg(sysdecode_flock_operation, fp, args[sc->offset]); + break; + case Getfsstatmode: + print_integer_arg(sysdecode_getfsstat_mode, fp, + args[sc->offset]); + break; + case Kldsymcmd: + print_integer_arg(sysdecode_kldsym_cmd, fp, args[sc->offset]); + break; + case Kldunloadflags: + print_integer_arg(sysdecode_kldunload_flags, fp, + args[sc->offset]); + break; case CloudABIAdvice: fputs(xlookup(cloudabi_advice, args[sc->offset]), fp);