aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pnp/base.h18
-rw-r--r--drivers/pnp/core.c25
-rw-r--r--drivers/pnp/interface.c60
-rw-r--r--drivers/pnp/isapnp/core.c12
-rw-r--r--drivers/pnp/manager.c220
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c131
-rw-r--r--drivers/pnp/pnpbios/rsparser.c95
-rw-r--r--drivers/pnp/quirks.c3
-rw-r--r--drivers/pnp/resource.c86
-rw-r--r--drivers/pnp/support.c79
-rw-r--r--drivers/pnp/system.c4
-rw-r--r--include/linux/pnp.h20
12 files changed, 331 insertions, 422 deletions
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index c91315826da2..1667ac3ca45b 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -46,27 +46,15 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res);
46char *pnp_resource_type_name(struct resource *res); 46char *pnp_resource_type_name(struct resource *res);
47void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); 47void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
48 48
49void pnp_init_resource(struct resource *res); 49void pnp_free_resources(struct pnp_dev *dev);
50int pnp_resource_type(struct resource *res); 50int pnp_resource_type(struct resource *res);
51 51
52struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
53 unsigned int type, unsigned int num);
54
55#define PNP_MAX_PORT 40
56#define PNP_MAX_MEM 24
57#define PNP_MAX_IRQ 2
58#define PNP_MAX_DMA 2
59
60struct pnp_resource { 52struct pnp_resource {
53 struct list_head list;
61 struct resource res; 54 struct resource res;
62}; 55};
63 56
64struct pnp_resource_table { 57void pnp_free_resource(struct pnp_resource *pnp_res);
65 struct pnp_resource port[PNP_MAX_PORT];
66 struct pnp_resource mem[PNP_MAX_MEM];
67 struct pnp_resource dma[PNP_MAX_DMA];
68 struct pnp_resource irq[PNP_MAX_IRQ];
69};
70 58
71struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 59struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
72 int flags); 60 int flags);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 20771b7d4482..7182da92aec3 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -99,6 +99,21 @@ 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);
@@ -106,7 +121,7 @@ static void pnp_release_device(struct device *dmdev)
106 pnp_free_option(dev->independent); 121 pnp_free_option(dev->independent);
107 pnp_free_option(dev->dependent); 122 pnp_free_option(dev->dependent);
108 pnp_free_ids(dev); 123 pnp_free_ids(dev);
109 kfree(dev->res); 124 pnp_free_resources(dev);
110 kfree(dev); 125 kfree(dev);
111} 126}
112 127
@@ -119,12 +134,7 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
119 if (!dev) 134 if (!dev)
120 return NULL; 135 return NULL;
121 136
122 dev->res = kzalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); 137 INIT_LIST_HEAD(&dev->resources);
123 if (!dev->res) {
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 3f8007ab94e3..7fc86bbed88e 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -269,46 +269,38 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
269 pnp_printf(buffer, "disabled\n"); 269 pnp_printf(buffer, "disabled\n");
270 270
271 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { 271 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
272 if (pnp_resource_valid(res)) { 272 pnp_printf(buffer, "io");
273 pnp_printf(buffer, "io"); 273 if (res->flags & IORESOURCE_DISABLED)
274 if (res->flags & IORESOURCE_DISABLED) 274 pnp_printf(buffer, " disabled\n");
275 pnp_printf(buffer, " disabled\n"); 275 else
276 else 276 pnp_printf(buffer, " 0x%llx-0x%llx\n",
277 pnp_printf(buffer, " 0x%llx-0x%llx\n", 277 (unsigned long long) res->start,
278 (unsigned long long) res->start, 278 (unsigned long long) res->end);
279 (unsigned long long) res->end);
280 }
281 } 279 }
282 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { 280 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
283 if (pnp_resource_valid(res)) { 281 pnp_printf(buffer, "mem");
284 pnp_printf(buffer, "mem"); 282 if (res->flags & IORESOURCE_DISABLED)
285 if (res->flags & IORESOURCE_DISABLED) 283 pnp_printf(buffer, " disabled\n");
286 pnp_printf(buffer, " disabled\n"); 284 else
287 else 285 pnp_printf(buffer, " 0x%llx-0x%llx\n",
288 pnp_printf(buffer, " 0x%llx-0x%llx\n", 286 (unsigned long long) res->start,
289 (unsigned long long) res->start, 287 (unsigned long long) res->end);
290 (unsigned long long) res->end);
291 }
292 } 288 }
293 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) { 289 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
294 if (pnp_resource_valid(res)) { 290 pnp_printf(buffer, "irq");
295 pnp_printf(buffer, "irq"); 291 if (res->flags & IORESOURCE_DISABLED)
296 if (res->flags & IORESOURCE_DISABLED) 292 pnp_printf(buffer, " disabled\n");
297 pnp_printf(buffer, " disabled\n"); 293 else
298 else 294 pnp_printf(buffer, " %lld\n",
299 pnp_printf(buffer, " %lld\n", 295 (unsigned long long) res->start);
300 (unsigned long long) res->start);
301 }
302 } 296 }
303 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { 297 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
304 if (pnp_resource_valid(res)) { 298 pnp_printf(buffer, "dma");
305 pnp_printf(buffer, "dma"); 299 if (res->flags & IORESOURCE_DISABLED)
306 if (res->flags & IORESOURCE_DISABLED) 300 pnp_printf(buffer, " disabled\n");
307 pnp_printf(buffer, " disabled\n"); 301 else
308 else 302 pnp_printf(buffer, " %lld\n",
309 pnp_printf(buffer, " %lld\n", 303 (unsigned long long) res->start);
310 (unsigned long long) res->start);
311 }
312 } 304 }
313 ret = (buffer->curr - buf); 305 ret = (buffer->curr - buf);
314 kfree(buffer); 306 kfree(buffer);
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 752b51fbaa6c..ca4457ec403b 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -973,8 +973,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)
973 dev->active = 1; 973 dev->active = 1;
974 for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { 974 for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
975 res = pnp_get_resource(dev, IORESOURCE_IO, tmp); 975 res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
976 if (res && pnp_resource_valid(res) && 976 if (pnp_resource_enabled(res)) {
977 !(res->flags & IORESOURCE_DISABLED)) {
978 dev_dbg(&dev->dev, " set io %d to %#llx\n", 977 dev_dbg(&dev->dev, " set io %d to %#llx\n",
979 tmp, (unsigned long long) res->start); 978 tmp, (unsigned long long) res->start);
980 isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1), 979 isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
@@ -983,8 +982,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)
983 } 982 }
984 for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) { 983 for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
985 res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp); 984 res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp);
986 if (res && pnp_resource_valid(res) && 985 if (pnp_resource_enabled(res)) {
987 !(res->flags & IORESOURCE_DISABLED)) {
988 int irq = res->start; 986 int irq = res->start;
989 if (irq == 2) 987 if (irq == 2)
990 irq = 9; 988 irq = 9;
@@ -994,8 +992,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)
994 } 992 }
995 for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { 993 for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
996 res = pnp_get_resource(dev, IORESOURCE_DMA, tmp); 994 res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
997 if (res && pnp_resource_valid(res) && 995 if (pnp_resource_enabled(res)) {
998 !(res->flags & IORESOURCE_DISABLED)) {
999 dev_dbg(&dev->dev, " set dma %d to %lld\n", 996 dev_dbg(&dev->dev, " set dma %d to %lld\n",
1000 tmp, (unsigned long long) res->start); 997 tmp, (unsigned long long) res->start);
1001 isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start); 998 isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
@@ -1003,8 +1000,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)
1003 } 1000 }
1004 for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { 1001 for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
1005 res = pnp_get_resource(dev, IORESOURCE_MEM, tmp); 1002 res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
1006 if (res && pnp_resource_valid(res) && 1003 if (pnp_resource_enabled(res)) {
1007 !(res->flags & IORESOURCE_DISABLED)) {
1008 dev_dbg(&dev->dev, " set mem %d to %#llx\n", 1004 dev_dbg(&dev->dev, " set mem %d to %#llx\n",
1009 tmp, (unsigned long long) res->start); 1005 tmp, (unsigned long long) res->start);
1010 isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3), 1006 isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 90bd9cb65563..165b624081ad 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -19,40 +19,30 @@ DEFINE_MUTEX(pnp_res_mutex);
19 19
20static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) 20static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
21{ 21{
22 struct pnp_resource *pnp_res; 22 struct resource *res, local_res;
23 struct resource *res;
24 23
25 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, idx); 24 res = pnp_get_resource(dev, IORESOURCE_IO, idx);
26 if (!pnp_res) { 25 if (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
34 /* check if this resource has been manually set, if so skip */
35 if (!(res->flags & IORESOURCE_AUTO)) {
36 dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx " 26 dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
37 "flags %#lx\n", idx, (unsigned long long) res->start, 27 "flags %#lx\n", idx, (unsigned long long) res->start,
38 (unsigned long long) res->end, res->flags); 28 (unsigned long long) res->end, res->flags);
39 return 1; 29 return 1;
40 } 30 }
41 31
42 /* set the initial values */ 32 res = &local_res;
43 res->flags |= rule->flags | IORESOURCE_IO; 33 res->flags = rule->flags | IORESOURCE_AUTO;
44 res->flags &= ~IORESOURCE_UNSET; 34 res->start = 0;
35 res->end = 0;
45 36
46 if (!rule->size) { 37 if (!rule->size) {
47 res->flags |= IORESOURCE_DISABLED; 38 res->flags |= IORESOURCE_DISABLED;
48 dev_dbg(&dev->dev, " io %d disabled\n", idx); 39 dev_dbg(&dev->dev, " io %d disabled\n", idx);
49 return 1; /* skip disabled resource requests */ 40 goto __add;
50 } 41 }
51 42
52 res->start = rule->min; 43 res->start = rule->min;
53 res->end = res->start + rule->size - 1; 44 res->end = res->start + rule->size - 1;
54 45
55 /* run through until pnp_check_port is happy */
56 while (!pnp_check_port(dev, res)) { 46 while (!pnp_check_port(dev, res)) {
57 res->start += rule->align; 47 res->start += rule->align;
58 res->end = res->start + rule->size - 1; 48 res->end = res->start + rule->size - 1;
@@ -61,38 +51,29 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
61 return 0; 51 return 0;
62 } 52 }
63 } 53 }
64 dev_dbg(&dev->dev, " assign io %d %#llx-%#llx\n", idx, 54
65 (unsigned long long) res->start, (unsigned long long) res->end); 55__add:
56 pnp_add_io_resource(dev, res->start, res->end, res->flags);
66 return 1; 57 return 1;
67} 58}
68 59
69static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) 60static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
70{ 61{
71 struct pnp_resource *pnp_res; 62 struct resource *res, local_res;
72 struct resource *res;
73 63
74 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, idx); 64 res = pnp_get_resource(dev, IORESOURCE_MEM, idx);
75 if (!pnp_res) { 65 if (res) {
76 dev_err(&dev->dev, "too many memory resources\n");
77 /* pretend we were successful so at least the manager won't try again */
78 return 1;
79 }
80
81 res = &pnp_res->res;
82
83 /* check if this resource has been manually set, if so skip */
84 if (!(res->flags & IORESOURCE_AUTO)) {
85 dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " 66 dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
86 "flags %#lx\n", idx, (unsigned long long) res->start, 67 "flags %#lx\n", idx, (unsigned long long) res->start,
87 (unsigned long long) res->end, res->flags); 68 (unsigned long long) res->end, res->flags);
88 return 1; 69 return 1;
89 } 70 }
90 71
91 /* set the initial values */ 72 res = &local_res;
92 res->flags |= rule->flags | IORESOURCE_MEM; 73 res->flags = rule->flags | IORESOURCE_AUTO;
93 res->flags &= ~IORESOURCE_UNSET; 74 res->start = 0;
75 res->end = 0;
94 76
95 /* convert pnp flags to standard Linux flags */
96 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) 77 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
97 res->flags |= IORESOURCE_READONLY; 78 res->flags |= IORESOURCE_READONLY;
98 if (rule->flags & IORESOURCE_MEM_CACHEABLE) 79 if (rule->flags & IORESOURCE_MEM_CACHEABLE)
@@ -105,13 +86,12 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
105 if (!rule->size) { 86 if (!rule->size) {
106 res->flags |= IORESOURCE_DISABLED; 87 res->flags |= IORESOURCE_DISABLED;
107 dev_dbg(&dev->dev, " mem %d disabled\n", idx); 88 dev_dbg(&dev->dev, " mem %d disabled\n", idx);
108 return 1; /* skip disabled resource requests */ 89 goto __add;
109 } 90 }
110 91
111 res->start = rule->min; 92 res->start = rule->min;
112 res->end = res->start + rule->size - 1; 93 res->end = res->start + rule->size - 1;
113 94
114 /* run through until pnp_check_mem is happy */
115 while (!pnp_check_mem(dev, res)) { 95 while (!pnp_check_mem(dev, res)) {
116 res->start += rule->align; 96 res->start += rule->align;
117 res->end = res->start + rule->size - 1; 97 res->end = res->start + rule->size - 1;
@@ -120,15 +100,15 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
120 return 0; 100 return 0;
121 } 101 }
122 } 102 }
123 dev_dbg(&dev->dev, " assign mem %d %#llx-%#llx\n", idx, 103
124 (unsigned long long) res->start, (unsigned long long) res->end); 104__add:
105 pnp_add_mem_resource(dev, res->start, res->end, res->flags);
125 return 1; 106 return 1;
126} 107}
127 108
128static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) 109static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
129{ 110{
130 struct pnp_resource *pnp_res; 111 struct resource *res, local_res;
131 struct resource *res;
132 int i; 112 int i;
133 113
134 /* IRQ priority: this table is good for i386 */ 114 /* IRQ priority: this table is good for i386 */
@@ -136,58 +116,48 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
136 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 116 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
137 }; 117 };
138 118
139 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, idx); 119 res = pnp_get_resource(dev, IORESOURCE_IRQ, idx);
140 if (!pnp_res) { 120 if (res) {
141 dev_err(&dev->dev, "too many IRQ resources\n");
142 /* pretend we were successful so at least the manager won't try again */
143 return 1;
144 }
145
146 res = &pnp_res->res;
147
148 /* check if this resource has been manually set, if so skip */
149 if (!(res->flags & IORESOURCE_AUTO)) {
150 dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", 121 dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
151 idx, (int) res->start, res->flags); 122 idx, (int) res->start, res->flags);
152 return 1; 123 return 1;
153 } 124 }
154 125
155 /* set the initial values */ 126 res = &local_res;
156 res->flags |= rule->flags | IORESOURCE_IRQ; 127 res->flags = rule->flags | IORESOURCE_AUTO;
157 res->flags &= ~IORESOURCE_UNSET; 128 res->start = -1;
129 res->end = -1;
158 130
159 if (bitmap_empty(rule->map, PNP_IRQ_NR)) { 131 if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
160 res->flags |= IORESOURCE_DISABLED; 132 res->flags |= IORESOURCE_DISABLED;
161 dev_dbg(&dev->dev, " irq %d disabled\n", idx); 133 dev_dbg(&dev->dev, " irq %d disabled\n", idx);
162 return 1; /* skip disabled resource requests */ 134 goto __add;
163 } 135 }
164 136
165 /* TBD: need check for >16 IRQ */ 137 /* TBD: need check for >16 IRQ */
166 res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16); 138 res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
167 if (res->start < PNP_IRQ_NR) { 139 if (res->start < PNP_IRQ_NR) {
168 res->end = res->start; 140 res->end = res->start;
169 dev_dbg(&dev->dev, " assign irq %d %d\n", idx, 141 goto __add;
170 (int) res->start);
171 return 1;
172 } 142 }
173 for (i = 0; i < 16; i++) { 143 for (i = 0; i < 16; i++) {
174 if (test_bit(xtab[i], rule->map)) { 144 if (test_bit(xtab[i], rule->map)) {
175 res->start = res->end = xtab[i]; 145 res->start = res->end = xtab[i];
176 if (pnp_check_irq(dev, res)) { 146 if (pnp_check_irq(dev, res))
177 dev_dbg(&dev->dev, " assign irq %d %d\n", idx, 147 goto __add;
178 (int) res->start);
179 return 1;
180 }
181 } 148 }
182 } 149 }
183 dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); 150 dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx);
184 return 0; 151 return 0;
152
153__add:
154 pnp_add_irq_resource(dev, res->start, res->flags);
155 return 1;
185} 156}
186 157
187static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) 158static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
188{ 159{
189 struct pnp_resource *pnp_res; 160 struct resource *res, local_res;
190 struct resource *res;
191 int i; 161 int i;
192 162
193 /* DMA priority: this table is good for i386 */ 163 /* DMA priority: this table is good for i386 */
@@ -195,127 +165,47 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
195 1, 3, 5, 6, 7, 0, 2, 4 165 1, 3, 5, 6, 7, 0, 2, 4
196 }; 166 };
197 167
198 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx); 168 res = pnp_get_resource(dev, IORESOURCE_DMA, idx);
199 if (!pnp_res) { 169 if (res) {
200 dev_err(&dev->dev, "too many DMA resources\n");
201 return;
202 }
203
204 res = &pnp_res->res;
205
206 /* check if this resource has been manually set, if so skip */
207 if (!(res->flags & IORESOURCE_AUTO)) {
208 dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", 170 dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
209 idx, (int) res->start, res->flags); 171 idx, (int) res->start, res->flags);
210 return; 172 return;
211 } 173 }
212 174
213 /* set the initial values */ 175 res = &local_res;
214 res->flags |= rule->flags | IORESOURCE_DMA; 176 res->flags = rule->flags | IORESOURCE_AUTO;
215 res->flags &= ~IORESOURCE_UNSET; 177 res->start = -1;
178 res->end = -1;
216 179
217 for (i = 0; i < 8; i++) { 180 for (i = 0; i < 8; i++) {
218 if (rule->map & (1 << xtab[i])) { 181 if (rule->map & (1 << xtab[i])) {
219 res->start = res->end = xtab[i]; 182 res->start = res->end = xtab[i];
220 if (pnp_check_dma(dev, res)) { 183 if (pnp_check_dma(dev, res))
221 dev_dbg(&dev->dev, " assign dma %d %d\n", idx, 184 goto __add;
222 (int) res->start);
223 return;
224 }
225 } 185 }
226 } 186 }
227#ifdef MAX_DMA_CHANNELS 187#ifdef MAX_DMA_CHANNELS
228 res->start = res->end = MAX_DMA_CHANNELS; 188 res->start = res->end = MAX_DMA_CHANNELS;
229#endif 189#endif
230 res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; 190 res->flags |= IORESOURCE_DISABLED;
231 dev_dbg(&dev->dev, " disable dma %d\n", idx); 191 dev_dbg(&dev->dev, " disable dma %d\n", idx);
232}
233 192
234void pnp_init_resource(struct resource *res) 193__add:
235{ 194 pnp_add_dma_resource(dev, res->start, res->flags);
236 unsigned long type;
237
238 type = res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
239 IORESOURCE_IRQ | IORESOURCE_DMA);
240
241 res->name = NULL;
242 res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET;
243 if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) {
244 res->start = -1;
245 res->end = -1;
246 } else {
247 res->start = 0;
248 res->end = 0;
249 }
250} 195}
251 196
252/**
253 * pnp_init_resources - Resets a resource table to default values.
254 * @table: pointer to the desired resource table
255 */
256void pnp_init_resources(struct pnp_dev *dev) 197void pnp_init_resources(struct pnp_dev *dev)
257{ 198{
258 struct resource *res; 199 pnp_free_resources(dev);
259 int idx;
260
261 for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
262 res = &dev->res->irq[idx].res;
263 res->flags = IORESOURCE_IRQ;
264 pnp_init_resource(res);
265 }
266 for (idx = 0; idx < PNP_MAX_DMA; idx++) {
267 res = &dev->res->dma[idx].res;
268 res->flags = IORESOURCE_DMA;
269 pnp_init_resource(res);
270 }
271 for (idx = 0; idx < PNP_MAX_PORT; idx++) {
272 res = &dev->res->port[idx].res;
273 res->flags = IORESOURCE_IO;
274 pnp_init_resource(res);
275 }
276 for (idx = 0; idx < PNP_MAX_MEM; idx++) {
277 res = &dev->res->mem[idx].res;
278 res->flags = IORESOURCE_MEM;
279 pnp_init_resource(res);
280 }
281} 200}
282 201
283/**
284 * pnp_clean_resources - clears resources that were not manually set
285 * @res: the resources to clean
286 */
287static void pnp_clean_resource_table(struct pnp_dev *dev) 202static void pnp_clean_resource_table(struct pnp_dev *dev)
288{ 203{
289 struct resource *res; 204 struct pnp_resource *pnp_res, *tmp;
290 int idx; 205
291 206 list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) {
292 for (idx = 0; idx < PNP_MAX_IRQ; idx++) { 207 if (pnp_res->res.flags & IORESOURCE_AUTO)
293 res = &dev->res->irq[idx].res; 208 pnp_free_resource(pnp_res);
294 if (res->flags & IORESOURCE_AUTO) {
295 res->flags = IORESOURCE_IRQ;
296 pnp_init_resource(res);
297 }
298 }
299 for (idx = 0; idx < PNP_MAX_DMA; idx++) {
300 res = &dev->res->dma[idx].res;
301 if (res->flags & IORESOURCE_AUTO) {
302 res->flags = IORESOURCE_DMA;
303 pnp_init_resource(res);
304 }
305 }
306 for (idx = 0; idx < PNP_MAX_PORT; idx++) {
307 res = &dev->res->port[idx].res;
308 if (res->flags & IORESOURCE_AUTO) {
309 res->flags = IORESOURCE_IO;
310 pnp_init_resource(res);
311 }
312 }
313 for (idx = 0; idx < PNP_MAX_MEM; idx++) {
314 res = &dev->res->mem[idx].res;
315 if (res->flags & IORESOURCE_AUTO) {
316 res->flags = IORESOURCE_MEM;
317 pnp_init_resource(res);
318 }
319 } 209 }
320} 210}
321 211
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 46c791adb894..9a45c25b46d2 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -806,6 +806,13 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
806 struct acpi_resource_irq *irq = &resource->data.irq; 806 struct acpi_resource_irq *irq = &resource->data.irq;
807 int triggering, polarity, shareable; 807 int triggering, polarity, shareable;
808 808
809 if (!pnp_resource_enabled(p)) {
810 irq->interrupt_count = 0;
811 dev_dbg(&dev->dev, " encode irq (%s)\n",
812 p ? "disabled" : "missing");
813 return;
814 }
815
809 decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); 816 decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
810 irq->triggering = triggering; 817 irq->triggering = triggering;
811 irq->polarity = polarity; 818 irq->polarity = polarity;
@@ -828,6 +835,13 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
828 struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; 835 struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
829 int triggering, polarity, shareable; 836 int triggering, polarity, shareable;
830 837
838 if (!pnp_resource_enabled(p)) {
839 extended_irq->interrupt_count = 0;
840 dev_dbg(&dev->dev, " encode extended irq (%s)\n",
841 p ? "disabled" : "missing");
842 return;
843 }
844
831 decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); 845 decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
832 extended_irq->producer_consumer = ACPI_CONSUMER; 846 extended_irq->producer_consumer = ACPI_CONSUMER;
833 extended_irq->triggering = triggering; 847 extended_irq->triggering = triggering;
@@ -848,6 +862,13 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev,
848{ 862{
849 struct acpi_resource_dma *dma = &resource->data.dma; 863 struct acpi_resource_dma *dma = &resource->data.dma;
850 864
865 if (!pnp_resource_enabled(p)) {
866 dma->channel_count = 0;
867 dev_dbg(&dev->dev, " encode dma (%s)\n",
868 p ? "disabled" : "missing");
869 return;
870 }
871
851 /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ 872 /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
852 switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { 873 switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
853 case IORESOURCE_DMA_TYPEA: 874 case IORESOURCE_DMA_TYPEA:
@@ -889,17 +910,21 @@ static void pnpacpi_encode_io(struct pnp_dev *dev,
889{ 910{
890 struct acpi_resource_io *io = &resource->data.io; 911 struct acpi_resource_io *io = &resource->data.io;
891 912
892 /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ 913 if (pnp_resource_enabled(p)) {
893 io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ? 914 /* Note: pnp_assign_port copies pnp_port->flags into p->flags */
894 ACPI_DECODE_16 : ACPI_DECODE_10; 915 io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
895 io->minimum = p->start; 916 ACPI_DECODE_16 : ACPI_DECODE_10;
896 io->maximum = p->end; 917 io->minimum = p->start;
897 io->alignment = 0; /* Correct? */ 918 io->maximum = p->end;
898 io->address_length = p->end - p->start + 1; 919 io->alignment = 0; /* Correct? */
899 920 io->address_length = p->end - p->start + 1;
900 dev_dbg(&dev->dev, " encode io %#llx-%#llx decode %#x\n", 921 } else {
901 (unsigned long long) p->start, (unsigned long long) p->end, 922 io->minimum = 0;
902 io->io_decode); 923 io->address_length = 0;
924 }
925
926 dev_dbg(&dev->dev, " encode io %#x-%#x decode %#x\n", io->minimum,
927 io->minimum + io->address_length - 1, io->io_decode);
903} 928}
904 929
905static void pnpacpi_encode_fixed_io(struct pnp_dev *dev, 930static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
@@ -908,11 +933,16 @@ static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
908{ 933{
909 struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io; 934 struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;
910 935
911 fixed_io->address = p->start; 936 if (pnp_resource_enabled(p)) {
912 fixed_io->address_length = p->end - p->start + 1; 937 fixed_io->address = p->start;
938 fixed_io->address_length = p->end - p->start + 1;
939 } else {
940 fixed_io->address = 0;
941 fixed_io->address_length = 0;
942 }
913 943
914 dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n", 944 dev_dbg(&dev->dev, " encode fixed_io %#x-%#x\n", fixed_io->address,
915 (unsigned long long) p->start, (unsigned long long) p->end); 945 fixed_io->address + fixed_io->address_length - 1);
916} 946}
917 947
918static void pnpacpi_encode_mem24(struct pnp_dev *dev, 948static void pnpacpi_encode_mem24(struct pnp_dev *dev,
@@ -921,17 +951,22 @@ static void pnpacpi_encode_mem24(struct pnp_dev *dev,
921{ 951{
922 struct acpi_resource_memory24 *memory24 = &resource->data.memory24; 952 struct acpi_resource_memory24 *memory24 = &resource->data.memory24;
923 953
924 /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ 954 if (pnp_resource_enabled(p)) {
925 memory24->write_protect = 955 /* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */
926 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 956 memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
927 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 957 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
928 memory24->minimum = p->start; 958 memory24->minimum = p->start;
929 memory24->maximum = p->end; 959 memory24->maximum = p->end;
930 memory24->alignment = 0; 960 memory24->alignment = 0;
931 memory24->address_length = p->end - p->start + 1; 961 memory24->address_length = p->end - p->start + 1;
932 962 } else {
933 dev_dbg(&dev->dev, " encode mem24 %#llx-%#llx write_protect %#x\n", 963 memory24->minimum = 0;
934 (unsigned long long) p->start, (unsigned long long) p->end, 964 memory24->address_length = 0;
965 }
966
967 dev_dbg(&dev->dev, " encode mem24 %#x-%#x write_protect %#x\n",
968 memory24->minimum,
969 memory24->minimum + memory24->address_length - 1,
935 memory24->write_protect); 970 memory24->write_protect);
936} 971}
937 972
@@ -941,16 +976,21 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev,
941{ 976{
942 struct acpi_resource_memory32 *memory32 = &resource->data.memory32; 977 struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
943 978
944 memory32->write_protect = 979 if (pnp_resource_enabled(p)) {
945 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 980 memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
946 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 981 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
947 memory32->minimum = p->start; 982 memory32->minimum = p->start;
948 memory32->maximum = p->end; 983 memory32->maximum = p->end;
949 memory32->alignment = 0; 984 memory32->alignment = 0;
950 memory32->address_length = p->end - p->start + 1; 985 memory32->address_length = p->end - p->start + 1;
986 } else {
987 memory32->minimum = 0;
988 memory32->alignment = 0;
989 }
951 990
952 dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx write_protect %#x\n", 991 dev_dbg(&dev->dev, " encode mem32 %#x-%#x write_protect %#x\n",
953 (unsigned long long) p->start, (unsigned long long) p->end, 992 memory32->minimum,
993 memory32->minimum + memory32->address_length - 1,
954 memory32->write_protect); 994 memory32->write_protect);
955} 995}
956 996
@@ -960,15 +1000,20 @@ static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
960{ 1000{
961 struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32; 1001 struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;
962 1002
963 fixed_memory32->write_protect = 1003 if (pnp_resource_enabled(p)) {
964 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 1004 fixed_memory32->write_protect =
965 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 1005 p->flags & IORESOURCE_MEM_WRITEABLE ?
966 fixed_memory32->address = p->start; 1006 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
967 fixed_memory32->address_length = p->end - p->start + 1; 1007 fixed_memory32->address = p->start;
1008 fixed_memory32->address_length = p->end - p->start + 1;
1009 } else {
1010 fixed_memory32->address = 0;
1011 fixed_memory32->address_length = 0;
1012 }
968 1013
969 dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx " 1014 dev_dbg(&dev->dev, " encode fixed_mem32 %#x-%#x write_protect %#x\n",
970 "write_protect %#x\n", 1015 fixed_memory32->address,
971 (unsigned long long) p->start, (unsigned long long) p->end, 1016 fixed_memory32->address + fixed_memory32->address_length - 1,
972 fixed_memory32->write_protect); 1017 fixed_memory32->write_protect);
973} 1018}
974 1019
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 5ff9a4c0447e..01f0c3dd1b08 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -526,8 +526,16 @@ len_err:
526static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p, 526static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
527 struct resource *res) 527 struct resource *res)
528{ 528{
529 unsigned long base = res->start; 529 unsigned long base;
530 unsigned long len = res->end - res->start + 1; 530 unsigned long len;
531
532 if (pnp_resource_enabled(res)) {
533 base = res->start;
534 len = res->end - res->start + 1;
535 } else {
536 base = 0;
537 len = 0;
538 }
531 539
532 p[4] = (base >> 8) & 0xff; 540 p[4] = (base >> 8) & 0xff;
533 p[5] = ((base >> 8) >> 8) & 0xff; 541 p[5] = ((base >> 8) >> 8) & 0xff;
@@ -536,15 +544,22 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
536 p[10] = (len >> 8) & 0xff; 544 p[10] = (len >> 8) & 0xff;
537 p[11] = ((len >> 8) >> 8) & 0xff; 545 p[11] = ((len >> 8) >> 8) & 0xff;
538 546
539 dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n", 547 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} 548}
542 549
543static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, 550static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
544 struct resource *res) 551 struct resource *res)
545{ 552{
546 unsigned long base = res->start; 553 unsigned long base;
547 unsigned long len = res->end - res->start + 1; 554 unsigned long len;
555
556 if (pnp_resource_enabled(res)) {
557 base = res->start;
558 len = res->end - res->start + 1;
559 } else {
560 base = 0;
561 len = 0;
562 }
548 563
549 p[4] = base & 0xff; 564 p[4] = base & 0xff;
550 p[5] = (base >> 8) & 0xff; 565 p[5] = (base >> 8) & 0xff;
@@ -559,15 +574,22 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
559 p[18] = (len >> 16) & 0xff; 574 p[18] = (len >> 16) & 0xff;
560 p[19] = (len >> 24) & 0xff; 575 p[19] = (len >> 24) & 0xff;
561 576
562 dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n", 577 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} 578}
565 579
566static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, 580static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
567 struct resource *res) 581 struct resource *res)
568{ 582{
569 unsigned long base = res->start; 583 unsigned long base;
570 unsigned long len = res->end - res->start + 1; 584 unsigned long len;
585
586 if (pnp_resource_enabled(res)) {
587 base = res->start;
588 len = res->end - res->start + 1;
589 } else {
590 base = 0;
591 len = 0;
592 }
571 593
572 p[4] = base & 0xff; 594 p[4] = base & 0xff;
573 p[5] = (base >> 8) & 0xff; 595 p[5] = (base >> 8) & 0xff;
@@ -578,40 +600,54 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
578 p[10] = (len >> 16) & 0xff; 600 p[10] = (len >> 16) & 0xff;
579 p[11] = (len >> 24) & 0xff; 601 p[11] = (len >> 24) & 0xff;
580 602
581 dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n", 603 dev_dbg(&dev->dev, " encode fixed_mem32 %#lx-%#lx\n", base,
582 (unsigned long long) res->start, (unsigned long long) res->end); 604 base + len - 1);
583} 605}
584 606
585static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p, 607static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
586 struct resource *res) 608 struct resource *res)
587{ 609{
588 unsigned long map = 0; 610 unsigned long map;
611
612 if (pnp_resource_enabled(res))
613 map = 1 << res->start;
614 else
615 map = 0;
589 616
590 map = 1 << res->start;
591 p[1] = map & 0xff; 617 p[1] = map & 0xff;
592 p[2] = (map >> 8) & 0xff; 618 p[2] = (map >> 8) & 0xff;
593 619
594 dev_dbg(&dev->dev, " encode irq %llu\n", 620 dev_dbg(&dev->dev, " encode irq mask %#lx\n", map);
595 (unsigned long long)res->start);
596} 621}
597 622
598static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, 623static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
599 struct resource *res) 624 struct resource *res)
600{ 625{
601 unsigned long map = 0; 626 unsigned long map;
627
628 if (pnp_resource_enabled(res))
629 map = 1 << res->start;
630 else
631 map = 0;
602 632
603 map = 1 << res->start;
604 p[1] = map & 0xff; 633 p[1] = map & 0xff;
605 634
606 dev_dbg(&dev->dev, " encode dma %llu\n", 635 dev_dbg(&dev->dev, " encode dma mask %#lx\n", map);
607 (unsigned long long)res->start);
608} 636}
609 637
610static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, 638static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
611 struct resource *res) 639 struct resource *res)
612{ 640{
613 unsigned long base = res->start; 641 unsigned long base;
614 unsigned long len = res->end - res->start + 1; 642 unsigned long len;
643
644 if (pnp_resource_enabled(res)) {
645 base = res->start;
646 len = res->end - res->start + 1;
647 } else {
648 base = 0;
649 len = 0;
650 }
615 651
616 p[2] = base & 0xff; 652 p[2] = base & 0xff;
617 p[3] = (base >> 8) & 0xff; 653 p[3] = (base >> 8) & 0xff;
@@ -619,8 +655,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
619 p[5] = (base >> 8) & 0xff; 655 p[5] = (base >> 8) & 0xff;
620 p[7] = len & 0xff; 656 p[7] = len & 0xff;
621 657
622 dev_dbg(&dev->dev, " encode io %#llx-%#llx\n", 658 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} 659}
625 660
626static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, 661static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
@@ -629,12 +664,20 @@ static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
629 unsigned long base = res->start; 664 unsigned long base = res->start;
630 unsigned long len = res->end - res->start + 1; 665 unsigned long len = res->end - res->start + 1;
631 666
667 if (pnp_resource_enabled(res)) {
668 base = res->start;
669 len = res->end - res->start + 1;
670 } else {
671 base = 0;
672 len = 0;
673 }
674
632 p[1] = base & 0xff; 675 p[1] = base & 0xff;
633 p[2] = (base >> 8) & 0xff; 676 p[2] = (base >> 8) & 0xff;
634 p[3] = len & 0xff; 677 p[3] = len & 0xff;
635 678
636 dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n", 679 dev_dbg(&dev->dev, " encode fixed_io %#lx-%#lx\n", base,
637 (unsigned long long) res->start, (unsigned long long) res->end); 680 base + len - 1);
638} 681}
639 682
640static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev 683static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 1ff3bb585ab2..21acb54eff6d 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -248,8 +248,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
248 for (j = 0; 248 for (j = 0;
249 (res = pnp_get_resource(dev, IORESOURCE_MEM, j)); 249 (res = pnp_get_resource(dev, IORESOURCE_MEM, j));
250 j++) { 250 j++) {
251 if (res->flags & IORESOURCE_UNSET || 251 if (res->start == 0 && res->end == 0)
252 (res->start == 0 && res->end == 0))
253 continue; 252 continue;
254 253
255 pnp_start = res->start; 254 pnp_start = res->start;
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index cce341f743d4..0797a77bd042 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -237,7 +237,7 @@ void pnp_free_option(struct pnp_option *option)
237 !((*(enda) < *(startb)) || (*(endb) < *(starta))) 237 !((*(enda) < *(startb)) || (*(endb) < *(starta)))
238 238
239#define cannot_compare(flags) \ 239#define cannot_compare(flags) \
240((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) 240((flags) & IORESOURCE_DISABLED)
241 241
242int pnp_check_port(struct pnp_dev *dev, struct resource *res) 242int pnp_check_port(struct pnp_dev *dev, struct resource *res)
243{ 243{
@@ -505,81 +505,31 @@ int pnp_resource_type(struct resource *res)
505 IORESOURCE_IRQ | IORESOURCE_DMA); 505 IORESOURCE_IRQ | IORESOURCE_DMA);
506} 506}
507 507
508struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
509 unsigned int type, unsigned int num)
510{
511 struct pnp_resource_table *res = dev->res;
512
513 switch (type) {
514 case IORESOURCE_IO:
515 if (num >= PNP_MAX_PORT)
516 return NULL;
517 return &res->port[num];
518 case IORESOURCE_MEM:
519 if (num >= PNP_MAX_MEM)
520 return NULL;
521 return &res->mem[num];
522 case IORESOURCE_IRQ:
523 if (num >= PNP_MAX_IRQ)
524 return NULL;
525 return &res->irq[num];
526 case IORESOURCE_DMA:
527 if (num >= PNP_MAX_DMA)
528 return NULL;
529 return &res->dma[num];
530 }
531 return NULL;
532}
533
534struct resource *pnp_get_resource(struct pnp_dev *dev, 508struct resource *pnp_get_resource(struct pnp_dev *dev,
535 unsigned int type, unsigned int num) 509 unsigned int type, unsigned int num)
536{ 510{
537 struct pnp_resource *pnp_res; 511 struct pnp_resource *pnp_res;
512 struct resource *res;
538 513
539 pnp_res = pnp_get_pnp_resource(dev, type, num); 514 list_for_each_entry(pnp_res, &dev->resources, list) {
540 if (pnp_res) 515 res = &pnp_res->res;
541 return &pnp_res->res; 516 if (pnp_resource_type(res) == type && num-- == 0)
542 517 return res;
518 }
543 return NULL; 519 return NULL;
544} 520}
545EXPORT_SYMBOL(pnp_get_resource); 521EXPORT_SYMBOL(pnp_get_resource);
546 522
547static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type) 523static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev)
548{ 524{
549 struct pnp_resource *pnp_res; 525 struct pnp_resource *pnp_res;
550 int i;
551 526
552 switch (type) { 527 pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL);
553 case IORESOURCE_IO: 528 if (!pnp_res)
554 for (i = 0; i < PNP_MAX_PORT; i++) { 529 return NULL;
555 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i); 530
556 if (pnp_res && !pnp_resource_valid(&pnp_res->res)) 531 list_add_tail(&pnp_res->list, &dev->resources);
557 return pnp_res; 532 return pnp_res;
558 }
559 break;
560 case IORESOURCE_MEM:
561 for (i = 0; i < PNP_MAX_MEM; i++) {
562 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, i);
563 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
564 return pnp_res;
565 }
566 break;
567 case IORESOURCE_IRQ:
568 for (i = 0; i < PNP_MAX_IRQ; i++) {
569 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, i);
570 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
571 return pnp_res;
572 }
573 break;
574 case IORESOURCE_DMA:
575 for (i = 0; i < PNP_MAX_DMA; i++) {
576 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, i);
577 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
578 return pnp_res;
579 }
580 break;
581 }
582 return NULL;
583} 533}
584 534
585struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 535struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
@@ -589,7 +539,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
589 struct resource *res; 539 struct resource *res;
590 static unsigned char warned; 540 static unsigned char warned;
591 541
592 pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ); 542 pnp_res = pnp_new_resource(dev);
593 if (!pnp_res) { 543 if (!pnp_res) {
594 if (!warned) { 544 if (!warned) {
595 dev_err(&dev->dev, "can't add resource for IRQ %d\n", 545 dev_err(&dev->dev, "can't add resource for IRQ %d\n",
@@ -615,7 +565,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
615 struct resource *res; 565 struct resource *res;
616 static unsigned char warned; 566 static unsigned char warned;
617 567
618 pnp_res = pnp_new_resource(dev, IORESOURCE_DMA); 568 pnp_res = pnp_new_resource(dev);
619 if (!pnp_res) { 569 if (!pnp_res) {
620 if (!warned) { 570 if (!warned) {
621 dev_err(&dev->dev, "can't add resource for DMA %d\n", 571 dev_err(&dev->dev, "can't add resource for DMA %d\n",
@@ -642,7 +592,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
642 struct resource *res; 592 struct resource *res;
643 static unsigned char warned; 593 static unsigned char warned;
644 594
645 pnp_res = pnp_new_resource(dev, IORESOURCE_IO); 595 pnp_res = pnp_new_resource(dev);
646 if (!pnp_res) { 596 if (!pnp_res) {
647 if (!warned) { 597 if (!warned) {
648 dev_err(&dev->dev, "can't add resource for IO " 598 dev_err(&dev->dev, "can't add resource for IO "
@@ -671,7 +621,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
671 struct resource *res; 621 struct resource *res;
672 static unsigned char warned; 622 static unsigned char warned;
673 623
674 pnp_res = pnp_new_resource(dev, IORESOURCE_MEM); 624 pnp_res = pnp_new_resource(dev);
675 if (!pnp_res) { 625 if (!pnp_res) {
676 if (!warned) { 626 if (!warned) {
677 dev_err(&dev->dev, "can't add resource for MEM " 627 dev_err(&dev->dev, "can't add resource for MEM "
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index eb07345f5cf7..1566e4a73849 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -16,6 +16,10 @@
16 */ 16 */
17int pnp_is_active(struct pnp_dev *dev) 17int pnp_is_active(struct pnp_dev *dev)
18{ 18{
19 /*
20 * I don't think this is very reliable because pnp_disable_dev()
21 * only clears out auto-assigned resources.
22 */
19 if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 && 23 if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 &&
20 !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 && 24 !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 &&
21 pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1) 25 pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1)
@@ -70,54 +74,41 @@ char *pnp_resource_type_name(struct resource *res)
70void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) 74void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
71{ 75{
72#ifdef DEBUG 76#ifdef DEBUG
77 char buf[128];
78 int len = 0;
79 struct pnp_resource *pnp_res;
73 struct resource *res; 80 struct resource *res;
74 int i;
75 81
76 dev_dbg(&dev->dev, "current resources: %s\n", desc); 82 dev_dbg(&dev->dev, "current resources: %s\n", desc);
83 list_for_each_entry(pnp_res, &dev->resources, list) {
84 res = &pnp_res->res;
77 85
78 for (i = 0; i < PNP_MAX_IRQ; i++) { 86 len += snprintf(buf + len, sizeof(buf) - len, " %-3s ",
79 res = pnp_get_resource(dev, IORESOURCE_IRQ, i); 87 pnp_resource_type_name(res));
80 if (res && !(res->flags & IORESOURCE_UNSET)) 88
81 dev_dbg(&dev->dev, " irq %lld flags %#lx%s%s\n", 89 if (res->flags & IORESOURCE_DISABLED) {
82 (unsigned long long) res->start, res->flags, 90 dev_dbg(&dev->dev, "%sdisabled\n", buf);
83 res->flags & IORESOURCE_DISABLED ? 91 continue;
84 " DISABLED" : "", 92 }
85 res->flags & IORESOURCE_AUTO ? 93
86 " AUTO" : ""); 94 switch (pnp_resource_type(res)) {
87 } 95 case IORESOURCE_IO:
88 for (i = 0; i < PNP_MAX_DMA; i++) { 96 case IORESOURCE_MEM:
89 res = pnp_get_resource(dev, IORESOURCE_DMA, i); 97 len += snprintf(buf + len, sizeof(buf) - len,
90 if (res && !(res->flags & IORESOURCE_UNSET)) 98 "%#llx-%#llx flags %#lx",
91 dev_dbg(&dev->dev, " dma %lld flags %#lx%s%s\n", 99 (unsigned long long) res->start,
92 (unsigned long long) res->start, res->flags, 100 (unsigned long long) res->end,
93 res->flags & IORESOURCE_DISABLED ? 101 res->flags);
94 " DISABLED" : "", 102 break;
95 res->flags & IORESOURCE_AUTO ? 103 case IORESOURCE_IRQ:
96 " AUTO" : ""); 104 case IORESOURCE_DMA:
97 } 105 len += snprintf(buf + len, sizeof(buf) - len,
98 for (i = 0; i < PNP_MAX_PORT; i++) { 106 "%lld flags %#lx",
99 res = pnp_get_resource(dev, IORESOURCE_IO, i); 107 (unsigned long long) res->start,
100 if (res && !(res->flags & IORESOURCE_UNSET)) 108 res->flags);
101 dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx" 109 break;
102 "%s%s\n", 110 }
103 (unsigned long long) res->start, 111 dev_dbg(&dev->dev, "%s\n", buf);
104 (unsigned long long) res->end, res->flags,
105 res->flags & IORESOURCE_DISABLED ?
106 " DISABLED" : "",
107 res->flags & IORESOURCE_AUTO ?
108 " AUTO" : "");
109 }
110 for (i = 0; i < PNP_MAX_MEM; i++) {
111 res = pnp_get_resource(dev, IORESOURCE_MEM, i);
112 if (res && !(res->flags & IORESOURCE_UNSET))
113 dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx"
114 "%s%s\n",
115 (unsigned long long) res->start,
116 (unsigned long long) res->end, res->flags,
117 res->flags & IORESOURCE_DISABLED ?
118 " DISABLED" : "",
119 res->flags & IORESOURCE_AUTO ?
120 " AUTO" : "");
121 } 112 }
122#endif 113#endif
123} 114}
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);
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 8b607aecd959..dfaa567e04a8 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -15,7 +15,6 @@
15 15
16struct pnp_protocol; 16struct pnp_protocol;
17struct pnp_dev; 17struct pnp_dev;
18struct pnp_resource_table;
19 18
20/* 19/*
21 * Resource Management 20 * Resource Management
@@ -24,7 +23,14 @@ struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int);
24 23
25static inline int pnp_resource_valid(struct resource *res) 24static inline int pnp_resource_valid(struct resource *res)
26{ 25{
27 if (res && !(res->flags & IORESOURCE_UNSET)) 26 if (res)
27 return 1;
28 return 0;
29}
30
31static inline int pnp_resource_enabled(struct resource *res)
32{
33 if (res && !(res->flags & IORESOURCE_DISABLED))
28 return 1; 34 return 1;
29 return 0; 35 return 0;
30} 36}
@@ -64,7 +70,7 @@ static inline unsigned long pnp_port_flags(struct pnp_dev *dev,
64 70
65 if (pnp_resource_valid(res)) 71 if (pnp_resource_valid(res))
66 return res->flags; 72 return res->flags;
67 return IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET; 73 return IORESOURCE_IO | IORESOURCE_AUTO;
68} 74}
69 75
70static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar) 76static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar)
@@ -109,7 +115,7 @@ static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar)
109 115
110 if (pnp_resource_valid(res)) 116 if (pnp_resource_valid(res))
111 return res->flags; 117 return res->flags;
112 return IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET; 118 return IORESOURCE_MEM | IORESOURCE_AUTO;
113} 119}
114 120
115static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar) 121static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar)
@@ -143,7 +149,7 @@ static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar)
143 149
144 if (pnp_resource_valid(res)) 150 if (pnp_resource_valid(res))
145 return res->flags; 151 return res->flags;
146 return IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET; 152 return IORESOURCE_IRQ | IORESOURCE_AUTO;
147} 153}
148 154
149static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar) 155static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar)
@@ -167,7 +173,7 @@ static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar)
167 173
168 if (pnp_resource_valid(res)) 174 if (pnp_resource_valid(res))
169 return res->flags; 175 return res->flags;
170 return IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET; 176 return IORESOURCE_DMA | IORESOURCE_AUTO;
171} 177}
172 178
173static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar) 179static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar)
@@ -296,7 +302,7 @@ struct pnp_dev {
296 int capabilities; 302 int capabilities;
297 struct pnp_option *independent; 303 struct pnp_option *independent;
298 struct pnp_option *dependent; 304 struct pnp_option *dependent;
299 struct pnp_resource_table *res; 305 struct list_head resources;
300 306
301 char name[PNP_NAME_LEN]; /* contains a human-readable name */ 307 char name[PNP_NAME_LEN]; /* contains a human-readable name */
302 int flags; /* used by protocols */ 308 int flags; /* used by protocols */