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.2 9 Jul 2003
10 #define __NO_VERSION__
11 #include <linux/module.h>
13 #include <linux/autoconf.h>
15 #include <linux/version.h>
16 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
17 #include <linux/malloc.h>
19 #include <linux/slab.h>
21 #include <linux/version.h>
22 #include <asm/uaccess.h>
25 #include "../include/main.h"
26 #include "../include/read.h"
27 #include "../include/ioctl.h"
29 /* This is the 'Normal' read handler for normal transmission messages */
30 inline ssize_t can_std_read(struct file *file, struct canque_ends_t *qends,
31 struct msgobj_t *obj, char *buffer, size_t length)
35 struct canque_edge_t *qedge;
36 struct canque_slot_t *slot;
38 ret=canque_test_outslot(qends, &qedge, &slot);
40 if (file->f_flags & O_NONBLOCK) {
43 ret=canque_get_outslot_wait_kern(qends, &qedge, &slot);
45 if (signal_pending(current)) {
46 DEBUGMSG("Rx interrupted\n");
50 DEBUGMSG("no data received\n");
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);
62 while (bytes_to_copy > 0) {
63 ret=canque_test_outslot(qends, &qedge, &slot);
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);
72 return length-bytes_to_copy;
75 /* This is the 'RTR' read handler for remote transmission request messages */
76 inline ssize_t can_rtr_read(struct chip_t *chip, struct msgobj_t *obj,
80 struct rtr_id *rtr_current, *new_rtr_entry;
81 struct canmsg_t read_msg;
83 DEBUGMSG("Remote transmission request\n");
84 spin_lock_irqsave(&hardware_p->rtr_lock, flags);
85 if (hardware_p->rtr_queue == NULL) { //No remote messages pending
86 new_rtr_entry=(struct rtr_id *)kmalloc(sizeof(struct rtr_id),GFP_ATOMIC);
87 if (new_rtr_entry == NULL) {
88 spin_unlock_irqrestore(&hardware_p->rtr_lock,
92 hardware_p->rtr_queue=new_rtr_entry;
95 rtr_current=hardware_p->rtr_queue;
96 while (rtr_current->next != NULL)
97 rtr_current=rtr_current->next;
98 new_rtr_entry=(struct rtr_id *)kmalloc(sizeof(struct rtr_id),GFP_ATOMIC);
99 rtr_current->next=new_rtr_entry;
101 init_waitqueue_head(&new_rtr_entry->rtr_wq);
102 new_rtr_entry->id = read_msg.id;
103 new_rtr_entry->rtr_message = &read_msg;
104 new_rtr_entry->next=NULL;
106 spin_unlock_irqrestore(&hardware_p->rtr_lock, flags);
108 /* Send remote transmission request */
109 chip->chipspecops->remote_request(chip,obj);
111 interruptible_sleep_on(&new_rtr_entry->rtr_wq);
113 spin_lock_irqsave(&hardware_p->rtr_lock, flags);
114 copy_to_user(buffer, &read_msg, sizeof(struct canmsg_t));
115 if (hardware_p->rtr_queue == new_rtr_entry) {
116 if (new_rtr_entry->next != NULL)
117 hardware_p->rtr_queue=new_rtr_entry->next;
119 hardware_p->rtr_queue=NULL;
122 rtr_current=hardware_p->rtr_queue;
123 while (rtr_current->next != new_rtr_entry)
124 rtr_current=rtr_current->next;
125 if (new_rtr_entry->next != NULL)
126 rtr_current->next=new_rtr_entry->next;
128 rtr_current->next=NULL;
130 spin_unlock_irqrestore(&hardware_p->rtr_lock, flags);
131 kfree(new_rtr_entry);
136 ssize_t can_read(struct file *file, char *buffer, size_t length, loff_t *offset)
138 struct canuser_t *canuser = (struct canuser_t*)(file->private_data);
139 struct msgobj_t *obj;
141 struct canmsg_t read_msg;
142 struct canque_ends_t *qends;
145 if(!canuser || (canuser->magic != CAN_USER_MAGIC)){
146 CANMSG("can_close: bad canuser magic\n");
150 if (length < sizeof(struct canmsg_t)) {
151 DEBUGMSG("Trying to read less bytes than a CAN message, \n");
152 DEBUGMSG("this will always return zero.\n");
155 if (length > 8 * sizeof(struct canmsg_t)) {
156 DEBUGMSG("Reading more than 8 CAN messages, this is not supported.\n");
157 DEBUGMSG("Defaulting to 8 messages.\n");
158 length = 8 * sizeof(struct canmsg_t);
160 /* Initialize hardware pointers */
161 obj = canuser->msgobj;
163 CANMSG("Could not assign buffer structure\n");
166 qends = canuser->qends;
167 if ( (chip = obj->hostchip) == NULL) {
168 CANMSG("Device is not correctly configured,\n");
169 CANMSG("please reload the driver.\n");
173 copy_from_user(&read_msg, buffer, sizeof(struct canmsg_t));
174 if (read_msg.flags & MSG_RTR)
175 ret = can_rtr_read(chip, obj, buffer);
177 ret = can_std_read(file, qends, obj, buffer, length);