diff options
author | Anirban Chakraborty <anirban.chakraborty@qlogic.com> | 2009-04-07 01:33:40 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-05-20 18:21:07 -0400 |
commit | 2afa19a9377ca61b9489e44bf50029574fbe63be (patch) | |
tree | cdfa3878eb04d833bbcd9ce92196bc4456b5ccf5 /drivers/scsi/qla2xxx/qla_isr.c | |
parent | 7640335ea5b1a2da0d64303e6003012c619ae01a (diff) |
[SCSI] qla2xxx: Add QoS support.
Set the number of request queues to the module paramater
ql2xmaxqueues. Each vport gets a request queue. The QoS value
set to the request queues determines priority control for queued
IOs. If QoS value is not specified, the vports use the default
queue 0.
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 242 |
1 files changed, 94 insertions, 148 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index d04981848e56..c8e906c702a1 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -13,10 +13,9 @@ static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); | |||
13 | static void qla2x00_process_completed_request(struct scsi_qla_host *, | 13 | static void qla2x00_process_completed_request(struct scsi_qla_host *, |
14 | struct req_que *, uint32_t); | 14 | struct req_que *, uint32_t); |
15 | static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *); | 15 | static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *); |
16 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); | 16 | static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *); |
17 | static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *, | 17 | static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *, |
18 | sts_entry_t *); | 18 | sts_entry_t *); |
19 | static struct scsi_qla_host *qla2x00_get_rsp_host(struct rsp_que *); | ||
20 | 19 | ||
21 | /** | 20 | /** |
22 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. | 21 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. |
@@ -51,7 +50,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
51 | status = 0; | 50 | status = 0; |
52 | 51 | ||
53 | spin_lock(&ha->hardware_lock); | 52 | spin_lock(&ha->hardware_lock); |
54 | vha = qla2x00_get_rsp_host(rsp); | 53 | vha = pci_get_drvdata(ha->pdev); |
55 | for (iter = 50; iter--; ) { | 54 | for (iter = 50; iter--; ) { |
56 | hccr = RD_REG_WORD(®->hccr); | 55 | hccr = RD_REG_WORD(®->hccr); |
57 | if (hccr & HCCR_RISC_PAUSE) { | 56 | if (hccr & HCCR_RISC_PAUSE) { |
@@ -147,7 +146,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
147 | status = 0; | 146 | status = 0; |
148 | 147 | ||
149 | spin_lock(&ha->hardware_lock); | 148 | spin_lock(&ha->hardware_lock); |
150 | vha = qla2x00_get_rsp_host(rsp); | 149 | vha = pci_get_drvdata(ha->pdev); |
151 | for (iter = 50; iter--; ) { | 150 | for (iter = 50; iter--; ) { |
152 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 151 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
153 | if (stat & HSR_RISC_PAUSED) { | 152 | if (stat & HSR_RISC_PAUSED) { |
@@ -685,7 +684,7 @@ skip_rio: | |||
685 | vha->host_no)); | 684 | vha->host_no)); |
686 | 685 | ||
687 | if (IS_FWI2_CAPABLE(ha)) | 686 | if (IS_FWI2_CAPABLE(ha)) |
688 | qla24xx_process_response_queue(rsp); | 687 | qla24xx_process_response_queue(vha, rsp); |
689 | else | 688 | else |
690 | qla2x00_process_response_queue(rsp); | 689 | qla2x00_process_response_queue(rsp); |
691 | break; | 690 | break; |
@@ -766,7 +765,7 @@ qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data) | |||
766 | struct qla_hw_data *ha = vha->hw; | 765 | struct qla_hw_data *ha = vha->hw; |
767 | struct req_que *req = NULL; | 766 | struct req_que *req = NULL; |
768 | 767 | ||
769 | req = ha->req_q_map[vha->req_ques[0]]; | 768 | req = vha->req; |
770 | if (!req) | 769 | if (!req) |
771 | return; | 770 | return; |
772 | if (req->max_q_depth <= sdev->queue_depth) | 771 | if (req->max_q_depth <= sdev->queue_depth) |
@@ -858,8 +857,8 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha, | |||
858 | qla2x00_ramp_up_queue_depth(vha, req, sp); | 857 | qla2x00_ramp_up_queue_depth(vha, req, sp); |
859 | qla2x00_sp_compl(ha, sp); | 858 | qla2x00_sp_compl(ha, sp); |
860 | } else { | 859 | } else { |
861 | DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n", | 860 | DEBUG2(printk("scsi(%ld) Req:%d: Invalid ISP SCSI completion" |
862 | vha->host_no)); | 861 | " handle(%d)\n", vha->host_no, req->id, index)); |
863 | qla_printk(KERN_WARNING, ha, | 862 | qla_printk(KERN_WARNING, ha, |
864 | "Invalid ISP SCSI completion handle\n"); | 863 | "Invalid ISP SCSI completion handle\n"); |
865 | 864 | ||
@@ -881,7 +880,7 @@ qla2x00_process_response_queue(struct rsp_que *rsp) | |||
881 | uint16_t handle_cnt; | 880 | uint16_t handle_cnt; |
882 | uint16_t cnt; | 881 | uint16_t cnt; |
883 | 882 | ||
884 | vha = qla2x00_get_rsp_host(rsp); | 883 | vha = pci_get_drvdata(ha->pdev); |
885 | 884 | ||
886 | if (!vha->flags.online) | 885 | if (!vha->flags.online) |
887 | return; | 886 | return; |
@@ -926,7 +925,7 @@ qla2x00_process_response_queue(struct rsp_que *rsp) | |||
926 | } | 925 | } |
927 | break; | 926 | break; |
928 | case STATUS_CONT_TYPE: | 927 | case STATUS_CONT_TYPE: |
929 | qla2x00_status_cont_entry(vha, (sts_cont_entry_t *)pkt); | 928 | qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt); |
930 | break; | 929 | break; |
931 | default: | 930 | default: |
932 | /* Type Not Supported. */ | 931 | /* Type Not Supported. */ |
@@ -945,7 +944,8 @@ qla2x00_process_response_queue(struct rsp_que *rsp) | |||
945 | } | 944 | } |
946 | 945 | ||
947 | static inline void | 946 | static inline void |
948 | qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len) | 947 | qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len, |
948 | struct rsp_que *rsp) | ||
949 | { | 949 | { |
950 | struct scsi_cmnd *cp = sp->cmd; | 950 | struct scsi_cmnd *cp = sp->cmd; |
951 | 951 | ||
@@ -962,7 +962,7 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len) | |||
962 | sp->request_sense_ptr += sense_len; | 962 | sp->request_sense_ptr += sense_len; |
963 | sp->request_sense_length -= sense_len; | 963 | sp->request_sense_length -= sense_len; |
964 | if (sp->request_sense_length != 0) | 964 | if (sp->request_sense_length != 0) |
965 | sp->fcport->vha->status_srb = sp; | 965 | rsp->status_srb = sp; |
966 | 966 | ||
967 | DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) " | 967 | DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) " |
968 | "cmd=%p pid=%ld\n", __func__, sp->fcport->vha->host_no, | 968 | "cmd=%p pid=%ld\n", __func__, sp->fcport->vha->host_no, |
@@ -992,7 +992,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
992 | uint32_t sense_len, rsp_info_len, resid_len, fw_resid_len; | 992 | uint32_t sense_len, rsp_info_len, resid_len, fw_resid_len; |
993 | uint8_t *rsp_info, *sense_data; | 993 | uint8_t *rsp_info, *sense_data; |
994 | struct qla_hw_data *ha = vha->hw; | 994 | struct qla_hw_data *ha = vha->hw; |
995 | struct req_que *req = rsp->req; | 995 | uint32_t handle; |
996 | uint16_t que; | ||
997 | struct req_que *req; | ||
996 | 998 | ||
997 | sts = (sts_entry_t *) pkt; | 999 | sts = (sts_entry_t *) pkt; |
998 | sts24 = (struct sts_entry_24xx *) pkt; | 1000 | sts24 = (struct sts_entry_24xx *) pkt; |
@@ -1003,18 +1005,20 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1003 | comp_status = le16_to_cpu(sts->comp_status); | 1005 | comp_status = le16_to_cpu(sts->comp_status); |
1004 | scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK; | 1006 | scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK; |
1005 | } | 1007 | } |
1006 | 1008 | handle = (uint32_t) LSW(sts->handle); | |
1009 | que = MSW(sts->handle); | ||
1010 | req = ha->req_q_map[que]; | ||
1007 | /* Fast path completion. */ | 1011 | /* Fast path completion. */ |
1008 | if (comp_status == CS_COMPLETE && scsi_status == 0) { | 1012 | if (comp_status == CS_COMPLETE && scsi_status == 0) { |
1009 | qla2x00_process_completed_request(vha, req, sts->handle); | 1013 | qla2x00_process_completed_request(vha, req, handle); |
1010 | 1014 | ||
1011 | return; | 1015 | return; |
1012 | } | 1016 | } |
1013 | 1017 | ||
1014 | /* Validate handle. */ | 1018 | /* Validate handle. */ |
1015 | if (sts->handle < MAX_OUTSTANDING_COMMANDS) { | 1019 | if (handle < MAX_OUTSTANDING_COMMANDS) { |
1016 | sp = req->outstanding_cmds[sts->handle]; | 1020 | sp = req->outstanding_cmds[handle]; |
1017 | req->outstanding_cmds[sts->handle] = NULL; | 1021 | req->outstanding_cmds[handle] = NULL; |
1018 | } else | 1022 | } else |
1019 | sp = NULL; | 1023 | sp = NULL; |
1020 | 1024 | ||
@@ -1030,7 +1034,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1030 | cp = sp->cmd; | 1034 | cp = sp->cmd; |
1031 | if (cp == NULL) { | 1035 | if (cp == NULL) { |
1032 | DEBUG2(printk("scsi(%ld): Command already returned back to OS " | 1036 | DEBUG2(printk("scsi(%ld): Command already returned back to OS " |
1033 | "pkt->handle=%d sp=%p.\n", vha->host_no, sts->handle, sp)); | 1037 | "pkt->handle=%d sp=%p.\n", vha->host_no, handle, sp)); |
1034 | qla_printk(KERN_WARNING, ha, | 1038 | qla_printk(KERN_WARNING, ha, |
1035 | "Command is NULL: already returned to OS (sp=%p)\n", sp); | 1039 | "Command is NULL: already returned to OS (sp=%p)\n", sp); |
1036 | 1040 | ||
@@ -1133,7 +1137,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1133 | if (!(scsi_status & SS_SENSE_LEN_VALID)) | 1137 | if (!(scsi_status & SS_SENSE_LEN_VALID)) |
1134 | break; | 1138 | break; |
1135 | 1139 | ||
1136 | qla2x00_handle_sense(sp, sense_data, sense_len); | 1140 | qla2x00_handle_sense(sp, sense_data, sense_len, rsp); |
1137 | break; | 1141 | break; |
1138 | 1142 | ||
1139 | case CS_DATA_UNDERRUN: | 1143 | case CS_DATA_UNDERRUN: |
@@ -1192,7 +1196,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1192 | if (!(scsi_status & SS_SENSE_LEN_VALID)) | 1196 | if (!(scsi_status & SS_SENSE_LEN_VALID)) |
1193 | break; | 1197 | break; |
1194 | 1198 | ||
1195 | qla2x00_handle_sense(sp, sense_data, sense_len); | 1199 | qla2x00_handle_sense(sp, sense_data, sense_len, rsp); |
1196 | } else { | 1200 | } else { |
1197 | /* | 1201 | /* |
1198 | * If RISC reports underrun and target does not report | 1202 | * If RISC reports underrun and target does not report |
@@ -1334,7 +1338,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1334 | } | 1338 | } |
1335 | 1339 | ||
1336 | /* Place command on done queue. */ | 1340 | /* Place command on done queue. */ |
1337 | if (vha->status_srb == NULL) | 1341 | if (rsp->status_srb == NULL) |
1338 | qla2x00_sp_compl(ha, sp); | 1342 | qla2x00_sp_compl(ha, sp); |
1339 | } | 1343 | } |
1340 | 1344 | ||
@@ -1346,11 +1350,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1346 | * Extended sense data. | 1350 | * Extended sense data. |
1347 | */ | 1351 | */ |
1348 | static void | 1352 | static void |
1349 | qla2x00_status_cont_entry(scsi_qla_host_t *vha, sts_cont_entry_t *pkt) | 1353 | qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) |
1350 | { | 1354 | { |
1351 | uint8_t sense_sz = 0; | 1355 | uint8_t sense_sz = 0; |
1352 | struct qla_hw_data *ha = vha->hw; | 1356 | struct qla_hw_data *ha = rsp->hw; |
1353 | srb_t *sp = vha->status_srb; | 1357 | srb_t *sp = rsp->status_srb; |
1354 | struct scsi_cmnd *cp; | 1358 | struct scsi_cmnd *cp; |
1355 | 1359 | ||
1356 | if (sp != NULL && sp->request_sense_length != 0) { | 1360 | if (sp != NULL && sp->request_sense_length != 0) { |
@@ -1362,7 +1366,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *vha, sts_cont_entry_t *pkt) | |||
1362 | "cmd is NULL: already returned to OS (sp=%p)\n", | 1366 | "cmd is NULL: already returned to OS (sp=%p)\n", |
1363 | sp); | 1367 | sp); |
1364 | 1368 | ||
1365 | vha->status_srb = NULL; | 1369 | rsp->status_srb = NULL; |
1366 | return; | 1370 | return; |
1367 | } | 1371 | } |
1368 | 1372 | ||
@@ -1383,7 +1387,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *vha, sts_cont_entry_t *pkt) | |||
1383 | 1387 | ||
1384 | /* Place command on done queue. */ | 1388 | /* Place command on done queue. */ |
1385 | if (sp->request_sense_length == 0) { | 1389 | if (sp->request_sense_length == 0) { |
1386 | vha->status_srb = NULL; | 1390 | rsp->status_srb = NULL; |
1387 | qla2x00_sp_compl(ha, sp); | 1391 | qla2x00_sp_compl(ha, sp); |
1388 | } | 1392 | } |
1389 | } | 1393 | } |
@@ -1399,7 +1403,9 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt) | |||
1399 | { | 1403 | { |
1400 | srb_t *sp; | 1404 | srb_t *sp; |
1401 | struct qla_hw_data *ha = vha->hw; | 1405 | struct qla_hw_data *ha = vha->hw; |
1402 | struct req_que *req = rsp->req; | 1406 | uint32_t handle = LSW(pkt->handle); |
1407 | uint16_t que = MSW(pkt->handle); | ||
1408 | struct req_que *req = ha->req_q_map[que]; | ||
1403 | #if defined(QL_DEBUG_LEVEL_2) | 1409 | #if defined(QL_DEBUG_LEVEL_2) |
1404 | if (pkt->entry_status & RF_INV_E_ORDER) | 1410 | if (pkt->entry_status & RF_INV_E_ORDER) |
1405 | qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__); | 1411 | qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__); |
@@ -1417,14 +1423,14 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt) | |||
1417 | #endif | 1423 | #endif |
1418 | 1424 | ||
1419 | /* Validate handle. */ | 1425 | /* Validate handle. */ |
1420 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) | 1426 | if (handle < MAX_OUTSTANDING_COMMANDS) |
1421 | sp = req->outstanding_cmds[pkt->handle]; | 1427 | sp = req->outstanding_cmds[handle]; |
1422 | else | 1428 | else |
1423 | sp = NULL; | 1429 | sp = NULL; |
1424 | 1430 | ||
1425 | if (sp) { | 1431 | if (sp) { |
1426 | /* Free outstanding command slot. */ | 1432 | /* Free outstanding command slot. */ |
1427 | req->outstanding_cmds[pkt->handle] = NULL; | 1433 | req->outstanding_cmds[handle] = NULL; |
1428 | 1434 | ||
1429 | /* Bad payload or header */ | 1435 | /* Bad payload or header */ |
1430 | if (pkt->entry_status & | 1436 | if (pkt->entry_status & |
@@ -1486,13 +1492,10 @@ qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) | |||
1486 | * qla24xx_process_response_queue() - Process response queue entries. | 1492 | * qla24xx_process_response_queue() - Process response queue entries. |
1487 | * @ha: SCSI driver HA context | 1493 | * @ha: SCSI driver HA context |
1488 | */ | 1494 | */ |
1489 | void | 1495 | void qla24xx_process_response_queue(struct scsi_qla_host *vha, |
1490 | qla24xx_process_response_queue(struct rsp_que *rsp) | 1496 | struct rsp_que *rsp) |
1491 | { | 1497 | { |
1492 | struct sts_entry_24xx *pkt; | 1498 | struct sts_entry_24xx *pkt; |
1493 | struct scsi_qla_host *vha; | ||
1494 | |||
1495 | vha = qla2x00_get_rsp_host(rsp); | ||
1496 | 1499 | ||
1497 | if (!vha->flags.online) | 1500 | if (!vha->flags.online) |
1498 | return; | 1501 | return; |
@@ -1523,7 +1526,7 @@ qla24xx_process_response_queue(struct rsp_que *rsp) | |||
1523 | qla2x00_status_entry(vha, rsp, pkt); | 1526 | qla2x00_status_entry(vha, rsp, pkt); |
1524 | break; | 1527 | break; |
1525 | case STATUS_CONT_TYPE: | 1528 | case STATUS_CONT_TYPE: |
1526 | qla2x00_status_cont_entry(vha, (sts_cont_entry_t *)pkt); | 1529 | qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt); |
1527 | break; | 1530 | break; |
1528 | case VP_RPT_ID_IOCB_TYPE: | 1531 | case VP_RPT_ID_IOCB_TYPE: |
1529 | qla24xx_report_id_acquisition(vha, | 1532 | qla24xx_report_id_acquisition(vha, |
@@ -1626,7 +1629,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1626 | status = 0; | 1629 | status = 0; |
1627 | 1630 | ||
1628 | spin_lock(&ha->hardware_lock); | 1631 | spin_lock(&ha->hardware_lock); |
1629 | vha = qla2x00_get_rsp_host(rsp); | 1632 | vha = pci_get_drvdata(ha->pdev); |
1630 | for (iter = 50; iter--; ) { | 1633 | for (iter = 50; iter--; ) { |
1631 | stat = RD_REG_DWORD(®->host_status); | 1634 | stat = RD_REG_DWORD(®->host_status); |
1632 | if (stat & HSRX_RISC_PAUSED) { | 1635 | if (stat & HSRX_RISC_PAUSED) { |
@@ -1664,7 +1667,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1664 | break; | 1667 | break; |
1665 | case 0x13: | 1668 | case 0x13: |
1666 | case 0x14: | 1669 | case 0x14: |
1667 | qla24xx_process_response_queue(rsp); | 1670 | qla24xx_process_response_queue(vha, rsp); |
1668 | break; | 1671 | break; |
1669 | default: | 1672 | default: |
1670 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " | 1673 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " |
@@ -1692,6 +1695,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1692 | struct qla_hw_data *ha; | 1695 | struct qla_hw_data *ha; |
1693 | struct rsp_que *rsp; | 1696 | struct rsp_que *rsp; |
1694 | struct device_reg_24xx __iomem *reg; | 1697 | struct device_reg_24xx __iomem *reg; |
1698 | struct scsi_qla_host *vha; | ||
1695 | 1699 | ||
1696 | rsp = (struct rsp_que *) dev_id; | 1700 | rsp = (struct rsp_que *) dev_id; |
1697 | if (!rsp) { | 1701 | if (!rsp) { |
@@ -1704,7 +1708,8 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1704 | 1708 | ||
1705 | spin_lock_irq(&ha->hardware_lock); | 1709 | spin_lock_irq(&ha->hardware_lock); |
1706 | 1710 | ||
1707 | qla24xx_process_response_queue(rsp); | 1711 | vha = qla25xx_get_host(rsp); |
1712 | qla24xx_process_response_queue(vha, rsp); | ||
1708 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1713 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1709 | 1714 | ||
1710 | spin_unlock_irq(&ha->hardware_lock); | 1715 | spin_unlock_irq(&ha->hardware_lock); |
@@ -1713,31 +1718,6 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1713 | } | 1718 | } |
1714 | 1719 | ||
1715 | static irqreturn_t | 1720 | static irqreturn_t |
1716 | qla25xx_msix_rsp_q(int irq, void *dev_id) | ||
1717 | { | ||
1718 | struct qla_hw_data *ha; | ||
1719 | struct rsp_que *rsp; | ||
1720 | struct device_reg_24xx __iomem *reg; | ||
1721 | |||
1722 | rsp = (struct rsp_que *) dev_id; | ||
1723 | if (!rsp) { | ||
1724 | printk(KERN_INFO | ||
1725 | "%s(): NULL response queue pointer\n", __func__); | ||
1726 | return IRQ_NONE; | ||
1727 | } | ||
1728 | ha = rsp->hw; | ||
1729 | reg = &ha->iobase->isp24; | ||
1730 | |||
1731 | spin_lock_irq(&ha->hardware_lock); | ||
1732 | |||
1733 | qla24xx_process_response_queue(rsp); | ||
1734 | |||
1735 | spin_unlock_irq(&ha->hardware_lock); | ||
1736 | |||
1737 | return IRQ_HANDLED; | ||
1738 | } | ||
1739 | |||
1740 | static irqreturn_t | ||
1741 | qla24xx_msix_default(int irq, void *dev_id) | 1721 | qla24xx_msix_default(int irq, void *dev_id) |
1742 | { | 1722 | { |
1743 | scsi_qla_host_t *vha; | 1723 | scsi_qla_host_t *vha; |
@@ -1760,7 +1740,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1760 | status = 0; | 1740 | status = 0; |
1761 | 1741 | ||
1762 | spin_lock_irq(&ha->hardware_lock); | 1742 | spin_lock_irq(&ha->hardware_lock); |
1763 | vha = qla2x00_get_rsp_host(rsp); | 1743 | vha = pci_get_drvdata(ha->pdev); |
1764 | do { | 1744 | do { |
1765 | stat = RD_REG_DWORD(®->host_status); | 1745 | stat = RD_REG_DWORD(®->host_status); |
1766 | if (stat & HSRX_RISC_PAUSED) { | 1746 | if (stat & HSRX_RISC_PAUSED) { |
@@ -1798,7 +1778,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1798 | break; | 1778 | break; |
1799 | case 0x13: | 1779 | case 0x13: |
1800 | case 0x14: | 1780 | case 0x14: |
1801 | qla24xx_process_response_queue(rsp); | 1781 | qla24xx_process_response_queue(vha, rsp); |
1802 | break; | 1782 | break; |
1803 | default: | 1783 | default: |
1804 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " | 1784 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " |
@@ -1822,31 +1802,13 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1822 | /* Interrupt handling helpers. */ | 1802 | /* Interrupt handling helpers. */ |
1823 | 1803 | ||
1824 | struct qla_init_msix_entry { | 1804 | struct qla_init_msix_entry { |
1825 | uint16_t entry; | ||
1826 | uint16_t index; | ||
1827 | const char *name; | 1805 | const char *name; |
1828 | irq_handler_t handler; | 1806 | irq_handler_t handler; |
1829 | }; | 1807 | }; |
1830 | 1808 | ||
1831 | static struct qla_init_msix_entry base_queue = { | 1809 | static struct qla_init_msix_entry msix_entries[2] = { |
1832 | .entry = 0, | 1810 | { "qla2xxx (default)", qla24xx_msix_default }, |
1833 | .index = 0, | 1811 | { "qla2xxx (rsp_q)", qla24xx_msix_rsp_q }, |
1834 | .name = "qla2xxx (default)", | ||
1835 | .handler = qla24xx_msix_default, | ||
1836 | }; | ||
1837 | |||
1838 | static struct qla_init_msix_entry base_rsp_queue = { | ||
1839 | .entry = 1, | ||
1840 | .index = 1, | ||
1841 | .name = "qla2xxx (rsp_q)", | ||
1842 | .handler = qla24xx_msix_rsp_q, | ||
1843 | }; | ||
1844 | |||
1845 | static struct qla_init_msix_entry multi_rsp_queue = { | ||
1846 | .entry = 1, | ||
1847 | .index = 1, | ||
1848 | .name = "qla2xxx (multi_q)", | ||
1849 | .handler = qla25xx_msix_rsp_q, | ||
1850 | }; | 1812 | }; |
1851 | 1813 | ||
1852 | static void | 1814 | static void |
@@ -1873,7 +1835,6 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) | |||
1873 | int i, ret; | 1835 | int i, ret; |
1874 | struct msix_entry *entries; | 1836 | struct msix_entry *entries; |
1875 | struct qla_msix_entry *qentry; | 1837 | struct qla_msix_entry *qentry; |
1876 | struct qla_init_msix_entry *msix_queue; | ||
1877 | 1838 | ||
1878 | entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count, | 1839 | entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count, |
1879 | GFP_KERNEL); | 1840 | GFP_KERNEL); |
@@ -1900,7 +1861,7 @@ msix_failed: | |||
1900 | ha->msix_count, ret); | 1861 | ha->msix_count, ret); |
1901 | goto msix_out; | 1862 | goto msix_out; |
1902 | } | 1863 | } |
1903 | ha->max_queues = ha->msix_count - 1; | 1864 | ha->max_rsp_queues = ha->msix_count - 1; |
1904 | } | 1865 | } |
1905 | ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) * | 1866 | ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) * |
1906 | ha->msix_count, GFP_KERNEL); | 1867 | ha->msix_count, GFP_KERNEL); |
@@ -1918,45 +1879,27 @@ msix_failed: | |||
1918 | qentry->rsp = NULL; | 1879 | qentry->rsp = NULL; |
1919 | } | 1880 | } |
1920 | 1881 | ||
1921 | /* Enable MSI-X for AENs for queue 0 */ | 1882 | /* Enable MSI-X vectors for the base queue */ |
1922 | qentry = &ha->msix_entries[0]; | 1883 | for (i = 0; i < 2; i++) { |
1923 | ret = request_irq(qentry->vector, base_queue.handler, 0, | 1884 | qentry = &ha->msix_entries[i]; |
1924 | base_queue.name, rsp); | 1885 | ret = request_irq(qentry->vector, msix_entries[i].handler, |
1925 | if (ret) { | 1886 | 0, msix_entries[i].name, rsp); |
1926 | qla_printk(KERN_WARNING, ha, | 1887 | if (ret) { |
1888 | qla_printk(KERN_WARNING, ha, | ||
1927 | "MSI-X: Unable to register handler -- %x/%d.\n", | 1889 | "MSI-X: Unable to register handler -- %x/%d.\n", |
1928 | qentry->vector, ret); | 1890 | qentry->vector, ret); |
1929 | qla24xx_disable_msix(ha); | 1891 | qla24xx_disable_msix(ha); |
1930 | goto msix_out; | 1892 | ha->mqenable = 0; |
1893 | goto msix_out; | ||
1894 | } | ||
1895 | qentry->have_irq = 1; | ||
1896 | qentry->rsp = rsp; | ||
1897 | rsp->msix = qentry; | ||
1931 | } | 1898 | } |
1932 | qentry->have_irq = 1; | ||
1933 | qentry->rsp = rsp; | ||
1934 | 1899 | ||
1935 | /* Enable MSI-X vector for response queue update for queue 0 */ | 1900 | /* Enable MSI-X vector for response queue update for queue 0 */ |
1936 | if (ha->max_queues > 1 && ha->mqiobase) { | 1901 | if (ha->mqiobase && (ha->max_rsp_queues > 1 || ha->max_req_queues > 1)) |
1937 | ha->mqenable = 1; | 1902 | ha->mqenable = 1; |
1938 | msix_queue = &multi_rsp_queue; | ||
1939 | qla_printk(KERN_INFO, ha, | ||
1940 | "MQ enabled, Number of Queue Resources: %d \n", | ||
1941 | ha->max_queues); | ||
1942 | } else { | ||
1943 | ha->mqenable = 0; | ||
1944 | msix_queue = &base_rsp_queue; | ||
1945 | } | ||
1946 | |||
1947 | qentry = &ha->msix_entries[1]; | ||
1948 | ret = request_irq(qentry->vector, msix_queue->handler, 0, | ||
1949 | msix_queue->name, rsp); | ||
1950 | if (ret) { | ||
1951 | qla_printk(KERN_WARNING, ha, | ||
1952 | "MSI-X: Unable to register handler -- %x/%d.\n", | ||
1953 | qentry->vector, ret); | ||
1954 | qla24xx_disable_msix(ha); | ||
1955 | ha->mqenable = 0; | ||
1956 | goto msix_out; | ||
1957 | } | ||
1958 | qentry->have_irq = 1; | ||
1959 | qentry->rsp = rsp; | ||
1960 | 1903 | ||
1961 | msix_out: | 1904 | msix_out: |
1962 | kfree(entries); | 1905 | kfree(entries); |
@@ -2063,35 +2006,11 @@ qla2x00_free_irqs(scsi_qla_host_t *vha) | |||
2063 | } | 2006 | } |
2064 | } | 2007 | } |
2065 | 2008 | ||
2066 | static struct scsi_qla_host * | ||
2067 | qla2x00_get_rsp_host(struct rsp_que *rsp) | ||
2068 | { | ||
2069 | srb_t *sp; | ||
2070 | struct qla_hw_data *ha = rsp->hw; | ||
2071 | struct scsi_qla_host *vha = NULL; | ||
2072 | struct sts_entry_24xx *pkt; | ||
2073 | struct req_que *req; | ||
2074 | |||
2075 | if (rsp->id) { | ||
2076 | pkt = (struct sts_entry_24xx *) rsp->ring_ptr; | ||
2077 | req = rsp->req; | ||
2078 | if (pkt && pkt->handle < MAX_OUTSTANDING_COMMANDS) { | ||
2079 | sp = req->outstanding_cmds[pkt->handle]; | ||
2080 | if (sp) | ||
2081 | vha = sp->fcport->vha; | ||
2082 | } | ||
2083 | } | ||
2084 | if (!vha) | ||
2085 | /* handle it in base queue */ | ||
2086 | vha = pci_get_drvdata(ha->pdev); | ||
2087 | |||
2088 | return vha; | ||
2089 | } | ||
2090 | 2009 | ||
2091 | int qla25xx_request_irq(struct rsp_que *rsp) | 2010 | int qla25xx_request_irq(struct rsp_que *rsp) |
2092 | { | 2011 | { |
2093 | struct qla_hw_data *ha = rsp->hw; | 2012 | struct qla_hw_data *ha = rsp->hw; |
2094 | struct qla_init_msix_entry *intr = &multi_rsp_queue; | 2013 | struct qla_init_msix_entry *intr = &msix_entries[2]; |
2095 | struct qla_msix_entry *msix = rsp->msix; | 2014 | struct qla_msix_entry *msix = rsp->msix; |
2096 | int ret; | 2015 | int ret; |
2097 | 2016 | ||
@@ -2106,3 +2025,30 @@ int qla25xx_request_irq(struct rsp_que *rsp) | |||
2106 | msix->rsp = rsp; | 2025 | msix->rsp = rsp; |
2107 | return ret; | 2026 | return ret; |
2108 | } | 2027 | } |
2028 | |||
2029 | struct scsi_qla_host * | ||
2030 | qla25xx_get_host(struct rsp_que *rsp) | ||
2031 | { | ||
2032 | srb_t *sp; | ||
2033 | struct qla_hw_data *ha = rsp->hw; | ||
2034 | struct scsi_qla_host *vha = NULL; | ||
2035 | struct sts_entry_24xx *pkt; | ||
2036 | struct req_que *req; | ||
2037 | uint16_t que; | ||
2038 | uint32_t handle; | ||
2039 | |||
2040 | pkt = (struct sts_entry_24xx *) rsp->ring_ptr; | ||
2041 | que = MSW(pkt->handle); | ||
2042 | handle = (uint32_t) LSW(pkt->handle); | ||
2043 | req = ha->req_q_map[que]; | ||
2044 | if (handle < MAX_OUTSTANDING_COMMANDS) { | ||
2045 | sp = req->outstanding_cmds[handle]; | ||
2046 | if (sp) | ||
2047 | return sp->fcport->vha; | ||
2048 | else | ||
2049 | goto base_que; | ||
2050 | } | ||
2051 | base_que: | ||
2052 | vha = pci_get_drvdata(ha->pdev); | ||
2053 | return vha; | ||
2054 | } | ||