Beispiel #1
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
s32 sdxc_program_clk(struct awsmc_host* smc_host)
{
  	u32 rval;
  	s32 time = 0xf000;
  	s32 ret = 0;
  	
  	rval = SDXC_Start|SDXC_UPCLKOnly|SDXC_WaitPreOver;
  	sdc_write(SDXC_REG_CMDR, rval);
	
	//disable command done interrupt
	sdxc_disable_imask(smc_host, SDXC_CmdDone);
	
	do {
	    rval = sdc_read(SDXC_REG_CMDR);
	    time--;
	} while(time && (rval & SDXC_Start));
	
	if (time <= 0)
	{
		ret = -1;
	}
	
	//clear command cone flag
	rval = sdc_read(SDXC_REG_RINTR);
	sdc_write(SDXC_REG_RINTR, rval);
	
	//enable command done interrupt
	sdxc_enable_imask(smc_host, SDXC_CmdDone);
	
	return ret;
}
Beispiel #2
0
int sdxc_send_manual_stop(struct awsmc_host* smc_host, struct mmc_request* request)
{
	struct mmc_data* data = request->data;
	u32 cmd_val = SDXC_Start | SDXC_RspExp | SDXC_CheckRspCRC | MMC_STOP_TRANSMISSION;
	u32 iflags = 0;
	int ret = 0;
	
	if (!data || !data->stop)
	{
		awsmc_dbg_err("no stop cmd request\n");
		return -1;
	}

	sdxc_int_disable(smc_host);
	
	sdc_write(SDXC_REG_CARG, 0);
	sdc_write(SDXC_REG_CMDR, cmd_val);
	do {
		iflags = sdc_read(SDXC_REG_RINTR);
	} while(!(iflags & (SDXC_CmdDone | SDXC_IntErrBit)));
	
	if (iflags & SDXC_IntErrBit)
	{
		awsmc_dbg_err("sdc %d send stop command failed\n", smc_host->pdev->id);
		data->stop->error = ETIMEDOUT;
		ret = -1;
	}

	sdc_write(SDXC_REG_RINTR, iflags);
    data->stop->resp[0] = sdc_read(SDXC_REG_RESP0);
	
	sdxc_int_enable(smc_host);

	return ret;
}
Beispiel #3
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
s32 sdxc_update_clk(struct awsmc_host* smc_host, u32 sclk, u32 cclk)
{
    u32 rval;
    u32 clk_div;
    u32 real_clk;
    
    //caculate new clock divider
    clk_div = (sclk / cclk)>>1;
    real_clk = clk_div ? sclk/(clk_div<<1) : sclk;
    while (real_clk > cclk)
    {
        clk_div++;
        real_clk = sclk/(clk_div<<1);
    }
    
    awsmc_dbg("sdc %d change clock over, src_clk %d, req_clk %d, real_clk %d, div %d\n", smc_host->pdev->id, sclk, cclk, real_clk, clk_div);
    
    //update new clock
    //disable clock 
    rval = sdc_read(SDXC_REG_CLKCR) & (~SDXC_CardClkOn) & (~SDXC_LowPowerOn);
    sdc_write(SDXC_REG_CLKCR, rval);
    if (-1 == sdxc_program_clk(smc_host))
    {
        awsmc_dbg_err("clock program failed in step 1\n");
        return -1;
    }
    
    //update divider
    rval = sdc_read(SDXC_REG_CLKCR);
    rval &= ~0xff;
    rval |= clk_div & 0xff;
    sdc_write(SDXC_REG_CLKCR, rval);
    if (-1 == sdxc_program_clk(smc_host))
    {
        awsmc_dbg_err("clock program failed in step 2\n");
        return -1;
    }
    
    //re-enable clock
    rval = sdc_read(SDXC_REG_CLKCR) | SDXC_CardClkOn ;//| SDXC_LowPowerOn;
    sdc_write(SDXC_REG_CLKCR, rval);
    if (-1 == sdxc_program_clk(smc_host))
    {
        awsmc_dbg_err("clock program failed in step 3\n");
        return -1;
    }
    
    smc_host->real_cclk = real_clk;
    return real_clk;
}
Beispiel #4
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static int sdxc_prepare_dma(struct awsmc_host* smc_host, struct mmc_data* data)
{
    u32 dma_len;
    u32 i;
   
	if (smc_host->pdes == NULL)
	{
		return -ENOMEM;
	}

	dma_len = dma_map_sg(mmc_dev(smc_host->mmc), data->sg, data->sg_len, (data->flags & MMC_DATA_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
	if (dma_len == 0)
	{
		awsmc_dbg_err("no dma map memory\n");
		return -ENOMEM;
	}	
		
    for (i=0; i<data->sg_len; i++)
    {
        if (sg_dma_address(&data->sg[i]) & 3)
        {
		    awsmc_dbg_err("unaligned dma address[%d] %p\n", i, (void*)sg_dma_address(&data->sg[i]));
			return -EINVAL;
        }
    }

    sdxc_init_idma_des(smc_host, data);
	sdxc_dma_enable(smc_host);
    sdxc_dma_reset(smc_host);
    sdxc_idma_reset(smc_host);
    sdxc_idma_on(smc_host);
    sdxc_idma_int_disable(smc_host, SDXC_IDMACTransmitInt|SDXC_IDMACReceiveInt);
    if (data->flags & MMC_DATA_WRITE)
    {
        sdxc_idma_int_enable(smc_host, SDXC_IDMACTransmitInt);
    }
    else
    {
        sdxc_idma_int_enable(smc_host, SDXC_IDMACReceiveInt);
    }
    
    //write descriptor address to register
    sdc_write(SDXC_REG_DLBA, __pa(smc_host->pdes));

    //write water level
    sdc_write(SDXC_REG_FTRGL, (2U<<28)|(7<<16)|8);
    
    return 0;
}
Beispiel #5
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
void sdxc_set_buswidth(struct awsmc_host* smc_host, u32 width)
{
    switch(width)
    {
        case 1:
            sdc_write(SDXC_REG_WIDTH, SDXC_WIDTH1);
            break;
        case 4:
            sdc_write(SDXC_REG_WIDTH, SDXC_WIDTH4);
            break;
        case 8:
            sdc_write(SDXC_REG_WIDTH, SDXC_WIDTH8);
            break;
    }
}
Beispiel #6
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline u32 sdxc_disable_imask(struct awsmc_host* smc_host, u32 imask)
{
    u32 newmask = sdc_read(SDXC_REG_IMASK) & (~imask);
    
    sdc_write(SDXC_REG_IMASK, newmask);
	return newmask;
}
Beispiel #7
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
void sdxc_regs_restore(struct awsmc_host* smc_host)
{
	struct awsmc_ctrl_regs* bak_regs = &smc_host->bak_regs;

    sdc_write(SDXC_REG_GCTRL, bak_regs->gctrl);
    sdc_write(SDXC_REG_CLKCR, bak_regs->clkc);
    sdc_write(SDXC_REG_TMOUT, bak_regs->timeout);
    sdc_write(SDXC_REG_WIDTH, bak_regs->buswid);
    sdc_write(SDXC_REG_FTRGL, bak_regs->waterlvl);
    sdc_write(SDXC_REG_FUNS, bak_regs->funcsel);
    sdc_write(SDXC_REG_DBGC, bak_regs->debugc);
    sdc_write(SDXC_REG_DMAC, bak_regs->idmacc);
}
Beispiel #8
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
s32 sdxc_reset(struct awsmc_host* smc_host)
{
    u32 rval = sdc_read(SDXC_REG_GCTRL) | SDXC_SoftReset | SDXC_FIFOReset | SDXC_DMAReset;
    s32 time = 0xffff;
    
    sdc_write(SDXC_REG_GCTRL, rval);
    while((sdc_read(SDXC_REG_GCTRL) & 0x7) && time--);
    if (time <= 0)
    {
        awsmc_dbg_err("sdc %d reset failed\n", smc_host->pdev->id);
        return -1;
    }
    return 0;
}
Beispiel #9
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
s32 sdxc_init(struct awsmc_host* smc_host)
{
	struct smc_idma_des* pdes = NULL;
	
    /* reset controller */
    if (-1 == sdxc_reset(smc_host))
    {
        return -1;
    }
    
    sdc_write(SDXC_REG_GCTRL, SDXC_PosedgeLatchData);
    
    /* config DMA/Interrupt Trigger threshold */
    sdc_write(SDXC_REG_FTRGL, 0x70008);
    
    /* config timeout register */
    sdc_write(SDXC_REG_TMOUT, 0xffffffff);
    
    /* clear interrupt flags */
    sdc_write(SDXC_REG_RINTR, 0xffffffff);
    
    sdc_write(SDXC_REG_DBGC, 0xdeb);
    sdc_write(SDXC_REG_FUNS, 0xceaa0000);
    
    sdxc_int_enable(smc_host);

   	/* alloc idma descriptor structure */ 
	pdes = (struct smc_idma_des*)kmalloc(sizeof(struct smc_idma_des) * SDXC_MAX_DES_NUM, GFP_DMA | GFP_KERNEL);
	if (pdes == NULL)
	{
	    awsmc_dbg_err("alloc dma des failed\n");
	    return -1;
	}
	smc_host->pdes = pdes;
	awsmc_msg("sdc %d idma des address %p\n", smc_host->pdev->id, pdes);
    return 0;
}
Beispiel #10
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_dma_reset(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_GCTRL, sdc_read(SDXC_REG_GCTRL)|SDXC_DMAReset);
}
Beispiel #11
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static void sdxc_send_cmd(struct awsmc_host* smc_host, struct mmc_command* cmd)
{
    u32 imask;
    u32 cmd_val = SDXC_Start|(cmd->opcode&0x3f);
    
    imask = SDXC_CmdDone|SDXC_IntErrBit|SDXC_WaitPreOver;
    
    if (cmd->opcode == MMC_GO_IDLE_STATE) 
    {
        cmd_val |= SDXC_SendInitSeq;
        smc_host->wait = SDC_WAIT_CMD_DONE;
    } 
    else 
    {
        if ((cmd->flags & MMC_CMD_MASK) != MMC_CMD_BC) //with response
        {
            cmd_val |= SDXC_RspExp;
            
            if (cmd->flags & MMC_RSP_136)                                   //long response
                cmd_val |= SDXC_LongRsp;
                
            if (cmd->flags & MMC_RSP_CRC)                                   //check response CRC
            {
                cmd_val |= SDXC_CheckRspCRC;
            }
                
            smc_host->wait = SDC_WAIT_CMD_DONE;
            
            if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC)                //with data transfer
            {
                cmd_val |= SDXC_DataExp | SDXC_WaitPreOver;
                smc_host->wait = SDC_WAIT_DATA_OVER;
                imask |= SDXC_DataOver;
                
                if (cmd->data->flags & MMC_DATA_STREAM)        //sequence mode
                {    
                    imask |= SDXC_AutoCMDDone;
                    cmd_val |= SDXC_Seqmod | SDXC_SendAutoStop;
                    smc_host->wait = SDC_WAIT_AUTOCMD_DONE;
                }
                
                if (smc_host->with_autostop)
                {
                    imask |= SDXC_AutoCMDDone;
                    cmd_val |= SDXC_SendAutoStop;
                    smc_host->wait = SDC_WAIT_AUTOCMD_DONE;
                }
                
                if (cmd->data->flags & MMC_DATA_WRITE)           //read
                {
                    cmd_val |= SDXC_Write;
                }
                else
                {
                    if (!smc_host->dodma)
                        imask &= ~(SDXC_AutoCMDDone | SDXC_DataOver);
                }
            }
        }
    }
    
    sdxc_enable_imask(smc_host, imask);
	
	awsmc_info("smc %d send cmd %d(%08x), imask = 0x%08x, wait = %d\n", smc_host->pdev->id, cmd_val&0x3f, cmd_val, imask, smc_host->wait);
    
    sdc_write(SDXC_REG_CARG, cmd->arg);
    sdc_write(SDXC_REG_CMDR, cmd_val);
}
Beispiel #12
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_fifo_reset(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_GCTRL, sdc_read(SDXC_REG_GCTRL)|SDXC_FIFOReset);
}
Beispiel #13
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_dma_enable(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_GCTRL, sdc_read(SDXC_REG_GCTRL)|SDXC_DMAEnb);
}
Beispiel #14
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_dma_disable(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_GCTRL, sdc_read(SDXC_REG_GCTRL)|SDXC_DMAReset);
    sdc_write(SDXC_REG_GCTRL, sdc_read(SDXC_REG_GCTRL)&(~SDXC_DMAEnb));
}
Beispiel #15
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_idma_reset(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_DMAC, SDXC_IDMACSoftRST);
}
Beispiel #16
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
void sdxc_request(struct awsmc_host* smc_host, struct mmc_request* request)
{
    struct mmc_command* cmd = request->cmd;
    struct mmc_data* data = request->data;
    struct scatterlist* sg = NULL;
    u32 byte_cnt = 0;
    int ret;
    
    smc_host->mrq = request;
    smc_host->int_sum = 0;
    awsmc_dbg("smc %d, cmd %d, arg %08x\n", smc_host->pdev->id, cmd->opcode, cmd->arg);
    if (data)
    {
        sg = data->sg;
        byte_cnt = data->blksz * data->blocks;
        
        sdc_write(SDXC_REG_BLKSZ, data->blksz);
        sdc_write(SDXC_REG_BCNTR, byte_cnt);
        
        awsmc_dbg("-> with data %d bytes, sg_len %d\n", byte_cnt, data->sg_len);
        //if (byte_cnt > 0)
        {
            sdxc_sel_access_mode(smc_host, SDXC_ACCESS_BY_DMA);
            smc_host->todma = 0;
            ret = sdxc_prepare_dma(smc_host, data);
            if (ret < 0)
            {
                awsmc_dbg_err("smc %d prepare DMA failed\n", smc_host->pdev->id);
		        smc_host->dodma = 0;
		        
                awsmc_dbg_err("data prepare error %d\n", ret);
    			cmd->error = ret;
    			cmd->data->error = ret;
    			mmc_request_done(smc_host->mmc, request);
    			return;
            }
            smc_host->dodma = 1;
        }
        
        /*
        if (!smc_host->dodma)
        {
            sdxc_sel_access_mode(smc_host, SDXC_ACCESS_BY_AHB);
            smc_host->dodma = 0;
            uart_send_char('h');
        }
        */
        if (data->stop)
            smc_host->with_autostop = 1;
        else
            smc_host->with_autostop = 0;
    }
    
    /* disable card detect debounce */
    sdxc_cd_debounce_off(smc_host);
    sdxc_send_cmd(smc_host, cmd);
    
    /*
    if (data && !smc_host->dodma)
    {
	    sdxc_disable_imask(smc_host, SDXC_DataOver | SDXC_AutoCMDDone);
        sdxc_trans_by_ahb(smc_host, data);
        sdxc_sel_access_mode(smc_host, SDXC_ACCESS_BY_DMA);
        if (smc_host->with_autostop)
        {
            sdxc_enable_imask(smc_host, SDXC_DataOver | SDXC_AutoCMDDone);
        }
        else
        {
            sdxc_enable_imask(smc_host, SDXC_DataOver);
        }
    }
    */
}
Beispiel #17
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_sel_access_mode(struct awsmc_host* smc_host, u32 access_mode)
{
    sdc_write(SDXC_REG_GCTRL, (sdc_read(SDXC_REG_GCTRL)&(~SDXC_ACCESS_BY_AHB)) | access_mode);
}
Beispiel #18
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_cd_debounce_off(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_GCTRL, sdc_read(SDXC_REG_GCTRL)&(~SDXC_DebounceEnb));
}
Beispiel #19
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_idma_int_disable(struct awsmc_host* smc_host, u32 int_mask)
{
    sdc_write(SDXC_REG_IDIE, sdc_read(SDXC_REG_IDIE) & (~int_mask));
}
Beispiel #20
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_idma_off(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_DMAC, 0);
}
Beispiel #21
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_idma_on(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_DMAC, SDXC_IDMACFixBurst | SDXC_IDMACIDMAOn);
}
Beispiel #22
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_int_disable(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_GCTRL, sdc_read(SDXC_REG_GCTRL)&(~SDXC_INTEnb));
}
Beispiel #23
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
static __inline void sdxc_clear_imask(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_IMASK, sdc_read(SDXC_REG_IMASK)&(SDXC_SDIOInt|SDXC_CardInsert|SDXC_CardRemove));
}
Beispiel #24
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
void sdxc_check_status(struct awsmc_host* smc_host)
{
    u32 raw_int;
    u32 msk_int;
	u32 idma_inte;
    u32 idma_int;
    
    sdxc_int_disable(smc_host);
    
    idma_int = sdc_read(SDXC_REG_IDST);
    idma_inte = sdc_read(SDXC_REG_IDIE);
    raw_int = sdc_read(SDXC_REG_RINTR);
    msk_int = sdc_read(SDXC_REG_MISTA);
    
    smc_host->int_sum |= raw_int;
    awsmc_info("smc %d int, ri %08x(%08x) mi %08x ie %08x idi %08x\n", smc_host->pdev->id, raw_int, smc_host->int_sum, msk_int, idma_inte, idma_int);
    
	if (msk_int & SDXC_SDIOInt) 
	{
		smc_host->sdio_int = 1;
    	sdc_write(SDXC_REG_RINTR, SDXC_SDIOInt);
	}
	
	if (smc_host->cd_gpio == CARD_DETECT_BY_DATA3)
    {
        if (msk_int&SDXC_CardInsert) 
        {
    	    awsmc_dbg("card detect insert\n");
    	    smc_host->present = 1;
    	    smc_host->change = 1;
    	    sdc_write(SDXC_REG_RINTR, SDXC_CardInsert);
    		goto irq_out;
    	}
    	if (msk_int&SDXC_CardRemove) 
    	{
    	    awsmc_dbg("card detect remove\n");
    	    smc_host->present = 0;
    	    smc_host->change = 1;
    	    sdc_write(SDXC_REG_RINTR, SDXC_CardRemove);
    		goto irq_out;
    	}
    }
    
    if (smc_host->wait == SDC_WAIT_NONE && !smc_host->sdio_int)
    {
    	awsmc_dbg_err("smc %x, nothing to complete, raw_int = %08x, mask_int = %08x\n", smc_host->pdev->id, raw_int, msk_int);
    	sdxc_clear_imask(smc_host);
		goto irq_normal_out;
    }
    
    if ((raw_int & SDXC_IntErrBit) || (idma_int & SDXC_IDMA_ERR))
    {
        smc_host->error = raw_int & SDXC_IntErrBit;
        smc_host->wait = SDC_WAIT_FINALIZE;
        goto irq_normal_out;
    }
    
	if (smc_host->wait == SDC_WAIT_AUTOCMD_DONE && (msk_int&SDXC_AutoCMDDone))
	{
	    smc_host->wait = SDC_WAIT_FINALIZE;
	}
	else if (smc_host->wait == SDC_WAIT_DATA_OVER && (msk_int&SDXC_DataOver))
	{
	    smc_host->wait = SDC_WAIT_FINALIZE;
	}
	else if (smc_host->wait == SDC_WAIT_CMD_DONE && (msk_int&SDXC_CmdDone) && !(smc_host->int_sum&SDXC_IntErrBit))
	{
	    smc_host->wait = SDC_WAIT_FINALIZE;
	}
    
//    if (idma_int & (SDXC_IDMACTransmitInt | SDXC_IDMACReceiveInt))
//    {
//    }
irq_normal_out:
    sdc_write(SDXC_REG_RINTR, (~SDXC_SDIOInt) & msk_int);
	sdc_write(SDXC_REG_IDST, idma_int);
	
irq_out:
    
    sdxc_int_enable(smc_host);
}
Beispiel #25
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
void sdxc_sel_sdr_mode(struct awsmc_host* smc_host)
{
    sdc_write(SDXC_REG_GCTRL, sdc_read(SDXC_REG_GCTRL) & (~SDXC_DDR_MODE));
}
Beispiel #26
0
/*********************************************************************
* Method	 :  
* Description:  
* Parameters :  
*	            
* Returns    :  
* Note       :
*********************************************************************/
s32 sdxc_request_done(struct awsmc_host* smc_host)
{
    struct mmc_request* req = smc_host->mrq;
    u32 temp;
    s32 ret = 0;
    
    if (smc_host->int_sum & SDXC_IntErrBit)
    {
        awsmc_dbg_err("smc %d err, cmd %d, %s%s%s%s%s%s%s%s%s%s !!\n", 
            smc_host->pdev->id, req->cmd->opcode,
    		smc_host->int_sum & SDXC_RespErr     ? " RE"     : "",
    		smc_host->int_sum & SDXC_RespCRCErr  ? " RCE"    : "",
    		smc_host->int_sum & SDXC_DataCRCErr  ? " DCE"    : "",
    		smc_host->int_sum & SDXC_RespTimeout ? " RTO"    : "",
    		smc_host->int_sum & SDXC_DataTimeout ? " DTO"    : "",
    		smc_host->int_sum & SDXC_DataStarve  ? " DS"     : "",
    		smc_host->int_sum & SDXC_FIFORunErr  ? " FE"     : "",
    		smc_host->int_sum & SDXC_HardWLocked ? " HL"     : "",
    		smc_host->int_sum & SDXC_StartBitErr ? " SBE"    : "",
    		smc_host->int_sum & SDXC_EndBitErr   ? " EBE"    : ""
    		);
        
        if (req->data)
        {
            awsmc_dbg_err("In data %s operation\n", req->data->flags & MMC_DATA_WRITE ? "write" : "read");
        }
    	ret = -1;
        goto _out_;
    }
    
    if (req->cmd)
    {
        if (req->cmd->flags & MMC_RSP_136)
    	{
    		req->cmd->resp[0] = sdc_read(SDXC_REG_RESP3);
    		req->cmd->resp[1] = sdc_read(SDXC_REG_RESP2);
    		req->cmd->resp[2] = sdc_read(SDXC_REG_RESP1);
    		req->cmd->resp[3] = sdc_read(SDXC_REG_RESP0);
    	}
    	else
    	{
    		req->cmd->resp[0] = sdc_read(SDXC_REG_RESP0);
    	}
    }
    
_out_:
    if (req->data)
    {
        if (!(req->data->flags & MMC_DATA_WRITE) && (sdc_read(SDXC_REG_STAS) & SDXC_DataFSMBusy))
        {
            printk("data fsm busy\n");
        }
        if (smc_host->dodma)
        {
    		smc_host->dma_done = 0;
            sdc_write(SDXC_REG_IDST, 0x337);
            sdc_write(SDXC_REG_IDIE, 0);
            sdxc_idma_off(smc_host);
            sdxc_dma_disable(smc_host);
        }
        
        sdxc_fifo_reset(smc_host);
    }
    
    temp = sdc_read(SDXC_REG_STAS);
    if ((temp & SDXC_DataFSMBusy) || (smc_host->int_sum & (SDXC_RespErr | SDXC_HardWLocked | SDXC_RespTimeout)))
    {
        awsmc_dbg("sdc %d abnormal status: %s %s\n", smc_host->pdev->id,
                                                  temp & SDXC_DataFSMBusy ? "DataFSMBusy" : "",
                                                  smc_host->int_sum & SDXC_HardWLocked ? "HardWLocked" : "");
        sdxc_reset(smc_host);
        sdxc_program_clk(smc_host);
    }
    
    sdc_write(SDXC_REG_RINTR, 0xffff);
    sdxc_clear_imask(smc_host);
    //re-enable card detect debounce
    if (smc_host->cd_gpio == CARD_DETECT_BY_DATA3)
    {
        sdxc_cd_debounce_on(smc_host);
    }

    awsmc_dbg("smc %d done, resp %08x %08x %08x %08x\n", smc_host->pdev->id, req->cmd->resp[0], req->cmd->resp[1], req->cmd->resp[2], req->cmd->resp[3]);
    
	if (req->data && req->data->stop && (smc_host->int_sum & SDXC_IntErrBit))
	{
		awsmc_msg("found data error, need to send stop command !!\n");
		sdxc_send_manual_stop(smc_host, req);
	}
    
    if ((smc_host->pdev->id==3) && req->data && (req->data->flags & MMC_DATA_WRITE) && !(smc_host->int_sum & SDXC_IntErrBit))
    {
        u32 ready = 0;
//        u32 i = 0;
        do {
//            awsmc_msg("smc %d check ready %d \r", smc_host->pdev->id, i++);
            ready = sdxc_check_r1_ready(smc_host);
        } while (!ready);
//        awsmc_msg("\n");
    }
    return ret;
}
Beispiel #27
0
int ArcCommand::ReplaceVar(std::string &Command)
{
  int MaxNamesLength = 0x10000;
  std::string LocalAllFilesMask = AllFilesMask;
  bool UseSlash = false;
  bool FolderMask = false;
  bool FolderName = false;
  bool NameOnly = false;
  bool PathOnly = false;
  int QuoteName = 0;

  if (Command.size() < 3)
    return 0;

  char Chr = Command[2] & (~0x20);
  if (Command[0] != '%' || Command[1] != '%' || Chr < 'A' || Chr > 'Z')
    return 0;

  int VarLength = 3;

  while (VarLength < Command.size())
  {
    bool BreakScan = false;
    Chr = Command[VarLength];
    if (Command[2]=='F' && Chr >= '0' && Chr <= '9')
    {
      MaxNamesLength = FSF.atoi(Command.c_str() + VarLength);
      while (Chr >= '0' && Chr <= '9' && VarLength < Command.size())
        Chr = Command[++VarLength];
      continue;
    }
    if (Command[2]=='E' && Chr >= '0' && Chr <= '9')
    {
      MaxAllowedExitCode = FSF.atoi(Command.c_str() + VarLength);
      while (Chr >= '0' && Chr <= '9' && VarLength < Command.size())
        Chr=Command[++VarLength];
      continue;
    }
    switch (Command[VarLength])
    {
      case 'A': break; /* deprecated AnsiCode = true; */
      case 'Q': QuoteName = 1; break;
      case 'q': QuoteName = 2; break;
      case 'S': UseSlash = true; break;
      case 'M': FolderMask = true; break;
      case 'N': FolderName = true; break;
      case 'W': NameOnly = true; break;
      case 'P': PathOnly = true; break;
      case '*': LocalAllFilesMask = "*"; break;
      default: BreakScan = true;
    }
    if (BreakScan)
      break;
    VarLength++;
  }

  if ( (MaxNamesLength-=(int)Command.size()) <= 0)
    MaxNamesLength = 1;

  if (!FolderMask && !FolderName)
    FolderName = true;

/////////////////////////////////
  switch (Command[2])
  {
    case 'A': case 'a': /* deprecated: short name - works same as normal name */
      Command = ArcName;
      if (PathOnly)
        CutToPathOrSpace(Command);
      QuoteCmdArgIfNeed(Command);
      break;

    case 'D': case 'E':
      Command.clear();
      break;

    case 'L': case 'l':
      if (!MakeListFile(ListFileName, QuoteName, UseSlash, FolderName,
         NameOnly, PathOnly, FolderMask, LocalAllFilesMask.c_str())) {
        return -1;
      }
      Command = ListFileName;
      QuoteCmdArgIfNeed(Command);
      break;

    case 'P':
      Command = Password;
      break;

    case 'C':
      if (*CommentFileName) //второй раз сюда не лезем
        break;
      {
        Command.clear();
        int CommentFile;
        if (FSF.MkTemp(CommentFileName, "FAR") && (CommentFile =
          sdc_open(CommentFileName, O_CREAT | O_TRUNC | O_RDWR, 0660)) != -1)
        {
          char Buf[512];
          if(Info.InputBox(GetMsg(MComment), GetMsg(MInputComment), NULL, "", Buf, sizeof(Buf), NULL, 0))
          //??тут можно и заполнить строку комментарием, но надо знать, файловый
          //?? он или архивный. да и имя файла в архиве тоже надо знать...
          {
            sdc_write(CommentFile, Buf, strlen(Buf));
            sdc_close(CommentFile);
            Command = CommentFileName;
          }
          WINPORT(FlushConsoleInputBuffer)(NULL);//GetStdHandle(STD_INPUT_HANDLE));
        }
      }
      break;

    case 'r':
      Command = RealArcDir;
      if (!Command.empty())
        Command+= '/';
      break;
    case 'R':
      Command = RealArcDir;
      if (UseSlash)
      {
      }
      QuoteCmdArgIfNeed(Command);
      break;

    case 'W':
      Command = TempPath;
      break;

    case 'F': case 'f':
      if (PanelItem!=NULL)
      {
        std::string CurArcDir = ArcDir;
        if (!CurArcDir.empty() && CurArcDir[CurArcDir.size() - 1] != GOOD_SLASH)
          CurArcDir+= GOOD_SLASH;

        std::string Names, Name;

        if (NameNumber == -1)
          NameNumber = 0;

        while (NameNumber < ItemsNumber || Command[2] == 'f')
        {
          int IncreaseNumber = 0;
          DWORD FileAttr;
          if (!NextFileName.empty())
          {
            Name = PrefixFileName;
            Name+= CurArcDir;
            Name+= NextFileName;
            NextFileName.clear();
            FileAttr = 0;
          }
          else
          {
            int N;
            if (Command[2]=='f' && PrevFileNameNumber!=-1)
              N = PrevFileNameNumber;
            else
            {
              N = NameNumber;
              IncreaseNumber=1;
            }
            if (N >= ItemsNumber)
              break;

            *PrefixFileName=0;
            char *cFileName = PanelItem[N].FindData.cFileName;

            if(PanelItem[N].UserData && (PanelItem[N].Flags & PPIF_USERDATA))
            {
              struct ArcItemUserData *aud=(struct ArcItemUserData*)PanelItem[N].UserData;
              if(aud->SizeStruct == sizeof(struct ArcItemUserData))
              {
                if(aud->Prefix)
                  strncpy(PrefixFileName,aud->Prefix,sizeof(PrefixFileName));
                if(aud->LinkName)
                  cFileName=aud->LinkName;
              }
            }
            // CHECK for BUGS!!
            Name = PrefixFileName;
            if(*cFileName != GOOD_SLASH)
            {
              Name+= CurArcDir;
              Name+= cFileName;
            }
            else
              Name+= cFileName+1;
            NormalizePath(Name);
            FileAttr = PanelItem[N].FindData.dwFileAttributes;
            PrevFileNameNumber = N;
          }
          if (NameOnly)
          {
            size_t slash = Name.rfind(GOOD_SLASH);
            if (slash != std::string::npos)
              Name.erase(0, slash + 1);
          }
          if (PathOnly)
            CutToPathOrSpace(Name);
          if (Names.empty() || (Names.size() + Name.size() < MaxNamesLength && Command[2] != 'f'))
          {
            NameNumber+= IncreaseNumber;
            if (FileAttr & FILE_ATTRIBUTE_DIRECTORY)
            {
              std::string FolderMaskName = Name;
              if (!PathOnly)
              {
                FolderMaskName+= GOOD_SLASH;
                FolderMaskName+= LocalAllFilesMask;
              }
              else
                CutToPathOrSpace(FolderMaskName);
              if (FolderMask)
              {
                if (FolderName)
                  NextFileName.swap(FolderMaskName);
                else
                  Name.swap(FolderMaskName);
              }
            }

            if (QuoteName==1)
              QuoteCmdArgIfNeed(Name);
            else if (QuoteName==2)
              QuoteCmdArg(Name);

            if (!Names.empty())
              Names+= ' ';
            Names+= Name;
          }
          else
            break;
        }
        Command.swap(Names);
      }
      else
        Command.clear();
      break;
    default:
      return 0;
  }

  return VarLength;
}