diff options
author | Marcus Meissner <marcus@jet.franken.de> | 2013-05-05 19:23:49 +0000 |
---|---|---|
committer | Marcus Meissner <marcus@jet.franken.de> | 2013-05-05 19:23:49 +0000 |
commit | ad503062b162f25ff03cb82448b2880d3a2e2097 (patch) | |
tree | 547a8a4aa6121aeee21aa9e3c32b1bdf4a6abb47 /libgphoto2_port/usb | |
parent | 4ffd86d99c3e32253e6ce5252e6eb3ee95ca1f87 (diff) | |
download | libgphoto2-ad503062b162f25ff03cb82448b2880d3a2e2097.tar.gz |
also allow port open with just the info set
git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@14405 67ed7778-7388-44ab-90cf-0a291f65f57c
Diffstat (limited to 'libgphoto2_port/usb')
-rw-r--r-- | libgphoto2_port/usb/libusb.c | 112 |
1 files changed, 108 insertions, 4 deletions
diff --git a/libgphoto2_port/usb/libusb.c b/libgphoto2_port/usb/libusb.c index 14ac75455..96d43d75a 100644 --- a/libgphoto2_port/usb/libusb.c +++ b/libgphoto2_port/usb/libusb.c @@ -241,15 +241,22 @@ gp_port_usb_exit (GPPort *port) return (GP_OK); } +static int gp_port_usb_find_path_lib(GPPort *); + static int gp_port_usb_open (GPPort *port) { int ret; char name[64]; - gp_log (GP_LOG_DEBUG,"libusb","gp_port_usb_open()"); - if (!port || !port->pl->d) + gp_log (GP_LOG_DEBUG,"libusb","gp_port_usb_open(%p)", port); + if (!port) return GP_ERROR_BAD_PARAMETERS; + if (!port->pl->d) { + ret = gp_port_usb_find_path_lib(port); + if (!port->pl->d) + return GP_ERROR_BAD_PARAMETERS; + } /* * Open the device using the previous usb_handle returned by @@ -564,13 +571,15 @@ gp_port_usb_update (GPPort *port) if (!port) return GP_ERROR_BAD_PARAMETERS; - gp_log (GP_LOG_DEBUG, "libusb", "gp_port_usb_update(old int=%d, conf=%d, alt=%d), (new int=%d, conf=%d, alt=%d)", + gp_log (GP_LOG_DEBUG, "libusb", "gp_port_usb_update(old int=%d, conf=%d, alt=%d) port %s, (new int=%d, conf=%d, alt=%d), port %s", port->settings.usb.interface, port->settings.usb.config, port->settings.usb.altsetting, + port->settings.usb.port, port->settings_pending.usb.interface, port->settings_pending.usb.config, - port->settings_pending.usb.altsetting + port->settings_pending.usb.altsetting, + port->settings_pending.usb.port ); #if 0 @@ -845,6 +854,101 @@ gp_port_usb_find_device_lib(GPPort *port, int idvendor, int idproduct) return GP_ERROR_IO_USB_FIND; } +static int +gp_port_usb_find_path_lib(GPPort *port) +{ + struct usb_bus *bus; + struct usb_device *dev; + char *s; + char busname[64], devname[64]; + + if (!port) + return (GP_ERROR_BAD_PARAMETERS); + + s = strchr (port->settings.usb.port,':'); + busname[0] = devname[0] = '\0'; + if (!s || s[1] == '\0') { + /* generic usb: match ... can't do */ + return GP_ERROR_BAD_PARAMETERS; + } + if (s && (s[1] != '\0')) { /* usb:%d,%d */ + strncpy(busname,s+1,sizeof(busname)); + busname[sizeof(busname)-1] = '\0'; + + s = strchr(busname,','); + if (s) { + strncpy(devname, s+1,sizeof(devname)); + devname[sizeof(devname)-1] = '\0'; + *s = '\0'; + } else { + /* generic usb: match ... can't do */ + return GP_ERROR_BAD_PARAMETERS; + } + } + for (bus = usb_busses; bus; bus = bus->next) { + if (strcmp(busname, bus->dirname)) + continue; + + for (dev = bus->devices; dev; dev = dev->next) { + int config = -1, interface = -1, altsetting = -1; + + if ((dev->filename != strstr(dev->filename, devname))) + continue; + + port->pl->d = dev; + + gp_log (GP_LOG_VERBOSE, "libusb", "Found device for path %s", port->settings.usb.port); + + /* Use the first config, interface and altsetting we find */ + gp_port_usb_find_first_altsetting(dev, &config, &interface, &altsetting); + + /* Set the defaults */ + if (dev->config) { + int i; + + port->settings.usb.config = dev->config[config].bConfigurationValue; + port->settings.usb.interface = dev->config[config].interface[interface].altsetting[altsetting].bInterfaceNumber; + port->settings.usb.altsetting = dev->config[config].interface[interface].altsetting[altsetting].bAlternateSetting; + + port->settings.usb.inep = gp_port_usb_find_ep(dev, config, interface, altsetting, USB_ENDPOINT_IN, USB_ENDPOINT_TYPE_BULK); + port->settings.usb.outep = gp_port_usb_find_ep(dev, config, interface, altsetting, USB_ENDPOINT_OUT, USB_ENDPOINT_TYPE_BULK); + port->settings.usb.intep = gp_port_usb_find_ep(dev, config, interface, altsetting, USB_ENDPOINT_IN, USB_ENDPOINT_TYPE_INTERRUPT); + + port->settings.usb.maxpacketsize = 0; + gp_log (GP_LOG_DEBUG, "libusb", "inep to look for is %02x", port->settings.usb.inep); + for (i=0;i<dev->config[config].interface[interface].altsetting[altsetting].bNumEndpoints;i++) { + if (port->settings.usb.inep == dev->config[config].interface[interface].altsetting[altsetting].endpoint[i].bEndpointAddress) { + port->settings.usb.maxpacketsize = dev->config[config].interface[interface].altsetting[altsetting].endpoint[i].wMaxPacketSize; + break; + } + } + gp_log (GP_LOG_VERBOSE, "libusb", + "Detected defaults: config %d, " + "interface %d, altsetting %d, " + "inep %02x, outep %02x, intep %02x, " + "class %02x, subclass %02x", + port->settings.usb.config, + port->settings.usb.interface, + port->settings.usb.altsetting, + port->settings.usb.inep, + port->settings.usb.outep, + port->settings.usb.intep, + dev->config[config].interface[interface].altsetting[altsetting].bInterfaceClass, + dev->config[config].interface[interface].altsetting[altsetting].bInterfaceSubClass + ); + } + return GP_OK; + } + } + +#if 0 + gp_port_set_error (port, _("Could not find USB device " + "(vendor 0x%x, product 0x%x). Make sure this device " + "is connected to the computer."), idvendor, idproduct); +#endif + return GP_ERROR_IO_USB_FIND; +} + /* This function reads the Microsoft OS Descriptor and looks inside to * find if it is a MTP device. This is the similar to the way that * Windows Media Player 10 uses. |