summaryrefslogtreecommitdiffstats
path: root/drivers/staging/bcm/InterfaceMisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/bcm/InterfaceMisc.c')
-rw-r--r--drivers/staging/bcm/InterfaceMisc.c290
1 files changed, 290 insertions, 0 deletions
diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c
new file mode 100644
index 0000000..8fc893b
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceMisc.c
@@ -0,0 +1,290 @@
+#include "headers.h"
+
+#ifndef BCM_SHM_INTERFACE
+
+PS_INTERFACE_ADAPTER
+InterfaceAdapterGet(PMINI_ADAPTER psAdapter)
+{
+ if(psAdapter == NULL)
+ {
+ return NULL;
+ }
+ return (PS_INTERFACE_ADAPTER)(psAdapter->pvInterfaceAdapter);
+}
+
+INT
+InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
+ UINT addr,
+ PVOID buff,
+ INT len)
+{
+ int retval = 0;
+ USHORT usRetries = 0 ;
+ if(psIntfAdapter == NULL )
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Interface Adapter is NULL");
+ return -EINVAL ;
+ }
+
+ if(psIntfAdapter->psAdapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed");
+ return -ENODEV;
+ }
+
+ if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB))
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus");
+ return -EACCES;
+ }
+
+ if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed..");
+ return -EACCES;
+ }
+ psIntfAdapter->psAdapter->DeviceAccess = TRUE ;
+ do {
+ retval = usb_control_msg(psIntfAdapter->udev,
+ usb_rcvctrlpipe(psIntfAdapter->udev,0),
+ 0x02,
+ 0xC2,
+ (addr & 0xFFFF),
+ ((addr >> 16) & 0xFFFF),
+ buff,
+ len,
+ 5000);
+
+ usRetries++ ;
+ if(-ENODEV == retval)
+ {
+ psIntfAdapter->psAdapter->device_removed =TRUE;
+ break;
+ }
+
+ }while((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES ) );
+
+ if(retval < 0)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval,usRetries);
+ psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
+ return retval;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval);
+ psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
+ return STATUS_SUCCESS;
+ }
+}
+
+INT
+InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
+ UINT addr,
+ PVOID buff,
+ INT len)
+{
+ int retval = 0;
+ USHORT usRetries = 0 ;
+
+ if(psIntfAdapter == NULL )
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL");
+ return -EINVAL;
+ }
+ if(psIntfAdapter->psAdapter->device_removed == TRUE)
+ {
+
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed");
+ return -ENODEV;
+ }
+
+ if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB))
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus...");
+ return EACCES;
+ }
+
+ if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed..");
+ return -EACCES;
+ }
+ psIntfAdapter->psAdapter->DeviceAccess = TRUE ;
+ do{
+ retval = usb_control_msg(psIntfAdapter->udev,
+ usb_sndctrlpipe(psIntfAdapter->udev,0),
+ 0x01,
+ 0x42,
+ (addr & 0xFFFF),
+ ((addr >> 16) & 0xFFFF),
+ buff,
+ len,
+ 5000);
+
+ usRetries++ ;
+ if(-ENODEV == retval)
+ {
+ psIntfAdapter->psAdapter->device_removed = TRUE ;
+ break;
+ }
+
+ }while((retval < 0) && ( usRetries < MAX_RDM_WRM_RETIRES));
+
+ if(retval < 0)
+ {
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries);
+ psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
+ return retval;
+ }
+ else
+ {
+ psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval);
+ return STATUS_SUCCESS;
+
+ }
+
+}
+
+INT
+BcmRDM(PVOID arg,
+ UINT addr,
+ PVOID buff,
+ INT len)
+{
+ return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
+}
+
+INT
+BcmWRM(PVOID arg,
+ UINT addr,
+ PVOID buff,
+ INT len)
+{
+ return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
+}
+
+
+
+INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter)
+{
+ PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter);
+ INT status = STATUS_SUCCESS ;
+
+ /*
+ usb_clear_halt - tells device to clear endpoint halt/stall condition
+ @dev: device whose endpoint is halted
+ @pipe: endpoint "pipe" being cleared
+ @ Context: !in_interrupt ()
+
+ usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code.
+ This is used to clear halt conditions for bulk and interrupt endpoints only.
+ Control and isochronous endpoints never halts.
+
+ Any URBs queued for such an endpoint should normally be unlinked by the driver
+ before clearing the halt condition.
+
+ */
+
+ //Killing all the submitted urbs to different end points.
+ Bcm_kill_all_URBs(psIntfAdapter);
+
+
+ //clear the halted/stalled state for every end point
+ status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sIntrIn.int_in_pipe);
+ if(status != STATUS_SUCCESS)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status);
+
+ status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkIn.bulk_in_pipe);
+ if(status != STATUS_SUCCESS)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status);
+
+ status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkOut.bulk_out_pipe);
+ if(status != STATUS_SUCCESS)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status);
+
+ return status ;
+}
+
+
+VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
+{
+ struct urb *tempUrb = NULL;
+ UINT i;
+
+ /**
+ * usb_kill_urb - cancel a transfer request and wait for it to finish
+ * @urb: pointer to URB describing a previously submitted request,
+ * returns nothing as it is void returned API.
+ *
+ * This routine cancels an in-progress request. It is guaranteed that
+ * upon return all completion handlers will have finished and the URB
+ * will be totally idle and available for reuse
+
+ * This routine may not be used in an interrupt context (such as a bottom
+ * half or a completion handler), or when holding a spinlock, or in other
+ * situations where the caller can't schedule().
+ *
+ **/
+
+ /* Cancel submitted Interrupt-URB's */
+ if(psIntfAdapter->psInterruptUrb != NULL)
+ {
+ if(psIntfAdapter->psInterruptUrb->status == -EINPROGRESS)
+ usb_kill_urb(psIntfAdapter->psInterruptUrb);
+ }
+
+ /* Cancel All submitted TX URB's */
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All Submitted TX Urbs \n");
+
+ for(i = 0; i < MAXIMUM_USB_TCB; i++)
+ {
+ tempUrb = psIntfAdapter->asUsbTcb[i].urb;
+ if(tempUrb)
+ {
+ if(tempUrb->status == -EINPROGRESS)
+ usb_kill_urb(tempUrb);
+ }
+ }
+
+
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All submitted Rx Urbs \n");
+
+ for(i = 0; i < MAXIMUM_USB_RCB; i++)
+ {
+ tempUrb = psIntfAdapter->asUsbRcb[i].urb;
+ if(tempUrb)
+ {
+ if(tempUrb->status == -EINPROGRESS)
+ usb_kill_urb(tempUrb);
+ }
+ }
+
+
+ atomic_set(&psIntfAdapter->uNumTcbUsed, 0);
+ atomic_set(&psIntfAdapter->uCurrTcb, 0);
+
+ atomic_set(&psIntfAdapter->uNumRcbUsed, 0);
+ atomic_set(&psIntfAdapter->uCurrRcb, 0);
+
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "TCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumTcbUsed), atomic_read(&psIntfAdapter->uCurrTcb));
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "RCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumRcbUsed), atomic_read(&psIntfAdapter->uCurrRcb));
+
+}
+
+VOID putUsbSuspend(struct work_struct *work)
+{
+ PS_INTERFACE_ADAPTER psIntfAdapter = NULL ;
+ struct usb_interface *intf = NULL ;
+ psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER,usbSuspendWork);
+ intf=psIntfAdapter->interface ;
+
+ if(psIntfAdapter->bSuspended == FALSE)
+ usb_autopm_put_interface(intf);
+ else
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Interface Resumed Completely\n");
+
+}
+
+#endif
OpenPOWER on IntegriCloud