Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / bcm / InterfaceIsr.c
1 #include "headers.h"
2
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
10         if (netif_msg_intr(Adapter))
11                 pr_info(PFX "%s: interrupt status %d\n",
12                         Adapter->dev->name, status);
13
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                 {
83                         //This situation may happend 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 occured... something very bad is going on");
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);
93                                 urb->status = STATUS_SUCCESS ;
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