diff options
Diffstat (limited to 'drivers/net/wireless/airo.c')
-rw-r--r-- | drivers/net/wireless/airo.c | 70 |
1 files changed, 29 insertions, 41 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 7fe0a61091a6..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); |
@@ -2740,8 +2752,6 @@ static int airo_networks_allocate(struct airo_info *ai) | |||
2740 | 2752 | ||
2741 | static void airo_networks_free(struct airo_info *ai) | 2753 | static void airo_networks_free(struct airo_info *ai) |
2742 | { | 2754 | { |
2743 | if (!ai->networks) | ||
2744 | return; | ||
2745 | kfree(ai->networks); | 2755 | kfree(ai->networks); |
2746 | ai->networks = NULL; | 2756 | ai->networks = NULL; |
2747 | } | 2757 | } |
@@ -2816,12 +2826,10 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2816 | if (IS_ERR(ai->airo_thread_task)) | 2826 | if (IS_ERR(ai->airo_thread_task)) |
2817 | goto err_out_free; | 2827 | goto err_out_free; |
2818 | ai->tfm = NULL; | 2828 | ai->tfm = NULL; |
2819 | rc = add_airo_dev( dev ); | 2829 | add_airo_dev(ai); |
2820 | if (rc) | ||
2821 | goto err_out_thr; | ||
2822 | 2830 | ||
2823 | if (airo_networks_allocate (ai)) | 2831 | if (airo_networks_allocate (ai)) |
2824 | goto err_out_unlink; | 2832 | goto err_out_thr; |
2825 | airo_networks_initialize (ai); | 2833 | airo_networks_initialize (ai); |
2826 | 2834 | ||
2827 | /* The Airo-specific entries in the device structure. */ | 2835 | /* The Airo-specific entries in the device structure. */ |
@@ -2937,9 +2945,8 @@ err_out_irq: | |||
2937 | free_irq(dev->irq, dev); | 2945 | free_irq(dev->irq, dev); |
2938 | err_out_nets: | 2946 | err_out_nets: |
2939 | airo_networks_free(ai); | 2947 | airo_networks_free(ai); |
2940 | err_out_unlink: | ||
2941 | del_airo_dev(dev); | ||
2942 | err_out_thr: | 2948 | err_out_thr: |
2949 | del_airo_dev(ai); | ||
2943 | set_bit(JOB_DIE, &ai->jobs); | 2950 | set_bit(JOB_DIE, &ai->jobs); |
2944 | kthread_stop(ai->airo_thread_task); | 2951 | kthread_stop(ai->airo_thread_task); |
2945 | err_out_free: | 2952 | err_out_free: |
@@ -5535,11 +5542,6 @@ static int proc_close( struct inode *inode, struct file *file ) | |||
5535 | return 0; | 5542 | return 0; |
5536 | } | 5543 | } |
5537 | 5544 | ||
5538 | static struct net_device_list { | ||
5539 | struct net_device *dev; | ||
5540 | struct net_device_list *next; | ||
5541 | } *airo_devices; | ||
5542 | |||
5543 | /* 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, |
5544 | 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 |
5545 | 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 |
@@ -5582,26 +5584,6 @@ static void timer_func( struct net_device *dev ) { | |||
5582 | apriv->expires = RUN_AT(HZ*3); | 5584 | apriv->expires = RUN_AT(HZ*3); |
5583 | } | 5585 | } |
5584 | 5586 | ||
5585 | static int add_airo_dev( struct net_device *dev ) { | ||
5586 | struct net_device_list *node = kmalloc( sizeof( *node ), GFP_KERNEL ); | ||
5587 | if ( !node ) | ||
5588 | return -ENOMEM; | ||
5589 | |||
5590 | node->dev = dev; | ||
5591 | node->next = airo_devices; | ||
5592 | airo_devices = node; | ||
5593 | |||
5594 | return 0; | ||
5595 | } | ||
5596 | |||
5597 | static void del_airo_dev( struct net_device *dev ) { | ||
5598 | struct net_device_list **p = &airo_devices; | ||
5599 | while( *p && ( (*p)->dev != dev ) ) | ||
5600 | p = &(*p)->next; | ||
5601 | if ( *p && (*p)->dev == dev ) | ||
5602 | *p = (*p)->next; | ||
5603 | } | ||
5604 | |||
5605 | #ifdef CONFIG_PCI | 5587 | #ifdef CONFIG_PCI |
5606 | static int __devinit airo_pci_probe(struct pci_dev *pdev, | 5588 | static int __devinit airo_pci_probe(struct pci_dev *pdev, |
5607 | const struct pci_device_id *pent) | 5589 | const struct pci_device_id *pent) |
@@ -5625,6 +5607,10 @@ static int __devinit airo_pci_probe(struct pci_dev *pdev, | |||
5625 | 5607 | ||
5626 | static void __devexit airo_pci_remove(struct pci_dev *pdev) | 5608 | static void __devexit airo_pci_remove(struct pci_dev *pdev) |
5627 | { | 5609 | { |
5610 | struct net_device *dev = pci_get_drvdata(pdev); | ||
5611 | |||
5612 | airo_print_info(dev->name, "Unregistering..."); | ||
5613 | stop_airo_card(dev, 1); | ||
5628 | } | 5614 | } |
5629 | 5615 | ||
5630 | 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) |
@@ -5750,9 +5736,11 @@ static int __init airo_init_module( void ) | |||
5750 | 5736 | ||
5751 | static void __exit airo_cleanup_module( void ) | 5737 | static void __exit airo_cleanup_module( void ) |
5752 | { | 5738 | { |
5753 | while( airo_devices ) { | 5739 | struct airo_info *ai; |
5754 | airo_print_info(airo_devices->dev->name, "Unregistering...\n"); | 5740 | while(!list_empty(&airo_devices)) { |
5755 | 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); | ||
5756 | } | 5744 | } |
5757 | #ifdef CONFIG_PCI | 5745 | #ifdef CONFIG_PCI |
5758 | pci_unregister_driver(&airo_driver); | 5746 | pci_unregister_driver(&airo_driver); |