From e05ec081fe81beb79567b82723bd045aa50f19c0 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 29 Aug 2016 22:48:36 +0000 Subject: Implement 'devctl clear driver' to undo a previous 'devctl set driver'. Add a new 'clear driver' command for devctl along with the accompanying ioctl and devctl_clear_driver() library routine to reset a device to use a wildcard devclass instead of a fixed devclass. This can be used to undo a previous 'set driver' command. After the device's name has been reset to permit wildcard names, it is reprobed so that it can attach to newly-available (to it) device drivers. MFC after: 1 month Sponsored by: Chelsio Communications --- lib/libdevctl/devctl.3 | 45 ++++++++++++++++++++++++++++++++++++++++++--- lib/libdevctl/devctl.c | 8 ++++++++ lib/libdevctl/devctl.h | 1 + 3 files changed, 51 insertions(+), 3 deletions(-) (limited to 'lib/libdevctl') diff --git a/lib/libdevctl/devctl.3 b/lib/libdevctl/devctl.3 index 866bb6a36cda..a4fe0620ac3f 100644 --- a/lib/libdevctl/devctl.3 +++ b/lib/libdevctl/devctl.3 @@ -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 diff --git a/lib/libdevctl/devctl.c b/lib/libdevctl/devctl.c index 9f275e786252..5013fb0b9d57 100644 --- a/lib/libdevctl/devctl.c +++ b/lib/libdevctl/devctl.c @@ -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) { diff --git a/lib/libdevctl/devctl.h b/lib/libdevctl/devctl.h index 670ca1a114f5..d49199ad0b59 100644 --- a/lib/libdevctl/devctl.h +++ b/lib/libdevctl/devctl.h @@ -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); -- cgit v1.2.3