summaryrefslogtreecommitdiff
path: root/drivers/staging/bcm/InterfaceIsr.c
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
committerYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
commit8e4bff4cab0ddac6060645b0715210484d02ff40 (patch)
tree3a5c3024371a04692a3a6d9974d001cdff8ebf84 /drivers/staging/bcm/InterfaceIsr.c
Initial file dump from open source releaseHEADmaster
Diffstat (limited to 'drivers/staging/bcm/InterfaceIsr.c')
-rw-r--r--drivers/staging/bcm/InterfaceIsr.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c
new file mode 100644
index 00000000..8322f1b7
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceIsr.c
@@ -0,0 +1,169 @@
+#include "headers.h"
+
+
+static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
+{
+ int status = urb->status;
+ struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)urb->context;
+ struct bcm_mini_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 happened 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 occurred... 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(struct bcm_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(struct bcm_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;
+}
+