[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>
This commit is contained in:
Giridhar Malavali 2011-11-18 09:03:16 -08:00 committed by James Bottomley
parent 2e26426917
commit 706f457d00
2 changed files with 133 additions and 124 deletions

View file

@ -2244,6 +2244,7 @@ struct isp_operations {
int (*get_flash_version) (struct scsi_qla_host *, void *);
int (*start_scsi) (srb_t *);
int (*abort_isp) (struct scsi_qla_host *);
int (*iospace_config)(struct qla_hw_data*);
};
/* MSI-X Support *************************************************************/

View file

@ -1484,6 +1484,118 @@ qla24xx_disable_intrs(struct qla_hw_data *ha)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
static int
qla2x00_iospace_config(struct qla_hw_data *ha)
{
resource_size_t pio;
uint16_t msix;
int cpus;
if (IS_QLA82XX(ha))
return qla82xx_iospace_config(ha);
if (pci_request_selected_regions(ha->pdev, ha->bars,
QLA2XXX_DRIVER_NAME)) {
ql_log_pci(ql_log_fatal, ha->pdev, 0x0011,
"Failed to reserve PIO/MMIO regions (%s), aborting.\n",
pci_name(ha->pdev));
goto iospace_error_exit;
}
if (!(ha->bars & 1))
goto skip_pio;
/* We only need PIO for Flash operations on ISP2312 v2 chips. */
pio = pci_resource_start(ha->pdev, 0);
if (pci_resource_flags(ha->pdev, 0) & IORESOURCE_IO) {
if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) {
ql_log_pci(ql_log_warn, ha->pdev, 0x0012,
"Invalid pci I/O region size (%s).\n",
pci_name(ha->pdev));
pio = 0;
}
} else {
ql_log_pci(ql_log_warn, ha->pdev, 0x0013,
"Region #0 no a PIO resource (%s).\n",
pci_name(ha->pdev));
pio = 0;
}
ha->pio_address = pio;
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0014,
"PIO address=%llu.\n",
(unsigned long long)ha->pio_address);
skip_pio:
/* Use MMIO operations for all accesses. */
if (!(pci_resource_flags(ha->pdev, 1) & IORESOURCE_MEM)) {
ql_log_pci(ql_log_fatal, ha->pdev, 0x0015,
"Region #1 not an MMIO resource (%s), aborting.\n",
pci_name(ha->pdev));
goto iospace_error_exit;
}
if (pci_resource_len(ha->pdev, 1) < MIN_IOBASE_LEN) {
ql_log_pci(ql_log_fatal, ha->pdev, 0x0016,
"Invalid PCI mem region size (%s), aborting.\n",
pci_name(ha->pdev));
goto iospace_error_exit;
}
ha->iobase = ioremap(pci_resource_start(ha->pdev, 1), MIN_IOBASE_LEN);
if (!ha->iobase) {
ql_log_pci(ql_log_fatal, ha->pdev, 0x0017,
"Cannot remap MMIO (%s), aborting.\n",
pci_name(ha->pdev));
goto iospace_error_exit;
}
/* Determine queue resources */
ha->max_req_queues = ha->max_rsp_queues = 1;
if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) ||
(ql2xmaxqueues > 1 && ql2xmultique_tag) ||
(!IS_QLA25XX(ha) && !IS_QLA81XX(ha)))
goto mqiobase_exit;
ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
pci_resource_len(ha->pdev, 3));
if (ha->mqiobase) {
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0018,
"MQIO Base=%p.\n", ha->mqiobase);
/* Read MSIX vector size of the board */
pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix);
ha->msix_count = msix;
/* Max queues are bounded by available msix vectors */
/* queue 0 uses two msix vectors */
if (ql2xmultique_tag) {
cpus = num_online_cpus();
ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ?
(cpus + 1) : (ha->msix_count - 1);
ha->max_req_queues = 2;
} else if (ql2xmaxqueues > 1) {
ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ?
QLA_MQ_SIZE : ql2xmaxqueues;
ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc008,
"QoS mode set, max no of request queues:%d.\n",
ha->max_req_queues);
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0019,
"QoS mode set, max no of request queues:%d.\n",
ha->max_req_queues);
}
ql_log_pci(ql_log_info, ha->pdev, 0x001a,
"MSI-X vector count: %d.\n", msix);
} else
ql_log_pci(ql_log_info, ha->pdev, 0x001b,
"BAR 3 not enabled.\n");
mqiobase_exit:
ha->msix_count = ha->max_rsp_queues + 1;
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x001c,
"MSIX Count:%d.\n", ha->msix_count);
return (0);
iospace_error_exit:
return (-ENOMEM);
}
static struct isp_operations qla2100_isp_ops = {
.pci_config = qla2100_pci_config,
.reset_chip = qla2x00_reset_chip,
@ -1518,6 +1630,7 @@ static struct isp_operations qla2100_isp_ops = {
.get_flash_version = qla2x00_get_flash_version,
.start_scsi = qla2x00_start_scsi,
.abort_isp = qla2x00_abort_isp,
.iospace_config = qla2x00_iospace_config,
};
static struct isp_operations qla2300_isp_ops = {
@ -1554,6 +1667,7 @@ static struct isp_operations qla2300_isp_ops = {
.get_flash_version = qla2x00_get_flash_version,
.start_scsi = qla2x00_start_scsi,
.abort_isp = qla2x00_abort_isp,
.iospace_config = qla2x00_iospace_config,
};
static struct isp_operations qla24xx_isp_ops = {
@ -1590,6 +1704,7 @@ static struct isp_operations qla24xx_isp_ops = {
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_start_scsi,
.abort_isp = qla2x00_abort_isp,
.iospace_config = qla2x00_iospace_config,
};
static struct isp_operations qla25xx_isp_ops = {
@ -1626,6 +1741,7 @@ static struct isp_operations qla25xx_isp_ops = {
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_dif_start_scsi,
.abort_isp = qla2x00_abort_isp,
.iospace_config = qla2x00_iospace_config,
};
static struct isp_operations qla81xx_isp_ops = {
@ -1662,6 +1778,7 @@ static struct isp_operations qla81xx_isp_ops = {
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_dif_start_scsi,
.abort_isp = qla2x00_abort_isp,
.iospace_config = qla2x00_iospace_config,
};
static struct isp_operations qla82xx_isp_ops = {
@ -1698,6 +1815,7 @@ static struct isp_operations qla82xx_isp_ops = {
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla82xx_start_scsi,
.abort_isp = qla82xx_abort_isp,
.iospace_config = qla82xx_iospace_config,
};
static inline void
@ -1811,117 +1929,6 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha)
ha->device_type, ha->flags.port0, ha->fw_srisc_address);
}
static int
qla2x00_iospace_config(struct qla_hw_data *ha)
{
resource_size_t pio;
uint16_t msix;
int cpus;
if (IS_QLA82XX(ha))
return qla82xx_iospace_config(ha);
if (pci_request_selected_regions(ha->pdev, ha->bars,
QLA2XXX_DRIVER_NAME)) {
ql_log_pci(ql_log_fatal, ha->pdev, 0x0011,
"Failed to reserve PIO/MMIO regions (%s), aborting.\n",
pci_name(ha->pdev));
goto iospace_error_exit;
}
if (!(ha->bars & 1))
goto skip_pio;
/* We only need PIO for Flash operations on ISP2312 v2 chips. */
pio = pci_resource_start(ha->pdev, 0);
if (pci_resource_flags(ha->pdev, 0) & IORESOURCE_IO) {
if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) {
ql_log_pci(ql_log_warn, ha->pdev, 0x0012,
"Invalid pci I/O region size (%s).\n",
pci_name(ha->pdev));
pio = 0;
}
} else {
ql_log_pci(ql_log_warn, ha->pdev, 0x0013,
"Region #0 no a PIO resource (%s).\n",
pci_name(ha->pdev));
pio = 0;
}
ha->pio_address = pio;
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0014,
"PIO address=%llu.\n",
(unsigned long long)ha->pio_address);
skip_pio:
/* Use MMIO operations for all accesses. */
if (!(pci_resource_flags(ha->pdev, 1) & IORESOURCE_MEM)) {
ql_log_pci(ql_log_fatal, ha->pdev, 0x0015,
"Region #1 not an MMIO resource (%s), aborting.\n",
pci_name(ha->pdev));
goto iospace_error_exit;
}
if (pci_resource_len(ha->pdev, 1) < MIN_IOBASE_LEN) {
ql_log_pci(ql_log_fatal, ha->pdev, 0x0016,
"Invalid PCI mem region size (%s), aborting.\n",
pci_name(ha->pdev));
goto iospace_error_exit;
}
ha->iobase = ioremap(pci_resource_start(ha->pdev, 1), MIN_IOBASE_LEN);
if (!ha->iobase) {
ql_log_pci(ql_log_fatal, ha->pdev, 0x0017,
"Cannot remap MMIO (%s), aborting.\n",
pci_name(ha->pdev));
goto iospace_error_exit;
}
/* Determine queue resources */
ha->max_req_queues = ha->max_rsp_queues = 1;
if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) ||
(ql2xmaxqueues > 1 && ql2xmultique_tag) ||
(!IS_QLA25XX(ha) && !IS_QLA81XX(ha)))
goto mqiobase_exit;
ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
pci_resource_len(ha->pdev, 3));
if (ha->mqiobase) {
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0018,
"MQIO Base=%p.\n", ha->mqiobase);
/* Read MSIX vector size of the board */
pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix);
ha->msix_count = msix;
/* Max queues are bounded by available msix vectors */
/* queue 0 uses two msix vectors */
if (ql2xmultique_tag) {
cpus = num_online_cpus();
ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ?
(cpus + 1) : (ha->msix_count - 1);
ha->max_req_queues = 2;
} else if (ql2xmaxqueues > 1) {
ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ?
QLA_MQ_SIZE : ql2xmaxqueues;
ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc008,
"QoS mode set, max no of request queues:%d.\n",
ha->max_req_queues);
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0019,
"QoS mode set, max no of request queues:%d.\n",
ha->max_req_queues);
}
ql_log_pci(ql_log_info, ha->pdev, 0x001a,
"MSI-X vector count: %d.\n", msix);
} else
ql_log_pci(ql_log_info, ha->pdev, 0x001b,
"BAR 3 not enabled.\n");
mqiobase_exit:
ha->msix_count = ha->max_rsp_queues + 1;
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x001c,
"MSIX Count:%d.\n", ha->msix_count);
return (0);
iospace_error_exit:
return (-ENOMEM);
}
static void
qla2xxx_scan_start(struct Scsi_Host *shost)
{
@ -2020,19 +2027,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
pdev->needs_freset = 1;
}
/* Configure PCI I/O space */
ret = qla2x00_iospace_config(ha);
if (ret)
goto probe_hw_failed;
ql_log_pci(ql_log_info, pdev, 0x001d,
"Found an ISP%04X irq %d iobase 0x%p.\n",
pdev->device, pdev->irq, ha->iobase);
ha->prev_topology = 0;
ha->init_cb_size = sizeof(init_cb_t);
ha->link_data_rate = PORT_SPEED_UNKNOWN;
ha->optrom_size = OPTROM_SIZE_2300;
/* Assign ISP specific operations. */
max_id = MAX_TARGETS_2200;
if (IS_QLA2100(ha)) {
@ -2140,6 +2134,20 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
"flash_data_off=%d, nvram_conf_off=%d, nvram_data_off=%d.\n",
ha->isp_ops, ha->flash_conf_off, ha->flash_data_off,
ha->nvram_conf_off, ha->nvram_data_off);
/* Configure PCI I/O space */
ret = ha->isp_ops->iospace_config(ha);
if (ret)
goto probe_hw_failed;
ql_log_pci(ql_log_info, pdev, 0x001d,
"Found an ISP%04X irq %d iobase 0x%p.\n",
pdev->device, pdev->irq, ha->iobase);
ha->prev_topology = 0;
ha->init_cb_size = sizeof(init_cb_t);
ha->link_data_rate = PORT_SPEED_UNKNOWN;
ha->optrom_size = OPTROM_SIZE_2300;
mutex_init(&ha->vport_lock);
init_completion(&ha->mbx_cmd_comp);
complete(&ha->mbx_cmd_comp);