diff options
author | Anil Veerabhadrappa <anilgv@broadcom.com> | 2009-06-23 17:07:40 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-08-22 18:51:53 -0400 |
commit | 3be924fb1d7be90c3ae6aa30ca42e9aa5d75efaf (patch) | |
tree | 5b0f81e20c15a8f11c5b0aca137768d415ca91e7 /drivers/scsi/bnx2i | |
parent | 4e85f15166a6a9da8317ddb8600b604b27e58aa3 (diff) |
[SCSI] bnx2i: convert bnx2i_dev_lock to mutex
convert bnx2i_dev_lock to type mutex from rwlock_t because
cnic->register_device() can sleep for various reasons including memory
allocation, waiting for ISCSI_INIT completion and while acquiring mutex lock,
cnic_lock.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: Anil Veerabhadrappa <anilgv@broadcom.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/bnx2i')
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i_init.c | 54 |
1 files changed, 25 insertions, 29 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c index 2aeeeee3372d..fd78540ffc95 100644 --- a/drivers/scsi/bnx2i/bnx2i_init.c +++ b/drivers/scsi/bnx2i/bnx2i_init.c | |||
@@ -17,8 +17,8 @@ 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.0.1d" | 20 | #define DRV_MODULE_VERSION "2.0.1e" |
21 | #define DRV_MODULE_RELDATE "Mar 25, 2009" | 21 | #define DRV_MODULE_RELDATE "June 22, 2009" |
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 \ |
@@ -30,7 +30,7 @@ MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709 iSCSI Driver"); | |||
30 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
31 | MODULE_VERSION(DRV_MODULE_VERSION); | 31 | MODULE_VERSION(DRV_MODULE_VERSION); |
32 | 32 | ||
33 | static DEFINE_RWLOCK(bnx2i_dev_lock); | 33 | static DEFINE_MUTEX(bnx2i_dev_lock); |
34 | 34 | ||
35 | unsigned int event_coal_div = 1; | 35 | unsigned int event_coal_div = 1; |
36 | module_param(event_coal_div, int, 0664); | 36 | module_param(event_coal_div, int, 0664); |
@@ -99,14 +99,14 @@ struct bnx2i_hba *get_adapter_list_head(void) | |||
99 | if (!adapter_count) | 99 | if (!adapter_count) |
100 | goto hba_not_found; | 100 | goto hba_not_found; |
101 | 101 | ||
102 | read_lock(&bnx2i_dev_lock); | 102 | mutex_lock(&bnx2i_dev_lock); |
103 | list_for_each_entry(tmp_hba, &adapter_list, link) { | 103 | list_for_each_entry(tmp_hba, &adapter_list, link) { |
104 | if (tmp_hba->cnic && tmp_hba->cnic->cm_select_dev) { | 104 | if (tmp_hba->cnic && tmp_hba->cnic->cm_select_dev) { |
105 | hba = tmp_hba; | 105 | hba = tmp_hba; |
106 | break; | 106 | break; |
107 | } | 107 | } |
108 | } | 108 | } |
109 | read_unlock(&bnx2i_dev_lock); | 109 | mutex_unlock(&bnx2i_dev_lock); |
110 | hba_not_found: | 110 | hba_not_found: |
111 | return hba; | 111 | return hba; |
112 | } | 112 | } |
@@ -121,14 +121,14 @@ struct bnx2i_hba *bnx2i_find_hba_for_cnic(struct cnic_dev *cnic) | |||
121 | { | 121 | { |
122 | struct bnx2i_hba *hba, *temp; | 122 | struct bnx2i_hba *hba, *temp; |
123 | 123 | ||
124 | read_lock(&bnx2i_dev_lock); | 124 | mutex_lock(&bnx2i_dev_lock); |
125 | list_for_each_entry_safe(hba, temp, &adapter_list, link) { | 125 | list_for_each_entry_safe(hba, temp, &adapter_list, link) { |
126 | if (hba->cnic == cnic) { | 126 | if (hba->cnic == cnic) { |
127 | read_unlock(&bnx2i_dev_lock); | 127 | mutex_unlock(&bnx2i_dev_lock); |
128 | return hba; | 128 | return hba; |
129 | } | 129 | } |
130 | } | 130 | } |
131 | read_unlock(&bnx2i_dev_lock); | 131 | mutex_unlock(&bnx2i_dev_lock); |
132 | return NULL; | 132 | return NULL; |
133 | } | 133 | } |
134 | 134 | ||
@@ -206,10 +206,10 @@ void bnx2i_reg_dev_all(void) | |||
206 | { | 206 | { |
207 | struct bnx2i_hba *hba, *temp; | 207 | struct bnx2i_hba *hba, *temp; |
208 | 208 | ||
209 | read_lock(&bnx2i_dev_lock); | 209 | mutex_lock(&bnx2i_dev_lock); |
210 | list_for_each_entry_safe(hba, temp, &adapter_list, link) | 210 | list_for_each_entry_safe(hba, temp, &adapter_list, link) |
211 | bnx2i_register_device(hba); | 211 | bnx2i_register_device(hba); |
212 | read_unlock(&bnx2i_dev_lock); | 212 | mutex_unlock(&bnx2i_dev_lock); |
213 | } | 213 | } |
214 | 214 | ||
215 | 215 | ||
@@ -246,10 +246,10 @@ void bnx2i_unreg_dev_all(void) | |||
246 | { | 246 | { |
247 | struct bnx2i_hba *hba, *temp; | 247 | struct bnx2i_hba *hba, *temp; |
248 | 248 | ||
249 | read_lock(&bnx2i_dev_lock); | 249 | mutex_lock(&bnx2i_dev_lock); |
250 | list_for_each_entry_safe(hba, temp, &adapter_list, link) | 250 | list_for_each_entry_safe(hba, temp, &adapter_list, link) |
251 | bnx2i_unreg_one_device(hba); | 251 | bnx2i_unreg_one_device(hba); |
252 | read_unlock(&bnx2i_dev_lock); | 252 | mutex_unlock(&bnx2i_dev_lock); |
253 | } | 253 | } |
254 | 254 | ||
255 | 255 | ||
@@ -258,19 +258,21 @@ void bnx2i_unreg_dev_all(void) | |||
258 | * @hba: bnx2i adapter instance | 258 | * @hba: bnx2i adapter instance |
259 | * @cnic: cnic device handle | 259 | * @cnic: cnic device handle |
260 | * | 260 | * |
261 | * Global resource lock and host adapter lock is held during critical sections | 261 | * Global resource lock is held during critical sections below. This routine is |
262 | * below. This routine is called from cnic_register_driver() context and | 262 | * called from either cnic_register_driver() or device hot plug context and |
263 | * work horse thread which does majority of device specific initialization | 263 | * and does majority of device specific initialization |
264 | */ | 264 | */ |
265 | static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic) | 265 | static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic) |
266 | { | 266 | { |
267 | int rc; | 267 | int rc; |
268 | 268 | ||
269 | read_lock(&bnx2i_dev_lock); | 269 | mutex_lock(&bnx2i_dev_lock); |
270 | rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba); | 270 | rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba); |
271 | if (!rc) { | 271 | if (!rc) { |
272 | hba->age++; | 272 | hba->age++; |
273 | set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); | 273 | set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); |
274 | list_add_tail(&hba->link, &adapter_list); | ||
275 | adapter_count++; | ||
274 | } else if (rc == -EBUSY) /* duplicate registration */ | 276 | } else if (rc == -EBUSY) /* duplicate registration */ |
275 | printk(KERN_ALERT "bnx2i, duplicate registration" | 277 | printk(KERN_ALERT "bnx2i, duplicate registration" |
276 | "hba=%p, cnic=%p\n", hba, cnic); | 278 | "hba=%p, cnic=%p\n", hba, cnic); |
@@ -280,14 +282,8 @@ static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic) | |||
280 | printk(KERN_ERR "bnx2i, invalid type %d\n", CNIC_ULP_ISCSI); | 282 | printk(KERN_ERR "bnx2i, invalid type %d\n", CNIC_ULP_ISCSI); |
281 | else | 283 | else |
282 | printk(KERN_ERR "bnx2i dev reg, unknown error, %d\n", rc); | 284 | printk(KERN_ERR "bnx2i dev reg, unknown error, %d\n", rc); |
283 | read_unlock(&bnx2i_dev_lock); | ||
284 | 285 | ||
285 | if (!rc) { | 286 | mutex_unlock(&bnx2i_dev_lock); |
286 | write_lock(&bnx2i_dev_lock); | ||
287 | list_add_tail(&hba->link, &adapter_list); | ||
288 | adapter_count++; | ||
289 | write_unlock(&bnx2i_dev_lock); | ||
290 | } | ||
291 | 287 | ||
292 | return rc; | 288 | return rc; |
293 | } | 289 | } |
@@ -337,7 +333,7 @@ void bnx2i_ulp_exit(struct cnic_dev *dev) | |||
337 | "found, dev 0x%p\n", dev); | 333 | "found, dev 0x%p\n", dev); |
338 | return; | 334 | return; |
339 | } | 335 | } |
340 | write_lock(&bnx2i_dev_lock); | 336 | mutex_lock(&bnx2i_dev_lock); |
341 | list_del_init(&hba->link); | 337 | list_del_init(&hba->link); |
342 | adapter_count--; | 338 | adapter_count--; |
343 | 339 | ||
@@ -345,7 +341,7 @@ void bnx2i_ulp_exit(struct cnic_dev *dev) | |||
345 | hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); | 341 | hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); |
346 | clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); | 342 | clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); |
347 | } | 343 | } |
348 | write_unlock(&bnx2i_dev_lock); | 344 | mutex_unlock(&bnx2i_dev_lock); |
349 | 345 | ||
350 | bnx2i_free_hba(hba); | 346 | bnx2i_free_hba(hba); |
351 | } | 347 | } |
@@ -367,6 +363,8 @@ static int __init bnx2i_mod_init(void) | |||
367 | if (!is_power_of_2(sq_size)) | 363 | if (!is_power_of_2(sq_size)) |
368 | sq_size = roundup_pow_of_two(sq_size); | 364 | sq_size = roundup_pow_of_two(sq_size); |
369 | 365 | ||
366 | mutex_init(&bnx2i_dev_lock); | ||
367 | |||
370 | bnx2i_scsi_xport_template = | 368 | bnx2i_scsi_xport_template = |
371 | iscsi_register_transport(&bnx2i_iscsi_transport); | 369 | iscsi_register_transport(&bnx2i_iscsi_transport); |
372 | if (!bnx2i_scsi_xport_template) { | 370 | if (!bnx2i_scsi_xport_template) { |
@@ -402,7 +400,7 @@ static void __exit bnx2i_mod_exit(void) | |||
402 | { | 400 | { |
403 | struct bnx2i_hba *hba; | 401 | struct bnx2i_hba *hba; |
404 | 402 | ||
405 | write_lock(&bnx2i_dev_lock); | 403 | mutex_lock(&bnx2i_dev_lock); |
406 | while (!list_empty(&adapter_list)) { | 404 | while (!list_empty(&adapter_list)) { |
407 | hba = list_entry(adapter_list.next, struct bnx2i_hba, link); | 405 | hba = list_entry(adapter_list.next, struct bnx2i_hba, link); |
408 | list_del(&hba->link); | 406 | list_del(&hba->link); |
@@ -413,11 +411,9 @@ static void __exit bnx2i_mod_exit(void) | |||
413 | clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); | 411 | clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); |
414 | } | 412 | } |
415 | 413 | ||
416 | write_unlock(&bnx2i_dev_lock); | ||
417 | bnx2i_free_hba(hba); | 414 | bnx2i_free_hba(hba); |
418 | write_lock(&bnx2i_dev_lock); | ||
419 | } | 415 | } |
420 | write_unlock(&bnx2i_dev_lock); | 416 | mutex_unlock(&bnx2i_dev_lock); |
421 | 417 | ||
422 | iscsi_unregister_transport(&bnx2i_iscsi_transport); | 418 | iscsi_unregister_transport(&bnx2i_iscsi_transport); |
423 | cnic_unregister_driver(CNIC_ULP_ISCSI); | 419 | cnic_unregister_driver(CNIC_ULP_ISCSI); |