]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/select.c
efdb212010e37e2372df0c27bb59df8a7ce59a7c
[lincan.git] / lincan / src / select.c
1 /* select.c
2  * Header file for the Linux CAN-bus driver.
3  * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
4  * Added by Pavel Pisa - OCERA team member
5  * email:pisa@cmp.felk.cvut.cz
6  * This software is released under the GPL-License.
7  * Version lincan-0.2  9 Jul 2003
8  */
9
10 #include <linux/autoconf.h>
11
12 #include <linux/version.h>
13 #include <linux/poll.h>
14
15 #include "../include/main.h"
16 #include "../include/select.h"
17
18 unsigned int can_poll(struct file *file, poll_table *wait)
19 {
20         struct canuser_t *canuser = (struct canuser_t*)(file->private_data);
21         struct canque_ends_t *qends;
22         struct msgobj_t *obj;
23         unsigned int mask = 0;
24         unsigned long flags;
25         struct canque_edge_t *edge;
26         struct list_head *entry;
27         int full=0;
28         int i;
29
30         if(!canuser || (canuser->magic != CAN_USER_MAGIC)){
31                 CANMSG("can_close: bad canuser magic\n");
32                 return -ENODEV;
33         }
34         
35         obj = canuser->msgobj;
36         qends = canuser->qends;
37
38         if (file->f_mode & FMODE_READ) {
39                 poll_wait(file, &qends->endinfo.fileinfo.readq, wait);
40                 for(i=CANQUEUE_PRIO_NR;--i>=0;) {
41                         if(!list_empty(&qends->active[i]))
42                                 mask |= POLLIN | POLLRDNORM;
43                 }
44         }
45
46         if ((file->f_mode & FMODE_WRITE) && !(file->f_flags & O_SYNC)) {
47                 poll_wait(file, &qends->endinfo.fileinfo.writeq, wait);
48
49                 spin_lock_irqsave(&qends->ends_lock, flags);
50                 list_for_each(entry,&qends->inlist){
51                         edge=list_entry(entry,struct canque_edge_t,inpeers);
52                         if(canque_fifo_test_fl(&edge->fifo,FULL))
53                                 full=1;
54                 }
55                 spin_unlock_irqrestore(&qends->ends_lock, flags);
56
57                 if(!full)
58                         mask |= POLLOUT | POLLWRNORM;
59         }
60
61         if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_SYNC)) {
62                 poll_wait(file, &qends->endinfo.fileinfo.emptyq, wait);
63
64                 spin_lock_irqsave(&qends->ends_lock, flags);
65                 list_for_each(entry,&qends->inlist){
66                         edge=list_entry(entry,struct canque_edge_t,inpeers);
67                         if(!canque_fifo_test_fl(&edge->fifo,EMPTY))
68                                 full=1;
69                 }
70                 spin_unlock_irqrestore(&qends->ends_lock, flags);
71
72                 if(!full)
73                         mask |= POLLOUT | POLLWRNORM;
74         }
75         return mask;
76 }