Annotation of qemu/roms/ipxe/src/drivers/linux/linux.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (C) 2010 Piotr JaroszyƄski <[email protected]>
        !             3:  *
        !             4:  * This program is free software; you can redistribute it and/or
        !             5:  * modify it under the terms of the GNU General Public License as
        !             6:  * published by the Free Software Foundation; either version 2 of the
        !             7:  * License, or any later version.
        !             8:  *
        !             9:  * This program is distributed in the hope that it will be useful, but
        !            10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            12:  * General Public License for more details.
        !            13:  *
        !            14:  * You should have received a copy of the GNU General Public License
        !            15:  * along with this program; if not, write to the Free Software
        !            16:  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
        !            17:  */
        !            18: 
        !            19: FILE_LICENCE(GPL2_OR_LATER);
        !            20: 
        !            21: /** @file
        !            22:  *
        !            23:  * Linux root_device and root_driver.
        !            24:  */
        !            25: 
        !            26: #include <errno.h>
        !            27: #include <string.h>
        !            28: #include <stdio.h>
        !            29: #include <ipxe/linux.h>
        !            30: #include <ipxe/malloc.h>
        !            31: #include <ipxe/settings.h>
        !            32: 
        !            33: LIST_HEAD(linux_device_requests);
        !            34: LIST_HEAD(linux_global_settings);
        !            35: 
        !            36: /** Go over the device requests looking for a matching linux driver to handle them. */
        !            37: static int linux_probe(struct root_device *rootdev)
        !            38: {
        !            39:        struct linux_device_request *request;
        !            40:        struct linux_driver *driver;
        !            41:        struct linux_device *device = NULL;
        !            42:        int rc;
        !            43: 
        !            44:        /* Apply global settings */
        !            45:        linux_apply_settings(&linux_global_settings, NULL);
        !            46: 
        !            47:        list_for_each_entry(request, &linux_device_requests, list) {
        !            48:                if (! device)
        !            49:                        device = zalloc(sizeof(*device));
        !            50: 
        !            51:                if (! device)
        !            52:                        return -ENOMEM;
        !            53: 
        !            54:                rc = 1;
        !            55: 
        !            56:                for_each_table_entry(driver, LINUX_DRIVERS) {
        !            57:                        if ((rc = strcmp(driver->name, request->driver)) == 0)
        !            58:                                break;
        !            59:                }
        !            60: 
        !            61:                if (rc != 0) {
        !            62:                        printf("Linux driver '%s' not found\n", request->driver);
        !            63:                        continue;
        !            64:                }
        !            65: 
        !            66:                if (! driver->can_probe) {
        !            67:                        printf("Driver '%s' cannot handle any more devices\n", driver->name);
        !            68:                        continue;
        !            69:                }
        !            70: 
        !            71:                /* We found a matching driver so add the device to the hierarchy */
        !            72:                list_add(&device->dev.siblings, &rootdev->dev.children);
        !            73:                device->dev.parent = &rootdev->dev;
        !            74:                INIT_LIST_HEAD(&device->dev.children);
        !            75: 
        !            76:                if (driver->probe(device, request) == 0) {
        !            77:                        device->driver = driver;
        !            78:                        device->dev.driver_name = driver->name;
        !            79:                        /* Driver handled the device so release ownership */
        !            80:                        device = NULL;
        !            81:                } else {
        !            82:                        /* Driver failed to handle the device so remove it from the hierarchy
        !            83:                         * and reuse the object */
        !            84:                        list_del(&device->dev.siblings);
        !            85:                }
        !            86:        };
        !            87: 
        !            88:        free(device);
        !            89: 
        !            90:        return 0;
        !            91: }
        !            92: 
        !            93: /** Remove all the linux devices registered in probe() */
        !            94: static void linux_remove(struct root_device *rootdev)
        !            95: {
        !            96:        struct linux_device *device;
        !            97:        struct linux_device *tmp;
        !            98: 
        !            99:        list_for_each_entry_safe(device, tmp, &rootdev->dev.children, dev.siblings) {
        !           100:                list_del(&device->dev.siblings);
        !           101:                device->driver->remove(device);
        !           102:                free(device);
        !           103:        }
        !           104: }
        !           105: 
        !           106: /** Linux root driver */
        !           107: static struct root_driver linux_root_driver = {
        !           108:        .probe = linux_probe,
        !           109:        .remove = linux_remove,
        !           110: };
        !           111: 
        !           112: /** Linux root device */
        !           113: struct root_device linux_root_device __root_device = {
        !           114:        .dev = { .name = "linux" },
        !           115:        .driver = &linux_root_driver,
        !           116: };
        !           117: 
        !           118: struct linux_setting *linux_find_setting(char *name, struct list_head *settings)
        !           119: {
        !           120:        struct linux_setting *setting;
        !           121:        struct linux_setting *result = NULL;
        !           122: 
        !           123:        /* Find the last occurrence of a setting with the specified name */
        !           124:        list_for_each_entry(setting, settings, list) {
        !           125:                if (strcmp(setting->name, name) == 0) {
        !           126:                        result = setting;
        !           127:                }
        !           128:        }
        !           129: 
        !           130:        return result;
        !           131: }
        !           132: 
        !           133: void linux_apply_settings(struct list_head *new_settings, struct settings *settings_block)
        !           134: {
        !           135:        struct linux_setting *setting;
        !           136:        int rc;
        !           137: 
        !           138:        list_for_each_entry(setting, new_settings, list) {
        !           139:                /* Skip already applied settings */
        !           140:                if (setting->applied)
        !           141:                        continue;
        !           142: 
        !           143:                struct setting *s = find_setting(setting->name);
        !           144:                if (s) {
        !           145:                        rc = storef_setting(settings_block, find_setting(setting->name), setting->value);
        !           146:                        if (rc != 0)
        !           147:                                DBG("linux storing setting '%s' = '%s' failed\n", setting->name, setting->value);
        !           148:                        setting->applied = 1;
        !           149:                } else {
        !           150:                        DBG("linux unknown setting '%s'\n", setting->name);
        !           151:                }
        !           152:        }
        !           153: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.