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

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [fs/] [fifo.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *  linux/fs/fifo.c
3
 *
4
 *  written by Paul H. Hargrove
5
 */
6
 
7
#include <linux/sched.h>
8
#include <linux/kernel.h>
9
#include <linux/errno.h>
10
#include <linux/fcntl.h>
11
#include <linux/mm.h>
12
 
13
static int fifo_open(struct inode * inode,struct file * filp)
14
{
15
        int retval = 0;
16
        unsigned long page;
17
 
18
        switch( filp->f_mode ) {
19
 
20
        case 1:
21
        /*
22
         *  O_RDONLY
23
         *  POSIX.1 says that O_NONBLOCK means return with the FIFO
24
         *  opened, even when there is no process writing the FIFO.
25
         */
26
                filp->f_op = &connecting_fifo_fops;
27
                if (!PIPE_READERS(*inode)++)
28
                        wake_up_interruptible(&PIPE_WAIT(*inode));
29
                if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) {
30
                        PIPE_RD_OPENERS(*inode)++;
31
                        while (!PIPE_WRITERS(*inode)) {
32
                                if (current->signal & ~current->blocked) {
33
                                        retval = -ERESTARTSYS;
34
                                        break;
35
                                }
36
                                interruptible_sleep_on(&PIPE_WAIT(*inode));
37
                        }
38
                        if (!--PIPE_RD_OPENERS(*inode))
39
                                wake_up_interruptible(&PIPE_WAIT(*inode));
40
                }
41
                while (PIPE_WR_OPENERS(*inode))
42
                        interruptible_sleep_on(&PIPE_WAIT(*inode));
43
                if (PIPE_WRITERS(*inode))
44
                        filp->f_op = &read_fifo_fops;
45
                if (retval && !--PIPE_READERS(*inode))
46
                        wake_up_interruptible(&PIPE_WAIT(*inode));
47
                break;
48
 
49
        case 2:
50
        /*
51
         *  O_WRONLY
52
         *  POSIX.1 says that O_NONBLOCK means return -1 with
53
         *  errno=ENXIO when there is no process reading the FIFO.
54
         */
55
                if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) {
56
                        retval = -ENXIO;
57
                        break;
58
                }
59
                filp->f_op = &write_fifo_fops;
60
                if (!PIPE_WRITERS(*inode)++)
61
                        wake_up_interruptible(&PIPE_WAIT(*inode));
62
                if (!PIPE_READERS(*inode)) {
63
                        PIPE_WR_OPENERS(*inode)++;
64
                        while (!PIPE_READERS(*inode)) {
65
                                if (current->signal & ~current->blocked) {
66
                                        retval = -ERESTARTSYS;
67
                                        break;
68
                                }
69
                                interruptible_sleep_on(&PIPE_WAIT(*inode));
70
                        }
71
                        if (!--PIPE_WR_OPENERS(*inode))
72
                                wake_up_interruptible(&PIPE_WAIT(*inode));
73
                }
74
                while (PIPE_RD_OPENERS(*inode))
75
                        interruptible_sleep_on(&PIPE_WAIT(*inode));
76
                if (retval && !--PIPE_WRITERS(*inode))
77
                        wake_up_interruptible(&PIPE_WAIT(*inode));
78
                break;
79
 
80
        case 3:
81
        /*
82
         *  O_RDWR
83
         *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
84
         *  This implementation will NEVER block on a O_RDWR open, since
85
         *  the process can at least talk to itself.
86
         */
87
                filp->f_op = &rdwr_fifo_fops;
88
                if (!PIPE_READERS(*inode)++)
89
                        wake_up_interruptible(&PIPE_WAIT(*inode));
90
                while (PIPE_WR_OPENERS(*inode))
91
                        interruptible_sleep_on(&PIPE_WAIT(*inode));
92
                if (!PIPE_WRITERS(*inode)++)
93
                        wake_up_interruptible(&PIPE_WAIT(*inode));
94
                while (PIPE_RD_OPENERS(*inode))
95
                        interruptible_sleep_on(&PIPE_WAIT(*inode));
96
                break;
97
 
98
        default:
99
                retval = -EINVAL;
100
        }
101
        if (retval || PIPE_BASE(*inode))
102
                return retval;
103
        page = __get_free_page(GFP_KERNEL);
104
        if (PIPE_BASE(*inode)) {
105
                free_page(page);
106
                return 0;
107
        }
108
        if (!page)
109
                return -ENOMEM;
110
        PIPE_LOCK(*inode) = 0;
111
        PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
112
        PIPE_BASE(*inode) = (char *) page;
113
        return 0;
114
}
115
 
116
/*
117
 * Dummy default file-operations: the only thing this does
118
 * is contain the open that then fills in the correct operations
119
 * depending on the access mode of the file...
120
 */
121
static struct file_operations def_fifo_fops = {
122
        NULL,
123
        NULL,
124
        NULL,
125
        NULL,
126
        NULL,
127
        NULL,
128
        NULL,
129
        fifo_open,              /* will set read or write pipe_fops */
130
        NULL,
131
        NULL
132
};
133
 
134
struct inode_operations fifo_inode_operations = {
135
        &def_fifo_fops,         /* default file operations */
136
        NULL,                   /* create */
137
        NULL,                   /* lookup */
138
        NULL,                   /* link */
139
        NULL,                   /* unlink */
140
        NULL,                   /* symlink */
141
        NULL,                   /* mkdir */
142
        NULL,                   /* rmdir */
143
        NULL,                   /* mknod */
144
        NULL,                   /* rename */
145
        NULL,                   /* readlink */
146
        NULL,                   /* follow_link */
147
        NULL,                   /* readpage */
148
        NULL,                   /* writepage */
149
        NULL,                   /* bmap */
150
        NULL,                   /* truncate */
151
        NULL                    /* permission */
152
};
153
 
154
void init_fifo(struct inode * inode)
155
{
156
        inode->i_op = &fifo_inode_operations;
157
        inode->i_pipe = 1;
158
        PIPE_LOCK(*inode) = 0;
159
        PIPE_BASE(*inode) = NULL;
160
        PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
161
        PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
162
        PIPE_WAIT(*inode) = NULL;
163
        PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
164
}

powered by: WebSVN 2.1.0

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