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:
parent
fe28ec8024
commit
e05c6840a1
@ -25,7 +25,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd February 2, 2016
|
.Dd April 27, 2016
|
||||||
.Dt DEVCTL 3
|
.Dt DEVCTL 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -34,6 +34,7 @@
|
|||||||
.Nm devctl_detach ,
|
.Nm devctl_detach ,
|
||||||
.Nm devctl_disable ,
|
.Nm devctl_disable ,
|
||||||
.Nm devctl_enable ,
|
.Nm devctl_enable ,
|
||||||
|
.Nm devctl_rescan ,
|
||||||
.Nm devctl_resume ,
|
.Nm devctl_resume ,
|
||||||
.Nm devctl_set_driver ,
|
.Nm devctl_set_driver ,
|
||||||
.Nm devctl_suspend
|
.Nm devctl_suspend
|
||||||
@ -51,6 +52,8 @@
|
|||||||
.Ft int
|
.Ft int
|
||||||
.Fn devctl_enable "const char *device"
|
.Fn devctl_enable "const char *device"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn devctl_rescan "const char *device"
|
||||||
|
.Ft int
|
||||||
.Fn devctl_resume "const char *device"
|
.Fn devctl_resume "const char *device"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn devctl_set_driver "const char *device" "const char *driver" "bool force"
|
.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,
|
is true,
|
||||||
the device will be detached from its current device driver before it is
|
the device will be detached from its current device driver before it is
|
||||||
attached to the new device driver.
|
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
|
.Sh RETURN VALUES
|
||||||
.Rv -std devctl_attach devctl_detach devctl_disable devctl_enable \
|
.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
|
.Sh ERRORS
|
||||||
In addition to specific errors noted below,
|
In addition to specific errors noted below,
|
||||||
all of the
|
all of the
|
||||||
@ -280,6 +288,16 @@ The device is disabled.
|
|||||||
.It Bq Er ENXIO
|
.It Bq Er ENXIO
|
||||||
The new device driver failed to attach.
|
The new device driver failed to attach.
|
||||||
.El
|
.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
|
.Sh SEE ALSO
|
||||||
.Xr devinfo 3 ,
|
.Xr devinfo 3 ,
|
||||||
.Xr devstat 3 ,
|
.Xr devstat 3 ,
|
||||||
|
@ -122,3 +122,10 @@ devctl_set_driver(const char *device, const char *driver, bool force)
|
|||||||
req.dr_flags |= DEVF_SET_DRIVER_DETACH;
|
req.dr_flags |= DEVF_SET_DRIVER_DETACH;
|
||||||
return (devctl_request(DEV_SET_DRIVER, &req));
|
return (devctl_request(DEV_SET_DRIVER, &req));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
devctl_rescan(const char *device)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (devctl_simple_request(DEV_RESCAN, device, 0));
|
||||||
|
}
|
||||||
|
@ -38,5 +38,6 @@ int devctl_disable(const char *device, bool force_detach);
|
|||||||
int devctl_suspend(const char *device);
|
int devctl_suspend(const char *device);
|
||||||
int devctl_resume(const char *device);
|
int devctl_resume(const char *device);
|
||||||
int devctl_set_driver(const char *device, const char *driver, bool force);
|
int devctl_set_driver(const char *device, const char *driver, bool force);
|
||||||
|
int devctl_rescan(const char *device);
|
||||||
|
|
||||||
#endif /* !__DEVCTL_H__ */
|
#endif /* !__DEVCTL_H__ */
|
||||||
|
51
share/man/man9/BUS_RESCAN.9
Normal file
51
share/man/man9/BUS_RESCAN.9
Normal 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
|
@ -46,6 +46,7 @@ MAN= accept_filter.9 \
|
|||||||
BUS_NEW_PASS.9 \
|
BUS_NEW_PASS.9 \
|
||||||
BUS_PRINT_CHILD.9 \
|
BUS_PRINT_CHILD.9 \
|
||||||
BUS_READ_IVAR.9 \
|
BUS_READ_IVAR.9 \
|
||||||
|
BUS_RESCAN.9 \
|
||||||
bus_release_resource.9 \
|
bus_release_resource.9 \
|
||||||
bus_set_pass.9 \
|
bus_set_pass.9 \
|
||||||
bus_set_resource.9 \
|
bus_set_resource.9 \
|
||||||
|
@ -231,6 +231,19 @@ METHOD device_t add_child {
|
|||||||
int _unit;
|
int _unit;
|
||||||
} DEFAULT null_add_child;
|
} 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
|
* @brief Allocate a system resource
|
||||||
*
|
*
|
||||||
|
@ -5203,6 +5203,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
|||||||
case DEV_SUSPEND:
|
case DEV_SUSPEND:
|
||||||
case DEV_RESUME:
|
case DEV_RESUME:
|
||||||
case DEV_SET_DRIVER:
|
case DEV_SET_DRIVER:
|
||||||
|
case DEV_RESCAN:
|
||||||
error = priv_check(td, PRIV_DRIVER);
|
error = priv_check(td, PRIV_DRIVER);
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
error = find_device(req, &dev);
|
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);
|
error = device_probe_and_attach(dev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DEV_RESCAN:
|
||||||
|
if (!device_is_attached(dev)) {
|
||||||
|
error = ENXIO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
error = BUS_RESCAN(dev);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mtx_unlock(&Giant);
|
mtx_unlock(&Giant);
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -117,6 +117,7 @@ struct devreq {
|
|||||||
#define DEV_SUSPEND _IOW('D', 5, struct devreq)
|
#define DEV_SUSPEND _IOW('D', 5, struct devreq)
|
||||||
#define DEV_RESUME _IOW('D', 6, struct devreq)
|
#define DEV_RESUME _IOW('D', 6, struct devreq)
|
||||||
#define DEV_SET_DRIVER _IOW('D', 7, 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. */
|
/* Flags for DEV_DETACH and DEV_DISABLE. */
|
||||||
#define DEVF_FORCE_DETACH 0x0000001
|
#define DEVF_FORCE_DETACH 0x0000001
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd February 2, 2016
|
.Dd April 27, 2016
|
||||||
.Dt DEVCTL 8
|
.Dt DEVCTL 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -56,6 +56,9 @@
|
|||||||
.Cm set driver
|
.Cm set driver
|
||||||
.Op Fl f
|
.Op Fl f
|
||||||
.Ar device driver
|
.Ar device driver
|
||||||
|
.Nm
|
||||||
|
.Cm rescan
|
||||||
|
.Ar device
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
@ -126,6 +129,9 @@ If the device is already attached to a device driver and the
|
|||||||
.Fl f
|
.Fl f
|
||||||
flag is not specified,
|
flag is not specified,
|
||||||
the device will not be changed.
|
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
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr devctl 3 ,
|
.Xr devctl 3 ,
|
||||||
|
@ -259,6 +259,18 @@ set_driver(int ac, char **av)
|
|||||||
}
|
}
|
||||||
DEVCTL_COMMAND(set, driver, set_driver);
|
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
|
int
|
||||||
main(int ac, char *av[])
|
main(int ac, char *av[])
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user