aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/3c574_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia/3c574_cs.c')
-rw-r--r--drivers/net/pcmcia/3c574_cs.c115
1 files changed, 42 insertions, 73 deletions
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index ce90becb8bdf..fab93360f017 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -204,7 +204,7 @@ enum Window4 { /* Window 4: Xcvr/media bits. */
204#define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ 204#define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */
205 205
206struct el3_private { 206struct el3_private {
207 dev_link_t link; 207 struct pcmcia_device *p_dev;
208 dev_node_t node; 208 dev_node_t node;
209 struct net_device_stats stats; 209 struct net_device_stats stats;
210 u16 advertising, partner; /* NWay media advertisement */ 210 u16 advertising, partner; /* NWay media advertisement */
@@ -225,8 +225,8 @@ static char mii_preamble_required = 0;
225 225
226/* Index of functions. */ 226/* Index of functions. */
227 227
228static void tc574_config(dev_link_t *link); 228static int tc574_config(struct pcmcia_device *link);
229static void tc574_release(dev_link_t *link); 229static void tc574_release(struct pcmcia_device *link);
230 230
231static void mdio_sync(kio_addr_t ioaddr, int bits); 231static void mdio_sync(kio_addr_t ioaddr, int bits);
232static int mdio_read(kio_addr_t ioaddr, int phy_id, int location); 232static int mdio_read(kio_addr_t ioaddr, int phy_id, int location);
@@ -256,10 +256,9 @@ static void tc574_detach(struct pcmcia_device *p_dev);
256 with Card Services. 256 with Card Services.
257*/ 257*/
258 258
259static int tc574_attach(struct pcmcia_device *p_dev) 259static int tc574_probe(struct pcmcia_device *link)
260{ 260{
261 struct el3_private *lp; 261 struct el3_private *lp;
262 dev_link_t *link;
263 struct net_device *dev; 262 struct net_device *dev;
264 263
265 DEBUG(0, "3c574_attach()\n"); 264 DEBUG(0, "3c574_attach()\n");
@@ -269,8 +268,8 @@ static int tc574_attach(struct pcmcia_device *p_dev)
269 if (!dev) 268 if (!dev)
270 return -ENOMEM; 269 return -ENOMEM;
271 lp = netdev_priv(dev); 270 lp = netdev_priv(dev);
272 link = &lp->link;
273 link->priv = dev; 271 link->priv = dev;
272 lp->p_dev = link;
274 273
275 spin_lock_init(&lp->window_lock); 274 spin_lock_init(&lp->window_lock);
276 link->io.NumPorts1 = 32; 275 link->io.NumPorts1 = 32;
@@ -280,7 +279,6 @@ static int tc574_attach(struct pcmcia_device *p_dev)
280 link->irq.Handler = &el3_interrupt; 279 link->irq.Handler = &el3_interrupt;
281 link->irq.Instance = dev; 280 link->irq.Instance = dev;
282 link->conf.Attributes = CONF_ENABLE_IRQ; 281 link->conf.Attributes = CONF_ENABLE_IRQ;
283 link->conf.Vcc = 50;
284 link->conf.IntType = INT_MEMORY_AND_IO; 282 link->conf.IntType = INT_MEMORY_AND_IO;
285 link->conf.ConfigIndex = 1; 283 link->conf.ConfigIndex = 1;
286 link->conf.Present = PRESENT_OPTION; 284 link->conf.Present = PRESENT_OPTION;
@@ -298,13 +296,7 @@ static int tc574_attach(struct pcmcia_device *p_dev)
298 dev->watchdog_timeo = TX_TIMEOUT; 296 dev->watchdog_timeo = TX_TIMEOUT;
299#endif 297#endif
300 298
301 link->handle = p_dev; 299 return tc574_config(link);
302 p_dev->instance = link;
303
304 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
305 tc574_config(link);
306
307 return 0;
308} /* tc574_attach */ 300} /* tc574_attach */
309 301
310/* 302/*
@@ -316,18 +308,16 @@ static int tc574_attach(struct pcmcia_device *p_dev)
316 308
317*/ 309*/
318 310
319static void tc574_detach(struct pcmcia_device *p_dev) 311static void tc574_detach(struct pcmcia_device *link)
320{ 312{
321 dev_link_t *link = dev_to_instance(p_dev);
322 struct net_device *dev = link->priv; 313 struct net_device *dev = link->priv;
323 314
324 DEBUG(0, "3c574_detach(0x%p)\n", link); 315 DEBUG(0, "3c574_detach(0x%p)\n", link);
325 316
326 if (link->dev) 317 if (link->dev_node)
327 unregister_netdev(dev); 318 unregister_netdev(dev);
328 319
329 if (link->state & DEV_CONFIG) 320 tc574_release(link);
330 tc574_release(link);
331 321
332 free_netdev(dev); 322 free_netdev(dev);
333} /* tc574_detach */ 323} /* tc574_detach */
@@ -343,9 +333,8 @@ static void tc574_detach(struct pcmcia_device *p_dev)
343 333
344static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; 334static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
345 335
346static void tc574_config(dev_link_t *link) 336static int tc574_config(struct pcmcia_device *link)
347{ 337{
348 client_handle_t handle = link->handle;
349 struct net_device *dev = link->priv; 338 struct net_device *dev = link->priv;
350 struct el3_private *lp = netdev_priv(dev); 339 struct el3_private *lp = netdev_priv(dev);
351 tuple_t tuple; 340 tuple_t tuple;
@@ -363,30 +352,27 @@ static void tc574_config(dev_link_t *link)
363 352
364 tuple.Attributes = 0; 353 tuple.Attributes = 0;
365 tuple.DesiredTuple = CISTPL_CONFIG; 354 tuple.DesiredTuple = CISTPL_CONFIG;
366 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 355 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
367 tuple.TupleData = (cisdata_t *)buf; 356 tuple.TupleData = (cisdata_t *)buf;
368 tuple.TupleDataMax = 64; 357 tuple.TupleDataMax = 64;
369 tuple.TupleOffset = 0; 358 tuple.TupleOffset = 0;
370 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 359 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
371 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 360 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
372 link->conf.ConfigBase = parse.config.base; 361 link->conf.ConfigBase = parse.config.base;
373 link->conf.Present = parse.config.rmask[0]; 362 link->conf.Present = parse.config.rmask[0];
374 363
375 /* Configure card */
376 link->state |= DEV_CONFIG;
377
378 link->io.IOAddrLines = 16; 364 link->io.IOAddrLines = 16;
379 for (i = j = 0; j < 0x400; j += 0x20) { 365 for (i = j = 0; j < 0x400; j += 0x20) {
380 link->io.BasePort1 = j ^ 0x300; 366 link->io.BasePort1 = j ^ 0x300;
381 i = pcmcia_request_io(link->handle, &link->io); 367 i = pcmcia_request_io(link, &link->io);
382 if (i == CS_SUCCESS) break; 368 if (i == CS_SUCCESS) break;
383 } 369 }
384 if (i != CS_SUCCESS) { 370 if (i != CS_SUCCESS) {
385 cs_error(link->handle, RequestIO, i); 371 cs_error(link, RequestIO, i);
386 goto failed; 372 goto failed;
387 } 373 }
388 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); 374 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
389 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); 375 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
390 376
391 dev->irq = link->irq.AssignedIRQ; 377 dev->irq = link->irq.AssignedIRQ;
392 dev->base_addr = link->io.BasePort1; 378 dev->base_addr = link->io.BasePort1;
@@ -397,8 +383,8 @@ static void tc574_config(dev_link_t *link)
397 the hardware address. The future products may include a modem chip 383 the hardware address. The future products may include a modem chip
398 and put the address in the CIS. */ 384 and put the address in the CIS. */
399 tuple.DesiredTuple = 0x88; 385 tuple.DesiredTuple = 0x88;
400 if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) { 386 if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
401 pcmcia_get_tuple_data(handle, &tuple); 387 pcmcia_get_tuple_data(link, &tuple);
402 for (i = 0; i < 3; i++) 388 for (i = 0; i < 3; i++)
403 phys_addr[i] = htons(buf[i]); 389 phys_addr[i] = htons(buf[i]);
404 } else { 390 } else {
@@ -412,9 +398,9 @@ static void tc574_config(dev_link_t *link)
412 } 398 }
413 } 399 }
414 tuple.DesiredTuple = CISTPL_VERS_1; 400 tuple.DesiredTuple = CISTPL_VERS_1;
415 if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS && 401 if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS &&
416 pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS && 402 pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS &&
417 pcmcia_parse_tuple(handle, &tuple, &parse) == CS_SUCCESS) { 403 pcmcia_parse_tuple(link, &tuple, &parse) == CS_SUCCESS) {
418 cardname = parse.version_1.str + parse.version_1.ofs[1]; 404 cardname = parse.version_1.str + parse.version_1.ofs[1];
419 } else 405 } else
420 cardname = "3Com 3c574"; 406 cardname = "3Com 3c574";
@@ -473,13 +459,12 @@ static void tc574_config(dev_link_t *link)
473 } 459 }
474 } 460 }
475 461
476 link->state &= ~DEV_CONFIG_PENDING; 462 link->dev_node = &lp->node;
477 link->dev = &lp->node; 463 SET_NETDEV_DEV(dev, &handle_to_dev(link));
478 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
479 464
480 if (register_netdev(dev) != 0) { 465 if (register_netdev(dev) != 0) {
481 printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n"); 466 printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
482 link->dev = NULL; 467 link->dev_node = NULL;
483 goto failed; 468 goto failed;
484 } 469 }
485 470
@@ -493,13 +478,13 @@ static void tc574_config(dev_link_t *link)
493 8 << config.u.ram_size, ram_split[config.u.ram_split], 478 8 << config.u.ram_size, ram_split[config.u.ram_split],
494 config.u.autoselect ? "autoselect " : ""); 479 config.u.autoselect ? "autoselect " : "");
495 480
496 return; 481 return 0;
497 482
498cs_failed: 483cs_failed:
499 cs_error(link->handle, last_fn, last_ret); 484 cs_error(link, last_fn, last_ret);
500failed: 485failed:
501 tc574_release(link); 486 tc574_release(link);
502 return; 487 return -ENODEV;
503 488
504} /* tc574_config */ 489} /* tc574_config */
505 490
@@ -509,44 +494,28 @@ failed:
509 still open, this will be postponed until it is closed. 494 still open, this will be postponed until it is closed.
510*/ 495*/
511 496
512static void tc574_release(dev_link_t *link) 497static void tc574_release(struct pcmcia_device *link)
513{ 498{
514 DEBUG(0, "3c574_release(0x%p)\n", link); 499 pcmcia_disable_device(link);
515
516 pcmcia_release_configuration(link->handle);
517 pcmcia_release_io(link->handle, &link->io);
518 pcmcia_release_irq(link->handle, &link->irq);
519
520 link->state &= ~DEV_CONFIG;
521} 500}
522 501
523static int tc574_suspend(struct pcmcia_device *p_dev) 502static int tc574_suspend(struct pcmcia_device *link)
524{ 503{
525 dev_link_t *link = dev_to_instance(p_dev);
526 struct net_device *dev = link->priv; 504 struct net_device *dev = link->priv;
527 505
528 link->state |= DEV_SUSPEND; 506 if (link->open)
529 if (link->state & DEV_CONFIG) { 507 netif_device_detach(dev);
530 if (link->open)
531 netif_device_detach(dev);
532 pcmcia_release_configuration(link->handle);
533 }
534 508
535 return 0; 509 return 0;
536} 510}
537 511
538static int tc574_resume(struct pcmcia_device *p_dev) 512static int tc574_resume(struct pcmcia_device *link)
539{ 513{
540 dev_link_t *link = dev_to_instance(p_dev);
541 struct net_device *dev = link->priv; 514 struct net_device *dev = link->priv;
542 515
543 link->state &= ~DEV_SUSPEND; 516 if (link->open) {
544 if (link->state & DEV_CONFIG) { 517 tc574_reset(dev);
545 pcmcia_request_configuration(link->handle, &link->conf); 518 netif_device_attach(dev);
546 if (link->open) {
547 tc574_reset(dev);
548 netif_device_attach(dev);
549 }
550 } 519 }
551 520
552 return 0; 521 return 0;
@@ -757,9 +726,9 @@ static void tc574_reset(struct net_device *dev)
757static int el3_open(struct net_device *dev) 726static int el3_open(struct net_device *dev)
758{ 727{
759 struct el3_private *lp = netdev_priv(dev); 728 struct el3_private *lp = netdev_priv(dev);
760 dev_link_t *link = &lp->link; 729 struct pcmcia_device *link = lp->p_dev;
761 730
762 if (!DEV_OK(link)) 731 if (!pcmcia_dev_present(link))
763 return -ENODEV; 732 return -ENODEV;
764 733
765 link->open++; 734 link->open++;
@@ -1203,11 +1172,11 @@ static int el3_close(struct net_device *dev)
1203{ 1172{
1204 kio_addr_t ioaddr = dev->base_addr; 1173 kio_addr_t ioaddr = dev->base_addr;
1205 struct el3_private *lp = netdev_priv(dev); 1174 struct el3_private *lp = netdev_priv(dev);
1206 dev_link_t *link = &lp->link; 1175 struct pcmcia_device *link = lp->p_dev;
1207 1176
1208 DEBUG(2, "%s: shutting down ethercard.\n", dev->name); 1177 DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
1209 1178
1210 if (DEV_OK(link)) { 1179 if (pcmcia_dev_present(link)) {
1211 unsigned long flags; 1180 unsigned long flags;
1212 1181
1213 /* Turn off statistics ASAP. We update lp->stats below. */ 1182 /* Turn off statistics ASAP. We update lp->stats below. */
@@ -1246,7 +1215,7 @@ static struct pcmcia_driver tc574_driver = {
1246 .drv = { 1215 .drv = {
1247 .name = "3c574_cs", 1216 .name = "3c574_cs",
1248 }, 1217 },
1249 .probe = tc574_attach, 1218 .probe = tc574_probe,
1250 .remove = tc574_detach, 1219 .remove = tc574_detach,
1251 .id_table = tc574_ids, 1220 .id_table = tc574_ids,
1252 .suspend = tc574_suspend, 1221 .suspend = tc574_suspend,