diff options
author | Chris Leech <christopher.leech@intel.com> | 2009-08-25 16:59:24 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-10 13:07:31 -0400 |
commit | af7f85d95a34b04f5cf8c3b8c2d4cdd179dc1e19 (patch) | |
tree | 59e0eae4a609f89dac651c5d59a797b44b9ce773 /drivers/scsi/fcoe | |
parent | 36eb7fc872bdd7f7443ce24a718784bfa567f6c7 (diff) |
[SCSI] fcoe: interface changes to fcoe_if_create and fcoe_if_destroy
By passing in the parent device instead of assuming the netdev is what
should be used, fcoe_if_create becomes usable for NPIV vports as well.
You still need a netdev, because that's how FCoE works. Also removed some
duplicate checks from fcoe_if_create that are already in fcoe_create.
fcoe_if_destroy needs to take an lport as it's only argument, not a netdev.
That removes the 1:1 netdev:lport assumption from the destroy path.
Signed-off-by: Chris Leech <christopher.leech@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 113 |
1 files changed, 48 insertions, 65 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index e481882a3e8f..749279698137 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. | 2 | * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms and conditions of the GNU General Public License, | 5 | * under the terms and conditions of the GNU General Public License, |
@@ -506,30 +506,20 @@ skip_oem: | |||
506 | 506 | ||
507 | /** | 507 | /** |
508 | * fcoe_if_destroy() - FCoE software HBA tear-down function | 508 | * fcoe_if_destroy() - FCoE software HBA tear-down function |
509 | * @netdev: ptr to the associated net_device | 509 | * @lport: fc_lport to destroy |
510 | * | ||
511 | * Returns: 0 if link is OK for use by FCoE. | ||
512 | */ | 510 | */ |
513 | static int fcoe_if_destroy(struct net_device *netdev) | 511 | static void fcoe_if_destroy(struct fc_lport *lport) |
514 | { | 512 | { |
515 | struct fc_lport *lp = NULL; | 513 | struct fcoe_softc *fc = lport_priv(lport); |
516 | struct fcoe_softc *fc; | 514 | struct net_device *netdev = fc->netdev; |
517 | |||
518 | BUG_ON(!netdev); | ||
519 | 515 | ||
520 | FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); | 516 | FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); |
521 | 517 | ||
522 | lp = fcoe_hostlist_lookup(netdev); | ||
523 | if (!lp) | ||
524 | return -ENODEV; | ||
525 | |||
526 | fc = lport_priv(lp); | ||
527 | |||
528 | /* Logout of the fabric */ | 518 | /* Logout of the fabric */ |
529 | fc_fabric_logoff(lp); | 519 | fc_fabric_logoff(lport); |
530 | 520 | ||
531 | /* Remove the instance from fcoe's list */ | 521 | /* Remove the instance from fcoe's list */ |
532 | fcoe_hostlist_remove(lp); | 522 | fcoe_hostlist_remove(lport); |
533 | 523 | ||
534 | /* clean up netdev configurations */ | 524 | /* clean up netdev configurations */ |
535 | fcoe_netdev_cleanup(fc); | 525 | fcoe_netdev_cleanup(fc); |
@@ -538,33 +528,31 @@ static int fcoe_if_destroy(struct net_device *netdev) | |||
538 | fcoe_ctlr_destroy(&fc->ctlr); | 528 | fcoe_ctlr_destroy(&fc->ctlr); |
539 | 529 | ||
540 | /* Free queued packets for the per-CPU receive threads */ | 530 | /* Free queued packets for the per-CPU receive threads */ |
541 | fcoe_percpu_clean(lp); | 531 | fcoe_percpu_clean(lport); |
542 | 532 | ||
543 | /* Cleanup the fc_lport */ | 533 | /* Cleanup the fc_lport */ |
544 | fc_lport_destroy(lp); | 534 | fc_lport_destroy(lport); |
545 | fc_fcp_destroy(lp); | 535 | fc_fcp_destroy(lport); |
546 | 536 | ||
547 | /* Detach from the scsi-ml */ | 537 | /* Detach from the scsi-ml */ |
548 | fc_remove_host(lp->host); | 538 | fc_remove_host(lport->host); |
549 | scsi_remove_host(lp->host); | 539 | scsi_remove_host(lport->host); |
550 | 540 | ||
551 | /* There are no more rports or I/O, free the EM */ | 541 | /* There are no more rports or I/O, free the EM */ |
552 | fc_exch_mgr_free(lp); | 542 | fc_exch_mgr_free(lport); |
553 | 543 | ||
554 | /* Free existing skbs */ | 544 | /* Free existing skbs */ |
555 | fcoe_clean_pending_queue(lp); | 545 | fcoe_clean_pending_queue(lport); |
556 | 546 | ||
557 | /* Stop the timer */ | 547 | /* Stop the timer */ |
558 | del_timer_sync(&fc->timer); | 548 | del_timer_sync(&fc->timer); |
559 | 549 | ||
560 | /* Free memory used by statistical counters */ | 550 | /* Free memory used by statistical counters */ |
561 | fc_lport_free_stats(lp); | 551 | fc_lport_free_stats(lport); |
562 | 552 | ||
563 | /* Release the net_device and Scsi_Host */ | 553 | /* Release the net_device and Scsi_Host */ |
564 | dev_put(netdev); | 554 | dev_put(netdev); |
565 | scsi_host_put(lp->host); | 555 | scsi_host_put(lport->host); |
566 | |||
567 | return 0; | ||
568 | } | 556 | } |
569 | 557 | ||
570 | /* | 558 | /* |
@@ -612,38 +600,35 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = { | |||
612 | /** | 600 | /** |
613 | * fcoe_if_create() - this function creates the fcoe interface | 601 | * fcoe_if_create() - this function creates the fcoe interface |
614 | * @netdev: pointer the associated netdevice | 602 | * @netdev: pointer the associated netdevice |
603 | * @parent: device pointer to be the parent in sysfs for the SCSI host | ||
615 | * | 604 | * |
616 | * Creates fc_lport struct and scsi_host for lport, configures lport | 605 | * Creates fc_lport struct and scsi_host for lport, configures lport |
617 | * and starts fabric login. | 606 | * and starts fabric login. |
618 | * | 607 | * |
619 | * Returns : 0 on success | 608 | * Returns : The allocated fc_lport or an error pointer |
620 | */ | 609 | */ |
621 | static int fcoe_if_create(struct net_device *netdev) | 610 | static struct fc_lport *fcoe_if_create(struct net_device *netdev, |
611 | struct device *parent) | ||
622 | { | 612 | { |
623 | int rc; | 613 | int rc; |
624 | struct fc_lport *lp = NULL; | 614 | struct fc_lport *lport = NULL; |
625 | struct fcoe_softc *fc; | 615 | struct fcoe_softc *fc; |
626 | struct Scsi_Host *shost; | 616 | struct Scsi_Host *shost; |
627 | 617 | ||
628 | BUG_ON(!netdev); | ||
629 | |||
630 | FCOE_NETDEV_DBG(netdev, "Create Interface\n"); | 618 | FCOE_NETDEV_DBG(netdev, "Create Interface\n"); |
631 | 619 | ||
632 | lp = fcoe_hostlist_lookup(netdev); | ||
633 | if (lp) | ||
634 | return -EEXIST; | ||
635 | |||
636 | shost = libfc_host_alloc(&fcoe_shost_template, | 620 | shost = libfc_host_alloc(&fcoe_shost_template, |
637 | sizeof(struct fcoe_softc)); | 621 | sizeof(struct fcoe_softc)); |
638 | if (!shost) { | 622 | if (!shost) { |
639 | FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n"); | 623 | FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n"); |
640 | return -ENOMEM; | 624 | rc = -ENOMEM; |
625 | goto out; | ||
641 | } | 626 | } |
642 | lp = shost_priv(shost); | 627 | lport = shost_priv(shost); |
643 | fc = lport_priv(lp); | 628 | fc = lport_priv(lport); |
644 | 629 | ||
645 | /* configure fc_lport, e.g., em */ | 630 | /* configure fc_lport, e.g., em */ |
646 | rc = fcoe_lport_config(lp); | 631 | rc = fcoe_lport_config(lport); |
647 | if (rc) { | 632 | if (rc) { |
648 | FCOE_NETDEV_DBG(netdev, "Could not configure lport for the " | 633 | FCOE_NETDEV_DBG(netdev, "Could not configure lport for the " |
649 | "interface\n"); | 634 | "interface\n"); |
@@ -658,7 +643,7 @@ static int fcoe_if_create(struct net_device *netdev) | |||
658 | fc->ctlr.update_mac = fcoe_update_src_mac; | 643 | fc->ctlr.update_mac = fcoe_update_src_mac; |
659 | 644 | ||
660 | /* configure lport network properties */ | 645 | /* configure lport network properties */ |
661 | rc = fcoe_netdev_config(lp, netdev); | 646 | rc = fcoe_netdev_config(lport, netdev); |
662 | if (rc) { | 647 | if (rc) { |
663 | FCOE_NETDEV_DBG(netdev, "Could not configure netdev for the " | 648 | FCOE_NETDEV_DBG(netdev, "Could not configure netdev for the " |
664 | "interface\n"); | 649 | "interface\n"); |
@@ -666,7 +651,7 @@ static int fcoe_if_create(struct net_device *netdev) | |||
666 | } | 651 | } |
667 | 652 | ||
668 | /* configure lport scsi host properties */ | 653 | /* configure lport scsi host properties */ |
669 | rc = fcoe_shost_config(lp, shost, &netdev->dev); | 654 | rc = fcoe_shost_config(lport, shost, parent); |
670 | if (rc) { | 655 | if (rc) { |
671 | FCOE_NETDEV_DBG(netdev, "Could not configure shost for the " | 656 | FCOE_NETDEV_DBG(netdev, "Could not configure shost for the " |
672 | "interface\n"); | 657 | "interface\n"); |
@@ -674,7 +659,7 @@ static int fcoe_if_create(struct net_device *netdev) | |||
674 | } | 659 | } |
675 | 660 | ||
676 | /* Initialize the library */ | 661 | /* Initialize the library */ |
677 | rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ); | 662 | rc = fcoe_libfc_config(lport, &fcoe_libfc_fcn_templ); |
678 | if (rc) { | 663 | if (rc) { |
679 | FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the " | 664 | FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the " |
680 | "interface\n"); | 665 | "interface\n"); |
@@ -689,7 +674,7 @@ static int fcoe_if_create(struct net_device *netdev) | |||
689 | */ | 674 | */ |
690 | write_lock(&fcoe_hostlist_lock); | 675 | write_lock(&fcoe_hostlist_lock); |
691 | /* lport exch manager allocation */ | 676 | /* lport exch manager allocation */ |
692 | rc = fcoe_em_config(lp); | 677 | rc = fcoe_em_config(lport); |
693 | if (rc) { | 678 | if (rc) { |
694 | FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the " | 679 | FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the " |
695 | "interface\n"); | 680 | "interface\n"); |
@@ -697,27 +682,28 @@ static int fcoe_if_create(struct net_device *netdev) | |||
697 | } | 682 | } |
698 | 683 | ||
699 | /* add to lports list */ | 684 | /* add to lports list */ |
700 | fcoe_hostlist_add(lp); | 685 | fcoe_hostlist_add(lport); |
701 | write_unlock(&fcoe_hostlist_lock); | 686 | write_unlock(&fcoe_hostlist_lock); |
702 | 687 | ||
703 | lp->boot_time = jiffies; | 688 | lport->boot_time = jiffies; |
704 | 689 | ||
705 | fc_fabric_login(lp); | 690 | fc_fabric_login(lport); |
706 | 691 | ||
707 | if (!fcoe_link_ok(lp)) | 692 | if (!fcoe_link_ok(lport)) |
708 | fcoe_ctlr_link_up(&fc->ctlr); | 693 | fcoe_ctlr_link_up(&fc->ctlr); |
709 | 694 | ||
710 | dev_hold(netdev); | 695 | dev_hold(netdev); |
711 | 696 | ||
712 | return rc; | 697 | return lport; |
713 | 698 | ||
714 | out_lp_destroy: | 699 | out_lp_destroy: |
715 | fc_exch_mgr_free(lp); | 700 | fc_exch_mgr_free(lport); |
716 | out_netdev_cleanup: | 701 | out_netdev_cleanup: |
717 | fcoe_netdev_cleanup(fc); | 702 | fcoe_netdev_cleanup(fc); |
718 | out_host_put: | 703 | out_host_put: |
719 | scsi_host_put(lp->host); | 704 | scsi_host_put(lport->host); |
720 | return rc; | 705 | out: |
706 | return ERR_PTR(rc); | ||
721 | } | 707 | } |
722 | 708 | ||
723 | /** | 709 | /** |
@@ -1616,8 +1602,9 @@ static int fcoe_ethdrv_put(const struct net_device *netdev) | |||
1616 | */ | 1602 | */ |
1617 | static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | 1603 | static int fcoe_destroy(const char *buffer, struct kernel_param *kp) |
1618 | { | 1604 | { |
1619 | int rc; | ||
1620 | struct net_device *netdev; | 1605 | struct net_device *netdev; |
1606 | struct fc_lport *lport; | ||
1607 | int rc; | ||
1621 | 1608 | ||
1622 | netdev = fcoe_if_to_netdev(buffer); | 1609 | netdev = fcoe_if_to_netdev(buffer); |
1623 | if (!netdev) { | 1610 | if (!netdev) { |
@@ -1625,17 +1612,12 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | |||
1625 | goto out_nodev; | 1612 | goto out_nodev; |
1626 | } | 1613 | } |
1627 | /* look for existing lport */ | 1614 | /* look for existing lport */ |
1628 | if (!fcoe_hostlist_lookup(netdev)) { | 1615 | lport = fcoe_hostlist_lookup(netdev); |
1616 | if (!lport) { | ||
1629 | rc = -ENODEV; | 1617 | rc = -ENODEV; |
1630 | goto out_putdev; | 1618 | goto out_putdev; |
1631 | } | 1619 | } |
1632 | rc = fcoe_if_destroy(netdev); | 1620 | fcoe_if_destroy(lport); |
1633 | if (rc) { | ||
1634 | printk(KERN_ERR "fcoe: Failed to destroy interface (%s)\n", | ||
1635 | netdev->name); | ||
1636 | rc = -EIO; | ||
1637 | goto out_putdev; | ||
1638 | } | ||
1639 | fcoe_ethdrv_put(netdev); | 1621 | fcoe_ethdrv_put(netdev); |
1640 | rc = 0; | 1622 | rc = 0; |
1641 | out_putdev: | 1623 | out_putdev: |
@@ -1654,6 +1636,7 @@ out_nodev: | |||
1654 | static int fcoe_create(const char *buffer, struct kernel_param *kp) | 1636 | static int fcoe_create(const char *buffer, struct kernel_param *kp) |
1655 | { | 1637 | { |
1656 | int rc; | 1638 | int rc; |
1639 | struct fc_lport *lport; | ||
1657 | struct net_device *netdev; | 1640 | struct net_device *netdev; |
1658 | 1641 | ||
1659 | netdev = fcoe_if_to_netdev(buffer); | 1642 | netdev = fcoe_if_to_netdev(buffer); |
@@ -1668,8 +1651,8 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
1668 | } | 1651 | } |
1669 | fcoe_ethdrv_get(netdev); | 1652 | fcoe_ethdrv_get(netdev); |
1670 | 1653 | ||
1671 | rc = fcoe_if_create(netdev); | 1654 | lport = fcoe_if_create(netdev, &netdev->dev); |
1672 | if (rc) { | 1655 | if (IS_ERR(lport)) { |
1673 | printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", | 1656 | printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", |
1674 | netdev->name); | 1657 | netdev->name); |
1675 | fcoe_ethdrv_put(netdev); | 1658 | fcoe_ethdrv_put(netdev); |
@@ -1926,7 +1909,7 @@ static void __exit fcoe_exit(void) | |||
1926 | 1909 | ||
1927 | /* releases the associated fcoe hosts */ | 1910 | /* releases the associated fcoe hosts */ |
1928 | list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) | 1911 | list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) |
1929 | fcoe_if_destroy(fc->netdev); | 1912 | fcoe_if_destroy(fc->ctlr.lp); |
1930 | 1913 | ||
1931 | unregister_hotcpu_notifier(&fcoe_cpu_notifier); | 1914 | unregister_hotcpu_notifier(&fcoe_cpu_notifier); |
1932 | 1915 | ||