From 7349ecafddaa8b3f2953917ba1c833d2004c33bb Mon Sep 17 00:00:00 2001 From: Karsten Keil Date: Tue, 10 Feb 2004 16:38:15 +0000 Subject: [PATCH] fix SMP for pcbit mark hysdn isdnloop and divert as BROKEN_ON_SMP --- drivers/isdn/hysdn/Kconfig | 2 +- drivers/isdn/i4l/Kconfig | 3 ++- drivers/isdn/pcbit/drv.c | 1 + drivers/isdn/pcbit/edss1.c | 8 +++---- drivers/isdn/pcbit/layer2.c | 43 +++++++++++++------------------------ drivers/isdn/pcbit/pcbit.h | 2 +- 6 files changed, 23 insertions(+), 36 deletions(-) diff --git a/drivers/isdn/hysdn/Kconfig b/drivers/isdn/hysdn/Kconfig index 1ad00bbf..1d82f3b4 100644 --- a/drivers/isdn/hysdn/Kconfig +++ b/drivers/isdn/hysdn/Kconfig @@ -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. diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig index 2b473765..028f099b 100644 --- a/drivers/isdn/i4l/Kconfig +++ b/drivers/isdn/i4l/Kconfig @@ -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 diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c index 84418df3..c3f43a56 100644 --- a/drivers/isdn/pcbit/drv.c +++ b/drivers/isdn/pcbit/drv.c @@ -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; diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c index 396f7b50..93ca7de5 100644 --- a/drivers/isdn/pcbit/edss1.c +++ b/drivers/isdn/pcbit/edss1.c @@ -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); diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c index a21ab4c9..ba766930 100644 --- a/drivers/isdn/pcbit/layer2.c +++ b/drivers/isdn/pcbit/layer2.c @@ -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); } /* diff --git a/drivers/isdn/pcbit/pcbit.h b/drivers/isdn/pcbit/pcbit.h index b9c02c7d..d1e3df02 100644 --- a/drivers/isdn/pcbit/pcbit.h +++ b/drivers/isdn/pcbit/pcbit.h @@ -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 */