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