aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew@wil.cx>2007-07-30 10:04:53 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:39:08 -0400
commit71f36115d20e8d8b0ef10479ff0cde877ec56f98 (patch)
treeadf0da802ca05e404ae6e6a9170e81e92dd0f3d0 /drivers
parentc304ec94733aec764396813f3f05dfbe02f4a6da (diff)
[SCSI] advansys: Update resource management
Make sure the resources are reserved and released by all the callers of advansys_board_found(). This eliminates the check_region-style race. It also allows us to use the pci_request_regions() API. Signed-off-by: Matthew Wilcox <matthew@wil.cx> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/advansys.c70
1 files changed, 33 insertions, 37 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index eda41f245bb4..d51ca86bda74 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -17681,14 +17681,12 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
17681 boardp->id, pci_memory_address, iolen); 17681 boardp->id, pci_memory_address, iolen);
17682 goto err_shost; 17682 goto err_shost;
17683 } 17683 }
17684 ASC_DBG1(1, 17684 ASC_DBG1(1, "advansys_board_found: ioremap_addr: 0x%lx\n",
17685 "advansys_board_found: ioremap_addr: 0x%lx\n",
17686 (ulong)boardp->ioremap_addr); 17685 (ulong)boardp->ioremap_addr);
17687 adv_dvc_varp->iop_base = (AdvPortAddr) 17686 adv_dvc_varp->iop_base = (AdvPortAddr)
17688 (boardp->ioremap_addr + 17687 (boardp->ioremap_addr +
17689 (pci_memory_address - (pci_memory_address & PAGE_MASK))); 17688 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
17690 ASC_DBG1(1, 17689 ASC_DBG1(1, "advansys_board_found: iop_base: 0x%lx\n",
17691 "advansys_board_found: iop_base: 0x%lx\n",
17692 adv_dvc_varp->iop_base); 17690 adv_dvc_varp->iop_base);
17693#endif /* CONFIG_PCI */ 17691#endif /* CONFIG_PCI */
17694 17692
@@ -18169,25 +18167,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
18169 * Register Board Resources - I/O Port, DMA, IRQ 18167 * Register Board Resources - I/O Port, DMA, IRQ
18170 */ 18168 */
18171 18169
18172 /*
18173 * Register I/O port range.
18174 *
18175 * For Wide boards the I/O ports are not used to access
18176 * the board, but request the region anyway.
18177 *
18178 * 'shost->n_io_port' is not referenced, because it may be truncated.
18179 */
18180 ASC_DBG2(2,
18181 "advansys_board_found: request_region port 0x%lx, len 0x%x\n",
18182 (ulong)shost->io_port, boardp->asc_n_io_port);
18183 if (request_region(shost->io_port, boardp->asc_n_io_port,
18184 "advansys") == NULL) {
18185 ASC_PRINT3
18186 ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
18187 boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port);
18188 goto err_free_proc;
18189 }
18190
18191 /* Register DMA Channel for Narrow boards. */ 18170 /* Register DMA Channel for Narrow boards. */
18192 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */ 18171 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
18193#ifdef CONFIG_ISA 18172#ifdef CONFIG_ISA
@@ -18200,7 +18179,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
18200 ASC_PRINT3 18179 ASC_PRINT3
18201 ("advansys_board_found: board %d: request_dma() %d failed %d\n", 18180 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
18202 boardp->id, shost->dma_channel, ret); 18181 boardp->id, shost->dma_channel, ret);
18203 goto err_free_region; 18182 goto err_free_proc;
18204 } 18183 }
18205 AscEnableIsaDma(shost->dma_channel); 18184 AscEnableIsaDma(shost->dma_channel);
18206 } 18185 }
@@ -18266,8 +18245,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
18266 err_free_dma: 18245 err_free_dma:
18267 if (shost->dma_channel != NO_ISA_DMA) 18246 if (shost->dma_channel != NO_ISA_DMA)
18268 free_dma(shost->dma_channel); 18247 free_dma(shost->dma_channel);
18269 err_free_region:
18270 release_region(shost->io_port, boardp->asc_n_io_port);
18271 err_free_proc: 18248 err_free_proc:
18272 kfree(boardp->prtbuf); 18249 kfree(boardp->prtbuf);
18273 err_unmap: 18250 err_unmap:
@@ -18295,7 +18272,6 @@ static int advansys_release(struct Scsi_Host *shost)
18295 ASC_DBG(1, "advansys_release: free_dma()\n"); 18272 ASC_DBG(1, "advansys_release: free_dma()\n");
18296 free_dma(shost->dma_channel); 18273 free_dma(shost->dma_channel);
18297 } 18274 }
18298 release_region(shost->io_port, boardp->asc_n_io_port);
18299 if (ASC_WIDE_BOARD(boardp)) { 18275 if (ASC_WIDE_BOARD(boardp)) {
18300 iounmap(boardp->ioremap_addr); 18276 iounmap(boardp->ioremap_addr);
18301 advansys_wide_free_mem(boardp); 18277 advansys_wide_free_mem(boardp);
@@ -18317,19 +18293,17 @@ static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
18317 struct Scsi_Host *shost; 18293 struct Scsi_Host *shost;
18318 18294
18319 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) { 18295 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
18320 ASC_DBG1(1, "advansys_isa_match: check_region() failed " 18296 ASC_DBG1(1, "advansys_isa_match: I/O port 0x%x busy\n",
18321 "I/O port 0x%x\n", iop_base); 18297 iop_base);
18322 return -ENODEV; 18298 return -ENODEV;
18323 } 18299 }
18324 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base); 18300 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
18325 release_region(iop_base, ASC_IOADR_GAP);
18326 if (!AscFindSignature(iop_base)) 18301 if (!AscFindSignature(iop_base))
18327 goto nodev; 18302 goto nodev;
18328 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT)) 18303 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
18329 goto nodev; 18304 goto nodev;
18330 18305
18331 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA); 18306 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
18332
18333 if (!shost) 18307 if (!shost)
18334 goto nodev; 18308 goto nodev;
18335 18309
@@ -18337,12 +18311,15 @@ static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
18337 return 0; 18311 return 0;
18338 18312
18339 nodev: 18313 nodev:
18314 release_region(iop_base, ASC_IOADR_GAP);
18340 return -ENODEV; 18315 return -ENODEV;
18341} 18316}
18342 18317
18343static int __devexit advansys_isa_remove(struct device *dev, unsigned int id) 18318static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
18344{ 18319{
18320 int ioport = _asc_def_iop_base[id];
18345 advansys_release(dev_get_drvdata(dev)); 18321 advansys_release(dev_get_drvdata(dev));
18322 release_region(ioport, ASC_IOADR_GAP);
18346 return 0; 18323 return 0;
18347} 18324}
18348 18325
@@ -18361,12 +18338,11 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
18361 struct Scsi_Host *shost; 18338 struct Scsi_Host *shost;
18362 18339
18363 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) { 18340 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
18364 ASC_DBG1(1, "advansys_vlb_match: check_region() failed " 18341 ASC_DBG1(1, "advansys_vlb_match: I/O port 0x%x busy\n",
18365 "I/O port 0x%x\n", iop_base); 18342 iop_base);
18366 return -ENODEV; 18343 return -ENODEV;
18367 } 18344 }
18368 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base); 18345 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
18369 release_region(iop_base, ASC_IOADR_GAP);
18370 if (!AscFindSignature(iop_base)) 18346 if (!AscFindSignature(iop_base))
18371 goto nodev; 18347 goto nodev;
18372 /* 18348 /*
@@ -18378,7 +18354,6 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
18378 goto nodev; 18354 goto nodev;
18379 18355
18380 shost = advansys_board_found(iop_base, dev, ASC_IS_VL); 18356 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
18381
18382 if (!shost) 18357 if (!shost)
18383 goto nodev; 18358 goto nodev;
18384 18359
@@ -18386,6 +18361,7 @@ static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
18386 return 0; 18361 return 0;
18387 18362
18388 nodev: 18363 nodev:
18364 release_region(iop_base, ASC_IOADR_GAP);
18389 return -ENODEV; 18365 return -ENODEV;
18390} 18366}
18391 18367
@@ -18429,8 +18405,16 @@ static int __devinit advansys_eisa_probe(struct device *dev)
18429 18405
18430 err = -ENODEV; 18406 err = -ENODEV;
18431 for (i = 0; i < 2; i++, ioport += 0x20) { 18407 for (i = 0; i < 2; i++, ioport += 0x20) {
18432 if (!AscFindSignature(ioport)) 18408 if (!request_region(ioport, ASC_IOADR_GAP, "advansys")) {
18409 printk(KERN_WARNING "Region %x-%x busy\n", ioport,
18410 ioport + ASC_IOADR_GAP - 1);
18411 continue;
18412 }
18413 if (!AscFindSignature(ioport)) {
18414 release_region(ioport, ASC_IOADR_GAP);
18433 continue; 18415 continue;
18416 }
18417
18434 /* 18418 /*
18435 * I don't know why we need to do this for EISA chips, but 18419 * I don't know why we need to do this for EISA chips, but
18436 * not for any others. It looks to be equivalent to 18420 * not for any others. It looks to be equivalent to
@@ -18440,8 +18424,11 @@ static int __devinit advansys_eisa_probe(struct device *dev)
18440 */ 18424 */
18441 inw(ioport + 4); 18425 inw(ioport + 4);
18442 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA); 18426 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
18443 if (data->host[i]) 18427 if (data->host[i]) {
18444 err = 0; 18428 err = 0;
18429 } else {
18430 release_region(ioport, ASC_IOADR_GAP);
18431 }
18445 } 18432 }
18446 18433
18447 if (err) { 18434 if (err) {
@@ -18460,10 +18447,13 @@ static __devexit int advansys_eisa_remove(struct device *dev)
18460 struct eisa_scsi_data *data = dev_get_drvdata(dev); 18447 struct eisa_scsi_data *data = dev_get_drvdata(dev);
18461 18448
18462 for (i = 0; i < 2; i++) { 18449 for (i = 0; i < 2; i++) {
18450 int ioport;
18463 struct Scsi_Host *shost = data->host[i]; 18451 struct Scsi_Host *shost = data->host[i];
18464 if (!shost) 18452 if (!shost)
18465 continue; 18453 continue;
18454 ioport = shost->io_port;
18466 advansys_release(shost); 18455 advansys_release(shost);
18456 release_region(ioport, ASC_IOADR_GAP);
18467 } 18457 }
18468 18458
18469 kfree(data); 18459 kfree(data);
@@ -18507,6 +18497,9 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18507 err = pci_enable_device(pdev); 18497 err = pci_enable_device(pdev);
18508 if (err) 18498 if (err)
18509 goto fail; 18499 goto fail;
18500 err = pci_request_regions(pdev, "advansys");
18501 if (err)
18502 goto disable_device;
18510 18503
18511 if (pci_resource_len(pdev, 0) == 0) 18504 if (pci_resource_len(pdev, 0) == 0)
18512 goto nodev; 18505 goto nodev;
@@ -18522,6 +18515,8 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18522 18515
18523 nodev: 18516 nodev:
18524 err = -ENODEV; 18517 err = -ENODEV;
18518 pci_release_regions(pdev);
18519 disable_device:
18525 pci_disable_device(pdev); 18520 pci_disable_device(pdev);
18526 fail: 18521 fail:
18527 return err; 18522 return err;
@@ -18530,6 +18525,7 @@ advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18530static void __devexit advansys_pci_remove(struct pci_dev *pdev) 18525static void __devexit advansys_pci_remove(struct pci_dev *pdev)
18531{ 18526{
18532 advansys_release(pci_get_drvdata(pdev)); 18527 advansys_release(pci_get_drvdata(pdev));
18528 pci_release_regions(pdev);
18533 pci_disable_device(pdev); 18529 pci_disable_device(pdev);
18534} 18530}
18535 18531