diff options
| -rw-r--r-- | drivers/pnp/base.h | 93 | ||||
| -rw-r--r-- | drivers/pnp/core.c | 4 | ||||
| -rw-r--r-- | drivers/pnp/interface.c | 75 | ||||
| -rw-r--r-- | drivers/pnp/isapnp/core.c | 72 | ||||
| -rw-r--r-- | drivers/pnp/manager.c | 145 | ||||
| -rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 93 | ||||
| -rw-r--r-- | drivers/pnp/pnpbios/rsparser.c | 67 | ||||
| -rw-r--r-- | drivers/pnp/quirks.c | 290 | ||||
| -rw-r--r-- | drivers/pnp/resource.c | 268 | ||||
| -rw-r--r-- | drivers/pnp/support.c | 92 | ||||
| -rw-r--r-- | include/linux/pnp.h | 6 |
11 files changed, 571 insertions, 634 deletions
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 360c6385686c..e3fa9a2d9a3d 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. | ||
| 3 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
| 4 | */ | ||
| 5 | |||
| 1 | extern spinlock_t pnp_lock; | 6 | extern spinlock_t pnp_lock; |
| 2 | void *pnp_alloc(long size); | 7 | void *pnp_alloc(long size); |
| 3 | 8 | ||
| @@ -25,8 +30,6 @@ struct pnp_port { | |||
| 25 | resource_size_t align; /* align boundary */ | 30 | resource_size_t align; /* align boundary */ |
| 26 | resource_size_t size; /* size of range */ | 31 | resource_size_t size; /* size of range */ |
| 27 | unsigned char flags; /* port flags */ | 32 | unsigned char flags; /* port flags */ |
| 28 | unsigned char pad; /* pad */ | ||
| 29 | struct pnp_port *next; /* next port */ | ||
| 30 | }; | 33 | }; |
| 31 | 34 | ||
| 32 | #define PNP_IRQ_NR 256 | 35 | #define PNP_IRQ_NR 256 |
| @@ -35,14 +38,11 @@ typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t; | |||
| 35 | struct pnp_irq { | 38 | struct pnp_irq { |
| 36 | pnp_irq_mask_t map; /* bitmap for IRQ lines */ | 39 | pnp_irq_mask_t map; /* bitmap for IRQ lines */ |
| 37 | unsigned char flags; /* IRQ flags */ | 40 | unsigned char flags; /* IRQ flags */ |
| 38 | unsigned char pad; /* pad */ | ||
| 39 | struct pnp_irq *next; /* next IRQ */ | ||
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 42 | struct pnp_dma { | 43 | struct pnp_dma { |
| 43 | unsigned char map; /* bitmask for DMA channels */ | 44 | unsigned char map; /* bitmask for DMA channels */ |
| 44 | unsigned char flags; /* DMA flags */ | 45 | unsigned char flags; /* DMA flags */ |
| 45 | struct pnp_dma *next; /* next port */ | ||
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | struct pnp_mem { | 48 | struct pnp_mem { |
| @@ -51,44 +51,91 @@ struct pnp_mem { | |||
| 51 | resource_size_t align; /* align boundary */ | 51 | resource_size_t align; /* align boundary */ |
| 52 | resource_size_t size; /* size of range */ | 52 | resource_size_t size; /* size of range */ |
| 53 | unsigned char flags; /* memory flags */ | 53 | unsigned char flags; /* memory flags */ |
| 54 | unsigned char pad; /* pad */ | ||
| 55 | struct pnp_mem *next; /* next memory resource */ | ||
| 56 | }; | 54 | }; |
| 57 | 55 | ||
| 56 | #define PNP_OPTION_DEPENDENT 0x80000000 | ||
| 57 | #define PNP_OPTION_SET_MASK 0xffff | ||
| 58 | #define PNP_OPTION_SET_SHIFT 12 | ||
| 59 | #define PNP_OPTION_PRIORITY_MASK 0xfff | ||
| 60 | #define PNP_OPTION_PRIORITY_SHIFT 0 | ||
| 61 | |||
| 58 | #define PNP_RES_PRIORITY_PREFERRED 0 | 62 | #define PNP_RES_PRIORITY_PREFERRED 0 |
| 59 | #define PNP_RES_PRIORITY_ACCEPTABLE 1 | 63 | #define PNP_RES_PRIORITY_ACCEPTABLE 1 |
| 60 | #define PNP_RES_PRIORITY_FUNCTIONAL 2 | 64 | #define PNP_RES_PRIORITY_FUNCTIONAL 2 |
| 61 | #define PNP_RES_PRIORITY_INVALID 65535 | 65 | #define PNP_RES_PRIORITY_INVALID PNP_OPTION_PRIORITY_MASK |
| 62 | 66 | ||
| 63 | struct pnp_option { | 67 | struct pnp_option { |
| 64 | unsigned short priority; /* priority */ | 68 | struct list_head list; |
| 65 | struct pnp_port *port; /* first port */ | 69 | unsigned int flags; /* independent/dependent, set, priority */ |
| 66 | struct pnp_irq *irq; /* first IRQ */ | 70 | |
| 67 | struct pnp_dma *dma; /* first DMA */ | 71 | unsigned long type; /* IORESOURCE_{IO,MEM,IRQ,DMA} */ |
| 68 | struct pnp_mem *mem; /* first memory resource */ | 72 | union { |
| 69 | struct pnp_option *next; /* used to chain dependent resources */ | 73 | struct pnp_port port; |
| 74 | struct pnp_irq irq; | ||
| 75 | struct pnp_dma dma; | ||
| 76 | struct pnp_mem mem; | ||
| 77 | } u; | ||
| 70 | }; | 78 | }; |
| 71 | 79 | ||
| 72 | struct pnp_option *pnp_build_option(int priority); | 80 | int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags, |
| 73 | struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev); | ||
| 74 | struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, | ||
| 75 | int priority); | ||
| 76 | int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, | ||
| 77 | pnp_irq_mask_t *map, unsigned char flags); | 81 | pnp_irq_mask_t *map, unsigned char flags); |
| 78 | int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, | 82 | int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags, |
| 79 | unsigned char map, unsigned char flags); | 83 | unsigned char map, unsigned char flags); |
| 80 | int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, | 84 | int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags, |
| 81 | resource_size_t min, resource_size_t max, | 85 | resource_size_t min, resource_size_t max, |
| 82 | resource_size_t align, resource_size_t size, | 86 | resource_size_t align, resource_size_t size, |
| 83 | unsigned char flags); | 87 | unsigned char flags); |
| 84 | int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, | 88 | int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags, |
| 85 | resource_size_t min, resource_size_t max, | 89 | resource_size_t min, resource_size_t max, |
| 86 | resource_size_t align, resource_size_t size, | 90 | resource_size_t align, resource_size_t size, |
| 87 | unsigned char flags); | 91 | unsigned char flags); |
| 92 | |||
| 93 | static inline int pnp_option_is_dependent(struct pnp_option *option) | ||
| 94 | { | ||
| 95 | return option->flags & PNP_OPTION_DEPENDENT ? 1 : 0; | ||
| 96 | } | ||
| 97 | |||
| 98 | static inline unsigned int pnp_option_set(struct pnp_option *option) | ||
| 99 | { | ||
| 100 | return (option->flags >> PNP_OPTION_SET_SHIFT) & PNP_OPTION_SET_MASK; | ||
| 101 | } | ||
| 102 | |||
| 103 | static inline unsigned int pnp_option_priority(struct pnp_option *option) | ||
| 104 | { | ||
| 105 | return (option->flags >> PNP_OPTION_PRIORITY_SHIFT) & | ||
| 106 | PNP_OPTION_PRIORITY_MASK; | ||
| 107 | } | ||
| 108 | |||
| 109 | static inline unsigned int pnp_new_dependent_set(struct pnp_dev *dev, | ||
| 110 | int priority) | ||
| 111 | { | ||
| 112 | unsigned int flags; | ||
| 113 | |||
| 114 | if (priority > PNP_RES_PRIORITY_FUNCTIONAL) { | ||
| 115 | dev_warn(&dev->dev, "invalid dependent option priority %d " | ||
| 116 | "clipped to %d", priority, | ||
| 117 | PNP_RES_PRIORITY_INVALID); | ||
| 118 | priority = PNP_RES_PRIORITY_INVALID; | ||
| 119 | } | ||
| 120 | |||
| 121 | flags = PNP_OPTION_DEPENDENT | | ||
| 122 | ((dev->num_dependent_sets & PNP_OPTION_SET_MASK) << | ||
| 123 | PNP_OPTION_SET_SHIFT) | | ||
| 124 | ((priority & PNP_OPTION_PRIORITY_MASK) << | ||
| 125 | PNP_OPTION_PRIORITY_SHIFT); | ||
| 126 | |||
| 127 | dev->num_dependent_sets++; | ||
| 128 | |||
| 129 | return flags; | ||
| 130 | } | ||
| 131 | |||
| 132 | char *pnp_option_priority_name(struct pnp_option *option); | ||
| 133 | void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option); | ||
| 134 | |||
| 88 | void pnp_init_resources(struct pnp_dev *dev); | 135 | void pnp_init_resources(struct pnp_dev *dev); |
| 89 | 136 | ||
| 90 | void pnp_fixup_device(struct pnp_dev *dev); | 137 | void pnp_fixup_device(struct pnp_dev *dev); |
| 91 | void pnp_free_option(struct pnp_option *option); | 138 | void pnp_free_options(struct pnp_dev *dev); |
| 92 | int __pnp_add_device(struct pnp_dev *dev); | 139 | int __pnp_add_device(struct pnp_dev *dev); |
| 93 | void __pnp_remove_device(struct pnp_dev *dev); | 140 | void __pnp_remove_device(struct pnp_dev *dev); |
| 94 | 141 | ||
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index 7182da92aec3..a411582bcd72 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c | |||
| @@ -118,10 +118,9 @@ static void pnp_release_device(struct device *dmdev) | |||
| 118 | { | 118 | { |
| 119 | struct pnp_dev *dev = to_pnp_dev(dmdev); | 119 | struct pnp_dev *dev = to_pnp_dev(dmdev); |
| 120 | 120 | ||
| 121 | pnp_free_option(dev->independent); | ||
| 122 | pnp_free_option(dev->dependent); | ||
| 123 | pnp_free_ids(dev); | 121 | pnp_free_ids(dev); |
| 124 | pnp_free_resources(dev); | 122 | pnp_free_resources(dev); |
| 123 | pnp_free_options(dev); | ||
| 125 | kfree(dev); | 124 | kfree(dev); |
| 126 | } | 125 | } |
| 127 | 126 | ||
| @@ -135,6 +134,7 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid | |||
| 135 | return NULL; | 134 | return NULL; |
| 136 | 135 | ||
| 137 | INIT_LIST_HEAD(&dev->resources); | 136 | INIT_LIST_HEAD(&dev->resources); |
| 137 | INIT_LIST_HEAD(&dev->options); | ||
| 138 | dev->protocol = protocol; | 138 | dev->protocol = protocol; |
| 139 | dev->number = id; | 139 | dev->number = id; |
| 140 | dev->dma_mask = DMA_24BIT_MASK; | 140 | dev->dma_mask = DMA_24BIT_MASK; |
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 7a9fb5544b80..a876ecf7028c 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | * | 3 | * |
| 4 | * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz> | 4 | * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz> |
| 5 | * Copyright 2002 Adam Belay <ambx1@neo.rr.com> | 5 | * Copyright 2002 Adam Belay <ambx1@neo.rr.com> |
| 6 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. | ||
| 7 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
| 6 | */ | 8 | */ |
| 7 | 9 | ||
| 8 | #include <linux/pnp.h> | 10 | #include <linux/pnp.h> |
| @@ -184,39 +186,22 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space, | |||
| 184 | } | 186 | } |
| 185 | 187 | ||
| 186 | static void pnp_print_option(pnp_info_buffer_t * buffer, char *space, | 188 | static void pnp_print_option(pnp_info_buffer_t * buffer, char *space, |
| 187 | struct pnp_option *option, int dep) | 189 | struct pnp_option *option) |
| 188 | { | 190 | { |
| 189 | char *s; | 191 | switch (option->type) { |
| 190 | struct pnp_port *port; | 192 | case IORESOURCE_IO: |
| 191 | struct pnp_irq *irq; | 193 | pnp_print_port(buffer, space, &option->u.port); |
| 192 | struct pnp_dma *dma; | 194 | break; |
| 193 | struct pnp_mem *mem; | 195 | case IORESOURCE_MEM: |
| 194 | 196 | pnp_print_mem(buffer, space, &option->u.mem); | |
| 195 | if (dep) { | 197 | break; |
| 196 | switch (option->priority) { | 198 | case IORESOURCE_IRQ: |
| 197 | case PNP_RES_PRIORITY_PREFERRED: | 199 | pnp_print_irq(buffer, space, &option->u.irq); |
| 198 | s = "preferred"; | 200 | break; |
| 199 | break; | 201 | case IORESOURCE_DMA: |
| 200 | case PNP_RES_PRIORITY_ACCEPTABLE: | 202 | pnp_print_dma(buffer, space, &option->u.dma); |
| 201 | s = "acceptable"; | 203 | break; |
| 202 | break; | ||
| 203 | case PNP_RES_PRIORITY_FUNCTIONAL: | ||
| 204 | s = "functional"; | ||
| 205 | break; | ||
| 206 | default: | ||
| 207 | s = "invalid"; | ||
| 208 | } | ||
| 209 | pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s); | ||
| 210 | } | 204 | } |
| 211 | |||
| 212 | for (port = option->port; port; port = port->next) | ||
| 213 | pnp_print_port(buffer, space, port); | ||
| 214 | for (irq = option->irq; irq; irq = irq->next) | ||
| 215 | pnp_print_irq(buffer, space, irq); | ||
| 216 | for (dma = option->dma; dma; dma = dma->next) | ||
| 217 | pnp_print_dma(buffer, space, dma); | ||
| 218 | for (mem = option->mem; mem; mem = mem->next) | ||
| 219 | pnp_print_mem(buffer, space, mem); | ||
| 220 | } | 205 | } |
| 221 | 206 | ||
| 222 | static ssize_t pnp_show_options(struct device *dmdev, | 207 | static ssize_t pnp_show_options(struct device *dmdev, |
| @@ -224,9 +209,9 @@ static ssize_t pnp_show_options(struct device *dmdev, | |||
| 224 | { | 209 | { |
| 225 | struct pnp_dev *dev = to_pnp_dev(dmdev); | 210 | struct pnp_dev *dev = to_pnp_dev(dmdev); |
| 226 | pnp_info_buffer_t *buffer; | 211 | pnp_info_buffer_t *buffer; |
| 227 | struct pnp_option *independent = dev->independent; | 212 | struct pnp_option *option; |
| 228 | struct pnp_option *dependent = dev->dependent; | 213 | int ret, dep = 0, set = 0; |
| 229 | int ret, dep = 1; | 214 | char *indent; |
| 230 | 215 | ||
| 231 | buffer = pnp_alloc(sizeof(pnp_info_buffer_t)); | 216 | buffer = pnp_alloc(sizeof(pnp_info_buffer_t)); |
| 232 | if (!buffer) | 217 | if (!buffer) |
| @@ -235,14 +220,24 @@ static ssize_t pnp_show_options(struct device *dmdev, | |||
| 235 | buffer->len = PAGE_SIZE; | 220 | buffer->len = PAGE_SIZE; |
| 236 | buffer->buffer = buf; | 221 | buffer->buffer = buf; |
| 237 | buffer->curr = buffer->buffer; | 222 | buffer->curr = buffer->buffer; |
| 238 | if (independent) | ||
| 239 | pnp_print_option(buffer, "", independent, 0); | ||
| 240 | 223 | ||
| 241 | while (dependent) { | 224 | list_for_each_entry(option, &dev->options, list) { |
| 242 | pnp_print_option(buffer, " ", dependent, dep); | 225 | if (pnp_option_is_dependent(option)) { |
| 243 | dependent = dependent->next; | 226 | indent = " "; |
| 244 | dep++; | 227 | if (!dep || pnp_option_set(option) != set) { |
| 228 | set = pnp_option_set(option); | ||
| 229 | dep = 1; | ||
| 230 | pnp_printf(buffer, "Dependent: %02i - " | ||
| 231 | "Priority %s\n", set, | ||
| 232 | pnp_option_priority_name(option)); | ||
| 233 | } | ||
| 234 | } else { | ||
| 235 | dep = 0; | ||
| 236 | indent = ""; | ||
| 237 | } | ||
| 238 | pnp_print_option(buffer, indent, option); | ||
| 245 | } | 239 | } |
| 240 | |||
| 246 | ret = (buffer->curr - buf); | 241 | ret = (buffer->curr - buf); |
| 247 | kfree(buffer); | 242 | kfree(buffer); |
| 248 | return ret; | 243 | return ret; |
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 53cc4d6133e6..101a835e8759 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c | |||
| @@ -429,7 +429,7 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card, | |||
| 429 | * Add IRQ resource to resources list. | 429 | * Add IRQ resource to resources list. |
| 430 | */ | 430 | */ |
| 431 | static void __init isapnp_parse_irq_resource(struct pnp_dev *dev, | 431 | static void __init isapnp_parse_irq_resource(struct pnp_dev *dev, |
| 432 | struct pnp_option *option, | 432 | unsigned int option_flags, |
| 433 | int size) | 433 | int size) |
| 434 | { | 434 | { |
| 435 | unsigned char tmp[3]; | 435 | unsigned char tmp[3]; |
| @@ -446,27 +446,27 @@ static void __init isapnp_parse_irq_resource(struct pnp_dev *dev, | |||
| 446 | if (size > 2) | 446 | if (size > 2) |
| 447 | flags = tmp[2]; | 447 | flags = tmp[2]; |
| 448 | 448 | ||
| 449 | pnp_register_irq_resource(dev, option, &map, flags); | 449 | pnp_register_irq_resource(dev, option_flags, &map, flags); |
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | /* | 452 | /* |
| 453 | * Add DMA resource to resources list. | 453 | * Add DMA resource to resources list. |
| 454 | */ | 454 | */ |
| 455 | static void __init isapnp_parse_dma_resource(struct pnp_dev *dev, | 455 | static void __init isapnp_parse_dma_resource(struct pnp_dev *dev, |
| 456 | struct pnp_option *option, | 456 | unsigned int option_flags, |
| 457 | int size) | 457 | int size) |
| 458 | { | 458 | { |
| 459 | unsigned char tmp[2]; | 459 | unsigned char tmp[2]; |
| 460 | 460 | ||
| 461 | isapnp_peek(tmp, size); | 461 | isapnp_peek(tmp, size); |
| 462 | pnp_register_dma_resource(dev, option, tmp[0], tmp[1]); | 462 | pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]); |
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | /* | 465 | /* |
| 466 | * Add port resource to resources list. | 466 | * Add port resource to resources list. |
| 467 | */ | 467 | */ |
| 468 | static void __init isapnp_parse_port_resource(struct pnp_dev *dev, | 468 | static void __init isapnp_parse_port_resource(struct pnp_dev *dev, |
| 469 | struct pnp_option *option, | 469 | unsigned int option_flags, |
| 470 | int size) | 470 | int size) |
| 471 | { | 471 | { |
| 472 | unsigned char tmp[7]; | 472 | unsigned char tmp[7]; |
| @@ -479,14 +479,15 @@ static void __init isapnp_parse_port_resource(struct pnp_dev *dev, | |||
| 479 | align = tmp[5]; | 479 | align = tmp[5]; |
| 480 | len = tmp[6]; | 480 | len = tmp[6]; |
| 481 | flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0; | 481 | flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0; |
| 482 | pnp_register_port_resource(dev, option, min, max, align, len, flags); | 482 | pnp_register_port_resource(dev, option_flags, |
| 483 | min, max, align, len, flags); | ||
| 483 | } | 484 | } |
| 484 | 485 | ||
| 485 | /* | 486 | /* |
| 486 | * Add fixed port resource to resources list. | 487 | * Add fixed port resource to resources list. |
| 487 | */ | 488 | */ |
| 488 | static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, | 489 | static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, |
| 489 | struct pnp_option *option, | 490 | unsigned int option_flags, |
| 490 | int size) | 491 | int size) |
| 491 | { | 492 | { |
| 492 | unsigned char tmp[3]; | 493 | unsigned char tmp[3]; |
| @@ -495,7 +496,7 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, | |||
| 495 | isapnp_peek(tmp, size); | 496 | isapnp_peek(tmp, size); |
| 496 | base = (tmp[1] << 8) | tmp[0]; | 497 | base = (tmp[1] << 8) | tmp[0]; |
| 497 | len = tmp[2]; | 498 | len = tmp[2]; |
| 498 | pnp_register_port_resource(dev, option, base, base, 0, len, | 499 | pnp_register_port_resource(dev, option_flags, base, base, 0, len, |
| 499 | IORESOURCE_IO_FIXED); | 500 | IORESOURCE_IO_FIXED); |
| 500 | } | 501 | } |
| 501 | 502 | ||
| @@ -503,7 +504,7 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, | |||
| 503 | * Add memory resource to resources list. | 504 | * Add memory resource to resources list. |
| 504 | */ | 505 | */ |
| 505 | static void __init isapnp_parse_mem_resource(struct pnp_dev *dev, | 506 | static void __init isapnp_parse_mem_resource(struct pnp_dev *dev, |
| 506 | struct pnp_option *option, | 507 | unsigned int option_flags, |
| 507 | int size) | 508 | int size) |
| 508 | { | 509 | { |
| 509 | unsigned char tmp[9]; | 510 | unsigned char tmp[9]; |
| @@ -516,14 +517,15 @@ static void __init isapnp_parse_mem_resource(struct pnp_dev *dev, | |||
| 516 | align = (tmp[6] << 8) | tmp[5]; | 517 | align = (tmp[6] << 8) | tmp[5]; |
| 517 | len = ((tmp[8] << 8) | tmp[7]) << 8; | 518 | len = ((tmp[8] << 8) | tmp[7]) << 8; |
| 518 | flags = tmp[0]; | 519 | flags = tmp[0]; |
| 519 | pnp_register_mem_resource(dev, option, min, max, align, len, flags); | 520 | pnp_register_mem_resource(dev, option_flags, |
| 521 | min, max, align, len, flags); | ||
| 520 | } | 522 | } |
| 521 | 523 | ||
| 522 | /* | 524 | /* |
| 523 | * Add 32-bit memory resource to resources list. | 525 | * Add 32-bit memory resource to resources list. |
| 524 | */ | 526 | */ |
| 525 | static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev, | 527 | static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev, |
| 526 | struct pnp_option *option, | 528 | unsigned int option_flags, |
| 527 | int size) | 529 | int size) |
| 528 | { | 530 | { |
| 529 | unsigned char tmp[17]; | 531 | unsigned char tmp[17]; |
| @@ -536,14 +538,15 @@ static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev, | |||
| 536 | align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9]; | 538 | align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9]; |
| 537 | len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13]; | 539 | len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13]; |
| 538 | flags = tmp[0]; | 540 | flags = tmp[0]; |
| 539 | pnp_register_mem_resource(dev, option, min, max, align, len, flags); | 541 | pnp_register_mem_resource(dev, option_flags, |
| 542 | min, max, align, len, flags); | ||
| 540 | } | 543 | } |
| 541 | 544 | ||
| 542 | /* | 545 | /* |
| 543 | * Add 32-bit fixed memory resource to resources list. | 546 | * Add 32-bit fixed memory resource to resources list. |
| 544 | */ | 547 | */ |
| 545 | static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev, | 548 | static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev, |
| 546 | struct pnp_option *option, | 549 | unsigned int option_flags, |
| 547 | int size) | 550 | int size) |
| 548 | { | 551 | { |
| 549 | unsigned char tmp[9]; | 552 | unsigned char tmp[9]; |
| @@ -554,7 +557,7 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev, | |||
| 554 | base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1]; | 557 | base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1]; |
| 555 | len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; | 558 | len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; |
| 556 | flags = tmp[0]; | 559 | flags = tmp[0]; |
| 557 | pnp_register_mem_resource(dev, option, base, base, 0, len, flags); | 560 | pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags); |
| 558 | } | 561 | } |
| 559 | 562 | ||
| 560 | /* | 563 | /* |
| @@ -584,18 +587,14 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 584 | { | 587 | { |
| 585 | int number = 0, skip = 0, priority, compat = 0; | 588 | int number = 0, skip = 0, priority, compat = 0; |
| 586 | unsigned char type, tmp[17]; | 589 | unsigned char type, tmp[17]; |
| 587 | struct pnp_option *option, *option_independent; | 590 | unsigned int option_flags; |
| 588 | struct pnp_dev *dev; | 591 | struct pnp_dev *dev; |
| 589 | u32 eisa_id; | 592 | u32 eisa_id; |
| 590 | char id[8]; | 593 | char id[8]; |
| 591 | 594 | ||
| 592 | if ((dev = isapnp_parse_device(card, size, number++)) == NULL) | 595 | if ((dev = isapnp_parse_device(card, size, number++)) == NULL) |
| 593 | return 1; | 596 | return 1; |
| 594 | option_independent = option = pnp_register_independent_option(dev); | 597 | option_flags = 0; |
| 595 | if (!option) { | ||
| 596 | kfree(dev); | ||
| 597 | return 1; | ||
| 598 | } | ||
| 599 | pnp_add_card_device(card, dev); | 598 | pnp_add_card_device(card, dev); |
| 600 | 599 | ||
| 601 | while (1) { | 600 | while (1) { |
| @@ -612,12 +611,7 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 612 | return 1; | 611 | return 1; |
| 613 | size = 0; | 612 | size = 0; |
| 614 | skip = 0; | 613 | skip = 0; |
| 615 | option = pnp_register_independent_option(dev); | 614 | option_flags = 0; |
| 616 | option_independent = option; | ||
| 617 | if (!option) { | ||
| 618 | kfree(dev); | ||
| 619 | return 1; | ||
| 620 | } | ||
| 621 | pnp_add_card_device(card, dev); | 615 | pnp_add_card_device(card, dev); |
| 622 | } else { | 616 | } else { |
| 623 | skip = 1; | 617 | skip = 1; |
| @@ -638,13 +632,13 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 638 | case _STAG_IRQ: | 632 | case _STAG_IRQ: |
| 639 | if (size < 2 || size > 3) | 633 | if (size < 2 || size > 3) |
| 640 | goto __skip; | 634 | goto __skip; |
| 641 | isapnp_parse_irq_resource(dev, option, size); | 635 | isapnp_parse_irq_resource(dev, option_flags, size); |
| 642 | size = 0; | 636 | size = 0; |
| 643 | break; | 637 | break; |
| 644 | case _STAG_DMA: | 638 | case _STAG_DMA: |
| 645 | if (size != 2) | 639 | if (size != 2) |
| 646 | goto __skip; | 640 | goto __skip; |
| 647 | isapnp_parse_dma_resource(dev, option, size); | 641 | isapnp_parse_dma_resource(dev, option_flags, size); |
| 648 | size = 0; | 642 | size = 0; |
| 649 | break; | 643 | break; |
| 650 | case _STAG_STARTDEP: | 644 | case _STAG_STARTDEP: |
| @@ -656,29 +650,24 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 656 | priority = tmp[0]; | 650 | priority = tmp[0]; |
| 657 | size = 0; | 651 | size = 0; |
| 658 | } | 652 | } |
| 659 | option = pnp_register_dependent_option(dev, priority); | 653 | option_flags = pnp_new_dependent_set(dev, priority); |
| 660 | if (!option) | ||
| 661 | return 1; | ||
| 662 | break; | 654 | break; |
| 663 | case _STAG_ENDDEP: | 655 | case _STAG_ENDDEP: |
| 664 | if (size != 0) | 656 | if (size != 0) |
| 665 | goto __skip; | 657 | goto __skip; |
| 666 | if (option_independent == option) | 658 | option_flags = 0; |
| 667 | dev_warn(&dev->dev, "missing " | ||
| 668 | "_STAG_STARTDEP tag\n"); | ||
| 669 | option = option_independent; | ||
| 670 | dev_dbg(&dev->dev, "end dependent options\n"); | ||
| 671 | break; | 659 | break; |
| 672 | case _STAG_IOPORT: | 660 | case _STAG_IOPORT: |
| 673 | if (size != 7) | 661 | if (size != 7) |
| 674 | goto __skip; | 662 | goto __skip; |
| 675 | isapnp_parse_port_resource(dev, option, size); | 663 | isapnp_parse_port_resource(dev, option_flags, size); |
| 676 | size = 0; | 664 | size = 0; |
| 677 | break; | 665 | break; |
| 678 | case _STAG_FIXEDIO: | 666 | case _STAG_FIXEDIO: |
| 679 | if (size != 3) | 667 | if (size != 3) |
| 680 | goto __skip; | 668 | goto __skip; |
| 681 | isapnp_parse_fixed_port_resource(dev, option, size); | 669 | isapnp_parse_fixed_port_resource(dev, option_flags, |
| 670 | size); | ||
| 682 | size = 0; | 671 | size = 0; |
| 683 | break; | 672 | break; |
| 684 | case _STAG_VENDOR: | 673 | case _STAG_VENDOR: |
| @@ -686,7 +675,7 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 686 | case _LTAG_MEMRANGE: | 675 | case _LTAG_MEMRANGE: |
| 687 | if (size != 9) | 676 | if (size != 9) |
| 688 | goto __skip; | 677 | goto __skip; |
| 689 | isapnp_parse_mem_resource(dev, option, size); | 678 | isapnp_parse_mem_resource(dev, option_flags, size); |
| 690 | size = 0; | 679 | size = 0; |
| 691 | break; | 680 | break; |
| 692 | case _LTAG_ANSISTR: | 681 | case _LTAG_ANSISTR: |
| @@ -701,13 +690,14 @@ static int __init isapnp_create_device(struct pnp_card *card, | |||
| 701 | case _LTAG_MEM32RANGE: | 690 | case _LTAG_MEM32RANGE: |
| 702 | if (size != 17) | 691 | if (size != 17) |
| 703 | goto __skip; | 692 | goto __skip; |
| 704 | isapnp_parse_mem32_resource(dev, option, size); | 693 | isapnp_parse_mem32_resource(dev, option_flags, size); |
| 705 | size = 0; | 694 | size = 0; |
| 706 | break; | 695 | break; |
| 707 | case _LTAG_FIXEDMEM32RANGE: | 696 | case _LTAG_FIXEDMEM32RANGE: |
| 708 | if (size != 9) | 697 | if (size != 9) |
| 709 | goto __skip; | 698 | goto __skip; |
| 710 | isapnp_parse_fixed_mem32_resource(dev, option, size); | 699 | isapnp_parse_fixed_mem32_resource(dev, option_flags, |
| 700 | size); | ||
| 711 | size = 0; | 701 | size = 0; |
| 712 | break; | 702 | break; |
| 713 | case _STAG_END: | 703 | case _STAG_END: |
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index a20accb5ef8f..b526eaad3f6c 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | * | 3 | * |
| 4 | * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> | 4 | * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> |
| 5 | * Copyright 2003 Adam Belay <ambx1@neo.rr.com> | 5 | * Copyright 2003 Adam Belay <ambx1@neo.rr.com> |
| 6 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. | ||
| 7 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
| 6 | */ | 8 | */ |
| 7 | 9 | ||
| 8 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
| @@ -228,102 +230,51 @@ static void pnp_clean_resource_table(struct pnp_dev *dev) | |||
| 228 | /** | 230 | /** |
| 229 | * pnp_assign_resources - assigns resources to the device based on the specified dependent number | 231 | * pnp_assign_resources - assigns resources to the device based on the specified dependent number |
| 230 | * @dev: pointer to the desired device | 232 | * @dev: pointer to the desired device |
| 231 | * @depnum: the dependent function number | 233 | * @set: the dependent function number |
| 232 | * | ||
| 233 | * Only set depnum to 0 if the device does not have dependent options. | ||
| 234 | */ | 234 | */ |
| 235 | static int pnp_assign_resources(struct pnp_dev *dev, int depnum) | 235 | static int pnp_assign_resources(struct pnp_dev *dev, int set) |
| 236 | { | 236 | { |
| 237 | struct pnp_port *port; | 237 | struct pnp_option *option; |
| 238 | struct pnp_mem *mem; | ||
| 239 | struct pnp_irq *irq; | ||
| 240 | struct pnp_dma *dma; | ||
| 241 | int nport = 0, nmem = 0, nirq = 0, ndma = 0; | 238 | int nport = 0, nmem = 0, nirq = 0, ndma = 0; |
| 239 | int ret = 0; | ||
| 242 | 240 | ||
| 243 | dbg_pnp_show_resources(dev, "before pnp_assign_resources"); | 241 | dev_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set); |
| 244 | mutex_lock(&pnp_res_mutex); | 242 | mutex_lock(&pnp_res_mutex); |
| 245 | pnp_clean_resource_table(dev); | 243 | pnp_clean_resource_table(dev); |
| 246 | if (dev->independent) { | ||
| 247 | dev_dbg(&dev->dev, "assigning independent options\n"); | ||
| 248 | port = dev->independent->port; | ||
| 249 | mem = dev->independent->mem; | ||
| 250 | irq = dev->independent->irq; | ||
| 251 | dma = dev->independent->dma; | ||
| 252 | while (port) { | ||
| 253 | if (pnp_assign_port(dev, port, nport) < 0) | ||
| 254 | goto fail; | ||
| 255 | nport++; | ||
| 256 | port = port->next; | ||
| 257 | } | ||
| 258 | while (mem) { | ||
| 259 | if (pnp_assign_mem(dev, mem, nmem) < 0) | ||
| 260 | goto fail; | ||
| 261 | nmem++; | ||
| 262 | mem = mem->next; | ||
| 263 | } | ||
| 264 | while (irq) { | ||
| 265 | if (pnp_assign_irq(dev, irq, nirq) < 0) | ||
| 266 | goto fail; | ||
| 267 | nirq++; | ||
| 268 | irq = irq->next; | ||
| 269 | } | ||
| 270 | while (dma) { | ||
| 271 | if (pnp_assign_dma(dev, dma, ndma) < 0) | ||
| 272 | goto fail; | ||
| 273 | ndma++; | ||
| 274 | dma = dma->next; | ||
| 275 | } | ||
| 276 | } | ||
| 277 | 244 | ||
| 278 | if (depnum) { | 245 | list_for_each_entry(option, &dev->options, list) { |
| 279 | struct pnp_option *dep; | 246 | if (pnp_option_is_dependent(option) && |
| 280 | int i; | 247 | pnp_option_set(option) != set) |
| 281 | 248 | continue; | |
| 282 | dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum); | 249 | |
| 283 | for (i = 1, dep = dev->dependent; i < depnum; | 250 | switch (option->type) { |
| 284 | i++, dep = dep->next) | 251 | case IORESOURCE_IO: |
| 285 | if (!dep) | 252 | ret = pnp_assign_port(dev, &option->u.port, nport++); |
| 286 | goto fail; | 253 | break; |
| 287 | port = dep->port; | 254 | case IORESOURCE_MEM: |
| 288 | mem = dep->mem; | 255 | ret = pnp_assign_mem(dev, &option->u.mem, nmem++); |
| 289 | irq = dep->irq; | 256 | break; |
| 290 | dma = dep->dma; | 257 | case IORESOURCE_IRQ: |
| 291 | while (port) { | 258 | ret = pnp_assign_irq(dev, &option->u.irq, nirq++); |
| 292 | if (pnp_assign_port(dev, port, nport) < 0) | 259 | break; |
| 293 | goto fail; | 260 | case IORESOURCE_DMA: |
| 294 | nport++; | 261 | ret = pnp_assign_dma(dev, &option->u.dma, ndma++); |
| 295 | port = port->next; | 262 | break; |
| 296 | } | 263 | default: |
| 297 | while (mem) { | 264 | ret = -EINVAL; |
| 298 | if (pnp_assign_mem(dev, mem, nmem) < 0) | 265 | break; |
| 299 | goto fail; | ||
| 300 | nmem++; | ||
| 301 | mem = mem->next; | ||
| 302 | } | ||
| 303 | while (irq) { | ||
| 304 | if (pnp_assign_irq(dev, irq, nirq) < 0) | ||
| 305 | goto fail; | ||
| 306 | nirq++; | ||
| 307 | irq = irq->next; | ||
| 308 | } | ||
| 309 | while (dma) { | ||
| 310 | if (pnp_assign_dma(dev, dma, ndma) < 0) | ||
| 311 | goto fail; | ||
| 312 | ndma++; | ||
| 313 | dma = dma->next; | ||
| 314 | } | 266 | } |
| 315 | } else if (dev->dependent) | 267 | if (ret < 0) |
| 316 | goto fail; | 268 | break; |
| 317 | 269 | } | |
| 318 | mutex_unlock(&pnp_res_mutex); | ||
| 319 | dbg_pnp_show_resources(dev, "after pnp_assign_resources"); | ||
| 320 | return 1; | ||
| 321 | 270 | ||
| 322 | fail: | ||
| 323 | pnp_clean_resource_table(dev); | ||
| 324 | mutex_unlock(&pnp_res_mutex); | 271 | mutex_unlock(&pnp_res_mutex); |
| 325 | dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)"); | 272 | if (ret < 0) { |
| 326 | return 0; | 273 | dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret); |
| 274 | pnp_clean_resource_table(dev); | ||
| 275 | } else | ||
| 276 | dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded"); | ||
| 277 | return ret; | ||
| 327 | } | 278 | } |
| 328 | 279 | ||
| 329 | /** | 280 | /** |
| @@ -332,29 +283,25 @@ fail: | |||
| 332 | */ | 283 | */ |
| 333 | int pnp_auto_config_dev(struct pnp_dev *dev) | 284 | int pnp_auto_config_dev(struct pnp_dev *dev) |
| 334 | { | 285 | { |
| 335 | struct pnp_option *dep; | 286 | int i, ret; |
| 336 | int i = 1; | ||
| 337 | 287 | ||
| 338 | if (!pnp_can_configure(dev)) { | 288 | if (!pnp_can_configure(dev)) { |
| 339 | dev_dbg(&dev->dev, "configuration not supported\n"); | 289 | dev_dbg(&dev->dev, "configuration not supported\n"); |
| 340 | return -ENODEV; | 290 | return -ENODEV; |
| 341 | } | 291 | } |
| 342 | 292 | ||
| 343 | if (!dev->dependent) { | 293 | ret = pnp_assign_resources(dev, 0); |
| 344 | if (pnp_assign_resources(dev, 0)) | 294 | if (ret == 0) |
| 295 | return 0; | ||
| 296 | |||
| 297 | for (i = 1; i < dev->num_dependent_sets; i++) { | ||
| 298 | ret = pnp_assign_resources(dev, i); | ||
| 299 | if (ret == 0) | ||
| 345 | return 0; | 300 | return 0; |
| 346 | } else { | ||
| 347 | dep = dev->dependent; | ||
| 348 | do { | ||
| 349 | if (pnp_assign_resources(dev, i)) | ||
| 350 | return 0; | ||
| 351 | dep = dep->next; | ||
| 352 | i++; | ||
| 353 | } while (dep); | ||
| 354 | } | 301 | } |
| 355 | 302 | ||
| 356 | dev_err(&dev->dev, "unable to assign resources\n"); | 303 | dev_err(&dev->dev, "unable to assign resources\n"); |
| 357 | return -EBUSY; | 304 | return ret; |
| 358 | } | 305 | } |
| 359 | 306 | ||
| 360 | /** | 307 | /** |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index e114b3d2b933..c2f59f4d20bc 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
| @@ -407,7 +407,7 @@ int pnpacpi_parse_allocated_resource(struct pnp_dev *dev) | |||
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, | 409 | static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, |
| 410 | struct pnp_option *option, | 410 | unsigned int option_flags, |
| 411 | struct acpi_resource_dma *p) | 411 | struct acpi_resource_dma *p) |
| 412 | { | 412 | { |
| 413 | int i; | 413 | int i; |
| @@ -420,11 +420,11 @@ static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, | |||
| 420 | map |= 1 << p->channels[i]; | 420 | map |= 1 << p->channels[i]; |
| 421 | 421 | ||
| 422 | flags = dma_flags(p->type, p->bus_master, p->transfer); | 422 | flags = dma_flags(p->type, p->bus_master, p->transfer); |
| 423 | pnp_register_dma_resource(dev, option, map, flags); | 423 | pnp_register_dma_resource(dev, option_flags, map, flags); |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, | 426 | static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, |
| 427 | struct pnp_option *option, | 427 | unsigned int option_flags, |
| 428 | struct acpi_resource_irq *p) | 428 | struct acpi_resource_irq *p) |
| 429 | { | 429 | { |
| 430 | int i; | 430 | int i; |
| @@ -440,11 +440,11 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, | |||
| 440 | __set_bit(p->interrupts[i], map.bits); | 440 | __set_bit(p->interrupts[i], map.bits); |
| 441 | 441 | ||
| 442 | flags = irq_flags(p->triggering, p->polarity, p->sharable); | 442 | flags = irq_flags(p->triggering, p->polarity, p->sharable); |
| 443 | pnp_register_irq_resource(dev, option, &map, flags); | 443 | pnp_register_irq_resource(dev, option_flags, &map, flags); |
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, | 446 | static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, |
| 447 | struct pnp_option *option, | 447 | unsigned int option_flags, |
| 448 | struct acpi_resource_extended_irq *p) | 448 | struct acpi_resource_extended_irq *p) |
| 449 | { | 449 | { |
| 450 | int i; | 450 | int i; |
| @@ -467,11 +467,11 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, | |||
| 467 | } | 467 | } |
| 468 | 468 | ||
| 469 | flags = irq_flags(p->triggering, p->polarity, p->sharable); | 469 | flags = irq_flags(p->triggering, p->polarity, p->sharable); |
| 470 | pnp_register_irq_resource(dev, option, &map, flags); | 470 | pnp_register_irq_resource(dev, option_flags, &map, flags); |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | static __init void pnpacpi_parse_port_option(struct pnp_dev *dev, | 473 | static __init void pnpacpi_parse_port_option(struct pnp_dev *dev, |
| 474 | struct pnp_option *option, | 474 | unsigned int option_flags, |
| 475 | struct acpi_resource_io *io) | 475 | struct acpi_resource_io *io) |
| 476 | { | 476 | { |
| 477 | unsigned char flags = 0; | 477 | unsigned char flags = 0; |
| @@ -481,23 +481,23 @@ static __init void pnpacpi_parse_port_option(struct pnp_dev *dev, | |||
| 481 | 481 | ||
| 482 | if (io->io_decode == ACPI_DECODE_16) | 482 | if (io->io_decode == ACPI_DECODE_16) |
| 483 | flags = IORESOURCE_IO_16BIT_ADDR; | 483 | flags = IORESOURCE_IO_16BIT_ADDR; |
| 484 | pnp_register_port_resource(dev, option, io->minimum, io->maximum, | 484 | pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum, |
| 485 | io->alignment, io->address_length, flags); | 485 | io->alignment, io->address_length, flags); |
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev, | 488 | static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev, |
| 489 | struct pnp_option *option, | 489 | unsigned int option_flags, |
| 490 | struct acpi_resource_fixed_io *io) | 490 | struct acpi_resource_fixed_io *io) |
| 491 | { | 491 | { |
| 492 | if (io->address_length == 0) | 492 | if (io->address_length == 0) |
| 493 | return; | 493 | return; |
| 494 | 494 | ||
| 495 | pnp_register_port_resource(dev, option, io->address, io->address, 0, | 495 | pnp_register_port_resource(dev, option_flags, io->address, io->address, |
| 496 | io->address_length, IORESOURCE_IO_FIXED); | 496 | 0, io->address_length, IORESOURCE_IO_FIXED); |
| 497 | } | 497 | } |
| 498 | 498 | ||
| 499 | static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev, | 499 | static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev, |
| 500 | struct pnp_option *option, | 500 | unsigned int option_flags, |
| 501 | struct acpi_resource_memory24 *p) | 501 | struct acpi_resource_memory24 *p) |
| 502 | { | 502 | { |
| 503 | unsigned char flags = 0; | 503 | unsigned char flags = 0; |
| @@ -507,12 +507,12 @@ static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev, | |||
| 507 | 507 | ||
| 508 | if (p->write_protect == ACPI_READ_WRITE_MEMORY) | 508 | if (p->write_protect == ACPI_READ_WRITE_MEMORY) |
| 509 | flags = IORESOURCE_MEM_WRITEABLE; | 509 | flags = IORESOURCE_MEM_WRITEABLE; |
| 510 | pnp_register_mem_resource(dev, option, p->minimum, p->maximum, | 510 | pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum, |
| 511 | p->alignment, p->address_length, flags); | 511 | p->alignment, p->address_length, flags); |
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev, | 514 | static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev, |
| 515 | struct pnp_option *option, | 515 | unsigned int option_flags, |
| 516 | struct acpi_resource_memory32 *p) | 516 | struct acpi_resource_memory32 *p) |
| 517 | { | 517 | { |
| 518 | unsigned char flags = 0; | 518 | unsigned char flags = 0; |
| @@ -522,12 +522,12 @@ static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev, | |||
| 522 | 522 | ||
| 523 | if (p->write_protect == ACPI_READ_WRITE_MEMORY) | 523 | if (p->write_protect == ACPI_READ_WRITE_MEMORY) |
| 524 | flags = IORESOURCE_MEM_WRITEABLE; | 524 | flags = IORESOURCE_MEM_WRITEABLE; |
| 525 | pnp_register_mem_resource(dev, option, p->minimum, p->maximum, | 525 | pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum, |
| 526 | p->alignment, p->address_length, flags); | 526 | p->alignment, p->address_length, flags); |
| 527 | } | 527 | } |
| 528 | 528 | ||
| 529 | static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev, | 529 | static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev, |
| 530 | struct pnp_option *option, | 530 | unsigned int option_flags, |
| 531 | struct acpi_resource_fixed_memory32 *p) | 531 | struct acpi_resource_fixed_memory32 *p) |
| 532 | { | 532 | { |
| 533 | unsigned char flags = 0; | 533 | unsigned char flags = 0; |
| @@ -537,12 +537,12 @@ static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev, | |||
| 537 | 537 | ||
| 538 | if (p->write_protect == ACPI_READ_WRITE_MEMORY) | 538 | if (p->write_protect == ACPI_READ_WRITE_MEMORY) |
| 539 | flags = IORESOURCE_MEM_WRITEABLE; | 539 | flags = IORESOURCE_MEM_WRITEABLE; |
| 540 | pnp_register_mem_resource(dev, option, p->address, p->address, | 540 | pnp_register_mem_resource(dev, option_flags, p->address, p->address, |
| 541 | 0, p->address_length, flags); | 541 | 0, p->address_length, flags); |
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, | 544 | static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, |
| 545 | struct pnp_option *option, | 545 | unsigned int option_flags, |
| 546 | struct acpi_resource *r) | 546 | struct acpi_resource *r) |
| 547 | { | 547 | { |
| 548 | struct acpi_resource_address64 addr, *p = &addr; | 548 | struct acpi_resource_address64 addr, *p = &addr; |
| @@ -562,18 +562,18 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, | |||
| 562 | if (p->resource_type == ACPI_MEMORY_RANGE) { | 562 | if (p->resource_type == ACPI_MEMORY_RANGE) { |
| 563 | if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) | 563 | if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) |
| 564 | flags = IORESOURCE_MEM_WRITEABLE; | 564 | flags = IORESOURCE_MEM_WRITEABLE; |
| 565 | pnp_register_mem_resource(dev, option, p->minimum, p->minimum, | 565 | pnp_register_mem_resource(dev, option_flags, p->minimum, |
| 566 | 0, p->address_length, flags); | 566 | p->minimum, 0, p->address_length, |
| 567 | flags); | ||
| 567 | } else if (p->resource_type == ACPI_IO_RANGE) | 568 | } else if (p->resource_type == ACPI_IO_RANGE) |
| 568 | pnp_register_port_resource(dev, option, p->minimum, p->minimum, | 569 | pnp_register_port_resource(dev, option_flags, p->minimum, |
| 569 | 0, p->address_length, | 570 | p->minimum, 0, p->address_length, |
| 570 | IORESOURCE_IO_FIXED); | 571 | IORESOURCE_IO_FIXED); |
| 571 | } | 572 | } |
| 572 | 573 | ||
| 573 | struct acpipnp_parse_option_s { | 574 | struct acpipnp_parse_option_s { |
| 574 | struct pnp_option *option; | ||
| 575 | struct pnp_option *option_independent; | ||
| 576 | struct pnp_dev *dev; | 575 | struct pnp_dev *dev; |
| 576 | unsigned int option_flags; | ||
| 577 | }; | 577 | }; |
| 578 | 578 | ||
| 579 | static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, | 579 | static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, |
| @@ -582,15 +582,15 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, | |||
| 582 | int priority; | 582 | int priority; |
| 583 | struct acpipnp_parse_option_s *parse_data = data; | 583 | struct acpipnp_parse_option_s *parse_data = data; |
| 584 | struct pnp_dev *dev = parse_data->dev; | 584 | struct pnp_dev *dev = parse_data->dev; |
| 585 | struct pnp_option *option = parse_data->option; | 585 | unsigned int option_flags = parse_data->option_flags; |
| 586 | 586 | ||
| 587 | switch (res->type) { | 587 | switch (res->type) { |
| 588 | case ACPI_RESOURCE_TYPE_IRQ: | 588 | case ACPI_RESOURCE_TYPE_IRQ: |
| 589 | pnpacpi_parse_irq_option(dev, option, &res->data.irq); | 589 | pnpacpi_parse_irq_option(dev, option_flags, &res->data.irq); |
| 590 | break; | 590 | break; |
| 591 | 591 | ||
| 592 | case ACPI_RESOURCE_TYPE_DMA: | 592 | case ACPI_RESOURCE_TYPE_DMA: |
| 593 | pnpacpi_parse_dma_option(dev, option, &res->data.dma); | 593 | pnpacpi_parse_dma_option(dev, option_flags, &res->data.dma); |
| 594 | break; | 594 | break; |
| 595 | 595 | ||
| 596 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: | 596 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: |
| @@ -610,31 +610,19 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, | |||
| 610 | priority = PNP_RES_PRIORITY_INVALID; | 610 | priority = PNP_RES_PRIORITY_INVALID; |
| 611 | break; | 611 | break; |
| 612 | } | 612 | } |
| 613 | /* TBD: Consider performance/robustness bits */ | 613 | parse_data->option_flags = pnp_new_dependent_set(dev, priority); |
| 614 | option = pnp_register_dependent_option(dev, priority); | ||
| 615 | if (!option) | ||
| 616 | return AE_ERROR; | ||
| 617 | parse_data->option = option; | ||
| 618 | break; | 614 | break; |
| 619 | 615 | ||
| 620 | case ACPI_RESOURCE_TYPE_END_DEPENDENT: | 616 | case ACPI_RESOURCE_TYPE_END_DEPENDENT: |
| 621 | /*only one EndDependentFn is allowed */ | 617 | parse_data->option_flags = 0; |
| 622 | if (!parse_data->option_independent) { | ||
| 623 | dev_warn(&dev->dev, "more than one EndDependentFn " | ||
| 624 | "in _PRS\n"); | ||
| 625 | return AE_ERROR; | ||
| 626 | } | ||
| 627 | parse_data->option = parse_data->option_independent; | ||
| 628 | parse_data->option_independent = NULL; | ||
| 629 | dev_dbg(&dev->dev, "end dependent options\n"); | ||
| 630 | break; | 618 | break; |
| 631 | 619 | ||
| 632 | case ACPI_RESOURCE_TYPE_IO: | 620 | case ACPI_RESOURCE_TYPE_IO: |
| 633 | pnpacpi_parse_port_option(dev, option, &res->data.io); | 621 | pnpacpi_parse_port_option(dev, option_flags, &res->data.io); |
| 634 | break; | 622 | break; |
| 635 | 623 | ||
| 636 | case ACPI_RESOURCE_TYPE_FIXED_IO: | 624 | case ACPI_RESOURCE_TYPE_FIXED_IO: |
| 637 | pnpacpi_parse_fixed_port_option(dev, option, | 625 | pnpacpi_parse_fixed_port_option(dev, option_flags, |
| 638 | &res->data.fixed_io); | 626 | &res->data.fixed_io); |
| 639 | break; | 627 | break; |
| 640 | 628 | ||
| @@ -643,29 +631,31 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, | |||
| 643 | break; | 631 | break; |
| 644 | 632 | ||
| 645 | case ACPI_RESOURCE_TYPE_MEMORY24: | 633 | case ACPI_RESOURCE_TYPE_MEMORY24: |
| 646 | pnpacpi_parse_mem24_option(dev, option, &res->data.memory24); | 634 | pnpacpi_parse_mem24_option(dev, option_flags, |
| 635 | &res->data.memory24); | ||
| 647 | break; | 636 | break; |
| 648 | 637 | ||
| 649 | case ACPI_RESOURCE_TYPE_MEMORY32: | 638 | case ACPI_RESOURCE_TYPE_MEMORY32: |
| 650 | pnpacpi_parse_mem32_option(dev, option, &res->data.memory32); | 639 | pnpacpi_parse_mem32_option(dev, option_flags, |
| 640 | &res->data.memory32); | ||
| 651 | break; | 641 | break; |
| 652 | 642 | ||
| 653 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | 643 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
| 654 | pnpacpi_parse_fixed_mem32_option(dev, option, | 644 | pnpacpi_parse_fixed_mem32_option(dev, option_flags, |
| 655 | &res->data.fixed_memory32); | 645 | &res->data.fixed_memory32); |
| 656 | break; | 646 | break; |
| 657 | 647 | ||
| 658 | case ACPI_RESOURCE_TYPE_ADDRESS16: | 648 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
| 659 | case ACPI_RESOURCE_TYPE_ADDRESS32: | 649 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
| 660 | case ACPI_RESOURCE_TYPE_ADDRESS64: | 650 | case ACPI_RESOURCE_TYPE_ADDRESS64: |
| 661 | pnpacpi_parse_address_option(dev, option, res); | 651 | pnpacpi_parse_address_option(dev, option_flags, res); |
| 662 | break; | 652 | break; |
| 663 | 653 | ||
| 664 | case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: | 654 | case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: |
| 665 | break; | 655 | break; |
| 666 | 656 | ||
| 667 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | 657 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
| 668 | pnpacpi_parse_ext_irq_option(dev, option, | 658 | pnpacpi_parse_ext_irq_option(dev, option_flags, |
| 669 | &res->data.extended_irq); | 659 | &res->data.extended_irq); |
| 670 | break; | 660 | break; |
| 671 | 661 | ||
| @@ -689,12 +679,9 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev) | |||
| 689 | 679 | ||
| 690 | dev_dbg(&dev->dev, "parse resource options\n"); | 680 | dev_dbg(&dev->dev, "parse resource options\n"); |
| 691 | 681 | ||
| 692 | parse_data.option = pnp_register_independent_option(dev); | ||
| 693 | if (!parse_data.option) | ||
| 694 | return -ENOMEM; | ||
| 695 | |||
| 696 | parse_data.option_independent = parse_data.option; | ||
| 697 | parse_data.dev = dev; | 682 | parse_data.dev = dev; |
| 683 | parse_data.option_flags = 0; | ||
| 684 | |||
| 698 | status = acpi_walk_resources(handle, METHOD_NAME__PRS, | 685 | status = acpi_walk_resources(handle, METHOD_NAME__PRS, |
| 699 | pnpacpi_option_resource, &parse_data); | 686 | pnpacpi_option_resource, &parse_data); |
| 700 | 687 | ||
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index db23ba78d39c..ca567671379e 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c | |||
| @@ -216,7 +216,7 @@ len_err: | |||
| 216 | 216 | ||
| 217 | static __init void pnpbios_parse_mem_option(struct pnp_dev *dev, | 217 | static __init void pnpbios_parse_mem_option(struct pnp_dev *dev, |
| 218 | unsigned char *p, int size, | 218 | unsigned char *p, int size, |
| 219 | struct pnp_option *option) | 219 | unsigned int option_flags) |
| 220 | { | 220 | { |
| 221 | resource_size_t min, max, align, len; | 221 | resource_size_t min, max, align, len; |
| 222 | unsigned char flags; | 222 | unsigned char flags; |
| @@ -226,12 +226,13 @@ static __init void pnpbios_parse_mem_option(struct pnp_dev *dev, | |||
| 226 | align = (p[9] << 8) | p[8]; | 226 | align = (p[9] << 8) | p[8]; |
| 227 | len = ((p[11] << 8) | p[10]) << 8; | 227 | len = ((p[11] << 8) | p[10]) << 8; |
| 228 | flags = p[3]; | 228 | flags = p[3]; |
| 229 | pnp_register_mem_resource(dev, option, min, max, align, len, flags); | 229 | pnp_register_mem_resource(dev, option_flags, min, max, align, len, |
| 230 | flags); | ||
| 230 | } | 231 | } |
| 231 | 232 | ||
| 232 | static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev, | 233 | static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev, |
| 233 | unsigned char *p, int size, | 234 | unsigned char *p, int size, |
| 234 | struct pnp_option *option) | 235 | unsigned int option_flags) |
| 235 | { | 236 | { |
| 236 | resource_size_t min, max, align, len; | 237 | resource_size_t min, max, align, len; |
| 237 | unsigned char flags; | 238 | unsigned char flags; |
| @@ -241,12 +242,13 @@ static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev, | |||
| 241 | align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; | 242 | align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; |
| 242 | len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; | 243 | len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; |
| 243 | flags = p[3]; | 244 | flags = p[3]; |
| 244 | pnp_register_mem_resource(dev, option, min, max, align, len, flags); | 245 | pnp_register_mem_resource(dev, option_flags, min, max, align, len, |
| 246 | flags); | ||
| 245 | } | 247 | } |
| 246 | 248 | ||
| 247 | static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev, | 249 | static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev, |
| 248 | unsigned char *p, int size, | 250 | unsigned char *p, int size, |
| 249 | struct pnp_option *option) | 251 | unsigned int option_flags) |
| 250 | { | 252 | { |
| 251 | resource_size_t base, len; | 253 | resource_size_t base, len; |
| 252 | unsigned char flags; | 254 | unsigned char flags; |
| @@ -254,12 +256,12 @@ static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev, | |||
| 254 | base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; | 256 | base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; |
| 255 | len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; | 257 | len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; |
| 256 | flags = p[3]; | 258 | flags = p[3]; |
| 257 | pnp_register_mem_resource(dev, option, base, base, 0, len, flags); | 259 | pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags); |
| 258 | } | 260 | } |
| 259 | 261 | ||
| 260 | static __init void pnpbios_parse_irq_option(struct pnp_dev *dev, | 262 | static __init void pnpbios_parse_irq_option(struct pnp_dev *dev, |
| 261 | unsigned char *p, int size, | 263 | unsigned char *p, int size, |
| 262 | struct pnp_option *option) | 264 | unsigned int option_flags) |
| 263 | { | 265 | { |
| 264 | unsigned long bits; | 266 | unsigned long bits; |
| 265 | pnp_irq_mask_t map; | 267 | pnp_irq_mask_t map; |
| @@ -273,19 +275,19 @@ static __init void pnpbios_parse_irq_option(struct pnp_dev *dev, | |||
| 273 | if (size > 2) | 275 | if (size > 2) |
| 274 | flags = p[3]; | 276 | flags = p[3]; |
| 275 | 277 | ||
| 276 | pnp_register_irq_resource(dev, option, &map, flags); | 278 | pnp_register_irq_resource(dev, option_flags, &map, flags); |
| 277 | } | 279 | } |
| 278 | 280 | ||
| 279 | static __init void pnpbios_parse_dma_option(struct pnp_dev *dev, | 281 | static __init void pnpbios_parse_dma_option(struct pnp_dev *dev, |
| 280 | unsigned char *p, int size, | 282 | unsigned char *p, int size, |
| 281 | struct pnp_option *option) | 283 | unsigned int option_flags) |
| 282 | { | 284 | { |
| 283 | pnp_register_dma_resource(dev, option, p[1], p[2]); | 285 | pnp_register_dma_resource(dev, option_flags, p[1], p[2]); |
| 284 | } | 286 | } |
| 285 | 287 | ||
| 286 | static __init void pnpbios_parse_port_option(struct pnp_dev *dev, | 288 | static __init void pnpbios_parse_port_option(struct pnp_dev *dev, |
| 287 | unsigned char *p, int size, | 289 | unsigned char *p, int size, |
| 288 | struct pnp_option *option) | 290 | unsigned int option_flags) |
| 289 | { | 291 | { |
| 290 | resource_size_t min, max, align, len; | 292 | resource_size_t min, max, align, len; |
| 291 | unsigned char flags; | 293 | unsigned char flags; |
| @@ -295,38 +297,35 @@ static __init void pnpbios_parse_port_option(struct pnp_dev *dev, | |||
| 295 | align = p[6]; | 297 | align = p[6]; |
| 296 | len = p[7]; | 298 | len = p[7]; |
| 297 | flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0; | 299 | flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0; |
| 298 | pnp_register_port_resource(dev, option, min, max, align, len, flags); | 300 | pnp_register_port_resource(dev, option_flags, min, max, align, len, |
| 301 | flags); | ||
| 299 | } | 302 | } |
| 300 | 303 | ||
| 301 | static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev, | 304 | static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev, |
| 302 | unsigned char *p, int size, | 305 | unsigned char *p, int size, |
| 303 | struct pnp_option *option) | 306 | unsigned int option_flags) |
| 304 | { | 307 | { |
| 305 | resource_size_t base, len; | 308 | resource_size_t base, len; |
| 306 | 309 | ||
| 307 | base = (p[2] << 8) | p[1]; | 310 | base = (p[2] << 8) | p[1]; |
| 308 | len = p[3]; | 311 | len = p[3]; |
| 309 | pnp_register_port_resource(dev, option, base, base, 0, len, | 312 | pnp_register_port_resource(dev, option_flags, base, base, 0, len, |
| 310 | IORESOURCE_IO_FIXED); | 313 | IORESOURCE_IO_FIXED); |
| 311 | } | 314 | } |
| 312 | 315 | ||
| 313 | static __init unsigned char * | 316 | static __init unsigned char * |
| 314 | pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, | 317 | pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, |
| 315 | struct pnp_dev *dev) | 318 | struct pnp_dev *dev) |
| 316 | { | 319 | { |
| 317 | unsigned int len, tag; | 320 | unsigned int len, tag; |
| 318 | int priority; | 321 | int priority; |
| 319 | struct pnp_option *option, *option_independent; | 322 | unsigned int option_flags; |
| 320 | 323 | ||
| 321 | if (!p) | 324 | if (!p) |
| 322 | return NULL; | 325 | return NULL; |
| 323 | 326 | ||
| 324 | dev_dbg(&dev->dev, "parse resource options\n"); | 327 | dev_dbg(&dev->dev, "parse resource options\n"); |
| 325 | 328 | option_flags = 0; | |
| 326 | option_independent = option = pnp_register_independent_option(dev); | ||
| 327 | if (!option) | ||
| 328 | return NULL; | ||
| 329 | |||
| 330 | while ((char *)p < (char *)end) { | 329 | while ((char *)p < (char *)end) { |
| 331 | 330 | ||
| 332 | /* determine the type of tag */ | 331 | /* determine the type of tag */ |
| @@ -343,37 +342,38 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, | |||
| 343 | case LARGE_TAG_MEM: | 342 | case LARGE_TAG_MEM: |
| 344 | if (len != 9) | 343 | if (len != 9) |
| 345 | goto len_err; | 344 | goto len_err; |
| 346 | pnpbios_parse_mem_option(dev, p, len, option); | 345 | pnpbios_parse_mem_option(dev, p, len, option_flags); |
| 347 | break; | 346 | break; |
| 348 | 347 | ||
| 349 | case LARGE_TAG_MEM32: | 348 | case LARGE_TAG_MEM32: |
| 350 | if (len != 17) | 349 | if (len != 17) |
| 351 | goto len_err; | 350 | goto len_err; |
| 352 | pnpbios_parse_mem32_option(dev, p, len, option); | 351 | pnpbios_parse_mem32_option(dev, p, len, option_flags); |
| 353 | break; | 352 | break; |
| 354 | 353 | ||
| 355 | case LARGE_TAG_FIXEDMEM32: | 354 | case LARGE_TAG_FIXEDMEM32: |
| 356 | if (len != 9) | 355 | if (len != 9) |
| 357 | goto len_err; | 356 | goto len_err; |
| 358 | pnpbios_parse_fixed_mem32_option(dev, p, len, option); | 357 | pnpbios_parse_fixed_mem32_option(dev, p, len, |
| 358 | option_flags); | ||
| 359 | break; | 359 | break; |
| 360 | 360 | ||
| 361 | case SMALL_TAG_IRQ: | 361 | case SMALL_TAG_IRQ: |
| 362 | if (len < 2 || len > 3) | 362 | if (len < 2 || len > 3) |
| 363 | goto len_err; | 363 | goto len_err; |
| 364 | pnpbios_parse_irq_option(dev, p, len, option); | 364 | pnpbios_parse_irq_option(dev, p, len, option_flags); |
| 365 | break; | 365 | break; |
| 366 | 366 | ||
| 367 | case SMALL_TAG_DMA: | 367 | case SMALL_TAG_DMA: |
| 368 | if (len != 2) | 368 | if (len != 2) |
| 369 | goto len_err; | 369 | goto len_err; |
| 370 | pnpbios_parse_dma_option(dev, p, len, option); | 370 | pnpbios_parse_dma_option(dev, p, len, option_flags); |
| 371 | break; | 371 | break; |
| 372 | 372 | ||
| 373 | case SMALL_TAG_PORT: | 373 | case SMALL_TAG_PORT: |
| 374 | if (len != 7) | 374 | if (len != 7) |
| 375 | goto len_err; | 375 | goto len_err; |
| 376 | pnpbios_parse_port_option(dev, p, len, option); | 376 | pnpbios_parse_port_option(dev, p, len, option_flags); |
| 377 | break; | 377 | break; |
| 378 | 378 | ||
| 379 | case SMALL_TAG_VENDOR: | 379 | case SMALL_TAG_VENDOR: |
| @@ -383,7 +383,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, | |||
| 383 | case SMALL_TAG_FIXEDPORT: | 383 | case SMALL_TAG_FIXEDPORT: |
| 384 | if (len != 3) | 384 | if (len != 3) |
| 385 | goto len_err; | 385 | goto len_err; |
| 386 | pnpbios_parse_fixed_port_option(dev, p, len, option); | 386 | pnpbios_parse_fixed_port_option(dev, p, len, |
| 387 | option_flags); | ||
| 387 | break; | 388 | break; |
| 388 | 389 | ||
| 389 | case SMALL_TAG_STARTDEP: | 390 | case SMALL_TAG_STARTDEP: |
| @@ -392,19 +393,13 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, | |||
| 392 | priority = PNP_RES_PRIORITY_ACCEPTABLE; | 393 | priority = PNP_RES_PRIORITY_ACCEPTABLE; |
| 393 | if (len > 0) | 394 | if (len > 0) |
| 394 | priority = p[1]; | 395 | priority = p[1]; |
| 395 | option = pnp_register_dependent_option(dev, priority); | 396 | option_flags = pnp_new_dependent_set(dev, priority); |
| 396 | if (!option) | ||
| 397 | return NULL; | ||
| 398 | break; | 397 | break; |
| 399 | 398 | ||
| 400 | case SMALL_TAG_ENDDEP: | 399 | case SMALL_TAG_ENDDEP: |
| 401 | if (len != 0) | 400 | if (len != 0) |
| 402 | goto len_err; | 401 | goto len_err; |
| 403 | if (option_independent == option) | 402 | option_flags = 0; |
| 404 | dev_warn(&dev->dev, "missing " | ||
| 405 | "SMALL_TAG_STARTDEP tag\n"); | ||
| 406 | option = option_independent; | ||
| 407 | dev_dbg(&dev->dev, "end dependent options\n"); | ||
| 408 | break; | 403 | break; |
| 409 | 404 | ||
| 410 | case SMALL_TAG_END: | 405 | case SMALL_TAG_END: |
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index e8515ce0d296..55f55ed72dc7 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | * when building up the resource structure for the first time. | 5 | * when building up the resource structure for the first time. |
| 6 | * | 6 | * |
| 7 | * Copyright (c) 2000 Peter Denison <peterd@pnd-pc.demon.co.uk> | 7 | * Copyright (c) 2000 Peter Denison <peterd@pnd-pc.demon.co.uk> |
| 8 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. | ||
| 9 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
| 8 | * | 10 | * |
| 9 | * Heavily based on PCI quirks handling which is | 11 | * Heavily based on PCI quirks handling which is |
| 10 | * | 12 | * |
| @@ -20,189 +22,207 @@ | |||
| 20 | #include <linux/kallsyms.h> | 22 | #include <linux/kallsyms.h> |
| 21 | #include "base.h" | 23 | #include "base.h" |
| 22 | 24 | ||
| 25 | static void quirk_awe32_add_ports(struct pnp_dev *dev, | ||
| 26 | struct pnp_option *option, | ||
| 27 | unsigned int offset) | ||
| 28 | { | ||
| 29 | struct pnp_option *new_option; | ||
| 30 | |||
| 31 | new_option = kmalloc(sizeof(struct pnp_option), GFP_KERNEL); | ||
| 32 | if (!new_option) { | ||
| 33 | dev_err(&dev->dev, "couldn't add ioport region to option set " | ||
| 34 | "%d\n", pnp_option_set(option)); | ||
| 35 | return; | ||
| 36 | } | ||
| 37 | |||
| 38 | *new_option = *option; | ||
| 39 | new_option->u.port.min += offset; | ||
| 40 | new_option->u.port.max += offset; | ||
| 41 | list_add(&new_option->list, &option->list); | ||
| 42 | |||
| 43 | dev_info(&dev->dev, "added ioport region %#llx-%#llx to set %d\n", | ||
| 44 | (unsigned long long) new_option->u.port.min, | ||
| 45 | (unsigned long long) new_option->u.port.max, | ||
| 46 | pnp_option_set(option)); | ||
| 47 | } | ||
| 48 | |||
| 23 | static void quirk_awe32_resources(struct pnp_dev *dev) | 49 | static void quirk_awe32_resources(struct pnp_dev *dev) |
| 24 | { | 50 | { |
| 25 | struct pnp_port *port, *port2, *port3; | 51 | struct pnp_option *option; |
| 26 | struct pnp_option *res = dev->dependent; | 52 | unsigned int set = ~0; |
| 27 | 53 | ||
| 28 | /* | 54 | /* |
| 29 | * Unfortunately the isapnp_add_port_resource is too tightly bound | 55 | * Add two extra ioport regions (at offset 0x400 and 0x800 from the |
| 30 | * into the PnP discovery sequence, and cannot be used. Link in the | 56 | * one given) to every dependent option set. |
| 31 | * two extra ports (at offset 0x400 and 0x800 from the one given) by | ||
| 32 | * hand. | ||
| 33 | */ | 57 | */ |
| 34 | for (; res; res = res->next) { | 58 | list_for_each_entry(option, &dev->options, list) { |
| 35 | port2 = pnp_alloc(sizeof(struct pnp_port)); | 59 | if (pnp_option_is_dependent(option) && |
| 36 | if (!port2) | 60 | pnp_option_set(option) != set) { |
| 37 | return; | 61 | set = pnp_option_set(option); |
| 38 | port3 = pnp_alloc(sizeof(struct pnp_port)); | 62 | quirk_awe32_add_ports(dev, option, 0x800); |
| 39 | if (!port3) { | 63 | quirk_awe32_add_ports(dev, option, 0x400); |
| 40 | kfree(port2); | ||
| 41 | return; | ||
| 42 | } | 64 | } |
| 43 | port = res->port; | ||
| 44 | memcpy(port2, port, sizeof(struct pnp_port)); | ||
| 45 | memcpy(port3, port, sizeof(struct pnp_port)); | ||
| 46 | port->next = port2; | ||
| 47 | port2->next = port3; | ||
| 48 | port2->min += 0x400; | ||
| 49 | port2->max += 0x400; | ||
| 50 | port3->min += 0x800; | ||
| 51 | port3->max += 0x800; | ||
| 52 | dev_info(&dev->dev, | ||
| 53 | "AWE32 quirk - added ioports 0x%lx and 0x%lx\n", | ||
| 54 | (unsigned long)port2->min, | ||
| 55 | (unsigned long)port3->min); | ||
| 56 | } | 65 | } |
| 57 | } | 66 | } |
| 58 | 67 | ||
| 59 | static void quirk_cmi8330_resources(struct pnp_dev *dev) | 68 | static void quirk_cmi8330_resources(struct pnp_dev *dev) |
| 60 | { | 69 | { |
| 61 | struct pnp_option *res = dev->dependent; | 70 | struct pnp_option *option; |
| 62 | unsigned long tmp; | 71 | struct pnp_irq *irq; |
| 63 | 72 | struct pnp_dma *dma; | |
| 64 | for (; res; res = res->next) { | ||
| 65 | |||
| 66 | struct pnp_irq *irq; | ||
| 67 | struct pnp_dma *dma; | ||
| 68 | 73 | ||
| 69 | for (irq = res->irq; irq; irq = irq->next) { | 74 | list_for_each_entry(option, &dev->options, list) { |
| 70 | /* Valid irqs are 5, 7, 10 */ | 75 | if (!pnp_option_is_dependent(option)) |
| 71 | tmp = 0x04A0; | 76 | continue; |
| 72 | bitmap_copy(irq->map.bits, &tmp, 16); | ||
| 73 | } | ||
| 74 | 77 | ||
| 75 | for (dma = res->dma; dma; dma = dma->next) { | 78 | if (option->type == IORESOURCE_IRQ) { |
| 76 | /* Valid 8bit dma channels are 1,3 */ | 79 | irq = &option->u.irq; |
| 80 | bitmap_zero(irq->map.bits, PNP_IRQ_NR); | ||
| 81 | __set_bit(5, irq->map.bits); | ||
| 82 | __set_bit(7, irq->map.bits); | ||
| 83 | __set_bit(10, irq->map.bits); | ||
| 84 | dev_info(&dev->dev, "set possible IRQs in " | ||
| 85 | "option set %d to 5, 7, 10\n", | ||
| 86 | pnp_option_set(option)); | ||
| 87 | } else if (option->type == IORESOURCE_DMA) { | ||
| 88 | dma = &option->u.dma; | ||
| 77 | if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) == | 89 | if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) == |
| 78 | IORESOURCE_DMA_8BIT) | 90 | IORESOURCE_DMA_8BIT && |
| 79 | dma->map = 0x000A; | 91 | dma->map != 0x0A) { |
| 92 | dev_info(&dev->dev, "changing possible " | ||
| 93 | "DMA channel mask in option set %d " | ||
| 94 | "from %#02x to 0x0A (1, 3)\n", | ||
| 95 | pnp_option_set(option), dma->map); | ||
| 96 | dma->map = 0x0A; | ||
| 97 | } | ||
| 80 | } | 98 | } |
| 81 | } | 99 | } |
| 82 | dev_info(&dev->dev, "CMI8330 quirk - forced possible IRQs to 5, 7, 10 " | ||
| 83 | "and DMA channels to 1, 3\n"); | ||
| 84 | } | 100 | } |
| 85 | 101 | ||
| 86 | static void quirk_sb16audio_resources(struct pnp_dev *dev) | 102 | static void quirk_sb16audio_resources(struct pnp_dev *dev) |
| 87 | { | 103 | { |
| 104 | struct pnp_option *option; | ||
| 105 | unsigned int prev_option_flags = ~0, n = 0; | ||
| 88 | struct pnp_port *port; | 106 | struct pnp_port *port; |
| 89 | struct pnp_option *res = dev->dependent; | ||
| 90 | int changed = 0; | ||
| 91 | 107 | ||
| 92 | /* | 108 | /* |
| 93 | * The default range on the mpu port for these devices is 0x388-0x388. | 109 | * The default range on the OPL port for these devices is 0x388-0x388. |
| 94 | * Here we increase that range so that two such cards can be | 110 | * Here we increase that range so that two such cards can be |
| 95 | * auto-configured. | 111 | * auto-configured. |
| 96 | */ | 112 | */ |
| 113 | list_for_each_entry(option, &dev->options, list) { | ||
| 114 | if (prev_option_flags != option->flags) { | ||
| 115 | prev_option_flags = option->flags; | ||
| 116 | n = 0; | ||
| 117 | } | ||
| 97 | 118 | ||
| 98 | for (; res; res = res->next) { | 119 | if (pnp_option_is_dependent(option) && |
| 99 | port = res->port; | 120 | option->type == IORESOURCE_IO) { |
| 100 | if (!port) | 121 | n++; |
| 101 | continue; | 122 | port = &option->u.port; |
| 102 | port = port->next; | 123 | if (n == 3 && port->min == port->max) { |
| 103 | if (!port) | 124 | port->max += 0x70; |
| 104 | continue; | 125 | dev_info(&dev->dev, "increased option port " |
| 105 | port = port->next; | 126 | "range from %#llx-%#llx to " |
| 106 | if (!port) | 127 | "%#llx-%#llx\n", |
| 107 | continue; | 128 | (unsigned long long) port->min, |
| 108 | if (port->min != port->max) | 129 | (unsigned long long) port->min, |
| 109 | continue; | 130 | (unsigned long long) port->min, |
| 110 | port->max += 0x70; | 131 | (unsigned long long) port->max); |
| 111 | changed = 1; | 132 | } |
| 133 | } | ||
| 112 | } | 134 | } |
| 113 | if (changed) | ||
| 114 | dev_info(&dev->dev, "SB audio device quirk - increased port range\n"); | ||
| 115 | } | 135 | } |
| 116 | 136 | ||
| 117 | static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) | 137 | static struct pnp_option *pnp_clone_dependent_set(struct pnp_dev *dev, |
| 138 | unsigned int set) | ||
| 118 | { | 139 | { |
| 119 | struct pnp_option *head = NULL; | 140 | struct pnp_option *tail = NULL, *first_new_option = NULL; |
| 120 | struct pnp_option *prev = NULL; | 141 | struct pnp_option *option, *new_option; |
| 121 | struct pnp_option *res; | 142 | unsigned int flags; |
| 122 | |||
| 123 | /* | ||
| 124 | * Build a functional IRQ-optional variant of each MPU option. | ||
| 125 | */ | ||
| 126 | |||
| 127 | for (res = dev->dependent; res; res = res->next) { | ||
| 128 | struct pnp_option *curr; | ||
| 129 | struct pnp_port *port; | ||
| 130 | struct pnp_port *copy_port; | ||
| 131 | struct pnp_irq *irq; | ||
| 132 | struct pnp_irq *copy_irq; | ||
| 133 | |||
| 134 | port = res->port; | ||
| 135 | irq = res->irq; | ||
| 136 | if (!port || !irq) | ||
| 137 | continue; | ||
| 138 | 143 | ||
| 139 | copy_port = pnp_alloc(sizeof *copy_port); | 144 | list_for_each_entry(option, &dev->options, list) { |
| 140 | if (!copy_port) | 145 | if (pnp_option_is_dependent(option)) |
| 141 | break; | 146 | tail = option; |
| 142 | 147 | } | |
| 143 | copy_irq = pnp_alloc(sizeof *copy_irq); | 148 | if (!tail) { |
| 144 | if (!copy_irq) { | 149 | dev_err(&dev->dev, "no dependent option sets\n"); |
| 145 | kfree(copy_port); | 150 | return NULL; |
| 146 | break; | 151 | } |
| 147 | } | ||
| 148 | 152 | ||
| 149 | *copy_port = *port; | 153 | flags = pnp_new_dependent_set(dev, PNP_RES_PRIORITY_FUNCTIONAL); |
| 150 | copy_port->next = NULL; | 154 | list_for_each_entry(option, &dev->options, list) { |
| 155 | if (pnp_option_is_dependent(option) && | ||
| 156 | pnp_option_set(option) == set) { | ||
| 157 | new_option = kmalloc(sizeof(struct pnp_option), | ||
| 158 | GFP_KERNEL); | ||
| 159 | if (!new_option) { | ||
| 160 | dev_err(&dev->dev, "couldn't clone dependent " | ||
| 161 | "set %d\n", set); | ||
| 162 | return NULL; | ||
| 163 | } | ||
| 151 | 164 | ||
| 152 | *copy_irq = *irq; | 165 | *new_option = *option; |
| 153 | copy_irq->flags |= IORESOURCE_IRQ_OPTIONAL; | 166 | new_option->flags = flags; |
| 154 | copy_irq->next = NULL; | 167 | if (!first_new_option) |
| 168 | first_new_option = new_option; | ||
| 155 | 169 | ||
| 156 | curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL); | 170 | list_add(&new_option->list, &tail->list); |
| 157 | if (!curr) { | 171 | tail = new_option; |
| 158 | kfree(copy_port); | ||
| 159 | kfree(copy_irq); | ||
| 160 | break; | ||
| 161 | } | 172 | } |
| 162 | curr->port = copy_port; | ||
| 163 | curr->irq = copy_irq; | ||
| 164 | |||
| 165 | if (prev) | ||
| 166 | prev->next = curr; | ||
| 167 | else | ||
| 168 | head = curr; | ||
| 169 | prev = curr; | ||
| 170 | } | 173 | } |
| 171 | if (head) | ||
| 172 | dev_info(&dev->dev, "adding IRQ-optional MPU options\n"); | ||
| 173 | 174 | ||
| 174 | return head; | 175 | return first_new_option; |
| 175 | } | 176 | } |
| 176 | 177 | ||
| 177 | static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) | 178 | |
| 179 | static void quirk_add_irq_optional_dependent_sets(struct pnp_dev *dev) | ||
| 178 | { | 180 | { |
| 179 | struct pnp_option *res; | 181 | struct pnp_option *new_option; |
| 182 | unsigned int num_sets, i, set; | ||
| 180 | struct pnp_irq *irq; | 183 | struct pnp_irq *irq; |
| 181 | 184 | ||
| 182 | res = dev->independent; | 185 | num_sets = dev->num_dependent_sets; |
| 183 | if (!res) | 186 | for (i = 0; i < num_sets; i++) { |
| 184 | return; | 187 | new_option = pnp_clone_dependent_set(dev, i); |
| 188 | if (!new_option) | ||
| 189 | return; | ||
| 185 | 190 | ||
| 186 | irq = res->irq; | 191 | set = pnp_option_set(new_option); |
| 187 | if (!irq || irq->next) | 192 | while (new_option && pnp_option_set(new_option) == set) { |
| 188 | return; | 193 | if (new_option->type == IORESOURCE_IRQ) { |
| 194 | irq = &new_option->u.irq; | ||
| 195 | irq->flags |= IORESOURCE_IRQ_OPTIONAL; | ||
| 196 | } | ||
| 197 | dbg_pnp_show_option(dev, new_option); | ||
| 198 | new_option = list_entry(new_option->list.next, | ||
| 199 | struct pnp_option, list); | ||
| 200 | } | ||
| 189 | 201 | ||
| 190 | irq->flags |= IORESOURCE_IRQ_OPTIONAL; | 202 | dev_info(&dev->dev, "added dependent option set %d (same as " |
| 191 | dev_info(&dev->dev, "made independent IRQ optional\n"); | 203 | "set %d except IRQ optional)\n", set, i); |
| 204 | } | ||
| 192 | } | 205 | } |
| 193 | 206 | ||
| 194 | static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) | 207 | static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) |
| 195 | { | 208 | { |
| 196 | struct pnp_option *res; | 209 | struct pnp_option *option; |
| 210 | struct pnp_irq *irq = NULL; | ||
| 211 | unsigned int independent_irqs = 0; | ||
| 212 | |||
| 213 | list_for_each_entry(option, &dev->options, list) { | ||
| 214 | if (option->type == IORESOURCE_IRQ && | ||
| 215 | !pnp_option_is_dependent(option)) { | ||
| 216 | independent_irqs++; | ||
| 217 | irq = &option->u.irq; | ||
| 218 | } | ||
| 219 | } | ||
| 197 | 220 | ||
| 198 | res = dev->dependent; | 221 | if (independent_irqs != 1) |
| 199 | if (!res) | ||
| 200 | return; | 222 | return; |
| 201 | 223 | ||
| 202 | while (res->next) | 224 | irq->flags |= IORESOURCE_IRQ_OPTIONAL; |
| 203 | res = res->next; | 225 | dev_info(&dev->dev, "made independent IRQ optional\n"); |
| 204 | |||
| 205 | res->next = quirk_isapnp_mpu_options(dev); | ||
| 206 | } | 226 | } |
| 207 | 227 | ||
| 208 | #include <linux/pci.h> | 228 | #include <linux/pci.h> |
| @@ -297,10 +317,10 @@ static struct pnp_fixup pnp_fixups[] = { | |||
| 297 | {"CTL0043", quirk_sb16audio_resources}, | 317 | {"CTL0043", quirk_sb16audio_resources}, |
| 298 | {"CTL0044", quirk_sb16audio_resources}, | 318 | {"CTL0044", quirk_sb16audio_resources}, |
| 299 | {"CTL0045", quirk_sb16audio_resources}, | 319 | {"CTL0045", quirk_sb16audio_resources}, |
| 300 | /* Add IRQ-less MPU options */ | 320 | /* Add IRQ-optional MPU options */ |
| 301 | {"ADS7151", quirk_ad1815_mpu_resources}, | 321 | {"ADS7151", quirk_ad1815_mpu_resources}, |
| 302 | {"ADS7181", quirk_isapnp_mpu_resources}, | 322 | {"ADS7181", quirk_add_irq_optional_dependent_sets}, |
| 303 | {"AZT0002", quirk_isapnp_mpu_resources}, | 323 | {"AZT0002", quirk_add_irq_optional_dependent_sets}, |
| 304 | /* PnP resources that might overlap PCI BARs */ | 324 | /* PnP resources that might overlap PCI BARs */ |
| 305 | {"PNP0c01", quirk_system_pci_resources}, | 325 | {"PNP0c01", quirk_system_pci_resources}, |
| 306 | {"PNP0c02", quirk_system_pci_resources}, | 326 | {"PNP0c02", quirk_system_pci_resources}, |
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index a795864dc695..d6388970a1a4 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | * | 3 | * |
| 4 | * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> | 4 | * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> |
| 5 | * Copyright 2003 Adam Belay <ambx1@neo.rr.com> | 5 | * Copyright 2003 Adam Belay <ambx1@neo.rr.com> |
| 6 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. | ||
| 7 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
| 6 | */ | 8 | */ |
| 7 | 9 | ||
| 8 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| @@ -28,78 +30,36 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some | |||
| 28 | * option registration | 30 | * option registration |
| 29 | */ | 31 | */ |
| 30 | 32 | ||
| 31 | struct pnp_option *pnp_build_option(int priority) | 33 | struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type, |
| 34 | unsigned int option_flags) | ||
| 32 | { | 35 | { |
| 33 | struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option)); | 36 | struct pnp_option *option; |
| 34 | 37 | ||
| 38 | option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL); | ||
| 35 | if (!option) | 39 | if (!option) |
| 36 | return NULL; | 40 | return NULL; |
| 37 | 41 | ||
| 38 | option->priority = priority & 0xff; | 42 | option->flags = option_flags; |
| 39 | /* make sure the priority is valid */ | 43 | option->type = type; |
| 40 | if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL) | ||
| 41 | option->priority = PNP_RES_PRIORITY_INVALID; | ||
| 42 | |||
| 43 | return option; | ||
| 44 | } | ||
| 45 | |||
| 46 | struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev) | ||
| 47 | { | ||
| 48 | struct pnp_option *option; | ||
| 49 | |||
| 50 | option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED); | ||
| 51 | |||
| 52 | /* this should never happen but if it does we'll try to continue */ | ||
| 53 | if (dev->independent) | ||
| 54 | dev_err(&dev->dev, "independent resource already registered\n"); | ||
| 55 | dev->independent = option; | ||
| 56 | |||
| 57 | dev_dbg(&dev->dev, "new independent option\n"); | ||
| 58 | return option; | ||
| 59 | } | ||
| 60 | |||
| 61 | struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, | ||
| 62 | int priority) | ||
| 63 | { | ||
| 64 | struct pnp_option *option; | ||
| 65 | 44 | ||
| 66 | option = pnp_build_option(priority); | 45 | list_add_tail(&option->list, &dev->options); |
| 67 | |||
| 68 | if (dev->dependent) { | ||
| 69 | struct pnp_option *parent = dev->dependent; | ||
| 70 | while (parent->next) | ||
| 71 | parent = parent->next; | ||
| 72 | parent->next = option; | ||
| 73 | } else | ||
| 74 | dev->dependent = option; | ||
| 75 | |||
| 76 | dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority); | ||
| 77 | return option; | 46 | return option; |
| 78 | } | 47 | } |
| 79 | 48 | ||
| 80 | int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, | 49 | int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags, |
| 81 | pnp_irq_mask_t *map, unsigned char flags) | 50 | pnp_irq_mask_t *map, unsigned char flags) |
| 82 | { | 51 | { |
| 83 | struct pnp_irq *irq, *ptr; | 52 | struct pnp_option *option; |
| 84 | #ifdef DEBUG | 53 | struct pnp_irq *irq; |
| 85 | char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */ | ||
| 86 | #endif | ||
| 87 | 54 | ||
| 88 | irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL); | 55 | option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags); |
| 89 | if (!irq) | 56 | if (!option) |
| 90 | return -ENOMEM; | 57 | return -ENOMEM; |
| 91 | 58 | ||
| 59 | irq = &option->u.irq; | ||
| 92 | irq->map = *map; | 60 | irq->map = *map; |
| 93 | irq->flags = flags; | 61 | irq->flags = flags; |
| 94 | 62 | ||
| 95 | ptr = option->irq; | ||
| 96 | while (ptr && ptr->next) | ||
| 97 | ptr = ptr->next; | ||
| 98 | if (ptr) | ||
| 99 | ptr->next = irq; | ||
| 100 | else | ||
| 101 | option->irq = irq; | ||
| 102 | |||
| 103 | #ifdef CONFIG_PCI | 63 | #ifdef CONFIG_PCI |
| 104 | { | 64 | { |
| 105 | int i; | 65 | int i; |
| @@ -110,163 +70,81 @@ int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, | |||
| 110 | } | 70 | } |
| 111 | #endif | 71 | #endif |
| 112 | 72 | ||
| 113 | #ifdef DEBUG | 73 | dbg_pnp_show_option(dev, option); |
| 114 | bitmap_scnprintf(buf, sizeof(buf), irq->map.bits, PNP_IRQ_NR); | ||
| 115 | dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf, | ||
| 116 | irq->flags); | ||
| 117 | #endif | ||
| 118 | return 0; | 74 | return 0; |
| 119 | } | 75 | } |
| 120 | 76 | ||
| 121 | int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, | 77 | int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags, |
| 122 | unsigned char map, unsigned char flags) | 78 | unsigned char map, unsigned char flags) |
| 123 | { | 79 | { |
| 124 | struct pnp_dma *dma, *ptr; | 80 | struct pnp_option *option; |
| 81 | struct pnp_dma *dma; | ||
| 125 | 82 | ||
| 126 | dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); | 83 | option = pnp_build_option(dev, IORESOURCE_DMA, option_flags); |
| 127 | if (!dma) | 84 | if (!option) |
| 128 | return -ENOMEM; | 85 | return -ENOMEM; |
| 129 | 86 | ||
| 87 | dma = &option->u.dma; | ||
| 130 | dma->map = map; | 88 | dma->map = map; |
| 131 | dma->flags = flags; | 89 | dma->flags = flags; |
| 132 | 90 | ||
| 133 | ptr = option->dma; | 91 | dbg_pnp_show_option(dev, option); |
| 134 | while (ptr && ptr->next) | ||
| 135 | ptr = ptr->next; | ||
| 136 | if (ptr) | ||
| 137 | ptr->next = dma; | ||
| 138 | else | ||
| 139 | option->dma = dma; | ||
| 140 | |||
| 141 | dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", dma->map, | ||
| 142 | dma->flags); | ||
| 143 | return 0; | 92 | return 0; |
| 144 | } | 93 | } |
| 145 | 94 | ||
| 146 | int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, | 95 | int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags, |
| 147 | resource_size_t min, resource_size_t max, | 96 | resource_size_t min, resource_size_t max, |
| 148 | resource_size_t align, resource_size_t size, | 97 | resource_size_t align, resource_size_t size, |
| 149 | unsigned char flags) | 98 | unsigned char flags) |
| 150 | { | 99 | { |
| 151 | struct pnp_port *port, *ptr; | 100 | struct pnp_option *option; |
| 101 | struct pnp_port *port; | ||
| 152 | 102 | ||
| 153 | port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); | 103 | option = pnp_build_option(dev, IORESOURCE_IO, option_flags); |
| 154 | if (!port) | 104 | if (!option) |
| 155 | return -ENOMEM; | 105 | return -ENOMEM; |
| 156 | 106 | ||
| 107 | port = &option->u.port; | ||
| 157 | port->min = min; | 108 | port->min = min; |
| 158 | port->max = max; | 109 | port->max = max; |
| 159 | port->align = align; | 110 | port->align = align; |
| 160 | port->size = size; | 111 | port->size = size; |
| 161 | port->flags = flags; | 112 | port->flags = flags; |
| 162 | 113 | ||
| 163 | ptr = option->port; | 114 | dbg_pnp_show_option(dev, option); |
| 164 | while (ptr && ptr->next) | ||
| 165 | ptr = ptr->next; | ||
| 166 | if (ptr) | ||
| 167 | ptr->next = port; | ||
| 168 | else | ||
| 169 | option->port = port; | ||
| 170 | |||
| 171 | dev_dbg(&dev->dev, " io " | ||
| 172 | "min %#llx max %#llx align %lld size %lld flags %#x\n", | ||
| 173 | (unsigned long long) port->min, | ||
| 174 | (unsigned long long) port->max, | ||
| 175 | (unsigned long long) port->align, | ||
| 176 | (unsigned long long) port->size, port->flags); | ||
| 177 | return 0; | 115 | return 0; |
| 178 | } | 116 | } |
| 179 | 117 | ||
| 180 | int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, | 118 | int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags, |
| 181 | resource_size_t min, resource_size_t max, | 119 | resource_size_t min, resource_size_t max, |
| 182 | resource_size_t align, resource_size_t size, | 120 | resource_size_t align, resource_size_t size, |
| 183 | unsigned char flags) | 121 | unsigned char flags) |
| 184 | { | 122 | { |
| 185 | struct pnp_mem *mem, *ptr; | 123 | struct pnp_option *option; |
| 124 | struct pnp_mem *mem; | ||
| 186 | 125 | ||
| 187 | mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); | 126 | option = pnp_build_option(dev, IORESOURCE_MEM, option_flags); |
| 188 | if (!mem) | 127 | if (!option) |
| 189 | return -ENOMEM; | 128 | return -ENOMEM; |
| 190 | 129 | ||
| 130 | mem = &option->u.mem; | ||
| 191 | mem->min = min; | 131 | mem->min = min; |
| 192 | mem->max = max; | 132 | mem->max = max; |
| 193 | mem->align = align; | 133 | mem->align = align; |
| 194 | mem->size = size; | 134 | mem->size = size; |
| 195 | mem->flags = flags; | 135 | mem->flags = flags; |
| 196 | 136 | ||
| 197 | ptr = option->mem; | 137 | dbg_pnp_show_option(dev, option); |
| 198 | while (ptr && ptr->next) | ||
| 199 | ptr = ptr->next; | ||
| 200 | if (ptr) | ||
| 201 | ptr->next = mem; | ||
| 202 | else | ||
| 203 | option->mem = mem; | ||
| 204 | |||
| 205 | dev_dbg(&dev->dev, " mem " | ||
| 206 | "min %#llx max %#llx align %lld size %lld flags %#x\n", | ||
| 207 | (unsigned long long) mem->min, | ||
| 208 | (unsigned long long) mem->max, | ||
| 209 | (unsigned long long) mem->align, | ||
| 210 | (unsigned long long) mem->size, mem->flags); | ||
| 211 | return 0; | 138 | return 0; |
| 212 | } | 139 | } |
| 213 | 140 | ||
| 214 | static void pnp_free_port(struct pnp_port *port) | 141 | void pnp_free_options(struct pnp_dev *dev) |
| 215 | { | ||
| 216 | struct pnp_port *next; | ||
| 217 | |||
| 218 | while (port) { | ||
| 219 | next = port->next; | ||
| 220 | kfree(port); | ||
| 221 | port = next; | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | static void pnp_free_irq(struct pnp_irq *irq) | ||
| 226 | { | ||
| 227 | struct pnp_irq *next; | ||
| 228 | |||
| 229 | while (irq) { | ||
| 230 | next = irq->next; | ||
| 231 | kfree(irq); | ||
| 232 | irq = next; | ||
| 233 | } | ||
| 234 | } | ||
| 235 | |||
| 236 | static void pnp_free_dma(struct pnp_dma *dma) | ||
| 237 | { | ||
| 238 | struct pnp_dma *next; | ||
| 239 | |||
| 240 | while (dma) { | ||
| 241 | next = dma->next; | ||
| 242 | kfree(dma); | ||
| 243 | dma = next; | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | static void pnp_free_mem(struct pnp_mem *mem) | ||
| 248 | { | 142 | { |
| 249 | struct pnp_mem *next; | 143 | struct pnp_option *option, *tmp; |
| 250 | |||
| 251 | while (mem) { | ||
| 252 | next = mem->next; | ||
| 253 | kfree(mem); | ||
| 254 | mem = next; | ||
| 255 | } | ||
| 256 | } | ||
| 257 | 144 | ||
| 258 | void pnp_free_option(struct pnp_option *option) | 145 | list_for_each_entry_safe(option, tmp, &dev->options, list) { |
| 259 | { | 146 | list_del(&option->list); |
| 260 | struct pnp_option *next; | ||
| 261 | |||
| 262 | while (option) { | ||
| 263 | next = option->next; | ||
| 264 | pnp_free_port(option->port); | ||
| 265 | pnp_free_irq(option->irq); | ||
| 266 | pnp_free_dma(option->dma); | ||
| 267 | pnp_free_mem(option->mem); | ||
| 268 | kfree(option); | 147 | kfree(option); |
| 269 | option = next; | ||
| 270 | } | 148 | } |
| 271 | } | 149 | } |
| 272 | 150 | ||
| @@ -668,66 +546,50 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, | |||
| 668 | return pnp_res; | 546 | return pnp_res; |
| 669 | } | 547 | } |
| 670 | 548 | ||
| 671 | static int pnp_possible_option(struct pnp_option *option, int type, | 549 | /* |
| 672 | resource_size_t start, resource_size_t size) | 550 | * Determine whether the specified resource is a possible configuration |
| 551 | * for this device. | ||
| 552 | */ | ||
| 553 | int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start, | ||
| 554 | resource_size_t size) | ||
| 673 | { | 555 | { |
| 674 | struct pnp_option *tmp; | 556 | struct pnp_option *option; |
| 675 | struct pnp_port *port; | 557 | struct pnp_port *port; |
| 676 | struct pnp_mem *mem; | 558 | struct pnp_mem *mem; |
| 677 | struct pnp_irq *irq; | 559 | struct pnp_irq *irq; |
| 678 | struct pnp_dma *dma; | 560 | struct pnp_dma *dma; |
| 679 | 561 | ||
| 680 | if (!option) | 562 | list_for_each_entry(option, &dev->options, list) { |
| 681 | return 0; | 563 | if (option->type != type) |
| 564 | continue; | ||
| 682 | 565 | ||
| 683 | for (tmp = option; tmp; tmp = tmp->next) { | 566 | switch (option->type) { |
| 684 | switch (type) { | ||
| 685 | case IORESOURCE_IO: | 567 | case IORESOURCE_IO: |
| 686 | for (port = tmp->port; port; port = port->next) { | 568 | port = &option->u.port; |
| 687 | if (port->min == start && port->size == size) | 569 | if (port->min == start && port->size == size) |
| 688 | return 1; | 570 | return 1; |
| 689 | } | ||
| 690 | break; | 571 | break; |
| 691 | case IORESOURCE_MEM: | 572 | case IORESOURCE_MEM: |
| 692 | for (mem = tmp->mem; mem; mem = mem->next) { | 573 | mem = &option->u.mem; |
| 693 | if (mem->min == start && mem->size == size) | 574 | if (mem->min == start && mem->size == size) |
| 694 | return 1; | 575 | return 1; |
| 695 | } | ||
| 696 | break; | 576 | break; |
| 697 | case IORESOURCE_IRQ: | 577 | case IORESOURCE_IRQ: |
| 698 | for (irq = tmp->irq; irq; irq = irq->next) { | 578 | irq = &option->u.irq; |
| 699 | if (start < PNP_IRQ_NR && | 579 | if (start < PNP_IRQ_NR && |
| 700 | test_bit(start, irq->map.bits)) | 580 | test_bit(start, irq->map.bits)) |
| 701 | return 1; | 581 | return 1; |
| 702 | } | ||
| 703 | break; | 582 | break; |
| 704 | case IORESOURCE_DMA: | 583 | case IORESOURCE_DMA: |
| 705 | for (dma = tmp->dma; dma; dma = dma->next) { | 584 | dma = &option->u.dma; |
| 706 | if (dma->map & (1 << start)) | 585 | if (dma->map & (1 << start)) |
| 707 | return 1; | 586 | return 1; |
| 708 | } | ||
| 709 | break; | 587 | break; |
| 710 | } | 588 | } |
| 711 | } | 589 | } |
| 712 | 590 | ||
| 713 | return 0; | 591 | return 0; |
| 714 | } | 592 | } |
| 715 | |||
| 716 | /* | ||
| 717 | * Determine whether the specified resource is a possible configuration | ||
| 718 | * for this device. | ||
| 719 | */ | ||
| 720 | int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start, | ||
| 721 | resource_size_t size) | ||
| 722 | { | ||
| 723 | if (pnp_possible_option(dev->independent, type, start, size)) | ||
| 724 | return 1; | ||
| 725 | |||
| 726 | if (pnp_possible_option(dev->dependent, type, start, size)) | ||
| 727 | return 1; | ||
| 728 | |||
| 729 | return 0; | ||
| 730 | } | ||
| 731 | EXPORT_SYMBOL(pnp_possible_config); | 593 | EXPORT_SYMBOL(pnp_possible_config); |
| 732 | 594 | ||
| 733 | /* format is: pnp_reserve_irq=irq1[,irq2] .... */ | 595 | /* format is: pnp_reserve_irq=irq1[,irq2] .... */ |
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 0ad42db94884..bbf78ef4ba02 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | * support.c - standard functions for the use of pnp protocol drivers | 2 | * support.c - standard functions for the use of pnp protocol drivers |
| 3 | * | 3 | * |
| 4 | * Copyright 2003 Adam Belay <ambx1@neo.rr.com> | 4 | * Copyright 2003 Adam Belay <ambx1@neo.rr.com> |
| 5 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. | ||
| 6 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
| 5 | */ | 7 | */ |
| 6 | 8 | ||
| 7 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| @@ -117,3 +119,93 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) | |||
| 117 | } | 119 | } |
| 118 | #endif | 120 | #endif |
| 119 | } | 121 | } |
| 122 | |||
| 123 | char *pnp_option_priority_name(struct pnp_option *option) | ||
| 124 | { | ||
| 125 | switch (pnp_option_priority(option)) { | ||
| 126 | case PNP_RES_PRIORITY_PREFERRED: | ||
| 127 | return "preferred"; | ||
| 128 | case PNP_RES_PRIORITY_ACCEPTABLE: | ||
| 129 | return "acceptable"; | ||
| 130 | case PNP_RES_PRIORITY_FUNCTIONAL: | ||
| 131 | return "functional"; | ||
| 132 | } | ||
| 133 | return "invalid"; | ||
| 134 | } | ||
| 135 | |||
| 136 | void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option) | ||
| 137 | { | ||
| 138 | #ifdef DEBUG | ||
| 139 | char buf[128]; | ||
| 140 | int len = 0, i; | ||
| 141 | struct pnp_port *port; | ||
| 142 | struct pnp_mem *mem; | ||
| 143 | struct pnp_irq *irq; | ||
| 144 | struct pnp_dma *dma; | ||
| 145 | |||
| 146 | if (pnp_option_is_dependent(option)) | ||
| 147 | len += snprintf(buf + len, sizeof(buf) - len, | ||
| 148 | " dependent set %d (%s) ", | ||
| 149 | pnp_option_set(option), | ||
| 150 | pnp_option_priority_name(option)); | ||
| 151 | else | ||
| 152 | len += snprintf(buf + len, sizeof(buf) - len, " independent "); | ||
| 153 | |||
| 154 | switch (option->type) { | ||
| 155 | case IORESOURCE_IO: | ||
| 156 | port = &option->u.port; | ||
| 157 | len += snprintf(buf + len, sizeof(buf) - len, "io min %#llx " | ||
| 158 | "max %#llx align %lld size %lld flags %#x", | ||
| 159 | (unsigned long long) port->min, | ||
| 160 | (unsigned long long) port->max, | ||
| 161 | (unsigned long long) port->align, | ||
| 162 | (unsigned long long) port->size, port->flags); | ||
| 163 | break; | ||
| 164 | case IORESOURCE_MEM: | ||
| 165 | mem = &option->u.mem; | ||
| 166 | len += snprintf(buf + len, sizeof(buf) - len, "mem min %#llx " | ||
| 167 | "max %#llx align %lld size %lld flags %#x", | ||
| 168 | (unsigned long long) mem->min, | ||
| 169 | (unsigned long long) mem->max, | ||
| 170 | (unsigned long long) mem->align, | ||
| 171 | (unsigned long long) mem->size, mem->flags); | ||
| 172 | break; | ||
| 173 | case IORESOURCE_IRQ: | ||
| 174 | irq = &option->u.irq; | ||
| 175 | len += snprintf(buf + len, sizeof(buf) - len, "irq"); | ||
| 176 | if (bitmap_empty(irq->map.bits, PNP_IRQ_NR)) | ||
| 177 | len += snprintf(buf + len, sizeof(buf) - len, | ||
| 178 | " <none>"); | ||
| 179 | else { | ||
| 180 | for (i = 0; i < PNP_IRQ_NR; i++) | ||
| 181 | if (test_bit(i, irq->map.bits)) | ||
| 182 | len += snprintf(buf + len, | ||
| 183 | sizeof(buf) - len, | ||
| 184 | " %d", i); | ||
| 185 | } | ||
| 186 | len += snprintf(buf + len, sizeof(buf) - len, " flags %#x", | ||
| 187 | irq->flags); | ||
| 188 | if (irq->flags & IORESOURCE_IRQ_OPTIONAL) | ||
| 189 | len += snprintf(buf + len, sizeof(buf) - len, | ||
| 190 | " (optional)"); | ||
| 191 | break; | ||
| 192 | case IORESOURCE_DMA: | ||
| 193 | dma = &option->u.dma; | ||
| 194 | len += snprintf(buf + len, sizeof(buf) - len, "dma"); | ||
| 195 | if (!dma->map) | ||
| 196 | len += snprintf(buf + len, sizeof(buf) - len, | ||
| 197 | " <none>"); | ||
| 198 | else { | ||
| 199 | for (i = 0; i < 8; i++) | ||
| 200 | if (dma->map & (1 << i)) | ||
| 201 | len += snprintf(buf + len, | ||
| 202 | sizeof(buf) - len, | ||
| 203 | " %d", i); | ||
| 204 | } | ||
| 205 | len += snprintf(buf + len, sizeof(buf) - len, " (bitmask %#x) " | ||
| 206 | "flags %#x", dma->map, dma->flags); | ||
| 207 | break; | ||
| 208 | } | ||
| 209 | dev_dbg(&dev->dev, "%s\n", buf); | ||
| 210 | #endif | ||
| 211 | } | ||
diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 785126ffcc11..1ce54b63085d 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Linux Plug and Play Support | 2 | * Linux Plug and Play Support |
| 3 | * Copyright by Adam Belay <ambx1@neo.rr.com> | 3 | * Copyright by Adam Belay <ambx1@neo.rr.com> |
| 4 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. | ||
| 5 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
| 4 | */ | 6 | */ |
| 5 | 7 | ||
| 6 | #ifndef _LINUX_PNP_H | 8 | #ifndef _LINUX_PNP_H |
| @@ -249,9 +251,9 @@ struct pnp_dev { | |||
| 249 | 251 | ||
| 250 | int active; | 252 | int active; |
| 251 | int capabilities; | 253 | int capabilities; |
| 252 | struct pnp_option *independent; | 254 | unsigned int num_dependent_sets; |
| 253 | struct pnp_option *dependent; | ||
| 254 | struct list_head resources; | 255 | struct list_head resources; |
| 256 | struct list_head options; | ||
| 255 | 257 | ||
| 256 | char name[PNP_NAME_LEN]; /* contains a human-readable name */ | 258 | char name[PNP_NAME_LEN]; /* contains a human-readable name */ |
| 257 | int flags; /* used by protocols */ | 259 | int flags; /* used by protocols */ |
