提交 783fa731 编写于 作者: T Tony Battersby 提交者: James Bottomley

[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: NTony Battersby <tonyb@cybernetics.com>
Signed-off-by: NJames Bottomley <James.Bottomley@HansenPartnership.com>
上级 a71d035d
...@@ -1236,7 +1236,7 @@ static int sym53c8xx_proc_info(struct Scsi_Host *shost, char *buffer, ...@@ -1236,7 +1236,7 @@ static int sym53c8xx_proc_info(struct Scsi_Host *shost, char *buffer,
#endif /* SYM_LINUX_PROC_INFO_SUPPORT */ #endif /* SYM_LINUX_PROC_INFO_SUPPORT */
/* /*
* Free resources claimed by sym_init_device(). Note that * Free resources claimed by sym_iomap_device(). Note that
* sym_free_resources() should be used instead of this function after calling * sym_free_resources() should be used instead of this function after calling
* sym_attach(). * sym_attach().
*/ */
...@@ -1336,12 +1336,9 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, ...@@ -1336,12 +1336,9 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
np->maxburst = dev->chip.burst_max; np->maxburst = dev->chip.burst_max;
np->myaddr = dev->host_id; np->myaddr = dev->host_id;
np->mmio_ba = (u32)dev->mmio_base; np->mmio_ba = (u32)dev->mmio_base;
np->ram_ba = (u32)dev->ram_base;
np->s.ioaddr = dev->s.ioaddr; np->s.ioaddr = dev->s.ioaddr;
np->s.ramaddr = dev->s.ramaddr; np->s.ramaddr = dev->s.ramaddr;
if (!(np->features & FE_RAM))
dev->ram_base = 0;
if (dev->ram_base)
np->ram_ba = (u32)dev->ram_base;
/* /*
* Edit its name. * Edit its name.
...@@ -1559,30 +1556,28 @@ static int __devinit sym_set_workarounds(struct sym_device *device) ...@@ -1559,30 +1556,28 @@ static int __devinit sym_set_workarounds(struct sym_device *device)
} }
/* /*
* Read and check the PCI configuration for any detected NCR * Map HBA registers and on-chip SRAM (if present).
* boards and save data for attaching after all boards have
* been detected.
*/ */
static void __devinit static int __devinit
sym_init_device(struct pci_dev *pdev, struct sym_device *device) sym_iomap_device(struct sym_device *device)
{ {
int i = 2; struct pci_dev *pdev = device->pdev;
struct pci_bus_region bus_addr; struct pci_bus_region bus_addr;
int i = 2;
device->host_id = SYM_SETUP_HOST_ID;
device->pdev = pdev;
pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]); pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]);
device->mmio_base = bus_addr.start; device->mmio_base = bus_addr.start;
/* if (device->chip.features & FE_RAM) {
* If the BAR is 64-bit, resource 2 will be occupied by the /*
* upper 32 bits * If the BAR is 64-bit, resource 2 will be occupied by the
*/ * upper 32 bits
if (!pdev->resource[i].flags) */
i++; if (!pdev->resource[i].flags)
pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]); i++;
device->ram_base = bus_addr.start; pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]);
device->ram_base = bus_addr.start;
}
#ifdef CONFIG_SCSI_SYM53C8XX_MMIO #ifdef CONFIG_SCSI_SYM53C8XX_MMIO
if (device->mmio_base) if (device->mmio_base)
...@@ -1592,9 +1587,21 @@ sym_init_device(struct pci_dev *pdev, struct sym_device *device) ...@@ -1592,9 +1587,21 @@ sym_init_device(struct pci_dev *pdev, struct sym_device *device)
if (!device->s.ioaddr) if (!device->s.ioaddr)
device->s.ioaddr = pci_iomap(pdev, 0, device->s.ioaddr = pci_iomap(pdev, 0,
pci_resource_len(pdev, 0)); pci_resource_len(pdev, 0));
if (device->ram_base) if (!device->s.ioaddr) {
dev_err(&pdev->dev, "could not map registers; giving up.\n");
return -EIO;
}
if (device->ram_base) {
device->s.ramaddr = pci_iomap(pdev, i, device->s.ramaddr = pci_iomap(pdev, i,
pci_resource_len(pdev, i)); pci_resource_len(pdev, i));
if (!device->s.ramaddr) {
dev_warn(&pdev->dev,
"could not map SRAM; continuing anyway.\n");
device->ram_base = 0;
}
}
return 0;
} }
/* /*
...@@ -1711,6 +1718,8 @@ static int __devinit sym2_probe(struct pci_dev *pdev, ...@@ -1711,6 +1718,8 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
memset(&sym_dev, 0, sizeof(sym_dev)); memset(&sym_dev, 0, sizeof(sym_dev));
memset(&nvram, 0, sizeof(nvram)); memset(&nvram, 0, sizeof(nvram));
sym_dev.pdev = pdev;
sym_dev.host_id = SYM_SETUP_HOST_ID;
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
goto leave; goto leave;
...@@ -1720,12 +1729,13 @@ static int __devinit sym2_probe(struct pci_dev *pdev, ...@@ -1720,12 +1729,13 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
if (pci_request_regions(pdev, NAME53C8XX)) if (pci_request_regions(pdev, NAME53C8XX))
goto disable; goto disable;
sym_init_device(pdev, &sym_dev);
do_iounmap = 1;
if (sym_check_supported(&sym_dev)) if (sym_check_supported(&sym_dev))
goto free; goto free;
if (sym_iomap_device(&sym_dev))
goto free;
do_iounmap = 1;
if (sym_check_raid(&sym_dev)) { if (sym_check_raid(&sym_dev)) {
do_disable_device = 0; /* Don't disable the device */ do_disable_device = 0; /* Don't disable the device */
goto free; goto free;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册