Commit db3a91fe authored by Al Viro's avatar Al Viro Committed by Linus Torvalds

deal with resource allocation bugs in arcmsr

a) for type B we should _not_ iounmap() acb->pmu; it's not ioremapped.
b) for type B we should iounmap() two regions we _do_ ioremap.
c) if ioremap() fails, we need to bail out (and clean up).
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 142956af
...@@ -348,14 +348,6 @@ struct MessageUnit_B ...@@ -348,14 +348,6 @@ struct MessageUnit_B
uint32_t __iomem *ioctl_rbuffer_reg; uint32_t __iomem *ioctl_rbuffer_reg;
}; };
struct MessageUnit
{
union
{
struct MessageUnit_A pmu_A;
struct MessageUnit_B pmu_B;
} u;
};
/* /*
******************************************************************************* *******************************************************************************
** Adapter Control Block ** Adapter Control Block
...@@ -375,7 +367,6 @@ struct AdapterControlBlock ...@@ -375,7 +367,6 @@ struct AdapterControlBlock
uint32_t outbound_int_enable; uint32_t outbound_int_enable;
union { union {
struct MessageUnit * pmu;
struct MessageUnit_A __iomem * pmuA; struct MessageUnit_A __iomem * pmuA;
struct MessageUnit_B * pmuB; struct MessageUnit_B * pmuB;
}; };
......
...@@ -240,14 +240,18 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) ...@@ -240,14 +240,18 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
if (!acb->pmuA) { if (!acb->pmuA) {
printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n",
acb->host->host_no); acb->host->host_no);
return -ENOMEM;
} }
dma_coherent = dma_alloc_coherent(&pdev->dev, dma_coherent = dma_alloc_coherent(&pdev->dev,
ARCMSR_MAX_FREECCB_NUM * ARCMSR_MAX_FREECCB_NUM *
sizeof (struct CommandControlBlock) + 0x20, sizeof (struct CommandControlBlock) + 0x20,
&dma_coherent_handle, GFP_KERNEL); &dma_coherent_handle, GFP_KERNEL);
if (!dma_coherent)
if (!dma_coherent) {
iounmap(acb->pmuA);
return -ENOMEM; return -ENOMEM;
}
acb->dma_coherent = dma_coherent; acb->dma_coherent = dma_coherent;
acb->dma_coherent_handle = dma_coherent_handle; acb->dma_coherent_handle = dma_coherent_handle;
...@@ -331,8 +335,16 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) ...@@ -331,8 +335,16 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
acb->pmuB = reg; acb->pmuB = reg;
mem_base0 = ioremap(pci_resource_start(pdev, 0), mem_base0 = ioremap(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0)); pci_resource_len(pdev, 0));
if (!mem_base0)
goto out;
mem_base1 = ioremap(pci_resource_start(pdev, 2), mem_base1 = ioremap(pci_resource_start(pdev, 2),
pci_resource_len(pdev, 2)); pci_resource_len(pdev, 2));
if (!mem_base1) {
iounmap(mem_base0);
goto out;
}
reg->drv2iop_doorbell_reg = mem_base0 + ARCMSR_DRV2IOP_DOORBELL; reg->drv2iop_doorbell_reg = mem_base0 + ARCMSR_DRV2IOP_DOORBELL;
reg->drv2iop_doorbell_mask_reg = mem_base0 + reg->drv2iop_doorbell_mask_reg = mem_base0 +
ARCMSR_DRV2IOP_DOORBELL_MASK; ARCMSR_DRV2IOP_DOORBELL_MASK;
...@@ -357,6 +369,12 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) ...@@ -357,6 +369,12 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
break; break;
} }
return 0; return 0;
out:
dma_free_coherent(&acb->pdev->dev,
ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock) + 0x20,
acb->dma_coherent, acb->dma_coherent_handle);
return -ENOMEM;
} }
static int arcmsr_probe(struct pci_dev *pdev, static int arcmsr_probe(struct pci_dev *pdev,
...@@ -449,7 +467,6 @@ static int arcmsr_probe(struct pci_dev *pdev, ...@@ -449,7 +467,6 @@ static int arcmsr_probe(struct pci_dev *pdev,
free_irq(pdev->irq, acb); free_irq(pdev->irq, acb);
out_free_ccb_pool: out_free_ccb_pool:
arcmsr_free_ccb_pool(acb); arcmsr_free_ccb_pool(acb);
iounmap(acb->pmu);
out_release_regions: out_release_regions:
pci_release_regions(pdev); pci_release_regions(pdev);
out_host_put: out_host_put:
...@@ -810,7 +827,6 @@ static void arcmsr_remove(struct pci_dev *pdev) ...@@ -810,7 +827,6 @@ static void arcmsr_remove(struct pci_dev *pdev)
} }
free_irq(pdev->irq, acb); free_irq(pdev->irq, acb);
iounmap(acb->pmu);
arcmsr_free_ccb_pool(acb); arcmsr_free_ccb_pool(acb);
pci_release_regions(pdev); pci_release_regions(pdev);
...@@ -1018,6 +1034,17 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) ...@@ -1018,6 +1034,17 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb)
{ {
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
iounmap(acb->pmuA);
break;
}
case ACB_ADAPTER_TYPE_B: {
struct MessageUnit_B *reg = acb->pmuB;
iounmap(reg->drv2iop_doorbell_reg - ARCMSR_DRV2IOP_DOORBELL);
iounmap(reg->ioctl_wbuffer_reg - ARCMSR_IOCTL_WBUFFER);
}
}
dma_free_coherent(&acb->pdev->dev, dma_free_coherent(&acb->pdev->dev,
ARCMSR_MAX_FREECCB_NUM * sizeof (struct CommandControlBlock) + 0x20, ARCMSR_MAX_FREECCB_NUM * sizeof (struct CommandControlBlock) + 0x20,
acb->dma_coherent, acb->dma_coherent,
......
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