Skip to contentSkip to conversation

NAND I/O instruction support

PATCH In review William J Beksi 3 participants 4 messages Mar 31, 2005 – Apr 9, 2005 Memory technology devices (MTD)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 NAND I/O instruction support

This patch is to implement reading and writing nand flash by I/O instructions. I have only been able to test on the x86 architecture.

Questions, comments, criticisms are welcome.

Signature · 2 lines
William J Beksi                          <[email protected]>
GPG Key Fingerprint = ED4B 32C3 69E6 C2B7 705C  263F CB2F 3253 E7E1 DB3B

Index: drivers/mtd/nand/Kconfig
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/Kconfig,v retrieving revision 1.26

mtd/nand/Kconfig +15 -0
diff -u -r1.26 Kconfig
@@ -203,5 +203,20 @@
 	help
 	  The simulator may simulate verious NAND flash chips for the
 	  MTD nand layer.
+
+config MTD_NAND_USE_IO_INSTR
+       bool "Support for NAND Flash through the I/0 ports"
+       depends on MTD_NAND && MTD_PARTITIONS
+       help
+         Enables the driver for accessing NAND Flash through the I/O
+         ports. This can allow NAND Flash to be accessed from the IDE interface 
+         of a PC. If you say Y, you will be asked to select your architecture 
+         below. 
+
+config MTD_NAND_X86_IO_INSTR
+	bool "Support for x86 architecture I/O instructions"
+	depends on MTD_NAND_USE_IO_INSTR
+        help
+         Port numbers are of type unsigned int.
  
 endmenu

Index: drivers/mtd/nand/nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v retrieving revision 1.137

mtd/nand/nand_base.c +63 -10

109 lines not on this page · raw message

#1 lore raw
Quoted 3 lines · William J Beksi

This patch is to implement reading and writing nand flash by I/O instructions. I have only been able to test on the x86 architecture.

Questions, comments, criticisms are welcome.

Why didn't you use request_region()/release_region() to allocate IO ports?

I wonder, for what do you need this? Shouldn't you redefine nand_read_byte() and the like *in your driver* instead.

Signature · 3 lines
Best Regards,
Artem B. Bityuckiy,
St.-Petersburg, Russia.
#2 lore raw

Hi Artem,

Quoted 11 lines · Artem B. Bityuckiy
Quoted 3 lines · William J Beksi

This patch is to implement reading and writing nand flash by I/O instructions. I have only been able to test on the x86 architecture.

Questions, comments, criticisms are welcome.

Why didn't you use request_region()/release_region() to allocate IO ports?

I wonder, for what do you need this?

Because I want to use the *same* I/O port range as that used by the IDE interface on a PC. I think a look at my driver below will make things clearer ;)

Quoted 1 line

Shouldn't you redefine nand_read_byte() and the like *in your driver* instead.

Sure, it can be done like that. I am just not sure if this feature would be useful to other driver writers in the future, that is why I tried to make it as general as possible.

Thomas, should read/write using inb/outb be in my driver, or should this be in nand_base.c?

Thanks for your comments.
--
William

/* drivers/mtd/nand/ide.c
*
* Copyright (C) 2004 William J Beksi <[email protected]> *
* Overview:
* This device driver allows a NAND flash device to be accessed from
* an IDE interface.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/delay.h>
#include <asm/io.h>

/*
* Values specific to the IDE
*/
#define IDE_IO_BASE_1 0x1F0 /* IDE1 NAND flash I/O base address */
#define IDE_IO_BASE_2 0x170 /* IDE2 NAND flash I/O base address */

#define IDE_IO_BASE IDE_IO_BASE_1

/*
* IDE MTD structure
*/
static struct mtd_info *ide_mtd = NULL;

/*
* Define partitions for flash device
*/

const static struct mtd_partition partition_info[] = {
	{ 
		.name   = "IDE flash partition 1", 
		.offset = 0,  
		.size   = 4*1024*1024 
	},
	{
		.name   = "IDE flash partition 2",
		.offset = 4*1024*1024,
		.size   = 4*1024*1024
	}
};

#define NUM_PARTITIONS 2

static void ide_hwcontrol(struct mtd_info *mtd, int cmd)

{
	struct nand_chip *this = (struct nand_chip *) mtd->priv;

	switch (cmd) {
		case NAND_CTL_SETCLE: this->IO_ADDR_W = (unsigned char *) IDE_IO_BASE+1; break;
		case NAND_CTL_CLRCLE: this->IO_ADDR_W = (unsigned char *) IDE_IO_BASE;   break;
		case NAND_CTL_SETALE: this->IO_ADDR_W = (unsigned char *) IDE_IO_BASE+2; break;	
		case NAND_CTL_CLRALE: this->IO_ADDR_W = (unsigned char *) IDE_IO_BASE;   break;
	}
}

/*
* Main initialization routine
*/
int __init ide_init(void)

{
	struct nand_chip *this;
	int err = 0;

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

	/* Initialize structures */
	memset((char *) ide_mtd, 0, sizeof(struct mtd_info) + sizeof(struct nand_chip));

	/* Get pointer to private data */
	this = (struct nand_chip *) (&ide_mtd[1]);
	/* Link the private data with the MTD structure */
	ide_mtd->priv = this;

	/* Set address of NAND IO lines */
	this->IO_ADDR_R  = (void __iomem *) IDE_IO_BASE;
	this->IO_ADDR_W  = (void __iomem *) IDE_IO_BASE;
	/* Reference hardware control function */
	this->hwcontrol = ide_hwcontrol;
	/* Set command delay time */
	this->chip_delay = 20;
	/* Assign the device ready function */
	this->dev_ready = NULL;
	/* Set the ECC generator mode */
	this->eccmode = NAND_ECC_SOFT;

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

	/* Register the partitions */
	add_mtd_partitions(ide_mtd, partition_info, NUM_PARTITIONS);
	goto out;

out_mtd:

	kfree(ide_mtd);
out:
	return err;
}

module_init(ide_init);

/*
* Clean up routine
*/
#ifdef MODULE
static void __exit ide_cleanup (void)

{
	/* Release resources, unregister the device */
	nand_release(ide_mtd);	

	/* Free the MTD device structure */
	kfree(ide_mtd);
}

module_exit(ide_cleanup);
#endif

MODULE_LICENSE("GPL");
MODULE_AUTHOR("William J Beksi <[email protected]>"); MODULE_DESCRIPTION("Glue layer for NAND flash through an IDE interface");

#3 lore raw
Quoted 3 lines · William J Beksi

Because I want to use the *same* I/O port range as that used by the IDE interface on a PC. I think a look at my driver below will make things clearer ;)

Then this is rather hack then a standard thing. Hacks should stay in drivers IMO.

Signature · 3 lines
Best Regards,
Artem B. Bityuckiy,
St.-Petersburg, Russia.