Matthieu CASTET a écrit :
Hi David,
David Brownell a écrit :
It's incomplete since only one USB peripheral
controller driver is even partially
converted to use this,
and having it work relies on all of them being
converted first ....
I converted only 2 USB peripherals (ci13xxx_udc.c and net2280.c) only
for doing an example. It was not worth doing all of them if upstream
doesn't like it !
Why do you say "partially" ?
Plus, the generic "everyone calls these" functions
are part of that driver, while they need to be
generic code (maybe a new file) that any UDC driver
can call ...
I don't understand what you mean. The generic functions are not in the
driver. There are in core.c, that is added into kernel (I don't make it
possible to be a module, because I don't think it is worth).
The driver only call usb_gadget_register_udc with its callback.
I guess I won't object much to the idea, just
its incomplete execution.
No problem, if you like the idea.
But first I want to be sure you like the changes and style.
Also I attach a version where not all driver need to be converted :
Sorry the previous patch was incomplete.
Matthieu
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index cd27f9b..8807035 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -424,46 +424,6 @@ config USB_FSL_QE
default USB_GADGET
select USB_GADGET_SELECTED
-config USB_GADGET_CI13XXX
- boolean "MIPS USB CI13xxx"
- depends on PCI
- select USB_GADGET_DUALSPEED
- help
- MIPS USB IP core family device controller
- Currently it only supports IP part number CI13412
-
- Say "y" to link the driver statically, or "m" to build a
- dynamically linked module called "ci13xxx_udc" and force all
- gadget drivers to also be dynamically linked.
-
-config USB_CI13XXX
- tristate
- depends on USB_GADGET_CI13XXX
- default USB_GADGET
- select USB_GADGET_SELECTED
-
-config USB_GADGET_NET2280
- boolean "NetChip 228x"
- depends on PCI
- select USB_GADGET_DUALSPEED
- help
- NetChip 2280 / 2282 is a PCI based USB peripheral controller which
- supports both full and high speed USB 2.0 data transfers.
-
- It has six configurable endpoints, as well as endpoint zero
- (for control transfers) and several endpoints with dedicated
- functions.
-
- Say "y" to link the driver statically, or "m" to build a
- dynamically linked module called "net2280" and force all
- gadget drivers to also be dynamically linked.
-
-config USB_NET2280
- tristate
- depends on USB_GADGET_NET2280
- default USB_GADGET
- select USB_GADGET_SELECTED
-
config USB_GADGET_GOKU
boolean "Toshiba TC86C001 'Goku-S'"
depends on PCI
@@ -505,6 +465,11 @@ config USB_LANGWELL
default USB_GADGET
select USB_GADGET_SELECTED
+config USB_GADGET_MULTIUDC
+ boolean "multi USB Device Port"
+ select USB_GADGET_SELECTED
+ help
+ Allow to build more than one udc.
#
# LAST -- dummy/emulated controller
@@ -544,6 +509,50 @@ config USB_DUMMY_HCD
endchoice
+menu "multi USB Peripheral Controller"
+ depends on USB_GADGET_MULTIUDC
+
+config USB_GADGET_CI13XXX
+ boolean "MIPS USB CI13xxx"
+ depends on PCI
+ select USB_GADGET_DUALSPEED
+ help
+ MIPS USB IP core family device controller
+ Currently it only supports IP part number CI13412
+
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module called "ci13xxx_udc" and force all
+ gadget drivers to also be dynamically linked.
+
+config USB_CI13XXX
+ tristate
+ depends on USB_GADGET_CI13XXX
+ default USB_GADGET
+ select USB_GADGET_SELECTED
+
+config USB_GADGET_NET2280
+ boolean "NetChip 228x"
+ depends on PCI
+ select USB_GADGET_DUALSPEED
+ help
+ NetChip 2280 / 2282 is a PCI based USB peripheral controller which
+ supports both full and high speed USB 2.0 data transfers.
+
+ It has six configurable endpoints, as well as endpoint zero
+ (for control transfers) and several endpoints with dedicated
+ functions.
+
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module called "net2280" and force all
+ gadget drivers to also be dynamically linked.
+
+config USB_NET2280
+ tristate
+ depends on USB_GADGET_NET2280
+ default USB_GADGET
+ select USB_GADGET_SELECTED
+endmenu
+
config USB_GADGET_DUALSPEED
bool
depends on USB_GADGET
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 27283df..5502bd3 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -65,3 +65,6 @@ obj-$(CONFIG_USB_G_MULTI) += g_multi.o
obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o
obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o
+ifneq ($(CONFIG_USB_GADGET_MULTIUDC),)
+obj-y += core.o
+endif
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 6996951..a775eee 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2339,15 +2339,16 @@ static const struct usb_ep_ops usb_ep_ops = {
*/
static const struct usb_gadget_ops usb_gadget_ops;
+static int cil_usb_gadget_unregister_driver(struct usb_gadget_driver *driver, void *priv);
/**
- * usb_gadget_register_driver: register a gadget driver
+ * cil_usb_gadget_register_driver: register a gadget driver
*
* Check usb_gadget_register_driver() at "usb_gadget.h" for details
* Interrupts are enabled here
*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+static int cil_usb_gadget_register_driver(struct usb_gadget_driver *driver, void *priv)
{
- struct ci13xxx *udc = _udc;
+ struct ci13xxx *udc = priv;
unsigned long i, k, flags;
int retval = -ENOMEM;
@@ -2444,19 +2445,18 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
done:
spin_unlock_irqrestore(udc->lock, flags);
if (retval)
- usb_gadget_unregister_driver(driver);
+ cil_usb_gadget_unregister_driver(driver, udc);
return retval;
}
-EXPORT_SYMBOL(usb_gadget_register_driver);
/**
- * usb_gadget_unregister_driver: unregister a gadget driver
+ * cil_usb_gadget_unregister_driver: unregister a gadget driver
*
* Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
*/
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int cil_usb_gadget_unregister_driver(struct usb_gadget_driver *driver, void *priv)
{
- struct ci13xxx *udc = _udc;
+ struct ci13xxx *udc = priv;
unsigned long i, k, flags;
trace("%p", driver);
@@ -2517,7 +2517,11 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
return 0;
}
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+struct usb_gadget_udc cil_driver = {
+ .register_driver = cil_usb_gadget_register_driver,
+ .unregister_driver = cil_usb_gadget_unregister_driver,
+};
/******************************************************************************
* BUS block
@@ -2647,6 +2651,12 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name)
}
_udc = udc;
+ retval = usb_gadget_register_udc(udc, &cil_driver);
+ if (retval) {
+ device_unregister(&udc->gadget.dev);
+ goto done;
+ }
+
return retval;
done:
diff --git a/drivers/usb/gadget/core.c b/drivers/usb/gadget/core.c
new file mode 100644
index 0000000..90a8033
--- /dev/null
+++ b/drivers/usb/gadget/core.c
@@ -0,0 +1,41 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+static struct usb_gadget_udc usb_gadget_udc;
+
+int usb_gadget_register_udc(void *priv, struct usb_gadget_udc *callback)
+{
+ if (!callback->register_driver || !callback->unregister_driver)
+ return -EINVAL;
+
+ if (usb_gadget_udc.register_driver || usb_gadget_udc.unregister_driver)
+ return -EBUSY;
+
+ usb_gadget_udc = *callback;
+ usb_gadget_udc.priv = priv;
+
+ return 0;
+}
+
+
+int usb_gadget_register_driver (struct usb_gadget_driver *driver)
+{
+ if (!usb_gadget_udc.register_driver)
+ return -ENODEV;
+ return usb_gadget_udc.register_driver(driver, usb_gadget_udc.priv);
+}
+EXPORT_SYMBOL (usb_gadget_register_driver);
+
+int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+{
+ if (!usb_gadget_udc.register_driver)
+ return -ENODEV;
+ return usb_gadget_udc.unregister_driver(driver, usb_gadget_udc.priv);
+}
+EXPORT_SYMBOL (usb_gadget_unregister_driver);
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 9498be8..6b11abf 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -1929,9 +1929,9 @@ static void ep0_start (struct net2280 *dev)
* disconnect is reported. then a host may connect again, or
* the driver might get unbound.
*/
-int usb_gadget_register_driver (struct usb_gadget_driver *driver)
+static int net2280_usb_gadget_register_driver (struct usb_gadget_driver *driver, void *priv)
{
- struct net2280 *dev = the_controller;
+ struct net2280 *dev = priv;
int retval;
unsigned i;
@@ -1993,7 +1993,6 @@ err_unbind:
dev->driver = NULL;
return retval;
}
-EXPORT_SYMBOL (usb_gadget_register_driver);
static void
stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver)
@@ -2021,9 +2020,9 @@ stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver)
usb_reinit (dev);
}
-int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+static int net2280_usb_gadget_unregister_driver (struct usb_gadget_driver *driver, void *priv)
{
- struct net2280 *dev = the_controller;
+ struct net2280 *dev = priv;
unsigned long flags;
if (!dev)
@@ -2048,7 +2047,11 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
DEBUG (dev, "unregistered driver '%s'\n", driver->driver.name);
return 0;
}
-EXPORT_SYMBOL (usb_gadget_unregister_driver);
+
+struct usb_gadget_udc net2280_driver = {
+ .register_driver = net2280_usb_gadget_register_driver,
+ .unregister_driver = net2280_usb_gadget_unregister_driver,
+};
/*-------------------------------------------------------------------------*/
@@ -2909,6 +2912,8 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
? (use_dma_chaining ? "chaining" : "enabled")
: "disabled");
the_controller = dev;
+ retval = usb_gadget_register_udc(dev, &net2280_driver);
+ if (retval) goto done;
retval = device_register (&dev->gadget.dev);
if (retval) goto done;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index d3ef42d..fa11432 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -825,6 +825,15 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver);
*/
int usb_gadget_unregister_driver(struct usb_gadget_driver *driver);
+#ifdef CONFIG_USB_GADGET_MULTIUDC
+struct usb_gadget_udc {
+ int (*register_driver) (struct usb_gadget_driver *driver, void *priv);
+ int (*unregister_driver) (struct usb_gadget_driver *driver, void *priv);
+ void *priv;
+};
+int usb_gadget_register_udc(void *priv, struct usb_gadget_udc *callback);
+#endif
+
/*-------------------------------------------------------------------------*/
/* utility to simplify dealing with string descriptors */