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