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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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