diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pnp/base.h | 2 | ||||
-rw-r--r-- | drivers/pnp/manager.c | 81 | ||||
-rw-r--r-- | drivers/pnp/support.c | 37 |
3 files changed, 100 insertions, 20 deletions
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index a83cdcfee165..0c5cb1d58c6c 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h | |||
@@ -16,3 +16,5 @@ int pnp_check_port(struct pnp_dev * dev, int idx); | |||
16 | int pnp_check_mem(struct pnp_dev * dev, int idx); | 16 | int pnp_check_mem(struct pnp_dev * dev, int idx); |
17 | int pnp_check_irq(struct pnp_dev * dev, int idx); | 17 | int pnp_check_irq(struct pnp_dev * dev, int idx); |
18 | int pnp_check_dma(struct pnp_dev * dev, int idx); | 18 | int pnp_check_dma(struct pnp_dev * dev, int idx); |
19 | |||
20 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); | ||
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 6a1f0b0b24b3..945c6201719d 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -28,20 +28,25 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | |||
28 | return 1; | 28 | return 1; |
29 | } | 29 | } |
30 | 30 | ||
31 | /* check if this resource has been manually set, if so skip */ | ||
32 | if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO)) | ||
33 | return 1; | ||
34 | |||
35 | start = &dev->res.port_resource[idx].start; | 31 | start = &dev->res.port_resource[idx].start; |
36 | end = &dev->res.port_resource[idx].end; | 32 | end = &dev->res.port_resource[idx].end; |
37 | flags = &dev->res.port_resource[idx].flags; | 33 | flags = &dev->res.port_resource[idx].flags; |
38 | 34 | ||
35 | /* check if this resource has been manually set, if so skip */ | ||
36 | if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO)) { | ||
37 | dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx " | ||
38 | "flags %#lx\n", idx, (unsigned long long) *start, | ||
39 | (unsigned long long) *end, *flags); | ||
40 | return 1; | ||
41 | } | ||
42 | |||
39 | /* set the initial values */ | 43 | /* set the initial values */ |
40 | *flags |= rule->flags | IORESOURCE_IO; | 44 | *flags |= rule->flags | IORESOURCE_IO; |
41 | *flags &= ~IORESOURCE_UNSET; | 45 | *flags &= ~IORESOURCE_UNSET; |
42 | 46 | ||
43 | if (!rule->size) { | 47 | if (!rule->size) { |
44 | *flags |= IORESOURCE_DISABLED; | 48 | *flags |= IORESOURCE_DISABLED; |
49 | dev_dbg(&dev->dev, " io %d disabled\n", idx); | ||
45 | return 1; /* skip disabled resource requests */ | 50 | return 1; /* skip disabled resource requests */ |
46 | } | 51 | } |
47 | 52 | ||
@@ -52,9 +57,13 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | |||
52 | while (!pnp_check_port(dev, idx)) { | 57 | while (!pnp_check_port(dev, idx)) { |
53 | *start += rule->align; | 58 | *start += rule->align; |
54 | *end = *start + rule->size - 1; | 59 | *end = *start + rule->size - 1; |
55 | if (*start > rule->max || !rule->align) | 60 | if (*start > rule->max || !rule->align) { |
61 | dev_dbg(&dev->dev, " couldn't assign io %d\n", idx); | ||
56 | return 0; | 62 | return 0; |
63 | } | ||
57 | } | 64 | } |
65 | dev_dbg(&dev->dev, " assign io %d %#llx-%#llx\n", idx, | ||
66 | (unsigned long long) *start, (unsigned long long) *end); | ||
58 | return 1; | 67 | return 1; |
59 | } | 68 | } |
60 | 69 | ||
@@ -69,14 +78,18 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | |||
69 | return 1; | 78 | return 1; |
70 | } | 79 | } |
71 | 80 | ||
72 | /* check if this resource has been manually set, if so skip */ | ||
73 | if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO)) | ||
74 | return 1; | ||
75 | |||
76 | start = &dev->res.mem_resource[idx].start; | 81 | start = &dev->res.mem_resource[idx].start; |
77 | end = &dev->res.mem_resource[idx].end; | 82 | end = &dev->res.mem_resource[idx].end; |
78 | flags = &dev->res.mem_resource[idx].flags; | 83 | flags = &dev->res.mem_resource[idx].flags; |
79 | 84 | ||
85 | /* check if this resource has been manually set, if so skip */ | ||
86 | if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO)) { | ||
87 | dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " | ||
88 | "flags %#lx\n", idx, (unsigned long long) *start, | ||
89 | (unsigned long long) *end, *flags); | ||
90 | return 1; | ||
91 | } | ||
92 | |||
80 | /* set the initial values */ | 93 | /* set the initial values */ |
81 | *flags |= rule->flags | IORESOURCE_MEM; | 94 | *flags |= rule->flags | IORESOURCE_MEM; |
82 | *flags &= ~IORESOURCE_UNSET; | 95 | *flags &= ~IORESOURCE_UNSET; |
@@ -93,6 +106,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | |||
93 | 106 | ||
94 | if (!rule->size) { | 107 | if (!rule->size) { |
95 | *flags |= IORESOURCE_DISABLED; | 108 | *flags |= IORESOURCE_DISABLED; |
109 | dev_dbg(&dev->dev, " mem %d disabled\n", idx); | ||
96 | return 1; /* skip disabled resource requests */ | 110 | return 1; /* skip disabled resource requests */ |
97 | } | 111 | } |
98 | 112 | ||
@@ -103,9 +117,13 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | |||
103 | while (!pnp_check_mem(dev, idx)) { | 117 | while (!pnp_check_mem(dev, idx)) { |
104 | *start += rule->align; | 118 | *start += rule->align; |
105 | *end = *start + rule->size - 1; | 119 | *end = *start + rule->size - 1; |
106 | if (*start > rule->max || !rule->align) | 120 | if (*start > rule->max || !rule->align) { |
121 | dev_dbg(&dev->dev, " couldn't assign mem %d\n", idx); | ||
107 | return 0; | 122 | return 0; |
123 | } | ||
108 | } | 124 | } |
125 | dev_dbg(&dev->dev, " assign mem %d %#llx-%#llx\n", idx, | ||
126 | (unsigned long long) *start, (unsigned long long) *end); | ||
109 | return 1; | 127 | return 1; |
110 | } | 128 | } |
111 | 129 | ||
@@ -126,20 +144,24 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) | |||
126 | return 1; | 144 | return 1; |
127 | } | 145 | } |
128 | 146 | ||
129 | /* check if this resource has been manually set, if so skip */ | ||
130 | if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO)) | ||
131 | return 1; | ||
132 | |||
133 | start = &dev->res.irq_resource[idx].start; | 147 | start = &dev->res.irq_resource[idx].start; |
134 | end = &dev->res.irq_resource[idx].end; | 148 | end = &dev->res.irq_resource[idx].end; |
135 | flags = &dev->res.irq_resource[idx].flags; | 149 | flags = &dev->res.irq_resource[idx].flags; |
136 | 150 | ||
151 | /* check if this resource has been manually set, if so skip */ | ||
152 | if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO)) { | ||
153 | dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", | ||
154 | idx, (int) *start, *flags); | ||
155 | return 1; | ||
156 | } | ||
157 | |||
137 | /* set the initial values */ | 158 | /* set the initial values */ |
138 | *flags |= rule->flags | IORESOURCE_IRQ; | 159 | *flags |= rule->flags | IORESOURCE_IRQ; |
139 | *flags &= ~IORESOURCE_UNSET; | 160 | *flags &= ~IORESOURCE_UNSET; |
140 | 161 | ||
141 | if (bitmap_empty(rule->map, PNP_IRQ_NR)) { | 162 | if (bitmap_empty(rule->map, PNP_IRQ_NR)) { |
142 | *flags |= IORESOURCE_DISABLED; | 163 | *flags |= IORESOURCE_DISABLED; |
164 | dev_dbg(&dev->dev, " irq %d disabled\n", idx); | ||
143 | return 1; /* skip disabled resource requests */ | 165 | return 1; /* skip disabled resource requests */ |
144 | } | 166 | } |
145 | 167 | ||
@@ -147,15 +169,20 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) | |||
147 | *start = find_next_bit(rule->map, PNP_IRQ_NR, 16); | 169 | *start = find_next_bit(rule->map, PNP_IRQ_NR, 16); |
148 | if (*start < PNP_IRQ_NR) { | 170 | if (*start < PNP_IRQ_NR) { |
149 | *end = *start; | 171 | *end = *start; |
172 | dev_dbg(&dev->dev, " assign irq %d %d\n", idx, (int) *start); | ||
150 | return 1; | 173 | return 1; |
151 | } | 174 | } |
152 | for (i = 0; i < 16; i++) { | 175 | for (i = 0; i < 16; i++) { |
153 | if (test_bit(xtab[i], rule->map)) { | 176 | if (test_bit(xtab[i], rule->map)) { |
154 | *start = *end = xtab[i]; | 177 | *start = *end = xtab[i]; |
155 | if (pnp_check_irq(dev, idx)) | 178 | if (pnp_check_irq(dev, idx)) { |
179 | dev_dbg(&dev->dev, " assign irq %d %d\n", idx, | ||
180 | (int) *start); | ||
156 | return 1; | 181 | return 1; |
182 | } | ||
157 | } | 183 | } |
158 | } | 184 | } |
185 | dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); | ||
159 | return 0; | 186 | return 0; |
160 | } | 187 | } |
161 | 188 | ||
@@ -175,14 +202,17 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) | |||
175 | return; | 202 | return; |
176 | } | 203 | } |
177 | 204 | ||
178 | /* check if this resource has been manually set, if so skip */ | ||
179 | if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) | ||
180 | return; | ||
181 | |||
182 | start = &dev->res.dma_resource[idx].start; | 205 | start = &dev->res.dma_resource[idx].start; |
183 | end = &dev->res.dma_resource[idx].end; | 206 | end = &dev->res.dma_resource[idx].end; |
184 | flags = &dev->res.dma_resource[idx].flags; | 207 | flags = &dev->res.dma_resource[idx].flags; |
185 | 208 | ||
209 | /* check if this resource has been manually set, if so skip */ | ||
210 | if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) { | ||
211 | dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", | ||
212 | idx, (int) *start, *flags); | ||
213 | return; | ||
214 | } | ||
215 | |||
186 | /* set the initial values */ | 216 | /* set the initial values */ |
187 | *flags |= rule->flags | IORESOURCE_DMA; | 217 | *flags |= rule->flags | IORESOURCE_DMA; |
188 | *flags &= ~IORESOURCE_UNSET; | 218 | *flags &= ~IORESOURCE_UNSET; |
@@ -190,14 +220,18 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) | |||
190 | for (i = 0; i < 8; i++) { | 220 | for (i = 0; i < 8; i++) { |
191 | if (rule->map & (1 << xtab[i])) { | 221 | if (rule->map & (1 << xtab[i])) { |
192 | *start = *end = xtab[i]; | 222 | *start = *end = xtab[i]; |
193 | if (pnp_check_dma(dev, idx)) | 223 | if (pnp_check_dma(dev, idx)) { |
224 | dev_dbg(&dev->dev, " assign dma %d %d\n", idx, | ||
225 | (int) *start); | ||
194 | return; | 226 | return; |
227 | } | ||
195 | } | 228 | } |
196 | } | 229 | } |
197 | #ifdef MAX_DMA_CHANNELS | 230 | #ifdef MAX_DMA_CHANNELS |
198 | *start = *end = MAX_DMA_CHANNELS; | 231 | *start = *end = MAX_DMA_CHANNELS; |
199 | #endif | 232 | #endif |
200 | *flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; | 233 | *flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; |
234 | dev_dbg(&dev->dev, " disable dma %d\n", idx); | ||
201 | } | 235 | } |
202 | 236 | ||
203 | /** | 237 | /** |
@@ -298,9 +332,11 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) | |||
298 | if (!pnp_can_configure(dev)) | 332 | if (!pnp_can_configure(dev)) |
299 | return -ENODEV; | 333 | return -ENODEV; |
300 | 334 | ||
335 | dbg_pnp_show_resources(dev, "before pnp_assign_resources"); | ||
301 | mutex_lock(&pnp_res_mutex); | 336 | mutex_lock(&pnp_res_mutex); |
302 | pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ | 337 | pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ |
303 | if (dev->independent) { | 338 | if (dev->independent) { |
339 | dev_dbg(&dev->dev, "assigning independent options\n"); | ||
304 | port = dev->independent->port; | 340 | port = dev->independent->port; |
305 | mem = dev->independent->mem; | 341 | mem = dev->independent->mem; |
306 | irq = dev->independent->irq; | 342 | irq = dev->independent->irq; |
@@ -333,6 +369,8 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) | |||
333 | if (depnum) { | 369 | if (depnum) { |
334 | struct pnp_option *dep; | 370 | struct pnp_option *dep; |
335 | int i; | 371 | int i; |
372 | |||
373 | dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum); | ||
336 | for (i = 1, dep = dev->dependent; i < depnum; | 374 | for (i = 1, dep = dev->dependent; i < depnum; |
337 | i++, dep = dep->next) | 375 | i++, dep = dep->next) |
338 | if (!dep) | 376 | if (!dep) |
@@ -368,11 +406,13 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) | |||
368 | goto fail; | 406 | goto fail; |
369 | 407 | ||
370 | mutex_unlock(&pnp_res_mutex); | 408 | mutex_unlock(&pnp_res_mutex); |
409 | dbg_pnp_show_resources(dev, "after pnp_assign_resources"); | ||
371 | return 1; | 410 | return 1; |
372 | 411 | ||
373 | fail: | 412 | fail: |
374 | pnp_clean_resource_table(&dev->res); | 413 | pnp_clean_resource_table(&dev->res); |
375 | mutex_unlock(&pnp_res_mutex); | 414 | mutex_unlock(&pnp_res_mutex); |
415 | dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)"); | ||
376 | return 0; | 416 | return 0; |
377 | } | 417 | } |
378 | 418 | ||
@@ -473,6 +513,7 @@ int pnp_start_dev(struct pnp_dev *dev) | |||
473 | return -EINVAL; | 513 | return -EINVAL; |
474 | } | 514 | } |
475 | 515 | ||
516 | dbg_pnp_show_resources(dev, "pnp_start_dev"); | ||
476 | if (dev->protocol->set(dev) < 0) { | 517 | if (dev->protocol->set(dev) < 0) { |
477 | dev_err(&dev->dev, "activation failed\n"); | 518 | dev_err(&dev->dev, "activation failed\n"); |
478 | return -EIO; | 519 | return -EIO; |
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index e848b794e312..3aeb154e27d6 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c | |||
@@ -51,3 +51,40 @@ void pnp_eisa_id_to_string(u32 id, char *str) | |||
51 | str[6] = hex_asc((id >> 0) & 0xf); | 51 | str[6] = hex_asc((id >> 0) & 0xf); |
52 | str[7] = '\0'; | 52 | str[7] = '\0'; |
53 | } | 53 | } |
54 | |||
55 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) | ||
56 | { | ||
57 | #ifdef DEBUG | ||
58 | struct resource *res; | ||
59 | int i; | ||
60 | |||
61 | dev_dbg(&dev->dev, "current resources: %s\n", desc); | ||
62 | |||
63 | for (i = 0; i < PNP_MAX_IRQ; i++) { | ||
64 | res = &dev->res.irq_resource[i]; | ||
65 | if (!(res->flags & IORESOURCE_UNSET)) | ||
66 | dev_dbg(&dev->dev, " irq %lld flags %#lx\n", | ||
67 | (unsigned long long) res->start, res->flags); | ||
68 | } | ||
69 | for (i = 0; i < PNP_MAX_DMA; i++) { | ||
70 | res = &dev->res.dma_resource[i]; | ||
71 | if (!(res->flags & IORESOURCE_UNSET)) | ||
72 | dev_dbg(&dev->dev, " dma %lld flags %#lx\n", | ||
73 | (unsigned long long) res->start, res->flags); | ||
74 | } | ||
75 | for (i = 0; i < PNP_MAX_PORT; i++) { | ||
76 | res = &dev->res.port_resource[i]; | ||
77 | if (!(res->flags & IORESOURCE_UNSET)) | ||
78 | dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n", | ||
79 | (unsigned long long) res->start, | ||
80 | (unsigned long long) res->end, res->flags); | ||
81 | } | ||
82 | for (i = 0; i < PNP_MAX_MEM; i++) { | ||
83 | res = &dev->res.mem_resource[i]; | ||
84 | if (!(res->flags & IORESOURCE_UNSET)) | ||
85 | dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n", | ||
86 | (unsigned long long) res->start, | ||
87 | (unsigned long long) res->end, res->flags); | ||
88 | } | ||
89 | #endif | ||
90 | } | ||