Hi, Below is a patch with the following changes to the berry_charge.c module:
1) kzalloc() is called, but memory is never freed Is this a memory leak? I'm not sure, but the buffer is only a dummy buffer to hold return data that is never used, so I suspect a stack variable will suffice. 2) Added pearl mode change Blackberry Pearls start out with a Product ID of 0006, and in this mode, only a usb mass storage configuration is available. This patch sends the required command to change it from 0006 to 0004, in which both mass storage and the Blackberry database configuration are available. Also, Pearls need to be reset explicitly before the power change takes effect. 3) Added a sleep() for slow devices. My kernel-fu is not up to speed, so I'm sure this is the wrong fix, and I hope someone recommends the proper one. Older devices, such as the 7750, are slow to reset, and this creates the possibility of the kernel going into an endless loop, detecting the device and trying to set the power. The devices, in some cases of my testing, never actually changed to 500mA, but the kernel was extremely busy trying to do so, and the entire USB subsystem seemed to lock up (lsusb would freeze, for example). On my system, the sleep gives the device a chance to change to 500mA, which prevents the endless loop. - Chris --- linux-2.6.21.1/drivers/usb/misc/berry_charge.c 2007-04-27 17:49:26.000000000 -0400 +++ ../linux-2.6.21.1/drivers/usb/misc/berry_charge.c 2007-05-17 14:56:07.000000000 -0400 @@ -26,6 +26,8 @@ #define RIM_VENDOR 0x0fca #define BLACKBERRY 0x0001 +#define PEARL_DUAL 0x0004 +#define PEARL 0x0006 static int debug; @@ -36,15 +38,22 @@ if (debug) \ dev_printk(KERN_DEBUG , dev , format , ## arg) +/* We watch for product IDs 0001 and 0006, with the idea that + * for non-Pearl devices, we only change the charging setting, + * and for Pearl devices, we change the charge and the mode. + * If a Pearl shows up as 0004, we've already seen it and + * don't need to mess with it again. + */ static struct usb_device_id id_table [] = { { USB_DEVICE(RIM_VENDOR, BLACKBERRY) }, + { USB_DEVICE(RIM_VENDOR, PEARL) }, { }, /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, id_table); static int magic_charge(struct usb_device *udev) { - char *dummy_buffer = kzalloc(2, GFP_KERNEL); + char dummy_buffer[2]; int retval; if (!dummy_buffer) @@ -78,11 +87,22 @@ return retval; } - dbg(&udev->dev, "Calling set_configuration\n"); - retval = usb_driver_set_configuration(udev, 1); - if (retval) - dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); + return retval; +} +static int magic_pearl(struct usb_device *udev) +{ + char dummy_buffer[2]; + int retval; + + dbg(&udev->dev, "Sending magic Pearl command\n"); + retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + 0xa9, 0xc0, 1, 1, dummy_buffer, 2, 100); + if (retval != 0) { + dev_err(&udev->dev, "Pearl magic command failed: %d.\n", + retval); + return retval; + } return retval; } @@ -90,6 +110,9 @@ const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); + int retval; + +dbg(&udev->dev, "Dev module, version: 2\n"); dbg(&udev->dev, "Power is set to %dmA\n", udev->actconfig->desc.bMaxPower * 2); @@ -105,6 +128,28 @@ /* turn the power on */ magic_charge(udev); + /* change modes if device is a Pearl */ + if (udev->descriptor.idProduct == PEARL) + magic_pearl(udev); + + /* set configuration and reset to activate change */ + dbg(&udev->dev, "Calling set_configuration\n"); + retval = usb_driver_set_configuration(udev, 1); + if (retval) { + dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); + return retval; + } + + /* reset is required by the Pearl */ + retval = usb_reset_configuration(udev); + if (retval) { + dev_err(&udev->dev, "Configuration reset failed: %d.\n", retval); + return retval; + } + + /* give slower devices a chance to reset properly */ + ssleep(1); + /* we don't really want to bind to the device, userspace programs can * handle the syncing just fine, so get outta here. */ return -ENODEV; ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel