Commit 5f3dec68 authored by Alexander Viro's avatar Alexander Viro Committed by Stephen Hemminger

[wan farsync] embedded struct hdlc_device removal

Removed embedded hdlc in farsync (same as for wanxl and friends).
setup-after-registration race fixed.
parent 184c5b5e
...@@ -328,7 +328,7 @@ struct buf_window { ...@@ -328,7 +328,7 @@ struct buf_window {
/* Per port (line or channel) information /* Per port (line or channel) information
*/ */
struct fst_port_info { struct fst_port_info {
hdlc_device hdlc; /* HDLC device struct - must be first */ struct net_device *dev;
struct fst_card_info *card; /* Card we're associated with */ struct fst_card_info *card; /* Card we're associated with */
int index; /* Port index on the card */ int index; /* Port index on the card */
int hwif; /* Line hardware (lineInterface copy) */ int hwif; /* Line hardware (lineInterface copy) */
...@@ -357,9 +357,8 @@ struct fst_card_info { ...@@ -357,9 +357,8 @@ struct fst_card_info {
}; };
/* Convert an HDLC device pointer into a port info pointer and similar */ /* Convert an HDLC device pointer into a port info pointer and similar */
#define hdlc_to_port(H) ((struct fst_port_info *)(H)) #define dev_to_port(D) (dev_to_hdlc(D)->priv)
#define dev_to_port(D) hdlc_to_port(dev_to_hdlc(D)) #define port_to_dev(P) ((P)->dev)
#define port_to_dev(P) hdlc_to_dev(&(P)->hdlc)
/* /*
...@@ -1454,54 +1453,26 @@ fst_init_card ( struct fst_card_info *card ) ...@@ -1454,54 +1453,26 @@ fst_init_card ( struct fst_card_info *card )
{ {
int i; int i;
int err; int err;
struct net_device *dev;
/* We're working on a number of ports based on the card ID. If the /* We're working on a number of ports based on the card ID. If the
* firmware detects something different later (should never happen) * firmware detects something different later (should never happen)
* we'll have to revise it in some way then. * we'll have to revise it in some way then.
*/ */
for ( i = 0 ; i < card->nports ; i++ ) for ( i = 0 ; i < card->nports ; i++ ) {
{ err = register_hdlc_device(card->ports[i].dev);
hdlc_device *hdlc; if (err < 0) {
card->ports[i].card = card; int j;
card->ports[i].index = i;
card->ports[i].run = 0;
dev = port_to_dev(&card->ports[i]);
hdlc = dev_to_hdlc(dev);
/* Fill in the net device info */
/* Since this is a PCI setup this is purely
* informational. Give them the buffer addresses
* and basic card I/O.
*/
dev->mem_start = card->phys_mem
+ BUF_OFFSET ( txBuffer[i][0][0]);
dev->mem_end = card->phys_mem
+ BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER][0]);
dev->base_addr = card->pci_conf;
dev->irq = card->irq;
dev->tx_queue_len = FST_TX_QUEUE_LEN;
dev->open = fst_open;
dev->stop = fst_close;
dev->do_ioctl = fst_ioctl;
dev->watchdog_timeo = FST_TX_TIMEOUT;
dev->tx_timeout = fst_tx_timeout;
hdlc->attach = fst_attach;
hdlc->xmit = fst_start_xmit;
if (( err = register_hdlc_device(dev)) < 0 )
{
printk_err ("Cannot register HDLC device for port %d" printk_err ("Cannot register HDLC device for port %d"
" (errno %d)\n", i, -err ); " (errno %d)\n", i, -err );
for (j = i; j < card->nports; j++) {
free_hdlcdev(card->ports[j].dev);
card->ports[j].dev = NULL;
}
card->nports = i; card->nports = i;
break; break;
} }
} }
spin_lock_init ( &card->card_lock );
printk ( KERN_INFO "%s-%s: %s IRQ%d, %d ports\n", printk ( KERN_INFO "%s-%s: %s IRQ%d, %d ports\n",
port_to_dev(&card->ports[0])->name, port_to_dev(&card->ports[0])->name,
port_to_dev(&card->ports[card->nports-1])->name, port_to_dev(&card->ports[card->nports-1])->name,
...@@ -1519,6 +1490,7 @@ fst_add_one ( struct pci_dev *pdev, const struct pci_device_id *ent ) ...@@ -1519,6 +1490,7 @@ fst_add_one ( struct pci_dev *pdev, const struct pci_device_id *ent )
static int firsttime_done = 0; static int firsttime_done = 0;
struct fst_card_info *card; struct fst_card_info *card;
int err = 0; int err = 0;
int i;
if ( ! firsttime_done ) if ( ! firsttime_done )
{ {
...@@ -1555,6 +1527,46 @@ fst_add_one ( struct pci_dev *pdev, const struct pci_device_id *ent ) ...@@ -1555,6 +1527,46 @@ fst_add_one ( struct pci_dev *pdev, const struct pci_device_id *ent )
card->state = FST_UNINIT; card->state = FST_UNINIT;
spin_lock_init ( &card->card_lock );
for ( i = 0 ; i < card->nports ; i++ ) {
struct net_device *dev = alloc_hdlcdev(&card->ports[i]);
hdlc_device *hdlc;
if (!dev) {
while (i--)
free_hdlcdev(card->ports[i].dev);
printk_err ("FarSync: out of memory\n");
goto error_free_card;
}
card->ports[i].dev = dev;
card->ports[i].card = card;
card->ports[i].index = i;
card->ports[i].run = 0;
hdlc = dev_to_hdlc(dev);
/* Fill in the net device info */
/* Since this is a PCI setup this is purely
* informational. Give them the buffer addresses
* and basic card I/O.
*/
dev->mem_start = card->phys_mem
+ BUF_OFFSET ( txBuffer[i][0][0]);
dev->mem_end = card->phys_mem
+ BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER][0]);
dev->base_addr = card->pci_conf;
dev->irq = card->irq;
dev->tx_queue_len = FST_TX_QUEUE_LEN;
dev->open = fst_open;
dev->stop = fst_close;
dev->do_ioctl = fst_ioctl;
dev->watchdog_timeo = FST_TX_TIMEOUT;
dev->tx_timeout = fst_tx_timeout;
hdlc->attach = fst_attach;
hdlc->xmit = fst_start_xmit;
}
dbg ( DBG_PCI,"type %d nports %d irq %d\n", card->type, dbg ( DBG_PCI,"type %d nports %d irq %d\n", card->type,
card->nports, card->irq ); card->nports, card->irq );
dbg ( DBG_PCI,"conf %04x mem %08x ctlmem %08x\n", dbg ( DBG_PCI,"conf %04x mem %08x ctlmem %08x\n",
...@@ -1566,7 +1578,7 @@ fst_add_one ( struct pci_dev *pdev, const struct pci_device_id *ent ) ...@@ -1566,7 +1578,7 @@ fst_add_one ( struct pci_dev *pdev, const struct pci_device_id *ent )
printk_err ("Unable to get config I/O @ 0x%04X\n", printk_err ("Unable to get config I/O @ 0x%04X\n",
card->pci_conf ); card->pci_conf );
err = -ENODEV; err = -ENODEV;
goto error_free_card; goto error_free_ports;
} }
if ( ! request_mem_region ( card->phys_mem, FST_MEMSIZE,"Shared RAM")) if ( ! request_mem_region ( card->phys_mem, FST_MEMSIZE,"Shared RAM"))
{ {
...@@ -1637,6 +1649,9 @@ fst_add_one ( struct pci_dev *pdev, const struct pci_device_id *ent ) ...@@ -1637,6 +1649,9 @@ fst_add_one ( struct pci_dev *pdev, const struct pci_device_id *ent )
error_release_io: error_release_io:
release_region ( card->pci_conf, 0x80 ); release_region ( card->pci_conf, 0x80 );
error_free_ports:
for (i = 0; i < card->nports; i++)
free_hdlcdev(card->ports[i].dev);
error_free_card: error_free_card:
kfree ( card ); kfree ( card );
return err; return err;
...@@ -1670,6 +1685,9 @@ fst_remove_one ( struct pci_dev *pdev ) ...@@ -1670,6 +1685,9 @@ fst_remove_one ( struct pci_dev *pdev )
release_mem_region ( card->phys_mem, FST_MEMSIZE ); release_mem_region ( card->phys_mem, FST_MEMSIZE );
release_region ( card->pci_conf, 0x80 ); release_region ( card->pci_conf, 0x80 );
for (i = 0; i < card->nports; i++)
free_hdlcdev(card->ports[i].dev);
kfree ( card ); kfree ( card );
} }
......
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