aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/ibmtr_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia/ibmtr_cs.c')
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c152
1 files changed, 47 insertions, 105 deletions
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index b6c140eb9799..b9c7e39576f5 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -108,15 +108,7 @@ MODULE_LICENSE("GPL");
108static void ibmtr_config(dev_link_t *link); 108static void ibmtr_config(dev_link_t *link);
109static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase); 109static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
110static void ibmtr_release(dev_link_t *link); 110static void ibmtr_release(dev_link_t *link);
111static int ibmtr_event(event_t event, int priority, 111static void ibmtr_detach(struct pcmcia_device *p_dev);
112 event_callback_args_t *args);
113
114static dev_info_t dev_info = "ibmtr_cs";
115
116static dev_link_t *ibmtr_attach(void);
117static void ibmtr_detach(dev_link_t *);
118
119static dev_link_t *dev_list;
120 112
121/*====================================================================*/ 113/*====================================================================*/
122 114
@@ -146,25 +138,23 @@ static struct ethtool_ops netdev_ethtool_ops = {
146 138
147======================================================================*/ 139======================================================================*/
148 140
149static dev_link_t *ibmtr_attach(void) 141static int ibmtr_attach(struct pcmcia_device *p_dev)
150{ 142{
151 ibmtr_dev_t *info; 143 ibmtr_dev_t *info;
152 dev_link_t *link; 144 dev_link_t *link;
153 struct net_device *dev; 145 struct net_device *dev;
154 client_reg_t client_reg;
155 int ret;
156 146
157 DEBUG(0, "ibmtr_attach()\n"); 147 DEBUG(0, "ibmtr_attach()\n");
158 148
159 /* Create new token-ring device */ 149 /* Create new token-ring device */
160 info = kmalloc(sizeof(*info), GFP_KERNEL); 150 info = kmalloc(sizeof(*info), GFP_KERNEL);
161 if (!info) return NULL; 151 if (!info) return -ENOMEM;
162 memset(info,0,sizeof(*info)); 152 memset(info,0,sizeof(*info));
163 dev = alloc_trdev(sizeof(struct tok_info)); 153 dev = alloc_trdev(sizeof(struct tok_info));
164 if (!dev) { 154 if (!dev) {
165 kfree(info); 155 kfree(info);
166 return NULL; 156 return -ENOMEM;
167 } 157 }
168 158
169 link = &info->link; 159 link = &info->link;
170 link->priv = info; 160 link->priv = info;
@@ -185,25 +175,13 @@ static dev_link_t *ibmtr_attach(void)
185 175
186 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); 176 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
187 177
188 /* Register with Card Services */ 178 link->handle = p_dev;
189 link->next = dev_list; 179 p_dev->instance = link;
190 dev_list = link;
191 client_reg.dev_info = &dev_info;
192 client_reg.Version = 0x0210;
193 client_reg.event_callback_args.client_data = link;
194 ret = pcmcia_register_client(&link->handle, &client_reg);
195 if (ret != 0) {
196 cs_error(link->handle, RegisterClient, ret);
197 goto out_detach;
198 }
199 180
200out: 181 link->state |= DEV_PRESENT;
201 return link; 182 ibmtr_config(link);
202 183
203out_detach: 184 return 0;
204 ibmtr_detach(link);
205 link = NULL;
206 goto out;
207} /* ibmtr_attach */ 185} /* ibmtr_attach */
208 186
209/*====================================================================== 187/*======================================================================
@@ -215,22 +193,14 @@ out_detach:
215 193
216======================================================================*/ 194======================================================================*/
217 195
218static void ibmtr_detach(dev_link_t *link) 196static void ibmtr_detach(struct pcmcia_device *p_dev)
219{ 197{
198 dev_link_t *link = dev_to_instance(p_dev);
220 struct ibmtr_dev_t *info = link->priv; 199 struct ibmtr_dev_t *info = link->priv;
221 dev_link_t **linkp; 200 struct net_device *dev = info->dev;
222 struct net_device *dev;
223 201
224 DEBUG(0, "ibmtr_detach(0x%p)\n", link); 202 DEBUG(0, "ibmtr_detach(0x%p)\n", link);
225 203
226 /* Locate device structure */
227 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
228 if (*linkp == link) break;
229 if (*linkp == NULL)
230 return;
231
232 dev = info->dev;
233
234 if (link->dev) 204 if (link->dev)
235 unregister_netdev(dev); 205 unregister_netdev(dev);
236 206
@@ -241,13 +211,8 @@ static void ibmtr_detach(dev_link_t *link)
241 if (link->state & DEV_CONFIG) 211 if (link->state & DEV_CONFIG)
242 ibmtr_release(link); 212 ibmtr_release(link);
243 213
244 if (link->handle)
245 pcmcia_deregister_client(link->handle);
246
247 /* Unlink device structure, free bits */
248 *linkp = link->next;
249 free_netdev(dev); 214 free_netdev(dev);
250 kfree(info); 215 kfree(info);
251} /* ibmtr_detach */ 216} /* ibmtr_detach */
252 217
253/*====================================================================== 218/*======================================================================
@@ -401,63 +366,40 @@ static void ibmtr_release(dev_link_t *link)
401 link->state &= ~DEV_CONFIG; 366 link->state &= ~DEV_CONFIG;
402} 367}
403 368
404/*====================================================================== 369static int ibmtr_suspend(struct pcmcia_device *p_dev)
370{
371 dev_link_t *link = dev_to_instance(p_dev);
372 ibmtr_dev_t *info = link->priv;
373 struct net_device *dev = info->dev;
405 374
406 The card status event handler. Mostly, this schedules other 375 link->state |= DEV_SUSPEND;
407 stuff to run after an event is received. A CARD_REMOVAL event 376 if (link->state & DEV_CONFIG) {
408 also sets some flags to discourage the net drivers from trying 377 if (link->open)
409 to talk to the card any more. 378 netif_device_detach(dev);
379 pcmcia_release_configuration(link->handle);
380 }
410 381
411======================================================================*/ 382 return 0;
383}
412 384
413static int ibmtr_event(event_t event, int priority, 385static int ibmtr_resume(struct pcmcia_device *p_dev)
414 event_callback_args_t *args)
415{ 386{
416 dev_link_t *link = args->client_data; 387 dev_link_t *link = dev_to_instance(p_dev);
417 ibmtr_dev_t *info = link->priv; 388 ibmtr_dev_t *info = link->priv;
418 struct net_device *dev = info->dev; 389 struct net_device *dev = info->dev;
419 390
420 DEBUG(1, "ibmtr_event(0x%06x)\n", event); 391 link->state &= ~DEV_SUSPEND;
421
422 switch (event) {
423 case CS_EVENT_CARD_REMOVAL:
424 link->state &= ~DEV_PRESENT;
425 if (link->state & DEV_CONFIG) {
426 /* set flag to bypass normal interrupt code */
427 struct tok_info *priv = netdev_priv(dev);
428 priv->sram_phys |= 1;
429 netif_device_detach(dev);
430 }
431 break;
432 case CS_EVENT_CARD_INSERTION:
433 link->state |= DEV_PRESENT;
434 ibmtr_config(link);
435 break;
436 case CS_EVENT_PM_SUSPEND:
437 link->state |= DEV_SUSPEND;
438 /* Fall through... */
439 case CS_EVENT_RESET_PHYSICAL:
440 if (link->state & DEV_CONFIG) { 392 if (link->state & DEV_CONFIG) {
441 if (link->open) 393 pcmcia_request_configuration(link->handle, &link->conf);
442 netif_device_detach(dev); 394 if (link->open) {
443 pcmcia_release_configuration(link->handle); 395 ibmtr_probe(dev); /* really? */
396 netif_device_attach(dev);
397 }
444 } 398 }
445 break; 399
446 case CS_EVENT_PM_RESUME: 400 return 0;
447 link->state &= ~DEV_SUSPEND; 401}
448 /* Fall through... */ 402
449 case CS_EVENT_CARD_RESET:
450 if (link->state & DEV_CONFIG) {
451 pcmcia_request_configuration(link->handle, &link->conf);
452 if (link->open) {
453 ibmtr_probe(dev); /* really? */
454 netif_device_attach(dev);
455 }
456 }
457 break;
458 }
459 return 0;
460} /* ibmtr_event */
461 403
462/*====================================================================*/ 404/*====================================================================*/
463 405
@@ -514,10 +456,11 @@ static struct pcmcia_driver ibmtr_cs_driver = {
514 .drv = { 456 .drv = {
515 .name = "ibmtr_cs", 457 .name = "ibmtr_cs",
516 }, 458 },
517 .attach = ibmtr_attach, 459 .probe = ibmtr_attach,
518 .event = ibmtr_event, 460 .remove = ibmtr_detach,
519 .detach = ibmtr_detach,
520 .id_table = ibmtr_ids, 461 .id_table = ibmtr_ids,
462 .suspend = ibmtr_suspend,
463 .resume = ibmtr_resume,
521}; 464};
522 465
523static int __init init_ibmtr_cs(void) 466static int __init init_ibmtr_cs(void)
@@ -528,7 +471,6 @@ static int __init init_ibmtr_cs(void)
528static void __exit exit_ibmtr_cs(void) 471static void __exit exit_ibmtr_cs(void)
529{ 472{
530 pcmcia_unregister_driver(&ibmtr_cs_driver); 473 pcmcia_unregister_driver(&ibmtr_cs_driver);
531 BUG_ON(dev_list != NULL);
532} 474}
533 475
534module_init(init_ibmtr_cs); 476module_init(init_ibmtr_cs);