From fb4d64e78ceab77cf20f7796f74aa10ebe862032 Mon Sep 17 00:00:00 2001
From: Frederik Deweerdt <deweerdt@free.fr>
Date: Fri, 16 Feb 2007 01:27:15 -0800
Subject: [PATCH] [PATCH] pci_iomap_regions() error handling fix

It appears that the pcim_iomap_regions() function doesn't get the error
handling right. It BUGs early at boot with a backtrace along the lines of:

ahci_init
pci_register_driver
driver_register
[...]
ahci_init_one
pcim_iomap_region
pcim_iounmap

The following patch allows me to boot. Only the if(mask..) continue;
part fixes the problem actually, the gotos where changed so that we
don't try to unmap something we couldn't map anyway.

Signed-off-by: Frederik Deweerdt <frederik.deweerdt@gmail.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Tejun Heo <htejun@gmail.com>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 lib/devres.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/devres.c b/lib/devres.c
index 2a668dd7cac7c..eb38849aa7170 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -274,21 +274,21 @@ int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name)
 
 		rc = pci_request_region(pdev, i, name);
 		if (rc)
-			goto err_region;
+			goto err_inval;
 
 		rc = -ENOMEM;
 		if (!pcim_iomap(pdev, i, 0))
-			goto err_iomap;
+			goto err_region;
 	}
 
 	return 0;
 
- err_iomap:
-	pcim_iounmap(pdev, iomap[i]);
  err_region:
 	pci_release_region(pdev, i);
  err_inval:
 	while (--i >= 0) {
+		if (!(mask & (1 << i)))
+			continue;
 		pcim_iounmap(pdev, iomap[i]);
 		pci_release_region(pdev, i);
 	}
-- 
GitLab