xdma_channel_sg.c
来自「适合KS8695X」· C语言 代码 · 共 1,318 行 · 第 1/4 页
C
1,318 行
XBufDescriptor_SetNextPtr(BufferDescriptorPtr, StartOfListPtr);
/* initialize the ring buffer to indicate that there are no
* buffer descriptors in the list which point to valid data buffers
*/
InstancePtr->PutPtr = BufferDescriptorPtr;
InstancePtr->GetPtr = BufferDescriptorPtr;
InstancePtr->CommitPtr = NULL;
InstancePtr->LastPtr = BufferDescriptorPtr;
InstancePtr->ActiveDescriptorCount = 0;
/* indicate the scatter gather list was successfully created */
return XST_SUCCESS;
}
/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_IsSgListEmpty
*
* DESCRIPTION:
*
* This function determines if the scatter gather list of a DMA channel is
* empty with regard to buffer descriptors which are pointing to buffers to be
* used for scatter gather operations.
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on. The DMA
* channel should be configured to use scatter gather in order for this function
* to be called.
*
* RETURN VALUE:
*
* A value of TRUE if the scatter gather list is empty, otherwise a value of
* FALSE.
*
* NOTES:
*
* None.
*
******************************************************************************/
u32
XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr)
{
/* assert to verify valid input arguments */
XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/* if the number of descriptors which are being used in the list is zero
* then the list is empty
*/
return (InstancePtr->ActiveDescriptorCount == 0);
}
/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_PutDescriptor
*
* DESCRIPTION:
*
* This function puts a buffer descriptor into the DMA channel scatter
* gather list. A DMA channel maintains a list of buffer descriptors which are
* to be processed. This function puts the specified buffer descriptor
* at the next location in the list. Note that since the list is already intact,
* the information in the parameter is copied into the list (rather than modify
* list pointers on the fly).
*
* After buffer descriptors are put into the list, they must also be committed
* by calling another function. This allows multiple buffer descriptors which
* span a single packet to be put into the list while preventing the hardware
* from starting the first buffer descriptor of the packet.
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on. The DMA
* channel should be configured to use scatter gather in order for this function
* to be called.
*
* BufferDescriptorPtr is a pointer to the buffer descriptor to be put into
* the next available location of the scatter gather list.
*
* RETURN VALUE:
*
* A status which indicates XST_SUCCESS if the buffer descriptor was
* successfully put into the scatter gather list.
*
* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
* been created.
*
* A value of XST_DMA_SG_LIST_FULL indicates the buffer descriptor was not
* put into the list because the list was full.
*
* A value of XST_DMA_SG_BD_LOCKED indicates the buffer descriptor was not
* put into the list because the buffer descriptor in the list which is to
* be overwritten was locked. A locked buffer descriptor indicates the higher
* layered software is still using the buffer descriptor.
*
* NOTES:
*
* It is necessary to create a scatter gather list for a DMA channel before
* putting buffer descriptors into it.
*
******************************************************************************/
XStatus
XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
XBufDescriptor * BufferDescriptorPtr)
{
u32 Control;
/* assert to verify valid input arguments and alignment for those
* arguments that have alignment restrictions
*/
XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(BufferDescriptorPtr != NULL);
XASSERT_NONVOID(((u32) BufferDescriptorPtr & 3) == 0);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/* if a scatter gather list has not been created yet, return a status */
if (InstancePtr->TotalDescriptorCount == 0) {
return XST_DMA_SG_NO_LIST;
}
/* if the list is full because all descriptors are pointing to valid
* buffers, then indicate an error, this code assumes no list or an
* empty list is detected above
*/
if (InstancePtr->ActiveDescriptorCount ==
InstancePtr->TotalDescriptorCount) {
return XST_DMA_SG_LIST_FULL;
}
/* if the buffer descriptor in the list which is to be overwritten is
* locked, then don't overwrite it and return a status
*/
if (XBufDescriptor_IsLocked(InstancePtr->PutPtr)) {
return XST_DMA_SG_BD_LOCKED;
}
/* set the scatter gather stop bit in the control word of the descriptor
* to cause the h/w to stop after it processes this descriptor since it
* will be the last in the list
*/
Control = XBufDescriptor_GetControl(BufferDescriptorPtr);
XBufDescriptor_SetControl(BufferDescriptorPtr,
Control | XDC_DMACR_SG_DISABLE_MASK);
/* set both statuses in the descriptor so we tell if they are updated with
* the status of the transfer, the hardware should change the busy in the
* DMA status to be false when it completes
*/
XBufDescriptor_SetStatus(BufferDescriptorPtr, XDC_DMASR_BUSY_MASK);
XBufDescriptor_SetDeviceStatus(BufferDescriptorPtr, 0);
/* copy the descriptor into the next position in the list so it's ready to
* be used by the h/w, this assumes the descriptor in the list prior to this
* one still has the stop bit in the control word set such that the h/w
* use this one yet
*/
CopyBufferDescriptor(BufferDescriptorPtr, InstancePtr->PutPtr);
/* only the last in the list and the one to be committed have scatter gather
* disabled in the control word, a commit requires only one descriptor
* to be changed, when # of descriptors to commit > 2 all others except the
* 1st and last have scatter gather enabled
*/
if ((InstancePtr->CommitPtr != InstancePtr->LastPtr) &&
(InstancePtr->CommitPtr != NULL)) {
Control = XBufDescriptor_GetControl(InstancePtr->LastPtr);
XBufDescriptor_SetControl(InstancePtr->LastPtr,
Control & ~XDC_DMACR_SG_DISABLE_MASK);
}
/* update the list data based upon putting a descriptor into the list,
* these operations must be last
*/
InstancePtr->ActiveDescriptorCount++;
/* only update the commit pointer if it is not already active, this allows
* it to be deactivated after every commit such that a single descriptor
* which is committed does not appear to be waiting to be committed
*/
if (InstancePtr->CommitPtr == NULL) {
InstancePtr->CommitPtr = InstancePtr->LastPtr;
}
/* these updates MUST BE LAST after the commit pointer update in order for
* the commit pointer to track the correct descriptor to be committed
*/
InstancePtr->LastPtr = InstancePtr->PutPtr;
InstancePtr->PutPtr = XBufDescriptor_GetNextPtr(InstancePtr->PutPtr);
return XST_SUCCESS;
}
/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_CommitPuts
*
* DESCRIPTION:
*
* This function commits the buffer descriptors which have been put into the
* scatter list for the DMA channel since the last commit operation was
* performed. This enables the calling functions to put several buffer
* descriptors into the list (e.g.,a packet's worth) before allowing the scatter
* gather operations to start. This prevents the DMA channel hardware from
* starting to use the buffer descriptors in the list before they are ready
* to be used (multiple buffer descriptors for a single packet).
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on. The DMA
* channel should be configured to use scatter gather in order for this function
* to be called.
*
* RETURN VALUE:
*
* A status indicating XST_SUCCESS if the buffer descriptors of the list were
* successfully committed.
*
* A value of XST_DMA_SG_NOTHING_TO_COMMIT indicates that the buffer descriptors
* were not committed because there was nothing to commit in the list. All the
* buffer descriptors which are in the list are commited.
*
* NOTES:
*
* None.
*
******************************************************************************/
XStatus
XDmaChannel_CommitPuts(XDmaChannel * InstancePtr)
{
/* assert to verify input arguments */
XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/* if the buffer descriptor to be committed is already committed or
* the list is empty (none have been put in), then indicate an error
*/
if ((InstancePtr->CommitPtr == NULL) ||
XDmaChannel_IsSgListEmpty(InstancePtr)) {
return XST_DMA_SG_NOTHING_TO_COMMIT;
}
/* last descriptor in the list must have scatter gather disabled so the end
* of the list is hit by h/w, if descriptor to commit is not last in list,
* commit descriptors by enabling scatter gather in the descriptor
*/
if (InstancePtr->CommitPtr != InstancePtr->LastPtr) {
u32 Control;
Control = XBufDescriptor_GetControl(InstancePtr->CommitPtr);
XBufDescriptor_SetControl(InstancePtr->CommitPtr, Control &
~XDC_DMACR_SG_DISABLE_MASK);
}
/* Update the commit pointer to indicate that there is nothing to be
* committed, this state is used by start processing to know that the
* buffer descriptor to start is not waiting to be committed
*/
InstancePtr->CommitPtr = NULL;
return XST_SUCCESS;
}
/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_GetDescriptor
*
* DESCRIPTION:
*
* This function gets a buffer descriptor from the scatter gather list of the
* DMA channel. The buffer descriptor is retrieved from the scatter gather list
* and the scatter gather list is updated to not include the retrieved buffer
* descriptor. This is typically done after a scatter gather operation
* completes indicating that a data buffer has been successfully sent or data
* has been received into the data buffer. The purpose of this function is to
* allow the device using the scatter gather operation to get the results of the
* operation.
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on. The DMA
* channel should be configured to use scatter gather in order for this function
* to be called.
*
* BufDescriptorPtr is a pointer to a pointer to the buffer descriptor which
* was retrieved from the list. The buffer descriptor is not really removed
* from the list, but it is changed to a state such that the hardware will not
* use it again until it is put into the scatter gather list of the DMA channel.
*
* RETURN VALUE:
*
* A status indicating XST_SUCCESS if a buffer descriptor was retrieved from
* the scatter gather list of the DMA channel.
*
* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
* been created.
*
* A value of XST_DMA_SG_LIST_EMPTY indicates no buffer descriptor was
* retrieved from the list because there are no buffer descriptors to be
* processed in the list.
*
* BufDescriptorPtr is updated to point to the buffer descriptor which was
* retrieved from the list if the status indicates success.
*
* NOTES:
*
* None.
*
******************************************************************************/
XStatus
XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
XBufDescriptor ** BufDescriptorPtr)
{
u32 Control;
/* assert to verify input arguments */
XASSERT_NONVOID(InstancePtr != NULL);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?