MFhead @ r305041
This commit is contained in:
parent
b11e153099
commit
898d95da6e
@ -35,15 +35,15 @@ SHLIB_MAJOR= 2
|
||||
# libatf-c++ depends on the C version of the ATF library to build.
|
||||
LIBADD+= atf_c
|
||||
|
||||
LDFLAGS+= -L${.OBJDIR}/../libatf-c
|
||||
LDFLAGS+= -L${.OBJDIR:H}/libatf-c
|
||||
|
||||
ATF= ${.CURDIR:H:H:H}/contrib/atf
|
||||
ATF= ${SRCTOP}/contrib/atf
|
||||
.PATH: ${ATF}
|
||||
.PATH: ${ATF}/atf-c++
|
||||
.PATH: ${ATF}/atf-c++/detail
|
||||
|
||||
CFLAGS+= -I${ATF}
|
||||
CFLAGS+= -I${.CURDIR}/../libatf-c
|
||||
CFLAGS+= -I${.CURDIR:H}/libatf-c
|
||||
CFLAGS+= -I.
|
||||
|
||||
CFLAGS+= -DHAVE_CONFIG_H
|
||||
|
@ -28,25 +28,25 @@
|
||||
.include <src.opts.mk>
|
||||
.include <bsd.init.mk>
|
||||
|
||||
_CFLAGS:= ${CFLAGS}
|
||||
_CPPFLAGS:= ${CPPFLAGS}
|
||||
_CXXFLAGS:= ${CXXFLAGS}
|
||||
ATF_BUILD_CFLAGS:= ${CFLAGS:M-[DILOWf]*}
|
||||
ATF_BUILD_CPPFLAGS:= ${CPPFLAGS:M-[DILOWf]*}
|
||||
ATF_BUILD_CXXFLAGS:= ${CXXFLAGS:M-[DILOWf]*}
|
||||
|
||||
LIB= atf-c
|
||||
PRIVATELIB= true
|
||||
SHLIB_MAJOR= 1
|
||||
|
||||
ATF= ${.CURDIR:H:H:H}/contrib/atf
|
||||
ATF= ${SRCTOP}/contrib/atf
|
||||
.PATH: ${ATF}
|
||||
.PATH: ${ATF}/atf-c
|
||||
.PATH: ${ATF}/atf-c/detail
|
||||
|
||||
CFLAGS+= -DATF_BUILD_CC='"${CC}"'
|
||||
CFLAGS+= -DATF_BUILD_CFLAGS='"${_CFLAGS}"'
|
||||
CFLAGS+= -DATF_BUILD_CFLAGS='"${ATF_BUILD_CFLAGS}"'
|
||||
CFLAGS+= -DATF_BUILD_CPP='"${CPP}"'
|
||||
CFLAGS+= -DATF_BUILD_CPPFLAGS='"${_CPPFLAGS}"'
|
||||
CFLAGS+= -DATF_BUILD_CPPFLAGS='"${ATF_BUILD_CPPFLAGS}"'
|
||||
CFLAGS+= -DATF_BUILD_CXX='"${CXX}"'
|
||||
CFLAGS+= -DATF_BUILD_CXXFLAGS='"${_CXXFLAGS}"'
|
||||
CFLAGS+= -DATF_BUILD_CXXFLAGS='"${ATF_BUILD_CXXFLAGS}"'
|
||||
CFLAGS+= -I${ATF}
|
||||
CFLAGS+= -I${.CURDIR}
|
||||
CFLAGS+= -I.
|
||||
|
@ -2,7 +2,7 @@
|
||||
.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
|
||||
.\"
|
||||
.\" This file is in the public domain.
|
||||
.Dd August 28, 2016
|
||||
.Dd August 29, 2016
|
||||
.Dt PTRACE 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -104,7 +104,7 @@ Each traced process has a tracing event mask.
|
||||
An event in the traced process only reports a
|
||||
signal stop if the corresponding flag is set in the tracing event mask.
|
||||
The current set of tracing event flags include:
|
||||
.Bl -tag -width ".Dv PTRACE_SYSCALL"
|
||||
.Bl -tag -width "Dv PTRACE_SYSCALL"
|
||||
.It Dv PTRACE_EXEC
|
||||
Report a stop for a successful invocation of
|
||||
.Xr execve 2 .
|
||||
@ -231,7 +231,7 @@ The
|
||||
.Fa request
|
||||
argument
|
||||
can be:
|
||||
.Bl -tag -width 12n
|
||||
.Bl -tag -width "Dv PT_GET_EVENT_MASK"
|
||||
.It Dv PT_TRACE_ME
|
||||
This request is the only one used by the traced process; it declares
|
||||
that the process expects to be traced by its parent.
|
||||
@ -469,31 +469,31 @@ The fields in the
|
||||
.Vt "struct ptrace_lwpinfo"
|
||||
have the following meaning:
|
||||
.Bl -tag -width indent -compact
|
||||
.It pl_lwpid
|
||||
.It Va pl_lwpid
|
||||
LWP id of the thread
|
||||
.It pl_event
|
||||
.It Va pl_event
|
||||
Event that caused the stop.
|
||||
Currently defined events are
|
||||
.Bl -tag -width indent -compact
|
||||
.It PL_EVENT_NONE
|
||||
Currently defined events are:
|
||||
.Bl -tag -width "Dv PL_EVENT_SIGNAL" -compact
|
||||
.It Dv PL_EVENT_NONE
|
||||
No reason given
|
||||
.It PL_EVENT_SIGNAL
|
||||
.It Dv PL_EVENT_SIGNAL
|
||||
Thread stopped due to the pending signal
|
||||
.El
|
||||
.It pl_flags
|
||||
.It Va pl_flags
|
||||
Flags that specify additional details about observed stop.
|
||||
Currently defined flags are:
|
||||
.Bl -tag -width indent -compact
|
||||
.It PL_FLAG_SCE
|
||||
.It Dv PL_FLAG_SCE
|
||||
The thread stopped due to system call entry, right after the kernel is entered.
|
||||
The debugger may examine syscall arguments that are stored in memory and
|
||||
registers according to the ABI of the current process, and modify them,
|
||||
if needed.
|
||||
.It PL_FLAG_SCX
|
||||
.It Dv PL_FLAG_SCX
|
||||
The thread is stopped immediately before syscall is returning to the usermode.
|
||||
The debugger may examine system call return values in the ABI-defined registers
|
||||
and/or memory.
|
||||
.It PL_FLAG_EXEC
|
||||
.It Dv PL_FLAG_EXEC
|
||||
When
|
||||
.Dv PL_FLAG_SCX
|
||||
is set, this flag may be additionally specified to inform that the
|
||||
@ -501,13 +501,13 @@ program being executed by debuggee process has been changed by successful
|
||||
execution of a system call from the
|
||||
.Fn execve 2
|
||||
family.
|
||||
.It PL_FLAG_SI
|
||||
.It Dv PL_FLAG_SI
|
||||
Indicates that
|
||||
.Va pl_siginfo
|
||||
member of
|
||||
.Vt "struct ptrace_lwpinfo"
|
||||
contains valid information.
|
||||
.It PL_FLAG_FORKED
|
||||
.It Dv PL_FLAG_FORKED
|
||||
Indicates that the process is returning from a call to
|
||||
.Fn fork 2
|
||||
that created a new child process.
|
||||
@ -515,42 +515,42 @@ The process identifier of the new process is available in the
|
||||
.Va pl_child_pid
|
||||
member of
|
||||
.Vt "struct ptrace_lwpinfo" .
|
||||
.It PL_FLAG_CHILD
|
||||
.It Dv PL_FLAG_CHILD
|
||||
The flag is set for first event reported from a new child which is
|
||||
automatically attached when
|
||||
.Dv PTRACE_FORK
|
||||
is enabled.
|
||||
.It PL_FLAG_BORN
|
||||
.It Dv PL_FLAG_BORN
|
||||
This flag is set for the first event reported from a new LWP when
|
||||
.Dv PTRACE_LWP
|
||||
is enabled.
|
||||
It is reported along with
|
||||
.Dv PL_FLAG_SCX .
|
||||
.It PL_FLAG_EXITED
|
||||
.It Dv PL_FLAG_EXITED
|
||||
This flag is set for the last event reported by an exiting LWP when
|
||||
.Dv PTRACE_LWP
|
||||
is enabled.
|
||||
Note that this event is not reported when the last LWP in a process exits.
|
||||
The termination of the last thread is reported via a normal process exit
|
||||
event.
|
||||
.It PL_FLAG_VFORKED
|
||||
.It Dv PL_FLAG_VFORKED
|
||||
Indicates that the thread is returning from a call to
|
||||
.Xr vfork 2
|
||||
that created a new child process.
|
||||
This flag is set in addition to
|
||||
.Dv PL_FLAG_FORKED .
|
||||
.It PL_FLAG_VFORK_DONE
|
||||
.It Dv PL_FLAG_VFORK_DONE
|
||||
Indicates that the thread has resumed after a child process created via
|
||||
.Xr vfork 2
|
||||
has stopped sharing its address space with the traced process.
|
||||
.El
|
||||
.It pl_sigmask
|
||||
.It Va pl_sigmask
|
||||
The current signal mask of the LWP
|
||||
.It pl_siglist
|
||||
.It Va pl_siglist
|
||||
The current pending set of signals for the LWP.
|
||||
Note that signals that are delivered to the process would not appear
|
||||
on an LWP siglist until the thread is selected for delivery.
|
||||
.It pl_siginfo
|
||||
.It Va pl_siginfo
|
||||
The siginfo that accompanies the signal pending.
|
||||
Only valid for
|
||||
.Dv PL_EVENT_SIGNAL
|
||||
@ -558,9 +558,9 @@ stop when
|
||||
.Dv PL_FLAG_SI
|
||||
is set in
|
||||
.Va pl_flags .
|
||||
.It pl_tdname
|
||||
.It Va pl_tdname
|
||||
The name of the thread.
|
||||
.It pl_child_pid
|
||||
.It Va pl_child_pid
|
||||
The process identifier of the new child process.
|
||||
Only valid for a
|
||||
.Dv PL_EVENT_SIGNAL
|
||||
@ -568,7 +568,7 @@ stop when
|
||||
.Dv PL_FLAG_FORKED
|
||||
is set in
|
||||
.Va pl_flags .
|
||||
.It pl_syscall_code
|
||||
.It Va pl_syscall_code
|
||||
The ABI-specific identifier of the current system call.
|
||||
Note that for indirect system calls this field reports the indirected
|
||||
system call.
|
||||
@ -578,7 +578,7 @@ or
|
||||
.Dv PL_FLAG_SCX
|
||||
is set in
|
||||
.Va pl_flags.
|
||||
.It pl_syscall_narg
|
||||
.It Va pl_syscall_narg
|
||||
The number of arguments passed to the current system call not counting
|
||||
the system call identifier.
|
||||
Note that for indirect system calls this field reports the arguments
|
||||
@ -590,10 +590,10 @@ or
|
||||
is set in
|
||||
.Va pl_flags.
|
||||
.El
|
||||
.It PT_GETNUMLWPS
|
||||
.It Dv PT_GETNUMLWPS
|
||||
This request returns the number of kernel threads associated with the
|
||||
traced process.
|
||||
.It PT_GETLWPLIST
|
||||
.It Dv PT_GETLWPLIST
|
||||
This request can be used to get the current thread list.
|
||||
A pointer to an array of type
|
||||
.Vt lwpid_t
|
||||
@ -604,15 +604,15 @@ with the array size specified by
|
||||
The return value from
|
||||
.Fn ptrace
|
||||
is the count of array entries filled in.
|
||||
.It PT_SETSTEP
|
||||
.It Dv PT_SETSTEP
|
||||
This request will turn on single stepping of the specified process.
|
||||
.It PT_CLEARSTEP
|
||||
.It Dv PT_CLEARSTEP
|
||||
This request will turn off single stepping of the specified process.
|
||||
.It PT_SUSPEND
|
||||
.It Dv PT_SUSPEND
|
||||
This request will suspend the specified thread.
|
||||
.It PT_RESUME
|
||||
.It Dv PT_RESUME
|
||||
This request will resume the specified thread.
|
||||
.It PT_TO_SCE
|
||||
.It Dv PT_TO_SCE
|
||||
This request will set the
|
||||
.Dv PTRACE_SCE
|
||||
event flag to trace all future system call entries and continue the process.
|
||||
@ -622,7 +622,7 @@ and
|
||||
.Fa data
|
||||
arguments are used the same as for
|
||||
.Dv PT_CONTINUE.
|
||||
.It PT_TO_SCX
|
||||
.It Dv PT_TO_SCX
|
||||
This request will set the
|
||||
.Dv PTRACE_SCX
|
||||
event flag to trace all future system call exits and continue the process.
|
||||
@ -632,7 +632,7 @@ and
|
||||
.Fa data
|
||||
arguments are used the same as for
|
||||
.Dv PT_CONTINUE.
|
||||
.It PT_SYSCALL
|
||||
.It Dv PT_SYSCALL
|
||||
This request will set the
|
||||
.Dv PTRACE_SYSCALL
|
||||
event flag to trace all future system call entries and exits and continue
|
||||
@ -643,7 +643,7 @@ and
|
||||
.Fa data
|
||||
arguments are used the same as for
|
||||
.Dv PT_CONTINUE.
|
||||
.It PT_FOLLOW_FORK
|
||||
.It Dv PT_FOLLOW_FORK
|
||||
This request controls tracing for new child processes of a traced process.
|
||||
If
|
||||
.Fa data
|
||||
@ -655,7 +655,7 @@ If
|
||||
is zero,
|
||||
.Dv PTRACE_FORK
|
||||
is cleared from the traced process's event tracing mask.
|
||||
.It PT_LWP_EVENTS
|
||||
.It Dv PT_LWP_EVENTS
|
||||
This request controls tracing of LWP creation and destruction.
|
||||
If
|
||||
.Fa data
|
||||
@ -667,25 +667,25 @@ If
|
||||
is zero,
|
||||
.Dv PTRACE_LWP
|
||||
is cleared from the traced process's event tracing mask.
|
||||
.It PT_GET_EVENT_MASK
|
||||
.It Dv PT_GET_EVENT_MASK
|
||||
This request reads the traced process's event tracing mask into the
|
||||
integer pointed to by
|
||||
.Fa addr .
|
||||
The size of the integer must be passed in
|
||||
.Fa data .
|
||||
.It PT_SET_EVENT_MASK
|
||||
.It Dv PT_SET_EVENT_MASK
|
||||
This request sets the traced process's event tracing mask from the
|
||||
integer pointed to by
|
||||
.Fa addr .
|
||||
The size of the integer must be passed in
|
||||
.Fa data .
|
||||
.It PT_VM_TIMESTAMP
|
||||
.It Dv PT_VM_TIMESTAMP
|
||||
This request returns the generation number or timestamp of the memory map of
|
||||
the traced process as the return value from
|
||||
.Fn ptrace .
|
||||
This provides a low-cost way for the tracing process to determine if the
|
||||
VM map changed since the last time this request was made.
|
||||
.It PT_VM_ENTRY
|
||||
.It Dv PT_VM_ENTRY
|
||||
This request is used to iterate over the entries of the VM map of the traced
|
||||
process.
|
||||
The
|
||||
@ -900,19 +900,29 @@ argument is ignored.
|
||||
.Pp
|
||||
Additionally, other machine-specific requests can exist.
|
||||
.Sh RETURN VALUES
|
||||
Most requests return 0 on success and \-1 on error.
|
||||
Some requests can cause
|
||||
.Fn ptrace
|
||||
to return
|
||||
\-1
|
||||
as a non-error value; to disambiguate,
|
||||
as a non-error value, among them are
|
||||
.Dv PT_READ_I
|
||||
and
|
||||
.Dv PT_READ_D ,
|
||||
which return the value read from the process memory on success.
|
||||
To disambiguate,
|
||||
.Va errno
|
||||
is set to 0 in the libc wrapper for the
|
||||
can be set to 0 before the call and checked afterwards.
|
||||
.Pp
|
||||
The current
|
||||
.Fn ptrace
|
||||
system call and
|
||||
.Fn ptrace
|
||||
callers can reliably check
|
||||
implementation always sets
|
||||
.Va errno
|
||||
for non-zero value afterwards.
|
||||
to 0 before calling into the kernel, both for historic reasons and for
|
||||
consistency with other operating systems.
|
||||
It is recommended to assign zero to
|
||||
.Va errno
|
||||
explicitly for forward compatibility.
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn ptrace
|
||||
|
@ -25,12 +25,13 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 27, 2016
|
||||
.Dd August 29, 2016
|
||||
.Dt DEVCTL 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm devctl ,
|
||||
.Nm devctl_attach ,
|
||||
.Nm devctl_clear_driver ,
|
||||
.Nm devctl_delete ,
|
||||
.Nm devctl_detach ,
|
||||
.Nm devctl_disable ,
|
||||
@ -47,6 +48,8 @@
|
||||
.Ft int
|
||||
.Fn devctl_attach "const char *device"
|
||||
.Ft int
|
||||
.Fn devctl_clear_driver "const char *device" "bool force"
|
||||
.Ft int
|
||||
.Fn devctl_delete "const char *device" "bool force"
|
||||
.Ft int
|
||||
.Fn devctl_detach "const char *device" "bool force"
|
||||
@ -166,12 +169,30 @@ the device will be detached from its current device driver before it is
|
||||
attached to the new device driver.
|
||||
.Pp
|
||||
The
|
||||
.Fn devctl_clear_driver
|
||||
function resets a device so that it can be attached to any valid device
|
||||
driver rather than only drivers with a previously specified name.
|
||||
This function is used to undo a previous call to
|
||||
.Fn devctl_set_driver .
|
||||
If the device is already attached and
|
||||
.Fa force
|
||||
is false,
|
||||
the request will fail.
|
||||
If the device is already attached and
|
||||
.Fa force
|
||||
is true,
|
||||
the device will be detached from its current device driver.
|
||||
After the device's name is reset,
|
||||
it is reprobed and attached to a suitable device driver if one is found.
|
||||
.Pp
|
||||
The
|
||||
.Fn devctl_rescan
|
||||
function rescans a bus device checking for devices that have been added or
|
||||
removed.
|
||||
.Sh RETURN VALUES
|
||||
.Rv -std devctl_attach devctl_delete devctl_detach devctl_disable \
|
||||
devctl_enable devctl_suspend devctl_rescan devctl_resume devctl_set_driver
|
||||
.Rv -std devctl_attach devctl_clear_driver devctl_delete devctl_detach \
|
||||
devctl_disable devctl_enable devctl_suspend devctl_rescan devctl_resume \
|
||||
devctl_set_driver
|
||||
.Sh ERRORS
|
||||
In addition to specific errors noted below,
|
||||
all of the
|
||||
@ -302,6 +323,24 @@ The new device driver failed to attach.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn devctl_clear_driver
|
||||
function may fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EBUSY
|
||||
The device is currently attached to a device driver and
|
||||
.Fa force
|
||||
is false.
|
||||
.It Bq Er EBUSY
|
||||
The current device driver for
|
||||
.Fa device
|
||||
is busy and cannot detach at this time.
|
||||
.It Bq Er EINVAL
|
||||
The device is not configured for a specific device driver name.
|
||||
.It Bq Er ENXIO
|
||||
The device driver chosen after reprobing failed to attach.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn devctl_rescan
|
||||
function may fail if:
|
||||
.Bl -tag -width Er
|
||||
|
@ -123,6 +123,14 @@ devctl_set_driver(const char *device, const char *driver, bool force)
|
||||
return (devctl_request(DEV_SET_DRIVER, &req));
|
||||
}
|
||||
|
||||
int
|
||||
devctl_clear_driver(const char *device, bool force)
|
||||
{
|
||||
|
||||
return (devctl_simple_request(DEV_CLEAR_DRIVER, device, force ?
|
||||
DEVF_CLEAR_DRIVER_DETACH : 0));
|
||||
}
|
||||
|
||||
int
|
||||
devctl_rescan(const char *device)
|
||||
{
|
||||
|
@ -38,6 +38,7 @@ int devctl_disable(const char *device, bool force_detach);
|
||||
int devctl_suspend(const char *device);
|
||||
int devctl_resume(const char *device);
|
||||
int devctl_set_driver(const char *device, const char *driver, bool force);
|
||||
int devctl_clear_driver(const char *device, bool force);
|
||||
int devctl_rescan(const char *device);
|
||||
int devctl_delete(const char *device, bool force);
|
||||
|
||||
|
@ -310,7 +310,9 @@ ti_pruss_kqfilter(struct cdev *cdev, struct knote *kn)
|
||||
case EVFILT_READ:
|
||||
kn->kn_hook = sc;
|
||||
kn->kn_fop = &ti_pruss_kq_read;
|
||||
mtx_lock(&sc->sc_mtx);
|
||||
knlist_add(&sc->sc_selinfo.si_note, kn, 1);
|
||||
mtx_unlock(&sc->sc_mtx);
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
|
@ -51,6 +51,9 @@ void HO(void);
|
||||
void end_term(void);
|
||||
#endif
|
||||
|
||||
static EFI_INPUT_KEY key_cur;
|
||||
static int key_pending;
|
||||
|
||||
static void efi_cons_probe(struct console *);
|
||||
static int efi_cons_init(int);
|
||||
void efi_cons_putchar(int);
|
||||
@ -436,14 +439,20 @@ efi_cons_getchar()
|
||||
EFI_STATUS status;
|
||||
UINTN junk;
|
||||
|
||||
/* Try to read a key stroke. We wait for one if none is pending. */
|
||||
status = conin->ReadKeyStroke(conin, &key);
|
||||
while (status == EFI_NOT_READY) {
|
||||
/* Some EFI implementation (u-boot for example) do not support WaitForKey */
|
||||
if (conin->WaitForKey != NULL)
|
||||
BS->WaitForEvent(1, &conin->WaitForKey, &junk);
|
||||
if (key_pending) {
|
||||
key = key_cur;
|
||||
key_pending = 0;
|
||||
} else {
|
||||
/* Try to read a key stroke. We wait for one if none is pending. */
|
||||
status = conin->ReadKeyStroke(conin, &key);
|
||||
while (status == EFI_NOT_READY) {
|
||||
/* Some EFI implementation (u-boot for example) do not support WaitForKey */
|
||||
if (conin->WaitForKey != NULL)
|
||||
BS->WaitForEvent(1, &conin->WaitForKey, &junk);
|
||||
status = conin->ReadKeyStroke(conin, &key);
|
||||
}
|
||||
}
|
||||
|
||||
switch (key.ScanCode) {
|
||||
case 0x17: /* ESC */
|
||||
return (0x1b); /* esc */
|
||||
@ -456,9 +465,20 @@ efi_cons_getchar()
|
||||
int
|
||||
efi_cons_poll()
|
||||
{
|
||||
EFI_INPUT_KEY key;
|
||||
EFI_STATUS status;
|
||||
|
||||
if (conin->WaitForKey == NULL) {
|
||||
if (key_pending)
|
||||
return (1);
|
||||
status = conin->ReadKeyStroke(conin, &key);
|
||||
if (status == EFI_SUCCESS) {
|
||||
key_cur = key;
|
||||
key_pending = 1;
|
||||
}
|
||||
return (key_pending);
|
||||
}
|
||||
|
||||
if (conin->WaitForKey == NULL)
|
||||
return (1);
|
||||
/* This can clear the signaled state. */
|
||||
return (BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS);
|
||||
}
|
||||
|
@ -137,7 +137,9 @@ ofw_init(void *vpd, int res, int (*openfirm)(void *), char *arg, int argl)
|
||||
|
||||
p = bootpath;
|
||||
while (*p != '\0') {
|
||||
/* Truncate partition ID */
|
||||
if (*p == ':') {
|
||||
ofw_close(bootdev);
|
||||
*(++p) = '\0';
|
||||
break;
|
||||
}
|
||||
@ -419,31 +421,40 @@ main(int ac, char **av)
|
||||
|
||||
memcpy(bootpath_full,bootpath,len+1);
|
||||
|
||||
if (bootpath_full[len-1] == ':') {
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i < 10) {
|
||||
bootpath_full[len] = i + '0';
|
||||
bootpath_full[len+1] = '\0';
|
||||
} else {
|
||||
bootpath_full[len] = '1';
|
||||
bootpath_full[len+1] = i - 10 + '0';
|
||||
bootpath_full[len+2] = '\0';
|
||||
}
|
||||
|
||||
if (domount(bootpath_full,1) >= 0)
|
||||
break;
|
||||
if (bootpath_full[len-1] != ':') {
|
||||
/* First try full volume */
|
||||
if (domount(bootpath_full,1) == 0)
|
||||
goto out;
|
||||
|
||||
if (bootdev > 0)
|
||||
ofw_close(bootdev);
|
||||
}
|
||||
|
||||
if (i >= 16)
|
||||
panic("domount");
|
||||
} else {
|
||||
if (domount(bootpath_full,0) == -1)
|
||||
panic("domount");
|
||||
/* Add a : so that we try partitions if that fails */
|
||||
if (bootdev > 0)
|
||||
ofw_close(bootdev);
|
||||
bootpath_full[len] = ':';
|
||||
len += 1;
|
||||
}
|
||||
|
||||
/* Loop through first 16 partitions to find a UFS one */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i < 10) {
|
||||
bootpath_full[len] = i + '0';
|
||||
bootpath_full[len+1] = '\0';
|
||||
} else {
|
||||
bootpath_full[len] = '1';
|
||||
bootpath_full[len+1] = i - 10 + '0';
|
||||
bootpath_full[len+2] = '\0';
|
||||
}
|
||||
|
||||
if (domount(bootpath_full,1) >= 0)
|
||||
break;
|
||||
|
||||
if (bootdev > 0)
|
||||
ofw_close(bootdev);
|
||||
}
|
||||
|
||||
if (i >= 16)
|
||||
panic("domount");
|
||||
|
||||
out:
|
||||
printf(" Boot volume: %s\n",bootpath_full);
|
||||
ofw_setprop(chosenh, "bootargs", bootpath_full, len+2);
|
||||
load(path);
|
||||
|
@ -209,10 +209,15 @@ static int
|
||||
t4iov_detach(device_t dev)
|
||||
{
|
||||
struct t4iov_softc *sc;
|
||||
int error;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
if (sc->sc_attached)
|
||||
return (t4iov_detach_child(dev));
|
||||
if (sc->sc_attached) {
|
||||
error = t4iov_detach_child(dev);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
device_verbose(dev);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -683,7 +683,16 @@ ioat_process_events(struct ioat_softc *ioat)
|
||||
__func__, ioat->chan_idx, comp_update, ioat->last_seen);
|
||||
status = comp_update & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK;
|
||||
|
||||
while (ioat_get_active(ioat) > 0) {
|
||||
if (status == ioat->last_seen) {
|
||||
/*
|
||||
* If we landed in process_events and nothing has been
|
||||
* completed, check for a timeout due to channel halt.
|
||||
*/
|
||||
goto out;
|
||||
}
|
||||
|
||||
desc = ioat_get_ring_entry(ioat, ioat->tail - 1);
|
||||
while (desc->hw_desc_bus_addr != status && ioat_get_active(ioat) > 0) {
|
||||
desc = ioat_get_ring_entry(ioat, ioat->tail);
|
||||
dmadesc = &desc->bus_dmadesc;
|
||||
CTR4(KTR_IOAT, "channel=%u completing desc %u ok cb %p(%p)",
|
||||
@ -695,8 +704,6 @@ ioat_process_events(struct ioat_softc *ioat)
|
||||
|
||||
completed++;
|
||||
ioat->tail++;
|
||||
if (desc->hw_desc_bus_addr == status)
|
||||
break;
|
||||
}
|
||||
|
||||
if (completed != 0) {
|
||||
@ -704,6 +711,7 @@ ioat_process_events(struct ioat_softc *ioat)
|
||||
ioat->stats.descriptors_processed += completed;
|
||||
}
|
||||
|
||||
out:
|
||||
ioat_write_chanctrl(ioat, IOAT_CHANCTRL_RUN);
|
||||
|
||||
/* Perform a racy check first; only take the locks if it passes. */
|
||||
@ -1823,6 +1831,9 @@ ioat_reset_hw(struct ioat_softc *ioat)
|
||||
ioat->resetting_cleanup = TRUE;
|
||||
mtx_unlock(&ioat->cleanup_lock);
|
||||
|
||||
CTR2(KTR_IOAT, "%s channel=%u quiesced and drained", __func__,
|
||||
ioat->chan_idx);
|
||||
|
||||
status = ioat_get_chansts(ioat);
|
||||
if (is_ioat_active(status) || is_ioat_idle(status))
|
||||
ioat_suspend(ioat);
|
||||
@ -1843,6 +1854,9 @@ ioat_reset_hw(struct ioat_softc *ioat)
|
||||
chanerr = ioat_read_4(ioat, IOAT_CHANERR_OFFSET);
|
||||
ioat_write_4(ioat, IOAT_CHANERR_OFFSET, chanerr);
|
||||
|
||||
CTR2(KTR_IOAT, "%s channel=%u hardware suspended", __func__,
|
||||
ioat->chan_idx);
|
||||
|
||||
/*
|
||||
* IOAT v3 workaround - CHANERRMSK_INT with 3E07h to masks out errors
|
||||
* that can cause stability issues for IOAT v3.
|
||||
@ -1862,6 +1876,8 @@ ioat_reset_hw(struct ioat_softc *ioat)
|
||||
}
|
||||
|
||||
ioat_reset(ioat);
|
||||
CTR2(KTR_IOAT, "%s channel=%u hardware reset", __func__,
|
||||
ioat->chan_idx);
|
||||
|
||||
/* Wait at most 20 ms */
|
||||
for (timeout = 0; ioat_reset_pending(ioat) && timeout < 20; timeout++)
|
||||
@ -1911,21 +1927,24 @@ ioat_reset_hw(struct ioat_softc *ioat)
|
||||
ioat_write_chancmp(ioat, ioat->comp_update_bus_addr);
|
||||
ioat_write_chainaddr(ioat, ioat->ring[0]->hw_desc_bus_addr);
|
||||
error = 0;
|
||||
CTR2(KTR_IOAT, "%s channel=%u configured channel", __func__,
|
||||
ioat->chan_idx);
|
||||
|
||||
out:
|
||||
/* Enqueues a null operation and ensures it completes. */
|
||||
if (error == 0) {
|
||||
error = ioat_start_channel(ioat);
|
||||
CTR2(KTR_IOAT, "%s channel=%u started channel", __func__,
|
||||
ioat->chan_idx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Resume completions now that ring state is consistent.
|
||||
* ioat_start_channel will add a pending completion and if we are still
|
||||
* blocking completions, we may livelock.
|
||||
*/
|
||||
mtx_lock(&ioat->cleanup_lock);
|
||||
ioat->resetting_cleanup = FALSE;
|
||||
mtx_unlock(&ioat->cleanup_lock);
|
||||
|
||||
/* Enqueues a null operation and ensures it completes. */
|
||||
if (error == 0)
|
||||
error = ioat_start_channel(ioat);
|
||||
|
||||
/* Unblock submission of new work */
|
||||
mtx_lock(IOAT_REFLK);
|
||||
ioat->quiescing = FALSE;
|
||||
@ -1933,6 +1952,11 @@ out:
|
||||
|
||||
ioat->resetting = FALSE;
|
||||
wakeup(&ioat->resetting);
|
||||
|
||||
if (ioat->is_completion_pending)
|
||||
callout_reset(&ioat->poll_timer, 1, ioat_poll_timer_callback,
|
||||
ioat);
|
||||
CTR2(KTR_IOAT, "%s channel=%u reset done", __func__, ioat->chan_idx);
|
||||
mtx_unlock(IOAT_REFLK);
|
||||
|
||||
return (error);
|
||||
|
@ -135,6 +135,7 @@ struct tsec_softc {
|
||||
int phyaddr;
|
||||
bus_space_tag_t phy_bst;
|
||||
bus_space_handle_t phy_bsh;
|
||||
int phy_regoff;
|
||||
};
|
||||
|
||||
/* interface to get/put generic objects */
|
||||
@ -258,9 +259,11 @@ extern struct mtx tsec_phy_mtx;
|
||||
#define TSEC_PHY_LOCK(sc) mtx_lock(&tsec_phy_mtx)
|
||||
#define TSEC_PHY_UNLOCK(sc) mtx_unlock(&tsec_phy_mtx)
|
||||
#define TSEC_PHY_READ(sc, reg) \
|
||||
bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, (reg))
|
||||
bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, \
|
||||
(reg) + (sc)->phy_regoff)
|
||||
#define TSEC_PHY_WRITE(sc, reg, val) \
|
||||
bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, (reg), (val))
|
||||
bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, \
|
||||
(reg) + (sc)->phy_regoff, (val))
|
||||
|
||||
/* Lock for transmitter */
|
||||
#define TSEC_TRANSMIT_LOCK(sc) do { \
|
||||
|
@ -121,25 +121,33 @@ tsec_fdt_probe(device_t dev)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
sc->sc_rrid = 0;
|
||||
sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid,
|
||||
RF_ACTIVE);
|
||||
if (sc->sc_rres == NULL)
|
||||
return (ENXIO);
|
||||
/*
|
||||
* Device trees with "fsl,etsec2" compatible nodes don't have a reg
|
||||
* property, as it's been relegated to the queue-group children.
|
||||
*/
|
||||
if (ofw_bus_is_compatible(dev, "fsl,etsec2"))
|
||||
sc->is_etsec = 1;
|
||||
else {
|
||||
sc->sc_rrid = 0;
|
||||
sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid,
|
||||
RF_ACTIVE);
|
||||
if (sc->sc_rres == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
|
||||
sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
|
||||
sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
|
||||
sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
|
||||
|
||||
/* Check if we are eTSEC (enhanced TSEC) */
|
||||
id = TSEC_READ(sc, TSEC_REG_ID);
|
||||
sc->is_etsec = ((id >> 16) == TSEC_ETSEC_ID) ? 1 : 0;
|
||||
id |= TSEC_READ(sc, TSEC_REG_ID2);
|
||||
/* Check if we are eTSEC (enhanced TSEC) */
|
||||
id = TSEC_READ(sc, TSEC_REG_ID);
|
||||
sc->is_etsec = ((id >> 16) == TSEC_ETSEC_ID) ? 1 : 0;
|
||||
id |= TSEC_READ(sc, TSEC_REG_ID2);
|
||||
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres);
|
||||
|
||||
if (id == 0) {
|
||||
device_printf(dev, "could not identify TSEC type\n");
|
||||
return (ENXIO);
|
||||
if (id == 0) {
|
||||
device_printf(dev, "could not identify TSEC type\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->is_etsec)
|
||||
@ -154,13 +162,31 @@ static int
|
||||
tsec_fdt_attach(device_t dev)
|
||||
{
|
||||
struct tsec_softc *sc;
|
||||
phandle_t phy;
|
||||
struct resource_list *rl;
|
||||
phandle_t child, mdio, phy;
|
||||
int acells, scells;
|
||||
int error = 0;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
sc->node = ofw_bus_get_node(dev);
|
||||
|
||||
if (fdt_addrsize_cells(sc->node, &acells, &scells) != 0) {
|
||||
acells = 1;
|
||||
scells = 1;
|
||||
}
|
||||
if (ofw_bus_is_compatible(dev, "fsl,etsec2")) {
|
||||
rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
|
||||
|
||||
/*
|
||||
* TODO: Add all children resources to the list. Will be
|
||||
* required to support multigroup mode.
|
||||
*/
|
||||
child = OF_child(sc->node);
|
||||
ofw_bus_reg_to_rl(dev, child, acells, scells, rl);
|
||||
ofw_bus_intr_to_rl(dev, child, rl, NULL);
|
||||
}
|
||||
|
||||
/* Get phy address from fdt */
|
||||
if (OF_getencprop(sc->node, "phy-handle", &phy, sizeof(phy)) <= 0) {
|
||||
device_printf(dev, "PHY not found in device tree");
|
||||
@ -168,9 +194,17 @@ tsec_fdt_attach(device_t dev)
|
||||
}
|
||||
|
||||
phy = OF_node_from_xref(phy);
|
||||
OF_decode_addr(OF_parent(phy), 0, &sc->phy_bst, &sc->phy_bsh, NULL);
|
||||
mdio = OF_parent(phy);
|
||||
OF_decode_addr(mdio, 0, &sc->phy_bst, &sc->phy_bsh, NULL);
|
||||
OF_getencprop(phy, "reg", &sc->phyaddr, sizeof(sc->phyaddr));
|
||||
|
||||
/*
|
||||
* etsec2 MDIO nodes are given the MDIO module base address, so we need
|
||||
* to add the MII offset to get the PHY registers.
|
||||
*/
|
||||
if (ofw_bus_node_is_compatible(mdio, "fsl,etsec2-mdio"))
|
||||
sc->phy_regoff = TSEC_REG_MIIBASE;
|
||||
|
||||
/* Init timer */
|
||||
callout_init(&sc->tsec_callout, 1);
|
||||
|
||||
|
@ -5349,6 +5349,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
||||
case DEV_SUSPEND:
|
||||
case DEV_RESUME:
|
||||
case DEV_SET_DRIVER:
|
||||
case DEV_CLEAR_DRIVER:
|
||||
case DEV_RESCAN:
|
||||
case DEV_DELETE:
|
||||
error = priv_check(td, PRIV_DRIVER);
|
||||
@ -5514,6 +5515,25 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
||||
error = device_probe_and_attach(dev);
|
||||
break;
|
||||
}
|
||||
case DEV_CLEAR_DRIVER:
|
||||
if (!(dev->flags & DF_FIXEDCLASS)) {
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
if (device_is_attached(dev)) {
|
||||
if (req->dr_flags & DEVF_CLEAR_DRIVER_DETACH)
|
||||
error = device_detach(dev);
|
||||
else
|
||||
error = EBUSY;
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
|
||||
dev->flags &= ~DF_FIXEDCLASS;
|
||||
dev->flags |= DF_WILDCARD;
|
||||
devclass_delete_device(dev->devclass, dev);
|
||||
error = device_probe_and_attach(dev);
|
||||
break;
|
||||
case DEV_RESCAN:
|
||||
if (!device_is_attached(dev)) {
|
||||
error = ENXIO;
|
||||
|
@ -117,6 +117,7 @@ struct devreq {
|
||||
#define DEV_SUSPEND _IOW('D', 5, struct devreq)
|
||||
#define DEV_RESUME _IOW('D', 6, struct devreq)
|
||||
#define DEV_SET_DRIVER _IOW('D', 7, struct devreq)
|
||||
#define DEV_CLEAR_DRIVER _IOW('D', 8, struct devreq)
|
||||
#define DEV_RESCAN _IOW('D', 9, struct devreq)
|
||||
#define DEV_DELETE _IOW('D', 10, struct devreq)
|
||||
|
||||
@ -126,6 +127,9 @@ struct devreq {
|
||||
/* Flags for DEV_SET_DRIVER. */
|
||||
#define DEVF_SET_DRIVER_DETACH 0x0000001 /* Detach existing driver. */
|
||||
|
||||
/* Flags for DEV_CLEAR_DRIVER. */
|
||||
#define DEVF_CLEAR_DRIVER_DETACH 0x0000001 /* Detach existing driver. */
|
||||
|
||||
/* Flags for DEV_DELETE. */
|
||||
#define DEVF_FORCE_DELETE 0x0000001
|
||||
|
||||
|
@ -574,7 +574,7 @@ bnep_recv_filter_multi_addr_rsp(channel_t *chan, uint8_t *ptr, size_t size)
|
||||
}
|
||||
|
||||
void
|
||||
bnep_send_control(channel_t *chan, uint8_t type, ...)
|
||||
bnep_send_control(channel_t *chan, unsigned type, ...)
|
||||
{
|
||||
packet_t *pkt;
|
||||
uint8_t *p;
|
||||
@ -590,7 +590,7 @@ bnep_send_control(channel_t *chan, uint8_t type, ...)
|
||||
va_start(ap, type);
|
||||
|
||||
*p++ = BNEP_CONTROL;
|
||||
*p++ = type;
|
||||
*p++ = (uint8_t)type;
|
||||
|
||||
switch(type) {
|
||||
case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
|
||||
|
@ -183,7 +183,7 @@ b2eaddr(void *dst, bdaddr_t *src)
|
||||
/* bnep.c */
|
||||
bool bnep_send(channel_t *, packet_t *);
|
||||
bool bnep_recv(packet_t *);
|
||||
void bnep_send_control(channel_t *, uint8_t, ...);
|
||||
void bnep_send_control(channel_t *, unsigned, ...);
|
||||
|
||||
/* channel.c */
|
||||
void channel_init(void);
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 27, 2016
|
||||
.Dd August 29, 2016
|
||||
.Dt DEVCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -36,6 +36,10 @@
|
||||
.Cm attach
|
||||
.Ar device
|
||||
.Nm
|
||||
.Cm clear driver
|
||||
.Op Fl f
|
||||
.Ar device
|
||||
.Nm
|
||||
.Cm detach
|
||||
.Op Fl f
|
||||
.Ar device
|
||||
@ -133,6 +137,21 @@ If the device is already attached to a device driver and the
|
||||
.Fl f
|
||||
flag is not specified,
|
||||
the device will not be changed.
|
||||
.It Xo Cm clear driver
|
||||
.Op Fl f
|
||||
.Ar device
|
||||
.Xc
|
||||
Clear a previously-forced driver name so that the device is able to use any
|
||||
valid device driver.
|
||||
After the previous name has been cleared,
|
||||
the device is reprobed so that other device drivers may attach to it.
|
||||
This can be used to undo an earlier
|
||||
.Cm set driver
|
||||
command.
|
||||
If the device is currently attached to a device driver and the
|
||||
.Fl f
|
||||
flag is not specified,
|
||||
the device will not be changed.
|
||||
.It Cm rescan Ar device
|
||||
Rescan a bus device checking for devices that have been added or
|
||||
removed.
|
||||
|
@ -65,12 +65,13 @@ static int devctl_table_handler(struct devctl_command **start,
|
||||
|
||||
SET_DECLARE(DEVCTL_DATASET(top), struct devctl_command);
|
||||
|
||||
DEVCTL_TABLE(top, clear);
|
||||
DEVCTL_TABLE(top, set);
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
"usage: devctl attach device",
|
||||
" devctl detach [-f] device",
|
||||
" devctl disable [-f] device",
|
||||
@ -78,6 +79,7 @@ usage(void)
|
||||
" devctl suspend device",
|
||||
" devctl resume device",
|
||||
" devctl set driver [-f] device driver",
|
||||
" devctl clear driver [-f] device",
|
||||
" devctl rescan device",
|
||||
" devctl delete [-f] device");
|
||||
exit(1);
|
||||
@ -261,6 +263,40 @@ set_driver(int ac, char **av)
|
||||
}
|
||||
DEVCTL_COMMAND(set, driver, set_driver);
|
||||
|
||||
static void
|
||||
clear_driver_usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: devctl clear driver [-f] device\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int
|
||||
clear_driver(int ac, char **av)
|
||||
{
|
||||
bool force;
|
||||
int ch;
|
||||
|
||||
force = false;
|
||||
while ((ch = getopt(ac, av, "f")) != -1)
|
||||
switch (ch) {
|
||||
case 'f':
|
||||
force = true;
|
||||
break;
|
||||
default:
|
||||
clear_driver_usage();
|
||||
}
|
||||
ac -= optind;
|
||||
av += optind;
|
||||
|
||||
if (ac != 1)
|
||||
clear_driver_usage();
|
||||
if (devctl_clear_driver(av[0], force) < 0)
|
||||
err(1, "Failed to clear %s driver", av[0]);
|
||||
return (0);
|
||||
}
|
||||
DEVCTL_COMMAND(clear, driver, clear_driver);
|
||||
|
||||
static int
|
||||
rescan(int ac, char **av)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user