diff --git a/cmd/mmc.c b/cmd/mmc.c index 8695c19187..eb4a547a97 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -348,7 +348,7 @@ static int do_mmc_read(cmd_tbl_t *cmdtp, int flag, printf("\nMMC read: dev # %d, block # %d, count %d ... ", curr_device, blk, cnt); - n = blk_dread(&mmc->block_dev, blk, cnt, addr); + n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr); /* flush cache after read */ flush_cache((ulong)addr, cnt * 512); /* FIXME */ printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR"); @@ -380,7 +380,7 @@ static int do_mmc_write(cmd_tbl_t *cmdtp, int flag, printf("Error: card is write protected!\n"); return CMD_RET_FAILURE; } - n = blk_dwrite(&mmc->block_dev, blk, cnt, addr); + n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr); printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; @@ -408,7 +408,7 @@ static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag, printf("Error: card is write protected!\n"); return CMD_RET_FAILURE; } - n = blk_derase(&mmc->block_dev, blk, cnt); + n = blk_derase(mmc_get_blk_desc(mmc), blk, cnt); printf("%d blocks erased: %s\n", n, (n == cnt) ? "OK" : "ERROR"); return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; @@ -480,7 +480,7 @@ static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag, printf("mmc%d is current device\n", curr_device); else printf("mmc%d(part %d) is current device\n", - curr_device, mmc->block_dev.hwpart); + curr_device, mmc_get_blk_desc(mmc)->hwpart); return CMD_RET_SUCCESS; } diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 585aaf3115..624164902d 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -7,6 +7,10 @@ obj-$(CONFIG_DM_MMC) += mmc-uclass.o +ifndef CONFIG_BLK +obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o +endif + obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o obj-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 7322f33404..48aedc212c 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -21,14 +21,6 @@ #include #include "mmc_private.h" -static struct list_head mmc_devices; -static int cur_dev_num = -1; - -struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) -{ - return &mmc->block_dev; -} - __weak int board_mmc_getwp(struct mmc *mmc) { return -1; @@ -183,25 +175,6 @@ int mmc_set_blocklen(struct mmc *mmc, int len) return mmc_send_cmd(mmc, &cmd, NULL); } -struct mmc *find_mmc_device(int dev_num) -{ - struct mmc *m; - struct list_head *entry; - - list_for_each(entry, &mmc_devices) { - m = list_entry(entry, struct mmc, link); - - if (m->block_dev.devnum == dev_num) - return m; - } - -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - printf("MMC Device %d not found\n", dev_num); -#endif - - return NULL; -} - static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, lbaint_t blkcnt) { @@ -261,10 +234,10 @@ static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, if (err < 0) return 0; - if ((start + blkcnt) > mmc->block_dev.lba) { + if ((start + blkcnt) > block_dev->lba) { #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n", - start + blkcnt, mmc->block_dev.lba); + start + blkcnt, block_dev->lba); #endif return 0; } @@ -582,7 +555,7 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num) return -1; } - mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len); + mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len); return 0; } @@ -1062,6 +1035,7 @@ static int mmc_startup(struct mmc *mmc) int timeout = 1000; bool has_parts = false; bool part_completed; + struct blk_desc *bdesc; #ifdef CONFIG_MMC_SPI_CRC_ON if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */ @@ -1358,7 +1332,7 @@ static int mmc_startup(struct mmc *mmc) mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET]; } - err = mmc_set_capacity(mmc, mmc->block_dev.hwpart); + err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart); if (err) return err; @@ -1498,31 +1472,32 @@ static int mmc_startup(struct mmc *mmc) } /* fill in device description */ - mmc->block_dev.lun = 0; - mmc->block_dev.hwpart = 0; - mmc->block_dev.type = 0; - mmc->block_dev.blksz = mmc->read_bl_len; - mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz); - mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len); + bdesc = mmc_get_blk_desc(mmc); + bdesc->lun = 0; + bdesc->hwpart = 0; + bdesc->type = 0; + bdesc->blksz = mmc->read_bl_len; + bdesc->log2blksz = LOG2(bdesc->blksz); + bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len); #if !defined(CONFIG_SPL_BUILD) || \ (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \ !defined(CONFIG_USE_TINY_PRINTF)) - sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x", + sprintf(bdesc->vendor, "Man %06x Snr %04x%04x", mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff), (mmc->cid[3] >> 16) & 0xffff); - sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff, + sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff, (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff, (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff, (mmc->cid[2] >> 24) & 0xff); - sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf, + sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf, (mmc->cid[2] >> 16) & 0xf); #else - mmc->block_dev.vendor[0] = 0; - mmc->block_dev.product[0] = 0; - mmc->block_dev.revision[0] = 0; + bdesc->vendor[0] = 0; + bdesc->product[0] = 0; + bdesc->revision[0] = 0; #endif #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT) - part_init(&mmc->block_dev); + part_init(bdesc); #endif return 0; @@ -1562,6 +1537,7 @@ int __deprecated mmc_register(struct mmc *mmc) struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) { + struct blk_desc *bdesc; struct mmc *mmc; /* quick validation */ @@ -1582,19 +1558,17 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) mmc->dsr_imp = 0; mmc->dsr = 0xffffffff; /* Setup the universal parts of the block interface just once */ - mmc->block_dev.if_type = IF_TYPE_MMC; - mmc->block_dev.devnum = cur_dev_num++; - mmc->block_dev.removable = 1; - mmc->block_dev.block_read = mmc_bread; - mmc->block_dev.block_write = mmc_bwrite; - mmc->block_dev.block_erase = mmc_berase; + bdesc = mmc_get_blk_desc(mmc); + bdesc->if_type = IF_TYPE_MMC; + bdesc->removable = 1; + bdesc->devnum = mmc_get_next_devnum(); + bdesc->block_read = mmc_bread; + bdesc->block_write = mmc_bwrite; + bdesc->block_erase = mmc_berase; /* setup initial part type */ - mmc->block_dev.part_type = mmc->cfg->part_type; - - INIT_LIST_HEAD(&mmc->link); - - list_add_tail(&mmc->link, &mmc_devices); + bdesc->part_type = mmc->cfg->part_type; + mmc_list_add(mmc); return mmc; } @@ -1664,7 +1638,7 @@ int mmc_start_init(struct mmc *mmc) return err; /* The internal partition reset to user partition(0) at every CMD0*/ - mmc->block_dev.hwpart = 0; + mmc_get_blk_desc(mmc)->hwpart = 0; /* Test for SD version 2 */ err = mmc_send_if_cond(mmc); @@ -1744,66 +1718,11 @@ __weak int board_mmc_init(bd_t *bis) return -1; } -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - -void print_mmc_devices(char separator) -{ - struct mmc *m; - struct list_head *entry; - char *mmc_type; - - list_for_each(entry, &mmc_devices) { - m = list_entry(entry, struct mmc, link); - - if (m->has_init) - mmc_type = IS_SD(m) ? "SD" : "eMMC"; - else - mmc_type = NULL; - - printf("%s: %d", m->cfg->name, m->block_dev.devnum); - if (mmc_type) - printf(" (%s)", mmc_type); - - if (entry->next != &mmc_devices) { - printf("%c", separator); - if (separator != '\n') - puts (" "); - } - } - - printf("\n"); -} - -#else -void print_mmc_devices(char separator) { } -#endif - -int get_mmc_num(void) -{ - return cur_dev_num; -} - void mmc_set_preinit(struct mmc *mmc, int preinit) { mmc->preinit = preinit; } -static void do_preinit(void) -{ - struct mmc *m; - struct list_head *entry; - - list_for_each(entry, &mmc_devices) { - m = list_entry(entry, struct mmc, link); - -#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT - mmc_set_preinit(m, 1); -#endif - if (m->preinit) - mmc_start_init(m); - } -} - #if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD) static int mmc_probe(bd_t *bis) { @@ -1856,9 +1775,9 @@ int mmc_initialize(bd_t *bis) return 0; initialized = 1; - INIT_LIST_HEAD (&mmc_devices); - cur_dev_num = 0; - +#ifndef CONFIG_BLK + mmc_list_init(); +#endif ret = mmc_probe(bis); if (ret) return ret; @@ -1867,7 +1786,7 @@ int mmc_initialize(bd_t *bis) print_mmc_devices(','); #endif - do_preinit(); + mmc_do_preinit(); return 0; } diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c new file mode 100644 index 0000000000..3ec649f2b8 --- /dev/null +++ b/drivers/mmc/mmc_legacy.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2016 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +static struct list_head mmc_devices; +static int cur_dev_num = -1; + +struct mmc *find_mmc_device(int dev_num) +{ + struct mmc *m; + struct list_head *entry; + + list_for_each(entry, &mmc_devices) { + m = list_entry(entry, struct mmc, link); + + if (m->block_dev.devnum == dev_num) + return m; + } + +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) + printf("MMC Device %d not found\n", dev_num); +#endif + + return NULL; +} + +int mmc_get_next_devnum(void) +{ + return cur_dev_num++; +} + +struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) +{ + return &mmc->block_dev; +} + +int get_mmc_num(void) +{ + return cur_dev_num; +} + +void mmc_do_preinit(void) +{ + struct mmc *m; + struct list_head *entry; + + list_for_each(entry, &mmc_devices) { + m = list_entry(entry, struct mmc, link); + +#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT + mmc_set_preinit(m, 1); +#endif + if (m->preinit) + mmc_start_init(m); + } +} + +void mmc_list_init(void) +{ + INIT_LIST_HEAD(&mmc_devices); + cur_dev_num = 0; +} + +void mmc_list_add(struct mmc *mmc) +{ + INIT_LIST_HEAD(&mmc->link); + + list_add_tail(&mmc->link, &mmc_devices); +} + +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) +void print_mmc_devices(char separator) +{ + struct mmc *m; + struct list_head *entry; + char *mmc_type; + + list_for_each(entry, &mmc_devices) { + m = list_entry(entry, struct mmc, link); + + if (m->has_init) + mmc_type = IS_SD(m) ? "SD" : "eMMC"; + else + mmc_type = NULL; + + printf("%s: %d", m->cfg->name, m->block_dev.devnum); + if (mmc_type) + printf(" (%s)", mmc_type); + + if (entry->next != &mmc_devices) { + printf("%c", separator); + if (separator != '\n') + puts(" "); + } + } + + printf("\n"); +} + +#else +void print_mmc_devices(char separator) { } +#endif diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h index d3f6bfe123..6ec52fda05 100644 --- a/drivers/mmc/mmc_private.h +++ b/drivers/mmc/mmc_private.h @@ -46,4 +46,28 @@ static inline ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, #endif /* CONFIG_SPL_BUILD */ +/** + * mmc_get_next_devnum() - Get the next available MMC device number + * + * @return next available device number (0 = first), or -ve on error + */ +int mmc_get_next_devnum(void); + +/** + * mmc_do_preinit() - Get an MMC device ready for use + */ +void mmc_do_preinit(void); + +/** + * mmc_list_init() - Set up the list of MMC devices + */ +void mmc_list_init(void); + +/** + * mmc_list_add() - Add a new MMC device to the list of devices + * + * @mmc: Device to add + */ +void mmc_list_add(struct mmc *mmc); + #endif /* _MMC_PRIVATE_H_ */ diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index f4d42aaa76..bd07b20f5f 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -122,9 +122,9 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start, struct mmc_data data; int timeout = 1000; - if ((start + blkcnt) > mmc->block_dev.lba) { + if ((start + blkcnt) > mmc_get_blk_desc(mmc)->lba) { printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n", - start + blkcnt, mmc->block_dev.lba); + start + blkcnt, mmc_get_blk_desc(mmc)->lba); return 0; }