Skip to content

Commit

Permalink
[MTD] update internal API to support 64-bit device size
Browse files Browse the repository at this point in the history
MTD internal API presently uses 32-bit values to represent
device size.  This patch updates them to 64-bits but leaves
the external API unchanged.  Extending the external API
is a separate issue for several reasons.  First, no one
needs it at the moment.  Secondly, whether the implementation
is done with IOCTLs, sysfs or both is still debated.  Thirdly
external API changes require the internal API to be accepted
first.

Note that although the MTD API will be able to support 64-bit
device sizes, existing drivers do not and are not required
to do so, although NAND base has been updated.

In general, changing from 32-bit to 64-bit values cause little
or no changes to the majority of the code with the following
exceptions:
    	- printk message formats
    	- division and modulus of 64-bit values
    	- NAND base support
	- 32-bit local variables used by mtdpart and mtdconcat
	- naughtily assuming one structure maps to another
	in MEMERASE ioctl

Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
Adrian Hunter authored and David Woodhouse committed Dec 10, 2008
1 parent 8a4c249 commit 69423d9
Show file tree
Hide file tree
Showing 30 changed files with 216 additions and 138 deletions.
12 changes: 6 additions & 6 deletions drivers/mtd/chips/cfi_cmdset_0001.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t
static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *);
static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_intelext_sync (struct mtd_info *);
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
#ifdef CONFIG_MTD_OTP
static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
Expand Down Expand Up @@ -558,8 +558,8 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
}

for (i=0; i<mtd->numeraseregions;i++){
printk(KERN_DEBUG "erase region %d: offset=0x%x,size=0x%x,blocks=%d\n",
i,mtd->eraseregions[i].offset,
printk(KERN_DEBUG "erase region %d: offset=0x%llx,size=0x%x,blocks=%d\n",
i,(unsigned long long)mtd->eraseregions[i].offset,
mtd->eraseregions[i].erasesize,
mtd->eraseregions[i].numblocks);
}
Expand Down Expand Up @@ -2058,7 +2058,7 @@ out: put_chip(map, chip, adr);
return ret;
}

static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
int ret;

Expand All @@ -2082,7 +2082,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
return ret;
}

static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
int ret;

Expand Down
8 changes: 4 additions & 4 deletions drivers/mtd/chips/cfi_cmdset_0002.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr);
#include "fwh_lock.h"

static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);

static struct mtd_chip_driver cfi_amdstd_chipdrv = {
.probe = NULL, /* Not usable directly */
Expand Down Expand Up @@ -1774,12 +1774,12 @@ static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
return ret;
}

static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
return cfi_varsize_frob(mtd, do_atmel_lock, ofs, len, NULL);
}

static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
return cfi_varsize_frob(mtd, do_atmel_unlock, ofs, len, NULL);
}
Expand Down
14 changes: 7 additions & 7 deletions drivers/mtd/chips/cfi_cmdset_0020.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ static int cfi_staa_writev(struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen);
static int cfi_staa_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_staa_sync (struct mtd_info *);
static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_staa_suspend (struct mtd_info *);
static void cfi_staa_resume (struct mtd_info *);

Expand Down Expand Up @@ -221,8 +221,8 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
}

for (i=0; i<mtd->numeraseregions;i++){
printk(KERN_DEBUG "%d: offset=0x%x,size=0x%x,blocks=%d\n",
i,mtd->eraseregions[i].offset,
printk(KERN_DEBUG "%d: offset=0x%llx,size=0x%x,blocks=%d\n",
i, (unsigned long long)mtd->eraseregions[i].offset,
mtd->eraseregions[i].erasesize,
mtd->eraseregions[i].numblocks);
}
Expand Down Expand Up @@ -964,7 +964,7 @@ static int cfi_staa_erase_varsize(struct mtd_info *mtd,
adr += regions[i].erasesize;
len -= regions[i].erasesize;

if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
if (adr % (1<< cfi->chipshift) == (((unsigned long)regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
i++;

if (adr >> cfi->chipshift) {
Expand Down Expand Up @@ -1135,7 +1135,7 @@ static inline int do_lock_oneblock(struct map_info *map, struct flchip *chip, un
spin_unlock_bh(chip->mutex);
return 0;
}
static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
Expand Down Expand Up @@ -1284,7 +1284,7 @@ static inline int do_unlock_oneblock(struct map_info *map, struct flchip *chip,
spin_unlock_bh(chip->mutex);
return 0;
}
static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/chips/fwh_lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
}


static int fwh_lock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
static int fwh_lock_varsize(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
int ret;

Expand All @@ -88,7 +88,7 @@ static int fwh_lock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
}


static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
int ret;

Expand Down
2 changes: 1 addition & 1 deletion drivers/mtd/inftlcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
struct INFTLrecord *inftl;
unsigned long temp;

if (mtd->type != MTD_NANDFLASH)
if (mtd->type != MTD_NANDFLASH || mtd->size > UINT_MAX)
return;
/* OK, this is moderately ugly. But probably safe. Alternatives? */
if (memcmp(mtd->name, "DiskOnChip", 10))
Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/inftlmount.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
* otherwise.
*/
inftl->EraseSize = inftl->mbd.mtd->erasesize;
inftl->nb_blocks = inftl->mbd.mtd->size / inftl->EraseSize;
inftl->nb_blocks = (u32)inftl->mbd.mtd->size / inftl->EraseSize;

inftl->MediaUnit = BLOCK_NIL;

Expand Down Expand Up @@ -187,7 +187,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
mh->BlockMultiplierBits);
inftl->EraseSize = inftl->mbd.mtd->erasesize <<
mh->BlockMultiplierBits;
inftl->nb_blocks = inftl->mbd.mtd->size / inftl->EraseSize;
inftl->nb_blocks = (u32)inftl->mbd.mtd->size / inftl->EraseSize;
block >>= mh->BlockMultiplierBits;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/maps/amd76xrom.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
/* Trim the size if we are larger than the map */
if (map->mtd->size > map->map.size) {
printk(KERN_WARNING MOD_NAME
" rom(%u) larger than window(%lu). fixing...\n",
map->mtd->size, map->map.size);
" rom(%llu) larger than window(%lu). fixing...\n",
(unsigned long long)map->mtd->size, map->map.size);
map->mtd->size = map->map.size;
}
if (window->rsrc.parent) {
Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/maps/ck804xrom.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev,
/* Trim the size if we are larger than the map */
if (map->mtd->size > map->map.size) {
printk(KERN_WARNING MOD_NAME
" rom(%u) larger than window(%lu). fixing...\n",
map->mtd->size, map->map.size);
" rom(%llu) larger than window(%lu). fixing...\n",
(unsigned long long)map->mtd->size, map->map.size);
map->mtd->size = map->map.size;
}
if (window->rsrc.parent) {
Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/maps/esb2rom.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,8 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev,
/* Trim the size if we are larger than the map */
if (map->mtd->size > map->map.size) {
printk(KERN_WARNING MOD_NAME
" rom(%u) larger than window(%lu). fixing...\n",
map->mtd->size, map->map.size);
" rom(%llu) larger than window(%lu). fixing...\n",
(unsigned long long)map->mtd->size, map->map.size);
map->mtd->size = map->map.size;
}
if (window->rsrc.parent) {
Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/maps/ichxrom.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
/* Trim the size if we are larger than the map */
if (map->mtd->size > map->map.size) {
printk(KERN_WARNING MOD_NAME
" rom(%u) larger than window(%lu). fixing...\n",
map->mtd->size, map->map.size);
" rom(%llu) larger than window(%lu). fixing...\n",
(unsigned long long)map->mtd->size, map->map.size);
map->mtd->size = map->map.size;
}
if (window->rsrc.parent) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/mtd/maps/nettel.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ static int __init nettel_init(void)

if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) {
printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n",
amd_mtd->size>>10);
(int)(amd_mtd->size>>10));

amd_mtd->owner = THIS_MODULE;

Expand Down
8 changes: 5 additions & 3 deletions drivers/mtd/maps/scb2_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ scb2_fixup_mtd(struct mtd_info *mtd)
struct mtd_erase_region_info *region = &mtd->eraseregions[i];

if (region->numblocks * region->erasesize > mtd->size) {
region->numblocks = (mtd->size / region->erasesize);
region->numblocks = ((unsigned long)mtd->size /
region->erasesize);
done = 1;
} else {
region->numblocks = 0;
Expand Down Expand Up @@ -187,8 +188,9 @@ scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent)
return -ENODEV;
}

printk(KERN_NOTICE MODNAME ": chip size 0x%x at offset 0x%x\n",
scb2_mtd->size, SCB2_WINDOW - scb2_mtd->size);
printk(KERN_NOTICE MODNAME ": chip size 0x%llx at offset 0x%llx\n",
(unsigned long long)scb2_mtd->size,
(unsigned long long)(SCB2_WINDOW - scb2_mtd->size));

add_mtd_device(scb2_mtd);

Expand Down
6 changes: 5 additions & 1 deletion drivers/mtd/mtdchar.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,16 +450,20 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
if (!erase)
ret = -ENOMEM;
else {
struct erase_info_user einfo;

wait_queue_head_t waitq;
DECLARE_WAITQUEUE(wait, current);

init_waitqueue_head(&waitq);

if (copy_from_user(&erase->addr, argp,
if (copy_from_user(&einfo, argp,
sizeof(struct erase_info_user))) {
kfree(erase);
return -EFAULT;
}
erase->addr = einfo.start;
erase->len = einfo.length;
erase->mtd = mtd;
erase->callback = mtdchar_erase_callback;
erase->priv = (unsigned long)&waitq;
Expand Down
33 changes: 19 additions & 14 deletions drivers/mtd/mtdconcat.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
continue;
}

size = min(total_len, (size_t)(subdev->size - to));
size = min_t(uint64_t, total_len, subdev->size - to);
wsize = size; /* store for future use */

entry_high = entry_low;
Expand Down Expand Up @@ -385,7 +385,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
struct mtd_concat *concat = CONCAT(mtd);
struct mtd_info *subdev;
int i, err;
u_int32_t length, offset = 0;
uint64_t length, offset = 0;
struct erase_info *erase;

if (!(mtd->flags & MTD_WRITEABLE))
Expand Down Expand Up @@ -518,7 +518,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
return 0;
}

static int concat_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
struct mtd_concat *concat = CONCAT(mtd);
int i, err = -EINVAL;
Expand All @@ -528,7 +528,7 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, size_t len)

for (i = 0; i < concat->num_subdev; i++) {
struct mtd_info *subdev = concat->subdev[i];
size_t size;
uint64_t size;

if (ofs >= subdev->size) {
size = 0;
Expand Down Expand Up @@ -556,7 +556,7 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
return err;
}

static int concat_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
struct mtd_concat *concat = CONCAT(mtd);
int i, err = 0;
Expand All @@ -566,7 +566,7 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)

for (i = 0; i < concat->num_subdev; i++) {
struct mtd_info *subdev = concat->subdev[i];
size_t size;
uint64_t size;

if (ofs >= subdev->size) {
size = 0;
Expand Down Expand Up @@ -842,12 +842,14 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.erasesize = curr_erasesize;
concat->mtd.numeraseregions = 0;
} else {
uint64_t tmp64;

/*
* erase block size varies across the subdevices: allocate
* space to store the data describing the variable erase regions
*/
struct mtd_erase_region_info *erase_region_p;
u_int32_t begin, position;
uint64_t begin, position;

concat->mtd.erasesize = max_erasesize;
concat->mtd.numeraseregions = num_erase_region;
Expand Down Expand Up @@ -879,8 +881,9 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
erase_region_p->offset = begin;
erase_region_p->erasesize =
curr_erasesize;
erase_region_p->numblocks =
(position - begin) / curr_erasesize;
tmp64 = position - begin;
do_div(tmp64, curr_erasesize);
erase_region_p->numblocks = tmp64;
begin = position;

curr_erasesize = subdev[i]->erasesize;
Expand All @@ -897,9 +900,9 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
erase_region_p->offset = begin;
erase_region_p->erasesize =
curr_erasesize;
erase_region_p->numblocks =
(position -
begin) / curr_erasesize;
tmp64 = position - begin;
do_div(tmp64, curr_erasesize);
erase_region_p->numblocks = tmp64;
begin = position;

curr_erasesize =
Expand All @@ -909,14 +912,16 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
}
position +=
subdev[i]->eraseregions[j].
numblocks * curr_erasesize;
numblocks * (uint64_t)curr_erasesize;
}
}
}
/* Now write the final entry */
erase_region_p->offset = begin;
erase_region_p->erasesize = curr_erasesize;
erase_region_p->numblocks = (position - begin) / curr_erasesize;
tmp64 = position - begin;
do_div(tmp64, curr_erasesize);
erase_region_p->numblocks = tmp64;
}

return &concat->mtd;
Expand Down
Loading

0 comments on commit 69423d9

Please sign in to comment.