fix SMP for pcbit

mark hysdn isdnloop and divert as BROKEN_ON_SMP
This commit is contained in:
Karsten Keil 2004-02-10 16:38:15 +00:00
parent fdb780adc6
commit 7349ecafdd
6 changed files with 23 additions and 36 deletions

View File

@ -3,7 +3,7 @@
#
config HYSDN
tristate "Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)"
depends on m && PROC_FS
depends on m && PROC_FS && BROKEN_ON_SMP
help
Say Y here if you have one of Hypercope's active PCI ISDN cards
Champ, Ergo and Metro. You will then get a module called hysdn.

View File

@ -78,6 +78,7 @@ menu "ISDN feature submodules"
config ISDN_DRV_LOOP
tristate "isdnloop support"
depends on BROKEN_ON_SMP
help
This driver provides a virtual ISDN card. Its primary purpose is
testing of linklevel features or configuration without getting
@ -87,7 +88,7 @@ config ISDN_DRV_LOOP
config ISDN_DIVERSION
tristate "Support isdn diversion services"
depends on BROKEN
depends on BROKEN && BROKEN_ON_SMP
help
This option allows you to use some supplementary diversion
services in conjunction with the HiSax driver on an EURO/DSS1

View File

@ -84,6 +84,7 @@ int pcbit_init_dev(int board, int mem_base, int irq)
dev_pcbit[board] = dev;
memset(dev, 0, sizeof(struct pcbit_dev));
init_waitqueue_head(&dev->set_running_wq);
spin_lock_init(&dev->lock);
if (mem_base >= 0xA0000 && mem_base <= 0xFFFFF ) {
dev->ph_mem = mem_base;

View File

@ -278,9 +278,7 @@ void pcbit_fsm_event(struct pcbit_dev *dev, struct pcbit_chan *chan,
struct fsm_timer_entry *tentry;
unsigned long flags;
save_flags(flags);
cli();
spin_lock_irqsave(&dev->lock, flags);
for (action = fsm_table; action->init != 0xff; action++)
if (action->init == chan->fsm_state && action->event == event)
@ -288,9 +286,9 @@ void pcbit_fsm_event(struct pcbit_dev *dev, struct pcbit_chan *chan,
if (action->init == 0xff) {
spin_unlock_irqrestore(&dev->lock, flags);
printk(KERN_DEBUG "fsm error: event %x on state %x\n",
event, chan->fsm_state);
restore_flags(flags);
return;
}
@ -315,7 +313,7 @@ void pcbit_fsm_event(struct pcbit_dev *dev, struct pcbit_chan *chan,
add_timer(&chan->fsm_timer);
}
restore_flags(flags);
spin_unlock_irqrestore(&dev->lock, flags);
if (action->callb)
action->callb(dev, chan, data);

View File

@ -121,18 +121,17 @@ pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
frame->next = NULL;
save_flags(flags);
cli();
spin_lock_irqsave(&dev->lock, flags);
if (dev->write_queue == NULL) {
dev->write_queue = frame;
restore_flags(flags);
spin_unlock_irqrestore(&dev->lock, flags);
pcbit_transmit(dev);
} else {
for (ptr = dev->write_queue; ptr->next; ptr = ptr->next);
ptr->next = frame;
restore_flags(flags);
spin_unlock_irqrestore(&dev->lock, flags);
}
return 0;
}
@ -174,15 +173,14 @@ pcbit_transmit(struct pcbit_dev *dev)
unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07;
save_flags(flags);
cli();
spin_lock_irqsave(&dev->lock, flags);
if (dev->free > 16 && dev->write_queue && unacked < 7) {
if (!dev->w_busy)
dev->w_busy = 1;
else {
restore_flags(flags);
spin_unlock_irqrestore(&dev->lock, flags);
return;
}
@ -190,7 +188,7 @@ pcbit_transmit(struct pcbit_dev *dev)
frame = dev->write_queue;
free = dev->free;
restore_flags(flags);
spin_unlock_irqrestore(&dev->lock, flags);
if (frame->copied == 0) {
@ -271,9 +269,7 @@ pcbit_transmit(struct pcbit_dev *dev)
dev->free -= flen;
pcbit_tx_update(dev, flen);
save_flags(flags);
cli();
spin_lock_irqsave(&dev->lock, flags);
if (frame->skb == NULL || frame->copied == frame->skb->len) {
@ -286,9 +282,9 @@ pcbit_transmit(struct pcbit_dev *dev)
kfree(frame);
}
dev->w_busy = 0;
restore_flags(flags);
spin_unlock_irqrestore(&dev->lock, flags);
} else {
restore_flags(flags);
spin_unlock_irqrestore(&dev->lock, flags);
#ifdef DEBUG
printk(KERN_DEBUG "unacked %d free %d write_queue %s\n",
unacked, dev->free, dev->write_queue ? "not empty" :
@ -309,12 +305,11 @@ pcbit_deliver(void *data)
unsigned long flags, msg;
struct pcbit_dev *dev = (struct pcbit_dev *) data;
save_flags(flags);
cli();
spin_lock_irqsave(&dev->lock, flags);
while ((frame = dev->read_queue)) {
dev->read_queue = frame->next;
restore_flags(flags);
spin_unlock_irqrestore(&dev->lock, flags);
SET_MSG_CPU(msg, 0);
SET_MSG_PROC(msg, 0);
@ -331,11 +326,10 @@ pcbit_deliver(void *data)
kfree(frame);
save_flags(flags);
cli();
spin_lock_irqsave(&dev->lock, flags);
}
restore_flags(flags);
spin_unlock_irqrestore(&dev->lock, flags);
}
/*
@ -460,12 +454,9 @@ pcbit_receive(struct pcbit_dev *dev)
memcpy_frompcbit(dev, skb_put(frame->skb, tt), tt);
frame->copied += tt;
spin_lock_irqsave(&dev->lock, flags);
if (frame->copied == frame->hdr_len + frame->dt_len) {
save_flags(flags);
cli();
if (type1) {
dev->read_frame = NULL;
}
@ -476,14 +467,10 @@ pcbit_receive(struct pcbit_dev *dev)
} else
dev->read_queue = frame;
restore_flags(flags);
} else {
save_flags(flags);
cli();
dev->read_frame = frame;
restore_flags(flags);
}
spin_unlock_irqrestore(&dev->lock, flags);
}
/*

View File

@ -51,7 +51,7 @@ struct pcbit_dev {
unsigned int id;
unsigned int interrupt; /* set during interrupt
processing */
spinlock_t lock;
/* isdn4linux */
struct msn_entry * msn_list; /* ISDN address list */