Merge branch 'for-next/mtd'
This commit is contained in:
commit
149e9d8121
|
@ -277,7 +277,7 @@ static int do_nandtest(int argc, char *argv[])
|
|||
}
|
||||
if (length + flash_offset > meminfo.size) {
|
||||
printf("Length 0x%08llx + offset 0x%08llx exceeds "
|
||||
"device size 0x%08x\n", length,
|
||||
"device size 0x%08llx\n", length,
|
||||
flash_offset, meminfo.size);
|
||||
goto err;
|
||||
}
|
||||
|
|
|
@ -42,10 +42,11 @@
|
|||
#define PART_ADD_DEVNAME (1 << 0)
|
||||
|
||||
static int mtd_part_do_parse_one(char *devname, const char *partstr,
|
||||
char **endp, unsigned long *offset,
|
||||
off_t devsize, size_t *retsize, unsigned int pflags)
|
||||
char **endp, loff_t *offset,
|
||||
loff_t devsize, size_t *retsize,
|
||||
unsigned int pflags)
|
||||
{
|
||||
ulong size;
|
||||
loff_t size;
|
||||
char *end;
|
||||
char buf[PATH_MAX] = {};
|
||||
unsigned long flags = 0;
|
||||
|
@ -58,11 +59,11 @@ static int mtd_part_do_parse_one(char *devname, const char *partstr,
|
|||
size = SIZE_REMAINING;
|
||||
end = (char *)partstr + 1;
|
||||
} else {
|
||||
size = strtoul_suffix(partstr, &end, 0);
|
||||
size = strtoull_suffix(partstr, &end, 0);
|
||||
}
|
||||
|
||||
if (*end == '@')
|
||||
*offset = strtoul_suffix(end+1, &end, 0);
|
||||
*offset = strtoull_suffix(end+1, &end, 0);
|
||||
|
||||
if (size == SIZE_REMAINING)
|
||||
size = devsize - *offset;
|
||||
|
@ -114,8 +115,8 @@ static int do_addpart(int argc, char *argv[])
|
|||
{
|
||||
char *devname;
|
||||
char *endp;
|
||||
unsigned long offset = 0;
|
||||
off_t devsize;
|
||||
loff_t offset = 0;
|
||||
loff_t devsize;
|
||||
struct stat s;
|
||||
int opt;
|
||||
unsigned int flags = PART_ADD_DEVNAME;
|
||||
|
|
|
@ -15,12 +15,12 @@ static int do_ubimkvol(int argc, char *argv[])
|
|||
{
|
||||
struct ubi_mkvol_req req;
|
||||
int fd, ret;
|
||||
size_t size;
|
||||
uint64_t size;
|
||||
|
||||
if (argc != 4)
|
||||
return COMMAND_ERROR_USAGE;
|
||||
|
||||
size = strtoul_suffix(argv[3], NULL, 0);
|
||||
size = strtoull_suffix(argv[3], NULL, 0);
|
||||
req.name_len = min_t(int, strlen(argv[2]), UBI_VOL_NAME_MAX);
|
||||
strncpy(req.name, argv[2], req.name_len);
|
||||
req.name[req.name_len] = 0;
|
||||
|
|
|
@ -401,7 +401,7 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
|
|||
mtd->cdev.mtd = mtd;
|
||||
|
||||
if (IS_ENABLED(CONFIG_PARAMETER)) {
|
||||
dev_add_param_int_ro(&mtd->class_dev, "size", mtd->size, "%u");
|
||||
dev_add_param_int_ro(&mtd->class_dev, "size", mtd->size, "%llu");
|
||||
dev_add_param_int_ro(&mtd->class_dev, "erasesize", mtd->erasesize, "%u");
|
||||
dev_add_param_int_ro(&mtd->class_dev, "writesize", mtd->oobsize, "%u");
|
||||
dev_add_param_int_ro(&mtd->class_dev, "oobsize", mtd->oobsize, "%u");
|
||||
|
|
|
@ -268,8 +268,9 @@ static int erase_sector(struct m25p *flash, u32 offset, u32 command)
|
|||
static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||
{
|
||||
struct m25p *flash = mtd_to_m25p(mtd);
|
||||
u32 addr, len;
|
||||
u32 addr;
|
||||
uint32_t rem;
|
||||
uint64_t len;
|
||||
|
||||
dev_dbg(&flash->spi->dev, "%s at 0x%llx, len %lld\n",
|
||||
__func__, (long long)instr->addr,
|
||||
|
@ -897,7 +898,7 @@ static int m25p_probe(struct device_d *dev)
|
|||
flash->mtd.type = MTD_NORFLASH;
|
||||
flash->mtd.writesize = 1;
|
||||
flash->mtd.flags = MTD_CAP_NORFLASH;
|
||||
flash->mtd.size = info->sector_size * info->n_sectors;
|
||||
flash->mtd.size = (uint64_t)info->sector_size * info->n_sectors;
|
||||
flash->mtd.erase = m25p80_erase;
|
||||
flash->mtd.read = m25p80_read;
|
||||
|
||||
|
|
|
@ -625,7 +625,7 @@ add_dataflash_otp(struct spi_device *spi, char *name,
|
|||
|
||||
device = &priv->mtd;
|
||||
device->name = (pdata && pdata->name) ? pdata->name : "dataflash";
|
||||
device->size = nr_pages * pagesize;
|
||||
device->size = nr_pages * (uint64_t)pagesize;
|
||||
device->erasesize = pagesize;
|
||||
device->writesize = pagesize;
|
||||
device->type = MTD_DATAFLASH;
|
||||
|
|
|
@ -78,7 +78,7 @@ static int add_mtdoob_device(struct mtd_info *mtd, char *devname, void **priv)
|
|||
|
||||
mtdoob = xzalloc(sizeof(*mtdoob));
|
||||
mtdoob->cdev.ops = &mtd_ops_oob;
|
||||
mtdoob->cdev.size = (mtd->size / mtd->writesize) * mtd->oobsize;
|
||||
mtdoob->cdev.size = mtd_div_by_wb(mtd->size, mtd) * mtd->oobsize;
|
||||
mtdoob->cdev.name = asprintf("%s_oob%d", devname, mtd->class_dev.id);
|
||||
mtdoob->cdev.priv = mtdoob;
|
||||
mtdoob->cdev.dev = &mtd->class_dev;
|
||||
|
|
|
@ -293,7 +293,7 @@ static int add_mtdraw_device(struct mtd_info *mtd, char *devname, void **priv)
|
|||
mtdraw->mtd = mtd;
|
||||
|
||||
mtdraw->cdev.ops = (struct file_operations *)&mtd_raw_fops;
|
||||
mtdraw->cdev.size = mtd->size / mtd->writesize *
|
||||
mtdraw->cdev.size = mtd_div_by_wb(mtd->size, mtd) *
|
||||
(mtd->writesize + mtd->oobsize);
|
||||
mtdraw->cdev.name = asprintf("%s.raw", mtd->cdev.name);
|
||||
mtdraw->cdev.priv = mtdraw;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <dma/apbh-dma.h>
|
||||
#include <stmp-device.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <mach/generic.h>
|
||||
|
||||
#define MX28_BLOCK_SFTRST (1 << 31)
|
||||
#define MX28_BLOCK_CLKGATE (1 << 30)
|
||||
|
@ -233,18 +234,31 @@ static uint32_t mxs_nand_aux_status_offset(void)
|
|||
static inline uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size,
|
||||
uint32_t page_oob_size)
|
||||
{
|
||||
int ecc_chunk_count = mxs_nand_ecc_chunk_cnt(page_data_size);
|
||||
int ecc_strength = 0;
|
||||
int gf_len = 13; /* length of Galois Field for non-DDR nand */
|
||||
|
||||
/*
|
||||
* Possibly this if-else calculation may be removed since
|
||||
* ecc_strength calculated after it is taken from kernel driver
|
||||
* and therefore should work for all cases. But it was tested only
|
||||
* on devices with {data_size = 2046, oob_size = 64} and
|
||||
* {data_size = 4096, oob_size = 224} configuration.
|
||||
*/
|
||||
if (page_data_size == 2048)
|
||||
return 8;
|
||||
|
||||
if (page_data_size == 4096) {
|
||||
else if (page_data_size == 4096) {
|
||||
if (page_oob_size == 128)
|
||||
return 8;
|
||||
|
||||
if (page_oob_size == 218)
|
||||
return 16;
|
||||
}
|
||||
|
||||
return 0;
|
||||
ecc_strength = ((page_oob_size - MXS_NAND_METADATA_SIZE) * 8)
|
||||
/ (gf_len * ecc_chunk_count);
|
||||
|
||||
/* We need the minor even number. */
|
||||
return rounddown(ecc_strength, 2);
|
||||
}
|
||||
|
||||
static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
|
||||
|
@ -427,7 +441,13 @@ static int mxs_nand_device_ready(struct mtd_info *mtd)
|
|||
|
||||
if (nand_info->version > GPMI_VERSION_TYPE_MX23) {
|
||||
tmp = readl(gpmi_regs + GPMI_STAT);
|
||||
tmp >>= (GPMI_STAT_READY_BUSY_OFFSET + nand_info->cur_chip);
|
||||
/* i.MX6 has only one R/B actual pin, so if there are several
|
||||
R/B signals they must be all connected to this pin */
|
||||
if (cpu_is_mx6())
|
||||
tmp >>= GPMI_STAT_READY_BUSY_OFFSET;
|
||||
else
|
||||
tmp >>= (GPMI_STAT_READY_BUSY_OFFSET +
|
||||
nand_info->cur_chip);
|
||||
} else {
|
||||
tmp = readl(gpmi_regs + GPMI_DEBUG);
|
||||
tmp >>= (GPMI_DEBUG_READY0_OFFSET + nand_info->cur_chip);
|
||||
|
@ -1304,7 +1324,7 @@ static int mxs_nand_probe(struct device_d *dev)
|
|||
nand->ecc.strength = 8;
|
||||
|
||||
/* first scan to find the device and get the page size */
|
||||
err = nand_scan_ident(mtd, 1, NULL);
|
||||
err = nand_scan_ident(mtd, 4, NULL);
|
||||
if (err)
|
||||
goto err2;
|
||||
|
||||
|
|
|
@ -75,8 +75,8 @@ static int mtd_part_block_markbad(struct mtd_info *mtd, loff_t ofs)
|
|||
return res;
|
||||
}
|
||||
|
||||
struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset, size_t size,
|
||||
unsigned long flags, const char *name)
|
||||
struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
|
||||
uint64_t size, unsigned long flags, const char *name)
|
||||
{
|
||||
struct mtd_info *part;
|
||||
int start = 0, end = 0, i;
|
||||
|
|
|
@ -222,7 +222,7 @@ static int ubi_cdev_ioctl(struct cdev *cdev, int cmd, void *buf)
|
|||
break;
|
||||
case UBI_IOCMKVOL:
|
||||
if (!req->bytes)
|
||||
req->bytes = ubi->avail_pebs * ubi->leb_size;
|
||||
req->bytes = (__s64)ubi->avail_pebs * ubi->leb_size;
|
||||
return ubi_create_volume(ubi, req);
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
#include <asm-generic/div64.h>
|
||||
|
||||
struct erase_info_user {
|
||||
uint32_t start;
|
||||
uint32_t length;
|
||||
|
@ -73,7 +75,7 @@ enum {
|
|||
struct mtd_info_user {
|
||||
uint8_t type;
|
||||
uint32_t flags;
|
||||
uint32_t size; // Total size of the MTD
|
||||
uint64_t size; /* Total size of the MTD */
|
||||
uint32_t erasesize;
|
||||
uint32_t writesize;
|
||||
uint32_t oobsize; // Amount of OOB data per block (e.g. 16)
|
||||
|
@ -173,6 +175,14 @@ enum mtd_file_modes {
|
|||
MTD_MODE_RAW,
|
||||
};
|
||||
|
||||
|
||||
static inline uint32_t mtd_user_div_by_eb(uint64_t sz,
|
||||
struct mtd_info_user *mtd_user)
|
||||
{
|
||||
do_div(sz, mtd_user->erasesize);
|
||||
return sz;
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
||||
|
||||
#endif /* __MTD_ABI_H__ */
|
||||
|
|
|
@ -86,7 +86,7 @@ struct mtd_oob_ops {
|
|||
struct mtd_info {
|
||||
u_char type;
|
||||
u_int32_t flags;
|
||||
u_int32_t size; // Total size of the MTD
|
||||
u_int64_t size; /* Total size of the MTD */
|
||||
|
||||
/* "Major" erase size for the device. Naïve users may take this
|
||||
* to be the only erase size available, or may use the more detailed
|
||||
|
@ -219,7 +219,7 @@ struct mtd_info {
|
|||
int p_allow_erasebad;
|
||||
|
||||
struct mtd_info *master;
|
||||
uint32_t master_offset;
|
||||
loff_t master_offset;
|
||||
};
|
||||
|
||||
int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
|
||||
|
@ -256,6 +256,13 @@ static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
|
|||
{
|
||||
return do_div(sz, mtd->erasesize);
|
||||
}
|
||||
|
||||
static inline uint32_t mtd_div_by_wb(uint64_t sz, struct mtd_info *mtd)
|
||||
{
|
||||
do_div(sz, mtd->writesize);
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* Kernel-side ioctl definitions */
|
||||
|
||||
extern int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id);
|
||||
|
@ -273,8 +280,8 @@ struct mtd_notifier {
|
|||
struct list_head list;
|
||||
};
|
||||
|
||||
struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset, size_t size,
|
||||
unsigned long flags, const char *name);
|
||||
struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
|
||||
uint64_t size, unsigned long flags, const char *name);
|
||||
int mtd_del_partition(struct mtd_info *mtd);
|
||||
|
||||
extern void register_mtd_user (struct mtd_notifier *new);
|
||||
|
|
10
lib/libmtd.c
10
lib/libmtd.c
|
@ -195,7 +195,7 @@ int libmtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs,
|
|||
void *buf, int len)
|
||||
{
|
||||
int ret, rd = 0;
|
||||
off_t seek;
|
||||
loff_t seek;
|
||||
|
||||
ret = mtd_valid_erase_block(mtd, eb);
|
||||
if (ret)
|
||||
|
@ -209,7 +209,7 @@ int libmtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs,
|
|||
}
|
||||
|
||||
/* Seek to the beginning of the eraseblock */
|
||||
seek = (off_t)eb * mtd->eb_size + offs;
|
||||
seek = (loff_t)eb * mtd->eb_size + offs;
|
||||
if (lseek(fd, seek, SEEK_SET) != seek)
|
||||
return sys_errmsg("cannot seek %s to offset %llu",
|
||||
mtd->node, (unsigned long long)seek);
|
||||
|
@ -229,7 +229,7 @@ int libmtd_write(const struct mtd_dev_info *mtd, int fd, int eb, int offs,
|
|||
void *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
off_t seek;
|
||||
loff_t seek;
|
||||
|
||||
ret = mtd_valid_erase_block(mtd, eb);
|
||||
if (ret)
|
||||
|
@ -255,7 +255,7 @@ int libmtd_write(const struct mtd_dev_info *mtd, int fd, int eb, int offs,
|
|||
}
|
||||
|
||||
/* Seek to the beginning of the eraseblock */
|
||||
seek = (off_t)eb * mtd->eb_size + offs;
|
||||
seek = (loff_t)eb * mtd->eb_size + offs;
|
||||
if (lseek(fd, seek, SEEK_SET) != seek)
|
||||
return sys_errmsg("cannot seek %s to offset %llu",
|
||||
mtd->node, (unsigned long long)seek);
|
||||
|
@ -326,7 +326,7 @@ int mtd_get_dev_info(const char *node, struct mtd_dev_info *mtd)
|
|||
goto out_close;
|
||||
}
|
||||
|
||||
mtd->eb_cnt = ui.size / ui.erasesize;
|
||||
mtd->eb_cnt = mtd_user_div_by_eb(ui.size, &ui);
|
||||
|
||||
switch(mtd->type) {
|
||||
case MTD_ABSENT:
|
||||
|
|
Loading…
Reference in New Issue