- Use existing libusb-using routines to try fetching Device ID.

This commit is contained in:
Tim Waugh 2009-07-23 17:30:37 +00:00
parent ea304cd7d4
commit e0f9c78587
2 changed files with 183 additions and 125 deletions

View File

@ -1,151 +1,204 @@
--- hplip-3.9.2/io/hpmud/musb.c 2009-07-21 23:43:07.016138839 +0100 diff -up hplip-3.9.2/io/hpmud/musb.c.device-id hplip-3.9.2/io/hpmud/musb.c
+++ hplip-3.9.2/io/hpmud/musb.c 2009-07-23 11:04:59.504163043 +0100 --- hplip-3.9.2/io/hpmud/musb.c.device-id 2009-02-20 00:36:44.000000000 +0000
@@ -26,6 +26,8 @@ +++ hplip-3.9.2/io/hpmud/musb.c 2009-07-23 18:15:12.923895944 +0100
@@ -26,6 +26,11 @@
#include "hpmud.h" #include "hpmud.h"
#include "hpmudi.h" #include "hpmudi.h"
+#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE 1 +#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE 1
+#include <libudev.h> +#include <libudev.h>
+
+/* Flags for claim_interface() */
+#define CLAIM_NO_DETACH 1
mud_device_vf __attribute__ ((visibility ("hidden"))) musb_mud_device_vf = mud_device_vf __attribute__ ((visibility ("hidden"))) musb_mud_device_vf =
{ {
@@ -1959,6 +1961,143 @@ @@ -488,7 +493,8 @@ bugout:
return -1; /* no endpoint found */
}
-static int claim_interface(struct usb_device *dev, file_descriptor *pfd)
+static int claim_interface(struct usb_device *dev, file_descriptor *pfd,
+ int flags)
{
int stat=1;
@@ -501,7 +507,8 @@ static int claim_interface(struct usb_de
goto bugout;
}
- detach(pfd->hd, pfd->interface);
+ if (!(flags & CLAIM_NO_DETACH))
+ detach(pfd->hd, pfd->interface);
#if 0 /* hp devices only have one configuration, so far ... */
if (usb_set_configuration(FD[fd].pHD, dev->config[config].bConfigurationValue))
@@ -561,7 +568,7 @@ static int release_interface(file_descri
}
/* Claim any open interface which is valid for device_id and device status. */
-static int claim_id_interface(struct usb_device *dev)
+static int claim_id_interface(struct usb_device *dev, int flags)
{
int fd[] = {FD_7_1_2, FD_7_1_3, FD_ff_ff_ff, FD_ff_d4_0, FD_ff_1_1, FD_ff_2_1, FD_NA};
int i;
@@ -570,7 +577,7 @@ static int claim_id_interface(struct usb
{
if (get_interface(dev, fd[i], &fd_table[fd[i]]) == 0)
{
- if (claim_interface(libusb_device, &fd_table[fd[i]]))
+ if (claim_interface(libusb_device, &fd_table[fd[i]], flags))
continue; /* interface is busy, try next interface */
break; /* done */
}
@@ -1111,7 +1118,7 @@ enum HPMUD_RESULT __attribute__ ((visibi
{
/* First client. */
- if ((fd = claim_id_interface(libusb_device)) == FD_NA)
+ if ((fd = claim_id_interface(libusb_device, 0)) == FD_NA)
{
stat = HPMUD_R_DEVICE_BUSY;
goto blackout;
@@ -1186,7 +1193,7 @@ enum HPMUD_RESULT __attribute__ ((visibi
if (fd == FD_NA)
{
/* Device not in use. Claim interface, but release for other processes. */
- if ((fd = claim_id_interface(libusb_device)) != FD_NA)
+ if ((fd = claim_id_interface(libusb_device, 0)) != FD_NA)
{
*len = device_id(fd, pd->id, sizeof(pd->id)); /* get new copy and cache it */
release_interface(&fd_table[fd]);
@@ -1236,7 +1243,7 @@ enum HPMUD_RESULT __attribute__ ((visibi
if (fd == FD_NA)
{
/* Device not in use. Claim interface, but release for other processes. */
- if ((fd = claim_id_interface(libusb_device)) != FD_NA)
+ if ((fd = claim_id_interface(libusb_device, 0)) != FD_NA)
{
r = device_status(fd, status);
release_interface(&fd_table[fd]);
@@ -1339,7 +1346,7 @@ enum HPMUD_RESULT __attribute__ ((visibi
int fd = FD_7_1_2;
enum HPMUD_RESULT stat = HPMUD_R_DEVICE_BUSY;
- if (claim_interface(libusb_device, &fd_table[fd]))
+ if (claim_interface(libusb_device, &fd_table[fd], 0))
goto bugout;
pc->fd = fd;
@@ -1470,7 +1477,7 @@ enum HPMUD_RESULT __attribute__ ((visibi
goto bugout;
}
- if (claim_interface(libusb_device, &fd_table[fd]))
+ if (claim_interface(libusb_device, &fd_table[fd], 0))
goto bugout;
pc->fd = fd;
@@ -1504,7 +1511,7 @@ enum HPMUD_RESULT __attribute__ ((visibi
else
fd = FD_7_1_2; /* raw, mlc, dot4 */
- if (claim_interface(libusb_device, &fd_table[fd]))
+ if (claim_interface(libusb_device, &fd_table[fd], 0))
{
stat = HPMUD_R_DEVICE_BUSY;
goto bugout;
@@ -1726,7 +1733,7 @@ enum HPMUD_RESULT __attribute__ ((visibi
else
fd = FD_7_1_2; /* raw, mlc, dot4 */
- if (claim_interface(libusb_device, &fd_table[fd]))
+ if (claim_interface(libusb_device, &fd_table[fd], 0))
{
stat = HPMUD_R_DEVICE_BUSY;
goto bugout;
@@ -1959,6 +1966,91 @@ bugout:
* USB probe devices, walk the USB bus(s) looking for HP products. * USB probe devices, walk the USB bus(s) looking for HP products.
*/ */
+static void +static void
+get_device_id (struct usb_device *dev, const char *serial, +get_device_id (struct usb_device *dev, const char *serial,
+ char *device_id, size_t len) + char *id, size_t len)
+{ +{
+ struct usb_config_descriptor *confptr;
+ int try_usblp = 0; + int try_usblp = 0;
+ int conf; + int fd;
+ +
+ *device_id = '\0'; + *id = '\0';
+ if (dev->descriptor.idVendor != 0x3f0) + if (dev->descriptor.idVendor != 0x3f0)
+ return; + return;
+ +
+ for (conf = 0, confptr = dev->config; + libusb_device = dev;
+ conf < dev->descriptor.bNumConfigurations; + fd = claim_id_interface (dev, CLAIM_NO_DETACH);
+ conf++, confptr++) + if (fd == FD_NA)
+ { + {
+ struct usb_interface *ifaceptr; + try_usblp = 1;
+ int iface = 0; + goto try_usblp_instead;
+ for (ifaceptr = confptr->interface; + }
+ iface < confptr->bNumInterfaces;
+ iface++, ifaceptr++)
+ {
+ struct usb_interface_descriptor *altptr;
+ int altset = 0;
+ for (altptr = ifaceptr->altsetting;
+ altset < ifaceptr->num_altsetting;
+ altset++, altptr++)
+ {
+ if (altptr->bInterfaceClass == USB_CLASS_PRINTER &&
+ altptr->bInterfaceSubClass == 1)
+ {
+ int n;
+ struct usb_dev_handle *hd;
+ +
+ if ((hd = usb_open (dev)) == NULL) + if (device_id (fd, id, len) == 0)
+ continue; + try_usblp = 1;
+ +
+ n = confptr->bConfigurationValue; + release_interface (&fd_table[fd]);
+ if (usb_set_configuration (hd, n) < 0)
+ goto try_usblp_instead;
+ +
+ n = altptr->bInterfaceNumber; + try_usblp_instead:
+ if (usb_claim_interface (hd, n) < 0)
+ goto try_usblp_instead;
+
+ n = altptr->bAlternateSetting;
+ if (usb_set_altinterface (hd, n) < 0)
+ goto try_usblp_instead;
+
+ memset (device_id, '\0',
+ sizeof (device_id));
+ if (usb_control_msg (hd,
+ USB_TYPE_CLASS |
+ USB_ENDPOINT_IN |
+ USB_RECIP_INTERFACE,
+ 0, conf, iface,
+ device_id, len,
+ 5000) < 0)
+ goto try_usblp_instead;
+
+ usb_close (hd);
+ memmove (device_id, device_id + 2,
+ len - 2);
+ device_id[len - 2] = '\0';
+ device_id[len - 1] = '\0';
+ return;
+
+ try_usblp_instead:
+ usb_close (hd);
+ try_usblp = 1;
+ goto out;
+ }
+ }
+ }
+ }
+
+ out:
+ if (try_usblp) + if (try_usblp)
+ { + {
+ struct udev *udev = udev_new (); + struct udev *udev = udev_new ();
+ struct udev_enumerate *en = udev_enumerate_new (udev); + struct udev_enumerate *en = udev_enumerate_new (udev);
+ struct udev_list_entry *list, *each; + struct udev_list_entry *list, *each;
+ udev_enumerate_add_match_subsystem (en, "usb"); + udev_enumerate_add_match_subsystem (en, "usb");
+ udev_enumerate_add_match_sysattr (en, "bInterfaceClass", "07"); + udev_enumerate_add_match_sysattr (en, "bInterfaceClass", "07");
+ udev_enumerate_add_match_sysattr (en, "bInterfaceSubClass", "01"); + udev_enumerate_add_match_sysattr (en, "bInterfaceSubClass", "01");
+ udev_enumerate_scan_devices (en); + udev_enumerate_scan_devices (en);
+ list = udev_enumerate_get_list_entry (en); + list = udev_enumerate_get_list_entry (en);
+ udev_list_entry_foreach (each, list) + udev_list_entry_foreach (each, list)
+ { + {
+ const char *syspath = udev_list_entry_get_name (each); + const char *syspath = udev_list_entry_get_name (each);
+ struct udev_device *parent_dev, *ddev; + struct udev_device *parent_dev, *ddev;
+ const char *ieee1284_id; + const char *ieee1284_id;
+ const char *idVendor; + const char *idVendor;
+ const char *idProductStr; + const char *idProductStr;
+ const char *serialstr; + const char *serialstr;
+ unsigned long idProduct; + unsigned long idProduct;
+ ddev = udev_device_new_from_syspath (udev, syspath); + ddev = udev_device_new_from_syspath (udev, syspath);
+ parent_dev = + parent_dev =
+ udev_device_get_parent_with_subsystem_devtype (ddev, + udev_device_get_parent_with_subsystem_devtype (ddev,
+ "usb", + "usb",
+ "usb_device"); + "usb_device");
+ if (!parent_dev) + if (!parent_dev)
+ continue; + continue;
+ +
+ idVendor = udev_device_get_sysattr_value (parent_dev, + idVendor = udev_device_get_sysattr_value (parent_dev,
+ "idVendor"); + "idVendor");
+ if (!idVendor || strcmp (idVendor, "03f0")) + if (!idVendor || strcmp (idVendor, "03f0"))
+ continue; + continue;
+ +
+ idProductStr = udev_device_get_sysattr_value (parent_dev, + idProductStr = udev_device_get_sysattr_value (parent_dev,
+ "idProduct"); + "idProduct");
+ if (!idProductStr || + if (!idProductStr ||
+ strtoul (idProductStr, NULL, 16) != + strtoul (idProductStr, NULL, 16) !=
+ dev->descriptor.idProduct) + dev->descriptor.idProduct)
+ continue; + continue;
+ +
+ serialstr = udev_device_get_sysattr_value (parent_dev, + serialstr = udev_device_get_sysattr_value (parent_dev,
+ "serial"); + "serial");
+ if (!serialstr || strcmp (serialstr, serial)) + if (!serialstr || strcmp (serialstr, serial))
+ continue; + continue;
+ +
+ ieee1284_id = udev_device_get_sysattr_value (ddev, + ieee1284_id = udev_device_get_sysattr_value (ddev,
+ "ieee1284_id"); + "ieee1284_id");
+ if (!ieee1284_id) + if (!ieee1284_id)
+ continue; + continue;
+ +
+ strncpy (device_id, ieee1284_id, len); + strncpy (id, ieee1284_id, len);
+ device_id[len - 1] = '\0'; + id[len - 1] = '\0';
+ } + }
+ +
+ udev_enumerate_unref (en); + udev_enumerate_unref (en);
+ udev_unref (udev); + udev_unref (udev);
+ } + }
+ +
+ return; + return;
+} +}
@ -153,7 +206,7 @@
int __attribute__ ((visibility ("hidden"))) musb_probe_devices(char *lst, int lst_size, int *cnt) int __attribute__ ((visibility ("hidden"))) musb_probe_devices(char *lst, int lst_size, int *cnt)
{ {
struct usb_bus *bus; struct usb_bus *bus;
@@ -2006,6 +2145,7 @@ @@ -2006,6 +2098,7 @@ int __attribute__ ((visibility ("hidden"
if (model[0]) if (model[0])
{ {
@ -161,7 +214,7 @@
snprintf(sz, sizeof(sz), "hp:/usb/%s?serial=%s", model, serial); snprintf(sz, sizeof(sz), "hp:/usb/%s?serial=%s", model, serial);
/* See if device is supported by hplip. */ /* See if device is supported by hplip. */
@@ -2016,17 +2156,19 @@ @@ -2016,17 +2109,19 @@ int __attribute__ ((visibility ("hidden"
continue; /* ignor, not supported */ continue; /* ignor, not supported */
} }
@ -192,8 +245,9 @@
*cnt+=1; *cnt+=1;
} }
} }
diff -up hplip-3.9.2/Makefile.am.device-id hplip-3.9.2/Makefile.am
--- hplip-3.9.2/Makefile.am.device-id 2009-02-20 00:36:58.000000000 +0000 --- hplip-3.9.2/Makefile.am.device-id 2009-02-20 00:36:58.000000000 +0000
+++ hplip-3.9.2/Makefile.am 2009-07-21 23:41:16.262138141 +0100 +++ hplip-3.9.2/Makefile.am 2009-07-23 18:12:15.843895808 +0100
@@ -218,9 +218,9 @@ libhpmud_la_SOURCES = io/hpmud/hpmud.c i @@ -218,9 +218,9 @@ libhpmud_la_SOURCES = io/hpmud/hpmud.c i
io/hpmud/hpmud.h io/hpmud/hpmudi.h io/hpmud/list.h io/hpmud/mlc.h io/hpmud/musb.h io/hpmud/pml.h io/hpmud/dot4.c \ io/hpmud/hpmud.h io/hpmud/hpmudi.h io/hpmud/list.h io/hpmud/mlc.h io/hpmud/musb.h io/hpmud/pml.h io/hpmud/dot4.c \
io/hpmud/dot4.h io/hpmud/jd.c io/hpmud/jd.h io/hpmud/pp.c io/hpmud/pp.h io/hpmud/dot4.h io/hpmud/jd.c io/hpmud/jd.h io/hpmud/pp.c io/hpmud/pp.h
@ -206,8 +260,9 @@
endif endif
libhpmud_la_CFLAGS = -DMUDNAME=\"$(MUDNAME)\" -DCONFDIR=\"$(hplip_confdir)\" libhpmud_la_CFLAGS = -DMUDNAME=\"$(MUDNAME)\" -DCONFDIR=\"$(hplip_confdir)\"
diff -up hplip-3.9.2/Makefile.in.device-id hplip-3.9.2/Makefile.in
--- hplip-3.9.2/Makefile.in.device-id 2009-02-20 00:37:52.000000000 +0000 --- hplip-3.9.2/Makefile.in.device-id 2009-02-20 00:37:52.000000000 +0000
+++ hplip-3.9.2/Makefile.in 2009-07-21 23:41:16.272138156 +0100 +++ hplip-3.9.2/Makefile.in 2009-07-23 18:12:15.850895526 +0100
@@ -3954,8 +3954,8 @@ dist_unrel_DATA = @@ -3954,8 +3954,8 @@ dist_unrel_DATA =
@HPLIP_BUILD_TRUE@ io/hpmud/hpmud.h io/hpmud/hpmudi.h io/hpmud/list.h io/hpmud/mlc.h io/hpmud/musb.h io/hpmud/pml.h io/hpmud/dot4.c \ @HPLIP_BUILD_TRUE@ io/hpmud/hpmud.h io/hpmud/hpmudi.h io/hpmud/list.h io/hpmud/mlc.h io/hpmud/musb.h io/hpmud/pml.h io/hpmud/dot4.c \
@HPLIP_BUILD_TRUE@ io/hpmud/dot4.h io/hpmud/jd.c io/hpmud/jd.h io/hpmud/pp.c io/hpmud/pp.h @HPLIP_BUILD_TRUE@ io/hpmud/dot4.h io/hpmud/jd.c io/hpmud/jd.h io/hpmud/pp.c io/hpmud/pp.h

View File

@ -1,7 +1,7 @@
Summary: HP Linux Imaging and Printing Project Summary: HP Linux Imaging and Printing Project
Name: hplip Name: hplip
Version: 3.9.2 Version: 3.9.2
Release: 7%{?dist} Release: 8%{?dist}
License: GPLv2+ and MIT License: GPLv2+ and MIT
Group: System Environment/Daemons Group: System Environment/Daemons
Conflicts: system-config-printer < 0.6.132 Conflicts: system-config-printer < 0.6.132
@ -336,6 +336,9 @@ fi
exit 0 exit 0
%changelog %changelog
* Thu Jul 23 2009 Tim Waugh <twaugh@redhat.com> 3.9.2-8
- Use existing libusb-using routines to try fetching Device ID.
* Thu Jul 23 2009 Tim Waugh <twaugh@redhat.com> 3.9.2-7 * Thu Jul 23 2009 Tim Waugh <twaugh@redhat.com> 3.9.2-7
- Error checking in the libudev device-id fallback code. - Error checking in the libudev device-id fallback code.