diff options
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 71 |
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); | |||
150 | static int fcoe_vport_disable(struct fc_vport *, bool disable); | 151 | static int fcoe_vport_disable(struct fc_vport *, bool disable); |
151 | static void fcoe_set_vport_symbolic_name(struct fc_vport *); | 152 | static void fcoe_set_vport_symbolic_name(struct fc_vport *); |
152 | static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); | 153 | static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); |
154 | static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *); | ||
155 | static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *); | ||
156 | |||
157 | static 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 | ||
154 | static struct libfc_function_template fcoe_libfc_fcn_templ = { | 170 | static 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, | |||
366 | static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, | 382 | static 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) | |||
2196 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | 2218 | static 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 | ||
2794 | static 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 | |||
2818 | static 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 |