aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i
diff options
context:
space:
mode:
authorEddie Wai <eddie.wai@broadcom.com>2010-08-12 19:44:30 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-09-05 13:51:16 -0400
commit250ae982e2864aa0e06a09137382f44e58b51683 (patch)
treefde480c10f393bbd4c6ea1d2af3e189d2d6f415e /drivers/scsi/bnx2i
parent2c2255e08dee510c68d641195f83d40899897c65 (diff)
[SCSI] bnx2i: Added chip cleanup for the remove module path
In the case when an ep_connect request is interrupted due to route request stall, if the iSCSI daemon is terminated by the user, the chip will be left in a state which will not get cleaned up upon module removal. Upon module reload, when the same context id is used for a new connection, chip panic would occur. This patch adds chip cleanup in the module removal path. Signed-off-by: Eddie Wai <eddie.wai@broadcom.com> Acked-by: Benjamin Li <benli@broadcom.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/bnx2i')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c54
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c3
2 files changed, 37 insertions, 20 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index a796f565f38..1294936f4fa 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -167,6 +167,38 @@ void bnx2i_start(void *handle)
167 167
168 168
169/** 169/**
170 * bnx2i_chip_cleanup - local routine to handle chip cleanup
171 * @hba: Adapter instance to register
172 *
173 * Driver checks if adapter still has any active connections before
174 * executing the cleanup process
175 */
176static void bnx2i_chip_cleanup(struct bnx2i_hba *hba)
177{
178 struct bnx2i_endpoint *bnx2i_ep;
179 struct list_head *pos, *tmp;
180
181 if (hba->ofld_conns_active) {
182 /* Stage to force the disconnection
183 * This is the case where the daemon is either slow or
184 * not present
185 */
186 printk(KERN_ALERT "bnx2i: (%s) chip cleanup for %d active "
187 "connections\n", hba->netdev->name,
188 hba->ofld_conns_active);
189 mutex_lock(&hba->net_dev_lock);
190 list_for_each_safe(pos, tmp, &hba->ep_active_list) {
191 bnx2i_ep = list_entry(pos, struct bnx2i_endpoint, link);
192 /* Clean up the chip only */
193 bnx2i_hw_ep_disconnect(bnx2i_ep);
194 bnx2i_ep->cm_sk = NULL;
195 }
196 mutex_unlock(&hba->net_dev_lock);
197 }
198}
199
200
201/**
170 * bnx2i_stop - cnic callback to shutdown adapter instance 202 * bnx2i_stop - cnic callback to shutdown adapter instance
171 * @handle: transparent handle pointing to adapter structure 203 * @handle: transparent handle pointing to adapter structure
172 * 204 *
@@ -176,8 +208,6 @@ void bnx2i_start(void *handle)
176void bnx2i_stop(void *handle) 208void bnx2i_stop(void *handle)
177{ 209{
178 struct bnx2i_hba *hba = handle; 210 struct bnx2i_hba *hba = handle;
179 struct list_head *pos, *tmp;
180 struct bnx2i_endpoint *bnx2i_ep;
181 int conns_active; 211 int conns_active;
182 212
183 /* check if cleanup happened in GOING_DOWN context */ 213 /* check if cleanup happened in GOING_DOWN context */
@@ -198,24 +228,7 @@ void bnx2i_stop(void *handle)
198 if (hba->ofld_conns_active == conns_active) 228 if (hba->ofld_conns_active == conns_active)
199 break; 229 break;
200 } 230 }
201 if (hba->ofld_conns_active) { 231 bnx2i_chip_cleanup(hba);
202 /* Stage to force the disconnection
203 * This is the case where the daemon is either slow or
204 * not present
205 */
206 printk(KERN_ALERT "bnx2i: Wait timeout, force all eps "
207 "to disconnect (%d)\n", hba->ofld_conns_active);
208 mutex_lock(&hba->net_dev_lock);
209 list_for_each_safe(pos, tmp, &hba->ep_active_list) {
210 bnx2i_ep = list_entry(pos, struct bnx2i_endpoint, link);
211 /* Clean up the chip only */
212 bnx2i_hw_ep_disconnect(bnx2i_ep);
213 }
214 mutex_unlock(&hba->net_dev_lock);
215 if (hba->ofld_conns_active)
216 printk(KERN_ERR "bnx2i: EP disconnect timeout (%d)!\n",
217 hba->ofld_conns_active);
218 }
219 232
220 /* This flag should be cleared last so that ep_disconnect() gracefully 233 /* This flag should be cleared last so that ep_disconnect() gracefully
221 * cleans up connection context 234 * cleans up connection context
@@ -457,6 +470,7 @@ static void __exit bnx2i_mod_exit(void)
457 adapter_count--; 470 adapter_count--;
458 471
459 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 472 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
473 bnx2i_chip_cleanup(hba);
460 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); 474 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
461 clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); 475 clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
462 } 476 }
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 0425540d481..fb50efbce08 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1953,6 +1953,9 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
1953 if (!cnic) 1953 if (!cnic)
1954 return 0; 1954 return 0;
1955 1955
1956 if (bnx2i_ep->state == EP_STATE_IDLE)
1957 return 0;
1958
1956 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep)) 1959 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep))
1957 goto destroy_conn; 1960 goto destroy_conn;
1958 1961