Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 270286
b: refs/heads/master
c: e0c368d
h: refs/heads/master
v: v3
  • Loading branch information
Namjae Jeon authored and Chris Ball committed Oct 26, 2011
1 parent 4262c59 commit a6a5f31
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5238acbe36dd5100fb6b035a995ae5fc89dd0708
refs/heads/master: e0c368d571d946ff40f068344b5c2df90c93dd2e
31 changes: 17 additions & 14 deletions trunk/drivers/mmc/card/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -1473,26 +1473,29 @@ static int mmc_blk_alloc_part(struct mmc_card *card,
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)
{
int ret = 0;
int idx, ret = 0;

if (!mmc_card_mmc(card))
return 0;

if (card->ext_csd.boot_size && mmc_boot_partition_access(card->host)) {
ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_BOOT0,
card->ext_csd.boot_size >> 9,
true,
"boot0");
if (ret)
return ret;
ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_BOOT1,
card->ext_csd.boot_size >> 9,
true,
"boot1");
if (ret)
return ret;
for (idx = 0; idx < card->nr_parts; idx++) {
if (card->part[idx].size) {
ret = mmc_blk_alloc_part(card, md,
card->part[idx].part_cfg,
card->part[idx].size >> 9,
card->part[idx].force_ro,
card->part[idx].name);
if (ret)
return ret;
}
}

return ret;
Expand Down
52 changes: 48 additions & 4 deletions trunk/drivers/mmc/core/mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
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);

Expand Down Expand Up @@ -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
* 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 =
Expand All @@ -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];
if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
(ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
u8 hc_erase_grp_sz =
hc_erase_grp_sz =
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];

card->ext_csd.enhanced_area_en = 1;
Expand Down Expand Up @@ -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_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 =
ext_csd[EXT_CSD_SEC_TRIM_MULT];
card->ext_csd.sec_erase_mult =
Expand Down
34 changes: 33 additions & 1 deletion trunk/include/linux/mmc/card.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <linux/mmc/core.h>
#include <linux/mod_devicetable.h>
#include <linux/genhd.h>

struct mmc_cid {
unsigned int manfid;
Expand Down Expand Up @@ -64,7 +65,6 @@ struct mmc_ext_csd {
bool enhanced_area_en; /* enable bit */
unsigned long long enhanced_area_offset; /* Units: Byte */
unsigned int enhanced_area_size; /* Units: KB */
unsigned int boot_size; /* in bytes */
u8 raw_partition_support; /* 160 */
u8 raw_erased_mem_count; /* 181 */
u8 raw_ext_csd_structure; /* 194 */
Expand Down Expand Up @@ -158,6 +158,23 @@ struct sdio_func_tuple;

#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
*/
Expand Down Expand Up @@ -219,8 +236,23 @@ struct mmc_card {
unsigned int sd_bus_speed; /* Bus Speed Mode set for the card */

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.
* For at least some of these bugs we need a work-around.
Expand Down
5 changes: 4 additions & 1 deletion trunk/include/linux/mmc/mmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ struct _mmc_csd {
* EXT_CSD fields
*/

#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
Expand Down Expand Up @@ -313,7 +314,9 @@ struct _mmc_csd {

#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
#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_SECURE (1<<1)
Expand Down

0 comments on commit a6a5f31

Please sign in to comment.