aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i/bnx2i_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bnx2i/bnx2i_init.c')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c100
1 files changed, 44 insertions, 56 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index ae4b2d588fd3..0c4210d48ee8 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -15,11 +15,10 @@
15 15
16static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list); 16static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list);
17static u32 adapter_count; 17static u32 adapter_count;
18static int bnx2i_reg_device;
19 18
20#define DRV_MODULE_NAME "bnx2i" 19#define DRV_MODULE_NAME "bnx2i"
21#define DRV_MODULE_VERSION "2.0.1d" 20#define DRV_MODULE_VERSION "2.0.1e"
22#define DRV_MODULE_RELDATE "Mar 25, 2009" 21#define DRV_MODULE_RELDATE "June 22, 2009"
23 22
24static char version[] __devinitdata = 23static char version[] __devinitdata =
25 "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \ 24 "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
@@ -31,7 +30,7 @@ MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709 iSCSI Driver");
31MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
32MODULE_VERSION(DRV_MODULE_VERSION); 31MODULE_VERSION(DRV_MODULE_VERSION);
33 32
34static DEFINE_RWLOCK(bnx2i_dev_lock); 33static DEFINE_MUTEX(bnx2i_dev_lock);
35 34
36unsigned int event_coal_div = 1; 35unsigned int event_coal_div = 1;
37module_param(event_coal_div, int, 0664); 36module_param(event_coal_div, int, 0664);
@@ -100,14 +99,14 @@ struct bnx2i_hba *get_adapter_list_head(void)
100 if (!adapter_count) 99 if (!adapter_count)
101 goto hba_not_found; 100 goto hba_not_found;
102 101
103 read_lock(&bnx2i_dev_lock); 102 mutex_lock(&bnx2i_dev_lock);
104 list_for_each_entry(tmp_hba, &adapter_list, link) { 103 list_for_each_entry(tmp_hba, &adapter_list, link) {
105 if (tmp_hba->cnic && tmp_hba->cnic->cm_select_dev) { 104 if (tmp_hba->cnic && tmp_hba->cnic->cm_select_dev) {
106 hba = tmp_hba; 105 hba = tmp_hba;
107 break; 106 break;
108 } 107 }
109 } 108 }
110 read_unlock(&bnx2i_dev_lock); 109 mutex_unlock(&bnx2i_dev_lock);
111hba_not_found: 110hba_not_found:
112 return hba; 111 return hba;
113} 112}
@@ -122,14 +121,14 @@ struct bnx2i_hba *bnx2i_find_hba_for_cnic(struct cnic_dev *cnic)
122{ 121{
123 struct bnx2i_hba *hba, *temp; 122 struct bnx2i_hba *hba, *temp;
124 123
125 read_lock(&bnx2i_dev_lock); 124 mutex_lock(&bnx2i_dev_lock);
126 list_for_each_entry_safe(hba, temp, &adapter_list, link) { 125 list_for_each_entry_safe(hba, temp, &adapter_list, link) {
127 if (hba->cnic == cnic) { 126 if (hba->cnic == cnic) {
128 read_unlock(&bnx2i_dev_lock); 127 mutex_unlock(&bnx2i_dev_lock);
129 return hba; 128 return hba;
130 } 129 }
131 } 130 }
132 read_unlock(&bnx2i_dev_lock); 131 mutex_unlock(&bnx2i_dev_lock);
133 return NULL; 132 return NULL;
134} 133}
135 134
@@ -186,18 +185,17 @@ void bnx2i_stop(void *handle)
186 */ 185 */
187void bnx2i_register_device(struct bnx2i_hba *hba) 186void bnx2i_register_device(struct bnx2i_hba *hba)
188{ 187{
188 int rc;
189
189 if (test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state) || 190 if (test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state) ||
190 test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 191 test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
191 return; 192 return;
192 } 193 }
193 194
194 hba->cnic->register_device(hba->cnic, CNIC_ULP_ISCSI, hba); 195 rc = hba->cnic->register_device(hba->cnic, CNIC_ULP_ISCSI, hba);
195 196
196 spin_lock(&hba->lock); 197 if (!rc)
197 bnx2i_reg_device++; 198 set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
198 spin_unlock(&hba->lock);
199
200 set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
201} 199}
202 200
203 201
@@ -211,10 +209,10 @@ void bnx2i_reg_dev_all(void)
211{ 209{
212 struct bnx2i_hba *hba, *temp; 210 struct bnx2i_hba *hba, *temp;
213 211
214 read_lock(&bnx2i_dev_lock); 212 mutex_lock(&bnx2i_dev_lock);
215 list_for_each_entry_safe(hba, temp, &adapter_list, link) 213 list_for_each_entry_safe(hba, temp, &adapter_list, link)
216 bnx2i_register_device(hba); 214 bnx2i_register_device(hba);
217 read_unlock(&bnx2i_dev_lock); 215 mutex_unlock(&bnx2i_dev_lock);
218} 216}
219 217
220 218
@@ -234,10 +232,6 @@ static void bnx2i_unreg_one_device(struct bnx2i_hba *hba)
234 232
235 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); 233 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
236 234
237 spin_lock(&hba->lock);
238 bnx2i_reg_device--;
239 spin_unlock(&hba->lock);
240
241 /* ep_disconnect could come before NETDEV_DOWN, driver won't 235 /* ep_disconnect could come before NETDEV_DOWN, driver won't
242 * see NETDEV_DOWN as it already unregistered itself. 236 * see NETDEV_DOWN as it already unregistered itself.
243 */ 237 */
@@ -255,10 +249,10 @@ void bnx2i_unreg_dev_all(void)
255{ 249{
256 struct bnx2i_hba *hba, *temp; 250 struct bnx2i_hba *hba, *temp;
257 251
258 read_lock(&bnx2i_dev_lock); 252 mutex_lock(&bnx2i_dev_lock);
259 list_for_each_entry_safe(hba, temp, &adapter_list, link) 253 list_for_each_entry_safe(hba, temp, &adapter_list, link)
260 bnx2i_unreg_one_device(hba); 254 bnx2i_unreg_one_device(hba);
261 read_unlock(&bnx2i_dev_lock); 255 mutex_unlock(&bnx2i_dev_lock);
262} 256}
263 257
264 258
@@ -267,35 +261,34 @@ void bnx2i_unreg_dev_all(void)
267 * @hba: bnx2i adapter instance 261 * @hba: bnx2i adapter instance
268 * @cnic: cnic device handle 262 * @cnic: cnic device handle
269 * 263 *
270 * Global resource lock and host adapter lock is held during critical sections 264 * Global resource lock is held during critical sections below. This routine is
271 * below. This routine is called from cnic_register_driver() context and 265 * called from either cnic_register_driver() or device hot plug context and
272 * work horse thread which does majority of device specific initialization 266 * and does majority of device specific initialization
273 */ 267 */
274static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic) 268static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic)
275{ 269{
276 int rc; 270 int rc;
277 271
278 read_lock(&bnx2i_dev_lock); 272 mutex_lock(&bnx2i_dev_lock);
279 if (bnx2i_reg_device && 273 rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba);
280 !test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 274 if (!rc) {
281 rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba);
282 if (rc) /* duplicate registration */
283 printk(KERN_ERR "bnx2i- dev reg failed\n");
284
285 spin_lock(&hba->lock);
286 bnx2i_reg_device++;
287 hba->age++; 275 hba->age++;
288 spin_unlock(&hba->lock);
289
290 set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); 276 set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
291 } 277 list_add_tail(&hba->link, &adapter_list);
292 read_unlock(&bnx2i_dev_lock); 278 adapter_count++;
293 279 } else if (rc == -EBUSY) /* duplicate registration */
294 write_lock(&bnx2i_dev_lock); 280 printk(KERN_ALERT "bnx2i, duplicate registration"
295 list_add_tail(&hba->link, &adapter_list); 281 "hba=%p, cnic=%p\n", hba, cnic);
296 adapter_count++; 282 else if (rc == -EAGAIN)
297 write_unlock(&bnx2i_dev_lock); 283 printk(KERN_ERR "bnx2i, driver not registered\n");
298 return 0; 284 else if (rc == -EINVAL)
285 printk(KERN_ERR "bnx2i, invalid type %d\n", CNIC_ULP_ISCSI);
286 else
287 printk(KERN_ERR "bnx2i dev reg, unknown error, %d\n", rc);
288
289 mutex_unlock(&bnx2i_dev_lock);
290
291 return rc;
299} 292}
300 293
301 294
@@ -343,19 +336,15 @@ void bnx2i_ulp_exit(struct cnic_dev *dev)
343 "found, dev 0x%p\n", dev); 336 "found, dev 0x%p\n", dev);
344 return; 337 return;
345 } 338 }
346 write_lock(&bnx2i_dev_lock); 339 mutex_lock(&bnx2i_dev_lock);
347 list_del_init(&hba->link); 340 list_del_init(&hba->link);
348 adapter_count--; 341 adapter_count--;
349 342
350 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 343 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
351 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); 344 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
352 clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); 345 clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
353
354 spin_lock(&hba->lock);
355 bnx2i_reg_device--;
356 spin_unlock(&hba->lock);
357 } 346 }
358 write_unlock(&bnx2i_dev_lock); 347 mutex_unlock(&bnx2i_dev_lock);
359 348
360 bnx2i_free_hba(hba); 349 bnx2i_free_hba(hba);
361} 350}
@@ -377,6 +366,8 @@ static int __init bnx2i_mod_init(void)
377 if (!is_power_of_2(sq_size)) 366 if (!is_power_of_2(sq_size))
378 sq_size = roundup_pow_of_two(sq_size); 367 sq_size = roundup_pow_of_two(sq_size);
379 368
369 mutex_init(&bnx2i_dev_lock);
370
380 bnx2i_scsi_xport_template = 371 bnx2i_scsi_xport_template =
381 iscsi_register_transport(&bnx2i_iscsi_transport); 372 iscsi_register_transport(&bnx2i_iscsi_transport);
382 if (!bnx2i_scsi_xport_template) { 373 if (!bnx2i_scsi_xport_template) {
@@ -412,7 +403,7 @@ static void __exit bnx2i_mod_exit(void)
412{ 403{
413 struct bnx2i_hba *hba; 404 struct bnx2i_hba *hba;
414 405
415 write_lock(&bnx2i_dev_lock); 406 mutex_lock(&bnx2i_dev_lock);
416 while (!list_empty(&adapter_list)) { 407 while (!list_empty(&adapter_list)) {
417 hba = list_entry(adapter_list.next, struct bnx2i_hba, link); 408 hba = list_entry(adapter_list.next, struct bnx2i_hba, link);
418 list_del(&hba->link); 409 list_del(&hba->link);
@@ -421,14 +412,11 @@ static void __exit bnx2i_mod_exit(void)
421 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 412 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
422 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI); 413 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
423 clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic); 414 clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
424 bnx2i_reg_device--;
425 } 415 }
426 416
427 write_unlock(&bnx2i_dev_lock);
428 bnx2i_free_hba(hba); 417 bnx2i_free_hba(hba);
429 write_lock(&bnx2i_dev_lock);
430 } 418 }
431 write_unlock(&bnx2i_dev_lock); 419 mutex_unlock(&bnx2i_dev_lock);
432 420
433 iscsi_unregister_transport(&bnx2i_iscsi_transport); 421 iscsi_unregister_transport(&bnx2i_iscsi_transport);
434 cnic_unregister_driver(CNIC_ULP_ISCSI); 422 cnic_unregister_driver(CNIC_ULP_ISCSI);