diff options
Diffstat (limited to 'drivers/scsi/sym53c8xx_2/sym_glue.c')
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_glue.c | 137 |
1 files changed, 83 insertions, 54 deletions
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index f4e6cde1fd0d..23e782015880 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c | |||
@@ -792,9 +792,9 @@ static int sym53c8xx_slave_configure(struct scsi_device *sdev) | |||
792 | 792 | ||
793 | /* | 793 | /* |
794 | * Select queue depth from driver setup. | 794 | * Select queue depth from driver setup. |
795 | * Donnot use more than configured by user. | 795 | * Do not use more than configured by user. |
796 | * Use at least 2. | 796 | * Use at least 1. |
797 | * Donnot use more than our maximum. | 797 | * Do not use more than our maximum. |
798 | */ | 798 | */ |
799 | reqtags = sym_driver_setup.max_tag; | 799 | reqtags = sym_driver_setup.max_tag; |
800 | if (reqtags > tp->usrtags) | 800 | if (reqtags > tp->usrtags) |
@@ -803,7 +803,7 @@ static int sym53c8xx_slave_configure(struct scsi_device *sdev) | |||
803 | reqtags = 0; | 803 | reqtags = 0; |
804 | if (reqtags > SYM_CONF_MAX_TAG) | 804 | if (reqtags > SYM_CONF_MAX_TAG) |
805 | reqtags = SYM_CONF_MAX_TAG; | 805 | reqtags = SYM_CONF_MAX_TAG; |
806 | depth_to_use = reqtags ? reqtags : 2; | 806 | depth_to_use = reqtags ? reqtags : 1; |
807 | scsi_adjust_queue_depth(sdev, | 807 | scsi_adjust_queue_depth(sdev, |
808 | sdev->tagged_supported ? MSG_SIMPLE_TAG : 0, | 808 | sdev->tagged_supported ? MSG_SIMPLE_TAG : 0, |
809 | depth_to_use); | 809 | depth_to_use); |
@@ -1236,14 +1236,29 @@ 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_iomap_device(). Note that | ||
1240 | * sym_free_resources() should be used instead of this function after calling | ||
1241 | * sym_attach(). | ||
1242 | */ | ||
1243 | static void __devinit | ||
1244 | sym_iounmap_device(struct sym_device *device) | ||
1245 | { | ||
1246 | if (device->s.ioaddr) | ||
1247 | pci_iounmap(device->pdev, device->s.ioaddr); | ||
1248 | if (device->s.ramaddr) | ||
1249 | pci_iounmap(device->pdev, device->s.ramaddr); | ||
1250 | } | ||
1251 | |||
1252 | /* | ||
1239 | * Free controller resources. | 1253 | * Free controller resources. |
1240 | */ | 1254 | */ |
1241 | static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev) | 1255 | static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev, |
1256 | int do_free_irq) | ||
1242 | { | 1257 | { |
1243 | /* | 1258 | /* |
1244 | * Free O/S specific resources. | 1259 | * Free O/S specific resources. |
1245 | */ | 1260 | */ |
1246 | if (pdev->irq) | 1261 | if (do_free_irq) |
1247 | free_irq(pdev->irq, np->s.host); | 1262 | free_irq(pdev->irq, np->s.host); |
1248 | if (np->s.ioaddr) | 1263 | if (np->s.ioaddr) |
1249 | pci_iounmap(pdev, np->s.ioaddr); | 1264 | pci_iounmap(pdev, np->s.ioaddr); |
@@ -1271,10 +1286,11 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1271 | { | 1286 | { |
1272 | struct sym_data *sym_data; | 1287 | struct sym_data *sym_data; |
1273 | struct sym_hcb *np = NULL; | 1288 | struct sym_hcb *np = NULL; |
1274 | struct Scsi_Host *shost; | 1289 | struct Scsi_Host *shost = NULL; |
1275 | struct pci_dev *pdev = dev->pdev; | 1290 | struct pci_dev *pdev = dev->pdev; |
1276 | unsigned long flags; | 1291 | unsigned long flags; |
1277 | struct sym_fw *fw; | 1292 | struct sym_fw *fw; |
1293 | int do_free_irq = 0; | ||
1278 | 1294 | ||
1279 | printk(KERN_INFO "sym%d: <%s> rev 0x%x at pci %s irq %u\n", | 1295 | printk(KERN_INFO "sym%d: <%s> rev 0x%x at pci %s irq %u\n", |
1280 | unit, dev->chip.name, pdev->revision, pci_name(pdev), | 1296 | unit, dev->chip.name, pdev->revision, pci_name(pdev), |
@@ -1285,11 +1301,11 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1285 | */ | 1301 | */ |
1286 | fw = sym_find_firmware(&dev->chip); | 1302 | fw = sym_find_firmware(&dev->chip); |
1287 | if (!fw) | 1303 | if (!fw) |
1288 | return NULL; | 1304 | goto attach_failed; |
1289 | 1305 | ||
1290 | shost = scsi_host_alloc(tpnt, sizeof(*sym_data)); | 1306 | shost = scsi_host_alloc(tpnt, sizeof(*sym_data)); |
1291 | if (!shost) | 1307 | if (!shost) |
1292 | return NULL; | 1308 | goto attach_failed; |
1293 | sym_data = shost_priv(shost); | 1309 | sym_data = shost_priv(shost); |
1294 | 1310 | ||
1295 | /* | 1311 | /* |
@@ -1319,6 +1335,10 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1319 | np->maxoffs = dev->chip.offset_max; | 1335 | np->maxoffs = dev->chip.offset_max; |
1320 | np->maxburst = dev->chip.burst_max; | 1336 | np->maxburst = dev->chip.burst_max; |
1321 | np->myaddr = dev->host_id; | 1337 | np->myaddr = dev->host_id; |
1338 | np->mmio_ba = (u32)dev->mmio_base; | ||
1339 | np->ram_ba = (u32)dev->ram_base; | ||
1340 | np->s.ioaddr = dev->s.ioaddr; | ||
1341 | np->s.ramaddr = dev->s.ramaddr; | ||
1322 | 1342 | ||
1323 | /* | 1343 | /* |
1324 | * Edit its name. | 1344 | * Edit its name. |
@@ -1334,22 +1354,6 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1334 | goto attach_failed; | 1354 | goto attach_failed; |
1335 | } | 1355 | } |
1336 | 1356 | ||
1337 | /* | ||
1338 | * Try to map the controller chip to | ||
1339 | * virtual and physical memory. | ||
1340 | */ | ||
1341 | np->mmio_ba = (u32)dev->mmio_base; | ||
1342 | np->s.ioaddr = dev->s.ioaddr; | ||
1343 | np->s.ramaddr = dev->s.ramaddr; | ||
1344 | |||
1345 | /* | ||
1346 | * Map on-chip RAM if present and supported. | ||
1347 | */ | ||
1348 | if (!(np->features & FE_RAM)) | ||
1349 | dev->ram_base = 0; | ||
1350 | if (dev->ram_base) | ||
1351 | np->ram_ba = (u32)dev->ram_base; | ||
1352 | |||
1353 | if (sym_hcb_attach(shost, fw, dev->nvram)) | 1357 | if (sym_hcb_attach(shost, fw, dev->nvram)) |
1354 | goto attach_failed; | 1358 | goto attach_failed; |
1355 | 1359 | ||
@@ -1364,6 +1368,7 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1364 | sym_name(np), pdev->irq); | 1368 | sym_name(np), pdev->irq); |
1365 | goto attach_failed; | 1369 | goto attach_failed; |
1366 | } | 1370 | } |
1371 | do_free_irq = 1; | ||
1367 | 1372 | ||
1368 | /* | 1373 | /* |
1369 | * After SCSI devices have been opened, we cannot | 1374 | * After SCSI devices have been opened, we cannot |
@@ -1416,12 +1421,13 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, | |||
1416 | "TERMINATION, DEVICE POWER etc.!\n", sym_name(np)); | 1421 | "TERMINATION, DEVICE POWER etc.!\n", sym_name(np)); |
1417 | spin_unlock_irqrestore(shost->host_lock, flags); | 1422 | spin_unlock_irqrestore(shost->host_lock, flags); |
1418 | attach_failed: | 1423 | attach_failed: |
1419 | if (!shost) | 1424 | printf_info("sym%d: giving up ...\n", unit); |
1420 | return NULL; | ||
1421 | printf_info("%s: giving up ...\n", sym_name(np)); | ||
1422 | if (np) | 1425 | if (np) |
1423 | sym_free_resources(np, pdev); | 1426 | sym_free_resources(np, pdev, do_free_irq); |
1424 | scsi_host_put(shost); | 1427 | else |
1428 | sym_iounmap_device(dev); | ||
1429 | if (shost) | ||
1430 | scsi_host_put(shost); | ||
1425 | 1431 | ||
1426 | return NULL; | 1432 | return NULL; |
1427 | } | 1433 | } |
@@ -1550,30 +1556,28 @@ static int __devinit sym_set_workarounds(struct sym_device *device) | |||
1550 | } | 1556 | } |
1551 | 1557 | ||
1552 | /* | 1558 | /* |
1553 | * Read and check the PCI configuration for any detected NCR | 1559 | * Map HBA registers and on-chip SRAM (if present). |
1554 | * boards and save data for attaching after all boards have | ||
1555 | * been detected. | ||
1556 | */ | 1560 | */ |
1557 | static void __devinit | 1561 | static int __devinit |
1558 | sym_init_device(struct pci_dev *pdev, struct sym_device *device) | 1562 | sym_iomap_device(struct sym_device *device) |
1559 | { | 1563 | { |
1560 | int i = 2; | 1564 | struct pci_dev *pdev = device->pdev; |
1561 | struct pci_bus_region bus_addr; | 1565 | struct pci_bus_region bus_addr; |
1562 | 1566 | int i = 2; | |
1563 | device->host_id = SYM_SETUP_HOST_ID; | ||
1564 | device->pdev = pdev; | ||
1565 | 1567 | ||
1566 | pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]); | 1568 | pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]); |
1567 | device->mmio_base = bus_addr.start; | 1569 | device->mmio_base = bus_addr.start; |
1568 | 1570 | ||
1569 | /* | 1571 | if (device->chip.features & FE_RAM) { |
1570 | * If the BAR is 64-bit, resource 2 will be occupied by the | 1572 | /* |
1571 | * upper 32 bits | 1573 | * If the BAR is 64-bit, resource 2 will be occupied by the |
1572 | */ | 1574 | * upper 32 bits |
1573 | if (!pdev->resource[i].flags) | 1575 | */ |
1574 | i++; | 1576 | if (!pdev->resource[i].flags) |
1575 | pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]); | 1577 | i++; |
1576 | 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 | } | ||
1577 | 1581 | ||
1578 | #ifdef CONFIG_SCSI_SYM53C8XX_MMIO | 1582 | #ifdef CONFIG_SCSI_SYM53C8XX_MMIO |
1579 | if (device->mmio_base) | 1583 | if (device->mmio_base) |
@@ -1583,9 +1587,21 @@ sym_init_device(struct pci_dev *pdev, struct sym_device *device) | |||
1583 | if (!device->s.ioaddr) | 1587 | if (!device->s.ioaddr) |
1584 | device->s.ioaddr = pci_iomap(pdev, 0, | 1588 | device->s.ioaddr = pci_iomap(pdev, 0, |
1585 | pci_resource_len(pdev, 0)); | 1589 | pci_resource_len(pdev, 0)); |
1586 | 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) { | ||
1587 | device->s.ramaddr = pci_iomap(pdev, i, | 1595 | device->s.ramaddr = pci_iomap(pdev, i, |
1588 | 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; | ||
1589 | } | 1605 | } |
1590 | 1606 | ||
1591 | /* | 1607 | /* |
@@ -1659,7 +1675,8 @@ static int sym_detach(struct Scsi_Host *shost, struct pci_dev *pdev) | |||
1659 | udelay(10); | 1675 | udelay(10); |
1660 | OUTB(np, nc_istat, 0); | 1676 | OUTB(np, nc_istat, 0); |
1661 | 1677 | ||
1662 | sym_free_resources(np, pdev); | 1678 | sym_free_resources(np, pdev, 1); |
1679 | scsi_host_put(shost); | ||
1663 | 1680 | ||
1664 | return 1; | 1681 | return 1; |
1665 | } | 1682 | } |
@@ -1696,9 +1713,13 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1696 | struct sym_device sym_dev; | 1713 | struct sym_device sym_dev; |
1697 | struct sym_nvram nvram; | 1714 | struct sym_nvram nvram; |
1698 | struct Scsi_Host *shost; | 1715 | struct Scsi_Host *shost; |
1716 | int do_iounmap = 0; | ||
1717 | int do_disable_device = 1; | ||
1699 | 1718 | ||
1700 | memset(&sym_dev, 0, sizeof(sym_dev)); | 1719 | memset(&sym_dev, 0, sizeof(sym_dev)); |
1701 | 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; | ||
1702 | 1723 | ||
1703 | if (pci_enable_device(pdev)) | 1724 | if (pci_enable_device(pdev)) |
1704 | goto leave; | 1725 | goto leave; |
@@ -1708,12 +1729,17 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1708 | if (pci_request_regions(pdev, NAME53C8XX)) | 1729 | if (pci_request_regions(pdev, NAME53C8XX)) |
1709 | goto disable; | 1730 | goto disable; |
1710 | 1731 | ||
1711 | sym_init_device(pdev, &sym_dev); | ||
1712 | if (sym_check_supported(&sym_dev)) | 1732 | if (sym_check_supported(&sym_dev)) |
1713 | goto free; | 1733 | goto free; |
1714 | 1734 | ||
1715 | if (sym_check_raid(&sym_dev)) | 1735 | if (sym_iomap_device(&sym_dev)) |
1716 | goto leave; /* Don't disable the device */ | 1736 | goto free; |
1737 | do_iounmap = 1; | ||
1738 | |||
1739 | if (sym_check_raid(&sym_dev)) { | ||
1740 | do_disable_device = 0; /* Don't disable the device */ | ||
1741 | goto free; | ||
1742 | } | ||
1717 | 1743 | ||
1718 | if (sym_set_workarounds(&sym_dev)) | 1744 | if (sym_set_workarounds(&sym_dev)) |
1719 | goto free; | 1745 | goto free; |
@@ -1722,6 +1748,7 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1722 | 1748 | ||
1723 | sym_get_nvram(&sym_dev, &nvram); | 1749 | sym_get_nvram(&sym_dev, &nvram); |
1724 | 1750 | ||
1751 | do_iounmap = 0; /* Don't sym_iounmap_device() after sym_attach(). */ | ||
1725 | shost = sym_attach(&sym2_template, attach_count, &sym_dev); | 1752 | shost = sym_attach(&sym2_template, attach_count, &sym_dev); |
1726 | if (!shost) | 1753 | if (!shost) |
1727 | goto free; | 1754 | goto free; |
@@ -1737,9 +1764,12 @@ static int __devinit sym2_probe(struct pci_dev *pdev, | |||
1737 | detach: | 1764 | detach: |
1738 | sym_detach(pci_get_drvdata(pdev), pdev); | 1765 | sym_detach(pci_get_drvdata(pdev), pdev); |
1739 | free: | 1766 | free: |
1767 | if (do_iounmap) | ||
1768 | sym_iounmap_device(&sym_dev); | ||
1740 | pci_release_regions(pdev); | 1769 | pci_release_regions(pdev); |
1741 | disable: | 1770 | disable: |
1742 | pci_disable_device(pdev); | 1771 | if (do_disable_device) |
1772 | pci_disable_device(pdev); | ||
1743 | leave: | 1773 | leave: |
1744 | return -ENODEV; | 1774 | return -ENODEV; |
1745 | } | 1775 | } |
@@ -1749,7 +1779,6 @@ static void sym2_remove(struct pci_dev *pdev) | |||
1749 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 1779 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
1750 | 1780 | ||
1751 | scsi_remove_host(shost); | 1781 | scsi_remove_host(shost); |
1752 | scsi_host_put(shost); | ||
1753 | sym_detach(shost, pdev); | 1782 | sym_detach(shost, pdev); |
1754 | pci_release_regions(pdev); | 1783 | pci_release_regions(pdev); |
1755 | pci_disable_device(pdev); | 1784 | pci_disable_device(pdev); |