summaryrefslogtreecommitdiffstats
path: root/drivers/staging/bcm/InterfaceIsr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/bcm/InterfaceIsr.c')
-rw-r--r--drivers/staging/bcm/InterfaceIsr.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c
new file mode 100644
index 0000000..f928fe4
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceIsr.c
@@ -0,0 +1,203 @@
+#include "headers.h"
+
+#ifndef BCM_SHM_INTERFACE
+
+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(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;
+}
+
+/*
+Function: InterfaceEnableInterrupt
+
+Description: This is the hardware specific Function for configuring
+ and enabling the interrupts on the device.
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+
+
+Return: BCM_STATUS_SUCCESS - If configuring the interrupts was successful.
+ Other - If an error occured.
+*/
+
+void InterfaceEnableInterrupt(PMINI_ADAPTER Adapter)
+{
+
+}
+
+/*
+Function: InterfaceDisableInterrupt
+
+Description: This is the hardware specific Function for disabling the interrupts on the device.
+
+Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
+
+
+Return: BCM_STATUS_SUCCESS - If disabling the interrupts was successful.
+ Other - If an error occured.
+*/
+
+void InterfaceDisableInterrupt(PMINI_ADAPTER Adapter)
+{
+
+}
+
+#endif
+
OpenPOWER on IntegriCloud