0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/device.h>
0010 #include <linux/list.h>
0011 #include <linux/module.h>
0012
0013 #include "vudc.h"
0014
0015 static unsigned int vudc_number = 1;
0016
0017 module_param_named(num, vudc_number, uint, S_IRUGO);
0018 MODULE_PARM_DESC(num, "number of emulated controllers");
0019
0020 static struct platform_driver vudc_driver = {
0021 .probe = vudc_probe,
0022 .remove = vudc_remove,
0023 .driver = {
0024 .name = GADGET_NAME,
0025 .dev_groups = vudc_groups,
0026 },
0027 };
0028
0029 static LIST_HEAD(vudc_devices);
0030
0031 static int __init vudc_init(void)
0032 {
0033 int retval = -ENOMEM;
0034 int i;
0035 struct vudc_device *udc_dev = NULL, *udc_dev2 = NULL;
0036
0037 if (usb_disabled())
0038 return -ENODEV;
0039
0040 if (vudc_number < 1) {
0041 pr_err("Number of emulated UDC must be no less than 1");
0042 return -EINVAL;
0043 }
0044
0045 retval = platform_driver_register(&vudc_driver);
0046 if (retval < 0)
0047 goto out;
0048
0049 for (i = 0; i < vudc_number; i++) {
0050 udc_dev = alloc_vudc_device(i);
0051 if (!udc_dev) {
0052 retval = -ENOMEM;
0053 goto cleanup;
0054 }
0055
0056 retval = platform_device_add(udc_dev->pdev);
0057 if (retval < 0) {
0058 put_vudc_device(udc_dev);
0059 goto cleanup;
0060 }
0061
0062 list_add_tail(&udc_dev->dev_entry, &vudc_devices);
0063 if (!platform_get_drvdata(udc_dev->pdev)) {
0064
0065
0066
0067
0068 retval = -EINVAL;
0069 goto cleanup;
0070 }
0071 }
0072 goto out;
0073
0074 cleanup:
0075 list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
0076 list_del(&udc_dev->dev_entry);
0077
0078
0079
0080
0081 platform_device_del(udc_dev->pdev);
0082 put_vudc_device(udc_dev);
0083 }
0084
0085 platform_driver_unregister(&vudc_driver);
0086 out:
0087 return retval;
0088 }
0089 module_init(vudc_init);
0090
0091 static void __exit vudc_cleanup(void)
0092 {
0093 struct vudc_device *udc_dev = NULL, *udc_dev2 = NULL;
0094
0095 list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
0096 list_del(&udc_dev->dev_entry);
0097
0098
0099
0100
0101 platform_device_del(udc_dev->pdev);
0102 put_vudc_device(udc_dev);
0103 }
0104 platform_driver_unregister(&vudc_driver);
0105 }
0106 module_exit(vudc_cleanup);
0107
0108 MODULE_DESCRIPTION("USB over IP Device Controller");
0109 MODULE_AUTHOR("Krzysztof Opasiak, Karol Kosik, Igor Kotrasinski");
0110 MODULE_LICENSE("GPL");