[kernel] r12971 - dists/trunk/linux-2.6/debian/patches/features/all

Ben Hutchings benh at alioth.debian.org
Thu Mar 5 04:03:54 UTC 2009


Author: benh
Date: Thu Mar  5 04:03:52 2009
New Revision: 12971

Log:
Update typhoon request_firmware() patch to reviewed and tested version


Modified:
   dists/trunk/linux-2.6/debian/patches/features/all/drivers-net-typhoon-request_firmware.patch

Modified: dists/trunk/linux-2.6/debian/patches/features/all/drivers-net-typhoon-request_firmware.patch
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/features/all/drivers-net-typhoon-request_firmware.patch	(original)
+++ dists/trunk/linux-2.6/debian/patches/features/all/drivers-net-typhoon-request_firmware.patch	Thu Mar  5 04:03:52 2009
@@ -1,18 +1,14 @@
-commit b775a750c3afacbfac884537d466d34d50b1023b
+commit 3185588805914cbaedae010d9c7f238f119a4ed3
 Author: Ben Hutchings <ben at decadent.org.uk>
-Date:   Thu Feb 26 23:21:23 2009 -0800
+Date:   Sun Feb 22 19:25:27 2009 +0000
 
     typhoon: Use request_firmware()
     
-    Based on a patch by Jaswinder Singh <jaswinder at infradead.org>.
-    
-    Compile-tested only.
-    
-    Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
-    Signed-off-by: David S. Miller <davem at davemloft.net>
+    Based on a patch by Jaswinder Singh <jaswinder at infradead.org> and
+    fixes for my bugs by David Dillow <dave at thedillows.org>.
 
 diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
-index c639aea..334472d 100644
+index 05f99fd..6134136 100644
 --- a/drivers/net/Kconfig
 +++ b/drivers/net/Kconfig
 @@ -733,7 +733,7 @@ config VORTEX
@@ -25,10 +21,18 @@
  	---help---
  	  This option enables driver support for the 3cr990 series of cards:
 diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
-index a8e5651..cd3283f 100644
+index 3af9a95..e907e86 100644
 --- a/drivers/net/typhoon.c
 +++ b/drivers/net/typhoon.c
-@@ -129,16 +129,18 @@ static const int multicast_filter_limit = 32;
+@@ -104,6 +104,7 @@ static const int multicast_filter_limit = 32;
+ #define DRV_MODULE_RELDATE	"06/11/09"
+ #define PFX			DRV_MODULE_NAME ": "
+ #define ERR_PFX			KERN_ERR PFX
++#define FIRMWARE_NAME		"3com/typhoon.bin"
+ 
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+@@ -129,9 +130,9 @@ static const int multicast_filter_limit = 32;
  #include <asm/uaccess.h>
  #include <linux/in6.h>
  #include <linux/dma-mapping.h>
@@ -39,8 +43,7 @@
  
  static char version[] __devinitdata =
      "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
- 
-+#define FIRMWARE_NAME		"3com/typhoon.bin"
+@@ -139,6 +140,7 @@ static char version[] __devinitdata =
  MODULE_AUTHOR("David Dillow <dave at thedillows.org>");
  MODULE_VERSION(DRV_MODULE_VERSION);
  MODULE_LICENSE("GPL");
@@ -48,7 +51,7 @@
  MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)");
  MODULE_PARM_DESC(rx_copybreak, "Packets smaller than this are copied and "
  			       "the buffer given back to the NIC. Default "
-@@ -1344,45 +1346,61 @@ typhoon_init_rings(struct typhoon *tp)
+@@ -1344,14 +1346,74 @@ typhoon_init_rings(struct typhoon *tp)
  	tp->txHiRing.lastRead = 0;
  }
  
@@ -57,6 +60,12 @@
 +static int
 +typhoon_request_firmware(struct typhoon *tp)
 +{
++	const struct typhoon_file_header *fHdr;
++	const struct typhoon_section_header *sHdr;
++	const u8 *image_data;
++	u32 numSections;
++	u32 section_len;
++	u32 remaining;
 +	int err;
 +
 +	if (typhoon_fw)
@@ -65,20 +74,45 @@
 +	err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev);
 +	if (err) {
 +		printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
-+		       tp->name, FIRMWARE_NAME);
++				tp->name, FIRMWARE_NAME);
 +		return err;
 +	}
 +
-+	if (typhoon_fw->size < sizeof(struct typhoon_file_header) ||
-+	    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;
++	image_data = (u8 *) typhoon_fw->data;
++	remaining = typhoon_fw->size;
++	if (remaining < sizeof(struct typhoon_file_header))
++		goto invalid_fw;
++
++	fHdr = (struct typhoon_file_header *) image_data;
++	if (memcmp(fHdr->tag, "TYPHOON", 8))
++		goto invalid_fw;
++
++	numSections = le32_to_cpu(fHdr->numSections);
++	image_data += sizeof(struct typhoon_file_header);
++	remaining -= sizeof(struct typhoon_file_header);
++
++	while (numSections--) {
++		if (remaining < sizeof(struct typhoon_section_header))
++			goto invalid_fw;
++
++		sHdr = (struct typhoon_section_header *) image_data;
++		image_data += sizeof(struct typhoon_section_header);
++		section_len = le32_to_cpu(sHdr->len);
++
++		if (remaining < section_len)
++			goto invalid_fw;
++
++		image_data += section_len;
++		remaining -= section_len;
 +	}
 +
 +	return 0;
++
++invalid_fw:
++	printk(KERN_ERR "%s: Invalid firmware image\n", tp->name);
++	release_firmware(typhoon_fw);
++	typhoon_fw = NULL;
++	return -EINVAL;
 +}
 +
  static int
@@ -89,20 +123,13 @@
 -	struct typhoon_file_header *fHdr;
 -	struct typhoon_section_header *sHdr;
 -	u8 *image_data;
--	void *dpage;
--	dma_addr_t dpage_dma;
 +	const struct typhoon_file_header *fHdr;
 +	const struct typhoon_section_header *sHdr;
 +	const u8 *image_data;
-+	dma_addr_t image_dma;
+ 	void *dpage;
+ 	dma_addr_t dpage_dma;
  	__sum16 csum;
- 	u32 irqEnabled;
- 	u32 irqMasked;
- 	u32 numSections;
- 	u32 section_len;
--	u32 len;
- 	u32 load_addr;
- 	u32 hmac;
+@@ -1365,20 +1427,12 @@ typhoon_download_firmware(struct typhoon *tp)
  	int i;
  	int err;
  
@@ -114,102 +141,20 @@
 -		printk(KERN_ERR "%s: Invalid firmware image!\n", tp->name);
 -		goto err_out;
 -	}
-+	image_data = typhoon_fw->data;
++	image_data = (u8 *) typhoon_fw->data;
 +	fHdr = (struct typhoon_file_header *) image_data;
  
--	/* Cannot just map the firmware image using pci_map_single() as
+ 	/* Cannot just map the firmware image using pci_map_single() as
 -	 * the firmware is part of the kernel/module image, so we allocate
 -	 * some consistent memory to copy the sections into, as it is simpler,
 -	 * and short-lived. If we ever split out and require a userland
 -	 * firmware loader, then we can revisit this.
--	 */
++	 * the firmware is vmalloc()'d and may not be physically contiguous,
++	 * so we allocate some consistent memory to copy the sections into.
+ 	 */
  	err = -ENOMEM;
--	dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma);
--	if(!dpage) {
-+	image_dma = pci_map_single(pdev, (u8 *) typhoon_fw->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);
- 		goto err_out;
- 	}
-@@ -1430,41 +1448,34 @@ typhoon_download_firmware(struct typhoon *tp)
- 		load_addr = le32_to_cpu(sHdr->startAddr);
- 		section_len = le32_to_cpu(sHdr->len);
- 
--		while(section_len) {
--			len = min_t(u32, section_len, PAGE_SIZE);
-+		if (typhoon_wait_interrupt(ioaddr) < 0 ||
-+		    ioread32(ioaddr + TYPHOON_REG_STATUS) !=
-+		    TYPHOON_STATUS_WAITING_FOR_SEGMENT) {
-+			printk(KERN_ERR "%s: segment ready timeout\n",
-+			       tp->name);
-+			goto err_out_irq;
-+		}
- 
--			if(typhoon_wait_interrupt(ioaddr) < 0 ||
--			   ioread32(ioaddr + TYPHOON_REG_STATUS) !=
--			   TYPHOON_STATUS_WAITING_FOR_SEGMENT) {
--				printk(KERN_ERR "%s: segment ready timeout\n",
--				       tp->name);
--				goto err_out_irq;
--			}
-+		/* Do an pseudo IPv4 checksum on the data -- first
-+		 * need to convert each u16 to cpu order before
-+		 * summing. Fortunately, due to the properties of
-+		 * the checksum, we can do this once, at the end.
-+		 */
-+		csum = csum_fold(csum_partial(image_data, section_len, 0));
-+
-+		iowrite32(section_len, ioaddr + TYPHOON_REG_BOOT_LENGTH);
-+		iowrite32(le16_to_cpu((__force __le16)csum),
-+			  ioaddr + TYPHOON_REG_BOOT_CHECKSUM);
-+		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),
-+			  ioaddr + TYPHOON_REG_BOOT_DATA_LO);
-+		typhoon_post_pci_writes(ioaddr);
-+		iowrite32(TYPHOON_BOOTCMD_SEG_AVAILABLE,
-+			  ioaddr + TYPHOON_REG_COMMAND);
- 
--			/* Do an pseudo IPv4 checksum on the data -- first
--			 * need to convert each u16 to cpu order before
--			 * summing. Fortunately, due to the properties of
--			 * the checksum, we can do this once, at the end.
--			 */
--			csum = csum_fold(csum_partial_copy_nocheck(image_data,
--								  dpage, len,
--								  0));
--
--			iowrite32(len, ioaddr + TYPHOON_REG_BOOT_LENGTH);
--			iowrite32(le16_to_cpu((__force __le16)csum),
--					ioaddr + TYPHOON_REG_BOOT_CHECKSUM);
--			iowrite32(load_addr,
--					ioaddr + TYPHOON_REG_BOOT_DEST_ADDR);
--			iowrite32(0, ioaddr + TYPHOON_REG_BOOT_DATA_HI);
--			iowrite32(dpage_dma, ioaddr + TYPHOON_REG_BOOT_DATA_LO);
--			typhoon_post_pci_writes(ioaddr);
--			iowrite32(TYPHOON_BOOTCMD_SEG_AVAILABLE,
--			       ioaddr + TYPHOON_REG_COMMAND);
--
--			image_data += len;
--			load_addr += len;
--			section_len -= len;
--		}
-+		image_data += section_len;
- 	}
- 
- 	if(typhoon_wait_interrupt(ioaddr) < 0 ||
-@@ -1488,7 +1499,7 @@ err_out_irq:
- 	iowrite32(irqMasked, ioaddr + TYPHOON_REG_INTR_MASK);
- 	iowrite32(irqEnabled, ioaddr + TYPHOON_REG_INTR_ENABLE);
- 
--	pci_free_consistent(pdev, PAGE_SIZE, dpage, dpage_dma);
-+	pci_unmap_single(pdev, image_dma,  typhoon_fw->size, PCI_DMA_TODEVICE);
- 
- err_out:
- 	return err;
-@@ -2086,6 +2097,10 @@ typhoon_open(struct net_device *dev)
+ 	dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma);
+@@ -2086,6 +2140,10 @@ typhoon_open(struct net_device *dev)
  	struct typhoon *tp = netdev_priv(dev);
  	int err;
  
@@ -220,7 +165,7 @@
  	err = typhoon_wakeup(tp, WaitSleep);
  	if(err < 0) {
  		printk(KERN_ERR "%s: unable to wakeup device\n", dev->name);
-@@ -2624,6 +2639,8 @@ typhoon_init(void)
+@@ -2624,6 +2682,8 @@ typhoon_init(void)
  static void __exit
  typhoon_cleanup(void)
  {



More information about the Kernel-svn-changes mailing list