[PATCH] airo: delay some initialization until the netdev is up
authorMichal Schmidt <mschmidt@redhat.com>
Fri, 29 Jun 2007 13:33:36 +0000 (15:33 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 10 Jul 2007 18:11:28 +0000 (14:11 -0400)
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>
drivers/net/wireless/airo.c

index 57da70b07f1f90acdc430b51871dd6a0de35be7c..d675d984c85d780ae22c1448ae0b3b780a94ff61 100644 (file)
@@ -1926,28 +1926,55 @@ static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) {
        return rc;
 }
 
+static void try_auto_wep(struct airo_info *ai)
+{
+       if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) {
+               ai->expires = RUN_AT(3*HZ);
+               wake_up_interruptible(&ai->thr_wait);
+       }
+}
+
 static int airo_open(struct net_device *dev) {
-       struct airo_info *info = dev->priv;
+       struct airo_info *ai = dev->priv;
        Resp rsp;
+       int rc = 0;
 
-       if (test_bit(FLAG_FLASHING, &info->flags))
+       if (test_bit(FLAG_FLASHING, &ai->flags))
                return -EIO;
 
        /* Make sure the card is configured.
         * Wireless Extensions may postpone config changes until the card
         * is open (to pipeline changes and speed-up card setup). If
         * those changes are not yet commited, do it now - Jean II */
-       if (test_bit (FLAG_COMMIT, &info->flags)) {
-               disable_MAC(info, 1);
-               writeConfigRid(info, 1);
+       if (test_bit(FLAG_COMMIT, &ai->flags)) {
+               disable_MAC(ai, 1);
+               writeConfigRid(ai, 1);
        }
 
-       if (info->wifidev != dev) {
+       if (ai->wifidev != dev) {
+               clear_bit(JOB_DIE, &ai->jobs);
+               ai->airo_thread_task = kthread_run(airo_thread, dev, dev->name);
+               if (IS_ERR(ai->airo_thread_task))
+                       return (int)PTR_ERR(ai->airo_thread_task);
+
+               rc = request_irq(dev->irq, airo_interrupt, IRQF_SHARED,
+                       dev->name, dev);
+               if (rc) {
+                       airo_print_err(dev->name,
+                               "register interrupt %d failed, rc %d",
+                               dev->irq, rc);
+                       set_bit(JOB_DIE, &ai->jobs);
+                       kthread_stop(ai->airo_thread_task);
+                       return rc;
+               }
+
                /* Power on the MAC controller (which may have been disabled) */
-               clear_bit(FLAG_RADIO_DOWN, &info->flags);
-               enable_interrupts(info);
+               clear_bit(FLAG_RADIO_DOWN, &ai->flags);
+               enable_interrupts(ai);
+
+               try_auto_wep(ai);
        }
-       enable_MAC(info, &rsp, 1);
+       enable_MAC(ai, &rsp, 1);
 
        netif_start_queue(dev);
        return 0;
@@ -2392,6 +2419,11 @@ static int airo_close(struct net_device *dev) {
                disable_MAC(ai, 1);
 #endif
                disable_interrupts( ai );
+
+               free_irq(dev->irq, dev);
+
+               set_bit(JOB_DIE, &ai->jobs);
+               kthread_stop(ai->airo_thread_task);
        }
        return 0;
 }
@@ -2403,7 +2435,6 @@ void stop_airo_card( struct net_device *dev, int freeres )
        set_bit(FLAG_RADIO_DOWN, &ai->flags);
        disable_MAC(ai, 1);
        disable_interrupts(ai);
-       free_irq( dev->irq, dev );
        takedown_proc_entry( dev, ai );
        if (test_bit(FLAG_REGISTERED, &ai->flags)) {
                unregister_netdev( dev );
@@ -2414,9 +2445,6 @@ void stop_airo_card( struct net_device *dev, int freeres )
                }
                clear_bit(FLAG_REGISTERED, &ai->flags);
        }
-       set_bit(JOB_DIE, &ai->jobs);
-       kthread_stop(ai->airo_thread_task);
-
        /*
         * Clean out tx queue
         */
@@ -2821,14 +2849,11 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
        ai->config.len = 0;
        ai->pci = pci;
        init_waitqueue_head (&ai->thr_wait);
-       ai->airo_thread_task = kthread_run(airo_thread, dev, dev->name);
-       if (IS_ERR(ai->airo_thread_task))
-               goto err_out_free;
        ai->tfm = NULL;
        add_airo_dev(ai);
 
        if (airo_networks_allocate (ai))
-               goto err_out_thr;
+               goto err_out_free;
        airo_networks_initialize (ai);
 
        /* The Airo-specific entries in the device structure. */
@@ -2851,21 +2876,16 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
        dev->base_addr = port;
 
        SET_NETDEV_DEV(dev, dmdev);
+       SET_MODULE_OWNER(dev);
 
        reset_card (dev, 1);
        msleep(400);
 
-       rc = request_irq( dev->irq, airo_interrupt, IRQF_SHARED, dev->name, dev );
-       if (rc) {
-               airo_print_err(dev->name, "register interrupt %d failed, rc %d",
-                               irq, rc);
-               goto err_out_nets;
-       }
        if (!is_pcmcia) {
                if (!request_region( dev->base_addr, 64, dev->name )) {
                        rc = -EBUSY;
                        airo_print_err(dev->name, "Couldn't request region");
-                       goto err_out_irq;
+                       goto err_out_nets;
                }
        }
 
@@ -2921,8 +2941,6 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
        if (setup_proc_entry(dev, dev->priv) < 0)
                goto err_out_wifi;
 
-       netif_start_queue(dev);
-       SET_MODULE_OWNER(dev);
        return dev;
 
 err_out_wifi:
@@ -2940,14 +2958,9 @@ err_out_map:
 err_out_res:
        if (!is_pcmcia)
                release_region( dev->base_addr, 64 );
-err_out_irq:
-       free_irq(dev->irq, dev);
 err_out_nets:
        airo_networks_free(ai);
-err_out_thr:
        del_airo_dev(ai);
-       set_bit(JOB_DIE, &ai->jobs);
-       kthread_stop(ai->airo_thread_task);
 err_out_free:
        free_netdev(dev);
        return NULL;
@@ -3919,10 +3932,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
                rc = readWepKeyRid(ai, &wkr, 0, lock);
        } while(lastindex != wkr.kindex);
 
-       if (auto_wep) {
-               ai->expires = RUN_AT(3*HZ);
-               wake_up_interruptible(&ai->thr_wait);
-       }
+       try_auto_wep(ai);
 
        return SUCCESS;
 }