Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] fcoe, bnx2fc, libfcoe: SW FCoE and bnx2fc use FCoE Syfs

This patch has the SW FCoE driver and the bnx2fc
driver make use of the new fcoe_sysfs API added
earlier in this patch series.

After this patch a fcoe_ctlr_device is allocated with
private data in this order.

+------------------+ +------------------+
| fcoe_ctlr_device | | fcoe_ctlr_device |
+------------------+ +------------------+
| fcoe_ctlr | | fcoe_ctlr |
+------------------+ +------------------+
| fcoe_interface | | bnx2fc_interface |
+------------------+ +------------------+

libfcoe also takes part in this new model since it
discovers and manages fcoe_fcf instances. The memory
allocation is different for FCFs. I didn't want to
impact libfcoe's fcoe_fcf processing, so this patch
creates fcoe_fcf_device instances for each discovered
fcoe_fcf. The two are paired using a (void * priv)
member of the fcoe_ctlr_device. This allows libfcoe
to continue maintaining its list of fcoe_fcf instances
and simply attaches and detaches them from existing
or new fcoe_fcf_device instances.

Signed-off-by: Robert Love <robert.w.love@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Robert Love and committed by
James Bottomley
8d55e507 9a74e884

+285 -25
+59 -4
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
··· 54 54 static struct libfc_function_template bnx2fc_libfc_fcn_templ; 55 55 static struct scsi_host_template bnx2fc_shost_template; 56 56 static struct fc_function_template bnx2fc_transport_function; 57 + static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ; 57 58 static struct fc_function_template bnx2fc_vport_xport_function; 58 59 static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode); 59 60 static void __bnx2fc_destroy(struct bnx2fc_interface *interface); ··· 89 88 static void bnx2fc_stop(struct bnx2fc_interface *interface); 90 89 static int __init bnx2fc_mod_init(void); 91 90 static void __exit bnx2fc_mod_exit(void); 91 + static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev); 92 92 93 93 unsigned int bnx2fc_debug_level; 94 94 module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR); ··· 118 116 struct net_device *netdev = bnx2fc_netdev(lport); 119 117 120 118 __fcoe_get_lesb(lport, fc_lesb, netdev); 119 + } 120 + 121 + static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev) 122 + { 123 + struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); 124 + struct net_device *netdev = bnx2fc_netdev(fip->lp); 125 + struct fcoe_fc_els_lesb *fcoe_lesb; 126 + struct fc_els_lesb fc_lesb; 127 + 128 + __fcoe_get_lesb(fip->lp, &fc_lesb, netdev); 129 + fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb); 130 + 131 + ctlr_dev->lesb.lesb_link_fail = 132 + ntohl(fcoe_lesb->lesb_link_fail); 133 + ctlr_dev->lesb.lesb_vlink_fail = 134 + ntohl(fcoe_lesb->lesb_vlink_fail); 135 + ctlr_dev->lesb.lesb_miss_fka = 136 + ntohl(fcoe_lesb->lesb_miss_fka); 137 + ctlr_dev->lesb.lesb_symb_err = 138 + ntohl(fcoe_lesb->lesb_symb_err); 139 + ctlr_dev->lesb.lesb_err_block = 140 + ntohl(fcoe_lesb->lesb_err_block); 141 + ctlr_dev->lesb.lesb_fcs_error = 142 + ntohl(fcoe_lesb->lesb_fcs_error); 143 + } 144 + EXPORT_SYMBOL(bnx2fc_ctlr_get_lesb); 145 + 146 + static void bnx2fc_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev) 147 + { 148 + struct fcoe_ctlr_device *ctlr_dev = 149 + fcoe_fcf_dev_to_ctlr_dev(fcf_dev); 150 + struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 151 + struct bnx2fc_interface *fcoe = fcoe_ctlr_priv(ctlr); 152 + 153 + fcf_dev->vlan_id = fcoe->vlan_id; 121 154 } 122 155 123 156 static void bnx2fc_clean_rx_queue(struct fc_lport *lp) ··· 1272 1235 1273 1236 static void bnx2fc_interface_release(struct kref *kref) 1274 1237 { 1238 + struct fcoe_ctlr_device *ctlr_dev; 1275 1239 struct bnx2fc_interface *interface; 1276 1240 struct fcoe_ctlr *ctlr; 1277 1241 struct net_device *netdev; ··· 1281 1243 BNX2FC_MISC_DBG("Interface is being released\n"); 1282 1244 1283 1245 ctlr = bnx2fc_to_ctlr(interface); 1246 + ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr); 1284 1247 netdev = interface->netdev; 1285 1248 1286 1249 /* tear-down FIP controller */ 1287 1250 if (test_and_clear_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags)) 1288 1251 fcoe_ctlr_destroy(ctlr); 1289 1252 1290 - kfree(ctlr); 1253 + fcoe_ctlr_device_delete(ctlr_dev); 1291 1254 1292 1255 dev_put(netdev); 1293 1256 module_put(THIS_MODULE); ··· 1381 1342 struct net_device *netdev, 1382 1343 enum fip_state fip_mode) 1383 1344 { 1345 + struct fcoe_ctlr_device *ctlr_dev; 1384 1346 struct bnx2fc_interface *interface; 1385 1347 struct fcoe_ctlr *ctlr; 1386 1348 int size; 1387 1349 int rc = 0; 1388 1350 1389 1351 size = (sizeof(*interface) + sizeof(struct fcoe_ctlr)); 1390 - ctlr = kzalloc(size, GFP_KERNEL); 1391 - if (!ctlr) { 1352 + ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &bnx2fc_fcoe_sysfs_templ, 1353 + size); 1354 + if (!ctlr_dev) { 1392 1355 printk(KERN_ERR PFX "Unable to allocate interface structure\n"); 1393 1356 return NULL; 1394 1357 } 1358 + ctlr = fcoe_ctlr_device_priv(ctlr_dev); 1395 1359 interface = fcoe_ctlr_priv(ctlr); 1396 1360 dev_hold(netdev); 1397 1361 kref_init(&interface->kref); ··· 1414 1372 1415 1373 fcoe_ctlr_destroy(ctlr); 1416 1374 dev_put(netdev); 1417 - kfree(ctlr); 1375 + fcoe_ctlr_device_delete(ctlr_dev); 1418 1376 return NULL; 1419 1377 } 1420 1378 ··· 2512 2470 2513 2471 module_init(bnx2fc_mod_init); 2514 2472 module_exit(bnx2fc_mod_exit); 2473 + 2474 + static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = { 2475 + .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode, 2476 + .get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb, 2477 + .get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb, 2478 + .get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb, 2479 + .get_fcoe_ctlr_symb_err = bnx2fc_ctlr_get_lesb, 2480 + .get_fcoe_ctlr_err_block = bnx2fc_ctlr_get_lesb, 2481 + .get_fcoe_ctlr_fcs_error = bnx2fc_ctlr_get_lesb, 2482 + 2483 + .get_fcoe_fcf_selected = fcoe_fcf_get_selected, 2484 + .get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id, 2485 + }; 2515 2486 2516 2487 static struct fc_function_template bnx2fc_transport_function = { 2517 2488 .show_host_node_name = 1,
+64 -7
drivers/scsi/fcoe/fcoe.c
··· 41 41 42 42 #include <scsi/fc/fc_encaps.h> 43 43 #include <scsi/fc/fc_fip.h> 44 + #include <scsi/fc/fc_fcoe.h> 44 45 45 46 #include <scsi/libfc.h> 46 47 #include <scsi/fc_frame.h> ··· 151 150 static int fcoe_vport_disable(struct fc_vport *, bool disable); 152 151 static void fcoe_set_vport_symbolic_name(struct fc_vport *); 153 152 static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); 153 + static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *); 154 + static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *); 155 + 156 + static struct fcoe_sysfs_function_template fcoe_sysfs_templ = { 157 + .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode, 158 + .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb, 159 + .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb, 160 + .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb, 161 + .get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb, 162 + .get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb, 163 + .get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb, 164 + 165 + .get_fcoe_fcf_selected = fcoe_fcf_get_selected, 166 + .get_fcoe_fcf_vlan_id = fcoe_fcf_get_vlan_id, 167 + }; 154 168 155 169 static struct libfc_function_template fcoe_libfc_fcn_templ = { 156 170 .frame_send = fcoe_xmit, ··· 382 366 static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, 383 367 enum fip_state fip_mode) 384 368 { 369 + struct fcoe_ctlr_device *ctlr_dev; 385 370 struct fcoe_ctlr *ctlr; 386 371 struct fcoe_interface *fcoe; 387 372 int size; ··· 396 379 } 397 380 398 381 size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface); 399 - ctlr = kzalloc(size, GFP_KERNEL); 400 - fcoe = fcoe_ctlr_priv(ctlr); 401 - if (!fcoe) { 402 - FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); 382 + ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &fcoe_sysfs_templ, 383 + size); 384 + if (!ctlr_dev) { 385 + FCOE_DBG("Failed to add fcoe_ctlr_device\n"); 403 386 fcoe = ERR_PTR(-ENOMEM); 404 387 goto out_putmod; 405 388 } 389 + 390 + ctlr = fcoe_ctlr_device_priv(ctlr_dev); 391 + fcoe = fcoe_ctlr_priv(ctlr); 406 392 407 393 dev_hold(netdev); 408 394 ··· 420 400 err = fcoe_interface_setup(fcoe, netdev); 421 401 if (err) { 422 402 fcoe_ctlr_destroy(ctlr); 403 + fcoe_ctlr_device_delete(ctlr_dev); 423 404 dev_put(netdev); 424 405 fcoe = ERR_PTR(err); 425 406 goto out_putmod; ··· 487 466 { 488 467 struct net_device *netdev = fcoe->netdev; 489 468 struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); 469 + struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); 490 470 491 471 rtnl_lock(); 492 472 if (!fcoe->removed) ··· 498 476 /* tear-down the FCoE controller */ 499 477 fcoe_ctlr_destroy(fip); 500 478 scsi_host_put(fip->lp->host); 501 - kfree(fip); 479 + fcoe_ctlr_device_delete(ctlr_dev); 502 480 dev_put(netdev); 503 481 module_put(THIS_MODULE); 504 482 } ··· 2218 2196 static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) 2219 2197 { 2220 2198 int rc = 0; 2199 + struct fcoe_ctlr_device *ctlr_dev; 2221 2200 struct fcoe_ctlr *ctlr; 2222 2201 struct fcoe_interface *fcoe; 2223 2202 struct fc_lport *lport; ··· 2239 2216 } 2240 2217 2241 2218 ctlr = fcoe_to_ctlr(fcoe); 2242 - 2243 - lport = fcoe_if_create(fcoe, &netdev->dev, 0); 2219 + ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr); 2220 + lport = fcoe_if_create(fcoe, &ctlr_dev->dev, 0); 2244 2221 if (IS_ERR(lport)) { 2245 2222 printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", 2246 2223 netdev->name); ··· 2789 2766 struct net_device *netdev = fcoe_netdev(lport); 2790 2767 2791 2768 __fcoe_get_lesb(lport, fc_lesb, netdev); 2769 + } 2770 + 2771 + static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev) 2772 + { 2773 + struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); 2774 + struct net_device *netdev = fcoe_netdev(fip->lp); 2775 + struct fcoe_fc_els_lesb *fcoe_lesb; 2776 + struct fc_els_lesb fc_lesb; 2777 + 2778 + __fcoe_get_lesb(fip->lp, &fc_lesb, netdev); 2779 + fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb); 2780 + 2781 + ctlr_dev->lesb.lesb_link_fail = 2782 + ntohl(fcoe_lesb->lesb_link_fail); 2783 + ctlr_dev->lesb.lesb_vlink_fail = 2784 + ntohl(fcoe_lesb->lesb_vlink_fail); 2785 + ctlr_dev->lesb.lesb_miss_fka = 2786 + ntohl(fcoe_lesb->lesb_miss_fka); 2787 + ctlr_dev->lesb.lesb_symb_err = 2788 + ntohl(fcoe_lesb->lesb_symb_err); 2789 + ctlr_dev->lesb.lesb_err_block = 2790 + ntohl(fcoe_lesb->lesb_err_block); 2791 + ctlr_dev->lesb.lesb_fcs_error = 2792 + ntohl(fcoe_lesb->lesb_fcs_error); 2793 + } 2794 + 2795 + static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev) 2796 + { 2797 + struct fcoe_ctlr_device *ctlr_dev = 2798 + fcoe_fcf_dev_to_ctlr_dev(fcf_dev); 2799 + struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 2800 + struct fcoe_interface *fcoe = fcoe_ctlr_priv(ctlr); 2801 + 2802 + fcf_dev->vlan_id = vlan_dev_vlan_id(fcoe->netdev); 2792 2803 } 2793 2804 2794 2805 /**
+145 -14
drivers/scsi/fcoe/fcoe_ctlr.c
··· 160 160 } 161 161 EXPORT_SYMBOL(fcoe_ctlr_init); 162 162 163 + static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new) 164 + { 165 + struct fcoe_ctlr *fip = new->fip; 166 + struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); 167 + struct fcoe_fcf_device temp, *fcf_dev; 168 + int rc = 0; 169 + 170 + LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n", 171 + new->fabric_name, new->fcf_mac); 172 + 173 + mutex_lock(&ctlr_dev->lock); 174 + 175 + temp.fabric_name = new->fabric_name; 176 + temp.switch_name = new->switch_name; 177 + temp.fc_map = new->fc_map; 178 + temp.vfid = new->vfid; 179 + memcpy(temp.mac, new->fcf_mac, ETH_ALEN); 180 + temp.priority = new->pri; 181 + temp.fka_period = new->fka_period; 182 + temp.selected = 0; /* default to unselected */ 183 + 184 + fcf_dev = fcoe_fcf_device_add(ctlr_dev, &temp); 185 + if (unlikely(!fcf_dev)) { 186 + rc = -ENOMEM; 187 + goto out; 188 + } 189 + 190 + /* 191 + * The fcoe_sysfs layer can return a CONNECTED fcf that 192 + * has a priv (fcf was never deleted) or a CONNECTED fcf 193 + * that doesn't have a priv (fcf was deleted). However, 194 + * libfcoe will always delete FCFs before trying to add 195 + * them. This is ensured because both recv_adv and 196 + * age_fcfs are protected by the the fcoe_ctlr's mutex. 197 + * This means that we should never get a FCF with a 198 + * non-NULL priv pointer. 199 + */ 200 + BUG_ON(fcf_dev->priv); 201 + 202 + fcf_dev->priv = new; 203 + new->fcf_dev = fcf_dev; 204 + 205 + list_add(&new->list, &fip->fcfs); 206 + fip->fcf_count++; 207 + 208 + out: 209 + mutex_unlock(&ctlr_dev->lock); 210 + return rc; 211 + } 212 + 213 + static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new) 214 + { 215 + struct fcoe_ctlr *fip = new->fip; 216 + struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); 217 + struct fcoe_fcf_device *fcf_dev; 218 + 219 + list_del(&new->list); 220 + fip->fcf_count--; 221 + 222 + mutex_lock(&ctlr_dev->lock); 223 + 224 + fcf_dev = fcoe_fcf_to_fcf_dev(new); 225 + WARN_ON(!fcf_dev); 226 + new->fcf_dev = NULL; 227 + fcoe_fcf_device_delete(fcf_dev); 228 + kfree(new); 229 + 230 + mutex_unlock(&ctlr_dev->lock); 231 + } 232 + 163 233 /** 164 234 * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller 165 235 * @fip: The FCoE controller whose FCFs are to be reset ··· 243 173 244 174 fip->sel_fcf = NULL; 245 175 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { 246 - list_del(&fcf->list); 247 - kfree(fcf); 176 + fcoe_sysfs_fcf_del(fcf); 248 177 } 249 - fip->fcf_count = 0; 178 + WARN_ON(fip->fcf_count); 179 + 250 180 fip->sel_time = 0; 251 181 } 252 182 ··· 787 717 unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD); 788 718 unsigned long deadline; 789 719 unsigned long sel_time = 0; 720 + struct list_head del_list; 790 721 struct fcoe_dev_stats *stats; 722 + 723 + INIT_LIST_HEAD(&del_list); 791 724 792 725 stats = per_cpu_ptr(fip->lp->dev_stats, get_cpu()); 793 726 ··· 812 739 if (time_after_eq(jiffies, deadline)) { 813 740 if (fip->sel_fcf == fcf) 814 741 fip->sel_fcf = NULL; 742 + /* 743 + * Move to delete list so we can call 744 + * fcoe_sysfs_fcf_del (which can sleep) 745 + * after the put_cpu(). 746 + */ 815 747 list_del(&fcf->list); 816 - WARN_ON(!fip->fcf_count); 817 - fip->fcf_count--; 818 - kfree(fcf); 748 + list_add(&fcf->list, &del_list); 819 749 stats->VLinkFailureCount++; 820 750 } else { 821 751 if (time_after(next_timer, deadline)) ··· 829 753 } 830 754 } 831 755 put_cpu(); 756 + 757 + list_for_each_entry_safe(fcf, next, &del_list, list) { 758 + /* Removes fcf from current list */ 759 + fcoe_sysfs_fcf_del(fcf); 760 + } 761 + 832 762 if (sel_time && !fip->sel_fcf && !fip->sel_time) { 833 763 sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY); 834 764 fip->sel_time = sel_time; ··· 985 903 { 986 904 struct fcoe_fcf *fcf; 987 905 struct fcoe_fcf new; 988 - struct fcoe_fcf *found; 989 906 unsigned long sol_tov = msecs_to_jiffies(FCOE_CTRL_SOL_TOV); 990 907 int first = 0; 991 908 int mtu_valid; 909 + int found = 0; 910 + int rc = 0; 992 911 993 912 if (fcoe_ctlr_parse_adv(fip, skb, &new)) 994 913 return; 995 914 996 915 mutex_lock(&fip->ctlr_mutex); 997 916 first = list_empty(&fip->fcfs); 998 - found = NULL; 999 917 list_for_each_entry(fcf, &fip->fcfs, list) { 1000 918 if (fcf->switch_name == new.switch_name && 1001 919 fcf->fabric_name == new.fabric_name && 1002 920 fcf->fc_map == new.fc_map && 1003 921 compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) { 1004 - found = fcf; 922 + found = 1; 1005 923 break; 1006 924 } 1007 925 } ··· 1013 931 if (!fcf) 1014 932 goto out; 1015 933 1016 - fip->fcf_count++; 1017 934 memcpy(fcf, &new, sizeof(new)); 1018 - list_add(&fcf->list, &fip->fcfs); 935 + fcf->fip = fip; 936 + rc = fcoe_sysfs_fcf_add(fcf); 937 + if (rc) { 938 + printk(KERN_ERR "Failed to allocate sysfs instance " 939 + "for FCF, fab %16.16llx mac %pM\n", 940 + new.fabric_name, new.fcf_mac); 941 + kfree(fcf); 942 + goto out; 943 + } 1019 944 } else { 1020 945 /* 1021 946 * Update the FCF's keep-alive descriptor flags. ··· 1043 954 fcf->fka_period = new.fka_period; 1044 955 memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN); 1045 956 } 957 + 1046 958 mtu_valid = fcoe_ctlr_mtu_valid(fcf); 1047 959 fcf->time = jiffies; 1048 960 if (!found) ··· 1086 996 time_before(fip->sel_time, fip->timer.expires)) 1087 997 mod_timer(&fip->timer, fip->sel_time); 1088 998 } 999 + 1089 1000 out: 1090 1001 mutex_unlock(&fip->ctlr_mutex); 1091 1002 } ··· 2809 2718 2810 2719 /** 2811 2720 * fcoe_libfc_config() - Sets up libfc related properties for local port 2812 - * @lp: The local port to configure libfc for 2813 - * @fip: The FCoE controller in use by the local port 2814 - * @tt: The libfc function template 2721 + * @lport: The local port to configure libfc for 2722 + * @fip: The FCoE controller in use by the local port 2723 + * @tt: The libfc function template 2815 2724 * @init_fcp: If non-zero, the FCP portion of libfc should be initialized 2816 2725 * 2817 2726 * Returns : 0 for success ··· 2844 2753 return 0; 2845 2754 } 2846 2755 EXPORT_SYMBOL_GPL(fcoe_libfc_config); 2756 + 2757 + void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev) 2758 + { 2759 + struct fcoe_ctlr_device *ctlr_dev = fcoe_fcf_dev_to_ctlr_dev(fcf_dev); 2760 + struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); 2761 + struct fcoe_fcf *fcf; 2762 + 2763 + mutex_lock(&fip->ctlr_mutex); 2764 + mutex_lock(&ctlr_dev->lock); 2765 + 2766 + fcf = fcoe_fcf_device_priv(fcf_dev); 2767 + if (fcf) 2768 + fcf_dev->selected = (fcf == fip->sel_fcf) ? 1 : 0; 2769 + else 2770 + fcf_dev->selected = 0; 2771 + 2772 + mutex_unlock(&ctlr_dev->lock); 2773 + mutex_unlock(&fip->ctlr_mutex); 2774 + } 2775 + EXPORT_SYMBOL(fcoe_fcf_get_selected); 2776 + 2777 + void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *ctlr_dev) 2778 + { 2779 + struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 2780 + 2781 + mutex_lock(&ctlr->ctlr_mutex); 2782 + switch (ctlr->mode) { 2783 + case FIP_MODE_FABRIC: 2784 + ctlr_dev->mode = FIP_CONN_TYPE_FABRIC; 2785 + break; 2786 + case FIP_MODE_VN2VN: 2787 + ctlr_dev->mode = FIP_CONN_TYPE_VN2VN; 2788 + break; 2789 + default: 2790 + ctlr_dev->mode = FIP_CONN_TYPE_UNKNOWN; 2791 + break; 2792 + } 2793 + mutex_unlock(&ctlr->ctlr_mutex); 2794 + } 2795 + EXPORT_SYMBOL(fcoe_ctlr_get_fip_mode);
+17
include/scsi/libfcoe.h
··· 168 168 return (void *)(ctlr + 1); 169 169 } 170 170 171 + #define fcoe_ctlr_to_ctlr_dev(x) \ 172 + (struct fcoe_ctlr_device *)(((struct fcoe_ctlr_device *)(x)) - 1) 173 + 171 174 /** 172 175 * struct fcoe_fcf - Fibre-Channel Forwarder 173 176 * @list: list linkage 177 + * @event_work: Work for FC Transport actions queue 178 + * @event: The event to be processed 179 + * @fip: The controller that the FCF was discovered on 180 + * @fcf_dev: The associated fcoe_fcf_device instance 174 181 * @time: system time (jiffies) when an advertisement was last received 175 182 * @switch_name: WWN of switch from advertisement 176 183 * @fabric_name: WWN of fabric from advertisement ··· 199 192 */ 200 193 struct fcoe_fcf { 201 194 struct list_head list; 195 + struct work_struct event_work; 196 + struct fcoe_ctlr *fip; 197 + struct fcoe_fcf_device *fcf_dev; 202 198 unsigned long time; 203 199 204 200 u64 switch_name; ··· 217 207 u32 fka_period; 218 208 u8 fd_flags:1; 219 209 }; 210 + 211 + #define fcoe_fcf_to_fcf_dev(x) \ 212 + ((x)->fcf_dev) 220 213 221 214 /** 222 215 * struct fcoe_rport - VN2VN remote port ··· 355 342 void fcoe_queue_timer(ulong lport); 356 343 int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen, 357 344 struct fcoe_percpu_s *fps); 345 + 346 + /* FCoE Sysfs helpers */ 347 + void fcoe_fcf_get_selected(struct fcoe_fcf_device *); 348 + void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *); 358 349 359 350 /** 360 351 * struct netdev_list