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