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 #include <linux/autoconf.h>
12 #define __NO_VERSION__
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/delay.h>
18 #include <asm/uaccess.h>
20 #include "../include/main.h"
22 ssize_t can_write(struct file *file, const char *buffer, size_t length, loff_t *offset)
24 struct canuser_t *canuser = (struct canuser_t*)(file->private_data);
26 struct canmsg_t msg_buff;
27 struct canque_ends_t *qends;
28 struct canque_edge_t *qedge;
29 struct canque_slot_t *slot;
31 int bytes_to_copy = 0;
33 if(!canuser || (canuser->magic != CAN_USER_MAGIC)){
34 CANMSG("can_close: bad canuser magic\n");
38 if (length < sizeof(struct canmsg_t)) {
39 DEBUGMSG("Trying to write less bytes than a CAN message,\n");
40 DEBUGMSG("this will always return 0 !\n");
43 if (length > 8 * sizeof(struct canmsg_t)) {
44 CANMSG("Trying to write more than is supported.\n");
47 if (length % sizeof(struct canmsg_t)) {
48 CANMSG("The number of bytes requested to be written is not a multiple of\n");
49 CANMSG("'sizeof(struct canmsg_t)', currently this is not allowed.\n");
53 /* Initialize hardware pointers */
54 obj = canuser->msgobj;
56 CANMSG("Could not assign buffer structure\n");
59 qends = canuser->qends;
62 /* Prepare first message */
63 copy_from_user(&msg_buff, buffer, sizeof(struct canmsg_t));
65 /* If the output buffer is full, return immediately in case O_NONBLOCK
66 * has been specified or loop until space becomes available.
68 if ((ret=canque_get_inslot4id(qends, &qedge, &slot,
69 0, msg_buff.id, 0))<0){
70 DEBUGMSG("Buffer is full\n");
71 if (file->f_flags & O_NONBLOCK)
76 ret=canque_get_inslot4id_wait_kern(qends, &qedge, &slot,
79 if (signal_pending(current))
86 canque_put_inslot(qends, qedge, slot);
87 buffer += sizeof(struct canmsg_t);
88 bytes_to_copy = length-sizeof(struct canmsg_t);
91 * Try to send more messages
93 while (bytes_to_copy > 0) {
94 /* Prepare first message */
95 copy_from_user(&msg_buff, buffer, sizeof(struct canmsg_t));
97 if(canque_get_inslot4id(qends, &qedge, &slot,
98 0, msg_buff.id, 0) < 0) break;
100 canque_put_inslot(qends, qedge, slot);
101 buffer += sizeof(struct canmsg_t);
102 bytes_to_copy -= sizeof(struct canmsg_t);
105 if(file->f_flags & O_SYNC) {
106 canque_sync_wait_kern(qends, qedge);
108 return length-bytes_to_copy;