diff options
Diffstat (limited to 'drivers/net/pcmcia/3c574_cs.c')
-rw-r--r-- | drivers/net/pcmcia/3c574_cs.c | 115 |
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 | ||
206 | struct el3_private { | 206 | struct 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 | ||
228 | static void tc574_config(dev_link_t *link); | 228 | static int tc574_config(struct pcmcia_device *link); |
229 | static void tc574_release(dev_link_t *link); | 229 | static void tc574_release(struct pcmcia_device *link); |
230 | 230 | ||
231 | static void mdio_sync(kio_addr_t ioaddr, int bits); | 231 | static void mdio_sync(kio_addr_t ioaddr, int bits); |
232 | static int mdio_read(kio_addr_t ioaddr, int phy_id, int location); | 232 | static 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 | ||
259 | static int tc574_attach(struct pcmcia_device *p_dev) | 259 | static 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 | ||
319 | static void tc574_detach(struct pcmcia_device *p_dev) | 311 | static 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 | ||
344 | static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; | 334 | static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; |
345 | 335 | ||
346 | static void tc574_config(dev_link_t *link) | 336 | static 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 | ||
498 | cs_failed: | 483 | cs_failed: |
499 | cs_error(link->handle, last_fn, last_ret); | 484 | cs_error(link, last_fn, last_ret); |
500 | failed: | 485 | failed: |
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 | ||
512 | static void tc574_release(dev_link_t *link) | 497 | static 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 | ||
523 | static int tc574_suspend(struct pcmcia_device *p_dev) | 502 | static 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 | ||
538 | static int tc574_resume(struct pcmcia_device *p_dev) | 512 | static 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) | |||
757 | static int el3_open(struct net_device *dev) | 726 | static 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, |