1/*- 2 * Copyright (c) 2014 John Baldwin <jhb@FreeBSD.org> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> 27__FBSDID("$FreeBSD: stable/11/lib/libdevctl/devctl.c 367457 2020-11-07 18:10:59Z dim $"); 28 29#include <sys/types.h> 30#include <sys/bus.h> 31#include <errno.h> 32#include <fcntl.h> 33#include <string.h> 34#include "devctl.h" 35 36static int 37devctl_request(u_long cmd, struct devreq *req) 38{ 39 static int devctl2_fd = -1; 40 41 if (devctl2_fd == -1) { 42 devctl2_fd = open("/dev/devctl2", O_RDONLY); 43 if (devctl2_fd == -1) 44 return (-1); 45 } 46 return (ioctl(devctl2_fd, cmd, req)); 47} 48 49static int 50devctl_simple_request(u_long cmd, const char *name, int flags) 51{ 52 struct devreq req; 53 54 memset(&req, 0, sizeof(req)); 55 if (strlcpy(req.dr_name, name, sizeof(req.dr_name)) >= 56 sizeof(req.dr_name)) { 57 errno = EINVAL; 58 return (-1); 59 } 60 req.dr_flags = flags; 61 return (devctl_request(cmd, &req)); 62} 63 64int 65devctl_attach(const char *device) 66{ 67 68 return (devctl_simple_request(DEV_ATTACH, device, 0)); 69} 70 71int 72devctl_detach(const char *device, bool force) 73{ 74 75 return (devctl_simple_request(DEV_DETACH, device, force ? 76 DEVF_FORCE_DETACH : 0)); 77} 78 79int 80devctl_enable(const char *device) 81{ 82 83 return (devctl_simple_request(DEV_ENABLE, device, 0)); 84} 85 86int 87devctl_disable(const char *device, bool force_detach) 88{ 89 90 return (devctl_simple_request(DEV_DISABLE, device, force_detach ? 91 DEVF_FORCE_DETACH : 0)); 92} 93 94int 95devctl_suspend(const char *device) 96{ 97 98 return (devctl_simple_request(DEV_SUSPEND, device, 0)); 99} 100 101int 102devctl_resume(const char *device) 103{ 104 105 return (devctl_simple_request(DEV_RESUME, device, 0)); 106} 107 108int 109devctl_set_driver(const char *device, const char *driver, bool force) 110{ 111 struct devreq req; 112 113 memset(&req, 0, sizeof(req)); 114 if (strlcpy(req.dr_name, device, sizeof(req.dr_name)) >= 115 sizeof(req.dr_name)) { 116 errno = EINVAL; 117 return (-1); 118 } 119 req.dr_data = __DECONST(char *, driver); 120 if (force) 121 req.dr_flags |= DEVF_SET_DRIVER_DETACH; 122 return (devctl_request(DEV_SET_DRIVER, &req)); 123} 124 125int 126devctl_clear_driver(const char *device, bool force) 127{ 128 129 return (devctl_simple_request(DEV_CLEAR_DRIVER, device, force ? 130 DEVF_CLEAR_DRIVER_DETACH : 0)); 131} 132 133int 134devctl_rescan(const char *device) 135{ 136 137 return (devctl_simple_request(DEV_RESCAN, device, 0)); 138} 139 140int 141devctl_delete(const char *device, bool force) 142{ 143 144 return (devctl_simple_request(DEV_DELETE, device, force ? 145 DEVF_FORCE_DELETE : 0)); 146} 147 148int 149devctl_reset(const char *device, bool detach) 150{ 151 152 return (devctl_simple_request(DEV_RESET, device, detach ? 153 DEVF_RESET_DETACH : 0)); 154} 155