#include "headers.h"

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 */
	for(i = 0; i < MAXIMUM_USB_TCB; i++)
	{
		tempUrb = psIntfAdapter->asUsbTcb[i].urb;
		if(tempUrb)
		{
			if(tempUrb->status == -EINPROGRESS)
				usb_kill_urb(tempUrb);
		}
	}

	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);
}

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);

}

