ISA Plug & Play support by Jaroslav Kysela <perex@suse.cz>
=========================================================

Please, notice that the device and the logical device are two different
things. The device is whole ISA PnP card and the logical device is part
of a ISA PnP card.

Interface /proc/isapnp
======================

Read commands:
--------------

No comment..

Write commands:
---------------

With write interface you can simply activate or modify the configuration
for ISA Plug & Play devices. It is mainly useable for drivers which don't
use the ISA Plug & Play kernel support yet.

device <idx> <vendor>	- select PnP device by vendor identification
csn <CSN>		- select PnP device by CSN
logdev <idx> <logdev>	- select logical device
auto			- run autoconfigure
activate		- activate logical device
deactivate		- deactivate logical device
port <idx> <value>	- set port 0-7 to value
irq <idx> <value>	- set IRQ 0-1 to value
dma <idx> <value>	- set DMA 0-1 to value
memory <idx> <value>	- set memory 0-3 to value
poke <reg> <value>	- poke configuration byte to selected register
pokew <reg> <value>	- poke configuration word to selected register
poked <reg> <value>	- poke configuration dword to selected register

Explanation:
	- variable <idx> begins with zero
	- variable <CSN> begins with one
	- <vendor> is in form 'PNP0000'
	- <logdev> is in form 'PNP0000'

Example:

cat > /proc/isapnp <<EOF
device 0 CSC7537
logdev 0 CSC0000
port 0 0x534
port 1 0x388
port 2 0x220
irq 0 5
dma 0 1
dma 1 3
poke 0x70 9
activate
logdev 0 CSC0001
port 0 0x240
activate
EOF

Information for developers
==========================

Finding appropriate device
--------------------------

extern struct isapnp_dev *isapnp_find_device(unsigned short vendor,
                                             unsigned short device,
                                             int index);

The above function finds the device by index. For the vendor device should
be used ISAPNP_VENDOR(a,b,c) where a,b,c are characters or integers.
For the device number should be used ISAPNP_DEVICE(x) macro where x is
integer value. Both vendor and device numbers can be get from contents
of the /proc/isapnp file.

extern struct isapnp_logdev *isapnp_find_logdev(struct isapnp_dev *dev,
                                                unsigned short vendor,
                                                unsigned short function,
                                                int index) { return NULL; }

The above function finds the logical device by index. If dev is NULL, then
the global search mode is used (all devices are used for the searching).
For the function number can be used ISAPNP_FUNCTION(x) macro which works
similarly as the ISAPNP_DEVICE(x) macro.

ISA PnP configuration
=====================

There are two ways how can be ISA PnP interface used.

First way is lowlevel
---------------------

All ISA PNP configuration registers are accessible via lowlevel
isapnp_cfg_(set|get)_(byte|word|dword) functions.

Before any lowlevel function 
The function isapnp_cfg_begin() must be called before any lowlevel function.
The function isapnp_cfg_end() must be always called after configuration
otherwise the access to the ISA PnP configuration functions will be blocked.

Second way is auto-configuration
--------------------------------

These two functions gives to the driver the real power of the ISA PnP
feature. First function isapnp_config_init() only initialize the
isapnp_config structure. This structure contains all resources set to
auto configuration values after the initialization. The driver for ISA PnP
logical device may modify (or not) some resources to skip auto configuration
for the given resource. The driver for ISA PnP logical device can also
pass to the isapnp_configure() function that some resources are already
used by the another logical device over *_disable members of the
isapnp_config structure.

The function isapnp_configure does:
	- resources which have the auto configuration value are configured
	- the auto configuration is created using ISA PnP resource map
	- the function writes configuration to ISA PnP configuration registers
	- the function returns to the caller actual used resources

Example (game port initialization)
==================================

/*** initialization ***/

	struct isapnp_logdev *logdev;
	struct isapnp_config cfg;

	/* find the first game port, use standard PnP IDs */
	logdev = isapnp_find_logdev(ISAPNP_VENDOR('P','N','P'),
				    ISAPNP_FUNCTION(0xb02f),
				    0);
	if (!logdev)
		return -ENODEV;
	if (isapnp_cfg_begin(logdev->dev->csn, logdev->number)<0)
		return -EAGAIN;
	if (isapnp_config_init(&cfg, logdev)<0) {
		isapnp_cfg_end();
		return -EAGAIN;
	}
	if (user_port != USER_PORT_AUTO_VALUE)
		cfg.port[0] = user_port;	/* override resource */
	if (isapnp_configure(&cfg)<0) {
		printk("isapnp configure failed (out of resources?)\n");
		isapnp_cfg_end();
		return -ENOMEM;
	}
	user_port = cfg.port[0];		/* get real port */
	isapnp_activate(logdev->number);	/* activate device */
	isapnp_cfg_end();

/*** deactivation ***/

	/* to deactivate use: */
	if (isapnp_cfg_begin(logdev->dev->csn, logdev->number)<0)
		return -EAGAIN;
	isapnp_deactivate(logdev->number);
	isapnp_cfg_end();
