/** * This function initializes a DMA engine. This function must be called * prior to using the DMA engine. Initialization of an engine includes setting * up the register base address, setting up the instance data, and ensuring the * hardware is in a quiescent state. * * @param InstancePtr is a pointer to the DMA engine instance to be worked on. * @param BaseAddress is where the registers for this engine can be found. * * @return None. * *****************************************************************************/ void Dma_Initialize(Dma_Engine * InstancePtr, u32 BaseAddress, u32 Type) { log_verbose(KERN_INFO "Initializing DMA()\n"); /* Set up the instance */ log_verbose(KERN_INFO "Clearing DMA instance %p\n", InstancePtr); memset(InstancePtr, 0, sizeof(Dma_Engine)); log_verbose(KERN_INFO "DMA base address is 0x%x\n", BaseAddress); InstancePtr->RegBase = BaseAddress; InstancePtr->Type = Type; /* Initialize the engine and ring states. */ InstancePtr->BdRing.RunState = XST_DMA_SG_IS_STOPPED; InstancePtr->EngineState = INITIALIZED; /* Initialize the ring structure */ InstancePtr->BdRing.ChanBase = BaseAddress; if(Type == DMA_ENG_C2S) InstancePtr->BdRing.IsRxChannel = 1; else InstancePtr->BdRing.IsRxChannel = 0; /* Reset the device and return */ Dma_Reset(InstancePtr); }
/** * This function must be called by the user driver to unregister itself from * the base DMA driver. After doing required checks to verify the handle * and engine state, the DMA engine is reset, interrupts are disabled if * required, and the BD ring is freed, while returning all the packet buffers * to the user driver. * * @param handle is the handle which was assigned during the registration * process. * * @return XST_FAILURE incase of any error * @return 0 incase of success * * @note This function should not be called in an interrupt context * *****************************************************************************/ int DmaUnregister(void * handle) { Dma_Engine * eptr; printk(KERN_INFO "User unregister for handle %p\n", handle); if(DriverState != INITIALIZED) { printk(KERN_ERR "DMA driver state %d - not ready\n", DriverState); return XST_FAILURE; } eptr = (Dma_Engine *)handle; /* Check if this engine's pointer is valid */ if(eptr == NULL) { printk(KERN_ERR "Handle is a NULL value\n"); return XST_FAILURE; } /* Is the engine assigned to any user? */ if(eptr->EngineState != USER_ASSIGNED) { printk(KERN_ERR "Engine is not assigned to any user\n"); return XST_FAILURE; } spin_lock_bh(&DmaLock); /* Change DMA engine state */ eptr->EngineState = UNREGISTERING; /* First, reset DMA engine, so that buffers can be removed. */ printk(KERN_INFO "Resetting DMA engine\n"); Dma_Reset(eptr); /* Next, return all the buffers in the BD ring to the user. * And free the BD ring. */ printk("Now checking all descriptors\n"); spin_unlock_bh(&DmaLock); descriptor_free(eptr->pdev, eptr); spin_lock_bh(&DmaLock); /* Change DMA engine state */ eptr->EngineState = INITIALIZED; dmaData->userCount --; printk("DMA driver user count is %d\n", dmaData->userCount); spin_unlock_bh(&DmaLock); return 0; }