> From [EMAIL PROTECTED] Tue Oct 23 10:51:00 2007 > Date: Tue, 23 Oct 2007 21:40:18 +0400 > From: Valentine Barshak <[EMAIL PROTECTED]> > To: [EMAIL PROTECTED] > Cc: netdev@vger.kernel.org > Subject: [linux-usb-devel] [PATCH] USB: net: Fix asix read transfer buffer > allocations. > > On systems with noncoherent cache, allocating dma buffers > on the stack for USB IN transfers causes kernel crash, > because usb map_urb_for_dma() code calls dma_map_single(), > that invalidates data cache for DMA_FROM_DEVICE transfer direction > and causes stack data loss if transfer size is less than cache line > and not cache-line aligned. This patch makes asix usb network > driver allocate USB IN transfer buffers with kmalloc instead of > directly using variables on stack. It also sets data parameter to NULL > for zero-length transfers and uses ETH_ALEN size for allocating MAC > address buffer.
Looks plausible to me, on a quick scan, but you should CC Dave Hollis for updates to this drver ... last I knew, he was still maintaining this code. (Though he's not listed in MAINTAINERS...) This is missing a Signed-Off-By line ... > diff -pruN linux-2.6.orig/drivers/net/usb/asix.c > linux-2.6/drivers/net/usb/asix.c > --- linux-2.6.orig/drivers/net/usb/asix.c 2007-10-23 20:52:11.000000000 > +0400 > +++ linux-2.6/drivers/net/usb/asix.c 2007-10-23 20:57:38.000000000 +0400 > @@ -568,15 +568,23 @@ static void asix_set_multicast(struct ne > static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) > { > struct usbnet *dev = netdev_priv(netdev); > + void *buf; > u16 res; > > + buf = kmalloc(2, GFP_KERNEL); > + if (!buf) > + return -ENOMEM; > + > mutex_lock(&dev->phy_mutex); > asix_set_sw_mii(dev); > asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, > - (__u16)loc, 2, (u16 *)&res); > + (__u16)loc, 2, buf); > asix_set_hw_mii(dev); > mutex_unlock(&dev->phy_mutex); > > + res = *((u16 *)buf); > + kfree(buf); > + > devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, > returns=0x%04x", phy_id, loc, le16_to_cpu(res & 0xffff)); > > return le16_to_cpu(res & 0xffff); > @@ -622,13 +630,22 @@ static void > asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) > { > struct usbnet *dev = netdev_priv(net); > + void *buf; > u8 opt; > > - if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { > + buf = kmalloc(1, GFP_KERNEL); > + if (!buf) > + return; > + > + if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, buf) < 0) { > wolinfo->supported = 0; > wolinfo->wolopts = 0; > + kfree(buf); > return; > } > + opt = *((u8 *)buf); > + kfree(buf); > + > wolinfo->supported = WAKE_PHY | WAKE_MAGIC; > wolinfo->wolopts = 0; > if (opt & AX_MONITOR_MODE) { > @@ -644,7 +661,6 @@ asix_set_wol(struct net_device *net, str > { > struct usbnet *dev = netdev_priv(net); > u8 opt = 0; > - u8 buf[1]; > > if (wolinfo->wolopts & WAKE_PHY) > opt |= AX_MONITOR_LINK; > @@ -654,7 +670,7 @@ asix_set_wol(struct net_device *net, str > opt |= AX_MONITOR_MODE; > > if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, > - opt, 0, 0, &buf) < 0) > + opt, 0, 0, NULL) < 0) > return -EINVAL; > > return 0; > @@ -820,7 +836,7 @@ static int ax88172_bind(struct usbnet *d > for (i = 2; i >= 0; i--) { > if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, > (gpio_bits >> (i * 8)) & 0xff, 0, 0, > - buf)) < 0) > + NULL)) < 0) > goto out2; > msleep(5); > } > @@ -831,7 +847,7 @@ static int ax88172_bind(struct usbnet *d > /* Get the MAC address */ > memset(buf, 0, ETH_ALEN); > if ((ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID, > - 0, 0, 6, buf)) < 0) { > + 0, 0, ETH_ALEN, buf)) < 0) { > dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); > goto out2; > } > @@ -909,7 +925,7 @@ static int ax88772_bind(struct usbnet *d > > usbnet_get_endpoints(dev,intf); > > - buf = kmalloc(6, GFP_KERNEL); > + buf = kmalloc(ETH_ALEN, GFP_KERNEL); > if(!buf) { > dbg ("Cannot allocate memory for buffer"); > ret = -ENOMEM; > @@ -923,7 +939,7 @@ static int ax88772_bind(struct usbnet *d > /* 0x10 is the phy id of the embedded 10/100 ethernet phy */ > embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); > if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, > - embd_phy, 0, 0, buf)) < 0) { > + embd_phy, 0, 0, NULL)) < 0) { > dbg("Select PHY #1 failed: %d", ret); > goto out2; > } > @@ -998,7 +1014,7 @@ static int ax88772_bind(struct usbnet *d > > if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, > AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, > - AX88772_IPG2_DEFAULT, 0, buf)) < 0) { > + AX88772_IPG2_DEFAULT, 0, NULL)) < 0) { > dbg("Write IPG,IPG1,IPG2 failed: %d", ret); > goto out2; > } > @@ -1202,20 +1218,22 @@ static int ax88178_bind(struct usbnet *d > > usbnet_get_endpoints(dev,intf); > > - buf = kmalloc(6, GFP_KERNEL); > + buf = kmalloc(ETH_ALEN, GFP_KERNEL); > if(!buf) { > dbg ("Cannot allocate memory for buffer"); > ret = -ENOMEM; > goto out1; > } > > - eeprom = 0; > - asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &eeprom); > + memset(buf, 0, ETH_ALEN); > + asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, buf); > + eeprom = *(u8 *)buf; > dbg("GPIO Status: 0x%04x", eeprom); > > asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL); > - asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom); > + asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, buf); > asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL); > + eeprom = *(u16 *)buf; > > dbg("EEPROM index 0x17 is 0x%04x", eeprom); > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Splunk Inc. > Still grepping through log files to find problems? Stop. > Now Search log events and configuration files using AJAX and a browser. > Download your FREE copy of Splunk now >> http://get.splunk.com/ > _______________________________________________ > [EMAIL PROTECTED] > To unsubscribe, use the last form field at: > https://lists.sourceforge.net/lists/listinfo/linux-usb-devel > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html