summaryrefslogtreecommitdiffstats
path: root/Documentation/isapnp.txt
blob: 3de97b2752ad4b5d7787e192d50a53ecbeaa74fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
ISA Plug & Play support by Jaroslav Kysela <perex@suse.cz>
==========================================================

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

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

No comment..

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

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

card <idx> <vendor>	- select PnP device by vendor identification
csn <CSN>		- select PnP device by CSN
dev <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 format 'PNP0000'
	- <logdev> is in format 'PNP0000'

Example:

cat > /proc/isapnp <<EOF
card 0 CSC7537
dev 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 pci_bus *isapnp_find_card(unsigned short vendor,
                                        unsigned short device,
                                        struct pci_bus *from);

This function finds a ISA PnP card. 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 taken from contents
of the /proc/isapnp file.

extern struct pci_dev *isapnp_find_dev(struct pci_bus *card,
                                       unsigned short vendor,
                                       unsigned short function,
                                       struct pci_dev *from);

This function finds the ISA PnP device. If card is NULL, then
the global search mode is used (all devices are used for the searching).
Otherwise only devices which belongs to the specified card are verified.
For the function number can be used ISAPNP_FUNCTION(x) macro which works
similarly as the ISAPNP_DEVICE(x) macro.

extern int isapnp_probe_cards(const struct isapnp_card_id *ids,
			      int (*probe)(struct pci_bus *card,
					   const struct isapnp_card_id *id));


This function is a helper for drivers which requires to use more than
one device from an ISA PnP card. For each cards is called the probe
callback with appropriate information.

Example for ids parameter initialization:

static struct isapnp_card_id card_ids[] __devinitdata = {
	{
        	ISAPNP_CARD_ID('A','D','V', 0x550a),
                devs: {
			ISAPNP_DEVICE_ID('A', 'D', 'V', 0x0010),
			ISAPNP_DEVICE_ID('A', 'D', 'V', 0x0011)
		},
		driver_data: 0x1234,
	},
	{
		ISAPNP_CARD_END,
	}
};
ISAPNP_CARD_TABLE(card_ids);

extern int isapnp_probe_devs(const struct isapnp_device_id *ids,
			     int (*probe)(struct pci_bus *card,
					  const struct isapnp_device_id *id));


This function is a helper for drivers which requires to use one
device from an ISA PnP card. For each matched devices is called the probe
callback with appropriate information.

Example for ids parameter initialization:

static struct isapnp_device_id device_ids[] __devinitdata = {
	{ ISAPNP_DEVICE_SINGLE('E','S','S', 0x0968, 'E','S','S', 0x0968), },
	{ ISAPNP_DEVICE_SINGLE_END, }
};
MODULE_DEVICE_TABLE(isapnp, device_ids);


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_(read|write)_(byte|word|dword) functions.

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
--------------------------------

This feature gives to the driver the real power of the ISA PnP code.
Function dev->prepare() initializes the resource members in the device
structure. This structure contains all resources set to auto configuration
values after the initialization. The device driver may modify some resources
to skip the auto configuration for a given resource.

Once the device structure contains all requested resource values, the function
dev->activate() must be called to assign free resources to resource members
with the auto configuration value.

Function dev->activate() does:
	- resources with 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

When the device driver is removing, function dev->deactivate() has to be
called to free all assigned resources.

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

/*** initialization ***/

	struct pci_dev *dev;

	/* find the first game port, use standard PnP IDs */
	dev = isapnp_find_dev(NULL,
			      ISAPNP_VENDOR('P','N','P'),
			      ISAPNP_FUNCTION(0xb02f),
			      NULL);
	if (!dev)
		return -ENODEV;
	if (dev->active)
		return -EBUSY;
	if (dev->prepare(dev)<0)
		return -EAGAIN;
	if (!(dev->resource[0].flags & IORESOURCE_IO))
		return -ENODEV;
	if (!dev->ro) {
		/* override resource */
		if (user_port != USER_PORT_AUTO_VALUE)
			isapnp_resource_change(&dev->resource[0], user_port, 1);
	}
	if (dev->activate(dev)<0) {
		printk("isapnp configure failed (out of resources?)\n");
		return -ENOMEM;
	}
	user_port = dev->resource[0].start;		/* get real port */

/*** deactivation ***/

	/* to deactivate use: */
 	if (dev)
 		dev->deactivate(dev);