Hi,

this fixes a race where timeout would request an asynchronous unlink and 
disconnect expects a synchronous.
Furthermore this change set has a compilation fix for hpusbscsi.

The race probably exists in all ethernet usb drivers save usbnet.
This is the kind of trouble why I'd prefer to have asynchronous and 
synchronous unlinking in two functions and the difficult things handeled
in usbcore.

        Regards
                Oliver

This BitKeeper patch contains the following changesets:
1.322

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: oliver
# Host: oenone.homelinux.org
# Root: /home/oliver/bk-trees/usb-2.5

#
#--- 1.5/BitKeeper/etc/ignore   Tue Nov 27 21:03:37 2001
#+++ 1.6/BitKeeper/etc/ignore   Wed Feb 13 16:48:48 2002
#@@ -77,3 +77,4 @@
# cscope.po.out
# *.html
# *.gif
#+drivers/usb/hpusbscsi.c.alt
#
#--- 1.11/drivers/usb/hpusbscsi.c       Tue Feb 12 23:05:31 2002
#+++ 1.12/drivers/usb/hpusbscsi.c       Wed Feb 13 16:48:48 2002
#@@ -451,12 +451,11 @@
#               hpusbscsi
#       );
# 
#-      if (unlikely(0 > usb_submit_urb(u))) {
#+      if (unlikely(0 > usb_submit_urb(u, GFP_ATOMIC))) {
#               handle_usb_error(hpusbscsi);
#               return;
#       }
#       hpusbscsi->state = HP_STATE_WORKING;
#-      }
# }
# 
# static void scatter_gather_callback(struct urb *u)
#@@ -558,6 +557,8 @@
#       TRACE_STATE;
#       }
# }
#+
#+
# 
# 
# 
#
#--- 1.14/drivers/usb/kaweth.c  Tue Feb 12 21:39:53 2002
#+++ 1.15/drivers/usb/kaweth.c  Wed Feb 13 16:48:48 2002
#@@ -203,6 +203,10 @@
#       struct usb_device *dev;
#       struct net_device *net;
#       wait_queue_head_t control_wait;
#+      wait_queue_head_t tx_cancel_wait;
#+
#+      int cancelled;
#+      int cancellation;
# 
#       struct urb *rx_urb;
#       struct urb *tx_urb;
#@@ -592,6 +596,11 @@
#               kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status);
# 
#       netif_wake_queue(kaweth->net);
#+      if (unlikely(urb->status == -ECONNRESET || urb->status == -ECONNABORTED)) {
#+              kaweth->cancellation = 0;
#+              kaweth->cancelled = 1;
#+              wake_up(&kaweth->tx_cancel_wait);
#+      }
# }
# 
# /****************************************************************
#@@ -622,6 +631,9 @@
#                     count + 2,
#                     kaweth_usb_transmit_complete,
#                     kaweth);
#+      kaweth->tx_urb->transfer_flags |= USB_ASYNC_UNLINK;
#+      kaweth->cancelled = 0;
#+      kaweth->cancellation = 0;
# 
#       if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
#       {
#@@ -716,10 +728,13 @@
#       struct kaweth_device *kaweth = net->priv;
# 
#       kaweth_warn("%s: Tx timed out. Resetting.", net->name);
#+      netif_stop_queue(net);
#       kaweth->stats.tx_errors++;
#       net->trans_start = jiffies;
#-
#-      usb_unlink_urb(kaweth->tx_urb);
#+      if (!kaweth->cancellation) {
#+              kaweth->cancellation = 1;
#+              usb_unlink_urb(kaweth->tx_urb);
#+      }
# }
# 
# /****************************************************************
#@@ -876,6 +891,13 @@
#       kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
#       kaweth->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
# 
#+      if (!kaweth->tx_urb || !kaweth->rx_urb) {
#+              if (kaweth->tx_urb) usb_free_urb(kaweth->tx_urb);
#+              if (kaweth->rx_urb) usb_free_urb(kaweth->rx_urb);
#+              kfree(kaweth);
#+              return NULL;
#+      }
#+
#       kaweth->net = init_etherdev(0, 0);
#       if (!kaweth->net) {
#               kaweth_err("Error calling init_etherdev.");
#@@ -900,6 +922,8 @@
#       kaweth->net->get_stats = kaweth_netdev_stats;
#       kaweth->net->mtu = le16_to_cpu(kaweth->configuration.segment_size);
# 
#+      init_waitqueue_head(&kaweth->tx_cancel_wait);
#+
#       memset(&kaweth->stats, 0, sizeof(kaweth->stats));
# 
#       kaweth_info("kaweth interface created at %s", kaweth->net->name);
#@@ -914,6 +938,7 @@
#  ****************************************************************/
# static void kaweth_disconnect(struct usb_device *dev, void *ptr)
# {
#+      DECLARE_WAITQUEUE(wait, current);
#       struct kaweth_device *kaweth = ptr;
# 
#       kaweth_info("Unregistering");
#@@ -922,7 +947,18 @@
#               kaweth_warn("unregistering non-existant device");
#               return;
#       }
#-      usb_unlink_urb(kaweth->tx_urb);
#+      if (!kaweth->cancellation) {
#+              kaweth->cancellation = 1;
#+              usb_unlink_urb(kaweth->tx_urb);
#+      }
#+      add_wait_queue(&kaweth->tx_cancel_wait, &wait);
#+      set_current_state(TASK_UNINTERRUPTIBLE);
#+      if (!kaweth->cancelled)
#+              schedule();
#+      else
#+              set_current_state(TASK_RUNNING);
#+      remove_wait_queue(&kaweth->tx_cancel_wait, &wait);
#+      
#       usb_unlink_urb(kaweth->rx_urb);
# 
#       if(kaweth->net) {
#@@ -1056,6 +1092,11 @@
# 
# module_init(kaweth_init);
# module_exit(kaweth_exit);
#+
#+
#+
#+
#+
# 
# 
# 
#

# Diff checksum=c75059b6


# Patch vers:   1.3
# Patch type:   REGULAR

== ChangeSet ==
[EMAIL PROTECTED]|ChangeSet|20011125035615|28334|160bd283d279fb69
[EMAIL PROTECTED]|ChangeSet|20020212220531|01004
D 1.322 02/02/13 16:48:48+01:00 [EMAIL PROTECTED] +3 -0
B [EMAIL PROTECTED]|ChangeSet|20011125035615|28334|160bd283d279fb69
C
c - compilation fix for hpusbscsi
c - race and mem leak for kaweth
K 1944
P ChangeSet
------------------------------------------------

0a0
> 
[EMAIL PROTECTED]|drivers/usb/kaweth.c|20011125040920|32813|666d104abca15d68 
[EMAIL PROTECTED]|drivers/usb/kaweth.c|20020213154848|61625
> 
[EMAIL PROTECTED]|drivers/usb/hpusbscsi.c|20011125040920|46737|3090def534485c04 
[EMAIL PROTECTED]|drivers/usb/hpusbscsi.c|20020213154848|41186
> 
[EMAIL PROTECTED]|BitKeeper/etc/ignore|20011125035615|34593|457c4b0edd887438 
[EMAIL PROTECTED]|BitKeeper/etc/ignore|20020213154848|01181

== BitKeeper/etc/ignore ==
[EMAIL PROTECTED]|BitKeeper/etc/ignore|20011125035615|34593|457c4b0edd887438
[EMAIL PROTECTED]|BitKeeper/etc/ignore|20011127200337|64024
D 1.6 02/02/13 16:48:48+01:00 [EMAIL PROTECTED] +1 -0
B [EMAIL PROTECTED]|ChangeSet|20011125035615|28334|160bd283d279fb69
C
c Added drivers/usb/hpusbscsi.c.alt to the ignore list
K 1181
O -rw-rw-r--
P BitKeeper/etc/ignore
------------------------------------------------

I79 1
drivers/usb/hpusbscsi.c.alt

== drivers/usb/hpusbscsi.c ==
[EMAIL PROTECTED]|drivers/usb/hpusbscsi.c|20011125040920|46737|3090def534485c04
[EMAIL PROTECTED]|drivers/usb/hpusbscsi.c|20020212220531|40473
D 1.12 02/02/13 16:48:48+01:00 [EMAIL PROTECTED] +3 -2
B [EMAIL PROTECTED]|ChangeSet|20011125035615|28334|160bd283d279fb69
C
c compilation fix for usb_submit_urb change
K 41186
O -rw-rw-r--
P drivers/usb/hpusbscsi.c
------------------------------------------------

D454 1
I454 1
        if (unlikely(0 > usb_submit_urb(u, GFP_ATOMIC))) {
D459 1
I560 2
\
\

== drivers/usb/kaweth.c ==
[EMAIL PROTECTED]|drivers/usb/kaweth.c|20011125040920|32813|666d104abca15d68
[EMAIL PROTECTED]|drivers/usb/kaweth.c|20020212203953|44131
D 1.15 02/02/13 16:48:48+01:00 [EMAIL PROTECTED] +44 -3
B [EMAIL PROTECTED]|ChangeSet|20011125035615|28334|160bd283d279fb69
C
c - fix for a race between timeout and disconnect
c - memory leak in error case
K 61625
O -rw-rw-r--
P drivers/usb/kaweth.c
------------------------------------------------

I205 4
        wait_queue_head_t tx_cancel_wait;
\
        int cancelled;
        int cancellation;
I594 5
        if (unlikely(urb->status == -ECONNRESET || urb->status == -ECONNABORTED)) {
                kaweth->cancellation = 0;
                kaweth->cancelled = 1;
                wake_up(&kaweth->tx_cancel_wait);
        }
I624 3
        kaweth->tx_urb->transfer_flags |= USB_ASYNC_UNLINK;
        kaweth->cancelled = 0;
        kaweth->cancellation = 0;
I718 1
        netif_stop_queue(net);
D721 2
I722 4
        if (!kaweth->cancellation) {
                kaweth->cancellation = 1;
                usb_unlink_urb(kaweth->tx_urb);
        }
I878 7
        if (!kaweth->tx_urb || !kaweth->rx_urb) {
                if (kaweth->tx_urb) usb_free_urb(kaweth->tx_urb);
                if (kaweth->rx_urb) usb_free_urb(kaweth->rx_urb);
                kfree(kaweth);
                return NULL;
        }
\
I902 2
        init_waitqueue_head(&kaweth->tx_cancel_wait);
\
I916 1
        DECLARE_WAITQUEUE(wait, current);
D925 1
I925 12
        if (!kaweth->cancellation) {
                kaweth->cancellation = 1;
                usb_unlink_urb(kaweth->tx_urb);
        }
        add_wait_queue(&kaweth->tx_cancel_wait, &wait);
        set_current_state(TASK_UNINTERRUPTIBLE);
        if (!kaweth->cancelled)
                schedule();
        else
                set_current_state(TASK_RUNNING);
        remove_wait_queue(&kaweth->tx_cancel_wait, &wait);
        
I1058 5
\
\
\
\
\

# Patch checksum=c51e47e5

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to