On Tue, March 27, 2012 8:48 am, Manu Gautam wrote: > > From: Mike Lockwood <lockwood@xxxxxxxxxxx> > > +static int mass_storage_function_init(struct android_usb_function *f, > + struct usb_composite_dev *cdev) > +{ > + struct fsg_config fsg; > + struct fsg_common *common; > + int err; > + > + memset(&fsg, 0, sizeof fsg); > + fsg.nluns = 1; > + fsg.luns[0].removable = 1; > + > + common = fsg_common_init(NULL, cdev, &fsg); > + if (IS_ERR(common)) > + return PTR_ERR(common); > + > + err = sysfs_create_link(&f->dev->kobj, > + &common->luns[0].dev.kobj, > + "lun"); > + if (err) { > + fsg_common_put(common); > + return err; > + } > + > + f->config = common; > + return 0; > +} > + > +static void mass_storage_function_cleanup(struct android_usb_function *f) > +{ > + fsg_common_put(f->config); > + kfree(f->config); I think f->config is not allocated anywhere. Please correct me otherwise. > +static ssize_t enable_store(struct device *pdev, struct device_attribute > *attr, > + const char *buff, size_t size) > +{ > + struct android_dev *dev = dev_get_drvdata(pdev); > + struct usb_composite_dev *cdev = dev->cdev; > + int enabled = 0; > + > + mutex_lock(&dev->mutex); > + > + sscanf(buff, "%d", &enabled); > + if (enabled && !dev->enabled) { > + cdev->next_string_id = 0; > + /* > + * Update values in composite driver's copy of > + * device descriptor. > + */ > + cdev->desc.idVendor = device_desc.idVendor; > + cdev->desc.idProduct = device_desc.idProduct; > + cdev->desc.bcdDevice = device_desc.bcdDevice; > + cdev->desc.bDeviceClass = device_desc.bDeviceClass; > + cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass; > + cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol; > + > + usb_add_config(cdev, &android_config_driver, > + android_bind_config); > + usb_gadget_connect(cdev->gadget); This may fail. After this failure subsequent usb_remove_config call, as part of disable, goes unchecked which could be problematic. > +static int __init init(void) > +{ > + struct android_dev *dev; > + int err; > + > + android_class = class_create(THIS_MODULE, "android_usb"); > + if (IS_ERR(android_class)) > + return PTR_ERR(android_class); > + > + dev = kzalloc(sizeof(*dev), GFP_KERNEL); > + if (!dev) > + return -ENOMEM; > + > + dev->functions = supported_functions; > + INIT_LIST_HEAD(&dev->enabled_functions); > + INIT_WORK(&dev->work, android_work); > + mutex_init(&dev->mutex); > + > + err = android_create_device(dev); > + if (err) { > + class_destroy(android_class); > + kfree(dev); > + return err; > + } > + > + _android_dev = dev; > + > + /* Override composite driver functions */ > + composite_driver.setup = android_setup; > + composite_driver.disconnect = android_disconnect; > + > + return usb_composite_probe(&android_usb_driver, android_bind); usb_composite_probe might fail. In that case we should do the cleanup. > +} > +module_init(init); > + > +static void __exit cleanup(void) > +{ > + usb_composite_unregister(&android_usb_driver); > + class_destroy(android_class); > + kfree(_android_dev); > + _android_dev = NULL; > +} > +module_exit(cleanup); > -- > 1.7.0.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-usb" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- Sent by an employee of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html