4 static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
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;
11 if (netif_msg_intr(Adapter))
12 pr_info(PFX "%s: interrupt status %d\n",
13 Adapter->dev->name, status);
15 if (Adapter->device_removed) {
16 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
17 DBG_LVL_ALL, "Device has Got Removed.");
21 if ((Adapter->bPreparingForLowPowerMode && Adapter->bDoSuspend) ||
22 psIntfAdapter->bSuspended ||
23 psIntfAdapter->bPreparingForBusSuspend) {
24 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
26 "Interrupt call back is called while suspending the device");
33 if (urb->actual_length) {
35 if (psIntfAdapter->ulInterruptData[1] & 0xFF) {
36 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
37 INTF_INIT, DBG_LVL_ALL,
38 "Got USIM interrupt");
41 if (psIntfAdapter->ulInterruptData[1] & 0xFF00) {
42 atomic_set(&Adapter->CurrNumFreeTxDesc,
43 (psIntfAdapter->ulInterruptData[1] &
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));
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);
60 if (Adapter->fw_download_done &&
61 !Adapter->downloadDDR &&
62 atomic_read(&Adapter->CurrNumFreeTxDesc)) {
64 psIntfAdapter->psAdapter->downloadDDR += 1;
65 wake_up(&Adapter->tx_packet_wait_queue);
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);
71 if (!atomic_read(&Adapter->TxPktAvail)) {
72 atomic_set(&Adapter->TxPktAvail, 1);
73 wake_up(&Adapter->tx_packet_wait_queue);
75 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
76 DBG_LVL_ALL, "Firing interrupt in URB");
80 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
81 DBG_LVL_ALL, "URB has got disconnected....");
85 * This situation may happened when URBunlink is used. for
86 * detail check usb_unlink_urb documentation.
88 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
90 "Impossibe condition has occurred... something very bad is going on");
94 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
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;
101 /* software-driven interface shutdown */
102 case -ECONNRESET: /* URB got unlinked */
103 case -ESHUTDOWN: /* hardware gone. this is the serious problem */
105 * Occurs only when something happens with the
106 * host controller device
108 case -ENODEV: /* Device got removed */
111 * Some thing very bad happened with the URB. No
112 * description is available.
114 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
115 DBG_LVL_ALL, "interrupt urb error %d", status);
116 urb->status = STATUS_SUCCESS;
121 * This is required to check what is the defaults conditions
124 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,
125 "GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...",
130 StartInterruptUrb(psIntfAdapter);
135 int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
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");
144 psIntfAdapter->psInterruptUrb->transfer_buffer =
145 psIntfAdapter->ulInterruptData;
146 psIntfAdapter->psInterruptUrb->transfer_buffer_length =
147 sizeof(psIntfAdapter->ulInterruptData);
149 psIntfAdapter->sIntrIn.int_in_pipe = usb_rcvintpipe(psIntfAdapter->udev,
150 psIntfAdapter->sIntrIn.int_in_endpointAddr);
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);
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);
166 INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter)
170 if (!(psIntfAdapter->psAdapter->device_removed ||
171 psIntfAdapter->psAdapter->bEndPointHalted ||
172 psIntfAdapter->bSuspended ||
173 psIntfAdapter->bPreparingForBusSuspend ||
174 psIntfAdapter->psAdapter->StopAllXaction)) {
176 usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC);
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 =
184 wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);