Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
ezynq
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
ezynq
Commits
9723d2aa
Commit
9723d2aa
authored
Jul 19, 2016
by
Oleg Dzhimiev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ubi support
parent
de55fc5d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
518 additions
and
0 deletions
+518
-0
elphel393_defconfig
u-boot-tree/configs/elphel393_defconfig
+1
-0
elphel393.h
u-boot-tree/include/configs/elphel393.h
+17
-0
mtd.h
u-boot-tree/include/linux/mtd/mtd.h
+500
-0
No files found.
u-boot-tree/configs/elphel393_defconfig
View file @
9723d2aa
...
...
@@ -19,5 +19,6 @@ CONFIG_ZYNQ_GEM=y
CONFIG_ZYNQ_QSPI=n
CONFIG_CMD_NAND=y
# i2c config is in ../include/configs/elphel393.h
# CONFIG_CMD_I2C=y
CONFIG_DM_I2C=n
u-boot-tree/include/configs/elphel393.h
View file @
9723d2aa
...
...
@@ -94,6 +94,23 @@
/*#define CONFIG_EZYNQ_SKIP_DDR*/
#define CONFIG_EZYNQ_SKIP_CLK
#define CONFIG_MTD_DEVICE
/* UBI support in full U-Boot */
#define CONFIG_MTD_PARTITIONS
#define CONFIG_CMD_MTDPARTS
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#define CONFIG_RBTREE
#define CONFIG_LZO
#define MTDIDS_DEFAULT "nand0=nand"
#define MTDPARTS_DEFAULT "mtdparts=nand:1m(u-boot-spl)," \
"4m(u-boot)," \
"1m(device-tree)," \
"16m(kernel)," \
"256m(rootfs)," \
"256m(rootfs)"
/* Default environment */
#define CONFIG_EXTRA_ENV_SETTINGS \
"ethaddr=00:0e:64:10:00:00\0" \
...
...
u-boot-tree/include/linux/mtd/mtd.h
0 → 100644
View file @
9723d2aa
/*
* Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> et al.
*
* SPDX-License-Identifier: GPL-2.0+
*
*/
#ifndef __MTD_MTD_H__
#define __MTD_MTD_H__
#ifndef __UBOOT__
#include <linux/types.h>
#include <linux/uio.h>
#include <linux/notifier.h>
#include <linux/device.h>
#include <mtd/mtd-abi.h>
#include <asm/div64.h>
#else
#include <linux/compat.h>
#include <mtd/mtd-abi.h>
#include <asm/errno.h>
#include <div64.h>
#define MAX_MTD_DEVICES 32
#endif
#define MTD_ERASE_PENDING 0x01
#define MTD_ERASING 0x02
#define MTD_ERASE_SUSPEND 0x04
#define MTD_ERASE_DONE 0x08
#define MTD_ERASE_FAILED 0x10
#define MTD_FAIL_ADDR_UNKNOWN -1LL
/*
* If the erase fails, fail_addr might indicate exactly which block failed. If
* fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level
* or was not specific to any particular block.
*/
struct
erase_info
{
struct
mtd_info
*
mtd
;
uint64_t
addr
;
uint64_t
len
;
uint64_t
fail_addr
;
u_long
time
;
u_long
retries
;
unsigned
dev
;
unsigned
cell
;
void
(
*
callback
)
(
struct
erase_info
*
self
);
u_long
priv
;
u_char
state
;
struct
erase_info
*
next
;
int
scrub
;
};
struct
mtd_erase_region_info
{
uint64_t
offset
;
/* At which this region starts, from the beginning of the MTD */
uint32_t
erasesize
;
/* For this region */
uint32_t
numblocks
;
/* Number of blocks of erasesize in this region */
unsigned
long
*
lockmap
;
/* If keeping bitmap of locks */
};
/**
* struct mtd_oob_ops - oob operation operands
* @mode: operation mode
*
* @len: number of data bytes to write/read
*
* @retlen: number of data bytes written/read
*
* @ooblen: number of oob bytes to write/read
* @oobretlen: number of oob bytes written/read
* @ooboffs: offset of oob data in the oob area (only relevant when
* mode = MTD_OPS_PLACE_OOB or MTD_OPS_RAW)
* @datbuf: data buffer - if NULL only oob data are read/written
* @oobbuf: oob data buffer
*
* Note, it is allowed to read more than one OOB area at one go, but not write.
* The interface assumes that the OOB write requests program only one page's
* OOB area.
*/
struct
mtd_oob_ops
{
unsigned
int
mode
;
size_t
len
;
size_t
retlen
;
size_t
ooblen
;
size_t
oobretlen
;
uint32_t
ooboffs
;
uint8_t
*
datbuf
;
uint8_t
*
oobbuf
;
};
#ifdef CONFIG_SYS_NAND_MAX_OOBFREE
#define MTD_MAX_OOBFREE_ENTRIES_LARGE CONFIG_SYS_NAND_MAX_OOBFREE
#else
#define MTD_MAX_OOBFREE_ENTRIES_LARGE 32
#endif
#ifdef CONFIG_SYS_NAND_MAX_ECCPOS
#define MTD_MAX_ECCPOS_ENTRIES_LARGE CONFIG_SYS_NAND_MAX_ECCPOS
#else
#define MTD_MAX_ECCPOS_ENTRIES_LARGE 680
#endif
/*
* Internal ECC layout control structure. For historical reasons, there is a
* similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained
* for export to user-space via the ECCGETLAYOUT ioctl.
* nand_ecclayout should be expandable in the future simply by the above macros.
*/
struct
nand_ecclayout
{
__u32
eccbytes
;
__u32
eccpos
[
MTD_MAX_ECCPOS_ENTRIES_LARGE
];
__u32
oobavail
;
struct
nand_oobfree
oobfree
[
MTD_MAX_OOBFREE_ENTRIES_LARGE
];
};
struct
module
;
/* only needed for owner field in mtd_info */
struct
mtd_info
{
u_char
type
;
uint32_t
flags
;
uint64_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
* information below if they desire
*/
uint32_t
erasesize
;
/* Minimal writable flash unit size. In case of NOR flash it is 1 (even
* though individual bits can be cleared), in case of NAND flash it is
* one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR
* it is of ECC block size, etc. It is illegal to have writesize = 0.
* Any driver registering a struct mtd_info must ensure a writesize of
* 1 or larger.
*/
uint32_t
writesize
;
/*
* Size of the write buffer used by the MTD. MTD devices having a write
* buffer can write multiple writesize chunks at a time. E.g. while
* writing 4 * writesize bytes to a device with 2 * writesize bytes
* buffer the MTD driver can (but doesn't have to) do 2 writesize
* operations, but not 4. Currently, all NANDs have writebufsize
* equivalent to writesize (NAND page size). Some NOR flashes do have
* writebufsize greater than writesize.
*/
uint32_t
writebufsize
;
uint32_t
oobsize
;
// Amount of OOB data per block (e.g. 16)
uint32_t
oobavail
;
// Available OOB bytes per block
/*
* If erasesize is a power of 2 then the shift is stored in
* erasesize_shift otherwise erasesize_shift is zero. Ditto writesize.
*/
unsigned
int
erasesize_shift
;
unsigned
int
writesize_shift
;
/* Masks based on erasesize_shift and writesize_shift */
unsigned
int
erasesize_mask
;
unsigned
int
writesize_mask
;
/*
* read ops return -EUCLEAN if max number of bitflips corrected on any
* one region comprising an ecc step equals or exceeds this value.
* Settable by driver, else defaults to ecc_strength. User can override
* in sysfs. N.B. The meaning of the -EUCLEAN return code has changed;
* see Documentation/ABI/testing/sysfs-class-mtd for more detail.
*/
unsigned
int
bitflip_threshold
;
// Kernel-only stuff starts here.
#ifndef __UBOOT__
const
char
*
name
;
#else
char
*
name
;
#endif
int
index
;
/* ECC layout structure pointer - read only! */
struct
nand_ecclayout
*
ecclayout
;
/* the ecc step size. */
unsigned
int
ecc_step_size
;
/* max number of correctible bit errors per ecc step */
unsigned
int
ecc_strength
;
/* Data for variable erase regions. If numeraseregions is zero,
* it means that the whole device has erasesize as given above.
*/
int
numeraseregions
;
struct
mtd_erase_region_info
*
eraseregions
;
/*
* Do not call via these pointers, use corresponding mtd_*()
* wrappers instead.
*/
int
(
*
_erase
)
(
struct
mtd_info
*
mtd
,
struct
erase_info
*
instr
);
#ifndef __UBOOT__
int
(
*
_point
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
void
**
virt
,
resource_size_t
*
phys
);
int
(
*
_unpoint
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
);
#endif
unsigned
long
(
*
_get_unmapped_area
)
(
struct
mtd_info
*
mtd
,
unsigned
long
len
,
unsigned
long
offset
,
unsigned
long
flags
);
int
(
*
_read
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
(
*
_write
)
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
);
int
(
*
_panic_write
)
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
);
int
(
*
_read_oob
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
struct
mtd_oob_ops
*
ops
);
int
(
*
_write_oob
)
(
struct
mtd_info
*
mtd
,
loff_t
to
,
struct
mtd_oob_ops
*
ops
);
int
(
*
_get_fact_prot_info
)
(
struct
mtd_info
*
mtd
,
size_t
len
,
size_t
*
retlen
,
struct
otp_info
*
buf
);
int
(
*
_read_fact_prot_reg
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
(
*
_get_user_prot_info
)
(
struct
mtd_info
*
mtd
,
size_t
len
,
size_t
*
retlen
,
struct
otp_info
*
buf
);
int
(
*
_read_user_prot_reg
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
(
*
_write_user_prot_reg
)
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
(
*
_lock_user_prot_reg
)
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
);
#ifndef __UBOOT__
int
(
*
_writev
)
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
);
#endif
void
(
*
_sync
)
(
struct
mtd_info
*
mtd
);
int
(
*
_lock
)
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
uint64_t
len
);
int
(
*
_unlock
)
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
uint64_t
len
);
int
(
*
_is_locked
)
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
uint64_t
len
);
int
(
*
_block_isreserved
)
(
struct
mtd_info
*
mtd
,
loff_t
ofs
);
int
(
*
_block_isbad
)
(
struct
mtd_info
*
mtd
,
loff_t
ofs
);
int
(
*
_block_markbad
)
(
struct
mtd_info
*
mtd
,
loff_t
ofs
);
#ifndef __UBOOT__
int
(
*
_suspend
)
(
struct
mtd_info
*
mtd
);
void
(
*
_resume
)
(
struct
mtd_info
*
mtd
);
void
(
*
_reboot
)
(
struct
mtd_info
*
mtd
);
#endif
/*
* If the driver is something smart, like UBI, it may need to maintain
* its own reference counting. The below functions are only for driver.
*/
int
(
*
_get_device
)
(
struct
mtd_info
*
mtd
);
void
(
*
_put_device
)
(
struct
mtd_info
*
mtd
);
#ifndef __UBOOT__
/* Backing device capabilities for this device
* - provides mmap capabilities
*/
struct
backing_dev_info
*
backing_dev_info
;
struct
notifier_block
reboot_notifier
;
/* default mode before reboot */
#endif
/* ECC status information */
struct
mtd_ecc_stats
ecc_stats
;
/* Subpage shift (NAND) */
int
subpage_sft
;
void
*
priv
;
struct
module
*
owner
;
#ifndef __UBOOT__
struct
device
dev
;
#else
struct
udevice
*
dev
;
#endif
int
usecount
;
};
int
mtd_erase
(
struct
mtd_info
*
mtd
,
struct
erase_info
*
instr
);
#ifndef __UBOOT__
int
mtd_point
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
void
**
virt
,
resource_size_t
*
phys
);
int
mtd_unpoint
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
);
#endif
unsigned
long
mtd_get_unmapped_area
(
struct
mtd_info
*
mtd
,
unsigned
long
len
,
unsigned
long
offset
,
unsigned
long
flags
);
int
mtd_read
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
mtd_write
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
);
int
mtd_panic_write
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
const
u_char
*
buf
);
int
mtd_read_oob
(
struct
mtd_info
*
mtd
,
loff_t
from
,
struct
mtd_oob_ops
*
ops
);
static
inline
int
mtd_write_oob
(
struct
mtd_info
*
mtd
,
loff_t
to
,
struct
mtd_oob_ops
*
ops
)
{
ops
->
retlen
=
ops
->
oobretlen
=
0
;
if
(
!
mtd
->
_write_oob
)
return
-
EOPNOTSUPP
;
if
(
!
(
mtd
->
flags
&
MTD_WRITEABLE
))
return
-
EROFS
;
return
mtd
->
_write_oob
(
mtd
,
to
,
ops
);
}
int
mtd_get_fact_prot_info
(
struct
mtd_info
*
mtd
,
size_t
len
,
size_t
*
retlen
,
struct
otp_info
*
buf
);
int
mtd_read_fact_prot_reg
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
mtd_get_user_prot_info
(
struct
mtd_info
*
mtd
,
size_t
len
,
size_t
*
retlen
,
struct
otp_info
*
buf
);
int
mtd_read_user_prot_reg
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
mtd_write_user_prot_reg
(
struct
mtd_info
*
mtd
,
loff_t
to
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
);
int
mtd_lock_user_prot_reg
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
);
#ifndef __UBOOT__
int
mtd_writev
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
);
#endif
static
inline
void
mtd_sync
(
struct
mtd_info
*
mtd
)
{
if
(
mtd
->
_sync
)
mtd
->
_sync
(
mtd
);
}
int
mtd_lock
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
uint64_t
len
);
int
mtd_unlock
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
uint64_t
len
);
int
mtd_is_locked
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
uint64_t
len
);
int
mtd_block_isreserved
(
struct
mtd_info
*
mtd
,
loff_t
ofs
);
int
mtd_block_isbad
(
struct
mtd_info
*
mtd
,
loff_t
ofs
);
int
mtd_block_markbad
(
struct
mtd_info
*
mtd
,
loff_t
ofs
);
#ifndef __UBOOT__
static
inline
int
mtd_suspend
(
struct
mtd_info
*
mtd
)
{
return
mtd
->
_suspend
?
mtd
->
_suspend
(
mtd
)
:
0
;
}
static
inline
void
mtd_resume
(
struct
mtd_info
*
mtd
)
{
if
(
mtd
->
_resume
)
mtd
->
_resume
(
mtd
);
}
#endif
static
inline
uint32_t
mtd_div_by_eb
(
uint64_t
sz
,
struct
mtd_info
*
mtd
)
{
if
(
mtd
->
erasesize_shift
)
return
sz
>>
mtd
->
erasesize_shift
;
do_div
(
sz
,
mtd
->
erasesize
);
return
sz
;
}
static
inline
uint32_t
mtd_mod_by_eb
(
uint64_t
sz
,
struct
mtd_info
*
mtd
)
{
if
(
mtd
->
erasesize_shift
)
return
sz
&
mtd
->
erasesize_mask
;
return
do_div
(
sz
,
mtd
->
erasesize
);
}
static
inline
uint32_t
mtd_div_by_ws
(
uint64_t
sz
,
struct
mtd_info
*
mtd
)
{
if
(
mtd
->
writesize_shift
)
return
sz
>>
mtd
->
writesize_shift
;
do_div
(
sz
,
mtd
->
writesize
);
return
sz
;
}
static
inline
uint32_t
mtd_mod_by_ws
(
uint64_t
sz
,
struct
mtd_info
*
mtd
)
{
if
(
mtd
->
writesize_shift
)
return
sz
&
mtd
->
writesize_mask
;
return
do_div
(
sz
,
mtd
->
writesize
);
}
static
inline
int
mtd_has_oob
(
const
struct
mtd_info
*
mtd
)
{
return
mtd
->
_read_oob
&&
mtd
->
_write_oob
;
}
static
inline
int
mtd_type_is_nand
(
const
struct
mtd_info
*
mtd
)
{
return
mtd
->
type
==
MTD_NANDFLASH
||
mtd
->
type
==
MTD_MLCNANDFLASH
;
}
static
inline
int
mtd_can_have_bb
(
const
struct
mtd_info
*
mtd
)
{
return
!!
mtd
->
_block_isbad
;
}
/* Kernel-side ioctl definitions */
struct
mtd_partition
;
struct
mtd_part_parser_data
;
extern
int
mtd_device_parse_register
(
struct
mtd_info
*
mtd
,
const
char
*
const
*
part_probe_types
,
struct
mtd_part_parser_data
*
parser_data
,
const
struct
mtd_partition
*
defparts
,
int
defnr_parts
);
#define mtd_device_register(master, parts, nr_parts) \
mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
extern
int
mtd_device_unregister
(
struct
mtd_info
*
master
);
extern
struct
mtd_info
*
get_mtd_device
(
struct
mtd_info
*
mtd
,
int
num
);
extern
int
__get_mtd_device
(
struct
mtd_info
*
mtd
);
extern
void
__put_mtd_device
(
struct
mtd_info
*
mtd
);
extern
struct
mtd_info
*
get_mtd_device_nm
(
const
char
*
name
);
extern
void
put_mtd_device
(
struct
mtd_info
*
mtd
);
#ifndef __UBOOT__
struct
mtd_notifier
{
void
(
*
add
)(
struct
mtd_info
*
mtd
);
void
(
*
remove
)(
struct
mtd_info
*
mtd
);
struct
list_head
list
;
};
extern
void
register_mtd_user
(
struct
mtd_notifier
*
new
);
extern
int
unregister_mtd_user
(
struct
mtd_notifier
*
old
);
#endif
void
*
mtd_kmalloc_up_to
(
const
struct
mtd_info
*
mtd
,
size_t
*
size
);
/*#ifdef CONFIG_MTD_PARTITIONS*/
#if defined(CONFIG_MTD_PARTITIONS) && !defined(CONFIG_SPL_BUILD)
void
mtd_erase_callback
(
struct
erase_info
*
instr
);
#else
static
inline
void
mtd_erase_callback
(
struct
erase_info
*
instr
)
{
if
(
instr
->
callback
)
instr
->
callback
(
instr
);
}
#endif
#ifdef __UBOOT__
/*
* Debugging macro and defines
*/
#define MTD_DEBUG_LEVEL0 (0)
/* Quiet */
#define MTD_DEBUG_LEVEL1 (1)
/* Audible */
#define MTD_DEBUG_LEVEL2 (2)
/* Loud */
#define MTD_DEBUG_LEVEL3 (3)
/* Noisy */
#ifdef CONFIG_MTD_DEBUG
#define pr_debug(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define MTDDEBUG(n, args...) \
do { \
if (n <= CONFIG_MTD_DEBUG_VERBOSE) \
printk(KERN_INFO args); \
} while(0)
#else
/* CONFIG_MTD_DEBUG */
#define pr_debug(args...)
#define MTDDEBUG(n, args...) \
do { \
if (0) \
printk(KERN_INFO args); \
} while(0)
#endif
/* CONFIG_MTD_DEBUG */
#define pr_info(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define pr_warn(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define pr_err(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define pr_crit(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define pr_cont(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define pr_notice(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#endif
static
inline
int
mtd_is_bitflip
(
int
err
)
{
return
err
==
-
EUCLEAN
;
}
static
inline
int
mtd_is_eccerr
(
int
err
)
{
return
err
==
-
EBADMSG
;
}
static
inline
int
mtd_is_bitflip_or_eccerr
(
int
err
)
{
return
mtd_is_bitflip
(
err
)
||
mtd_is_eccerr
(
err
);
}
unsigned
mtd_mmap_capabilities
(
struct
mtd_info
*
mtd
);
#ifdef __UBOOT__
/* drivers/mtd/mtdcore.h */
int
add_mtd_device
(
struct
mtd_info
*
mtd
);
int
del_mtd_device
(
struct
mtd_info
*
mtd
);
int
add_mtd_partitions
(
struct
mtd_info
*
,
const
struct
mtd_partition
*
,
int
);
int
del_mtd_partitions
(
struct
mtd_info
*
);
int
mtd_arg_off
(
const
char
*
arg
,
int
*
idx
,
loff_t
*
off
,
loff_t
*
size
,
loff_t
*
maxsize
,
int
devtype
,
uint64_t
chipsize
);
int
mtd_arg_off_size
(
int
argc
,
char
*
const
argv
[],
int
*
idx
,
loff_t
*
off
,
loff_t
*
size
,
loff_t
*
maxsize
,
int
devtype
,
uint64_t
chipsize
);
#endif
#endif
/* __MTD_MTD_H__ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment