From 783fa7311b2c639f39c6163f9fbb05253fb2d702 Mon Sep 17 00:00:00 2001 From: Tony Battersby Date: Thu, 8 Jan 2009 12:56:58 -0500 Subject: [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 Signed-off-by: James Bottomley --- drivers/scsi/sym53c8xx_2/sym_glue.c | 62 +++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 26 deletions(-) (limited to 'drivers/scsi/sym53c8xx_2/sym_glue.c') 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, #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_attach(). */ @@ -1336,12 +1336,9 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, np->maxburst = dev->chip.burst_max; np->myaddr = dev->host_id; np->mmio_ba = (u32)dev->mmio_base; + np->ram_ba = (u32)dev->ram_base; np->s.ioaddr = dev->s.ioaddr; 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. @@ -1559,30 +1556,28 @@ static int __devinit sym_set_workarounds(struct sym_device *device) } /* - * Read and check the PCI configuration for any detected NCR - * boards and save data for attaching after all boards have - * been detected. + * Map HBA registers and on-chip SRAM (if present). */ -static void __devinit -sym_init_device(struct pci_dev *pdev, struct sym_device *device) +static int __devinit +sym_iomap_device(struct sym_device *device) { - int i = 2; + struct pci_dev *pdev = device->pdev; struct pci_bus_region bus_addr; - - device->host_id = SYM_SETUP_HOST_ID; - device->pdev = pdev; + int i = 2; pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]); device->mmio_base = bus_addr.start; - /* - * If the BAR is 64-bit, resource 2 will be occupied by the - * upper 32 bits - */ - if (!pdev->resource[i].flags) - i++; - pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]); - device->ram_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 (!pdev->resource[i].flags) + i++; + pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]); + device->ram_base = bus_addr.start; + } #ifdef CONFIG_SCSI_SYM53C8XX_MMIO if (device->mmio_base) @@ -1592,9 +1587,21 @@ sym_init_device(struct pci_dev *pdev, struct sym_device *device) if (!device->s.ioaddr) device->s.ioaddr = pci_iomap(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, 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, memset(&sym_dev, 0, sizeof(sym_dev)); memset(&nvram, 0, sizeof(nvram)); + sym_dev.pdev = pdev; + sym_dev.host_id = SYM_SETUP_HOST_ID; if (pci_enable_device(pdev)) goto leave; @@ -1720,12 +1729,13 @@ static int __devinit sym2_probe(struct pci_dev *pdev, if (pci_request_regions(pdev, NAME53C8XX)) goto disable; - sym_init_device(pdev, &sym_dev); - do_iounmap = 1; - if (sym_check_supported(&sym_dev)) goto free; + if (sym_iomap_device(&sym_dev)) + goto free; + do_iounmap = 1; + if (sym_check_raid(&sym_dev)) { do_disable_device = 0; /* Don't disable the device */ goto free; -- cgit v1.2.2