📄 xdma_channel_sg.c
字号:
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.*******************************************************************************/u32XDmaChannel_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.*******************************************************************************/XStatusXDmaChannel_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.*******************************************************************************/XStatusXDmaChannel_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.*******************************************************************************/XStatusXDmaChannel_GetDescriptor(XDmaChannel * InstancePtr, XBufDescriptor ** BufDescriptorPtr){ u32 Control; /* assert to verify input arguments */ XASSERT_NONVOID(InstancePtr != NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -