Exemplo n.º 1
0
    /* called by async task to perform the operation synchronously using direct MMC APIs  */
A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest)
{
    int                     i;
    A_UINT8                 rw;
    A_UINT8                 opcode;
    struct mmc_request      mmcreq;
    struct mmc_command      cmd;
    struct mmc_data         data;
    HIF_SCATTER_REQ_PRIV   *pReqPriv;   
    HIF_SCATTER_REQ        *pReq;       
    A_STATUS                status = A_OK;
    struct                  scatterlist *pSg;
    
    pReqPriv = busrequest->pScatterReq;
    
    A_ASSERT(pReqPriv != NULL);
    
    pReq = pReqPriv->pHifScatterReq;
    
    memset(&mmcreq, 0, sizeof(struct mmc_request));
    memset(&cmd, 0, sizeof(struct mmc_command));
    memset(&data, 0, sizeof(struct mmc_data));
       
    data.blksz = HIF_MBOX_BLOCK_SIZE;
    data.blocks = pReq->TotalLength / HIF_MBOX_BLOCK_SIZE;
                        
    AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: (%s) Address: 0x%X, (BlockLen: %d, BlockCount: %d) , (tot:%d,sg:%d)\n",
              (pReq->Request & HIF_WRITE) ? "WRITE":"READ", pReq->Address, data.blksz, data.blocks,
              pReq->TotalLength,pReq->ValidScatterEntries));
         
    if (pReq->Request  & HIF_WRITE) {
        rw = _CMD53_ARG_WRITE;
        data.flags = MMC_DATA_WRITE;
    } else {
        rw = _CMD53_ARG_READ;
        data.flags = MMC_DATA_READ;
    }

    if (pReq->Request & HIF_FIXED_ADDRESS) {
        opcode = _CMD53_ARG_FIXED_ADDRESS;
    } else {
        opcode = _CMD53_ARG_INCR_ADDRESS;
    }
    
        /* fill SG entries */
    pSg = pReqPriv->sgentries;   
    sg_init_table(pSg, pReq->ValidScatterEntries); 
          
        /* assemble SG list */   
    for (i = 0 ; i < pReq->ValidScatterEntries ; i++, pSg++) {
            /* setup each sg entry */
        if ((unsigned long)pReq->ScatterList[i].pBuffer & 0x3) {
                /* note some scatter engines can handle unaligned buffers, print this
                 * as informational only */
            AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER,
                            ("HIF: (%s) Scatter Buffer is unaligned 0x%lx\n",
                            pReq->Request & HIF_WRITE ? "WRITE":"READ",
                            (unsigned long)pReq->ScatterList[i].pBuffer)); 
        }
        
        AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("  %d:  Addr:0x%lX, Len:%d \n",
            i,(unsigned long)pReq->ScatterList[i].pBuffer,pReq->ScatterList[i].Length));
            
        sg_set_buf(pSg, pReq->ScatterList[i].pBuffer, pReq->ScatterList[i].Length);
    }
        /* set scatter-gather table for request */
    data.sg = pReqPriv->sgentries;
    data.sg_len = pReq->ValidScatterEntries;
        /* set command argument */    
    SDIO_SET_CMD53_ARG(cmd.arg, 
                       rw, 
                       device->func->num, 
                       _CMD53_ARG_BLOCK_BASIS, 
                       opcode,  
                       pReq->Address,
                       data.blocks);  
                       
    cmd.opcode = SD_IO_RW_EXTENDED;
    cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
    
    mmcreq.cmd = &cmd;
    mmcreq.data = &data;
    
    mmc_set_data_timeout(&data, device->func->card);    
        /* synchronous call to process request */
    mmc_wait_for_req(device->func->card->host, &mmcreq);
 
    if (cmd.error) {
        status = A_ERROR;   
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: cmd error: %d \n",cmd.error));
    }
               
    if (data.error) {
        status = A_ERROR;
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: data error: %d \n",data.error));   
    }

    if (A_FAILED(status)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: FAILED!!! (%s) Address: 0x%X, Block mode (BlockLen: %d, BlockCount: %d)\n",
              (pReq->Request & HIF_WRITE) ? "WRITE":"READ",pReq->Address, data.blksz, data.blocks));        
    }
    
        /* set completion status, fail or success */
    pReq->CompletionStatus = status;
    
    if (pReq->Request & HIF_ASYNCHRONOUS) {
        AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: async_task completion routine req: 0x%lX (%d)\n",(unsigned long)busrequest, status));
            /* complete the request */
        A_ASSERT(pReq->CompletionRoutine != NULL);
        pReq->CompletionRoutine(pReq);
    } else {
        AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER async_task upping busrequest : 0x%lX (%d)\n", (unsigned long)busrequest,status));
            /* signal wait */
        up(&busrequest->sem_req);
    }
                                                               
    return status;   
}
Exemplo n.º 2
0
static A_STATUS HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq)
{
   
    A_STATUS        status = A_EINVAL;   
    SDREQUEST       *sdrequest;
    A_UINT8         rw;
    A_UINT8         mode;
    A_UINT8         funcNo;
    A_UINT8         opcode;
    A_UINT16        count;
    SDIO_STATUS     sdiostatus;
    A_UINT32        request = pReq->Request;
    
    do {
        
        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("HIF Scatter : %d Scatter Entries: %d\n", 
                            pReq->TotalLength, pReq->ValidScatterEntries));
        
        if (pReq->TotalLength > MAX_SCATTER_REQ_TRANSFER_SIZE) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid length: %d \n", pReq->TotalLength));
            break;          
        }
        
        if (pReq->TotalLength == 0) {
            A_ASSERT(FALSE);
            break;    
        }
        
            /* get the sd bus request associated with this scatter request */         
        sdrequest = GET_SDREQUEST_SR(pReq);
        
        if (request & HIF_SYNCHRONOUS) {
            sdrequest->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | SDREQ_FLAGS_DATA_TRANS;
            sdrequest->pCompleteContext = NULL;
            sdrequest->pCompletion = NULL;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,("  Synchronous \n"));
        } else if (request & HIF_ASYNCHRONOUS) {
            sdrequest->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | SDREQ_FLAGS_DATA_TRANS |
                               SDREQ_FLAGS_TRANS_ASYNC;  
            sdrequest->pCompleteContext = pReq;
            sdrequest->pCompletion = HifReadWriteScatterCompletion;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,("  Asynchronous \n"));
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid execution mode: 0x%08x\n", request));
            break;
        }

        if (!(request & HIF_EXTENDED_IO)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid command type: 0x%08x\n", request));
            break;
        }

        sdrequest->Command = CMD53;
            
        if (!(request & HIF_BLOCK_BASIS)) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid data mode: 0x%08x\n", request));
            break;   
        }
            /* only block-mode commands */
        mode = CMD53_BLOCK_BASIS;
        sdrequest->BlockLen = HIF_MBOX_BLOCK_SIZE;
        sdrequest->BlockCount = pReq->TotalLength / HIF_MBOX_BLOCK_SIZE;
        count = sdrequest->BlockCount;
        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
                        ("  Block mode (BlockLen: %d, BlockCount: %d)\n",
                        sdrequest->BlockLen, sdrequest->BlockCount));
             
        if (request & HIF_WRITE) {
            rw = CMD53_WRITE;
            sdrequest->Flags |= SDREQ_FLAGS_DATA_WRITE;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("  Direction: Write\n"));
        } else if (request & HIF_READ) {
            rw = CMD53_READ;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("  Direction: Read\n"));
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid direction: 0x%08x\n", request));
            break;
        }

        if (request & HIF_FIXED_ADDRESS) {
            opcode = CMD53_FIXED_ADDRESS;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("  Address mode: Fixed\n"));
        } else if (request & HIF_INCREMENTAL_ADDRESS) {
            opcode = CMD53_INCR_ADDRESS;
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("  Address mode: Incremental\n"));
        } else {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            ("Invalid address mode: 0x%08x\n", request));
            break;
        }
        
        
        funcNo = SDDEVICE_GET_SDIO_FUNCNO(device->handle);
       
        SDIO_SET_CMD53_ARG(sdrequest->Argument, rw, funcNo,
                           mode, opcode, pReq->Address, count);
        
        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("HIF Scatter : SDIO CMD53 card address: 0x%X blocks: %d\n", 
                            pReq->Address, count));
                            
        AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("HIF Scatter : SDIO CMD53 , request flags:0x%X arg:0x%X\n", 
                            sdrequest->Flags, sdrequest->Argument));
                            
        status = SetupBusRequestForDMA(device, sdrequest, pReq);
        
        if (A_FAILED(status)){
            break;    
        }

        if (sdrequest->pDataBuffer == NULL) {
            AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
                            (" sdrequest->pDataBuffer is NULL!!!\n"));
            status = A_ERROR;
            // A_ASSERT(FALSE);
            break;    
        }
                    
            /* Send the command out */
        sdiostatus = SDDEVICE_CALL_REQUEST_FUNC(device->handle, sdrequest);
        
        if (!SDIO_SUCCESS(sdiostatus)) {
            status = A_ERROR;
            break;
        }
            
        status = A_OK;
       
    } while (FALSE);

    if (A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) {
        pReq->CompletionStatus = status;
        pReq->CompletionRoutine(pReq);
        status = A_OK;
    }
        
    return status;  
}