1 #include "headers.h"
2
3
read_int_callback(struct urb * urb)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 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");
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
CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)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
StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)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
170