aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-05-03 16:15:43 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-27 17:43:52 -0400
commitd9b762510c186584a6be0d3ece03e8a4b2ac13a8 (patch)
tree23cd5e51145e4a11ad669a5f6ddca20b0fd7272f
parentc2db8b5e5692a6f35913a829607ee6efde3c7cbd (diff)
[PATCH] USB dummy_hcd: Use separate pdevs for HC and UDC
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. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/gadget/dummy_hcd.c231
1 files changed, 133 insertions, 98 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index ffedf4d1b747..dc0e3233b0e9 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -141,6 +141,8 @@ static const char *const ep_name [] = {
141}; 141};
142#define DUMMY_ENDPOINTS (sizeof(ep_name)/sizeof(char *)) 142#define DUMMY_ENDPOINTS (sizeof(ep_name)/sizeof(char *))
143 143
144/*-------------------------------------------------------------------------*/
145
144#define FIFO_SIZE 64 146#define FIFO_SIZE 64
145 147
146struct urbp { 148struct urbp {
@@ -189,6 +191,11 @@ static inline struct device *dummy_dev (struct dummy *dum)
189 return dummy_to_hcd(dum)->self.controller; 191 return dummy_to_hcd(dum)->self.controller;
190} 192}
191 193
194static inline struct device *udc_dev (struct dummy *dum)
195{
196 return dum->gadget.dev.parent;
197}
198
192static inline struct dummy *ep_to_dummy (struct dummy_ep *ep) 199static inline struct dummy *ep_to_dummy (struct dummy_ep *ep)
193{ 200{
194 return container_of (ep->gadget, struct dummy, gadget); 201 return container_of (ep->gadget, struct dummy, gadget);
@@ -208,19 +215,6 @@ static struct dummy *the_controller;
208 215
209/*-------------------------------------------------------------------------*/ 216/*-------------------------------------------------------------------------*/
210 217
211/*
212 * This "hardware" may look a bit odd in diagnostics since it's got both
213 * host and device sides; and it binds different drivers to each side.
214 */
215static struct platform_device the_pdev;
216
217static struct device_driver dummy_driver = {
218 .name = (char *) driver_name,
219 .bus = &platform_bus_type,
220};
221
222/*-------------------------------------------------------------------------*/
223
224/* SLAVE/GADGET SIDE DRIVER 218/* SLAVE/GADGET SIDE DRIVER
225 * 219 *
226 * This only tracks gadget state. All the work is done when the host 220 * This only tracks gadget state. All the work is done when the host
@@ -324,7 +318,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
324 _ep->maxpacket = max; 318 _ep->maxpacket = max;
325 ep->desc = desc; 319 ep->desc = desc;
326 320
327 dev_dbg (dummy_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d\n", 321 dev_dbg (udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d\n",
328 _ep->name, 322 _ep->name,
329 desc->bEndpointAddress & 0x0f, 323 desc->bEndpointAddress & 0x0f,
330 (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", 324 (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
@@ -379,7 +373,7 @@ static int dummy_disable (struct usb_ep *_ep)
379 nuke (dum, ep); 373 nuke (dum, ep);
380 spin_unlock_irqrestore (&dum->lock, flags); 374 spin_unlock_irqrestore (&dum->lock, flags);
381 375
382 dev_dbg (dummy_dev(dum), "disabled %s\n", _ep->name); 376 dev_dbg (udc_dev(dum), "disabled %s\n", _ep->name);
383 return retval; 377 return retval;
384} 378}
385 379
@@ -474,7 +468,7 @@ dummy_queue (struct usb_ep *_ep, struct usb_request *_req, int mem_flags)
474 return -ESHUTDOWN; 468 return -ESHUTDOWN;
475 469
476#if 0 470#if 0
477 dev_dbg (dummy_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n", 471 dev_dbg (udc_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n",
478 ep, _req, _ep->name, _req->length, _req->buf); 472 ep, _req, _ep->name, _req->length, _req->buf);
479#endif 473#endif
480 474
@@ -537,7 +531,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
537 spin_unlock_irqrestore (&dum->lock, flags); 531 spin_unlock_irqrestore (&dum->lock, flags);
538 532
539 if (retval == 0) { 533 if (retval == 0) {
540 dev_dbg (dummy_dev(dum), 534 dev_dbg (udc_dev(dum),
541 "dequeued req %p from %s, len %d buf %p\n", 535 "dequeued req %p from %s, len %d buf %p\n",
542 req, _ep->name, _req->length, _req->buf); 536 req, _ep->name, _req->length, _req->buf);
543 _req->complete (_ep, _req); 537 _req->complete (_ep, _req);
@@ -661,38 +655,6 @@ DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
661 * for each driver that registers: just add to a big root hub. 655 * for each driver that registers: just add to a big root hub.
662 */ 656 */
663 657
664/* This doesn't need to do anything because the udc device structure is
665 * stored inside the hcd and will be deallocated along with it. */
666static void
667dummy_udc_release (struct device *dev) {}
668
669/* This doesn't need to do anything because the pdev structure is
670 * statically allocated. */
671static void
672dummy_pdev_release (struct device *dev) {}
673
674static int
675dummy_register_udc (struct dummy *dum)
676{
677 int rc;
678
679 strcpy (dum->gadget.dev.bus_id, "udc");
680 dum->gadget.dev.parent = dummy_dev(dum);
681 dum->gadget.dev.release = dummy_udc_release;
682
683 rc = device_register (&dum->gadget.dev);
684 if (rc == 0)
685 device_create_file (&dum->gadget.dev, &dev_attr_function);
686 return rc;
687}
688
689static void
690dummy_unregister_udc (struct dummy *dum)
691{
692 device_remove_file (&dum->gadget.dev, &dev_attr_function);
693 device_unregister (&dum->gadget.dev);
694}
695
696int 658int
697usb_gadget_register_driver (struct usb_gadget_driver *driver) 659usb_gadget_register_driver (struct usb_gadget_driver *driver)
698{ 660{
@@ -711,12 +673,6 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
711 * SLAVE side init ... the layer above hardware, which 673 * SLAVE side init ... the layer above hardware, which
712 * can't enumerate without help from the driver we're binding. 674 * can't enumerate without help from the driver we're binding.
713 */ 675 */
714 dum->gadget.name = gadget_name;
715 dum->gadget.ops = &dummy_ops;
716 dum->gadget.is_dualspeed = 1;
717
718 /* maybe claim OTG support, though we won't complete HNP */
719 dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
720 676
721 dum->devstatus = 0; 677 dum->devstatus = 0;
722 dum->resuming = 0; 678 dum->resuming = 0;
@@ -745,7 +701,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
745 701
746 dum->driver = driver; 702 dum->driver = driver;
747 dum->gadget.dev.driver = &driver->driver; 703 dum->gadget.dev.driver = &driver->driver;
748 dev_dbg (dummy_dev(dum), "binding gadget driver '%s'\n", 704 dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n",
749 driver->driver.name); 705 driver->driver.name);
750 if ((retval = driver->bind (&dum->gadget)) != 0) { 706 if ((retval = driver->bind (&dum->gadget)) != 0) {
751 dum->driver = NULL; 707 dum->driver = NULL;
@@ -798,7 +754,7 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
798 if (!driver || driver != dum->driver) 754 if (!driver || driver != dum->driver)
799 return -EINVAL; 755 return -EINVAL;
800 756
801 dev_dbg (dummy_dev(dum), "unregister gadget driver '%s'\n", 757 dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n",
802 driver->driver.name); 758 driver->driver.name);
803 759
804 spin_lock_irqsave (&dum->lock, flags); 760 spin_lock_irqsave (&dum->lock, flags);
@@ -826,6 +782,64 @@ int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode)
826} 782}
827EXPORT_SYMBOL (net2280_set_fifo_mode); 783EXPORT_SYMBOL (net2280_set_fifo_mode);
828 784
785
786/* The gadget structure is stored inside the hcd structure and will be
787 * released along with it. */
788static void
789dummy_gadget_release (struct device *dev)
790{
791#if 0 /* usb_bus_put isn't EXPORTed! */
792 struct dummy *dum = gadget_dev_to_dummy (dev);
793
794 usb_bus_put (&dummy_to_hcd (dum)->self);
795#endif
796}
797
798static int dummy_udc_probe (struct device *dev)
799{
800 struct dummy *dum = the_controller;
801 int rc;
802
803 dum->gadget.name = gadget_name;
804 dum->gadget.ops = &dummy_ops;
805 dum->gadget.is_dualspeed = 1;
806
807 /* maybe claim OTG support, though we won't complete HNP */
808 dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
809
810 strcpy (dum->gadget.dev.bus_id, "gadget");
811 dum->gadget.dev.parent = dev;
812 dum->gadget.dev.release = dummy_gadget_release;
813 rc = device_register (&dum->gadget.dev);
814 if (rc < 0)
815 return rc;
816
817#if 0 /* usb_bus_get isn't EXPORTed! */
818 usb_bus_get (&dummy_to_hcd (dum)->self);
819#endif
820
821 dev_set_drvdata (dev, dum);
822 device_create_file (&dum->gadget.dev, &dev_attr_function);
823 return rc;
824}
825
826static int dummy_udc_remove (struct device *dev)
827{
828 struct dummy *dum = dev_get_drvdata (dev);
829
830 dev_set_drvdata (dev, NULL);
831 device_remove_file (&dum->gadget.dev, &dev_attr_function);
832 device_unregister (&dum->gadget.dev);
833 return 0;
834}
835
836static struct device_driver dummy_udc_driver = {
837 .name = (char *) gadget_name,
838 .bus = &platform_bus_type,
839 .probe = dummy_udc_probe,
840 .remove = dummy_udc_remove,
841};
842
829/*-------------------------------------------------------------------------*/ 843/*-------------------------------------------------------------------------*/
830 844
831/* MASTER/HOST SIDE DRIVER 845/* MASTER/HOST SIDE DRIVER
@@ -1184,7 +1198,7 @@ restart:
1184 list_for_each_entry (req, &ep->queue, queue) { 1198 list_for_each_entry (req, &ep->queue, queue) {
1185 list_del_init (&req->queue); 1199 list_del_init (&req->queue);
1186 req->req.status = -EOVERFLOW; 1200 req->req.status = -EOVERFLOW;
1187 dev_dbg (dummy_dev(dum), "stale req = %p\n", 1201 dev_dbg (udc_dev(dum), "stale req = %p\n",
1188 req); 1202 req);
1189 1203
1190 spin_unlock (&dum->lock); 1204 spin_unlock (&dum->lock);
@@ -1207,7 +1221,7 @@ restart:
1207 break; 1221 break;
1208 dum->address = setup.wValue; 1222 dum->address = setup.wValue;
1209 maybe_set_status (urb, 0); 1223 maybe_set_status (urb, 0);
1210 dev_dbg (dummy_dev(dum), "set_address = %d\n", 1224 dev_dbg (udc_dev(dum), "set_address = %d\n",
1211 setup.wValue); 1225 setup.wValue);
1212 value = 0; 1226 value = 0;
1213 break; 1227 break;
@@ -1333,7 +1347,7 @@ restart:
1333 1347
1334 if (value < 0) { 1348 if (value < 0) {
1335 if (value != -EOPNOTSUPP) 1349 if (value != -EOPNOTSUPP)
1336 dev_dbg (dummy_dev(dum), 1350 dev_dbg (udc_dev(dum),
1337 "setup --> %d\n", 1351 "setup --> %d\n",
1338 value); 1352 value);
1339 maybe_set_status (urb, -EPIPE); 1353 maybe_set_status (urb, -EPIPE);
@@ -1561,7 +1575,7 @@ static int dummy_hub_control (
1561 | USB_PORT_STAT_LOW_SPEED 1575 | USB_PORT_STAT_LOW_SPEED
1562 | USB_PORT_STAT_HIGH_SPEED); 1576 | USB_PORT_STAT_HIGH_SPEED);
1563 if (dum->driver) { 1577 if (dum->driver) {
1564 dev_dbg (dummy_dev(dum), 1578 dev_dbg (udc_dev(dum),
1565 "disconnect\n"); 1579 "disconnect\n");
1566 stop_activity (dum, dum->driver); 1580 stop_activity (dum, dum->driver);
1567 } 1581 }
@@ -1643,7 +1657,6 @@ static DEVICE_ATTR (urbs, S_IRUGO, show_urbs, NULL);
1643static int dummy_start (struct usb_hcd *hcd) 1657static int dummy_start (struct usb_hcd *hcd)
1644{ 1658{
1645 struct dummy *dum; 1659 struct dummy *dum;
1646 int retval;
1647 1660
1648 dum = hcd_to_dummy (hcd); 1661 dum = hcd_to_dummy (hcd);
1649 1662
@@ -1659,9 +1672,6 @@ static int dummy_start (struct usb_hcd *hcd)
1659 1672
1660 INIT_LIST_HEAD (&dum->urbp_list); 1673 INIT_LIST_HEAD (&dum->urbp_list);
1661 1674
1662 if ((retval = dummy_register_udc (dum)) != 0)
1663 return retval;
1664
1665 /* only show a low-power port: just 8mA */ 1675 /* only show a low-power port: just 8mA */
1666 hcd->power_budget = 8; 1676 hcd->power_budget = 8;
1667 hcd->state = HC_STATE_RUNNING; 1677 hcd->state = HC_STATE_RUNNING;
@@ -1682,10 +1692,7 @@ static void dummy_stop (struct usb_hcd *hcd)
1682 dum = hcd_to_dummy (hcd); 1692 dum = hcd_to_dummy (hcd);
1683 1693
1684 device_remove_file (dummy_dev(dum), &dev_attr_urbs); 1694 device_remove_file (dummy_dev(dum), &dev_attr_urbs);
1685
1686 usb_gadget_unregister_driver (dum->driver); 1695 usb_gadget_unregister_driver (dum->driver);
1687 dummy_unregister_udc (dum);
1688
1689 dev_info (dummy_dev(dum), "stopped\n"); 1696 dev_info (dummy_dev(dum), "stopped\n");
1690} 1697}
1691 1698
@@ -1715,7 +1722,7 @@ static const struct hc_driver dummy_hcd = {
1715 .hub_control = dummy_hub_control, 1722 .hub_control = dummy_hub_control,
1716}; 1723};
1717 1724
1718static int dummy_probe (struct device *dev) 1725static int dummy_hcd_probe (struct device *dev)
1719{ 1726{
1720 struct usb_hcd *hcd; 1727 struct usb_hcd *hcd;
1721 int retval; 1728 int retval;
@@ -1735,7 +1742,7 @@ static int dummy_probe (struct device *dev)
1735 return retval; 1742 return retval;
1736} 1743}
1737 1744
1738static void dummy_remove (struct device *dev) 1745static int dummy_hcd_remove (struct device *dev)
1739{ 1746{
1740 struct usb_hcd *hcd; 1747 struct usb_hcd *hcd;
1741 1748
@@ -1743,35 +1750,41 @@ static void dummy_remove (struct device *dev)
1743 usb_remove_hcd (hcd); 1750 usb_remove_hcd (hcd);
1744 usb_put_hcd (hcd); 1751 usb_put_hcd (hcd);
1745 the_controller = NULL; 1752 the_controller = NULL;
1753 return 0;
1746} 1754}
1747 1755
1748/*-------------------------------------------------------------------------*/ 1756static struct device_driver dummy_hcd_driver = {
1749 1757 .name = (char *) driver_name,
1750static int dummy_pdev_detect (void) 1758 .bus = &platform_bus_type,
1751{ 1759 .probe = dummy_hcd_probe,
1752 int retval; 1760 .remove = dummy_hcd_remove,
1753 1761};
1754 retval = driver_register (&dummy_driver);
1755 if (retval < 0)
1756 return retval;
1757 1762
1758 the_pdev.name = "hc"; 1763/*-------------------------------------------------------------------------*/
1759 the_pdev.dev.driver = &dummy_driver;
1760 the_pdev.dev.release = dummy_pdev_release;
1761 1764
1762 retval = platform_device_register (&the_pdev); 1765/* These don't need to do anything because the pdev structures are
1763 if (retval < 0) 1766 * statically allocated. */
1764 driver_unregister (&dummy_driver); 1767static void
1765 return retval; 1768dummy_udc_release (struct device *dev) {}
1766}
1767 1769
1768static void dummy_pdev_remove (void) 1770static void
1769{ 1771dummy_hcd_release (struct device *dev) {}
1770 platform_device_unregister (&the_pdev); 1772
1771 driver_unregister (&dummy_driver); 1773static struct platform_device the_udc_pdev = {
1772} 1774 .name = (char *) gadget_name,
1775 .id = -1,
1776 .dev = {
1777 .release = dummy_udc_release,
1778 },
1779};
1773 1780
1774/*-------------------------------------------------------------------------*/ 1781static struct platform_device the_hcd_pdev = {
1782 .name = (char *) driver_name,
1783 .id = -1,
1784 .dev = {
1785 .release = dummy_hcd_release,
1786 },
1787};
1775 1788
1776static int __init init (void) 1789static int __init init (void)
1777{ 1790{
@@ -1779,17 +1792,39 @@ static int __init init (void)
1779 1792
1780 if (usb_disabled ()) 1793 if (usb_disabled ())
1781 return -ENODEV; 1794 return -ENODEV;
1782 if ((retval = dummy_pdev_detect ()) != 0) 1795
1796 retval = driver_register (&dummy_hcd_driver);
1797 if (retval < 0)
1783 return retval; 1798 return retval;
1784 if ((retval = dummy_probe (&the_pdev.dev)) != 0) 1799
1785 dummy_pdev_remove (); 1800 retval = driver_register (&dummy_udc_driver);
1801 if (retval < 0)
1802 goto err_register_udc_driver;
1803
1804 retval = platform_device_register (&the_hcd_pdev);
1805 if (retval < 0)
1806 goto err_register_hcd;
1807
1808 retval = platform_device_register (&the_udc_pdev);
1809 if (retval < 0)
1810 goto err_register_udc;
1811 return retval;
1812
1813err_register_udc:
1814 platform_device_unregister (&the_hcd_pdev);
1815err_register_hcd:
1816 driver_unregister (&dummy_udc_driver);
1817err_register_udc_driver:
1818 driver_unregister (&dummy_hcd_driver);
1786 return retval; 1819 return retval;
1787} 1820}
1788module_init (init); 1821module_init (init);
1789 1822
1790static void __exit cleanup (void) 1823static void __exit cleanup (void)
1791{ 1824{
1792 dummy_remove (&the_pdev.dev); 1825 platform_device_unregister (&the_udc_pdev);
1793 dummy_pdev_remove (); 1826 platform_device_unregister (&the_hcd_pdev);
1827 driver_unregister (&dummy_udc_driver);
1828 driver_unregister (&dummy_hcd_driver);
1794} 1829}
1795module_exit (cleanup); 1830module_exit (cleanup);