Add a new rescan method to the bus interface.

The BUS_RESCAN() method rescans a single bus device checking for devices
that have been added or removed from the bus.  A new 'rescan' command is
added to devctl(8) to trigger a rescan.

Differential Revision:	https://reviews.freebsd.org/D6016
This commit is contained in:
John Baldwin 2016-04-27 16:29:03 +00:00
parent 167e63e394
commit a907c6914c
10 changed files with 121 additions and 3 deletions

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 2, 2016
.Dd April 27, 2016
.Dt DEVCTL 3
.Os
.Sh NAME
@ -34,6 +34,7 @@
.Nm devctl_detach ,
.Nm devctl_disable ,
.Nm devctl_enable ,
.Nm devctl_rescan ,
.Nm devctl_resume ,
.Nm devctl_set_driver ,
.Nm devctl_suspend
@ -51,6 +52,8 @@
.Ft int
.Fn devctl_enable "const char *device"
.Ft int
.Fn devctl_rescan "const char *device"
.Ft int
.Fn devctl_resume "const char *device"
.Ft int
.Fn devctl_set_driver "const char *device" "const char *driver" "bool force"
@ -149,9 +152,14 @@ If the device is already attached and
is true,
the device will be detached from its current device driver before it is
attached to the new device driver.
.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_detach devctl_disable devctl_enable \
devctl_suspend devctl_resume devctl_set_driver
devctl_suspend devctl_rescan devctl_resume devctl_set_driver
.Sh ERRORS
In addition to specific errors noted below,
all of the
@ -280,6 +288,16 @@ The device is disabled.
.It Bq Er ENXIO
The new device driver failed to attach.
.El
.Pp
The
.Fn devctl_rescan
function may fail if:
.Bl -tag -width Er
.It Bq Er ENXIO
The device is not attached to a driver.
.It Bq Er ENXIO
The bus driver does not support rescanning.
.El
.Sh SEE ALSO
.Xr devinfo 3 ,
.Xr devstat 3 ,

View File

@ -122,3 +122,10 @@ devctl_set_driver(const char *device, const char *driver, bool force)
req.dr_flags |= DEVF_SET_DRIVER_DETACH;
return (devctl_request(DEV_SET_DRIVER, &req));
}
int
devctl_rescan(const char *device)
{
return (devctl_simple_request(DEV_RESCAN, device, 0));
}

View File

@ -38,5 +38,6 @@ 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_rescan(const char *device);
#endif /* !__DEVCTL_H__ */

View File

@ -0,0 +1,51 @@
.\" -*- nroff -*-
.\"
.\" Copyright (c) 2016 John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
.\" 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.
.\"
.\" 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.
.\"
.\" $FreeBSD$
.\"
.Dd April 27, 2016
.Dt BUS_RESCAN 9
.Os
.Sh NAME
.Nm BUS_RESCAN
.Nd "rescan a bus checking for devices that have been added or removed"
.Sh SYNOPSIS
.In sys/param.h
.In sys/bus.h
.Ft void
.Fn BUS_RESCAN "device_t dev"
.Sh DESCRIPTION
The
.Fn BUS_RESCAN
method is called to request a rescan of the child devices on a bus device.
The method should add any devices that have been added since the previous
scan and remove devices that have been removed.
This method is not required to re-examine existing devices to determine if
their properties have changed.
This method is also not required to propagate the rescan request to child
devices.
.Sh SEE ALSO
.Xr device 9

View File

@ -46,6 +46,7 @@ MAN= accept_filter.9 \
BUS_NEW_PASS.9 \
BUS_PRINT_CHILD.9 \
BUS_READ_IVAR.9 \
BUS_RESCAN.9 \
bus_release_resource.9 \
bus_set_pass.9 \
bus_set_resource.9 \

View File

@ -231,6 +231,19 @@ METHOD device_t add_child {
int _unit;
} DEFAULT null_add_child;
/**
* @brief Rescan the bus
*
* This method is called by a parent bridge or devctl to trigger a bus
* rescan. The rescan should delete devices no longer present and
* enumerate devices that have newly arrived.
*
* @param _dev the bus device
*/
METHOD int rescan {
device_t _dev;
}
/**
* @brief Allocate a system resource
*

View File

@ -5203,6 +5203,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_RESCAN:
error = priv_check(td, PRIV_DRIVER);
if (error == 0)
error = find_device(req, &dev);
@ -5366,6 +5367,13 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
error = device_probe_and_attach(dev);
break;
}
case DEV_RESCAN:
if (!device_is_attached(dev)) {
error = ENXIO;
break;
}
error = BUS_RESCAN(dev);
break;
}
mtx_unlock(&Giant);
return (error);

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_RESCAN _IOW('D', 9, struct devreq)
/* Flags for DEV_DETACH and DEV_DISABLE. */
#define DEVF_FORCE_DETACH 0x0000001

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 2, 2016
.Dd April 27, 2016
.Dt DEVCTL 8
.Os
.Sh NAME
@ -56,6 +56,9 @@
.Cm set driver
.Op Fl f
.Ar device driver
.Nm
.Cm rescan
.Ar device
.Sh DESCRIPTION
The
.Nm
@ -126,6 +129,9 @@ 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 Cm rescan Ar device
Rescan a bus device checking for devices that have been added or
removed.
.El
.Sh SEE ALSO
.Xr devctl 3 ,

View File

@ -259,6 +259,18 @@ set_driver(int ac, char **av)
}
DEVCTL_COMMAND(set, driver, set_driver);
static int
rescan(int ac, char **av)
{
if (ac != 2)
usage();
if (devctl_rescan(av[1]) < 0)
err(1, "Failed to rescan %s", av[1]);
return (0);
}
DEVCTL_COMMAND(top, rescan, rescan);
int
main(int ac, char *av[])
{