aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bnx2i')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c100
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c13
2 files changed, 50 insertions, 63 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);
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index f7412196f2f8..9a7ba71f1af4 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -387,6 +387,7 @@ static struct iscsi_endpoint *bnx2i_alloc_ep(struct bnx2i_hba *hba)
387 bnx2i_ep = ep->dd_data; 387 bnx2i_ep = ep->dd_data;
388 INIT_LIST_HEAD(&bnx2i_ep->link); 388 INIT_LIST_HEAD(&bnx2i_ep->link);
389 bnx2i_ep->state = EP_STATE_IDLE; 389 bnx2i_ep->state = EP_STATE_IDLE;
390 bnx2i_ep->ep_iscsi_cid = (u16) -1;
390 bnx2i_ep->hba = hba; 391 bnx2i_ep->hba = hba;
391 bnx2i_ep->hba_age = hba->age; 392 bnx2i_ep->hba_age = hba->age;
392 hba->ofld_conns_active++; 393 hba->ofld_conns_active++;
@@ -1160,9 +1161,6 @@ static int bnx2i_task_xmit(struct iscsi_task *task)
1160 struct bnx2i_cmd *cmd = task->dd_data; 1161 struct bnx2i_cmd *cmd = task->dd_data;
1161 struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr; 1162 struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr;
1162 1163
1163 if (test_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state))
1164 return -ENOTCONN;
1165
1166 if (!bnx2i_conn->is_bound) 1164 if (!bnx2i_conn->is_bound)
1167 return -ENOTCONN; 1165 return -ENOTCONN;
1168 1166
@@ -1653,15 +1651,18 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1653 struct iscsi_endpoint *ep; 1651 struct iscsi_endpoint *ep;
1654 int rc = 0; 1652 int rc = 0;
1655 1653
1656 if (shost) 1654 if (shost) {
1657 /* driver is given scsi host to work with */ 1655 /* driver is given scsi host to work with */
1658 hba = iscsi_host_priv(shost); 1656 hba = iscsi_host_priv(shost);
1659 else 1657 /* Register the device with cnic if not already done so */
1658 bnx2i_register_device(hba);
1659 } else
1660 /* 1660 /*
1661 * check if the given destination can be reached through 1661 * check if the given destination can be reached through
1662 * a iscsi capable NetXtreme2 device 1662 * a iscsi capable NetXtreme2 device
1663 */ 1663 */
1664 hba = bnx2i_check_route(dst_addr); 1664 hba = bnx2i_check_route(dst_addr);
1665
1665 if (!hba) { 1666 if (!hba) {
1666 rc = -ENOMEM; 1667 rc = -ENOMEM;
1667 goto check_busy; 1668 goto check_busy;
@@ -1681,8 +1682,6 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1681 goto net_if_down; 1682 goto net_if_down;
1682 } 1683 }
1683 1684
1684 bnx2i_ep->state = EP_STATE_IDLE;
1685 bnx2i_ep->ep_iscsi_cid = (u16) -1;
1686 bnx2i_ep->num_active_cmds = 0; 1685 bnx2i_ep->num_active_cmds = 0;
1687 iscsi_cid = bnx2i_alloc_iscsi_cid(hba); 1686 iscsi_cid = bnx2i_alloc_iscsi_cid(hba);
1688 if (iscsi_cid == -1) { 1687 if (iscsi_cid == -1) {