diff options
author | Giridhar Malavali <giridhar.malavali@qlogic.com> | 2011-11-18 12:03:16 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-12-15 01:55:04 -0500 |
commit | 706f457d000c8f334a1af37508d946a561d5929a (patch) | |
tree | 67dfc7376b52bedb3b1dbd3bc8732c792c9f11b4 /drivers/scsi/qla2xxx | |
parent | 2e26426917ae5b093d355abe1fc1a7b89492f0e6 (diff) |
[SCSI] qla2xxx: Added a new entry to ISP specific function pointers structure.
Add a new function to ISP specific pointers structure to take care of ISP
specific PCI IO space configuration.
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 256 |
2 files changed, 133 insertions, 124 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 964e2886311b..d046db1a2ded 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2244,6 +2244,7 @@ struct isp_operations { | |||
2244 | int (*get_flash_version) (struct scsi_qla_host *, void *); | 2244 | int (*get_flash_version) (struct scsi_qla_host *, void *); |
2245 | int (*start_scsi) (srb_t *); | 2245 | int (*start_scsi) (srb_t *); |
2246 | int (*abort_isp) (struct scsi_qla_host *); | 2246 | int (*abort_isp) (struct scsi_qla_host *); |
2247 | int (*iospace_config)(struct qla_hw_data*); | ||
2247 | }; | 2248 | }; |
2248 | 2249 | ||
2249 | /* MSI-X Support *************************************************************/ | 2250 | /* MSI-X Support *************************************************************/ |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b3028f546848..d713bc387790 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1484,6 +1484,118 @@ qla24xx_disable_intrs(struct qla_hw_data *ha) | |||
1484 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1484 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1485 | } | 1485 | } |
1486 | 1486 | ||
1487 | static int | ||
1488 | qla2x00_iospace_config(struct qla_hw_data *ha) | ||
1489 | { | ||
1490 | resource_size_t pio; | ||
1491 | uint16_t msix; | ||
1492 | int cpus; | ||
1493 | |||
1494 | if (IS_QLA82XX(ha)) | ||
1495 | return qla82xx_iospace_config(ha); | ||
1496 | |||
1497 | if (pci_request_selected_regions(ha->pdev, ha->bars, | ||
1498 | QLA2XXX_DRIVER_NAME)) { | ||
1499 | ql_log_pci(ql_log_fatal, ha->pdev, 0x0011, | ||
1500 | "Failed to reserve PIO/MMIO regions (%s), aborting.\n", | ||
1501 | pci_name(ha->pdev)); | ||
1502 | goto iospace_error_exit; | ||
1503 | } | ||
1504 | if (!(ha->bars & 1)) | ||
1505 | goto skip_pio; | ||
1506 | |||
1507 | /* We only need PIO for Flash operations on ISP2312 v2 chips. */ | ||
1508 | pio = pci_resource_start(ha->pdev, 0); | ||
1509 | if (pci_resource_flags(ha->pdev, 0) & IORESOURCE_IO) { | ||
1510 | if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) { | ||
1511 | ql_log_pci(ql_log_warn, ha->pdev, 0x0012, | ||
1512 | "Invalid pci I/O region size (%s).\n", | ||
1513 | pci_name(ha->pdev)); | ||
1514 | pio = 0; | ||
1515 | } | ||
1516 | } else { | ||
1517 | ql_log_pci(ql_log_warn, ha->pdev, 0x0013, | ||
1518 | "Region #0 no a PIO resource (%s).\n", | ||
1519 | pci_name(ha->pdev)); | ||
1520 | pio = 0; | ||
1521 | } | ||
1522 | ha->pio_address = pio; | ||
1523 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0014, | ||
1524 | "PIO address=%llu.\n", | ||
1525 | (unsigned long long)ha->pio_address); | ||
1526 | |||
1527 | skip_pio: | ||
1528 | /* Use MMIO operations for all accesses. */ | ||
1529 | if (!(pci_resource_flags(ha->pdev, 1) & IORESOURCE_MEM)) { | ||
1530 | ql_log_pci(ql_log_fatal, ha->pdev, 0x0015, | ||
1531 | "Region #1 not an MMIO resource (%s), aborting.\n", | ||
1532 | pci_name(ha->pdev)); | ||
1533 | goto iospace_error_exit; | ||
1534 | } | ||
1535 | if (pci_resource_len(ha->pdev, 1) < MIN_IOBASE_LEN) { | ||
1536 | ql_log_pci(ql_log_fatal, ha->pdev, 0x0016, | ||
1537 | "Invalid PCI mem region size (%s), aborting.\n", | ||
1538 | pci_name(ha->pdev)); | ||
1539 | goto iospace_error_exit; | ||
1540 | } | ||
1541 | |||
1542 | ha->iobase = ioremap(pci_resource_start(ha->pdev, 1), MIN_IOBASE_LEN); | ||
1543 | if (!ha->iobase) { | ||
1544 | ql_log_pci(ql_log_fatal, ha->pdev, 0x0017, | ||
1545 | "Cannot remap MMIO (%s), aborting.\n", | ||
1546 | pci_name(ha->pdev)); | ||
1547 | goto iospace_error_exit; | ||
1548 | } | ||
1549 | |||
1550 | /* Determine queue resources */ | ||
1551 | ha->max_req_queues = ha->max_rsp_queues = 1; | ||
1552 | if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) || | ||
1553 | (ql2xmaxqueues > 1 && ql2xmultique_tag) || | ||
1554 | (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))) | ||
1555 | goto mqiobase_exit; | ||
1556 | |||
1557 | ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3), | ||
1558 | pci_resource_len(ha->pdev, 3)); | ||
1559 | if (ha->mqiobase) { | ||
1560 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0018, | ||
1561 | "MQIO Base=%p.\n", ha->mqiobase); | ||
1562 | /* Read MSIX vector size of the board */ | ||
1563 | pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix); | ||
1564 | ha->msix_count = msix; | ||
1565 | /* Max queues are bounded by available msix vectors */ | ||
1566 | /* queue 0 uses two msix vectors */ | ||
1567 | if (ql2xmultique_tag) { | ||
1568 | cpus = num_online_cpus(); | ||
1569 | ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ? | ||
1570 | (cpus + 1) : (ha->msix_count - 1); | ||
1571 | ha->max_req_queues = 2; | ||
1572 | } else if (ql2xmaxqueues > 1) { | ||
1573 | ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ? | ||
1574 | QLA_MQ_SIZE : ql2xmaxqueues; | ||
1575 | ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc008, | ||
1576 | "QoS mode set, max no of request queues:%d.\n", | ||
1577 | ha->max_req_queues); | ||
1578 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0019, | ||
1579 | "QoS mode set, max no of request queues:%d.\n", | ||
1580 | ha->max_req_queues); | ||
1581 | } | ||
1582 | ql_log_pci(ql_log_info, ha->pdev, 0x001a, | ||
1583 | "MSI-X vector count: %d.\n", msix); | ||
1584 | } else | ||
1585 | ql_log_pci(ql_log_info, ha->pdev, 0x001b, | ||
1586 | "BAR 3 not enabled.\n"); | ||
1587 | |||
1588 | mqiobase_exit: | ||
1589 | ha->msix_count = ha->max_rsp_queues + 1; | ||
1590 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x001c, | ||
1591 | "MSIX Count:%d.\n", ha->msix_count); | ||
1592 | return (0); | ||
1593 | |||
1594 | iospace_error_exit: | ||
1595 | return (-ENOMEM); | ||
1596 | } | ||
1597 | |||
1598 | |||
1487 | static struct isp_operations qla2100_isp_ops = { | 1599 | static struct isp_operations qla2100_isp_ops = { |
1488 | .pci_config = qla2100_pci_config, | 1600 | .pci_config = qla2100_pci_config, |
1489 | .reset_chip = qla2x00_reset_chip, | 1601 | .reset_chip = qla2x00_reset_chip, |
@@ -1518,6 +1630,7 @@ static struct isp_operations qla2100_isp_ops = { | |||
1518 | .get_flash_version = qla2x00_get_flash_version, | 1630 | .get_flash_version = qla2x00_get_flash_version, |
1519 | .start_scsi = qla2x00_start_scsi, | 1631 | .start_scsi = qla2x00_start_scsi, |
1520 | .abort_isp = qla2x00_abort_isp, | 1632 | .abort_isp = qla2x00_abort_isp, |
1633 | .iospace_config = qla2x00_iospace_config, | ||
1521 | }; | 1634 | }; |
1522 | 1635 | ||
1523 | static struct isp_operations qla2300_isp_ops = { | 1636 | static struct isp_operations qla2300_isp_ops = { |
@@ -1554,6 +1667,7 @@ static struct isp_operations qla2300_isp_ops = { | |||
1554 | .get_flash_version = qla2x00_get_flash_version, | 1667 | .get_flash_version = qla2x00_get_flash_version, |
1555 | .start_scsi = qla2x00_start_scsi, | 1668 | .start_scsi = qla2x00_start_scsi, |
1556 | .abort_isp = qla2x00_abort_isp, | 1669 | .abort_isp = qla2x00_abort_isp, |
1670 | .iospace_config = qla2x00_iospace_config, | ||
1557 | }; | 1671 | }; |
1558 | 1672 | ||
1559 | static struct isp_operations qla24xx_isp_ops = { | 1673 | static struct isp_operations qla24xx_isp_ops = { |
@@ -1590,6 +1704,7 @@ static struct isp_operations qla24xx_isp_ops = { | |||
1590 | .get_flash_version = qla24xx_get_flash_version, | 1704 | .get_flash_version = qla24xx_get_flash_version, |
1591 | .start_scsi = qla24xx_start_scsi, | 1705 | .start_scsi = qla24xx_start_scsi, |
1592 | .abort_isp = qla2x00_abort_isp, | 1706 | .abort_isp = qla2x00_abort_isp, |
1707 | .iospace_config = qla2x00_iospace_config, | ||
1593 | }; | 1708 | }; |
1594 | 1709 | ||
1595 | static struct isp_operations qla25xx_isp_ops = { | 1710 | static struct isp_operations qla25xx_isp_ops = { |
@@ -1626,6 +1741,7 @@ static struct isp_operations qla25xx_isp_ops = { | |||
1626 | .get_flash_version = qla24xx_get_flash_version, | 1741 | .get_flash_version = qla24xx_get_flash_version, |
1627 | .start_scsi = qla24xx_dif_start_scsi, | 1742 | .start_scsi = qla24xx_dif_start_scsi, |
1628 | .abort_isp = qla2x00_abort_isp, | 1743 | .abort_isp = qla2x00_abort_isp, |
1744 | .iospace_config = qla2x00_iospace_config, | ||
1629 | }; | 1745 | }; |
1630 | 1746 | ||
1631 | static struct isp_operations qla81xx_isp_ops = { | 1747 | static struct isp_operations qla81xx_isp_ops = { |
@@ -1662,6 +1778,7 @@ static struct isp_operations qla81xx_isp_ops = { | |||
1662 | .get_flash_version = qla24xx_get_flash_version, | 1778 | .get_flash_version = qla24xx_get_flash_version, |
1663 | .start_scsi = qla24xx_dif_start_scsi, | 1779 | .start_scsi = qla24xx_dif_start_scsi, |
1664 | .abort_isp = qla2x00_abort_isp, | 1780 | .abort_isp = qla2x00_abort_isp, |
1781 | .iospace_config = qla2x00_iospace_config, | ||
1665 | }; | 1782 | }; |
1666 | 1783 | ||
1667 | static struct isp_operations qla82xx_isp_ops = { | 1784 | static struct isp_operations qla82xx_isp_ops = { |
@@ -1698,6 +1815,7 @@ static struct isp_operations qla82xx_isp_ops = { | |||
1698 | .get_flash_version = qla24xx_get_flash_version, | 1815 | .get_flash_version = qla24xx_get_flash_version, |
1699 | .start_scsi = qla82xx_start_scsi, | 1816 | .start_scsi = qla82xx_start_scsi, |
1700 | .abort_isp = qla82xx_abort_isp, | 1817 | .abort_isp = qla82xx_abort_isp, |
1818 | .iospace_config = qla82xx_iospace_config, | ||
1701 | }; | 1819 | }; |
1702 | 1820 | ||
1703 | static inline void | 1821 | static inline void |
@@ -1811,117 +1929,6 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha) | |||
1811 | ha->device_type, ha->flags.port0, ha->fw_srisc_address); | 1929 | ha->device_type, ha->flags.port0, ha->fw_srisc_address); |
1812 | } | 1930 | } |
1813 | 1931 | ||
1814 | static int | ||
1815 | qla2x00_iospace_config(struct qla_hw_data *ha) | ||
1816 | { | ||
1817 | resource_size_t pio; | ||
1818 | uint16_t msix; | ||
1819 | int cpus; | ||
1820 | |||
1821 | if (IS_QLA82XX(ha)) | ||
1822 | return qla82xx_iospace_config(ha); | ||
1823 | |||
1824 | if (pci_request_selected_regions(ha->pdev, ha->bars, | ||
1825 | QLA2XXX_DRIVER_NAME)) { | ||
1826 | ql_log_pci(ql_log_fatal, ha->pdev, 0x0011, | ||
1827 | "Failed to reserve PIO/MMIO regions (%s), aborting.\n", | ||
1828 | pci_name(ha->pdev)); | ||
1829 | goto iospace_error_exit; | ||
1830 | } | ||
1831 | if (!(ha->bars & 1)) | ||
1832 | goto skip_pio; | ||
1833 | |||
1834 | /* We only need PIO for Flash operations on ISP2312 v2 chips. */ | ||
1835 | pio = pci_resource_start(ha->pdev, 0); | ||
1836 | if (pci_resource_flags(ha->pdev, 0) & IORESOURCE_IO) { | ||
1837 | if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) { | ||
1838 | ql_log_pci(ql_log_warn, ha->pdev, 0x0012, | ||
1839 | "Invalid pci I/O region size (%s).\n", | ||
1840 | pci_name(ha->pdev)); | ||
1841 | pio = 0; | ||
1842 | } | ||
1843 | } else { | ||
1844 | ql_log_pci(ql_log_warn, ha->pdev, 0x0013, | ||
1845 | "Region #0 no a PIO resource (%s).\n", | ||
1846 | pci_name(ha->pdev)); | ||
1847 | pio = 0; | ||
1848 | } | ||
1849 | ha->pio_address = pio; | ||
1850 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0014, | ||
1851 | "PIO address=%llu.\n", | ||
1852 | (unsigned long long)ha->pio_address); | ||
1853 | |||
1854 | skip_pio: | ||
1855 | /* Use MMIO operations for all accesses. */ | ||
1856 | if (!(pci_resource_flags(ha->pdev, 1) & IORESOURCE_MEM)) { | ||
1857 | ql_log_pci(ql_log_fatal, ha->pdev, 0x0015, | ||
1858 | "Region #1 not an MMIO resource (%s), aborting.\n", | ||
1859 | pci_name(ha->pdev)); | ||
1860 | goto iospace_error_exit; | ||
1861 | } | ||
1862 | if (pci_resource_len(ha->pdev, 1) < MIN_IOBASE_LEN) { | ||
1863 | ql_log_pci(ql_log_fatal, ha->pdev, 0x0016, | ||
1864 | "Invalid PCI mem region size (%s), aborting.\n", | ||
1865 | pci_name(ha->pdev)); | ||
1866 | goto iospace_error_exit; | ||
1867 | } | ||
1868 | |||
1869 | ha->iobase = ioremap(pci_resource_start(ha->pdev, 1), MIN_IOBASE_LEN); | ||
1870 | if (!ha->iobase) { | ||
1871 | ql_log_pci(ql_log_fatal, ha->pdev, 0x0017, | ||
1872 | "Cannot remap MMIO (%s), aborting.\n", | ||
1873 | pci_name(ha->pdev)); | ||
1874 | goto iospace_error_exit; | ||
1875 | } | ||
1876 | |||
1877 | /* Determine queue resources */ | ||
1878 | ha->max_req_queues = ha->max_rsp_queues = 1; | ||
1879 | if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) || | ||
1880 | (ql2xmaxqueues > 1 && ql2xmultique_tag) || | ||
1881 | (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))) | ||
1882 | goto mqiobase_exit; | ||
1883 | |||
1884 | ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3), | ||
1885 | pci_resource_len(ha->pdev, 3)); | ||
1886 | if (ha->mqiobase) { | ||
1887 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0018, | ||
1888 | "MQIO Base=%p.\n", ha->mqiobase); | ||
1889 | /* Read MSIX vector size of the board */ | ||
1890 | pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix); | ||
1891 | ha->msix_count = msix; | ||
1892 | /* Max queues are bounded by available msix vectors */ | ||
1893 | /* queue 0 uses two msix vectors */ | ||
1894 | if (ql2xmultique_tag) { | ||
1895 | cpus = num_online_cpus(); | ||
1896 | ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ? | ||
1897 | (cpus + 1) : (ha->msix_count - 1); | ||
1898 | ha->max_req_queues = 2; | ||
1899 | } else if (ql2xmaxqueues > 1) { | ||
1900 | ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ? | ||
1901 | QLA_MQ_SIZE : ql2xmaxqueues; | ||
1902 | ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc008, | ||
1903 | "QoS mode set, max no of request queues:%d.\n", | ||
1904 | ha->max_req_queues); | ||
1905 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0019, | ||
1906 | "QoS mode set, max no of request queues:%d.\n", | ||
1907 | ha->max_req_queues); | ||
1908 | } | ||
1909 | ql_log_pci(ql_log_info, ha->pdev, 0x001a, | ||
1910 | "MSI-X vector count: %d.\n", msix); | ||
1911 | } else | ||
1912 | ql_log_pci(ql_log_info, ha->pdev, 0x001b, | ||
1913 | "BAR 3 not enabled.\n"); | ||
1914 | |||
1915 | mqiobase_exit: | ||
1916 | ha->msix_count = ha->max_rsp_queues + 1; | ||
1917 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x001c, | ||
1918 | "MSIX Count:%d.\n", ha->msix_count); | ||
1919 | return (0); | ||
1920 | |||
1921 | iospace_error_exit: | ||
1922 | return (-ENOMEM); | ||
1923 | } | ||
1924 | |||
1925 | static void | 1932 | static void |
1926 | qla2xxx_scan_start(struct Scsi_Host *shost) | 1933 | qla2xxx_scan_start(struct Scsi_Host *shost) |
1927 | { | 1934 | { |
@@ -2020,19 +2027,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2020 | pdev->needs_freset = 1; | 2027 | pdev->needs_freset = 1; |
2021 | } | 2028 | } |
2022 | 2029 | ||
2023 | /* Configure PCI I/O space */ | ||
2024 | ret = qla2x00_iospace_config(ha); | ||
2025 | if (ret) | ||
2026 | goto probe_hw_failed; | ||
2027 | |||
2028 | ql_log_pci(ql_log_info, pdev, 0x001d, | ||
2029 | "Found an ISP%04X irq %d iobase 0x%p.\n", | ||
2030 | pdev->device, pdev->irq, ha->iobase); | ||
2031 | ha->prev_topology = 0; | ||
2032 | ha->init_cb_size = sizeof(init_cb_t); | ||
2033 | ha->link_data_rate = PORT_SPEED_UNKNOWN; | ||
2034 | ha->optrom_size = OPTROM_SIZE_2300; | ||
2035 | |||
2036 | /* Assign ISP specific operations. */ | 2030 | /* Assign ISP specific operations. */ |
2037 | max_id = MAX_TARGETS_2200; | 2031 | max_id = MAX_TARGETS_2200; |
2038 | if (IS_QLA2100(ha)) { | 2032 | if (IS_QLA2100(ha)) { |
@@ -2140,6 +2134,20 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2140 | "flash_data_off=%d, nvram_conf_off=%d, nvram_data_off=%d.\n", | 2134 | "flash_data_off=%d, nvram_conf_off=%d, nvram_data_off=%d.\n", |
2141 | ha->isp_ops, ha->flash_conf_off, ha->flash_data_off, | 2135 | ha->isp_ops, ha->flash_conf_off, ha->flash_data_off, |
2142 | ha->nvram_conf_off, ha->nvram_data_off); | 2136 | ha->nvram_conf_off, ha->nvram_data_off); |
2137 | |||
2138 | /* Configure PCI I/O space */ | ||
2139 | ret = ha->isp_ops->iospace_config(ha); | ||
2140 | if (ret) | ||
2141 | goto probe_hw_failed; | ||
2142 | |||
2143 | ql_log_pci(ql_log_info, pdev, 0x001d, | ||
2144 | "Found an ISP%04X irq %d iobase 0x%p.\n", | ||
2145 | pdev->device, pdev->irq, ha->iobase); | ||
2146 | ha->prev_topology = 0; | ||
2147 | ha->init_cb_size = sizeof(init_cb_t); | ||
2148 | ha->link_data_rate = PORT_SPEED_UNKNOWN; | ||
2149 | ha->optrom_size = OPTROM_SIZE_2300; | ||
2150 | |||
2143 | mutex_init(&ha->vport_lock); | 2151 | mutex_init(&ha->vport_lock); |
2144 | init_completion(&ha->mbx_cmd_comp); | 2152 | init_completion(&ha->mbx_cmd_comp); |
2145 | complete(&ha->mbx_cmd_comp); | 2153 | complete(&ha->mbx_cmd_comp); |