diff options
author | Tony Battersby <tonyb@cybernetics.com> | 2009-01-08 12:56:58 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-03-12 13:58:16 -0400 |
commit | 783fa7311b2c639f39c6163f9fbb05253fb2d702 (patch) | |
tree | bdb1f754113aac781190d104e85de475b04d0c1c /drivers/scsi/sym53c8xx_2 | |
parent | a71d035de835caa7d14ef69928e0fde9fc241cc0 (diff) |
[SCSI] sym53c8xx: handle pci_iomap() failures
sym_init_device() doesn't check if pci_iomap() fails. It also tries
to map device RAM without first checking FE_RAM.
1) Move some initialization from sym_init_device() to the top of
sym2_probe().
2) Rename sym_init_device() to sym_iomap_device().
3) Call sym_iomap_device() after sym_check_supported() instead of
before so that device->chip.features will be set.
4) Check FE_RAM in sym_iomap_device() before mapping RAM.
5) If sym_iomap_device() cannot map registers, then abort.
6) If sym_iomap_device() cannot map RAM, then fall back to not using
RAM and continue.
7) Remove the check for FE_RAM in sym_attach() since dev->ram_base
is now always set correctly.
Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/sym53c8xx_2')
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_glue.c | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 8e69b5c35f58..a0d5aa6aad79 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c | |||
@@ -1236,7 +1236,7 @@ static int sym53c8xx_proc_info(struct Scsi_Host *shost, char *buffer, | |||
1236 | #endif /* SYM_LINUX_PROC_INFO_SUPPORT */ | 1236 | #endif /* SYM_LINUX_PROC_INFO_SUPPORT */ |
1237 | 1237 | ||
1238 | /* | 1238 | /* |
1239 | * Free resources claimed by sym_init_device(). Note that | 1239 | * Free resources claimed by sym_iomap_device(). Note that |
1240 | * sym_free_resources() should be used instead of this function after calling | 1240 | * sym_free_resources() should be used instead of this function after calling |
1241 | * sym_attach(). | 1241 | * sym_attach(). |
1242 | */ | 1242 | */ |
@@ -1336,12 +1336,9 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1336 | np->maxburst = dev->chip.burst_max; | 1336 | np->maxburst = dev->chip.burst_max; |
1337 | np->myaddr = dev->host_id; | 1337 | np->myaddr = dev->host_id; |
1338 | np->mmio_ba = (u32)dev->mmio_base; | 1338 | np->mmio_ba = (u32)dev->mmio_base; |
1339 | np->ram_ba = (u32)dev->ram_base; | ||
1339 | np->s.ioaddr = dev->s.ioaddr; | 1340 | np->s.ioaddr = dev->s.ioaddr; |
1340 | np->s.ramaddr = dev->s.ramaddr; | 1341 | np->s.ramaddr = dev->s.ramaddr; |
1341 | if (!(np->features & FE_RAM)) | ||
1342 | dev->ram_base = 0; | ||
1343 | if (dev->ram_base) | ||
1344 | np->ram_ba = (u32)dev->ram_base; | ||
1345 | 1342 | ||
1346 | /* | 1343 | /* |
1347 | * Edit its name. | 1344 | * Edit its name. |
@@ -1559,30 +1556,28 @@ static int __devinit sym_set_workarounds(struct sym_device *device) | |||
1559 | } | 1556 | } |
1560 | 1557 | ||
1561 | /* | 1558 | /* |
1562 | * Read and check the PCI configuration for any detected NCR | 1559 | * Map HBA registers and on-chip SRAM (if present). |
1563 | * boards and save data for attaching after all boards have | ||
1564 | * been detected. | ||
1565 | */ | 1560 | */ |
1566 | static void __devinit | 1561 | static int __devinit |
1567 | sym_init_device(struct pci_dev *pdev, struct sym_device *device) | 1562 | sym_iomap_device(struct sym_device *device) |
1568 | { | 1563 | { |
1569 | int i = 2; | 1564 | struct pci_dev *pdev = device->pdev; |
1570 | struct pci_bus_region bus_addr; | 1565 | struct pci_bus_region bus_addr; |
1571 | 1566 | int i = 2; | |
1572 | device->host_id = SYM_SETUP_HOST_ID; | ||
1573 | device->pdev = pdev; | ||
1574 | 1567 | ||
1575 | pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]); | 1568 | pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]); |
1576 | device->mmio_base = bus_addr.start; | 1569 | device->mmio_base = bus_addr.start; |
1577 | 1570 | ||
1578 | /* | 1571 | if (device->chip.features & FE_RAM) { |
1579 | * If the BAR is 64-bit, resource 2 will be occupied by the | 1572 | /* |
1580 | * upper 32 bits | 1573 | * If the BAR is 64-bit, resource 2 will be occupied by the |
1581 | */ | 1574 | * upper 32 bits |
1582 | if (!pdev->resource[i].flags) | 1575 | */ |
1583 | i++; | 1576 | if (!pdev->resource[i].flags) |
1584 | pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]); | 1577 | i++; |
1585 | device->ram_base = bus_addr.start; | 1578 | pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]); |
1579 | device->ram_base = bus_addr.start; | ||
1580 | } | ||
1586 | 1581 | ||
1587 | #ifdef CONFIG_SCSI_SYM53C8XX_MMIO | 1582 | #ifdef CONFIG_SCSI_SYM53C8XX_MMIO |
1588 | if (device->mmio_base) | 1583 | if (device->mmio_base) |
@@ -1592,9 +1587,21 @@ sym_init_device(struct pci_dev *pdev, struct sym_device *device) | |||
1592 | if (!device->s.ioaddr) | 1587 | if (!device->s.ioaddr) |
1593 | device->s.ioaddr = pci_iomap(pdev, 0, | 1588 | device->s.ioaddr = pci_iomap(pdev, 0, |
1594 | pci_resource_len(pdev, 0)); | 1589 | pci_resource_len(pdev, 0)); |
1595 | if (device->ram_base) | 1590 | if (!device->s.ioaddr) { |
1591 | dev_err(&pdev->dev, "could not map registers; giving up.\n"); | ||
1592 | return -EIO; | ||
1593 | } | ||
1594 | if (device->ram_base) { | ||
1596 | device->s.ramaddr = pci_iomap(pdev, i, | 1595 | device->s.ramaddr = pci_iomap(pdev, i, |
1597 | pci_resource_len(pdev, i)); | 1596 | pci_resource_len(pdev, i)); |
1597 | if (!device->s.ramaddr) { | ||
1598 | dev_warn(&pdev->dev, | ||
1599 | "could not map SRAM; continuing anyway.\n"); | ||
1600 | device->ram_base = 0; | ||
1601 | } | ||
1602 | } | ||
1603 | |||
1604 | return 0; | ||
1598 | } | 1605 | } |
1599 | 1606 | ||
1600 | /* | 1607 | /* |
@@ -1711,6 +1718,8 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1711 | 1718 | ||
1712 | memset(&sym_dev, 0, sizeof(sym_dev)); | 1719 | memset(&sym_dev, 0, sizeof(sym_dev)); |
1713 | memset(&nvram, 0, sizeof(nvram)); | 1720 | memset(&nvram, 0, sizeof(nvram)); |
1721 | sym_dev.pdev = pdev; | ||
1722 | sym_dev.host_id = SYM_SETUP_HOST_ID; | ||
1714 | 1723 | ||
1715 | if (pci_enable_device(pdev)) | 1724 | if (pci_enable_device(pdev)) |
1716 | goto leave; | 1725 | goto leave; |
@@ -1720,12 +1729,13 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1720 | if (pci_request_regions(pdev, NAME53C8XX)) | 1729 | if (pci_request_regions(pdev, NAME53C8XX)) |
1721 | goto disable; | 1730 | goto disable; |
1722 | 1731 | ||
1723 | sym_init_device(pdev, &sym_dev); | ||
1724 | do_iounmap = 1; | ||
1725 | |||
1726 | if (sym_check_supported(&sym_dev)) | 1732 | if (sym_check_supported(&sym_dev)) |
1727 | goto free; | 1733 | goto free; |
1728 | 1734 | ||
1735 | if (sym_iomap_device(&sym_dev)) | ||
1736 | goto free; | ||
1737 | do_iounmap = 1; | ||
1738 | |||
1729 | if (sym_check_raid(&sym_dev)) { | 1739 | if (sym_check_raid(&sym_dev)) { |
1730 | do_disable_device = 0; /* Don't disable the device */ | 1740 | do_disable_device = 0; /* Don't disable the device */ |
1731 | goto free; | 1741 | goto free; |