Embedded Linux, FFS, VFS help

Mike Cruse (mcruse@cti-ltd.com)
Tue, 09 Sep 1997 16:24:46 -0700


--------------F5BF2457FCB8F0D51B92767F
Content-Type: text/plain; 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
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--