diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-11-06 18:43:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-11-06 18:43:13 -0500 |
commit | c36194871293100bd4b2ecb54ac9774d6e627aa2 (patch) | |
tree | 9fd6894103918f439d0e7ec35620e18018ccfa76 | |
parent | c3302931db090d87e9015c3a7ce5c97a7dd90f78 (diff) | |
parent | dc8a0843a435b2c0891e7eaea64faaf1ebec9b11 (diff) |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6:
[JFFS2] fix race condition in jffs2_lzo_compress()
[MTD] [NOR] Fix cfi_send_gen_cmd handling of x16 devices in x8 mode (v4)
[JFFS2] Fix lack of locking in thread_should_wake()
[JFFS2] Fix build failure with !CONFIG_JFFS2_FS_WRITEBUFFER
[MTD] [NAND] OMAP2: remove duplicated #include
-rw-r--r-- | drivers/mtd/chips/cfi_cmdset_0002.c | 13 | ||||
-rw-r--r-- | drivers/mtd/chips/jedec_probe.c | 10 | ||||
-rw-r--r-- | fs/jffs2/background.c | 10 | ||||
-rw-r--r-- | fs/jffs2/compr_lzo.c | 15 | ||||
-rw-r--r-- | fs/jffs2/nodemgmt.c | 2 | ||||
-rw-r--r-- | include/linux/mtd/cfi.h | 22 |
6 files changed, 39 insertions, 33 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 3e6f5d8609e8..d74ec46aa032 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
@@ -406,19 +406,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
406 | /* Set the default CFI lock/unlock addresses */ | 406 | /* Set the default CFI lock/unlock addresses */ |
407 | cfi->addr_unlock1 = 0x555; | 407 | cfi->addr_unlock1 = 0x555; |
408 | cfi->addr_unlock2 = 0x2aa; | 408 | cfi->addr_unlock2 = 0x2aa; |
409 | /* Modify the unlock address if we are in compatibility mode */ | ||
410 | if ( /* x16 in x8 mode */ | ||
411 | ((cfi->device_type == CFI_DEVICETYPE_X8) && | ||
412 | (cfi->cfiq->InterfaceDesc == | ||
413 | CFI_INTERFACE_X8_BY_X16_ASYNC)) || | ||
414 | /* x32 in x16 mode */ | ||
415 | ((cfi->device_type == CFI_DEVICETYPE_X16) && | ||
416 | (cfi->cfiq->InterfaceDesc == | ||
417 | CFI_INTERFACE_X16_BY_X32_ASYNC))) | ||
418 | { | ||
419 | cfi->addr_unlock1 = 0xaaa; | ||
420 | cfi->addr_unlock2 = 0x555; | ||
421 | } | ||
422 | 409 | ||
423 | } /* CFI mode */ | 410 | } /* CFI mode */ |
424 | else if (cfi->cfi_mode == CFI_MODE_JEDEC) { | 411 | else if (cfi->cfi_mode == CFI_MODE_JEDEC) { |
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index f84ab6182148..2f3f2f719ba4 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c | |||
@@ -1808,9 +1808,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base, | |||
1808 | * several first banks can contain 0x7f instead of actual ID | 1808 | * several first banks can contain 0x7f instead of actual ID |
1809 | */ | 1809 | */ |
1810 | do { | 1810 | do { |
1811 | uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), | 1811 | uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi); |
1812 | cfi_interleave(cfi), | ||
1813 | cfi->device_type); | ||
1814 | mask = (1 << (cfi->device_type * 8)) - 1; | 1812 | mask = (1 << (cfi->device_type * 8)) - 1; |
1815 | result = map_read(map, base + ofs); | 1813 | result = map_read(map, base + ofs); |
1816 | bank++; | 1814 | bank++; |
@@ -1824,7 +1822,7 @@ static inline u32 jedec_read_id(struct map_info *map, uint32_t base, | |||
1824 | { | 1822 | { |
1825 | map_word result; | 1823 | map_word result; |
1826 | unsigned long mask; | 1824 | unsigned long mask; |
1827 | u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type); | 1825 | u32 ofs = cfi_build_cmd_addr(1, map, cfi); |
1828 | mask = (1 << (cfi->device_type * 8)) -1; | 1826 | mask = (1 << (cfi->device_type * 8)) -1; |
1829 | result = map_read(map, base + ofs); | 1827 | result = map_read(map, base + ofs); |
1830 | return result.x[0] & mask; | 1828 | return result.x[0] & mask; |
@@ -2067,8 +2065,8 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, | |||
2067 | 2065 | ||
2068 | } | 2066 | } |
2069 | /* Ensure the unlock addresses we try stay inside the map */ | 2067 | /* Ensure the unlock addresses we try stay inside the map */ |
2070 | probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, cfi_interleave(cfi), cfi->device_type); | 2068 | probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, map, cfi); |
2071 | probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, cfi_interleave(cfi), cfi->device_type); | 2069 | probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, map, cfi); |
2072 | if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || | 2070 | if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || |
2073 | ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) | 2071 | ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) |
2074 | goto retry; | 2072 | goto retry; |
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c index 8adebd3e43c6..3cceef4ad2b7 100644 --- a/fs/jffs2/background.c +++ b/fs/jffs2/background.c | |||
@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread(void *_c) | |||
85 | for (;;) { | 85 | for (;;) { |
86 | allow_signal(SIGHUP); | 86 | allow_signal(SIGHUP); |
87 | again: | 87 | again: |
88 | spin_lock(&c->erase_completion_lock); | ||
88 | if (!jffs2_thread_should_wake(c)) { | 89 | if (!jffs2_thread_should_wake(c)) { |
89 | set_current_state (TASK_INTERRUPTIBLE); | 90 | set_current_state (TASK_INTERRUPTIBLE); |
91 | spin_unlock(&c->erase_completion_lock); | ||
90 | D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n")); | 92 | D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n")); |
91 | /* Yes, there's a race here; we checked jffs2_thread_should_wake() | ||
92 | before setting current->state to TASK_INTERRUPTIBLE. But it doesn't | ||
93 | matter - We don't care if we miss a wakeup, because the GC thread | ||
94 | is only an optimisation anyway. */ | ||
95 | schedule(); | 93 | schedule(); |
96 | } | 94 | } else |
95 | spin_unlock(&c->erase_completion_lock); | ||
96 | |||
97 | 97 | ||
98 | /* This thread is purely an optimisation. But if it runs when | 98 | /* This thread is purely an optimisation. But if it runs when |
99 | other things could be running, it actually makes things a | 99 | other things could be running, it actually makes things a |
diff --git a/fs/jffs2/compr_lzo.c b/fs/jffs2/compr_lzo.c index 47b045797e42..90cb60d09787 100644 --- a/fs/jffs2/compr_lzo.c +++ b/fs/jffs2/compr_lzo.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | static void *lzo_mem; | 20 | static void *lzo_mem; |
21 | static void *lzo_compress_buf; | 21 | static void *lzo_compress_buf; |
22 | static DEFINE_MUTEX(deflate_mutex); | 22 | static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */ |
23 | 23 | ||
24 | static void free_workspace(void) | 24 | static void free_workspace(void) |
25 | { | 25 | { |
@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out, | |||
49 | 49 | ||
50 | mutex_lock(&deflate_mutex); | 50 | mutex_lock(&deflate_mutex); |
51 | ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); | 51 | ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); |
52 | mutex_unlock(&deflate_mutex); | ||
53 | |||
54 | if (ret != LZO_E_OK) | 52 | if (ret != LZO_E_OK) |
55 | return -1; | 53 | goto fail; |
56 | 54 | ||
57 | if (compress_size > *dstlen) | 55 | if (compress_size > *dstlen) |
58 | return -1; | 56 | goto fail; |
59 | 57 | ||
60 | memcpy(cpage_out, lzo_compress_buf, compress_size); | 58 | memcpy(cpage_out, lzo_compress_buf, compress_size); |
61 | *dstlen = compress_size; | 59 | mutex_unlock(&deflate_mutex); |
62 | 60 | ||
61 | *dstlen = compress_size; | ||
63 | return 0; | 62 | return 0; |
63 | |||
64 | fail: | ||
65 | mutex_unlock(&deflate_mutex); | ||
66 | return -1; | ||
64 | } | 67 | } |
65 | 68 | ||
66 | static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out, | 69 | static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out, |
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c index 0875b60b4bf7..21a052915aa9 100644 --- a/fs/jffs2/nodemgmt.c +++ b/fs/jffs2/nodemgmt.c | |||
@@ -261,9 +261,11 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c) | |||
261 | 261 | ||
262 | jffs2_sum_reset_collected(c->summary); /* reset collected summary */ | 262 | jffs2_sum_reset_collected(c->summary); /* reset collected summary */ |
263 | 263 | ||
264 | #ifdef CONFIG_JFFS2_FS_WRITEBUFFER | ||
264 | /* adjust write buffer offset, else we get a non contiguous write bug */ | 265 | /* adjust write buffer offset, else we get a non contiguous write bug */ |
265 | if (!(c->wbuf_ofs % c->sector_size) && !c->wbuf_len) | 266 | if (!(c->wbuf_ofs % c->sector_size) && !c->wbuf_len) |
266 | c->wbuf_ofs = 0xffffffff; | 267 | c->wbuf_ofs = 0xffffffff; |
268 | #endif | ||
267 | 269 | ||
268 | D1(printk(KERN_DEBUG "jffs2_find_nextblock(): new nextblock = 0x%08x\n", c->nextblock->offset)); | 270 | D1(printk(KERN_DEBUG "jffs2_find_nextblock(): new nextblock = 0x%08x\n", c->nextblock->offset)); |
269 | 271 | ||
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index ee5124ec319e..00e2b575021f 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h | |||
@@ -282,9 +282,25 @@ struct cfi_private { | |||
282 | /* | 282 | /* |
283 | * Returns the command address according to the given geometry. | 283 | * Returns the command address according to the given geometry. |
284 | */ | 284 | */ |
285 | static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int type) | 285 | static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, |
286 | struct map_info *map, struct cfi_private *cfi) | ||
286 | { | 287 | { |
287 | return (cmd_ofs * type) * interleave; | 288 | unsigned bankwidth = map_bankwidth(map); |
289 | unsigned interleave = cfi_interleave(cfi); | ||
290 | unsigned type = cfi->device_type; | ||
291 | uint32_t addr; | ||
292 | |||
293 | addr = (cmd_ofs * type) * interleave; | ||
294 | |||
295 | /* Modify the unlock address if we are in compatiblity mode. | ||
296 | * For 16bit devices on 8 bit busses | ||
297 | * and 32bit devices on 16 bit busses | ||
298 | * set the low bit of the alternating bit sequence of the address. | ||
299 | */ | ||
300 | if (((type * interleave) > bankwidth) && ((uint8_t)cmd_ofs == 0xaa)) | ||
301 | addr |= (type >> 1)*interleave; | ||
302 | |||
303 | return addr; | ||
288 | } | 304 | } |
289 | 305 | ||
290 | /* | 306 | /* |
@@ -430,7 +446,7 @@ static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t | |||
430 | int type, map_word *prev_val) | 446 | int type, map_word *prev_val) |
431 | { | 447 | { |
432 | map_word val; | 448 | map_word val; |
433 | uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type); | 449 | uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, map, cfi); |
434 | val = cfi_build_cmd(cmd, map, cfi); | 450 | val = cfi_build_cmd(cmd, map, cfi); |
435 | 451 | ||
436 | if (prev_val) | 452 | if (prev_val) |