On Fri, Mar 22, 2002 at 03:59:32PM -0800, Greg KH wrote:
> [EMAIL PROTECTED], 2002-03-22 14:40:07-08:00, petkan@mastika.
>   USB pegasus driver
>   
>   fix problem which cause hotplug/unplug crash the kernel
> 
>  drivers/usb/pegasus.c |   63 +++++++++++++++++++++++++++++++++++---------------
>  drivers/usb/pegasus.h |    2 -
>  2 files changed, 46 insertions(+), 19 deletions(-)


# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.225   -> 1.226  
#       drivers/usb/pegasus.h   1.8     -> 1.9    
#       drivers/usb/pegasus.c   1.12    -> 1.13   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/03/22      petkan@mastika. 1.226
# USB pegasus driver
# 
# fix problem which cause hotplug/unplug crash the kernel
# --------------------------------------------
#
diff -Nru a/drivers/usb/pegasus.c b/drivers/usb/pegasus.c
--- a/drivers/usb/pegasus.c     Fri Mar 22 15:47:39 2002
+++ b/drivers/usb/pegasus.c     Fri Mar 22 15:47:39 2002
@@ -57,7 +57,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.4.25 (2002/03/06)"
+#define DRIVER_VERSION "v0.4.26 (2002/03/21)"
 #define DRIVER_AUTHOR "Petko Manolov <[EMAIL PROTECTED]>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -69,6 +69,7 @@
 static int loopback = 0;
 static int mii_mode = 1;
 static int multicast_filter_limit = 32;
+static DECLARE_MUTEX(gsem);
 
 static struct usb_eth_dev usb_dev_id[] = {
 #define        PEGASUS_DEV(pn, vid, pid, flags)        \
@@ -741,6 +742,7 @@
        int     res;
 
 
+       down(&pegasus->sem);
        FILL_BULK_URB( pegasus->rx_urb, pegasus->usb,
                        usb_rcvbulkpipe(pegasus->usb, 1),
                        pegasus->rx_buff, PEGASUS_MAX_MTU, 
@@ -759,12 +761,16 @@
        pegasus->flags |= PEGASUS_RUNNING;
        if ( (res = enable_net_traffic(net, pegasus->usb)) ) {
                err("can't enable_net_traffic() - %d", res);
-               return -EIO;
+               res = -EIO;
+               goto exit;
        }
 
        set_carrier(net);
-
-       return 0;
+       res = 0;
+exit:
+       up(&pegasus->sem);
+       
+       return res;
 }
 
 
@@ -772,6 +778,7 @@
 {
        pegasus_t       *pegasus = net->priv;
 
+       down(&pegasus->sem);
        pegasus->flags &= ~PEGASUS_RUNNING;
        netif_stop_queue( net );
        if ( !(pegasus->flags & PEGASUS_UNPLUG) )
@@ -783,7 +790,8 @@
 #ifdef PEGASUS_USE_INTR
        usb_unlink_urb( pegasus->intr_urb );
 #endif
-
+       up(&pegasus->sem);
+       
        return 0;
 }
 
@@ -869,23 +877,33 @@
 {
        __u16 *data = (__u16 *)&rq->ifr_data;
        pegasus_t       *pegasus = net->priv;
+       int     res;
 
+       down(&pegasus->sem);
        switch(cmd) {
        case SIOCETHTOOL:
-               return pegasus_ethtool_ioctl(net, rq->ifr_data);
+               res = pegasus_ethtool_ioctl(net, rq->ifr_data);
+               break;
        case SIOCDEVPRIVATE:
                data[0] = pegasus->phy;
        case SIOCDEVPRIVATE+1:
                read_mii_word(pegasus, data[0], data[1]&0x1f, &data[3]);
-               return 0;
+               res = 0;
+               break;
        case SIOCDEVPRIVATE+2:
-               if ( !capable(CAP_NET_ADMIN) )
+               if ( !capable(CAP_NET_ADMIN) ) {
+                       up(&pegasus->sem);
                        return -EPERM;
+               }
                write_mii_word(pegasus, pegasus->phy, data[1] & 0x1f, data[2]);
-               return 0;
+               res = 0;
+               break;
        default:
-               return -EOPNOTSUPP;
+               res = -EOPNOTSUPP;
        }
+       up(&pegasus->sem);
+
+       return res;
 }
 
 
@@ -955,9 +973,10 @@
                return NULL;
        }
 
+       down(&gsem);
        if(!(pegasus = kmalloc(sizeof(struct pegasus), GFP_KERNEL))) {
                err("out of memory allocating device structure");
-               return NULL;
+               goto exit;
        }
 
        usb_inc_dev_use( dev );
@@ -968,20 +987,23 @@
        pegasus->ctrl_urb = usb_alloc_urb(0);
        if (!pegasus->ctrl_urb) {
                kfree (pegasus);
-               return NULL;
+               pegasus = NULL;
+               goto exit;
        }
        pegasus->rx_urb = usb_alloc_urb(0);
        if (!pegasus->rx_urb) {
                usb_free_urb (pegasus->ctrl_urb);
                kfree (pegasus);
-               return NULL;
+               pegasus = NULL;
+               goto exit;
        }
        pegasus->tx_urb = usb_alloc_urb(0);
        if (!pegasus->tx_urb) {
                usb_free_urb (pegasus->rx_urb);
                usb_free_urb (pegasus->ctrl_urb);
                kfree (pegasus);
-               return NULL;
+               pegasus = NULL;
+               goto exit;
        }
        pegasus->intr_urb = usb_alloc_urb(0);
        if (!pegasus->intr_urb) {
@@ -989,7 +1011,8 @@
                usb_free_urb (pegasus->rx_urb);
                usb_free_urb (pegasus->ctrl_urb);
                kfree (pegasus);
-               return NULL;
+               pegasus = NULL;
+               goto exit;
        }
 
        net = init_etherdev( NULL, 0 );
@@ -998,9 +1021,11 @@
                usb_free_urb (pegasus->rx_urb);
                usb_free_urb (pegasus->ctrl_urb);
                kfree( pegasus );
-               return  NULL;
+               pegasus = NULL;
+               goto exit;
        }
-       
+
+       init_MUTEX(&pegasus->sem);
        pegasus->usb = dev;
        pegasus->net = net;
        SET_MODULE_OWNER(net);
@@ -1028,7 +1053,7 @@
                kfree(pegasus->net);
                kfree(pegasus);
                pegasus = NULL;
-               return NULL;
+               goto exit;
        }
 
        info( "%s: %s", net->name, usb_dev_id[dev_index].name );
@@ -1046,6 +1071,8 @@
                pegasus->phy = 1;
        }
 
+exit:
+       up(&gsem);
        return pegasus;
 }
 
diff -Nru a/drivers/usb/pegasus.h b/drivers/usb/pegasus.h
--- a/drivers/usb/pegasus.h     Fri Mar 22 15:47:39 2002
+++ b/drivers/usb/pegasus.h     Fri Mar 22 15:47:39 2002
@@ -102,7 +102,7 @@
        struct urb              *ctrl_urb, *rx_urb, *tx_urb, *intr_urb;
        devrequest              dr;
        wait_queue_head_t       ctrl_wait;
-       struct semaphore        ctrl_sem;
+       struct semaphore        sem;
        unsigned char           ALIGN(rx_buff[PEGASUS_MAX_MTU]);
        unsigned char           ALIGN(tx_buff[PEGASUS_MAX_MTU]);
        unsigned char           ALIGN(intr_buff[8]);

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

Reply via email to