Commit eb8cdaeb authored by Roland Dreier's avatar Roland Dreier Committed by Linus Torvalds

[PATCH] InfiniBand/mthca: clean up ioremap()/request_region() usage

From: "Michael S. Tsirkin" <mst@mellanox.co.il>

Here are misc fixes for mthca mapping:

1. Thinkably, MSI tables or another region could fall between HCR
   and ECR tables.
   Thus its arguably wrong to map both tables in one region.
   So, do it separately.
   I think its also more readable to have ecr_base and access ecr there,
   not access ecr with hcr pointer.

2. mthca_request_regions error handling was borken
   (wrong order of cleanups). For example on all errors
   pci_release_region was called which is wrong if the region
   was not yet mapped. And other such cleanups.

3. Fixed some error messages too.
Signed-off-by: default avatarRoland Dreier <roland@topspin.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent dd9398cf
...@@ -43,13 +43,8 @@ ...@@ -43,13 +43,8 @@
#define MTHCA_ECR_SIZE 0x00008 #define MTHCA_ECR_SIZE 0x00008
#define MTHCA_ECR_CLR_BASE 0x80708 #define MTHCA_ECR_CLR_BASE 0x80708
#define MTHCA_ECR_CLR_SIZE 0x00008 #define MTHCA_ECR_CLR_SIZE 0x00008
#define MTHCA_ECR_OFFSET (MTHCA_ECR_BASE - MTHCA_HCR_BASE) #define MTHCA_MAP_ECR_SIZE (MTHCA_ECR_SIZE + MTHCA_ECR_CLR_SIZE)
#define MTHCA_ECR_CLR_OFFSET (MTHCA_ECR_CLR_BASE - MTHCA_HCR_BASE)
#define MTHCA_CLR_INT_BASE 0xf00d8 #define MTHCA_CLR_INT_BASE 0xf00d8
#define MTHCA_CLR_INT_SIZE 0x00008 #define MTHCA_CLR_INT_SIZE 0x00008
#define MTHCA_MAP_HCR_SIZE (MTHCA_ECR_CLR_BASE + \
MTHCA_ECR_CLR_SIZE - \
MTHCA_HCR_BASE)
#endif /* MTHCA_CONFIG_REG_H */ #endif /* MTHCA_CONFIG_REG_H */
...@@ -237,6 +237,7 @@ struct mthca_dev { ...@@ -237,6 +237,7 @@ struct mthca_dev {
struct semaphore cap_mask_mutex; struct semaphore cap_mask_mutex;
void __iomem *hcr; void __iomem *hcr;
void __iomem *ecr_base;
void __iomem *clr_base; void __iomem *clr_base;
void __iomem *kar; void __iomem *kar;
......
...@@ -366,10 +366,11 @@ static irqreturn_t mthca_interrupt(int irq, void *dev_ptr, struct pt_regs *regs) ...@@ -366,10 +366,11 @@ static irqreturn_t mthca_interrupt(int irq, void *dev_ptr, struct pt_regs *regs)
if (dev->eq_table.clr_mask) if (dev->eq_table.clr_mask)
writel(dev->eq_table.clr_mask, dev->eq_table.clr_int); writel(dev->eq_table.clr_mask, dev->eq_table.clr_int);
if ((ecr = readl(dev->hcr + MTHCA_ECR_OFFSET + 4)) != 0) { if ((ecr = readl(dev->ecr_base + 4)) != 0) {
work = 1; work = 1;
writel(ecr, dev->hcr + MTHCA_ECR_CLR_OFFSET + 4); writel(ecr, dev->ecr_base +
MTHCA_ECR_CLR_BASE - MTHCA_ECR_BASE + 4);
for (i = 0; i < MTHCA_NUM_EQ; ++i) for (i = 0; i < MTHCA_NUM_EQ; ++i)
if (ecr & dev->eq_table.eq[i].ecr_mask) if (ecr & dev->eq_table.eq[i].ecr_mask)
......
...@@ -699,57 +699,83 @@ static int __devinit mthca_request_regions(struct pci_dev *pdev, ...@@ -699,57 +699,83 @@ static int __devinit mthca_request_regions(struct pci_dev *pdev,
*/ */
if (!request_mem_region(pci_resource_start(pdev, 0) + if (!request_mem_region(pci_resource_start(pdev, 0) +
MTHCA_HCR_BASE, MTHCA_HCR_BASE,
MTHCA_MAP_HCR_SIZE, MTHCA_HCR_SIZE,
DRV_NAME)) DRV_NAME)) {
return -EBUSY; err = -EBUSY;
goto err_hcr_failed;
}
if (!request_mem_region(pci_resource_start(pdev, 0) +
MTHCA_ECR_BASE,
MTHCA_MAP_ECR_SIZE,
DRV_NAME)) {
err = -EBUSY;
goto err_ecr_failed;
}
if (!request_mem_region(pci_resource_start(pdev, 0) + if (!request_mem_region(pci_resource_start(pdev, 0) +
MTHCA_CLR_INT_BASE, MTHCA_CLR_INT_BASE,
MTHCA_CLR_INT_SIZE, MTHCA_CLR_INT_SIZE,
DRV_NAME)) { DRV_NAME)) {
err = -EBUSY; err = -EBUSY;
goto err_bar0_beg; goto err_int_failed;
} }
err = pci_request_region(pdev, 2, DRV_NAME); err = pci_request_region(pdev, 2, DRV_NAME);
if (err) if (err)
goto err_bar0_end; goto err_bar2_failed;
if (!ddr_hidden) { if (!ddr_hidden) {
err = pci_request_region(pdev, 4, DRV_NAME); err = pci_request_region(pdev, 4, DRV_NAME);
if (err) if (err)
goto err_bar2; goto err_bar4_failed;
} }
return 0; return 0;
err_bar0_beg: err_bar4_failed:
release_mem_region(pci_resource_start(pdev, 0) +
MTHCA_HCR_BASE, pci_release_region(pdev, 2);
MTHCA_MAP_HCR_SIZE); err_bar2_failed:
err_bar0_end:
release_mem_region(pci_resource_start(pdev, 0) + release_mem_region(pci_resource_start(pdev, 0) +
MTHCA_CLR_INT_BASE, MTHCA_CLR_INT_BASE,
MTHCA_CLR_INT_SIZE); MTHCA_CLR_INT_SIZE);
err_int_failed:
release_mem_region(pci_resource_start(pdev, 0) +
MTHCA_ECR_BASE,
MTHCA_MAP_ECR_SIZE);
err_ecr_failed:
release_mem_region(pci_resource_start(pdev, 0) +
MTHCA_HCR_BASE,
MTHCA_HCR_SIZE);
err_hcr_failed:
err_bar2:
pci_release_region(pdev, 2);
return err; return err;
} }
static void mthca_release_regions(struct pci_dev *pdev, static void mthca_release_regions(struct pci_dev *pdev,
int ddr_hidden) int ddr_hidden)
{ {
release_mem_region(pci_resource_start(pdev, 0) + if (!ddr_hidden)
MTHCA_HCR_BASE, pci_release_region(pdev, 4);
MTHCA_MAP_HCR_SIZE);
pci_release_region(pdev, 2);
release_mem_region(pci_resource_start(pdev, 0) + release_mem_region(pci_resource_start(pdev, 0) +
MTHCA_CLR_INT_BASE, MTHCA_CLR_INT_BASE,
MTHCA_CLR_INT_SIZE); MTHCA_CLR_INT_SIZE);
pci_release_region(pdev, 2);
if (!ddr_hidden) release_mem_region(pci_resource_start(pdev, 0) +
pci_release_region(pdev, 4); MTHCA_ECR_BASE,
MTHCA_MAP_ECR_SIZE);
release_mem_region(pci_resource_start(pdev, 0) +
MTHCA_HCR_BASE,
MTHCA_HCR_SIZE);
} }
static int __devinit mthca_enable_msi_x(struct mthca_dev *mdev) static int __devinit mthca_enable_msi_x(struct mthca_dev *mdev)
...@@ -911,29 +937,39 @@ static int __devinit mthca_init_one(struct pci_dev *pdev, ...@@ -911,29 +937,39 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
mdev->cmd.use_events = 0; mdev->cmd.use_events = 0;
mthca_base = pci_resource_start(pdev, 0); mthca_base = pci_resource_start(pdev, 0);
mdev->hcr = ioremap(mthca_base + MTHCA_HCR_BASE, MTHCA_MAP_HCR_SIZE); mdev->hcr = ioremap(mthca_base + MTHCA_HCR_BASE, MTHCA_HCR_SIZE);
if (!mdev->hcr) { if (!mdev->hcr) {
mthca_err(mdev, "Couldn't map command register, " mthca_err(mdev, "Couldn't map command register, "
"aborting.\n"); "aborting.\n");
err = -ENOMEM; err = -ENOMEM;
goto err_free_dev; goto err_free_dev;
} }
mdev->clr_base = ioremap(mthca_base + MTHCA_CLR_INT_BASE, mdev->clr_base = ioremap(mthca_base + MTHCA_CLR_INT_BASE,
MTHCA_CLR_INT_SIZE); MTHCA_CLR_INT_SIZE);
if (!mdev->clr_base) { if (!mdev->clr_base) {
mthca_err(mdev, "Couldn't map command register, " mthca_err(mdev, "Couldn't map interrupt clear register, "
"aborting.\n"); "aborting.\n");
err = -ENOMEM; err = -ENOMEM;
goto err_iounmap; goto err_iounmap;
} }
mdev->ecr_base = ioremap(mthca_base + MTHCA_ECR_BASE,
MTHCA_ECR_SIZE + MTHCA_ECR_CLR_SIZE);
if (!mdev->ecr_base) {
mthca_err(mdev, "Couldn't map ecr register, "
"aborting.\n");
err = -ENOMEM;
goto err_iounmap_clr;
}
mthca_base = pci_resource_start(pdev, 2); mthca_base = pci_resource_start(pdev, 2);
mdev->kar = ioremap(mthca_base + PAGE_SIZE * MTHCA_KAR_PAGE, PAGE_SIZE); mdev->kar = ioremap(mthca_base + PAGE_SIZE * MTHCA_KAR_PAGE, PAGE_SIZE);
if (!mdev->kar) { if (!mdev->kar) {
mthca_err(mdev, "Couldn't map kernel access region, " mthca_err(mdev, "Couldn't map kernel access region, "
"aborting.\n"); "aborting.\n");
err = -ENOMEM; err = -ENOMEM;
goto err_iounmap_clr; goto err_iounmap_ecr;
} }
err = mthca_tune_pci(mdev); err = mthca_tune_pci(mdev);
...@@ -982,6 +1018,9 @@ static int __devinit mthca_init_one(struct pci_dev *pdev, ...@@ -982,6 +1018,9 @@ static int __devinit mthca_init_one(struct pci_dev *pdev,
err_iounmap_kar: err_iounmap_kar:
iounmap(mdev->kar); iounmap(mdev->kar);
err_iounmap_ecr:
iounmap(mdev->ecr_base);
err_iounmap_clr: err_iounmap_clr:
iounmap(mdev->clr_base); iounmap(mdev->clr_base);
...@@ -1033,6 +1072,7 @@ static void __devexit mthca_remove_one(struct pci_dev *pdev) ...@@ -1033,6 +1072,7 @@ static void __devexit mthca_remove_one(struct pci_dev *pdev)
mthca_close_hca(mdev); mthca_close_hca(mdev);
iounmap(mdev->hcr); iounmap(mdev->hcr);
iounmap(mdev->ecr_base);
iounmap(mdev->clr_base); iounmap(mdev->clr_base);
if (mdev->mthca_flags & MTHCA_FLAG_MSI_X) if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment