unsigned short encoding;
unsigned short parity;
- hdlc_device hdlc;
+ struct net_device *dev;
sync_serial_settings settings;
u32 __pad __attribute__ ((aligned (4)));
};
static void dscc4_timer(unsigned long);
static void dscc4_tx_timeout(struct net_device *);
static irqreturn_t dscc4_irq(int irq, void *dev_id, struct pt_regs *ptregs);
-static int dscc4_hdlc_attach(hdlc_device *, unsigned short, unsigned short);
+static int dscc4_hdlc_attach(struct net_device *, unsigned short, unsigned short);
static int dscc4_set_iface(struct dscc4_dev_priv *, struct net_device *);
static inline int dscc4_set_quartz(struct dscc4_dev_priv *, int);
#ifdef DSCC4_POLLING
static inline struct dscc4_dev_priv *dscc4_priv(struct net_device *dev)
{
- return list_entry(dev, struct dscc4_dev_priv, hdlc.netdev);
+ return dev_to_hdlc(dev)->priv;
+}
+
+static inline struct net_device *dscc4_to_dev(struct dscc4_dev_priv *p)
+{
+ return p->dev;
}
static void scc_patchl(u32 mask, u32 value, struct dscc4_dev_priv *dpriv,
struct net_device *dev)
{
struct RxFD *rx_fd = dpriv->rx_fd + dpriv->rx_current%RX_RING_SIZE;
- struct net_device_stats *stats = &dpriv->hdlc.stats;
+ struct net_device_stats *stats = hdlc_stats(dev);
struct pci_dev *pdev = dpriv->pci_priv->pdev;
struct sk_buff *skb;
int pkt_len;
root = ppriv->root;
for (i = 0; i < dev_per_card; i++)
- unregister_hdlc_device(&root[i].hdlc);
+ unregister_hdlc_device(dscc4_to_dev(&root[i]));
pci_set_drvdata(pdev, NULL);
+ for (i = 0; i < dev_per_card; i++)
+ free_netdev(root[i].dev);
kfree(root);
kfree(ppriv);
}
}
memset(root, 0, dev_per_card*sizeof(*root));
+ for (i = 0; i < dev_per_card; i++) {
+ root[i].dev = alloc_hdlcdev(root + i);
+ if (!root[i].dev) {
+ while (i--)
+ free_netdev(root[i].dev);
+ goto err_free_dev;
+ }
+ }
+
ppriv = (struct dscc4_pci_priv *) kmalloc(sizeof(*ppriv), GFP_KERNEL);
if (!ppriv) {
printk(KERN_ERR "%s: can't allocate private data\n", DRV_NAME);
- goto err_free_dev;
+ goto err_free_dev2;
}
memset(ppriv, 0, sizeof(struct dscc4_pci_priv));
+ ret = dscc4_set_quartz(root, quartz);
+ if (ret < 0)
+ goto err_free_priv;
+ ppriv->root = root;
+ spin_lock_init(&ppriv->lock);
for (i = 0; i < dev_per_card; i++) {
struct dscc4_dev_priv *dpriv = root + i;
- hdlc_device *hdlc = &dpriv->hdlc;
- struct net_device *d = hdlc_to_dev(hdlc);
+ struct net_device *d = dscc4_to_dev(dpriv);
+ hdlc_device *hdlc = dev_to_hdlc(d);
d->base_addr = ioaddr;
d->init = NULL;
hdlc->xmit = dscc4_start_xmit;
hdlc->attach = dscc4_hdlc_attach;
- ret = register_hdlc_device(hdlc);
- if (ret < 0) {
- printk(KERN_ERR "%s: unable to register\n", DRV_NAME);
- goto err_unregister;
- }
-
dscc4_init_registers(dpriv, d);
dpriv->parity = PARITY_CRC16_PR0_CCITT;
dpriv->encoding = ENCODING_NRZ;
-
+
ret = dscc4_init_ring(d);
+ if (ret < 0)
+ goto err_unregister;
+
+ ret = register_hdlc_device(d);
if (ret < 0) {
- unregister_hdlc_device(hdlc);
+ printk(KERN_ERR "%s: unable to register\n", DRV_NAME);
+ dscc4_release_ring(dpriv);
goto err_unregister;
- }
+ }
}
- ret = dscc4_set_quartz(root, quartz);
- if (ret < 0)
- goto err_unregister;
- ppriv->root = root;
- spin_lock_init(&ppriv->lock);
pci_set_drvdata(pdev, ppriv);
return ret;
err_unregister:
while (--i >= 0) {
dscc4_release_ring(root + i);
- unregister_hdlc_device(&root[i].hdlc);
+ unregister_hdlc_device(dscc4_to_dev(&root[i]));
}
+err_free_priv:
kfree(ppriv);
+err_free_dev2:
+ for (i = 0; i < dev_per_card; i++)
+ free_netdev(root[i].dev);
err_free_dev:
kfree(root);
err_out:
sync_serial_settings *settings = &dpriv->settings;
if (settings->loopback && (settings->clock_type != CLOCK_INT)) {
- struct net_device *dev = hdlc_to_dev(&dpriv->hdlc);
+ struct net_device *dev = dscc4_to_dev(dpriv);
printk(KERN_INFO "%s: loopback requires clock\n", dev->name);
return -1;
static int dscc4_open(struct net_device *dev)
{
struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
- hdlc_device *hdlc = &dpriv->hdlc;
struct dscc4_pci_priv *ppriv;
int ret = -EAGAIN;
if ((dscc4_loopback_check(dpriv) < 0) || !dev->hard_start_xmit)
goto err;
- if ((ret = hdlc_open(hdlc)))
+ if ((ret = hdlc_open(dev)))
goto err;
ppriv = dpriv->pci_priv;
scc_writel(0xffffffff, dpriv, dev, IMR);
scc_patchl(PowerUp | Vis, 0, dpriv, dev, CCR0);
err_out:
- hdlc_close(hdlc);
+ hdlc_close(dev);
err:
return ret;
}
static int dscc4_close(struct net_device *dev)
{
struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
- hdlc_device *hdlc = dev_to_hdlc(dev);
del_timer_sync(&dpriv->timer);
netif_stop_queue(dev);
dpriv->flags |= FakeReset;
- hdlc_close(hdlc);
+ hdlc_close(dev);
return 0;
}
int i, handled = 1;
priv = root->pci_priv;
- dev = hdlc_to_dev(&root->hdlc);
+ dev = dscc4_to_dev(root);
spin_lock_irqsave(&priv->lock, flags);
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 = dscc4_to_dev(dpriv);
u32 state;
int cur, loop = 0;
if (state & SccEvt) {
if (state & Alls) {
- struct net_device_stats *stats = &dpriv->hdlc.stats;
+ struct net_device_stats *stats = hdlc_stats(dev);
struct sk_buff *skb;
struct TxFD *tx_fd;
}
if (state & Err) {
printk(KERN_INFO "%s: Tx ERR\n", dev->name);
- dev_to_hdlc(dev)->stats.tx_errors++;
+ hdlc_stats(dev)->tx_errors++;
state &= ~Err;
}
}
static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv,
struct dscc4_dev_priv *dpriv)
{
- struct net_device *dev = hdlc_to_dev(&dpriv->hdlc);
+ struct net_device *dev = dscc4_to_dev(dpriv);
u32 state;
int cur;
if (!(rx_fd->state2 & DataComplete))
break;
if (rx_fd->state2 & FrameAborted) {
- dev_to_hdlc(dev)->stats.rx_over_errors++;
+ hdlc_stats(dev)->rx_over_errors++;
rx_fd->state1 |= Hold;
rx_fd->state2 = 0x00000000;
rx_fd->end = 0xbabeface;
ppriv = pci_get_drvdata(pdev);
root = ppriv->root;
- ioaddr = hdlc_to_dev(&root->hdlc)->base_addr;
+ ioaddr = dscc4_to_dev(root)->base_addr;
dscc4_pci_reset(pdev, ioaddr);
pci_resource_len(pdev, 0));
}
-static int dscc4_hdlc_attach(hdlc_device *hdlc, unsigned short encoding,
+static int dscc4_hdlc_attach(struct net_device *dev, unsigned short encoding,
unsigned short parity)
{
- struct net_device *dev = hdlc_to_dev(hdlc);
struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
if (encoding != ENCODING_NRZ &&