Some shapeups from Nicolas
diff --git a/src/libusb-glue.c b/src/libusb-glue.c
index 61ffdce..6b5c0b4 100644
--- a/src/libusb-glue.c
+++ b/src/libusb-glue.c
@@ -93,13 +93,13 @@
 // Local functions
 static struct usb_bus* init_usb();
 static void close_usb(PTP_USB* ptp_usb);
-static void find_interface_and_endpoints(struct usb_device *dev,
-					 uint8_t *interface,
-					 int* inep, 
-					 int* inep_maxpacket, 
-					 int* outep, 
-					 int* outep_maxpacket, 
-					 int* intep);
+static int find_interface_and_endpoints(struct usb_device *dev,
+					uint8_t *interface,
+					int* inep,
+					int* inep_maxpacket,
+					int* outep,
+					int* outep_maxpacket,
+					int* intep);
 static void clear_stall(PTP_USB* ptp_usb);
 static int init_ptp_usb (PTPParams* params, PTP_USB* ptp_usb, struct usb_device* dev);
 static short ptp_write_func (unsigned long,PTPDataHandler*,void *data,unsigned long*);
@@ -1307,20 +1307,20 @@
 		  printf("Reading in zero packet after header\n");
 #endif
                   zeroresult = USB_BULK_READ(ptp_usb->handle, ptp_usb->inep, &zerobyte, 0, ptp_usb->timeout);
-		  
+
 		  if (zeroresult != 0)
 		    printf("LIBMTP panic: unable to read in zero packet, response 0x%04x", zeroresult);
 		}
-		
+
 		/* Is that all of data? */
 		if (len+PTP_USB_BULK_HDR_LEN<=rlen) {
 		  break;
 		}
-		
+
 		ret = ptp_read_func(len - (rlen - PTP_USB_BULK_HDR_LEN),
 				    handler,
 				    params->data, &rlen, 1);
-		
+
 		if (ret!=PTP_RC_OK) {
 		  break;
 		}
@@ -1410,7 +1410,7 @@
 
 	memset(&usbevent,0,sizeof(usbevent));
 
-	if ((params==NULL) || (event==NULL)) 
+	if ((params==NULL) || (event==NULL))
 		return PTP_ERROR_BADPARAM;
 	ret = PTP_RC_OK;
 	switch(wait) {
@@ -1472,7 +1472,7 @@
 
 	htod16a(&buffer[0],PTP_EC_CancelTransaction);
 	htod32a(&buffer[2],transactionid);
-	ret = usb_control_msg(ptp_usb->handle, 
+	ret = usb_control_msg(ptp_usb->handle,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                               0x64, 0x0000, 0x0000, (char *) buffer, sizeof(buffer), ptp_usb->timeout);
 	if (ret < sizeof(buffer))
@@ -1483,7 +1483,7 @@
 static int init_ptp_usb (PTPParams* params, PTP_USB* ptp_usb, struct usb_device* dev)
 {
   usb_dev_handle *device_handle;
-  
+
   params->sendreq_func=ptp_usb_sendreq;
   params->senddata_func=ptp_usb_senddata;
   params->getresp_func=ptp_usb_getresp;
@@ -1496,9 +1496,9 @@
    * Change this the day we run into our first BE device (if ever).
    */
   params->byteorder = PTP_DL_LE;
-  
+
   ptp_usb->timeout = USB_TIMEOUT_DEFAULT;
-  
+
   if ((device_handle = usb_open(dev))){
     if (!device_handle) {
       perror("usb_open()");
@@ -1529,6 +1529,14 @@
       perror("usb_claim_interface()");
       return -1;
     }
+    // FIXME : Discovered in the Barry project
+    // kernels >= 2.6.28 don't set the interface the same way as
+    // previous versions did, and the Blackberry gets confused
+    // if it isn't explicitly set
+    if (usb_set_altinterface(device_handle, 0)) {
+      perror("usb_set_altinterface()");
+      return -1;
+    }
   }
   return 0;
 }
@@ -1537,7 +1545,7 @@
 {
   uint16_t status;
   int ret;
-  
+
   /* check the inep status */
   status = 0;
   ret = usb_get_endpoint_status(ptp_usb,ptp_usb->inep,&status);
@@ -1550,7 +1558,7 @@
       perror ("usb_clear_stall_feature()");
     }
   }
-  
+
   /* check the outep status */
   status=0;
   ret = usb_get_endpoint_status(ptp_usb,ptp_usb->outep,&status);
@@ -1595,9 +1603,9 @@
      * On misbehaving devices designed for Windows/Mac, quote from:
      * http://www2.one-eyed-alien.net/~mdharm/linux-usb/target_offenses.txt
      * Device does Bad Things(tm) when it gets a GET_STATUS after CLEAR_HALT
-     * (...) Windows, when clearing a stall, only sends the CLEAR_HALT command, 
-     * and presumes that the stall has cleared.  Some devices actually choke 
-     * if the CLEAR_HALT is followed by a GET_STATUS (used to determine if the 
+     * (...) Windows, when clearing a stall, only sends the CLEAR_HALT command,
+     * and presumes that the stall has cleared.  Some devices actually choke
+     * if the CLEAR_HALT is followed by a GET_STATUS (used to determine if the
      * STALL is persistant or not).
      */
     clear_stall(ptp_usb);
@@ -1618,13 +1626,13 @@
 /**
  * Self-explanatory?
  */
-static void find_interface_and_endpoints(struct usb_device *dev, 
-					 uint8_t *interface,
-					 int* inep, 
-					 int* inep_maxpacket, 
-					 int* outep, 
-					 int *outep_maxpacket, 
-					 int* intep)
+static int find_interface_and_endpoints(struct usb_device *dev,
+					uint8_t *interface,
+					int* inep,
+					int* inep_maxpacket,
+					int* outep,
+					int *outep_maxpacket,
+					int* intep)
 {
   int i;
 
@@ -1632,22 +1640,26 @@
   for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
     uint8_t j;
 
+    // Loop over each configurations interfaces
     for (j = 0; j < dev->config[i].bNumInterfaces; j++) {
       uint8_t k;
       uint8_t no_ep;
+      int found_inep = 0;
+      int found_outep = 0;
+      int found_intep = 0;
       struct usb_endpoint_descriptor *ep;
-      
-      if (dev->descriptor.bNumConfigurations > 1 || dev->config[i].bNumInterfaces > 1) {
-	// OK This device has more than one interface, so we have to find out
-	// which one to use! 
-	// FIXME: Probe the interface.
-	// FIXME: Release modules attached to all other interfaces in Linux...?
-      }
+
+      // MTP devices shall have 3 endpoints, ignore those interfaces
+      // that haven't.
+      no_ep = dev->config[i].interface[j].altsetting->bNumEndpoints;
+      if (no_ep != 3)
+	continue;
 
       *interface = dev->config[i].interface[j].altsetting->bInterfaceNumber;
       ep = dev->config[i].interface[j].altsetting->endpoint;
-      no_ep = dev->config[i].interface[j].altsetting->bNumEndpoints;
-      
+
+      // Loop over the three endpoints to locate two bulk and
+      // one interrupt endpoint and FAIL if we cannot, and continue.
       for (k = 0; k < no_ep; k++) {
 	if (ep[k].bmAttributes==USB_ENDPOINT_TYPE_BULK)	{
 	  if ((ep[k].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==
@@ -1655,24 +1667,30 @@
 	    {
 	      *inep=ep[k].bEndpointAddress;
 	      *inep_maxpacket=ep[k].wMaxPacketSize;
+	      found_inep = 1;
 	    }
 	  if ((ep[k].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==0)
 	    {
 	      *outep=ep[k].bEndpointAddress;
 	      *outep_maxpacket=ep[k].wMaxPacketSize;
+	      found_outep = 1;
 	    }
 	} else if (ep[k].bmAttributes==USB_ENDPOINT_TYPE_INTERRUPT){
 	  if ((ep[k].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==
 	      USB_ENDPOINT_DIR_MASK)
 	    {
 	      *intep=ep[k].bEndpointAddress;
+	      found_intep = 1;
 	    }
 	}
       }
-      // We assigned the endpoints so return here.
-      return;
+      if (found_inep && found_outep && found_intep)
+	// We assigned the endpoints so return here.
+	return 0;
+      // Else loop to next interface/config
     }
   }
+  return -1;
 }
 
 /**
@@ -1691,6 +1709,7 @@
   uint16_t ret = 0;
   struct usb_bus *bus;
   int found = 0;
+  int err;
 
   /* See if we can find this raw device again... */
   bus = init_usb();
@@ -1735,39 +1754,44 @@
     // Massage the device descriptor
     (void) probe_device_descriptor(libusb_device, NULL);
   }
-  
-  /* Assign endpoints to usbinfo... */
-  find_interface_and_endpoints(libusb_device,
-		   &ptp_usb->interface,
-		   &ptp_usb->inep,
-		   &ptp_usb->inep_maxpacket,
-		   &ptp_usb->outep,
-		   &ptp_usb->outep_maxpacket,
-		   &ptp_usb->intep);
-    
+
+  /* Assign interface and endpoints to usbinfo... */
+  err = find_interface_and_endpoints(libusb_device,
+				     &ptp_usb->interface,
+				     &ptp_usb->inep,
+				     &ptp_usb->inep_maxpacket,
+				     &ptp_usb->outep,
+				     &ptp_usb->outep_maxpacket,
+				     &ptp_usb->intep);
+
+  if (err) {
+    fprintf(stderr, "LIBMTP PANIC: Unable to find interface & endpoints of device\n");
+    return LIBMTP_ERROR_CONNECTING;
+  }
+
   /* Attempt to initialize this device */
   if (init_ptp_usb(params, ptp_usb, libusb_device) < 0) {
     fprintf(stderr, "LIBMTP PANIC: Unable to initialize device\n");
     return LIBMTP_ERROR_CONNECTING;
   }
-  
+
   /*
    * This works in situations where previous bad applications
-   * have not used LIBMTP_Release_Device on exit 
+   * have not used LIBMTP_Release_Device on exit
    */
   if ((ret = ptp_opensession(params, 1)) == PTP_ERROR_IO) {
     fprintf(stderr, "PTP_ERROR_IO: Trying again after re-initializing USB interface\n");
     close_usb(ptp_usb);
-      
+
     if(init_ptp_usb(params, ptp_usb, libusb_device) <0) {
       fprintf(stderr, "LIBMTP PANIC: Could not open session on device\n");
       return LIBMTP_ERROR_CONNECTING;
     }
-    
+
     /* Device has been reset, try again */
     ret = ptp_opensession(params, 1);
   }
-  
+
   /* Was the transaction id invalid? Try again */
   if (ret == PTP_RC_InvalidTransactionID) {
     fprintf(stderr, "LIBMTP WARNING: Transaction ID was invalid, increment and try again\n");
@@ -1809,7 +1833,6 @@
 
 static int usb_clear_stall_feature(PTP_USB* ptp_usb, int ep)
 {
-  
   return (usb_control_msg(ptp_usb->handle,
 			  USB_RECIP_ENDPOINT, USB_REQ_CLEAR_FEATURE, USB_FEATURE_HALT,
                           ep, NULL, 0, ptp_usb->timeout));