Commit d517c4a1 authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parent e8e26350
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -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);
}