diff options
author | Chris Leech <christopher.leech@intel.com> | 2009-08-25 16:59:30 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-10 13:07:31 -0400 |
commit | 014f5c3f560a336cb8ad5b9f828c85de0398e7bb (patch) | |
tree | 0b51f21ec8690a0a416e3f8c12eec8e3391b2778 /drivers/scsi/fcoe | |
parent | af7f85d95a34b04f5cf8c3b8c2d4cdd179dc1e19 (diff) |
[SCSI] fcoe: Introduce and allocate fcoe_interface structure, 1:1 with net_device
In preparation for NPIV support, I'm splitting the fcoe instance structure
into two to remove the assumptions about it being 1:1 with the net_device.
There will now be two structures, one which is 1:1 with the underlying
net_device and one which is allocated per virtual SCSI/FC host.
fcoe_softc is renamed to fcoe_port for the per Scsi_Host FCoE private data.
Later patches with start moving shared stuff from fcoe_port to fcoe_interface
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')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 326 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe.h | 19 |
2 files changed, 188 insertions, 157 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 749279698137..0ae54b2bce34 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -151,10 +151,10 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev, | |||
151 | struct packet_type *ptype, | 151 | struct packet_type *ptype, |
152 | struct net_device *orig_dev) | 152 | struct net_device *orig_dev) |
153 | { | 153 | { |
154 | struct fcoe_softc *fc; | 154 | struct fcoe_port *port; |
155 | 155 | ||
156 | fc = container_of(ptype, struct fcoe_softc, fip_packet_type); | 156 | port = container_of(ptype, struct fcoe_port, fip_packet_type); |
157 | fcoe_ctlr_recv(&fc->ctlr, skb); | 157 | fcoe_ctlr_recv(&port->ctlr, skb); |
158 | return 0; | 158 | return 0; |
159 | } | 159 | } |
160 | 160 | ||
@@ -180,13 +180,13 @@ static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
180 | */ | 180 | */ |
181 | static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new) | 181 | static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new) |
182 | { | 182 | { |
183 | struct fcoe_softc *fc; | 183 | struct fcoe_port *port; |
184 | 184 | ||
185 | fc = fcoe_from_ctlr(fip); | 185 | port = fcoe_from_ctlr(fip); |
186 | rtnl_lock(); | 186 | rtnl_lock(); |
187 | if (!is_zero_ether_addr(old)) | 187 | if (!is_zero_ether_addr(old)) |
188 | dev_unicast_delete(fc->netdev, old); | 188 | dev_unicast_delete(port->netdev, old); |
189 | dev_unicast_add(fc->netdev, new); | 189 | dev_unicast_add(port->netdev, new); |
190 | rtnl_unlock(); | 190 | rtnl_unlock(); |
191 | } | 191 | } |
192 | 192 | ||
@@ -224,25 +224,25 @@ static int fcoe_lport_config(struct fc_lport *lp) | |||
224 | 224 | ||
225 | /** | 225 | /** |
226 | * fcoe_netdev_cleanup() - clean up netdev configurations | 226 | * fcoe_netdev_cleanup() - clean up netdev configurations |
227 | * @fc: ptr to the fcoe_softc | 227 | * @port: ptr to the fcoe_port |
228 | */ | 228 | */ |
229 | void fcoe_netdev_cleanup(struct fcoe_softc *fc) | 229 | void fcoe_netdev_cleanup(struct fcoe_port *port) |
230 | { | 230 | { |
231 | u8 flogi_maddr[ETH_ALEN]; | 231 | u8 flogi_maddr[ETH_ALEN]; |
232 | 232 | ||
233 | /* Don't listen for Ethernet packets anymore */ | 233 | /* Don't listen for Ethernet packets anymore */ |
234 | dev_remove_pack(&fc->fcoe_packet_type); | 234 | dev_remove_pack(&port->fcoe_packet_type); |
235 | dev_remove_pack(&fc->fip_packet_type); | 235 | dev_remove_pack(&port->fip_packet_type); |
236 | 236 | ||
237 | /* Delete secondary MAC addresses */ | 237 | /* Delete secondary MAC addresses */ |
238 | rtnl_lock(); | 238 | rtnl_lock(); |
239 | memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); | 239 | memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); |
240 | dev_unicast_delete(fc->netdev, flogi_maddr); | 240 | dev_unicast_delete(port->netdev, flogi_maddr); |
241 | if (!is_zero_ether_addr(fc->ctlr.data_src_addr)) | 241 | if (!is_zero_ether_addr(port->ctlr.data_src_addr)) |
242 | dev_unicast_delete(fc->netdev, fc->ctlr.data_src_addr); | 242 | dev_unicast_delete(port->netdev, port->ctlr.data_src_addr); |
243 | if (fc->ctlr.spma) | 243 | if (port->ctlr.spma) |
244 | dev_unicast_delete(fc->netdev, fc->ctlr.ctl_src_addr); | 244 | dev_unicast_delete(port->netdev, port->ctlr.ctl_src_addr); |
245 | dev_mc_delete(fc->netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); | 245 | dev_mc_delete(port->netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); |
246 | rtnl_unlock(); | 246 | rtnl_unlock(); |
247 | } | 247 | } |
248 | 248 | ||
@@ -271,14 +271,14 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) | |||
271 | { | 271 | { |
272 | u32 mfs; | 272 | u32 mfs; |
273 | u64 wwnn, wwpn; | 273 | u64 wwnn, wwpn; |
274 | struct fcoe_softc *fc; | 274 | struct fcoe_port *port; |
275 | u8 flogi_maddr[ETH_ALEN]; | 275 | u8 flogi_maddr[ETH_ALEN]; |
276 | struct netdev_hw_addr *ha; | 276 | struct netdev_hw_addr *ha; |
277 | 277 | ||
278 | /* Setup lport private data to point to fcoe softc */ | 278 | /* Setup lport private data to point to fcoe softc */ |
279 | fc = lport_priv(lp); | 279 | port = lport_priv(lp); |
280 | fc->ctlr.lp = lp; | 280 | port->ctlr.lp = lp; |
281 | fc->netdev = netdev; | 281 | port->netdev = netdev; |
282 | 282 | ||
283 | /* Do not support for bonding device */ | 283 | /* Do not support for bonding device */ |
284 | if ((netdev->priv_flags & IFF_MASTER_ALB) || | 284 | if ((netdev->priv_flags & IFF_MASTER_ALB) || |
@@ -317,27 +317,27 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) | |||
317 | FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n", | 317 | FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n", |
318 | lp->lro_xid); | 318 | lp->lro_xid); |
319 | } | 319 | } |
320 | skb_queue_head_init(&fc->fcoe_pending_queue); | 320 | skb_queue_head_init(&port->fcoe_pending_queue); |
321 | fc->fcoe_pending_queue_active = 0; | 321 | port->fcoe_pending_queue_active = 0; |
322 | setup_timer(&fc->timer, fcoe_queue_timer, (unsigned long)lp); | 322 | setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lp); |
323 | 323 | ||
324 | /* look for SAN MAC address, if multiple SAN MACs exist, only | 324 | /* look for SAN MAC address, if multiple SAN MACs exist, only |
325 | * use the first one for SPMA */ | 325 | * use the first one for SPMA */ |
326 | rcu_read_lock(); | 326 | rcu_read_lock(); |
327 | for_each_dev_addr(netdev, ha) { | 327 | for_each_dev_addr(netdev, ha) { |
328 | if ((ha->type == NETDEV_HW_ADDR_T_SAN) && | 328 | if ((ha->type == NETDEV_HW_ADDR_T_SAN) && |
329 | (is_valid_ether_addr(ha->addr))) { | 329 | (is_valid_ether_addr(port->ctlr.ctl_src_addr))) { |
330 | memcpy(fc->ctlr.ctl_src_addr, ha->addr, ETH_ALEN); | 330 | memcpy(port->ctlr.ctl_src_addr, ha->addr, ETH_ALEN); |
331 | fc->ctlr.spma = 1; | 331 | port->ctlr.spma = 1; |
332 | break; | 332 | break; |
333 | } | 333 | } |
334 | } | 334 | } |
335 | rcu_read_unlock(); | 335 | rcu_read_unlock(); |
336 | 336 | ||
337 | /* setup Source Mac Address */ | 337 | /* setup Source Mac Address */ |
338 | if (!fc->ctlr.spma) | 338 | if (!port->ctlr.spma) |
339 | memcpy(fc->ctlr.ctl_src_addr, netdev->dev_addr, | 339 | memcpy(port->ctlr.ctl_src_addr, netdev->dev_addr, |
340 | fc->netdev->addr_len); | 340 | netdev->addr_len); |
341 | 341 | ||
342 | wwnn = fcoe_wwn_from_mac(netdev->dev_addr, 1, 0); | 342 | wwnn = fcoe_wwn_from_mac(netdev->dev_addr, 1, 0); |
343 | fc_set_wwnn(lp, wwnn); | 343 | fc_set_wwnn(lp, wwnn); |
@@ -353,8 +353,8 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) | |||
353 | rtnl_lock(); | 353 | rtnl_lock(); |
354 | memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); | 354 | memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); |
355 | dev_unicast_add(netdev, flogi_maddr); | 355 | dev_unicast_add(netdev, flogi_maddr); |
356 | if (fc->ctlr.spma) | 356 | if (port->ctlr.spma) |
357 | dev_unicast_add(netdev, fc->ctlr.ctl_src_addr); | 357 | dev_unicast_add(netdev, port->ctlr.ctl_src_addr); |
358 | dev_mc_add(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); | 358 | dev_mc_add(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); |
359 | rtnl_unlock(); | 359 | rtnl_unlock(); |
360 | 360 | ||
@@ -362,15 +362,15 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) | |||
362 | * setup the receive function from ethernet driver | 362 | * setup the receive function from ethernet driver |
363 | * on the ethertype for the given device | 363 | * on the ethertype for the given device |
364 | */ | 364 | */ |
365 | fc->fcoe_packet_type.func = fcoe_rcv; | 365 | port->fcoe_packet_type.func = fcoe_rcv; |
366 | fc->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE); | 366 | port->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE); |
367 | fc->fcoe_packet_type.dev = netdev; | 367 | port->fcoe_packet_type.dev = netdev; |
368 | dev_add_pack(&fc->fcoe_packet_type); | 368 | dev_add_pack(&port->fcoe_packet_type); |
369 | 369 | ||
370 | fc->fip_packet_type.func = fcoe_fip_recv; | 370 | port->fip_packet_type.func = fcoe_fip_recv; |
371 | fc->fip_packet_type.type = htons(ETH_P_FIP); | 371 | port->fip_packet_type.type = htons(ETH_P_FIP); |
372 | fc->fip_packet_type.dev = netdev; | 372 | port->fip_packet_type.dev = netdev; |
373 | dev_add_pack(&fc->fip_packet_type); | 373 | dev_add_pack(&port->fip_packet_type); |
374 | 374 | ||
375 | return 0; | 375 | return 0; |
376 | } | 376 | } |
@@ -426,7 +426,7 @@ bool fcoe_oem_match(struct fc_frame *fp) | |||
426 | 426 | ||
427 | /** | 427 | /** |
428 | * fcoe_em_config() - allocates em for this lport | 428 | * fcoe_em_config() - allocates em for this lport |
429 | * @lp: the port that em is to allocated for | 429 | * @lp: the fcoe that em is to allocated for |
430 | * | 430 | * |
431 | * Called with write fcoe_hostlist_lock held. | 431 | * Called with write fcoe_hostlist_lock held. |
432 | * | 432 | * |
@@ -434,8 +434,9 @@ bool fcoe_oem_match(struct fc_frame *fp) | |||
434 | */ | 434 | */ |
435 | static inline int fcoe_em_config(struct fc_lport *lp) | 435 | static inline int fcoe_em_config(struct fc_lport *lp) |
436 | { | 436 | { |
437 | struct fcoe_softc *fc = lport_priv(lp); | 437 | struct fcoe_interface *fcoe; |
438 | struct fcoe_softc *oldfc = NULL; | 438 | struct fcoe_port *port = lport_priv(lp); |
439 | struct fcoe_port *oldfc = NULL; | ||
439 | struct net_device *old_real_dev, *cur_real_dev; | 440 | struct net_device *old_real_dev, *cur_real_dev; |
440 | u16 min_xid = FCOE_MIN_XID; | 441 | u16 min_xid = FCOE_MIN_XID; |
441 | u16 max_xid = FCOE_MAX_XID; | 442 | u16 max_xid = FCOE_MAX_XID; |
@@ -453,38 +454,39 @@ static inline int fcoe_em_config(struct fc_lport *lp) | |||
453 | * Reuse existing offload em instance in case | 454 | * Reuse existing offload em instance in case |
454 | * it is already allocated on real eth device | 455 | * it is already allocated on real eth device |
455 | */ | 456 | */ |
456 | if (fc->netdev->priv_flags & IFF_802_1Q_VLAN) | 457 | if (port->netdev->priv_flags & IFF_802_1Q_VLAN) |
457 | cur_real_dev = vlan_dev_real_dev(fc->netdev); | 458 | cur_real_dev = vlan_dev_real_dev(port->netdev); |
458 | else | 459 | else |
459 | cur_real_dev = fc->netdev; | 460 | cur_real_dev = port->netdev; |
460 | 461 | ||
461 | list_for_each_entry(oldfc, &fcoe_hostlist, list) { | 462 | list_for_each_entry(fcoe, &fcoe_hostlist, list) { |
463 | oldfc = fcoe->priv; | ||
462 | if (oldfc->netdev->priv_flags & IFF_802_1Q_VLAN) | 464 | if (oldfc->netdev->priv_flags & IFF_802_1Q_VLAN) |
463 | old_real_dev = vlan_dev_real_dev(oldfc->netdev); | 465 | old_real_dev = vlan_dev_real_dev(oldfc->netdev); |
464 | else | 466 | else |
465 | old_real_dev = oldfc->netdev; | 467 | old_real_dev = oldfc->netdev; |
466 | 468 | ||
467 | if (cur_real_dev == old_real_dev) { | 469 | if (cur_real_dev == old_real_dev) { |
468 | fc->oem = oldfc->oem; | 470 | port->oem = oldfc->oem; |
469 | break; | 471 | break; |
470 | } | 472 | } |
471 | } | 473 | } |
472 | 474 | ||
473 | if (fc->oem) { | 475 | if (port->oem) { |
474 | if (!fc_exch_mgr_add(lp, fc->oem, fcoe_oem_match)) { | 476 | if (!fc_exch_mgr_add(lp, port->oem, fcoe_oem_match)) { |
475 | printk(KERN_ERR "fcoe_em_config: failed to add " | 477 | printk(KERN_ERR "fcoe_em_config: failed to add " |
476 | "offload em:%p on interface:%s\n", | 478 | "offload em:%p on interface:%s\n", |
477 | fc->oem, fc->netdev->name); | 479 | port->oem, port->netdev->name); |
478 | return -ENOMEM; | 480 | return -ENOMEM; |
479 | } | 481 | } |
480 | } else { | 482 | } else { |
481 | fc->oem = fc_exch_mgr_alloc(lp, FC_CLASS_3, | 483 | port->oem = fc_exch_mgr_alloc(lp, FC_CLASS_3, |
482 | FCOE_MIN_XID, lp->lro_xid, | 484 | FCOE_MIN_XID, lp->lro_xid, |
483 | fcoe_oem_match); | 485 | fcoe_oem_match); |
484 | if (!fc->oem) { | 486 | if (!port->oem) { |
485 | printk(KERN_ERR "fcoe_em_config: failed to allocate " | 487 | printk(KERN_ERR "fcoe_em_config: failed to allocate " |
486 | "em for offload exches on interface:%s\n", | 488 | "em for offload exches on interface:%s\n", |
487 | fc->netdev->name); | 489 | port->netdev->name); |
488 | return -ENOMEM; | 490 | return -ENOMEM; |
489 | } | 491 | } |
490 | } | 492 | } |
@@ -497,7 +499,7 @@ static inline int fcoe_em_config(struct fc_lport *lp) | |||
497 | skip_oem: | 499 | skip_oem: |
498 | if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, min_xid, max_xid, NULL)) { | 500 | if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, min_xid, max_xid, NULL)) { |
499 | printk(KERN_ERR "fcoe_em_config: failed to " | 501 | printk(KERN_ERR "fcoe_em_config: failed to " |
500 | "allocate em on interface %s\n", fc->netdev->name); | 502 | "allocate em on interface %s\n", port->netdev->name); |
501 | return -ENOMEM; | 503 | return -ENOMEM; |
502 | } | 504 | } |
503 | 505 | ||
@@ -510,8 +512,9 @@ skip_oem: | |||
510 | */ | 512 | */ |
511 | static void fcoe_if_destroy(struct fc_lport *lport) | 513 | static void fcoe_if_destroy(struct fc_lport *lport) |
512 | { | 514 | { |
513 | struct fcoe_softc *fc = lport_priv(lport); | 515 | struct fcoe_port *port = lport_priv(lport); |
514 | struct net_device *netdev = fc->netdev; | 516 | struct fcoe_interface *fcoe = port->fcoe; |
517 | struct net_device *netdev = port->netdev; | ||
515 | 518 | ||
516 | FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); | 519 | FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); |
517 | 520 | ||
@@ -522,10 +525,10 @@ static void fcoe_if_destroy(struct fc_lport *lport) | |||
522 | fcoe_hostlist_remove(lport); | 525 | fcoe_hostlist_remove(lport); |
523 | 526 | ||
524 | /* clean up netdev configurations */ | 527 | /* clean up netdev configurations */ |
525 | fcoe_netdev_cleanup(fc); | 528 | fcoe_netdev_cleanup(port); |
526 | 529 | ||
527 | /* tear-down the FCoE controller */ | 530 | /* tear-down the FCoE controller */ |
528 | fcoe_ctlr_destroy(&fc->ctlr); | 531 | fcoe_ctlr_destroy(&port->ctlr); |
529 | 532 | ||
530 | /* Free queued packets for the per-CPU receive threads */ | 533 | /* Free queued packets for the per-CPU receive threads */ |
531 | fcoe_percpu_clean(lport); | 534 | fcoe_percpu_clean(lport); |
@@ -545,7 +548,7 @@ static void fcoe_if_destroy(struct fc_lport *lport) | |||
545 | fcoe_clean_pending_queue(lport); | 548 | fcoe_clean_pending_queue(lport); |
546 | 549 | ||
547 | /* Stop the timer */ | 550 | /* Stop the timer */ |
548 | del_timer_sync(&fc->timer); | 551 | del_timer_sync(&port->timer); |
549 | 552 | ||
550 | /* Free memory used by statistical counters */ | 553 | /* Free memory used by statistical counters */ |
551 | fc_lport_free_stats(lport); | 554 | fc_lport_free_stats(lport); |
@@ -553,6 +556,7 @@ static void fcoe_if_destroy(struct fc_lport *lport) | |||
553 | /* Release the net_device and Scsi_Host */ | 556 | /* Release the net_device and Scsi_Host */ |
554 | dev_put(netdev); | 557 | dev_put(netdev); |
555 | scsi_host_put(lport->host); | 558 | scsi_host_put(lport->host); |
559 | kfree(fcoe); /* TODO, should be refcounted */ | ||
556 | } | 560 | } |
557 | 561 | ||
558 | /* | 562 | /* |
@@ -612,20 +616,31 @@ static struct fc_lport *fcoe_if_create(struct net_device *netdev, | |||
612 | { | 616 | { |
613 | int rc; | 617 | int rc; |
614 | struct fc_lport *lport = NULL; | 618 | struct fc_lport *lport = NULL; |
615 | struct fcoe_softc *fc; | 619 | struct fcoe_port *port; |
620 | struct fcoe_interface *fcoe; | ||
616 | struct Scsi_Host *shost; | 621 | struct Scsi_Host *shost; |
617 | 622 | ||
618 | FCOE_NETDEV_DBG(netdev, "Create Interface\n"); | 623 | FCOE_NETDEV_DBG(netdev, "Create Interface\n"); |
619 | 624 | ||
625 | fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL); | ||
626 | if (!fcoe) { | ||
627 | FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); | ||
628 | rc = -ENOMEM; | ||
629 | goto out; | ||
630 | } | ||
631 | |||
620 | shost = libfc_host_alloc(&fcoe_shost_template, | 632 | shost = libfc_host_alloc(&fcoe_shost_template, |
621 | sizeof(struct fcoe_softc)); | 633 | sizeof(struct fcoe_port)); |
622 | if (!shost) { | 634 | if (!shost) { |
623 | FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n"); | 635 | FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n"); |
624 | rc = -ENOMEM; | 636 | rc = -ENOMEM; |
625 | goto out; | 637 | goto out_kfree_port; |
626 | } | 638 | } |
627 | lport = shost_priv(shost); | 639 | lport = shost_priv(shost); |
628 | fc = lport_priv(lport); | 640 | port = lport_priv(lport); |
641 | |||
642 | port->fcoe = fcoe; | ||
643 | fcoe->priv = port; | ||
629 | 644 | ||
630 | /* configure fc_lport, e.g., em */ | 645 | /* configure fc_lport, e.g., em */ |
631 | rc = fcoe_lport_config(lport); | 646 | rc = fcoe_lport_config(lport); |
@@ -638,9 +653,9 @@ static struct fc_lport *fcoe_if_create(struct net_device *netdev, | |||
638 | /* | 653 | /* |
639 | * Initialize FIP. | 654 | * Initialize FIP. |
640 | */ | 655 | */ |
641 | fcoe_ctlr_init(&fc->ctlr); | 656 | fcoe_ctlr_init(&port->ctlr); |
642 | fc->ctlr.send = fcoe_fip_send; | 657 | port->ctlr.send = fcoe_fip_send; |
643 | fc->ctlr.update_mac = fcoe_update_src_mac; | 658 | port->ctlr.update_mac = fcoe_update_src_mac; |
644 | 659 | ||
645 | /* configure lport network properties */ | 660 | /* configure lport network properties */ |
646 | rc = fcoe_netdev_config(lport, netdev); | 661 | rc = fcoe_netdev_config(lport, netdev); |
@@ -690,7 +705,7 @@ static struct fc_lport *fcoe_if_create(struct net_device *netdev, | |||
690 | fc_fabric_login(lport); | 705 | fc_fabric_login(lport); |
691 | 706 | ||
692 | if (!fcoe_link_ok(lport)) | 707 | if (!fcoe_link_ok(lport)) |
693 | fcoe_ctlr_link_up(&fc->ctlr); | 708 | fcoe_ctlr_link_up(&port->ctlr); |
694 | 709 | ||
695 | dev_hold(netdev); | 710 | dev_hold(netdev); |
696 | 711 | ||
@@ -699,9 +714,11 @@ static struct fc_lport *fcoe_if_create(struct net_device *netdev, | |||
699 | out_lp_destroy: | 714 | out_lp_destroy: |
700 | fc_exch_mgr_free(lport); | 715 | fc_exch_mgr_free(lport); |
701 | out_netdev_cleanup: | 716 | out_netdev_cleanup: |
702 | fcoe_netdev_cleanup(fc); | 717 | fcoe_netdev_cleanup(port); |
703 | out_host_put: | 718 | out_host_put: |
704 | scsi_host_put(lport->host); | 719 | scsi_host_put(lport->host); |
720 | out_kfree_port: | ||
721 | kfree(fcoe); | ||
705 | out: | 722 | out: |
706 | return ERR_PTR(rc); | 723 | return ERR_PTR(rc); |
707 | } | 724 | } |
@@ -902,13 +919,13 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, | |||
902 | { | 919 | { |
903 | struct fc_lport *lp; | 920 | struct fc_lport *lp; |
904 | struct fcoe_rcv_info *fr; | 921 | struct fcoe_rcv_info *fr; |
905 | struct fcoe_softc *fc; | 922 | struct fcoe_port *port; |
906 | struct fc_frame_header *fh; | 923 | struct fc_frame_header *fh; |
907 | struct fcoe_percpu_s *fps; | 924 | struct fcoe_percpu_s *fps; |
908 | unsigned int cpu; | 925 | unsigned int cpu; |
909 | 926 | ||
910 | fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type); | 927 | port = container_of(ptype, struct fcoe_port, fcoe_packet_type); |
911 | lp = fc->ctlr.lp; | 928 | lp = port->ctlr.lp; |
912 | if (unlikely(lp == NULL)) { | 929 | if (unlikely(lp == NULL)) { |
913 | FCOE_NETDEV_DBG(dev, "Cannot find hba structure"); | 930 | FCOE_NETDEV_DBG(dev, "Cannot find hba structure"); |
914 | goto err2; | 931 | goto err2; |
@@ -1059,7 +1076,7 @@ static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) | |||
1059 | * fcoe_fc_crc() - calculates FC CRC in this fcoe skb | 1076 | * fcoe_fc_crc() - calculates FC CRC in this fcoe skb |
1060 | * @fp: the fc_frame containing data to be checksummed | 1077 | * @fp: the fc_frame containing data to be checksummed |
1061 | * | 1078 | * |
1062 | * This uses crc32() to calculate the crc for fc frame | 1079 | * This uses crc32() to calculate the crc for port frame |
1063 | * Return : 32 bit crc | 1080 | * Return : 32 bit crc |
1064 | */ | 1081 | */ |
1065 | u32 fcoe_fc_crc(struct fc_frame *fp) | 1082 | u32 fcoe_fc_crc(struct fc_frame *fp) |
@@ -1092,7 +1109,7 @@ u32 fcoe_fc_crc(struct fc_frame *fp) | |||
1092 | 1109 | ||
1093 | /** | 1110 | /** |
1094 | * fcoe_xmit() - FCoE frame transmit function | 1111 | * fcoe_xmit() - FCoE frame transmit function |
1095 | * @lp: the associated local port | 1112 | * @lp: the associated local fcoe |
1096 | * @fp: the fc_frame to be transmitted | 1113 | * @fp: the fc_frame to be transmitted |
1097 | * | 1114 | * |
1098 | * Return : 0 for success | 1115 | * Return : 0 for success |
@@ -1109,13 +1126,13 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) | |||
1109 | unsigned int hlen; /* header length implies the version */ | 1126 | unsigned int hlen; /* header length implies the version */ |
1110 | unsigned int tlen; /* trailer length */ | 1127 | unsigned int tlen; /* trailer length */ |
1111 | unsigned int elen; /* eth header, may include vlan */ | 1128 | unsigned int elen; /* eth header, may include vlan */ |
1112 | struct fcoe_softc *fc; | 1129 | struct fcoe_port *port; |
1113 | u8 sof, eof; | 1130 | u8 sof, eof; |
1114 | struct fcoe_hdr *hp; | 1131 | struct fcoe_hdr *hp; |
1115 | 1132 | ||
1116 | WARN_ON((fr_len(fp) % sizeof(u32)) != 0); | 1133 | WARN_ON((fr_len(fp) % sizeof(u32)) != 0); |
1117 | 1134 | ||
1118 | fc = lport_priv(lp); | 1135 | port = lport_priv(lp); |
1119 | fh = fc_frame_header_get(fp); | 1136 | fh = fc_frame_header_get(fp); |
1120 | skb = fp_skb(fp); | 1137 | skb = fp_skb(fp); |
1121 | wlen = skb->len / FCOE_WORD_TO_BYTE; | 1138 | wlen = skb->len / FCOE_WORD_TO_BYTE; |
@@ -1126,7 +1143,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) | |||
1126 | } | 1143 | } |
1127 | 1144 | ||
1128 | if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) && | 1145 | if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) && |
1129 | fcoe_ctlr_els_send(&fc->ctlr, skb)) | 1146 | fcoe_ctlr_els_send(&port->ctlr, skb)) |
1130 | return 0; | 1147 | return 0; |
1131 | 1148 | ||
1132 | sof = fr_sof(fp); | 1149 | sof = fr_sof(fp); |
@@ -1148,7 +1165,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) | |||
1148 | crc = fcoe_fc_crc(fp); | 1165 | crc = fcoe_fc_crc(fp); |
1149 | } | 1166 | } |
1150 | 1167 | ||
1151 | /* copy fc crc and eof to the skb buff */ | 1168 | /* copy port crc and eof to the skb buff */ |
1152 | if (skb_is_nonlinear(skb)) { | 1169 | if (skb_is_nonlinear(skb)) { |
1153 | skb_frag_t *frag; | 1170 | skb_frag_t *frag; |
1154 | if (fcoe_get_paged_crc_eof(skb, tlen)) { | 1171 | if (fcoe_get_paged_crc_eof(skb, tlen)) { |
@@ -1171,27 +1188,27 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) | |||
1171 | cp = NULL; | 1188 | cp = NULL; |
1172 | } | 1189 | } |
1173 | 1190 | ||
1174 | /* adjust skb network/transport offsets to match mac/fcoe/fc */ | 1191 | /* adjust skb network/transport offsets to match mac/fcoe/port */ |
1175 | skb_push(skb, elen + hlen); | 1192 | skb_push(skb, elen + hlen); |
1176 | skb_reset_mac_header(skb); | 1193 | skb_reset_mac_header(skb); |
1177 | skb_reset_network_header(skb); | 1194 | skb_reset_network_header(skb); |
1178 | skb->mac_len = elen; | 1195 | skb->mac_len = elen; |
1179 | skb->protocol = htons(ETH_P_FCOE); | 1196 | skb->protocol = htons(ETH_P_FCOE); |
1180 | skb->dev = fc->netdev; | 1197 | skb->dev = port->netdev; |
1181 | 1198 | ||
1182 | /* fill up mac and fcoe headers */ | 1199 | /* fill up mac and fcoe headers */ |
1183 | eh = eth_hdr(skb); | 1200 | eh = eth_hdr(skb); |
1184 | eh->h_proto = htons(ETH_P_FCOE); | 1201 | eh->h_proto = htons(ETH_P_FCOE); |
1185 | if (fc->ctlr.map_dest) | 1202 | if (port->ctlr.map_dest) |
1186 | fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id); | 1203 | fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id); |
1187 | else | 1204 | else |
1188 | /* insert GW address */ | 1205 | /* insert GW address */ |
1189 | memcpy(eh->h_dest, fc->ctlr.dest_addr, ETH_ALEN); | 1206 | memcpy(eh->h_dest, port->ctlr.dest_addr, ETH_ALEN); |
1190 | 1207 | ||
1191 | if (unlikely(fc->ctlr.flogi_oxid != FC_XID_UNKNOWN)) | 1208 | if (unlikely(port->ctlr.flogi_oxid != FC_XID_UNKNOWN)) |
1192 | memcpy(eh->h_source, fc->ctlr.ctl_src_addr, ETH_ALEN); | 1209 | memcpy(eh->h_source, port->ctlr.ctl_src_addr, ETH_ALEN); |
1193 | else | 1210 | else |
1194 | memcpy(eh->h_source, fc->ctlr.data_src_addr, ETH_ALEN); | 1211 | memcpy(eh->h_source, port->ctlr.data_src_addr, ETH_ALEN); |
1195 | 1212 | ||
1196 | hp = (struct fcoe_hdr *)(eh + 1); | 1213 | hp = (struct fcoe_hdr *)(eh + 1); |
1197 | memset(hp, 0, sizeof(*hp)); | 1214 | memset(hp, 0, sizeof(*hp)); |
@@ -1214,7 +1231,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) | |||
1214 | 1231 | ||
1215 | /* send down to lld */ | 1232 | /* send down to lld */ |
1216 | fr_dev(fp) = lp; | 1233 | fr_dev(fp) = lp; |
1217 | if (fc->fcoe_pending_queue.qlen) | 1234 | if (port->fcoe_pending_queue.qlen) |
1218 | fcoe_check_wait_queue(lp, skb); | 1235 | fcoe_check_wait_queue(lp, skb); |
1219 | else if (fcoe_start_io(skb)) | 1236 | else if (fcoe_start_io(skb)) |
1220 | fcoe_check_wait_queue(lp, skb); | 1237 | fcoe_check_wait_queue(lp, skb); |
@@ -1240,7 +1257,7 @@ int fcoe_percpu_receive_thread(void *arg) | |||
1240 | struct fcoe_crc_eof crc_eof; | 1257 | struct fcoe_crc_eof crc_eof; |
1241 | struct fc_frame *fp; | 1258 | struct fc_frame *fp; |
1242 | u8 *mac = NULL; | 1259 | u8 *mac = NULL; |
1243 | struct fcoe_softc *fc; | 1260 | struct fcoe_port *port; |
1244 | struct fcoe_hdr *hp; | 1261 | struct fcoe_hdr *hp; |
1245 | 1262 | ||
1246 | set_user_nice(current, -20); | 1263 | set_user_nice(current, -20); |
@@ -1276,7 +1293,7 @@ int fcoe_percpu_receive_thread(void *arg) | |||
1276 | /* | 1293 | /* |
1277 | * Save source MAC address before discarding header. | 1294 | * Save source MAC address before discarding header. |
1278 | */ | 1295 | */ |
1279 | fc = lport_priv(lp); | 1296 | port = lport_priv(lp); |
1280 | if (skb_is_nonlinear(skb)) | 1297 | if (skb_is_nonlinear(skb)) |
1281 | skb_linearize(skb); /* not ideal */ | 1298 | skb_linearize(skb); /* not ideal */ |
1282 | mac = eth_hdr(skb)->h_source; | 1299 | mac = eth_hdr(skb)->h_source; |
@@ -1354,8 +1371,8 @@ int fcoe_percpu_receive_thread(void *arg) | |||
1354 | } | 1371 | } |
1355 | fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; | 1372 | fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; |
1356 | } | 1373 | } |
1357 | if (unlikely(fc->ctlr.flogi_oxid != FC_XID_UNKNOWN) && | 1374 | if (unlikely(port->ctlr.flogi_oxid != FC_XID_UNKNOWN) && |
1358 | fcoe_ctlr_recv_flogi(&fc->ctlr, fp, mac)) { | 1375 | fcoe_ctlr_recv_flogi(&port->ctlr, fp, mac)) { |
1359 | fc_frame_free(fp); | 1376 | fc_frame_free(fp); |
1360 | continue; | 1377 | continue; |
1361 | } | 1378 | } |
@@ -1379,46 +1396,46 @@ int fcoe_percpu_receive_thread(void *arg) | |||
1379 | */ | 1396 | */ |
1380 | static void fcoe_check_wait_queue(struct fc_lport *lp, struct sk_buff *skb) | 1397 | static void fcoe_check_wait_queue(struct fc_lport *lp, struct sk_buff *skb) |
1381 | { | 1398 | { |
1382 | struct fcoe_softc *fc = lport_priv(lp); | 1399 | struct fcoe_port *port = lport_priv(lp); |
1383 | int rc; | 1400 | int rc; |
1384 | 1401 | ||
1385 | spin_lock_bh(&fc->fcoe_pending_queue.lock); | 1402 | spin_lock_bh(&port->fcoe_pending_queue.lock); |
1386 | 1403 | ||
1387 | if (skb) | 1404 | if (skb) |
1388 | __skb_queue_tail(&fc->fcoe_pending_queue, skb); | 1405 | __skb_queue_tail(&port->fcoe_pending_queue, skb); |
1389 | 1406 | ||
1390 | if (fc->fcoe_pending_queue_active) | 1407 | if (port->fcoe_pending_queue_active) |
1391 | goto out; | 1408 | goto out; |
1392 | fc->fcoe_pending_queue_active = 1; | 1409 | port->fcoe_pending_queue_active = 1; |
1393 | 1410 | ||
1394 | while (fc->fcoe_pending_queue.qlen) { | 1411 | while (port->fcoe_pending_queue.qlen) { |
1395 | /* keep qlen > 0 until fcoe_start_io succeeds */ | 1412 | /* keep qlen > 0 until fcoe_start_io succeeds */ |
1396 | fc->fcoe_pending_queue.qlen++; | 1413 | port->fcoe_pending_queue.qlen++; |
1397 | skb = __skb_dequeue(&fc->fcoe_pending_queue); | 1414 | skb = __skb_dequeue(&port->fcoe_pending_queue); |
1398 | 1415 | ||
1399 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); | 1416 | spin_unlock_bh(&port->fcoe_pending_queue.lock); |
1400 | rc = fcoe_start_io(skb); | 1417 | rc = fcoe_start_io(skb); |
1401 | spin_lock_bh(&fc->fcoe_pending_queue.lock); | 1418 | spin_lock_bh(&port->fcoe_pending_queue.lock); |
1402 | 1419 | ||
1403 | if (rc) { | 1420 | if (rc) { |
1404 | __skb_queue_head(&fc->fcoe_pending_queue, skb); | 1421 | __skb_queue_head(&port->fcoe_pending_queue, skb); |
1405 | /* undo temporary increment above */ | 1422 | /* undo temporary increment above */ |
1406 | fc->fcoe_pending_queue.qlen--; | 1423 | port->fcoe_pending_queue.qlen--; |
1407 | break; | 1424 | break; |
1408 | } | 1425 | } |
1409 | /* undo temporary increment above */ | 1426 | /* undo temporary increment above */ |
1410 | fc->fcoe_pending_queue.qlen--; | 1427 | port->fcoe_pending_queue.qlen--; |
1411 | } | 1428 | } |
1412 | 1429 | ||
1413 | if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) | 1430 | if (port->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) |
1414 | lp->qfull = 0; | 1431 | lp->qfull = 0; |
1415 | if (fc->fcoe_pending_queue.qlen && !timer_pending(&fc->timer)) | 1432 | if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer)) |
1416 | mod_timer(&fc->timer, jiffies + 2); | 1433 | mod_timer(&port->timer, jiffies + 2); |
1417 | fc->fcoe_pending_queue_active = 0; | 1434 | port->fcoe_pending_queue_active = 0; |
1418 | out: | 1435 | out: |
1419 | if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) | 1436 | if (port->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) |
1420 | lp->qfull = 1; | 1437 | lp->qfull = 1; |
1421 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); | 1438 | spin_unlock_bh(&port->fcoe_pending_queue.lock); |
1422 | return; | 1439 | return; |
1423 | } | 1440 | } |
1424 | 1441 | ||
@@ -1453,16 +1470,18 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
1453 | { | 1470 | { |
1454 | struct fc_lport *lp = NULL; | 1471 | struct fc_lport *lp = NULL; |
1455 | struct net_device *netdev = ptr; | 1472 | struct net_device *netdev = ptr; |
1456 | struct fcoe_softc *fc; | 1473 | struct fcoe_interface *fcoe; |
1474 | struct fcoe_port *port = NULL; | ||
1457 | struct fcoe_dev_stats *stats; | 1475 | struct fcoe_dev_stats *stats; |
1458 | u32 link_possible = 1; | 1476 | u32 link_possible = 1; |
1459 | u32 mfs; | 1477 | u32 mfs; |
1460 | int rc = NOTIFY_OK; | 1478 | int rc = NOTIFY_OK; |
1461 | 1479 | ||
1462 | read_lock(&fcoe_hostlist_lock); | 1480 | read_lock(&fcoe_hostlist_lock); |
1463 | list_for_each_entry(fc, &fcoe_hostlist, list) { | 1481 | list_for_each_entry(fcoe, &fcoe_hostlist, list) { |
1464 | if (fc->netdev == netdev) { | 1482 | port = fcoe->priv; |
1465 | lp = fc->ctlr.lp; | 1483 | if (port->netdev == netdev) { |
1484 | lp = port->ctlr.lp; | ||
1466 | break; | 1485 | break; |
1467 | } | 1486 | } |
1468 | } | 1487 | } |
@@ -1493,8 +1512,8 @@ static int fcoe_device_notification(struct notifier_block *notifier, | |||
1493 | "from netdev netlink\n", event); | 1512 | "from netdev netlink\n", event); |
1494 | } | 1513 | } |
1495 | if (link_possible && !fcoe_link_ok(lp)) | 1514 | if (link_possible && !fcoe_link_ok(lp)) |
1496 | fcoe_ctlr_link_up(&fc->ctlr); | 1515 | fcoe_ctlr_link_up(&port->ctlr); |
1497 | else if (fcoe_ctlr_link_down(&fc->ctlr)) { | 1516 | else if (fcoe_ctlr_link_down(&port->ctlr)) { |
1498 | stats = fc_lport_get_stats(lp); | 1517 | stats = fc_lport_get_stats(lp); |
1499 | stats->LinkFailureCount++; | 1518 | stats->LinkFailureCount++; |
1500 | fcoe_clean_pending_queue(lp); | 1519 | fcoe_clean_pending_queue(lp); |
@@ -1668,10 +1687,10 @@ out_nodev: | |||
1668 | 1687 | ||
1669 | module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR); | 1688 | module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR); |
1670 | __MODULE_PARM_TYPE(create, "string"); | 1689 | __MODULE_PARM_TYPE(create, "string"); |
1671 | MODULE_PARM_DESC(create, "Create fcoe port using net device passed in."); | 1690 | MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in."); |
1672 | module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); | 1691 | module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); |
1673 | __MODULE_PARM_TYPE(destroy, "string"); | 1692 | __MODULE_PARM_TYPE(destroy, "string"); |
1674 | MODULE_PARM_DESC(destroy, "Destroy fcoe port"); | 1693 | MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe"); |
1675 | 1694 | ||
1676 | /** | 1695 | /** |
1677 | * fcoe_link_ok() - Check if link is ok for the fc_lport | 1696 | * fcoe_link_ok() - Check if link is ok for the fc_lport |
@@ -1689,8 +1708,8 @@ MODULE_PARM_DESC(destroy, "Destroy fcoe port"); | |||
1689 | */ | 1708 | */ |
1690 | int fcoe_link_ok(struct fc_lport *lp) | 1709 | int fcoe_link_ok(struct fc_lport *lp) |
1691 | { | 1710 | { |
1692 | struct fcoe_softc *fc = lport_priv(lp); | 1711 | struct fcoe_port *port = lport_priv(lp); |
1693 | struct net_device *dev = fc->netdev; | 1712 | struct net_device *dev = port->netdev; |
1694 | struct ethtool_cmd ecmd = { ETHTOOL_GSET }; | 1713 | struct ethtool_cmd ecmd = { ETHTOOL_GSET }; |
1695 | 1714 | ||
1696 | if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && | 1715 | if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && |
@@ -1752,16 +1771,16 @@ void fcoe_percpu_clean(struct fc_lport *lp) | |||
1752 | */ | 1771 | */ |
1753 | void fcoe_clean_pending_queue(struct fc_lport *lp) | 1772 | void fcoe_clean_pending_queue(struct fc_lport *lp) |
1754 | { | 1773 | { |
1755 | struct fcoe_softc *fc = lport_priv(lp); | 1774 | struct fcoe_port *port = lport_priv(lp); |
1756 | struct sk_buff *skb; | 1775 | struct sk_buff *skb; |
1757 | 1776 | ||
1758 | spin_lock_bh(&fc->fcoe_pending_queue.lock); | 1777 | spin_lock_bh(&port->fcoe_pending_queue.lock); |
1759 | while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) { | 1778 | while ((skb = __skb_dequeue(&port->fcoe_pending_queue)) != NULL) { |
1760 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); | 1779 | spin_unlock_bh(&port->fcoe_pending_queue.lock); |
1761 | kfree_skb(skb); | 1780 | kfree_skb(skb); |
1762 | spin_lock_bh(&fc->fcoe_pending_queue.lock); | 1781 | spin_lock_bh(&port->fcoe_pending_queue.lock); |
1763 | } | 1782 | } |
1764 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); | 1783 | spin_unlock_bh(&port->fcoe_pending_queue.lock); |
1765 | } | 1784 | } |
1766 | 1785 | ||
1767 | /** | 1786 | /** |
@@ -1778,21 +1797,21 @@ int fcoe_reset(struct Scsi_Host *shost) | |||
1778 | } | 1797 | } |
1779 | 1798 | ||
1780 | /** | 1799 | /** |
1781 | * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device | 1800 | * fcoe_hostlist_lookup_port() - find the corresponding lport by a given device |
1782 | * @dev: this is currently ptr to net_device | 1801 | * @dev: this is currently ptr to net_device |
1783 | * | 1802 | * |
1784 | * Called with fcoe_hostlist_lock held. | 1803 | * Called with fcoe_hostlist_lock held. |
1785 | * | 1804 | * |
1786 | * Returns: NULL or the located fcoe_softc | 1805 | * Returns: NULL or the located fcoe_port |
1787 | */ | 1806 | */ |
1788 | static struct fcoe_softc * | 1807 | static struct fcoe_interface * |
1789 | fcoe_hostlist_lookup_softc(const struct net_device *dev) | 1808 | fcoe_hostlist_lookup_port(const struct net_device *dev) |
1790 | { | 1809 | { |
1791 | struct fcoe_softc *fc; | 1810 | struct fcoe_interface *fcoe; |
1792 | 1811 | ||
1793 | list_for_each_entry(fc, &fcoe_hostlist, list) { | 1812 | list_for_each_entry(fcoe, &fcoe_hostlist, list) { |
1794 | if (fc->netdev == dev) | 1813 | if (fcoe->priv->netdev == dev) |
1795 | return fc; | 1814 | return fcoe; |
1796 | } | 1815 | } |
1797 | return NULL; | 1816 | return NULL; |
1798 | } | 1817 | } |
@@ -1805,13 +1824,13 @@ fcoe_hostlist_lookup_softc(const struct net_device *dev) | |||
1805 | */ | 1824 | */ |
1806 | struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) | 1825 | struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) |
1807 | { | 1826 | { |
1808 | struct fcoe_softc *fc; | 1827 | struct fcoe_interface *fcoe; |
1809 | 1828 | ||
1810 | read_lock(&fcoe_hostlist_lock); | 1829 | read_lock(&fcoe_hostlist_lock); |
1811 | fc = fcoe_hostlist_lookup_softc(netdev); | 1830 | fcoe = fcoe_hostlist_lookup_port(netdev); |
1812 | read_unlock(&fcoe_hostlist_lock); | 1831 | read_unlock(&fcoe_hostlist_lock); |
1813 | 1832 | ||
1814 | return (fc) ? fc->ctlr.lp : NULL; | 1833 | return (fcoe) ? fcoe->priv->ctlr.lp : NULL; |
1815 | } | 1834 | } |
1816 | 1835 | ||
1817 | /** | 1836 | /** |
@@ -1822,14 +1841,16 @@ struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) | |||
1822 | * | 1841 | * |
1823 | * Returns: 0 for success | 1842 | * Returns: 0 for success |
1824 | */ | 1843 | */ |
1825 | int fcoe_hostlist_add(const struct fc_lport *lp) | 1844 | int fcoe_hostlist_add(const struct fc_lport *lport) |
1826 | { | 1845 | { |
1827 | struct fcoe_softc *fc; | 1846 | struct fcoe_interface *fcoe; |
1828 | 1847 | struct fcoe_port *port; | |
1829 | fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp)); | 1848 | |
1830 | if (!fc) { | 1849 | fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport)); |
1831 | fc = lport_priv(lp); | 1850 | if (!fcoe) { |
1832 | list_add_tail(&fc->list, &fcoe_hostlist); | 1851 | port = lport_priv(lport); |
1852 | fcoe = port->fcoe; | ||
1853 | list_add_tail(&fcoe->list, &fcoe_hostlist); | ||
1833 | } | 1854 | } |
1834 | return 0; | 1855 | return 0; |
1835 | } | 1856 | } |
@@ -1840,14 +1861,14 @@ int fcoe_hostlist_add(const struct fc_lport *lp) | |||
1840 | * | 1861 | * |
1841 | * Returns: 0 for success | 1862 | * Returns: 0 for success |
1842 | */ | 1863 | */ |
1843 | int fcoe_hostlist_remove(const struct fc_lport *lp) | 1864 | int fcoe_hostlist_remove(const struct fc_lport *lport) |
1844 | { | 1865 | { |
1845 | struct fcoe_softc *fc; | 1866 | struct fcoe_interface *fcoe; |
1846 | 1867 | ||
1847 | write_lock_bh(&fcoe_hostlist_lock); | 1868 | write_lock_bh(&fcoe_hostlist_lock); |
1848 | fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp)); | 1869 | fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport)); |
1849 | BUG_ON(!fc); | 1870 | BUG_ON(!fcoe); |
1850 | list_del(&fc->list); | 1871 | list_del(&fcoe->list); |
1851 | write_unlock_bh(&fcoe_hostlist_lock); | 1872 | write_unlock_bh(&fcoe_hostlist_lock); |
1852 | 1873 | ||
1853 | return 0; | 1874 | return 0; |
@@ -1903,19 +1924,18 @@ module_init(fcoe_init); | |||
1903 | static void __exit fcoe_exit(void) | 1924 | static void __exit fcoe_exit(void) |
1904 | { | 1925 | { |
1905 | unsigned int cpu; | 1926 | unsigned int cpu; |
1906 | struct fcoe_softc *fc, *tmp; | 1927 | struct fcoe_interface *fcoe, *tmp; |
1907 | 1928 | ||
1908 | fcoe_dev_cleanup(); | 1929 | fcoe_dev_cleanup(); |
1909 | 1930 | ||
1910 | /* releases the associated fcoe hosts */ | 1931 | /* releases the associated fcoe hosts */ |
1911 | list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) | 1932 | list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) |
1912 | fcoe_if_destroy(fc->ctlr.lp); | 1933 | fcoe_if_destroy(fcoe->priv->ctlr.lp); |
1913 | 1934 | ||
1914 | unregister_hotcpu_notifier(&fcoe_cpu_notifier); | 1935 | unregister_hotcpu_notifier(&fcoe_cpu_notifier); |
1915 | 1936 | ||
1916 | for_each_online_cpu(cpu) { | 1937 | for_each_online_cpu(cpu) |
1917 | fcoe_percpu_thread_destroy(cpu); | 1938 | fcoe_percpu_thread_destroy(cpu); |
1918 | } | ||
1919 | 1939 | ||
1920 | /* detach from scsi transport */ | 1940 | /* detach from scsi transport */ |
1921 | fcoe_if_exit(); | 1941 | fcoe_if_exit(); |
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h index 550d1e49d1a3..060a6dce6580 100644 --- a/drivers/scsi/fcoe/fcoe.h +++ b/drivers/scsi/fcoe/fcoe.h | |||
@@ -75,10 +75,21 @@ struct fcoe_percpu_s { | |||
75 | }; | 75 | }; |
76 | 76 | ||
77 | /* | 77 | /* |
78 | * the fcoe sw transport private data | 78 | * an FCoE interface, 1:1 with netdev |
79 | */ | 79 | */ |
80 | struct fcoe_softc { | 80 | struct fcoe_interface { |
81 | struct list_head list; | 81 | struct list_head list; |
82 | /* This will be removed once all the shared values are | ||
83 | * moved out of fcoe_port */ | ||
84 | struct fcoe_port *priv; | ||
85 | }; | ||
86 | |||
87 | /* | ||
88 | * the FCoE private structure that's allocated along with the | ||
89 | * Scsi_Host and libfc fc_lport structures | ||
90 | */ | ||
91 | struct fcoe_port { | ||
92 | struct fcoe_interface *fcoe; | ||
82 | struct net_device *netdev; | 93 | struct net_device *netdev; |
83 | struct fc_exch_mgr *oem; /* offload exchange manger */ | 94 | struct fc_exch_mgr *oem; /* offload exchange manger */ |
84 | struct packet_type fcoe_packet_type; | 95 | struct packet_type fcoe_packet_type; |
@@ -89,12 +100,12 @@ struct fcoe_softc { | |||
89 | struct fcoe_ctlr ctlr; | 100 | struct fcoe_ctlr ctlr; |
90 | }; | 101 | }; |
91 | 102 | ||
92 | #define fcoe_from_ctlr(fc) container_of(fc, struct fcoe_softc, ctlr) | 103 | #define fcoe_from_ctlr(port) container_of(port, struct fcoe_port, ctlr) |
93 | 104 | ||
94 | static inline struct net_device *fcoe_netdev( | 105 | static inline struct net_device *fcoe_netdev( |
95 | const struct fc_lport *lp) | 106 | const struct fc_lport *lp) |
96 | { | 107 | { |
97 | return ((struct fcoe_softc *)lport_priv(lp))->netdev; | 108 | return ((struct fcoe_port *)lport_priv(lp))->netdev; |
98 | } | 109 | } |
99 | 110 | ||
100 | #endif /* _FCOE_H_ */ | 111 | #endif /* _FCOE_H_ */ |