Merge branch 'support_for_dragino2'
[oweals/u-boot_mod.git] / u-boot / common / devices.c
1 /*
2  * (C) Copyright 2000
3  * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23 #include <config.h>
24 #include <common.h>
25 #include <stdarg.h>
26 #include <malloc.h>
27 #include <devices.h>
28 #include <serial.h>
29
30 DECLARE_GLOBAL_DATA_PTR;
31
32 list_t devlist = 0;
33 device_t *stdio_devices[] = {NULL, NULL, NULL};
34 char *stdio_names[MAX_FILES] = {"stdin", "stdout", "stderr"};
35
36 /**************************************************************************
37  * SYSTEM DRIVERS
38  **************************************************************************
39  */
40 static void drv_system_init(void){
41         device_t dev;
42
43         memset(&dev, 0, sizeof(dev));
44
45         strcpy(dev.name, "serial");
46         dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
47
48         dev.putc = serial_putc;
49         dev.puts = serial_puts;
50         dev.getc = serial_getc;
51         dev.tstc = serial_tstc;
52
53         device_register(&dev);
54 }
55
56 /**************************************************************************
57  * DEVICES
58  **************************************************************************
59  */
60 int device_register(device_t * dev){
61         ListInsertItem(devlist, dev, LIST_END);
62         return(0);
63 }
64
65 /*
66  * deregister the device "devname".
67  * returns 0 if success, -1 if device is assigned and 1 if devname not found
68  */
69 #ifdef  CFG_DEVICE_DEREGISTER
70 int device_deregister(char *devname){
71         int i,l,dev_index;
72         device_t *dev = NULL;
73         char temp_names[3][8];
74
75         dev_index=-1;
76
77         for(i=1; i<=ListNumItems(devlist); i++){
78                 dev = ListGetPtrToItem(devlist, i);
79
80                 if(strcmp(dev->name,devname)==0){
81                         dev_index=i;
82                         break;
83                 }
84         }
85
86         if(dev_index<0){ /* device not found */
87                 return(0);
88         }
89
90         /* get stdio devices (ListRemoveItem changes the dev list) */
91         for(l=0; l< MAX_FILES; l++){
92                 if(stdio_devices[l] == dev){
93                         /* Device is assigned -> report error */
94                         return(-1);
95                 }
96                 memcpy(&temp_names[l][0], stdio_devices[l]->name, sizeof(stdio_devices[l]->name));
97         }
98
99         ListRemoveItem(devlist,NULL,dev_index);
100
101         /* reassign Device list */
102         for(i=1; i<=ListNumItems(devlist); i++){
103                 dev = ListGetPtrToItem(devlist, i);
104
105                 for(l=0; l< MAX_FILES; l++){
106                         if(strcmp(dev->name,temp_names[l])==0){
107                                 stdio_devices[l] = dev;
108                         }
109                 }
110         }
111
112         return(0);
113 }
114 #endif  /* CFG_DEVICE_DEREGISTER */
115
116 int devices_init(void){
117         ulong relocation_offset = gd->reloc_off;
118         int i;
119
120         /* relocate device name pointers */
121         for(i = 0; i < (sizeof(stdio_names) / sizeof(char *)); ++i){
122                 stdio_names[i] = (char *)(((ulong)stdio_names[i]) + relocation_offset);
123         }
124
125         /* Initialize the list */
126         devlist = ListCreate(sizeof(device_t));
127
128         if(devlist == NULL){
129                 eputs("Cannot initialize the list of devices!\n");
130                 return(-1);
131         }
132
133         drv_system_init();
134
135 #ifdef CONFIG_NETCONSOLE
136         drv_nc_init();
137 #endif
138
139         return(0);
140 }
141
142 int devices_done(void){
143         ListDispose(devlist);
144
145         return(0);
146 }