aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/dummy_hcd.c254
1 files changed, 162 insertions, 92 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index dc0e3233b0e9..2d6d22951326 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -163,12 +163,16 @@ struct dummy {
163 struct dummy_request fifo_req; 163 struct dummy_request fifo_req;
164 u8 fifo_buf [FIFO_SIZE]; 164 u8 fifo_buf [FIFO_SIZE];
165 u16 devstatus; 165 u16 devstatus;
166 unsigned pullup:1;
167 unsigned active:1;
168 unsigned old_active:1;
166 169
167 /* 170 /*
168 * MASTER/HOST side support 171 * MASTER/HOST side support
169 */ 172 */
170 struct timer_list timer; 173 struct timer_list timer;
171 u32 port_status; 174 u32 port_status;
175 u32 old_status;
172 unsigned resuming:1; 176 unsigned resuming:1;
173 unsigned long re_timeout; 177 unsigned long re_timeout;
174 178
@@ -215,6 +219,98 @@ static struct dummy *the_controller;
215 219
216/*-------------------------------------------------------------------------*/ 220/*-------------------------------------------------------------------------*/
217 221
222/* SLAVE/GADGET SIDE UTILITY ROUTINES */
223
224/* called with spinlock held */
225static void nuke (struct dummy *dum, struct dummy_ep *ep)
226{
227 while (!list_empty (&ep->queue)) {
228 struct dummy_request *req;
229
230 req = list_entry (ep->queue.next, struct dummy_request, queue);
231 list_del_init (&req->queue);
232 req->req.status = -ESHUTDOWN;
233
234 spin_unlock (&dum->lock);
235 req->req.complete (&ep->ep, &req->req);
236 spin_lock (&dum->lock);
237 }
238}
239
240/* caller must hold lock */
241static void
242stop_activity (struct dummy *dum)
243{
244 struct dummy_ep *ep;
245
246 /* prevent any more requests */
247 dum->address = 0;
248
249 /* The timer is left running so that outstanding URBs can fail */
250
251 /* nuke any pending requests first, so driver i/o is quiesced */
252 list_for_each_entry (ep, &dum->gadget.ep_list, ep.ep_list)
253 nuke (dum, ep);
254
255 /* driver now does any non-usb quiescing necessary */
256}
257
258/* caller must hold lock */
259static void
260set_link_state (struct dummy *dum)
261{
262 dum->active = 0;
263 if ((dum->port_status & USB_PORT_STAT_POWER) == 0)
264 dum->port_status = 0;
265 else if (!dum->pullup) {
266 dum->port_status &= ~(USB_PORT_STAT_CONNECTION |
267 USB_PORT_STAT_ENABLE |
268 USB_PORT_STAT_LOW_SPEED |
269 USB_PORT_STAT_HIGH_SPEED |
270 USB_PORT_STAT_SUSPEND);
271 if ((dum->old_status & USB_PORT_STAT_CONNECTION) != 0)
272 dum->port_status |= (USB_PORT_STAT_C_CONNECTION << 16);
273 } else {
274 dum->port_status |= USB_PORT_STAT_CONNECTION;
275 if ((dum->old_status & USB_PORT_STAT_CONNECTION) == 0)
276 dum->port_status |= (USB_PORT_STAT_C_CONNECTION << 16);
277 if ((dum->port_status & USB_PORT_STAT_ENABLE) == 0)
278 dum->port_status &= ~USB_PORT_STAT_SUSPEND;
279 else if ((dum->port_status & USB_PORT_STAT_SUSPEND) == 0)
280 dum->active = 1;
281 }
282
283 if ((dum->port_status & USB_PORT_STAT_ENABLE) == 0 || dum->active)
284 dum->resuming = 0;
285
286 if ((dum->port_status & USB_PORT_STAT_CONNECTION) == 0 ||
287 (dum->port_status & USB_PORT_STAT_RESET) != 0) {
288 if ((dum->old_status & USB_PORT_STAT_CONNECTION) != 0 &&
289 (dum->old_status & USB_PORT_STAT_RESET) == 0 &&
290 dum->driver) {
291 stop_activity (dum);
292 spin_unlock (&dum->lock);
293 dum->driver->disconnect (&dum->gadget);
294 spin_lock (&dum->lock);
295 }
296 } else if (dum->active != dum->old_active) {
297 if (dum->old_active && dum->driver->suspend) {
298 spin_unlock (&dum->lock);
299 dum->driver->suspend (&dum->gadget);
300 spin_lock (&dum->lock);
301 } else if (!dum->old_active && dum->driver->resume) {
302 spin_unlock (&dum->lock);
303 dum->driver->resume (&dum->gadget);
304 spin_lock (&dum->lock);
305 }
306 }
307
308 dum->old_status = dum->port_status;
309 dum->old_active = dum->active;
310}
311
312/*-------------------------------------------------------------------------*/
313
218/* SLAVE/GADGET SIDE DRIVER 314/* SLAVE/GADGET SIDE DRIVER
219 * 315 *
220 * This only tracks gadget state. All the work is done when the host 316 * This only tracks gadget state. All the work is done when the host
@@ -339,22 +435,6 @@ done:
339 return retval; 435 return retval;
340} 436}
341 437
342/* called with spinlock held */
343static void nuke (struct dummy *dum, struct dummy_ep *ep)
344{
345 while (!list_empty (&ep->queue)) {
346 struct dummy_request *req;
347
348 req = list_entry (ep->queue.next, struct dummy_request, queue);
349 list_del_init (&req->queue);
350 req->req.status = -ESHUTDOWN;
351
352 spin_unlock (&dum->lock);
353 req->req.complete (&ep->ep, &req->req);
354 spin_lock (&dum->lock);
355 }
356}
357
358static int dummy_disable (struct usb_ep *_ep) 438static int dummy_disable (struct usb_ep *_ep)
359{ 439{
360 struct dummy_ep *ep; 440 struct dummy_ep *ep;
@@ -603,7 +683,7 @@ static int dummy_wakeup (struct usb_gadget *_gadget)
603 683
604 /* hub notices our request, issues downstream resume, etc */ 684 /* hub notices our request, issues downstream resume, etc */
605 dum->resuming = 1; 685 dum->resuming = 1;
606 dum->port_status |= (USB_PORT_STAT_C_SUSPEND << 16); 686 dum->re_timeout = jiffies + msecs_to_jiffies(20);
607 return 0; 687 return 0;
608} 688}
609 689
@@ -619,10 +699,24 @@ static int dummy_set_selfpowered (struct usb_gadget *_gadget, int value)
619 return 0; 699 return 0;
620} 700}
621 701
702static int dummy_pullup (struct usb_gadget *_gadget, int value)
703{
704 struct dummy *dum;
705 unsigned long flags;
706
707 dum = gadget_to_dummy (_gadget);
708 spin_lock_irqsave (&dum->lock, flags);
709 dum->pullup = (value != 0);
710 set_link_state (dum);
711 spin_unlock_irqrestore (&dum->lock, flags);
712 return 0;
713}
714
622static const struct usb_gadget_ops dummy_ops = { 715static const struct usb_gadget_ops dummy_ops = {
623 .get_frame = dummy_g_get_frame, 716 .get_frame = dummy_g_get_frame,
624 .wakeup = dummy_wakeup, 717 .wakeup = dummy_wakeup,
625 .set_selfpowered = dummy_set_selfpowered, 718 .set_selfpowered = dummy_set_selfpowered,
719 .pullup = dummy_pullup,
626}; 720};
627 721
628/*-------------------------------------------------------------------------*/ 722/*-------------------------------------------------------------------------*/
@@ -675,7 +769,6 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
675 */ 769 */
676 770
677 dum->devstatus = 0; 771 dum->devstatus = 0;
678 dum->resuming = 0;
679 772
680 INIT_LIST_HEAD (&dum->gadget.ep_list); 773 INIT_LIST_HEAD (&dum->gadget.ep_list);
681 for (i = 0; i < DUMMY_ENDPOINTS; i++) { 774 for (i = 0; i < DUMMY_ENDPOINTS; i++) {
@@ -714,35 +807,14 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
714 device_bind_driver (&dum->gadget.dev); 807 device_bind_driver (&dum->gadget.dev);
715 808
716 /* khubd will enumerate this in a while */ 809 /* khubd will enumerate this in a while */
717 dum->port_status |= USB_PORT_STAT_CONNECTION 810 spin_lock_irq (&dum->lock);
718 | (USB_PORT_STAT_C_CONNECTION << 16); 811 dum->pullup = 1;
812 set_link_state (dum);
813 spin_unlock_irq (&dum->lock);
719 return 0; 814 return 0;
720} 815}
721EXPORT_SYMBOL (usb_gadget_register_driver); 816EXPORT_SYMBOL (usb_gadget_register_driver);
722 817
723/* caller must hold lock */
724static void
725stop_activity (struct dummy *dum, struct usb_gadget_driver *driver)
726{
727 struct dummy_ep *ep;
728
729 /* prevent any more requests */
730 dum->address = 0;
731
732 /* The timer is left running so that outstanding URBs can fail */
733
734 /* nuke any pending requests first, so driver i/o is quiesced */
735 list_for_each_entry (ep, &dum->gadget.ep_list, ep.ep_list)
736 nuke (dum, ep);
737
738 /* driver now does any non-usb quiescing necessary */
739 if (driver) {
740 spin_unlock (&dum->lock);
741 driver->disconnect (&dum->gadget);
742 spin_lock (&dum->lock);
743 }
744}
745
746int 818int
747usb_gadget_unregister_driver (struct usb_gadget_driver *driver) 819usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
748{ 820{
@@ -758,10 +830,8 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
758 driver->driver.name); 830 driver->driver.name);
759 831
760 spin_lock_irqsave (&dum->lock, flags); 832 spin_lock_irqsave (&dum->lock, flags);
761 stop_activity (dum, driver); 833 dum->pullup = 0;
762 dum->port_status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE | 834 set_link_state (dum);
763 USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
764 dum->port_status |= (USB_PORT_STAT_C_CONNECTION << 16);
765 spin_unlock_irqrestore (&dum->lock, flags); 835 spin_unlock_irqrestore (&dum->lock, flags);
766 836
767 driver->unbind (&dum->gadget); 837 driver->unbind (&dum->gadget);
@@ -770,6 +840,11 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
770 device_release_driver (&dum->gadget.dev); 840 device_release_driver (&dum->gadget.dev);
771 driver_unregister (&driver->driver); 841 driver_unregister (&driver->driver);
772 842
843 spin_lock_irqsave (&dum->lock, flags);
844 dum->pullup = 0;
845 set_link_state (dum);
846 spin_unlock_irqrestore (&dum->lock, flags);
847
773 return 0; 848 return 0;
774} 849}
775EXPORT_SYMBOL (usb_gadget_unregister_driver); 850EXPORT_SYMBOL (usb_gadget_unregister_driver);
@@ -1432,6 +1507,13 @@ static int dummy_hub_status (struct usb_hcd *hcd, char *buf)
1432 dum = hcd_to_dummy (hcd); 1507 dum = hcd_to_dummy (hcd);
1433 1508
1434 spin_lock_irqsave (&dum->lock, flags); 1509 spin_lock_irqsave (&dum->lock, flags);
1510
1511 if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) {
1512 dum->port_status |= (USB_PORT_STAT_C_SUSPEND << 16);
1513 dum->port_status &= ~USB_PORT_STAT_SUSPEND;
1514 set_link_state (dum);
1515 }
1516
1435 if (!(dum->port_status & PORT_C_MASK)) 1517 if (!(dum->port_status & PORT_C_MASK))
1436 retval = 0; 1518 retval = 0;
1437 else { 1519 else {
@@ -1480,16 +1562,16 @@ static int dummy_hub_control (
1480 /* 20msec resume signaling */ 1562 /* 20msec resume signaling */
1481 dum->resuming = 1; 1563 dum->resuming = 1;
1482 dum->re_timeout = jiffies + 1564 dum->re_timeout = jiffies +
1483 msecs_to_jiffies(20); 1565 msecs_to_jiffies(20);
1484 } 1566 }
1485 break; 1567 break;
1486 case USB_PORT_FEAT_POWER: 1568 case USB_PORT_FEAT_POWER:
1487 dum->port_status = 0; 1569 if (dum->port_status & USB_PORT_STAT_POWER)
1488 dum->resuming = 0; 1570 dev_dbg (dummy_dev(dum), "power-off\n");
1489 stop_activity(dum, dum->driver); 1571 /* FALLS THROUGH */
1490 break;
1491 default: 1572 default:
1492 dum->port_status &= ~(1 << wValue); 1573 dum->port_status &= ~(1 << wValue);
1574 set_link_state (dum);
1493 } 1575 }
1494 break; 1576 break;
1495 case GetHubDescriptor: 1577 case GetHubDescriptor:
@@ -1505,23 +1587,16 @@ static int dummy_hub_control (
1505 /* whoever resets or resumes must GetPortStatus to 1587 /* whoever resets or resumes must GetPortStatus to
1506 * complete it!! 1588 * complete it!!
1507 */ 1589 */
1508 if (dum->resuming && time_after (jiffies, dum->re_timeout)) { 1590 if (dum->resuming &&
1591 time_after_eq (jiffies, dum->re_timeout)) {
1509 dum->port_status |= (USB_PORT_STAT_C_SUSPEND << 16); 1592 dum->port_status |= (USB_PORT_STAT_C_SUSPEND << 16);
1510 dum->port_status &= ~USB_PORT_STAT_SUSPEND; 1593 dum->port_status &= ~USB_PORT_STAT_SUSPEND;
1511 dum->resuming = 0;
1512 dum->re_timeout = 0;
1513 if (dum->driver && dum->driver->resume) {
1514 spin_unlock (&dum->lock);
1515 dum->driver->resume (&dum->gadget);
1516 spin_lock (&dum->lock);
1517 }
1518 } 1594 }
1519 if ((dum->port_status & USB_PORT_STAT_RESET) != 0 1595 if ((dum->port_status & USB_PORT_STAT_RESET) != 0 &&
1520 && time_after (jiffies, dum->re_timeout)) { 1596 time_after_eq (jiffies, dum->re_timeout)) {
1521 dum->port_status |= (USB_PORT_STAT_C_RESET << 16); 1597 dum->port_status |= (USB_PORT_STAT_C_RESET << 16);
1522 dum->port_status &= ~USB_PORT_STAT_RESET; 1598 dum->port_status &= ~USB_PORT_STAT_RESET;
1523 dum->re_timeout = 0; 1599 if (dum->pullup) {
1524 if (dum->driver) {
1525 dum->port_status |= USB_PORT_STAT_ENABLE; 1600 dum->port_status |= USB_PORT_STAT_ENABLE;
1526 /* give it the best speed we agree on */ 1601 /* give it the best speed we agree on */
1527 dum->gadget.speed = dum->driver->speed; 1602 dum->gadget.speed = dum->driver->speed;
@@ -1542,6 +1617,7 @@ static int dummy_hub_control (
1542 } 1617 }
1543 } 1618 }
1544 } 1619 }
1620 set_link_state (dum);
1545 ((u16 *) buf)[0] = cpu_to_le16 (dum->port_status); 1621 ((u16 *) buf)[0] = cpu_to_le16 (dum->port_status);
1546 ((u16 *) buf)[1] = cpu_to_le16 (dum->port_status >> 16); 1622 ((u16 *) buf)[1] = cpu_to_le16 (dum->port_status >> 16);
1547 break; 1623 break;
@@ -1551,42 +1627,36 @@ static int dummy_hub_control (
1551 case SetPortFeature: 1627 case SetPortFeature:
1552 switch (wValue) { 1628 switch (wValue) {
1553 case USB_PORT_FEAT_SUSPEND: 1629 case USB_PORT_FEAT_SUSPEND:
1554 if ((dum->port_status & USB_PORT_STAT_SUSPEND) 1630 if (dum->active) {
1555 == 0) {
1556 dum->port_status |= USB_PORT_STAT_SUSPEND; 1631 dum->port_status |= USB_PORT_STAT_SUSPEND;
1557 if (dum->driver && dum->driver->suspend) { 1632
1558 spin_unlock (&dum->lock); 1633 /* HNP would happen here; for now we
1559 dum->driver->suspend (&dum->gadget); 1634 * assume b_bus_req is always true.
1560 spin_lock (&dum->lock); 1635 */
1561 /* HNP would happen here; for now we 1636 set_link_state (dum);
1562 * assume b_bus_req is always true. 1637 if (((1 << USB_DEVICE_B_HNP_ENABLE)
1563 */ 1638 & dum->devstatus) != 0)
1564 if (((1 << USB_DEVICE_B_HNP_ENABLE) 1639 dev_dbg (dummy_dev(dum),
1565 & dum->devstatus) != 0)
1566 dev_dbg (dummy_dev(dum),
1567 "no HNP yet!\n"); 1640 "no HNP yet!\n");
1568 }
1569 } 1641 }
1570 break; 1642 break;
1643 case USB_PORT_FEAT_POWER:
1644 dum->port_status |= USB_PORT_STAT_POWER;
1645 set_link_state (dum);
1646 break;
1571 case USB_PORT_FEAT_RESET: 1647 case USB_PORT_FEAT_RESET:
1572 /* if it's already running, disconnect first */ 1648 /* if it's already enabled, disable */
1573 if (dum->port_status & USB_PORT_STAT_ENABLE) { 1649 dum->port_status &= ~(USB_PORT_STAT_ENABLE
1574 dum->port_status &= ~(USB_PORT_STAT_ENABLE 1650 | USB_PORT_STAT_LOW_SPEED
1575 | USB_PORT_STAT_LOW_SPEED 1651 | USB_PORT_STAT_HIGH_SPEED);
1576 | USB_PORT_STAT_HIGH_SPEED);
1577 if (dum->driver) {
1578 dev_dbg (udc_dev(dum),
1579 "disconnect\n");
1580 stop_activity (dum, dum->driver);
1581 }
1582
1583 /* FIXME test that code path! */
1584 }
1585 /* 50msec reset signaling */ 1652 /* 50msec reset signaling */
1586 dum->re_timeout = jiffies + msecs_to_jiffies(50); 1653 dum->re_timeout = jiffies + msecs_to_jiffies(50);
1587 /* FALLTHROUGH */ 1654 /* FALLS THROUGH */
1588 default: 1655 default:
1589 dum->port_status |= (1 << wValue); 1656 if ((dum->port_status & USB_PORT_STAT_POWER) != 0) {
1657 dum->port_status |= (1 << wValue);
1658 set_link_state (dum);
1659 }
1590 } 1660 }
1591 break; 1661 break;
1592 1662