On Tue, Jun 27, 2006 at 12:14:41AM +0200, Rodolfo Giometti wrote: > > I notice that during sleep/wakeup au1000_lowlevel_probe() tries to > access to variables arcs_cmdline,prom_envp & Co.. This sometime does > an oops. Here my proposal to avoid oops during wake up. Ciao, Rodolfo -- GNU/Linux Solutions e-mail: giometti@xxxxxxxxxxxx Linux Device Driver giometti@xxxxxxxxx Embedded Systems giometti@xxxxxxxx UNIX programming phone: +39 349 2432127
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 341fdc4..c49004a 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -84,7 +84,7 @@ MODULE_LICENSE("GPL"); // prototypes static void hard_stop(struct net_device *); static void enable_rx_tx(struct net_device *dev); -static int au1000_lowlevel_probe(struct net_device *ndev, void *ioaddr, void *macen_addr, int port_num); +static int au1000_lowlevel_probe(struct net_device *ndev, void *ioaddr, void *macen_addr, int port_num, int skip_prom); static void au1000_lowlevel_remove(struct net_device *ndev); static int au1000_init(struct net_device *); static int au1000_open(struct net_device *); @@ -1393,7 +1393,7 @@ static struct ethtool_ops au1000_ethtool }; static int -au1000_lowlevel_probe(struct net_device *ndev, void *ioaddr, void *macen_addr, int port_num) +au1000_lowlevel_probe(struct net_device *ndev, void *ioaddr, void *macen_addr, int port_num, int skip_prom) { struct au1000_private *aup = ndev->priv; db_dest_t *pDB, *pDBfree; @@ -1419,24 +1419,25 @@ au1000_lowlevel_probe(struct net_device /* Setup some variables for quick register address access */ if (port_num == 0) { - /* check env variables first */ - if (!get_ethernet_addr(ethaddr)) { - memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); - } else { - /* Check command line */ - argptr = prom_getcmdline(); - if ((pmac = strstr(argptr, "ethaddr=")) == NULL) { - printk(KERN_INFO "%s: No mac address found\n", - ndev->name); - /* use the hard coded mac addresses */ + if (!skip_prom) { + /* check env variables first */ + if (!get_ethernet_addr(ethaddr)) { + memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); } else { - str2eaddr(ethaddr, pmac + strlen("ethaddr=")); - memcpy(au1000_mac_addr, ethaddr, - sizeof(au1000_mac_addr)); + /* Check command line */ + argptr = prom_getcmdline(); + if ((pmac = strstr(argptr, "ethaddr=")) == NULL) { + printk(KERN_INFO "%s: No mac address found\n", + ndev->name); + /* use the hard coded mac addresses */ + } else { + str2eaddr(ethaddr, pmac + strlen("ethaddr=")); + memcpy(au1000_mac_addr, ethaddr, + sizeof(au1000_mac_addr)); + } } } - aup->enable = (volatile u32 *) - ((unsigned long) macen_addr); + aup->enable = (volatile u32 *) ((unsigned long) macen_addr); memcpy(ndev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); aup->mac_id = 0; @@ -2196,7 +2197,7 @@ static int au1000_drv_probe(struct devic /* Force the device name to a know state... */ sprintf(ndev->name, "au1xxx_eth(%d)", pdev->id); - ret = au1000_lowlevel_probe(ndev, base_addr, macen_addr, pdev->id); + ret = au1000_lowlevel_probe(ndev, base_addr, macen_addr, pdev->id, 0); if (ret < 0) { printk (KERN_ERR "%s: low level probe failed\n", DRV_NAME); goto out_free_netdev; @@ -2304,7 +2305,7 @@ static int au1000_drv_resume(struct devi if (!ndev) return 0; - ret = au1000_lowlevel_probe(ndev, (void *) aup->mac, (void *) aup->enable, aup->mac_id); + ret = au1000_lowlevel_probe(ndev, (void *) aup->mac, (void *) aup->enable, aup->mac_id, ~0); if (ret < 0) { printk (KERN_ERR "%s: low level probe failed\n", DRV_NAME); return ret;
Attachment:
signature.asc
Description: Digital signature