Commit 638abf2b authored by Martin Diehl's avatar Martin Diehl Committed by Stephen Hemminger

[IRDA]: vlsi_ir v0.5 update, 5/7.

* cleanup baud rate setting and mode switch
* locking and barrier review
parent 968d9bd9
...@@ -875,21 +875,16 @@ static int vlsi_process_tx(struct vlsi_ring *r, struct ring_descr *rd) ...@@ -875,21 +875,16 @@ static int vlsi_process_tx(struct vlsi_ring *r, struct ring_descr *rd)
return (ret) ? -ret : len; return (ret) ? -ret : len;
} }
static int vlsi_set_baud(struct net_device *ndev, int dolock) static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase)
{ {
vlsi_irda_dev_t *idev = ndev->priv;
unsigned long flags;
u16 nphyctl; u16 nphyctl;
unsigned iobase;
u16 config; u16 config;
unsigned mode; unsigned mode;
unsigned idle_retry;
int ret; int ret;
int baudrate; int baudrate;
int fifocnt = 0; /* Keep compiler happy */ int fifocnt;
baudrate = idev->new_baud; baudrate = idev->new_baud;
iobase = ndev->base_addr;
IRDA_DEBUG(2, "%s: %d -> %d\n", __FUNCTION__, idev->baud, idev->new_baud); IRDA_DEBUG(2, "%s: %d -> %d\n", __FUNCTION__, idev->baud, idev->new_baud);
if (baudrate == 4000000) { if (baudrate == 4000000) {
mode = IFF_FIR; mode = IFF_FIR;
...@@ -920,37 +915,15 @@ static int vlsi_set_baud(struct net_device *ndev, int dolock) ...@@ -920,37 +915,15 @@ static int vlsi_set_baud(struct net_device *ndev, int dolock)
break; break;
} }
} }
config |= IRCFG_MSTR | IRCFG_ENRX;
if (dolock) fifocnt = inw(iobase+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK;
spin_lock_irqsave(&idev->lock, flags); if (fifocnt != 0) {
else
flags = 0xdead; /* prevent bogus warning about possible uninitialized use */
for (idle_retry=0; idle_retry < 100; idle_retry++) {
fifocnt = inw(ndev->base_addr+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK;
if (fifocnt == 0)
break;
if (!idle_retry)
IRDA_DEBUG(0, "%s: waiting for rx fifo to become empty(%d)\n",
__FUNCTION__, fifocnt);
if (dolock) {
spin_unlock_irqrestore(&idev->lock, flags);
udelay(100);
spin_lock_irqsave(&idev->lock, flags);
}
else
udelay(100);
}
if (fifocnt != 0)
IRDA_DEBUG(0, "%s: rx fifo not empty(%d)\n", __FUNCTION__, fifocnt); IRDA_DEBUG(0, "%s: rx fifo not empty(%d)\n", __FUNCTION__, fifocnt);
}
outw(0, iobase+VLSI_PIO_IRENABLE); outw(0, iobase+VLSI_PIO_IRENABLE);
wmb();
config |= IRCFG_MSTR | IRCFG_ENRX;
outw(config, iobase+VLSI_PIO_IRCFG); outw(config, iobase+VLSI_PIO_IRCFG);
outw(nphyctl, iobase+VLSI_PIO_NPHYCTL); outw(nphyctl, iobase+VLSI_PIO_NPHYCTL);
wmb(); wmb();
outw(IRENABLE_IREN, iobase+VLSI_PIO_IRENABLE); outw(IRENABLE_IREN, iobase+VLSI_PIO_IRENABLE);
...@@ -987,8 +960,6 @@ static int vlsi_set_baud(struct net_device *ndev, int dolock) ...@@ -987,8 +960,6 @@ static int vlsi_set_baud(struct net_device *ndev, int dolock)
ret = 0; ret = 0;
} }
} }
if (dolock)
spin_unlock_irqrestore(&idev->lock, flags);
if (ret) if (ret)
vlsi_reg_debug(iobase,__FUNCTION__); vlsi_reg_debug(iobase,__FUNCTION__);
...@@ -998,12 +969,14 @@ static int vlsi_set_baud(struct net_device *ndev, int dolock) ...@@ -998,12 +969,14 @@ static int vlsi_set_baud(struct net_device *ndev, int dolock)
static inline int vlsi_set_baud_lock(struct net_device *ndev) static inline int vlsi_set_baud_lock(struct net_device *ndev)
{ {
return vlsi_set_baud(ndev, 1); vlsi_irda_dev_t *idev = ndev->priv;
} unsigned long flags;
int ret;
static inline int vlsi_set_baud_nolock(struct net_device *ndev) spin_lock_irqsave(&idev->lock, flags);
{ ret = vlsi_set_baud(idev, ndev->base_addr);
return vlsi_set_baud(ndev, 0); spin_unlock_irqrestore(&idev->lock, flags);
return ret;
} }
static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
...@@ -1047,7 +1020,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -1047,7 +1020,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
spin_lock_irqsave(&idev->lock, flags); spin_lock_irqsave(&idev->lock, flags);
if (ring_first(idev->tx_ring) == NULL) { if (ring_first(idev->tx_ring) == NULL) {
/* no race - tx-ring already empty */ /* no race - tx-ring already empty */
vlsi_set_baud_nolock(ndev); vlsi_set_baud(idev, iobase);
netif_wake_queue(ndev); netif_wake_queue(ndev);
} }
else else
...@@ -1441,7 +1414,7 @@ static int vlsi_init_chip(struct pci_dev *pdev) ...@@ -1441,7 +1414,7 @@ static int vlsi_init_chip(struct pci_dev *pdev)
atomic_set(&idev->tx_ring->head, RINGPTR_GET_TX(ptr)); atomic_set(&idev->tx_ring->head, RINGPTR_GET_TX(ptr));
atomic_set(&idev->tx_ring->tail, RINGPTR_GET_TX(ptr)); atomic_set(&idev->tx_ring->tail, RINGPTR_GET_TX(ptr));
vlsi_set_baud_lock(ndev); /* idev->new_baud used as provided by caller */ vlsi_set_baud(idev, iobase); /* idev->new_baud used as provided by caller */
outb(IRINTR_INT_MASK, iobase+VLSI_PIO_IRINTR); /* just in case - w/c pending IRQ's */ outb(IRINTR_INT_MASK, iobase+VLSI_PIO_IRINTR); /* just in case - w/c pending IRQ's */
wmb(); wmb();
...@@ -1498,10 +1471,11 @@ static int vlsi_stop_hw(vlsi_irda_dev_t *idev) ...@@ -1498,10 +1471,11 @@ static int vlsi_stop_hw(vlsi_irda_dev_t *idev)
spin_lock_irqsave(&idev->lock,flags); spin_lock_irqsave(&idev->lock,flags);
outw(0, iobase+VLSI_PIO_IRENABLE); outw(0, iobase+VLSI_PIO_IRENABLE);
outw(0, iobase+VLSI_PIO_IRCFG); /* disable everything */ outw(0, iobase+VLSI_PIO_IRCFG); /* disable everything */
wmb();
outb(IRINTR_INT_MASK, iobase+VLSI_PIO_IRINTR); /* w/c pending + disable further IRQ */ /* disable and w/c irqs */
mb(); outb(0, iobase+VLSI_PIO_IRINTR);
wmb();
outb(IRINTR_INT_MASK, iobase+VLSI_PIO_IRINTR);
spin_unlock_irqrestore(&idev->lock,flags); spin_unlock_irqrestore(&idev->lock,flags);
vlsi_unarm_tx(idev); vlsi_unarm_tx(idev);
...@@ -1569,7 +1543,7 @@ static int vlsi_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) ...@@ -1569,7 +1543,7 @@ static int vlsi_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
* if the stack tries to change speed concurrently - which would be * if the stack tries to change speed concurrently - which would be
* pretty strange anyway with the userland having full control... * pretty strange anyway with the userland having full control...
*/ */
vlsi_set_baud_nolock(ndev); vlsi_set_baud(idev, ndev->base_addr);
spin_unlock_irqrestore(&idev->lock, flags); spin_unlock_irqrestore(&idev->lock, flags);
break; break;
case SIOCSMEDIABUSY: case SIOCSMEDIABUSY:
......
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