aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i
diff options
context:
space:
mode:
authorAnil Veerabhadrappa <anilgv@broadcom.com>2009-06-23 17:07:40 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-08-22 18:51:53 -0400
commit3be924fb1d7be90c3ae6aa30ca42e9aa5d75efaf (patch)
tree5b0f81e20c15a8f11c5b0aca137768d415ca91e7 /drivers/scsi/bnx2i
parent4e85f15166a6a9da8317ddb8600b604b27e58aa3 (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.c54
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);
17static u32 adapter_count; 17static 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
23static char version[] __devinitdata = 23static 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");
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31MODULE_VERSION(DRV_MODULE_VERSION); 31MODULE_VERSION(DRV_MODULE_VERSION);
32 32
33static DEFINE_RWLOCK(bnx2i_dev_lock); 33static DEFINE_MUTEX(bnx2i_dev_lock);
34 34
35unsigned int event_coal_div = 1; 35unsigned int event_coal_div = 1;
36module_param(event_coal_div, int, 0664); 36module_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);
110hba_not_found: 110hba_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 */
265static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic) 265static 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);