]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/select.c
Header-files cleanup and CAN queue edges and ends locking reimplemented.
[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 "../include/can.h"
11 #include "../include/can_sysdep.h"
12 #include "../include/main.h"
13
14 #include <linux/poll.h>
15 #include "../include/select.h"
16
17 unsigned int can_poll(struct file *file, poll_table *wait)
18 {
19         struct canuser_t *canuser = (struct canuser_t*)(file->private_data);
20         struct canque_ends_t *qends;
21         struct msgobj_t *obj;
22         unsigned int mask = 0;
23         unsigned long flags;
24         struct canque_edge_t *edge;
25         struct list_head *entry;
26         int full=0;
27         int i;
28
29         if(!canuser || (canuser->magic != CAN_USER_MAGIC)){
30                 CANMSG("can_close: bad canuser magic\n");
31                 return -ENODEV;
32         }
33         
34         obj = canuser->msgobj;
35         qends = canuser->qends;
36
37         if (file->f_mode & FMODE_READ) {
38                 poll_wait(file, &qends->endinfo.fileinfo.readq, wait);
39                 for(i=CANQUEUE_PRIO_NR;--i>=0;) {
40                         if(!list_empty(&qends->active[i]))
41                                 mask |= POLLIN | POLLRDNORM;
42                 }
43         }
44
45         if ((file->f_mode & FMODE_WRITE) && !(file->f_flags & O_SYNC)) {
46                 poll_wait(file, &qends->endinfo.fileinfo.writeq, wait);
47
48                 spin_lock_irqsave(&qends->ends_lock, flags);
49                 list_for_each(entry,&qends->inlist){
50                         edge=list_entry(entry,struct canque_edge_t,inpeers);
51                         if(canque_fifo_test_fl(&edge->fifo,FULL))
52                                 full=1;
53                 }
54                 spin_unlock_irqrestore(&qends->ends_lock, flags);
55
56                 if(!full)
57                         mask |= POLLOUT | POLLWRNORM;
58         }
59
60         if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_SYNC)) {
61                 poll_wait(file, &qends->endinfo.fileinfo.emptyq, wait);
62
63                 spin_lock_irqsave(&qends->ends_lock, flags);
64                 list_for_each(entry,&qends->inlist){
65                         edge=list_entry(entry,struct canque_edge_t,inpeers);
66                         if(!canque_fifo_test_fl(&edge->fifo,EMPTY))
67                                 full=1;
68                 }
69                 spin_unlock_irqrestore(&qends->ends_lock, flags);
70
71                 if(!full)
72                         mask |= POLLOUT | POLLWRNORM;
73         }
74         return mask;
75 }