Changeset 80a96d2 in mainline for uspace/srv/devman/main.c


Ignore:
Timestamp:
2011-09-05T21:26:47Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b33870b
Parents:
16cc9a6
Message:

DDF support for surprise removal.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/devman/main.c

    r16cc9a6 r80a96d2  
    316316                if (fun->child != NULL) {
    317317                        dev_node_t *dev = fun->child;
     318                        device_state_t dev_state;
    318319                       
    319320                        dev_add_ref(dev);
     321                        dev_state = dev->state;
     322                       
    320323                        fibril_rwlock_write_unlock(&device_tree.rwlock);
    321                        
     324
    322325                        /* If device is owned by driver, ask driver to give it up. */
    323                         if (dev->state == DEVICE_USABLE) {
     326                        if (dev_state == DEVICE_USABLE) {
    324327                                rc = driver_dev_remove(&device_tree, dev);
    325328                                if (rc != EOK) {
     
    333336                        if (!list_empty(&dev->functions)) {
    334337                                fibril_rwlock_read_unlock(&device_tree.rwlock);
     338                                dev_del_ref(dev);
    335339                                return EIO;
    336340                        }
     341                       
    337342                        driver_t *driver = dev->drv;
    338343                        fibril_rwlock_read_unlock(&device_tree.rwlock);
     
    579584        int rc;
    580585       
    581        
    582586        fun_node_t *fun = find_fun_node(&device_tree, fun_handle);
    583587        if (fun == NULL) {
     
    598602       
    599603        if (fun->ftype == fun_inner) {
    600                 /* Handle possible descendants */
    601                 /* TODO - This is a surprise removal */
     604                /* This is a surprise removal. Handle possible descendants */
    602605                if (fun->child != NULL) {
    603                         log_msg(LVL_WARN, "devman_remove_function(): not handling "
    604                             "descendants\n");
     606                        dev_node_t *dev = fun->child;
     607                        device_state_t dev_state;
     608                        int gone_rc;
     609                       
     610                        dev_add_ref(dev);
     611                        dev_state = dev->state;
     612                       
     613                        fibril_rwlock_write_unlock(&device_tree.rwlock);
     614                       
     615                        /* If device is owned by driver, inform driver it is gone. */
     616                        if (dev_state == DEVICE_USABLE)
     617                                gone_rc = driver_dev_gone(&device_tree, dev);
     618                        else
     619                                gone_rc = EOK;
     620                       
     621                        fibril_rwlock_read_lock(&device_tree.rwlock);
     622                       
     623                        /* Verify that driver succeeded and removed all functions */
     624                        if (gone_rc != EOK || !list_empty(&dev->functions)) {
     625                                log_msg(LVL_ERROR, "Driver did not remove "
     626                                    "functions for device that is gone. "
     627                                    "Device node is now defunct.");
     628                               
     629                                /*
     630                                 * Not much we can do but mark the device
     631                                 * node as having invalid state. This
     632                                 * is a driver bug.
     633                                 */
     634                                dev->state = DEVICE_INVALID;
     635                                fibril_rwlock_read_unlock(&device_tree.rwlock);
     636                                dev_del_ref(dev);
     637                                return;
     638                        }
     639                       
     640                        driver_t *driver = dev->drv;
     641                        fibril_rwlock_read_unlock(&device_tree.rwlock);
     642                       
     643                        if (driver)
     644                                detach_driver(&device_tree, dev);
     645                       
     646                        fibril_rwlock_write_lock(&device_tree.rwlock);
     647                        remove_dev_node(&device_tree, dev);
     648                       
     649                        /* Delete ref created when node was inserted */
     650                        dev_del_ref(dev);
     651                        /* Delete ref created by dev_add_ref(dev) above */
     652                        dev_del_ref(dev);
    605653                }
    606654        } else {
Note: See TracChangeset for help on using the changeset viewer.