Blame view

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

13cde3b2a   Witold Szczeponik   PNP: Handle IORES...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  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
35
36
  static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
37
  	struct resource *res, local_res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38

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

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

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

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

f5d94ff01   Bjorn Helgaas   PNP: pass resourc...
113
  	while (!pnp_check_mem(dev, res)) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
114
115
116
  		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...
117
  			pnp_dbg(&dev->dev, "  couldn't assign mem %d "
fcfb7ce3d   Bjorn Helgaas   PNP: improve reso...
118
119
120
121
  				"(min %#llx max %#llx)
  ", idx,
  				(unsigned long long) rule->min,
  				(unsigned long long) rule->max);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
122
  			return -EBUSY;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
123
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
125
126
127
  
  __add:
  	pnp_add_mem_resource(dev, res->start, res->end, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
128
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
  }
9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
130
  static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
132
  	struct resource *res, local_res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
134
135
136
137
138
  	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...
139
  	res = pnp_find_resource(dev, rule->flags, IORESOURCE_IRQ, idx);
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
140
  	if (res) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
141
142
  		pnp_dbg(&dev->dev, "  irq %d already set to %d flags %#lx
  ",
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
143
  			idx, (int) res->start, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
144
  		return 0;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
145
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
146
147
148
149
  	res = &local_res;
  	res->flags = rule->flags | IORESOURCE_AUTO;
  	res->start = -1;
  	res->end = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150

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

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

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

2cd139309   Bjorn Helgaas   PNP: remove unuse...
234
  void pnp_init_resources(struct pnp_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
236
  	pnp_free_resources(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
  }
6969c7ed5   Bjorn Helgaas   PNP: remove pnp_r...
238
  static void pnp_clean_resource_table(struct pnp_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
240
241
242
243
244
  	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
245
246
247
248
249
250
  	}
  }
  
  /**
   * 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...
251
   * @set: the dependent function number
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
   */
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
253
  static int pnp_assign_resources(struct pnp_dev *dev, int set)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
  {
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
255
  	struct pnp_option *option;
586f83e2b   David Rientjes   pnp: only assign ...
256
257
  	int nport = 0, nmem = 0, nirq = 0;
  	int ndma __maybe_unused = 0;
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
258
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259

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

1f32ca31e   Bjorn Helgaas   PNP: convert reso...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
  	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 ...
280
  #ifdef CONFIG_ISA_DMA_API
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
281
282
283
  		case IORESOURCE_DMA:
  			ret = pnp_assign_dma(dev, &option->u.dma, ndma++);
  			break;
586f83e2b   David Rientjes   pnp: only assign ...
284
  #endif
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
285
286
287
  		default:
  			ret = -EINVAL;
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  		}
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
289
290
291
  		if (ret < 0)
  			break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292

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

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

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

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