diff options
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 3 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 20 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 53 |
4 files changed, 50 insertions, 28 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index d60cd1737ee6..f7df01b76714 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
| @@ -2734,7 +2734,8 @@ struct isp_operations { | |||
| 2734 | 2734 | ||
| 2735 | #define QLA_MSIX_DEFAULT 0x00 | 2735 | #define QLA_MSIX_DEFAULT 0x00 |
| 2736 | #define QLA_MSIX_RSP_Q 0x01 | 2736 | #define QLA_MSIX_RSP_Q 0x01 |
| 2737 | #define QLA_MSIX_QPAIR_MULTIQ_RSP_Q 0x02 | 2737 | #define QLA_ATIO_VECTOR 0x02 |
| 2738 | #define QLA_MSIX_QPAIR_MULTIQ_RSP_Q 0x03 | ||
| 2738 | 2739 | ||
| 2739 | #define QLA_MIDX_DEFAULT 0 | 2740 | #define QLA_MIDX_DEFAULT 0 |
| 2740 | #define QLA_MIDX_RSP_Q 1 | 2741 | #define QLA_MIDX_RSP_Q 1 |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 400ffd1894ee..632d5f30386a 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -6764,7 +6764,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v | |||
| 6764 | qpair->vp_idx = vp_idx; | 6764 | qpair->vp_idx = vp_idx; |
| 6765 | 6765 | ||
| 6766 | for (i = 0; i < ha->msix_count; i++) { | 6766 | for (i = 0; i < ha->msix_count; i++) { |
| 6767 | msix = &ha->msix_entries[i + 2]; | 6767 | msix = &ha->msix_entries[i]; |
| 6768 | if (msix->in_use) | 6768 | if (msix->in_use) |
| 6769 | continue; | 6769 | continue; |
| 6770 | qpair->msix = msix; | 6770 | qpair->msix = msix; |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index d27019b3ed74..af840bf587d5 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
| @@ -3005,6 +3005,7 @@ struct qla_init_msix_entry { | |||
| 3005 | static struct qla_init_msix_entry msix_entries[] = { | 3005 | static struct qla_init_msix_entry msix_entries[] = { |
| 3006 | { "qla2xxx (default)", qla24xx_msix_default }, | 3006 | { "qla2xxx (default)", qla24xx_msix_default }, |
| 3007 | { "qla2xxx (rsp_q)", qla24xx_msix_rsp_q }, | 3007 | { "qla2xxx (rsp_q)", qla24xx_msix_rsp_q }, |
| 3008 | { "qla2xxx (atio_q)", qla83xx_msix_atio_q }, | ||
| 3008 | { "qla2xxx (qpair_multiq)", qla2xxx_msix_rsp_q }, | 3009 | { "qla2xxx (qpair_multiq)", qla2xxx_msix_rsp_q }, |
| 3009 | }; | 3010 | }; |
| 3010 | 3011 | ||
| @@ -3013,17 +3014,10 @@ static struct qla_init_msix_entry qla82xx_msix_entries[] = { | |||
| 3013 | { "qla2xxx (rsp_q)", qla82xx_msix_rsp_q }, | 3014 | { "qla2xxx (rsp_q)", qla82xx_msix_rsp_q }, |
| 3014 | }; | 3015 | }; |
| 3015 | 3016 | ||
| 3016 | static struct qla_init_msix_entry qla83xx_msix_entries[] = { | ||
| 3017 | { "qla2xxx (default)", qla24xx_msix_default }, | ||
| 3018 | { "qla2xxx (rsp_q)", qla24xx_msix_rsp_q }, | ||
| 3019 | { "qla2xxx (atio_q)", qla83xx_msix_atio_q }, | ||
| 3020 | }; | ||
| 3021 | |||
| 3022 | static int | 3017 | static int |
| 3023 | qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) | 3018 | qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) |
| 3024 | { | 3019 | { |
| 3025 | #define MIN_MSIX_COUNT 2 | 3020 | #define MIN_MSIX_COUNT 2 |
| 3026 | #define ATIO_VECTOR 2 | ||
| 3027 | int i, ret; | 3021 | int i, ret; |
| 3028 | struct qla_msix_entry *qentry; | 3022 | struct qla_msix_entry *qentry; |
| 3029 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 3023 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
| @@ -3080,7 +3074,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) | |||
| 3080 | } | 3074 | } |
| 3081 | 3075 | ||
| 3082 | /* Enable MSI-X vectors for the base queue */ | 3076 | /* Enable MSI-X vectors for the base queue */ |
| 3083 | for (i = 0; i < 2; i++) { | 3077 | for (i = 0; i < (QLA_MSIX_RSP_Q + 1); i++) { |
| 3084 | qentry = &ha->msix_entries[i]; | 3078 | qentry = &ha->msix_entries[i]; |
| 3085 | qentry->handle = rsp; | 3079 | qentry->handle = rsp; |
| 3086 | rsp->msix = qentry; | 3080 | rsp->msix = qentry; |
| @@ -3097,6 +3091,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) | |||
| 3097 | if (ret) | 3091 | if (ret) |
| 3098 | goto msix_register_fail; | 3092 | goto msix_register_fail; |
| 3099 | qentry->have_irq = 1; | 3093 | qentry->have_irq = 1; |
| 3094 | qentry->in_use = 1; | ||
| 3100 | 3095 | ||
| 3101 | /* Register for CPU affinity notification. */ | 3096 | /* Register for CPU affinity notification. */ |
| 3102 | irq_set_affinity_notifier(qentry->vector, &qentry->irq_notify); | 3097 | irq_set_affinity_notifier(qentry->vector, &qentry->irq_notify); |
| @@ -3116,14 +3111,15 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) | |||
| 3116 | * queue. | 3111 | * queue. |
| 3117 | */ | 3112 | */ |
| 3118 | if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) { | 3113 | if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) { |
| 3119 | qentry = &ha->msix_entries[ATIO_VECTOR]; | 3114 | qentry = &ha->msix_entries[QLA_ATIO_VECTOR]; |
| 3120 | rsp->msix = qentry; | 3115 | rsp->msix = qentry; |
| 3121 | qentry->handle = rsp; | 3116 | qentry->handle = rsp; |
| 3122 | scnprintf(qentry->name, sizeof(qentry->name), | 3117 | scnprintf(qentry->name, sizeof(qentry->name), |
| 3123 | qla83xx_msix_entries[ATIO_VECTOR].name); | 3118 | msix_entries[QLA_ATIO_VECTOR].name); |
| 3119 | qentry->in_use = 1; | ||
| 3124 | ret = request_irq(qentry->vector, | 3120 | ret = request_irq(qentry->vector, |
| 3125 | qla83xx_msix_entries[ATIO_VECTOR].handler, | 3121 | msix_entries[QLA_ATIO_VECTOR].handler, |
| 3126 | 0, qla83xx_msix_entries[ATIO_VECTOR].name, rsp); | 3122 | 0, msix_entries[QLA_ATIO_VECTOR].name, rsp); |
| 3127 | qentry->have_irq = 1; | 3123 | qentry->have_irq = 1; |
| 3128 | } | 3124 | } |
| 3129 | 3125 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index d10a8763caaf..8521cfe302e9 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -439,24 +439,41 @@ static void qla2x00_free_queues(struct qla_hw_data *ha) | |||
| 439 | struct req_que *req; | 439 | struct req_que *req; |
| 440 | struct rsp_que *rsp; | 440 | struct rsp_que *rsp; |
| 441 | int cnt; | 441 | int cnt; |
| 442 | unsigned long flags; | ||
| 442 | 443 | ||
| 444 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
| 443 | for (cnt = 0; cnt < ha->max_req_queues; cnt++) { | 445 | for (cnt = 0; cnt < ha->max_req_queues; cnt++) { |
| 444 | if (!test_bit(cnt, ha->req_qid_map)) | 446 | if (!test_bit(cnt, ha->req_qid_map)) |
| 445 | continue; | 447 | continue; |
| 446 | 448 | ||
| 447 | req = ha->req_q_map[cnt]; | 449 | req = ha->req_q_map[cnt]; |
| 450 | clear_bit(cnt, ha->req_qid_map); | ||
| 451 | ha->req_q_map[cnt] = NULL; | ||
| 452 | |||
| 453 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
| 448 | qla2x00_free_req_que(ha, req); | 454 | qla2x00_free_req_que(ha, req); |
| 455 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
| 449 | } | 456 | } |
| 457 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
| 458 | |||
| 450 | kfree(ha->req_q_map); | 459 | kfree(ha->req_q_map); |
| 451 | ha->req_q_map = NULL; | 460 | ha->req_q_map = NULL; |
| 452 | 461 | ||
| 462 | |||
| 463 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
| 453 | for (cnt = 0; cnt < ha->max_rsp_queues; cnt++) { | 464 | for (cnt = 0; cnt < ha->max_rsp_queues; cnt++) { |
| 454 | if (!test_bit(cnt, ha->rsp_qid_map)) | 465 | if (!test_bit(cnt, ha->rsp_qid_map)) |
| 455 | continue; | 466 | continue; |
| 456 | 467 | ||
| 457 | rsp = ha->rsp_q_map[cnt]; | 468 | rsp = ha->rsp_q_map[cnt]; |
| 469 | clear_bit(cnt, ha->req_qid_map); | ||
| 470 | ha->rsp_q_map[cnt] = NULL; | ||
| 471 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
| 458 | qla2x00_free_rsp_que(ha, rsp); | 472 | qla2x00_free_rsp_que(ha, rsp); |
| 473 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
| 459 | } | 474 | } |
| 475 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
| 476 | |||
| 460 | kfree(ha->rsp_q_map); | 477 | kfree(ha->rsp_q_map); |
| 461 | ha->rsp_q_map = NULL; | 478 | ha->rsp_q_map = NULL; |
| 462 | } | 479 | } |
| @@ -1890,17 +1907,22 @@ qla83xx_iospace_config(struct qla_hw_data *ha) | |||
| 1890 | pci_read_config_word(ha->pdev, | 1907 | pci_read_config_word(ha->pdev, |
| 1891 | QLA_83XX_PCI_MSIX_CONTROL, &msix); | 1908 | QLA_83XX_PCI_MSIX_CONTROL, &msix); |
| 1892 | ha->msix_count = msix + 1; | 1909 | ha->msix_count = msix + 1; |
| 1893 | /* Max queues are bounded by available msix vectors */ | 1910 | /* |
| 1894 | /* queue 0 uses two msix vectors */ | 1911 | * By default, driver uses at least two msix vectors |
| 1912 | * (default & rspq) | ||
| 1913 | */ | ||
| 1895 | if (ql2xmqsupport) { | 1914 | if (ql2xmqsupport) { |
| 1896 | /* MB interrupt uses 1 vector */ | 1915 | /* MB interrupt uses 1 vector */ |
| 1897 | ha->max_req_queues = ha->msix_count - 1; | 1916 | ha->max_req_queues = ha->msix_count - 1; |
| 1898 | ha->max_rsp_queues = ha->max_req_queues; | 1917 | ha->max_rsp_queues = ha->max_req_queues; |
| 1918 | |||
| 1919 | /* ATIOQ needs 1 vector. That's 1 less QPair */ | ||
| 1920 | if (QLA_TGT_MODE_ENABLED()) | ||
| 1921 | ha->max_req_queues--; | ||
| 1922 | |||
| 1899 | /* Queue pairs is the max value minus | 1923 | /* Queue pairs is the max value minus |
| 1900 | * the base queue pair */ | 1924 | * the base queue pair */ |
| 1901 | ha->max_qpairs = ha->max_req_queues - 1; | 1925 | ha->max_qpairs = ha->max_req_queues - 1; |
| 1902 | ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc010, | ||
| 1903 | "Max no of queues pairs: %d.\n", ha->max_qpairs); | ||
| 1904 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0190, | 1926 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0190, |
| 1905 | "Max no of queues pairs: %d.\n", ha->max_qpairs); | 1927 | "Max no of queues pairs: %d.\n", ha->max_qpairs); |
| 1906 | } | 1928 | } |
| @@ -1912,6 +1934,8 @@ qla83xx_iospace_config(struct qla_hw_data *ha) | |||
| 1912 | 1934 | ||
| 1913 | mqiobase_exit: | 1935 | mqiobase_exit: |
| 1914 | ha->msix_count = ha->max_rsp_queues + 1; | 1936 | ha->msix_count = ha->max_rsp_queues + 1; |
| 1937 | if (QLA_TGT_MODE_ENABLED()) | ||
| 1938 | ha->msix_count++; | ||
| 1915 | 1939 | ||
| 1916 | qlt_83xx_iospace_config(ha); | 1940 | qlt_83xx_iospace_config(ha); |
| 1917 | 1941 | ||
| @@ -2989,7 +3013,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 2989 | host->can_queue, base_vha->req, | 3013 | host->can_queue, base_vha->req, |
| 2990 | base_vha->mgmt_svr_loop_id, host->sg_tablesize); | 3014 | base_vha->mgmt_svr_loop_id, host->sg_tablesize); |
| 2991 | 3015 | ||
| 2992 | if (ha->mqenable) { | 3016 | if (ha->mqenable && qla_ini_mode_enabled(base_vha)) { |
| 2993 | ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 1); | 3017 | ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 1); |
| 2994 | /* Create start of day qpairs for Block MQ */ | 3018 | /* Create start of day qpairs for Block MQ */ |
| 2995 | if (shost_use_blk_mq(host)) { | 3019 | if (shost_use_blk_mq(host)) { |
| @@ -3263,13 +3287,6 @@ qla2x00_delete_all_vps(struct qla_hw_data *ha, scsi_qla_host_t *base_vha) | |||
| 3263 | static void | 3287 | static void |
| 3264 | qla2x00_destroy_deferred_work(struct qla_hw_data *ha) | 3288 | qla2x00_destroy_deferred_work(struct qla_hw_data *ha) |
| 3265 | { | 3289 | { |
| 3266 | /* Flush the work queue and remove it */ | ||
| 3267 | if (ha->wq) { | ||
| 3268 | flush_workqueue(ha->wq); | ||
| 3269 | destroy_workqueue(ha->wq); | ||
| 3270 | ha->wq = NULL; | ||
| 3271 | } | ||
| 3272 | |||
| 3273 | /* Cancel all work and destroy DPC workqueues */ | 3290 | /* Cancel all work and destroy DPC workqueues */ |
| 3274 | if (ha->dpc_lp_wq) { | 3291 | if (ha->dpc_lp_wq) { |
| 3275 | cancel_work_sync(&ha->idc_aen); | 3292 | cancel_work_sync(&ha->idc_aen); |
| @@ -3465,9 +3482,17 @@ qla2x00_free_device(scsi_qla_host_t *vha) | |||
| 3465 | ha->isp_ops->disable_intrs(ha); | 3482 | ha->isp_ops->disable_intrs(ha); |
| 3466 | } | 3483 | } |
| 3467 | 3484 | ||
| 3485 | qla2x00_free_fcports(vha); | ||
| 3486 | |||
| 3468 | qla2x00_free_irqs(vha); | 3487 | qla2x00_free_irqs(vha); |
| 3469 | 3488 | ||
| 3470 | qla2x00_free_fcports(vha); | 3489 | /* Flush the work queue and remove it */ |
| 3490 | if (ha->wq) { | ||
| 3491 | flush_workqueue(ha->wq); | ||
| 3492 | destroy_workqueue(ha->wq); | ||
| 3493 | ha->wq = NULL; | ||
| 3494 | } | ||
| 3495 | |||
| 3471 | 3496 | ||
| 3472 | qla2x00_mem_free(ha); | 3497 | qla2x00_mem_free(ha); |
| 3473 | 3498 | ||
| @@ -5187,8 +5212,8 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work) | |||
| 5187 | 5212 | ||
| 5188 | base_vha->flags.init_done = 0; | 5213 | base_vha->flags.init_done = 0; |
| 5189 | qla25xx_delete_queues(base_vha); | 5214 | qla25xx_delete_queues(base_vha); |
| 5190 | qla2x00_free_irqs(base_vha); | ||
| 5191 | qla2x00_free_fcports(base_vha); | 5215 | qla2x00_free_fcports(base_vha); |
| 5216 | qla2x00_free_irqs(base_vha); | ||
| 5192 | qla2x00_mem_free(ha); | 5217 | qla2x00_mem_free(ha); |
| 5193 | qla82xx_md_free(base_vha); | 5218 | qla82xx_md_free(base_vha); |
| 5194 | qla2x00_free_queues(ha); | 5219 | qla2x00_free_queues(ha); |
