From 3d7a066a273aa2f9ca8186ce37e0466d1e815f76 Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Tue, 30 Sep 2008 11:01:09 -0400 Subject: [PATCH] Fix oops in wlan_setup on 2.6.27-rc3 oops caused by not setting up network device queues. Change wlan_setup to use the kernel provided alloc_netdev() rather than hand coding it. This should help avoid any future problems. Also change register_wlandev to not call dev_alloc_name() as register_netdev() will do that if the device name has been setup. Signed-off-by: Richard Kennedy --- CHANGES | 1 + src/p80211/p80211netdev.c | 45 +++++++++++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index f286bf6..a1084c0 100644 --- a/CHANGES +++ b/CHANGES @@ -41,6 +41,7 @@ * Intersil Corporation as part of PRISM(R) chipset product development. * * -------------------------------------------------------------------- + - Fix oops due to 2.6.27 API change (Richard Kennedy) - Fix compiles with 2.6.26 (Pavel Roskin) - Add compatibility with 2.6.27+ WEXT API (Pavel Roskin) - Fix misplaced variable in PCMCIA code (Pavel Roskin) diff --git a/src/p80211/p80211netdev.c b/src/p80211/p80211netdev.c index c8d879a..7fa9b99 100644 --- a/src/p80211/p80211netdev.c +++ b/src/p80211/p80211netdev.c @@ -869,6 +869,30 @@ static int wlan_change_mtu(netdevice_t *dev, int new_mtu) return 0; } +/*--------------------------------------------------------- + * wlan_alloc_netdev + * + * create a netdev properly over different kernel versions + * this should work with kernels earlier than 2.6.26, and if + * anyone cares they can change it +----------------------------------------------------------*/ + +static inline netdevice_t * wlan_alloc_netdev() { + netdevice_t *dev; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ) + dev = alloc_netdev(0,"wlan%d",ether_setup); +#else + dev = kmalloc(sizeof(netdevice_t), GFP_ATOMIC); + if ( dev ) { + memset( dev, 0, sizeof(netdevice_t)); + ether_setup(dev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ) + dev->nd_net = &init_net; +#endif + } +#endif + return dev; +} /*---------------------------------------------------------------- @@ -911,14 +935,12 @@ int wlan_setup(wlandevice_t *wlandev) p80211netdev_rx_bh, (unsigned long)wlandev); - /* Allocate and initialize the struct device */ - dev = kmalloc(sizeof(netdevice_t), GFP_ATOMIC); + /* Allocate and initialize the struct net device */ + dev = wlan_alloc_netdev(); if ( dev == NULL ) { WLAN_LOG_ERROR("Failed to alloc netdev.\n"); result = 1; } else { - memset( dev, 0, sizeof(netdevice_t)); - ether_setup(dev); wlandev->netdev = dev; dev->priv = wlandev; dev->hard_start_xmit = p80211knetdev_hard_start_xmit; @@ -946,12 +968,6 @@ int wlan_setup(wlandevice_t *wlandev) dev->wireless_handlers = &p80211wext_handler_def; #endif #endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ) - dev_net_set(dev, &init_net); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ) - dev->nd_net = &init_net; -#endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) dev->tbusy = 1; @@ -1044,7 +1060,12 @@ int register_wlandev(wlandevice_t *wlandev) netdevice_t *dev = wlandev->netdev; DBFENTER; - +/* alloc_netdev already sets up the name */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ) + i = register_netdev(dev); + if (i) + return i; +#else i = dev_alloc_name(wlandev->netdev, "wlan%d"); if (i >= 0) { i = register_netdev(wlandev->netdev); @@ -1058,6 +1079,8 @@ int register_wlandev(wlandevice_t *wlandev) #else strcpy(wlandev->name, dev->name); #endif +#endif + #ifdef CONFIG_PROC_FS if (proc_p80211) {