]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/finish.c
Merge branch 'master' into can-usb1
[lincan.git] / lincan / src / finish.c
1 /* finish.c - finalization of the driver operation
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/devcommon.h"
14 #include "../include/finish.h"
15 #include "../include/setup.h"
16
17 extern int next_minor;
18 /**
19  * msgobj_done - destroys one CAN message object
20  * @obj: pointer to CAN message object structure
21  */
22 void msgobj_done(struct msgobj_t *obj)
23 {
24         int delayed=0;
25         if(obj->qends) {
26                 delayed=canqueue_ends_done_chip(obj->qends);
27                 if(delayed < 0)
28                         CANMSG("msgobj_done: problem with chip queue ends\n");
29         }
30
31         if((obj->hostchip) && (obj->object>0)) {
32                 if(obj->hostchip->msgobj[obj->object-1] == obj)
33                         obj->hostchip->msgobj[obj->object-1]=NULL;
34                 else
35                         CANMSG("msgobj_done: not registered in the canchip_t\n");
36                 obj->hostchip=NULL;
37         }
38
39         if((obj->minor>=0)) {
40                 if(objects_p[obj->minor] == obj){
41                         objects_p[obj->minor] = NULL;
42                         if (--next_minor<0)
43                                 next_minor=0;
44                 }
45                 else
46                         CANMSG("msgobj_done: not registered as minor\n");
47         }
48
49         del_timer_sync(&obj->tx_timeout);
50
51         if(obj->qends) {
52                 /*delayed free could be required there in the future,
53                   actual use patter cannot generate such situation*/
54                 if(!delayed) {
55                         can_checked_free(obj->qends);
56                 }
57         }
58         obj->qends=NULL;
59 }
60
61
62 /**
63  * canchip_done - destroys one CAN chip representation
64  * @chip: pointer to CAN chip structure
65  */
66 void canchip_done(struct canchip_t *chip)
67 {
68
69         int i;
70         struct msgobj_t *obj;
71
72         if(chip->flags & CHIP_ATTACHED){
73                 chip->chipspecops->release_chip(chip);
74                 chip->flags &= ~CHIP_ATTACHED;
75         }
76
77         if((chip->hostdevice) && (chip->chip_idx>=0)) {
78                 if(chip->hostdevice->chip[chip->chip_idx] == chip)
79                         chip->hostdevice->chip[chip->chip_idx] = NULL;
80                 else
81                         CANMSG("canchip_done: not registered in hostdevice\n");
82         }
83
84         can_chip_free_irq(chip);
85
86         can_synchronize_irq(chip->chip_irq);
87
88         for(i=0; i<chip->max_objects; i++){
89                 if((obj=chip->msgobj[i])==NULL)
90                         continue;
91                 msgobj_done(obj);
92                 can_checked_free(obj);
93         }
94
95         can_checked_free(chip->chipspecops);
96         chip->chipspecops=NULL;
97
98 }
99
100 /**
101  * candevice_done - destroys representation of one CAN device/board
102  * @candev: pointer to CAN device/board structure
103  */
104 void candevice_done(struct candevice_t *candev)
105 {
106         int i;
107         struct canchip_t *chip;
108
109         for(i=0; i<candev->nr_all_chips; i++){
110                 if((chip=candev->chip[i])==NULL)
111                         continue;
112                 canchip_done(chip);
113                 can_checked_free(chip);
114
115         }
116         if(candev->flags & CANDEV_IO_RESERVED) {
117                 candev->hwspecops->release_io(candev);
118                 candev->flags &= ~CANDEV_IO_RESERVED;
119         }
120         can_checked_free(candev->hwspecops);
121         candev->hwspecops=NULL;
122 }
123
124 /**
125  * candevice_done - destroys representation of all CAN devices/boards
126  * @canhw: pointer to the root of all CAN hardware representation
127  */
128 void canhardware_done(struct canhardware_t *canhw)
129 {
130         int i;
131         struct candevice_t *candev;
132
133         for(i=0; i<MAX_HW_CARDS; i++){
134                 if((candev=canhw->candevice[i])==NULL)
135                         continue;
136                 candevice_done(candev);
137                 can_checked_free(candev);
138         }
139
140 }