static int sd_ioctl_reinit(struct msdc_ioctl* msdc_ctl) { struct msdc_host *host = msdc_get_host(MSDC_SD,0,0); if (NULL != host) { return msdc_reinit(host); } else { return -EINVAL; } }
static int simple_mmc_get_disk_info(struct mbr_part_info *mpi, unsigned char *name) { int i = 0; char* no_partition_name = "n/a"; struct disk_part_iter piter; struct hd_struct *part; struct msdc_host *host; struct gendisk *disk; struct __mmc_blk_data *md; if(!name || !mpi) return -EINVAL; /* emmc always in slot0 */ host = msdc_get_host(MSDC_EMMC,MSDC_BOOT_EN,0); BUG_ON(!host); BUG_ON(!host->mmc); BUG_ON(!host->mmc->card); md = mmc_get_drvdata(host->mmc->card); BUG_ON(!md); BUG_ON(!md->disk); disk = md->disk; /* use this way to find partition info is to avoid handle addr transfer in scatter file * and 64bit address calculate */ disk_part_iter_init(&piter, disk, 0); while ((part = disk_part_iter_next(&piter))){ for (i = 0; i < PART_NUM; i++) { if ((PartInfo[i].partition_idx != 0) && (PartInfo[i].partition_idx == part->partno)) { #if DEBUG_MMC_IOCTL pr_debug("part_name = %s name = %s\n", PartInfo[i].name, name); #endif if (!strncmp(PartInfo[i].name, name, PARTITION_NAME_LENGTH)) { mpi->start_sector = part->start_sect; mpi->nr_sects = part->nr_sects; mpi->part_no = part->partno; if (i < PART_NUM) { mpi->part_name = PartInfo[i].name; } else { mpi->part_name = no_partition_name; } disk_part_iter_exit(&piter); return 0; } break; } } } disk_part_iter_exit(&piter); return 1; }
void msdc_check_init_done(void) { struct msdc_host *host = NULL; host = msdc_get_host(MSDC_EMMC,1,0); BUG_ON(!host); BUG_ON(!host->mmc); host->mmc->card_init_wait(host->mmc); BUG_ON(!host->mmc->card); return; }
void msdc_check_init_done(void) { struct msdc_host *host = NULL; host = msdc_get_host(MSDC_EMMC, 1, 0); BUG_ON(!host); BUG_ON(!host->mmc); host->mmc->card_init_wait(host->mmc); BUG_ON(!host->mmc->card); pr_err("[%s]: get the emmc init done signal\n", __func__); return; }
int mt65xx_mmc_change_disk_info(unsigned int px, unsigned int addr, unsigned int size) { #ifdef MTK_EMMC_SUPPORT struct disk_part_iter piter; struct hd_struct *part; struct msdc_host *host; struct gendisk *disk; struct __mmc_blk_data *md; int i; /* emmc always in slot0 */ host = msdc_get_host(MSDC_EMMC,MSDC_BOOT_EN,0); BUG_ON(!host); BUG_ON(!host->mmc); BUG_ON(!host->mmc->card); md = mmc_get_drvdata(host->mmc->card); BUG_ON(!md); BUG_ON(!md->disk); disk = md->disk; disk_part_iter_init(&piter, disk, 0); for(i=0;i<PART_NUM;i++){ if((PartInfo[i].partition_idx == px)&&((!strncmp(PartInfo[i].name,"usrdata",7))||(!strncmp(PartInfo[i].name,"sec_ro",6))||(!strncmp(PartInfo[i].name,"android",7))||(!strncmp(PartInfo[i].name,"cache",5)))){ printk("update %s,need reduce 1MB in block device\n",PartInfo[i].name); size -= (0x100000)/512; } } while ((part = disk_part_iter_next(&piter))){ if (px != 0 && px == part->partno) { //#if DEBUG_MMC_IOCTL printk("[mt65xx_mmc_change_disk_info]px = %d size %llx -> %x offset %llx -> %x\n",px,part->nr_sects,size,part->start_sect,addr); //#endif part->start_sect = addr; part->nr_sects = size; disk_part_iter_exit(&piter); return 0; } } disk_part_iter_exit(&piter); return 1; #else return 0; #endif }
static int sd_ioctl_cd_pin_en(struct msdc_ioctl *msdc_ctl) { struct msdc_host *host = msdc_get_host(MSDC_SD, 0, 0); if (NULL != host) { if (host->hw->host_function == MSDC_SD) { return (host->hw->flags & MSDC_CD_PIN_EN == MSDC_CD_PIN_EN); } else { return -EINVAL; } } else { return -EINVAL; } }
static int simple_mmc_get_disk_info(struct mbr_part_info* mpi, unsigned char* name) { char* no_partition_name = "n/a"; struct disk_part_iter piter; struct hd_struct *part; struct msdc_host *host; struct gendisk *disk; struct __mmc_blk_data *md; /* emmc always in slot0 */ host = msdc_get_host(MSDC_EMMC,MSDC_BOOT_EN,0); BUG_ON(!host); BUG_ON(!host->mmc); BUG_ON(!host->mmc->card); md = mmc_get_drvdata(host->mmc->card); BUG_ON(!md); BUG_ON(!md->disk); disk = md->disk; /* use this way to find partition info is to avoid handle addr transfer in scatter file * and 64bit address calculate */ disk_part_iter_init(&piter, disk, 0); while ((part = disk_part_iter_next(&piter))){ #if DEBUG_MMC_IOCTL printk("part_name = %s name = %s\n", part->info->volname, name); #endif if (!strncmp(part->info->volname, name, PARTITION_NAME_LENGTH)){ mpi->start_sector = part->start_sect; mpi->nr_sects = part->nr_sects; mpi->part_no = part->partno; if (part->info){ mpi->part_name = part->info->volname; } else { mpi->part_name = no_partition_name; } disk_part_iter_exit(&piter); return 0; } } disk_part_iter_exit(&piter); return 1; }
/* call mmc block layer interface for userspace to do erase operate */ static int simple_mmc_erase_func(unsigned int start, unsigned int size) { struct msdc_host *host; unsigned int arg; /* emmc always in slot0 */ host = msdc_get_host(MSDC_EMMC,MSDC_BOOT_EN,0); BUG_ON(!host); BUG_ON(!host->mmc); BUG_ON(!host->mmc->card); mmc_claim_host(host->mmc); if(mmc_can_discard(host->mmc->card)) { arg = __MMC_DISCARD_ARG; }else if (host->mmc->card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN){ /* for Hynix eMMC chip£¬do trim even if it is MMC_QUIRK_TRIM_UNSTABLE */ arg = __MMC_TRIM_ARG; }else if(mmc_can_erase(host->mmc->card)){ /* mmc_erase() will remove the erase group un-aligned part, * msdc_command_start() will do trim for old combo erase un-aligned issue */ arg = __MMC_ERASE_ARG; }else { printk("[%s]: emmc card can't support trim / discard / erase\n", __func__); goto end; } printk("[%s]: start=0x%x, size=%d, arg=0x%x, can_trim=(0x%x),EXT_CSD_SEC_GB_CL_EN=0x%x\n", __func__, start, size, arg, host->mmc->card->ext_csd.sec_feature_support, EXT_CSD_SEC_GB_CL_EN); mmc_erase(host->mmc->card, start, size, arg); #if DEBUG_MMC_IOCTL printk("[%s]: erase done....arg=0x%x\n", __func__, arg); #endif end: mmc_release_host(host->mmc); return 0; }
static int sd_ioctl_reinit(struct msdc_ioctl* msdc_ctl) { struct msdc_host *host = msdc_get_host(MSDC_SD,0,0); return msdc_reinit(host); }
int msdc_get_info(STORAGE_TPYE storage_type, GET_STORAGE_INFO info_type, struct storage_info *info) { struct msdc_host *host = NULL; int host_function = 0; bool boot = 0; if(!info) return -EINVAL; switch (storage_type) { case EMMC_CARD_BOOT: host_function = MSDC_EMMC; boot = MSDC_BOOT_EN; break; case EMMC_CARD: host_function = MSDC_EMMC; break; case SD_CARD_BOOT: host_function = MSDC_SD; boot = MSDC_BOOT_EN; break; case SD_CARD: host_function = MSDC_SD; break; default: pr_err(KERN_ERR "No supported storage type!"); return 0; break; } host = msdc_get_host(host_function, boot, 0); BUG_ON(!host); BUG_ON(!host->mmc); BUG_ON(!host->mmc->card); switch (info_type) { case CARD_INFO: if (host->mmc && host->mmc->card) info->card = host->mmc->card; else { pr_err(KERN_ERR "CARD was not ready<get card>!"); return 0; } break; case DISK_INFO: if (host->mmc && host->mmc->card) info->disk = mmc_get_disk(host->mmc->card); else { pr_err(KERN_ERR "CARD was not ready<get disk>!"); return 0; } break; case EMMC_USER_CAPACITY: info->emmc_user_capacity = msdc_get_capacity(0); break; case EMMC_CAPACITY: info->emmc_capacity = msdc_get_capacity(1); break; case EMMC_RESERVE: #ifdef CONFIG_MTK_EMMC_SUPPORT info->emmc_reserve = msdc_get_reserve(); #endif break; default: pr_err(KERN_ERR "Please check INFO_TYPE"); return 0; } return 1; }