diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-23 14:13:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-23 14:13:11 -0400 |
commit | d4e06701b89286a306b31e20ec69a904fae374a1 (patch) | |
tree | f6adefd65b021ccddb7655109ea8b9ab4e714292 /drivers/scsi/bnx2i/bnx2i_init.c | |
parent | e4980371059ca4a81ccdcb4381c41af8869ca711 (diff) | |
parent | 87045b033a62777337ae4aa62834876da09b5fb5 (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.c | 153 |
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); | |||
18 | static u32 adapter_count; | 18 | static 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 | ||
24 | static char version[] __devinitdata = | 24 | static 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; | |||
40 | module_param(event_coal_min, int, 0664); | 40 | module_param(event_coal_min, int, 0664); |
41 | MODULE_PARM_DESC(event_coal_min, "Event Coalescing Minimum Commands"); | 41 | MODULE_PARM_DESC(event_coal_min, "Event Coalescing Minimum Commands"); |
42 | 42 | ||
43 | unsigned int event_coal_div = 1; | 43 | unsigned int event_coal_div = 2; |
44 | module_param(event_coal_div, int, 0664); | 44 | module_param(event_coal_div, int, 0664); |
45 | MODULE_PARM_DESC(event_coal_div, "Event Coalescing Divide Factor"); | 45 | MODULE_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 | ||
67 | u64 iscsi_error_mask = 0x00; | 67 | u64 iscsi_error_mask = 0x00; |
68 | 68 | ||
69 | DEFINE_PER_CPU(struct bnx2i_percpu_s, bnx2i_percpu); | ||
70 | |||
71 | static int bnx2i_cpu_callback(struct notifier_block *nfb, | ||
72 | unsigned long action, void *hcpu); | ||
73 | /* notification function for CPU hotplug events */ | ||
74 | static 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 | ||
319 | out: | ||
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 | */ | ||
389 | static 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 | |||
407 | static 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 | */ | ||
444 | static 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) | |||
380 | static int __init bnx2i_mod_init(void) | 475 | static 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 | ||
407 | unreg_xport: | 518 | unreg_xport: |
@@ -422,6 +533,7 @@ out: | |||
422 | static void __exit bnx2i_mod_exit(void) | 533 | static 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 | } |