netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] wan/lmc -- convert to new network device model
@ 2003-09-29 21:41 Stephen Hemminger
  2003-10-14 17:39 ` Jeff Garzik
  0 siblings, 1 reply; 2+ messages in thread
From: Stephen Hemminger @ 2003-09-29 21:41 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

Resend of LMC driver patch for 2.6.0-test6
  * do proper probing
  * allocate network device with alloc_netdev
  * use standard pci_id's instead of local defines
  * use standard PCI device interface to find and remove devices.

diff -urN -X dontdiff linux-2.5/drivers/net/wan/lmc/lmc_main.c linux-2.5-net/drivers/net/wan/lmc/lmc_main.c
--- linux-2.5/drivers/net/wan/lmc/lmc_main.c	2003-08-20 11:19:42.000000000 -0700
+++ linux-2.5-net/drivers/net/wan/lmc/lmc_main.c	2003-09-22 11:43:51.000000000 -0700
@@ -78,30 +78,22 @@
 #include "lmc_debug.h"
 #include "lmc_proto.h"
 
-
-static int Lmc_Count = 0;
-static struct net_device *Lmc_root_dev = NULL;
-static u8 cards_found = 0;
-
 static int lmc_first_load = 0;
 
-int LMC_PKT_BUF_SZ = 1542;
+static int LMC_PKT_BUF_SZ = 1542;
 
-#ifdef MODULE
 static struct pci_device_id lmc_pci_tbl[] = {
-    { 0x1011, 0x009, 0x1379, PCI_ANY_ID, 0, 0, 0},
-    { 0, }
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
+	  PCI_VENDOR_ID_LMC, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
+	  PCI_ANY_ID, PCI_VENDOR_ID_LMC },
+	{ 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, lmc_pci_tbl);
-
 MODULE_LICENSE("GPL");
-#endif
 
 
-int lmc_probe_fake(struct net_device *dev);
-static struct net_device *lmc_probe1(struct net_device *dev, unsigned long ioaddr, unsigned int irq,
-				 int chip_id, int subdevice, int board_idx);
 static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lmc_rx (struct net_device *dev);
@@ -115,12 +107,9 @@
 static void lmc_running_reset(struct net_device *dev);
 static int lmc_ifdown(struct net_device * const);
 static void lmc_watchdog(unsigned long data);
-static int lmc_init(struct net_device * const);
 static void lmc_reset(lmc_softc_t * const sc);
 static void lmc_dec_reset(lmc_softc_t * const sc);
 static void lmc_driver_timeout(struct net_device *dev);
-int lmc_setup(void);
-
 
 /*
  * linux reserves 16 device specific IOCTLs.  We call them
@@ -815,67 +804,77 @@
 
 }
 
-static int lmc_init(struct net_device * const dev) /*fold00*/
+static void lmc_setup(struct net_device * const dev) /*fold00*/
 {
-    lmc_trace(dev, "lmc_init in");
-    lmc_trace(dev, "lmc_init out");
-	
-    return 0;
+    lmc_trace(dev, "lmc_setup in");
+
+    dev->type = ARPHRD_HDLC;
+    dev->hard_start_xmit = lmc_start_xmit;
+    dev->open = lmc_open;
+    dev->stop = lmc_close;
+    dev->get_stats = lmc_get_stats;
+    dev->do_ioctl = lmc_ioctl;
+    dev->set_config = lmc_set_config;
+    dev->tx_timeout = lmc_driver_timeout;
+    dev->watchdog_timeo = (HZ); /* 1 second */
+    
+    lmc_trace(dev, "lmc_setup out");
 }
 
-/* This initializes each card from lmc_probe() */
-static struct net_device *lmc_probe1 (struct net_device *dev, unsigned long ioaddr, unsigned int irq, /*fold00*/
-                                  int chip_id, int subdevice, int board_idx)
+
+static int __devinit lmc_init_one(struct pci_dev *pdev,
+				  const struct pci_device_id *ent)
 {
-    lmc_softc_t *sc = NULL;
+    struct net_device *dev;
+    lmc_softc_t *sc;
+    u16 subdevice;
     u_int16_t AdapModelNum;
-
-    /*
-     * Allocate our own device structure
-     */
-
-    dev = kmalloc (sizeof (struct net_device)+8, GFP_KERNEL);
-    if (dev == NULL){
-        printk (KERN_ERR "lmc: kmalloc for device failed\n");
-        return NULL;
-    }
-    memset (dev, 0, sizeof (struct net_device));
-
+    int err = -ENOMEM;
+    static int cards_found;
 #ifndef GCOM
-    /*
-     *	Switch to common hdlc%d naming. We name by type not by vendor
-     */
-    
-    dev_alloc_name(dev, "hdlc%d");
+    /* We name by type not by vendor */
+    static const char lmcname[] = "hdlc%d";
 #else
-    /*
+    /* 
      * GCOM uses LMC vendor name so that clients can know which card
      * to attach to.
      */
-    dev_alloc_name(dev, "lmc%d");
+    static const char lmcname[] = "lmc%d";
 #endif
 
-    lmc_trace(dev, "lmc_probe1 in");
+
+    /*
+     * Allocate our own device structure
+     */
+    dev = alloc_netdev(sizeof(lmc_softc_t), lmcname, lmc_setup);
+    if (!dev) {
+        printk (KERN_ERR "lmc:alloc_netdev for device failed\n");
+	goto out1;
+    }
+ 
+    lmc_trace(dev, "lmc_init_one in");
+
+    err = pci_enable_device(pdev);
+    if (err) {
+	    printk(KERN_ERR "lmc: pci enable failed:%d\n", err);
+	    goto out2;
+    }
     
-    Lmc_Count++;
+    if (pci_request_regions(pdev, "lmc")) {
+	    printk(KERN_ERR "lmc: pci_request_region failed\n");
+	    err = -EIO;
+	    goto out3;
+    }
+
+    pci_set_drvdata(pdev, dev);
 
     if(lmc_first_load == 0){
-        printk(KERN_INFO "Lan Media Corporation WAN Driver Version %d.%d.%d\n",DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION,DRIVER_SUB_VERSION);
+        printk(KERN_INFO "Lan Media Corporation WAN Driver Version %d.%d.%d\n",
+	       DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION,DRIVER_SUB_VERSION);
         lmc_first_load = 1;
     }
     
-    /*
-     * Allocate space for the private data structure
-     */
-
-    sc = kmalloc (sizeof (lmc_softc_t), GFP_KERNEL);
-    if (sc == NULL) {
-        printk (KERN_WARNING "%s: Cannot allocate memory for device state\n",
-                dev->name);
-        return (NULL);
-    }
-    memset (sc, 0, sizeof (lmc_softc_t));
-    dev->priv = sc;
+    sc = dev->priv;
     sc->lmc_device = dev;
     sc->name = dev->name;
 
@@ -883,8 +882,12 @@
     /* An ioctl can cause a subsequent detach for raw frame interface */
     sc->if_type = LMC_PPP;
     sc->check = 0xBEAFCAFE;
-    dev->base_addr = ioaddr;
-    dev->irq = irq;
+    dev->base_addr = pci_resource_start(pdev, 0);
+    dev->irq = pdev->irq;
+
+    SET_MODULE_OWNER(dev);
+    SET_NETDEV_DEV(dev, &pdev->dev);
+
     /*
      * This will get the protocol layer ready and do any 1 time init's
      * Must have a valid sc and dev structure
@@ -893,19 +896,6 @@
 
     lmc_proto_attach(sc);
 
-    /* Just fill in the entries for the device */
-
-    dev->init = lmc_init;
-    dev->type = ARPHRD_HDLC;
-    dev->hard_start_xmit = lmc_start_xmit;
-    dev->open = lmc_open;
-    dev->stop = lmc_close;
-    dev->get_stats = lmc_get_stats;
-    dev->do_ioctl = lmc_ioctl;
-    dev->set_config = lmc_set_config;
-    dev->tx_timeout = lmc_driver_timeout;
-    dev->watchdog_timeo = (HZ); /* 1 second */
-    
     /*
      * Why were we changing this???
      dev->tx_queue_len = 100;
@@ -914,44 +904,45 @@
     /* Init the spin lock so can call it latter */
 
     spin_lock_init(&sc->lmc_lock);
+    pci_set_master(pdev);
 
-    printk ("%s: detected at %lx, irq %d\n", dev->name, ioaddr, dev->irq);
+    printk ("%s: detected at %lx, irq %d\n", dev->name,
+	    dev->base_addr, dev->irq);
 
     if (register_netdev (dev) != 0) {
         printk (KERN_ERR "%s: register_netdev failed.\n", dev->name);
-        lmc_proto_detach(sc);
-        kfree (dev->priv);
-        kfree (dev);
-        return NULL;
+	goto out4;
     }
 
-    /*
-     * Request the region of registers we need, so that
-     * later on, no one else will take our card away from
-     * us.
-     */
-    request_region (ioaddr, LMC_REG_RANGE, dev->name);
-
     sc->lmc_cardtype = LMC_CARDTYPE_UNKNOWN;
     sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;
 
+    /*
+     *
+     * Check either the subvendor or the subdevice, some systems reverse
+     * the setting in the bois, seems to be version and arch dependent?
+     * Fix the error, exchange the two values 
+     */
+    if ((subdevice = pdev->subsystem_device) == PCI_VENDOR_ID_LMC)
+	    subdevice = pdev->subsystem_vendor;
+
     switch (subdevice) {
-    case PCI_PRODUCT_LMC_HSSI:
+    case PCI_DEVICE_ID_LMC_HSSI:
         printk ("%s: LMC HSSI\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_HSSI;
         sc->lmc_media = &lmc_hssi_media;
         break;
-    case PCI_PRODUCT_LMC_DS3:
+    case PCI_DEVICE_ID_LMC_DS3:
         printk ("%s: LMC DS3\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_DS3;
         sc->lmc_media = &lmc_ds3_media;
         break;
-    case PCI_PRODUCT_LMC_SSI:
+    case PCI_DEVICE_ID_LMC_SSI:
         printk ("%s: LMC SSI\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_SSI;
         sc->lmc_media = &lmc_ssi_media;
         break;
-    case PCI_PRODUCT_LMC_T1:
+    case PCI_DEVICE_ID_LMC_T1:
         printk ("%s: LMC T1\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_T1;
         sc->lmc_media = &lmc_t1_media;
@@ -976,13 +967,13 @@
     AdapModelNum = (lmc_mii_readreg (sc, 0, 3) & 0x3f0) >> 4;
 
     if ((AdapModelNum == LMC_ADAP_T1
-         && subdevice == PCI_PRODUCT_LMC_T1) ||		/* detect LMC1200 */
+         && subdevice == PCI_DEVICE_ID_LMC_T1) ||	/* detect LMC1200 */
         (AdapModelNum == LMC_ADAP_SSI
-         && subdevice == PCI_PRODUCT_LMC_SSI) ||	/* detect LMC1000 */
+         && subdevice == PCI_DEVICE_ID_LMC_SSI) ||	/* detect LMC1000 */
         (AdapModelNum == LMC_ADAP_DS3
-         && subdevice == PCI_PRODUCT_LMC_DS3) ||	/* detect LMC5245 */
+         && subdevice == PCI_DEVICE_ID_LMC_DS3) ||	/* detect LMC5245 */
         (AdapModelNum == LMC_ADAP_HSSI
-         && subdevice == PCI_PRODUCT_LMC_HSSI))
+         && subdevice == PCI_DEVICE_ID_LMC_HSSI))
     {				/* detect LMC5200 */
 
     }
@@ -996,10 +987,7 @@
      */
     LMC_CSR_WRITE (sc, csr_gp_timer, 0xFFFFFFFFUL);
 
-    sc->board_idx = board_idx;
-
-    memset (&sc->stats, 0, sizeof (struct lmc_statistics));
-
+    sc->board_idx = cards_found++;
     sc->stats.check = STATCHECK;
     sc->stats.version_size = (DRIVER_VERSION << 16) +
         sizeof (struct lmc_statistics);
@@ -1008,105 +996,40 @@
     sc->lmc_ok = 0;
     sc->last_link_status = 0;
 
-    lmc_trace(dev, "lmc_probe1 out");
-
-    return dev;
-}
-
-
-/* This is the entry point.  This is what is called immediately. */
-/* This goes out and finds the card */
+    lmc_trace(dev, "lmc_init_one out");
+    return 0;
 
-int lmc_probe_fake(struct net_device *dev) /*fold00*/
-{
-    lmc_probe(NULL);
-    /* Return 1 to unloaded bogus device */
-    return 1;
+ out4:
+    lmc_proto_detach(sc);
+ out3:
+    if (pdev) {
+	    pci_release_regions(pdev);
+	    pci_set_drvdata(pdev, NULL);
+    }
+ out2:
+    free_netdev(dev);
+ out1:
+    return err;
 }
 
-int lmc_probe (struct net_device *dev) /*fold00*/
+/*
+ * Called from pci when removing module.
+ */
+static void __devexit lmc_remove_one (struct pci_dev *pdev)
 {
-    int pci_index = 0;
-    unsigned long pci_ioaddr;
-    unsigned int pci_irq_line;
-    u16 vendor, subvendor, device, subdevice;
-    u32 foundaddr = 0;
-    u8 intcf = 0;
-    struct pci_dev *pdev = NULL;
-
-    /* Loop basically until we don't find anymore. */
-    while ((pdev = pci_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) {
-	if (pci_enable_device(pdev))
-		break;
-
-        vendor = pdev->vendor;
-        device = pdev->device;
-        pci_irq_line = pdev->irq;
-        pci_ioaddr = pci_resource_start (pdev, 0);
-	subvendor = pdev->subsystem_vendor;
-	subdevice = pdev->subsystem_device;
-
-	pci_set_master (pdev);
-
-        /*
-         * Make sure it's the correct card.  CHECK SUBVENDOR ID!
-         * There are lots of tulip's out there.
-         * Also check the region of registers we will soon be
-         * poking, to make sure no one else has reserved them.
-         * This prevents taking someone else's device.
-         *
-         * Check either the subvendor or the subdevice, some systems reverse
-         * the setting in the bois, seems to be version and arch dependent?
-         * Fix the two variables
-         *
-         */
-        if (!(check_region (pci_ioaddr, LMC_REG_RANGE)) &&
-            (vendor == CORRECT_VENDOR_ID) &&
-            (device == CORRECT_DEV_ID) &&
-            ((subvendor == PCI_VENDOR_LMC)  || (subdevice == PCI_VENDOR_LMC))){
-            struct net_device *cur, *prev = NULL;
-
-            /* Fix the error, exchange the two values */
-            if(subdevice == PCI_VENDOR_LMC){
-                subdevice = subvendor;
-                subvendor = PCI_VENDOR_LMC ;
-            }
-
-            /* Make the call to actually setup this card */
-            dev = lmc_probe1 (dev, pci_ioaddr, pci_irq_line,
-                              device, subdevice, cards_found);
-            if (dev == NULL) {
-                printk ("lmc_probe: lmc_probe1 failed\n");
-                goto lmc_probe_next_card;
-            }
-            /* insert the device into the chain of lmc devices */
-            for (cur = Lmc_root_dev;
-                 cur != NULL;
-                 cur = ((lmc_softc_t *) cur->priv)->next_module) {
-                prev = cur;
-            }
-
-            if (prev == NULL)
-                Lmc_root_dev = dev;
-            else
-                ((lmc_softc_t *) prev->priv)->next_module = dev;
-
-            ((lmc_softc_t *) dev->priv)->next_module = NULL;
-            /* end insert */
-
-            foundaddr = dev->base_addr;
-
-            cards_found++;
-            intcf++;
-        }
-    lmc_probe_next_card:
-        pci_index++;
+    struct net_device *dev = pci_get_drvdata(pdev);
+    
+    if (dev) {
+	    lmc_softc_t *sc = dev->priv;
+	    
+	    printk("%s: removing...\n", dev->name);
+	    lmc_proto_detach(sc);
+	    unregister_netdev(dev);
+	    free_netdev(dev);
+	    pci_release_regions(pdev);
+	    pci_disable_device(pdev);
+	    pci_set_drvdata(pdev, NULL);
     }
-
-    if (cards_found < 1)
-        return -1;
-
-    return foundaddr;
 }
 
 /* After this is called, packets can be sent.
@@ -1181,8 +1104,6 @@
     
     sc->stats.tx_tbusy0++ ;
 
-    MOD_INC_USE_COUNT;
-
     /*
      * select what interrupts we want to get
      */
@@ -1352,7 +1273,6 @@
 
     lmc_trace(dev, "lmc_ifdown out");
 
-    MOD_DEC_USE_COUNT;
     return 0;
 }
 
@@ -1850,12 +1770,11 @@
 
 static struct net_device_stats *lmc_get_stats (struct net_device *dev) /*fold00*/
 {
-    lmc_softc_t *sc;
+    lmc_softc_t *sc = dev->priv;
     unsigned long flags;
 
     lmc_trace(dev, "lmc_get_stats in");
 
-    sc = dev->priv;
 
     spin_lock_irqsave(&sc->lmc_lock, flags);
 
@@ -1868,58 +1787,21 @@
     return (struct net_device_stats *) &sc->stats;
 }
 
+static struct pci_driver lmc_driver = {
+	.name		= "lmc",
+	.id_table	= lmc_pci_tbl,
+	.probe		= lmc_init_one,
+	.remove		= __devexit_p(lmc_remove_one),
+};
+
 static int __init init_lmc(void)
 {
-    printk ("lmc: module loaded\n");
-
-    /* Have lmc_probe search for all the cards, and allocate devices */
-    if (lmc_probe (NULL) < 0)
-        return -EIO;
-
-    return 0;
+    return pci_module_init(&lmc_driver);
 }
 
 static void __exit exit_lmc(void)
 {
-    struct net_device *dev, *next;
-    lmc_softc_t *sc;
-
-    /* we have no pointer to our devices, since they are all dynamically
-     * allocated.  So, here we loop through all the network devices
-     * looking for ours.  When found, dispose of them properly.
-     */
-
-    for (dev = Lmc_root_dev;
-         dev != NULL;
-         dev = next )
-    {
-
-        next = ((lmc_softc_t *) dev->priv)->next_module; /* get it now before we deallocate it */
-        printk ("%s: removing...\n", dev->name);
-
-        /* close the syncppp stuff, and release irq. Close is run on unreg net */
-        lmc_close (dev);
-	sc = dev->priv;
-        if (sc != NULL)
-            lmc_proto_detach(sc);
-
-        /* Remove the device from the linked list */
-        unregister_netdev (dev);
-
-        /* Let go of the io region */;
-        release_region (dev->base_addr, LMC_REG_RANGE);
-
-        /* free our allocated structures. */
-        kfree (dev->priv);
-        dev->priv = NULL;
-
-        free_netdev (dev);
-        dev = NULL;
-    }
-
-
-    Lmc_root_dev = NULL;
-    printk ("lmc module unloaded\n");
+    pci_unregister_driver(&lmc_driver);
 }
 
 module_init(init_lmc);
@@ -2326,8 +2208,3 @@
 
 
 }
-
-int lmc_setup(void) { /*FOLD00*/
-   return lmc_probe(NULL);
-}
-
diff -urN -X dontdiff linux-2.5/drivers/net/wan/lmc/lmc_var.h linux-2.5-net/drivers/net/wan/lmc/lmc_var.h
--- linux-2.5/drivers/net/wan/lmc/lmc_var.h	2003-06-05 10:04:38.000000000 -0700
+++ linux-2.5-net/drivers/net/wan/lmc/lmc_var.h	2003-09-22 11:43:46.000000000 -0700
@@ -390,7 +390,7 @@
 	struct timer_list	timer;
 	lmc_ctl_t		ictl;
 	u_int32_t		TxDescriptControlInit;  
-	struct net_device		*next_module;   /* Link to the next module  */
+
 	int                     tx_TimeoutInd; /* additional driver state */
 	int                     tx_TimeoutDisplay;
 	unsigned int		lastlmc_taint_tx;
@@ -519,18 +519,7 @@
 #define TULIP_CMD_RECEIVEALL 0x40000000L
 #endif
 
-
-/* PCI register values */
-#define CORRECT_VENDOR_ID    0x1011
-#define CORRECT_DEV_ID       9
-
-#define PCI_VENDOR_LMC		0x1376
-#define PCI_PRODUCT_LMC_HSSI	0x0003
-#define PCI_PRODUCT_LMC_DS3	0x0004
-#define PCI_PRODUCT_LMC_SSI	0x0005
-#define PCI_PRODUCT_LMC_T1      0x0006
-
-/* Adapcter module number */
+/* Adapter module number */
 #define LMC_ADAP_HSSI           2
 #define LMC_ADAP_DS3            3
 #define LMC_ADAP_SSI            4

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

end of thread, other threads:[~2003-10-14 17:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-09-29 21:41 [PATCH] wan/lmc -- convert to new network device model Stephen Hemminger
2003-10-14 17:39 ` 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).