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