edge=list_entry(entry,struct canque_edge_t,inpeers);
if(canque_fifo_test_fl(&edge->fifo,BLOCK)||canque_fifo_test_fl(&edge->fifo,DEAD))
continue;
+ /* FIXME: the next comparison should be outside of ends lock */
if((msg->id^edge->filtid)&edge->filtmask)
continue;
atomic_inc(&edge->edge_used);
if(qedge == NULL) return NULL;
memset(qedge,0,sizeof(struct canque_edge_t));
+ spin_lock_init(&qedge->fifo.fifo_lock);
if(canque_fifo_init_slots(&qedge->fifo, slotsnr)<0){
kfree(qedge);
DEBUGQUE("canque_new_edge_kern failed\n");
{
int ret;
unsigned long flags;
- spin_lock_irqsave(&qedge->inends->ends_lock,flags);
- spin_lock(&qedge->outends->ends_lock);
+ struct canque_ends_t *inends, *outends;
+
+ inends=qedge->inends;
+ if(inends) spin_lock_irqsave(&inends->ends_lock,flags);
+ outends=qedge->outends;
+ if(outends) spin_lock(&outends->ends_lock);
spin_lock(&qedge->fifo.fifo_lock);
if(atomic_read(&qedge->edge_used)==0) {
if(qedge->outends){
ret=1;
} else ret=-1;
spin_unlock(&qedge->fifo.fifo_lock);
- spin_unlock(&qedge->outends->ends_lock);
- spin_unlock_irqrestore(&qedge->inends->ends_lock,flags);
+ if(outends) spin_unlock(&outends->ends_lock);
+ if(inends) spin_unlock_irqrestore(&inends->ends_lock,flags);
DEBUGQUE("canqueue_disconnect_edge %d returned %d\n",qedge->edge_num,ret);
return ret;
}
{
struct canque_edge_t *edge;
struct list_head *entry;
- unsigned long flags;
- spin_lock_irqsave(&qends->ends_lock, flags);
+ /* has to be called with qends->ends_lock already locked */
list_for_each(entry,&qends->inlist){
if(list == &qends->inlist)
edge=list_entry(list->next,struct canque_edge_t,inpeers);
else
edge=list_entry(list->next,struct canque_edge_t,outpeers);
canque_fifo_set_fl(&edge->fifo,BLOCK);
- /*spin_unlock_irqrestore(&qends->ends_lock, flags);*/
- /* Loop can be break by interrupts and preempts there */
- /*spin_lock_irqsave(&qends->ends_lock, flags);*/
}
- spin_unlock_irqrestore(&qends->ends_lock, flags);
}