summaryrefslogtreecommitdiff
path: root/libgphoto2_port/usb
diff options
context:
space:
mode:
authorMarcus Meissner <marcus@jet.franken.de>2009-04-13 21:03:32 +0000
committerMarcus Meissner <marcus@jet.franken.de>2009-04-13 21:03:32 +0000
commit27c8a8ec3a35c2c60b39eb65c71500cfa7cefe08 (patch)
tree2bd87b7d5894ad4a449d60ff1052c659fc4457ae /libgphoto2_port/usb
parentab967a21992f0b705e63cc6e32d9991e5d8e7ebd (diff)
downloadlibgphoto2-27c8a8ec3a35c2c60b39eb65c71500cfa7cefe08.tar.gz
reattach usb kernel driver on close, if attached previously
git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@11984 67ed7778-7388-44ab-90cf-0a291f65f57c
Diffstat (limited to 'libgphoto2_port/usb')
-rw-r--r--libgphoto2_port/usb/libusb.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/libgphoto2_port/usb/libusb.c b/libgphoto2_port/usb/libusb.c
index be071d9a1..7eafe5194 100644
--- a/libgphoto2_port/usb/libusb.c
+++ b/libgphoto2_port/usb/libusb.c
@@ -66,6 +66,8 @@ struct _GPPortPrivateLibrary {
int config;
int interface;
int altsetting;
+
+ int detached;
};
GPPortType
@@ -262,6 +264,8 @@ gp_port_usb_open (GPPort *port)
ret = usb_detach_kernel_driver_np (port->pl->dh, port->settings.usb.interface);
if (ret < 0)
gp_port_set_error (port, _("Could not detach kernel driver '%s' of camera device."),name);
+ else
+ port->pl->detached = 1;
} else {
if (errno != ENODATA) /* ENODATA - just no driver there */
gp_port_set_error (port, _("Could not query kernel driver of device."));
@@ -308,6 +312,27 @@ gp_port_usb_close (GPPort *port)
}
}
#endif
+#if defined(LIBUSB_HAS_GET_DRIVER_NP) && defined(LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP) && defined(USBDEVFS_CONNECT)
+ if (port->pl->detached) {
+ char filename[PATH_MAX + 1];
+ int fd;
+
+ /* FIXME shouldn't be a fixed path to usb root */
+ snprintf(filename, sizeof(filename) - 1, "%s/%s/%s", "/dev/bus/usb", port->pl->d->bus->dirname, port->pl->d->filename);
+ fd = open(filename, O_RDWR);
+
+ if (fd >= 0) {
+ struct usbdevfs_ioctl command;
+ command.ifno = 0;
+ command.ioctl_code = USBDEVFS_CONNECT;
+ command.data = NULL;
+ if (ioctl(fd, USBDEVFS_IOCTL, &command))
+ gp_log (GP_LOG_DEBUG,"libusb","reattach kernel driver failed");
+ close(fd);
+ }
+ }
+#endif
+
if (usb_close (port->pl->dh) < 0) {
gp_port_set_error (port, _("Could not close USB port (%m)."));
return (GP_ERROR_IO);