|  | #include "headers.h" | 
|  |  | 
|  |  | 
|  | static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) | 
|  | { | 
|  | int		status = urb->status; | 
|  | PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context; | 
|  | PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter ; | 
|  |  | 
|  | if (netif_msg_intr(Adapter)) | 
|  | pr_info(PFX "%s: interrupt status %d\n", | 
|  | Adapter->dev->name, status); | 
|  |  | 
|  | if(Adapter->device_removed == TRUE) | 
|  | { | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Device has Got Removed."); | 
|  | return ; | 
|  | } | 
|  |  | 
|  | if(((Adapter->bPreparingForLowPowerMode == TRUE) && (Adapter->bDoSuspend == TRUE)) || | 
|  | psIntfAdapter->bSuspended || | 
|  | psIntfAdapter->bPreparingForBusSuspend) | 
|  | { | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt call back is called while suspending the device"); | 
|  | return ; | 
|  | } | 
|  |  | 
|  | //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "interrupt urb status %d", status); | 
|  | switch (status) { | 
|  | /* success */ | 
|  | case STATUS_SUCCESS: | 
|  | if ( urb->actual_length ) | 
|  | { | 
|  |  | 
|  | if(psIntfAdapter->ulInterruptData[1] & 0xFF) | 
|  | { | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Got USIM interrupt"); | 
|  | } | 
|  |  | 
|  | if(psIntfAdapter->ulInterruptData[1] & 0xFF00) | 
|  | { | 
|  | atomic_set(&Adapter->CurrNumFreeTxDesc, | 
|  | (psIntfAdapter->ulInterruptData[1] & 0xFF00) >> 8); | 
|  | atomic_set (&Adapter->uiMBupdate, TRUE); | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "TX mailbox contains %d", | 
|  | atomic_read(&Adapter->CurrNumFreeTxDesc)); | 
|  | } | 
|  | if(psIntfAdapter->ulInterruptData[1] >> 16) | 
|  | { | 
|  | Adapter->CurrNumRecvDescs= | 
|  | (psIntfAdapter->ulInterruptData[1]  >> 16); | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"RX mailbox contains %d", | 
|  | Adapter->CurrNumRecvDescs); | 
|  | InterfaceRx(psIntfAdapter); | 
|  | } | 
|  | if(Adapter->fw_download_done && | 
|  | !Adapter->downloadDDR && | 
|  | atomic_read(&Adapter->CurrNumFreeTxDesc)) | 
|  | { | 
|  | psIntfAdapter->psAdapter->downloadDDR +=1; | 
|  | wake_up(&Adapter->tx_packet_wait_queue); | 
|  | } | 
|  | if(FALSE == Adapter->waiting_to_fw_download_done) | 
|  | { | 
|  | Adapter->waiting_to_fw_download_done = TRUE; | 
|  | wake_up(&Adapter->ioctl_fw_dnld_wait_queue); | 
|  | } | 
|  | if(!atomic_read(&Adapter->TxPktAvail)) | 
|  | { | 
|  | atomic_set(&Adapter->TxPktAvail, 1); | 
|  | wake_up(&Adapter->tx_packet_wait_queue); | 
|  | } | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Firing interrupt in URB"); | 
|  | } | 
|  | break; | 
|  | case -ENOENT : | 
|  | { | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"URB has got disconnected ...."); | 
|  | return ; | 
|  | } | 
|  | case -EINPROGRESS: | 
|  | { | 
|  | //This situation may happend when URBunlink is used. for detail check usb_unlink_urb documentation. | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Impossibe condition has occured... something very bad is going on"); | 
|  | break ; | 
|  | //return; | 
|  | } | 
|  | case -EPIPE: | 
|  | { | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt IN endPoint  has got halted/stalled...need to clear this"); | 
|  | Adapter->bEndPointHalted = TRUE ; | 
|  | wake_up(&Adapter->tx_packet_wait_queue); | 
|  | urb->status = STATUS_SUCCESS ; | 
|  | return; | 
|  | } | 
|  | /* software-driven interface shutdown */ | 
|  | case -ECONNRESET: //URB got unlinked. | 
|  | case -ESHUTDOWN:		// hardware gone. this is the serious problem. | 
|  | //Occurs only when something happens with the host controller device | 
|  | case -ENODEV : //Device got removed | 
|  | case -EINVAL : //Some thing very bad happened with the URB. No description is available. | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"interrupt urb error %d", status); | 
|  | urb->status = STATUS_SUCCESS ; | 
|  | break ; | 
|  | //return; | 
|  | default: | 
|  | //This is required to check what is the defaults conditions when it occurs.. | 
|  | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"GOT DEFAULT INTERRUPT URB STATUS :%d..Please Analyze it...", status); | 
|  | break; | 
|  | } | 
|  |  | 
|  | StartInterruptUrb(psIntfAdapter); | 
|  |  | 
|  |  | 
|  | } | 
|  |  | 
|  | int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter) | 
|  | { | 
|  | psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL); | 
|  | if (!psIntfAdapter->psInterruptUrb) | 
|  | { | 
|  | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Cannot allocate interrupt urb"); | 
|  | return -ENOMEM; | 
|  | } | 
|  | psIntfAdapter->psInterruptUrb->transfer_buffer = | 
|  | psIntfAdapter->ulInterruptData; | 
|  | psIntfAdapter->psInterruptUrb->transfer_buffer_length = | 
|  | sizeof(psIntfAdapter->ulInterruptData); | 
|  |  | 
|  | psIntfAdapter->sIntrIn.int_in_pipe = usb_rcvintpipe(psIntfAdapter->udev, | 
|  | psIntfAdapter->sIntrIn.int_in_endpointAddr); | 
|  |  | 
|  | usb_fill_int_urb(psIntfAdapter->psInterruptUrb, psIntfAdapter->udev, | 
|  | psIntfAdapter->sIntrIn.int_in_pipe, | 
|  | psIntfAdapter->psInterruptUrb->transfer_buffer, | 
|  | psIntfAdapter->psInterruptUrb->transfer_buffer_length, | 
|  | read_int_callback, psIntfAdapter, | 
|  | psIntfAdapter->sIntrIn.int_in_interval); | 
|  |  | 
|  | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt Interval: %d\n", | 
|  | psIntfAdapter->sIntrIn.int_in_interval); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter) | 
|  | { | 
|  | INT status = 0; | 
|  |  | 
|  | if( FALSE == psIntfAdapter->psAdapter->device_removed && | 
|  | FALSE == psIntfAdapter->psAdapter->bEndPointHalted && | 
|  | FALSE == psIntfAdapter->bSuspended && | 
|  | FALSE == psIntfAdapter->bPreparingForBusSuspend && | 
|  | FALSE == psIntfAdapter->psAdapter->StopAllXaction) | 
|  | { | 
|  | status = usb_submit_urb(psIntfAdapter->psInterruptUrb, GFP_ATOMIC); | 
|  | if (status) | 
|  | { | 
|  | BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Cannot send int urb %d\n", status); | 
|  | if(status == -EPIPE) | 
|  | { | 
|  | psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; | 
|  | wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); | 
|  | } | 
|  | } | 
|  | } | 
|  | return status; | 
|  | } | 
|  |  |