Bug 176333

Summary: Cannot use second USB printer
Product: [Fedora] Fedora Reporter: David Woodhouse <dwmw2>
Component: kernelAssignee: Pete Zaitcev <zaitcev>
Status: CLOSED ERRATA QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 4CC: davej, wtogami
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2006-03-04 18:40:27 EST Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Description David Woodhouse 2005-12-21 10:36:02 EST
When I connect a second USB printer, a device node /dev/usb/lp1 appears.
However, anything sent to that device appears on the _first_ printer (as does
anything sent to /dev/usb/lp0). The device node for lp1 appears to be correct (c
 180 1)

I see this in dmesg when I connect the second printer:

usb 1-1.1.1: new full speed USB device using ehci_hcd and address 12
drivers/usb/class/usblp.c: usblp0: USB Bidirectional printer dev 12 if 0 alt 0
proto 2 vid 0x04B8 pid 0x0005

When I disconnect it, I see this:

usb 1-1.1.1: USB disconnect, address 12
drivers/usb/class/usblp.c: usblp1: removed
Comment 1 David Woodhouse 2005-12-21 12:51:02 EST
This is the simple fix. The better fix is to take whoever wrote
usb_find_interface() out back and shoot them. With a blunt gun.

--- drivers/usb/core/usb.c~     2005-12-19 00:57:23.000000000 +0000
+++ drivers/usb/core/usb.c      2005-12-21 17:49:58.000000000 +0000
@@ -488,7 +488,7 @@ static int __find_interface(struct devic
 {
        struct usb_interface ** ret = (struct usb_interface **)data;
        struct usb_interface * intf = *ret;
-       int *minor = (int *)data;
+       long *minor = (long *)data;

        /* can't look at usb devices, only interfaces */
        if (dev->driver == &usb_generic_driver)
Comment 2 Pete Zaitcev 2005-12-21 14:23:05 EST
What a horrible shit. Written by Pat Mochel, no less.
Please try this instead:

--- linux-2.6.14/drivers/usb/core/usb.c	2005-10-28 19:12:01.000000000 -0700
+++ linux-2.6.14-lem/drivers/usb/core/usb.c	2005-12-21 11:19:00.000000000 -0800
@@ -478,20 +477,23 @@ usb_match_id(struct usb_interface *inter
 	return NULL;
 }
 
+struct find_interface_arg {
+	int minor;
+	struct usb_interface *interface;
+};
 
 static int __find_interface(struct device * dev, void * data)
 {
-	struct usb_interface ** ret = (struct usb_interface **)data;
-	struct usb_interface * intf = *ret;
-	int *minor = (int *)data;
+	struct find_interface_arg *arg = data;
+	struct usb_interface *intf;
 
 	/* can't look at usb devices, only interfaces */
 	if (dev->driver == &usb_generic_driver)
 		return 0;
 
 	intf = to_usb_interface(dev);
-	if (intf->minor != -1 && intf->minor == *minor) {
-		*ret = intf;
+	if (intf->minor != -1 && intf->minor == arg->minor) {
+		arg->interface = intf;
 		return 1;
 	}
 	return 0;
@@ -508,12 +510,12 @@ static int __find_interface(struct devic
  */
 struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
 {
-	struct usb_interface *intf = (struct usb_interface *)(long)minor;
-	int ret;
-
-	ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface);
+	struct find_interface_arg argb;
 
-	return ret ? intf : NULL;
+	argb.minor = minor;
+	argb.interface = NULL;
+	driver_for_each_device(&drv->driver, NULL, &argb, __find_interface);
+	return argb.interface;
 }
 
 static int usb_device_match (struct device *dev, struct device_driver *drv)
Comment 3 David Woodhouse 2005-12-21 19:54:21 EST
Your patch works for me; thanks. 
Comment 4 Dave Jones 2006-02-03 01:50:22 EST
This is a mass-update to all currently open kernel bugs.

A new kernel update has been released (Version: 2.6.15-1.1830_FC4)
based upon a new upstream kernel release.

Please retest against this new kernel, as a large number of patches
go into each upstream release, possibly including changes that
may address this problem.

This bug has been placed in NEEDINFO_REPORTER state.
Due to the large volume of inactive bugs in bugzilla, if this bug is
still in this state in two weeks time, it will be closed.

Should this bug still be relevant after this period, the reporter
can reopen the bug at any time. Any other users on the Cc: list
of this bug can request that the bug be reopened by adding a
comment to the bug.

If this bug is a problem preventing you from installing the
release this version is filed against, please see bug 169613.

Thank you.
Comment 5 David Woodhouse 2006-02-20 06:01:38 EST
This is fixed in FC5, but I believe not yet in FC4. It is, however, already
committed to the FC4 kernel tree and will be in the next erratum.