aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i/bnx2i_init.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-23 14:13:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-23 14:13:11 -0400
commitd4e06701b89286a306b31e20ec69a904fae374a1 (patch)
treef6adefd65b021ccddb7655109ea8b9ab4e714292 /drivers/scsi/bnx2i/bnx2i_init.c
parente4980371059ca4a81ccdcb4381c41af8869ca711 (diff)
parent87045b033a62777337ae4aa62834876da09b5fb5 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (77 commits) [SCSI] fix crash in scsi_dispatch_cmd() [SCSI] sr: check_events() ignore GET_EVENT when TUR says otherwise [SCSI] bnx2i: Fixed kernel panic due to illegal usage of sc->request->cpu [SCSI] bfa: Update the driver version to 3.0.2.1 [SCSI] bfa: Driver and BSG enhancements. [SCSI] bfa: Added support to query PHY. [SCSI] bfa: Added HBA diagnostics support. [SCSI] bfa: Added support for flash configuration [SCSI] bfa: Added support to obtain SFP info. [SCSI] bfa: Added support for CEE info and stats query. [SCSI] bfa: Extend BSG interface. [SCSI] bfa: FCS bug fixes. [SCSI] bfa: DMA memory allocation enhancement. [SCSI] bfa: Brocade-1860 Fabric Adapter vHBA support. [SCSI] bfa: Brocade-1860 Fabric Adapter PLL init fixes. [SCSI] bfa: Added Fabric Assigned Address(FAA) support [SCSI] bfa: IOC bug fixes. [SCSI] bfa: Enable ASIC block configuration and query. [SCSI] bnx2i: Updated copyright and bump version [SCSI] bnx2i: Modified to skip CNIC registration if iSCSI is not supported ... Fix up some trivial conflicts in: - drivers/scsi/bnx2fc/{bnx2fc.h,bnx2fc_fcoe.c}: Crazy broadcom version number conflicts - drivers/target/tcm_fc/tfc_cmd.c Just trivial cleanups done on adjacent lines
Diffstat (limited to 'drivers/scsi/bnx2i/bnx2i_init.c')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c153
1 files changed, 135 insertions, 18 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index 6973413e91ec..1a947f1b9729 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -1,6 +1,6 @@
1/* bnx2i.c: Broadcom NetXtreme II iSCSI driver. 1/* bnx2i.c: Broadcom NetXtreme II iSCSI driver.
2 * 2 *
3 * Copyright (c) 2006 - 2010 Broadcom Corporation 3 * Copyright (c) 2006 - 2011 Broadcom Corporation
4 * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved. 4 * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
5 * Copyright (c) 2007, 2008 Mike Christie 5 * Copyright (c) 2007, 2008 Mike Christie
6 * 6 *
@@ -18,8 +18,8 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list);
18static u32 adapter_count; 18static u32 adapter_count;
19 19
20#define DRV_MODULE_NAME "bnx2i" 20#define DRV_MODULE_NAME "bnx2i"
21#define DRV_MODULE_VERSION "2.6.2.3" 21#define DRV_MODULE_VERSION "2.7.0.3"
22#define DRV_MODULE_RELDATE "Dec 31, 2010" 22#define DRV_MODULE_RELDATE "Jun 15, 2011"
23 23
24static char version[] __devinitdata = 24static char version[] __devinitdata =
25 "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \ 25 "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
@@ -40,7 +40,7 @@ unsigned int event_coal_min = 24;
40module_param(event_coal_min, int, 0664); 40module_param(event_coal_min, int, 0664);
41MODULE_PARM_DESC(event_coal_min, "Event Coalescing Minimum Commands"); 41MODULE_PARM_DESC(event_coal_min, "Event Coalescing Minimum Commands");
42 42
43unsigned int event_coal_div = 1; 43unsigned int event_coal_div = 2;
44module_param(event_coal_div, int, 0664); 44module_param(event_coal_div, int, 0664);
45MODULE_PARM_DESC(event_coal_div, "Event Coalescing Divide Factor"); 45MODULE_PARM_DESC(event_coal_div, "Event Coalescing Divide Factor");
46 46
@@ -66,6 +66,15 @@ MODULE_PARM_DESC(rq_size, "Configure RQ size");
66 66
67u64 iscsi_error_mask = 0x00; 67u64 iscsi_error_mask = 0x00;
68 68
69DEFINE_PER_CPU(struct bnx2i_percpu_s, bnx2i_percpu);
70
71static int bnx2i_cpu_callback(struct notifier_block *nfb,
72 unsigned long action, void *hcpu);
73/* notification function for CPU hotplug events */
74static struct notifier_block bnx2i_cpu_notifier = {
75 .notifier_call = bnx2i_cpu_callback,
76};
77
69 78
70/** 79/**
71 * bnx2i_identify_device - identifies NetXtreme II device type 80 * bnx2i_identify_device - identifies NetXtreme II device type
@@ -172,21 +181,14 @@ void bnx2i_start(void *handle)
172 struct bnx2i_hba *hba = handle; 181 struct bnx2i_hba *hba = handle;
173 int i = HZ; 182 int i = HZ;
174 183
175 if (!hba->cnic->max_iscsi_conn) { 184 /*
176 printk(KERN_ALERT "bnx2i: dev %s does not support " 185 * We should never register devices that don't support iSCSI
177 "iSCSI\n", hba->netdev->name); 186 * (see bnx2i_init_one), so something is wrong if we try to
187 * start a iSCSI adapter on hardware with 0 supported iSCSI
188 * connections
189 */
190 BUG_ON(!hba->cnic->max_iscsi_conn);
178 191
179 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
180 mutex_lock(&bnx2i_dev_lock);
181 list_del_init(&hba->link);
182 adapter_count--;
183 hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
184 clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
185 mutex_unlock(&bnx2i_dev_lock);
186 bnx2i_free_hba(hba);
187 }
188 return;
189 }
190 bnx2i_send_fw_iscsi_init_msg(hba); 192 bnx2i_send_fw_iscsi_init_msg(hba);
191 while (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state) && i--) 193 while (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state) && i--)
192 msleep(BNX2I_INIT_POLL_TIME); 194 msleep(BNX2I_INIT_POLL_TIME);
@@ -290,6 +292,13 @@ static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic)
290 int rc; 292 int rc;
291 293
292 mutex_lock(&bnx2i_dev_lock); 294 mutex_lock(&bnx2i_dev_lock);
295 if (!cnic->max_iscsi_conn) {
296 printk(KERN_ALERT "bnx2i: dev %s does not support "
297 "iSCSI\n", hba->netdev->name);
298 rc = -EOPNOTSUPP;
299 goto out;
300 }
301
293 hba->cnic = cnic; 302 hba->cnic = cnic;
294 rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba); 303 rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba);
295 if (!rc) { 304 if (!rc) {
@@ -307,6 +316,7 @@ static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic)
307 else 316 else
308 printk(KERN_ERR "bnx2i dev reg, unknown error, %d\n", rc); 317 printk(KERN_ERR "bnx2i dev reg, unknown error, %d\n", rc);
309 318
319out:
310 mutex_unlock(&bnx2i_dev_lock); 320 mutex_unlock(&bnx2i_dev_lock);
311 321
312 return rc; 322 return rc;
@@ -371,6 +381,91 @@ void bnx2i_ulp_exit(struct cnic_dev *dev)
371 381
372 382
373/** 383/**
384 * bnx2i_percpu_thread_create - Create a receive thread for an
385 * online CPU
386 *
387 * @cpu: cpu index for the online cpu
388 */
389static void bnx2i_percpu_thread_create(unsigned int cpu)
390{
391 struct bnx2i_percpu_s *p;
392 struct task_struct *thread;
393
394 p = &per_cpu(bnx2i_percpu, cpu);
395
396 thread = kthread_create(bnx2i_percpu_io_thread, (void *)p,
397 "bnx2i_thread/%d", cpu);
398 /* bind thread to the cpu */
399 if (likely(!IS_ERR(thread))) {
400 kthread_bind(thread, cpu);
401 p->iothread = thread;
402 wake_up_process(thread);
403 }
404}
405
406
407static void bnx2i_percpu_thread_destroy(unsigned int cpu)
408{
409 struct bnx2i_percpu_s *p;
410 struct task_struct *thread;
411 struct bnx2i_work *work, *tmp;
412
413 /* Prevent any new work from being queued for this CPU */
414 p = &per_cpu(bnx2i_percpu, cpu);
415 spin_lock_bh(&p->p_work_lock);
416 thread = p->iothread;
417 p->iothread = NULL;
418
419 /* Free all work in the list */
420 list_for_each_entry_safe(work, tmp, &p->work_list, list) {
421 list_del_init(&work->list);
422 bnx2i_process_scsi_cmd_resp(work->session,
423 work->bnx2i_conn, &work->cqe);
424 kfree(work);
425 }
426
427 spin_unlock_bh(&p->p_work_lock);
428 if (thread)
429 kthread_stop(thread);
430}
431
432
433/**
434 * bnx2i_cpu_callback - Handler for CPU hotplug events
435 *
436 * @nfb: The callback data block
437 * @action: The event triggering the callback
438 * @hcpu: The index of the CPU that the event is for
439 *
440 * This creates or destroys per-CPU data for iSCSI
441 *
442 * Returns NOTIFY_OK always.
443 */
444static int bnx2i_cpu_callback(struct notifier_block *nfb,
445 unsigned long action, void *hcpu)
446{
447 unsigned cpu = (unsigned long)hcpu;
448
449 switch (action) {
450 case CPU_ONLINE:
451 case CPU_ONLINE_FROZEN:
452 printk(KERN_INFO "bnx2i: CPU %x online: Create Rx thread\n",
453 cpu);
454 bnx2i_percpu_thread_create(cpu);
455 break;
456 case CPU_DEAD:
457 case CPU_DEAD_FROZEN:
458 printk(KERN_INFO "CPU %x offline: Remove Rx thread\n", cpu);
459 bnx2i_percpu_thread_destroy(cpu);
460 break;
461 default:
462 break;
463 }
464 return NOTIFY_OK;
465}
466
467
468/**
374 * bnx2i_mod_init - module init entry point 469 * bnx2i_mod_init - module init entry point
375 * 470 *
376 * initialize any driver wide global data structures such as endpoint pool, 471 * initialize any driver wide global data structures such as endpoint pool,
@@ -380,6 +475,8 @@ void bnx2i_ulp_exit(struct cnic_dev *dev)
380static int __init bnx2i_mod_init(void) 475static int __init bnx2i_mod_init(void)
381{ 476{
382 int err; 477 int err;
478 unsigned cpu = 0;
479 struct bnx2i_percpu_s *p;
383 480
384 printk(KERN_INFO "%s", version); 481 printk(KERN_INFO "%s", version);
385 482
@@ -402,6 +499,20 @@ static int __init bnx2i_mod_init(void)
402 goto unreg_xport; 499 goto unreg_xport;
403 } 500 }
404 501
502 /* Create percpu kernel threads to handle iSCSI I/O completions */
503 for_each_possible_cpu(cpu) {
504 p = &per_cpu(bnx2i_percpu, cpu);
505 INIT_LIST_HEAD(&p->work_list);
506 spin_lock_init(&p->p_work_lock);
507 p->iothread = NULL;
508 }
509
510 for_each_online_cpu(cpu)
511 bnx2i_percpu_thread_create(cpu);
512
513 /* Initialize per CPU interrupt thread */
514 register_hotcpu_notifier(&bnx2i_cpu_notifier);
515
405 return 0; 516 return 0;
406 517
407unreg_xport: 518unreg_xport:
@@ -422,6 +533,7 @@ out:
422static void __exit bnx2i_mod_exit(void) 533static void __exit bnx2i_mod_exit(void)
423{ 534{
424 struct bnx2i_hba *hba; 535 struct bnx2i_hba *hba;
536 unsigned cpu = 0;
425 537
426 mutex_lock(&bnx2i_dev_lock); 538 mutex_lock(&bnx2i_dev_lock);
427 while (!list_empty(&adapter_list)) { 539 while (!list_empty(&adapter_list)) {
@@ -439,6 +551,11 @@ static void __exit bnx2i_mod_exit(void)
439 } 551 }
440 mutex_unlock(&bnx2i_dev_lock); 552 mutex_unlock(&bnx2i_dev_lock);
441 553
554 unregister_hotcpu_notifier(&bnx2i_cpu_notifier);
555
556 for_each_online_cpu(cpu)
557 bnx2i_percpu_thread_destroy(cpu);
558
442 iscsi_unregister_transport(&bnx2i_iscsi_transport); 559 iscsi_unregister_transport(&bnx2i_iscsi_transport);
443 cnic_unregister_driver(CNIC_ULP_ISCSI); 560 cnic_unregister_driver(CNIC_ULP_ISCSI);
444} 561}