|
|
1.1 root 1: /****************************************************************************** 1.1.1.3 ! root 2: * Copyright (c) 2004, 2011 IBM Corporation 1.1 root 3: * All rights reserved. 4: * This program and the accompanying materials 5: * are made available under the terms of the BSD License 6: * which accompanies this distribution, and is available at 7: * http://www.opensource.org/licenses/bsd-license.php 8: * 9: * Contributors: 10: * IBM Corporation - initial implementation 11: *****************************************************************************/ 12: 13: #include <netdriver_int.h> 14: #include <kernel.h> 15: #include <of.h> 16: #include <rtas.h> 1.1.1.2 root 17: #include <libelf.h> 1.1 root 18: #include <cpu.h> /* flush_cache */ 19: #include <unistd.h> /* open, close, read, write */ 1.1.1.2 root 20: #include <stdio.h> 1.1.1.3 ! root 21: #include <pci.h> ! 22: #include "modules.h" 1.1.1.2 root 23: 1.1.1.3 ! root 24: snk_module_t * cimod_check_and_install(void); 1.1 root 25: 1.1.1.3 ! root 26: extern snk_module_t of_module, ci_module; 1.1 root 27: 1.1.1.2 root 28: extern char __client_start[]; 29: 30: 1.1 root 31: typedef snk_module_t *(*module_init_t) (snk_kernel_t *, pci_config_t *); 32: 33: typedef struct { 34: const char *name; 35: int type; 36: } mod_descriptor_t; 37: 38: static const mod_descriptor_t modules[] = { 1.1.1.2 root 39: { "net_e1000", MOD_TYPE_NETWORK }, 40: { "net_bcm", MOD_TYPE_NETWORK }, 41: { "net_veth", MOD_TYPE_NETWORK }, 1.1.1.3 ! root 42: { "net_virtio", MOD_TYPE_NETWORK }, 1.1.1.2 root 43: { NULL, 0 } 1.1 root 44: }; 45: 46: snk_module_t *snk_modules[MODULES_MAX]; 47: 48: extern snk_kernel_t snk_kernel_interface; 49: 50: /* Load module and call init code. 51: Init code will check, if module is responsible for device. 52: Returns -1, if not responsible for device, 0 otherwise. 53: */ 54: 55: static int 56: load_module(const char *name) 57: { 58: int len, i; 59: void *addr; 60: void *link_addr; 61: module_init_t module_init; 62: 1.1.1.2 root 63: // Load modules right after the SNK... 64: // FIXME: hard-coded offset! 65: link_addr = (void*)__client_start + 0x800000; 66: 67: // snk_kernel_interface.print("Loading Module '%s'\n", name); 68: 1.1 root 69: /* find module in module list and lookup link address */ 70: for(i=0; modules[i].name; ++i) { 71: if(strcmp(modules[i].name, name) == 0) 72: break; 73: } 74: if( modules[i].name == 0 ) { 75: /* module not in list */ 76: return -1; 77: } 78: 79: /* check if link address is used already */ 1.1.1.2 root 80: for(i=1; i<MODULES_MAX; ++i) { 81: if(snk_modules[i] /* && snk_modules[i]->link_addr == link_addr*/) { 82: // busy, can't load modules 1.1 root 83: return -2; 84: } 85: } 86: 87: /* find empty position in array of loaded modules */ 88: for(i=0; i<MODULES_MAX; ++i) { 89: if(snk_modules[i] == 0) { 90: break; 91: } 92: } 93: if(i == MODULES_MAX) { 94: // no space avaliable! 95: return -3; 96: } 97: 98: /* Read module from FLASH */ 99: len = romfs_lookup(name, &addr); 100: if (len <= 0) { 101: /* file not found */ 102: return -4; 103: } 1.1.1.2 root 104: 105: /* Copy image from flash to RAM */ 106: if (elf_load_file_to_addr(addr, link_addr, (void*)&module_init, 107: NULL, flush_cache) != 2) { 108: snk_kernel_interface.print("ELF loading failed!\n"); 109: return -5; 110: } 1.1 root 111: 112: snk_modules[i] = module_init(&snk_kernel_interface, &snk_kernel_interface.pci_conf); 113: if(snk_modules[i] == 0) { 114: /* no device found that can be managed by this module */ 115: return -5; 116: } 117: 118: if(snk_modules[i]->type == MOD_TYPE_NETWORK) { 119: /* Get mac address from device tree */ 120: get_mac(snk_modules[i]->mac_addr); 121: } 122: 123: return i; 124: } 125: 126: void 127: modules_init(void) 128: { 129: int i; 130: 131: snk_kernel_interface.io_read = read_io; 132: snk_kernel_interface.io_write = write_io; 133: 134: snk_modules[0] = &of_module; 135: 136: /* Setup Module List */ 137: for(i=1; i<MODULES_MAX; ++i) { 138: snk_modules[i] = 0; 139: } 140: 141: /* Load all modules */ 142: for(i=0; modules[i].name; ++i) { 143: load_module(modules[i].name); 144: } 1.1.1.3 ! root 145: ! 146: /* Try to init client-interface module (it's built-in, not loadable) */ ! 147: for(i=0; i<MODULES_MAX; ++i) { ! 148: if(snk_modules[i] == 0) { ! 149: snk_modules[i] = cimod_check_and_install(); ! 150: break; ! 151: } ! 152: } 1.1 root 153: } 154: 155: void 1.1.1.3 ! root 156: modules_term(void) 1.1 root 157: { 158: int i; 159: 160: /* remove all modules */ 161: for(i=0; i<MODULES_MAX; ++i) { 162: if(snk_modules[i] && snk_modules[i]->running != 0) { 163: snk_modules[i]->term(); 164: } 165: snk_modules[i] = 0; 166: } 167: } 168: 169: snk_module_t * 170: get_module_by_type(int type) { 171: int i; 172: 173: for(i=0; i<MODULES_MAX; ++i) { 174: if(snk_modules[i] && snk_modules[i]->type == type) { 175: return snk_modules[i]; 176: } 177: } 178: return 0; 179: } 180: 181: /** 182: * insmod_by_type - Load first module of given type 183: * 184: * @param type Type of module that we want to load 185: * @return module descriptor on success 186: * NULL if not successful 187: */ 188: snk_module_t * 189: insmod_by_type(int type) { 190: int i, j; 191: for(i = 0; modules[i].name; ++i) { 192: if(modules[i].type != type) 193: continue; 194: j = load_module(modules[i].name); 195: if(j >= 0) 196: return snk_modules[j]; 197: } 198: return 0; 199: } 200: 201: /** 202: * rmmod_by_type - Remove all module of given type 203: * 204: * @param type Type of module that we want to load 205: */ 206: void 207: rmmod_by_type(int type) { 208: int i; 209: 210: for (i = 0; i < MODULES_MAX; ++i) { 211: if (snk_modules[i] && snk_modules[i]->type == type) { 212: if (snk_modules[i]->running) 213: snk_modules[i]->term(); 214: snk_modules[i] = 0; 215: } 216: } 217: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.