aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/atm/solos-pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/atm/solos-pci.c')
-rw-r--r--drivers/atm/solos-pci.c53
1 files changed, 28 insertions, 25 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 5e228a3f7502..e7691b3328f9 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -140,7 +140,7 @@ module_param(fpga_upgrade, int, 0444);
140 140
141static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb, 141static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
142 struct atm_vcc *vcc); 142 struct atm_vcc *vcc);
143static int fpga_tx(struct solos_card *); 143static uint32_t fpga_tx(struct solos_card *);
144static irqreturn_t solos_irq(int irq, void *dev_id); 144static irqreturn_t solos_irq(int irq, void *dev_id);
145static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); 145static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
146static int list_vccs(int vci); 146static int list_vccs(int vci);
@@ -438,8 +438,6 @@ static int send_command(struct solos_card *card, int dev, const char *buf, size_
438 struct sk_buff *skb; 438 struct sk_buff *skb;
439 struct pkt_hdr *header; 439 struct pkt_hdr *header;
440 440
441// dev_dbg(&card->dev->dev, "size: %d\n", size);
442
443 if (size > (BUF_SIZE - sizeof(*header))) { 441 if (size > (BUF_SIZE - sizeof(*header))) {
444 dev_dbg(&card->dev->dev, "Command is too big. Dropping request\n"); 442 dev_dbg(&card->dev->dev, "Command is too big. Dropping request\n");
445 return 0; 443 return 0;
@@ -574,9 +572,9 @@ static irqreturn_t solos_irq(int irq, void *dev_id)
574 struct solos_card *card = dev_id; 572 struct solos_card *card = dev_id;
575 int handled = 1; 573 int handled = 1;
576 574
577 //ACK IRQ
578 iowrite32(0, card->config_regs + IRQ_CLEAR); 575 iowrite32(0, card->config_regs + IRQ_CLEAR);
579 576
577 /* If we're up and running, just kick the tasklet to process TX/RX */
580 if (card->atmdev[0]) 578 if (card->atmdev[0])
581 tasklet_schedule(&card->tlet); 579 tasklet_schedule(&card->tlet);
582 else 580 else
@@ -588,16 +586,16 @@ static irqreturn_t solos_irq(int irq, void *dev_id)
588void solos_bh(unsigned long card_arg) 586void solos_bh(unsigned long card_arg)
589{ 587{
590 struct solos_card *card = (void *)card_arg; 588 struct solos_card *card = (void *)card_arg;
591 int port;
592 uint32_t card_flags; 589 uint32_t card_flags;
593 uint32_t rx_done = 0; 590 uint32_t rx_done = 0;
591 int port;
594 592
595 card_flags = ioread32(card->config_regs + FLAGS_ADDR); 593 /*
596 594 * Since fpga_tx() is going to need to read the flags under its lock,
597 /* The TX bits are set if the channel is busy; clear if not. We want to 595 * it can return them to us so that we don't have to hit PCI MMIO
598 invoke fpga_tx() unless _all_ the bits for active channels are set */ 596 * again for the same information
599 if ((card_flags & card->tx_mask) != card->tx_mask) 597 */
600 fpga_tx(card); 598 card_flags = fpga_tx(card);
601 599
602 for (port = 0; port < card->nr_ports; port++) { 600 for (port = 0; port < card->nr_ports; port++) {
603 if (card_flags & (0x10 << port)) { 601 if (card_flags & (0x10 << port)) {
@@ -892,9 +890,8 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
892 spin_lock_irqsave(&card->tx_queue_lock, flags); 890 spin_lock_irqsave(&card->tx_queue_lock, flags);
893 old_len = skb_queue_len(&card->tx_queue[port]); 891 old_len = skb_queue_len(&card->tx_queue[port]);
894 skb_queue_tail(&card->tx_queue[port], skb); 892 skb_queue_tail(&card->tx_queue[port], skb);
895 if (!old_len) { 893 if (!old_len)
896 card->tx_mask |= (1 << port); 894 card->tx_mask |= (1 << port);
897 }
898 spin_unlock_irqrestore(&card->tx_queue_lock, flags); 895 spin_unlock_irqrestore(&card->tx_queue_lock, flags);
899 896
900 /* Theoretically we could just schedule the tasklet here, but 897 /* Theoretically we could just schedule the tasklet here, but
@@ -903,9 +900,9 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
903 fpga_tx(card); 900 fpga_tx(card);
904} 901}
905 902
906static int fpga_tx(struct solos_card *card) 903static uint32_t fpga_tx(struct solos_card *card)
907{ 904{
908 uint32_t tx_pending; 905 uint32_t tx_pending, card_flags;
909 uint32_t tx_started = 0; 906 uint32_t tx_started = 0;
910 struct sk_buff *skb; 907 struct sk_buff *skb;
911 struct atm_vcc *vcc; 908 struct atm_vcc *vcc;
@@ -913,19 +910,24 @@ static int fpga_tx(struct solos_card *card)
913 unsigned long flags; 910 unsigned long flags;
914 911
915 spin_lock_irqsave(&card->tx_lock, flags); 912 spin_lock_irqsave(&card->tx_lock, flags);
916 913
917 tx_pending = ioread32(card->config_regs + FLAGS_ADDR) & card->tx_mask; 914 card_flags = ioread32(card->config_regs + FLAGS_ADDR);
918 915 /*
919 dev_vdbg(&card->dev->dev, "TX Flags are %X\n", tx_pending); 916 * The queue lock is required for _writing_ to tx_mask, but we're
920 917 * OK to read it here without locking. The only potential update
921 for (port = 0; port < card->nr_ports; port++) { 918 * that we could race with is in fpga_queue() where it sets a bit
922 if (card->atmdev[port] && !(tx_pending & (1 << port))) { 919 * for a new port... but it's going to call this function again if
920 * it's doing that, anyway.
921 */
922 tx_pending = card->tx_mask & ~card_flags;
923
924 for (port = 0; tx_pending; tx_pending >>= 1, port++) {
925 if (tx_pending & 1) {
923 struct sk_buff *oldskb = card->tx_skb[port]; 926 struct sk_buff *oldskb = card->tx_skb[port];
924
925 if (oldskb) 927 if (oldskb)
926 pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr, 928 pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr,
927 oldskb->len, PCI_DMA_TODEVICE); 929 oldskb->len, PCI_DMA_TODEVICE);
928 930
929 spin_lock(&card->tx_queue_lock); 931 spin_lock(&card->tx_queue_lock);
930 skb = skb_dequeue(&card->tx_queue[port]); 932 skb = skb_dequeue(&card->tx_queue[port]);
931 if (!skb) 933 if (!skb)
@@ -966,8 +968,9 @@ static int fpga_tx(struct solos_card *card)
966 if (tx_started) 968 if (tx_started)
967 iowrite32(tx_started, card->config_regs + FLAGS_ADDR); 969 iowrite32(tx_started, card->config_regs + FLAGS_ADDR);
968 970
971 out:
969 spin_unlock_irqrestore(&card->tx_lock, flags); 972 spin_unlock_irqrestore(&card->tx_lock, flags);
970 return 0; 973 return card_flags;
971} 974}
972 975
973static int psend(struct atm_vcc *vcc, struct sk_buff *skb) 976static int psend(struct atm_vcc *vcc, struct sk_buff *skb)