]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/ioctl.c
changed usb vendor and product id.
[lincan.git] / lincan / src / ioctl.c
1 /* ioctl.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/ioctl.h"
14
15 int can_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
16 {
17         int i=0;
18         unsigned short channel=0;
19         unsigned btr0=0, btr1=0;
20         struct canuser_t *canuser = (struct canuser_t*)(file->private_data);
21         struct msgobj_t *obj;
22         struct canchip_t *chip;
23         struct canque_ends_t *qends;
24         
25         if(!canuser || (canuser->magic != CAN_USER_MAGIC)){
26                 CANMSG("can_ioctl: bad canuser magic\n");
27                 return -ENODEV;
28         }
29         
30         obj = canuser->msgobj;
31         if (obj == NULL) {
32                 CANMSG("Could not assign buffer structure\n");
33                 return -1;
34         }
35
36         qends = canuser->qends;
37         chip = obj->hostchip;
38         if (chip == NULL) {
39                 CANMSG("Device is not correctly configured.\n");
40                 CANMSG("Please reload the driver.\n");
41                 return -1;
42         }
43
44         switch (cmd) {
45                 case CAN_DRV_QUERY: {
46                         return can_ioctl_query(canuser, arg);
47                 }
48                 case STAT: {
49                         for (i=0x0; i<0x100; i++)
50                                 CANMSG("0x%x is 0x%x\n",i,can_read_reg(chip,i));
51                         break;
52                 }
53                 case CMD_START: {
54                         if (chip->chipspecops->start_chip(chip))
55                                 return -1;
56                         break;
57                 }
58                 case CMD_STOP: {
59                         if (chip->chipspecops->stop_chip(chip))
60                                 return -1;
61                         break;
62                 }
63                 case CANQUE_FLUSH: {
64                         canque_flush(canuser->rx_edge0);
65                         break;
66                 }
67                 case CONF_FILTER: {
68
69                         /* In- and output buffer re-initialization */
70                         
71                         if(canuser->rx_edge0){
72                                 canque_set_filt(canuser->rx_edge0, arg, ~0, 0);
73                         }
74
75                         break;
76                 }
77                 
78                 case CANQUE_FILTER: {
79                         struct canfilt_t canfilt;
80                         int ret;
81                         ret = copy_from_user(&canfilt, (void*)arg, sizeof(struct canfilt_t));
82                         if(ret) return -EFAULT;
83                         if(canuser->rx_edge0){
84                                 canque_set_filt(canuser->rx_edge0, canfilt.id, canfilt.mask, canfilt.flags);
85                         }
86                         break;
87                 }
88                 
89                 case CANRTR_READ: {
90                         int ret;
91                         struct canmsg_t rtr_msg;
92                         
93                         ret = copy_from_user(&rtr_msg, (void*)arg, sizeof(struct canmsg_t));
94                         if(ret) return -EFAULT;
95                         ret = can_ioctl_remote_read(canuser, &rtr_msg, rtr_msg.id, 0);
96                         if(ret<0) return ret;
97                         ret = copy_to_user((void*)arg, &rtr_msg, sizeof(struct canmsg_t));
98                         if(ret) return -EFAULT;
99                         break;
100                 }
101
102                 case CONF_BAUD: {
103                         channel = arg & 0xff;
104                         btr0 = (arg >> 8) & 0xff;
105                         btr1 = (arg >> 16) & 0xff;
106
107                         if (chip->chipspecops->set_btregs(chip, btr0, btr1)) {
108                                 CANMSG("Error setting bit timing registers\n");
109                                 return -1;
110                         }
111                         break;
112                 }
113                 
114                 case CONF_BAUDPARAMS: {
115                         struct can_baudparams_t params;
116                         int ret;
117                         
118                         ret = copy_from_user(&params, (void*)arg, sizeof(struct can_baudparams_t));
119                         if(ret) return -EFAULT;
120
121                         if(params.flags == -1) params.flags = 0;
122                         if(params.baudrate == -1) params.baudrate = chip->baudrate;
123                         if(params.sjw == -1) params.sjw = 0;
124                         if(params.sample_pt == -1) params.sample_pt = 75;
125                         i=chip->chipspecops->baud_rate(chip, params.baudrate, chip->clock, params.sjw,
126                                                         params.sample_pt, params.flags);
127                         if(i>=0) chip->baudrate = params.baudrate;
128                         else {
129                                 CANMSG("Error setting baud parameters\n");
130                                 return -1;
131                         }
132                         break;
133                 }
134
135
136                 default: {
137                         CANMSG("Not a valid ioctl command\n");
138                         return -EINVAL;
139                 }
140                 
141         }
142
143         return 0;
144 }