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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [sparc64/] [solaris/] [socksys.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* $Id: socksys.c,v 1.1.1.1 2004-04-15 01:33:59 phoenix Exp $
2
 * socksys.c: /dev/inet/ stuff for Solaris emulation.
3
 *
4
 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5
 * Copyright (C) 1997, 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
6
 * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
7
 */
8
 
9
#include <linux/types.h>
10
#include <linux/kernel.h>
11
#include <linux/sched.h>
12
#include <linux/smp.h>
13
#include <linux/smp_lock.h>
14
#include <linux/ioctl.h>
15
#include <linux/fs.h>
16
#include <linux/file.h>
17
#include <linux/init.h>
18
#include <linux/poll.h>
19
#include <linux/slab.h>
20
#include <linux/in.h>
21
#include <linux/devfs_fs_kernel.h>
22
 
23
#include <asm/uaccess.h>
24
#include <asm/termios.h>
25
 
26
#include "conv.h"
27
#include "socksys.h"
28
 
29
extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd,
30
        unsigned long arg);
31
 
32
static int af_inet_protocols[] = {
33
IPPROTO_ICMP, IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPIP, IPPROTO_TCP,
34
IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_RAW,
35
0, 0, 0, 0, 0, 0,
36
};
37
 
38
#ifndef DEBUG_SOLARIS_KMALLOC
39
 
40
#define mykmalloc kmalloc
41
#define mykfree kfree
42
 
43
#else
44
 
45
extern void * mykmalloc(size_t s, int gfp);
46
extern void mykfree(void *);
47
 
48
#endif
49
 
50
static unsigned int (*sock_poll)(struct file *, poll_table *);
51
 
52
static struct file_operations socksys_file_ops = {
53
        /* Currently empty */
54
};
55
 
56
static int socksys_open(struct inode * inode, struct file * filp)
57
{
58
        int family, type, protocol, fd;
59
        struct dentry *dentry;
60
        int (*sys_socket)(int,int,int) =
61
                (int (*)(int,int,int))SUNOS(97);
62
        struct sol_socket_struct * sock;
63
 
64
        family = ((MINOR(inode->i_rdev) >> 4) & 0xf);
65
        switch (family) {
66
        case AF_UNIX:
67
                type = SOCK_STREAM;
68
                protocol = 0;
69
                break;
70
        case AF_INET:
71
                protocol = af_inet_protocols[MINOR(inode->i_rdev) & 0xf];
72
                switch (protocol) {
73
                case IPPROTO_TCP: type = SOCK_STREAM; break;
74
                case IPPROTO_UDP: type = SOCK_DGRAM; break;
75
                default: type = SOCK_RAW; break;
76
                }
77
                break;
78
        default:
79
                type = SOCK_RAW;
80
                protocol = 0;
81
                break;
82
        }
83
 
84
        fd = sys_socket(family, type, protocol);
85
        if (fd < 0)
86
                return fd;
87
        /*
88
         * N.B. The following operations are not legal!
89
         * Try instead:
90
         * d_delete(filp->f_dentry), then d_instantiate with sock inode
91
         */
92
        dentry = filp->f_dentry;
93
        filp->f_dentry = dget(fcheck(fd)->f_dentry);
94
        filp->f_dentry->d_inode->i_rdev = inode->i_rdev;
95
        filp->f_dentry->d_inode->i_flock = inode->i_flock;
96
        filp->f_dentry->d_inode->u.socket_i.file = filp;
97
        filp->f_op = &socksys_file_ops;
98
        sock = (struct sol_socket_struct*)
99
                mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL);
100
        if (!sock) return -ENOMEM;
101
        SOLDD(("sock=%016lx(%016lx)\n", sock, filp));
102
        sock->magic = SOLARIS_SOCKET_MAGIC;
103
        sock->modcount = 0;
104
        sock->state = TS_UNBND;
105
        sock->offset = 0;
106
        sock->pfirst = sock->plast = NULL;
107
        filp->private_data = sock;
108
        SOLDD(("filp->private_data %016lx\n", filp->private_data));
109
 
110
        sys_close(fd);
111
        dput(dentry);
112
        return 0;
113
}
114
 
115
static int socksys_release(struct inode * inode, struct file * filp)
116
{
117
        struct sol_socket_struct * sock;
118
        struct T_primsg *it;
119
 
120
        /* XXX: check this */
121
        lock_kernel();
122
        sock = (struct sol_socket_struct *)filp->private_data;
123
        SOLDD(("sock release %016lx(%016lx)\n", sock, filp));
124
        it = sock->pfirst;
125
        while (it) {
126
                struct T_primsg *next = it->next;
127
 
128
                SOLDD(("socksys_release %016lx->%016lx\n", it, next));
129
                mykfree((char*)it);
130
                it = next;
131
        }
132
        filp->private_data = NULL;
133
        SOLDD(("socksys_release %016lx\n", sock));
134
        mykfree((char*)sock);
135
        unlock_kernel();
136
        return 0;
137
}
138
 
139
static unsigned int socksys_poll(struct file * filp, poll_table * wait)
140
{
141
        struct inode *ino;
142
        unsigned int mask = 0;
143
 
144
        ino=filp->f_dentry->d_inode;
145
        if (ino && ino->i_sock) {
146
                struct sol_socket_struct *sock;
147
                sock = (struct sol_socket_struct*)filp->private_data;
148
                if (sock && sock->pfirst) {
149
                        mask |= POLLIN | POLLRDNORM;
150
                        if (sock->pfirst->pri == MSG_HIPRI)
151
                                mask |= POLLPRI;
152
                }
153
        }
154
        if (sock_poll)
155
                mask |= (*sock_poll)(filp, wait);
156
        return mask;
157
}
158
 
159
static struct file_operations socksys_fops = {
160
        open:           socksys_open,
161
        release:        socksys_release,
162
};
163
 
164
static devfs_handle_t devfs_handle;
165
 
166
int __init
167
init_socksys(void)
168
{
169
        int ret;
170
        struct file * file;
171
        int (*sys_socket)(int,int,int) =
172
                (int (*)(int,int,int))SUNOS(97);
173
        int (*sys_close)(unsigned int) =
174
                (int (*)(unsigned int))SYS(close);
175
 
176
        ret = devfs_register_chrdev (30, "socksys", &socksys_fops);
177
        if (ret < 0) {
178
                printk ("Couldn't register socksys character device\n");
179
                return ret;
180
        }
181
        ret = sys_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
182
        if (ret < 0) {
183
                printk ("Couldn't create socket\n");
184
                return ret;
185
        }
186
        devfs_handle = devfs_register (NULL, "socksys", DEVFS_FL_DEFAULT,
187
                                       30, 0,
188
                                       S_IFCHR | S_IRUSR | S_IWUSR,
189
                                       &socksys_fops, NULL);
190
        file = fcheck(ret);
191
        /* N.B. Is this valid? Suppose the f_ops are in a module ... */
192
        socksys_file_ops = *file->f_op;
193
        sys_close(ret);
194
        sock_poll = socksys_file_ops.poll;
195
        socksys_file_ops.poll = socksys_poll;
196
        socksys_file_ops.release = socksys_release;
197
        return 0;
198
}
199
 
200
void
201
cleanup_socksys(void)
202
{
203
        if (devfs_unregister_chrdev(30, "socksys"))
204
                printk ("Couldn't unregister socksys character device\n");
205
        devfs_unregister (devfs_handle);
206
}

powered by: WebSVN 2.1.0

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