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