aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/airo.c
diff options
context:
space:
mode:
authorMichal Schmidt <mschmidt@redhat.com>2007-03-16 07:44:40 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 11:01:00 -0400
commitaf5b5c9aa92ced95fca509e775aec90933f8959d (patch)
treeb053d2f524a0b3b437f89d6f38e1aecb6e3bbb7f /drivers/net/wireless/airo.c
parentfd48f8d3a3e147e666d838194d5f9de64403ecb1 (diff)
[PATCH] airo: Make /sys/bus/pci/drivers/airo/{,un}bind work
The way airo.c keeps track of all its devices is complicated and buggy as well (del_airo_dev forgets to free the memory add_airo_dev allocates). It's cleaner to use the standard list primitives. While we're at it, it's not necessary to put PCI cards in the list, because the kernel already keeps track of them. We can take advantage of it and use the .remove callback as it was meant to be. This makes /sys/bus/pci/drivers/airo/{,un}bind work. 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.c68
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);
1145struct airo_info { 1145struct 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
2364static LIST_HEAD(airo_devices);
2365
2366static 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
2374static void del_airo_dev(struct airo_info *ai)
2375{
2376 if (!ai->pci)
2377 list_del(&ai->dev_list);
2378}
2363 2379
2364static int airo_close(struct net_device *dev) { 2380static 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
2384static void del_airo_dev( struct net_device *dev );
2385
2386void stop_airo_card( struct net_device *dev, int freeres ) 2400void 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
2441EXPORT_SYMBOL(stop_airo_card); 2455EXPORT_SYMBOL(stop_airo_card);
2442 2456
2443static int add_airo_dev( struct net_device *dev );
2444
2445static int wll_header_parse(struct sk_buff *skb, unsigned char *haddr) 2457static 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);
2936err_out_nets: 2946err_out_nets:
2937 airo_networks_free(ai); 2947 airo_networks_free(ai);
2938err_out_unlink:
2939 del_airo_dev(dev);
2940err_out_thr: 2948err_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);
2943err_out_free: 2952err_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
5536static 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
5583static 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
5595static 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
5604static int __devinit airo_pci_probe(struct pci_dev *pdev, 5588static 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
5624static void __devexit airo_pci_remove(struct pci_dev *pdev) 5608static 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
5628static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state) 5616static 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
5749static void __exit airo_cleanup_module( void ) 5737static 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);