[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>
This commit is contained in:
committed by
John W. Linville
parent
777ec5e9ce
commit
1c2b7db8c8
@@ -1926,28 +1926,55 @@ static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int airo_open(struct net_device *dev) {
|
static void try_auto_wep(struct airo_info *ai)
|
||||||
struct airo_info *info = dev->priv;
|
{
|
||||||
Resp rsp;
|
if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) {
|
||||||
|
ai->expires = RUN_AT(3*HZ);
|
||||||
|
wake_up_interruptible(&ai->thr_wait);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (test_bit(FLAG_FLASHING, &info->flags))
|
static int airo_open(struct net_device *dev) {
|
||||||
|
struct airo_info *ai = dev->priv;
|
||||||
|
Resp rsp;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (test_bit(FLAG_FLASHING, &ai->flags))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
/* Make sure the card is configured.
|
/* Make sure the card is configured.
|
||||||
* Wireless Extensions may postpone config changes until the card
|
* Wireless Extensions may postpone config changes until the card
|
||||||
* is open (to pipeline changes and speed-up card setup). If
|
* is open (to pipeline changes and speed-up card setup). If
|
||||||
* those changes are not yet commited, do it now - Jean II */
|
* those changes are not yet commited, do it now - Jean II */
|
||||||
if (test_bit (FLAG_COMMIT, &info->flags)) {
|
if (test_bit(FLAG_COMMIT, &ai->flags)) {
|
||||||
disable_MAC(info, 1);
|
disable_MAC(ai, 1);
|
||||||
writeConfigRid(info, 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) */
|
/* Power on the MAC controller (which may have been disabled) */
|
||||||
clear_bit(FLAG_RADIO_DOWN, &info->flags);
|
clear_bit(FLAG_RADIO_DOWN, &ai->flags);
|
||||||
enable_interrupts(info);
|
enable_interrupts(ai);
|
||||||
|
|
||||||
|
try_auto_wep(ai);
|
||||||
}
|
}
|
||||||
enable_MAC(info, &rsp, 1);
|
enable_MAC(ai, &rsp, 1);
|
||||||
|
|
||||||
netif_start_queue(dev);
|
netif_start_queue(dev);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2392,6 +2419,11 @@ static int airo_close(struct net_device *dev) {
|
|||||||
disable_MAC(ai, 1);
|
disable_MAC(ai, 1);
|
||||||
#endif
|
#endif
|
||||||
disable_interrupts( ai );
|
disable_interrupts( ai );
|
||||||
|
|
||||||
|
free_irq(dev->irq, dev);
|
||||||
|
|
||||||
|
set_bit(JOB_DIE, &ai->jobs);
|
||||||
|
kthread_stop(ai->airo_thread_task);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2403,7 +2435,6 @@ void stop_airo_card( struct net_device *dev, int freeres )
|
|||||||
set_bit(FLAG_RADIO_DOWN, &ai->flags);
|
set_bit(FLAG_RADIO_DOWN, &ai->flags);
|
||||||
disable_MAC(ai, 1);
|
disable_MAC(ai, 1);
|
||||||
disable_interrupts(ai);
|
disable_interrupts(ai);
|
||||||
free_irq( dev->irq, dev );
|
|
||||||
takedown_proc_entry( dev, ai );
|
takedown_proc_entry( dev, ai );
|
||||||
if (test_bit(FLAG_REGISTERED, &ai->flags)) {
|
if (test_bit(FLAG_REGISTERED, &ai->flags)) {
|
||||||
unregister_netdev( dev );
|
unregister_netdev( dev );
|
||||||
@@ -2414,9 +2445,6 @@ void stop_airo_card( struct net_device *dev, int freeres )
|
|||||||
}
|
}
|
||||||
clear_bit(FLAG_REGISTERED, &ai->flags);
|
clear_bit(FLAG_REGISTERED, &ai->flags);
|
||||||
}
|
}
|
||||||
set_bit(JOB_DIE, &ai->jobs);
|
|
||||||
kthread_stop(ai->airo_thread_task);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clean out tx queue
|
* 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->config.len = 0;
|
||||||
ai->pci = pci;
|
ai->pci = pci;
|
||||||
init_waitqueue_head (&ai->thr_wait);
|
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;
|
ai->tfm = NULL;
|
||||||
add_airo_dev(ai);
|
add_airo_dev(ai);
|
||||||
|
|
||||||
if (airo_networks_allocate (ai))
|
if (airo_networks_allocate (ai))
|
||||||
goto err_out_thr;
|
goto err_out_free;
|
||||||
airo_networks_initialize (ai);
|
airo_networks_initialize (ai);
|
||||||
|
|
||||||
/* The Airo-specific entries in the device structure. */
|
/* 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;
|
dev->base_addr = port;
|
||||||
|
|
||||||
SET_NETDEV_DEV(dev, dmdev);
|
SET_NETDEV_DEV(dev, dmdev);
|
||||||
|
SET_MODULE_OWNER(dev);
|
||||||
|
|
||||||
reset_card (dev, 1);
|
reset_card (dev, 1);
|
||||||
msleep(400);
|
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 (!is_pcmcia) {
|
||||||
if (!request_region( dev->base_addr, 64, dev->name )) {
|
if (!request_region( dev->base_addr, 64, dev->name )) {
|
||||||
rc = -EBUSY;
|
rc = -EBUSY;
|
||||||
airo_print_err(dev->name, "Couldn't request region");
|
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)
|
if (setup_proc_entry(dev, dev->priv) < 0)
|
||||||
goto err_out_wifi;
|
goto err_out_wifi;
|
||||||
|
|
||||||
netif_start_queue(dev);
|
|
||||||
SET_MODULE_OWNER(dev);
|
|
||||||
return dev;
|
return dev;
|
||||||
|
|
||||||
err_out_wifi:
|
err_out_wifi:
|
||||||
@@ -2940,14 +2958,9 @@ err_out_map:
|
|||||||
err_out_res:
|
err_out_res:
|
||||||
if (!is_pcmcia)
|
if (!is_pcmcia)
|
||||||
release_region( dev->base_addr, 64 );
|
release_region( dev->base_addr, 64 );
|
||||||
err_out_irq:
|
|
||||||
free_irq(dev->irq, dev);
|
|
||||||
err_out_nets:
|
err_out_nets:
|
||||||
airo_networks_free(ai);
|
airo_networks_free(ai);
|
||||||
err_out_thr:
|
|
||||||
del_airo_dev(ai);
|
del_airo_dev(ai);
|
||||||
set_bit(JOB_DIE, &ai->jobs);
|
|
||||||
kthread_stop(ai->airo_thread_task);
|
|
||||||
err_out_free:
|
err_out_free:
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -3919,10 +3932,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
|
|||||||
rc = readWepKeyRid(ai, &wkr, 0, lock);
|
rc = readWepKeyRid(ai, &wkr, 0, lock);
|
||||||
} while(lastindex != wkr.kindex);
|
} while(lastindex != wkr.kindex);
|
||||||
|
|
||||||
if (auto_wep) {
|
try_auto_wep(ai);
|
||||||
ai->expires = RUN_AT(3*HZ);
|
|
||||||
wake_up_interruptible(&ai->thr_wait);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user