Go to the source code of this file.
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| int | undinet_probe (struct undi_device *undi) |
| Probe UNDI device. | |
| void | undinet_remove (struct undi_device *undi) |
| Remove UNDI device. | |
Definition in file undinet.h.
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| int undinet_probe | ( | struct undi_device * | undi | ) |
Probe UNDI device.
| undi | UNDI device |
| rc | Return status code |
Definition at line 464 of file undinet.c.
References alloc_etherdev(), s_PXENV_START_UNDI::AX, BIOS_SEG, s_PXENV_START_UNDI::BX, DBGC, undi_device::dev, net_device::dev, s_PXENV_START_UNDI::DI, s_PXENV_START_UNDI::DX, ENOMEM, undi_device::entry, s_PXENV_START_UNDI::ES, ETH_ALEN, eth_ntoa(), find_pnp_bios(), undi_device::flags, undi_nic::hacks, net_device::hw_addr, s_PXENV_UNDI_GET_IFACE_INFO::IfaceType, s_PXENV_UNDI_GET_INFORMATION::IntNumber, undi_nic::irq, IRQ_MAX, undi_device::isapnp_csn, undi_device::isapnp_read_port, s_PXENV_UNDI_GET_IFACE_INFO::LinkSpeed, memcpy, memset(), netdev, netdev_init(), netdev_link_up(), netdev_nullify(), netdev_put(), NULL, undi_device::pci_busdevfn, s_PXENV_UNDI_GET_INFORMATION::PermNodeAddress, net_device::priv, PXENV_START_UNDI, PXENV_STOP_UNDI, PXENV_UNDI_CLEANUP, PXENV_UNDI_GET_IFACE_INFO, PXENV_UNDI_GET_INFORMATION, PXENV_UNDI_INITIALIZE, PXENV_UNDI_SHUTDOWN, PXENV_UNDI_STARTUP, pxeparent_call(), register_netdev(), s_PXENV_UNDI_GET_IFACE_INFO::ServiceFlags, strncmp(), UNDI_FL_INITIALIZED, UNDI_FL_STARTED, UNDI_HACK_EB54, and undi_set_drvdata().
Referenced by undibus_probe(), and undipci_probe().
00464 { 00465 struct net_device *netdev; 00466 struct undi_nic *undinic; 00467 struct s_PXENV_START_UNDI start_undi; 00468 struct s_PXENV_UNDI_STARTUP undi_startup; 00469 struct s_PXENV_UNDI_INITIALIZE undi_initialize; 00470 struct s_PXENV_UNDI_GET_INFORMATION undi_info; 00471 struct s_PXENV_UNDI_GET_IFACE_INFO undi_iface; 00472 struct s_PXENV_UNDI_SHUTDOWN undi_shutdown; 00473 struct s_PXENV_UNDI_CLEANUP undi_cleanup; 00474 struct s_PXENV_STOP_UNDI stop_undi; 00475 int rc; 00476 00477 /* Allocate net device */ 00478 netdev = alloc_etherdev ( sizeof ( *undinic ) ); 00479 if ( ! netdev ) 00480 return -ENOMEM; 00481 netdev_init ( netdev, &undinet_operations ); 00482 undinic = netdev->priv; 00483 undi_set_drvdata ( undi, netdev ); 00484 netdev->dev = &undi->dev; 00485 memset ( undinic, 0, sizeof ( *undinic ) ); 00486 undinet_entry = undi->entry; 00487 DBGC ( undinic, "UNDINIC %p using UNDI %p\n", undinic, undi ); 00488 00489 /* Hook in UNDI stack */ 00490 if ( ! ( undi->flags & UNDI_FL_STARTED ) ) { 00491 memset ( &start_undi, 0, sizeof ( start_undi ) ); 00492 start_undi.AX = undi->pci_busdevfn; 00493 start_undi.BX = undi->isapnp_csn; 00494 start_undi.DX = undi->isapnp_read_port; 00495 start_undi.ES = BIOS_SEG; 00496 start_undi.DI = find_pnp_bios(); 00497 if ( ( rc = pxeparent_call ( undinet_entry, PXENV_START_UNDI, 00498 &start_undi, 00499 sizeof ( start_undi ) ) ) != 0 ) 00500 goto err_start_undi; 00501 } 00502 undi->flags |= UNDI_FL_STARTED; 00503 00504 /* Bring up UNDI stack */ 00505 if ( ! ( undi->flags & UNDI_FL_INITIALIZED ) ) { 00506 memset ( &undi_startup, 0, sizeof ( undi_startup ) ); 00507 if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_STARTUP, 00508 &undi_startup, 00509 sizeof ( undi_startup ) ) ) != 0 ) 00510 goto err_undi_startup; 00511 memset ( &undi_initialize, 0, sizeof ( undi_initialize ) ); 00512 if ( ( rc = pxeparent_call ( undinet_entry, 00513 PXENV_UNDI_INITIALIZE, 00514 &undi_initialize, 00515 sizeof ( undi_initialize ))) != 0 ) 00516 goto err_undi_initialize; 00517 } 00518 undi->flags |= UNDI_FL_INITIALIZED; 00519 00520 /* Get device information */ 00521 memset ( &undi_info, 0, sizeof ( undi_info ) ); 00522 if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_GET_INFORMATION, 00523 &undi_info, sizeof ( undi_info ) ) ) != 0 ) 00524 goto err_undi_get_information; 00525 memcpy ( netdev->hw_addr, undi_info.PermNodeAddress, ETH_ALEN ); 00526 undinic->irq = undi_info.IntNumber; 00527 if ( undinic->irq > IRQ_MAX ) { 00528 DBGC ( undinic, "UNDINIC %p invalid IRQ %d\n", 00529 undinic, undinic->irq ); 00530 goto err_bad_irq; 00531 } 00532 DBGC ( undinic, "UNDINIC %p is %s on IRQ %d\n", 00533 undinic, eth_ntoa ( netdev->hw_addr ), undinic->irq ); 00534 00535 /* Get interface information */ 00536 memset ( &undi_iface, 0, sizeof ( undi_iface ) ); 00537 if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_GET_IFACE_INFO, 00538 &undi_iface, 00539 sizeof ( undi_iface ) ) ) != 0 ) 00540 goto err_undi_get_iface_info; 00541 DBGC ( undinic, "UNDINIC %p has type %s, speed %d, flags %08x\n", 00542 undinic, undi_iface.IfaceType, undi_iface.LinkSpeed, 00543 undi_iface.ServiceFlags ); 00544 if ( strncmp ( ( ( char * ) undi_iface.IfaceType ), "Etherboot", 00545 sizeof ( undi_iface.IfaceType ) ) == 0 ) { 00546 DBGC ( undinic, "UNDINIC %p Etherboot 5.4 workaround enabled\n", 00547 undinic ); 00548 undinic->hacks |= UNDI_HACK_EB54; 00549 } 00550 00551 /* Mark as link up; we don't handle link state */ 00552 netdev_link_up ( netdev ); 00553 00554 /* Register network device */ 00555 if ( ( rc = register_netdev ( netdev ) ) != 0 ) 00556 goto err_register; 00557 00558 DBGC ( undinic, "UNDINIC %p added\n", undinic ); 00559 return 0; 00560 00561 err_register: 00562 err_undi_get_iface_info: 00563 err_bad_irq: 00564 err_undi_get_information: 00565 err_undi_initialize: 00566 /* Shut down UNDI stack */ 00567 memset ( &undi_shutdown, 0, sizeof ( undi_shutdown ) ); 00568 pxeparent_call ( undinet_entry, PXENV_UNDI_SHUTDOWN, &undi_shutdown, 00569 sizeof ( undi_shutdown ) ); 00570 memset ( &undi_cleanup, 0, sizeof ( undi_cleanup ) ); 00571 pxeparent_call ( undinet_entry, PXENV_UNDI_CLEANUP, &undi_cleanup, 00572 sizeof ( undi_cleanup ) ); 00573 undi->flags &= ~UNDI_FL_INITIALIZED; 00574 err_undi_startup: 00575 /* Unhook UNDI stack */ 00576 memset ( &stop_undi, 0, sizeof ( stop_undi ) ); 00577 pxeparent_call ( undinet_entry, PXENV_STOP_UNDI, &stop_undi, 00578 sizeof ( stop_undi ) ); 00579 undi->flags &= ~UNDI_FL_STARTED; 00580 err_start_undi: 00581 netdev_nullify ( netdev ); 00582 netdev_put ( netdev ); 00583 undi_set_drvdata ( undi, NULL ); 00584 return rc; 00585 }
| void undinet_remove | ( | struct undi_device * | undi | ) |
Remove UNDI device.
| undi | UNDI device |
Definition at line 592 of file undinet.c.
References DBGC, undi_device::flags, memset(), netdev, netdev_nullify(), netdev_put(), net_device::priv, PXENV_STOP_UNDI, PXENV_UNDI_CLEANUP, PXENV_UNDI_SHUTDOWN, pxeparent_call(), UNDI_FL_INITIALIZED, UNDI_FL_KEEP_ALL, UNDI_FL_STARTED, undi_get_drvdata(), and unregister_netdev().
Referenced by undibus_remove(), and undipci_remove().
00592 { 00593 struct net_device *netdev = undi_get_drvdata ( undi ); 00594 struct undi_nic *undinic = netdev->priv; 00595 struct s_PXENV_UNDI_SHUTDOWN undi_shutdown; 00596 struct s_PXENV_UNDI_CLEANUP undi_cleanup; 00597 struct s_PXENV_STOP_UNDI stop_undi; 00598 00599 /* Unregister net device */ 00600 unregister_netdev ( netdev ); 00601 00602 /* If we are preparing for an OS boot, or if we cannot exit 00603 * via the PXE stack, then shut down the PXE stack. 00604 */ 00605 if ( ! ( undi->flags & UNDI_FL_KEEP_ALL ) ) { 00606 00607 /* Shut down UNDI stack */ 00608 memset ( &undi_shutdown, 0, sizeof ( undi_shutdown ) ); 00609 pxeparent_call ( undinet_entry, PXENV_UNDI_SHUTDOWN, 00610 &undi_shutdown, sizeof ( undi_shutdown ) ); 00611 memset ( &undi_cleanup, 0, sizeof ( undi_cleanup ) ); 00612 pxeparent_call ( undinet_entry, PXENV_UNDI_CLEANUP, 00613 &undi_cleanup, sizeof ( undi_cleanup ) ); 00614 undi->flags &= ~UNDI_FL_INITIALIZED; 00615 00616 /* Unhook UNDI stack */ 00617 memset ( &stop_undi, 0, sizeof ( stop_undi ) ); 00618 pxeparent_call ( undinet_entry, PXENV_STOP_UNDI, &stop_undi, 00619 sizeof ( stop_undi ) ); 00620 undi->flags &= ~UNDI_FL_STARTED; 00621 } 00622 00623 /* Clear entry point */ 00624 memset ( &undinet_entry, 0, sizeof ( undinet_entry ) ); 00625 00626 /* Free network device */ 00627 netdev_nullify ( netdev ); 00628 netdev_put ( netdev ); 00629 00630 DBGC ( undinic, "UNDINIC %p removed\n", undinic ); 00631 }
1.5.7.1