Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
c71dac64
Commit
c71dac64
authored
Mar 21, 2002
by
Petko Manolov
Committed by
Greg Kroah-Hartman
Mar 21, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
USB pegasus driver
fix problem which cause hotplug/unplug crash the kernel
parent
f0c3878e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
43 additions
and
19 deletions
+43
-19
drivers/usb/pegasus.c
drivers/usb/pegasus.c
+42
-18
drivers/usb/pegasus.h
drivers/usb/pegasus.h
+1
-1
No files found.
drivers/usb/pegasus.c
View file @
c71dac64
...
@@ -59,7 +59,7 @@
...
@@ -59,7 +59,7 @@
/*
/*
* Version Information
* Version Information
*/
*/
#define DRIVER_VERSION "v0.5.
1 (2002/03/06
)"
#define DRIVER_VERSION "v0.5.
2 (2002/03/21
)"
#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
...
@@ -71,6 +71,7 @@
...
@@ -71,6 +71,7 @@
static
int
loopback
=
0
;
static
int
loopback
=
0
;
static
int
mii_mode
=
0
;
static
int
mii_mode
=
0
;
static
int
multicast_filter_limit
=
32
;
static
int
multicast_filter_limit
=
32
;
static
DECLARE_MUTEX
(
gsem
);
static
struct
usb_eth_dev
usb_dev_id
[]
=
{
static
struct
usb_eth_dev
usb_dev_id
[]
=
{
#define PEGASUS_DEV(pn, vid, pid, flags) \
#define PEGASUS_DEV(pn, vid, pid, flags) \
...
@@ -741,6 +742,7 @@ static int pegasus_open(struct net_device *net)
...
@@ -741,6 +742,7 @@ static int pegasus_open(struct net_device *net)
pegasus_t
*
pegasus
=
(
pegasus_t
*
)
net
->
priv
;
pegasus_t
*
pegasus
=
(
pegasus_t
*
)
net
->
priv
;
int
res
;
int
res
;
down
(
&
pegasus
->
sem
);
FILL_BULK_URB
(
pegasus
->
rx_urb
,
pegasus
->
usb
,
FILL_BULK_URB
(
pegasus
->
rx_urb
,
pegasus
->
usb
,
usb_rcvbulkpipe
(
pegasus
->
usb
,
1
),
usb_rcvbulkpipe
(
pegasus
->
usb
,
1
),
pegasus
->
rx_buff
,
PEGASUS_MAX_MTU
,
pegasus
->
rx_buff
,
PEGASUS_MAX_MTU
,
...
@@ -759,11 +761,15 @@ static int pegasus_open(struct net_device *net)
...
@@ -759,11 +761,15 @@ static int pegasus_open(struct net_device *net)
pegasus
->
flags
|=
PEGASUS_RUNNING
;
pegasus
->
flags
|=
PEGASUS_RUNNING
;
if
(
(
res
=
enable_net_traffic
(
net
,
pegasus
->
usb
))
)
{
if
(
(
res
=
enable_net_traffic
(
net
,
pegasus
->
usb
))
)
{
err
(
"can't enable_net_traffic() - %d"
,
res
);
err
(
"can't enable_net_traffic() - %d"
,
res
);
return
-
EIO
;
res
=
-
EIO
;
goto
exit
;
}
}
set_carrier
(
net
);
set_carrier
(
net
);
res
=
0
;
exit:
up
(
&
pegasus
->
sem
);
return
0
;
return
res
;
}
}
...
@@ -771,6 +777,7 @@ static int pegasus_close( struct net_device *net )
...
@@ -771,6 +777,7 @@ static int pegasus_close( struct net_device *net )
{
{
pegasus_t
*
pegasus
=
net
->
priv
;
pegasus_t
*
pegasus
=
net
->
priv
;
down
(
&
pegasus
->
sem
);
pegasus
->
flags
&=
~
PEGASUS_RUNNING
;
pegasus
->
flags
&=
~
PEGASUS_RUNNING
;
netif_stop_queue
(
net
);
netif_stop_queue
(
net
);
if
(
!
(
pegasus
->
flags
&
PEGASUS_UNPLUG
)
)
if
(
!
(
pegasus
->
flags
&
PEGASUS_UNPLUG
)
)
...
@@ -782,6 +789,7 @@ static int pegasus_close( struct net_device *net )
...
@@ -782,6 +789,7 @@ static int pegasus_close( struct net_device *net )
#ifdef PEGASUS_USE_INTR
#ifdef PEGASUS_USE_INTR
usb_unlink_urb
(
pegasus
->
intr_urb
);
usb_unlink_urb
(
pegasus
->
intr_urb
);
#endif
#endif
up
(
&
pegasus
->
sem
);
return
0
;
return
0
;
}
}
...
@@ -868,23 +876,32 @@ static int pegasus_ioctl( struct net_device *net, struct ifreq *rq, int cmd )
...
@@ -868,23 +876,32 @@ static int pegasus_ioctl( struct net_device *net, struct ifreq *rq, int cmd )
{
{
__u16
*
data
=
(
__u16
*
)
&
rq
->
ifr_data
;
__u16
*
data
=
(
__u16
*
)
&
rq
->
ifr_data
;
pegasus_t
*
pegasus
=
net
->
priv
;
pegasus_t
*
pegasus
=
net
->
priv
;
int
res
;
down
(
&
pegasus
->
sem
);
switch
(
cmd
)
{
switch
(
cmd
)
{
case
SIOCETHTOOL
:
case
SIOCETHTOOL
:
return
pegasus_ethtool_ioctl
(
net
,
rq
->
ifr_data
);
res
=
pegasus_ethtool_ioctl
(
net
,
rq
->
ifr_data
);
break
;
case
SIOCDEVPRIVATE
:
case
SIOCDEVPRIVATE
:
data
[
0
]
=
pegasus
->
phy
;
data
[
0
]
=
pegasus
->
phy
;
case
SIOCDEVPRIVATE
+
1
:
case
SIOCDEVPRIVATE
+
1
:
read_mii_word
(
pegasus
,
data
[
0
],
data
[
1
]
&
0x1f
,
&
data
[
3
]);
read_mii_word
(
pegasus
,
data
[
0
],
data
[
1
]
&
0x1f
,
&
data
[
3
]);
return
0
;
res
=
0
;
break
;
case
SIOCDEVPRIVATE
+
2
:
case
SIOCDEVPRIVATE
+
2
:
if
(
!
capable
(
CAP_NET_ADMIN
)
)
if
(
!
capable
(
CAP_NET_ADMIN
)
)
{
up
(
&
pegasus
->
sem
);
return
-
EPERM
;
return
-
EPERM
;
}
write_mii_word
(
pegasus
,
pegasus
->
phy
,
data
[
1
]
&
0x1f
,
data
[
2
]);
write_mii_word
(
pegasus
,
pegasus
->
phy
,
data
[
1
]
&
0x1f
,
data
[
2
]);
return
0
;
res
=
0
;
break
;
default:
default:
re
turn
-
EOPNOTSUPP
;
re
s
=
-
EOPNOTSUPP
;
}
}
up
(
&
pegasus
->
sem
);
return
res
;
}
}
...
@@ -953,10 +970,10 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
...
@@ -953,10 +970,10 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
err
(
"usb_set_configuration() failed"
);
err
(
"usb_set_configuration() failed"
);
return
NULL
;
return
NULL
;
}
}
down
(
&
gsem
);
if
(
!
(
pegasus
=
kmalloc
(
sizeof
(
struct
pegasus
),
GFP_KERNEL
)))
{
if
(
!
(
pegasus
=
kmalloc
(
sizeof
(
struct
pegasus
),
GFP_KERNEL
)))
{
err
(
"out of memory allocating device structure"
);
err
(
"out of memory allocating device structure"
);
return
NULL
;
goto
exit
;
}
}
usb_inc_dev_use
(
dev
);
usb_inc_dev_use
(
dev
);
...
@@ -967,20 +984,23 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
...
@@ -967,20 +984,23 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
pegasus
->
ctrl_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
pegasus
->
ctrl_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
pegasus
->
ctrl_urb
)
{
if
(
!
pegasus
->
ctrl_urb
)
{
kfree
(
pegasus
);
kfree
(
pegasus
);
return
NULL
;
pegasus
=
NULL
;
goto
exit
;
}
}
pegasus
->
rx_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
pegasus
->
rx_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
pegasus
->
rx_urb
)
{
if
(
!
pegasus
->
rx_urb
)
{
usb_free_urb
(
pegasus
->
ctrl_urb
);
usb_free_urb
(
pegasus
->
ctrl_urb
);
kfree
(
pegasus
);
kfree
(
pegasus
);
return
NULL
;
pegasus
=
NULL
;
goto
exit
;
}
}
pegasus
->
tx_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
pegasus
->
tx_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
pegasus
->
tx_urb
)
{
if
(
!
pegasus
->
tx_urb
)
{
usb_free_urb
(
pegasus
->
rx_urb
);
usb_free_urb
(
pegasus
->
rx_urb
);
usb_free_urb
(
pegasus
->
ctrl_urb
);
usb_free_urb
(
pegasus
->
ctrl_urb
);
kfree
(
pegasus
);
kfree
(
pegasus
);
return
NULL
;
pegasus
=
NULL
;
goto
exit
;
}
}
pegasus
->
intr_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
pegasus
->
intr_urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
pegasus
->
intr_urb
)
{
if
(
!
pegasus
->
intr_urb
)
{
...
@@ -988,7 +1008,8 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
...
@@ -988,7 +1008,8 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
usb_free_urb
(
pegasus
->
rx_urb
);
usb_free_urb
(
pegasus
->
rx_urb
);
usb_free_urb
(
pegasus
->
ctrl_urb
);
usb_free_urb
(
pegasus
->
ctrl_urb
);
kfree
(
pegasus
);
kfree
(
pegasus
);
return
NULL
;
pegasus
=
NULL
;
goto
exit
;
}
}
net
=
init_etherdev
(
NULL
,
0
);
net
=
init_etherdev
(
NULL
,
0
);
...
@@ -997,9 +1018,11 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
...
@@ -997,9 +1018,11 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
usb_free_urb
(
pegasus
->
rx_urb
);
usb_free_urb
(
pegasus
->
rx_urb
);
usb_free_urb
(
pegasus
->
ctrl_urb
);
usb_free_urb
(
pegasus
->
ctrl_urb
);
kfree
(
pegasus
);
kfree
(
pegasus
);
return
NULL
;
pegasus
=
NULL
;
goto
exit
;
}
}
init_MUTEX
(
&
pegasus
->
sem
);
pegasus
->
usb
=
dev
;
pegasus
->
usb
=
dev
;
pegasus
->
net
=
net
;
pegasus
->
net
=
net
;
SET_MODULE_OWNER
(
net
);
SET_MODULE_OWNER
(
net
);
...
@@ -1027,7 +1050,7 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
...
@@ -1027,7 +1050,7 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
kfree
(
pegasus
->
net
);
kfree
(
pegasus
->
net
);
kfree
(
pegasus
);
kfree
(
pegasus
);
pegasus
=
NULL
;
pegasus
=
NULL
;
return
NULL
;
goto
exit
;
}
}
info
(
"%s: %s"
,
net
->
name
,
usb_dev_id
[
dev_index
].
name
);
info
(
"%s: %s"
,
net
->
name
,
usb_dev_id
[
dev_index
].
name
);
...
@@ -1044,7 +1067,8 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
...
@@ -1044,7 +1067,8 @@ static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum,
warn
(
"can't locate MII phy, using default"
);
warn
(
"can't locate MII phy, using default"
);
pegasus
->
phy
=
1
;
pegasus
->
phy
=
1
;
}
}
exit:
up
(
&
gsem
);
return
pegasus
;
return
pegasus
;
}
}
...
...
drivers/usb/pegasus.h
View file @
c71dac64
...
@@ -101,7 +101,7 @@ typedef struct pegasus {
...
@@ -101,7 +101,7 @@ typedef struct pegasus {
struct
urb
*
ctrl_urb
,
*
rx_urb
,
*
tx_urb
,
*
intr_urb
;
struct
urb
*
ctrl_urb
,
*
rx_urb
,
*
tx_urb
,
*
intr_urb
;
struct
usb_ctrlrequest
dr
;
struct
usb_ctrlrequest
dr
;
wait_queue_head_t
ctrl_wait
;
wait_queue_head_t
ctrl_wait
;
struct
semaphore
ctrl_
sem
;
struct
semaphore
sem
;
unsigned
char
rx_buff
[
PEGASUS_MAX_MTU
];
unsigned
char
rx_buff
[
PEGASUS_MAX_MTU
];
unsigned
char
tx_buff
[
PEGASUS_MAX_MTU
];
unsigned
char
tx_buff
[
PEGASUS_MAX_MTU
];
unsigned
char
intr_buff
[
8
];
unsigned
char
intr_buff
[
8
];
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment