|
|
1.1 root 1: /******************************************************************************
2: * Copyright (c) 2004, 2008 IBM Corporation
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>
! 21:
1.1 root 22:
23: unsigned int read_io(void *, size_t);
24: int write_io(void *, unsigned int, size_t);
25:
26: extern void get_mac(char *mac);
27: extern snk_module_t of_module;
28:
1.1.1.2 ! root 29: extern char __client_start[];
! 30:
! 31:
1.1 root 32: typedef snk_module_t *(*module_init_t) (snk_kernel_t *, pci_config_t *);
33:
34: typedef struct {
35: const char *name;
36: int type;
37: } mod_descriptor_t;
38:
39: static const mod_descriptor_t modules[] = {
1.1.1.2 ! root 40: { "net_e1000", MOD_TYPE_NETWORK },
! 41: { "net_bcm", MOD_TYPE_NETWORK },
! 42: { "net_veth", MOD_TYPE_NETWORK },
! 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: }
145: }
146:
147: void
148: modules_term()
149: {
150: int i;
151:
152: /* remove all modules */
153: for(i=0; i<MODULES_MAX; ++i) {
154: if(snk_modules[i] && snk_modules[i]->running != 0) {
155: snk_modules[i]->term();
156: }
157: snk_modules[i] = 0;
158: }
159: }
160:
161: snk_module_t *
162: get_module_by_type(int type) {
163: int i;
164:
165: for(i=0; i<MODULES_MAX; ++i) {
166: if(snk_modules[i] && snk_modules[i]->type == type) {
167: return snk_modules[i];
168: }
169: }
170: return 0;
171: }
172:
173: /**
174: * insmod_by_type - Load first module of given type
175: *
176: * @param type Type of module that we want to load
177: * @return module descriptor on success
178: * NULL if not successful
179: */
180: snk_module_t *
181: insmod_by_type(int type) {
182: int i, j;
183: for(i = 0; modules[i].name; ++i) {
184: if(modules[i].type != type)
185: continue;
186: j = load_module(modules[i].name);
187: if(j >= 0)
188: return snk_modules[j];
189: }
190: return 0;
191: }
192:
193: /**
194: * rmmod_by_type - Remove all module of given type
195: *
196: * @param type Type of module that we want to load
197: */
198: void
199: rmmod_by_type(int type) {
200: int i;
201:
202: for (i = 0; i < MODULES_MAX; ++i) {
203: if (snk_modules[i] && snk_modules[i]->type == type) {
204: if (snk_modules[i]->running)
205: snk_modules[i]->term();
206: snk_modules[i] = 0;
207: }
208: }
209: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.