Greg:

This patch makes the dummy_hcd driver create separate platform devices for
the emulated host controller and emulated device controller.  This gives a
more accurate simulation and will permit testing of situations where only
one of the two devices is suspended.

This also changes the name of the host controller platform device to match 
the name of the driver.  That way the normal platform bus probe mechanism 
will handle binding the driver to the device.

Alan Stern



Signed-off-by: Alan Stern <[EMAIL PROTECTED]>

Index: usb-2.6/drivers/usb/gadget/dummy_hcd.c
===================================================================
--- usb-2.6.orig/drivers/usb/gadget/dummy_hcd.c
+++ usb-2.6/drivers/usb/gadget/dummy_hcd.c
@@ -141,6 +141,8 @@ static const char *const ep_name [] = {
 };
 #define DUMMY_ENDPOINTS        (sizeof(ep_name)/sizeof(char *))
 
+/*-------------------------------------------------------------------------*/
+
 #define FIFO_SIZE              64
 
 struct urbp {
@@ -189,6 +191,11 @@ static inline struct device *dummy_dev (
        return dummy_to_hcd(dum)->self.controller;
 }
 
+static inline struct device *udc_dev (struct dummy *dum)
+{
+       return dum->gadget.dev.parent;
+}
+
 static inline struct dummy *ep_to_dummy (struct dummy_ep *ep)
 {
        return container_of (ep->gadget, struct dummy, gadget);
@@ -208,19 +215,6 @@ static struct dummy                        *the_controller;
 
 /*-------------------------------------------------------------------------*/
 
-/*
- * This "hardware" may look a bit odd in diagnostics since it's got both
- * host and device sides; and it binds different drivers to each side.
- */
-static struct platform_device          the_pdev;
-
-static struct device_driver dummy_driver = {
-       .name           = (char *) driver_name,
-       .bus            = &platform_bus_type,
-};
-
-/*-------------------------------------------------------------------------*/
-
 /* SLAVE/GADGET SIDE DRIVER
  *
  * This only tracks gadget state.  All the work is done when the host
@@ -324,7 +318,7 @@ dummy_enable (struct usb_ep *_ep, const 
        _ep->maxpacket = max;
        ep->desc = desc;
 
-       dev_dbg (dummy_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d\n",
+       dev_dbg (udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d\n",
                _ep->name,
                desc->bEndpointAddress & 0x0f,
                (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
@@ -379,7 +373,7 @@ static int dummy_disable (struct usb_ep 
        nuke (dum, ep);
        spin_unlock_irqrestore (&dum->lock, flags);
 
-       dev_dbg (dummy_dev(dum), "disabled %s\n", _ep->name);
+       dev_dbg (udc_dev(dum), "disabled %s\n", _ep->name);
        return retval;
 }
 
@@ -474,7 +468,7 @@ dummy_queue (struct usb_ep *_ep, struct 
                return -ESHUTDOWN;
 
 #if 0
-       dev_dbg (dummy_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n",
+       dev_dbg (udc_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n",
                        ep, _req, _ep->name, _req->length, _req->buf);
 #endif
 
@@ -537,7 +531,7 @@ static int dummy_dequeue (struct usb_ep 
        spin_unlock_irqrestore (&dum->lock, flags);
 
        if (retval == 0) {
-               dev_dbg (dummy_dev(dum),
+               dev_dbg (udc_dev(dum),
                                "dequeued req %p from %s, len %d buf %p\n",
                                req, _ep->name, _req->length, _req->buf);
                _req->complete (_ep, _req);
@@ -661,38 +655,6 @@ DEVICE_ATTR (function, S_IRUGO, show_fun
  * for each driver that registers:  just add to a big root hub.
  */
 
-/* This doesn't need to do anything because the udc device structure is
- * stored inside the hcd and will be deallocated along with it. */
-static void
-dummy_udc_release (struct device *dev) {}
-
-/* This doesn't need to do anything because the pdev structure is
- * statically allocated. */
-static void
-dummy_pdev_release (struct device *dev) {}
-
-static int
-dummy_register_udc (struct dummy *dum)
-{
-       int             rc;
-
-       strcpy (dum->gadget.dev.bus_id, "udc");
-       dum->gadget.dev.parent = dummy_dev(dum);
-       dum->gadget.dev.release = dummy_udc_release;
-
-       rc = device_register (&dum->gadget.dev);
-       if (rc == 0)
-               device_create_file (&dum->gadget.dev, &dev_attr_function);
-       return rc;
-}
-
-static void
-dummy_unregister_udc (struct dummy *dum)
-{
-       device_remove_file (&dum->gadget.dev, &dev_attr_function);
-       device_unregister (&dum->gadget.dev);
-}
-
 int
 usb_gadget_register_driver (struct usb_gadget_driver *driver)
 {
@@ -711,12 +673,6 @@ usb_gadget_register_driver (struct usb_g
         * SLAVE side init ... the layer above hardware, which
         * can't enumerate without help from the driver we're binding.
         */
-       dum->gadget.name = gadget_name;
-       dum->gadget.ops = &dummy_ops;
-       dum->gadget.is_dualspeed = 1;
-
-       /* maybe claim OTG support, though we won't complete HNP */
-       dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
 
        dum->devstatus = 0;
        dum->resuming = 0;
@@ -745,7 +701,7 @@ usb_gadget_register_driver (struct usb_g
 
        dum->driver = driver;
        dum->gadget.dev.driver = &driver->driver;
-       dev_dbg (dummy_dev(dum), "binding gadget driver '%s'\n",
+       dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n",
                        driver->driver.name);
        if ((retval = driver->bind (&dum->gadget)) != 0) {
                dum->driver = NULL;
@@ -798,7 +754,7 @@ usb_gadget_unregister_driver (struct usb
        if (!driver || driver != dum->driver)
                return -EINVAL;
 
-       dev_dbg (dummy_dev(dum), "unregister gadget driver '%s'\n",
+       dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n",
                        driver->driver.name);
 
        spin_lock_irqsave (&dum->lock, flags);
@@ -826,6 +782,64 @@ int net2280_set_fifo_mode (struct usb_ga
 }
 EXPORT_SYMBOL (net2280_set_fifo_mode);
 
+
+/* The gadget structure is stored inside the hcd structure and will be
+ * released along with it. */
+static void
+dummy_gadget_release (struct device *dev)
+{
+#if 0          /* usb_bus_put isn't EXPORTed! */
+       struct dummy    *dum = gadget_dev_to_dummy (dev);
+
+       usb_bus_put (&dummy_to_hcd (dum)->self);
+#endif
+}
+
+static int dummy_udc_probe (struct device *dev)
+{
+       struct dummy    *dum = the_controller;
+       int             rc;
+
+       dum->gadget.name = gadget_name;
+       dum->gadget.ops = &dummy_ops;
+       dum->gadget.is_dualspeed = 1;
+
+       /* maybe claim OTG support, though we won't complete HNP */
+       dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
+
+       strcpy (dum->gadget.dev.bus_id, "gadget");
+       dum->gadget.dev.parent = dev;
+       dum->gadget.dev.release = dummy_gadget_release;
+       rc = device_register (&dum->gadget.dev);
+       if (rc < 0)
+               return rc;
+
+#if 0          /* usb_bus_get isn't EXPORTed! */
+       usb_bus_get (&dummy_to_hcd (dum)->self);
+#endif
+
+       dev_set_drvdata (dev, dum);
+       device_create_file (&dum->gadget.dev, &dev_attr_function);
+       return rc;
+}
+
+static int dummy_udc_remove (struct device *dev)
+{
+       struct dummy    *dum = dev_get_drvdata (dev);
+
+       dev_set_drvdata (dev, NULL);
+       device_remove_file (&dum->gadget.dev, &dev_attr_function);
+       device_unregister (&dum->gadget.dev);
+       return 0;
+}
+
+static struct device_driver dummy_udc_driver = {
+       .name           = (char *) gadget_name,
+       .bus            = &platform_bus_type,
+       .probe          = dummy_udc_probe,
+       .remove         = dummy_udc_remove,
+};
+
 /*-------------------------------------------------------------------------*/
 
 /* MASTER/HOST SIDE DRIVER
@@ -1184,7 +1198,7 @@ restart:
                        list_for_each_entry (req, &ep->queue, queue) {
                                list_del_init (&req->queue);
                                req->req.status = -EOVERFLOW;
-                               dev_dbg (dummy_dev(dum), "stale req = %p\n",
+                               dev_dbg (udc_dev(dum), "stale req = %p\n",
                                                req);
 
                                spin_unlock (&dum->lock);
@@ -1207,7 +1221,7 @@ restart:
                                        break;
                                dum->address = setup.wValue;
                                maybe_set_status (urb, 0);
-                               dev_dbg (dummy_dev(dum), "set_address = %d\n",
+                               dev_dbg (udc_dev(dum), "set_address = %d\n",
                                                setup.wValue);
                                value = 0;
                                break;
@@ -1333,7 +1347,7 @@ restart:
 
                        if (value < 0) {
                                if (value != -EOPNOTSUPP)
-                                       dev_dbg (dummy_dev(dum),
+                                       dev_dbg (udc_dev(dum),
                                                "setup --> %d\n",
                                                value);
                                maybe_set_status (urb, -EPIPE);
@@ -1561,7 +1575,7 @@ static int dummy_hub_control (
                                                | USB_PORT_STAT_LOW_SPEED
                                                | USB_PORT_STAT_HIGH_SPEED);
                                if (dum->driver) {
-                                       dev_dbg (dummy_dev(dum),
+                                       dev_dbg (udc_dev(dum),
                                                        "disconnect\n");
                                        stop_activity (dum, dum->driver);
                                }
@@ -1643,7 +1657,6 @@ static DEVICE_ATTR (urbs, S_IRUGO, show_
 static int dummy_start (struct usb_hcd *hcd)
 {
        struct dummy            *dum;
-       int                     retval;
 
        dum = hcd_to_dummy (hcd);
 
@@ -1659,9 +1672,6 @@ static int dummy_start (struct usb_hcd *
 
        INIT_LIST_HEAD (&dum->urbp_list);
 
-       if ((retval = dummy_register_udc (dum)) != 0)
-               return retval;
-
        /* only show a low-power port: just 8mA */
        hcd->power_budget = 8;
        hcd->state = HC_STATE_RUNNING;
@@ -1682,10 +1692,7 @@ static void dummy_stop (struct usb_hcd *
        dum = hcd_to_dummy (hcd);
 
        device_remove_file (dummy_dev(dum), &dev_attr_urbs);
-
        usb_gadget_unregister_driver (dum->driver);
-       dummy_unregister_udc (dum);
-
        dev_info (dummy_dev(dum), "stopped\n");
 }
 
@@ -1715,7 +1722,7 @@ static const struct hc_driver dummy_hcd 
        .hub_control =          dummy_hub_control,
 };
 
-static int dummy_probe (struct device *dev)
+static int dummy_hcd_probe (struct device *dev)
 {
        struct usb_hcd          *hcd;
        int                     retval;
@@ -1735,7 +1742,7 @@ static int dummy_probe (struct device *d
        return retval;
 }
 
-static void dummy_remove (struct device *dev)
+static int dummy_hcd_remove (struct device *dev)
 {
        struct usb_hcd          *hcd;
 
@@ -1743,35 +1750,41 @@ static void dummy_remove (struct device 
        usb_remove_hcd (hcd);
        usb_put_hcd (hcd);
        the_controller = NULL;
+       return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int dummy_pdev_detect (void)
-{
-       int                     retval;
+static struct device_driver dummy_hcd_driver = {
+       .name           = (char *) driver_name,
+       .bus            = &platform_bus_type,
+       .probe          = dummy_hcd_probe,
+       .remove         = dummy_hcd_remove,
+};
 
-       retval = driver_register (&dummy_driver);
-       if (retval < 0)
-               return retval;
+/*-------------------------------------------------------------------------*/
 
-       the_pdev.name = "hc";
-       the_pdev.dev.driver = &dummy_driver;
-       the_pdev.dev.release = dummy_pdev_release;
+/* These don't need to do anything because the pdev structures are
+ * statically allocated. */
+static void
+dummy_udc_release (struct device *dev) {}
 
-       retval = platform_device_register (&the_pdev);
-       if (retval < 0)
-               driver_unregister (&dummy_driver);
-       return retval;
-}
+static void
+dummy_hcd_release (struct device *dev) {}
 
-static void dummy_pdev_remove (void)
-{
-       platform_device_unregister (&the_pdev);
-       driver_unregister (&dummy_driver);
-}
+static struct platform_device          the_udc_pdev = {
+       .name           = (char *) gadget_name,
+       .id             = -1,
+       .dev            = {
+               .release        = dummy_udc_release,
+       },
+};
 
-/*-------------------------------------------------------------------------*/
+static struct platform_device          the_hcd_pdev = {
+       .name           = (char *) driver_name,
+       .id             = -1,
+       .dev            = {
+               .release        = dummy_hcd_release,
+       },
+};
 
 static int __init init (void)
 {
@@ -1779,17 +1792,39 @@ static int __init init (void)
 
        if (usb_disabled ())
                return -ENODEV;
-       if ((retval = dummy_pdev_detect ()) != 0)
+
+       retval = driver_register (&dummy_hcd_driver);
+       if (retval < 0)
                return retval;
-       if ((retval = dummy_probe (&the_pdev.dev)) != 0)
-               dummy_pdev_remove ();
+
+       retval = driver_register (&dummy_udc_driver);
+       if (retval < 0)
+               goto err_register_udc_driver;
+
+       retval = platform_device_register (&the_hcd_pdev);
+       if (retval < 0)
+               goto err_register_hcd;
+
+       retval = platform_device_register (&the_udc_pdev);
+       if (retval < 0)
+               goto err_register_udc;
+       return retval;
+
+err_register_udc:
+       platform_device_unregister (&the_hcd_pdev);
+err_register_hcd:
+       driver_unregister (&dummy_udc_driver);
+err_register_udc_driver:
+       driver_unregister (&dummy_hcd_driver);
        return retval;
 }
 module_init (init);
 
 static void __exit cleanup (void)
 {
-       dummy_remove (&the_pdev.dev);
-       dummy_pdev_remove ();
+       platform_device_unregister (&the_udc_pdev);
+       platform_device_unregister (&the_hcd_pdev);
+       driver_unregister (&dummy_udc_driver);
+       driver_unregister (&dummy_hcd_driver);
 }
 module_exit (cleanup);



-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.
Get your fingers limbered up and give it your best shot. 4 great events, 4
opportunities to win big! Highest score wins.NEC IT Guy Games. Play to
win an NEC 61 plasma display. Visit http://www.necitguy.com/?r=20
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to