diff options
Diffstat (limited to 'drivers/net/wireless/ray_cs.c')
-rw-r--r-- | drivers/net/wireless/ray_cs.c | 98 |
1 files changed, 33 insertions, 65 deletions
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 7d95587d09db..60297460debd 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -190,12 +190,6 @@ static int bc; | |||
190 | static char *phy_addr = NULL; | 190 | static char *phy_addr = NULL; |
191 | 191 | ||
192 | 192 | ||
193 | /* A linked list of "instances" of the ray device. Each actual | ||
194 | PCMCIA card corresponds to one device instance, and is described | ||
195 | by one dev_link_t structure (defined in ds.h). | ||
196 | */ | ||
197 | static dev_link_t *dev_list = NULL; | ||
198 | |||
199 | /* A dev_link_t structure has fields for most things that are needed | 193 | /* A dev_link_t structure has fields for most things that are needed |
200 | to keep track of a socket, but there will usually be some device | 194 | to keep track of a socket, but there will usually be some device |
201 | specific information that also needs to be kept track of. The | 195 | specific information that also needs to be kept track of. The |
@@ -204,6 +198,9 @@ static dev_link_t *dev_list = NULL; | |||
204 | */ | 198 | */ |
205 | static unsigned int ray_mem_speed = 500; | 199 | static unsigned int ray_mem_speed = 500; |
206 | 200 | ||
201 | /* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */ | ||
202 | static struct pcmcia_device *this_device = NULL; | ||
203 | |||
207 | MODULE_AUTHOR("Corey Thomas <corey@world.std.com>"); | 204 | MODULE_AUTHOR("Corey Thomas <corey@world.std.com>"); |
208 | MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver"); | 205 | MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver"); |
209 | MODULE_LICENSE("GPL"); | 206 | MODULE_LICENSE("GPL"); |
@@ -308,53 +305,44 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world. | |||
308 | =============================================================================*/ | 305 | =============================================================================*/ |
309 | static int ray_attach(struct pcmcia_device *p_dev) | 306 | static int ray_attach(struct pcmcia_device *p_dev) |
310 | { | 307 | { |
311 | dev_link_t *link; | ||
312 | ray_dev_t *local; | 308 | ray_dev_t *local; |
313 | struct net_device *dev; | 309 | struct net_device *dev; |
314 | |||
315 | DEBUG(1, "ray_attach()\n"); | ||
316 | |||
317 | /* Initialize the dev_link_t structure */ | ||
318 | link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); | ||
319 | 310 | ||
320 | if (!link) | 311 | DEBUG(1, "ray_attach()\n"); |
321 | return -ENOMEM; | ||
322 | 312 | ||
323 | /* Allocate space for private device-specific data */ | 313 | /* Allocate space for private device-specific data */ |
324 | dev = alloc_etherdev(sizeof(ray_dev_t)); | 314 | dev = alloc_etherdev(sizeof(ray_dev_t)); |
325 | |||
326 | if (!dev) | 315 | if (!dev) |
327 | goto fail_alloc_dev; | 316 | goto fail_alloc_dev; |
328 | 317 | ||
329 | local = dev->priv; | 318 | local = dev->priv; |
330 | 319 | local->finder = p_dev; | |
331 | memset(link, 0, sizeof(struct dev_link_t)); | ||
332 | 320 | ||
333 | /* The io structure describes IO port mapping. None used here */ | 321 | /* The io structure describes IO port mapping. None used here */ |
334 | link->io.NumPorts1 = 0; | 322 | p_dev->io.NumPorts1 = 0; |
335 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 323 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
336 | link->io.IOAddrLines = 5; | 324 | p_dev->io.IOAddrLines = 5; |
337 | 325 | ||
338 | /* Interrupt setup. For PCMCIA, driver takes what's given */ | 326 | /* Interrupt setup. For PCMCIA, driver takes what's given */ |
339 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; | 327 | p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; |
340 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | 328 | p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; |
341 | link->irq.Handler = &ray_interrupt; | 329 | p_dev->irq.Handler = &ray_interrupt; |
342 | 330 | ||
343 | /* General socket configuration */ | 331 | /* General socket configuration */ |
344 | link->conf.Attributes = CONF_ENABLE_IRQ; | 332 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; |
345 | link->conf.IntType = INT_MEMORY_AND_IO; | 333 | p_dev->conf.IntType = INT_MEMORY_AND_IO; |
346 | link->conf.ConfigIndex = 1; | 334 | p_dev->conf.ConfigIndex = 1; |
347 | link->conf.Present = PRESENT_OPTION; | 335 | p_dev->conf.Present = PRESENT_OPTION; |
348 | 336 | ||
349 | link->priv = dev; | 337 | p_dev->priv = dev; |
350 | link->irq.Instance = dev; | 338 | p_dev->irq.Instance = dev; |
351 | 339 | ||
352 | local->finder = link; | 340 | local->finder = p_dev; |
353 | local->card_status = CARD_INSERTED; | 341 | local->card_status = CARD_INSERTED; |
354 | local->authentication_state = UNAUTHENTICATED; | 342 | local->authentication_state = UNAUTHENTICATED; |
355 | local->num_multi = 0; | 343 | local->num_multi = 0; |
356 | DEBUG(2,"ray_attach link = %p, dev = %p, local = %p, intr = %p\n", | 344 | DEBUG(2,"ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n", |
357 | link,dev,local,&ray_interrupt); | 345 | p_dev,dev,local,&ray_interrupt); |
358 | 346 | ||
359 | /* Raylink entries in the device structure */ | 347 | /* Raylink entries in the device structure */ |
360 | dev->hard_start_xmit = &ray_dev_start_xmit; | 348 | dev->hard_start_xmit = &ray_dev_start_xmit; |
@@ -378,16 +366,13 @@ static int ray_attach(struct pcmcia_device *p_dev) | |||
378 | 366 | ||
379 | init_timer(&local->timer); | 367 | init_timer(&local->timer); |
380 | 368 | ||
381 | link->handle = p_dev; | 369 | p_dev->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
382 | p_dev->instance = link; | 370 | this_device = p_dev; |
383 | 371 | ray_config(p_dev); | |
384 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
385 | ray_config(link); | ||
386 | 372 | ||
387 | return 0; | 373 | return 0; |
388 | 374 | ||
389 | fail_alloc_dev: | 375 | fail_alloc_dev: |
390 | kfree(link); | ||
391 | return -ENOMEM; | 376 | return -ENOMEM; |
392 | } /* ray_attach */ | 377 | } /* ray_attach */ |
393 | /*============================================================================= | 378 | /*============================================================================= |
@@ -399,18 +384,12 @@ fail_alloc_dev: | |||
399 | static void ray_detach(struct pcmcia_device *p_dev) | 384 | static void ray_detach(struct pcmcia_device *p_dev) |
400 | { | 385 | { |
401 | dev_link_t *link = dev_to_instance(p_dev); | 386 | dev_link_t *link = dev_to_instance(p_dev); |
402 | dev_link_t **linkp; | ||
403 | struct net_device *dev; | 387 | struct net_device *dev; |
404 | ray_dev_t *local; | 388 | ray_dev_t *local; |
405 | 389 | ||
406 | DEBUG(1, "ray_detach(0x%p)\n", link); | 390 | DEBUG(1, "ray_detach(0x%p)\n", link); |
407 | |||
408 | /* Locate device structure */ | ||
409 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
410 | if (*linkp == link) break; | ||
411 | if (*linkp == NULL) | ||
412 | return; | ||
413 | 391 | ||
392 | this_device = NULL; | ||
414 | dev = link->priv; | 393 | dev = link->priv; |
415 | 394 | ||
416 | if (link->state & DEV_CONFIG) { | 395 | if (link->state & DEV_CONFIG) { |
@@ -420,13 +399,10 @@ static void ray_detach(struct pcmcia_device *p_dev) | |||
420 | del_timer(&local->timer); | 399 | del_timer(&local->timer); |
421 | } | 400 | } |
422 | 401 | ||
423 | /* Unlink device structure, free pieces */ | ||
424 | *linkp = link->next; | ||
425 | if (link->priv) { | 402 | if (link->priv) { |
426 | if (link->dev) unregister_netdev(dev); | 403 | if (link->dev_node) unregister_netdev(dev); |
427 | free_netdev(dev); | 404 | free_netdev(dev); |
428 | } | 405 | } |
429 | kfree(link); | ||
430 | DEBUG(2,"ray_cs ray_detach ending\n"); | 406 | DEBUG(2,"ray_cs ray_detach ending\n"); |
431 | } /* ray_detach */ | 407 | } /* ray_detach */ |
432 | /*============================================================================= | 408 | /*============================================================================= |
@@ -537,7 +513,7 @@ static void ray_config(dev_link_t *link) | |||
537 | } | 513 | } |
538 | 514 | ||
539 | strcpy(local->node.dev_name, dev->name); | 515 | strcpy(local->node.dev_name, dev->name); |
540 | link->dev = &local->node; | 516 | link->dev_node = &local->node; |
541 | 517 | ||
542 | link->state &= ~DEV_CONFIG_PENDING; | 518 | link->state &= ~DEV_CONFIG_PENDING; |
543 | printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ", | 519 | printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ", |
@@ -1640,18 +1616,14 @@ static const struct iw_handler_def ray_handler_def = | |||
1640 | /*===========================================================================*/ | 1616 | /*===========================================================================*/ |
1641 | static int ray_open(struct net_device *dev) | 1617 | static int ray_open(struct net_device *dev) |
1642 | { | 1618 | { |
1643 | dev_link_t *link; | ||
1644 | ray_dev_t *local = (ray_dev_t *)dev->priv; | 1619 | ray_dev_t *local = (ray_dev_t *)dev->priv; |
1620 | dev_link_t *link; | ||
1621 | link = local->finder; | ||
1645 | 1622 | ||
1646 | DEBUG(1, "ray_open('%s')\n", dev->name); | 1623 | DEBUG(1, "ray_open('%s')\n", dev->name); |
1647 | 1624 | ||
1648 | for (link = dev_list; link; link = link->next) | 1625 | if (link->open == 0) |
1649 | if (link->priv == dev) break; | 1626 | local->num_multi = 0; |
1650 | if (!DEV_OK(link)) { | ||
1651 | return -ENODEV; | ||
1652 | } | ||
1653 | |||
1654 | if (link->open == 0) local->num_multi = 0; | ||
1655 | link->open++; | 1627 | link->open++; |
1656 | 1628 | ||
1657 | /* If the card is not started, time to start it ! - Jean II */ | 1629 | /* If the card is not started, time to start it ! - Jean II */ |
@@ -1678,15 +1650,12 @@ static int ray_open(struct net_device *dev) | |||
1678 | /*===========================================================================*/ | 1650 | /*===========================================================================*/ |
1679 | static int ray_dev_close(struct net_device *dev) | 1651 | static int ray_dev_close(struct net_device *dev) |
1680 | { | 1652 | { |
1653 | ray_dev_t *local = (ray_dev_t *)dev->priv; | ||
1681 | dev_link_t *link; | 1654 | dev_link_t *link; |
1655 | link = local->finder; | ||
1682 | 1656 | ||
1683 | DEBUG(1, "ray_dev_close('%s')\n", dev->name); | 1657 | DEBUG(1, "ray_dev_close('%s')\n", dev->name); |
1684 | 1658 | ||
1685 | for (link = dev_list; link; link = link->next) | ||
1686 | if (link->priv == dev) break; | ||
1687 | if (link == NULL) | ||
1688 | return -ENODEV; | ||
1689 | |||
1690 | link->open--; | 1659 | link->open--; |
1691 | netif_stop_queue(dev); | 1660 | netif_stop_queue(dev); |
1692 | 1661 | ||
@@ -2679,7 +2648,7 @@ static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len) | |||
2679 | struct freq_hop_element *pfh; | 2648 | struct freq_hop_element *pfh; |
2680 | UCHAR c[33]; | 2649 | UCHAR c[33]; |
2681 | 2650 | ||
2682 | link = dev_list; | 2651 | link = this_device; |
2683 | if (!link) | 2652 | if (!link) |
2684 | return 0; | 2653 | return 0; |
2685 | dev = (struct net_device *)link->priv; | 2654 | dev = (struct net_device *)link->priv; |
@@ -2923,7 +2892,6 @@ static void __exit exit_ray_cs(void) | |||
2923 | #endif | 2892 | #endif |
2924 | 2893 | ||
2925 | pcmcia_unregister_driver(&ray_driver); | 2894 | pcmcia_unregister_driver(&ray_driver); |
2926 | BUG_ON(dev_list != NULL); | ||
2927 | } /* exit_ray_cs */ | 2895 | } /* exit_ray_cs */ |
2928 | 2896 | ||
2929 | module_init(init_ray_cs); | 2897 | module_init(init_ray_cs); |