]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/virtual.c
changed usb vendor and product id.
[lincan.git] / lincan / src / virtual.c
index 42c0f57c6c0ab551c7a60f9d57f64d9ba24ac822..f1ae39e120c015c40fcb6279133e1d8e8d94b4cc 100644 (file)
@@ -3,23 +3,33 @@
  * Written for new CAN driver version by Pavel Pisa - OCERA team member
  * email:pisa@cmp.felk.cvut.cz
  * This software is released under the GPL-License.
- * Version lincan-0.2  9 Jul 2003
+ * Version lincan-0.3  17 Jun 2004
  */ 
 
-#include <linux/autoconf.h>
-
-#include <linux/delay.h>
-#include <asm/errno.h>
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
 #include "../include/main.h"
 
+
+long virtual_bus_latency(struct msgobj_t *obj)
+{
+       long latency;
+       latency=obj->hostchip->baudrate;
+       if(latency){
+               latency=(long)HZ*1000/latency;
+       }
+       return latency;
+}
+
+
 /* * * Virtual Chip Functionality * * */
 
-int virtual_enable_configuration(struct chip_t *chip)
+int virtual_enable_configuration(struct canchip_t *chip)
 {
        return 0;
 }
 
-int virtual_disable_configuration(struct chip_t *chip)
+int virtual_disable_configuration(struct canchip_t *chip)
 {
        return 0;
 }
@@ -31,7 +41,7 @@ int virtual_disable_configuration(struct chip_t *chip)
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_chip_config(struct chip_t *chip)
+int virtual_chip_config(struct canchip_t *chip)
 {
        return 0;
 }
@@ -45,7 +55,7 @@ int virtual_chip_config(struct chip_t *chip)
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_extended_mask(struct chip_t *chip, unsigned long code, unsigned  long mask)
+int virtual_extended_mask(struct canchip_t *chip, unsigned long code, unsigned  long mask)
 {
        return 0;
 }
@@ -62,7 +72,7 @@ int virtual_extended_mask(struct chip_t *chip, unsigned long code, unsigned  lon
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_baud_rate(struct chip_t *chip, int rate, int clock, int sjw,
+int virtual_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
                                                        int sampl_pt, int flags)
 {
        return 0;
@@ -75,7 +85,7 @@ int virtual_baud_rate(struct chip_t *chip, int rate, int clock, int sjw,
  *
  * File: src/virtual.c
  */
-void virtual_read(struct chip_t *chip, struct msgobj_t *obj) {
+void virtual_read(struct canchip_t *chip, struct msgobj_t *obj) {
 
 }
 
@@ -88,7 +98,7 @@ void virtual_read(struct chip_t *chip, struct msgobj_t *obj) {
  *     Positive value indicates immediate reception of message.
  * File: src/virtual.c
  */
-int virtual_pre_read_config(struct chip_t *chip, struct msgobj_t *obj)
+int virtual_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
 {
        return 0;
 }
@@ -103,7 +113,7 @@ int virtual_pre_read_config(struct chip_t *chip, struct msgobj_t *obj)
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, 
+int virtual_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, 
                                                        struct canmsg_t *msg)
 {
        return 0;
@@ -120,7 +130,7 @@ int virtual_pre_write_config(struct chip_t *chip, struct msgobj_t *obj,
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_send_msg(struct chip_t *chip, struct msgobj_t *obj, 
+int virtual_send_msg(struct canchip_t *chip, struct msgobj_t *obj, 
                                                        struct canmsg_t *msg)
 {
        return 0;
@@ -135,7 +145,7 @@ int virtual_send_msg(struct chip_t *chip, struct msgobj_t *obj,
  *     Zero value indicates finishing of all issued transmission requests.
  * File: src/virtual.c
  */
-int virtual_check_tx_stat(struct chip_t *chip)
+int virtual_check_tx_stat(struct canchip_t *chip)
 {
        return 0;
 }
@@ -149,7 +159,7 @@ int virtual_check_tx_stat(struct chip_t *chip)
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_set_btregs(struct chip_t *chip, unsigned short btr0, 
+int virtual_set_btregs(struct canchip_t *chip, unsigned short btr0, 
                                                        unsigned short btr1)
 {
        return 0;
@@ -162,7 +172,7 @@ int virtual_set_btregs(struct chip_t *chip, unsigned short btr0,
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_start_chip(struct chip_t *chip)
+int virtual_start_chip(struct canchip_t *chip)
 {
        return 0;
 }
@@ -174,11 +184,35 @@ int virtual_start_chip(struct chip_t *chip)
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_stop_chip(struct chip_t *chip)
+int virtual_stop_chip(struct canchip_t *chip)
 {
        return 0;
 }
 
+/**
+ * virtual_attach_to_chip: - attaches to the chip, setups registers and state
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/virtual.c
+ */
+int virtual_attach_to_chip(struct canchip_t *chip)
+{
+       return 0;
+}
+
+/**
+ * virtual_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
+ * @chip: pointer to chip state structure
+ *
+ * Return Value: negative value reports error.
+ * File: src/virtual.c
+ */
+int virtual_release_chip(struct canchip_t *chip)
+{
+       virtual_stop_chip(chip);
+       return 0;
+}
 
 /**
  * virtual_remote_request: - configures message object and asks for RTR message
@@ -188,7 +222,7 @@ int virtual_stop_chip(struct chip_t *chip)
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_remote_request(struct chip_t *chip, struct msgobj_t *obj)
+int virtual_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
 {
        CANMSG("virtual_remote_request not implemented\n");
        return -ENOSYS;
@@ -203,7 +237,7 @@ int virtual_remote_request(struct chip_t *chip, struct msgobj_t *obj)
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_standard_mask(struct chip_t *chip, unsigned short code,
+int virtual_standard_mask(struct canchip_t *chip, unsigned short code,
                unsigned short mask)
 {
        CANMSG("virtual_standard_mask not implemented\n");
@@ -217,7 +251,7 @@ int virtual_standard_mask(struct chip_t *chip, unsigned short code,
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_clear_objects(struct chip_t *chip)
+int virtual_clear_objects(struct canchip_t *chip)
 {
        CANMSG("virtual_clear_objects not implemented\n");
        return -ENOSYS;
@@ -231,7 +265,7 @@ int virtual_clear_objects(struct chip_t *chip)
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_config_irqs(struct chip_t *chip, short irqs)
+int virtual_config_irqs(struct canchip_t *chip, short irqs)
 {
        CANMSG("virtual_config_irqs not implemented\n");
        return -ENOSYS;
@@ -248,7 +282,7 @@ int virtual_config_irqs(struct chip_t *chip, short irqs)
  * virtual_irq_write_handler() for transmit events.
  * File: src/virtual.c
  */
-void virtual_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj)
+void virtual_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
 {
 
 }
@@ -260,7 +294,7 @@ void virtual_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj)
  * @irq: interrupt vector number, this value is system specific
  * @dev_id: driver private pointer registered at time of request_irq() call.
  *     The CAN driver uses this pointer to store relationship of interrupt
- *     to chip state structure - @struct chip_t
+ *     to chip state structure - @struct canchip_t
  * @regs: system dependent value pointing to registers stored in exception frame
  * 
  * Interrupt handler is activated when state of CAN controller chip changes,
@@ -270,9 +304,59 @@ void virtual_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj)
  * message queues.
  * File: src/virtual.c
  */
-irqreturn_t virtual_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+int virtual_irq_handler(int irq, struct canchip_t *chip)
+{
+       return CANCHIP_IRQ_HANDLED;
+}
+
+
+void virtual_schedule_next(struct msgobj_t *obj)
 {
-       return IRQ_HANDLED;
+       int cmd;
+
+       can_preempt_disable();
+
+       can_msgobj_set_fl(obj,TX_REQUEST);
+       
+       while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+
+               can_msgobj_clear_fl(obj,TX_REQUEST);
+               
+               cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
+               if(cmd>=0) {
+                       mod_timer(&obj->tx_timeout,
+                               jiffies+virtual_bus_latency(obj));
+                       DEBUGMSG("virtual: scheduled delivery\n");
+
+               } else          
+                       can_msgobj_clear_fl(obj,TX_LOCK);
+               
+               if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
+               DEBUGMSG("TX looping in virtual_schedule_next\n");
+       }
+
+       can_preempt_enable();
+}
+
+
+void virtual_do_tx_timeout(unsigned long data)
+{
+       struct msgobj_t *obj=(struct msgobj_t *)data;
+       
+       if(obj->tx_slot) {
+               /* fill CAN message timestamp */
+               can_filltimestamp(&obj->tx_slot->msg.timestamp);
+
+               /* Deliver message to edges */
+               canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
+               /* Free transmitted slot */
+               canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
+               obj->tx_slot=NULL;
+               DEBUGMSG("virtual: delayed delivery\n");
+       }
+       can_msgobj_clear_fl(obj,TX_LOCK);
+
+       virtual_schedule_next(obj);
 }
 
 /**
@@ -280,25 +364,41 @@ irqreturn_t virtual_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
  * @chip: pointer to chip state structure
  * @obj: pointer to message object structure
  *
+ * Function is responsible for initiating message transmition.
+ * It is responsible for clearing of object TX_REQUEST flag
+ *
  * Return Value: negative value reports error.
  * File: src/virtual.c
  */
-int virtual_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj)
+int virtual_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
 {
-       /* set_bit(OBJ_TX_REQUEST,&obj->flags); */
+       /* can_msgobj_set_fl(obj,TX_REQUEST); */
        
        struct canque_edge_t *qedge;
        struct canque_slot_t *slot;
        int cmd;
-       
-       /* Ensure delivery of all ready slots */
-       
-       while((cmd=canque_test_outslot(obj->qends, &qedge, &slot)) >= 0){
-               if(cmd==0) {
-                       canque_filter_msg2edges(obj->qends, &slot->msg);
+
+       can_msgobj_clear_fl(obj,TX_REQUEST);
+
+    #ifndef CAN_WITH_RTL
+       if(!virtual_bus_latency(obj)) {
+    #endif /*CAN_WITH_RTL*/
+               /* Ensure delivery of all ready slots */
+               while((cmd=canque_test_outslot(obj->qends, &qedge, &slot)) >= 0){
+                       if(cmd==0) {
+                               /* fill CAN message timestamp */
+                               can_filltimestamp(&slot->msg.timestamp);
+                               
+                               canque_filter_msg2edges(obj->qends, &slot->msg);
+                               DEBUGMSG("virtual: direct delivery\n");
+                       }
+                       canque_free_outslot(obj->qends, qedge, slot);
                }
-               canque_free_outslot(obj->qends, qedge, slot);
+    #ifndef CAN_WITH_RTL
+       } else {
+               virtual_schedule_next(obj);
        }
+    #endif /*CAN_WITH_RTL*/
 
        return 0;
 }
@@ -356,7 +456,7 @@ int virtual_init_hw_data(struct candevice_t *candev)
        candev->nr_82527_chips=0;
        candev->nr_sja1000_chips=0;
        candev->nr_all_chips=1;
-       candev->flags |= PROGRAMMABLE_IRQ*0;
+       candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
 
        return 0;
 }
@@ -373,7 +473,7 @@ int virtual_init_hw_data(struct candevice_t *candev)
  */
 int virtual_init_chip_data(struct candevice_t *candev, int chipnr)
 {
-       struct chip_t *chip = candev->chip[chipnr];
+       struct canchip_t *chip = candev->chip[chipnr];
        chip->chip_type = CHIP_TYPE;
        chip->chip_base_addr = 0;
        chip->clock = 10000000;
@@ -397,10 +497,13 @@ int virtual_init_chip_data(struct candevice_t *candev, int chipnr)
        chip->chipspecops->remote_request=virtual_remote_request;
        chip->chipspecops->enable_configuration=virtual_enable_configuration;
        chip->chipspecops->disable_configuration=virtual_disable_configuration;
+       chip->chipspecops->attach_to_chip=virtual_attach_to_chip;
+       chip->chipspecops->release_chip=virtual_release_chip;
        chip->chipspecops->set_btregs=virtual_set_btregs;
        chip->chipspecops->start_chip=virtual_start_chip;
        chip->chipspecops->stop_chip=virtual_stop_chip;
        chip->chipspecops->irq_handler=NULL;
+       chip->chipspecops->irq_accept=NULL;
 
        return 0;
 }
@@ -413,10 +516,12 @@ int virtual_init_chip_data(struct candevice_t *candev, int chipnr)
  * Return Value: The function always returns zero
  * File: src/virtual.c
  */
-int virtual_init_obj_data(struct chip_t *chip, int objnr)
+int virtual_init_obj_data(struct canchip_t *chip, int objnr)
 {
-       chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
-       chip->msgobj[objnr]->flags=0;
+       struct msgobj_t *obj=chip->msgobj[objnr];
+       obj->obj_base_addr=chip->chip_base_addr;
+       obj->tx_timeout.function=virtual_do_tx_timeout;
+       obj->tx_timeout.data=(unsigned long)obj;
        return 0;
 }