MFhead @ r305041

This commit is contained in:
Enji Cooper 2016-08-30 02:07:15 +00:00
commit f39ffb4147
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/netbsd-tests-update-12/; revision=305042
19 changed files with 362 additions and 126 deletions

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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 @@ ioat_reset_hw(struct ioat_softc *ioat)
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);

View File

@ -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 { \

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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.

View File

@ -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)
{