aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/atm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-12-01 20:45:24 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-01 20:45:24 -0500
commitddb303301bed80f700db6f36870642a08016f266 (patch)
treee332b17c20732b22192e2ddec7762c90c19f73b4 /drivers/atm
parent577b981714b0b3530817569bf705bd74881efc83 (diff)
parentc48d49aab0b5b48b40e00fe43927efed5fc09d88 (diff)
Merge git://git.infradead.org/users/dwmw2/atm
David Woodhouse says: ==================== This is the result of pulling on the thread started by Krzysztof Mazur's original patch 'pppoatm: don't send frames to destroyed vcc'. Various problems in the pppoatm and br2684 code are solved, some of which were easily triggered and would panic the kernel. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/atm')
-rw-r--r--drivers/atm/solos-pci.c83
1 files changed, 32 insertions, 51 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 98510931c815..6619a8a9607c 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -164,7 +164,6 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
164static uint32_t fpga_tx(struct solos_card *); 164static uint32_t fpga_tx(struct solos_card *);
165static irqreturn_t solos_irq(int irq, void *dev_id); 165static irqreturn_t solos_irq(int irq, void *dev_id);
166static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); 166static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
167static int list_vccs(int vci);
168static int atm_init(struct solos_card *, struct device *); 167static int atm_init(struct solos_card *, struct device *);
169static void atm_remove(struct solos_card *); 168static void atm_remove(struct solos_card *);
170static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); 169static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
@@ -710,7 +709,8 @@ void solos_bh(unsigned long card_arg)
710 dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n", 709 dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n",
711 le16_to_cpu(header->vpi), le16_to_cpu(header->vci), 710 le16_to_cpu(header->vpi), le16_to_cpu(header->vci),
712 port); 711 port);
713 continue; 712 dev_kfree_skb_any(skb);
713 break;
714 } 714 }
715 atm_charge(vcc, skb->truesize); 715 atm_charge(vcc, skb->truesize);
716 vcc->push(vcc, skb); 716 vcc->push(vcc, skb);
@@ -790,44 +790,6 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
790 return vcc; 790 return vcc;
791} 791}
792 792
793static int list_vccs(int vci)
794{
795 struct hlist_head *head;
796 struct atm_vcc *vcc;
797 struct hlist_node *node;
798 struct sock *s;
799 int num_found = 0;
800 int i;
801
802 read_lock(&vcc_sklist_lock);
803 if (vci != 0){
804 head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
805 sk_for_each(s, node, head) {
806 num_found ++;
807 vcc = atm_sk(s);
808 printk(KERN_DEBUG "Device: %d Vpi: %d Vci: %d\n",
809 vcc->dev->number,
810 vcc->vpi,
811 vcc->vci);
812 }
813 } else {
814 for(i = 0; i < VCC_HTABLE_SIZE; i++){
815 head = &vcc_hash[i];
816 sk_for_each(s, node, head) {
817 num_found ++;
818 vcc = atm_sk(s);
819 printk(KERN_DEBUG "Device: %d Vpi: %d Vci: %d\n",
820 vcc->dev->number,
821 vcc->vpi,
822 vcc->vci);
823 }
824 }
825 }
826 read_unlock(&vcc_sklist_lock);
827 return num_found;
828}
829
830
831static int popen(struct atm_vcc *vcc) 793static int popen(struct atm_vcc *vcc)
832{ 794{
833 struct solos_card *card = vcc->dev->dev_data; 795 struct solos_card *card = vcc->dev->dev_data;
@@ -840,7 +802,7 @@ static int popen(struct atm_vcc *vcc)
840 return -EINVAL; 802 return -EINVAL;
841 } 803 }
842 804
843 skb = alloc_skb(sizeof(*header), GFP_ATOMIC); 805 skb = alloc_skb(sizeof(*header), GFP_KERNEL);
844 if (!skb) { 806 if (!skb) {
845 if (net_ratelimit()) 807 if (net_ratelimit())
846 dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n"); 808 dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
@@ -857,8 +819,6 @@ static int popen(struct atm_vcc *vcc)
857 819
858 set_bit(ATM_VF_ADDR, &vcc->flags); 820 set_bit(ATM_VF_ADDR, &vcc->flags);
859 set_bit(ATM_VF_READY, &vcc->flags); 821 set_bit(ATM_VF_READY, &vcc->flags);
860 list_vccs(0);
861
862 822
863 return 0; 823 return 0;
864} 824}
@@ -866,10 +826,21 @@ static int popen(struct atm_vcc *vcc)
866static void pclose(struct atm_vcc *vcc) 826static void pclose(struct atm_vcc *vcc)
867{ 827{
868 struct solos_card *card = vcc->dev->dev_data; 828 struct solos_card *card = vcc->dev->dev_data;
869 struct sk_buff *skb; 829 unsigned char port = SOLOS_CHAN(vcc->dev);
830 struct sk_buff *skb, *tmpskb;
870 struct pkt_hdr *header; 831 struct pkt_hdr *header;
871 832
872 skb = alloc_skb(sizeof(*header), GFP_ATOMIC); 833 /* Remove any yet-to-be-transmitted packets from the pending queue */
834 spin_lock(&card->tx_queue_lock);
835 skb_queue_walk_safe(&card->tx_queue[port], skb, tmpskb) {
836 if (SKB_CB(skb)->vcc == vcc) {
837 skb_unlink(skb, &card->tx_queue[port]);
838 solos_pop(vcc, skb);
839 }
840 }
841 spin_unlock(&card->tx_queue_lock);
842
843 skb = alloc_skb(sizeof(*header), GFP_KERNEL);
873 if (!skb) { 844 if (!skb) {
874 dev_warn(&card->dev->dev, "Failed to allocate sk_buff in pclose()\n"); 845 dev_warn(&card->dev->dev, "Failed to allocate sk_buff in pclose()\n");
875 return; 846 return;
@@ -881,15 +852,22 @@ static void pclose(struct atm_vcc *vcc)
881 header->vci = cpu_to_le16(vcc->vci); 852 header->vci = cpu_to_le16(vcc->vci);
882 header->type = cpu_to_le16(PKT_PCLOSE); 853 header->type = cpu_to_le16(PKT_PCLOSE);
883 854
884 fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL); 855 skb_get(skb);
856 fpga_queue(card, port, skb, NULL);
885 857
886 clear_bit(ATM_VF_ADDR, &vcc->flags); 858 if (!wait_event_timeout(card->param_wq, !skb_shared(skb), 5 * HZ))
887 clear_bit(ATM_VF_READY, &vcc->flags); 859 dev_warn(&card->dev->dev,
860 "Timeout waiting for VCC close on port %d\n", port);
861
862 dev_kfree_skb(skb);
888 863
889 /* Hold up vcc_destroy_socket() (our caller) until solos_bh() in the 864 /* Hold up vcc_destroy_socket() (our caller) until solos_bh() in the
890 tasklet has finished processing any incoming packets (and, more to 865 tasklet has finished processing any incoming packets (and, more to
891 the point, using the vcc pointer). */ 866 the point, using the vcc pointer). */
892 tasklet_unlock_wait(&card->tlet); 867 tasklet_unlock_wait(&card->tlet);
868
869 clear_bit(ATM_VF_ADDR, &vcc->flags);
870
893 return; 871 return;
894} 872}
895 873
@@ -1011,9 +989,10 @@ static uint32_t fpga_tx(struct solos_card *card)
1011 if (vcc) { 989 if (vcc) {
1012 atomic_inc(&vcc->stats->tx); 990 atomic_inc(&vcc->stats->tx);
1013 solos_pop(vcc, oldskb); 991 solos_pop(vcc, oldskb);
1014 } else 992 } else {
1015 dev_kfree_skb_irq(oldskb); 993 dev_kfree_skb_irq(oldskb);
1016 994 wake_up(&card->param_wq);
995 }
1017 } 996 }
1018 } 997 }
1019 /* For non-DMA TX, write the 'TX start' bit for all four ports simultaneously */ 998 /* For non-DMA TX, write the 'TX start' bit for all four ports simultaneously */
@@ -1248,7 +1227,7 @@ static int atm_init(struct solos_card *card, struct device *parent)
1248 card->atmdev[i]->phy_data = (void *)(unsigned long)i; 1227 card->atmdev[i]->phy_data = (void *)(unsigned long)i;
1249 atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND); 1228 atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND);
1250 1229
1251 skb = alloc_skb(sizeof(*header), GFP_ATOMIC); 1230 skb = alloc_skb(sizeof(*header), GFP_KERNEL);
1252 if (!skb) { 1231 if (!skb) {
1253 dev_warn(&card->dev->dev, "Failed to allocate sk_buff in atm_init()\n"); 1232 dev_warn(&card->dev->dev, "Failed to allocate sk_buff in atm_init()\n");
1254 continue; 1233 continue;
@@ -1345,6 +1324,8 @@ static struct pci_driver fpga_driver = {
1345 1324
1346static int __init solos_pci_init(void) 1325static int __init solos_pci_init(void)
1347{ 1326{
1327 BUILD_BUG_ON(sizeof(struct solos_skb_cb) > sizeof(((struct sk_buff *)0)->cb));
1328
1348 printk(KERN_INFO "Solos PCI Driver Version %s\n", VERSION); 1329 printk(KERN_INFO "Solos PCI Driver Version %s\n", VERSION);
1349 return pci_register_driver(&fpga_driver); 1330 return pci_register_driver(&fpga_driver);
1350} 1331}