📄 ide.c
字号:
/* drivers/mtd/nand/ide.c * * Copyright (C) 2005 William J Beksi <wjbeksi@users.sourceforge.net> * * Overview: * This 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#ifdef CONFIG_MTD_NAND_USE_IO_INSTRstatic int nand_use_io_instr = 1;#elsestatic int nand_use_io_instr = 0;#endif#ifdef CONFIG_MTD_NAND_X86_IO_INSTRstatic int nand_x86_io_instr = 1;#endif/* * 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; }}static u_char ide_read_byte(struct mtd_info *mtd){ struct nand_chip *this = (struct nand_chip *)mtd->priv; if (nand_use_io_instr) { if (nand_x86_io_instr) return inb((unsigned int) this->IO_ADDR_R); } return readb(this->IO_ADDR_R);}static void ide_write_byte(struct mtd_info *mtd, u_char byte){ struct nand_chip *this = (struct nand_chip *)mtd->priv; switch (nand_use_io_instr) { case 0: writeb(byte, this->IO_ADDR_W); break; case 1: if (nand_x86_io_instr) outb(byte, (unsigned int)this->IO_ADDR_W); break; }}static void ide_read_buf(struct mtd_info *mtd, u_char *buf, int len){ int i; struct nand_chip *this = mtd->priv; switch(nand_use_io_instr) { case 0: for (i=0; i<len; i++) buf[i] = readb(this->IO_ADDR_R); break; case 1: for (i=0; i<len; i++) if (nand_x86_io_instr) buf[i] = inb((unsigned int)this->IO_ADDR_R); break; }}static void ide_write_buf(struct mtd_info *mtd, const u_char *buf, int len){ int i; struct nand_chip *this = (struct nand_chip *)mtd->priv; switch (nand_use_io_instr) { case 0: for (i=0; i<len; i++) writeb(buf[i], this->IO_ADDR_W); break; case 1: for (i=0; i<len; i++) if (nand_x86_io_instr) outb(buf[i], (unsigned int) this->IO_ADDR_W); break; }}static int ide_verify_buf(struct mtd_info *mtd, const u_char *buf, int len){ int i; struct nand_chip *this = (struct nand_chip *)mtd->priv; switch (nand_use_io_instr) { case 0: for (i=0; i<len; i++) if (buf[i] != readb(this->IO_ADDR_R)) return -EFAULT; break; case 1: for (i=0; i<len; i++) if (nand_x86_io_instr) if (buf[i] != inb((unsigned int) this->IO_ADDR_R)) return -EFAULT; break; } return 0;}/* * Main initialization routine */int __init ide_init(void){ struct nand_chip *this; /* 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"); return -ENOMEM; } /* 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 read/write functions */ this->read_buf = ide_read_buf; this->read_byte = ide_read_byte; this->write_buf = ide_write_buf; this->write_byte = ide_write_byte; this->verify_buf = ide_verify_buf; /* 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)) { kfree(ide_mtd); return -ENXIO; } /* Register the partitions */ add_mtd_partitions(ide_mtd, partition_info, NUM_PARTITIONS); return 0;}module_init(ide_init);/* * Clean up routine */#ifdef MODULEstatic 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);#endifMODULE_LICENSE("GPL");MODULE_AUTHOR("William J Beksi <wjbeksi@users.sourceforge.net>");MODULE_DESCRIPTION("Glue layer for NAND flash through an IDE interface");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -