Changeset f278930 in mainline
- Timestamp:
- 2011-09-03T12:02:08Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7fff38c1
- Parents:
- f480d7e
- Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/isa/isa.c
rf480d7e rf278930 37 37 */ 38 38 39 #include <adt/list.h> 39 40 #include <assert.h> 40 41 #include <stdio.h> … … 63 64 #define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev" 64 65 65 /** Obtain soft-state pointer from function node pointer */ 66 #define ISA_FUN(fnode) ((isa_fun_t *) ((fnode)->driver_data)) 66 /** Obtain soft-state from device node */ 67 #define ISA_BUS(dev) ((isa_bus_t *) ((dev)->driver_data)) 68 69 /** Obtain soft-state from function node */ 70 #define ISA_FUN(fun) ((isa_fun_t *) ((fun)->driver_data)) 67 71 68 72 #define ISA_MAX_HW_RES 4 69 73 74 typedef struct { 75 fibril_mutex_t mutex; 76 ddf_dev_t *dev; 77 ddf_fun_t *fctl; 78 list_t functions; 79 } isa_bus_t; 80 70 81 typedef struct isa_fun { 82 fibril_mutex_t mutex; 71 83 ddf_fun_t *fnode; 72 84 hw_resource_list_t hw_resources; 85 link_t bus_link; 73 86 } isa_fun_t; 74 87 … … 96 109 97 110 static int isa_add_device(ddf_dev_t *dev); 111 static int isa_dev_remove(ddf_dev_t *dev); 98 112 static int isa_fun_online(ddf_fun_t *fun); 99 113 static int isa_fun_offline(ddf_fun_t *fun); … … 102 116 static driver_ops_t isa_ops = { 103 117 .add_device = &isa_add_device, 118 .dev_remove = &isa_dev_remove, 104 119 .fun_online = &isa_fun_online, 105 120 .fun_offline = &isa_fun_offline … … 112 127 }; 113 128 114 static isa_fun_t *isa_fun_create(ddf_dev_t *dev, const char *name) 115 { 116 isa_fun_t *fun = calloc(1, sizeof(isa_fun_t)); 129 static isa_fun_t *isa_fun_create(isa_bus_t *isa, const char *name) 130 { 131 ddf_fun_t *fnode = ddf_fun_create(isa->dev, fun_inner, name); 132 if (fnode == NULL) 133 return NULL; 134 135 isa_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(isa_fun_t)); 117 136 if (fun == NULL) 118 137 return NULL; 119 138 120 ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name); 121 if (fnode == NULL) { 122 free(fun); 123 return NULL; 124 } 125 139 fibril_mutex_initialize(&fun->mutex); 126 140 fun->fnode = fnode; 127 fnode->driver_data = fun;128 141 return fun; 129 142 } … … 396 409 } 397 410 398 static char *isa_fun_read_info(char *fun_conf, ddf_dev_t *dev) 411 static void fun_hw_res_free(isa_fun_t *fun) 412 { 413 free(fun->hw_resources.resources); 414 fun->hw_resources.resources = NULL; 415 } 416 417 static char *isa_fun_read_info(char *fun_conf, isa_bus_t *isa) 399 418 { 400 419 char *line; … … 419 438 return NULL; 420 439 421 isa_fun_t *fun = isa_fun_create( dev, fun_name);440 isa_fun_t *fun = isa_fun_create(isa, fun_name); 422 441 if (fun == NULL) { 423 442 free(fun_name); … … 452 471 (void) ddf_fun_bind(fun->fnode); 453 472 473 list_append(&fun->bus_link, &isa->functions); 474 454 475 return fun_conf; 455 476 } 456 477 457 static void fun_conf_parse(char *conf, ddf_dev_t *dev)478 static void fun_conf_parse(char *conf, isa_bus_t *isa) 458 479 { 459 480 while (conf != NULL && *conf != '\0') { 460 conf = isa_fun_read_info(conf, dev);461 } 462 } 463 464 static void isa_functions_add( ddf_dev_t *dev)481 conf = isa_fun_read_info(conf, isa); 482 } 483 } 484 485 static void isa_functions_add(isa_bus_t *isa) 465 486 { 466 487 char *fun_conf; … … 468 489 fun_conf = fun_conf_read(CHILD_FUN_CONF_PATH); 469 490 if (fun_conf != NULL) { 470 fun_conf_parse(fun_conf, dev);491 fun_conf_parse(fun_conf, isa); 471 492 free(fun_conf); 472 493 } … … 475 496 static int isa_add_device(ddf_dev_t *dev) 476 497 { 498 isa_bus_t *isa; 499 477 500 ddf_msg(LVL_DEBUG, "isa_add_device, device handle = %d", 478 501 (int) dev->handle); 479 502 503 isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t)); 504 if (isa == NULL) 505 return ENOMEM; 506 507 fibril_mutex_initialize(&isa->mutex); 508 isa->dev = dev; 509 list_initialize(&isa->functions); 510 480 511 /* Make the bus device more visible. Does not do anything. */ 481 512 ddf_msg(LVL_DEBUG, "Adding a 'ctl' function"); 482 513 483 ddf_fun_t *ctl = ddf_fun_create(dev, fun_exposed, "ctl"); 484 if (ctl == NULL) { 514 fibril_mutex_lock(&isa->mutex); 515 516 isa->fctl = ddf_fun_create(dev, fun_exposed, "ctl"); 517 if (isa->fctl == NULL) { 485 518 ddf_msg(LVL_ERROR, "Failed creating control function."); 486 519 return EXDEV; 487 520 } 488 521 489 if (ddf_fun_bind(ctl) != EOK) { 522 if (ddf_fun_bind(isa->fctl) != EOK) { 523 ddf_fun_destroy(isa->fctl); 490 524 ddf_msg(LVL_ERROR, "Failed binding control function."); 491 525 return EXDEV; … … 493 527 494 528 /* Add functions as specified in the configuration file. */ 495 isa_functions_add( dev);529 isa_functions_add(isa); 496 530 ddf_msg(LVL_NOTE, "Finished enumerating legacy functions"); 531 532 fibril_mutex_unlock(&isa->mutex); 533 534 return EOK; 535 } 536 537 static int isa_dev_remove(ddf_dev_t *dev) 538 { 539 isa_bus_t *isa = ISA_BUS(dev); 540 int rc; 541 542 fibril_mutex_lock(&isa->mutex); 543 544 while (!list_empty(&isa->functions)) { 545 isa_fun_t *fun = list_get_instance(list_first(&isa->functions), 546 isa_fun_t, bus_link); 547 548 rc = ddf_fun_offline(fun->fnode); 549 if (rc != EOK) { 550 fibril_mutex_unlock(&isa->mutex); 551 ddf_msg(LVL_ERROR, "Failed offlining %s", fun->fnode->name); 552 return rc; 553 } 554 555 rc = ddf_fun_unbind(fun->fnode); 556 if (rc != EOK) { 557 fibril_mutex_unlock(&isa->mutex); 558 ddf_msg(LVL_ERROR, "Failed unbinding %s", fun->fnode->name); 559 return rc; 560 } 561 562 list_remove(&fun->bus_link); 563 564 fun_hw_res_free(fun); 565 ddf_fun_destroy(fun->fnode); 566 } 567 568 if (ddf_fun_unbind(isa->fctl) != EOK) { 569 fibril_mutex_unlock(&isa->mutex); 570 ddf_msg(LVL_ERROR, "Failed unbinding control function."); 571 return EXDEV; 572 } 573 574 fibril_mutex_unlock(&isa->mutex); 497 575 498 576 return EOK; -
uspace/drv/bus/pci/pciintel/pci.c
rf480d7e rf278930 203 203 204 204 static int pci_add_device(ddf_dev_t *); 205 static int pci_fun_online(ddf_fun_t *); 206 static int pci_fun_offline(ddf_fun_t *); 205 207 206 208 /** PCI bus driver standard operations */ 207 209 static driver_ops_t pci_ops = { 208 .add_device = &pci_add_device 210 .add_device = &pci_add_device, 211 .fun_online = &pci_fun_online, 212 .fun_offline = &pci_fun_offline, 209 213 }; 210 214 … … 651 655 } 652 656 657 static int pci_fun_online(ddf_fun_t *fun) 658 { 659 ddf_msg(LVL_DEBUG, "pci_fun_online()"); 660 return ddf_fun_online(fun); 661 } 662 663 static int pci_fun_offline(ddf_fun_t *fun) 664 { 665 ddf_msg(LVL_DEBUG, "pci_fun_offline()"); 666 return ddf_fun_offline(fun); 667 } 668 653 669 static void pciintel_init(void) 654 670 { -
uspace/lib/drv/generic/driver.c
rf480d7e rf278930 313 313 fibril_mutex_lock(&devices_mutex); 314 314 dev = driver_get_device(devh); 315 dev_add_ref(dev); 315 if (dev != NULL) 316 dev_add_ref(dev); 316 317 fibril_mutex_unlock(&devices_mutex); 317 318 -
uspace/srv/devman/main.c
rf480d7e rf278930 320 320 fibril_rwlock_write_unlock(&device_tree.rwlock); 321 321 322 rc = driver_dev_remove(&device_tree, dev); 323 if (rc != EOK) { 324 dev_del_ref(dev); 325 return ENOTSUP; 322 /* If device is owned by driver, ask driver to give it up. */ 323 if (dev->state == DEVICE_USABLE) { 324 rc = driver_dev_remove(&device_tree, dev); 325 if (rc != EOK) { 326 dev_del_ref(dev); 327 return ENOTSUP; 328 } 326 329 } 327 330 … … 332 335 return EIO; 333 336 } 337 driver_t *driver = dev->drv; 334 338 fibril_rwlock_read_unlock(&device_tree.rwlock); 335 339 336 detach_driver(&device_tree, dev); 340 if (driver) 341 detach_driver(&device_tree, dev); 337 342 338 343 fibril_rwlock_write_lock(&device_tree.rwlock);
Note:
See TracChangeset
for help on using the changeset viewer.