1#include "headers.h" 2 3 4static 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 117int 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 146INT 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