SmartDisk FlashPath DESIGN ALTERNATIVES DOCUMENT
------------------------------------------------
	Copyright (C) 2000 Linuxcare, Inc.
	Author:	Jason McMullan <jmcmullan@linuxcare.com>

Product:
--------

	SmartDisk Corporation FlashPath - A family of 3.5" diskette format
devices that are capable of presenting a flash memory device as
a FAT file system. I/O is performed via the SmartDisk protocol
through track 0, head 0, sectors 1-18 of the FlashPath device.

	The device runs on ``watch batteries'', and its electronics
allow it to run on any drive that is capable of reading 1.44Mb
floppies PROVIDED that the spin rate of the drive is 300RPM.
This is due to the fact that the internal clock of the 
FlashPath is fixed, and is not correlated to the drive spindle.


Design goal:
------------

	It should be transparent to the user whether they're using
a floppy or a FlashPath.

Device Driver Implementations:
------------------------------

	Final Driver Choice:	Inode Mangler
	Final I/O Choice:		Raw Floppy Commands

=============================
	Driver Implementations
=============================
******* Inode Mangler
	
	When the driver is loaded, it overrides the open(2) method of
/dev/fdX. If a flashpath is detected, the inode passed to open(2)
is ``mangled'' into a different device major.  Read/Write/Ioctl
will then be performed on the mangled inode -> the flashpath major.
When the flashpath close(2) routine is called, the inode is placed
into a timeout queue to be unmangled. After a short time, (2 secs?)
the inode is unmangled. 

	For mount(2) to work properly, we need to open/close (and mangle)
the inode _immediately_ before sys_mount is called. Therefore, the drive
modifies sys_call_table[__NR_mount] to point to a small routine that
1) determines if the dev_name passed to mount is a FLOPPY_MAJOR inode
2) opens the dev_name, 3) closes the (inode mangled) inode, then
4) calls the original sys_mount(). This was the sys_mount() call will
get the correct major number from the inode->i_rdev and do ``the right
thing''.


	PROS
	----
		Seamless to user.
		Small amount of state manglement.
		Easy to implement.

	CONS
	----
		Small race conditions may be possible with the inode mangler
		  on very slow (16Mhz i386 under high load) machines.


******* Switch Device

	/dev/fd0 is actually a switch device, that is NOT operating on
FLASHPATH_MAJOR. /dev/fd0 will ``automagically'' redirect to the
flashpath if there is an read() or write() to sector 0 of the
floppy by ``pre-reading'' sector 0, and determining if it is, indeed,
a FlashPath. Then, it will redirect all traffic to the appropriate
Major number's (struct file_operations *) and all will be well.

	/dev/fd0 is returned to its default state when FlashPath
returns an invalid media state.

	Some fixups on file->f_dentry->d_inode->i_rdev will need
to be done on pass-through open().

	PROS
	----
		Seamless to user
		Small amount of state mangling

	CONS
	----
		Always need to pre-read sector 0
		Requires changing /dev/fd[0-9] to be some other major,
			

******* Shared Major

	/dev/fd0 is BOTH a floppy and a FlashPath device. Here's the
trick: 

General
	1) Precreate the FlashPath structures for all the /dev/fdX 
	2) On open, do the normal floppy open.
	3) On close, do the normal floppy close.
	4) On ioctl, do the one appropriate for the state

Floppy Mode
	1) On read/write(!=0), do as normal
	2) On read/write(0), see if it's a FlashPath
			If so, change state to FlashPath

FlashPath Mode
	1) On read/write(), if we get a ``not a flashpath'' error,
	   invalidate the buffers and return to floppy state.

		

	PROS
	----
		Seamless to user
		No need to change /dev entries

	CONS
	----
		Hideous state manglement needed
		Lots and LOTS of race conditions.
		Have to mess around with a LOT of the block cache
			internals to get it to work.

	
******* Separate device

	/dev/fp0 is the FlashPath device. A daemon will watch /dev/fd0,
and periodically check it for an inserted FlashPath device. If so,
it'll notify the user/automount the device.

	PROS
	----
		Easy to implement

	CONS
	----
		Does not meet the spirit of the design goals

=============================
	I/O	Implementations
=============================
	
******** Raw Floppy Command

	Using the ``struct floppy_raw_cmd'' structure, directly send commands
to the low level floppy device.

	PROS
	----
		Uses ``known-to-work'' code from the original implementation.
		No block io handler races
		No block io deadlocks

	CONS
	----
		Specific to IBM-style floppies, will require different implementation
			for a PowerPC port.

******** Block read/write

	Unlock the io_request lock, and use the buffer handler interface to 
read/write blocks (sectors) to the underlying floppy device.

	PROS
	----
		Would work on IBM/Macintosh/Amiga/etc. floppies
		
	CONS
	----
		Races and deadlock conditions in the block I/O subsystem are
			almost assured if there are any locking errors.
		SMP safety is hard to assure.

******** File operations read/write

	Use the inode->f_op->{lseek,read,write} methods to perform the IO on the
underlying floppy device.

	PROS
	----
		Would work on IBM/Macintosh/Amiga/etc. floppies
		Simple code to understand
		
	CONS
	----
		Inappropriate combination of high/low level functionality
		Races and deadlock conditions in the block I/O subsystem are
			almost assured if there are any locking errors.
		SMP safety is hard to assure.

		


	
