cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

vudc_main.c (2545B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
      4 * Copyright (C) 2015-2016 Samsung Electronics
      5 *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
      6 *               Krzysztof Opasiak <k.opasiak@samsung.com>
      7 */
      8
      9#include <linux/device.h>
     10#include <linux/list.h>
     11#include <linux/module.h>
     12
     13#include "vudc.h"
     14
     15static unsigned int vudc_number = 1;
     16
     17module_param_named(num, vudc_number, uint, S_IRUGO);
     18MODULE_PARM_DESC(num, "number of emulated controllers");
     19
     20static struct platform_driver vudc_driver = {
     21	.probe		= vudc_probe,
     22	.remove		= vudc_remove,
     23	.driver		= {
     24		.name	= GADGET_NAME,
     25		.dev_groups = vudc_groups,
     26	},
     27};
     28
     29static LIST_HEAD(vudc_devices);
     30
     31static int __init vudc_init(void)
     32{
     33	int retval = -ENOMEM;
     34	int i;
     35	struct vudc_device *udc_dev = NULL, *udc_dev2 = NULL;
     36
     37	if (usb_disabled())
     38		return -ENODEV;
     39
     40	if (vudc_number < 1) {
     41		pr_err("Number of emulated UDC must be no less than 1");
     42		return -EINVAL;
     43	}
     44
     45	retval = platform_driver_register(&vudc_driver);
     46	if (retval < 0)
     47		goto out;
     48
     49	for (i = 0; i < vudc_number; i++) {
     50		udc_dev = alloc_vudc_device(i);
     51		if (!udc_dev) {
     52			retval = -ENOMEM;
     53			goto cleanup;
     54		}
     55
     56		retval = platform_device_add(udc_dev->pdev);
     57		if (retval < 0) {
     58			put_vudc_device(udc_dev);
     59			goto cleanup;
     60		}
     61
     62		list_add_tail(&udc_dev->dev_entry, &vudc_devices);
     63		if (!platform_get_drvdata(udc_dev->pdev)) {
     64			/*
     65			 * The udc was added successfully but its probe
     66			 * function failed for some reason.
     67			 */
     68			retval = -EINVAL;
     69			goto cleanup;
     70		}
     71	}
     72	goto out;
     73
     74cleanup:
     75	list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
     76		list_del(&udc_dev->dev_entry);
     77		/*
     78		 * Just do platform_device_del() here, put_vudc_device()
     79		 * calls the platform_device_put()
     80		 */
     81		platform_device_del(udc_dev->pdev);
     82		put_vudc_device(udc_dev);
     83	}
     84
     85	platform_driver_unregister(&vudc_driver);
     86out:
     87	return retval;
     88}
     89module_init(vudc_init);
     90
     91static void __exit vudc_cleanup(void)
     92{
     93	struct vudc_device *udc_dev = NULL, *udc_dev2 = NULL;
     94
     95	list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
     96		list_del(&udc_dev->dev_entry);
     97		/*
     98		 * Just do platform_device_del() here, put_vudc_device()
     99		 * calls the platform_device_put()
    100		 */
    101		platform_device_del(udc_dev->pdev);
    102		put_vudc_device(udc_dev);
    103	}
    104	platform_driver_unregister(&vudc_driver);
    105}
    106module_exit(vudc_cleanup);
    107
    108MODULE_DESCRIPTION("USB over IP Device Controller");
    109MODULE_AUTHOR("Krzysztof Opasiak, Karol Kosik, Igor Kotrasinski");
    110MODULE_LICENSE("GPL");