1 /* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */ 2 /* 3 * Linux usbfs backend for libusb 4 * Copyright (C) 2007-2009 Daniel Drake <dsd (at) gentoo.org> 5 * Copyright (c) 2001 Johannes Erdfelt <johannes (at) erdfelt.com> 6 * Copyright (c) 2012-2013 Nathan Hjelm <hjelmn (at) mac.com> 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 #include "config.h" 24 25 #include <assert.h> 26 #include <ctype.h> 27 #include <dirent.h> 28 #include <errno.h> 29 #include <fcntl.h> 30 #include <poll.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <sys/ioctl.h> 35 #include <sys/stat.h> 36 #include <sys/types.h> 37 #include <sys/utsname.h> 38 #include <sys/socket.h> 39 #include <unistd.h> 40 #include <libudev.h> 41 42 #include "libusb.h" 43 #include "libusbi.h" 44 #include "linux_usbfs.h" 45 46 /* udev context */ 47 static struct udev *udev_ctx = NULL; 48 static int udev_monitor_fd = -1; 49 static struct udev_monitor *udev_monitor = NULL; 50 static pthread_t linux_event_thread; 51 52 static void udev_hotplug_event(struct udev_device* udev_dev); 53 static void *linux_udev_event_thread_main(void *arg); 54 55 int linux_udev_start_event_monitor(void) 56 { 57 int r; 58 59 assert(udev_ctx == NULL); 60 udev_ctx = udev_new(); 61 if (!udev_ctx) { 62 usbi_err(NULL, "could not create udev context"); 63 return LIBUSB_ERROR_OTHER; 64 } 65 66 udev_monitor = udev_monitor_new_from_netlink(udev_ctx, "udev"); 67 if (!udev_monitor) { 68 usbi_err(NULL, "could not initialize udev monitor"); 69 goto err_free_ctx; 70 } 71 72 r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", 0); 73 if (r) { 74 usbi_err(NULL, "could not initialize udev monitor filter for \"usb\" subsystem"); 75 goto err_free_monitor; 76 } 77 78 if (udev_monitor_enable_receiving(udev_monitor)) { 79 usbi_err(NULL, "failed to enable the udev monitor"); 80 goto err_free_monitor; 81 } 82 83 udev_monitor_fd = udev_monitor_get_fd(udev_monitor); 84 85 /* Some older versions of udev are not non-blocking by default, 86 * so make sure this is set */ 87 r = fcntl(udev_monitor_fd, F_GETFL); 88 if (r == -1) { 89 usbi_err(NULL, "getting udev monitor fd flags (%d)", errno); 90 goto err_free_monitor; 91 } 92 r = fcntl(udev_monitor_fd, F_SETFL, r | O_NONBLOCK); 93 if (r) { 94 usbi_err(NULL, "setting udev monitor fd flags (%d)", errno); 95 goto err_free_monitor; 96 } 97 98 r = pthread_create(&linux_event_thread, NULL, linux_udev_event_thread_main, NULL); 99 if (r) { 100 usbi_err(NULL, "creating hotplug event thread (%d)", r); 101 goto err_free_monitor; 102 } 103 104 return LIBUSB_SUCCESS; 105 106 err_free_monitor: 107 udev_monitor_unref(udev_monitor); 108 udev_monitor = NULL; 109 udev_monitor_fd = -1; 110 err_free_ctx: 111 udev_unref(udev_ctx); 112 udev_ctx = NULL; 113 return LIBUSB_ERROR_OTHER; 114 } 115 116 int linux_udev_stop_event_monitor(void) 117 { 118 assert(udev_ctx != NULL); 119 assert(udev_monitor != NULL); 120 assert(udev_monitor_fd != -1); 121 122 /* Cancel the event thread. This is the only way to guarantee the 123 thread exits since closing the monitor fd won't necessarily cause 124 poll to return. */ 125 pthread_cancel(linux_event_thread); 126 pthread_join(linux_event_thread, NULL); 127 128 /* Release the udev monitor */ 129 udev_monitor_unref(udev_monitor); 130 udev_monitor = NULL; 131 udev_monitor_fd = -1; 132 133 /* Clean up the udev context */ 134 udev_unref(udev_ctx); 135 udev_ctx = NULL; 136 137 return LIBUSB_SUCCESS; 138 } 139 140 static void *linux_udev_event_thread_main(void *arg) 141 { 142 struct udev_device* udev_dev; 143 struct pollfd fds = {.fd = udev_monitor_fd, 144 .events = POLLIN}; 145 146 usbi_dbg("udev event thread entering."); 147 148 while (1 == poll(&fds, 1, -1)) { 149 if (NULL == udev_monitor || POLLIN != fds.revents) { 150 break; 151 } 152 153 usbi_mutex_static_lock(&linux_hotplug_lock); 154 udev_dev = udev_monitor_receive_device(udev_monitor); 155 if (udev_dev) 156 udev_hotplug_event(udev_dev); 157 usbi_mutex_static_unlock(&linux_hotplug_lock); 158 } 159 160 usbi_dbg("udev event thread exiting"); 161 162 return NULL; 163 } 164 165 static int udev_device_info(struct libusb_context *ctx, int detached, 166 struct udev_device *udev_dev, uint8_t *busnum, 167 uint8_t *devaddr, const char **sys_name) { 168 const char *dev_node; 169 170 dev_node = udev_device_get_devnode(udev_dev); 171 if (!dev_node) { 172 return LIBUSB_ERROR_OTHER; 173 } 174 175 *sys_name = udev_device_get_sysname(udev_dev); 176 if (!*sys_name) { 177 return LIBUSB_ERROR_OTHER; 178 } 179 180 return linux_get_device_address(ctx, detached, busnum, devaddr, 181 dev_node, *sys_name); 182 } 183 184 static void udev_hotplug_event(struct udev_device* udev_dev) 185 { 186 const char* udev_action; 187 const char* sys_name = NULL; 188 uint8_t busnum = 0, devaddr = 0; 189 int detached; 190 int r; 191 192 do { 193 udev_action = udev_device_get_action(udev_dev); 194 if (!udev_action) { 195 break; 196 } 197 198 detached = !strncmp(udev_action, "remove", 6); 199 200 r = udev_device_info(NULL, detached, udev_dev, &busnum, &devaddr, &sys_name); 201 if (LIBUSB_SUCCESS != r) { 202 break; 203 } 204 205 usbi_dbg("udev hotplug event. action: %s.", udev_action); 206 207 if (strncmp(udev_action, "add", 3) == 0) { 208 linux_hotplug_enumerate(busnum, devaddr, sys_name); 209 } else if (detached) { 210 linux_hotplug_disconnected(busnum, devaddr, sys_name); 211 } else { 212 usbi_err(NULL, "ignoring udev action %s", udev_action); 213 } 214 } while (0); 215 216 udev_device_unref(udev_dev); 217 } 218 219 int linux_udev_scan_devices(struct libusb_context *ctx) 220 { 221 struct udev_enumerate *enumerator; 222 struct udev_list_entry *devices, *entry; 223 struct udev_device *udev_dev; 224 const char *sys_name; 225 int r; 226 227 assert(udev_ctx != NULL); 228 229 enumerator = udev_enumerate_new(udev_ctx); 230 if (NULL == enumerator) { 231 usbi_err(ctx, "error creating udev enumerator"); 232 return LIBUSB_ERROR_OTHER; 233 } 234 235 udev_enumerate_add_match_subsystem(enumerator, "usb"); 236 udev_enumerate_scan_devices(enumerator); 237 devices = udev_enumerate_get_list_entry(enumerator); 238 239 udev_list_entry_foreach(entry, devices) { 240 const char *path = udev_list_entry_get_name(entry); 241 uint8_t busnum = 0, devaddr = 0; 242 243 udev_dev = udev_device_new_from_syspath(udev_ctx, path); 244 245 r = udev_device_info(ctx, 0, udev_dev, &busnum, &devaddr, &sys_name); 246 if (r) { 247 udev_device_unref(udev_dev); 248 continue; 249 } 250 251 linux_enumerate_device(ctx, busnum, devaddr, sys_name); 252 udev_device_unref(udev_dev); 253 } 254 255 udev_enumerate_unref(enumerator); 256 257 return LIBUSB_SUCCESS; 258 } 259 260 void linux_udev_hotplug_poll(void) 261 { 262 struct udev_device* udev_dev; 263 264 usbi_mutex_static_lock(&linux_hotplug_lock); 265 do { 266 udev_dev = udev_monitor_receive_device(udev_monitor); 267 if (udev_dev) { 268 usbi_dbg("Handling hotplug event from hotplug_poll"); 269 udev_hotplug_event(udev_dev); 270 } 271 } while (udev_dev); 272 usbi_mutex_static_unlock(&linux_hotplug_lock); 273 } 274