Blame view

drivers/pnp/manager.c 9.34 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
19
20
  
  static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
21
  	struct resource *res, local_res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22

aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
23
24
  	res = pnp_get_resource(dev, IORESOURCE_IO, idx);
  	if (res) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
25
  		pnp_dbg(&dev->dev, "  io %d already set to %#llx-%#llx "
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
26
27
28
  			"flags %#lx
  ", idx, (unsigned long long) res->start,
  			(unsigned long long) res->end, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
29
  		return 0;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
30
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
31
32
33
34
  	res = &local_res;
  	res->flags = rule->flags | IORESOURCE_AUTO;
  	res->start = 0;
  	res->end = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
  
  	if (!rule->size) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
37
  		res->flags |= IORESOURCE_DISABLED;
2f53432c2   Bjorn Helgaas   PNP: convert to u...
38
39
  		pnp_dbg(&dev->dev, "  io %d disabled
  ", idx);
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
40
  		goto __add;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
  	}
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
42
43
  	res->start = rule->min;
  	res->end = res->start + rule->size - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44

f5d94ff01   Bjorn Helgaas   PNP: pass resourc...
45
  	while (!pnp_check_port(dev, res)) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
46
47
48
  		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...
49
  			pnp_dbg(&dev->dev, "  couldn't assign io %d "
fcfb7ce3d   Bjorn Helgaas   PNP: improve reso...
50
51
52
53
  				"(min %#llx max %#llx)
  ", idx,
  				(unsigned long long) rule->min,
  				(unsigned long long) rule->max);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
54
  			return -EBUSY;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
55
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
57
58
59
  
  __add:
  	pnp_add_io_resource(dev, res->start, res->end, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
60
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
64
  }
  
  static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
65
  	struct resource *res, local_res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66

aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
67
68
  	res = pnp_get_resource(dev, IORESOURCE_MEM, idx);
  	if (res) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
69
  		pnp_dbg(&dev->dev, "  mem %d already set to %#llx-%#llx "
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
70
71
72
  			"flags %#lx
  ", idx, (unsigned long long) res->start,
  			(unsigned long long) res->end, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
73
  		return 0;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
74
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
75
76
77
78
  	res = &local_res;
  	res->flags = rule->flags | IORESOURCE_AUTO;
  	res->start = 0;
  	res->end = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
  	if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
81
  		res->flags |= IORESOURCE_READONLY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  	if (rule->flags & IORESOURCE_MEM_CACHEABLE)
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
83
  		res->flags |= IORESOURCE_CACHEABLE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
  	if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
85
  		res->flags |= IORESOURCE_RANGELENGTH;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
  	if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
87
  		res->flags |= IORESOURCE_SHADOWABLE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
  
  	if (!rule->size) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
90
  		res->flags |= IORESOURCE_DISABLED;
2f53432c2   Bjorn Helgaas   PNP: convert to u...
91
92
  		pnp_dbg(&dev->dev, "  mem %d disabled
  ", idx);
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
93
  		goto __add;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
  	}
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
95
96
  	res->start = rule->min;
  	res->end = res->start + rule->size - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97

f5d94ff01   Bjorn Helgaas   PNP: pass resourc...
98
  	while (!pnp_check_mem(dev, res)) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
99
100
101
  		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...
102
  			pnp_dbg(&dev->dev, "  couldn't assign mem %d "
fcfb7ce3d   Bjorn Helgaas   PNP: improve reso...
103
104
105
106
  				"(min %#llx max %#llx)
  ", idx,
  				(unsigned long long) rule->min,
  				(unsigned long long) rule->max);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
107
  			return -EBUSY;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
108
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
110
111
112
  
  __add:
  	pnp_add_mem_resource(dev, res->start, res->end, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
113
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
  }
9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
115
  static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
117
  	struct resource *res, local_res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
120
121
122
123
  	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
  	};
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
124
125
  	res = pnp_get_resource(dev, IORESOURCE_IRQ, idx);
  	if (res) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
126
127
  		pnp_dbg(&dev->dev, "  irq %d already set to %d flags %#lx
  ",
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
128
  			idx, (int) res->start, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
129
  		return 0;
81b5c75f0   Bjorn Helgaas   PNP: add debug wh...
130
  	}
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
131
132
133
134
  	res = &local_res;
  	res->flags = rule->flags | IORESOURCE_AUTO;
  	res->start = -1;
  	res->end = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
  	for (i = 0; i < 8; i++) {
9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
196
  		if (rule->map & (1 << xtab[i])) {
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
197
  			res->start = res->end = xtab[i];
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
198
199
  			if (pnp_check_dma(dev, res))
  				goto __add;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
201
  		}
  	}
7ef36390f   Jan Beulich   PNP: don't fail d...
202
  #ifdef MAX_DMA_CHANNELS
28ccffcf0   Bjorn Helgaas   PNP: reduce redun...
203
  	res->start = res->end = MAX_DMA_CHANNELS;
7ef36390f   Jan Beulich   PNP: don't fail d...
204
  #endif
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
205
  	res->flags |= IORESOURCE_DISABLED;
2f53432c2   Bjorn Helgaas   PNP: convert to u...
206
207
  	pnp_dbg(&dev->dev, "  disable dma %d
  ", idx);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208

aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
209
210
  __add:
  	pnp_add_dma_resource(dev, res->start, res->flags);
6e906f0e1   Bjorn Helgaas   PNP: make resourc...
211
  	return 0;
d948a8daa   Bjorn Helgaas   PNP: factor pnp_i...
212
  }
586f83e2b   David Rientjes   pnp: only assign ...
213
  #endif /* CONFIG_ISA_DMA_API */
d948a8daa   Bjorn Helgaas   PNP: factor pnp_i...
214

2cd139309   Bjorn Helgaas   PNP: remove unuse...
215
  void pnp_init_resources(struct pnp_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
217
  	pnp_free_resources(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  }
6969c7ed5   Bjorn Helgaas   PNP: remove pnp_r...
219
  static void pnp_clean_resource_table(struct pnp_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
  {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
221
222
223
224
225
  	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
226
227
228
229
230
231
  	}
  }
  
  /**
   * 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...
232
   * @set: the dependent function number
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
   */
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
234
  static int pnp_assign_resources(struct pnp_dev *dev, int set)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
  {
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
236
  	struct pnp_option *option;
586f83e2b   David Rientjes   pnp: only assign ...
237
238
  	int nport = 0, nmem = 0, nirq = 0;
  	int ndma __maybe_unused = 0;
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
239
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240

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

1f32ca31e   Bjorn Helgaas   PNP: convert reso...
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  	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 ...
261
  #ifdef CONFIG_ISA_DMA_API
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
262
263
264
  		case IORESOURCE_DMA:
  			ret = pnp_assign_dma(dev, &option->u.dma, ndma++);
  			break;
586f83e2b   David Rientjes   pnp: only assign ...
265
  #endif
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
266
267
268
  		default:
  			ret = -EINVAL;
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
  		}
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
270
271
272
  		if (ret < 0)
  			break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273

b3bd86e2f   Daniel Walker   isapnp driver sem...
274
  	mutex_unlock(&pnp_res_mutex);
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
275
  	if (ret < 0) {
2f53432c2   Bjorn Helgaas   PNP: convert to u...
276
277
  		pnp_dbg(&dev->dev, "pnp_assign_resources failed (%d)
  ", ret);
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
278
279
280
281
  		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
282
283
284
  }
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
   * pnp_auto_config_dev - automatically assigns resources to a device
   * @dev: pointer to the desired device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
288
289
   */
  int pnp_auto_config_dev(struct pnp_dev *dev)
  {
1f32ca31e   Bjorn Helgaas   PNP: convert reso...
290
  	int i, ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291

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

68094e325   Pierre Ossman   [ALSA] [PATCH] al...
393
394
395
  	error = pnp_stop_dev(dev);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
397
  
  	dev->active = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
399
  
  	/* release the resources so that other devices can use them */
b3bd86e2f   Daniel Walker   isapnp driver sem...
400
  	mutex_lock(&pnp_res_mutex);
6969c7ed5   Bjorn Helgaas   PNP: remove pnp_r...
401
  	pnp_clean_resource_table(dev);
b3bd86e2f   Daniel Walker   isapnp driver sem...
402
  	mutex_unlock(&pnp_res_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403

cc8259a66   Bjorn Helgaas   simplify pnp_acti...
404
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405
  }
68094e325   Pierre Ossman   [ALSA] [PATCH] al...
406
407
  EXPORT_SYMBOL(pnp_start_dev);
  EXPORT_SYMBOL(pnp_stop_dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
409
  EXPORT_SYMBOL(pnp_activate_dev);
  EXPORT_SYMBOL(pnp_disable_dev);