diff options
Diffstat (limited to 'drivers/scsi/bnx2i/bnx2i_init.c')
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i_init.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index a796f565f383..50c2aa3b8eb1 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c | |||
@@ -17,15 +17,17 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list); | |||
17 | static u32 adapter_count; | 17 | static u32 adapter_count; |
18 | 18 | ||
19 | #define DRV_MODULE_NAME "bnx2i" | 19 | #define DRV_MODULE_NAME "bnx2i" |
20 | #define DRV_MODULE_VERSION "2.1.2" | 20 | #define DRV_MODULE_VERSION "2.1.3" |
21 | #define DRV_MODULE_RELDATE "Jun 28, 2010" | 21 | #define DRV_MODULE_RELDATE "Aug 10, 2010" |
22 | 22 | ||
23 | static char version[] __devinitdata = | 23 | static char version[] __devinitdata = |
24 | "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \ | 24 | "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \ |
25 | " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 25 | " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
26 | 26 | ||
27 | 27 | ||
28 | MODULE_AUTHOR("Anil Veerabhadrappa <anilgv@broadcom.com>"); | 28 | MODULE_AUTHOR("Anil Veerabhadrappa <anilgv@broadcom.com> and " |
29 | "Eddie Wai <eddie.wai@broadcom.com>"); | ||
30 | |||
29 | MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/57710/57711" | 31 | MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/57710/57711" |
30 | " iSCSI Driver"); | 32 | " iSCSI Driver"); |
31 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
@@ -167,6 +169,38 @@ void bnx2i_start(void *handle) | |||
167 | 169 | ||
168 | 170 | ||
169 | /** | 171 | /** |
172 | * bnx2i_chip_cleanup - local routine to handle chip cleanup | ||
173 | * @hba: Adapter instance to register | ||
174 | * | ||
175 | * Driver checks if adapter still has any active connections before | ||
176 | * executing the cleanup process | ||
177 | */ | ||
178 | static void bnx2i_chip_cleanup(struct bnx2i_hba *hba) | ||
179 | { | ||
180 | struct bnx2i_endpoint *bnx2i_ep; | ||
181 | struct list_head *pos, *tmp; | ||
182 | |||
183 | if (hba->ofld_conns_active) { | ||
184 | /* Stage to force the disconnection | ||
185 | * This is the case where the daemon is either slow or | ||
186 | * not present | ||
187 | */ | ||
188 | printk(KERN_ALERT "bnx2i: (%s) chip cleanup for %d active " | ||
189 | "connections\n", hba->netdev->name, | ||
190 | hba->ofld_conns_active); | ||
191 | mutex_lock(&hba->net_dev_lock); | ||
192 | list_for_each_safe(pos, tmp, &hba->ep_active_list) { | ||
193 | bnx2i_ep = list_entry(pos, struct bnx2i_endpoint, link); | ||
194 | /* Clean up the chip only */ | ||
195 | bnx2i_hw_ep_disconnect(bnx2i_ep); | ||
196 | bnx2i_ep->cm_sk = NULL; | ||
197 | } | ||
198 | mutex_unlock(&hba->net_dev_lock); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | |||
203 | /** | ||
170 | * bnx2i_stop - cnic callback to shutdown adapter instance | 204 | * bnx2i_stop - cnic callback to shutdown adapter instance |
171 | * @handle: transparent handle pointing to adapter structure | 205 | * @handle: transparent handle pointing to adapter structure |
172 | * | 206 | * |
@@ -176,8 +210,6 @@ void bnx2i_start(void *handle) | |||
176 | void bnx2i_stop(void *handle) | 210 | void bnx2i_stop(void *handle) |
177 | { | 211 | { |
178 | struct bnx2i_hba *hba = handle; | 212 | struct bnx2i_hba *hba = handle; |
179 | struct list_head *pos, *tmp; | ||
180 | struct bnx2i_endpoint *bnx2i_ep; | ||
181 | int conns_active; | 213 | int conns_active; |
182 | 214 | ||
183 | /* check if cleanup happened in GOING_DOWN context */ | 215 | /* check if cleanup happened in GOING_DOWN context */ |
@@ -198,24 +230,7 @@ void bnx2i_stop(void *handle) | |||
198 | if (hba->ofld_conns_active == conns_active) | 230 | if (hba->ofld_conns_active == conns_active) |
199 | break; | 231 | break; |
200 | } | 232 | } |
201 | if (hba->ofld_conns_active) { | 233 | 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 | 234 | ||
220 | /* This flag should be cleared last so that ep_disconnect() gracefully | 235 | /* This flag should be cleared last so that ep_disconnect() gracefully |
221 | * cleans up connection context | 236 | * cleans up connection context |
@@ -457,6 +472,7 @@ static void __exit bnx2i_mod_exit(void) | |||
457 | adapter_count--; | 472 | adapter_count--; |
458 | 473 | ||
459 | if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { | 474 | if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { |
475 | bnx2i_chip_cleanup(hba); | ||
460 | hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); | 476 | hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); |
461 | clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); | 477 | clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); |
462 | } | 478 | } |