1 /**************************************************************************/
2 /* File: finish.c - finalization of the driver operations */
4 /* LinCAN - (Not only) Linux CAN bus driver */
5 /* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
6 /* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
7 /* Funded by OCERA and FRESCOR IST projects */
8 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
10 /* LinCAN is free software; you can redistribute it and/or modify it */
11 /* under terms of the GNU General Public License as published by the */
12 /* Free Software Foundation; either version 2, or (at your option) any */
13 /* later version. LinCAN is distributed in the hope that it will be */
14 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
15 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
16 /* General Public License for more details. You should have received a */
17 /* copy of the GNU General Public License along with LinCAN; see file */
18 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
19 /* Cambridge, MA 02139, USA. */
21 /* To allow use of LinCAN in the compact embedded systems firmware */
22 /* and RT-executives (RTEMS for example), main authors agree with next */
23 /* special exception: */
25 /* Including LinCAN header files in a file, instantiating LinCAN generics */
26 /* or templates, or linking other files with LinCAN objects to produce */
27 /* an application image/executable, does not by itself cause the */
28 /* resulting application image/executable to be covered by */
29 /* the GNU General Public License. */
30 /* This exception does not however invalidate any other reasons */
31 /* why the executable file might be covered by the GNU Public License. */
32 /* Publication of enhanced or derived LinCAN files is required although. */
33 /**************************************************************************/
35 #include "../include/can.h"
36 #include "../include/can_sysdep.h"
37 #include "../include/main.h"
38 #include "../include/devcommon.h"
39 #include "../include/finish.h"
40 #include "../include/setup.h"
44 * msgobj_done - destroys one CAN message object
45 * @obj: pointer to CAN message object structure
47 void msgobj_done(struct msgobj_t *obj)
51 delayed=canqueue_ends_done_chip(obj->qends);
53 CANMSG("msgobj_done: problem with chip queue ends\n");
56 if((obj->hostchip) && (obj->object>0)) {
57 if(obj->hostchip->msgobj[obj->object-1] == obj)
58 obj->hostchip->msgobj[obj->object-1]=NULL;
60 CANMSG("msgobj_done: not registered in the canchip_t\n");
65 if(objects_p[obj->minor] == obj)
66 objects_p[obj->minor] = NULL;
68 CANMSG("msgobj_done: not registered as minor\n");
71 del_timer_sync(&obj->tx_timeout);
74 /*delayed free could be required there in the future,
75 actual use patter cannot generate such situation*/
77 can_checked_free(obj->qends);
85 * canchip_done - destroys one CAN chip representation
86 * @chip: pointer to CAN chip structure
88 void canchip_done(struct canchip_t *chip)
94 if(chip->flags & CHIP_ATTACHED){
95 chip->chipspecops->release_chip(chip);
96 chip->flags &= ~CHIP_ATTACHED;
99 if((chip->hostdevice) && (chip->chip_idx>=0)) {
100 if(chip->hostdevice->chip[chip->chip_idx] == chip)
101 chip->hostdevice->chip[chip->chip_idx] = NULL;
103 CANMSG("canchip_done: not registered in hostdevice\n");
106 can_chip_free_irq(chip);
108 can_synchronize_irq(chip->chip_irq);
110 for(i=0; i<chip->max_objects; i++){
111 if((obj=chip->msgobj[i])==NULL)
114 can_checked_free(obj);
117 can_checked_free(chip->chipspecops);
118 chip->chipspecops=NULL;
123 * candevice_done - destroys representation of one CAN device/board
124 * @candev: pointer to CAN device/board structure
126 void candevice_done(struct candevice_t *candev)
129 struct canchip_t *chip;
131 for(i=0; i<candev->nr_all_chips; i++){
132 if((chip=candev->chip[i])==NULL)
135 can_checked_free(chip);
138 if(candev->flags & CANDEV_IO_RESERVED) {
139 candev->hwspecops->release_io(candev);
140 candev->flags &= ~CANDEV_IO_RESERVED;
142 can_checked_free(candev->hwspecops);
143 candev->hwspecops=NULL;
147 * candevice_done - destroys representation of all CAN devices/boards
148 * @canhw: pointer to the root of all CAN hardware representation
150 void canhardware_done(struct canhardware_t *canhw)
153 struct candevice_t *candev;
155 for(i=0; i<canhw->nr_boards; i++){
156 if((candev=canhw->candevice[i])==NULL)
158 candevice_done(candev);
159 can_checked_free(candev);