diff options
author | Michal Schmidt <mschmidt@redhat.com> | 2007-06-29 09:33:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2007-07-10 14:11:28 -0400 |
commit | 1c2b7db8c8c4212761fcb5190a4122afd5e02d58 (patch) | |
tree | 8f75f7af1bef648234ce832c0c78e40374b79111 /drivers/net/wireless/airo.c | |
parent | 777ec5e9cec521af617fc52a1c1ae24f68f4a43b (diff) |
[PATCH] airo: delay some initialization until the netdev is up
airo's kernel thread and the IRQ handler are needed only when the interface
is up.
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/airo.c')
-rw-r--r-- | drivers/net/wireless/airo.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 57da70b07f1f..d675d984c85d 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -1926,28 +1926,55 @@ static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) { | |||
1926 | return rc; | 1926 | return rc; |
1927 | } | 1927 | } |
1928 | 1928 | ||
1929 | static void try_auto_wep(struct airo_info *ai) | ||
1930 | { | ||
1931 | if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) { | ||
1932 | ai->expires = RUN_AT(3*HZ); | ||
1933 | wake_up_interruptible(&ai->thr_wait); | ||
1934 | } | ||
1935 | } | ||
1936 | |||
1929 | static int airo_open(struct net_device *dev) { | 1937 | static int airo_open(struct net_device *dev) { |
1930 | struct airo_info *info = dev->priv; | 1938 | struct airo_info *ai = dev->priv; |
1931 | Resp rsp; | 1939 | Resp rsp; |
1940 | int rc = 0; | ||
1932 | 1941 | ||
1933 | if (test_bit(FLAG_FLASHING, &info->flags)) | 1942 | if (test_bit(FLAG_FLASHING, &ai->flags)) |
1934 | return -EIO; | 1943 | return -EIO; |
1935 | 1944 | ||
1936 | /* Make sure the card is configured. | 1945 | /* Make sure the card is configured. |
1937 | * Wireless Extensions may postpone config changes until the card | 1946 | * Wireless Extensions may postpone config changes until the card |
1938 | * is open (to pipeline changes and speed-up card setup). If | 1947 | * is open (to pipeline changes and speed-up card setup). If |
1939 | * those changes are not yet commited, do it now - Jean II */ | 1948 | * those changes are not yet commited, do it now - Jean II */ |
1940 | if (test_bit (FLAG_COMMIT, &info->flags)) { | 1949 | if (test_bit(FLAG_COMMIT, &ai->flags)) { |
1941 | disable_MAC(info, 1); | 1950 | disable_MAC(ai, 1); |
1942 | writeConfigRid(info, 1); | 1951 | writeConfigRid(ai, 1); |
1943 | } | 1952 | } |
1944 | 1953 | ||
1945 | if (info->wifidev != dev) { | 1954 | if (ai->wifidev != dev) { |
1955 | clear_bit(JOB_DIE, &ai->jobs); | ||
1956 | ai->airo_thread_task = kthread_run(airo_thread, dev, dev->name); | ||
1957 | if (IS_ERR(ai->airo_thread_task)) | ||
1958 | return (int)PTR_ERR(ai->airo_thread_task); | ||
1959 | |||
1960 | rc = request_irq(dev->irq, airo_interrupt, IRQF_SHARED, | ||
1961 | dev->name, dev); | ||
1962 | if (rc) { | ||
1963 | airo_print_err(dev->name, | ||
1964 | "register interrupt %d failed, rc %d", | ||
1965 | dev->irq, rc); | ||
1966 | set_bit(JOB_DIE, &ai->jobs); | ||
1967 | kthread_stop(ai->airo_thread_task); | ||
1968 | return rc; | ||
1969 | } | ||
1970 | |||
1946 | /* Power on the MAC controller (which may have been disabled) */ | 1971 | /* Power on the MAC controller (which may have been disabled) */ |
1947 | clear_bit(FLAG_RADIO_DOWN, &info->flags); | 1972 | clear_bit(FLAG_RADIO_DOWN, &ai->flags); |
1948 | enable_interrupts(info); | 1973 | enable_interrupts(ai); |
1974 | |||
1975 | try_auto_wep(ai); | ||
1949 | } | 1976 | } |
1950 | enable_MAC(info, &rsp, 1); | 1977 | enable_MAC(ai, &rsp, 1); |
1951 | 1978 | ||
1952 | netif_start_queue(dev); | 1979 | netif_start_queue(dev); |
1953 | return 0; | 1980 | return 0; |
@@ -2392,6 +2419,11 @@ static int airo_close(struct net_device *dev) { | |||
2392 | disable_MAC(ai, 1); | 2419 | disable_MAC(ai, 1); |
2393 | #endif | 2420 | #endif |
2394 | disable_interrupts( ai ); | 2421 | disable_interrupts( ai ); |
2422 | |||
2423 | free_irq(dev->irq, dev); | ||
2424 | |||
2425 | set_bit(JOB_DIE, &ai->jobs); | ||
2426 | kthread_stop(ai->airo_thread_task); | ||
2395 | } | 2427 | } |
2396 | return 0; | 2428 | return 0; |
2397 | } | 2429 | } |
@@ -2403,7 +2435,6 @@ void stop_airo_card( struct net_device *dev, int freeres ) | |||
2403 | set_bit(FLAG_RADIO_DOWN, &ai->flags); | 2435 | set_bit(FLAG_RADIO_DOWN, &ai->flags); |
2404 | disable_MAC(ai, 1); | 2436 | disable_MAC(ai, 1); |
2405 | disable_interrupts(ai); | 2437 | disable_interrupts(ai); |
2406 | free_irq( dev->irq, dev ); | ||
2407 | takedown_proc_entry( dev, ai ); | 2438 | takedown_proc_entry( dev, ai ); |
2408 | if (test_bit(FLAG_REGISTERED, &ai->flags)) { | 2439 | if (test_bit(FLAG_REGISTERED, &ai->flags)) { |
2409 | unregister_netdev( dev ); | 2440 | unregister_netdev( dev ); |
@@ -2414,9 +2445,6 @@ void stop_airo_card( struct net_device *dev, int freeres ) | |||
2414 | } | 2445 | } |
2415 | clear_bit(FLAG_REGISTERED, &ai->flags); | 2446 | clear_bit(FLAG_REGISTERED, &ai->flags); |
2416 | } | 2447 | } |
2417 | set_bit(JOB_DIE, &ai->jobs); | ||
2418 | kthread_stop(ai->airo_thread_task); | ||
2419 | |||
2420 | /* | 2448 | /* |
2421 | * Clean out tx queue | 2449 | * Clean out tx queue |
2422 | */ | 2450 | */ |
@@ -2821,14 +2849,11 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2821 | ai->config.len = 0; | 2849 | ai->config.len = 0; |
2822 | ai->pci = pci; | 2850 | ai->pci = pci; |
2823 | init_waitqueue_head (&ai->thr_wait); | 2851 | init_waitqueue_head (&ai->thr_wait); |
2824 | ai->airo_thread_task = kthread_run(airo_thread, dev, dev->name); | ||
2825 | if (IS_ERR(ai->airo_thread_task)) | ||
2826 | goto err_out_free; | ||
2827 | ai->tfm = NULL; | 2852 | ai->tfm = NULL; |
2828 | add_airo_dev(ai); | 2853 | add_airo_dev(ai); |
2829 | 2854 | ||
2830 | if (airo_networks_allocate (ai)) | 2855 | if (airo_networks_allocate (ai)) |
2831 | goto err_out_thr; | 2856 | goto err_out_free; |
2832 | airo_networks_initialize (ai); | 2857 | airo_networks_initialize (ai); |
2833 | 2858 | ||
2834 | /* The Airo-specific entries in the device structure. */ | 2859 | /* The Airo-specific entries in the device structure. */ |
@@ -2851,21 +2876,16 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2851 | dev->base_addr = port; | 2876 | dev->base_addr = port; |
2852 | 2877 | ||
2853 | SET_NETDEV_DEV(dev, dmdev); | 2878 | SET_NETDEV_DEV(dev, dmdev); |
2879 | SET_MODULE_OWNER(dev); | ||
2854 | 2880 | ||
2855 | reset_card (dev, 1); | 2881 | reset_card (dev, 1); |
2856 | msleep(400); | 2882 | msleep(400); |
2857 | 2883 | ||
2858 | rc = request_irq( dev->irq, airo_interrupt, IRQF_SHARED, dev->name, dev ); | ||
2859 | if (rc) { | ||
2860 | airo_print_err(dev->name, "register interrupt %d failed, rc %d", | ||
2861 | irq, rc); | ||
2862 | goto err_out_nets; | ||
2863 | } | ||
2864 | if (!is_pcmcia) { | 2884 | if (!is_pcmcia) { |
2865 | if (!request_region( dev->base_addr, 64, dev->name )) { | 2885 | if (!request_region( dev->base_addr, 64, dev->name )) { |
2866 | rc = -EBUSY; | 2886 | rc = -EBUSY; |
2867 | airo_print_err(dev->name, "Couldn't request region"); | 2887 | airo_print_err(dev->name, "Couldn't request region"); |
2868 | goto err_out_irq; | 2888 | goto err_out_nets; |
2869 | } | 2889 | } |
2870 | } | 2890 | } |
2871 | 2891 | ||
@@ -2921,8 +2941,6 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2921 | if (setup_proc_entry(dev, dev->priv) < 0) | 2941 | if (setup_proc_entry(dev, dev->priv) < 0) |
2922 | goto err_out_wifi; | 2942 | goto err_out_wifi; |
2923 | 2943 | ||
2924 | netif_start_queue(dev); | ||
2925 | SET_MODULE_OWNER(dev); | ||
2926 | return dev; | 2944 | return dev; |
2927 | 2945 | ||
2928 | err_out_wifi: | 2946 | err_out_wifi: |
@@ -2940,14 +2958,9 @@ err_out_map: | |||
2940 | err_out_res: | 2958 | err_out_res: |
2941 | if (!is_pcmcia) | 2959 | if (!is_pcmcia) |
2942 | release_region( dev->base_addr, 64 ); | 2960 | release_region( dev->base_addr, 64 ); |
2943 | err_out_irq: | ||
2944 | free_irq(dev->irq, dev); | ||
2945 | err_out_nets: | 2961 | err_out_nets: |
2946 | airo_networks_free(ai); | 2962 | airo_networks_free(ai); |
2947 | err_out_thr: | ||
2948 | del_airo_dev(ai); | 2963 | del_airo_dev(ai); |
2949 | set_bit(JOB_DIE, &ai->jobs); | ||
2950 | kthread_stop(ai->airo_thread_task); | ||
2951 | err_out_free: | 2964 | err_out_free: |
2952 | free_netdev(dev); | 2965 | free_netdev(dev); |
2953 | return NULL; | 2966 | return NULL; |
@@ -3919,10 +3932,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) | |||
3919 | rc = readWepKeyRid(ai, &wkr, 0, lock); | 3932 | rc = readWepKeyRid(ai, &wkr, 0, lock); |
3920 | } while(lastindex != wkr.kindex); | 3933 | } while(lastindex != wkr.kindex); |
3921 | 3934 | ||
3922 | if (auto_wep) { | 3935 | try_auto_wep(ai); |
3923 | ai->expires = RUN_AT(3*HZ); | ||
3924 | wake_up_interruptible(&ai->thr_wait); | ||
3925 | } | ||
3926 | 3936 | ||
3927 | return SUCCESS; | 3937 | return SUCCESS; |
3928 | } | 3938 | } |