summaryrefslogtreecommitdiffstats
path: root/drivers/staging/bcm/InterfaceIsr.c
diff options
context:
space:
mode:
authorStephen Hemminger2010-09-08 23:46:36 +0200
committerGreg Kroah-Hartman2010-09-09 06:15:06 +0200
commitf8942e07a3db9d82e8fb11d3d494876b8bae9ff9 (patch)
tree2406636a4f9a4ac6b0bfc90e07aefa8b1b18b8ff /drivers/staging/bcm/InterfaceIsr.c
parentStaging: keucr: fix up some coding style issues in the .h files (diff)
downloadkernel-qcow2-linux-f8942e07a3db9d82e8fb11d3d494876b8bae9ff9.tar.gz
kernel-qcow2-linux-f8942e07a3db9d82e8fb11d3d494876b8bae9ff9.tar.xz
kernel-qcow2-linux-f8942e07a3db9d82e8fb11d3d494876b8bae9ff9.zip
staging: Beeceem USB Wimax driver
The Sprint 4G network uses a Wimax dongle with Beecem chipset. The driver is typical of out of tree drivers, but maybe useful for people, and the hardware is readily available. Here is a staging ready version (i.e warts and all) 0. Started with Rel_5.2.7.3P1_USB from Sprint4GDeveloperPack-1.1 1. Consolidated files in staging 2. Remove Dos cr/lf 3. Remove unnecessary ioctl from usbbcm_fops Applied patches that were in the developer pack, surprising there were ones for 2.6.35 already. This is compile tested only, see TODO for what still needs to be done. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
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 000000000000..f928fe4d564d
--- /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
+