Blame view

drivers/pnp/manager.c 9.79 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /*
   * manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices
   *
c1017a4cd   Jaroslav Kysela   [ALSA] Changed Ja...
4
   * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
   * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
6
7
   * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
   *	Bjorn Helgaas <bjorn.helgaas@hp.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
12
  #include <linux/errno.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
  #include <linux/pnp.h>
4e57b6817   Tim Schmielau   [PATCH] fix missi...
14
  #include <linux/bitmap.h>
b3bd86e2f   Daniel Walker   isapnp driver sem...
15
  #include <linux/mutex.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
  #include "base.h"
b3bd86e2f   Daniel Walker   isapnp driver sem...
17
  DEFINE_MUTEX(pnp_res_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18

13cde3b2a   Witold Szczeponik   PNP: Handle IORES...
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  static struct resource *pnp_find_resource(struct pnp_dev *dev,
  					  unsigned char rule,
  					  unsigned long type,
  					  unsigned int bar)
  {
  	struct resource *res = pnp_get_resource(dev, type, bar);
  
  	/* when the resource already exists, set its resource bits from rule */
  	if (res) {
  		res->flags &= ~IORESOURCE_BITS;
  		res->flags |= rule & IORESOURCE_BITS;
  	}
  
  	return res;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
  static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
36
  	struct resource *res, local_res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37

13cde3b2a   Witold Szczeponik   PNP: Handle IORES...
38
  	res = pnp_find_resource(dev, rule->flags, IORESOURCE_IO, idx);
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
39
  	if (res) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
40
  		pnp_dbg(&dev->dev, "  io %d already set to %#llx-%#llx "
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
41
42
43
  			"flags %#lx
  ", idx, (unsigned long long) res->start,
  			(unsigned long long) res->end, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
44
  		return 0;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
45
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
46
47
48
49
  	res = &local_res;
  	res->flags = rule->flags | IORESOURCE_AUTO;
  	res->start = 0;
  	res->end = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
  
  	if (!rule->size) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
52
  		res->flags |= IORESOURCE_DISABLED;
2f53432c2   Bjorn Helgaas   PNP: convert to u...
53
54
  		pnp_dbg(&dev->dev, "  io %d disabled
  ", idx);
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
55
  		goto __add;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  	}
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
57
58
  	res->start = rule->min;
  	res->end = res->start + rule->size - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59

f5d94ff01   Bjorn Helgaas   PNP: pass resourc...
60
  	while (!pnp_check_port(dev, res)) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
61
62
63
  		res->start += rule->align;
  		res->end = res->start + rule->size - 1;
  		if (res->start > rule->max || !rule->align) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
64
  			pnp_dbg(&dev->dev, "  couldn't assign io %d "
fcfb7ce3d   Bjorn Helgaas   PNP: improve reso...
65
66
67
68
  				"(min %#llx max %#llx)
  ", idx,
  				(unsigned long long) rule->min,
  				(unsigned long long) rule->max);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
69
  			return -EBUSY;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
70
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
72
73
74
  
  __add:
  	pnp_add_io_resource(dev, res->start, res->end, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
75
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
  }
  
  static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
80
  	struct resource *res, local_res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81

13cde3b2a   Witold Szczeponik   PNP: Handle IORES...
82
  	res = pnp_find_resource(dev, rule->flags, IORESOURCE_MEM, idx);
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
83
  	if (res) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
84
  		pnp_dbg(&dev->dev, "  mem %d already set to %#llx-%#llx "
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
85
86
87
  			"flags %#lx
  ", idx, (unsigned long long) res->start,
  			(unsigned long long) res->end, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
88
  		return 0;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
89
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
90
91
92
93
  	res = &local_res;
  	res->flags = rule->flags | IORESOURCE_AUTO;
  	res->start = 0;
  	res->end = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94

13cde3b2a   Witold Szczeponik   PNP: Handle IORES...
95
  	/* ??? rule->flags restricted to 8 bits, all tests bogus ??? */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
  	if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
97
  		res->flags |= IORESOURCE_READONLY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
  	if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
99
  		res->flags |= IORESOURCE_RANGELENGTH;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
  	if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
101
  		res->flags |= IORESOURCE_SHADOWABLE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
  
  	if (!rule->size) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
104
  		res->flags |= IORESOURCE_DISABLED;
2f53432c2   Bjorn Helgaas   PNP: convert to u...
105
106
  		pnp_dbg(&dev->dev, "  mem %d disabled
  ", idx);
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
107
  		goto __add;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
  	}
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
109
110
  	res->start = rule->min;
  	res->end = res->start + rule->size - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111

f5d94ff01   Bjorn Helgaas   PNP: pass resourc...
112
  	while (!pnp_check_mem(dev, res)) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
113
114
115
  		res->start += rule->align;
  		res->end = res->start + rule->size - 1;
  		if (res->start > rule->max || !rule->align) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
116
  			pnp_dbg(&dev->dev, "  couldn't assign mem %d "
fcfb7ce3d   Bjorn Helgaas   PNP: improve reso...
117
118
119
120
  				"(min %#llx max %#llx)
  ", idx,
  				(unsigned long long) rule->min,
  				(unsigned long long) rule->max);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
121
  			return -EBUSY;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
122
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
124
125
126
  
  __add:
  	pnp_add_mem_resource(dev, res->start, res->end, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
127
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
  }
9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
129
  static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
131
  	struct resource *res, local_res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
134
135
136
137
  	int i;
  
  	/* IRQ priority: this table is good for i386 */
  	static unsigned short xtab[16] = {
  		5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
  	};
13cde3b2a   Witold Szczeponik   PNP: Handle IORES...
138
  	res = pnp_find_resource(dev, rule->flags, IORESOURCE_IRQ, idx);
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
139
  	if (res) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
140
141
  		pnp_dbg(&dev->dev, "  irq %d already set to %d flags %#lx
  ",
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
142
  			idx, (int) res->start, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
143
  		return 0;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
144
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
145
146
147
148
  	res = &local_res;
  	res->flags = rule->flags | IORESOURCE_AUTO;
  	res->start = -1;
  	res->end = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149

7aefff518   Bjorn Helgaas   PNP: introduce pn...
150
  	if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
151
  		res->flags |= IORESOURCE_DISABLED;
2f53432c2   Bjorn Helgaas   PNP: convert to u...
152
153
  		pnp_dbg(&dev->dev, "  irq %d disabled
  ", idx);
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
154
  		goto __add;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
156
157
  	}
  
  	/* TBD: need check for >16 IRQ */
7aefff518   Bjorn Helgaas   PNP: introduce pn...
158
  	res->start = find_next_bit(rule->map.bits, PNP_IRQ_NR, 16);
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
159
160
  	if (res->start < PNP_IRQ_NR) {
  		res->end = res->start;
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
161
  		goto __add;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
163
  	}
  	for (i = 0; i < 16; i++) {
7aefff518   Bjorn Helgaas   PNP: introduce pn...
164
  		if (test_bit(xtab[i], rule->map.bits)) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
165
  			res->start = res->end = xtab[i];
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
166
167
  			if (pnp_check_irq(dev, res))
  				goto __add;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
  		}
  	}
d5ebde6ef   Bjorn Helgaas   PNP: support opti...
170
171
172
173
174
  
  	if (rule->flags & IORESOURCE_IRQ_OPTIONAL) {
  		res->start = -1;
  		res->end = -1;
  		res->flags |= IORESOURCE_DISABLED;
2f53432c2   Bjorn Helgaas   PNP: convert to u...
175
176
  		pnp_dbg(&dev->dev, "  irq %d disabled (optional)
  ", idx);
d5ebde6ef   Bjorn Helgaas   PNP: support opti...
177
178
  		goto __add;
  	}
2f53432c2   Bjorn Helgaas   PNP: convert to u...
179
180
  	pnp_dbg(&dev->dev, "  couldn't assign irq %d
  ", idx);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
181
  	return -EBUSY;
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
182
183
184
  
  __add:
  	pnp_add_irq_resource(dev, res->start, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
185
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  }
586f83e2b   David Rientjes   pnp: only assign ...
187
  #ifdef CONFIG_ISA_DMA_API
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
188
  static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
190
  	struct resource *res, local_res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
193
194
195
196
  	int i;
  
  	/* DMA priority: this table is good for i386 */
  	static unsigned short xtab[8] = {
  		1, 3, 5, 6, 7, 0, 2, 4
  	};
13cde3b2a   Witold Szczeponik   PNP: Handle IORES...
197
  	res = pnp_find_resource(dev, rule->flags, IORESOURCE_DMA, idx);
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
198
  	if (res) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
199
200
  		pnp_dbg(&dev->dev, "  dma %d already set to %d flags %#lx
  ",
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
201
  			idx, (int) res->start, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
202
  		return 0;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
203
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
204
205
206
207
  	res = &local_res;
  	res->flags = rule->flags | IORESOURCE_AUTO;
  	res->start = -1;
  	res->end = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208

bdf0eb3a0   David Flater   pnp: restore auto...
209
210
211
212
213
214
  	if (!rule->map) {
  		res->flags |= IORESOURCE_DISABLED;
  		pnp_dbg(&dev->dev, "  dma %d disabled
  ", idx);
  		goto __add;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
  	for (i = 0; i < 8; i++) {
9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
216
  		if (rule->map & (1 << xtab[i])) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
217
  			res->start = res->end = xtab[i];
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
218
219
  			if (pnp_check_dma(dev, res))
  				goto __add;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
221
  		}
  	}
bdf0eb3a0   David Flater   pnp: restore auto...
222
223
224
225
  
  	pnp_dbg(&dev->dev, "  couldn't assign dma %d
  ", idx);
  	return -EBUSY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226

aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
227
228
  __add:
  	pnp_add_dma_resource(dev, res->start, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
229
  	return 0;
d948a8daa   Bjorn Helgaas   PNP: factor pnp_i...
230
  }
586f83e2b   David Rientjes   pnp: only assign ...
231
  #endif /* CONFIG_ISA_DMA_API */
d948a8daa   Bjorn Helgaas   PNP: factor pnp_i...
232

2cd139309   Bjorn Helgaas   PNP: remove unuse...
233
  void pnp_init_resources(struct pnp_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
235
  	pnp_free_resources(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
  }
6969c7ed5   Bjorn Helgaas   PNP: remove pnp_r...
237
  static void pnp_clean_resource_table(struct pnp_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
239
240
241
242
243
  	struct pnp_resource *pnp_res, *tmp;
  
  	list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) {
  		if (pnp_res->res.flags & IORESOURCE_AUTO)
  			pnp_free_resource(pnp_res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
245
246
247
248
249
  	}
  }
  
  /**
   * pnp_assign_resources - assigns resources to the device based on the specified dependent number
   * @dev: pointer to the desired device
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
250
   * @set: the dependent function number
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
   */
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
252
  static int pnp_assign_resources(struct pnp_dev *dev, int set)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
  {
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
254
  	struct pnp_option *option;
586f83e2b   David Rientjes   pnp: only assign ...
255
256
  	int nport = 0, nmem = 0, nirq = 0;
  	int ndma __maybe_unused = 0;
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
257
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
258

2f53432c2   Bjorn Helgaas   PNP: convert to u...
259
260
  	pnp_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d
  ", set);
b3bd86e2f   Daniel Walker   isapnp driver sem...
261
  	mutex_lock(&pnp_res_mutex);
6969c7ed5   Bjorn Helgaas   PNP: remove pnp_r...
262
  	pnp_clean_resource_table(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263

1f32ca31e   Bjorn Helgaas   PNP: convert reso...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
  	list_for_each_entry(option, &dev->options, list) {
  		if (pnp_option_is_dependent(option) &&
  		    pnp_option_set(option) != set)
  				continue;
  
  		switch (option->type) {
  		case IORESOURCE_IO:
  			ret = pnp_assign_port(dev, &option->u.port, nport++);
  			break;
  		case IORESOURCE_MEM:
  			ret = pnp_assign_mem(dev, &option->u.mem, nmem++);
  			break;
  		case IORESOURCE_IRQ:
  			ret = pnp_assign_irq(dev, &option->u.irq, nirq++);
  			break;
586f83e2b   David Rientjes   pnp: only assign ...
279
  #ifdef CONFIG_ISA_DMA_API
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
280
281
282
  		case IORESOURCE_DMA:
  			ret = pnp_assign_dma(dev, &option->u.dma, ndma++);
  			break;
586f83e2b   David Rientjes   pnp: only assign ...
283
  #endif
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
284
285
286
  		default:
  			ret = -EINVAL;
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
  		}
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
288
289
290
  		if (ret < 0)
  			break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291

b3bd86e2f   Daniel Walker   isapnp driver sem...
292
  	mutex_unlock(&pnp_res_mutex);
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
293
  	if (ret < 0) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
294
295
  		pnp_dbg(&dev->dev, "pnp_assign_resources failed (%d)
  ", ret);
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
296
297
298
299
  		pnp_clean_resource_table(dev);
  	} else
  		dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
301
302
  }
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
304
   * pnp_auto_config_dev - automatically assigns resources to a device
   * @dev: pointer to the desired device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
305
306
307
   */
  int pnp_auto_config_dev(struct pnp_dev *dev)
  {
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
308
  	int i, ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309

9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
310
  	if (!pnp_can_configure(dev)) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
311
312
  		pnp_dbg(&dev->dev, "configuration not supported
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
314
  		return -ENODEV;
  	}
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
315
316
317
318
319
320
321
  	ret = pnp_assign_resources(dev, 0);
  	if (ret == 0)
  		return 0;
  
  	for (i = 1; i < dev->num_dependent_sets; i++) {
  		ret = pnp_assign_resources(dev, i);
  		if (ret == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
  	}
a05d07816   Bjorn Helgaas   PNP: use dev_info...
324
325
  	dev_err(&dev->dev, "unable to assign resources
  ");
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
326
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
328
329
  }
  
  /**
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
330
331
332
   * pnp_start_dev - low-level start of the PnP device
   * @dev: pointer to the desired device
   *
07d4e9af1   Bjorn Helgaas   PNP: fix up after...
333
   * assumes that resources have already been allocated
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
334
   */
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
335
336
337
  int pnp_start_dev(struct pnp_dev *dev)
  {
  	if (!pnp_can_write(dev)) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
338
339
  		pnp_dbg(&dev->dev, "activation not supported
  ");
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
340
341
  		return -EINVAL;
  	}
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
342
  	dbg_pnp_show_resources(dev, "pnp_start_dev");
59284cb40   Bjorn Helgaas   PNP: remove pnp_r...
343
  	if (dev->protocol->set(dev) < 0) {
a05d07816   Bjorn Helgaas   PNP: use dev_info...
344
345
  		dev_err(&dev->dev, "activation failed
  ");
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
346
347
  		return -EIO;
  	}
a05d07816   Bjorn Helgaas   PNP: use dev_info...
348
349
  	dev_info(&dev->dev, "activated
  ");
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
350
351
352
353
354
355
356
357
358
  	return 0;
  }
  
  /**
   * pnp_stop_dev - low-level disable of the PnP device
   * @dev: pointer to the desired device
   *
   * does not free resources
   */
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
359
360
361
  int pnp_stop_dev(struct pnp_dev *dev)
  {
  	if (!pnp_can_disable(dev)) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
362
363
  		pnp_dbg(&dev->dev, "disabling not supported
  ");
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
364
365
  		return -EINVAL;
  	}
9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
366
  	if (dev->protocol->disable(dev) < 0) {
a05d07816   Bjorn Helgaas   PNP: use dev_info...
367
368
  		dev_err(&dev->dev, "disable failed
  ");
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
369
370
  		return -EIO;
  	}
a05d07816   Bjorn Helgaas   PNP: use dev_info...
371
372
  	dev_info(&dev->dev, "disabled
  ");
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
373
374
375
376
  	return 0;
  }
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
378
379
380
381
382
383
   * pnp_activate_dev - activates a PnP device for use
   * @dev: pointer to the desired device
   *
   * does not validate or set resources so be careful.
   */
  int pnp_activate_dev(struct pnp_dev *dev)
  {
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
384
  	int error;
07d4e9af1   Bjorn Helgaas   PNP: fix up after...
385
  	if (dev->active)
cc8259a66   Bjorn Helgaas   simplify pnp_acti...
386
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
388
389
390
  
  	/* ensure resources are allocated */
  	if (pnp_auto_config_dev(dev))
  		return -EBUSY;
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
391
392
393
  	error = pnp_start_dev(dev);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394
395
  
  	dev->active = 1;
cc8259a66   Bjorn Helgaas   simplify pnp_acti...
396
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
398
399
400
401
402
403
404
405
406
  }
  
  /**
   * pnp_disable_dev - disables device
   * @dev: pointer to the desired device
   *
   * inform the correct pnp protocol so that resources can be used by other devices
   */
  int pnp_disable_dev(struct pnp_dev *dev)
  {
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
407
  	int error;
07d4e9af1   Bjorn Helgaas   PNP: fix up after...
408
  	if (!dev->active)
cc8259a66   Bjorn Helgaas   simplify pnp_acti...
409
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410

68094e325   Pierre Ossman   [ALSA] [PATCH] al...
411
412
413
  	error = pnp_stop_dev(dev);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
415
  
  	dev->active = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
  
  	/* release the resources so that other devices can use them */
b3bd86e2f   Daniel Walker   isapnp driver sem...
418
  	mutex_lock(&pnp_res_mutex);
6969c7ed5   Bjorn Helgaas   PNP: remove pnp_r...
419
  	pnp_clean_resource_table(dev);
b3bd86e2f   Daniel Walker   isapnp driver sem...
420
  	mutex_unlock(&pnp_res_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421

cc8259a66   Bjorn Helgaas   simplify pnp_acti...
422
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
  }
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
424
425
  EXPORT_SYMBOL(pnp_start_dev);
  EXPORT_SYMBOL(pnp_stop_dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
427
  EXPORT_SYMBOL(pnp_activate_dev);
  EXPORT_SYMBOL(pnp_disable_dev);