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

Subversion Repositories or1k

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

Go to most recent revision | 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
#include <config.h>
24
#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 1244 hpanther
#ifndef HAVE_STRNDUP
39
#include "extras/extras.h"
40
#endif
41
 
42 1070 rprescott
#include "channel.h"
43
 
44
struct channel_factory
45
{
46
        const char * name;
47
        const struct channel_ops * ops;
48
        struct channel_factory * next;
49
};
50
 
51 1118 sfurman
extern struct channel_ops fd_channel_ops, file_channel_ops,
52 1127 sfurman
        xterm_channel_ops, tcp_channel_ops, tty_channel_ops;
53 1070 rprescott
 
54
static struct channel_factory preloaded[] =
55
{
56
        { "fd",     &fd_channel_ops,     &preloaded[1] },
57
        { "file",   &file_channel_ops,   &preloaded[2] },
58 1118 sfurman
        { "xterm",  &xterm_channel_ops,  &preloaded[3] },
59 1127 sfurman
        { "tcp",    &tcp_channel_ops,    &preloaded[4] },
60
        { "tty",    &tty_channel_ops,    NULL          }
61 1070 rprescott
};
62
 
63
static struct channel_factory * head = &preloaded[0];
64
 
65
static struct channel_factory * find_channel_factory(const char * name);
66
 
67
struct channel * channel_init(const char * descriptor)
68
{
69
        struct channel * retval;
70
        struct channel_factory * current;
71
        char * args, * name;
72
        int count;
73
 
74
        if(!descriptor)
75
        {
76
                return NULL;
77
        }
78
 
79
        retval = (struct channel*)calloc(1, sizeof(struct channel));
80
 
81
        if(!retval)
82
        {
83
                perror(descriptor);
84
                exit(1);
85
        }
86
 
87
        args = strchr(descriptor, ':');
88
 
89
        if(args)
90
        {
91
                count = args - descriptor;
92
                args++;
93
        }
94
        else
95
        {
96
                count = strlen(descriptor);
97
        }
98
 
99
        name = (char*)strndup(descriptor, count);
100
 
101
        if(!name)
102
        {
103
                perror(name);
104
                exit(1);
105
        }
106
 
107
        current = find_channel_factory(name);
108
 
109
        if(!current)
110
        {
111
                errno = ENODEV;
112
                perror(descriptor);
113
                exit(1);
114
        }
115
 
116
        retval->ops = current->ops;
117
 
118
        free(name);
119
 
120
        if(!retval->ops)
121
        {
122
                errno = ENODEV;
123
                perror(descriptor);
124
                exit(1);
125
        }
126
 
127
        if(retval->ops->init)
128
        {
129
                retval->data = (retval->ops->init)(args);
130
 
131
                if(!retval->data)
132
                {
133
                        perror(descriptor);
134
                        exit(1);
135
                }
136
        }
137
 
138
        return retval;
139
}
140
 
141
int channel_open(struct channel * channel)
142
{
143
        if(channel && channel->ops && channel->ops->open)
144
        {
145
                return (channel->ops->open)(channel->data);
146
        }
147
        errno = ENOSYS;
148
        return -1;
149
}
150
 
151
int channel_read(struct channel * channel, char * buffer, int size)
152
{
153
        if(channel && channel->ops && channel->ops->read)
154
        {
155
                return (channel->ops->read)(channel->data, buffer, size);
156
        }
157
        errno = ENOSYS;
158
        return -1;
159
}
160
 
161
int channel_write(struct channel * channel, const char * buffer, int size)
162
{
163
        if(channel && channel->ops && channel->ops->write)
164
        {
165
                return (channel->ops->write)(channel->data, buffer, size);
166
        }
167
        errno = ENOSYS;
168
        return -1;
169
}
170
 
171
void channel_close(struct channel * channel)
172
{
173
        if(channel && channel->ops && channel->ops->close)
174
        {
175
                (channel->ops->close)(channel->data);
176
        }
177
}
178
 
179
void channel_free(struct channel * channel)
180
{
181 1118 sfurman
        if(channel && channel->ops && channel->ops->free)
182 1070 rprescott
        {
183
                (channel->ops->free)(channel->data);
184
                free(channel);
185
        }
186
}
187
 
188
 
189
int channel_ok(struct channel * channel)
190
{
191
        if(channel && channel->ops)
192
        {
193
                if(channel->ops->isok)
194
                        return (channel->ops->isok)(channel->data);
195
                else
196
                        return 1;
197
        }
198
        return 0;
199
}
200
 
201
char * channel_status(struct channel * channel)
202
{
203
        if(channel && channel->ops && channel->ops->status)
204
        {
205
                return (channel->ops->status)(channel->data);
206
        }
207
        return "";
208
}
209
 
210
 
211
 
212
static struct channel_factory * find_channel_factory(const char * name)
213
{
214
        struct channel_factory * current = head;
215
 
216
        current = head;
217
        while(current && strcmp(current->name, name))
218
        {
219
                current = current->next;
220
        }
221
 
222
        return current;
223
}
224
 
225
int register_channel(const char * name, const struct channel_ops * ops)
226
{
227
        struct channel_factory * new;
228
 
229
 
230
        if(find_channel_factory(name))
231
        {
232
                errno = EEXIST;
233
                perror(name);
234
                exit(1);
235
        }
236
 
237
        new = (struct channel_factory *)calloc(1, sizeof(struct channel_factory));
238
 
239
        if(!new)
240
        {
241
                perror(name);
242
                exit(1);
243
        }
244
 
245
        new->name = name;
246
        new->ops  = ops;
247
        new->next = head;
248
        head = new;
249
 
250
        return (int)new;        /* dummy */
251
}
252
 
253
/*
254
 * Local variables:
255
 * c-file-style: "linux"
256
 * End:
257
 */
258
 

powered by: WebSVN 2.1.0

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