+ 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);