Commit 9e3083c1 authored by Chas Williams's avatar Chas Williams Committed by David S. Miller

[ATM]: Convert cli() to spinlock in ZATM driver.

parent ba79a0ce
...@@ -27,6 +27,7 @@ struct uPD98402_priv { ...@@ -27,6 +27,7 @@ struct uPD98402_priv {
struct k_sonet_stats sonet_stats;/* link diagnostics */ struct k_sonet_stats sonet_stats;/* link diagnostics */
unsigned char framing; /* SONET/SDH framing */ unsigned char framing; /* SONET/SDH framing */
int loop_mode; /* loopback mode */ int loop_mode; /* loopback mode */
spinlock_t lock;
}; };
...@@ -71,14 +72,13 @@ static int set_framing(struct atm_dev *dev,unsigned char framing) ...@@ -71,14 +72,13 @@ static int set_framing(struct atm_dev *dev,unsigned char framing)
default: default:
return -EINVAL; return -EINVAL;
} }
save_flags(flags); spin_lock_irqsave(&PRIV(dev)->lock, flags);
cli();
PUT(set[0],C11T); PUT(set[0],C11T);
PUT(set[1],C12T); PUT(set[1],C12T);
PUT(set[2],C13T); PUT(set[2],C13T);
PUT((GET(MDR) & ~uPD98402_MDR_SS_MASK) | (set[3] << PUT((GET(MDR) & ~uPD98402_MDR_SS_MASK) | (set[3] <<
uPD98402_MDR_SS_SHIFT),MDR); uPD98402_MDR_SS_SHIFT),MDR);
restore_flags(flags); spin_unlock_irqrestore(&PRIV(dev)->lock, flags);
return 0; return 0;
} }
...@@ -88,12 +88,11 @@ static int get_sense(struct atm_dev *dev,u8 *arg) ...@@ -88,12 +88,11 @@ static int get_sense(struct atm_dev *dev,u8 *arg)
unsigned long flags; unsigned long flags;
unsigned char s[3]; unsigned char s[3];
save_flags(flags); spin_lock_irqsave(&PRIV(dev)->lock, flags);
cli();
s[0] = GET(C11R); s[0] = GET(C11R);
s[1] = GET(C12R); s[1] = GET(C12R);
s[2] = GET(C13R); s[2] = GET(C13R);
restore_flags(flags); spin_unlock_irqrestore(&PRIV(dev)->lock, flags);
return (put_user(s[0], arg) || put_user(s[1], arg+1) || return (put_user(s[0], arg) || put_user(s[1], arg+1) ||
put_user(s[2], arg+2) || put_user(0xff, arg+3) || put_user(s[2], arg+2) || put_user(0xff, arg+3) ||
put_user(0xff, arg+4) || put_user(0xff, arg+5)) ? -EFAULT : 0; put_user(0xff, arg+4) || put_user(0xff, arg+5)) ? -EFAULT : 0;
...@@ -214,6 +213,7 @@ static int uPD98402_start(struct atm_dev *dev) ...@@ -214,6 +213,7 @@ static int uPD98402_start(struct atm_dev *dev)
DPRINTK("phy_start\n"); DPRINTK("phy_start\n");
if (!(PRIV(dev) = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL))) if (!(PRIV(dev) = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
spin_lock_init(&PRIV(dev)->lock);
memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats)); memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats));
(void) GET(PCR); /* clear performance events */ (void) GET(PCR); /* clear performance events */
PUT(uPD98402_PFM_FJ,PCMR); /* ignore frequency adj */ PUT(uPD98402_PFM_FJ,PCMR); /* ignore frequency adj */
......
...@@ -195,11 +195,10 @@ static void refill_pool(struct atm_dev *dev,int pool) ...@@ -195,11 +195,10 @@ static void refill_pool(struct atm_dev *dev,int pool)
sizeof(struct rx_buffer_head); sizeof(struct rx_buffer_head);
} }
size += align; size += align;
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
free = zpeekl(zatm_dev,zatm_dev->pool_base+2*pool) & free = zpeekl(zatm_dev,zatm_dev->pool_base+2*pool) &
uPD98401_RXFP_REMAIN; uPD98401_RXFP_REMAIN;
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
if (free >= zatm_dev->pool_info[pool].low_water) return; if (free >= zatm_dev->pool_info[pool].low_water) return;
EVENT("starting ... POOL: 0x%x, 0x%x\n", EVENT("starting ... POOL: 0x%x, 0x%x\n",
zpeekl(zatm_dev,zatm_dev->pool_base+2*pool), zpeekl(zatm_dev,zatm_dev->pool_base+2*pool),
...@@ -228,22 +227,22 @@ static void refill_pool(struct atm_dev *dev,int pool) ...@@ -228,22 +227,22 @@ static void refill_pool(struct atm_dev *dev,int pool)
head->skb = skb; head->skb = skb;
EVENT("enq skb 0x%08lx/0x%08lx\n",(unsigned long) skb, EVENT("enq skb 0x%08lx/0x%08lx\n",(unsigned long) skb,
(unsigned long) head); (unsigned long) head);
cli(); spin_lock_irqsave(&zatm_dev->lock, flags);
if (zatm_dev->last_free[pool]) if (zatm_dev->last_free[pool])
((struct rx_buffer_head *) (zatm_dev->last_free[pool]-> ((struct rx_buffer_head *) (zatm_dev->last_free[pool]->
data))[-1].link = virt_to_bus(head); data))[-1].link = virt_to_bus(head);
zatm_dev->last_free[pool] = skb; zatm_dev->last_free[pool] = skb;
skb_queue_tail(&zatm_dev->pool[pool],skb); skb_queue_tail(&zatm_dev->pool[pool],skb);
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
free++; free++;
} }
if (first) { if (first) {
cli(); spin_lock_irqsave(&zatm_dev->lock, flags);
zwait; zwait;
zout(virt_to_bus(first),CER); zout(virt_to_bus(first),CER);
zout(uPD98401_ADD_BAT | (pool << uPD98401_POOL_SHIFT) | count, zout(uPD98401_ADD_BAT | (pool << uPD98401_POOL_SHIFT) | count,
CMR); CMR);
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
EVENT ("POOL: 0x%x, 0x%x\n", EVENT ("POOL: 0x%x, 0x%x\n",
zpeekl(zatm_dev,zatm_dev->pool_base+2*pool), zpeekl(zatm_dev,zatm_dev->pool_base+2*pool),
zpeekl(zatm_dev,zatm_dev->pool_base+2*pool+1)); zpeekl(zatm_dev,zatm_dev->pool_base+2*pool+1));
...@@ -286,8 +285,7 @@ static void use_pool(struct atm_dev *dev,int pool) ...@@ -286,8 +285,7 @@ static void use_pool(struct atm_dev *dev,int pool)
size = pool-ZATM_AAL5_POOL_BASE; size = pool-ZATM_AAL5_POOL_BASE;
if (size < 0) size = 0; /* 64B... */ if (size < 0) size = 0; /* 64B... */
else if (size > 10) size = 10; /* ... 64kB */ else if (size > 10) size = 10; /* ... 64kB */
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
zpokel(zatm_dev,((zatm_dev->pool_info[pool].low_water/4) << zpokel(zatm_dev,((zatm_dev->pool_info[pool].low_water/4) <<
uPD98401_RXFP_ALERT_SHIFT) | uPD98401_RXFP_ALERT_SHIFT) |
(1 << uPD98401_RXFP_BTSZ_SHIFT) | (1 << uPD98401_RXFP_BTSZ_SHIFT) |
...@@ -295,7 +293,7 @@ static void use_pool(struct atm_dev *dev,int pool) ...@@ -295,7 +293,7 @@ static void use_pool(struct atm_dev *dev,int pool)
zatm_dev->pool_base+pool*2); zatm_dev->pool_base+pool*2);
zpokel(zatm_dev,(unsigned long) dummy,zatm_dev->pool_base+ zpokel(zatm_dev,(unsigned long) dummy,zatm_dev->pool_base+
pool*2+1); pool*2+1);
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
zatm_dev->last_free[pool] = NULL; zatm_dev->last_free[pool] = NULL;
refill_pool(dev,pool); refill_pool(dev,pool);
} }
...@@ -315,29 +313,29 @@ static void zatm_feedback(struct atm_vcc *vcc,struct sk_buff *skb, ...@@ -315,29 +313,29 @@ static void zatm_feedback(struct atm_vcc *vcc,struct sk_buff *skb,
{ {
struct zatm_pool_info *pool; struct zatm_pool_info *pool;
unsigned long offset,flags; unsigned long offset,flags;
struct zatm_dev *zatm_dev = ZATM_DEV(vcc->dev);
DPRINTK("start 0x%08lx dest 0x%08lx len %d\n",start,dest,len); DPRINTK("start 0x%08lx dest 0x%08lx len %d\n",start,dest,len);
if (len < PAGE_SIZE) return; if (len < PAGE_SIZE) return;
pool = &ZATM_DEV(vcc->dev)->pool_info[ZATM_VCC(vcc)->pool]; pool = &zatm_dev->pool_info[ZATM_VCC(vcc)->pool];
offset = (dest-start) & (PAGE_SIZE-1); offset = (dest-start) & (PAGE_SIZE-1);
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
if (!offset || pool->offset == offset) { if (!offset || pool->offset == offset) {
pool->next_cnt = 0; pool->next_cnt = 0;
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
return; return;
} }
if (offset != pool->next_off) { if (offset != pool->next_off) {
pool->next_off = offset; pool->next_off = offset;
pool->next_cnt = 0; pool->next_cnt = 0;
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
return; return;
} }
if (++pool->next_cnt >= pool->next_thres) { if (++pool->next_cnt >= pool->next_thres) {
pool->offset = pool->next_off; pool->offset = pool->next_off;
pool->next_cnt = 0; pool->next_cnt = 0;
} }
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
} }
/*----------------------------------- RX ------------------------------------*/ /*----------------------------------- RX ------------------------------------*/
...@@ -535,20 +533,19 @@ static int open_rx_first(struct atm_vcc *vcc) ...@@ -535,20 +533,19 @@ static int open_rx_first(struct atm_vcc *vcc)
zatm_vcc->pool = ZATM_AAL0_POOL; zatm_vcc->pool = ZATM_AAL0_POOL;
} }
if (zatm_vcc->pool < 0) return -EMSGSIZE; if (zatm_vcc->pool < 0) return -EMSGSIZE;
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
zwait; zwait;
zout(uPD98401_OPEN_CHAN,CMR); zout(uPD98401_OPEN_CHAN,CMR);
zwait; zwait;
DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER)); DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER));
chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT; chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT;
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
DPRINTK("chan is %d\n",chan); DPRINTK("chan is %d\n",chan);
if (!chan) return -EAGAIN; if (!chan) return -EAGAIN;
use_pool(vcc->dev,zatm_vcc->pool); use_pool(vcc->dev,zatm_vcc->pool);
DPRINTK("pool %d\n",zatm_vcc->pool); DPRINTK("pool %d\n",zatm_vcc->pool);
/* set up VC descriptor */ /* set up VC descriptor */
cli(); spin_lock_irqsave(&zatm_dev->lock, flags);
zpokel(zatm_dev,zatm_vcc->pool << uPD98401_RXVC_POOL_SHIFT, zpokel(zatm_dev,zatm_vcc->pool << uPD98401_RXVC_POOL_SHIFT,
chan*VC_SIZE/4); chan*VC_SIZE/4);
zpokel(zatm_dev,uPD98401_RXVC_OD | (vcc->qos.aal == ATM_AAL5 ? zpokel(zatm_dev,uPD98401_RXVC_OD | (vcc->qos.aal == ATM_AAL5 ?
...@@ -556,7 +553,7 @@ static int open_rx_first(struct atm_vcc *vcc) ...@@ -556,7 +553,7 @@ static int open_rx_first(struct atm_vcc *vcc)
zpokel(zatm_dev,0,chan*VC_SIZE/4+2); zpokel(zatm_dev,0,chan*VC_SIZE/4+2);
zatm_vcc->rx_chan = chan; zatm_vcc->rx_chan = chan;
zatm_dev->rx_map[chan] = vcc; zatm_dev->rx_map[chan] = vcc;
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
return 0; return 0;
} }
...@@ -572,14 +569,13 @@ static int open_rx_second(struct atm_vcc *vcc) ...@@ -572,14 +569,13 @@ static int open_rx_second(struct atm_vcc *vcc)
zatm_dev = ZATM_DEV(vcc->dev); zatm_dev = ZATM_DEV(vcc->dev);
zatm_vcc = ZATM_VCC(vcc); zatm_vcc = ZATM_VCC(vcc);
if (!zatm_vcc->rx_chan) return 0; if (!zatm_vcc->rx_chan) return 0;
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
/* should also handle VPI @@@ */ /* should also handle VPI @@@ */
pos = vcc->vci >> 1; pos = vcc->vci >> 1;
shift = (1-(vcc->vci & 1)) << 4; shift = (1-(vcc->vci & 1)) << 4;
zpokel(zatm_dev,(zpeekl(zatm_dev,pos) & ~(0xffff << shift)) | zpokel(zatm_dev,(zpeekl(zatm_dev,pos) & ~(0xffff << shift)) |
((zatm_vcc->rx_chan | uPD98401_RXLT_ENBL) << shift),pos); ((zatm_vcc->rx_chan | uPD98401_RXLT_ENBL) << shift),pos);
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
return 0; return 0;
} }
...@@ -596,9 +592,8 @@ static void close_rx(struct atm_vcc *vcc) ...@@ -596,9 +592,8 @@ static void close_rx(struct atm_vcc *vcc)
if (!zatm_vcc->rx_chan) return; if (!zatm_vcc->rx_chan) return;
DPRINTK("close_rx\n"); DPRINTK("close_rx\n");
/* disable receiver */ /* disable receiver */
save_flags(flags);
if (vcc->vpi != ATM_VPI_UNSPEC && vcc->vci != ATM_VCI_UNSPEC) { if (vcc->vpi != ATM_VPI_UNSPEC && vcc->vci != ATM_VCI_UNSPEC) {
cli(); spin_lock_irqsave(&zatm_dev->lock, flags);
pos = vcc->vci >> 1; pos = vcc->vci >> 1;
shift = (1-(vcc->vci & 1)) << 4; shift = (1-(vcc->vci & 1)) << 4;
zpokel(zatm_dev,zpeekl(zatm_dev,pos) & ~(0xffff << shift),pos); zpokel(zatm_dev,zpeekl(zatm_dev,pos) & ~(0xffff << shift),pos);
...@@ -606,9 +601,9 @@ static void close_rx(struct atm_vcc *vcc) ...@@ -606,9 +601,9 @@ static void close_rx(struct atm_vcc *vcc)
zout(uPD98401_NOP,CMR); zout(uPD98401_NOP,CMR);
zwait; zwait;
zout(uPD98401_NOP,CMR); zout(uPD98401_NOP,CMR);
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
} }
cli(); spin_lock_irqsave(&zatm_dev->lock, flags);
zwait; zwait;
zout(uPD98401_DEACT_CHAN | uPD98401_CHAN_RT | (zatm_vcc->rx_chan << zout(uPD98401_DEACT_CHAN | uPD98401_CHAN_RT | (zatm_vcc->rx_chan <<
uPD98401_CHAN_ADDR_SHIFT),CMR); uPD98401_CHAN_ADDR_SHIFT),CMR);
...@@ -620,7 +615,7 @@ static void close_rx(struct atm_vcc *vcc) ...@@ -620,7 +615,7 @@ static void close_rx(struct atm_vcc *vcc)
if (!(zin(CMR) & uPD98401_CHAN_ADDR)) if (!(zin(CMR) & uPD98401_CHAN_ADDR))
printk(KERN_CRIT DEV_LABEL "(itf %d): can't close RX channel " printk(KERN_CRIT DEV_LABEL "(itf %d): can't close RX channel "
"%d\n",vcc->dev->number,zatm_vcc->rx_chan); "%d\n",vcc->dev->number,zatm_vcc->rx_chan);
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
zatm_dev->rx_map[zatm_vcc->rx_chan] = NULL; zatm_dev->rx_map[zatm_vcc->rx_chan] = NULL;
zatm_vcc->rx_chan = 0; zatm_vcc->rx_chan = 0;
unuse_pool(vcc->dev,zatm_vcc->pool); unuse_pool(vcc->dev,zatm_vcc->pool);
...@@ -673,11 +668,10 @@ static int do_tx(struct sk_buff *skb) ...@@ -673,11 +668,10 @@ static int do_tx(struct sk_buff *skb)
zatm_dev = ZATM_DEV(vcc->dev); zatm_dev = ZATM_DEV(vcc->dev);
zatm_vcc = ZATM_VCC(vcc); zatm_vcc = ZATM_VCC(vcc);
EVENT("iovcnt=%d\n",skb_shinfo(skb)->nr_frags,0); EVENT("iovcnt=%d\n",skb_shinfo(skb)->nr_frags,0);
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
if (!skb_shinfo(skb)->nr_frags) { if (!skb_shinfo(skb)->nr_frags) {
if (zatm_vcc->txing == RING_ENTRIES-1) { if (zatm_vcc->txing == RING_ENTRIES-1) {
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
return RING_BUSY; return RING_BUSY;
} }
zatm_vcc->txing++; zatm_vcc->txing++;
...@@ -732,7 +726,7 @@ printk("NONONONOO!!!!\n"); ...@@ -732,7 +726,7 @@ printk("NONONONOO!!!!\n");
zwait; zwait;
zout(uPD98401_TX_READY | (zatm_vcc->tx_chan << zout(uPD98401_TX_READY | (zatm_vcc->tx_chan <<
uPD98401_CHAN_ADDR_SHIFT),CMR); uPD98401_CHAN_ADDR_SHIFT),CMR);
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
EVENT("done\n",0,0); EVENT("done\n",0,0);
return 0; return 0;
} }
...@@ -866,15 +860,14 @@ static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr) ...@@ -866,15 +860,14 @@ static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr)
if (zatm_dev->tx_bw < *pcr) return -EAGAIN; if (zatm_dev->tx_bw < *pcr) return -EAGAIN;
zatm_dev->tx_bw -= *pcr; zatm_dev->tx_bw -= *pcr;
} }
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
DPRINTK("i = %d, m = %d, PCR = %d\n",i,m,*pcr); DPRINTK("i = %d, m = %d, PCR = %d\n",i,m,*pcr);
zpokel(zatm_dev,(i << uPD98401_IM_I_SHIFT) | m,uPD98401_IM(shaper)); zpokel(zatm_dev,(i << uPD98401_IM_I_SHIFT) | m,uPD98401_IM(shaper));
zpokel(zatm_dev,c << uPD98401_PC_C_SHIFT,uPD98401_PC(shaper)); zpokel(zatm_dev,c << uPD98401_PC_C_SHIFT,uPD98401_PC(shaper));
zpokel(zatm_dev,0,uPD98401_X(shaper)); zpokel(zatm_dev,0,uPD98401_X(shaper));
zpokel(zatm_dev,0,uPD98401_Y(shaper)); zpokel(zatm_dev,0,uPD98401_Y(shaper));
zpokel(zatm_dev,uPD98401_PS_E,uPD98401_PS(shaper)); zpokel(zatm_dev,uPD98401_PS_E,uPD98401_PS(shaper));
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
return shaper; return shaper;
} }
...@@ -889,11 +882,10 @@ static void dealloc_shaper(struct atm_dev *dev,int shaper) ...@@ -889,11 +882,10 @@ static void dealloc_shaper(struct atm_dev *dev,int shaper)
if (--zatm_dev->ubr_ref_cnt) return; if (--zatm_dev->ubr_ref_cnt) return;
zatm_dev->ubr = -1; zatm_dev->ubr = -1;
} }
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
zpokel(zatm_dev,zpeekl(zatm_dev,uPD98401_PS(shaper)) & ~uPD98401_PS_E, zpokel(zatm_dev,zpeekl(zatm_dev,uPD98401_PS(shaper)) & ~uPD98401_PS_E,
uPD98401_PS(shaper)); uPD98401_PS(shaper));
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
zatm_dev->free_shapers |= 1 << shaper; zatm_dev->free_shapers |= 1 << shaper;
} }
...@@ -912,8 +904,6 @@ int once = 1; ...@@ -912,8 +904,6 @@ int once = 1;
chan = zatm_vcc->tx_chan; chan = zatm_vcc->tx_chan;
if (!chan) return; if (!chan) return;
DPRINTK("close_tx\n"); DPRINTK("close_tx\n");
save_flags(flags);
cli();
while (skb_peek(&zatm_vcc->backlog)) { while (skb_peek(&zatm_vcc->backlog)) {
if (once) { if (once) {
printk("waiting for backlog to drain ...\n"); printk("waiting for backlog to drain ...\n");
...@@ -932,6 +922,7 @@ once = 0; ...@@ -932,6 +922,7 @@ once = 0;
DPRINTK("waiting for TX queue to drain ... %p\n",skb); DPRINTK("waiting for TX queue to drain ... %p\n",skb);
sleep_on(&zatm_vcc->tx_wait); sleep_on(&zatm_vcc->tx_wait);
} }
spin_lock_irqsave(&zatm_dev->lock, flags);
#if 0 #if 0
zwait; zwait;
zout(uPD98401_DEACT_CHAN | (chan << uPD98401_CHAN_ADDR_SHIFT),CMR); zout(uPD98401_DEACT_CHAN | (chan << uPD98401_CHAN_ADDR_SHIFT),CMR);
...@@ -942,7 +933,7 @@ once = 0; ...@@ -942,7 +933,7 @@ once = 0;
if (!(zin(CMR) & uPD98401_CHAN_ADDR)) if (!(zin(CMR) & uPD98401_CHAN_ADDR))
printk(KERN_CRIT DEV_LABEL "(itf %d): can't close TX channel " printk(KERN_CRIT DEV_LABEL "(itf %d): can't close TX channel "
"%d\n",vcc->dev->number,chan); "%d\n",vcc->dev->number,chan);
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
zatm_vcc->tx_chan = 0; zatm_vcc->tx_chan = 0;
zatm_dev->tx_map[chan] = NULL; zatm_dev->tx_map[chan] = NULL;
if (zatm_vcc->shaper != zatm_dev->ubr) { if (zatm_vcc->shaper != zatm_dev->ubr) {
...@@ -967,14 +958,13 @@ static int open_tx_first(struct atm_vcc *vcc) ...@@ -967,14 +958,13 @@ static int open_tx_first(struct atm_vcc *vcc)
zatm_vcc = ZATM_VCC(vcc); zatm_vcc = ZATM_VCC(vcc);
zatm_vcc->tx_chan = 0; zatm_vcc->tx_chan = 0;
if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0; if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
zwait; zwait;
zout(uPD98401_OPEN_CHAN,CMR); zout(uPD98401_OPEN_CHAN,CMR);
zwait; zwait;
DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER)); DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER));
chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT; chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT;
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
DPRINTK("chan is %d\n",chan); DPRINTK("chan is %d\n",chan);
if (!chan) return -EAGAIN; if (!chan) return -EAGAIN;
unlimited = vcc->qos.txtp.traffic_class == ATM_UBR && unlimited = vcc->qos.txtp.traffic_class == ATM_UBR &&
...@@ -1022,15 +1012,14 @@ static int open_tx_second(struct atm_vcc *vcc) ...@@ -1022,15 +1012,14 @@ static int open_tx_second(struct atm_vcc *vcc)
zatm_dev = ZATM_DEV(vcc->dev); zatm_dev = ZATM_DEV(vcc->dev);
zatm_vcc = ZATM_VCC(vcc); zatm_vcc = ZATM_VCC(vcc);
if (!zatm_vcc->tx_chan) return 0; if (!zatm_vcc->tx_chan) return 0;
save_flags(flags);
/* set up VC descriptor */ /* set up VC descriptor */
cli(); spin_lock_irqsave(&zatm_dev->lock, flags);
zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4); zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4);
zpokel(zatm_dev,uPD98401_TXVC_L | (zatm_vcc->shaper << zpokel(zatm_dev,uPD98401_TXVC_L | (zatm_vcc->shaper <<
uPD98401_TXVC_SHP_SHIFT) | (vcc->vpi << uPD98401_TXVC_VPI_SHIFT) | uPD98401_TXVC_SHP_SHIFT) | (vcc->vpi << uPD98401_TXVC_VPI_SHIFT) |
vcc->vci,zatm_vcc->tx_chan*VC_SIZE/4+1); vcc->vci,zatm_vcc->tx_chan*VC_SIZE/4+1);
zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4+2); zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4+2);
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
zatm_dev->tx_map[zatm_vcc->tx_chan] = vcc; zatm_dev->tx_map[zatm_vcc->tx_chan] = vcc;
return 0; return 0;
} }
...@@ -1236,6 +1225,7 @@ static int __init zatm_init(struct atm_dev *dev) ...@@ -1236,6 +1225,7 @@ static int __init zatm_init(struct atm_dev *dev)
DPRINTK(">zatm_init\n"); DPRINTK(">zatm_init\n");
zatm_dev = ZATM_DEV(dev); zatm_dev = ZATM_DEV(dev);
spin_lock_init(&zatm_dev->lock);
pci_dev = zatm_dev->pci_dev; pci_dev = zatm_dev->pci_dev;
zatm_dev->base = pci_resource_start(pci_dev, 0); zatm_dev->base = pci_resource_start(pci_dev, 0);
zatm_dev->irq = pci_dev->irq; zatm_dev->irq = pci_dev->irq;
...@@ -1285,14 +1275,13 @@ static int __init zatm_init(struct atm_dev *dev) ...@@ -1285,14 +1275,13 @@ static int __init zatm_init(struct atm_dev *dev)
do { do {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
t0 = zpeekl(zatm_dev,uPD98401_TSR); t0 = zpeekl(zatm_dev,uPD98401_TSR);
udelay(10); udelay(10);
t1 = zpeekl(zatm_dev,uPD98401_TSR); t1 = zpeekl(zatm_dev,uPD98401_TSR);
udelay(1010); udelay(1010);
t2 = zpeekl(zatm_dev,uPD98401_TSR); t2 = zpeekl(zatm_dev,uPD98401_TSR);
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
} }
while (t0 > t1 || t1 > t2); /* loop if wrapping ... */ while (t0 > t1 || t1 > t2); /* loop if wrapping ... */
zatm_dev->khz = t2-2*t1+t0; zatm_dev->khz = t2-2*t1+t0;
...@@ -1492,14 +1481,13 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) ...@@ -1492,14 +1481,13 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
return -EFAULT; return -EFAULT;
if (pool < 0 || pool > ZATM_LAST_POOL) if (pool < 0 || pool > ZATM_LAST_POOL)
return -EINVAL; return -EINVAL;
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
info = zatm_dev->pool_info[pool]; info = zatm_dev->pool_info[pool];
if (cmd == ZATM_GETPOOLZ) { if (cmd == ZATM_GETPOOLZ) {
zatm_dev->pool_info[pool].rqa_count = 0; zatm_dev->pool_info[pool].rqa_count = 0;
zatm_dev->pool_info[pool].rqu_count = 0; zatm_dev->pool_info[pool].rqu_count = 0;
} }
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
return copy_to_user( return copy_to_user(
&((struct zatm_pool_req *) arg)->info, &((struct zatm_pool_req *) arg)->info,
&info,sizeof(info)) ? -EFAULT : 0; &info,sizeof(info)) ? -EFAULT : 0;
...@@ -1530,15 +1518,14 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) ...@@ -1530,15 +1518,14 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
if (info.low_water >= info.high_water || if (info.low_water >= info.high_water ||
info.low_water < 0) info.low_water < 0)
return -EINVAL; return -EINVAL;
save_flags(flags); spin_lock_irqsave(&zatm_dev->lock, flags);
cli();
zatm_dev->pool_info[pool].low_water = zatm_dev->pool_info[pool].low_water =
info.low_water; info.low_water;
zatm_dev->pool_info[pool].high_water = zatm_dev->pool_info[pool].high_water =
info.high_water; info.high_water;
zatm_dev->pool_info[pool].next_thres = zatm_dev->pool_info[pool].next_thres =
info.next_thres; info.next_thres;
restore_flags(flags); spin_unlock_irqrestore(&zatm_dev->lock, flags);
return 0; return 0;
} }
default: default:
......
...@@ -85,6 +85,7 @@ struct zatm_dev { ...@@ -85,6 +85,7 @@ struct zatm_dev {
unsigned char irq; /* IRQ */ unsigned char irq; /* IRQ */
unsigned int base; /* IO base address */ unsigned int base; /* IO base address */
struct pci_dev *pci_dev; /* PCI stuff */ struct pci_dev *pci_dev; /* PCI stuff */
spinlock_t lock;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment