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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [peripheral/] [channels/] [channel.c] - Blame information for rev 1127

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

powered by: WebSVN 2.1.0

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