public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* latest mtd changes broke collie
@ 2005-11-09 22:17 Pavel Machek
  2005-11-10  0:19 ` Josh Boyer
  2005-11-10  2:59 ` Todd Poynor
  0 siblings, 2 replies; 26+ messages in thread
From: Pavel Machek @ 2005-11-09 22:17 UTC (permalink / raw)
  To: rpurdie, lenz, kernel list, Russell King, dwmw2, Andrew Morton


Latest mtd changes break collie...it now oopses during boot. This
reverts the bad patch.

Signed-off-by: Pavel Machek <pavel@suse.cz>

diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
--- a/drivers/mtd/chips/sharp.c
+++ b/drivers/mtd/chips/sharp.c
@@ -4,7 +4,7 @@
  * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
  *           2000,2001 Lineo, Inc.
  *
- * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $
+ * $Id: sharp.c,v 1.14 2004/08/09 13:19:43 dwmw2 Exp $
  *
  * Devices supported:
  *   LH28F016SCT Symmetrical block flash memory, 2Mx8
@@ -32,7 +32,6 @@
 #include <linux/mtd/cfi.h>
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/slab.h>
 
 #define CMD_RESET		0xffffffff
 #define CMD_READ_ID		0x90909090
@@ -234,7 +233,7 @@ static int sharp_probe_map(struct map_in
 /* This function returns with the chip->mutex lock held. */
 static int sharp_wait(struct map_info *map, struct flchip *chip)
 {
-	int status, i;
+	__u32 status;
 	unsigned long timeo = jiffies + HZ;
 	DECLARE_WAITQUEUE(wait, current);
 	int adr = 0;
@@ -247,11 +246,13 @@ retry:
 		map_write32(map, CMD_READ_STATUS, adr);
 		chip->state = FL_STATUS;
 	case FL_STATUS:
-		for(i=0;i<100;i++){
-			status = map_read32(map,adr);
-			if((status & SR_READY)==SR_READY)
-				break;
-			udelay(1);
+		status = map_read32(map,adr);
+		if ((status & SR_READY) == SR_READY)
+			break;
+		spin_unlock_bh(chip->mutex);
+		if (time_after(jiffies, timeo)) {
+			printk("Waiting for chip to be ready timed out in erase\n");
+			return -EIO;
 		}
 		sharp_udelay(1);
 		goto retry;
@@ -491,11 +492,7 @@ static inline int sharp_do_wait_for_read
 		spin_lock_bh(chip->mutex);
 
 		remove_wait_queue(&chip->wq, &wait);
-
-		if (signal_pending(current)){
-			ret = -EINTR;
-			goto out;
-		}
+		set_current_state(TASK_RUNNING);
 	}
 	ret = -ETIME;
 out:



-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-09 22:17 latest mtd changes broke collie Pavel Machek
@ 2005-11-10  0:19 ` Josh Boyer
  2005-11-10  9:48   ` Pavel Machek
  2005-11-10  2:59 ` Todd Poynor
  1 sibling, 1 reply; 26+ messages in thread
From: Josh Boyer @ 2005-11-10  0:19 UTC (permalink / raw)
  To: Pavel Machek
  Cc: rpurdie, lenz, kernel list, Russell King, dwmw2, Andrew Morton

On 11/9/05, Pavel Machek <pavel@ucw.cz> wrote:
>
> Latest mtd changes break collie...it now oopses during boot. This
> reverts the bad patch.
>
> Signed-off-by: Pavel Machek <pavel@suse.cz>
>
<snip>
> -               for(i=0;i<100;i++){
> -                       status = map_read32(map,adr);
> -                       if((status & SR_READY)==SR_READY)
> -                               break;
> -                       udelay(1);
> +               status = map_read32(map,adr);

I was just discussing with someone today how map_read32 no longer
exists in the kernel...  does this even compile for you?

Somehow I think I'm missing something...

josh

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

* Re: latest mtd changes broke collie
  2005-11-09 22:17 latest mtd changes broke collie Pavel Machek
  2005-11-10  0:19 ` Josh Boyer
@ 2005-11-10  2:59 ` Todd Poynor
  2005-11-10  9:50   ` Pavel Machek
  1 sibling, 1 reply; 26+ messages in thread
From: Todd Poynor @ 2005-11-10  2:59 UTC (permalink / raw)
  To: Pavel Machek
  Cc: rpurdie, lenz, kernel list, Russell King, dwmw2, Andrew Morton

Pavel Machek wrote:
> Latest mtd changes break collie...it now oopses during boot. This
> reverts the bad patch.

What tree was this generated against?  It doesn't seem to match recent 
linux-mtd or kernel.org trees.  It looks like the tree used had 
different version of a couple fixes recently added to linux-mtd (removal 
of bogus udelays and 32-bit status datatype).

I'm guessing the important part is to add a missing spin_unlock_bh(), 
which is definitely a bug in the mtd code, but this code is so different 
than linux-mtd CVS that it seems more resyncing is needed.  As it stands 
now, force-fitting this patch would still leave an unbalanced 
spin_lock_bh() without other changes.  And it does look like this driver 
hasn't been converted to modern mtd apis.

> 
> Signed-off-by: Pavel Machek <pavel@suse.cz>
> 
> diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
> --- a/drivers/mtd/chips/sharp.c
> +++ b/drivers/mtd/chips/sharp.c
> @@ -4,7 +4,7 @@
>   * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
>   *           2000,2001 Lineo, Inc.
>   *
> - * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $
> + * $Id: sharp.c,v 1.14 2004/08/09 13:19:43 dwmw2 Exp $
>   *
>   * Devices supported:
>   *   LH28F016SCT Symmetrical block flash memory, 2Mx8
> @@ -32,7 +32,6 @@
>  #include <linux/mtd/cfi.h>
>  #include <linux/delay.h>
>  #include <linux/init.h>
> -#include <linux/slab.h>
>  
>  #define CMD_RESET		0xffffffff
>  #define CMD_READ_ID		0x90909090
> @@ -234,7 +233,7 @@ static int sharp_probe_map(struct map_in
>  /* This function returns with the chip->mutex lock held. */
>  static int sharp_wait(struct map_info *map, struct flchip *chip)
>  {
> -	int status, i;
> +	__u32 status;
>  	unsigned long timeo = jiffies + HZ;
>  	DECLARE_WAITQUEUE(wait, current);
>  	int adr = 0;
> @@ -247,11 +246,13 @@ retry:
>  		map_write32(map, CMD_READ_STATUS, adr);
>  		chip->state = FL_STATUS;
>  	case FL_STATUS:
> -		for(i=0;i<100;i++){
> -			status = map_read32(map,adr);
> -			if((status & SR_READY)==SR_READY)
> -				break;
> -			udelay(1);
> +		status = map_read32(map,adr);
> +		if ((status & SR_READY) == SR_READY)
> +			break;
> +		spin_unlock_bh(chip->mutex);
> +		if (time_after(jiffies, timeo)) {
> +			printk("Waiting for chip to be ready timed out in erase\n");
> +			return -EIO;
>  		}
>  		sharp_udelay(1);
>  		goto retry;
> @@ -491,11 +492,7 @@ static inline int sharp_do_wait_for_read
>  		spin_lock_bh(chip->mutex);
>  
>  		remove_wait_queue(&chip->wq, &wait);
> -
> -		if (signal_pending(current)){
> -			ret = -EINTR;
> -			goto out;
> -		}
> +		set_current_state(TASK_RUNNING);
>  	}
>  	ret = -ETIME;
>  out:
> 
> 
> 


-- 
Todd

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

* Re: latest mtd changes broke collie
  2005-11-10  0:19 ` Josh Boyer
@ 2005-11-10  9:48   ` Pavel Machek
  0 siblings, 0 replies; 26+ messages in thread
From: Pavel Machek @ 2005-11-10  9:48 UTC (permalink / raw)
  To: Josh Boyer; +Cc: rpurdie, lenz, kernel list, Russell King, dwmw2, Andrew Morton

Hi!

> > Latest mtd changes break collie...it now oopses during boot. This
> > reverts the bad patch.
> >
> > Signed-off-by: Pavel Machek <pavel@suse.cz>
> >
> <snip>
> > -               for(i=0;i<100;i++){
> > -                       status = map_read32(map,adr);
> > -                       if((status & SR_READY)==SR_READY)
> > -                               break;
> > -                       udelay(1);
> > +               status = map_read32(map,adr);
> 
> I was just discussing with someone today how map_read32 no longer
> exists in the kernel...  does this even compile for you?
> 
> Somehow I think I'm missing something...

I had other changes in my tree. Only old_mtd+my_changes worked, but
new_mtd+my_changes broke, so I figured out diff between old_mtd and
new_mtd must be bad. Given that neither old_mtd compiled nor new_mtd
compiled...

Fixes to map_read32 are being prepared.

								Pavel
-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-10  2:59 ` Todd Poynor
@ 2005-11-10  9:50   ` Pavel Machek
  2005-11-10 10:02     ` David Woodhouse
  0 siblings, 1 reply; 26+ messages in thread
From: Pavel Machek @ 2005-11-10  9:50 UTC (permalink / raw)
  To: Todd Poynor
  Cc: rpurdie, lenz, kernel list, Russell King, dwmw2, Andrew Morton

Hi!

> >Latest mtd changes break collie...it now oopses during boot. This
> >reverts the bad patch.
> 
> What tree was this generated against?  It doesn't seem to match recent 
> linux-mtd or kernel.org trees.  It looks like the tree used had 
> different version of a couple fixes recently added to linux-mtd (removal 
> of bogus udelays and 32-bit status datatype).
> 
> I'm guessing the important part is to add a missing spin_unlock_bh(), 
> which is definitely a bug in the mtd code, but this code is so different 
> than linux-mtd CVS that it seems more resyncing is needed.  As it stands 
> now, force-fitting this patch would still leave an unbalanced 
> spin_lock_bh() without other changes.  And it does look like this driver 
> hasn't been converted to modern mtd apis.

Is there easy way to get at linux-mtd CVS? Attached is my current
version of sharp.c; map_read32/map_write32 was deleted thanks to
Richard Purdue.

							Pavel
/*
 * MTD chip driver for pre-CFI Sharp flash chips
 *
 * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
 *           2000,2001 Lineo, Inc.
 *
 * $Id: sharp.c,v 1.14 2004/08/09 13:19:43 dwmw2 Exp $
 *
 * Devices supported:
 *   LH28F016SCT Symmetrical block flash memory, 2Mx8
 *   LH28F008SCT Symmetrical block flash memory, 1Mx8
 *
 * Documentation:
 *   http://www.sharpmeg.com/datasheets/memic/flashcmp/
 *   http://www.sharpmeg.com/datasheets/memic/flashcmp/01symf/16m/016sctl9.pdf
 *   016sctl9.pdf
 *
 * Limitations:
 *   This driver only supports 4x1 arrangement of chips.
 *   Not tested on anything but PowerPC.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/cfi.h>
#include <linux/delay.h>
#include <linux/init.h>

#define CMD_RESET		0xffffffff
#define CMD_READ_ID		0x90909090
#define CMD_READ_STATUS		0x70707070
#define CMD_CLEAR_STATUS	0x50505050
#define CMD_BLOCK_ERASE_1	0x20202020
#define CMD_BLOCK_ERASE_2	0xd0d0d0d0
#define CMD_BYTE_WRITE		0x40404040
#define CMD_SUSPEND		0xb0b0b0b0
#define CMD_RESUME		0xd0d0d0d0
#define CMD_SET_BLOCK_LOCK_1	0x60606060
#define CMD_SET_BLOCK_LOCK_2	0x01010101
#define CMD_SET_MASTER_LOCK_1	0x60606060
#define CMD_SET_MASTER_LOCK_2	0xf1f1f1f1
#define CMD_CLEAR_BLOCK_LOCKS_1	0x60606060
#define CMD_CLEAR_BLOCK_LOCKS_2	0xd0d0d0d0

#define SR_READY		0x80808080 // 1 = ready
#define SR_ERASE_SUSPEND	0x40404040 // 1 = block erase suspended
#define SR_ERROR_ERASE		0x20202020 // 1 = error in block erase or clear lock bits
#define SR_ERROR_WRITE		0x10101010 // 1 = error in byte write or set lock bit
#define	SR_VPP			0x08080808 // 1 = Vpp is low
#define SR_WRITE_SUSPEND	0x04040404 // 1 = byte write suspended
#define SR_PROTECT		0x02020202 // 1 = lock bit set
#define SR_RESERVED		0x01010101

#define SR_ERRORS (SR_ERROR_ERASE|SR_ERROR_WRITE|SR_VPP|SR_PROTECT)

#define BLOCK_MASK		0xfffe0000

/* Configuration options */

#define AUTOUNLOCK  /* automatically unlocks blocks before erasing */

struct mtd_info *sharp_probe(struct map_info *);

static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);

static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
	size_t *retlen, u_char *buf);
static int sharp_write(struct mtd_info *mtd, loff_t from, size_t len,
	size_t *retlen, const u_char *buf);
static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr);
static void sharp_sync(struct mtd_info *mtd);
static int sharp_suspend(struct mtd_info *mtd);
static void sharp_resume(struct mtd_info *mtd);
static void sharp_destroy(struct mtd_info *mtd);

static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
	unsigned long adr, __u32 datum);
static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
	unsigned long adr);
#ifdef AUTOUNLOCK
static inline void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
	unsigned long adr);
#endif


struct sharp_info{
	struct flchip *chip;
	int bogus;
	int chipshift;
	int numchips;
	struct flchip chips[1];
};

struct mtd_info *sharp_probe(struct map_info *map);
static void sharp_destroy(struct mtd_info *mtd);

static struct mtd_chip_driver sharp_chipdrv = {
	.probe		= sharp_probe,
	.destroy	= sharp_destroy,
	.name		= "sharp",
	.module		= THIS_MODULE
};

static void sharp_udelay(unsigned long i) {
	if (in_interrupt()) {
		udelay(i);
	} else {
		schedule();
	}
}

struct mtd_info *sharp_probe(struct map_info *map)
{
	struct mtd_info *mtd = NULL;
	struct sharp_info *sharp = NULL;
	int width;

	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
	if(!mtd)
		return NULL;

	sharp = kmalloc(sizeof(*sharp), GFP_KERNEL);
	if(!sharp) {
		kfree(mtd);
		return NULL;
	}

	memset(mtd, 0, sizeof(*mtd));

	width = sharp_probe_map(map,mtd);
	if(!width){
		kfree(mtd);
		kfree(sharp);
		return NULL;
	}

	mtd->priv = map;
	mtd->type = MTD_NORFLASH;
	mtd->erase = sharp_erase;
	mtd->read = sharp_read;
	mtd->write = sharp_write;
	mtd->sync = sharp_sync;
	mtd->suspend = sharp_suspend;
	mtd->resume = sharp_resume;
	mtd->flags = MTD_CAP_NORFLASH;
	mtd->name = map->name;

	memset(sharp, 0, sizeof(*sharp));
	sharp->chipshift = 24;
	sharp->numchips = 1;
	sharp->chips[0].start = 0;
	sharp->chips[0].state = FL_READY;
	sharp->chips[0].mutex = &sharp->chips[0]._spinlock;
	sharp->chips[0].word_write_time = 0;
	init_waitqueue_head(&sharp->chips[0].wq);
	spin_lock_init(&sharp->chips[0]._spinlock);

	map->fldrv = &sharp_chipdrv;
	map->fldrv_priv = sharp;

	__module_get(THIS_MODULE);
	return mtd;
}

static inline void sharp_send_cmd(struct map_info *map, unsigned long cmd, unsigned long adr)
{
	map_word map_cmd;
	map_cmd.x[0] = cmd;
	map_write(map, map_cmd, adr);
}

static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
{
	map_word tmp, read0, read4;
	unsigned long base = 0;
	int width = 4;

	tmp = map_read(map, base+0);

	sharp_send_cmd(map, CMD_READ_ID, base+0);

	read0 = map_read(map, base+0);
	read4 = map_read(map, base+4);
	if (read0.x[0] == 0x00b000b0) {
		switch(read4.x[0]){
		case 0xaaaaaaaa:
		case 0xa0a0a0a0:
			/* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/
			/* a0 - LH28F016SCT-Z4  2Mx8, 32 64k blocks*/
			mtd->erasesize = 0x10000 * width;
			mtd->size = 0x200000 * width;
			return width;
		case 0xa6a6a6a6:
			/* a6 - LH28F008SCT-L12 1Mx8, 16 64k blocks*/
			/* a6 - LH28F008SCR-L85 1Mx8, 16 64k blocks*/
			mtd->erasesize = 0x10000 * width;
			mtd->size = 0x100000 * width;
			return width;
		case 0x00b000b0:
			/* a6 - LH28F640BFHE 8 64k * 2 chip blocks*/
			mtd->erasesize = 0x10000 * width / 2;
			mtd->size = 0x800000 * width / 2;
			return width;
		default:
			printk("Sort-of looks like sharp flash.\n");
		}
	} else if ((map_read(map, base+0).x[0] == CMD_READ_ID)){
		/* RAM, probably */
		printk("Looks like RAM\n");
		map_write(map, tmp, base+0);
	} else {
		printk("Doesn't look like sharp flash.\n");
	}

	return 0;
}

/* This function returns with the chip->mutex lock held. */
static int sharp_wait(struct map_info *map, struct flchip *chip)
{
	map_word status;
	unsigned long timeo = jiffies + HZ;
	DECLARE_WAITQUEUE(wait, current);
	int adr = 0;

retry:
	spin_lock_bh(chip->mutex);

	switch (chip->state) {
	case FL_READY:
		sharp_send_cmd(map, CMD_READ_STATUS, adr);
		chip->state = FL_STATUS;
	case FL_STATUS:
		status = map_read(map, adr);
		if ((status.x[0] & SR_READY) == SR_READY)
			break;
		spin_unlock_bh(chip->mutex);
		if (time_after(jiffies, timeo)) {
			printk("Waiting for chip to be ready timed out in erase\n");
			return -EIO;
		}
		sharp_udelay(1);
		goto retry;
	default:
		set_current_state(TASK_INTERRUPTIBLE);
		add_wait_queue(&chip->wq, &wait);

		spin_unlock_bh(chip->mutex);

		sharp_udelay(1);

		set_current_state(TASK_RUNNING);
		remove_wait_queue(&chip->wq, &wait);

		if(signal_pending(current))
			return -EINTR;

		timeo = jiffies + HZ;

		goto retry;
	}

	sharp_send_cmd(map, CMD_RESET, adr);

	chip->state = FL_READY;

	return 0;
}

static void sharp_release(struct flchip *chip)
{
	wake_up(&chip->wq);
	spin_unlock_bh(chip->mutex);
}

static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
	size_t *retlen, u_char *buf)
{
	struct map_info *map = mtd->priv;
	struct sharp_info *sharp = map->fldrv_priv;
	int chipnum;
	int ret = 0;
	int ofs = 0;

	chipnum = (from >> sharp->chipshift);
	ofs = from & ((1 << sharp->chipshift)-1);

	*retlen = 0;

	while(len){
		unsigned long thislen;

		if(chipnum>=sharp->numchips)
			break;

		thislen = len;
		if(ofs+thislen >= (1<<sharp->chipshift))
			thislen = (1<<sharp->chipshift) - ofs;

		ret = sharp_wait(map,&sharp->chips[chipnum]);
		if(ret<0)
			break;

		map_copy_from(map,buf,ofs,thislen);

		sharp_release(&sharp->chips[chipnum]);

		*retlen += thislen;
		len -= thislen;
		buf += thislen;

		ofs = 0;
		chipnum++;
	}
	return ret;
}

static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len,
	size_t *retlen, const u_char *buf)
{
	struct map_info *map = mtd->priv;
	struct sharp_info *sharp = map->fldrv_priv;
	int ret = 0;
	int i,j;
	int chipnum;
	unsigned long ofs;
	union { u32 l; unsigned char uc[4]; } tbuf;

	*retlen = 0;

	while(len){
		tbuf.l = 0xffffffff;
		chipnum = to >> sharp->chipshift;
		ofs = to & ((1<<sharp->chipshift)-1);

		j=0;
		for(i=ofs&3;i<4 && len;i++){
			tbuf.uc[i] = *buf;
			buf++;
			to++;
			len--;
			j++;
		}
		sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l);
		if(ret<0)
			return ret;
		(*retlen)+=j;
	}

	return 0;
}

static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
	unsigned long adr, __u32 datum)
{
	int ret;
	int try;
	int i;
	map_word status, data;

	status.x[0] = 0;
	ret = sharp_wait(map,chip);
	if (ret < 0)
		return ret;

	for(try=0;try<10;try++){
		sharp_send_cmd(map, CMD_BYTE_WRITE, adr);
		/* cpu_to_le32 -> hack to fix the writel be->le conversion */
		data.x[0] = cpu_to_le32(datum);
		map_write(map, data, adr);

		chip->state = FL_WRITING;

		sharp_send_cmd(map, CMD_READ_STATUS, adr);
		for(i=0;i<100;i++){
			status = map_read(map, adr);
			if((status.x[0] & SR_READY)==SR_READY)
				break;
		}
#ifdef AUTOUNLOCK
		if (status.x[0] & SR_PROTECT) { /* lock block */
			sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
			sharp_unlock_oneblock(map,chip,adr);
			sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
			sharp_send_cmd(map, CMD_RESET, adr);
			continue;
		}
#endif
		if(i==100){
			printk("sharp: timed out writing\n");
		}

		if (!(status.x[0] & SR_ERRORS))
			break;

		printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status.x[0]);

		sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
	}
	sharp_send_cmd(map, CMD_RESET, adr);
	chip->state = FL_READY;

	sharp_release(chip);

	return 0;
}

static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	struct map_info *map = mtd->priv;
	struct sharp_info *sharp = map->fldrv_priv;
	unsigned long adr,len;
	int chipnum, ret=0;

//printk("sharp_erase()\n");
	if(instr->addr & (mtd->erasesize - 1))
		return -EINVAL;
	if(instr->len & (mtd->erasesize - 1))
		return -EINVAL;
	if(instr->len + instr->addr > mtd->size)
		return -EINVAL;

	chipnum = instr->addr >> sharp->chipshift;
	adr = instr->addr & ((1<<sharp->chipshift)-1);
	len = instr->len;

	while(len){
		ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr);
		if(ret)return ret;

		if (adr >= 0xfe0000) {
			adr += mtd->erasesize / 8;
			len -= mtd->erasesize / 8;
		} else {
			adr += mtd->erasesize;
			len -= mtd->erasesize;
		}
		if(adr >> sharp->chipshift){
			adr = 0;
			chipnum++;
			if(chipnum>=sharp->numchips)
				break;
		}
	}

	instr->state = MTD_ERASE_DONE;
	mtd_erase_callback(instr);

	return 0;
}

static inline int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
	unsigned long adr)
{
	int ret;
	unsigned long timeo;
	map_word status;
	DECLARE_WAITQUEUE(wait, current);

	sharp_send_cmd(map, CMD_READ_STATUS, adr);
	status = map_read(map, adr);

	timeo = jiffies + HZ * 10;

	while (time_before(jiffies, timeo)){
		sharp_send_cmd(map, CMD_READ_STATUS, adr);
		status = map_read(map, adr);
		if ((status.x[0] & SR_READY)==SR_READY) {
			ret = 0;
			goto out;
		}
		set_current_state(TASK_INTERRUPTIBLE);
		add_wait_queue(&chip->wq, &wait);

		spin_unlock_bh(chip->mutex);

		schedule_timeout(1);
		schedule();

		spin_lock_bh(chip->mutex);

		remove_wait_queue(&chip->wq, &wait);
		set_current_state(TASK_RUNNING);
	}
	ret = -ETIME;
out:
	return ret;
}

static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
	unsigned long adr)
{
	int ret;
	map_word status;

	ret = sharp_wait(map,chip);
	if (ret < 0)
		return ret;

#ifdef AUTOUNLOCK
	/* This seems like a good place to do an unlock */
	sharp_unlock_oneblock(map,chip,adr);
#endif

	sharp_send_cmd(map, CMD_BLOCK_ERASE_1, adr);
	sharp_send_cmd(map, CMD_BLOCK_ERASE_2, adr);

	chip->state = FL_ERASING;

	ret = sharp_do_wait_for_ready(map,chip,adr);
	if(ret<0) {
		spin_unlock_bh(chip->mutex);
		return ret;
	}

	sharp_send_cmd(map, CMD_READ_STATUS, adr);
	status = map_read(map,adr);

	if (!(status.x[0] & SR_ERRORS)) {
		sharp_send_cmd(map, CMD_RESET, adr);
		chip->state = FL_READY;
		spin_unlock_bh(chip->mutex);
		return 0;
	}

	printk("sharp: error erasing block at addr=%08lx status=%08x\n", adr, status.x[0]);
	sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);

	sharp_release(chip);

	return -EIO;
}

#ifdef AUTOUNLOCK
static inline void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
	unsigned long adr)
{
	map_word status;

	sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_1, adr & BLOCK_MASK);
	sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_2, adr & BLOCK_MASK);

	sharp_do_wait_for_ready(map,chip,adr);

	status = map_read(map, adr);

	if (!(status.x[0] & SR_ERRORS)) {
		sharp_send_cmd(map, CMD_RESET, adr);
		chip->state = FL_READY;
		return;
	}

	printk("sharp: error unlocking block at addr=%08lx status=%08lx\n", adr, status.x[0]);
	sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
}
#endif

static void sharp_sync(struct mtd_info *mtd)
{
}

static int sharp_suspend(struct mtd_info *mtd)
{
	struct map_info *map = mtd->priv;
	struct sharp_info *sharp = map->fldrv_priv;
	int i;
	struct flchip *chip;
	int ret = 0;

	for (i = 0; !ret && i < sharp->numchips; i++) {
		chip = &sharp->chips[i];
		ret = sharp_wait(map,chip);

		if (ret) {
			ret = -EAGAIN;
		} else {
			chip->state = FL_PM_SUSPENDED;
			spin_unlock_bh(chip->mutex);
		}
	}
	return ret;
}

static void sharp_resume(struct mtd_info *mtd)
{
	struct map_info *map = mtd->priv;
	struct sharp_info *sharp = map->fldrv_priv;
	int i;
	struct flchip *chip;

	for (i = 0; i < sharp->numchips; i++) {
		chip = &sharp->chips[i];

		spin_lock_bh(chip->mutex);

		if (chip->state == FL_PM_SUSPENDED) {
			/* We need to force it back to a known state */
			sharp_send_cmd(map, CMD_RESET, chip->start);
			chip->state = FL_READY;
			wake_up(&chip->wq);
		}

		spin_unlock_bh(chip->mutex);
	}
}

static void sharp_destroy(struct mtd_info *mtd)
{
	struct map_info *map = mtd->priv;
	struct sharp_info *sharp = map->fldrv_priv;

	kfree(sharp);
}

int __init sharp_probe_init(void)
{
	printk("MTD Sharp chip driver <ds@lineo.com>\n");

	register_mtd_chip_driver(&sharp_chipdrv);

	return 0;
}

static void __exit sharp_probe_exit(void)
{
	unregister_mtd_chip_driver(&sharp_chipdrv);
}

module_init(sharp_probe_init);
module_exit(sharp_probe_exit);


MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Schleef <ds@schleef.org>");
MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips");


-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-10  9:50   ` Pavel Machek
@ 2005-11-10 10:02     ` David Woodhouse
  2005-11-10 10:38       ` Pavel Machek
  0 siblings, 1 reply; 26+ messages in thread
From: David Woodhouse @ 2005-11-10 10:02 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Todd Poynor, rpurdie, lenz, kernel list, Russell King,
	Andrew Morton

On Thu, 2005-11-10 at 10:50 +0100, Pavel Machek wrote:
> Is there easy way to get at linux-mtd CVS? Attached is my current
> version of sharp.c; map_read32/map_write32 was deleted thanks to
> Richard Purdue.

http://www.linux-mtd.infradead.org/source.html has a reference to
anoncvs.

I'd really prefer not to see sharp.c revived -- it's supposed to be
dying, in favour of the CFI chipset drivers and jedec_probe code.
Can we try to work out what's wrong with those, instead?

-- 
dwmw2



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

* Re: latest mtd changes broke collie
  2005-11-10 10:02     ` David Woodhouse
@ 2005-11-10 10:38       ` Pavel Machek
  2005-11-10 10:51         ` David Woodhouse
  0 siblings, 1 reply; 26+ messages in thread
From: Pavel Machek @ 2005-11-10 10:38 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Todd Poynor, rpurdie, lenz, kernel list, Russell King,
	Andrew Morton

Hi!

> > Is there easy way to get at linux-mtd CVS? Attached is my current
> > version of sharp.c; map_read32/map_write32 was deleted thanks to
> > Richard Purdue.
> 
> http://www.linux-mtd.infradead.org/source.html has a reference to
> anoncvs.
> 
> I'd really prefer not to see sharp.c revived -- it's supposed to be
> dying, in favour of the CFI chipset drivers and jedec_probe code.
> Can we try to work out what's wrong with those, instead?

This is quite hard to debug -- I do not even have serial console for
collie, and I know nothing about mtd.

Another issue is that collie is in pretty poor state -- it never
worked in mainline. Getting it working in mainline, even with
deprecated sharp.c driver, would bea big plus as I should get
users/testers at that point.

That said... I can certainly do few experiments. Switching map_name
from "sharp" to "cfi" should be theoretically enough to get new code
up?
								Pavel
-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-10 10:38       ` Pavel Machek
@ 2005-11-10 10:51         ` David Woodhouse
  2005-11-10 10:59           ` Pavel Machek
  0 siblings, 1 reply; 26+ messages in thread
From: David Woodhouse @ 2005-11-10 10:51 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Todd Poynor, rpurdie, lenz, kernel list, Russell King,
	Andrew Morton

On Thu, 2005-11-10 at 11:38 +0100, Pavel Machek wrote:
> That said... I can certainly do few experiments. Switching map_name
> from "sharp" to "cfi" should be theoretically enough to get new code
> up?

That's if the chips are actually compliant with the Common Flash
Interface. Otherwise, use the 'jedec_probe' method to identify them,
which will still end up using the same actual back-end driver.

-- 
dwmw2



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

* Re: latest mtd changes broke collie
  2005-11-10 10:51         ` David Woodhouse
@ 2005-11-10 10:59           ` Pavel Machek
  2005-11-10 11:11             ` David Woodhouse
  0 siblings, 1 reply; 26+ messages in thread
From: Pavel Machek @ 2005-11-10 10:59 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Todd Poynor, rpurdie, lenz, kernel list, Russell King,
	Andrew Morton

Hi!

> > That said... I can certainly do few experiments. Switching map_name
> > from "sharp" to "cfi" should be theoretically enough to get new code
> > up?
> 
> That's if the chips are actually compliant with the Common Flash
> Interface. Otherwise, use the 'jedec_probe' method to identify them,
> which will still end up using the same actual back-end driver.

Well, how do I found out? I tried switching to CFI, and it will not
boot (unable to mount root...). No mtd-related messages as far as I
can see. There's quite a lot of mtd-related config options, I set them
like this:

#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AFS_PARTS is not set

#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_AMDSTD_RETRY=0
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
CONFIG_MTD_OBSOLETE_CHIPS=y
# CONFIG_MTD_AMDSTD is not set
# CONFIG_MTD_SHARP is not set
# CONFIG_MTD_JEDEC is not set
# CONFIG_MTD_XIP is not set

#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
# CONFIG_MTD_ARM_INTEGRATOR is not set
CONFIG_MTD_SA1100=y
# CONFIG_MTD_IMPA7 is not set
# CONFIG_MTD_PLATRAM is not set

#
# Self-contained MTD device drivers
#
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLKMTD is not set
# CONFIG_MTD_BLOCK2MTD is not set

There's this kind of strange code in sharp.c; is it the thing I need
to rewrite into cfi_probe?

static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
{
        map_word tmp, read0, read4;
        unsigned long base = 0;
        int width = 4;

        tmp = map_read(map, base+0);

        sharp_send_cmd(map, CMD_READ_ID, base+0);

        read0 = map_read(map, base+0);
        read4 = map_read(map, base+4);
        if (read0.x[0] == 0x00b000b0) {
                switch(read4.x[0]){
                case 0xaaaaaaaa:
                case 0xa0a0a0a0:
                        /* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/
                        /* a0 - LH28F016SCT-Z4  2Mx8, 32 64k blocks*/
                        mtd->erasesize = 0x10000 * width;
                        mtd->size = 0x200000 * width;
                        return width;
                case 0xa6a6a6a6:
                        /* a6 - LH28F008SCT-L12 1Mx8, 16 64k blocks*/
                        /* a6 - LH28F008SCR-L85 1Mx8, 16 64k blocks*/
                        mtd->erasesize = 0x10000 * width;
                        mtd->size = 0x100000 * width;
                        return width;
                case 0x00b000b0:
                        /* a6 - LH28F640BFHE 8 64k * 2 chip blocks*/
                        mtd->erasesize = 0x10000 * width / 2;
                        mtd->size = 0x800000 * width / 2;
                        return width;
                default:
                        printk("Sort-of looks like sharp flash.\n");
                }

?
							Pavel
-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-10 10:59           ` Pavel Machek
@ 2005-11-10 11:11             ` David Woodhouse
  2005-11-10 11:44               ` Pavel Machek
                                 ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: David Woodhouse @ 2005-11-10 11:11 UTC (permalink / raw)
  To: Pavel Machek; +Cc: linux-mtd, kernel list

On Thu, 2005-11-10 at 11:59 +0100, Pavel Machek wrote:
> Well, how do I found out? I tried switching to CFI, and it will not
> boot (unable to mount root...). No mtd-related messages as far as I
> can see. There's quite a lot of mtd-related config options, I set them
> like this:

If the old sharp driver had even a _chance_ of working, then you
presumably have four 8-bit flash chips laid out on a 32-bit bus, and
those chips are compatible with the Intel command set.

You can CONFIG_MTD_JEDECPROBE, and you want CONFIG_MTD_MAP_BANK_WIDTH=4,
CONFIG_MTD_CFI_I4, CONFIG_MTD_CFI_INTELEXT.

Check that your chips are listed in the table in jedec_probe.c and turn
on all the debugging in jedec_probe.c 

-- 
dwmw2



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

* Re: latest mtd changes broke collie
  2005-11-10 11:11             ` David Woodhouse
@ 2005-11-10 11:44               ` Pavel Machek
  2005-11-10 12:07               ` Pavel Machek
  2005-11-10 22:41               ` Pavel Machek
  2 siblings, 0 replies; 26+ messages in thread
From: Pavel Machek @ 2005-11-10 11:44 UTC (permalink / raw)
  To: David Woodhouse; +Cc: linux-mtd, kernel list

Hi!

> > Well, how do I found out? I tried switching to CFI, and it will not
> > boot (unable to mount root...). No mtd-related messages as far as I
> > can see. There's quite a lot of mtd-related config options, I set them
> > like this:
> 
> If the old sharp driver had even a _chance_ of working, then you
> presumably have four 8-bit flash chips laid out on a 32-bit bus, and
> those chips are compatible with the Intel command set.
> 
> You can CONFIG_MTD_JEDECPROBE, and you want CONFIG_MTD_MAP_BANK_WIDTH=4,
> CONFIG_MTD_CFI_I4, CONFIG_MTD_CFI_INTELEXT.
> 
> Check that your chips are listed in the table in jedec_probe.c and turn
> on all the debugging in jedec_probe.c 

As far as I can see, they are not listed :-(.

static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
{
        map_word tmp, read0, read4;
        int width = 4;

        tmp = map_read(map, base+0);
        sharp_send_cmd(map, CMD_READ_ID, base+0);

        read0 = map_read(map, base+0);
        read4 = map_read(map, base+4);
        if (read0.x[0] == 0x00b000b0) {
                switch(read4.x[0]){
                case 0x00b000b0:
                        /* a6 - LH28F640BFHE 8 64k * 2 chip blocks*/
                        mtd->erasesize = 0x10000 * width / 2;
                        mtd->size = 0x800000 * width / 2;
                        return width;

...I've removed unneccessary code, this path is actually taken. Does
it mean that mfr == id == 0x00b0? [Notice that comment is wrong there,
probably belongs to another chip :-(]
							Pavel

-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-10 11:11             ` David Woodhouse
  2005-11-10 11:44               ` Pavel Machek
@ 2005-11-10 12:07               ` Pavel Machek
  2005-11-10 13:02                 ` David Vrabel
  2005-11-10 22:41               ` Pavel Machek
  2 siblings, 1 reply; 26+ messages in thread
From: Pavel Machek @ 2005-11-10 12:07 UTC (permalink / raw)
  To: David Woodhouse; +Cc: linux-mtd, kernel list

Hi!

> > Well, how do I found out? I tried switching to CFI, and it will not
> > boot (unable to mount root...). No mtd-related messages as far as I
> > can see. There's quite a lot of mtd-related config options, I set them
> > like this:
> 
> If the old sharp driver had even a _chance_ of working, then you
> presumably have four 8-bit flash chips laid out on a 32-bit bus, and
> those chips are compatible with the Intel command set.
> 
> You can CONFIG_MTD_JEDECPROBE, and you want CONFIG_MTD_MAP_BANK_WIDTH=4,
> CONFIG_MTD_CFI_I4, CONFIG_MTD_CFI_INTELEXT.
> 
> Check that your chips are listed in the table in jedec_probe.c and turn
> on all the debugging in jedec_probe.c 

Ok, I got a little bit more forward.

I created entry like this:
        {
                .mfr_id         = 0x00b0,
                .dev_id         = 0x00b0,
                .name           = "Collie hack",
                .uaddr          = {
                        [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
                },
                .DevSize        = SIZE_4MiB,
                .CmdSet         = P_ID_INTEL_EXT,
                .NumEraseRegions= 1,
                .regions        = {
                        ERASEINFO(0x10000,8),
                }
}

(Which is probably wrong, I just made up the data), and set name in
collie.c to "jedec_probe". That made jedec_probe.c go alive, and it
prints...

Found: Collie hack
sa1100-0: Found 4 x8 devices at 0x0 in 32-bit bank
Sum of regions (200000) != total size of set of interleaved chips (1000000)
gen_probe: No Supported Vendor Command set found

sharp.c sets

			width = 4;
                        mtd->erasesize = 0x10000 * width / 2;
                        mtd->size = 0x800000 * width / 2;

...that is
		width = 4;
		erazesize = 0x20000;
		size      = 0x1000000;

Does it mean ERASEINFO(0x20000,7) should do the trick?

							Pavel
-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-10 12:07               ` Pavel Machek
@ 2005-11-10 13:02                 ` David Vrabel
  2005-11-10 13:09                   ` Pavel Machek
  0 siblings, 1 reply; 26+ messages in thread
From: David Vrabel @ 2005-11-10 13:02 UTC (permalink / raw)
  To: Pavel Machek; +Cc: David Woodhouse, linux-mtd, kernel list

Pavel Machek wrote:
> 
> Ok, I got a little bit more forward.
> 
> I created entry like this:
>         {
>                 .mfr_id         = 0x00b0,
>                 .dev_id         = 0x00b0,
>                 .name           = "Collie hack",
>                 .uaddr          = {
>                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
>                 },
>                 .DevSize        = SIZE_4MiB,
>                 .CmdSet         = P_ID_INTEL_EXT,
>                 .NumEraseRegions= 1,
>                 .regions        = {
>                         ERASEINFO(0x10000,8),
>                 }
> }
> 
> (Which is probably wrong, I just made up the data)

Shouldn't you get hold of the datasheet for the flash chips and fill in
this information correctly?

David Vrabel

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

* Re: latest mtd changes broke collie
  2005-11-10 13:02                 ` David Vrabel
@ 2005-11-10 13:09                   ` Pavel Machek
  2005-11-10 17:41                     ` Richard Purdie
  0 siblings, 1 reply; 26+ messages in thread
From: Pavel Machek @ 2005-11-10 13:09 UTC (permalink / raw)
  To: David Vrabel; +Cc: David Woodhouse, linux-mtd, kernel list

Hi!

> > Ok, I got a little bit more forward.
> > 
> > I created entry like this:
> >         {
> >                 .mfr_id         = 0x00b0,
> >                 .dev_id         = 0x00b0,
> >                 .name           = "Collie hack",
> >                 .uaddr          = {
> >                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
> >                 },
> >                 .DevSize        = SIZE_4MiB,
> >                 .CmdSet         = P_ID_INTEL_EXT,
> >                 .NumEraseRegions= 1,
> >                 .regions        = {
> >                         ERASEINFO(0x10000,8),
> >                 }
> > }
> > 
> > (Which is probably wrong, I just made up the data)
> 
> Shouldn't you get hold of the datasheet for the flash chips and fill in
> this information correctly?

I already have working sharp.c driver... And I do not even know
manufacturer of the chip, just its ids.
							Pavel

-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-10 13:09                   ` Pavel Machek
@ 2005-11-10 17:41                     ` Richard Purdie
  2005-11-10 18:09                       ` Richard Purdie
  0 siblings, 1 reply; 26+ messages in thread
From: Richard Purdie @ 2005-11-10 17:41 UTC (permalink / raw)
  To: Pavel Machek; +Cc: David Vrabel, linux-mtd, David Woodhouse, kernel list

On Thu, 2005-11-10 at 14:09 +0100, Pavel Machek wrote:
> > Shouldn't you get hold of the datasheet for the flash chips and fill in
> > this information correctly?
> 
> I already have working sharp.c driver... And I do not even know
> manufacturer of the chip, just its ids.

The chip number is LF28F640BX which is a 64MBit device so perhaps Intel
StrataFlash 28F640? That seems to be a fairly common chip...

Richard


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

* Re: latest mtd changes broke collie
  2005-11-10 17:41                     ` Richard Purdie
@ 2005-11-10 18:09                       ` Richard Purdie
  2005-11-10 22:06                         ` Pavel Machek
  0 siblings, 1 reply; 26+ messages in thread
From: Richard Purdie @ 2005-11-10 18:09 UTC (permalink / raw)
  To: Pavel Machek; +Cc: David Vrabel, linux-mtd, David Woodhouse, kernel list

On Thu, 2005-11-10 at 17:41 +0000, Richard Purdie wrote:
> On Thu, 2005-11-10 at 14:09 +0100, Pavel Machek wrote:
> > > Shouldn't you get hold of the datasheet for the flash chips and fill in
> > > this information correctly?
> > 
> > I already have working sharp.c driver... And I do not even know
> > manufacturer of the chip, just its ids.
> 
> The chip number is LF28F640BX which is a 64MBit device so perhaps Intel
> StrataFlash 28F640? That seems to be a fairly common chip...

Some further research suggests it should perhaps be LH28F640BX which is
a 48 pin Sharp flash chip (much more likely). The nearest datasheet I
can find is:

http://www.datasheetarchive.com/semiconductors/download.php?Datasheet=1120647

Richard


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

* Re: latest mtd changes broke collie
  2005-11-10 18:09                       ` Richard Purdie
@ 2005-11-10 22:06                         ` Pavel Machek
  0 siblings, 0 replies; 26+ messages in thread
From: Pavel Machek @ 2005-11-10 22:06 UTC (permalink / raw)
  To: Richard Purdie; +Cc: David Vrabel, linux-mtd, David Woodhouse, kernel list

Hi!

> > > > Shouldn't you get hold of the datasheet for the flash chips and fill in
> > > > this information correctly?
> > > 
> > > I already have working sharp.c driver... And I do not even know
> > > manufacturer of the chip, just its ids.
> > 
> > The chip number is LF28F640BX which is a 64MBit device so perhaps Intel
> > StrataFlash 28F640? That seems to be a fairly common chip...
> 
> Some further research suggests it should perhaps be LH28F640BX which is
> a 48 pin Sharp flash chip (much more likely). The nearest datasheet I
> can find is:
> 
> http://www.datasheetarchive.com/semiconductors/download.php?Datasheet=1120647

That's strange; first the datasheet is pretty much useless; it does
not even give you product ID ("refer to documentation"). Then it
claims this device supports CFI. I guess it is easier to get the
values from sharp.c than from this datasheet :-(.

[It seems like the chip has many "options", and it is up to user how
it uses the chip.]
							Pavel
-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-10 11:11             ` David Woodhouse
  2005-11-10 11:44               ` Pavel Machek
  2005-11-10 12:07               ` Pavel Machek
@ 2005-11-10 22:41               ` Pavel Machek
  2005-11-10 23:58                 ` Todd Poynor
  2 siblings, 1 reply; 26+ messages in thread
From: Pavel Machek @ 2005-11-10 22:41 UTC (permalink / raw)
  To: David Woodhouse; +Cc: linux-mtd, kernel list

Hi!

> > Well, how do I found out? I tried switching to CFI, and it will not
> > boot (unable to mount root...). No mtd-related messages as far as I
> > can see. There's quite a lot of mtd-related config options, I set them
> > like this:
> 
> If the old sharp driver had even a _chance_ of working, then you
> presumably have four 8-bit flash chips laid out on a 32-bit bus, and
> those chips are compatible with the Intel command set.
> 
> You can CONFIG_MTD_JEDECPROBE, and you want CONFIG_MTD_MAP_BANK_WIDTH=4,
> CONFIG_MTD_CFI_I4, CONFIG_MTD_CFI_INTELEXT.
> 
> Check that your chips are listed in the table in jedec_probe.c and turn
> on all the debugging in jedec_probe.c 

With these hacks, I'm able to mount flash at least read-only. On
attempt to remount read-write, I get 

"Write error in obliterating obsoleted node at 0x00bc0000: -30
...
Erase at 0x00c00000 failed immediately: -EROFS. Is the sector locked?"

Is it good news?
								Pavel

diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -208,7 +208,7 @@ static void collie_set_vpp(int vpp)
 }
 
 static struct flash_platform_data collie_flash_data = {
-	.map_name	= "sharp",
+	.map_name	= "jedec_probe",
 	.set_vpp	= collie_set_vpp,
 	.parts		= collie_partitions,
 	.nr_parts	= ARRAY_SIZE(collie_partitions),
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -25,6 +25,8 @@
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/gen_probe.h>
 
+#define DEBUG(a, b...) printk(b)
+
 /* Manufacturers */
 #define MANUFACTURER_AMD	0x0001
 #define MANUFACTURER_ATMEL	0x001f
@@ -271,6 +273,19 @@ struct amd_flash_info {
  */
 static const struct amd_flash_info jedec_table[] = {
 	{
+		.mfr_id		= 0x00b0,
+		.dev_id		= 0x00b0,
+		.name		= "Collie hack",
+		.uaddr		= {
+                        [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
+		},
+		.DevSize	= SIZE_4MiB,
+                .CmdSet         = P_ID_INTEL_EXT,
+                .NumEraseRegions= 1,
+                .regions        = {
+                        ERASEINFO(0x10000,64),
+                }
+	}, {
 		.mfr_id		= MANUFACTURER_AMD,
 		.dev_id		= AM29F032B,
 		.name		= "AMD AM29F032B",


-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-10 22:41               ` Pavel Machek
@ 2005-11-10 23:58                 ` Todd Poynor
  2005-11-11  0:16                   ` Pavel Machek
  0 siblings, 1 reply; 26+ messages in thread
From: Todd Poynor @ 2005-11-10 23:58 UTC (permalink / raw)
  To: Pavel Machek; +Cc: David Woodhouse, linux-mtd, kernel list

Pavel Machek wrote:
> 
> With these hacks, I'm able to mount flash at least read-only. On
> attempt to remount read-write, I get 
> 
> "Write error in obliterating obsoleted node at 0x00bc0000: -30
> ...
> Erase at 0x00c00000 failed immediately: -EROFS. Is the sector locked?"
> 
> Is it good news?

I see the old sharp driver has a normally-not-defined AUTOUNLOCK symbol 
that would enable some code to unlock blocks before writing/erasing 
(which isn't recommended since the code doesn't know the policy on 
whether the block is supposed to be locked).  The tree previously in use 
may have had something similar setup.  It seems these flashes have all 
blocks locked by default at power up.

Try flash_unlock /dev/mtdX before remounting.  More automatic means of 
handling this are still under debate, I need to try another stab at 
resolving that soon.

Looks like you're close to obsoleting the pre-CFI Sharp flash driver, 
it's good news...

-- 
Todd

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

* Re: latest mtd changes broke collie
  2005-11-10 23:58                 ` Todd Poynor
@ 2005-11-11  0:16                   ` Pavel Machek
  2005-11-11  7:01                     ` Ian Campbell
  0 siblings, 1 reply; 26+ messages in thread
From: Pavel Machek @ 2005-11-11  0:16 UTC (permalink / raw)
  To: Todd Poynor; +Cc: David Woodhouse, linux-mtd, kernel list

Hi!

> >With these hacks, I'm able to mount flash at least read-only. On
> >attempt to remount read-write, I get 
> >
> >"Write error in obliterating obsoleted node at 0x00bc0000: -30
> >...
> >Erase at 0x00c00000 failed immediately: -EROFS. Is the sector locked?"
> >
> >Is it good news?
> 
> I see the old sharp driver has a normally-not-defined AUTOUNLOCK symbol 
> that would enable some code to unlock blocks before writing/erasing 
> (which isn't recommended since the code doesn't know the policy on 
> whether the block is supposed to be locked).  The tree previously in use 
> may have had something similar setup.  It seems these flashes have all 
> blocks locked by default at power up.

Is there some quick hack I can do in kernel to unlock it? Is it
possible to accidentally unlock "BIOS" area and brick the device?

> Try flash_unlock /dev/mtdX before remounting.  More automatic means of 
> handling this are still under debate, I need to try another stab at 
> resolving that soon.

Good news is that I do have /dev/mtdX. Bad news is I do not have
flash_unlock. Does anyone have binary suitable for arm, preferably
statically linked?

> Looks like you're close to obsoleting the pre-CFI Sharp flash driver, 
> it's good news...

Ok, good. Read-only access is certainly better than nothing, and might
even be enough. Sharp shipped it with flash read-only originally.

								Pavel
-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-11  0:16                   ` Pavel Machek
@ 2005-11-11  7:01                     ` Ian Campbell
  2005-11-12 21:33                       ` Pavel Machek
  0 siblings, 1 reply; 26+ messages in thread
From: Ian Campbell @ 2005-11-11  7:01 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Todd Poynor, linux-mtd, David Woodhouse, kernel list

[-- Attachment #1: Type: text/plain, Size: 1522 bytes --]

On Fri, 2005-11-11 at 01:16 +0100, Pavel Machek wrote:
> Hi!
> 
> > >With these hacks, I'm able to mount flash at least read-only. On
> > >attempt to remount read-write, I get 
> > >
> > >"Write error in obliterating obsoleted node at 0x00bc0000: -30
> > >...
> > >Erase at 0x00c00000 failed immediately: -EROFS. Is the sector locked?"
> > >
> > >Is it good news?
> > 
> > I see the old sharp driver has a normally-not-defined AUTOUNLOCK symbol 
> > that would enable some code to unlock blocks before writing/erasing 
> > (which isn't recommended since the code doesn't know the policy on 
> > whether the block is supposed to be locked).  The tree previously in use 
> > may have had something similar setup.  It seems these flashes have all 
> > blocks locked by default at power up.
> 
> Is there some quick hack I can do in kernel to unlock it?

I use the following on my device:

        mtd = do_map_probe(...);
        
        if (!mtd) { ...err... }
        
        mtd->owner = THIS_MODULE;
        
        mtd->unlock(mtd,0,mtd->size);
        
> Is it possible to accidentally unlock "BIOS" area and brick the device?

Yep, but you could modify the parameters to unlock to no do so.
Depending on you partitioning scheme you might be able to use that to
figure out what to unlock...

Ian.

-- 
Ian Campbell

The most exciting phrase to hear in science, the one that heralds new
discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
		-- Isaac Asimov

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: latest mtd changes broke collie
  2005-11-11  7:01                     ` Ian Campbell
@ 2005-11-12 21:33                       ` Pavel Machek
  2005-11-13 10:35                         ` Ian Campbell
  2005-11-13 19:40                         ` Todd Poynor
  0 siblings, 2 replies; 26+ messages in thread
From: Pavel Machek @ 2005-11-12 21:33 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Todd Poynor, linux-mtd, David Woodhouse, kernel list

Hi!

> > > I see the old sharp driver has a normally-not-defined AUTOUNLOCK symbol 
> > > that would enable some code to unlock blocks before writing/erasing 
> > > (which isn't recommended since the code doesn't know the policy on 
> > > whether the block is supposed to be locked).  The tree previously in use 
> > > may have had something similar setup.  It seems these flashes have all 
> > > blocks locked by default at power up.
> > 
> > Is there some quick hack I can do in kernel to unlock it?
> 
> I use the following on my device:
> 
>         mtd = do_map_probe(...);
>         
>         if (!mtd) { ...err... }
>         
>         mtd->owner = THIS_MODULE;
>         
>         mtd->unlock(mtd,0,mtd->size);
>         
> > Is it possible to accidentally unlock "BIOS" area and brick the device?
> 
> Yep, but you could modify the parameters to unlock to no do so.
> Depending on you partitioning scheme you might be able to use that to
> figure out what to unlock...

I tried this one. Size 0xc0000 is reported as a "bootloader" during
boot. 

[Plus I get a warning from jffs2 that flashsize is not aligned to
erasesize. Then I get lot of messages that empty flash at XXX ends at
XXX.]

Any more ideas?
								Pavel

diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -208,8 +208,8 @@ static void collie_set_vpp(int vpp)
 }
 
 static struct flash_platform_data collie_flash_data = {
-//	.map_name	= "jedec_probe",
-	.map_name	= "sharp",
+	.map_name	= "jedec_probe",
+//	.map_name	= "sharp",
 	.set_vpp	= collie_set_vpp,
 	.parts		= collie_partitions,
 	.nr_parts	= ARRAY_SIZE(collie_partitions),
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -211,6 +211,7 @@ static int sa1100_probe_subdev(struct sa
 		goto err;
 	}
 	subdev->mtd->owner = THIS_MODULE;
+	subdev->mtd->unlock(subdev->mtd, 0xc0000, subdev->mtd->size);
 
 	printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, "
 		"%d-bit\n", phys, subdev->mtd->size >> 20,




-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-12 21:33                       ` Pavel Machek
@ 2005-11-13 10:35                         ` Ian Campbell
  2005-11-14 12:10                           ` Pavel Machek
  2005-11-13 19:40                         ` Todd Poynor
  1 sibling, 1 reply; 26+ messages in thread
From: Ian Campbell @ 2005-11-13 10:35 UTC (permalink / raw)
  To: Pavel Machek; +Cc: kernel list, David Woodhouse, linux-mtd, Todd Poynor

[-- Attachment #1: Type: text/plain, Size: 567 bytes --]

On Sat, 2005-11-12 at 22:33 +0100, Pavel Machek wrote:
> I tried this one. Size 0xc0000 is reported as a "bootloader" during
> boot. 
> 
> [Plus I get a warning from jffs2 that flashsize is not aligned to
> erasesize. Then I get lot of messages that empty flash at XXX ends at
> XXX.]

What erase size did you end up using? Is 0xc0000 a multiple of it?

> +	subdev->mtd->unlock(subdev->mtd, 0xc0000, subdev->mtd->size);

Probably unrelated to the actual problems, but shouldn't that be
subdev->mtd->size - 0xc0000 at the end?

Ian.
-- 
Ian Campbell

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: latest mtd changes broke collie
  2005-11-12 21:33                       ` Pavel Machek
  2005-11-13 10:35                         ` Ian Campbell
@ 2005-11-13 19:40                         ` Todd Poynor
  2005-11-14 12:08                           ` Pavel Machek
  1 sibling, 1 reply; 26+ messages in thread
From: Todd Poynor @ 2005-11-13 19:40 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Ian Campbell, linux-mtd, David Woodhouse, kernel list

Pavel Machek wrote:

> [Plus I get a warning from jffs2 that flashsize is not aligned to
> erasesize. Then I get lot of messages that empty flash at XXX ends at
> XXX.]

The datasheet ref'ed earlier says the chips have a 64KB erase block 
size, and the sharp driver multiplies that value by an interleave of 4 
chips to set the erase size.  What erase size is set under the new 
setup?  cat /proc/mtd or set loglevel for KERN_DEBUG at chip probe time. 
  The new code is setting it based on what was read from the CFI query 
info reported by the chip times the interleave factor (which apparently 
should be set as 4 after detecting 4 chips if CONFIG_MTD_CFI_I4=y).


-- 
Todd

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

* Re: latest mtd changes broke collie
  2005-11-13 19:40                         ` Todd Poynor
@ 2005-11-14 12:08                           ` Pavel Machek
  0 siblings, 0 replies; 26+ messages in thread
From: Pavel Machek @ 2005-11-14 12:08 UTC (permalink / raw)
  To: Todd Poynor; +Cc: Ian Campbell, linux-mtd, David Woodhouse, kernel list

Hi!

> >[Plus I get a warning from jffs2 that flashsize is not aligned to
> >erasesize. Then I get lot of messages that empty flash at XXX ends at
> >XXX.]
> 
> The datasheet ref'ed earlier says the chips have a 64KB erase block 
> size, and the sharp driver multiplies that value by an interleave of 4 
> chips to set the erase size.  What erase size is set under the new 

I'm currently using:

        {
                .mfr_id         = 0x00b0,
                .dev_id         = 0x00b0,
                .name           = "Collie hack",
                .uaddr          = {
                        [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
                },
                .DevSize        = SIZE_4MiB,
                .CmdSet         = P_ID_INTEL_STD,
                .NumEraseRegions= 1,
                .regions        = {
                        ERASEINFO(0x10000,64),
                }
        },

...so I should use ERASEINFO(0x40000,16)?

> setup?  cat /proc/mtd or set loglevel for KERN_DEBUG at chip probe time. 
>  The new code is setting it based on what was read from the CFI query 
> info reported by the chip times the interleave factor (which apparently 
> should be set as 4 after detecting 4 chips if CONFIG_MTD_CFI_I4=y).

I do not have collie with me right now.
								Pavel
-- 
Thanks, Sharp!

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

* Re: latest mtd changes broke collie
  2005-11-13 10:35                         ` Ian Campbell
@ 2005-11-14 12:10                           ` Pavel Machek
  0 siblings, 0 replies; 26+ messages in thread
From: Pavel Machek @ 2005-11-14 12:10 UTC (permalink / raw)
  To: Ian Campbell; +Cc: kernel list, David Woodhouse, linux-mtd, Todd Poynor

Hi!

> > I tried this one. Size 0xc0000 is reported as a "bootloader" during
> > boot. 
> > 
> > [Plus I get a warning from jffs2 that flashsize is not aligned to
> > erasesize. Then I get lot of messages that empty flash at XXX ends at
> > XXX.]
> 
> What erase size did you end up using? Is 0xc0000 a multiple of it?

I ended up using ERASEINFO(0x10000,64), but I should probably be using
ERASEINFO(0x40000,16).

> > +	subdev->mtd->unlock(subdev->mtd, 0xc0000, subdev->mtd->size);
> 
> Probably unrelated to the actual problems, but shouldn't that be
> subdev->mtd->size - 0xc0000 at the end?

Fixed, thanks.
								Pavel
-- 
Thanks, Sharp!

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

end of thread, other threads:[~2005-11-14 15:33 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-09 22:17 latest mtd changes broke collie Pavel Machek
2005-11-10  0:19 ` Josh Boyer
2005-11-10  9:48   ` Pavel Machek
2005-11-10  2:59 ` Todd Poynor
2005-11-10  9:50   ` Pavel Machek
2005-11-10 10:02     ` David Woodhouse
2005-11-10 10:38       ` Pavel Machek
2005-11-10 10:51         ` David Woodhouse
2005-11-10 10:59           ` Pavel Machek
2005-11-10 11:11             ` David Woodhouse
2005-11-10 11:44               ` Pavel Machek
2005-11-10 12:07               ` Pavel Machek
2005-11-10 13:02                 ` David Vrabel
2005-11-10 13:09                   ` Pavel Machek
2005-11-10 17:41                     ` Richard Purdie
2005-11-10 18:09                       ` Richard Purdie
2005-11-10 22:06                         ` Pavel Machek
2005-11-10 22:41               ` Pavel Machek
2005-11-10 23:58                 ` Todd Poynor
2005-11-11  0:16                   ` Pavel Machek
2005-11-11  7:01                     ` Ian Campbell
2005-11-12 21:33                       ` Pavel Machek
2005-11-13 10:35                         ` Ian Campbell
2005-11-14 12:10                           ` Pavel Machek
2005-11-13 19:40                         ` Todd Poynor
2005-11-14 12:08                           ` Pavel Machek

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