Separated normal read and RTR assisted read transfer.
[lincan.git] / lincan / src / read.c
1 /* read.c
2  * Linux CAN-bus device driver.
3  * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
4  * Rewritten for new CAN queues 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.3  17 Jun 2004
8  */
9
10 #include "../include/can.h"
11 #include "../include/can_sysdep.h"
12 #include "../include/main.h"
13 #include "../include/read.h"
14
15 /* This is the 'Normal' read handler for normal transmission messages */
16 ssize_t can_read(struct file *file, char *buffer, size_t length, loff_t *offset)
17 {
18         struct canuser_t *canuser = (struct canuser_t*)(file->private_data);
19         struct canque_ends_t *qends;
20         int bytes_to_copy;
21         struct canque_edge_t *qedge;
22         struct canque_slot_t *slot;
23         int ret;
24
25         if(!canuser || (canuser->magic != CAN_USER_MAGIC)){
26                 CANMSG("can_read: bad canuser magic\n");
27                 return -ENODEV;
28         }
29
30         if (length < sizeof(struct canmsg_t)) {
31                 DEBUGMSG("Trying to read less bytes than a CAN message, \n");
32                 DEBUGMSG("this will always return zero.\n");
33                 return 0;
34         }
35
36         qends = canuser->qends;
37
38         ret=canque_test_outslot(qends, &qedge, &slot);
39         if(ret<0){
40                 if (file->f_flags & O_NONBLOCK) {
41                         return -EAGAIN;
42                 }
43                 ret=canque_get_outslot_wait_kern(qends, &qedge, &slot);
44                 if(ret<0){
45                         if (signal_pending(current)) {
46                                 DEBUGMSG("Rx interrupted\n");
47                                 return -EINTR;
48                         }
49                         /*if (!can_timeout) {
50                                 DEBUGMSG("no data received\n");
51                                 return 0;
52                         }*/
53                         return -EIO;
54                 }
55         }
56         
57         copy_to_user(buffer, &slot->msg, sizeof(struct canmsg_t));
58         canque_free_outslot(qends, qedge, slot);
59         buffer += sizeof(struct canmsg_t);
60         bytes_to_copy = length-sizeof(struct canmsg_t);
61         
62         while (bytes_to_copy > 0) {
63                 ret=canque_test_outslot(qends, &qedge, &slot);
64                 if(ret<0)
65                         break;
66                 copy_to_user(buffer, &slot->msg, sizeof(struct canmsg_t));
67                 canque_free_outslot(qends, qedge, slot);
68                 buffer += sizeof(struct canmsg_t);
69                 bytes_to_copy -= sizeof(struct canmsg_t);
70         }
71
72         return length-bytes_to_copy;
73 }
74