aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/typhoon.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-03-01 23:24:32 -0500
committerDavid S. Miller <davem@davemloft.net>2009-03-01 23:24:32 -0500
commitd517c4a1da590a7fa50325a5e5cd18f07e8fb5a7 (patch)
tree75e267695e3d208d68f4097e3915905424d54ba1 /drivers/net/typhoon.c
parente8e26350f114fa212e277ea02332d9347c59865d (diff)
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 <davem@davemloft.net>
Diffstat (limited to 'drivers/net/typhoon.c')
-rw-r--r--drivers/net/typhoon.c27
1 files changed, 20 insertions, 7 deletions
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)
1347} 1347}
1348 1348
1349static const struct firmware *typhoon_fw; 1349static const struct firmware *typhoon_fw;
1350static u8 *typhoon_fw_image;
1350 1351
1351static int 1352static int
1352typhoon_request_firmware(struct typhoon *tp) 1353typhoon_request_firmware(struct typhoon *tp)
@@ -1367,12 +1368,22 @@ typhoon_request_firmware(struct typhoon *tp)
1367 memcmp(typhoon_fw->data, "TYPHOON", 8)) { 1368 memcmp(typhoon_fw->data, "TYPHOON", 8)) {
1368 printk(KERN_ERR "%s: Invalid firmware image\n", 1369 printk(KERN_ERR "%s: Invalid firmware image\n",
1369 tp->name); 1370 tp->name);
1370 release_firmware(typhoon_fw); 1371 err = -EINVAL;
1371 typhoon_fw = NULL; 1372 goto out_err;
1372 return -EINVAL; 1373 }
1374
1375 typhoon_fw_image = kmalloc(typhoon_fw->size, GFP_KERNEL);
1376 if (!typhoon_fw_image) {
1377 err = -ENOMEM;
1378 goto out_err;
1373 } 1379 }
1374 1380
1375 return 0; 1381 return 0;
1382
1383out_err:
1384 release_firmware(typhoon_fw);
1385 typhoon_fw = NULL;
1386 return err;
1376} 1387}
1377 1388
1378static int 1389static int
@@ -1394,11 +1405,11 @@ typhoon_download_firmware(struct typhoon *tp)
1394 int i; 1405 int i;
1395 int err; 1406 int err;
1396 1407
1397 image_data = typhoon_fw->data; 1408 image_data = typhoon_fw_image;
1398 fHdr = (struct typhoon_file_header *) image_data; 1409 fHdr = (struct typhoon_file_header *) image_data;
1399 1410
1400 err = -ENOMEM; 1411 err = -ENOMEM;
1401 image_dma = pci_map_single(pdev, (u8 *) typhoon_fw->data, 1412 image_dma = pci_map_single(pdev, (u8 *) image_data,
1402 typhoon_fw->size, PCI_DMA_TODEVICE); 1413 typhoon_fw->size, PCI_DMA_TODEVICE);
1403 if (pci_dma_mapping_error(pdev, image_dma)) { 1414 if (pci_dma_mapping_error(pdev, image_dma)) {
1404 printk(KERN_ERR "%s: no DMA mem for firmware\n", tp->name); 1415 printk(KERN_ERR "%s: no DMA mem for firmware\n", tp->name);
@@ -1469,7 +1480,7 @@ typhoon_download_firmware(struct typhoon *tp)
1469 iowrite32(load_addr, 1480 iowrite32(load_addr,
1470 ioaddr + TYPHOON_REG_BOOT_DEST_ADDR); 1481 ioaddr + TYPHOON_REG_BOOT_DEST_ADDR);
1471 iowrite32(0, ioaddr + TYPHOON_REG_BOOT_DATA_HI); 1482 iowrite32(0, ioaddr + TYPHOON_REG_BOOT_DATA_HI);
1472 iowrite32(image_dma + (image_data - typhoon_fw->data), 1483 iowrite32(image_dma + (image_data - typhoon_fw_image),
1473 ioaddr + TYPHOON_REG_BOOT_DATA_LO); 1484 ioaddr + TYPHOON_REG_BOOT_DATA_LO);
1474 typhoon_post_pci_writes(ioaddr); 1485 typhoon_post_pci_writes(ioaddr);
1475 iowrite32(TYPHOON_BOOTCMD_SEG_AVAILABLE, 1486 iowrite32(TYPHOON_BOOTCMD_SEG_AVAILABLE,
@@ -2639,8 +2650,10 @@ typhoon_init(void)
2639static void __exit 2650static void __exit
2640typhoon_cleanup(void) 2651typhoon_cleanup(void)
2641{ 2652{
2642 if (typhoon_fw) 2653 if (typhoon_fw) {
2654 kfree(typhoon_fw_image);
2643 release_firmware(typhoon_fw); 2655 release_firmware(typhoon_fw);
2656 }
2644 pci_unregister_driver(&typhoon_driver); 2657 pci_unregister_driver(&typhoon_driver);
2645} 2658}
2646 2659