mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 19:40:56 +07:00
mmc: core: general purpose MMC partition support.
It allows gerneral purpose partitions in MMC Device. And I try to simply make mmc_blk_alloc_parts using mmc_part structure suggested by Andrei Warkentin. After patching, we see general purpose partitions like this: > cat /proc/partitions 179 0 847872 mmcblk0 179 192 4096 mmcblk0gp3 179 160 4096 mmcblk0gp2 179 128 4096 mmcblk0gp1 179 96 1052672 mmcblk0gp0 179 64 1024 mmcblk0boot1 179 32 1024 mmcblk0boot0 Signed-off-by: Namjae Jeon <linkinjeon@gmail.com> Acked-by: Andrei Warkentin <awarkentin@vmware.com> Signed-off-by: Chris Ball <cjb@laptop.org>
This commit is contained in:
parent
5238acbe36
commit
e0c368d571
@ -1473,27 +1473,30 @@ static int mmc_blk_alloc_part(struct mmc_card *card,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* MMC Physical partitions consist of two boot partitions and
|
||||||
|
* up to four general purpose partitions.
|
||||||
|
* For each partition enabled in EXT_CSD a block device will be allocatedi
|
||||||
|
* to provide access to the partition.
|
||||||
|
*/
|
||||||
|
|
||||||
static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md)
|
static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int idx, ret = 0;
|
||||||
|
|
||||||
if (!mmc_card_mmc(card))
|
if (!mmc_card_mmc(card))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (card->ext_csd.boot_size && mmc_boot_partition_access(card->host)) {
|
for (idx = 0; idx < card->nr_parts; idx++) {
|
||||||
ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_BOOT0,
|
if (card->part[idx].size) {
|
||||||
card->ext_csd.boot_size >> 9,
|
ret = mmc_blk_alloc_part(card, md,
|
||||||
true,
|
card->part[idx].part_cfg,
|
||||||
"boot0");
|
card->part[idx].size >> 9,
|
||||||
if (ret)
|
card->part[idx].force_ro,
|
||||||
return ret;
|
card->part[idx].name);
|
||||||
ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_BOOT1,
|
|
||||||
card->ext_csd.boot_size >> 9,
|
|
||||||
true,
|
|
||||||
"boot1");
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,9 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd)
|
|||||||
*/
|
*/
|
||||||
static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0, idx;
|
||||||
|
unsigned int part_size;
|
||||||
|
u8 hc_erase_grp_sz = 0, hc_wp_grp_sz = 0;
|
||||||
|
|
||||||
BUG_ON(!card);
|
BUG_ON(!card);
|
||||||
|
|
||||||
@ -340,7 +342,14 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
|||||||
* There are two boot regions of equal size, defined in
|
* There are two boot regions of equal size, defined in
|
||||||
* multiples of 128K.
|
* multiples of 128K.
|
||||||
*/
|
*/
|
||||||
card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
|
if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_boot_partition_access(card->host)) {
|
||||||
|
for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) {
|
||||||
|
part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
|
||||||
|
mmc_part_add(card, part_size,
|
||||||
|
EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx,
|
||||||
|
"boot%d", idx, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
card->ext_csd.raw_hc_erase_gap_size =
|
card->ext_csd.raw_hc_erase_gap_size =
|
||||||
@ -362,9 +371,9 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
|||||||
card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
|
card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
|
||||||
if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
|
if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
|
||||||
(ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
|
(ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
|
||||||
u8 hc_erase_grp_sz =
|
hc_erase_grp_sz =
|
||||||
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
||||||
u8 hc_wp_grp_sz =
|
hc_wp_grp_sz =
|
||||||
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
||||||
|
|
||||||
card->ext_csd.enhanced_area_en = 1;
|
card->ext_csd.enhanced_area_en = 1;
|
||||||
@ -393,6 +402,41 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
|||||||
card->ext_csd.enhanced_area_offset = -EINVAL;
|
card->ext_csd.enhanced_area_offset = -EINVAL;
|
||||||
card->ext_csd.enhanced_area_size = -EINVAL;
|
card->ext_csd.enhanced_area_size = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General purpose partition feature support --
|
||||||
|
* If ext_csd has the size of general purpose partitions,
|
||||||
|
* set size, part_cfg, partition name in mmc_part.
|
||||||
|
*/
|
||||||
|
if (ext_csd[EXT_CSD_PARTITION_SUPPORT] &
|
||||||
|
EXT_CSD_PART_SUPPORT_PART_EN) {
|
||||||
|
if (card->ext_csd.enhanced_area_en != 1) {
|
||||||
|
hc_erase_grp_sz =
|
||||||
|
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
||||||
|
hc_wp_grp_sz =
|
||||||
|
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
||||||
|
|
||||||
|
card->ext_csd.enhanced_area_en = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) {
|
||||||
|
if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] &&
|
||||||
|
!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] &&
|
||||||
|
!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2])
|
||||||
|
continue;
|
||||||
|
part_size =
|
||||||
|
(ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]
|
||||||
|
<< 16) +
|
||||||
|
(ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1]
|
||||||
|
<< 8) +
|
||||||
|
ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3];
|
||||||
|
part_size *= (size_t)(hc_erase_grp_sz *
|
||||||
|
hc_wp_grp_sz);
|
||||||
|
mmc_part_add(card, part_size << 19,
|
||||||
|
EXT_CSD_PART_CONFIG_ACC_GP0 + idx,
|
||||||
|
"gp%d", idx, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
card->ext_csd.sec_trim_mult =
|
card->ext_csd.sec_trim_mult =
|
||||||
ext_csd[EXT_CSD_SEC_TRIM_MULT];
|
ext_csd[EXT_CSD_SEC_TRIM_MULT];
|
||||||
card->ext_csd.sec_erase_mult =
|
card->ext_csd.sec_erase_mult =
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <linux/mmc/core.h>
|
#include <linux/mmc/core.h>
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/mod_devicetable.h>
|
||||||
|
#include <linux/genhd.h>
|
||||||
|
|
||||||
struct mmc_cid {
|
struct mmc_cid {
|
||||||
unsigned int manfid;
|
unsigned int manfid;
|
||||||
@ -64,7 +65,6 @@ struct mmc_ext_csd {
|
|||||||
bool enhanced_area_en; /* enable bit */
|
bool enhanced_area_en; /* enable bit */
|
||||||
unsigned long long enhanced_area_offset; /* Units: Byte */
|
unsigned long long enhanced_area_offset; /* Units: Byte */
|
||||||
unsigned int enhanced_area_size; /* Units: KB */
|
unsigned int enhanced_area_size; /* Units: KB */
|
||||||
unsigned int boot_size; /* in bytes */
|
|
||||||
u8 raw_partition_support; /* 160 */
|
u8 raw_partition_support; /* 160 */
|
||||||
u8 raw_erased_mem_count; /* 181 */
|
u8 raw_erased_mem_count; /* 181 */
|
||||||
u8 raw_ext_csd_structure; /* 194 */
|
u8 raw_ext_csd_structure; /* 194 */
|
||||||
@ -158,6 +158,23 @@ struct sdio_func_tuple;
|
|||||||
|
|
||||||
#define SDIO_MAX_FUNCS 7
|
#define SDIO_MAX_FUNCS 7
|
||||||
|
|
||||||
|
/* The number of MMC physical partitions. These consist of:
|
||||||
|
* boot partitions (2), general purpose partitions (4) in MMC v4.4.
|
||||||
|
*/
|
||||||
|
#define MMC_NUM_BOOT_PARTITION 2
|
||||||
|
#define MMC_NUM_GP_PARTITION 4
|
||||||
|
#define MMC_NUM_PHY_PARTITION 6
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MMC Physical partitions
|
||||||
|
*/
|
||||||
|
struct mmc_part {
|
||||||
|
unsigned int size; /* partition size (in bytes) */
|
||||||
|
unsigned int part_cfg; /* partition type */
|
||||||
|
char name[DISK_NAME_LEN];
|
||||||
|
bool force_ro; /* to make boot parts RO by default */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMC device
|
* MMC device
|
||||||
*/
|
*/
|
||||||
@ -219,8 +236,23 @@ struct mmc_card {
|
|||||||
unsigned int sd_bus_speed; /* Bus Speed Mode set for the card */
|
unsigned int sd_bus_speed; /* Bus Speed Mode set for the card */
|
||||||
|
|
||||||
struct dentry *debugfs_root;
|
struct dentry *debugfs_root;
|
||||||
|
struct mmc_part part[MMC_NUM_PHY_PARTITION]; /* physical partitions */
|
||||||
|
unsigned int nr_parts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function fill contents in mmc_part.
|
||||||
|
*/
|
||||||
|
static inline void mmc_part_add(struct mmc_card *card, unsigned int size,
|
||||||
|
unsigned int part_cfg, char *name, int idx, bool ro)
|
||||||
|
{
|
||||||
|
card->part[card->nr_parts].size = size;
|
||||||
|
card->part[card->nr_parts].part_cfg = part_cfg;
|
||||||
|
sprintf(card->part[card->nr_parts].name, name, idx);
|
||||||
|
card->part[card->nr_parts].force_ro = ro;
|
||||||
|
card->nr_parts++;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The world is not perfect and supplies us with broken mmc/sdio devices.
|
* The world is not perfect and supplies us with broken mmc/sdio devices.
|
||||||
* For at least some of these bugs we need a work-around.
|
* For at least some of these bugs we need a work-around.
|
||||||
|
@ -270,6 +270,7 @@ struct _mmc_csd {
|
|||||||
* EXT_CSD fields
|
* EXT_CSD fields
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
|
||||||
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
|
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
|
||||||
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
|
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
|
||||||
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
|
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
|
||||||
@ -313,7 +314,9 @@ struct _mmc_csd {
|
|||||||
|
|
||||||
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
|
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
|
||||||
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
|
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
|
||||||
#define EXT_CSD_PART_CONFIG_ACC_BOOT1 (0x2)
|
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
|
||||||
|
|
||||||
|
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
|
||||||
|
|
||||||
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
|
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
|
||||||
#define EXT_CSD_CMD_SET_SECURE (1<<1)
|
#define EXT_CSD_CMD_SET_SECURE (1<<1)
|
||||||
|
Loading…
Reference in New Issue
Block a user