diff options
Diffstat (limited to 'drivers/pnp')
-rw-r--r-- | drivers/pnp/base.h | 74 | ||||
-rw-r--r-- | drivers/pnp/card.c | 55 | ||||
-rw-r--r-- | drivers/pnp/core.c | 46 | ||||
-rw-r--r-- | drivers/pnp/driver.c | 28 | ||||
-rw-r--r-- | drivers/pnp/interface.c | 111 | ||||
-rw-r--r-- | drivers/pnp/isapnp/Makefile | 4 | ||||
-rw-r--r-- | drivers/pnp/isapnp/core.c | 340 | ||||
-rw-r--r-- | drivers/pnp/manager.c | 356 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/Makefile | 4 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/core.c | 90 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/pnpacpi.h | 8 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 589 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/Makefile | 4 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/bioscalls.c | 1 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/core.c | 31 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/pnpbios.h | 140 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/proc.c | 2 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/rsparser.c | 326 | ||||
-rw-r--r-- | drivers/pnp/quirks.c | 15 | ||||
-rw-r--r-- | drivers/pnp/resource.c | 361 | ||||
-rw-r--r-- | drivers/pnp/support.c | 63 | ||||
-rw-r--r-- | drivers/pnp/system.c | 21 |
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 @@ | |||
1 | extern spinlock_t pnp_lock; | 1 | extern spinlock_t pnp_lock; |
2 | void *pnp_alloc(long size); | 2 | void *pnp_alloc(long size); |
3 | |||
4 | int pnp_register_protocol(struct pnp_protocol *protocol); | ||
5 | void pnp_unregister_protocol(struct pnp_protocol *protocol); | ||
6 | |||
7 | #define PNP_EISA_ID_MASK 0x7fffffff | ||
8 | void pnp_eisa_id_to_string(u32 id, char *str); | ||
9 | struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, char *pnpid); | ||
10 | struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid); | ||
11 | |||
12 | int pnp_add_device(struct pnp_dev *dev); | ||
13 | struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id); | ||
3 | int pnp_interface_attach_device(struct pnp_dev *dev); | 14 | int pnp_interface_attach_device(struct pnp_dev *dev); |
15 | |||
16 | int pnp_add_card(struct pnp_card *card); | ||
17 | struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id); | ||
18 | void pnp_remove_card(struct pnp_card *card); | ||
19 | int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); | ||
20 | void pnp_remove_card_device(struct pnp_dev *dev); | ||
21 | |||
22 | struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev); | ||
23 | struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, | ||
24 | int priority); | ||
25 | int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, | ||
26 | struct pnp_irq *data); | ||
27 | int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, | ||
28 | struct pnp_dma *data); | ||
29 | int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, | ||
30 | struct pnp_port *data); | ||
31 | int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, | ||
32 | struct pnp_mem *data); | ||
33 | void pnp_init_resources(struct pnp_dev *dev); | ||
34 | |||
4 | void pnp_fixup_device(struct pnp_dev *dev); | 35 | void pnp_fixup_device(struct pnp_dev *dev); |
5 | void pnp_free_option(struct pnp_option *option); | 36 | void pnp_free_option(struct pnp_option *option); |
6 | int __pnp_add_device(struct pnp_dev *dev); | 37 | int __pnp_add_device(struct pnp_dev *dev); |
7 | void __pnp_remove_device(struct pnp_dev *dev); | 38 | void __pnp_remove_device(struct pnp_dev *dev); |
8 | 39 | ||
9 | int pnp_check_port(struct pnp_dev * dev, int idx); | 40 | int pnp_check_port(struct pnp_dev *dev, struct resource *res); |
10 | int pnp_check_mem(struct pnp_dev * dev, int idx); | 41 | int pnp_check_mem(struct pnp_dev *dev, struct resource *res); |
11 | int pnp_check_irq(struct pnp_dev * dev, int idx); | 42 | int pnp_check_irq(struct pnp_dev *dev, struct resource *res); |
12 | int pnp_check_dma(struct pnp_dev * dev, int idx); | 43 | int pnp_check_dma(struct pnp_dev *dev, struct resource *res); |
44 | |||
45 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); | ||
46 | |||
47 | void pnp_init_resource(struct resource *res); | ||
48 | |||
49 | struct 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 | |||
57 | struct pnp_resource { | ||
58 | struct resource res; | ||
59 | unsigned int index; /* ISAPNP config register index */ | ||
60 | }; | ||
61 | |||
62 | struct 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 | |||
69 | struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, | ||
70 | int flags); | ||
71 | struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, | ||
72 | int flags); | ||
73 | struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, | ||
74 | resource_size_t start, | ||
75 | resource_size_t end, int flags); | ||
76 | struct 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 | */ |
103 | int pnp_add_card_id(struct pnp_id *id, struct pnp_card *card) | 104 | struct 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 | ||
118 | static void pnp_free_card_ids(struct pnp_card *card) | 133 | static 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 | ||
154 | struct 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 | |||
139 | static ssize_t pnp_show_card_name(struct device *dmdev, | 179 | static 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 | ||
112 | int __pnp_add_device(struct pnp_dev *dev) | 113 | struct 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 | |||
151 | int __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 | */ |
232 | int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) | 232 | struct 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 | ||
247 | EXPORT_SYMBOL(pnp_register_driver); | 261 | EXPORT_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 @@ | |||
5 | isapnp-proc-$(CONFIG_PROC_FS) = proc.o | 5 | isapnp-proc-$(CONFIG_PROC_FS) = proc.o |
6 | 6 | ||
7 | obj-y := core.o compat.o $(isapnp-proc-y) | 7 | obj-y := core.o compat.o $(isapnp-proc-y) |
8 | |||
9 | ifeq ($(CONFIG_PNP_DEBUG),y) | ||
10 | EXTRA_CFLAGS += -DDEBUG | ||
11 | endif | ||
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 | */ | ||
393 | static 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 | */ |
415 | static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card, | 403 | static 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 | */ |
443 | static void __init isapnp_parse_irq_resource(struct pnp_option *option, | 431 | static 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 | */ |
466 | static void __init isapnp_parse_dma_resource(struct pnp_option *option, | 455 | static 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 | */ |
484 | static void __init isapnp_parse_port_resource(struct pnp_option *option, | 474 | static 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 | */ |
505 | static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option, | 496 | static 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 | */ |
525 | static void __init isapnp_parse_mem_resource(struct pnp_option *option, | 517 | static 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 | */ |
546 | static void __init isapnp_parse_mem32_resource(struct pnp_option *option, | 539 | static 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 | */ |
569 | static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option, | 563 | static 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 | */ | ||
827 | static 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 | */ |
846 | static int __init isapnp_build_device_list(void) | 825 | static 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); | |||
947 | EXPORT_SYMBOL(isapnp_cfg_end); | 926 | EXPORT_SYMBOL(isapnp_cfg_end); |
948 | EXPORT_SYMBOL(isapnp_write_byte); | 927 | EXPORT_SYMBOL(isapnp_write_byte); |
949 | 928 | ||
950 | static int isapnp_read_resources(struct pnp_dev *dev, | 929 | static 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 | |||
994 | static 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 | ||
1006 | static int isapnp_set_resources(struct pnp_dev *dev, | 979 | static 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 | ||
20 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | 20 | static 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 | ||
61 | static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | 70 | static 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 | ||
112 | static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) | 130 | static 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 | ||
162 | static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) | 190 | static 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 | |||
238 | void 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 | */ |
207 | void pnp_init_resource_table(struct pnp_resource_table *table) | 260 | void 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 | */ |
245 | static void pnp_clean_resource_table(struct pnp_resource_table *res) | 291 | static 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 | ||
373 | fail: | 421 | fail: |
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 | */ | ||
387 | int 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 | |||
425 | fail: | ||
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 | */ | ||
564 | void 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 | |||
572 | EXPORT_SYMBOL(pnp_manual_config_dev); | ||
573 | EXPORT_SYMBOL(pnp_start_dev); | 555 | EXPORT_SYMBOL(pnp_start_dev); |
574 | EXPORT_SYMBOL(pnp_stop_dev); | 556 | EXPORT_SYMBOL(pnp_stop_dev); |
575 | EXPORT_SYMBOL(pnp_activate_dev); | 557 | EXPORT_SYMBOL(pnp_activate_dev); |
576 | EXPORT_SYMBOL(pnp_disable_dev); | 558 | EXPORT_SYMBOL(pnp_disable_dev); |
577 | EXPORT_SYMBOL(pnp_resource_change); | ||
578 | EXPORT_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 | ||
5 | obj-y := core.o rsparser.o | 5 | obj-y := core.o rsparser.o |
6 | |||
7 | ifeq ($(CONFIG_PNP_DEBUG),y) | ||
8 | EXTRA_CFLAGS += -DDEBUG | ||
9 | endif | ||
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 | ||
30 | static int num = 0; | 31 | static int num = 0; |
@@ -72,40 +73,24 @@ static int __init ispnpidacpi(char *id) | |||
72 | return 1; | 73 | return 1; |
73 | } | 74 | } |
74 | 75 | ||
75 | static void __init pnpidacpi_to_pnpid(char *id, char *str) | 76 | static 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 | ||
87 | static int pnpacpi_get_resources(struct pnp_dev *dev, | 82 | static 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 | |||
97 | static 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; |
255 | err1: | ||
256 | kfree(dev_id); | ||
257 | err: | ||
258 | kfree(dev); | ||
259 | return -EINVAL; | ||
260 | } | 206 | } |
261 | 207 | ||
262 | static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, | 208 | static 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 | ||
8 | acpi_status pnpacpi_parse_allocated_resource(acpi_handle, struct pnp_resource_table*); | 8 | int pnpacpi_parse_allocated_resource(struct pnp_dev *); |
9 | acpi_status pnpacpi_parse_resource_option_data(acpi_handle, struct pnp_dev*); | 9 | int pnpacpi_parse_resource_option_data(struct pnp_dev *); |
10 | int pnpacpi_encode_resources(struct pnp_resource_table *, struct acpi_buffer *); | 10 | int pnpacpi_encode_resources(struct pnp_dev *, struct acpi_buffer *); |
11 | int pnpacpi_build_resource_template(acpi_handle, struct acpi_buffer*); | 11 | int 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 | */ |
35 | static int irq_flags(int triggering, int polarity) | 37 | static 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 | ||
50 | static void decode_irq_flags(int flag, int *triggering, int *polarity) | 59 | static 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 | ||
72 | static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, | 81 | static 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 | ||
128 | static int dma_flags(int type, int bus_master, int transfer) | 118 | static 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 | ||
171 | static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, | 161 | static 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 | ||
198 | static 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 | ||
224 | static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, | 175 | static 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 | ||
252 | static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table, | 190 | static 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 | |||
279 | static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | 217 | static 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 | ||
386 | acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle, | 342 | int 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 | ||
396 | static __init void pnpacpi_parse_dma_option(struct pnp_option *option, | 362 | static __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 | ||
416 | static __init void pnpacpi_parse_irq_option(struct pnp_option *option, | 383 | static __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 | ||
436 | static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option, | 404 | static __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 | ||
456 | static __init void pnpacpi_parse_port_option(struct pnp_option *option, | 425 | static __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 | ||
475 | static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option, | 445 | static __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 | ||
492 | static __init void pnpacpi_parse_mem24_option(struct pnp_option *option, | 463 | static __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 | ||
513 | static __init void pnpacpi_parse_mem32_option(struct pnp_option *option, | 485 | static __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 | ||
534 | static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, | 507 | static __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 | ||
554 | static __init void pnpacpi_parse_address_option(struct pnp_option *option, | 528 | static __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 | ||
701 | acpi_status __init pnpacpi_parse_resource_option_data(acpi_handle handle, | 681 | int __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 | ||
718 | static int pnpacpi_supported_resource(struct acpi_resource *res) | 706 | static 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 | ||
763 | int pnpacpi_build_resource_template(acpi_handle handle, | 751 | int 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 | ||
797 | static void pnpacpi_encode_irq(struct acpi_resource *resource, | 786 | static 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 | ||
813 | static void pnpacpi_encode_ext_irq(struct acpi_resource *resource, | 809 | static 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 | ||
830 | static void pnpacpi_encode_dma(struct acpi_resource *resource, | 833 | static 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 | ||
864 | static void pnpacpi_encode_io(struct acpi_resource *resource, | 874 | static 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 | ||
876 | static void pnpacpi_encode_fixed_io(struct acpi_resource *resource, | 893 | static 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 | ||
883 | static void pnpacpi_encode_mem24(struct acpi_resource *resource, | 906 | static 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 | ||
896 | static void pnpacpi_encode_mem32(struct acpi_resource *resource, | 926 | static 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 | ||
908 | static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource, | 945 | static 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 | ||
918 | int pnpacpi_encode_resources(struct pnp_resource_table *res_table, | 963 | int 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 @@ | |||
5 | pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o | 5 | pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o |
6 | 6 | ||
7 | obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y) | 7 | obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y) |
8 | |||
9 | ifeq ($(CONFIG_PNP_DEBUG),y) | ||
10 | EXTRA_CFLAGS += -DDEBUG | ||
11 | endif | ||
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 | ||
206 | static int pnpbios_get_resources(struct pnp_dev *dev, | 206 | static 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 | ||
228 | static int pnpbios_set_resources(struct pnp_dev *dev, | 228 | static 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) | ||
97 | struct pnp_dev_node_info { | ||
98 | __u16 no_nodes; | ||
99 | __u16 max_node_size; | ||
100 | }; | ||
101 | struct pnp_docking_station_info { | ||
102 | __u32 location_id; | ||
103 | __u32 serial; | ||
104 | __u16 capabilities; | ||
105 | }; | ||
106 | struct pnp_isa_config_struc { | ||
107 | __u8 revision; | ||
108 | __u8 no_csns; | ||
109 | __u16 isa_rd_data_port; | ||
110 | __u16 reserved; | ||
111 | }; | ||
112 | struct escd_info_struc { | ||
113 | __u16 min_escd_write_size; | ||
114 | __u16 escd_size; | ||
115 | __u32 nv_storage_base; | ||
116 | }; | ||
117 | struct 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 */ | ||
128 | extern struct pnp_dev_node_info node_info; | ||
129 | |||
130 | extern int pnp_bios_dev_node_info(struct pnp_dev_node_info *data); | ||
131 | extern int pnp_bios_get_dev_node(u8 *nodenum, char config, | ||
132 | struct pnp_bios_node *data); | ||
133 | extern int pnp_bios_set_dev_node(u8 nodenum, char config, | ||
134 | struct pnp_bios_node *data); | ||
135 | extern int pnp_bios_get_stat_res(char *info); | ||
136 | extern int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data); | ||
137 | extern int pnp_bios_escd_info(struct escd_info_struc *data); | ||
138 | extern int pnp_bios_read_escd(char *data, u32 nvram_base); | ||
139 | extern int pnp_bios_dock_station_info(struct pnp_docking_station_info *data); | ||
140 | |||
5 | #pragma pack(1) | 141 | #pragma pack(1) |
6 | union pnp_bios_install_struct { | 142 | union pnp_bios_install_struct { |
7 | struct { | 143 | struct { |
@@ -28,8 +164,8 @@ extern int pnp_bios_present(void); | |||
28 | extern int pnpbios_dont_use_current_config; | 164 | extern int pnpbios_dont_use_current_config; |
29 | 165 | ||
30 | extern int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node); | 166 | extern int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node); |
31 | extern int pnpbios_read_resources_from_node(struct pnp_resource_table *res, struct pnp_bios_node * node); | 167 | extern int pnpbios_read_resources_from_node(struct pnp_dev *dev, struct pnp_bios_node *node); |
32 | extern int pnpbios_write_resources_to_node(struct pnp_resource_table *res, struct pnp_bios_node * node); | 168 | extern int pnpbios_write_resources_to_node(struct pnp_dev *dev, struct pnp_bios_node *node); |
33 | extern void pnpid32_to_pnpid(u32 id, char *str); | 169 | extern void pnpid32_to_pnpid(u32 id, char *str); |
34 | 170 | ||
35 | extern void pnpbios_print_status(const char * module, u16 status); | 171 | extern 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 | ||
56 | static void pnpbios_parse_allocated_irqresource(struct pnp_resource_table *res, | 56 | static 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 | ||
76 | static 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 | ||
95 | static 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 | ||
114 | static void pnpbios_parse_allocated_memresource(struct pnp_resource_table *res, | 68 | static 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 | ||
133 | static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, | 80 | static 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 */ |
241 | len_err: | 195 | len_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 | ||
265 | static __init void pnpbios_parse_mem_option(unsigned char *p, int size, | 217 | static __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 | ||
281 | static __init void pnpbios_parse_mem32_option(unsigned char *p, int size, | 234 | static __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 | ||
297 | static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, | 251 | static __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 | ||
312 | static __init void pnpbios_parse_irq_option(unsigned char *p, int size, | 267 | static __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 | ||
330 | static __init void pnpbios_parse_dma_option(unsigned char *p, int size, | 286 | static __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 | ||
343 | static __init void pnpbios_parse_port_option(unsigned char *p, int size, | 300 | static __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 | ||
359 | static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size, | 317 | static __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 | ||
374 | static __init unsigned char * | 333 | static __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 */ |
472 | len_err: | 434 | len_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 | |||
499 | void 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 | |||
517 | static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, | 456 | static 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 */ |
566 | len_err: | 504 | len_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 | ||
590 | static void pnpbios_encode_mem(unsigned char *p, struct resource *res) | 526 | static 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 | ||
603 | static void pnpbios_encode_mem32(unsigned char *p, struct resource *res) | 543 | static 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 | ||
622 | static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource *res) | 566 | static 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 | ||
637 | static void pnpbios_encode_irq(unsigned char *p, struct resource *res) | 585 | static 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 | ||
646 | static void pnpbios_encode_dma(unsigned char *p, struct resource *res) | 597 | static 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 | ||
654 | static void pnpbios_encode_port(unsigned char *p, struct resource *res) | 608 | static 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 | ||
666 | static void pnpbios_encode_fixed_port(unsigned char *p, struct resource *res) | 624 | static 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 | ||
676 | static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p, | 638 | static 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 */ |
760 | len_err: | 728 | len_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 | ||
802 | int pnpbios_read_resources_from_node(struct pnp_resource_table *res, | 768 | int 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 | ||
814 | int pnpbios_write_resources_to_node(struct pnp_resource_table *res, | 780 | int 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) | |||
117 | static void quirk_system_pci_resources(struct pnp_dev *dev) | 117 | static 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 | ||
76 | int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) | 80 | int 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 | ||
100 | int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) | 114 | int 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 | ||
115 | int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) | 132 | int 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 | ||
130 | int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) | 151 | int 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 | ||
216 | int pnp_check_port(struct pnp_dev *dev, int idx) | 242 | int 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 | ||
274 | int pnp_check_mem(struct pnp_dev *dev, int idx) | 302 | int 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 | ||
337 | int pnp_check_irq(struct pnp_dev *dev, int idx) | 367 | int 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 | ||
405 | int pnp_check_dma(struct pnp_dev *dev, int idx) | 439 | int 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 | ||
502 | struct 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 | |||
528 | struct 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 | } | ||
539 | EXPORT_SYMBOL(pnp_get_resource); | ||
540 | |||
541 | static 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 | |||
579 | struct 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 | |||
605 | struct 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 | |||
631 | struct 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 | |||
660 | struct 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] .... */ |
465 | static int __init pnp_setup_reserve_irq(char *str) | 690 | static 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 | ||
27 | EXPORT_SYMBOL(pnp_is_active); | 27 | EXPORT_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 | */ | ||
33 | void 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 | |||
55 | void 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 | ||
57 | static void reserve_resources_of_dev(struct pnp_dev *dev) | 57 | static 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 | ||