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 1118

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

powered by: WebSVN 2.1.0

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