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