public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* cfi_cmdset_0001 unaligned write problems.
@ 2000-10-19 14:05 David Woodhouse
  2000-10-19 14:30 ` Nicolas Pitre
  0 siblings, 1 reply; 5+ messages in thread
From: David Woodhouse @ 2000-10-19 14:05 UTC (permalink / raw)
  To: nico; +Cc: mtd

Either this code is suspect or I need more caffeine. Probably both.
Scenario: Buswidth is 2. CPU is big-endian. Writing '5a' to an odd address.

	/* If it's not bus-aligned, do the first byte write */
	if (ofs & (CFIDEV_BUSWIDTH-1)) {
		unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
		int i = 0, n = 0;
		u_char tmp_buf[4];
		__u32 datum;

		while (bus_ofs++ < ofs)
			tmp_buf[i++] = 0xff;
		while (len && i < CFIDEV_BUSWIDTH)
			tmp_buf[i++] = buf[n++], len--;
		while (i < CFIDEV_BUSWIDTH)
			tmp_buf[i++] = 0xff;

// now tmp_buf is 0xff,0x5a,xx,yy

		if (cfi_buswidth_is_2()) {
			datum = *(__u16*)tmp_buf;

// now datum is 0xff5a (stored as 0,0,ff,5a)

		} else if (cfi_buswidth_is_4()) {
			datum = *(__u32*)tmp_buf;
		} else {
			return -EINVAL;  /* should never happen, but be safe */
		}

		ret = do_write_oneword(map, &cfi->chips[chipnum],
					       ofs, datum);
// do_write_oneword writes 2 bytes at &datum, which is 0,0.
// What's more, it writes it to 'ofs' (and faults on the unaligned access)
//  instead of to buf_ofs, which was presumably the intention.

		if (ret) 
			return ret;
		
		ofs += n;
		buf += n;
		(*retlen) += n;

		if (ofs >> cfi->chipshift) {
			chipnum ++; 
			ofs = 0;
			if (chipnum == cfi->numchips)
				return 0;
		}
	}




--
dwmw2




To unsubscribe, send "unsubscribe mtd" to majordomo@infradead.org

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cfi_cmdset_0001 unaligned write problems.
  2000-10-19 14:05 cfi_cmdset_0001 unaligned write problems David Woodhouse
@ 2000-10-19 14:30 ` Nicolas Pitre
  2000-10-19 14:43   ` David Woodhouse
  2000-10-19 15:26   ` David Given
  0 siblings, 2 replies; 5+ messages in thread
From: Nicolas Pitre @ 2000-10-19 14:30 UTC (permalink / raw)
  To: David Woodhouse; +Cc: mtd



On Thu, 19 Oct 2000, David Woodhouse wrote:

> Either this code is suspect or I need more caffeine. Probably both.
> Scenario: Buswidth is 2. CPU is big-endian. Writing '5a' to an odd address.
> 
> 	/* If it's not bus-aligned, do the first byte write */
> 	if (ofs & (CFIDEV_BUSWIDTH-1)) {
> 		unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
> 		int i = 0, n = 0;
> 		u_char tmp_buf[4];
> 		__u32 datum;
> 
> 		while (bus_ofs++ < ofs)
> 			tmp_buf[i++] = 0xff;
> 		while (len && i < CFIDEV_BUSWIDTH)
> 			tmp_buf[i++] = buf[n++], len--;
> 		while (i < CFIDEV_BUSWIDTH)
> 			tmp_buf[i++] = 0xff;
> 
> // now tmp_buf is 0xff,0x5a,xx,yy
> 
> 		if (cfi_buswidth_is_2()) {
> 			datum = *(__u16*)tmp_buf;
> 
> // now datum is 0xff5a (stored as 0,0,ff,5a)
> 
> 		} else if (cfi_buswidth_is_4()) {
> 			datum = *(__u32*)tmp_buf;
> 		} else {
> 			return -EINVAL;  /* should never happen, but be safe */
> 		}
> 
> 		ret = do_write_oneword(map, &cfi->chips[chipnum],
> 					       ofs, datum);
> // do_write_oneword writes 2 bytes at &datum, which is 0,0.
> // What's more, it writes it to 'ofs' (and faults on the unaligned access)
> //  instead of to buf_ofs, which was presumably the intention.

Yeah...  I just fixed that one...  Wonder why it worked for me till now...

However I suspect that there might be an issue with __u16 promoted to
__u32 then back to __u16 on big endian CPUs.  What is the expected
behavior?

On LE, 0x1234 becomes 0x00001234 the back to 0x1234 which is fine...


Nicolas



To unsubscribe, send "unsubscribe mtd" to majordomo@infradead.org

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cfi_cmdset_0001 unaligned write problems.
  2000-10-19 14:30 ` Nicolas Pitre
@ 2000-10-19 14:43   ` David Woodhouse
  2000-10-19 15:26   ` David Given
  1 sibling, 0 replies; 5+ messages in thread
From: David Woodhouse @ 2000-10-19 14:43 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: mtd


Quick response :)

nico@cam.org said:
>  Yeah...  I just fixed that one...  Wonder why it worked for me till
> now...

If you're testing with JFFS you won't have exercised that code. 

> However I suspect that there might be an issue with __u16 promoted to
> __u32 then back to __u16 on big endian CPUs.  What is the expected
> behavior?

> On LE, 0x1234 becomes 0x00001234 the back to 0x1234 which is fine... 

On BE, I think it'll match the comments I put in.
 (writing 0x5a to an odd address)
tmp_buf holds {0xff, 0x5a, xx, yy}
*(__u16)tmp_buf is 0xff5a
datum is 0x0000ff5a, which is stored as 0x00,0x00,0xff,0x5a
do_write_oneword uses the two bytes at &datum, which are 0x00 and 0x00.

I have no BE machine to test on ATM, though.

I was also seeing problems with JFFS - whatever I was writing to the flash 
wasn't 'taking'. Immediately reading files back would give corrupted data, 
and the filesystem was entirely untouched on rebooting - it didn't even 
complain of invalid nodes.

I very much doubt that was the same problem - I'm running on SH3 where the
unaligned trap would kill it first time. The unaligned problems showed up
when I was using 'cat' to write to the flash, to check it was working.

I've reverted to v1.25 for now. 


--
dwmw2




To unsubscribe, send "unsubscribe mtd" to majordomo@infradead.org

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cfi_cmdset_0001 unaligned write problems.
  2000-10-19 14:30 ` Nicolas Pitre
  2000-10-19 14:43   ` David Woodhouse
@ 2000-10-19 15:26   ` David Given
  2000-10-19 15:39     ` David Woodhouse
  1 sibling, 1 reply; 5+ messages in thread
From: David Given @ 2000-10-19 15:26 UTC (permalink / raw)
  To: mtd

[...]
>However I suspect that there might be an issue with __u16 promoted to
>__u32 then back to __u16 on big endian CPUs.  What is the expected
>behavior?
>
>On LE, 0x1234 becomes 0x00001234 the back to 0x1234 which is fine...

Ditto on BE. Endianness only matters when you are reading and writing non-quad 
values to memory. The internal representations are identical.


-- 
David Given
dg@tao-group.com




To unsubscribe, send "unsubscribe mtd" to majordomo@infradead.org

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cfi_cmdset_0001 unaligned write problems.
  2000-10-19 15:26   ` David Given
@ 2000-10-19 15:39     ` David Woodhouse
  0 siblings, 0 replies; 5+ messages in thread
From: David Woodhouse @ 2000-10-19 15:39 UTC (permalink / raw)
  To: David Given; +Cc: mtd, nico


dg@tao-group.com said:
>  Ditto on BE. Endianness only matters when you are reading and writing
> non-quad  values to memory. The internal representations are
> identical.

Yep, I was misunderstanding what do_write_oneword() does. In fact, it 
passes datum intact to cfi_write() which does the correct thing, rather 
than passing it by reference. That code does look OK.


--
dwmw2




To unsubscribe, send "unsubscribe mtd" to majordomo@infradead.org

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2000-10-19 15:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2000-10-19 14:05 cfi_cmdset_0001 unaligned write problems David Woodhouse
2000-10-19 14:30 ` Nicolas Pitre
2000-10-19 14:43   ` David Woodhouse
2000-10-19 15:26   ` David Given
2000-10-19 15:39     ` David Woodhouse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox