]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/finish.c
Header-files cleanup and CAN queue edges and ends locking reimplemented.
[lincan.git] / lincan / src / finish.c
diff --git a/lincan/src/finish.c b/lincan/src/finish.c
new file mode 100644 (file)
index 0000000..a5cd8d1
--- /dev/null
@@ -0,0 +1,105 @@
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
+#include "../include/main.h"
+#include "../include/devcommon.h"
+#include "../include/finish.h"
+#include "../include/setup.h"
+
+
+
+void msgobj_done(struct msgobj_t *obj)
+{
+       if(obj->qends) {
+               if(canqueue_ends_done_chip(obj->qends) < 0)
+                       CANMSG("msgobj_done: problem with chip queue ends\n");
+       }
+
+       if((obj->hostchip) && (obj->object>0)) {
+               if(obj->hostchip->msgobj[obj->object-1] == obj)
+                       obj->hostchip->msgobj[obj->object-1]=NULL;
+               else
+                       CANMSG("msgobj_done: not registered in the chip_t\n");
+               obj->hostchip=NULL;
+       }
+       
+       if((obj->minor>=0)) {
+               if(objects_p[obj->minor] == obj)
+                       objects_p[obj->minor] = NULL;
+               else
+                       CANMSG("msgobj_done: not registered as minor\n");
+       }
+       
+       del_timer_sync(&obj->tx_timeout);
+
+       if(obj->qends) {
+               can_checked_free(obj->qends);
+       }
+       obj->qends=NULL;
+}
+
+
+void canchip_done(struct chip_t *chip)
+{
+
+       int i;
+       struct msgobj_t *obj;
+
+       if((chip->hostdevice) && (chip->chip_idx>=0)) {
+               if(chip->hostdevice->chip[chip->chip_idx] == chip)
+                       chip->hostdevice->chip[chip->chip_idx] = NULL;
+               else
+                       CANMSG("canchip_done: not registered in hostdevice\n");
+       }
+
+       if((chip->flags & CHIP_IRQ_SETUP) && (chip->chip_irq>=0)) {
+               free_irq(chip->chip_irq, chip);
+               chip->flags &= ~CHIP_IRQ_SETUP;
+       }
+               
+       can_synchronize_irq(chip->chip_irq);
+       
+       for(i=0; i<chip->max_objects; i++){
+               if((obj=chip->msgobj[i])==NULL)
+                       continue;
+               msgobj_done(obj);
+               can_checked_free(obj);
+       }
+       
+       can_checked_free(chip->chipspecops);
+       chip->chipspecops=NULL;
+
+}
+
+void candevice_done(struct candevice_t *candev)
+{
+       int i;
+       struct chip_t *chip;
+       
+       for(i=0; i<candev->nr_all_chips; i++){
+               if((chip=candev->chip[i])==NULL)
+                       continue;
+               canchip_done(chip);
+               can_checked_free(chip);
+       
+       }
+       if(candev->flags & CANDEV_IO_RESERVED) {
+               candev->hwspecops->release_io(candev);
+               candev->flags &= ~CANDEV_IO_RESERVED;
+       }
+       can_checked_free(candev->hwspecops);
+       candev->hwspecops=NULL;
+}
+
+void canhardware_done(struct canhardware_t *canhw)
+{
+       int i;
+       struct candevice_t *candev;
+       
+       for(i=0; i<canhw->nr_boards; i++){
+               if((candev=canhw->candevice[i])==NULL)
+                       continue;
+               candevice_done(candev);
+               can_checked_free(candev);
+       }
+
+}