From cb7faa938003cd4cb4362daa07502c219230ddcc Mon Sep 17 00:00:00 2001
From: Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk>
Date: Sat, 10 Jan 2004 06:10:43 -0500
Subject: [PATCH] [netdrvr axnet_cs] use embedded private struct

---
 drivers/net/pcmcia/axnet_cs.c | 139 ++++++++++++++--------------------
 1 file changed, 57 insertions(+), 82 deletions(-)

diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index eab0bd986469..1eeb3531f936 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -119,7 +119,7 @@ static void axnet_detach(dev_link_t *);
 static dev_info_t dev_info = "axnet_cs";
 static dev_link_t *dev_list;
 
-static int axdev_init(struct net_device *dev);
+static void axdev_setup(struct net_device *dev);
 static void AX88190_init(struct net_device *dev, int startp);
 static int ax_open(struct net_device *dev);
 static int ax_close(struct net_device *dev);
@@ -128,7 +128,6 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 /*====================================================================*/
 
 typedef struct axnet_dev_t {
-    struct net_device	dev;	/* so &dev == &axnet_dev_t */
     dev_link_t		link;
     dev_node_t		node;
     caddr_t		base;
@@ -140,16 +139,10 @@ typedef struct axnet_dev_t {
     int			flags;
 } axnet_dev_t;
 
-/*======================================================================
-
-    We never need to do anything when a axnet device is "initialized"
-    by the net software, because we only register already-found cards.
-
-======================================================================*/
-
-static int axnet_init(struct net_device *dev)
+static inline axnet_dev_t *PRIV(struct net_device *dev)
 {
-    return 0;
+	void *p = (char *)netdev_priv(dev) + sizeof(struct ei_device);
+	return p;
 }
 
 /*======================================================================
@@ -170,12 +163,15 @@ static dev_link_t *axnet_attach(void)
 
     DEBUG(0, "axnet_attach()\n");
 
-    /* Create new ethernet device */
-    info = kmalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
-    memset(info, 0, sizeof(*info));
-    link = &info->link; dev = &info->dev;
-    link->priv = info;
+    dev = alloc_netdev(sizeof(struct ei_device) + sizeof(axnet_dev_t),
+			"eth%d", axdev_setup);
+
+    if (!dev)
+	return NULL;
+
+    info = PRIV(dev);
+    link = &info->link;
+    link->priv = dev;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
     if (irq_list[0] == -1)
@@ -186,8 +182,6 @@ static dev_link_t *axnet_attach(void)
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    axdev_init(dev);
-    dev->init = &axnet_init;
     dev->open = &axnet_open;
     dev->stop = &axnet_close;
     dev->do_ioctl = &axnet_ioctl;
@@ -226,7 +220,7 @@ static dev_link_t *axnet_attach(void)
 
 static void axnet_detach(dev_link_t *link)
 {
-    axnet_dev_t *info = link->priv;
+    struct net_device *dev = link->priv;
     dev_link_t **linkp;
 
     DEBUG(0, "axnet_detach(0x%p)\n", link);
@@ -245,12 +239,9 @@ static void axnet_detach(dev_link_t *link)
 
     /* Unlink device structure, free bits */
     *linkp = link->next;
-    if (link->dev) {
-	unregister_netdev(&info->dev);
-	free_netdev(&info->dev);
-    } else
-	kfree(info);
-
+    if (link->dev)
+	unregister_netdev(dev);
+    free_netdev(dev);
 } /* axnet_detach */
 
 /*======================================================================
@@ -349,8 +340,8 @@ static int try_io_port(dev_link_t *link)
 static void axnet_config(dev_link_t *link)
 {
     client_handle_t handle = link->handle;
-    axnet_dev_t *info = link->priv;
-    struct net_device *dev = &info->dev;
+    struct net_device *dev = link->priv;
+    axnet_dev_t *info = PRIV(dev);
     tuple_t tuple;
     cisparse_t parse;
     int i, j, last_ret, last_fn;
@@ -425,15 +416,10 @@ static void axnet_config(dev_link_t *link)
     CS_CHECK(RequestConfiguration, handle, &link->conf);
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
-    if (register_netdev(dev) != 0) {
-	printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
-	goto failed;
-    }
 
     if (!get_prom(link)) {
 	printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n");
 	printk(KERN_NOTICE "axnet_cs: use pcnet_cs instead.\n");
-	unregister_netdev(dev);
 	goto failed;
     }
 
@@ -448,7 +434,6 @@ static void axnet_config(dev_link_t *link)
     ei_status.block_output = &block_output;
 
     strcpy(info->node.dev_name, dev->name);
-    link->dev = &info->node;
 
     if (inb(dev->base_addr + AXNET_TEST) != 0)
 	info->flags |= IS_AX88790;
@@ -487,6 +472,12 @@ static void axnet_config(dev_link_t *link)
 	printk(KERN_NOTICE "  No MII transceivers found!\n");
     }
 
+    if (register_netdev(dev) != 0) {
+	printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
+	goto failed;
+    }
+
+    link->dev = &info->node;
     link->state &= ~DEV_CONFIG_PENDING;
     return;
 
@@ -530,7 +521,7 @@ static int axnet_event(event_t event, int priority,
 		       event_callback_args_t *args)
 {
     dev_link_t *link = args->client_data;
-    axnet_dev_t *info = link->priv;
+    struct net_device *dev = link->priv;
 
     DEBUG(2, "axnet_event(0x%06x)\n", event);
 
@@ -538,7 +529,7 @@ static int axnet_event(event_t event, int priority,
     case CS_EVENT_CARD_REMOVAL:
 	link->state &= ~DEV_PRESENT;
 	if (link->state & DEV_CONFIG) {
-	    netif_device_detach(&info->dev);
+	    netif_device_detach(dev);
 	    axnet_release(link);
 	}
 	break;
@@ -552,7 +543,7 @@ static int axnet_event(event_t event, int priority,
     case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
 	    if (link->open)
-		netif_device_detach(&info->dev);
+		netif_device_detach(dev);
 	    CardServices(ReleaseConfiguration, link->handle);
 	}
 	break;
@@ -563,9 +554,9 @@ static int axnet_event(event_t event, int priority,
 	if (link->state & DEV_CONFIG) {
 	    CardServices(RequestConfiguration, link->handle, &link->conf);
 	    if (link->open) {
-		axnet_reset_8390(&info->dev);
-		AX88190_init(&info->dev, 1);
-		netif_device_attach(&info->dev);
+		axnet_reset_8390(dev);
+		AX88190_init(dev, 1);
+		netif_device_attach(dev);
 	    }
 	}
 	break;
@@ -635,7 +626,7 @@ static void mdio_write(ioaddr_t addr, int phy_id, int loc, int value)
 
 static int axnet_open(struct net_device *dev)
 {
-    axnet_dev_t *info = (axnet_dev_t *)dev;
+    axnet_dev_t *info = PRIV(dev);
     dev_link_t *link = &info->link;
     
     DEBUG(2, "axnet_open('%s')\n", dev->name);
@@ -650,7 +641,7 @@ static int axnet_open(struct net_device *dev)
     info->link_status = 0x00;
     init_timer(&info->watchdog);
     info->watchdog.function = &ei_watchdog;
-    info->watchdog.data = (u_long)info;
+    info->watchdog.data = (u_long)dev;
     info->watchdog.expires = jiffies + HZ;
     add_timer(&info->watchdog);
 
@@ -661,7 +652,7 @@ static int axnet_open(struct net_device *dev)
 
 static int axnet_close(struct net_device *dev)
 {
-    axnet_dev_t *info = (axnet_dev_t *)dev;
+    axnet_dev_t *info = PRIV(dev);
     dev_link_t *link = &info->link;
 
     DEBUG(2, "axnet_close('%s')\n", dev->name);
@@ -711,15 +702,15 @@ static void axnet_reset_8390(struct net_device *dev)
 
 static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
 {
-    axnet_dev_t *info = dev_id;
-    info->stale = 0;
+    struct net_device *dev = dev_id;
+    PRIV(dev)->stale = 0;
     return ax_interrupt(irq, dev_id, regs);
 }
 
 static void ei_watchdog(u_long arg)
 {
-    axnet_dev_t *info = (axnet_dev_t *)(arg);
-    struct net_device *dev = &info->dev;
+    struct net_device *dev = (struct net_device *)(arg);
+    axnet_dev_t *info = PRIV(dev);
     ioaddr_t nic_base = dev->base_addr;
     ioaddr_t mii_addr = nic_base + AXNET_MII_EEP;
     u_short link;
@@ -789,7 +780,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
 
 static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-    axnet_dev_t *info = (axnet_dev_t *)dev;
+    axnet_dev_t *info = PRIV(dev);
     u16 *data = (u16 *)&rq->ifr_data;
     ioaddr_t mii_addr = dev->base_addr + AXNET_MII_EEP;
     switch (cmd) {
@@ -1038,14 +1029,7 @@ static void do_set_multicast_list(struct net_device *dev);
 static int ax_open(struct net_device *dev)
 {
 	unsigned long flags;
-	struct ei_device *ei_local = (struct ei_device *) dev->priv;
-
-	/* This can't happen unless somebody forgot to call axdev_init(). */
-	if (ei_local == NULL) 
-	{
-		printk(KERN_EMERG "%s: ax_open passed a non-existent device!\n", dev->name);
-		return -ENXIO;
-	}
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 
 #ifdef HAVE_TX_TIMEOUT
 	/* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout
@@ -1071,7 +1055,7 @@ static int ax_open(struct net_device *dev)
 	return 0;
 }
 
-#define dev_lock(dev) (((struct ei_device *)(dev)->priv)->page_lock)
+#define dev_lock(dev) (((struct ei_device *)netdev_priv(dev))->page_lock)
 
 /**
  * ax_close - shut down network device
@@ -1105,7 +1089,7 @@ int ax_close(struct net_device *dev)
 void ei_tx_timeout(struct net_device *dev)
 {
 	long e8390_base = dev->base_addr;
-	struct ei_device *ei_local = (struct ei_device *) dev->priv;
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 	int txsr, isr, tickssofar = jiffies - dev->trans_start;
 	unsigned long flags;
 
@@ -1151,7 +1135,7 @@ void ei_tx_timeout(struct net_device *dev)
 static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	long e8390_base = dev->base_addr;
-	struct ei_device *ei_local = (struct ei_device *) dev->priv;
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 	int length, send_length, output_page;
 	unsigned long flags;
 	u8 packet[ETH_ZLEN];
@@ -1297,7 +1281,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 	}
     
 	e8390_base = dev->base_addr;
-	ei_local = (struct ei_device *) dev->priv;
+	ei_local = (struct ei_device *) netdev_priv(dev);
 
 	/*
 	 *	Protect the irq test too.
@@ -1409,7 +1393,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 static void ei_tx_err(struct net_device *dev)
 {
 	long e8390_base = dev->base_addr;
-	struct ei_device *ei_local = (struct ei_device *) dev->priv;
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 	unsigned char txsr = inb_p(e8390_base+EN0_TSR);
 	unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
 
@@ -1450,7 +1434,7 @@ static void ei_tx_err(struct net_device *dev)
 static void ei_tx_intr(struct net_device *dev)
 {
 	long e8390_base = dev->base_addr;
-	struct ei_device *ei_local = (struct ei_device *) dev->priv;
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 	int status = inb(e8390_base + EN0_TSR);
     
 	/*
@@ -1531,7 +1515,7 @@ static void ei_tx_intr(struct net_device *dev)
 static void ei_receive(struct net_device *dev)
 {
 	long e8390_base = dev->base_addr;
-	struct ei_device *ei_local = (struct ei_device *) dev->priv;
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 	unsigned char rxing_page, this_frame, next_frame;
 	unsigned short current_offset;
 	int rx_pkt_count = 0;
@@ -1651,7 +1635,7 @@ static void ei_rx_overrun(struct net_device *dev)
 	axnet_dev_t *info = (axnet_dev_t *)dev;
 	long e8390_base = dev->base_addr;
 	unsigned char was_txing, must_resend = 0;
-	struct ei_device *ei_local = (struct ei_device *) dev->priv;
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
     
 	/*
 	 * Record whether a Tx was in progress and then issue the
@@ -1718,7 +1702,7 @@ static void ei_rx_overrun(struct net_device *dev)
 static struct net_device_stats *get_stats(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
-	struct ei_device *ei_local = (struct ei_device *) dev->priv;
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 	unsigned long flags;
     
 	/* If the card is stopped, just return the present stats. */
@@ -1771,39 +1755,30 @@ static void set_multicast_list(struct net_device *dev)
 }	
 
 /**
- * axdev_init - init rest of 8390 device struct
+ * axdev_setup - init rest of 8390 device struct
  * @dev: network device structure to init
  *
  * Initialize the rest of the 8390 device structure.  Do NOT __init
  * this, as it is used by 8390 based modular drivers too.
  */
 
-static int axdev_init(struct net_device *dev)
+static void axdev_setup(struct net_device *dev)
 {
+	struct ei_device *ei_local;
 	if (ei_debug > 1)
 		printk(version_8390);
     
 	SET_MODULE_OWNER(dev);
 
-	if (dev->priv == NULL) 
-	{
-		struct ei_device *ei_local;
 		
-		dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL);
-		if (dev->priv == NULL)
-			return -ENOMEM;
-		memset(dev->priv, 0, sizeof(struct ei_device));
-		ei_local = (struct ei_device *)dev->priv;
-		spin_lock_init(&ei_local->page_lock);
-	}
+	ei_local = (struct ei_device *)netdev_priv(dev);
+	spin_lock_init(&ei_local->page_lock);
     
 	dev->hard_start_xmit = &ei_start_xmit;
 	dev->get_stats	= get_stats;
 	dev->set_multicast_list = &set_multicast_list;
 
 	ether_setup(dev);
-        
-	return 0;
 }
 
 /* This page of functions should be 8390 generic */
@@ -1819,9 +1794,9 @@ static int axdev_init(struct net_device *dev)
 
 static void AX88190_init(struct net_device *dev, int startp)
 {
-	axnet_dev_t *info = (axnet_dev_t *)dev;
+	axnet_dev_t *info = PRIV(dev);
 	long e8390_base = dev->base_addr;
-	struct ei_device *ei_local = (struct ei_device *) dev->priv;
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
 	int i;
 	int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48;
     
@@ -1890,7 +1865,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
 								int start_page)
 {
 	long e8390_base = dev->base_addr;
- 	struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) dev->priv;
+ 	struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev);
     
 	if (inb_p(e8390_base) & E8390_TRANS) 
 	{
-- 
2.30.9