]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/scsi/fcoe/fcoe.c
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi...
[karo-tx-linux.git] / drivers / scsi / fcoe / fcoe.c
index d86ca37b3787b19667fbac7d973920cde6c214ea..335e85192807a4b75e7aa229cc2b2b6f396e0b9b 100644 (file)
@@ -1471,7 +1471,7 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
         * in softirq context.
         */
        __skb_queue_tail(&fps->fcoe_rx_list, skb);
-       if (fps->fcoe_rx_list.qlen == 1)
+       if (fps->thread->state == TASK_INTERRUPTIBLE)
                wake_up_process(fps->thread);
        spin_unlock(&fps->fcoe_rx_list.lock);
 
@@ -1552,7 +1552,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
 
        /* crc offload */
        if (likely(lport->crc_offload)) {
-               skb->ip_summed = CHECKSUM_PARTIAL;
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
                skb->csum_start = skb_headroom(skb);
                skb->csum_offset = skb->len;
                crc = 0;
@@ -1569,7 +1569,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
                        return -ENOMEM;
                }
                frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
-               cp = kmap_atomic(skb_frag_page(frag), KM_SKB_DATA_SOFTIRQ)
+               cp = kmap_atomic(skb_frag_page(frag))
                        + frag->page_offset;
        } else {
                cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
@@ -1580,7 +1580,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
        cp->fcoe_crc32 = cpu_to_le32(~crc);
 
        if (skb_is_nonlinear(skb)) {
-               kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
+               kunmap_atomic(cp);
                cp = NULL;
        }
 
@@ -1790,23 +1790,29 @@ static int fcoe_percpu_receive_thread(void *arg)
 {
        struct fcoe_percpu_s *p = arg;
        struct sk_buff *skb;
+       struct sk_buff_head tmp;
+
+       skb_queue_head_init(&tmp);
 
        set_user_nice(current, -20);
 
        while (!kthread_should_stop()) {
 
                spin_lock_bh(&p->fcoe_rx_list.lock);
-               while ((skb = __skb_dequeue(&p->fcoe_rx_list)) == NULL) {
+               skb_queue_splice_init(&p->fcoe_rx_list, &tmp);
+               spin_unlock_bh(&p->fcoe_rx_list.lock);
+
+               while ((skb = __skb_dequeue(&tmp)) != NULL)
+                       fcoe_recv_frame(skb);
+
+               spin_lock_bh(&p->fcoe_rx_list.lock);
+               if (!skb_queue_len(&p->fcoe_rx_list)) {
                        set_current_state(TASK_INTERRUPTIBLE);
                        spin_unlock_bh(&p->fcoe_rx_list.lock);
                        schedule();
                        set_current_state(TASK_RUNNING);
-                       if (kthread_should_stop())
-                               return 0;
-                       spin_lock_bh(&p->fcoe_rx_list.lock);
-               }
-               spin_unlock_bh(&p->fcoe_rx_list.lock);
-               fcoe_recv_frame(skb);
+               } else
+                       spin_unlock_bh(&p->fcoe_rx_list.lock);
        }
        return 0;
 }
@@ -2180,8 +2186,12 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
        /* start FIP Discovery and FLOGI */
        lport->boot_time = jiffies;
        fc_fabric_login(lport);
-       if (!fcoe_link_ok(lport))
+       if (!fcoe_link_ok(lport)) {
+               rtnl_unlock();
                fcoe_ctlr_link_up(&fcoe->ctlr);
+               mutex_unlock(&fcoe_config_mutex);
+               return rc;
+       }
 
 out_nodev:
        rtnl_unlock();