Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xcap
xcap-capability-linux
Commits
e3d18658
Commit
e3d18658
authored
Oct 14, 2007
by
David Woodhouse
Browse files
Merge branch 'master' of
git://git.infradead.org/~dedekind/ubi-2.6
parents
a2e1b833
cc5f4f28
Changes
12
Hide whitespace changes
Inline
Side-by-side
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
_buf
1
+
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_
buf
1
,
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_
buf
1
,
data_size
);
cond_resched
();
crc
=
crc32
(
UBI_CRC32_INIT
,
buf
,
data_size
);
crc
=
crc32
(
UBI_CRC32_INIT
,
ubi
->
peb_
buf
1
,
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_
buf
1
,
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
,
buf
1
,
to
,
0
,
aldata_size
);
err
=
ubi_io_read_data
(
ubi
,
ubi
->
peb_
buf
2
,
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
,
buf
1
,
aldata_size
))
{
if
(
memcmp
(
ubi
->
peb_
buf
1
,
ubi
->
peb_
buf
2
,
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_
buf
1
,
pnum
,
0
,
ubi
->
peb_size
);
if
(
err
)
goto
out
;
err
=
check_pattern
(
buf
,
0xFF
,
ubi
->
peb_size
);
err
=
check_pattern
(
ubi
->
peb_
buf
1
,
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_
buf
1
,
patterns
[
i
],
ubi
->
peb_size
);
err
=
ubi_io_write
(
ubi
,
ubi
->
peb_
buf
1
,
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_
buf
1
,
~
patterns
[
i
],
ubi
->
peb_size
);
err
=
ubi_io_read
(
ubi
,
ubi
->
peb_
buf
1
,
pnum
,
0
,
ubi
->
peb_size
);
if
(
err
)
goto
out
;
err
=
check_pattern
(
buf
,
patterns
[
i
],
ubi
->
peb_size
);
err
=
check_pattern
(
ubi
->
peb_
buf
1
,
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
;