Beispiel #1
0
static void
eraseflash(Flash *f, Flashregion *r, ulong addr)
{
	int rv;

	if(f->protect && r != nil && r->start == 0 && addr < r->erasesize)
		error(Eprotect);
	qlock(f);
	archflashwp(f, 0);
	if(waserror()){
		archflashwp(f, 1);
		qunlock(f);
		nexterror();
	}
	if(r == nil){
		if(f->eraseall != nil)
			rv = f->eraseall(f);
		else
			rv = -1;
	}else
		rv = f->erasezone(f, r, addr);
	if(rv < 0)
		error(Eio);
	poperror();
	archflashwp(f, 1);
	qunlock(f);
}
Beispiel #2
0
static long
writeflash(Flash *f, long offset, void *buf, int n)
{
	uchar tmp[16];
	uchar *p;
	ulong o;
	int r, width, wmask;
	Flashregion *rg;

	if(f->write == nil || offset < 0 || offset+n > f->size)
		error(Ebadarg);
	rg = flashregion(f, offset);
	if(f->protect && rg != nil && rg->start == 0 && offset < rg->erasesize)
		error(Eprotect);
	width = f->width;
	wmask = width-1;
	qlock(f);
	archflashwp(f, 0);
	if(waserror()){
		archflashwp(f, 1);
		qunlock(f);
		nexterror();
	}
	p = buf;
	if(offset&wmask){
		o = offset & ~wmask;
		if(f->read != nil){
			if(f->read(f, o, tmp, width) < 0)
				error(Eio);
		}else
			memmove(tmp, (uchar*)f->addr+o, width);
		for(; n > 0 && offset&wmask; n--)
			tmp[offset++&wmask] = *p++;
		if(f->write(f, o, tmp, width) < 0)
			error(Eio);
	}
	r = n&wmask;
	n &= ~wmask;
	if(n){
		if(f->write(f, offset, p, n) < 0)
			error(Eio);
		offset += n;
		p += n;
	}
	if(r){
		if(f->read != nil){
			if(f->read(f, offset, tmp, width) < 0)
				error(Eio);
		}else
			memmove(tmp, (uchar*)f->addr+offset, width);
		memmove(tmp, p, r);
		if(f->write(f, offset, tmp, width) < 0)
			error(Eio);
	}
	poperror();
	archflashwp(f, 1);
	qunlock(f);
	return n;
}
Beispiel #3
0
/*
 * Clean up routine
 */
static void __exit toto_cleanup (void)
{
	/* Release resources, unregister device */
	nand_release (toto_mtd);

	/* Free the MTD device structure */
	kfree (toto_mtd);

	/* stop flash writes */
	 archflashwp(0,1);
	
	/* release gpios to system */
	 gpiorelease(NAND_MASK);
}
Beispiel #4
0
/*
 * Main initialization routine
 */
int __init toto_init (void)
{
	struct nand_chip *this;
	int err = 0;

	/* Allocate memory for MTD device structure and private data */
	toto_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
				GFP_KERNEL);
	if (!toto_mtd) {
		printk (KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n");
		err = -ENOMEM;
		goto out;
	}

	/* Get pointer to private data */
	this = (struct nand_chip *) (&toto_mtd[1]);

	/* Initialize structures */
	memset((char *) toto_mtd, 0, sizeof(struct mtd_info));
	memset((char *) this, 0, sizeof(struct nand_chip));

	/* Link the private data with the MTD structure */
	toto_mtd->priv = this;

	/* Set address of NAND IO lines */
	this->IO_ADDR_R = toto_io_base;
	this->IO_ADDR_W = toto_io_base;
	this->hwcontrol = toto_hwcontrol;
	this->dev_ready = NULL;
	/* 25 us command delay time */
	this->chip_delay = 30;		
	this->eccmode = NAND_ECC_SOFT;

        /* Scan to find existance of the device */
	if (nand_scan (toto_mtd, 1)) {
		err = -ENXIO;
		goto out_mtd;
	}

	/* Register the partitions */
	switch(toto_mtd->size){
		case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break; 
		case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break; 
		default: {
			printk (KERN_WARNING "Unsupported Nand device\n"); 
			err = -ENXIO;
			goto out_buf;
		}
	}

    	gpioreserve(NAND_MASK);  /* claim our gpios */
    	archflashwp(0,0);	 /* open up flash for writing */

	goto out;
    
out_buf:
	kfree (this->data_buf);    
out_mtd:
	kfree (toto_mtd);
out:
	return err;
}