1 /* 2 * resource.c - Contains functions for registering and analyzing resource information 3 * 4 * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> 5 * Copyright 2003 Adam Belay <ambx1@neo.rr.com> 6 */ 7 8 #include <linux/module.h> 9 #include <linux/errno.h> 10 #include <linux/interrupt.h> 11 #include <linux/kernel.h> 12 #include <asm/io.h> 13 #include <asm/dma.h> 14 #include <asm/irq.h> 15 #include <linux/pci.h> 16 #include <linux/ioport.h> 17 #include <linux/init.h> 18 19 #include <linux/pnp.h> 20 #include "base.h" 21 22 static int pnp_reserve_irq[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some IRQ */ 23 static int pnp_reserve_dma[8] = {[0 ... 7] = -1 }; /* reserve (don't use) some DMA */ 24 static int pnp_reserve_io[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some I/O region */ 25 static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some memory region */ 26 27 /* 28 * option registration 29 */ 30 31 static struct pnp_option *pnp_build_option(int priority) 32 { 33 struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option)); 34 35 if (!option) 36 return NULL; 37 38 option->priority = priority & 0xff; 39 /* make sure the priority is valid */ 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 return option; 57 } 58 59 struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, 60 int priority) 61 { 62 struct pnp_option *option; 63 64 option = pnp_build_option(priority); 65 66 if (dev->dependent) { 67 struct pnp_option *parent = dev->dependent; 68 while (parent->next) 69 parent = parent->next; 70 parent->next = option; 71 } else 72 dev->dependent = option; 73 return option; 74 } 75 76 int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) 77 { 78 struct pnp_irq *ptr; 79 80 ptr = option->irq; 81 while (ptr && ptr->next) 82 ptr = ptr->next; 83 if (ptr) 84 ptr->next = data; 85 else 86 option->irq = data; 87 88 #ifdef CONFIG_PCI 89 { 90 int i; 91 92 for (i = 0; i < 16; i++) 93 if (test_bit(i, data->map)) 94 pcibios_penalize_isa_irq(i, 0); 95 } 96 #endif 97 return 0; 98 } 99 100 int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) 101 { 102 struct pnp_dma *ptr; 103 104 ptr = option->dma; 105 while (ptr && ptr->next) 106 ptr = ptr->next; 107 if (ptr) 108 ptr->next = data; 109 else 110 option->dma = data; 111 112 return 0; 113 } 114 115 int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) 116 { 117 struct pnp_port *ptr; 118 119 ptr = option->port; 120 while (ptr && ptr->next) 121 ptr = ptr->next; 122 if (ptr) 123 ptr->next = data; 124 else 125 option->port = data; 126 127 return 0; 128 } 129 130 int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) 131 { 132 struct pnp_mem *ptr; 133 134 ptr = option->mem; 135 while (ptr && ptr->next) 136 ptr = ptr->next; 137 if (ptr) 138 ptr->next = data; 139 else 140 option->mem = data; 141 return 0; 142 } 143 144 static void pnp_free_port(struct pnp_port *port) 145 { 146 struct pnp_port *next; 147 148 while (port) { 149 next = port->next; 150 kfree(port); 151 port = next; 152 } 153 } 154 155 static void pnp_free_irq(struct pnp_irq *irq) 156 { 157 struct pnp_irq *next; 158 159 while (irq) { 160 next = irq->next; 161 kfree(irq); 162 irq = next; 163 } 164 } 165 166 static void pnp_free_dma(struct pnp_dma *dma) 167 { 168 struct pnp_dma *next; 169 170 while (dma) { 171 next = dma->next; 172 kfree(dma); 173 dma = next; 174 } 175 } 176 177 static void pnp_free_mem(struct pnp_mem *mem) 178 { 179 struct pnp_mem *next; 180 181 while (mem) { 182 next = mem->next; 183 kfree(mem); 184 mem = next; 185 } 186 } 187 188 void pnp_free_option(struct pnp_option *option) 189 { 190 struct pnp_option *next; 191 192 while (option) { 193 next = option->next; 194 pnp_free_port(option->port); 195 pnp_free_irq(option->irq); 196 pnp_free_dma(option->dma); 197 pnp_free_mem(option->mem); 198 kfree(option); 199 option = next; 200 } 201 } 202 203 /* 204 * resource validity checking 205 */ 206 207 #define length(start, end) (*(end) - *(start) + 1) 208 209 /* Two ranges conflict if one doesn't end before the other starts */ 210 #define ranged_conflict(starta, enda, startb, endb) \ 211 !((*(enda) < *(startb)) || (*(endb) < *(starta))) 212 213 #define cannot_compare(flags) \ 214 ((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) 215 216 int pnp_check_port(struct pnp_dev *dev, int idx) 217 { 218 int tmp; 219 struct pnp_dev *tdev; 220 resource_size_t *port, *end, *tport, *tend; 221 222 port = &dev->res.port_resource[idx].start; 223 end = &dev->res.port_resource[idx].end; 224 225 /* if the resource doesn't exist, don't complain about it */ 226 if (cannot_compare(dev->res.port_resource[idx].flags)) 227 return 1; 228 229 /* check if the resource is already in use, skip if the 230 * device is active because it itself may be in use */ 231 if (!dev->active) { 232 if (__check_region(&ioport_resource, *port, length(port, end))) 233 return 0; 234 } 235 236 /* check if the resource is reserved */ 237 for (tmp = 0; tmp < 8; tmp++) { 238 int rport = pnp_reserve_io[tmp << 1]; 239 int rend = pnp_reserve_io[(tmp << 1) + 1] + rport - 1; 240 if (ranged_conflict(port, end, &rport, &rend)) 241 return 0; 242 } 243 244 /* check for internal conflicts */ 245 for (tmp = 0; tmp < PNP_MAX_PORT && tmp != idx; tmp++) { 246 if (dev->res.port_resource[tmp].flags & IORESOURCE_IO) { 247 tport = &dev->res.port_resource[tmp].start; 248 tend = &dev->res.port_resource[tmp].end; 249 if (ranged_conflict(port, end, tport, tend)) 250 return 0; 251 } 252 } 253 254 /* check for conflicts with other pnp devices */ 255 pnp_for_each_dev(tdev) { 256 if (tdev == dev) 257 continue; 258 for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) { 259 if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) { 260 if (cannot_compare 261 (tdev->res.port_resource[tmp].flags)) 262 continue; 263 tport = &tdev->res.port_resource[tmp].start; 264 tend = &tdev->res.port_resource[tmp].end; 265 if (ranged_conflict(port, end, tport, tend)) 266 return 0; 267 } 268 } 269 } 270 271 return 1; 272 } 273 274 int pnp_check_mem(struct pnp_dev *dev, int idx) 275 { 276 int tmp; 277 struct pnp_dev *tdev; 278 resource_size_t *addr, *end, *taddr, *tend; 279 280 addr = &dev->res.mem_resource[idx].start; 281 end = &dev->res.mem_resource[idx].end; 282 283 /* if the resource doesn't exist, don't complain about it */ 284 if (cannot_compare(dev->res.mem_resource[idx].flags)) 285 return 1; 286 287 /* check if the resource is already in use, skip if the 288 * device is active because it itself may be in use */ 289 if (!dev->active) { 290 if (check_mem_region(*addr, length(addr, end))) 291 return 0; 292 } 293 294 /* check if the resource is reserved */ 295 for (tmp = 0; tmp < 8; tmp++) { 296 int raddr = pnp_reserve_mem[tmp << 1]; 297 int rend = pnp_reserve_mem[(tmp << 1) + 1] + raddr - 1; 298 if (ranged_conflict(addr, end, &raddr, &rend)) 299 return 0; 300 } 301 302 /* check for internal conflicts */ 303 for (tmp = 0; tmp < PNP_MAX_MEM && tmp != idx; tmp++) { 304 if (dev->res.mem_resource[tmp].flags & IORESOURCE_MEM) { 305 taddr = &dev->res.mem_resource[tmp].start; 306 tend = &dev->res.mem_resource[tmp].end; 307 if (ranged_conflict(addr, end, taddr, tend)) 308 return 0; 309 } 310 } 311 312 /* check for conflicts with other pnp devices */ 313 pnp_for_each_dev(tdev) { 314 if (tdev == dev) 315 continue; 316 for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) { 317 if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) { 318 if (cannot_compare 319 (tdev->res.mem_resource[tmp].flags)) 320 continue; 321 taddr = &tdev->res.mem_resource[tmp].start; 322 tend = &tdev->res.mem_resource[tmp].end; 323 if (ranged_conflict(addr, end, taddr, tend)) 324 return 0; 325 } 326 } 327 } 328 329 return 1; 330 } 331 332 static irqreturn_t pnp_test_handler(int irq, void *dev_id) 333 { 334 return IRQ_HANDLED; 335 } 336 337 int pnp_check_irq(struct pnp_dev *dev, int idx) 338 { 339 int tmp; 340 struct pnp_dev *tdev; 341 resource_size_t *irq = &dev->res.irq_resource[idx].start; 342 343 /* if the resource doesn't exist, don't complain about it */ 344 if (cannot_compare(dev->res.irq_resource[idx].flags)) 345 return 1; 346 347 /* check if the resource is valid */ 348 if (*irq < 0 || *irq > 15) 349 return 0; 350 351 /* check if the resource is reserved */ 352 for (tmp = 0; tmp < 16; tmp++) { 353 if (pnp_reserve_irq[tmp] == *irq) 354 return 0; 355 } 356 357 /* check for internal conflicts */ 358 for (tmp = 0; tmp < PNP_MAX_IRQ && tmp != idx; tmp++) { 359 if (dev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) { 360 if (dev->res.irq_resource[tmp].start == *irq) 361 return 0; 362 } 363 } 364 365 #ifdef CONFIG_PCI 366 /* check if the resource is being used by a pci device */ 367 { 368 struct pci_dev *pci = NULL; 369 for_each_pci_dev(pci) { 370 if (pci->irq == *irq) { 371 pci_dev_put(pci); 372 return 0; 373 } 374 } 375 } 376 #endif 377 378 /* check if the resource is already in use, skip if the 379 * device is active because it itself may be in use */ 380 if (!dev->active) { 381 if (request_irq(*irq, pnp_test_handler, 382 IRQF_DISABLED | IRQF_PROBE_SHARED, "pnp", NULL)) 383 return 0; 384 free_irq(*irq, NULL); 385 } 386 387 /* check for conflicts with other pnp devices */ 388 pnp_for_each_dev(tdev) { 389 if (tdev == dev) 390 continue; 391 for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) { 392 if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) { 393 if (cannot_compare 394 (tdev->res.irq_resource[tmp].flags)) 395 continue; 396 if ((tdev->res.irq_resource[tmp].start == *irq)) 397 return 0; 398 } 399 } 400 } 401 402 return 1; 403 } 404 405 int pnp_check_dma(struct pnp_dev *dev, int idx) 406 { 407 #ifndef CONFIG_IA64 408 int tmp; 409 struct pnp_dev *tdev; 410 resource_size_t *dma = &dev->res.dma_resource[idx].start; 411 412 /* if the resource doesn't exist, don't complain about it */ 413 if (cannot_compare(dev->res.dma_resource[idx].flags)) 414 return 1; 415 416 /* check if the resource is valid */ 417 if (*dma < 0 || *dma == 4 || *dma > 7) 418 return 0; 419 420 /* check if the resource is reserved */ 421 for (tmp = 0; tmp < 8; tmp++) { 422 if (pnp_reserve_dma[tmp] == *dma) 423 return 0; 424 } 425 426 /* check for internal conflicts */ 427 for (tmp = 0; tmp < PNP_MAX_DMA && tmp != idx; tmp++) { 428 if (dev->res.dma_resource[tmp].flags & IORESOURCE_DMA) { 429 if (dev->res.dma_resource[tmp].start == *dma) 430 return 0; 431 } 432 } 433 434 /* check if the resource is already in use, skip if the 435 * device is active because it itself may be in use */ 436 if (!dev->active) { 437 if (request_dma(*dma, "pnp")) 438 return 0; 439 free_dma(*dma); 440 } 441 442 /* check for conflicts with other pnp devices */ 443 pnp_for_each_dev(tdev) { 444 if (tdev == dev) 445 continue; 446 for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) { 447 if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) { 448 if (cannot_compare 449 (tdev->res.dma_resource[tmp].flags)) 450 continue; 451 if ((tdev->res.dma_resource[tmp].start == *dma)) 452 return 0; 453 } 454 } 455 } 456 457 return 1; 458 #else 459 /* IA64 does not have legacy DMA */ 460 return 0; 461 #endif 462 } 463 464 /* format is: pnp_reserve_irq=irq1[,irq2] .... */ 465 static int __init pnp_setup_reserve_irq(char *str) 466 { 467 int i; 468 469 for (i = 0; i < 16; i++) 470 if (get_option(&str, &pnp_reserve_irq[i]) != 2) 471 break; 472 return 1; 473 } 474 475 __setup("pnp_reserve_irq=", pnp_setup_reserve_irq); 476 477 /* format is: pnp_reserve_dma=dma1[,dma2] .... */ 478 static int __init pnp_setup_reserve_dma(char *str) 479 { 480 int i; 481 482 for (i = 0; i < 8; i++) 483 if (get_option(&str, &pnp_reserve_dma[i]) != 2) 484 break; 485 return 1; 486 } 487 488 __setup("pnp_reserve_dma=", pnp_setup_reserve_dma); 489 490 /* format is: pnp_reserve_io=io1,size1[,io2,size2] .... */ 491 static int __init pnp_setup_reserve_io(char *str) 492 { 493 int i; 494 495 for (i = 0; i < 16; i++) 496 if (get_option(&str, &pnp_reserve_io[i]) != 2) 497 break; 498 return 1; 499 } 500 501 __setup("pnp_reserve_io=", pnp_setup_reserve_io); 502 503 /* format is: pnp_reserve_mem=mem1,size1[,mem2,size2] .... */ 504 static int __init pnp_setup_reserve_mem(char *str) 505 { 506 int i; 507 508 for (i = 0; i < 16; i++) 509 if (get_option(&str, &pnp_reserve_mem[i]) != 2) 510 break; 511 return 1; 512 } 513 514 __setup("pnp_reserve_mem=", pnp_setup_reserve_mem); 515