static int sd_request(struct memory_card *card, struct card_blk_request *brq) { SD_MMC_Card_Info_t *sd_mmc_info = (SD_MMC_Card_Info_t *)card->card_info; unsigned int lba, byte_cnt; unsigned char *data_buf; struct card_host *host = card->host; struct memory_card *sdio_card; lba = brq->card_data.lba; byte_cnt = brq->card_data.blk_size * brq->card_data.blk_nums; data_buf = brq->crq.buf; if(sd_mmc_info == NULL){ brq->card_data.error = SD_MMC_ERROR_NO_CARD_INS; printk("[sd_request] sd_mmc_info == NULL, return SD_MMC_ERROR_NO_CARD_INS\n"); return 0; } sdio_close_host_interrupt(SDIO_IF_INT); sd_sdio_enable(sd_mmc_info->io_pad_type); if(brq->crq.cmd == READ) { brq->card_data.error = sd_mmc_read_data(sd_mmc_info, lba, byte_cnt, data_buf); } else if(brq->crq.cmd == WRITE) { brq->card_data.error = sd_mmc_write_data(sd_mmc_info, lba, byte_cnt, data_buf); } sd_gpio_enable(sd_mmc_info->io_pad_type); sdio_card = card_find_card(host, CARD_SDIO); if(sdio_card) { sd_mmc_info = (SD_MMC_Card_Info_t *)sdio_card->card_info; sd_sdio_enable(sd_mmc_info->io_pad_type); sdio_open_host_interrupt(SDIO_IF_INT); if (sd_mmc_info->sd_save_hw_io_flag) { WRITE_CBUS_REG(SDIO_CONFIG, sd_mmc_info->sd_save_hw_io_config); WRITE_CBUS_REG(SDIO_MULT_CONFIG, sd_mmc_info->sd_save_hw_io_mult_config); } } return 0; }
static int sdio_request(struct memory_card *card, struct card_blk_request *brq) { SD_MMC_Card_Info_t *sdio_info = (SD_MMC_Card_Info_t *)card->card_info; int incr_addr, err; unsigned addr, blocks, blksz, fn, read_after_write; u8 *in, *out, *buf; sd_sdio_enable(sdio_info->io_pad_type); if (brq->crq.cmd & SDIO_OPS_REG) { WARN_ON(brq->card_data.blk_size != 1); WARN_ON(brq->card_data.blk_nums != 1); in = brq->crq.buf; addr = brq->card_data.lba; fn = brq->card_data.flags; out = brq->crq.back_buf; if (brq->crq.cmd & READ_AFTER_WRITE) read_after_write = 1; else read_after_write = 0; if ((brq->crq.cmd & 0x1 )== WRITE) { err = sdio_write_reg(sdio_info, fn, addr, in, read_after_write); if (err) { printk("sdio card write_reg failed %d at addr: %x \n", err, addr); brq->card_data.error = err; goto err; } } else { err = sdio_read_reg(sdio_info, fn, addr, out); if (err) { printk("sdio card read_reg failed %d at addr: %x \n", err, addr); brq->card_data.error = err; goto err; } } } else { if (brq->crq.cmd & SDIO_FIFO_ADDR) incr_addr = 1; else incr_addr = 0; buf = brq->crq.buf; addr = brq->card_data.lba; blksz = brq->card_data.blk_size; blocks = brq->card_data.blk_nums; fn = brq->card_data.flags; sdio_info->sdio_blk_len[fn] = card->sdio_func[fn-1]->cur_blksize; if ((brq->crq.cmd & 0x1)== WRITE) { err = sdio_write_data(sdio_info, fn, incr_addr, addr, blocks*blksz, buf); if (err) { printk("sdio card write_data failed %d at addr: %x, function: %d \n", err, addr, fn); brq->card_data.error = err; goto err; } } else { err = sdio_read_data(sdio_info, fn, incr_addr, addr, blocks*blksz, buf); if (err) { printk("sdio card read_data failed %d at addr: %x, function: %d\n", err, addr, fn); brq->card_data.error = err; goto err; } } } //sd_gpio_enable(sdio_info->io_pad_type); brq->card_data.error = 0; return 0; err: //sd_gpio_enable(sdio_info->io_pad_type); return err; }
static int sd_request(struct memory_card *card, struct card_blk_request *brq) { SD_MMC_Card_Info_t *sd_mmc_info = (SD_MMC_Card_Info_t *)card->card_info; unsigned int lba, byte_cnt,ret; unsigned char *data_buf; struct card_host *host = card->host; struct memory_card *sdio_card; SD_MMC_Card_Info_t *sdio_info; lba = brq->card_data.lba; byte_cnt = brq->card_data.blk_size * brq->card_data.blk_nums; data_buf = brq->crq.buf; if(sd_mmc_info == NULL){ brq->card_data.error = SD_MMC_ERROR_NO_CARD_INS; printk("[sd_request] sd_mmc_info == NULL, return SD_MMC_ERROR_NO_CARD_INS\n"); return 0; } if(!sd_mmc_info->blk_len){ card->card_io_init(card); card->card_detector(card); if(card->card_status == CARD_REMOVED){ brq->card_data.error = SD_MMC_ERROR_NO_CARD_INS; return 0; } #if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6 switch_mod_gate_by_type(MOD_SDIO,1); #endif ret = sd_mmc_init(sd_mmc_info); #if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6 switch_mod_gate_by_type(MOD_SDIO,0); #endif if(ret){ brq->card_data.error = SD_MMC_ERROR_NO_CARD_INS; return 0; } } #if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6 switch_mod_gate_by_type(MOD_SDIO,1); #endif sdio_card = card_find_card(host, CARD_SDIO); if (sdio_card) { sdio_close_host_interrupt(SDIO_IF_INT); sdio_info = (SD_MMC_Card_Info_t *)sdio_card->card_info; sd_gpio_enable(sdio_info->io_pad_type); } sd_sdio_enable(sd_mmc_info->io_pad_type); if(brq->crq.cmd == READ) { brq->card_data.error = sd_mmc_read_data(sd_mmc_info, lba, byte_cnt, data_buf); } else if(brq->crq.cmd == WRITE) { brq->card_data.error = sd_mmc_write_data(sd_mmc_info, lba, byte_cnt, data_buf); } sd_gpio_enable(sd_mmc_info->io_pad_type); if(brq->card_data.error == SD_WAIT_FOR_COMPLETION_TIMEOUT) { printk("[sd_request] wait for completion timeout, reinit\n"); card->card_io_init(card); card->card_detector(card); if(card->card_status == CARD_REMOVED){ printk("[sd_request] card removed\n"); brq->card_data.error = SD_MMC_ERROR_NO_CARD_INS; return 0; } sd_mmc_staff_init(sd_mmc_info); ret = sd_mmc_init(sd_mmc_info); if(ret){ printk("[sd_request] reinit fail %d\n", ret); brq->card_data.error = SD_MMC_ERROR_NO_CARD_INS; return 0; } sd_sdio_enable(sd_mmc_info->io_pad_type); if(brq->crq.cmd == READ) { brq->card_data.error = sd_mmc_read_data(sd_mmc_info, lba, byte_cnt, data_buf); } else if(brq->crq.cmd == WRITE) { brq->card_data.error = sd_mmc_write_data(sd_mmc_info, lba, byte_cnt, data_buf); } sd_gpio_enable(sd_mmc_info->io_pad_type); if(brq->card_data.error == SD_WAIT_FOR_COMPLETION_TIMEOUT) printk("[sd_request] after reinit still error \n"); } sdio_card = card_find_card(host, CARD_SDIO); if(sdio_card) { sdio_info = (SD_MMC_Card_Info_t *)sdio_card->card_info; sd_sdio_enable(sdio_info->io_pad_type); if (sdio_info->sd_save_hw_io_flag) { WRITE_CBUS_REG(SDIO_CONFIG, sdio_info->sd_save_hw_io_config); WRITE_CBUS_REG(SDIO_MULT_CONFIG, sdio_info->sd_save_hw_io_mult_config); } sdio_open_host_interrupt(SDIO_IF_INT); } #if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6 switch_mod_gate_by_type(MOD_SDIO,0); #endif return 0; }