lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 24 Apr 2008 12:57:08 +0000 (GMT)
From:	Michael Abbott <michael@...neidae.co.uk>
To:	Ben Dooks <ben-linux@...ff.org>, linux-net@...r.kernel.org
cc:	linux-kernel@...r.kernel.org
Subject: [PATCH] DM9000: Reimplement 2-resource device specification (fwd)

From: Michael Abbott <michael.abbott@...mond.ac.uk>

[PATCH] DM9000: Reimplement 2-resource device specification

In commit 1a5f1c4ff80f522555d78d4dd0109f18395c6d83 a change was made to
the handling of the resources passed the DM9000 device.  Unfortunately,
if only two resources are passed (the read and write register in the same
area) the pointer db->irq_res ends up being used without being initialised.

This patch tidies this up a little.  Only one architecture class,
blackfin, uses two resource specification, so it may be better to enforce
three resource specification as before by simply removing the 0 and 2
resource branches from dm9000_probe.

This patch implements the data resource, if it is not specified, by setting
io_data = io_addr+4 -- this is the original behaviour.

The memory region releasing has also been revisited, as the old 
implemention looks horribly broken to me.

Signed-off-by: Michael Abbott <michael.abbott@...mond.ac.uk>
---
  drivers/net/dm9000.c |  122 +++++++++++++++++++++----------------------------
  1 files changed, 52 insertions(+), 70 deletions(-)

I'm not so confident of this patch, and it does include a small amout of 
peripherally related reformatting.  I'm afraid I've not been able to test 
this very thoroughly, thought it does appear to work.

diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 9ad9499..7f3e78f 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -469,6 +469,8 @@ static const struct ethtool_ops dm9000_ethtool_ops = {
   	.set_eeprom		= dm9000_set_eeprom,
  };

+#define res_size(_r) (((_r)->end - (_r)->start) + 1)
+

  /* dm9000_release_board
   *
@@ -478,11 +480,13 @@ static const struct ethtool_ops dm9000_ethtool_ops = {
  static void
  dm9000_release_board(struct platform_device *pdev, struct board_info *db)
  {
-	if (db->data_res == NULL) {
-		if (db->addr_res != NULL)
-			release_mem_region((unsigned long)db->io_addr, 4);
-		return;
-	}
+	/* Release the allocated mem regions. */
+	if (db->addr_req != NULL)
+		release_mem_region(
+			db->addr_res->start, res_size(db->addr_res));
+	if (db->data_req != NULL)
+		release_mem_region(
+			db->data_res->start, res_size(db->data_res));

  	/* unmap our resources */

@@ -502,8 +506,6 @@ dm9000_release_board(struct platform_device *pdev, struct board_info *db)
  	}
  }

-#define res_size(_r) (((_r)->end - (_r)->start) + 1)
-
  /*
   * Search DM9000 board, allocate space and register it
   */
@@ -514,10 +516,9 @@ dm9000_probe(struct platform_device *pdev)
  	struct board_info *db;	/* Point a board information structure */
  	struct net_device *ndev;
  	const unsigned char *mac_src;
-	unsigned long base;
  	int ret = 0;
  	int iosize;
-	int i;
+	int addrsize;
  	u32 id_val;

  	/* Init network device */
@@ -540,105 +541,86 @@ dm9000_probe(struct platform_device *pdev)
  	spin_lock_init(&db->lock);
  	mutex_init(&db->addr_lock);

-	if (pdev->num_resources < 2) {
-		ret = -ENODEV;
+	/* Process the platform resources to configure the address register,
+	 * data register and IRQ. */
+	db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	db->irq_res  = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (db->addr_res == NULL || db->irq_res == NULL) {
+		dev_err(db->dev, "insufficient resources\n");
+		ret = -ENOENT;
  		goto out;
-	} else if (pdev->num_resources == 2) {
-		base = pdev->resource[0].start;
-
-		if (!request_mem_region(base, 4, ndev->name)) {
-			ret = -EBUSY;
-			goto out;
-		}
-
-		ndev->base_addr = base;
-		ndev->irq = pdev->resource[1].start;
-		db->io_addr = (void __iomem *)base;
-		db->io_data = (void __iomem *)(base + 4);
-
-		/* ensure at least we have a default set of IO routines */
-		dm9000_set_io(db, 2);
-
-	} else {
-		db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-		db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-		db->irq_res  = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-
-		if (db->addr_res == NULL || db->data_res == NULL ||
-		    db->irq_res == NULL) {
-			dev_err(db->dev, "insufficient resources\n");
-			ret = -ENOENT;
-			goto out;
-		}
-
-		i = res_size(db->addr_res);
-		db->addr_req = request_mem_region(db->addr_res->start, i,
-						  pdev->name);
-
-		if (db->addr_req == NULL) {
-			dev_err(db->dev, "cannot claim address reg area\n");
-			ret = -EIO;
-			goto out;
-		}
-
-		db->io_addr = ioremap(db->addr_res->start, i);
-
-		if (db->io_addr == NULL) {
-			dev_err(db->dev, "failed to ioremap address reg\n");
+	}
+
+	addrsize = res_size(db->addr_res);
+	db->addr_req = request_mem_region(
+		db->addr_res->start, addrsize, pdev->name);
+	if (db->addr_req == NULL) {
+		dev_err(db->dev, "cannot claim address reg area\n");
+		ret = -EIO;
+		goto out;
+	}
+	db->io_addr = ioremap(db->addr_res->start, addrsize);
+	if (db->io_addr == NULL) {
+		dev_err(db->dev, "failed to ioremap address reg\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (db->data_res == NULL) {
+		/* Special case: if no separate data resource is provided
+		 * then use io_addr+4 as the io_data address and take the
+		 * remaining io length from the resource. */
+		iosize = addrsize - 4;
+		if (iosize < 1) {
+			dev_err(db->dev, "no space allocated for data reg\n");
  			ret = -EINVAL;
  			goto out;
  		}
-
+		db->io_data = db->io_addr + 4;
+	} else {
  		iosize = res_size(db->data_res);
  		db->data_req = request_mem_region(db->data_res->start, iosize,
  						  pdev->name);
-
  		if (db->data_req == NULL) {
  			dev_err(db->dev, "cannot claim data reg area\n");
  			ret = -EIO;
  			goto out;
  		}
-
  		db->io_data = ioremap(db->data_res->start, iosize);
-
  		if (db->io_data == NULL) {
  			dev_err(db->dev,"failed to ioremap data reg\n");
  			ret = -EINVAL;
  			goto out;
  		}
+	}

-		/* fill in parameters for net-dev structure */
+	/* fill in parameters for net-dev structure */

-		ndev->base_addr = (unsigned long)db->io_addr;
-		ndev->irq	= db->irq_res->start;
+	ndev->base_addr = (unsigned long)db->io_addr;
+	ndev->irq	= db->irq_res->start;
+
+	/* ensure at least we have a default set of IO routines */
+	dm9000_set_io(db, iosize);

-		/* ensure at least we have a default set of IO routines */
-		dm9000_set_io(db, iosize);
-	}

  	/* check to see if anything is being over-ridden */
  	if (pdata != NULL) {
  		/* check to see if the driver wants to over-ride the
  		 * default IO width */
-
  		if (pdata->flags & DM9000_PLATF_8BITONLY)
  			dm9000_set_io(db, 1);
-
  		if (pdata->flags & DM9000_PLATF_16BITONLY)
  			dm9000_set_io(db, 2);
-
  		if (pdata->flags & DM9000_PLATF_32BITONLY)
  			dm9000_set_io(db, 4);

  		/* check to see if there are any IO routine
  		 * over-rides */
-
  		if (pdata->inblk != NULL)
  			db->inblk = pdata->inblk;
-
  		if (pdata->outblk != NULL)
  			db->outblk = pdata->outblk;
-
  		if (pdata->dumpblk != NULL)
  			db->dumpblk = pdata->dumpblk;

@@ -647,7 +629,7 @@ dm9000_probe(struct platform_device *pdev)

  	dm9000_reset(db);

-	/* try two times, DM9000 sometimes gets the first read wrong */
+	/* try several times, DM9000 sometimes gets the first read wrong */
  	for (i = 0; i < 8; i++) {
  		id_val  = ior(db, DM9000_VIDL);
  		id_val |= (u32)ior(db, DM9000_VIDH) << 8;
-- 
1.5.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ