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 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0))
102 init_waitqueue(&new_rtr_entry->rtr_wq);
104 init_waitqueue_head(&new_rtr_entry->rtr_wq);
106 new_rtr_entry->id = read_msg.id;
107 new_rtr_entry->rtr_message = &read_msg;
108 new_rtr_entry->next=NULL;
110 spin_unlock_irqrestore(&hardware_p->rtr_lock, flags);
112 /* Send remote transmission request */
113 chip->chipspecops->remote_request(chip,obj);
115 interruptible_sleep_on(&new_rtr_entry->rtr_wq);
117 spin_lock_irqsave(&hardware_p->rtr_lock, flags);
118 copy_to_user(buffer, &read_msg, sizeof(struct canmsg_t));
119 if (hardware_p->rtr_queue == new_rtr_entry) {
120 if (new_rtr_entry->next != NULL)
121 hardware_p->rtr_queue=new_rtr_entry->next;
123 hardware_p->rtr_queue=NULL;
126 rtr_current=hardware_p->rtr_queue;
127 while (rtr_current->next != new_rtr_entry)
128 rtr_current=rtr_current->next;
129 if (new_rtr_entry->next != NULL)
130 rtr_current->next=new_rtr_entry->next;
132 rtr_current->next=NULL;
134 spin_unlock_irqrestore(&hardware_p->rtr_lock, flags);
135 kfree(new_rtr_entry);
140 ssize_t can_read(struct file *file, char *buffer, size_t length, loff_t *offset)
142 struct canuser_t *canuser = (struct canuser_t*)(file->private_data);
143 struct msgobj_t *obj;
145 struct canmsg_t read_msg;
146 struct canque_ends_t *qends;
149 if(!canuser || (canuser->magic != CAN_USER_MAGIC)){
150 CANMSG("can_close: bad canuser magic\n");
154 if (length < sizeof(struct canmsg_t)) {
155 DEBUGMSG("Trying to read less bytes than a CAN message, \n");
156 DEBUGMSG("this will always return zero.\n");
159 if (length > 8 * sizeof(struct canmsg_t)) {
160 DEBUGMSG("Reading more than 8 CAN messages, this is not supported.\n");
161 DEBUGMSG("Defaulting to 8 messages.\n");
162 length = 8 * sizeof(struct canmsg_t);
164 /* Initialize hardware pointers */
165 obj = canuser->msgobj;
167 CANMSG("Could not assign buffer structure\n");
170 qends = canuser->qends;
171 if ( (chip = obj->hostchip) == NULL) {
172 CANMSG("Device is not correctly configured,\n");
173 CANMSG("please reload the driver.\n");
177 copy_from_user(&read_msg, buffer, sizeof(struct canmsg_t));
178 if (read_msg.flags & MSG_RTR)
179 ret = can_rtr_read(chip, obj, buffer);
181 ret = can_std_read(file, qends, obj, buffer, length);