OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_68/] [or1ksim/] [peripheral/] [channels/] [channel.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1070 rprescott
/* channel.h -- Definition of types and structures for
2
   peripheral to communicate with host.  Addapted from UML.
3
 
4
   Copyright (C) 2002 Richard Prescott <rip@step.polymtl.ca>
5
 
6
This file is part of OpenRISC 1000 Architectural Simulator.
7
 
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(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., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
 
22 1244 hpanther
#if HAVE_CONFIG_H
23 1350 nogj
#include "config.h"
24 1244 hpanther
#endif
25
 
26 1070 rprescott
#define _GNU_SOURCE     /* for strndup */
27
 
28
#include <stdio.h>      /* perror */
29
#include <stdlib.h>     /* exit */
30 1244 hpanther
 
31
#if HAVE_MALLOC_H
32 1070 rprescott
#include <malloc.h>     /* calloc, free */
33 1244 hpanther
#endif
34
 
35 1070 rprescott
#include <string.h>     /* strndup, strcmp, strlen, strchr */
36
#include <errno.h>      /* errno */
37
 
38 1350 nogj
#include "port.h"
39 1244 hpanther
 
40 1070 rprescott
#include "channel.h"
41
 
42
struct channel_factory
43
{
44
        const char * name;
45
        const struct channel_ops * ops;
46
        struct channel_factory * next;
47
};
48
 
49 1118 sfurman
extern struct channel_ops fd_channel_ops, file_channel_ops,
50 1127 sfurman
        xterm_channel_ops, tcp_channel_ops, tty_channel_ops;
51 1070 rprescott
 
52
static struct channel_factory preloaded[] =
53
{
54
        { "fd",     &fd_channel_ops,     &preloaded[1] },
55
        { "file",   &file_channel_ops,   &preloaded[2] },
56 1118 sfurman
        { "xterm",  &xterm_channel_ops,  &preloaded[3] },
57 1127 sfurman
        { "tcp",    &tcp_channel_ops,    &preloaded[4] },
58
        { "tty",    &tty_channel_ops,    NULL          }
59 1070 rprescott
};
60
 
61
static struct channel_factory * head = &preloaded[0];
62
 
63
static struct channel_factory * find_channel_factory(const char * name);
64
 
65
struct channel * channel_init(const char * descriptor)
66
{
67
        struct channel * retval;
68
        struct channel_factory * current;
69
        char * args, * name;
70
        int count;
71
 
72
        if(!descriptor)
73
        {
74
                return NULL;
75
        }
76
 
77
        retval = (struct channel*)calloc(1, sizeof(struct channel));
78
 
79
        if(!retval)
80
        {
81
                perror(descriptor);
82
                exit(1);
83
        }
84
 
85
        args = strchr(descriptor, ':');
86
 
87
        if(args)
88
        {
89
                count = args - descriptor;
90
                args++;
91
        }
92
        else
93
        {
94
                count = strlen(descriptor);
95
        }
96
 
97
        name = (char*)strndup(descriptor, count);
98
 
99
        if(!name)
100
        {
101
                perror(name);
102
                exit(1);
103
        }
104
 
105
        current = find_channel_factory(name);
106
 
107
        if(!current)
108
        {
109
                errno = ENODEV;
110
                perror(descriptor);
111
                exit(1);
112
        }
113
 
114
        retval->ops = current->ops;
115
 
116
        free(name);
117
 
118
        if(!retval->ops)
119
        {
120
                errno = ENODEV;
121
                perror(descriptor);
122
                exit(1);
123
        }
124
 
125
        if(retval->ops->init)
126
        {
127
                retval->data = (retval->ops->init)(args);
128
 
129
                if(!retval->data)
130
                {
131
                        perror(descriptor);
132
                        exit(1);
133
                }
134
        }
135
 
136
        return retval;
137
}
138
 
139
int channel_open(struct channel * channel)
140
{
141
        if(channel && channel->ops && channel->ops->open)
142
        {
143
                return (channel->ops->open)(channel->data);
144
        }
145
        errno = ENOSYS;
146
        return -1;
147
}
148
 
149
int channel_read(struct channel * channel, char * buffer, int size)
150
{
151
        if(channel && channel->ops && channel->ops->read)
152
        {
153
                return (channel->ops->read)(channel->data, buffer, size);
154
        }
155
        errno = ENOSYS;
156
        return -1;
157
}
158
 
159
int channel_write(struct channel * channel, const char * buffer, int size)
160
{
161
        if(channel && channel->ops && channel->ops->write)
162
        {
163
                return (channel->ops->write)(channel->data, buffer, size);
164
        }
165
        errno = ENOSYS;
166
        return -1;
167
}
168
 
169
void channel_close(struct channel * channel)
170
{
171
        if(channel && channel->ops && channel->ops->close)
172
        {
173
                (channel->ops->close)(channel->data);
174
        }
175
}
176
 
177
void channel_free(struct channel * channel)
178
{
179 1118 sfurman
        if(channel && channel->ops && channel->ops->free)
180 1070 rprescott
        {
181
                (channel->ops->free)(channel->data);
182
                free(channel);
183
        }
184
}
185
 
186
 
187
int channel_ok(struct channel * channel)
188
{
189
        if(channel && channel->ops)
190
        {
191
                if(channel->ops->isok)
192
                        return (channel->ops->isok)(channel->data);
193
                else
194
                        return 1;
195
        }
196
        return 0;
197
}
198
 
199
char * channel_status(struct channel * channel)
200
{
201
        if(channel && channel->ops && channel->ops->status)
202
        {
203
                return (channel->ops->status)(channel->data);
204
        }
205
        return "";
206
}
207
 
208
 
209
 
210
static struct channel_factory * find_channel_factory(const char * name)
211
{
212
        struct channel_factory * current = head;
213
 
214
        current = head;
215
        while(current && strcmp(current->name, name))
216
        {
217
                current = current->next;
218
        }
219
 
220
        return current;
221
}
222
 
223
int register_channel(const char * name, const struct channel_ops * ops)
224
{
225
        struct channel_factory * new;
226
 
227
 
228
        if(find_channel_factory(name))
229
        {
230
                errno = EEXIST;
231
                perror(name);
232
                exit(1);
233
        }
234
 
235
        new = (struct channel_factory *)calloc(1, sizeof(struct channel_factory));
236
 
237
        if(!new)
238
        {
239
                perror(name);
240
                exit(1);
241
        }
242
 
243
        new->name = name;
244
        new->ops  = ops;
245
        new->next = head;
246
        head = new;
247
 
248
        return (int)new;        /* dummy */
249
}
250
 
251
/*
252
 * Local variables:
253
 * c-file-style: "linux"
254
 * End:
255
 */
256
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.