/********************************************************************* * 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; }
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; }
/********************************************************************* * 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; }
/********************************************************************* * 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; }
/********************************************************************* * 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; } }
/********************************************************************* * 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; }
/********************************************************************* * 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); }
/********************************************************************* * 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; }
/********************************************************************* * 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; }
/********************************************************************* * 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); }
/********************************************************************* * 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); }
/********************************************************************* * 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); }
/********************************************************************* * 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); }
/********************************************************************* * 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)); }
/********************************************************************* * Method : * Description: * Parameters : * * Returns : * Note : *********************************************************************/ static __inline void sdxc_idma_reset(struct awsmc_host* smc_host) { sdc_write(SDXC_REG_DMAC, SDXC_IDMACSoftRST); }
/********************************************************************* * 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); } } */ }
/********************************************************************* * 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); }
/********************************************************************* * 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)); }
/********************************************************************* * 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)); }
/********************************************************************* * Method : * Description: * Parameters : * * Returns : * Note : *********************************************************************/ static __inline void sdxc_idma_off(struct awsmc_host* smc_host) { sdc_write(SDXC_REG_DMAC, 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); }
/********************************************************************* * 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)); }
/********************************************************************* * 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)); }
/********************************************************************* * 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); }
/********************************************************************* * 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)); }
/********************************************************************* * 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; }
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; }