diff options
Diffstat (limited to 'drivers/net/pcmcia/fmvj18x_cs.c')
-rw-r--r-- | drivers/net/pcmcia/fmvj18x_cs.c | 128 |
1 files changed, 45 insertions, 83 deletions
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 356f50909222..28fe2fb4d6c0 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c | |||
@@ -88,10 +88,7 @@ static void fmvj18x_config(dev_link_t *link); | |||
88 | static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id); | 88 | static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id); |
89 | static int fmvj18x_setup_mfc(dev_link_t *link); | 89 | static int fmvj18x_setup_mfc(dev_link_t *link); |
90 | static void fmvj18x_release(dev_link_t *link); | 90 | static void fmvj18x_release(dev_link_t *link); |
91 | static int fmvj18x_event(event_t event, int priority, | 91 | static void fmvj18x_detach(struct pcmcia_device *p_dev); |
92 | event_callback_args_t *args); | ||
93 | static dev_link_t *fmvj18x_attach(void); | ||
94 | static void fmvj18x_detach(dev_link_t *); | ||
95 | 92 | ||
96 | /* | 93 | /* |
97 | LAN controller(MBH86960A) specific routines | 94 | LAN controller(MBH86960A) specific routines |
@@ -108,9 +105,6 @@ static void set_rx_mode(struct net_device *dev); | |||
108 | static void fjn_tx_timeout(struct net_device *dev); | 105 | static void fjn_tx_timeout(struct net_device *dev); |
109 | static struct ethtool_ops netdev_ethtool_ops; | 106 | static struct ethtool_ops netdev_ethtool_ops; |
110 | 107 | ||
111 | static dev_info_t dev_info = "fmvj18x_cs"; | ||
112 | static dev_link_t *dev_list; | ||
113 | |||
114 | /* | 108 | /* |
115 | card type | 109 | card type |
116 | */ | 110 | */ |
@@ -234,20 +228,18 @@ typedef struct local_info_t { | |||
234 | #define BANK_1U 0x24 /* bank 1 (CONFIG_1) */ | 228 | #define BANK_1U 0x24 /* bank 1 (CONFIG_1) */ |
235 | #define BANK_2U 0x28 /* bank 2 (CONFIG_1) */ | 229 | #define BANK_2U 0x28 /* bank 2 (CONFIG_1) */ |
236 | 230 | ||
237 | static dev_link_t *fmvj18x_attach(void) | 231 | static int fmvj18x_attach(struct pcmcia_device *p_dev) |
238 | { | 232 | { |
239 | local_info_t *lp; | 233 | local_info_t *lp; |
240 | dev_link_t *link; | 234 | dev_link_t *link; |
241 | struct net_device *dev; | 235 | struct net_device *dev; |
242 | client_reg_t client_reg; | 236 | |
243 | int ret; | ||
244 | |||
245 | DEBUG(0, "fmvj18x_attach()\n"); | 237 | DEBUG(0, "fmvj18x_attach()\n"); |
246 | 238 | ||
247 | /* Make up a FMVJ18x specific data structure */ | 239 | /* Make up a FMVJ18x specific data structure */ |
248 | dev = alloc_etherdev(sizeof(local_info_t)); | 240 | dev = alloc_etherdev(sizeof(local_info_t)); |
249 | if (!dev) | 241 | if (!dev) |
250 | return NULL; | 242 | return -ENOMEM; |
251 | lp = netdev_priv(dev); | 243 | lp = netdev_priv(dev); |
252 | link = &lp->link; | 244 | link = &lp->link; |
253 | link->priv = dev; | 245 | link->priv = dev; |
@@ -262,7 +254,7 @@ static dev_link_t *fmvj18x_attach(void) | |||
262 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | 254 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; |
263 | link->irq.Handler = &fjn_interrupt; | 255 | link->irq.Handler = &fjn_interrupt; |
264 | link->irq.Instance = dev; | 256 | link->irq.Instance = dev; |
265 | 257 | ||
266 | /* General socket configuration */ | 258 | /* General socket configuration */ |
267 | link->conf.Attributes = CONF_ENABLE_IRQ; | 259 | link->conf.Attributes = CONF_ENABLE_IRQ; |
268 | link->conf.Vcc = 50; | 260 | link->conf.Vcc = 50; |
@@ -281,37 +273,24 @@ static dev_link_t *fmvj18x_attach(void) | |||
281 | dev->watchdog_timeo = TX_TIMEOUT; | 273 | dev->watchdog_timeo = TX_TIMEOUT; |
282 | #endif | 274 | #endif |
283 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); | 275 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); |
284 | |||
285 | /* Register with Card Services */ | ||
286 | link->next = dev_list; | ||
287 | dev_list = link; | ||
288 | client_reg.dev_info = &dev_info; | ||
289 | client_reg.Version = 0x0210; | ||
290 | client_reg.event_callback_args.client_data = link; | ||
291 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
292 | if (ret != 0) { | ||
293 | cs_error(link->handle, RegisterClient, ret); | ||
294 | fmvj18x_detach(link); | ||
295 | return NULL; | ||
296 | } | ||
297 | 276 | ||
298 | return link; | 277 | link->handle = p_dev; |
278 | p_dev->instance = link; | ||
279 | |||
280 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
281 | fmvj18x_config(link); | ||
282 | |||
283 | return 0; | ||
299 | } /* fmvj18x_attach */ | 284 | } /* fmvj18x_attach */ |
300 | 285 | ||
301 | /*====================================================================*/ | 286 | /*====================================================================*/ |
302 | 287 | ||
303 | static void fmvj18x_detach(dev_link_t *link) | 288 | static void fmvj18x_detach(struct pcmcia_device *p_dev) |
304 | { | 289 | { |
290 | dev_link_t *link = dev_to_instance(p_dev); | ||
305 | struct net_device *dev = link->priv; | 291 | struct net_device *dev = link->priv; |
306 | dev_link_t **linkp; | 292 | |
307 | |||
308 | DEBUG(0, "fmvj18x_detach(0x%p)\n", link); | 293 | DEBUG(0, "fmvj18x_detach(0x%p)\n", link); |
309 | |||
310 | /* Locate device structure */ | ||
311 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
312 | if (*linkp == link) break; | ||
313 | if (*linkp == NULL) | ||
314 | return; | ||
315 | 294 | ||
316 | if (link->dev) | 295 | if (link->dev) |
317 | unregister_netdev(dev); | 296 | unregister_netdev(dev); |
@@ -319,12 +298,6 @@ static void fmvj18x_detach(dev_link_t *link) | |||
319 | if (link->state & DEV_CONFIG) | 298 | if (link->state & DEV_CONFIG) |
320 | fmvj18x_release(link); | 299 | fmvj18x_release(link); |
321 | 300 | ||
322 | /* Break the link with Card Services */ | ||
323 | if (link->handle) | ||
324 | pcmcia_deregister_client(link->handle); | ||
325 | |||
326 | /* Unlink device structure, free pieces */ | ||
327 | *linkp = link->next; | ||
328 | free_netdev(dev); | 301 | free_netdev(dev); |
329 | } /* fmvj18x_detach */ | 302 | } /* fmvj18x_detach */ |
330 | 303 | ||
@@ -713,51 +686,40 @@ static void fmvj18x_release(dev_link_t *link) | |||
713 | link->state &= ~DEV_CONFIG; | 686 | link->state &= ~DEV_CONFIG; |
714 | } | 687 | } |
715 | 688 | ||
716 | /*====================================================================*/ | 689 | static int fmvj18x_suspend(struct pcmcia_device *p_dev) |
717 | |||
718 | static int fmvj18x_event(event_t event, int priority, | ||
719 | event_callback_args_t *args) | ||
720 | { | 690 | { |
721 | dev_link_t *link = args->client_data; | 691 | dev_link_t *link = dev_to_instance(p_dev); |
722 | struct net_device *dev = link->priv; | 692 | struct net_device *dev = link->priv; |
723 | 693 | ||
724 | DEBUG(1, "fmvj18x_event(0x%06x)\n", event); | ||
725 | |||
726 | switch (event) { | ||
727 | case CS_EVENT_CARD_REMOVAL: | ||
728 | link->state &= ~DEV_PRESENT; | ||
729 | if (link->state & DEV_CONFIG) | ||
730 | netif_device_detach(dev); | ||
731 | break; | ||
732 | case CS_EVENT_CARD_INSERTION: | ||
733 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
734 | fmvj18x_config(link); | ||
735 | break; | ||
736 | case CS_EVENT_PM_SUSPEND: | ||
737 | link->state |= DEV_SUSPEND; | 694 | link->state |= DEV_SUSPEND; |
738 | /* Fall through... */ | ||
739 | case CS_EVENT_RESET_PHYSICAL: | ||
740 | if (link->state & DEV_CONFIG) { | 695 | if (link->state & DEV_CONFIG) { |
741 | if (link->open) | 696 | if (link->open) |
742 | netif_device_detach(dev); | 697 | netif_device_detach(dev); |
743 | pcmcia_release_configuration(link->handle); | 698 | pcmcia_release_configuration(link->handle); |
744 | } | 699 | } |
745 | break; | 700 | |
746 | case CS_EVENT_PM_RESUME: | 701 | |
702 | return 0; | ||
703 | } | ||
704 | |||
705 | static int fmvj18x_resume(struct pcmcia_device *p_dev) | ||
706 | { | ||
707 | dev_link_t *link = dev_to_instance(p_dev); | ||
708 | struct net_device *dev = link->priv; | ||
709 | |||
747 | link->state &= ~DEV_SUSPEND; | 710 | link->state &= ~DEV_SUSPEND; |
748 | /* Fall through... */ | ||
749 | case CS_EVENT_CARD_RESET: | ||
750 | if (link->state & DEV_CONFIG) { | 711 | if (link->state & DEV_CONFIG) { |
751 | pcmcia_request_configuration(link->handle, &link->conf); | 712 | pcmcia_request_configuration(link->handle, &link->conf); |
752 | if (link->open) { | 713 | if (link->open) { |
753 | fjn_reset(dev); | 714 | fjn_reset(dev); |
754 | netif_device_attach(dev); | 715 | netif_device_attach(dev); |
755 | } | 716 | } |
756 | } | 717 | } |
757 | break; | 718 | |
758 | } | 719 | return 0; |
759 | return 0; | 720 | } |
760 | } /* fmvj18x_event */ | 721 | |
722 | /*====================================================================*/ | ||
761 | 723 | ||
762 | static struct pcmcia_device_id fmvj18x_ids[] = { | 724 | static struct pcmcia_device_id fmvj18x_ids[] = { |
763 | PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004), | 725 | PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004), |
@@ -789,10 +751,11 @@ static struct pcmcia_driver fmvj18x_cs_driver = { | |||
789 | .drv = { | 751 | .drv = { |
790 | .name = "fmvj18x_cs", | 752 | .name = "fmvj18x_cs", |
791 | }, | 753 | }, |
792 | .attach = fmvj18x_attach, | 754 | .probe = fmvj18x_attach, |
793 | .event = fmvj18x_event, | 755 | .remove = fmvj18x_detach, |
794 | .detach = fmvj18x_detach, | ||
795 | .id_table = fmvj18x_ids, | 756 | .id_table = fmvj18x_ids, |
757 | .suspend = fmvj18x_suspend, | ||
758 | .resume = fmvj18x_resume, | ||
796 | }; | 759 | }; |
797 | 760 | ||
798 | static int __init init_fmvj18x_cs(void) | 761 | static int __init init_fmvj18x_cs(void) |
@@ -803,7 +766,6 @@ static int __init init_fmvj18x_cs(void) | |||
803 | static void __exit exit_fmvj18x_cs(void) | 766 | static void __exit exit_fmvj18x_cs(void) |
804 | { | 767 | { |
805 | pcmcia_unregister_driver(&fmvj18x_cs_driver); | 768 | pcmcia_unregister_driver(&fmvj18x_cs_driver); |
806 | BUG_ON(dev_list != NULL); | ||
807 | } | 769 | } |
808 | 770 | ||
809 | module_init(init_fmvj18x_cs); | 771 | module_init(init_fmvj18x_cs); |