Hmmm. Handling aliases of flash chips is far more of a pain
in the arse than I'd expected, but I think it should be more
or less working now.
Asynchronous operations on the flash chips are going to be
interesting. The erase function is called with the address
of a callback routine to be called when the requested erase
is complete. The erase gets started, then a timer is
scheduled to check whether it's finished or not at around
the time we expect it to be done. The erase function returns
immediately - most users of flash chips don't need to wait
around for erases to happen.
We need a mutex of some kind to prevent that timer from
trying to talk to the chip while other code is in the middle
of writing data to somewhere else in the chip. (Also to
prevent concurrent access on SMP systems)
A spinlock would mean I need spin_lock_bh() in the write()
code, which doesn't actually exist in 2.2, and would disable
bottom halves for quite a long time.
A semaphore is a possibility, obviously with down_trylock()
in the timer code - but if the timer code fails to get the
semaphore, what happens? Reschedule itself every jiffie
until it _does_ succeed?
Alternatively, I could start a kernel thread for each chip
to handle pending operations, and use either a spinlock or
semaphore without trouble. But is that too much overhead?
I suspect I'll end up using timers and semaphores, if I can
work out a race-free way for the timer to set a flag when
it's failed to obtain the lock, so that the write() function
can do the timer's job immediately after dropping the
semaphore. That shouldn't be too difficult, as long as
there's only one pending operation per chip, which for now
should be a reasonable assumption to make.
Hmmm. Today has been a high-caffeine intake day.