aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi
diff options
context:
space:
mode:
authorJayamohan Kallickal <jayamohank@gmail.com>2013-04-05 23:38:25 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-05-02 11:08:27 -0400
commit43f388b02e5c3a10a89f7163f38787a98638eb18 (patch)
tree7237beb102754fb5c2dbfa4314a754dd597b28ac /drivers/scsi/be2iscsi
parentbf9131cbb860fbd0faf5483d3df5d60b25a3f47c (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.c15
-rw-r--r--drivers/scsi/be2iscsi/be_main.c68
-rw-r--r--drivers/scsi/be2iscsi/be_main.h1
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)
990static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) 990static 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 **/
4074void
4075beiscsi_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
749free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); 749free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
750 750
751void beiscsi_process_all_cqs(struct work_struct *work); 751void beiscsi_process_all_cqs(struct work_struct *work);
752void beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn);
752 753
753static inline bool beiscsi_error(struct beiscsi_hba *phba) 754static inline bool beiscsi_error(struct beiscsi_hba *phba)
754{ 755{