diff options
Diffstat (limited to 'drivers/pnp/support.c')
| -rw-r--r-- | drivers/pnp/support.c | 171 |
1 files changed, 146 insertions, 25 deletions
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 95b076c18c07..bbf78ef4ba02 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | * support.c - standard functions for the use of pnp protocol drivers | 2 | * support.c - standard functions for the use of pnp protocol drivers |
| 3 | * | 3 | * |
| 4 | * Copyright 2003 Adam Belay <ambx1@neo.rr.com> | 4 | * Copyright 2003 Adam Belay <ambx1@neo.rr.com> |
| 5 | * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. | ||
| 6 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
| 5 | */ | 7 | */ |
| 6 | 8 | ||
| 7 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| @@ -16,6 +18,10 @@ | |||
| 16 | */ | 18 | */ |
| 17 | int pnp_is_active(struct pnp_dev *dev) | 19 | int pnp_is_active(struct pnp_dev *dev) |
| 18 | { | 20 | { |
| 21 | /* | ||
| 22 | * I don't think this is very reliable because pnp_disable_dev() | ||
| 23 | * only clears out auto-assigned resources. | ||
| 24 | */ | ||
| 19 | if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 && | 25 | if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 && |
| 20 | !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 && | 26 | !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 && |
| 21 | pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1) | 27 | pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1) |
| @@ -52,39 +58,154 @@ void pnp_eisa_id_to_string(u32 id, char *str) | |||
| 52 | str[7] = '\0'; | 58 | str[7] = '\0'; |
| 53 | } | 59 | } |
| 54 | 60 | ||
| 61 | char *pnp_resource_type_name(struct resource *res) | ||
| 62 | { | ||
| 63 | switch (pnp_resource_type(res)) { | ||
| 64 | case IORESOURCE_IO: | ||
| 65 | return "io"; | ||
| 66 | case IORESOURCE_MEM: | ||
| 67 | return "mem"; | ||
| 68 | case IORESOURCE_IRQ: | ||
| 69 | return "irq"; | ||
| 70 | case IORESOURCE_DMA: | ||
| 71 | return "dma"; | ||
| 72 | } | ||
| 73 | return NULL; | ||
| 74 | } | ||
| 75 | |||
| 55 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) | 76 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) |
| 56 | { | 77 | { |
| 57 | #ifdef DEBUG | 78 | #ifdef DEBUG |
| 79 | char buf[128]; | ||
| 80 | int len = 0; | ||
| 81 | struct pnp_resource *pnp_res; | ||
| 58 | struct resource *res; | 82 | struct resource *res; |
| 59 | int i; | ||
| 60 | 83 | ||
| 61 | dev_dbg(&dev->dev, "current resources: %s\n", desc); | 84 | if (list_empty(&dev->resources)) { |
| 62 | 85 | dev_dbg(&dev->dev, "%s: no current resources\n", desc); | |
| 63 | for (i = 0; i < PNP_MAX_IRQ; i++) { | 86 | return; |
| 64 | res = pnp_get_resource(dev, IORESOURCE_IRQ, i); | ||
| 65 | if (res && !(res->flags & IORESOURCE_UNSET)) | ||
| 66 | dev_dbg(&dev->dev, " irq %lld flags %#lx\n", | ||
| 67 | (unsigned long long) res->start, res->flags); | ||
| 68 | } | 87 | } |
| 69 | for (i = 0; i < PNP_MAX_DMA; i++) { | 88 | |
| 70 | res = pnp_get_resource(dev, IORESOURCE_DMA, i); | 89 | dev_dbg(&dev->dev, "%s: current resources:\n", desc); |
| 71 | if (res && !(res->flags & IORESOURCE_UNSET)) | 90 | list_for_each_entry(pnp_res, &dev->resources, list) { |
| 72 | dev_dbg(&dev->dev, " dma %lld flags %#lx\n", | 91 | res = &pnp_res->res; |
| 73 | (unsigned long long) res->start, res->flags); | 92 | |
| 93 | len += snprintf(buf + len, sizeof(buf) - len, " %-3s ", | ||
| 94 | pnp_resource_type_name(res)); | ||
| 95 | |||
| 96 | if (res->flags & IORESOURCE_DISABLED) { | ||
| 97 | dev_dbg(&dev->dev, "%sdisabled\n", buf); | ||
| 98 | continue; | ||
| 99 | } | ||
| 100 | |||
| 101 | switch (pnp_resource_type(res)) { | ||
| 102 | case IORESOURCE_IO: | ||
| 103 | case IORESOURCE_MEM: | ||
| 104 | len += snprintf(buf + len, sizeof(buf) - len, | ||
| 105 | "%#llx-%#llx flags %#lx", | ||
| 106 | (unsigned long long) res->start, | ||
| 107 | (unsigned long long) res->end, | ||
| 108 | res->flags); | ||
| 109 | break; | ||
| 110 | case IORESOURCE_IRQ: | ||
| 111 | case IORESOURCE_DMA: | ||
| 112 | len += snprintf(buf + len, sizeof(buf) - len, | ||
| 113 | "%lld flags %#lx", | ||
| 114 | (unsigned long long) res->start, | ||
| 115 | res->flags); | ||
| 116 | break; | ||
| 117 | } | ||
| 118 | dev_dbg(&dev->dev, "%s\n", buf); | ||
| 74 | } | 119 | } |
| 75 | for (i = 0; i < PNP_MAX_PORT; i++) { | 120 | #endif |
| 76 | res = pnp_get_resource(dev, IORESOURCE_IO, i); | 121 | } |
| 77 | if (res && !(res->flags & IORESOURCE_UNSET)) | 122 | |
| 78 | dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n", | 123 | char *pnp_option_priority_name(struct pnp_option *option) |
| 79 | (unsigned long long) res->start, | 124 | { |
| 80 | (unsigned long long) res->end, res->flags); | 125 | switch (pnp_option_priority(option)) { |
| 126 | case PNP_RES_PRIORITY_PREFERRED: | ||
| 127 | return "preferred"; | ||
| 128 | case PNP_RES_PRIORITY_ACCEPTABLE: | ||
| 129 | return "acceptable"; | ||
| 130 | case PNP_RES_PRIORITY_FUNCTIONAL: | ||
| 131 | return "functional"; | ||
| 81 | } | 132 | } |
| 82 | for (i = 0; i < PNP_MAX_MEM; i++) { | 133 | return "invalid"; |
| 83 | res = pnp_get_resource(dev, IORESOURCE_MEM, i); | 134 | } |
| 84 | if (res && !(res->flags & IORESOURCE_UNSET)) | 135 | |
| 85 | dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n", | 136 | void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option) |
| 86 | (unsigned long long) res->start, | 137 | { |
| 87 | (unsigned long long) res->end, res->flags); | 138 | #ifdef DEBUG |
| 139 | char buf[128]; | ||
| 140 | int len = 0, i; | ||
| 141 | struct pnp_port *port; | ||
| 142 | struct pnp_mem *mem; | ||
| 143 | struct pnp_irq *irq; | ||
| 144 | struct pnp_dma *dma; | ||
| 145 | |||
| 146 | if (pnp_option_is_dependent(option)) | ||
| 147 | len += snprintf(buf + len, sizeof(buf) - len, | ||
| 148 | " dependent set %d (%s) ", | ||
| 149 | pnp_option_set(option), | ||
| 150 | pnp_option_priority_name(option)); | ||
| 151 | else | ||
| 152 | len += snprintf(buf + len, sizeof(buf) - len, " independent "); | ||
| 153 | |||
| 154 | switch (option->type) { | ||
| 155 | case IORESOURCE_IO: | ||
| 156 | port = &option->u.port; | ||
| 157 | len += snprintf(buf + len, sizeof(buf) - len, "io min %#llx " | ||
| 158 | "max %#llx align %lld size %lld flags %#x", | ||
| 159 | (unsigned long long) port->min, | ||
| 160 | (unsigned long long) port->max, | ||
| 161 | (unsigned long long) port->align, | ||
| 162 | (unsigned long long) port->size, port->flags); | ||
| 163 | break; | ||
| 164 | case IORESOURCE_MEM: | ||
| 165 | mem = &option->u.mem; | ||
| 166 | len += snprintf(buf + len, sizeof(buf) - len, "mem min %#llx " | ||
| 167 | "max %#llx align %lld size %lld flags %#x", | ||
| 168 | (unsigned long long) mem->min, | ||
| 169 | (unsigned long long) mem->max, | ||
| 170 | (unsigned long long) mem->align, | ||
| 171 | (unsigned long long) mem->size, mem->flags); | ||
| 172 | break; | ||
| 173 | case IORESOURCE_IRQ: | ||
| 174 | irq = &option->u.irq; | ||
| 175 | len += snprintf(buf + len, sizeof(buf) - len, "irq"); | ||
| 176 | if (bitmap_empty(irq->map.bits, PNP_IRQ_NR)) | ||
| 177 | len += snprintf(buf + len, sizeof(buf) - len, | ||
| 178 | " <none>"); | ||
| 179 | else { | ||
| 180 | for (i = 0; i < PNP_IRQ_NR; i++) | ||
| 181 | if (test_bit(i, irq->map.bits)) | ||
| 182 | len += snprintf(buf + len, | ||
| 183 | sizeof(buf) - len, | ||
| 184 | " %d", i); | ||
| 185 | } | ||
| 186 | len += snprintf(buf + len, sizeof(buf) - len, " flags %#x", | ||
| 187 | irq->flags); | ||
| 188 | if (irq->flags & IORESOURCE_IRQ_OPTIONAL) | ||
| 189 | len += snprintf(buf + len, sizeof(buf) - len, | ||
| 190 | " (optional)"); | ||
| 191 | break; | ||
| 192 | case IORESOURCE_DMA: | ||
| 193 | dma = &option->u.dma; | ||
| 194 | len += snprintf(buf + len, sizeof(buf) - len, "dma"); | ||
| 195 | if (!dma->map) | ||
| 196 | len += snprintf(buf + len, sizeof(buf) - len, | ||
| 197 | " <none>"); | ||
| 198 | else { | ||
| 199 | for (i = 0; i < 8; i++) | ||
| 200 | if (dma->map & (1 << i)) | ||
| 201 | len += snprintf(buf + len, | ||
| 202 | sizeof(buf) - len, | ||
| 203 | " %d", i); | ||
| 204 | } | ||
| 205 | len += snprintf(buf + len, sizeof(buf) - len, " (bitmask %#x) " | ||
| 206 | "flags %#x", dma->map, dma->flags); | ||
| 207 | break; | ||
| 88 | } | 208 | } |
| 209 | dev_dbg(&dev->dev, "%s\n", buf); | ||
| 89 | #endif | 210 | #endif |
| 90 | } | 211 | } |
