ports/58925: bug in *BSD port of libusb, with fix

Andreas Klemm andreas at klemm.apsfilter.org
Tue Nov 4 16:20:30 UTC 2003


>Number:         58925
>Category:       ports
>Synopsis:       bug in *BSD port of libusb, with fix
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 04 08:20:24 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Andreas Klemm
>Release:        FreeBSD-5.1
>Organization:
FreeBSD
>Environment:
System: FreeBSD titan.klemm.apsfilter.org 5.1-CURRENT FreeBSD 5.1-CURRENT #0: Sun Oct 19 16:33:53 CEST 2003 root at titan.klemm.apsfilter.org:/usr/src/sys/i386/compile/TITAN i386


	FreeBSD-current, but since its related to libusb, this bug
	and fix from Mariusz Woloszyn should apply to all FreeBSD versions.

>Description:

	Have a look at this bug report with fix:
	http://sourceforge.net/tracker/index.php?func=detail&aid=835645&group_id=1674&atid=101674
	Problem is:
	connect a canon powershot G5 to your USB port.
	You can talk to it in canon native mode perfectly.
	But not in ptp2 mode.

	Unfortunately the gphoto2 port autodetects ptp2 mode first.
	And in this ptp2 mode the camera locks up after transferring
	the first bytes.

	Workaround is to choose the canon native mode.
	But this surely doesn't fix libusb and if you have a 
	Camera that needs the ptp2 mode ....

	So libusb has definitively to be fixed for all BSD's.

	The fix removes the linux specific approach from *BSD code.
	The porter did his best, when reading the comments in the header ;-)
	But broke it when porting the code from Linux to bsd.

	You may ask: But why does the camera run in canon mode but not
	especially in ptp2 mode ?
	Answer: The canon driver uses an arbitrary large packets.
	PTP does not. PTP cannot determine the mmount of data that the
	device is going to send. That's why PTP calls are a read from
	an USB endpoint with a large number of bytes.

	Problems that remain after this fix are only Caono Firmware
	problems:
	After one ptp2 session the camera returns to canon native mode
	and stays in it!
	After a ptp2 session you have to powercycle the camera, to be able
	to talk in ptp2 mode again.
	Workaround: don't get listings, you may do -P or start
	a gphoto2 -shell and get listing, then get photos, etc 
	So to say: "do it all in ONE session".

>How-To-Repeat:
	Try to use camera in ptp2 mode. Chokes after 1st read.
	Use truss to find it out...:
	truss -o file gphoto2 -L --debug > & debug

>Fix:

--- bsd.c	Tue Nov  4 12:23:39 2003
+++ bsd-new.c	Tue Nov  4 12:23:21 2003
@@ -276,7 +276,7 @@
 int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
                    int timeout)
 {
-  int fd, ret, sent = 0;
+  int fd, ret;
 
   /* Ensure the endpoint address is correct */
   ep &= ~USB_ENDPOINT_IN;
@@ -298,8 +298,7 @@
     USB_ERROR_STR(ret, "error setting timeout: %s",
                   strerror(errno));
 
-  do {
-    ret = write(fd, bytes+sent, size-sent);
+    ret = write(fd, bytes, size);
     if (ret < 0)
 #if __FreeBSD__
       USB_ERROR_STR(ret, "error writing to bulk endpoint %s.%d: %s",
@@ -309,16 +308,13 @@
                   dev->device->filename, UE_GET_ADDR(ep), strerror(errno));
 #endif
 
-    sent += ret;
-  } while(ret > 0 && sent < size);
-
-  return sent;
+  return ret;
 }
 
 int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
                   int timeout)
 {
-  int fd, ret, retrieved = 0, one = 1;
+  int fd, ret, one = 1;
 
   /* Ensure the endpoint address is correct */
   ep |= USB_ENDPOINT_IN;
@@ -345,8 +341,7 @@
     USB_ERROR_STR(ret, "error setting short xfer: %s",
                   strerror(errno));
 
-  do {
-    ret = read(fd, bytes+retrieved, size-retrieved);
+    ret = read(fd, bytes, size);
     if (ret < 0)
 #if __FreeBSD__
       USB_ERROR_STR(ret, "error reading from bulk endpoint %s.%d: %s",
@@ -355,10 +350,8 @@
       USB_ERROR_STR(ret, "error reading from bulk endpoint %s.%02d: %s",
                   dev->device->filename, UE_GET_ADDR(ep), strerror(errno));
 #endif
-    retrieved += ret;
-  } while (ret > 0 && retrieved < size);
 
-  return retrieved;
+  return ret;
 }
 
 int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list