| Summary: | le nic driver causes kernel panic | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Vladimir Kurtukov <vk> |
| Component: | kern | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 4.2-STABLE | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->closed Fixed. Not actually fixed. ifconfig'ing an address on an le NIC card still causes a panic in 4.5. See the patch I submitted in a followup to a related older PR, PR18641. The patch fixes the problem for me in 4.5. http://www.freebsd.org/cgi/query-pr.cgi?pr=18641 andrew |
le nic driver is broken: driver interface was changed but driver was incorrectly updated to new interface. Generic ether_ioctl from if_ethersubr.c make nic initialization in a way like this: ifp->if_init(ifp->if_softc); But lemac_init or lance_init functions from if_le.c have another syntax, they need unit number as an argument. Correct way for le driver is: (*sc->if_init)(ifp->if_unit); Fix: Here is my patch (code taken from 3.5-STABLE): --- if_le.std Tue Jul 18 05:24:30 2000 +++ if_le.new Sat Mar 10 17:05:01 2001 @@ -441,7 +441,66 @@ s = splimp(); switch (cmd) { - case SIOCSIFADDR: + case SIOCSIFADDR: { + struct ifaddr *ifa = (struct ifaddr *)data; + + ifp->if_flags |= IFF_UP; + switch(ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: { + (*sc->if_init)(ifp->if_unit); + arp_ifinit((struct arpcom *)ifp, ifa); + break; + } +#endif /* INET */ +#ifdef IPX + /* This magic copied from if_is.c; I don't use XNS, + * so I have no way of telling if this actually + * works or not. + */ + case AF_IPX: { + struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); + if (ipx_nullhost(*ina)) { + ina->x_host = *(union ipx_host *)(sc->le_ac.ac_enaddr); + } else { + ifp->if_flags &= ~IFF_RUNNING; + bcopy((caddr_t)ina->x_host.c_host, + (caddr_t)sc->le_ac.ac_enaddr, + sizeof sc->le_ac.ac_enaddr); + } + + (*sc->if_init)(ifp->if_unit); + break; + } +#endif /* IPX */ +#ifdef NS + /* This magic copied from if_is.c; I don't use XNS, + * so I have no way of telling if this actually + * works or not. + */ + case AF_NS: { + struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); + if (ns_nullhost(*ina)) { + ina->x_host = *(union ns_host *)(sc->le_ac.ac_enaddr); + } else { + ifp->if_flags &= ~IFF_RUNNING; + bcopy((caddr_t)ina->x_host.c_host, + (caddr_t)sc->le_ac.ac_enaddr, + sizeof sc->le_ac.ac_enaddr); + } + + (*sc->if_init)(ifp->if_unit); + break; + } +#endif /* NS */ + default: { + (*sc->if_init)(ifp->if_unit); + break; + } + } + break; + } + case SIOCGIFADDR: case SIOCSIFMTU: error = ether_ioctl(ifp, cmd, data); How-To-Repeat: Compile in le driver into kernel and try to assign an IP address for it - result will be immediate kernel panic