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

[PATCH] 2.4.8 - dscc4 update 7/13

- dscc4_do_action() now looks like the others event waiting loops (may be
  called from interrupt context however);
- dscc4_start_xmit(): cosmetic before LxDA changes + mb() parano;
- dscc4_clock_setting(): only one return point, thanks;
- dscc4_priv() invocation removed from dscc4_xxx_settings;
- minor cleanups.
parent 757ea6b3
...@@ -520,26 +520,28 @@ static int dscc4_wait_ack_cec(struct dscc4_dev_priv *dpriv, ...@@ -520,26 +520,28 @@ static int dscc4_wait_ack_cec(struct dscc4_dev_priv *dpriv,
static int dscc4_do_action(struct net_device *dev, char *msg) static int dscc4_do_action(struct net_device *dev, char *msg)
{ {
unsigned long ioaddr = dev->base_addr; unsigned long ioaddr = dev->base_addr;
u32 state; s16 i = 0;
s16 i;
writel(Action, ioaddr + GCMDR); writel(Action, ioaddr + GCMDR);
ioaddr += GSTAR; ioaddr += GSTAR;
for (i = 0; i >= 0; i++) { do {
state = readl(ioaddr); u32 state = readl(ioaddr);
if (state & Arf) {
if (state & ArAck) {
printk(KERN_DEBUG "%s: %s ack\n", dev->name, msg);
writel(ArAck, ioaddr);
goto done;
} else if (state & Arf) {
printk(KERN_ERR "%s: %s failed\n", dev->name, msg); printk(KERN_ERR "%s: %s failed\n", dev->name, msg);
writel(Arf, ioaddr); writel(Arf, ioaddr);
return -1; i = -1;
} else if (state & ArAck) { goto done;
printk(KERN_DEBUG "%s: %s ack (%d try)\n",
dev->name, msg, i);
writel(ArAck, ioaddr);
return 0;
}
} }
rmb();
} while (++i > 0);
printk(KERN_ERR "%s: %s timeout\n", dev->name, msg); printk(KERN_ERR "%s: %s timeout\n", dev->name, msg);
return -1; done:
return i;
} }
static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv) static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv)
...@@ -1000,11 +1002,10 @@ static int dscc4_tx_poll(struct dscc4_dev_priv *dpriv, struct net_device *dev) ...@@ -1000,11 +1002,10 @@ static int dscc4_tx_poll(struct dscc4_dev_priv *dpriv, struct net_device *dev)
static int dscc4_start_xmit(struct sk_buff *skb, struct net_device *dev) static int dscc4_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
struct dscc4_dev_priv *dpriv = dscc4_priv(dev); struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
struct dscc4_pci_priv *ppriv; struct dscc4_pci_priv *ppriv = dpriv->pci_priv;
struct TxFD *tx_fd; struct TxFD *tx_fd;
int cur, next; int cur, next;
ppriv = dpriv->pci_priv;
cur = dpriv->tx_current++%TX_RING_SIZE; cur = dpriv->tx_current++%TX_RING_SIZE;
next = dpriv->tx_current%TX_RING_SIZE; next = dpriv->tx_current%TX_RING_SIZE;
dpriv->tx_skbuff[next] = skb; dpriv->tx_skbuff[next] = skb;
...@@ -1013,7 +1014,8 @@ static int dscc4_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1013,7 +1014,8 @@ static int dscc4_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_fd->data = pci_map_single(ppriv->pdev, skb->data, skb->len, tx_fd->data = pci_map_single(ppriv->pdev, skb->data, skb->len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
tx_fd->complete = 0x00000000; tx_fd->complete = 0x00000000;
mb(); // FIXME: suppress ? tx_fd->jiffies = jiffies;
mb();
#ifdef DSCC4_POLLING #ifdef DSCC4_POLLING
spin_lock(&dpriv->lock); spin_lock(&dpriv->lock);
...@@ -1196,21 +1198,22 @@ static int dscc4_match(struct thingie *p, int value) ...@@ -1196,21 +1198,22 @@ static int dscc4_match(struct thingie *p, int value)
return i; return i;
} }
static int dscc4_clock_setting(struct net_device *dev) static int dscc4_clock_setting(struct dscc4_dev_priv *dpriv,
struct net_device *dev)
{ {
struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
sync_serial_settings *settings = &dpriv->settings; sync_serial_settings *settings = &dpriv->settings;
int ret = -EOPNOTSUPP;
u32 bps, state; u32 bps, state;
bps = settings->clock_rate; bps = settings->clock_rate;
state = scc_readl(dpriv, CCR0); state = scc_readl(dpriv, CCR0);
if (dscc4_set_clock(dev, &bps, &state) < 0) if (dscc4_set_clock(dev, &bps, &state) < 0)
return -EOPNOTSUPP; goto done;
if (bps) { /* DCE */ if (bps) { /* DCE */
printk(KERN_DEBUG "%s: generated RxClk (DCE)\n", dev->name); printk(KERN_DEBUG "%s: generated RxClk (DCE)\n", dev->name);
if (settings->clock_rate != bps) { if (settings->clock_rate != bps) {
settings->clock_rate = bps; settings->clock_rate = bps;
printk(KERN_DEBUG "%s: clock adjusted from %08d to %08d \n", printk(KERN_DEBUG "%s: clock adjusted (%08d -> %08d)\n",
dev->name, dpriv->settings.clock_rate, bps); dev->name, dpriv->settings.clock_rate, bps);
} }
} else { /* DTE */ } else { /* DTE */
...@@ -1218,12 +1221,14 @@ static int dscc4_clock_setting(struct net_device *dev) ...@@ -1218,12 +1221,14 @@ static int dscc4_clock_setting(struct net_device *dev)
printk(KERN_DEBUG "%s: external RxClk (DTE)\n", dev->name); printk(KERN_DEBUG "%s: external RxClk (DTE)\n", dev->name);
} }
scc_writel(state, dpriv, dev, CCR0); scc_writel(state, dpriv, dev, CCR0);
return 0; ret = 0;
done:
return ret;
} }
static int dscc4_encoding_setting(struct net_device *dev) static int dscc4_encoding_setting(struct dscc4_dev_priv *dpriv,
struct net_device *dev)
{ {
struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
struct thingie encoding[] = { struct thingie encoding[] = {
{ ENCODING_NRZ, 0x00000000 }, { ENCODING_NRZ, 0x00000000 },
{ ENCODING_NRZI, 0x00200000 }, { ENCODING_NRZI, 0x00200000 },
...@@ -1242,9 +1247,9 @@ static int dscc4_encoding_setting(struct net_device *dev) ...@@ -1242,9 +1247,9 @@ static int dscc4_encoding_setting(struct net_device *dev)
return ret; return ret;
} }
static int dscc4_loopback_setting(struct net_device *dev) static int dscc4_loopback_setting(struct dscc4_dev_priv *dpriv,
struct net_device *dev)
{ {
struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
sync_serial_settings *settings = &dpriv->settings; sync_serial_settings *settings = &dpriv->settings;
u32 state; u32 state;
...@@ -1260,9 +1265,9 @@ static int dscc4_loopback_setting(struct net_device *dev) ...@@ -1260,9 +1265,9 @@ static int dscc4_loopback_setting(struct net_device *dev)
return 0; return 0;
} }
static int dscc4_crc_setting(struct net_device *dev) static int dscc4_crc_setting(struct dscc4_dev_priv *dpriv,
struct net_device *dev)
{ {
struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
struct thingie crc[] = { struct thingie crc[] = {
{ PARITY_CRC16_PR0_CCITT, 0x00000010 }, { PARITY_CRC16_PR0_CCITT, 0x00000010 },
{ PARITY_CRC16_PR1_CCITT, 0x00000000 }, { PARITY_CRC16_PR1_CCITT, 0x00000000 },
...@@ -1282,7 +1287,7 @@ static int dscc4_crc_setting(struct net_device *dev) ...@@ -1282,7 +1287,7 @@ static int dscc4_crc_setting(struct net_device *dev)
static int dscc4_set_iface(struct dscc4_dev_priv *dpriv, struct net_device *dev) static int dscc4_set_iface(struct dscc4_dev_priv *dpriv, struct net_device *dev)
{ {
struct { struct {
int (*action)(struct net_device *); int (*action)(struct dscc4_dev_priv *, struct net_device *);
} *p, do_setting[] = { } *p, do_setting[] = {
{ dscc4_encoding_setting }, { dscc4_encoding_setting },
{ dscc4_clock_setting }, { dscc4_clock_setting },
...@@ -1293,7 +1298,7 @@ static int dscc4_set_iface(struct dscc4_dev_priv *dpriv, struct net_device *dev) ...@@ -1293,7 +1298,7 @@ static int dscc4_set_iface(struct dscc4_dev_priv *dpriv, struct net_device *dev)
int ret = 0; int ret = 0;
for (p = do_setting; p->action; p++) { for (p = do_setting; p->action; p++) {
if ((ret = p->action(dev)) < 0) if ((ret = p->action(dpriv, dev)) < 0)
break; break;
} }
return ret; return ret;
...@@ -1352,7 +1357,8 @@ static void dscc4_irq(int irq, void *token, struct pt_regs *ptregs) ...@@ -1352,7 +1357,8 @@ static void dscc4_irq(int irq, void *token, struct pt_regs *ptregs)
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
} }
static inline void dscc4_tx_irq(struct dscc4_pci_priv *ppriv, struct dscc4_dev_priv *dpriv) static inline void dscc4_tx_irq(struct dscc4_pci_priv *ppriv,
struct dscc4_dev_priv *dpriv)
{ {
struct net_device *dev = hdlc_to_dev(&dpriv->hdlc); struct net_device *dev = hdlc_to_dev(&dpriv->hdlc);
u32 state; u32 state;
...@@ -1375,7 +1381,7 @@ static inline void dscc4_tx_irq(struct dscc4_pci_priv *ppriv, struct dscc4_dev_p ...@@ -1375,7 +1381,7 @@ static inline void dscc4_tx_irq(struct dscc4_pci_priv *ppriv, struct dscc4_dev_p
dpriv->iqtx[cur] = 0; dpriv->iqtx[cur] = 0;
dpriv->iqtx_current++; dpriv->iqtx_current++;
if (state_check(state, dpriv, dev, "Tx")) if (state_check(state, dpriv, dev, "Tx") < 0)
return; return;
if (state & SccEvt) { if (state & SccEvt) {
...@@ -1464,7 +1470,7 @@ static inline void dscc4_tx_irq(struct dscc4_pci_priv *ppriv, struct dscc4_dev_p ...@@ -1464,7 +1470,7 @@ static inline void dscc4_tx_irq(struct dscc4_pci_priv *ppriv, struct dscc4_dev_p
writel(dpriv->tx_fd_dma + writel(dpriv->tx_fd_dma +
(dpriv->tx_dirty%TX_RING_SIZE)* (dpriv->tx_dirty%TX_RING_SIZE)*
sizeof(struct TxFD), scc_addr + CH0BTDA); sizeof(struct TxFD), scc_addr + CH0BTDA);
if (dscc4_do_action(dev, "IDT")) if (dscc4_do_action(dev, "IDT") < 0)
goto err_xpr; goto err_xpr;
dpriv->flags &= ~NeedIDT; dpriv->flags &= ~NeedIDT;
mb(); mb();
...@@ -1474,7 +1480,7 @@ static inline void dscc4_tx_irq(struct dscc4_pci_priv *ppriv, struct dscc4_dev_p ...@@ -1474,7 +1480,7 @@ static inline void dscc4_tx_irq(struct dscc4_pci_priv *ppriv, struct dscc4_dev_p
writel(dpriv->rx_fd_dma + writel(dpriv->rx_fd_dma +
(dpriv->rx_current%RX_RING_SIZE)* (dpriv->rx_current%RX_RING_SIZE)*
sizeof(struct RxFD), scc_addr + CH0BRDA); sizeof(struct RxFD), scc_addr + CH0BRDA);
if (dscc4_do_action(dev, "IDR")) if (dscc4_do_action(dev, "IDR") < 0)
goto err_xpr; goto err_xpr;
dpriv->flags &= ~NeedIDR; dpriv->flags &= ~NeedIDR;
mb(); mb();
...@@ -1519,7 +1525,7 @@ static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv, ...@@ -1519,7 +1525,7 @@ static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv,
dpriv->iqrx[cur] = 0; dpriv->iqrx[cur] = 0;
dpriv->iqrx_current++; dpriv->iqrx_current++;
if (state_check(state, dpriv, dev, "Tx")) if (state_check(state, dpriv, dev, "Rx") < 0)
return; return;
if (!(state & SccEvt)){ if (!(state & SccEvt)){
...@@ -1563,11 +1569,13 @@ static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv, ...@@ -1563,11 +1569,13 @@ static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv,
goto try; goto try;
} }
if (state & Hi ) { /* HI bit */ if (state & Hi ) { /* HI bit */
printk(KERN_INFO "%s: Rx Hi\n", dev->name);
state &= ~Hi; state &= ~Hi;
goto try; goto try;
} }
} else { /* ! SccEvt */ } else { /* ! SccEvt */
#ifdef DEBUG_PARANOIA if (debug > 1) {
//FIXME: verifier la presence de tous les evts + indent
static struct { static struct {
u32 mask; u32 mask;
const char *irq_name; const char *irq_name;
...@@ -1580,9 +1588,8 @@ static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv, ...@@ -1580,9 +1588,8 @@ static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv,
{ 0x00000004, "CDSC"}, { 0x00000004, "CDSC"},
{ 0, NULL} { 0, NULL}
}, *evt; }, *evt;
#endif /* DEBUG_PARANOIA */
state &= 0x00ffffff; state &= 0x00ffffff;
#ifdef DEBUG_PARANOIA
for (evt = evts; evt->irq_name; evt++) { for (evt = evts; evt->irq_name; evt++) {
if (state & evt->mask) { if (state & evt->mask) {
printk(KERN_DEBUG "%s: %s\n", dev->name, printk(KERN_DEBUG "%s: %s\n", dev->name,
...@@ -1591,7 +1598,10 @@ static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv, ...@@ -1591,7 +1598,10 @@ static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv,
goto try; goto try;
} }
} }
#endif /* DEBUG_PARANOIA */ } else {
if (!(state &= ~0x0000c03c))
goto try;
}
/* /*
* Receive Data Overflow (FIXME: fscked) * Receive Data Overflow (FIXME: fscked)
*/ */
...@@ -1648,21 +1658,20 @@ static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv, ...@@ -1648,21 +1658,20 @@ static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv,
(dpriv->rx_current%RX_RING_SIZE)* (dpriv->rx_current%RX_RING_SIZE)*
sizeof(struct RxFD), scc_addr + CH0BRDA); sizeof(struct RxFD), scc_addr + CH0BRDA);
writel(MTFi|Rdr|Idr, scc_addr + CH0CFG); writel(MTFi|Rdr|Idr, scc_addr + CH0CFG);
if (dscc4_do_action(dev, "RDR")) { if (dscc4_do_action(dev, "RDR") < 0) {
printk(KERN_ERR "%s: RDO recovery failed(%s)\n", printk(KERN_ERR "%s: RDO recovery failed(%s)\n",
dev->name, "RDR"); dev->name, "RDR");
goto rdo_end; goto rdo_end;
} }
writel(MTFi|Idr, scc_addr + CH0CFG); writel(MTFi|Idr, scc_addr + CH0CFG);
if (dscc4_do_action(dev, "IDR")) { if (dscc4_do_action(dev, "IDR") < 0) {
printk(KERN_ERR "%s: RDO recovery failed(%s)\n", printk(KERN_ERR "%s: RDO recovery failed(%s)\n",
dev->name, "IDR"); dev->name, "IDR");
goto rdo_end; goto rdo_end;
} }
rdo_end: rdo_end:
#endif #endif
writel(readl(scc_offset + CCR2) | RxActivate, scc_patchl(0, RxActivate, dpriv, dev, CCR2);
scc_offset + CCR2);
goto try; goto try;
} }
/* These will be used later */ /* These will be used later */
......
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