diff options
Diffstat (limited to 'drivers/staging/bcm/InterfaceIsr.c')
-rw-r--r-- | drivers/staging/bcm/InterfaceIsr.c | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c new file mode 100644 index 00000000000..f928fe4d564 --- /dev/null +++ b/drivers/staging/bcm/InterfaceIsr.c | |||
@@ -0,0 +1,203 @@ | |||
1 | #include "headers.h" | ||
2 | |||
3 | #ifndef BCM_SHM_INTERFACE | ||
4 | |||
5 | static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) | ||
6 | { | ||
7 | int status = urb->status; | ||
8 | PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context; | ||
9 | PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter ; | ||
10 | |||
11 | if(Adapter->device_removed == TRUE) | ||
12 | { | ||
13 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Device has Got Removed."); | ||
14 | return ; | ||
15 | } | ||
16 | |||
17 | if(((Adapter->bPreparingForLowPowerMode == TRUE) && (Adapter->bDoSuspend == TRUE)) || | ||
18 | psIntfAdapter->bSuspended || | ||
19 | psIntfAdapter->bPreparingForBusSuspend) | ||
20 | { | ||
21 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt call back is called while suspending the device"); | ||
22 | return ; | ||
23 | } | ||
24 | |||
25 | //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "interrupt urb status %d", status); | ||
26 | switch (status) { | ||
27 | /* success */ | ||
28 | case STATUS_SUCCESS: | ||
29 | if ( urb->actual_length ) | ||
30 | { | ||
31 | |||
32 | if(psIntfAdapter->ulInterruptData[1] & 0xFF) | ||
33 | { | ||
34 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Got USIM interrupt"); | ||
35 | } | ||
36 | |||
37 | if(psIntfAdapter->ulInterruptData[1] & 0xFF00) | ||
38 | { | ||
39 | atomic_set(&Adapter->CurrNumFreeTxDesc, | ||
40 | (psIntfAdapter->ulInterruptData[1] & 0xFF00) >> 8); | ||
41 | atomic_set (&Adapter->uiMBupdate, TRUE); | ||
42 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "TX mailbox contains %d", | ||
43 | atomic_read(&Adapter->CurrNumFreeTxDesc)); | ||
44 | } | ||
45 | if(psIntfAdapter->ulInterruptData[1] >> 16) | ||
46 | { | ||
47 | Adapter->CurrNumRecvDescs= | ||
48 | (psIntfAdapter->ulInterruptData[1] >> 16); | ||
49 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"RX mailbox contains %d", | ||
50 | Adapter->CurrNumRecvDescs); | ||
51 | InterfaceRx(psIntfAdapter); | ||
52 | } | ||
53 | if(Adapter->fw_download_done && | ||
54 | !Adapter->downloadDDR && | ||
55 | atomic_read(&Adapter->CurrNumFreeTxDesc)) | ||
56 | { | ||
57 | psIntfAdapter->psAdapter->downloadDDR +=1; | ||
58 | wake_up(&Adapter->tx_packet_wait_queue); | ||
59 | } | ||
60 | if(FALSE == Adapter->waiting_to_fw_download_done) | ||
61 | { | ||
62 | Adapter->waiting_to_fw_download_done = TRUE; | ||
63 | wake_up(&Adapter->ioctl_fw_dnld_wait_queue); | ||
64 | } | ||
65 | if(!atomic_read(&Adapter->TxPktAvail)) | ||
66 | { | ||
67 | atomic_set(&Adapter->TxPktAvail, 1); | ||
68 | wake_up(&Adapter->tx_packet_wait_queue); | ||
69 | } | ||
70 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Firing interrupt in URB"); | ||
71 | } | ||
72 | break; | ||
73 | case -ENOENT : | ||
74 | { | ||
75 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"URB has got disconnected ...."); | ||
76 | return ; | ||
77 | } | ||
78 | case -EINPROGRESS: | ||
79 | { | ||
80 | //This situation may happend when URBunlink is used. for detail check usb_unlink_urb documentation. | ||
81 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Impossibe condition has occured... something very bad is going on"); | ||
82 | break ; | ||
83 | //return; | ||
84 | } | ||
85 | case -EPIPE: | ||
86 | { | ||
87 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"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 | } | ||
93 | /* software-driven interface shutdown */ | ||
94 | case -ECONNRESET: //URB got unlinked. | ||
95 | case -ESHUTDOWN: // hardware gone. this is the serious problem. | ||
96 | //Occurs only when something happens with the host controller device | ||
97 | case -ENODEV : //Device got removed | ||
98 | case -EINVAL : //Some thing very bad happened with the URB. No description is available. | ||
99 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"interrupt urb error %d", status); | ||
100 | urb->status = STATUS_SUCCESS ; | ||
101 | break ; | ||
102 | //return; | ||
103 | default: | ||
104 | //This is required to check what is the defaults conditions when it occurs.. | ||
105 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...", status); | ||
106 | break; | ||
107 | } | ||
108 | |||
109 | StartInterruptUrb(psIntfAdapter); | ||
110 | |||
111 | |||
112 | } | ||
113 | |||
114 | int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter) | ||
115 | { | ||
116 | psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL); | ||
117 | if (!psIntfAdapter->psInterruptUrb) | ||
118 | { | ||
119 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Cannot allocate interrupt urb"); | ||
120 | return -ENOMEM; | ||
121 | } | ||
122 | psIntfAdapter->psInterruptUrb->transfer_buffer = | ||
123 | psIntfAdapter->ulInterruptData; | ||
124 | psIntfAdapter->psInterruptUrb->transfer_buffer_length = | ||
125 | sizeof(psIntfAdapter->ulInterruptData); | ||
126 | |||
127 | psIntfAdapter->sIntrIn.int_in_pipe = usb_rcvintpipe(psIntfAdapter->udev, | ||
128 | psIntfAdapter->sIntrIn.int_in_endpointAddr); | ||
129 | |||
130 | usb_fill_int_urb(psIntfAdapter->psInterruptUrb, psIntfAdapter->udev, | ||
131 | psIntfAdapter->sIntrIn.int_in_pipe, | ||
132 | psIntfAdapter->psInterruptUrb->transfer_buffer, | ||
133 | psIntfAdapter->psInterruptUrb->transfer_buffer_length, | ||
134 | read_int_callback, psIntfAdapter, | ||
135 | psIntfAdapter->sIntrIn.int_in_interval); | ||
136 | |||
137 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt Interval: %d\n", | ||
138 | psIntfAdapter->sIntrIn.int_in_interval); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | |||
143 | INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter) | ||
144 | { | ||
145 | INT status = 0; | ||
146 | |||
147 | if( FALSE == psIntfAdapter->psAdapter->device_removed && | ||
148 | FALSE == psIntfAdapter->psAdapter->bEndPointHalted && | ||
149 | FALSE == psIntfAdapter->bSuspended && | ||
150 | FALSE == psIntfAdapter->bPreparingForBusSuspend && | ||
151 | FALSE == psIntfAdapter->psAdapter->StopAllXaction) | ||
152 | { | ||
153 | status = usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC); | ||
154 | if (status) | ||
155 | { | ||
156 | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Cannot send int urb %d\n", status); | ||
157 | if(status == -EPIPE) | ||
158 | { | ||
159 | psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; | ||
160 | wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | return status; | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | Function: InterfaceEnableInterrupt | ||
169 | |||
170 | Description: This is the hardware specific Function for configuring | ||
171 | and enabling the interrupts on the device. | ||
172 | |||
173 | Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context | ||
174 | |||
175 | |||
176 | Return: BCM_STATUS_SUCCESS - If configuring the interrupts was successful. | ||
177 | Other - If an error occured. | ||
178 | */ | ||
179 | |||
180 | void InterfaceEnableInterrupt(PMINI_ADAPTER Adapter) | ||
181 | { | ||
182 | |||
183 | } | ||
184 | |||
185 | /* | ||
186 | Function: InterfaceDisableInterrupt | ||
187 | |||
188 | Description: This is the hardware specific Function for disabling the interrupts on the device. | ||
189 | |||
190 | Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context | ||
191 | |||
192 | |||
193 | Return: BCM_STATUS_SUCCESS - If disabling the interrupts was successful. | ||
194 | Other - If an error occured. | ||
195 | */ | ||
196 | |||
197 | void InterfaceDisableInterrupt(PMINI_ADAPTER Adapter) | ||
198 | { | ||
199 | |||
200 | } | ||
201 | |||
202 | #endif | ||
203 | |||