Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
e3d18658
Commit
e3d18658
authored
Oct 14, 2007
by
David Woodhouse
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.infradead.org/~dedekind/ubi-2.6
parents
a2e1b833
cc5f4f28
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
274 additions
and
317 deletions
+274
-317
drivers/mtd/ubi/build.c
drivers/mtd/ubi/build.c
+27
-1
drivers/mtd/ubi/debug.c
drivers/mtd/ubi/debug.c
+2
-35
drivers/mtd/ubi/debug.h
drivers/mtd/ubi/debug.h
+0
-2
drivers/mtd/ubi/eba.c
drivers/mtd/ubi/eba.c
+60
-71
drivers/mtd/ubi/io.c
drivers/mtd/ubi/io.c
+35
-40
drivers/mtd/ubi/kapi.c
drivers/mtd/ubi/kapi.c
+7
-2
drivers/mtd/ubi/scan.c
drivers/mtd/ubi/scan.c
+21
-24
drivers/mtd/ubi/scan.h
drivers/mtd/ubi/scan.h
+4
-4
drivers/mtd/ubi/ubi.h
drivers/mtd/ubi/ubi.h
+30
-12
drivers/mtd/ubi/vmt.c
drivers/mtd/ubi/vmt.c
+37
-33
drivers/mtd/ubi/vtbl.c
drivers/mtd/ubi/vtbl.c
+4
-4
drivers/mtd/ubi/wl.c
drivers/mtd/ubi/wl.c
+47
-89
No files found.
drivers/mtd/ubi/build.c
View file @
e3d18658
...
...
@@ -565,7 +565,7 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset,
}
ubi
=
ubi_devices
[
ubi_devices_cnt
]
=
kzalloc
(
sizeof
(
struct
ubi_device
),
GFP_KERNEL
);
GFP_KERNEL
);
if
(
!
ubi
)
{
err
=
-
ENOMEM
;
goto
out_mtd
;
...
...
@@ -583,6 +583,22 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset,
if
(
err
)
goto
out_free
;
mutex_init
(
&
ubi
->
buf_mutex
);
ubi
->
peb_buf1
=
vmalloc
(
ubi
->
peb_size
);
if
(
!
ubi
->
peb_buf1
)
goto
out_free
;
ubi
->
peb_buf2
=
vmalloc
(
ubi
->
peb_size
);
if
(
!
ubi
->
peb_buf2
)
goto
out_free
;
#ifdef CONFIG_MTD_UBI_DEBUG
mutex_init
(
&
ubi
->
dbg_buf_mutex
);
ubi
->
dbg_peb_buf
=
vmalloc
(
ubi
->
peb_size
);
if
(
!
ubi
->
dbg_peb_buf
)
goto
out_free
;
#endif
err
=
attach_by_scanning
(
ubi
);
if
(
err
)
{
dbg_err
(
"failed to attach by scanning, error %d"
,
err
);
...
...
@@ -630,6 +646,11 @@ out_detach:
ubi_wl_close
(
ubi
);
vfree
(
ubi
->
vtbl
);
out_free:
vfree
(
ubi
->
peb_buf1
);
vfree
(
ubi
->
peb_buf2
);
#ifdef CONFIG_MTD_UBI_DEBUG
vfree
(
ubi
->
dbg_peb_buf
);
#endif
kfree
(
ubi
);
out_mtd:
put_mtd_device
(
mtd
);
...
...
@@ -651,6 +672,11 @@ static void detach_mtd_dev(struct ubi_device *ubi)
ubi_wl_close
(
ubi
);
vfree
(
ubi
->
vtbl
);
put_mtd_device
(
ubi
->
mtd
);
vfree
(
ubi
->
peb_buf1
);
vfree
(
ubi
->
peb_buf2
);
#ifdef CONFIG_MTD_UBI_DEBUG
vfree
(
ubi
->
dbg_peb_buf
);
#endif
kfree
(
ubi_devices
[
ubi_num
]);
ubi_devices
[
ubi_num
]
=
NULL
;
ubi_devices_cnt
-=
1
;
...
...
drivers/mtd/ubi/debug.c
View file @
e3d18658
...
...
@@ -42,7 +42,8 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
dbg_msg
(
"data_offset %d"
,
be32_to_cpu
(
ec_hdr
->
data_offset
));
dbg_msg
(
"hdr_crc %#08x"
,
be32_to_cpu
(
ec_hdr
->
hdr_crc
));
dbg_msg
(
"erase counter header hexdump:"
);
ubi_dbg_hexdump
(
ec_hdr
,
UBI_EC_HDR_SIZE
);
print_hex_dump
(
KERN_DEBUG
,
""
,
DUMP_PREFIX_OFFSET
,
32
,
1
,
ec_hdr
,
UBI_EC_HDR_SIZE
,
1
);
}
/**
...
...
@@ -187,38 +188,4 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req)
dbg_msg
(
"the 1st 16 characters of the name: %s"
,
nm
);
}
#define BYTES_PER_LINE 32
/**
* ubi_dbg_hexdump - dump a buffer.
* @ptr: the buffer to dump
* @size: buffer size which must be multiple of 4 bytes
*/
void
ubi_dbg_hexdump
(
const
void
*
ptr
,
int
size
)
{
int
i
,
k
=
0
,
rows
,
columns
;
const
uint8_t
*
p
=
ptr
;
size
=
ALIGN
(
size
,
4
);
rows
=
size
/
BYTES_PER_LINE
+
size
%
BYTES_PER_LINE
;
for
(
i
=
0
;
i
<
rows
;
i
++
)
{
int
j
;
cond_resched
();
columns
=
min
(
size
-
k
,
BYTES_PER_LINE
)
/
4
;
if
(
columns
==
0
)
break
;
printk
(
KERN_DEBUG
"%5d: "
,
i
*
BYTES_PER_LINE
);
for
(
j
=
0
;
j
<
columns
;
j
++
)
{
int
n
,
N
;
N
=
size
-
k
>
4
?
4
:
size
-
k
;
for
(
n
=
0
;
n
<
N
;
n
++
)
printk
(
"%02x"
,
p
[
k
++
]);
printk
(
" "
);
}
printk
(
"
\n
"
);
}
}
#endif
/* CONFIG_MTD_UBI_DEBUG_MSG */
drivers/mtd/ubi/debug.h
View file @
e3d18658
...
...
@@ -59,7 +59,6 @@ void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx);
void
ubi_dbg_dump_sv
(
const
struct
ubi_scan_volume
*
sv
);
void
ubi_dbg_dump_seb
(
const
struct
ubi_scan_leb
*
seb
,
int
type
);
void
ubi_dbg_dump_mkvol_req
(
const
struct
ubi_mkvol_req
*
req
);
void
ubi_dbg_hexdump
(
const
void
*
buf
,
int
size
);
#else
...
...
@@ -72,7 +71,6 @@ void ubi_dbg_hexdump(const void *buf, int size);
#define ubi_dbg_dump_sv(sv) ({})
#define ubi_dbg_dump_seb(seb, type) ({})
#define ubi_dbg_dump_mkvol_req(req) ({})
#define ubi_dbg_hexdump(buf, size) ({})
#endif
/* CONFIG_MTD_UBI_DEBUG_MSG */
...
...
drivers/mtd/ubi/eba.c
View file @
e3d18658
...
...
@@ -46,6 +46,9 @@
#include <linux/err.h>
#include "ubi.h"
/* Number of physical eraseblocks reserved for atomic LEB change operation */
#define EBA_RESERVED_PEBS 1
/**
* struct ltree_entry - an entry in the lock tree.
* @rb: links RB-tree nodes
...
...
@@ -157,7 +160,7 @@ static struct ltree_entry *ltree_add_entry(struct ubi_device *ubi, int vol_id,
{
struct
ltree_entry
*
le
,
*
le1
,
*
le_free
;
le
=
kmem_cache_alloc
(
ltree_slab
,
GFP_
KERNEL
);
le
=
kmem_cache_alloc
(
ltree_slab
,
GFP_
NOFS
);
if
(
!
le
)
return
ERR_PTR
(
-
ENOMEM
);
...
...
@@ -397,7 +400,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf,
retry:
if
(
check
)
{
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
);
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
,
GFP_NOFS
);
if
(
!
vid_hdr
)
{
err
=
-
ENOMEM
;
goto
out_unlock
;
...
...
@@ -495,16 +498,18 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
int
err
,
idx
=
vol_id2idx
(
ubi
,
vol_id
),
new_pnum
,
data_size
,
tries
=
0
;
struct
ubi_volume
*
vol
=
ubi
->
volumes
[
idx
];
struct
ubi_vid_hdr
*
vid_hdr
;
unsigned
char
*
new_buf
;
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
);
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
,
GFP_NOFS
);
if
(
!
vid_hdr
)
{
return
-
ENOMEM
;
}
mutex_lock
(
&
ubi
->
buf_mutex
);
retry:
new_pnum
=
ubi_wl_get_peb
(
ubi
,
UBI_UNKNOWN
);
if
(
new_pnum
<
0
)
{
mutex_unlock
(
&
ubi
->
buf_mutex
);
ubi_free_vid_hdr
(
ubi
,
vid_hdr
);
return
new_pnum
;
}
...
...
@@ -524,31 +529,22 @@ retry:
goto
write_error
;
data_size
=
offset
+
len
;
new_buf
=
vmalloc
(
data_size
);
if
(
!
new_buf
)
{
err
=
-
ENOMEM
;
goto
out_put
;
}
memset
(
new_buf
+
offset
,
0xFF
,
len
);
memset
(
ubi
->
peb_buf1
+
offset
,
0xFF
,
len
);
/* Read everything before the area where the write failure happened */
if
(
offset
>
0
)
{
err
=
ubi_io_read_data
(
ubi
,
new_buf
,
pnum
,
0
,
offset
);
if
(
err
&&
err
!=
UBI_IO_BITFLIPS
)
{
vfree
(
new_buf
);
err
=
ubi_io_read_data
(
ubi
,
ubi
->
peb_buf1
,
pnum
,
0
,
offset
);
if
(
err
&&
err
!=
UBI_IO_BITFLIPS
)
goto
out_put
;
}
}
memcpy
(
new_buf
+
offset
,
buf
,
len
);
memcpy
(
ubi
->
peb_buf1
+
offset
,
buf
,
len
);
err
=
ubi_io_write_data
(
ubi
,
new_buf
,
new_pnum
,
0
,
data_size
);
if
(
err
)
{
vfree
(
new_buf
);
err
=
ubi_io_write_data
(
ubi
,
ubi
->
peb_buf1
,
new_pnum
,
0
,
data_size
);
if
(
err
)
goto
write_error
;
}
vfree
(
new_buf
);
mutex_unlock
(
&
ubi
->
buf_mutex
);
ubi_free_vid_hdr
(
ubi
,
vid_hdr
);
vol
->
eba_tbl
[
lnum
]
=
new_pnum
;
...
...
@@ -558,6 +554,7 @@ retry:
return
0
;
out_put:
mutex_unlock
(
&
ubi
->
buf_mutex
);
ubi_wl_put_peb
(
ubi
,
new_pnum
,
1
);
ubi_free_vid_hdr
(
ubi
,
vid_hdr
);
return
err
;
...
...
@@ -570,6 +567,7 @@ write_error:
ubi_warn
(
"failed to write to PEB %d"
,
new_pnum
);
ubi_wl_put_peb
(
ubi
,
new_pnum
,
1
);
if
(
++
tries
>
UBI_IO_RETRIES
)
{
mutex_unlock
(
&
ubi
->
buf_mutex
);
ubi_free_vid_hdr
(
ubi
,
vid_hdr
);
return
err
;
}
...
...
@@ -627,7 +625,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum,
* The logical eraseblock is not mapped. We have to get a free physical
* eraseblock and write the volume identifier header there first.
*/
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
);
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
,
GFP_NOFS
);
if
(
!
vid_hdr
)
{
leb_write_unlock
(
ubi
,
vol_id
,
lnum
);
return
-
ENOMEM
;
...
...
@@ -738,7 +736,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum,
else
ubi_assert
(
len
%
ubi
->
min_io_size
==
0
);
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
);
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
,
GFP_NOFS
);
if
(
!
vid_hdr
)
return
-
ENOMEM
;
...
...
@@ -832,6 +830,9 @@ write_error:
* data, which has to be aligned. This function guarantees that in case of an
* unclean reboot the old contents is preserved. Returns zero in case of
* success and a negative error code in case of failure.
*
* UBI reserves one LEB for the "atomic LEB change" operation, so only one
* LEB change may be done at a time. This is ensured by @ubi->alc_mutex.
*/
int
ubi_eba_atomic_leb_change
(
struct
ubi_device
*
ubi
,
int
vol_id
,
int
lnum
,
const
void
*
buf
,
int
len
,
int
dtype
)
...
...
@@ -844,15 +845,14 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum,
if
(
ubi
->
ro_mode
)
return
-
EROFS
;
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
);
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
,
GFP_NOFS
);
if
(
!
vid_hdr
)
return
-
ENOMEM
;
mutex_lock
(
&
ubi
->
alc_mutex
);
err
=
leb_write_lock
(
ubi
,
vol_id
,
lnum
);
if
(
err
)
{
ubi_free_vid_hdr
(
ubi
,
vid_hdr
);
return
err
;
}
if
(
err
)
goto
out_mutex
;
vid_hdr
->
sqnum
=
cpu_to_be64
(
next_sqnum
(
ubi
));
vid_hdr
->
vol_id
=
cpu_to_be32
(
vol_id
);
...
...
@@ -869,9 +869,8 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum,
retry:
pnum
=
ubi_wl_get_peb
(
ubi
,
dtype
);
if
(
pnum
<
0
)
{
ubi_free_vid_hdr
(
ubi
,
vid_hdr
);
leb_write_unlock
(
ubi
,
vol_id
,
lnum
);
return
pnum
;
err
=
pnum
;
goto
out_leb_unlock
;
}
dbg_eba
(
"change LEB %d:%d, PEB %d, write VID hdr to PEB %d"
,
...
...
@@ -893,17 +892,18 @@ retry:
if
(
vol
->
eba_tbl
[
lnum
]
>=
0
)
{
err
=
ubi_wl_put_peb
(
ubi
,
vol
->
eba_tbl
[
lnum
],
1
);
if
(
err
)
{
ubi_free_vid_hdr
(
ubi
,
vid_hdr
);
leb_write_unlock
(
ubi
,
vol_id
,
lnum
);
return
err
;
}
if
(
err
)
goto
out_leb_unlock
;
}
vol
->
eba_tbl
[
lnum
]
=
pnum
;
out_leb_unlock:
leb_write_unlock
(
ubi
,
vol_id
,
lnum
);
out_mutex:
mutex_unlock
(
&
ubi
->
alc_mutex
);
ubi_free_vid_hdr
(
ubi
,
vid_hdr
);
return
0
;
return
err
;
write_error:
if
(
err
!=
-
EIO
||
!
ubi
->
bad_allowed
)
{
...
...
@@ -913,17 +913,13 @@ write_error:
* mode just in case.
*/
ubi_ro_mode
(
ubi
);
leb_write_unlock
(
ubi
,
vol_id
,
lnum
);
ubi_free_vid_hdr
(
ubi
,
vid_hdr
);
return
err
;
goto
out_leb_unlock
;
}
err
=
ubi_wl_put_peb
(
ubi
,
pnum
,
1
);
if
(
err
||
++
tries
>
UBI_IO_RETRIES
)
{
ubi_ro_mode
(
ubi
);
leb_write_unlock
(
ubi
,
vol_id
,
lnum
);
ubi_free_vid_hdr
(
ubi
,
vid_hdr
);
return
err
;
goto
out_leb_unlock
;
}
vid_hdr
->
sqnum
=
cpu_to_be64
(
next_sqnum
(
ubi
));
...
...
@@ -965,7 +961,6 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
int
err
,
vol_id
,
lnum
,
data_size
,
aldata_size
,
pnum
,
idx
;
struct
ubi_volume
*
vol
;
uint32_t
crc
;
void
*
buf
,
*
buf1
=
NULL
;
vol_id
=
be32_to_cpu
(
vid_hdr
->
vol_id
);
lnum
=
be32_to_cpu
(
vid_hdr
->
lnum
);
...
...
@@ -979,19 +974,15 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
data_size
=
aldata_size
=
ubi
->
leb_size
-
be32_to_cpu
(
vid_hdr
->
data_pad
);
buf
=
vmalloc
(
aldata_size
);
if
(
!
buf
)
return
-
ENOMEM
;
/*
* We do not want anybody to write to this logical eraseblock while we
* are moving it, so we lock it.
*/
err
=
leb_write_lock
(
ubi
,
vol_id
,
lnum
);
if
(
err
)
{
vfree
(
buf
);
if
(
err
)
return
err
;
}
mutex_lock
(
&
ubi
->
buf_mutex
);
/*
* But the logical eraseblock might have been put by this time.
...
...
@@ -1023,7 +1014,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
/* OK, now the LEB is locked and we can safely start moving it */
dbg_eba
(
"read %d bytes of data"
,
aldata_size
);
err
=
ubi_io_read_data
(
ubi
,
buf
,
from
,
0
,
aldata_size
);
err
=
ubi_io_read_data
(
ubi
,
ubi
->
peb_buf1
,
from
,
0
,
aldata_size
);
if
(
err
&&
err
!=
UBI_IO_BITFLIPS
)
{
ubi_warn
(
"error %d while reading data from PEB %d"
,
err
,
from
);
...
...
@@ -1042,10 +1033,10 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
*/
if
(
vid_hdr
->
vol_type
==
UBI_VID_DYNAMIC
)
aldata_size
=
data_size
=
ubi_calc_data_len
(
ubi
,
buf
,
data_size
);
ubi_calc_data_len
(
ubi
,
ubi
->
peb_buf1
,
data_size
);
cond_resched
();
crc
=
crc32
(
UBI_CRC32_INIT
,
buf
,
data_size
);
crc
=
crc32
(
UBI_CRC32_INIT
,
ubi
->
peb_buf1
,
data_size
);
cond_resched
();
/*
...
...
@@ -1076,23 +1067,18 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
}
if
(
data_size
>
0
)
{
err
=
ubi_io_write_data
(
ubi
,
buf
,
to
,
0
,
aldata_size
);
err
=
ubi_io_write_data
(
ubi
,
ubi
->
peb_buf1
,
to
,
0
,
aldata_size
);
if
(
err
)
goto
out_unlock
;
cond_resched
();
/*
* We've written the data and are going to read it back to make
* sure it was written correctly.
*/
buf1
=
vmalloc
(
aldata_size
);
if
(
!
buf1
)
{
err
=
-
ENOMEM
;
goto
out_unlock
;
}
cond_resched
();
err
=
ubi_io_read_data
(
ubi
,
buf1
,
to
,
0
,
aldata_size
);
err
=
ubi_io_read_data
(
ubi
,
ubi
->
peb_buf2
,
to
,
0
,
aldata_size
);
if
(
err
)
{
if
(
err
!=
UBI_IO_BITFLIPS
)
ubi_warn
(
"cannot read data back from PEB %d"
,
...
...
@@ -1102,7 +1088,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
cond_resched
();
if
(
memcmp
(
buf
,
buf1
,
aldata_size
))
{
if
(
memcmp
(
ubi
->
peb_buf1
,
ubi
->
peb_buf2
,
aldata_size
))
{
ubi_warn
(
"read data back from PEB %d - it is different"
,
to
);
goto
out_unlock
;
...
...
@@ -1112,16 +1098,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
ubi_assert
(
vol
->
eba_tbl
[
lnum
]
==
from
);
vol
->
eba_tbl
[
lnum
]
=
to
;
leb_write_unlock
(
ubi
,
vol_id
,
lnum
);
vfree
(
buf
);
vfree
(
buf1
);
return
0
;
out_unlock:
mutex_unlock
(
&
ubi
->
buf_mutex
);
leb_write_unlock
(
ubi
,
vol_id
,
lnum
);
vfree
(
buf
);
vfree
(
buf1
);
return
err
;
}
...
...
@@ -1144,6 +1123,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
dbg_eba
(
"initialize EBA unit"
);
spin_lock_init
(
&
ubi
->
ltree_lock
);
mutex_init
(
&
ubi
->
alc_mutex
);
ubi
->
ltree
=
RB_ROOT
;
if
(
ubi_devices_cnt
==
0
)
{
...
...
@@ -1205,6 +1185,15 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
ubi
->
rsvd_pebs
+=
ubi
->
beb_rsvd_pebs
;
}
if
(
ubi
->
avail_pebs
<
EBA_RESERVED_PEBS
)
{
ubi_err
(
"no enough physical eraseblocks (%d, need %d)"
,
ubi
->
avail_pebs
,
EBA_RESERVED_PEBS
);
err
=
-
ENOSPC
;
goto
out_free
;
}
ubi
->
avail_pebs
-=
EBA_RESERVED_PEBS
;
ubi
->
rsvd_pebs
+=
EBA_RESERVED_PEBS
;
dbg_eba
(
"EBA unit is initialized"
);
return
0
;
...
...
drivers/mtd/ubi/io.c
View file @
e3d18658
...
...
@@ -98,8 +98,8 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
static
int
paranoid_check_peb_vid_hdr
(
const
struct
ubi_device
*
ubi
,
int
pnum
);
static
int
paranoid_check_vid_hdr
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
const
struct
ubi_vid_hdr
*
vid_hdr
);
static
int
paranoid_check_all_ff
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
offset
,
int
len
);
static
int
paranoid_check_all_ff
(
struct
ubi_device
*
ubi
,
int
pnum
,
int
offset
,
int
len
);
#else
#define paranoid_check_not_bad(ubi, pnum) 0
#define paranoid_check_peb_ec_hdr(ubi, pnum) 0
...
...
@@ -202,8 +202,8 @@ retry:
* Note, in case of an error, it is possible that something was still written
* to the flash media, but may be some garbage.
*/
int
ubi_io_write
(
const
struct
ubi_device
*
ubi
,
const
void
*
buf
,
int
pnum
,
int
offset
,
int
len
)
int
ubi_io_write
(
struct
ubi_device
*
ubi
,
const
void
*
buf
,
int
pnum
,
int
offset
,
int
len
)
{
int
err
;
size_t
written
;
...
...
@@ -285,7 +285,7 @@ static void erase_callback(struct erase_info *ei)
* zero in case of success and a negative error code in case of failure. If
* %-EIO is returned, the physical eraseblock most probably went bad.
*/
static
int
do_sync_erase
(
const
struct
ubi_device
*
ubi
,
int
pnum
)
static
int
do_sync_erase
(
struct
ubi_device
*
ubi
,
int
pnum
)
{
int
err
,
retries
=
0
;
struct
erase_info
ei
;
...
...
@@ -377,29 +377,25 @@ static uint8_t patterns[] = {0xa5, 0x5a, 0x0};
* test, a positive number of erase operations done if the test was
* successfully passed, and other negative error codes in case of other errors.
*/
static
int
torture_peb
(
const
struct
ubi_device
*
ubi
,
int
pnum
)
static
int
torture_peb
(
struct
ubi_device
*
ubi
,
int
pnum
)
{
void
*
buf
;
int
err
,
i
,
patt_count
;
buf
=
vmalloc
(
ubi
->
peb_size
);
if
(
!
buf
)
return
-
ENOMEM
;
patt_count
=
ARRAY_SIZE
(
patterns
);
ubi_assert
(
patt_count
>
0
);
mutex_lock
(
&
ubi
->
buf_mutex
);
for
(
i
=
0
;
i
<
patt_count
;
i
++
)
{
err
=
do_sync_erase
(
ubi
,
pnum
);
if
(
err
)
goto
out
;
/* Make sure the PEB contains only 0xFF bytes */
err
=
ubi_io_read
(
ubi
,
buf
,
pnum
,
0
,
ubi
->
peb_size
);
err
=
ubi_io_read
(
ubi
,
ubi
->
peb_buf1
,
pnum
,
0
,
ubi
->
peb_size
);
if
(
err
)
goto
out
;
err
=
check_pattern
(
buf
,
0xFF
,
ubi
->
peb_size
);
err
=
check_pattern
(
ubi
->
peb_buf1
,
0xFF
,
ubi
->
peb_size
);
if
(
err
==
0
)
{
ubi_err
(
"erased PEB %d, but a non-0xFF byte found"
,
pnum
);
...
...
@@ -408,17 +404,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
}
/* Write a pattern and check it */
memset
(
buf
,
patterns
[
i
],
ubi
->
peb_size
);
err
=
ubi_io_write
(
ubi
,
buf
,
pnum
,
0
,
ubi
->
peb_size
);
memset
(
ubi
->
peb_buf1
,
patterns
[
i
],
ubi
->
peb_size
);
err
=
ubi_io_write
(
ubi
,
ubi
->
peb_buf1
,
pnum
,
0
,
ubi
->
peb_size
);
if
(
err
)
goto
out
;
memset
(
buf
,
~
patterns
[
i
],
ubi
->
peb_size
);
err
=
ubi_io_read
(
ubi
,
buf
,
pnum
,
0
,
ubi
->
peb_size
);
memset
(
ubi
->
peb_buf1
,
~
patterns
[
i
],
ubi
->
peb_size
);
err
=
ubi_io_read
(
ubi
,
ubi
->
peb_buf1
,
pnum
,
0
,
ubi
->
peb_size
);
if
(
err
)
goto
out
;
err
=
check_pattern
(
buf
,
patterns
[
i
],
ubi
->
peb_size
);
err
=
check_pattern
(
ubi
->
peb_buf1
,
patterns
[
i
],
ubi
->
peb_size
);
if
(
err
==
0
)
{
ubi_err
(
"pattern %x checking failed for PEB %d"
,
patterns
[
i
],
pnum
);
...
...
@@ -430,14 +426,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
err
=
patt_count
;
out:
if
(
err
==
UBI_IO_BITFLIPS
||
err
==
-
EBADMSG
)
mutex_unlock
(
&
ubi
->
buf_mutex
);
if
(
err
==
UBI_IO_BITFLIPS
||
err
==
-
EBADMSG
)
{
/*
* If a bit-flip or data integrity error was detected, the test
* has not passed because it happened on a freshly erased
* physical eraseblock which means something is wrong with it.
*/
ubi_err
(
"read problems on freshly erased PEB %d, must be bad"
,
pnum
);
err
=
-
EIO
;
vfree
(
buf
);
}
return
err
;
}
...
...
@@ -457,7 +456,7 @@ out:
* codes in case of other errors. Note, %-EIO means that the physical
* eraseblock is bad.
*/
int
ubi_io_sync_erase
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
torture
)
int
ubi_io_sync_erase
(
struct
ubi_device
*
ubi
,
int
pnum
,
int
torture
)
{
int
err
,
ret
=
0
;
...
...
@@ -614,7 +613,7 @@ bad:
* o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty;
* o a negative error code in case of failure.
*/
int
ubi_io_read_ec_hdr
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
ubi_io_read_ec_hdr
(
struct
ubi_device
*
ubi
,
int
pnum
,
struct
ubi_ec_hdr
*
ec_hdr
,
int
verbose
)
{
int
err
,
read_err
=
0
;
...
...
@@ -720,7 +719,7 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum,
* case of failure. If %-EIO is returned, the physical eraseblock most probably
* went bad.
*/
int
ubi_io_write_ec_hdr
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
ubi_io_write_ec_hdr
(
struct
ubi_device
*
ubi
,
int
pnum
,
struct
ubi_ec_hdr
*
ec_hdr
)
{
int
err
;
...
...
@@ -886,7 +885,7 @@ bad:
* header there);
* o a negative error code in case of failure.
*/
int
ubi_io_read_vid_hdr
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
ubi_io_read_vid_hdr
(
struct
ubi_device
*
ubi
,
int
pnum
,
struct
ubi_vid_hdr
*
vid_hdr
,
int
verbose
)
{
int
err
,
read_err
=
0
;
...
...
@@ -993,7 +992,7 @@ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum,
* case of failure. If %-EIO is returned, the physical eraseblock probably went
* bad.
*/
int
ubi_io_write_vid_hdr
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
ubi_io_write_vid_hdr
(
struct
ubi_device
*
ubi
,
int
pnum
,
struct
ubi_vid_hdr
*
vid_hdr
)
{
int
err
;
...
...
@@ -1096,7 +1095,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
uint32_t
crc
,
hdr_crc
;
struct
ubi_ec_hdr
*
ec_hdr
;
ec_hdr
=
kzalloc
(
ubi
->
ec_hdr_alsize
,
GFP_
KERNEL
);
ec_hdr
=
kzalloc
(
ubi
->
ec_hdr_alsize
,
GFP_
NOFS
);
if
(
!
ec_hdr
)
return
-
ENOMEM
;
...
...
@@ -1176,7 +1175,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
struct
ubi_vid_hdr
*
vid_hdr
;
void
*
p
;
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
);
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
,
GFP_NOFS
);
if
(
!
vid_hdr
)
return
-
ENOMEM
;
...
...
@@ -1216,44 +1215,40 @@ exit:
* @offset of the physical eraseblock @pnum, %1 if not, and a negative error
* code if an error occurred.
*/
static
int
paranoid_check_all_ff
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
offset
,
int
len
)
static
int
paranoid_check_all_ff
(
struct
ubi_device
*
ubi
,
int
pnum
,
int
offset
,
int
len
)
{
size_t
read
;
int
err
;
void
*
buf
;
loff_t
addr
=
(
loff_t
)
pnum
*
ubi
->
peb_size
+
offset
;
buf
=
vmalloc
(
len
);
if
(
!
buf
)
return
-
ENOMEM
;
memset
(
buf
,
0
,
len
);
err
=
ubi
->
mtd
->
read
(
ubi
->
mtd
,
addr
,
len
,
&
read
,
buf
);
mutex_lock
(
&
ubi
->
dbg_buf_mutex
);
err
=
ubi
->
mtd
->
read
(
ubi
->
mtd
,
addr
,
len
,
&
read
,
ubi
->
dbg_peb_buf
);
if
(
err
&&
err
!=
-
EUCLEAN
)
{
ubi_err
(
"error %d while reading %d bytes from PEB %d:%d, "
"read %zd bytes"
,
err
,
len
,
pnum
,
offset
,
read
);
goto
error
;
}
err
=
check_pattern
(
buf
,
0xFF
,
len
);
err
=
check_pattern
(
ubi
->
dbg_peb_
buf
,
0xFF
,
len
);
if
(
err
==
0
)
{
ubi_err
(
"flash region at PEB %d:%d, length %d does not "
"contain all 0xFF bytes"
,
pnum
,
offset
,
len
);
goto
fail
;
}
mutex_unlock
(
&
ubi
->
dbg_buf_mutex
);
vfree
(
buf
);
return
0
;
fail:
ubi_err
(
"paranoid check failed for PEB %d"
,
pnum
);
dbg_msg
(
"hex dump of the %d-%d region"
,
offset
,
offset
+
len
);
ubi_dbg_hexdump
(
buf
,
len
);
print_hex_dump
(
KERN_DEBUG
,
""
,
DUMP_PREFIX_OFFSET
,
32
,
1
,
ubi
->
dbg_peb_buf
,
len
,
1
);
err
=
1
;
error:
ubi_dbg_dump_stack
();
vfree
(
buf
);
mutex_unlock
(
&
ubi
->
dbg_buf_mutex
);
return
err
;
}
...
...
drivers/mtd/ubi/kapi.c
View file @
e3d18658
...
...
@@ -99,16 +99,21 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
{
int
err
;
struct
ubi_volume_desc
*
desc
;
struct
ubi_device
*
ubi
=
ubi_devices
[
ubi_num
]
;
struct
ubi_device
*
ubi
;
struct
ubi_volume
*
vol
;
dbg_msg
(
"open device %d volume %d, mode %d"
,
ubi_num
,
vol_id
,
mode
);
err
=
-
ENODEV
;
if
(
ubi_num
<
0
)
return
ERR_PTR
(
err
);
ubi
=
ubi_devices
[
ubi_num
];
if
(
!
try_module_get
(
THIS_MODULE
))
return
ERR_PTR
(
err
);
if
(
ubi_num
<
0
||
ubi_num
>=
UBI_MAX_DEVICES
||
!
ubi
)
if
(
ubi_num
>=
UBI_MAX_DEVICES
||
!
ubi
)
goto
out_put
;
err
=
-
EINVAL
;
...
...
drivers/mtd/ubi/scan.c
View file @
e3d18658
...
...
@@ -45,8 +45,7 @@
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
static
int
paranoid_check_si
(
const
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
);
static
int
paranoid_check_si
(
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
);
#else
#define paranoid_check_si(ubi, si) 0
#endif
...
...
@@ -259,14 +258,13 @@ static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id,
* o bit 2 is cleared: the older LEB is not corrupted;
* o bit 2 is set: the older LEB is corrupted.
*/
static
int
compare_lebs
(
const
struct
ubi_device
*
ubi
,
const
struct
ubi_scan_leb
*
seb
,
int
pnum
,
const
struct
ubi_vid_hdr
*
vid_hdr
)
static
int
compare_lebs
(
struct
ubi_device
*
ubi
,
const
struct
ubi_scan_leb
*
seb
,
int
pnum
,
const
struct
ubi_vid_hdr
*
vid_hdr
)
{
void
*
buf
;
int
len
,
err
,
second_is_newer
,
bitflips
=
0
,
corrupted
=
0
;
uint32_t
data_crc
,
crc
;
struct
ubi_vid_hdr
*
v
id
h
=
NULL
;
struct
ubi_vid_hdr
*
vh
=
NULL
;
unsigned
long
long
sqnum2
=
be64_to_cpu
(
vid_hdr
->
sqnum
);
if
(
seb
->
sqnum
==
0
&&
sqnum2
==
0
)
{
...
...
@@ -323,11 +321,11 @@ static int compare_lebs(const struct ubi_device *ubi,
}
else
{
pnum
=
seb
->
pnum
;
v
idh
=
ubi_zalloc_vid_hdr
(
ubi
);
if
(
!
v
id
h
)
v
h
=
ubi_zalloc_vid_hdr
(
ubi
,
GFP_KERNEL
);
if
(
!
vh
)
return
-
ENOMEM
;
err
=
ubi_io_read_vid_hdr
(
ubi
,
pnum
,
v
id
h
,
0
);
err
=
ubi_io_read_vid_hdr
(
ubi
,
pnum
,
vh
,
0
);
if
(
err
)
{
if
(
err
==
UBI_IO_BITFLIPS
)
bitflips
=
1
;
...
...
@@ -341,7 +339,7 @@ static int compare_lebs(const struct ubi_device *ubi,
}
}
if
(
!
v
id
h
->
copy_flag
)
{
if
(
!
vh
->
copy_flag
)
{
/* It is not a copy, so it is newer */
dbg_bld
(
"first PEB %d is newer, copy_flag is unset"
,
pnum
);
...
...
@@ -349,7 +347,7 @@ static int compare_lebs(const struct ubi_device *ubi,
goto
out_free_vidh
;
}
vid_hdr
=
v
id
h
;
vid_hdr
=
vh
;
}
/* Read the data of the copy and check the CRC */
...
...
@@ -379,7 +377,7 @@ static int compare_lebs(const struct ubi_device *ubi,
}
vfree
(
buf
);
ubi_free_vid_hdr
(
ubi
,
v
id
h
);
ubi_free_vid_hdr
(
ubi
,
vh
);
if
(
second_is_newer
)
dbg_bld
(
"second PEB %d is newer, copy_flag is set"
,
pnum
);
...
...
@@ -391,7 +389,7 @@ static int compare_lebs(const struct ubi_device *ubi,
out_free_buf:
vfree
(
buf
);
out_free_vidh:
ubi_free_vid_hdr
(
ubi
,
v
id
h
);
ubi_free_vid_hdr
(
ubi
,
vh
);
ubi_assert
(
err
<
0
);
return
err
;
}
...
...
@@ -413,7 +411,7 @@ out_free_vidh:
* to be picked, while the older one has to be dropped. This function returns
* zero in case of success and a negative error code in case of failure.
*/
int
ubi_scan_add_used
(
const
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
,
int
ubi_scan_add_used
(
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
,
int
pnum
,
int
ec
,
const
struct
ubi_vid_hdr
*
vid_hdr
,
int
bitflips
)
{
...
...
@@ -667,16 +665,12 @@ void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv)
* function returns zero in case of success and a negative error code in case
* of failure.
*/
int
ubi_scan_erase_peb
(
const
struct
ubi_device
*
ub
i
,
const
struct
ubi_scan_info
*
si
,
int
pnum
,
int
ec
)
int
ubi_scan_erase_peb
(
struct
ubi_device
*
ubi
,
const
struct
ubi_scan_info
*
s
i
,
int
pnum
,
int
ec
)
{
int
err
;
struct
ubi_ec_hdr
*
ec_hdr
;
ec_hdr
=
kzalloc
(
ubi
->
ec_hdr_alsize
,
GFP_KERNEL
);
if
(
!
ec_hdr
)
return
-
ENOMEM
;
if
((
long
long
)
ec
>=
UBI_MAX_ERASECOUNTER
)
{
/*
* Erase counter overflow. Upgrade UBI and use 64-bit
...
...
@@ -686,6 +680,10 @@ int ubi_scan_erase_peb(const struct ubi_device *ubi,
return
-
EINVAL
;
}
ec_hdr
=
kzalloc
(
ubi
->
ec_hdr_alsize
,
GFP_KERNEL
);
if
(
!
ec_hdr
)
return
-
ENOMEM
;
ec_hdr
->
ec
=
cpu_to_be64
(
ec
);
err
=
ubi_io_sync_erase
(
ubi
,
pnum
,
0
);
...
...
@@ -712,7 +710,7 @@ out_free:
* This function returns scanning physical eraseblock information in case of
* success and an error code in case of failure.
*/
struct
ubi_scan_leb
*
ubi_scan_get_free_peb
(
const
struct
ubi_device
*
ubi
,
struct
ubi_scan_leb
*
ubi_scan_get_free_peb
(
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
)
{
int
err
=
0
,
i
;
...
...
@@ -948,7 +946,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
if
(
!
ech
)
goto
out_si
;
vidh
=
ubi_zalloc_vid_hdr
(
ubi
);
vidh
=
ubi_zalloc_vid_hdr
(
ubi
,
GFP_KERNEL
);
if
(
!
vidh
)
goto
out_ech
;
...
...
@@ -1110,8 +1108,7 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si)
* This function returns zero if the scanning information is all right, %1 if
* not and a negative error code if an error occurred.
*/
static
int
paranoid_check_si
(
const
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
)
static
int
paranoid_check_si
(
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
)
{
int
pnum
,
err
,
vols_found
=
0
;
struct
rb_node
*
rb1
,
*
rb2
;
...
...
drivers/mtd/ubi/scan.h
View file @
e3d18658
...
...
@@ -147,7 +147,7 @@ static inline void ubi_scan_move_to_list(struct ubi_scan_volume *sv,
list_add_tail
(
&
seb
->
u
.
list
,
list
);
}
int
ubi_scan_add_used
(
const
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
,
int
ubi_scan_add_used
(
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
,
int
pnum
,
int
ec
,
const
struct
ubi_vid_hdr
*
vid_hdr
,
int
bitflips
);
struct
ubi_scan_volume
*
ubi_scan_find_sv
(
const
struct
ubi_scan_info
*
si
,
...
...
@@ -155,10 +155,10 @@ struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si,
struct
ubi_scan_leb
*
ubi_scan_find_seb
(
const
struct
ubi_scan_volume
*
sv
,
int
lnum
);
void
ubi_scan_rm_volume
(
struct
ubi_scan_info
*
si
,
struct
ubi_scan_volume
*
sv
);
struct
ubi_scan_leb
*
ubi_scan_get_free_peb
(
const
struct
ubi_device
*
ubi
,
struct
ubi_scan_leb
*
ubi_scan_get_free_peb
(
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
);
int
ubi_scan_erase_peb
(
const
struct
ubi_device
*
ub
i
,
const
struct
ubi_scan_info
*
si
,
int
pnum
,
int
ec
);
int
ubi_scan_erase_peb
(
struct
ubi_device
*
ubi
,
const
struct
ubi_scan_info
*
s
i
,
int
pnum
,
int
ec
);
struct
ubi_scan_info
*
ubi_scan
(
struct
ubi_device
*
ubi
);
void
ubi_scan_destroy_si
(
struct
ubi_scan_info
*
si
);
...
...
drivers/mtd/ubi/ubi.h
View file @
e3d18658
...
...
@@ -221,14 +221,15 @@ struct ubi_wl_entry;
* @vtbl_slots: how many slots are available in the volume table
* @vtbl_size: size of the volume table in bytes
* @vtbl: in-RAM volume table copy
* @vtbl_mutex: protects on-flash volume table
*
* @max_ec: current highest erase counter value
* @mean_ec: current mean erase counter value
*
* global_sqnum: global sequence number
*
@
global_sqnum: global sequence number
* @ltree_lock: protects the lock tree and @global_sqnum
* @ltree: the lock tree
* @
vtbl_mutex: protects on-flash volume table
* @
alc_mutex: serializes "atomic LEB change" operations
*
* @used: RB-tree of used physical eraseblocks
* @free: RB-tree of free physical eraseblocks
...
...
@@ -274,6 +275,12 @@ struct ubi_wl_entry;
* @bad_allowed: whether the MTD device admits of bad physical eraseblocks or
* not
* @mtd: MTD device descriptor
*
* @peb_buf1: a buffer of PEB size used for different purposes
* @peb_buf2: another buffer of PEB size used for different purposes
* @buf_mutex: proptects @peb_buf1 and @peb_buf2
* @dbg_peb_buf: buffer of PEB size used for debugging
* @dbg_buf_mutex: proptects @dbg_peb_buf
*/
struct
ubi_device
{
struct
cdev
cdev
;
...
...
@@ -302,6 +309,7 @@ struct ubi_device {
unsigned
long
long
global_sqnum
;
spinlock_t
ltree_lock
;
struct
rb_root
ltree
;
struct
mutex
alc_mutex
;
/* Wear-leveling unit's stuff */
struct
rb_root
used
;
...
...
@@ -343,6 +351,14 @@ struct ubi_device {
int
vid_hdr_shift
;
int
bad_allowed
;
struct
mtd_info
*
mtd
;
void
*
peb_buf1
;
void
*
peb_buf2
;
struct
mutex
buf_mutex
;
#ifdef CONFIG_MTD_UBI_DEBUG
void
*
dbg_peb_buf
;
struct
mutex
dbg_buf_mutex
;
#endif
};
extern
struct
file_operations
ubi_cdev_operations
;
...
...
@@ -409,18 +425,18 @@ void ubi_wl_close(struct ubi_device *ubi);
/* io.c */
int
ubi_io_read
(
const
struct
ubi_device
*
ubi
,
void
*
buf
,
int
pnum
,
int
offset
,
int
len
);
int
ubi_io_write
(
const
struct
ubi_device
*
ubi
,
const
void
*
buf
,
int
pnum
,
int
offset
,
int
len
);
int
ubi_io_sync_erase
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
torture
);
int
ubi_io_write
(
struct
ubi_device
*
ubi
,
const
void
*
buf
,
int
pnum
,
int
offset
,
int
len
);
int
ubi_io_sync_erase
(
struct
ubi_device
*
ubi
,
int
pnum
,
int
torture
);
int
ubi_io_is_bad
(
const
struct
ubi_device
*
ubi
,
int
pnum
);
int
ubi_io_mark_bad
(
const
struct
ubi_device
*
ubi
,
int
pnum
);
int
ubi_io_read_ec_hdr
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
ubi_io_read_ec_hdr
(
struct
ubi_device
*
ubi
,
int
pnum
,
struct
ubi_ec_hdr
*
ec_hdr
,
int
verbose
);
int
ubi_io_write_ec_hdr
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
ubi_io_write_ec_hdr
(
struct
ubi_device
*
ubi
,
int
pnum
,
struct
ubi_ec_hdr
*
ec_hdr
);
int
ubi_io_read_vid_hdr
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
ubi_io_read_vid_hdr
(
struct
ubi_device
*
ubi
,
int
pnum
,
struct
ubi_vid_hdr
*
vid_hdr
,
int
verbose
);
int
ubi_io_write_vid_hdr
(
const
struct
ubi_device
*
ubi
,
int
pnum
,
int
ubi_io_write_vid_hdr
(
struct
ubi_device
*
ubi
,
int
pnum
,
struct
ubi_vid_hdr
*
vid_hdr
);
/*
...
...
@@ -439,16 +455,18 @@ int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum,
/**
* ubi_zalloc_vid_hdr - allocate a volume identifier header object.
* @ubi: UBI device description object
* @gfp_flags: GFP flags to allocate with
*
* This function returns a pointer to the newly allocated and zero-filled
* volume identifier header object in case of success and %NULL in case of
* failure.
*/
static
inline
struct
ubi_vid_hdr
*
ubi_zalloc_vid_hdr
(
const
struct
ubi_device
*
ubi
)
static
inline
struct
ubi_vid_hdr
*
ubi_zalloc_vid_hdr
(
const
struct
ubi_device
*
ubi
,
gfp_t
gfp_flags
)
{
void
*
vid_hdr
;
vid_hdr
=
kzalloc
(
ubi
->
vid_hdr_alsize
,
GFP_KERNEL
);
vid_hdr
=
kzalloc
(
ubi
->
vid_hdr_alsize
,
gfp_flags
);
if
(
!
vid_hdr
)
return
NULL
;
...
...
@@ -492,7 +510,7 @@ static inline int ubi_io_read_data(const struct ubi_device *ubi, void *buf,
* the beginning of the logical eraseblock, not to the beginning of the
* physical eraseblock.
*/
static
inline
int
ubi_io_write_data
(
const
struct
ubi_device
*
ubi
,
const
void
*
buf
,
static
inline
int
ubi_io_write_data
(
struct
ubi_device
*
ubi
,
const
void
*
buf
,
int
pnum
,
int
offset
,
int
len
)
{
ubi_assert
(
offset
>=
0
);
...
...
drivers/mtd/ubi/vmt.c
View file @
e3d18658
...
...
@@ -37,21 +37,21 @@ static ssize_t vol_attribute_show(struct device *dev,
struct
device_attribute
*
attr
,
char
*
buf
);
/* Device attributes corresponding to files in '/<sysfs>/class/ubi/ubiX_Y' */
static
struct
device_attribute
vol_reserved_ebs
=
static
struct
device_attribute
attr_
vol_reserved_ebs
=
__ATTR
(
reserved_ebs
,
S_IRUGO
,
vol_attribute_show
,
NULL
);
static
struct
device_attribute
vol_type
=
static
struct
device_attribute
attr_
vol_type
=
__ATTR
(
type
,
S_IRUGO
,
vol_attribute_show
,
NULL
);
static
struct
device_attribute
vol_name
=
static
struct
device_attribute
attr_
vol_name
=
__ATTR
(
name
,
S_IRUGO
,
vol_attribute_show
,
NULL
);
static
struct
device_attribute
vol_corrupted
=
static
struct
device_attribute
attr_
vol_corrupted
=
__ATTR
(
corrupted
,
S_IRUGO
,
vol_attribute_show
,
NULL
);
static
struct
device_attribute
vol_alignment
=
static
struct
device_attribute
attr_
vol_alignment
=
__ATTR
(
alignment
,
S_IRUGO
,
vol_attribute_show
,
NULL
);
static
struct
device_attribute
vol_usable_eb_size
=
static
struct
device_attribute
attr_
vol_usable_eb_size
=
__ATTR
(
usable_eb_size
,
S_IRUGO
,
vol_attribute_show
,
NULL
);
static
struct
device_attribute
vol_data_bytes
=
static
struct
device_attribute
attr_
vol_data_bytes
=
__ATTR
(
data_bytes
,
S_IRUGO
,
vol_attribute_show
,
NULL
);
static
struct
device_attribute
vol_upd_marker
=
static
struct
device_attribute
attr_
vol_upd_marker
=
__ATTR
(
upd_marker
,
S_IRUGO
,
vol_attribute_show
,
NULL
);
/*
...
...
@@ -78,23 +78,27 @@ static ssize_t vol_attribute_show(struct device *dev,
spin_unlock
(
&
vol
->
ubi
->
volumes_lock
);
return
-
ENODEV
;
}
if
(
attr
==
&
vol_reserved_ebs
)
if
(
attr
==
&
attr_
vol_reserved_ebs
)
ret
=
sprintf
(
buf
,
"%d
\n
"
,
vol
->
reserved_pebs
);
else
if
(
attr
==
&
vol_type
)
{
else
if
(
attr
==
&
attr_
vol_type
)
{
const
char
*
tp
;
tp
=
vol
->
vol_type
==
UBI_DYNAMIC_VOLUME
?
"dynamic"
:
"static"
;
if
(
vol
->
vol_type
==
UBI_DYNAMIC_VOLUME
)
tp
=
"dynamic"
;
else
tp
=
"static"
;
ret
=
sprintf
(
buf
,
"%s
\n
"
,
tp
);
}
else
if
(
attr
==
&
vol_name
)
}
else
if
(
attr
==
&
attr_
vol_name
)
ret
=
sprintf
(
buf
,
"%s
\n
"
,
vol
->
name
);
else
if
(
attr
==
&
vol_corrupted
)
else
if
(
attr
==
&
attr_
vol_corrupted
)
ret
=
sprintf
(
buf
,
"%d
\n
"
,
vol
->
corrupted
);
else
if
(
attr
==
&
vol_alignment
)
else
if
(
attr
==
&
attr_
vol_alignment
)
ret
=
sprintf
(
buf
,
"%d
\n
"
,
vol
->
alignment
);
else
if
(
attr
==
&
vol_usable_eb_size
)
{
else
if
(
attr
==
&
attr_
vol_usable_eb_size
)
{
ret
=
sprintf
(
buf
,
"%d
\n
"
,
vol
->
usable_leb_size
);
}
else
if
(
attr
==
&
vol_data_bytes
)
}
else
if
(
attr
==
&
attr_
vol_data_bytes
)
ret
=
sprintf
(
buf
,
"%lld
\n
"
,
vol
->
used_bytes
);
else
if
(
attr
==
&
vol_upd_marker
)
else
if
(
attr
==
&
attr_
vol_upd_marker
)
ret
=
sprintf
(
buf
,
"%d
\n
"
,
vol
->
upd_marker
);
else
BUG
();
...
...
@@ -126,28 +130,28 @@ static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol)
{
int
err
;
err
=
device_create_file
(
&
vol
->
dev
,
&
vol_reserved_ebs
);
err
=
device_create_file
(
&
vol
->
dev
,
&
attr_
vol_reserved_ebs
);
if
(
err
)
return
err
;
err
=
device_create_file
(
&
vol
->
dev
,
&
vol_type
);
err
=
device_create_file
(
&
vol
->
dev
,
&
attr_
vol_type
);
if
(
err
)
return
err
;
err
=
device_create_file
(
&
vol
->
dev
,
&
vol_name
);
err
=
device_create_file
(
&
vol
->
dev
,
&
attr_
vol_name
);
if
(
err
)
return
err
;
err
=
device_create_file
(
&
vol
->
dev
,
&
vol_corrupted
);
err
=
device_create_file
(
&
vol
->
dev
,
&
attr_
vol_corrupted
);
if
(
err
)
return
err
;
err
=
device_create_file
(
&
vol
->
dev
,
&
vol_alignment
);
err
=
device_create_file
(
&
vol
->
dev
,
&
attr_
vol_alignment
);
if
(
err
)
return
err
;
err
=
device_create_file
(
&
vol
->
dev
,
&
vol_usable_eb_size
);
err
=
device_create_file
(
&
vol
->
dev
,
&
attr_
vol_usable_eb_size
);
if
(
err
)
return
err
;
err
=
device_create_file
(
&
vol
->
dev
,
&
vol_data_bytes
);
err
=
device_create_file
(
&
vol
->
dev
,
&
attr_
vol_data_bytes
);
if
(
err
)
return
err
;
err
=
device_create_file
(
&
vol
->
dev
,
&
vol_upd_marker
);
err
=
device_create_file
(
&
vol
->
dev
,
&
attr_
vol_upd_marker
);
if
(
err
)
return
err
;
return
0
;
...
...
@@ -159,14 +163,14 @@ static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol)
*/
static
void
volume_sysfs_close
(
struct
ubi_volume
*
vol
)
{
device_remove_file
(
&
vol
->
dev
,
&
vol_upd_marker
);
device_remove_file
(
&
vol
->
dev
,
&
vol_data_bytes
);
device_remove_file
(
&
vol
->
dev
,
&
vol_usable_eb_size
);
device_remove_file
(
&
vol
->
dev
,
&
vol_alignment
);
device_remove_file
(
&
vol
->
dev
,
&
vol_corrupted
);
device_remove_file
(
&
vol
->
dev
,
&
vol_name
);
device_remove_file
(
&
vol
->
dev
,
&
vol_type
);
device_remove_file
(
&
vol
->
dev
,
&
vol_reserved_ebs
);
device_remove_file
(
&
vol
->
dev
,
&
attr_
vol_upd_marker
);
device_remove_file
(
&
vol
->
dev
,
&
attr_
vol_data_bytes
);
device_remove_file
(
&
vol
->
dev
,
&
attr_
vol_usable_eb_size
);
device_remove_file
(
&
vol
->
dev
,
&
attr_
vol_alignment
);
device_remove_file
(
&
vol
->
dev
,
&
attr_
vol_corrupted
);
device_remove_file
(
&
vol
->
dev
,
&
attr_
vol_name
);
device_remove_file
(
&
vol
->
dev
,
&
attr_
vol_type
);
device_remove_file
(
&
vol
->
dev
,
&
attr_
vol_reserved_ebs
);
device_unregister
(
&
vol
->
dev
);
}
...
...
drivers/mtd/ubi/vtbl.c
View file @
e3d18658
...
...
@@ -254,7 +254,7 @@ bad:
* This function returns zero in case of success and a negative error code in
* case of failure.
*/
static
int
create_vtbl
(
const
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
,
static
int
create_vtbl
(
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
,
int
copy
,
void
*
vtbl
)
{
int
err
,
tries
=
0
;
...
...
@@ -264,7 +264,7 @@ static int create_vtbl(const struct ubi_device *ubi, struct ubi_scan_info *si,
ubi_msg
(
"create volume table (copy #%d)"
,
copy
+
1
);
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
);
vid_hdr
=
ubi_zalloc_vid_hdr
(
ubi
,
GFP_KERNEL
);
if
(
!
vid_hdr
)
return
-
ENOMEM
;
...
...
@@ -339,7 +339,7 @@ out_free:
* not corrupted, and recovering from corruptions if needed. Returns volume
* table in case of success and a negative error code in case of failure.
*/
static
struct
ubi_vtbl_record
*
process_lvol
(
const
struct
ubi_device
*
ubi
,
static
struct
ubi_vtbl_record
*
process_lvol
(
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
,
struct
ubi_scan_volume
*
sv
)
{
...
...
@@ -453,7 +453,7 @@ out_free:
* This function returns volume table contents in case of success and a
* negative error code in case of failure.
*/
static
struct
ubi_vtbl_record
*
create_empty_lvol
(
const
struct
ubi_device
*
ubi
,
static
struct
ubi_vtbl_record
*
create_empty_lvol
(
struct
ubi_device
*
ubi
,
struct
ubi_scan_info
*
si
)
{
int
i
;
...
...
drivers/mtd/ubi/wl.c
View file @
e3d18658
This diff is collapsed.
Click to expand it.
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