Implement devctl(8) command 'reset', using DEV_RESET /dev/devctl2 ioctl.

Reviewed by:	imp (previous version), jhb (previous version)
Sponsored by:	Mellanox Technologies
MFC after:	2 weeks
Differential revision:	https://reviews.freebsd.org/D19646
This commit is contained in:
Konstantin Belousov 2019-04-05 19:32:26 +00:00
parent 1d1a5c2b02
commit 4fbf8e1c2e
5 changed files with 124 additions and 3 deletions

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd August 22, 2018
.Dd April 4, 2019
.Dt DEVCTL 3
.Os
.Sh NAME
@ -37,6 +37,7 @@
.Nm devctl_enable ,
.Nm devctl_freeze ,
.Nm devctl_rescan ,
.Nm devctl_reset ,
.Nm devctl_resume ,
.Nm devctl_set_driver ,
.Nm devctl_suspend ,
@ -63,6 +64,8 @@
.Ft int
.Fn devctl_rescan "const char *device"
.Ft int
.Fn devctl_reset "const char *device" "bool detach"
.Ft int
.Fn devctl_resume "const char *device"
.Ft int
.Fn devctl_set_driver "const char *device" "const char *driver" "bool force"
@ -204,6 +207,15 @@ The
.Fn devctl_thaw
function resumes (thaws the freeze) probe and attach processing
initiated in response to drivers being loaded.
.Pp
The
.Fn devctl_reset
function resets the specified device using bus-specific reset method.
The
.Fa detach
argument, if true, specifies that the device driver is detached before
the reset, and re-attached afterwards.
If false, the device is suspended before the reset, and resumed after.
.Sh RETURN VALUES
.Rv -std devctl_attach devctl_clear_driver devctl_delete devctl_detach \
devctl_disable devctl_enable devctl_suspend devctl_rescan devctl_resume \
@ -377,6 +389,21 @@ is false.
.Fa dev
is the root device of the device tree.
.El
.Pp
The
.Fn devctl_reset
function may fail if:
.Bl -tag -width Er
.It Bq Er ENXIO
The bus does not implement the reset method.
.It Bq Er ETIMEDOUT
The device failed to respond after the reset in the time limits
specific to the bus.
.El
The
.Fn devctl_reset
function may also return errors caused by the attach, detach, suspend,
and resume methods of the device driver.
.Sh SEE ALSO
.Xr devinfo 3 ,
.Xr devstat 3 ,
@ -391,3 +418,20 @@ If a device is suspended individually via
.Fn devctl_suspend
and the entire machine is subsequently suspended,
the device will be resumed when the machine resumes.
.Pp
Similarly, if the device is suspended, and
.Fn devctl_reset
is called on the device with
.Fa detach
set to
.Va false ,
the device is resumed by the
.Fn devctl_reset
call.
Or, if the driver for the device is detached manually, and
.Fn devctl_reset
is called on the device with
.Fa detach
set to
.Va true ,
device reset re-attaches the driver.

View File

@ -158,3 +158,11 @@ devctl_thaw(void)
return (devctl_simple_request(DEV_THAW, "", 0));
}
int
devctl_reset(const char *device, bool detach)
{
return (devctl_simple_request(DEV_RESET, device, detach ?
DEVF_RESET_DETACH : 0));
}

View File

@ -43,6 +43,7 @@ int devctl_rescan(const char *device);
int devctl_delete(const char *device, bool force);
int devctl_freeze(void);
int devctl_thaw(void);
int devctl_reset(const char *device, bool detach);
__END_DECLS
#endif /* !__DEVCTL_H__ */

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd August 29, 2016
.Dd April 4, 2019
.Dt DEVCTL 8
.Os
.Sh NAME
@ -66,6 +66,10 @@
.Cm delete
.Op Fl f
.Ar device
.Nm
.Cm reset
.Op Fl d
.Ar device
.Sh DESCRIPTION
The
.Nm
@ -166,7 +170,35 @@ the device will be deleted even if it is physically present.
This command should be used with care as a device that is deleted but present
can no longer be used unless the parent bus device rediscovers the device via
a rescan request.
.It Xo Cm reset
.Op Fl d
.Ar device
.Xc
Reset the device, using bus-specific reset method.
Drivers for the devices being reset are suspended around the reset.
If the
.Fl d
option is specified, drivers are detached instead.
.Pp
Currently, resets are implemented for PCIe buses and PCI devices.
For PCIe bus, the link is disabled and then re-trained, causing all
children of the bus to reset.
Use
.Fl p
option of
.Xr devinfo 8
tool to report parent bus for the device.
For PCI device, if Function-Level Reset is implemented by it, FLR is
tried first; if failed or not implemented, power reset is tried.
.Pp
If you have detached or suspended a child device explicitly and then
do a reset, the child device will end up attached.
.El
.Sh BUGS
Currently there is no administrative flag to prevent re-attach or resume
of the manually detached or suspended devices after reset.
Similarly, there is no flag to prevent un-suspending of the the manually
suspended devices after system resume.
.Sh SEE ALSO
.Xr devctl 3 ,
.Xr devinfo 8

View File

@ -82,7 +82,9 @@ usage(void)
" devctl rescan device\n"
" devctl delete [-f] device\n"
" devctl freeze\n"
" devctl thaw\n");
" devctl thaw\n"
" devctl reset [-d] device\n"
);
exit(1);
}
@ -384,6 +386,40 @@ thaw(int ac, char **av __unused)
}
DEVCTL_COMMAND(top, thaw, thaw);
static void
reset_usage(void)
{
fprintf(stderr, "usage: devctl reset [-d] device\n");
exit(1);
}
static int
reset(int ac, char **av)
{
bool detach;
int ch;
detach = false;
while ((ch = getopt(ac, av, "d")) != -1)
switch (ch) {
case 'd':
detach = true;
break;
default:
reset_usage();
}
ac -= optind;
av += optind;
if (ac != 1)
reset_usage();
if (devctl_reset(av[0], detach) < 0)
err(1, "Failed to reset %s", av[0]);
return (0);
}
DEVCTL_COMMAND(top, reset, reset);
int
main(int ac, char *av[])
{