[PATCH 3/4] dummy_hcd: add setup / cleanup of multiple HW intances

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch creates & adds multiple instances of the HCD and UDC. We have
a new module option "num" which says how many emulated UDCs + HCDs we
want. The default value is one and currently the maximum is one as well.
This will change soon.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
---
 drivers/usb/gadget/dummy_hcd.c |   97 +++++++++++++++++++++++++++++-----------
 1 file changed, 72 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 97c7c00..eb0401b 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -63,16 +63,20 @@ MODULE_LICENSE("GPL");
 struct dummy_hcd_module_parameters {
 	bool is_super_speed;
 	bool is_high_speed;
+	unsigned int num;
 };
 
 static struct dummy_hcd_module_parameters mod_data = {
 	.is_super_speed = false,
 	.is_high_speed = true,
+	.num = 1,
 };
 module_param_named(is_super_speed, mod_data.is_super_speed, bool, S_IRUGO);
 MODULE_PARM_DESC(is_super_speed, "true to simulate SuperSpeed connection");
 module_param_named(is_high_speed, mod_data.is_high_speed, bool, S_IRUGO);
 MODULE_PARM_DESC(is_high_speed, "true to simulate HighSpeed connection");
+module_param_named(num, mod_data.num, uint, S_IRUGO);
+MODULE_PARM_DESC(num, "number of emulated controllers");
 /*-------------------------------------------------------------------------*/
 
 /* gadget side driver data structres */
@@ -2737,6 +2741,7 @@ static struct platform_device *the_hcd_pdev[MAX_NUM_UDC];
 static int __init init(void)
 {
 	int	retval = -ENOMEM;
+	int	i;
 
 	if (usb_disabled())
 		return -ENODEV;
@@ -2744,12 +2749,29 @@ static int __init init(void)
 	if (!mod_data.is_high_speed && mod_data.is_super_speed)
 		return -EINVAL;
 
-	the_hcd_pdev[0] = platform_device_alloc(driver_name, 0);
-	if (!the_hcd_pdev[0])
-		return retval;
-	the_udc_pdev[0] = platform_device_alloc(gadget_name, 0);
-	if (!the_udc_pdev[0])
-		goto err_alloc_udc;
+	if (mod_data.num < 1 || mod_data.num > MAX_NUM_UDC) {
+		pr_err("Number of emulated UDC must be in range of 1…%d\n",
+				MAX_NUM_UDC);
+		return -EINVAL;
+	}
+	for (i = 0; i < mod_data.num; i++) {
+		the_hcd_pdev[i] = platform_device_alloc(driver_name, i);
+		if (!the_hcd_pdev[i]) {
+			i--;
+			while (i >= 0)
+				platform_device_put(the_hcd_pdev[i--]);
+			return retval;
+		}
+	}
+	for (i = 0; i < mod_data.num; i++) {
+		the_udc_pdev[i] = platform_device_alloc(gadget_name, i);
+		if (!the_udc_pdev[i]) {
+			i--;
+			while (i >= 0)
+				platform_device_put(the_udc_pdev[i--]);
+			goto err_alloc_udc;
+		}
+	}
 
 	retval = platform_driver_register(&dummy_hcd_driver);
 	if (retval < 0)
@@ -2758,9 +2780,15 @@ static int __init init(void)
 	if (retval < 0)
 		goto err_register_udc_driver;
 
-	retval = platform_device_add(the_hcd_pdev[0]);
-	if (retval < 0)
-		goto err_add_hcd;
+	for (i = 0; i < mod_data.num; i++) {
+		retval = platform_device_add(the_hcd_pdev[i]);
+		if (retval < 0) {
+			i--;
+			while (i >= 0)
+				platform_device_del(the_hcd_pdev[i--]);
+			goto err_add_hcd;
+		}
+	}
 	if (!the_controller.hs_hcd ||
 	    (!the_controller.ss_hcd && mod_data.is_super_speed)) {
 		/*
@@ -2770,39 +2798,58 @@ static int __init init(void)
 		retval = -EINVAL;
 		goto err_add_udc;
 	}
-	retval = platform_device_add(the_udc_pdev[0]);
-	if (retval < 0)
-		goto err_add_udc;
-	if (!platform_get_drvdata(the_udc_pdev[0])) {
-		/*
-		 * The udc was added successfully but its probe function failed
-		 * for some reason.
-		 */
-		retval = -EINVAL;
-		goto err_probe_udc;
+
+
+	for (i = 0; i < mod_data.num; i++) {
+		retval = platform_device_add(the_udc_pdev[i]);
+		if (retval < 0) {
+			i--;
+			while (i >= 0)
+				platform_device_del(the_udc_pdev[i]);
+			goto err_add_udc;
+		}
+	}
+
+	for (i = 0; i < mod_data.num; i++) {
+		if (!platform_get_drvdata(the_udc_pdev[i])) {
+			/*
+			 * The udc was added successfully but its probe
+			 * function failed for some reason.
+			 */
+			retval = -EINVAL;
+			goto err_probe_udc;
+		}
 	}
 	return retval;
 
 err_probe_udc:
-	platform_device_del(the_udc_pdev[0]);
+	for (i = 0; i < mod_data.num; i++)
+		platform_device_del(the_udc_pdev[i]);
 err_add_udc:
-	platform_device_del(the_hcd_pdev[0]);
+	for (i = 0; i < mod_data.num; i++)
+		platform_device_del(the_hcd_pdev[i]);
 err_add_hcd:
 	platform_driver_unregister(&dummy_udc_driver);
 err_register_udc_driver:
 	platform_driver_unregister(&dummy_hcd_driver);
 err_register_hcd_driver:
-	platform_device_put(the_udc_pdev[0]);
+	for (i = 0; i < mod_data.num; i++)
+		platform_device_put(the_udc_pdev[i]);
 err_alloc_udc:
-	platform_device_put(the_hcd_pdev[0]);
+	for (i = 0; i < mod_data.num; i++)
+		platform_device_put(the_hcd_pdev[i]);
 	return retval;
 }
 module_init(init);
 
 static void __exit cleanup(void)
 {
-	platform_device_unregister(the_udc_pdev[0]);
-	platform_device_unregister(the_hcd_pdev[0]);
+	int i;
+
+	for (i = 0; i < mod_data.num; i++) {
+		platform_device_unregister(the_udc_pdev[i]);
+		platform_device_unregister(the_hcd_pdev[i]);
+	}
 	platform_driver_unregister(&dummy_udc_driver);
 	platform_driver_unregister(&dummy_hcd_driver);
 }
-- 
1.7.10.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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux