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 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; }