InterfaceIsr.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include "headers.h"
  2. static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
  3. {
  4. int status = urb->status;
  5. struct bcm_interface_adapter *psIntfAdapter =
  6. (struct bcm_interface_adapter *)urb->context;
  7. struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter;
  8. if (netif_msg_intr(Adapter))
  9. pr_info(PFX "%s: interrupt status %d\n",
  10. Adapter->dev->name, status);
  11. if (Adapter->device_removed) {
  12. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
  13. DBG_LVL_ALL, "Device has Got Removed.");
  14. return;
  15. }
  16. if ((Adapter->bPreparingForLowPowerMode && Adapter->bDoSuspend) ||
  17. psIntfAdapter->bSuspended ||
  18. psIntfAdapter->bPreparingForBusSuspend) {
  19. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
  20. DBG_LVL_ALL,
  21. "Interrupt call back is called while suspending the device");
  22. return;
  23. }
  24. switch (status) {
  25. /* success */
  26. case STATUS_SUCCESS:
  27. if (urb->actual_length) {
  28. if (psIntfAdapter->ulInterruptData[1] & 0xFF) {
  29. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
  30. INTF_INIT, DBG_LVL_ALL,
  31. "Got USIM interrupt");
  32. }
  33. if (psIntfAdapter->ulInterruptData[1] & 0xFF00) {
  34. atomic_set(&Adapter->CurrNumFreeTxDesc,
  35. (psIntfAdapter->ulInterruptData[1] &
  36. 0xFF00) >> 8);
  37. atomic_set(&Adapter->uiMBupdate, TRUE);
  38. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
  39. INTF_INIT, DBG_LVL_ALL,
  40. "TX mailbox contains %d",
  41. atomic_read(&Adapter->CurrNumFreeTxDesc));
  42. }
  43. if (psIntfAdapter->ulInterruptData[1] >> 16) {
  44. Adapter->CurrNumRecvDescs =
  45. (psIntfAdapter->ulInterruptData[1] >> 16);
  46. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
  47. INTF_INIT, DBG_LVL_ALL,
  48. "RX mailbox contains %d",
  49. Adapter->CurrNumRecvDescs);
  50. InterfaceRx(psIntfAdapter);
  51. }
  52. if (Adapter->fw_download_done &&
  53. !Adapter->downloadDDR &&
  54. atomic_read(&Adapter->CurrNumFreeTxDesc)) {
  55. psIntfAdapter->psAdapter->downloadDDR += 1;
  56. wake_up(&Adapter->tx_packet_wait_queue);
  57. }
  58. if (!Adapter->waiting_to_fw_download_done) {
  59. Adapter->waiting_to_fw_download_done = TRUE;
  60. wake_up(&Adapter->ioctl_fw_dnld_wait_queue);
  61. }
  62. if (!atomic_read(&Adapter->TxPktAvail)) {
  63. atomic_set(&Adapter->TxPktAvail, 1);
  64. wake_up(&Adapter->tx_packet_wait_queue);
  65. }
  66. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
  67. DBG_LVL_ALL, "Firing interrupt in URB");
  68. }
  69. break;
  70. case -ENOENT:
  71. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
  72. DBG_LVL_ALL, "URB has got disconnected....");
  73. return;
  74. case -EINPROGRESS:
  75. /*
  76. * This situation may happened when URBunlink is used. for
  77. * detail check usb_unlink_urb documentation.
  78. */
  79. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
  80. DBG_LVL_ALL,
  81. "Impossibe condition has occurred... something very bad is going on");
  82. break;
  83. /* return; */
  84. case -EPIPE:
  85. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
  86. DBG_LVL_ALL,
  87. "Interrupt IN endPoint has got halted/stalled...need to clear this");
  88. Adapter->bEndPointHalted = TRUE;
  89. wake_up(&Adapter->tx_packet_wait_queue);
  90. urb->status = STATUS_SUCCESS;
  91. return;
  92. /* software-driven interface shutdown */
  93. case -ECONNRESET: /* URB got unlinked */
  94. case -ESHUTDOWN: /* hardware gone. this is the serious problem */
  95. /*
  96. * Occurs only when something happens with the
  97. * host controller device
  98. */
  99. case -ENODEV: /* Device got removed */
  100. case -EINVAL:
  101. /*
  102. * Some thing very bad happened with the URB. No
  103. * description is available.
  104. */
  105. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
  106. DBG_LVL_ALL, "interrupt urb error %d", status);
  107. urb->status = STATUS_SUCCESS;
  108. break;
  109. /* return; */
  110. default:
  111. /*
  112. * This is required to check what is the defaults conditions
  113. * when it occurs..
  114. */
  115. BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,
  116. "GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...",
  117. status);
  118. break;
  119. }
  120. StartInterruptUrb(psIntfAdapter);
  121. }
  122. int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
  123. {
  124. psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL);
  125. if (!psIntfAdapter->psInterruptUrb) {
  126. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS,
  127. INTF_INIT, DBG_LVL_ALL,
  128. "Cannot allocate interrupt urb");
  129. return -ENOMEM;
  130. }
  131. psIntfAdapter->psInterruptUrb->transfer_buffer =
  132. psIntfAdapter->ulInterruptData;
  133. psIntfAdapter->psInterruptUrb->transfer_buffer_length =
  134. sizeof(psIntfAdapter->ulInterruptData);
  135. psIntfAdapter->sIntrIn.int_in_pipe = usb_rcvintpipe(psIntfAdapter->udev,
  136. psIntfAdapter->sIntrIn.int_in_endpointAddr);
  137. usb_fill_int_urb(psIntfAdapter->psInterruptUrb, psIntfAdapter->udev,
  138. psIntfAdapter->sIntrIn.int_in_pipe,
  139. psIntfAdapter->psInterruptUrb->transfer_buffer,
  140. psIntfAdapter->psInterruptUrb->transfer_buffer_length,
  141. read_int_callback, psIntfAdapter,
  142. psIntfAdapter->sIntrIn.int_in_interval);
  143. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, INTF_INIT,
  144. DBG_LVL_ALL, "Interrupt Interval: %d\n",
  145. psIntfAdapter->sIntrIn.int_in_interval);
  146. return 0;
  147. }
  148. INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
  149. {
  150. INT status = 0;
  151. if (!(psIntfAdapter->psAdapter->device_removed ||
  152. psIntfAdapter->psAdapter->bEndPointHalted ||
  153. psIntfAdapter->bSuspended ||
  154. psIntfAdapter->bPreparingForBusSuspend ||
  155. psIntfAdapter->psAdapter->StopAllXaction)) {
  156. status =
  157. usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC);
  158. if (status) {
  159. BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
  160. DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,
  161. "Cannot send inturb %d\n", status);
  162. if (status == -EPIPE) {
  163. psIntfAdapter->psAdapter->bEndPointHalted =
  164. TRUE;
  165. wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
  166. }
  167. }
  168. }
  169. return status;
  170. }