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