From philips@ifup.org Thu Aug 2 15:28:20 2007 Message-Id: <20070802222519.849634039@ifup.org> User-Agent: quilt/0.46-1 Date: Thu, 02 Aug 2007 15:25:19 -0700 From: Brandon Philips To: netdev@vger.kernel.org Cc: teheo@suse.de Subject: [patch 0/5][RFC] Update network drivers to use devres Status: RO Content-Length: 488 Lines: 12 This patch set adds support for devres in the net core and converts the e100 and e1000 drivers to devres. Devres is a simple resource manager for device drivers, see Documentation/driver-model/devres.txt for more information. The use of devres will remain optional for drivers with this patch set. Drivers can be converted when it makes sense. Builds on top of f0a664bbd1839fbe9f57564983f39bfc6c6f931d in Linus' tree which renames __pci_reenable_device() to pci_reenable_device() -- From philips@ifup.org Thu Aug 2 15:28:20 2007 Message-Id: <20070802222820.438508815@ifup.org> References: <20070802222519.849634039@ifup.org> User-Agent: quilt/0.46-1 Date: Thu, 02 Aug 2007 15:25:20 -0700 From: Brandon Philips To: netdev@vger.kernel.org Cc: teheo@suse.de, Brandon Philips Subject: [patch 1/5][RFC] NET: Change pci_enable_device to pci_reenable_device to keep device enable balance Content-Disposition: inline; filename=net-pci-reenable-on-slot-reset.patch Status: RO Content-Length: 2552 Lines: 66 On a slot_reset event pci_disable_device() is never called so calling pci_enable_device() will unbalance the enable count. Signed-off-by: Brandon Philips --- drivers/net/e100.c | 2 +- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/ixgb/ixgb_main.c | 2 +- drivers/net/s2io.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) Index: linux-2.6/drivers/net/e100.c =================================================================== --- linux-2.6.orig/drivers/net/e100.c +++ linux-2.6/drivers/net/e100.c @@ -2828,7 +2828,7 @@ static pci_ers_result_t e100_io_slot_res struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); - if (pci_enable_device(pdev)) { + if (pci_reenable_device(pdev)) { printk(KERN_ERR "e100: Cannot re-enable PCI device after reset.\n"); return PCI_ERS_RESULT_DISCONNECT; } Index: linux-2.6/drivers/net/e1000/e1000_main.c =================================================================== --- linux-2.6.orig/drivers/net/e1000/e1000_main.c +++ linux-2.6/drivers/net/e1000/e1000_main.c @@ -5270,7 +5270,7 @@ static pci_ers_result_t e1000_io_slot_re struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev->priv; - if (pci_enable_device(pdev)) { + if (pci_reenable_device(pdev)) { printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n"); return PCI_ERS_RESULT_DISCONNECT; } Index: linux-2.6/drivers/net/ixgb/ixgb_main.c =================================================================== --- linux-2.6.orig/drivers/net/ixgb/ixgb_main.c +++ linux-2.6/drivers/net/ixgb/ixgb_main.c @@ -2294,7 +2294,7 @@ static pci_ers_result_t ixgb_io_slot_res struct net_device *netdev = pci_get_drvdata(pdev); struct ixgb_adapter *adapter = netdev_priv(netdev); - if(pci_enable_device(pdev)) { + if(pci_reenable_device(pdev)) { DPRINTK(PROBE, ERR, "Cannot re-enable PCI device after reset.\n"); return PCI_ERS_RESULT_DISCONNECT; } Index: linux-2.6/drivers/net/s2io.c =================================================================== --- linux-2.6.orig/drivers/net/s2io.c +++ linux-2.6/drivers/net/s2io.c @@ -7833,7 +7833,7 @@ static pci_ers_result_t s2io_io_slot_res struct net_device *netdev = pci_get_drvdata(pdev); struct s2io_nic *sp = netdev->priv; - if (pci_enable_device(pdev)) { + if (pci_reenable_device(pdev)) { printk(KERN_ERR "s2io: " "Cannot re-enable PCI device after reset.\n"); return PCI_ERS_RESULT_DISCONNECT; -- From philips@ifup.org Thu Aug 2 15:28:21 2007 Message-Id: <20070802222820.788857326@ifup.org> References: <20070802222519.849634039@ifup.org> User-Agent: quilt/0.46-1 Date: Thu, 02 Aug 2007 15:25:21 -0700 From: Brandon Philips To: netdev@vger.kernel.org Cc: teheo@suse.de, Brandon Philips Subject: [patch 2/5][RFC] Update net core to use devres. Content-Disposition: inline; filename=ether-core-devres.patch Status: RO Content-Length: 7821 Lines: 221 * netdev_pci_remove_one() can replace simple pci device remove functions * devm_alloc_netdev() is like alloc_netdev but allocates memory using devres. Signed-off-by: Brandon Philips --- include/linux/etherdevice.h | 5 ++ include/linux/netdevice.h | 7 ++ net/core/dev.c | 109 +++++++++++++++++++++++++++++++++++++++----- net/ethernet/eth.c | 8 +++ 4 files changed, 119 insertions(+), 10 deletions(-) Index: linux-2.6/include/linux/netdevice.h =================================================================== --- linux-2.6.orig/include/linux/netdevice.h +++ linux-2.6/include/linux/netdevice.h @@ -656,6 +656,7 @@ extern int dev_queue_xmit(struct sk_buf extern int register_netdevice(struct net_device *dev); extern void unregister_netdevice(struct net_device *dev); extern void free_netdev(struct net_device *dev); +extern void netdev_pci_remove_one(struct pci_dev *pdev); extern void synchronize_net(void); extern int register_netdevice_notifier(struct notifier_block *nb); extern int unregister_netdevice_notifier(struct notifier_block *nb); @@ -1085,8 +1086,14 @@ extern void ether_setup(struct net_devi extern struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, void (*setup)(struct net_device *), unsigned int queue_count); +extern struct net_device *devm_alloc_netdev_mq(struct device *dev, + int sizeof_priv, const char *name, + void (*setup)(struct net_device *), + unsigned int queue_count); #define alloc_netdev(sizeof_priv, name, setup) \ alloc_netdev_mq(sizeof_priv, name, setup, 1) +#define devm_alloc_netdev(dev, sizeof_priv, name, setup) \ + devm_alloc_netdev_mq(dev, sizeof_priv, name, setup, 1) extern int register_netdev(struct net_device *dev); extern void unregister_netdev(struct net_device *dev); /* Functions used for secondary unicast and multicast support */ Index: linux-2.6/net/core/dev.c =================================================================== --- linux-2.6.orig/net/core/dev.c +++ linux-2.6/net/core/dev.c @@ -89,6 +89,7 @@ #include #include #include +#include #include #include #include @@ -3658,18 +3659,51 @@ static struct net_device_stats *internal } /** - * alloc_netdev_mq - allocate network device - * @sizeof_priv: size of private data to allocate space for - * @name: device name format string - * @setup: callback to initialize device - * @queue_count: the number of subqueues to allocate + * devm_free_netdev - wrapper around free_netdev for devres + */ +static void devm_free_netdev(struct device *gendev, void *res) +{ + struct net_device *dev = dev_get_drvdata(gendev); + free_netdev(dev); +} + +/** + * register_netdev_devres - register netdev with a managed device + * @dev: devres managed device responsible for the memory + * @netdev: pointer to netdev to be managed * - * Allocates a struct net_device with private data area for driver use - * and performs basic initialization. Also allocates subquue structs - * for each queue on the device at the end of the netdevice. + * Registers @netdev to the device @dev and calls free_netdev automatically when the + * device disappears */ -struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, - void (*setup)(struct net_device *), unsigned int queue_count) +static inline void * register_netdev_devres(struct device *gendev, + struct net_device *dev) +{ + struct net_device **p; + + /* 0 size because we don't need it. The net_device is already alloc'd + * in alloc_netdev_mq. We can't use devm_kzalloc in alloc_netdeev_mq + * because a net_device cannot be free'd directly as it can be a + * kobject. See free_netdev. + */ + p = devres_alloc(devm_free_netdev, 0, GFP_KERNEL); + + if (unlikely(!p)) + return NULL; + + *p = dev; + devres_add(gendev, p); + + return dev; +} + +/** + * __alloc_netdev_mq - does the work to allocate a network device + * @dev: devres managed device responsible for mem. + * NULL if unmanaged + */ +struct net_device *__alloc_netdev_mq(struct device *gendev, int sizeof_priv, + const char *name, void (*setup)(struct net_device *), + unsigned int queue_count) { void *p; struct net_device *dev; @@ -3706,8 +3740,43 @@ struct net_device *alloc_netdev_mq(int s dev->get_stats = internal_stats; setup(dev); strcpy(dev->name, name); + + /* If we are given a device then manage this netdev with devres */ + if (gendev != NULL) + return register_netdev_devres(gendev, dev); + return dev; } + +/** + * alloc_netdev_mq - alloc_netdev_mq for devres managed devices + * @dev: devres managed device responsible for mem. + */ +struct net_device *devm_alloc_netdev_mq(struct device *dev, int sizeof_priv, const + char *name, void (*setup)(struct net_device *), + unsigned int queue_count) +{ + return __alloc_netdev_mq(dev, sizeof_priv, name, setup, queue_count); +} +EXPORT_SYMBOL(devm_alloc_netdev_mq); + +/** + * alloc_netdev_mq - allocate network device + * @sizeof_priv: size of private data to allocate space for + * @name: device name format string + * @setup: callback to initialize device + * @queue_count: the number of subqueues to allocate + * + * Allocates a struct net_device with private data area for driver use + * and performs basic initialization. Also allocates subquue structs + * for each queue on the device at the end of the netdevice. + */ +struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, + void (*setup)(struct net_device *), + unsigned int queue_count) +{ + return __alloc_netdev_mq(NULL, sizeof_priv, name, setup, queue_count); +} EXPORT_SYMBOL(alloc_netdev_mq); /** @@ -3737,6 +3806,26 @@ void free_netdev(struct net_device *dev) #endif } +#ifdef CONFIG_PCI +/** + * netdev_pci_remove_one - free network device + * @pdev: pci_dev of the device to remove + * + * Simple remove function for pci network devices with no teardown besides + * resource deallocation. + */ +void netdev_pci_remove_one(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + if (netdev) { + unregister_netdev(netdev); + pci_set_drvdata(pdev, NULL); + } +} +EXPORT_SYMBOL(netdev_pci_remove_one); +#endif + + /* Synchronize with packet receive processing. */ void synchronize_net(void) { Index: linux-2.6/include/linux/etherdevice.h =================================================================== --- linux-2.6.orig/include/linux/etherdevice.h +++ linux-2.6/include/linux/etherdevice.h @@ -40,7 +40,12 @@ extern int eth_header_cache(struct neig struct hh_cache *hh); extern struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count); +extern struct net_device *devm_alloc_etherdev_mq(struct device *dev, + int sizeof_priv, + unsigned int queue_count); #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) +#define devm_alloc_etherdev(dev, sizeof_priv) \ + devm_alloc_etherdev_mq(dev, sizeof_priv, 1) /** * is_zero_ether_addr - Determine if give Ethernet address is all zeros. Index: linux-2.6/net/ethernet/eth.c =================================================================== --- linux-2.6.orig/net/ethernet/eth.c +++ linux-2.6/net/ethernet/eth.c @@ -337,3 +337,11 @@ struct net_device *alloc_etherdev_mq(int return alloc_netdev_mq(sizeof_priv, "eth%d", ether_setup, queue_count); } EXPORT_SYMBOL(alloc_etherdev_mq); + +struct net_device *devm_alloc_etherdev_mq(struct device *dev, int sizeof_priv, + unsigned int queue_count) +{ + return devm_alloc_netdev_mq(dev, sizeof_priv, "eth%d", ether_setup, + queue_count); +} +EXPORT_SYMBOL(devm_alloc_etherdev_mq); -- From philips@ifup.org Thu Aug 2 15:28:21 2007 Message-Id: <20070802222821.172485062@ifup.org> References: <20070802222519.849634039@ifup.org> User-Agent: quilt/0.46-1 Date: Thu, 02 Aug 2007 15:25:22 -0700 From: Brandon Philips To: netdev@vger.kernel.org Cc: teheo@suse.de, Brandon Philips Subject: [patch 3/5][RFC] Update e100 driver to use devres. Content-Disposition: inline; filename=e100-devres.patch Status: RO Content-Length: 5340 Lines: 178 devres manages device resources and is currently used by all libata low level drivers. It can greatly reduce the complexity of the error handling on probe and the device removal functions. For example the e100_free() function and all of the gotos in e100_probe have been removed. Also, e100_remove() has been deleted and replaced with a much simpler netdev_pci_remove_one() function that can handle PCI net devices that don't require teardown besides resource deallocation. Signed-off-by: Brandon Philips --- drivers/net/e100.c | 70 ++++++++++++----------------------------------------- 1 file changed, 17 insertions(+), 53 deletions(-) Index: linux-2.6/drivers/net/e100.c =================================================================== --- linux-2.6.orig/drivers/net/e100.c +++ linux-2.6/drivers/net/e100.c @@ -2517,18 +2517,11 @@ static int e100_do_ioctl(struct net_devi static int e100_alloc(struct nic *nic) { - nic->mem = pci_alloc_consistent(nic->pdev, sizeof(struct mem), - &nic->dma_addr); - return nic->mem ? 0 : -ENOMEM; -} + struct device *dev = &nic->pdev->dev; -static void e100_free(struct nic *nic) -{ - if(nic->mem) { - pci_free_consistent(nic->pdev, sizeof(struct mem), - nic->mem, nic->dma_addr); - nic->mem = NULL; - } + nic->mem = dmam_alloc_coherent(dev, sizeof(struct mem), + &nic->dma_addr, GFP_ATOMIC); + return nic->mem ? 0 : -ENOMEM; } static int e100_open(struct net_device *netdev) @@ -2555,7 +2548,7 @@ static int __devinit e100_probe(struct p struct nic *nic; int err; - if(!(netdev = alloc_etherdev(sizeof(struct nic)))) { + if (!(netdev = devm_alloc_etherdev(&pdev->dev, sizeof(struct nic)))) { if(((1 << debug) - 1) & NETIF_MSG_PROBE) printk(KERN_ERR PFX "Etherdev alloc failed, abort.\n"); return -ENOMEM; @@ -2585,26 +2578,26 @@ static int __devinit e100_probe(struct p nic->msg_enable = (1 << debug) - 1; pci_set_drvdata(pdev, netdev); - if((err = pci_enable_device(pdev))) { + if ((err = pcim_enable_device(pdev))) { DPRINTK(PROBE, ERR, "Cannot enable PCI device, aborting.\n"); - goto err_out_free_dev; + return err; } if(!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { DPRINTK(PROBE, ERR, "Cannot find proper PCI device " "base address, aborting.\n"); err = -ENODEV; - goto err_out_disable_pdev; + return err; } if((err = pci_request_regions(pdev, DRV_NAME))) { DPRINTK(PROBE, ERR, "Cannot obtain PCI resources, aborting.\n"); - goto err_out_disable_pdev; + return err; } if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) { DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n"); - goto err_out_free_res; + return err; } SET_MODULE_OWNER(netdev); @@ -2613,11 +2606,11 @@ static int __devinit e100_probe(struct p if (use_io) DPRINTK(PROBE, INFO, "using i/o access mode\n"); - nic->csr = pci_iomap(pdev, (use_io ? 1 : 0), sizeof(struct csr)); + nic->csr = pcim_iomap(pdev, (use_io ? 1 : 0), sizeof(struct csr)); if(!nic->csr) { DPRINTK(PROBE, ERR, "Cannot map device registers, aborting.\n"); err = -ENOMEM; - goto err_out_free_res; + return err; } if(ent->driver_data) @@ -2650,11 +2643,11 @@ static int __devinit e100_probe(struct p if((err = e100_alloc(nic))) { DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n"); - goto err_out_iounmap; + return err; } if((err = e100_eeprom_load(nic))) - goto err_out_free; + return err; e100_phy_init(nic); @@ -2664,8 +2657,7 @@ static int __devinit e100_probe(struct p if (!eeprom_bad_csum_allow) { DPRINTK(PROBE, ERR, "Invalid MAC address from " "EEPROM, aborting.\n"); - err = -EAGAIN; - goto err_out_free; + return -EAGAIN; } else { DPRINTK(PROBE, ERR, "Invalid MAC address from EEPROM, " "you MUST configure one.\n"); @@ -2685,7 +2677,7 @@ static int __devinit e100_probe(struct p strcpy(netdev->name, "eth%d"); if((err = register_netdev(netdev))) { DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); - goto err_out_free; + return err; } DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, " @@ -2695,36 +2687,8 @@ static int __devinit e100_probe(struct p netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); return 0; - -err_out_free: - e100_free(nic); -err_out_iounmap: - pci_iounmap(pdev, nic->csr); -err_out_free_res: - pci_release_regions(pdev); -err_out_disable_pdev: - pci_disable_device(pdev); -err_out_free_dev: - pci_set_drvdata(pdev, NULL); - free_netdev(netdev); - return err; } -static void __devexit e100_remove(struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - - if(netdev) { - struct nic *nic = netdev_priv(netdev); - unregister_netdev(netdev); - e100_free(nic); - iounmap(nic->csr); - free_netdev(netdev); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - } -} #ifdef CONFIG_PM static int e100_suspend(struct pci_dev *pdev, pm_message_t state) @@ -2875,7 +2839,7 @@ static struct pci_driver e100_driver = { .name = DRV_NAME, .id_table = e100_id_table, .probe = e100_probe, - .remove = __devexit_p(e100_remove), + .remove = __devexit_p(netdev_pci_remove_one), #ifdef CONFIG_PM /* Power Management hooks */ .suspend = e100_suspend, -- From philips@ifup.org Thu Aug 2 15:28:21 2007 Message-Id: <20070802222821.542921183@ifup.org> References: <20070802222519.849634039@ifup.org> User-Agent: quilt/0.46-1 Date: Thu, 02 Aug 2007 15:25:23 -0700 From: Brandon Philips To: netdev@vger.kernel.org Cc: teheo@suse.de, Brandon Philips Subject: [patch 4/5][RFC] Implement devm_kcalloc Content-Disposition: inline; filename=kcalloc-devres.patch Status: RO Content-Length: 1711 Lines: 51 devm_kcalloc is a simple wrapper around devm_kzalloc for arrays. This is needed because kcalloc is often used in network devices. Signed-off-by: Brandon Philips --- drivers/base/devres.c | 16 ++++++++++++++++ include/linux/device.h | 1 + 2 files changed, 17 insertions(+) Index: linux-2.6/drivers/base/devres.c =================================================================== --- linux-2.6.orig/drivers/base/devres.c +++ linux-2.6/drivers/base/devres.c @@ -630,6 +630,22 @@ void * devm_kzalloc(struct device *dev, EXPORT_SYMBOL_GPL(devm_kzalloc); /** + * devm_kcalloc - resource-managed kcalloc + * @dev: Device to allocate memory for + * @n: number of elements. + * @size: element size. + * @flags: the type of memory to allocate. + */ +inline void * devm_kcalloc(struct device * dev, size_t n, size_t size, + gfp_t flags) +{ + if (n != 0 && size > ULONG_MAX / n) + return NULL; + return devm_kzalloc(dev, n * size, flags); +} +EXPORT_SYMBOL_GPL(devm_kcalloc); + +/** * devm_kfree - Resource-managed kfree * @dev: Device this memory belongs to * @p: Memory to free Index: linux-2.6/include/linux/device.h =================================================================== --- linux-2.6.orig/include/linux/device.h +++ linux-2.6/include/linux/device.h @@ -402,6 +402,7 @@ extern int devres_release_group(struct d /* managed kzalloc/kfree for device drivers, no kmalloc, always use kzalloc */ extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp); +extern void *devm_kcalloc(struct device *dev, size_t n, size_t size, gfp_t flags); extern void devm_kfree(struct device *dev, void *p); struct device { -- From philips@ifup.org Thu Aug 2 15:28:22 2007 Message-Id: <20070802222821.932316119@ifup.org> References: <20070802222519.849634039@ifup.org> User-Agent: quilt/0.46-1 Date: Thu, 02 Aug 2007 15:25:24 -0700 From: Brandon Philips To: netdev@vger.kernel.org Cc: teheo@suse.de, Brandon Philips Subject: [patch 5/5][RFC] Update e1000 driver to use devres. Content-Disposition: inline; filename=e1000-devres.patch Status: RO Content-Length: 5523 Lines: 186 Conversion of e1000 probe() and remove() to devres. Signed-off-by: Brandon Philips --- drivers/net/e1000/e1000.h | 1 drivers/net/e1000/e1000_main.c | 79 ++++++++++++----------------------------- 2 files changed, 26 insertions(+), 54 deletions(-) Index: linux-2.6/drivers/net/e1000/e1000_main.c =================================================================== --- linux-2.6.orig/drivers/net/e1000/e1000_main.c +++ linux-2.6/drivers/net/e1000/e1000_main.c @@ -868,7 +868,7 @@ e1000_probe(struct pci_dev *pdev, int i, err, pci_using_dac; uint16_t eeprom_data = 0; uint16_t eeprom_apme_mask = E1000_EEPROM_APME; - if ((err = pci_enable_device(pdev))) + if ((err = pcim_enable_device(pdev))) return err; if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) && @@ -884,14 +884,14 @@ e1000_probe(struct pci_dev *pdev, } if ((err = pci_request_regions(pdev, e1000_driver_name))) - goto err_pci_reg; + goto err_dma; pci_set_master(pdev); err = -ENOMEM; - netdev = alloc_etherdev(sizeof(struct e1000_adapter)); + netdev = devm_alloc_etherdev(&pdev->dev, sizeof(struct e1000_adapter)); if (!netdev) - goto err_alloc_etherdev; + goto err_dma; SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); @@ -907,9 +907,9 @@ e1000_probe(struct pci_dev *pdev, mmio_len = pci_resource_len(pdev, BAR_0); err = -EIO; - adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); + adapter->hw.hw_addr = devm_ioremap(&pdev->dev, mmio_start, mmio_len); if (!adapter->hw.hw_addr) - goto err_ioremap; + goto err_dma; for (i = BAR_1; i <= BAR_5; i++) { if (pci_resource_len(pdev, i) == 0) @@ -952,7 +952,7 @@ e1000_probe(struct pci_dev *pdev, /* setup the private structure */ if ((err = e1000_sw_init(adapter))) - goto err_sw_init; + goto err_dma; err = -EIO; /* Flash BAR mapping must happen after e1000_sw_init @@ -961,7 +961,9 @@ e1000_probe(struct pci_dev *pdev, (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { flash_start = pci_resource_start(pdev, 1); flash_len = pci_resource_len(pdev, 1); - adapter->hw.flash_address = ioremap(flash_start, flash_len); + adapter->hw.flash_address = devm_ioremap(&pdev->dev, + flash_start, + flash_len); if (!adapter->hw.flash_address) goto err_flashmap; } @@ -1163,27 +1165,11 @@ err_register: err_eeprom: if (!e1000_check_phy_reset_block(&adapter->hw)) e1000_phy_hw_reset(&adapter->hw); - - if (adapter->hw.flash_address) - iounmap(adapter->hw.flash_address); err_flashmap: #ifdef CONFIG_E1000_NAPI for (i = 0; i < adapter->num_rx_queues; i++) dev_put(&adapter->polling_netdev[i]); #endif - - kfree(adapter->tx_ring); - kfree(adapter->rx_ring); -#ifdef CONFIG_E1000_NAPI - kfree(adapter->polling_netdev); -#endif -err_sw_init: - iounmap(adapter->hw.hw_addr); -err_ioremap: - free_netdev(netdev); -err_alloc_etherdev: - pci_release_regions(pdev); -err_pci_reg: err_dma: pci_disable_device(pdev); return err; @@ -1224,21 +1210,6 @@ e1000_remove(struct pci_dev *pdev) if (!e1000_check_phy_reset_block(&adapter->hw)) e1000_phy_hw_reset(&adapter->hw); - - kfree(adapter->tx_ring); - kfree(adapter->rx_ring); -#ifdef CONFIG_E1000_NAPI - kfree(adapter->polling_netdev); -#endif - - iounmap(adapter->hw.hw_addr); - if (adapter->hw.flash_address) - iounmap(adapter->hw.flash_address); - pci_release_regions(pdev); - - free_netdev(netdev); - - pci_disable_device(pdev); } /** @@ -1350,27 +1321,27 @@ e1000_sw_init(struct e1000_adapter *adap static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter) { - adapter->tx_ring = kcalloc(adapter->num_tx_queues, - sizeof(struct e1000_tx_ring), GFP_KERNEL); + adapter->tx_ring = devm_kcalloc(&adapter->pdev->dev, + adapter->num_tx_queues, + sizeof(struct e1000_tx_ring), + GFP_KERNEL); if (!adapter->tx_ring) return -ENOMEM; - adapter->rx_ring = kcalloc(adapter->num_rx_queues, - sizeof(struct e1000_rx_ring), GFP_KERNEL); - if (!adapter->rx_ring) { - kfree(adapter->tx_ring); + adapter->rx_ring = devm_kcalloc(&adapter->pdev->dev, + adapter->num_rx_queues, + sizeof(struct e1000_rx_ring), + GFP_KERNEL); + if (!adapter->rx_ring) return -ENOMEM; - } #ifdef CONFIG_E1000_NAPI - adapter->polling_netdev = kcalloc(adapter->num_rx_queues, - sizeof(struct net_device), - GFP_KERNEL); - if (!adapter->polling_netdev) { - kfree(adapter->tx_ring); - kfree(adapter->rx_ring); + adapter->polling_netdev = devm_kcalloc(&adapter->pdev->dev, + adapter->num_rx_queues, + sizeof(struct net_device), + GFP_KERNEL); + if (!adapter->polling_netdev) return -ENOMEM; - } #endif return E1000_SUCCESS; @@ -5174,7 +5145,7 @@ e1000_resume(struct pci_dev *pdev) pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); - if ((err = pci_enable_device(pdev))) { + if ((err = pcim_enable_device(pdev))) { printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n"); return err; } Index: linux-2.6/drivers/net/e1000/e1000.h =================================================================== --- linux-2.6.orig/drivers/net/e1000/e1000.h +++ linux-2.6/drivers/net/e1000/e1000.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include --