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
12 #include "../include/can.h"
13 #include "../include/can_sysdep.h"
14 #include "../include/main.h"
16 #include <rtl_posixio.h>
17 #include "../include/can_iortl.h"
19 ssize_t can_write_rtl_posix(struct rtl_file *fptr, const char *buffer,
20 size_t length, loff_t *ppos)
22 struct canuser_t *canuser =
23 (struct canuser_t *)can_get_rtl_file_private_data(fptr);
24 const struct canmsg_t *msg_buff = (struct canmsg_t *)buffer;
25 struct canque_ends_t *qends;
26 struct canque_edge_t *qedge;
27 struct canque_slot_t *slot;
32 if(!canuser || (canuser->magic != CAN_USER_MAGIC)){
33 CANMSG("can_write_rtl_posix: bad canuser magic\n");
37 if (length < sizeof(struct canmsg_t)) {
38 DEBUGMSG("Trying to write less bytes than a CAN message,\n");
39 DEBUGMSG("this will always return 0 !\n");
42 if (length > INT_MAX) {
43 CANMSG("Trying to write more than is supported.\n");
47 qends = canuser->qends;
49 msg_flags=msg_buff->flags;
51 /* Automatic selection of extended format if ID>2047 */
52 if (msg_buff->id & ~0x7ffl & MSG_ID_MASK ) msg_flags |= MSG_EXT;
53 /* has been dependent on "extended" option */
55 /* If the output buffer is full, return immediately in case O_NONBLOCK
56 * has been specified or loop until space becomes available.
58 if ((ret=canque_get_inslot4id(qends, &qedge, &slot,
59 0, msg_buff->id, 0))<0){
60 DEBUGMSG("Buffer is full\n");
64 if (fptr->f_flags & O_NONBLOCK)
67 ret=canque_get_inslot4id_wait_rtl(qends, &qedge, &slot,
76 slot->msg=*(msg_buff++);
77 slot->msg.flags=msg_flags;
78 canque_put_inslot(qends, qedge, slot);
79 bytes_to_copy = length-sizeof(struct canmsg_t);
82 * Try to send more messages
84 while (bytes_to_copy >= sizeof(struct canmsg_t)) {
85 bytes_to_copy -= sizeof(struct canmsg_t);
86 msg_flags=msg_buff->flags;
88 /* Automatic selection of extended format if ID>2047 */
89 if (msg_buff->id & ~0x7ffl & MSG_ID_MASK ) msg_flags |= MSG_EXT;
90 /* has been dependent on "extended" option */
93 if(canque_get_inslot4id(qends, &qedge, &slot,
94 0, msg_buff->id, 0) < 0) break;
95 slot->msg=*(msg_buff++);
96 slot->msg.flags=msg_flags;
97 canque_put_inslot(qends, qedge, slot);
100 if(fptr->f_flags & O_SYNC) {
101 canque_sync_wait_rtl(qends, qedge);
103 return length-bytes_to_copy;
106 #endif /*CAN_WITH_RTL*/