Commit c3619487 authored by Linus Torvalds's avatar Linus Torvalds

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
parents c3302931 dc8a0843
...@@ -406,19 +406,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) ...@@ -406,19 +406,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
/* Set the default CFI lock/unlock addresses */ /* Set the default CFI lock/unlock addresses */
cfi->addr_unlock1 = 0x555; cfi->addr_unlock1 = 0x555;
cfi->addr_unlock2 = 0x2aa; cfi->addr_unlock2 = 0x2aa;
/* Modify the unlock address if we are in compatibility mode */
if ( /* x16 in x8 mode */
((cfi->device_type == CFI_DEVICETYPE_X8) &&
(cfi->cfiq->InterfaceDesc ==
CFI_INTERFACE_X8_BY_X16_ASYNC)) ||
/* x32 in x16 mode */
((cfi->device_type == CFI_DEVICETYPE_X16) &&
(cfi->cfiq->InterfaceDesc ==
CFI_INTERFACE_X16_BY_X32_ASYNC)))
{
cfi->addr_unlock1 = 0xaaa;
cfi->addr_unlock2 = 0x555;
}
} /* CFI mode */ } /* CFI mode */
else if (cfi->cfi_mode == CFI_MODE_JEDEC) { else if (cfi->cfi_mode == CFI_MODE_JEDEC) {
......
...@@ -1808,9 +1808,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base, ...@@ -1808,9 +1808,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base,
* several first banks can contain 0x7f instead of actual ID * several first banks can contain 0x7f instead of actual ID
*/ */
do { do {
uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi);
cfi_interleave(cfi),
cfi->device_type);
mask = (1 << (cfi->device_type * 8)) - 1; mask = (1 << (cfi->device_type * 8)) - 1;
result = map_read(map, base + ofs); result = map_read(map, base + ofs);
bank++; bank++;
...@@ -1824,7 +1822,7 @@ static inline u32 jedec_read_id(struct map_info *map, uint32_t base, ...@@ -1824,7 +1822,7 @@ static inline u32 jedec_read_id(struct map_info *map, uint32_t base,
{ {
map_word result; map_word result;
unsigned long mask; unsigned long mask;
u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type); u32 ofs = cfi_build_cmd_addr(1, map, cfi);
mask = (1 << (cfi->device_type * 8)) -1; mask = (1 << (cfi->device_type * 8)) -1;
result = map_read(map, base + ofs); result = map_read(map, base + ofs);
return result.x[0] & mask; return result.x[0] & mask;
...@@ -2067,8 +2065,8 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, ...@@ -2067,8 +2065,8 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
} }
/* Ensure the unlock addresses we try stay inside the map */ /* Ensure the unlock addresses we try stay inside the map */
probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, cfi_interleave(cfi), cfi->device_type); probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, map, cfi);
probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, cfi_interleave(cfi), cfi->device_type); probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, map, cfi);
if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
((base + probe_offset2 + map_bankwidth(map)) >= map->size)) ((base + probe_offset2 + map_bankwidth(map)) >= map->size))
goto retry; goto retry;
......
...@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread(void *_c) ...@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread(void *_c)
for (;;) { for (;;) {
allow_signal(SIGHUP); allow_signal(SIGHUP);
again: again:
spin_lock(&c->erase_completion_lock);
if (!jffs2_thread_should_wake(c)) { if (!jffs2_thread_should_wake(c)) {
set_current_state (TASK_INTERRUPTIBLE); set_current_state (TASK_INTERRUPTIBLE);
spin_unlock(&c->erase_completion_lock);
D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n")); D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
/* Yes, there's a race here; we checked jffs2_thread_should_wake()
before setting current->state to TASK_INTERRUPTIBLE. But it doesn't
matter - We don't care if we miss a wakeup, because the GC thread
is only an optimisation anyway. */
schedule(); schedule();
} } else
spin_unlock(&c->erase_completion_lock);
/* This thread is purely an optimisation. But if it runs when /* This thread is purely an optimisation. But if it runs when
other things could be running, it actually makes things a other things could be running, it actually makes things a
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
static void *lzo_mem; static void *lzo_mem;
static void *lzo_compress_buf; static void *lzo_compress_buf;
static DEFINE_MUTEX(deflate_mutex); static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */
static void free_workspace(void) static void free_workspace(void)
{ {
...@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out, ...@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out,
mutex_lock(&deflate_mutex); mutex_lock(&deflate_mutex);
ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem);
mutex_unlock(&deflate_mutex);
if (ret != LZO_E_OK) if (ret != LZO_E_OK)
return -1; goto fail;
if (compress_size > *dstlen) if (compress_size > *dstlen)
return -1; goto fail;
memcpy(cpage_out, lzo_compress_buf, compress_size); memcpy(cpage_out, lzo_compress_buf, compress_size);
*dstlen = compress_size; mutex_unlock(&deflate_mutex);
*dstlen = compress_size;
return 0; return 0;
fail:
mutex_unlock(&deflate_mutex);
return -1;
} }
static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out, static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
......
...@@ -261,9 +261,11 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c) ...@@ -261,9 +261,11 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c)
jffs2_sum_reset_collected(c->summary); /* reset collected summary */ jffs2_sum_reset_collected(c->summary); /* reset collected summary */
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
/* adjust write buffer offset, else we get a non contiguous write bug */ /* adjust write buffer offset, else we get a non contiguous write bug */
if (!(c->wbuf_ofs % c->sector_size) && !c->wbuf_len) if (!(c->wbuf_ofs % c->sector_size) && !c->wbuf_len)
c->wbuf_ofs = 0xffffffff; c->wbuf_ofs = 0xffffffff;
#endif
D1(printk(KERN_DEBUG "jffs2_find_nextblock(): new nextblock = 0x%08x\n", c->nextblock->offset)); D1(printk(KERN_DEBUG "jffs2_find_nextblock(): new nextblock = 0x%08x\n", c->nextblock->offset));
......
...@@ -282,9 +282,25 @@ struct cfi_private { ...@@ -282,9 +282,25 @@ struct cfi_private {
/* /*
* Returns the command address according to the given geometry. * Returns the command address according to the given geometry.
*/ */
static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int type) static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs,
struct map_info *map, struct cfi_private *cfi)
{ {
return (cmd_ofs * type) * interleave; unsigned bankwidth = map_bankwidth(map);
unsigned interleave = cfi_interleave(cfi);
unsigned type = cfi->device_type;
uint32_t addr;
addr = (cmd_ofs * type) * interleave;
/* Modify the unlock address if we are in compatiblity mode.
* For 16bit devices on 8 bit busses
* and 32bit devices on 16 bit busses
* set the low bit of the alternating bit sequence of the address.
*/
if (((type * interleave) > bankwidth) && ((uint8_t)cmd_ofs == 0xaa))
addr |= (type >> 1)*interleave;
return addr;
} }
/* /*
...@@ -430,7 +446,7 @@ static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t ...@@ -430,7 +446,7 @@ static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t
int type, map_word *prev_val) int type, map_word *prev_val)
{ {
map_word val; map_word val;
uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type); uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, map, cfi);
val = cfi_build_cmd(cmd, map, cfi); val = cfi_build_cmd(cmd, map, cfi);
if (prev_val) if (prev_val)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment