1 |
62 |
marcus.erl |
Linux Plug and Play Documentation
|
2 |
|
|
by Adam Belay
|
3 |
|
|
last updated: Oct. 16, 2002
|
4 |
|
|
---------------------------------------------------------------------------------------
|
5 |
|
|
|
6 |
|
|
|
7 |
|
|
|
8 |
|
|
Overview
|
9 |
|
|
--------
|
10 |
|
|
Plug and Play provides a means of detecting and setting resources for legacy or
|
11 |
|
|
otherwise unconfigurable devices. The Linux Plug and Play Layer provides these
|
12 |
|
|
services to compatible drivers.
|
13 |
|
|
|
14 |
|
|
|
15 |
|
|
|
16 |
|
|
The User Interface
|
17 |
|
|
------------------
|
18 |
|
|
The Linux Plug and Play user interface provides a means to activate PnP devices
|
19 |
|
|
for legacy and user level drivers that do not support Linux Plug and Play. The
|
20 |
|
|
user interface is integrated into driverfs.
|
21 |
|
|
|
22 |
|
|
In addition to the standard driverfs file the following are created in each
|
23 |
|
|
device's directory:
|
24 |
|
|
id - displays a list of support EISA IDs
|
25 |
|
|
options - displays possible resource configurations
|
26 |
|
|
resources - displays currently allocated resources and allows resource changes
|
27 |
|
|
|
28 |
|
|
-activating a device
|
29 |
|
|
|
30 |
|
|
#echo "auto" > resources
|
31 |
|
|
|
32 |
|
|
this will invoke the automatic resource config system to activate the device
|
33 |
|
|
|
34 |
|
|
-manually activating a device
|
35 |
|
|
|
36 |
|
|
#echo "manual " > resources
|
37 |
|
|
- the configuration number
|
38 |
|
|
- static or dynamic
|
39 |
|
|
static = for next boot
|
40 |
|
|
dynamic = now
|
41 |
|
|
|
42 |
|
|
-disabling a device
|
43 |
|
|
|
44 |
|
|
#echo "disable" > resources
|
45 |
|
|
|
46 |
|
|
|
47 |
|
|
EXAMPLE:
|
48 |
|
|
|
49 |
|
|
Suppose you need to activate the floppy disk controller.
|
50 |
|
|
1.) change to the proper directory, in my case it is
|
51 |
|
|
/driver/bus/pnp/devices/00:0f
|
52 |
|
|
# cd /driver/bus/pnp/devices/00:0f
|
53 |
|
|
# cat name
|
54 |
|
|
PC standard floppy disk controller
|
55 |
|
|
|
56 |
|
|
2.) check if the device is already active
|
57 |
|
|
# cat resources
|
58 |
|
|
DISABLED
|
59 |
|
|
|
60 |
|
|
- Notice the string "DISABLED". THis means the device is not active.
|
61 |
|
|
|
62 |
|
|
3.) check the device's possible configurations (optional)
|
63 |
|
|
# cat options
|
64 |
|
|
Dependent: 01 - Priority acceptable
|
65 |
|
|
port 0x3f0-0x3f0, align 0x7, size 0x6, 16-bit address decoding
|
66 |
|
|
port 0x3f7-0x3f7, align 0x0, size 0x1, 16-bit address decoding
|
67 |
|
|
irq 6
|
68 |
|
|
dma 2 8-bit compatible
|
69 |
|
|
Dependent: 02 - Priority acceptable
|
70 |
|
|
port 0x370-0x370, align 0x7, size 0x6, 16-bit address decoding
|
71 |
|
|
port 0x377-0x377, align 0x0, size 0x1, 16-bit address decoding
|
72 |
|
|
irq 6
|
73 |
|
|
dma 2 8-bit compatible
|
74 |
|
|
|
75 |
|
|
4.) now activate the device
|
76 |
|
|
# echo "auto" > resources
|
77 |
|
|
|
78 |
|
|
5.) finally check if the device is active
|
79 |
|
|
# cat resources
|
80 |
|
|
io 0x3f0-0x3f5
|
81 |
|
|
io 0x3f7-0x3f7
|
82 |
|
|
irq 6
|
83 |
|
|
dma 2
|
84 |
|
|
|
85 |
|
|
also there are a series of kernel parameters:
|
86 |
|
|
pnp_reserve_irq=irq1[,irq2] ....
|
87 |
|
|
pnp_reserve_dma=dma1[,dma2] ....
|
88 |
|
|
pnp_reserve_io=io1,size1[,io2,size2] ....
|
89 |
|
|
pnp_reserve_mem=mem1,size1[,mem2,size2] ....
|
90 |
|
|
|
91 |
|
|
|
92 |
|
|
|
93 |
|
|
The Unified Plug and Play Layer
|
94 |
|
|
-------------------------------
|
95 |
|
|
All Plug and Play drivers, protocols, and services meet at a central location
|
96 |
|
|
called the Plug and Play Layer. This layer is responsible for the exchange of
|
97 |
|
|
information between PnP drivers and PnP protocols. Thus it automatically
|
98 |
|
|
forwards commands to the proper protocol. This makes writing PnP drivers
|
99 |
|
|
significantly easier.
|
100 |
|
|
|
101 |
|
|
The following functions are available from the Plug and Play Layer:
|
102 |
|
|
|
103 |
|
|
pnp_get_protocol
|
104 |
|
|
- increments the number of uses by one
|
105 |
|
|
|
106 |
|
|
pnp_put_protocol
|
107 |
|
|
- deincrements the number of uses by one
|
108 |
|
|
|
109 |
|
|
pnp_register_protocol
|
110 |
|
|
- use this to register a new PnP protocol
|
111 |
|
|
|
112 |
|
|
pnp_unregister_protocol
|
113 |
|
|
- use this function to remove a PnP protocol from the Plug and Play Layer
|
114 |
|
|
|
115 |
|
|
pnp_register_driver
|
116 |
|
|
- adds a PnP driver to the Plug and Play Layer
|
117 |
|
|
- this includes driver model integration
|
118 |
|
|
- returns zero for success or a negative error number for failure; count
|
119 |
|
|
calls to the .add() method if you need to know how many devices bind to
|
120 |
|
|
the driver
|
121 |
|
|
|
122 |
|
|
pnp_unregister_driver
|
123 |
|
|
- removes a PnP driver from the Plug and Play Layer
|
124 |
|
|
|
125 |
|
|
|
126 |
|
|
|
127 |
|
|
Plug and Play Protocols
|
128 |
|
|
-----------------------
|
129 |
|
|
This section contains information for PnP protocol developers.
|
130 |
|
|
|
131 |
|
|
The following Protocols are currently available in the computing world:
|
132 |
|
|
- PNPBIOS: used for system devices such as serial and parallel ports.
|
133 |
|
|
- ISAPNP: provides PnP support for the ISA bus
|
134 |
|
|
- ACPI: among its many uses, ACPI provides information about system level
|
135 |
|
|
devices.
|
136 |
|
|
It is meant to replace the PNPBIOS. It is not currently supported by Linux
|
137 |
|
|
Plug and Play but it is planned to be in the near future.
|
138 |
|
|
|
139 |
|
|
|
140 |
|
|
Requirements for a Linux PnP protocol:
|
141 |
|
|
1.) the protocol must use EISA IDs
|
142 |
|
|
2.) the protocol must inform the PnP Layer of a devices current configuration
|
143 |
|
|
- the ability to set resources is optional but preferred.
|
144 |
|
|
|
145 |
|
|
The following are PnP protocol related functions:
|
146 |
|
|
|
147 |
|
|
pnp_add_device
|
148 |
|
|
- use this function to add a PnP device to the PnP layer
|
149 |
|
|
- only call this function when all wanted values are set in the pnp_dev
|
150 |
|
|
structure
|
151 |
|
|
|
152 |
|
|
pnp_init_device
|
153 |
|
|
- call this to initialize the PnP structure
|
154 |
|
|
|
155 |
|
|
pnp_remove_device
|
156 |
|
|
- call this to remove a device from the Plug and Play Layer.
|
157 |
|
|
- it will fail if the device is still in use.
|
158 |
|
|
- automatically will free mem used by the device and related structures
|
159 |
|
|
|
160 |
|
|
pnp_add_id
|
161 |
|
|
- adds a EISA ID to the list of supported IDs for the specified device
|
162 |
|
|
|
163 |
|
|
For more information consult the source of a protocol such as
|
164 |
|
|
/drivers/pnp/pnpbios/core.c.
|
165 |
|
|
|
166 |
|
|
|
167 |
|
|
|
168 |
|
|
Linux Plug and Play Drivers
|
169 |
|
|
---------------------------
|
170 |
|
|
This section contains information for linux PnP driver developers.
|
171 |
|
|
|
172 |
|
|
The New Way
|
173 |
|
|
...........
|
174 |
|
|
1.) first make a list of supported EISA IDS
|
175 |
|
|
ex:
|
176 |
|
|
static const struct pnp_id pnp_dev_table[] = {
|
177 |
|
|
/* Standard LPT Printer Port */
|
178 |
|
|
{.id = "PNP0400", .driver_data = 0},
|
179 |
|
|
/* ECP Printer Port */
|
180 |
|
|
{.id = "PNP0401", .driver_data = 0},
|
181 |
|
|
{.id = ""}
|
182 |
|
|
};
|
183 |
|
|
|
184 |
|
|
Please note that the character 'X' can be used as a wild card in the function
|
185 |
|
|
portion (last four characters).
|
186 |
|
|
ex:
|
187 |
|
|
/* Unknown PnP modems */
|
188 |
|
|
{ "PNPCXXX", UNKNOWN_DEV },
|
189 |
|
|
|
190 |
|
|
Supported PnP card IDs can optionally be defined.
|
191 |
|
|
ex:
|
192 |
|
|
static const struct pnp_id pnp_card_table[] = {
|
193 |
|
|
{ "ANYDEVS", 0 },
|
194 |
|
|
{ "", 0 }
|
195 |
|
|
};
|
196 |
|
|
|
197 |
|
|
2.) Optionally define probe and remove functions. It may make sense not to
|
198 |
|
|
define these functions if the driver already has a reliable method of detecting
|
199 |
|
|
the resources, such as the parport_pc driver.
|
200 |
|
|
ex:
|
201 |
|
|
static int
|
202 |
|
|
serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const
|
203 |
|
|
struct pnp_id *dev_id)
|
204 |
|
|
{
|
205 |
|
|
. . .
|
206 |
|
|
|
207 |
|
|
ex:
|
208 |
|
|
static void serial_pnp_remove(struct pnp_dev * dev)
|
209 |
|
|
{
|
210 |
|
|
. . .
|
211 |
|
|
|
212 |
|
|
consult /drivers/serial/8250_pnp.c for more information.
|
213 |
|
|
|
214 |
|
|
3.) create a driver structure
|
215 |
|
|
ex:
|
216 |
|
|
|
217 |
|
|
static struct pnp_driver serial_pnp_driver = {
|
218 |
|
|
.name = "serial",
|
219 |
|
|
.card_id_table = pnp_card_table,
|
220 |
|
|
.id_table = pnp_dev_table,
|
221 |
|
|
.probe = serial_pnp_probe,
|
222 |
|
|
.remove = serial_pnp_remove,
|
223 |
|
|
};
|
224 |
|
|
|
225 |
|
|
* name and id_table cannot be NULL.
|
226 |
|
|
|
227 |
|
|
4.) register the driver
|
228 |
|
|
ex:
|
229 |
|
|
|
230 |
|
|
static int __init serial8250_pnp_init(void)
|
231 |
|
|
{
|
232 |
|
|
return pnp_register_driver(&serial_pnp_driver);
|
233 |
|
|
}
|
234 |
|
|
|
235 |
|
|
The Old Way
|
236 |
|
|
...........
|
237 |
|
|
|
238 |
|
|
a series of compatibility functions have been created to make it easy to convert
|
239 |
|
|
|
240 |
|
|
ISAPNP drivers. They should serve as a temporary solution only.
|
241 |
|
|
|
242 |
|
|
they are as follows:
|
243 |
|
|
|
244 |
|
|
struct pnp_card *pnp_find_card(unsigned short vendor,
|
245 |
|
|
unsigned short device,
|
246 |
|
|
struct pnp_card *from)
|
247 |
|
|
|
248 |
|
|
struct pnp_dev *pnp_find_dev(struct pnp_card *card,
|
249 |
|
|
unsigned short vendor,
|
250 |
|
|
unsigned short function,
|
251 |
|
|
struct pnp_dev *from)
|
252 |
|
|
|