Ejemplo n.º 1
0
/**Fill the buffer descriptor with the values given in parameter.
 *
 * @return none
 */
void
iapi_SetBufferDescriptor( bufferDescriptor * bd_p, unsigned char command,
                    unsigned char status, unsigned short count,
                    void * buffAddr, void * extBufferAddr)
{
  bd_p->mode.command = command;
  bd_p->mode.status = status;
  bd_p->mode.count = count;
  if (buffAddr != NULL) {
    bd_p->bufferAddr = iapi_Virt2Phys(buffAddr);
  } else {
    bd_p->bufferAddr = buffAddr;
  }
  bd_p->extBufferAddr = extBufferAddr;
}
/**Send a command on SDMA's channel zero.
 * Check if buffer descriptor is already used by the sdma, if yes return
 * an error as c0BDNum is wrong.
 *
 * <b>Notes</b>\n
 *  There is an upgrade in the script on the Context load command and
 * the fact that the context structure has a fixed length of 20 or 24
 * depending on SDMA versions.
 *
 * @return
 *   - IAPI_SUCCESS
 *   - -iapi_errno if failure
 */
int
iapi_Channel0Command(channelDescriptor *cd_p, void *buf,
		     unsigned short nbyte, unsigned char command)
{
	channelControlBlock *ccb_p;
	bufferDescriptor *bd_p;
	int result = IAPI_SUCCESS;
	unsigned char chNum;

	/*
	 * Check data structures are properly initialized
	 */
	/* Channel descriptor validity */
	if (cd_p == NULL) {
		result = IAPI_ERR_CD_UNINITIALIZED;
		iapi_errno = result;
		return -result;
	}

	/* Channel control block validity */
	if (cd_p->ccb_ptr == NULL) {
		result = IAPI_ERR_CCB_UNINITIALIZED;
		iapi_errno = result;
		return -result;
	}

	/* Control block & Descriptpor associated with the channel being worked on */
	chNum = cd_p->channelNumber;
	ccb_p = cd_p->ccb_ptr;

	/* Is channel already in use ? */
	if (ccb_p->baseBDptr != NULL) {
		result = IAPI_ERR_BD_ALLOCATED | IAPI_ERR_CH_AVAILABLE | chNum;
		iapi_errno = result;
		return -result;
	}

	/* Allocation of buffer descriptors */
	bd_p = (bufferDescriptor *) MALLOC(sizeof(bufferDescriptor), SDMA_ERAM);
	if (bd_p != NULL) {
		ccb_p->baseBDptr = (bufferDescriptor *) iapi_Virt2Phys(bd_p);
	} else {
		result = IAPI_ERR_BD_ALLOCATION | IAPI_ERR_CH_AVAILABLE | chNum;
		iapi_errno = result;
		return -result;
	}

	/* Buffer descriptor setting */
	iapi_SetBufferDescriptor(bd_p, command, BD_WRAP | BD_DONE | BD_INTR,
				 nbyte, buf, NULL);

	/* Actually the transfer */
	iapi_lowStartChannel(cd_p->channelNumber);
	iapi_lowSynchChannel(cd_p->channelNumber);

	/* Cleaning of allocation */
	FREE(bd_p);
	ccb_p->baseBDptr = NULL;

	return IAPI_SUCCESS;

}