Hi,
We have built a some devices for the purpose of energy management,
i.e. lots of on board A/D I/O as well as ethernet, RS232/485, Dallas Bus etc.
It currently has a 2.5 inch IDE drive inside too.
I also had space reserved on the board for two Toshiba 8 megabyte Nand-Flash
chips. They present themselves in the I/O space using 4 I/O ports. I really need
to
use FTL for obvious reasons (at least to those familiar with flash technology).
I have written a loadable module that can do simple reads and writes (although
very inefficiently) as directed by VFS. Sometimes it even works. I have at times
managed to create an ext2 filesystem on the devices but under load my machine
just stops.
The driver is not interrupt driven so I have to poll the devices to see when an
erase
or write cycle etc. has completed. I don't care if it is a little slow but other
processes
should not be impeded.
In the strategy routine an erase cycle will be started, a kernel timer
(timer_list) is set
to wait for 1 jiffie (10 milliseconds), then I do sleep_on() and wait for the
timer function
to be called where I will check the Nand Flash status again before continuing. I
only
three times max before giving up.
Does this sound right? Here are some code snippets
static struct wait_queue *flash_wait = NULL;
static struct timer_list flash_timer;
** The flash_timer struct is initialized elsewhere (init_module)
/* The polling really occurs in the Erase and Write routines */
void nfd_poll(unsigned long data) {
wake_up(&flash_wait);
}
/* Called indirectly from the strategy routine - nfd_request */
int
nfd_erase_block (unsigned int block)
{
unsigned char a1, a2;
int timeout;
printk("NFD: nfd_erase_block(%d) \n", block);
a1 = (block << 4) & 0xff;
a2 = (block >> 4) & 0xff;
outb(ERASE, NF_COMMAND);
outb(a1, NF_ADDRESS);
outb(a2, NF_ADDRESS);
udelay(100);
outb(RESUME, NF_COMMAND);
outb(STATUS, NF_COMMAND);
timeout = 3;
while (!(inb(NF_DATA) & READY)) {
printk("NFD: nfd_erase_block is waiting.\n");
if (!timeout--) {
printk("NFD: nfd_erase_block timeout!\n");
return 0;
}
flash_timer.expires = jiffies + 1;
add_timer(&flash_timer);
sleep_on(&flash_wait);
}
printk("NFD: nfd_erase_block is done.\n");
return (inb(NF_DATA) & 0x01);
}
Any comments will be greatly appreciated.
Regards,
Mike Cruse
Conservation Through Innovation
www.cti-ltd.com
--------------F5BF2457FCB8F0D51B92767F
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit
Hi,
We have built a some devices for the purpose of energy management,
i.e. lots of on board A/D I/O as well as ethernet, RS232/485, Dallas
Bus etc.
It currently has a 2.5 inch IDE drive inside too.
I also had space reserved on the board for two Toshiba 8 megabyte Nand-Flash
chips. They present themselves in the I/O space using 4 I/O ports.
I really need to
use FTL for obvious reasons (at least to those familiar with flash
technology).
I have written a loadable module that can do simple reads and writes
(although
very inefficiently) as directed by VFS. Sometimes it even works. I
have at times
managed to create an ext2 filesystem on the devices but under load
my machine
just stops.
The driver is not interrupt driven so I have to poll the devices to
see when an erase
or write cycle etc. has completed. I don't care if it is a little slow
but other processes
should not be impeded.
In the strategy routine an erase cycle will be started, a kernel timer
(timer_list) is set
to wait for 1 jiffie (10 milliseconds), then I do sleep_on() and wait
for the timer function
to be called where I will check the Nand Flash status again before
continuing. I only
three times max before giving up.
Does this sound right? Here are some code snippets
static struct wait_queue *flash_wait = NULL;
static struct timer_list flash_timer;
** The flash_timer struct is initialized elsewhere (init_module)
/* The polling really occurs in the Erase and Write routines */
void nfd_poll(unsigned long data) {
wake_up(&flash_wait);
}
/* Called indirectly from the strategy routine - nfd_request */
int
nfd_erase_block (unsigned int block)
{
unsigned char a1, a2;
int timeout;
printk("NFD: nfd_erase_block(%d) \n", block);
a1 = (block << 4) & 0xff;
a2 = (block >> 4) & 0xff;
outb(ERASE, NF_COMMAND);
outb(a1, NF_ADDRESS);
outb(a2, NF_ADDRESS);
udelay(100);
outb(RESUME, NF_COMMAND);
outb(STATUS, NF_COMMAND);
timeout = 3;
while (!(inb(NF_DATA) & READY)) {
printk("NFD: nfd_erase_block is waiting.\n");
if (!timeout--) {
printk("NFD: nfd_erase_block
timeout!\n");
return 0;
}
flash_timer.expires = jiffies + 1;
add_timer(&flash_timer);
sleep_on(&flash_wait);
}
printk("NFD: nfd_erase_block is done.\n");
return (inb(NF_DATA) & 0x01);
}
Any comments will be greatly appreciated.
Regards,
Mike Cruse
Conservation Through Innovation
www.cti-ltd.com
--------------F5BF2457FCB8F0D51B92767F--