Blame view
common/stdio.c
5.4 KB
91d3256c6
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/* * (C) Copyright 2000 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include <config.h> #include <common.h> #include <stdarg.h> #include <malloc.h> |
52cb4d4fb
|
28 |
#include <stdio_dev.h> |
281e00a3b
|
29 |
#include <serial.h> |
7f6c2cbc2
|
30 31 32 33 |
#ifdef CONFIG_LOGBUFFER #include <logbuff.h> #endif #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) |
91d3256c6
|
34 |
#include <i2c.h> |
7f6c2cbc2
|
35 |
#endif |
91d3256c6
|
36 |
|
d87080b72
|
37 |
DECLARE_GLOBAL_DATA_PTR; |
52cb4d4fb
|
38 39 |
static struct stdio_dev devs; struct stdio_dev *stdio_devices[] = { NULL, NULL, NULL }; |
91d3256c6
|
40 |
char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" }; |
6d0f6bcf3
|
41 42 |
#if defined(CONFIG_SPLASH_SCREEN) && !defined(CONFIG_SYS_DEVICE_NULLDEV) #define CONFIG_SYS_DEVICE_NULLDEV 1 |
d791b1dc3
|
43 |
#endif |
6d0f6bcf3
|
44 |
#ifdef CONFIG_SYS_DEVICE_NULLDEV |
91d3256c6
|
45 46 |
void nulldev_putc(const char c) { |
c1de7a6da
|
47 |
/* nulldev is empty! */ |
91d3256c6
|
48 49 50 51 |
} void nulldev_puts(const char *s) { |
c1de7a6da
|
52 |
/* nulldev is empty! */ |
91d3256c6
|
53 54 55 56 |
} int nulldev_input(void) { |
c1de7a6da
|
57 58 |
/* nulldev is empty! */ return 0; |
91d3256c6
|
59 60 61 62 63 64 65 66 67 68 |
} #endif /************************************************************************** * SYSTEM DRIVERS ************************************************************************** */ static void drv_system_init (void) { |
52cb4d4fb
|
69 |
struct stdio_dev dev; |
91d3256c6
|
70 71 72 73 74 |
memset (&dev, 0, sizeof (dev)); strcpy (dev.name, "serial"); dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; |
91d3256c6
|
75 76 77 78 |
dev.putc = serial_putc; dev.puts = serial_puts; dev.getc = serial_getc; dev.tstc = serial_tstc; |
52cb4d4fb
|
79 |
stdio_register (&dev); |
91d3256c6
|
80 |
|
6d0f6bcf3
|
81 |
#ifdef CONFIG_SYS_DEVICE_NULLDEV |
91d3256c6
|
82 83 84 85 86 87 88 89 |
memset (&dev, 0, sizeof (dev)); strcpy (dev.name, "nulldev"); dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; dev.putc = nulldev_putc; dev.puts = nulldev_puts; dev.getc = nulldev_input; dev.tstc = nulldev_input; |
52cb4d4fb
|
90 |
stdio_register (&dev); |
91d3256c6
|
91 92 93 94 95 96 97 |
#endif } /************************************************************************** * DEVICES ************************************************************************** */ |
52cb4d4fb
|
98 |
struct list_head* stdio_get_list(void) |
c1de7a6da
|
99 100 101 |
{ return &(devs.list); } |
d7be3056d
|
102 |
struct stdio_dev* stdio_get_by_name(const char *name) |
c1de7a6da
|
103 104 |
{ struct list_head *pos; |
52cb4d4fb
|
105 |
struct stdio_dev *dev; |
c1de7a6da
|
106 107 108 109 110 |
if(!name) return NULL; list_for_each(pos, &(devs.list)) { |
52cb4d4fb
|
111 |
dev = list_entry(pos, struct stdio_dev, list); |
c1de7a6da
|
112 113 114 115 116 117 |
if(strcmp(dev->name, name) == 0) return dev; } return NULL; } |
52cb4d4fb
|
118 |
struct stdio_dev* stdio_clone(struct stdio_dev *dev) |
628ffd73b
|
119 |
{ |
52cb4d4fb
|
120 |
struct stdio_dev *_dev; |
628ffd73b
|
121 122 123 |
if(!dev) return NULL; |
52cb4d4fb
|
124 |
_dev = calloc(1, sizeof(struct stdio_dev)); |
628ffd73b
|
125 126 127 |
if(!_dev) return NULL; |
52cb4d4fb
|
128 |
memcpy(_dev, dev, sizeof(struct stdio_dev)); |
628ffd73b
|
129 130 131 132 |
strncpy(_dev->name, dev->name, 16); return _dev; } |
91d3256c6
|
133 |
|
52cb4d4fb
|
134 |
int stdio_register (struct stdio_dev * dev) |
91d3256c6
|
135 |
{ |
52cb4d4fb
|
136 |
struct stdio_dev *_dev; |
628ffd73b
|
137 |
|
52cb4d4fb
|
138 |
_dev = stdio_clone(dev); |
628ffd73b
|
139 140 |
if(!_dev) return -1; |
3e3c026ed
|
141 |
list_add_tail(&(_dev->list), &(devs.list)); |
91d3256c6
|
142 143 144 145 146 147 |
return 0; } /* deregister the device "devname". * returns 0 if success, -1 if device is assigned and 1 if devname not found */ |
52cb4d4fb
|
148 |
#ifdef CONFIG_SYS_STDIO_DEREGISTER |
d7be3056d
|
149 |
int stdio_deregister(const char *devname) |
91d3256c6
|
150 |
{ |
c1de7a6da
|
151 152 |
int l; struct list_head *pos; |
52cb4d4fb
|
153 |
struct stdio_dev *dev; |
03bf22f55
|
154 |
char temp_names[3][16]; |
91d3256c6
|
155 |
|
52cb4d4fb
|
156 |
dev = stdio_get_by_name(devname); |
c1de7a6da
|
157 158 159 |
if(!dev) /* device not found */ return -1; |
91d3256c6
|
160 161 162 163 164 165 166 167 |
/* get stdio devices (ListRemoveItem changes the dev list) */ for (l=0 ; l< MAX_FILES; l++) { if (stdio_devices[l] == dev) { /* Device is assigned -> report error */ return -1; } memcpy (&temp_names[l][0], stdio_devices[l]->name, |
03bf22f55
|
168 |
sizeof(temp_names[l])); |
91d3256c6
|
169 |
} |
c1de7a6da
|
170 171 |
list_del(&(dev->list)); |
91d3256c6
|
172 |
/* reassign Device list */ |
c1de7a6da
|
173 |
list_for_each(pos, &(devs.list)) { |
52cb4d4fb
|
174 |
dev = list_entry(pos, struct stdio_dev, list); |
91d3256c6
|
175 |
for (l=0 ; l< MAX_FILES; l++) { |
c1de7a6da
|
176 |
if(strcmp(dev->name, temp_names[l]) == 0) |
91d3256c6
|
177 |
stdio_devices[l] = dev; |
91d3256c6
|
178 179 180 181 |
} } return 0; } |
52cb4d4fb
|
182 |
#endif /* CONFIG_SYS_STDIO_DEREGISTER */ |
91d3256c6
|
183 |
|
52cb4d4fb
|
184 |
int stdio_init (void) |
91d3256c6
|
185 |
{ |
2e5167cca
|
186 |
#if defined(CONFIG_NEEDS_MANUAL_RELOC) |
521af04d8
|
187 |
/* already relocated for current ARM implementation */ |
91d3256c6
|
188 |
ulong relocation_offset = gd->reloc_off; |
3595ac497
|
189 |
int i; |
91d3256c6
|
190 191 192 193 194 195 |
/* relocate device name pointers */ for (i = 0; i < (sizeof (stdio_names) / sizeof (char *)); ++i) { stdio_names[i] = (char *) (((ulong) stdio_names[i]) + relocation_offset); } |
2e5167cca
|
196 |
#endif /* CONFIG_NEEDS_MANUAL_RELOC */ |
91d3256c6
|
197 198 |
/* Initialize the list */ |
c1de7a6da
|
199 |
INIT_LIST_HEAD(&(devs.list)); |
91d3256c6
|
200 |
|
4f5728987
|
201 202 203 |
#ifdef CONFIG_ARM_DCC_MULTI drv_arm_dcc_init (); #endif |
91d3256c6
|
204 |
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) |
6d0f6bcf3
|
205 |
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); |
91d3256c6
|
206 207 208 209 |
#endif #ifdef CONFIG_LCD drv_lcd_init (); #endif |
a6c7ad2f6
|
210 |
#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) |
91d3256c6
|
211 212 |
drv_video_init (); #endif |
682011ff6
|
213 214 |
#ifdef CONFIG_KEYBOARD drv_keyboard_init (); |
91d3256c6
|
215 |
#endif |
56f94be3e
|
216 217 218 |
#ifdef CONFIG_LOGBUFFER drv_logbuff_init (); #endif |
91d3256c6
|
219 |
drv_system_init (); |
281e00a3b
|
220 |
#ifdef CONFIG_SERIAL_MULTI |
52cb4d4fb
|
221 |
serial_stdio_init (); |
281e00a3b
|
222 |
#endif |
232c150a2
|
223 224 225 |
#ifdef CONFIG_USB_TTY drv_usbtty_init (); #endif |
68ceb29e7
|
226 227 228 |
#ifdef CONFIG_NETCONSOLE drv_nc_init (); #endif |
36ea8e9ad
|
229 230 231 |
#ifdef CONFIG_JTAG_CONSOLE drv_jtag_console_init (); #endif |
91d3256c6
|
232 |
|
91d3256c6
|
233 234 |
return (0); } |