# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.656 -> 1.657 # drivers/usb/net/kaweth.c 1.26 -> 1.27 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/09/12 oliver@neukum.name 1.657 # [PATCH] fixes for races in kaweth probe # # using init_etherdev(0, 0) in probe is a race. The struct net_device must be # allocate and filled before init_etherdev is called, or there's a race which # creates a network interface that isn't usable. # The patch for kaweth for 2.5 fixes it. # -------------------------------------------- # diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c --- a/drivers/usb/net/kaweth.c Thu Sep 12 10:25:38 2002 +++ b/drivers/usb/net/kaweth.c Thu Sep 12 10:25:38 2002 @@ -854,6 +854,7 @@ ) { struct kaweth_device *kaweth; + struct net_device *netdev; const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; int result = 0; @@ -869,10 +870,8 @@ (int)dev->descriptor.bLength, (int)dev->descriptor.bDescriptorType); - if(!(kaweth = kmalloc(sizeof(struct kaweth_device), GFP_KERNEL))) { - kaweth_dbg("out of memory allocating device structure\n"); + if(!(kaweth = kmalloc(sizeof(struct kaweth_device), GFP_KERNEL))) return NULL; - } memset(kaweth, 0, sizeof(struct kaweth_device)); @@ -998,11 +997,17 @@ if(result < 0) { kaweth_err("Error setting receive filter"); - return kaweth; + kfree(kaweth); + return NULL; } kaweth_dbg("Initializing net device."); + if(!(netdev = kmalloc(sizeof(struct net_device), GFP_KERNEL))) { + kfree(kaweth); + return NULL; + } + kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!kaweth->tx_urb) goto err_no_urb; @@ -1013,12 +1018,7 @@ if (!kaweth->irq_urb) goto err_tx_and_rx; - kaweth->net = init_etherdev(0, 0); - if (!kaweth->net) { - kaweth_err("Error calling init_etherdev."); - return kaweth; - } - + kaweth->net = netdev; memcpy(kaweth->net->broadcast, &bcast_addr, sizeof(bcast_addr)); memcpy(kaweth->net->dev_addr, &kaweth->configuration.hw_addr, @@ -1038,6 +1038,13 @@ kaweth->net->mtu = le16_to_cpu(kaweth->configuration.segment_size); memset(&kaweth->stats, 0, sizeof(kaweth->stats)); + + SET_MODULE_OWNER(netdev); + + if (!init_etherdev(netdev, 0)) { + kaweth_err("Error calling init_etherdev."); + goto err_tx_and_rx; + } kaweth_info("kaweth interface created at %s", kaweth->net->name); @@ -1051,6 +1058,7 @@ usb_free_urb(kaweth->tx_urb); err_no_urb: kfree(kaweth); + kfree(netdev); return NULL; }