aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/fcoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r--drivers/scsi/fcoe/fcoe.c71
1 files changed, 64 insertions, 7 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 4bb42e19d537..fe30b1b65e1d 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -41,6 +41,7 @@
41 41
42#include <scsi/fc/fc_encaps.h> 42#include <scsi/fc/fc_encaps.h>
43#include <scsi/fc/fc_fip.h> 43#include <scsi/fc/fc_fip.h>
44#include <scsi/fc/fc_fcoe.h>
44 45
45#include <scsi/libfc.h> 46#include <scsi/libfc.h>
46#include <scsi/fc_frame.h> 47#include <scsi/fc_frame.h>
@@ -150,6 +151,21 @@ static int fcoe_vport_create(struct fc_vport *, bool disabled);
150static int fcoe_vport_disable(struct fc_vport *, bool disable); 151static int fcoe_vport_disable(struct fc_vport *, bool disable);
151static void fcoe_set_vport_symbolic_name(struct fc_vport *); 152static void fcoe_set_vport_symbolic_name(struct fc_vport *);
152static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); 153static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *);
154static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *);
155static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *);
156
157static struct fcoe_sysfs_function_template fcoe_sysfs_templ = {
158 .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode,
159 .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
160 .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
161 .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
162 .get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb,
163 .get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb,
164 .get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb,
165
166 .get_fcoe_fcf_selected = fcoe_fcf_get_selected,
167 .get_fcoe_fcf_vlan_id = fcoe_fcf_get_vlan_id,
168};
153 169
154static struct libfc_function_template fcoe_libfc_fcn_templ = { 170static struct libfc_function_template fcoe_libfc_fcn_templ = {
155 .frame_send = fcoe_xmit, 171 .frame_send = fcoe_xmit,
@@ -366,6 +382,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe,
366static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, 382static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
367 enum fip_state fip_mode) 383 enum fip_state fip_mode)
368{ 384{
385 struct fcoe_ctlr_device *ctlr_dev;
369 struct fcoe_ctlr *ctlr; 386 struct fcoe_ctlr *ctlr;
370 struct fcoe_interface *fcoe; 387 struct fcoe_interface *fcoe;
371 int size; 388 int size;
@@ -379,14 +396,17 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
379 } 396 }
380 397
381 size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface); 398 size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface);
382 ctlr = kzalloc(size, GFP_KERNEL); 399 ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &fcoe_sysfs_templ,
383 fcoe = fcoe_ctlr_priv(ctlr); 400 size);
384 if (!fcoe) { 401 if (!ctlr_dev) {
385 FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); 402 FCOE_DBG("Failed to add fcoe_ctlr_device\n");
386 fcoe = ERR_PTR(-ENOMEM); 403 fcoe = ERR_PTR(-ENOMEM);
387 goto out_putmod; 404 goto out_putmod;
388 } 405 }
389 406
407 ctlr = fcoe_ctlr_device_priv(ctlr_dev);
408 fcoe = fcoe_ctlr_priv(ctlr);
409
390 dev_hold(netdev); 410 dev_hold(netdev);
391 411
392 /* 412 /*
@@ -400,6 +420,7 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
400 err = fcoe_interface_setup(fcoe, netdev); 420 err = fcoe_interface_setup(fcoe, netdev);
401 if (err) { 421 if (err) {
402 fcoe_ctlr_destroy(ctlr); 422 fcoe_ctlr_destroy(ctlr);
423 fcoe_ctlr_device_delete(ctlr_dev);
403 dev_put(netdev); 424 dev_put(netdev);
404 fcoe = ERR_PTR(err); 425 fcoe = ERR_PTR(err);
405 goto out_putmod; 426 goto out_putmod;
@@ -466,6 +487,7 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
466{ 487{
467 struct net_device *netdev = fcoe->netdev; 488 struct net_device *netdev = fcoe->netdev;
468 struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); 489 struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe);
490 struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip);
469 491
470 rtnl_lock(); 492 rtnl_lock();
471 if (!fcoe->removed) 493 if (!fcoe->removed)
@@ -476,7 +498,7 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
476 /* tear-down the FCoE controller */ 498 /* tear-down the FCoE controller */
477 fcoe_ctlr_destroy(fip); 499 fcoe_ctlr_destroy(fip);
478 scsi_host_put(fip->lp->host); 500 scsi_host_put(fip->lp->host);
479 kfree(fip); 501 fcoe_ctlr_device_delete(ctlr_dev);
480 dev_put(netdev); 502 dev_put(netdev);
481 module_put(THIS_MODULE); 503 module_put(THIS_MODULE);
482} 504}
@@ -2196,6 +2218,7 @@ static void fcoe_dcb_create(struct fcoe_interface *fcoe)
2196static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) 2218static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
2197{ 2219{
2198 int rc = 0; 2220 int rc = 0;
2221 struct fcoe_ctlr_device *ctlr_dev;
2199 struct fcoe_ctlr *ctlr; 2222 struct fcoe_ctlr *ctlr;
2200 struct fcoe_interface *fcoe; 2223 struct fcoe_interface *fcoe;
2201 struct fc_lport *lport; 2224 struct fc_lport *lport;
@@ -2216,8 +2239,8 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
2216 } 2239 }
2217 2240
2218 ctlr = fcoe_to_ctlr(fcoe); 2241 ctlr = fcoe_to_ctlr(fcoe);
2219 2242 ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr);
2220 lport = fcoe_if_create(fcoe, &netdev->dev, 0); 2243 lport = fcoe_if_create(fcoe, &ctlr_dev->dev, 0);
2221 if (IS_ERR(lport)) { 2244 if (IS_ERR(lport)) {
2222 printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", 2245 printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
2223 netdev->name); 2246 netdev->name);
@@ -2768,6 +2791,40 @@ static void fcoe_get_lesb(struct fc_lport *lport,
2768 __fcoe_get_lesb(lport, fc_lesb, netdev); 2791 __fcoe_get_lesb(lport, fc_lesb, netdev);
2769} 2792}
2770 2793
2794static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
2795{
2796 struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
2797 struct net_device *netdev = fcoe_netdev(fip->lp);
2798 struct fcoe_fc_els_lesb *fcoe_lesb;
2799 struct fc_els_lesb fc_lesb;
2800
2801 __fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
2802 fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
2803
2804 ctlr_dev->lesb.lesb_link_fail =
2805 ntohl(fcoe_lesb->lesb_link_fail);
2806 ctlr_dev->lesb.lesb_vlink_fail =
2807 ntohl(fcoe_lesb->lesb_vlink_fail);
2808 ctlr_dev->lesb.lesb_miss_fka =
2809 ntohl(fcoe_lesb->lesb_miss_fka);
2810 ctlr_dev->lesb.lesb_symb_err =
2811 ntohl(fcoe_lesb->lesb_symb_err);
2812 ctlr_dev->lesb.lesb_err_block =
2813 ntohl(fcoe_lesb->lesb_err_block);
2814 ctlr_dev->lesb.lesb_fcs_error =
2815 ntohl(fcoe_lesb->lesb_fcs_error);
2816}
2817
2818static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev)
2819{
2820 struct fcoe_ctlr_device *ctlr_dev =
2821 fcoe_fcf_dev_to_ctlr_dev(fcf_dev);
2822 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
2823 struct fcoe_interface *fcoe = fcoe_ctlr_priv(ctlr);
2824
2825 fcf_dev->vlan_id = vlan_dev_vlan_id(fcoe->netdev);
2826}
2827
2771/** 2828/**
2772 * fcoe_set_port_id() - Callback from libfc when Port_ID is set. 2829 * fcoe_set_port_id() - Callback from libfc when Port_ID is set.
2773 * @lport: the local port 2830 * @lport: the local port