1 From: Vasu Dev <vasu.dev@linux.intel.com>
2 Subject: Incremental Open-FCoE for Beta6
5 Incremental Open-FCoE update for Beta6.
7 Signed-off-by: Vasu Dev <vasu.dev@linux.intel.com>
8 Acked-by: Hannes Reinecke <hare@suse.de>
10 diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
11 index 6f38b13..4922958 100644
12 --- a/drivers/scsi/Kconfig
13 +++ b/drivers/scsi/Kconfig
14 @@ -328,19 +328,6 @@ menuconfig SCSI_LOWLEVEL
16 if SCSI_LOWLEVEL && SCSI
19 - tristate "LibFC module"
20 - depends on SCSI && SCSI_FC_ATTRS
22 - Fibre Channel library module
25 - tristate "FCoE module"
26 - depends on SCSI && SCSI_FC_ATTRS
29 - Fibre Channel over Ethernet module
32 tristate "iSCSI Initiator over TCP/IP"
33 depends on SCSI && INET
34 @@ -616,6 +603,20 @@ config SCSI_FLASHPOINT
35 substantial, so users of MultiMaster Host Adapters may not
39 + tristate "LibFC module"
40 + depends on SCSI && SCSI_FC_ATTRS
42 + Fibre Channel library module
45 + tristate "FCoE module"
49 + Fibre Channel over Ethernet module
53 tristate "DMX3191D SCSI support"
54 depends on PCI && SCSI
55 diff --git a/drivers/scsi/fcoe/fc_transport_fcoe.c b/drivers/scsi/fcoe/fc_transport_fcoe.c
56 index ff207b2..bf7fe6f 100644
57 --- a/drivers/scsi/fcoe/fc_transport_fcoe.c
58 +++ b/drivers/scsi/fcoe/fc_transport_fcoe.c
60 * Maintained at www.Open-FCoE.org
63 -#include <linux/module.h>
64 -#include <linux/version.h>
65 -#include <linux/kernel.h>
66 -#include <linux/kthread.h>
67 -#include <linux/spinlock.h>
68 -#include <linux/cpu.h>
69 -#include <linux/netdevice.h>
70 -#include <linux/etherdevice.h>
71 -#include <linux/ethtool.h>
72 -#include <linux/if_ether.h>
73 -#include <linux/fs.h>
74 -#include <linux/sysfs.h>
75 -#include <linux/ctype.h>
77 -#include <scsi/libfc/libfc.h>
79 -#include "fcoe_def.h"
81 -MODULE_AUTHOR("Open-FCoE.org");
82 -MODULE_DESCRIPTION("FCoE");
83 -MODULE_LICENSE("GPL");
84 -MODULE_VERSION("1.0.3");
85 +#include <linux/pci.h>
86 +#include <scsi/libfcoe.h>
87 +#include <scsi/fc_transport_fcoe.h>
90 - * Static functions and variables definations
92 -#ifdef CONFIG_HOTPLUG_CPU
93 -static int fcoe_cpu_callback(struct notifier_block *, ulong, void *);
94 -#endif /* CONFIG_HOTPLUG_CPU */
95 -static int fcoe_device_notification(struct notifier_block *, ulong, void *);
96 -static void fcoe_dev_setup(void);
97 -static void fcoe_dev_cleanup(void);
99 -#ifdef CONFIG_HOTPLUG_CPU
100 -static struct notifier_block fcoe_cpu_notifier = {
101 - .notifier_call = fcoe_cpu_callback,
102 +/* internal fcoe transport */
103 +struct fcoe_transport_internal {
104 + struct fcoe_transport *t;
105 + struct net_device *netdev;
106 + struct list_head list;
108 -#endif /* CONFIG_HOTPLUG_CPU */
111 - * notification function from net device
113 -static struct notifier_block fcoe_notifier = {
114 - .notifier_call = fcoe_device_notification,
116 +/* fcoe transports list and its lock */
117 +static LIST_HEAD(fcoe_transports);
118 +static DEFINE_MUTEX(fcoe_transports_lock);
120 -#ifdef CONFIG_HOTPLUG_CPU
122 - * create percpu stats block
123 - * called by cpu add/remove notifier
125 -static void fcoe_create_percpu_data(int cpu)
127 + * fcoe_transport_default - returns ptr to the default transport fcoe_sw
129 +struct fcoe_transport *fcoe_transport_default(void)
131 - struct fc_lport *lp;
132 - struct fcoe_softc *fc;
134 - write_lock_bh(&fcoe_hostlist_lock);
135 - list_for_each_entry(fc, &fcoe_hostlist, list) {
137 - if (lp->dev_stats[cpu] == NULL)
138 - lp->dev_stats[cpu] = kzalloc(sizeof(struct fcoe_dev_stats),
141 - write_unlock_bh(&fcoe_hostlist_lock);
142 + return &fcoe_sw_transport;
146 - * destroy percpu stats block
147 - * called by cpu add/remove notifier
149 -static void fcoe_destroy_percpu_data(int cpu)
151 + * fcoe_transport_to_pcidev - get the pci dev from a netdev
152 + * @netdev: the netdev that pci dev will be retrived from
154 + * Returns: NULL or the corrsponding pci_dev
156 +struct pci_dev *fcoe_transport_pcidev(const struct net_device *netdev)
158 - struct fc_lport *lp;
159 - struct fcoe_softc *fc;
161 - write_lock_bh(&fcoe_hostlist_lock);
162 - list_for_each_entry(fc, &fcoe_hostlist, list) {
164 - kfree(lp->dev_stats[cpu]);
165 - lp->dev_stats[cpu] = NULL;
167 - write_unlock_bh(&fcoe_hostlist_lock);
168 + if (!netdev->dev.parent)
170 + return to_pci_dev(netdev->dev.parent);
174 - * Get notified when a cpu comes on/off. Be hotplug friendly.
176 -static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
179 + * fcoe_transport_device_lookup - find out netdev is managed by the
181 + * assign a transport to a device
182 + * @netdev: the netdev the transport to be attached to
184 + * This will look for existing offload driver, if not found, it falls back to
185 + * the default sw hba (fcoe_sw) as its fcoe transport.
187 + * Returns: 0 for success
189 +static struct fcoe_transport_internal *fcoe_transport_device_lookup(
190 + struct fcoe_transport *t, struct net_device *netdev)
192 - unsigned int cpu = (unsigned long)hcpu;
196 - fcoe_create_percpu_data(cpu);
199 - fcoe_destroy_percpu_data(cpu);
203 + struct fcoe_transport_internal *ti;
205 + /* assign the transpor to this device */
206 + mutex_lock(&t->devlock);
207 + list_for_each_entry(ti, &t->devlist, list) {
208 + if (ti->netdev == netdev) {
209 + mutex_unlock(&t->devlock);
214 + mutex_unlock(&t->devlock);
217 -#endif /* CONFIG_HOTPLUG_CPU */
220 - * function to setup link change notification interface
222 -static void fcoe_dev_setup(void)
224 + * fcoe_transport_device_add - assign a transport to a device
225 + * @netdev: the netdev the transport to be attached to
227 + * This will look for existing offload driver, if not found, it falls back to
228 + * the default sw hba (fcoe_sw) as its fcoe transport.
230 + * Returns: 0 for success
232 +static int fcoe_transport_device_add(struct fcoe_transport *t,
233 + struct net_device *netdev)
236 - * here setup a interface specific wd time to
237 - * monitor the link state
239 - register_netdevice_notifier(&fcoe_notifier);
240 + struct fcoe_transport_internal *ti;
242 + ti = fcoe_transport_device_lookup(t, netdev);
244 + printk(KERN_DEBUG "fcoe_transport_device_add:"
245 + "device %s is already added to transport %s\n",
246 + netdev->name, t->name);
249 + /* allocate an internal struct to host the netdev and the list */
250 + ti = kzalloc(sizeof(*ti), GFP_KERNEL);
255 + ti->netdev = netdev;
256 + INIT_LIST_HEAD(&ti->list);
257 + dev_hold(ti->netdev);
259 + mutex_lock(&t->devlock);
260 + list_add(&ti->list, &t->devlist);
261 + mutex_unlock(&t->devlock);
263 + printk(KERN_DEBUG "fcoe_transport_device_add:"
264 + "device %s added to transport %s\n",
265 + netdev->name, t->name);
271 - * function to cleanup link change notification interface
273 -static void fcoe_dev_cleanup(void)
275 + * fcoe_transport_device_remove - remove a device from its transport
276 + * @netdev: the netdev the transport to be attached to
278 + * this removes the device from the transport so the given transport will
279 + * not manage this device any more
281 + * Returns: 0 for success
283 +static int fcoe_transport_device_remove(struct fcoe_transport *t,
284 + struct net_device *netdev)
286 - unregister_netdevice_notifier(&fcoe_notifier);
287 + struct fcoe_transport_internal *ti;
289 + ti = fcoe_transport_device_lookup(t, netdev);
291 + printk(KERN_DEBUG "fcoe_transport_device_remove:"
292 + "device %s is not managed by transport %s\n",
293 + netdev->name, t->name);
296 + mutex_lock(&t->devlock);
297 + list_del(&ti->list);
298 + mutex_unlock(&t->devlock);
299 + printk(KERN_DEBUG "fcoe_transport_device_remove:"
300 + "device %s removed from transport %s\n",
301 + netdev->name, t->name);
302 + dev_put(ti->netdev);
308 - * This function is called by the ethernet driver
309 - * this is called in case of link change event
311 -static int fcoe_device_notification(struct notifier_block *notifier,
312 - ulong event, void *ptr)
314 + * fcoe_transport_device_remove_all - remove all from transport devlist
316 + * this removes the device from the transport so the given transport will
317 + * not manage this device any more
319 + * Returns: 0 for success
321 +static void fcoe_transport_device_remove_all(struct fcoe_transport *t)
323 - struct fc_lport *lp = NULL;
324 - struct net_device *real_dev = ptr;
325 - struct fcoe_softc *fc;
326 - struct fcoe_dev_stats *stats;
329 - int rc = NOTIFY_OK;
331 - read_lock(&fcoe_hostlist_lock);
332 - list_for_each_entry(fc, &fcoe_hostlist, list) {
333 - if (fc->real_dev == real_dev) {
338 - read_unlock(&fcoe_hostlist_lock);
343 + struct fcoe_transport_internal *ti, *tmp;
345 - new_status = lp->link_status;
348 - case NETDEV_GOING_DOWN:
349 - new_status &= ~FC_LINK_UP;
352 - case NETDEV_CHANGE:
353 - new_status &= ~FC_LINK_UP;
354 - if (!fcoe_link_ok(lp))
355 - new_status |= FC_LINK_UP;
357 - case NETDEV_CHANGEMTU:
358 - mfs = fc->real_dev->mtu -
359 - (sizeof(struct fcoe_hdr) +
360 - sizeof(struct fcoe_crc_eof));
361 - if (fc->user_mfs && fc->user_mfs < mfs)
362 - mfs = fc->user_mfs;
363 - if (mfs >= FC_MIN_MAX_FRAME)
364 - fc_set_mfs(lp, mfs);
365 - new_status &= ~FC_LINK_UP;
366 - if (!fcoe_link_ok(lp))
367 - new_status |= FC_LINK_UP;
369 - case NETDEV_REGISTER:
372 - FC_DBG("unknown event %ld call", event);
374 - if (lp->link_status != new_status) {
375 - if ((new_status & FC_LINK_UP) == FC_LINK_UP)
378 - stats = lp->dev_stats[smp_processor_id()];
380 - stats->LinkFailureCount++;
382 - fcoe_clean_pending_queue(lp);
384 + mutex_lock(&t->devlock);
385 + list_for_each_entry_safe(ti, tmp, &t->devlist, list) {
386 + list_del(&ti->list);
391 + mutex_unlock(&t->devlock);
394 -static void trimstr(char *str, int len)
396 + * fcoe_transport_match - use the bus device match function to match the hw
397 + * @t: the fcoe transport
400 + * This function is used to check if the givne transport wants to manage the
401 + * input netdev. if the transports implements the match function, it will be
402 + * called, o.w. we just compare the pci vendor and device id.
404 + * Returns: true for match up
406 +static bool fcoe_transport_match(struct fcoe_transport *t,
407 + struct net_device *netdev)
409 - char *cp = str + len;
410 - while (--cp >= str && *cp == '\n')
412 + /* match transport by vendor and device id */
413 + struct pci_dev *pci;
415 + pci = fcoe_transport_pcidev(netdev);
418 + printk(KERN_DEBUG "fcoe_transport_match:"
419 + "%s:%x:%x -- %s:%x:%x\n",
420 + t->name, t->vendor, t->device,
421 + netdev->name, pci->vendor, pci->device);
423 + /* if transport supports match */
425 + return t->match(netdev);
427 + /* else just compare the vendor and device id: pci only */
428 + return (t->vendor == pci->vendor) && (t->device == pci->device);
433 -static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
435 + * fcoe_transport_lookup - check if the transport is already registered
436 + * @t: the transport to be looked up
438 + * This compares the parent device (pci) vendor and device id
440 + * Returns: NULL if not found
442 + * TODO - return default sw transport if no other transport is found
444 +static struct fcoe_transport *fcoe_transport_lookup(
445 + struct net_device *netdev)
447 - struct net_device *netdev;
448 - char ifname[IFNAMSIZ + 2];
451 - strlcpy(ifname, buffer, IFNAMSIZ);
452 - trimstr(ifname, strlen(ifname));
453 - netdev = dev_get_by_name(&init_net, ifname);
455 - rc = fcoe_destroy_interface(netdev);
457 + struct fcoe_transport *t;
459 + mutex_lock(&fcoe_transports_lock);
460 + list_for_each_entry(t, &fcoe_transports, list) {
461 + if (fcoe_transport_match(t, netdev)) {
462 + mutex_unlock(&fcoe_transports_lock);
467 + mutex_unlock(&fcoe_transports_lock);
469 + printk(KERN_DEBUG "fcoe_transport_lookup:"
470 + "use default transport for %s\n", netdev->name);
471 + return fcoe_transport_default();
474 -static int fcoe_create(const char *buffer, struct kernel_param *kp)
476 + * fcoe_transport_register - adds a fcoe transport to the fcoe transports list
477 + * @t: ptr to the fcoe transport to be added
479 + * Returns: 0 for success
481 +int fcoe_transport_register(struct fcoe_transport *t)
483 - struct net_device *netdev;
484 - char ifname[IFNAMSIZ + 2];
487 - strlcpy(ifname, buffer, IFNAMSIZ);
488 - trimstr(ifname, strlen(ifname));
489 - netdev = dev_get_by_name(&init_net, ifname);
491 - rc = fcoe_create_interface(netdev);
493 + struct fcoe_transport *tt;
495 + /* TODO - add fcoe_transport specific initialization here */
496 + mutex_lock(&fcoe_transports_lock);
497 + list_for_each_entry(tt, &fcoe_transports, list) {
499 + mutex_unlock(&fcoe_transports_lock);
504 + list_add_tail(&t->list, &fcoe_transports);
505 + mutex_unlock(&fcoe_transports_lock);
507 + mutex_init(&t->devlock);
508 + INIT_LIST_HEAD(&t->devlist);
510 + printk(KERN_DEBUG "fcoe_transport_register:%s\n", t->name);
514 +EXPORT_SYMBOL_GPL(fcoe_transport_register);
516 -module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
517 -__MODULE_PARM_TYPE(create, "string");
518 -MODULE_PARM_DESC(create, "Create fcoe port using net device passed in.");
519 -module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
520 -__MODULE_PARM_TYPE(destroy, "string");
521 -MODULE_PARM_DESC(destroy, "Destroy fcoe port");
523 + * fcoe_transport_unregister - remove the tranport fro the fcoe transports list
524 + * @t: ptr to the fcoe transport to be removed
526 + * Returns: 0 for success
528 +int fcoe_transport_unregister(struct fcoe_transport *t)
530 + struct fcoe_transport *tt, *tmp;
532 + mutex_lock(&fcoe_transports_lock);
533 + list_for_each_entry_safe(tt, tmp, &fcoe_transports, list) {
535 + list_del(&t->list);
536 + mutex_unlock(&fcoe_transports_lock);
537 + fcoe_transport_device_remove_all(t);
538 + printk(KERN_DEBUG "fcoe_transport_unregister:%s\n",
543 + mutex_unlock(&fcoe_transports_lock);
546 +EXPORT_SYMBOL_GPL(fcoe_transport_unregister);
549 - * Initialization routine
550 - * 1. Will create fc transport software structure
551 - * 2. initialize the link list of port information structure
553 -static int __init fcoe_init(void)
554 + * fcoe_load_transport_driver - load an offload driver by alias name
555 + * @netdev: the target net device
557 + * Requests for an offload driver module as the fcoe transport, if fails, it
558 + * falls back to use the SW HBA (fcoe_sw) as its transport
561 + * 1. supports only PCI device
562 + * 2. needs fix for VLAn and bonding
563 + * 3. pure hw fcoe hba may not have netdev
565 + * Returns: 0 for success
567 +int fcoe_load_transport_driver(struct net_device *netdev)
570 - struct fcoe_percpu_s *p;
572 - rwlock_init(&fcoe_hostlist_lock);
574 -#ifdef CONFIG_HOTPLUG_CPU
575 - register_cpu_notifier(&fcoe_cpu_notifier);
576 -#endif /* CONFIG_HOTPLUG_CPU */
579 - * initialize per CPU interrupt thread
581 - for_each_online_cpu(cpu) {
582 - p = kzalloc(sizeof(struct fcoe_percpu_s), GFP_KERNEL);
584 - p->thread = kthread_create(fcoe_percpu_receive_thread,
586 - "fcoethread/%d", cpu);
589 - * if there is no error then bind the thread to the cpu
590 - * initialize the semaphore and skb queue head
592 - if (likely(!IS_ERR(p->thread))) {
594 - fcoe_percpu[cpu] = p;
595 - skb_queue_head_init(&p->fcoe_rx_list);
596 - kthread_bind(p->thread, cpu);
597 - wake_up_process(p->thread);
599 - fcoe_percpu[cpu] = NULL;
604 + struct pci_dev *pci;
605 + struct device *dev = netdev->dev.parent;
607 + if (fcoe_transport_lookup(netdev)) {
608 + /* load default transport */
609 + printk(KERN_DEBUG "fcoe: already loaded transport for %s\n",
615 - * setup link change notification
618 + pci = to_pci_dev(dev);
619 + if (dev->bus != &pci_bus_type) {
620 + printk(KERN_DEBUG "fcoe: support noly PCI device\n");
623 + printk(KERN_DEBUG "fcoe: loading driver fcoe-pci-0x%04x-0x%04x\n",
624 + pci->vendor, pci->device);
626 + return request_module("fcoe-pci-0x%04x-0x%04x",
627 + pci->vendor, pci->device);
629 - init_timer(&fcoe_timer);
630 - fcoe_timer.data = 0;
631 - fcoe_timer.function = fcoe_watchdog;
632 - fcoe_timer.expires = (jiffies + (10 * HZ));
633 - add_timer(&fcoe_timer);
635 +EXPORT_SYMBOL_GPL(fcoe_load_transport_driver);
637 - if (fcoe_sw_init() != 0) {
638 - FC_DBG("fail to attach fc transport");
641 + * fcoe_transport_attach - load transport to fcoe
642 + * @netdev: the netdev the transport to be attached to
644 + * This will look for existing offload driver, if not found, it falls back to
645 + * the default sw hba (fcoe_sw) as its fcoe transport.
647 + * Returns: 0 for success
649 +int fcoe_transport_attach(struct net_device *netdev)
651 + struct fcoe_transport *t;
653 + /* find the corresponding transport */
654 + t = fcoe_transport_lookup(netdev);
656 + printk(KERN_DEBUG "fcoe_transport_attach"
657 + ":no transport for %s:use %s\n",
658 + netdev->name, t->name);
661 + /* add to the transport */
662 + if (fcoe_transport_device_add(t, netdev)) {
663 + printk(KERN_DEBUG "fcoe_transport_attach"
664 + ":failed to add %s to tramsport %s\n",
665 + netdev->name, t->name);
668 + /* transport create function */
672 + printk(KERN_DEBUG "fcoe_transport_attach:transport %s for %s\n",
673 + t->name, netdev->name);
676 -module_init(fcoe_init);
677 +EXPORT_SYMBOL_GPL(fcoe_transport_attach);
679 -static void __exit fcoe_exit(void)
681 + * fcoe_transport_release - unload transport from fcoe
682 + * @netdev: the net device on which fcoe is to be released
684 + * Returns: 0 for success
686 +int fcoe_transport_release(struct net_device *netdev)
689 - struct fcoe_softc *fc, *tmp;
690 - struct fcoe_percpu_s *p;
691 - struct sk_buff *skb;
694 - * Stop all call back interfaces
696 -#ifdef CONFIG_HOTPLUG_CPU
697 - unregister_cpu_notifier(&fcoe_cpu_notifier);
698 -#endif /* CONFIG_HOTPLUG_CPU */
699 - fcoe_dev_cleanup();
704 - del_timer_sync(&fcoe_timer);
707 - * assuming that at this time there will be no
708 - * ioctl in prograss, therefore we do not need to lock the
711 - list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
712 - fcoe_destroy_interface(fc->real_dev);
714 - for (idx = 0; idx < NR_CPUS; idx++) {
715 - if (fcoe_percpu[idx]) {
716 - kthread_stop(fcoe_percpu[idx]->thread);
717 - p = fcoe_percpu[idx];
718 - spin_lock_bh(&p->fcoe_rx_list.lock);
719 - while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
721 - spin_unlock_bh(&p->fcoe_rx_list.lock);
722 - if (fcoe_percpu[idx]->crc_eof_page)
723 - put_page(fcoe_percpu[idx]->crc_eof_page);
724 - kfree(fcoe_percpu[idx]);
726 + struct fcoe_transport *t;
728 + /* find the corresponding transport */
729 + t = fcoe_transport_lookup(netdev);
731 + printk(KERN_DEBUG "fcoe_transport_release:"
732 + "no transport for %s:use %s\n",
733 + netdev->name, t->name);
736 + /* remove the device from the transport */
737 + if (fcoe_transport_device_remove(t, netdev)) {
738 + printk(KERN_DEBUG "fcoe_transport_release:"
739 + "failed to add %s to tramsport %s\n",
740 + netdev->name, t->name);
743 + /* transport destroy function */
745 + t->destroy(netdev);
747 + printk(KERN_DEBUG "fcoe_transport_release:"
748 + "device %s dettached from transport %s\n",
749 + netdev->name, t->name);
753 +EXPORT_SYMBOL_GPL(fcoe_transport_release);
756 + * fcoe_transport_init - initializes fcoe transport layer
758 + * This prepares for the fcoe transport layer
762 +int __init fcoe_transport_init(void)
764 + INIT_LIST_HEAD(&fcoe_transports);
765 + mutex_init(&fcoe_transports_lock);
771 + * fcoe_transport_exit - cleans up the fcoe transport layer
772 + * This cleans up the fcoe transport layer. removing any transport on the list,
773 + * note that the transport destroy func is not called here.
777 +int __exit fcoe_transport_exit(void)
779 + struct fcoe_transport *t, *tmp;
781 + mutex_lock(&fcoe_transports_lock);
782 + list_for_each_entry_safe(t, tmp, &fcoe_transports, list) {
783 + list_del(&t->list);
784 + mutex_unlock(&fcoe_transports_lock);
785 + fcoe_transport_device_remove_all(t);
786 + mutex_lock(&fcoe_transports_lock);
788 + mutex_unlock(&fcoe_transports_lock);
791 -module_exit(fcoe_exit);
792 diff --git a/drivers/scsi/fcoe/fcoe_def.h b/drivers/scsi/fcoe/fcoe_def.h
793 deleted file mode 100644
794 index b00e14b..0000000
795 --- a/drivers/scsi/fcoe/fcoe_def.h
799 - * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
801 - * This program is free software; you can redistribute it and/or modify it
802 - * under the terms and conditions of the GNU General Public License,
803 - * version 2, as published by the Free Software Foundation.
805 - * This program is distributed in the hope it will be useful, but WITHOUT
806 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
807 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
810 - * You should have received a copy of the GNU General Public License along with
811 - * this program; if not, write to the Free Software Foundation, Inc.,
812 - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
814 - * Maintained at www.Open-FCoE.org
817 -#ifndef _FCOE_DEF_H_
818 -#define _FCOE_DEF_H_
820 -#include <linux/etherdevice.h>
821 -#include <linux/if_ether.h>
823 -#include <scsi/libfc/libfc.h>
825 -#include <scsi/fc/fc_fcoe.h>
827 -#define FCOE_DRIVER_NAME "fcoe" /* driver name for ioctls */
828 -#define FCOE_DRIVER_VENDOR "Open-FC.org" /* vendor name for ioctls */
830 -#define FCOE_MIN_FRAME 36
831 -#define FCOE_WORD_TO_BYTE 4
834 - * this is the main common structure across all instance of fcoe driver.
835 - * There is one to one mapping between hba struct and ethernet nic.
836 - * list of hbas contains pointer to the hba struct, these structures are
837 - * stored in this array using there corresponding if_index.
840 -struct fcoe_percpu_s {
842 - struct task_struct *thread;
843 - struct sk_buff_head fcoe_rx_list;
844 - struct page *crc_eof_page;
845 - int crc_eof_offset;
848 -extern struct timer_list fcoe_timer;
849 -extern rwlock_t fcoe_hostlist_lock;
850 -extern struct list_head fcoe_hostlist;
851 -extern struct fcoe_percpu_s *fcoe_percpu[];
854 - struct list_head list;
855 - struct fc_lport *lp;
856 - struct net_device *real_dev;
857 - struct net_device *phys_dev; /* device with ethtool_ops */
858 - struct packet_type fcoe_packet_type;
859 - struct sk_buff_head fcoe_pending_queue;
860 - u16 user_mfs; /* configured max frame size */
862 - u8 dest_addr[ETH_ALEN];
863 - u8 ctl_src_addr[ETH_ALEN];
864 - u8 data_src_addr[ETH_ALEN];
866 - * fcoe protocol address learning related stuff
873 -int fcoe_percpu_receive_thread(void *arg);
876 - * HBA transport ops prototypes
878 -void fcoe_clean_pending_queue(struct fc_lport *fd);
879 -void fcoe_watchdog(ulong vp);
880 -int fcoe_destroy_interface(struct net_device *);
881 -int fcoe_create_interface(struct net_device *);
882 -int fcoe_xmit(struct fc_lport *, struct fc_frame *);
883 -int fcoe_rcv(struct sk_buff *, struct net_device *,
884 - struct packet_type *, struct net_device *);
885 -int fcoe_link_ok(struct fc_lport *);
887 -int __init fcoe_sw_init(void);
888 -void __exit fcoe_sw_exit(void);
889 -#endif /* _FCOE_DEF_H_ */
890 diff --git a/drivers/scsi/fcoe/fcoe_sw.c b/drivers/scsi/fcoe/fcoe_sw.c
891 index d7ceb1b..33aebe5 100644
892 --- a/drivers/scsi/fcoe/fcoe_sw.c
893 +++ b/drivers/scsi/fcoe/fcoe_sw.c
895 * Maintained at www.Open-FCoE.org
899 - * FCOE protocol file
902 #include <linux/module.h>
903 #include <linux/version.h>
904 #include <linux/kernel.h>
905 +#include <linux/pci.h>
906 #include <linux/init.h>
907 #include <linux/spinlock.h>
908 #include <linux/netdevice.h>
909 #include <linux/etherdevice.h>
910 -#include <linux/ethtool.h>
911 -#include <linux/if_ether.h>
912 #include <linux/if_vlan.h>
913 #include <net/rtnetlink.h>
916 #include <scsi/scsi_transport.h>
917 #include <scsi/scsi_transport_fc.h>
919 -#include <scsi/libfc/libfc.h>
921 -#include <scsi/fc/fc_fcoe.h>
922 -#include "fcoe_def.h"
923 +#include <scsi/libfc.h>
924 +#include <scsi/libfcoe.h>
925 +#include <scsi/fc_transport_fcoe.h>
927 -#define FCOE_VERSION "0.1"
928 +#define FCOE_SW_VERSION "0.1"
929 +#define FCOE_SW_NAME "fcoesw"
930 +#define FCOE_SW_VENDOR "Open-FCoE.org"
932 #define FCOE_MAX_LUN 255
933 #define FCOE_MAX_FCP_TARGET 256
935 #define FCOE_MAX_OUTSTANDING_COMMANDS 1024
937 -#define FCOE_MIN_XID 0x0004
938 -#define FCOE_MAX_XID 0x07ef
939 +#define FCOE_MIN_XID 0x0001 /* the min xid supported by fcoe_sw */
940 +#define FCOE_MAX_XID 0x07ef /* the max xid supported by fcoe_sw */
942 -LIST_HEAD(fcoe_hostlist);
943 -DEFINE_RWLOCK(fcoe_hostlist_lock);
944 -DEFINE_TIMER(fcoe_timer, NULL, 0, 0);
945 -struct fcoe_percpu_s *fcoe_percpu[NR_CPUS];
947 -static struct scsi_transport_template *fcoe_transport_template;
949 -static int fcoe_reset(struct Scsi_Host *shost)
951 - struct fc_lport *lport = shost_priv(shost);
952 - fc_lport_reset(lport);
955 +static struct scsi_transport_template *scsi_transport_fcoe_sw;
957 -struct fc_function_template fcoe_transport_function = {
958 +struct fc_function_template fcoe_sw_transport_function = {
959 .show_host_node_name = 1,
960 .show_host_port_name = 1,
961 .show_host_supported_classes = 1,
962 @@ -101,60 +85,10 @@ struct fc_function_template fcoe_transport_function = {
963 .terminate_rport_io = fc_rport_terminate_io,
966 -static struct fcoe_softc *fcoe_find_fc_lport(const struct net_device *netdev)
968 - struct fcoe_softc *fc;
970 - read_lock(&fcoe_hostlist_lock);
971 - list_for_each_entry(fc, &fcoe_hostlist, list) {
972 - if (fc->real_dev == netdev) {
973 - read_unlock(&fcoe_hostlist_lock);
977 - read_unlock(&fcoe_hostlist_lock);
982 - * Convert 48-bit IEEE MAC address to 64-bit FC WWN.
984 -static u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
985 - unsigned int scheme, unsigned int port)
990 - /* The MAC is in NO, so flip only the low 48 bits */
991 - host_mac = ((u64) mac[0] << 40) |
992 - ((u64) mac[1] << 32) |
993 - ((u64) mac[2] << 24) |
994 - ((u64) mac[3] << 16) |
995 - ((u64) mac[4] << 8) |
998 - WARN_ON(host_mac >= (1ULL << 48));
999 - wwn = host_mac | ((u64) scheme << 60);
1002 - WARN_ON(port != 0);
1005 - WARN_ON(port >= 0xfff);
1006 - wwn |= (u64) port << 48;
1016 -static struct scsi_host_template fcoe_driver_template = {
1017 +static struct scsi_host_template fcoe_sw_shost_template = {
1018 .module = THIS_MODULE,
1019 .name = "FCoE Driver",
1020 - .proc_name = FCOE_DRIVER_NAME,
1021 + .proc_name = FCOE_SW_NAME,
1022 .queuecommand = fc_queuecommand,
1023 .eh_abort_handler = fc_eh_abort,
1024 .eh_device_reset_handler = fc_eh_device_reset,
1025 @@ -170,138 +104,18 @@ static struct scsi_host_template fcoe_driver_template = {
1026 .max_sectors = 0xffff,
1029 -int fcoe_destroy_interface(struct net_device *netdev)
1032 - struct fcoe_percpu_s *pp;
1033 - struct fcoe_softc *fc;
1034 - struct fcoe_rcv_info *fr;
1035 - struct sk_buff_head *list;
1036 - struct sk_buff *skb, *next;
1037 - struct sk_buff *head;
1038 - struct fc_lport *lp;
1039 - u8 flogi_maddr[ETH_ALEN];
1041 - fc = fcoe_find_fc_lport(netdev);
1047 - /* Remove the instance from fcoe's list */
1048 - write_lock_bh(&fcoe_hostlist_lock);
1049 - list_del(&fc->list);
1050 - write_unlock_bh(&fcoe_hostlist_lock);
1052 - /* Don't listen for Ethernet packets anymore */
1053 - dev_remove_pack(&fc->fcoe_packet_type);
1055 - /* Detach from the scsi-ml */
1056 - fc_remove_host(lp->host);
1057 - scsi_remove_host(lp->host);
1059 - /* Cleanup the fc_lport */
1060 - fc_lport_destroy(lp);
1061 - fc_fcp_destroy(lp);
1063 - fc_exch_mgr_free(lp->emp);
1065 - /* Delete secondary MAC addresses */
1067 - memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
1068 - dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
1069 - if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
1070 - dev_unicast_delete(fc->real_dev, fc->data_src_addr, ETH_ALEN);
1073 - /* Free the per-CPU revieve threads */
1074 - for (idx = 0; idx < NR_CPUS; idx++) {
1075 - if (fcoe_percpu[idx]) {
1076 - pp = fcoe_percpu[idx];
1077 - spin_lock_bh(&pp->fcoe_rx_list.lock);
1078 - list = &pp->fcoe_rx_list;
1079 - head = list->next;
1080 - for (skb = head; skb != (struct sk_buff *)list;
1083 - fr = fcoe_dev_from_skb(skb);
1084 - if (fr->fr_dev == fc->lp) {
1085 - __skb_unlink(skb, list);
1089 - spin_unlock_bh(&pp->fcoe_rx_list.lock);
1093 - /* Free existing skbs */
1094 - fcoe_clean_pending_queue(lp);
1096 - /* Free memory used by statistical counters */
1097 - for_each_online_cpu(cpu)
1098 - kfree(lp->dev_stats[cpu]);
1100 - /* Release the net_device and Scsi_Host */
1101 - dev_put(fc->real_dev);
1102 - scsi_host_put(lp->host);
1107 - * Return zero if link is OK for use by FCoE.
1108 - * Any permanently-disqualifying conditions have been previously checked.
1109 - * This also updates the speed setting, which may change with link for 100/1000.
1110 + * fcoe_sw_lport_config - sets up the fc_lport
1111 + * @lp: ptr to the fc_lport
1112 + * @shost: ptr to the parent scsi host
1114 + * Returns: 0 for success
1116 - * This function should probably be checking for PAUSE support at some point
1117 - * in the future. Currently Per-priority-pause is not determinable using
1118 - * ethtool, so we shouldn't be restrictive until that problem is resolved.
1120 -int fcoe_link_ok(struct fc_lport *lp)
1122 - struct fcoe_softc *fc = (struct fcoe_softc *)lp->drv_priv;
1123 - struct net_device *dev = fc->real_dev;
1124 - struct ethtool_cmd ecmd = { ETHTOOL_GSET };
1127 - if ((dev->flags & IFF_UP) && netif_carrier_ok(dev)) {
1128 - dev = fc->phys_dev;
1129 - if (dev->ethtool_ops->get_settings) {
1130 - dev->ethtool_ops->get_settings(dev, &ecmd);
1131 - lp->link_supported_speeds &=
1132 - ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
1133 - if (ecmd.supported & (SUPPORTED_1000baseT_Half |
1134 - SUPPORTED_1000baseT_Full))
1135 - lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
1136 - if (ecmd.supported & SUPPORTED_10000baseT_Full)
1137 - lp->link_supported_speeds |=
1138 - FC_PORTSPEED_10GBIT;
1139 - if (ecmd.speed == SPEED_1000)
1140 - lp->link_speed = FC_PORTSPEED_1GBIT;
1141 - if (ecmd.speed == SPEED_10000)
1142 - lp->link_speed = FC_PORTSPEED_10GBIT;
1150 -static struct libfc_function_template fcoe_libfc_fcn_templ = {
1151 - .frame_send = fcoe_xmit,
1154 -static int lport_config(struct fc_lport *lp, struct Scsi_Host *shost)
1155 +static int fcoe_sw_lport_config(struct fc_lport *lp)
1160 - lp->drv_priv = (void *)(lp + 1);
1162 - lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
1163 - FCOE_MIN_XID, FCOE_MAX_XID);
1167 lp->link_status = 0;
1168 lp->max_retry_count = 3;
1169 lp->e_d_tov = 2 * 1000; /* FC-FS default */
1170 @@ -316,25 +130,39 @@ static int lport_config(struct fc_lport *lp, struct Scsi_Host *shost)
1171 lp->dev_stats[i] = kzalloc(sizeof(struct fcoe_dev_stats),
1174 - /* Finish fc_lport configuration */
1175 + /* lport fc_lport related configuration */
1176 fc_lport_config(lp);
1181 -static int net_config(struct fc_lport *lp)
1183 + * fcoe_sw_netdev_config - sets up fcoe_softc for lport and network
1184 + * related properties
1185 + * @lp : ptr to the fc_lport
1186 + * @netdev : ptr to the associated netdevice struct
1188 + * Must be called after fcoe_sw_lport_config() as it will use lport mutex
1190 + * Returns : 0 for success
1193 +static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev)
1197 - struct net_device *net_dev;
1198 - struct fcoe_softc *fc = (struct fcoe_softc *)lp->drv_priv;
1199 + struct fcoe_softc *fc;
1200 u8 flogi_maddr[ETH_ALEN];
1202 + /* Setup lport private data to point to fcoe softc */
1203 + fc = lport_priv(lp);
1205 + fc->real_dev = netdev;
1206 + fc->phys_dev = netdev;
1208 /* Require support for get_pauseparam ethtool op. */
1209 - net_dev = fc->real_dev;
1210 - if (net_dev->priv_flags & IFF_802_1Q_VLAN)
1211 - net_dev = vlan_dev_real_dev(net_dev);
1212 - fc->phys_dev = net_dev;
1213 + if (netdev->priv_flags & IFF_802_1Q_VLAN)
1214 + fc->phys_dev = vlan_dev_real_dev(netdev);
1216 /* Do not support for bonding device */
1217 if ((fc->real_dev->priv_flags & IFF_MASTER_ALB) ||
1218 @@ -356,6 +184,7 @@ static int net_config(struct fc_lport *lp)
1219 if (!fcoe_link_ok(lp))
1220 lp->link_status |= FC_LINK_UP;
1222 + /* offload features support */
1223 if (fc->real_dev->features & NETIF_F_SG)
1226 @@ -394,96 +223,210 @@ static int net_config(struct fc_lport *lp)
1230 -static void shost_config(struct fc_lport *lp)
1232 + * fcoe_sw_shost_config - sets up fc_lport->host
1233 + * @lp : ptr to the fc_lport
1234 + * @shost : ptr to the associated scsi host
1235 + * @dev : device associated to scsi host
1237 + * Must be called after fcoe_sw_lport_config) and fcoe_sw_netdev_config()
1239 + * Returns : 0 for success
1242 +static int fcoe_sw_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
1243 + struct device *dev)
1247 + /* lport scsi host config */
1250 lp->host->max_lun = FCOE_MAX_LUN;
1251 lp->host->max_id = FCOE_MAX_FCP_TARGET;
1252 lp->host->max_channel = 0;
1253 - lp->host->transportt = fcoe_transport_template;
1254 + lp->host->transportt = scsi_transport_fcoe_sw;
1256 + /* add the new host to the SCSI-ml */
1257 + rc = scsi_add_host(lp->host, dev);
1259 + FC_DBG("fcoe_sw_shost_config:error on scsi_add_host\n");
1262 + sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
1263 + FCOE_SW_NAME, FCOE_SW_VERSION,
1264 + fcoe_netdev(lp)->name);
1269 -static int libfc_config(struct fc_lport *lp)
1271 + * fcoe_sw_em_config - allocates em for this lport
1272 + * @lp: the port that em is to allocated for
1274 + * Returns : 0 on success
1276 +static inline int fcoe_sw_em_config(struct fc_lport *lp)
1278 - /* Set the function pointers set by the LLDD */
1279 - memcpy(&lp->tt, &fcoe_libfc_fcn_templ,
1280 - sizeof(struct libfc_function_template));
1283 - if (fc_fcp_init(lp))
1284 + lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
1285 + FCOE_MIN_XID, FCOE_MAX_XID);
1289 - fc_lport_init(lp);
1290 - fc_rport_init(lp);
1297 - * This function creates the fcoe interface
1298 - * create struct fcdev which is a shared structure between opefc
1299 - * and transport level protocol.
1300 + * fcoe_sw_destroy - FCoE software HBA tear-down function
1301 + * @netdev: ptr to the associated net_device
1303 + * Returns: 0 if link is OK for use by FCoE.
1305 -int fcoe_create_interface(struct net_device *netdev)
1306 +static int fcoe_sw_destroy(struct net_device *netdev)
1309 + struct fc_lport *lp = NULL;
1310 + struct fcoe_softc *fc;
1311 + u8 flogi_maddr[ETH_ALEN];
1315 + printk(KERN_DEBUG "fcoe_sw_destroy:interface on %s\n",
1318 + lp = fcoe_hostlist_lookup(netdev);
1322 + fc = fcoe_softc(lp);
1324 + /* Remove the instance from fcoe's list */
1325 + fcoe_hostlist_remove(lp);
1327 + /* Don't listen for Ethernet packets anymore */
1328 + dev_remove_pack(&fc->fcoe_packet_type);
1330 + /* Cleanup the fc_lport */
1331 + fc_lport_destroy(lp);
1332 + fc_fcp_destroy(lp);
1334 + /* Detach from the scsi-ml */
1335 + fc_remove_host(lp->host);
1336 + scsi_remove_host(lp->host);
1338 + /* There are no more rports or I/O, free the EM */
1340 + fc_exch_mgr_free(lp->emp);
1342 + /* Delete secondary MAC addresses */
1344 + memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
1345 + dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
1346 + if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
1347 + dev_unicast_delete(fc->real_dev, fc->data_src_addr, ETH_ALEN);
1350 + /* Free the per-CPU revieve threads */
1351 + fcoe_percpu_clean(lp);
1353 + /* Free existing skbs */
1354 + fcoe_clean_pending_queue(lp);
1356 + /* Free memory used by statistical counters */
1357 + for_each_online_cpu(cpu)
1358 + kfree(lp->dev_stats[cpu]);
1360 + /* Release the net_device and Scsi_Host */
1361 + dev_put(fc->real_dev);
1362 + scsi_host_put(lp->host);
1367 +static struct libfc_function_template fcoe_sw_libfc_fcn_templ = {
1368 + .frame_send = fcoe_xmit,
1372 + * fcoe_sw_create - this function creates the fcoe interface
1373 + * @netdev: pointer the associated netdevice
1375 + * Creates fc_lport struct and scsi_host for lport, configures lport
1376 + * and starts fabric login.
1378 + * Returns : 0 on success
1380 +static int fcoe_sw_create(struct net_device *netdev)
1383 struct fc_lport *lp = NULL;
1384 struct fcoe_softc *fc;
1385 struct Scsi_Host *shost;
1388 - if (fcoe_find_fc_lport(netdev) != NULL)
1391 + printk(KERN_DEBUG "fcoe_sw_create:interface on %s\n",
1394 + lp = fcoe_hostlist_lookup(netdev);
1398 - shost = scsi_host_alloc(&fcoe_driver_template,
1399 - sizeof(struct fc_lport) +
1400 + shost = fcoe_host_alloc(&fcoe_sw_shost_template,
1401 sizeof(struct fcoe_softc));
1404 FC_DBG("Could not allocate host structure\n");
1408 lp = shost_priv(shost);
1409 - rc = lport_config(lp, shost);
1411 - goto out_host_put;
1413 - /* Configure the fcoe_softc */
1414 - fc = (struct fcoe_softc *)lp->drv_priv;
1416 - fc->real_dev = netdev;
1418 + fc = lport_priv(lp);
1420 + /* configure fc_lport, e.g., em */
1421 + rc = fcoe_sw_lport_config(lp);
1423 + FC_DBG("Could not configure lport\n");
1424 + goto out_host_put;
1427 - /* Add the new host to the SCSI-ml */
1428 - rc = scsi_add_host(lp->host, NULL);
1429 + /* configure lport network properties */
1430 + rc = fcoe_sw_netdev_config(lp, netdev);
1432 - FC_DBG("error on scsi_add_host\n");
1433 - goto out_lp_destroy;
1434 + FC_DBG("Could not configure netdev for lport\n");
1435 + goto out_host_put;
1438 - sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
1439 - FCOE_DRIVER_NAME, FCOE_VERSION,
1441 + /* configure lport scsi host properties */
1442 + rc = fcoe_sw_shost_config(lp, shost, &netdev->dev);
1444 + FC_DBG("Could not configure shost for lport\n");
1445 + goto out_host_put;
1448 - /* Configure netdev and networking properties of the lp */
1449 - rc = net_config(lp);
1451 - goto out_lp_destroy;
1452 + /* lport exch manager allocation */
1453 + rc = fcoe_sw_em_config(lp);
1455 + FC_DBG("Could not configure em for lport\n");
1456 + goto out_host_put;
1459 /* Initialize the library */
1460 - rc = libfc_config(lp);
1462 + rc = fcoe_libfc_config(lp, &fcoe_sw_libfc_fcn_templ);
1464 + FC_DBG("Could not configure libfc for lport!\n");
1465 goto out_lp_destroy;
1468 - write_lock_bh(&fcoe_hostlist_lock);
1469 - list_add_tail(&fc->list, &fcoe_hostlist);
1470 - write_unlock_bh(&fcoe_hostlist_lock);
1471 + /* add to lports list */
1472 + fcoe_hostlist_add(lp);
1474 lp->boot_time = jiffies;
1476 fc_fabric_login(lp);
1483 @@ -493,28 +436,55 @@ out_host_put:
1487 -void fcoe_clean_pending_queue(struct fc_lport *lp)
1489 + * fcoe_sw_match - the fcoe sw transport match function
1491 + * Returns : false always
1493 +static bool fcoe_sw_match(struct net_device *netdev)
1495 - struct fcoe_softc *fc = lp->drv_priv;
1496 - struct sk_buff *skb;
1498 - spin_lock_bh(&fc->fcoe_pending_queue.lock);
1499 - while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
1500 - spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1502 - spin_lock_bh(&fc->fcoe_pending_queue.lock);
1504 - spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1505 + /* FIXME - for sw transport, always return false */
1509 +/* the sw hba fcoe transport */
1510 +struct fcoe_transport fcoe_sw_transport = {
1512 + .create = fcoe_sw_create,
1513 + .destroy = fcoe_sw_destroy,
1514 + .match = fcoe_sw_match,
1520 + * fcoe_sw_init - registers fcoe_sw_transport
1522 + * Returns : 0 on success
1524 int __init fcoe_sw_init(void)
1526 - fcoe_transport_template =
1527 - fc_attach_transport(&fcoe_transport_function);
1528 - return fcoe_transport_template ? 0 : -1;
1529 + /* attach to scsi transport */
1530 + scsi_transport_fcoe_sw =
1531 + fc_attach_transport(&fcoe_sw_transport_function);
1532 + if (!scsi_transport_fcoe_sw) {
1533 + printk(KERN_ERR "fcoe_sw_init:fc_attach_transport() failed\n");
1536 + /* register sw transport */
1537 + fcoe_transport_register(&fcoe_sw_transport);
1541 -void __exit fcoe_sw_exit(void)
1543 + * fcoe_sw_exit - unregisters fcoe_sw_transport
1545 + * Returns : 0 on success
1547 +int __exit fcoe_sw_exit(void)
1549 - fc_release_transport(fcoe_transport_template);
1550 + /* dettach the transport */
1551 + fc_release_transport(scsi_transport_fcoe_sw);
1552 + fcoe_transport_unregister(&fcoe_sw_transport);
1555 diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
1556 index 45a7d6f..de29ccd 100644
1557 --- a/drivers/scsi/fcoe/libfcoe.c
1558 +++ b/drivers/scsi/fcoe/libfcoe.c
1560 * Maintained at www.Open-FCoE.org
1564 - * FCOE protocol file
1567 #include <linux/module.h>
1568 #include <linux/version.h>
1569 #include <linux/kernel.h>
1571 #include <linux/skbuff.h>
1572 #include <linux/netdevice.h>
1573 #include <linux/etherdevice.h>
1574 +#include <linux/ethtool.h>
1575 #include <linux/if_ether.h>
1576 +#include <linux/if_vlan.h>
1577 #include <linux/kthread.h>
1578 #include <linux/crc32.h>
1579 +#include <linux/cpu.h>
1580 +#include <linux/fs.h>
1581 +#include <linux/sysfs.h>
1582 +#include <linux/ctype.h>
1583 #include <scsi/scsi_tcq.h>
1584 #include <scsi/scsicam.h>
1585 #include <scsi/scsi_transport.h>
1588 #include <scsi/fc/fc_encaps.h>
1590 -#include <scsi/libfc/libfc.h>
1591 -#include <scsi/libfc/fc_frame.h>
1593 -#include <scsi/fc/fc_fcoe.h>
1594 -#include "fcoe_def.h"
1595 +#include <scsi/libfc.h>
1596 +#include <scsi/fc_frame.h>
1597 +#include <scsi/libfcoe.h>
1598 +#include <scsi/fc_transport_fcoe.h>
1600 static int debug_fcoe;
1602 @@ -53,18 +54,129 @@ static int debug_fcoe;
1603 #define FCOE_GW_ADDR_MODE 0x00
1604 #define FCOE_FCOUI_ADDR_MODE 0x01
1606 +#define FCOE_WORD_TO_BYTE 4
1608 +MODULE_AUTHOR("Open-FCoE.org");
1609 +MODULE_DESCRIPTION("FCoE");
1610 +MODULE_LICENSE("GPL");
1611 +MODULE_VERSION("1.0.4");
1613 +/* fcoe host list */
1614 +LIST_HEAD(fcoe_hostlist);
1615 +DEFINE_RWLOCK(fcoe_hostlist_lock);
1616 +DEFINE_TIMER(fcoe_timer, NULL, 0, 0);
1617 +struct fcoe_percpu_s *fcoe_percpu[NR_CPUS];
1620 /* Function Prototyes */
1621 static int fcoe_check_wait_queue(struct fc_lport *);
1622 static void fcoe_insert_wait_queue_head(struct fc_lport *, struct sk_buff *);
1623 static void fcoe_insert_wait_queue(struct fc_lport *, struct sk_buff *);
1624 static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *);
1625 +#ifdef CONFIG_HOTPLUG_CPU
1626 +static int fcoe_cpu_callback(struct notifier_block *, ulong, void *);
1627 +#endif /* CONFIG_HOTPLUG_CPU */
1628 +static int fcoe_device_notification(struct notifier_block *, ulong, void *);
1629 +static void fcoe_dev_setup(void);
1630 +static void fcoe_dev_cleanup(void);
1632 +/* notification function from net device */
1633 +static struct notifier_block fcoe_notifier = {
1634 + .notifier_call = fcoe_device_notification,
1638 +#ifdef CONFIG_HOTPLUG_CPU
1639 +static struct notifier_block fcoe_cpu_notifier = {
1640 + .notifier_call = fcoe_cpu_callback,
1644 + * fcoe_create_percpu_data - creates the associated cpu data
1645 + * @cpu: index for the cpu where fcoe cpu data will be created
1647 + * create percpu stats block, from cpu add notifier
1651 +static void fcoe_create_percpu_data(int cpu)
1653 + struct fc_lport *lp;
1654 + struct fcoe_softc *fc;
1657 - * this is the fcoe receive function
1658 - * called by NET_RX_SOFTIRQ
1659 - * this function will receive the packet and
1660 - * build fc frame and pass it up
1662 + write_lock_bh(&fcoe_hostlist_lock);
1663 + list_for_each_entry(fc, &fcoe_hostlist, list) {
1665 + if (lp->dev_stats[cpu] == NULL)
1666 + lp->dev_stats[cpu] =
1667 + kzalloc(sizeof(struct fcoe_dev_stats),
1670 + write_unlock_bh(&fcoe_hostlist_lock);
1674 + * fcoe_destroy_percpu_data - destroys the associated cpu data
1675 + * @cpu: index for the cpu where fcoe cpu data will destroyed
1677 + * destroy percpu stats block called by cpu add/remove notifier
1681 +static void fcoe_destroy_percpu_data(int cpu)
1683 + struct fc_lport *lp;
1684 + struct fcoe_softc *fc;
1686 + write_lock_bh(&fcoe_hostlist_lock);
1687 + list_for_each_entry(fc, &fcoe_hostlist, list) {
1689 + kfree(lp->dev_stats[cpu]);
1690 + lp->dev_stats[cpu] = NULL;
1692 + write_unlock_bh(&fcoe_hostlist_lock);
1696 + * fcoe_cpu_callback - fcoe cpu hotplug event callback
1697 + * @nfb: callback data block
1698 + * @action: event triggering the callback
1699 + * @hcpu: index for the cpu of this event
1701 + * this creates or destroys per cpu data for fcoe
1703 + * Returns NOTIFY_OK always.
1705 +static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
1708 + unsigned int cpu = (unsigned long)hcpu;
1712 + fcoe_create_percpu_data(cpu);
1715 + fcoe_destroy_percpu_data(cpu);
1722 +#endif /* CONFIG_HOTPLUG_CPU */
1725 + * foce_rcv - this is the fcoe receive function called by NET_RX_SOFTIRQ
1726 + * @skb: the receive skb
1727 + * @dev: associated net device
1729 + * @odldev: last device
1731 + * this function will receive the packet and build fc frame and pass it up
1733 + * Returns: 0 for success
1735 int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
1736 struct packet_type *ptype, struct net_device *olddev)
1738 @@ -142,7 +254,14 @@ err2:
1742 +EXPORT_SYMBOL_GPL(fcoe_rcv);
1745 + * fcoe_start_io - pass to netdev to start xmit for fcoe
1746 + * @skb: the skb to be xmitted
1748 + * Returns: 0 for success
1750 static inline int fcoe_start_io(struct sk_buff *skb)
1753 @@ -155,6 +274,13 @@ static inline int fcoe_start_io(struct sk_buff *skb)
1758 + * fcoe_get_paged_crc_eof - in case we need alloc a page for crc_eof
1759 + * @skb: the skb to be xmitted
1760 + * @tlen: total len
1762 + * Returns: 0 for success
1764 static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
1766 struct fcoe_percpu_s *fps;
1767 @@ -191,12 +317,53 @@ static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
1772 - * this is the frame xmit routine
1775 + * fcoe_fc_crc - calculates FC CRC in this fcoe skb
1776 + * @fp: the fc_frame containg data to be checksummed
1778 + * This uses crc32() to calculate the crc for fc frame
1779 + * Return : 32 bit crc
1782 +u32 fcoe_fc_crc(struct fc_frame *fp)
1784 + struct sk_buff *skb = fp_skb(fp);
1785 + struct skb_frag_struct *frag;
1786 + unsigned char *data;
1787 + unsigned long off, len, clen;
1791 + crc = crc32(~0, skb->data, skb_headlen(skb));
1793 + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1794 + frag = &skb_shinfo(skb)->frags[i];
1795 + off = frag->page_offset;
1798 + clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
1799 + data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
1800 + KM_SKB_DATA_SOFTIRQ);
1801 + crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
1802 + kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
1809 +EXPORT_SYMBOL_GPL(fcoe_fc_crc);
1812 + * fcoe_xmit - FCoE frame transmit function
1813 + * @lp: the associated local port
1814 + * @fp: the fc_frame to be transmitted
1816 + * Return : 0 for success
1819 int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
1825 @@ -206,15 +373,15 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
1826 struct fc_frame_header *fh;
1827 unsigned int hlen; /* header length implies the version */
1828 unsigned int tlen; /* trailer length */
1829 + unsigned int elen; /* eth header, may include vlan */
1830 int flogi_in_progress = 0;
1831 struct fcoe_softc *fc;
1834 struct fcoe_hdr *hp;
1836 WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
1838 - fc = (struct fcoe_softc *)lp->drv_priv;
1839 + fc = fcoe_softc(lp);
1841 * if it is a flogi then we need to learn gw-addr
1843 @@ -243,45 +410,24 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
1848 - crc = crc32(crc, skb->data, skb_headlen(skb));
1850 - for (indx = 0; indx < skb_shinfo(skb)->nr_frags; indx++) {
1851 - skb_frag_t *frag = &skb_shinfo(skb)->frags[indx];
1852 - unsigned long off = frag->page_offset;
1853 - unsigned long len = frag->size;
1856 - unsigned long clen;
1858 - clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
1859 - data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
1860 - KM_SKB_DATA_SOFTIRQ);
1861 - crc = crc32(crc, data + (off & ~PAGE_MASK),
1863 - kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
1870 - * Get header and trailer lengths.
1871 - * This is temporary code until we get rid of the old protocol.
1872 - * Both versions have essentially the same trailer layout but T11
1873 - * has padding afterwards.
1875 + elen = (fc->real_dev->priv_flags & IFF_802_1Q_VLAN) ?
1876 + sizeof(struct vlan_ethhdr) : sizeof(struct ethhdr);
1877 hlen = sizeof(struct fcoe_hdr);
1878 tlen = sizeof(struct fcoe_crc_eof);
1879 + wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
1882 - * copy fc crc and eof to the skb buff
1883 - * Use utility buffer in the fc_frame part of the sk_buff for the
1885 - * We don't do a get_page for this frag, since that page may not be
1886 - * managed that way. So that skb_free() doesn't do that either, we
1887 - * setup the destructor to remove this frag.
1890 + if (likely(lp->crc_offload)) {
1891 + skb->ip_summed = CHECKSUM_COMPLETE;
1892 + skb->csum_start = skb_headroom(skb);
1893 + skb->csum_offset = skb->len;
1896 + skb->ip_summed = CHECKSUM_NONE;
1897 + crc = fcoe_fc_crc(fp);
1900 + /* copy fc crc and eof to the skb buff */
1901 if (skb_is_nonlinear(skb)) {
1903 if (fcoe_get_paged_crc_eof(skb, tlen)) {
1904 @@ -295,22 +441,27 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
1905 cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
1908 + memset(cp, 0, sizeof(*cp));
1910 cp->fcoe_crc32 = cpu_to_le32(~crc);
1911 - if (tlen == sizeof(*cp))
1912 - memset(cp->fcoe_resvd, 0, sizeof(cp->fcoe_resvd));
1913 - wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
1915 if (skb_is_nonlinear(skb)) {
1916 kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
1921 - * Fill in the control structures
1923 - skb->ip_summed = CHECKSUM_NONE;
1924 - eh = (struct ethhdr *)skb_push(skb, hlen + sizeof(struct ethhdr));
1925 + /* adjust skb netowrk/transport offsets to match mac/fcoe/fc */
1926 + skb_push(skb, elen + hlen);
1927 + skb_reset_mac_header(skb);
1928 + skb_set_network_header(skb, elen);
1929 + skb_set_transport_header(skb, elen + hlen);
1930 + skb->mac_len = elen;
1931 + skb->protocol = htons(ETH_P_FCOE);
1932 + skb->dev = fc->real_dev;
1934 + /* fill up mac and fcoe headers */
1935 + eh = eth_hdr(skb);
1936 + eh->h_proto = htons(ETH_P_FCOE);
1937 if (fc->address_mode == FCOE_FCOUI_ADDR_MODE)
1938 fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
1940 @@ -322,24 +473,20 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
1942 memcpy(eh->h_source, fc->data_src_addr, ETH_ALEN);
1944 - eh->h_proto = htons(ETH_P_FCOE);
1945 - skb->protocol = htons(ETH_P_802_3);
1946 - skb_reset_mac_header(skb);
1947 - skb_reset_network_header(skb);
1949 - hp = (struct fcoe_hdr *)(eh + 1);
1950 + hp = (struct fcoe_hdr *)skb_network_header(skb);
1951 memset(hp, 0, sizeof(*hp));
1953 FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
1956 + /* update tx stats: regardless if LLD fails */
1957 stats = lp->dev_stats[smp_processor_id()];
1960 stats->TxWords += wlen;
1962 - skb->dev = fc->real_dev;
1964 + /* send down to lld */
1966 if (fc->fcoe_pending_queue.qlen)
1967 rc = fcoe_check_wait_queue(lp);
1968 @@ -355,7 +502,15 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
1972 +EXPORT_SYMBOL_GPL(fcoe_xmit);
1975 + * fcoe_percpu_receive_thread - recv thread per cpu
1976 + * @arg: ptr to the fcoe per cpu struct
1978 + * Return: 0 for success
1981 int fcoe_percpu_receive_thread(void *arg)
1983 struct fcoe_percpu_s *p = arg;
1984 @@ -368,7 +523,6 @@ int fcoe_percpu_receive_thread(void *arg)
1985 struct fc_frame_header *fh;
1986 struct sk_buff *skb;
1987 struct fcoe_crc_eof *cp;
1989 struct fc_frame *fp;
1991 struct fcoe_softc *fc;
1992 @@ -411,7 +565,7 @@ int fcoe_percpu_receive_thread(void *arg)
1994 * Save source MAC address before discarding header.
1996 - fc = lp->drv_priv;
1997 + fc = lport_priv(lp);
1998 if (unlikely(fc->flogi_progress))
1999 mac = eth_hdr(skb)->h_source;
2001 @@ -422,7 +576,6 @@ int fcoe_percpu_receive_thread(void *arg)
2002 * Check the header and pull it off.
2004 hlen = sizeof(struct fcoe_hdr);
2006 hp = (struct fcoe_hdr *)skb->data;
2007 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
2009 @@ -434,11 +587,10 @@ int fcoe_percpu_receive_thread(void *arg)
2013 - sof = hp->fcoe_sof;
2014 - skb_pull(skb, sizeof(*hp));
2015 - fr_len = skb->len - sizeof(struct fcoe_crc_eof);
2016 - skb_trim(skb, fr_len);
2017 + skb_pull(skb, sizeof(struct fcoe_hdr));
2018 tlen = sizeof(struct fcoe_crc_eof);
2019 + fr_len = skb->len - tlen;
2020 + skb_trim(skb, fr_len);
2022 if (unlikely(fr_len > skb->len)) {
2024 @@ -456,47 +608,61 @@ int fcoe_percpu_receive_thread(void *arg)
2025 stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
2028 - fp = (struct fc_frame *) skb;
2029 - fc_frame_init(fp);
2030 + fp = (struct fc_frame *)skb;
2031 cp = (struct fcoe_crc_eof *)(skb->data + fr_len);
2032 + fc_frame_init(fp);
2033 fr_eof(fp) = cp->fcoe_eof;
2035 + fr_sof(fp) = hp->fcoe_sof;
2039 - * Check the CRC here, unless it's solicited data for SCSI.
2040 - * In that case, the SCSI layer can check it during the copy,
2041 - * and it'll be more cache-efficient.
2042 + * We only check CRC if no offload is available and if it is
2043 + * it's solicited data, in which case, the FCP layer would
2044 + * check it during the copy.
2046 + if (lp->crc_offload)
2047 + fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
2049 + fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
2051 fh = fc_frame_header_get(fp);
2052 if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
2053 fh->fh_type == FC_TYPE_FCP) {
2054 - fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
2055 fc_exch_recv(lp, lp->emp, fp);
2056 - } else if (le32_to_cpu(cp->fcoe_crc32) ==
2057 - ~crc32(~0, skb->data, fr_len)) {
2058 - if (unlikely(fc->flogi_progress))
2059 - fcoe_recv_flogi(fc, fp, mac);
2060 - fc_exch_recv(lp, lp->emp, fp);
2063 - (stats && stats->InvalidCRCCount < 5)) {
2064 - printk(KERN_WARNING \
2065 - "fcoe: dropping frame with CRC error");
2070 + if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
2071 + if (le32_to_cpu(cp->fcoe_crc32) !=
2072 + ~crc32(~0, skb->data, fr_len)) {
2073 + if (debug_fcoe || stats->InvalidCRCCount < 5)
2074 + printk(KERN_WARNING "fcoe: dropping "
2075 + "frame with CRC error\n");
2076 stats->InvalidCRCCount++;
2077 stats->ErrorFrames++;
2078 + fc_frame_free(fp);
2081 - fc_frame_free(fp);
2082 + fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
2084 + /* non flogi and non data exchanges are handled here */
2085 + if (unlikely(fc->flogi_progress))
2086 + fcoe_recv_flogi(fc, fp, mac);
2087 + fc_exch_recv(lp, lp->emp, fp);
2093 - * Snoop potential response to FLOGI or even incoming FLOGI.
2096 + * fcoe_recv_flogi - flogi receive function
2097 + * @fc: associated fcoe_softc
2098 + * @fp: the recieved frame
2099 + * @sa: the source address of this flogi
2101 + * This is responsible to parse the flogi response and sets the corresponding
2102 + * mac address for the initiator, eitehr OUI based or GW based.
2106 static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa)
2108 struct fc_frame_header *fh;
2109 @@ -543,6 +709,16 @@ static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa)
2114 + * fcoe_watchdog - fcoe timer callback
2117 + * This checks the pending queue length for fcoe and put fcoe to be paused state
2118 + * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the
2121 + * Returns: 0 for success
2123 void fcoe_watchdog(ulong vp)
2125 struct fc_lport *lp;
2126 @@ -567,27 +743,23 @@ void fcoe_watchdog(ulong vp)
2127 add_timer(&fcoe_timer);
2131 - * the wait_queue is used when the skb transmit fails. skb will go
2132 - * in the wait_queue which will be emptied by the time function OR
2133 - * by the next skb transmit.
2138 - * Function name : fcoe_check_wait_queue()
2140 + * fcoe_check_wait_queue - put the skb into fcoe pending xmit queue
2141 + * @lp: the fc_port for this skb
2142 + * @skb: the associated skb to be xmitted
2144 - * Return Values : 0 or error
2145 + * This empties the wait_queue, dequeue the head of the wait_queue queue
2146 + * and calls fcoe_start_io() for each packet, if all skb have been
2147 + * transmitted, return 0 if a error occurs, then restore wait_queue and
2148 + * try again later.
2150 - * Description : empties the wait_queue
2151 - * dequeue the head of the wait_queue queue and
2152 - * calls fcoe_start_io() for each packet
2153 - * if all skb have been transmitted, return 0
2154 - * if a error occurs, then restore wait_queue and try again
2156 + * The wait_queue is used when the skb transmit fails. skb will go
2157 + * in the wait_queue which will be emptied by the time function OR
2158 + * by the next skb transmit.
2162 + * Returns: 0 for success
2164 static int fcoe_check_wait_queue(struct fc_lport *lp)
2166 int rc, unpause = 0;
2167 @@ -595,7 +767,7 @@ static int fcoe_check_wait_queue(struct fc_lport *lp)
2168 struct sk_buff *skb;
2169 struct fcoe_softc *fc;
2171 - fc = (struct fcoe_softc *)lp->drv_priv;
2172 + fc = fcoe_softc(lp);
2173 spin_lock_bh(&fc->fcoe_pending_queue.lock);
2176 @@ -622,24 +794,714 @@ static int fcoe_check_wait_queue(struct fc_lport *lp)
2177 return fc->fcoe_pending_queue.qlen;
2181 + * fcoe_insert_wait_queue_head - puts skb to fcoe pending queue head
2182 + * @lp: the fc_port for this skb
2183 + * @skb: the associated skb to be xmitted
2187 static void fcoe_insert_wait_queue_head(struct fc_lport *lp,
2188 struct sk_buff *skb)
2190 struct fcoe_softc *fc;
2192 - fc = (struct fcoe_softc *)lp->drv_priv;
2193 + fc = fcoe_softc(lp);
2194 spin_lock_bh(&fc->fcoe_pending_queue.lock);
2195 __skb_queue_head(&fc->fcoe_pending_queue, skb);
2196 spin_unlock_bh(&fc->fcoe_pending_queue.lock);
2200 + * fcoe_insert_wait_queue - put the skb into fcoe pending queue tail
2201 + * @lp: the fc_port for this skb
2202 + * @skb: the associated skb to be xmitted
2206 static void fcoe_insert_wait_queue(struct fc_lport *lp,
2207 struct sk_buff *skb)
2209 struct fcoe_softc *fc;
2211 - fc = (struct fcoe_softc *)lp->drv_priv;
2212 + fc = fcoe_softc(lp);
2213 spin_lock_bh(&fc->fcoe_pending_queue.lock);
2214 __skb_queue_tail(&fc->fcoe_pending_queue, skb);
2215 spin_unlock_bh(&fc->fcoe_pending_queue.lock);
2219 + * fcoe_dev_setup - setup link change notification interface
2222 +static void fcoe_dev_setup(void)
2225 + * here setup a interface specific wd time to
2226 + * monitor the link state
2228 + register_netdevice_notifier(&fcoe_notifier);
2232 + * fcoe_dev_setup - cleanup link change notification interface
2234 +static void fcoe_dev_cleanup(void)
2236 + unregister_netdevice_notifier(&fcoe_notifier);
2240 + * fcoe_device_notification - netdev event notification callback
2241 + * @notifier: context of the notification
2242 + * @event: type of event
2243 + * @ptr: fixed array for output parsed ifname
2245 + * This function is called by the ethernet driver in case of link change event
2247 + * Returns: 0 for success
2249 +static int fcoe_device_notification(struct notifier_block *notifier,
2250 + ulong event, void *ptr)
2252 + struct fc_lport *lp = NULL;
2253 + struct net_device *real_dev = ptr;
2254 + struct fcoe_softc *fc;
2255 + struct fcoe_dev_stats *stats;
2258 + int rc = NOTIFY_OK;
2260 + read_lock(&fcoe_hostlist_lock);
2261 + list_for_each_entry(fc, &fcoe_hostlist, list) {
2262 + if (fc->real_dev == real_dev) {
2267 + read_unlock(&fcoe_hostlist_lock);
2273 + new_status = lp->link_status;
2276 + case NETDEV_GOING_DOWN:
2277 + new_status &= ~FC_LINK_UP;
2280 + case NETDEV_CHANGE:
2281 + new_status &= ~FC_LINK_UP;
2282 + if (!fcoe_link_ok(lp))
2283 + new_status |= FC_LINK_UP;
2285 + case NETDEV_CHANGEMTU:
2286 + mfs = fc->real_dev->mtu -
2287 + (sizeof(struct fcoe_hdr) +
2288 + sizeof(struct fcoe_crc_eof));
2289 + if (fc->user_mfs && fc->user_mfs < mfs)
2290 + mfs = fc->user_mfs;
2291 + if (mfs >= FC_MIN_MAX_FRAME)
2292 + fc_set_mfs(lp, mfs);
2293 + new_status &= ~FC_LINK_UP;
2294 + if (!fcoe_link_ok(lp))
2295 + new_status |= FC_LINK_UP;
2297 + case NETDEV_REGISTER:
2300 + FC_DBG("unknown event %ld call", event);
2302 + if (lp->link_status != new_status) {
2303 + if ((new_status & FC_LINK_UP) == FC_LINK_UP)
2306 + stats = lp->dev_stats[smp_processor_id()];
2308 + stats->LinkFailureCount++;
2310 + fcoe_clean_pending_queue(lp);
2318 + * fcoe_if_to_netdev - parse a name buffer to get netdev
2319 + * @ifname: fixed array for output parsed ifname
2320 + * @buffer: incoming buffer to be copied
2322 + * Returns: NULL or ptr to netdeive
2324 +static struct net_device *fcoe_if_to_netdev(const char *buffer)
2327 + char ifname[IFNAMSIZ + 2];
2330 + strlcpy(ifname, buffer, IFNAMSIZ);
2331 + cp = ifname + strlen(ifname);
2332 + while (--cp >= ifname && *cp == '\n')
2334 + return dev_get_by_name(&init_net, ifname);
2340 + * fcoe_netdev_to_module_owner - finds out the nic drive moddule of the netdev
2341 + * @netdev: the target netdev
2343 + * Returns: ptr to the struct module, NULL for failure
2345 +static struct module *fcoe_netdev_to_module_owner(
2346 + const struct net_device *netdev)
2348 + struct device *dev;
2353 + dev = netdev->dev.parent;
2360 + return dev->driver->owner;
2364 + * fcoe_ethdrv_get - holds the nic driver module by try_module_get() for
2365 + * the corresponding netdev.
2366 + * @netdev: the target netdev
2368 + * Returns: 0 for succsss
2370 +static int fcoe_ethdrv_get(const struct net_device *netdev)
2372 + struct module *owner;
2374 + owner = fcoe_netdev_to_module_owner(netdev);
2376 + printk(KERN_DEBUG "foce:hold driver module %s for %s\n",
2377 + owner->name, netdev->name);
2378 + return try_module_get(owner);
2384 + * fcoe_ethdrv_get - releases the nic driver module by module_put for
2385 + * the corresponding netdev.
2386 + * @netdev: the target netdev
2388 + * Returns: 0 for succsss
2390 +static int fcoe_ethdrv_put(const struct net_device *netdev)
2392 + struct module *owner;
2394 + owner = fcoe_netdev_to_module_owner(netdev);
2396 + printk(KERN_DEBUG "foce:release driver module %s for %s\n",
2397 + owner->name, netdev->name);
2398 + module_put(owner);
2405 + * fcoe_destroy- handles the destroy from sysfs
2406 + * @buffer: expcted to be a eth if name
2407 + * @kp: associated kernel param
2409 + * Returns: 0 for success
2411 +static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
2414 + struct net_device *netdev;
2416 + netdev = fcoe_if_to_netdev(buffer);
2421 + /* look for existing lport */
2422 + if (!fcoe_hostlist_lookup(netdev)) {
2426 + /* pass to transport */
2427 + rc = fcoe_transport_release(netdev);
2429 + printk(KERN_ERR "fcoe: fcoe_transport_release(%s) failed\n",
2434 + fcoe_ethdrv_put(netdev);
2443 + * fcoe_create - handles the create call from sysfs
2444 + * @buffer: expcted to be a eth if name
2445 + * @kp: associated kernel param
2447 + * Returns: 0 for success
2449 +static int fcoe_create(const char *buffer, struct kernel_param *kp)
2452 + struct net_device *netdev;
2454 + netdev = fcoe_if_to_netdev(buffer);
2459 + /* look for existing lport */
2460 + if (fcoe_hostlist_lookup(netdev)) {
2464 + fcoe_ethdrv_get(netdev);
2466 + /* pass to transport */
2467 + rc = fcoe_transport_attach(netdev);
2469 + printk(KERN_ERR "fcoe: fcoe_transport_attach(%s) failed\n",
2471 + fcoe_ethdrv_put(netdev);
2482 +module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
2483 +__MODULE_PARM_TYPE(create, "string");
2484 +MODULE_PARM_DESC(create, "Create fcoe port using net device passed in.");
2485 +module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
2486 +__MODULE_PARM_TYPE(destroy, "string");
2487 +MODULE_PARM_DESC(destroy, "Destroy fcoe port");
2490 + * fcoe_link_ok - check if link is ok for the fc_lport
2491 + * @lp: ptr to the fc_lport
2493 + * Any permanently-disqualifying conditions have been previously checked.
2494 + * This also updates the speed setting, which may change with link for 100/1000.
2496 + * This function should probably be checking for PAUSE support at some point
2497 + * in the future. Currently Per-priority-pause is not determinable using
2498 + * ethtool, so we shouldn't be restrictive until that problem is resolved.
2500 + * Returns: 0 if link is OK for use by FCoE.
2503 +int fcoe_link_ok(struct fc_lport *lp)
2505 + struct fcoe_softc *fc = fcoe_softc(lp);
2506 + struct net_device *dev = fc->real_dev;
2507 + struct ethtool_cmd ecmd = { ETHTOOL_GSET };
2510 + if ((dev->flags & IFF_UP) && netif_carrier_ok(dev)) {
2511 + dev = fc->phys_dev;
2512 + if (dev->ethtool_ops->get_settings) {
2513 + dev->ethtool_ops->get_settings(dev, &ecmd);
2514 + lp->link_supported_speeds &=
2515 + ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
2516 + if (ecmd.supported & (SUPPORTED_1000baseT_Half |
2517 + SUPPORTED_1000baseT_Full))
2518 + lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
2519 + if (ecmd.supported & SUPPORTED_10000baseT_Full)
2520 + lp->link_supported_speeds |=
2521 + FC_PORTSPEED_10GBIT;
2522 + if (ecmd.speed == SPEED_1000)
2523 + lp->link_speed = FC_PORTSPEED_1GBIT;
2524 + if (ecmd.speed == SPEED_10000)
2525 + lp->link_speed = FC_PORTSPEED_10GBIT;
2532 +EXPORT_SYMBOL_GPL(fcoe_link_ok);
2535 + * fcoe_percpu_clean - frees skb of the corresponding lport from the per
2537 + * @lp: the fc_lport
2539 +void fcoe_percpu_clean(struct fc_lport *lp)
2542 + struct fcoe_percpu_s *pp;
2543 + struct fcoe_rcv_info *fr;
2544 + struct sk_buff_head *list;
2545 + struct sk_buff *skb, *next;
2546 + struct sk_buff *head;
2548 + for (idx = 0; idx < NR_CPUS; idx++) {
2549 + if (fcoe_percpu[idx]) {
2550 + pp = fcoe_percpu[idx];
2551 + spin_lock_bh(&pp->fcoe_rx_list.lock);
2552 + list = &pp->fcoe_rx_list;
2553 + head = list->next;
2554 + for (skb = head; skb != (struct sk_buff *)list;
2557 + fr = fcoe_dev_from_skb(skb);
2558 + if (fr->fr_dev == lp) {
2559 + __skb_unlink(skb, list);
2563 + spin_unlock_bh(&pp->fcoe_rx_list.lock);
2567 +EXPORT_SYMBOL_GPL(fcoe_percpu_clean);
2570 + * fcoe_clean_pending_queue - dequeue skb and free it
2571 + * @lp: the corresponding fc_lport
2575 +void fcoe_clean_pending_queue(struct fc_lport *lp)
2577 + struct fcoe_softc *fc = lport_priv(lp);
2578 + struct sk_buff *skb;
2580 + spin_lock_bh(&fc->fcoe_pending_queue.lock);
2581 + while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
2582 + spin_unlock_bh(&fc->fcoe_pending_queue.lock);
2584 + spin_lock_bh(&fc->fcoe_pending_queue.lock);
2586 + spin_unlock_bh(&fc->fcoe_pending_queue.lock);
2588 +EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue);
2591 + * libfc_host_alloc - allocate a Scsi_Host with room for the fc_lport
2592 + * @sht: ptr to the scsi host templ
2593 + * @priv_size: size of private data after fc_lport
2595 + * Returns: ptr to Scsi_Host
2596 + * TODO - to libfc?
2598 +static inline struct Scsi_Host *libfc_host_alloc(
2599 + struct scsi_host_template *sht, int priv_size)
2601 + return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size);
2605 + * fcoe_host_alloc - allocate a Scsi_Host with room for the fcoe_softc
2606 + * @sht: ptr to the scsi host templ
2607 + * @priv_size: size of private data after fc_lport
2609 + * Returns: ptr to Scsi_Host
2611 +struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *sht, int priv_size)
2613 + return libfc_host_alloc(sht, sizeof(struct fcoe_softc) + priv_size);
2615 +EXPORT_SYMBOL_GPL(fcoe_host_alloc);
2618 + * fcoe_reset - resets the fcoe
2619 + * @shost: shost the reset is from
2621 + * Returns: always 0
2623 +int fcoe_reset(struct Scsi_Host *shost)
2625 + struct fc_lport *lport = shost_priv(shost);
2626 + fc_lport_reset(lport);
2629 +EXPORT_SYMBOL_GPL(fcoe_reset);
2632 + * fcoe_wwn_from_mac - converts 48-bit IEEE MAC address to 64-bit FC WWN.
2633 + * @mac: mac address
2634 + * @scheme: check port
2635 + * @port: port indicator for converting
2637 + * Returns: u64 fc world wide name
2639 +u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
2640 + unsigned int scheme, unsigned int port)
2645 + /* The MAC is in NO, so flip only the low 48 bits */
2646 + host_mac = ((u64) mac[0] << 40) |
2647 + ((u64) mac[1] << 32) |
2648 + ((u64) mac[2] << 24) |
2649 + ((u64) mac[3] << 16) |
2650 + ((u64) mac[4] << 8) |
2653 + WARN_ON(host_mac >= (1ULL << 48));
2654 + wwn = host_mac | ((u64) scheme << 60);
2657 + WARN_ON(port != 0);
2660 + WARN_ON(port >= 0xfff);
2661 + wwn |= (u64) port << 48;
2670 +EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
2672 + * fcoe_hostlist_lookup_softc - find the corresponding lport by a given device
2673 + * @device: this is currently ptr to net_device
2675 + * Returns: NULL or the located fcoe_softc
2677 +static struct fcoe_softc *fcoe_hostlist_lookup_softc(
2678 + const struct net_device *dev)
2680 + struct fcoe_softc *fc;
2682 + read_lock(&fcoe_hostlist_lock);
2683 + list_for_each_entry(fc, &fcoe_hostlist, list) {
2684 + if (fc->real_dev == dev) {
2685 + read_unlock(&fcoe_hostlist_lock);
2689 + read_unlock(&fcoe_hostlist_lock);
2694 + * fcoe_hostlist_lookup - find the corresponding lport by netdev
2695 + * @netdev: ptr to net_device
2697 + * Returns: 0 for success
2699 +struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
2701 + struct fcoe_softc *fc;
2703 + fc = fcoe_hostlist_lookup_softc(netdev);
2705 + return (fc) ? fc->lp : NULL;
2707 +EXPORT_SYMBOL_GPL(fcoe_hostlist_lookup);
2710 + * fcoe_hostlist_add - add a lport to lports list
2711 + * @lp: ptr to the fc_lport to badded
2713 + * Returns: 0 for success
2715 +int fcoe_hostlist_add(const struct fc_lport *lp)
2717 + struct fcoe_softc *fc;
2719 + fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
2721 + fc = fcoe_softc(lp);
2722 + write_lock_bh(&fcoe_hostlist_lock);
2723 + list_add_tail(&fc->list, &fcoe_hostlist);
2724 + write_unlock_bh(&fcoe_hostlist_lock);
2728 +EXPORT_SYMBOL_GPL(fcoe_hostlist_add);
2731 + * fcoe_hostlist_remove - remove a lport from lports list
2732 + * @lp: ptr to the fc_lport to badded
2734 + * Returns: 0 for success
2736 +int fcoe_hostlist_remove(const struct fc_lport *lp)
2738 + struct fcoe_softc *fc;
2740 + fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
2742 + write_lock_bh(&fcoe_hostlist_lock);
2743 + list_del(&fc->list);
2744 + write_unlock_bh(&fcoe_hostlist_lock);
2748 +EXPORT_SYMBOL_GPL(fcoe_hostlist_remove);
2751 + * fcoe_libfc_config - sets up libfc related properties for lport
2752 + * @lp: ptr to the fc_lport
2753 + * @tt: libfc function template
2755 + * Returns : 0 for success
2757 +int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt)
2759 + /* Set the function pointers set by the LLDD */
2760 + memcpy(&lp->tt, tt, sizeof(*tt));
2761 + if (fc_fcp_init(lp))
2764 + fc_elsct_init(lp);
2765 + fc_lport_init(lp);
2766 + fc_rport_init(lp);
2771 +EXPORT_SYMBOL_GPL(fcoe_libfc_config);
2774 + * fcoe_init - fcoe module loading initialization
2776 + * Initialization routine
2777 + * 1. Will create fc transport software structure
2778 + * 2. initialize the link list of port information structure
2780 + * Returns 0 on success, negative on failure
2782 +static int __init fcoe_init(void)
2785 + struct fcoe_percpu_s *p;
2788 + INIT_LIST_HEAD(&fcoe_hostlist);
2789 + rwlock_init(&fcoe_hostlist_lock);
2791 +#ifdef CONFIG_HOTPLUG_CPU
2792 + register_cpu_notifier(&fcoe_cpu_notifier);
2793 +#endif /* CONFIG_HOTPLUG_CPU */
2796 + * initialize per CPU interrupt thread
2798 + for_each_online_cpu(cpu) {
2799 + p = kzalloc(sizeof(struct fcoe_percpu_s), GFP_KERNEL);
2801 + p->thread = kthread_create(fcoe_percpu_receive_thread,
2803 + "fcoethread/%d", cpu);
2806 + * if there is no error then bind the thread to the cpu
2807 + * initialize the semaphore and skb queue head
2809 + if (likely(!IS_ERR(p->thread))) {
2811 + fcoe_percpu[cpu] = p;
2812 + skb_queue_head_init(&p->fcoe_rx_list);
2813 + kthread_bind(p->thread, cpu);
2814 + wake_up_process(p->thread);
2816 + fcoe_percpu[cpu] = NULL;
2824 + * setup link change notification
2828 + init_timer(&fcoe_timer);
2829 + fcoe_timer.data = 0;
2830 + fcoe_timer.function = fcoe_watchdog;
2831 + fcoe_timer.expires = (jiffies + (10 * HZ));
2832 + add_timer(&fcoe_timer);
2834 + /* initiatlize the fcoe transport */
2835 + fcoe_transport_init();
2841 +module_init(fcoe_init);
2844 + * fcoe_exit - fcoe module unloading cleanup
2846 + * Returns 0 on success, negative on failure
2848 +static void __exit fcoe_exit(void)
2851 + struct fcoe_softc *fc, *tmp;
2852 + struct fcoe_percpu_s *p;
2853 + struct sk_buff *skb;
2856 + * Stop all call back interfaces
2858 +#ifdef CONFIG_HOTPLUG_CPU
2859 + unregister_cpu_notifier(&fcoe_cpu_notifier);
2860 +#endif /* CONFIG_HOTPLUG_CPU */
2861 + fcoe_dev_cleanup();
2866 + del_timer_sync(&fcoe_timer);
2868 + /* releases the assocaited fcoe transport for each lport */
2869 + list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
2870 + fcoe_transport_release(fc->real_dev);
2872 + for (idx = 0; idx < NR_CPUS; idx++) {
2873 + if (fcoe_percpu[idx]) {
2874 + kthread_stop(fcoe_percpu[idx]->thread);
2875 + p = fcoe_percpu[idx];
2876 + spin_lock_bh(&p->fcoe_rx_list.lock);
2877 + while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
2879 + spin_unlock_bh(&p->fcoe_rx_list.lock);
2880 + if (fcoe_percpu[idx]->crc_eof_page)
2881 + put_page(fcoe_percpu[idx]->crc_eof_page);
2882 + kfree(fcoe_percpu[idx]);
2886 + /* remove sw trasnport */
2889 + /* detach the transport */
2890 + fcoe_transport_exit();
2892 +module_exit(fcoe_exit);
2893 diff --git a/drivers/scsi/libfc/Makefile b/drivers/scsi/libfc/Makefile
2894 index e6d4086..55f982d 100644
2895 --- a/drivers/scsi/libfc/Makefile
2896 +++ b/drivers/scsi/libfc/Makefile
2897 @@ -5,6 +5,7 @@ obj-$(CONFIG_LIBFC) += libfc.o
2905 diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
2906 index d50f1a5..aee2f9c 100644
2907 --- a/drivers/scsi/libfc/fc_disc.c
2908 +++ b/drivers/scsi/libfc/fc_disc.c
2911 #include <scsi/fc/fc_gs.h>
2913 -#include <scsi/libfc/libfc.h>
2914 +#include <scsi/libfc.h>
2916 #define FC_DISC_RETRY_LIMIT 3 /* max retries */
2917 #define FC_DISC_RETRY_DELAY 500UL /* (msecs) delay */
2919 +#define FC_DISC_DELAY 3
2921 static int fc_disc_debug;
2923 #define FC_DEBUG_DISC(fmt...) \
2924 @@ -43,26 +45,182 @@ static int fc_disc_debug;
2928 -static void fc_disc_gpn_ft_req(struct fc_lport *);
2929 +static struct mutex disc_list_lock;
2930 +static struct list_head disc_list;
2933 + unsigned char retry_count;
2934 + unsigned char delay;
2935 + unsigned char pending;
2936 + unsigned char requested;
2937 + unsigned short seq_count;
2938 + unsigned char buf_len;
2939 + enum fc_disc_event event;
2941 + void (*disc_callback)(struct fc_lport *,
2942 + enum fc_disc_event);
2944 + struct list_head rports;
2945 + struct fc_lport *lport;
2946 + struct mutex disc_mutex;
2947 + struct fc_gpn_ft_resp partial_buf; /* partial name buffer */
2948 + struct delayed_work disc_work;
2950 + struct list_head list;
2953 +static void fc_disc_gpn_ft_req(struct fc_disc *);
2954 static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *);
2955 -static int fc_disc_new_target(struct fc_lport *, struct fc_rport *,
2956 +static int fc_disc_new_target(struct fc_disc *, struct fc_rport *,
2957 struct fc_rport_identifiers *);
2958 -static void fc_disc_del_target(struct fc_lport *, struct fc_rport *);
2959 -static void fc_disc_done(struct fc_lport *);
2960 -static void fc_disc_error(struct fc_lport *, struct fc_frame *);
2961 +static void fc_disc_del_target(struct fc_disc *, struct fc_rport *);
2962 +static void fc_disc_done(struct fc_disc *);
2963 static void fc_disc_timeout(struct work_struct *);
2964 -static void fc_disc_single(struct fc_lport *, struct fc_disc_port *);
2965 -static int fc_disc_restart(struct fc_lport *);
2966 +static void fc_disc_single(struct fc_disc *, struct fc_disc_port *);
2967 +static void fc_disc_restart(struct fc_disc *);
2970 + * fc_disc_lookup_rport - lookup a remote port by port_id
2971 + * @lport: Fibre Channel host port instance
2972 + * @port_id: remote port port_id to match
2974 +struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport,
2977 + struct fc_disc *disc;
2978 + struct fc_rport *rport, *found = NULL;
2979 + struct fc_rport_libfc_priv *rdata;
2980 + int disc_found = 0;
2982 + mutex_lock(&disc_list_lock);
2983 + list_for_each_entry(disc, &disc_list, list) {
2984 + if (disc->lport == lport) {
2985 + list_for_each_entry(rdata, &disc->rports, peers) {
2986 + rport = PRIV_TO_RPORT(rdata);
2987 + if (rport->port_id == port_id) {
2990 + get_device(&found->dev);
2996 + mutex_unlock(&disc_list_lock);
2998 + if (!disc_found) {
2999 + FC_DEBUG_DISC("The rport (%6x) for lport (%6x) "
3000 + "is not maintained by the discovery layer\n",
3001 + port_id, fc_host_port_id(lport->host));
3009 + * fc_disc_alloc - Allocate a discovery work object
3010 + * @lport: The FC lport associated with the discovery job
3012 +static inline struct fc_disc *fc_disc_alloc(struct fc_lport *lport)
3014 + struct fc_disc *disc;
3016 + disc = kzalloc(sizeof(struct fc_disc), GFP_KERNEL);
3017 + INIT_LIST_HEAD(&disc->list);
3018 + INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout);
3019 + mutex_init(&disc->disc_mutex);
3020 + INIT_LIST_HEAD(&disc->rports);
3022 + disc->lport = lport;
3023 + disc->delay = FC_DISC_DELAY;
3024 + disc->event = DISC_EV_NONE;
3026 + mutex_lock(&disc_list_lock);
3027 + list_add_tail(&disc->list, &disc_list);
3028 + mutex_unlock(&disc_list_lock);
3034 + * fc_disc_stop_rports - delete all the remote ports associated with the lport
3035 + * @disc: The discovery job to stop rports on
3037 + * Locking Note: This function expects that the lport mutex is locked before
3040 +void fc_disc_stop_rports(struct fc_disc *disc)
3042 + struct fc_lport *lport;
3043 + struct fc_rport *rport;
3044 + struct fc_rport_libfc_priv *rdata, *next;
3046 + lport = disc->lport;
3048 + mutex_lock(&disc->disc_mutex);
3049 + list_for_each_entry_safe(rdata, next, &disc->rports, peers) {
3050 + rport = PRIV_TO_RPORT(rdata);
3051 + list_del(&rdata->peers);
3052 + lport->tt.rport_logoff(rport);
3055 + mutex_unlock(&disc->disc_mutex);
3059 + * fc_disc_rport_event - Event handler for rport events
3060 + * @lport: The lport which is receiving the event
3061 + * @rport: The rport which the event has occured on
3062 + * @event: The event that occured
3064 + * Locking Note: The rport lock should not be held when calling
3067 +static void fc_disc_rport_event(struct fc_lport *lport,
3068 + struct fc_rport *rport,
3069 + enum fc_lport_event event)
3071 + struct fc_rport_libfc_priv *rdata = rport->dd_data;
3072 + struct fc_disc *disc;
3075 + FC_DEBUG_DISC("Received a %d event for port (%6x)\n", event,
3078 + if (event == RPORT_EV_CREATED) {
3079 + mutex_lock(&disc_list_lock);
3080 + list_for_each_entry(disc, &disc_list, list) {
3081 + if (disc->lport == lport) {
3083 + mutex_lock(&disc->disc_mutex);
3084 + list_add_tail(&rdata->peers, &disc->rports);
3085 + mutex_unlock(&disc->disc_mutex);
3088 + mutex_unlock(&disc_list_lock);
3092 + FC_DEBUG_DISC("The rport (%6x) is not maintained "
3093 + "by the discovery layer\n", rport->port_id);
3097 * fc_disc_recv_rscn_req - Handle Registered State Change Notification (RSCN)
3098 * @sp: Current sequence of the RSCN exchange
3100 * @lport: Fibre Channel host port instance
3102 + * Locking Note: This function expects that the disc_mutex is locked
3103 + * before it is called.
3105 static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
3106 - struct fc_lport *lport)
3107 + struct fc_disc *disc)
3109 + struct fc_lport *lport;
3110 + struct fc_rport *rport;
3111 + struct fc_rport_libfc_priv *rdata;
3112 struct fc_els_rscn *rp;
3113 struct fc_els_rscn_page *pp;
3114 struct fc_seq_els_data rjt_data;
3115 @@ -70,9 +228,14 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
3117 enum fc_els_rscn_ev_qual ev_qual;
3118 enum fc_els_rscn_addr_fmt fmt;
3119 - LIST_HEAD(disc_list);
3120 + LIST_HEAD(disc_ports);
3121 struct fc_disc_port *dp, *next;
3123 + lport = disc->lport;
3125 + FC_DEBUG_DISC("Received an RSCN event on port (%6x)\n",
3126 + fc_host_port_id(lport->host));
3128 rp = fc_frame_payload_get(fp, sizeof(*rp));
3130 if (!rp || rp->rscn_page_len != sizeof(*pp))
3131 @@ -106,7 +269,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
3132 dp->ids.port_name = -1;
3133 dp->ids.node_name = -1;
3134 dp->ids.roles = FC_RPORT_ROLE_UNKNOWN;
3135 - list_add_tail(&dp->peers, &disc_list);
3136 + list_add_tail(&dp->peers, &disc_ports);
3138 case ELS_ADDR_FMT_AREA:
3139 case ELS_ADDR_FMT_DOM:
3140 @@ -120,18 +283,20 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
3141 lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
3143 FC_DEBUG_DISC("RSCN received: rediscovering\n");
3144 - list_for_each_entry_safe(dp, next, &disc_list, peers) {
3145 - list_del(&dp->peers);
3148 - fc_disc_restart(lport);
3149 + fc_disc_restart(disc);
3151 FC_DEBUG_DISC("RSCN received: not rediscovering. "
3152 "redisc %d state %d in_prog %d\n",
3153 - redisc, lport->state, lport->disc_pending);
3154 - list_for_each_entry_safe(dp, next, &disc_list, peers) {
3155 + redisc, lport->state, disc->pending);
3156 + list_for_each_entry_safe(dp, next, &disc_ports, peers) {
3157 list_del(&dp->peers);
3158 - fc_disc_single(lport, dp);
3159 + rport = lport->tt.rport_lookup(lport, dp->ids.port_id);
3161 + rdata = RPORT_TO_PRIV(rport);
3162 + list_del(&rdata->peers);
3163 + lport->tt.rport_logoff(rport);
3165 + fc_disc_single(disc, dp);
3169 @@ -149,16 +314,39 @@ reject:
3170 * @sp: Current sequence of the request exchange
3172 * @lport: The FC local port
3174 + * Locking Note: This function is called from the EM and will lock
3175 + * the disc_mutex before calling the handler for the
3178 static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp,
3179 struct fc_lport *lport)
3182 + struct fc_disc *disc;
3185 + mutex_lock(&disc_list_lock);
3186 + list_for_each_entry(disc, &disc_list, list) {
3187 + if (disc->lport == lport) {
3192 + mutex_unlock(&disc_list_lock);
3195 + FC_DBG("Received a request for an lport not managed "
3196 + "by the discovery engine\n");
3200 op = fc_frame_payload_op(fp);
3203 - fc_disc_recv_rscn_req(sp, fp, lport);
3204 + mutex_lock(&disc->disc_mutex);
3205 + fc_disc_recv_rscn_req(sp, fp, disc);
3206 + mutex_unlock(&disc->disc_mutex);
3209 FC_DBG("Received an unsupported request. opcode (%x)\n", op);
3210 @@ -168,16 +356,30 @@ static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp,
3213 * fc_disc_restart - Restart discovery
3214 - * @lport: FC local port
3215 + * @lport: FC discovery context
3217 + * Locking Note: This function expects that the disc mutex
3218 + * is already locked.
3220 -static int fc_disc_restart(struct fc_lport *lport)
3221 +static void fc_disc_restart(struct fc_disc *disc)
3223 - if (!lport->disc_requested && !lport->disc_pending) {
3224 - schedule_delayed_work(&lport->disc_work,
3225 - msecs_to_jiffies(lport->disc_delay * 1000));
3226 + struct fc_rport *rport;
3227 + struct fc_rport_libfc_priv *rdata, *next;
3228 + struct fc_lport *lport = disc->lport;
3230 + FC_DEBUG_DISC("Restarting discovery for port (%6x)\n",
3231 + fc_host_port_id(lport->host));
3233 + list_for_each_entry_safe(rdata, next, &disc->rports, peers) {
3234 + rport = PRIV_TO_RPORT(rdata);
3235 + FC_DEBUG_DISC("list_del(%6x)\n", rport->port_id);
3236 + list_del(&rdata->peers);
3237 + lport->tt.rport_logoff(rport);
3239 - lport->disc_requested = 1;
3242 + disc->requested = 1;
3243 + if (!disc->pending)
3244 + fc_disc_gpn_ft_req(disc);
3248 @@ -186,29 +388,58 @@ static int fc_disc_restart(struct fc_lport *lport)
3250 * Returns non-zero if discovery cannot be started.
3252 -static int fc_disc_start(struct fc_lport *lport)
3253 +static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
3254 + enum fc_disc_event),
3255 + struct fc_lport *lport)
3257 struct fc_rport *rport;
3259 struct fc_rport_identifiers ids;
3260 + struct fc_disc *disc;
3263 + mutex_lock(&disc_list_lock);
3264 + list_for_each_entry(disc, &disc_list, list) {
3265 + if (disc->lport == lport) {
3270 + mutex_unlock(&disc_list_lock);
3273 + FC_DEBUG_DISC("No existing discovery job, "
3274 + "creating one for lport (%6x)\n",
3275 + fc_host_port_id(lport->host));
3276 + disc = fc_disc_alloc(lport);
3278 + FC_DEBUG_DISC("Found an existing discovery job "
3279 + "for lport (%6x)\n",
3280 + fc_host_port_id(lport->host));
3283 + * At this point we may have a new disc job or an existing
3284 + * one. Either way, let's lock when we make changes to it
3285 + * and send the GPN_FT request.
3287 + mutex_lock(&disc->disc_mutex);
3289 + disc->disc_callback = disc_callback;
3292 * If not ready, or already running discovery, just set request flag.
3294 - if (!fc_lport_test_ready(lport) || lport->disc_pending) {
3295 - lport->disc_requested = 1;
3296 + disc->requested = 1;
3299 + if (disc->pending) {
3300 + mutex_unlock(&disc->disc_mutex);
3303 - lport->disc_pending = 1;
3304 - lport->disc_requested = 0;
3305 - lport->disc_retry_count = 0;
3308 * Handle point-to-point mode as a simple discovery
3309 - * of the remote port.
3310 + * of the remote port. Yucky, yucky, yuck, yuck!
3312 - rport = lport->ptp_rp;
3313 + rport = disc->lport->ptp_rp;
3315 ids.port_id = rport->port_id;
3316 ids.port_name = rport->port_name;
3317 @@ -216,32 +447,16 @@ static int fc_disc_start(struct fc_lport *lport)
3318 ids.roles = FC_RPORT_ROLE_UNKNOWN;
3319 get_device(&rport->dev);
3321 - error = fc_disc_new_target(lport, rport, &ids);
3322 + if (!fc_disc_new_target(disc, rport, &ids)) {
3323 + disc->event = DISC_EV_SUCCESS;
3324 + fc_disc_done(disc);
3326 put_device(&rport->dev);
3328 - fc_disc_done(lport);
3330 - fc_disc_gpn_ft_req(lport); /* get ports by FC-4 type */
3332 + fc_disc_gpn_ft_req(disc); /* get ports by FC-4 type */
3338 - * fc_disc_retry - Retry discovery
3339 - * @lport: FC local port
3341 -static void fc_disc_retry(struct fc_lport *lport)
3343 - unsigned long delay = FC_DISC_RETRY_DELAY;
3345 - if (!lport->disc_retry_count)
3346 - delay /= 4; /* timeout faster first time */
3347 - if (lport->disc_retry_count++ < FC_DISC_RETRY_LIMIT)
3348 - schedule_delayed_work(&lport->disc_work,
3349 - msecs_to_jiffies(delay));
3351 - fc_disc_done(lport);
3352 + mutex_unlock(&disc->disc_mutex);
3356 @@ -249,11 +464,15 @@ static void fc_disc_retry(struct fc_lport *lport)
3357 * @lport: FC local port
3358 * @rport: The previous FC remote port (NULL if new remote port)
3359 * @ids: Identifiers for the new FC remote port
3361 + * Locking Note: This function expects that the disc_mutex is locked
3362 + * before it is called.
3364 -static int fc_disc_new_target(struct fc_lport *lport,
3365 +static int fc_disc_new_target(struct fc_disc *disc,
3366 struct fc_rport *rport,
3367 struct fc_rport_identifiers *ids)
3369 + struct fc_lport *lport = disc->lport;
3370 struct fc_rport_libfc_priv *rp;
3373 @@ -272,7 +491,7 @@ static int fc_disc_new_target(struct fc_lport *lport,
3374 * assigned the same FCID. This should be rare.
3375 * Delete the old one and fall thru to re-create.
3377 - fc_disc_del_target(lport, rport);
3378 + fc_disc_del_target(disc, rport);
3382 @@ -295,7 +514,7 @@ static int fc_disc_new_target(struct fc_lport *lport,
3385 rp = rport->dd_data;
3386 - rp->event_callback = lport->tt.event_callback;
3387 + rp->event_callback = fc_disc_rport_event;
3388 rp->rp_state = RPORT_ST_INIT;
3389 lport->tt.rport_login(rport);
3391 @@ -305,89 +524,111 @@ static int fc_disc_new_target(struct fc_lport *lport,
3394 * fc_disc_del_target - Delete a target
3395 - * @lport: FC local port
3396 + * @disc: FC discovery context
3397 * @rport: The remote port to be removed
3399 -static void fc_disc_del_target(struct fc_lport *lport, struct fc_rport *rport)
3400 +static void fc_disc_del_target(struct fc_disc *disc, struct fc_rport *rport)
3402 - lport->tt.rport_stop(rport);
3403 + struct fc_lport *lport = disc->lport;
3404 + struct fc_rport_libfc_priv *rdata = RPORT_TO_PRIV(rport);
3405 + list_del(&rdata->peers);
3406 + lport->tt.rport_logoff(rport);
3410 * fc_disc_done - Discovery has been completed
3411 - * @lport: FC local port
3412 + * @disc: FC discovery context
3414 -static void fc_disc_done(struct fc_lport *lport)
3415 +static void fc_disc_done(struct fc_disc *disc)
3417 - lport->disc_done = 1;
3418 - lport->disc_pending = 0;
3419 - if (lport->disc_requested)
3420 - lport->tt.disc_start(lport);
3421 + struct fc_lport *lport = disc->lport;
3423 + FC_DEBUG_DISC("Discovery complete for port (%6x)\n",
3424 + fc_host_port_id(lport->host));
3426 + disc->disc_callback(lport, disc->event);
3427 + disc->event = DISC_EV_NONE;
3429 + if (disc->requested)
3430 + fc_disc_gpn_ft_req(disc);
3432 + disc->pending = 0;
3436 - * fc_disc_gpn_ft_req - Send Get Port Names by FC-4 type (GPN_FT) request
3437 - * @lport: FC local port
3438 + * fc_disc_error - Handle error on dNS request
3439 + * @disc: FC discovery context
3440 + * @fp: The frame pointer
3442 -static void fc_disc_gpn_ft_req(struct fc_lport *lport)
3443 +static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)
3445 - struct fc_frame *fp;
3446 - struct fc_seq *sp = NULL;
3448 - struct fc_ct_hdr ct;
3449 - struct fc_ns_gid_ft gid;
3453 - lport->disc_buf_len = 0;
3454 - lport->disc_seq_count = 0;
3455 - fp = fc_frame_alloc(lport, sizeof(*rp));
3459 - rp = fc_frame_payload_get(fp, sizeof(*rp));
3460 - fc_fill_dns_hdr(lport, &rp->ct, FC_NS_GPN_FT, sizeof(rp->gid));
3461 - rp->gid.fn_fc4_type = FC_TYPE_FCP;
3463 - WARN_ON(!fc_lport_test_ready(lport));
3465 - fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
3466 - sp = lport->tt.exch_seq_send(lport, fp,
3467 - fc_disc_gpn_ft_resp, NULL,
3468 - lport, lport->e_d_tov,
3469 - fc_host_port_id(lport->host),
3471 - FC_FC_SEQ_INIT | FC_FC_END_SEQ);
3472 + struct fc_lport *lport = disc->lport;
3473 + unsigned long delay = 0;
3474 + if (fc_disc_debug)
3475 + FC_DBG("Error %ld, retries %d/%d\n",
3476 + PTR_ERR(fp), disc->retry_count,
3477 + FC_DISC_RETRY_LIMIT);
3479 + if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) {
3481 + * Memory allocation failure, or the exchange timed out,
3482 + * retry after delay.
3484 + if (disc->retry_count < FC_DISC_RETRY_LIMIT) {
3485 + /* go ahead and retry */
3487 + delay = msecs_to_jiffies(500);
3490 + msecs_to_jiffies(lport->e_d_tov);
3492 + /* timeout faster first time */
3493 + if (!disc->retry_count)
3496 + disc->retry_count++;
3497 + schedule_delayed_work(&disc->disc_work,
3500 + /* exceeded retries */
3501 + disc->event = DISC_EV_FAILED;
3502 + fc_disc_done(disc);
3506 - fc_disc_retry(lport);
3510 - * fc_disc_error - Handle error on dNS request
3511 - * @lport: FC local port
3512 - * @fp: The frame pointer
3513 + * fc_disc_gpn_ft_req - Send Get Port Names by FC-4 type (GPN_FT) request
3514 + * @lport: FC discovery context
3516 + * Locking Note: This function expects that the disc_mutex is locked
3517 + * before it is called.
3519 -static void fc_disc_error(struct fc_lport *lport, struct fc_frame *fp)
3520 +static void fc_disc_gpn_ft_req(struct fc_disc *disc)
3522 - long err = PTR_ERR(fp);
3523 + struct fc_frame *fp;
3524 + struct fc_lport *lport = disc->lport;
3526 - FC_DEBUG_DISC("Error %ld, retries %d/%d\n", PTR_ERR(fp),
3527 - lport->retry_count, FC_DISC_RETRY_LIMIT);
3528 + WARN_ON(!fc_lport_test_ready(lport));
3531 - case -FC_EX_TIMEOUT:
3532 - if (lport->disc_retry_count++ < FC_DISC_RETRY_LIMIT) {
3533 - fc_disc_gpn_ft_req(lport);
3535 - fc_disc_done(lport);
3539 - FC_DBG("Error code %ld not supported\n", err);
3540 - fc_disc_done(lport);
3543 + disc->pending = 1;
3544 + disc->requested = 0;
3546 + disc->buf_len = 0;
3547 + disc->seq_count = 0;
3548 + fp = fc_frame_alloc(lport,
3549 + sizeof(struct fc_ct_hdr) +
3550 + sizeof(struct fc_ns_gid_ft));
3554 + if (lport->tt.elsct_send(lport, NULL, fp,
3556 + fc_disc_gpn_ft_resp,
3557 + disc, lport->e_d_tov))
3560 + fc_disc_error(disc, fp);
3564 @@ -396,8 +637,9 @@ static void fc_disc_error(struct fc_lport *lport, struct fc_frame *fp)
3565 * @buf: GPN_FT response buffer
3566 * @len: size of response buffer
3568 -static int fc_disc_gpn_ft_parse(struct fc_lport *lport, void *buf, size_t len)
3569 +static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
3571 + struct fc_lport *lport;
3572 struct fc_gpn_ft_resp *np;
3575 @@ -407,13 +649,15 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lport, void *buf, size_t len)
3576 struct fc_rport *rport;
3577 struct fc_rport_libfc_priv *rdata;
3579 + lport = disc->lport;
3582 * Handle partial name record left over from previous call.
3586 np = (struct fc_gpn_ft_resp *)bp;
3587 - tlen = lport->disc_buf_len;
3588 + tlen = disc->buf_len;
3590 WARN_ON(tlen >= sizeof(*np));
3591 plen = sizeof(*np) - tlen;
3592 @@ -421,7 +665,7 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lport, void *buf, size_t len)
3593 WARN_ON(plen >= sizeof(*np));
3596 - np = &lport->disc_buf;
3597 + np = &disc->partial_buf;
3598 memcpy((char *)np + tlen, bp, plen);
3601 @@ -431,9 +675,9 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lport, void *buf, size_t len)
3605 - lport->disc_buf_len = (unsigned char) plen;
3606 + disc->buf_len = (unsigned char) plen;
3607 if (plen == sizeof(*np))
3608 - lport->disc_buf_len = 0;
3609 + disc->buf_len = 0;
3613 @@ -455,7 +699,7 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lport, void *buf, size_t len)
3614 rport = fc_rport_rogue_create(&dp);
3616 rdata = rport->dd_data;
3617 - rdata->event_callback = lport->tt.event_callback;
3618 + rdata->event_callback = fc_disc_rport_event;
3619 rdata->local_port = lport;
3620 lport->tt.rport_login(rport);
3622 @@ -465,7 +709,8 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lport, void *buf, size_t len)
3625 if (np->fp_flags & FC_NS_FID_LAST) {
3626 - fc_disc_done(lport);
3627 + disc->event = DISC_EV_SUCCESS;
3628 + fc_disc_done(disc);
3632 @@ -479,11 +724,15 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lport, void *buf, size_t len)
3633 * Save any partial record at the end of the buffer for next time.
3635 if (error == 0 && len > 0 && len < sizeof(*np)) {
3636 - if (np != &lport->disc_buf)
3637 - memcpy(&lport->disc_buf, np, len);
3638 - lport->disc_buf_len = (unsigned char) len;
3639 + if (np != &disc->partial_buf) {
3640 + FC_DEBUG_DISC("Partial buffer remains "
3641 + "for discovery by (%6x)\n",
3642 + fc_host_port_id(lport->host));
3643 + memcpy(&disc->partial_buf, np, len);
3645 + disc->buf_len = (unsigned char) len;
3647 - lport->disc_buf_len = 0;
3648 + disc->buf_len = 0;
3652 @@ -493,14 +742,13 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lport, void *buf, size_t len)
3654 static void fc_disc_timeout(struct work_struct *work)
3656 - struct fc_lport *lport;
3658 - lport = container_of(work, struct fc_lport, disc_work.work);
3660 - if (lport->disc_pending)
3661 - fc_disc_gpn_ft_req(lport);
3663 - lport->tt.disc_start(lport);
3664 + struct fc_disc *disc = container_of(work,
3667 + mutex_lock(&disc->disc_mutex);
3668 + if (disc->requested && !disc->pending)
3669 + fc_disc_gpn_ft_req(disc);
3670 + mutex_unlock(&disc->disc_mutex);
3674 @@ -509,12 +757,13 @@ static void fc_disc_timeout(struct work_struct *work)
3675 * @fp: response frame
3676 * @lp_arg: Fibre Channel host port instance
3678 - * The response may be in multiple frames
3679 + * Locking Note: This function expects that the disc_mutex is locked
3680 + * before it is called.
3682 static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
3686 - struct fc_lport *lport = lp_arg;
3687 + struct fc_disc *disc = disc_arg;
3688 struct fc_ct_hdr *cp;
3689 struct fc_frame_header *fh;
3690 unsigned int seq_cnt;
3691 @@ -522,8 +771,11 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
3695 + FC_DEBUG_DISC("Received a GPN_FT response on port (%6x)\n",
3696 + fc_host_port_id(disc->lport->host));
3699 - fc_disc_error(lport, fp);
3700 + fc_disc_error(disc, fp);
3704 @@ -532,9 +784,9 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
3705 len = fr_len(fp) - sizeof(*fh);
3706 seq_cnt = ntohs(fh->fh_seq_cnt);
3707 if (fr_sof(fp) == FC_SOF_I3 && seq_cnt == 0 &&
3708 - lport->disc_seq_count == 0) {
3709 + disc->seq_count == 0) {
3710 cp = fc_frame_payload_get(fp, sizeof(*cp));
3713 FC_DBG("GPN_FT response too short, len %d\n",
3715 } else if (ntohs(cp->ct_cmd) == FC_FS_ACC) {
3716 @@ -548,25 +800,26 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
3717 FC_DBG("GPN_FT rejected reason %x exp %x "
3718 "(check zoning)\n", cp->ct_reason,
3720 - fc_disc_done(lport);
3721 + disc->event = DISC_EV_FAILED;
3722 + fc_disc_done(disc);
3724 FC_DBG("GPN_FT unexpected response code %x\n",
3727 } else if (fr_sof(fp) == FC_SOF_N3 &&
3728 - seq_cnt == lport->disc_seq_count) {
3729 + seq_cnt == disc->seq_count) {
3732 FC_DBG("GPN_FT unexpected frame - out of sequence? "
3733 "seq_cnt %x expected %x sof %x eof %x\n",
3734 - seq_cnt, lport->disc_seq_count, fr_sof(fp), fr_eof(fp));
3735 + seq_cnt, disc->seq_count, fr_sof(fp), fr_eof(fp));
3738 - error = fc_disc_gpn_ft_parse(lport, buf, len);
3739 + error = fc_disc_gpn_ft_parse(disc, buf, len);
3741 - fc_disc_retry(lport);
3742 + fc_disc_error(disc, fp);
3744 - lport->disc_seq_count++;
3745 + disc->seq_count++;
3749 @@ -576,27 +829,31 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
3750 * @lport: FC local port
3751 * @dp: The port to rediscover
3753 - * This could be from an RSCN that reported a change for the target.
3754 + * Locking Note: This function expects that the disc_mutex is locked
3755 + * before it is called.
3757 -static void fc_disc_single(struct fc_lport *lport, struct fc_disc_port *dp)
3758 +static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp)
3760 + struct fc_lport *lport;
3761 struct fc_rport *rport;
3762 struct fc_rport *new_rport;
3763 struct fc_rport_libfc_priv *rdata;
3765 + lport = disc->lport;
3767 if (dp->ids.port_id == fc_host_port_id(lport->host))
3770 rport = lport->tt.rport_lookup(lport, dp->ids.port_id);
3772 - fc_disc_del_target(lport, rport);
3773 + fc_disc_del_target(disc, rport);
3774 put_device(&rport->dev); /* hold from lookup */
3777 new_rport = fc_rport_rogue_create(dp);
3779 rdata = new_rport->dd_data;
3780 - rdata->event_callback = lport->tt.event_callback;
3781 + rdata->event_callback = fc_disc_rport_event;
3783 lport->tt.rport_login(new_rport);
3785 @@ -606,19 +863,70 @@ out:
3789 + * fc_disc_stop - Stop discovery for a given lport
3790 + * @lport: The lport that discovery should stop for
3792 +void fc_disc_stop(struct fc_lport *lport)
3794 + struct fc_disc *disc, *next;
3796 + mutex_lock(&disc_list_lock);
3797 + list_for_each_entry_safe(disc, next, &disc_list, list) {
3798 + if (disc->lport == lport) {
3799 + cancel_delayed_work_sync(&disc->disc_work);
3800 + fc_disc_stop_rports(disc);
3803 + mutex_unlock(&disc_list_lock);
3807 + * fc_disc_stop_final - Stop discovery for a given lport
3808 + * @lport: The lport that discovery should stop for
3810 + * This function will block until discovery has been
3811 + * completely stopped and all rports have been deleted.
3813 +void fc_disc_stop_final(struct fc_lport *lport)
3815 + struct fc_disc *disc, *next;
3816 + fc_disc_stop(lport);
3817 + lport->tt.rport_flush_queue();
3819 + mutex_lock(&disc_list_lock);
3820 + list_for_each_entry_safe(disc, next, &disc_list, list) {
3821 + if (disc->lport == lport) {
3822 + list_del(&disc->list);
3826 + mutex_unlock(&disc_list_lock);
3830 * fc_disc_init - Initialize the discovery block
3831 * @lport: FC local port
3833 int fc_disc_init(struct fc_lport *lport)
3835 - INIT_DELAYED_WORK(&lport->disc_work, fc_disc_timeout);
3836 + INIT_LIST_HEAD(&disc_list);
3837 + mutex_init(&disc_list_lock);
3839 if (!lport->tt.disc_start)
3840 lport->tt.disc_start = fc_disc_start;
3842 + if (!lport->tt.disc_stop)
3843 + lport->tt.disc_stop = fc_disc_stop;
3845 + if (!lport->tt.disc_stop_final)
3846 + lport->tt.disc_stop_final = fc_disc_stop_final;
3848 if (!lport->tt.disc_recv_req)
3849 lport->tt.disc_recv_req = fc_disc_recv_req;
3851 + if (!lport->tt.rport_lookup)
3852 + lport->tt.rport_lookup = fc_disc_lookup_rport;
3856 EXPORT_SYMBOL(fc_disc_init);
3857 diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c
3858 new file mode 100644
3859 index 0000000..dd47fe6
3861 +++ b/drivers/scsi/libfc/fc_elsct.c
3864 + * Copyright(c) 2008 Intel Corporation. All rights reserved.
3866 + * This program is free software; you can redistribute it and/or modify it
3867 + * under the terms and conditions of the GNU General Public License,
3868 + * version 2, as published by the Free Software Foundation.
3870 + * This program is distributed in the hope it will be useful, but WITHOUT
3871 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3872 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
3875 + * You should have received a copy of the GNU General Public License along with
3876 + * this program; if not, write to the Free Software Foundation, Inc.,
3877 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
3879 + * Maintained at www.Open-FCoE.org
3883 + * Provide interface to send ELS/CT FC frames
3886 +#include <asm/unaligned.h>
3887 +#include <scsi/fc/fc_gs.h>
3888 +#include <scsi/fc/fc_ns.h>
3889 +#include <scsi/fc/fc_els.h>
3890 +#include <scsi/libfc.h>
3891 +#include <scsi/fc_encode.h>
3894 + * fc_elsct_send - sends ELS/CT frame
3896 +static struct fc_seq *fc_elsct_send(struct fc_lport *lport,
3897 + struct fc_rport *rport,
3898 + struct fc_frame *fp,
3900 + void (*resp)(struct fc_seq *,
3901 + struct fc_frame *fp,
3903 + void *arg, u32 timer_msec)
3905 + enum fc_rctl r_ctl;
3907 + enum fc_fh_type fh_type;
3910 + /* ELS requests */
3911 + if ((op >= ELS_LS_RJT) && (op <= ELS_AUTH_ELS))
3912 + rc = fc_els_fill(lport, rport, fp, op, &r_ctl, &did, &fh_type);
3915 + rc = fc_ct_fill(lport, fp, op, &r_ctl, &did, &fh_type);
3920 + fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type,
3921 + FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
3923 + return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec);
3926 +int fc_elsct_init(struct fc_lport *lport)
3928 + if (!lport->tt.elsct_send)
3929 + lport->tt.elsct_send = fc_elsct_send;
3933 +EXPORT_SYMBOL(fc_elsct_init);
3934 diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
3935 index 67c5bad..12a1196 100644
3936 --- a/drivers/scsi/libfc/fc_exch.c
3937 +++ b/drivers/scsi/libfc/fc_exch.c
3940 #include <scsi/fc/fc_fc2.h>
3942 -#include <scsi/libfc/libfc.h>
3943 +#include <scsi/libfc.h>
3944 +#include <scsi/fc_encode.h>
3946 #define FC_DEF_R_A_TOV (10 * 1000) /* resource allocation timeout */
3948 @@ -60,66 +61,6 @@ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */
3955 - u8 id; /* seq ID */
3956 - u16 ssb_stat; /* status flags for sequence status block */
3957 - u16 cnt; /* frames sent so far on sequence */
3958 - u32 f_ctl; /* F_CTL flags for frames */
3959 - u32 rec_data; /* FC-4 value for REC */
3964 -#define FC_EX_DONE (1 << 0) /* ep is completed */
3965 -#define FC_EX_RST_CLEANUP (1 << 1) /* reset is forcing completion */
3970 - * Locking notes: The ex_lock protects changes to the following fields:
3971 - * esb_stat, f_ctl, seq.ssb_stat, seq.f_ctl.
3973 - * sequence allocation
3975 - * If the em_lock and ex_lock must be taken at the same time, the
3976 - * em_lock must be taken before the ex_lock.
3979 - struct fc_exch_mgr *em; /* exchange manager */
3980 - u32 state; /* internal driver state */
3981 - u16 xid; /* our exchange ID */
3982 - struct list_head ex_list; /* free or busy list linkage */
3983 - spinlock_t ex_lock; /* lock covering exchange state */
3984 - atomic_t ex_refcnt; /* reference counter */
3985 - struct delayed_work timeout_work; /* timer for upper level protocols */
3986 - struct fc_lport *lp; /* fc device instance */
3987 - u16 oxid; /* originator's exchange ID */
3988 - u16 rxid; /* responder's exchange ID */
3989 - u32 oid; /* originator's FCID */
3990 - u32 sid; /* source FCID */
3991 - u32 did; /* destination FCID */
3992 - u32 esb_stat; /* exchange status for ESB */
3993 - u32 r_a_tov; /* r_a_tov from rport (msec) */
3994 - u8 seq_id; /* next sequence ID to use */
3995 - u32 f_ctl; /* F_CTL flags for sequences */
3996 - u8 fh_type; /* frame type */
3997 - enum fc_class class; /* class of service */
3998 - struct fc_seq seq; /* single sequence */
4000 - * Handler for responses to this current exchange.
4002 - void (*resp)(struct fc_seq *, struct fc_frame *, void *);
4003 - void (*destructor)(struct fc_seq *, void *);
4005 - * arg is passed as void pointer to exchange
4006 - * resp and destructor handlers
4014 * This structure is the center for creating exchanges and sequences.
4015 @@ -131,6 +72,8 @@ struct fc_exch_mgr {
4016 u16 last_xid; /* last allocated exchange ID */
4017 u16 min_xid; /* min exchange ID */
4018 u16 max_xid; /* max exchange ID */
4019 + u16 max_read; /* max exchange ID for read */
4020 + u16 last_read; /* last xid allocated for read */
4021 u32 total_exches; /* total allocated exchanges */
4022 struct list_head ex_list; /* allocated exchanges list */
4023 struct fc_lport *lp; /* fc device instance */
4024 @@ -151,14 +94,12 @@ struct fc_exch_mgr {
4026 struct fc_exch **exches; /* for exch pointers indexed by xid */
4029 #define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
4030 -#define fc_exch_next_xid(mp, id) ((id == mp->max_xid) ? mp->min_xid : id + 1)
4032 static void fc_exch_rrq(struct fc_exch *);
4033 static void fc_seq_ls_acc(struct fc_seq *);
4034 static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason,
4035 - enum fc_els_rjt_explan);
4036 + enum fc_els_rjt_explan);
4037 static void fc_exch_els_rec(struct fc_seq *, struct fc_frame *);
4038 static void fc_exch_els_rrq(struct fc_seq *, struct fc_frame *);
4039 static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp);
4040 @@ -274,34 +215,57 @@ static void fc_exch_hold(struct fc_exch *ep)
4044 - * Fill in frame header.
4046 - * The following fields are the responsibility of this routine:
4047 - * d_id, s_id, df_ctl, oxid, rxid, cs_ctl, seq_id
4049 - * The following fields are handled by the caller.
4050 - * r_ctl, type, f_ctl, seq_cnt, parm_offset
4052 - * That should be a complete list.
4054 - * We may be the originator or responder to the sequence.
4055 + * setup fc hdr by initializing few more FC header fields and sof/eof.
4056 + * Initialized fields by this func:
4057 + * - fh_ox_id, fh_rx_id, fh_seq_id, fh_seq_cnt
4060 -static void fc_seq_fill_hdr(struct fc_seq *sp, struct fc_frame *fp)
4061 +static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp,
4064 struct fc_frame_header *fh = fc_frame_header_get(fp);
4065 - struct fc_exch *ep;
4068 - ep = fc_seq_exch(sp);
4069 + fr_sof(fp) = ep->class;
4071 + fr_sof(fp) = fc_sof_normal(ep->class);
4073 + if (f_ctl & FC_FC_END_SEQ) {
4074 + fr_eof(fp) = FC_EOF_T;
4075 + if (fc_sof_needs_ack(ep->class))
4076 + fr_eof(fp) = FC_EOF_N;
4079 + * The number of fill bytes to make the length a 4-byte
4080 + * multiple is the low order 2-bits of the f_ctl.
4081 + * The fill itself will have been cleared by the frame
4083 + * After this, the length will be even, as expected by
4086 + fill = fr_len(fp) & 3;
4089 + /* TODO, this may be a problem with fragmented skb */
4090 + skb_put(fp_skb(fp), fill);
4091 + hton24(fh->fh_f_ctl, f_ctl | fill);
4094 + WARN_ON(fr_len(fp) % 4 != 0); /* no pad to non last frame */
4095 + fr_eof(fp) = FC_EOF_N;
4098 - hton24(fh->fh_s_id, ep->sid);
4099 - hton24(fh->fh_d_id, ep->did);
4101 + * Initialize remainig fh fields
4102 + * from fc_fill_fc_hdr
4104 fh->fh_ox_id = htons(ep->oxid);
4105 fh->fh_rx_id = htons(ep->rxid);
4106 - fh->fh_seq_id = sp->id;
4107 - fh->fh_cs_ctl = 0;
4108 - fh->fh_df_ctl = 0;
4109 + fh->fh_seq_id = ep->seq.id;
4110 + fh->fh_seq_cnt = htons(ep->seq.cnt);
4115 * Release a reference to an exchange.
4116 * If the refcnt goes to zero and the exchange is complete, it is freed.
4117 @@ -432,8 +396,9 @@ int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec)
4119 fp = fc_frame_alloc(ep->lp, 0);
4121 - fc_frame_setup(fp, FC_RCTL_BA_ABTS, FC_TYPE_BLS);
4122 - error = fc_seq_send(ep->lp, sp, fp, FC_FC_END_SEQ);
4123 + fc_fill_fc_hdr(fp, FC_RCTL_BA_ABTS, ep->did, ep->sid,
4124 + FC_TYPE_BLS, FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
4125 + error = fc_seq_send(ep->lp, sp, fp);
4129 @@ -508,36 +473,66 @@ static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
4133 - * Allocate an exchange.
4134 + * fc_em_alloc_xid - returns an xid based on request type
4135 + * @lp : ptr to associated lport
4136 + * @fp : ptr to the assocated frame
4138 - * if xid is supplied zero then assign next free exchange ID
4139 - * from exchange manager, otherwise use supplied xid.
4140 - * Returns with exch lock held.
4141 + * check the associated fc_fsp_pkt to get scsi command type and
4142 + * command direction to decide from which range this exch id
4143 + * will be allocated from.
4145 + * Returns : 0 or an valid xid
4147 -struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, u16 xid)
4148 +static u16 fc_em_alloc_xid(struct fc_exch_mgr *mp, const struct fc_frame *fp)
4150 + u16 xid, min, max;
4152 struct fc_exch *ep = NULL;
4153 - u16 min_xid, max_xid;
4155 - min_xid = mp->min_xid;
4156 - max_xid = mp->max_xid;
4158 - * if xid is supplied then verify its xid range
4161 - if (unlikely((xid < min_xid) || (xid > max_xid))) {
4162 - FC_DBG("Invalid xid 0x:%x\n", xid);
4165 - if (unlikely(mp->exches[xid - min_xid] != NULL)) {
4166 - FC_DBG("xid 0x:%x is already in use\n", xid);
4168 + if (mp->max_read) {
4169 + if (fc_frame_is_read(fp)) {
4170 + min = mp->min_xid;
4171 + max = mp->max_read;
4172 + plast = &mp->last_read;
4174 + min = mp->max_read + 1;
4175 + max = mp->max_xid;
4176 + plast = &mp->last_xid;
4179 + min = mp->min_xid;
4180 + max = mp->max_xid;
4181 + plast = &mp->last_xid;
4185 + xid = (xid == max) ? min : xid + 1;
4186 + ep = mp->exches[xid - mp->min_xid];
4187 + } while ((ep != NULL) && (xid != *plast));
4190 - * Allocate new exchange
4201 + * fc_exch_alloc - allocate an exchange.
4202 + * @mp : ptr to the exchange manager
4205 + * if xid is supplied zero then assign next free exchange ID
4206 + * from exchange manager, otherwise use supplied xid.
4207 + * Returns with exch lock held.
4209 +struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
4210 + struct fc_frame *fp, u16 xid)
4212 + struct fc_exch *ep = NULL;
4214 + /* allocate memory for exchange */
4215 ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
4217 atomic_inc(&mp->stats.no_free_exch);
4218 @@ -546,40 +541,26 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, u16 xid)
4219 memset(ep, 0, sizeof(*ep));
4221 spin_lock_bh(&mp->em_lock);
4224 - * if xid is zero then assign next free exchange ID
4226 + /* alloc xid if input xid 0 */
4228 - xid = fc_exch_next_xid(mp, mp->last_xid);
4230 - * find next free xid using linear search
4232 - while (mp->exches[xid - min_xid] != NULL) {
4233 - if (xid == mp->last_xid)
4235 - xid = fc_exch_next_xid(mp, xid);
4238 - if (unlikely(mp->exches[xid - min_xid] != NULL))
4239 + /* alloc a new xid */
4240 + xid = fc_em_alloc_xid(mp, fp);
4242 + printk(KERN_ERR "fc_em_alloc_xid() failed\n");
4244 - mp->last_xid = xid;
4248 - /* lport lock ? */
4249 - if (mp->lp->state == LPORT_ST_RESET)
4250 - goto err; /* don't add new ep during local port reset */
4252 fc_exch_hold(ep); /* hold for exch in mp */
4253 spin_lock_init(&ep->ex_lock);
4255 * Hold exch lock for caller to prevent fc_exch_reset()
4256 - * from releasing exch while fc_exch_alloc() caller is
4257 + * from releasing exch while fc_exch_alloc() caller is
4258 * still working on exch.
4260 spin_lock_bh(&ep->ex_lock);
4262 - mp->exches[xid - min_xid] = ep;
4263 + mp->exches[xid - mp->min_xid] = ep;
4264 list_add_tail(&ep->ex_list, &mp->ex_list);
4265 fc_seq_alloc(ep, ep->seq_id++);
4267 @@ -874,55 +855,17 @@ struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
4269 EXPORT_SYMBOL(fc_seq_start_next);
4271 -int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp,
4272 - struct fc_frame *fp, u32 f_ctl)
4273 +int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp)
4276 - struct fc_frame_header *fh;
4277 - enum fc_class class;
4279 + struct fc_frame_header *fh = fc_frame_header_get(fp);
4282 ep = fc_seq_exch(sp);
4283 WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT);
4285 - fc_seq_fill_hdr(sp, fp);
4286 - fh = fc_frame_header_get(fp);
4287 - class = ep->class;
4288 - fr_sof(fp) = class;
4290 - fr_sof(fp) = fc_sof_normal(class);
4292 - if (f_ctl & FC_FC_END_SEQ) {
4293 - fr_eof(fp) = FC_EOF_T;
4294 - if (fc_sof_needs_ack(class))
4295 - fr_eof(fp) = FC_EOF_N;
4298 - * The number of fill bytes to make the length a 4-byte
4299 - * multiple is the low order 2-bits of the f_ctl.
4300 - * The fill itself will have been cleared by the frame
4302 - * After this, the length will be even, as expected by
4303 - * the transport. Don't include the fill in the f_ctl
4304 - * saved in the sequence.
4306 - fill = fr_len(fp) & 3;
4309 - /* TODO, this may be a problem with fragmented skb */
4310 - skb_put(fp_skb(fp), fill);
4312 - f_ctl |= sp->f_ctl | ep->f_ctl;
4314 - WARN_ON(fr_len(fp) % 4 != 0); /* no pad to non last frame */
4315 - f_ctl |= sp->f_ctl | ep->f_ctl;
4316 - f_ctl &= ~FC_FC_SEQ_INIT;
4317 - fr_eof(fp) = FC_EOF_N;
4320 - hton24(fh->fh_f_ctl, f_ctl | fill);
4321 - fh->fh_seq_cnt = htons(sp->cnt);
4322 + sp->f_ctl = ntoh24(fh->fh_f_ctl);
4323 + fc_exch_setup_hdr(ep, fp, sp->f_ctl);
4326 * update sequence count if this frame is carrying
4327 @@ -946,12 +889,10 @@ int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp,
4328 * We can only be called to send once for each sequence.
4330 spin_lock_bh(&ep->ex_lock);
4331 - sp->f_ctl = f_ctl; /* save for possible abort */
4332 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */
4333 - if (f_ctl & FC_FC_END_SEQ) {
4334 - if (f_ctl & FC_FC_SEQ_INIT)
4335 - ep->esb_stat &= ~ESB_ST_SEQ_INIT;
4337 + sp->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */
4338 + if (sp->f_ctl & (FC_FC_END_SEQ | FC_FC_SEQ_INIT))
4339 + ep->esb_stat &= ~ESB_ST_SEQ_INIT;
4340 spin_unlock_bh(&ep->ex_lock);
4343 @@ -986,10 +927,11 @@ static void fc_seq_send_last(struct fc_seq *sp, struct fc_frame *fp,
4344 enum fc_rctl rctl, enum fc_fh_type fh_type)
4347 + struct fc_exch *ep = fc_seq_exch(sp);
4349 - fc_frame_setup(fp, rctl, fh_type);
4350 - f_ctl = FC_FC_SEQ_INIT | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
4351 - fc_seq_send(fc_seq_exch(sp)->lp, sp, fp, f_ctl);
4352 + f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
4353 + fc_fill_fc_hdr(fp, rctl, ep->did, ep->sid, fh_type, f_ctl, 0);
4354 + fc_seq_send(fc_seq_exch(sp)->lp, sp, fp);
4358 @@ -1001,7 +943,8 @@ static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp)
4359 struct fc_frame *fp;
4360 struct fc_frame_header *rx_fh;
4361 struct fc_frame_header *fh;
4362 - struct fc_lport *lp = fc_seq_exch(sp)->lp;
4363 + struct fc_exch *ep = fc_seq_exch(sp);
4364 + struct fc_lport *lp = ep->lp;
4368 @@ -1013,7 +956,6 @@ static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp)
4372 - fc_seq_fill_hdr(sp, fp);
4373 fh = fc_frame_header_get(fp);
4374 fh->fh_r_ctl = FC_RCTL_ACK_1;
4375 fh->fh_type = FC_TYPE_BLS;
4376 @@ -1034,6 +976,7 @@ static void fc_seq_send_ack(struct fc_seq *sp, const struct fc_frame *rx_fp)
4377 f_ctl ^= FC_FC_EX_CTX | FC_FC_SEQ_CTX;
4378 hton24(fh->fh_f_ctl, f_ctl);
4380 + fc_exch_setup_hdr(ep, fp, f_ctl);
4381 fh->fh_seq_id = rx_fh->fh_seq_id;
4382 fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
4383 fh->fh_parm_offset = htonl(1); /* ack single frame */
4384 @@ -1514,7 +1457,7 @@ static void fc_exch_reset(struct fc_exch *ep)
4387 if (cancel_delayed_work(&ep->timeout_work))
4388 - atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
4389 + atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
4392 if (ep->esb_stat & ESB_ST_REC_QUAL)
4393 @@ -1565,22 +1508,6 @@ restart:
4395 EXPORT_SYMBOL(fc_exch_mgr_reset);
4397 -void fc_seq_get_xids(struct fc_seq *sp, u16 *oxid, u16 *rxid)
4399 - struct fc_exch *ep;
4401 - ep = fc_seq_exch(sp);
4405 -EXPORT_SYMBOL(fc_seq_get_xids);
4407 -void fc_seq_set_rec_data(struct fc_seq *sp, u32 rec_data)
4409 - sp->rec_data = rec_data;
4411 -EXPORT_SYMBOL(fc_seq_set_rec_data);
4414 * Handle incoming ELS REC - Read Exchange Concise.
4415 * Note that the requesting port may be different than the S_ID in the request.
4416 @@ -1648,8 +1575,8 @@ static void fc_exch_els_rec(struct fc_seq *sp, struct fc_frame *rfp)
4417 hton24(acc->reca_rfid, ep->sid);
4418 acc->reca_fc4value = htonl(ep->seq.rec_data);
4419 acc->reca_e_stat = htonl(ep->esb_stat & (ESB_ST_RESP |
4421 - ESB_ST_COMPLETE));
4423 + ESB_ST_COMPLETE));
4424 sp = fc_seq_start_next(sp);
4425 fc_seq_send_last(sp, fp, FC_RCTL_ELS_REP, FC_TYPE_ELS);
4427 @@ -1723,7 +1650,6 @@ static void fc_exch_rrq(struct fc_exch *ep)
4428 fp = fc_frame_alloc(lp, sizeof(*rrq));
4431 - fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
4432 rrq = fc_frame_payload_get(fp, sizeof(*rrq));
4433 memset(rrq, 0, sizeof(*rrq));
4434 rrq->rrq_cmd = ELS_RRQ;
4435 @@ -1734,9 +1660,13 @@ static void fc_exch_rrq(struct fc_exch *ep)
4437 if (ep->esb_stat & ESB_ST_RESP)
4440 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, did,
4441 + fc_host_port_id(lp->host), FC_TYPE_ELS,
4442 + FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
4444 rrq_sp = fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep,
4445 - lp->e_d_tov, fc_host_port_id(lp->host), did,
4446 - FC_FC_SEQ_INIT | FC_FC_END_SEQ);
4449 ep->esb_stat |= ESB_ST_REC_QUAL;
4450 fc_exch_timer_set_locked(ep, ep->r_a_tov);
4451 @@ -1791,7 +1721,7 @@ static void fc_exch_els_rrq(struct fc_seq *sp, struct fc_frame *fp)
4453 if (ep->esb_stat & ESB_ST_COMPLETE) {
4454 if (cancel_delayed_work(&ep->timeout_work))
4455 - atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
4456 + atomic_dec(&ep->ex_refcnt); /* drop timer hold */
4459 spin_unlock_bh(&ep->ex_lock);
4460 @@ -1827,6 +1757,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
4462 * Memory need for EM
4464 +#define xid_ok(i, m1, m2) (((i) >= (m1)) && ((i) <= (m2)))
4465 len = (max_xid - min_xid + 1) * (sizeof(struct fc_exch *));
4466 len += sizeof(struct fc_exch_mgr);
4468 @@ -1837,10 +1768,22 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
4470 mp->total_exches = 0;
4471 mp->exches = (struct fc_exch **)(mp + 1);
4472 - mp->last_xid = min_xid - 1;
4474 + /* adjust em exch xid range for offload */
4475 mp->min_xid = min_xid;
4476 mp->max_xid = max_xid;
4478 + mp->last_xid = min_xid - 1;
4480 + mp->last_read = 0;
4481 + if (lp->lro_enabled && xid_ok(lp->lro_xid, min_xid, max_xid)) {
4482 + mp->max_read = lp->lro_xid;
4483 + mp->last_read = min_xid - 1;
4484 + mp->last_xid = mp->max_read;
4486 + /* disable lro if no xid control over read */
4487 + lp->lro_enabled = 0;
4490 INIT_LIST_HEAD(&mp->ex_list);
4491 spin_lock_init(&mp->em_lock);
4493 @@ -1873,7 +1816,8 @@ struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp)
4495 if (!lp || !lp->emp)
4497 - return fc_exch_alloc(lp->emp, 0);
4499 + return fc_exch_alloc(lp->emp, fp, 0);
4501 EXPORT_SYMBOL(fc_exch_get);
4503 @@ -1883,13 +1827,11 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
4504 struct fc_frame *fp,
4506 void (*destructor)(struct fc_seq *, void *),
4507 - void *arg, u32 timer_msec,
4508 - u32 sid, u32 did, u32 f_ctl)
4509 + void *arg, u32 timer_msec)
4512 struct fc_seq *sp = NULL;
4513 struct fc_frame_header *fh;
4517 ep = lp->tt.exch_get(lp, fp);
4518 @@ -1898,7 +1840,8 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
4521 ep->esb_stat |= ESB_ST_SEQ_INIT;
4522 - fc_exch_set_addr(ep, sid, did);
4523 + fh = fc_frame_header_get(fp);
4524 + fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id));
4526 ep->destructor = destructor;
4528 @@ -1907,43 +1850,20 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
4530 WARN_ON((sp->f_ctl & FC_FC_END_SEQ) != 0);
4532 - fr_sof(fp) = ep->class;
4534 - fr_sof(fp) = fc_sof_normal(ep->class);
4535 - fr_eof(fp) = FC_EOF_T;
4536 - if (fc_sof_needs_ack(ep->class))
4537 - fr_eof(fp) = FC_EOF_N;
4539 - fc_seq_fill_hdr(sp, fp);
4542 - * The number of fill bytes to make the length a 4-byte multiple is
4543 - * the low order 2-bits of the f_ctl. The fill itself will have been
4544 - * cleared by the frame allocation.
4545 - * After this, the length will be even, as expected by the transport.
4546 - * Don't include the fill in the f_ctl saved in the sequence.
4548 - fill = fr_len(fp) & 3;
4551 - /* TODO, this may be a problem with fragmented skb */
4552 - skb_put(fp_skb(fp), fill);
4554 - f_ctl |= ep->f_ctl;
4555 - fh = fc_frame_header_get(fp);
4556 - hton24(fh->fh_f_ctl, f_ctl | fill);
4557 - fh->fh_seq_cnt = htons(sp->cnt++);
4558 ep->fh_type = fh->fh_type; /* save for possbile timeout handling */
4559 + ep->f_ctl = ntoh24(fh->fh_f_ctl);
4560 + fc_exch_setup_hdr(ep, fp, ep->f_ctl);
4563 if (unlikely(lp->tt.frame_send(lp, fp)))
4567 fc_exch_timer_set_locked(ep, timer_msec);
4568 - sp->f_ctl = f_ctl; /* save for possible abort */
4569 ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */
4570 + sp->f_ctl = ep->f_ctl; /* save for possible abort */
4572 - if (f_ctl & FC_FC_SEQ_INIT)
4573 + if (ep->f_ctl & FC_FC_SEQ_INIT)
4574 ep->esb_stat &= ~ESB_ST_SEQ_INIT;
4575 spin_unlock_bh(&ep->ex_lock);
4577 @@ -2032,11 +1952,6 @@ int fc_exch_init(struct fc_lport *lp)
4578 if (!lp->tt.seq_exch_abort)
4579 lp->tt.seq_exch_abort = fc_seq_exch_abort;
4581 - if (!lp->tt.seq_get_xids)
4582 - lp->tt.seq_get_xids = fc_seq_get_xids;
4584 - if (!lp->tt.seq_set_rec_data)
4585 - lp->tt.seq_set_rec_data = fc_seq_set_rec_data;
4588 EXPORT_SYMBOL(fc_exch_init);
4589 diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
4590 index 01e84dc..04ced7f 100644
4591 --- a/drivers/scsi/libfc/fc_fcp.c
4592 +++ b/drivers/scsi/libfc/fc_fcp.c
4595 #include <scsi/fc/fc_fc2.h>
4597 -#include <scsi/libfc/libfc.h>
4598 +#include <scsi/libfc.h>
4599 +#include <scsi/fc_encode.h>
4601 MODULE_AUTHOR("Open-FCoE.org");
4602 MODULE_DESCRIPTION("libfc");
4603 MODULE_LICENSE("GPL");
4604 -MODULE_VERSION("1.0.3");
4606 static int fc_fcp_debug;
4608 @@ -388,15 +388,23 @@ crc_err:
4612 - * Send SCSI data to target.
4613 + * fc_fcp_send_data - Send SCSI data to target.
4614 + * @fsp: ptr to fc_fcp_pkt
4615 + * @sp: ptr to this sequence
4616 + * @offset: starting offset for this data request
4617 + * @seq_blen: the burst length for this data request
4619 * Called after receiving a Transfer Ready data descriptor.
4620 * if LLD is capable of seq offload then send down seq_blen
4621 * size of data in single frame, otherwise send multiple FC
4622 * frames of max FC frame payload supported by target port.
4624 + * Returns : 0 for success.
4626 static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
4627 size_t offset, size_t seq_blen)
4629 + struct fc_exch *ep;
4630 struct scsi_cmnd *sc;
4631 struct scatterlist *sg;
4632 struct fc_frame *fp = NULL;
4633 @@ -405,7 +413,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
4637 - size_t frame_offset;
4638 + size_t frame_offset, fh_parm_offset;
4642 @@ -438,7 +446,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
4645 remaining = seq_blen;
4646 - frame_offset = offset;
4647 + fh_parm_offset = frame_offset = offset;
4649 seq = lp->tt.seq_start_next(seq);
4650 f_ctl = FC_FC_REL_OFF;
4651 @@ -501,8 +509,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
4652 data = (void *)(fr_hdr(fp)) +
4653 sizeof(struct fc_frame_header);
4655 - fc_frame_setup(fp, FC_RCTL_DD_SOL_DATA, FC_TYPE_FCP);
4656 - fc_frame_set_offset(fp, frame_offset);
4657 + fh_parm_offset = frame_offset;
4658 fr_max_payload(fp) = fsp->max_payload;
4660 sg_bytes = min(tlen, sg->length - offset);
4661 @@ -539,28 +546,30 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
4663 remaining -= sg_bytes;
4665 - if (remaining == 0) {
4667 - * Send a request sequence with
4668 - * transfer sequence initiative.
4670 - f_ctl |= FC_FC_SEQ_INIT | FC_FC_END_SEQ;
4671 - error = lp->tt.seq_send(lp, seq, fp, f_ctl);
4672 - } else if (tlen == 0) {
4674 - * send fragment using for a sequence.
4676 - error = lp->tt.seq_send(lp, seq, fp, f_ctl);
4684 + * Send sequence with transfer sequence initiative in case
4685 + * this is last FCP frame of the sequence.
4687 + if (remaining == 0)
4688 + f_ctl |= FC_FC_SEQ_INIT | FC_FC_END_SEQ;
4690 + ep = fc_seq_exch(seq);
4691 + fc_fill_fc_hdr(fp, FC_RCTL_DD_SOL_DATA, ep->did, ep->sid,
4692 + FC_TYPE_FCP, f_ctl, fh_parm_offset);
4695 + * send fragment using for a sequence.
4697 + error = lp->tt.seq_send(lp, seq, fp);
4699 WARN_ON(1); /* send error should be rare */
4700 fc_fcp_retry_cmd(fsp);
4705 fsp->xfer_len += seq_blen; /* premature count? */
4707 @@ -684,7 +693,7 @@ static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg)
4708 (size_t) ntohl(dd->ft_data_ro),
4709 (size_t) ntohl(dd->ft_burst_len));
4711 - lp->tt.seq_set_rec_data(seq, fsp->xfer_len);
4712 + seq->rec_data = fsp->xfer_len;
4713 else if (rc == -ENOMEM)
4714 fsp->state |= FC_SRB_NOMEM;
4715 } else if (r_ctl == FC_RCTL_DD_SOL_DATA) {
4716 @@ -694,7 +703,7 @@ static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg)
4718 WARN_ON(fr_len(fp) < sizeof(*fh)); /* len may be 0 */
4719 fc_fcp_recv_data(fsp, fp);
4720 - lp->tt.seq_set_rec_data(seq, fsp->xfer_contig_end);
4721 + seq->rec_data = fsp->xfer_contig_end;
4722 } else if (r_ctl == FC_RCTL_DD_CMD_STATUS) {
4723 WARN_ON(fr_flags(fp) & FCPHF_CRC_UNCHECKED);
4725 @@ -833,6 +842,7 @@ static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
4727 struct fc_lport *lp = fsp->lp;
4729 + struct fc_exch *ep;
4732 if (fsp->state & FC_SRB_ABORT_PENDING)
4733 @@ -864,11 +874,13 @@ static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
4734 csp = lp->tt.seq_start_next(seq);
4735 conf_frame = fc_frame_alloc(fsp->lp, 0);
4737 - fc_frame_setup(conf_frame,
4738 - FC_RCTL_DD_SOL_CTL, FC_TYPE_FCP);
4739 f_ctl = FC_FC_SEQ_INIT;
4740 f_ctl |= FC_FC_LAST_SEQ | FC_FC_END_SEQ;
4741 - lp->tt.seq_send(lp, csp, conf_frame, f_ctl);
4742 + ep = fc_seq_exch(seq);
4743 + fc_fill_fc_hdr(conf_frame, FC_RCTL_DD_SOL_CTL,
4745 + FC_TYPE_FCP, f_ctl, 0);
4746 + lp->tt.seq_send(lp, csp, conf_frame);
4749 lp->tt.exch_done(seq);
4750 @@ -947,7 +959,7 @@ static void fc_fcp_abort_io(struct fc_lport *lp)
4751 * This is called by upper layer protocol.
4752 * Return : zero for success and -1 for failure
4753 * Context : called from queuecommand which can be called from process
4754 - * or scsi soft irq.
4755 + * or scsi soft irq.
4756 * Locks : called with the host lock and irqs disabled.
4758 static int fc_fcp_pkt_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp)
4759 @@ -995,18 +1007,16 @@ static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
4762 memcpy(fc_frame_payload_get(fp, len), &fsp->cdb_cmd, len);
4763 - fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CMD, FC_TYPE_FCP);
4764 - fc_frame_set_offset(fp, 0);
4765 + fr_cmd(fp) = fsp->cmd;
4767 fsp->max_payload = rport->maxframe_size;
4768 rp = rport->dd_data;
4769 - seq = lp->tt.exch_seq_send(lp, fp,
4771 - fc_fcp_pkt_destroy,
4773 - fc_host_port_id(rp->local_port->host),
4775 - FC_FC_SEQ_INIT | FC_FC_END_SEQ);
4777 + fc_fill_fc_hdr(fp, FC_RCTL_DD_UNSOL_CMD, rport->port_id,
4778 + fc_host_port_id(rp->local_port->host), FC_TYPE_FCP,
4779 + FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
4781 + seq = lp->tt.exch_seq_send(lp, fp, resp, fc_fcp_pkt_destroy, fsp, 0);
4785 @@ -1018,8 +1028,8 @@ static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
4787 setup_timer(&fsp->timer, fc_fcp_timeout, (unsigned long)fsp);
4788 fc_fcp_timer_set(fsp,
4789 - (fsp->tgt_flags & FC_RP_FLAGS_REC_SUPPORTED) ?
4790 - FC_SCSI_REC_TOV : FC_SCSI_ER_TIMEOUT);
4791 + (fsp->tgt_flags & FC_RP_FLAGS_REC_SUPPORTED) ?
4792 + FC_SCSI_REC_TOV : FC_SCSI_ER_TIMEOUT);
4794 fc_fcp_unlock_pkt(fsp);
4796 @@ -1249,50 +1259,33 @@ unlock:
4797 static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
4799 struct fc_lport *lp;
4800 - struct fc_seq *seq;
4801 struct fc_frame *fp;
4802 - struct fc_els_rec *rec;
4803 struct fc_rport *rport;
4804 struct fc_rport_libfc_priv *rp;
4810 rp = rport->dd_data;
4811 - seq = fsp->seq_ptr;
4812 - if (!seq || rp->rp_state != RPORT_ST_READY) {
4813 + if (!fsp->seq_ptr || rp->rp_state != RPORT_ST_READY) {
4814 fsp->status_code = FC_HRD_ERROR;
4815 fsp->io_status = SUGGEST_RETRY << 24;
4816 fc_fcp_complete_locked(fsp);
4819 - lp->tt.seq_get_xids(seq, &ox_id, &rx_id);
4820 - fp = fc_frame_alloc(lp, sizeof(*rec));
4821 + fp = fc_frame_alloc(lp, sizeof(struct fc_els_rec));
4825 - rec = fc_frame_payload_get(fp, sizeof(*rec));
4826 - memset(rec, 0, sizeof(*rec));
4827 - rec->rec_cmd = ELS_REC;
4828 - hton24(rec->rec_s_id, fc_host_port_id(lp->host));
4829 - rec->rec_ox_id = htons(ox_id);
4830 - rec->rec_rx_id = htons(rx_id);
4832 - fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
4833 - fc_frame_set_offset(fp, 0);
4834 - seq = lp->tt.exch_seq_send(lp, fp,
4835 - fc_fcp_rec_resp, NULL,
4836 - fsp, jiffies_to_msecs(FC_SCSI_REC_TOV),
4837 - fc_host_port_id(rp->local_port->host),
4839 - FC_FC_SEQ_INIT | FC_FC_END_SEQ);
4842 + fr_seq(fp) = fsp->seq_ptr;
4843 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id,
4844 + fc_host_port_id(rp->local_port->host), FC_TYPE_ELS,
4845 + FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
4846 + if (lp->tt.elsct_send(lp, rport, fp, ELS_REC, fc_fcp_rec_resp,
4847 + fsp, jiffies_to_msecs(FC_SCSI_REC_TOV))) {
4848 fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */
4851 - fc_frame_free(fp);
4853 + fc_frame_free(fp);
4855 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
4856 fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
4857 @@ -1510,17 +1503,15 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
4858 struct fc_lport *lp = fsp->lp;
4859 struct fc_rport *rport;
4860 struct fc_rport_libfc_priv *rp;
4861 + struct fc_exch *ep = fc_seq_exch(fsp->seq_ptr);
4863 struct fcp_srr *srr;
4864 struct fc_frame *fp;
4870 rp = rport->dd_data;
4871 cdb_op = fsp->cdb_cmd.fc_cdb[0];
4872 - lp->tt.seq_get_xids(fsp->seq_ptr, &ox_id, &rx_id);
4874 if (!(rp->flags & FC_RP_FLAGS_RETRY) || rp->rp_state != RPORT_ST_READY)
4875 goto retry; /* shouldn't happen */
4876 @@ -1531,19 +1522,17 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
4877 srr = fc_frame_payload_get(fp, sizeof(*srr));
4878 memset(srr, 0, sizeof(*srr));
4879 srr->srr_op = ELS_SRR;
4880 - srr->srr_ox_id = htons(ox_id);
4881 - srr->srr_rx_id = htons(rx_id);
4882 + srr->srr_ox_id = htons(ep->oxid);
4883 + srr->srr_rx_id = htons(ep->rxid);
4884 srr->srr_r_ctl = r_ctl;
4885 srr->srr_rel_off = htonl(offset);
4887 - fc_frame_setup(fp, FC_RCTL_ELS4_REQ, FC_TYPE_FCP);
4888 - fc_frame_set_offset(fp, 0);
4889 - seq = lp->tt.exch_seq_send(lp, fp,
4890 - fc_fcp_srr_resp, NULL,
4891 - fsp, jiffies_to_msecs(FC_SCSI_REC_TOV),
4892 - fc_host_port_id(rp->local_port->host),
4894 - FC_FC_SEQ_INIT | FC_FC_END_SEQ);
4895 + fc_fill_fc_hdr(fp, FC_RCTL_ELS4_REQ, rport->port_id,
4896 + fc_host_port_id(rp->local_port->host), FC_TYPE_FCP,
4897 + FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
4899 + seq = lp->tt.exch_seq_send(lp, fp, fc_fcp_srr_resp, NULL,
4900 + fsp, jiffies_to_msecs(FC_SCSI_REC_TOV));
4904 @@ -1565,8 +1554,6 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
4906 struct fc_fcp_pkt *fsp = arg;
4907 struct fc_frame_header *fh;
4912 fc_fcp_srr_error(fsp, fp);
4913 @@ -1590,8 +1577,6 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
4916 fsp->recov_seq = NULL;
4918 - fsp->lp->tt.seq_get_xids(fsp->seq_ptr, &ox_id, &rx_id);
4919 switch (fc_frame_payload_op(fp)) {
4921 fsp->recov_retry = 0;
4922 @@ -2007,7 +1992,7 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd)
4925 shost_printk(KERN_INFO, shost, "Host reset failed. "
4926 - "lport not ready.\n");
4927 + "lport not ready.\n");
4931 diff --git a/drivers/scsi/libfc/fc_frame.c b/drivers/scsi/libfc/fc_frame.c
4932 index 388dc6c..0bbeff2 100644
4933 --- a/drivers/scsi/libfc/fc_frame.c
4934 +++ b/drivers/scsi/libfc/fc_frame.c
4936 #include <linux/skbuff.h>
4937 #include <linux/crc32.h>
4939 -#include <scsi/libfc/fc_frame.h>
4940 +#include <scsi/fc_frame.h>
4943 * Check the CRC in a frame.
4944 @@ -82,7 +82,8 @@ struct fc_frame *fc_frame_alloc_fill(struct fc_lport *lp, size_t payload_len)
4946 memset((char *) fr_hdr(fp) + payload_len, 0, fill);
4947 /* trim is OK, we just allocated it so there are no fragments */
4948 - skb_trim(fp_skb(fp), payload_len + sizeof(struct fc_frame_header));
4949 + skb_trim(fp_skb(fp),
4950 + payload_len + sizeof(struct fc_frame_header));
4954 diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
4955 index 7e7c060..083d57b 100644
4956 --- a/drivers/scsi/libfc/fc_lport.c
4957 +++ b/drivers/scsi/libfc/fc_lport.c
4960 #include <scsi/fc/fc_gs.h>
4962 -#include <scsi/libfc/libfc.h>
4963 +#include <scsi/libfc.h>
4964 +#include <scsi/fc_encode.h>
4966 /* Fabric IDs to use for point-to-point mode, chosen on whims. */
4967 #define FC_LOCAL_PTP_FID_LO 0x010101
4968 @@ -124,71 +125,59 @@ static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
4972 - * fc_lport_lookup_rport - lookup a remote port by port_id
4973 - * @lport: Fibre Channel host port instance
4974 - * @port_id: remote port port_id to match
4976 -struct fc_rport *fc_lport_lookup_rport(const struct fc_lport *lport,
4979 - struct fc_rport *rport, *found;
4980 - struct fc_rport_libfc_priv *rdata;
4984 - list_for_each_entry(rdata, &lport->rports, peers) {
4985 - rport = PRIV_TO_RPORT(rdata);
4986 - if (rport->port_id == port_id) {
4988 - get_device(&found->dev);
4998 * fc_lport_rport_event - Event handler for rport events
4999 * @lport: The lport which is receiving the event
5000 * @rport: The rport which the event has occured on
5001 * @event: The event that occured
5003 * Locking Note: The rport lock should not be held when calling
5007 static void fc_lport_rport_event(struct fc_lport *lport,
5008 struct fc_rport *rport,
5009 enum fc_lport_event event)
5011 - struct fc_rport_libfc_priv *rdata = rport->dd_data;
5013 FC_DEBUG_LPORT("Received a %d event for port (%6x)\n", event,
5016 - mutex_lock(&lport->lp_mutex);
5018 - case LPORT_EV_RPORT_CREATED:
5019 + case RPORT_EV_CREATED:
5020 if (rport->port_id == FC_FID_DIR_SERV) {
5021 - lport->dns_rp = rport;
5022 - fc_lport_enter_rpn_id(lport);
5024 - list_add_tail(&rdata->peers, &lport->rports);
5026 + mutex_lock(&lport->lp_mutex);
5027 + if (lport->state == LPORT_ST_DNS) {
5028 + lport->dns_rp = rport;
5029 + fc_lport_enter_rpn_id(lport);
5031 + FC_DEBUG_LPORT("Received an CREATED event on "
5032 + "port (%6x) for the directory "
5033 + "server, but the lport is not "
5034 + "in the DNS state, it's in the "
5035 + "%d state", rport->port_id,
5037 + lport->tt.rport_logoff(rport);
5039 + mutex_unlock(&lport->lp_mutex);
5041 + FC_DEBUG_LPORT("Received an event for port (%6x) "
5042 + "which is not the directory server\n",
5045 - case LPORT_EV_RPORT_LOGO:
5046 - case LPORT_EV_RPORT_FAILED:
5047 - case LPORT_EV_RPORT_STOP:
5048 - if (rport->port_id == FC_FID_DIR_SERV)
5049 + case RPORT_EV_LOGO:
5050 + case RPORT_EV_FAILED:
5051 + case RPORT_EV_STOP:
5052 + if (rport->port_id == FC_FID_DIR_SERV) {
5053 + mutex_lock(&lport->lp_mutex);
5054 lport->dns_rp = NULL;
5056 - list_del(&rdata->peers);
5057 + mutex_unlock(&lport->lp_mutex);
5060 + FC_DEBUG_LPORT("Received an event for port (%6x) "
5061 + "which is not the directory server\n",
5064 - case LPORT_EV_RPORT_NONE:
5065 + case RPORT_EV_NONE:
5068 - mutex_unlock(&lport->lp_mutex);
5072 @@ -225,7 +214,7 @@ static void fc_lport_ptp_setup(struct fc_lport *lport,
5073 dp.ids.roles = FC_RPORT_ROLE_UNKNOWN;
5075 if (lport->ptp_rp) {
5076 - lport->tt.rport_stop(lport->ptp_rp);
5077 + lport->tt.rport_logoff(lport->ptp_rp);
5078 lport->ptp_rp = NULL;
5081 @@ -379,6 +368,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
5082 struct fc_lport *lport)
5084 struct fc_frame *fp;
5085 + struct fc_exch *ep = fc_seq_exch(sp);
5089 @@ -399,9 +389,10 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
5090 memcpy(dp, pp, len);
5091 *((u32 *)dp) = htonl(ELS_LS_ACC << 24);
5092 sp = lport->tt.seq_start_next(sp);
5093 - f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ;
5094 - fc_frame_setup(fp, FC_RCTL_ELS_REP, FC_TYPE_ELS);
5095 - lport->tt.seq_send(lport, sp, fp, f_ctl);
5096 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
5097 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
5098 + FC_TYPE_ELS, f_ctl, 0);
5099 + lport->tt.seq_send(lport, sp, fp);
5101 fc_frame_free(in_fp);
5103 @@ -419,6 +410,7 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
5104 struct fc_lport *lport)
5106 struct fc_frame *fp;
5107 + struct fc_exch *ep = fc_seq_exch(sp);
5108 struct fc_els_rnid *req;
5110 struct fc_els_rnid_resp rnid;
5111 @@ -462,9 +454,11 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
5114 sp = lport->tt.seq_start_next(sp);
5115 - f_ctl = FC_FC_SEQ_INIT | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
5116 - fc_frame_setup(fp, FC_RCTL_ELS_REP, FC_TYPE_ELS);
5117 - lport->tt.seq_send(lport, sp, fp, f_ctl);
5118 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
5119 + f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
5120 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
5121 + FC_TYPE_ELS, f_ctl, 0);
5122 + lport->tt.seq_send(lport, sp, fp);
5125 fc_frame_free(in_fp);
5126 @@ -492,7 +486,7 @@ static void fc_lport_recv_logo_req(struct fc_seq *sp, struct fc_frame *fp,
5127 * @lport: The lport that should log into the fabric
5129 * Locking Note: This function should not be called
5130 - * with the lport lock held.
5131 + * with the lport lock held.
5133 int fc_fabric_login(struct fc_lport *lport)
5135 @@ -515,6 +509,9 @@ EXPORT_SYMBOL(fc_fabric_login);
5137 void fc_linkup(struct fc_lport *lport)
5139 + FC_DEBUG_LPORT("Link is up for port (%6x)\n",
5140 + fc_host_port_id(lport->host));
5142 mutex_lock(&lport->lp_mutex);
5143 if ((lport->link_status & FC_LINK_UP) != FC_LINK_UP) {
5144 lport->link_status |= FC_LINK_UP;
5145 @@ -533,13 +530,14 @@ EXPORT_SYMBOL(fc_linkup);
5146 void fc_linkdown(struct fc_lport *lport)
5148 mutex_lock(&lport->lp_mutex);
5149 + FC_DEBUG_LPORT("Link is down for port (%6x)\n",
5150 + fc_host_port_id(lport->host));
5152 if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) {
5153 lport->link_status &= ~(FC_LINK_UP);
5154 fc_lport_enter_reset(lport);
5155 lport->tt.fcp_cleanup(lport);
5158 mutex_unlock(&lport->lp_mutex);
5160 EXPORT_SYMBOL(fc_linkdown);
5161 @@ -577,9 +575,9 @@ EXPORT_SYMBOL(fc_unpause);
5163 int fc_fabric_logoff(struct fc_lport *lport)
5165 + lport->tt.disc_stop_final(lport);
5166 mutex_lock(&lport->lp_mutex);
5167 fc_lport_enter_logo(lport);
5168 - lport->tt.fcp_cleanup(lport);
5169 mutex_unlock(&lport->lp_mutex);
5172 @@ -599,9 +597,8 @@ EXPORT_SYMBOL(fc_fabric_logoff);
5174 int fc_lport_destroy(struct fc_lport *lport)
5176 - cancel_delayed_work_sync(&lport->disc_work);
5177 - lport->tt.fcp_abort_io(lport);
5178 lport->tt.frame_send = fc_frame_drop;
5179 + lport->tt.fcp_abort_io(lport);
5180 lport->tt.exch_mgr_reset(lport->emp, 0, 0);
5183 @@ -626,10 +623,8 @@ int fc_set_mfs(struct fc_lport *lport, u32 mfs)
5187 - if (!rc && mfs < old_mfs) {
5188 - lport->disc_done = 0;
5189 + if (!rc && mfs < old_mfs)
5190 fc_lport_enter_reset(lport);
5193 mutex_unlock(&lport->lp_mutex);
5195 @@ -638,6 +633,31 @@ int fc_set_mfs(struct fc_lport *lport, u32 mfs)
5196 EXPORT_SYMBOL(fc_set_mfs);
5199 + * fc_lport_disc_callback - Callback for discovery events
5200 + * @lport: FC local port
5201 + * @event: The discovery event
5203 +void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event)
5206 + case DISC_EV_SUCCESS:
5207 + FC_DEBUG_LPORT("Got a SUCCESS event for port (%6x)\n",
5208 + fc_host_port_id(lport->host));
5210 + case DISC_EV_FAILED:
5211 + FC_DEBUG_LPORT("Got a FAILED event for port (%6x)\n",
5212 + fc_host_port_id(lport->host));
5213 + mutex_lock(&lport->lp_mutex);
5214 + fc_lport_enter_reset(lport);
5215 + mutex_unlock(&lport->lp_mutex);
5217 + case DISC_EV_NONE:
5224 * fc_rport_enter_ready - Enter the ready state and start discovery
5225 * @lport: Fibre Channel local port that is ready
5227 @@ -651,7 +671,7 @@ static void fc_lport_enter_ready(struct fc_lport *lport)
5229 fc_lport_state_enter(lport, LPORT_ST_READY);
5231 - lport->tt.disc_start(lport);
5232 + lport->tt.disc_start(fc_lport_disc_callback, lport);
5236 @@ -674,6 +694,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
5237 struct fc_frame *fp;
5238 struct fc_frame_header *fh;
5240 + struct fc_exch *ep;
5241 struct fc_els_flogi *flp;
5242 struct fc_els_flogi *new_flp;
5244 @@ -724,9 +745,11 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
5245 * Send the response. If this fails, the originator should
5246 * repeat the sequence.
5248 - f_ctl = FC_FC_LAST_SEQ | FC_FC_END_SEQ;
5249 - fc_frame_setup(fp, FC_RCTL_ELS_REP, FC_TYPE_ELS);
5250 - lport->tt.seq_send(lport, sp, fp, f_ctl);
5251 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
5252 + ep = fc_seq_exch(sp);
5253 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
5254 + FC_TYPE_ELS, f_ctl, 0);
5255 + lport->tt.seq_send(lport, sp, fp);
5258 fc_lport_error(lport, fp);
5259 @@ -734,8 +757,8 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
5260 fc_lport_ptp_setup(lport, remote_fid, remote_wwpn,
5261 get_unaligned_be64(&flp->fl_wwnn));
5263 - if (lport->tt.disc_start(lport))
5264 - FC_DBG("target discovery start error\n");
5265 + lport->tt.disc_start(fc_lport_disc_callback, lport);
5269 fc_frame_free(rx_fp);
5270 @@ -751,7 +774,7 @@ out:
5271 * if an rport should handle the request.
5273 * Locking Note: This function should not be called with the lport
5274 - * lock held becuase it will grab the lock.
5275 + * lock held becuase it will grab the lock.
5277 static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
5278 struct fc_frame *fp)
5279 @@ -808,7 +831,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
5280 s_id = ntoh24(fh->fh_s_id);
5281 d_id = ntoh24(fh->fh_d_id);
5283 - rport = fc_lport_lookup_rport(lport, s_id);
5284 + rport = lport->tt.rport_lookup(lport, s_id);
5286 lport->tt.rport_recv_req(sp, fp, rport);
5287 put_device(&rport->dev); /* hold from lookup */
5288 @@ -840,7 +863,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
5289 * @lport: The lport which should be reset
5291 * Locking Note: This functions should not be called with the
5292 - * lport lock held.
5293 + * lport lock held.
5295 int fc_lport_reset(struct fc_lport *lport)
5297 @@ -852,24 +875,6 @@ int fc_lport_reset(struct fc_lport *lport)
5298 EXPORT_SYMBOL(fc_lport_reset);
5301 - * fc_lport_stop_rports - delete all the remote ports associated with the lport
5302 - * @lport: libfc local port instance
5304 - * Locking Note: This function expects that the lport mutex is locked before
5307 -void fc_lport_stop_rports(struct fc_lport *lport)
5309 - struct fc_rport *rport;
5310 - struct fc_rport_libfc_priv *rdata;
5312 - list_for_each_entry(rdata, &lport->rports, peers) {
5313 - rport = PRIV_TO_RPORT(rdata);
5314 - lport->tt.rport_stop(rport);
5319 * fc_rport_enter_reset - Reset the local port
5320 * @lport: Fibre Channel local port to be reset
5322 @@ -883,17 +888,15 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
5324 fc_lport_state_enter(lport, LPORT_ST_RESET);
5326 - if (lport->dns_rp) {
5327 - lport->tt.rport_stop(lport->dns_rp);
5328 - lport->dns_rp = NULL;
5330 + if (lport->dns_rp)
5331 + lport->tt.rport_logoff(lport->dns_rp);
5333 if (lport->ptp_rp) {
5334 - lport->tt.rport_stop(lport->ptp_rp);
5335 + lport->tt.rport_logoff(lport->ptp_rp);
5336 lport->ptp_rp = NULL;
5339 - fc_lport_stop_rports(lport);
5340 + lport->tt.disc_stop(lport);
5342 lport->tt.exch_mgr_reset(lport->emp, 0, 0);
5343 fc_host_fabric_name(lport->host) = 0;
5344 @@ -952,7 +955,7 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
5347 * fc_lport_rft_id_resp - Handle response to Register Fibre
5348 - * Channel Types by ID (RPN_ID) request
5349 + * Channel Types by ID (RPN_ID) request
5350 * @sp: current sequence in RPN_ID exchange
5351 * @fp: response frame
5352 * @lp_arg: Fibre Channel host port instance
5353 @@ -1004,7 +1007,7 @@ err:
5356 * fc_lport_rpn_id_resp - Handle response to Register Port
5357 - * Name by ID (RPN_ID) request
5358 + * Name by ID (RPN_ID) request
5359 * @sp: current sequence in RPN_ID exchange
5360 * @fp: response frame
5361 * @lp_arg: Fibre Channel host port instance
5362 @@ -1110,32 +1113,20 @@ err:
5363 static void fc_lport_enter_scr(struct fc_lport *lport)
5365 struct fc_frame *fp;
5366 - struct fc_els_scr *scr;
5368 FC_DEBUG_LPORT("Port (%6x) entered SCR state from %s state\n",
5369 fc_host_port_id(lport->host), fc_lport_state(lport));
5371 fc_lport_state_enter(lport, LPORT_ST_SCR);
5373 - fp = fc_frame_alloc(lport, sizeof(*scr));
5374 + fp = fc_frame_alloc(lport, sizeof(struct fc_els_scr));
5376 fc_lport_error(lport, fp);
5380 - scr = fc_frame_payload_get(fp, sizeof(*scr));
5381 - memset(scr, 0, sizeof(*scr));
5382 - scr->scr_cmd = ELS_SCR;
5383 - scr->scr_reg_func = ELS_SCRF_FULL;
5384 - fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
5385 - fc_frame_set_offset(fp, 0);
5387 - if (!lport->tt.exch_seq_send(lport, fp,
5388 - fc_lport_scr_resp, NULL,
5389 - lport, lport->e_d_tov,
5390 - fc_host_port_id(lport->host),
5392 - FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5393 + if (!lport->tt.elsct_send(lport, NULL, fp, ELS_SCR,
5394 + fc_lport_scr_resp, lport, lport->e_d_tov))
5395 fc_lport_error(lport, fp);
5398 @@ -1149,11 +1140,6 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
5399 static void fc_lport_enter_rft_id(struct fc_lport *lport)
5401 struct fc_frame *fp;
5403 - struct fc_ct_hdr ct;
5404 - struct fc_ns_fid fid; /* port ID object */
5405 - struct fc_ns_fts fts; /* FC4-types object */
5407 struct fc_ns_fts *lps;
5410 @@ -1170,31 +1156,20 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport)
5412 /* nothing to register, move on to SCR */
5413 fc_lport_enter_scr(lport);
5415 - fp = fc_frame_alloc(lport, sizeof(*req));
5417 - fc_lport_error(lport, fp);
5423 - req = fc_frame_payload_get(fp, sizeof(*req));
5424 - fc_fill_dns_hdr(lport, &req->ct,
5427 - sizeof(struct fc_ct_hdr));
5428 - hton24(req->fid.fp_fid, fc_host_port_id(lport->host));
5430 - fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
5432 - if (!lport->tt.exch_seq_send(lport, fp,
5433 - fc_lport_rft_id_resp, NULL,
5434 - lport, lport->e_d_tov,
5435 - fc_host_port_id(lport->host),
5439 - fc_lport_error(lport, fp);
5440 + fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
5441 + sizeof(struct fc_ns_rft));
5443 + fc_lport_error(lport, fp);
5447 + if (!lport->tt.elsct_send(lport, NULL, fp, FC_NS_RFT_ID,
5448 + fc_lport_rft_id_resp,
5449 + lport, lport->e_d_tov))
5450 + fc_lport_error(lport, fp);
5454 @@ -1207,37 +1182,23 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport)
5455 static void fc_lport_enter_rpn_id(struct fc_lport *lport)
5457 struct fc_frame *fp;
5459 - struct fc_ct_hdr ct;
5460 - struct fc_ns_rn_id rn;
5463 FC_DEBUG_LPORT("Port (%6x) entered RPN_ID state from %s state\n",
5464 fc_host_port_id(lport->host), fc_lport_state(lport));
5466 fc_lport_state_enter(lport, LPORT_ST_RPN_ID);
5468 - fp = fc_frame_alloc(lport, sizeof(*req));
5469 + fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
5470 + sizeof(struct fc_ns_rn_id));
5472 fc_lport_error(lport, fp);
5476 - req = fc_frame_payload_get(fp, sizeof(*req));
5477 - memset(req, 0, sizeof(*req));
5478 - fc_fill_dns_hdr(lport, &req->ct, FC_NS_RPN_ID, sizeof(req->rn));
5479 - hton24(req->rn.fr_fid.fp_fid, fc_host_port_id(lport->host));
5480 - put_unaligned_be64(lport->wwpn, &req->rn.fr_wwn);
5481 - fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
5483 - if (!lport->tt.exch_seq_send(lport, fp,
5484 - fc_lport_rpn_id_resp, NULL,
5485 - lport, lport->e_d_tov,
5486 - fc_host_port_id(lport->host),
5488 - FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5489 + if (!lport->tt.elsct_send(lport, NULL, fp, FC_NS_RPN_ID,
5490 + fc_lport_rpn_id_resp,
5491 + lport, lport->e_d_tov))
5492 fc_lport_error(lport, fp);
5497 @@ -1264,16 +1225,10 @@ static void fc_lport_enter_dns(struct fc_lport *lport)
5499 fc_lport_state_enter(lport, LPORT_ST_DNS);
5501 - if (!lport->dns_rp) {
5502 - /* Set up a rogue rport to directory server */
5503 - rport = fc_rport_rogue_create(&dp);
5507 - lport->dns_rp = rport;
5509 + rport = fc_rport_rogue_create(&dp);
5513 - rport = lport->dns_rp;
5514 rdata = rport->dd_data;
5515 rdata->event_callback = fc_lport_rport_event;
5516 lport->tt.rport_login(rport);
5517 @@ -1388,10 +1343,8 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
5518 fc_lport_state_enter(lport, LPORT_ST_LOGO);
5520 /* DNS session should be closed so we can release it here */
5521 - if (lport->dns_rp) {
5522 - lport->tt.rport_logout(lport->dns_rp);
5523 - lport->dns_rp = NULL;
5525 + if (lport->dns_rp)
5526 + lport->tt.rport_logoff(lport->dns_rp);
5528 fp = fc_frame_alloc(lport, sizeof(*logo));
5530 @@ -1399,19 +1352,8 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
5534 - logo = fc_frame_payload_get(fp, sizeof(*logo));
5535 - memset(logo, 0, sizeof(*logo));
5536 - logo->fl_cmd = ELS_LOGO;
5537 - hton24(logo->fl_n_port_id, fc_host_port_id(lport->host));
5538 - logo->fl_n_port_wwn = htonll(lport->wwpn);
5539 - fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
5540 - fc_frame_set_offset(fp, 0);
5542 - if (!lport->tt.exch_seq_send(lport, fp,
5543 - fc_lport_logo_resp, NULL,
5544 - lport, lport->e_d_tov,
5545 - fc_host_port_id(lport->host), FC_FID_FLOGI,
5546 - FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5547 + if (!lport->tt.elsct_send(lport, NULL, fp, ELS_LOGO, fc_lport_logo_resp,
5548 + lport, lport->e_d_tov))
5549 fc_lport_error(lport, fp);
5552 @@ -1496,8 +1438,8 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
5554 csp_flags = ntohs(flp->fl_csp.sp_features);
5555 if ((csp_flags & FC_SP_FT_FPORT) == 0) {
5556 - if (lport->tt.disc_start(lport))
5557 - FC_DBG("Target disc start error\n");
5558 + lport->tt.disc_start(fc_lport_disc_callback,
5563 @@ -1520,29 +1462,18 @@ err:
5564 void fc_lport_enter_flogi(struct fc_lport *lport)
5566 struct fc_frame *fp;
5567 - struct fc_els_flogi *flp;
5569 FC_DEBUG_LPORT("Processing FLOGI state\n");
5571 fc_lport_state_enter(lport, LPORT_ST_FLOGI);
5573 - fp = fc_frame_alloc(lport, sizeof(*flp));
5574 + fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
5576 return fc_lport_error(lport, fp);
5578 - flp = fc_frame_payload_get(fp, sizeof(*flp));
5579 - fc_lport_flogi_fill(lport, flp, ELS_FLOGI);
5581 - fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
5582 - fc_frame_set_offset(fp, 0);
5584 - if (!lport->tt.exch_seq_send(lport, fp,
5585 - fc_lport_flogi_resp, NULL,
5586 - lport, lport->e_d_tov,
5588 - FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5589 + if (!lport->tt.elsct_send(lport, NULL, fp, ELS_FLOGI,
5590 + fc_lport_flogi_resp, lport, lport->e_d_tov))
5591 fc_lport_error(lport, fp);
5595 /* Configure a fc_lport */
5596 @@ -1550,12 +1481,9 @@ int fc_lport_config(struct fc_lport *lport)
5598 INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
5599 mutex_init(&lport->lp_mutex);
5600 - INIT_LIST_HEAD(&lport->rports);
5602 fc_lport_state_enter(lport, LPORT_ST_NONE);
5604 - lport->disc_delay = DNS_DELAY;
5606 fc_lport_add_fc4_type(lport, FC_TYPE_FCP);
5607 fc_lport_add_fc4_type(lport, FC_TYPE_CT);
5609 @@ -1571,12 +1499,6 @@ int fc_lport_init(struct fc_lport *lport)
5610 if (!lport->tt.lport_reset)
5611 lport->tt.lport_reset = fc_lport_reset;
5613 - if (!lport->tt.rport_lookup)
5614 - lport->tt.rport_lookup = fc_lport_lookup_rport;
5616 - if (!lport->tt.event_callback)
5617 - lport->tt.event_callback = fc_lport_rport_event;
5619 fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
5620 fc_host_node_name(lport->host) = lport->wwnn;
5621 fc_host_port_name(lport->host) = lport->wwpn;
5622 diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
5623 index 2d0bd85..d081af5 100644
5624 --- a/drivers/scsi/libfc/fc_rport.c
5625 +++ b/drivers/scsi/libfc/fc_rport.c
5627 * The locking strategy is similar to the lport's strategy. The lock protects
5628 * the rport's states and is held and released by the entry points to the rport
5629 * block. All _enter_* functions correspond to rport states and expect the rport
5630 - * mutex to be locked before calling them. This means that rports only handle one
5631 - * request or response at a time, since they're not critical for the I/O path
5632 - * this potential over-use of the mutex is acceptable.
5633 + * mutex to be locked before calling them. This means that rports only handle
5634 + * one request or response at a time, since they're not critical for the I/O
5635 + * path this potential over-use of the mutex is acceptable.
5638 #include <linux/kernel.h>
5640 #include <linux/workqueue.h>
5641 #include <asm/unaligned.h>
5643 -#include <scsi/libfc/libfc.h>
5644 +#include <scsi/libfc.h>
5645 +#include <scsi/fc_encode.h>
5647 static int fc_rport_debug;
5649 @@ -59,7 +60,7 @@ static int fc_rport_debug;
5653 -static struct workqueue_struct *rport_event_queue;
5654 +struct workqueue_struct *rport_event_queue;
5656 static void fc_rport_enter_plogi(struct fc_rport *);
5657 static void fc_rport_enter_prli(struct fc_rport *);
5658 @@ -122,7 +123,7 @@ struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp)
5659 rdata->local_port = dp->lp;
5660 rdata->trans_state = FC_PORTSTATE_ROGUE;
5661 rdata->rp_state = RPORT_ST_INIT;
5662 - rdata->event = LPORT_EV_RPORT_NONE;
5663 + rdata->event = RPORT_EV_NONE;
5664 rdata->flags = FC_RP_FLAGS_REC_SUPPORTED;
5665 rdata->event_callback = NULL;
5666 rdata->e_d_tov = dp->lp->e_d_tov;
5667 @@ -196,43 +197,6 @@ fc_plogi_get_maxframe(struct fc_els_flogi *flp, unsigned int maxval)
5671 - * fc_lport_plogi_fill - Fill in PLOGI command for request
5672 - * @lport: Fibre Channel host port instance
5673 - * @plogi: PLOGI command structure to fill (same structure as FLOGI)
5674 - * @op: either ELS_PLOGI for a localy generated request, or ELS_LS_ACC
5677 -fc_lport_plogi_fill(struct fc_lport *lport,
5678 - struct fc_els_flogi *plogi, unsigned int op)
5680 - struct fc_els_csp *sp;
5681 - struct fc_els_cssp *cp;
5683 - memset(plogi, 0, sizeof(*plogi));
5684 - plogi->fl_cmd = (u8) op;
5685 - put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn);
5686 - put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn);
5688 - sp = &plogi->fl_csp;
5689 - sp->sp_hi_ver = 0x20;
5690 - sp->sp_lo_ver = 0x20;
5691 - sp->sp_bb_cred = htons(10); /* this gets set by gateway */
5692 - sp->sp_bb_data = htons((u16) lport->mfs);
5693 - cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */
5694 - cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
5695 - if (op != ELS_FLOGI) {
5696 - sp->sp_features = htons(FC_SP_FT_CIRO);
5697 - sp->sp_tot_seq = htons(255); /* seq. we accept */
5698 - sp->sp_rel_off = htons(0x1f);
5699 - sp->sp_e_d_tov = htonl(lport->e_d_tov);
5701 - cp->cp_rdfs = htons((u16) lport->mfs);
5702 - cp->cp_con_seq = htons(255);
5703 - cp->cp_open_seq = 1;
5708 * fc_rport_state_enter - Change the rport's state
5709 * @rport: The rport whose state should change
5710 * @new: The new state of the rport
5711 @@ -263,7 +227,7 @@ static void fc_rport_work(struct work_struct *work)
5712 event = rdata->event;
5713 event_callback = rdata->event_callback;
5715 - if (event == LPORT_EV_RPORT_CREATED) {
5716 + if (event == RPORT_EV_CREATED) {
5717 struct fc_rport *new_rport;
5718 struct fc_rport_libfc_priv *new_rdata;
5719 struct fc_rport_identifiers ids;
5720 @@ -300,19 +264,20 @@ static void fc_rport_work(struct work_struct *work)
5722 FC_DBG("Failed to create the rport for port "
5723 "(%6x).\n", ids.port_id);
5724 - event = LPORT_EV_RPORT_FAILED;
5725 + event = RPORT_EV_FAILED;
5727 fc_rport_rogue_destroy(rport);
5729 rdata = new_rport->dd_data;
5730 - event_callback(lport, rport, event);
5731 - } else if ((event == LPORT_EV_RPORT_FAILED) ||
5732 - (event == LPORT_EV_RPORT_LOGO) ||
5733 - (event == LPORT_EV_RPORT_STOP)) {
5735 + if (event_callback)
5736 + event_callback(lport, rport, event);
5737 + } else if ((event == RPORT_EV_FAILED) ||
5738 + (event == RPORT_EV_LOGO) ||
5739 + (event == RPORT_EV_STOP)) {
5740 trans_state = rdata->trans_state;
5741 mutex_unlock(&rdata->rp_mutex);
5742 - event_callback(lport, rport, event);
5743 + if (event_callback)
5744 + event_callback(lport, rport, event);
5745 if (trans_state == FC_PORTSTATE_ROGUE)
5746 fc_rport_rogue_destroy(rport);
5748 @@ -345,45 +310,32 @@ int fc_rport_login(struct fc_rport *rport)
5752 - * fc_rport_logout - Logout of the remote port and delete it
5753 - * @rport: Fibre Channel remote port
5754 + * fc_rport_logoff - Logoff and remove an rport
5755 + * @rport: Fibre Channel remote port to be removed
5757 * Locking Note: Called without the rport lock held. This
5758 * function will hold the rport lock, call an _enter_*
5759 * function and then unlock the rport.
5761 -int fc_rport_logout(struct fc_rport *rport)
5762 +int fc_rport_logoff(struct fc_rport *rport)
5764 struct fc_rport_libfc_priv *rdata = rport->dd_data;
5766 mutex_lock(&rdata->rp_mutex);
5768 - FC_DEBUG_RPORT("Logout of port (%6x)\n", rport->port_id);
5769 + FC_DEBUG_RPORT("Remove port (%6x)\n", rport->port_id);
5771 fc_rport_enter_logo(rport);
5773 - mutex_unlock(&rdata->rp_mutex);
5779 - * fc_rport_remove - Remove an rport
5780 - * @rport: Fibre Channel remote port to be removed
5782 - * Locking Note: Called without the rport lock held. This
5783 - * function will hold the rport lock, call an _enter_*
5784 - * function and then unlock the rport.
5786 -int fc_rport_stop(struct fc_rport *rport)
5788 - struct fc_rport_libfc_priv *rdata = rport->dd_data;
5790 - mutex_lock(&rdata->rp_mutex);
5792 + * Change the state to NONE so that we discard
5795 + fc_rport_state_enter(rport, RPORT_ST_NONE);
5797 - FC_DEBUG_RPORT("Remove port (%6x)\n", rport->port_id);
5798 + cancel_delayed_work_sync(&rdata->retry_work);
5800 - rdata->event = LPORT_EV_RPORT_STOP;
5801 + rdata->event = RPORT_EV_STOP;
5802 queue_work(rport_event_queue, &rdata->event_work);
5804 mutex_unlock(&rdata->rp_mutex);
5805 @@ -406,7 +358,7 @@ static void fc_rport_enter_ready(struct fc_rport *rport)
5807 FC_DEBUG_RPORT("Port (%6x) is Ready\n", rport->port_id);
5809 - rdata->event = LPORT_EV_RPORT_CREATED;
5810 + rdata->event = RPORT_EV_CREATED;
5811 queue_work(rport_event_queue, &rdata->event_work);
5814 @@ -441,9 +393,7 @@ static void fc_rport_timeout(struct work_struct *work)
5816 case RPORT_ST_READY:
5823 put_device(&rport->dev);
5824 @@ -487,8 +437,9 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
5825 case RPORT_ST_PLOGI:
5828 - rdata->event = LPORT_EV_RPORT_FAILED;
5829 - queue_work(rport_event_queue, &rdata->event_work);
5830 + rdata->event = RPORT_EV_FAILED;
5831 + queue_work(rport_event_queue,
5832 + &rdata->event_work);
5835 fc_rport_enter_ready(rport);
5836 @@ -496,7 +447,6 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
5838 case RPORT_ST_READY:
5844 @@ -527,7 +477,8 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
5846 mutex_lock(&rdata->rp_mutex);
5848 - FC_DEBUG_RPORT("Received a PLOGI response\n");
5849 + FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n",
5852 if (rdata->rp_state != RPORT_ST_PLOGI) {
5853 FC_DBG("Received a PLOGI response, but in state %s\n",
5854 @@ -588,7 +539,6 @@ static void fc_rport_enter_plogi(struct fc_rport *rport)
5855 struct fc_rport_libfc_priv *rdata = rport->dd_data;
5856 struct fc_lport *lport = rdata->local_port;
5857 struct fc_frame *fp;
5858 - struct fc_els_flogi *plogi;
5860 FC_DEBUG_RPORT("Port (%6x) entered PLOGI state from %s state\n",
5861 rport->port_id, fc_rport_state(rport));
5862 @@ -596,23 +546,15 @@ static void fc_rport_enter_plogi(struct fc_rport *rport)
5863 fc_rport_state_enter(rport, RPORT_ST_PLOGI);
5865 rport->maxframe_size = FC_MIN_MAX_PAYLOAD;
5866 - fp = fc_frame_alloc(lport, sizeof(*plogi));
5867 + fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
5869 fc_rport_error(rport, fp);
5873 - plogi = fc_frame_payload_get(fp, sizeof(*plogi));
5874 - fc_lport_plogi_fill(rdata->local_port, plogi, ELS_PLOGI);
5875 rdata->e_d_tov = lport->e_d_tov;
5876 - fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
5878 - if (!lport->tt.exch_seq_send(lport, fp,
5879 - fc_rport_plogi_resp, NULL,
5880 - rport, lport->e_d_tov,
5881 - fc_host_port_id(rdata->local_port->host),
5883 - FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5885 + if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI,
5886 + fc_rport_plogi_resp, rport, lport->e_d_tov))
5887 fc_rport_error(rport, fp);
5890 @@ -641,7 +583,8 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
5892 mutex_lock(&rdata->rp_mutex);
5894 - FC_DEBUG_RPORT("Received a PRLI response\n");
5895 + FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n",
5898 if (rdata->rp_state != RPORT_ST_PRLI) {
5899 FC_DBG("Received a PRLI response, but in state %s\n",
5900 @@ -674,7 +617,7 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
5903 FC_DBG("Bad ELS response\n");
5904 - rdata->event = LPORT_EV_RPORT_FAILED;
5905 + rdata->event = RPORT_EV_FAILED;
5906 queue_work(rport_event_queue, &rdata->event_work);
5909 @@ -703,25 +646,26 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
5911 mutex_lock(&rdata->rp_mutex);
5913 - FC_DEBUG_RPORT("Received a LOGO response\n");
5915 - if (rdata->rp_state != RPORT_ST_LOGO) {
5916 - FC_DBG("Received a LOGO response, but in state %s\n",
5917 - fc_rport_state(rport));
5920 + FC_DEBUG_RPORT("Received a LOGO response from port (%6x)\n",
5924 fc_rport_error(rport, fp);
5928 + if (rdata->rp_state != RPORT_ST_LOGO) {
5929 + FC_DEBUG_RPORT("Received a LOGO response, but in state %s\n",
5930 + fc_rport_state(rport));
5934 op = fc_frame_payload_op(fp);
5935 if (op == ELS_LS_ACC) {
5936 fc_rport_enter_rtv(rport);
5938 FC_DBG("Bad ELS response\n");
5939 - rdata->event = LPORT_EV_RPORT_LOGO;
5940 + rdata->event = RPORT_EV_LOGO;
5941 queue_work(rport_event_queue, &rdata->event_work);
5944 @@ -759,22 +703,8 @@ static void fc_rport_enter_prli(struct fc_rport *rport)
5948 - pp = fc_frame_payload_get(fp, sizeof(*pp));
5949 - memset(pp, 0, sizeof(*pp));
5950 - pp->prli.prli_cmd = ELS_PRLI;
5951 - pp->prli.prli_spp_len = sizeof(struct fc_els_spp);
5952 - pp->prli.prli_len = htons(sizeof(*pp));
5953 - pp->spp.spp_type = FC_TYPE_FCP;
5954 - pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR;
5955 - pp->spp.spp_params = htonl(lport->service_params);
5956 - fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
5958 - if (!lport->tt.exch_seq_send(lport, fp,
5959 - fc_rport_prli_resp, NULL,
5960 - rport, lport->e_d_tov,
5961 - fc_host_port_id(lport->host),
5963 - FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5964 + if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI,
5965 + fc_rport_prli_resp, rport, lport->e_d_tov))
5966 fc_rport_error(rport, fp);
5969 @@ -799,7 +729,8 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
5971 mutex_lock(&rdata->rp_mutex);
5973 - FC_DEBUG_RPORT("Received a RTV response\n");
5974 + FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n",
5977 if (rdata->rp_state != RPORT_ST_RTV) {
5978 FC_DBG("Received a RTV response, but in state %s\n",
5979 @@ -851,7 +782,6 @@ err:
5981 static void fc_rport_enter_rtv(struct fc_rport *rport)
5983 - struct fc_els_rtv *rtv;
5984 struct fc_frame *fp;
5985 struct fc_rport_libfc_priv *rdata = rport->dd_data;
5986 struct fc_lport *lport = rdata->local_port;
5987 @@ -861,23 +791,14 @@ static void fc_rport_enter_rtv(struct fc_rport *rport)
5989 fc_rport_state_enter(rport, RPORT_ST_RTV);
5991 - fp = fc_frame_alloc(lport, sizeof(*rtv));
5992 + fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv));
5994 fc_rport_error(rport, fp);
5998 - rtv = fc_frame_payload_get(fp, sizeof(*rtv));
5999 - memset(rtv, 0, sizeof(*rtv));
6000 - rtv->rtv_cmd = ELS_RTV;
6001 - fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
6003 - if (!lport->tt.exch_seq_send(lport, fp,
6004 - fc_rport_rtv_resp, NULL,
6005 - rport, lport->e_d_tov,
6006 - fc_host_port_id(lport->host),
6008 - FC_FC_SEQ_INIT | FC_FC_END_SEQ))
6009 + if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV,
6010 + fc_rport_rtv_resp, rport, lport->e_d_tov))
6011 fc_rport_error(rport, fp);
6014 @@ -893,32 +814,20 @@ static void fc_rport_enter_logo(struct fc_rport *rport)
6015 struct fc_rport_libfc_priv *rdata = rport->dd_data;
6016 struct fc_lport *lport = rdata->local_port;
6017 struct fc_frame *fp;
6018 - struct fc_els_logo *logo;
6020 FC_DEBUG_RPORT("Port (%6x) entered LOGO state from %s state\n",
6021 rport->port_id, fc_rport_state(rport));
6023 fc_rport_state_enter(rport, RPORT_ST_LOGO);
6025 - fp = fc_frame_alloc(lport, sizeof(*logo));
6026 + fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo));
6028 fc_rport_error(rport, fp);
6032 - logo = fc_frame_payload_get(fp, sizeof(*logo));
6033 - memset(logo, 0, sizeof(*logo));
6034 - logo->fl_cmd = ELS_LOGO;
6035 - hton24(logo->fl_n_port_id, fc_host_port_id(lport->host));
6036 - logo->fl_n_port_wwn = htonll(lport->wwpn);
6037 - fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
6039 - if (!lport->tt.exch_seq_send(lport, fp,
6040 - fc_rport_logo_resp, NULL,
6041 - rport, lport->e_d_tov,
6042 - fc_host_port_id(lport->host),
6044 - FC_FC_SEQ_INIT | FC_FC_END_SEQ))
6045 + if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO,
6046 + fc_rport_logo_resp, rport, lport->e_d_tov))
6047 fc_rport_error(rport, fp);
6050 @@ -982,7 +891,6 @@ void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp,
6053 mutex_unlock(&rdata->rp_mutex);
6054 - fc_frame_free(fp);
6058 @@ -1000,7 +908,7 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport,
6059 struct fc_rport_libfc_priv *rdata = rport->dd_data;
6060 struct fc_lport *lport = rdata->local_port;
6061 struct fc_frame *fp = rx_fp;
6063 + struct fc_exch *ep;
6064 struct fc_frame_header *fh;
6065 struct fc_els_flogi *pl;
6066 struct fc_seq_els_data rjt_data;
6067 @@ -1089,17 +997,18 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport,
6068 rport->maxframe_size =
6069 fc_plogi_get_maxframe(pl, lport->mfs);
6070 fc_frame_free(rx_fp);
6071 - pl = fc_frame_payload_get(fp, sizeof(*pl));
6073 - fc_lport_plogi_fill(lport, pl, ELS_LS_ACC);
6074 + fc_plogi_fill(lport, fp, ELS_LS_ACC);
6077 * Send LS_ACC. If this fails,
6078 * the originator should retry.
6080 - f_ctl = FC_FC_SEQ_INIT | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
6081 - fc_frame_setup(fp, FC_RCTL_ELS_REP, FC_TYPE_ELS);
6082 - lport->tt.seq_send(lport, sp, fp, f_ctl);
6083 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
6084 + f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
6085 + ep = fc_seq_exch(sp);
6086 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
6087 + FC_TYPE_ELS, f_ctl, 0);
6088 + lport->tt.seq_send(lport, sp, fp);
6089 if (rdata->rp_state == RPORT_ST_PLOGI)
6090 fc_rport_enter_prli(rport);
6092 @@ -1120,7 +1029,7 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
6094 struct fc_rport_libfc_priv *rdata = rport->dd_data;
6095 struct fc_lport *lport = rdata->local_port;
6097 + struct fc_exch *ep;
6098 struct fc_frame *fp;
6099 struct fc_frame_header *fh;
6101 @@ -1234,9 +1143,12 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
6103 * Send LS_ACC. If this fails, the originator should retry.
6105 - f_ctl = FC_FC_SEQ_INIT | FC_FC_LAST_SEQ | FC_FC_END_SEQ;
6106 - fc_frame_setup(fp, FC_RCTL_ELS_REP, FC_TYPE_ELS);
6107 - lport->tt.seq_send(lport, sp, fp, f_ctl);
6108 + f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
6109 + f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
6110 + ep = fc_seq_exch(sp);
6111 + fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
6112 + FC_TYPE_ELS, f_ctl, 0);
6113 + lport->tt.seq_send(lport, sp, fp);
6116 * Get lock and re-check state.
6117 @@ -1307,27 +1219,33 @@ static void fc_rport_recv_logo_req(struct fc_rport *rport, struct fc_seq *sp,
6118 "while in state %s\n", ntoh24(fh->fh_s_id),
6119 fc_rport_state(rport));
6121 - rdata->event = LPORT_EV_RPORT_LOGO;
6122 + rdata->event = RPORT_EV_LOGO;
6123 queue_work(rport_event_queue, &rdata->event_work);
6125 lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
6129 +static void fc_rport_flush_queue(void)
6131 + flush_workqueue(rport_event_queue);
6135 int fc_rport_init(struct fc_lport *lport)
6137 if (!lport->tt.rport_login)
6138 lport->tt.rport_login = fc_rport_login;
6140 - if (!lport->tt.rport_logout)
6141 - lport->tt.rport_logout = fc_rport_logout;
6143 - if (!lport->tt.rport_stop)
6144 - lport->tt.rport_stop = fc_rport_stop;
6145 + if (!lport->tt.rport_logoff)
6146 + lport->tt.rport_logoff = fc_rport_logoff;
6148 if (!lport->tt.rport_recv_req)
6149 lport->tt.rport_recv_req = fc_rport_recv_req;
6151 + if (!lport->tt.rport_flush_queue)
6152 + lport->tt.rport_flush_queue = fc_rport_flush_queue;
6156 EXPORT_SYMBOL(fc_rport_init);
6157 diff --git a/include/scsi/fc/fc_fcoe.h b/include/scsi/fc/fc_fcoe.h
6158 index 59c9d0c..a6118a2 100644
6159 --- a/include/scsi/fc/fc_fcoe.h
6160 +++ b/include/scsi/fc/fc_fcoe.h
6162 #define ETH_P_FCOE 0x8906 /* FCOE ether type */
6165 +#ifndef ETH_P_8021Q
6166 +#define ETH_P_8021Q 0x8100
6170 * FC_FCOE_OUI hasn't been standardized yet. XXX TBD.
6172 @@ -81,7 +85,9 @@ struct fcoe_crc_eof {
6173 } __attribute__((packed));
6176 - * Store OUI + DID into MAC address field.
6177 + * fc_fcoe_set_mac - Store OUI + DID into MAC address field.
6178 + * @mac: mac address to be set
6179 + * @did: fc dest id to use
6181 static inline void fc_fcoe_set_mac(u8 *mac, u8 *did)
6183 @@ -93,8 +99,4 @@ static inline void fc_fcoe_set_mac(u8 *mac, u8 *did)
6187 -#ifndef ETH_P_8021Q
6188 -#define ETH_P_8021Q 0x8100
6191 #endif /* _FC_FCOE_H_ */
6192 diff --git a/include/scsi/fc/fc_fs.h b/include/scsi/fc/fc_fs.h
6193 index 3897c6c..3e4801d 100644
6194 --- a/include/scsi/fc/fc_fs.h
6195 +++ b/include/scsi/fc/fc_fs.h
6196 @@ -82,6 +82,12 @@ enum fc_rctl {
6197 FC_RCTL_ELS4_REQ = 0x32, /* FC-4 ELS request */
6198 FC_RCTL_ELS4_REP = 0x33, /* FC-4 ELS reply */
6200 + * Optional Extended Headers
6202 + FC_RCTL_VFTH = 0x50, /* virtual fabric tagging header */
6203 + FC_RCTL_IFRH = 0x51, /* inter-fabric routing header */
6204 + FC_RCTL_ENCH = 0x52, /* encapsulation header */
6206 * Basic Link Services fh_r_ctl values.
6208 FC_RCTL_BA_NOP = 0x80, /* basic link service NOP */
6209 @@ -200,6 +206,8 @@ enum fc_fh_type {
6212 #define FC_XID_UNKNOWN 0xffff /* unknown exchange ID */
6213 +#define FC_XID_MIN 0x0 /* supported min exchange ID */
6214 +#define FC_XID_MAX 0xfffe /* supported max exchange ID */
6217 * fh_f_ctl - Frame control flags.
6218 diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
6219 new file mode 100644
6220 index 0000000..6300f55
6222 +++ b/include/scsi/fc_encode.h
6225 + * Copyright(c) 2008 Intel Corporation. All rights reserved.
6227 + * This program is free software; you can redistribute it and/or modify it
6228 + * under the terms and conditions of the GNU General Public License,
6229 + * version 2, as published by the Free Software Foundation.
6231 + * This program is distributed in the hope it will be useful, but WITHOUT
6232 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6233 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
6236 + * You should have received a copy of the GNU General Public License along with
6237 + * this program; if not, write to the Free Software Foundation, Inc.,
6238 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
6240 + * Maintained at www.Open-FCoE.org
6243 +#ifndef _FC_ENCODE_H_
6244 +#define _FC_ENCODE_H_
6245 +#include <asm/unaligned.h>
6248 + struct fc_ns_fid fid; /* port ID object */
6249 + struct fc_ns_fts fts; /* FC4-types object */
6253 + struct fc_ct_hdr hdr;
6255 + struct fc_ns_gid_ft gid;
6256 + struct fc_ns_rn_id rn;
6257 + struct fc_ns_rft rft;
6262 + * fill FC header fields in specified fc_frame
6264 +static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
6265 + u32 did, u32 sid, enum fc_fh_type type,
6266 + u32 f_ctl, u32 parm_offset)
6268 + struct fc_frame_header *fh;
6270 + fh = fc_frame_header_get(fp);
6271 + WARN_ON(r_ctl == 0);
6272 + fh->fh_r_ctl = r_ctl;
6273 + hton24(fh->fh_d_id, did);
6274 + hton24(fh->fh_s_id, sid);
6275 + fh->fh_type = type;
6276 + hton24(fh->fh_f_ctl, f_ctl);
6277 + fh->fh_cs_ctl = 0;
6278 + fh->fh_df_ctl = 0;
6279 + fh->fh_parm_offset = htonl(parm_offset);
6283 + * fc_ct_hdr_fill- fills ct header and reset ct payload
6284 + * returns pointer to ct request.
6286 +static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
6287 + unsigned int op, size_t req_size)
6289 + struct fc_ct_req *ct;
6292 + ct_plen = sizeof(struct fc_ct_hdr) + req_size;
6293 + ct = fc_frame_payload_get(fp, ct_plen);
6294 + memset(ct, 0, ct_plen);
6295 + ct->hdr.ct_rev = FC_CT_REV;
6296 + ct->hdr.ct_fs_type = FC_FST_DIR;
6297 + ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE;
6298 + ct->hdr.ct_cmd = htons((u16) op);
6303 + * fc_ct_fill - Fill in a name service request frame
6305 +static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
6306 + unsigned int op, enum fc_rctl *r_ctl, u32 *did,
6307 + enum fc_fh_type *fh_type)
6309 + struct fc_ct_req *ct;
6312 + case FC_NS_GPN_FT:
6313 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft));
6314 + ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
6317 + case FC_NS_RFT_ID:
6318 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft));
6319 + hton24(ct->payload.rft.fid.fp_fid,
6320 + fc_host_port_id(lport->host));
6321 + ct->payload.rft.fts = lport->fcts;
6324 + case FC_NS_RPN_ID:
6325 + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id));
6326 + hton24(ct->payload.rn.fr_fid.fp_fid,
6327 + fc_host_port_id(lport->host));
6328 + ct->payload.rft.fts = lport->fcts;
6329 + put_unaligned_be64(lport->wwpn, &ct->payload.rn.fr_wwn);
6333 + FC_DBG("Invalid op code %x \n", op);
6336 + *r_ctl = FC_RCTL_DD_UNSOL_CTL;
6337 + *did = FC_FID_DIR_SERV;
6338 + *fh_type = FC_TYPE_CT;
6343 + * fc_plogi_fill - Fill in plogi request frame
6345 +static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,
6348 + struct fc_els_flogi *plogi;
6349 + struct fc_els_csp *csp;
6350 + struct fc_els_cssp *cp;
6352 + plogi = fc_frame_payload_get(fp, sizeof(*plogi));
6353 + memset(plogi, 0, sizeof(*plogi));
6354 + plogi->fl_cmd = (u8) op;
6355 + put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn);
6356 + put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn);
6358 + csp = &plogi->fl_csp;
6359 + csp->sp_hi_ver = 0x20;
6360 + csp->sp_lo_ver = 0x20;
6361 + csp->sp_bb_cred = htons(10); /* this gets set by gateway */
6362 + csp->sp_bb_data = htons((u16) lport->mfs);
6363 + cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */
6364 + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
6365 + csp->sp_features = htons(FC_SP_FT_CIRO);
6366 + csp->sp_tot_seq = htons(255); /* seq. we accept */
6367 + csp->sp_rel_off = htons(0x1f);
6368 + csp->sp_e_d_tov = htonl(lport->e_d_tov);
6370 + cp->cp_rdfs = htons((u16) lport->mfs);
6371 + cp->cp_con_seq = htons(255);
6372 + cp->cp_open_seq = 1;
6376 + * fc_flogi_fill - Fill in a flogi request frame.
6378 +static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp)
6380 + struct fc_els_csp *sp;
6381 + struct fc_els_cssp *cp;
6382 + struct fc_els_flogi *flogi;
6384 + flogi = fc_frame_payload_get(fp, sizeof(*flogi));
6385 + memset(flogi, 0, sizeof(*flogi));
6386 + flogi->fl_cmd = (u8) ELS_FLOGI;
6387 + put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
6388 + put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
6389 + sp = &flogi->fl_csp;
6390 + sp->sp_hi_ver = 0x20;
6391 + sp->sp_lo_ver = 0x20;
6392 + sp->sp_bb_cred = htons(10); /* this gets set by gateway */
6393 + sp->sp_bb_data = htons((u16) lport->mfs);
6394 + cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */
6395 + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
6399 + * fc_logo_fill - Fill in a logo request frame.
6401 +static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp)
6403 + struct fc_els_logo *logo;
6405 + logo = fc_frame_payload_get(fp, sizeof(*logo));
6406 + memset(logo, 0, sizeof(*logo));
6407 + logo->fl_cmd = ELS_LOGO;
6408 + hton24(logo->fl_n_port_id, fc_host_port_id(lport->host));
6409 + logo->fl_n_port_wwn = htonll(lport->wwpn);
6413 + * fc_rtv_fill - Fill in RTV (read timeout value) request frame.
6415 +static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp)
6417 + struct fc_els_rtv *rtv;
6419 + rtv = fc_frame_payload_get(fp, sizeof(*rtv));
6420 + memset(rtv, 0, sizeof(*rtv));
6421 + rtv->rtv_cmd = ELS_RTV;
6425 + * fc_rec_fill - Fill in rec request frame
6427 +static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp)
6429 + struct fc_els_rec *rec;
6430 + struct fc_exch *ep = fc_seq_exch(fr_seq(fp));
6432 + rec = fc_frame_payload_get(fp, sizeof(*rec));
6433 + memset(rec, 0, sizeof(*rec));
6434 + rec->rec_cmd = ELS_REC;
6435 + hton24(rec->rec_s_id, fc_host_port_id(lport->host));
6436 + rec->rec_ox_id = htons(ep->oxid);
6437 + rec->rec_rx_id = htons(ep->rxid);
6441 + * fc_prli_fill - Fill in prli request frame
6443 +static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp)
6446 + struct fc_els_prli prli;
6447 + struct fc_els_spp spp;
6450 + pp = fc_frame_payload_get(fp, sizeof(*pp));
6451 + memset(pp, 0, sizeof(*pp));
6452 + pp->prli.prli_cmd = ELS_PRLI;
6453 + pp->prli.prli_spp_len = sizeof(struct fc_els_spp);
6454 + pp->prli.prli_len = htons(sizeof(*pp));
6455 + pp->spp.spp_type = FC_TYPE_FCP;
6456 + pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR;
6457 + pp->spp.spp_params = htonl(lport->service_params);
6461 + * fc_scr_fill - Fill in a scr request frame.
6463 +static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
6465 + struct fc_els_scr *scr;
6467 + scr = fc_frame_payload_get(fp, sizeof(*scr));
6468 + memset(scr, 0, sizeof(*scr));
6469 + scr->scr_cmd = ELS_SCR;
6470 + scr->scr_reg_func = ELS_SCRF_FULL;
6474 + * fc_els_fill - Fill in an ELS request frame
6476 +static inline int fc_els_fill(struct fc_lport *lport, struct fc_rport *rport,
6477 + struct fc_frame *fp, unsigned int op,
6478 + enum fc_rctl *r_ctl, u32 *did, enum fc_fh_type *fh_type)
6482 + fc_plogi_fill(lport, fp, ELS_PLOGI);
6483 + *did = rport->port_id;
6487 + fc_flogi_fill(lport, fp);
6488 + *did = FC_FID_FLOGI;
6492 + fc_logo_fill(lport, fp);
6493 + *did = FC_FID_FLOGI;
6495 + * if rport is valid then it
6496 + * is port logo, therefore
6497 + * set did to rport id.
6500 + *did = rport->port_id;
6504 + fc_rtv_fill(lport, fp);
6505 + *did = rport->port_id;
6509 + fc_rec_fill(lport, fp);
6510 + *did = rport->port_id;
6514 + fc_prli_fill(lport, fp);
6515 + *did = rport->port_id;
6519 + fc_scr_fill(lport, fp);
6520 + *did = FC_FID_FCTRL;
6524 + FC_DBG("Invalid op code %x \n", op);
6528 + *r_ctl = FC_RCTL_ELS_REQ;
6529 + *fh_type = FC_TYPE_ELS;
6532 +#endif /* _FC_ENCODE_H_ */
6533 diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
6534 new file mode 100644
6535 index 0000000..dc5f734
6537 +++ b/include/scsi/fc_frame.h
6540 + * Copyright(c) 2007 Intel Corporation. All rights reserved.
6542 + * This program is free software; you can redistribute it and/or modify it
6543 + * under the terms and conditions of the GNU General Public License,
6544 + * version 2, as published by the Free Software Foundation.
6546 + * This program is distributed in the hope it will be useful, but WITHOUT
6547 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6548 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
6551 + * You should have received a copy of the GNU General Public License along with
6552 + * this program; if not, write to the Free Software Foundation, Inc.,
6553 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
6555 + * Maintained at www.Open-FCoE.org
6558 +#ifndef _FC_FRAME_H_
6559 +#define _FC_FRAME_H_
6561 +#include <linux/scatterlist.h>
6562 +#include <linux/skbuff.h>
6563 +#include <scsi/scsi_cmnd.h>
6565 +#include <scsi/fc/fc_fs.h>
6566 +#include <scsi/fc/fc_fcp.h>
6567 +#include <scsi/fc/fc_encaps.h>
6570 + * The fc_frame interface is used to pass frame data between functions.
6571 + * The frame includes the data buffer, length, and SOF / EOF delimiter types.
6572 + * A pointer to the port structure of the receiving port is also includeded.
6575 +#define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */
6576 +#define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */
6579 + * Information about an individual fibre channel frame received or to be sent.
6580 + * The buffer may be in up to 4 additional non-contiguous sections,
6581 + * but the linear section must hold the frame header.
6583 +#define FC_FRAME_SG_LEN 4 /* scatter/gather list maximum length */
6585 +#define fp_skb(fp) (&((fp)->skb))
6586 +#define fr_hdr(fp) ((fp)->skb.data)
6587 +#define fr_len(fp) ((fp)->skb.len)
6588 +#define fr_cb(fp) ((struct fcoe_rcv_info *)&((fp)->skb.cb[0]))
6589 +#define fr_dev(fp) (fr_cb(fp)->fr_dev)
6590 +#define fr_seq(fp) (fr_cb(fp)->fr_seq)
6591 +#define fr_sof(fp) (fr_cb(fp)->fr_sof)
6592 +#define fr_eof(fp) (fr_cb(fp)->fr_eof)
6593 +#define fr_flags(fp) (fr_cb(fp)->fr_flags)
6594 +#define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload)
6595 +#define fr_cmd(fp) (fr_cb(fp)->fr_cmd)
6596 +#define fr_dir(fp) (fr_cmd(fp)->sc_data_direction)
6599 + struct sk_buff skb;
6602 +struct fcoe_rcv_info {
6603 + struct packet_type *ptype;
6604 + struct fc_lport *fr_dev; /* transport layer private pointer */
6605 + struct fc_seq *fr_seq; /* for use with exchange manager */
6606 + struct scsi_cmnd *fr_cmd; /* for use of scsi command */
6607 + enum fc_sof fr_sof; /* start of frame delimiter */
6608 + enum fc_eof fr_eof; /* end of frame delimiter */
6609 + u8 fr_flags; /* flags - see below */
6610 + u16 fr_max_payload; /* max FC payload */
6614 + * Get fc_frame pointer for an skb that's already been imported.
6616 +static inline struct fcoe_rcv_info *fcoe_dev_from_skb(const struct sk_buff *skb)
6618 + BUILD_BUG_ON(sizeof(struct fcoe_rcv_info) > sizeof(skb->cb));
6619 + return (struct fcoe_rcv_info *) skb->cb;
6625 +#define FCPHF_CRC_UNCHECKED 0x01 /* CRC not computed, still appended */
6628 + * Initialize a frame.
6629 + * We don't do a complete memset here for performance reasons.
6630 + * The caller must set fr_free, fr_hdr, fr_len, fr_sof, and fr_eof eventually.
6632 +static inline void fc_frame_init(struct fc_frame *fp)
6634 + fr_dev(fp) = NULL;
6635 + fr_seq(fp) = NULL;
6639 +struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len);
6641 +struct fc_frame *__fc_frame_alloc(size_t payload_len);
6644 + * Get frame for sending via port.
6646 +static inline struct fc_frame *_fc_frame_alloc(struct fc_lport *dev,
6647 + size_t payload_len)
6649 + return __fc_frame_alloc(payload_len);
6653 + * Allocate fc_frame structure and buffer. Set the initial length to
6654 + * payload_size + sizeof (struct fc_frame_header).
6656 +static inline struct fc_frame *fc_frame_alloc(struct fc_lport *dev, size_t len)
6658 + struct fc_frame *fp;
6661 + * Note: Since len will often be a constant multiple of 4,
6662 + * this check will usually be evaluated and eliminated at compile time.
6664 + if ((len % 4) != 0)
6665 + fp = fc_frame_alloc_fill(dev, len);
6667 + fp = _fc_frame_alloc(dev, len);
6672 + * Free the fc_frame structure and buffer.
6674 +static inline void fc_frame_free(struct fc_frame *fp)
6676 + kfree_skb(fp_skb(fp));
6679 +static inline int fc_frame_is_linear(struct fc_frame *fp)
6681 + return !skb_is_nonlinear(fp_skb(fp));
6685 + * Get frame header from message in fc_frame structure.
6686 + * This hides a cast and provides a place to add some checking.
6689 +struct fc_frame_header *fc_frame_header_get(const struct fc_frame *fp)
6691 + WARN_ON(fr_len(fp) < sizeof(struct fc_frame_header));
6692 + return (struct fc_frame_header *) fr_hdr(fp);
6696 + * Get frame payload from message in fc_frame structure.
6697 + * This hides a cast and provides a place to add some checking.
6698 + * The len parameter is the minimum length for the payload portion.
6699 + * Returns NULL if the frame is too short.
6701 + * This assumes the interesting part of the payload is in the first part
6702 + * of the buffer for received data. This may not be appropriate to use for
6703 + * buffers being transmitted.
6705 +static inline void *fc_frame_payload_get(const struct fc_frame *fp,
6710 + if (fr_len(fp) >= sizeof(struct fc_frame_header) + len)
6711 + pp = fc_frame_header_get(fp) + 1;
6716 + * Get frame payload opcode (first byte) from message in fc_frame structure.
6717 + * This hides a cast and provides a place to add some checking. Return 0
6718 + * if the frame has no payload.
6720 +static inline u8 fc_frame_payload_op(const struct fc_frame *fp)
6724 + cp = fc_frame_payload_get(fp, sizeof(u8));
6732 + * Get FC class from frame.
6734 +static inline enum fc_class fc_frame_class(const struct fc_frame *fp)
6736 + return fc_sof_class(fr_sof(fp));
6740 + * Check the CRC in a frame.
6741 + * The CRC immediately follows the last data item *AFTER* the length.
6742 + * The return value is zero if the CRC matches.
6744 +u32 fc_frame_crc_check(struct fc_frame *);
6746 +static inline u8 fc_frame_rctl(const struct fc_frame *fp)
6748 + return fc_frame_header_get(fp)->fh_r_ctl;
6751 +static inline bool fc_frame_is_cmd(const struct fc_frame *fp)
6753 + return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD;
6756 +static inline bool fc_frame_is_read(const struct fc_frame *fp)
6758 + if (fc_frame_is_cmd(fp) && fr_cmd(fp))
6759 + return fr_dir(fp) == DMA_FROM_DEVICE;
6763 +static inline bool fc_frame_is_write(const struct fc_frame *fp)
6765 + if (fc_frame_is_cmd(fp) && fr_cmd(fp))
6766 + return fr_dir(fp) == DMA_TO_DEVICE;
6771 + * Check for leaks.
6772 + * Print the frame header of any currently allocated frame, assuming there
6773 + * should be none at this point.
6775 +void fc_frame_leak_check(void);
6777 +#endif /* _FC_FRAME_H_ */
6778 diff --git a/include/scsi/fc_transport_fcoe.h b/include/scsi/fc_transport_fcoe.h
6779 new file mode 100644
6780 index 0000000..8dca2af
6782 +++ b/include/scsi/fc_transport_fcoe.h
6784 +#ifndef FC_TRANSPORT_FCOE_H
6785 +#define FC_TRANSPORT_FCOE_H
6787 +#include <linux/device.h>
6788 +#include <linux/netdevice.h>
6789 +#include <scsi/scsi_host.h>
6790 +#include <scsi/libfc.h>
6793 + * struct fcoe_transport - FCoE transport struct for generic transport
6794 + * for Ethernet devices as well as pure HBAs
6796 + * @name: name for thsi transport
6797 + * @bus: physical bus type (pci_bus_type)
6798 + * @driver: physical bus driver for network device
6799 + * @create: entry create function
6800 + * @destroy: exit destroy function
6801 + * @list: list of transports
6803 +struct fcoe_transport {
6805 + unsigned short vendor;
6806 + unsigned short device;
6807 + struct bus_type *bus;
6808 + struct device_driver *driver;
6809 + int (*create)(struct net_device *device);
6810 + int (*destroy)(struct net_device *device);
6811 + bool (*match)(struct net_device *device);
6812 + struct list_head list;
6813 + struct list_head devlist;
6814 + struct mutex devlock;
6818 + * MODULE_ALIAS_FCOE_PCI
6820 + * some care must be taken with this, vendor and device MUST be a hex value
6821 + * preceded with 0x and with letters in lower case (0x12ab, not 0x12AB or 12AB)
6823 +#define MODULE_ALIAS_FCOE_PCI(vendor, device) \
6824 + MODULE_ALIAS("fcoe-pci-" __stringify(vendor) "-" __stringify(device))
6826 +/* exported funcs */
6827 +int fcoe_transport_attach(struct net_device *netdev);
6828 +int fcoe_transport_release(struct net_device *netdev);
6829 +int fcoe_transport_register(struct fcoe_transport *t);
6830 +int fcoe_transport_unregister(struct fcoe_transport *t);
6831 +int fcoe_load_transport_driver(struct net_device *netdev);
6832 +int __init fcoe_transport_init(void);
6833 +int __exit fcoe_transport_exit(void);
6835 +/* fcow_sw is the default transport */
6836 +extern struct fcoe_transport fcoe_sw_transport;
6837 +#endif /* FC_TRANSPORT_FCOE_H */
6838 diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
6839 new file mode 100644
6840 index 0000000..dac03e2
6842 +++ b/include/scsi/libfc.h
6845 + * Copyright(c) 2007 Intel Corporation. All rights reserved.
6847 + * This program is free software; you can redistribute it and/or modify it
6848 + * under the terms and conditions of the GNU General Public License,
6849 + * version 2, as published by the Free Software Foundation.
6851 + * This program is distributed in the hope it will be useful, but WITHOUT
6852 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6853 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
6856 + * You should have received a copy of the GNU General Public License along with
6857 + * this program; if not, write to the Free Software Foundation, Inc.,
6858 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
6860 + * Maintained at www.Open-FCoE.org
6866 +#include <linux/timer.h>
6867 +#include <linux/if.h>
6869 +#include <scsi/scsi_transport.h>
6870 +#include <scsi/scsi_transport_fc.h>
6872 +#include <scsi/fc/fc_fcp.h>
6873 +#include <scsi/fc/fc_ns.h>
6874 +#include <scsi/fc/fc_els.h>
6875 +#include <scsi/fc/fc_gs.h>
6877 +#include <scsi/fc_frame.h>
6879 +#define LIBFC_DEBUG
6883 +#define FC_DBG(fmt, args...) \
6885 + printk(KERN_INFO "%s " fmt, __func__, ##args); \
6888 +#define FC_DBG(fmt, args...)
6892 + * libfc error codes
6894 +#define FC_NO_ERR 0 /* no error */
6895 +#define FC_EX_TIMEOUT 1 /* Exchange timeout */
6896 +#define FC_EX_CLOSED 2 /* Exchange closed */
6898 +/* some helpful macros */
6900 +#define ntohll(x) be64_to_cpu(x)
6901 +#define htonll(x) cpu_to_be64(x)
6903 +#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
6905 +#define hton24(p, v) do { \
6906 + p[0] = (((v) >> 16) & 0xFF); \
6907 + p[1] = (((v) >> 8) & 0xFF); \
6908 + p[2] = ((v) & 0xFF); \
6914 +#define FC_PAUSE (1 << 1)
6915 +#define FC_LINK_UP (1 << 0)
6917 +enum fc_lport_state {
6918 + LPORT_ST_NONE = 0,
6929 +enum fc_disc_event {
6935 +enum fc_lport_event {
6936 + RPORT_EV_NONE = 0,
6943 +enum fc_rport_state {
6944 + RPORT_ST_NONE = 0,
6945 + RPORT_ST_INIT, /* initialized */
6946 + RPORT_ST_PLOGI, /* waiting for PLOGI completion */
6947 + RPORT_ST_PRLI, /* waiting for PRLI completion */
6948 + RPORT_ST_RTV, /* waiting for RTV completion */
6949 + RPORT_ST_READY, /* ready for use */
6950 + RPORT_ST_LOGO, /* port logout sent */
6953 +enum fc_rport_trans_state {
6954 + FC_PORTSTATE_ROGUE,
6955 + FC_PORTSTATE_REAL,
6959 + * struct fc_disc_port - temporary discovery port to hold rport identifiers
6960 + * @lp: Fibre Channel host port instance
6961 + * @peers: node for list management during discovery and RSCN processing
6962 + * @ids: identifiers structure to pass to fc_remote_port_add()
6963 + * @rport_work: work struct for starting the rport state machine
6965 +struct fc_disc_port {
6966 + struct fc_lport *lp;
6967 + struct list_head peers;
6968 + struct fc_rport_identifiers ids;
6969 + struct work_struct rport_work;
6973 + * struct fc_rport_libfc_priv - libfc internal information about a remote port
6974 + * @local_port: Fibre Channel host port instance
6975 + * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges
6976 + * @flags: REC and RETRY supported flags
6977 + * @max_seq: maximum number of concurrent sequences
6978 + * @retries: retry count in current state
6979 + * @e_d_tov: error detect timeout value (in msec)
6980 + * @r_a_tov: resource allocation timeout value (in msec)
6981 + * @rp_mutex: mutex protects rport
6983 + * @event_callback: Callback for rport READY, FAILED or LOGO
6985 +struct fc_rport_libfc_priv {
6986 + struct fc_lport *local_port;
6987 + enum fc_rport_state rp_state;
6989 + #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0)
6990 + #define FC_RP_FLAGS_RETRY (1 << 1)
6992 + unsigned int retries;
6993 + unsigned int e_d_tov;
6994 + unsigned int r_a_tov;
6995 + enum fc_rport_trans_state trans_state;
6996 + struct mutex rp_mutex;
6997 + struct delayed_work retry_work;
6998 + enum fc_lport_event event;
6999 + void (*event_callback)(struct fc_lport *,
7000 + struct fc_rport *,
7001 + enum fc_lport_event);
7002 + struct list_head peers;
7003 + struct work_struct event_work;
7006 +#define PRIV_TO_RPORT(x) \
7007 + (struct fc_rport *)((void *)x - sizeof(struct fc_rport));
7008 +#define RPORT_TO_PRIV(x) \
7009 + (struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport));
7011 +struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *);
7012 +void fc_rport_rogue_destroy(struct fc_rport *);
7014 +static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn)
7016 + rport->node_name = wwnn;
7017 + rport->port_name = wwpn;
7021 + * fcoe stats structure
7023 +struct fcoe_dev_stats {
7024 + u64 SecondsSinceLastReset;
7031 + u64 LinkFailureCount;
7032 + u64 LossOfSignalCount;
7033 + u64 InvalidTxWordCount;
7034 + u64 InvalidCRCCount;
7035 + u64 InputRequests;
7036 + u64 OutputRequests;
7037 + u64 ControlRequests;
7038 + u64 InputMegabytes;
7039 + u64 OutputMegabytes;
7043 + * els data is used for passing ELS respone specific
7044 + * data to send ELS response mainly using infomation
7045 + * in exchange and sequence in EM layer.
7047 +struct fc_seq_els_data {
7048 + struct fc_frame *fp;
7049 + enum fc_els_rjt_reason reason;
7050 + enum fc_els_rjt_explan explan;
7054 + * FCP request structure, one for each scsi cmd request
7056 +struct fc_fcp_pkt {
7058 + * housekeeping stuff
7060 + struct fc_lport *lp; /* handle to hba struct */
7061 + u16 state; /* scsi_pkt state state */
7062 + u16 tgt_flags; /* target flags */
7063 + atomic_t ref_cnt; /* fcp pkt ref count */
7064 + spinlock_t scsi_pkt_lock; /* Must be taken before the host lock
7065 + * if both are held at the same time */
7067 + * SCSI I/O related stuff
7069 + struct scsi_cmnd *cmd; /* scsi command pointer. set/clear
7070 + * under host lock */
7071 + struct list_head list; /* tracks queued commands. access under
7074 + * timeout related stuff
7076 + struct timer_list timer; /* command timer */
7077 + struct completion tm_done;
7078 + int wait_for_comp;
7079 + unsigned long start_time; /* start jiffie */
7080 + unsigned long end_time; /* end jiffie */
7081 + unsigned long last_pkt_time; /* jiffies of last frame received */
7084 + * scsi cmd and data transfer information
7088 + * transport related veriables
7090 + struct fcp_cmnd cdb_cmd;
7092 + u32 xfer_contig_end; /* offset of end of contiguous xfer */
7093 + u16 max_payload; /* max payload size in bytes */
7096 + * scsi/fcp return status
7098 + u32 io_status; /* SCSI result upper 24 bits */
7100 + u8 status_code; /* FCP I/O status */
7101 + /* bit 3 Underrun bit 2: overrun */
7102 + u8 scsi_comp_flags;
7103 + u32 req_flags; /* bit 0: read bit:1 write */
7104 + u32 scsi_resid; /* residule length */
7106 + struct fc_rport *rport; /* remote port pointer */
7107 + struct fc_seq *seq_ptr; /* current sequence pointer */
7109 + * Error Processing
7111 + u8 recov_retry; /* count of recovery retries */
7112 + struct fc_seq *recov_seq; /* sequence for REC or SRR */
7116 + * Structure and function definitions for managing Fibre Channel Exchanges
7119 + * fc_exch holds state for one exchange and links to its active sequence.
7121 + * fc_seq holds the state for an individual sequence.
7124 +struct fc_exch_mgr;
7130 + u8 id; /* seq ID */
7131 + u16 ssb_stat; /* status flags for sequence status block */
7132 + u16 cnt; /* frames sent so far on sequence */
7133 + u32 f_ctl; /* F_CTL flags for frames */
7134 + u32 rec_data; /* FC-4 value for REC */
7137 +#define FC_EX_DONE (1 << 0) /* ep is completed */
7138 +#define FC_EX_RST_CLEANUP (1 << 1) /* reset is forcing completion */
7143 + * Locking notes: The ex_lock protects changes to the following fields:
7144 + * esb_stat, f_ctl, seq.ssb_stat, seq.f_ctl.
7146 + * sequence allocation
7150 + struct fc_exch_mgr *em; /* exchange manager */
7151 + u32 state; /* internal driver state */
7152 + u16 xid; /* our exchange ID */
7153 + struct list_head ex_list; /* free or busy list linkage */
7154 + spinlock_t ex_lock; /* lock covering exchange state */
7155 + atomic_t ex_refcnt; /* reference counter */
7156 + struct delayed_work timeout_work; /* timer for upper level protocols */
7157 + struct fc_lport *lp; /* fc device instance */
7158 + u16 oxid; /* originator's exchange ID */
7159 + u16 rxid; /* responder's exchange ID */
7160 + u32 oid; /* originator's FCID */
7161 + u32 sid; /* source FCID */
7162 + u32 did; /* destination FCID */
7163 + u32 esb_stat; /* exchange status for ESB */
7164 + u32 r_a_tov; /* r_a_tov from rport (msec) */
7165 + u8 seq_id; /* next sequence ID to use */
7166 + u32 f_ctl; /* F_CTL flags for sequences */
7167 + u8 fh_type; /* frame type */
7168 + enum fc_class class; /* class of service */
7169 + struct fc_seq seq; /* single sequence */
7171 + * Handler for responses to this current exchange.
7173 + void (*resp)(struct fc_seq *, struct fc_frame *, void *);
7174 + void (*destructor)(struct fc_seq *, void *);
7176 + * arg is passed as void pointer to exchange
7177 + * resp and destructor handlers
7181 +#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
7183 +struct libfc_function_template {
7186 + * Mandatory Fields
7188 + * These handlers must be implemented by the LLD.
7192 + * Interface to send a FC frame
7194 + int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp);
7199 + * The LLD may choose to implement any of the following handlers.
7200 + * If LLD doesn't specify hander and leaves its pointer NULL then
7201 + * the default libfc function will be used for that handler.
7205 + * ELS/CT interfaces
7209 + * elsct_send - sends ELS/CT frame
7211 + struct fc_seq *(*elsct_send)(struct fc_lport *lport,
7212 + struct fc_rport *rport,
7213 + struct fc_frame *fp,
7215 + void (*resp)(struct fc_seq *,
7216 + struct fc_frame *fp,
7218 + void *arg, u32 timer_msec);
7220 + * Exhance Manager interfaces
7224 + * Send the FC frame payload using a new exchange and sequence.
7226 + * The frame pointer with some of the header's fields must be
7227 + * filled before calling exch_seq_send(), those fields are,
7229 + * - routing control
7232 + * - FC header type
7234 + * - parameter or relative offset
7236 + * The exchange response handler is set in this routine to resp()
7237 + * function pointer. It can be called in two scenarios: if a timeout
7238 + * occurs or if a response frame is received for the exchange. The
7239 + * fc_frame pointer in response handler will also indicate timeout
7240 + * as error using IS_ERR related macros.
7242 + * The exchange destructor handler is also set in this routine.
7243 + * The destructor handler is invoked by EM layer when exchange
7244 + * is about to free, this can be used by caller to free its
7245 + * resources along with exchange free.
7247 + * The arg is passed back to resp and destructor handler.
7249 + * The timeout value (in msec) for an exchange is set if non zero
7250 + * timer_msec argument is specified. The timer is canceled when
7251 + * it fires or when the exchange is done. The exchange timeout handler
7252 + * is registered by EM layer.
7254 + struct fc_seq *(*exch_seq_send)(struct fc_lport *lp,
7255 + struct fc_frame *fp,
7256 + void (*resp)(struct fc_seq *sp,
7257 + struct fc_frame *fp,
7259 + void (*destructor)(struct fc_seq *sp,
7261 + void *arg, unsigned int timer_msec);
7264 + * send a frame using existing sequence and exchange.
7266 + int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp,
7267 + struct fc_frame *fp);
7270 + * Send ELS response using mainly infomation
7271 + * in exchange and sequence in EM layer.
7273 + void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd,
7274 + struct fc_seq_els_data *els_data);
7277 + * Abort an exchange and sequence. Generally called because of a
7278 + * exchange timeout or an abort from the upper layer.
7280 + * A timer_msec can be specified for abort timeout, if non-zero
7281 + * timer_msec value is specified then exchange resp handler
7282 + * will be called with timeout error if no response to abort.
7284 + int (*seq_exch_abort)(const struct fc_seq *req_sp,
7285 + unsigned int timer_msec);
7288 + * Indicate that an exchange/sequence tuple is complete and the memory
7289 + * allocated for the related objects may be freed.
7291 + void (*exch_done)(struct fc_seq *sp);
7294 + * Assigns a EM and a free XID for an new exchange and then
7295 + * allocates a new exchange and sequence pair.
7296 + * The fp can be used to determine free XID.
7298 + struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp);
7301 + * Release previously assigned XID by exch_get API.
7302 + * The LLD may implement this if XID is assigned by LLD
7305 + void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp,
7309 + * Start a new sequence on the same exchange/sequence tuple.
7311 + struct fc_seq *(*seq_start_next)(struct fc_seq *sp);
7314 + * Reset an exchange manager, completing all sequences and exchanges.
7315 + * If s_id is non-zero, reset only exchanges originating from that FID.
7316 + * If d_id is non-zero, reset only exchanges sending to that FID.
7318 + void (*exch_mgr_reset)(struct fc_exch_mgr *,
7319 + u32 s_id, u32 d_id);
7321 + void (*rport_flush_queue)(void);
7323 + * Local Port interfaces
7327 + * Receive a frame to a local port.
7329 + void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp,
7330 + struct fc_frame *fp);
7332 + int (*lport_reset)(struct fc_lport *);
7335 + * Remote Port interfaces
7339 + * Initiates the RP state machine. It is called from the LP module.
7340 + * This function will issue the following commands to the N_Port
7341 + * identified by the FC ID provided.
7347 + int (*rport_login)(struct fc_rport *rport);
7350 + * Logoff, and remove the rport from the transport if
7351 + * it had been added. This will send a LOGO to the target.
7353 + int (*rport_logoff)(struct fc_rport *rport);
7356 + * Recieve a request from a remote port.
7358 + void (*rport_recv_req)(struct fc_seq *, struct fc_frame *,
7359 + struct fc_rport *);
7361 + struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32);
7368 + * Send a fcp cmd from fsp pkt.
7369 + * Called with the SCSI host lock unlocked and irqs disabled.
7371 + * The resp handler is called when FCP_RSP received.
7374 + int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
7375 + void (*resp)(struct fc_seq *, struct fc_frame *fp,
7379 + * Used at least durring linkdown and reset
7381 + void (*fcp_cleanup)(struct fc_lport *lp);
7384 + * Abort all I/O on a local port
7386 + void (*fcp_abort_io)(struct fc_lport *lp);
7389 + * Discovery interfaces
7392 + void (*disc_recv_req)(struct fc_seq *,
7393 + struct fc_frame *, struct fc_lport *);
7396 + * Start discovery for a local port.
7398 + void (*disc_start)(void (*disc_callback)(struct fc_lport *,
7399 + enum fc_disc_event),
7400 + struct fc_lport *);
7403 + * Stop discovery for a given lport. This will remove
7404 + * all discovered rports
7406 + void (*disc_stop) (struct fc_lport *);
7409 + * Stop discovery for a given lport. This will block
7410 + * until all discovered rports are deleted from the
7411 + * FC transport class
7413 + void (*disc_stop_final) (struct fc_lport *);
7417 + struct list_head list;
7419 + /* Associations */
7420 + struct Scsi_Host *host;
7421 + struct fc_exch_mgr *emp;
7422 + struct fc_rport *dns_rp;
7423 + struct fc_rport *ptp_rp;
7426 + /* Operational Information */
7427 + struct libfc_function_template tt;
7429 + enum fc_lport_state state;
7430 + unsigned long boot_time;
7432 + struct fc_host_statistics host_stats;
7433 + struct fcoe_dev_stats *dev_stats[NR_CPUS];
7438 + /* Capabilities */
7439 + u32 sg_supp:1; /* scatter gather supported */
7440 + u32 seq_offload:1; /* seq offload supported */
7441 + u32 crc_offload:1; /* crc offload supported */
7442 + u32 lro_enabled:1; /* large receive offload */
7443 + u32 mfs; /* max FC payload size */
7444 + unsigned int service_params;
7445 + unsigned int e_d_tov;
7446 + unsigned int r_a_tov;
7447 + u8 max_retry_count;
7449 + u16 link_supported_speeds;
7450 + u16 lro_xid; /* max xid for fcoe lro */
7451 + struct fc_ns_fts fcts; /* FC-4 type masks */
7452 + struct fc_els_rnid_gen rnid_gen; /* RNID information */
7455 + struct mutex lp_mutex;
7457 + /* Miscellaneous */
7458 + struct delayed_work retry_work;
7459 + struct delayed_work disc_work;
7463 + * FC_LPORT HELPER FUNCTIONS
7464 + *****************************/
7465 +static inline void *lport_priv(const struct fc_lport *lp)
7467 + return (void *)(lp + 1);
7470 +static inline int fc_lport_test_ready(struct fc_lport *lp)
7472 + return lp->state == LPORT_ST_READY;
7475 +static inline void fc_set_wwnn(struct fc_lport *lp, u64 wwnn)
7480 +static inline void fc_set_wwpn(struct fc_lport *lp, u64 wwnn)
7485 +static inline void fc_lport_state_enter(struct fc_lport *lp,
7486 + enum fc_lport_state state)
7488 + if (state != lp->state)
7489 + lp->retry_count = 0;
7490 + lp->state = state;
7495 + * LOCAL PORT LAYER
7496 + *****************************/
7497 +int fc_lport_init(struct fc_lport *lp);
7500 + * Destroy the specified local port by finding and freeing all
7501 + * fc_rports associated with it and then by freeing the fc_lport
7504 +int fc_lport_destroy(struct fc_lport *lp);
7507 + * Logout the specified local port from the fabric
7509 +int fc_fabric_logoff(struct fc_lport *lp);
7512 + * Initiate the LP state machine. This handler will use fc_host_attr
7513 + * to store the FLOGI service parameters, so fc_host_attr must be
7514 + * initialized before calling this handler.
7516 +int fc_fabric_login(struct fc_lport *lp);
7519 + * The link is up for the given local port.
7521 +void fc_linkup(struct fc_lport *);
7524 + * Link is down for the given local port.
7526 +void fc_linkdown(struct fc_lport *);
7529 + * Pause and unpause traffic.
7531 +void fc_pause(struct fc_lport *);
7532 +void fc_unpause(struct fc_lport *);
7535 + * Configure the local port.
7537 +int fc_lport_config(struct fc_lport *);
7540 + * Reset the local port.
7542 +int fc_lport_reset(struct fc_lport *);
7545 + * Set the mfs or reset
7547 +int fc_set_mfs(struct fc_lport *lp, u32 mfs);
7551 + * REMOTE PORT LAYER
7552 + *****************************/
7553 +int fc_rport_init(struct fc_lport *lp);
7554 +void fc_rport_terminate_io(struct fc_rport *rp);
7558 + *****************************/
7559 +int fc_disc_init(struct fc_lport *lp);
7564 + *****************************/
7566 + * Initialize the SCSI block of libfc
7568 +int fc_fcp_init(struct fc_lport *);
7571 + * This section provides an API which allows direct interaction
7572 + * with the SCSI-ml. Each of these functions satisfies a function
7573 + * pointer defined in Scsi_Host and therefore is always called
7574 + * directly from the SCSI-ml.
7576 +int fc_queuecommand(struct scsi_cmnd *sc_cmd,
7577 + void (*done)(struct scsi_cmnd *));
7580 + * complete processing of a fcp packet
7582 + * This function may sleep if a fsp timer is pending.
7583 + * The host lock must not be held by caller.
7585 +void fc_fcp_complete(struct fc_fcp_pkt *fsp);
7588 + * Send an ABTS frame to the target device. The sc_cmd argument
7589 + * is a pointer to the SCSI command to be aborted.
7591 +int fc_eh_abort(struct scsi_cmnd *sc_cmd);
7594 + * Reset a LUN by sending send the tm cmd to the target.
7596 +int fc_eh_device_reset(struct scsi_cmnd *sc_cmd);
7599 + * Reset the host adapter.
7601 +int fc_eh_host_reset(struct scsi_cmnd *sc_cmd);
7604 + * Check rport status.
7606 +int fc_slave_alloc(struct scsi_device *sdev);
7609 + * Adjust the queue depth.
7611 +int fc_change_queue_depth(struct scsi_device *sdev, int qdepth);
7614 + * Change the tag type.
7616 +int fc_change_queue_type(struct scsi_device *sdev, int tag_type);
7619 + * Free memory pools used by the FCP layer.
7621 +void fc_fcp_destroy(struct fc_lport *);
7624 + * ELS/CT interface
7625 + *****************************/
7627 + * Initializes ELS/CT interface
7629 +int fc_elsct_init(struct fc_lport *lp);
7633 + * EXCHANGE MANAGER LAYER
7634 + *****************************/
7636 + * Initializes Exchange Manager related
7637 + * function pointers in struct libfc_function_template.
7639 +int fc_exch_init(struct fc_lport *lp);
7642 + * Allocates an Exchange Manager (EM).
7644 + * The EM manages exchanges for their allocation and
7645 + * free, also allows exchange lookup for received
7648 + * The class is used for initializing FC class of
7649 + * allocated exchange from EM.
7651 + * The min_xid and max_xid will limit new
7652 + * exchange ID (XID) within this range for
7654 + * The LLD may choose to have multiple EMs,
7655 + * e.g. one EM instance per CPU receive thread in LLD.
7656 + * The LLD can use exch_get() of struct libfc_function_template
7657 + * to specify XID for a new exchange within
7658 + * a specified EM instance.
7660 + * The em_idx to uniquely identify an EM instance.
7662 +struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
7663 + enum fc_class class,
7668 + * Free an exchange manager.
7670 +void fc_exch_mgr_free(struct fc_exch_mgr *mp);
7673 + * Receive a frame on specified local port and exchange manager.
7675 +void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
7676 + struct fc_frame *fp);
7679 + * This function is for exch_seq_send function pointer in
7680 + * struct libfc_function_template, see comment block on
7681 + * exch_seq_send for description of this function.
7683 +struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
7684 + struct fc_frame *fp,
7685 + void (*resp)(struct fc_seq *sp,
7686 + struct fc_frame *fp,
7688 + void (*destructor)(struct fc_seq *sp,
7690 + void *arg, u32 timer_msec);
7693 + * send a frame using existing sequence and exchange.
7695 +int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp);
7698 + * Send ELS response using mainly infomation
7699 + * in exchange and sequence in EM layer.
7701 +void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd,
7702 + struct fc_seq_els_data *els_data);
7705 + * This function is for seq_exch_abort function pointer in
7706 + * struct libfc_function_template, see comment block on
7707 + * seq_exch_abort for description of this function.
7709 +int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec);
7712 + * Indicate that an exchange/sequence tuple is complete and the memory
7713 + * allocated for the related objects may be freed.
7715 +void fc_exch_done(struct fc_seq *sp);
7718 + * Assigns a EM and XID for a frame and then allocates
7719 + * a new exchange and sequence pair.
7720 + * The fp can be used to determine free XID.
7722 +struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp);
7725 + * Allocate a new exchange and sequence pair.
7726 + * if ex_id is zero then next free exchange id
7727 + * from specified exchange manger mp will be assigned.
7729 +struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
7730 + struct fc_frame *fp, u16 ex_id);
7732 + * Start a new sequence on the same exchange as the supplied sequence.
7734 +struct fc_seq *fc_seq_start_next(struct fc_seq *sp);
7737 + * Reset an exchange manager, completing all sequences and exchanges.
7738 + * If s_id is non-zero, reset only exchanges originating from that FID.
7739 + * If d_id is non-zero, reset only exchanges sending to that FID.
7741 +void fc_exch_mgr_reset(struct fc_exch_mgr *, u32 s_id, u32 d_id);
7744 + * Functions for fc_functions_template
7746 +void fc_get_host_speed(struct Scsi_Host *shost);
7747 +void fc_get_host_port_type(struct Scsi_Host *shost);
7748 +void fc_get_host_port_state(struct Scsi_Host *shost);
7749 +void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout);
7750 +struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *);
7753 + * module setup functions.
7755 +int fc_setup_exch_mgr(void);
7756 +void fc_destroy_exch_mgr(void);
7757 +int fc_setup_rport(void);
7758 +void fc_destroy_rport(void);
7760 +#endif /* _LIBFC_H_ */
7761 diff --git a/include/scsi/libfc/fc_frame.h b/include/scsi/libfc/fc_frame.h
7762 deleted file mode 100644
7763 index 9508e55..0000000
7764 --- a/include/scsi/libfc/fc_frame.h
7768 - * Copyright(c) 2007 Intel Corporation. All rights reserved.
7770 - * This program is free software; you can redistribute it and/or modify it
7771 - * under the terms and conditions of the GNU General Public License,
7772 - * version 2, as published by the Free Software Foundation.
7774 - * This program is distributed in the hope it will be useful, but WITHOUT
7775 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7776 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
7779 - * You should have received a copy of the GNU General Public License along with
7780 - * this program; if not, write to the Free Software Foundation, Inc.,
7781 - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
7783 - * Maintained at www.Open-FCoE.org
7786 -#ifndef _FC_FRAME_H_
7787 -#define _FC_FRAME_H_
7789 -#include <linux/scatterlist.h>
7790 -#include <linux/skbuff.h>
7792 -#include <scsi/fc/fc_fs.h>
7793 -#include <scsi/fc/fc_encaps.h>
7796 - * The fc_frame interface is used to pass frame data between functions.
7797 - * The frame includes the data buffer, length, and SOF / EOF delimiter types.
7798 - * A pointer to the port structure of the receiving port is also includeded.
7801 -#define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */
7802 -#define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */
7805 - * Information about an individual fibre channel frame received or to be sent.
7806 - * The buffer may be in up to 4 additional non-contiguous sections,
7807 - * but the linear section must hold the frame header.
7809 -#define FC_FRAME_SG_LEN 4 /* scatter/gather list maximum length */
7811 -#define fp_skb(fp) (&((fp)->skb))
7812 -#define fr_hdr(fp) ((fp)->skb.data)
7813 -#define fr_len(fp) ((fp)->skb.len)
7814 -#define fr_cb(fp) ((struct fcoe_rcv_info *)&((fp)->skb.cb[0]))
7815 -#define fr_dev(fp) (fr_cb(fp)->fr_dev)
7816 -#define fr_seq(fp) (fr_cb(fp)->fr_seq)
7817 -#define fr_sof(fp) (fr_cb(fp)->fr_sof)
7818 -#define fr_eof(fp) (fr_cb(fp)->fr_eof)
7819 -#define fr_flags(fp) (fr_cb(fp)->fr_flags)
7820 -#define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload)
7823 - struct sk_buff skb;
7826 -struct fcoe_rcv_info {
7827 - struct packet_type *ptype;
7828 - struct fc_lport *fr_dev; /* transport layer private pointer */
7829 - struct fc_seq *fr_seq; /* for use with exchange manager */
7830 - enum fc_sof fr_sof; /* start of frame delimiter */
7831 - enum fc_eof fr_eof; /* end of frame delimiter */
7832 - u8 fr_flags; /* flags - see below */
7833 - u16 fr_max_payload; /* max FC payload */
7837 - * Get fc_frame pointer for an skb that's already been imported.
7839 -static inline struct fcoe_rcv_info *fcoe_dev_from_skb(const struct sk_buff *skb)
7841 - BUILD_BUG_ON(sizeof(struct fcoe_rcv_info) > sizeof(skb->cb));
7842 - return (struct fcoe_rcv_info *) skb->cb;
7848 -#define FCPHF_CRC_UNCHECKED 0x01 /* CRC not computed, still appended */
7851 - * Initialize a frame.
7852 - * We don't do a complete memset here for performance reasons.
7853 - * The caller must set fr_free, fr_hdr, fr_len, fr_sof, and fr_eof eventually.
7855 -static inline void fc_frame_init(struct fc_frame *fp)
7857 - fr_dev(fp) = NULL;
7858 - fr_seq(fp) = NULL;
7862 -struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len);
7864 -struct fc_frame *__fc_frame_alloc(size_t payload_len);
7867 - * Get frame for sending via port.
7869 -static inline struct fc_frame *_fc_frame_alloc(struct fc_lport *dev,
7870 - size_t payload_len)
7872 - return __fc_frame_alloc(payload_len);
7876 - * Allocate fc_frame structure and buffer. Set the initial length to
7877 - * payload_size + sizeof (struct fc_frame_header).
7879 -static inline struct fc_frame *fc_frame_alloc(struct fc_lport *dev, size_t len)
7881 - struct fc_frame *fp;
7884 - * Note: Since len will often be a constant multiple of 4,
7885 - * this check will usually be evaluated and eliminated at compile time.
7887 - if ((len % 4) != 0)
7888 - fp = fc_frame_alloc_fill(dev, len);
7890 - fp = _fc_frame_alloc(dev, len);
7895 - * Free the fc_frame structure and buffer.
7897 -static inline void fc_frame_free(struct fc_frame *fp)
7899 - kfree_skb(fp_skb(fp));
7902 -static inline int fc_frame_is_linear(struct fc_frame *fp)
7904 - return !skb_is_nonlinear(fp_skb(fp));
7908 - * Get frame header from message in fc_frame structure.
7909 - * This hides a cast and provides a place to add some checking.
7912 -struct fc_frame_header *fc_frame_header_get(const struct fc_frame *fp)
7914 - WARN_ON(fr_len(fp) < sizeof(struct fc_frame_header));
7915 - return (struct fc_frame_header *) fr_hdr(fp);
7919 - * Get frame payload from message in fc_frame structure.
7920 - * This hides a cast and provides a place to add some checking.
7921 - * The len parameter is the minimum length for the payload portion.
7922 - * Returns NULL if the frame is too short.
7924 - * This assumes the interesting part of the payload is in the first part
7925 - * of the buffer for received data. This may not be appropriate to use for
7926 - * buffers being transmitted.
7928 -static inline void *fc_frame_payload_get(const struct fc_frame *fp,
7933 - if (fr_len(fp) >= sizeof(struct fc_frame_header) + len)
7934 - pp = fc_frame_header_get(fp) + 1;
7939 - * Get frame payload opcode (first byte) from message in fc_frame structure.
7940 - * This hides a cast and provides a place to add some checking. Return 0
7941 - * if the frame has no payload.
7943 -static inline u8 fc_frame_payload_op(const struct fc_frame *fp)
7947 - cp = fc_frame_payload_get(fp, sizeof(u8));
7955 - * Get FC class from frame.
7957 -static inline enum fc_class fc_frame_class(const struct fc_frame *fp)
7959 - return fc_sof_class(fr_sof(fp));
7963 - * Set r_ctl and type in preparation for sending frame.
7964 - * This also clears fh_parm_offset.
7966 -static inline void fc_frame_setup(struct fc_frame *fp, enum fc_rctl r_ctl,
7967 - enum fc_fh_type type)
7969 - struct fc_frame_header *fh;
7971 - fh = fc_frame_header_get(fp);
7972 - WARN_ON(r_ctl == 0);
7973 - fh->fh_r_ctl = r_ctl;
7974 - fh->fh_type = type;
7975 - fh->fh_parm_offset = htonl(0);
7979 - * Set offset in preparation for sending frame.
7982 -fc_frame_set_offset(struct fc_frame *fp, u32 offset)
7984 - struct fc_frame_header *fh;
7986 - fh = fc_frame_header_get(fp);
7987 - fh->fh_parm_offset = htonl(offset);
7991 - * Check the CRC in a frame.
7992 - * The CRC immediately follows the last data item *AFTER* the length.
7993 - * The return value is zero if the CRC matches.
7995 -u32 fc_frame_crc_check(struct fc_frame *);
7998 - * Check for leaks.
7999 - * Print the frame header of any currently allocated frame, assuming there
8000 - * should be none at this point.
8002 -void fc_frame_leak_check(void);
8004 -#endif /* _FC_FRAME_H_ */
8005 diff --git a/include/scsi/libfc/libfc.h b/include/scsi/libfc/libfc.h
8006 deleted file mode 100644
8007 index 237abd3..0000000
8008 --- a/include/scsi/libfc/libfc.h
8012 - * Copyright(c) 2007 Intel Corporation. All rights reserved.
8014 - * This program is free software; you can redistribute it and/or modify it
8015 - * under the terms and conditions of the GNU General Public License,
8016 - * version 2, as published by the Free Software Foundation.
8018 - * This program is distributed in the hope it will be useful, but WITHOUT
8019 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8020 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
8023 - * You should have received a copy of the GNU General Public License along with
8024 - * this program; if not, write to the Free Software Foundation, Inc.,
8025 - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
8027 - * Maintained at www.Open-FCoE.org
8033 -#include <linux/timer.h>
8034 -#include <linux/if.h>
8036 -#include <scsi/scsi_transport.h>
8037 -#include <scsi/scsi_transport_fc.h>
8039 -#include <scsi/fc/fc_fcp.h>
8040 -#include <scsi/fc/fc_ns.h>
8041 -#include <scsi/fc/fc_els.h>
8042 -#include <scsi/fc/fc_gs.h>
8044 -#include <scsi/libfc/fc_frame.h>
8046 -#define LIBFC_DEBUG
8050 -#define FC_DBG(fmt, args...) \
8052 - printk(KERN_INFO "%s " fmt, __func__, ##args); \
8055 -#define FC_DBG(fmt, args...)
8059 - * libfc error codes
8061 -#define FC_NO_ERR 0 /* no error */
8062 -#define FC_EX_TIMEOUT 1 /* Exchange timeout */
8063 -#define FC_EX_CLOSED 2 /* Exchange closed */
8065 -/* some helpful macros */
8067 -#define ntohll(x) be64_to_cpu(x)
8068 -#define htonll(x) cpu_to_be64(x)
8070 -#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
8072 -#define hton24(p, v) do { \
8073 - p[0] = (((v) >> 16) & 0xFF); \
8074 - p[1] = (((v) >> 8) & 0xFF); \
8075 - p[2] = ((v) & 0xFF); \
8078 -struct fc_exch_mgr;
8083 -#define FC_PAUSE (1 << 1)
8084 -#define FC_LINK_UP (1 << 0)
8086 -enum fc_lport_state {
8087 - LPORT_ST_NONE = 0,
8098 -enum fc_lport_event {
8099 - LPORT_EV_RPORT_NONE = 0,
8100 - LPORT_EV_RPORT_CREATED,
8101 - LPORT_EV_RPORT_FAILED,
8102 - LPORT_EV_RPORT_STOP,
8103 - LPORT_EV_RPORT_LOGO
8106 -enum fc_rport_state {
8107 - RPORT_ST_NONE = 0,
8108 - RPORT_ST_INIT, /* initialized */
8109 - RPORT_ST_PLOGI, /* waiting for PLOGI completion */
8110 - RPORT_ST_PRLI, /* waiting for PRLI completion */
8111 - RPORT_ST_RTV, /* waiting for RTV completion */
8112 - RPORT_ST_READY, /* ready for use */
8113 - RPORT_ST_LOGO, /* port logout sent */
8116 -enum fc_rport_trans_state {
8117 - FC_PORTSTATE_ROGUE,
8118 - FC_PORTSTATE_REAL,
8122 - * struct fc_disc_port - temporary discovery port to hold rport identifiers
8123 - * @lp: Fibre Channel host port instance
8124 - * @peers: node for list management during discovery and RSCN processing
8125 - * @ids: identifiers structure to pass to fc_remote_port_add()
8126 - * @rport_work: work struct for starting the rport state machine
8128 -struct fc_disc_port {
8129 - struct fc_lport *lp;
8130 - struct list_head peers;
8131 - struct fc_rport_identifiers ids;
8132 - struct work_struct rport_work;
8136 - * struct fc_rport_libfc_priv - libfc internal information about a remote port
8137 - * @local_port: Fibre Channel host port instance
8138 - * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges
8139 - * @flags: REC and RETRY supported flags
8140 - * @max_seq: maximum number of concurrent sequences
8141 - * @retries: retry count in current state
8142 - * @e_d_tov: error detect timeout value (in msec)
8143 - * @r_a_tov: resource allocation timeout value (in msec)
8144 - * @rp_mutex: mutex protects rport
8146 - * @event_callback: Callback for rport READY, FAILED or LOGO
8148 -struct fc_rport_libfc_priv {
8149 - struct fc_lport *local_port;
8150 - enum fc_rport_state rp_state;
8152 - #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0)
8153 - #define FC_RP_FLAGS_RETRY (1 << 1)
8155 - unsigned int retries;
8156 - unsigned int e_d_tov;
8157 - unsigned int r_a_tov;
8158 - enum fc_rport_trans_state trans_state;
8159 - struct mutex rp_mutex;
8160 - struct delayed_work retry_work;
8161 - enum fc_lport_event event;
8162 - void (*event_callback)(struct fc_lport *,
8163 - struct fc_rport *,
8164 - enum fc_lport_event);
8165 - struct list_head peers;
8166 - struct work_struct event_work;
8169 -#define PRIV_TO_RPORT(x) \
8170 - (struct fc_rport *)((void *)x - sizeof(struct fc_rport));
8171 -#define RPORT_TO_PRIV(x) \
8172 - (struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport));
8174 -struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *);
8175 -void fc_rport_rogue_destroy(struct fc_rport *);
8177 -static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn)
8179 - rport->node_name = wwnn;
8180 - rport->port_name = wwpn;
8184 - * fcoe stats structure
8186 -struct fcoe_dev_stats {
8187 - u64 SecondsSinceLastReset;
8194 - u64 LinkFailureCount;
8195 - u64 LossOfSignalCount;
8196 - u64 InvalidTxWordCount;
8197 - u64 InvalidCRCCount;
8198 - u64 InputRequests;
8199 - u64 OutputRequests;
8200 - u64 ControlRequests;
8201 - u64 InputMegabytes;
8202 - u64 OutputMegabytes;
8206 - * els data is used for passing ELS respone specific
8207 - * data to send ELS response mainly using infomation
8208 - * in exchange and sequence in EM layer.
8210 -struct fc_seq_els_data {
8211 - struct fc_frame *fp;
8212 - enum fc_els_rjt_reason reason;
8213 - enum fc_els_rjt_explan explan;
8217 - * FCP request structure, one for each scsi cmd request
8219 -struct fc_fcp_pkt {
8221 - * housekeeping stuff
8223 - struct fc_lport *lp; /* handle to hba struct */
8224 - u16 state; /* scsi_pkt state state */
8225 - u16 tgt_flags; /* target flags */
8226 - atomic_t ref_cnt; /* fcp pkt ref count */
8227 - spinlock_t scsi_pkt_lock; /* Must be taken before the host lock
8228 - * if both are held at the same time */
8230 - * SCSI I/O related stuff
8232 - struct scsi_cmnd *cmd; /* scsi command pointer. set/clear
8233 - * under host lock */
8234 - struct list_head list; /* tracks queued commands. access under
8237 - * timeout related stuff
8239 - struct timer_list timer; /* command timer */
8240 - struct completion tm_done;
8241 - int wait_for_comp;
8242 - unsigned long start_time; /* start jiffie */
8243 - unsigned long end_time; /* end jiffie */
8244 - unsigned long last_pkt_time; /* jiffies of last frame received */
8247 - * scsi cmd and data transfer information
8251 - * transport related veriables
8253 - struct fcp_cmnd cdb_cmd;
8255 - u32 xfer_contig_end; /* offset of end of contiguous xfer */
8256 - u16 max_payload; /* max payload size in bytes */
8259 - * scsi/fcp return status
8261 - u32 io_status; /* SCSI result upper 24 bits */
8263 - u8 status_code; /* FCP I/O status */
8264 - /* bit 3 Underrun bit 2: overrun */
8265 - u8 scsi_comp_flags;
8266 - u32 req_flags; /* bit 0: read bit:1 write */
8267 - u32 scsi_resid; /* residule length */
8269 - struct fc_rport *rport; /* remote port pointer */
8270 - struct fc_seq *seq_ptr; /* current sequence pointer */
8272 - * Error Processing
8274 - u8 recov_retry; /* count of recovery retries */
8275 - struct fc_seq *recov_seq; /* sequence for REC or SRR */
8278 -struct libfc_function_template {
8281 - * Mandatory Fields
8283 - * These handlers must be implemented by the LLD.
8287 - * Interface to send a FC frame
8289 - int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp);
8294 - * The LLD may choose to implement any of the following handlers.
8295 - * If LLD doesn't specify hander and leaves its pointer NULL then
8296 - * the default libfc function will be used for that handler.
8300 - * Exhance Manager interfaces
8304 - * Send the FC frame payload using a new exchange and sequence.
8306 - * The frame pointer with some of the header's fields must be
8307 - * filled before calling exch_seq_send(), those fields are,
8309 - * - routing control
8310 - * - FC header type
8311 - * - parameter or relative offset
8313 - * The exchange response handler is set in this routine to resp()
8314 - * function pointer. It can be called in two scenarios: if a timeout
8315 - * occurs or if a response frame is received for the exchange. The
8316 - * fc_frame pointer in response handler will also indicate timeout
8317 - * as error using IS_ERR related macros.
8319 - * The exchange destructor handler is also set in this routine.
8320 - * The destructor handler is invoked by EM layer when exchange
8321 - * is about to free, this can be used by caller to free its
8322 - * resources along with exchange free.
8324 - * The arg is passed back to resp and destructor handler.
8326 - * The timeout value (in msec) for an exchange is set if non zero
8327 - * timer_msec argument is specified. The timer is canceled when
8328 - * it fires or when the exchange is done. The exchange timeout handler
8329 - * is registered by EM layer.
8331 - * The caller also need to specify FC sid, did and frame control field.
8333 - struct fc_seq *(*exch_seq_send)(struct fc_lport *lp,
8334 - struct fc_frame *fp,
8335 - void (*resp)(struct fc_seq *sp,
8336 - struct fc_frame *fp,
8338 - void (*destructor)(struct fc_seq *sp,
8340 - void *arg, unsigned int timer_msec,
8341 - u32 sid, u32 did, u32 f_ctl);
8344 - * send a frame using existing sequence and exchange.
8346 - int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp,
8347 - struct fc_frame *fp, u32 f_ctl);
8350 - * Send ELS response using mainly infomation
8351 - * in exchange and sequence in EM layer.
8353 - void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd,
8354 - struct fc_seq_els_data *els_data);
8357 - * Abort an exchange and sequence. Generally called because of a
8358 - * exchange timeout or an abort from the upper layer.
8360 - * A timer_msec can be specified for abort timeout, if non-zero
8361 - * timer_msec value is specified then exchange resp handler
8362 - * will be called with timeout error if no response to abort.
8364 - int (*seq_exch_abort)(const struct fc_seq *req_sp,
8365 - unsigned int timer_msec);
8368 - * Indicate that an exchange/sequence tuple is complete and the memory
8369 - * allocated for the related objects may be freed.
8371 - void (*exch_done)(struct fc_seq *sp);
8374 - * Assigns a EM and a free XID for an new exchange and then
8375 - * allocates a new exchange and sequence pair.
8376 - * The fp can be used to determine free XID.
8378 - struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp);
8381 - * Release previously assigned XID by exch_get API.
8382 - * The LLD may implement this if XID is assigned by LLD
8385 - void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp,
8389 - * Start a new sequence on the same exchange/sequence tuple.
8391 - struct fc_seq *(*seq_start_next)(struct fc_seq *sp);
8394 - * Reset an exchange manager, completing all sequences and exchanges.
8395 - * If s_id is non-zero, reset only exchanges originating from that FID.
8396 - * If d_id is non-zero, reset only exchanges sending to that FID.
8398 - void (*exch_mgr_reset)(struct fc_exch_mgr *,
8399 - u32 s_id, u32 d_id);
8402 - * Get exchange Ids of a sequence
8404 - void (*seq_get_xids)(struct fc_seq *sp, u16 *oxid, u16 *rxid);
8407 - * Set REC data to a sequence
8409 - void (*seq_set_rec_data)(struct fc_seq *sp, u32 rec_data);
8412 - * Local Port interfaces
8416 - * Receive a frame to a local port.
8418 - void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp,
8419 - struct fc_frame *fp);
8421 - int (*lport_reset)(struct fc_lport *);
8423 - void (*event_callback)(struct fc_lport *, struct fc_rport *,
8424 - enum fc_lport_event);
8427 - * Remote Port interfaces
8431 - * Initiates the RP state machine. It is called from the LP module.
8432 - * This function will issue the following commands to the N_Port
8433 - * identified by the FC ID provided.
8439 - int (*rport_login)(struct fc_rport *rport);
8442 - * Logs the specified local port out of a N_Port identified
8443 - * by the ID provided.
8445 - int (*rport_logout)(struct fc_rport *rport);
8448 - * Delete the rport and remove it from the transport if
8449 - * it had been added. This will not send a LOGO, use
8450 - * rport_logout for a gracefull logout.
8452 - int (*rport_stop)(struct fc_rport *rport);
8455 - * Recieve a request from a remote port.
8457 - void (*rport_recv_req)(struct fc_seq *, struct fc_frame *,
8458 - struct fc_rport *);
8460 - struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32);
8467 - * Send a fcp cmd from fsp pkt.
8468 - * Called with the SCSI host lock unlocked and irqs disabled.
8470 - * The resp handler is called when FCP_RSP received.
8473 - int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
8474 - void (*resp)(struct fc_seq *, struct fc_frame *fp,
8478 - * Used at least durring linkdown and reset
8480 - void (*fcp_cleanup)(struct fc_lport *lp);
8483 - * Abort all I/O on a local port
8485 - void (*fcp_abort_io)(struct fc_lport *lp);
8488 - * Discovery interfaces
8491 - void (*disc_recv_req)(struct fc_seq *,
8492 - struct fc_frame *, struct fc_lport *);
8495 - * Start discovery for a local port.
8497 - int (*disc_start)(struct fc_lport *);
8501 - struct list_head list;
8503 - /* Associations */
8504 - struct Scsi_Host *host;
8505 - struct fc_exch_mgr *emp;
8506 - struct fc_rport *dns_rp;
8507 - struct fc_rport *ptp_rp;
8509 - struct list_head rports;
8511 - /* Operational Information */
8512 - struct libfc_function_template tt;
8515 - enum fc_lport_state state;
8516 - unsigned long boot_time;
8518 - struct fc_host_statistics host_stats;
8519 - struct fcoe_dev_stats *dev_stats[NR_CPUS];
8524 - unsigned char disc_retry_count;
8525 - unsigned char disc_delay;
8526 - unsigned char disc_pending;
8527 - unsigned char disc_requested;
8528 - unsigned short disc_seq_count;
8529 - unsigned char disc_buf_len;
8531 - /* Capabilities */
8532 - u32 sg_supp:1; /* scatter gather supported */
8533 - u32 seq_offload:1; /* seq offload supported */
8534 - u32 mfs; /* max FC payload size */
8535 - unsigned int service_params;
8536 - unsigned int e_d_tov;
8537 - unsigned int r_a_tov;
8538 - u8 max_retry_count;
8540 - u16 link_supported_speeds;
8541 - struct fc_ns_fts fcts; /* FC-4 type masks */
8542 - struct fc_els_rnid_gen rnid_gen; /* RNID information */
8545 - struct mutex lp_mutex;
8547 - /* Miscellaneous */
8548 - struct fc_gpn_ft_resp disc_buf; /* partial name buffer */
8549 - struct delayed_work retry_work;
8550 - struct delayed_work disc_work;
8556 - * FC_LPORT HELPER FUNCTIONS
8557 - *****************************/
8559 -static inline int fc_lport_test_ready(struct fc_lport *lp)
8561 - return lp->state == LPORT_ST_READY;
8564 -static inline void fc_set_wwnn(struct fc_lport *lp, u64 wwnn)
8569 -static inline void fc_set_wwpn(struct fc_lport *lp, u64 wwnn)
8575 - * fc_fill_dns_hdr - Fill in a name service request header
8576 - * @lp: Fibre Channel host port instance
8577 - * @ct: Common Transport (CT) header structure
8578 - * @op: Name Service request code
8579 - * @req_size: Full size of Name Service request
8581 -static inline void fc_fill_dns_hdr(struct fc_lport *lp, struct fc_ct_hdr *ct,
8582 - unsigned int op, unsigned int req_size)
8584 - memset(ct, 0, sizeof(*ct) + req_size);
8585 - ct->ct_rev = FC_CT_REV;
8586 - ct->ct_fs_type = FC_FST_DIR;
8587 - ct->ct_fs_subtype = FC_NS_SUBTYPE;
8588 - ct->ct_cmd = htons((u16) op);
8591 -static inline void fc_lport_state_enter(struct fc_lport *lp,
8592 - enum fc_lport_state state)
8594 - if (state != lp->state)
8595 - lp->retry_count = 0;
8596 - lp->state = state;
8601 - * LOCAL PORT LAYER
8602 - *****************************/
8603 -int fc_lport_init(struct fc_lport *lp);
8606 - * Destroy the specified local port by finding and freeing all
8607 - * fc_rports associated with it and then by freeing the fc_lport
8610 -int fc_lport_destroy(struct fc_lport *lp);
8613 - * Logout the specified local port from the fabric
8615 -int fc_fabric_logoff(struct fc_lport *lp);
8618 - * Initiate the LP state machine. This handler will use fc_host_attr
8619 - * to store the FLOGI service parameters, so fc_host_attr must be
8620 - * initialized before calling this handler.
8622 -int fc_fabric_login(struct fc_lport *lp);
8625 - * The link is up for the given local port.
8627 -void fc_linkup(struct fc_lport *);
8630 - * Link is down for the given local port.
8632 -void fc_linkdown(struct fc_lport *);
8635 - * Pause and unpause traffic.
8637 -void fc_pause(struct fc_lport *);
8638 -void fc_unpause(struct fc_lport *);
8641 - * Configure the local port.
8643 -int fc_lport_config(struct fc_lport *);
8646 - * Reset the local port.
8648 -int fc_lport_reset(struct fc_lport *);
8651 - * Set the mfs or reset
8653 -int fc_set_mfs(struct fc_lport *lp, u32 mfs);
8657 - * REMOTE PORT LAYER
8658 - *****************************/
8659 -int fc_rport_init(struct fc_lport *lp);
8660 -void fc_rport_terminate_io(struct fc_rport *rp);
8664 - *****************************/
8665 -int fc_disc_init(struct fc_lport *lp);
8670 - *****************************/
8672 - * Initialize the SCSI block of libfc
8674 -int fc_fcp_init(struct fc_lport *);
8677 - * This section provides an API which allows direct interaction
8678 - * with the SCSI-ml. Each of these functions satisfies a function
8679 - * pointer defined in Scsi_Host and therefore is always called
8680 - * directly from the SCSI-ml.
8682 -int fc_queuecommand(struct scsi_cmnd *sc_cmd,
8683 - void (*done)(struct scsi_cmnd *));
8686 - * complete processing of a fcp packet
8688 - * This function may sleep if a fsp timer is pending.
8689 - * The host lock must not be held by caller.
8691 -void fc_fcp_complete(struct fc_fcp_pkt *fsp);
8694 - * Send an ABTS frame to the target device. The sc_cmd argument
8695 - * is a pointer to the SCSI command to be aborted.
8697 -int fc_eh_abort(struct scsi_cmnd *sc_cmd);
8700 - * Reset a LUN by sending send the tm cmd to the target.
8702 -int fc_eh_device_reset(struct scsi_cmnd *sc_cmd);
8705 - * Reset the host adapter.
8707 -int fc_eh_host_reset(struct scsi_cmnd *sc_cmd);
8710 - * Check rport status.
8712 -int fc_slave_alloc(struct scsi_device *sdev);
8715 - * Adjust the queue depth.
8717 -int fc_change_queue_depth(struct scsi_device *sdev, int qdepth);
8720 - * Change the tag type.
8722 -int fc_change_queue_type(struct scsi_device *sdev, int tag_type);
8725 - * Free memory pools used by the FCP layer.
8727 -void fc_fcp_destroy(struct fc_lport *);
8731 - * EXCHANGE MANAGER LAYER
8732 - *****************************/
8734 - * Initializes Exchange Manager related
8735 - * function pointers in struct libfc_function_template.
8737 -int fc_exch_init(struct fc_lport *lp);
8740 - * Allocates an Exchange Manager (EM).
8742 - * The EM manages exchanges for their allocation and
8743 - * free, also allows exchange lookup for received
8746 - * The class is used for initializing FC class of
8747 - * allocated exchange from EM.
8749 - * The min_xid and max_xid will limit new
8750 - * exchange ID (XID) within this range for
8752 - * The LLD may choose to have multiple EMs,
8753 - * e.g. one EM instance per CPU receive thread in LLD.
8754 - * The LLD can use exch_get() of struct libfc_function_template
8755 - * to specify XID for a new exchange within
8756 - * a specified EM instance.
8758 - * The em_idx to uniquely identify an EM instance.
8760 -struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
8761 - enum fc_class class,
8766 - * Free an exchange manager.
8768 -void fc_exch_mgr_free(struct fc_exch_mgr *mp);
8771 - * Receive a frame on specified local port and exchange manager.
8773 -void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
8774 - struct fc_frame *fp);
8777 - * This function is for exch_seq_send function pointer in
8778 - * struct libfc_function_template, see comment block on
8779 - * exch_seq_send for description of this function.
8781 -struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
8782 - struct fc_frame *fp,
8783 - void (*resp)(struct fc_seq *sp,
8784 - struct fc_frame *fp,
8786 - void (*destructor)(struct fc_seq *sp,
8788 - void *arg, u32 timer_msec,
8789 - u32 sid, u32 did, u32 f_ctl);
8792 - * send a frame using existing sequence and exchange.
8794 -int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp,
8795 - struct fc_frame *fp, u32 f_ctl);
8798 - * Send ELS response using mainly infomation
8799 - * in exchange and sequence in EM layer.
8801 -void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd,
8802 - struct fc_seq_els_data *els_data);
8805 - * This function is for seq_exch_abort function pointer in
8806 - * struct libfc_function_template, see comment block on
8807 - * seq_exch_abort for description of this function.
8809 -int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec);
8812 - * Indicate that an exchange/sequence tuple is complete and the memory
8813 - * allocated for the related objects may be freed.
8815 -void fc_exch_done(struct fc_seq *sp);
8818 - * Assigns a EM and XID for a frame and then allocates
8819 - * a new exchange and sequence pair.
8820 - * The fp can be used to determine free XID.
8822 -struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp);
8825 - * Allocate a new exchange and sequence pair.
8826 - * if ex_id is zero then next free exchange id
8827 - * from specified exchange manger mp will be assigned.
8829 -struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, u16 ex_id);
8832 - * Start a new sequence on the same exchange as the supplied sequence.
8834 -struct fc_seq *fc_seq_start_next(struct fc_seq *sp);
8837 - * Reset an exchange manager, completing all sequences and exchanges.
8838 - * If s_id is non-zero, reset only exchanges originating from that FID.
8839 - * If d_id is non-zero, reset only exchanges sending to that FID.
8841 -void fc_exch_mgr_reset(struct fc_exch_mgr *, u32 s_id, u32 d_id);
8844 - * Get exchange Ids of a sequence
8846 -void fc_seq_get_xids(struct fc_seq *sp, u16 *oxid, u16 *rxid);
8849 - * Set REC data to a sequence
8851 -void fc_seq_set_rec_data(struct fc_seq *sp, u32 rec_data);
8854 - * Functions for fc_functions_template
8856 -void fc_get_host_speed(struct Scsi_Host *shost);
8857 -void fc_get_host_port_type(struct Scsi_Host *shost);
8858 -void fc_get_host_port_state(struct Scsi_Host *shost);
8859 -void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout);
8860 -struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *);
8863 - * module setup functions.
8865 -int fc_setup_exch_mgr(void);
8866 -void fc_destroy_exch_mgr(void);
8867 -int fc_setup_rport(void);
8868 -void fc_destroy_rport(void);
8870 -#endif /* _LIBFC_H_ */
8871 diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
8872 new file mode 100644
8873 index 0000000..4ca5902
8875 +++ b/include/scsi/libfcoe.h
8878 + * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
8880 + * This program is free software; you can redistribute it and/or modify it
8881 + * under the terms and conditions of the GNU General Public License,
8882 + * version 2, as published by the Free Software Foundation.
8884 + * This program is distributed in the hope it will be useful, but WITHOUT
8885 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8886 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
8889 + * You should have received a copy of the GNU General Public License along with
8890 + * this program; if not, write to the Free Software Foundation, Inc.,
8891 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
8893 + * Maintained at www.Open-FCoE.org
8899 +#include <linux/netdevice.h>
8900 +#include <linux/skbuff.h>
8901 +#include <scsi/fc/fc_fcoe.h>
8902 +#include <scsi/libfc.h>
8905 + * this percpu struct for fcoe
8907 +struct fcoe_percpu_s {
8909 + struct task_struct *thread;
8910 + struct sk_buff_head fcoe_rx_list;
8911 + struct page *crc_eof_page;
8912 + int crc_eof_offset;
8916 + * the fcoe sw transport private data
8918 +struct fcoe_softc {
8919 + struct list_head list;
8920 + struct fc_lport *lp;
8921 + struct net_device *real_dev;
8922 + struct net_device *phys_dev; /* device with ethtool_ops */
8923 + struct packet_type fcoe_packet_type;
8924 + struct sk_buff_head fcoe_pending_queue;
8925 + u16 user_mfs; /* configured max frame size */
8927 + u8 dest_addr[ETH_ALEN];
8928 + u8 ctl_src_addr[ETH_ALEN];
8929 + u8 data_src_addr[ETH_ALEN];
8931 + * fcoe protocol address learning related stuff
8934 + u8 flogi_progress;
8938 +static inline struct fcoe_softc *fcoe_softc(
8939 + const struct fc_lport *lp)
8941 + return (struct fcoe_softc *)lport_priv(lp);
8944 +static inline struct net_device *fcoe_netdev(
8945 + const struct fc_lport *lp)
8947 + return fcoe_softc(lp)->real_dev;
8950 +static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb)
8952 + return (struct fcoe_hdr *)skb_network_header(skb);
8955 +static inline int skb_fcoe_offset(const struct sk_buff *skb)
8957 + return skb_network_offset(skb);
8960 +static inline struct fc_frame_header *skb_fc_header(const struct sk_buff *skb)
8962 + return (struct fc_frame_header *)skb_transport_header(skb);
8965 +static inline int skb_fc_offset(const struct sk_buff *skb)
8967 + return skb_transport_offset(skb);
8970 +static inline void skb_reset_fc_header(struct sk_buff *skb)
8972 + skb_reset_network_header(skb);
8973 + skb_set_transport_header(skb, skb_network_offset(skb) +
8974 + sizeof(struct fcoe_hdr));
8977 +static inline bool skb_fc_is_data(const struct sk_buff *skb)
8979 + return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_SOL_DATA;
8982 +static inline bool skb_fc_is_cmd(const struct sk_buff *skb)
8984 + return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD;
8987 +static inline bool skb_fc_has_exthdr(const struct sk_buff *skb)
8989 + return (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_VFTH) ||
8990 + (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_IFRH) ||
8991 + (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_ENCH);
8994 +static inline bool skb_fc_is_roff(const struct sk_buff *skb)
8996 + return skb_fc_header(skb)->fh_f_ctl[2] & FC_FC_REL_OFF;
8999 +static inline u16 skb_fc_oxid(const struct sk_buff *skb)
9001 + return be16_to_cpu(skb_fc_header(skb)->fh_ox_id);
9004 +static inline u16 skb_fc_rxid(const struct sk_buff *skb)
9006 + return be16_to_cpu(skb_fc_header(skb)->fh_rx_id);
9009 +/* FIXME - DMA_BIDIRECTIONAL ? */
9010 +#define skb_cb(skb) ((struct fcoe_rcv_info *)&((skb)->cb[0]))
9011 +#define skb_cmd(skb) (skb_cb(skb)->fr_cmd)
9012 +#define skb_dir(skb) (skb_cmd(skb)->sc_data_direction)
9013 +static inline bool skb_fc_is_read(const struct sk_buff *skb)
9015 + if (skb_fc_is_cmd(skb) && skb_cmd(skb))
9016 + return skb_dir(skb) == DMA_FROM_DEVICE;
9020 +static inline bool skb_fc_is_write(const struct sk_buff *skb)
9022 + if (skb_fc_is_cmd(skb) && skb_cmd(skb))
9023 + return skb_dir(skb) == DMA_TO_DEVICE;
9027 +/* libfcoe funcs */
9028 +int fcoe_reset(struct Scsi_Host *shost);
9029 +u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
9030 + unsigned int scheme, unsigned int port);
9032 +u32 fcoe_fc_crc(struct fc_frame *fp);
9033 +int fcoe_xmit(struct fc_lport *, struct fc_frame *);
9034 +int fcoe_rcv(struct sk_buff *, struct net_device *,
9035 + struct packet_type *, struct net_device *);
9037 +int fcoe_percpu_receive_thread(void *arg);
9038 +void fcoe_clean_pending_queue(struct fc_lport *lp);
9039 +void fcoe_percpu_clean(struct fc_lport *lp);
9040 +void fcoe_watchdog(ulong vp);
9041 +int fcoe_link_ok(struct fc_lport *lp);
9043 +struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
9044 +int fcoe_hostlist_add(const struct fc_lport *);
9045 +int fcoe_hostlist_remove(const struct fc_lport *);
9047 +struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int);
9048 +int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *);
9051 +int __init fcoe_sw_init(void);
9052 +int __exit fcoe_sw_exit(void);
9053 +#endif /* _LIBFCOE_H */