usb_recv.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Generic receive layer for the PXA USB client function
  3.  *
  4.  * This code was loosely inspired by the original version which was
  5.  * Copyright (c) Compaq Computer Corporation, 1998-1999
  6.  * Copyright (c) 2001 by Nicolas Pitre
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License version 2 as
  10.  * published by the Free Software Foundation.
  11.  *
  12.  * 02-May-2002
  13.  *   Frank Becker (Intrinsyc) - derived from sa1100 usb_recv.c
  14.  * 
  15.  * TODO: Add support for DMA.
  16.  *
  17.  */
  18. #include <linux/module.h>
  19. #include <linux/pci.h>
  20. #include <linux/errno.h>
  21. #include <asm/dma.h>
  22. #include <asm/system.h>
  23. #include "pxa_usb.h"
  24. #include "usb_ctl.h"
  25. #if DEBUG
  26. static unsigned int usb_debug = DEBUG;
  27. #else
  28. #define usb_debug 0     /* gcc will remove all the debug code for us */
  29. #endif
  30. static char *ep_bulk_out1_buf;
  31. static int   ep_bulk_out1_len;
  32. static int   ep_bulk_out1_remain;
  33. static usb_callback_t ep_bulk_out1_callback;
  34. static int rx_pktsize;
  35. static void
  36. ep_bulk_out1_start(void)
  37. {
  38. /* disable DMA */
  39. UDCCS2 &= ~UDCCS_BO_DME;
  40. /* enable interrupts for endpoint 2 (bulk out) */
  41.         UICR0 &= ~UICR0_IM2;
  42. }
  43. static void
  44. ep_bulk_out1_done(int flag)
  45. {
  46. int size = ep_bulk_out1_len - ep_bulk_out1_remain;
  47. if (!ep_bulk_out1_len)
  48. return;
  49. ep_bulk_out1_len = 0;
  50. if (ep_bulk_out1_callback) {
  51. ep_bulk_out1_callback(flag, size);
  52. }
  53. }
  54. void
  55. ep_bulk_out1_state_change_notify( int new_state )
  56. {
  57. }
  58. void
  59. ep_bulk_out1_stall( void )
  60. {
  61. /* SET_FEATURE force stall at UDC */
  62. UDCCS2 |= UDCCS_BO_FST;
  63. }
  64. int
  65. ep_bulk_out1_init(int chn)
  66. {
  67. desc_t * pd = pxa_usb_get_descriptor_ptr();
  68. rx_pktsize = __le16_to_cpu( pd->b.ep1.wMaxPacketSize );
  69. ep_bulk_out1_done(-EAGAIN);
  70. return 0;
  71. }
  72. void
  73. ep_bulk_out1_reset(void)
  74. {
  75. desc_t * pd = pxa_usb_get_descriptor_ptr();
  76. rx_pktsize = __le16_to_cpu( pd->b.ep1.wMaxPacketSize );
  77. UDCCS2 &= ~UDCCS_BO_FST;
  78. ep_bulk_out1_done(-EINTR);
  79. }
  80. void
  81. ep_bulk_out1_int_hndlr(int udcsr)
  82. {
  83. int status = UDCCS2;
  84. if( usb_debug) printk("ep_bulk_out1_int_hndlr: UDCCS2=%xn", status);
  85. if( (status & (UDCCS_BO_RNE | UDCCS_BO_RSP)) == UDCCS_BO_RSP)
  86. {
  87. /* zero-length packet */
  88. }
  89. if( status & UDCCS_BO_RNE)
  90. {
  91. int len;
  92. int i;
  93. char *buf = ep_bulk_out1_buf + ep_bulk_out1_len - ep_bulk_out1_remain;
  94. /* bytes in FIFO */
  95. len = (UBCR2 & 0xff) +1;
  96. if( usb_debug) printk("usb_recv: "
  97. "len=%d out1_len=%d out1_remain=%dn",
  98. len,ep_bulk_out1_len,ep_bulk_out1_remain);
  99. if( len > ep_bulk_out1_remain)
  100. {
  101. /* FIXME: if this happens, we need a temporary overflow buffer */
  102. printk("usb_recv: Buffer overwrite warning...n");
  103. len = ep_bulk_out1_remain;
  104. }
  105. /* read data out of fifo */
  106. for( i=0; i<len; i++)
  107. {
  108. *buf++ = UDDR2 & 0xff;
  109. }
  110. ep_bulk_out1_remain -= len;
  111. ep_bulk_out1_done((len) ? 0 : -EPIPE);
  112. }
  113. /* ack RPC - FIXME: '|=' we may ack SST here, too */
  114. UDCCS2 |= UDCCS_BO_RPC;
  115. return;
  116. }
  117. int
  118. pxa_usb_recv(char *buf, int len, usb_callback_t callback)
  119. {
  120. int flags;
  121. if (ep_bulk_out1_len)
  122. return -EBUSY;
  123. local_irq_save(flags);
  124. ep_bulk_out1_buf = buf;
  125. ep_bulk_out1_len = len;
  126. ep_bulk_out1_callback = callback;
  127. ep_bulk_out1_remain = len;
  128. ep_bulk_out1_start();
  129. local_irq_restore(flags);
  130. return 0;
  131. }
  132. void
  133. pxa_usb_recv_reset(void)
  134. {
  135. ep_bulk_out1_reset();
  136. }
  137. void
  138. pxa_usb_recv_stall(void)
  139. {
  140. ep_bulk_out1_stall();
  141. }
  142. EXPORT_SYMBOL(pxa_usb_recv_stall);
  143. EXPORT_SYMBOL(pxa_usb_recv);
  144. EXPORT_SYMBOL(pxa_usb_recv_reset);