]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.drivers/open-fcoe-beta4-update
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.drivers / open-fcoe-beta4-update
CommitLineData
2cb7cef9
BS
1Subject: Open-FCoE: Update for Beta4
2From: John Fastabend <john.r.fastabend@intel.com>
3Date: Thu Nov 6 13:08:49 2008 +0100:
4Git: c66b456a7eb389e5f19d5bf23170b47a3e01d755
5References: bnc#438954
6
7Incremental Open-FCoE update for Beta4.
8
9Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
10Acked-by: Hannes Reinecke <hare@suse.de>
11
12diff --git a/drivers/scsi/fcoe/Makefile b/drivers/scsi/fcoe/Makefile
13index 342e2ad..b78da06 100644
14--- a/drivers/scsi/fcoe/Makefile
15+++ b/drivers/scsi/fcoe/Makefile
16@@ -3,6 +3,6 @@
17 obj-$(CONFIG_FCOE) += fcoe.o
18
19 fcoe-y := \
20- fcoe_dev.o \
21- fcoe_if.o \
22- fcoeinit.o
23+ libfcoe.o \
24+ fcoe_sw.o \
25+ fc_transport_fcoe.o
26diff --git a/drivers/scsi/fcoe/fc_transport_fcoe.c b/drivers/scsi/fcoe/fc_transport_fcoe.c
27new file mode 100644
28index 0000000..e11d36b
29--- /dev/null
30+++ b/drivers/scsi/fcoe/fc_transport_fcoe.c
31@@ -0,0 +1,396 @@
32+/*
33+ * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
34+ *
35+ * This program is free software; you can redistribute it and/or modify it
36+ * under the terms and conditions of the GNU General Public License,
37+ * version 2, as published by the Free Software Foundation.
38+ *
39+ * This program is distributed in the hope it will be useful, but WITHOUT
40+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
41+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
42+ * more details.
43+ *
44+ * You should have received a copy of the GNU General Public License along with
45+ * this program; if not, write to the Free Software Foundation, Inc.,
46+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
47+ *
48+ * Maintained at www.Open-FCoE.org
49+ */
50+
51+#include <linux/module.h>
52+#include <linux/version.h>
53+#include <linux/kernel.h>
54+#include <linux/kthread.h>
55+#include <linux/spinlock.h>
56+#include <linux/cpu.h>
57+#include <linux/netdevice.h>
58+#include <linux/etherdevice.h>
59+#include <linux/ethtool.h>
60+#include <linux/if_ether.h>
61+#include <linux/fs.h>
62+#include <linux/sysfs.h>
63+#include <linux/ctype.h>
64+
65+#include <scsi/libfc/libfc.h>
66+
67+#include "fcoe_def.h"
68+
69+MODULE_AUTHOR("Open-FCoE.org");
70+MODULE_DESCRIPTION("FCoE");
71+MODULE_LICENSE("GPL");
72+
73+/*
74+ * Static functions and variables definations
75+ */
76+#ifdef CONFIG_HOTPLUG_CPU
77+static int fcoe_cpu_callback(struct notifier_block *, ulong, void *);
78+#endif /* CONFIG_HOTPLUG_CPU */
79+static int fcoe_device_notification(struct notifier_block *, ulong, void *);
80+static void fcoe_dev_setup(void);
81+static void fcoe_dev_cleanup(void);
82+
83+#ifdef CONFIG_HOTPLUG_CPU
84+static struct notifier_block fcoe_cpu_notifier = {
85+ .notifier_call = fcoe_cpu_callback,
86+};
87+#endif /* CONFIG_HOTPLUG_CPU */
88+
89+/*
90+ * notification function from net device
91+ */
92+static struct notifier_block fcoe_notifier = {
93+ .notifier_call = fcoe_device_notification,
94+};
95+
96+#ifdef CONFIG_HOTPLUG_CPU
97+/*
98+ * create percpu stats block
99+ * called by cpu add/remove notifier
100+ */
101+static void fcoe_create_percpu_data(int cpu)
102+{
103+ struct fc_lport *lp;
104+ struct fcoe_softc *fc;
105+ struct fcoe_dev_stats *p;
106+
107+ write_lock_bh(&fcoe_hostlist_lock);
108+ list_for_each_entry(fc, &fcoe_hostlist, list) {
109+ lp = fc->lp;
110+ if (lp->dev_stats[cpu] == NULL) {
111+ p = kzalloc(sizeof(struct fcoe_dev_stats), GFP_KERNEL);
112+ if (p)
113+ lp->dev_stats[cpu] = p;
114+ }
115+ }
116+ write_unlock_bh(&fcoe_hostlist_lock);
117+}
118+
119+/*
120+ * destroy percpu stats block
121+ * called by cpu add/remove notifier
122+ */
123+static void fcoe_destroy_percpu_data(int cpu)
124+{
125+ struct fcoe_dev_stats *p;
126+ struct fc_lport *lp;
127+ struct fcoe_softc *fc;
128+
129+ write_lock_bh(&fcoe_hostlist_lock);
130+ list_for_each_entry(fc, &fcoe_hostlist, list) {
131+ lp = fc->lp;
132+ p = lp->dev_stats[cpu];
133+ if (p != NULL) {
134+ lp->dev_stats[cpu] = NULL;
135+ kfree(p);
136+ }
137+ }
138+ write_unlock_bh(&fcoe_hostlist_lock);
139+}
140+
141+/*
142+ * Get notified when a cpu comes on/off. Be hotplug friendly.
143+ */
144+static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
145+ void *hcpu)
146+{
147+ unsigned int cpu = (unsigned long)hcpu;
148+
149+ switch (action) {
150+ case CPU_ONLINE:
151+ fcoe_create_percpu_data(cpu);
152+ break;
153+ case CPU_DEAD:
154+ fcoe_destroy_percpu_data(cpu);
155+ break;
156+ default:
157+ break;
158+ }
159+ return NOTIFY_OK;
160+}
161+#endif /* CONFIG_HOTPLUG_CPU */
162+
163+/*
164+ * function to setup link change notification interface
165+ */
166+static void fcoe_dev_setup(void)
167+{
168+ /*
169+ * here setup a interface specific wd time to
170+ * monitor the link state
171+ */
172+ register_netdevice_notifier(&fcoe_notifier);
173+}
174+
175+/*
176+ * function to cleanup link change notification interface
177+ */
178+static void fcoe_dev_cleanup(void)
179+{
180+ unregister_netdevice_notifier(&fcoe_notifier);
181+}
182+
183+/*
184+ * This function is called by the ethernet driver
185+ * this is called in case of link change event
186+ */
187+static int fcoe_device_notification(struct notifier_block *notifier,
188+ ulong event, void *ptr)
189+{
190+ struct fc_lport *lp = NULL;
191+ struct net_device *real_dev = ptr;
192+ struct fcoe_softc *fc;
193+ struct fcoe_dev_stats *stats;
194+ u16 new_status;
195+ u32 mfs;
196+ int rc = NOTIFY_OK;
197+
198+ read_lock(&fcoe_hostlist_lock);
199+ list_for_each_entry(fc, &fcoe_hostlist, list) {
200+ if (fc->real_dev == real_dev) {
201+ lp = fc->lp;
202+ break;
203+ }
204+ }
205+ read_unlock(&fcoe_hostlist_lock);
206+ if (lp == NULL) {
207+ rc = NOTIFY_DONE;
208+ goto out;
209+ }
210+
211+ new_status = lp->link_status;
212+ switch (event) {
213+ case NETDEV_DOWN:
214+ case NETDEV_GOING_DOWN:
215+ new_status &= ~FC_LINK_UP;
216+ break;
217+ case NETDEV_UP:
218+ case NETDEV_CHANGE:
219+ new_status &= ~FC_LINK_UP;
220+ if (!fcoe_link_ok(lp))
221+ new_status |= FC_LINK_UP;
222+ break;
223+ case NETDEV_CHANGEMTU:
224+ mfs = fc->real_dev->mtu -
225+ (sizeof(struct fcoe_hdr) +
226+ sizeof(struct fcoe_crc_eof));
227+ if (fc->user_mfs && fc->user_mfs < mfs)
228+ mfs = fc->user_mfs;
229+ if (mfs >= FC_MIN_MAX_FRAME)
230+ fc_set_mfs(lp, mfs);
231+ new_status &= ~FC_LINK_UP;
232+ if (!fcoe_link_ok(lp))
233+ new_status |= FC_LINK_UP;
234+ break;
235+ case NETDEV_REGISTER:
236+ break;
237+ default:
238+ FC_DBG("unknown event %ld call", event);
239+ }
240+ if (lp->link_status != new_status) {
241+ if ((new_status & FC_LINK_UP) == FC_LINK_UP)
242+ fc_linkup(lp);
243+ else {
244+ stats = lp->dev_stats[smp_processor_id()];
245+ stats->LinkFailureCount++;
246+ fc_linkdown(lp);
247+ fcoe_clean_pending_queue(lp);
248+ }
249+ }
250+out:
251+ return rc;
252+}
253+
254+static void trimstr(char *str, int len)
255+{
256+ char *cp = str + len;
257+ while (--cp >= str && *cp == '\n')
258+ *cp = '\0';
259+}
260+
261+static ssize_t fcoe_destroy(struct kobject *kobj, struct kobj_attribute *attr,
262+ const char *buffer, size_t size)
263+{
264+ struct net_device *netdev;
265+ char ifname[IFNAMSIZ + 2];
266+
267+ strlcpy(ifname, buffer, IFNAMSIZ);
268+ trimstr(ifname, strlen(ifname));
269+ netdev = dev_get_by_name(&init_net, ifname);
270+ if (netdev) {
271+ fcoe_destroy_interface(netdev);
272+ dev_put(netdev);
273+ }
274+ return size;
275+}
276+
277+static ssize_t fcoe_create(struct kobject *kobj, struct kobj_attribute *attr,
278+ const char *buffer, size_t size)
279+{
280+ struct net_device *netdev;
281+ char ifname[IFNAMSIZ + 2];
282+
283+ strlcpy(ifname, buffer, IFNAMSIZ);
284+ trimstr(ifname, strlen(ifname));
285+ netdev = dev_get_by_name(&init_net, ifname);
286+ if (netdev) {
287+ fcoe_create_interface(netdev);
288+ dev_put(netdev);
289+ }
290+ return size;
291+}
292+
293+static const struct kobj_attribute fcoe_destroyattr = \
294+ __ATTR(destroy, S_IWUSR, NULL, fcoe_destroy);
295+static const struct kobj_attribute fcoe_createattr = \
296+ __ATTR(create, S_IWUSR, NULL, fcoe_create);
297+
298+/*
299+ * Initialization routine
300+ * 1. Will create fc transport software structure
301+ * 2. initialize the link list of port information structure
302+ */
303+static int __init fcoe_init(void)
304+{
305+ int rc = 0;
306+ int cpu;
307+ struct fcoe_percpu_s *p;
308+
309+ rc = sysfs_create_file(&THIS_MODULE->mkobj.kobj,
310+ &fcoe_destroyattr.attr);
311+ if (!rc)
312+ rc = sysfs_create_file(&THIS_MODULE->mkobj.kobj,
313+ &fcoe_createattr.attr);
314+
315+ if (rc)
316+ return rc;
317+
318+ rwlock_init(&fcoe_hostlist_lock);
319+
320+#ifdef CONFIG_HOTPLUG_CPU
321+ register_cpu_notifier(&fcoe_cpu_notifier);
322+#endif /* CONFIG_HOTPLUG_CPU */
323+
324+ /*
325+ * initialize per CPU interrupt thread
326+ */
327+ for_each_online_cpu(cpu) {
328+ p = kzalloc(sizeof(struct fcoe_percpu_s), GFP_KERNEL);
329+ if (p) {
330+ p->thread = kthread_create(fcoe_percpu_receive_thread,
331+ (void *)p,
332+ "fcoethread/%d", cpu);
333+
334+ /*
335+ * if there is no error then bind the thread to the cpu
336+ * initialize the semaphore and skb queue head
337+ */
338+ if (likely(!IS_ERR(p->thread))) {
339+ p->cpu = cpu;
340+ fcoe_percpu[cpu] = p;
341+ skb_queue_head_init(&p->fcoe_rx_list);
342+ kthread_bind(p->thread, cpu);
343+ wake_up_process(p->thread);
344+ } else {
345+ fcoe_percpu[cpu] = NULL;
346+ kfree(p);
347+
348+ }
349+ }
350+ }
351+ if (rc < 0) {
352+ FC_DBG("failed to initialize proc intrerface\n");
353+ rc = -ENODEV;
354+ goto out_chrdev;
355+ }
356+
357+ /*
358+ * setup link change notification
359+ */
360+ fcoe_dev_setup();
361+
362+ init_timer(&fcoe_timer);
363+ fcoe_timer.data = 0;
364+ fcoe_timer.function = fcoe_watchdog;
365+ fcoe_timer.expires = (jiffies + (10 * HZ));
366+ add_timer(&fcoe_timer);
367+
368+ if (fcoe_sw_init() != 0) {
369+ FC_DBG("fail to attach fc transport");
370+ return -1;
371+ }
372+
373+ return 0;
374+
375+out_chrdev:
376+#ifdef CONFIG_HOTPLUG_CPU
377+ unregister_cpu_notifier(&fcoe_cpu_notifier);
378+#endif /* CONFIG_HOTPLUG_CPU */
379+ return rc;
380+}
381+module_init(fcoe_init);
382+
383+static void __exit fcoe_exit(void)
384+{
385+ u32 idx;
386+ struct fcoe_softc *fc, *tmp;
387+ struct fcoe_percpu_s *p;
388+ struct sk_buff *skb;
389+
390+ /*
391+ * Stop all call back interfaces
392+ */
393+#ifdef CONFIG_HOTPLUG_CPU
394+ unregister_cpu_notifier(&fcoe_cpu_notifier);
395+#endif /* CONFIG_HOTPLUG_CPU */
396+ fcoe_dev_cleanup();
397+
398+ /*
399+ * stop timer
400+ */
401+ del_timer_sync(&fcoe_timer);
402+
403+ /*
404+ * assuming that at this time there will be no
405+ * ioctl in prograss, therefore we do not need to lock the
406+ * list.
407+ */
408+ list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
409+ fcoe_destroy_interface(fc->real_dev);
410+
411+ for (idx = 0; idx < NR_CPUS; idx++) {
412+ if (fcoe_percpu[idx]) {
413+ kthread_stop(fcoe_percpu[idx]->thread);
414+ p = fcoe_percpu[idx];
415+ spin_lock_bh(&p->fcoe_rx_list.lock);
416+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
417+ kfree_skb(skb);
418+ spin_unlock_bh(&p->fcoe_rx_list.lock);
419+ if (fcoe_percpu[idx]->crc_eof_page)
420+ put_page(fcoe_percpu[idx]->crc_eof_page);
421+ kfree(fcoe_percpu[idx]);
422+ }
423+ }
424+
425+ fcoe_sw_exit();
426+}
427+module_exit(fcoe_exit);
428diff --git a/drivers/scsi/fcoe/fcoe_def.h b/drivers/scsi/fcoe/fcoe_def.h
429index 12bf69c..b00e14b 100644
430--- a/drivers/scsi/fcoe/fcoe_def.h
431+++ b/drivers/scsi/fcoe/fcoe_def.h
432@@ -1,5 +1,5 @@
433 /*
434- * Copyright(c) 2007 Intel Corporation. All rights reserved.
435+ * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
436 *
437 * This program is free software; you can redistribute it and/or modify it
438 * under the terms and conditions of the GNU General Public License,
439@@ -48,16 +48,10 @@ struct fcoe_percpu_s {
440 int crc_eof_offset;
441 };
442
443-struct fcoe_info {
444- struct timer_list timer;
445- /*
446- * fcoe host list is protected by the following read/write lock
447- */
448- rwlock_t fcoe_hostlist_lock;
449- struct list_head fcoe_hostlist;
450-
451- struct fcoe_percpu_s *fcoe_percpu[NR_CPUS];
452-};
453+extern struct timer_list fcoe_timer;
454+extern rwlock_t fcoe_hostlist_lock;
455+extern struct list_head fcoe_hostlist;
456+extern struct fcoe_percpu_s *fcoe_percpu[];
457
458 struct fcoe_softc {
459 struct list_head list;
460@@ -79,22 +73,20 @@ struct fcoe_softc {
461 u8 address_mode;
462 };
463
464-extern int debug_fcoe;
465-extern struct fcoe_percpu_s *fcoe_percpu[];
466-extern struct scsi_transport_template *fcoe_transport_template;
467 int fcoe_percpu_receive_thread(void *arg);
468
469 /*
470 * HBA transport ops prototypes
471 */
472-extern struct fcoe_info fcoei;
473-
474 void fcoe_clean_pending_queue(struct fc_lport *fd);
475 void fcoe_watchdog(ulong vp);
476-int fcoe_destroy_interface(const char *ifname);
477-int fcoe_create_interface(const char *ifname);
478+int fcoe_destroy_interface(struct net_device *);
479+int fcoe_create_interface(struct net_device *);
480 int fcoe_xmit(struct fc_lport *, struct fc_frame *);
481 int fcoe_rcv(struct sk_buff *, struct net_device *,
482 struct packet_type *, struct net_device *);
483 int fcoe_link_ok(struct fc_lport *);
484+
485+int __init fcoe_sw_init(void);
486+void __exit fcoe_sw_exit(void);
487 #endif /* _FCOE_DEF_H_ */
488diff --git a/drivers/scsi/fcoe/fcoe_dev.c b/drivers/scsi/fcoe/fcoe_dev.c
489deleted file mode 100644
490index d5a354f..0000000
491--- a/drivers/scsi/fcoe/fcoe_dev.c
492+++ /dev/null
493@@ -1,633 +0,0 @@
494-/*
495- * Copyright(c) 2007 Intel Corporation. All rights reserved.
496- *
497- * This program is free software; you can redistribute it and/or modify it
498- * under the terms and conditions of the GNU General Public License,
499- * version 2, as published by the Free Software Foundation.
500- *
501- * This program is distributed in the hope it will be useful, but WITHOUT
502- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
503- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
504- * more details.
505- *
506- * You should have received a copy of the GNU General Public License along with
507- * this program; if not, write to the Free Software Foundation, Inc.,
508- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
509- *
510- * Maintained at www.Open-FCoE.org
511- */
512-
513-/*
514- * FCOE protocol file
515- */
516-
517-#include <linux/module.h>
518-#include <linux/version.h>
519-#include <linux/kernel.h>
520-#include <linux/spinlock.h>
521-#include <linux/skbuff.h>
522-#include <linux/netdevice.h>
523-#include <linux/etherdevice.h>
524-#include <linux/if_ether.h>
525-#include <linux/kthread.h>
526-#include <linux/crc32.h>
527-#include <scsi/scsi_tcq.h>
528-#include <scsi/scsicam.h>
529-#include <scsi/scsi_transport.h>
530-#include <scsi/scsi_transport_fc.h>
531-#include <net/rtnetlink.h>
532-
533-#include <scsi/fc/fc_encaps.h>
534-
535-#include <scsi/libfc/libfc.h>
536-#include <scsi/libfc/fc_frame.h>
537-
538-#include <scsi/fc/fc_fcoe.h>
539-#include "fcoe_def.h"
540-
541-#define FCOE_MAX_QUEUE_DEPTH 256
542-
543-/* destination address mode */
544-#define FCOE_GW_ADDR_MODE 0x00
545-#define FCOE_FCOUI_ADDR_MODE 0x01
546-
547-/* Function Prototyes */
548-static int fcoe_check_wait_queue(struct fc_lport *);
549-static void fcoe_insert_wait_queue_head(struct fc_lport *, struct sk_buff *);
550-static void fcoe_insert_wait_queue(struct fc_lport *, struct sk_buff *);
551-static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *);
552-
553-/*
554- * this is the fcoe receive function
555- * called by NET_RX_SOFTIRQ
556- * this function will receive the packet and
557- * build fc frame and pass it up
558- */
559-int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
560- struct packet_type *ptype, struct net_device *olddev)
561-{
562- struct fc_lport *lp;
563- struct fcoe_rcv_info *fr;
564- struct fcoe_softc *fc;
565- struct fcoe_dev_stats *stats;
566- u8 *data;
567- struct fc_frame_header *fh;
568- unsigned short oxid;
569- int cpu_idx;
570- struct fcoe_percpu_s *fps;
571- struct fcoe_info *fci = &fcoei;
572-
573- fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type);
574- lp = fc->lp;
575- if (unlikely(lp == NULL)) {
576- FC_DBG("cannot find hba structure");
577- goto err2;
578- }
579-
580- if (unlikely(debug_fcoe)) {
581- FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p tail:%p "
582- "end:%p sum:%d dev:%s", skb->len, skb->data_len,
583- skb->head, skb->data, skb_tail_pointer(skb),
584- skb_end_pointer(skb), skb->csum,
585- skb->dev ? skb->dev->name : "<NULL>");
586-
587- }
588-
589- /* check for FCOE packet type */
590- if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
591- FC_DBG("wrong FC type frame");
592- goto err;
593- }
594- data = skb->data;
595- data += sizeof(struct fcoe_hdr);
596- fh = (struct fc_frame_header *)data;
597- oxid = ntohs(fh->fh_ox_id);
598-
599- fr = fcoe_dev_from_skb(skb);
600- fr->fr_dev = lp;
601- fr->ptype = ptype;
602- cpu_idx = 0;
603-#ifdef CONFIG_SMP
604- /*
605- * The exchange ID are ANDed with num of online CPUs,
606- * so that will have the least lock contention in
607- * handling the exchange. if there is no thread
608- * for a given idx then use first online cpu.
609- */
610- cpu_idx = oxid & (num_online_cpus() >> 1);
611- if (fci->fcoe_percpu[cpu_idx] == NULL)
612- cpu_idx = first_cpu(cpu_online_map);
613-#endif
614- fps = fci->fcoe_percpu[cpu_idx];
615-
616- spin_lock_bh(&fps->fcoe_rx_list.lock);
617- __skb_queue_tail(&fps->fcoe_rx_list, skb);
618- if (fps->fcoe_rx_list.qlen == 1)
619- wake_up_process(fps->thread);
620-
621- spin_unlock_bh(&fps->fcoe_rx_list.lock);
622-
623- return 0;
624-err:
625-#ifdef CONFIG_SMP
626- stats = lp->dev_stats[smp_processor_id()];
627-#else
628- stats = lp->dev_stats[0];
629-#endif
630- stats->ErrorFrames++;
631-
632-err2:
633- kfree_skb(skb);
634- return -1;
635-}
636-
637-static inline int fcoe_start_io(struct sk_buff *skb)
638-{
639- int rc;
640-
641- skb_get(skb);
642- rc = dev_queue_xmit(skb);
643- if (rc != 0)
644- return rc;
645- kfree_skb(skb);
646- return 0;
647-}
648-
649-static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
650-{
651- struct fcoe_info *fci = &fcoei;
652- struct fcoe_percpu_s *fps;
653- struct page *page;
654- int cpu_idx;
655-
656- cpu_idx = get_cpu();
657- fps = fci->fcoe_percpu[cpu_idx];
658- page = fps->crc_eof_page;
659- if (!page) {
660- page = alloc_page(GFP_ATOMIC);
661- if (!page) {
662- put_cpu();
663- return -ENOMEM;
664- }
665- fps->crc_eof_page = page;
666- WARN_ON(fps->crc_eof_offset != 0);
667- }
668-
669- get_page(page);
670- skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
671- fps->crc_eof_offset, tlen);
672- skb->len += tlen;
673- skb->data_len += tlen;
674- skb->truesize += tlen;
675- fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
676-
677- if (fps->crc_eof_offset >= PAGE_SIZE) {
678- fps->crc_eof_page = NULL;
679- fps->crc_eof_offset = 0;
680- put_page(page);
681- }
682- put_cpu();
683- return 0;
684-}
685-
686-/*
687- * this is the frame xmit routine
688- */
689-int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
690-{
691- int indx;
692- int wlen, rc = 0;
693- u32 crc;
694- struct ethhdr *eh;
695- struct fcoe_crc_eof *cp;
696- struct sk_buff *skb;
697- struct fcoe_dev_stats *stats;
698- struct fc_frame_header *fh;
699- unsigned int hlen; /* header length implies the version */
700- unsigned int tlen; /* trailer length */
701- int flogi_in_progress = 0;
702- struct fcoe_softc *fc;
703- void *data;
704- u8 sof, eof;
705- struct fcoe_hdr *hp;
706-
707- WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
708-
709- fc = (struct fcoe_softc *)lp->drv_priv;
710- /*
711- * if it is a flogi then we need to learn gw-addr
712- * and my own fcid
713- */
714- fh = fc_frame_header_get(fp);
715- if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) {
716- if (fc_frame_payload_op(fp) == ELS_FLOGI) {
717- fc->flogi_oxid = ntohs(fh->fh_ox_id);
718- fc->address_mode = FCOE_FCOUI_ADDR_MODE;
719- fc->flogi_progress = 1;
720- flogi_in_progress = 1;
721- } else if (fc->flogi_progress && ntoh24(fh->fh_s_id) != 0) {
722- /*
723- * Here we must've gotten an SID by accepting an FLOGI
724- * from a point-to-point connection. Switch to using
725- * the source mac based on the SID. The destination
726- * MAC in this case would have been set by receving the
727- * FLOGI.
728- */
729- fc_fcoe_set_mac(fc->data_src_addr, fh->fh_s_id);
730- fc->flogi_progress = 0;
731- }
732- }
733-
734- skb = fp_skb(fp);
735- sof = fr_sof(fp);
736- eof = fr_eof(fp);
737-
738- crc = ~0;
739- crc = crc32(crc, skb->data, skb_headlen(skb));
740-
741- for (indx = 0; indx < skb_shinfo(skb)->nr_frags; indx++) {
742- skb_frag_t *frag = &skb_shinfo(skb)->frags[indx];
743- unsigned long off = frag->page_offset;
744- unsigned long len = frag->size;
745-
746- while (len > 0) {
747- unsigned long clen;
748-
749- clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
750- data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
751- KM_SKB_DATA_SOFTIRQ);
752- crc = crc32(crc, data + (off & ~PAGE_MASK),
753- clen);
754- kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
755- off += clen;
756- len -= clen;
757- }
758- }
759-
760- /*
761- * Get header and trailer lengths.
762- * This is temporary code until we get rid of the old protocol.
763- * Both versions have essentially the same trailer layout but T11
764- * has padding afterwards.
765- */
766- hlen = sizeof(struct fcoe_hdr);
767- tlen = sizeof(struct fcoe_crc_eof);
768-
769- /*
770- * copy fc crc and eof to the skb buff
771- * Use utility buffer in the fc_frame part of the sk_buff for the
772- * trailer.
773- * We don't do a get_page for this frag, since that page may not be
774- * managed that way. So that skb_free() doesn't do that either, we
775- * setup the destructor to remove this frag.
776- */
777- if (skb_is_nonlinear(skb)) {
778- skb_frag_t *frag;
779- if (fcoe_get_paged_crc_eof(skb, tlen)) {
780- kfree(skb);
781- return -ENOMEM;
782- }
783- frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
784- cp = kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ)
785- + frag->page_offset;
786- } else {
787- cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
788- }
789-
790- cp->fcoe_eof = eof;
791- cp->fcoe_crc32 = cpu_to_le32(~crc);
792- if (tlen == sizeof(*cp))
793- memset(cp->fcoe_resvd, 0, sizeof(cp->fcoe_resvd));
794- wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
795-
796- if (skb_is_nonlinear(skb)) {
797- kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
798- cp = NULL;
799- }
800-
801- /*
802- * Fill in the control structures
803- */
804- skb->ip_summed = CHECKSUM_NONE;
805- eh = (struct ethhdr *)skb_push(skb, hlen + sizeof(struct ethhdr));
806- if (fc->address_mode == FCOE_FCOUI_ADDR_MODE)
807- fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
808- else
809- /* insert GW address */
810- memcpy(eh->h_dest, fc->dest_addr, ETH_ALEN);
811-
812- if (unlikely(flogi_in_progress))
813- memcpy(eh->h_source, fc->ctl_src_addr, ETH_ALEN);
814- else
815- memcpy(eh->h_source, fc->data_src_addr, ETH_ALEN);
816-
817- eh->h_proto = htons(ETH_P_FCOE);
818- skb->protocol = htons(ETH_P_802_3);
819- skb_reset_mac_header(skb);
820- skb_reset_network_header(skb);
821-
822- hp = (struct fcoe_hdr *)(eh + 1);
823- memset(hp, 0, sizeof(*hp));
824- if (FC_FCOE_VER)
825- FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
826- hp->fcoe_sof = sof;
827-
828- stats = lp->dev_stats[smp_processor_id()];
829- stats->TxFrames++;
830- stats->TxWords += wlen;
831- skb->dev = fc->real_dev;
832-
833- fr_dev(fp) = lp;
834- if (fc->fcoe_pending_queue.qlen)
835- rc = fcoe_check_wait_queue(lp);
836-
837- if (rc == 0)
838- rc = fcoe_start_io(skb);
839-
840- if (rc) {
841- fcoe_insert_wait_queue(lp, skb);
842- if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
843- fc_pause(lp);
844- }
845-
846- return 0;
847-}
848-
849-int fcoe_percpu_receive_thread(void *arg)
850-{
851- struct fcoe_percpu_s *p = arg;
852- u32 fr_len;
853- unsigned int hlen;
854- unsigned int tlen;
855- struct fc_lport *lp;
856- struct fcoe_rcv_info *fr;
857- struct fcoe_dev_stats *stats;
858- struct fc_frame_header *fh;
859- struct sk_buff *skb;
860- struct fcoe_crc_eof *cp;
861- enum fc_sof sof;
862- struct fc_frame *fp;
863- u8 *mac = NULL;
864- struct fcoe_softc *fc;
865- struct fcoe_hdr *hp;
866-
867- set_user_nice(current, 19);
868-
869- while (!kthread_should_stop()) {
870-
871- spin_lock_bh(&p->fcoe_rx_list.lock);
872- while ((skb = __skb_dequeue(&p->fcoe_rx_list)) == NULL) {
873- set_current_state(TASK_INTERRUPTIBLE);
874- spin_unlock_bh(&p->fcoe_rx_list.lock);
875- schedule();
876- set_current_state(TASK_RUNNING);
877- if (kthread_should_stop())
878- return 0;
879- spin_lock_bh(&p->fcoe_rx_list.lock);
880- }
881- spin_unlock_bh(&p->fcoe_rx_list.lock);
882- fr = fcoe_dev_from_skb(skb);
883- lp = fr->fr_dev;
884- if (unlikely(lp == NULL)) {
885- FC_DBG("invalid HBA Structure");
886- kfree_skb(skb);
887- continue;
888- }
889-
890- stats = lp->dev_stats[smp_processor_id()];
891-
892- if (unlikely(debug_fcoe)) {
893- FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p "
894- "tail:%p end:%p sum:%d dev:%s",
895- skb->len, skb->data_len,
896- skb->head, skb->data, skb_tail_pointer(skb),
897- skb_end_pointer(skb), skb->csum,
898- skb->dev ? skb->dev->name : "<NULL>");
899- }
900-
901- /*
902- * Save source MAC address before discarding header.
903- */
904- fc = lp->drv_priv;
905- if (unlikely(fc->flogi_progress))
906- mac = eth_hdr(skb)->h_source;
907-
908- if (skb_is_nonlinear(skb))
909- skb_linearize(skb); /* not ideal */
910-
911- /*
912- * Check the header and pull it off.
913- */
914- hlen = sizeof(struct fcoe_hdr);
915-
916- hp = (struct fcoe_hdr *)skb->data;
917- if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
918- if (stats->ErrorFrames < 5)
919- FC_DBG("unknown FCoE version %x",
920- FC_FCOE_DECAPS_VER(hp));
921- stats->ErrorFrames++;
922- kfree_skb(skb);
923- continue;
924- }
925- sof = hp->fcoe_sof;
926- skb_pull(skb, sizeof(*hp));
927- fr_len = skb->len - sizeof(struct fcoe_crc_eof);
928- skb_trim(skb, fr_len);
929- tlen = sizeof(struct fcoe_crc_eof);
930-
931- if (unlikely(fr_len > skb->len)) {
932- if (stats->ErrorFrames < 5)
933- FC_DBG("length error fr_len 0x%x skb->len 0x%x",
934- fr_len, skb->len);
935- stats->ErrorFrames++;
936- kfree_skb(skb);
937- continue;
938- }
939- stats->RxFrames++;
940- stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
941-
942- fp = (struct fc_frame *) skb;
943- fc_frame_init(fp);
944- cp = (struct fcoe_crc_eof *)(skb->data + fr_len);
945- fr_eof(fp) = cp->fcoe_eof;
946- fr_sof(fp) = sof;
947- fr_dev(fp) = lp;
948-
949- /*
950- * Check the CRC here, unless it's solicited data for SCSI.
951- * In that case, the SCSI layer can check it during the copy,
952- * and it'll be more cache-efficient.
953- */
954- fh = fc_frame_header_get(fp);
955- if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
956- fh->fh_type == FC_TYPE_FCP) {
957- fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
958- fc_exch_recv(lp, lp->emp, fp);
959- } else if (le32_to_cpu(cp->fcoe_crc32) ==
960- ~crc32(~0, skb->data, fr_len)) {
961- if (unlikely(fc->flogi_progress))
962- fcoe_recv_flogi(fc, fp, mac);
963- fc_exch_recv(lp, lp->emp, fp);
964- } else {
965- if (debug_fcoe || stats->InvalidCRCCount < 5) {
966- printk(KERN_WARNING \
967- "fcoe: dropping frame with CRC error");
968- }
969- stats->InvalidCRCCount++;
970- stats->ErrorFrames++;
971- fc_frame_free(fp);
972- }
973- }
974- return 0;
975-}
976-
977-/*
978- * Snoop potential response to FLOGI or even incoming FLOGI.
979- */
980-static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa)
981-{
982- struct fc_frame_header *fh;
983- u8 op;
984-
985- fh = fc_frame_header_get(fp);
986- if (fh->fh_type != FC_TYPE_ELS)
987- return;
988- op = fc_frame_payload_op(fp);
989- if (op == ELS_LS_ACC && fh->fh_r_ctl == FC_RCTL_ELS_REP &&
990- fc->flogi_oxid == ntohs(fh->fh_ox_id)) {
991- /*
992- * FLOGI accepted.
993- * If the src mac addr is FC_OUI-based, then we mark the
994- * address_mode flag to use FC_OUI-based Ethernet DA.
995- * Otherwise we use the FCoE gateway addr
996- */
997- if (!compare_ether_addr(sa, (u8[6]) FC_FCOE_FLOGI_MAC)) {
998- fc->address_mode = FCOE_FCOUI_ADDR_MODE;
999- } else {
1000- memcpy(fc->dest_addr, sa, ETH_ALEN);
1001- fc->address_mode = FCOE_GW_ADDR_MODE;
1002- }
1003-
1004- /*
1005- * Remove any previously-set unicast MAC filter.
1006- * Add secondary FCoE MAC address filter for our OUI.
1007- */
1008- rtnl_lock();
1009- if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
1010- dev_unicast_delete(fc->real_dev, fc->data_src_addr,
1011- ETH_ALEN);
1012- fc_fcoe_set_mac(fc->data_src_addr, fh->fh_d_id);
1013- dev_unicast_add(fc->real_dev, fc->data_src_addr, ETH_ALEN);
1014- rtnl_unlock();
1015-
1016- fc->flogi_progress = 0;
1017- } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
1018- /*
1019- * Save source MAC for point-to-point responses.
1020- */
1021- memcpy(fc->dest_addr, sa, ETH_ALEN);
1022- fc->address_mode = FCOE_GW_ADDR_MODE;
1023- }
1024-}
1025-
1026-void fcoe_watchdog(ulong vp)
1027-{
1028- struct fc_lport *lp;
1029- struct fcoe_softc *fc;
1030- struct fcoe_info *fci = &fcoei;
1031- int paused = 0;
1032-
1033- read_lock(&fci->fcoe_hostlist_lock);
1034- list_for_each_entry(fc, &fci->fcoe_hostlist, list) {
1035- lp = fc->lp;
1036- if (lp) {
1037- if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
1038- paused = 1;
1039- if (fcoe_check_wait_queue(lp) < FCOE_MAX_QUEUE_DEPTH) {
1040- if (paused)
1041- fc_unpause(lp);
1042- }
1043- }
1044- }
1045- read_unlock(&fci->fcoe_hostlist_lock);
1046-
1047- fci->timer.expires = jiffies + (1 * HZ);
1048- add_timer(&fci->timer);
1049-}
1050-
1051-/*
1052- * the wait_queue is used when the skb transmit fails. skb will go
1053- * in the wait_queue which will be emptied by the time function OR
1054- * by the next skb transmit.
1055- *
1056- */
1057-
1058-/*
1059- * Function name : fcoe_check_wait_queue()
1060- *
1061- * Return Values : 0 or error
1062- *
1063- * Description : empties the wait_queue
1064- * dequeue the head of the wait_queue queue and
1065- * calls fcoe_start_io() for each packet
1066- * if all skb have been transmitted, return 0
1067- * if a error occurs, then restore wait_queue and try again
1068- * later
1069- *
1070- */
1071-
1072-static int fcoe_check_wait_queue(struct fc_lport *lp)
1073-{
1074- int rc, unpause = 0;
1075- int paused = 0;
1076- struct sk_buff *skb;
1077- struct fcoe_softc *fc;
1078-
1079- fc = (struct fcoe_softc *)lp->drv_priv;
1080- spin_lock_bh(&fc->fcoe_pending_queue.lock);
1081-
1082- /*
1083- * is this interface paused?
1084- */
1085- if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
1086- paused = 1;
1087- if (fc->fcoe_pending_queue.qlen) {
1088- while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
1089- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1090- rc = fcoe_start_io(skb);
1091- if (rc) {
1092- fcoe_insert_wait_queue_head(lp, skb);
1093- return rc;
1094- }
1095- spin_lock_bh(&fc->fcoe_pending_queue.lock);
1096- }
1097- if (fc->fcoe_pending_queue.qlen < FCOE_MAX_QUEUE_DEPTH)
1098- unpause = 1;
1099- }
1100- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1101- if ((unpause) && (paused))
1102- fc_unpause(lp);
1103- return fc->fcoe_pending_queue.qlen;
1104-}
1105-
1106-static void fcoe_insert_wait_queue_head(struct fc_lport *lp,
1107- struct sk_buff *skb)
1108-{
1109- struct fcoe_softc *fc;
1110-
1111- fc = (struct fcoe_softc *)lp->drv_priv;
1112- spin_lock_bh(&fc->fcoe_pending_queue.lock);
1113- __skb_queue_head(&fc->fcoe_pending_queue, skb);
1114- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1115-}
1116-
1117-static void fcoe_insert_wait_queue(struct fc_lport *lp,
1118- struct sk_buff *skb)
1119-{
1120- struct fcoe_softc *fc;
1121-
1122- fc = (struct fcoe_softc *)lp->drv_priv;
1123- spin_lock_bh(&fc->fcoe_pending_queue.lock);
1124- __skb_queue_tail(&fc->fcoe_pending_queue, skb);
1125- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1126-}
1127diff --git a/drivers/scsi/fcoe/fcoe_if.c b/drivers/scsi/fcoe/fcoe_if.c
1128deleted file mode 100644
1129index 73b83ce..0000000
1130--- a/drivers/scsi/fcoe/fcoe_if.c
1131+++ /dev/null
1132@@ -1,496 +0,0 @@
1133-/*
1134- * Copyright(c) 2007 Intel Corporation. All rights reserved.
1135- *
1136- * This program is free software; you can redistribute it and/or modify it
1137- * under the terms and conditions of the GNU General Public License,
1138- * version 2, as published by the Free Software Foundation.
1139- *
1140- * This program is distributed in the hope it will be useful, but WITHOUT
1141- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1142- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
1143- * more details.
1144- *
1145- * You should have received a copy of the GNU General Public License along with
1146- * this program; if not, write to the Free Software Foundation, Inc.,
1147- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1148- *
1149- * Maintained at www.Open-FCoE.org
1150- */
1151-
1152-/*
1153- * FCOE protocol file
1154- */
1155-
1156-#include <linux/module.h>
1157-#include <linux/version.h>
1158-#include <linux/kernel.h>
1159-#include <linux/init.h>
1160-#include <linux/spinlock.h>
1161-#include <linux/netdevice.h>
1162-#include <linux/etherdevice.h>
1163-#include <linux/ethtool.h>
1164-#include <linux/if_ether.h>
1165-#include <linux/if_vlan.h>
1166-#include <net/rtnetlink.h>
1167-
1168-#include <scsi/fc/fc_els.h>
1169-#include <scsi/fc/fc_encaps.h>
1170-#include <scsi/fc/fc_fs.h>
1171-#include <scsi/scsi_transport.h>
1172-#include <scsi/scsi_transport_fc.h>
1173-
1174-#include <scsi/libfc/libfc.h>
1175-
1176-#include <scsi/fc/fc_fcoe.h>
1177-#include "fcoe_def.h"
1178-
1179-#define FCOE_VERSION "0.1"
1180-
1181-#define FCOE_MAX_LUN 255
1182-#define FCOE_MAX_FCP_TARGET 256
1183-
1184-#define FCOE_MIN_XID 0x0004
1185-#define FCOE_MAX_XID 0x07ef
1186-
1187-int debug_fcoe;
1188-
1189-struct fcoe_info fcoei = {
1190- .fcoe_hostlist = LIST_HEAD_INIT(fcoei.fcoe_hostlist),
1191-};
1192-
1193-static struct fcoe_softc *fcoe_find_fc_lport(const char *name)
1194-{
1195- struct fcoe_softc *fc;
1196- struct fc_lport *lp;
1197- struct fcoe_info *fci = &fcoei;
1198-
1199- read_lock(&fci->fcoe_hostlist_lock);
1200- list_for_each_entry(fc, &fci->fcoe_hostlist, list) {
1201- lp = fc->lp;
1202- if (!strncmp(name, lp->ifname, IFNAMSIZ)) {
1203- read_unlock(&fci->fcoe_hostlist_lock);
1204- return fc;
1205- }
1206- }
1207- read_unlock(&fci->fcoe_hostlist_lock);
1208- return NULL;
1209-}
1210-
1211-/*
1212- * Convert 48-bit IEEE MAC address to 64-bit FC WWN.
1213- */
1214-static u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
1215- unsigned int scheme, unsigned int port)
1216-{
1217- u64 wwn;
1218- u64 host_mac;
1219-
1220- /* The MAC is in NO, so flip only the low 48 bits */
1221- host_mac = ((u64) mac[0] << 40) |
1222- ((u64) mac[1] << 32) |
1223- ((u64) mac[2] << 24) |
1224- ((u64) mac[3] << 16) |
1225- ((u64) mac[4] << 8) |
1226- (u64) mac[5];
1227-
1228- WARN_ON(host_mac >= (1ULL << 48));
1229- wwn = host_mac | ((u64) scheme << 60);
1230- switch (scheme) {
1231- case 1:
1232- WARN_ON(port != 0);
1233- break;
1234- case 2:
1235- WARN_ON(port >= 0xfff);
1236- wwn |= (u64) port << 48;
1237- break;
1238- default:
1239- WARN_ON(1);
1240- break;
1241- }
1242-
1243- return wwn;
1244-}
1245-
1246-static struct scsi_host_template fcoe_driver_template = {
1247- .module = THIS_MODULE,
1248- .name = "FCoE Driver",
1249- .proc_name = FCOE_DRIVER_NAME,
1250- .queuecommand = fc_queuecommand,
1251- .eh_abort_handler = fc_eh_abort,
1252- .eh_device_reset_handler = fc_eh_device_reset,
1253- .eh_host_reset_handler = fc_eh_host_reset,
1254- .slave_alloc = fc_slave_alloc,
1255- .change_queue_depth = fc_change_queue_depth,
1256- .change_queue_type = fc_change_queue_type,
1257- .this_id = -1,
1258- .cmd_per_lun = 32,
1259- .can_queue = FC_MAX_OUTSTANDING_COMMANDS,
1260- .use_clustering = ENABLE_CLUSTERING,
1261- .sg_tablesize = 4,
1262- .max_sectors = 0xffff,
1263-};
1264-
1265-int fcoe_destroy_interface(const char *ifname)
1266-{
1267- int cpu, idx;
1268- struct fcoe_dev_stats *p;
1269- struct fcoe_percpu_s *pp;
1270- struct fcoe_softc *fc;
1271- struct fcoe_rcv_info *fr;
1272- struct fcoe_info *fci = &fcoei;
1273- struct sk_buff_head *list;
1274- struct sk_buff *skb, *next;
1275- struct sk_buff *head;
1276- struct fc_lport *lp;
1277- u8 flogi_maddr[ETH_ALEN];
1278-
1279- fc = fcoe_find_fc_lport(ifname);
1280- if (!fc)
1281- return -ENODEV;
1282-
1283- lp = fc->lp;
1284-
1285- /* Remove the instance from fcoe's list */
1286- write_lock_bh(&fci->fcoe_hostlist_lock);
1287- list_del(&fc->list);
1288- write_unlock_bh(&fci->fcoe_hostlist_lock);
1289-
1290- /* Don't listen for Ethernet packets anymore */
1291- dev_remove_pack(&fc->fcoe_packet_type);
1292-
1293- /* Detach from the scsi-ml */
1294- fc_remove_host(lp->host);
1295- scsi_remove_host(lp->host);
1296-
1297- /* Cleanup the fc_lport */
1298- fc_lport_destroy(lp);
1299- fc_fcp_destroy(lp);
1300- if (lp->emp)
1301- fc_exch_mgr_free(lp->emp);
1302-
1303- /* Delete secondary MAC addresses */
1304- rtnl_lock();
1305- memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
1306- dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
1307- if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
1308- dev_unicast_delete(fc->real_dev, fc->data_src_addr, ETH_ALEN);
1309- rtnl_unlock();
1310-
1311- /* Free the per-CPU revieve threads */
1312- for (idx = 0; idx < NR_CPUS; idx++) {
1313- if (fci->fcoe_percpu[idx]) {
1314- pp = fci->fcoe_percpu[idx];
1315- spin_lock_bh(&pp->fcoe_rx_list.lock);
1316- list = &pp->fcoe_rx_list;
1317- head = list->next;
1318- for (skb = head; skb != (struct sk_buff *)list;
1319- skb = next) {
1320- next = skb->next;
1321- fr = fcoe_dev_from_skb(skb);
1322- if (fr->fr_dev == fc->lp) {
1323- __skb_unlink(skb, list);
1324- kfree_skb(skb);
1325- }
1326- }
1327- spin_unlock_bh(&pp->fcoe_rx_list.lock);
1328- }
1329- }
1330-
1331- /* Free existing skbs */
1332- fcoe_clean_pending_queue(lp);
1333-
1334- /* Free memory used by statistical counters */
1335- for_each_online_cpu(cpu) {
1336- p = lp->dev_stats[cpu];
1337- if (p) {
1338- lp->dev_stats[cpu] = NULL;
1339- kfree(p);
1340- }
1341- }
1342-
1343- /* Release the net_device and Scsi_Host */
1344- dev_put(fc->real_dev);
1345- scsi_host_put(lp->host);
1346- return 0;
1347-}
1348-
1349-/*
1350- * Return zero if link is OK for use by FCoE.
1351- * Any permanently-disqualifying conditions have been previously checked.
1352- * This also updates the speed setting, which may change with link for 100/1000.
1353- *
1354- * This function should probably be checking for PAUSE support at some point
1355- * in the future. Currently Per-priority-pause is not determinable using
1356- * ethtool, so we shouldn't be restrictive until that problem is resolved.
1357- */
1358-int fcoe_link_ok(struct fc_lport *lp)
1359-{
1360- struct fcoe_softc *fc = (struct fcoe_softc *)lp->drv_priv;
1361- struct net_device *dev = fc->real_dev;
1362- struct ethtool_cmd ecmd = { ETHTOOL_GSET };
1363- int rc = 0;
1364-
1365- if ((dev->flags & IFF_UP) && netif_carrier_ok(dev)) {
1366- dev = fc->phys_dev;
1367- if (dev->ethtool_ops->get_settings) {
1368- dev->ethtool_ops->get_settings(dev, &ecmd);
1369- lp->link_supported_speeds &=
1370- ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
1371- if (ecmd.supported & (SUPPORTED_1000baseT_Half |
1372- SUPPORTED_1000baseT_Full))
1373- lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
1374- if (ecmd.supported & SUPPORTED_10000baseT_Full)
1375- lp->link_supported_speeds |=
1376- FC_PORTSPEED_10GBIT;
1377- if (ecmd.speed == SPEED_1000)
1378- lp->link_speed = FC_PORTSPEED_1GBIT;
1379- if (ecmd.speed == SPEED_10000)
1380- lp->link_speed = FC_PORTSPEED_10GBIT;
1381- }
1382- } else
1383- rc = -1;
1384-
1385- return rc;
1386-}
1387-
1388-static struct libfc_function_template fcoe_libfc_fcn_templ = {
1389- .frame_send = fcoe_xmit,
1390-};
1391-
1392-static int lport_config(struct fc_lport *lp, struct Scsi_Host *shost)
1393-{
1394- int i = 0;
1395- struct fcoe_dev_stats *p;
1396-
1397- lp->host = shost;
1398- lp->drv_priv = (void *)(lp + 1);
1399-
1400- lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
1401- FCOE_MIN_XID, FCOE_MAX_XID);
1402- if (!lp->emp)
1403- return -ENOMEM;
1404-
1405- lp->link_status = 0;
1406- lp->max_retry_count = 3;
1407- lp->e_d_tov = 2 * 1000; /* FC-FS default */
1408- lp->r_a_tov = 2 * 2 * 1000;
1409- lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
1410- FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
1411-
1412- /*
1413- * allocate per cpu stats block
1414- */
1415- for_each_online_cpu(i) {
1416- p = kzalloc(sizeof(struct fcoe_dev_stats), GFP_KERNEL);
1417- if (p)
1418- lp->dev_stats[i] = p;
1419- }
1420-
1421- /* Finish fc_lport configuration */
1422- fc_lport_config(lp);
1423-
1424- return 0;
1425-}
1426-
1427-static int net_config(struct fc_lport *lp)
1428-{
1429- u32 mfs;
1430- u64 wwnn, wwpn;
1431- struct net_device *net_dev;
1432- struct fcoe_softc *fc = (struct fcoe_softc *)lp->drv_priv;
1433- u8 flogi_maddr[ETH_ALEN];
1434-
1435- /* Require support for get_pauseparam ethtool op. */
1436- net_dev = fc->real_dev;
1437- if (!net_dev->ethtool_ops && (net_dev->priv_flags & IFF_802_1Q_VLAN))
1438- net_dev = vlan_dev_real_dev(net_dev);
1439- if (!net_dev->ethtool_ops || !net_dev->ethtool_ops->get_pauseparam)
1440- return -EOPNOTSUPP;
1441-
1442- fc->phys_dev = net_dev;
1443-
1444- /* Do not support for bonding device */
1445- if ((fc->real_dev->priv_flags & IFF_MASTER_ALB) ||
1446- (fc->real_dev->priv_flags & IFF_SLAVE_INACTIVE) ||
1447- (fc->real_dev->priv_flags & IFF_MASTER_8023AD)) {
1448- return -EOPNOTSUPP;
1449- }
1450-
1451- /*
1452- * Determine max frame size based on underlying device and optional
1453- * user-configured limit. If the MFS is too low, fcoe_link_ok()
1454- * will return 0, so do this first.
1455- */
1456- mfs = fc->real_dev->mtu - (sizeof(struct fcoe_hdr) +
1457- sizeof(struct fcoe_crc_eof));
1458- fc_set_mfs(lp, mfs);
1459-
1460- lp->link_status = ~FC_PAUSE & ~FC_LINK_UP;
1461- if (!fcoe_link_ok(lp))
1462- lp->link_status |= FC_LINK_UP;
1463-
1464- if (fc->real_dev->features & NETIF_F_SG)
1465- lp->capabilities = TRANS_C_SG;
1466-
1467-
1468- skb_queue_head_init(&fc->fcoe_pending_queue);
1469-
1470- memcpy(lp->ifname, fc->real_dev->name, IFNAMSIZ);
1471-
1472- /* setup Source Mac Address */
1473- memcpy(fc->ctl_src_addr, fc->real_dev->dev_addr,
1474- fc->real_dev->addr_len);
1475-
1476- wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
1477- fc_set_wwnn(lp, wwnn);
1478- /* XXX - 3rd arg needs to be vlan id */
1479- wwpn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 2, 0);
1480- fc_set_wwpn(lp, wwpn);
1481-
1482- /*
1483- * Add FCoE MAC address as second unicast MAC address
1484- * or enter promiscuous mode if not capable of listening
1485- * for multiple unicast MACs.
1486- */
1487- rtnl_lock();
1488- memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
1489- dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
1490- rtnl_unlock();
1491-
1492- /*
1493- * setup the receive function from ethernet driver
1494- * on the ethertype for the given device
1495- */
1496- fc->fcoe_packet_type.func = fcoe_rcv;
1497- fc->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
1498- fc->fcoe_packet_type.dev = fc->real_dev;
1499- dev_add_pack(&fc->fcoe_packet_type);
1500-
1501- return 0;
1502-}
1503-
1504-static void shost_config(struct fc_lport *lp)
1505-{
1506- lp->host->max_lun = FCOE_MAX_LUN;
1507- lp->host->max_id = FCOE_MAX_FCP_TARGET;
1508- lp->host->max_channel = 0;
1509- lp->host->transportt = fcoe_transport_template;
1510-}
1511-
1512-static int libfc_config(struct fc_lport *lp)
1513-{
1514- /* Set the function pointers set by the LLDD */
1515- memcpy(&lp->tt, &fcoe_libfc_fcn_templ,
1516- sizeof(struct libfc_function_template));
1517-
1518- if (fc_fcp_init(lp))
1519- return -ENOMEM;
1520- fc_exch_init(lp);
1521- fc_lport_init(lp);
1522- fc_rport_init(lp);
1523- fc_disc_init(lp);
1524-
1525- return 0;
1526-}
1527-
1528-/*
1529- * This function creates the fcoe interface
1530- * create struct fcdev which is a shared structure between opefc
1531- * and transport level protocol.
1532- */
1533-int fcoe_create_interface(const char *ifname)
1534-{
1535- struct fc_lport *lp = NULL;
1536- struct fcoe_softc *fc;
1537- struct net_device *net_dev;
1538- struct Scsi_Host *shost;
1539- struct fcoe_info *fci = &fcoei;
1540- int rc = 0;
1541-
1542- net_dev = dev_get_by_name(&init_net, ifname);
1543- if (net_dev == NULL) {
1544- FC_DBG("could not get network device for %s",
1545- ifname);
1546- return -ENODEV;
1547- }
1548-
1549- if (fcoe_find_fc_lport(net_dev->name) != NULL) {
1550- rc = -EEXIST;
1551- goto out_put_dev;
1552- }
1553-
1554- shost = scsi_host_alloc(&fcoe_driver_template,
1555- sizeof(struct fc_lport) +
1556- sizeof(struct fcoe_softc));
1557-
1558- if (!shost) {
1559- FC_DBG("Could not allocate host structure\n");
1560- rc = -ENOMEM;
1561- goto out_put_dev;
1562- }
1563-
1564- lp = shost_priv(shost);
1565- rc = lport_config(lp, shost);
1566- if (rc)
1567- goto out_host_put;
1568-
1569- /* Configure the fcoe_softc */
1570- fc = (struct fcoe_softc *)lp->drv_priv;
1571- fc->lp = lp;
1572- fc->real_dev = net_dev;
1573- shost_config(lp);
1574-
1575-
1576- /* Add the new host to the SCSI-ml */
1577- rc = scsi_add_host(lp->host, NULL);
1578- if (rc) {
1579- FC_DBG("error on scsi_add_host\n");
1580- goto out_lp_destroy;
1581- }
1582-
1583- sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
1584- FCOE_DRIVER_NAME, FCOE_VERSION,
1585- ifname);
1586-
1587- /* Configure netdev and networking properties of the lp */
1588- rc = net_config(lp);
1589- if (rc)
1590- goto out_lp_destroy;
1591-
1592- /* Initialize the library */
1593- rc = libfc_config(lp);
1594- if (rc)
1595- goto out_lp_destroy;
1596-
1597- write_lock_bh(&fci->fcoe_hostlist_lock);
1598- list_add_tail(&fc->list, &fci->fcoe_hostlist);
1599- write_unlock_bh(&fci->fcoe_hostlist_lock);
1600-
1601- lp->boot_time = jiffies;
1602-
1603- fc_fabric_login(lp);
1604-
1605- return rc;
1606-
1607-out_lp_destroy:
1608- fc_exch_mgr_free(lp->emp); /* Free the EM */
1609-out_host_put:
1610- scsi_host_put(lp->host);
1611-out_put_dev:
1612- dev_put(net_dev);
1613- return rc;
1614-}
1615-
1616-void fcoe_clean_pending_queue(struct fc_lport *lp)
1617-{
1618- struct fcoe_softc *fc = lp->drv_priv;
1619- struct sk_buff *skb;
1620-
1621- spin_lock_bh(&fc->fcoe_pending_queue.lock);
1622- while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
1623- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1624- kfree_skb(skb);
1625- spin_lock_bh(&fc->fcoe_pending_queue.lock);
1626- }
1627- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
1628-}
1629diff --git a/drivers/scsi/fcoe/fcoe_sw.c b/drivers/scsi/fcoe/fcoe_sw.c
1630new file mode 100644
1631index 0000000..3cf5ad6
1632--- /dev/null
1633+++ b/drivers/scsi/fcoe/fcoe_sw.c
1634@@ -0,0 +1,532 @@
1635+/*
1636+ * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
1637+ *
1638+ * This program is free software; you can redistribute it and/or modify it
1639+ * under the terms and conditions of the GNU General Public License,
1640+ * version 2, as published by the Free Software Foundation.
1641+ *
1642+ * This program is distributed in the hope it will be useful, but WITHOUT
1643+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1644+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
1645+ * more details.
1646+ *
1647+ * You should have received a copy of the GNU General Public License along with
1648+ * this program; if not, write to the Free Software Foundation, Inc.,
1649+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1650+ *
1651+ * Maintained at www.Open-FCoE.org
1652+ */
1653+
1654+/*
1655+ * FCOE protocol file
1656+ */
1657+
1658+#include <linux/module.h>
1659+#include <linux/version.h>
1660+#include <linux/kernel.h>
1661+#include <linux/init.h>
1662+#include <linux/spinlock.h>
1663+#include <linux/netdevice.h>
1664+#include <linux/etherdevice.h>
1665+#include <linux/ethtool.h>
1666+#include <linux/if_ether.h>
1667+#include <linux/if_vlan.h>
1668+#include <net/rtnetlink.h>
1669+
1670+#include <scsi/fc/fc_els.h>
1671+#include <scsi/fc/fc_encaps.h>
1672+#include <scsi/fc/fc_fs.h>
1673+#include <scsi/scsi_transport.h>
1674+#include <scsi/scsi_transport_fc.h>
1675+
1676+#include <scsi/libfc/libfc.h>
1677+
1678+#include <scsi/fc/fc_fcoe.h>
1679+#include "fcoe_def.h"
1680+
1681+#define FCOE_VERSION "0.1"
1682+
1683+#define FCOE_MAX_LUN 255
1684+#define FCOE_MAX_FCP_TARGET 256
1685+
1686+#define FCOE_MAX_OUTSTANDING_COMMANDS 1024
1687+
1688+#define FCOE_MIN_XID 0x0004
1689+#define FCOE_MAX_XID 0x07ef
1690+
1691+LIST_HEAD(fcoe_hostlist);
1692+DEFINE_RWLOCK(fcoe_hostlist_lock);
1693+DEFINE_TIMER(fcoe_timer, NULL, 0, 0);
1694+struct fcoe_percpu_s *fcoe_percpu[NR_CPUS];
1695+
1696+static struct scsi_transport_template *fcoe_transport_template;
1697+
1698+static int fcoe_reset(struct Scsi_Host *shost)
1699+{
1700+ struct fc_lport *lport = shost_priv(shost);
1701+ fc_lport_reset(lport);
1702+ return 0;
1703+}
1704+
1705+struct fc_function_template fcoe_transport_function = {
1706+ .show_host_node_name = 1,
1707+ .show_host_port_name = 1,
1708+ .show_host_supported_classes = 1,
1709+ .show_host_supported_fc4s = 1,
1710+ .show_host_active_fc4s = 1,
1711+ .show_host_maxframe_size = 1,
1712+
1713+ .show_host_port_id = 1,
1714+ .show_host_supported_speeds = 1,
1715+ .get_host_speed = fc_get_host_speed,
1716+ .show_host_speed = 1,
1717+ .show_host_port_type = 1,
1718+ .get_host_port_state = fc_get_host_port_state,
1719+ .show_host_port_state = 1,
1720+ .show_host_symbolic_name = 1,
1721+
1722+ .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
1723+ .show_rport_maxframe_size = 1,
1724+ .show_rport_supported_classes = 1,
1725+
1726+ .show_host_fabric_name = 1,
1727+ .show_starget_node_name = 1,
1728+ .show_starget_port_name = 1,
1729+ .show_starget_port_id = 1,
1730+ .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
1731+ .show_rport_dev_loss_tmo = 1,
1732+ .get_fc_host_stats = fc_get_host_stats,
1733+ .issue_fc_host_lip = fcoe_reset,
1734+
1735+ .terminate_rport_io = fc_rport_terminate_io,
1736+};
1737+
1738+static struct fcoe_softc *fcoe_find_fc_lport(const struct net_device *netdev)
1739+{
1740+ struct fcoe_softc *fc;
1741+
1742+ read_lock(&fcoe_hostlist_lock);
1743+ list_for_each_entry(fc, &fcoe_hostlist, list) {
1744+ if (fc->real_dev == netdev) {
1745+ read_unlock(&fcoe_hostlist_lock);
1746+ return fc;
1747+ }
1748+ }
1749+ read_unlock(&fcoe_hostlist_lock);
1750+ return NULL;
1751+}
1752+
1753+/*
1754+ * Convert 48-bit IEEE MAC address to 64-bit FC WWN.
1755+ */
1756+static u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
1757+ unsigned int scheme, unsigned int port)
1758+{
1759+ u64 wwn;
1760+ u64 host_mac;
1761+
1762+ /* The MAC is in NO, so flip only the low 48 bits */
1763+ host_mac = ((u64) mac[0] << 40) |
1764+ ((u64) mac[1] << 32) |
1765+ ((u64) mac[2] << 24) |
1766+ ((u64) mac[3] << 16) |
1767+ ((u64) mac[4] << 8) |
1768+ (u64) mac[5];
1769+
1770+ WARN_ON(host_mac >= (1ULL << 48));
1771+ wwn = host_mac | ((u64) scheme << 60);
1772+ switch (scheme) {
1773+ case 1:
1774+ WARN_ON(port != 0);
1775+ break;
1776+ case 2:
1777+ WARN_ON(port >= 0xfff);
1778+ wwn |= (u64) port << 48;
1779+ break;
1780+ default:
1781+ WARN_ON(1);
1782+ break;
1783+ }
1784+
1785+ return wwn;
1786+}
1787+
1788+static struct scsi_host_template fcoe_driver_template = {
1789+ .module = THIS_MODULE,
1790+ .name = "FCoE Driver",
1791+ .proc_name = FCOE_DRIVER_NAME,
1792+ .queuecommand = fc_queuecommand,
1793+ .eh_abort_handler = fc_eh_abort,
1794+ .eh_device_reset_handler = fc_eh_device_reset,
1795+ .eh_host_reset_handler = fc_eh_host_reset,
1796+ .slave_alloc = fc_slave_alloc,
1797+ .change_queue_depth = fc_change_queue_depth,
1798+ .change_queue_type = fc_change_queue_type,
1799+ .this_id = -1,
1800+ .cmd_per_lun = 32,
1801+ .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
1802+ .use_clustering = ENABLE_CLUSTERING,
1803+ .sg_tablesize = 4,
1804+ .max_sectors = 0xffff,
1805+};
1806+
1807+int fcoe_destroy_interface(struct net_device *netdev)
1808+{
1809+ int cpu, idx;
1810+ struct fcoe_dev_stats *p;
1811+ struct fcoe_percpu_s *pp;
1812+ struct fcoe_softc *fc;
1813+ struct fcoe_rcv_info *fr;
1814+ struct sk_buff_head *list;
1815+ struct sk_buff *skb, *next;
1816+ struct sk_buff *head;
1817+ struct fc_lport *lp;
1818+ u8 flogi_maddr[ETH_ALEN];
1819+
1820+ fc = fcoe_find_fc_lport(netdev);
1821+ if (!fc)
1822+ return -ENODEV;
1823+
1824+ lp = fc->lp;
1825+
1826+ /* Remove the instance from fcoe's list */
1827+ write_lock_bh(&fcoe_hostlist_lock);
1828+ list_del(&fc->list);
1829+ write_unlock_bh(&fcoe_hostlist_lock);
1830+
1831+ /* Don't listen for Ethernet packets anymore */
1832+ dev_remove_pack(&fc->fcoe_packet_type);
1833+
1834+ /* Detach from the scsi-ml */
1835+ fc_remove_host(lp->host);
1836+ scsi_remove_host(lp->host);
1837+
1838+ /* Cleanup the fc_lport */
1839+ fc_lport_destroy(lp);
1840+ fc_fcp_destroy(lp);
1841+ if (lp->emp)
1842+ fc_exch_mgr_free(lp->emp);
1843+
1844+ /* Delete secondary MAC addresses */
1845+ rtnl_lock();
1846+ memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
1847+ dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
1848+ if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
1849+ dev_unicast_delete(fc->real_dev, fc->data_src_addr, ETH_ALEN);
1850+ rtnl_unlock();
1851+
1852+ /* Free the per-CPU revieve threads */
1853+ for (idx = 0; idx < NR_CPUS; idx++) {
1854+ if (fcoe_percpu[idx]) {
1855+ pp = fcoe_percpu[idx];
1856+ spin_lock_bh(&pp->fcoe_rx_list.lock);
1857+ list = &pp->fcoe_rx_list;
1858+ head = list->next;
1859+ for (skb = head; skb != (struct sk_buff *)list;
1860+ skb = next) {
1861+ next = skb->next;
1862+ fr = fcoe_dev_from_skb(skb);
1863+ if (fr->fr_dev == fc->lp) {
1864+ __skb_unlink(skb, list);
1865+ kfree_skb(skb);
1866+ }
1867+ }
1868+ spin_unlock_bh(&pp->fcoe_rx_list.lock);
1869+ }
1870+ }
1871+
1872+ /* Free existing skbs */
1873+ fcoe_clean_pending_queue(lp);
1874+
1875+ /* Free memory used by statistical counters */
1876+ for_each_online_cpu(cpu) {
1877+ p = lp->dev_stats[cpu];
1878+ if (p) {
1879+ lp->dev_stats[cpu] = NULL;
1880+ kfree(p);
1881+ }
1882+ }
1883+
1884+ /* Release the net_device and Scsi_Host */
1885+ dev_put(fc->real_dev);
1886+ scsi_host_put(lp->host);
1887+ return 0;
1888+}
1889+
1890+/*
1891+ * Return zero if link is OK for use by FCoE.
1892+ * Any permanently-disqualifying conditions have been previously checked.
1893+ * This also updates the speed setting, which may change with link for 100/1000.
1894+ *
1895+ * This function should probably be checking for PAUSE support at some point
1896+ * in the future. Currently Per-priority-pause is not determinable using
1897+ * ethtool, so we shouldn't be restrictive until that problem is resolved.
1898+ */
1899+int fcoe_link_ok(struct fc_lport *lp)
1900+{
1901+ struct fcoe_softc *fc = (struct fcoe_softc *)lp->drv_priv;
1902+ struct net_device *dev = fc->real_dev;
1903+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
1904+ int rc = 0;
1905+
1906+ if ((dev->flags & IFF_UP) && netif_carrier_ok(dev)) {
1907+ dev = fc->phys_dev;
1908+ if (dev->ethtool_ops->get_settings) {
1909+ dev->ethtool_ops->get_settings(dev, &ecmd);
1910+ lp->link_supported_speeds &=
1911+ ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
1912+ if (ecmd.supported & (SUPPORTED_1000baseT_Half |
1913+ SUPPORTED_1000baseT_Full))
1914+ lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
1915+ if (ecmd.supported & SUPPORTED_10000baseT_Full)
1916+ lp->link_supported_speeds |=
1917+ FC_PORTSPEED_10GBIT;
1918+ if (ecmd.speed == SPEED_1000)
1919+ lp->link_speed = FC_PORTSPEED_1GBIT;
1920+ if (ecmd.speed == SPEED_10000)
1921+ lp->link_speed = FC_PORTSPEED_10GBIT;
1922+ }
1923+ } else
1924+ rc = -1;
1925+
1926+ return rc;
1927+}
1928+
1929+static struct libfc_function_template fcoe_libfc_fcn_templ = {
1930+ .frame_send = fcoe_xmit,
1931+};
1932+
1933+static int lport_config(struct fc_lport *lp, struct Scsi_Host *shost)
1934+{
1935+ int i = 0;
1936+ struct fcoe_dev_stats *p;
1937+
1938+ lp->host = shost;
1939+ lp->drv_priv = (void *)(lp + 1);
1940+
1941+ lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
1942+ FCOE_MIN_XID, FCOE_MAX_XID);
1943+ if (!lp->emp)
1944+ return -ENOMEM;
1945+
1946+ lp->link_status = 0;
1947+ lp->max_retry_count = 3;
1948+ lp->e_d_tov = 2 * 1000; /* FC-FS default */
1949+ lp->r_a_tov = 2 * 2 * 1000;
1950+ lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
1951+ FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
1952+
1953+ /*
1954+ * allocate per cpu stats block
1955+ */
1956+ for_each_online_cpu(i) {
1957+ p = kzalloc(sizeof(struct fcoe_dev_stats), GFP_KERNEL);
1958+ if (p)
1959+ lp->dev_stats[i] = p;
1960+ }
1961+
1962+ /* Finish fc_lport configuration */
1963+ fc_lport_config(lp);
1964+
1965+ return 0;
1966+}
1967+
1968+static int net_config(struct fc_lport *lp)
1969+{
1970+ u32 mfs;
1971+ u64 wwnn, wwpn;
1972+ struct net_device *net_dev;
1973+ struct fcoe_softc *fc = (struct fcoe_softc *)lp->drv_priv;
1974+ u8 flogi_maddr[ETH_ALEN];
1975+
1976+ /* Require support for get_pauseparam ethtool op. */
1977+ net_dev = fc->real_dev;
1978+ if (!net_dev->ethtool_ops && (net_dev->priv_flags & IFF_802_1Q_VLAN))
1979+ net_dev = vlan_dev_real_dev(net_dev);
1980+ if (!net_dev->ethtool_ops || !net_dev->ethtool_ops->get_pauseparam)
1981+ return -EOPNOTSUPP;
1982+
1983+ fc->phys_dev = net_dev;
1984+
1985+ /* Do not support for bonding device */
1986+ if ((fc->real_dev->priv_flags & IFF_MASTER_ALB) ||
1987+ (fc->real_dev->priv_flags & IFF_SLAVE_INACTIVE) ||
1988+ (fc->real_dev->priv_flags & IFF_MASTER_8023AD)) {
1989+ return -EOPNOTSUPP;
1990+ }
1991+
1992+ /*
1993+ * Determine max frame size based on underlying device and optional
1994+ * user-configured limit. If the MFS is too low, fcoe_link_ok()
1995+ * will return 0, so do this first.
1996+ */
1997+ mfs = fc->real_dev->mtu - (sizeof(struct fcoe_hdr) +
1998+ sizeof(struct fcoe_crc_eof));
1999+ fc_set_mfs(lp, mfs);
2000+
2001+ lp->link_status = ~FC_PAUSE & ~FC_LINK_UP;
2002+ if (!fcoe_link_ok(lp))
2003+ lp->link_status |= FC_LINK_UP;
2004+
2005+ if (fc->real_dev->features & NETIF_F_SG)
2006+ lp->sg_supp = 1;
2007+
2008+
2009+ skb_queue_head_init(&fc->fcoe_pending_queue);
2010+
2011+ /* setup Source Mac Address */
2012+ memcpy(fc->ctl_src_addr, fc->real_dev->dev_addr,
2013+ fc->real_dev->addr_len);
2014+
2015+ wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
2016+ fc_set_wwnn(lp, wwnn);
2017+ /* XXX - 3rd arg needs to be vlan id */
2018+ wwpn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 2, 0);
2019+ fc_set_wwpn(lp, wwpn);
2020+
2021+ /*
2022+ * Add FCoE MAC address as second unicast MAC address
2023+ * or enter promiscuous mode if not capable of listening
2024+ * for multiple unicast MACs.
2025+ */
2026+ rtnl_lock();
2027+ memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
2028+ dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
2029+ rtnl_unlock();
2030+
2031+ /*
2032+ * setup the receive function from ethernet driver
2033+ * on the ethertype for the given device
2034+ */
2035+ fc->fcoe_packet_type.func = fcoe_rcv;
2036+ fc->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
2037+ fc->fcoe_packet_type.dev = fc->real_dev;
2038+ dev_add_pack(&fc->fcoe_packet_type);
2039+
2040+ return 0;
2041+}
2042+
2043+static void shost_config(struct fc_lport *lp)
2044+{
2045+ lp->host->max_lun = FCOE_MAX_LUN;
2046+ lp->host->max_id = FCOE_MAX_FCP_TARGET;
2047+ lp->host->max_channel = 0;
2048+ lp->host->transportt = fcoe_transport_template;
2049+}
2050+
2051+static int libfc_config(struct fc_lport *lp)
2052+{
2053+ /* Set the function pointers set by the LLDD */
2054+ memcpy(&lp->tt, &fcoe_libfc_fcn_templ,
2055+ sizeof(struct libfc_function_template));
2056+
2057+ if (fc_fcp_init(lp))
2058+ return -ENOMEM;
2059+ fc_exch_init(lp);
2060+ fc_lport_init(lp);
2061+ fc_rport_init(lp);
2062+ fc_disc_init(lp);
2063+
2064+ return 0;
2065+}
2066+
2067+/*
2068+ * This function creates the fcoe interface
2069+ * create struct fcdev which is a shared structure between opefc
2070+ * and transport level protocol.
2071+ */
2072+int fcoe_create_interface(struct net_device *netdev)
2073+{
2074+ struct fc_lport *lp = NULL;
2075+ struct fcoe_softc *fc;
2076+ struct Scsi_Host *shost;
2077+ int rc = 0;
2078+
2079+ if (fcoe_find_fc_lport(netdev) != NULL)
2080+ return -EEXIST;
2081+
2082+ shost = scsi_host_alloc(&fcoe_driver_template,
2083+ sizeof(struct fc_lport) +
2084+ sizeof(struct fcoe_softc));
2085+
2086+ if (!shost) {
2087+ FC_DBG("Could not allocate host structure\n");
2088+ return -ENOMEM;
2089+ }
2090+
2091+ lp = shost_priv(shost);
2092+ rc = lport_config(lp, shost);
2093+ if (rc)
2094+ goto out_host_put;
2095+
2096+ /* Configure the fcoe_softc */
2097+ fc = (struct fcoe_softc *)lp->drv_priv;
2098+ fc->lp = lp;
2099+ fc->real_dev = netdev;
2100+ shost_config(lp);
2101+
2102+
2103+ /* Add the new host to the SCSI-ml */
2104+ rc = scsi_add_host(lp->host, NULL);
2105+ if (rc) {
2106+ FC_DBG("error on scsi_add_host\n");
2107+ goto out_lp_destroy;
2108+ }
2109+
2110+ sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
2111+ FCOE_DRIVER_NAME, FCOE_VERSION,
2112+ netdev->name);
2113+
2114+ /* Configure netdev and networking properties of the lp */
2115+ rc = net_config(lp);
2116+ if (rc)
2117+ goto out_lp_destroy;
2118+
2119+ /* Initialize the library */
2120+ rc = libfc_config(lp);
2121+ if (rc)
2122+ goto out_lp_destroy;
2123+
2124+ write_lock_bh(&fcoe_hostlist_lock);
2125+ list_add_tail(&fc->list, &fcoe_hostlist);
2126+ write_unlock_bh(&fcoe_hostlist_lock);
2127+
2128+ lp->boot_time = jiffies;
2129+
2130+ fc_fabric_login(lp);
2131+
2132+ dev_hold(netdev);
2133+ return rc;
2134+
2135+out_lp_destroy:
2136+ fc_exch_mgr_free(lp->emp); /* Free the EM */
2137+out_host_put:
2138+ scsi_host_put(lp->host);
2139+ return rc;
2140+}
2141+
2142+void fcoe_clean_pending_queue(struct fc_lport *lp)
2143+{
2144+ struct fcoe_softc *fc = lp->drv_priv;
2145+ struct sk_buff *skb;
2146+
2147+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
2148+ while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
2149+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
2150+ kfree_skb(skb);
2151+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
2152+ }
2153+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
2154+}
2155+
2156+int __init fcoe_sw_init(void)
2157+{
2158+ fcoe_transport_template =
2159+ fc_attach_transport(&fcoe_transport_function);
2160+ return fcoe_transport_template ? 0 : -1;
2161+}
2162+
2163+void __exit fcoe_sw_exit(void)
2164+{
2165+ fc_release_transport(fcoe_transport_template);
2166+}
2167diff --git a/drivers/scsi/fcoe/fcoeinit.c b/drivers/scsi/fcoe/fcoeinit.c
2168deleted file mode 100644
2169index 7d52ed5..0000000
2170--- a/drivers/scsi/fcoe/fcoeinit.c
2171+++ /dev/null
2172@@ -1,440 +0,0 @@
2173-/*
2174- * Copyright(c) 2007 Intel Corporation. All rights reserved.
2175- *
2176- * This program is free software; you can redistribute it and/or modify it
2177- * under the terms and conditions of the GNU General Public License,
2178- * version 2, as published by the Free Software Foundation.
2179- *
2180- * This program is distributed in the hope it will be useful, but WITHOUT
2181- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2182- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
2183- * more details.
2184- *
2185- * You should have received a copy of the GNU General Public License along with
2186- * this program; if not, write to the Free Software Foundation, Inc.,
2187- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
2188- *
2189- * Maintained at www.Open-FCoE.org
2190- */
2191-
2192-#include <linux/module.h>
2193-#include <linux/version.h>
2194-#include <linux/kernel.h>
2195-#include <linux/kthread.h>
2196-#include <linux/spinlock.h>
2197-#include <linux/cpu.h>
2198-#include <linux/netdevice.h>
2199-#include <linux/etherdevice.h>
2200-#include <linux/ethtool.h>
2201-#include <linux/if_ether.h>
2202-#include <linux/fs.h>
2203-#include <linux/sysfs.h>
2204-#include <linux/ctype.h>
2205-
2206-#include <scsi/libfc/libfc.h>
2207-
2208-#include "fcoe_def.h"
2209-
2210-MODULE_AUTHOR("Open-FCoE.org");
2211-MODULE_DESCRIPTION("FCoE");
2212-MODULE_LICENSE("GPL");
2213-
2214-/*
2215- * Static functions and variables definations
2216- */
2217-#ifdef CONFIG_HOTPLUG_CPU
2218-static int fcoe_cpu_callback(struct notifier_block *, ulong, void *);
2219-#endif /* CONFIG_HOTPLUG_CPU */
2220-static int fcoe_device_notification(struct notifier_block *, ulong, void *);
2221-static void fcoe_dev_setup(void);
2222-static void fcoe_dev_cleanup(void);
2223-
2224-struct scsi_transport_template *fcoe_transport_template;
2225-
2226-static int fcoe_reset(struct Scsi_Host *shost)
2227-{
2228- struct fc_lport *lport = shost_priv(shost);
2229- fc_lport_reset(lport);
2230- return 0;
2231-}
2232-
2233-struct fc_function_template fcoe_transport_function = {
2234- .show_host_node_name = 1,
2235- .show_host_port_name = 1,
2236- .show_host_supported_classes = 1,
2237- .show_host_supported_fc4s = 1,
2238- .show_host_active_fc4s = 1,
2239- .show_host_maxframe_size = 1,
2240-
2241- .show_host_port_id = 1,
2242- .show_host_supported_speeds = 1,
2243- .get_host_speed = fc_get_host_speed,
2244- .show_host_speed = 1,
2245- .show_host_port_type = 1,
2246- .get_host_port_state = fc_get_host_port_state,
2247- .show_host_port_state = 1,
2248- .show_host_symbolic_name = 1,
2249-
2250- .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
2251- .show_rport_maxframe_size = 1,
2252- .show_rport_supported_classes = 1,
2253-
2254- .show_host_fabric_name = 1,
2255- .show_starget_node_name = 1,
2256- .show_starget_port_name = 1,
2257- .show_starget_port_id = 1,
2258- .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
2259- .show_rport_dev_loss_tmo = 1,
2260- .get_fc_host_stats = fc_get_host_stats,
2261- .issue_fc_host_lip = fcoe_reset,
2262-
2263- .terminate_rport_io = fc_rport_terminate_io,
2264-};
2265-
2266-struct fcoe_percpu_s *fcoe_percpu[NR_CPUS];
2267-
2268-#ifdef CONFIG_HOTPLUG_CPU
2269-static struct notifier_block fcoe_cpu_notifier = {
2270- .notifier_call = fcoe_cpu_callback,
2271-};
2272-#endif /* CONFIG_HOTPLUG_CPU */
2273-
2274-/*
2275- * notification function from net device
2276- */
2277-static struct notifier_block fcoe_notifier = {
2278- .notifier_call = fcoe_device_notification,
2279-};
2280-
2281-#ifdef CONFIG_HOTPLUG_CPU
2282-/*
2283- * create percpu stats block
2284- * called by cpu add/remove notifier
2285- */
2286-static void fcoe_create_percpu_data(int cpu)
2287-{
2288- struct fc_lport *lp;
2289- struct fcoe_softc *fc;
2290- struct fcoe_dev_stats *p;
2291- struct fcoe_info *fci = &fcoei;
2292-
2293- write_lock_bh(&fci->fcoe_hostlist_lock);
2294- list_for_each_entry(fc, &fci->fcoe_hostlist, list) {
2295- lp = fc->lp;
2296- if (lp->dev_stats[cpu] == NULL) {
2297- p = kzalloc(sizeof(struct fcoe_dev_stats), GFP_KERNEL);
2298- if (p)
2299- lp->dev_stats[cpu] = p;
2300- }
2301- }
2302- write_unlock_bh(&fci->fcoe_hostlist_lock);
2303-}
2304-
2305-/*
2306- * destroy percpu stats block
2307- * called by cpu add/remove notifier
2308- */
2309-static void fcoe_destroy_percpu_data(int cpu)
2310-{
2311- struct fcoe_dev_stats *p;
2312- struct fc_lport *lp;
2313- struct fcoe_softc *fc;
2314- struct fcoe_info *fci = &fcoei;
2315-
2316- write_lock_bh(&fci->fcoe_hostlist_lock);
2317- list_for_each_entry(fc, &fci->fcoe_hostlist, list) {
2318- lp = fc->lp;
2319- p = lp->dev_stats[cpu];
2320- if (p != NULL) {
2321- lp->dev_stats[cpu] = NULL;
2322- kfree(p);
2323- }
2324- }
2325- write_unlock_bh(&fci->fcoe_hostlist_lock);
2326-}
2327-
2328-/*
2329- * Get notified when a cpu comes on/off. Be hotplug friendly.
2330- */
2331-static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
2332- void *hcpu)
2333-{
2334- unsigned int cpu = (unsigned long)hcpu;
2335-
2336- switch (action) {
2337- case CPU_ONLINE:
2338- fcoe_create_percpu_data(cpu);
2339- break;
2340- case CPU_DEAD:
2341- fcoe_destroy_percpu_data(cpu);
2342- break;
2343- default:
2344- break;
2345- }
2346- return NOTIFY_OK;
2347-}
2348-#endif /* CONFIG_HOTPLUG_CPU */
2349-
2350-/*
2351- * function to setup link change notification interface
2352- */
2353-static void fcoe_dev_setup(void)
2354-{
2355- /*
2356- * here setup a interface specific wd time to
2357- * monitor the link state
2358- */
2359- register_netdevice_notifier(&fcoe_notifier);
2360-}
2361-
2362-/*
2363- * function to cleanup link change notification interface
2364- */
2365-static void fcoe_dev_cleanup(void)
2366-{
2367- unregister_netdevice_notifier(&fcoe_notifier);
2368-}
2369-
2370-/*
2371- * This function is called by the ethernet driver
2372- * this is called in case of link change event
2373- */
2374-static int fcoe_device_notification(struct notifier_block *notifier,
2375- ulong event, void *ptr)
2376-{
2377- struct fc_lport *lp = NULL;
2378- struct net_device *real_dev = ptr;
2379- struct fcoe_softc *fc;
2380- struct fcoe_dev_stats *stats;
2381- struct fcoe_info *fci = &fcoei;
2382- u16 new_status;
2383- u32 mfs;
2384- int rc = NOTIFY_OK;
2385-
2386- read_lock(&fci->fcoe_hostlist_lock);
2387- list_for_each_entry(fc, &fci->fcoe_hostlist, list) {
2388- if (fc->real_dev == real_dev) {
2389- lp = fc->lp;
2390- break;
2391- }
2392- }
2393- read_unlock(&fci->fcoe_hostlist_lock);
2394- if (lp == NULL) {
2395- rc = NOTIFY_DONE;
2396- goto out;
2397- }
2398-
2399- new_status = lp->link_status;
2400- switch (event) {
2401- case NETDEV_DOWN:
2402- case NETDEV_GOING_DOWN:
2403- new_status &= ~FC_LINK_UP;
2404- break;
2405- case NETDEV_UP:
2406- case NETDEV_CHANGE:
2407- new_status &= ~FC_LINK_UP;
2408- if (!fcoe_link_ok(lp))
2409- new_status |= FC_LINK_UP;
2410- break;
2411- case NETDEV_CHANGEMTU:
2412- mfs = fc->real_dev->mtu -
2413- (sizeof(struct fcoe_hdr) +
2414- sizeof(struct fcoe_crc_eof));
2415- if (fc->user_mfs && fc->user_mfs < mfs)
2416- mfs = fc->user_mfs;
2417- if (mfs >= FC_MIN_MAX_FRAME)
2418- fc_set_mfs(lp, mfs);
2419- new_status &= ~FC_LINK_UP;
2420- if (!fcoe_link_ok(lp))
2421- new_status |= FC_LINK_UP;
2422- break;
2423- case NETDEV_REGISTER:
2424- break;
2425- default:
2426- FC_DBG("unknown event %ld call", event);
2427- }
2428- if (lp->link_status != new_status) {
2429- if ((new_status & FC_LINK_UP) == FC_LINK_UP)
2430- fc_linkup(lp);
2431- else {
2432- stats = lp->dev_stats[smp_processor_id()];
2433- stats->LinkFailureCount++;
2434- fc_linkdown(lp);
2435- fcoe_clean_pending_queue(lp);
2436- }
2437- }
2438-out:
2439- return rc;
2440-}
2441-
2442-static void trimstr(char *str, int len)
2443-{
2444- char *cp = str + len;
2445- while (--cp >= str && *cp == '\n')
2446- *cp = '\0';
2447-}
2448-
2449-static ssize_t fcoe_destroy(struct kobject *kobj, struct kobj_attribute *attr,
2450- const char *buffer, size_t size)
2451-{
2452- char ifname[40];
2453- strcpy(ifname, buffer);
2454- trimstr(ifname, strlen(ifname));
2455- fcoe_destroy_interface(ifname);
2456- return size;
2457-}
2458-
2459-static ssize_t fcoe_create(struct kobject *kobj, struct kobj_attribute *attr,
2460- const char *buffer, size_t size)
2461-{
2462- char ifname[40];
2463- strcpy(ifname, buffer);
2464- trimstr(ifname, strlen(ifname));
2465- fcoe_create_interface(ifname);
2466- return size;
2467-}
2468-
2469-static const struct kobj_attribute fcoe_destroyattr = \
2470- __ATTR(destroy, S_IWUSR, NULL, fcoe_destroy);
2471-static const struct kobj_attribute fcoe_createattr = \
2472- __ATTR(create, S_IWUSR, NULL, fcoe_create);
2473-
2474-/*
2475- * Initialization routine
2476- * 1. Will create fc transport software structure
2477- * 2. initialize the link list of port information structure
2478- */
2479-static int __init fcoeinit(void)
2480-{
2481- int rc = 0;
2482- int cpu;
2483- struct fcoe_percpu_s *p;
2484- struct fcoe_info *fci = &fcoei;
2485-
2486- rc = sysfs_create_file(&THIS_MODULE->mkobj.kobj,
2487- &fcoe_destroyattr.attr);
2488- if (!rc)
2489- rc = sysfs_create_file(&THIS_MODULE->mkobj.kobj,
2490- &fcoe_createattr.attr);
2491-
2492- if (rc)
2493- return rc;
2494-
2495- rwlock_init(&fci->fcoe_hostlist_lock);
2496-
2497-#ifdef CONFIG_HOTPLUG_CPU
2498- register_cpu_notifier(&fcoe_cpu_notifier);
2499-#endif /* CONFIG_HOTPLUG_CPU */
2500-
2501- /*
2502- * initialize per CPU interrupt thread
2503- */
2504- for_each_online_cpu(cpu) {
2505- p = kzalloc(sizeof(struct fcoe_percpu_s), GFP_KERNEL);
2506- if (p) {
2507- p->thread = kthread_create(fcoe_percpu_receive_thread,
2508- (void *)p,
2509- "fcoethread/%d", cpu);
2510-
2511- /*
2512- * if there is no error then bind the thread to the cpu
2513- * initialize the semaphore and skb queue head
2514- */
2515- if (likely(!IS_ERR(p->thread))) {
2516- p->cpu = cpu;
2517- fci->fcoe_percpu[cpu] = p;
2518- skb_queue_head_init(&p->fcoe_rx_list);
2519- kthread_bind(p->thread, cpu);
2520- wake_up_process(p->thread);
2521- } else {
2522- fci->fcoe_percpu[cpu] = NULL;
2523- kfree(p);
2524-
2525- }
2526- }
2527- }
2528- if (rc < 0) {
2529- FC_DBG("failed to initialize proc intrerface\n");
2530- rc = -ENODEV;
2531- goto out_chrdev;
2532- }
2533-
2534- /*
2535- * setup link change notification
2536- */
2537- fcoe_dev_setup();
2538-
2539- init_timer(&fci->timer);
2540- fci->timer.data = (ulong) fci;
2541- fci->timer.function = fcoe_watchdog;
2542- fci->timer.expires = (jiffies + (10 * HZ));
2543- add_timer(&fci->timer);
2544-
2545- fcoe_transport_template =
2546- fc_attach_transport(&fcoe_transport_function);
2547-
2548- if (fcoe_transport_template == NULL) {
2549- FC_DBG("fail to attach fc transport");
2550- return -1;
2551- }
2552-
2553- return 0;
2554-
2555-out_chrdev:
2556-#ifdef CONFIG_HOTPLUG_CPU
2557- unregister_cpu_notifier(&fcoe_cpu_notifier);
2558-#endif /* CONFIG_HOTPLUG_CPU */
2559- return rc;
2560-}
2561-
2562-static void __exit fcoe_exit(void)
2563-{
2564- u32 idx;
2565- struct fcoe_softc *fc, *tmp;
2566- struct fc_lport *lp;
2567- struct fcoe_info *fci = &fcoei;
2568- struct fcoe_percpu_s *p;
2569- struct sk_buff *skb;
2570-
2571- /*
2572- * Stop all call back interfaces
2573- */
2574-#ifdef CONFIG_HOTPLUG_CPU
2575- unregister_cpu_notifier(&fcoe_cpu_notifier);
2576-#endif /* CONFIG_HOTPLUG_CPU */
2577- fcoe_dev_cleanup();
2578-
2579- /*
2580- * stop timer
2581- */
2582- del_timer_sync(&fci->timer);
2583-
2584- /*
2585- * assuming that at this time there will be no
2586- * ioctl in prograss, therefore we do not need to lock the
2587- * list.
2588- */
2589- list_for_each_entry_safe(fc, tmp, &fci->fcoe_hostlist, list) {
2590- lp = fc->lp;
2591- fcoe_destroy_interface(lp->ifname);
2592- }
2593-
2594- for (idx = 0; idx < NR_CPUS; idx++) {
2595- if (fci->fcoe_percpu[idx]) {
2596- kthread_stop(fci->fcoe_percpu[idx]->thread);
2597- p = fci->fcoe_percpu[idx];
2598- spin_lock_bh(&p->fcoe_rx_list.lock);
2599- while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
2600- kfree_skb(skb);
2601- spin_unlock_bh(&p->fcoe_rx_list.lock);
2602- if (fci->fcoe_percpu[idx]->crc_eof_page)
2603- put_page(fci->fcoe_percpu[idx]->crc_eof_page);
2604- kfree(fci->fcoe_percpu[idx]);
2605- }
2606- }
2607-
2608- fc_release_transport(fcoe_transport_template);
2609-}
2610-
2611-module_init(fcoeinit);
2612-module_exit(fcoe_exit);
2613diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
2614new file mode 100644
2615index 0000000..93c47aa
2616--- /dev/null
2617+++ b/drivers/scsi/fcoe/libfcoe.c
2618@@ -0,0 +1,632 @@
2619+/*
2620+ * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
2621+ *
2622+ * This program is free software; you can redistribute it and/or modify it
2623+ * under the terms and conditions of the GNU General Public License,
2624+ * version 2, as published by the Free Software Foundation.
2625+ *
2626+ * This program is distributed in the hope it will be useful, but WITHOUT
2627+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2628+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
2629+ * more details.
2630+ *
2631+ * You should have received a copy of the GNU General Public License along with
2632+ * this program; if not, write to the Free Software Foundation, Inc.,
2633+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
2634+ *
2635+ * Maintained at www.Open-FCoE.org
2636+ */
2637+
2638+/*
2639+ * FCOE protocol file
2640+ */
2641+
2642+#include <linux/module.h>
2643+#include <linux/version.h>
2644+#include <linux/kernel.h>
2645+#include <linux/spinlock.h>
2646+#include <linux/skbuff.h>
2647+#include <linux/netdevice.h>
2648+#include <linux/etherdevice.h>
2649+#include <linux/if_ether.h>
2650+#include <linux/kthread.h>
2651+#include <linux/crc32.h>
2652+#include <scsi/scsi_tcq.h>
2653+#include <scsi/scsicam.h>
2654+#include <scsi/scsi_transport.h>
2655+#include <scsi/scsi_transport_fc.h>
2656+#include <net/rtnetlink.h>
2657+
2658+#include <scsi/fc/fc_encaps.h>
2659+
2660+#include <scsi/libfc/libfc.h>
2661+#include <scsi/libfc/fc_frame.h>
2662+
2663+#include <scsi/fc/fc_fcoe.h>
2664+#include "fcoe_def.h"
2665+
2666+static int debug_fcoe;
2667+
2668+#define FCOE_MAX_QUEUE_DEPTH 256
2669+
2670+/* destination address mode */
2671+#define FCOE_GW_ADDR_MODE 0x00
2672+#define FCOE_FCOUI_ADDR_MODE 0x01
2673+
2674+/* Function Prototyes */
2675+static int fcoe_check_wait_queue(struct fc_lport *);
2676+static void fcoe_insert_wait_queue_head(struct fc_lport *, struct sk_buff *);
2677+static void fcoe_insert_wait_queue(struct fc_lport *, struct sk_buff *);
2678+static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *);
2679+
2680+/*
2681+ * this is the fcoe receive function
2682+ * called by NET_RX_SOFTIRQ
2683+ * this function will receive the packet and
2684+ * build fc frame and pass it up
2685+ */
2686+int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
2687+ struct packet_type *ptype, struct net_device *olddev)
2688+{
2689+ struct fc_lport *lp;
2690+ struct fcoe_rcv_info *fr;
2691+ struct fcoe_softc *fc;
2692+ struct fcoe_dev_stats *stats;
2693+ u8 *data;
2694+ struct fc_frame_header *fh;
2695+ unsigned short oxid;
2696+ int cpu_idx;
2697+ struct fcoe_percpu_s *fps;
2698+
2699+ fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type);
2700+ lp = fc->lp;
2701+ if (unlikely(lp == NULL)) {
2702+ FC_DBG("cannot find hba structure");
2703+ goto err2;
2704+ }
2705+
2706+ if (unlikely(debug_fcoe)) {
2707+ FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p tail:%p "
2708+ "end:%p sum:%d dev:%s", skb->len, skb->data_len,
2709+ skb->head, skb->data, skb_tail_pointer(skb),
2710+ skb_end_pointer(skb), skb->csum,
2711+ skb->dev ? skb->dev->name : "<NULL>");
2712+
2713+ }
2714+
2715+ /* check for FCOE packet type */
2716+ if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
2717+ FC_DBG("wrong FC type frame");
2718+ goto err;
2719+ }
2720+ data = skb->data;
2721+ data += sizeof(struct fcoe_hdr);
2722+ fh = (struct fc_frame_header *)data;
2723+ oxid = ntohs(fh->fh_ox_id);
2724+
2725+ fr = fcoe_dev_from_skb(skb);
2726+ fr->fr_dev = lp;
2727+ fr->ptype = ptype;
2728+ cpu_idx = 0;
2729+#ifdef CONFIG_SMP
2730+ /*
2731+ * The exchange ID are ANDed with num of online CPUs,
2732+ * so that will have the least lock contention in
2733+ * handling the exchange. if there is no thread
2734+ * for a given idx then use first online cpu.
2735+ */
2736+ cpu_idx = oxid & (num_online_cpus() >> 1);
2737+ if (fcoe_percpu[cpu_idx] == NULL)
2738+ cpu_idx = first_cpu(cpu_online_map);
2739+#endif
2740+ fps = fcoe_percpu[cpu_idx];
2741+
2742+ spin_lock_bh(&fps->fcoe_rx_list.lock);
2743+ __skb_queue_tail(&fps->fcoe_rx_list, skb);
2744+ if (fps->fcoe_rx_list.qlen == 1)
2745+ wake_up_process(fps->thread);
2746+
2747+ spin_unlock_bh(&fps->fcoe_rx_list.lock);
2748+
2749+ return 0;
2750+err:
2751+#ifdef CONFIG_SMP
2752+ stats = lp->dev_stats[smp_processor_id()];
2753+#else
2754+ stats = lp->dev_stats[0];
2755+#endif
2756+ stats->ErrorFrames++;
2757+
2758+err2:
2759+ kfree_skb(skb);
2760+ return -1;
2761+}
2762+
2763+static inline int fcoe_start_io(struct sk_buff *skb)
2764+{
2765+ int rc;
2766+
2767+ skb_get(skb);
2768+ rc = dev_queue_xmit(skb);
2769+ if (rc != 0)
2770+ return rc;
2771+ kfree_skb(skb);
2772+ return 0;
2773+}
2774+
2775+static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
2776+{
2777+ struct fcoe_percpu_s *fps;
2778+ struct page *page;
2779+ int cpu_idx;
2780+
2781+ cpu_idx = get_cpu();
2782+ fps = fcoe_percpu[cpu_idx];
2783+ page = fps->crc_eof_page;
2784+ if (!page) {
2785+ page = alloc_page(GFP_ATOMIC);
2786+ if (!page) {
2787+ put_cpu();
2788+ return -ENOMEM;
2789+ }
2790+ fps->crc_eof_page = page;
2791+ WARN_ON(fps->crc_eof_offset != 0);
2792+ }
2793+
2794+ get_page(page);
2795+ skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
2796+ fps->crc_eof_offset, tlen);
2797+ skb->len += tlen;
2798+ skb->data_len += tlen;
2799+ skb->truesize += tlen;
2800+ fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
2801+
2802+ if (fps->crc_eof_offset >= PAGE_SIZE) {
2803+ fps->crc_eof_page = NULL;
2804+ fps->crc_eof_offset = 0;
2805+ put_page(page);
2806+ }
2807+ put_cpu();
2808+ return 0;
2809+}
2810+
2811+/*
2812+ * this is the frame xmit routine
2813+ */
2814+int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
2815+{
2816+ int indx;
2817+ int wlen, rc = 0;
2818+ u32 crc;
2819+ struct ethhdr *eh;
2820+ struct fcoe_crc_eof *cp;
2821+ struct sk_buff *skb;
2822+ struct fcoe_dev_stats *stats;
2823+ struct fc_frame_header *fh;
2824+ unsigned int hlen; /* header length implies the version */
2825+ unsigned int tlen; /* trailer length */
2826+ int flogi_in_progress = 0;
2827+ struct fcoe_softc *fc;
2828+ void *data;
2829+ u8 sof, eof;
2830+ struct fcoe_hdr *hp;
2831+
2832+ WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
2833+
2834+ fc = (struct fcoe_softc *)lp->drv_priv;
2835+ /*
2836+ * if it is a flogi then we need to learn gw-addr
2837+ * and my own fcid
2838+ */
2839+ fh = fc_frame_header_get(fp);
2840+ if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) {
2841+ if (fc_frame_payload_op(fp) == ELS_FLOGI) {
2842+ fc->flogi_oxid = ntohs(fh->fh_ox_id);
2843+ fc->address_mode = FCOE_FCOUI_ADDR_MODE;
2844+ fc->flogi_progress = 1;
2845+ flogi_in_progress = 1;
2846+ } else if (fc->flogi_progress && ntoh24(fh->fh_s_id) != 0) {
2847+ /*
2848+ * Here we must've gotten an SID by accepting an FLOGI
2849+ * from a point-to-point connection. Switch to using
2850+ * the source mac based on the SID. The destination
2851+ * MAC in this case would have been set by receving the
2852+ * FLOGI.
2853+ */
2854+ fc_fcoe_set_mac(fc->data_src_addr, fh->fh_s_id);
2855+ fc->flogi_progress = 0;
2856+ }
2857+ }
2858+
2859+ skb = fp_skb(fp);
2860+ sof = fr_sof(fp);
2861+ eof = fr_eof(fp);
2862+
2863+ crc = ~0;
2864+ crc = crc32(crc, skb->data, skb_headlen(skb));
2865+
2866+ for (indx = 0; indx < skb_shinfo(skb)->nr_frags; indx++) {
2867+ skb_frag_t *frag = &skb_shinfo(skb)->frags[indx];
2868+ unsigned long off = frag->page_offset;
2869+ unsigned long len = frag->size;
2870+
2871+ while (len > 0) {
2872+ unsigned long clen;
2873+
2874+ clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
2875+ data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
2876+ KM_SKB_DATA_SOFTIRQ);
2877+ crc = crc32(crc, data + (off & ~PAGE_MASK),
2878+ clen);
2879+ kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
2880+ off += clen;
2881+ len -= clen;
2882+ }
2883+ }
2884+
2885+ /*
2886+ * Get header and trailer lengths.
2887+ * This is temporary code until we get rid of the old protocol.
2888+ * Both versions have essentially the same trailer layout but T11
2889+ * has padding afterwards.
2890+ */
2891+ hlen = sizeof(struct fcoe_hdr);
2892+ tlen = sizeof(struct fcoe_crc_eof);
2893+
2894+ /*
2895+ * copy fc crc and eof to the skb buff
2896+ * Use utility buffer in the fc_frame part of the sk_buff for the
2897+ * trailer.
2898+ * We don't do a get_page for this frag, since that page may not be
2899+ * managed that way. So that skb_free() doesn't do that either, we
2900+ * setup the destructor to remove this frag.
2901+ */
2902+ if (skb_is_nonlinear(skb)) {
2903+ skb_frag_t *frag;
2904+ if (fcoe_get_paged_crc_eof(skb, tlen)) {
2905+ kfree(skb);
2906+ return -ENOMEM;
2907+ }
2908+ frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
2909+ cp = kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ)
2910+ + frag->page_offset;
2911+ } else {
2912+ cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
2913+ }
2914+
2915+ cp->fcoe_eof = eof;
2916+ cp->fcoe_crc32 = cpu_to_le32(~crc);
2917+ if (tlen == sizeof(*cp))
2918+ memset(cp->fcoe_resvd, 0, sizeof(cp->fcoe_resvd));
2919+ wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
2920+
2921+ if (skb_is_nonlinear(skb)) {
2922+ kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
2923+ cp = NULL;
2924+ }
2925+
2926+ /*
2927+ * Fill in the control structures
2928+ */
2929+ skb->ip_summed = CHECKSUM_NONE;
2930+ eh = (struct ethhdr *)skb_push(skb, hlen + sizeof(struct ethhdr));
2931+ if (fc->address_mode == FCOE_FCOUI_ADDR_MODE)
2932+ fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
2933+ else
2934+ /* insert GW address */
2935+ memcpy(eh->h_dest, fc->dest_addr, ETH_ALEN);
2936+
2937+ if (unlikely(flogi_in_progress))
2938+ memcpy(eh->h_source, fc->ctl_src_addr, ETH_ALEN);
2939+ else
2940+ memcpy(eh->h_source, fc->data_src_addr, ETH_ALEN);
2941+
2942+ eh->h_proto = htons(ETH_P_FCOE);
2943+ skb->protocol = htons(ETH_P_802_3);
2944+ skb_reset_mac_header(skb);
2945+ skb_reset_network_header(skb);
2946+
2947+ hp = (struct fcoe_hdr *)(eh + 1);
2948+ memset(hp, 0, sizeof(*hp));
2949+ if (FC_FCOE_VER)
2950+ FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
2951+ hp->fcoe_sof = sof;
2952+
2953+ stats = lp->dev_stats[smp_processor_id()];
2954+ stats->TxFrames++;
2955+ stats->TxWords += wlen;
2956+ skb->dev = fc->real_dev;
2957+
2958+ fr_dev(fp) = lp;
2959+ if (fc->fcoe_pending_queue.qlen)
2960+ rc = fcoe_check_wait_queue(lp);
2961+
2962+ if (rc == 0)
2963+ rc = fcoe_start_io(skb);
2964+
2965+ if (rc) {
2966+ fcoe_insert_wait_queue(lp, skb);
2967+ if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
2968+ fc_pause(lp);
2969+ }
2970+
2971+ return 0;
2972+}
2973+
2974+int fcoe_percpu_receive_thread(void *arg)
2975+{
2976+ struct fcoe_percpu_s *p = arg;
2977+ u32 fr_len;
2978+ unsigned int hlen;
2979+ unsigned int tlen;
2980+ struct fc_lport *lp;
2981+ struct fcoe_rcv_info *fr;
2982+ struct fcoe_dev_stats *stats;
2983+ struct fc_frame_header *fh;
2984+ struct sk_buff *skb;
2985+ struct fcoe_crc_eof *cp;
2986+ enum fc_sof sof;
2987+ struct fc_frame *fp;
2988+ u8 *mac = NULL;
2989+ struct fcoe_softc *fc;
2990+ struct fcoe_hdr *hp;
2991+
2992+ set_user_nice(current, 19);
2993+
2994+ while (!kthread_should_stop()) {
2995+
2996+ spin_lock_bh(&p->fcoe_rx_list.lock);
2997+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) == NULL) {
2998+ set_current_state(TASK_INTERRUPTIBLE);
2999+ spin_unlock_bh(&p->fcoe_rx_list.lock);
3000+ schedule();
3001+ set_current_state(TASK_RUNNING);
3002+ if (kthread_should_stop())
3003+ return 0;
3004+ spin_lock_bh(&p->fcoe_rx_list.lock);
3005+ }
3006+ spin_unlock_bh(&p->fcoe_rx_list.lock);
3007+ fr = fcoe_dev_from_skb(skb);
3008+ lp = fr->fr_dev;
3009+ if (unlikely(lp == NULL)) {
3010+ FC_DBG("invalid HBA Structure");
3011+ kfree_skb(skb);
3012+ continue;
3013+ }
3014+
3015+ stats = lp->dev_stats[smp_processor_id()];
3016+
3017+ if (unlikely(debug_fcoe)) {
3018+ FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p "
3019+ "tail:%p end:%p sum:%d dev:%s",
3020+ skb->len, skb->data_len,
3021+ skb->head, skb->data, skb_tail_pointer(skb),
3022+ skb_end_pointer(skb), skb->csum,
3023+ skb->dev ? skb->dev->name : "<NULL>");
3024+ }
3025+
3026+ /*
3027+ * Save source MAC address before discarding header.
3028+ */
3029+ fc = lp->drv_priv;
3030+ if (unlikely(fc->flogi_progress))
3031+ mac = eth_hdr(skb)->h_source;
3032+
3033+ if (skb_is_nonlinear(skb))
3034+ skb_linearize(skb); /* not ideal */
3035+
3036+ /*
3037+ * Check the header and pull it off.
3038+ */
3039+ hlen = sizeof(struct fcoe_hdr);
3040+
3041+ hp = (struct fcoe_hdr *)skb->data;
3042+ if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
3043+ if (stats->ErrorFrames < 5)
3044+ FC_DBG("unknown FCoE version %x",
3045+ FC_FCOE_DECAPS_VER(hp));
3046+ stats->ErrorFrames++;
3047+ kfree_skb(skb);
3048+ continue;
3049+ }
3050+ sof = hp->fcoe_sof;
3051+ skb_pull(skb, sizeof(*hp));
3052+ fr_len = skb->len - sizeof(struct fcoe_crc_eof);
3053+ skb_trim(skb, fr_len);
3054+ tlen = sizeof(struct fcoe_crc_eof);
3055+
3056+ if (unlikely(fr_len > skb->len)) {
3057+ if (stats->ErrorFrames < 5)
3058+ FC_DBG("length error fr_len 0x%x skb->len 0x%x",
3059+ fr_len, skb->len);
3060+ stats->ErrorFrames++;
3061+ kfree_skb(skb);
3062+ continue;
3063+ }
3064+ stats->RxFrames++;
3065+ stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
3066+
3067+ fp = (struct fc_frame *) skb;
3068+ fc_frame_init(fp);
3069+ cp = (struct fcoe_crc_eof *)(skb->data + fr_len);
3070+ fr_eof(fp) = cp->fcoe_eof;
3071+ fr_sof(fp) = sof;
3072+ fr_dev(fp) = lp;
3073+
3074+ /*
3075+ * Check the CRC here, unless it's solicited data for SCSI.
3076+ * In that case, the SCSI layer can check it during the copy,
3077+ * and it'll be more cache-efficient.
3078+ */
3079+ fh = fc_frame_header_get(fp);
3080+ if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
3081+ fh->fh_type == FC_TYPE_FCP) {
3082+ fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
3083+ fc_exch_recv(lp, lp->emp, fp);
3084+ } else if (le32_to_cpu(cp->fcoe_crc32) ==
3085+ ~crc32(~0, skb->data, fr_len)) {
3086+ if (unlikely(fc->flogi_progress))
3087+ fcoe_recv_flogi(fc, fp, mac);
3088+ fc_exch_recv(lp, lp->emp, fp);
3089+ } else {
3090+ if (debug_fcoe || stats->InvalidCRCCount < 5) {
3091+ printk(KERN_WARNING \
3092+ "fcoe: dropping frame with CRC error");
3093+ }
3094+ stats->InvalidCRCCount++;
3095+ stats->ErrorFrames++;
3096+ fc_frame_free(fp);
3097+ }
3098+ }
3099+ return 0;
3100+}
3101+
3102+/*
3103+ * Snoop potential response to FLOGI or even incoming FLOGI.
3104+ */
3105+static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa)
3106+{
3107+ struct fc_frame_header *fh;
3108+ u8 op;
3109+
3110+ fh = fc_frame_header_get(fp);
3111+ if (fh->fh_type != FC_TYPE_ELS)
3112+ return;
3113+ op = fc_frame_payload_op(fp);
3114+ if (op == ELS_LS_ACC && fh->fh_r_ctl == FC_RCTL_ELS_REP &&
3115+ fc->flogi_oxid == ntohs(fh->fh_ox_id)) {
3116+ /*
3117+ * FLOGI accepted.
3118+ * If the src mac addr is FC_OUI-based, then we mark the
3119+ * address_mode flag to use FC_OUI-based Ethernet DA.
3120+ * Otherwise we use the FCoE gateway addr
3121+ */
3122+ if (!compare_ether_addr(sa, (u8[6]) FC_FCOE_FLOGI_MAC)) {
3123+ fc->address_mode = FCOE_FCOUI_ADDR_MODE;
3124+ } else {
3125+ memcpy(fc->dest_addr, sa, ETH_ALEN);
3126+ fc->address_mode = FCOE_GW_ADDR_MODE;
3127+ }
3128+
3129+ /*
3130+ * Remove any previously-set unicast MAC filter.
3131+ * Add secondary FCoE MAC address filter for our OUI.
3132+ */
3133+ rtnl_lock();
3134+ if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
3135+ dev_unicast_delete(fc->real_dev, fc->data_src_addr,
3136+ ETH_ALEN);
3137+ fc_fcoe_set_mac(fc->data_src_addr, fh->fh_d_id);
3138+ dev_unicast_add(fc->real_dev, fc->data_src_addr, ETH_ALEN);
3139+ rtnl_unlock();
3140+
3141+ fc->flogi_progress = 0;
3142+ } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
3143+ /*
3144+ * Save source MAC for point-to-point responses.
3145+ */
3146+ memcpy(fc->dest_addr, sa, ETH_ALEN);
3147+ fc->address_mode = FCOE_GW_ADDR_MODE;
3148+ }
3149+}
3150+
3151+void fcoe_watchdog(ulong vp)
3152+{
3153+ struct fc_lport *lp;
3154+ struct fcoe_softc *fc;
3155+ int paused = 0;
3156+
3157+ read_lock(&fcoe_hostlist_lock);
3158+ list_for_each_entry(fc, &fcoe_hostlist, list) {
3159+ lp = fc->lp;
3160+ if (lp) {
3161+ if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
3162+ paused = 1;
3163+ if (fcoe_check_wait_queue(lp) < FCOE_MAX_QUEUE_DEPTH) {
3164+ if (paused)
3165+ fc_unpause(lp);
3166+ }
3167+ }
3168+ }
3169+ read_unlock(&fcoe_hostlist_lock);
3170+
3171+ fcoe_timer.expires = jiffies + (1 * HZ);
3172+ add_timer(&fcoe_timer);
3173+}
3174+
3175+/*
3176+ * the wait_queue is used when the skb transmit fails. skb will go
3177+ * in the wait_queue which will be emptied by the time function OR
3178+ * by the next skb transmit.
3179+ *
3180+ */
3181+
3182+/*
3183+ * Function name : fcoe_check_wait_queue()
3184+ *
3185+ * Return Values : 0 or error
3186+ *
3187+ * Description : empties the wait_queue
3188+ * dequeue the head of the wait_queue queue and
3189+ * calls fcoe_start_io() for each packet
3190+ * if all skb have been transmitted, return 0
3191+ * if a error occurs, then restore wait_queue and try again
3192+ * later
3193+ *
3194+ */
3195+
3196+static int fcoe_check_wait_queue(struct fc_lport *lp)
3197+{
3198+ int rc, unpause = 0;
3199+ int paused = 0;
3200+ struct sk_buff *skb;
3201+ struct fcoe_softc *fc;
3202+
3203+ fc = (struct fcoe_softc *)lp->drv_priv;
3204+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
3205+
3206+ /*
3207+ * is this interface paused?
3208+ */
3209+ if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
3210+ paused = 1;
3211+ if (fc->fcoe_pending_queue.qlen) {
3212+ while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
3213+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
3214+ rc = fcoe_start_io(skb);
3215+ if (rc) {
3216+ fcoe_insert_wait_queue_head(lp, skb);
3217+ return rc;
3218+ }
3219+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
3220+ }
3221+ if (fc->fcoe_pending_queue.qlen < FCOE_MAX_QUEUE_DEPTH)
3222+ unpause = 1;
3223+ }
3224+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
3225+ if ((unpause) && (paused))
3226+ fc_unpause(lp);
3227+ return fc->fcoe_pending_queue.qlen;
3228+}
3229+
3230+static void fcoe_insert_wait_queue_head(struct fc_lport *lp,
3231+ struct sk_buff *skb)
3232+{
3233+ struct fcoe_softc *fc;
3234+
3235+ fc = (struct fcoe_softc *)lp->drv_priv;
3236+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
3237+ __skb_queue_head(&fc->fcoe_pending_queue, skb);
3238+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
3239+}
3240+
3241+static void fcoe_insert_wait_queue(struct fc_lport *lp,
3242+ struct sk_buff *skb)
3243+{
3244+ struct fcoe_softc *fc;
3245+
3246+ fc = (struct fcoe_softc *)lp->drv_priv;
3247+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
3248+ __skb_queue_tail(&fc->fcoe_pending_queue, skb);
3249+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
3250+}
3251diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
3252index 30403aa..f724dd2 100644
3253--- a/drivers/scsi/libfc/fc_disc.c
3254+++ b/drivers/scsi/libfc/fc_disc.c
3255@@ -19,7 +19,9 @@
3256
3257 /*
3258 * Target Discovery
3259- * Actually, this discovers all FC-4 remote ports, including FCP initiators.
3260+ *
3261+ * This block discovers all FC-4 remote ports, including FCP initiators. It
3262+ * also handles RSCN events and re-discovery if necessary.
3263 */
3264
3265 #include <linux/timer.h>
3266@@ -33,12 +35,18 @@
3267 #define FC_DISC_RETRY_LIMIT 3 /* max retries */
3268 #define FC_DISC_RETRY_DELAY 500UL /* (msecs) delay */
3269
3270-int fc_disc_debug;
3271+static int fc_disc_debug;
3272+
3273+#define FC_DEBUG_DISC(fmt...) \
3274+ do { \
3275+ if (fc_disc_debug) \
3276+ FC_DBG(fmt); \
3277+ } while (0)
3278
3279 static void fc_disc_gpn_ft_req(struct fc_lport *);
3280 static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *);
3281 static int fc_disc_new_target(struct fc_lport *, struct fc_rport *,
3282- struct fc_rport_identifiers *);
3283+ struct fc_rport_identifiers *);
3284 static void fc_disc_del_target(struct fc_lport *, struct fc_rport *);
3285 static void fc_disc_done(struct fc_lport *);
3286 static void fc_disc_error(struct fc_lport *, struct fc_frame *);
3287@@ -47,13 +55,13 @@ static void fc_disc_single(struct fc_lport *, struct fc_disc_port *);
3288 static int fc_disc_restart(struct fc_lport *);
3289
3290 /**
3291- * fc_disc_rscn_req - Handle Registered State Change Notification (RSCN)
3292+ * fc_disc_recv_rscn_req - Handle Registered State Change Notification (RSCN)
3293 * @sp: Current sequence of the RSCN exchange
3294 * @fp: RSCN Frame
3295- * @lp: Fibre Channel host port instance
3296+ * @lport: Fibre Channel host port instance
3297 */
3298-static void fc_disc_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
3299- struct fc_lport *lp)
3300+static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
3301+ struct fc_lport *lport)
3302 {
3303 struct fc_els_rscn *rp;
3304 struct fc_els_rscn_page *pp;
3305@@ -86,12 +94,14 @@ static void fc_disc_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
3306 */
3307 switch (fmt) {
3308 case ELS_ADDR_FMT_PORT:
3309+ FC_DEBUG_DISC("Port address format for port (%6x)\n",
3310+ ntoh24(pp->rscn_fid));
3311 dp = kzalloc(sizeof(*dp), GFP_KERNEL);
3312 if (!dp) {
3313 redisc = 1;
3314 break;
3315 }
3316- dp->lp = lp;
3317+ dp->lp = lport;
3318 dp->ids.port_id = ntoh24(pp->rscn_fid);
3319 dp->ids.port_name = -1;
3320 dp->ids.node_name = -1;
3321@@ -102,27 +112,26 @@ static void fc_disc_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
3322 case ELS_ADDR_FMT_DOM:
3323 case ELS_ADDR_FMT_FAB:
3324 default:
3325+ FC_DEBUG_DISC("Address format is (%d)\n", fmt);
3326 redisc = 1;
3327 break;
3328 }
3329 }
3330- lp->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
3331+ lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
3332 if (redisc) {
3333- if (fc_disc_debug)
3334- FC_DBG("RSCN received: rediscovering\n");
3335+ FC_DEBUG_DISC("RSCN received: rediscovering\n");
3336 list_for_each_entry_safe(dp, next, &disc_list, peers) {
3337 list_del(&dp->peers);
3338 kfree(dp);
3339 }
3340- fc_disc_restart(lp);
3341+ fc_disc_restart(lport);
3342 } else {
3343- if (fc_disc_debug)
3344- FC_DBG("RSCN received: not rediscovering. "
3345- "redisc %d state %d in_prog %d\n",
3346- redisc, lp->state, lp->disc_pending);
3347+ FC_DEBUG_DISC("RSCN received: not rediscovering. "
3348+ "redisc %d state %d in_prog %d\n",
3349+ redisc, lport->state, lport->disc_pending);
3350 list_for_each_entry_safe(dp, next, &disc_list, peers) {
3351 list_del(&dp->peers);
3352- fc_disc_single(lp, dp);
3353+ fc_disc_single(lport, dp);
3354 }
3355 }
3356 fc_frame_free(fp);
3357@@ -131,48 +140,53 @@ reject:
3358 rjt_data.fp = NULL;
3359 rjt_data.reason = ELS_RJT_LOGIC;
3360 rjt_data.explan = ELS_EXPL_NONE;
3361- lp->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
3362+ lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
3363 fc_frame_free(fp);
3364 }
3365
3366+/**
3367+ * fc_disc_recv_req - Handle incoming requests
3368+ * @sp: Current sequence of the request exchange
3369+ * @fp: The frame
3370+ * @lport: The FC local port
3371+ */
3372 static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp,
3373- struct fc_lport *lp)
3374+ struct fc_lport *lport)
3375 {
3376- switch (fc_frame_payload_op(fp)) {
3377+ u8 op;
3378+
3379+ op = fc_frame_payload_op(fp);
3380+ switch (op) {
3381 case ELS_RSCN:
3382- fc_disc_rscn_req(sp, fp, lp);
3383+ fc_disc_recv_rscn_req(sp, fp, lport);
3384 break;
3385 default:
3386- FC_DBG("fc_disc recieved an unexpected request\n");
3387+ FC_DBG("Received an unsupported request. opcode (%x)\n", op);
3388 break;
3389 }
3390 }
3391
3392-/*
3393- * Refresh target discovery, perhaps due to an RSCN.
3394- * A configurable delay is introduced to collect any subsequent RSCNs.
3395+/**
3396+ * fc_disc_restart - Restart discovery
3397+ * @lport: FC local port
3398 */
3399-static int fc_disc_restart(struct fc_lport *lp)
3400+static int fc_disc_restart(struct fc_lport *lport)
3401 {
3402- if (!lp->disc_requested && !lp->disc_pending) {
3403- schedule_delayed_work(&lp->disc_work,
3404- msecs_to_jiffies(lp->disc_delay * 1000));
3405+ if (!lport->disc_requested && !lport->disc_pending) {
3406+ schedule_delayed_work(&lport->disc_work,
3407+ msecs_to_jiffies(lport->disc_delay * 1000));
3408 }
3409- lp->disc_requested = 1;
3410+ lport->disc_requested = 1;
3411 return 0;
3412 }
3413
3414-/*
3415- * Fibre Channel Target discovery.
3416+/**
3417+ * fc_disc_start - Fibre Channel Target discovery
3418+ * @lport: FC local port
3419 *
3420 * Returns non-zero if discovery cannot be started.
3421- *
3422- * Callback is called for each target remote port found in discovery.
3423- * When discovery is complete, the callback is called with a NULL remote port.
3424- * Discovery may be restarted after an RSCN is received, causing the
3425- * callback to be called after discovery complete is indicated.
3426 */
3427-int fc_disc_start(struct fc_lport *lp)
3428+static int fc_disc_start(struct fc_lport *lport)
3429 {
3430 struct fc_rport *rport;
3431 int error;
3432@@ -181,20 +195,20 @@ int fc_disc_start(struct fc_lport *lp)
3433 /*
3434 * If not ready, or already running discovery, just set request flag.
3435 */
3436- if (!fc_lport_test_ready(lp) || lp->disc_pending) {
3437- lp->disc_requested = 1;
3438+ if (!fc_lport_test_ready(lport) || lport->disc_pending) {
3439+ lport->disc_requested = 1;
3440
3441 return 0;
3442 }
3443- lp->disc_pending = 1;
3444- lp->disc_requested = 0;
3445- lp->disc_retry_count = 0;
3446+ lport->disc_pending = 1;
3447+ lport->disc_requested = 0;
3448+ lport->disc_retry_count = 0;
3449
3450 /*
3451 * Handle point-to-point mode as a simple discovery
3452 * of the remote port.
3453 */
3454- rport = lp->ptp_rp;
3455+ rport = lport->ptp_rp;
3456 if (rport) {
3457 ids.port_id = rport->port_id;
3458 ids.port_name = rport->port_name;
3459@@ -202,46 +216,41 @@ int fc_disc_start(struct fc_lport *lp)
3460 ids.roles = FC_RPORT_ROLE_UNKNOWN;
3461 get_device(&rport->dev);
3462
3463- error = fc_disc_new_target(lp, rport, &ids);
3464+ error = fc_disc_new_target(lport, rport, &ids);
3465 put_device(&rport->dev);
3466 if (!error)
3467- fc_disc_done(lp);
3468+ fc_disc_done(lport);
3469 } else {
3470- fc_block_rports(lp);
3471- fc_disc_gpn_ft_req(lp); /* get ports by FC-4 type */
3472+ fc_disc_gpn_ft_req(lport); /* get ports by FC-4 type */
3473 error = 0;
3474 }
3475 return error;
3476 }
3477
3478-/*
3479- * Restart discovery after a delay due to resource shortages.
3480- * If the error persists, the discovery will be abandoned.
3481+/**
3482+ * fc_disc_retry - Retry discovery
3483+ * @lport: FC local port
3484 */
3485-static void fc_disc_retry(struct fc_lport *lp)
3486+static void fc_disc_retry(struct fc_lport *lport)
3487 {
3488 unsigned long delay = FC_DISC_RETRY_DELAY;
3489
3490- if (!lp->disc_retry_count)
3491+ if (!lport->disc_retry_count)
3492 delay /= 4; /* timeout faster first time */
3493- if (lp->disc_retry_count++ < FC_DISC_RETRY_LIMIT)
3494- schedule_delayed_work(&lp->disc_work,
3495+ if (lport->disc_retry_count++ < FC_DISC_RETRY_LIMIT)
3496+ schedule_delayed_work(&lport->disc_work,
3497 msecs_to_jiffies(delay));
3498 else
3499- fc_disc_done(lp);
3500+ fc_disc_done(lport);
3501 }
3502
3503-/*
3504- * Handle new target found by discovery.
3505- * Create remote port and session if needed.
3506- * Ignore returns of our own FID & WWPN.
3507- *
3508- * If a non-NULL rp is passed in, it is held for the caller, but not for us.
3509- *
3510- * Events delivered are:
3511- * FC_EV_READY, when remote port is rediscovered.
3512+/**
3513+ * fc_disc_new_target - Handle new target found by discovery
3514+ * @lport: FC local port
3515+ * @rport: The previous FC remote port (NULL if new remote port)
3516+ * @ids: Identifiers for the new FC remote port
3517 */
3518-static int fc_disc_new_target(struct fc_lport *lp,
3519+static int fc_disc_new_target(struct fc_lport *lport,
3520 struct fc_rport *rport,
3521 struct fc_rport_identifiers *ids)
3522 {
3523@@ -263,61 +272,64 @@ static int fc_disc_new_target(struct fc_lport *lp,
3524 * assigned the same FCID. This should be rare.
3525 * Delete the old one and fall thru to re-create.
3526 */
3527- fc_disc_del_target(lp, rport);
3528+ fc_disc_del_target(lport, rport);
3529 rport = NULL;
3530 }
3531 }
3532 if (((ids->port_name != -1) || (ids->port_id != -1)) &&
3533- ids->port_id != lp->fid && ids->port_name != lp->wwpn) {
3534+ ids->port_id != fc_host_port_id(lport->host) &&
3535+ ids->port_name != lport->wwpn) {
3536 if (!rport) {
3537- rport = lp->tt.rport_lookup(lp, ids->port_id);
3538+ rport = lport->tt.rport_lookup(lport, ids->port_id);
3539 if (!rport) {
3540 struct fc_disc_port dp;
3541- dp.lp = lp;
3542+ dp.lp = lport;
3543 dp.ids.port_id = ids->port_id;
3544 dp.ids.port_name = ids->port_name;
3545 dp.ids.node_name = ids->node_name;
3546 dp.ids.roles = ids->roles;
3547- rport = fc_rport_dummy_create(&dp);
3548+ rport = fc_rport_rogue_create(&dp);
3549 }
3550 if (!rport)
3551 error = ENOMEM;
3552 }
3553 if (rport) {
3554 rp = rport->dd_data;
3555- rp->event_callback = lp->tt.event_callback;
3556+ rp->event_callback = lport->tt.event_callback;
3557 rp->rp_state = RPORT_ST_INIT;
3558- lp->tt.rport_login(rport);
3559+ lport->tt.rport_login(rport);
3560 }
3561 }
3562 return error;
3563 }
3564
3565-/*
3566- * Delete the remote port.
3567+/**
3568+ * fc_disc_del_target - Delete a target
3569+ * @lport: FC local port
3570+ * @rport: The remote port to be removed
3571 */
3572-static void fc_disc_del_target(struct fc_lport *lp, struct fc_rport *rport)
3573+static void fc_disc_del_target(struct fc_lport *lport, struct fc_rport *rport)
3574 {
3575- lp->tt.rport_reset(rport);
3576- fc_remote_port_delete(rport); /* release hold from create */
3577+ lport->tt.rport_stop(rport);
3578 }
3579
3580-/*
3581- * Done with discovery
3582+/**
3583+ * fc_disc_done - Discovery has been completed
3584+ * @lport: FC local port
3585 */
3586-static void fc_disc_done(struct fc_lport *lp)
3587+static void fc_disc_done(struct fc_lport *lport)
3588 {
3589- lp->disc_done = 1;
3590- lp->disc_pending = 0;
3591- if (lp->disc_requested)
3592- lp->tt.disc_start(lp);
3593+ lport->disc_done = 1;
3594+ lport->disc_pending = 0;
3595+ if (lport->disc_requested)
3596+ lport->tt.disc_start(lport);
3597 }
3598
3599 /**
3600 * fc_disc_gpn_ft_req - Send Get Port Names by FC-4 type (GPN_FT) request
3601- * @lp: Fibre Channel host port instance
3602+ * @lport: FC local port
3603 */
3604-static void fc_disc_gpn_ft_req(struct fc_lport *lp)
3605+static void fc_disc_gpn_ft_req(struct fc_lport *lport)
3606 {
3607 struct fc_frame *fp;
3608 struct fc_seq *sp = NULL;
3609@@ -327,60 +339,64 @@ static void fc_disc_gpn_ft_req(struct fc_lport *lp)
3610 } *rp;
3611 int error = 0;
3612
3613- lp->disc_buf_len = 0;
3614- lp->disc_seq_count = 0;
3615- fp = fc_frame_alloc(lp, sizeof(*rp));
3616- if (fp == NULL) {
3617+ lport->disc_buf_len = 0;
3618+ lport->disc_seq_count = 0;
3619+ fp = fc_frame_alloc(lport, sizeof(*rp));
3620+ if (!fp) {
3621 error = ENOMEM;
3622 } else {
3623 rp = fc_frame_payload_get(fp, sizeof(*rp));
3624- fc_fill_dns_hdr(lp, &rp->ct, FC_NS_GPN_FT, sizeof(rp->gid));
3625+ fc_fill_dns_hdr(lport, &rp->ct, FC_NS_GPN_FT, sizeof(rp->gid));
3626 rp->gid.fn_fc4_type = FC_TYPE_FCP;
3627
3628- WARN_ON(!fc_lport_test_ready(lp));
3629+ WARN_ON(!fc_lport_test_ready(lport));
3630
3631 fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
3632- sp = lp->tt.exch_seq_send(lp, fp,
3633- fc_disc_gpn_ft_resp, NULL,
3634- lp, lp->e_d_tov,
3635- lp->fid,
3636- FC_FID_DIR_SERV,
3637- FC_FC_SEQ_INIT | FC_FC_END_SEQ);
3638+ sp = lport->tt.exch_seq_send(lport, fp,
3639+ fc_disc_gpn_ft_resp, NULL,
3640+ lport, lport->e_d_tov,
3641+ fc_host_port_id(lport->host),
3642+ FC_FID_DIR_SERV,
3643+ FC_FC_SEQ_INIT | FC_FC_END_SEQ);
3644 }
3645- if (error || sp == NULL)
3646- fc_disc_retry(lp);
3647+ if (error || !sp)
3648+ fc_disc_retry(lport);
3649 }
3650
3651-/*
3652- * Handle error on dNS request.
3653+/**
3654+ * fc_disc_error - Handle error on dNS request
3655+ * @lport: FC local port
3656+ * @fp: The frame pointer
3657 */
3658-static void fc_disc_error(struct fc_lport *lp, struct fc_frame *fp)
3659+static void fc_disc_error(struct fc_lport *lport, struct fc_frame *fp)
3660 {
3661- int err = PTR_ERR(fp);
3662+ long err = PTR_ERR(fp);
3663
3664+ FC_DEBUG_DISC("Error %ld, retries %d/%d\n", PTR_ERR(fp),
3665+ lport->retry_count, FC_DISC_RETRY_LIMIT);
3666+
3667 switch (err) {
3668 case -FC_EX_TIMEOUT:
3669- if (lp->disc_retry_count++ < FC_DISC_RETRY_LIMIT) {
3670- fc_disc_gpn_ft_req(lp);
3671+ if (lport->disc_retry_count++ < FC_DISC_RETRY_LIMIT) {
3672+ fc_disc_gpn_ft_req(lport);
3673 } else {
3674- FC_DBG("err %d - ending\n", err);
3675- fc_disc_done(lp);
3676+ fc_disc_done(lport);
3677 }
3678 break;
3679 default:
3680- FC_DBG("err %d - ending\n", err);
3681- fc_disc_done(lp);
3682+ FC_DBG("Error code %ld not supported\n", err);
3683+ fc_disc_done(lport);
3684 break;
3685 }
3686 }
3687
3688 /**
3689 * fc_disc_gpn_ft_parse - Parse the list of IDs and names resulting from a request
3690- * @lp: Fibre Channel host port instance
3691+ * @lport: Fibre Channel host port instance
3692 * @buf: GPN_FT response buffer
3693 * @len: size of response buffer
3694 */
3695-static int fc_disc_gpn_ft_parse(struct fc_lport *lp, void *buf, size_t len)
3696+static int fc_disc_gpn_ft_parse(struct fc_lport *lport, void *buf, size_t len)
3697 {
3698 struct fc_gpn_ft_resp *np;
3699 char *bp;
3700@@ -388,8 +404,8 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lp, void *buf, size_t len)
3701 size_t tlen;
3702 int error = 0;
3703 struct fc_disc_port dp;
3704- struct fc_rport *rp;
3705- struct fc_rport_libfc_priv *rpp;
3706+ struct fc_rport *rport;
3707+ struct fc_rport_libfc_priv *rdata;
3708
3709 /*
3710 * Handle partial name record left over from previous call.
3711@@ -397,7 +413,7 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lp, void *buf, size_t len)
3712 bp = buf;
3713 plen = len;
3714 np = (struct fc_gpn_ft_resp *)bp;
3715- tlen = lp->disc_buf_len;
3716+ tlen = lport->disc_buf_len;
3717 if (tlen) {
3718 WARN_ON(tlen >= sizeof(*np));
3719 plen = sizeof(*np) - tlen;
3720@@ -405,7 +421,7 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lp, void *buf, size_t len)
3721 WARN_ON(plen >= sizeof(*np));
3722 if (plen > len)
3723 plen = len;
3724- np = &lp->disc_buf;
3725+ np = &lport->disc_buf;
3726 memcpy((char *)np + tlen, bp, plen);
3727
3728 /*
3729@@ -415,9 +431,9 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lp, void *buf, size_t len)
3730 bp -= tlen;
3731 len += tlen;
3732 plen += tlen;
3733- lp->disc_buf_len = (unsigned char) plen;
3734+ lport->disc_buf_len = (unsigned char) plen;
3735 if (plen == sizeof(*np))
3736- lp->disc_buf_len = 0;
3737+ lport->disc_buf_len = 0;
3738 }
3739
3740 /*
3741@@ -428,19 +444,20 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lp, void *buf, size_t len)
3742 * After the first time through the loop, things return to "normal".
3743 */
3744 while (plen >= sizeof(*np)) {
3745- dp.lp = lp;
3746+ dp.lp = lport;
3747 dp.ids.port_id = ntoh24(np->fp_fid);
3748 dp.ids.port_name = ntohll(np->fp_wwpn);
3749 dp.ids.node_name = -1;
3750 dp.ids.roles = FC_RPORT_ROLE_UNKNOWN;
3751
3752- if ((dp.ids.port_id != lp->fid) &&
3753- (dp.ids.port_name != lp->wwpn)) {
3754- rp = fc_rport_dummy_create(&dp);
3755- if (rp) {
3756- rpp = rp->dd_data;
3757- rpp->local_port = lp;
3758- lp->tt.rport_login(rp);
3759+ if ((dp.ids.port_id != fc_host_port_id(lport->host)) &&
3760+ (dp.ids.port_name != lport->wwpn)) {
3761+ rport = fc_rport_rogue_create(&dp);
3762+ if (rport) {
3763+ rdata = rport->dd_data;
3764+ rdata->event_callback = lport->tt.event_callback;
3765+ rdata->local_port = lport;
3766+ lport->tt.rport_login(rport);
3767 } else
3768 FC_DBG("Failed to allocate memory for "
3769 "the newly discovered port (%6x)\n",
3770@@ -448,7 +465,7 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lp, void *buf, size_t len)
3771 }
3772
3773 if (np->fp_flags & FC_NS_FID_LAST) {
3774- fc_disc_done(lp);
3775+ fc_disc_done(lport);
3776 len = 0;
3777 break;
3778 }
3779@@ -462,11 +479,11 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lp, void *buf, size_t len)
3780 * Save any partial record at the end of the buffer for next time.
3781 */
3782 if (error == 0 && len > 0 && len < sizeof(*np)) {
3783- if (np != &lp->disc_buf)
3784- memcpy(&lp->disc_buf, np, len);
3785- lp->disc_buf_len = (unsigned char) len;
3786+ if (np != &lport->disc_buf)
3787+ memcpy(&lport->disc_buf, np, len);
3788+ lport->disc_buf_len = (unsigned char) len;
3789 } else {
3790- lp->disc_buf_len = 0;
3791+ lport->disc_buf_len = 0;
3792 }
3793 return error;
3794 }
3795@@ -476,14 +493,14 @@ static int fc_disc_gpn_ft_parse(struct fc_lport *lp, void *buf, size_t len)
3796 */
3797 static void fc_disc_timeout(struct work_struct *work)
3798 {
3799- struct fc_lport *lp;
3800+ struct fc_lport *lport;
3801
3802- lp = container_of(work, struct fc_lport, disc_work.work);
3803+ lport = container_of(work, struct fc_lport, disc_work.work);
3804
3805- if (lp->disc_pending)
3806- fc_disc_gpn_ft_req(lp);
3807+ if (lport->disc_pending)
3808+ fc_disc_gpn_ft_req(lport);
3809 else
3810- lp->tt.disc_start(lp);
3811+ lport->tt.disc_start(lport);
3812 }
3813
3814 /**
3815@@ -495,9 +512,9 @@ static void fc_disc_timeout(struct work_struct *work)
3816 * The response may be in multiple frames
3817 */
3818 static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
3819- void *lp_arg)
3820+ void *lp_arg)
3821 {
3822- struct fc_lport *lp = lp_arg;
3823+ struct fc_lport *lport = lp_arg;
3824 struct fc_ct_hdr *cp;
3825 struct fc_frame_header *fh;
3826 unsigned int seq_cnt;
3827@@ -506,7 +523,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
3828 int error;
3829
3830 if (IS_ERR(fp)) {
3831- fc_disc_error(lp, fp);
3832+ fc_disc_error(lport, fp);
3833 return;
3834 }
3835
3836@@ -515,7 +532,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
3837 len = fr_len(fp) - sizeof(*fh);
3838 seq_cnt = ntohs(fh->fh_seq_cnt);
3839 if (fr_sof(fp) == FC_SOF_I3 && seq_cnt == 0 &&
3840- lp->disc_seq_count == 0) {
3841+ lport->disc_seq_count == 0) {
3842 cp = fc_frame_payload_get(fp, sizeof(*cp));
3843 if (cp == NULL) {
3844 FC_DBG("GPN_FT response too short, len %d\n",
3845@@ -531,68 +548,76 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
3846 FC_DBG("GPN_FT rejected reason %x exp %x "
3847 "(check zoning)\n", cp->ct_reason,
3848 cp->ct_explan);
3849- fc_disc_done(lp);
3850+ fc_disc_done(lport);
3851 } else {
3852 FC_DBG("GPN_FT unexpected response code %x\n",
3853 ntohs(cp->ct_cmd));
3854 }
3855 } else if (fr_sof(fp) == FC_SOF_N3 &&
3856- seq_cnt == lp->disc_seq_count) {
3857+ seq_cnt == lport->disc_seq_count) {
3858 buf = fh + 1;
3859 } else {
3860 FC_DBG("GPN_FT unexpected frame - out of sequence? "
3861 "seq_cnt %x expected %x sof %x eof %x\n",
3862- seq_cnt, lp->disc_seq_count, fr_sof(fp), fr_eof(fp));
3863+ seq_cnt, lport->disc_seq_count, fr_sof(fp), fr_eof(fp));
3864 }
3865 if (buf) {
3866- error = fc_disc_gpn_ft_parse(lp, buf, len);
3867+ error = fc_disc_gpn_ft_parse(lport, buf, len);
3868 if (error)
3869- fc_disc_retry(lp);
3870+ fc_disc_retry(lport);
3871 else
3872- lp->disc_seq_count++;
3873+ lport->disc_seq_count++;
3874 }
3875 fc_frame_free(fp);
3876 }
3877
3878-/*
3879- * Discover the directory information for a single target.
3880+/**
3881+ * fc_disc_single - Discover the directory information for a single target
3882+ * @lport: FC local port
3883+ * @dp: The port to rediscover
3884+ *
3885 * This could be from an RSCN that reported a change for the target.
3886 */
3887-static void fc_disc_single(struct fc_lport *lp, struct fc_disc_port *dp)
3888+static void fc_disc_single(struct fc_lport *lport, struct fc_disc_port *dp)
3889 {
3890 struct fc_rport *rport;
3891- struct fc_rport *rp;
3892- struct fc_rport_libfc_priv *rpp;
3893+ struct fc_rport *new_rport;
3894+ struct fc_rport_libfc_priv *rdata;
3895
3896- if (dp->ids.port_id == lp->fid)
3897+ if (dp->ids.port_id == fc_host_port_id(lport->host))
3898 goto out;
3899
3900- rport = lp->tt.rport_lookup(lp, dp->ids.port_id);
3901+ rport = lport->tt.rport_lookup(lport, dp->ids.port_id);
3902 if (rport) {
3903- fc_disc_del_target(lp, rport);
3904+ fc_disc_del_target(lport, rport);
3905 put_device(&rport->dev); /* hold from lookup */
3906 }
3907
3908- rp = fc_rport_dummy_create(dp);
3909- if (rp) {
3910- rpp = rp->dd_data;
3911+ new_rport = fc_rport_rogue_create(dp);
3912+ if (new_rport) {
3913+ rdata = new_rport->dd_data;
3914+ rdata->event_callback = lport->tt.event_callback;
3915 kfree(dp);
3916- lp->tt.rport_login(rp);
3917+ lport->tt.rport_login(new_rport);
3918 }
3919 return;
3920 out:
3921 kfree(dp);
3922 }
3923
3924-int fc_disc_init(struct fc_lport *lp)
3925+/**
3926+ * fc_disc_init - Initialize the discovery block
3927+ * @lport: FC local port
3928+ */
3929+int fc_disc_init(struct fc_lport *lport)
3930 {
3931- INIT_DELAYED_WORK(&lp->disc_work, fc_disc_timeout);
3932+ INIT_DELAYED_WORK(&lport->disc_work, fc_disc_timeout);
3933
3934- if (!lp->tt.disc_start)
3935- lp->tt.disc_start = fc_disc_start;
3936+ if (!lport->tt.disc_start)
3937+ lport->tt.disc_start = fc_disc_start;
3938
3939- if (!lp->tt.disc_recv_req)
3940- lp->tt.disc_recv_req = fc_disc_recv_req;
3941+ if (!lport->tt.disc_recv_req)
3942+ lport->tt.disc_recv_req = fc_disc_recv_req;
3943
3944 return 0;
3945 }
3946diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
3947index ed74d95..80dc1ef 100644
3948--- a/drivers/scsi/libfc/fc_exch.c
3949+++ b/drivers/scsi/libfc/fc_exch.c
3950@@ -37,6 +37,13 @@
3951 * fc_exch_debug can be set in debugger or at compile time to get more logs.
3952 */
3953 static int fc_exch_debug;
3954+
3955+#define FC_DEBUG_EXCH(fmt...) \
3956+ do { \
3957+ if (fc_exch_debug) \
3958+ FC_DBG(fmt); \
3959+ } while (0)
3960+
3961 static struct kmem_cache *fc_em_cachep; /* cache for exchanges */
3962
3963 /*
3964@@ -86,7 +93,7 @@ struct fc_exch {
3965 struct list_head ex_list; /* free or busy list linkage */
3966 spinlock_t ex_lock; /* lock covering exchange state */
3967 atomic_t ex_refcnt; /* reference counter */
3968- struct timer_list ex_timer; /* timer for upper level protocols */
3969+ struct delayed_work timeout_work; /* timer for upper level protocols */
3970 struct fc_lport *lp; /* fc device instance */
3971 u16 oxid; /* originator's exchange ID */
3972 u16 rxid; /* responder's exchange ID */
3973@@ -310,7 +317,6 @@ static void fc_exch_release(struct fc_exch *ep)
3974 if (ep->lp->tt.exch_put)
3975 ep->lp->tt.exch_put(ep->lp, mp, ep->xid);
3976 WARN_ON(!ep->esb_stat & ESB_ST_COMPLETE);
3977- WARN_ON(timer_pending(&ep->ex_timer));
3978 mempool_free(ep, mp->ep_pool);
3979 }
3980 }
3981@@ -332,7 +338,7 @@ static int fc_exch_done_locked(struct fc_exch *ep)
3982
3983 if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
3984 ep->state |= FC_EX_DONE;
3985- if (del_timer(&ep->ex_timer))
3986+ if (cancel_delayed_work(&ep->timeout_work))
3987 atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
3988 rc = 0;
3989 }
3990@@ -362,7 +368,10 @@ static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
3991 if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
3992 return;
3993
3994- if (!mod_timer(&ep->ex_timer, jiffies + msecs_to_jiffies(timer_msec)))
3995+ FC_DEBUG_EXCH("Exchange (%4x) timed out, notifying the upper layer\n",
3996+ ep->xid);
3997+ if (schedule_delayed_work(&ep->timeout_work,
3998+ jiffies + msecs_to_jiffies(timer_msec)))
3999 fc_exch_hold(ep); /* hold for timer */
4000 }
4001
4002@@ -435,9 +444,10 @@ EXPORT_SYMBOL(fc_seq_exch_abort);
4003 * Exchange timeout - handle exchange timer expiration.
4004 * The timer will have been cancelled before this is called.
4005 */
4006-static void fc_exch_timeout(unsigned long ep_arg)
4007+static void fc_exch_timeout(struct work_struct *work)
4008 {
4009- struct fc_exch *ep = (struct fc_exch *)ep_arg;
4010+ struct fc_exch *ep = container_of(work, struct fc_exch,
4011+ timeout_work.work);
4012 struct fc_seq *sp = &ep->seq;
4013 void (*resp)(struct fc_seq *, struct fc_frame *fp, void *arg);
4014 void *arg;
4015@@ -584,7 +594,7 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, u16 xid)
4016 ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */
4017 ep->rxid = FC_XID_UNKNOWN;
4018 ep->class = mp->class;
4019- setup_timer(&ep->ex_timer, fc_exch_timeout, (unsigned long)ep);
4020+ INIT_DELAYED_WORK(&ep->timeout_work, fc_exch_timeout);
4021 out:
4022 return ep;
4023 err:
4024@@ -843,9 +853,8 @@ static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp)
4025 struct fc_exch *ep = fc_seq_exch(sp);
4026
4027 sp = fc_seq_alloc(ep, ep->seq_id++);
4028- if (fc_exch_debug)
4029- FC_DBG("exch %4x f_ctl %6x seq %2x f_ctl %6x\n",
4030- ep->xid, ep->f_ctl, sp->id, sp->f_ctl);
4031+ FC_DEBUG_EXCH("exch %4x f_ctl %6x seq %2x f_ctl %6x\n",
4032+ ep->xid, ep->f_ctl, sp->id, sp->f_ctl);
4033 return sp;
4034 }
4035 /*
4036@@ -913,7 +922,18 @@ int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp,
4037 }
4038
4039 hton24(fh->fh_f_ctl, f_ctl | fill);
4040- fh->fh_seq_cnt = htons(sp->cnt++);
4041+ fh->fh_seq_cnt = htons(sp->cnt);
4042+
4043+ /*
4044+ * update sequence count if this frame is carrying
4045+ * multiple FC frames when sequence offload is enabled
4046+ * by LLD.
4047+ */
4048+ if (fr_max_payload(fp))
4049+ sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)),
4050+ fr_max_payload(fp));
4051+ else
4052+ sp->cnt++;
4053
4054 /*
4055 * Send the frame.
4056@@ -1185,8 +1205,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp,
4057 lp->tt.lport_recv(lp, sp, fp);
4058 fc_exch_release(ep); /* release from lookup */
4059 } else {
4060- if (fc_exch_debug)
4061- FC_DBG("exch/seq lookup failed: reject %x\n", reject);
4062+ FC_DEBUG_EXCH("exch/seq lookup failed: reject %x\n", reject);
4063 fc_frame_free(fp);
4064 }
4065 }
4066@@ -1290,12 +1309,10 @@ static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
4067 sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */
4068 if (!sp) {
4069 atomic_inc(&mp->stats.xid_not_found);
4070- if (fc_exch_debug)
4071- FC_DBG("seq lookup failed\n");
4072+ FC_DEBUG_EXCH("seq lookup failed\n");
4073 } else {
4074 atomic_inc(&mp->stats.non_bls_resp);
4075- if (fc_exch_debug)
4076- FC_DBG("non-BLS response to sequence");
4077+ FC_DEBUG_EXCH("non-BLS response to sequence");
4078 }
4079 fc_frame_free(fp);
4080 }
4081@@ -1316,11 +1333,10 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
4082 int rc = 1, has_rec = 0;
4083
4084 fh = fc_frame_header_get(fp);
4085- if (fc_exch_debug)
4086- FC_DBG("exch: BLS rctl %x - %s\n",
4087- fh->fh_r_ctl, fc_exch_rctl_name(fh->fh_r_ctl));
4088+ FC_DEBUG_EXCH("exch: BLS rctl %x - %s\n",
4089+ fh->fh_r_ctl, fc_exch_rctl_name(fh->fh_r_ctl));
4090
4091- if (del_timer_sync(&ep->ex_timer))
4092+ if (cancel_delayed_work_sync(&ep->timeout_work))
4093 fc_exch_release(ep); /* release from pending timer hold */
4094
4095 spin_lock_bh(&ep->ex_lock);
4096@@ -1410,10 +1426,9 @@ static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp)
4097 case FC_RCTL_ACK_0:
4098 break;
4099 default:
4100- if (fc_exch_debug)
4101- FC_DBG("BLS rctl %x - %s received",
4102- fh->fh_r_ctl,
4103- fc_exch_rctl_name(fh->fh_r_ctl));
4104+ FC_DEBUG_EXCH("BLS rctl %x - %s received",
4105+ fh->fh_r_ctl,
4106+ fc_exch_rctl_name(fh->fh_r_ctl));
4107 break;
4108 }
4109 fc_frame_free(fp);
4110@@ -1498,7 +1513,7 @@ static void fc_exch_reset(struct fc_exch *ep)
4111 * functions can also grab the lport lock which could cause
4112 * a deadlock).
4113 */
4114- if (del_timer(&ep->ex_timer))
4115+ if (cancel_delayed_work(&ep->timeout_work))
4116 atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
4117 resp = ep->resp;
4118 ep->resp = NULL;
4119@@ -1720,7 +1735,7 @@ static void fc_exch_rrq(struct fc_exch *ep)
4120 if (ep->esb_stat & ESB_ST_RESP)
4121 did = ep->sid;
4122 rrq_sp = fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, ep,
4123- lp->e_d_tov, lp->fid, did,
4124+ lp->e_d_tov, fc_host_port_id(lp->host), did,
4125 FC_FC_SEQ_INIT | FC_FC_END_SEQ);
4126 if (!rrq_sp) {
4127 ep->esb_stat |= ESB_ST_REC_QUAL;
4128@@ -1774,8 +1789,10 @@ static void fc_exch_els_rrq(struct fc_seq *sp, struct fc_frame *fp)
4129 ep->esb_stat &= ~ESB_ST_REC_QUAL;
4130 atomic_dec(&ep->ex_refcnt); /* drop hold for rec qual */
4131 }
4132- if ((ep->esb_stat & ESB_ST_COMPLETE) && (del_timer(&ep->ex_timer)))
4133- atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
4134+ if (ep->esb_stat & ESB_ST_COMPLETE) {
4135+ if (cancel_delayed_work(&ep->timeout_work))
4136+ atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
4137+ }
4138
4139 spin_unlock_bh(&ep->ex_lock);
4140
4141diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
4142index 2566eed..bf8202f 100644
4143--- a/drivers/scsi/libfc/fc_fcp.c
4144+++ b/drivers/scsi/libfc/fc_fcp.c
4145@@ -42,22 +42,29 @@ MODULE_AUTHOR("Open-FCoE.org");
4146 MODULE_DESCRIPTION("libfc");
4147 MODULE_LICENSE("GPL");
4148
4149-int fc_fcp_debug;
4150+static int fc_fcp_debug;
4151+
4152+#define FC_DEBUG_FCP(fmt...) \
4153+ do { \
4154+ if (fc_fcp_debug) \
4155+ FC_DBG(fmt); \
4156+ } while (0)
4157+
4158 static struct kmem_cache *scsi_pkt_cachep;
4159
4160 /* SRB state definitions */
4161-#define FC_SRB_FREE 0 /* cmd is free */
4162-#define FC_SRB_CMD_SENT (1 << 0) /* cmd has been sent */
4163-#define FC_SRB_RCV_STATUS (1 << 1) /* response has arrived */
4164-#define FC_SRB_ABORT_PENDING (1 << 2) /* cmd abort sent to device */
4165-#define FC_SRB_ABORTED (1 << 3) /* abort acknowleged */
4166-#define FC_SRB_DISCONTIG (1 << 4) /* non-sequential data recvd */
4167-#define FC_SRB_COMPL (1 << 5) /* fc_io_compl has been run */
4168+#define FC_SRB_FREE 0 /* cmd is free */
4169+#define FC_SRB_CMD_SENT (1 << 0) /* cmd has been sent */
4170+#define FC_SRB_RCV_STATUS (1 << 1) /* response has arrived */
4171+#define FC_SRB_ABORT_PENDING (1 << 2) /* cmd abort sent to device */
4172+#define FC_SRB_ABORTED (1 << 3) /* abort acknowleged */
4173+#define FC_SRB_DISCONTIG (1 << 4) /* non-sequential data recvd */
4174+#define FC_SRB_COMPL (1 << 5) /* fc_io_compl has been run */
4175 #define FC_SRB_FCP_PROCESSING_TMO (1 << 6) /* timer function processing */
4176-#define FC_SRB_NOMEM (1 << 7) /* dropped to out of mem */
4177+#define FC_SRB_NOMEM (1 << 7) /* dropped to out of mem */
4178
4179-#define FC_SRB_READ (1 << 1)
4180-#define FC_SRB_WRITE (1 << 0)
4181+#define FC_SRB_READ (1 << 1)
4182+#define FC_SRB_WRITE (1 << 0)
4183
4184 /*
4185 * scsi request structure, one for each scsi request
4186@@ -184,8 +191,8 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *, struct fc_frame *);
4187 #define FC_SCSI_REC_TOV (2 * HZ)
4188 #define FC_HOST_RESET_TIMEOUT (30 * HZ)
4189
4190-#define FC_MAX_ERROR_CNT 5
4191-#define FC_MAX_RECOV_RETRY 3
4192+#define FC_MAX_ERROR_CNT 5
4193+#define FC_MAX_RECOV_RETRY 3
4194
4195 #define FC_FCP_DFLT_QUEUE_DEPTH 32
4196
4197@@ -353,11 +360,8 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
4198 if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) &&
4199 fc_frame_crc_check(fp))
4200 goto crc_err;
4201- if (fc_fcp_debug) {
4202- FC_DBG("data received past end. "
4203- "len %zx offset %zx "
4204- "data_len %x\n", len, offset, fsp->data_len);
4205- }
4206+ FC_DEBUG_FCP("data received past end. len %zx offset %zx "
4207+ "data_len %x\n", len, offset, fsp->data_len);
4208 fc_fcp_retry_cmd(fsp);
4209 return;
4210 }
4211@@ -449,55 +453,54 @@ crc_err:
4212 /*
4213 * Send SCSI data to target.
4214 * Called after receiving a Transfer Ready data descriptor.
4215+ * if LLD is capable of seq offload then send down seq_blen
4216+ * size of data in single frame, otherwise send multiple FC
4217+ * frames of max FC frame payload supported by target port.
4218 */
4219 static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *sp,
4220- size_t offset, size_t len,
4221- struct fc_frame *oldfp, int sg_supp)
4222+ size_t offset, size_t seq_blen)
4223 {
4224 struct scsi_cmnd *sc;
4225 struct scatterlist *sg;
4226 struct fc_frame *fp = NULL;
4227 struct fc_lport *lp = fsp->lp;
4228 size_t remaining;
4229- size_t mfs;
4230+ size_t t_blen;
4231 size_t tlen;
4232 size_t sg_bytes;
4233 size_t frame_offset;
4234 int error;
4235 void *data = NULL;
4236 void *page_addr;
4237- int using_sg = sg_supp;
4238+ int using_sg = lp->sg_supp;
4239 u32 f_ctl;
4240
4241- if (unlikely(offset + len > fsp->data_len)) {
4242- /*
4243- * this should never happen
4244- */
4245- if (fc_fcp_debug) {
4246- FC_DBG("xfer-ready past end. len %zx offset %zx\n",
4247- len, offset);
4248- }
4249+ WARN_ON(seq_blen <= 0);
4250+ if (unlikely(offset + seq_blen > fsp->data_len)) {
4251+ /* this should never happen */
4252+ FC_DEBUG_FCP("xfer-ready past end. seq_blen %zx offset %zx\n",
4253+ seq_blen, offset);
4254 fc_fcp_send_abort(fsp);
4255 return 0;
4256 } else if (offset != fsp->xfer_len) {
4257- /*
4258- * Out of Order Data Request - no problem, but unexpected.
4259- */
4260- if (fc_fcp_debug) {
4261- FC_DBG("xfer-ready non-contiguous. "
4262- "len %zx offset %zx\n", len, offset);
4263- }
4264+ /* Out of Order Data Request - no problem, but unexpected. */
4265+ FC_DEBUG_FCP("xfer-ready non-contiguous. "
4266+ "seq_blen %zx offset %zx\n", seq_blen, offset);
4267 }
4268- mfs = fsp->max_payload;
4269- WARN_ON(mfs > FC_MAX_PAYLOAD);
4270- WARN_ON(mfs < FC_MIN_MAX_PAYLOAD);
4271- if (mfs > 512)
4272- mfs &= ~(512 - 1); /* round down to block size */
4273- WARN_ON(mfs < FC_MIN_MAX_PAYLOAD); /* won't go below 256 */
4274- WARN_ON(len <= 0);
4275+
4276+ /*
4277+ * if LLD is capable of seq_offload then set transport
4278+ * burst length (t_blen) to seq_blen, otherwise set t_blen
4279+ * to max FC frame payload previously set in fsp->max_payload.
4280+ */
4281+ t_blen = lp->seq_offload ? seq_blen : fsp->max_payload;
4282+ WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD);
4283+ if (t_blen > 512)
4284+ t_blen &= ~(512 - 1); /* round down to block size */
4285+ WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD); /* won't go below 256 */
4286 sc = fsp->cmd;
4287
4288- remaining = len;
4289+ remaining = seq_blen;
4290 frame_offset = offset;
4291 tlen = 0;
4292 sp = lp->tt.seq_start_next(sp);
4293@@ -540,7 +543,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *sp,
4294 continue;
4295 }
4296 if (!fp) {
4297- tlen = min(mfs, remaining);
4298+ tlen = min(t_blen, remaining);
4299
4300 /*
4301 * TODO. Temporary workaround. fc_seq_send() can't
4302@@ -563,6 +566,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *sp,
4303 }
4304 fc_frame_setup(fp, FC_RCTL_DD_SOL_DATA, FC_TYPE_FCP);
4305 fc_frame_set_offset(fp, frame_offset);
4306+ fr_max_payload(fp) = fsp->max_payload;
4307 }
4308 sg_bytes = min(tlen, sg->length - offset);
4309 if (using_sg) {
4310@@ -621,7 +625,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *sp,
4311 return 0;
4312 }
4313 }
4314- fsp->xfer_len += len; /* premature count? */
4315+ fsp->xfer_len += seq_blen; /* premature count? */
4316 return 0;
4317 }
4318
4319@@ -741,8 +745,7 @@ static void fc_fcp_recv(struct fc_seq *sp, struct fc_frame *fp, void *arg)
4320
4321 rc = fc_fcp_send_data(fsp, sp,
4322 (size_t) ntohl(dd->ft_data_ro),
4323- (size_t) ntohl(dd->ft_burst_len), fp,
4324- lp->capabilities & TRANS_C_SG);
4325+ (size_t) ntohl(dd->ft_burst_len));
4326 if (!rc)
4327 lp->tt.seq_set_rec_data(sp, fsp->xfer_len);
4328 else if (rc == -ENOMEM)
4329@@ -1066,7 +1069,7 @@ static int fc_fcp_send_cmd(struct fc_fcp_pkt *fsp)
4330 fc_fcp_recv,
4331 fc_fcp_pkt_destroy,
4332 fsp, 0,
4333- rp->local_port->fid,
4334+ fc_host_port_id(rp->local_port->host),
4335 rport->port_id,
4336 FC_FC_SEQ_INIT | FC_FC_END_SEQ);
4337 if (!sp) {
4338@@ -1175,7 +1178,7 @@ static void fc_lun_reset_send(unsigned long data)
4339 fc_tm_done,
4340 fc_fcp_pkt_destroy,
4341 fsp, 0,
4342- rp->local_port->fid,
4343+ fc_host_port_id(rp->local_port->host),
4344 rport->port_id,
4345 FC_FC_SEQ_INIT | FC_FC_END_SEQ);
4346
4347@@ -1367,7 +1370,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
4348 rec = fc_frame_payload_get(fp, sizeof(*rec));
4349 memset(rec, 0, sizeof(*rec));
4350 rec->rec_cmd = ELS_REC;
4351- hton24(rec->rec_s_id, lp->fid);
4352+ hton24(rec->rec_s_id, fc_host_port_id(lp->host));
4353 rec->rec_ox_id = htons(ox_id);
4354 rec->rec_rx_id = htons(rx_id);
4355
4356@@ -1376,7 +1379,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
4357 sp = lp->tt.exch_seq_send(lp, fp,
4358 fc_fcp_rec_resp, NULL,
4359 fsp, jiffies_to_msecs(FC_SCSI_REC_TOV),
4360- rp->local_port->fid,
4361+ fc_host_port_id(rp->local_port->host),
4362 rport->port_id,
4363 FC_FC_SEQ_INIT | FC_FC_END_SEQ);
4364
4365@@ -1425,16 +1428,13 @@ static void fc_fcp_rec_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg)
4366 rjt = fc_frame_payload_get(fp, sizeof(*rjt));
4367 switch (rjt->er_reason) {
4368 default:
4369- if (fc_fcp_debug)
4370- FC_DBG("device %x unexpected REC reject "
4371- "reason %d expl %d\n",
4372- fsp->rport->port_id, rjt->er_reason,
4373- rjt->er_explan);
4374+ FC_DEBUG_FCP("device %x unexpected REC reject "
4375+ "reason %d expl %d\n",
4376+ fsp->rport->port_id, rjt->er_reason,
4377+ rjt->er_explan);
4378 /* fall through */
4379-
4380 case ELS_RJT_UNSUP:
4381- if (fc_fcp_debug)
4382- FC_DBG("device does not support REC\n");
4383+ FC_DEBUG_FCP("device does not support REC\n");
4384 rp = fsp->rport->dd_data;
4385 /*
4386 * if we do not spport RECs or got some bogus
4387@@ -1636,7 +1636,7 @@ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
4388 sp = lp->tt.exch_seq_send(lp, fp,
4389 fc_fcp_srr_resp, NULL,
4390 fsp, jiffies_to_msecs(FC_SCSI_REC_TOV),
4391- rp->local_port->fid,
4392+ fc_host_port_id(rp->local_port->host),
4393 rport->port_id,
4394 FC_FC_SEQ_INIT | FC_FC_END_SEQ);
4395 if (!sp) {
4396@@ -2199,7 +2199,17 @@ static int __init libfc_init(void)
4397
4398 rc = fc_setup_exch_mgr();
4399 if (rc)
4400- kmem_cache_destroy(scsi_pkt_cachep);
4401+ goto destroy_pkt_cache;
4402+
4403+ rc = fc_setup_rport();
4404+ if (rc)
4405+ goto destroy_em;
4406+
4407+ return rc;
4408+destroy_em:
4409+ fc_destroy_exch_mgr();
4410+destroy_pkt_cache:
4411+ kmem_cache_destroy(scsi_pkt_cachep);
4412 return rc;
4413 }
4414
4415@@ -2207,6 +2217,7 @@ static void __exit libfc_exit(void)
4416 {
4417 kmem_cache_destroy(scsi_pkt_cachep);
4418 fc_destroy_exch_mgr();
4419+ fc_destroy_rport();
4420 }
4421
4422 module_init(libfc_init);
4423diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
4424index b1854b9..bfbc7d4 100644
4425--- a/drivers/scsi/libfc/fc_lport.c
4426+++ b/drivers/scsi/libfc/fc_lport.c
4427@@ -18,7 +18,59 @@
4428 */
4429
4430 /*
4431- * Logical interface support.
4432+ * General locking notes:
4433+ *
4434+ * The lport and rport blocks both have mutexes that are used to protect
4435+ * the port objects states. The main motivation for this protection is that
4436+ * we don't want to be preparing a request/response in one context while
4437+ * another thread "resets" the port in question. For example, if the lport
4438+ * block is sending a SCR request to the directory server we don't want
4439+ * the lport to be reset before we fill out the frame header's port_id. The
4440+ * problem is that a reset would cause the lport's port_id to reset to 0.
4441+ * If we don't protect the lport we'd spew incorrect frames.
82094b55 4442+ *
2cb7cef9
BS
4443+ * At the time of this writing there are two primary mutexes, one for the
4444+ * lport and one for the rport. Since the lport uses the rport and makes
4445+ * calls into that block the rport should never make calls that would cause
4446+ * the lport's mutex to be locked. In other words, the lport's mutex is
4447+ * considered the outer lock and the rport's lock is considered the inner
4448+ * lock. The bottom line is that you can hold a lport's mutex and then
4449+ * hold the rport's mutex, but not the other way around.
4450+ *
4451+ * The only complication to this rule is the callbacks from the rport to
4452+ * the lport's event_callback function. When rports become READY they make
4453+ * a callback to the lport so that it can track them. In the case of the
4454+ * directory server that callback might cause the lport to change its
4455+ * state, implying that the lport mutex would need to be held. This problem
4456+ * was solved by serializing the rport notifications to the lport and the
4457+ * callback is made without holding the rport's lock.
4458+ *
4459+ * lport locking notes:
4460+ *
4461+ * The critical sections protected by the lport's mutex are quite broad and
4462+ * may be improved upon in the future. The lport code and its locking doesn't
4463+ * influence the I/O path, so excessive locking doesn't penalize I/O
4464+ * performance.
4465+ *
4466+ * The strategy is to lock whenever processing a request or response. Note
4467+ * that every _enter_* function corresponds to a state change. They generally
4468+ * change the lports state and then sends a request out on the wire. We lock
4469+ * before calling any of these functions to protect that state change. This
4470+ * means that the entry points into the lport block to manage the locks while
4471+ * the state machine can transition between states (i.e. _enter_* functions)
4472+ * while always staying protected.
4473+ *
4474+ * When handling responses we also hold the lport mutex broadly. When the
4475+ * lport receives the response frame it locks the mutex and then calls the
4476+ * appropriate handler for the particuar response. Generally a response will
4477+ * trigger a state change and so the lock must already be held.
4478+ *
4479+ * Retries also have to consider the locking. The retries occur from a work
4480+ * context and the work function will lock the lport and then retry the state
4481+ * (i.e. _enter_* function).
4482+ *
4483+ * The implication to all of this is that each lport can only process one
4484+ * state at a time.
4485 */
4486
4487 #include <linux/timer.h>
4488@@ -36,6 +88,12 @@
4489
4490 static int fc_lport_debug;
4491
4492+#define FC_DEBUG_LPORT(fmt...) \
4493+ do { \
4494+ if (fc_lport_debug) \
4495+ FC_DBG(fmt); \
4496+ } while (0)
4497+
4498 static void fc_lport_error(struct fc_lport *, struct fc_frame *);
4499
4500 static void fc_lport_enter_reset(struct fc_lport *);
4501@@ -66,41 +124,71 @@ static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
4502 }
4503
4504 /**
4505+ * fc_lport_lookup_rport - lookup a remote port by port_id
4506+ * @lport: Fibre Channel host port instance
4507+ * @port_id: remote port port_id to match
4508+ */
4509+struct fc_rport *fc_lport_lookup_rport(const struct fc_lport *lport,
4510+ u32 port_id)
4511+{
4512+ struct fc_rport *rport, *found;
4513+ struct fc_rport_libfc_priv *rdata;
4514+
4515+ found = NULL;
4516+
4517+ list_for_each_entry(rdata, &lport->rports, peers) {
4518+ rport = PRIV_TO_RPORT(rdata);
4519+ if (rport->port_id == port_id) {
4520+ found = rport;
4521+ get_device(&found->dev);
4522+ break;
4523+ }
4524+ }
4525+ return found;
4526+}
4527+
4528+
4529+
4530+/**
4531 * fc_lport_rport_event - Event handler for rport events
4532 * @lport: The lport which is receiving the event
4533- * @port_id: The FID of the rport which the event has occured on
4534+ * @rport: The rport which the event has occured on
4535 * @event: The event that occured
4536 *
4537 * Locking Note: The rport lock should not be held when calling
4538 * this function.
4539 */
4540-static void fc_lport_rport_event(struct fc_lport *lport, u32 port_id,
4541+static void fc_lport_rport_event(struct fc_lport *lport,
4542+ struct fc_rport *rport,
4543 enum fc_lport_event event)
4544 {
4545- struct fc_rport *rport = lport->tt.rport_lookup(lport, port_id);
4546+ struct fc_rport_libfc_priv *rdata = rport->dd_data;
4547
4548- if (fc_lport_debug)
4549- FC_DBG("Received a %d event for port (%6x)\n", event, port_id);
4550+ FC_DEBUG_LPORT("Received a %d event for port (%6x)\n", event,
4551+ rport->port_id);
4552
4553- if (port_id == FC_FID_DIR_SERV) {
4554- mutex_lock(&lport->lp_mutex);
4555- switch (event) {
4556- case LPORT_EV_RPORT_CREATED:
4557- if (rport) {
4558- lport->dns_rp = rport;
4559- fc_lport_enter_rpn_id(lport);
4560- }
4561- break;
4562- case LPORT_EV_RPORT_LOGO:
4563- case LPORT_EV_RPORT_FAILED:
4564- lport->dns_rp = NULL;
4565- fc_lport_enter_dns(lport);
4566- break;
4567- case LPORT_EV_RPORT_NONE:
4568- break;
4569+ mutex_lock(&lport->lp_mutex);
4570+ switch (event) {
4571+ case LPORT_EV_RPORT_CREATED:
4572+ if (rport->port_id == FC_FID_DIR_SERV) {
4573+ lport->dns_rp = rport;
4574+ fc_lport_enter_rpn_id(lport);
4575+ } else {
4576+ list_add_tail(&rdata->peers, &lport->rports);
4577 }
4578- mutex_unlock(&lport->lp_mutex);
4579+ break;
4580+ case LPORT_EV_RPORT_LOGO:
4581+ case LPORT_EV_RPORT_FAILED:
4582+ case LPORT_EV_RPORT_STOP:
4583+ if (rport->port_id == FC_FID_DIR_SERV)
4584+ lport->dns_rp = NULL;
4585+ else
4586+ list_del(&rdata->peers);
4587+ break;
4588+ case LPORT_EV_RPORT_NONE:
4589+ break;
4590 }
4591+ mutex_unlock(&lport->lp_mutex);
4592 }
4593
4594 /**
4595@@ -118,18 +206,6 @@ static const char *fc_lport_state(struct fc_lport *lport)
4596 }
4597
4598 /**
4599- * fc_lport_ptp_clear - Delete the ptp rport
4600- * @lport: The lport whose ptp rport should be removed
4601- */
4602-static void fc_lport_ptp_clear(struct fc_lport *lport)
4603-{
4604- if (lport->ptp_rp) {
4605- fc_remote_port_delete(lport->ptp_rp);
4606- lport->ptp_rp = NULL;
4607- }
4608-}
4609-
4610-/**
4611 * fc_lport_ptp_setup - Create an rport for point-to-point mode
4612 * @lport: The lport to attach the ptp rport to
4613 * @fid: The FID of the ptp rport
4614@@ -148,19 +224,25 @@ static void fc_lport_ptp_setup(struct fc_lport *lport,
4615 dp.ids.node_name = remote_wwnn;
4616 dp.ids.roles = FC_RPORT_ROLE_UNKNOWN;
4617
4618- fc_lport_ptp_clear(lport);
4619+ if (lport->ptp_rp) {
4620+ lport->tt.rport_stop(lport->ptp_rp);
4621+ lport->ptp_rp = NULL;
4622+ }
4623
4624- lport->ptp_rp = fc_rport_dummy_create(&dp);
4625+ lport->ptp_rp = fc_rport_rogue_create(&dp);
4626
4627 lport->tt.rport_login(lport->ptp_rp);
4628
4629 fc_lport_enter_ready(lport);
4630 }
4631
4632-/**
4633- * fc_get_host_port_state - supports fc_function_template
4634- * @shost: The host whose port state should be returned
4635- */
4636+void fc_get_host_port_type(struct Scsi_Host *shost)
4637+{
4638+ /* TODO - currently just NPORT */
4639+ fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
4640+}
4641+EXPORT_SYMBOL(fc_get_host_port_type);
4642+
4643 void fc_get_host_port_state(struct Scsi_Host *shost)
4644 {
4645 struct fc_lport *lp = shost_priv(shost);
4646@@ -277,8 +359,7 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
4647 static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
4648 struct fc_lport *lport)
4649 {
4650- if (fc_lport_debug)
4651- FC_DBG("Received RLIR request while in state %s\n",
4652+ FC_DEBUG_LPORT("Received RLIR request while in state %s\n",
4653 fc_lport_state(lport));
4654
4655 lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
4656@@ -303,8 +384,7 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
4657 void *dp;
4658 u32 f_ctl;
4659
4660- if (fc_lport_debug)
4661- FC_DBG("Received RLIR request while in state %s\n",
4662+ FC_DEBUG_LPORT("Received RLIR request while in state %s\n",
4663 fc_lport_state(lport));
4664
4665 len = fr_len(in_fp) - sizeof(struct fc_frame_header);
4666@@ -350,8 +430,7 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
4667 size_t len;
4668 u32 f_ctl;
4669
4670- if (fc_lport_debug)
4671- FC_DBG("Received RNID request while in state %s\n",
4672+ FC_DEBUG_LPORT("Received RNID request while in state %s\n",
4673 fc_lport_state(lport));
4674
4675 req = fc_frame_payload_get(in_fp, sizeof(*req));
4676@@ -520,12 +599,10 @@ EXPORT_SYMBOL(fc_fabric_logoff);
4677 **/
4678 int fc_lport_destroy(struct fc_lport *lport)
4679 {
4680- mutex_lock(&lport->lp_mutex);
4681 cancel_delayed_work_sync(&lport->disc_work);
4682 lport->tt.scsi_abort_io(lport);
4683 lport->tt.frame_send = fc_frame_drop;
4684 lport->tt.exch_mgr_reset(lport->emp, 0, 0);
4685- mutex_unlock(&lport->lp_mutex);
4686 return 0;
4687 }
4688 EXPORT_SYMBOL(fc_lport_destroy);
4689@@ -569,9 +646,8 @@ EXPORT_SYMBOL(fc_set_mfs);
4690 */
4691 static void fc_lport_enter_ready(struct fc_lport *lport)
4692 {
4693- if (fc_lport_debug)
4694- FC_DBG("Port (%6x) entered Ready from state %s\n",
4695- lport->fid, fc_lport_state(lport));
4696+ FC_DEBUG_LPORT("Port (%6x) entered Ready from state %s\n",
4697+ fc_host_port_id(lport->host), fc_lport_state(lport));
4698
4699 fc_lport_state_enter(lport, LPORT_ST_READY);
4700
4701@@ -605,8 +681,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
4702 u32 local_fid;
4703 u32 f_ctl;
4704
4705- if (fc_lport_debug)
4706- FC_DBG("Received FLOGI request while in state %s\n",
4707+ FC_DEBUG_LPORT("Received FLOGI request while in state %s\n",
4708 fc_lport_state(lport));
4709
4710 fh = fc_frame_header_get(rx_fp);
4711@@ -636,7 +711,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
4712 remote_fid = FC_LOCAL_PTP_FID_HI;
4713 }
4714
4715- lport->fid = local_fid;
4716+ fc_host_port_id(lport->host) = local_fid;
4717
4718 fp = fc_frame_alloc(lport, sizeof(*flp));
4719 if (fp) {
4720@@ -733,7 +808,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
4721 s_id = ntoh24(fh->fh_s_id);
4722 d_id = ntoh24(fh->fh_d_id);
4723
4724- rport = lport->tt.rport_lookup(lport, s_id);
4725+ rport = fc_lport_lookup_rport(lport, s_id);
4726 if (rport) {
4727 lport->tt.rport_recv_req(sp, fp, rport);
4728 put_device(&rport->dev); /* hold from lookup */
4729@@ -752,6 +827,12 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
4730 fc_frame_free(fp);
4731 }
4732 mutex_unlock(&lport->lp_mutex);
4733+
4734+ /*
4735+ * The common exch_done for all request may not be good
4736+ * if any request requires longer hold on exhange. XXX
4737+ */
4738+ lport->tt.exch_done(sp);
4739 }
4740
4741 /**
4742@@ -771,6 +852,24 @@ int fc_lport_reset(struct fc_lport *lport)
4743 EXPORT_SYMBOL(fc_lport_reset);
4744
4745 /**
4746+ * fc_lport_stop_rports - delete all the remote ports associated with the lport
4747+ * @lport: libfc local port instance
4748+ *
4749+ * Locking Note: This function expects that the lport mutex is locked before
4750+ * calling it.
4751+ */
4752+void fc_lport_stop_rports(struct fc_lport *lport)
4753+{
4754+ struct fc_rport *rport;
4755+ struct fc_rport_libfc_priv *rdata;
4756+
4757+ list_for_each_entry(rdata, &lport->rports, peers) {
4758+ rport = PRIV_TO_RPORT(rdata);
4759+ lport->tt.rport_stop(rport);
4760+ }
4761+}
4762+
4763+/**
4764 * fc_rport_enter_reset - Reset the local port
4765 * @lport: Fibre Channel local port to be reset
4766 *
4767@@ -779,24 +878,26 @@ EXPORT_SYMBOL(fc_lport_reset);
4768 */
4769 static void fc_lport_enter_reset(struct fc_lport *lport)
4770 {
4771- if (fc_lport_debug)
4772- FC_DBG("Port (%6x) entered RESET state from %s state\n",
4773- lport->fid, fc_lport_state(lport));
4774+ FC_DEBUG_LPORT("Port (%6x) entered RESET state from %s state\n",
4775+ fc_host_port_id(lport->host), fc_lport_state(lport));
4776
4777 fc_lport_state_enter(lport, LPORT_ST_RESET);
4778
4779 if (lport->dns_rp) {
4780- fc_remote_port_delete(lport->dns_rp);
4781+ lport->tt.rport_stop(lport->dns_rp);
4782 lport->dns_rp = NULL;
4783 }
4784- fc_lport_ptp_clear(lport);
4785
4786- fc_block_rports(lport);
4787+ if (lport->ptp_rp) {
4788+ lport->tt.rport_stop(lport->ptp_rp);
4789+ lport->ptp_rp = NULL;
4790+ }
4791+
4792+ fc_lport_stop_rports(lport);
4793
4794- lport->tt.rport_reset_list(lport);
4795 lport->tt.exch_mgr_reset(lport->emp, 0, 0);
4796 fc_host_fabric_name(lport->host) = 0;
4797- lport->fid = 0;
4798+ fc_host_port_id(lport->host) = 0;
4799
4800 if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP)
4801 fc_lport_enter_flogi(lport);
4802@@ -814,33 +915,38 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
4803 static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
4804 {
4805 unsigned long delay = 0;
4806- if (fc_lport_debug)
4807- FC_DBG("Error %ld in state %s, retries %d\n",
4808+ FC_DEBUG_LPORT("Error %ld in state %s, retries %d\n",
4809 PTR_ERR(fp), fc_lport_state(lport),
4810 lport->retry_count);
4811
4812- if (lport->retry_count < lport->max_retry_count) {
4813- lport->retry_count++;
4814- if (!fp)
4815- delay = msecs_to_jiffies(500);
4816- else
4817- delay = jiffies +
4818- msecs_to_jiffies(lport->e_d_tov);
4819-
4820- schedule_delayed_work(&lport->retry_work, delay);
4821- } else {
4822- switch (lport->state) {
4823- case LPORT_ST_NONE:
4824- case LPORT_ST_READY:
4825- case LPORT_ST_RESET:
4826- case LPORT_ST_RPN_ID:
4827- case LPORT_ST_RFT_ID:
4828- case LPORT_ST_SCR:
4829- case LPORT_ST_DNS:
4830- case LPORT_ST_FLOGI:
4831- case LPORT_ST_LOGO:
4832- fc_lport_enter_reset(lport);
4833- break;
4834+ if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) {
4835+ /*
4836+ * Memory allocation failure, or the exchange timed out.
4837+ * Retry after delay
4838+ */
4839+ if (lport->retry_count < lport->max_retry_count) {
4840+ lport->retry_count++;
4841+ if (!fp)
4842+ delay = msecs_to_jiffies(500);
4843+ else
4844+ delay = jiffies +
4845+ msecs_to_jiffies(lport->e_d_tov);
4846+
4847+ schedule_delayed_work(&lport->retry_work, delay);
4848+ } else {
4849+ switch (lport->state) {
4850+ case LPORT_ST_NONE:
4851+ case LPORT_ST_READY:
4852+ case LPORT_ST_RESET:
4853+ case LPORT_ST_RPN_ID:
4854+ case LPORT_ST_RFT_ID:
4855+ case LPORT_ST_SCR:
4856+ case LPORT_ST_DNS:
4857+ case LPORT_ST_FLOGI:
4858+ case LPORT_ST_LOGO:
4859+ fc_lport_enter_reset(lport);
4860+ break;
4861+ }
4862 }
4863 }
4864 }
4865@@ -865,8 +971,7 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
4866
4867 mutex_lock(&lport->lp_mutex);
4868
4869- if (fc_lport_debug)
4870- FC_DBG("Received a RFT_ID response\n");
4871+ FC_DEBUG_LPORT("Received a RFT_ID response\n");
4872
4873 if (lport->state != LPORT_ST_RFT_ID) {
4874 FC_DBG("Received a RFT_ID response, but in state %s\n",
4875@@ -876,7 +981,7 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
4876
4877 if (IS_ERR(fp)) {
4878 fc_lport_error(lport, fp);
4879- goto out;
4880+ goto err;
4881 }
4882
4883 fh = fc_frame_header_get(fp);
4884@@ -890,8 +995,9 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
4885 else
4886 fc_lport_error(lport, fp);
4887 out:
4888- mutex_unlock(&lport->lp_mutex);
4889 fc_frame_free(fp);
4890+err:
4891+ mutex_unlock(&lport->lp_mutex);
4892 }
4893
4894 /**
4895@@ -914,8 +1020,7 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
4896
4897 mutex_lock(&lport->lp_mutex);
4898
4899- if (fc_lport_debug)
4900- FC_DBG("Received a RPN_ID response\n");
4901+ FC_DEBUG_LPORT("Received a RPN_ID response\n");
4902
4903 if (lport->state != LPORT_ST_RPN_ID) {
4904 FC_DBG("Received a RPN_ID response, but in state %s\n",
4905@@ -925,7 +1030,7 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
4906
4907 if (IS_ERR(fp)) {
4908 fc_lport_error(lport, fp);
4909- goto out;
4910+ goto err;
4911 }
4912
4913 fh = fc_frame_header_get(fp);
4914@@ -939,8 +1044,9 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
4915 fc_lport_error(lport, fp);
4916
4917 out:
4918- mutex_unlock(&lport->lp_mutex);
4919 fc_frame_free(fp);
4920+err:
4921+ mutex_unlock(&lport->lp_mutex);
4922 }
4923
4924 /**
4925@@ -961,8 +1067,7 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
4926
4927 mutex_lock(&lport->lp_mutex);
4928
4929- if (fc_lport_debug)
4930- FC_DBG("Received a SCR response\n");
4931+ FC_DEBUG_LPORT("Received a SCR response\n");
4932
4933 if (lport->state != LPORT_ST_SCR) {
4934 FC_DBG("Received a SCR response, but in state %s\n",
4935@@ -972,7 +1077,7 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
4936
4937 if (IS_ERR(fp)) {
4938 fc_lport_error(lport, fp);
4939- goto out;
4940+ goto err;
4941 }
4942
4943 op = fc_frame_payload_op(fp);
4944@@ -982,8 +1087,9 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
4945 fc_lport_error(lport, fp);
4946
4947 out:
4948- mutex_unlock(&lport->lp_mutex);
4949 fc_frame_free(fp);
4950+err:
4951+ mutex_unlock(&lport->lp_mutex);
4952 }
4953
4954 /**
4955@@ -998,9 +1104,8 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
4956 struct fc_frame *fp;
4957 struct fc_els_scr *scr;
4958
4959- if (fc_lport_debug)
4960- FC_DBG("Port (%6x) entered SCR state from %s state\n",
4961- lport->fid, fc_lport_state(lport));
4962+ FC_DEBUG_LPORT("Port (%6x) entered SCR state from %s state\n",
4963+ fc_host_port_id(lport->host), fc_lport_state(lport));
4964
4965 fc_lport_state_enter(lport, LPORT_ST_SCR);
4966
4967@@ -1020,7 +1125,8 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
4968 if (!lport->tt.exch_seq_send(lport, fp,
4969 fc_lport_scr_resp, NULL,
4970 lport, lport->e_d_tov,
4971- lport->fid, FC_FID_FCTRL,
4972+ fc_host_port_id(lport->host),
4973+ FC_FID_FCTRL,
4974 FC_FC_SEQ_INIT | FC_FC_END_SEQ))
4975 fc_lport_error(lport, fp);
4976 }
4977@@ -1043,9 +1149,8 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport)
4978 struct fc_ns_fts *lps;
4979 int i;
4980
4981- if (fc_lport_debug)
4982- FC_DBG("Port (%6x) entered RFT_ID state from %s state\n",
4983- lport->fid, fc_lport_state(lport));
4984+ FC_DEBUG_LPORT("Port (%6x) entered RFT_ID state from %s state\n",
4985+ fc_host_port_id(lport->host), fc_lport_state(lport));
4986
4987 fc_lport_state_enter(lport, LPORT_ST_RFT_ID);
4988
4989@@ -1069,14 +1174,14 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport)
4990 FC_NS_RFT_ID,
4991 sizeof(*req) -
4992 sizeof(struct fc_ct_hdr));
4993- hton24(req->fid.fp_fid, lport->fid);
4994+ hton24(req->fid.fp_fid, fc_host_port_id(lport->host));
4995 req->fts = *lps;
4996 fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
4997
4998 if (!lport->tt.exch_seq_send(lport, fp,
4999 fc_lport_rft_id_resp, NULL,
5000 lport, lport->e_d_tov,
5001- lport->fid,
5002+ fc_host_port_id(lport->host),
5003 FC_FID_DIR_SERV,
5004 FC_FC_SEQ_INIT |
5005 FC_FC_END_SEQ))
5006@@ -1099,9 +1204,8 @@ static void fc_lport_enter_rpn_id(struct fc_lport *lport)
5007 struct fc_ns_rn_id rn;
5008 } *req;
5009
5010- if (fc_lport_debug)
5011- FC_DBG("Port (%6x) entered RPN_ID state from %s state\n",
5012- lport->fid, fc_lport_state(lport));
5013+ FC_DEBUG_LPORT("Port (%6x) entered RPN_ID state from %s state\n",
5014+ fc_host_port_id(lport->host), fc_lport_state(lport));
5015
5016 fc_lport_state_enter(lport, LPORT_ST_RPN_ID);
5017
5018@@ -1114,14 +1218,14 @@ static void fc_lport_enter_rpn_id(struct fc_lport *lport)
5019 req = fc_frame_payload_get(fp, sizeof(*req));
5020 memset(req, 0, sizeof(*req));
5021 fc_fill_dns_hdr(lport, &req->ct, FC_NS_RPN_ID, sizeof(req->rn));
5022- hton24(req->rn.fr_fid.fp_fid, lport->fid);
5023+ hton24(req->rn.fr_fid.fp_fid, fc_host_port_id(lport->host));
5024 put_unaligned_be64(lport->wwpn, &req->rn.fr_wwn);
5025 fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
5026
5027 if (!lport->tt.exch_seq_send(lport, fp,
5028 fc_lport_rpn_id_resp, NULL,
5029 lport, lport->e_d_tov,
5030- lport->fid,
5031+ fc_host_port_id(lport->host),
5032 FC_FID_DIR_SERV,
5033 FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5034 fc_lport_error(lport, fp);
5035@@ -1147,20 +1251,18 @@ static void fc_lport_enter_dns(struct fc_lport *lport)
5036 dp.ids.roles = FC_RPORT_ROLE_UNKNOWN;
5037 dp.lp = lport;
5038
5039- if (fc_lport_debug)
5040- FC_DBG("Port (%6x) entered DNS state from %s state\n",
5041- lport->fid, fc_lport_state(lport));
5042+ FC_DEBUG_LPORT("Port (%6x) entered DNS state from %s state\n",
5043+ fc_host_port_id(lport->host), fc_lport_state(lport));
5044
5045 fc_lport_state_enter(lport, LPORT_ST_DNS);
5046
5047 if (!lport->dns_rp) {
5048- /* Set up a dummy rport to directory server */
5049- rport = fc_rport_dummy_create(&dp);
5050+ /* Set up a rogue rport to directory server */
5051+ rport = fc_rport_rogue_create(&dp);
5052
5053 if (!rport)
5054 goto err;
5055 lport->dns_rp = rport;
5056- FC_DBG("created an rport for the NS\n");
5057 }
5058
5059 rport = lport->dns_rp;
5060@@ -1232,8 +1334,7 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
5061
5062 mutex_lock(&lport->lp_mutex);
5063
5064- if (fc_lport_debug)
5065- FC_DBG("Received a LOGO response\n");
5066+ FC_DEBUG_LPORT("Received a LOGO response\n");
5067
5068 if (lport->state != LPORT_ST_LOGO) {
5069 FC_DBG("Received a LOGO response, but in state %s\n",
5070@@ -1243,7 +1344,7 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
5071
5072 if (IS_ERR(fp)) {
5073 fc_lport_error(lport, fp);
5074- goto out;
5075+ goto err;
5076 }
5077
5078 op = fc_frame_payload_op(fp);
5079@@ -1253,8 +1354,9 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
5080 fc_lport_error(lport, fp);
5081
5082 out:
5083- mutex_unlock(&lport->lp_mutex);
5084 fc_frame_free(fp);
5085+err:
5086+ mutex_unlock(&lport->lp_mutex);
5087 }
5088
5089 /**
5090@@ -1269,15 +1371,14 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
5091 struct fc_frame *fp;
5092 struct fc_els_logo *logo;
5093
5094- if (fc_lport_debug)
5095- FC_DBG("Port (%6x) entered LOGO state from %s state\n",
5096- lport->fid, fc_lport_state(lport));
5097+ FC_DEBUG_LPORT("Port (%6x) entered LOGO state from %s state\n",
5098+ fc_host_port_id(lport->host), fc_lport_state(lport));
5099
5100 fc_lport_state_enter(lport, LPORT_ST_LOGO);
5101
5102 /* DNS session should be closed so we can release it here */
5103 if (lport->dns_rp) {
5104- fc_remote_port_delete(lport->dns_rp);
5105+ lport->tt.rport_logout(lport->dns_rp);
5106 lport->dns_rp = NULL;
5107 }
5108
5109@@ -1290,7 +1391,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
5110 logo = fc_frame_payload_get(fp, sizeof(*logo));
5111 memset(logo, 0, sizeof(*logo));
5112 logo->fl_cmd = ELS_LOGO;
5113- hton24(logo->fl_n_port_id, lport->fid);
5114+ hton24(logo->fl_n_port_id, fc_host_port_id(lport->host));
5115 logo->fl_n_port_wwn = htonll(lport->wwpn);
5116 fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
5117 fc_frame_set_offset(fp, 0);
5118@@ -1298,7 +1399,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
5119 if (!lport->tt.exch_seq_send(lport, fp,
5120 fc_lport_logo_resp, NULL,
5121 lport, lport->e_d_tov,
5122- lport->fid, FC_FID_FLOGI,
5123+ fc_host_port_id(lport->host), FC_FID_FLOGI,
5124 FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5125 fc_lport_error(lport, fp);
5126 }
5127@@ -1327,8 +1428,7 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
5128
5129 mutex_lock(&lport->lp_mutex);
5130
5131- if (fc_lport_debug)
5132- FC_DBG("Received a FLOGI response\n");
5133+ FC_DEBUG_LPORT("Received a FLOGI response\n");
5134
5135 if (lport->state != LPORT_ST_FLOGI) {
5136 FC_DBG("Received a FLOGI response, but in state %s\n",
5137@@ -1338,16 +1438,16 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
5138
5139 if (IS_ERR(fp)) {
5140 fc_lport_error(lport, fp);
5141- goto out;
5142+ goto err;
5143 }
5144
5145 fh = fc_frame_header_get(fp);
5146 did = ntoh24(fh->fh_d_id);
5147 if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) {
5148- if (fc_lport_debug)
5149- FC_DBG("Assigned fid %x\n", did);
5150
5151- lport->fid = did;
5152+ FC_DEBUG_LPORT("Assigned fid %x\n", did);
5153+ fc_host_port_id(lport->host) = did;
5154+
5155 flp = fc_frame_payload_get(fp, sizeof(*flp));
5156 if (flp) {
5157 mfs = ntohs(flp->fl_csp.sp_bb_data) &
5158@@ -1391,8 +1491,9 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
5159 }
5160
5161 out:
5162- mutex_unlock(&lport->lp_mutex);
5163 fc_frame_free(fp);
5164+err:
5165+ mutex_unlock(&lport->lp_mutex);
5166 }
5167
5168 /**
5169@@ -1407,8 +1508,7 @@ void fc_lport_enter_flogi(struct fc_lport *lport)
5170 struct fc_frame *fp;
5171 struct fc_els_flogi *flp;
5172
5173- if (fc_lport_debug)
5174- FC_DBG("Processing FLOGI state\n");
5175+ FC_DEBUG_LPORT("Processing FLOGI state\n");
5176
5177 fc_lport_state_enter(lport, LPORT_ST_FLOGI);
5178
5179@@ -1436,6 +1536,7 @@ int fc_lport_config(struct fc_lport *lport)
5180 {
5181 INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
5182 mutex_init(&lport->lp_mutex);
5183+ INIT_LIST_HEAD(&lport->rports);
5184
5185 fc_lport_state_enter(lport, LPORT_ST_NONE);
5186
5187@@ -1456,6 +1557,9 @@ int fc_lport_init(struct fc_lport *lport)
5188 if (!lport->tt.lport_reset)
5189 lport->tt.lport_reset = fc_lport_reset;
5190
5191+ if (!lport->tt.rport_lookup)
5192+ lport->tt.rport_lookup = fc_lport_lookup_rport;
5193+
5194 if (!lport->tt.event_callback)
5195 lport->tt.event_callback = fc_lport_rport_event;
5196
5197diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
5198index 107b304..651a3ed 100644
5199--- a/drivers/scsi/libfc/fc_rport.c
5200+++ b/drivers/scsi/libfc/fc_rport.c
5201@@ -18,10 +18,27 @@
5202 */
5203
5204 /*
5205- * Remote Port support.
5206+ * This file contains all processing regarding fc_rports. It contains the
5207+ * rport state machine and does all rport interaction with the transport class.
5208+ * There should be no other places in libfc that interact directly with the
5209+ * transport class in regards to adding and deleting rports.
5210 *
5211- * A remote port structure contains information about an N port to which we
5212- * will create sessions.
5213+ * fc_rport's represent N_Port's within the fabric.
5214+ *
5215+ * rport locking notes:
5216+ *
5217+ * The rport should never hold the rport mutex and then lock the lport
5218+ * mutex. The rport's mutex is considered lesser than the lport's mutex, so
5219+ * the lport mutex can be held before locking the rport mutex, but not the
5220+ * other way around. See the comment block at the top of fc_lport.c for more
5221+ * details.
5222+ *
5223+ * The locking strategy is similar to the lport's strategy. The lock protects
5224+ * the rport's states and is held and released by the entry points to the rport
5225+ * block. All _enter_* functions correspond to rport states and expect the rport
5226+ * mutex to be locked before calling them. This means that rports only handle one
5227+ * request or response at a time, since they're not critical for the I/O path
5228+ * this potential over-use of the mutex is acceptable.
5229 */
5230
5231 #include <linux/kernel.h>
5232@@ -34,7 +51,15 @@
5233
5234 #include <scsi/libfc/libfc.h>
5235
5236-static int fc_rp_debug;
5237+static int fc_rport_debug;
5238+
5239+#define FC_DEBUG_RPORT(fmt...) \
5240+ do { \
5241+ if (fc_rport_debug) \
5242+ FC_DBG(fmt); \
5243+ } while (0)
5244+
5245+static struct workqueue_struct *rport_event_queue;
5246
5247 static void fc_rport_enter_plogi(struct fc_rport *);
5248 static void fc_rport_enter_prli(struct fc_rport *);
5249@@ -52,6 +77,7 @@ static void fc_rport_recv_logo_req(struct fc_rport *,
5250 struct fc_seq *, struct fc_frame *);
5251 static void fc_rport_timeout(struct work_struct *);
5252 static void fc_rport_error(struct fc_rport *, struct fc_frame *);
5253+static void fc_rport_work(struct work_struct *);
5254
5255 static const char *fc_rport_state_names[] = {
5256 [RPORT_ST_NONE] = "None",
5257@@ -63,7 +89,7 @@ static const char *fc_rport_state_names[] = {
5258 [RPORT_ST_LOGO] = "LOGO",
5259 };
5260
5261-struct fc_rport *fc_rport_dummy_create(struct fc_disc_port *dp)
5262+struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp)
5263 {
5264 struct fc_rport *rport;
5265 struct fc_rport_libfc_priv *rdata;
5266@@ -91,11 +117,17 @@ struct fc_rport *fc_rport_dummy_create(struct fc_disc_port *dp)
5267 rdata->e_d_tov = dp->lp->e_d_tov;
5268 rdata->r_a_tov = dp->lp->r_a_tov;
5269 INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
5270+ INIT_WORK(&rdata->event_work, fc_rport_work);
5271+ /*
5272+ * For good measure, but not necessary as we should only
5273+ * add REAL rport to the lport list.
5274+ */
5275+ INIT_LIST_HEAD(&rdata->peers);
5276
5277 return rport;
5278 }
5279
5280-void fc_rport_dummy_destroy(struct fc_rport *rport)
5281+void fc_rport_rogue_destroy(struct fc_rport *rport)
5282 {
5283 kfree(rport);
5284 }
5285@@ -116,30 +148,6 @@ static const char *fc_rport_state(struct fc_rport *rport)
5286 }
5287
5288 /**
5289- * fc_rport_lookup - lookup a remote port by port_id
5290- * @lp: Fibre Channel host port instance
5291- * @fid: remote port port_id to match
5292- */
5293-struct fc_rport *fc_rport_lookup(const struct fc_lport *lp, u32 fid)
5294-{
5295- struct Scsi_Host *shost = lp->host;
5296- struct fc_rport *rport, *found;
5297- unsigned long flags;
5298-
5299- found = NULL;
5300- spin_lock_irqsave(shost->host_lock, flags);
5301- list_for_each_entry(rport, &fc_host_rports(shost), peers)
5302- if (rport->port_id == fid &&
5303- rport->port_state == FC_PORTSTATE_ONLINE) {
5304- found = rport;
5305- get_device(&found->dev);
5306- break;
5307- }
5308- spin_unlock_irqrestore(shost->host_lock, flags);
5309- return found;
5310-}
5311-
5312-/**
5313 * fc_set_rport_loss_tmo - Set the remote port loss timeout in seconds.
5314 * @rport: Pointer to Fibre Channel remote port structure
5315 * @timeout: timeout in seconds
5316@@ -229,15 +237,20 @@ static void fc_rport_state_enter(struct fc_rport *rport,
5317 rdata->rp_state = new;
5318 }
5319
5320-static void fc_rport_unlock(struct fc_rport *rport)
5321+static void fc_rport_work(struct work_struct *work)
5322 {
5323- struct fc_rport_libfc_priv *rdata = rport->dd_data;
5324- enum fc_lport_event event = rdata->event;
5325+ struct fc_rport_libfc_priv *rdata =
5326+ container_of(work, struct fc_rport_libfc_priv, event_work);
5327+ enum fc_lport_event event;
5328+ enum fc_rport_trans_state trans_state;
5329 struct fc_lport *lport = rdata->local_port;
5330- u32 fid = rport->port_id;
5331- void (*event_callback)(struct fc_lport *, u32,
5332- enum fc_lport_event) =
5333- rdata->event_callback;
5334+ void (*event_callback)(struct fc_lport *, struct fc_rport *,
5335+ enum fc_lport_event);
5336+ struct fc_rport *rport = PRIV_TO_RPORT(rdata);
5337+
5338+ mutex_lock(&rdata->rp_mutex);
5339+ event = rdata->event;
5340+ event_callback = rdata->event_callback;
5341
5342 if (event == LPORT_EV_RPORT_CREATED) {
5343 struct fc_rport *new_rport;
5344@@ -249,10 +262,12 @@ static void fc_rport_unlock(struct fc_rport *rport)
5345 ids.port_name = rport->port_name;
5346 ids.node_name = rport->node_name;
5347
5348+ mutex_unlock(&rdata->rp_mutex);
5349+
5350 new_rport = fc_remote_port_add(lport->host, 0, &ids);
5351 if (new_rport) {
5352 /*
5353- * Switch from the dummy rport to the rport
5354+ * Switch from the rogue rport to the rport
5355 * returned by the FC class.
5356 */
5357 new_rport->maxframe_size = rport->maxframe_size;
5358@@ -267,36 +282,32 @@ static void fc_rport_unlock(struct fc_rport *rport)
5359 mutex_init(&new_rdata->rp_mutex);
5360 INIT_DELAYED_WORK(&new_rdata->retry_work,
5361 fc_rport_timeout);
5362+ INIT_LIST_HEAD(&new_rdata->peers);
5363+ INIT_WORK(&new_rdata->event_work, fc_rport_work);
5364
5365 fc_rport_state_enter(new_rport, RPORT_ST_READY);
5366- fc_remote_port_rolechg(new_rport, rdata->roles);
5367 } else {
5368 FC_DBG("Failed to create the rport for port "
5369 "(%6x).\n", ids.port_id);
5370 event = LPORT_EV_RPORT_FAILED;
5371 }
5372-
5373- mutex_unlock(&rdata->rp_mutex);
5374- fc_rport_dummy_destroy(rport);
5375+ fc_rport_rogue_destroy(rport);
5376 rport = new_rport;
5377 rdata = new_rport->dd_data;
5378+ event_callback(lport, rport, event);
5379 } else if ((event == LPORT_EV_RPORT_FAILED) ||
5380- (event == LPORT_EV_RPORT_LOGO)) {
5381- if (rdata->trans_state == FC_PORTSTATE_ROGUE) {
5382- mutex_unlock(&rdata->rp_mutex);
5383- fc_rport_dummy_destroy(rport);
5384- } else {
5385- mutex_unlock(&rdata->rp_mutex);
5386+ (event == LPORT_EV_RPORT_LOGO) ||
5387+ (event == LPORT_EV_RPORT_STOP)) {
5388+
5389+ trans_state = rdata->trans_state;
5390+ mutex_unlock(&rdata->rp_mutex);
5391+ event_callback(lport, rport, event);
5392+ if (trans_state == FC_PORTSTATE_ROGUE)
5393+ fc_rport_rogue_destroy(rport);
5394+ else
5395 fc_remote_port_delete(rport);
5396- }
5397- } else {
5398+ } else
5399 mutex_unlock(&rdata->rp_mutex);
5400- }
5401-
5402- if (event != LPORT_EV_RPORT_NONE && event_callback) {
5403- event_callback(lport, fid, event);
5404- rdata->event = LPORT_EV_RPORT_NONE;
5405- }
5406 }
5407
5408 /**
5409@@ -313,12 +324,11 @@ int fc_rport_login(struct fc_rport *rport)
5410
5411 mutex_lock(&rdata->rp_mutex);
5412
5413- if (fc_rp_debug)
5414- FC_DBG("Login to port (%6x)\n", rport->port_id);
5415+ FC_DEBUG_RPORT("Login to port (%6x)\n", rport->port_id);
5416
5417 fc_rport_enter_plogi(rport);
5418
5419- fc_rport_unlock(rport);
5420+ mutex_unlock(&rdata->rp_mutex);
5421
5422 return 0;
5423 }
5424@@ -337,57 +347,37 @@ int fc_rport_logout(struct fc_rport *rport)
5425
5426 mutex_lock(&rdata->rp_mutex);
5427
5428- if (fc_rp_debug)
5429- FC_DBG("Logout of port (%6x)\n", rport->port_id);
5430+ FC_DEBUG_RPORT("Logout of port (%6x)\n", rport->port_id);
5431
5432 fc_rport_enter_logo(rport);
5433- fc_rport_unlock(rport);
5434+
5435+ mutex_unlock(&rdata->rp_mutex);
5436
5437 return 0;
5438 }
5439
5440 /**
5441- * fc_rport_reset - Reset the remote port
5442- * @rport: Fibre Channel remote port
5443- *
5444- * XXX - This functionality is currently broken
5445+ * fc_rport_remove - Remove an rport
5446+ * @rport: Fibre Channel remote port to be removed
5447 *
5448 * Locking Note: Called without the rport lock held. This
5449 * function will hold the rport lock, call an _enter_*
5450 * function and then unlock the rport.
5451 */
5452-void fc_rport_reset(struct fc_rport *rport)
5453+int fc_rport_stop(struct fc_rport *rport)
5454 {
5455 struct fc_rport_libfc_priv *rdata = rport->dd_data;
5456
5457 mutex_lock(&rdata->rp_mutex);
5458
5459- if (fc_rp_debug)
5460- FC_DBG("Reset port (%6x)\n", rport->port_id);
5461+ FC_DEBUG_RPORT("Remove port (%6x)\n", rport->port_id);
5462
5463- fc_rport_enter_plogi(rport);
5464-
5465- fc_rport_unlock(rport);
5466-}
5467+ rdata->event = LPORT_EV_RPORT_STOP;
5468+ queue_work(rport_event_queue, &rdata->event_work);
5469
5470-/**
5471- * fc_rport_reset_list - Reset all sessions for a local port session list.
5472- * @lport: The lport whose rports should be reset
5473- *
5474- * Locking Note: TBD
5475- */
5476-void fc_rport_reset_list(struct fc_lport *lport)
5477-{
5478- struct Scsi_Host *shost = lport->host;
5479- struct fc_rport *rport;
5480- struct fc_rport *next;
5481- unsigned long flags;
5482+ mutex_unlock(&rdata->rp_mutex);
5483
5484- spin_lock_irqsave(shost->host_lock, flags);
5485- list_for_each_entry_safe(rport, next, &fc_host_rports(shost), peers) {
5486- lport->tt.rport_reset(rport);
5487- }
5488- spin_unlock_irqrestore(shost->host_lock, flags);
5489+ return 0;
5490 }
5491
5492 /**
5493@@ -403,10 +393,10 @@ static void fc_rport_enter_ready(struct fc_rport *rport)
5494
5495 fc_rport_state_enter(rport, RPORT_ST_READY);
5496
5497- if (fc_rp_debug)
5498- FC_DBG("Port (%6x) is Ready\n", rport->port_id);
5499+ FC_DEBUG_RPORT("Port (%6x) is Ready\n", rport->port_id);
5500
5501 rdata->event = LPORT_EV_RPORT_CREATED;
5502+ queue_work(rport_event_queue, &rdata->event_work);
5503 }
5504
5505 /**
5506@@ -447,7 +437,7 @@ static void fc_rport_timeout(struct work_struct *work)
5507 }
5508 put_device(&rport->dev);
5509
5510- fc_rport_unlock(rport);
5511+ mutex_unlock(&rdata->rp_mutex);
5512 }
5513
5514 /**
5515@@ -467,37 +457,37 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
5516 struct fc_rport_libfc_priv *rdata = rport->dd_data;
5517 unsigned long delay = 0;
5518
5519- if (fc_rp_debug)
5520- FC_DBG("Error %ld in state %s, retries %d\n",
5521+ FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n",
5522 PTR_ERR(fp), fc_rport_state(rport), rdata->retries);
5523
5524- if (rdata->retries < rdata->local_port->max_retry_count) {
5525- rdata->retries++;
5526- if (!fp)
5527- delay = msecs_to_jiffies(500);
5528- get_device(&rport->dev);
5529- schedule_delayed_work(&rdata->retry_work, delay);
5530- } else {
5531- switch (rdata->rp_state) {
5532- case RPORT_ST_PLOGI:
5533- case RPORT_ST_PRLI:
5534- case RPORT_ST_LOGO:
5535- if (fc_rp_debug)
5536- FC_DBG("Remote port (%6x) closed.\n",
5537- rport->port_id);
5538-
5539- fc_remote_port_delete(rport);
5540-
5541- rdata->event = LPORT_EV_RPORT_FAILED;
5542- break;
5543- case RPORT_ST_RTV:
5544- fc_rport_enter_ready(rport);
5545- break;
5546- case RPORT_ST_NONE:
5547- case RPORT_ST_READY:
5548- case RPORT_ST_INIT:
5549- BUG();
5550- break;
5551+ if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) {
82094b55 5552+ /*
2cb7cef9
BS
5553+ * Memory allocation failure, or the exchange timed out.
5554+ * Retry after delay
5555+ */
5556+ if (rdata->retries < rdata->local_port->max_retry_count) {
5557+ rdata->retries++;
5558+ if (!fp)
5559+ delay = msecs_to_jiffies(500);
5560+ get_device(&rport->dev);
5561+ schedule_delayed_work(&rdata->retry_work, delay);
5562+ } else {
5563+ switch (rdata->rp_state) {
5564+ case RPORT_ST_PLOGI:
5565+ case RPORT_ST_PRLI:
5566+ case RPORT_ST_LOGO:
5567+ rdata->event = LPORT_EV_RPORT_FAILED;
5568+ queue_work(rport_event_queue, &rdata->event_work);
5569+ break;
5570+ case RPORT_ST_RTV:
5571+ fc_rport_enter_ready(rport);
5572+ break;
5573+ case RPORT_ST_NONE:
5574+ case RPORT_ST_READY:
5575+ case RPORT_ST_INIT:
5576+ BUG();
5577+ break;
5578+ }
5579 }
5580 }
5581 }
5582@@ -526,8 +516,7 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
5583
5584 mutex_lock(&rdata->rp_mutex);
5585
5586- if (fc_rp_debug)
5587- FC_DBG("Received a PLOGI response\n");
5588+ FC_DEBUG_RPORT("Received a PLOGI response\n");
5589
5590 if (rdata->rp_state != RPORT_ST_PLOGI) {
5591 FC_DBG("Received a PLOGI response, but in state %s\n",
5592@@ -537,12 +526,15 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
5593
5594 if (IS_ERR(fp)) {
5595 fc_rport_error(rport, fp);
5596- goto out;
5597+ goto err;
5598 }
5599
5600 op = fc_frame_payload_op(fp);
5601 if (op == ELS_LS_ACC &&
5602 (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) {
5603+ rport->port_name = get_unaligned_be64(&plp->fl_wwpn);
5604+ rport->node_name = get_unaligned_be64(&plp->fl_wwnn);
5605+
5606 tov = ntohl(plp->fl_csp.sp_e_d_tov);
5607 if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR)
5608 tov /= 1000;
5609@@ -568,8 +560,9 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
5610 fc_rport_error(rport, fp);
5611
5612 out:
5613- fc_rport_unlock(rport);
5614 fc_frame_free(fp);
5615+err:
5616+ mutex_unlock(&rdata->rp_mutex);
5617 }
5618
5619 /**
5620@@ -586,8 +579,7 @@ static void fc_rport_enter_plogi(struct fc_rport *rport)
5621 struct fc_frame *fp;
5622 struct fc_els_flogi *plogi;
5623
5624- if (fc_rp_debug)
5625- FC_DBG("Port (%6x) entered PLOGI state from %s state\n",
5626+ FC_DEBUG_RPORT("Port (%6x) entered PLOGI state from %s state\n",
5627 rport->port_id, fc_rport_state(rport));
5628
5629 fc_rport_state_enter(rport, RPORT_ST_PLOGI);
5630@@ -607,7 +599,7 @@ static void fc_rport_enter_plogi(struct fc_rport *rport)
5631 if (!lport->tt.exch_seq_send(lport, fp,
5632 fc_rport_plogi_resp, NULL,
5633 rport, lport->e_d_tov,
5634- rdata->local_port->fid,
5635+ fc_host_port_id(rdata->local_port->host),
5636 rport->port_id,
5637 FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5638 fc_rport_error(rport, fp);
5639@@ -638,8 +630,7 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
5640
5641 mutex_lock(&rdata->rp_mutex);
5642
5643- if (fc_rp_debug)
5644- FC_DBG("Received a PRLI response\n");
5645+ FC_DEBUG_RPORT("Received a PRLI response\n");
5646
5647 if (rdata->rp_state != RPORT_ST_PRLI) {
5648 FC_DBG("Received a PRLI response, but in state %s\n",
5649@@ -649,7 +640,7 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
5650
5651 if (IS_ERR(fp)) {
5652 fc_rport_error(rport, fp);
5653- goto out;
5654+ goto err;
5655 }
5656
5657 op = fc_frame_payload_op(fp);
5658@@ -667,18 +658,19 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
5659 if (fcp_parm & FCP_SPPF_TARG_FCN)
5660 roles |= FC_RPORT_ROLE_FCP_TARGET;
5661
5662- rdata->roles = roles;
5663+ rport->roles = roles;
5664 fc_rport_enter_rtv(rport);
5665
5666 } else {
5667 FC_DBG("Bad ELS response\n");
5668 rdata->event = LPORT_EV_RPORT_FAILED;
5669- fc_remote_port_delete(rport);
5670+ queue_work(rport_event_queue, &rdata->event_work);
5671 }
5672
5673 out:
5674- fc_rport_unlock(rport);
5675 fc_frame_free(fp);
5676+err:
5677+ mutex_unlock(&rdata->rp_mutex);
5678 }
5679
5680 /**
5681@@ -700,8 +692,7 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
5682
5683 mutex_lock(&rdata->rp_mutex);
5684
5685- if (fc_rp_debug)
5686- FC_DBG("Received a LOGO response\n");
5687+ FC_DEBUG_RPORT("Received a LOGO response\n");
5688
5689 if (rdata->rp_state != RPORT_ST_LOGO) {
5690 FC_DBG("Received a LOGO response, but in state %s\n",
5691@@ -711,22 +702,22 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
5692
5693 if (IS_ERR(fp)) {
5694 fc_rport_error(rport, fp);
5695- goto out;
5696+ goto err;
5697 }
5698
5699 op = fc_frame_payload_op(fp);
5700 if (op == ELS_LS_ACC) {
5701 fc_rport_enter_rtv(rport);
5702-
5703 } else {
5704 FC_DBG("Bad ELS response\n");
5705 rdata->event = LPORT_EV_RPORT_LOGO;
5706- fc_remote_port_delete(rport);
5707+ queue_work(rport_event_queue, &rdata->event_work);
5708 }
5709
5710 out:
5711- fc_rport_unlock(rport);
5712 fc_frame_free(fp);
5713+err:
5714+ mutex_unlock(&rdata->rp_mutex);
5715 }
5716
5717 /**
5718@@ -746,8 +737,7 @@ static void fc_rport_enter_prli(struct fc_rport *rport)
5719 } *pp;
5720 struct fc_frame *fp;
5721
5722- if (fc_rp_debug)
5723- FC_DBG("Port (%6x) entered PRLI state from %s state\n",
5724+ FC_DEBUG_RPORT("Port (%6x) entered PRLI state from %s state\n",
5725 rport->port_id, fc_rport_state(rport));
5726
5727 fc_rport_state_enter(rport, RPORT_ST_PRLI);
5728@@ -771,7 +761,8 @@ static void fc_rport_enter_prli(struct fc_rport *rport)
5729 if (!lport->tt.exch_seq_send(lport, fp,
5730 fc_rport_prli_resp, NULL,
5731 rport, lport->e_d_tov,
5732- lport->fid, rport->port_id,
5733+ fc_host_port_id(lport->host),
5734+ rport->port_id,
5735 FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5736 fc_rport_error(rport, fp);
5737 }
5738@@ -797,8 +788,7 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
5739
5740 mutex_lock(&rdata->rp_mutex);
5741
5742- if (fc_rp_debug)
5743- FC_DBG("Received a RTV response\n");
5744+ FC_DEBUG_RPORT("Received a RTV response\n");
5745
5746 if (rdata->rp_state != RPORT_ST_RTV) {
5747 FC_DBG("Received a RTV response, but in state %s\n",
5748@@ -808,7 +798,7 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
5749
5750 if (IS_ERR(fp)) {
5751 fc_rport_error(rport, fp);
5752- goto out;
5753+ goto err;
5754 }
5755
5756 op = fc_frame_payload_op(fp);
5757@@ -836,8 +826,9 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
5758 fc_rport_enter_ready(rport);
5759
5760 out:
5761- fc_rport_unlock(rport);
5762 fc_frame_free(fp);
5763+err:
5764+ mutex_unlock(&rdata->rp_mutex);
5765 }
5766
5767 /**
5768@@ -854,8 +845,7 @@ static void fc_rport_enter_rtv(struct fc_rport *rport)
5769 struct fc_rport_libfc_priv *rdata = rport->dd_data;
5770 struct fc_lport *lport = rdata->local_port;
5771
5772- if (fc_rp_debug)
5773- FC_DBG("Port (%6x) entered RTV state from %s state\n",
5774+ FC_DEBUG_RPORT("Port (%6x) entered RTV state from %s state\n",
5775 rport->port_id, fc_rport_state(rport));
5776
5777 fc_rport_state_enter(rport, RPORT_ST_RTV);
5778@@ -874,7 +864,8 @@ static void fc_rport_enter_rtv(struct fc_rport *rport)
5779 if (!lport->tt.exch_seq_send(lport, fp,
5780 fc_rport_rtv_resp, NULL,
5781 rport, lport->e_d_tov,
5782- lport->fid, rport->port_id,
5783+ fc_host_port_id(lport->host),
5784+ rport->port_id,
5785 FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5786 fc_rport_error(rport, fp);
5787 }
5788@@ -893,8 +884,7 @@ static void fc_rport_enter_logo(struct fc_rport *rport)
5789 struct fc_frame *fp;
5790 struct fc_els_logo *logo;
5791
5792- if (fc_rp_debug)
5793- FC_DBG("Port (%6x) entered LOGO state from %s state\n",
5794+ FC_DEBUG_RPORT("Port (%6x) entered LOGO state from %s state\n",
5795 rport->port_id, fc_rport_state(rport));
5796
5797 fc_rport_state_enter(rport, RPORT_ST_LOGO);
5798@@ -908,14 +898,15 @@ static void fc_rport_enter_logo(struct fc_rport *rport)
5799 logo = fc_frame_payload_get(fp, sizeof(*logo));
5800 memset(logo, 0, sizeof(*logo));
5801 logo->fl_cmd = ELS_LOGO;
5802- hton24(logo->fl_n_port_id, lport->fid);
5803+ hton24(logo->fl_n_port_id, fc_host_port_id(lport->host));
5804 logo->fl_n_port_wwn = htonll(lport->wwpn);
5805 fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
5806
5807 if (!lport->tt.exch_seq_send(lport, fp,
5808 fc_rport_logo_resp, NULL,
5809 rport, lport->e_d_tov,
5810- lport->fid, rport->port_id,
5811+ fc_host_port_id(lport->host),
5812+ rport->port_id,
5813 FC_FC_SEQ_INIT | FC_FC_END_SEQ))
5814 fc_rport_error(rport, fp);
5815 }
5816@@ -979,7 +970,7 @@ void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp,
5817 }
5818 }
5819
5820- fc_rport_unlock(rport);
5821+ mutex_unlock(&rdata->rp_mutex);
5822 fc_frame_free(fp);
5823 }
5824
5825@@ -1011,8 +1002,7 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport,
5826
5827 fh = fc_frame_header_get(fp);
5828
5829- if (fc_rp_debug)
5830- FC_DBG("Received PLOGI request from port (%6x) "
5831+ FC_DEBUG_RPORT("Received PLOGI request from port (%6x) "
5832 "while in state %s\n", ntoh24(fh->fh_s_id),
5833 fc_rport_state(rport));
5834
5835@@ -1041,29 +1031,25 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport,
5836 */
5837 switch (rdata->rp_state) {
5838 case RPORT_ST_INIT:
5839- if (fc_rp_debug)
5840- FC_DBG("incoming PLOGI from %6x wwpn %llx state INIT "
5841+ FC_DEBUG_RPORT("incoming PLOGI from %6x wwpn %llx state INIT "
5842 "- reject\n", sid, wwpn);
5843 reject = ELS_RJT_UNSUP;
5844 break;
5845 case RPORT_ST_PLOGI:
5846- if (fc_rp_debug)
5847- FC_DBG("incoming PLOGI from %x in PLOGI state %d\n",
5848+ FC_DEBUG_RPORT("incoming PLOGI from %x in PLOGI state %d\n",
5849 sid, rdata->rp_state);
5850 if (wwpn < lport->wwpn)
5851 reject = ELS_RJT_INPROG;
5852 break;
5853 case RPORT_ST_PRLI:
5854 case RPORT_ST_READY:
5855- if (fc_rp_debug)
5856- FC_DBG("incoming PLOGI from %x in logged-in state %d "
5857+ FC_DEBUG_RPORT("incoming PLOGI from %x in logged-in state %d "
5858 "- ignored for now\n", sid, rdata->rp_state);
5859 /* XXX TBD - should reset */
5860 break;
5861 case RPORT_ST_NONE:
5862 default:
5863- if (fc_rp_debug)
5864- FC_DBG("incoming PLOGI from %x in unexpected "
5865+ FC_DEBUG_RPORT("incoming PLOGI from %x in unexpected "
5866 "state %d\n", sid, rdata->rp_state);
5867 break;
5868 }
5869@@ -1145,8 +1131,7 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
5870
5871 fh = fc_frame_header_get(rx_fp);
5872
5873- if (fc_rp_debug)
5874- FC_DBG("Received PRLI request from port (%6x) "
5875+ FC_DEBUG_RPORT("Received PRLI request from port (%6x) "
5876 "while in state %s\n", ntoh24(fh->fh_s_id),
5877 fc_rport_state(rport));
5878
5879@@ -1220,7 +1205,7 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
5880 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
5881 if (fcp_parm & FCP_SPPF_TARG_FCN)
5882 roles |= FC_RPORT_ROLE_FCP_TARGET;
5883- rdata->roles = roles;
5884+ rport->roles = roles;
5885
5886 spp->spp_params =
5887 htonl(lport->service_params);
5888@@ -1278,8 +1263,7 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp,
5889
5890 fh = fc_frame_header_get(fp);
5891
5892- if (fc_rp_debug)
5893- FC_DBG("Received PRLO request from port (%6x) "
5894+ FC_DEBUG_RPORT("Received PRLO request from port (%6x) "
5895 "while in state %s\n", ntoh24(fh->fh_s_id),
5896 fc_rport_state(rport));
5897
5898@@ -1308,12 +1292,12 @@ static void fc_rport_recv_logo_req(struct fc_rport *rport, struct fc_seq *sp,
5899
5900 fh = fc_frame_header_get(fp);
5901
5902- if (fc_rp_debug)
5903- FC_DBG("Received LOGO request from port (%6x) "
5904+ FC_DEBUG_RPORT("Received LOGO request from port (%6x) "
5905 "while in state %s\n", ntoh24(fh->fh_s_id),
5906 fc_rport_state(rport));
5907
5908 rdata->event = LPORT_EV_RPORT_LOGO;
5909+ queue_work(rport_event_queue, &rdata->event_work);
5910
5911 lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
5912 fc_frame_free(fp);
5913@@ -1327,63 +1311,37 @@ int fc_rport_init(struct fc_lport *lport)
5914 if (!lport->tt.rport_logout)
5915 lport->tt.rport_logout = fc_rport_logout;
5916
5917+ if (!lport->tt.rport_stop)
5918+ lport->tt.rport_stop = fc_rport_stop;
5919+
5920 if (!lport->tt.rport_recv_req)
5921 lport->tt.rport_recv_req = fc_rport_recv_req;
5922
5923- if (!lport->tt.rport_lookup)
5924- lport->tt.rport_lookup = fc_rport_lookup;
5925-
5926- if (!lport->tt.rport_reset)
5927- lport->tt.rport_reset = fc_rport_reset;
5928-
5929- if (!lport->tt.rport_reset_list)
5930- lport->tt.rport_reset_list = fc_rport_reset_list;
5931-
5932 return 0;
5933 }
5934 EXPORT_SYMBOL(fc_rport_init);
5935
5936-/**
5937- * fc_block_rports - delete all the remote ports, on reset or link down
5938- * @lp: libfc local port instance
5939- *
5940- * This routine temporarily removes any online remote ports from the fc_host
5941- * rport list, then drops the host lock in order to call fc_remote_port_delete()
5942- * on each rport in turn, and finally splices the list back onto the fc_host.
5943- */
5944-void fc_block_rports(struct fc_lport *lp)
5945+int fc_setup_rport()
5946 {
5947- struct Scsi_Host *shost = lp->host;
5948- struct fc_rport *rport, *next;
5949- unsigned long flags;
5950- LIST_HEAD(rports);
5951-
5952- spin_lock_irqsave(shost->host_lock, flags);
5953- list_for_each_entry_safe(rport, next, &fc_host_rports(shost), peers) {
5954- /* protect the name service remote port */
5955- if (rport->port_id == FC_FID_DIR_SERV)
5956- continue;
5957- if (rport->port_state != FC_PORTSTATE_ONLINE)
5958- continue;
5959- list_move_tail(&rport->peers, &rports);
5960- }
5961- spin_unlock_irqrestore(shost->host_lock, flags);
5962-
5963- list_for_each_entry(rport, &rports, peers) {
5964- fc_remote_port_delete(rport);
5965- }
5966+ rport_event_queue = create_singlethread_workqueue("fc_rport_eq");
5967+ if (!rport_event_queue)
5968+ return -ENOMEM;
5969+ return 0;
5970+}
5971+EXPORT_SYMBOL(fc_setup_rport);
5972
5973- spin_lock_irqsave(shost->host_lock, flags);
5974- list_splice(&rports, &fc_host_rports(shost));
5975- spin_unlock_irqrestore(shost->host_lock, flags);
5976+void fc_destroy_rport()
5977+{
5978+ destroy_workqueue(rport_event_queue);
5979 }
5980+EXPORT_SYMBOL(fc_destroy_rport);
5981
5982 void fc_rport_terminate_io(struct fc_rport *rport)
5983 {
5984- struct fc_rport_libfc_priv *rp = rport->dd_data;
5985- struct fc_lport *lp = rp->local_port;
5986+ struct fc_rport_libfc_priv *rdata = rport->dd_data;
5987+ struct fc_lport *lport = rdata->local_port;
5988
5989- lp->tt.exch_mgr_reset(lp->emp, 0, rport->port_id);
5990- lp->tt.exch_mgr_reset(lp->emp, rport->port_id, 0);
5991+ lport->tt.exch_mgr_reset(lport->emp, 0, rport->port_id);
5992+ lport->tt.exch_mgr_reset(lport->emp, rport->port_id, 0);
5993 }
5994 EXPORT_SYMBOL(fc_rport_terminate_io);
5995diff --git a/include/scsi/libfc/fc_frame.h b/include/scsi/libfc/fc_frame.h
5996index c7a52bb..9508e55 100644
5997--- a/include/scsi/libfc/fc_frame.h
5998+++ b/include/scsi/libfc/fc_frame.h
5999@@ -51,6 +51,7 @@
6000 #define fr_sof(fp) (fr_cb(fp)->fr_sof)
6001 #define fr_eof(fp) (fr_cb(fp)->fr_eof)
6002 #define fr_flags(fp) (fr_cb(fp)->fr_flags)
6003+#define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload)
6004
6005 struct fc_frame {
6006 struct sk_buff skb;
6007@@ -63,6 +64,7 @@ struct fcoe_rcv_info {
6008 enum fc_sof fr_sof; /* start of frame delimiter */
6009 enum fc_eof fr_eof; /* end of frame delimiter */
6010 u8 fr_flags; /* flags - see below */
6011+ u16 fr_max_payload; /* max FC payload */
6012 };
6013
6014 /*
6015diff --git a/include/scsi/libfc/libfc.h b/include/scsi/libfc/libfc.h
6016index 24d3fcb..7e5e6be 100644
6017--- a/include/scsi/libfc/libfc.h
6018+++ b/include/scsi/libfc/libfc.h
6019@@ -36,12 +36,10 @@
6020 #define LIBFC_DEBUG
6021
6022 #ifdef LIBFC_DEBUG
6023-/*
6024- * Log message.
6025- */
6026+/* Log messages */
6027 #define FC_DBG(fmt, args...) \
6028 do { \
6029- printk(KERN_INFO "%s " fmt, __func__, ##args); \
6030+ printk(KERN_INFO "%s " fmt, __func__, ##args); \
6031 } while (0)
6032 #else
6033 #define FC_DBG(fmt, args...)
6034@@ -59,35 +57,22 @@
6035 #define ntohll(x) be64_to_cpu(x)
6036 #define htonll(x) cpu_to_be64(x)
6037
6038-#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
6039+#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
6040
6041-#define hton24(p, v) do { \
6042- p[0] = (((v) >> 16) & 0xFF); \
6043- p[1] = (((v) >> 8) & 0xFF); \
6044- p[2] = ((v) & 0xFF); \
6045-} while (0)
6046+#define hton24(p, v) do { \
6047+ p[0] = (((v) >> 16) & 0xFF); \
6048+ p[1] = (((v) >> 8) & 0xFF); \
6049+ p[2] = ((v) & 0xFF); \
6050+ } while (0)
6051
6052 struct fc_exch_mgr;
6053
6054 /*
6055- * tgt_flags
6056- */
6057-#define FC_TGT_REC_SUPPORTED (1 << 0)
6058-
6059-/*
6060 * FC HBA status
6061 */
6062 #define FC_PAUSE (1 << 1)
6063 #define FC_LINK_UP (1 << 0)
6064
6065-/* for fc_softc */
6066-#define FC_MAX_OUTSTANDING_COMMANDS 1024
6067-
6068-/*
6069- * Transport Capabilities
6070- */
6071-#define TRANS_C_SG (1 << 0) /* Scatter gather */
6072-
6073 enum fc_lport_state {
6074 LPORT_ST_NONE = 0,
6075 LPORT_ST_FLOGI,
6076@@ -104,6 +89,7 @@ enum fc_lport_event {
6077 LPORT_EV_RPORT_NONE = 0,
6078 LPORT_EV_RPORT_CREATED,
6079 LPORT_EV_RPORT_FAILED,
6080+ LPORT_EV_RPORT_STOP,
6081 LPORT_EV_RPORT_LOGO
6082 };
6083
6084@@ -163,9 +149,11 @@ struct fc_rport_libfc_priv {
6085 struct mutex rp_mutex;
6086 struct delayed_work retry_work;
6087 enum fc_lport_event event;
6088- void (*event_callback)(struct fc_lport *, u32,
6089+ void (*event_callback)(struct fc_lport *,
6090+ struct fc_rport *,
6091 enum fc_lport_event);
6092- u32 roles;
6093+ struct list_head peers;
6094+ struct work_struct event_work;
6095 };
6096
6097 #define PRIV_TO_RPORT(x) \
6098@@ -173,8 +161,8 @@ struct fc_rport_libfc_priv {
6099 #define RPORT_TO_PRIV(x) \
6100 (struct fc_rport_libfc_priv*)((void *)x + sizeof(struct fc_rport));
6101
6102-struct fc_rport *fc_rport_dummy_create(struct fc_disc_port *);
6103-void fc_rport_dummy_destroy(struct fc_rport *);
6104+struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *);
6105+void fc_rport_rogue_destroy(struct fc_rport *);
6106
6107 static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn)
6108 {
6109@@ -360,7 +348,7 @@ struct libfc_function_template {
6110
6111 int (*lport_reset)(struct fc_lport *);
6112
6113- void (*event_callback)(struct fc_lport *, u32,
6114+ void (*event_callback)(struct fc_lport *, struct fc_rport *,
6115 enum fc_lport_event);
6116
6117 /**
6118@@ -384,15 +372,21 @@ struct libfc_function_template {
6119 */
6120 int (*rport_logout)(struct fc_rport *rport);
6121
6122+ /*
6123+ * Delete the rport and remove it from the transport if
6124+ * it had been added. This will not send a LOGO, use
6125+ * rport_logout for a gracefull logout.
6126+ */
6127+ int (*rport_stop)(struct fc_rport *rport);
6128+
6129+ /*
6130+ * Recieve a request from a remote port.
6131+ */
6132 void (*rport_recv_req)(struct fc_seq *, struct fc_frame *,
6133 struct fc_rport *);
6134
6135 struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32);
6136
6137- void (*rport_reset)(struct fc_rport *);
6138-
6139- void (*rport_reset_list)(struct fc_lport *);
6140-
6141 /**
6142 * SCSI interfaces
6143 */
6144@@ -429,6 +423,7 @@ struct fc_lport {
6145 struct fc_rport *dns_rp;
6146 struct fc_rport *ptp_rp;
6147 void *scsi_priv;
6148+ struct list_head rports;
6149
6150 /* Operational Information */
6151 struct libfc_function_template tt;
6152@@ -442,7 +437,6 @@ struct fc_lport {
6153
6154 u64 wwpn;
6155 u64 wwnn;
6156- u32 fid;
6157 u8 retry_count;
6158 unsigned char disc_retry_count;
6159 unsigned char disc_delay;
6160@@ -452,8 +446,8 @@ struct fc_lport {
6161 unsigned char disc_buf_len;
6162
6163 /* Capabilities */
6164- char ifname[IFNAMSIZ];
6165- u32 capabilities;
6166+ u32 sg_supp:1; /* scatter gather supported */
6167+ u32 seq_offload:1; /* seq offload supported */
6168 u32 mfs; /* max FC payload size */
6169 unsigned int service_params;
6170 unsigned int e_d_tov;
6171@@ -484,11 +478,6 @@ static inline int fc_lport_test_ready(struct fc_lport *lp)
6172 return lp->state == LPORT_ST_READY;
6173 }
6174
6175-static inline u32 fc_lport_get_fid(const struct fc_lport *lp)
6176-{
6177- return lp->fid;
6178-}
6179-
6180 static inline void fc_set_wwnn(struct fc_lport *lp, u64 wwnn)
6181 {
6182 lp->wwnn = wwnn;
6183@@ -586,8 +575,6 @@ int fc_set_mfs(struct fc_lport *lp, u32 mfs);
6184 *****************************/
6185 int fc_rport_init(struct fc_lport *lp);
6186 void fc_rport_terminate_io(struct fc_rport *rp);
6187-void fc_block_rports(struct fc_lport *lp);
6188-
6189
6190 /**
6191 * DISCOVERY LAYER
6192@@ -776,6 +763,7 @@ void fc_seq_set_rec_data(struct fc_seq *sp, u32 rec_data);
6193 * Functions for fc_functions_template
6194 */
6195 void fc_get_host_speed(struct Scsi_Host *shost);
6196+void fc_get_host_port_type(struct Scsi_Host *shost);
6197 void fc_get_host_port_state(struct Scsi_Host *shost);
6198 void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout);
6199 struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *);
6200@@ -785,6 +773,7 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *);
6201 */
6202 int fc_setup_exch_mgr(void);
6203 void fc_destroy_exch_mgr(void);
6204-
6205+int fc_setup_rport(void);
6206+void fc_destroy_rport(void);
6207
6208 #endif /* _LIBFC_H_ */