aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pppol2tp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pppol2tp.c')
-rw-r--r--drivers/net/pppol2tp.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index e0b072d9fdb7..86e5dba079fe 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -455,6 +455,7 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
455 skb_queue_len(&session->reorder_q)); 455 skb_queue_len(&session->reorder_q));
456 __skb_unlink(skb, &session->reorder_q); 456 __skb_unlink(skb, &session->reorder_q);
457 kfree_skb(skb); 457 kfree_skb(skb);
458 sock_put(session->sock);
458 continue; 459 continue;
459 } 460 }
460 461
@@ -1110,6 +1111,8 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
1110 for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) { 1111 for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) {
1111again: 1112again:
1112 hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { 1113 hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
1114 struct sk_buff *skb;
1115
1113 session = hlist_entry(walk, struct pppol2tp_session, hlist); 1116 session = hlist_entry(walk, struct pppol2tp_session, hlist);
1114 1117
1115 sk = session->sock; 1118 sk = session->sock;
@@ -1138,7 +1141,10 @@ again:
1138 /* Purge any queued data */ 1141 /* Purge any queued data */
1139 skb_queue_purge(&sk->sk_receive_queue); 1142 skb_queue_purge(&sk->sk_receive_queue);
1140 skb_queue_purge(&sk->sk_write_queue); 1143 skb_queue_purge(&sk->sk_write_queue);
1141 skb_queue_purge(&session->reorder_q); 1144 while ((skb = skb_dequeue(&session->reorder_q))) {
1145 kfree_skb(skb);
1146 sock_put(sk);
1147 }
1142 1148
1143 release_sock(sk); 1149 release_sock(sk);
1144 sock_put(sk); 1150 sock_put(sk);
icense, incorporated herein by reference. * * This driver module supports the following cards: * - SysKonnect TR4/16(+) PCI (SK-4590) * - SysKonnect TR4/16 PCI (SK-4591) * - Compaq TR 4/16 PCI * - Thomas-Conrad TC4048 4/16 PCI * - 3Com 3C339 Token Link Velocity * * Maintainer(s): * AF Adam Fritzler mid@auk.cx * * Modification History: * 30-Dec-99 AF Split off from the tms380tr driver. * 22-Jan-00 AF Updated to use indirect read/writes * 23-Nov-00 JG New PCI API, cleanups * * TODO: * 1. See if we can use MMIO instead of port accesses * */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/pci.h> #include <linux/init.h> #include <linux/netdevice.h> #include <linux/trdevice.h> #include <asm/system.h> #include <asm/io.h> #include <asm/irq.h> #include "tms380tr.h" static char version[] __devinitdata = "tmspci.c: v1.02 23/11/2000 by Adam Fritzler\n"; #define TMS_PCI_IO_EXTENT 32 struct card_info { unsigned char nselout[2]; /* NSELOUT vals for 4mb([0]) and 16mb([1]) */ char *name; }; static struct card_info card_info_table[] = { { {0x03, 0x01}, "Compaq 4/16 TR PCI"}, { {0x03, 0x01}, "SK NET TR 4/16 PCI"}, { {0x03, 0x01}, "Thomas-Conrad TC4048 PCI 4/16"}, { {0x03, 0x01}, "3Com Token Link Velocity"}, }; static struct pci_device_id tmspci_pci_tbl[] = { { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, { PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(pci, tmspci_pci_tbl); MODULE_LICENSE("GPL"); static void tms_pci_read_eeprom(struct net_device *dev); static unsigned short tms_pci_setnselout_pins(struct net_device *dev); static unsigned short tms_pci_sifreadb(struct net_device *dev, unsigned short reg) { return inb(dev->base_addr + reg); } static unsigned short tms_pci_sifreadw(struct net_device *dev, unsigned short reg) { return inw(dev->base_addr + reg); } static void tms_pci_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg) { outb(val, dev->base_addr + reg); } static void tms_pci_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg) { outw(val, dev->base_addr + reg); } static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_device_id *ent) { static int versionprinted; struct net_device *dev; struct net_local *tp; int ret; unsigned int pci_irq_line; unsigned long pci_ioaddr; struct card_info *cardinfo = &card_info_table[ent->driver_data]; DECLARE_MAC_BUF(mac); if (versionprinted++ == 0) printk("%s", version); if (pci_enable_device(pdev)) return -EIO; /* Remove I/O space marker in bit 0. */ pci_irq_line = pdev->irq; pci_ioaddr = pci_resource_start (pdev, 0); /* At this point we have found a valid card. */ dev = alloc_trdev(sizeof(struct net_local)); if (!dev) return -ENOMEM; if (!request_region(pci_ioaddr, TMS_PCI_IO_EXTENT, dev->name)) { ret = -EBUSY; goto err_out_trdev; } ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, dev->name, dev); if (ret) goto err_out_region; dev->base_addr = pci_ioaddr; dev->irq = pci_irq_line; dev->dma = 0; printk("%s: %s\n", dev->name, cardinfo->name); printk("%s: IO: %#4lx IRQ: %d\n", dev->name, dev->base_addr, dev->irq); tms_pci_read_eeprom(dev); printk("%s: Ring Station Address: %s\n", dev->name, print_mac(mac, dev->dev_addr)); ret = tmsdev_init(dev, &pdev->dev); if (ret) { printk("%s: unable to get memory for dev->priv.\n", dev->name); goto err_out_irq; } tp = netdev_priv(dev); tp->setnselout = tms_pci_setnselout_pins; tp->sifreadb = tms_pci_sifreadb; tp->sifreadw = tms_pci_sifreadw; tp->sifwriteb = tms_pci_sifwriteb; tp->sifwritew = tms_pci_sifwritew; memcpy(tp->ProductID, cardinfo->name, PROD_ID_SIZE + 1); tp->tmspriv = cardinfo; dev->open = tms380tr_open; dev->stop = tms380tr_close; pci_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); ret = register_netdev(dev); if (ret) goto err_out_tmsdev; return 0; err_out_tmsdev: pci_set_drvdata(pdev, NULL); tmsdev_term(dev); err_out_irq: free_irq(pdev->irq, dev); err_out_region: release_region(pci_ioaddr, TMS_PCI_IO_EXTENT); err_out_trdev: free_netdev(dev); return ret; } /* * Reads MAC address from adapter RAM, which should've read it from * the onboard ROM. * * Calling this on a board that does not support it can be a very * dangerous thing. The Madge board, for instance, will lock your * machine hard when this is called. Luckily, its supported in a * separate driver. --ASF */ static void tms_pci_read_eeprom(struct net_device *dev) { int i; /* Address: 0000:0000 */ tms_pci_sifwritew(dev, 0, SIFADX); tms_pci_sifwritew(dev, 0, SIFADR); /* Read six byte MAC address data */ dev->addr_len = 6; for(i = 0; i < 6; i++) dev->dev_addr[i] = tms_pci_sifreadw(dev, SIFINC) >> 8; } static unsigned short tms_pci_setnselout_pins(struct net_device *dev) { unsigned short val = 0; struct net_local *tp = netdev_priv(dev); struct card_info *cardinfo = tp->tmspriv; if(tp->DataRate == SPEED_4) val |= cardinfo->nselout[0]; /* Set 4Mbps */ else val |= cardinfo->nselout[1]; /* Set 16Mbps */ return val; } static void __devexit tms_pci_detach (struct pci_dev *pdev) {