1 /* 2 * manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices 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/errno.h> 10 #include <linux/module.h> 11 #include <linux/init.h> 12 #include <linux/kernel.h> 13 #include <linux/pnp.h> 14 #include <linux/slab.h> 15 #include <linux/bitmap.h> 16 #include "base.h" 17 18 DECLARE_MUTEX(pnp_res_mutex); 19 20 static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) 21 { 22 resource_size_t *start, *end; 23 unsigned long *flags; 24 25 if (!dev || !rule) 26 return -EINVAL; 27 28 if (idx >= PNP_MAX_PORT) { 29 pnp_err("More than 4 ports is incompatible with pnp specifications."); 30 /* pretend we were successful so at least the manager won't try again */ 31 return 1; 32 } 33 34 /* check if this resource has been manually set, if so skip */ 35 if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO)) 36 return 1; 37 38 start = &dev->res.port_resource[idx].start; 39 end = &dev->res.port_resource[idx].end; 40 flags = &dev->res.port_resource[idx].flags; 41 42 /* set the initial values */ 43 *flags |= rule->flags | IORESOURCE_IO; 44 *flags &= ~IORESOURCE_UNSET; 45 46 if (!rule->size) { 47 *flags |= IORESOURCE_DISABLED; 48 return 1; /* skip disabled resource requests */ 49 } 50 51 *start = rule->min; 52 *end = *start + rule->size - 1; 53 54 /* run through until pnp_check_port is happy */ 55 while (!pnp_check_port(dev, idx)) { 56 *start += rule->align; 57 *end = *start + rule->size - 1; 58 if (*start > rule->max || !rule->align) 59 return 0; 60 } 61 return 1; 62 } 63 64 static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) 65 { 66 resource_size_t *start, *end; 67 unsigned long *flags; 68 69 if (!dev || !rule) 70 return -EINVAL; 71 72 if (idx >= PNP_MAX_MEM) { 73 pnp_err("More than 8 mems is incompatible with pnp specifications."); 74 /* pretend we were successful so at least the manager won't try again */ 75 return 1; 76 } 77 78 /* check if this resource has been manually set, if so skip */ 79 if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO)) 80 return 1; 81 82 start = &dev->res.mem_resource[idx].start; 83 end = &dev->res.mem_resource[idx].end; 84 flags = &dev->res.mem_resource[idx].flags; 85 86 /* set the initial values */ 87 *flags |= rule->flags | IORESOURCE_MEM; 88 *flags &= ~IORESOURCE_UNSET; 89 90 /* convert pnp flags to standard Linux flags */ 91 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) 92 *flags |= IORESOURCE_READONLY; 93 if (rule->flags & IORESOURCE_MEM_CACHEABLE) 94 *flags |= IORESOURCE_CACHEABLE; 95 if (rule->flags & IORESOURCE_MEM_RANGELENGTH) 96 *flags |= IORESOURCE_RANGELENGTH; 97 if (rule->flags & IORESOURCE_MEM_SHADOWABLE) 98 *flags |= IORESOURCE_SHADOWABLE; 99 100 if (!rule->size) { 101 *flags |= IORESOURCE_DISABLED; 102 return 1; /* skip disabled resource requests */ 103 } 104 105 *start = rule->min; 106 *end = *start + rule->size -1; 107 108 /* run through until pnp_check_mem is happy */ 109 while (!pnp_check_mem(dev, idx)) { 110 *start += rule->align; 111 *end = *start + rule->size - 1; 112 if (*start > rule->max || !rule->align) 113 return 0; 114 } 115 return 1; 116 } 117 118 static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx) 119 { 120 resource_size_t *start, *end; 121 unsigned long *flags; 122 int i; 123 124 /* IRQ priority: this table is good for i386 */ 125 static unsigned short xtab[16] = { 126 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 127 }; 128 129 if (!dev || !rule) 130 return -EINVAL; 131 132 if (idx >= PNP_MAX_IRQ) { 133 pnp_err("More than 2 irqs is incompatible with pnp specifications."); 134 /* pretend we were successful so at least the manager won't try again */ 135 return 1; 136 } 137 138 /* check if this resource has been manually set, if so skip */ 139 if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO)) 140 return 1; 141 142 start = &dev->res.irq_resource[idx].start; 143 end = &dev->res.irq_resource[idx].end; 144 flags = &dev->res.irq_resource[idx].flags; 145 146 /* set the initial values */ 147 *flags |= rule->flags | IORESOURCE_IRQ; 148 *flags &= ~IORESOURCE_UNSET; 149 150 if (bitmap_empty(rule->map, PNP_IRQ_NR)) { 151 *flags |= IORESOURCE_DISABLED; 152 return 1; /* skip disabled resource requests */ 153 } 154 155 /* TBD: need check for >16 IRQ */ 156 *start = find_next_bit(rule->map, PNP_IRQ_NR, 16); 157 if (*start < PNP_IRQ_NR) { 158 *end = *start; 159 return 1; 160 } 161 for (i = 0; i < 16; i++) { 162 if(test_bit(xtab[i], rule->map)) { 163 *start = *end = xtab[i]; 164 if(pnp_check_irq(dev, idx)) 165 return 1; 166 } 167 } 168 return 0; 169 } 170 171 static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) 172 { 173 resource_size_t *start, *end; 174 unsigned long *flags; 175 int i; 176 177 /* DMA priority: this table is good for i386 */ 178 static unsigned short xtab[8] = { 179 1, 3, 5, 6, 7, 0, 2, 4 180 }; 181 182 if (!dev || !rule) 183 return -EINVAL; 184 185 if (idx >= PNP_MAX_DMA) { 186 pnp_err("More than 2 dmas is incompatible with pnp specifications."); 187 /* pretend we were successful so at least the manager won't try again */ 188 return 1; 189 } 190 191 /* check if this resource has been manually set, if so skip */ 192 if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) 193 return 1; 194 195 start = &dev->res.dma_resource[idx].start; 196 end = &dev->res.dma_resource[idx].end; 197 flags = &dev->res.dma_resource[idx].flags; 198 199 /* set the initial values */ 200 *flags |= rule->flags | IORESOURCE_DMA; 201 *flags &= ~IORESOURCE_UNSET; 202 203 if (!rule->map) { 204 *flags |= IORESOURCE_DISABLED; 205 return 1; /* skip disabled resource requests */ 206 } 207 208 for (i = 0; i < 8; i++) { 209 if(rule->map & (1<<xtab[i])) { 210 *start = *end = xtab[i]; 211 if(pnp_check_dma(dev, idx)) 212 return 1; 213 } 214 } 215 return 0; 216 } 217 218 /** 219 * pnp_init_resources - Resets a resource table to default values. 220 * @table: pointer to the desired resource table 221 * 222 */ 223 void pnp_init_resource_table(struct pnp_resource_table *table) 224 { 225 int idx; 226 for (idx = 0; idx < PNP_MAX_IRQ; idx++) { 227 table->irq_resource[idx].name = NULL; 228 table->irq_resource[idx].start = -1; 229 table->irq_resource[idx].end = -1; 230 table->irq_resource[idx].flags = IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET; 231 } 232 for (idx = 0; idx < PNP_MAX_DMA; idx++) { 233 table->dma_resource[idx].name = NULL; 234 table->dma_resource[idx].start = -1; 235 table->dma_resource[idx].end = -1; 236 table->dma_resource[idx].flags = IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET; 237 } 238 for (idx = 0; idx < PNP_MAX_PORT; idx++) { 239 table->port_resource[idx].name = NULL; 240 table->port_resource[idx].start = 0; 241 table->port_resource[idx].end = 0; 242 table->port_resource[idx].flags = IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET; 243 } 244 for (idx = 0; idx < PNP_MAX_MEM; idx++) { 245 table->mem_resource[idx].name = NULL; 246 table->mem_resource[idx].start = 0; 247 table->mem_resource[idx].end = 0; 248 table->mem_resource[idx].flags = IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET; 249 } 250 } 251 252 /** 253 * pnp_clean_resources - clears resources that were not manually set 254 * @res: the resources to clean 255 * 256 */ 257 static void pnp_clean_resource_table(struct pnp_resource_table * res) 258 { 259 int idx; 260 for (idx = 0; idx < PNP_MAX_IRQ; idx++) { 261 if (!(res->irq_resource[idx].flags & IORESOURCE_AUTO)) 262 continue; 263 res->irq_resource[idx].start = -1; 264 res->irq_resource[idx].end = -1; 265 res->irq_resource[idx].flags = IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET; 266 } 267 for (idx = 0; idx < PNP_MAX_DMA; idx++) { 268 if (!(res->dma_resource[idx].flags & IORESOURCE_AUTO)) 269 continue; 270 res->dma_resource[idx].start = -1; 271 res->dma_resource[idx].end = -1; 272 res->dma_resource[idx].flags = IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET; 273 } 274 for (idx = 0; idx < PNP_MAX_PORT; idx++) { 275 if (!(res->port_resource[idx].flags & IORESOURCE_AUTO)) 276 continue; 277 res->port_resource[idx].start = 0; 278 res->port_resource[idx].end = 0; 279 res->port_resource[idx].flags = IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET; 280 } 281 for (idx = 0; idx < PNP_MAX_MEM; idx++) { 282 if (!(res->mem_resource[idx].flags & IORESOURCE_AUTO)) 283 continue; 284 res->mem_resource[idx].start = 0; 285 res->mem_resource[idx].end = 0; 286 res->mem_resource[idx].flags = IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET; 287 } 288 } 289 290 /** 291 * pnp_assign_resources - assigns resources to the device based on the specified dependent number 292 * @dev: pointer to the desired device 293 * @depnum: the dependent function number 294 * 295 * Only set depnum to 0 if the device does not have dependent options. 296 */ 297 static int pnp_assign_resources(struct pnp_dev *dev, int depnum) 298 { 299 struct pnp_port *port; 300 struct pnp_mem *mem; 301 struct pnp_irq *irq; 302 struct pnp_dma *dma; 303 int nport = 0, nmem = 0, nirq = 0, ndma = 0; 304 305 if (!pnp_can_configure(dev)) 306 return -ENODEV; 307 308 down(&pnp_res_mutex); 309 pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ 310 if (dev->independent) { 311 port = dev->independent->port; 312 mem = dev->independent->mem; 313 irq = dev->independent->irq; 314 dma = dev->independent->dma; 315 while (port) { 316 if (!pnp_assign_port(dev, port, nport)) 317 goto fail; 318 nport++; 319 port = port->next; 320 } 321 while (mem) { 322 if (!pnp_assign_mem(dev, mem, nmem)) 323 goto fail; 324 nmem++; 325 mem = mem->next; 326 } 327 while (irq) { 328 if (!pnp_assign_irq(dev, irq, nirq)) 329 goto fail; 330 nirq++; 331 irq = irq->next; 332 } 333 while (dma) { 334 if (!pnp_assign_dma(dev, dma, ndma)) 335 goto fail; 336 ndma++; 337 dma = dma->next; 338 } 339 } 340 341 if (depnum) { 342 struct pnp_option *dep; 343 int i; 344 for (i=1,dep=dev->dependent; i<depnum; i++, dep=dep->next) 345 if(!dep) 346 goto fail; 347 port =dep->port; 348 mem = dep->mem; 349 irq = dep->irq; 350 dma = dep->dma; 351 while (port) { 352 if (!pnp_assign_port(dev, port, nport)) 353 goto fail; 354 nport++; 355 port = port->next; 356 } 357 while (mem) { 358 if (!pnp_assign_mem(dev, mem, nmem)) 359 goto fail; 360 nmem++; 361 mem = mem->next; 362 } 363 while (irq) { 364 if (!pnp_assign_irq(dev, irq, nirq)) 365 goto fail; 366 nirq++; 367 irq = irq->next; 368 } 369 while (dma) { 370 if (!pnp_assign_dma(dev, dma, ndma)) 371 goto fail; 372 ndma++; 373 dma = dma->next; 374 } 375 } else if (dev->dependent) 376 goto fail; 377 378 up(&pnp_res_mutex); 379 return 1; 380 381 fail: 382 pnp_clean_resource_table(&dev->res); 383 up(&pnp_res_mutex); 384 return 0; 385 } 386 387 /** 388 * pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table 389 * @dev: pointer to the desired device 390 * @res: pointer to the new resource config 391 * @mode: 0 or PNP_CONFIG_FORCE 392 * 393 * This function can be used by drivers that want to manually set thier resources. 394 */ 395 int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table * res, int mode) 396 { 397 int i; 398 struct pnp_resource_table * bak; 399 if (!dev || !res) 400 return -EINVAL; 401 if (!pnp_can_configure(dev)) 402 return -ENODEV; 403 bak = pnp_alloc(sizeof(struct pnp_resource_table)); 404 if (!bak) 405 return -ENOMEM; 406 *bak = dev->res; 407 408 down(&pnp_res_mutex); 409 dev->res = *res; 410 if (!(mode & PNP_CONFIG_FORCE)) { 411 for (i = 0; i < PNP_MAX_PORT; i++) { 412 if(!pnp_check_port(dev,i)) 413 goto fail; 414 } 415 for (i = 0; i < PNP_MAX_MEM; i++) { 416 if(!pnp_check_mem(dev,i)) 417 goto fail; 418 } 419 for (i = 0; i < PNP_MAX_IRQ; i++) { 420 if(!pnp_check_irq(dev,i)) 421 goto fail; 422 } 423 for (i = 0; i < PNP_MAX_DMA; i++) { 424 if(!pnp_check_dma(dev,i)) 425 goto fail; 426 } 427 } 428 up(&pnp_res_mutex); 429 430 kfree(bak); 431 return 0; 432 433 fail: 434 dev->res = *bak; 435 up(&pnp_res_mutex); 436 kfree(bak); 437 return -EINVAL; 438 } 439 440 /** 441 * pnp_auto_config_dev - automatically assigns resources to a device 442 * @dev: pointer to the desired device 443 * 444 */ 445 int pnp_auto_config_dev(struct pnp_dev *dev) 446 { 447 struct pnp_option *dep; 448 int i = 1; 449 450 if(!dev) 451 return -EINVAL; 452 453 if(!pnp_can_configure(dev)) { 454 pnp_info("Device %s does not support resource configuration.", dev->dev.bus_id); 455 return -ENODEV; 456 } 457 458 if (!dev->dependent) { 459 if (pnp_assign_resources(dev, 0)) 460 return 0; 461 } else { 462 dep = dev->dependent; 463 do { 464 if (pnp_assign_resources(dev, i)) 465 return 0; 466 dep = dep->next; 467 i++; 468 } while (dep); 469 } 470 471 pnp_err("Unable to assign resources to device %s.", dev->dev.bus_id); 472 return -EBUSY; 473 } 474 475 /** 476 * pnp_start_dev - low-level start of the PnP device 477 * @dev: pointer to the desired device 478 * 479 * assumes that resources have alread been allocated 480 */ 481 482 int pnp_start_dev(struct pnp_dev *dev) 483 { 484 if (!pnp_can_write(dev)) { 485 pnp_info("Device %s does not support activation.", dev->dev.bus_id); 486 return -EINVAL; 487 } 488 489 if (dev->protocol->set(dev, &dev->res)<0) { 490 pnp_err("Failed to activate device %s.", dev->dev.bus_id); 491 return -EIO; 492 } 493 494 pnp_info("Device %s activated.", dev->dev.bus_id); 495 496 return 0; 497 } 498 499 /** 500 * pnp_stop_dev - low-level disable of the PnP device 501 * @dev: pointer to the desired device 502 * 503 * does not free resources 504 */ 505 506 int pnp_stop_dev(struct pnp_dev *dev) 507 { 508 if (!pnp_can_disable(dev)) { 509 pnp_info("Device %s does not support disabling.", dev->dev.bus_id); 510 return -EINVAL; 511 } 512 if (dev->protocol->disable(dev)<0) { 513 pnp_err("Failed to disable device %s.", dev->dev.bus_id); 514 return -EIO; 515 } 516 517 pnp_info("Device %s disabled.", dev->dev.bus_id); 518 519 return 0; 520 } 521 522 /** 523 * pnp_activate_dev - activates a PnP device for use 524 * @dev: pointer to the desired device 525 * 526 * does not validate or set resources so be careful. 527 */ 528 int pnp_activate_dev(struct pnp_dev *dev) 529 { 530 int error; 531 532 if (!dev) 533 return -EINVAL; 534 if (dev->active) { 535 return 0; /* the device is already active */ 536 } 537 538 /* ensure resources are allocated */ 539 if (pnp_auto_config_dev(dev)) 540 return -EBUSY; 541 542 error = pnp_start_dev(dev); 543 if (error) 544 return error; 545 546 dev->active = 1; 547 548 return 1; 549 } 550 551 /** 552 * pnp_disable_dev - disables device 553 * @dev: pointer to the desired device 554 * 555 * inform the correct pnp protocol so that resources can be used by other devices 556 */ 557 int pnp_disable_dev(struct pnp_dev *dev) 558 { 559 int error; 560 561 if (!dev) 562 return -EINVAL; 563 if (!dev->active) { 564 return 0; /* the device is already disabled */ 565 } 566 567 error = pnp_stop_dev(dev); 568 if (error) 569 return error; 570 571 dev->active = 0; 572 573 /* release the resources so that other devices can use them */ 574 down(&pnp_res_mutex); 575 pnp_clean_resource_table(&dev->res); 576 up(&pnp_res_mutex); 577 578 return 1; 579 } 580 581 /** 582 * pnp_resource_change - change one resource 583 * @resource: pointer to resource to be changed 584 * @start: start of region 585 * @size: size of region 586 * 587 */ 588 void pnp_resource_change(struct resource *resource, resource_size_t start, 589 resource_size_t size) 590 { 591 if (resource == NULL) 592 return; 593 resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET); 594 resource->start = start; 595 resource->end = start + size - 1; 596 } 597 598 599 EXPORT_SYMBOL(pnp_manual_config_dev); 600 #if 0 601 EXPORT_SYMBOL(pnp_auto_config_dev); 602 #endif 603 EXPORT_SYMBOL(pnp_start_dev); 604 EXPORT_SYMBOL(pnp_stop_dev); 605 EXPORT_SYMBOL(pnp_activate_dev); 606 EXPORT_SYMBOL(pnp_disable_dev); 607 EXPORT_SYMBOL(pnp_resource_change); 608 EXPORT_SYMBOL(pnp_init_resource_table); 609