diff options
author | Jayamohan Kallickal <jayamohank@gmail.com> | 2013-04-05 23:38:25 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-05-02 11:08:27 -0400 |
commit | 43f388b02e5c3a10a89f7163f38787a98638eb18 (patch) | |
tree | 7237beb102754fb5c2dbfa4314a754dd597b28ac /drivers/scsi/be2iscsi | |
parent | bf9131cbb860fbd0faf5483d3df5d60b25a3f47c (diff) |
[SCSI] be2iscsi: Fix freeing CXN specific driver resources.
Free CXN specific resource held by driver when login redirection
or connection retry happens. Login redirection was failing
because WRB/SGL were not allocated from the CID on which
doorbell was rung.
Fixed the issue raised by MikeC
Signed-off-by: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 15 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 68 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 1 |
3 files changed, 62 insertions, 22 deletions
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index 461f859cfbf6..dd5beff92c61 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c | |||
@@ -990,9 +990,24 @@ static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) | |||
990 | static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) | 990 | static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) |
991 | { | 991 | { |
992 | struct beiscsi_hba *phba = beiscsi_ep->phba; | 992 | struct beiscsi_hba *phba = beiscsi_ep->phba; |
993 | struct beiscsi_conn *beiscsi_conn; | ||
993 | 994 | ||
994 | beiscsi_put_cid(phba, beiscsi_ep->ep_cid); | 995 | beiscsi_put_cid(phba, beiscsi_ep->ep_cid); |
995 | beiscsi_ep->phba = NULL; | 996 | beiscsi_ep->phba = NULL; |
997 | |||
998 | /** | ||
999 | * Check if any connection resource allocated by driver | ||
1000 | * is to be freed.This case occurs when target redirection | ||
1001 | * or connection retry is done. | ||
1002 | **/ | ||
1003 | if (!beiscsi_ep->conn) | ||
1004 | return; | ||
1005 | |||
1006 | beiscsi_conn = beiscsi_ep->conn; | ||
1007 | if (beiscsi_conn->login_in_progress) { | ||
1008 | beiscsi_free_mgmt_task_handles(beiscsi_conn); | ||
1009 | beiscsi_conn->login_in_progress = 0; | ||
1010 | } | ||
996 | } | 1011 | } |
997 | 1012 | ||
998 | /** | 1013 | /** |
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 72e4052238cd..75d7186723c1 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -4066,6 +4066,49 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba) | |||
4066 | } | 4066 | } |
4067 | 4067 | ||
4068 | /** | 4068 | /** |
4069 | * beiscsi_free_mgmt_task_handles()- Free driver CXN resources | ||
4070 | * @beiscsi_conn: ptr to the conn to be cleaned up | ||
4071 | * | ||
4072 | * Free driver mgmt resources binded to CXN. | ||
4073 | **/ | ||
4074 | void | ||
4075 | beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn) | ||
4076 | { | ||
4077 | struct beiscsi_io_task *io_task; | ||
4078 | struct beiscsi_hba *phba = beiscsi_conn->phba; | ||
4079 | struct hwi_wrb_context *pwrb_context; | ||
4080 | struct hwi_controller *phwi_ctrlr; | ||
4081 | |||
4082 | phwi_ctrlr = phba->phwi_ctrlr; | ||
4083 | pwrb_context = &phwi_ctrlr->wrb_context | ||
4084 | [beiscsi_conn->beiscsi_conn_cid | ||
4085 | - phba->fw_config.iscsi_cid_start]; | ||
4086 | io_task = beiscsi_conn->task->dd_data; | ||
4087 | |||
4088 | if (io_task->pwrb_handle) { | ||
4089 | memset(io_task->pwrb_handle->pwrb, 0, | ||
4090 | sizeof(struct iscsi_wrb)); | ||
4091 | free_wrb_handle(phba, pwrb_context, | ||
4092 | io_task->pwrb_handle); | ||
4093 | io_task->pwrb_handle = NULL; | ||
4094 | } | ||
4095 | |||
4096 | if (io_task->psgl_handle) { | ||
4097 | spin_lock_bh(&phba->mgmt_sgl_lock); | ||
4098 | free_mgmt_sgl_handle(phba, | ||
4099 | io_task->psgl_handle); | ||
4100 | spin_unlock_bh(&phba->mgmt_sgl_lock); | ||
4101 | io_task->psgl_handle = NULL; | ||
4102 | } | ||
4103 | |||
4104 | if (io_task->mtask_addr) | ||
4105 | pci_unmap_single(phba->pcidev, | ||
4106 | io_task->mtask_addr, | ||
4107 | io_task->mtask_data_count, | ||
4108 | PCI_DMA_TODEVICE); | ||
4109 | } | ||
4110 | |||
4111 | /** | ||
4069 | * beiscsi_cleanup_task()- Free driver resources of the task | 4112 | * beiscsi_cleanup_task()- Free driver resources of the task |
4070 | * @task: ptr to the iscsi task | 4113 | * @task: ptr to the iscsi task |
4071 | * | 4114 | * |
@@ -4104,27 +4147,8 @@ static void beiscsi_cleanup_task(struct iscsi_task *task) | |||
4104 | io_task->psgl_handle = NULL; | 4147 | io_task->psgl_handle = NULL; |
4105 | } | 4148 | } |
4106 | } else { | 4149 | } else { |
4107 | if (!beiscsi_conn->login_in_progress) { | 4150 | if (!beiscsi_conn->login_in_progress) |
4108 | if (io_task->pwrb_handle) { | 4151 | beiscsi_free_mgmt_task_handles(beiscsi_conn); |
4109 | free_wrb_handle(phba, pwrb_context, | ||
4110 | io_task->pwrb_handle); | ||
4111 | io_task->pwrb_handle = NULL; | ||
4112 | } | ||
4113 | if (io_task->psgl_handle) { | ||
4114 | spin_lock(&phba->mgmt_sgl_lock); | ||
4115 | free_mgmt_sgl_handle(phba, | ||
4116 | io_task->psgl_handle); | ||
4117 | spin_unlock(&phba->mgmt_sgl_lock); | ||
4118 | io_task->psgl_handle = NULL; | ||
4119 | } | ||
4120 | if (io_task->mtask_addr) { | ||
4121 | pci_unmap_single(phba->pcidev, | ||
4122 | io_task->mtask_addr, | ||
4123 | io_task->mtask_data_count, | ||
4124 | PCI_DMA_TODEVICE); | ||
4125 | io_task->mtask_addr = 0; | ||
4126 | } | ||
4127 | } | ||
4128 | } | 4152 | } |
4129 | } | 4153 | } |
4130 | 4154 | ||
@@ -4237,6 +4261,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) | |||
4237 | } else { | 4261 | } else { |
4238 | io_task->scsi_cmnd = NULL; | 4262 | io_task->scsi_cmnd = NULL; |
4239 | if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) { | 4263 | if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) { |
4264 | beiscsi_conn->task = task; | ||
4240 | if (!beiscsi_conn->login_in_progress) { | 4265 | if (!beiscsi_conn->login_in_progress) { |
4241 | spin_lock(&phba->mgmt_sgl_lock); | 4266 | spin_lock(&phba->mgmt_sgl_lock); |
4242 | io_task->psgl_handle = (struct sgl_handle *) | 4267 | io_task->psgl_handle = (struct sgl_handle *) |
@@ -4279,7 +4304,6 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) | |||
4279 | io_task->pwrb_handle = | 4304 | io_task->pwrb_handle = |
4280 | beiscsi_conn->plogin_wrb_handle; | 4305 | beiscsi_conn->plogin_wrb_handle; |
4281 | } | 4306 | } |
4282 | beiscsi_conn->task = task; | ||
4283 | } else { | 4307 | } else { |
4284 | spin_lock(&phba->mgmt_sgl_lock); | 4308 | spin_lock(&phba->mgmt_sgl_lock); |
4285 | io_task->psgl_handle = alloc_mgmt_sgl_handle(phba); | 4309 | io_task->psgl_handle = alloc_mgmt_sgl_handle(phba); |
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index e53d08777c01..b098b5b7d188 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h | |||
@@ -749,6 +749,7 @@ void | |||
749 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); | 749 | free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); |
750 | 750 | ||
751 | void beiscsi_process_all_cqs(struct work_struct *work); | 751 | void beiscsi_process_all_cqs(struct work_struct *work); |
752 | void beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn); | ||
752 | 753 | ||
753 | static inline bool beiscsi_error(struct beiscsi_hba *phba) | 754 | static inline bool beiscsi_error(struct beiscsi_hba *phba) |
754 | { | 755 | { |