aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/fcoe.c
diff options
context:
space:
mode:
authorChris Leech <christopher.leech@intel.com>2009-08-25 17:00:02 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-10 13:07:35 -0400
commit030f4e001f13e0ee80bac1e756013341b1674d10 (patch)
tree042791ba7bc3d9f2543abf33c511034421c97178 /drivers/scsi/fcoe/fcoe.c
parentcb0a6ca81439a9f113d3b46de0953da168a06f6a (diff)
[SCSI] fcoe: fcoe_interface create, destroy and refcounting
Up to this point the fcoe_instance structure was simply kzalloc/kfreed. This patch introduces create and destroy functions as well as kref based reference counting. The create function will grow as the initialization code is moved there. 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/fcoe.c')
-rw-r--r--drivers/scsi/fcoe/fcoe.c97
1 files changed, 78 insertions, 19 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 7f14c633da6f..d1d6b3b8bf5b 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -139,6 +139,58 @@ static struct scsi_host_template fcoe_shost_template = {
139}; 139};
140 140
141/** 141/**
142 * fcoe_interface_create()
143 * @netdev: network interface
144 *
145 * Returns: pointer to a struct fcoe_interface or NULL on error
146 */
147static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev)
148{
149 struct fcoe_interface *fcoe;
150
151 fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL);
152 if (!fcoe) {
153 FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n");
154 return NULL;
155 }
156
157 kref_init(&fcoe->kref);
158 fcoe->netdev = netdev;
159
160 return fcoe;
161}
162
163/**
164 * fcoe_interface_release() - fcoe_port kref release function
165 * @kref: embedded reference count in an fcoe_interface struct
166 */
167static void fcoe_interface_release(struct kref *kref)
168{
169 struct fcoe_interface *fcoe;
170
171 fcoe = container_of(kref, struct fcoe_interface, kref);
172 kfree(fcoe);
173}
174
175/**
176 * fcoe_interface_get()
177 * @fcoe:
178 */
179static inline void fcoe_interface_get(struct fcoe_interface *fcoe)
180{
181 kref_get(&fcoe->kref);
182}
183
184/**
185 * fcoe_interface_put()
186 * @fcoe:
187 */
188static inline void fcoe_interface_put(struct fcoe_interface *fcoe)
189{
190 kref_put(&fcoe->kref, fcoe_interface_release);
191}
192
193/**
142 * fcoe_fip_recv - handle a received FIP frame. 194 * fcoe_fip_recv - handle a received FIP frame.
143 * @skb: the receive skb 195 * @skb: the receive skb
144 * @dev: associated &net_device 196 * @dev: associated &net_device
@@ -558,7 +610,7 @@ static void fcoe_if_destroy(struct fc_lport *lport)
558 /* Release the net_device and Scsi_Host */ 610 /* Release the net_device and Scsi_Host */
559 dev_put(netdev); 611 dev_put(netdev);
560 scsi_host_put(lport->host); 612 scsi_host_put(lport->host);
561 kfree(fcoe); /* TODO, should be refcounted */ 613 fcoe_interface_put(fcoe);
562} 614}
563 615
564/* 616/*
@@ -604,8 +656,8 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = {
604}; 656};
605 657
606/** 658/**
607 * fcoe_if_create() - this function creates the fcoe interface 659 * fcoe_if_create() - this function creates the fcoe port
608 * @netdev: pointer the associated netdevice 660 * @fcoe: fcoe_interface structure to create an fc_lport instance on
609 * @parent: device pointer to be the parent in sysfs for the SCSI host 661 * @parent: device pointer to be the parent in sysfs for the SCSI host
610 * 662 *
611 * Creates fc_lport struct and scsi_host for lport, configures lport 663 * Creates fc_lport struct and scsi_host for lport, configures lport
@@ -613,30 +665,23 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = {
613 * 665 *
614 * Returns : The allocated fc_lport or an error pointer 666 * Returns : The allocated fc_lport or an error pointer
615 */ 667 */
616static struct fc_lport *fcoe_if_create(struct net_device *netdev, 668static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
617 struct device *parent) 669 struct device *parent)
618{ 670{
619 int rc; 671 int rc;
620 struct fc_lport *lport = NULL; 672 struct fc_lport *lport = NULL;
621 struct fcoe_port *port; 673 struct fcoe_port *port;
622 struct fcoe_interface *fcoe;
623 struct Scsi_Host *shost; 674 struct Scsi_Host *shost;
675 struct net_device *netdev = fcoe->netdev;
624 676
625 FCOE_NETDEV_DBG(netdev, "Create Interface\n"); 677 FCOE_NETDEV_DBG(netdev, "Create Interface\n");
626 678
627 fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL);
628 if (!fcoe) {
629 FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n");
630 rc = -ENOMEM;
631 goto out;
632 }
633
634 shost = libfc_host_alloc(&fcoe_shost_template, 679 shost = libfc_host_alloc(&fcoe_shost_template,
635 sizeof(struct fcoe_port)); 680 sizeof(struct fcoe_port));
636 if (!shost) { 681 if (!shost) {
637 FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n"); 682 FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n");
638 rc = -ENOMEM; 683 rc = -ENOMEM;
639 goto out_kfree_port; 684 goto out;
640 } 685 }
641 lport = shost_priv(shost); 686 lport = shost_priv(shost);
642 port = lport_priv(lport); 687 port = lport_priv(lport);
@@ -708,7 +753,7 @@ static struct fc_lport *fcoe_if_create(struct net_device *netdev,
708 fcoe_ctlr_link_up(&fcoe->ctlr); 753 fcoe_ctlr_link_up(&fcoe->ctlr);
709 754
710 dev_hold(netdev); 755 dev_hold(netdev);
711 756 fcoe_interface_get(fcoe);
712 return lport; 757 return lport;
713 758
714out_lp_destroy: 759out_lp_destroy:
@@ -717,8 +762,6 @@ out_netdev_cleanup:
717 fcoe_netdev_cleanup(port); 762 fcoe_netdev_cleanup(port);
718out_host_put: 763out_host_put:
719 scsi_host_put(lport->host); 764 scsi_host_put(lport->host);
720out_kfree_port:
721 kfree(fcoe);
722out: 765out:
723 return ERR_PTR(rc); 766 return ERR_PTR(rc);
724} 767}
@@ -1620,6 +1663,8 @@ static int fcoe_ethdrv_put(const struct net_device *netdev)
1620static int fcoe_destroy(const char *buffer, struct kernel_param *kp) 1663static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
1621{ 1664{
1622 struct net_device *netdev; 1665 struct net_device *netdev;
1666 struct fcoe_interface *fcoe;
1667 struct fcoe_port *port;
1623 struct fc_lport *lport; 1668 struct fc_lport *lport;
1624 int rc; 1669 int rc;
1625 1670
@@ -1634,6 +1679,8 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
1634 rc = -ENODEV; 1679 rc = -ENODEV;
1635 goto out_putdev; 1680 goto out_putdev;
1636 } 1681 }
1682 port = lport_priv(lport);
1683 fcoe = port->fcoe;
1637 fcoe_if_destroy(lport); 1684 fcoe_if_destroy(lport);
1638 fcoe_ethdrv_put(netdev); 1685 fcoe_ethdrv_put(netdev);
1639 rc = 0; 1686 rc = 0;
@@ -1653,6 +1700,7 @@ out_nodev:
1653static int fcoe_create(const char *buffer, struct kernel_param *kp) 1700static int fcoe_create(const char *buffer, struct kernel_param *kp)
1654{ 1701{
1655 int rc; 1702 int rc;
1703 struct fcoe_interface *fcoe;
1656 struct fc_lport *lport; 1704 struct fc_lport *lport;
1657 struct net_device *netdev; 1705 struct net_device *netdev;
1658 1706
@@ -1668,15 +1716,26 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
1668 } 1716 }
1669 fcoe_ethdrv_get(netdev); 1717 fcoe_ethdrv_get(netdev);
1670 1718
1671 lport = fcoe_if_create(netdev, &netdev->dev); 1719 fcoe = fcoe_interface_create(netdev);
1720 if (!fcoe) {
1721 rc = -ENOMEM;
1722 goto out_putdev;
1723 }
1724
1725 lport = fcoe_if_create(fcoe, &netdev->dev);
1672 if (IS_ERR(lport)) { 1726 if (IS_ERR(lport)) {
1673 printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", 1727 printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
1674 netdev->name); 1728 netdev->name);
1675 fcoe_ethdrv_put(netdev); 1729 fcoe_ethdrv_put(netdev);
1676 rc = -EIO; 1730 rc = -EIO;
1677 goto out_putdev; 1731 goto out_free;
1678 } 1732 }
1679 rc = 0; 1733
1734 dev_put(netdev);
1735 return 0;
1736
1737out_free:
1738 fcoe_interface_put(fcoe);
1680out_putdev: 1739out_putdev:
1681 dev_put(netdev); 1740 dev_put(netdev);
1682out_nodev: 1741out_nodev: