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.device-id 2009-02-20 00:36:44.000000000 +0000 +++ hplip-3.9.2/io/hpmud/musb.c 2009-07-23 18:15:12.923895944 +0100 @@ -26,6 +26,11 @@ #include "hpmud.h" #include "hpmudi.h" +#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE 1 +#include + +/* Flags for claim_interface() */ +#define CLAIM_NO_DETACH 1 mud_device_vf __attribute__ ((visibility ("hidden"))) musb_mud_device_vf = { @@ -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. */ +static void +get_device_id (struct usb_device *dev, const char *serial, + char *id, size_t len) +{ + int try_usblp = 0; + int fd; + + *id = '\0'; + if (dev->descriptor.idVendor != 0x3f0) + return; + + libusb_device = dev; + fd = claim_id_interface (dev, CLAIM_NO_DETACH); + if (fd == FD_NA) + { + try_usblp = 1; + goto try_usblp_instead; + } + + if (device_id (fd, id, len) == 0) + try_usblp = 1; + + release_interface (&fd_table[fd]); + + try_usblp_instead: + if (try_usblp) + { + struct udev *udev = udev_new (); + struct udev_enumerate *en = udev_enumerate_new (udev); + struct udev_list_entry *list, *each; + udev_enumerate_add_match_subsystem (en, "usb"); + udev_enumerate_add_match_sysattr (en, "bInterfaceClass", "07"); + udev_enumerate_add_match_sysattr (en, "bInterfaceSubClass", "01"); + udev_enumerate_scan_devices (en); + list = udev_enumerate_get_list_entry (en); + udev_list_entry_foreach (each, list) + { + const char *syspath = udev_list_entry_get_name (each); + struct udev_device *parent_dev, *ddev; + const char *ieee1284_id; + const char *idVendor; + const char *idProductStr; + const char *serialstr; + unsigned long idProduct; + ddev = udev_device_new_from_syspath (udev, syspath); + parent_dev = + udev_device_get_parent_with_subsystem_devtype (ddev, + "usb", + "usb_device"); + if (!parent_dev) + continue; + + idVendor = udev_device_get_sysattr_value (parent_dev, + "idVendor"); + if (!idVendor || strcmp (idVendor, "03f0")) + continue; + + idProductStr = udev_device_get_sysattr_value (parent_dev, + "idProduct"); + if (!idProductStr || + strtoul (idProductStr, NULL, 16) != + dev->descriptor.idProduct) + continue; + + serialstr = udev_device_get_sysattr_value (parent_dev, + "serial"); + if (!serialstr || strcmp (serialstr, serial)) + continue; + + ieee1284_id = udev_device_get_sysattr_value (ddev, + "ieee1284_id"); + if (!ieee1284_id) + continue; + + strncpy (id, ieee1284_id, len); + id[len - 1] = '\0'; + } + + udev_enumerate_unref (en); + udev_unref (udev); + } + + return; +} + int __attribute__ ((visibility ("hidden"))) musb_probe_devices(char *lst, int lst_size, int *cnt) { struct usb_bus *bus; @@ -2006,6 +2098,7 @@ int __attribute__ ((visibility ("hidden" if (model[0]) { + char device_id[1024]; snprintf(sz, sizeof(sz), "hp:/usb/%s?serial=%s", model, serial); /* See if device is supported by hplip. */ @@ -2016,17 +2109,19 @@ int __attribute__ ((visibility ("hidden" continue; /* ignor, not supported */ } - /* - * For Cups 1.2 we append a dummy deviceid. A valid deviceid would require us to claim the USB interface, thus removing usblp. - * This will allow us to do discovery and not disable other CUPS backend(s) who use /dev/usb/lpx instead of libusb. - */ - if (strncasecmp(rmodel, "hp ", 3) == 0) - size += snprintf(lst+size, lst_size-size, "direct %s \"HP %s\" \"HP %s USB %s HPLIP\" \"MFG:HP;MDL:%s;CLS:PRINTER;DES:%s;SN:%s;\"\n", - sz, &rmodel[3], &rmodel[3], serial, rmodel, rmodel, rserial); - else - size += snprintf(lst+size, lst_size-size, "direct %s \"HP %s\" \"HP %s USB %s HPLIP\" \"MFG:HP;MDL:%s;CLS:PRINTER;DES:%s;SN:%s;\"\n", - sz, rmodel, rmodel, serial, rmodel, rmodel, rserial); - + get_device_id (dev, rserial, device_id, sizeof (device_id)); + if (strncasecmp(rmodel, "hp ", 3) == 0) + size += snprintf(lst+size, lst_size-size, + "direct %s \"HP %s\" \"HP %s USB %s " + "HPLIP\" \"%s\"\n", + sz, &rmodel[3], &rmodel[3], serial, + device_id); + else + size += snprintf(lst+size, lst_size-size, + "direct %s \"HP %s\" \"HP %s USB %s " + "HPLIP\" \"%s\"\n", + sz, rmodel, rmodel, serial, + device_id); *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 2009-07-23 18:12:15.843895808 +0100 @@ -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/dot4.h io/hpmud/jd.c io/hpmud/jd.h io/hpmud/pp.c io/hpmud/pp.h if NETWORK_BUILD -libhpmud_la_LDFLAGS = -version-info 0:4:0 -lusb -lpthread -lnetsnmp -lcrypto +libhpmud_la_LDFLAGS = -version-info 0:4:0 -lusb -ludev -lpthread -lnetsnmp -lcrypto else -libhpmud_la_LDFLAGS = -version-info 0:4:0 -lusb -lpthread +libhpmud_la_LDFLAGS = -version-info 0:4:0 -lusb -ludev -lpthread endif 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 2009-07-23 18:12:15.850895526 +0100 @@ -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/dot4.h io/hpmud/jd.c io/hpmud/jd.h io/hpmud/pp.c io/hpmud/pp.h -@HPLIP_BUILD_TRUE@@NETWORK_BUILD_FALSE@libhpmud_la_LDFLAGS = -version-info 0:4:0 -lusb -lpthread -@HPLIP_BUILD_TRUE@@NETWORK_BUILD_TRUE@libhpmud_la_LDFLAGS = -version-info 0:4:0 -lusb -lpthread -lnetsnmp -lcrypto +@HPLIP_BUILD_TRUE@@NETWORK_BUILD_FALSE@libhpmud_la_LDFLAGS = -version-info 0:4:0 -lusb -ludev -lpthread +@HPLIP_BUILD_TRUE@@NETWORK_BUILD_TRUE@libhpmud_la_LDFLAGS = -version-info 0:4:0 -lusb -ludev -lpthread -lnetsnmp -lcrypto @HPLIP_BUILD_TRUE@libhpmud_la_CFLAGS = -DMUDNAME=\"$(MUDNAME)\" -DCONFDIR=\"$(hplip_confdir)\" # hpmudext