diff options
| -rw-r--r-- | drivers/scsi/fcoe/libfcoe.c | 81 |
1 files changed, 24 insertions, 57 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 14dd8a0402b6..0e0b494fc17c 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c | |||
| @@ -70,8 +70,6 @@ struct fcoe_percpu_s *fcoe_percpu[NR_CPUS]; | |||
| 70 | 70 | ||
| 71 | /* Function Prototyes */ | 71 | /* Function Prototyes */ |
| 72 | static int fcoe_check_wait_queue(struct fc_lport *); | 72 | static int fcoe_check_wait_queue(struct fc_lport *); |
| 73 | static void fcoe_insert_wait_queue_head(struct fc_lport *, struct sk_buff *); | ||
| 74 | static void fcoe_insert_wait_queue(struct fc_lport *, struct sk_buff *); | ||
| 75 | static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *); | 73 | static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *); |
| 76 | #ifdef CONFIG_HOTPLUG_CPU | 74 | #ifdef CONFIG_HOTPLUG_CPU |
| 77 | static int fcoe_cpu_callback(struct notifier_block *, ulong, void *); | 75 | static int fcoe_cpu_callback(struct notifier_block *, ulong, void *); |
| @@ -501,7 +499,9 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) | |||
| 501 | rc = fcoe_start_io(skb); | 499 | rc = fcoe_start_io(skb); |
| 502 | 500 | ||
| 503 | if (rc) { | 501 | if (rc) { |
| 504 | fcoe_insert_wait_queue(lp, skb); | 502 | spin_lock_bh(&fc->fcoe_pending_queue.lock); |
| 503 | __skb_queue_tail(&fc->fcoe_pending_queue, skb); | ||
| 504 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); | ||
| 505 | if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) | 505 | if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) |
| 506 | lp->qfull = 1; | 506 | lp->qfull = 1; |
| 507 | } | 507 | } |
| @@ -756,33 +756,36 @@ void fcoe_watchdog(ulong vp) | |||
| 756 | */ | 756 | */ |
| 757 | static int fcoe_check_wait_queue(struct fc_lport *lp) | 757 | static int fcoe_check_wait_queue(struct fc_lport *lp) |
| 758 | { | 758 | { |
| 759 | struct fcoe_softc *fc = lport_priv(lp); | ||
| 759 | struct sk_buff *skb; | 760 | struct sk_buff *skb; |
| 760 | struct fcoe_softc *fc; | ||
| 761 | int rc = -1; | 761 | int rc = -1; |
| 762 | 762 | ||
| 763 | fc = lport_priv(lp); | ||
| 764 | spin_lock_bh(&fc->fcoe_pending_queue.lock); | 763 | spin_lock_bh(&fc->fcoe_pending_queue.lock); |
| 765 | |||
| 766 | if (fc->fcoe_pending_queue_active) | 764 | if (fc->fcoe_pending_queue_active) |
| 767 | goto out; | 765 | goto out; |
| 768 | fc->fcoe_pending_queue_active = 1; | 766 | fc->fcoe_pending_queue_active = 1; |
| 769 | if (fc->fcoe_pending_queue.qlen) { | 767 | |
| 770 | while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) { | 768 | while (fc->fcoe_pending_queue.qlen) { |
| 771 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); | 769 | /* keep qlen > 0 until fcoe_start_io succeeds */ |
| 772 | rc = fcoe_start_io(skb); | 770 | fc->fcoe_pending_queue.qlen++; |
| 773 | if (rc) | 771 | skb = __skb_dequeue(&fc->fcoe_pending_queue); |
| 774 | fcoe_insert_wait_queue_head(lp, skb); | 772 | |
| 775 | spin_lock_bh(&fc->fcoe_pending_queue.lock); | 773 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); |
| 776 | if (rc) | 774 | rc = fcoe_start_io(skb); |
| 777 | break; | 775 | spin_lock_bh(&fc->fcoe_pending_queue.lock); |
| 776 | |||
| 777 | if (rc) { | ||
| 778 | __skb_queue_head(&fc->fcoe_pending_queue, skb); | ||
| 779 | /* undo temporary increment above */ | ||
| 780 | fc->fcoe_pending_queue.qlen--; | ||
| 781 | break; | ||
| 778 | } | 782 | } |
| 779 | /* | 783 | /* undo temporary increment above */ |
| 780 | * if interface pending queue is below FCOE_LOW_QUEUE_DEPTH | 784 | fc->fcoe_pending_queue.qlen--; |
| 781 | * then clear qfull flag. | ||
| 782 | */ | ||
| 783 | if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) | ||
| 784 | lp->qfull = 0; | ||
| 785 | } | 785 | } |
| 786 | |||
| 787 | if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) | ||
| 788 | lp->qfull = 0; | ||
| 786 | fc->fcoe_pending_queue_active = 0; | 789 | fc->fcoe_pending_queue_active = 0; |
| 787 | rc = fc->fcoe_pending_queue.qlen; | 790 | rc = fc->fcoe_pending_queue.qlen; |
| 788 | out: | 791 | out: |
| @@ -791,42 +794,6 @@ out: | |||
| 791 | } | 794 | } |
| 792 | 795 | ||
| 793 | /** | 796 | /** |
| 794 | * fcoe_insert_wait_queue_head() - puts skb to fcoe pending queue head | ||
| 795 | * @lp: the fc_port for this skb | ||
| 796 | * @skb: the associated skb to be xmitted | ||
| 797 | * | ||
| 798 | * Returns: none | ||
| 799 | */ | ||
| 800 | static void fcoe_insert_wait_queue_head(struct fc_lport *lp, | ||
| 801 | struct sk_buff *skb) | ||
| 802 | { | ||
| 803 | struct fcoe_softc *fc; | ||
| 804 | |||
| 805 | fc = lport_priv(lp); | ||
| 806 | spin_lock_bh(&fc->fcoe_pending_queue.lock); | ||
| 807 | __skb_queue_head(&fc->fcoe_pending_queue, skb); | ||
| 808 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); | ||
| 809 | } | ||
| 810 | |||
| 811 | /** | ||
| 812 | * fcoe_insert_wait_queue() - put the skb into fcoe pending queue tail | ||
| 813 | * @lp: the fc_port for this skb | ||
| 814 | * @skb: the associated skb to be xmitted | ||
| 815 | * | ||
| 816 | * Returns: none | ||
| 817 | */ | ||
| 818 | static void fcoe_insert_wait_queue(struct fc_lport *lp, | ||
| 819 | struct sk_buff *skb) | ||
| 820 | { | ||
| 821 | struct fcoe_softc *fc; | ||
| 822 | |||
| 823 | fc = lport_priv(lp); | ||
| 824 | spin_lock_bh(&fc->fcoe_pending_queue.lock); | ||
| 825 | __skb_queue_tail(&fc->fcoe_pending_queue, skb); | ||
| 826 | spin_unlock_bh(&fc->fcoe_pending_queue.lock); | ||
| 827 | } | ||
| 828 | |||
| 829 | /** | ||
| 830 | * fcoe_dev_setup() - setup link change notification interface | 797 | * fcoe_dev_setup() - setup link change notification interface |
| 831 | */ | 798 | */ |
| 832 | static void fcoe_dev_setup() | 799 | static void fcoe_dev_setup() |
