netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* 2.6.x wanXL driver update
@ 2004-03-08  0:00 Krzysztof Halasa
  2004-03-08  1:20 ` Jeff Garzik
  0 siblings, 1 reply; 2+ messages in thread
From: Krzysztof Halasa @ 2004-03-08  0:00 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

[-- Attachment #1: Type: text/plain, Size: 296 bytes --]

Hi,

The attached patch updates wanXL card driver. Please apply to Linux 2.6.
Thanks.

Changes:
* fixed initialization kernel panic, introduced with recent alloc_netdev()
  wan patch,
* wanxl_rx_intr() port# now checked before accessing port structure,
* cleanups etc.
-- 
Krzysztof Halasa, B*FH

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: wanxl-2.6.4rc2.patch --]
[-- Type: text/x-patch, Size: 10967 bytes --]

--- linux/drivers/net/wan/wanxl.c	26 Feb 2004 16:26:48 -0000	1.5
+++ linux/drivers/net/wan/wanxl.c	7 Mar 2004 21:50:38 -0000
@@ -31,7 +31,7 @@
 
 #include "wanxl.h"
 
-static const char* version = "wanXL serial card driver version: 0.47";
+static const char* version = "wanXL serial card driver version: 0.48";
 
 #define PLX_CTL_RESET   0x40000000 /* adapter reset */
 
@@ -73,12 +73,11 @@
 
 	u8 *plx;		/* PLX PCI9060 virtual base address */
 	struct pci_dev *pdev;	/* for pdev->slot_name */
-	port_t *ports[4];
 	int rx_in;
 	struct sk_buff *rx_skbs[RX_QUEUE_LENGTH];
 	card_status_t *status;	/* shared between host and card */
 	dma_addr_t status_address;
-	port_t __ports[0];
+	port_t ports[0];	/* 1 - 4 port_t structures follow */
 }card_t;
 
 
@@ -89,18 +88,6 @@
 }
 
 
-static inline struct net_device *port_to_dev(port_t* port)
-{
-        return port->dev;
-}
-
-
-static inline const char* port_name(port_t *port)
-{
-	return port_to_dev(port)->name;
-}
-
-
 static inline const char* card_name(struct pci_dev *pdev)
 {
 	return pdev->slot_name;
@@ -165,9 +152,9 @@
 		dte = (value & STATUS_CABLE_DCE) ? " DCE" : " DTE";
 	}
 	printk(KERN_INFO "%s: %s%s module, %s cable%s%s\n",
-	       port_name(port), pm, dte, cable, dsr, dcd);
+	       port->dev->name, pm, dte, cable, dsr, dcd);
 
-	hdlc_set_carrier(value & STATUS_CABLE_DCD, port_to_dev(port));
+	hdlc_set_carrier(value & STATUS_CABLE_DCD, port->dev);
 }
 
 
@@ -175,7 +162,7 @@
 /* Transmit complete interrupt service */
 static inline void wanxl_tx_intr(port_t *port)
 {
-	struct net_device *dev = port_to_dev(port);
+	struct net_device *dev = port->dev;
 	struct net_device_stats *stats = hdlc_stats(dev);
 	while (1) {
                 desc_t *desc = &get_status(port)->tx_descs[port->tx_in];
@@ -210,47 +197,49 @@
 static inline void wanxl_rx_intr(card_t *card)
 {
 	desc_t *desc;
-	while(desc = &card->status->rx_descs[card->rx_in],
-	      desc->stat != PACKET_EMPTY) {
-		struct sk_buff *skb = card->rx_skbs[card->rx_in];
-		port_t *port = card->ports[desc->stat & PACKET_PORT_MASK];
-		struct net_device *dev = port_to_dev(port);
-		struct net_device_stats *stats = hdlc_stats(dev);
-
+	while (desc = &card->status->rx_descs[card->rx_in],
+	       desc->stat != PACKET_EMPTY) {
 		if ((desc->stat & PACKET_PORT_MASK) > card->n_ports)
 			printk(KERN_CRIT "wanXL %s: received packet for"
 			       " nonexistent port\n", card_name(card->pdev));
-
-		else if (!skb)
-			stats->rx_dropped++;
-
 		else {
-			pci_unmap_single(card->pdev, desc->address,
-					 BUFFER_LENGTH, PCI_DMA_FROMDEVICE);
-			skb_put(skb, desc->length);
+			struct sk_buff *skb = card->rx_skbs[card->rx_in];
+			port_t *port = &card->ports[desc->stat &
+						    PACKET_PORT_MASK];
+			struct net_device *dev = port->dev;
+			struct net_device_stats *stats = hdlc_stats(dev);
+
+			if (!skb)
+				stats->rx_dropped++;
+			else {
+				pci_unmap_single(card->pdev, desc->address,
+						 BUFFER_LENGTH,
+						 PCI_DMA_FROMDEVICE);
+				skb_put(skb, desc->length);
 
 #ifdef DEBUG_PKT
-			printk(KERN_DEBUG "%s RX(%i):", port_name(port),
-			       skb->len);
-			debug_frame(skb);
+				printk(KERN_DEBUG "%s RX(%i):", dev->name,
+				       skb->len);
+				debug_frame(skb);
 #endif
-			stats->rx_packets++;
-			stats->rx_bytes += skb->len;
-			skb->mac.raw = skb->data;
-			skb->dev = dev;
-			dev->last_rx = jiffies;
-			skb->protocol = hdlc_type_trans(skb, dev);
-			netif_rx(skb);
-			skb = NULL;
-		}
-
-		if (!skb) {
-			skb = dev_alloc_skb(BUFFER_LENGTH);
-			desc->address = skb ?
-				pci_map_single(card->pdev, skb->data,
-					       BUFFER_LENGTH,
-					       PCI_DMA_FROMDEVICE) : 0;
-			card->rx_skbs[card->rx_in] = skb;
+				stats->rx_packets++;
+				stats->rx_bytes += skb->len;
+				skb->mac.raw = skb->data;
+				skb->dev = dev;
+				dev->last_rx = jiffies;
+				skb->protocol = hdlc_type_trans(skb, dev);
+				netif_rx(skb);
+				skb = NULL;
+			}
+
+			if (!skb) {
+				skb = dev_alloc_skb(BUFFER_LENGTH);
+				desc->address = skb ?
+					pci_map_single(card->pdev, skb->data,
+						       BUFFER_LENGTH,
+						       PCI_DMA_FROMDEVICE) : 0;
+				card->rx_skbs[card->rx_in] = skb;
+			}
 		}
 		desc->stat = PACKET_EMPTY; /* Free descriptor */
 		card->rx_in = (card->rx_in + 1) % RX_QUEUE_LENGTH;
@@ -273,9 +262,9 @@
 
                 for (i = 0; i < card->n_ports; i++) {
 			if (stat & (1 << (DOORBELL_FROM_CARD_TX_0 + i)))
-				wanxl_tx_intr(card->ports[i]);
+				wanxl_tx_intr(&card->ports[i]);
 			if (stat & (1 << (DOORBELL_FROM_CARD_CABLE_0 + i)))
-				wanxl_cable_intr(card->ports[i]);
+				wanxl_cable_intr(&card->ports[i]);
 		}
 		if (stat & (1 << DOORBELL_FROM_CARD_RX))
 			wanxl_rx_intr(card);
@@ -297,8 +286,7 @@
         if (desc->stat != PACKET_EMPTY) {
                 /* should never happen - previous xmit should stop queue */
 #ifdef DEBUG_PKT
-                printk(KERN_DEBUG "%s: transmitter buffer full\n",
-		       port_name(port));
+                printk(KERN_DEBUG "%s: transmitter buffer full\n", dev->name);
 #endif
 		netif_stop_queue(dev);
 		spin_unlock_irq(&port->lock);
@@ -306,7 +294,7 @@
 	}
 
 #ifdef DEBUG_PKT
-	printk(KERN_DEBUG "%s TX(%i):", port_name(port), skb->len);
+	printk(KERN_DEBUG "%s TX(%i):", dev->name, skb->len);
 	debug_frame(skb);
 #endif
 
@@ -324,8 +312,7 @@
 	if (get_status(port)->tx_descs[port->tx_out].stat != PACKET_EMPTY) {
 		netif_stop_queue(dev);
 #ifdef DEBUG_PKT
-		printk(KERN_DEBUG "%s: transmitter buffer full\n",
-		       port_name(port));
+		printk(KERN_DEBUG "%s: transmitter buffer full\n", dev->name);
 #endif
 	}
 
@@ -417,7 +404,7 @@
 	int i;
 
 	if (get_status(port)->open) {
-		printk(KERN_ERR "%s: port already open\n", port_name(port));
+		printk(KERN_ERR "%s: port already open\n", dev->name);
 		return -EIO;
 	}
 	if ((i = hdlc_open(dev)) != 0)
@@ -435,7 +422,7 @@
 			return 0;
 	while (time_after(timeout, jiffies));
 
-	printk(KERN_ERR "%s: unable to open port\n", port_name(port));
+	printk(KERN_ERR "%s: unable to open port\n", dev->name);
 	/* ask the card to close the port, should it be still alive */
 	writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node), dbr);
 	return -EFAULT;
@@ -461,7 +448,7 @@
 	while (time_after(timeout, jiffies));
 
 	if (get_status(port)->open)
-		printk(KERN_ERR "%s: unable to close port\n", port_name(port));
+		printk(KERN_ERR "%s: unable to close port\n", dev->name);
 
 	for (i = 0; i < TX_BUFFERS; i++) {
 		desc_t *desc = &get_status(port)->tx_descs[i];
@@ -528,11 +515,10 @@
 	card_t *card = pci_get_drvdata(pdev);
 	int i;
 
-	for (i = 0; i < 4; i++)
-		if (card->ports[i]) {
-			struct net_device *dev = port_to_dev(card->ports[i]);
-			unregister_hdlc_device(dev);
-		}
+	for (i = 0; i < card->n_ports; i++) {
+		unregister_hdlc_device(card->ports[i].dev);
+		free_netdev(card->ports[i].dev);
+	}
 
 	/* unregister and free all host resources */
 	if (card->irq)
@@ -555,13 +541,10 @@
 		pci_free_consistent(pdev, sizeof(card_status_t),
 				    card->status, card->status_address);
 
-	for (i = 0; i < card->n_ports; i++)
-		if (card->__ports[i].dev)
-			free_netdev(card->__ports[i].dev);
-
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 	kfree(card);
-	pci_release_regions(pdev);
 }
 
 
@@ -599,13 +582,15 @@
 	   work on most platforms */
 	if (pci_set_consistent_dma_mask(pdev, 0x0FFFFFFF) ||
 	    pci_set_dma_mask(pdev, 0x0FFFFFFF)) {
-		printk(KERN_ERR "No usable DMA configuration\n");
+		printk(KERN_ERR "wanXL: No usable DMA configuration\n");
 		return -EIO;
 	}
 
 	i = pci_request_regions(pdev, "wanXL");
-	if (i)
+	if (i) {
+		pci_disable_device(pdev);
 		return i;
+	}
 
 	switch (pdev->device) {
 	case PCI_DEVICE_ID_SBE_WANXL100: ports = 1; break;
@@ -619,23 +604,13 @@
 		printk(KERN_ERR "wanXL %s: unable to allocate memory\n",
 		       card_name(pdev));
 		pci_release_regions(pdev);
+		pci_disable_device(pdev);
 		return -ENOBUFS;
 	}
 	memset(card, 0, alloc_size);
 
 	pci_set_drvdata(pdev, card);
 	card->pdev = pdev;
-	card->n_ports = ports;
-
-	for (i = 0; i < ports; i++) {
-		card->__ports[i].dev = alloc_hdlcdev(&card->__ports[i]);
-		if (!card->__ports[i].dev) {
-			printk(KERN_ERR "wanXL %s: unable to allocate memory\n",
-			       card_name(pdev));
-			wanxl_pci_remove_one(pdev);
-			return -ENOMEM;
-		}
-	}
 
 	card->status = pci_alloc_consistent(pdev, sizeof(card_status_t),
 					    &card->status_address);
@@ -655,7 +630,7 @@
 	   to indicate the card can do 32-bit DMA addressing */
 	if (pci_set_consistent_dma_mask(pdev, 0xFFFFFFFF) ||
 	    pci_set_dma_mask(pdev, 0xFFFFFFFF)) {
-		printk(KERN_ERR "No usable DMA configuration\n");
+		printk(KERN_ERR "wanXL: No usable DMA configuration\n");
 		wanxl_pci_remove_one(pdev);
 		return -EIO;
 	}
@@ -767,17 +742,11 @@
 	ramsize = stat;
 #endif
 
-	printk(KERN_INFO "wanXL %s: at 0x%X, %u KB of RAM at 0x%X, irq"
-	       " %u\n" KERN_INFO "wanXL %s: port", card_name(pdev),
-	       plx_phy, ramsize / 1024, mem_phy, pdev->irq, card_name(pdev));
-
-	for (i = 0; i < ports; i++)
-		printk("%s #%i: %s", i ? "," : "", i,
-		       port_name(card->ports[i]));
-	printk("\n");
+	printk(KERN_INFO "wanXL %s: at 0x%X, %u KB of RAM at 0x%X, irq %u\n",
+	       card_name(pdev), plx_phy, ramsize / 1024, mem_phy, pdev->irq);
 
 	/* Allocate IRQ */
-	if(request_irq(pdev->irq, wanxl_intr, SA_SHIRQ, "wanXL", card)) {
+	if (request_irq(pdev->irq, wanxl_intr, SA_SHIRQ, "wanXL", card)) {
 		printk(KERN_WARNING "wanXL %s: could not allocate IRQ%i.\n",
 		       card_name(pdev), pdev->irq);
 		wanxl_pci_remove_one(pdev);
@@ -786,9 +755,18 @@
 	card->irq = pdev->irq;
 
 	for (i = 0; i < ports; i++) {
-		port_t *port = &card->__ports[i];
-		struct net_device *dev = port_to_dev(port);
-		hdlc_device *hdlc = dev_to_hdlc(dev);
+		hdlc_device *hdlc;
+		port_t *port = &card->ports[i];
+		struct net_device *dev = alloc_hdlcdev(port);
+		if (!dev) {
+			printk(KERN_ERR "wanXL %s: unable to allocate"
+			       " memory\n", card_name(pdev));
+			wanxl_pci_remove_one(pdev);
+			return -ENOMEM;
+		}
+
+		port->dev = dev;
+		hdlc = dev_to_hdlc(dev);
 		spin_lock_init(&port->lock);
 		SET_MODULE_OWNER(dev);
 		dev->tx_queue_len = 50;
@@ -797,7 +775,6 @@
 		dev->stop = wanxl_close;
 		hdlc->attach = wanxl_attach;
 		hdlc->xmit = wanxl_xmit;
-		card->ports[i] = port;
 		dev->get_stats = wanxl_get_stats;
 		port->card = card;
 		port->node = i;
@@ -805,11 +782,21 @@
 		if (register_hdlc_device(dev)) {
 			printk(KERN_ERR "wanXL %s: unable to register hdlc"
 			       " device\n", card_name(pdev));
-			card->ports[i] = NULL;
+			free_netdev(dev);
 			wanxl_pci_remove_one(pdev);
 			return -ENOBUFS;
 		}
+		card->n_ports++;
 	}
+
+	printk(KERN_INFO "wanXL %s: port", card_name(pdev));
+	for (i = 0; i < ports; i++)
+		printk("%s #%i: %s", i ? "," : "", i,
+		       card->ports[i].dev->name);
+	printk("\n");
+
+	for (i = 0; i < ports; i++)
+		wanxl_cable_intr(&card->ports[i]); /* get carrier status etc.*/
 
 	return 0;
 }

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-03-08  1:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-08  0:00 2.6.x wanXL driver update Krzysztof Halasa
2004-03-08  1:20 ` Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).