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