Commit aefad917 authored by François Romieu's avatar François Romieu Committed by Linus Torvalds

[PATCH] 2.4.8 - dscc4 update 4/13

- dscc4_xpr_ack() busy waiting loop is modified so as to allow long
  delay without chewing too much cycles;
- more errata sheet magic;
- dscc4_set_clock() now has only one return point.
parent 3f32c8a9
...@@ -528,16 +528,18 @@ static int dscc4_do_action(struct net_device *dev, char *msg) ...@@ -528,16 +528,18 @@ static int dscc4_do_action(struct net_device *dev, char *msg)
static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv) static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv)
{ {
int cur = dpriv->iqtx_current%IRQ_RING_SIZE; int cur = dpriv->iqtx_current%IRQ_RING_SIZE;
s16 i = 0; s8 i = 0;
do { do {
if (!(dpriv->flags & (NeedIDR | NeedIDT)) || if (!(dpriv->flags & (NeedIDR | NeedIDT)) ||
(dpriv->iqtx[cur] & Xpr)) (dpriv->iqtx[cur] & Xpr))
break; break;
smp_rmb(); smp_rmb();
} while (i++ >= 0); set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(10);
} while (++i > 0);
return i; return (i >= 0 ) ? i : -EAGAIN;
} }
static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv, int cur, static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv, int cur,
...@@ -620,8 +622,8 @@ static int __init dscc4_init_one (struct pci_dev *pdev, ...@@ -620,8 +622,8 @@ static int __init dscc4_init_one (struct pci_dev *pdev,
pci_resource_start(pdev, 0), pci_resource_start(pdev, 0),
pci_resource_start(pdev, 1), pdev->irq); pci_resource_start(pdev, 1), pdev->irq);
/* No need for High PCI latency. Cf app. note. */ /* Cf errata DS5 p.2 */
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x10); pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xf8);
pci_set_master(pdev); pci_set_master(pdev);
if (dscc4_found1(pdev, ioaddr)) if (dscc4_found1(pdev, ioaddr))
...@@ -865,6 +867,8 @@ static void dscc4_timer(unsigned long data) ...@@ -865,6 +867,8 @@ static void dscc4_timer(unsigned long data)
printk(KERN_DEBUG "%s: re-enabled\n", dev->name); printk(KERN_DEBUG "%s: re-enabled\n", dev->name);
} }
} }
goto done;
done:
dpriv->timer.expires = jiffies + TX_TIMEOUT; dpriv->timer.expires = jiffies + TX_TIMEOUT;
add_timer(&dpriv->timer); add_timer(&dpriv->timer);
} }
...@@ -920,10 +924,11 @@ static int dscc4_open(struct net_device *dev) ...@@ -920,10 +924,11 @@ static int dscc4_open(struct net_device *dev)
* power-down mode or..." and CCR2.RAC = 1 are two different * power-down mode or..." and CCR2.RAC = 1 are two different
* situations. * situations.
*/ */
if (readl(ioaddr + STAR) & SccBusy) { if (scc_readl_star(dpriv, dev) & SccBusy) {
printk(KERN_ERR "%s busy. Try later\n", dev->name); printk(KERN_ERR "%s busy. Try later\n", dev->name);
goto err_free_ring; goto err_free_ring;
} } else
printk(KERN_INFO "%s: available. Good\n", dev->name);
/* Posted write is flushed in the busy-waiting loop */ /* Posted write is flushed in the busy-waiting loop */
scc_writel(TxSccRes | RxSccRes, dpriv, dev, CMDR); scc_writel(TxSccRes | RxSccRes, dpriv, dev, CMDR);
...@@ -1056,6 +1061,7 @@ static inline int dscc4_check_clock_ability(int port) ...@@ -1056,6 +1061,7 @@ static inline int dscc4_check_clock_ability(int port)
static int dscc4_set_clock(struct net_device *dev, u32 *bps, u32 *state) static int dscc4_set_clock(struct net_device *dev, u32 *bps, u32 *state)
{ {
struct dscc4_dev_priv *dpriv = dscc4_priv(dev); struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
int ret = -1;
u32 brr; u32 brr;
*state &= ~Ccr0ClockMask; *state &= ~Ccr0ClockMask;
...@@ -1065,9 +1071,9 @@ static int dscc4_set_clock(struct net_device *dev, u32 *bps, u32 *state) ...@@ -1065,9 +1071,9 @@ static int dscc4_set_clock(struct net_device *dev, u32 *bps, u32 *state)
xtal = dpriv->pci_priv->xtal_hz; xtal = dpriv->pci_priv->xtal_hz;
if (!xtal) if (!xtal)
return -1; goto done;
if (dscc4_check_clock_ability(dpriv->dev_id) < 0) if (dscc4_check_clock_ability(dpriv->dev_id) < 0)
return -1; goto done;
divider = xtal / *bps; divider = xtal / *bps;
if (divider > BRR_DIVIDER_MAX) { if (divider > BRR_DIVIDER_MAX) {
divider >>= 4; divider >>= 4;
...@@ -1100,8 +1106,9 @@ static int dscc4_set_clock(struct net_device *dev, u32 *bps, u32 *state) ...@@ -1100,8 +1106,9 @@ static int dscc4_set_clock(struct net_device *dev, u32 *bps, u32 *state)
brr = 0; brr = 0;
} }
scc_writel(brr, dpriv, dev, BRR); scc_writel(brr, dpriv, dev, BRR);
ret = 0;
return 0; done:
return ret;
} }
static int dscc4_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int dscc4_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
......
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