diff options
author | Robert Love <robert.w.love@intel.com> | 2012-05-22 22:06:26 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-05-23 04:43:13 -0400 |
commit | 8d55e507d24c6db7eb012c379c62912e642eb75e (patch) | |
tree | 5118b221cf9eab4ad040c9e1bcabb794e57dc906 /drivers/scsi/bnx2fc | |
parent | 9a74e884ee71dbf3d0967b0321d7b4529a04826c (diff) |
[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>
Diffstat (limited to 'drivers/scsi/bnx2fc')
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index cb9bf364170b..f52f668fd247 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c | |||
@@ -54,6 +54,7 @@ static struct cnic_ulp_ops bnx2fc_cnic_cb; | |||
54 | static struct libfc_function_template bnx2fc_libfc_fcn_templ; | 54 | static struct libfc_function_template bnx2fc_libfc_fcn_templ; |
55 | static struct scsi_host_template bnx2fc_shost_template; | 55 | static struct scsi_host_template bnx2fc_shost_template; |
56 | static struct fc_function_template bnx2fc_transport_function; | 56 | static struct fc_function_template bnx2fc_transport_function; |
57 | static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ; | ||
57 | static struct fc_function_template bnx2fc_vport_xport_function; | 58 | static struct fc_function_template bnx2fc_vport_xport_function; |
58 | static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode); | 59 | static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode); |
59 | static void __bnx2fc_destroy(struct bnx2fc_interface *interface); | 60 | static void __bnx2fc_destroy(struct bnx2fc_interface *interface); |
@@ -88,6 +89,7 @@ static void bnx2fc_port_shutdown(struct fc_lport *lport); | |||
88 | static void bnx2fc_stop(struct bnx2fc_interface *interface); | 89 | static void bnx2fc_stop(struct bnx2fc_interface *interface); |
89 | static int __init bnx2fc_mod_init(void); | 90 | static int __init bnx2fc_mod_init(void); |
90 | static void __exit bnx2fc_mod_exit(void); | 91 | static void __exit bnx2fc_mod_exit(void); |
92 | static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev); | ||
91 | 93 | ||
92 | unsigned int bnx2fc_debug_level; | 94 | unsigned int bnx2fc_debug_level; |
93 | module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR); | 95 | module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR); |
@@ -118,6 +120,41 @@ static void bnx2fc_get_lesb(struct fc_lport *lport, | |||
118 | __fcoe_get_lesb(lport, fc_lesb, netdev); | 120 | __fcoe_get_lesb(lport, fc_lesb, netdev); |
119 | } | 121 | } |
120 | 122 | ||
123 | static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev) | ||
124 | { | ||
125 | struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); | ||
126 | struct net_device *netdev = bnx2fc_netdev(fip->lp); | ||
127 | struct fcoe_fc_els_lesb *fcoe_lesb; | ||
128 | struct fc_els_lesb fc_lesb; | ||
129 | |||
130 | __fcoe_get_lesb(fip->lp, &fc_lesb, netdev); | ||
131 | fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb); | ||
132 | |||
133 | ctlr_dev->lesb.lesb_link_fail = | ||
134 | ntohl(fcoe_lesb->lesb_link_fail); | ||
135 | ctlr_dev->lesb.lesb_vlink_fail = | ||
136 | ntohl(fcoe_lesb->lesb_vlink_fail); | ||
137 | ctlr_dev->lesb.lesb_miss_fka = | ||
138 | ntohl(fcoe_lesb->lesb_miss_fka); | ||
139 | ctlr_dev->lesb.lesb_symb_err = | ||
140 | ntohl(fcoe_lesb->lesb_symb_err); | ||
141 | ctlr_dev->lesb.lesb_err_block = | ||
142 | ntohl(fcoe_lesb->lesb_err_block); | ||
143 | ctlr_dev->lesb.lesb_fcs_error = | ||
144 | ntohl(fcoe_lesb->lesb_fcs_error); | ||
145 | } | ||
146 | EXPORT_SYMBOL(bnx2fc_ctlr_get_lesb); | ||
147 | |||
148 | static void bnx2fc_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev) | ||
149 | { | ||
150 | struct fcoe_ctlr_device *ctlr_dev = | ||
151 | fcoe_fcf_dev_to_ctlr_dev(fcf_dev); | ||
152 | struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); | ||
153 | struct bnx2fc_interface *fcoe = fcoe_ctlr_priv(ctlr); | ||
154 | |||
155 | fcf_dev->vlan_id = fcoe->vlan_id; | ||
156 | } | ||
157 | |||
121 | static void bnx2fc_clean_rx_queue(struct fc_lport *lp) | 158 | static void bnx2fc_clean_rx_queue(struct fc_lport *lp) |
122 | { | 159 | { |
123 | struct fcoe_percpu_s *bg; | 160 | struct fcoe_percpu_s *bg; |
@@ -1235,6 +1272,7 @@ static void bnx2fc_release_transport(void) | |||
1235 | 1272 | ||
1236 | static void bnx2fc_interface_release(struct kref *kref) | 1273 | static void bnx2fc_interface_release(struct kref *kref) |
1237 | { | 1274 | { |
1275 | struct fcoe_ctlr_device *ctlr_dev; | ||
1238 | struct bnx2fc_interface *interface; | 1276 | struct bnx2fc_interface *interface; |
1239 | struct fcoe_ctlr *ctlr; | 1277 | struct fcoe_ctlr *ctlr; |
1240 | struct net_device *netdev; | 1278 | struct net_device *netdev; |
@@ -1243,13 +1281,14 @@ static void bnx2fc_interface_release(struct kref *kref) | |||
1243 | BNX2FC_MISC_DBG("Interface is being released\n"); | 1281 | BNX2FC_MISC_DBG("Interface is being released\n"); |
1244 | 1282 | ||
1245 | ctlr = bnx2fc_to_ctlr(interface); | 1283 | ctlr = bnx2fc_to_ctlr(interface); |
1284 | ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr); | ||
1246 | netdev = interface->netdev; | 1285 | netdev = interface->netdev; |
1247 | 1286 | ||
1248 | /* tear-down FIP controller */ | 1287 | /* tear-down FIP controller */ |
1249 | if (test_and_clear_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags)) | 1288 | if (test_and_clear_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags)) |
1250 | fcoe_ctlr_destroy(ctlr); | 1289 | fcoe_ctlr_destroy(ctlr); |
1251 | 1290 | ||
1252 | kfree(ctlr); | 1291 | fcoe_ctlr_device_delete(ctlr_dev); |
1253 | 1292 | ||
1254 | dev_put(netdev); | 1293 | dev_put(netdev); |
1255 | module_put(THIS_MODULE); | 1294 | module_put(THIS_MODULE); |
@@ -1342,17 +1381,20 @@ struct bnx2fc_interface *bnx2fc_interface_create(struct bnx2fc_hba *hba, | |||
1342 | struct net_device *netdev, | 1381 | struct net_device *netdev, |
1343 | enum fip_state fip_mode) | 1382 | enum fip_state fip_mode) |
1344 | { | 1383 | { |
1384 | struct fcoe_ctlr_device *ctlr_dev; | ||
1345 | struct bnx2fc_interface *interface; | 1385 | struct bnx2fc_interface *interface; |
1346 | struct fcoe_ctlr *ctlr; | 1386 | struct fcoe_ctlr *ctlr; |
1347 | int size; | 1387 | int size; |
1348 | int rc = 0; | 1388 | int rc = 0; |
1349 | 1389 | ||
1350 | size = (sizeof(*interface) + sizeof(struct fcoe_ctlr)); | 1390 | size = (sizeof(*interface) + sizeof(struct fcoe_ctlr)); |
1351 | ctlr = kzalloc(size, GFP_KERNEL); | 1391 | ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &bnx2fc_fcoe_sysfs_templ, |
1352 | if (!ctlr) { | 1392 | size); |
1393 | if (!ctlr_dev) { | ||
1353 | printk(KERN_ERR PFX "Unable to allocate interface structure\n"); | 1394 | printk(KERN_ERR PFX "Unable to allocate interface structure\n"); |
1354 | return NULL; | 1395 | return NULL; |
1355 | } | 1396 | } |
1397 | ctlr = fcoe_ctlr_device_priv(ctlr_dev); | ||
1356 | interface = fcoe_ctlr_priv(ctlr); | 1398 | interface = fcoe_ctlr_priv(ctlr); |
1357 | dev_hold(netdev); | 1399 | dev_hold(netdev); |
1358 | kref_init(&interface->kref); | 1400 | kref_init(&interface->kref); |
@@ -1372,7 +1414,7 @@ struct bnx2fc_interface *bnx2fc_interface_create(struct bnx2fc_hba *hba, | |||
1372 | 1414 | ||
1373 | fcoe_ctlr_destroy(ctlr); | 1415 | fcoe_ctlr_destroy(ctlr); |
1374 | dev_put(netdev); | 1416 | dev_put(netdev); |
1375 | kfree(ctlr); | 1417 | fcoe_ctlr_device_delete(ctlr_dev); |
1376 | return NULL; | 1418 | return NULL; |
1377 | } | 1419 | } |
1378 | 1420 | ||
@@ -2471,6 +2513,19 @@ static void __exit bnx2fc_mod_exit(void) | |||
2471 | module_init(bnx2fc_mod_init); | 2513 | module_init(bnx2fc_mod_init); |
2472 | module_exit(bnx2fc_mod_exit); | 2514 | module_exit(bnx2fc_mod_exit); |
2473 | 2515 | ||
2516 | static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = { | ||
2517 | .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode, | ||
2518 | .get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb, | ||
2519 | .get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb, | ||
2520 | .get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb, | ||
2521 | .get_fcoe_ctlr_symb_err = bnx2fc_ctlr_get_lesb, | ||
2522 | .get_fcoe_ctlr_err_block = bnx2fc_ctlr_get_lesb, | ||
2523 | .get_fcoe_ctlr_fcs_error = bnx2fc_ctlr_get_lesb, | ||
2524 | |||
2525 | .get_fcoe_fcf_selected = fcoe_fcf_get_selected, | ||
2526 | .get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id, | ||
2527 | }; | ||
2528 | |||
2474 | static struct fc_function_template bnx2fc_transport_function = { | 2529 | static struct fc_function_template bnx2fc_transport_function = { |
2475 | .show_host_node_name = 1, | 2530 | .show_host_node_name = 1, |
2476 | .show_host_port_name = 1, | 2531 | .show_host_port_name = 1, |