diff options
-rw-r--r-- | drivers/net/wireless/airo.c | 68 |
1 files changed, 29 insertions, 39 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index d08d2275ad5f..f21bbafcb728 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -1145,6 +1145,7 @@ static void airo_networks_free(struct airo_info *ai); | |||
1145 | struct airo_info { | 1145 | struct airo_info { |
1146 | struct net_device_stats stats; | 1146 | struct net_device_stats stats; |
1147 | struct net_device *dev; | 1147 | struct net_device *dev; |
1148 | struct list_head dev_list; | ||
1148 | /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we | 1149 | /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we |
1149 | use the high bit to mark whether it is in use. */ | 1150 | use the high bit to mark whether it is in use. */ |
1150 | #define MAX_FIDS 6 | 1151 | #define MAX_FIDS 6 |
@@ -2360,6 +2361,21 @@ static int airo_change_mtu(struct net_device *dev, int new_mtu) | |||
2360 | return 0; | 2361 | return 0; |
2361 | } | 2362 | } |
2362 | 2363 | ||
2364 | static LIST_HEAD(airo_devices); | ||
2365 | |||
2366 | static void add_airo_dev(struct airo_info *ai) | ||
2367 | { | ||
2368 | /* Upper layers already keep track of PCI devices, | ||
2369 | * so we only need to remember our non-PCI cards. */ | ||
2370 | if (!ai->pci) | ||
2371 | list_add_tail(&ai->dev_list, &airo_devices); | ||
2372 | } | ||
2373 | |||
2374 | static void del_airo_dev(struct airo_info *ai) | ||
2375 | { | ||
2376 | if (!ai->pci) | ||
2377 | list_del(&ai->dev_list); | ||
2378 | } | ||
2363 | 2379 | ||
2364 | static int airo_close(struct net_device *dev) { | 2380 | static int airo_close(struct net_device *dev) { |
2365 | struct airo_info *ai = dev->priv; | 2381 | struct airo_info *ai = dev->priv; |
@@ -2381,8 +2397,6 @@ static int airo_close(struct net_device *dev) { | |||
2381 | return 0; | 2397 | return 0; |
2382 | } | 2398 | } |
2383 | 2399 | ||
2384 | static void del_airo_dev( struct net_device *dev ); | ||
2385 | |||
2386 | void stop_airo_card( struct net_device *dev, int freeres ) | 2400 | void stop_airo_card( struct net_device *dev, int freeres ) |
2387 | { | 2401 | { |
2388 | struct airo_info *ai = dev->priv; | 2402 | struct airo_info *ai = dev->priv; |
@@ -2434,14 +2448,12 @@ void stop_airo_card( struct net_device *dev, int freeres ) | |||
2434 | } | 2448 | } |
2435 | } | 2449 | } |
2436 | crypto_free_cipher(ai->tfm); | 2450 | crypto_free_cipher(ai->tfm); |
2437 | del_airo_dev( dev ); | 2451 | del_airo_dev(ai); |
2438 | free_netdev( dev ); | 2452 | free_netdev( dev ); |
2439 | } | 2453 | } |
2440 | 2454 | ||
2441 | EXPORT_SYMBOL(stop_airo_card); | 2455 | EXPORT_SYMBOL(stop_airo_card); |
2442 | 2456 | ||
2443 | static int add_airo_dev( struct net_device *dev ); | ||
2444 | |||
2445 | static int wll_header_parse(struct sk_buff *skb, unsigned char *haddr) | 2457 | static int wll_header_parse(struct sk_buff *skb, unsigned char *haddr) |
2446 | { | 2458 | { |
2447 | memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); | 2459 | memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); |
@@ -2814,12 +2826,10 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2814 | if (IS_ERR(ai->airo_thread_task)) | 2826 | if (IS_ERR(ai->airo_thread_task)) |
2815 | goto err_out_free; | 2827 | goto err_out_free; |
2816 | ai->tfm = NULL; | 2828 | ai->tfm = NULL; |
2817 | rc = add_airo_dev( dev ); | 2829 | add_airo_dev(ai); |
2818 | if (rc) | ||
2819 | goto err_out_thr; | ||
2820 | 2830 | ||
2821 | if (airo_networks_allocate (ai)) | 2831 | if (airo_networks_allocate (ai)) |
2822 | goto err_out_unlink; | 2832 | goto err_out_thr; |
2823 | airo_networks_initialize (ai); | 2833 | airo_networks_initialize (ai); |
2824 | 2834 | ||
2825 | /* The Airo-specific entries in the device structure. */ | 2835 | /* The Airo-specific entries in the device structure. */ |
@@ -2935,9 +2945,8 @@ err_out_irq: | |||
2935 | free_irq(dev->irq, dev); | 2945 | free_irq(dev->irq, dev); |
2936 | err_out_nets: | 2946 | err_out_nets: |
2937 | airo_networks_free(ai); | 2947 | airo_networks_free(ai); |
2938 | err_out_unlink: | ||
2939 | del_airo_dev(dev); | ||
2940 | err_out_thr: | 2948 | err_out_thr: |
2949 | del_airo_dev(ai); | ||
2941 | set_bit(JOB_DIE, &ai->jobs); | 2950 | set_bit(JOB_DIE, &ai->jobs); |
2942 | kthread_stop(ai->airo_thread_task); | 2951 | kthread_stop(ai->airo_thread_task); |
2943 | err_out_free: | 2952 | err_out_free: |
@@ -5533,11 +5542,6 @@ static int proc_close( struct inode *inode, struct file *file ) | |||
5533 | return 0; | 5542 | return 0; |
5534 | } | 5543 | } |
5535 | 5544 | ||
5536 | static struct net_device_list { | ||
5537 | struct net_device *dev; | ||
5538 | struct net_device_list *next; | ||
5539 | } *airo_devices; | ||
5540 | |||
5541 | /* Since the card doesn't automatically switch to the right WEP mode, | 5545 | /* Since the card doesn't automatically switch to the right WEP mode, |
5542 | we will make it do it. If the card isn't associated, every secs we | 5546 | we will make it do it. If the card isn't associated, every secs we |
5543 | will switch WEP modes to see if that will help. If the card is | 5547 | will switch WEP modes to see if that will help. If the card is |
@@ -5580,26 +5584,6 @@ static void timer_func( struct net_device *dev ) { | |||
5580 | apriv->expires = RUN_AT(HZ*3); | 5584 | apriv->expires = RUN_AT(HZ*3); |
5581 | } | 5585 | } |
5582 | 5586 | ||
5583 | static int add_airo_dev( struct net_device *dev ) { | ||
5584 | struct net_device_list *node = kmalloc( sizeof( *node ), GFP_KERNEL ); | ||
5585 | if ( !node ) | ||
5586 | return -ENOMEM; | ||
5587 | |||
5588 | node->dev = dev; | ||
5589 | node->next = airo_devices; | ||
5590 | airo_devices = node; | ||
5591 | |||
5592 | return 0; | ||
5593 | } | ||
5594 | |||
5595 | static void del_airo_dev( struct net_device *dev ) { | ||
5596 | struct net_device_list **p = &airo_devices; | ||
5597 | while( *p && ( (*p)->dev != dev ) ) | ||
5598 | p = &(*p)->next; | ||
5599 | if ( *p && (*p)->dev == dev ) | ||
5600 | *p = (*p)->next; | ||
5601 | } | ||
5602 | |||
5603 | #ifdef CONFIG_PCI | 5587 | #ifdef CONFIG_PCI |
5604 | static int __devinit airo_pci_probe(struct pci_dev *pdev, | 5588 | static int __devinit airo_pci_probe(struct pci_dev *pdev, |
5605 | const struct pci_device_id *pent) | 5589 | const struct pci_device_id *pent) |
@@ -5623,6 +5607,10 @@ static int __devinit airo_pci_probe(struct pci_dev *pdev, | |||
5623 | 5607 | ||
5624 | static void __devexit airo_pci_remove(struct pci_dev *pdev) | 5608 | static void __devexit airo_pci_remove(struct pci_dev *pdev) |
5625 | { | 5609 | { |
5610 | struct net_device *dev = pci_get_drvdata(pdev); | ||
5611 | |||
5612 | airo_print_info(dev->name, "Unregistering..."); | ||
5613 | stop_airo_card(dev, 1); | ||
5626 | } | 5614 | } |
5627 | 5615 | ||
5628 | static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 5616 | static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
@@ -5748,9 +5736,11 @@ static int __init airo_init_module( void ) | |||
5748 | 5736 | ||
5749 | static void __exit airo_cleanup_module( void ) | 5737 | static void __exit airo_cleanup_module( void ) |
5750 | { | 5738 | { |
5751 | while( airo_devices ) { | 5739 | struct airo_info *ai; |
5752 | airo_print_info(airo_devices->dev->name, "Unregistering...\n"); | 5740 | while(!list_empty(&airo_devices)) { |
5753 | stop_airo_card( airo_devices->dev, 1 ); | 5741 | ai = list_entry(airo_devices.next, struct airo_info, dev_list); |
5742 | airo_print_info(ai->dev->name, "Unregistering..."); | ||
5743 | stop_airo_card(ai->dev, 1); | ||
5754 | } | 5744 | } |
5755 | #ifdef CONFIG_PCI | 5745 | #ifdef CONFIG_PCI |
5756 | pci_unregister_driver(&airo_driver); | 5746 | pci_unregister_driver(&airo_driver); |