aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/fmvj18x_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia/fmvj18x_cs.c')
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c128
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);
88static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id); 88static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);
89static int fmvj18x_setup_mfc(dev_link_t *link); 89static int fmvj18x_setup_mfc(dev_link_t *link);
90static void fmvj18x_release(dev_link_t *link); 90static void fmvj18x_release(dev_link_t *link);
91static int fmvj18x_event(event_t event, int priority, 91static void fmvj18x_detach(struct pcmcia_device *p_dev);
92 event_callback_args_t *args);
93static dev_link_t *fmvj18x_attach(void);
94static 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);
108static void fjn_tx_timeout(struct net_device *dev); 105static void fjn_tx_timeout(struct net_device *dev);
109static struct ethtool_ops netdev_ethtool_ops; 106static struct ethtool_ops netdev_ethtool_ops;
110 107
111static dev_info_t dev_info = "fmvj18x_cs";
112static 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
237static dev_link_t *fmvj18x_attach(void) 231static 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
303static void fmvj18x_detach(dev_link_t *link) 288static 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/*====================================================================*/ 689static int fmvj18x_suspend(struct pcmcia_device *p_dev)
717
718static 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
705static 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
762static struct pcmcia_device_id fmvj18x_ids[] = { 724static 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
798static int __init init_fmvj18x_cs(void) 761static int __init init_fmvj18x_cs(void)
@@ -803,7 +766,6 @@ static int __init init_fmvj18x_cs(void)
803static void __exit exit_fmvj18x_cs(void) 766static 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
809module_init(init_fmvj18x_cs); 771module_init(init_fmvj18x_cs);