aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
authorAnirban Chakraborty <anirban.chakraborty@qlogic.com>2008-12-18 13:06:15 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-12-29 12:24:35 -0500
commit17d98630a4f2a38537618503ad0c7ec97ba461ca (patch)
tree27deaa971e7b3a95a56a0ba5cf4c92e12853a775 /drivers/scsi/qla2xxx/qla_os.c
parent20c09df7eb9c92a40e0ecf654b6e8f14c8583b9e (diff)
[SCSI] qla2xxx: changes in multiq code
Following changes have been made: 1. Scan outstanding commands only in the queue where it is submitted 2. Update queue registers directly in the fast path 3. Queue specific BAR is remapped only for multiq capable adapters Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c176
1 files changed, 98 insertions, 78 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 9142025db3d..8ea927788b3 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -441,6 +441,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
441 sp->vha = vha; 441 sp->vha = vha;
442 sp->fcport = fcport; 442 sp->fcport = fcport;
443 sp->cmd = cmd; 443 sp->cmd = cmd;
444 sp->que = ha->req_q_map[0];
444 sp->flags = 0; 445 sp->flags = 0;
445 CMD_SP(cmd) = (void *)sp; 446 CMD_SP(cmd) = (void *)sp;
446 cmd->scsi_done = done; 447 cmd->scsi_done = done;
@@ -775,13 +776,14 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
775{ 776{
776 scsi_qla_host_t *vha = shost_priv(cmd->device->host); 777 scsi_qla_host_t *vha = shost_priv(cmd->device->host);
777 srb_t *sp; 778 srb_t *sp;
778 int ret, i, que; 779 int ret, i;
779 unsigned int id, lun; 780 unsigned int id, lun;
780 unsigned long serial; 781 unsigned long serial;
781 unsigned long flags; 782 unsigned long flags;
782 int wait = 0; 783 int wait = 0;
783 struct qla_hw_data *ha = vha->hw; 784 struct qla_hw_data *ha = vha->hw;
784 struct req_que *req; 785 struct req_que *req;
786 srb_t *spt;
785 787
786 qla2x00_block_error_handler(cmd); 788 qla2x00_block_error_handler(cmd);
787 789
@@ -793,37 +795,36 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
793 id = cmd->device->id; 795 id = cmd->device->id;
794 lun = cmd->device->lun; 796 lun = cmd->device->lun;
795 serial = cmd->serial_number; 797 serial = cmd->serial_number;
798 spt = (srb_t *) CMD_SP(cmd);
799 if (!spt)
800 return SUCCESS;
801 req = spt->que;
796 802
797 /* Check active list for command command. */ 803 /* Check active list for command command. */
798 spin_lock_irqsave(&ha->hardware_lock, flags); 804 spin_lock_irqsave(&ha->hardware_lock, flags);
799 for (que = 0; que < QLA_MAX_HOST_QUES; que++) { 805 for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
800 req = ha->req_q_map[vha->req_ques[que]]; 806 sp = req->outstanding_cmds[i];
801 if (!req)
802 continue;
803 for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
804 sp = req->outstanding_cmds[i];
805 807
806 if (sp == NULL) 808 if (sp == NULL)
807 continue; 809 continue;
808 810
809 if (sp->cmd != cmd) 811 if (sp->cmd != cmd)
810 continue; 812 continue;
811 813
812 DEBUG2(printk("%s(%ld): aborting sp %p from RISC." 814 DEBUG2(printk("%s(%ld): aborting sp %p from RISC."
813 " pid=%ld.\n", __func__, vha->host_no, sp, serial)); 815 " pid=%ld.\n", __func__, vha->host_no, sp, serial));
814 816
815 spin_unlock_irqrestore(&ha->hardware_lock, flags); 817 spin_unlock_irqrestore(&ha->hardware_lock, flags);
816 if (ha->isp_ops->abort_command(vha, sp, req)) { 818 if (ha->isp_ops->abort_command(vha, sp, req)) {
817 DEBUG2(printk("%s(%ld): abort_command " 819 DEBUG2(printk("%s(%ld): abort_command "
818 "mbx failed.\n", __func__, vha->host_no)); 820 "mbx failed.\n", __func__, vha->host_no));
819 } else { 821 } else {
820 DEBUG3(printk("%s(%ld): abort_command " 822 DEBUG3(printk("%s(%ld): abort_command "
821 "mbx success.\n", __func__, vha->host_no)); 823 "mbx success.\n", __func__, vha->host_no));
822 wait = 1; 824 wait = 1;
823 }
824 spin_lock_irqsave(&ha->hardware_lock, flags);
825 break;
826 } 825 }
826 spin_lock_irqsave(&ha->hardware_lock, flags);
827 break;
827 } 828 }
828 spin_unlock_irqrestore(&ha->hardware_lock, flags); 829 spin_unlock_irqrestore(&ha->hardware_lock, flags);
829 830
@@ -852,48 +853,46 @@ enum nexus_wait_type {
852 853
853static int 854static int
854qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, 855qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
855 unsigned int l, enum nexus_wait_type type) 856 unsigned int l, srb_t *sp, enum nexus_wait_type type)
856{ 857{
857 int cnt, match, status, que; 858 int cnt, match, status;
858 srb_t *sp;
859 unsigned long flags; 859 unsigned long flags;
860 struct qla_hw_data *ha = vha->hw; 860 struct qla_hw_data *ha = vha->hw;
861 struct req_que *req; 861 struct req_que *req;
862 862
863 status = QLA_SUCCESS; 863 status = QLA_SUCCESS;
864 if (!sp)
865 return status;
866
864 spin_lock_irqsave(&ha->hardware_lock, flags); 867 spin_lock_irqsave(&ha->hardware_lock, flags);
865 for (que = 0; que < QLA_MAX_HOST_QUES; que++) { 868 req = sp->que;
866 req = ha->req_q_map[vha->req_ques[que]]; 869 for (cnt = 1; status == QLA_SUCCESS &&
867 if (!req) 870 cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
871 sp = req->outstanding_cmds[cnt];
872 if (!sp)
868 continue; 873 continue;
869 for (cnt = 1; status == QLA_SUCCESS &&
870 cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
871 sp = req->outstanding_cmds[cnt];
872 if (!sp)
873 continue;
874
875 if (vha->vp_idx != sp->fcport->vha->vp_idx)
876 continue;
877 match = 0;
878 switch (type) {
879 case WAIT_HOST:
880 match = 1;
881 break;
882 case WAIT_TARGET:
883 match = sp->cmd->device->id == t;
884 break;
885 case WAIT_LUN:
886 match = (sp->cmd->device->id == t &&
887 sp->cmd->device->lun == l);
888 break;
889 }
890 if (!match)
891 continue;
892 874
893 spin_unlock_irqrestore(&ha->hardware_lock, flags); 875 if (vha->vp_idx != sp->fcport->vha->vp_idx)
894 status = qla2x00_eh_wait_on_command(sp->cmd); 876 continue;
895 spin_lock_irqsave(&ha->hardware_lock, flags); 877 match = 0;
878 switch (type) {
879 case WAIT_HOST:
880 match = 1;
881 break;
882 case WAIT_TARGET:
883 match = sp->cmd->device->id == t;
884 break;
885 case WAIT_LUN:
886 match = (sp->cmd->device->id == t &&
887 sp->cmd->device->lun == l);
888 break;
896 } 889 }
890 if (!match)
891 continue;
892
893 spin_unlock_irqrestore(&ha->hardware_lock, flags);
894 status = qla2x00_eh_wait_on_command(sp->cmd);
895 spin_lock_irqsave(&ha->hardware_lock, flags);
897 } 896 }
898 spin_unlock_irqrestore(&ha->hardware_lock, flags); 897 spin_unlock_irqrestore(&ha->hardware_lock, flags);
899 898
@@ -934,7 +933,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
934 goto eh_reset_failed; 933 goto eh_reset_failed;
935 err = 3; 934 err = 3;
936 if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id, 935 if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id,
937 cmd->device->lun, type) != QLA_SUCCESS) 936 cmd->device->lun, (srb_t *) CMD_SP(cmd), type) != QLA_SUCCESS)
938 goto eh_reset_failed; 937 goto eh_reset_failed;
939 938
940 qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n", 939 qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n",
@@ -992,6 +991,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
992 int ret = FAILED; 991 int ret = FAILED;
993 unsigned int id, lun; 992 unsigned int id, lun;
994 unsigned long serial; 993 unsigned long serial;
994 srb_t *sp = (srb_t *) CMD_SP(cmd);
995 995
996 qla2x00_block_error_handler(cmd); 996 qla2x00_block_error_handler(cmd);
997 997
@@ -1018,7 +1018,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
1018 goto eh_bus_reset_done; 1018 goto eh_bus_reset_done;
1019 1019
1020 /* Flush outstanding commands. */ 1020 /* Flush outstanding commands. */
1021 if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) != 1021 if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, sp, WAIT_HOST) !=
1022 QLA_SUCCESS) 1022 QLA_SUCCESS)
1023 ret = FAILED; 1023 ret = FAILED;
1024 1024
@@ -1053,6 +1053,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
1053 int ret = FAILED; 1053 int ret = FAILED;
1054 unsigned int id, lun; 1054 unsigned int id, lun;
1055 unsigned long serial; 1055 unsigned long serial;
1056 srb_t *sp = (srb_t *) CMD_SP(cmd);
1056 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 1057 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
1057 1058
1058 qla2x00_block_error_handler(cmd); 1059 qla2x00_block_error_handler(cmd);
@@ -1096,7 +1097,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
1096 } 1097 }
1097 1098
1098 /* Waiting for command to be returned to OS.*/ 1099 /* Waiting for command to be returned to OS.*/
1099 if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) == 1100 if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, sp, WAIT_HOST) ==
1100 QLA_SUCCESS) 1101 QLA_SUCCESS)
1101 ret = SUCCESS; 1102 ret = SUCCESS;
1102 1103
@@ -1368,6 +1369,9 @@ static struct isp_operations qla2100_isp_ops = {
1368 .write_optrom = qla2x00_write_optrom_data, 1369 .write_optrom = qla2x00_write_optrom_data,
1369 .get_flash_version = qla2x00_get_flash_version, 1370 .get_flash_version = qla2x00_get_flash_version,
1370 .start_scsi = qla2x00_start_scsi, 1371 .start_scsi = qla2x00_start_scsi,
1372 .wrt_req_reg = NULL,
1373 .wrt_rsp_reg = NULL,
1374 .rd_req_reg = NULL,
1371}; 1375};
1372 1376
1373static struct isp_operations qla2300_isp_ops = { 1377static struct isp_operations qla2300_isp_ops = {
@@ -1403,6 +1407,9 @@ static struct isp_operations qla2300_isp_ops = {
1403 .write_optrom = qla2x00_write_optrom_data, 1407 .write_optrom = qla2x00_write_optrom_data,
1404 .get_flash_version = qla2x00_get_flash_version, 1408 .get_flash_version = qla2x00_get_flash_version,
1405 .start_scsi = qla2x00_start_scsi, 1409 .start_scsi = qla2x00_start_scsi,
1410 .wrt_req_reg = NULL,
1411 .wrt_rsp_reg = NULL,
1412 .rd_req_reg = NULL,
1406}; 1413};
1407 1414
1408static struct isp_operations qla24xx_isp_ops = { 1415static struct isp_operations qla24xx_isp_ops = {
@@ -1438,6 +1445,9 @@ static struct isp_operations qla24xx_isp_ops = {
1438 .write_optrom = qla24xx_write_optrom_data, 1445 .write_optrom = qla24xx_write_optrom_data,
1439 .get_flash_version = qla24xx_get_flash_version, 1446 .get_flash_version = qla24xx_get_flash_version,
1440 .start_scsi = qla24xx_start_scsi, 1447 .start_scsi = qla24xx_start_scsi,
1448 .wrt_req_reg = qla24xx_wrt_req_reg,
1449 .wrt_rsp_reg = qla24xx_wrt_rsp_reg,
1450 .rd_req_reg = qla24xx_rd_req_reg,
1441}; 1451};
1442 1452
1443static struct isp_operations qla25xx_isp_ops = { 1453static struct isp_operations qla25xx_isp_ops = {
@@ -1473,6 +1483,9 @@ static struct isp_operations qla25xx_isp_ops = {
1473 .write_optrom = qla24xx_write_optrom_data, 1483 .write_optrom = qla24xx_write_optrom_data,
1474 .get_flash_version = qla24xx_get_flash_version, 1484 .get_flash_version = qla24xx_get_flash_version,
1475 .start_scsi = qla24xx_start_scsi, 1485 .start_scsi = qla24xx_start_scsi,
1486 .wrt_req_reg = qla24xx_wrt_req_reg,
1487 .wrt_rsp_reg = qla24xx_wrt_rsp_reg,
1488 .rd_req_reg = qla24xx_rd_req_reg,
1476}; 1489};
1477 1490
1478static inline void 1491static inline void
@@ -1616,26 +1629,27 @@ skip_pio:
1616 1629
1617 /* Determine queue resources */ 1630 /* Determine queue resources */
1618 ha->max_queues = 1; 1631 ha->max_queues = 1;
1619 if (ql2xmaxqueues > 1) { 1632 if (ql2xmaxqueues <= 1 || !IS_QLA25XX(ha))
1620 ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3), 1633 goto mqiobase_exit;
1621 pci_resource_len(ha->pdev, 3)); 1634 ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
1622 if (ha->mqiobase) { 1635 pci_resource_len(ha->pdev, 3));
1623 /* Read MSIX vector size of the board */ 1636 if (ha->mqiobase) {
1624 pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, 1637 /* Read MSIX vector size of the board */
1625 &msix); 1638 pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix);
1626 ha->msix_count = msix; 1639 ha->msix_count = msix;
1627 /* Max queues are bounded by available msix vectors */ 1640 /* Max queues are bounded by available msix vectors */
1628 /* queue 0 uses two msix vectors */ 1641 /* queue 0 uses two msix vectors */
1629 if (ha->msix_count - 1 < ql2xmaxqueues) 1642 if (ha->msix_count - 1 < ql2xmaxqueues)
1630 ha->max_queues = ha->msix_count - 1; 1643 ha->max_queues = ha->msix_count - 1;
1631 else if (ql2xmaxqueues > QLA_MQ_SIZE) 1644 else if (ql2xmaxqueues > QLA_MQ_SIZE)
1632 ha->max_queues = QLA_MQ_SIZE; 1645 ha->max_queues = QLA_MQ_SIZE;
1633 else 1646 else
1634 ha->max_queues = ql2xmaxqueues; 1647 ha->max_queues = ql2xmaxqueues;
1635 qla_printk(KERN_INFO, ha, 1648 qla_printk(KERN_INFO, ha,
1636 "MSI-X vector count: %d\n", msix); 1649 "MSI-X vector count: %d\n", msix);
1637 }
1638 } 1650 }
1651
1652mqiobase_exit:
1639 ha->msix_count = ha->max_queues + 1; 1653 ha->msix_count = ha->max_queues + 1;
1640 return (0); 1654 return (0);
1641 1655
@@ -1852,6 +1866,12 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1852 ha->rsp_q_map[0] = rsp; 1866 ha->rsp_q_map[0] = rsp;
1853 ha->req_q_map[0] = req; 1867 ha->req_q_map[0] = req;
1854 1868
1869 if (ha->mqenable) {
1870 ha->isp_ops->wrt_req_reg = qla25xx_wrt_req_reg;
1871 ha->isp_ops->wrt_rsp_reg = qla25xx_wrt_rsp_reg;
1872 ha->isp_ops->rd_req_reg = qla25xx_rd_req_reg;
1873 }
1874
1855 if (qla2x00_initialize_adapter(base_vha)) { 1875 if (qla2x00_initialize_adapter(base_vha)) {
1856 qla_printk(KERN_WARNING, ha, 1876 qla_printk(KERN_WARNING, ha,
1857 "Failed to initialize adapter\n"); 1877 "Failed to initialize adapter\n");