From: David S. Miller Date: Mon, 2 Mar 2009 04:24:32 +0000 (-0800) Subject: typhoon: Need non-vmalloc memory to DMA firmware to the card. X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=d517c4a1da590a7fa50325a5e5cd18f07e8fb5a7;p=openwrt%2Fstaging%2Fblogic.git typhoon: Need non-vmalloc memory to DMA firmware to the card. request_firmware() gives vmalloc'd memory, which is not suitable for pci_map_single() and friends. Use a kmalloc()'d copy of the firmware for this DMA operation. Signed-off-by: David S. Miller --- diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index cd3283f766d9..ec2541c8c229 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1347,6 +1347,7 @@ typhoon_init_rings(struct typhoon *tp) } static const struct firmware *typhoon_fw; +static u8 *typhoon_fw_image; static int typhoon_request_firmware(struct typhoon *tp) @@ -1367,12 +1368,22 @@ typhoon_request_firmware(struct typhoon *tp) memcmp(typhoon_fw->data, "TYPHOON", 8)) { printk(KERN_ERR "%s: Invalid firmware image\n", tp->name); - release_firmware(typhoon_fw); - typhoon_fw = NULL; - return -EINVAL; + err = -EINVAL; + goto out_err; + } + + typhoon_fw_image = kmalloc(typhoon_fw->size, GFP_KERNEL); + if (!typhoon_fw_image) { + err = -ENOMEM; + goto out_err; } return 0; + +out_err: + release_firmware(typhoon_fw); + typhoon_fw = NULL; + return err; } static int @@ -1394,11 +1405,11 @@ typhoon_download_firmware(struct typhoon *tp) int i; int err; - image_data = typhoon_fw->data; + image_data = typhoon_fw_image; fHdr = (struct typhoon_file_header *) image_data; err = -ENOMEM; - image_dma = pci_map_single(pdev, (u8 *) typhoon_fw->data, + image_dma = pci_map_single(pdev, (u8 *) image_data, typhoon_fw->size, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(pdev, image_dma)) { printk(KERN_ERR "%s: no DMA mem for firmware\n", tp->name); @@ -1469,7 +1480,7 @@ typhoon_download_firmware(struct typhoon *tp) iowrite32(load_addr, ioaddr + TYPHOON_REG_BOOT_DEST_ADDR); iowrite32(0, ioaddr + TYPHOON_REG_BOOT_DATA_HI); - iowrite32(image_dma + (image_data - typhoon_fw->data), + iowrite32(image_dma + (image_data - typhoon_fw_image), ioaddr + TYPHOON_REG_BOOT_DATA_LO); typhoon_post_pci_writes(ioaddr); iowrite32(TYPHOON_BOOTCMD_SEG_AVAILABLE, @@ -2639,8 +2650,10 @@ typhoon_init(void) static void __exit typhoon_cleanup(void) { - if (typhoon_fw) + if (typhoon_fw) { + kfree(typhoon_fw_image); release_firmware(typhoon_fw); + } pci_unregister_driver(&typhoon_driver); }