aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2008-04-30 13:59:05 -0400
committerLen Brown <len.brown@intel.com>2008-04-30 13:59:05 -0400
commit008238b54ac2350babf195084ecedbcf7851a202 (patch)
treea7cc18ea0403f4478883a3e36a6f0d2bf67eef3e /drivers/pnp
parent96916090f488986a4ebb8e9ffa6a3b50881d5ccd (diff)
parentdfd2e1b4e6eb46ff59c7e1c1111c967b8b5981c1 (diff)
Merge branch 'pnp' into release
Diffstat (limited to 'drivers/pnp')
-rw-r--r--drivers/pnp/base.h74
-rw-r--r--drivers/pnp/card.c55
-rw-r--r--drivers/pnp/core.c46
-rw-r--r--drivers/pnp/driver.c28
-rw-r--r--drivers/pnp/interface.c111
-rw-r--r--drivers/pnp/isapnp/Makefile4
-rw-r--r--drivers/pnp/isapnp/core.c340
-rw-r--r--drivers/pnp/manager.c356
-rw-r--r--drivers/pnp/pnpacpi/Makefile4
-rw-r--r--drivers/pnp/pnpacpi/core.c90
-rw-r--r--drivers/pnp/pnpacpi/pnpacpi.h8
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c589
-rw-r--r--drivers/pnp/pnpbios/Makefile4
-rw-r--r--drivers/pnp/pnpbios/bioscalls.c1
-rw-r--r--drivers/pnp/pnpbios/core.c31
-rw-r--r--drivers/pnp/pnpbios/pnpbios.h140
-rw-r--r--drivers/pnp/pnpbios/proc.c2
-rw-r--r--drivers/pnp/pnpbios/rsparser.c326
-rw-r--r--drivers/pnp/quirks.c15
-rw-r--r--drivers/pnp/resource.c361
-rw-r--r--drivers/pnp/support.c63
-rw-r--r--drivers/pnp/system.c21
22 files changed, 1575 insertions, 1094 deletions
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 31a633f65547..4fe7c58f57e9 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -1,12 +1,78 @@
1extern spinlock_t pnp_lock; 1extern spinlock_t pnp_lock;
2void *pnp_alloc(long size); 2void *pnp_alloc(long size);
3
4int pnp_register_protocol(struct pnp_protocol *protocol);
5void pnp_unregister_protocol(struct pnp_protocol *protocol);
6
7#define PNP_EISA_ID_MASK 0x7fffffff
8void pnp_eisa_id_to_string(u32 id, char *str);
9struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, char *pnpid);
10struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid);
11
12int pnp_add_device(struct pnp_dev *dev);
13struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id);
3int pnp_interface_attach_device(struct pnp_dev *dev); 14int pnp_interface_attach_device(struct pnp_dev *dev);
15
16int pnp_add_card(struct pnp_card *card);
17struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id);
18void pnp_remove_card(struct pnp_card *card);
19int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
20void pnp_remove_card_device(struct pnp_dev *dev);
21
22struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
23struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
24 int priority);
25int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
26 struct pnp_irq *data);
27int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
28 struct pnp_dma *data);
29int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
30 struct pnp_port *data);
31int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
32 struct pnp_mem *data);
33void pnp_init_resources(struct pnp_dev *dev);
34
4void pnp_fixup_device(struct pnp_dev *dev); 35void pnp_fixup_device(struct pnp_dev *dev);
5void pnp_free_option(struct pnp_option *option); 36void pnp_free_option(struct pnp_option *option);
6int __pnp_add_device(struct pnp_dev *dev); 37int __pnp_add_device(struct pnp_dev *dev);
7void __pnp_remove_device(struct pnp_dev *dev); 38void __pnp_remove_device(struct pnp_dev *dev);
8 39
9int pnp_check_port(struct pnp_dev * dev, int idx); 40int pnp_check_port(struct pnp_dev *dev, struct resource *res);
10int pnp_check_mem(struct pnp_dev * dev, int idx); 41int pnp_check_mem(struct pnp_dev *dev, struct resource *res);
11int pnp_check_irq(struct pnp_dev * dev, int idx); 42int pnp_check_irq(struct pnp_dev *dev, struct resource *res);
12int pnp_check_dma(struct pnp_dev * dev, int idx); 43int pnp_check_dma(struct pnp_dev *dev, struct resource *res);
44
45void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
46
47void pnp_init_resource(struct resource *res);
48
49struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
50 unsigned int type, unsigned int num);
51
52#define PNP_MAX_PORT 40
53#define PNP_MAX_MEM 24
54#define PNP_MAX_IRQ 2
55#define PNP_MAX_DMA 2
56
57struct pnp_resource {
58 struct resource res;
59 unsigned int index; /* ISAPNP config register index */
60};
61
62struct pnp_resource_table {
63 struct pnp_resource port[PNP_MAX_PORT];
64 struct pnp_resource mem[PNP_MAX_MEM];
65 struct pnp_resource dma[PNP_MAX_DMA];
66 struct pnp_resource irq[PNP_MAX_IRQ];
67};
68
69struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
70 int flags);
71struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
72 int flags);
73struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
74 resource_size_t start,
75 resource_size_t end, int flags);
76struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
77 resource_size_t start,
78 resource_size_t end, int flags);
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index da1c9909eb44..a762a4176736 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -5,6 +5,7 @@
5 */ 5 */
6 6
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/ctype.h>
8#include <linux/slab.h> 9#include <linux/slab.h>
9#include <linux/pnp.h> 10#include <linux/pnp.h>
10#include "base.h" 11#include "base.h"
@@ -100,19 +101,33 @@ static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv)
100 * @id: pointer to a pnp_id structure 101 * @id: pointer to a pnp_id structure
101 * @card: pointer to the desired card 102 * @card: pointer to the desired card
102 */ 103 */
103int pnp_add_card_id(struct pnp_id *id, struct pnp_card *card) 104struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id)
104{ 105{
105 struct pnp_id *ptr; 106 struct pnp_id *dev_id, *ptr;
106 107
107 id->next = NULL; 108 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
109 if (!dev_id)
110 return NULL;
111
112 dev_id->id[0] = id[0];
113 dev_id->id[1] = id[1];
114 dev_id->id[2] = id[2];
115 dev_id->id[3] = tolower(id[3]);
116 dev_id->id[4] = tolower(id[4]);
117 dev_id->id[5] = tolower(id[5]);
118 dev_id->id[6] = tolower(id[6]);
119 dev_id->id[7] = '\0';
120
121 dev_id->next = NULL;
108 ptr = card->id; 122 ptr = card->id;
109 while (ptr && ptr->next) 123 while (ptr && ptr->next)
110 ptr = ptr->next; 124 ptr = ptr->next;
111 if (ptr) 125 if (ptr)
112 ptr->next = id; 126 ptr->next = dev_id;
113 else 127 else
114 card->id = id; 128 card->id = dev_id;
115 return 0; 129
130 return dev_id;
116} 131}
117 132
118static void pnp_free_card_ids(struct pnp_card *card) 133static void pnp_free_card_ids(struct pnp_card *card)
@@ -136,6 +151,31 @@ static void pnp_release_card(struct device *dmdev)
136 kfree(card); 151 kfree(card);
137} 152}
138 153
154struct pnp_card *pnp_alloc_card(struct pnp_protocol *protocol, int id, char *pnpid)
155{
156 struct pnp_card *card;
157 struct pnp_id *dev_id;
158
159 card = kzalloc(sizeof(struct pnp_card), GFP_KERNEL);
160 if (!card)
161 return NULL;
162
163 card->protocol = protocol;
164 card->number = id;
165
166 card->dev.parent = &card->protocol->dev;
167 sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number,
168 card->number);
169
170 dev_id = pnp_add_card_id(card, pnpid);
171 if (!dev_id) {
172 kfree(card);
173 return NULL;
174 }
175
176 return card;
177}
178
139static ssize_t pnp_show_card_name(struct device *dmdev, 179static ssize_t pnp_show_card_name(struct device *dmdev,
140 struct device_attribute *attr, char *buf) 180 struct device_attribute *attr, char *buf)
141{ 181{
@@ -191,9 +231,6 @@ int pnp_add_card(struct pnp_card *card)
191 int error; 231 int error;
192 struct list_head *pos, *temp; 232 struct list_head *pos, *temp;
193 233
194 sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number,
195 card->number);
196 card->dev.parent = &card->protocol->dev;
197 card->dev.bus = NULL; 234 card->dev.bus = NULL;
198 card->dev.release = &pnp_release_card; 235 card->dev.release = &pnp_release_card;
199 error = device_register(&card->dev); 236 error = device_register(&card->dev);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 7d366ca672d3..20771b7d4482 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -106,18 +106,53 @@ static void pnp_release_device(struct device *dmdev)
106 pnp_free_option(dev->independent); 106 pnp_free_option(dev->independent);
107 pnp_free_option(dev->dependent); 107 pnp_free_option(dev->dependent);
108 pnp_free_ids(dev); 108 pnp_free_ids(dev);
109 kfree(dev->res);
109 kfree(dev); 110 kfree(dev);
110} 111}
111 112
112int __pnp_add_device(struct pnp_dev *dev) 113struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid)
113{ 114{
114 int ret; 115 struct pnp_dev *dev;
116 struct pnp_id *dev_id;
115 117
116 pnp_fixup_device(dev); 118 dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
119 if (!dev)
120 return NULL;
121
122 dev->res = kzalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
123 if (!dev->res) {
124 kfree(dev);
125 return NULL;
126 }
127
128 dev->protocol = protocol;
129 dev->number = id;
130 dev->dma_mask = DMA_24BIT_MASK;
131
132 dev->dev.parent = &dev->protocol->dev;
117 dev->dev.bus = &pnp_bus_type; 133 dev->dev.bus = &pnp_bus_type;
118 dev->dev.dma_mask = &dev->dma_mask; 134 dev->dev.dma_mask = &dev->dma_mask;
119 dev->dma_mask = dev->dev.coherent_dma_mask = DMA_24BIT_MASK; 135 dev->dev.coherent_dma_mask = dev->dma_mask;
120 dev->dev.release = &pnp_release_device; 136 dev->dev.release = &pnp_release_device;
137
138 sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number,
139 dev->number);
140
141 dev_id = pnp_add_id(dev, pnpid);
142 if (!dev_id) {
143 kfree(dev->res);
144 kfree(dev);
145 return NULL;
146 }
147
148 return dev;
149}
150
151int __pnp_add_device(struct pnp_dev *dev)
152{
153 int ret;
154
155 pnp_fixup_device(dev);
121 dev->status = PNP_READY; 156 dev->status = PNP_READY;
122 spin_lock(&pnp_lock); 157 spin_lock(&pnp_lock);
123 list_add_tail(&dev->global_list, &pnp_global); 158 list_add_tail(&dev->global_list, &pnp_global);
@@ -145,9 +180,6 @@ int pnp_add_device(struct pnp_dev *dev)
145 if (dev->card) 180 if (dev->card)
146 return -EINVAL; 181 return -EINVAL;
147 182
148 dev->dev.parent = &dev->protocol->dev;
149 sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number,
150 dev->number);
151 ret = __pnp_add_device(dev); 183 ret = __pnp_add_device(dev);
152 if (ret) 184 if (ret)
153 return ret; 185 return ret;
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index e85cbf116db1..d3f869ee1d92 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -226,22 +226,36 @@ void pnp_unregister_driver(struct pnp_driver *drv)
226 226
227/** 227/**
228 * pnp_add_id - adds an EISA id to the specified device 228 * pnp_add_id - adds an EISA id to the specified device
229 * @id: pointer to a pnp_id structure
230 * @dev: pointer to the desired device 229 * @dev: pointer to the desired device
230 * @id: pointer to an EISA id string
231 */ 231 */
232int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) 232struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id)
233{ 233{
234 struct pnp_id *ptr; 234 struct pnp_id *dev_id, *ptr;
235 235
236 id->next = NULL; 236 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
237 if (!dev_id)
238 return NULL;
239
240 dev_id->id[0] = id[0];
241 dev_id->id[1] = id[1];
242 dev_id->id[2] = id[2];
243 dev_id->id[3] = tolower(id[3]);
244 dev_id->id[4] = tolower(id[4]);
245 dev_id->id[5] = tolower(id[5]);
246 dev_id->id[6] = tolower(id[6]);
247 dev_id->id[7] = '\0';
248
249 dev_id->next = NULL;
237 ptr = dev->id; 250 ptr = dev->id;
238 while (ptr && ptr->next) 251 while (ptr && ptr->next)
239 ptr = ptr->next; 252 ptr = ptr->next;
240 if (ptr) 253 if (ptr)
241 ptr->next = id; 254 ptr->next = dev_id;
242 else 255 else
243 dev->id = id; 256 dev->id = dev_id;
244 return 0; 257
258 return dev_id;
245} 259}
246 260
247EXPORT_SYMBOL(pnp_register_driver); 261EXPORT_SYMBOL(pnp_register_driver);
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 982658477a58..5d9301de1778 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -248,6 +248,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
248 char *buf) 248 char *buf)
249{ 249{
250 struct pnp_dev *dev = to_pnp_dev(dmdev); 250 struct pnp_dev *dev = to_pnp_dev(dmdev);
251 struct resource *res;
251 int i, ret; 252 int i, ret;
252 pnp_info_buffer_t *buffer; 253 pnp_info_buffer_t *buffer;
253 254
@@ -267,50 +268,46 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
267 else 268 else
268 pnp_printf(buffer, "disabled\n"); 269 pnp_printf(buffer, "disabled\n");
269 270
270 for (i = 0; i < PNP_MAX_PORT; i++) { 271 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
271 if (pnp_port_valid(dev, i)) { 272 if (pnp_resource_valid(res)) {
272 pnp_printf(buffer, "io"); 273 pnp_printf(buffer, "io");
273 if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED) 274 if (res->flags & IORESOURCE_DISABLED)
274 pnp_printf(buffer, " disabled\n"); 275 pnp_printf(buffer, " disabled\n");
275 else 276 else
276 pnp_printf(buffer, " 0x%llx-0x%llx\n", 277 pnp_printf(buffer, " 0x%llx-0x%llx\n",
277 (unsigned long long) 278 (unsigned long long) res->start,
278 pnp_port_start(dev, i), 279 (unsigned long long) res->end);
279 (unsigned long long)pnp_port_end(dev,
280 i));
281 } 280 }
282 } 281 }
283 for (i = 0; i < PNP_MAX_MEM; i++) { 282 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
284 if (pnp_mem_valid(dev, i)) { 283 if (pnp_resource_valid(res)) {
285 pnp_printf(buffer, "mem"); 284 pnp_printf(buffer, "mem");
286 if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED) 285 if (res->flags & IORESOURCE_DISABLED)
287 pnp_printf(buffer, " disabled\n"); 286 pnp_printf(buffer, " disabled\n");
288 else 287 else
289 pnp_printf(buffer, " 0x%llx-0x%llx\n", 288 pnp_printf(buffer, " 0x%llx-0x%llx\n",
290 (unsigned long long) 289 (unsigned long long) res->start,
291 pnp_mem_start(dev, i), 290 (unsigned long long) res->end);
292 (unsigned long long)pnp_mem_end(dev,
293 i));
294 } 291 }
295 } 292 }
296 for (i = 0; i < PNP_MAX_IRQ; i++) { 293 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
297 if (pnp_irq_valid(dev, i)) { 294 if (pnp_resource_valid(res)) {
298 pnp_printf(buffer, "irq"); 295 pnp_printf(buffer, "irq");
299 if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED) 296 if (res->flags & IORESOURCE_DISABLED)
300 pnp_printf(buffer, " disabled\n"); 297 pnp_printf(buffer, " disabled\n");
301 else 298 else
302 pnp_printf(buffer, " %lld\n", 299 pnp_printf(buffer, " %lld\n",
303 (unsigned long long)pnp_irq(dev, i)); 300 (unsigned long long) res->start);
304 } 301 }
305 } 302 }
306 for (i = 0; i < PNP_MAX_DMA; i++) { 303 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
307 if (pnp_dma_valid(dev, i)) { 304 if (pnp_resource_valid(res)) {
308 pnp_printf(buffer, "dma"); 305 pnp_printf(buffer, "dma");
309 if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED) 306 if (res->flags & IORESOURCE_DISABLED)
310 pnp_printf(buffer, " disabled\n"); 307 pnp_printf(buffer, " disabled\n");
311 else 308 else
312 pnp_printf(buffer, " %lld\n", 309 pnp_printf(buffer, " %lld\n",
313 (unsigned long long)pnp_dma(dev, i)); 310 (unsigned long long) res->start);
314 } 311 }
315 } 312 }
316 ret = (buffer->curr - buf); 313 ret = (buffer->curr - buf);
@@ -323,8 +320,10 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
323 const char *ubuf, size_t count) 320 const char *ubuf, size_t count)
324{ 321{
325 struct pnp_dev *dev = to_pnp_dev(dmdev); 322 struct pnp_dev *dev = to_pnp_dev(dmdev);
323 struct pnp_resource *pnp_res;
326 char *buf = (void *)ubuf; 324 char *buf = (void *)ubuf;
327 int retval = 0; 325 int retval = 0;
326 resource_size_t start, end;
328 327
329 if (dev->status & PNP_ATTACHED) { 328 if (dev->status & PNP_ATTACHED) {
330 retval = -EBUSY; 329 retval = -EBUSY;
@@ -351,20 +350,20 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
351 if (!strnicmp(buf, "auto", 4)) { 350 if (!strnicmp(buf, "auto", 4)) {
352 if (dev->active) 351 if (dev->active)
353 goto done; 352 goto done;
354 pnp_init_resource_table(&dev->res); 353 pnp_init_resources(dev);
355 retval = pnp_auto_config_dev(dev); 354 retval = pnp_auto_config_dev(dev);
356 goto done; 355 goto done;
357 } 356 }
358 if (!strnicmp(buf, "clear", 5)) { 357 if (!strnicmp(buf, "clear", 5)) {
359 if (dev->active) 358 if (dev->active)
360 goto done; 359 goto done;
361 pnp_init_resource_table(&dev->res); 360 pnp_init_resources(dev);
362 goto done; 361 goto done;
363 } 362 }
364 if (!strnicmp(buf, "get", 3)) { 363 if (!strnicmp(buf, "get", 3)) {
365 mutex_lock(&pnp_res_mutex); 364 mutex_lock(&pnp_res_mutex);
366 if (pnp_can_read(dev)) 365 if (pnp_can_read(dev))
367 dev->protocol->get(dev, &dev->res); 366 dev->protocol->get(dev);
368 mutex_unlock(&pnp_res_mutex); 367 mutex_unlock(&pnp_res_mutex);
369 goto done; 368 goto done;
370 } 369 }
@@ -373,7 +372,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
373 if (dev->active) 372 if (dev->active)
374 goto done; 373 goto done;
375 buf += 3; 374 buf += 3;
376 pnp_init_resource_table(&dev->res); 375 pnp_init_resources(dev);
377 mutex_lock(&pnp_res_mutex); 376 mutex_lock(&pnp_res_mutex);
378 while (1) { 377 while (1) {
379 while (isspace(*buf)) 378 while (isspace(*buf))
@@ -382,76 +381,60 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
382 buf += 2; 381 buf += 2;
383 while (isspace(*buf)) 382 while (isspace(*buf))
384 ++buf; 383 ++buf;
385 dev->res.port_resource[nport].start = 384 start = simple_strtoul(buf, &buf, 0);
386 simple_strtoul(buf, &buf, 0);
387 while (isspace(*buf)) 385 while (isspace(*buf))
388 ++buf; 386 ++buf;
389 if (*buf == '-') { 387 if (*buf == '-') {
390 buf += 1; 388 buf += 1;
391 while (isspace(*buf)) 389 while (isspace(*buf))
392 ++buf; 390 ++buf;
393 dev->res.port_resource[nport].end = 391 end = simple_strtoul(buf, &buf, 0);
394 simple_strtoul(buf, &buf, 0);
395 } else 392 } else
396 dev->res.port_resource[nport].end = 393 end = start;
397 dev->res.port_resource[nport].start; 394 pnp_res = pnp_add_io_resource(dev, start, end,
398 dev->res.port_resource[nport].flags = 395 0);
399 IORESOURCE_IO; 396 if (pnp_res)
400 nport++; 397 pnp_res->index = nport++;
401 if (nport >= PNP_MAX_PORT)
402 break;
403 continue; 398 continue;
404 } 399 }
405 if (!strnicmp(buf, "mem", 3)) { 400 if (!strnicmp(buf, "mem", 3)) {
406 buf += 3; 401 buf += 3;
407 while (isspace(*buf)) 402 while (isspace(*buf))
408 ++buf; 403 ++buf;
409 dev->res.mem_resource[nmem].start = 404 start = simple_strtoul(buf, &buf, 0);
410 simple_strtoul(buf, &buf, 0);
411 while (isspace(*buf)) 405 while (isspace(*buf))
412 ++buf; 406 ++buf;
413 if (*buf == '-') { 407 if (*buf == '-') {
414 buf += 1; 408 buf += 1;
415 while (isspace(*buf)) 409 while (isspace(*buf))
416 ++buf; 410 ++buf;
417 dev->res.mem_resource[nmem].end = 411 end = simple_strtoul(buf, &buf, 0);
418 simple_strtoul(buf, &buf, 0);
419 } else 412 } else
420 dev->res.mem_resource[nmem].end = 413 end = start;
421 dev->res.mem_resource[nmem].start; 414 pnp_res = pnp_add_mem_resource(dev, start, end,
422 dev->res.mem_resource[nmem].flags = 415 0);
423 IORESOURCE_MEM; 416 if (pnp_res)
424 nmem++; 417 pnp_res->index = nmem++;
425 if (nmem >= PNP_MAX_MEM)
426 break;
427 continue; 418 continue;
428 } 419 }
429 if (!strnicmp(buf, "irq", 3)) { 420 if (!strnicmp(buf, "irq", 3)) {
430 buf += 3; 421 buf += 3;
431 while (isspace(*buf)) 422 while (isspace(*buf))
432 ++buf; 423 ++buf;
433 dev->res.irq_resource[nirq].start = 424 start = simple_strtoul(buf, &buf, 0);
434 dev->res.irq_resource[nirq].end = 425 pnp_res = pnp_add_irq_resource(dev, start, 0);
435 simple_strtoul(buf, &buf, 0); 426 if (pnp_res)
436 dev->res.irq_resource[nirq].flags = 427 nirq++;
437 IORESOURCE_IRQ;
438 nirq++;
439 if (nirq >= PNP_MAX_IRQ)
440 break;
441 continue; 428 continue;
442 } 429 }
443 if (!strnicmp(buf, "dma", 3)) { 430 if (!strnicmp(buf, "dma", 3)) {
444 buf += 3; 431 buf += 3;
445 while (isspace(*buf)) 432 while (isspace(*buf))
446 ++buf; 433 ++buf;
447 dev->res.dma_resource[ndma].start = 434 start = simple_strtoul(buf, &buf, 0);
448 dev->res.dma_resource[ndma].end = 435 pnp_res = pnp_add_dma_resource(dev, start, 0);
449 simple_strtoul(buf, &buf, 0); 436 if (pnp_res)
450 dev->res.dma_resource[ndma].flags = 437 pnp_res->index = ndma++;
451 IORESOURCE_DMA;
452 ndma++;
453 if (ndma >= PNP_MAX_DMA)
454 break;
455 continue; 438 continue;
456 } 439 }
457 break; 440 break;
diff --git a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile
index cac18bbfb817..3e38f06f8d78 100644
--- a/drivers/pnp/isapnp/Makefile
+++ b/drivers/pnp/isapnp/Makefile
@@ -5,3 +5,7 @@
5isapnp-proc-$(CONFIG_PROC_FS) = proc.o 5isapnp-proc-$(CONFIG_PROC_FS) = proc.o
6 6
7obj-y := core.o compat.o $(isapnp-proc-y) 7obj-y := core.o compat.o $(isapnp-proc-y)
8
9ifeq ($(CONFIG_PNP_DEBUG),y)
10EXTRA_CFLAGS += -DDEBUG
11endif
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 257f5d827d83..f1bccdbdeb08 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -44,6 +44,8 @@
44#include <linux/mutex.h> 44#include <linux/mutex.h>
45#include <asm/io.h> 45#include <asm/io.h>
46 46
47#include "../base.h"
48
47#if 0 49#if 0
48#define ISAPNP_REGION_OK 50#define ISAPNP_REGION_OK
49#endif 51#endif
@@ -88,6 +90,14 @@ MODULE_LICENSE("GPL");
88#define _LTAG_MEM32RANGE 0x85 90#define _LTAG_MEM32RANGE 0x85
89#define _LTAG_FIXEDMEM32RANGE 0x86 91#define _LTAG_FIXEDMEM32RANGE 0x86
90 92
93/* Logical device control and configuration registers */
94
95#define ISAPNP_CFG_ACTIVATE 0x30 /* byte */
96#define ISAPNP_CFG_MEM 0x40 /* 4 * dword */
97#define ISAPNP_CFG_PORT 0x60 /* 8 * word */
98#define ISAPNP_CFG_IRQ 0x70 /* 2 * word */
99#define ISAPNP_CFG_DMA 0x74 /* 2 * byte */
100
91/* 101/*
92 * Sizes of ISAPNP logical device configuration register sets. 102 * Sizes of ISAPNP logical device configuration register sets.
93 * See PNP-ISA-v1.0a.pdf, Appendix A. 103 * See PNP-ISA-v1.0a.pdf, Appendix A.
@@ -388,28 +398,6 @@ static void __init isapnp_skip_bytes(int count)
388} 398}
389 399
390/* 400/*
391 * Parse EISA id.
392 */
393static void isapnp_parse_id(struct pnp_dev *dev, unsigned short vendor,
394 unsigned short device)
395{
396 struct pnp_id *id;
397
398 if (!dev)
399 return;
400 id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
401 if (!id)
402 return;
403 sprintf(id->id, "%c%c%c%x%x%x%x",
404 'A' + ((vendor >> 2) & 0x3f) - 1,
405 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
406 'A' + ((vendor >> 8) & 0x1f) - 1,
407 (device >> 4) & 0x0f,
408 device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f);
409 pnp_add_id(id, dev);
410}
411
412/*
413 * Parse logical device tag. 401 * Parse logical device tag.
414 */ 402 */
415static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card, 403static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
@@ -417,30 +405,31 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
417{ 405{
418 unsigned char tmp[6]; 406 unsigned char tmp[6];
419 struct pnp_dev *dev; 407 struct pnp_dev *dev;
408 u32 eisa_id;
409 char id[8];
420 410
421 isapnp_peek(tmp, size); 411 isapnp_peek(tmp, size);
422 dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); 412 eisa_id = tmp[0] | tmp[1] << 8 | tmp[2] << 16 | tmp[3] << 24;
413 pnp_eisa_id_to_string(eisa_id, id);
414
415 dev = pnp_alloc_dev(&isapnp_protocol, number, id);
423 if (!dev) 416 if (!dev)
424 return NULL; 417 return NULL;
425 dev->number = number; 418
426 isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], (tmp[3] << 8) | tmp[2]);
427 dev->regs = tmp[4];
428 dev->card = card; 419 dev->card = card;
429 if (size > 5)
430 dev->regs |= tmp[5] << 8;
431 dev->protocol = &isapnp_protocol;
432 dev->capabilities |= PNP_CONFIGURABLE; 420 dev->capabilities |= PNP_CONFIGURABLE;
433 dev->capabilities |= PNP_READ; 421 dev->capabilities |= PNP_READ;
434 dev->capabilities |= PNP_WRITE; 422 dev->capabilities |= PNP_WRITE;
435 dev->capabilities |= PNP_DISABLE; 423 dev->capabilities |= PNP_DISABLE;
436 pnp_init_resource_table(&dev->res); 424 pnp_init_resources(dev);
437 return dev; 425 return dev;
438} 426}
439 427
440/* 428/*
441 * Add IRQ resource to resources list. 429 * Add IRQ resource to resources list.
442 */ 430 */
443static void __init isapnp_parse_irq_resource(struct pnp_option *option, 431static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
432 struct pnp_option *option,
444 int size) 433 int size)
445{ 434{
446 unsigned char tmp[3]; 435 unsigned char tmp[3];
@@ -457,13 +446,14 @@ static void __init isapnp_parse_irq_resource(struct pnp_option *option,
457 irq->flags = tmp[2]; 446 irq->flags = tmp[2];
458 else 447 else
459 irq->flags = IORESOURCE_IRQ_HIGHEDGE; 448 irq->flags = IORESOURCE_IRQ_HIGHEDGE;
460 pnp_register_irq_resource(option, irq); 449 pnp_register_irq_resource(dev, option, irq);
461} 450}
462 451
463/* 452/*
464 * Add DMA resource to resources list. 453 * Add DMA resource to resources list.
465 */ 454 */
466static void __init isapnp_parse_dma_resource(struct pnp_option *option, 455static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
456 struct pnp_option *option,
467 int size) 457 int size)
468{ 458{
469 unsigned char tmp[2]; 459 unsigned char tmp[2];
@@ -475,13 +465,14 @@ static void __init isapnp_parse_dma_resource(struct pnp_option *option,
475 return; 465 return;
476 dma->map = tmp[0]; 466 dma->map = tmp[0];
477 dma->flags = tmp[1]; 467 dma->flags = tmp[1];
478 pnp_register_dma_resource(option, dma); 468 pnp_register_dma_resource(dev, option, dma);
479} 469}
480 470
481/* 471/*
482 * Add port resource to resources list. 472 * Add port resource to resources list.
483 */ 473 */
484static void __init isapnp_parse_port_resource(struct pnp_option *option, 474static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
475 struct pnp_option *option,
485 int size) 476 int size)
486{ 477{
487 unsigned char tmp[7]; 478 unsigned char tmp[7];
@@ -496,13 +487,14 @@ static void __init isapnp_parse_port_resource(struct pnp_option *option,
496 port->align = tmp[5]; 487 port->align = tmp[5];
497 port->size = tmp[6]; 488 port->size = tmp[6];
498 port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0; 489 port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
499 pnp_register_port_resource(option, port); 490 pnp_register_port_resource(dev, option, port);
500} 491}
501 492
502/* 493/*
503 * Add fixed port resource to resources list. 494 * Add fixed port resource to resources list.
504 */ 495 */
505static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option, 496static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
497 struct pnp_option *option,
506 int size) 498 int size)
507{ 499{
508 unsigned char tmp[3]; 500 unsigned char tmp[3];
@@ -516,13 +508,14 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option,
516 port->size = tmp[2]; 508 port->size = tmp[2];
517 port->align = 0; 509 port->align = 0;
518 port->flags = PNP_PORT_FLAG_FIXED; 510 port->flags = PNP_PORT_FLAG_FIXED;
519 pnp_register_port_resource(option, port); 511 pnp_register_port_resource(dev, option, port);
520} 512}
521 513
522/* 514/*
523 * Add memory resource to resources list. 515 * Add memory resource to resources list.
524 */ 516 */
525static void __init isapnp_parse_mem_resource(struct pnp_option *option, 517static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
518 struct pnp_option *option,
526 int size) 519 int size)
527{ 520{
528 unsigned char tmp[9]; 521 unsigned char tmp[9];
@@ -537,13 +530,14 @@ static void __init isapnp_parse_mem_resource(struct pnp_option *option,
537 mem->align = (tmp[6] << 8) | tmp[5]; 530 mem->align = (tmp[6] << 8) | tmp[5];
538 mem->size = ((tmp[8] << 8) | tmp[7]) << 8; 531 mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
539 mem->flags = tmp[0]; 532 mem->flags = tmp[0];
540 pnp_register_mem_resource(option, mem); 533 pnp_register_mem_resource(dev, option, mem);
541} 534}
542 535
543/* 536/*
544 * Add 32-bit memory resource to resources list. 537 * Add 32-bit memory resource to resources list.
545 */ 538 */
546static void __init isapnp_parse_mem32_resource(struct pnp_option *option, 539static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
540 struct pnp_option *option,
547 int size) 541 int size)
548{ 542{
549 unsigned char tmp[17]; 543 unsigned char tmp[17];
@@ -560,13 +554,14 @@ static void __init isapnp_parse_mem32_resource(struct pnp_option *option,
560 mem->size = 554 mem->size =
561 (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13]; 555 (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
562 mem->flags = tmp[0]; 556 mem->flags = tmp[0];
563 pnp_register_mem_resource(option, mem); 557 pnp_register_mem_resource(dev, option, mem);
564} 558}
565 559
566/* 560/*
567 * Add 32-bit fixed memory resource to resources list. 561 * Add 32-bit fixed memory resource to resources list.
568 */ 562 */
569static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option, 563static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
564 struct pnp_option *option,
570 int size) 565 int size)
571{ 566{
572 unsigned char tmp[9]; 567 unsigned char tmp[9];
@@ -581,7 +576,7 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option,
581 mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; 576 mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
582 mem->align = 0; 577 mem->align = 0;
583 mem->flags = tmp[0]; 578 mem->flags = tmp[0];
584 pnp_register_mem_resource(option, mem); 579 pnp_register_mem_resource(dev, option, mem);
585} 580}
586 581
587/* 582/*
@@ -613,6 +608,8 @@ static int __init isapnp_create_device(struct pnp_card *card,
613 unsigned char type, tmp[17]; 608 unsigned char type, tmp[17];
614 struct pnp_option *option; 609 struct pnp_option *option;
615 struct pnp_dev *dev; 610 struct pnp_dev *dev;
611 u32 eisa_id;
612 char id[8];
616 613
617 if ((dev = isapnp_parse_device(card, size, number++)) == NULL) 614 if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
618 return 1; 615 return 1;
@@ -652,8 +649,10 @@ static int __init isapnp_create_device(struct pnp_card *card,
652 case _STAG_COMPATDEVID: 649 case _STAG_COMPATDEVID:
653 if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) { 650 if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
654 isapnp_peek(tmp, 4); 651 isapnp_peek(tmp, 4);
655 isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], 652 eisa_id = tmp[0] | tmp[1] << 8 |
656 (tmp[3] << 8) | tmp[2]); 653 tmp[2] << 16 | tmp[3] << 24;
654 pnp_eisa_id_to_string(eisa_id, id);
655 pnp_add_id(dev, id);
657 compat++; 656 compat++;
658 size = 0; 657 size = 0;
659 } 658 }
@@ -661,13 +660,13 @@ static int __init isapnp_create_device(struct pnp_card *card,
661 case _STAG_IRQ: 660 case _STAG_IRQ:
662 if (size < 2 || size > 3) 661 if (size < 2 || size > 3)
663 goto __skip; 662 goto __skip;
664 isapnp_parse_irq_resource(option, size); 663 isapnp_parse_irq_resource(dev, option, size);
665 size = 0; 664 size = 0;
666 break; 665 break;
667 case _STAG_DMA: 666 case _STAG_DMA:
668 if (size != 2) 667 if (size != 2)
669 goto __skip; 668 goto __skip;
670 isapnp_parse_dma_resource(option, size); 669 isapnp_parse_dma_resource(dev, option, size);
671 size = 0; 670 size = 0;
672 break; 671 break;
673 case _STAG_STARTDEP: 672 case _STAG_STARTDEP:
@@ -687,17 +686,18 @@ static int __init isapnp_create_device(struct pnp_card *card,
687 if (size != 0) 686 if (size != 0)
688 goto __skip; 687 goto __skip;
689 priority = 0; 688 priority = 0;
689 dev_dbg(&dev->dev, "end dependent options\n");
690 break; 690 break;
691 case _STAG_IOPORT: 691 case _STAG_IOPORT:
692 if (size != 7) 692 if (size != 7)
693 goto __skip; 693 goto __skip;
694 isapnp_parse_port_resource(option, size); 694 isapnp_parse_port_resource(dev, option, size);
695 size = 0; 695 size = 0;
696 break; 696 break;
697 case _STAG_FIXEDIO: 697 case _STAG_FIXEDIO:
698 if (size != 3) 698 if (size != 3)
699 goto __skip; 699 goto __skip;
700 isapnp_parse_fixed_port_resource(option, size); 700 isapnp_parse_fixed_port_resource(dev, option, size);
701 size = 0; 701 size = 0;
702 break; 702 break;
703 case _STAG_VENDOR: 703 case _STAG_VENDOR:
@@ -705,7 +705,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
705 case _LTAG_MEMRANGE: 705 case _LTAG_MEMRANGE:
706 if (size != 9) 706 if (size != 9)
707 goto __skip; 707 goto __skip;
708 isapnp_parse_mem_resource(option, size); 708 isapnp_parse_mem_resource(dev, option, size);
709 size = 0; 709 size = 0;
710 break; 710 break;
711 case _LTAG_ANSISTR: 711 case _LTAG_ANSISTR:
@@ -720,13 +720,13 @@ static int __init isapnp_create_device(struct pnp_card *card,
720 case _LTAG_MEM32RANGE: 720 case _LTAG_MEM32RANGE:
721 if (size != 17) 721 if (size != 17)
722 goto __skip; 722 goto __skip;
723 isapnp_parse_mem32_resource(option, size); 723 isapnp_parse_mem32_resource(dev, option, size);
724 size = 0; 724 size = 0;
725 break; 725 break;
726 case _LTAG_FIXEDMEM32RANGE: 726 case _LTAG_FIXEDMEM32RANGE:
727 if (size != 9) 727 if (size != 9)
728 goto __skip; 728 goto __skip;
729 isapnp_parse_fixed_mem32_resource(option, size); 729 isapnp_parse_fixed_mem32_resource(dev, option, size);
730 size = 0; 730 size = 0;
731 break; 731 break;
732 case _STAG_END: 732 case _STAG_END:
@@ -734,9 +734,8 @@ static int __init isapnp_create_device(struct pnp_card *card,
734 isapnp_skip_bytes(size); 734 isapnp_skip_bytes(size);
735 return 1; 735 return 1;
736 default: 736 default:
737 printk(KERN_ERR 737 dev_err(&dev->dev, "unknown tag %#x (card %i), "
738 "isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", 738 "ignored\n", type, card->number);
739 type, dev->number, card->number);
740 } 739 }
741__skip: 740__skip:
742 if (size > 0) 741 if (size > 0)
@@ -789,9 +788,8 @@ static void __init isapnp_parse_resource_map(struct pnp_card *card)
789 isapnp_skip_bytes(size); 788 isapnp_skip_bytes(size);
790 return; 789 return;
791 default: 790 default:
792 printk(KERN_ERR 791 dev_err(&card->dev, "unknown tag %#x, ignored\n",
793 "isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", 792 type);
794 type, card->number);
795 } 793 }
796__skip: 794__skip:
797 if (size > 0) 795 if (size > 0)
@@ -822,25 +820,6 @@ static unsigned char __init isapnp_checksum(unsigned char *data)
822} 820}
823 821
824/* 822/*
825 * Parse EISA id for ISA PnP card.
826 */
827static void isapnp_parse_card_id(struct pnp_card *card, unsigned short vendor,
828 unsigned short device)
829{
830 struct pnp_id *id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
831
832 if (!id)
833 return;
834 sprintf(id->id, "%c%c%c%x%x%x%x",
835 'A' + ((vendor >> 2) & 0x3f) - 1,
836 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
837 'A' + ((vendor >> 8) & 0x1f) - 1,
838 (device >> 4) & 0x0f,
839 device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f);
840 pnp_add_card_id(id, card);
841}
842
843/*
844 * Build device list for all present ISA PnP devices. 823 * Build device list for all present ISA PnP devices.
845 */ 824 */
846static int __init isapnp_build_device_list(void) 825static int __init isapnp_build_device_list(void)
@@ -848,6 +827,8 @@ static int __init isapnp_build_device_list(void)
848 int csn; 827 int csn;
849 unsigned char header[9], checksum; 828 unsigned char header[9], checksum;
850 struct pnp_card *card; 829 struct pnp_card *card;
830 u32 eisa_id;
831 char id[8];
851 832
852 isapnp_wait(); 833 isapnp_wait();
853 isapnp_key(); 834 isapnp_key();
@@ -855,32 +836,30 @@ static int __init isapnp_build_device_list(void)
855 isapnp_wake(csn); 836 isapnp_wake(csn);
856 isapnp_peek(header, 9); 837 isapnp_peek(header, 9);
857 checksum = isapnp_checksum(header); 838 checksum = isapnp_checksum(header);
839 eisa_id = header[0] | header[1] << 8 |
840 header[2] << 16 | header[3] << 24;
841 pnp_eisa_id_to_string(eisa_id, id);
842 card = pnp_alloc_card(&isapnp_protocol, csn, id);
843 if (!card)
844 continue;
845
858#if 0 846#if 0
859 printk(KERN_DEBUG 847 dev_info(&card->dev,
860 "vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 848 "vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
861 header[0], header[1], header[2], header[3], header[4], 849 header[0], header[1], header[2], header[3], header[4],
862 header[5], header[6], header[7], header[8]); 850 header[5], header[6], header[7], header[8]);
863 printk(KERN_DEBUG "checksum = 0x%x\n", checksum); 851 dev_info(&card->dev, "checksum = %#x\n", checksum);
864#endif 852#endif
865 if ((card =
866 kzalloc(sizeof(struct pnp_card), GFP_KERNEL)) == NULL)
867 continue;
868
869 card->number = csn;
870 INIT_LIST_HEAD(&card->devices); 853 INIT_LIST_HEAD(&card->devices);
871 isapnp_parse_card_id(card, (header[1] << 8) | header[0],
872 (header[3] << 8) | header[2]);
873 card->serial = 854 card->serial =
874 (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | 855 (header[7] << 24) | (header[6] << 16) | (header[5] << 8) |
875 header[4]; 856 header[4];
876 isapnp_checksum_value = 0x00; 857 isapnp_checksum_value = 0x00;
877 isapnp_parse_resource_map(card); 858 isapnp_parse_resource_map(card);
878 if (isapnp_checksum_value != 0x00) 859 if (isapnp_checksum_value != 0x00)
879 printk(KERN_ERR 860 dev_err(&card->dev, "invalid checksum %#x\n",
880 "isapnp: checksum for device %i is not valid (0x%x)\n", 861 isapnp_checksum_value);
881 csn, isapnp_checksum_value);
882 card->checksum = isapnp_checksum_value; 862 card->checksum = isapnp_checksum_value;
883 card->protocol = &isapnp_protocol;
884 863
885 pnp_add_card(card); 864 pnp_add_card(card);
886 } 865 }
@@ -947,100 +926,117 @@ EXPORT_SYMBOL(isapnp_cfg_begin);
947EXPORT_SYMBOL(isapnp_cfg_end); 926EXPORT_SYMBOL(isapnp_cfg_end);
948EXPORT_SYMBOL(isapnp_write_byte); 927EXPORT_SYMBOL(isapnp_write_byte);
949 928
950static int isapnp_read_resources(struct pnp_dev *dev, 929static int isapnp_get_resources(struct pnp_dev *dev)
951 struct pnp_resource_table *res)
952{ 930{
953 int tmp, ret; 931 struct pnp_resource *pnp_res;
932 int i, ret;
954 933
934 dev_dbg(&dev->dev, "get resources\n");
935 pnp_init_resources(dev);
936 isapnp_cfg_begin(dev->card->number, dev->number);
955 dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE); 937 dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
956 if (dev->active) { 938 if (!dev->active)
957 for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { 939 goto __end;
958 ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1)); 940
959 if (!ret) 941 for (i = 0; i < ISAPNP_MAX_PORT; i++) {
960 continue; 942 ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1));
961 res->port_resource[tmp].start = ret; 943 if (ret) {
962 res->port_resource[tmp].flags = IORESOURCE_IO; 944 pnp_res = pnp_add_io_resource(dev, ret, ret, 0);
945 if (pnp_res)
946 pnp_res->index = i;
963 } 947 }
964 for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { 948 }
965 ret = 949 for (i = 0; i < ISAPNP_MAX_MEM; i++) {
966 isapnp_read_word(ISAPNP_CFG_MEM + (tmp << 3)) << 8; 950 ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8;
967 if (!ret) 951 if (ret) {
968 continue; 952 pnp_res = pnp_add_mem_resource(dev, ret, ret, 0);
969 res->mem_resource[tmp].start = ret; 953 if (pnp_res)
970 res->mem_resource[tmp].flags = IORESOURCE_MEM; 954 pnp_res->index = i;
971 } 955 }
972 for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) { 956 }
973 ret = 957 for (i = 0; i < ISAPNP_MAX_IRQ; i++) {
974 (isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >> 958 ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8;
975 8); 959 if (ret) {
976 if (!ret) 960 pnp_res = pnp_add_irq_resource(dev, ret, 0);
977 continue; 961 if (pnp_res)
978 res->irq_resource[tmp].start = 962 pnp_res->index = i;
979 res->irq_resource[tmp].end = ret;
980 res->irq_resource[tmp].flags = IORESOURCE_IRQ;
981 } 963 }
982 for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { 964 }
983 ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp); 965 for (i = 0; i < ISAPNP_MAX_DMA; i++) {
984 if (ret == 4) 966 ret = isapnp_read_byte(ISAPNP_CFG_DMA + i);
985 continue; 967 if (ret != 4) {
986 res->dma_resource[tmp].start = 968 pnp_res = pnp_add_dma_resource(dev, ret, 0);
987 res->dma_resource[tmp].end = ret; 969 if (pnp_res)
988 res->dma_resource[tmp].flags = IORESOURCE_DMA; 970 pnp_res->index = i;
989 } 971 }
990 } 972 }
991 return 0;
992}
993
994static int isapnp_get_resources(struct pnp_dev *dev,
995 struct pnp_resource_table *res)
996{
997 int ret;
998 973
999 pnp_init_resource_table(res); 974__end:
1000 isapnp_cfg_begin(dev->card->number, dev->number);
1001 ret = isapnp_read_resources(dev, res);
1002 isapnp_cfg_end(); 975 isapnp_cfg_end();
1003 return ret; 976 return 0;
1004} 977}
1005 978
1006static int isapnp_set_resources(struct pnp_dev *dev, 979static int isapnp_set_resources(struct pnp_dev *dev)
1007 struct pnp_resource_table *res)
1008{ 980{
1009 int tmp; 981 struct pnp_resource *pnp_res;
982 struct resource *res;
983 int tmp, index;
1010 984
985 dev_dbg(&dev->dev, "set resources\n");
1011 isapnp_cfg_begin(dev->card->number, dev->number); 986 isapnp_cfg_begin(dev->card->number, dev->number);
1012 dev->active = 1; 987 dev->active = 1;
1013 for (tmp = 0; 988 for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
1014 tmp < ISAPNP_MAX_PORT 989 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, tmp);
1015 && (res->port_resource[tmp]. 990 if (!pnp_res)
1016 flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO; 991 continue;
1017 tmp++) 992 res = &pnp_res->res;
1018 isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1), 993 if (pnp_resource_valid(res)) {
1019 res->port_resource[tmp].start); 994 index = pnp_res->index;
1020 for (tmp = 0; 995 dev_dbg(&dev->dev, " set io %d to %#llx\n",
1021 tmp < ISAPNP_MAX_IRQ 996 index, (unsigned long long) res->start);
1022 && (res->irq_resource[tmp]. 997 isapnp_write_word(ISAPNP_CFG_PORT + (index << 1),
1023 flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ; 998 res->start);
1024 tmp++) { 999 }
1025 int irq = res->irq_resource[tmp].start; 1000 }
1026 if (irq == 2) 1001 for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
1027 irq = 9; 1002 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, tmp);
1028 isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq); 1003 if (!pnp_res)
1004 continue;
1005 res = &pnp_res->res;
1006 if (pnp_resource_valid(res)) {
1007 int irq = res->start;
1008 if (irq == 2)
1009 irq = 9;
1010 index = pnp_res->index;
1011 dev_dbg(&dev->dev, " set irq %d to %d\n", index, irq);
1012 isapnp_write_byte(ISAPNP_CFG_IRQ + (index << 1), irq);
1013 }
1014 }
1015 for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
1016 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, tmp);
1017 if (!pnp_res)
1018 continue;
1019 res = &pnp_res->res;
1020 if (pnp_resource_valid(res)) {
1021 index = pnp_res->index;
1022 dev_dbg(&dev->dev, " set dma %d to %lld\n",
1023 index, (unsigned long long) res->start);
1024 isapnp_write_byte(ISAPNP_CFG_DMA + index, res->start);
1025 }
1026 }
1027 for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
1028 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, tmp);
1029 if (!pnp_res)
1030 continue;
1031 res = &pnp_res->res;
1032 if (pnp_resource_valid(res)) {
1033 index = pnp_res->index;
1034 dev_dbg(&dev->dev, " set mem %d to %#llx\n",
1035 index, (unsigned long long) res->start);
1036 isapnp_write_word(ISAPNP_CFG_MEM + (index << 3),
1037 (res->start >> 8) & 0xffff);
1038 }
1029 } 1039 }
1030 for (tmp = 0;
1031 tmp < ISAPNP_MAX_DMA
1032 && (res->dma_resource[tmp].
1033 flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA;
1034 tmp++)
1035 isapnp_write_byte(ISAPNP_CFG_DMA + tmp,
1036 res->dma_resource[tmp].start);
1037 for (tmp = 0;
1038 tmp < ISAPNP_MAX_MEM
1039 && (res->mem_resource[tmp].
1040 flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM;
1041 tmp++)
1042 isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
1043 (res->mem_resource[tmp].start >> 8) & 0xffff);
1044 /* FIXME: We aren't handling 32bit mems properly here */ 1040 /* FIXME: We aren't handling 32bit mems properly here */
1045 isapnp_activate(dev->number); 1041 isapnp_activate(dev->number);
1046 isapnp_cfg_end(); 1042 isapnp_cfg_end();
@@ -1138,13 +1134,13 @@ static int __init isapnp_init(void)
1138 protocol_for_each_card(&isapnp_protocol, card) { 1134 protocol_for_each_card(&isapnp_protocol, card) {
1139 cards++; 1135 cards++;
1140 if (isapnp_verbose) { 1136 if (isapnp_verbose) {
1141 printk(KERN_INFO "isapnp: Card '%s'\n", 1137 dev_info(&card->dev, "card '%s'\n",
1142 card->name[0] ? card->name : "Unknown"); 1138 card->name[0] ? card->name : "unknown");
1143 if (isapnp_verbose < 2) 1139 if (isapnp_verbose < 2)
1144 continue; 1140 continue;
1145 card_for_each_dev(card, dev) { 1141 card_for_each_dev(card, dev) {
1146 printk(KERN_INFO "isapnp: Device '%s'\n", 1142 dev_info(&card->dev, "device '%s'\n",
1147 dev->name[0] ? dev->name : "Unknown"); 1143 dev->name[0] ? dev->name : "unknown");
1148 } 1144 }
1149 } 1145 }
1150 } 1146 }
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index c28caf272c11..bea0914ff947 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -19,100 +19,118 @@ DEFINE_MUTEX(pnp_res_mutex);
19 19
20static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) 20static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
21{ 21{
22 resource_size_t *start, *end; 22 struct pnp_resource *pnp_res;
23 unsigned long *flags; 23 struct resource *res;
24 24
25 if (idx >= PNP_MAX_PORT) { 25 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, idx);
26 if (!pnp_res) {
26 dev_err(&dev->dev, "too many I/O port resources\n"); 27 dev_err(&dev->dev, "too many I/O port resources\n");
27 /* pretend we were successful so at least the manager won't try again */ 28 /* pretend we were successful so at least the manager won't try again */
28 return 1; 29 return 1;
29 } 30 }
30 31
32 res = &pnp_res->res;
33
31 /* check if this resource has been manually set, if so skip */ 34 /* check if this resource has been manually set, if so skip */
32 if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO)) 35 if (!(res->flags & IORESOURCE_AUTO)) {
36 dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
37 "flags %#lx\n", idx, (unsigned long long) res->start,
38 (unsigned long long) res->end, res->flags);
33 return 1; 39 return 1;
34 40 }
35 start = &dev->res.port_resource[idx].start;
36 end = &dev->res.port_resource[idx].end;
37 flags = &dev->res.port_resource[idx].flags;
38 41
39 /* set the initial values */ 42 /* set the initial values */
40 *flags |= rule->flags | IORESOURCE_IO; 43 pnp_res->index = idx;
41 *flags &= ~IORESOURCE_UNSET; 44 res->flags |= rule->flags | IORESOURCE_IO;
45 res->flags &= ~IORESOURCE_UNSET;
42 46
43 if (!rule->size) { 47 if (!rule->size) {
44 *flags |= IORESOURCE_DISABLED; 48 res->flags |= IORESOURCE_DISABLED;
49 dev_dbg(&dev->dev, " io %d disabled\n", idx);
45 return 1; /* skip disabled resource requests */ 50 return 1; /* skip disabled resource requests */
46 } 51 }
47 52
48 *start = rule->min; 53 res->start = rule->min;
49 *end = *start + rule->size - 1; 54 res->end = res->start + rule->size - 1;
50 55
51 /* run through until pnp_check_port is happy */ 56 /* run through until pnp_check_port is happy */
52 while (!pnp_check_port(dev, idx)) { 57 while (!pnp_check_port(dev, res)) {
53 *start += rule->align; 58 res->start += rule->align;
54 *end = *start + rule->size - 1; 59 res->end = res->start + rule->size - 1;
55 if (*start > rule->max || !rule->align) 60 if (res->start > rule->max || !rule->align) {
61 dev_dbg(&dev->dev, " couldn't assign io %d\n", idx);
56 return 0; 62 return 0;
63 }
57 } 64 }
65 dev_dbg(&dev->dev, " assign io %d %#llx-%#llx\n", idx,
66 (unsigned long long) res->start, (unsigned long long) res->end);
58 return 1; 67 return 1;
59} 68}
60 69
61static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) 70static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
62{ 71{
63 resource_size_t *start, *end; 72 struct pnp_resource *pnp_res;
64 unsigned long *flags; 73 struct resource *res;
65 74
66 if (idx >= PNP_MAX_MEM) { 75 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, idx);
76 if (!pnp_res) {
67 dev_err(&dev->dev, "too many memory resources\n"); 77 dev_err(&dev->dev, "too many memory resources\n");
68 /* pretend we were successful so at least the manager won't try again */ 78 /* pretend we were successful so at least the manager won't try again */
69 return 1; 79 return 1;
70 } 80 }
71 81
82 res = &pnp_res->res;
83
72 /* check if this resource has been manually set, if so skip */ 84 /* check if this resource has been manually set, if so skip */
73 if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO)) 85 if (!(res->flags & IORESOURCE_AUTO)) {
86 dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
87 "flags %#lx\n", idx, (unsigned long long) res->start,
88 (unsigned long long) res->end, res->flags);
74 return 1; 89 return 1;
75 90 }
76 start = &dev->res.mem_resource[idx].start;
77 end = &dev->res.mem_resource[idx].end;
78 flags = &dev->res.mem_resource[idx].flags;
79 91
80 /* set the initial values */ 92 /* set the initial values */
81 *flags |= rule->flags | IORESOURCE_MEM; 93 pnp_res->index = idx;
82 *flags &= ~IORESOURCE_UNSET; 94 res->flags |= rule->flags | IORESOURCE_MEM;
95 res->flags &= ~IORESOURCE_UNSET;
83 96
84 /* convert pnp flags to standard Linux flags */ 97 /* convert pnp flags to standard Linux flags */
85 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) 98 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
86 *flags |= IORESOURCE_READONLY; 99 res->flags |= IORESOURCE_READONLY;
87 if (rule->flags & IORESOURCE_MEM_CACHEABLE) 100 if (rule->flags & IORESOURCE_MEM_CACHEABLE)
88 *flags |= IORESOURCE_CACHEABLE; 101 res->flags |= IORESOURCE_CACHEABLE;
89 if (rule->flags & IORESOURCE_MEM_RANGELENGTH) 102 if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
90 *flags |= IORESOURCE_RANGELENGTH; 103 res->flags |= IORESOURCE_RANGELENGTH;
91 if (rule->flags & IORESOURCE_MEM_SHADOWABLE) 104 if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
92 *flags |= IORESOURCE_SHADOWABLE; 105 res->flags |= IORESOURCE_SHADOWABLE;
93 106
94 if (!rule->size) { 107 if (!rule->size) {
95 *flags |= IORESOURCE_DISABLED; 108 res->flags |= IORESOURCE_DISABLED;
109 dev_dbg(&dev->dev, " mem %d disabled\n", idx);
96 return 1; /* skip disabled resource requests */ 110 return 1; /* skip disabled resource requests */
97 } 111 }
98 112
99 *start = rule->min; 113 res->start = rule->min;
100 *end = *start + rule->size - 1; 114 res->end = res->start + rule->size - 1;
101 115
102 /* run through until pnp_check_mem is happy */ 116 /* run through until pnp_check_mem is happy */
103 while (!pnp_check_mem(dev, idx)) { 117 while (!pnp_check_mem(dev, res)) {
104 *start += rule->align; 118 res->start += rule->align;
105 *end = *start + rule->size - 1; 119 res->end = res->start + rule->size - 1;
106 if (*start > rule->max || !rule->align) 120 if (res->start > rule->max || !rule->align) {
121 dev_dbg(&dev->dev, " couldn't assign mem %d\n", idx);
107 return 0; 122 return 0;
123 }
108 } 124 }
125 dev_dbg(&dev->dev, " assign mem %d %#llx-%#llx\n", idx,
126 (unsigned long long) res->start, (unsigned long long) res->end);
109 return 1; 127 return 1;
110} 128}
111 129
112static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) 130static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
113{ 131{
114 resource_size_t *start, *end; 132 struct pnp_resource *pnp_res;
115 unsigned long *flags; 133 struct resource *res;
116 int i; 134 int i;
117 135
118 /* IRQ priority: this table is good for i386 */ 136 /* IRQ priority: this table is good for i386 */
@@ -120,49 +138,59 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
120 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 138 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
121 }; 139 };
122 140
123 if (idx >= PNP_MAX_IRQ) { 141 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, idx);
142 if (!pnp_res) {
124 dev_err(&dev->dev, "too many IRQ resources\n"); 143 dev_err(&dev->dev, "too many IRQ resources\n");
125 /* pretend we were successful so at least the manager won't try again */ 144 /* pretend we were successful so at least the manager won't try again */
126 return 1; 145 return 1;
127 } 146 }
128 147
148 res = &pnp_res->res;
149
129 /* check if this resource has been manually set, if so skip */ 150 /* check if this resource has been manually set, if so skip */
130 if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO)) 151 if (!(res->flags & IORESOURCE_AUTO)) {
152 dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
153 idx, (int) res->start, res->flags);
131 return 1; 154 return 1;
132 155 }
133 start = &dev->res.irq_resource[idx].start;
134 end = &dev->res.irq_resource[idx].end;
135 flags = &dev->res.irq_resource[idx].flags;
136 156
137 /* set the initial values */ 157 /* set the initial values */
138 *flags |= rule->flags | IORESOURCE_IRQ; 158 pnp_res->index = idx;
139 *flags &= ~IORESOURCE_UNSET; 159 res->flags |= rule->flags | IORESOURCE_IRQ;
160 res->flags &= ~IORESOURCE_UNSET;
140 161
141 if (bitmap_empty(rule->map, PNP_IRQ_NR)) { 162 if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
142 *flags |= IORESOURCE_DISABLED; 163 res->flags |= IORESOURCE_DISABLED;
164 dev_dbg(&dev->dev, " irq %d disabled\n", idx);
143 return 1; /* skip disabled resource requests */ 165 return 1; /* skip disabled resource requests */
144 } 166 }
145 167
146 /* TBD: need check for >16 IRQ */ 168 /* TBD: need check for >16 IRQ */
147 *start = find_next_bit(rule->map, PNP_IRQ_NR, 16); 169 res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
148 if (*start < PNP_IRQ_NR) { 170 if (res->start < PNP_IRQ_NR) {
149 *end = *start; 171 res->end = res->start;
172 dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
173 (int) res->start);
150 return 1; 174 return 1;
151 } 175 }
152 for (i = 0; i < 16; i++) { 176 for (i = 0; i < 16; i++) {
153 if (test_bit(xtab[i], rule->map)) { 177 if (test_bit(xtab[i], rule->map)) {
154 *start = *end = xtab[i]; 178 res->start = res->end = xtab[i];
155 if (pnp_check_irq(dev, idx)) 179 if (pnp_check_irq(dev, res)) {
180 dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
181 (int) res->start);
156 return 1; 182 return 1;
183 }
157 } 184 }
158 } 185 }
186 dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx);
159 return 0; 187 return 0;
160} 188}
161 189
162static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) 190static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
163{ 191{
164 resource_size_t *start, *end; 192 struct pnp_resource *pnp_res;
165 unsigned long *flags; 193 struct resource *res;
166 int i; 194 int i;
167 195
168 /* DMA priority: this table is good for i386 */ 196 /* DMA priority: this table is good for i386 */
@@ -170,71 +198,89 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
170 1, 3, 5, 6, 7, 0, 2, 4 198 1, 3, 5, 6, 7, 0, 2, 4
171 }; 199 };
172 200
173 if (idx >= PNP_MAX_DMA) { 201 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx);
202 if (!pnp_res) {
174 dev_err(&dev->dev, "too many DMA resources\n"); 203 dev_err(&dev->dev, "too many DMA resources\n");
175 return; 204 return;
176 } 205 }
177 206
207 res = &pnp_res->res;
208
178 /* check if this resource has been manually set, if so skip */ 209 /* check if this resource has been manually set, if so skip */
179 if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) 210 if (!(res->flags & IORESOURCE_AUTO)) {
211 dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
212 idx, (int) res->start, res->flags);
180 return; 213 return;
181 214 }
182 start = &dev->res.dma_resource[idx].start;
183 end = &dev->res.dma_resource[idx].end;
184 flags = &dev->res.dma_resource[idx].flags;
185 215
186 /* set the initial values */ 216 /* set the initial values */
187 *flags |= rule->flags | IORESOURCE_DMA; 217 pnp_res->index = idx;
188 *flags &= ~IORESOURCE_UNSET; 218 res->flags |= rule->flags | IORESOURCE_DMA;
219 res->flags &= ~IORESOURCE_UNSET;
189 220
190 for (i = 0; i < 8; i++) { 221 for (i = 0; i < 8; i++) {
191 if (rule->map & (1 << xtab[i])) { 222 if (rule->map & (1 << xtab[i])) {
192 *start = *end = xtab[i]; 223 res->start = res->end = xtab[i];
193 if (pnp_check_dma(dev, idx)) 224 if (pnp_check_dma(dev, res)) {
225 dev_dbg(&dev->dev, " assign dma %d %d\n", idx,
226 (int) res->start);
194 return; 227 return;
228 }
195 } 229 }
196 } 230 }
197#ifdef MAX_DMA_CHANNELS 231#ifdef MAX_DMA_CHANNELS
198 *start = *end = MAX_DMA_CHANNELS; 232 res->start = res->end = MAX_DMA_CHANNELS;
199#endif 233#endif
200 *flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; 234 res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
235 dev_dbg(&dev->dev, " disable dma %d\n", idx);
236}
237
238void pnp_init_resource(struct resource *res)
239{
240 unsigned long type;
241
242 type = res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
243 IORESOURCE_IRQ | IORESOURCE_DMA);
244
245 res->name = NULL;
246 res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET;
247 if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) {
248 res->start = -1;
249 res->end = -1;
250 } else {
251 res->start = 0;
252 res->end = 0;
253 }
201} 254}
202 255
203/** 256/**
204 * pnp_init_resources - Resets a resource table to default values. 257 * pnp_init_resources - Resets a resource table to default values.
205 * @table: pointer to the desired resource table 258 * @table: pointer to the desired resource table
206 */ 259 */
207void pnp_init_resource_table(struct pnp_resource_table *table) 260void pnp_init_resources(struct pnp_dev *dev)
208{ 261{
262 struct resource *res;
209 int idx; 263 int idx;
210 264
211 for (idx = 0; idx < PNP_MAX_IRQ; idx++) { 265 for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
212 table->irq_resource[idx].name = NULL; 266 res = &dev->res->irq[idx].res;
213 table->irq_resource[idx].start = -1; 267 res->flags = IORESOURCE_IRQ;
214 table->irq_resource[idx].end = -1; 268 pnp_init_resource(res);
215 table->irq_resource[idx].flags =
216 IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
217 } 269 }
218 for (idx = 0; idx < PNP_MAX_DMA; idx++) { 270 for (idx = 0; idx < PNP_MAX_DMA; idx++) {
219 table->dma_resource[idx].name = NULL; 271 res = &dev->res->dma[idx].res;
220 table->dma_resource[idx].start = -1; 272 res->flags = IORESOURCE_DMA;
221 table->dma_resource[idx].end = -1; 273 pnp_init_resource(res);
222 table->dma_resource[idx].flags =
223 IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
224 } 274 }
225 for (idx = 0; idx < PNP_MAX_PORT; idx++) { 275 for (idx = 0; idx < PNP_MAX_PORT; idx++) {
226 table->port_resource[idx].name = NULL; 276 res = &dev->res->port[idx].res;
227 table->port_resource[idx].start = 0; 277 res->flags = IORESOURCE_IO;
228 table->port_resource[idx].end = 0; 278 pnp_init_resource(res);
229 table->port_resource[idx].flags =
230 IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
231 } 279 }
232 for (idx = 0; idx < PNP_MAX_MEM; idx++) { 280 for (idx = 0; idx < PNP_MAX_MEM; idx++) {
233 table->mem_resource[idx].name = NULL; 281 res = &dev->res->mem[idx].res;
234 table->mem_resource[idx].start = 0; 282 res->flags = IORESOURCE_MEM;
235 table->mem_resource[idx].end = 0; 283 pnp_init_resource(res);
236 table->mem_resource[idx].flags =
237 IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
238 } 284 }
239} 285}
240 286
@@ -242,41 +288,38 @@ void pnp_init_resource_table(struct pnp_resource_table *table)
242 * pnp_clean_resources - clears resources that were not manually set 288 * pnp_clean_resources - clears resources that were not manually set
243 * @res: the resources to clean 289 * @res: the resources to clean
244 */ 290 */
245static void pnp_clean_resource_table(struct pnp_resource_table *res) 291static void pnp_clean_resource_table(struct pnp_dev *dev)
246{ 292{
293 struct resource *res;
247 int idx; 294 int idx;
248 295
249 for (idx = 0; idx < PNP_MAX_IRQ; idx++) { 296 for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
250 if (!(res->irq_resource[idx].flags & IORESOURCE_AUTO)) 297 res = &dev->res->irq[idx].res;
251 continue; 298 if (res->flags & IORESOURCE_AUTO) {
252 res->irq_resource[idx].start = -1; 299 res->flags = IORESOURCE_IRQ;
253 res->irq_resource[idx].end = -1; 300 pnp_init_resource(res);
254 res->irq_resource[idx].flags = 301 }
255 IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
256 } 302 }
257 for (idx = 0; idx < PNP_MAX_DMA; idx++) { 303 for (idx = 0; idx < PNP_MAX_DMA; idx++) {
258 if (!(res->dma_resource[idx].flags & IORESOURCE_AUTO)) 304 res = &dev->res->dma[idx].res;
259 continue; 305 if (res->flags & IORESOURCE_AUTO) {
260 res->dma_resource[idx].start = -1; 306 res->flags = IORESOURCE_DMA;
261 res->dma_resource[idx].end = -1; 307 pnp_init_resource(res);
262 res->dma_resource[idx].flags = 308 }
263 IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
264 } 309 }
265 for (idx = 0; idx < PNP_MAX_PORT; idx++) { 310 for (idx = 0; idx < PNP_MAX_PORT; idx++) {
266 if (!(res->port_resource[idx].flags & IORESOURCE_AUTO)) 311 res = &dev->res->port[idx].res;
267 continue; 312 if (res->flags & IORESOURCE_AUTO) {
268 res->port_resource[idx].start = 0; 313 res->flags = IORESOURCE_IO;
269 res->port_resource[idx].end = 0; 314 pnp_init_resource(res);
270 res->port_resource[idx].flags = 315 }
271 IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
272 } 316 }
273 for (idx = 0; idx < PNP_MAX_MEM; idx++) { 317 for (idx = 0; idx < PNP_MAX_MEM; idx++) {
274 if (!(res->mem_resource[idx].flags & IORESOURCE_AUTO)) 318 res = &dev->res->mem[idx].res;
275 continue; 319 if (res->flags & IORESOURCE_AUTO) {
276 res->mem_resource[idx].start = 0; 320 res->flags = IORESOURCE_MEM;
277 res->mem_resource[idx].end = 0; 321 pnp_init_resource(res);
278 res->mem_resource[idx].flags = 322 }
279 IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
280 } 323 }
281} 324}
282 325
@@ -298,9 +341,11 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
298 if (!pnp_can_configure(dev)) 341 if (!pnp_can_configure(dev))
299 return -ENODEV; 342 return -ENODEV;
300 343
344 dbg_pnp_show_resources(dev, "before pnp_assign_resources");
301 mutex_lock(&pnp_res_mutex); 345 mutex_lock(&pnp_res_mutex);
302 pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ 346 pnp_clean_resource_table(dev);
303 if (dev->independent) { 347 if (dev->independent) {
348 dev_dbg(&dev->dev, "assigning independent options\n");
304 port = dev->independent->port; 349 port = dev->independent->port;
305 mem = dev->independent->mem; 350 mem = dev->independent->mem;
306 irq = dev->independent->irq; 351 irq = dev->independent->irq;
@@ -333,6 +378,8 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
333 if (depnum) { 378 if (depnum) {
334 struct pnp_option *dep; 379 struct pnp_option *dep;
335 int i; 380 int i;
381
382 dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum);
336 for (i = 1, dep = dev->dependent; i < depnum; 383 for (i = 1, dep = dev->dependent; i < depnum;
337 i++, dep = dep->next) 384 i++, dep = dep->next)
338 if (!dep) 385 if (!dep)
@@ -368,68 +415,17 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
368 goto fail; 415 goto fail;
369 416
370 mutex_unlock(&pnp_res_mutex); 417 mutex_unlock(&pnp_res_mutex);
418 dbg_pnp_show_resources(dev, "after pnp_assign_resources");
371 return 1; 419 return 1;
372 420
373fail: 421fail:
374 pnp_clean_resource_table(&dev->res); 422 pnp_clean_resource_table(dev);
375 mutex_unlock(&pnp_res_mutex); 423 mutex_unlock(&pnp_res_mutex);
424 dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)");
376 return 0; 425 return 0;
377} 426}
378 427
379/** 428/**
380 * pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
381 * @dev: pointer to the desired device
382 * @res: pointer to the new resource config
383 * @mode: 0 or PNP_CONFIG_FORCE
384 *
385 * This function can be used by drivers that want to manually set thier resources.
386 */
387int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res,
388 int mode)
389{
390 int i;
391 struct pnp_resource_table *bak;
392
393 if (!pnp_can_configure(dev))
394 return -ENODEV;
395 bak = pnp_alloc(sizeof(struct pnp_resource_table));
396 if (!bak)
397 return -ENOMEM;
398 *bak = dev->res;
399
400 mutex_lock(&pnp_res_mutex);
401 dev->res = *res;
402 if (!(mode & PNP_CONFIG_FORCE)) {
403 for (i = 0; i < PNP_MAX_PORT; i++) {
404 if (!pnp_check_port(dev, i))
405 goto fail;
406 }
407 for (i = 0; i < PNP_MAX_MEM; i++) {
408 if (!pnp_check_mem(dev, i))
409 goto fail;
410 }
411 for (i = 0; i < PNP_MAX_IRQ; i++) {
412 if (!pnp_check_irq(dev, i))
413 goto fail;
414 }
415 for (i = 0; i < PNP_MAX_DMA; i++) {
416 if (!pnp_check_dma(dev, i))
417 goto fail;
418 }
419 }
420 mutex_unlock(&pnp_res_mutex);
421
422 kfree(bak);
423 return 0;
424
425fail:
426 dev->res = *bak;
427 mutex_unlock(&pnp_res_mutex);
428 kfree(bak);
429 return -EINVAL;
430}
431
432/**
433 * pnp_auto_config_dev - automatically assigns resources to a device 429 * pnp_auto_config_dev - automatically assigns resources to a device
434 * @dev: pointer to the desired device 430 * @dev: pointer to the desired device
435 */ 431 */
@@ -473,7 +469,8 @@ int pnp_start_dev(struct pnp_dev *dev)
473 return -EINVAL; 469 return -EINVAL;
474 } 470 }
475 471
476 if (dev->protocol->set(dev, &dev->res) < 0) { 472 dbg_pnp_show_resources(dev, "pnp_start_dev");
473 if (dev->protocol->set(dev) < 0) {
477 dev_err(&dev->dev, "activation failed\n"); 474 dev_err(&dev->dev, "activation failed\n");
478 return -EIO; 475 return -EIO;
479 } 476 }
@@ -549,30 +546,13 @@ int pnp_disable_dev(struct pnp_dev *dev)
549 546
550 /* release the resources so that other devices can use them */ 547 /* release the resources so that other devices can use them */
551 mutex_lock(&pnp_res_mutex); 548 mutex_lock(&pnp_res_mutex);
552 pnp_clean_resource_table(&dev->res); 549 pnp_clean_resource_table(dev);
553 mutex_unlock(&pnp_res_mutex); 550 mutex_unlock(&pnp_res_mutex);
554 551
555 return 0; 552 return 0;
556} 553}
557 554
558/**
559 * pnp_resource_change - change one resource
560 * @resource: pointer to resource to be changed
561 * @start: start of region
562 * @size: size of region
563 */
564void pnp_resource_change(struct resource *resource, resource_size_t start,
565 resource_size_t size)
566{
567 resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET);
568 resource->start = start;
569 resource->end = start + size - 1;
570}
571
572EXPORT_SYMBOL(pnp_manual_config_dev);
573EXPORT_SYMBOL(pnp_start_dev); 555EXPORT_SYMBOL(pnp_start_dev);
574EXPORT_SYMBOL(pnp_stop_dev); 556EXPORT_SYMBOL(pnp_stop_dev);
575EXPORT_SYMBOL(pnp_activate_dev); 557EXPORT_SYMBOL(pnp_activate_dev);
576EXPORT_SYMBOL(pnp_disable_dev); 558EXPORT_SYMBOL(pnp_disable_dev);
577EXPORT_SYMBOL(pnp_resource_change);
578EXPORT_SYMBOL(pnp_init_resource_table);
diff --git a/drivers/pnp/pnpacpi/Makefile b/drivers/pnp/pnpacpi/Makefile
index 905326fcca85..2d7a1e6908be 100644
--- a/drivers/pnp/pnpacpi/Makefile
+++ b/drivers/pnp/pnpacpi/Makefile
@@ -3,3 +3,7 @@
3# 3#
4 4
5obj-y := core.o rsparser.o 5obj-y := core.o rsparser.o
6
7ifeq ($(CONFIG_PNP_DEBUG),y)
8EXTRA_CFLAGS += -DDEBUG
9endif
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 63e64ef39fb7..50902773beaf 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -25,6 +25,7 @@
25#include <acpi/acpi_bus.h> 25#include <acpi/acpi_bus.h>
26#include <acpi/actypes.h> 26#include <acpi/actypes.h>
27 27
28#include "../base.h"
28#include "pnpacpi.h" 29#include "pnpacpi.h"
29 30
30static int num = 0; 31static int num = 0;
@@ -72,40 +73,24 @@ static int __init ispnpidacpi(char *id)
72 return 1; 73 return 1;
73} 74}
74 75
75static void __init pnpidacpi_to_pnpid(char *id, char *str) 76static int pnpacpi_get_resources(struct pnp_dev *dev)
76{ 77{
77 str[0] = id[0]; 78 dev_dbg(&dev->dev, "get resources\n");
78 str[1] = id[1]; 79 return pnpacpi_parse_allocated_resource(dev);
79 str[2] = id[2];
80 str[3] = tolower(id[3]);
81 str[4] = tolower(id[4]);
82 str[5] = tolower(id[5]);
83 str[6] = tolower(id[6]);
84 str[7] = '\0';
85} 80}
86 81
87static int pnpacpi_get_resources(struct pnp_dev *dev, 82static int pnpacpi_set_resources(struct pnp_dev *dev)
88 struct pnp_resource_table *res)
89{
90 acpi_status status;
91
92 status = pnpacpi_parse_allocated_resource((acpi_handle) dev->data,
93 &dev->res);
94 return ACPI_FAILURE(status) ? -ENODEV : 0;
95}
96
97static int pnpacpi_set_resources(struct pnp_dev *dev,
98 struct pnp_resource_table *res)
99{ 83{
100 acpi_handle handle = dev->data; 84 acpi_handle handle = dev->data;
101 struct acpi_buffer buffer; 85 struct acpi_buffer buffer;
102 int ret = 0; 86 int ret;
103 acpi_status status; 87 acpi_status status;
104 88
105 ret = pnpacpi_build_resource_template(handle, &buffer); 89 dev_dbg(&dev->dev, "set resources\n");
90 ret = pnpacpi_build_resource_template(dev, &buffer);
106 if (ret) 91 if (ret)
107 return ret; 92 return ret;
108 ret = pnpacpi_encode_resources(res, &buffer); 93 ret = pnpacpi_encode_resources(dev, &buffer);
109 if (ret) { 94 if (ret) {
110 kfree(buffer.pointer); 95 kfree(buffer.pointer);
111 return ret; 96 return ret;
@@ -163,7 +148,6 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
163{ 148{
164 acpi_handle temp = NULL; 149 acpi_handle temp = NULL;
165 acpi_status status; 150 acpi_status status;
166 struct pnp_id *dev_id;
167 struct pnp_dev *dev; 151 struct pnp_dev *dev;
168 152
169 status = acpi_get_handle(device->handle, "_CRS", &temp); 153 status = acpi_get_handle(device->handle, "_CRS", &temp);
@@ -171,11 +155,10 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
171 is_exclusive_device(device)) 155 is_exclusive_device(device))
172 return 0; 156 return 0;
173 157
174 dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); 158 dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
175 if (!dev) { 159 if (!dev)
176 pnp_err("Out of memory");
177 return -ENOMEM; 160 return -ENOMEM;
178 } 161
179 dev->data = device->handle; 162 dev->data = device->handle;
180 /* .enabled means the device can decode the resources */ 163 /* .enabled means the device can decode the resources */
181 dev->active = device->status.enabled; 164 dev->active = device->status.enabled;
@@ -191,44 +174,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
191 if (ACPI_SUCCESS(status)) 174 if (ACPI_SUCCESS(status))
192 dev->capabilities |= PNP_DISABLE; 175 dev->capabilities |= PNP_DISABLE;
193 176
194 dev->protocol = &pnpacpi_protocol;
195
196 if (strlen(acpi_device_name(device))) 177 if (strlen(acpi_device_name(device)))
197 strncpy(dev->name, acpi_device_name(device), sizeof(dev->name)); 178 strncpy(dev->name, acpi_device_name(device), sizeof(dev->name));
198 else 179 else
199 strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); 180 strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));
200 181
201 dev->number = num; 182 if (dev->active)
202 183 pnpacpi_parse_allocated_resource(dev);
203 /* set the initial values for the PnP device */
204 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
205 if (!dev_id)
206 goto err;
207 pnpidacpi_to_pnpid(acpi_device_hid(device), dev_id->id);
208 pnp_add_id(dev_id, dev);
209
210 if (dev->active) {
211 /* parse allocated resource */
212 status = pnpacpi_parse_allocated_resource(device->handle,
213 &dev->res);
214 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
215 pnp_err("PnPACPI: METHOD_NAME__CRS failure for %s",
216 dev_id->id);
217 goto err1;
218 }
219 }
220 184
221 if (dev->capabilities & PNP_CONFIGURABLE) { 185 if (dev->capabilities & PNP_CONFIGURABLE)
222 status = pnpacpi_parse_resource_option_data(device->handle, 186 pnpacpi_parse_resource_option_data(dev);
223 dev);
224 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
225 pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s",
226 dev_id->id);
227 goto err1;
228 }
229 }
230 187
231 /* parse compatible ids */
232 if (device->flags.compatible_ids) { 188 if (device->flags.compatible_ids) {
233 struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; 189 struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
234 int i; 190 int i;
@@ -236,27 +192,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
236 for (i = 0; i < cid_list->count; i++) { 192 for (i = 0; i < cid_list->count; i++) {
237 if (!ispnpidacpi(cid_list->id[i].value)) 193 if (!ispnpidacpi(cid_list->id[i].value))
238 continue; 194 continue;
239 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); 195 pnp_add_id(dev, cid_list->id[i].value);
240 if (!dev_id)
241 continue;
242
243 pnpidacpi_to_pnpid(cid_list->id[i].value, dev_id->id);
244 pnp_add_id(dev_id, dev);
245 } 196 }
246 } 197 }
247 198
248 /* clear out the damaged flags */ 199 /* clear out the damaged flags */
249 if (!dev->active) 200 if (!dev->active)
250 pnp_init_resource_table(&dev->res); 201 pnp_init_resources(dev);
251 pnp_add_device(dev); 202 pnp_add_device(dev);
252 num++; 203 num++;
253 204
254 return AE_OK; 205 return AE_OK;
255err1:
256 kfree(dev_id);
257err:
258 kfree(dev);
259 return -EINVAL;
260} 206}
261 207
262static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, 208static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
diff --git a/drivers/pnp/pnpacpi/pnpacpi.h b/drivers/pnp/pnpacpi/pnpacpi.h
index f28e2ed66fa3..3e60225b0227 100644
--- a/drivers/pnp/pnpacpi/pnpacpi.h
+++ b/drivers/pnp/pnpacpi/pnpacpi.h
@@ -5,8 +5,8 @@
5#include <linux/acpi.h> 5#include <linux/acpi.h>
6#include <linux/pnp.h> 6#include <linux/pnp.h>
7 7
8acpi_status pnpacpi_parse_allocated_resource(acpi_handle, struct pnp_resource_table*); 8int pnpacpi_parse_allocated_resource(struct pnp_dev *);
9acpi_status pnpacpi_parse_resource_option_data(acpi_handle, struct pnp_dev*); 9int pnpacpi_parse_resource_option_data(struct pnp_dev *);
10int pnpacpi_encode_resources(struct pnp_resource_table *, struct acpi_buffer *); 10int pnpacpi_encode_resources(struct pnp_dev *, struct acpi_buffer *);
11int pnpacpi_build_resource_template(acpi_handle, struct acpi_buffer*); 11int pnpacpi_build_resource_template(struct pnp_dev *, struct acpi_buffer *);
12#endif 12#endif
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 98cbc9f18eed..0201c8adfda7 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -21,6 +21,8 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/acpi.h> 22#include <linux/acpi.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/pnp.h>
25#include "../base.h"
24#include "pnpacpi.h" 26#include "pnpacpi.h"
25 27
26#ifdef CONFIG_IA64 28#ifdef CONFIG_IA64
@@ -32,19 +34,26 @@
32/* 34/*
33 * Allocated Resources 35 * Allocated Resources
34 */ 36 */
35static int irq_flags(int triggering, int polarity) 37static int irq_flags(int triggering, int polarity, int shareable)
36{ 38{
39 int flags;
40
37 if (triggering == ACPI_LEVEL_SENSITIVE) { 41 if (triggering == ACPI_LEVEL_SENSITIVE) {
38 if (polarity == ACPI_ACTIVE_LOW) 42 if (polarity == ACPI_ACTIVE_LOW)
39 return IORESOURCE_IRQ_LOWLEVEL; 43 flags = IORESOURCE_IRQ_LOWLEVEL;
40 else 44 else
41 return IORESOURCE_IRQ_HIGHLEVEL; 45 flags = IORESOURCE_IRQ_HIGHLEVEL;
42 } else { 46 } else {
43 if (polarity == ACPI_ACTIVE_LOW) 47 if (polarity == ACPI_ACTIVE_LOW)
44 return IORESOURCE_IRQ_LOWEDGE; 48 flags = IORESOURCE_IRQ_LOWEDGE;
45 else 49 else
46 return IORESOURCE_IRQ_HIGHEDGE; 50 flags = IORESOURCE_IRQ_HIGHEDGE;
47 } 51 }
52
53 if (shareable)
54 flags |= IORESOURCE_IRQ_SHAREABLE;
55
56 return flags;
48} 57}
49 58
50static void decode_irq_flags(int flag, int *triggering, int *polarity) 59static void decode_irq_flags(int flag, int *triggering, int *polarity)
@@ -69,29 +78,16 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity)
69 } 78 }
70} 79}
71 80
72static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, 81static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
73 u32 gsi, int triggering, 82 u32 gsi, int triggering,
74 int polarity, int shareable) 83 int polarity, int shareable)
75{ 84{
76 int i = 0; 85 int irq, flags;
77 int irq;
78 int p, t; 86 int p, t;
79 static unsigned char warned;
80 87
81 if (!valid_IRQ(gsi)) 88 if (!valid_IRQ(gsi))
82 return; 89 return;
83 90
84 while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
85 i < PNP_MAX_IRQ)
86 i++;
87 if (i >= PNP_MAX_IRQ) {
88 if (!warned) {
89 printk(KERN_WARNING "pnpacpi: exceeded the max number"
90 " of IRQ resources: %d\n", PNP_MAX_IRQ);
91 warned = 1;
92 }
93 return;
94 }
95 /* 91 /*
96 * in IO-APIC mode, use overrided attribute. Two reasons: 92 * in IO-APIC mode, use overrided attribute. Two reasons:
97 * 1. BIOS bug in DSDT 93 * 1. BIOS bug in DSDT
@@ -102,27 +98,21 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
102 p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; 98 p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
103 99
104 if (triggering != t || polarity != p) { 100 if (triggering != t || polarity != p) {
105 pnp_warn("IRQ %d override to %s, %s", 101 dev_warn(&dev->dev, "IRQ %d override to %s, %s\n",
106 gsi, t ? "edge":"level", p ? "low":"high"); 102 gsi, t ? "edge":"level", p ? "low":"high");
107 triggering = t; 103 triggering = t;
108 polarity = p; 104 polarity = p;
109 } 105 }
110 } 106 }
111 107
112 res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag 108 flags = irq_flags(triggering, polarity, shareable);
113 res->irq_resource[i].flags |= irq_flags(triggering, polarity);
114 irq = acpi_register_gsi(gsi, triggering, polarity); 109 irq = acpi_register_gsi(gsi, triggering, polarity);
115 if (irq < 0) { 110 if (irq >= 0)
116 res->irq_resource[i].flags |= IORESOURCE_DISABLED; 111 pcibios_penalize_isa_irq(irq, 1);
117 return; 112 else
118 } 113 flags |= IORESOURCE_DISABLED;
119
120 if (shareable)
121 res->irq_resource[i].flags |= IORESOURCE_IRQ_SHAREABLE;
122 114
123 res->irq_resource[i].start = irq; 115 pnp_add_irq_resource(dev, irq, flags);
124 res->irq_resource[i].end = irq;
125 pcibios_penalize_isa_irq(irq, 1);
126} 116}
127 117
128static int dma_flags(int type, int bus_master, int transfer) 118static int dma_flags(int type, int bus_master, int transfer)
@@ -168,88 +158,36 @@ static int dma_flags(int type, int bus_master, int transfer)
168 return flags; 158 return flags;
169} 159}
170 160
171static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, 161static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
172 u32 dma, int type, 162 u64 len, int io_decode)
173 int bus_master, int transfer)
174{ 163{
175 int i = 0; 164 int flags = 0;
176 static unsigned char warned; 165 u64 end = start + len - 1;
177
178 while (i < PNP_MAX_DMA &&
179 !(res->dma_resource[i].flags & IORESOURCE_UNSET))
180 i++;
181 if (i < PNP_MAX_DMA) {
182 res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
183 res->dma_resource[i].flags |=
184 dma_flags(type, bus_master, transfer);
185 if (dma == -1) {
186 res->dma_resource[i].flags |= IORESOURCE_DISABLED;
187 return;
188 }
189 res->dma_resource[i].start = dma;
190 res->dma_resource[i].end = dma;
191 } else if (!warned) {
192 printk(KERN_WARNING "pnpacpi: exceeded the max number of DMA "
193 "resources: %d \n", PNP_MAX_DMA);
194 warned = 1;
195 }
196}
197 166
198static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, 167 if (io_decode == ACPI_DECODE_16)
199 u64 io, u64 len, int io_decode) 168 flags |= PNP_PORT_FLAG_16BITADDR;
200{ 169 if (len == 0 || end >= 0x10003)
201 int i = 0; 170 flags |= IORESOURCE_DISABLED;
202 static unsigned char warned;
203 171
204 while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && 172 pnp_add_io_resource(dev, start, end, flags);
205 i < PNP_MAX_PORT)
206 i++;
207 if (i < PNP_MAX_PORT) {
208 res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag
209 if (io_decode == ACPI_DECODE_16)
210 res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR;
211 if (len <= 0 || (io + len - 1) >= 0x10003) {
212 res->port_resource[i].flags |= IORESOURCE_DISABLED;
213 return;
214 }
215 res->port_resource[i].start = io;
216 res->port_resource[i].end = io + len - 1;
217 } else if (!warned) {
218 printk(KERN_WARNING "pnpacpi: exceeded the max number of IO "
219 "resources: %d \n", PNP_MAX_PORT);
220 warned = 1;
221 }
222} 173}
223 174
224static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, 175static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
225 u64 mem, u64 len, 176 u64 start, u64 len,
226 int write_protect) 177 int write_protect)
227{ 178{
228 int i = 0; 179 int flags = 0;
229 static unsigned char warned; 180 u64 end = start + len - 1;
230 181
231 while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && 182 if (len == 0)
232 (i < PNP_MAX_MEM)) 183 flags |= IORESOURCE_DISABLED;
233 i++; 184 if (write_protect == ACPI_READ_WRITE_MEMORY)
234 if (i < PNP_MAX_MEM) { 185 flags |= IORESOURCE_MEM_WRITEABLE;
235 res->mem_resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag 186
236 if (len <= 0) { 187 pnp_add_mem_resource(dev, start, end, flags);
237 res->mem_resource[i].flags |= IORESOURCE_DISABLED;
238 return;
239 }
240 if (write_protect == ACPI_READ_WRITE_MEMORY)
241 res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE;
242
243 res->mem_resource[i].start = mem;
244 res->mem_resource[i].end = mem + len - 1;
245 } else if (!warned) {
246 printk(KERN_WARNING "pnpacpi: exceeded the max number of mem "
247 "resources: %d\n", PNP_MAX_MEM);
248 warned = 1;
249 }
250} 188}
251 189
252static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table, 190static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
253 struct acpi_resource *res) 191 struct acpi_resource *res)
254{ 192{
255 struct acpi_resource_address64 addr, *p = &addr; 193 struct acpi_resource_address64 addr, *p = &addr;
@@ -257,7 +195,7 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res
257 195
258 status = acpi_resource_to_address64(res, p); 196 status = acpi_resource_to_address64(res, p);
259 if (!ACPI_SUCCESS(status)) { 197 if (!ACPI_SUCCESS(status)) {
260 pnp_warn("PnPACPI: failed to convert resource type %d", 198 dev_warn(&dev->dev, "failed to convert resource type %d\n",
261 res->type); 199 res->type);
262 return; 200 return;
263 } 201 }
@@ -266,11 +204,11 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res
266 return; 204 return;
267 205
268 if (p->resource_type == ACPI_MEMORY_RANGE) 206 if (p->resource_type == ACPI_MEMORY_RANGE)
269 pnpacpi_parse_allocated_memresource(res_table, 207 pnpacpi_parse_allocated_memresource(dev,
270 p->minimum, p->address_length, 208 p->minimum, p->address_length,
271 p->info.mem.write_protect); 209 p->info.mem.write_protect);
272 else if (p->resource_type == ACPI_IO_RANGE) 210 else if (p->resource_type == ACPI_IO_RANGE)
273 pnpacpi_parse_allocated_ioresource(res_table, 211 pnpacpi_parse_allocated_ioresource(dev,
274 p->minimum, p->address_length, 212 p->minimum, p->address_length,
275 p->granularity == 0xfff ? ACPI_DECODE_10 : 213 p->granularity == 0xfff ? ACPI_DECODE_10 :
276 ACPI_DECODE_16); 214 ACPI_DECODE_16);
@@ -279,8 +217,16 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res
279static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, 217static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
280 void *data) 218 void *data)
281{ 219{
282 struct pnp_resource_table *res_table = data; 220 struct pnp_dev *dev = data;
283 int i; 221 struct acpi_resource_irq *irq;
222 struct acpi_resource_dma *dma;
223 struct acpi_resource_io *io;
224 struct acpi_resource_fixed_io *fixed_io;
225 struct acpi_resource_memory24 *memory24;
226 struct acpi_resource_memory32 *memory32;
227 struct acpi_resource_fixed_memory32 *fixed_memory32;
228 struct acpi_resource_extended_irq *extended_irq;
229 int i, flags;
284 230
285 switch (res->type) { 231 switch (res->type) {
286 case ACPI_RESOURCE_TYPE_IRQ: 232 case ACPI_RESOURCE_TYPE_IRQ:
@@ -288,29 +234,33 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
288 * Per spec, only one interrupt per descriptor is allowed in 234 * Per spec, only one interrupt per descriptor is allowed in
289 * _CRS, but some firmware violates this, so parse them all. 235 * _CRS, but some firmware violates this, so parse them all.
290 */ 236 */
291 for (i = 0; i < res->data.irq.interrupt_count; i++) { 237 irq = &res->data.irq;
292 pnpacpi_parse_allocated_irqresource(res_table, 238 for (i = 0; i < irq->interrupt_count; i++) {
293 res->data.irq.interrupts[i], 239 pnpacpi_parse_allocated_irqresource(dev,
294 res->data.irq.triggering, 240 irq->interrupts[i],
295 res->data.irq.polarity, 241 irq->triggering,
296 res->data.irq.sharable); 242 irq->polarity,
243 irq->sharable);
297 } 244 }
298 break; 245 break;
299 246
300 case ACPI_RESOURCE_TYPE_DMA: 247 case ACPI_RESOURCE_TYPE_DMA:
301 if (res->data.dma.channel_count > 0) 248 dma = &res->data.dma;
302 pnpacpi_parse_allocated_dmaresource(res_table, 249 if (dma->channel_count > 0) {
303 res->data.dma.channels[0], 250 flags = dma_flags(dma->type, dma->bus_master,
304 res->data.dma.type, 251 dma->transfer);
305 res->data.dma.bus_master, 252 if (dma->channels[0] == (u8) -1)
306 res->data.dma.transfer); 253 flags |= IORESOURCE_DISABLED;
254 pnp_add_dma_resource(dev, dma->channels[0], flags);
255 }
307 break; 256 break;
308 257
309 case ACPI_RESOURCE_TYPE_IO: 258 case ACPI_RESOURCE_TYPE_IO:
310 pnpacpi_parse_allocated_ioresource(res_table, 259 io = &res->data.io;
311 res->data.io.minimum, 260 pnpacpi_parse_allocated_ioresource(dev,
312 res->data.io.address_length, 261 io->minimum,
313 res->data.io.io_decode); 262 io->address_length,
263 io->io_decode);
314 break; 264 break;
315 265
316 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 266 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -318,9 +268,10 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
318 break; 268 break;
319 269
320 case ACPI_RESOURCE_TYPE_FIXED_IO: 270 case ACPI_RESOURCE_TYPE_FIXED_IO:
321 pnpacpi_parse_allocated_ioresource(res_table, 271 fixed_io = &res->data.fixed_io;
322 res->data.fixed_io.address, 272 pnpacpi_parse_allocated_ioresource(dev,
323 res->data.fixed_io.address_length, 273 fixed_io->address,
274 fixed_io->address_length,
324 ACPI_DECODE_10); 275 ACPI_DECODE_10);
325 break; 276 break;
326 277
@@ -331,27 +282,30 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
331 break; 282 break;
332 283
333 case ACPI_RESOURCE_TYPE_MEMORY24: 284 case ACPI_RESOURCE_TYPE_MEMORY24:
334 pnpacpi_parse_allocated_memresource(res_table, 285 memory24 = &res->data.memory24;
335 res->data.memory24.minimum, 286 pnpacpi_parse_allocated_memresource(dev,
336 res->data.memory24.address_length, 287 memory24->minimum,
337 res->data.memory24.write_protect); 288 memory24->address_length,
289 memory24->write_protect);
338 break; 290 break;
339 case ACPI_RESOURCE_TYPE_MEMORY32: 291 case ACPI_RESOURCE_TYPE_MEMORY32:
340 pnpacpi_parse_allocated_memresource(res_table, 292 memory32 = &res->data.memory32;
341 res->data.memory32.minimum, 293 pnpacpi_parse_allocated_memresource(dev,
342 res->data.memory32.address_length, 294 memory32->minimum,
343 res->data.memory32.write_protect); 295 memory32->address_length,
296 memory32->write_protect);
344 break; 297 break;
345 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 298 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
346 pnpacpi_parse_allocated_memresource(res_table, 299 fixed_memory32 = &res->data.fixed_memory32;
347 res->data.fixed_memory32.address, 300 pnpacpi_parse_allocated_memresource(dev,
348 res->data.fixed_memory32.address_length, 301 fixed_memory32->address,
349 res->data.fixed_memory32.write_protect); 302 fixed_memory32->address_length,
303 fixed_memory32->write_protect);
350 break; 304 break;
351 case ACPI_RESOURCE_TYPE_ADDRESS16: 305 case ACPI_RESOURCE_TYPE_ADDRESS16:
352 case ACPI_RESOURCE_TYPE_ADDRESS32: 306 case ACPI_RESOURCE_TYPE_ADDRESS32:
353 case ACPI_RESOURCE_TYPE_ADDRESS64: 307 case ACPI_RESOURCE_TYPE_ADDRESS64:
354 pnpacpi_parse_allocated_address_space(res_table, res); 308 pnpacpi_parse_allocated_address_space(dev, res);
355 break; 309 break;
356 310
357 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 311 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
@@ -360,15 +314,16 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
360 break; 314 break;
361 315
362 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 316 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
363 if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER) 317 extended_irq = &res->data.extended_irq;
318 if (extended_irq->producer_consumer == ACPI_PRODUCER)
364 return AE_OK; 319 return AE_OK;
365 320
366 for (i = 0; i < res->data.extended_irq.interrupt_count; i++) { 321 for (i = 0; i < extended_irq->interrupt_count; i++) {
367 pnpacpi_parse_allocated_irqresource(res_table, 322 pnpacpi_parse_allocated_irqresource(dev,
368 res->data.extended_irq.interrupts[i], 323 extended_irq->interrupts[i],
369 res->data.extended_irq.triggering, 324 extended_irq->triggering,
370 res->data.extended_irq.polarity, 325 extended_irq->polarity,
371 res->data.extended_irq.sharable); 326 extended_irq->sharable);
372 } 327 }
373 break; 328 break;
374 329
@@ -376,24 +331,36 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
376 break; 331 break;
377 332
378 default: 333 default:
379 pnp_warn("PnPACPI: unknown resource type %d", res->type); 334 dev_warn(&dev->dev, "unknown resource type %d in _CRS\n",
335 res->type);
380 return AE_ERROR; 336 return AE_ERROR;
381 } 337 }
382 338
383 return AE_OK; 339 return AE_OK;
384} 340}
385 341
386acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle, 342int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
387 struct pnp_resource_table * res)
388{ 343{
389 /* Blank the resource table values */ 344 acpi_handle handle = dev->data;
390 pnp_init_resource_table(res); 345 acpi_status status;
346
347 dev_dbg(&dev->dev, "parse allocated resources\n");
391 348
392 return acpi_walk_resources(handle, METHOD_NAME__CRS, 349 pnp_init_resources(dev);
393 pnpacpi_allocated_resource, res); 350
351 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
352 pnpacpi_allocated_resource, dev);
353
354 if (ACPI_FAILURE(status)) {
355 if (status != AE_NOT_FOUND)
356 dev_err(&dev->dev, "can't evaluate _CRS: %d", status);
357 return -EPERM;
358 }
359 return 0;
394} 360}
395 361
396static __init void pnpacpi_parse_dma_option(struct pnp_option *option, 362static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
363 struct pnp_option *option,
397 struct acpi_resource_dma *p) 364 struct acpi_resource_dma *p)
398{ 365{
399 int i; 366 int i;
@@ -410,10 +377,11 @@ static __init void pnpacpi_parse_dma_option(struct pnp_option *option,
410 377
411 dma->flags = dma_flags(p->type, p->bus_master, p->transfer); 378 dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
412 379
413 pnp_register_dma_resource(option, dma); 380 pnp_register_dma_resource(dev, option, dma);
414} 381}
415 382
416static __init void pnpacpi_parse_irq_option(struct pnp_option *option, 383static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
384 struct pnp_option *option,
417 struct acpi_resource_irq *p) 385 struct acpi_resource_irq *p)
418{ 386{
419 int i; 387 int i;
@@ -428,12 +396,13 @@ static __init void pnpacpi_parse_irq_option(struct pnp_option *option,
428 for (i = 0; i < p->interrupt_count; i++) 396 for (i = 0; i < p->interrupt_count; i++)
429 if (p->interrupts[i]) 397 if (p->interrupts[i])
430 __set_bit(p->interrupts[i], irq->map); 398 __set_bit(p->interrupts[i], irq->map);
431 irq->flags = irq_flags(p->triggering, p->polarity); 399 irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
432 400
433 pnp_register_irq_resource(option, irq); 401 pnp_register_irq_resource(dev, option, irq);
434} 402}
435 403
436static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option, 404static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
405 struct pnp_option *option,
437 struct acpi_resource_extended_irq *p) 406 struct acpi_resource_extended_irq *p)
438{ 407{
439 int i; 408 int i;
@@ -448,12 +417,13 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
448 for (i = 0; i < p->interrupt_count; i++) 417 for (i = 0; i < p->interrupt_count; i++)
449 if (p->interrupts[i]) 418 if (p->interrupts[i])
450 __set_bit(p->interrupts[i], irq->map); 419 __set_bit(p->interrupts[i], irq->map);
451 irq->flags = irq_flags(p->triggering, p->polarity); 420 irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
452 421
453 pnp_register_irq_resource(option, irq); 422 pnp_register_irq_resource(dev, option, irq);
454} 423}
455 424
456static __init void pnpacpi_parse_port_option(struct pnp_option *option, 425static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
426 struct pnp_option *option,
457 struct acpi_resource_io *io) 427 struct acpi_resource_io *io)
458{ 428{
459 struct pnp_port *port; 429 struct pnp_port *port;
@@ -469,10 +439,11 @@ static __init void pnpacpi_parse_port_option(struct pnp_option *option,
469 port->size = io->address_length; 439 port->size = io->address_length;
470 port->flags = ACPI_DECODE_16 == io->io_decode ? 440 port->flags = ACPI_DECODE_16 == io->io_decode ?
471 PNP_PORT_FLAG_16BITADDR : 0; 441 PNP_PORT_FLAG_16BITADDR : 0;
472 pnp_register_port_resource(option, port); 442 pnp_register_port_resource(dev, option, port);
473} 443}
474 444
475static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option, 445static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
446 struct pnp_option *option,
476 struct acpi_resource_fixed_io *io) 447 struct acpi_resource_fixed_io *io)
477{ 448{
478 struct pnp_port *port; 449 struct pnp_port *port;
@@ -486,10 +457,11 @@ static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
486 port->size = io->address_length; 457 port->size = io->address_length;
487 port->align = 0; 458 port->align = 0;
488 port->flags = PNP_PORT_FLAG_FIXED; 459 port->flags = PNP_PORT_FLAG_FIXED;
489 pnp_register_port_resource(option, port); 460 pnp_register_port_resource(dev, option, port);
490} 461}
491 462
492static __init void pnpacpi_parse_mem24_option(struct pnp_option *option, 463static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
464 struct pnp_option *option,
493 struct acpi_resource_memory24 *p) 465 struct acpi_resource_memory24 *p)
494{ 466{
495 struct pnp_mem *mem; 467 struct pnp_mem *mem;
@@ -507,10 +479,11 @@ static __init void pnpacpi_parse_mem24_option(struct pnp_option *option,
507 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? 479 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
508 IORESOURCE_MEM_WRITEABLE : 0; 480 IORESOURCE_MEM_WRITEABLE : 0;
509 481
510 pnp_register_mem_resource(option, mem); 482 pnp_register_mem_resource(dev, option, mem);
511} 483}
512 484
513static __init void pnpacpi_parse_mem32_option(struct pnp_option *option, 485static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
486 struct pnp_option *option,
514 struct acpi_resource_memory32 *p) 487 struct acpi_resource_memory32 *p)
515{ 488{
516 struct pnp_mem *mem; 489 struct pnp_mem *mem;
@@ -528,10 +501,11 @@ static __init void pnpacpi_parse_mem32_option(struct pnp_option *option,
528 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? 501 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
529 IORESOURCE_MEM_WRITEABLE : 0; 502 IORESOURCE_MEM_WRITEABLE : 0;
530 503
531 pnp_register_mem_resource(option, mem); 504 pnp_register_mem_resource(dev, option, mem);
532} 505}
533 506
534static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, 507static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
508 struct pnp_option *option,
535 struct acpi_resource_fixed_memory32 *p) 509 struct acpi_resource_fixed_memory32 *p)
536{ 510{
537 struct pnp_mem *mem; 511 struct pnp_mem *mem;
@@ -548,10 +522,11 @@ static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
548 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? 522 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
549 IORESOURCE_MEM_WRITEABLE : 0; 523 IORESOURCE_MEM_WRITEABLE : 0;
550 524
551 pnp_register_mem_resource(option, mem); 525 pnp_register_mem_resource(dev, option, mem);
552} 526}
553 527
554static __init void pnpacpi_parse_address_option(struct pnp_option *option, 528static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
529 struct pnp_option *option,
555 struct acpi_resource *r) 530 struct acpi_resource *r)
556{ 531{
557 struct acpi_resource_address64 addr, *p = &addr; 532 struct acpi_resource_address64 addr, *p = &addr;
@@ -579,7 +554,7 @@ static __init void pnpacpi_parse_address_option(struct pnp_option *option,
579 mem->flags = (p->info.mem.write_protect == 554 mem->flags = (p->info.mem.write_protect ==
580 ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE 555 ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
581 : 0; 556 : 0;
582 pnp_register_mem_resource(option, mem); 557 pnp_register_mem_resource(dev, option, mem);
583 } else if (p->resource_type == ACPI_IO_RANGE) { 558 } else if (p->resource_type == ACPI_IO_RANGE) {
584 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 559 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
585 if (!port) 560 if (!port)
@@ -588,7 +563,7 @@ static __init void pnpacpi_parse_address_option(struct pnp_option *option,
588 port->size = p->address_length; 563 port->size = p->address_length;
589 port->align = 0; 564 port->align = 0;
590 port->flags = PNP_PORT_FLAG_FIXED; 565 port->flags = PNP_PORT_FLAG_FIXED;
591 pnp_register_port_resource(option, port); 566 pnp_register_port_resource(dev, option, port);
592 } 567 }
593} 568}
594 569
@@ -608,11 +583,11 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
608 583
609 switch (res->type) { 584 switch (res->type) {
610 case ACPI_RESOURCE_TYPE_IRQ: 585 case ACPI_RESOURCE_TYPE_IRQ:
611 pnpacpi_parse_irq_option(option, &res->data.irq); 586 pnpacpi_parse_irq_option(dev, option, &res->data.irq);
612 break; 587 break;
613 588
614 case ACPI_RESOURCE_TYPE_DMA: 589 case ACPI_RESOURCE_TYPE_DMA:
615 pnpacpi_parse_dma_option(option, &res->data.dma); 590 pnpacpi_parse_dma_option(dev, option, &res->data.dma);
616 break; 591 break;
617 592
618 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 593 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -642,19 +617,22 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
642 case ACPI_RESOURCE_TYPE_END_DEPENDENT: 617 case ACPI_RESOURCE_TYPE_END_DEPENDENT:
643 /*only one EndDependentFn is allowed */ 618 /*only one EndDependentFn is allowed */
644 if (!parse_data->option_independent) { 619 if (!parse_data->option_independent) {
645 pnp_warn("PnPACPI: more than one EndDependentFn"); 620 dev_warn(&dev->dev, "more than one EndDependentFn "
621 "in _PRS\n");
646 return AE_ERROR; 622 return AE_ERROR;
647 } 623 }
648 parse_data->option = parse_data->option_independent; 624 parse_data->option = parse_data->option_independent;
649 parse_data->option_independent = NULL; 625 parse_data->option_independent = NULL;
626 dev_dbg(&dev->dev, "end dependent options\n");
650 break; 627 break;
651 628
652 case ACPI_RESOURCE_TYPE_IO: 629 case ACPI_RESOURCE_TYPE_IO:
653 pnpacpi_parse_port_option(option, &res->data.io); 630 pnpacpi_parse_port_option(dev, option, &res->data.io);
654 break; 631 break;
655 632
656 case ACPI_RESOURCE_TYPE_FIXED_IO: 633 case ACPI_RESOURCE_TYPE_FIXED_IO:
657 pnpacpi_parse_fixed_port_option(option, &res->data.fixed_io); 634 pnpacpi_parse_fixed_port_option(dev, option,
635 &res->data.fixed_io);
658 break; 636 break;
659 637
660 case ACPI_RESOURCE_TYPE_VENDOR: 638 case ACPI_RESOURCE_TYPE_VENDOR:
@@ -662,57 +640,67 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
662 break; 640 break;
663 641
664 case ACPI_RESOURCE_TYPE_MEMORY24: 642 case ACPI_RESOURCE_TYPE_MEMORY24:
665 pnpacpi_parse_mem24_option(option, &res->data.memory24); 643 pnpacpi_parse_mem24_option(dev, option, &res->data.memory24);
666 break; 644 break;
667 645
668 case ACPI_RESOURCE_TYPE_MEMORY32: 646 case ACPI_RESOURCE_TYPE_MEMORY32:
669 pnpacpi_parse_mem32_option(option, &res->data.memory32); 647 pnpacpi_parse_mem32_option(dev, option, &res->data.memory32);
670 break; 648 break;
671 649
672 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 650 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
673 pnpacpi_parse_fixed_mem32_option(option, 651 pnpacpi_parse_fixed_mem32_option(dev, option,
674 &res->data.fixed_memory32); 652 &res->data.fixed_memory32);
675 break; 653 break;
676 654
677 case ACPI_RESOURCE_TYPE_ADDRESS16: 655 case ACPI_RESOURCE_TYPE_ADDRESS16:
678 case ACPI_RESOURCE_TYPE_ADDRESS32: 656 case ACPI_RESOURCE_TYPE_ADDRESS32:
679 case ACPI_RESOURCE_TYPE_ADDRESS64: 657 case ACPI_RESOURCE_TYPE_ADDRESS64:
680 pnpacpi_parse_address_option(option, res); 658 pnpacpi_parse_address_option(dev, option, res);
681 break; 659 break;
682 660
683 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 661 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
684 break; 662 break;
685 663
686 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 664 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
687 pnpacpi_parse_ext_irq_option(option, &res->data.extended_irq); 665 pnpacpi_parse_ext_irq_option(dev, option,
666 &res->data.extended_irq);
688 break; 667 break;
689 668
690 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: 669 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
691 break; 670 break;
692 671
693 default: 672 default:
694 pnp_warn("PnPACPI: unknown resource type %d", res->type); 673 dev_warn(&dev->dev, "unknown resource type %d in _PRS\n",
674 res->type);
695 return AE_ERROR; 675 return AE_ERROR;
696 } 676 }
697 677
698 return AE_OK; 678 return AE_OK;
699} 679}
700 680
701acpi_status __init pnpacpi_parse_resource_option_data(acpi_handle handle, 681int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
702 struct pnp_dev *dev)
703{ 682{
683 acpi_handle handle = dev->data;
704 acpi_status status; 684 acpi_status status;
705 struct acpipnp_parse_option_s parse_data; 685 struct acpipnp_parse_option_s parse_data;
706 686
687 dev_dbg(&dev->dev, "parse resource options\n");
688
707 parse_data.option = pnp_register_independent_option(dev); 689 parse_data.option = pnp_register_independent_option(dev);
708 if (!parse_data.option) 690 if (!parse_data.option)
709 return AE_ERROR; 691 return -ENOMEM;
692
710 parse_data.option_independent = parse_data.option; 693 parse_data.option_independent = parse_data.option;
711 parse_data.dev = dev; 694 parse_data.dev = dev;
712 status = acpi_walk_resources(handle, METHOD_NAME__PRS, 695 status = acpi_walk_resources(handle, METHOD_NAME__PRS,
713 pnpacpi_option_resource, &parse_data); 696 pnpacpi_option_resource, &parse_data);
714 697
715 return status; 698 if (ACPI_FAILURE(status)) {
699 if (status != AE_NOT_FOUND)
700 dev_err(&dev->dev, "can't evaluate _PRS: %d", status);
701 return -EPERM;
702 }
703 return 0;
716} 704}
717 705
718static int pnpacpi_supported_resource(struct acpi_resource *res) 706static int pnpacpi_supported_resource(struct acpi_resource *res)
@@ -760,9 +748,10 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
760 return AE_OK; 748 return AE_OK;
761} 749}
762 750
763int pnpacpi_build_resource_template(acpi_handle handle, 751int pnpacpi_build_resource_template(struct pnp_dev *dev,
764 struct acpi_buffer *buffer) 752 struct acpi_buffer *buffer)
765{ 753{
754 acpi_handle handle = dev->data;
766 struct acpi_resource *resource; 755 struct acpi_resource *resource;
767 int res_cnt = 0; 756 int res_cnt = 0;
768 acpi_status status; 757 acpi_status status;
@@ -770,7 +759,7 @@ int pnpacpi_build_resource_template(acpi_handle handle,
770 status = acpi_walk_resources(handle, METHOD_NAME__CRS, 759 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
771 pnpacpi_count_resources, &res_cnt); 760 pnpacpi_count_resources, &res_cnt);
772 if (ACPI_FAILURE(status)) { 761 if (ACPI_FAILURE(status)) {
773 pnp_err("Evaluate _CRS failed"); 762 dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status);
774 return -EINVAL; 763 return -EINVAL;
775 } 764 }
776 if (!res_cnt) 765 if (!res_cnt)
@@ -779,13 +768,13 @@ int pnpacpi_build_resource_template(acpi_handle handle,
779 buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL); 768 buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
780 if (!buffer->pointer) 769 if (!buffer->pointer)
781 return -ENOMEM; 770 return -ENOMEM;
782 pnp_dbg("Res cnt %d", res_cnt); 771
783 resource = (struct acpi_resource *)buffer->pointer; 772 resource = (struct acpi_resource *)buffer->pointer;
784 status = acpi_walk_resources(handle, METHOD_NAME__CRS, 773 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
785 pnpacpi_type_resources, &resource); 774 pnpacpi_type_resources, &resource);
786 if (ACPI_FAILURE(status)) { 775 if (ACPI_FAILURE(status)) {
787 kfree(buffer->pointer); 776 kfree(buffer->pointer);
788 pnp_err("Evaluate _CRS failed"); 777 dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status);
789 return -EINVAL; 778 return -EINVAL;
790 } 779 }
791 /* resource will pointer the end resource now */ 780 /* resource will pointer the end resource now */
@@ -794,129 +783,184 @@ int pnpacpi_build_resource_template(acpi_handle handle,
794 return 0; 783 return 0;
795} 784}
796 785
797static void pnpacpi_encode_irq(struct acpi_resource *resource, 786static void pnpacpi_encode_irq(struct pnp_dev *dev,
787 struct acpi_resource *resource,
798 struct resource *p) 788 struct resource *p)
799{ 789{
790 struct acpi_resource_irq *irq = &resource->data.irq;
800 int triggering, polarity; 791 int triggering, polarity;
801 792
802 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); 793 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
803 resource->data.irq.triggering = triggering; 794 irq->triggering = triggering;
804 resource->data.irq.polarity = polarity; 795 irq->polarity = polarity;
805 if (triggering == ACPI_EDGE_SENSITIVE) 796 if (triggering == ACPI_EDGE_SENSITIVE)
806 resource->data.irq.sharable = ACPI_EXCLUSIVE; 797 irq->sharable = ACPI_EXCLUSIVE;
807 else 798 else
808 resource->data.irq.sharable = ACPI_SHARED; 799 irq->sharable = ACPI_SHARED;
809 resource->data.irq.interrupt_count = 1; 800 irq->interrupt_count = 1;
810 resource->data.irq.interrupts[0] = p->start; 801 irq->interrupts[0] = p->start;
802
803 dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start,
804 triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
805 polarity == ACPI_ACTIVE_LOW ? "low" : "high",
806 irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
811} 807}
812 808
813static void pnpacpi_encode_ext_irq(struct acpi_resource *resource, 809static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
810 struct acpi_resource *resource,
814 struct resource *p) 811 struct resource *p)
815{ 812{
813 struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
816 int triggering, polarity; 814 int triggering, polarity;
817 815
818 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); 816 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
819 resource->data.extended_irq.producer_consumer = ACPI_CONSUMER; 817 extended_irq->producer_consumer = ACPI_CONSUMER;
820 resource->data.extended_irq.triggering = triggering; 818 extended_irq->triggering = triggering;
821 resource->data.extended_irq.polarity = polarity; 819 extended_irq->polarity = polarity;
822 if (triggering == ACPI_EDGE_SENSITIVE) 820 if (triggering == ACPI_EDGE_SENSITIVE)
823 resource->data.irq.sharable = ACPI_EXCLUSIVE; 821 extended_irq->sharable = ACPI_EXCLUSIVE;
824 else 822 else
825 resource->data.irq.sharable = ACPI_SHARED; 823 extended_irq->sharable = ACPI_SHARED;
826 resource->data.extended_irq.interrupt_count = 1; 824 extended_irq->interrupt_count = 1;
827 resource->data.extended_irq.interrupts[0] = p->start; 825 extended_irq->interrupts[0] = p->start;
826
827 dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start,
828 triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
829 polarity == ACPI_ACTIVE_LOW ? "low" : "high",
830 extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
828} 831}
829 832
830static void pnpacpi_encode_dma(struct acpi_resource *resource, 833static void pnpacpi_encode_dma(struct pnp_dev *dev,
834 struct acpi_resource *resource,
831 struct resource *p) 835 struct resource *p)
832{ 836{
837 struct acpi_resource_dma *dma = &resource->data.dma;
838
833 /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ 839 /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
834 switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { 840 switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
835 case IORESOURCE_DMA_TYPEA: 841 case IORESOURCE_DMA_TYPEA:
836 resource->data.dma.type = ACPI_TYPE_A; 842 dma->type = ACPI_TYPE_A;
837 break; 843 break;
838 case IORESOURCE_DMA_TYPEB: 844 case IORESOURCE_DMA_TYPEB:
839 resource->data.dma.type = ACPI_TYPE_B; 845 dma->type = ACPI_TYPE_B;
840 break; 846 break;
841 case IORESOURCE_DMA_TYPEF: 847 case IORESOURCE_DMA_TYPEF:
842 resource->data.dma.type = ACPI_TYPE_F; 848 dma->type = ACPI_TYPE_F;
843 break; 849 break;
844 default: 850 default:
845 resource->data.dma.type = ACPI_COMPATIBILITY; 851 dma->type = ACPI_COMPATIBILITY;
846 } 852 }
847 853
848 switch (p->flags & IORESOURCE_DMA_TYPE_MASK) { 854 switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
849 case IORESOURCE_DMA_8BIT: 855 case IORESOURCE_DMA_8BIT:
850 resource->data.dma.transfer = ACPI_TRANSFER_8; 856 dma->transfer = ACPI_TRANSFER_8;
851 break; 857 break;
852 case IORESOURCE_DMA_8AND16BIT: 858 case IORESOURCE_DMA_8AND16BIT:
853 resource->data.dma.transfer = ACPI_TRANSFER_8_16; 859 dma->transfer = ACPI_TRANSFER_8_16;
854 break; 860 break;
855 default: 861 default:
856 resource->data.dma.transfer = ACPI_TRANSFER_16; 862 dma->transfer = ACPI_TRANSFER_16;
857 } 863 }
858 864
859 resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER); 865 dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
860 resource->data.dma.channel_count = 1; 866 dma->channel_count = 1;
861 resource->data.dma.channels[0] = p->start; 867 dma->channels[0] = p->start;
868
869 dev_dbg(&dev->dev, " encode dma %d "
870 "type %#x transfer %#x master %d\n",
871 (int) p->start, dma->type, dma->transfer, dma->bus_master);
862} 872}
863 873
864static void pnpacpi_encode_io(struct acpi_resource *resource, 874static void pnpacpi_encode_io(struct pnp_dev *dev,
875 struct acpi_resource *resource,
865 struct resource *p) 876 struct resource *p)
866{ 877{
878 struct acpi_resource_io *io = &resource->data.io;
879
867 /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ 880 /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
868 resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ? 881 io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
869 ACPI_DECODE_16 : ACPI_DECODE_10; 882 ACPI_DECODE_16 : ACPI_DECODE_10;
870 resource->data.io.minimum = p->start; 883 io->minimum = p->start;
871 resource->data.io.maximum = p->end; 884 io->maximum = p->end;
872 resource->data.io.alignment = 0; /* Correct? */ 885 io->alignment = 0; /* Correct? */
873 resource->data.io.address_length = p->end - p->start + 1; 886 io->address_length = p->end - p->start + 1;
887
888 dev_dbg(&dev->dev, " encode io %#llx-%#llx decode %#x\n",
889 (unsigned long long) p->start, (unsigned long long) p->end,
890 io->io_decode);
874} 891}
875 892
876static void pnpacpi_encode_fixed_io(struct acpi_resource *resource, 893static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
894 struct acpi_resource *resource,
877 struct resource *p) 895 struct resource *p)
878{ 896{
879 resource->data.fixed_io.address = p->start; 897 struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;
880 resource->data.fixed_io.address_length = p->end - p->start + 1; 898
899 fixed_io->address = p->start;
900 fixed_io->address_length = p->end - p->start + 1;
901
902 dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n",
903 (unsigned long long) p->start, (unsigned long long) p->end);
881} 904}
882 905
883static void pnpacpi_encode_mem24(struct acpi_resource *resource, 906static void pnpacpi_encode_mem24(struct pnp_dev *dev,
907 struct acpi_resource *resource,
884 struct resource *p) 908 struct resource *p)
885{ 909{
910 struct acpi_resource_memory24 *memory24 = &resource->data.memory24;
911
886 /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ 912 /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
887 resource->data.memory24.write_protect = 913 memory24->write_protect =
888 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 914 (p->flags & IORESOURCE_MEM_WRITEABLE) ?
889 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 915 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
890 resource->data.memory24.minimum = p->start; 916 memory24->minimum = p->start;
891 resource->data.memory24.maximum = p->end; 917 memory24->maximum = p->end;
892 resource->data.memory24.alignment = 0; 918 memory24->alignment = 0;
893 resource->data.memory24.address_length = p->end - p->start + 1; 919 memory24->address_length = p->end - p->start + 1;
920
921 dev_dbg(&dev->dev, " encode mem24 %#llx-%#llx write_protect %#x\n",
922 (unsigned long long) p->start, (unsigned long long) p->end,
923 memory24->write_protect);
894} 924}
895 925
896static void pnpacpi_encode_mem32(struct acpi_resource *resource, 926static void pnpacpi_encode_mem32(struct pnp_dev *dev,
927 struct acpi_resource *resource,
897 struct resource *p) 928 struct resource *p)
898{ 929{
899 resource->data.memory32.write_protect = 930 struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
931
932 memory32->write_protect =
900 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 933 (p->flags & IORESOURCE_MEM_WRITEABLE) ?
901 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 934 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
902 resource->data.memory32.minimum = p->start; 935 memory32->minimum = p->start;
903 resource->data.memory32.maximum = p->end; 936 memory32->maximum = p->end;
904 resource->data.memory32.alignment = 0; 937 memory32->alignment = 0;
905 resource->data.memory32.address_length = p->end - p->start + 1; 938 memory32->address_length = p->end - p->start + 1;
939
940 dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx write_protect %#x\n",
941 (unsigned long long) p->start, (unsigned long long) p->end,
942 memory32->write_protect);
906} 943}
907 944
908static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource, 945static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
946 struct acpi_resource *resource,
909 struct resource *p) 947 struct resource *p)
910{ 948{
911 resource->data.fixed_memory32.write_protect = 949 struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;
950
951 fixed_memory32->write_protect =
912 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 952 (p->flags & IORESOURCE_MEM_WRITEABLE) ?
913 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 953 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
914 resource->data.fixed_memory32.address = p->start; 954 fixed_memory32->address = p->start;
915 resource->data.fixed_memory32.address_length = p->end - p->start + 1; 955 fixed_memory32->address_length = p->end - p->start + 1;
956
957 dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx "
958 "write_protect %#x\n",
959 (unsigned long long) p->start, (unsigned long long) p->end,
960 fixed_memory32->write_protect);
916} 961}
917 962
918int pnpacpi_encode_resources(struct pnp_resource_table *res_table, 963int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
919 struct acpi_buffer *buffer)
920{ 964{
921 int i = 0; 965 int i = 0;
922 /* pnpacpi_build_resource_template allocates extra mem */ 966 /* pnpacpi_build_resource_template allocates extra mem */
@@ -924,58 +968,48 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
924 struct acpi_resource *resource = buffer->pointer; 968 struct acpi_resource *resource = buffer->pointer;
925 int port = 0, irq = 0, dma = 0, mem = 0; 969 int port = 0, irq = 0, dma = 0, mem = 0;
926 970
927 pnp_dbg("res cnt %d", res_cnt); 971 dev_dbg(&dev->dev, "encode %d resources\n", res_cnt);
928 while (i < res_cnt) { 972 while (i < res_cnt) {
929 switch (resource->type) { 973 switch (resource->type) {
930 case ACPI_RESOURCE_TYPE_IRQ: 974 case ACPI_RESOURCE_TYPE_IRQ:
931 pnp_dbg("Encode irq"); 975 pnpacpi_encode_irq(dev, resource,
932 pnpacpi_encode_irq(resource, 976 pnp_get_resource(dev, IORESOURCE_IRQ, irq));
933 &res_table->irq_resource[irq]);
934 irq++; 977 irq++;
935 break; 978 break;
936 979
937 case ACPI_RESOURCE_TYPE_DMA: 980 case ACPI_RESOURCE_TYPE_DMA:
938 pnp_dbg("Encode dma"); 981 pnpacpi_encode_dma(dev, resource,
939 pnpacpi_encode_dma(resource, 982 pnp_get_resource(dev, IORESOURCE_DMA, dma));
940 &res_table->dma_resource[dma]);
941 dma++; 983 dma++;
942 break; 984 break;
943 case ACPI_RESOURCE_TYPE_IO: 985 case ACPI_RESOURCE_TYPE_IO:
944 pnp_dbg("Encode io"); 986 pnpacpi_encode_io(dev, resource,
945 pnpacpi_encode_io(resource, 987 pnp_get_resource(dev, IORESOURCE_IO, port));
946 &res_table->port_resource[port]);
947 port++; 988 port++;
948 break; 989 break;
949 case ACPI_RESOURCE_TYPE_FIXED_IO: 990 case ACPI_RESOURCE_TYPE_FIXED_IO:
950 pnp_dbg("Encode fixed io"); 991 pnpacpi_encode_fixed_io(dev, resource,
951 pnpacpi_encode_fixed_io(resource, 992 pnp_get_resource(dev, IORESOURCE_IO, port));
952 &res_table->
953 port_resource[port]);
954 port++; 993 port++;
955 break; 994 break;
956 case ACPI_RESOURCE_TYPE_MEMORY24: 995 case ACPI_RESOURCE_TYPE_MEMORY24:
957 pnp_dbg("Encode mem24"); 996 pnpacpi_encode_mem24(dev, resource,
958 pnpacpi_encode_mem24(resource, 997 pnp_get_resource(dev, IORESOURCE_MEM, mem));
959 &res_table->mem_resource[mem]);
960 mem++; 998 mem++;
961 break; 999 break;
962 case ACPI_RESOURCE_TYPE_MEMORY32: 1000 case ACPI_RESOURCE_TYPE_MEMORY32:
963 pnp_dbg("Encode mem32"); 1001 pnpacpi_encode_mem32(dev, resource,
964 pnpacpi_encode_mem32(resource, 1002 pnp_get_resource(dev, IORESOURCE_MEM, mem));
965 &res_table->mem_resource[mem]);
966 mem++; 1003 mem++;
967 break; 1004 break;
968 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 1005 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
969 pnp_dbg("Encode fixed mem32"); 1006 pnpacpi_encode_fixed_mem32(dev, resource,
970 pnpacpi_encode_fixed_mem32(resource, 1007 pnp_get_resource(dev, IORESOURCE_MEM, mem));
971 &res_table->
972 mem_resource[mem]);
973 mem++; 1008 mem++;
974 break; 1009 break;
975 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 1010 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
976 pnp_dbg("Encode ext irq"); 1011 pnpacpi_encode_ext_irq(dev, resource,
977 pnpacpi_encode_ext_irq(resource, 1012 pnp_get_resource(dev, IORESOURCE_IRQ, irq));
978 &res_table->irq_resource[irq]);
979 irq++; 1013 irq++;
980 break; 1014 break;
981 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 1015 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -988,7 +1022,8 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
988 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 1022 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
989 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: 1023 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
990 default: /* other type */ 1024 default: /* other type */
991 pnp_warn("unknown resource type %d", resource->type); 1025 dev_warn(&dev->dev, "can't encode unknown resource "
1026 "type %d\n", resource->type);
992 return -EINVAL; 1027 return -EINVAL;
993 } 1028 }
994 resource++; 1029 resource++;
diff --git a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile
index 3cd3ed760605..310e2b3a7710 100644
--- a/drivers/pnp/pnpbios/Makefile
+++ b/drivers/pnp/pnpbios/Makefile
@@ -5,3 +5,7 @@
5pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o 5pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o
6 6
7obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y) 7obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y)
8
9ifeq ($(CONFIG_PNP_DEBUG),y)
10EXTRA_CFLAGS += -DDEBUG
11endif
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index a8364d815222..7ff824496b39 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -7,7 +7,6 @@
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/linkage.h> 8#include <linux/linkage.h>
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/pnpbios.h>
11#include <linux/device.h> 10#include <linux/device.h>
12#include <linux/pnp.h> 11#include <linux/pnp.h>
13#include <linux/mm.h> 12#include <linux/mm.h>
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index a8a51500e1e9..19a4be1a9a31 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -50,7 +50,6 @@
50#include <linux/init.h> 50#include <linux/init.h>
51#include <linux/linkage.h> 51#include <linux/linkage.h>
52#include <linux/kernel.h> 52#include <linux/kernel.h>
53#include <linux/pnpbios.h>
54#include <linux/device.h> 53#include <linux/device.h>
55#include <linux/pnp.h> 54#include <linux/pnp.h>
56#include <linux/mm.h> 55#include <linux/mm.h>
@@ -69,6 +68,7 @@
69#include <asm/system.h> 68#include <asm/system.h>
70#include <asm/byteorder.h> 69#include <asm/byteorder.h>
71 70
71#include "../base.h"
72#include "pnpbios.h" 72#include "pnpbios.h"
73 73
74/* 74/*
@@ -203,8 +203,7 @@ static int pnp_dock_thread(void *unused)
203 203
204#endif /* CONFIG_HOTPLUG */ 204#endif /* CONFIG_HOTPLUG */
205 205
206static int pnpbios_get_resources(struct pnp_dev *dev, 206static int pnpbios_get_resources(struct pnp_dev *dev)
207 struct pnp_resource_table *res)
208{ 207{
209 u8 nodenum = dev->number; 208 u8 nodenum = dev->number;
210 struct pnp_bios_node *node; 209 struct pnp_bios_node *node;
@@ -212,6 +211,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev,
212 if (!pnpbios_is_dynamic(dev)) 211 if (!pnpbios_is_dynamic(dev))
213 return -EPERM; 212 return -EPERM;
214 213
214 dev_dbg(&dev->dev, "get resources\n");
215 node = kzalloc(node_info.max_node_size, GFP_KERNEL); 215 node = kzalloc(node_info.max_node_size, GFP_KERNEL);
216 if (!node) 216 if (!node)
217 return -1; 217 return -1;
@@ -219,14 +219,13 @@ static int pnpbios_get_resources(struct pnp_dev *dev,
219 kfree(node); 219 kfree(node);
220 return -ENODEV; 220 return -ENODEV;
221 } 221 }
222 pnpbios_read_resources_from_node(res, node); 222 pnpbios_read_resources_from_node(dev, node);
223 dev->active = pnp_is_active(dev); 223 dev->active = pnp_is_active(dev);
224 kfree(node); 224 kfree(node);
225 return 0; 225 return 0;
226} 226}
227 227
228static int pnpbios_set_resources(struct pnp_dev *dev, 228static int pnpbios_set_resources(struct pnp_dev *dev)
229 struct pnp_resource_table *res)
230{ 229{
231 u8 nodenum = dev->number; 230 u8 nodenum = dev->number;
232 struct pnp_bios_node *node; 231 struct pnp_bios_node *node;
@@ -235,6 +234,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev,
235 if (!pnpbios_is_dynamic(dev)) 234 if (!pnpbios_is_dynamic(dev))
236 return -EPERM; 235 return -EPERM;
237 236
237 dev_dbg(&dev->dev, "set resources\n");
238 node = kzalloc(node_info.max_node_size, GFP_KERNEL); 238 node = kzalloc(node_info.max_node_size, GFP_KERNEL);
239 if (!node) 239 if (!node)
240 return -1; 240 return -1;
@@ -242,7 +242,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev,
242 kfree(node); 242 kfree(node);
243 return -ENODEV; 243 return -ENODEV;
244 } 244 }
245 if (pnpbios_write_resources_to_node(res, node) < 0) { 245 if (pnpbios_write_resources_to_node(dev, node) < 0) {
246 kfree(node); 246 kfree(node);
247 return -1; 247 return -1;
248 } 248 }
@@ -317,7 +317,6 @@ static int __init insert_device(struct pnp_bios_node *node)
317{ 317{
318 struct list_head *pos; 318 struct list_head *pos;
319 struct pnp_dev *dev; 319 struct pnp_dev *dev;
320 struct pnp_id *dev_id;
321 char id[8]; 320 char id[8];
322 321
323 /* check if the device is already added */ 322 /* check if the device is already added */
@@ -327,20 +326,11 @@ static int __init insert_device(struct pnp_bios_node *node)
327 return -1; 326 return -1;
328 } 327 }
329 328
330 dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); 329 pnp_eisa_id_to_string(node->eisa_id & PNP_EISA_ID_MASK, id);
330 dev = pnp_alloc_dev(&pnpbios_protocol, node->handle, id);
331 if (!dev) 331 if (!dev)
332 return -1; 332 return -1;
333 333
334 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
335 if (!dev_id) {
336 kfree(dev);
337 return -1;
338 }
339
340 dev->number = node->handle;
341 pnpid32_to_pnpid(node->eisa_id, id);
342 memcpy(dev_id->id, id, 7);
343 pnp_add_id(dev_id, dev);
344 pnpbios_parse_data_stream(dev, node); 334 pnpbios_parse_data_stream(dev, node);
345 dev->active = pnp_is_active(dev); 335 dev->active = pnp_is_active(dev);
346 dev->flags = node->flags; 336 dev->flags = node->flags;
@@ -353,11 +343,10 @@ static int __init insert_device(struct pnp_bios_node *node)
353 dev->capabilities |= PNP_WRITE; 343 dev->capabilities |= PNP_WRITE;
354 if (dev->flags & PNPBIOS_REMOVABLE) 344 if (dev->flags & PNPBIOS_REMOVABLE)
355 dev->capabilities |= PNP_REMOVABLE; 345 dev->capabilities |= PNP_REMOVABLE;
356 dev->protocol = &pnpbios_protocol;
357 346
358 /* clear out the damaged flags */ 347 /* clear out the damaged flags */
359 if (!dev->active) 348 if (!dev->active)
360 pnp_init_resource_table(&dev->res); 349 pnp_init_resources(dev);
361 350
362 pnp_add_device(dev); 351 pnp_add_device(dev);
363 pnpbios_interface_attach_device(node); 352 pnpbios_interface_attach_device(node);
diff --git a/drivers/pnp/pnpbios/pnpbios.h b/drivers/pnp/pnpbios/pnpbios.h
index d8cb2fd1f127..b09cf6dc2075 100644
--- a/drivers/pnp/pnpbios/pnpbios.h
+++ b/drivers/pnp/pnpbios/pnpbios.h
@@ -2,6 +2,142 @@
2 * pnpbios.h - contains local definitions 2 * pnpbios.h - contains local definitions
3 */ 3 */
4 4
5/*
6 * Include file for the interface to a PnP BIOS
7 *
8 * Original BIOS code (C) 1998 Christian Schmidt (chr.schmidt@tu-bs.de)
9 * PnP handler parts (c) 1998 Tom Lees <tom@lpsg.demon.co.uk>
10 * Minor reorganizations by David Hinds <dahinds@users.sourceforge.net>
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2, or (at your option) any
15 * later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27/*
28 * Return codes
29 */
30#define PNP_SUCCESS 0x00
31#define PNP_NOT_SET_STATICALLY 0x7f
32#define PNP_UNKNOWN_FUNCTION 0x81
33#define PNP_FUNCTION_NOT_SUPPORTED 0x82
34#define PNP_INVALID_HANDLE 0x83
35#define PNP_BAD_PARAMETER 0x84
36#define PNP_SET_FAILED 0x85
37#define PNP_EVENTS_NOT_PENDING 0x86
38#define PNP_SYSTEM_NOT_DOCKED 0x87
39#define PNP_NO_ISA_PNP_CARDS 0x88
40#define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89
41#define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY 0x8a
42#define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b
43#define PNP_BUFFER_TOO_SMALL 0x8c
44#define PNP_USE_ESCD_SUPPORT 0x8d
45#define PNP_MESSAGE_NOT_SUPPORTED 0x8e
46#define PNP_HARDWARE_ERROR 0x8f
47
48#define ESCD_SUCCESS 0x00
49#define ESCD_IO_ERROR_READING 0x55
50#define ESCD_INVALID 0x56
51#define ESCD_BUFFER_TOO_SMALL 0x59
52#define ESCD_NVRAM_TOO_SMALL 0x5a
53#define ESCD_FUNCTION_NOT_SUPPORTED 0x81
54
55/*
56 * Events that can be received by "get event"
57 */
58#define PNPEV_ABOUT_TO_CHANGE_CONFIG 0x0001
59#define PNPEV_DOCK_CHANGED 0x0002
60#define PNPEV_SYSTEM_DEVICE_CHANGED 0x0003
61#define PNPEV_CONFIG_CHANGED_FAILED 0x0004
62#define PNPEV_UNKNOWN_SYSTEM_EVENT 0xffff
63/* 0x8000 through 0xfffe are OEM defined */
64
65/*
66 * Messages that should be sent through "send message"
67 */
68#define PNPMSG_OK 0x00
69#define PNPMSG_ABORT 0x01
70#define PNPMSG_UNDOCK_DEFAULT_ACTION 0x40
71#define PNPMSG_POWER_OFF 0x41
72#define PNPMSG_PNP_OS_ACTIVE 0x42
73#define PNPMSG_PNP_OS_INACTIVE 0x43
74
75/*
76 * Plug and Play BIOS flags
77 */
78#define PNPBIOS_NO_DISABLE 0x0001
79#define PNPBIOS_NO_CONFIG 0x0002
80#define PNPBIOS_OUTPUT 0x0004
81#define PNPBIOS_INPUT 0x0008
82#define PNPBIOS_BOOTABLE 0x0010
83#define PNPBIOS_DOCK 0x0020
84#define PNPBIOS_REMOVABLE 0x0040
85#define pnpbios_is_static(x) (((x)->flags & 0x0100) == 0x0000)
86#define pnpbios_is_dynamic(x) ((x)->flags & 0x0080)
87
88/*
89 * Function Parameters
90 */
91#define PNPMODE_STATIC 1
92#define PNPMODE_DYNAMIC 0
93
94/* 0x8000 through 0xffff are OEM defined */
95
96#pragma pack(1)
97struct pnp_dev_node_info {
98 __u16 no_nodes;
99 __u16 max_node_size;
100};
101struct pnp_docking_station_info {
102 __u32 location_id;
103 __u32 serial;
104 __u16 capabilities;
105};
106struct pnp_isa_config_struc {
107 __u8 revision;
108 __u8 no_csns;
109 __u16 isa_rd_data_port;
110 __u16 reserved;
111};
112struct escd_info_struc {
113 __u16 min_escd_write_size;
114 __u16 escd_size;
115 __u32 nv_storage_base;
116};
117struct pnp_bios_node {
118 __u16 size;
119 __u8 handle;
120 __u32 eisa_id;
121 __u8 type_code[3];
122 __u16 flags;
123 __u8 data[0];
124};
125#pragma pack()
126
127/* non-exported */
128extern struct pnp_dev_node_info node_info;
129
130extern int pnp_bios_dev_node_info(struct pnp_dev_node_info *data);
131extern int pnp_bios_get_dev_node(u8 *nodenum, char config,
132 struct pnp_bios_node *data);
133extern int pnp_bios_set_dev_node(u8 nodenum, char config,
134 struct pnp_bios_node *data);
135extern int pnp_bios_get_stat_res(char *info);
136extern int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data);
137extern int pnp_bios_escd_info(struct escd_info_struc *data);
138extern int pnp_bios_read_escd(char *data, u32 nvram_base);
139extern int pnp_bios_dock_station_info(struct pnp_docking_station_info *data);
140
5#pragma pack(1) 141#pragma pack(1)
6union pnp_bios_install_struct { 142union pnp_bios_install_struct {
7 struct { 143 struct {
@@ -28,8 +164,8 @@ extern int pnp_bios_present(void);
28extern int pnpbios_dont_use_current_config; 164extern int pnpbios_dont_use_current_config;
29 165
30extern int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node); 166extern int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node);
31extern int pnpbios_read_resources_from_node(struct pnp_resource_table *res, struct pnp_bios_node * node); 167extern int pnpbios_read_resources_from_node(struct pnp_dev *dev, struct pnp_bios_node *node);
32extern int pnpbios_write_resources_to_node(struct pnp_resource_table *res, struct pnp_bios_node * node); 168extern int pnpbios_write_resources_to_node(struct pnp_dev *dev, struct pnp_bios_node *node);
33extern void pnpid32_to_pnpid(u32 id, char *str); 169extern void pnpid32_to_pnpid(u32 id, char *str);
34 170
35extern void pnpbios_print_status(const char * module, u16 status); 171extern void pnpbios_print_status(const char * module, u16 status);
diff --git a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c
index bb19bc957bad..4f89f1677e69 100644
--- a/drivers/pnp/pnpbios/proc.c
+++ b/drivers/pnp/pnpbios/proc.c
@@ -23,7 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/proc_fs.h> 25#include <linux/proc_fs.h>
26#include <linux/pnpbios.h> 26#include <linux/pnp.h>
27#include <linux/init.h> 27#include <linux/init.h>
28 28
29#include <asm/uaccess.h> 29#include <asm/uaccess.h>
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index caade3531416..2e2c457a0fea 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -4,7 +4,6 @@
4 4
5#include <linux/ctype.h> 5#include <linux/ctype.h>
6#include <linux/pnp.h> 6#include <linux/pnp.h>
7#include <linux/pnpbios.h>
8#include <linux/string.h> 7#include <linux/string.h>
9#include <linux/slab.h> 8#include <linux/slab.h>
10 9
@@ -16,6 +15,7 @@ inline void pcibios_penalize_isa_irq(int irq, int active)
16} 15}
17#endif /* CONFIG_PCI */ 16#endif /* CONFIG_PCI */
18 17
18#include "../base.h"
19#include "pnpbios.h" 19#include "pnpbios.h"
20 20
21/* standard resource tags */ 21/* standard resource tags */
@@ -53,97 +53,43 @@ inline void pcibios_penalize_isa_irq(int irq, int active)
53 * Allocated Resources 53 * Allocated Resources
54 */ 54 */
55 55
56static void pnpbios_parse_allocated_irqresource(struct pnp_resource_table *res, 56static void pnpbios_parse_allocated_ioresource(struct pnp_dev *dev,
57 int irq) 57 int start, int len)
58{ 58{
59 int i = 0; 59 int flags = 0;
60 60 int end = start + len - 1;
61 while (!(res->irq_resource[i].flags & IORESOURCE_UNSET)
62 && i < PNP_MAX_IRQ)
63 i++;
64 if (i < PNP_MAX_IRQ) {
65 res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
66 if (irq == -1) {
67 res->irq_resource[i].flags |= IORESOURCE_DISABLED;
68 return;
69 }
70 res->irq_resource[i].start =
71 res->irq_resource[i].end = (unsigned long)irq;
72 pcibios_penalize_isa_irq(irq, 1);
73 }
74}
75 61
76static void pnpbios_parse_allocated_dmaresource(struct pnp_resource_table *res, 62 if (len <= 0 || end >= 0x10003)
77 int dma) 63 flags |= IORESOURCE_DISABLED;
78{
79 int i = 0;
80
81 while (i < PNP_MAX_DMA &&
82 !(res->dma_resource[i].flags & IORESOURCE_UNSET))
83 i++;
84 if (i < PNP_MAX_DMA) {
85 res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
86 if (dma == -1) {
87 res->dma_resource[i].flags |= IORESOURCE_DISABLED;
88 return;
89 }
90 res->dma_resource[i].start =
91 res->dma_resource[i].end = (unsigned long)dma;
92 }
93}
94 64
95static void pnpbios_parse_allocated_ioresource(struct pnp_resource_table *res, 65 pnp_add_io_resource(dev, start, end, flags);
96 int io, int len)
97{
98 int i = 0;
99
100 while (!(res->port_resource[i].flags & IORESOURCE_UNSET)
101 && i < PNP_MAX_PORT)
102 i++;
103 if (i < PNP_MAX_PORT) {
104 res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag
105 if (len <= 0 || (io + len - 1) >= 0x10003) {
106 res->port_resource[i].flags |= IORESOURCE_DISABLED;
107 return;
108 }
109 res->port_resource[i].start = (unsigned long)io;
110 res->port_resource[i].end = (unsigned long)(io + len - 1);
111 }
112} 66}
113 67
114static void pnpbios_parse_allocated_memresource(struct pnp_resource_table *res, 68static void pnpbios_parse_allocated_memresource(struct pnp_dev *dev,
115 int mem, int len) 69 int start, int len)
116{ 70{
117 int i = 0; 71 int flags = 0;
118 72 int end = start + len - 1;
119 while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) 73
120 && i < PNP_MAX_MEM) 74 if (len <= 0)
121 i++; 75 flags |= IORESOURCE_DISABLED;
122 if (i < PNP_MAX_MEM) { 76
123 res->mem_resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag 77 pnp_add_mem_resource(dev, start, end, flags);
124 if (len <= 0) {
125 res->mem_resource[i].flags |= IORESOURCE_DISABLED;
126 return;
127 }
128 res->mem_resource[i].start = (unsigned long)mem;
129 res->mem_resource[i].end = (unsigned long)(mem + len - 1);
130 }
131} 78}
132 79
133static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, 80static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev,
134 unsigned char *end, 81 unsigned char *p,
135 struct 82 unsigned char *end)
136 pnp_resource_table
137 *res)
138{ 83{
139 unsigned int len, tag; 84 unsigned int len, tag;
140 int io, size, mask, i; 85 int io, size, mask, i, flags;
141 86
142 if (!p) 87 if (!p)
143 return NULL; 88 return NULL;
144 89
145 /* Blank the resource table values */ 90 dev_dbg(&dev->dev, "parse allocated resources\n");
146 pnp_init_resource_table(res); 91
92 pnp_init_resources(dev);
147 93
148 while ((char *)p < (char *)end) { 94 while ((char *)p < (char *)end) {
149 95
@@ -163,7 +109,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
163 goto len_err; 109 goto len_err;
164 io = *(short *)&p[4]; 110 io = *(short *)&p[4];
165 size = *(short *)&p[10]; 111 size = *(short *)&p[10];
166 pnpbios_parse_allocated_memresource(res, io, size); 112 pnpbios_parse_allocated_memresource(dev, io, size);
167 break; 113 break;
168 114
169 case LARGE_TAG_ANSISTR: 115 case LARGE_TAG_ANSISTR:
@@ -179,7 +125,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
179 goto len_err; 125 goto len_err;
180 io = *(int *)&p[4]; 126 io = *(int *)&p[4];
181 size = *(int *)&p[16]; 127 size = *(int *)&p[16];
182 pnpbios_parse_allocated_memresource(res, io, size); 128 pnpbios_parse_allocated_memresource(dev, io, size);
183 break; 129 break;
184 130
185 case LARGE_TAG_FIXEDMEM32: 131 case LARGE_TAG_FIXEDMEM32:
@@ -187,29 +133,37 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
187 goto len_err; 133 goto len_err;
188 io = *(int *)&p[4]; 134 io = *(int *)&p[4];
189 size = *(int *)&p[8]; 135 size = *(int *)&p[8];
190 pnpbios_parse_allocated_memresource(res, io, size); 136 pnpbios_parse_allocated_memresource(dev, io, size);
191 break; 137 break;
192 138
193 case SMALL_TAG_IRQ: 139 case SMALL_TAG_IRQ:
194 if (len < 2 || len > 3) 140 if (len < 2 || len > 3)
195 goto len_err; 141 goto len_err;
142 flags = 0;
196 io = -1; 143 io = -1;
197 mask = p[1] + p[2] * 256; 144 mask = p[1] + p[2] * 256;
198 for (i = 0; i < 16; i++, mask = mask >> 1) 145 for (i = 0; i < 16; i++, mask = mask >> 1)
199 if (mask & 0x01) 146 if (mask & 0x01)
200 io = i; 147 io = i;
201 pnpbios_parse_allocated_irqresource(res, io); 148 if (io != -1)
149 pcibios_penalize_isa_irq(io, 1);
150 else
151 flags = IORESOURCE_DISABLED;
152 pnp_add_irq_resource(dev, io, flags);
202 break; 153 break;
203 154
204 case SMALL_TAG_DMA: 155 case SMALL_TAG_DMA:
205 if (len != 2) 156 if (len != 2)
206 goto len_err; 157 goto len_err;
158 flags = 0;
207 io = -1; 159 io = -1;
208 mask = p[1]; 160 mask = p[1];
209 for (i = 0; i < 8; i++, mask = mask >> 1) 161 for (i = 0; i < 8; i++, mask = mask >> 1)
210 if (mask & 0x01) 162 if (mask & 0x01)
211 io = i; 163 io = i;
212 pnpbios_parse_allocated_dmaresource(res, io); 164 if (io == -1)
165 flags = IORESOURCE_DISABLED;
166 pnp_add_dma_resource(dev, io, flags);
213 break; 167 break;
214 168
215 case SMALL_TAG_PORT: 169 case SMALL_TAG_PORT:
@@ -217,7 +171,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
217 goto len_err; 171 goto len_err;
218 io = p[2] + p[3] * 256; 172 io = p[2] + p[3] * 256;
219 size = p[7]; 173 size = p[7];
220 pnpbios_parse_allocated_ioresource(res, io, size); 174 pnpbios_parse_allocated_ioresource(dev, io, size);
221 break; 175 break;
222 176
223 case SMALL_TAG_VENDOR: 177 case SMALL_TAG_VENDOR:
@@ -229,7 +183,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
229 goto len_err; 183 goto len_err;
230 io = p[1] + p[2] * 256; 184 io = p[1] + p[2] * 256;
231 size = p[3]; 185 size = p[3];
232 pnpbios_parse_allocated_ioresource(res, io, size); 186 pnpbios_parse_allocated_ioresource(dev, io, size);
233 break; 187 break;
234 188
235 case SMALL_TAG_END: 189 case SMALL_TAG_END:
@@ -239,9 +193,8 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
239 193
240 default: /* an unkown tag */ 194 default: /* an unkown tag */
241len_err: 195len_err:
242 printk(KERN_ERR 196 dev_err(&dev->dev, "unknown tag %#x length %d\n",
243 "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", 197 tag, len);
244 tag, len);
245 break; 198 break;
246 } 199 }
247 200
@@ -252,8 +205,7 @@ len_err:
252 p += len + 1; 205 p += len + 1;
253 } 206 }
254 207
255 printk(KERN_ERR 208 dev_err(&dev->dev, "no end tag in resource structure\n");
256 "PnPBIOS: Resource structure does not contain an end tag.\n");
257 209
258 return NULL; 210 return NULL;
259} 211}
@@ -262,7 +214,8 @@ len_err:
262 * Resource Configuration Options 214 * Resource Configuration Options
263 */ 215 */
264 216
265static __init void pnpbios_parse_mem_option(unsigned char *p, int size, 217static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
218 unsigned char *p, int size,
266 struct pnp_option *option) 219 struct pnp_option *option)
267{ 220{
268 struct pnp_mem *mem; 221 struct pnp_mem *mem;
@@ -275,10 +228,11 @@ static __init void pnpbios_parse_mem_option(unsigned char *p, int size,
275 mem->align = (p[9] << 8) | p[8]; 228 mem->align = (p[9] << 8) | p[8];
276 mem->size = ((p[11] << 8) | p[10]) << 8; 229 mem->size = ((p[11] << 8) | p[10]) << 8;
277 mem->flags = p[3]; 230 mem->flags = p[3];
278 pnp_register_mem_resource(option, mem); 231 pnp_register_mem_resource(dev, option, mem);
279} 232}
280 233
281static __init void pnpbios_parse_mem32_option(unsigned char *p, int size, 234static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
235 unsigned char *p, int size,
282 struct pnp_option *option) 236 struct pnp_option *option)
283{ 237{
284 struct pnp_mem *mem; 238 struct pnp_mem *mem;
@@ -291,10 +245,11 @@ static __init void pnpbios_parse_mem32_option(unsigned char *p, int size,
291 mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; 245 mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
292 mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; 246 mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
293 mem->flags = p[3]; 247 mem->flags = p[3];
294 pnp_register_mem_resource(option, mem); 248 pnp_register_mem_resource(dev, option, mem);
295} 249}
296 250
297static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, 251static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
252 unsigned char *p, int size,
298 struct pnp_option *option) 253 struct pnp_option *option)
299{ 254{
300 struct pnp_mem *mem; 255 struct pnp_mem *mem;
@@ -306,11 +261,12 @@ static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size,
306 mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; 261 mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
307 mem->align = 0; 262 mem->align = 0;
308 mem->flags = p[3]; 263 mem->flags = p[3];
309 pnp_register_mem_resource(option, mem); 264 pnp_register_mem_resource(dev, option, mem);
310} 265}
311 266
312static __init void pnpbios_parse_irq_option(unsigned char *p, int size, 267static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
313 struct pnp_option *option) 268 unsigned char *p, int size,
269 struct pnp_option *option)
314{ 270{
315 struct pnp_irq *irq; 271 struct pnp_irq *irq;
316 unsigned long bits; 272 unsigned long bits;
@@ -324,11 +280,12 @@ static __init void pnpbios_parse_irq_option(unsigned char *p, int size,
324 irq->flags = p[3]; 280 irq->flags = p[3];
325 else 281 else
326 irq->flags = IORESOURCE_IRQ_HIGHEDGE; 282 irq->flags = IORESOURCE_IRQ_HIGHEDGE;
327 pnp_register_irq_resource(option, irq); 283 pnp_register_irq_resource(dev, option, irq);
328} 284}
329 285
330static __init void pnpbios_parse_dma_option(unsigned char *p, int size, 286static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
331 struct pnp_option *option) 287 unsigned char *p, int size,
288 struct pnp_option *option)
332{ 289{
333 struct pnp_dma *dma; 290 struct pnp_dma *dma;
334 291
@@ -337,10 +294,11 @@ static __init void pnpbios_parse_dma_option(unsigned char *p, int size,
337 return; 294 return;
338 dma->map = p[1]; 295 dma->map = p[1];
339 dma->flags = p[2]; 296 dma->flags = p[2];
340 pnp_register_dma_resource(option, dma); 297 pnp_register_dma_resource(dev, option, dma);
341} 298}
342 299
343static __init void pnpbios_parse_port_option(unsigned char *p, int size, 300static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
301 unsigned char *p, int size,
344 struct pnp_option *option) 302 struct pnp_option *option)
345{ 303{
346 struct pnp_port *port; 304 struct pnp_port *port;
@@ -353,10 +311,11 @@ static __init void pnpbios_parse_port_option(unsigned char *p, int size,
353 port->align = p[6]; 311 port->align = p[6];
354 port->size = p[7]; 312 port->size = p[7];
355 port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0; 313 port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
356 pnp_register_port_resource(option, port); 314 pnp_register_port_resource(dev, option, port);
357} 315}
358 316
359static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size, 317static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
318 unsigned char *p, int size,
360 struct pnp_option *option) 319 struct pnp_option *option)
361{ 320{
362 struct pnp_port *port; 321 struct pnp_port *port;
@@ -368,7 +327,7 @@ static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size,
368 port->size = p[3]; 327 port->size = p[3];
369 port->align = 0; 328 port->align = 0;
370 port->flags = PNP_PORT_FLAG_FIXED; 329 port->flags = PNP_PORT_FLAG_FIXED;
371 pnp_register_port_resource(option, port); 330 pnp_register_port_resource(dev, option, port);
372} 331}
373 332
374static __init unsigned char * 333static __init unsigned char *
@@ -382,6 +341,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
382 if (!p) 341 if (!p)
383 return NULL; 342 return NULL;
384 343
344 dev_dbg(&dev->dev, "parse resource options\n");
345
385 option_independent = option = pnp_register_independent_option(dev); 346 option_independent = option = pnp_register_independent_option(dev);
386 if (!option) 347 if (!option)
387 return NULL; 348 return NULL;
@@ -402,37 +363,37 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
402 case LARGE_TAG_MEM: 363 case LARGE_TAG_MEM:
403 if (len != 9) 364 if (len != 9)
404 goto len_err; 365 goto len_err;
405 pnpbios_parse_mem_option(p, len, option); 366 pnpbios_parse_mem_option(dev, p, len, option);
406 break; 367 break;
407 368
408 case LARGE_TAG_MEM32: 369 case LARGE_TAG_MEM32:
409 if (len != 17) 370 if (len != 17)
410 goto len_err; 371 goto len_err;
411 pnpbios_parse_mem32_option(p, len, option); 372 pnpbios_parse_mem32_option(dev, p, len, option);
412 break; 373 break;
413 374
414 case LARGE_TAG_FIXEDMEM32: 375 case LARGE_TAG_FIXEDMEM32:
415 if (len != 9) 376 if (len != 9)
416 goto len_err; 377 goto len_err;
417 pnpbios_parse_fixed_mem32_option(p, len, option); 378 pnpbios_parse_fixed_mem32_option(dev, p, len, option);
418 break; 379 break;
419 380
420 case SMALL_TAG_IRQ: 381 case SMALL_TAG_IRQ:
421 if (len < 2 || len > 3) 382 if (len < 2 || len > 3)
422 goto len_err; 383 goto len_err;
423 pnpbios_parse_irq_option(p, len, option); 384 pnpbios_parse_irq_option(dev, p, len, option);
424 break; 385 break;
425 386
426 case SMALL_TAG_DMA: 387 case SMALL_TAG_DMA:
427 if (len != 2) 388 if (len != 2)
428 goto len_err; 389 goto len_err;
429 pnpbios_parse_dma_option(p, len, option); 390 pnpbios_parse_dma_option(dev, p, len, option);
430 break; 391 break;
431 392
432 case SMALL_TAG_PORT: 393 case SMALL_TAG_PORT:
433 if (len != 7) 394 if (len != 7)
434 goto len_err; 395 goto len_err;
435 pnpbios_parse_port_option(p, len, option); 396 pnpbios_parse_port_option(dev, p, len, option);
436 break; 397 break;
437 398
438 case SMALL_TAG_VENDOR: 399 case SMALL_TAG_VENDOR:
@@ -442,7 +403,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
442 case SMALL_TAG_FIXEDPORT: 403 case SMALL_TAG_FIXEDPORT:
443 if (len != 3) 404 if (len != 3)
444 goto len_err; 405 goto len_err;
445 pnpbios_parse_fixed_port_option(p, len, option); 406 pnpbios_parse_fixed_port_option(dev, p, len, option);
446 break; 407 break;
447 408
448 case SMALL_TAG_STARTDEP: 409 case SMALL_TAG_STARTDEP:
@@ -460,9 +421,10 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
460 if (len != 0) 421 if (len != 0)
461 goto len_err; 422 goto len_err;
462 if (option_independent == option) 423 if (option_independent == option)
463 printk(KERN_WARNING 424 dev_warn(&dev->dev, "missing "
464 "PnPBIOS: Missing SMALL_TAG_STARTDEP tag\n"); 425 "SMALL_TAG_STARTDEP tag\n");
465 option = option_independent; 426 option = option_independent;
427 dev_dbg(&dev->dev, "end dependent options\n");
466 break; 428 break;
467 429
468 case SMALL_TAG_END: 430 case SMALL_TAG_END:
@@ -470,9 +432,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
470 432
471 default: /* an unkown tag */ 433 default: /* an unkown tag */
472len_err: 434len_err:
473 printk(KERN_ERR 435 dev_err(&dev->dev, "unknown tag %#x length %d\n",
474 "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", 436 tag, len);
475 tag, len);
476 break; 437 break;
477 } 438 }
478 439
@@ -483,8 +444,7 @@ len_err:
483 p += len + 1; 444 p += len + 1;
484 } 445 }
485 446
486 printk(KERN_ERR 447 dev_err(&dev->dev, "no end tag in resource structure\n");
487 "PnPBIOS: Resource structure does not contain an end tag.\n");
488 448
489 return NULL; 449 return NULL;
490} 450}
@@ -493,32 +453,12 @@ len_err:
493 * Compatible Device IDs 453 * Compatible Device IDs
494 */ 454 */
495 455
496#define HEX(id,a) hex[((id)>>a) & 15]
497#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
498
499void pnpid32_to_pnpid(u32 id, char *str)
500{
501 const char *hex = "0123456789abcdef";
502
503 id = be32_to_cpu(id);
504 str[0] = CHAR(id, 26);
505 str[1] = CHAR(id, 21);
506 str[2] = CHAR(id, 16);
507 str[3] = HEX(id, 12);
508 str[4] = HEX(id, 8);
509 str[5] = HEX(id, 4);
510 str[6] = HEX(id, 0);
511 str[7] = '\0';
512}
513
514#undef CHAR
515#undef HEX
516
517static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, 456static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
518 unsigned char *end, 457 unsigned char *end,
519 struct pnp_dev *dev) 458 struct pnp_dev *dev)
520{ 459{
521 int len, tag; 460 int len, tag;
461 u32 eisa_id;
522 char id[8]; 462 char id[8];
523 struct pnp_id *dev_id; 463 struct pnp_id *dev_id;
524 464
@@ -548,13 +488,11 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
548 case SMALL_TAG_COMPATDEVID: /* compatible ID */ 488 case SMALL_TAG_COMPATDEVID: /* compatible ID */
549 if (len != 4) 489 if (len != 4)
550 goto len_err; 490 goto len_err;
551 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); 491 eisa_id = p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24;
492 pnp_eisa_id_to_string(eisa_id & PNP_EISA_ID_MASK, id);
493 dev_id = pnp_add_id(dev, id);
552 if (!dev_id) 494 if (!dev_id)
553 return NULL; 495 return NULL;
554 pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] <<
555 24, id);
556 memcpy(&dev_id->id, id, 7);
557 pnp_add_id(dev_id, dev);
558 break; 496 break;
559 497
560 case SMALL_TAG_END: 498 case SMALL_TAG_END:
@@ -564,9 +502,8 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
564 502
565 default: /* an unkown tag */ 503 default: /* an unkown tag */
566len_err: 504len_err:
567 printk(KERN_ERR 505 dev_err(&dev->dev, "unknown tag %#x length %d\n",
568 "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", 506 tag, len);
569 tag, len);
570 break; 507 break;
571 } 508 }
572 509
@@ -577,8 +514,7 @@ len_err:
577 p += len + 1; 514 p += len + 1;
578 } 515 }
579 516
580 printk(KERN_ERR 517 dev_err(&dev->dev, "no end tag in resource structure\n");
581 "PnPBIOS: Resource structure does not contain an end tag.\n");
582 518
583 return NULL; 519 return NULL;
584} 520}
@@ -587,7 +523,8 @@ len_err:
587 * Allocated Resource Encoding 523 * Allocated Resource Encoding
588 */ 524 */
589 525
590static void pnpbios_encode_mem(unsigned char *p, struct resource *res) 526static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
527 struct resource *res)
591{ 528{
592 unsigned long base = res->start; 529 unsigned long base = res->start;
593 unsigned long len = res->end - res->start + 1; 530 unsigned long len = res->end - res->start + 1;
@@ -598,9 +535,13 @@ static void pnpbios_encode_mem(unsigned char *p, struct resource *res)
598 p[7] = ((base >> 8) >> 8) & 0xff; 535 p[7] = ((base >> 8) >> 8) & 0xff;
599 p[10] = (len >> 8) & 0xff; 536 p[10] = (len >> 8) & 0xff;
600 p[11] = ((len >> 8) >> 8) & 0xff; 537 p[11] = ((len >> 8) >> 8) & 0xff;
538
539 dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n",
540 (unsigned long long) res->start, (unsigned long long) res->end);
601} 541}
602 542
603static void pnpbios_encode_mem32(unsigned char *p, struct resource *res) 543static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
544 struct resource *res)
604{ 545{
605 unsigned long base = res->start; 546 unsigned long base = res->start;
606 unsigned long len = res->end - res->start + 1; 547 unsigned long len = res->end - res->start + 1;
@@ -617,9 +558,13 @@ static void pnpbios_encode_mem32(unsigned char *p, struct resource *res)
617 p[17] = (len >> 8) & 0xff; 558 p[17] = (len >> 8) & 0xff;
618 p[18] = (len >> 16) & 0xff; 559 p[18] = (len >> 16) & 0xff;
619 p[19] = (len >> 24) & 0xff; 560 p[19] = (len >> 24) & 0xff;
561
562 dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n",
563 (unsigned long long) res->start, (unsigned long long) res->end);
620} 564}
621 565
622static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource *res) 566static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
567 struct resource *res)
623{ 568{
624 unsigned long base = res->start; 569 unsigned long base = res->start;
625 unsigned long len = res->end - res->start + 1; 570 unsigned long len = res->end - res->start + 1;
@@ -632,26 +577,36 @@ static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource *res)
632 p[9] = (len >> 8) & 0xff; 577 p[9] = (len >> 8) & 0xff;
633 p[10] = (len >> 16) & 0xff; 578 p[10] = (len >> 16) & 0xff;
634 p[11] = (len >> 24) & 0xff; 579 p[11] = (len >> 24) & 0xff;
580
581 dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n",
582 (unsigned long long) res->start, (unsigned long long) res->end);
635} 583}
636 584
637static void pnpbios_encode_irq(unsigned char *p, struct resource *res) 585static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
586 struct resource *res)
638{ 587{
639 unsigned long map = 0; 588 unsigned long map = 0;
640 589
641 map = 1 << res->start; 590 map = 1 << res->start;
642 p[1] = map & 0xff; 591 p[1] = map & 0xff;
643 p[2] = (map >> 8) & 0xff; 592 p[2] = (map >> 8) & 0xff;
593
594 dev_dbg(&dev->dev, " encode irq %d\n", res->start);
644} 595}
645 596
646static void pnpbios_encode_dma(unsigned char *p, struct resource *res) 597static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
598 struct resource *res)
647{ 599{
648 unsigned long map = 0; 600 unsigned long map = 0;
649 601
650 map = 1 << res->start; 602 map = 1 << res->start;
651 p[1] = map & 0xff; 603 p[1] = map & 0xff;
604
605 dev_dbg(&dev->dev, " encode dma %d\n", res->start);
652} 606}
653 607
654static void pnpbios_encode_port(unsigned char *p, struct resource *res) 608static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
609 struct resource *res)
655{ 610{
656 unsigned long base = res->start; 611 unsigned long base = res->start;
657 unsigned long len = res->end - res->start + 1; 612 unsigned long len = res->end - res->start + 1;
@@ -661,9 +616,13 @@ static void pnpbios_encode_port(unsigned char *p, struct resource *res)
661 p[4] = base & 0xff; 616 p[4] = base & 0xff;
662 p[5] = (base >> 8) & 0xff; 617 p[5] = (base >> 8) & 0xff;
663 p[7] = len & 0xff; 618 p[7] = len & 0xff;
619
620 dev_dbg(&dev->dev, " encode io %#llx-%#llx\n",
621 (unsigned long long) res->start, (unsigned long long) res->end);
664} 622}
665 623
666static void pnpbios_encode_fixed_port(unsigned char *p, struct resource *res) 624static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
625 struct resource *res)
667{ 626{
668 unsigned long base = res->start; 627 unsigned long base = res->start;
669 unsigned long len = res->end - res->start + 1; 628 unsigned long len = res->end - res->start + 1;
@@ -671,13 +630,15 @@ static void pnpbios_encode_fixed_port(unsigned char *p, struct resource *res)
671 p[1] = base & 0xff; 630 p[1] = base & 0xff;
672 p[2] = (base >> 8) & 0xff; 631 p[2] = (base >> 8) & 0xff;
673 p[3] = len & 0xff; 632 p[3] = len & 0xff;
633
634 dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n",
635 (unsigned long long) res->start, (unsigned long long) res->end);
674} 636}
675 637
676static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p, 638static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev
677 unsigned char *end, 639 *dev,
678 struct 640 unsigned char *p,
679 pnp_resource_table 641 unsigned char *end)
680 *res)
681{ 642{
682 unsigned int len, tag; 643 unsigned int len, tag;
683 int port = 0, irq = 0, dma = 0, mem = 0; 644 int port = 0, irq = 0, dma = 0, mem = 0;
@@ -701,42 +662,48 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
701 case LARGE_TAG_MEM: 662 case LARGE_TAG_MEM:
702 if (len != 9) 663 if (len != 9)
703 goto len_err; 664 goto len_err;
704 pnpbios_encode_mem(p, &res->mem_resource[mem]); 665 pnpbios_encode_mem(dev, p,
666 pnp_get_resource(dev, IORESOURCE_MEM, mem));
705 mem++; 667 mem++;
706 break; 668 break;
707 669
708 case LARGE_TAG_MEM32: 670 case LARGE_TAG_MEM32:
709 if (len != 17) 671 if (len != 17)
710 goto len_err; 672 goto len_err;
711 pnpbios_encode_mem32(p, &res->mem_resource[mem]); 673 pnpbios_encode_mem32(dev, p,
674 pnp_get_resource(dev, IORESOURCE_MEM, mem));
712 mem++; 675 mem++;
713 break; 676 break;
714 677
715 case LARGE_TAG_FIXEDMEM32: 678 case LARGE_TAG_FIXEDMEM32:
716 if (len != 9) 679 if (len != 9)
717 goto len_err; 680 goto len_err;
718 pnpbios_encode_fixed_mem32(p, &res->mem_resource[mem]); 681 pnpbios_encode_fixed_mem32(dev, p,
682 pnp_get_resource(dev, IORESOURCE_MEM, mem));
719 mem++; 683 mem++;
720 break; 684 break;
721 685
722 case SMALL_TAG_IRQ: 686 case SMALL_TAG_IRQ:
723 if (len < 2 || len > 3) 687 if (len < 2 || len > 3)
724 goto len_err; 688 goto len_err;
725 pnpbios_encode_irq(p, &res->irq_resource[irq]); 689 pnpbios_encode_irq(dev, p,
690 pnp_get_resource(dev, IORESOURCE_IRQ, irq));
726 irq++; 691 irq++;
727 break; 692 break;
728 693
729 case SMALL_TAG_DMA: 694 case SMALL_TAG_DMA:
730 if (len != 2) 695 if (len != 2)
731 goto len_err; 696 goto len_err;
732 pnpbios_encode_dma(p, &res->dma_resource[dma]); 697 pnpbios_encode_dma(dev, p,
698 pnp_get_resource(dev, IORESOURCE_DMA, dma));
733 dma++; 699 dma++;
734 break; 700 break;
735 701
736 case SMALL_TAG_PORT: 702 case SMALL_TAG_PORT:
737 if (len != 7) 703 if (len != 7)
738 goto len_err; 704 goto len_err;
739 pnpbios_encode_port(p, &res->port_resource[port]); 705 pnpbios_encode_port(dev, p,
706 pnp_get_resource(dev, IORESOURCE_IO, port));
740 port++; 707 port++;
741 break; 708 break;
742 709
@@ -747,7 +714,8 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
747 case SMALL_TAG_FIXEDPORT: 714 case SMALL_TAG_FIXEDPORT:
748 if (len != 3) 715 if (len != 3)
749 goto len_err; 716 goto len_err;
750 pnpbios_encode_fixed_port(p, &res->port_resource[port]); 717 pnpbios_encode_fixed_port(dev, p,
718 pnp_get_resource(dev, IORESOURCE_IO, port));
751 port++; 719 port++;
752 break; 720 break;
753 721
@@ -758,9 +726,8 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
758 726
759 default: /* an unkown tag */ 727 default: /* an unkown tag */
760len_err: 728len_err:
761 printk(KERN_ERR 729 dev_err(&dev->dev, "unknown tag %#x length %d\n",
762 "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", 730 tag, len);
763 tag, len);
764 break; 731 break;
765 } 732 }
766 733
@@ -771,8 +738,7 @@ len_err:
771 p += len + 1; 738 p += len + 1;
772 } 739 }
773 740
774 printk(KERN_ERR 741 dev_err(&dev->dev, "no end tag in resource structure\n");
775 "PnPBIOS: Resource structure does not contain an end tag.\n");
776 742
777 return NULL; 743 return NULL;
778} 744}
@@ -787,7 +753,7 @@ int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
787 unsigned char *p = (char *)node->data; 753 unsigned char *p = (char *)node->data;
788 unsigned char *end = (char *)(node->data + node->size); 754 unsigned char *end = (char *)(node->data + node->size);
789 755
790 p = pnpbios_parse_allocated_resource_data(p, end, &dev->res); 756 p = pnpbios_parse_allocated_resource_data(dev, p, end);
791 if (!p) 757 if (!p)
792 return -EIO; 758 return -EIO;
793 p = pnpbios_parse_resource_option_data(p, end, dev); 759 p = pnpbios_parse_resource_option_data(p, end, dev);
@@ -799,25 +765,25 @@ int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
799 return 0; 765 return 0;
800} 766}
801 767
802int pnpbios_read_resources_from_node(struct pnp_resource_table *res, 768int pnpbios_read_resources_from_node(struct pnp_dev *dev,
803 struct pnp_bios_node *node) 769 struct pnp_bios_node *node)
804{ 770{
805 unsigned char *p = (char *)node->data; 771 unsigned char *p = (char *)node->data;
806 unsigned char *end = (char *)(node->data + node->size); 772 unsigned char *end = (char *)(node->data + node->size);
807 773
808 p = pnpbios_parse_allocated_resource_data(p, end, res); 774 p = pnpbios_parse_allocated_resource_data(dev, p, end);
809 if (!p) 775 if (!p)
810 return -EIO; 776 return -EIO;
811 return 0; 777 return 0;
812} 778}
813 779
814int pnpbios_write_resources_to_node(struct pnp_resource_table *res, 780int pnpbios_write_resources_to_node(struct pnp_dev *dev,
815 struct pnp_bios_node *node) 781 struct pnp_bios_node *node)
816{ 782{
817 unsigned char *p = (char *)node->data; 783 unsigned char *p = (char *)node->data;
818 unsigned char *end = (char *)(node->data + node->size); 784 unsigned char *end = (char *)(node->data + node->size);
819 785
820 p = pnpbios_encode_allocated_resource_data(p, end, res); 786 p = pnpbios_encode_allocated_resource_data(dev, p, end);
821 if (!p) 787 if (!p)
822 return -EIO; 788 return -EIO;
823 return 0; 789 return 0;
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index e4daf4635c48..d049a2279fea 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -117,6 +117,7 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
117static void quirk_system_pci_resources(struct pnp_dev *dev) 117static void quirk_system_pci_resources(struct pnp_dev *dev)
118{ 118{
119 struct pci_dev *pdev = NULL; 119 struct pci_dev *pdev = NULL;
120 struct resource *res;
120 resource_size_t pnp_start, pnp_end, pci_start, pci_end; 121 resource_size_t pnp_start, pnp_end, pci_start, pci_end;
121 int i, j; 122 int i, j;
122 123
@@ -137,13 +138,15 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
137 138
138 pci_start = pci_resource_start(pdev, i); 139 pci_start = pci_resource_start(pdev, i);
139 pci_end = pci_resource_end(pdev, i); 140 pci_end = pci_resource_end(pdev, i);
140 for (j = 0; j < PNP_MAX_MEM; j++) { 141 for (j = 0;
141 if (!pnp_mem_valid(dev, j) || 142 (res = pnp_get_resource(dev, IORESOURCE_MEM, j));
142 pnp_mem_len(dev, j) == 0) 143 j++) {
144 if (res->flags & IORESOURCE_UNSET ||
145 (res->start == 0 && res->end == 0))
143 continue; 146 continue;
144 147
145 pnp_start = pnp_mem_start(dev, j); 148 pnp_start = res->start;
146 pnp_end = pnp_mem_end(dev, j); 149 pnp_end = res->end;
147 150
148 /* 151 /*
149 * If the PNP region doesn't overlap the PCI 152 * If the PNP region doesn't overlap the PCI
@@ -176,7 +179,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
176 pci_name(pdev), i, 179 pci_name(pdev), i,
177 (unsigned long long) pci_start, 180 (unsigned long long) pci_start,
178 (unsigned long long) pci_end); 181 (unsigned long long) pci_end);
179 pnp_mem_flags(dev, j) = 0; 182 res->flags = 0;
180 } 183 }
181 } 184 }
182 } 185 }
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index e50ebcffb962..2041620d5682 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -53,6 +53,8 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
53 if (dev->independent) 53 if (dev->independent)
54 dev_err(&dev->dev, "independent resource already registered\n"); 54 dev_err(&dev->dev, "independent resource already registered\n");
55 dev->independent = option; 55 dev->independent = option;
56
57 dev_dbg(&dev->dev, "new independent option\n");
56 return option; 58 return option;
57} 59}
58 60
@@ -70,12 +72,18 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
70 parent->next = option; 72 parent->next = option;
71 } else 73 } else
72 dev->dependent = option; 74 dev->dependent = option;
75
76 dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority);
73 return option; 77 return option;
74} 78}
75 79
76int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) 80int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
81 struct pnp_irq *data)
77{ 82{
78 struct pnp_irq *ptr; 83 struct pnp_irq *ptr;
84#ifdef DEBUG
85 char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */
86#endif
79 87
80 ptr = option->irq; 88 ptr = option->irq;
81 while (ptr && ptr->next) 89 while (ptr && ptr->next)
@@ -94,10 +102,17 @@ int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data)
94 pcibios_penalize_isa_irq(i, 0); 102 pcibios_penalize_isa_irq(i, 0);
95 } 103 }
96#endif 104#endif
105
106#ifdef DEBUG
107 bitmap_scnprintf(buf, sizeof(buf), data->map, PNP_IRQ_NR);
108 dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf,
109 data->flags);
110#endif
97 return 0; 111 return 0;
98} 112}
99 113
100int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) 114int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
115 struct pnp_dma *data)
101{ 116{
102 struct pnp_dma *ptr; 117 struct pnp_dma *ptr;
103 118
@@ -109,10 +124,13 @@ int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data)
109 else 124 else
110 option->dma = data; 125 option->dma = data;
111 126
127 dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", data->map,
128 data->flags);
112 return 0; 129 return 0;
113} 130}
114 131
115int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) 132int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
133 struct pnp_port *data)
116{ 134{
117 struct pnp_port *ptr; 135 struct pnp_port *ptr;
118 136
@@ -124,10 +142,14 @@ int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data)
124 else 142 else
125 option->port = data; 143 option->port = data;
126 144
145 dev_dbg(&dev->dev, " io "
146 "min %#x max %#x align %d size %d flags %#x\n",
147 data->min, data->max, data->align, data->size, data->flags);
127 return 0; 148 return 0;
128} 149}
129 150
130int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) 151int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
152 struct pnp_mem *data)
131{ 153{
132 struct pnp_mem *ptr; 154 struct pnp_mem *ptr;
133 155
@@ -138,6 +160,10 @@ int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data)
138 ptr->next = data; 160 ptr->next = data;
139 else 161 else
140 option->mem = data; 162 option->mem = data;
163
164 dev_dbg(&dev->dev, " mem "
165 "min %#x max %#x align %d size %d flags %#x\n",
166 data->min, data->max, data->align, data->size, data->flags);
141 return 0; 167 return 0;
142} 168}
143 169
@@ -213,17 +239,18 @@ void pnp_free_option(struct pnp_option *option)
213#define cannot_compare(flags) \ 239#define cannot_compare(flags) \
214((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) 240((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
215 241
216int pnp_check_port(struct pnp_dev *dev, int idx) 242int pnp_check_port(struct pnp_dev *dev, struct resource *res)
217{ 243{
218 int tmp; 244 int i;
219 struct pnp_dev *tdev; 245 struct pnp_dev *tdev;
246 struct resource *tres;
220 resource_size_t *port, *end, *tport, *tend; 247 resource_size_t *port, *end, *tport, *tend;
221 248
222 port = &dev->res.port_resource[idx].start; 249 port = &res->start;
223 end = &dev->res.port_resource[idx].end; 250 end = &res->end;
224 251
225 /* if the resource doesn't exist, don't complain about it */ 252 /* if the resource doesn't exist, don't complain about it */
226 if (cannot_compare(dev->res.port_resource[idx].flags)) 253 if (cannot_compare(res->flags))
227 return 1; 254 return 1;
228 255
229 /* check if the resource is already in use, skip if the 256 /* check if the resource is already in use, skip if the
@@ -234,18 +261,18 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
234 } 261 }
235 262
236 /* check if the resource is reserved */ 263 /* check if the resource is reserved */
237 for (tmp = 0; tmp < 8; tmp++) { 264 for (i = 0; i < 8; i++) {
238 int rport = pnp_reserve_io[tmp << 1]; 265 int rport = pnp_reserve_io[i << 1];
239 int rend = pnp_reserve_io[(tmp << 1) + 1] + rport - 1; 266 int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1;
240 if (ranged_conflict(port, end, &rport, &rend)) 267 if (ranged_conflict(port, end, &rport, &rend))
241 return 0; 268 return 0;
242 } 269 }
243 270
244 /* check for internal conflicts */ 271 /* check for internal conflicts */
245 for (tmp = 0; tmp < PNP_MAX_PORT && tmp != idx; tmp++) { 272 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
246 if (dev->res.port_resource[tmp].flags & IORESOURCE_IO) { 273 if (tres != res && tres->flags & IORESOURCE_IO) {
247 tport = &dev->res.port_resource[tmp].start; 274 tport = &tres->start;
248 tend = &dev->res.port_resource[tmp].end; 275 tend = &tres->end;
249 if (ranged_conflict(port, end, tport, tend)) 276 if (ranged_conflict(port, end, tport, tend))
250 return 0; 277 return 0;
251 } 278 }
@@ -255,13 +282,14 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
255 pnp_for_each_dev(tdev) { 282 pnp_for_each_dev(tdev) {
256 if (tdev == dev) 283 if (tdev == dev)
257 continue; 284 continue;
258 for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) { 285 for (i = 0;
259 if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) { 286 (tres = pnp_get_resource(tdev, IORESOURCE_IO, i));
260 if (cannot_compare 287 i++) {
261 (tdev->res.port_resource[tmp].flags)) 288 if (tres->flags & IORESOURCE_IO) {
289 if (cannot_compare(tres->flags))
262 continue; 290 continue;
263 tport = &tdev->res.port_resource[tmp].start; 291 tport = &tres->start;
264 tend = &tdev->res.port_resource[tmp].end; 292 tend = &tres->end;
265 if (ranged_conflict(port, end, tport, tend)) 293 if (ranged_conflict(port, end, tport, tend))
266 return 0; 294 return 0;
267 } 295 }
@@ -271,17 +299,18 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
271 return 1; 299 return 1;
272} 300}
273 301
274int pnp_check_mem(struct pnp_dev *dev, int idx) 302int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
275{ 303{
276 int tmp; 304 int i;
277 struct pnp_dev *tdev; 305 struct pnp_dev *tdev;
306 struct resource *tres;
278 resource_size_t *addr, *end, *taddr, *tend; 307 resource_size_t *addr, *end, *taddr, *tend;
279 308
280 addr = &dev->res.mem_resource[idx].start; 309 addr = &res->start;
281 end = &dev->res.mem_resource[idx].end; 310 end = &res->end;
282 311
283 /* if the resource doesn't exist, don't complain about it */ 312 /* if the resource doesn't exist, don't complain about it */
284 if (cannot_compare(dev->res.mem_resource[idx].flags)) 313 if (cannot_compare(res->flags))
285 return 1; 314 return 1;
286 315
287 /* check if the resource is already in use, skip if the 316 /* check if the resource is already in use, skip if the
@@ -292,18 +321,18 @@ int pnp_check_mem(struct pnp_dev *dev, int idx)
292 } 321 }
293 322
294 /* check if the resource is reserved */ 323 /* check if the resource is reserved */
295 for (tmp = 0; tmp < 8; tmp++) { 324 for (i = 0; i < 8; i++) {
296 int raddr = pnp_reserve_mem[tmp << 1]; 325 int raddr = pnp_reserve_mem[i << 1];
297 int rend = pnp_reserve_mem[(tmp << 1) + 1] + raddr - 1; 326 int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1;
298 if (ranged_conflict(addr, end, &raddr, &rend)) 327 if (ranged_conflict(addr, end, &raddr, &rend))
299 return 0; 328 return 0;
300 } 329 }
301 330
302 /* check for internal conflicts */ 331 /* check for internal conflicts */
303 for (tmp = 0; tmp < PNP_MAX_MEM && tmp != idx; tmp++) { 332 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
304 if (dev->res.mem_resource[tmp].flags & IORESOURCE_MEM) { 333 if (tres != res && tres->flags & IORESOURCE_MEM) {
305 taddr = &dev->res.mem_resource[tmp].start; 334 taddr = &tres->start;
306 tend = &dev->res.mem_resource[tmp].end; 335 tend = &tres->end;
307 if (ranged_conflict(addr, end, taddr, tend)) 336 if (ranged_conflict(addr, end, taddr, tend))
308 return 0; 337 return 0;
309 } 338 }
@@ -313,13 +342,14 @@ int pnp_check_mem(struct pnp_dev *dev, int idx)
313 pnp_for_each_dev(tdev) { 342 pnp_for_each_dev(tdev) {
314 if (tdev == dev) 343 if (tdev == dev)
315 continue; 344 continue;
316 for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) { 345 for (i = 0;
317 if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) { 346 (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i));
318 if (cannot_compare 347 i++) {
319 (tdev->res.mem_resource[tmp].flags)) 348 if (tres->flags & IORESOURCE_MEM) {
349 if (cannot_compare(tres->flags))
320 continue; 350 continue;
321 taddr = &tdev->res.mem_resource[tmp].start; 351 taddr = &tres->start;
322 tend = &tdev->res.mem_resource[tmp].end; 352 tend = &tres->end;
323 if (ranged_conflict(addr, end, taddr, tend)) 353 if (ranged_conflict(addr, end, taddr, tend))
324 return 0; 354 return 0;
325 } 355 }
@@ -334,14 +364,17 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id)
334 return IRQ_HANDLED; 364 return IRQ_HANDLED;
335} 365}
336 366
337int pnp_check_irq(struct pnp_dev *dev, int idx) 367int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
338{ 368{
339 int tmp; 369 int i;
340 struct pnp_dev *tdev; 370 struct pnp_dev *tdev;
341 resource_size_t *irq = &dev->res.irq_resource[idx].start; 371 struct resource *tres;
372 resource_size_t *irq;
373
374 irq = &res->start;
342 375
343 /* if the resource doesn't exist, don't complain about it */ 376 /* if the resource doesn't exist, don't complain about it */
344 if (cannot_compare(dev->res.irq_resource[idx].flags)) 377 if (cannot_compare(res->flags))
345 return 1; 378 return 1;
346 379
347 /* check if the resource is valid */ 380 /* check if the resource is valid */
@@ -349,15 +382,15 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
349 return 0; 382 return 0;
350 383
351 /* check if the resource is reserved */ 384 /* check if the resource is reserved */
352 for (tmp = 0; tmp < 16; tmp++) { 385 for (i = 0; i < 16; i++) {
353 if (pnp_reserve_irq[tmp] == *irq) 386 if (pnp_reserve_irq[i] == *irq)
354 return 0; 387 return 0;
355 } 388 }
356 389
357 /* check for internal conflicts */ 390 /* check for internal conflicts */
358 for (tmp = 0; tmp < PNP_MAX_IRQ && tmp != idx; tmp++) { 391 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
359 if (dev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) { 392 if (tres != res && tres->flags & IORESOURCE_IRQ) {
360 if (dev->res.irq_resource[tmp].start == *irq) 393 if (tres->start == *irq)
361 return 0; 394 return 0;
362 } 395 }
363 } 396 }
@@ -388,12 +421,13 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
388 pnp_for_each_dev(tdev) { 421 pnp_for_each_dev(tdev) {
389 if (tdev == dev) 422 if (tdev == dev)
390 continue; 423 continue;
391 for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) { 424 for (i = 0;
392 if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) { 425 (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i));
393 if (cannot_compare 426 i++) {
394 (tdev->res.irq_resource[tmp].flags)) 427 if (tres->flags & IORESOURCE_IRQ) {
428 if (cannot_compare(tres->flags))
395 continue; 429 continue;
396 if ((tdev->res.irq_resource[tmp].start == *irq)) 430 if (tres->start == *irq)
397 return 0; 431 return 0;
398 } 432 }
399 } 433 }
@@ -402,15 +436,18 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
402 return 1; 436 return 1;
403} 437}
404 438
405int pnp_check_dma(struct pnp_dev *dev, int idx) 439int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
406{ 440{
407#ifndef CONFIG_IA64 441#ifndef CONFIG_IA64
408 int tmp; 442 int i;
409 struct pnp_dev *tdev; 443 struct pnp_dev *tdev;
410 resource_size_t *dma = &dev->res.dma_resource[idx].start; 444 struct resource *tres;
445 resource_size_t *dma;
446
447 dma = &res->start;
411 448
412 /* if the resource doesn't exist, don't complain about it */ 449 /* if the resource doesn't exist, don't complain about it */
413 if (cannot_compare(dev->res.dma_resource[idx].flags)) 450 if (cannot_compare(res->flags))
414 return 1; 451 return 1;
415 452
416 /* check if the resource is valid */ 453 /* check if the resource is valid */
@@ -418,15 +455,15 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
418 return 0; 455 return 0;
419 456
420 /* check if the resource is reserved */ 457 /* check if the resource is reserved */
421 for (tmp = 0; tmp < 8; tmp++) { 458 for (i = 0; i < 8; i++) {
422 if (pnp_reserve_dma[tmp] == *dma) 459 if (pnp_reserve_dma[i] == *dma)
423 return 0; 460 return 0;
424 } 461 }
425 462
426 /* check for internal conflicts */ 463 /* check for internal conflicts */
427 for (tmp = 0; tmp < PNP_MAX_DMA && tmp != idx; tmp++) { 464 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
428 if (dev->res.dma_resource[tmp].flags & IORESOURCE_DMA) { 465 if (tres != res && tres->flags & IORESOURCE_DMA) {
429 if (dev->res.dma_resource[tmp].start == *dma) 466 if (tres->start == *dma)
430 return 0; 467 return 0;
431 } 468 }
432 } 469 }
@@ -443,12 +480,13 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
443 pnp_for_each_dev(tdev) { 480 pnp_for_each_dev(tdev) {
444 if (tdev == dev) 481 if (tdev == dev)
445 continue; 482 continue;
446 for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) { 483 for (i = 0;
447 if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) { 484 (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i));
448 if (cannot_compare 485 i++) {
449 (tdev->res.dma_resource[tmp].flags)) 486 if (tres->flags & IORESOURCE_DMA) {
487 if (cannot_compare(tres->flags))
450 continue; 488 continue;
451 if ((tdev->res.dma_resource[tmp].start == *dma)) 489 if (tres->start == *dma)
452 return 0; 490 return 0;
453 } 491 }
454 } 492 }
@@ -461,6 +499,193 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
461#endif 499#endif
462} 500}
463 501
502struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
503 unsigned int type, unsigned int num)
504{
505 struct pnp_resource_table *res = dev->res;
506
507 switch (type) {
508 case IORESOURCE_IO:
509 if (num >= PNP_MAX_PORT)
510 return NULL;
511 return &res->port[num];
512 case IORESOURCE_MEM:
513 if (num >= PNP_MAX_MEM)
514 return NULL;
515 return &res->mem[num];
516 case IORESOURCE_IRQ:
517 if (num >= PNP_MAX_IRQ)
518 return NULL;
519 return &res->irq[num];
520 case IORESOURCE_DMA:
521 if (num >= PNP_MAX_DMA)
522 return NULL;
523 return &res->dma[num];
524 }
525 return NULL;
526}
527
528struct resource *pnp_get_resource(struct pnp_dev *dev,
529 unsigned int type, unsigned int num)
530{
531 struct pnp_resource *pnp_res;
532
533 pnp_res = pnp_get_pnp_resource(dev, type, num);
534 if (pnp_res)
535 return &pnp_res->res;
536
537 return NULL;
538}
539EXPORT_SYMBOL(pnp_get_resource);
540
541static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type)
542{
543 struct pnp_resource *pnp_res;
544 int i;
545
546 switch (type) {
547 case IORESOURCE_IO:
548 for (i = 0; i < PNP_MAX_PORT; i++) {
549 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i);
550 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
551 return pnp_res;
552 }
553 break;
554 case IORESOURCE_MEM:
555 for (i = 0; i < PNP_MAX_MEM; i++) {
556 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, i);
557 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
558 return pnp_res;
559 }
560 break;
561 case IORESOURCE_IRQ:
562 for (i = 0; i < PNP_MAX_IRQ; i++) {
563 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, i);
564 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
565 return pnp_res;
566 }
567 break;
568 case IORESOURCE_DMA:
569 for (i = 0; i < PNP_MAX_DMA; i++) {
570 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, i);
571 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
572 return pnp_res;
573 }
574 break;
575 }
576 return NULL;
577}
578
579struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
580 int flags)
581{
582 struct pnp_resource *pnp_res;
583 struct resource *res;
584 static unsigned char warned;
585
586 pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ);
587 if (!pnp_res) {
588 if (!warned) {
589 dev_err(&dev->dev, "can't add resource for IRQ %d\n",
590 irq);
591 warned = 1;
592 }
593 return NULL;
594 }
595
596 res = &pnp_res->res;
597 res->flags = IORESOURCE_IRQ | flags;
598 res->start = irq;
599 res->end = irq;
600
601 dev_dbg(&dev->dev, " add irq %d flags %#x\n", irq, flags);
602 return pnp_res;
603}
604
605struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
606 int flags)
607{
608 struct pnp_resource *pnp_res;
609 struct resource *res;
610 static unsigned char warned;
611
612 pnp_res = pnp_new_resource(dev, IORESOURCE_DMA);
613 if (!pnp_res) {
614 if (!warned) {
615 dev_err(&dev->dev, "can't add resource for DMA %d\n",
616 dma);
617 warned = 1;
618 }
619 return NULL;
620 }
621
622 res = &pnp_res->res;
623 res->flags = IORESOURCE_DMA | flags;
624 res->start = dma;
625 res->end = dma;
626
627 dev_dbg(&dev->dev, " add dma %d flags %#x\n", dma, flags);
628 return pnp_res;
629}
630
631struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
632 resource_size_t start,
633 resource_size_t end, int flags)
634{
635 struct pnp_resource *pnp_res;
636 struct resource *res;
637 static unsigned char warned;
638
639 pnp_res = pnp_new_resource(dev, IORESOURCE_IO);
640 if (!pnp_res) {
641 if (!warned) {
642 dev_err(&dev->dev, "can't add resource for IO "
643 "%#llx-%#llx\n",(unsigned long long) start,
644 (unsigned long long) end);
645 warned = 1;
646 }
647 return NULL;
648 }
649
650 res = &pnp_res->res;
651 res->flags = IORESOURCE_IO | flags;
652 res->start = start;
653 res->end = end;
654
655 dev_dbg(&dev->dev, " add io %#llx-%#llx flags %#x\n",
656 (unsigned long long) start, (unsigned long long) end, flags);
657 return pnp_res;
658}
659
660struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
661 resource_size_t start,
662 resource_size_t end, int flags)
663{
664 struct pnp_resource *pnp_res;
665 struct resource *res;
666 static unsigned char warned;
667
668 pnp_res = pnp_new_resource(dev, IORESOURCE_MEM);
669 if (!pnp_res) {
670 if (!warned) {
671 dev_err(&dev->dev, "can't add resource for MEM "
672 "%#llx-%#llx\n",(unsigned long long) start,
673 (unsigned long long) end);
674 warned = 1;
675 }
676 return NULL;
677 }
678
679 res = &pnp_res->res;
680 res->flags = IORESOURCE_MEM | flags;
681 res->start = start;
682 res->end = end;
683
684 dev_dbg(&dev->dev, " add mem %#llx-%#llx flags %#x\n",
685 (unsigned long long) start, (unsigned long long) end, flags);
686 return pnp_res;
687}
688
464/* format is: pnp_reserve_irq=irq1[,irq2] .... */ 689/* format is: pnp_reserve_irq=irq1[,irq2] .... */
465static int __init pnp_setup_reserve_irq(char *str) 690static int __init pnp_setup_reserve_irq(char *str)
466{ 691{
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index 13c608f5fb30..3eba85ed729c 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -25,3 +25,66 @@ int pnp_is_active(struct pnp_dev *dev)
25} 25}
26 26
27EXPORT_SYMBOL(pnp_is_active); 27EXPORT_SYMBOL(pnp_is_active);
28
29/*
30 * Functionally similar to acpi_ex_eisa_id_to_string(), but that's
31 * buried in the ACPI CA, and we can't depend on it being present.
32 */
33void pnp_eisa_id_to_string(u32 id, char *str)
34{
35 id = be32_to_cpu(id);
36
37 /*
38 * According to the specs, the first three characters are five-bit
39 * compressed ASCII, and the left-over high order bit should be zero.
40 * However, the Linux ISAPNP code historically used six bits for the
41 * first character, and there seem to be IDs that depend on that,
42 * e.g., "nEC8241" in the Linux 8250_pnp serial driver and the
43 * FreeBSD sys/pc98/cbus/sio_cbus.c driver.
44 */
45 str[0] = 'A' + ((id >> 26) & 0x3f) - 1;
46 str[1] = 'A' + ((id >> 21) & 0x1f) - 1;
47 str[2] = 'A' + ((id >> 16) & 0x1f) - 1;
48 str[3] = hex_asc((id >> 12) & 0xf);
49 str[4] = hex_asc((id >> 8) & 0xf);
50 str[5] = hex_asc((id >> 4) & 0xf);
51 str[6] = hex_asc((id >> 0) & 0xf);
52 str[7] = '\0';
53}
54
55void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
56{
57#ifdef DEBUG
58 struct resource *res;
59 int i;
60
61 dev_dbg(&dev->dev, "current resources: %s\n", desc);
62
63 for (i = 0; i < PNP_MAX_IRQ; i++) {
64 res = pnp_get_resource(dev, IORESOURCE_IRQ, i);
65 if (res && !(res->flags & IORESOURCE_UNSET))
66 dev_dbg(&dev->dev, " irq %lld flags %#lx\n",
67 (unsigned long long) res->start, res->flags);
68 }
69 for (i = 0; i < PNP_MAX_DMA; i++) {
70 res = pnp_get_resource(dev, IORESOURCE_DMA, i);
71 if (res && !(res->flags & IORESOURCE_UNSET))
72 dev_dbg(&dev->dev, " dma %lld flags %#lx\n",
73 (unsigned long long) res->start, res->flags);
74 }
75 for (i = 0; i < PNP_MAX_PORT; i++) {
76 res = pnp_get_resource(dev, IORESOURCE_IO, i);
77 if (res && !(res->flags & IORESOURCE_UNSET))
78 dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n",
79 (unsigned long long) res->start,
80 (unsigned long long) res->end, res->flags);
81 }
82 for (i = 0; i < PNP_MAX_MEM; i++) {
83 res = pnp_get_resource(dev, IORESOURCE_MEM, i);
84 if (res && !(res->flags & IORESOURCE_UNSET))
85 dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n",
86 (unsigned long long) res->start,
87 (unsigned long long) res->end, res->flags);
88 }
89#endif
90}
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index 55c4563986b3..9c2496dbeee4 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -56,14 +56,15 @@ static void reserve_range(struct pnp_dev *dev, resource_size_t start,
56 56
57static void reserve_resources_of_dev(struct pnp_dev *dev) 57static void reserve_resources_of_dev(struct pnp_dev *dev)
58{ 58{
59 struct resource *res;
59 int i; 60 int i;
60 61
61 for (i = 0; i < PNP_MAX_PORT; i++) { 62 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
62 if (!pnp_port_valid(dev, i)) 63 if (res->flags & IORESOURCE_UNSET)
63 continue; 64 continue;
64 if (pnp_port_start(dev, i) == 0) 65 if (res->start == 0)
65 continue; /* disabled */ 66 continue; /* disabled */
66 if (pnp_port_start(dev, i) < 0x100) 67 if (res->start < 0x100)
67 /* 68 /*
68 * Below 0x100 is only standard PC hardware 69 * Below 0x100 is only standard PC hardware
69 * (pics, kbd, timer, dma, ...) 70 * (pics, kbd, timer, dma, ...)
@@ -73,19 +74,17 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
73 * So, do nothing 74 * So, do nothing
74 */ 75 */
75 continue; 76 continue;
76 if (pnp_port_end(dev, i) < pnp_port_start(dev, i)) 77 if (res->end < res->start)
77 continue; /* invalid */ 78 continue; /* invalid */
78 79
79 reserve_range(dev, pnp_port_start(dev, i), 80 reserve_range(dev, res->start, res->end, 1);
80 pnp_port_end(dev, i), 1);
81 } 81 }
82 82
83 for (i = 0; i < PNP_MAX_MEM; i++) { 83 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
84 if (!pnp_mem_valid(dev, i)) 84 if (res->flags & IORESOURCE_UNSET)
85 continue; 85 continue;
86 86
87 reserve_range(dev, pnp_mem_start(dev, i), 87 reserve_range(dev, res->start, res->end, 0);
88 pnp_mem_end(dev, i), 0);
89 } 88 }
90} 89}
91 90