aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp')
-rw-r--r--drivers/pnp/base.h148
-rw-r--r--drivers/pnp/core.c29
-rw-r--r--drivers/pnp/interface.c207
-rw-r--r--drivers/pnp/isapnp/core.c253
-rw-r--r--drivers/pnp/manager.c414
-rw-r--r--drivers/pnp/pnpacpi/core.c4
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c492
-rw-r--r--drivers/pnp/pnpbios/rsparser.c274
-rw-r--r--drivers/pnp/quirks.c307
-rw-r--r--drivers/pnp/resource.c454
-rw-r--r--drivers/pnp/support.c171
-rw-r--r--drivers/pnp/system.c4
12 files changed, 1396 insertions, 1361 deletions
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 886dac823ed6..e3fa9a2d9a3d 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -1,3 +1,8 @@
1/*
2 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
3 * Bjorn Helgaas <bjorn.helgaas@hp.com>
4 */
5
1extern spinlock_t pnp_lock; 6extern spinlock_t pnp_lock;
2void *pnp_alloc(long size); 7void *pnp_alloc(long size);
3 8
@@ -19,22 +24,118 @@ void pnp_remove_card(struct pnp_card *card);
19int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); 24int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
20void pnp_remove_card_device(struct pnp_dev *dev); 25void pnp_remove_card_device(struct pnp_dev *dev);
21 26
22struct pnp_option *pnp_build_option(int priority); 27struct pnp_port {
23struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev); 28 resource_size_t min; /* min base number */
24struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, 29 resource_size_t max; /* max base number */
25 int priority); 30 resource_size_t align; /* align boundary */
26int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, 31 resource_size_t size; /* size of range */
27 struct pnp_irq *data); 32 unsigned char flags; /* port flags */
28int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, 33};
29 struct pnp_dma *data); 34
30int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, 35#define PNP_IRQ_NR 256
31 struct pnp_port *data); 36typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t;
32int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, 37
33 struct pnp_mem *data); 38struct pnp_irq {
39 pnp_irq_mask_t map; /* bitmap for IRQ lines */
40 unsigned char flags; /* IRQ flags */
41};
42
43struct pnp_dma {
44 unsigned char map; /* bitmask for DMA channels */
45 unsigned char flags; /* DMA flags */
46};
47
48struct pnp_mem {
49 resource_size_t min; /* min base number */
50 resource_size_t max; /* max base number */
51 resource_size_t align; /* align boundary */
52 resource_size_t size; /* size of range */
53 unsigned char flags; /* memory flags */
54};
55
56#define PNP_OPTION_DEPENDENT 0x80000000
57#define PNP_OPTION_SET_MASK 0xffff
58#define PNP_OPTION_SET_SHIFT 12
59#define PNP_OPTION_PRIORITY_MASK 0xfff
60#define PNP_OPTION_PRIORITY_SHIFT 0
61
62#define PNP_RES_PRIORITY_PREFERRED 0
63#define PNP_RES_PRIORITY_ACCEPTABLE 1
64#define PNP_RES_PRIORITY_FUNCTIONAL 2
65#define PNP_RES_PRIORITY_INVALID PNP_OPTION_PRIORITY_MASK
66
67struct pnp_option {
68 struct list_head list;
69 unsigned int flags; /* independent/dependent, set, priority */
70
71 unsigned long type; /* IORESOURCE_{IO,MEM,IRQ,DMA} */
72 union {
73 struct pnp_port port;
74 struct pnp_irq irq;
75 struct pnp_dma dma;
76 struct pnp_mem mem;
77 } u;
78};
79
80int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
81 pnp_irq_mask_t *map, unsigned char flags);
82int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
83 unsigned char map, unsigned char flags);
84int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags,
85 resource_size_t min, resource_size_t max,
86 resource_size_t align, resource_size_t size,
87 unsigned char flags);
88int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags,
89 resource_size_t min, resource_size_t max,
90 resource_size_t align, resource_size_t size,
91 unsigned char flags);
92
93static inline int pnp_option_is_dependent(struct pnp_option *option)
94{
95 return option->flags & PNP_OPTION_DEPENDENT ? 1 : 0;
96}
97
98static inline unsigned int pnp_option_set(struct pnp_option *option)
99{
100 return (option->flags >> PNP_OPTION_SET_SHIFT) & PNP_OPTION_SET_MASK;
101}
102
103static inline unsigned int pnp_option_priority(struct pnp_option *option)
104{
105 return (option->flags >> PNP_OPTION_PRIORITY_SHIFT) &
106 PNP_OPTION_PRIORITY_MASK;
107}
108
109static inline unsigned int pnp_new_dependent_set(struct pnp_dev *dev,
110 int priority)
111{
112 unsigned int flags;
113
114 if (priority > PNP_RES_PRIORITY_FUNCTIONAL) {
115 dev_warn(&dev->dev, "invalid dependent option priority %d "
116 "clipped to %d", priority,
117 PNP_RES_PRIORITY_INVALID);
118 priority = PNP_RES_PRIORITY_INVALID;
119 }
120
121 flags = PNP_OPTION_DEPENDENT |
122 ((dev->num_dependent_sets & PNP_OPTION_SET_MASK) <<
123 PNP_OPTION_SET_SHIFT) |
124 ((priority & PNP_OPTION_PRIORITY_MASK) <<
125 PNP_OPTION_PRIORITY_SHIFT);
126
127 dev->num_dependent_sets++;
128
129 return flags;
130}
131
132char *pnp_option_priority_name(struct pnp_option *option);
133void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option);
134
34void pnp_init_resources(struct pnp_dev *dev); 135void pnp_init_resources(struct pnp_dev *dev);
35 136
36void pnp_fixup_device(struct pnp_dev *dev); 137void pnp_fixup_device(struct pnp_dev *dev);
37void pnp_free_option(struct pnp_option *option); 138void pnp_free_options(struct pnp_dev *dev);
38int __pnp_add_device(struct pnp_dev *dev); 139int __pnp_add_device(struct pnp_dev *dev);
39void __pnp_remove_device(struct pnp_dev *dev); 140void __pnp_remove_device(struct pnp_dev *dev);
40 141
@@ -43,29 +144,18 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res);
43int pnp_check_irq(struct pnp_dev *dev, struct resource *res); 144int pnp_check_irq(struct pnp_dev *dev, struct resource *res);
44int pnp_check_dma(struct pnp_dev *dev, struct resource *res); 145int pnp_check_dma(struct pnp_dev *dev, struct resource *res);
45 146
147char *pnp_resource_type_name(struct resource *res);
46void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); 148void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
47 149
48void pnp_init_resource(struct resource *res); 150void pnp_free_resources(struct pnp_dev *dev);
49 151int pnp_resource_type(struct resource *res);
50struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
51 unsigned int type, unsigned int num);
52
53#define PNP_MAX_PORT 40
54#define PNP_MAX_MEM 24
55#define PNP_MAX_IRQ 2
56#define PNP_MAX_DMA 2
57 152
58struct pnp_resource { 153struct pnp_resource {
154 struct list_head list;
59 struct resource res; 155 struct resource res;
60 unsigned int index; /* ISAPNP config register index */
61}; 156};
62 157
63struct pnp_resource_table { 158void pnp_free_resource(struct pnp_resource *pnp_res);
64 struct pnp_resource port[PNP_MAX_PORT];
65 struct pnp_resource mem[PNP_MAX_MEM];
66 struct pnp_resource dma[PNP_MAX_DMA];
67 struct pnp_resource irq[PNP_MAX_IRQ];
68};
69 159
70struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 160struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
71 int flags); 161 int flags);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 20771b7d4482..a411582bcd72 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -99,14 +99,28 @@ static void pnp_free_ids(struct pnp_dev *dev)
99 } 99 }
100} 100}
101 101
102void pnp_free_resource(struct pnp_resource *pnp_res)
103{
104 list_del(&pnp_res->list);
105 kfree(pnp_res);
106}
107
108void pnp_free_resources(struct pnp_dev *dev)
109{
110 struct pnp_resource *pnp_res, *tmp;
111
112 list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) {
113 pnp_free_resource(pnp_res);
114 }
115}
116
102static void pnp_release_device(struct device *dmdev) 117static void pnp_release_device(struct device *dmdev)
103{ 118{
104 struct pnp_dev *dev = to_pnp_dev(dmdev); 119 struct pnp_dev *dev = to_pnp_dev(dmdev);
105 120
106 pnp_free_option(dev->independent);
107 pnp_free_option(dev->dependent);
108 pnp_free_ids(dev); 121 pnp_free_ids(dev);
109 kfree(dev->res); 122 pnp_free_resources(dev);
123 pnp_free_options(dev);
110 kfree(dev); 124 kfree(dev);
111} 125}
112 126
@@ -119,12 +133,8 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
119 if (!dev) 133 if (!dev)
120 return NULL; 134 return NULL;
121 135
122 dev->res = kzalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); 136 INIT_LIST_HEAD(&dev->resources);
123 if (!dev->res) { 137 INIT_LIST_HEAD(&dev->options);
124 kfree(dev);
125 return NULL;
126 }
127
128 dev->protocol = protocol; 138 dev->protocol = protocol;
129 dev->number = id; 139 dev->number = id;
130 dev->dma_mask = DMA_24BIT_MASK; 140 dev->dma_mask = DMA_24BIT_MASK;
@@ -140,7 +150,6 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
140 150
141 dev_id = pnp_add_id(dev, pnpid); 151 dev_id = pnp_add_id(dev, pnpid);
142 if (!dev_id) { 152 if (!dev_id) {
143 kfree(dev->res);
144 kfree(dev); 153 kfree(dev);
145 return NULL; 154 return NULL;
146 } 155 }
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 5695a79f3a52..a876ecf7028c 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -3,6 +3,8 @@
3 * 3 *
4 * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz> 4 * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz>
5 * Copyright 2002 Adam Belay <ambx1@neo.rr.com> 5 * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
6 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
6 */ 8 */
7 9
8#include <linux/pnp.h> 10#include <linux/pnp.h>
@@ -53,11 +55,13 @@ static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...)
53static void pnp_print_port(pnp_info_buffer_t * buffer, char *space, 55static void pnp_print_port(pnp_info_buffer_t * buffer, char *space,
54 struct pnp_port *port) 56 struct pnp_port *port)
55{ 57{
56 pnp_printf(buffer, 58 pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, "
57 "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n", 59 "%i-bit address decoding\n", space,
58 space, port->min, port->max, 60 (unsigned long long) port->min,
59 port->align ? (port->align - 1) : 0, port->size, 61 (unsigned long long) port->max,
60 port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10); 62 port->align ? ((unsigned long long) port->align - 1) : 0,
63 (unsigned long long) port->size,
64 port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10);
61} 65}
62 66
63static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, 67static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
@@ -67,7 +71,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
67 71
68 pnp_printf(buffer, "%sirq ", space); 72 pnp_printf(buffer, "%sirq ", space);
69 for (i = 0; i < PNP_IRQ_NR; i++) 73 for (i = 0; i < PNP_IRQ_NR; i++)
70 if (test_bit(i, irq->map)) { 74 if (test_bit(i, irq->map.bits)) {
71 if (!first) { 75 if (!first) {
72 pnp_printf(buffer, ","); 76 pnp_printf(buffer, ",");
73 } else { 77 } else {
@@ -78,7 +82,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
78 else 82 else
79 pnp_printf(buffer, "%i", i); 83 pnp_printf(buffer, "%i", i);
80 } 84 }
81 if (bitmap_empty(irq->map, PNP_IRQ_NR)) 85 if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
82 pnp_printf(buffer, "<none>"); 86 pnp_printf(buffer, "<none>");
83 if (irq->flags & IORESOURCE_IRQ_HIGHEDGE) 87 if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
84 pnp_printf(buffer, " High-Edge"); 88 pnp_printf(buffer, " High-Edge");
@@ -88,6 +92,8 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
88 pnp_printf(buffer, " High-Level"); 92 pnp_printf(buffer, " High-Level");
89 if (irq->flags & IORESOURCE_IRQ_LOWLEVEL) 93 if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
90 pnp_printf(buffer, " Low-Level"); 94 pnp_printf(buffer, " Low-Level");
95 if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
96 pnp_printf(buffer, " (optional)");
91 pnp_printf(buffer, "\n"); 97 pnp_printf(buffer, "\n");
92} 98}
93 99
@@ -148,8 +154,11 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
148{ 154{
149 char *s; 155 char *s;
150 156
151 pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x", 157 pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
152 space, mem->min, mem->max, mem->align, mem->size); 158 space, (unsigned long long) mem->min,
159 (unsigned long long) mem->max,
160 (unsigned long long) mem->align,
161 (unsigned long long) mem->size);
153 if (mem->flags & IORESOURCE_MEM_WRITEABLE) 162 if (mem->flags & IORESOURCE_MEM_WRITEABLE)
154 pnp_printf(buffer, ", writeable"); 163 pnp_printf(buffer, ", writeable");
155 if (mem->flags & IORESOURCE_MEM_CACHEABLE) 164 if (mem->flags & IORESOURCE_MEM_CACHEABLE)
@@ -177,65 +186,58 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
177} 186}
178 187
179static void pnp_print_option(pnp_info_buffer_t * buffer, char *space, 188static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
180 struct pnp_option *option, int dep) 189 struct pnp_option *option)
181{ 190{
182 char *s; 191 switch (option->type) {
183 struct pnp_port *port; 192 case IORESOURCE_IO:
184 struct pnp_irq *irq; 193 pnp_print_port(buffer, space, &option->u.port);
185 struct pnp_dma *dma; 194 break;
186 struct pnp_mem *mem; 195 case IORESOURCE_MEM:
187 196 pnp_print_mem(buffer, space, &option->u.mem);
188 if (dep) { 197 break;
189 switch (option->priority) { 198 case IORESOURCE_IRQ:
190 case PNP_RES_PRIORITY_PREFERRED: 199 pnp_print_irq(buffer, space, &option->u.irq);
191 s = "preferred"; 200 break;
192 break; 201 case IORESOURCE_DMA:
193 case PNP_RES_PRIORITY_ACCEPTABLE: 202 pnp_print_dma(buffer, space, &option->u.dma);
194 s = "acceptable"; 203 break;
195 break;
196 case PNP_RES_PRIORITY_FUNCTIONAL:
197 s = "functional";
198 break;
199 default:
200 s = "invalid";
201 }
202 pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s);
203 } 204 }
204
205 for (port = option->port; port; port = port->next)
206 pnp_print_port(buffer, space, port);
207 for (irq = option->irq; irq; irq = irq->next)
208 pnp_print_irq(buffer, space, irq);
209 for (dma = option->dma; dma; dma = dma->next)
210 pnp_print_dma(buffer, space, dma);
211 for (mem = option->mem; mem; mem = mem->next)
212 pnp_print_mem(buffer, space, mem);
213} 205}
214 206
215static ssize_t pnp_show_options(struct device *dmdev, 207static ssize_t pnp_show_options(struct device *dmdev,
216 struct device_attribute *attr, char *buf) 208 struct device_attribute *attr, char *buf)
217{ 209{
218 struct pnp_dev *dev = to_pnp_dev(dmdev); 210 struct pnp_dev *dev = to_pnp_dev(dmdev);
219 struct pnp_option *independent = dev->independent; 211 pnp_info_buffer_t *buffer;
220 struct pnp_option *dependent = dev->dependent; 212 struct pnp_option *option;
221 int ret, dep = 1; 213 int ret, dep = 0, set = 0;
214 char *indent;
222 215
223 pnp_info_buffer_t *buffer = (pnp_info_buffer_t *) 216 buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
224 pnp_alloc(sizeof(pnp_info_buffer_t));
225 if (!buffer) 217 if (!buffer)
226 return -ENOMEM; 218 return -ENOMEM;
227 219
228 buffer->len = PAGE_SIZE; 220 buffer->len = PAGE_SIZE;
229 buffer->buffer = buf; 221 buffer->buffer = buf;
230 buffer->curr = buffer->buffer; 222 buffer->curr = buffer->buffer;
231 if (independent)
232 pnp_print_option(buffer, "", independent, 0);
233 223
234 while (dependent) { 224 list_for_each_entry(option, &dev->options, list) {
235 pnp_print_option(buffer, " ", dependent, dep); 225 if (pnp_option_is_dependent(option)) {
236 dependent = dependent->next; 226 indent = " ";
237 dep++; 227 if (!dep || pnp_option_set(option) != set) {
228 set = pnp_option_set(option);
229 dep = 1;
230 pnp_printf(buffer, "Dependent: %02i - "
231 "Priority %s\n", set,
232 pnp_option_priority_name(option));
233 }
234 } else {
235 dep = 0;
236 indent = "";
237 }
238 pnp_print_option(buffer, indent, option);
238 } 239 }
240
239 ret = (buffer->curr - buf); 241 ret = (buffer->curr - buf);
240 kfree(buffer); 242 kfree(buffer);
241 return ret; 243 return ret;
@@ -248,79 +250,59 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
248 char *buf) 250 char *buf)
249{ 251{
250 struct pnp_dev *dev = to_pnp_dev(dmdev); 252 struct pnp_dev *dev = to_pnp_dev(dmdev);
251 struct resource *res;
252 int i, ret;
253 pnp_info_buffer_t *buffer; 253 pnp_info_buffer_t *buffer;
254 struct pnp_resource *pnp_res;
255 struct resource *res;
256 int ret;
254 257
255 if (!dev) 258 if (!dev)
256 return -EINVAL; 259 return -EINVAL;
257 260
258 buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t)); 261 buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
259 if (!buffer) 262 if (!buffer)
260 return -ENOMEM; 263 return -ENOMEM;
264
261 buffer->len = PAGE_SIZE; 265 buffer->len = PAGE_SIZE;
262 buffer->buffer = buf; 266 buffer->buffer = buf;
263 buffer->curr = buffer->buffer; 267 buffer->curr = buffer->buffer;
264 268
265 pnp_printf(buffer, "state = "); 269 pnp_printf(buffer, "state = %s\n", dev->active ? "active" : "disabled");
266 if (dev->active) 270
267 pnp_printf(buffer, "active\n"); 271 list_for_each_entry(pnp_res, &dev->resources, list) {
268 else 272 res = &pnp_res->res;
269 pnp_printf(buffer, "disabled\n"); 273
270 274 pnp_printf(buffer, pnp_resource_type_name(res));
271 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { 275
272 if (pnp_resource_valid(res)) { 276 if (res->flags & IORESOURCE_DISABLED) {
273 pnp_printf(buffer, "io"); 277 pnp_printf(buffer, " disabled\n");
274 if (res->flags & IORESOURCE_DISABLED) 278 continue;
275 pnp_printf(buffer, " disabled\n");
276 else
277 pnp_printf(buffer, " 0x%llx-0x%llx\n",
278 (unsigned long long) res->start,
279 (unsigned long long) res->end);
280 }
281 }
282 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
283 if (pnp_resource_valid(res)) {
284 pnp_printf(buffer, "mem");
285 if (res->flags & IORESOURCE_DISABLED)
286 pnp_printf(buffer, " disabled\n");
287 else
288 pnp_printf(buffer, " 0x%llx-0x%llx\n",
289 (unsigned long long) res->start,
290 (unsigned long long) res->end);
291 }
292 }
293 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
294 if (pnp_resource_valid(res)) {
295 pnp_printf(buffer, "irq");
296 if (res->flags & IORESOURCE_DISABLED)
297 pnp_printf(buffer, " disabled\n");
298 else
299 pnp_printf(buffer, " %lld\n",
300 (unsigned long long) res->start);
301 } 279 }
302 } 280
303 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { 281 switch (pnp_resource_type(res)) {
304 if (pnp_resource_valid(res)) { 282 case IORESOURCE_IO:
305 pnp_printf(buffer, "dma"); 283 case IORESOURCE_MEM:
306 if (res->flags & IORESOURCE_DISABLED) 284 pnp_printf(buffer, " %#llx-%#llx\n",
307 pnp_printf(buffer, " disabled\n"); 285 (unsigned long long) res->start,
308 else 286 (unsigned long long) res->end);
309 pnp_printf(buffer, " %lld\n", 287 break;
310 (unsigned long long) res->start); 288 case IORESOURCE_IRQ:
289 case IORESOURCE_DMA:
290 pnp_printf(buffer, " %lld\n",
291 (unsigned long long) res->start);
292 break;
311 } 293 }
312 } 294 }
295
313 ret = (buffer->curr - buf); 296 ret = (buffer->curr - buf);
314 kfree(buffer); 297 kfree(buffer);
315 return ret; 298 return ret;
316} 299}
317 300
318static ssize_t 301static ssize_t pnp_set_current_resources(struct device *dmdev,
319pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, 302 struct device_attribute *attr,
320 const char *ubuf, size_t count) 303 const char *ubuf, size_t count)
321{ 304{
322 struct pnp_dev *dev = to_pnp_dev(dmdev); 305 struct pnp_dev *dev = to_pnp_dev(dmdev);
323 struct pnp_resource *pnp_res;
324 char *buf = (void *)ubuf; 306 char *buf = (void *)ubuf;
325 int retval = 0; 307 int retval = 0;
326 resource_size_t start, end; 308 resource_size_t start, end;
@@ -368,7 +350,6 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
368 goto done; 350 goto done;
369 } 351 }
370 if (!strnicmp(buf, "set", 3)) { 352 if (!strnicmp(buf, "set", 3)) {
371 int nport = 0, nmem = 0, nirq = 0, ndma = 0;
372 if (dev->active) 353 if (dev->active)
373 goto done; 354 goto done;
374 buf += 3; 355 buf += 3;
@@ -391,10 +372,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
391 end = simple_strtoul(buf, &buf, 0); 372 end = simple_strtoul(buf, &buf, 0);
392 } else 373 } else
393 end = start; 374 end = start;
394 pnp_res = pnp_add_io_resource(dev, start, end, 375 pnp_add_io_resource(dev, start, end, 0);
395 0);
396 if (pnp_res)
397 pnp_res->index = nport++;
398 continue; 376 continue;
399 } 377 }
400 if (!strnicmp(buf, "mem", 3)) { 378 if (!strnicmp(buf, "mem", 3)) {
@@ -411,10 +389,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
411 end = simple_strtoul(buf, &buf, 0); 389 end = simple_strtoul(buf, &buf, 0);
412 } else 390 } else
413 end = start; 391 end = start;
414 pnp_res = pnp_add_mem_resource(dev, start, end, 392 pnp_add_mem_resource(dev, start, end, 0);
415 0);
416 if (pnp_res)
417 pnp_res->index = nmem++;
418 continue; 393 continue;
419 } 394 }
420 if (!strnicmp(buf, "irq", 3)) { 395 if (!strnicmp(buf, "irq", 3)) {
@@ -422,9 +397,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
422 while (isspace(*buf)) 397 while (isspace(*buf))
423 ++buf; 398 ++buf;
424 start = simple_strtoul(buf, &buf, 0); 399 start = simple_strtoul(buf, &buf, 0);
425 pnp_res = pnp_add_irq_resource(dev, start, 0); 400 pnp_add_irq_resource(dev, start, 0);
426 if (pnp_res)
427 pnp_res->index = nirq++;
428 continue; 401 continue;
429 } 402 }
430 if (!strnicmp(buf, "dma", 3)) { 403 if (!strnicmp(buf, "dma", 3)) {
@@ -432,9 +405,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
432 while (isspace(*buf)) 405 while (isspace(*buf))
433 ++buf; 406 ++buf;
434 start = simple_strtoul(buf, &buf, 0); 407 start = simple_strtoul(buf, &buf, 0);
435 pnp_res = pnp_add_dma_resource(dev, start, 0); 408 pnp_add_dma_resource(dev, start, 0);
436 if (pnp_res)
437 pnp_res->index = ndma++;
438 continue; 409 continue;
439 } 410 }
440 break; 411 break;
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index f1bccdbdeb08..101a835e8759 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -429,154 +429,135 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
429 * Add IRQ resource to resources list. 429 * Add IRQ resource to resources list.
430 */ 430 */
431static void __init isapnp_parse_irq_resource(struct pnp_dev *dev, 431static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
432 struct pnp_option *option, 432 unsigned int option_flags,
433 int size) 433 int size)
434{ 434{
435 unsigned char tmp[3]; 435 unsigned char tmp[3];
436 struct pnp_irq *irq;
437 unsigned long bits; 436 unsigned long bits;
437 pnp_irq_mask_t map;
438 unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
438 439
439 isapnp_peek(tmp, size); 440 isapnp_peek(tmp, size);
440 irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
441 if (!irq)
442 return;
443 bits = (tmp[1] << 8) | tmp[0]; 441 bits = (tmp[1] << 8) | tmp[0];
444 bitmap_copy(irq->map, &bits, 16); 442
443 bitmap_zero(map.bits, PNP_IRQ_NR);
444 bitmap_copy(map.bits, &bits, 16);
445
445 if (size > 2) 446 if (size > 2)
446 irq->flags = tmp[2]; 447 flags = tmp[2];
447 else 448
448 irq->flags = IORESOURCE_IRQ_HIGHEDGE; 449 pnp_register_irq_resource(dev, option_flags, &map, flags);
449 pnp_register_irq_resource(dev, option, irq);
450} 450}
451 451
452/* 452/*
453 * Add DMA resource to resources list. 453 * Add DMA resource to resources list.
454 */ 454 */
455static void __init isapnp_parse_dma_resource(struct pnp_dev *dev, 455static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
456 struct pnp_option *option, 456 unsigned int option_flags,
457 int size) 457 int size)
458{ 458{
459 unsigned char tmp[2]; 459 unsigned char tmp[2];
460 struct pnp_dma *dma;
461 460
462 isapnp_peek(tmp, size); 461 isapnp_peek(tmp, size);
463 dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); 462 pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]);
464 if (!dma)
465 return;
466 dma->map = tmp[0];
467 dma->flags = tmp[1];
468 pnp_register_dma_resource(dev, option, dma);
469} 463}
470 464
471/* 465/*
472 * Add port resource to resources list. 466 * Add port resource to resources list.
473 */ 467 */
474static void __init isapnp_parse_port_resource(struct pnp_dev *dev, 468static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
475 struct pnp_option *option, 469 unsigned int option_flags,
476 int size) 470 int size)
477{ 471{
478 unsigned char tmp[7]; 472 unsigned char tmp[7];
479 struct pnp_port *port; 473 resource_size_t min, max, align, len;
474 unsigned char flags;
480 475
481 isapnp_peek(tmp, size); 476 isapnp_peek(tmp, size);
482 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 477 min = (tmp[2] << 8) | tmp[1];
483 if (!port) 478 max = (tmp[4] << 8) | tmp[3];
484 return; 479 align = tmp[5];
485 port->min = (tmp[2] << 8) | tmp[1]; 480 len = tmp[6];
486 port->max = (tmp[4] << 8) | tmp[3]; 481 flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
487 port->align = tmp[5]; 482 pnp_register_port_resource(dev, option_flags,
488 port->size = tmp[6]; 483 min, max, align, len, flags);
489 port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
490 pnp_register_port_resource(dev, option, port);
491} 484}
492 485
493/* 486/*
494 * Add fixed port resource to resources list. 487 * Add fixed port resource to resources list.
495 */ 488 */
496static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, 489static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
497 struct pnp_option *option, 490 unsigned int option_flags,
498 int size) 491 int size)
499{ 492{
500 unsigned char tmp[3]; 493 unsigned char tmp[3];
501 struct pnp_port *port; 494 resource_size_t base, len;
502 495
503 isapnp_peek(tmp, size); 496 isapnp_peek(tmp, size);
504 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 497 base = (tmp[1] << 8) | tmp[0];
505 if (!port) 498 len = tmp[2];
506 return; 499 pnp_register_port_resource(dev, option_flags, base, base, 0, len,
507 port->min = port->max = (tmp[1] << 8) | tmp[0]; 500 IORESOURCE_IO_FIXED);
508 port->size = tmp[2];
509 port->align = 0;
510 port->flags = PNP_PORT_FLAG_FIXED;
511 pnp_register_port_resource(dev, option, port);
512} 501}
513 502
514/* 503/*
515 * Add memory resource to resources list. 504 * Add memory resource to resources list.
516 */ 505 */
517static void __init isapnp_parse_mem_resource(struct pnp_dev *dev, 506static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
518 struct pnp_option *option, 507 unsigned int option_flags,
519 int size) 508 int size)
520{ 509{
521 unsigned char tmp[9]; 510 unsigned char tmp[9];
522 struct pnp_mem *mem; 511 resource_size_t min, max, align, len;
512 unsigned char flags;
523 513
524 isapnp_peek(tmp, size); 514 isapnp_peek(tmp, size);
525 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 515 min = ((tmp[2] << 8) | tmp[1]) << 8;
526 if (!mem) 516 max = ((tmp[4] << 8) | tmp[3]) << 8;
527 return; 517 align = (tmp[6] << 8) | tmp[5];
528 mem->min = ((tmp[2] << 8) | tmp[1]) << 8; 518 len = ((tmp[8] << 8) | tmp[7]) << 8;
529 mem->max = ((tmp[4] << 8) | tmp[3]) << 8; 519 flags = tmp[0];
530 mem->align = (tmp[6] << 8) | tmp[5]; 520 pnp_register_mem_resource(dev, option_flags,
531 mem->size = ((tmp[8] << 8) | tmp[7]) << 8; 521 min, max, align, len, flags);
532 mem->flags = tmp[0];
533 pnp_register_mem_resource(dev, option, mem);
534} 522}
535 523
536/* 524/*
537 * Add 32-bit memory resource to resources list. 525 * Add 32-bit memory resource to resources list.
538 */ 526 */
539static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev, 527static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
540 struct pnp_option *option, 528 unsigned int option_flags,
541 int size) 529 int size)
542{ 530{
543 unsigned char tmp[17]; 531 unsigned char tmp[17];
544 struct pnp_mem *mem; 532 resource_size_t min, max, align, len;
533 unsigned char flags;
545 534
546 isapnp_peek(tmp, size); 535 isapnp_peek(tmp, size);
547 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 536 min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
548 if (!mem) 537 max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
549 return; 538 align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
550 mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1]; 539 len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
551 mem->max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; 540 flags = tmp[0];
552 mem->align = 541 pnp_register_mem_resource(dev, option_flags,
553 (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9]; 542 min, max, align, len, flags);
554 mem->size =
555 (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
556 mem->flags = tmp[0];
557 pnp_register_mem_resource(dev, option, mem);
558} 543}
559 544
560/* 545/*
561 * Add 32-bit fixed memory resource to resources list. 546 * Add 32-bit fixed memory resource to resources list.
562 */ 547 */
563static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev, 548static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
564 struct pnp_option *option, 549 unsigned int option_flags,
565 int size) 550 int size)
566{ 551{
567 unsigned char tmp[9]; 552 unsigned char tmp[9];
568 struct pnp_mem *mem; 553 resource_size_t base, len;
554 unsigned char flags;
569 555
570 isapnp_peek(tmp, size); 556 isapnp_peek(tmp, size);
571 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 557 base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
572 if (!mem) 558 len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
573 return; 559 flags = tmp[0];
574 mem->min = mem->max = 560 pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
575 (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
576 mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
577 mem->align = 0;
578 mem->flags = tmp[0];
579 pnp_register_mem_resource(dev, option, mem);
580} 561}
581 562
582/* 563/*
@@ -604,20 +585,16 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
604static int __init isapnp_create_device(struct pnp_card *card, 585static int __init isapnp_create_device(struct pnp_card *card,
605 unsigned short size) 586 unsigned short size)
606{ 587{
607 int number = 0, skip = 0, priority = 0, compat = 0; 588 int number = 0, skip = 0, priority, compat = 0;
608 unsigned char type, tmp[17]; 589 unsigned char type, tmp[17];
609 struct pnp_option *option; 590 unsigned int option_flags;
610 struct pnp_dev *dev; 591 struct pnp_dev *dev;
611 u32 eisa_id; 592 u32 eisa_id;
612 char id[8]; 593 char id[8];
613 594
614 if ((dev = isapnp_parse_device(card, size, number++)) == NULL) 595 if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
615 return 1; 596 return 1;
616 option = pnp_register_independent_option(dev); 597 option_flags = 0;
617 if (!option) {
618 kfree(dev);
619 return 1;
620 }
621 pnp_add_card_device(card, dev); 598 pnp_add_card_device(card, dev);
622 599
623 while (1) { 600 while (1) {
@@ -634,16 +611,11 @@ static int __init isapnp_create_device(struct pnp_card *card,
634 return 1; 611 return 1;
635 size = 0; 612 size = 0;
636 skip = 0; 613 skip = 0;
637 option = pnp_register_independent_option(dev); 614 option_flags = 0;
638 if (!option) {
639 kfree(dev);
640 return 1;
641 }
642 pnp_add_card_device(card, dev); 615 pnp_add_card_device(card, dev);
643 } else { 616 } else {
644 skip = 1; 617 skip = 1;
645 } 618 }
646 priority = 0;
647 compat = 0; 619 compat = 0;
648 break; 620 break;
649 case _STAG_COMPATDEVID: 621 case _STAG_COMPATDEVID:
@@ -660,44 +632,42 @@ static int __init isapnp_create_device(struct pnp_card *card,
660 case _STAG_IRQ: 632 case _STAG_IRQ:
661 if (size < 2 || size > 3) 633 if (size < 2 || size > 3)
662 goto __skip; 634 goto __skip;
663 isapnp_parse_irq_resource(dev, option, size); 635 isapnp_parse_irq_resource(dev, option_flags, size);
664 size = 0; 636 size = 0;
665 break; 637 break;
666 case _STAG_DMA: 638 case _STAG_DMA:
667 if (size != 2) 639 if (size != 2)
668 goto __skip; 640 goto __skip;
669 isapnp_parse_dma_resource(dev, option, size); 641 isapnp_parse_dma_resource(dev, option_flags, size);
670 size = 0; 642 size = 0;
671 break; 643 break;
672 case _STAG_STARTDEP: 644 case _STAG_STARTDEP:
673 if (size > 1) 645 if (size > 1)
674 goto __skip; 646 goto __skip;
675 priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE; 647 priority = PNP_RES_PRIORITY_ACCEPTABLE;
676 if (size > 0) { 648 if (size > 0) {
677 isapnp_peek(tmp, size); 649 isapnp_peek(tmp, size);
678 priority = 0x100 | tmp[0]; 650 priority = tmp[0];
679 size = 0; 651 size = 0;
680 } 652 }
681 option = pnp_register_dependent_option(dev, priority); 653 option_flags = pnp_new_dependent_set(dev, priority);
682 if (!option)
683 return 1;
684 break; 654 break;
685 case _STAG_ENDDEP: 655 case _STAG_ENDDEP:
686 if (size != 0) 656 if (size != 0)
687 goto __skip; 657 goto __skip;
688 priority = 0; 658 option_flags = 0;
689 dev_dbg(&dev->dev, "end dependent options\n");
690 break; 659 break;
691 case _STAG_IOPORT: 660 case _STAG_IOPORT:
692 if (size != 7) 661 if (size != 7)
693 goto __skip; 662 goto __skip;
694 isapnp_parse_port_resource(dev, option, size); 663 isapnp_parse_port_resource(dev, option_flags, size);
695 size = 0; 664 size = 0;
696 break; 665 break;
697 case _STAG_FIXEDIO: 666 case _STAG_FIXEDIO:
698 if (size != 3) 667 if (size != 3)
699 goto __skip; 668 goto __skip;
700 isapnp_parse_fixed_port_resource(dev, option, size); 669 isapnp_parse_fixed_port_resource(dev, option_flags,
670 size);
701 size = 0; 671 size = 0;
702 break; 672 break;
703 case _STAG_VENDOR: 673 case _STAG_VENDOR:
@@ -705,7 +675,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
705 case _LTAG_MEMRANGE: 675 case _LTAG_MEMRANGE:
706 if (size != 9) 676 if (size != 9)
707 goto __skip; 677 goto __skip;
708 isapnp_parse_mem_resource(dev, option, size); 678 isapnp_parse_mem_resource(dev, option_flags, size);
709 size = 0; 679 size = 0;
710 break; 680 break;
711 case _LTAG_ANSISTR: 681 case _LTAG_ANSISTR:
@@ -720,13 +690,14 @@ static int __init isapnp_create_device(struct pnp_card *card,
720 case _LTAG_MEM32RANGE: 690 case _LTAG_MEM32RANGE:
721 if (size != 17) 691 if (size != 17)
722 goto __skip; 692 goto __skip;
723 isapnp_parse_mem32_resource(dev, option, size); 693 isapnp_parse_mem32_resource(dev, option_flags, size);
724 size = 0; 694 size = 0;
725 break; 695 break;
726 case _LTAG_FIXEDMEM32RANGE: 696 case _LTAG_FIXEDMEM32RANGE:
727 if (size != 9) 697 if (size != 9)
728 goto __skip; 698 goto __skip;
729 isapnp_parse_fixed_mem32_resource(dev, option, size); 699 isapnp_parse_fixed_mem32_resource(dev, option_flags,
700 size);
730 size = 0; 701 size = 0;
731 break; 702 break;
732 case _STAG_END: 703 case _STAG_END:
@@ -928,7 +899,6 @@ EXPORT_SYMBOL(isapnp_write_byte);
928 899
929static int isapnp_get_resources(struct pnp_dev *dev) 900static int isapnp_get_resources(struct pnp_dev *dev)
930{ 901{
931 struct pnp_resource *pnp_res;
932 int i, ret; 902 int i, ret;
933 903
934 dev_dbg(&dev->dev, "get resources\n"); 904 dev_dbg(&dev->dev, "get resources\n");
@@ -940,35 +910,23 @@ static int isapnp_get_resources(struct pnp_dev *dev)
940 910
941 for (i = 0; i < ISAPNP_MAX_PORT; i++) { 911 for (i = 0; i < ISAPNP_MAX_PORT; i++) {
942 ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1)); 912 ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1));
943 if (ret) { 913 pnp_add_io_resource(dev, ret, ret,
944 pnp_res = pnp_add_io_resource(dev, ret, ret, 0); 914 ret == 0 ? IORESOURCE_DISABLED : 0);
945 if (pnp_res)
946 pnp_res->index = i;
947 }
948 } 915 }
949 for (i = 0; i < ISAPNP_MAX_MEM; i++) { 916 for (i = 0; i < ISAPNP_MAX_MEM; i++) {
950 ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8; 917 ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8;
951 if (ret) { 918 pnp_add_mem_resource(dev, ret, ret,
952 pnp_res = pnp_add_mem_resource(dev, ret, ret, 0); 919 ret == 0 ? IORESOURCE_DISABLED : 0);
953 if (pnp_res)
954 pnp_res->index = i;
955 }
956 } 920 }
957 for (i = 0; i < ISAPNP_MAX_IRQ; i++) { 921 for (i = 0; i < ISAPNP_MAX_IRQ; i++) {
958 ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8; 922 ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8;
959 if (ret) { 923 pnp_add_irq_resource(dev, ret,
960 pnp_res = pnp_add_irq_resource(dev, ret, 0); 924 ret == 0 ? IORESOURCE_DISABLED : 0);
961 if (pnp_res)
962 pnp_res->index = i;
963 }
964 } 925 }
965 for (i = 0; i < ISAPNP_MAX_DMA; i++) { 926 for (i = 0; i < ISAPNP_MAX_DMA; i++) {
966 ret = isapnp_read_byte(ISAPNP_CFG_DMA + i); 927 ret = isapnp_read_byte(ISAPNP_CFG_DMA + i);
967 if (ret != 4) { 928 pnp_add_dma_resource(dev, ret,
968 pnp_res = pnp_add_dma_resource(dev, ret, 0); 929 ret == 4 ? IORESOURCE_DISABLED : 0);
969 if (pnp_res)
970 pnp_res->index = i;
971 }
972 } 930 }
973 931
974__end: 932__end:
@@ -978,62 +936,45 @@ __end:
978 936
979static int isapnp_set_resources(struct pnp_dev *dev) 937static int isapnp_set_resources(struct pnp_dev *dev)
980{ 938{
981 struct pnp_resource *pnp_res;
982 struct resource *res; 939 struct resource *res;
983 int tmp, index; 940 int tmp;
984 941
985 dev_dbg(&dev->dev, "set resources\n"); 942 dev_dbg(&dev->dev, "set resources\n");
986 isapnp_cfg_begin(dev->card->number, dev->number); 943 isapnp_cfg_begin(dev->card->number, dev->number);
987 dev->active = 1; 944 dev->active = 1;
988 for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { 945 for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
989 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, tmp); 946 res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
990 if (!pnp_res) 947 if (pnp_resource_enabled(res)) {
991 continue;
992 res = &pnp_res->res;
993 if (pnp_resource_valid(res)) {
994 index = pnp_res->index;
995 dev_dbg(&dev->dev, " set io %d to %#llx\n", 948 dev_dbg(&dev->dev, " set io %d to %#llx\n",
996 index, (unsigned long long) res->start); 949 tmp, (unsigned long long) res->start);
997 isapnp_write_word(ISAPNP_CFG_PORT + (index << 1), 950 isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
998 res->start); 951 res->start);
999 } 952 }
1000 } 953 }
1001 for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) { 954 for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
1002 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, tmp); 955 res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp);
1003 if (!pnp_res) 956 if (pnp_resource_enabled(res)) {
1004 continue;
1005 res = &pnp_res->res;
1006 if (pnp_resource_valid(res)) {
1007 int irq = res->start; 957 int irq = res->start;
1008 if (irq == 2) 958 if (irq == 2)
1009 irq = 9; 959 irq = 9;
1010 index = pnp_res->index; 960 dev_dbg(&dev->dev, " set irq %d to %d\n", tmp, irq);
1011 dev_dbg(&dev->dev, " set irq %d to %d\n", index, irq); 961 isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
1012 isapnp_write_byte(ISAPNP_CFG_IRQ + (index << 1), irq);
1013 } 962 }
1014 } 963 }
1015 for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { 964 for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
1016 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, tmp); 965 res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
1017 if (!pnp_res) 966 if (pnp_resource_enabled(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", 967 dev_dbg(&dev->dev, " set dma %d to %lld\n",
1023 index, (unsigned long long) res->start); 968 tmp, (unsigned long long) res->start);
1024 isapnp_write_byte(ISAPNP_CFG_DMA + index, res->start); 969 isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
1025 } 970 }
1026 } 971 }
1027 for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { 972 for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
1028 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, tmp); 973 res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
1029 if (!pnp_res) 974 if (pnp_resource_enabled(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", 975 dev_dbg(&dev->dev, " set mem %d to %#llx\n",
1035 index, (unsigned long long) res->start); 976 tmp, (unsigned long long) res->start);
1036 isapnp_write_word(ISAPNP_CFG_MEM + (index << 3), 977 isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
1037 (res->start >> 8) & 0xffff); 978 (res->start >> 8) & 0xffff);
1038 } 979 }
1039 } 980 }
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index bea0914ff947..b526eaad3f6c 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -3,6 +3,8 @@
3 * 3 *
4 * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> 4 * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
5 * Copyright 2003 Adam Belay <ambx1@neo.rr.com> 5 * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
6 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
6 */ 8 */
7 9
8#include <linux/errno.h> 10#include <linux/errno.h>
@@ -19,82 +21,64 @@ DEFINE_MUTEX(pnp_res_mutex);
19 21
20static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) 22static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
21{ 23{
22 struct pnp_resource *pnp_res; 24 struct resource *res, local_res;
23 struct resource *res;
24
25 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, idx);
26 if (!pnp_res) {
27 dev_err(&dev->dev, "too many I/O port resources\n");
28 /* pretend we were successful so at least the manager won't try again */
29 return 1;
30 }
31
32 res = &pnp_res->res;
33 25
34 /* check if this resource has been manually set, if so skip */ 26 res = pnp_get_resource(dev, IORESOURCE_IO, idx);
35 if (!(res->flags & IORESOURCE_AUTO)) { 27 if (res) {
36 dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx " 28 dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
37 "flags %#lx\n", idx, (unsigned long long) res->start, 29 "flags %#lx\n", idx, (unsigned long long) res->start,
38 (unsigned long long) res->end, res->flags); 30 (unsigned long long) res->end, res->flags);
39 return 1; 31 return 0;
40 } 32 }
41 33
42 /* set the initial values */ 34 res = &local_res;
43 pnp_res->index = idx; 35 res->flags = rule->flags | IORESOURCE_AUTO;
44 res->flags |= rule->flags | IORESOURCE_IO; 36 res->start = 0;
45 res->flags &= ~IORESOURCE_UNSET; 37 res->end = 0;
46 38
47 if (!rule->size) { 39 if (!rule->size) {
48 res->flags |= IORESOURCE_DISABLED; 40 res->flags |= IORESOURCE_DISABLED;
49 dev_dbg(&dev->dev, " io %d disabled\n", idx); 41 dev_dbg(&dev->dev, " io %d disabled\n", idx);
50 return 1; /* skip disabled resource requests */ 42 goto __add;
51 } 43 }
52 44
53 res->start = rule->min; 45 res->start = rule->min;
54 res->end = res->start + rule->size - 1; 46 res->end = res->start + rule->size - 1;
55 47
56 /* run through until pnp_check_port is happy */
57 while (!pnp_check_port(dev, res)) { 48 while (!pnp_check_port(dev, res)) {
58 res->start += rule->align; 49 res->start += rule->align;
59 res->end = res->start + rule->size - 1; 50 res->end = res->start + rule->size - 1;
60 if (res->start > rule->max || !rule->align) { 51 if (res->start > rule->max || !rule->align) {
61 dev_dbg(&dev->dev, " couldn't assign io %d\n", idx); 52 dev_dbg(&dev->dev, " couldn't assign io %d "
62 return 0; 53 "(min %#llx max %#llx)\n", idx,
54 (unsigned long long) rule->min,
55 (unsigned long long) rule->max);
56 return -EBUSY;
63 } 57 }
64 } 58 }
65 dev_dbg(&dev->dev, " assign io %d %#llx-%#llx\n", idx, 59
66 (unsigned long long) res->start, (unsigned long long) res->end); 60__add:
67 return 1; 61 pnp_add_io_resource(dev, res->start, res->end, res->flags);
62 return 0;
68} 63}
69 64
70static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) 65static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
71{ 66{
72 struct pnp_resource *pnp_res; 67 struct resource *res, local_res;
73 struct resource *res;
74
75 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, idx);
76 if (!pnp_res) {
77 dev_err(&dev->dev, "too many memory resources\n");
78 /* pretend we were successful so at least the manager won't try again */
79 return 1;
80 }
81 68
82 res = &pnp_res->res; 69 res = pnp_get_resource(dev, IORESOURCE_MEM, idx);
83 70 if (res) {
84 /* check if this resource has been manually set, if so skip */
85 if (!(res->flags & IORESOURCE_AUTO)) {
86 dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " 71 dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
87 "flags %#lx\n", idx, (unsigned long long) res->start, 72 "flags %#lx\n", idx, (unsigned long long) res->start,
88 (unsigned long long) res->end, res->flags); 73 (unsigned long long) res->end, res->flags);
89 return 1; 74 return 0;
90 } 75 }
91 76
92 /* set the initial values */ 77 res = &local_res;
93 pnp_res->index = idx; 78 res->flags = rule->flags | IORESOURCE_AUTO;
94 res->flags |= rule->flags | IORESOURCE_MEM; 79 res->start = 0;
95 res->flags &= ~IORESOURCE_UNSET; 80 res->end = 0;
96 81
97 /* convert pnp flags to standard Linux flags */
98 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) 82 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
99 res->flags |= IORESOURCE_READONLY; 83 res->flags |= IORESOURCE_READONLY;
100 if (rule->flags & IORESOURCE_MEM_CACHEABLE) 84 if (rule->flags & IORESOURCE_MEM_CACHEABLE)
@@ -107,30 +91,32 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
107 if (!rule->size) { 91 if (!rule->size) {
108 res->flags |= IORESOURCE_DISABLED; 92 res->flags |= IORESOURCE_DISABLED;
109 dev_dbg(&dev->dev, " mem %d disabled\n", idx); 93 dev_dbg(&dev->dev, " mem %d disabled\n", idx);
110 return 1; /* skip disabled resource requests */ 94 goto __add;
111 } 95 }
112 96
113 res->start = rule->min; 97 res->start = rule->min;
114 res->end = res->start + rule->size - 1; 98 res->end = res->start + rule->size - 1;
115 99
116 /* run through until pnp_check_mem is happy */
117 while (!pnp_check_mem(dev, res)) { 100 while (!pnp_check_mem(dev, res)) {
118 res->start += rule->align; 101 res->start += rule->align;
119 res->end = res->start + rule->size - 1; 102 res->end = res->start + rule->size - 1;
120 if (res->start > rule->max || !rule->align) { 103 if (res->start > rule->max || !rule->align) {
121 dev_dbg(&dev->dev, " couldn't assign mem %d\n", idx); 104 dev_dbg(&dev->dev, " couldn't assign mem %d "
122 return 0; 105 "(min %#llx max %#llx)\n", idx,
106 (unsigned long long) rule->min,
107 (unsigned long long) rule->max);
108 return -EBUSY;
123 } 109 }
124 } 110 }
125 dev_dbg(&dev->dev, " assign mem %d %#llx-%#llx\n", idx, 111
126 (unsigned long long) res->start, (unsigned long long) res->end); 112__add:
127 return 1; 113 pnp_add_mem_resource(dev, res->start, res->end, res->flags);
114 return 0;
128} 115}
129 116
130static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) 117static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
131{ 118{
132 struct pnp_resource *pnp_res; 119 struct resource *res, local_res;
133 struct resource *res;
134 int i; 120 int i;
135 121
136 /* IRQ priority: this table is good for i386 */ 122 /* IRQ priority: this table is good for i386 */
@@ -138,59 +124,57 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
138 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 124 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
139 }; 125 };
140 126
141 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, idx); 127 res = pnp_get_resource(dev, IORESOURCE_IRQ, idx);
142 if (!pnp_res) { 128 if (res) {
143 dev_err(&dev->dev, "too many IRQ resources\n");
144 /* pretend we were successful so at least the manager won't try again */
145 return 1;
146 }
147
148 res = &pnp_res->res;
149
150 /* check if this resource has been manually set, if so skip */
151 if (!(res->flags & IORESOURCE_AUTO)) {
152 dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", 129 dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
153 idx, (int) res->start, res->flags); 130 idx, (int) res->start, res->flags);
154 return 1; 131 return 0;
155 } 132 }
156 133
157 /* set the initial values */ 134 res = &local_res;
158 pnp_res->index = idx; 135 res->flags = rule->flags | IORESOURCE_AUTO;
159 res->flags |= rule->flags | IORESOURCE_IRQ; 136 res->start = -1;
160 res->flags &= ~IORESOURCE_UNSET; 137 res->end = -1;
161 138
162 if (bitmap_empty(rule->map, PNP_IRQ_NR)) { 139 if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) {
163 res->flags |= IORESOURCE_DISABLED; 140 res->flags |= IORESOURCE_DISABLED;
164 dev_dbg(&dev->dev, " irq %d disabled\n", idx); 141 dev_dbg(&dev->dev, " irq %d disabled\n", idx);
165 return 1; /* skip disabled resource requests */ 142 goto __add;
166 } 143 }
167 144
168 /* TBD: need check for >16 IRQ */ 145 /* TBD: need check for >16 IRQ */
169 res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16); 146 res->start = find_next_bit(rule->map.bits, PNP_IRQ_NR, 16);
170 if (res->start < PNP_IRQ_NR) { 147 if (res->start < PNP_IRQ_NR) {
171 res->end = res->start; 148 res->end = res->start;
172 dev_dbg(&dev->dev, " assign irq %d %d\n", idx, 149 goto __add;
173 (int) res->start);
174 return 1;
175 } 150 }
176 for (i = 0; i < 16; i++) { 151 for (i = 0; i < 16; i++) {
177 if (test_bit(xtab[i], rule->map)) { 152 if (test_bit(xtab[i], rule->map.bits)) {
178 res->start = res->end = xtab[i]; 153 res->start = res->end = xtab[i];
179 if (pnp_check_irq(dev, res)) { 154 if (pnp_check_irq(dev, res))
180 dev_dbg(&dev->dev, " assign irq %d %d\n", idx, 155 goto __add;
181 (int) res->start);
182 return 1;
183 }
184 } 156 }
185 } 157 }
158
159 if (rule->flags & IORESOURCE_IRQ_OPTIONAL) {
160 res->start = -1;
161 res->end = -1;
162 res->flags |= IORESOURCE_DISABLED;
163 dev_dbg(&dev->dev, " irq %d disabled (optional)\n", idx);
164 goto __add;
165 }
166
186 dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); 167 dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx);
168 return -EBUSY;
169
170__add:
171 pnp_add_irq_resource(dev, res->start, res->flags);
187 return 0; 172 return 0;
188} 173}
189 174
190static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) 175static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
191{ 176{
192 struct pnp_resource *pnp_res; 177 struct resource *res, local_res;
193 struct resource *res;
194 int i; 178 int i;
195 179
196 /* DMA priority: this table is good for i386 */ 180 /* DMA priority: this table is good for i386 */
@@ -198,231 +182,99 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
198 1, 3, 5, 6, 7, 0, 2, 4 182 1, 3, 5, 6, 7, 0, 2, 4
199 }; 183 };
200 184
201 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx); 185 res = pnp_get_resource(dev, IORESOURCE_DMA, idx);
202 if (!pnp_res) { 186 if (res) {
203 dev_err(&dev->dev, "too many DMA resources\n");
204 return;
205 }
206
207 res = &pnp_res->res;
208
209 /* check if this resource has been manually set, if so skip */
210 if (!(res->flags & IORESOURCE_AUTO)) {
211 dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", 187 dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
212 idx, (int) res->start, res->flags); 188 idx, (int) res->start, res->flags);
213 return; 189 return 0;
214 } 190 }
215 191
216 /* set the initial values */ 192 res = &local_res;
217 pnp_res->index = idx; 193 res->flags = rule->flags | IORESOURCE_AUTO;
218 res->flags |= rule->flags | IORESOURCE_DMA; 194 res->start = -1;
219 res->flags &= ~IORESOURCE_UNSET; 195 res->end = -1;
220 196
221 for (i = 0; i < 8; i++) { 197 for (i = 0; i < 8; i++) {
222 if (rule->map & (1 << xtab[i])) { 198 if (rule->map & (1 << xtab[i])) {
223 res->start = res->end = xtab[i]; 199 res->start = res->end = xtab[i];
224 if (pnp_check_dma(dev, res)) { 200 if (pnp_check_dma(dev, res))
225 dev_dbg(&dev->dev, " assign dma %d %d\n", idx, 201 goto __add;
226 (int) res->start);
227 return;
228 }
229 } 202 }
230 } 203 }
231#ifdef MAX_DMA_CHANNELS 204#ifdef MAX_DMA_CHANNELS
232 res->start = res->end = MAX_DMA_CHANNELS; 205 res->start = res->end = MAX_DMA_CHANNELS;
233#endif 206#endif
234 res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; 207 res->flags |= IORESOURCE_DISABLED;
235 dev_dbg(&dev->dev, " disable dma %d\n", idx); 208 dev_dbg(&dev->dev, " disable dma %d\n", idx);
236}
237
238void pnp_init_resource(struct resource *res)
239{
240 unsigned long type;
241
242 type = res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
243 IORESOURCE_IRQ | IORESOURCE_DMA);
244 209
245 res->name = NULL; 210__add:
246 res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET; 211 pnp_add_dma_resource(dev, res->start, res->flags);
247 if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) { 212 return 0;
248 res->start = -1;
249 res->end = -1;
250 } else {
251 res->start = 0;
252 res->end = 0;
253 }
254} 213}
255 214
256/**
257 * pnp_init_resources - Resets a resource table to default values.
258 * @table: pointer to the desired resource table
259 */
260void pnp_init_resources(struct pnp_dev *dev) 215void pnp_init_resources(struct pnp_dev *dev)
261{ 216{
262 struct resource *res; 217 pnp_free_resources(dev);
263 int idx;
264
265 for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
266 res = &dev->res->irq[idx].res;
267 res->flags = IORESOURCE_IRQ;
268 pnp_init_resource(res);
269 }
270 for (idx = 0; idx < PNP_MAX_DMA; idx++) {
271 res = &dev->res->dma[idx].res;
272 res->flags = IORESOURCE_DMA;
273 pnp_init_resource(res);
274 }
275 for (idx = 0; idx < PNP_MAX_PORT; idx++) {
276 res = &dev->res->port[idx].res;
277 res->flags = IORESOURCE_IO;
278 pnp_init_resource(res);
279 }
280 for (idx = 0; idx < PNP_MAX_MEM; idx++) {
281 res = &dev->res->mem[idx].res;
282 res->flags = IORESOURCE_MEM;
283 pnp_init_resource(res);
284 }
285} 218}
286 219
287/**
288 * pnp_clean_resources - clears resources that were not manually set
289 * @res: the resources to clean
290 */
291static void pnp_clean_resource_table(struct pnp_dev *dev) 220static void pnp_clean_resource_table(struct pnp_dev *dev)
292{ 221{
293 struct resource *res; 222 struct pnp_resource *pnp_res, *tmp;
294 int idx; 223
295 224 list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) {
296 for (idx = 0; idx < PNP_MAX_IRQ; idx++) { 225 if (pnp_res->res.flags & IORESOURCE_AUTO)
297 res = &dev->res->irq[idx].res; 226 pnp_free_resource(pnp_res);
298 if (res->flags & IORESOURCE_AUTO) {
299 res->flags = IORESOURCE_IRQ;
300 pnp_init_resource(res);
301 }
302 }
303 for (idx = 0; idx < PNP_MAX_DMA; idx++) {
304 res = &dev->res->dma[idx].res;
305 if (res->flags & IORESOURCE_AUTO) {
306 res->flags = IORESOURCE_DMA;
307 pnp_init_resource(res);
308 }
309 }
310 for (idx = 0; idx < PNP_MAX_PORT; idx++) {
311 res = &dev->res->port[idx].res;
312 if (res->flags & IORESOURCE_AUTO) {
313 res->flags = IORESOURCE_IO;
314 pnp_init_resource(res);
315 }
316 }
317 for (idx = 0; idx < PNP_MAX_MEM; idx++) {
318 res = &dev->res->mem[idx].res;
319 if (res->flags & IORESOURCE_AUTO) {
320 res->flags = IORESOURCE_MEM;
321 pnp_init_resource(res);
322 }
323 } 227 }
324} 228}
325 229
326/** 230/**
327 * pnp_assign_resources - assigns resources to the device based on the specified dependent number 231 * pnp_assign_resources - assigns resources to the device based on the specified dependent number
328 * @dev: pointer to the desired device 232 * @dev: pointer to the desired device
329 * @depnum: the dependent function number 233 * @set: the dependent function number
330 *
331 * Only set depnum to 0 if the device does not have dependent options.
332 */ 234 */
333static int pnp_assign_resources(struct pnp_dev *dev, int depnum) 235static int pnp_assign_resources(struct pnp_dev *dev, int set)
334{ 236{
335 struct pnp_port *port; 237 struct pnp_option *option;
336 struct pnp_mem *mem;
337 struct pnp_irq *irq;
338 struct pnp_dma *dma;
339 int nport = 0, nmem = 0, nirq = 0, ndma = 0; 238 int nport = 0, nmem = 0, nirq = 0, ndma = 0;
239 int ret = 0;
340 240
341 if (!pnp_can_configure(dev)) 241 dev_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set);
342 return -ENODEV;
343
344 dbg_pnp_show_resources(dev, "before pnp_assign_resources");
345 mutex_lock(&pnp_res_mutex); 242 mutex_lock(&pnp_res_mutex);
346 pnp_clean_resource_table(dev); 243 pnp_clean_resource_table(dev);
347 if (dev->independent) {
348 dev_dbg(&dev->dev, "assigning independent options\n");
349 port = dev->independent->port;
350 mem = dev->independent->mem;
351 irq = dev->independent->irq;
352 dma = dev->independent->dma;
353 while (port) {
354 if (!pnp_assign_port(dev, port, nport))
355 goto fail;
356 nport++;
357 port = port->next;
358 }
359 while (mem) {
360 if (!pnp_assign_mem(dev, mem, nmem))
361 goto fail;
362 nmem++;
363 mem = mem->next;
364 }
365 while (irq) {
366 if (!pnp_assign_irq(dev, irq, nirq))
367 goto fail;
368 nirq++;
369 irq = irq->next;
370 }
371 while (dma) {
372 pnp_assign_dma(dev, dma, ndma);
373 ndma++;
374 dma = dma->next;
375 }
376 }
377 244
378 if (depnum) { 245 list_for_each_entry(option, &dev->options, list) {
379 struct pnp_option *dep; 246 if (pnp_option_is_dependent(option) &&
380 int i; 247 pnp_option_set(option) != set)
381 248 continue;
382 dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum); 249
383 for (i = 1, dep = dev->dependent; i < depnum; 250 switch (option->type) {
384 i++, dep = dep->next) 251 case IORESOURCE_IO:
385 if (!dep) 252 ret = pnp_assign_port(dev, &option->u.port, nport++);
386 goto fail; 253 break;
387 port = dep->port; 254 case IORESOURCE_MEM:
388 mem = dep->mem; 255 ret = pnp_assign_mem(dev, &option->u.mem, nmem++);
389 irq = dep->irq; 256 break;
390 dma = dep->dma; 257 case IORESOURCE_IRQ:
391 while (port) { 258 ret = pnp_assign_irq(dev, &option->u.irq, nirq++);
392 if (!pnp_assign_port(dev, port, nport)) 259 break;
393 goto fail; 260 case IORESOURCE_DMA:
394 nport++; 261 ret = pnp_assign_dma(dev, &option->u.dma, ndma++);
395 port = port->next; 262 break;
396 } 263 default:
397 while (mem) { 264 ret = -EINVAL;
398 if (!pnp_assign_mem(dev, mem, nmem)) 265 break;
399 goto fail;
400 nmem++;
401 mem = mem->next;
402 }
403 while (irq) {
404 if (!pnp_assign_irq(dev, irq, nirq))
405 goto fail;
406 nirq++;
407 irq = irq->next;
408 } 266 }
409 while (dma) { 267 if (ret < 0)
410 pnp_assign_dma(dev, dma, ndma); 268 break;
411 ndma++; 269 }
412 dma = dma->next;
413 }
414 } else if (dev->dependent)
415 goto fail;
416
417 mutex_unlock(&pnp_res_mutex);
418 dbg_pnp_show_resources(dev, "after pnp_assign_resources");
419 return 1;
420 270
421fail:
422 pnp_clean_resource_table(dev);
423 mutex_unlock(&pnp_res_mutex); 271 mutex_unlock(&pnp_res_mutex);
424 dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)"); 272 if (ret < 0) {
425 return 0; 273 dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
274 pnp_clean_resource_table(dev);
275 } else
276 dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
277 return ret;
426} 278}
427 279
428/** 280/**
@@ -431,29 +283,25 @@ fail:
431 */ 283 */
432int pnp_auto_config_dev(struct pnp_dev *dev) 284int pnp_auto_config_dev(struct pnp_dev *dev)
433{ 285{
434 struct pnp_option *dep; 286 int i, ret;
435 int i = 1;
436 287
437 if (!pnp_can_configure(dev)) { 288 if (!pnp_can_configure(dev)) {
438 dev_dbg(&dev->dev, "configuration not supported\n"); 289 dev_dbg(&dev->dev, "configuration not supported\n");
439 return -ENODEV; 290 return -ENODEV;
440 } 291 }
441 292
442 if (!dev->dependent) { 293 ret = pnp_assign_resources(dev, 0);
443 if (pnp_assign_resources(dev, 0)) 294 if (ret == 0)
295 return 0;
296
297 for (i = 1; i < dev->num_dependent_sets; i++) {
298 ret = pnp_assign_resources(dev, i);
299 if (ret == 0)
444 return 0; 300 return 0;
445 } else {
446 dep = dev->dependent;
447 do {
448 if (pnp_assign_resources(dev, i))
449 return 0;
450 dep = dep->next;
451 i++;
452 } while (dep);
453 } 301 }
454 302
455 dev_err(&dev->dev, "unable to assign resources\n"); 303 dev_err(&dev->dev, "unable to assign resources\n");
456 return -EBUSY; 304 return ret;
457} 305}
458 306
459/** 307/**
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 50902773beaf..c1b9ea34977b 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -117,9 +117,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
117{ 117{
118 int power_state; 118 int power_state;
119 119
120 power_state = acpi_pm_device_sleep_state(&dev->dev, 120 power_state = acpi_pm_device_sleep_state(&dev->dev, NULL);
121 device_may_wakeup(&dev->dev),
122 NULL);
123 if (power_state < 0) 121 if (power_state < 0)
124 power_state = (state.event == PM_EVENT_ON) ? 122 power_state = (state.event == PM_EVENT_ON) ?
125 ACPI_STATE_D0 : ACPI_STATE_D3; 123 ACPI_STATE_D0 : ACPI_STATE_D3;
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 46c791adb894..d7e9f2152df0 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -3,6 +3,8 @@
3 * 3 *
4 * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr> 4 * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
5 * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> 5 * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
6 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
6 * 8 *
7 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the 10 * under the terms of the GNU General Public License as published by the
@@ -98,8 +100,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
98 int irq, flags; 100 int irq, flags;
99 int p, t; 101 int p, t;
100 102
101 if (!valid_IRQ(gsi)) 103 if (!valid_IRQ(gsi)) {
104 pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED);
102 return; 105 return;
106 }
103 107
104 /* 108 /*
105 * in IO-APIC mode, use overrided attribute. Two reasons: 109 * in IO-APIC mode, use overrided attribute. Two reasons:
@@ -178,13 +182,68 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
178 u64 end = start + len - 1; 182 u64 end = start + len - 1;
179 183
180 if (io_decode == ACPI_DECODE_16) 184 if (io_decode == ACPI_DECODE_16)
181 flags |= PNP_PORT_FLAG_16BITADDR; 185 flags |= IORESOURCE_IO_16BIT_ADDR;
182 if (len == 0 || end >= 0x10003) 186 if (len == 0 || end >= 0x10003)
183 flags |= IORESOURCE_DISABLED; 187 flags |= IORESOURCE_DISABLED;
184 188
185 pnp_add_io_resource(dev, start, end, flags); 189 pnp_add_io_resource(dev, start, end, flags);
186} 190}
187 191
192/*
193 * Device CSRs that do not appear in PCI config space should be described
194 * via ACPI. This would normally be done with Address Space Descriptors
195 * marked as "consumer-only," but old versions of Windows and Linux ignore
196 * the producer/consumer flag, so HP invented a vendor-defined resource to
197 * describe the location and size of CSR space.
198 */
199static struct acpi_vendor_uuid hp_ccsr_uuid = {
200 .subtype = 2,
201 .data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a,
202 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad },
203};
204
205static int vendor_resource_matches(struct pnp_dev *dev,
206 struct acpi_resource_vendor_typed *vendor,
207 struct acpi_vendor_uuid *match,
208 int expected_len)
209{
210 int uuid_len = sizeof(vendor->uuid);
211 u8 uuid_subtype = vendor->uuid_subtype;
212 u8 *uuid = vendor->uuid;
213 int actual_len;
214
215 /* byte_length includes uuid_subtype and uuid */
216 actual_len = vendor->byte_length - uuid_len - 1;
217
218 if (uuid_subtype == match->subtype &&
219 uuid_len == sizeof(match->data) &&
220 memcmp(uuid, match->data, uuid_len) == 0) {
221 if (expected_len && expected_len != actual_len) {
222 dev_err(&dev->dev, "wrong vendor descriptor size; "
223 "expected %d, found %d bytes\n",
224 expected_len, actual_len);
225 return 0;
226 }
227
228 return 1;
229 }
230
231 return 0;
232}
233
234static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev,
235 struct acpi_resource_vendor_typed *vendor)
236{
237 if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, 16)) {
238 u64 start, length;
239
240 memcpy(&start, vendor->byte_data, sizeof(start));
241 memcpy(&length, vendor->byte_data + 8, sizeof(length));
242
243 pnp_add_mem_resource(dev, start, start + length - 1, 0);
244 }
245}
246
188static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, 247static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
189 u64 start, u64 len, 248 u64 start, u64 len,
190 int write_protect) 249 int write_protect)
@@ -235,6 +294,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
235 struct acpi_resource_dma *dma; 294 struct acpi_resource_dma *dma;
236 struct acpi_resource_io *io; 295 struct acpi_resource_io *io;
237 struct acpi_resource_fixed_io *fixed_io; 296 struct acpi_resource_fixed_io *fixed_io;
297 struct acpi_resource_vendor_typed *vendor_typed;
238 struct acpi_resource_memory24 *memory24; 298 struct acpi_resource_memory24 *memory24;
239 struct acpi_resource_memory32 *memory32; 299 struct acpi_resource_memory32 *memory32;
240 struct acpi_resource_fixed_memory32 *fixed_memory32; 300 struct acpi_resource_fixed_memory32 *fixed_memory32;
@@ -248,24 +308,39 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
248 * _CRS, but some firmware violates this, so parse them all. 308 * _CRS, but some firmware violates this, so parse them all.
249 */ 309 */
250 irq = &res->data.irq; 310 irq = &res->data.irq;
251 for (i = 0; i < irq->interrupt_count; i++) { 311 if (irq->interrupt_count == 0)
252 pnpacpi_parse_allocated_irqresource(dev, 312 pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
253 irq->interrupts[i], 313 else {
254 irq->triggering, 314 for (i = 0; i < irq->interrupt_count; i++) {
255 irq->polarity, 315 pnpacpi_parse_allocated_irqresource(dev,
256 irq->sharable); 316 irq->interrupts[i],
317 irq->triggering,
318 irq->polarity,
319 irq->sharable);
320 }
321
322 /*
323 * The IRQ encoder puts a single interrupt in each
324 * descriptor, so if a _CRS descriptor has more than
325 * one interrupt, we won't be able to re-encode it.
326 */
327 if (pnp_can_write(dev) && irq->interrupt_count > 1) {
328 dev_warn(&dev->dev, "multiple interrupts in "
329 "_CRS descriptor; configuration can't "
330 "be changed\n");
331 dev->capabilities &= ~PNP_WRITE;
332 }
257 } 333 }
258 break; 334 break;
259 335
260 case ACPI_RESOURCE_TYPE_DMA: 336 case ACPI_RESOURCE_TYPE_DMA:
261 dma = &res->data.dma; 337 dma = &res->data.dma;
262 if (dma->channel_count > 0) { 338 if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
263 flags = dma_flags(dma->type, dma->bus_master, 339 flags = dma_flags(dma->type, dma->bus_master,
264 dma->transfer); 340 dma->transfer);
265 if (dma->channels[0] == (u8) -1) 341 else
266 flags |= IORESOURCE_DISABLED; 342 flags = IORESOURCE_DISABLED;
267 pnp_add_dma_resource(dev, dma->channels[0], flags); 343 pnp_add_dma_resource(dev, dma->channels[0], flags);
268 }
269 break; 344 break;
270 345
271 case ACPI_RESOURCE_TYPE_IO: 346 case ACPI_RESOURCE_TYPE_IO:
@@ -289,6 +364,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
289 break; 364 break;
290 365
291 case ACPI_RESOURCE_TYPE_VENDOR: 366 case ACPI_RESOURCE_TYPE_VENDOR:
367 vendor_typed = &res->data.vendor_typed;
368 pnpacpi_parse_allocated_vendor(dev, vendor_typed);
292 break; 369 break;
293 370
294 case ACPI_RESOURCE_TYPE_END_TAG: 371 case ACPI_RESOURCE_TYPE_END_TAG:
@@ -331,12 +408,29 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
331 if (extended_irq->producer_consumer == ACPI_PRODUCER) 408 if (extended_irq->producer_consumer == ACPI_PRODUCER)
332 return AE_OK; 409 return AE_OK;
333 410
334 for (i = 0; i < extended_irq->interrupt_count; i++) { 411 if (extended_irq->interrupt_count == 0)
335 pnpacpi_parse_allocated_irqresource(dev, 412 pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
336 extended_irq->interrupts[i], 413 else {
337 extended_irq->triggering, 414 for (i = 0; i < extended_irq->interrupt_count; i++) {
338 extended_irq->polarity, 415 pnpacpi_parse_allocated_irqresource(dev,
339 extended_irq->sharable); 416 extended_irq->interrupts[i],
417 extended_irq->triggering,
418 extended_irq->polarity,
419 extended_irq->sharable);
420 }
421
422 /*
423 * The IRQ encoder puts a single interrupt in each
424 * descriptor, so if a _CRS descriptor has more than
425 * one interrupt, we won't be able to re-encode it.
426 */
427 if (pnp_can_write(dev) &&
428 extended_irq->interrupt_count > 1) {
429 dev_warn(&dev->dev, "multiple interrupts in "
430 "_CRS descriptor; configuration can't "
431 "be changed\n");
432 dev->capabilities &= ~PNP_WRITE;
433 }
340 } 434 }
341 break; 435 break;
342 436
@@ -373,179 +467,147 @@ int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
373} 467}
374 468
375static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, 469static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
376 struct pnp_option *option, 470 unsigned int option_flags,
377 struct acpi_resource_dma *p) 471 struct acpi_resource_dma *p)
378{ 472{
379 int i; 473 int i;
380 struct pnp_dma *dma; 474 unsigned char map = 0, flags;
381 475
382 if (p->channel_count == 0) 476 if (p->channel_count == 0)
383 return; 477 return;
384 dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
385 if (!dma)
386 return;
387 478
388 for (i = 0; i < p->channel_count; i++) 479 for (i = 0; i < p->channel_count; i++)
389 dma->map |= 1 << p->channels[i]; 480 map |= 1 << p->channels[i];
390
391 dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
392 481
393 pnp_register_dma_resource(dev, option, dma); 482 flags = dma_flags(p->type, p->bus_master, p->transfer);
483 pnp_register_dma_resource(dev, option_flags, map, flags);
394} 484}
395 485
396static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, 486static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
397 struct pnp_option *option, 487 unsigned int option_flags,
398 struct acpi_resource_irq *p) 488 struct acpi_resource_irq *p)
399{ 489{
400 int i; 490 int i;
401 struct pnp_irq *irq; 491 pnp_irq_mask_t map;
492 unsigned char flags;
402 493
403 if (p->interrupt_count == 0) 494 if (p->interrupt_count == 0)
404 return; 495 return;
405 irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
406 if (!irq)
407 return;
408 496
497 bitmap_zero(map.bits, PNP_IRQ_NR);
409 for (i = 0; i < p->interrupt_count; i++) 498 for (i = 0; i < p->interrupt_count; i++)
410 if (p->interrupts[i]) 499 if (p->interrupts[i])
411 __set_bit(p->interrupts[i], irq->map); 500 __set_bit(p->interrupts[i], map.bits);
412 irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
413 501
414 pnp_register_irq_resource(dev, option, irq); 502 flags = irq_flags(p->triggering, p->polarity, p->sharable);
503 pnp_register_irq_resource(dev, option_flags, &map, flags);
415} 504}
416 505
417static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, 506static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
418 struct pnp_option *option, 507 unsigned int option_flags,
419 struct acpi_resource_extended_irq *p) 508 struct acpi_resource_extended_irq *p)
420{ 509{
421 int i; 510 int i;
422 struct pnp_irq *irq; 511 pnp_irq_mask_t map;
512 unsigned char flags;
423 513
424 if (p->interrupt_count == 0) 514 if (p->interrupt_count == 0)
425 return; 515 return;
426 irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
427 if (!irq)
428 return;
429 516
430 for (i = 0; i < p->interrupt_count; i++) 517 bitmap_zero(map.bits, PNP_IRQ_NR);
431 if (p->interrupts[i]) 518 for (i = 0; i < p->interrupt_count; i++) {
432 __set_bit(p->interrupts[i], irq->map); 519 if (p->interrupts[i]) {
433 irq->flags = irq_flags(p->triggering, p->polarity, p->sharable); 520 if (p->interrupts[i] < PNP_IRQ_NR)
521 __set_bit(p->interrupts[i], map.bits);
522 else
523 dev_err(&dev->dev, "ignoring IRQ %d option "
524 "(too large for %d entry bitmap)\n",
525 p->interrupts[i], PNP_IRQ_NR);
526 }
527 }
434 528
435 pnp_register_irq_resource(dev, option, irq); 529 flags = irq_flags(p->triggering, p->polarity, p->sharable);
530 pnp_register_irq_resource(dev, option_flags, &map, flags);
436} 531}
437 532
438static __init void pnpacpi_parse_port_option(struct pnp_dev *dev, 533static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
439 struct pnp_option *option, 534 unsigned int option_flags,
440 struct acpi_resource_io *io) 535 struct acpi_resource_io *io)
441{ 536{
442 struct pnp_port *port; 537 unsigned char flags = 0;
443 538
444 if (io->address_length == 0) 539 if (io->address_length == 0)
445 return; 540 return;
446 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 541
447 if (!port) 542 if (io->io_decode == ACPI_DECODE_16)
448 return; 543 flags = IORESOURCE_IO_16BIT_ADDR;
449 port->min = io->minimum; 544 pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum,
450 port->max = io->maximum; 545 io->alignment, io->address_length, flags);
451 port->align = io->alignment;
452 port->size = io->address_length;
453 port->flags = ACPI_DECODE_16 == io->io_decode ?
454 PNP_PORT_FLAG_16BITADDR : 0;
455 pnp_register_port_resource(dev, option, port);
456} 546}
457 547
458static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev, 548static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
459 struct pnp_option *option, 549 unsigned int option_flags,
460 struct acpi_resource_fixed_io *io) 550 struct acpi_resource_fixed_io *io)
461{ 551{
462 struct pnp_port *port;
463
464 if (io->address_length == 0) 552 if (io->address_length == 0)
465 return; 553 return;
466 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 554
467 if (!port) 555 pnp_register_port_resource(dev, option_flags, io->address, io->address,
468 return; 556 0, io->address_length, IORESOURCE_IO_FIXED);
469 port->min = port->max = io->address;
470 port->size = io->address_length;
471 port->align = 0;
472 port->flags = PNP_PORT_FLAG_FIXED;
473 pnp_register_port_resource(dev, option, port);
474} 557}
475 558
476static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev, 559static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
477 struct pnp_option *option, 560 unsigned int option_flags,
478 struct acpi_resource_memory24 *p) 561 struct acpi_resource_memory24 *p)
479{ 562{
480 struct pnp_mem *mem; 563 unsigned char flags = 0;
481 564
482 if (p->address_length == 0) 565 if (p->address_length == 0)
483 return; 566 return;
484 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
485 if (!mem)
486 return;
487 mem->min = p->minimum;
488 mem->max = p->maximum;
489 mem->align = p->alignment;
490 mem->size = p->address_length;
491
492 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
493 IORESOURCE_MEM_WRITEABLE : 0;
494 567
495 pnp_register_mem_resource(dev, option, mem); 568 if (p->write_protect == ACPI_READ_WRITE_MEMORY)
569 flags = IORESOURCE_MEM_WRITEABLE;
570 pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
571 p->alignment, p->address_length, flags);
496} 572}
497 573
498static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev, 574static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
499 struct pnp_option *option, 575 unsigned int option_flags,
500 struct acpi_resource_memory32 *p) 576 struct acpi_resource_memory32 *p)
501{ 577{
502 struct pnp_mem *mem; 578 unsigned char flags = 0;
503 579
504 if (p->address_length == 0) 580 if (p->address_length == 0)
505 return; 581 return;
506 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
507 if (!mem)
508 return;
509 mem->min = p->minimum;
510 mem->max = p->maximum;
511 mem->align = p->alignment;
512 mem->size = p->address_length;
513
514 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
515 IORESOURCE_MEM_WRITEABLE : 0;
516 582
517 pnp_register_mem_resource(dev, option, mem); 583 if (p->write_protect == ACPI_READ_WRITE_MEMORY)
584 flags = IORESOURCE_MEM_WRITEABLE;
585 pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
586 p->alignment, p->address_length, flags);
518} 587}
519 588
520static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev, 589static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
521 struct pnp_option *option, 590 unsigned int option_flags,
522 struct acpi_resource_fixed_memory32 *p) 591 struct acpi_resource_fixed_memory32 *p)
523{ 592{
524 struct pnp_mem *mem; 593 unsigned char flags = 0;
525 594
526 if (p->address_length == 0) 595 if (p->address_length == 0)
527 return; 596 return;
528 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
529 if (!mem)
530 return;
531 mem->min = mem->max = p->address;
532 mem->size = p->address_length;
533 mem->align = 0;
534
535 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
536 IORESOURCE_MEM_WRITEABLE : 0;
537 597
538 pnp_register_mem_resource(dev, option, mem); 598 if (p->write_protect == ACPI_READ_WRITE_MEMORY)
599 flags = IORESOURCE_MEM_WRITEABLE;
600 pnp_register_mem_resource(dev, option_flags, p->address, p->address,
601 0, p->address_length, flags);
539} 602}
540 603
541static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, 604static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
542 struct pnp_option *option, 605 unsigned int option_flags,
543 struct acpi_resource *r) 606 struct acpi_resource *r)
544{ 607{
545 struct acpi_resource_address64 addr, *p = &addr; 608 struct acpi_resource_address64 addr, *p = &addr;
546 acpi_status status; 609 acpi_status status;
547 struct pnp_mem *mem; 610 unsigned char flags = 0;
548 struct pnp_port *port;
549 611
550 status = acpi_resource_to_address64(r, p); 612 status = acpi_resource_to_address64(r, p);
551 if (!ACPI_SUCCESS(status)) { 613 if (!ACPI_SUCCESS(status)) {
@@ -558,49 +620,37 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
558 return; 620 return;
559 621
560 if (p->resource_type == ACPI_MEMORY_RANGE) { 622 if (p->resource_type == ACPI_MEMORY_RANGE) {
561 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 623 if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
562 if (!mem) 624 flags = IORESOURCE_MEM_WRITEABLE;
563 return; 625 pnp_register_mem_resource(dev, option_flags, p->minimum,
564 mem->min = mem->max = p->minimum; 626 p->minimum, 0, p->address_length,
565 mem->size = p->address_length; 627 flags);
566 mem->align = 0; 628 } else if (p->resource_type == ACPI_IO_RANGE)
567 mem->flags = (p->info.mem.write_protect == 629 pnp_register_port_resource(dev, option_flags, p->minimum,
568 ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE 630 p->minimum, 0, p->address_length,
569 : 0; 631 IORESOURCE_IO_FIXED);
570 pnp_register_mem_resource(dev, option, mem);
571 } else if (p->resource_type == ACPI_IO_RANGE) {
572 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
573 if (!port)
574 return;
575 port->min = port->max = p->minimum;
576 port->size = p->address_length;
577 port->align = 0;
578 port->flags = PNP_PORT_FLAG_FIXED;
579 pnp_register_port_resource(dev, option, port);
580 }
581} 632}
582 633
583struct acpipnp_parse_option_s { 634struct acpipnp_parse_option_s {
584 struct pnp_option *option;
585 struct pnp_option *option_independent;
586 struct pnp_dev *dev; 635 struct pnp_dev *dev;
636 unsigned int option_flags;
587}; 637};
588 638
589static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, 639static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
590 void *data) 640 void *data)
591{ 641{
592 int priority = 0; 642 int priority;
593 struct acpipnp_parse_option_s *parse_data = data; 643 struct acpipnp_parse_option_s *parse_data = data;
594 struct pnp_dev *dev = parse_data->dev; 644 struct pnp_dev *dev = parse_data->dev;
595 struct pnp_option *option = parse_data->option; 645 unsigned int option_flags = parse_data->option_flags;
596 646
597 switch (res->type) { 647 switch (res->type) {
598 case ACPI_RESOURCE_TYPE_IRQ: 648 case ACPI_RESOURCE_TYPE_IRQ:
599 pnpacpi_parse_irq_option(dev, option, &res->data.irq); 649 pnpacpi_parse_irq_option(dev, option_flags, &res->data.irq);
600 break; 650 break;
601 651
602 case ACPI_RESOURCE_TYPE_DMA: 652 case ACPI_RESOURCE_TYPE_DMA:
603 pnpacpi_parse_dma_option(dev, option, &res->data.dma); 653 pnpacpi_parse_dma_option(dev, option_flags, &res->data.dma);
604 break; 654 break;
605 655
606 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 656 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -620,31 +670,19 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
620 priority = PNP_RES_PRIORITY_INVALID; 670 priority = PNP_RES_PRIORITY_INVALID;
621 break; 671 break;
622 } 672 }
623 /* TBD: Consider performance/robustness bits */ 673 parse_data->option_flags = pnp_new_dependent_set(dev, priority);
624 option = pnp_register_dependent_option(dev, priority);
625 if (!option)
626 return AE_ERROR;
627 parse_data->option = option;
628 break; 674 break;
629 675
630 case ACPI_RESOURCE_TYPE_END_DEPENDENT: 676 case ACPI_RESOURCE_TYPE_END_DEPENDENT:
631 /*only one EndDependentFn is allowed */ 677 parse_data->option_flags = 0;
632 if (!parse_data->option_independent) {
633 dev_warn(&dev->dev, "more than one EndDependentFn "
634 "in _PRS\n");
635 return AE_ERROR;
636 }
637 parse_data->option = parse_data->option_independent;
638 parse_data->option_independent = NULL;
639 dev_dbg(&dev->dev, "end dependent options\n");
640 break; 678 break;
641 679
642 case ACPI_RESOURCE_TYPE_IO: 680 case ACPI_RESOURCE_TYPE_IO:
643 pnpacpi_parse_port_option(dev, option, &res->data.io); 681 pnpacpi_parse_port_option(dev, option_flags, &res->data.io);
644 break; 682 break;
645 683
646 case ACPI_RESOURCE_TYPE_FIXED_IO: 684 case ACPI_RESOURCE_TYPE_FIXED_IO:
647 pnpacpi_parse_fixed_port_option(dev, option, 685 pnpacpi_parse_fixed_port_option(dev, option_flags,
648 &res->data.fixed_io); 686 &res->data.fixed_io);
649 break; 687 break;
650 688
@@ -653,29 +691,31 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
653 break; 691 break;
654 692
655 case ACPI_RESOURCE_TYPE_MEMORY24: 693 case ACPI_RESOURCE_TYPE_MEMORY24:
656 pnpacpi_parse_mem24_option(dev, option, &res->data.memory24); 694 pnpacpi_parse_mem24_option(dev, option_flags,
695 &res->data.memory24);
657 break; 696 break;
658 697
659 case ACPI_RESOURCE_TYPE_MEMORY32: 698 case ACPI_RESOURCE_TYPE_MEMORY32:
660 pnpacpi_parse_mem32_option(dev, option, &res->data.memory32); 699 pnpacpi_parse_mem32_option(dev, option_flags,
700 &res->data.memory32);
661 break; 701 break;
662 702
663 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 703 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
664 pnpacpi_parse_fixed_mem32_option(dev, option, 704 pnpacpi_parse_fixed_mem32_option(dev, option_flags,
665 &res->data.fixed_memory32); 705 &res->data.fixed_memory32);
666 break; 706 break;
667 707
668 case ACPI_RESOURCE_TYPE_ADDRESS16: 708 case ACPI_RESOURCE_TYPE_ADDRESS16:
669 case ACPI_RESOURCE_TYPE_ADDRESS32: 709 case ACPI_RESOURCE_TYPE_ADDRESS32:
670 case ACPI_RESOURCE_TYPE_ADDRESS64: 710 case ACPI_RESOURCE_TYPE_ADDRESS64:
671 pnpacpi_parse_address_option(dev, option, res); 711 pnpacpi_parse_address_option(dev, option_flags, res);
672 break; 712 break;
673 713
674 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 714 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
675 break; 715 break;
676 716
677 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 717 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
678 pnpacpi_parse_ext_irq_option(dev, option, 718 pnpacpi_parse_ext_irq_option(dev, option_flags,
679 &res->data.extended_irq); 719 &res->data.extended_irq);
680 break; 720 break;
681 721
@@ -699,12 +739,9 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
699 739
700 dev_dbg(&dev->dev, "parse resource options\n"); 740 dev_dbg(&dev->dev, "parse resource options\n");
701 741
702 parse_data.option = pnp_register_independent_option(dev);
703 if (!parse_data.option)
704 return -ENOMEM;
705
706 parse_data.option_independent = parse_data.option;
707 parse_data.dev = dev; 742 parse_data.dev = dev;
743 parse_data.option_flags = 0;
744
708 status = acpi_walk_resources(handle, METHOD_NAME__PRS, 745 status = acpi_walk_resources(handle, METHOD_NAME__PRS,
709 pnpacpi_option_resource, &parse_data); 746 pnpacpi_option_resource, &parse_data);
710 747
@@ -806,6 +843,13 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
806 struct acpi_resource_irq *irq = &resource->data.irq; 843 struct acpi_resource_irq *irq = &resource->data.irq;
807 int triggering, polarity, shareable; 844 int triggering, polarity, shareable;
808 845
846 if (!pnp_resource_enabled(p)) {
847 irq->interrupt_count = 0;
848 dev_dbg(&dev->dev, " encode irq (%s)\n",
849 p ? "disabled" : "missing");
850 return;
851 }
852
809 decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); 853 decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
810 irq->triggering = triggering; 854 irq->triggering = triggering;
811 irq->polarity = polarity; 855 irq->polarity = polarity;
@@ -828,6 +872,13 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
828 struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; 872 struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
829 int triggering, polarity, shareable; 873 int triggering, polarity, shareable;
830 874
875 if (!pnp_resource_enabled(p)) {
876 extended_irq->interrupt_count = 0;
877 dev_dbg(&dev->dev, " encode extended irq (%s)\n",
878 p ? "disabled" : "missing");
879 return;
880 }
881
831 decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); 882 decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
832 extended_irq->producer_consumer = ACPI_CONSUMER; 883 extended_irq->producer_consumer = ACPI_CONSUMER;
833 extended_irq->triggering = triggering; 884 extended_irq->triggering = triggering;
@@ -848,6 +899,13 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev,
848{ 899{
849 struct acpi_resource_dma *dma = &resource->data.dma; 900 struct acpi_resource_dma *dma = &resource->data.dma;
850 901
902 if (!pnp_resource_enabled(p)) {
903 dma->channel_count = 0;
904 dev_dbg(&dev->dev, " encode dma (%s)\n",
905 p ? "disabled" : "missing");
906 return;
907 }
908
851 /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ 909 /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
852 switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { 910 switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
853 case IORESOURCE_DMA_TYPEA: 911 case IORESOURCE_DMA_TYPEA:
@@ -889,17 +947,21 @@ static void pnpacpi_encode_io(struct pnp_dev *dev,
889{ 947{
890 struct acpi_resource_io *io = &resource->data.io; 948 struct acpi_resource_io *io = &resource->data.io;
891 949
892 /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ 950 if (pnp_resource_enabled(p)) {
893 io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ? 951 /* Note: pnp_assign_port copies pnp_port->flags into p->flags */
894 ACPI_DECODE_16 : ACPI_DECODE_10; 952 io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ?
895 io->minimum = p->start; 953 ACPI_DECODE_16 : ACPI_DECODE_10;
896 io->maximum = p->end; 954 io->minimum = p->start;
897 io->alignment = 0; /* Correct? */ 955 io->maximum = p->end;
898 io->address_length = p->end - p->start + 1; 956 io->alignment = 0; /* Correct? */
899 957 io->address_length = p->end - p->start + 1;
900 dev_dbg(&dev->dev, " encode io %#llx-%#llx decode %#x\n", 958 } else {
901 (unsigned long long) p->start, (unsigned long long) p->end, 959 io->minimum = 0;
902 io->io_decode); 960 io->address_length = 0;
961 }
962
963 dev_dbg(&dev->dev, " encode io %#x-%#x decode %#x\n", io->minimum,
964 io->minimum + io->address_length - 1, io->io_decode);
903} 965}
904 966
905static void pnpacpi_encode_fixed_io(struct pnp_dev *dev, 967static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
@@ -908,11 +970,16 @@ static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
908{ 970{
909 struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io; 971 struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;
910 972
911 fixed_io->address = p->start; 973 if (pnp_resource_enabled(p)) {
912 fixed_io->address_length = p->end - p->start + 1; 974 fixed_io->address = p->start;
975 fixed_io->address_length = p->end - p->start + 1;
976 } else {
977 fixed_io->address = 0;
978 fixed_io->address_length = 0;
979 }
913 980
914 dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n", 981 dev_dbg(&dev->dev, " encode fixed_io %#x-%#x\n", fixed_io->address,
915 (unsigned long long) p->start, (unsigned long long) p->end); 982 fixed_io->address + fixed_io->address_length - 1);
916} 983}
917 984
918static void pnpacpi_encode_mem24(struct pnp_dev *dev, 985static void pnpacpi_encode_mem24(struct pnp_dev *dev,
@@ -921,17 +988,22 @@ static void pnpacpi_encode_mem24(struct pnp_dev *dev,
921{ 988{
922 struct acpi_resource_memory24 *memory24 = &resource->data.memory24; 989 struct acpi_resource_memory24 *memory24 = &resource->data.memory24;
923 990
924 /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ 991 if (pnp_resource_enabled(p)) {
925 memory24->write_protect = 992 /* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */
926 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 993 memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
927 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 994 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
928 memory24->minimum = p->start; 995 memory24->minimum = p->start;
929 memory24->maximum = p->end; 996 memory24->maximum = p->end;
930 memory24->alignment = 0; 997 memory24->alignment = 0;
931 memory24->address_length = p->end - p->start + 1; 998 memory24->address_length = p->end - p->start + 1;
932 999 } else {
933 dev_dbg(&dev->dev, " encode mem24 %#llx-%#llx write_protect %#x\n", 1000 memory24->minimum = 0;
934 (unsigned long long) p->start, (unsigned long long) p->end, 1001 memory24->address_length = 0;
1002 }
1003
1004 dev_dbg(&dev->dev, " encode mem24 %#x-%#x write_protect %#x\n",
1005 memory24->minimum,
1006 memory24->minimum + memory24->address_length - 1,
935 memory24->write_protect); 1007 memory24->write_protect);
936} 1008}
937 1009
@@ -941,16 +1013,21 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev,
941{ 1013{
942 struct acpi_resource_memory32 *memory32 = &resource->data.memory32; 1014 struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
943 1015
944 memory32->write_protect = 1016 if (pnp_resource_enabled(p)) {
945 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 1017 memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
946 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 1018 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
947 memory32->minimum = p->start; 1019 memory32->minimum = p->start;
948 memory32->maximum = p->end; 1020 memory32->maximum = p->end;
949 memory32->alignment = 0; 1021 memory32->alignment = 0;
950 memory32->address_length = p->end - p->start + 1; 1022 memory32->address_length = p->end - p->start + 1;
1023 } else {
1024 memory32->minimum = 0;
1025 memory32->alignment = 0;
1026 }
951 1027
952 dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx write_protect %#x\n", 1028 dev_dbg(&dev->dev, " encode mem32 %#x-%#x write_protect %#x\n",
953 (unsigned long long) p->start, (unsigned long long) p->end, 1029 memory32->minimum,
1030 memory32->minimum + memory32->address_length - 1,
954 memory32->write_protect); 1031 memory32->write_protect);
955} 1032}
956 1033
@@ -960,15 +1037,20 @@ static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
960{ 1037{
961 struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32; 1038 struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;
962 1039
963 fixed_memory32->write_protect = 1040 if (pnp_resource_enabled(p)) {
964 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 1041 fixed_memory32->write_protect =
965 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 1042 p->flags & IORESOURCE_MEM_WRITEABLE ?
966 fixed_memory32->address = p->start; 1043 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
967 fixed_memory32->address_length = p->end - p->start + 1; 1044 fixed_memory32->address = p->start;
1045 fixed_memory32->address_length = p->end - p->start + 1;
1046 } else {
1047 fixed_memory32->address = 0;
1048 fixed_memory32->address_length = 0;
1049 }
968 1050
969 dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx " 1051 dev_dbg(&dev->dev, " encode fixed_mem32 %#x-%#x write_protect %#x\n",
970 "write_protect %#x\n", 1052 fixed_memory32->address,
971 (unsigned long long) p->start, (unsigned long long) p->end, 1053 fixed_memory32->address + fixed_memory32->address_length - 1,
972 fixed_memory32->write_protect); 1054 fixed_memory32->write_protect);
973} 1055}
974 1056
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 5ff9a4c0447e..ca567671379e 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -216,137 +216,116 @@ len_err:
216 216
217static __init void pnpbios_parse_mem_option(struct pnp_dev *dev, 217static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
218 unsigned char *p, int size, 218 unsigned char *p, int size,
219 struct pnp_option *option) 219 unsigned int option_flags)
220{ 220{
221 struct pnp_mem *mem; 221 resource_size_t min, max, align, len;
222 222 unsigned char flags;
223 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 223
224 if (!mem) 224 min = ((p[5] << 8) | p[4]) << 8;
225 return; 225 max = ((p[7] << 8) | p[6]) << 8;
226 mem->min = ((p[5] << 8) | p[4]) << 8; 226 align = (p[9] << 8) | p[8];
227 mem->max = ((p[7] << 8) | p[6]) << 8; 227 len = ((p[11] << 8) | p[10]) << 8;
228 mem->align = (p[9] << 8) | p[8]; 228 flags = p[3];
229 mem->size = ((p[11] << 8) | p[10]) << 8; 229 pnp_register_mem_resource(dev, option_flags, min, max, align, len,
230 mem->flags = p[3]; 230 flags);
231 pnp_register_mem_resource(dev, option, mem);
232} 231}
233 232
234static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev, 233static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
235 unsigned char *p, int size, 234 unsigned char *p, int size,
236 struct pnp_option *option) 235 unsigned int option_flags)
237{ 236{
238 struct pnp_mem *mem; 237 resource_size_t min, max, align, len;
239 238 unsigned char flags;
240 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 239
241 if (!mem) 240 min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
242 return; 241 max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
243 mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; 242 align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
244 mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; 243 len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
245 mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; 244 flags = p[3];
246 mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; 245 pnp_register_mem_resource(dev, option_flags, min, max, align, len,
247 mem->flags = p[3]; 246 flags);
248 pnp_register_mem_resource(dev, option, mem);
249} 247}
250 248
251static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev, 249static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
252 unsigned char *p, int size, 250 unsigned char *p, int size,
253 struct pnp_option *option) 251 unsigned int option_flags)
254{ 252{
255 struct pnp_mem *mem; 253 resource_size_t base, len;
256 254 unsigned char flags;
257 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); 255
258 if (!mem) 256 base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
259 return; 257 len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
260 mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; 258 flags = p[3];
261 mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; 259 pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
262 mem->align = 0;
263 mem->flags = p[3];
264 pnp_register_mem_resource(dev, option, mem);
265} 260}
266 261
267static __init void pnpbios_parse_irq_option(struct pnp_dev *dev, 262static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
268 unsigned char *p, int size, 263 unsigned char *p, int size,
269 struct pnp_option *option) 264 unsigned int option_flags)
270{ 265{
271 struct pnp_irq *irq;
272 unsigned long bits; 266 unsigned long bits;
267 pnp_irq_mask_t map;
268 unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
273 269
274 irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
275 if (!irq)
276 return;
277 bits = (p[2] << 8) | p[1]; 270 bits = (p[2] << 8) | p[1];
278 bitmap_copy(irq->map, &bits, 16); 271
272 bitmap_zero(map.bits, PNP_IRQ_NR);
273 bitmap_copy(map.bits, &bits, 16);
274
279 if (size > 2) 275 if (size > 2)
280 irq->flags = p[3]; 276 flags = p[3];
281 else 277
282 irq->flags = IORESOURCE_IRQ_HIGHEDGE; 278 pnp_register_irq_resource(dev, option_flags, &map, flags);
283 pnp_register_irq_resource(dev, option, irq);
284} 279}
285 280
286static __init void pnpbios_parse_dma_option(struct pnp_dev *dev, 281static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
287 unsigned char *p, int size, 282 unsigned char *p, int size,
288 struct pnp_option *option) 283 unsigned int option_flags)
289{ 284{
290 struct pnp_dma *dma; 285 pnp_register_dma_resource(dev, option_flags, p[1], p[2]);
291
292 dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
293 if (!dma)
294 return;
295 dma->map = p[1];
296 dma->flags = p[2];
297 pnp_register_dma_resource(dev, option, dma);
298} 286}
299 287
300static __init void pnpbios_parse_port_option(struct pnp_dev *dev, 288static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
301 unsigned char *p, int size, 289 unsigned char *p, int size,
302 struct pnp_option *option) 290 unsigned int option_flags)
303{ 291{
304 struct pnp_port *port; 292 resource_size_t min, max, align, len;
305 293 unsigned char flags;
306 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 294
307 if (!port) 295 min = (p[3] << 8) | p[2];
308 return; 296 max = (p[5] << 8) | p[4];
309 port->min = (p[3] << 8) | p[2]; 297 align = p[6];
310 port->max = (p[5] << 8) | p[4]; 298 len = p[7];
311 port->align = p[6]; 299 flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
312 port->size = p[7]; 300 pnp_register_port_resource(dev, option_flags, min, max, align, len,
313 port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0; 301 flags);
314 pnp_register_port_resource(dev, option, port);
315} 302}
316 303
317static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev, 304static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
318 unsigned char *p, int size, 305 unsigned char *p, int size,
319 struct pnp_option *option) 306 unsigned int option_flags)
320{ 307{
321 struct pnp_port *port; 308 resource_size_t base, len;
322 309
323 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 310 base = (p[2] << 8) | p[1];
324 if (!port) 311 len = p[3];
325 return; 312 pnp_register_port_resource(dev, option_flags, base, base, 0, len,
326 port->min = port->max = (p[2] << 8) | p[1]; 313 IORESOURCE_IO_FIXED);
327 port->size = p[3];
328 port->align = 0;
329 port->flags = PNP_PORT_FLAG_FIXED;
330 pnp_register_port_resource(dev, option, port);
331} 314}
332 315
333static __init unsigned char * 316static __init unsigned char *
334pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, 317pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
335 struct pnp_dev *dev) 318 struct pnp_dev *dev)
336{ 319{
337 unsigned int len, tag; 320 unsigned int len, tag;
338 int priority = 0; 321 int priority;
339 struct pnp_option *option, *option_independent; 322 unsigned int option_flags;
340 323
341 if (!p) 324 if (!p)
342 return NULL; 325 return NULL;
343 326
344 dev_dbg(&dev->dev, "parse resource options\n"); 327 dev_dbg(&dev->dev, "parse resource options\n");
345 328 option_flags = 0;
346 option_independent = option = pnp_register_independent_option(dev);
347 if (!option)
348 return NULL;
349
350 while ((char *)p < (char *)end) { 329 while ((char *)p < (char *)end) {
351 330
352 /* determine the type of tag */ 331 /* determine the type of tag */
@@ -363,37 +342,38 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
363 case LARGE_TAG_MEM: 342 case LARGE_TAG_MEM:
364 if (len != 9) 343 if (len != 9)
365 goto len_err; 344 goto len_err;
366 pnpbios_parse_mem_option(dev, p, len, option); 345 pnpbios_parse_mem_option(dev, p, len, option_flags);
367 break; 346 break;
368 347
369 case LARGE_TAG_MEM32: 348 case LARGE_TAG_MEM32:
370 if (len != 17) 349 if (len != 17)
371 goto len_err; 350 goto len_err;
372 pnpbios_parse_mem32_option(dev, p, len, option); 351 pnpbios_parse_mem32_option(dev, p, len, option_flags);
373 break; 352 break;
374 353
375 case LARGE_TAG_FIXEDMEM32: 354 case LARGE_TAG_FIXEDMEM32:
376 if (len != 9) 355 if (len != 9)
377 goto len_err; 356 goto len_err;
378 pnpbios_parse_fixed_mem32_option(dev, p, len, option); 357 pnpbios_parse_fixed_mem32_option(dev, p, len,
358 option_flags);
379 break; 359 break;
380 360
381 case SMALL_TAG_IRQ: 361 case SMALL_TAG_IRQ:
382 if (len < 2 || len > 3) 362 if (len < 2 || len > 3)
383 goto len_err; 363 goto len_err;
384 pnpbios_parse_irq_option(dev, p, len, option); 364 pnpbios_parse_irq_option(dev, p, len, option_flags);
385 break; 365 break;
386 366
387 case SMALL_TAG_DMA: 367 case SMALL_TAG_DMA:
388 if (len != 2) 368 if (len != 2)
389 goto len_err; 369 goto len_err;
390 pnpbios_parse_dma_option(dev, p, len, option); 370 pnpbios_parse_dma_option(dev, p, len, option_flags);
391 break; 371 break;
392 372
393 case SMALL_TAG_PORT: 373 case SMALL_TAG_PORT:
394 if (len != 7) 374 if (len != 7)
395 goto len_err; 375 goto len_err;
396 pnpbios_parse_port_option(dev, p, len, option); 376 pnpbios_parse_port_option(dev, p, len, option_flags);
397 break; 377 break;
398 378
399 case SMALL_TAG_VENDOR: 379 case SMALL_TAG_VENDOR:
@@ -403,28 +383,23 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
403 case SMALL_TAG_FIXEDPORT: 383 case SMALL_TAG_FIXEDPORT:
404 if (len != 3) 384 if (len != 3)
405 goto len_err; 385 goto len_err;
406 pnpbios_parse_fixed_port_option(dev, p, len, option); 386 pnpbios_parse_fixed_port_option(dev, p, len,
387 option_flags);
407 break; 388 break;
408 389
409 case SMALL_TAG_STARTDEP: 390 case SMALL_TAG_STARTDEP:
410 if (len > 1) 391 if (len > 1)
411 goto len_err; 392 goto len_err;
412 priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE; 393 priority = PNP_RES_PRIORITY_ACCEPTABLE;
413 if (len > 0) 394 if (len > 0)
414 priority = 0x100 | p[1]; 395 priority = p[1];
415 option = pnp_register_dependent_option(dev, priority); 396 option_flags = pnp_new_dependent_set(dev, priority);
416 if (!option)
417 return NULL;
418 break; 397 break;
419 398
420 case SMALL_TAG_ENDDEP: 399 case SMALL_TAG_ENDDEP:
421 if (len != 0) 400 if (len != 0)
422 goto len_err; 401 goto len_err;
423 if (option_independent == option) 402 option_flags = 0;
424 dev_warn(&dev->dev, "missing "
425 "SMALL_TAG_STARTDEP tag\n");
426 option = option_independent;
427 dev_dbg(&dev->dev, "end dependent options\n");
428 break; 403 break;
429 404
430 case SMALL_TAG_END: 405 case SMALL_TAG_END:
@@ -526,8 +501,16 @@ len_err:
526static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p, 501static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
527 struct resource *res) 502 struct resource *res)
528{ 503{
529 unsigned long base = res->start; 504 unsigned long base;
530 unsigned long len = res->end - res->start + 1; 505 unsigned long len;
506
507 if (pnp_resource_enabled(res)) {
508 base = res->start;
509 len = res->end - res->start + 1;
510 } else {
511 base = 0;
512 len = 0;
513 }
531 514
532 p[4] = (base >> 8) & 0xff; 515 p[4] = (base >> 8) & 0xff;
533 p[5] = ((base >> 8) >> 8) & 0xff; 516 p[5] = ((base >> 8) >> 8) & 0xff;
@@ -536,15 +519,22 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
536 p[10] = (len >> 8) & 0xff; 519 p[10] = (len >> 8) & 0xff;
537 p[11] = ((len >> 8) >> 8) & 0xff; 520 p[11] = ((len >> 8) >> 8) & 0xff;
538 521
539 dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n", 522 dev_dbg(&dev->dev, " encode mem %#lx-%#lx\n", base, base + len - 1);
540 (unsigned long long) res->start, (unsigned long long) res->end);
541} 523}
542 524
543static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, 525static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
544 struct resource *res) 526 struct resource *res)
545{ 527{
546 unsigned long base = res->start; 528 unsigned long base;
547 unsigned long len = res->end - res->start + 1; 529 unsigned long len;
530
531 if (pnp_resource_enabled(res)) {
532 base = res->start;
533 len = res->end - res->start + 1;
534 } else {
535 base = 0;
536 len = 0;
537 }
548 538
549 p[4] = base & 0xff; 539 p[4] = base & 0xff;
550 p[5] = (base >> 8) & 0xff; 540 p[5] = (base >> 8) & 0xff;
@@ -559,15 +549,22 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
559 p[18] = (len >> 16) & 0xff; 549 p[18] = (len >> 16) & 0xff;
560 p[19] = (len >> 24) & 0xff; 550 p[19] = (len >> 24) & 0xff;
561 551
562 dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n", 552 dev_dbg(&dev->dev, " encode mem32 %#lx-%#lx\n", base, base + len - 1);
563 (unsigned long long) res->start, (unsigned long long) res->end);
564} 553}
565 554
566static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, 555static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
567 struct resource *res) 556 struct resource *res)
568{ 557{
569 unsigned long base = res->start; 558 unsigned long base;
570 unsigned long len = res->end - res->start + 1; 559 unsigned long len;
560
561 if (pnp_resource_enabled(res)) {
562 base = res->start;
563 len = res->end - res->start + 1;
564 } else {
565 base = 0;
566 len = 0;
567 }
571 568
572 p[4] = base & 0xff; 569 p[4] = base & 0xff;
573 p[5] = (base >> 8) & 0xff; 570 p[5] = (base >> 8) & 0xff;
@@ -578,40 +575,54 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
578 p[10] = (len >> 16) & 0xff; 575 p[10] = (len >> 16) & 0xff;
579 p[11] = (len >> 24) & 0xff; 576 p[11] = (len >> 24) & 0xff;
580 577
581 dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n", 578 dev_dbg(&dev->dev, " encode fixed_mem32 %#lx-%#lx\n", base,
582 (unsigned long long) res->start, (unsigned long long) res->end); 579 base + len - 1);
583} 580}
584 581
585static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p, 582static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
586 struct resource *res) 583 struct resource *res)
587{ 584{
588 unsigned long map = 0; 585 unsigned long map;
586
587 if (pnp_resource_enabled(res))
588 map = 1 << res->start;
589 else
590 map = 0;
589 591
590 map = 1 << res->start;
591 p[1] = map & 0xff; 592 p[1] = map & 0xff;
592 p[2] = (map >> 8) & 0xff; 593 p[2] = (map >> 8) & 0xff;
593 594
594 dev_dbg(&dev->dev, " encode irq %llu\n", 595 dev_dbg(&dev->dev, " encode irq mask %#lx\n", map);
595 (unsigned long long)res->start);
596} 596}
597 597
598static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, 598static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
599 struct resource *res) 599 struct resource *res)
600{ 600{
601 unsigned long map = 0; 601 unsigned long map;
602
603 if (pnp_resource_enabled(res))
604 map = 1 << res->start;
605 else
606 map = 0;
602 607
603 map = 1 << res->start;
604 p[1] = map & 0xff; 608 p[1] = map & 0xff;
605 609
606 dev_dbg(&dev->dev, " encode dma %llu\n", 610 dev_dbg(&dev->dev, " encode dma mask %#lx\n", map);
607 (unsigned long long)res->start);
608} 611}
609 612
610static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, 613static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
611 struct resource *res) 614 struct resource *res)
612{ 615{
613 unsigned long base = res->start; 616 unsigned long base;
614 unsigned long len = res->end - res->start + 1; 617 unsigned long len;
618
619 if (pnp_resource_enabled(res)) {
620 base = res->start;
621 len = res->end - res->start + 1;
622 } else {
623 base = 0;
624 len = 0;
625 }
615 626
616 p[2] = base & 0xff; 627 p[2] = base & 0xff;
617 p[3] = (base >> 8) & 0xff; 628 p[3] = (base >> 8) & 0xff;
@@ -619,8 +630,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
619 p[5] = (base >> 8) & 0xff; 630 p[5] = (base >> 8) & 0xff;
620 p[7] = len & 0xff; 631 p[7] = len & 0xff;
621 632
622 dev_dbg(&dev->dev, " encode io %#llx-%#llx\n", 633 dev_dbg(&dev->dev, " encode io %#lx-%#lx\n", base, base + len - 1);
623 (unsigned long long) res->start, (unsigned long long) res->end);
624} 634}
625 635
626static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, 636static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
@@ -629,12 +639,20 @@ static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
629 unsigned long base = res->start; 639 unsigned long base = res->start;
630 unsigned long len = res->end - res->start + 1; 640 unsigned long len = res->end - res->start + 1;
631 641
642 if (pnp_resource_enabled(res)) {
643 base = res->start;
644 len = res->end - res->start + 1;
645 } else {
646 base = 0;
647 len = 0;
648 }
649
632 p[1] = base & 0xff; 650 p[1] = base & 0xff;
633 p[2] = (base >> 8) & 0xff; 651 p[2] = (base >> 8) & 0xff;
634 p[3] = len & 0xff; 652 p[3] = len & 0xff;
635 653
636 dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n", 654 dev_dbg(&dev->dev, " encode fixed_io %#lx-%#lx\n", base,
637 (unsigned long long) res->start, (unsigned long long) res->end); 655 base + len - 1);
638} 656}
639 657
640static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev 658static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 1ff3bb585ab2..55f55ed72dc7 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -5,6 +5,8 @@
5 * when building up the resource structure for the first time. 5 * when building up the resource structure for the first time.
6 * 6 *
7 * Copyright (c) 2000 Peter Denison <peterd@pnd-pc.demon.co.uk> 7 * Copyright (c) 2000 Peter Denison <peterd@pnd-pc.demon.co.uk>
8 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
9 * Bjorn Helgaas <bjorn.helgaas@hp.com>
8 * 10 *
9 * Heavily based on PCI quirks handling which is 11 * Heavily based on PCI quirks handling which is
10 * 12 *
@@ -20,203 +22,207 @@
20#include <linux/kallsyms.h> 22#include <linux/kallsyms.h>
21#include "base.h" 23#include "base.h"
22 24
25static void quirk_awe32_add_ports(struct pnp_dev *dev,
26 struct pnp_option *option,
27 unsigned int offset)
28{
29 struct pnp_option *new_option;
30
31 new_option = kmalloc(sizeof(struct pnp_option), GFP_KERNEL);
32 if (!new_option) {
33 dev_err(&dev->dev, "couldn't add ioport region to option set "
34 "%d\n", pnp_option_set(option));
35 return;
36 }
37
38 *new_option = *option;
39 new_option->u.port.min += offset;
40 new_option->u.port.max += offset;
41 list_add(&new_option->list, &option->list);
42
43 dev_info(&dev->dev, "added ioport region %#llx-%#llx to set %d\n",
44 (unsigned long long) new_option->u.port.min,
45 (unsigned long long) new_option->u.port.max,
46 pnp_option_set(option));
47}
48
23static void quirk_awe32_resources(struct pnp_dev *dev) 49static void quirk_awe32_resources(struct pnp_dev *dev)
24{ 50{
25 struct pnp_port *port, *port2, *port3; 51 struct pnp_option *option;
26 struct pnp_option *res = dev->dependent; 52 unsigned int set = ~0;
27 53
28 /* 54 /*
29 * Unfortunately the isapnp_add_port_resource is too tightly bound 55 * Add two extra ioport regions (at offset 0x400 and 0x800 from the
30 * into the PnP discovery sequence, and cannot be used. Link in the 56 * one given) to every dependent option set.
31 * two extra ports (at offset 0x400 and 0x800 from the one given) by
32 * hand.
33 */ 57 */
34 for (; res; res = res->next) { 58 list_for_each_entry(option, &dev->options, list) {
35 port2 = pnp_alloc(sizeof(struct pnp_port)); 59 if (pnp_option_is_dependent(option) &&
36 if (!port2) 60 pnp_option_set(option) != set) {
37 return; 61 set = pnp_option_set(option);
38 port3 = pnp_alloc(sizeof(struct pnp_port)); 62 quirk_awe32_add_ports(dev, option, 0x800);
39 if (!port3) { 63 quirk_awe32_add_ports(dev, option, 0x400);
40 kfree(port2);
41 return;
42 } 64 }
43 port = res->port;
44 memcpy(port2, port, sizeof(struct pnp_port));
45 memcpy(port3, port, sizeof(struct pnp_port));
46 port->next = port2;
47 port2->next = port3;
48 port2->min += 0x400;
49 port2->max += 0x400;
50 port3->min += 0x800;
51 port3->max += 0x800;
52 dev_info(&dev->dev,
53 "AWE32 quirk - added ioports 0x%lx and 0x%lx\n",
54 (unsigned long)port2->min,
55 (unsigned long)port3->min);
56 } 65 }
57} 66}
58 67
59static void quirk_cmi8330_resources(struct pnp_dev *dev) 68static void quirk_cmi8330_resources(struct pnp_dev *dev)
60{ 69{
61 struct pnp_option *res = dev->dependent; 70 struct pnp_option *option;
62 unsigned long tmp; 71 struct pnp_irq *irq;
63 72 struct pnp_dma *dma;
64 for (; res; res = res->next) {
65
66 struct pnp_irq *irq;
67 struct pnp_dma *dma;
68 73
69 for (irq = res->irq; irq; irq = irq->next) { // Valid irqs are 5, 7, 10 74 list_for_each_entry(option, &dev->options, list) {
70 tmp = 0x04A0; 75 if (!pnp_option_is_dependent(option))
71 bitmap_copy(irq->map, &tmp, 16); // 0000 0100 1010 0000 76 continue;
72 }
73 77
74 for (dma = res->dma; dma; dma = dma->next) // Valid 8bit dma channels are 1,3 78 if (option->type == IORESOURCE_IRQ) {
79 irq = &option->u.irq;
80 bitmap_zero(irq->map.bits, PNP_IRQ_NR);
81 __set_bit(5, irq->map.bits);
82 __set_bit(7, irq->map.bits);
83 __set_bit(10, irq->map.bits);
84 dev_info(&dev->dev, "set possible IRQs in "
85 "option set %d to 5, 7, 10\n",
86 pnp_option_set(option));
87 } else if (option->type == IORESOURCE_DMA) {
88 dma = &option->u.dma;
75 if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) == 89 if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) ==
76 IORESOURCE_DMA_8BIT) 90 IORESOURCE_DMA_8BIT &&
77 dma->map = 0x000A; 91 dma->map != 0x0A) {
92 dev_info(&dev->dev, "changing possible "
93 "DMA channel mask in option set %d "
94 "from %#02x to 0x0A (1, 3)\n",
95 pnp_option_set(option), dma->map);
96 dma->map = 0x0A;
97 }
98 }
78 } 99 }
79 dev_info(&dev->dev, "CMI8330 quirk - forced possible IRQs to 5, 7, 10 "
80 "and DMA channels to 1, 3\n");
81} 100}
82 101
83static void quirk_sb16audio_resources(struct pnp_dev *dev) 102static void quirk_sb16audio_resources(struct pnp_dev *dev)
84{ 103{
104 struct pnp_option *option;
105 unsigned int prev_option_flags = ~0, n = 0;
85 struct pnp_port *port; 106 struct pnp_port *port;
86 struct pnp_option *res = dev->dependent;
87 int changed = 0;
88 107
89 /* 108 /*
90 * The default range on the mpu port for these devices is 0x388-0x388. 109 * The default range on the OPL port for these devices is 0x388-0x388.
91 * Here we increase that range so that two such cards can be 110 * Here we increase that range so that two such cards can be
92 * auto-configured. 111 * auto-configured.
93 */ 112 */
113 list_for_each_entry(option, &dev->options, list) {
114 if (prev_option_flags != option->flags) {
115 prev_option_flags = option->flags;
116 n = 0;
117 }
94 118
95 for (; res; res = res->next) { 119 if (pnp_option_is_dependent(option) &&
96 port = res->port; 120 option->type == IORESOURCE_IO) {
97 if (!port) 121 n++;
98 continue; 122 port = &option->u.port;
99 port = port->next; 123 if (n == 3 && port->min == port->max) {
100 if (!port) 124 port->max += 0x70;
101 continue; 125 dev_info(&dev->dev, "increased option port "
102 port = port->next; 126 "range from %#llx-%#llx to "
103 if (!port) 127 "%#llx-%#llx\n",
104 continue; 128 (unsigned long long) port->min,
105 if (port->min != port->max) 129 (unsigned long long) port->min,
106 continue; 130 (unsigned long long) port->min,
107 port->max += 0x70; 131 (unsigned long long) port->max);
108 changed = 1; 132 }
133 }
109 } 134 }
110 if (changed)
111 dev_info(&dev->dev, "SB audio device quirk - increased port range\n");
112} 135}
113 136
114static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) 137static struct pnp_option *pnp_clone_dependent_set(struct pnp_dev *dev,
138 unsigned int set)
115{ 139{
116 struct pnp_option *head = NULL; 140 struct pnp_option *tail = NULL, *first_new_option = NULL;
117 struct pnp_option *prev = NULL; 141 struct pnp_option *option, *new_option;
118 struct pnp_option *res; 142 unsigned int flags;
119
120 /*
121 * Build a functional IRQ-less variant of each MPU option.
122 */
123
124 for (res = dev->dependent; res; res = res->next) {
125 struct pnp_option *curr;
126 struct pnp_port *port;
127 struct pnp_port *copy;
128 143
129 port = res->port; 144 list_for_each_entry(option, &dev->options, list) {
130 if (!port || !res->irq) 145 if (pnp_option_is_dependent(option))
131 continue; 146 tail = option;
147 }
148 if (!tail) {
149 dev_err(&dev->dev, "no dependent option sets\n");
150 return NULL;
151 }
132 152
133 copy = pnp_alloc(sizeof *copy); 153 flags = pnp_new_dependent_set(dev, PNP_RES_PRIORITY_FUNCTIONAL);
134 if (!copy) 154 list_for_each_entry(option, &dev->options, list) {
135 break; 155 if (pnp_option_is_dependent(option) &&
156 pnp_option_set(option) == set) {
157 new_option = kmalloc(sizeof(struct pnp_option),
158 GFP_KERNEL);
159 if (!new_option) {
160 dev_err(&dev->dev, "couldn't clone dependent "
161 "set %d\n", set);
162 return NULL;
163 }
136 164
137 copy->min = port->min; 165 *new_option = *option;
138 copy->max = port->max; 166 new_option->flags = flags;
139 copy->align = port->align; 167 if (!first_new_option)
140 copy->size = port->size; 168 first_new_option = new_option;
141 copy->flags = port->flags;
142 169
143 curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL); 170 list_add(&new_option->list, &tail->list);
144 if (!curr) { 171 tail = new_option;
145 kfree(copy);
146 break;
147 } 172 }
148 curr->port = copy;
149
150 if (prev)
151 prev->next = curr;
152 else
153 head = curr;
154 prev = curr;
155 } 173 }
156 if (head)
157 dev_info(&dev->dev, "adding IRQ-less MPU options\n");
158 174
159 return head; 175 return first_new_option;
160} 176}
161 177
162static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) 178
179static void quirk_add_irq_optional_dependent_sets(struct pnp_dev *dev)
163{ 180{
164 struct pnp_option *res; 181 struct pnp_option *new_option;
182 unsigned int num_sets, i, set;
165 struct pnp_irq *irq; 183 struct pnp_irq *irq;
166 184
167 /* 185 num_sets = dev->num_dependent_sets;
168 * Distribute the independent IRQ over the dependent options 186 for (i = 0; i < num_sets; i++) {
169 */ 187 new_option = pnp_clone_dependent_set(dev, i);
170 188 if (!new_option)
171 res = dev->independent; 189 return;
172 if (!res)
173 return;
174
175 irq = res->irq;
176 if (!irq || irq->next)
177 return;
178
179 res = dev->dependent;
180 if (!res)
181 return;
182
183 while (1) {
184 struct pnp_irq *copy;
185
186 copy = pnp_alloc(sizeof *copy);
187 if (!copy)
188 break;
189
190 memcpy(copy->map, irq->map, sizeof copy->map);
191 copy->flags = irq->flags;
192 190
193 copy->next = res->irq; /* Yes, this is NULL */ 191 set = pnp_option_set(new_option);
194 res->irq = copy; 192 while (new_option && pnp_option_set(new_option) == set) {
193 if (new_option->type == IORESOURCE_IRQ) {
194 irq = &new_option->u.irq;
195 irq->flags |= IORESOURCE_IRQ_OPTIONAL;
196 }
197 dbg_pnp_show_option(dev, new_option);
198 new_option = list_entry(new_option->list.next,
199 struct pnp_option, list);
200 }
195 201
196 if (!res->next) 202 dev_info(&dev->dev, "added dependent option set %d (same as "
197 break; 203 "set %d except IRQ optional)\n", set, i);
198 res = res->next;
199 } 204 }
200 kfree(irq);
201
202 res->next = quirk_isapnp_mpu_options(dev);
203
204 res = dev->independent;
205 res->irq = NULL;
206} 205}
207 206
208static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) 207static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
209{ 208{
210 struct pnp_option *res; 209 struct pnp_option *option;
210 struct pnp_irq *irq = NULL;
211 unsigned int independent_irqs = 0;
212
213 list_for_each_entry(option, &dev->options, list) {
214 if (option->type == IORESOURCE_IRQ &&
215 !pnp_option_is_dependent(option)) {
216 independent_irqs++;
217 irq = &option->u.irq;
218 }
219 }
211 220
212 res = dev->dependent; 221 if (independent_irqs != 1)
213 if (!res)
214 return; 222 return;
215 223
216 while (res->next) 224 irq->flags |= IORESOURCE_IRQ_OPTIONAL;
217 res = res->next; 225 dev_info(&dev->dev, "made independent IRQ optional\n");
218
219 res->next = quirk_isapnp_mpu_options(dev);
220} 226}
221 227
222#include <linux/pci.h> 228#include <linux/pci.h>
@@ -248,8 +254,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
248 for (j = 0; 254 for (j = 0;
249 (res = pnp_get_resource(dev, IORESOURCE_MEM, j)); 255 (res = pnp_get_resource(dev, IORESOURCE_MEM, j));
250 j++) { 256 j++) {
251 if (res->flags & IORESOURCE_UNSET || 257 if (res->start == 0 && res->end == 0)
252 (res->start == 0 && res->end == 0))
253 continue; 258 continue;
254 259
255 pnp_start = res->start; 260 pnp_start = res->start;
@@ -312,10 +317,10 @@ static struct pnp_fixup pnp_fixups[] = {
312 {"CTL0043", quirk_sb16audio_resources}, 317 {"CTL0043", quirk_sb16audio_resources},
313 {"CTL0044", quirk_sb16audio_resources}, 318 {"CTL0044", quirk_sb16audio_resources},
314 {"CTL0045", quirk_sb16audio_resources}, 319 {"CTL0045", quirk_sb16audio_resources},
315 /* Add IRQ-less MPU options */ 320 /* Add IRQ-optional MPU options */
316 {"ADS7151", quirk_ad1815_mpu_resources}, 321 {"ADS7151", quirk_ad1815_mpu_resources},
317 {"ADS7181", quirk_isapnp_mpu_resources}, 322 {"ADS7181", quirk_add_irq_optional_dependent_sets},
318 {"AZT0002", quirk_isapnp_mpu_resources}, 323 {"AZT0002", quirk_add_irq_optional_dependent_sets},
319 /* PnP resources that might overlap PCI BARs */ 324 /* PnP resources that might overlap PCI BARs */
320 {"PNP0c01", quirk_system_pci_resources}, 325 {"PNP0c01", quirk_system_pci_resources},
321 {"PNP0c02", quirk_system_pci_resources}, 326 {"PNP0c02", quirk_system_pci_resources},
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 390b50096e30..4cfe3a1efdfb 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -3,6 +3,8 @@
3 * 3 *
4 * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> 4 * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
5 * Copyright 2003 Adam Belay <ambx1@neo.rr.com> 5 * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
6 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
6 */ 8 */
7 9
8#include <linux/module.h> 10#include <linux/module.h>
@@ -28,201 +30,121 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some
28 * option registration 30 * option registration
29 */ 31 */
30 32
31struct pnp_option *pnp_build_option(int priority) 33struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type,
34 unsigned int option_flags)
32{ 35{
33 struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option)); 36 struct pnp_option *option;
34 37
38 option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL);
35 if (!option) 39 if (!option)
36 return NULL; 40 return NULL;
37 41
38 option->priority = priority & 0xff; 42 option->flags = option_flags;
39 /* make sure the priority is valid */ 43 option->type = type;
40 if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL)
41 option->priority = PNP_RES_PRIORITY_INVALID;
42
43 return option;
44}
45
46struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
47{
48 struct pnp_option *option;
49
50 option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED);
51
52 /* this should never happen but if it does we'll try to continue */
53 if (dev->independent)
54 dev_err(&dev->dev, "independent resource already registered\n");
55 dev->independent = option;
56 44
57 dev_dbg(&dev->dev, "new independent option\n"); 45 list_add_tail(&option->list, &dev->options);
58 return option; 46 return option;
59} 47}
60 48
61struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, 49int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
62 int priority) 50 pnp_irq_mask_t *map, unsigned char flags)
63{ 51{
64 struct pnp_option *option; 52 struct pnp_option *option;
53 struct pnp_irq *irq;
65 54
66 option = pnp_build_option(priority); 55 option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags);
67 56 if (!option)
68 if (dev->dependent) { 57 return -ENOMEM;
69 struct pnp_option *parent = dev->dependent;
70 while (parent->next)
71 parent = parent->next;
72 parent->next = option;
73 } else
74 dev->dependent = option;
75
76 dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority);
77 return option;
78}
79
80int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
81 struct pnp_irq *data)
82{
83 struct pnp_irq *ptr;
84#ifdef DEBUG
85 char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */
86#endif
87 58
88 ptr = option->irq; 59 irq = &option->u.irq;
89 while (ptr && ptr->next) 60 irq->map = *map;
90 ptr = ptr->next; 61 irq->flags = flags;
91 if (ptr)
92 ptr->next = data;
93 else
94 option->irq = data;
95 62
96#ifdef CONFIG_PCI 63#ifdef CONFIG_PCI
97 { 64 {
98 int i; 65 int i;
99 66
100 for (i = 0; i < 16; i++) 67 for (i = 0; i < 16; i++)
101 if (test_bit(i, data->map)) 68 if (test_bit(i, irq->map.bits))
102 pcibios_penalize_isa_irq(i, 0); 69 pcibios_penalize_isa_irq(i, 0);
103 } 70 }
104#endif 71#endif
105 72
106#ifdef DEBUG 73 dbg_pnp_show_option(dev, option);
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
111 return 0; 74 return 0;
112} 75}
113 76
114int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, 77int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
115 struct pnp_dma *data) 78 unsigned char map, unsigned char flags)
116{ 79{
117 struct pnp_dma *ptr; 80 struct pnp_option *option;
118 81 struct pnp_dma *dma;
119 ptr = option->dma;
120 while (ptr && ptr->next)
121 ptr = ptr->next;
122 if (ptr)
123 ptr->next = data;
124 else
125 option->dma = data;
126
127 dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", data->map,
128 data->flags);
129 return 0;
130}
131 82
132int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, 83 option = pnp_build_option(dev, IORESOURCE_DMA, option_flags);
133 struct pnp_port *data) 84 if (!option)
134{ 85 return -ENOMEM;
135 struct pnp_port *ptr;
136
137 ptr = option->port;
138 while (ptr && ptr->next)
139 ptr = ptr->next;
140 if (ptr)
141 ptr->next = data;
142 else
143 option->port = data;
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);
148 return 0;
149}
150 86
151int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, 87 dma = &option->u.dma;
152 struct pnp_mem *data) 88 dma->map = map;
153{ 89 dma->flags = flags;
154 struct pnp_mem *ptr; 90
155 91 dbg_pnp_show_option(dev, option);
156 ptr = option->mem;
157 while (ptr && ptr->next)
158 ptr = ptr->next;
159 if (ptr)
160 ptr->next = data;
161 else
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);
167 return 0; 92 return 0;
168} 93}
169 94
170static void pnp_free_port(struct pnp_port *port) 95int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags,
96 resource_size_t min, resource_size_t max,
97 resource_size_t align, resource_size_t size,
98 unsigned char flags)
171{ 99{
172 struct pnp_port *next; 100 struct pnp_option *option;
101 struct pnp_port *port;
173 102
174 while (port) { 103 option = pnp_build_option(dev, IORESOURCE_IO, option_flags);
175 next = port->next; 104 if (!option)
176 kfree(port); 105 return -ENOMEM;
177 port = next;
178 }
179}
180 106
181static void pnp_free_irq(struct pnp_irq *irq) 107 port = &option->u.port;
182{ 108 port->min = min;
183 struct pnp_irq *next; 109 port->max = max;
110 port->align = align;
111 port->size = size;
112 port->flags = flags;
184 113
185 while (irq) { 114 dbg_pnp_show_option(dev, option);
186 next = irq->next; 115 return 0;
187 kfree(irq);
188 irq = next;
189 }
190} 116}
191 117
192static void pnp_free_dma(struct pnp_dma *dma) 118int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags,
119 resource_size_t min, resource_size_t max,
120 resource_size_t align, resource_size_t size,
121 unsigned char flags)
193{ 122{
194 struct pnp_dma *next; 123 struct pnp_option *option;
124 struct pnp_mem *mem;
195 125
196 while (dma) { 126 option = pnp_build_option(dev, IORESOURCE_MEM, option_flags);
197 next = dma->next; 127 if (!option)
198 kfree(dma); 128 return -ENOMEM;
199 dma = next;
200 }
201}
202 129
203static void pnp_free_mem(struct pnp_mem *mem) 130 mem = &option->u.mem;
204{ 131 mem->min = min;
205 struct pnp_mem *next; 132 mem->max = max;
133 mem->align = align;
134 mem->size = size;
135 mem->flags = flags;
206 136
207 while (mem) { 137 dbg_pnp_show_option(dev, option);
208 next = mem->next; 138 return 0;
209 kfree(mem);
210 mem = next;
211 }
212} 139}
213 140
214void pnp_free_option(struct pnp_option *option) 141void pnp_free_options(struct pnp_dev *dev)
215{ 142{
216 struct pnp_option *next; 143 struct pnp_option *option, *tmp;
217 144
218 while (option) { 145 list_for_each_entry_safe(option, tmp, &dev->options, list) {
219 next = option->next; 146 list_del(&option->list);
220 pnp_free_port(option->port);
221 pnp_free_irq(option->irq);
222 pnp_free_dma(option->dma);
223 pnp_free_mem(option->mem);
224 kfree(option); 147 kfree(option);
225 option = next;
226 } 148 }
227} 149}
228 150
@@ -237,7 +159,7 @@ void pnp_free_option(struct pnp_option *option)
237 !((*(enda) < *(startb)) || (*(endb) < *(starta))) 159 !((*(enda) < *(startb)) || (*(endb) < *(starta)))
238 160
239#define cannot_compare(flags) \ 161#define cannot_compare(flags) \
240((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) 162((flags) & IORESOURCE_DISABLED)
241 163
242int pnp_check_port(struct pnp_dev *dev, struct resource *res) 164int pnp_check_port(struct pnp_dev *dev, struct resource *res)
243{ 165{
@@ -364,6 +286,61 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id)
364 return IRQ_HANDLED; 286 return IRQ_HANDLED;
365} 287}
366 288
289#ifdef CONFIG_PCI
290static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,
291 unsigned int irq)
292{
293 u32 class;
294 u8 progif;
295
296 if (pci->irq == irq) {
297 dev_dbg(&pnp->dev, "device %s using irq %d\n",
298 pci_name(pci), irq);
299 return 1;
300 }
301
302 /*
303 * See pci_setup_device() and ata_pci_sff_activate_host() for
304 * similar IDE legacy detection.
305 */
306 pci_read_config_dword(pci, PCI_CLASS_REVISION, &class);
307 class >>= 8; /* discard revision ID */
308 progif = class & 0xff;
309 class >>= 8;
310
311 if (class == PCI_CLASS_STORAGE_IDE) {
312 /*
313 * Unless both channels are native-PCI mode only,
314 * treat the compatibility IRQs as busy.
315 */
316 if ((progif & 0x5) != 0x5)
317 if (pci_get_legacy_ide_irq(pci, 0) == irq ||
318 pci_get_legacy_ide_irq(pci, 1) == irq) {
319 dev_dbg(&pnp->dev, "legacy IDE device %s "
320 "using irq %d\n", pci_name(pci), irq);
321 return 1;
322 }
323 }
324
325 return 0;
326}
327#endif
328
329static int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq)
330{
331#ifdef CONFIG_PCI
332 struct pci_dev *pci = NULL;
333
334 for_each_pci_dev(pci) {
335 if (pci_dev_uses_irq(pnp, pci, irq)) {
336 pci_dev_put(pci);
337 return 1;
338 }
339 }
340#endif
341 return 0;
342}
343
367int pnp_check_irq(struct pnp_dev *dev, struct resource *res) 344int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
368{ 345{
369 int i; 346 int i;
@@ -395,18 +372,9 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
395 } 372 }
396 } 373 }
397 374
398#ifdef CONFIG_PCI
399 /* check if the resource is being used by a pci device */ 375 /* check if the resource is being used by a pci device */
400 { 376 if (pci_uses_irq(dev, *irq))
401 struct pci_dev *pci = NULL; 377 return 0;
402 for_each_pci_dev(pci) {
403 if (pci->irq == *irq) {
404 pci_dev_put(pci);
405 return 0;
406 }
407 }
408 }
409#endif
410 378
411 /* check if the resource is already in use, skip if the 379 /* check if the resource is already in use, skip if the
412 * device is active because it itself may be in use */ 380 * device is active because it itself may be in use */
@@ -499,81 +467,37 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
499#endif 467#endif
500} 468}
501 469
502struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev, 470int pnp_resource_type(struct resource *res)
503 unsigned int type, unsigned int num)
504{ 471{
505 struct pnp_resource_table *res = dev->res; 472 return res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
506 473 IORESOURCE_IRQ | IORESOURCE_DMA);
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} 474}
527 475
528struct resource *pnp_get_resource(struct pnp_dev *dev, 476struct resource *pnp_get_resource(struct pnp_dev *dev,
529 unsigned int type, unsigned int num) 477 unsigned int type, unsigned int num)
530{ 478{
531 struct pnp_resource *pnp_res; 479 struct pnp_resource *pnp_res;
480 struct resource *res;
532 481
533 pnp_res = pnp_get_pnp_resource(dev, type, num); 482 list_for_each_entry(pnp_res, &dev->resources, list) {
534 if (pnp_res) 483 res = &pnp_res->res;
535 return &pnp_res->res; 484 if (pnp_resource_type(res) == type && num-- == 0)
536 485 return res;
486 }
537 return NULL; 487 return NULL;
538} 488}
539EXPORT_SYMBOL(pnp_get_resource); 489EXPORT_SYMBOL(pnp_get_resource);
540 490
541static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type) 491static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev)
542{ 492{
543 struct pnp_resource *pnp_res; 493 struct pnp_resource *pnp_res;
544 int i;
545 494
546 switch (type) { 495 pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL);
547 case IORESOURCE_IO: 496 if (!pnp_res)
548 for (i = 0; i < PNP_MAX_PORT; i++) { 497 return NULL;
549 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i); 498
550 if (pnp_res && !pnp_resource_valid(&pnp_res->res)) 499 list_add_tail(&pnp_res->list, &dev->resources);
551 return pnp_res; 500 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} 501}
578 502
579struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 503struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
@@ -581,15 +505,10 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
581{ 505{
582 struct pnp_resource *pnp_res; 506 struct pnp_resource *pnp_res;
583 struct resource *res; 507 struct resource *res;
584 static unsigned char warned;
585 508
586 pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ); 509 pnp_res = pnp_new_resource(dev);
587 if (!pnp_res) { 510 if (!pnp_res) {
588 if (!warned) { 511 dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq);
589 dev_err(&dev->dev, "can't add resource for IRQ %d\n",
590 irq);
591 warned = 1;
592 }
593 return NULL; 512 return NULL;
594 } 513 }
595 514
@@ -607,15 +526,10 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
607{ 526{
608 struct pnp_resource *pnp_res; 527 struct pnp_resource *pnp_res;
609 struct resource *res; 528 struct resource *res;
610 static unsigned char warned;
611 529
612 pnp_res = pnp_new_resource(dev, IORESOURCE_DMA); 530 pnp_res = pnp_new_resource(dev);
613 if (!pnp_res) { 531 if (!pnp_res) {
614 if (!warned) { 532 dev_err(&dev->dev, "can't add resource for DMA %d\n", dma);
615 dev_err(&dev->dev, "can't add resource for DMA %d\n",
616 dma);
617 warned = 1;
618 }
619 return NULL; 533 return NULL;
620 } 534 }
621 535
@@ -634,16 +548,12 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
634{ 548{
635 struct pnp_resource *pnp_res; 549 struct pnp_resource *pnp_res;
636 struct resource *res; 550 struct resource *res;
637 static unsigned char warned;
638 551
639 pnp_res = pnp_new_resource(dev, IORESOURCE_IO); 552 pnp_res = pnp_new_resource(dev);
640 if (!pnp_res) { 553 if (!pnp_res) {
641 if (!warned) { 554 dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n",
642 dev_err(&dev->dev, "can't add resource for IO " 555 (unsigned long long) start,
643 "%#llx-%#llx\n",(unsigned long long) start, 556 (unsigned long long) end);
644 (unsigned long long) end);
645 warned = 1;
646 }
647 return NULL; 557 return NULL;
648 } 558 }
649 559
@@ -663,16 +573,12 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
663{ 573{
664 struct pnp_resource *pnp_res; 574 struct pnp_resource *pnp_res;
665 struct resource *res; 575 struct resource *res;
666 static unsigned char warned;
667 576
668 pnp_res = pnp_new_resource(dev, IORESOURCE_MEM); 577 pnp_res = pnp_new_resource(dev);
669 if (!pnp_res) { 578 if (!pnp_res) {
670 if (!warned) { 579 dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n",
671 dev_err(&dev->dev, "can't add resource for MEM " 580 (unsigned long long) start,
672 "%#llx-%#llx\n",(unsigned long long) start, 581 (unsigned long long) end);
673 (unsigned long long) end);
674 warned = 1;
675 }
676 return NULL; 582 return NULL;
677 } 583 }
678 584
@@ -686,6 +592,52 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
686 return pnp_res; 592 return pnp_res;
687} 593}
688 594
595/*
596 * Determine whether the specified resource is a possible configuration
597 * for this device.
598 */
599int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
600 resource_size_t size)
601{
602 struct pnp_option *option;
603 struct pnp_port *port;
604 struct pnp_mem *mem;
605 struct pnp_irq *irq;
606 struct pnp_dma *dma;
607
608 list_for_each_entry(option, &dev->options, list) {
609 if (option->type != type)
610 continue;
611
612 switch (option->type) {
613 case IORESOURCE_IO:
614 port = &option->u.port;
615 if (port->min == start && port->size == size)
616 return 1;
617 break;
618 case IORESOURCE_MEM:
619 mem = &option->u.mem;
620 if (mem->min == start && mem->size == size)
621 return 1;
622 break;
623 case IORESOURCE_IRQ:
624 irq = &option->u.irq;
625 if (start < PNP_IRQ_NR &&
626 test_bit(start, irq->map.bits))
627 return 1;
628 break;
629 case IORESOURCE_DMA:
630 dma = &option->u.dma;
631 if (dma->map & (1 << start))
632 return 1;
633 break;
634 }
635 }
636
637 return 0;
638}
639EXPORT_SYMBOL(pnp_possible_config);
640
689/* format is: pnp_reserve_irq=irq1[,irq2] .... */ 641/* format is: pnp_reserve_irq=irq1[,irq2] .... */
690static int __init pnp_setup_reserve_irq(char *str) 642static int __init pnp_setup_reserve_irq(char *str)
691{ 643{
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index 95b076c18c07..bbf78ef4ba02 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -2,6 +2,8 @@
2 * support.c - standard functions for the use of pnp protocol drivers 2 * support.c - standard functions for the use of pnp protocol drivers
3 * 3 *
4 * Copyright 2003 Adam Belay <ambx1@neo.rr.com> 4 * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
5 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
6 * Bjorn Helgaas <bjorn.helgaas@hp.com>
5 */ 7 */
6 8
7#include <linux/module.h> 9#include <linux/module.h>
@@ -16,6 +18,10 @@
16 */ 18 */
17int pnp_is_active(struct pnp_dev *dev) 19int pnp_is_active(struct pnp_dev *dev)
18{ 20{
21 /*
22 * I don't think this is very reliable because pnp_disable_dev()
23 * only clears out auto-assigned resources.
24 */
19 if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 && 25 if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 &&
20 !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 && 26 !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 &&
21 pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1) 27 pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1)
@@ -52,39 +58,154 @@ void pnp_eisa_id_to_string(u32 id, char *str)
52 str[7] = '\0'; 58 str[7] = '\0';
53} 59}
54 60
61char *pnp_resource_type_name(struct resource *res)
62{
63 switch (pnp_resource_type(res)) {
64 case IORESOURCE_IO:
65 return "io";
66 case IORESOURCE_MEM:
67 return "mem";
68 case IORESOURCE_IRQ:
69 return "irq";
70 case IORESOURCE_DMA:
71 return "dma";
72 }
73 return NULL;
74}
75
55void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) 76void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
56{ 77{
57#ifdef DEBUG 78#ifdef DEBUG
79 char buf[128];
80 int len = 0;
81 struct pnp_resource *pnp_res;
58 struct resource *res; 82 struct resource *res;
59 int i;
60 83
61 dev_dbg(&dev->dev, "current resources: %s\n", desc); 84 if (list_empty(&dev->resources)) {
62 85 dev_dbg(&dev->dev, "%s: no current resources\n", desc);
63 for (i = 0; i < PNP_MAX_IRQ; i++) { 86 return;
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 } 87 }
69 for (i = 0; i < PNP_MAX_DMA; i++) { 88
70 res = pnp_get_resource(dev, IORESOURCE_DMA, i); 89 dev_dbg(&dev->dev, "%s: current resources:\n", desc);
71 if (res && !(res->flags & IORESOURCE_UNSET)) 90 list_for_each_entry(pnp_res, &dev->resources, list) {
72 dev_dbg(&dev->dev, " dma %lld flags %#lx\n", 91 res = &pnp_res->res;
73 (unsigned long long) res->start, res->flags); 92
93 len += snprintf(buf + len, sizeof(buf) - len, " %-3s ",
94 pnp_resource_type_name(res));
95
96 if (res->flags & IORESOURCE_DISABLED) {
97 dev_dbg(&dev->dev, "%sdisabled\n", buf);
98 continue;
99 }
100
101 switch (pnp_resource_type(res)) {
102 case IORESOURCE_IO:
103 case IORESOURCE_MEM:
104 len += snprintf(buf + len, sizeof(buf) - len,
105 "%#llx-%#llx flags %#lx",
106 (unsigned long long) res->start,
107 (unsigned long long) res->end,
108 res->flags);
109 break;
110 case IORESOURCE_IRQ:
111 case IORESOURCE_DMA:
112 len += snprintf(buf + len, sizeof(buf) - len,
113 "%lld flags %#lx",
114 (unsigned long long) res->start,
115 res->flags);
116 break;
117 }
118 dev_dbg(&dev->dev, "%s\n", buf);
74 } 119 }
75 for (i = 0; i < PNP_MAX_PORT; i++) { 120#endif
76 res = pnp_get_resource(dev, IORESOURCE_IO, i); 121}
77 if (res && !(res->flags & IORESOURCE_UNSET)) 122
78 dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n", 123char *pnp_option_priority_name(struct pnp_option *option)
79 (unsigned long long) res->start, 124{
80 (unsigned long long) res->end, res->flags); 125 switch (pnp_option_priority(option)) {
126 case PNP_RES_PRIORITY_PREFERRED:
127 return "preferred";
128 case PNP_RES_PRIORITY_ACCEPTABLE:
129 return "acceptable";
130 case PNP_RES_PRIORITY_FUNCTIONAL:
131 return "functional";
81 } 132 }
82 for (i = 0; i < PNP_MAX_MEM; i++) { 133 return "invalid";
83 res = pnp_get_resource(dev, IORESOURCE_MEM, i); 134}
84 if (res && !(res->flags & IORESOURCE_UNSET)) 135
85 dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n", 136void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
86 (unsigned long long) res->start, 137{
87 (unsigned long long) res->end, res->flags); 138#ifdef DEBUG
139 char buf[128];
140 int len = 0, i;
141 struct pnp_port *port;
142 struct pnp_mem *mem;
143 struct pnp_irq *irq;
144 struct pnp_dma *dma;
145
146 if (pnp_option_is_dependent(option))
147 len += snprintf(buf + len, sizeof(buf) - len,
148 " dependent set %d (%s) ",
149 pnp_option_set(option),
150 pnp_option_priority_name(option));
151 else
152 len += snprintf(buf + len, sizeof(buf) - len, " independent ");
153
154 switch (option->type) {
155 case IORESOURCE_IO:
156 port = &option->u.port;
157 len += snprintf(buf + len, sizeof(buf) - len, "io min %#llx "
158 "max %#llx align %lld size %lld flags %#x",
159 (unsigned long long) port->min,
160 (unsigned long long) port->max,
161 (unsigned long long) port->align,
162 (unsigned long long) port->size, port->flags);
163 break;
164 case IORESOURCE_MEM:
165 mem = &option->u.mem;
166 len += snprintf(buf + len, sizeof(buf) - len, "mem min %#llx "
167 "max %#llx align %lld size %lld flags %#x",
168 (unsigned long long) mem->min,
169 (unsigned long long) mem->max,
170 (unsigned long long) mem->align,
171 (unsigned long long) mem->size, mem->flags);
172 break;
173 case IORESOURCE_IRQ:
174 irq = &option->u.irq;
175 len += snprintf(buf + len, sizeof(buf) - len, "irq");
176 if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
177 len += snprintf(buf + len, sizeof(buf) - len,
178 " <none>");
179 else {
180 for (i = 0; i < PNP_IRQ_NR; i++)
181 if (test_bit(i, irq->map.bits))
182 len += snprintf(buf + len,
183 sizeof(buf) - len,
184 " %d", i);
185 }
186 len += snprintf(buf + len, sizeof(buf) - len, " flags %#x",
187 irq->flags);
188 if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
189 len += snprintf(buf + len, sizeof(buf) - len,
190 " (optional)");
191 break;
192 case IORESOURCE_DMA:
193 dma = &option->u.dma;
194 len += snprintf(buf + len, sizeof(buf) - len, "dma");
195 if (!dma->map)
196 len += snprintf(buf + len, sizeof(buf) - len,
197 " <none>");
198 else {
199 for (i = 0; i < 8; i++)
200 if (dma->map & (1 << i))
201 len += snprintf(buf + len,
202 sizeof(buf) - len,
203 " %d", i);
204 }
205 len += snprintf(buf + len, sizeof(buf) - len, " (bitmask %#x) "
206 "flags %#x", dma->map, dma->flags);
207 break;
88 } 208 }
209 dev_dbg(&dev->dev, "%s\n", buf);
89#endif 210#endif
90} 211}
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index cf4e07b01d48..764f3a310685 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -60,7 +60,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
60 int i; 60 int i;
61 61
62 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { 62 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
63 if (res->flags & IORESOURCE_UNSET) 63 if (res->flags & IORESOURCE_DISABLED)
64 continue; 64 continue;
65 if (res->start == 0) 65 if (res->start == 0)
66 continue; /* disabled */ 66 continue; /* disabled */
@@ -81,7 +81,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
81 } 81 }
82 82
83 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { 83 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
84 if (res->flags & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) 84 if (res->flags & IORESOURCE_DISABLED)
85 continue; 85 continue;
86 86
87 reserve_range(dev, res->start, res->end, 0); 87 reserve_range(dev, res->start, res->end, 0);