Exemple #1
0
ETxnStatus sdioAdapt_Transact (unsigned int  uFuncId,
                               unsigned int  uHwAddr,
                               void *        pHostAddr,
                               unsigned int  uLength,
                               unsigned int  bDirection,
                               unsigned int  bBlkMode,
                               unsigned int  bFixedAddr,
                               unsigned int  bMore)
{
    int iStatus,i;


    if (bDirection) { /* Read */
		iStatus = sdioDrv_ReadSync (uFuncId, uHwAddr, pHostAddr, uLength, bBlkMode, bFixedAddr, bMore);
		if (iStatus)
		{
			return TXN_STATUS_ERROR;
		}
		return TXN_STATUS_COMPLETE;
    } else { /* Write */
	    if (use52)
	    {
	//    printk("use 52\n");jj = 0;
	        for (i = 0; i < uLength ; ++i)
	        {
	           // printk("uHwAddr = 0x%x *pHostValue = 0x%x\n",uHwAddr,(unsigned char)(*((unsigned char*)pHostAddr)));
	            sdioAdapt_TransactBytes(uFuncId,uHwAddr,pHostAddr,1,bDirection,bMore);
	            uHwAddr += 1;
	            pHostAddr = (void *)((unsigned int)pHostAddr+1);

	        }
	        return TXN_STATUS_COMPLETE;
	    }
	    else
	    {
			iStatus = sdioDrv_WriteSync (uFuncId, uHwAddr, pHostAddr, uLength, bBlkMode, bFixedAddr, bMore);
		}

	    if (iStatus)
		{
			return TXN_STATUS_ERROR;
		}
		return TXN_STATUS_COMPLETE;
    }
}
/** 
 * \fn     busDrv_SendTxnParts
 * \brief  Send prepared transaction parts
 * 
 * Called first by busDrv_Transact(), and also from TxnDone CB after Async completion.
 * Sends the prepared transaction parts in a loop.
 * If a transaction part is Async, the loop continues later in the TxnDone ISR context.
 * When all parts are done, the upper layer TxnDone CB is called.
 * 
 * \note   
 * \param  pBusDrv - The module's object
 * \return void
 * \sa     busDrv_Transact, busDrv_PrepareTxnParts
 */ 
static void busDrv_SendTxnParts (TBusDrvObj *pBusDrv)
{
    ETxnStatus  eStatus;
    TTxnPart   *pTxnPart;
    TTxnStruct *pTxn = pBusDrv->pCurrTxn;

    /* While there are transaction parts to send */
    while (pBusDrv->uCurrTxnPartsCount < pBusDrv->uCurrTxnPartsNum)
    {
        pTxnPart = &(pBusDrv->aTxnParts[pBusDrv->uCurrTxnPartsCount]);
        pBusDrv->uCurrTxnPartsCount++;

        /* Assume pending to be ready in case we are preempted by the TxnDon CB !! */
        pBusDrv->eCurrTxnStatus = TXN_STATUS_PENDING;   

        /* If single step, send ELP byte */
        if (TXN_PARAM_GET_SINGLE_STEP(pTxn)) 
        {
            /* Overwrite the function id with function 0 - for ELP register !!!! */
            eStatus = sdioAdapt_TransactBytes (TXN_FUNC_ID_CTRL,
                                               pTxnPart->uHwAddr,
                                               pTxnPart->pHostAddr,
                                               pTxnPart->uLength,
                                               TXN_PARAM_GET_DIRECTION(pTxn),
                                               pTxnPart->bMore);

            /* If first write failed try once again (may happen once upon chip wakeup) */
            if (eStatus == TXN_STATUS_ERROR)
            {
                /* Overwrite the function id with function 0 - for ELP register !!!! */
                eStatus = sdioAdapt_TransactBytes (TXN_FUNC_ID_CTRL,
                                                   pTxnPart->uHwAddr,
                                                   pTxnPart->pHostAddr,
                                                   pTxnPart->uLength,
                                                   TXN_PARAM_GET_DIRECTION(pTxn),
                                                   pTxnPart->bMore);
                TRACE0(pBusDrv->hReport, REPORT_SEVERITY_WARNING, "busDrv_SendTxnParts: SDIO Single-Step transaction failed once so try again");
            }
        }
        else
        {
            eStatus = sdioAdapt_Transact (TXN_PARAM_GET_FUNC_ID(pTxn),
                                          pTxnPart->uHwAddr,
                                          pTxnPart->pHostAddr,
                                          pTxnPart->uLength,
                                          TXN_PARAM_GET_DIRECTION(pTxn),
                                          pTxnPart->bBlkMode,
                                          ((TXN_PARAM_GET_FIXED_ADDR(pTxn) == 1) ? 0 : 1),
                                          pTxnPart->bMore);
        }

        TRACE7(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_SendTxnParts: PartNum = %d, SingleStep = %d, Direction = %d, HwAddr = 0x%x, HostAddr = 0x%x, Length = %d, BlkMode = %d\n", pBusDrv->uCurrTxnPartsCount-1, TXN_PARAM_GET_SINGLE_STEP(pTxn), TXN_PARAM_GET_DIRECTION(pTxn), pTxnPart->uHwAddr, pTxnPart->pHostAddr, pTxnPart->uLength, pTxnPart->bBlkMode);

        /* If pending TxnDone (Async), continue this loop in the next TxnDone interrupt */
        if (eStatus == TXN_STATUS_PENDING)
        {
            return; 
        }

        /* Update current transaction status to deduce if it is all finished in the original context (Sync) or not. */
        pBusDrv->eCurrTxnStatus = eStatus;
        pBusDrv->uCurrTxnPartsCountSync++;

        /* If error, set error in Txn struct, call TxnDone CB if not fully sync, and exit */
        if (eStatus == TXN_STATUS_ERROR)
        {
            TXN_PARAM_SET_STATUS(pTxn, TXN_PARAM_STATUS_ERROR);
            if (pBusDrv->uCurrTxnPartsCountSync != pBusDrv->uCurrTxnPartsCount)
            {
                pBusDrv->fTxnDoneCb (pBusDrv->hCbHandle, pTxn);
            }
        	return;
        }
    }

    /* If we got here we sent all buffers and we don't pend transaction end */
    TRACE3(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_SendTxnParts: Txn finished successfully, Status = %d, PartsCount = %d, SyncCount = %d\n", pBusDrv->eCurrTxnStatus, pBusDrv->uCurrTxnPartsCount, pBusDrv->uCurrTxnPartsCountSync);

    /* For read transaction, copy the data from the DMA-able buffer to the host buffer(s) */
    if (TXN_PARAM_GET_DIRECTION(pTxn) == TXN_DIRECTION_READ)
    {
        TI_UINT32 uBufNum;
        TI_UINT32 uBufLen;
        TI_UINT8 *pDmaBuf = pBusDrv->pRxDmaBuf; /* After the read transaction the data is in the Rx DMA buffer */

        for (uBufNum = 0; uBufNum < MAX_XFER_BUFS; uBufNum++)
        {
            uBufLen = pTxn->aLen[uBufNum];

            /* If no more buffers, exit the loop */
            if (uBufLen == 0)
            {
                break;
            }

            os_memoryCopy (pBusDrv->hOs, pTxn->aBuf[uBufNum], pDmaBuf, uBufLen);
            pDmaBuf += uBufLen;
        }
    }

    /* If not fully sync, call TxnDone CB */
    if (pBusDrv->uCurrTxnPartsCountSync != pBusDrv->uCurrTxnPartsCount)
    {
        pBusDrv->fTxnDoneCb (pBusDrv->hCbHandle, pTxn);
    }
}